This commit was manufactured by cvs2svn to create tag 'freeside_1_5_0pre4'. freeside_1_5_0pre4
authorcvs2git <cvs2git>
Sat, 28 Feb 2004 23:06:14 +0000 (23:06 +0000)
committercvs2git <cvs2git>
Sat, 28 Feb 2004 23:06:14 +0000 (23:06 +0000)
1796 files changed:
ANNOUCE.1.4.0 [deleted file]
Artistic [deleted file]
CREDITS
FS/FS.pm
FS/FS/CGI.pm
FS/FS/ClientAPI.pm
FS/FS/ClientAPI/MyAccount.pm
FS/FS/ClientAPI/Signup.pm [new file with mode: 0644]
FS/FS/ClientAPI/passwd.pm
FS/FS/Conf.pm
FS/FS/InitHandler.pm
FS/FS/Misc.pm [new file with mode: 0644]
FS/FS/Record.pm
FS/FS/UID.pm
FS/FS/acct_snarf.pm [new file with mode: 0644]
FS/FS/addr_block.pm [new file with mode: 0755]
FS/FS/agent.pm
FS/FS/agent_type.pm
FS/FS/cust_bill.pm
FS/FS/cust_bill_event.pm
FS/FS/cust_bill_pay.pm
FS/FS/cust_bill_pkg.pm
FS/FS/cust_bill_pkg_detail.pm [new file with mode: 0644]
FS/FS/cust_credit.pm
FS/FS/cust_credit_bill.pm
FS/FS/cust_credit_refund.pm
FS/FS/cust_main.pm
FS/FS/cust_main_county.pm
FS/FS/cust_main_invoice.pm
FS/FS/cust_pay.pm
FS/FS/cust_pay_batch.pm
FS/FS/cust_pkg.pm
FS/FS/cust_refund.pm
FS/FS/cust_svc.pm
FS/FS/cust_tax_exempt.pm
FS/FS/domain_record.pm
FS/FS/export_svc.pm
FS/FS/msgcat.pm
FS/FS/nas.pm
FS/FS/part_bill_event.pm
FS/FS/part_export.pm
FS/FS/part_export/apache.pm [new file with mode: 0644]
FS/FS/part_export/communigate_pro.pm [new file with mode: 0644]
FS/FS/part_export/communigate_pro_singledomain.pm [new file with mode: 0644]
FS/FS/part_export/cp.pm
FS/FS/part_export/domain_shellcommands.pm [new file with mode: 0644]
FS/FS/part_export/forward_shellcommands.pm [new file with mode: 0644]
FS/FS/part_export/infostreet.pm
FS/FS/part_export/ldap.pm [new file with mode: 0644]
FS/FS/part_export/postfix.pm [new file with mode: 0644]
FS/FS/part_export/router.pm [new file with mode: 0644]
FS/FS/part_export/shellcommands.pm
FS/FS/part_export/sqlmail.pm
FS/FS/part_export/sqlradius.pm
FS/FS/part_export/sqlradius_withdomain.pm [new file with mode: 0644]
FS/FS/part_export/vpopmail.pm
FS/FS/part_export/www_shellcommands.pm
FS/FS/part_export_option.pm
FS/FS/part_pkg.pm
FS/FS/part_pop_local.pm
FS/FS/part_referral.pm
FS/FS/part_svc.pm
FS/FS/part_svc_column.pm
FS/FS/part_svc_router.pm [new file with mode: 0755]
FS/FS/part_virtual_field.pm [new file with mode: 0755]
FS/FS/pkg_svc.pm
FS/FS/port.pm
FS/FS/prepay_credit.pm
FS/FS/queue.pm
FS/FS/queue_arg.pm
FS/FS/queue_depend.pm
FS/FS/raddb.pm
FS/FS/radius_usergroup.pm
FS/FS/router.pm [new file with mode: 0755]
FS/FS/session.pm
FS/FS/svc_Common.pm
FS/FS/svc_acct.pm
FS/FS/svc_acct_pop.pm
FS/FS/svc_acct_sm.pm [deleted file]
FS/FS/svc_broadband.pm [new file with mode: 0755]
FS/FS/svc_domain.pm
FS/FS/svc_external.pm [new file with mode: 0644]
FS/FS/svc_forward.pm
FS/FS/svc_www.pm
FS/FS/type_pkgs.pm
FS/MANIFEST
FS/Makefile.PL
FS/bin/freeside-addoutsource [new file with mode: 0644]
FS/bin/freeside-addoutsourceuser [new file with mode: 0644]
FS/bin/freeside-adduser
FS/bin/freeside-cc-receipts-report
FS/bin/freeside-count-active-customers [new file with mode: 0755]
FS/bin/freeside-credit-report
FS/bin/freeside-daily
FS/bin/freeside-deloutsource [new file with mode: 0644]
FS/bin/freeside-deloutsourceuser [new file with mode: 0644]
FS/bin/freeside-deluser [new file with mode: 0644]
FS/bin/freeside-email
FS/bin/freeside-expiration-alerter
FS/bin/freeside-overdue [deleted file]
FS/bin/freeside-queued
FS/bin/freeside-radgroup [new file with mode: 0644]
FS/bin/freeside-receivables-report [deleted file]
FS/bin/freeside-selfservice-server [new file with mode: 0644]
FS/bin/freeside-setup [new file with mode: 0755]
FS/bin/freeside-sqlradius-radacctd [new file with mode: 0644]
FS/bin/freeside-sqlradius-reset
FS/bin/freeside-sqlradius-seconds [new file with mode: 0644]
FS/bin/freeside-tax-report
FS/t/Misc.t [new file with mode: 0644]
FS/t/acct_snarf.t [new file with mode: 0644]
FS/t/cust_bill_pkg_detail.t [new file with mode: 0644]
FS/t/part_export-apache.t [new file with mode: 0644]
FS/t/part_export-domain_shellcommands.t [new file with mode: 0644]
FS/t/part_export-forward_shellcommands.t [new file with mode: 0644]
FS/t/part_export-ldap.t [new file with mode: 0644]
FS/t/part_export-sqlradius_withdomain.t [new file with mode: 0644]
FS/t/svc_acct_sm.t [deleted file]
FS/t/svc_broadband.t [new file with mode: 0644]
FS/t/svc_external.t [new file with mode: 0644]
Makefile
README
README.1.5.0pre1 [new file with mode: 0644]
bin/apache.export [new file with mode: 0755]
bin/bind.export
bin/bind.import
bin/bsdshell.export
bin/create-fetchmailrc [new file with mode: 0644]
bin/create-history-tables
bin/dbdef-create
bin/fix-sequences [new file with mode: 0755]
bin/fs-setup [deleted file]
bin/generate-raddb
bin/masonize
bin/passwd.import
bin/populate-msgcat
bin/postfix.export [new file with mode: 0755]
bin/sendmail.import [new file with mode: 0644]
bin/shadow.reimport [new file with mode: 0755]
bin/svc_acct_sm.import [deleted file]
bin/sysvshell.export
conf/invoice_latex [new file with mode: 0644]
conf/invoice_latexfooter [new file with mode: 0644]
conf/invoice_latexnotes [new file with mode: 0644]
conf/invoice_latexsmallfooter [new file with mode: 0644]
conf/soadefaultttl [new file with mode: 0644]
conf/soaexpire [new file with mode: 0644]
conf/soarefresh [new file with mode: 0644]
conf/soaretry [new file with mode: 0644]
debian/changelog
debian/control
eg/export_template.pm
eg/table_template-svc.pm
eg/vpopmailrestart [deleted file]
etc/abbr_state.txt [new file with mode: 0644]
etc/acp_logfile-parse [deleted file]
etc/example-direct-cardin [deleted file]
fs_selfservice/DEPLOY
fs_selfservice/FS-SelfService/Makefile.PL
fs_selfservice/FS-SelfService/SelfService.pm
fs_selfservice/FS-SelfService/cgi/login.html
fs_selfservice/FS-SelfService/cgi/make_payment.html [new file with mode: 0644]
fs_selfservice/FS-SelfService/cgi/myaccount.html
fs_selfservice/FS-SelfService/cgi/payment_results.html [new file with mode: 0644]
fs_selfservice/FS-SelfService/cgi/selfservice.cgi
fs_selfservice/FS-SelfService/cgi/view_invoice.html
fs_selfservice/FS-SelfService/freeside-selfservice-clientd
fs_selfservice/freeside-selfservice-server [deleted file]
fs_signup/FS-SignupClient/Makefile.PL
fs_signup/FS-SignupClient/SignupClient.pm
fs_signup/FS-SignupClient/cgi/cvv2.html [new file with mode: 0644]
fs_signup/FS-SignupClient/cgi/cvv2.png [new file with mode: 0644]
fs_signup/FS-SignupClient/cgi/cvv2_amex.png [new file with mode: 0644]
fs_signup/FS-SignupClient/cgi/signup-agentselect.html [new file with mode: 0755]
fs_signup/FS-SignupClient/cgi/signup-snarf.html [new file with mode: 0755]
fs_signup/FS-SignupClient/cgi/signup.cgi
fs_signup/FS-SignupClient/cgi/signup.html
fs_signup/FS-SignupClient/cgi/stateselect.html [new file with mode: 0644]
fs_signup/fs_signup_server [deleted file]
htetc/global.asa
htetc/handler.pl
httemplate/autohandler [new file with mode: 0644]
httemplate/browse/addr_block.cgi [new file with mode: 0644]
httemplate/browse/agent.cgi
httemplate/browse/agent_type.cgi
httemplate/browse/cust_main_county.cgi
httemplate/browse/cust_pay_batch.cgi
httemplate/browse/generic.cgi [new file with mode: 0644]
httemplate/browse/part_export.cgi
httemplate/browse/part_pkg.cgi
httemplate/browse/part_referral.cgi
httemplate/browse/part_svc.cgi
httemplate/browse/part_virtual_field.cgi [new file with mode: 0644]
httemplate/browse/router.cgi [new file with mode: 0644]
httemplate/browse/svc_acct_pop.cgi
httemplate/config/config-view.cgi
httemplate/config/config.cgi
httemplate/docs/billing.html
httemplate/docs/cvv2.html [new file with mode: 0644]
httemplate/docs/ieak.html [new file with mode: 0644]
httemplate/docs/index.html
httemplate/docs/install.html
httemplate/docs/legacy.html
httemplate/docs/man/FS/part_export/.cvs_is_on_crack [new file with mode: 0644]
httemplate/docs/schema.dia
httemplate/docs/schema.html
httemplate/docs/session.html
httemplate/docs/signup.html
httemplate/docs/ssh.html
httemplate/docs/upgrade-1.4.2.html [new file with mode: 0644]
httemplate/docs/upgrade10.html [new file with mode: 0644]
httemplate/docs/upgrade4.html [deleted file]
httemplate/docs/upgrade5.html [deleted file]
httemplate/docs/upgrade6.html [deleted file]
httemplate/docs/upgrade8.html
httemplate/docs/upgrade9.html [new file with mode: 0644]
httemplate/edit/REAL_cust_pkg.cgi
httemplate/edit/agent.cgi
httemplate/edit/cust_main.cgi
httemplate/edit/cust_main_county.cgi
httemplate/edit/part_bill_event.cgi
httemplate/edit/part_export.cgi
httemplate/edit/part_pkg.cgi
httemplate/edit/part_svc.cgi
httemplate/edit/part_virtual_field.cgi [new file with mode: 0644]
httemplate/edit/process/REAL_cust_pkg.cgi
httemplate/edit/process/addr_block/add.cgi [new file with mode: 0755]
httemplate/edit/process/addr_block/allocate.cgi [new file with mode: 0755]
httemplate/edit/process/addr_block/deallocate.cgi [new file with mode: 0755]
httemplate/edit/process/addr_block/split.cgi [new file with mode: 0755]
httemplate/edit/process/cust_main.cgi
httemplate/edit/process/cust_main_county-collapse.cgi
httemplate/edit/process/cust_main_county.cgi
httemplate/edit/process/cust_pkg.cgi
httemplate/edit/process/generic.cgi [new file with mode: 0644]
httemplate/edit/process/part_bill_event.cgi
httemplate/edit/process/part_pkg.cgi
httemplate/edit/process/part_svc.cgi
httemplate/edit/process/router.cgi [new file with mode: 0644]
httemplate/edit/process/svc_acct_sm.cgi [deleted file]
httemplate/edit/process/svc_broadband.cgi [new file with mode: 0644]
httemplate/edit/process/svc_external.cgi [new file with mode: 0755]
httemplate/edit/router.cgi [new file with mode: 0755]
httemplate/edit/svc_acct.cgi
httemplate/edit/svc_acct_sm.cgi [deleted file]
httemplate/edit/svc_broadband.cgi [new file with mode: 0644]
httemplate/edit/svc_domain.cgi
httemplate/edit/svc_external.cgi [new file with mode: 0644]
httemplate/edit/svc_forward.cgi
httemplate/edit/svc_www.cgi
httemplate/elements/calendar-en.js [new file with mode: 0644]
httemplate/elements/calendar-setup.js [new file with mode: 0644]
httemplate/elements/calendar-win2k-2.css [new file with mode: 0644]
httemplate/elements/calendar.js [new file with mode: 0644]
httemplate/elements/calendar_stripped.js [new file with mode: 0644]
httemplate/elements/header.html [new file with mode: 0644]
httemplate/elements/menubar.html [new file with mode: 0644]
httemplate/elements/pager.html [new file with mode: 0644]
httemplate/elements/table.html [new file with mode: 0644]
httemplate/graph/money_time-graph.cgi [new file with mode: 0755]
httemplate/graph/money_time.cgi [new file with mode: 0644]
httemplate/images/calendar.png [new file with mode: 0644]
httemplate/images/cvv2.png [new file with mode: 0644]
httemplate/images/cvv2_amex.png [new file with mode: 0644]
httemplate/index.html
httemplate/misc/bill.cgi
httemplate/misc/catchall.cgi
httemplate/misc/change_pkg.cgi [new file with mode: 0755]
httemplate/misc/cust_main-cancel.cgi [new file with mode: 0755]
httemplate/misc/cust_main-import.cgi [new file with mode: 0644]
httemplate/misc/cust_main-import_charges.cgi [new file with mode: 0644]
httemplate/misc/delete-cust_credit.cgi [new file with mode: 0755]
httemplate/misc/download-batch.cgi [new file with mode: 0644]
httemplate/misc/dump.cgi [new file with mode: 0644]
httemplate/misc/email-invoice.cgi [new file with mode: 0755]
httemplate/misc/link.cgi
httemplate/misc/meta-import.cgi [new file with mode: 0644]
httemplate/misc/print-invoice.cgi
httemplate/misc/process/cust_main-import.cgi [new file with mode: 0644]
httemplate/misc/process/cust_main-import_charges.cgi [new file with mode: 0644]
httemplate/misc/process/link.cgi
httemplate/misc/process/meta-import.cgi [new file with mode: 0644]
httemplate/misc/unapply-cust_pay.cgi [new file with mode: 0755]
httemplate/misc/unprovision.cgi [new file with mode: 0755]
httemplate/misc/upload-batch.cgi [new file with mode: 0644]
httemplate/search/cust_bill.cgi
httemplate/search/cust_bill_event.cgi
httemplate/search/cust_main-quickpay.html
httemplate/search/cust_main.cgi
httemplate/search/cust_pay.cgi
httemplate/search/cust_pkg.cgi
httemplate/search/cust_pkg.html [deleted file]
httemplate/search/cust_pkg_report.cgi [new file with mode: 0755]
httemplate/search/elements/search.html [new file with mode: 0644]
httemplate/search/report_cc.html
httemplate/search/report_credit.html
httemplate/search/report_cust_pay.html [new file with mode: 0644]
httemplate/search/report_prepaid_income.cgi [new file with mode: 0644]
httemplate/search/report_prepaid_income.html [new file with mode: 0644]
httemplate/search/report_receivables.cgi
httemplate/search/report_tax.html
httemplate/search/sql.cgi [deleted file]
httemplate/search/sql.html [new file with mode: 0644]
httemplate/search/svc_acct.cgi
httemplate/search/svc_acct_sm.cgi [deleted file]
httemplate/search/svc_acct_sm.html [deleted file]
httemplate/search/svc_domain.cgi
httemplate/search/svc_forward.cgi [new file with mode: 0755]
httemplate/view/cust_bill-pdf.cgi [new file with mode: 0755]
httemplate/view/cust_bill-ps.cgi [new file with mode: 0755]
httemplate/view/cust_bill.cgi
httemplate/view/cust_main.cgi
httemplate/view/cust_pkg.cgi
httemplate/view/svc_acct.cgi
httemplate/view/svc_acct_sm.cgi [deleted file]
httemplate/view/svc_broadband.cgi [new file with mode: 0644]
httemplate/view/svc_domain.cgi
httemplate/view/svc_external.cgi [new file with mode: 0644]
httemplate/view/svc_forward.cgi
httemplate/view/svc_www.cgi
init.d/freeside-init
install/debian/3.0/INSTALL [new file with mode: 0644]
install/freebsd/INSTALL [new file with mode: 0755]
install/freebsd/ports [new file with mode: 0644]
install/openbsd/INSTALL [new file with mode: 0644]
install/openbsd/cpan [new file with mode: 0644]
install/openbsd/ports [new file with mode: 0644]
install/redhat/7.3/INSTALL [new file with mode: 0644]
install/redhat/7.3/sources.list [new file with mode: 0644]
install/redhat/9/INSTALL [new file with mode: 0644]
install/redhat/9/sources.list [new file with mode: 0644]
rt/ChangeLog [deleted file]
rt/Changelog [new file with mode: 0644]
rt/HOWTO/README [new file with mode: 0644]
rt/HOWTO/change.txt [new file with mode: 0644]
rt/HOWTO/release.txt [new file with mode: 0644]
rt/HOWTO/version-control.txt [new file with mode: 0644]
rt/Makefile
rt/Makefile.in [new file with mode: 0644]
rt/README [deleted file]
rt/TODO [deleted file]
rt/aclocal.m4 [new file with mode: 0644]
rt/autom4te.cache/output.0 [new file with mode: 0644]
rt/autom4te.cache/requests [new file with mode: 0644]
rt/autom4te.cache/traces.0 [new file with mode: 0644]
rt/bin/initacls.Oracle [deleted file]
rt/bin/initacls.Pg [deleted file]
rt/bin/initacls.mysql [deleted file]
rt/bin/mason_handler.fcgi
rt/bin/mason_handler.fcgi.in [new file with mode: 0644]
rt/bin/mason_handler.scgi
rt/bin/mason_handler.scgi.in [new file with mode: 0644]
rt/bin/mason_handler.svc [new file with mode: 0644]
rt/bin/mason_handler.svc.in [new file with mode: 0644]
rt/bin/rt [deleted file]
rt/bin/rt-commit-handler [new file with mode: 0644]
rt/bin/rt-commit-handler.in [new file with mode: 0644]
rt/bin/rt-crontool [new file with mode: 0644]
rt/bin/rt-crontool.in [new file with mode: 0644]
rt/bin/rt-mailgate
rt/bin/rt-mailgate.in [new file with mode: 0644]
rt/bin/rtadmin [deleted file]
rt/bin/webmux.pl
rt/bin/webmux.pl.in [new file with mode: 0644]
rt/config [new file with mode: 0644]
rt/config.layout [new file with mode: 0644]
rt/config.log [new file with mode: 0644]
rt/config.pld [new file with mode: 0644]
rt/config.status [new file with mode: 0755]
rt/configure [new file with mode: 0755]
rt/configure.ac [new file with mode: 0644]
rt/docs/design_docs/acls
rt/docs/design_docs/approval_notices [new file with mode: 0644]
rt/docs/design_docs/approval_template [new file with mode: 0644]
rt/docs/design_docs/basic-definitions.txt [deleted file]
rt/docs/design_docs/cf_search [new file with mode: 0644]
rt/docs/design_docs/cli_spec
rt/docs/design_docs/delegation [new file with mode: 0644]
rt/docs/design_docs/evil_plans
rt/docs/design_docs/groups_notes [new file with mode: 0644]
rt/docs/design_docs/local_hacking [deleted file]
rt/docs/design_docs/recursive_group_membership_algorithm [new file with mode: 0644]
rt/docs/design_docs/rql_parser_machine.graphviz [new file with mode: 0644]
rt/docs/design_docs/string-extraction-guide.txt [new file with mode: 0644]
rt/docs/design_docs/ticket_templates [new file with mode: 0644]
rt/docs/rt.gif [deleted file]
rt/etc/RT_Config.pm [new file with mode: 0644]
rt/etc/RT_Config.pm.in [new file with mode: 0644]
rt/etc/RT_SiteConfig.pm [new file with mode: 0644]
rt/etc/acl.Oracle
rt/etc/acl.Pg
rt/etc/acl.mysql
rt/etc/config.pm [deleted file]
rt/etc/constraints.mysql [new file with mode: 0644]
rt/etc/initialdata [new file with mode: 0644]
rt/etc/schema.Oracle [deleted file]
rt/etc/schema.Pg
rt/etc/schema.SQLite [new file with mode: 0644]
rt/etc/schema.mysql
rt/etc/schema.pm [deleted file]
rt/etc/upgrade/2.1.71 [new file with mode: 0644]
rt/html/Admin/Elements/AddCustomFieldValue [new file with mode: 0644]
rt/html/Admin/Elements/CreateUserCalled [new file with mode: 0644]
rt/html/Admin/Elements/EditCustomField [new file with mode: 0644]
rt/html/Admin/Elements/EditCustomFieldValues [new file with mode: 0644]
rt/html/Admin/Elements/EditCustomFields [new file with mode: 0644]
rt/html/Admin/Elements/EditQueueWatchers [new file with mode: 0644]
rt/html/Admin/Elements/EditScrip [new file with mode: 0644]
rt/html/Admin/Elements/EditScrips [new file with mode: 0644]
rt/html/Admin/Elements/EditTemplates [new file with mode: 0644]
rt/html/Admin/Elements/EditUserComments [new file with mode: 0644]
rt/html/Admin/Elements/GroupTabs [new file with mode: 0644]
rt/html/Admin/Elements/Header [new file with mode: 0644]
rt/html/Admin/Elements/ListGlobalCustomFields [new file with mode: 0644]
rt/html/Admin/Elements/ListGlobalScrips [new file with mode: 0644]
rt/html/Admin/Elements/ModifyQueue [new file with mode: 0644]
rt/html/Admin/Elements/ModifyTemplate [new file with mode: 0644]
rt/html/Admin/Elements/ModifyUser [new file with mode: 0644]
rt/html/Admin/Elements/QueueRightsForUser [new file with mode: 0644]
rt/html/Admin/Elements/QueueTabs [new file with mode: 0644]
rt/html/Admin/Elements/SelectCustomFieldType [new file with mode: 0644]
rt/html/Admin/Elements/SelectGroups [new file with mode: 0644]
rt/html/Admin/Elements/SelectModifyGroup [new file with mode: 0644]
rt/html/Admin/Elements/SelectModifyQueue [new file with mode: 0644]
rt/html/Admin/Elements/SelectModifyUser [new file with mode: 0644]
rt/html/Admin/Elements/SelectNewGroupMembers [new file with mode: 0644]
rt/html/Admin/Elements/SelectRights [new file with mode: 0644]
rt/html/Admin/Elements/SelectScrip [new file with mode: 0644]
rt/html/Admin/Elements/SelectScripAction [new file with mode: 0644]
rt/html/Admin/Elements/SelectScripCondition [new file with mode: 0644]
rt/html/Admin/Elements/SelectSingleOrMultiple [new file with mode: 0644]
rt/html/Admin/Elements/SelectTemplate [new file with mode: 0644]
rt/html/Admin/Elements/SelectUsers [new file with mode: 0644]
rt/html/Admin/Elements/SystemTabs [new file with mode: 0644]
rt/html/Admin/Elements/Tabs [new file with mode: 0644]
rt/html/Admin/Elements/UserTabs [new file with mode: 0644]
rt/html/Admin/Global/CustomField.html [new file with mode: 0644]
rt/html/Admin/Global/CustomFields.html [new file with mode: 0644]
rt/html/Admin/Global/GroupRights.html [new file with mode: 0644]
rt/html/Admin/Global/Scrip.html [new file with mode: 0644]
rt/html/Admin/Global/Scrips.html [new file with mode: 0644]
rt/html/Admin/Global/Template.html [new file with mode: 0644]
rt/html/Admin/Global/Templates.html [new file with mode: 0644]
rt/html/Admin/Global/UserRights.html [new file with mode: 0644]
rt/html/Admin/Global/index.html [new file with mode: 0644]
rt/html/Admin/Groups/GroupRights.html [new file with mode: 0644]
rt/html/Admin/Groups/Members.html [new file with mode: 0644]
rt/html/Admin/Groups/Modify.html [new file with mode: 0644]
rt/html/Admin/Groups/UserRights.html [new file with mode: 0644]
rt/html/Admin/Groups/index.html [new file with mode: 0644]
rt/html/Admin/Queues/CustomField.html [new file with mode: 0644]
rt/html/Admin/Queues/CustomFields.html [new file with mode: 0644]
rt/html/Admin/Queues/GroupRights.html [new file with mode: 0644]
rt/html/Admin/Queues/Modify.html [new file with mode: 0644]
rt/html/Admin/Queues/People.html [new file with mode: 0644]
rt/html/Admin/Queues/Scrip.html [new file with mode: 0644]
rt/html/Admin/Queues/Scrips.html [new file with mode: 0644]
rt/html/Admin/Queues/Template.html [new file with mode: 0644]
rt/html/Admin/Queues/Templates.html [new file with mode: 0644]
rt/html/Admin/Queues/UserRights.html [new file with mode: 0644]
rt/html/Admin/Queues/index.html [new file with mode: 0644]
rt/html/Admin/Users/Modify.html [new file with mode: 0644]
rt/html/Admin/Users/Prefs.html [new file with mode: 0644]
rt/html/Admin/Users/index.html [new file with mode: 0644]
rt/html/Admin/index.html [new file with mode: 0644]
rt/html/Approvals/Display.html [new file with mode: 0644]
rt/html/Approvals/Elements/Approve [new file with mode: 0644]
rt/html/Approvals/Elements/PendingMyApproval [new file with mode: 0644]
rt/html/Approvals/Elements/ShowDependency [new file with mode: 0644]
rt/html/Approvals/Elements/Tabs [new file with mode: 0644]
rt/html/Approvals/index.html [new file with mode: 0644]
rt/html/Elements/BevelBoxRaisedEnd [new file with mode: 0644]
rt/html/Elements/BevelBoxRaisedStart [new file with mode: 0644]
rt/html/Elements/Callback [new file with mode: 0644]
rt/html/Elements/Checkbox [new file with mode: 0644]
rt/html/Elements/CreateTicket [new file with mode: 0644]
rt/html/Elements/Error [new file with mode: 0644]
rt/html/Elements/Footer [new file with mode: 0644]
rt/html/Elements/GotoTicket [new file with mode: 0644]
rt/html/Elements/Header [new file with mode: 0644]
rt/html/Elements/ListActions [new file with mode: 0644]
rt/html/Elements/Login [new file with mode: 0644]
rt/html/Elements/Menu [new file with mode: 0644]
rt/html/Elements/MessageBox [new file with mode: 0644]
rt/html/Elements/MyRequests [new file with mode: 0644]
rt/html/Elements/MyTickets [new file with mode: 0644]
rt/html/Elements/PageLayout [new file with mode: 0644]
rt/html/Elements/Quicksearch [new file with mode: 0644]
rt/html/Elements/Refresh [new file with mode: 0644]
rt/html/Elements/Section [new file with mode: 0644]
rt/html/Elements/SelectAttachmentField [new file with mode: 0644]
rt/html/Elements/SelectBoolean [new file with mode: 0644]
rt/html/Elements/SelectCustomFieldOperator [new file with mode: 0644]
rt/html/Elements/SelectCustomFieldValue [new file with mode: 0644]
rt/html/Elements/SelectDate [new file with mode: 0644]
rt/html/Elements/SelectDateRelation [new file with mode: 0644]
rt/html/Elements/SelectDateType [new file with mode: 0644]
rt/html/Elements/SelectEqualityOperator [new file with mode: 0644]
rt/html/Elements/SelectGroups [new file with mode: 0644]
rt/html/Elements/SelectLinkType [new file with mode: 0644]
rt/html/Elements/SelectMatch [new file with mode: 0644]
rt/html/Elements/SelectNewTicketQueue [new file with mode: 0644]
rt/html/Elements/SelectOwner [new file with mode: 0644]
rt/html/Elements/SelectQueue [new file with mode: 0644]
rt/html/Elements/SelectResultsPerPage [new file with mode: 0644]
rt/html/Elements/SelectSortOrder [new file with mode: 0644]
rt/html/Elements/SelectStatus [new file with mode: 0644]
rt/html/Elements/SelectTicketSortBy [new file with mode: 0644]
rt/html/Elements/SelectTicketTypes [new file with mode: 0644]
rt/html/Elements/SelectUsers [new file with mode: 0644]
rt/html/Elements/SelectWatcherType [new file with mode: 0644]
rt/html/Elements/SetupSessionCookie [new file with mode: 0644]
rt/html/Elements/ShadedBox [new file with mode: 0644]
rt/html/Elements/ShadedInputRow [new file with mode: 0644]
rt/html/Elements/ShadedRow [new file with mode: 0644]
rt/html/Elements/SimpleSearch [new file with mode: 0644]
rt/html/Elements/Submit [new file with mode: 0644]
rt/html/Elements/Tabs [new file with mode: 0644]
rt/html/Elements/TitleBoxEnd [new file with mode: 0644]
rt/html/Elements/TitleBoxStart [new file with mode: 0644]
rt/html/Elements/ViewUser [new file with mode: 0644]
rt/html/NoAuth/Logout.html [new file with mode: 0644]
rt/html/NoAuth/Reminder.html [new file with mode: 0644]
rt/html/NoAuth/images/back_home.gif [new file with mode: 0644]
rt/html/NoAuth/images/bplogo.gif [new file with mode: 0644]
rt/html/NoAuth/images/favicon.png [new file with mode: 0644]
rt/html/NoAuth/images/head_requestracker.gif [new file with mode: 0644]
rt/html/NoAuth/images/rt.jpg [new file with mode: 0644]
rt/html/NoAuth/images/space.gif [new file with mode: 0644]
rt/html/NoAuth/images/spacer.gif [new file with mode: 0644]
rt/html/NoAuth/images/squares_blue.gif [new file with mode: 0644]
rt/html/NoAuth/webrt.css [new file with mode: 0644]
rt/html/REST/1.0/NoAuth/mail-gateway [new file with mode: 0644]
rt/html/Search/Bulk.html [new file with mode: 0644]
rt/html/Search/Elements/PickRestriction [new file with mode: 0644]
rt/html/Search/Elements/TicketHeader [new file with mode: 0644]
rt/html/Search/Elements/TicketHeaderCell [new file with mode: 0644]
rt/html/Search/Elements/TicketRow [new file with mode: 0644]
rt/html/Search/Listing.html [new file with mode: 0644]
rt/html/SelfService/Attachment/dhandler [new file with mode: 0644]
rt/html/SelfService/Closed.html [new file with mode: 0644]
rt/html/SelfService/Create.html [new file with mode: 0644]
rt/html/SelfService/Display.html [new file with mode: 0644]
rt/html/SelfService/Elements/GotoTicket [new file with mode: 0644]
rt/html/SelfService/Elements/Header [new file with mode: 0644]
rt/html/SelfService/Elements/MyRequests [new file with mode: 0644]
rt/html/SelfService/Elements/Tabs [new file with mode: 0644]
rt/html/SelfService/Error.html [new file with mode: 0644]
rt/html/SelfService/Prefs.html [new file with mode: 0644]
rt/html/SelfService/Update.html [new file with mode: 0644]
rt/html/SelfService/index.html [new file with mode: 0644]
rt/html/Ticket/Attachment/dhandler [new file with mode: 0644]
rt/html/Ticket/Create.html [new file with mode: 0644]
rt/html/Ticket/Display.html [new file with mode: 0644]
rt/html/Ticket/Elements/AddWatchers [new file with mode: 0644]
rt/html/Ticket/Elements/BulkLinks [new file with mode: 0644]
rt/html/Ticket/Elements/EditBasics [new file with mode: 0644]
rt/html/Ticket/Elements/EditCustomField [new file with mode: 0644]
rt/html/Ticket/Elements/EditCustomFields [new file with mode: 0644]
rt/html/Ticket/Elements/EditDates [new file with mode: 0644]
rt/html/Ticket/Elements/EditLinks [new file with mode: 0644]
rt/html/Ticket/Elements/EditPeople [new file with mode: 0644]
rt/html/Ticket/Elements/EditWatchers [new file with mode: 0644]
rt/html/Ticket/Elements/ShowAttachments [new file with mode: 0644]
rt/html/Ticket/Elements/ShowBasics [new file with mode: 0644]
rt/html/Ticket/Elements/ShowCustomFields [new file with mode: 0644]
rt/html/Ticket/Elements/ShowDates [new file with mode: 0644]
rt/html/Ticket/Elements/ShowDependencies [new file with mode: 0644]
rt/html/Ticket/Elements/ShowHistory [new file with mode: 0644]
rt/html/Ticket/Elements/ShowLink [new file with mode: 0644]
rt/html/Ticket/Elements/ShowLinks [new file with mode: 0644]
rt/html/Ticket/Elements/ShowMemberOf [new file with mode: 0644]
rt/html/Ticket/Elements/ShowMembers [new file with mode: 0644]
rt/html/Ticket/Elements/ShowMessageHeaders [new file with mode: 0644]
rt/html/Ticket/Elements/ShowMessageStanza [new file with mode: 0644]
rt/html/Ticket/Elements/ShowPeople [new file with mode: 0644]
rt/html/Ticket/Elements/ShowReferences [new file with mode: 0644]
rt/html/Ticket/Elements/ShowRequestor [new file with mode: 0644]
rt/html/Ticket/Elements/ShowSummary [new file with mode: 0644]
rt/html/Ticket/Elements/ShowTransaction [new file with mode: 0644]
rt/html/Ticket/Elements/Tabs [new file with mode: 0644]
rt/html/Ticket/History.html [new file with mode: 0644]
rt/html/Ticket/Modify.html [new file with mode: 0644]
rt/html/Ticket/ModifyAll.html [new file with mode: 0644]
rt/html/Ticket/ModifyDates.html [new file with mode: 0644]
rt/html/Ticket/ModifyLinks.html [new file with mode: 0644]
rt/html/Ticket/ModifyPeople.html [new file with mode: 0644]
rt/html/Ticket/Update.html [new file with mode: 0644]
rt/html/User/Delegation.html [new file with mode: 0644]
rt/html/User/Elements/DelegateRights [new file with mode: 0644]
rt/html/User/Elements/GroupTabs [new file with mode: 0644]
rt/html/User/Elements/Tabs [new file with mode: 0644]
rt/html/User/Groups/Members.html [new file with mode: 0644]
rt/html/User/Groups/Modify.html [new file with mode: 0644]
rt/html/User/Groups/index.html [new file with mode: 0644]
rt/html/User/Prefs.html [new file with mode: 0644]
rt/html/autohandler [new file with mode: 0644]
rt/html/index.html [new file with mode: 0644]
rt/html/l [new file with mode: 0644]
rt/install-sh [new file with mode: 0644]
rt/lib/MANIFEST [deleted file]
rt/lib/MANIFEST.SKIP [deleted file]
rt/lib/Makefile.PL [deleted file]
rt/lib/RT.pm
rt/lib/RT.pm.in [new file with mode: 0644]
rt/lib/RT/ACE.pm
rt/lib/RT/ACE_Overlay.pm [new file with mode: 0644]
rt/lib/RT/ACL.pm
rt/lib/RT/ACL_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Action/AutoOpen.pm [new file with mode: 0644]
rt/lib/RT/Action/Autoreply.pm
rt/lib/RT/Action/CreateTickets.pm [new file with mode: 0644]
rt/lib/RT/Action/EscalatePriority.pm [new file with mode: 0644]
rt/lib/RT/Action/Generic.pm
rt/lib/RT/Action/Notify.pm
rt/lib/RT/Action/NotifyAsComment.pm
rt/lib/RT/Action/OpenDependent.pm [deleted file]
rt/lib/RT/Action/ResolveMembers.pm
rt/lib/RT/Action/SendEmail.pm
rt/lib/RT/Action/SendPasswordEmail.pm [deleted file]
rt/lib/RT/Action/SetPriority.pm [new file with mode: 0644]
rt/lib/RT/Action/StallDependent.pm [deleted file]
rt/lib/RT/Action/UserDefined.pm [new file with mode: 0644]
rt/lib/RT/Attachment.pm
rt/lib/RT/Attachment_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Attachments.pm
rt/lib/RT/Attachments_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Base.pm [new file with mode: 0644]
rt/lib/RT/CachedGroupMember.pm [new file with mode: 0644]
rt/lib/RT/CachedGroupMember_Overlay.pm [new file with mode: 0644]
rt/lib/RT/CachedGroupMembers.pm [new file with mode: 0644]
rt/lib/RT/CachedGroupMembers_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Condition/AnyTransaction.pm
rt/lib/RT/Condition/BeforeDue.pm [new file with mode: 0644]
rt/lib/RT/Condition/Generic.pm
rt/lib/RT/Condition/NewDependency.pm [deleted file]
rt/lib/RT/Condition/Overdue.pm [new file with mode: 0644]
rt/lib/RT/Condition/OwnerChange.pm [new file with mode: 0644]
rt/lib/RT/Condition/PriorityExceeds.pm [new file with mode: 0644]
rt/lib/RT/Condition/QueueChange.pm [new file with mode: 0644]
rt/lib/RT/Condition/StatusChange.pm
rt/lib/RT/Condition/UserDefined.pm [new file with mode: 0644]
rt/lib/RT/CurrentUser.pm
rt/lib/RT/CustomField.pm [new file with mode: 0644]
rt/lib/RT/CustomFieldValue.pm [new file with mode: 0644]
rt/lib/RT/CustomFieldValues.pm [new file with mode: 0644]
rt/lib/RT/CustomFieldValues_Overlay.pm [new file with mode: 0644]
rt/lib/RT/CustomField_Overlay.pm [new file with mode: 0644]
rt/lib/RT/CustomFields.pm [new file with mode: 0644]
rt/lib/RT/CustomFields_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Date.pm
rt/lib/RT/EasySearch.pm [deleted file]
rt/lib/RT/EmailParser.pm [new file with mode: 0644]
rt/lib/RT/Group.pm
rt/lib/RT/GroupMember.pm
rt/lib/RT/GroupMember_Overlay.pm [new file with mode: 0644]
rt/lib/RT/GroupMembers.pm
rt/lib/RT/GroupMembers_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Group_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Groups.pm
rt/lib/RT/Groups_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Handle.pm
rt/lib/RT/I18N.pm [new file with mode: 0644]
rt/lib/RT/I18N/cs.pm [new file with mode: 0644]
rt/lib/RT/I18N/cs.po [new file with mode: 0644]
rt/lib/RT/I18N/de.po [new file with mode: 0644]
rt/lib/RT/I18N/en.po [new file with mode: 0644]
rt/lib/RT/I18N/es.po [new file with mode: 0644]
rt/lib/RT/I18N/fi.po [new file with mode: 0644]
rt/lib/RT/I18N/fr.po [new file with mode: 0644]
rt/lib/RT/I18N/he.po [new file with mode: 0644]
rt/lib/RT/I18N/i_default.pm [new file with mode: 0644]
rt/lib/RT/I18N/ja.po [new file with mode: 0644]
rt/lib/RT/I18N/nl.po [new file with mode: 0644]
rt/lib/RT/I18N/no.po [new file with mode: 0644]
rt/lib/RT/I18N/pt_br.po [new file with mode: 0644]
rt/lib/RT/I18N/ru.po [new file with mode: 0644]
rt/lib/RT/I18N/zh_cn.po [new file with mode: 0644]
rt/lib/RT/I18N/zh_tw.po [new file with mode: 0644]
rt/lib/RT/Interface/CLI.pm
rt/lib/RT/Interface/Email.pm
rt/lib/RT/Interface/Email/Auth/MailFrom.pm [new file with mode: 0644]
rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm [new file with mode: 0644]
rt/lib/RT/Interface/Web.pm
rt/lib/RT/Keyword.pm [deleted file]
rt/lib/RT/KeywordSelect.pm [deleted file]
rt/lib/RT/KeywordSelects.pm [deleted file]
rt/lib/RT/Keywords.pm [deleted file]
rt/lib/RT/Link.pm
rt/lib/RT/Link_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Links.pm
rt/lib/RT/Links_Overlay.pm [new file with mode: 0644]
rt/lib/RT/ObjectKeyword.pm [deleted file]
rt/lib/RT/ObjectKeywords.pm [deleted file]
rt/lib/RT/Principal.pm [new file with mode: 0644]
rt/lib/RT/Principal_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Principals.pm [new file with mode: 0644]
rt/lib/RT/Principals_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Queue.pm
rt/lib/RT/Queue_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Queues.pm
rt/lib/RT/Queues_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Record.pm
rt/lib/RT/Scrip.pm
rt/lib/RT/ScripAction.pm
rt/lib/RT/ScripAction_Overlay.pm [new file with mode: 0644]
rt/lib/RT/ScripActions.pm
rt/lib/RT/ScripActions_Overlay.pm [new file with mode: 0644]
rt/lib/RT/ScripCondition.pm
rt/lib/RT/ScripCondition_Overlay.pm [new file with mode: 0644]
rt/lib/RT/ScripConditions.pm
rt/lib/RT/ScripConditions_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Scrip_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Scrips.pm
rt/lib/RT/Scrips_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Search/ActiveTicketsInQueue.pm [new file with mode: 0644]
rt/lib/RT/Search/Generic.pm [new file with mode: 0644]
rt/lib/RT/SearchBuilder.pm [new file with mode: 0644]
rt/lib/RT/System.pm [new file with mode: 0644]
rt/lib/RT/Template.pm
rt/lib/RT/Template_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Templates.pm
rt/lib/RT/Templates_Overlay.pm [new file with mode: 0644]
rt/lib/RT/TestHarness.pm [deleted file]
rt/lib/RT/Ticket.pm
rt/lib/RT/TicketCustomFieldValue.pm [new file with mode: 0644]
rt/lib/RT/TicketCustomFieldValue_Overlay.pm [new file with mode: 0644]
rt/lib/RT/TicketCustomFieldValues.pm [new file with mode: 0644]
rt/lib/RT/TicketCustomFieldValues_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Ticket_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Tickets.pm
rt/lib/RT/Tickets_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Tickets_Overlay_SQL.pm [new file with mode: 0644]
rt/lib/RT/Transaction.pm
rt/lib/RT/Transaction_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Transactions.pm
rt/lib/RT/Transactions_Overlay.pm [new file with mode: 0644]
rt/lib/RT/URI.pm [new file with mode: 0644]
rt/lib/RT/URI/base.pm [new file with mode: 0644]
rt/lib/RT/URI/fsck_com_rt.pm [new file with mode: 0644]
rt/lib/RT/User.pm
rt/lib/RT/User_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Users.pm
rt/lib/RT/Users_Overlay.pm [new file with mode: 0644]
rt/lib/RT/Watcher.pm [deleted file]
rt/lib/RT/Watchers.pm [deleted file]
rt/lib/t/00smoke.t [new file with mode: 0644]
rt/lib/t/00smoke.t.in [new file with mode: 0644]
rt/lib/t/01harness.t [new file with mode: 0644]
rt/lib/t/01harness.t.in [new file with mode: 0644]
rt/lib/t/02regression.t [new file with mode: 0644]
rt/lib/t/02regression.t.in [new file with mode: 0644]
rt/lib/t/03web.pl [new file with mode: 0644]
rt/lib/t/03web.pl.in [new file with mode: 0644]
rt/lib/t/04_send_email.pl [new file with mode: 0644]
rt/lib/t/04_send_email.pl.in [new file with mode: 0644]
rt/lib/t/data/8859-15-message-series/dir [new file with mode: 0644]
rt/lib/t/data/8859-15-message-series/msg1 [new file with mode: 0644]
rt/lib/t/data/8859-15-message-series/msg2 [new file with mode: 0644]
rt/lib/t/data/8859-15-message-series/msg3 [new file with mode: 0644]
rt/lib/t/data/8859-15-message-series/msg4 [new file with mode: 0644]
rt/lib/t/data/8859-15-message-series/msg5 [new file with mode: 0644]
rt/lib/t/data/8859-15-message-series/msg6 [new file with mode: 0644]
rt/lib/t/data/8859-15-message-series/msg7 [new file with mode: 0644]
rt/lib/t/data/multipart-alternative-with-umlaut [new file with mode: 0644]
rt/lib/t/data/nested-mime-sample [new file with mode: 0644]
rt/lib/t/data/nested-rfc-822 [new file with mode: 0644]
rt/lib/t/data/new-ticket-from-iso-8859-1 [new file with mode: 0644]
rt/lib/t/data/new-ticket-from-iso-8859-1-full [new file with mode: 0644]
rt/lib/t/data/russian-subject-no-content-type [new file with mode: 0644]
rt/lib/t/data/text-html-in-russian [new file with mode: 0644]
rt/lib/t/data/text-html-with-umlaut [new file with mode: 0644]
rt/lib/t/regression/00placeholder [new file with mode: 0644]
rt/lib/t/regression/mime_tests [new file with mode: 0644]
rt/lib/test.pl [deleted file]
rt/m4/rt_enable_layout.m4 [new file with mode: 0644]
rt/m4/rt_expand_var.m4 [new file with mode: 0644]
rt/m4/rt_layout.m4 [new file with mode: 0644]
rt/m4/rt_subst_expanded_arg.m4 [new file with mode: 0644]
rt/sbin/extract-message-catalog [new file with mode: 0644]
rt/sbin/extract_pod_tests [new file with mode: 0644]
rt/sbin/factory [new file with mode: 0644]
rt/sbin/license_tag [new file with mode: 0644]
rt/sbin/regression_harness [new file with mode: 0644]
rt/sbin/rt-setup-database [new file with mode: 0644]
rt/sbin/rt-setup-database.in [new file with mode: 0644]
rt/sbin/rt-test-dependencies [new file with mode: 0644]
rt/sbin/rt-test-dependencies.in [new file with mode: 0644]
rt/tools/cpan2rpm [deleted file]
rt/tools/initdb [deleted file]
rt/tools/insertdata [deleted file]
rt/tools/testdeps [deleted file]
rt/webrt/Admin/Elements/CreateQueueCalled [deleted file]
rt/webrt/Admin/Elements/CreateUserCalled [deleted file]
rt/webrt/Admin/Elements/EditUserComments [deleted file]
rt/webrt/Admin/Elements/GrantQueueRightsTo [deleted file]
rt/webrt/Admin/Elements/GroupTabs [deleted file]
rt/webrt/Admin/Elements/Header [deleted file]
rt/webrt/Admin/Elements/ListGlobalKeywordSelects [deleted file]
rt/webrt/Admin/Elements/ListGlobalScrips [deleted file]
rt/webrt/Admin/Elements/ModifyKeyword [deleted file]
rt/webrt/Admin/Elements/ModifyKeywordSelect [deleted file]
rt/webrt/Admin/Elements/ModifyQueue [deleted file]
rt/webrt/Admin/Elements/ModifyTemplate [deleted file]
rt/webrt/Admin/Elements/ModifyUser [deleted file]
rt/webrt/Admin/Elements/QueueRightsForUser [deleted file]
rt/webrt/Admin/Elements/QueueTabs [deleted file]
rt/webrt/Admin/Elements/SelectKeywordSelect [deleted file]
rt/webrt/Admin/Elements/SelectModifyGroup [deleted file]
rt/webrt/Admin/Elements/SelectModifyKeyword [deleted file]
rt/webrt/Admin/Elements/SelectModifyKeywordSelect [deleted file]
rt/webrt/Admin/Elements/SelectModifyQueue [deleted file]
rt/webrt/Admin/Elements/SelectModifyUser [deleted file]
rt/webrt/Admin/Elements/SelectQueueRights [deleted file]
rt/webrt/Admin/Elements/SelectRights [deleted file]
rt/webrt/Admin/Elements/SelectScrip [deleted file]
rt/webrt/Admin/Elements/SelectScripAction [deleted file]
rt/webrt/Admin/Elements/SelectScripCondition [deleted file]
rt/webrt/Admin/Elements/SelectSingleOrMultiple [deleted file]
rt/webrt/Admin/Elements/SelectTemplate [deleted file]
rt/webrt/Admin/Elements/SelectUsers [deleted file]
rt/webrt/Admin/Elements/SystemTabs [deleted file]
rt/webrt/Admin/Elements/Tabs [deleted file]
rt/webrt/Admin/Elements/UserTabs [deleted file]
rt/webrt/Admin/Global/GroupRights.html [deleted file]
rt/webrt/Admin/Global/Keywords.html [deleted file]
rt/webrt/Admin/Global/Scrips.html [deleted file]
rt/webrt/Admin/Global/Template.html [deleted file]
rt/webrt/Admin/Global/Templates.html [deleted file]
rt/webrt/Admin/Global/UserRights.html [deleted file]
rt/webrt/Admin/Global/index.html [deleted file]
rt/webrt/Admin/Groups/Members.html [deleted file]
rt/webrt/Admin/Groups/Modify.html [deleted file]
rt/webrt/Admin/Groups/Rights.html [deleted file]
rt/webrt/Admin/Groups/index.html [deleted file]
rt/webrt/Admin/KeywordSelects/Modify.html [deleted file]
rt/webrt/Admin/KeywordSelects/index.html [deleted file]
rt/webrt/Admin/Keywords/Modify.html [deleted file]
rt/webrt/Admin/Keywords/index.html [deleted file]
rt/webrt/Admin/Queues/Create.html [deleted file]
rt/webrt/Admin/Queues/GroupRights.html [deleted file]
rt/webrt/Admin/Queues/Keywords.html [deleted file]
rt/webrt/Admin/Queues/Modify.html [deleted file]
rt/webrt/Admin/Queues/People.html [deleted file]
rt/webrt/Admin/Queues/Scrips.html [deleted file]
rt/webrt/Admin/Queues/Template.html [deleted file]
rt/webrt/Admin/Queues/Templates.html [deleted file]
rt/webrt/Admin/Queues/UserRights.html [deleted file]
rt/webrt/Admin/Queues/index.html [deleted file]
rt/webrt/Admin/Users/Modify.html [deleted file]
rt/webrt/Admin/Users/Prefs.html [deleted file]
rt/webrt/Admin/Users/Rights.html [deleted file]
rt/webrt/Admin/Users/index.html [deleted file]
rt/webrt/Admin/index.html [deleted file]
rt/webrt/Elements/Checkbox [deleted file]
rt/webrt/Elements/CreateTicket [deleted file]
rt/webrt/Elements/CustomHomepageHeader [deleted file]
rt/webrt/Elements/Error [deleted file]
rt/webrt/Elements/Footer [deleted file]
rt/webrt/Elements/GotoTicket [deleted file]
rt/webrt/Elements/Header [deleted file]
rt/webrt/Elements/ListActions [deleted file]
rt/webrt/Elements/Login [deleted file]
rt/webrt/Elements/MessageBox [deleted file]
rt/webrt/Elements/MyRequests [deleted file]
rt/webrt/Elements/MyTickets [deleted file]
rt/webrt/Elements/Quicksearch [deleted file]
rt/webrt/Elements/Refresh [deleted file]
rt/webrt/Elements/Section [deleted file]
rt/webrt/Elements/SelectBoolean [deleted file]
rt/webrt/Elements/SelectDate [deleted file]
rt/webrt/Elements/SelectDateRelation [deleted file]
rt/webrt/Elements/SelectDateType [deleted file]
rt/webrt/Elements/SelectEqualityOperator [deleted file]
rt/webrt/Elements/SelectKeyword [deleted file]
rt/webrt/Elements/SelectKeywordOptions [deleted file]
rt/webrt/Elements/SelectLinkType [deleted file]
rt/webrt/Elements/SelectMatch [deleted file]
rt/webrt/Elements/SelectNewTicketQueue [deleted file]
rt/webrt/Elements/SelectOwner [deleted file]
rt/webrt/Elements/SelectQueue [deleted file]
rt/webrt/Elements/SelectResultsPerPage [deleted file]
rt/webrt/Elements/SelectSortOrder [deleted file]
rt/webrt/Elements/SelectStatus [deleted file]
rt/webrt/Elements/SelectTicketSortBy [deleted file]
rt/webrt/Elements/SelectUsers [deleted file]
rt/webrt/Elements/SelectWatcherType [deleted file]
rt/webrt/Elements/ShadedBox [deleted file]
rt/webrt/Elements/Submit [deleted file]
rt/webrt/Elements/Tabs [deleted file]
rt/webrt/Elements/TitleBoxEnd [deleted file]
rt/webrt/Elements/TitleBoxStart [deleted file]
rt/webrt/Elements/ViewUser [deleted file]
rt/webrt/Elements/dayMenu [deleted file]
rt/webrt/Elements/monthMenu [deleted file]
rt/webrt/Elements/yearMenu [deleted file]
rt/webrt/NoAuth/Logout.html [deleted file]
rt/webrt/NoAuth/Reminder.html [deleted file]
rt/webrt/NoAuth/images/rt.jpg [deleted file]
rt/webrt/NoAuth/images/spacer.gif [deleted file]
rt/webrt/NoAuth/webrt.css [deleted file]
rt/webrt/Search/Bulk.html [deleted file]
rt/webrt/Search/Listing.html [deleted file]
rt/webrt/Search/PickRestriction [deleted file]
rt/webrt/Search/RestrictSearch.html [deleted file]
rt/webrt/Search/TicketCell [deleted file]
rt/webrt/SelfService/Attachment/dhandler [deleted file]
rt/webrt/SelfService/Closed.html [deleted file]
rt/webrt/SelfService/Create.html [deleted file]
rt/webrt/SelfService/Display.html [deleted file]
rt/webrt/SelfService/Elements/GotoTicket [deleted file]
rt/webrt/SelfService/Elements/Header [deleted file]
rt/webrt/SelfService/Elements/MyRequests [deleted file]
rt/webrt/SelfService/Elements/Tabs [deleted file]
rt/webrt/SelfService/Error.html [deleted file]
rt/webrt/SelfService/Prefs.html [deleted file]
rt/webrt/SelfService/Update.html [deleted file]
rt/webrt/SelfService/index.html [deleted file]
rt/webrt/Ticket/Attachment/dhandler [deleted file]
rt/webrt/Ticket/Create.html [deleted file]
rt/webrt/Ticket/Display.html [deleted file]
rt/webrt/Ticket/Elements/AddWatchers [deleted file]
rt/webrt/Ticket/Elements/EditBasics [deleted file]
rt/webrt/Ticket/Elements/EditDates [deleted file]
rt/webrt/Ticket/Elements/EditKeywordSelects [deleted file]
rt/webrt/Ticket/Elements/EditLinks [deleted file]
rt/webrt/Ticket/Elements/EditPeople [deleted file]
rt/webrt/Ticket/Elements/EditWatchers [deleted file]
rt/webrt/Ticket/Elements/ShowBasics [deleted file]
rt/webrt/Ticket/Elements/ShowDates [deleted file]
rt/webrt/Ticket/Elements/ShowDependencies [deleted file]
rt/webrt/Ticket/Elements/ShowHistory [deleted file]
rt/webrt/Ticket/Elements/ShowKeywordSelects [deleted file]
rt/webrt/Ticket/Elements/ShowLinks [deleted file]
rt/webrt/Ticket/Elements/ShowMemberOf [deleted file]
rt/webrt/Ticket/Elements/ShowMembers [deleted file]
rt/webrt/Ticket/Elements/ShowPeople [deleted file]
rt/webrt/Ticket/Elements/ShowReferences [deleted file]
rt/webrt/Ticket/Elements/ShowRequestor [deleted file]
rt/webrt/Ticket/Elements/ShowSummary [deleted file]
rt/webrt/Ticket/Elements/ShowTransaction [deleted file]
rt/webrt/Ticket/Elements/Tabs [deleted file]
rt/webrt/Ticket/Elements/ToolBar [deleted file]
rt/webrt/Ticket/History.html [deleted file]
rt/webrt/Ticket/Modify.html [deleted file]
rt/webrt/Ticket/ModifyAll.html [deleted file]
rt/webrt/Ticket/ModifyDates.html [deleted file]
rt/webrt/Ticket/ModifyLinks.html [deleted file]
rt/webrt/Ticket/ModifyPeople.html [deleted file]
rt/webrt/Ticket/Update.html [deleted file]
rt/webrt/User/Prefs.html [deleted file]
rt/webrt/autohandler [deleted file]
rt/webrt/index.html [deleted file]
sql-ledger/SL/AM.pm [new file with mode: 0644]
sql-ledger/SL/AP.pm [new file with mode: 0644]
sql-ledger/SL/AR.pm [new file with mode: 0644]
sql-ledger/SL/CA.pm [new file with mode: 0644]
sql-ledger/SL/CP.pm [new file with mode: 0644]
sql-ledger/SL/CT.pm [new file with mode: 0644]
sql-ledger/SL/Form.pm [new file with mode: 0644]
sql-ledger/SL/GL.pm [new file with mode: 0644]
sql-ledger/SL/IC.pm [new file with mode: 0644]
sql-ledger/SL/IR.pm [new file with mode: 0644]
sql-ledger/SL/IS.pm [new file with mode: 0644]
sql-ledger/SL/Inifile.pm [new file with mode: 0644]
sql-ledger/SL/Mailer.pm [new file with mode: 0644]
sql-ledger/SL/Menu.pm [new file with mode: 0644]
sql-ledger/SL/Num2text.pm [new file with mode: 0644]
sql-ledger/SL/OE.pm [new file with mode: 0644]
sql-ledger/SL/PE.pm [new file with mode: 0644]
sql-ledger/SL/RC.pm [new file with mode: 0644]
sql-ledger/SL/RP.pm [new file with mode: 0644]
sql-ledger/SL/User.pm [new file with mode: 0644]
sql-ledger/VERSION [new file with mode: 0644]
sql-ledger/am.pl [new file with mode: 0755]
sql-ledger/bin/lynx/menu.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/admin.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/am.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/ap.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/ar.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/arap.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/ca.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/cp.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/ct.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/gl.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/ic.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/io.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/ir.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/is.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/login.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/menu.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/oe.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/pe.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/rc.pl [new file with mode: 0644]
sql-ledger/bin/mozilla/rp.pl [new file with mode: 0644]
sql-ledger/css/sql-ledger.css [new file with mode: 0644]
sql-ledger/doc/COPYING [new file with mode: 0644]
sql-ledger/doc/README [new file with mode: 0644]
sql-ledger/doc/UPGRADE-1.6-1.8 [new file with mode: 0644]
sql-ledger/doc/UPGRADE-1.8-1.8.3 [new file with mode: 0644]
sql-ledger/doc/UPGRADE-1.8.3-1.8.4 [new file with mode: 0644]
sql-ledger/doc/UPGRADE-1.8.4-1.8.5 [new file with mode: 0644]
sql-ledger/doc/UPGRADE-1.8.5-1.8.7 [new file with mode: 0644]
sql-ledger/doc/UPGRADE-1.8.7-2.0.0 [new file with mode: 0644]
sql-ledger/doc/UPGRADE-2.0-2.0.8 [new file with mode: 0644]
sql-ledger/doc/copyright [new file with mode: 0644]
sql-ledger/doc/faq.html [new file with mode: 0644]
sql-ledger/favicon.ico [new file with mode: 0644]
sql-ledger/locale/br/COPYING [new file with mode: 0644]
sql-ledger/locale/br/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/br/admin [new file with mode: 0644]
sql-ledger/locale/br/all [new file with mode: 0644]
sql-ledger/locale/br/am [new file with mode: 0644]
sql-ledger/locale/br/ap [new file with mode: 0644]
sql-ledger/locale/br/ar [new file with mode: 0644]
sql-ledger/locale/br/arap [new file with mode: 0644]
sql-ledger/locale/br/ca [new file with mode: 0644]
sql-ledger/locale/br/cp [new file with mode: 0644]
sql-ledger/locale/br/ct [new file with mode: 0644]
sql-ledger/locale/br/gl [new file with mode: 0644]
sql-ledger/locale/br/ic [new file with mode: 0644]
sql-ledger/locale/br/io [new file with mode: 0644]
sql-ledger/locale/br/ir [new file with mode: 0644]
sql-ledger/locale/br/is [new file with mode: 0644]
sql-ledger/locale/br/login [new file with mode: 0644]
sql-ledger/locale/br/menu [new file with mode: 0644]
sql-ledger/locale/br/oe [new file with mode: 0644]
sql-ledger/locale/br/pe [new file with mode: 0644]
sql-ledger/locale/br/rc [new file with mode: 0644]
sql-ledger/locale/br/rp [new file with mode: 0644]
sql-ledger/locale/cn/COPYING [new file with mode: 0644]
sql-ledger/locale/cn/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/cn/admin [new file with mode: 0644]
sql-ledger/locale/cn/all [new file with mode: 0644]
sql-ledger/locale/cn/am [new file with mode: 0644]
sql-ledger/locale/cn/ap [new file with mode: 0644]
sql-ledger/locale/cn/ar [new file with mode: 0644]
sql-ledger/locale/cn/arap [new file with mode: 0644]
sql-ledger/locale/cn/ca [new file with mode: 0644]
sql-ledger/locale/cn/cp [new file with mode: 0644]
sql-ledger/locale/cn/ct [new file with mode: 0644]
sql-ledger/locale/cn/gl [new file with mode: 0644]
sql-ledger/locale/cn/ic [new file with mode: 0644]
sql-ledger/locale/cn/io [new file with mode: 0644]
sql-ledger/locale/cn/ir [new file with mode: 0644]
sql-ledger/locale/cn/is [new file with mode: 0644]
sql-ledger/locale/cn/login [new file with mode: 0644]
sql-ledger/locale/cn/menu [new file with mode: 0644]
sql-ledger/locale/cn/oe [new file with mode: 0644]
sql-ledger/locale/cn/pe [new file with mode: 0644]
sql-ledger/locale/cn/rc [new file with mode: 0644]
sql-ledger/locale/cn/rp [new file with mode: 0644]
sql-ledger/locale/ct/COPYING [new file with mode: 0644]
sql-ledger/locale/ct/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/ct/admin [new file with mode: 0644]
sql-ledger/locale/ct/all [new file with mode: 0644]
sql-ledger/locale/ct/am [new file with mode: 0644]
sql-ledger/locale/ct/ap [new file with mode: 0644]
sql-ledger/locale/ct/ar [new file with mode: 0644]
sql-ledger/locale/ct/arap [new file with mode: 0644]
sql-ledger/locale/ct/ca [new file with mode: 0644]
sql-ledger/locale/ct/cp [new file with mode: 0644]
sql-ledger/locale/ct/ct [new file with mode: 0644]
sql-ledger/locale/ct/gl [new file with mode: 0644]
sql-ledger/locale/ct/ic [new file with mode: 0644]
sql-ledger/locale/ct/io [new file with mode: 0644]
sql-ledger/locale/ct/ir [new file with mode: 0644]
sql-ledger/locale/ct/is [new file with mode: 0644]
sql-ledger/locale/ct/login [new file with mode: 0644]
sql-ledger/locale/ct/menu [new file with mode: 0644]
sql-ledger/locale/ct/oe [new file with mode: 0644]
sql-ledger/locale/ct/pe [new file with mode: 0644]
sql-ledger/locale/ct/rc [new file with mode: 0644]
sql-ledger/locale/ct/rp [new file with mode: 0644]
sql-ledger/locale/cz/COPYING [new file with mode: 0644]
sql-ledger/locale/cz/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/cz/admin [new file with mode: 0644]
sql-ledger/locale/cz/all [new file with mode: 0644]
sql-ledger/locale/cz/am [new file with mode: 0644]
sql-ledger/locale/cz/ap [new file with mode: 0644]
sql-ledger/locale/cz/ar [new file with mode: 0644]
sql-ledger/locale/cz/arap [new file with mode: 0644]
sql-ledger/locale/cz/ca [new file with mode: 0644]
sql-ledger/locale/cz/cp [new file with mode: 0644]
sql-ledger/locale/cz/ct [new file with mode: 0644]
sql-ledger/locale/cz/gl [new file with mode: 0644]
sql-ledger/locale/cz/ic [new file with mode: 0644]
sql-ledger/locale/cz/io [new file with mode: 0644]
sql-ledger/locale/cz/ir [new file with mode: 0644]
sql-ledger/locale/cz/is [new file with mode: 0644]
sql-ledger/locale/cz/login [new file with mode: 0644]
sql-ledger/locale/cz/menu [new file with mode: 0644]
sql-ledger/locale/cz/oe [new file with mode: 0644]
sql-ledger/locale/cz/pe [new file with mode: 0644]
sql-ledger/locale/cz/rc [new file with mode: 0644]
sql-ledger/locale/cz/rp [new file with mode: 0644]
sql-ledger/locale/de/COPYING [new file with mode: 0644]
sql-ledger/locale/de/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/de/Num2text [new file with mode: 0644]
sql-ledger/locale/de/admin [new file with mode: 0644]
sql-ledger/locale/de/all [new file with mode: 0644]
sql-ledger/locale/de/am [new file with mode: 0644]
sql-ledger/locale/de/ap [new file with mode: 0644]
sql-ledger/locale/de/ar [new file with mode: 0644]
sql-ledger/locale/de/arap [new file with mode: 0644]
sql-ledger/locale/de/ca [new file with mode: 0644]
sql-ledger/locale/de/cp [new file with mode: 0644]
sql-ledger/locale/de/ct [new file with mode: 0644]
sql-ledger/locale/de/gl [new file with mode: 0644]
sql-ledger/locale/de/ic [new file with mode: 0644]
sql-ledger/locale/de/io [new file with mode: 0644]
sql-ledger/locale/de/ir [new file with mode: 0644]
sql-ledger/locale/de/is [new file with mode: 0644]
sql-ledger/locale/de/locales.pl [new file with mode: 0755]
sql-ledger/locale/de/login [new file with mode: 0644]
sql-ledger/locale/de/menu [new file with mode: 0644]
sql-ledger/locale/de/oe [new file with mode: 0644]
sql-ledger/locale/de/pe [new file with mode: 0644]
sql-ledger/locale/de/rc [new file with mode: 0644]
sql-ledger/locale/de/rp [new file with mode: 0644]
sql-ledger/locale/dk/COPYING [new file with mode: 0644]
sql-ledger/locale/dk/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/dk/admin [new file with mode: 0644]
sql-ledger/locale/dk/all [new file with mode: 0644]
sql-ledger/locale/dk/am [new file with mode: 0644]
sql-ledger/locale/dk/ap [new file with mode: 0644]
sql-ledger/locale/dk/ar [new file with mode: 0644]
sql-ledger/locale/dk/arap [new file with mode: 0644]
sql-ledger/locale/dk/ca [new file with mode: 0644]
sql-ledger/locale/dk/cp [new file with mode: 0644]
sql-ledger/locale/dk/ct [new file with mode: 0644]
sql-ledger/locale/dk/gl [new file with mode: 0644]
sql-ledger/locale/dk/ic [new file with mode: 0644]
sql-ledger/locale/dk/io [new file with mode: 0644]
sql-ledger/locale/dk/ir [new file with mode: 0644]
sql-ledger/locale/dk/is [new file with mode: 0644]
sql-ledger/locale/dk/login [new file with mode: 0644]
sql-ledger/locale/dk/menu [new file with mode: 0644]
sql-ledger/locale/dk/oe [new file with mode: 0644]
sql-ledger/locale/dk/pe [new file with mode: 0644]
sql-ledger/locale/dk/rc [new file with mode: 0644]
sql-ledger/locale/dk/rp [new file with mode: 0644]
sql-ledger/locale/ee/COPYING [new file with mode: 0644]
sql-ledger/locale/ee/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/ee/admin [new file with mode: 0644]
sql-ledger/locale/ee/all [new file with mode: 0644]
sql-ledger/locale/ee/am [new file with mode: 0644]
sql-ledger/locale/ee/ap [new file with mode: 0644]
sql-ledger/locale/ee/ar [new file with mode: 0644]
sql-ledger/locale/ee/arap [new file with mode: 0644]
sql-ledger/locale/ee/ca [new file with mode: 0644]
sql-ledger/locale/ee/cp [new file with mode: 0644]
sql-ledger/locale/ee/ct [new file with mode: 0644]
sql-ledger/locale/ee/gl [new file with mode: 0644]
sql-ledger/locale/ee/ic [new file with mode: 0644]
sql-ledger/locale/ee/io [new file with mode: 0644]
sql-ledger/locale/ee/ir [new file with mode: 0644]
sql-ledger/locale/ee/is [new file with mode: 0644]
sql-ledger/locale/ee/login [new file with mode: 0644]
sql-ledger/locale/ee/menu [new file with mode: 0644]
sql-ledger/locale/ee/oe [new file with mode: 0644]
sql-ledger/locale/ee/pe [new file with mode: 0644]
sql-ledger/locale/ee/rc [new file with mode: 0644]
sql-ledger/locale/ee/rp [new file with mode: 0644]
sql-ledger/locale/en_GB/COPYING [new file with mode: 0644]
sql-ledger/locale/en_GB/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/en_GB/admin [new file with mode: 0644]
sql-ledger/locale/en_GB/all [new file with mode: 0644]
sql-ledger/locale/en_GB/am [new file with mode: 0644]
sql-ledger/locale/en_GB/ap [new file with mode: 0644]
sql-ledger/locale/en_GB/ar [new file with mode: 0644]
sql-ledger/locale/en_GB/arap [new file with mode: 0644]
sql-ledger/locale/en_GB/bp [new file with mode: 0644]
sql-ledger/locale/en_GB/ca [new file with mode: 0644]
sql-ledger/locale/en_GB/cp [new file with mode: 0644]
sql-ledger/locale/en_GB/ct [new file with mode: 0644]
sql-ledger/locale/en_GB/gl [new file with mode: 0644]
sql-ledger/locale/en_GB/ic [new file with mode: 0644]
sql-ledger/locale/en_GB/io [new file with mode: 0644]
sql-ledger/locale/en_GB/ir [new file with mode: 0644]
sql-ledger/locale/en_GB/is [new file with mode: 0644]
sql-ledger/locale/en_GB/login [new file with mode: 0644]
sql-ledger/locale/en_GB/menu [new file with mode: 0644]
sql-ledger/locale/en_GB/oe [new file with mode: 0644]
sql-ledger/locale/en_GB/pe [new file with mode: 0644]
sql-ledger/locale/en_GB/rc [new file with mode: 0644]
sql-ledger/locale/en_GB/rp [new file with mode: 0644]
sql-ledger/locale/es/COPYING [new file with mode: 0644]
sql-ledger/locale/es/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/es/Num2text [new file with mode: 0644]
sql-ledger/locale/es/admin [new file with mode: 0644]
sql-ledger/locale/es/all [new file with mode: 0644]
sql-ledger/locale/es/am [new file with mode: 0644]
sql-ledger/locale/es/ap [new file with mode: 0644]
sql-ledger/locale/es/ar [new file with mode: 0644]
sql-ledger/locale/es/arap [new file with mode: 0644]
sql-ledger/locale/es/ca [new file with mode: 0644]
sql-ledger/locale/es/cp [new file with mode: 0644]
sql-ledger/locale/es/ct [new file with mode: 0644]
sql-ledger/locale/es/gl [new file with mode: 0644]
sql-ledger/locale/es/ic [new file with mode: 0644]
sql-ledger/locale/es/io [new file with mode: 0644]
sql-ledger/locale/es/ir [new file with mode: 0644]
sql-ledger/locale/es/is [new file with mode: 0644]
sql-ledger/locale/es/login [new file with mode: 0644]
sql-ledger/locale/es/menu [new file with mode: 0644]
sql-ledger/locale/es/oe [new file with mode: 0644]
sql-ledger/locale/es/pe [new file with mode: 0644]
sql-ledger/locale/es/rc [new file with mode: 0644]
sql-ledger/locale/es/rp [new file with mode: 0644]
sql-ledger/locale/fi/COPYING [new file with mode: 0644]
sql-ledger/locale/fi/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/fi/admin [new file with mode: 0644]
sql-ledger/locale/fi/all [new file with mode: 0644]
sql-ledger/locale/fi/am [new file with mode: 0644]
sql-ledger/locale/fi/ap [new file with mode: 0644]
sql-ledger/locale/fi/ar [new file with mode: 0644]
sql-ledger/locale/fi/arap [new file with mode: 0644]
sql-ledger/locale/fi/ca [new file with mode: 0644]
sql-ledger/locale/fi/cp [new file with mode: 0644]
sql-ledger/locale/fi/ct [new file with mode: 0644]
sql-ledger/locale/fi/gl [new file with mode: 0644]
sql-ledger/locale/fi/ic [new file with mode: 0644]
sql-ledger/locale/fi/io [new file with mode: 0644]
sql-ledger/locale/fi/ir [new file with mode: 0644]
sql-ledger/locale/fi/is [new file with mode: 0644]
sql-ledger/locale/fi/login [new file with mode: 0644]
sql-ledger/locale/fi/menu [new file with mode: 0644]
sql-ledger/locale/fi/oe [new file with mode: 0644]
sql-ledger/locale/fi/pe [new file with mode: 0644]
sql-ledger/locale/fi/rc [new file with mode: 0644]
sql-ledger/locale/fi/rp [new file with mode: 0644]
sql-ledger/locale/fr/COPYING [new file with mode: 0644]
sql-ledger/locale/fr/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/fr/admin [new file with mode: 0644]
sql-ledger/locale/fr/all [new file with mode: 0644]
sql-ledger/locale/fr/am [new file with mode: 0644]
sql-ledger/locale/fr/ap [new file with mode: 0644]
sql-ledger/locale/fr/ar [new file with mode: 0644]
sql-ledger/locale/fr/arap [new file with mode: 0644]
sql-ledger/locale/fr/ca [new file with mode: 0644]
sql-ledger/locale/fr/cp [new file with mode: 0644]
sql-ledger/locale/fr/ct [new file with mode: 0644]
sql-ledger/locale/fr/gl [new file with mode: 0644]
sql-ledger/locale/fr/ic [new file with mode: 0644]
sql-ledger/locale/fr/io [new file with mode: 0644]
sql-ledger/locale/fr/ir [new file with mode: 0644]
sql-ledger/locale/fr/is [new file with mode: 0644]
sql-ledger/locale/fr/login [new file with mode: 0644]
sql-ledger/locale/fr/menu [new file with mode: 0644]
sql-ledger/locale/fr/oe [new file with mode: 0644]
sql-ledger/locale/fr/pe [new file with mode: 0644]
sql-ledger/locale/fr/rc [new file with mode: 0644]
sql-ledger/locale/fr/rp [new file with mode: 0644]
sql-ledger/locale/hu/COPYING [new file with mode: 0644]
sql-ledger/locale/hu/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/hu/admin [new file with mode: 0644]
sql-ledger/locale/hu/all [new file with mode: 0644]
sql-ledger/locale/hu/am [new file with mode: 0644]
sql-ledger/locale/hu/ap [new file with mode: 0644]
sql-ledger/locale/hu/ar [new file with mode: 0644]
sql-ledger/locale/hu/arap [new file with mode: 0644]
sql-ledger/locale/hu/ca [new file with mode: 0644]
sql-ledger/locale/hu/cp [new file with mode: 0644]
sql-ledger/locale/hu/ct [new file with mode: 0644]
sql-ledger/locale/hu/gl [new file with mode: 0644]
sql-ledger/locale/hu/ic [new file with mode: 0644]
sql-ledger/locale/hu/io [new file with mode: 0644]
sql-ledger/locale/hu/ir [new file with mode: 0644]
sql-ledger/locale/hu/is [new file with mode: 0644]
sql-ledger/locale/hu/login [new file with mode: 0644]
sql-ledger/locale/hu/menu [new file with mode: 0644]
sql-ledger/locale/hu/oe [new file with mode: 0644]
sql-ledger/locale/hu/pe [new file with mode: 0644]
sql-ledger/locale/hu/rc [new file with mode: 0644]
sql-ledger/locale/hu/rp [new file with mode: 0644]
sql-ledger/locale/is/COPYING [new file with mode: 0644]
sql-ledger/locale/is/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/is/admin [new file with mode: 0644]
sql-ledger/locale/is/all [new file with mode: 0644]
sql-ledger/locale/is/am [new file with mode: 0644]
sql-ledger/locale/is/ap [new file with mode: 0644]
sql-ledger/locale/is/ar [new file with mode: 0644]
sql-ledger/locale/is/arap [new file with mode: 0644]
sql-ledger/locale/is/ca [new file with mode: 0644]
sql-ledger/locale/is/cp [new file with mode: 0644]
sql-ledger/locale/is/ct [new file with mode: 0644]
sql-ledger/locale/is/gl [new file with mode: 0644]
sql-ledger/locale/is/ic [new file with mode: 0644]
sql-ledger/locale/is/io [new file with mode: 0644]
sql-ledger/locale/is/ir [new file with mode: 0644]
sql-ledger/locale/is/is [new file with mode: 0644]
sql-ledger/locale/is/login [new file with mode: 0644]
sql-ledger/locale/is/menu [new file with mode: 0644]
sql-ledger/locale/is/oe [new file with mode: 0644]
sql-ledger/locale/is/pe [new file with mode: 0644]
sql-ledger/locale/is/rc [new file with mode: 0644]
sql-ledger/locale/is/rp [new file with mode: 0644]
sql-ledger/locale/it/COPYING [new file with mode: 0644]
sql-ledger/locale/it/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/it/Num2text [new file with mode: 0644]
sql-ledger/locale/it/admin [new file with mode: 0644]
sql-ledger/locale/it/all [new file with mode: 0644]
sql-ledger/locale/it/am [new file with mode: 0644]
sql-ledger/locale/it/ap [new file with mode: 0644]
sql-ledger/locale/it/ar [new file with mode: 0644]
sql-ledger/locale/it/arap [new file with mode: 0644]
sql-ledger/locale/it/ca [new file with mode: 0644]
sql-ledger/locale/it/cp [new file with mode: 0644]
sql-ledger/locale/it/ct [new file with mode: 0644]
sql-ledger/locale/it/gl [new file with mode: 0644]
sql-ledger/locale/it/ic [new file with mode: 0644]
sql-ledger/locale/it/io [new file with mode: 0644]
sql-ledger/locale/it/ir [new file with mode: 0644]
sql-ledger/locale/it/is [new file with mode: 0644]
sql-ledger/locale/it/login [new file with mode: 0644]
sql-ledger/locale/it/menu [new file with mode: 0644]
sql-ledger/locale/it/oe [new file with mode: 0644]
sql-ledger/locale/it/pe [new file with mode: 0644]
sql-ledger/locale/it/qe [new file with mode: 0644]
sql-ledger/locale/it/rc [new file with mode: 0644]
sql-ledger/locale/it/rp [new file with mode: 0644]
sql-ledger/locale/lt/COPYING [new file with mode: 0644]
sql-ledger/locale/lt/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/lt/admin [new file with mode: 0644]
sql-ledger/locale/lt/all [new file with mode: 0644]
sql-ledger/locale/lt/am [new file with mode: 0644]
sql-ledger/locale/lt/ap [new file with mode: 0644]
sql-ledger/locale/lt/ar [new file with mode: 0644]
sql-ledger/locale/lt/arap [new file with mode: 0644]
sql-ledger/locale/lt/ca [new file with mode: 0644]
sql-ledger/locale/lt/cp [new file with mode: 0644]
sql-ledger/locale/lt/ct [new file with mode: 0644]
sql-ledger/locale/lt/gl [new file with mode: 0644]
sql-ledger/locale/lt/ic [new file with mode: 0644]
sql-ledger/locale/lt/io [new file with mode: 0644]
sql-ledger/locale/lt/ir [new file with mode: 0644]
sql-ledger/locale/lt/is [new file with mode: 0644]
sql-ledger/locale/lt/login [new file with mode: 0644]
sql-ledger/locale/lt/menu [new file with mode: 0644]
sql-ledger/locale/lt/oe [new file with mode: 0644]
sql-ledger/locale/lt/pe [new file with mode: 0644]
sql-ledger/locale/lt/rc [new file with mode: 0644]
sql-ledger/locale/lt/rp [new file with mode: 0644]
sql-ledger/locale/mx/COPYING [new file with mode: 0644]
sql-ledger/locale/mx/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/mx/admin [new file with mode: 0644]
sql-ledger/locale/mx/all [new file with mode: 0644]
sql-ledger/locale/mx/am [new file with mode: 0644]
sql-ledger/locale/mx/ap [new file with mode: 0644]
sql-ledger/locale/mx/ar [new file with mode: 0644]
sql-ledger/locale/mx/arap [new file with mode: 0644]
sql-ledger/locale/mx/ca [new file with mode: 0644]
sql-ledger/locale/mx/cp [new file with mode: 0644]
sql-ledger/locale/mx/ct [new file with mode: 0644]
sql-ledger/locale/mx/gl [new file with mode: 0644]
sql-ledger/locale/mx/ic [new file with mode: 0644]
sql-ledger/locale/mx/io [new file with mode: 0644]
sql-ledger/locale/mx/ir [new file with mode: 0644]
sql-ledger/locale/mx/is [new file with mode: 0644]
sql-ledger/locale/mx/login [new file with mode: 0644]
sql-ledger/locale/mx/menu [new file with mode: 0644]
sql-ledger/locale/mx/oe [new file with mode: 0644]
sql-ledger/locale/mx/pe [new file with mode: 0644]
sql-ledger/locale/mx/rc [new file with mode: 0644]
sql-ledger/locale/mx/rp [new file with mode: 0644]
sql-ledger/locale/nl/COPYING [new file with mode: 0644]
sql-ledger/locale/nl/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/nl/Num2text [new file with mode: 0644]
sql-ledger/locale/nl/admin [new file with mode: 0644]
sql-ledger/locale/nl/all [new file with mode: 0644]
sql-ledger/locale/nl/am [new file with mode: 0644]
sql-ledger/locale/nl/ap [new file with mode: 0644]
sql-ledger/locale/nl/ar [new file with mode: 0644]
sql-ledger/locale/nl/arap [new file with mode: 0644]
sql-ledger/locale/nl/ca [new file with mode: 0644]
sql-ledger/locale/nl/cp [new file with mode: 0644]
sql-ledger/locale/nl/ct [new file with mode: 0644]
sql-ledger/locale/nl/gl [new file with mode: 0644]
sql-ledger/locale/nl/ic [new file with mode: 0644]
sql-ledger/locale/nl/io [new file with mode: 0644]
sql-ledger/locale/nl/ir [new file with mode: 0644]
sql-ledger/locale/nl/is [new file with mode: 0644]
sql-ledger/locale/nl/login [new file with mode: 0644]
sql-ledger/locale/nl/menu [new file with mode: 0644]
sql-ledger/locale/nl/oe [new file with mode: 0644]
sql-ledger/locale/nl/pe [new file with mode: 0644]
sql-ledger/locale/nl/rc [new file with mode: 0644]
sql-ledger/locale/nl/rp [new file with mode: 0644]
sql-ledger/locale/no/COPYING [new file with mode: 0644]
sql-ledger/locale/no/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/no/admin [new file with mode: 0644]
sql-ledger/locale/no/all [new file with mode: 0644]
sql-ledger/locale/no/am [new file with mode: 0644]
sql-ledger/locale/no/ap [new file with mode: 0644]
sql-ledger/locale/no/ar [new file with mode: 0644]
sql-ledger/locale/no/arap [new file with mode: 0644]
sql-ledger/locale/no/ca [new file with mode: 0644]
sql-ledger/locale/no/cp [new file with mode: 0644]
sql-ledger/locale/no/ct [new file with mode: 0644]
sql-ledger/locale/no/gl [new file with mode: 0644]
sql-ledger/locale/no/ic [new file with mode: 0644]
sql-ledger/locale/no/io [new file with mode: 0644]
sql-ledger/locale/no/ir [new file with mode: 0644]
sql-ledger/locale/no/is [new file with mode: 0644]
sql-ledger/locale/no/login [new file with mode: 0644]
sql-ledger/locale/no/menu [new file with mode: 0644]
sql-ledger/locale/no/oe [new file with mode: 0644]
sql-ledger/locale/no/pe [new file with mode: 0644]
sql-ledger/locale/no/rc [new file with mode: 0644]
sql-ledger/locale/no/rp [new file with mode: 0644]
sql-ledger/locale/pa/COPYING [new file with mode: 0644]
sql-ledger/locale/pa/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/pa/admin [new file with mode: 0644]
sql-ledger/locale/pa/all [new file with mode: 0644]
sql-ledger/locale/pa/am [new file with mode: 0644]
sql-ledger/locale/pa/ap [new file with mode: 0644]
sql-ledger/locale/pa/ar [new file with mode: 0644]
sql-ledger/locale/pa/arap [new file with mode: 0644]
sql-ledger/locale/pa/ca [new file with mode: 0644]
sql-ledger/locale/pa/cp [new file with mode: 0644]
sql-ledger/locale/pa/ct [new file with mode: 0644]
sql-ledger/locale/pa/gl [new file with mode: 0644]
sql-ledger/locale/pa/ic [new file with mode: 0644]
sql-ledger/locale/pa/io [new file with mode: 0644]
sql-ledger/locale/pa/ir [new file with mode: 0644]
sql-ledger/locale/pa/is [new file with mode: 0644]
sql-ledger/locale/pa/login [new file with mode: 0644]
sql-ledger/locale/pa/menu [new file with mode: 0644]
sql-ledger/locale/pa/oe [new file with mode: 0644]
sql-ledger/locale/pa/pe [new file with mode: 0644]
sql-ledger/locale/pa/rc [new file with mode: 0644]
sql-ledger/locale/pa/rp [new file with mode: 0644]
sql-ledger/locale/pl/COPYING [new file with mode: 0644]
sql-ledger/locale/pl/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/pl/admin [new file with mode: 0644]
sql-ledger/locale/pl/all [new file with mode: 0644]
sql-ledger/locale/pl/am [new file with mode: 0644]
sql-ledger/locale/pl/ap [new file with mode: 0644]
sql-ledger/locale/pl/ar [new file with mode: 0644]
sql-ledger/locale/pl/arap [new file with mode: 0644]
sql-ledger/locale/pl/ca [new file with mode: 0644]
sql-ledger/locale/pl/cp [new file with mode: 0644]
sql-ledger/locale/pl/ct [new file with mode: 0644]
sql-ledger/locale/pl/gl [new file with mode: 0644]
sql-ledger/locale/pl/ic [new file with mode: 0644]
sql-ledger/locale/pl/io [new file with mode: 0644]
sql-ledger/locale/pl/ir [new file with mode: 0644]
sql-ledger/locale/pl/is [new file with mode: 0644]
sql-ledger/locale/pl/login [new file with mode: 0644]
sql-ledger/locale/pl/menu [new file with mode: 0644]
sql-ledger/locale/pl/oe [new file with mode: 0644]
sql-ledger/locale/pl/pe [new file with mode: 0644]
sql-ledger/locale/pl/rc [new file with mode: 0644]
sql-ledger/locale/pl/rp [new file with mode: 0644]
sql-ledger/locale/pt/COPYING [new file with mode: 0644]
sql-ledger/locale/pt/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/pt/admin [new file with mode: 0644]
sql-ledger/locale/pt/all [new file with mode: 0644]
sql-ledger/locale/pt/am [new file with mode: 0644]
sql-ledger/locale/pt/ap [new file with mode: 0644]
sql-ledger/locale/pt/ar [new file with mode: 0644]
sql-ledger/locale/pt/arap [new file with mode: 0644]
sql-ledger/locale/pt/ca [new file with mode: 0644]
sql-ledger/locale/pt/cp [new file with mode: 0644]
sql-ledger/locale/pt/ct [new file with mode: 0644]
sql-ledger/locale/pt/gl [new file with mode: 0644]
sql-ledger/locale/pt/ic [new file with mode: 0644]
sql-ledger/locale/pt/io [new file with mode: 0644]
sql-ledger/locale/pt/ir [new file with mode: 0644]
sql-ledger/locale/pt/is [new file with mode: 0644]
sql-ledger/locale/pt/login [new file with mode: 0644]
sql-ledger/locale/pt/menu [new file with mode: 0644]
sql-ledger/locale/pt/oe [new file with mode: 0644]
sql-ledger/locale/pt/pe [new file with mode: 0644]
sql-ledger/locale/pt/rc [new file with mode: 0644]
sql-ledger/locale/pt/rp [new file with mode: 0644]
sql-ledger/locale/ru/COPYING [new file with mode: 0644]
sql-ledger/locale/ru/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/ru/admin [new file with mode: 0644]
sql-ledger/locale/ru/all [new file with mode: 0644]
sql-ledger/locale/ru/am [new file with mode: 0644]
sql-ledger/locale/ru/ap [new file with mode: 0644]
sql-ledger/locale/ru/ar [new file with mode: 0644]
sql-ledger/locale/ru/arap [new file with mode: 0644]
sql-ledger/locale/ru/ca [new file with mode: 0644]
sql-ledger/locale/ru/cp [new file with mode: 0644]
sql-ledger/locale/ru/ct [new file with mode: 0644]
sql-ledger/locale/ru/gl [new file with mode: 0644]
sql-ledger/locale/ru/ic [new file with mode: 0644]
sql-ledger/locale/ru/io [new file with mode: 0644]
sql-ledger/locale/ru/ir [new file with mode: 0644]
sql-ledger/locale/ru/is [new file with mode: 0644]
sql-ledger/locale/ru/login [new file with mode: 0644]
sql-ledger/locale/ru/menu [new file with mode: 0644]
sql-ledger/locale/ru/oe [new file with mode: 0644]
sql-ledger/locale/ru/pe [new file with mode: 0644]
sql-ledger/locale/ru/rc [new file with mode: 0644]
sql-ledger/locale/ru/rp [new file with mode: 0644]
sql-ledger/locale/se/COPYING [new file with mode: 0644]
sql-ledger/locale/se/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/se/admin [new file with mode: 0644]
sql-ledger/locale/se/all [new file with mode: 0644]
sql-ledger/locale/se/am [new file with mode: 0644]
sql-ledger/locale/se/ap [new file with mode: 0644]
sql-ledger/locale/se/ar [new file with mode: 0644]
sql-ledger/locale/se/arap [new file with mode: 0644]
sql-ledger/locale/se/ca [new file with mode: 0644]
sql-ledger/locale/se/cp [new file with mode: 0644]
sql-ledger/locale/se/ct [new file with mode: 0644]
sql-ledger/locale/se/gl [new file with mode: 0644]
sql-ledger/locale/se/ic [new file with mode: 0644]
sql-ledger/locale/se/io [new file with mode: 0644]
sql-ledger/locale/se/ir [new file with mode: 0644]
sql-ledger/locale/se/is [new file with mode: 0644]
sql-ledger/locale/se/login [new file with mode: 0644]
sql-ledger/locale/se/menu [new file with mode: 0644]
sql-ledger/locale/se/oe [new file with mode: 0644]
sql-ledger/locale/se/pe [new file with mode: 0644]
sql-ledger/locale/se/rc [new file with mode: 0644]
sql-ledger/locale/se/rp [new file with mode: 0644]
sql-ledger/locale/tr/COPYING [new file with mode: 0644]
sql-ledger/locale/tr/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/tr/admin [new file with mode: 0644]
sql-ledger/locale/tr/all [new file with mode: 0644]
sql-ledger/locale/tr/am [new file with mode: 0644]
sql-ledger/locale/tr/ap [new file with mode: 0644]
sql-ledger/locale/tr/ar [new file with mode: 0644]
sql-ledger/locale/tr/arap [new file with mode: 0644]
sql-ledger/locale/tr/ca [new file with mode: 0644]
sql-ledger/locale/tr/cp [new file with mode: 0644]
sql-ledger/locale/tr/ct [new file with mode: 0644]
sql-ledger/locale/tr/gl [new file with mode: 0644]
sql-ledger/locale/tr/ic [new file with mode: 0644]
sql-ledger/locale/tr/io [new file with mode: 0644]
sql-ledger/locale/tr/ir [new file with mode: 0644]
sql-ledger/locale/tr/is [new file with mode: 0644]
sql-ledger/locale/tr/login [new file with mode: 0644]
sql-ledger/locale/tr/menu [new file with mode: 0644]
sql-ledger/locale/tr/oe [new file with mode: 0644]
sql-ledger/locale/tr/pe [new file with mode: 0644]
sql-ledger/locale/tr/rc [new file with mode: 0644]
sql-ledger/locale/tr/rp [new file with mode: 0644]
sql-ledger/locale/tw/COPYING [new file with mode: 0644]
sql-ledger/locale/tw/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/tw/admin [new file with mode: 0644]
sql-ledger/locale/tw/all [new file with mode: 0644]
sql-ledger/locale/tw/am [new file with mode: 0644]
sql-ledger/locale/tw/ap [new file with mode: 0644]
sql-ledger/locale/tw/ar [new file with mode: 0644]
sql-ledger/locale/tw/arap [new file with mode: 0644]
sql-ledger/locale/tw/ca [new file with mode: 0644]
sql-ledger/locale/tw/cp [new file with mode: 0644]
sql-ledger/locale/tw/ct [new file with mode: 0644]
sql-ledger/locale/tw/gl [new file with mode: 0644]
sql-ledger/locale/tw/ic [new file with mode: 0644]
sql-ledger/locale/tw/io [new file with mode: 0644]
sql-ledger/locale/tw/ir [new file with mode: 0644]
sql-ledger/locale/tw/is [new file with mode: 0644]
sql-ledger/locale/tw/login [new file with mode: 0644]
sql-ledger/locale/tw/menu [new file with mode: 0644]
sql-ledger/locale/tw/oe [new file with mode: 0644]
sql-ledger/locale/tw/pe [new file with mode: 0644]
sql-ledger/locale/tw/rc [new file with mode: 0644]
sql-ledger/locale/tw/rp [new file with mode: 0644]
sql-ledger/locale/ua/COPYING [new file with mode: 0644]
sql-ledger/locale/ua/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/ua/admin [new file with mode: 0644]
sql-ledger/locale/ua/all [new file with mode: 0644]
sql-ledger/locale/ua/am [new file with mode: 0644]
sql-ledger/locale/ua/ap [new file with mode: 0644]
sql-ledger/locale/ua/ar [new file with mode: 0644]
sql-ledger/locale/ua/arap [new file with mode: 0644]
sql-ledger/locale/ua/ca [new file with mode: 0644]
sql-ledger/locale/ua/cp [new file with mode: 0644]
sql-ledger/locale/ua/ct [new file with mode: 0644]
sql-ledger/locale/ua/gl [new file with mode: 0644]
sql-ledger/locale/ua/ic [new file with mode: 0644]
sql-ledger/locale/ua/io [new file with mode: 0644]
sql-ledger/locale/ua/ir [new file with mode: 0644]
sql-ledger/locale/ua/is [new file with mode: 0644]
sql-ledger/locale/ua/login [new file with mode: 0644]
sql-ledger/locale/ua/menu [new file with mode: 0644]
sql-ledger/locale/ua/oe [new file with mode: 0644]
sql-ledger/locale/ua/pe [new file with mode: 0644]
sql-ledger/locale/ua/rc [new file with mode: 0644]
sql-ledger/locale/ua/rp [new file with mode: 0644]
sql-ledger/locale/ve/COPYING [new file with mode: 0644]
sql-ledger/locale/ve/LANGUAGE [new file with mode: 0644]
sql-ledger/locale/ve/admin [new file with mode: 0644]
sql-ledger/locale/ve/all [new file with mode: 0644]
sql-ledger/locale/ve/am [new file with mode: 0644]
sql-ledger/locale/ve/ap [new file with mode: 0644]
sql-ledger/locale/ve/ar [new file with mode: 0644]
sql-ledger/locale/ve/arap [new file with mode: 0644]
sql-ledger/locale/ve/ca [new file with mode: 0644]
sql-ledger/locale/ve/cp [new file with mode: 0644]
sql-ledger/locale/ve/ct [new file with mode: 0644]
sql-ledger/locale/ve/gl [new file with mode: 0644]
sql-ledger/locale/ve/ic [new file with mode: 0644]
sql-ledger/locale/ve/io [new file with mode: 0644]
sql-ledger/locale/ve/ir [new file with mode: 0644]
sql-ledger/locale/ve/is [new file with mode: 0644]
sql-ledger/locale/ve/login [new file with mode: 0644]
sql-ledger/locale/ve/menu [new file with mode: 0644]
sql-ledger/locale/ve/oe [new file with mode: 0644]
sql-ledger/locale/ve/pe [new file with mode: 0644]
sql-ledger/locale/ve/rc [new file with mode: 0644]
sql-ledger/locale/ve/rp [new file with mode: 0644]
sql-ledger/login.pl [new file with mode: 0755]
sql-ledger/menu.ini [new file with mode: 0644]
sql-ledger/setup.pl [new file with mode: 0755]
sql-ledger/sql-ledger.conf.default [new file with mode: 0644]
sql-ledger/sql-ledger.png [new file with mode: 0644]
sql-ledger/sql/Austria-chart.sql [new file with mode: 0644]
sql-ledger/sql/Austria-gifi.sql [new file with mode: 0644]
sql-ledger/sql/Brazil_General-chart.sql [new file with mode: 0644]
sql-ledger/sql/Canada-gifi.sql [new file with mode: 0644]
sql-ledger/sql/Canada_General-chart.sql [new file with mode: 0644]
sql-ledger/sql/Czech_Republic-chart.sql [new file with mode: 0644]
sql-ledger/sql/Danish_Default-chart.sql [new file with mode: 0644]
sql-ledger/sql/Default-chart.sql [new file with mode: 0644]
sql-ledger/sql/Dutch_Default-chart.sql [new file with mode: 0644]
sql-ledger/sql/Dutch_Standard-chart.sql [new file with mode: 0644]
sql-ledger/sql/France-chart.sql [new file with mode: 0644]
sql-ledger/sql/German-Sample-chart.sql [new file with mode: 0644]
sql-ledger/sql/German-Sample-gifi.sql [new file with mode: 0644]
sql-ledger/sql/Germany-DATEV-SKR03-chart.sql [new file with mode: 0644]
sql-ledger/sql/Germany-DATEV-SKR03-gifi.sql [new file with mode: 0644]
sql-ledger/sql/Germany-SKR03-chart.sql [new file with mode: 0644]
sql-ledger/sql/Germany-SKR03-gifi.sql [new file with mode: 0644]
sql-ledger/sql/Italy-chart.sql [new file with mode: 0644]
sql-ledger/sql/Oracle-indices.sql [new file with mode: 0644]
sql-ledger/sql/Oracle-tables.sql [new file with mode: 0644]
sql-ledger/sql/Oracle-upgrade-1.8.0-1.8.4.sql [new file with mode: 0644]
sql-ledger/sql/Oracle-upgrade-1.8.4-1.8.5.sql [new file with mode: 0644]
sql-ledger/sql/Oracle-upgrade-1.8.5-2.0.0.sql [new file with mode: 0644]
sql-ledger/sql/Oracle-upgrade-2.0.0-2.0.8.sql [new file with mode: 0644]
sql-ledger/sql/Pg-indices.sql [new file with mode: 0644]
sql-ledger/sql/Pg-tables.sql [new file with mode: 0644]
sql-ledger/sql/Pg-upgrade-1.2.6-1.2.7.sql [new file with mode: 0644]
sql-ledger/sql/Pg-upgrade-1.2.7-1.4.0.sql [new file with mode: 0644]
sql-ledger/sql/Pg-upgrade-1.4.0-1.6.0.sql [new file with mode: 0644]
sql-ledger/sql/Pg-upgrade-1.6.0-1.8.0.sql [new file with mode: 0644]
sql-ledger/sql/Pg-upgrade-1.8.0-1.8.4.sql [new file with mode: 0644]
sql-ledger/sql/Pg-upgrade-1.8.4-1.8.5.sql [new file with mode: 0644]
sql-ledger/sql/Pg-upgrade-1.8.5-2.0.0.sql [new file with mode: 0644]
sql-ledger/sql/Pg-upgrade-2.0.0-2.0.8.sql [new file with mode: 0644]
sql-ledger/sql/Poland-chart.sql [new file with mode: 0644]
sql-ledger/sql/Simplified_Chinese_Default-chart.sql [new file with mode: 0644]
sql-ledger/sql/Spain-chart.sql [new file with mode: 0644]
sql-ledger/sql/Swiss-German-chart.sql [new file with mode: 0644]
sql-ledger/sql/Swiss-German-gifi.sql [new file with mode: 0644]
sql-ledger/sql/Traditional_Chinese_Default-chart.sql [new file with mode: 0644]
sql-ledger/sql/US_General-chart.sql [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-balance_sheet.html [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-check.tex [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-income_statement.html [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-invoice.html [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-invoice.tex [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-packing_list.html [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-packing_list.tex [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-purchase_order.html [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-purchase_order.tex [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-receipt.tex [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-sales_order.html [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-sales_order.tex [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-statement.html [new file with mode: 0644]
sql-ledger/templates/Brazilian_Portuguese-statement.tex [new file with mode: 0644]
sql-ledger/templates/Danish-balance_sheet.html [new file with mode: 0644]
sql-ledger/templates/Danish-check.tex [new file with mode: 0644]
sql-ledger/templates/Danish-income_statement.html [new file with mode: 0644]
sql-ledger/templates/Danish-invoice.html [new file with mode: 0644]
sql-ledger/templates/Danish-invoice.tex [new file with mode: 0644]
sql-ledger/templates/Danish-packing_list.html [new file with mode: 0644]
sql-ledger/templates/Danish-packing_list.tex [new file with mode: 0644]
sql-ledger/templates/Danish-purchase_order.html [new file with mode: 0644]
sql-ledger/templates/Danish-purchase_order.tex [new file with mode: 0644]
sql-ledger/templates/Danish-receipt.tex [new file with mode: 0644]
sql-ledger/templates/Danish-sales_order.html [new file with mode: 0644]
sql-ledger/templates/Danish-sales_order.tex [new file with mode: 0644]
sql-ledger/templates/Danish-statement.html [new file with mode: 0644]
sql-ledger/templates/Danish-statement.tex [new file with mode: 0644]
sql-ledger/templates/Default-balance_sheet.html [new file with mode: 0644]
sql-ledger/templates/Default-check.tex [new file with mode: 0644]
sql-ledger/templates/Default-income_statement.html [new file with mode: 0644]
sql-ledger/templates/Default-invoice.html [new file with mode: 0644]
sql-ledger/templates/Default-invoice.tex [new file with mode: 0644]
sql-ledger/templates/Default-packing_list.html [new file with mode: 0644]
sql-ledger/templates/Default-packing_list.tex [new file with mode: 0644]
sql-ledger/templates/Default-purchase_order.html [new file with mode: 0644]
sql-ledger/templates/Default-purchase_order.tex [new file with mode: 0644]
sql-ledger/templates/Default-receipt.tex [new file with mode: 0644]
sql-ledger/templates/Default-sales_order.html [new file with mode: 0644]
sql-ledger/templates/Default-sales_order.tex [new file with mode: 0644]
sql-ledger/templates/Default-statement.html [new file with mode: 0644]
sql-ledger/templates/Default-statement.tex [new file with mode: 0644]
sql-ledger/templates/Dutch-balance_sheet.html [new file with mode: 0644]
sql-ledger/templates/Dutch-check.tex [new file with mode: 0644]
sql-ledger/templates/Dutch-income_statement.html [new file with mode: 0644]
sql-ledger/templates/Dutch-invoice.html [new file with mode: 0644]
sql-ledger/templates/Dutch-invoice.tex [new file with mode: 0644]
sql-ledger/templates/Dutch-packing_list.html [new file with mode: 0644]
sql-ledger/templates/Dutch-packing_list.tex [new file with mode: 0644]
sql-ledger/templates/Dutch-purchase_order.html [new file with mode: 0644]
sql-ledger/templates/Dutch-purchase_order.tex [new file with mode: 0644]
sql-ledger/templates/Dutch-receipt.tex [new file with mode: 0644]
sql-ledger/templates/Dutch-sales_order.html [new file with mode: 0644]
sql-ledger/templates/Dutch-sales_order.tex [new file with mode: 0644]
sql-ledger/templates/Dutch-statement.html [new file with mode: 0644]
sql-ledger/templates/Dutch-statement.tex [new file with mode: 0644]
sql-ledger/templates/Estonian-balance_sheet.html [new file with mode: 0644]
sql-ledger/templates/Estonian-check.tex [new file with mode: 0644]
sql-ledger/templates/Estonian-income_statement.html [new file with mode: 0644]
sql-ledger/templates/Estonian-invoice.html [new file with mode: 0644]
sql-ledger/templates/Estonian-invoice.tex [new file with mode: 0644]
sql-ledger/templates/Estonian-packing_list.html [new file with mode: 0644]
sql-ledger/templates/Estonian-packing_list.tex [new file with mode: 0644]
sql-ledger/templates/Estonian-purchase_order.html [new file with mode: 0644]
sql-ledger/templates/Estonian-purchase_order.tex [new file with mode: 0644]
sql-ledger/templates/Estonian-receipt.tex [new file with mode: 0644]
sql-ledger/templates/Estonian-sales_order.html [new file with mode: 0644]
sql-ledger/templates/Estonian-sales_order.tex [new file with mode: 0644]
sql-ledger/templates/Estonian-statement.html [new file with mode: 0644]
sql-ledger/templates/Estonian-statement.tex [new file with mode: 0644]
sql-ledger/templates/French-balance_sheet.html [new file with mode: 0644]
sql-ledger/templates/French-check.tex [new file with mode: 0644]
sql-ledger/templates/French-income_statement.html [new file with mode: 0644]
sql-ledger/templates/French-invoice.html [new file with mode: 0644]
sql-ledger/templates/French-invoice.tex [new file with mode: 0644]
sql-ledger/templates/French-packing_list.html [new file with mode: 0644]
sql-ledger/templates/French-packing_list.tex [new file with mode: 0644]
sql-ledger/templates/French-purchase_order.html [new file with mode: 0644]
sql-ledger/templates/French-purchase_order.tex [new file with mode: 0644]
sql-ledger/templates/French-receipt.tex [new file with mode: 0644]
sql-ledger/templates/French-sales_order.html [new file with mode: 0644]
sql-ledger/templates/French-sales_order.tex [new file with mode: 0644]
sql-ledger/templates/French-statement.html [new file with mode: 0644]
sql-ledger/templates/French-statement.tex [new file with mode: 0644]
sql-ledger/templates/German-balance_sheet.html [new file with mode: 0644]
sql-ledger/templates/German-check.tex [new file with mode: 0644]
sql-ledger/templates/German-income_statement.html [new file with mode: 0644]
sql-ledger/templates/German-invoice.html [new file with mode: 0644]
sql-ledger/templates/German-invoice.tex [new file with mode: 0644]
sql-ledger/templates/German-packing_list.html [new file with mode: 0644]
sql-ledger/templates/German-packing_list.tex [new file with mode: 0644]
sql-ledger/templates/German-purchase_order.html [new file with mode: 0644]
sql-ledger/templates/German-purchase_order.tex [new file with mode: 0644]
sql-ledger/templates/German-receipt.tex [new file with mode: 0644]
sql-ledger/templates/German-sales_order.html [new file with mode: 0644]
sql-ledger/templates/German-sales_order.tex [new file with mode: 0644]
sql-ledger/templates/German-statement.html [new file with mode: 0644]
sql-ledger/templates/German-statement.tex [new file with mode: 0644]
sql-ledger/templates/Service-balance_sheet.html [new file with mode: 0644]
sql-ledger/templates/Service-check.tex [new file with mode: 0644]
sql-ledger/templates/Service-income_statement.html [new file with mode: 0644]
sql-ledger/templates/Service-invoice.html [new file with mode: 0644]
sql-ledger/templates/Service-invoice.tex [new file with mode: 0644]
sql-ledger/templates/Service-packing_list.html [new file with mode: 0644]
sql-ledger/templates/Service-packing_list.tex [new file with mode: 0644]
sql-ledger/templates/Service-purchase_order.html [new file with mode: 0644]
sql-ledger/templates/Service-purchase_order.tex [new file with mode: 0644]
sql-ledger/templates/Service-receipt.tex [new file with mode: 0644]
sql-ledger/templates/Service-sales_order.html [new file with mode: 0644]
sql-ledger/templates/Service-sales_order.tex [new file with mode: 0644]
sql-ledger/templates/Service-statement.html [new file with mode: 0644]
sql-ledger/templates/Service-statement.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-balance_sheet.html [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-check.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-income_statement.html [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-invoice.html [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-invoice.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-packing_list.html [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-packing_list.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-purchase_order.html [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-purchase_order.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-receipt.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-sales_order.html [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-sales_order.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-statement.html [new file with mode: 0644]
sql-ledger/templates/Spanish_A4-statement.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-balance_sheet.html [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-check.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-income_statement.html [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-invoice.html [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-invoice.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-packing_list.html [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-packing_list.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-purchase_order.html [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-purchase_order.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-receipt.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-sales_order.html [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-sales_order.tex [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-statement.html [new file with mode: 0644]
sql-ledger/templates/Spanish_Letter-statement.tex [new file with mode: 0644]
sql-ledger/users/members.default [new file with mode: 0644]

diff --git a/ANNOUCE.1.4.0 b/ANNOUCE.1.4.0
deleted file mode 100644 (file)
index d110c6f..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-Hi,
-
-I'm pleased to announce the first beta release of Freeside 1.4.0.
-Freeside is a web-based, open-source billing and account administration
-package for ISPs, web hosts, and similar businesses.
-
-You can see a web demo, read the documentation, and download the new beta
-at <http://www.sisd.com/freeside/>.
-
-Although Freeside is free software, it is supported commercially with
-installation, customization, training and support services.  Please
-consider our services and help support the development of the software!
-
-
-Major new features in 1.4.0 include:
-
-- Billing engine has been rewritten and now has support for easily added
-  "price plans".  Included price plans include anniversary billing,
-  1st-of-the-month billing (pro-rated and subscription), free for N days,
-  commissions for referrals and per-minute/per-hour charges.
-
-- Customer-to-customer referrals, tracking and commissions.
-
-- Configurable invoice events triggered for delinquent customers can
-  re-send invoices, suspend accounts, charge late fees, and so on.
-
-- Export and provisioning system has been rewritten.  New provisioning
-  methods can now be "plugged-in" for any service type.  Included exports
-  include BSD and Linux password files, configurable shell commands,
-  RADIUS (both text and SQL, including groups), BIND configuration files,
-  Cyrus, vpopmail, and many others.
-
-- Complete set of history tables tracking all changes to the database.
-
-- Job queue with display and retry for provisioning tasks.
-
-- UI overhaul - easier to navigate and use.  Quick package order and
-  one-time charges.  Separate billing and service contact information.
-  Customer comments.
-
-- Performance optimizations.
-
-- Financials have been rewritten.  Apply payments and credits against
-  specific invoices (in whole or in part), or have the system apply
-  automatically.
-
-- Texas tax.
-
-- Improved documentation and easier install.
-
diff --git a/Artistic b/Artistic
deleted file mode 100644 (file)
index 4ffc78e..0000000
--- a/Artistic
+++ /dev/null
@@ -1,125 +0,0 @@
-                      The "Artistic License"
-
-                             Preamble
-
-The intent of this document is to state the conditions under which a
-Package may be copied, such that the Copyright Holder maintains some
-semblance of artistic control over the development of the Package,
-while giving the users of the package the right to use and distribute
-the Package in a more-or-less customary fashion, plus the right to make
-reasonable modifications.
-
-It also grants you the rights to reuse parts of a Package in your own
-programs without transferring this License to those programs, provided
-that you meet some reasonable requirements.
-
-Definitions:
-
-        "Package" refers to the collection of files distributed by the
-        Copyright Holder, and derivatives of that collection of files
-        created through textual modification.
-
-        "Standard Version" refers to such a Package if it has not been
-        modified, or has been modified in accordance with the wishes
-        of the Copyright Holder as specified below.
-
-        "Copyright Holder" is whoever is named in the copyright or
-        copyrights for the package.
-
-        "You" is you, if you're thinking about copying or distributing
-        this Package.
-
-        "Reasonable copying fee" is whatever you can justify on the
-        basis of media cost, duplication charges, time of people involved,
-        and so on.  (You will not be required to justify it to the
-        Copyright Holder, but only to the computing community at large
-        as a market that must bear the fee.)
-
-        "Freely Available" means that no fee is charged for the item
-        itself, though there may be fees involved in handling the item.
-        It also means that recipients of the item may redistribute it
-        under the same conditions they received it.
-
-1. You may make and give away verbatim copies of the source form of the
-Standard Version of this Package without restriction, provided that you
-duplicate all of the original copyright notices and associated disclaimers.
-
-2. You may apply bug fixes, portability fixes and other modifications
-derived from the Public Domain or from the Copyright Holder.  A Package
-modified in such a way shall still be considered the Standard Version.
-
-3. You may otherwise modify your copy of this Package in any way, provided
-that you insert a prominent notice in each changed file stating how and
-when you changed that file, and provided that you do at least ONE of the
-following:
-
-    a) place your modifications in the Public Domain or otherwise make them
-    Freely Available, such as by posting said modifications to Usenet or
-    an equivalent medium, or placing the modifications on a major archive
-    site such as uunet.uu.net, or by allowing the Copyright Holder to include
-    your modifications in the Standard Version of the Package.
-
-    b) use the modified Package only within your corporation or organization.
-
-    c) rename any non-standard executables so the names do not conflict
-    with standard executables, which must also be provided, and provide
-    a separate manual page for each non-standard executable that clearly
-    documents how it differs from the Standard Version.
-
-    d) make other distribution arrangements with the Copyright Holder.
-
-4. You may distribute the programs of this Package in object code or
-executable form, provided that you do at least ONE of the following:
-
-    a) distribute a Standard Version of the executables and library files,
-    together with instructions (in the manual page or equivalent) on where
-    to get the Standard Version.
-
-    b) accompany the distribution with the machine-readable source of
-    the Package with your modifications.
-
-    c) give non-standard executables non-standard names, and clearly
-    document the differences in manual pages (or equivalent), together
-    with instructions on where to get the Standard Version.
-
-    d) make other distribution arrangements with the Copyright Holder.
-
-5. You may charge a reasonable copying fee for any distribution of this
-Package.  You may charge any fee you choose for support of this
-Package.  You may not charge a fee for this Package itself.  However,
-you may distribute this Package in aggregate with other (possibly
-commercial) programs as part of a larger (possibly commercial) software
-distribution provided that you do not advertise this Package as a
-product of your own.
-
-6. The scripts and library files supplied as input to or produced as
-output from the programs of this Package do not automatically fall
-under the copyright of this Package, but belong to whomever generated
-them, and may be sold commercially, and may be aggregated with this
-Package.  If such scripts or library files are aggregated with this
-Package via the so-called "undump" or "unexec" methods of producing a
-binary executable image, then distribution of such an image shall
-neither be construed as a distribution of this Package nor shall it
-fall under the restrictions of Paragraphs 3 and 4, provided that you do
-not represent such an executable image as a Standard Version of this
-Package.
-
-7. You may reuse parts of this Package in your own programs, provided that
-you explicitly state where you got them from, in the source code (and, left
-to your courtesy, in the documentation), duplicating all the associated
-copyright notices and disclaimers. Besides your changes, if any, must be
-clearly marked as such. Parts reused that way will no longer fall under this
-license if, and only if, the name of your program(s) have no immediate
-connection with the name of the Package itself or its associated programs.
-You may then apply whatever restrictions you wish on the reused parts or
-choose to place them in the Public Domain--this will apply only within the
-context of your package.
-
-8. The name of the Copyright Holder may not be used to endorse or promote
-products derived from this software without specific prior written permission.
-
-9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-                                The End
diff --git a/CREDITS b/CREDITS
index d89f4f5..592be44 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -52,7 +52,8 @@ Kristian Hoffmann <khoff@pc-intouch.com> contributed Netscape CCK
 autoconfiguration support for the signup server, lots of great mailing
 lists posts which I shamelessly made into documentation, fixes to get rid of
 the embarassing and non-database-normal "owed" field, and many other things
-I'm forgetting.
+I'm forgetting.  Most recently Kristian and Mark (last name?) contributed
+the IP address tracking and svc_broadband in 1.5.
 
 Jeff Finucane <jeff@cmh.net> send in a bunch of bugfixes (for the sendmail
 export, cancel-unaudited.cgi), patches to support billing date modification,
@@ -106,5 +107,18 @@ Thanks!
 "Stephen Bechard" <steve@destek.net> sent in patches for svc_www services and
 other fixes.
 
+Charles A Beasley <cbeasley@noment.net> contributed quota editing for the
+Infostreet export.
+
+Richard Siddall <richard.siddall@elirion.net> sent in Mason fixes and other
+things I'm probably forgetting.
+
+Contains "JS Calendar" v0.9.3 <http://dynarch.com/mishoo/calendar.epl>
+by Mihai Bazon <mishoo@infoiasi.ro> licensed under the terms of the GNU LGPL.
+
+Latex invoice template based on a template from eBills
+<http://ebills.sourceforge.net/> by Mark Asplen-Taylor <mark@asplen.co.uk>,
+licensed under the terms fo the GNU GPL.
+
 Everything else is my (Ivan Kohler <ivan@420.am>) fault.
 
index 963c735..36c3a17 100644 (file)
--- a/FS/FS.pm
+++ b/FS/FS.pm
@@ -54,6 +54,8 @@ L<FS::svc_Common> - Service base class
 
 L<FS::svc_acct> - Account (shell, RADIUS, POP3) class
 
+L<FS::acct_snarf> - External mail account class
+
 L<FS::radius_usergroup> - RADIUS groups
 
 L<FS::svc_domain> - Domain class
@@ -62,10 +64,12 @@ L<FS::domain_record> - DNS zone entries
 
 L<FS::svc_forward> - Mail forwarding class
 
-L<FS::svc_acct_sm> - (Depreciated) Vitual mail alias class
-
 L<FS::svc_www> - Web virtual host class.
 
+L<FS::svc_broadband> - DSL, wireless and other broadband class.
+
+L<FS::svc_external> - Externally tracked service class.
+
 L<FS::part_svc> - Service definition class
 
 L<FS::part_svc_column> - Column constraint class
@@ -104,6 +108,8 @@ L<FS::cust_bill> - Invoice class
 
 L<FS::cust_bill_pkg> - Invoice line item class
 
+L<FS::cust_bill_pkg_detail> - Invoice line item detail class
+
 L<FS::part_bill_event> - Invoice event definition class
 
 L<FS::cust_bill_event> - Completed invoice event class
@@ -187,7 +193,7 @@ first time, the suggested order will tend to reduce the number of forward
 references."
 
 If you've never used OO modules before,
-http://www.cpan.org/doc/FMTEYEWTK/easy_objects.html might help you out.
+http://www.perl.com/doc/FMTEYEWTK/easy_objects.html might help you out.
 
 =head1 DESCRIPTION
 
index e44ebcc..905189e 100644 (file)
@@ -10,7 +10,7 @@ use FS::UID;
 
 @ISA = qw(Exporter);
 @EXPORT_OK = qw(header menubar idiot eidiot popurl table itable ntable
-                small_custview myexit);
+                small_custview myexit http_header);
 
 =head1 NAME
 
@@ -44,8 +44,10 @@ Returns an HTML header.
 =cut
 
 sub header {
+  use Carp;
+  carp 'FS::CGI::header deprecated; include /elements/header.html instead';
+
   my($title,$menubar,$etc)=@_; #$etc is for things like onLoad= etc.
-  #use Carp;
   $etc = '' unless defined $etc;
 
   my $x =  <<END;
@@ -68,6 +70,38 @@ END
   $x;
 }
 
+=item http_header
+
+Sets an http header.
+
+=cut
+
+sub http_header {
+  my ( $header, $value ) = @_;
+  if (exists $ENV{MOD_PERL}) {
+    if ( defined $main::Response
+         && $main::Response->isa('Apache::ASP::Response') ) {  #Apache::ASP
+      if ( $header =~ /^Content-Type$/ ) {
+        $main::Response->{ContentType} = $value;
+      } else {
+        $main::Response->AddHeader( $header => $value );
+      }
+    } elsif ( defined $HTML::Mason::Commands::r  ) { #Mason
+      ## is this the correct pacakge for $r ???  for 1.0x and 1.1x ?
+      if ( $header =~ /^Content-Type$/ ) {
+        $HTML::Mason::Commands::r->content_type($value);
+      } else {
+        $HTML::Mason::Commands::r->header_out( $header => $value );
+      }
+    } else {
+      die "http_header called in unknown environment";
+    }
+  } else {
+    die "http_header called not running under mod_perl";
+  }
+
+}
+
 =item menubar ITEM, URL, ...
 
 Returns an HTML menubar.
@@ -75,6 +109,9 @@ Returns an HTML menubar.
 =cut
 
 sub menubar { #$menubar=menubar('Main Menu', '../', 'Item', 'url', ... );
+  use Carp;
+  carp 'FS::CGI::menubar deprecated; include /elements/menubar.html instead';
+
   my($item,$url,@html);
   while (@_) {
     ($item,$url)=splice(@_,0,2);
@@ -177,7 +214,9 @@ Returns current URL with LEVEL levels of path removed from the end (default 0).
 sub popurl {
   my($up)=@_;
   my $cgi = &FS::UID::cgi;
-  my $url = new URI::URL ( $cgi->isa('Apache') ? $cgi->uri : $cgi->url );
+  my $url_string = $cgi->isa('Apache') ? $cgi->uri : $cgi->url;
+  $url_string =~ s/\?.*//;
+  my $url = new URI::URL ( $url_string );
   my(@path)=$url->path_components;
   splice @path, 0-$up;
   $url->path_components(@path);
@@ -193,6 +232,9 @@ Returns HTML tag for beginning a table.
 =cut
 
 sub table {
+  use Carp;
+  carp 'FS::CGI::table deprecated; include /elements/table.html instead';
+
   my $col = shift;
   if ( $col ) {
     qq!<TABLE BGCOLOR="$col" BORDER=1 WIDTH="100%" CELLSPACING=0 CELLPADDING=2 BORDERCOLOR="#999999">!;
@@ -290,6 +332,10 @@ sub small_custview {
 
   $html .= '</TR></TABLE>';
 
+  $html .= '<BR>Balance: <B>$'. $cust_main->balance. '</B><BR>';
+
+  # last payment might be good here too?
+
   $html;
 }
 
index f7b8eb0..7cbbdbf 100644 (file)
@@ -1,13 +1,13 @@
 package FS::ClientAPI;
 
 use strict;
-use vars qw(%handler);
+use vars qw(%handler $domain);
 
 %handler = ();
 
 #find modules
 foreach my $INC ( @INC ) {
-  foreach my $file ( glob("$INC/FS/ClientAPI/*") ) {
+  foreach my $file ( glob("$INC/FS/ClientAPI/*.pm") ) {
     $file =~ /\/(\w+)\.pm$/ or do {
       warn "unrecognized ClientAPI file: $file";
       next
index 6747855..445f0ec 100644 (file)
@@ -4,24 +4,45 @@ use strict;
 use vars qw($cache);
 use Digest::MD5 qw(md5_hex);
 use Date::Format;
+use Business::CreditCard;
 use Cache::SharedMemoryCache; #store in db?
 use FS::CGI qw(small_custview); #doh
 use FS::Conf;
-use FS::Record qw(qsearchs);
+use FS::Record qw(qsearch qsearchs);
 use FS::svc_acct;
 use FS::svc_domain;
 use FS::cust_main;
 use FS::cust_bill;
+use FS::cust_main_county;
+use FS::cust_pkg;
 
 use FS::ClientAPI; #hmm
 FS::ClientAPI->register_handlers(
-  'MyAccount/login'         => \&login,
-  'MyAccount/customer_info' => \&customer_info,
-  'MyAccount/invoice'       => \&invoice,
+  'MyAccount/login'            => \&login,
+  'MyAccount/customer_info'    => \&customer_info,
+  'MyAccount/edit_info'        => \&edit_info,
+  'MyAccount/invoice'          => \&invoice,
+  'MyAccount/cancel'           => \&cancel,
+  'MyAccount/payment_info'     => \&payment_info,
+  'MyAccount/process_payment'  => \&process_payment,
+  'MyAccount/list_pkgs'        => \&list_pkgs,
+  'MyAccount/order_pkg'        => \&order_pkg,
+  'MyAccount/cancel_pkg'       => \&cancel_pkg,
+  'MyAccount/charge'           => \&charge,
+);
+
+use vars qw( @cust_main_editable_fields );
+@cust_main_editable_fields = qw(
+  first last company address1 address2 city
+    county state zip country daytime night fax
+  ship_first ship_last ship_company ship_address1 ship_address2 ship_city
+    ship_state ship_zip ship_country ship_daytime ship_night ship_fax
 );
 
 #store in db?
-my $cache = new Cache::SharedMemoryCache();
+my $cache = new Cache::SharedMemoryCache( {
+   'namespace' => 'FS::ClientAPI::MyAccount',
+} );
 
 #false laziness w/FS::ClientAPI::passwd::passwd (needs to handle encrypted pw)
 sub login {
@@ -95,6 +116,10 @@ sub customer_info {
 
     $return{name} = $cust_main->first. ' '. $cust_main->get('last');
 
+    for (@cust_main_editable_fields) {
+      $return{$_} = $cust_main->get($_);
+    }
+
   } else { #no customer record
 
     my $svc_acct = qsearchs('svc_acct', { 'svcnum' => $session->{'svcnum'} } )
@@ -103,7 +128,6 @@ sub customer_info {
 
   }
 
-
   return { 'error'          => '',
            'custnum'        => $custnum,
            %return,
@@ -111,6 +135,125 @@ sub customer_info {
 
 }
 
+sub edit_info {
+  my $p = shift;
+  my $session = $cache->get($p->{'session_id'})
+    or return { 'error' => "Can't resume session" }; #better error message
+
+  my $custnum = $session->{'custnum'}
+    or return { 'error' => "no customer record" };
+
+  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+    or return { 'error' => "unknown custnum $custnum" };
+
+  my $new = new FS::cust_main { $cust_main->hash };
+  $new->set( $_ => $p->{$_} )
+    foreach grep { exists $p->{$_} } @cust_main_editable_fields;
+  my $error = $new->replace($cust_main);
+  return { 'error' => $error } if $error;
+  #$cust_main = $new;
+  
+  return { 'error' => '' };
+}
+
+sub payment_info {
+  my $p = shift;
+  my $session = $cache->get($p->{'session_id'})
+    or return { 'error' => "Can't resume session" }; #better error message
+
+  my %return;
+
+  my $custnum = $session->{'custnum'};
+
+  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+    or return { 'error' => "unknown custnum $custnum" };
+
+  $return{balance} = $cust_main->balance;
+
+  $return{payname} = $cust_main->payname
+                     || ( $cust_main->first. ' '. $cust_main->get('last') );
+
+  $return{$_} = $cust_main->get($_) for qw(address1 address2 city state zip);
+
+  $return{payby} = $cust_main->payby;
+
+  if ( $cust_main->payby =~ /^(CARD|DCRD)$/ ) {
+    warn $return{card_type} = cardtype($cust_main->payinfo);
+    $return{payinfo} = $cust_main->payinfo;
+
+    if ( $cust_main->paydate  =~ /^(\d{4})-(\d{2})-\d{2}$/ ) { #Pg date format
+      @return{'month', 'year'} = ( $2, $1 );
+    } elsif ( $cust_main->paydate =~ /^(\d{1,2})-(\d{1,2}-)?(\d{4}$)/ ) {
+      @return{'month', 'year'} = ( $1, $3 );
+    }
+
+  }
+
+  #list all counties/states/countries
+  $return{'cust_main_county'} = 
+      [ map { $_->hashref } qsearch('cust_main_county', {}) ],
+
+  #shortcut for one-country folks
+  my $conf = new FS::Conf;
+  my %states = map { $_->state => 1 }
+                 qsearch('cust_main_county', {
+                   'country' => $conf->config('defaultcountry') || 'US'
+                 } );
+  $return{'states'} = [ sort { $a cmp $b } keys %states ];
+
+  $return{card_types} = {
+    'VISA' => 'VISA card',
+    'MasterCard' => 'MasterCard',
+    'Discover' => 'Discover card',
+    'American Express' => 'American Express card',
+  };
+
+  my $_date = time;
+  $return{paybatch} = "webui-MyAccount-$_date-$$-". rand() * 2**32;
+
+  return { 'error' => '',
+           %return,
+         };
+
+};
+
+sub process_payment {
+  my $p = shift;
+
+  my $session = $cache->get($p->{'session_id'})
+    or return { 'error' => "Can't resume session" }; #better error message
+
+  my %return;
+
+  my $custnum = $session->{'custnum'};
+
+  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+    or return { 'error' => "unknown custnum $custnum" };
+
+  if ( $p->{'save'} ) {
+    my $new = new FS::cust_main { $cust_main->hash };
+    $new->set( $_ => $p->{$_} )
+      foreach qw( payname address1 address2 city state zip payinfo );
+    $new->set( 'paydate' => $p->{'year'}. '-'. $p->{'month'}. '-01' );
+    $new->set( 'payby' => $p->{'auto'} ? 'CARD' : 'DCRD' );
+    my $error = $new->replace($cust_main);
+    return { 'error' => $error } if $error;
+    $cust_main = $new;
+  }
+
+  my $error = $cust_main->realtime_bop( 'CC', $p->{'amount'}, quiet=>1,
+    'paydate' => $p->{'year'}. '-'. $p->{'month'}. '-01',
+    map { $_ => $p->{$_} }
+      qw( payname address1 address2 city state zip payinfo paybatch )
+  );
+  return { 'error' => $error } if $error;
+
+  $cust_main->apply_payments;
+
+  return { 'error' => '' };
+
+}
+
 sub invoice {
   my $p = shift;
   my $session = $cache->get($p->{'session_id'})
@@ -133,4 +276,135 @@ sub invoice {
 
 }
 
+sub cancel {
+  my $p = shift;
+  my $session = $cache->get($p->{'session_id'})
+    or return { 'error' => "Can't resume session" }; #better error message
+
+  my $custnum = $session->{'custnum'};
+
+  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+    or return { 'error' => "unknown custnum $custnum" };
+
+  my @errors = $cust_main->cancel( 'quiet'=>1 );
+
+  my $error = scalar(@errors) ? join(' / ', @errors) : '';
+
+  return { 'error' => $error };
+
+}
+
+sub list_pkgs {
+  my $p = shift;
+  my $session = $cache->get($p->{'session_id'})
+    or return { 'error' => "Can't resume session" }; #better error message
+
+  my $custnum = $session->{'custnum'};
+
+  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+    or return { 'error' => "unknown custnum $custnum" };
+
+  return { 'cust_pkg' => [ map { $_->hashref } $cust_main->ncancelled_pkgs ] };
+
+}
+
+sub order_pkg {
+  my $p = shift;
+  my $session = $cache->get($p->{'session_id'})
+    or return { 'error' => "Can't resume session" }; #better error message
+
+  my $custnum = $session->{'custnum'};
+
+  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+    or return { 'error' => "unknown custnum $custnum" };
+
+  #false laziness w/ClientAPI/Signup.pm
+
+  my $cust_pkg = new FS::cust_pkg ( {
+    'custnum' => $custnum,
+    'pkgpart' => $p->{'pkgpart'},
+  } );
+  my $error = $cust_pkg->check;
+  return { 'error' => $error } if $error;
+
+  my $svc_acct = new FS::svc_acct ( {
+    'svcpart'   => $p->{'svcpart'} || $cust_pkg->part_pkg->svcpart('svc_acct'),
+    map { $_ => $p->{$_} }
+      qw( username _password sec_phrase popnum ),
+  } );
+
+  my @acct_snarf;
+  my $snarfnum = 1;
+  while ( length($p->{"snarf_machine$snarfnum"}) ) {
+    my $acct_snarf = new FS::acct_snarf ( {
+      'machine'   => $p->{"snarf_machine$snarfnum"},
+      'protocol'  => $p->{"snarf_protocol$snarfnum"},
+      'username'  => $p->{"snarf_username$snarfnum"},
+      '_password' => $p->{"snarf_password$snarfnum"},
+    } );
+    $snarfnum++;
+    push @acct_snarf, $acct_snarf;
+  }
+  $svc_acct->child_objects( \@acct_snarf );
+
+  my $y = $svc_acct->setdefault; # arguably should be in new method
+  return { 'error' => $y } if $y && !ref($y);
+
+  $error = $svc_acct->check;
+  return { 'error' => $error } if $error;
+
+  use Tie::RefHash;
+  tie my %hash, 'Tie::RefHash';
+  %hash = ( $cust_pkg => [ $svc_acct ] );
+  #msgcat
+  $error = $cust_main->order_pkgs( \%hash, '', 'noexport' => 1 );
+  return { 'error' => $error } if $error;
+
+  my $conf = new FS::Conf;
+  if ( $conf->exists('signup_server-realtime') ) {
+
+    my $old_balance = $cust_main->balance;
+
+    my $bill_error = $cust_main->bill;
+    $cust_main->apply_payments;
+    $cust_main->apply_credits;
+    $bill_error = $cust_main->collect;
+
+    if ( $cust_main->balance > $old_balance ) {
+      $cust_pkg->cancel('quiet'=>1);
+      return { 'error' => '_decline' };
+    } else {
+      $cust_pkg->reexport;
+    }
+
+  } else {
+    $cust_pkg->reexport;
+  }
+
+  return { error => '' };
+
+}
+
+sub cancel_pkg {
+  my $p = shift;
+  my $session = $cache->get($p->{'session_id'})
+    or return { 'error' => "Can't resume session" }; #better error message
+
+  my $custnum = $session->{'custnum'};
+
+  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+    or return { 'error' => "unknown custnum $custnum" };
+
+  my $pkgnum = $session->{'pkgnum'};
+
+  my $cust_pkg = qsearchs('cust_pkg', { 'custnum' => $custnum,
+                                        'pkgnum'  => $pkgnum,   } )
+    or return { 'error' => "unknown pkgnum $pkgnum" };
+
+  my $error = $cust_main->cancel( 'quiet'=>1 );
+  return { 'error' => $error };
+
+}
+
+1;
 
diff --git a/FS/FS/ClientAPI/Signup.pm b/FS/FS/ClientAPI/Signup.pm
new file mode 100644 (file)
index 0000000..375958b
--- /dev/null
@@ -0,0 +1,235 @@
+package FS::ClientAPI::Signup;
+
+use strict;
+use Tie::RefHash;
+use FS::Conf;
+use FS::Record qw(qsearch qsearchs dbdef);
+use FS::agent;
+use FS::cust_main_county;
+use FS::part_pkg;
+use FS::svc_acct_pop;
+use FS::cust_main;
+use FS::cust_pkg;
+use FS::svc_acct;
+use FS::acct_snarf;
+use FS::Msgcat qw(gettext);
+
+use FS::ClientAPI; #hmm
+FS::ClientAPI->register_handlers(
+  'Signup/signup_info'  => \&signup_info,
+  'Signup/new_customer' => \&new_customer,
+);
+
+sub signup_info {
+  #my $packet = shift;
+
+  my $conf = new FS::Conf;
+
+  use vars qw($signup_info); #cache for performance;
+  $signup_info ||= {
+
+    'cust_main_county' =>
+      [ map { $_->hashref } qsearch('cust_main_county', {}) ],
+
+    'agent' =>
+      [
+        map { $_->hashref }
+          qsearch('agent', dbdef->table('agent')->column('disabled')
+                             ? { 'disabled' => '' }
+                             : {}
+                 )
+      ],
+
+    'part_referral' =>
+      [
+        map { $_->hashref }
+          qsearch('part_referral',
+                    dbdef->table('part_referral')->column('disabled')
+                      ? { 'disabled' => '' }
+                      : {}
+                 )
+      ],
+
+    'agentnum2part_pkg' =>
+      {
+        map {
+          my $href = $_->pkgpart_hashref;
+          $_->agentnum =>
+            [
+              map { { 'payby' => [ $_->payby ], %{$_->hashref} } }
+                grep { $_->svcpart('svc_acct') && $href->{ $_->pkgpart } }
+                  qsearch( 'part_pkg', { 'disabled' => '' } )
+            ];
+        } qsearch('agent', dbdef->table('agent')->column('disabled')
+                             ? { 'disabled' => '' }
+                             : {}
+                 )
+      },
+
+    'svc_acct_pop' => [ map { $_->hashref } qsearch('svc_acct_pop',{} ) ],
+
+    'security_phrase' => $conf->exists('security_phrase'),
+
+    'payby' => [ $conf->config('signup_server-payby') ],
+
+    'cvv_enabled' => defined dbdef->table('cust_main')->column('paycvv'),
+
+    'msgcat' => { map { $_=>gettext($_) } qw(
+      passwords_dont_match invalid_card unknown_card_type not_a
+    ) },
+
+    'statedefault' => $conf->config('statedefault') || 'CA',
+
+    'countrydefault' => $conf->config('countrydefault') || 'US',
+
+    'refnum' => $conf->config('signup_server-default_refnum'),
+
+  };
+
+  if (
+    $conf->config('signup_server-default_agentnum')
+    && !exists $signup_info->{'part_pkg'} #cache for performance
+  ) {
+    my $agentnum = $conf->config('signup_server-default_agentnum');
+    my $agent = qsearchs( 'agent', { 'agentnum' => $agentnum } )
+      or die "fatal: signup_server-default_agentnum $agentnum not found\n";
+    my $pkgpart_href = $agent->pkgpart_hashref;
+
+    $signup_info->{'part_pkg'} = [
+      #map { $_->hashref }
+      map { { 'payby' => [ $_->payby ], %{$_->hashref} } }
+        grep { $_->svcpart('svc_acct') && $pkgpart_href->{ $_->pkgpart } }
+          qsearch( 'part_pkg', { 'disabled' => '' } )
+    ];
+  }
+
+  $signup_info;
+
+}
+
+sub new_customer {
+  my $packet = shift;
+
+  my $conf = new FS::Conf;
+  
+  #things that aren't necessary in base class, but are for signup server
+    #return "Passwords don't match"
+    #  if $hashref->{'_password'} ne $hashref->{'_password2'}
+  return { 'error' => gettext('empty_password') }
+    unless $packet->{'_password'};
+  # a bit inefficient for large numbers of pops
+  return { 'error' => gettext('no_access_number_selected') }
+    unless $packet->{'popnum'} || !scalar(qsearch('svc_acct_pop',{} ));
+
+  #shares some stuff with htdocs/edit/process/cust_main.cgi... take any
+  # common that are still here and library them.
+  my $cust_main = new FS::cust_main ( {
+    #'custnum'          => '',
+    'agentnum'      => $packet->{agentnum}
+                       || $conf->config('signup_server-default_agentnum'),
+    'refnum'        => $packet->{refnum}
+                       || $conf->config('signup_server-default_refnum'),
+
+    map { $_ => $packet->{$_} } qw(
+      last first ss company address1 address2 city county state zip country
+      daytime night fax payby payinfo paycvv paydate payname referral_custnum
+      comments
+    ),
+
+  } );
+
+  return { 'error' => "Illegal payment type" }
+    unless grep { $_ eq $packet->{'payby'} }
+                $conf->config('signup_server-payby');
+
+  $cust_main->payinfo($cust_main->daytime)
+    if $cust_main->payby eq 'LECB' && ! $cust_main->payinfo;
+
+  my @invoicing_list = split( /\s*\,\s*/, $packet->{'invoicing_list'} );
+
+  $packet->{'pkgpart'} =~ /^(\d+)$/ or '' =~ /^()$/;
+  my $pkgpart = $1;
+  return { 'error' => 'Please select a package' } unless $pkgpart; #msgcat
+
+  my $part_pkg =
+    qsearchs( 'part_pkg', { 'pkgpart' => $pkgpart } )
+      or return { 'error' => "WARNING: unknown pkgpart: $pkgpart" };
+  my $svcpart = $part_pkg->svcpart('svc_acct');
+
+  my $cust_pkg = new FS::cust_pkg ( {
+    #later#'custnum' => $custnum,
+    'pkgpart' => $packet->{'pkgpart'},
+  } );
+  my $error = $cust_pkg->check;
+  return { 'error' => $error } if $error;
+
+  my $svc_acct = new FS::svc_acct ( {
+    'svcpart'   => $svcpart,
+    map { $_ => $packet->{$_} }
+      qw( username _password sec_phrase popnum ),
+  } );
+
+  my @acct_snarf;
+  my $snarfnum = 1;
+  while ( length($packet->{"snarf_machine$snarfnum"}) ) {
+    my $acct_snarf = new FS::acct_snarf ( {
+      'machine'   => $packet->{"snarf_machine$snarfnum"},
+      'protocol'  => $packet->{"snarf_protocol$snarfnum"},
+      'username'  => $packet->{"snarf_username$snarfnum"},
+      '_password' => $packet->{"snarf_password$snarfnum"},
+    } );
+    $snarfnum++;
+    push @acct_snarf, $acct_snarf;
+  }
+  $svc_acct->child_objects( \@acct_snarf );
+
+  my $y = $svc_acct->setdefault; # arguably should be in new method
+  return { 'error' => $y } if $y && !ref($y);
+
+  $error = $svc_acct->check;
+  return { 'error' => $error } if $error;
+
+  use Tie::RefHash;
+  tie my %hash, 'Tie::RefHash';
+  %hash = ( $cust_pkg => [ $svc_acct ] );
+  #msgcat
+  $error = $cust_main->insert( \%hash, \@invoicing_list, 'noexport' => 1 );
+  return { 'error' => $error } if $error;
+
+  if ( $conf->exists('signup_server-realtime') ) {
+
+    #warn "[fs_signup_server] Billing customer...\n" if $Debug;
+
+    my $bill_error = $cust_main->bill;
+    #warn "[fs_signup_server] error billing new customer: $bill_error"
+    #  if $bill_error;
+
+    $cust_main->apply_payments;
+    $cust_main->apply_credits;
+
+    $bill_error = $cust_main->collect;
+    #warn "[fs_signup_server] error collecting from new customer: $bill_error"
+    #  if $bill_error;
+
+    if ( $cust_main->balance > 0 ) {
+
+      #this makes sense.  credit is "un-doing" the invoice
+      $cust_main->credit( $cust_main->balance, 'signup server decline' );
+      $cust_main->apply_credits;
+
+      #should check list for errors...
+      #$cust_main->suspend;
+      local $FS::svc_Common::noexport_hack = 1;
+      $cust_main->cancel('quiet'=>1);
+
+      return { 'error' => '_decline' };
+    }
+
+  }
+  $cust_main->reexport;
+
+  return { error => '' };
+
+}
+
+1;
index 2960622..016ebff 100644 (file)
@@ -15,8 +15,9 @@ FS::ClientAPI->register_handlers(
 sub passwd {
   my $packet = shift;
 
-  #my $domain = qsearchs('svc_domain', { 'domain' => $packet->{'domain'} } )
-  #  or return { error => "Domain $domain not found" };
+  my $domain = $FS::ClientAPI::domain || $packet->{'domain'};
+  my $svc_domain = qsearchs('svc_domain', { 'domain' => $domain } )
+    or return { error => "Domain $domain not found" };
 
   my $old_password = $packet->{'old_password'};
   my $new_password = $packet->{'new_password'};
@@ -27,11 +28,11 @@ sub passwd {
   my $svc_acct =
     ( length($old_password) < 13
       && qsearchs( 'svc_acct', { 'username'  => $packet->{'username'},
-                                 #'domsvc'    => $svc_domain->svcnum,
+                                 'domsvc'    => $svc_domain->svcnum,
                                  '_password' => $old_password } )
     )
     || qsearchs( 'svc_acct', { 'username'  => $packet->{'username'},
-                               #'domsvc'    => $svc_domain->svcnum,
+                               'domsvc'    => $svc_domain->svcnum,
                                '_password' => $old_password } );
 
   unless ( $svc_acct ) { return { error => 'Incorrect password.' } }
index e93eaf3..99eee18 100644 (file)
@@ -174,7 +174,7 @@ sub config_items {
   my $self = shift; 
   #quelle kludge
   @config_items,
-  map { 
+  map { 
         my $basename = basename($_);
         $basename =~ /^(.*)$/;
         $basename = $1;
@@ -185,7 +185,19 @@ sub config_items {
                            'type'        => 'textarea',
                          }
       } glob($self->dir. '/invoice_template_*')
-  ;
+  ),
+  ( map { 
+        my $basename = basename($_);
+        $basename =~ /^(.*)$/;
+        $basename = $1;
+        new FS::ConfItem {
+                           'key'         => $basename,
+                           'section'     => 'billing',
+                           'description' => 'Alternate LaTeX template for invoices.  See the <a href="../docs/billing.html">billing documentation</a> for details.',
+                           'type'        => 'textarea',
+                         }
+      } glob($self->dir. '/invoice_latex_*')
+  );
 }
 
 =back
@@ -228,8 +240,8 @@ httemplate/docs/config.html
 
   {
     'key'         => 'apacheip',
-    'section'     => 'apache',
-    'description' => 'The current IP address to assign to new virtual hosts',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add an <i>apache</i> <a href="../browse/part_export.cgi">export</a> instead.  Used to be the current IP address to assign to new virtual hosts',
     'type'        => 'text',
   },
 
@@ -242,8 +254,8 @@ httemplate/docs/config.html
 
   {
     'key'         => 'apachemachines',
-    'section'     => 'apache',
-    'description' => 'Your Apache machines, one per line.  This enables export of `/etc/apache/vhosts.conf\', which can be included in your Apache configuration via the <a href="http://www.apache.org/docs/mod/core.html#include">Include</a> directive.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add an <i>apache</i> <a href="../browse/part_export.cgi">export</a> instead.  Used to be Apache machines, one per line.  This enables export of `/etc/apache/vhosts.conf\', which can be included in your Apache configuration via the <a href="http://www.apache.org/docs/mod/core.html#include">Include</a> directive.',
     'type'        => 'textarea',
   },
 
@@ -269,9 +281,16 @@ httemplate/docs/config.html
   },
 
   {
+    'key'         => 'business-onlinepayment-ach',
+    'section'     => 'billing',
+    'description' => 'Alternate <a href="http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment">Business::OnlinePayment</a> support for ACH transactions (defaults to regular <b>business-onlinepayment</b>).  At least three lines: processor, login, and password.  An optional fourth line specifies the action or actions (multiple actions are separated with `,\': for example: `Authorization Only, Post Authorization\').    Optional additional lines are passed to Business::OnlinePayment as %processor_options.',
+    'type'        => 'textarea',
+  },
+
+  {
     'key'         => 'business-onlinepayment-description',
     'section'     => 'billing',
-    'description' => 'String passed as the description field to <a href="http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment">Business::OnlinePayment</a>.  Evaluated as a double-quoted perl string, with the following variables available: <code>$agent</code> (the agent name), and <code>$pkgs</code> (a comma-separated list of packages to which the invoiced being charged applies)',
+    'description' => 'String passed as the description field to <a href="http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment">Business::OnlinePayment</a>.  Evaluated as a double-quoted perl string, with the following variables available: <code>$agent</code> (the agent name), and <code>$pkgs</code> (a comma-separated list of packages for which these charges apply)',
     'type'        => 'text',
   },
 
@@ -290,13 +309,6 @@ httemplate/docs/config.html
   },
 
   {
-    'key'         => 'cybercash3.2',
-    'section'     => 'billing',
-    'description' => '<a href="http://www.cybercash.com/cashregister/">CyberCash Cashregister v3.2</a> support.  Two lines: the full path and name of your merchant_conf file, and the transaction type (`mauthonly\' or `mauthcapture\').',
-    'type'        => 'textarea',
-  },
-
-  {
     'key'         => 'cyrus',
     'section'     => 'deprecated',
     'description' => '<b>DEPRECATED</b>, add a <i>cyrus</i> <a href="../browse/part_export.cgi">export</a> instead.  This option used to integrate with <a href="http://asg.web.cmu.edu/cyrus/imapd/">Cyrus IMAP Server</a>, three lines: IMAP server, admin username, and admin password.  Cyrus::IMAP::Admin should be installed locally and the connection to the server secured.',
@@ -320,11 +332,25 @@ httemplate/docs/config.html
   {
     'key'         => 'deletepayments',
     'section'     => 'UI',
-    'description' => 'Enable deletion of unclosed payments.  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.',
+    'description' => 'Enable deletion of unclosed payments.  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',
+    'section'     => 'UI',
+    'description' => 'Enable deletion of unclosed credits.  Be very careful!  Only delete credits that were data-entry errors, not adjustments.  Optionally specify one or more comma-separated email addresses to be notified when a credit is deleted.',
     'type'        => [qw( checkbox text )],
   },
 
   {
+    'key'         => 'unapplypayments',
+    'section'     => 'UI',
+    'description' => 'Enable "unapplication" of unclosed payments.',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'dirhash',
     'section'     => 'shell',
     'description' => 'Optional numeric value to control directory hashing.  If positive, hashes directories for the specified number of levels from the front of the username.  If negative, hashes directories for the specified number of levels from the end of the username.  Some examples: <ul><li>1: user -> <a href="#home">/home</a>/u/user<li>2: user -> <a href="#home">/home</a>/u/s/user<li>-1: user -> <a href="#home">/home</a>/r/user<li>-2: user -> <a href="#home">home</a>/r/e/user</ul>',
@@ -339,13 +365,6 @@ httemplate/docs/config.html
   },
 
   {
-    'key'         => 'domain',
-    'section'     => 'deprecated',
-    'description' => 'Your domain name.',
-    'type'        => 'text',
-  },
-
-  {
     'key'         => 'editreferrals',
     'section'     => 'UI',
     'description' => 'Enable advertising source modification for existing customers',
@@ -369,14 +388,21 @@ httemplate/docs/config.html
   {
     'key'         => 'emailinvoiceauto',
     'section'     => 'billing',
-    'description' => 'Automatically adds new accounts to the email invoice list upon customer creation',
+    'description' => 'Automatically adds new accounts to the email invoice list',
     'type'       => 'checkbox',
   },
 
   {
-    'key'         => 'erpcdmachines',
+    'key'         => 'exclude_ip_addr',
     'section'     => '',
-    'description' => 'Your ERPCD authenticaion machines, one per line.  This enables export of `/usr/annex/acp_passwd\' and `/usr/annex/acp_dialup\'',
+    'description' => 'Exclude these from the list of available broadband service IP addresses. (One per line)',
+    'type'        => 'textarea',
+  },
+  
+  {
+    'key'         => 'erpcdmachines',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, ERPCD is no longer supported.  Used to be ERPCD authenticaion machines, one per line.  This enables export of `/usr/annex/acp_passwd\' and `/usr/annex/acp_dialup\'',
     'type'        => 'textarea',
   },
 
@@ -411,21 +437,21 @@ httemplate/docs/config.html
   {
     'key'         => 'icradius_mysqldest',
     'section'     => 'deprecated',
-    'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> https://billing.crosswind.net/freeside/browse/part_export.cgi">export</a> instead.  Used to be the destination directory for the MySQL databases, on the ICRADIUS/FreeRADIUS machines.  Defaults to "/usr/local/var/".',
+    'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> <a href="../browse/part_export.cgi">export</a> instead.  Used to be the destination directory for the MySQL databases, on the ICRADIUS/FreeRADIUS machines.  Defaults to "/usr/local/var/".',
     'type'        => 'text',
   },
 
   {
     'key'         => 'icradius_mysqlsource',
     'section'     => 'deprecated',
-    'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> https://billing.crosswind.net/freeside/browse/part_export.cgi">export</a> instead.  Used to be the source directory for for the MySQL radcheck table files, on the Freeside machine.  Defaults to "/usr/local/var/freeside".',
+    'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> <a href="../browse/part_export.cgi">export</a> instead.  Used to be the source directory for for the MySQL radcheck table files, on the Freeside machine.  Defaults to "/usr/local/var/freeside".',
     'type'        => 'text',
   },
 
   {
     'key'         => 'icradius_secrets',
     'section'     => 'deprecated',
-    'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> https://billing.crosswind.net/freeside/browse/part_export.cgi">export</a> instead.  This option used to specify a database for ICRADIUS/FreeRADIUS export.  Three lines: DBI data source, username and password.',
+    'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> <a href="../browse/part_export.cgi">export</a> instead.  This option used to specify a database for ICRADIUS/FreeRADIUS export.  Three lines: DBI data source, username and password.',
     'type'        => 'textarea',
   },
 
@@ -444,6 +470,49 @@ httemplate/docs/config.html
   },
 
   {
+    'key'         => 'invoice_latex',
+    'section'     => 'billing',
+    'description' => 'Optional LaTeX template for typeset PostScript invoices.',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'invoice_latexnotes',
+    'section'     => 'billing',
+    'description' => 'Notes section for LaTeX typeset PostScript invoices.',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'invoice_latexfooter',
+    'section'     => 'billing',
+    'description' => 'Footer for LaTeX typeset PostScript invoices.',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'invoice_latexsmallfooter',
+    'section'     => 'billing',
+    'description' => 'Optional small footer for multi-page LaTeX typeset PostScript invoices.',
+    'type'        => 'textarea',
+  },
+
+  { 
+    'key'         => 'invoice_default_terms',
+    'section'     => 'billing',
+    'description' => 'Optional default invoice term, used to calculate a due date printed on invoices.',
+    'type'        => 'select',
+    'select_enum' => [ '', 'Payable upon receipt', 'Net 0', 'Net 10', 'Net 15', 'Net 30', 'Net 45', 'Net 60' ],
+  },
+
+  {
+    'key'         => 'invoice_send_receipts',
+    'section'     => 'billing',
+    'description' => 'Send receipts for payments and credits.',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'lpr',
     'section'     => 'required',
     'description' => 'Print command for paper invoices, for example `lpr -h\'',
@@ -527,8 +596,8 @@ httemplate/docs/config.html
 
   {
     'key'         => 'qmailmachines',
-    'section'     => 'mail',
-    'description' => 'Your qmail machines, one per line.  This enables export of `/var/qmail/control/virtualdomains\', `/var/qmail/control/recipientmap\', and `/var/qmail/control/rcpthosts\'.  Setting this option (even if empty) also turns on user `.qmail-extension\' file maintenance in conjunction with the <b>shellmachine</b> option.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add <i>qmail</i> and <i>shellcommands</i> <a href="../browse/part_export.cgi">exports</a> instead.  This option used to export `/var/qmail/control/virtualdomains\', `/var/qmail/control/recipientmap\', and `/var/qmail/control/rcpthosts\'.  Setting this option (even if empty) also turns on user `.qmail-extension\' file maintenance in conjunction with the <b>shellmachine</b> option.',
     'type'        => [qw( checkbox textarea )],
   },
 
@@ -569,22 +638,22 @@ httemplate/docs/config.html
 
   {
     'key'         => 'sendmailconfigpath',
-    'section'     => 'mail',
-    'description' => 'Sendmail configuration file path.  Defaults to `/etc\'.  Many newer distributions use `/etc/mail\'.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>sendmail</i> <a href="../browse/part_export.cgi">export</a> instead.  Used to be sendmail configuration file path.  Defaults to `/etc\'.  Many newer distributions use `/etc/mail\'.',
     'type'        => 'text',
   },
 
   {
     'key'         => 'sendmailmachines',
-    'section'     => 'mail',
-    'description' => 'Your sendmail machines, one per line.  This enables export of `/etc/virtusertable\' and `/etc/sendmail.cw\'.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>sendmail</i> <a href="../browse/part_export.cgi">export</a> instead.  Used to be sendmail machines, one per line.  This enables export of `/etc/virtusertable\' and `/etc/sendmail.cw\'.',
     'type'        => 'textarea',
   },
 
   {
     'key'         => 'sendmailrestart',
-    'section'     => 'mail',
-    'description' => 'If defined, the command which is run on sendmail machines after files are copied.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>sendmail</i> <a href="../browse/part_export.cgi">export</a> instead.  Used to define the command which is run on sendmail machines after files are copied.',
     'type'        => 'text',
   },
 
@@ -753,7 +822,7 @@ httemplate/docs/config.html
   {
     'key'         => 'username-ampersand',
     'section'     => 'username',
-    'description' => 'Allow the ampersand character (&amp;) in usernames.  Be careful when using this option in conjunction with <a href="#shellmachine-useradd">shellmachine-useradd</a> and other configuration options which execute shell commands, as the ampersand will be interpreted by the shell if not quoted.',
+    'description' => 'Allow the ampersand character (&amp;) in usernames.  Be careful when using this option in conjunction with <a href="../browse/part_export.cgi">exports</a> which execute shell commands, as the ampersand will be interpreted by the shell if not quoted.',
     'type'        => 'checkbox',
   },
 
@@ -801,7 +870,7 @@ httemplate/docs/config.html
 
   {
     'key'         => 'username_policy',
-    'section'     => '',
+    'section'     => 'deprecated',
     'description' => 'This file controls the mechanism for preventing duplicate usernames in passwd/radius files exported from svc_accts.  This should be one of \'prepend domsvc\' \'append domsvc\' \'append domain\' or \'append @domain\'',
     'type'        => 'select',
     'select_enum' => [ 'prepend domsvc', 'append domsvc', 'append domain', 'append @domain' ],
@@ -811,14 +880,14 @@ httemplate/docs/config.html
   {
     'key'         => 'vpopmailmachines',
     'section'     => 'deprecated',
-    'description' => '<b>DEPRECATED</b>, add a <i>cp</i> <a href="../browse/part_export.cgi">export</a> instead.  This option used to contain your vpopmail pop toasters, one per line.  Each line is of the form "machinename vpopdir vpopuid vpopgid".  For example: <code>poptoaster.domain.tld /home/vpopmail 508 508</code>  Note: vpopuid and vpopgid are values taken from the vpopmail machine\'s /etc/passwd',
+    'description' => '<b>DEPRECATED</b>, add a <i>vpopmail</i> <a href="../browse/part_export.cgi">export</a> instead.  This option used to contain your vpopmail pop toasters, one per line.  Each line is of the form "machinename vpopdir vpopuid vpopgid".  For example: <code>poptoaster.domain.tld /home/vpopmail 508 508</code>  Note: vpopuid and vpopgid are values taken from the vpopmail machine\'s /etc/passwd',
     'type'        => 'textarea',
   },
 
   {
     'key'         => 'vpopmailrestart',
-    'section'     => 'mail',
-    'description' => 'If defined, the shell commands to run on vpopmail machines after files are copied.  An example can be found in eg/vpopmailrestart of the source distribution.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>vpopmail</i> <a href="../browse/part_export.cgi">export</a> instead.  This option used to define the shell commands to run on vpopmail machines after files are copied.  An example can be found in eg/vpopmailrestart of the source distribution.',
     'type'        => 'textarea',
   },
 
@@ -880,20 +949,47 @@ httemplate/docs/config.html
   },
 
   {
+    'key'         => 'selfservice_server-quiet',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, the self-service server no longer sends superfluous decline and cancel emails.  Used to disable decline and cancel emails generated by transactions initiated by the selfservice server.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'signup_server-quiet',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, the signup server is now part of the self-service server and no longer sends superfluous decline and cancel emails.  Used to disable decline and cancel emails generated by transactions initiated by the signup server.  Does not disable welcome emails.',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'signup_server-payby',
     'section'     => '',
     'description' => 'Acceptable payment types for the signup server',
     'type'        => 'selectmultiple',
-    'select_enum' => [ qw(CARD PREPAY BILL COMP) ],
+    'select_enum' => [ qw(CARD DCRD CHEK DCHK LECB PREPAY BILL COMP) ],
   },
 
   {
     'key'         => 'signup_server-email',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, this feature is no longer available.  See the ***fill me in*** report instead.  Used to contain a comma-separated list of email addresses to receive notification of signups via the signup server.',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'signup_server-default_agentnum',
     'section'     => '',
-    'description' => 'Comma-separated list of email addresses to receive notification of signups via the signup server.',
+    'description' => 'Default agentnum for the signup server',
     'type'        => 'text',
   },
 
+  {
+    'key'         => 'signup_server-default_refnum',
+    'section'     => '',
+    'description' => 'Default advertising source number for the signup server',
+    'type'        => 'text',
+  },
 
   {
     'key'         => 'show-msgcat-codes',
@@ -924,6 +1020,34 @@ httemplate/docs/config.html
   },
 
   {
+    'key'         => 'emaildecline-exclude',
+    'section'     => 'billing',
+    'description' => 'List of error messages that should not trigger email decline notices, one per line.',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'cancelmessage',
+    'section'     => 'billing',
+    'description' => 'Template file for cancellation emails.',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'cancelsubject',
+    'section'     => 'billing',
+    'description' => 'Subject line for cancellation emails.',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'emailcancel',
+    'section'     => 'billing',
+    'description' => 'Enable emailing of cancellation notices.',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'require_cardname',
     'section'     => 'billing',
     'description' => 'Require an "Exact name on card" to be entered explicitly; don\'t default to using the first and last name.',
@@ -966,6 +1090,87 @@ httemplate/docs/config.html
     'select_enum' => [ 'text/plain', 'text/html' ],
   },
 
+  {
+    'key'         => 'payby-default',
+    '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 COMP HIDE) ],
+  },
+
+  {
+    'key'         => 'svc_acct-notes',
+    'section'     => 'UI',
+    'description' => 'Extra HTML to be displayed on the Account View screen.',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'radius-password',
+    'section'     => '',
+    'description' => 'RADIUS attribute for plain-text passwords.',
+    'type'        => 'select',
+    'select_enum' => [ 'Password', 'User-Password' ],
+  },
+
+  {
+    'key'         => 'radius-ip',
+    'section'     => '',
+    'description' => 'RADIUS attribute for IP addresses.',
+    'type'        => 'select',
+    'select_enum' => [ 'Framed-IP-Address', 'Framed-Address' ],
+  },
+
+  {
+    'key'         => 'svc_acct-alldomains',
+    'section'     => '',
+    'description' => 'Allow accounts to select any domain in the database.  Normally accounts can only select from the domain set in the service definition and those purchased by the customer.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'dump-scpdest',
+    'section'     => '',
+    'description' => 'destination for scp database dumps: user@host:/path',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'users-allow_comp',
+    'section'     => '',
+    'description' => 'Usernames (Freeside users, created with <a href="../docs/man/bin/freeside-adduser.html">freeside-adduser</a>) which can create complimentary customers, one per line.  If no usernames are entered, all users can create complimentary accounts.',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'cvv-save',
+    'section'     => 'billing',
+    'description' => 'Save CVV2 information after the initial transaction for the selected credit card types.  Enabling this option may be in violation of your merchant agreement(s), so please check them carefully before enabling this option for any credit card types.',
+    'type'        => 'selectmultiple',
+    'select_enum' => [ "VISA card",
+                       "MasterCard",
+                       "Discover card",
+                       "American Express card",
+                       "Diner's Club/Carte Blanche",
+                       "enRoute",
+                       "JCB",
+                       "BankCard",
+                     ],
+  },
+
+  {
+    'key'         => 'allow_negative_charges',
+    'section'     => 'billing',
+    'description' => 'Allow negative charges.  Normally not used unless importing data from a legacy system that requires this.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'system_usernames',
+    'section'     => 'username',
+    'description' => 'A list of system usernames that cannot be edited or removed, one per line.  Use a bare username to prohibit modification/deletion of the username in any domain, or username@domain to prohibit modification/deletetion of a specific username and domain.',
+    'type'        => 'textarea',
+  },
 );
 
 1;
index 87f507c..5038cf3 100644 (file)
@@ -1,5 +1,9 @@
 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);
@@ -48,7 +52,6 @@ sub handler {
   use FS::session;
   use FS::svc_acct;
   use FS::svc_acct_pop;
-  use FS::svc_acct_sm;
   use FS::svc_domain;
   use FS::svc_forward;
   use FS::svc_www;
diff --git a/FS/FS/Misc.pm b/FS/FS/Misc.pm
new file mode 100644 (file)
index 0000000..efad2df
--- /dev/null
@@ -0,0 +1,102 @@
+package FS::Misc;
+
+use strict;
+use vars qw ( @ISA @EXPORT_OK );
+use Exporter;
+
+@ISA = qw( Exporter );
+@EXPORT_OK = qw( send_email );
+
+=head1 NAME
+
+FS::Misc - Miscellaneous subroutines
+
+=head1 SYNOPSIS
+
+  use FS::Misc qw(send_email);
+
+  send_email();
+
+=head1 DESCRIPTION
+
+Miscellaneous subroutines.  This module contains miscellaneous subroutines
+called from multiple other modules.  These are not OO or necessarily related,
+but are collected here to elimiate code duplication.
+
+=head1 SUBROUTINES
+
+=over 4
+
+=item send_email OPTION => VALUE ...
+
+Options:
+
+I<from> - (required)
+
+I<to> - (required) comma-separated scalar or arrayref of recipients
+
+I<subject> - (required)
+
+I<content-type> - (optional) MIME type
+
+I<body> - (required) arrayref of body text lines
+
+=cut
+
+use vars qw( $conf );
+use Date::Format;
+use Mail::Header;
+use Mail::Internet 1.44;
+use FS::UID;
+
+FS::UID->install_callback( sub {
+  $conf = new FS::Conf;
+} );
+
+sub send_email {
+  my(%options) = @_;
+
+  $ENV{MAILADDRESS} = $options{'from'};
+  my $to = ref($options{to}) ? join(', ', @{ $options{to} } ) : $options{to};
+  my @header = (
+    'From: '.     $options{'from'},
+    'To: '.       $to,
+    'Sender: '.   $options{'from'},
+    'Reply-To: '. $options{'from'},
+    'Date: '.     time2str("%a, %d %b %Y %X %z", time),
+    'Subject: '.  $options{'subject'},
+  );
+  push @header, 'Content-Type: '. $options{'content-type'}
+    if exists($options{'content-type'});
+  my $header = new Mail::Header ( \@header );
+
+  my $message = new Mail::Internet (
+    'Header' => $header,
+    'Body'   => $options{'body'},
+  );
+
+  my $smtpmachine = $conf->config('smtpmachine');
+  $!=0;
+
+  my $rv = $message->smtpsend( 'Host' => $smtpmachine )
+    or $message->smtpsend( Host => $smtpmachine, Debug => 1 );
+
+  if ($rv) { #smtpsend returns a list of addresses, not true/false
+    return '';
+  } else {
+    return "can't send email to $to via server $smtpmachine with SMTP: $!";
+  }  
+
+}
+
+=head1 BUGS
+
+This package exists.
+
+=head1 SEE ALSO
+
+L<FS::UID>, L<FS::CGI>, L<FS::Record>, the base documentation.
+
+=cut
+
+1;
index e6126a1..801b89d 100644 (file)
@@ -2,18 +2,22 @@ package FS::Record;
 
 use strict;
 use vars qw( $dbdef_file $dbdef $setup_hack $AUTOLOAD @ISA @EXPORT_OK $DEBUG
-             $me %dbdef_cache );
+             $me %dbdef_cache %virtual_fields_cache );
 use subs qw(reload_dbdef);
 use Exporter;
 use Carp qw(carp cluck croak confess);
 use File::CounterFile;
 use Locale::Country;
 use DBI qw(:sql_types);
-use DBIx::DBSchema 0.19;
-use FS::UID qw(dbh checkruid getotaker datasrc driver_name);
+use DBIx::DBSchema 0.23;
+use FS::UID qw(dbh getotaker datasrc driver_name);
 use FS::SearchCache;
 use FS::Msgcat qw(gettext);
 
+use FS::part_virtual_field;
+
+use Tie::IxHash;
+
 @ISA = qw(Exporter);
 @EXPORT_OK = qw(dbh fields hfields qsearch qsearchs dbdef jsearch);
 
@@ -60,14 +64,12 @@ FS::Record - Database record objects
     $hashref = $record->hashref;
 
     $error = $record->insert;
-    #$error = $record->add; #deprecated
 
     $error = $record->delete;
-    #$error = $record->del; #deprecated
 
     $error = $new_record->replace($old_record);
-    #$error = $new_record->rep($old_record); #deprecated
 
+    # external use deprecated - handled by the database (at least for Pg, mysql)
     $value = $record->unique('column');
 
     $error = $record->ut_float('column');
@@ -88,7 +90,7 @@ FS::Record - Database record objects
 
     $quoted_value = _quote($value,'table','field');
 
-    #depriciated
+    #deprecated
     $fields = hfields('table');
     if ( $fields->{Field} ) { # etc.
 
@@ -167,7 +169,7 @@ sub create {
   my $self = {};
   bless ($self, $class);
   if ( defined $self->table ) {
-    cluck "create constructor is depriciated, use new!";
+    cluck "create constructor is deprecated, use new!";
     $self->new(@_);
   } else {
     croak "FS::Record::create called (not from a subclass)!";
@@ -202,45 +204,101 @@ sub qsearch {
   my $dbh = dbh;
 
   my $table = $cache ? $cache->table : $stable;
+  my $pkey = $dbdef->table($table)->primary_key;
 
-  my @fields = grep exists($record->{$_}), fields($table);
+  my @real_fields = grep exists($record->{$_}), real_fields($table);
+  my @virtual_fields = grep exists($record->{$_}), "FS::$table"->virtual_fields;
 
   my $statement = "SELECT $select FROM $stable";
-  if ( @fields ) {
-    $statement .= ' WHERE '. join(' AND ', map {
+  if ( @real_fields or @virtual_fields ) {
+    $statement .= ' WHERE '. join(' AND ',
+      ( map {
 
       my $op = '=';
+      my $column = $_;
       if ( ref($record->{$_}) ) {
         $op = $record->{$_}{'op'} if $record->{$_}{'op'};
-        $op = 'LIKE' if $op =~ /^ILIKE$/i && driver_name !~ /^Pg$/i;
+        #$op = 'LIKE' if $op =~ /^ILIKE$/i && driver_name ne 'Pg';
+        if ( uc($op) eq 'ILIKE' ) {
+          $op = 'LIKE';
+          $record->{$_}{'value'} = lc($record->{$_}{'value'});
+          $column = "LOWER($_)";
+        }
         $record->{$_} = $record->{$_}{'value'}
       }
 
       if ( ! defined( $record->{$_} ) || $record->{$_} eq '' ) {
         if ( $op eq '=' ) {
-          if ( driver_name =~ /^Pg$/i ) {
-            qq-( $_ IS NULL OR $_ = '' )-;
+          if ( driver_name eq 'Pg' ) {
+            my $type = $dbdef->table($table)->column($column)->type;
+            if ( $type =~ /(int|serial)/i ) {
+              qq-( $column IS NULL )-;
+            } else {
+              qq-( $column IS NULL OR $column = '' )-;
+            }
           } else {
-            qq-( $_ IS NULL OR $_ = "" )-;
+            qq-( $column IS NULL OR $column = "" )-;
           }
         } elsif ( $op eq '!=' ) {
-          if ( driver_name =~ /^Pg$/i ) {
-            qq-( $_ IS NOT NULL AND $_ != '' )-;
+          if ( driver_name eq 'Pg' ) {
+            my $type = $dbdef->table($table)->column($column)->type;
+            if ( $type =~ /(int|serial)/i ) {
+              qq-( $column IS NOT NULL )-;
+            } else {
+              qq-( $column IS NOT NULL AND $column != '' )-;
+            }
           } else {
-            qq-( $_ IS NOT NULL AND $_ != "" )-;
+            qq-( $column IS NOT NULL AND $column != "" )-;
           }
         } else {
-          if ( driver_name =~ /^Pg$/i ) {
-            qq-( $_ $op '' )-;
+          if ( driver_name eq 'Pg' ) {
+            qq-( $column $op '' )-;
           } else {
-            qq-( $_ $op "" )-;
+            qq-( $column $op "" )-;
           }
         }
       } else {
-        "$_ $op ?";
+        "$column $op ?";
       }
-    } @fields );
+    } @real_fields ), 
+    ( map {
+      my $op = '=';
+      my $column = $_;
+      if ( ref($record->{$_}) ) {
+        $op = $record->{$_}{'op'} if $record->{$_}{'op'};
+       if ( uc($op) eq 'ILIKE' ) {
+         $op = 'LIKE';
+         $record->{$_}{'value'} = lc($record->{$_}{'value'});
+         $column = "LOWER($_)";
+       }
+       $record->{$_} = $record->{$_}{'value'};
+      }
+
+      # ... EXISTS ( SELECT name, value FROM part_virtual_field
+      #              JOIN virtual_field
+      #              ON part_virtual_field.vfieldpart = virtual_field.vfieldpart
+      #              WHERE recnum = svc_acct.svcnum
+      #              AND (name, value) = ('egad', 'brain') )
+
+      my $value = $record->{$_};
+
+      my $subq;
+
+      $subq = ($value ? 'EXISTS ' : 'NOT EXISTS ') .
+      "( SELECT part_virtual_field.name, virtual_field.value ".
+      "FROM part_virtual_field JOIN virtual_field ".
+      "ON part_virtual_field.vfieldpart = virtual_field.vfieldpart ".
+      "WHERE virtual_field.recnum = ${table}.${pkey} ".
+      "AND part_virtual_field.name = '${column}'".
+      ($value ? 
+        " AND virtual_field.value ${op} '${value}'"
+      : "") . ")";
+      $subq;
+
+    } @virtual_fields ) );
+
   }
+
   $statement .= " $extra_sql" if defined($extra_sql);
 
   warn "[debug]$me $statement\n" if $DEBUG > 1;
@@ -250,10 +308,10 @@ sub qsearch {
   my $bind = 1;
 
   foreach my $field (
-    grep defined( $record->{$_} ) && $record->{$_} ne '', @fields
+    grep defined( $record->{$_} ) && $record->{$_} ne '', @real_fields
   ) {
     if ( $record->{$field} =~ /^\d+(\.\d+)?$/
-         && $dbdef->table($table)->column($field)->type =~ /(int)/i
+         && $dbdef->table($table)->column($field)->type =~ /(int|serial)/i
     ) {
       $sth->bind_param($bind++, $record->{$field}, { TYPE => SQL_INTEGER } );
     } else {
@@ -267,31 +325,64 @@ sub qsearch {
 
   $sth->execute or croak "Error executing \"$statement\": ". $sth->errstr;
 
-  $dbh->commit or croak $dbh->errstr if $FS::UID::AutoCommit;
+  my %result;
+  tie %result, "Tie::IxHash";
+  @virtual_fields = "FS::$table"->virtual_fields;
 
+  my @stuff = @{ $sth->fetchall_arrayref( {} ) };
+  if($pkey) {
+    %result = map { $_->{$pkey}, $_ } @stuff;
+  } else {
+    @result{@stuff} = @stuff;
+  }
+
+  $sth->finish;
+  if ( keys(%result) and @virtual_fields ) {
+    $statement =
+      "SELECT virtual_field.recnum, part_virtual_field.name, ".
+             "virtual_field.value ".
+      "FROM part_virtual_field JOIN virtual_field USING (vfieldpart) ".
+      "WHERE part_virtual_field.dbtable = '$table' AND ".
+      "virtual_field.recnum IN (".
+      join(',', keys(%result)). ") AND part_virtual_field.name IN ('".
+      join(q!', '!, @virtual_fields) . "')";
+    warn "[debug]$me $statement\n" if $DEBUG > 1;
+    $sth = $dbh->prepare($statement) or croak "$dbh->errstr doing $statement";
+    $sth->execute or croak "Error executing \"$statement\": ". $sth->errstr;
+
+    foreach (@{ $sth->fetchall_arrayref({}) }) {
+      my $recnum = $_->{recnum};
+      my $name = $_->{name};
+      my $value = $_->{value};
+      if (exists($result{$recnum})) {
+        $result{$recnum}->{$name} = $value;
+      }
+    }
+  }
+  
   if ( eval 'scalar(@FS::'. $table. '::ISA);' ) {
     if ( eval 'FS::'. $table. '->can(\'new\')' eq \&new ) {
       #derivied class didn't override new method, so this optimization is safe
       if ( $cache ) {
         map {
           new_or_cached( "FS::$table", { %{$_} }, $cache )
-        } @{$sth->fetchall_arrayref( {} )};
+        } values(%result);
       } else {
         map {
           new( "FS::$table", { %{$_} } )
-        } @{$sth->fetchall_arrayref( {} )};
+        } values(%result);
       }
     } else {
       warn "untested code (class FS::$table uses custom new method)";
       map {
         eval 'FS::'. $table. '->new( { %{$_} } )';
-      } @{$sth->fetchall_arrayref( {} )};
+      } values(%result);
     }
   } else {
     cluck "warning: FS::$table not loaded; returning FS::Record objects";
     map {
       FS::Record->new( $table, { %{$_} } );
-    } @{$sth->fetchall_arrayref( {} )};
+    } values(%result);
   }
 
 }
@@ -326,9 +417,11 @@ for a single item, or your data is corrupted.
 =cut
 
 sub qsearchs { # $result_record = &FS::Record:qsearchs('table',\%hash);
+  my $table = $_[0];
   my(@result) = qsearch(@_);
-  carp "warning: Multiple records in scalar search!" if scalar(@result) > 1;
-    #should warn more vehemently if the search was on a primary key?
+  carp "warning: Multiple records in scalar search ($table)"
+    if scalar(@result) > 1;
+  #should warn more vehemently if the search was on a primary key?
   scalar(@result) ? ($result[0]) : ();
 }
 
@@ -345,7 +438,7 @@ Returns the table name.
 =cut
 
 sub table {
-#  cluck "warning: FS::Record::table depriciated; supply one in subclass!";
+#  cluck "warning: FS::Record::table deprecated; supply one in subclass!";
   my $self = shift;
   $self -> {'Table'};
 }
@@ -412,11 +505,11 @@ sub AUTOLOAD {
   $field =~ s/.*://;
   if ( defined($value) ) {
     confess "errant AUTOLOAD $field for $self (arg $value)"
-      unless $self->can('setfield');
+      unless ref($self) && $self->can('setfield');
     $self->setfield($field,$value);
   } else {
     confess "errant AUTOLOAD $field for $self (no args)"
-      unless $self->can('getfield');
+      unless ref($self) && $self->can('getfield');
     $self->getfield($field);
   }    
 }
@@ -472,25 +565,41 @@ sub insert {
   return $error if $error;
 
   #single-field unique keys are given a value if false
-  #(like MySQL's AUTO_INCREMENT)
+  #(like MySQL's AUTO_INCREMENT or Pg SERIAL)
   foreach ( $self->dbdef_table->unique->singles ) {
     $self->unique($_) unless $self->getfield($_);
   }
-  #and also the primary key
+
+  #and also the primary key, if the database isn't going to
   my $primary_key = $self->dbdef_table->primary_key;
-  $self->unique($primary_key) 
-    if $primary_key && ! $self->getfield($primary_key);
+  my $db_seq = 0;
+  if ( $primary_key ) {
+    my $col = $self->dbdef_table->column($primary_key);
+    
+    $db_seq =
+      uc($col->type) eq 'SERIAL'
+      || ( driver_name eq 'Pg'
+             && defined($col->default)
+             && $col->default =~ /^nextval\(/i
+         )
+      || ( driver_name eq 'mysql'
+             && defined($col->local)
+             && $col->local =~ /AUTO_INCREMENT/i
+         );
+    $self->unique($primary_key) unless $self->getfield($primary_key) || $db_seq;
+  }
 
+  my $table = $self->table;
   #false laziness w/delete
-  my @fields =
+  my @real_fields =
     grep defined($self->getfield($_)) && $self->getfield($_) ne "",
-    $self->fields
+    real_fields($table)
   ;
-  my @values = map { _quote( $self->getfield($_), $self->table, $_) } @fields;
+  my @values = map { _quote( $self->getfield($_), $table, $_) } @real_fields;
   #eslaf
 
-  my $statement = "INSERT INTO ". $self->table. " ( ".
-      join( ', ', @fields ).
+  my $statement = "INSERT INTO $table ( ".
+      join( ', ', @real_fields ).
     ") VALUES (".
       join( ', ', @values ).
     ")"
@@ -498,15 +607,6 @@ sub insert {
   warn "[debug]$me $statement\n" if $DEBUG > 1;
   my $sth = dbh->prepare($statement) or return dbh->errstr;
 
-  my $h_sth;
-  if ( defined $dbdef->table('h_'. $self->table) ) {
-    my $h_statement = $self->_h_statement('insert');
-    warn "[debug]$me $h_statement\n" if $DEBUG > 2;
-    $h_sth = dbh->prepare($h_statement) or return dbh->errstr;
-  } else {
-    $h_sth = '';
-  }
-
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
   local $SIG{QUIT} = 'IGNORE'; 
@@ -515,7 +615,92 @@ sub insert {
   local $SIG{PIPE} = 'IGNORE';
 
   $sth->execute or return $sth->errstr;
+
+  my $insertid = '';
+  if ( $db_seq ) { # get inserted id from the database, if applicable
+    warn "[debug]$me retreiving sequence from database\n" if $DEBUG;
+    if ( driver_name eq 'Pg' ) {
+
+      my $oid = $sth->{'pg_oid_status'};
+      my $i_sql = "SELECT $primary_key FROM $table WHERE oid = ?";
+      my $i_sth = dbh->prepare($i_sql) or do {
+        dbh->rollback if $FS::UID::AutoCommit;
+        return dbh->errstr;
+      };
+      $i_sth->execute($oid) or do {
+        dbh->rollback if $FS::UID::AutoCommit;
+        return $i_sth->errstr;
+      };
+      $insertid = $i_sth->fetchrow_arrayref->[0];
+
+    } elsif ( driver_name eq 'mysql' ) {
+
+      $insertid = dbh->{'mysql_insertid'};
+      # work around mysql_insertid being null some of the time, ala RT :/
+      unless ( $insertid ) {
+        warn "WARNING: DBD::mysql didn't return mysql_insertid; ".
+             "using SELECT LAST_INSERT_ID();";
+        my $i_sql = "SELECT LAST_INSERT_ID()";
+        my $i_sth = dbh->prepare($i_sql) or do {
+          dbh->rollback if $FS::UID::AutoCommit;
+          return dbh->errstr;
+        };
+        $i_sth->execute or do {
+          dbh->rollback if $FS::UID::AutoCommit;
+          return $i_sth->errstr;
+        };
+        $insertid = $i_sth->fetchrow_arrayref->[0];
+      }
+
+    } else {
+      dbh->rollback if $FS::UID::AutoCommit;
+      return "don't know how to retreive inserted ids from ". driver_name. 
+             ", try using counterfiles (maybe run dbdef-create?)";
+    }
+    $self->setfield($primary_key, $insertid);
+  }
+
+  my @virtual_fields = 
+      grep defined($self->getfield($_)) && $self->getfield($_) ne "",
+          $self->virtual_fields;
+  if (@virtual_fields) {
+    my %v_values = map { $_, $self->getfield($_) } @virtual_fields;
+
+    my $vfieldpart = $self->vfieldpart_hashref;
+
+    my $v_statement = "INSERT INTO virtual_field(recnum, vfieldpart, value) ".
+                    "VALUES (?, ?, ?)";
+
+    my $v_sth = dbh->prepare($v_statement) or do {
+      dbh->rollback if $FS::UID::AutoCommit;
+      return dbh->errstr;
+    };
+
+    foreach (keys(%v_values)) {
+      $v_sth->execute($self->getfield($primary_key),
+                      $vfieldpart->{$_},
+                      $v_values{$_})
+      or do {
+        dbh->rollback if $FS::UID::AutoCommit;
+        return $v_sth->errstr;
+      };
+    }
+  }
+
+
+  my $h_sth;
+  if ( defined $dbdef->table('h_'. $table) ) {
+    my $h_statement = $self->_h_statement('insert');
+    warn "[debug]$me $h_statement\n" if $DEBUG > 2;
+    $h_sth = dbh->prepare($h_statement) or do {
+      dbh->rollback if $FS::UID::AutoCommit;
+      return dbh->errstr;
+    };
+  } else {
+    $h_sth = '';
+  }
   $h_sth->execute or return $h_sth->errstr if $h_sth;
+
   dbh->commit or croak dbh->errstr if $FS::UID::AutoCommit;
 
   '';
@@ -528,7 +713,7 @@ Depriciated (use insert instead).
 =cut
 
 sub add {
-  cluck "warning: FS::Record::add depriciated!";
+  cluck "warning: FS::Record::add deprecated!";
   insert @_; #call method in this scope
 }
 
@@ -546,14 +731,14 @@ sub delete {
     map {
       $self->getfield($_) eq ''
         #? "( $_ IS NULL OR $_ = \"\" )"
-        ? ( driver_name =~ /^Pg$/i
+        ? ( driver_name eq 'Pg'
               ? "$_ IS NULL"
               : "( $_ IS NULL OR $_ = \"\" )"
           )
         : "$_ = ". _quote($self->getfield($_),$self->table,$_)
     } ( $self->dbdef_table->primary_key )
           ? ( $self->dbdef_table->primary_key)
-          : $self->fields
+          : real_fields($self->table)
   );
   warn "[debug]$me $statement\n" if $DEBUG > 1;
   my $sth = dbh->prepare($statement) or return dbh->errstr;
@@ -567,6 +752,19 @@ sub delete {
     $h_sth = '';
   }
 
+  my $primary_key = $self->dbdef_table->primary_key;
+  my $v_sth;
+  my @del_vfields;
+  my $vfp = $self->vfieldpart_hashref;
+  foreach($self->virtual_fields) {
+    next if $self->getfield($_) eq '';
+    unless(@del_vfields) {
+      my $st = "DELETE FROM virtual_field WHERE recnum = ? AND vfieldpart = ?";
+      $v_sth = dbh->prepare($st) or return dbh->errstr;
+    }
+    push @del_vfields, $_;
+  }
+
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
   local $SIG{QUIT} = 'IGNORE'; 
@@ -577,6 +775,10 @@ sub delete {
   my $rc = $sth->execute or return $sth->errstr;
   #not portable #return "Record not found, statement:\n$statement" if $rc eq "0E0";
   $h_sth->execute or return $h_sth->errstr if $h_sth;
+  $v_sth->execute($self->getfield($primary_key), $vfp->{$_}) 
+    or return $v_sth->errstr 
+        foreach (@del_vfields);
+  
   dbh->commit or croak dbh->errstr if $FS::UID::AutoCommit;
 
   #no need to needlessly destoy the data either (causes problems actually)
@@ -592,7 +794,7 @@ Depriciated (use delete instead).
 =cut
 
 sub del {
-  cluck "warning: FS::Record::del depriciated!";
+  cluck "warning: FS::Record::del deprecated!";
   &delete(@_); #call method in this scope
 }
 
@@ -604,7 +806,24 @@ returns the error, otherwise returns false.
 =cut
 
 sub replace {
-  my ( $new, $old ) = ( shift, shift );
+  my $new = shift;
+
+  my $old;
+  if ( @_ ) { 
+    $old = shift;
+  } else {
+    warn "[debug]$me replace called with no arguments; autoloading old record\n"
+     if $DEBUG;
+    my $primary_key = $new->dbdef_table->primary_key;
+    if ( $primary_key ) {
+      $old = qsearchs($new->table, { $primary_key => $new->$primary_key() } )
+        or croak "can't find ". $new->table. ".$primary_key ".
+                 $new->$primary_key();
+    } else {
+      croak $new->table. " has no primary key; pass old record as argument";
+    }
+  }
+
   warn "[debug]$me $new ->replace $old\n" if $DEBUG;
 
   return "Records not in same table!" unless $new->table eq $old->table;
@@ -617,8 +836,11 @@ sub replace {
   my $error = $new->check;
   return $error if $error;
 
-  my @diff = grep $new->getfield($_) ne $old->getfield($_), $old->fields;
-  unless ( @diff ) {
+  #my @diff = grep $new->getfield($_) ne $old->getfield($_), $old->fields;
+  my %diff = map { ($new->getfield($_) ne $old->getfield($_))
+                   ? ($_, $new->getfield($_)) : () } $old->fields;
+                   
+  unless ( keys(%diff) ) {
     carp "[warning]$me $new -> replace $old: records identical";
     return '';
   }
@@ -626,18 +848,18 @@ sub replace {
   my $statement = "UPDATE ". $old->table. " SET ". join(', ',
     map {
       "$_ = ". _quote($new->getfield($_),$old->table,$_) 
-    } @diff
+    } real_fields($old->table)
   ). ' WHERE '.
     join(' AND ',
       map {
         $old->getfield($_) eq ''
           #? "( $_ IS NULL OR $_ = \"\" )"
-          ? ( driver_name =~ /^Pg$/i
-                ? "$_ IS NULL"
+          ? ( driver_name eq 'Pg'
+                ? "( $_ IS NULL OR $_ = '' )"
                 : "( $_ IS NULL OR $_ = \"\" )"
             )
           : "$_ = ". _quote($old->getfield($_),$old->table,$_)
-      } ( $primary_key ? ( $primary_key ) : $old->fields )
+      } ( $primary_key ? ( $primary_key ) : real_fields($old->table) )
     )
   ;
   warn "[debug]$me $statement\n" if $DEBUG > 1;
@@ -661,6 +883,44 @@ sub replace {
     $h_new_sth = '';
   }
 
+  # For virtual fields we have three cases with different SQL 
+  # statements: add, replace, delete
+  my $v_add_sth;
+  my $v_rep_sth;
+  my $v_del_sth;
+  my (@add_vfields, @rep_vfields, @del_vfields);
+  my $vfp = $old->vfieldpart_hashref;
+  foreach(grep { exists($diff{$_}) } $new->virtual_fields) {
+    if($diff{$_} eq '') {
+      # Delete
+      unless(@del_vfields) {
+        my $st = "DELETE FROM virtual_field WHERE recnum = ? ".
+                 "AND vfieldpart = ?";
+        warn "[debug]$me $st\n" if $DEBUG > 2;
+        $v_del_sth = dbh->prepare($st) or return dbh->errstr;
+      }
+      push @del_vfields, $_;
+    } elsif($old->getfield($_) eq '') {
+      # Add
+      unless(@add_vfields) {
+        my $st = "INSERT INTO virtual_field (value, recnum, vfieldpart) ".
+                "VALUES (?, ?, ?)";
+        warn "[debug]$me $st\n" if $DEBUG > 2;
+        $v_add_sth = dbh->prepare($st) or return dbh->errstr;
+      }
+      push @add_vfields, $_;
+    } else {
+      # Replace
+      unless(@rep_vfields) {
+        my $st = "UPDATE virtual_field SET value = ? ".
+                 "WHERE recnum = ? AND vfieldpart = ?";
+        warn "[debug]$me $st\n" if $DEBUG > 2;
+        $v_rep_sth = dbh->prepare($st) or return dbh->errstr;
+      }
+      push @rep_vfields, $_;
+    }
+  }
+
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
   local $SIG{QUIT} = 'IGNORE'; 
@@ -672,6 +932,24 @@ sub replace {
   #not portable #return "Record not found (or records identical)." if $rc eq "0E0";
   $h_old_sth->execute or return $h_old_sth->errstr if $h_old_sth;
   $h_new_sth->execute or return $h_new_sth->errstr if $h_new_sth;
+
+  $v_del_sth->execute($old->getfield($primary_key),
+                      $vfp->{$_})
+        or return $v_del_sth->errstr
+      foreach(@del_vfields);
+
+  $v_add_sth->execute($new->getfield($_),
+                      $old->getfield($primary_key),
+                      $vfp->{$_})
+        or return $v_add_sth->errstr
+      foreach(@add_vfields);
+
+  $v_rep_sth->execute($new->getfield($_),
+                      $old->getfield($primary_key),
+                      $vfp->{$_})
+        or return $v_rep_sth->errstr
+      foreach(@rep_vfields);
+
   dbh->commit or croak dbh->errstr if $FS::UID::AutoCommit;
 
   '';
@@ -685,18 +963,34 @@ Depriciated (use replace instead).
 =cut
 
 sub rep {
-  cluck "warning: FS::Record::rep depriciated!";
+  cluck "warning: FS::Record::rep deprecated!";
   replace @_; #call method in this scope
 }
 
 =item check
 
-Not yet implemented, croaks.  Derived classes should provide a check method.
+Checks virtual fields (using check_blocks).  Subclasses should still provide 
+a check method to validate real fields, foreign keys, etc., and call this 
+method via $self->SUPER::check.
+
+(FIXME: Should this method try to make sure that it I<is> being called from 
+a subclass's check method, to keep the current semantics as far as possible?)
 
 =cut
 
 sub check {
-  confess "FS::Record::check not implemented; supply one in subclass!";
+  #confess "FS::Record::check not implemented; supply one in subclass!";
+  my $self = shift;
+
+  foreach my $field ($self->virtual_fields) {
+    for ($self->getfield($field)) {
+      # See notes on check_block in FS::part_virtual_field.
+      eval $self->pvf($field)->check_block;
+      return $@ if $@;
+      $self->setfield($field, $_);
+    }
+  }
+  '';
 }
 
 sub _h_statement {
@@ -704,7 +998,7 @@ sub _h_statement {
 
   my @fields =
     grep defined($self->getfield($_)) && $self->getfield($_) ne "",
-    $self->fields
+    real_fields($self->table);
   ;
   my @values = map { _quote( $self->getfield($_), $self->table, $_) } @fields;
 
@@ -718,8 +1012,13 @@ sub _h_statement {
 
 =item unique COLUMN
 
-Replaces COLUMN in record with a unique number.  Called by the B<add> method
-on primary keys and single-field unique columns (see L<DBIx::DBSchema::Table>).
+B<Warning>: External use is B<deprecated>.  
+
+Replaces COLUMN in record with a unique number, using counters in the
+filesystem.  Used by the B<insert> method on single-field unique columns
+(see L<DBIx::DBSchema::Table>) and also as a fallback for primary keys
+that aren't SERIAL (Pg) or AUTO_INCREMENT (mysql).
+
 Returns the new value.
 
 =cut
@@ -728,8 +1027,6 @@ sub unique {
   my($self,$field) = @_;
   my($table)=$self->table;
 
-  #croak("&FS::UID::checkruid failed") unless &checkruid;
-
   croak "Unique called on field $field, but it is ",
         $self->getfield($field),
         ", not null!"
@@ -745,9 +1042,8 @@ sub unique {
 #  my($counter) = new File::CounterFile "$user/$table.$field",0;
 # endhack
 
-  my($index)=$counter->inc;
-  $index=$counter->inc
-    while qsearchs($table,{$field=>$index}); #just in case
+  my $index = $counter->inc;
+  $index = $counter->inc while qsearchs($table, { $field=>$index } );
 
   $index =~ /^(\d*)$/;
   $index=$1;
@@ -774,6 +1070,21 @@ sub ut_float {
   '';
 }
 
+=item ut_snumber COLUMN
+
+Check/untaint signed numeric data (whole numbers).  May not be null.  If there
+is an error, returns the error, otherwise returns false.
+
+=cut
+
+sub ut_snumber {
+  my($self, $field) = @_;
+  $self->getfield($field) =~ /^(-?)\s*(\d+)$/
+    or return "Illegal or empty (numeric) $field: ". $self->getfield($field);
+  $self->setfield($field, "$1$2");
+  '';
+}
+
 =item ut_number COLUMN
 
 Check/untaint simple numeric data (whole numbers).  May not be null.  If there
@@ -930,7 +1241,7 @@ sub ut_ip {
   $self->getfield($field) =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
     or return "Illegal (IP address) $field: ". $self->getfield($field);
   for ( $1, $2, $3, $4 ) { return "Illegal (IP address) $field" if $_ > 255; }
-  $self->setfield($field, "$1.$2.$3.$3");
+  $self->setfield($field, "$1.$2.$3.$4");
   '';
 }
 
@@ -1083,36 +1394,94 @@ sub ut_foreign_keyn {
     : '';
 }
 
+
+=item virtual_fields [ TABLE ]
+
+Returns a list of virtual fields defined for the table.  This should not 
+be exported, and should only be called as an instance or class method.
+
+=cut
+
+sub virtual_fields {
+  my $self = shift;
+  my $table;
+  $table = $self->table or confess "virtual_fields called on non-table";
+
+  confess "Unknown table $table" unless $dbdef->table($table);
+
+  return () unless $self->dbdef->table('part_virtual_field');
+
+  unless ( $virtual_fields_cache{$table} ) {
+    my $query = 'SELECT name from part_virtual_field ' .
+                "WHERE dbtable = '$table'";
+    my $dbh = dbh;
+    my $result = $dbh->selectcol_arrayref($query);
+    confess $dbh->errstr if $dbh->err;
+    $virtual_fields_cache{$table} = $result;
+  }
+
+  @{$virtual_fields_cache{$table}};
+
+}
+
+
 =item fields [ TABLE ]
 
-This can be used as both a subroutine and a method call.  It returns a list
-of the columns in this record's table, or an explicitly specified table.
-(See L<DBIx::DBSchema::Table>).
+This is a wrapper for real_fields and virtual_fields.  Code that called
+fields before should probably continue to call fields.
 
 =cut
 
-# Usage: @fields = fields($table);
-#        @fields = $record->fields;
 sub fields {
   my $something = shift;
   my $table;
-  if ( ref($something) ) {
+  if($something->isa('FS::Record')) {
     $table = $something->table;
   } else {
     $table = $something;
+    $something = "FS::$table";
   }
-  #croak "Usage: \@fields = fields(\$table)\n   or: \@fields = \$record->fields" unless $table;
-  my($table_obj) = $dbdef->table($table);
-  confess "Unknown table $table" unless $table_obj;
-  $table_obj->columns;
+  return (real_fields($table), $something->virtual_fields());
 }
 
 =back
 
+=item pvf FIELD_NAME
+
+Returns the FS::part_virtual_field object corresponding to a field in the 
+record (specified by FIELD_NAME).
+
+=cut
+
+sub pvf {
+  my ($self, $name) = (shift, shift);
+
+  if(grep /^$name$/, $self->virtual_fields) {
+    return qsearchs('part_virtual_field', { dbtable => $self->table,
+                                            name    => $name } );
+  }
+  ''
+}
+
 =head1 SUBROUTINES
 
 =over 4
 
+=item real_fields [ TABLE ]
+
+Returns a list of the real columns in the specified table.  Called only by 
+fields() and other subroutines elsewhere in FS::Record.
+
+=cut
+
+sub real_fields {
+  my $table = shift;
+
+  my($table_obj) = $dbdef->table($table);
+  confess "Unknown table $table" unless $table_obj;
+  $table_obj->columns;
+}
+
 =item reload_dbdef([FILENAME])
 
 Load a database definition (see L<DBIx::DBSchema>), optionally from a
@@ -1151,28 +1520,60 @@ type (see L<DBIx::DBSchema::Column>) does not end in `char' or `binary'.
 =cut
 
 sub _quote {
-  my($value,$table,$field)=@_;
-  my($dbh)=dbh;
-  if ( $value =~ /^\d+(\.\d+)?$/ && 
-#       ! ( datatype($table,$field) =~ /^char/ ) 
-       ! $dbdef->table($table)->column($field)->type =~ /(char|binary|text)$/i 
-  ) {
+  my($value, $table, $column) = @_;
+  my $column_obj = $dbdef->table($table)->column($column);
+  my $column_type = $column_obj->type;
+
+  if ( $value eq '' && $column_type =~ /^int/ ) {
+    if ( $column_obj->null ) {
+      'NULL';
+    } else {
+      cluck "WARNING: Attempting to set non-null integer $table.$column null; ".
+            "using 0 instead";
+      0;
+    }
+  } elsif ( $value =~ /^\d+(\.\d+)?$/ && 
+            ! $column_type =~ /(char|binary|text)$/i ) {
     $value;
   } else {
-    $dbh->quote($value);
+    dbh->quote($value);
   }
 }
 
+=item vfieldpart_hashref TABLE
+
+Returns a hashref of virtual field names and vfieldparts applicable to the given
+TABLE.
+
+=cut
+
+sub vfieldpart_hashref {
+  my $self = shift;
+  my $table = $self->table;
+
+  return {} unless $self->dbdef->table('part_virtual_field');
+
+  my $dbh = dbh;
+  my $statement = "SELECT vfieldpart, name FROM part_virtual_field WHERE ".
+                  "dbtable = '$table'";
+  my $sth = $dbh->prepare($statement);
+  $sth->execute or croak "Execution of '$statement' failed: ".$dbh->errstr;
+  return { map { $_->{name}, $_->{vfieldpart} } 
+    @{$sth->fetchall_arrayref({})} };
+
+}
+
+
 =item hfields TABLE
 
-This is depriciated.  Don't use it.
+This is deprecated.  Don't use it.
 
 It returns a hash-type list with the fields of this record's table set true.
 
 =cut
 
 sub hfields {
-  carp "warning: hfields is depriciated";
+  carp "warning: hfields is deprecated";
   my($table)=@_;
   my(%hash);
   foreach (fields($table)) {
@@ -1208,7 +1609,7 @@ sub DESTROY { return; }
 This module should probably be renamed, since much of the functionality is
 of general use.  It is not completely unlike Adapter::DBI (see below).
 
-Exported qsearch and qsearchs should be depriciated in favor of method calls
+Exported qsearch and qsearchs should be deprecated in favor of method calls
 (against an FS::Record object like the old search and searchs that qsearch
 and qsearchs were on top of.)
 
@@ -1216,7 +1617,7 @@ The whole fields / hfields mess should be removed.
 
 The various WHERE clauses should be subroutined.
 
-table string should be depriciated in favor of DBIx::DBSchema::Table.
+table string should be deprecated in favor of DBIx::DBSchema::Table.
 
 No doubt we could benefit from a Tied hash.  Documenting how exists / defined
 true maps to the database (and WHERE clauses) would also help.
index 0b10612..8271f89 100644 (file)
@@ -3,8 +3,8 @@ package FS::UID;
 use strict;
 use vars qw(
   @ISA @EXPORT_OK $cgi $dbh $freeside_uid $user 
-  $conf_dir $secrets $datasrc $db_user $db_pass %callback $driver_name
-  $AutoCommit
+  $conf_dir $secrets $datasrc $db_user $db_pass %callback @callback
+  $driver_name $AutoCommit
 );
 use subs qw(
   getsecrets cgisetotaker
@@ -95,9 +95,33 @@ sub forksuidsetup {
     # breaks multi-database installs # delete $callback{$_}; #run once
   }
 
+  &{$_} foreach @callback;
+
   $dbh;
 }
 
+=item install_callback
+
+A package can install a callback to be run in adminsuidsetup by passing
+a coderef to the FS::UID->install_callback class method.  If adminsuidsetup has
+run already, the callback will also be run immediately.
+
+    $coderef = sub { warn "Hi, I'm returning your call!" };
+    FS::UID->install_callback($coderef);
+
+    install_callback FS::UID sub { 
+      warn "Hi, I'm returning your call!"
+    };
+
+=cut
+
+sub install_callback {
+  my $class = shift;
+  my $callback = shift;
+  push @callback, $callback;
+  &{$callback} if $dbh;
+}
+
 =item cgisuidsetup CGI_object
 
 Takes a single argument, which is a CGI (see L<CGI>) or Apache (see L<Apache>)
@@ -246,17 +270,28 @@ sub getsecrets {
 
 =head1 CALLBACKS
 
-Warning: this interface is likely to change in future releases.
+Warning: this interface is (still) likely to change in future releases.
 
-A package can install a callback to be run in adminsuidsetup by putting a
-coderef into the hash %FS::UID::callback :
+New (experimental) callback interface:
+
+A package can install a callback to be run in adminsuidsetup by passing
+a coderef to the FS::UID->install_callback class method.  If adminsuidsetup has
+run already, the callback will also be run immediately.
 
     $coderef = sub { warn "Hi, I'm returning your call!" };
-    $FS::UID::callback{'Package::Name'};
+    FS::UID->install_callback($coderef);
+
+    install_callback FS::UID sub { 
+      warn "Hi, I'm returning your call!"
+    };
 
-=head1 VERSION
+Old (deprecated) callback interface:
 
-$Id: UID.pm,v 1.18 2002-07-03 11:23:25 ivan Exp $
+A package can install a callback to be run in adminsuidsetup by putting a
+coderef into the hash %FS::UID::callback :
+
+    $coderef = sub { warn "Hi, I'm returning your call!" };
+    $FS::UID::callback{'Package::Name'} = $coderef;
 
 =head1 BUGS
 
@@ -269,7 +304,7 @@ cgisuidsetup will go away as well.
 
 Goes through contortions to support non-OO syntax with multiple datasrc's.
 
-Callbacks are inelegant.
+Callbacks are (still) inelegant.
 
 =head1 SEE ALSO
 
diff --git a/FS/FS/acct_snarf.pm b/FS/FS/acct_snarf.pm
new file mode 100644 (file)
index 0000000..b4e88bf
--- /dev/null
@@ -0,0 +1,128 @@
+package FS::acct_snarf;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record;
+
+@ISA = qw( FS::Record );
+
+=head1 NAME
+
+FS::acct_snarf - Object methods for acct_snarf records
+
+=head1 SYNOPSIS
+
+  use FS::acct_snarf;
+
+  $record = new FS::acct_snarf \%hash;
+  $record = new FS::acct_snarf { 'column' => 'value' };
+
+  $error = $record->insert;
+
+  $error = $new_record->replace($old_record);
+
+  $error = $record->delete;
+
+  $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::svc_acct object represents an external mail account, typically for
+download of mail.  FS::acct_snarf inherits from FS::Record.  The following
+fields are currently supported:
+
+=over 4
+
+=item snarfnum - primary key
+
+=item svcnum - Account (see L<FS::svc_acct>)
+
+=item machine - external machine to download mail from
+
+=item protocol - protocol (pop3, imap, etc.)
+
+=item username - external login username
+
+=item _password - external login password
+
+=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<hash> method.
+
+=cut
+
+sub table { 'acct_snarf'; }
+
+=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 external mail account.  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('snarfnum')
+    || $self->ut_number('svcnum')
+    || $self->ut_foreign_key('svcnum', 'svc_acct', 'svcnum')
+    || $self->ut_domain('machine')
+    || $self->ut_alphan('protocol')
+    || $self->ut_textn('username')
+  ;
+  return $error if $error;
+
+  $self->_password =~ /^[^\t\n]*$/ or return "illegal password";
+  $self->_password($1);
+
+  ''; #no error
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::Record>, schema.html from the base documentation.
+
+=cut
+
+1;
+
diff --git a/FS/FS/addr_block.pm b/FS/FS/addr_block.pm
new file mode 100755 (executable)
index 0000000..1fb6060
--- /dev/null
@@ -0,0 +1,331 @@
+package FS::addr_block;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record qw( qsearchs qsearch dbh );
+use FS::router;
+use FS::svc_broadband;
+use FS::Conf;
+use NetAddr::IP;
+
+@ISA = qw( FS::Record );
+
+=head1 NAME
+
+FS::addr_block - Object methods for addr_block records
+
+=head1 SYNOPSIS
+
+  use FS::addr_block;
+
+  $record = new FS::addr_block \%hash;
+  $record = new FS::addr_block { 'column' => 'value' };
+
+  $error = $record->insert;
+
+  $error = $new_record->replace($old_record);
+
+  $error = $record->delete;
+
+  $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::addr_block record describes an address block assigned for broadband 
+access.  FS::addr_block inherits from FS::Record.  The following fields are 
+currently supported:
+
+=over 4
+
+=item blocknum - primary key, used in FS::svc_broadband to associate 
+services to the block.
+
+=item routernum - the router (see FS::router) to which this 
+block is assigned.
+
+=item ip_gateway - the gateway address used by customers within this block.  
+
+=item ip_netmask - the netmask of the block, expressed as an integer.
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Create a new record.  To add the record to the database, see "insert".
+
+=cut
+
+sub table { 'addr_block'; }
+
+=item insert
+
+Adds this record to the database.  If there is an error, returns the error,
+otherwise returns false.
+
+=item delete
+
+Deletes this record from the database.  If there is an error, returns the
+error, otherwise returns false.
+
+sub delete {
+  my $self = shift;
+  return 'Block must be deallocated before deletion'
+    if $self->router;
+
+  $self->SUPER::delete;
+}
+
+=item replace OLD_RECORD
+
+Replaces 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_number('routernum')
+    || $self->ut_ip('ip_gateway')
+    || $self->ut_number('ip_netmask')
+  ;
+  return $error if $error;
+
+
+  # A routernum of 0 indicates an unassigned block and is allowed
+  return "Unknown routernum"
+    if ($self->routernum and not $self->router);
+
+  my $self_addr = $self->NetAddr;
+  return "Cannot parse address: ". $self->ip_gateway . '/' . $self->ip_netmask
+    unless $self_addr;
+
+  if (not $self->blocknum) {
+    my @block = grep {
+      my $block_addr = $_->NetAddr;
+      if($block_addr->contains($self_addr) 
+      or $self_addr->contains($block_addr)) { $_; };
+    } qsearch( 'addr_block', {});
+    foreach(@block) {
+      return "Block intersects existing block ".$_->ip_gateway."/".$_->ip_netmask;
+    }
+  }
+
+  $self->SUPER::check;
+}
+
+
+=item router
+
+Returns the FS::router object corresponding to this object.  If the 
+block is unassigned, returns undef.
+
+=cut
+
+sub router {
+  my $self = shift;
+  return qsearchs('router', { routernum => $self->routernum });
+}
+
+=item svc_broadband
+
+Returns a list of FS::svc_broadband objects associated
+with this object.
+
+=cut
+
+sub svc_broadband {
+  my $self = shift;
+  return qsearch('svc_broadband', { blocknum => $self->blocknum });
+}
+
+=item NetAddr
+
+Returns a NetAddr::IP object for this block's address and netmask.
+
+=cut
+
+sub NetAddr {
+  my $self = shift;
+
+  return new NetAddr::IP ($self->ip_gateway, $self->ip_netmask);
+}
+
+=item next_free_addr
+
+Returns a NetAddr::IP object corresponding to the first unassigned address 
+in the block (other than the network, broadcast, or gateway address).  If 
+there are no free addresses, returns false.
+
+=cut
+
+sub next_free_addr {
+  my $self = shift;
+
+  my $conf = new FS::Conf;
+  my @excludeaddr = $conf->config('exclude_ip_addr');
+  
+my @used =
+( (map { $_->NetAddr->addr }
+    ($self,
+     qsearch('svc_broadband', { blocknum => $self->blocknum }))
+  ), @excludeaddr
+);
+
+  my @free = $self->NetAddr->hostenum;
+  while (my $ip = shift @free) {
+    if (not grep {$_ eq $ip->addr;} @used) { return $ip; };
+  }
+
+  '';
+
+}
+
+=item allocate
+
+Allocates this address block to a router.  Takes an FS::router object 
+as an argument.
+
+At present it's not possible to reallocate a block to a different router 
+except by deallocating it first, which requires that none of its addresses 
+be assigned.  This is probably as it should be.
+
+=cut
+
+sub allocate {
+  my ($self, $router) = @_;
+
+  return 'Block is already allocated'
+    if($self->router);
+
+  return 'Block must be allocated to a router'
+    unless(ref $router eq 'FS::router');
+
+  my @svc = $self->svc_broadband;
+  if (@svc) {
+    return 'Block has assigned addresses: '. join ', ', map {$_->ip_addr} @svc;
+  }
+
+  my $new = new FS::addr_block {$self->hash};
+  $new->routernum($router->routernum);
+  return $new->replace($self);
+
+}
+
+=item deallocate
+
+Deallocates the block (i.e. sets the routernum to 0).  If any addresses in the 
+block are assigned to services, it fails.
+
+=cut
+
+sub deallocate {
+  my $self = shift;
+
+  my @svc = $self->svc_broadband;
+  if (@svc) {
+    return 'Block has assigned addresses: '. join ', ', map {$_->ip_addr} @svc;
+  }
+
+  my $new = new FS::addr_block {$self->hash};
+  $new->routernum(0);
+  return $new->replace($self);
+}
+
+=item split_block
+
+Splits this address block into two equal blocks, occupying the same space as
+the original block.  The first of the two will also have the same blocknum.
+The gateway address of each block will be set to the first usable address, i.e.
+(network address)+1.  Since this method is designed for use on unallocated
+blocks, this is probably the correct behavior.
+
+(At present, splitting allocated blocks is disallowed.  Anyone who wants to
+implement this is reminded that each split costs three addresses, and any
+customers who were using these addresses will have to be moved; depending on
+how full the block was before being split, they might have to be moved to a
+different block.  Anyone who I<still> wants to implement it is asked to tie it
+to a configuration switch so that site admins can disallow it.)
+
+=cut
+
+sub split_block {
+
+  # We should consider using Attribute::Handlers/Aspect/Hook::LexWrap/
+  # something to atomicize functions, so that we can say 
+  #
+  # sub split_block : atomic {
+  # 
+  # instead of repeating all this AutoCommit verbage in every 
+  # sub that does more than one database operation.
+
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+  my $dbh = dbh;
+
+  my $self = shift;
+  my $error;
+
+  if ($self->router) {
+    return 'Block is already allocated';
+  }
+
+  #TODO: Smallest allowed block should be a config option.
+  if ($self->NetAddr->masklen() ge 30) {
+    return 'Cannot split blocks with a mask length >= 30';
+  }
+
+  my (@new, @ip);
+  $ip[0] = $self->NetAddr;
+  @ip = map {$_->first()} $ip[0]->split($self->ip_netmask + 1);
+
+  foreach (0,1) {
+    $new[$_] = new FS::addr_block {$self->hash};
+    $new[$_]->ip_gateway($ip[$_]->addr);
+    $new[$_]->ip_netmask($ip[$_]->masklen);
+  }
+
+  $new[1]->blocknum('');
+
+  $error = $new[0]->replace($self);
+  if ($error) {
+    $dbh->rollback;
+    return $error;
+  }
+
+  $error = $new[1]->insert;
+  if ($error) {
+    $dbh->rollback;
+    return $error;
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  return '';
+}
+
+=item merge
+
+To be implemented.
+
+=back
+
+=head1 BUGS
+
+Minimum block size should be a config option.  It's hardcoded at /30 right
+now because that's the smallest block that makes any sense at all.
+
+=cut
+
+1;
+
index f11a28d..2f70d65 100644 (file)
@@ -50,6 +50,12 @@ from FS::Record.  The following fields are currently supported:
 
 =item freq - For future use.
 
+=item disabled - Disabled flag, empty or 'Y'
+
+=item username - Username for the Agent interface
+
+=item _password - Password for the Agent interface
+
 =back
 
 =head1 METHODS
@@ -110,11 +116,28 @@ sub check {
   ;
   return $error if $error;
 
+  if ( $self->dbdef_table->column('disabled') ) {
+    $error = $self->ut_enum('disabled', [ '', 'Y' ] );
+    return $error if $error;
+  }
+
+  if ( $self->dbdef_table->column('username') ) {
+    $error = $self->ut_alphan('username');
+    return $error if $error;
+    if ( length($self->username) ) {
+      my $conflict = qsearchs('agent', { 'username' => $self->username } );
+      return 'duplicate agent username (with '. $conflict->agent. ')'
+        if $conflict;
+      $error = $self->ut_text('password'); # ut_text... arbitrary choice
+    } else {
+      $self->_password('');
+    }
+  }
+
   return "Unknown typenum!"
     unless $self->agent_type;
 
-  '';
-
+  $self->SUPER::check;
 }
 
 =item agent_type
@@ -145,7 +168,7 @@ sub pkgpart_hashref {
 
 =head1 VERSION
 
-$Id: agent.pm,v 1.3 2002-03-24 18:23:47 ivan Exp $
+$Id: agent.pm,v 1.6 2003-09-30 15:01:46 ivan Exp $
 
 =head1 BUGS
 
index 988533a..5ba5ef2 100644 (file)
@@ -102,7 +102,8 @@ sub check {
   my $self = shift;
 
   $self->ut_numbern('typenum')
-  or $self->ut_text('atype');
+  or $self->ut_text('atype')
+  or $self->SUPER::check;
 
 }
 
@@ -150,7 +151,7 @@ sub pkgpart {
 
 =head1 VERSION
 
-$Id: agent_type.pm,v 1.1 1999-08-04 09:03:53 ivan Exp $
+$Id: agent_type.pm,v 1.2 2003-08-05 00:20:40 khoff Exp $
 
 =head1 BUGS
 
index 5a9fdd0..a3e7662 100644 (file)
@@ -2,16 +2,12 @@ package FS::cust_bill;
 
 use strict;
 use vars qw( @ISA $conf $money_char );
-use vars qw( $lpr $invoice_from $smtpmachine );
-use vars qw( $processor );
-use vars qw( $xaction $E_NoErr );
-use vars qw( $bop_processor $bop_login $bop_password $bop_action @bop_options );
 use vars qw( $invoice_lines @buf ); #yuck
 use Date::Format;
-use Mail::Internet 1.44;
-use Mail::Header;
 use Text::Template;
+use FS::UID qw( datasrc );
 use FS::Record qw( qsearch qsearchs );
+use FS::Misc qw( send_email );
 use FS::cust_main;
 use FS::cust_bill_pkg;
 use FS::cust_credit;
@@ -24,50 +20,10 @@ use FS::cust_bill_event;
 @ISA = qw( FS::Record );
 
 #ask FS::UID to run this stuff for us later
-$FS::UID::callback{'FS::cust_bill'} = sub { 
-
+FS::UID->install_callback( sub { 
   $conf = new FS::Conf;
-
   $money_char = $conf->config('money_char') || '$';  
-
-  $lpr = $conf->config('lpr');
-  $invoice_from = $conf->config('invoice_from');
-  $smtpmachine = $conf->config('smtpmachine');
-
-  if ( $conf->exists('cybercash3.2') ) {
-    require CCMckLib3_2;
-      #qw($MCKversion %Config InitConfig CCError CCDebug CCDebug2);
-    require CCMckDirectLib3_2;
-      #qw(SendCC2_1Server);
-    require CCMckErrno3_2;
-      #qw(MCKGetErrorMessage $E_NoErr);
-    import CCMckErrno3_2 qw($E_NoErr);
-
-    my $merchant_conf;
-    ($merchant_conf,$xaction)= $conf->config('cybercash3.2');
-    my $status = &CCMckLib3_2::InitConfig($merchant_conf);
-    if ( $status != $E_NoErr ) {
-      warn "CCMckLib3_2::InitConfig error:\n";
-      foreach my $key (keys %CCMckLib3_2::Config) {
-        warn "  $key => $CCMckLib3_2::Config{$key}\n"
-      }
-      my($errmsg) = &CCMckErrno3_2::MCKGetErrorMessage($status);
-      die "CCMckLib3_2::InitConfig fatal error: $errmsg\n";
-    }
-    $processor='cybercash3.2';
-  } elsif ( $conf->exists('business-onlinepayment') ) {
-    ( $bop_processor,
-      $bop_login,
-      $bop_password,
-      $bop_action,
-      @bop_options
-    ) = $conf->config('business-onlinepayment');
-    $bop_action ||= 'normal authorization';
-    eval "use Business::OnlinePayment";  
-    $processor="Business::OnlinePayment::$bop_processor";
-  }
-
-};
+} );
 
 =head1 NAME
 
@@ -205,7 +161,7 @@ sub check {
 
   $self->printed(0) if $self->printed eq '';
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item previous
@@ -372,32 +328,27 @@ sub send {
   my @print_text = $self->print_text('', $template);
   my @invoicing_list = $self->cust_main->invoicing_list;
 
-  if ( grep { $_ ne 'POST' } @invoicing_list ) { #email invoice
-    #false laziness w/FS::cust_pay::delete & fs_signup_server && ::realtime_card
-    #$ENV{SMTPHOSTS} = $smtpmachine;
-    $ENV{MAILADDRESS} = $invoice_from;
-    my $header = new Mail::Header ( [
-      "From: $invoice_from",
-      "To: ". join(', ', grep { $_ ne 'POST' } @invoicing_list ),
-      "Sender: $invoice_from",
-      "Reply-To: $invoice_from",
-      "Date: ". time2str("%a, %d %b %Y %X %z", time),
-      "Subject: Invoice",
-    ] );
-    my $message = new Mail::Internet (
-      'Header' => $header,
-      'Body' => [ @print_text ], #( date)
+  if ( grep { $_ ne 'POST' } @invoicing_list or !@invoicing_list  ) { #email
+
+    #better to notify this person than silence
+    @invoicing_list = ($conf->config('invoice_from')) unless @invoicing_list;
+
+    my $error = send_email(
+      'from'    => $conf->config('invoice_from'),
+      'to'      => [ grep { $_ ne 'POST' } @invoicing_list ],
+      'subject' => 'Invoice',
+      'body'    => \@print_text,
     );
-    $!=0;
-    $message->smtpsend( Host => $smtpmachine )
-      or $message->smtpsend( Host => $smtpmachine, Debug => 1 )
-        or return "(customer # ". $self->custnum. ") can't send invoice email".
-                  " to ". join(', ', grep { $_ ne 'POST' } @invoicing_list ).
-                  " via server $smtpmachine with SMTP: $!";
+    return "can't send invoice: $error" if $error;
+
+  }
 
+  if ( $conf->config('invoice_latex') ) {
+    @print_text = $self->print_ps('', $template);
   }
 
-  if ( ! @invoicing_list || grep { $_ eq 'POST' } @invoicing_list ) { #postal
+  if ( grep { $_ eq 'POST' } @invoicing_list ) { #postal
+    my $lpr = $conf->config('lpr');
     open(LPR, "|$lpr")
       or return "Can't open pipe to $lpr: $!";
     print LPR @print_text;
@@ -410,6 +361,173 @@ sub send {
 
 }
 
+=item send_csv OPTIONS
+
+Sends invoice as a CSV data-file to a remote host with the specified protocol.
+
+Options are:
+
+protocol - currently only "ftp"
+server
+username
+password
+dir
+
+The file will be named "N-YYYYMMDDHHMMSS.csv" where N is the invoice number
+and YYMMDDHHMMSS is a timestamp.
+
+The fields of the CSV file is as follows:
+
+record_type, invnum, custnum, _date, charged, first, last, company, address1, address2, city, state, zip, country, pkg, setup, recur, sdate, edate
+
+=over 4
+
+=item record type - B<record_type> is either C<cust_bill> or C<cust_bill_pkg>
+
+If B<record_type> is C<cust_bill>, this is a primary invoice record.  The
+last five fields (B<pkg> through B<edate>) are irrelevant, and all other
+fields are filled in.
+
+If B<record_type> is C<cust_bill_pkg>, this is a line item record.  Only the
+first two fields (B<record_type> and B<invnum>) and the last five fields
+(B<pkg> through B<edate>) are filled in.
+
+=item invnum - invoice number
+
+=item custnum - customer number
+
+=item _date - invoice date
+
+=item charged - total invoice amount
+
+=item first - customer first name
+
+=item last - customer first name
+
+=item company - company name
+
+=item address1 - address line 1
+
+=item address2 - address line 1
+
+=item city
+
+=item state
+
+=item zip
+
+=item country
+
+=item pkg - line item description
+
+=item setup - line item setup fee (one or both of B<setup> and B<recur> will be defined)
+
+=item recur - line item recurring fee (one or both of B<setup> and B<recur> will be defined)
+
+=item sdate - start date for recurring fee
+
+=item edate - end date for recurring fee
+
+=back
+
+=cut
+
+sub send_csv {
+  my($self, %opt) = @_;
+
+  #part one: create file
+
+  my $spooldir = "/usr/local/etc/freeside/export.". datasrc. "/cust_bill";
+  mkdir $spooldir, 0700 unless -d $spooldir;
+
+  my $file = $spooldir. '/'. $self->invnum. time2str('-%Y%m%d%H%M%S.csv', time);
+
+  open(CSV, ">$file") or die "can't open $file: $!";
+
+  eval "use Text::CSV_XS";
+  die $@ if $@;
+
+  my $csv = Text::CSV_XS->new({'always_quote'=>1});
+
+  my $cust_main = $self->cust_main;
+
+  $csv->combine(
+    'cust_bill',
+    $self->invnum,
+    $self->custnum,
+    time2str("%x", $self->_date),
+    sprintf("%.2f", $self->charged),
+    ( map { $cust_main->getfield($_) }
+        qw( first last company address1 address2 city state zip country ) ),
+    map { '' } (1..5),
+  ) or die "can't create csv";
+  print CSV $csv->string. "\n";
+
+  #new charges (false laziness w/print_text)
+  foreach my $cust_bill_pkg ( $self->cust_bill_pkg ) {
+
+    my($pkg, $setup, $recur, $sdate, $edate);
+    if ( $cust_bill_pkg->pkgnum ) {
+    
+      ($pkg, $setup, $recur, $sdate, $edate) = (
+        $cust_bill_pkg->cust_pkg->part_pkg->pkg,
+        ( $cust_bill_pkg->setup != 0
+          ? sprintf("%.2f", $cust_bill_pkg->setup )
+          : '' ),
+        ( $cust_bill_pkg->recur != 0
+          ? sprintf("%.2f", $cust_bill_pkg->recur )
+          : '' ),
+        time2str("%x", $cust_bill_pkg->sdate),
+        time2str("%x", $cust_bill_pkg->edate),
+      );
+
+    } else { #pkgnum tax
+      next unless $cust_bill_pkg->setup != 0;
+      my $itemdesc = defined $cust_bill_pkg->dbdef_table->column('itemdesc')
+                       ? ( $cust_bill_pkg->itemdesc || 'Tax' )
+                       : 'Tax';
+      ($pkg, $setup, $recur, $sdate, $edate) =
+        ( $itemdesc, sprintf("%10.2f",$cust_bill_pkg->setup), '', '', '' );
+    }
+
+    $csv->combine(
+      'cust_bill_pkg',
+      $self->invnum,
+      ( map { '' } (1..11) ),
+      ($pkg, $setup, $recur, $sdate, $edate)
+    ) or die "can't create csv";
+    print CSV $csv->string. "\n";
+
+  }
+
+  close CSV or die "can't close CSV: $!";
+
+  #part two: upload it
+
+  my $net;
+  if ( $opt{protocol} eq 'ftp' ) {
+    eval "use Net::FTP;";
+    die $@ if $@;
+    $net = Net::FTP->new($opt{server}) or die @$;
+  } else {
+    die "unknown protocol: $opt{protocol}";
+  }
+
+  $net->login( $opt{username}, $opt{password} )
+    or die "can't FTP to $opt{username}\@$opt{server}: login error: $@";
+
+  $net->binary or die "can't set binary mode";
+
+  $net->cwd($opt{dir}) or die "can't cwd to $opt{dir}";
+
+  $net->put($file) or die "can't put $file: $!";
+
+  $net->quit;
+
+  unlink $file;
+
+}
+
 =item comp
 
 Pays this invoice with a compliemntary payment.  If there is an error,
@@ -432,53 +550,54 @@ sub comp {
 
 =item realtime_card
 
-Attempts to pay this invoice with a Business::OnlinePayment realtime gateway.
-See http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment
-for supproted processors.
+Attempts to pay this invoice with a credit card payment via a
+Business::OnlinePayment realtime gateway.  See
+http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment
+for supported processors.
 
 =cut
 
 sub realtime_card {
   my $self = shift;
-  my $cust_main = $self->cust_main;
-  my $amount = $self->owed;
+  $self->realtime_bop( 'CC', @_ );
+}
 
-  unless ( $processor =~ /^Business::OnlinePayment::(.*)$/ ) {
-    return "Real-time card processing not enabled (processor $processor)";
-  }
-  my $bop_processor = $1; #hmm?
-
-  my $address = $cust_main->address1;
-  $address .= ", ". $cust_main->address2 if $cust_main->address2;
-
-  #fix exp. date
-  #$cust_main->paydate =~ /^(\d+)\/\d*(\d{2})$/;
-  $cust_main->paydate =~ /^\d{2}(\d{2})[\/\-](\d+)[\/\-]\d+$/;
-  my $exp = "$2/$1";
-
-  my($payname, $payfirst, $paylast);
-  if ( $cust_main->payname ) {
-    $payname = $cust_main->payname;
-    $payname =~ /^\s*([\w \,\.\-\']*)?\s+([\w\,\.\-\']+)\s*$/
-      or do {
-              #$dbh->rollback if $oldAutoCommit;
-              return "Illegal payname $payname";
-            };
-    ($payfirst, $paylast) = ($1, $2);
-  } else {
-    $payfirst = $cust_main->getfield('first');
-    $paylast = $cust_main->getfield('last');
-    $payname =  "$payfirst $paylast";
-  }
+=item realtime_ach
 
-  my @invoicing_list = grep { $_ ne 'POST' } $cust_main->invoicing_list;
-  if ( $conf->exists('emailinvoiceauto')
-       || ( $conf->exists('emailinvoiceonly') && ! @invoicing_list ) ) {
-    push @invoicing_list, $cust_main->default_invoicing_list;
-  }
-  my $email = $invoicing_list[0];
+Attempts to pay this invoice with an electronic check (ACH) payment via a
+Business::OnlinePayment realtime gateway.  See
+http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment
+for supported processors.
 
-  my( $action1, $action2 ) = split(/\s*\,\s*/, $bop_action );
+=cut
+
+sub realtime_ach {
+  my $self = shift;
+  $self->realtime_bop( 'ECHECK', @_ );
+}
+
+=item realtime_lec
+
+Attempts to pay this invoice with phone bill (LEC) payment via a
+Business::OnlinePayment realtime gateway.  See
+http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment
+for supported processors.
+
+=cut
+
+sub realtime_lec {
+  my $self = shift;
+  $self->realtime_bop( 'LEC', @_ );
+}
+
+sub realtime_bop {
+  my( $self, $method ) = @_;
+
+  my $cust_main = $self->cust_main;
+  my $balance = $cust_main->balance;
+  my $amount = ( $balance < $self->owed ) ? $balance : $self->owed;
+  $amount = sprintf("%.2f", $amount);
+  return "not run (balance $balance)" unless $amount > 0;
 
   my $description = 'Internet Services';
   if ( $conf->exists('business-onlinepayment-description') ) {
@@ -493,211 +612,13 @@ sub realtime_card {
         grep { $_->pkgnum } $self->cust_bill_pkg
     );
     $description = eval qq("$dtempl");
-
-  }
-  
-  my $transaction =
-    new Business::OnlinePayment( $bop_processor, @bop_options );
-  $transaction->content(
-    'type'           => 'CC',
-    'login'          => $bop_login,
-    'password'       => $bop_password,
-    'action'         => $action1,
-    'description'    => $description,
-    'amount'         => $amount,
-    'invoice_number' => $self->invnum,
-    'customer_id'    => $self->custnum,
-    'last_name'      => $paylast,
-    'first_name'     => $payfirst,
-    'name'           => $payname,
-    'address'        => $address,
-    'city'           => $cust_main->city,
-    'state'          => $cust_main->state,
-    'zip'            => $cust_main->zip,
-    'country'        => $cust_main->country,
-    'card_number'    => $cust_main->payinfo,
-    'expiration'     => $exp,
-    'referer'        => 'http://cleanwhisker.420.am/',
-    'email'          => $email,
-    'phone'          => $cust_main->daytime || $cust_main->night,
-  );
-  $transaction->submit();
-
-  if ( $transaction->is_success() && $action2 ) {
-    my $auth = $transaction->authorization;
-    my $ordernum = $transaction->order_number;
-
-    #warn "********* $auth ***********\n";
-    #warn "********* $ordernum ***********\n";
-    my $capture =
-      new Business::OnlinePayment( $bop_processor, @bop_options );
-
-    $capture->content(
-      action         => $action2,
-      login          => $bop_login,
-      password       => $bop_password,
-      order_number   => $ordernum,
-      amount         => $amount,
-      authorization  => $auth,
-      description    => $description,
-    );
-
-    $capture->submit();
-
-    unless ( $capture->is_success ) {
-      my $e = "Authorization sucessful but capture failed, invnum #".
-              $self->invnum. ': '.  $capture->result_code.
-              ": ". $capture->error_message;
-      warn $e;
-      return $e;
-    }
-
   }
 
-  if ( $transaction->is_success() ) {
-
-    my $cust_pay = new FS::cust_pay ( {
-       'invnum'   => $self->invnum,
-       'paid'     => $amount,
-       '_date'     => '',
-       'payby'    => 'CARD',
-       'payinfo'  => $cust_main->payinfo,
-       'paybatch' => "$processor:". $transaction->authorization,
-    } );
-    my $error = $cust_pay->insert;
-    if ( $error ) {
-      # gah, even with transactions.
-      my $e = 'WARNING: Card debited but database not updated - '.
-              'error applying payment, invnum #' . $self->invnum.
-              " ($processor): $error";
-      warn $e;
-      return $e;
-    } else {
-      return '';
-    }
-  #} elsif ( $options{'report_badcard'} ) {
-  } else {
-
-    my $perror = "$processor error, invnum #". $self->invnum. ': '.
-                 $transaction->result_code. ": ". $transaction->error_message;
-
-    if ( $conf->exists('emaildecline')
-         && grep { $_ ne 'POST' } $cust_main->invoicing_list
-    ) {
-      my @templ = $conf->config('declinetemplate');
-      my $template = new Text::Template (
-        TYPE   => 'ARRAY',
-        SOURCE => [ map "$_\n", @templ ],
-      ) or return "($perror) can't create template: $Text::Template::ERROR";
-      $template->compile()
-        or return "($perror) can't compile template: $Text::Template::ERROR";
-
-      my $templ_hash = { error => $transaction->error_message };
-
-      #false laziness w/FS::cust_pay::delete & fs_signup_server && ::send
-      $ENV{MAILADDRESS} = $invoice_from;
-      my $header = new Mail::Header ( [
-        "From: $invoice_from",
-        "To: ". join(', ', grep { $_ ne 'POST' } $cust_main->invoicing_list ),
-        "Sender: $invoice_from",
-        "Reply-To: $invoice_from",
-        "Date: ". time2str("%a, %d %b %Y %X %z", time),
-        "Subject: Your credit card could not be processed",
-      ] );
-      my $message = new Mail::Internet (
-        'Header' => $header,
-        'Body' => [ $template->fill_in(HASH => $templ_hash) ],
-      );
-      $!=0;
-      $message->smtpsend( Host => $smtpmachine )
-        or $message->smtpsend( Host => $smtpmachine, Debug => 1 )
-          or return "($perror) (customer # ". $self->custnum.
-            ") can't send card decline email to ".
-            join(', ', grep { $_ ne 'POST' } $cust_main->invoicing_list ).
-            " via server $smtpmachine with SMTP: $!";
-    }
-  
-    return $perror;
-  }
-
-}
-
-=item realtime_card_cybercash
-
-Attempts to pay this invoice with the CyberCash CashRegister realtime gateway.
-
-=cut
-
-sub realtime_card_cybercash {
-  my $self = shift;
-  my $cust_main = $self->cust_main;
-  my $amount = $self->owed;
-
-  return "CyberCash CashRegister real-time card processing not enabled!"
-    unless $processor eq 'cybercash3.2';
-
-  my $address = $cust_main->address1;
-  $address .= ", ". $cust_main->address2 if $cust_main->address2;
-
-  #fix exp. date
-  #$cust_main->paydate =~ /^(\d+)\/\d*(\d{2})$/;
-  $cust_main->paydate =~ /^\d{2}(\d{2})[\/\-](\d+)[\/\-]\d+$/;
-  my $exp = "$2/$1";
-
-  #
-
-  my $paybatch = $self->invnum. 
-                  '-' . time2str("%y%m%d%H%M%S", time);
-
-  my $payname = $cust_main->payname ||
-                $cust_main->getfield('first').' '.$cust_main->getfield('last');
-
-  my $country = $cust_main->country eq 'US' ? 'USA' : $cust_main->country;
-
-  my @full_xaction = ( $xaction,
-    'Order-ID'     => $paybatch,
-    'Amount'       => "usd $amount",
-    'Card-Number'  => $cust_main->getfield('payinfo'),
-    'Card-Name'    => $payname,
-    'Card-Address' => $address,
-    'Card-City'    => $cust_main->getfield('city'),
-    'Card-State'   => $cust_main->getfield('state'),
-    'Card-Zip'     => $cust_main->getfield('zip'),
-    'Card-Country' => $country,
-    'Card-Exp'     => $exp,
+  $cust_main->realtime_bop($method, $amount,
+    'description' => $description,
+    'invnum'      => $self->invnum,
   );
 
-  my %result;
-  %result = &CCMckDirectLib3_2::SendCC2_1Server(@full_xaction);
-  
-  if ( $result{'MStatus'} eq 'success' ) { #cybercash smps v.2 or 3
-    my $cust_pay = new FS::cust_pay ( {
-       'invnum'   => $self->invnum,
-       'paid'     => $amount,
-       '_date'     => '',
-       'payby'    => 'CARD',
-       'payinfo'  => $cust_main->payinfo,
-       'paybatch' => "$processor:$paybatch",
-    } );
-    my $error = $cust_pay->insert;
-    if ( $error ) {
-      # gah, even with transactions.
-      my $e = 'WARNING: Card debited but database not updated - '.
-              'error applying payment, invnum #' . $self->invnum.
-              " (CyberCash Order-ID $paybatch): $error";
-      warn $e;
-      return $e;
-    } else {
-      return '';
-    }
-#  } elsif ( $result{'Mstatus'} ne 'failure-bad-money'
-#            || $options{'report_badcard'}
-#          ) {
-  } else {
-     return 'Cybercash error, invnum #' . 
-       $self->invnum. ':'. $result{'MErrMsg'};
-  }
-
 }
 
 =item batch_card
@@ -722,7 +643,6 @@ sub batch_card {
     'state'    => $cust_main->getfield('state'),
     'zip'      => $cust_main->getfield('zip'),
     'country'  => $cust_main->getfield('country'),
-    'trancode' => 77,
     'cardnum'  => $cust_main->getfield('payinfo'),
     'exp'      => $cust_main->getfield('paydate'),
     'payname'  => $cust_main->getfield('payname'),
@@ -734,7 +654,7 @@ sub batch_card {
   '';
 }
 
-=item print_text [TIME];
+=item print_text [ TIME [ , TEMPLATE ] ]
 
 Returns an text invoice, as a list of lines.
 
@@ -752,7 +672,7 @@ sub print_text {
 #  my $invnum = $self->invnum;
   my $cust_main = qsearchs('cust_main', { 'custnum', $self->custnum } );
   $cust_main->payname( $cust_main->first. ' '. $cust_main->getfield('last') )
-    unless $cust_main->payname;
+    unless $cust_main->payname && $cust_main->payby ne 'CHEK';
 
   my( $pr_total, @pr_cust_bill ) = $self->previous; #previous balance
 #  my( $cr_total, @cr_cust_credit ) = $self->cust_credit; #credits
@@ -779,33 +699,52 @@ sub print_text {
   }
 
   #new charges
-  foreach ( $self->cust_bill_pkg ) {
-
-    if ( $_->pkgnum ) {
-
-      my($cust_pkg)=qsearchs('cust_pkg', { 'pkgnum', $_->pkgnum } );
-      my($part_pkg)=qsearchs('part_pkg',{'pkgpart'=>$cust_pkg->pkgpart});
-      my($pkg)=$part_pkg->pkg;
-
-      if ( $_->setup != 0 ) {
-        push @buf, [ "$pkg Setup", $money_char. sprintf("%10.2f",$_->setup) ];
+  foreach my $cust_bill_pkg (
+    ( grep {   $_->pkgnum } $self->cust_bill_pkg ),  #packages first
+    ( grep { ! $_->pkgnum } $self->cust_bill_pkg ),  #then taxes
+  ) {
+
+    if ( $cust_bill_pkg->pkgnum ) {
+
+      my $cust_pkg = qsearchs('cust_pkg', { pkgnum =>$cust_bill_pkg->pkgnum } );
+      my $part_pkg = qsearchs('part_pkg', { pkgpart=>$cust_pkg->pkgpart } );
+      my $pkg = $part_pkg->pkg;
+
+      if ( $cust_bill_pkg->setup != 0 ) {
+        my $description = $pkg;
+        $description .= ' Setup' if $cust_bill_pkg->recur != 0;
+        push @buf, [ $description,
+                     $money_char. sprintf("%10.2f", $cust_bill_pkg->setup) ];
         push @buf,
           map { [ "  ". $_->[0]. ": ". $_->[1], '' ] } $cust_pkg->labels;
       }
 
-      if ( $_->recur != 0 ) {
+      if ( $cust_bill_pkg->recur != 0 ) {
         push @buf, [
-          "$pkg (" . time2str("%x",$_->sdate) . " - " .
-                                time2str("%x",$_->edate) . ")",
-          $money_char. sprintf("%10.2f",$_->recur)
+          "$pkg (" . time2str("%x", $cust_bill_pkg->sdate) . " - " .
+                                time2str("%x", $cust_bill_pkg->edate) . ")",
+          $money_char. sprintf("%10.2f", $cust_bill_pkg->recur)
         ];
         push @buf,
           map { [ "  ". $_->[0]. ": ". $_->[1], '' ] } $cust_pkg->labels;
       }
 
-    } else { #pkgnum Tax
-      push @buf,["Tax", $money_char. sprintf("%10.2f",$_->setup) ] 
-        if $_->setup != 0;
+      push @buf, map { [ "  $_", '' ] } $cust_bill_pkg->details;
+
+    } else { #pkgnum tax or one-shot line item
+      my $itemdesc = defined $cust_bill_pkg->dbdef_table->column('itemdesc')
+                     ? ( $cust_bill_pkg->itemdesc || 'Tax' )
+                     : 'Tax';
+      if ( $cust_bill_pkg->setup != 0 ) {
+        push @buf, [ $itemdesc,
+                     $money_char. sprintf("%10.2f", $cust_bill_pkg->setup) ];
+      }
+      if ( $cust_bill_pkg->recur != 0 ) {
+        push @buf, [ "$itemdesc (". time2str("%x", $cust_bill_pkg->sdate). " - "
+                                  . time2str("%x", $cust_bill_pkg->edate). ")",
+                     $money_char. sprintf("%10.2f", $cust_bill_pkg->recur)
+                   ];
+      }
     }
   }
 
@@ -852,8 +791,10 @@ sub print_text {
   }
 
   #balance due
+  my $balance_due_msg = $self->balance_due_msg;
+
   push @buf,['','-----------'];
-  push @buf,['Balance Due', $money_char. 
+  push @buf,[$balance_due_msg, $money_char. 
     sprintf("%10.2f", $balance_due ) ];
 
   #create the template
@@ -863,9 +804,9 @@ sub print_text {
   or die "cannot load config file $templatefile";
   $invoice_lines = 0;
   my $wasfunc = 0;
-  foreach ( grep /invoice_lines\(\d+\)/, @invoice_template ) { #kludgy
-    /invoice_lines\((\d+)\)/;
-    $invoice_lines += $1;
+  foreach ( grep /invoice_lines\(\d*\)/, @invoice_template ) { #kludgy
+    /invoice_lines\((\d*)\)/;
+    $invoice_lines += $1 || scalar(@buf);
     $wasfunc=1;
   }
   die "no invoice_lines() functions in template?" unless $wasfunc;
@@ -878,11 +819,12 @@ sub print_text {
 
   #setup template variables
   package FS::cust_bill::_template; #!
-  use vars qw( $invnum $date $page $total_pages @address $overdue @buf );
+  use vars qw( $invnum $date $page $total_pages @address $overdue @buf $agent );
 
   $invnum = $self->invnum;
   $date = $self->_date;
   $page = 1;
+  $agent = $self->cust_main->agent->agent;
 
   if ( $FS::cust_bill::invoice_lines ) {
     $total_pages =
@@ -923,16 +865,14 @@ sub print_text {
        #  );
 
   #and subroutine for the template
-
   sub FS::cust_bill::_template::invoice_lines {
-    my $lines = shift or return @buf;
+    my $lines = shift || scalar(@buf);
     map { 
       scalar(@buf) ? shift @buf : [ '', '' ];
     }
     ( 1 .. $lines );
   }
 
-
   #and fill it in
   $FS::cust_bill::_template::page = 1;
   my $lines;
@@ -948,11 +888,506 @@ sub print_text {
 
 }
 
-=back
+=item print_latex [ TIME [ , TEMPLATE ] ]
+
+Internal method - returns a filename of a filled-in LaTeX template for this
+invoice (Note: add ".tex" to get the actual filename).
+
+See print_ps and print_pdf for methods that return PostScript and PDF output.
+
+TIME an optional value used to control the printing of overdue messages.  The
+default is now.  It isn't the date of the invoice; that's the `_date' field.
+It is specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see
+L<Time::Local> and L<Date::Parse> for conversion functions.
+
+=cut
+
+#still some false laziness w/print_text
+sub print_latex {
+
+  my( $self, $today, $template ) = @_;
+  $today ||= time;
+
+#  my $invnum = $self->invnum;
+  my $cust_main = $self->cust_main;
+  $cust_main->payname( $cust_main->first. ' '. $cust_main->getfield('last') )
+    unless $cust_main->payname && $cust_main->payby ne 'CHEK';
+
+  my( $pr_total, @pr_cust_bill ) = $self->previous; #previous balance
+#  my( $cr_total, @cr_cust_credit ) = $self->cust_credit; #credits
+  #my $balance_due = $self->owed + $pr_total - $cr_total;
+  my $balance_due = $self->owed + $pr_total;
 
-=head1 VERSION
+  #my @collect = ();
+  #my($description,$amount);
+  @buf = ();
+
+  #create the template
+  my $templatefile = 'invoice_latex';
+  $templatefile .= "_$template" if $template;
+  my @invoice_template = $conf->config($templatefile)
+    or die "cannot load config file $templatefile";
+
+  my %invoice_data = (
+    'invnum'       => $self->invnum,
+    'date'         => time2str('%b %o, %Y', $self->_date),
+    'agent'        => _latex_escape($cust_main->agent->agent),
+    'payname'      => _latex_escape($cust_main->payname),
+    'company'      => _latex_escape($cust_main->company),
+    'address1'     => _latex_escape($cust_main->address1),
+    'address2'     => _latex_escape($cust_main->address2),
+    'city'         => _latex_escape($cust_main->city),
+    'state'        => _latex_escape($cust_main->state),
+    'zip'          => _latex_escape($cust_main->zip),
+    'country'      => _latex_escape($cust_main->country),
+    'footer'       => join("\n", $conf->config('invoice_latexfooter') ),
+    'smallfooter'  => join("\n", $conf->config('invoice_latexsmallfooter') ),
+    'quantity'     => 1,
+    'terms'        => $conf->config('invoice_default_terms') || 'Payable upon receipt',
+    #'notes'        => join("\n", $conf->config('invoice_latexnotes') ),
+  );
+
+  my $countrydefault = $conf->config('countrydefault') || 'US';
+  $invoice_data{'country'} = '' if $invoice_data{'country'} eq $countrydefault;
+
+  #do variable substitutions in notes
+  $invoice_data{'notes'} =
+    join("\n",
+      map { my $b=$_; $b =~ s/\$(\w+)/$invoice_data{$1}/eg; $b }
+        $conf->config('invoice_latexnotes')
+    );
+
+  $invoice_data{'footer'} =~ s/\n+$//;
+  $invoice_data{'smallfooter'} =~ s/\n+$//;
+  $invoice_data{'notes'} =~ s/\n+$//;
+
+  $invoice_data{'po_line'} =
+    (  $cust_main->payby eq 'BILL' && $cust_main->payinfo )
+      ? _latex_escape("Purchase Order #". $cust_main->payinfo)
+      : '~';
+
+  my @line_item = ();
+  my @total_item = ();
+  my @filled_in = ();
+  while ( @invoice_template ) {
+    my $line = shift @invoice_template;
+
+    if ( $line =~ /^%%Detail\s*$/ ) {
+
+      while ( ( my $line_item_line = shift @invoice_template )
+              !~ /^%%EndDetail\s*$/                            ) {
+        push @line_item, $line_item_line;
+      }
+      foreach my $line_item ( $self->_items ) {
+      #foreach my $line_item ( $self->_items_pkg ) {
+        $invoice_data{'ref'} = $line_item->{'pkgnum'};
+        $invoice_data{'description'} = _latex_escape($line_item->{'description'});
+        if ( exists $line_item->{'ext_description'} ) {
+          $invoice_data{'description'} .=
+            "\\tabularnewline\n~~".
+            join("\\tabularnewline\n~~", map { _latex_escape($_) } @{$line_item->{'ext_description'}} );
+        }
+        $invoice_data{'amount'} = $line_item->{'amount'};
+        $invoice_data{'product_code'} = $line_item->{'pkgpart'} || 'N/A';
+        push @filled_in,
+          map { my $b=$_; $b =~ s/\$(\w+)/$invoice_data{$1}/eg; $b } @line_item;
+      }
+
+    } elsif ( $line =~ /^%%TotalDetails\s*$/ ) {
+
+      while ( ( my $total_item_line = shift @invoice_template )
+              !~ /^%%EndTotalDetails\s*$/                      ) {
+        push @total_item, $total_item_line;
+      }
+
+      my @total_fill = ();
+
+      my $taxtotal = 0;
+      foreach my $tax ( $self->_items_tax ) {
+        $invoice_data{'total_item'} = _latex_escape($tax->{'description'});
+        $taxtotal += ( $invoice_data{'total_amount'} = $tax->{'amount'} );
+        push @total_fill,
+          map { my $b=$_; $b =~ s/\$(\w+)/$invoice_data{$1}/eg; $b }
+              @total_item;
+      }
+
+      if ( $taxtotal ) {
+        $invoice_data{'total_item'} = 'Sub-total';
+        $invoice_data{'total_amount'} =
+          '\dollar '. sprintf('%.2f', $self->charged - $taxtotal );
+        unshift @total_fill,
+          map { my $b=$_; $b =~ s/\$(\w+)/$invoice_data{$1}/eg; $b }
+              @total_item;
+      }
+
+      $invoice_data{'total_item'} = '\textbf{Total}';
+      $invoice_data{'total_amount'} =
+        '\textbf{\dollar '. sprintf('%.2f', $self->charged + $pr_total ). '}';
+      push @total_fill,
+        map { my $b=$_; $b =~ s/\$(\w+)/$invoice_data{$1}/eg; $b }
+            @total_item;
+
+      #foreach my $thing ( sort { $a->_date <=> $b->_date } $self->_items_credits, $self->_items_payments
+
+      # credits
+      foreach my $credit ( $self->_items_credits ) {
+        $invoice_data{'total_item'} = _latex_escape($credit->{'description'});
+        #$credittotal
+        $invoice_data{'total_amount'} = '-\dollar '. $credit->{'amount'};
+        push @total_fill, 
+          map { my $b=$_; $b =~ s/\$(\w+)/$invoice_data{$1}/eg; $b }
+              @total_item;
+      }
+
+      # payments
+      foreach my $payment ( $self->_items_payments ) {
+        $invoice_data{'total_item'} = _latex_escape($payment->{'description'});
+        #$paymenttotal
+        $invoice_data{'total_amount'} = '-\dollar '. $payment->{'amount'};
+        push @total_fill, 
+          map { my $b=$_; $b =~ s/\$(\w+)/$invoice_data{$1}/eg; $b }
+              @total_item;
+      }
+
+      $invoice_data{'total_item'} = '\textbf{'. $self->balance_due_msg. '}';
+      $invoice_data{'total_amount'} =
+        '\textbf{\dollar '. sprintf('%.2f', $self->owed + $pr_total ). '}';
+      push @total_fill,
+        map { my $b=$_; $b =~ s/\$(\w+)/$invoice_data{$1}/eg; $b }
+            @total_item;
+
+      push @filled_in, @total_fill;
+
+    } else {
+      #$line =~ s/\$(\w+)/$invoice_data{$1}/eg;
+      $line =~ s/\$(\w+)/exists($invoice_data{$1}) ? $invoice_data{$1} : nounder($1)/eg;
+      push @filled_in, $line;
+    }
+
+  }
+
+  sub nounder {
+    my $var = $1;
+    $var =~ s/_/\-/g;
+    $var;
+  }
+
+  my $dir = '/tmp'; #! /usr/local/etc/freeside/invoices.datasrc/
+  my $unique = int(rand(2**31)); #UGH... use File::Temp or something
+
+  chdir($dir);
+  my $file = $self->invnum. ".$unique";
+
+  open(TEX,">$file.tex") or die "can't open $file.tex: $!\n";
+  print TEX join("\n", @filled_in ), "\n";
+  close TEX;
+
+  return $file;
+
+}
+
+=item print_ps [ TIME [ , TEMPLATE ] ]
+
+Returns an postscript invoice, as a scalar.
+
+TIME an optional value used to control the printing of overdue messages.  The
+default is now.  It isn't the date of the invoice; that's the `_date' field.
+It is specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see
+L<Time::Local> and L<Date::Parse> for conversion functions.
+
+=cut
+
+sub print_ps {
+  my $self = shift;
+
+  my $file = $self->print_latex(@_);
+
+  #error checking!!
+  system('pslatex', "$file.tex");
+  system('pslatex', "$file.tex");
+  system('dvips', '-q', '-t', 'letter', "$file.dvi", '-o', "$file.ps" );
+
+  open(POSTSCRIPT, "<$file.ps")
+    or die "can't open $file.ps (probable error in LaTeX template): $!\n";
+
+  unlink("$file.dvi", "$file.log", "$file.aux", "$file.ps", "$file.tex");
+
+  my $ps = '';
+  while (<POSTSCRIPT>) {
+    $ps .= $_;
+  }
+
+  close POSTSCRIPT;
+
+  return $ps;
+
+}
+
+=item print_pdf [ TIME [ , TEMPLATE ] ]
+
+Returns an PDF invoice, as a scalar.
+
+TIME an optional value used to control the printing of overdue messages.  The
+default is now.  It isn't the date of the invoice; that's the `_date' field.
+It is specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see
+L<Time::Local> and L<Date::Parse> for conversion functions.
+
+=cut
+
+sub print_pdf {
+  my $self = shift;
+
+  my $file = $self->print_latex(@_);
+
+  #system('pdflatex', "$file.tex");
+  #system('pdflatex', "$file.tex");
+  #! LaTeX Error: Unknown graphics extension: .eps.
+
+  #error checking!!
+  system('pslatex', "$file.tex");
+  system('pslatex', "$file.tex");
+
+  #system('dvipdf', "$file.dvi", "$file.pdf" );
+  system("dvips -q -t letter -f $file.dvi | gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=$file.pdf -c save pop -");
+
+  open(PDF, "<$file.pdf")
+    or die "can't open $file.pdf (probably error in LaTeX tempalte: $!\n";
 
-$Id: cust_bill.pm,v 1.38 2002-06-26 02:37:48 ivan Exp $
+  unlink("$file.dvi", "$file.log", "$file.aux", "$file.pdf", "$file.tex");
+
+  my $pdf = '';
+  while (<PDF>) {
+    $pdf .= $_;
+  }
+
+  close PDF;
+
+  return $pdf;
+
+}
+
+# quick subroutine for print_latex
+#
+# There are ten characters that LaTeX treats as special characters, which
+# means that they do not simply typeset themselves: 
+#      # $ % & ~ _ ^ \ { }
+#
+# TeX ignores blanks following an escaped character; if you want a blank (as
+# in "10% of ..."), you have to "escape" the blank as well ("10\%\ of ..."). 
+
+sub _latex_escape {
+  my $value = shift;
+  $value =~ s/([#\$%&~_\^{}])( )?/"\\$1". ( length($2) ? "\\$2" : '' )/ge;
+  $value;
+}
+
+#utility methods for print_*
+
+sub balance_due_msg {
+  my $self = shift;
+  my $msg = 'Balance Due';
+  return $msg unless $conf->exists('invoice_default_terms');
+  if ( $conf->config('invoice_default_terms') =~ /^\s*Net\s*(\d+)\s*$/ ) {
+    $msg .= ' - Please pay by '. time2str("%x", $self->_date + ($1*86400) );
+  } elsif ( $conf->config('invoice_default_terms') ) {
+    $msg .= ' - '. $conf->config('invoice_default_terms');
+  }
+  $msg;
+}
+
+sub _items {
+  my $self = shift;
+  my @display = scalar(@_)
+                ? @_
+                : qw( _items_previous _items_pkg );
+                #: qw( _items_pkg );
+                #: qw( _items_previous _items_pkg _items_tax _items_credits _items_payments );
+  my @b = ();
+  foreach my $display ( @display ) {
+    push @b, $self->$display(@_);
+  }
+  @b;
+}
+
+sub _items_previous {
+  my $self = shift;
+  my $cust_main = $self->cust_main;
+  my( $pr_total, @pr_cust_bill ) = $self->previous; #previous balance
+  my @b = ();
+  foreach ( @pr_cust_bill ) {
+    push @b, {
+      'description' => 'Previous Balance, Invoice #'. $_->invnum. 
+                       ' ('. time2str('%x',$_->_date). ')',
+      #'pkgpart'     => 'N/A',
+      'pkgnum'      => 'N/A',
+      'amount'      => sprintf("%10.2f", $_->owed),
+    };
+  }
+  @b;
+
+  #{
+  #    'description'     => 'Previous Balance',
+  #    #'pkgpart'         => 'N/A',
+  #    'pkgnum'          => 'N/A',
+  #    'amount'          => sprintf("%10.2f", $pr_total ),
+  #    'ext_description' => [ map {
+  #                                 "Invoice ". $_->invnum.
+  #                                 " (". time2str("%x",$_->_date). ") ".
+  #                                 sprintf("%10.2f", $_->owed)
+  #                         } @pr_cust_bill ],
+
+  #};
+}
+
+sub _items_pkg {
+  my $self = shift;
+  my @cust_bill_pkg = grep { $_->pkgnum } $self->cust_bill_pkg;
+  $self->_items_cust_bill_pkg(\@cust_bill_pkg, @_);
+}
+
+sub _items_tax {
+  my $self = shift;
+  my @cust_bill_pkg = grep { ! $_->pkgnum } $self->cust_bill_pkg;
+  $self->_items_cust_bill_pkg(\@cust_bill_pkg, @_);
+}
+
+sub _items_cust_bill_pkg {
+  my $self = shift;
+  my $cust_bill_pkg = shift;
+
+  my @b = ();
+  foreach my $cust_bill_pkg ( @$cust_bill_pkg ) {
+
+    if ( $cust_bill_pkg->pkgnum ) {
+
+      my $cust_pkg = qsearchs('cust_pkg', { pkgnum =>$cust_bill_pkg->pkgnum } );
+      my $part_pkg = qsearchs('part_pkg', { pkgpart=>$cust_pkg->pkgpart } );
+      my $pkg = $part_pkg->pkg;
+
+      my %labels;
+      #tie %labels, 'Tie::IxHash';
+      push @{ $labels{$_->[0]} }, $_->[1] foreach $cust_pkg->labels;
+      my @ext_description;
+      foreach my $label ( keys %labels ) {
+        my @values = @{ $labels{$label} };
+        my $num = scalar(@values);
+        if ( $num > 5 ) {
+          push @ext_description, "$label ($num)";
+        } else {
+          push @ext_description, map { "$label: $_" } @values;
+        }
+      }
+
+      if ( $cust_bill_pkg->setup != 0 ) {
+        my $description = $pkg;
+        $description .= ' Setup' if $cust_bill_pkg->recur != 0;
+        my @d = @ext_description;
+        push @d, $cust_bill_pkg->details if $cust_bill_pkg->recur == 0;
+        push @b, {
+          'description'     => $description,
+          #'pkgpart'         => $part_pkg->pkgpart,
+          'pkgnum'          => $cust_pkg->pkgnum,
+          'amount'          => sprintf("%10.2f", $cust_bill_pkg->setup),
+          'ext_description' => \@d,
+        };
+      }
+
+      if ( $cust_bill_pkg->recur != 0 ) {
+        push @b, {
+          'description'     => "$pkg (" .
+                               time2str('%x', $cust_bill_pkg->sdate). ' - '.
+                               time2str('%x', $cust_bill_pkg->edate). ')',
+          #'pkgpart'         => $part_pkg->pkgpart,
+          'pkgnum'          => $cust_pkg->pkgnum,
+          'amount'          => sprintf("%10.2f", $cust_bill_pkg->recur),
+          'ext_description' => [ @ext_description,
+                                 $cust_bill_pkg->details,
+                               ],
+        };
+      }
+
+    } else { #pkgnum tax or one-shot line item (??)
+
+      my $itemdesc = defined $cust_bill_pkg->dbdef_table->column('itemdesc')
+                     ? ( $cust_bill_pkg->itemdesc || 'Tax' )
+                     : 'Tax';
+      if ( $cust_bill_pkg->setup != 0 ) {
+        push @b, {
+          'description' => $itemdesc,
+          'amount'      => sprintf("%10.2f", $cust_bill_pkg->setup),
+        };
+      }
+      if ( $cust_bill_pkg->recur != 0 ) {
+        push @b, {
+          'description' => "$itemdesc (".
+                           time2str("%x", $cust_bill_pkg->sdate). ' - '.
+                           time2str("%x", $cust_bill_pkg->edate). ')',
+          'amount'      => sprintf("%10.2f", $cust_bill_pkg->recur),
+        };
+      }
+
+    }
+
+  }
+
+  @b;
+
+}
+
+sub _items_credits {
+  my $self = shift;
+
+  my @b;
+  #credits
+  foreach ( $self->cust_credited ) {
+
+    #something more elaborate if $_->amount ne $_->cust_credit->credited ?
+
+    my $reason = $_->cust_credit->reason;
+    #my $reason = substr($_->cust_credit->reason,0,32);
+    #$reason .= '...' if length($reason) < length($_->cust_credit->reason);
+    $reason = " ($reason) " if $reason;
+    push @b, {
+      #'description' => 'Credit ref\#'. $_->crednum.
+      #                 " (". time2str("%x",$_->cust_credit->_date) .")".
+      #                 $reason,
+      'description' => 'Credit applied'.
+                       time2str("%x",$_->cust_credit->_date). $reason,
+      'amount'      => sprintf("%10.2f",$_->amount),
+    };
+  }
+  #foreach ( @cr_cust_credit ) {
+  #  push @buf,[
+  #    "Credit #". $_->crednum. " (" . time2str("%x",$_->_date) .")",
+  #    $money_char. sprintf("%10.2f",$_->credited)
+  #  ];
+  #}
+
+  @b;
+
+}
+
+sub _items_payments {
+  my $self = shift;
+
+  my @b;
+  #get & print payments
+  foreach ( $self->cust_bill_pay ) {
+
+    #something more elaborate if $_->amount ne ->cust_pay->paid ?
+
+    push @b, {
+      'description' => "Payment received ".
+                       time2str("%x",$_->cust_pay->_date ),
+      'amount'      => sprintf("%10.2f", $_->amount )
+    };
+  }
+
+  @b;
+
+}
+
+=back
 
 =head1 BUGS
 
index f631987..ddd6762 100644 (file)
@@ -3,6 +3,7 @@ package FS::cust_bill_event;
 use strict;
 use vars qw( @ISA );
 use FS::Record qw( qsearch qsearchs );
+use FS::cust_bill;
 use FS::part_bill_event;
 
 @ISA = qw(FS::Record);
@@ -43,6 +44,10 @@ currently supported:
 =item _date - specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see
 L<Time::Local> and L<Date::Parse> for conversion functions.
 
+=item status - event status: B<done> or B<failed>
+
+=item statustext - additional status detail (i.e. error message)
+
 =back
 
 =head1 METHODS
@@ -111,13 +116,13 @@ sub check {
     || $self->ut_textn('statustext')
   ;
 
-  return "Unknown invnum"
+  return "Unknown invnum ". $self->invnum
     unless qsearchs( 'cust_bill' ,{ 'invnum' => $self->invnum } );
 
-  return "Unknown eventpart"
+  return "Unknown eventpart ". $self->eventpart
     unless qsearchs( 'part_bill_event' ,{ 'eventpart' => $self->eventpart } );
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item part_bill_event
index 913704b..c8b5525 100644 (file)
@@ -1,13 +1,18 @@
 package FS::cust_bill_pay;
 
 use strict;
-use vars qw( @ISA );
+use vars qw( @ISA $conf );
 use FS::Record qw( qsearch qsearchs dbh );
 use FS::cust_bill;
 use FS::cust_pay;
 
 @ISA = qw( FS::Record );
 
+#ask FS::UID to run this stuff for us later
+FS::UID->install_callback( sub { 
+  $conf = new FS::Conf;
+} );
+
 =head1 NAME
 
 FS::cust_bill_pay - Object methods for cust_bill_pay records
@@ -101,7 +106,8 @@ sub insert {
            " greater than cust_pay.paid ". $cust_pay->paid;
   }
 
-  my $cust_bill = qsearchs('cust_bill', { 'invnum' => $self->invnum } ) or do {
+  my $cust_bill = $self->cust_bill;
+  unless ( $cust_bill ) {
     $dbh->rollback if $oldAutoCommit;
     return "unknown cust_bill.invnum: ". $self->invnum;
   };
@@ -120,6 +126,11 @@ sub insert {
 
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
 
+  if ( $conf->exists('invoice_send_receipts') ) {
+    my $send_error = $cust_bill->send;
+    warn "Error sending receipt: $send_error\n" if $send_error;
+  }
+
   '';
 }
 
@@ -170,7 +181,7 @@ sub check {
 
   $self->_date(time) unless $self->_date;
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item cust_pay 
@@ -197,10 +208,6 @@ sub cust_bill {
 
 =back
 
-=head1 VERSION
-
-$Id: cust_bill_pay.pm,v 1.12 2002-02-07 22:29:34 ivan Exp $
-
 =head1 BUGS
 
 Delete and replace methods.
index 72f9ce4..6800707 100644 (file)
@@ -2,11 +2,12 @@ package FS::cust_bill_pkg;
 
 use strict;
 use vars qw( @ISA );
-use FS::Record qw( qsearchs );
+use FS::Record qw( qsearch qsearchs dbdef dbh );
 use FS::cust_pkg;
 use FS::cust_bill;
+use FS::cust_bill_pkg_detail;
 
-@ISA = qw(FS::Record );
+@ISA = qw( FS::Record );
 
 =head1 NAME
 
@@ -47,6 +48,8 @@ supported:
 
 =item edate - ending date of recurring fee
 
+=item itemdesc - Line item description (currentlty used only when pkgnum is 0)
+
 =back
 
 sdate and edate are specified as UNIX timestamps; see L<perlfunc/"time">.  Also
@@ -71,6 +74,51 @@ sub table { 'cust_bill_pkg'; }
 Adds this line item to the database.  If there is an error, returns the error,
 otherwise returns false.
 
+=cut
+
+sub insert {
+  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;
+
+  my $error = $self->SUPER::insert;
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return $error;
+  }
+
+  unless ( defined dbdef->table('cust_bill_pkg_detail') && $self->get('details') ) {
+    $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+    return '';
+  }
+
+  foreach my $detail ( @{$self->get('details')} ) {
+    my $cust_bill_pkg_detail = new FS::cust_bill_pkg_detail {
+      'pkgnum' => $self->pkgnum,
+      'invnum' => $self->invnum,
+      'detail' => $detail,
+    };
+    $error = $cust_bill_pkg_detail->insert;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
+    }
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
+
+}
+
 =item delete
 
 Currently unimplemented.  I don't remove line items because there would then be
@@ -111,6 +159,7 @@ sub check {
       || $self->ut_money('recur')
       || $self->ut_numbern('sdate')
       || $self->ut_numbern('edate')
+      || $self->ut_textn('itemdesc')
   ;
   return $error if $error;
 
@@ -122,7 +171,7 @@ sub check {
   return "Unknown invnum"
     unless qsearchs( 'cust_bill' ,{ 'invnum' => $self->invnum } );
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item cust_pkg
@@ -136,11 +185,22 @@ sub cust_pkg {
   qsearchs( 'cust_pkg', { 'pkgnum' => $self->pkgnum } );
 }
 
-=back
+=item details
+
+Returns an array of detail information for the invoice line item.
 
-=head1 VERSION
+=cut
 
-$Id: cust_bill_pkg.pm,v 1.3 2002-04-06 22:32:43 ivan Exp $
+sub details {
+  my $self = shift;
+  return () unless defined dbdef->table('cust_bill_pkg_detail');
+  map { $_->detail }
+    qsearch ( 'cust_bill_pkg_detail', { 'pkgnum' => $self->pkgnum,
+                                        'invnum' => $self->invnum, } );
+    #qsearch ( 'cust_bill_pkg_detail', { 'lineitemnum' => $self->lineitemnum });
+}
+
+=back
 
 =head1 BUGS
 
diff --git a/FS/FS/cust_bill_pkg_detail.pm b/FS/FS/cust_bill_pkg_detail.pm
new file mode 100644 (file)
index 0000000..261aa80
--- /dev/null
@@ -0,0 +1,124 @@
+package FS::cust_bill_pkg_detail;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record qw( qsearch qsearchs );
+
+@ISA = qw(FS::Record);
+
+=head1 NAME
+
+FS::cust_bill_pkg_detail - Object methods for cust_bill_pkg_detail records
+
+=head1 SYNOPSIS
+
+  use FS::cust_bill_pkg_detail;
+
+  $record = new FS::cust_bill_pkg_detail \%hash;
+  $record = new FS::cust_bill_pkg_detail { 'column' => 'value' };
+
+  $error = $record->insert;
+
+  $error = $new_record->replace($old_record);
+
+  $error = $record->delete;
+
+  $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::cust_bill_pkg_detail object represents additional detail information for
+an invoice line item (see L<FS::cust_bill_pkg>).  FS::cust_bill_pkg_detail
+inherits from FS::Record.  The following fields are currently supported:
+
+=over 4
+
+=item detailnum - primary key
+
+=item pkgnum -
+
+=item invnum -
+
+=item detail - detail description
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new line item detail.  To add the line item detail 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<hash> method.
+
+=cut
+
+# the new method can be inherited from FS::Record, if a table method is defined
+
+sub table { 'cust_bill_pkg_detail'; }
+
+=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 line item detail.  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;
+
+  $self->ut_numbern('detailnum')
+    || $self->ut_foreign_key('pkgnum', 'cust_pkg', 'pkgnum')
+    || $self->ut_foreign_key('invnum', 'cust_pkg', 'invnum')
+    || $self->ut_text('detail')
+    || $self->SUPER::check
+    ;
+
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::cust_bill_pkg>, L<FS::Record>, schema.html from the base documentation.
+
+=cut
+
+1;
+
index 284d59d..19a5453 100644 (file)
@@ -2,8 +2,10 @@ package FS::cust_credit;
 
 use strict;
 use vars qw( @ISA $conf $unsuspendauto );
+use Date::Format;
 use FS::UID qw( dbh getotaker );
 use FS::Record qw( qsearch qsearchs );
+use FS::Misc qw(send_email);
 use FS::cust_main;
 use FS::cust_refund;
 use FS::cust_credit_bill;
@@ -130,7 +132,64 @@ Currently unimplemented.
 sub delete {
   my $self = shift;
   return "Can't delete closed credit" if $self->closed =~ /^Y/i;
-  $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 $cust_credit_bill ( $self->cust_credit_bill ) {
+    my $error = $cust_credit_bill->delete;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
+    }
+  }
+
+  my $error = $self->SUPER::delete(@_);
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return $error;
+  }
+
+  if ( $conf->config('deletecredits') ne '' ) {
+
+    my $cust_main = qsearchs('cust_main',{ 'custnum' => $self->custnum });
+
+    my $error = send_email(
+      'from'    => $conf->config('invoice_from'), #??? well as good as any
+      'to'      => $conf->config('deletecredits'),
+      'subject' => 'FREESIDE NOTIFICATION: Credit deleted',
+      'body'    => [
+        "This is an automatic message from your Freeside installation\n",
+        "informing you that the following credit has been deleted:\n",
+        "\n",
+        'crednum: '. $self->crednum. "\n",
+        'custnum: '. $self->custnum.
+          " (". $cust_main->last. ", ". $cust_main->first. ")\n",
+        'amount: $'. sprintf("%.2f", $self->amount). "\n",
+        'date: '. time2str("%a %b %e %T %Y", $self->_date). "\n",
+        'reason: '. $self->reason. "\n",
+      ],
+    );
+
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "can't send credit deletion notification: $error";
+    }
+
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+  '';
+
 }
 
 =item replace OLD_RECORD
@@ -141,7 +200,10 @@ posted.
 =cut
 
 sub replace {
-  return "Can't modify credit!"
+  #return "Can't modify credit!"
+  my $self = shift;
+  return "Can't modify closed credit" if $self->closed =~ /^Y/i;
+  $self->SUPER::replace(@_);
 }
 
 =item check
@@ -174,7 +236,7 @@ sub check {
 
   $self->otaker(getotaker);
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item cust_refund
@@ -240,13 +302,9 @@ sub credited {
 
 =back
 
-=head1 VERSION
-
-$Id: cust_credit.pm,v 1.16 2002-06-04 14:35:52 ivan Exp $
-
 =head1 BUGS
 
-The delete method.
+The delete method.  The replace method.
 
 =head1 SEE ALSO
 
index 6221541..bd76c2e 100644 (file)
@@ -1,7 +1,7 @@
 package FS::cust_credit_bill;
 
 use strict;
-use vars qw( @ISA );
+use vars qw( @ISA $conf );
 use FS::UID qw( getotaker );
 use FS::Record qw( qsearch qsearchs );
 use FS::cust_main;
@@ -11,6 +11,11 @@ use FS::cust_bill;
 
 @ISA = qw( FS::Record );
 
+#ask FS::UID to run this stuff for us later
+FS::UID->install_callback( sub { 
+  $conf = new FS::Conf;
+} );
+
 =head1 NAME
 
 FS::cust_credit_bill - Object methods for cust_credit_bill records
@@ -69,6 +74,21 @@ sub table { 'cust_credit_bill'; }
 Adds this cust_credit_bill to the database ("Posts" all or part of a credit).
 If there is an error, returns the error, otherwise returns false.
 
+=cut
+
+sub insert {
+  my $self = shift;
+  my $error = $self->SUPER::insert(@_);
+  return $error if $error;
+
+  if ( $conf->exists('invoice_send_receipts') ) {
+    my $send_error = $self->cust_bill->send;
+    warn "Error sending receipt: $send_error\n" if $send_error;
+  }
+
+  '';
+}
+
 =item delete
 
 Currently unimplemented.
@@ -76,7 +96,10 @@ Currently unimplemented.
 =cut
 
 sub delete {
-  return "Can't unapply credit!"
+  my $self = shift;
+  return "Can't delete application for closed credit"
+    if $self->cust_credit->closed =~ /^Y/i;
+  $self->SUPER::delete(@_);
 }
 
 =item replace OLD_RECORD
@@ -127,7 +150,7 @@ sub check {
   return "Cannot apply more than remaining value of invoice"
     unless $self->amount <= $cust_bill->owed;
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item sub cust_credit
@@ -141,11 +164,18 @@ sub cust_credit {
   qsearchs( 'cust_credit', { 'crednum' => $self->crednum } );
 }
 
-=back
+=item cust_bill 
+
+Returns the invoice (see L<FS::cust_bill>)
+
+=cut
 
-=head1 VERSION
+sub cust_bill {
+  my $self = shift;
+  qsearchs( 'cust_bill', { 'invnum' => $self->invnum } );
+}
 
-$Id: cust_credit_bill.pm,v 1.7 2002-01-24 16:58:47 ivan Exp $
+=back
 
 =head1 BUGS
 
index cc3b32c..d0deae2 100644 (file)
@@ -156,7 +156,7 @@ sub check {
   return "unknown cust_credit.crednum: ". $self->crednum
     unless qsearchs( 'cust_credit', { 'crednum' => $self->crednum } );
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item cust_refund
@@ -185,7 +185,7 @@ sub cust_credit {
 
 =head1 VERSION
 
-$Id: cust_credit_refund.pm,v 1.9 2002-01-26 01:52:31 ivan Exp $
+$Id: cust_credit_refund.pm,v 1.10 2003-08-05 00:20:41 khoff Exp $
 
 =head1 BUGS
 
index eb468d9..6ca3287 100644 (file)
@@ -2,19 +2,27 @@ package FS::cust_main;
 
 use strict;
 use vars qw( @ISA $conf $Debug $import );
+use vars qw( $realtime_bop_decline_quiet ); #ugh
 use Safe;
 use Carp;
-use Time::Local;
+BEGIN {
+  eval "use Time::Local;";
+  die "Time::Local minimum version 1.05 required with Perl versions before 5.6"
+    if $] < 5.006 && !defined($Time::Local::VERSION);
+  eval "use Time::Local qw(timelocal timelocal_nocheck);";
+}
 use Date::Format;
 #use Date::Manip;
 use Business::CreditCard;
 use FS::UID qw( getotaker dbh );
 use FS::Record qw( qsearchs qsearch dbdef );
+use FS::Misc qw( send_email );
 use FS::cust_pkg;
 use FS::cust_bill;
 use FS::cust_bill_pkg;
 use FS::cust_pay;
 use FS::cust_credit;
+use FS::cust_refund;
 use FS::part_referral;
 use FS::cust_main_county;
 use FS::agent;
@@ -32,13 +40,16 @@ use FS::Msgcat qw(gettext);
 
 @ISA = qw( FS::Record );
 
+$realtime_bop_decline_quiet = 0;
+
 $Debug = 0;
 #$Debug = 1;
 
 $import = 0;
 
 #ask FS::UID to run this stuff for us later
-$FS::UID::callback{'FS::cust_main'} = sub { 
+#$FS::UID::callback{'FS::cust_main'} = sub { 
+install_callback FS::UID sub { 
   $conf = new FS::Conf;
   #yes, need it for stuff below (prolly should be cached)
 };
@@ -158,10 +169,12 @@ FS::Record.  The following fields are currently supported:
 
 =item ship_fax - phone (optional)
 
-=item payby - `CARD' (credit cards), `BILL' (billing), `COMP' (free), or `PREPAY' (special billing type: applies a credit - see L<FS::prepay_credit> and sets billing type to BILL)
+=item payby - I<CARD> (credit card - automatic), I<DCRD> (credit card - on-demand), I<CHEK> (electronic check - automatic), I<DCHK> (electronic check - on-demand), I<LECB> (Phone bill billing), I<BILL> (billing), I<COMP> (free), or I<PREPAY> (special billing type: applies a credit - see L<FS::prepay_credit> and sets billing type to I<BILL>)
 
 =item payinfo - card number, P.O., comp issuer (4-8 lowercase alphanumerics; think username) or prepayment identifier (see L<FS::prepay_credit>)
 
+=item paycvv - Card Verification Value, "CVV2" (also known as CVC2 or CID), the 3 or 4 digit number on the back (or front, for American Express) of the credit card
+
 =item paydate - expiration date, mm/yyyy, m/yyyy, mm/yy or m/yy
 
 =item payname - name on card or billing name
@@ -172,6 +185,8 @@ FS::Record.  The following fields are currently supported:
 
 =item comments - comments (optional)
 
+=item referral_custnum - referring customer number
+
 =back
 
 =head1 METHODS
@@ -189,7 +204,7 @@ points to.  You can ask the object for a copy with the I<hash> method.
 
 sub table { 'cust_main'; }
 
-=item insert [ CUST_PKG_HASHREF [ , INVOICING_LIST_ARYREF ] ]
+=item insert [ CUST_PKG_HASHREF [ , INVOICING_LIST_ARYREF ] [ , OPTION => VALUE ... ] ]
 
 Adds this customer to the database.  If there is an error, returns the error,
 otherwise returns false.
@@ -217,12 +232,18 @@ invoicing_list destination to the newly-created svc_acct.  Here's an example:
 
   $cust_main->insert( {}, [ $email, 'POST' ] );
 
+Currently available options are: I<noexport>
+
+If I<noexport> is set true, no provisioning jobs (exports) are scheduled.
+(You can schedule them later with the B<reexport> method.)
+
 =cut
 
 sub insert {
   my $self = shift;
   my $cust_pkgs = @_ ? shift : {};
   my $invoicing_list = @_ ? shift : '';
+  my %options = @_;
 
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
@@ -274,26 +295,11 @@ sub insert {
   }
 
   # packages
-  foreach my $cust_pkg ( keys %$cust_pkgs ) {
-    $cust_pkg->custnum( $self->custnum );
-    $error = $cust_pkg->insert;
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "inserting cust_pkg (transaction rolled back): $error";
-    }
-    foreach my $svc_something ( @{$cust_pkgs->{$cust_pkg}} ) {
-      $svc_something->pkgnum( $cust_pkg->pkgnum );
-      if ( $seconds && $svc_something->isa('FS::svc_acct') ) {
-        $svc_something->seconds( $svc_something->seconds + $seconds );
-        $seconds = 0;
-      }
-      $error = $svc_something->insert;
-      if ( $error ) {
-        $dbh->rollback if $oldAutoCommit;
-        #return "inserting svc_ (transaction rolled back): $error";
-        return $error;
-      }
-    }
+  #local $FS::svc_Common::noexport_hack = 1 if $options{'noexport'};
+  $error = $self->order_pkgs($cust_pkgs, \$seconds, %options);
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return $error;
   }
 
   if ( $seconds ) {
@@ -313,23 +319,115 @@ sub insert {
     }
   }
 
-  #false laziness with sub replace
-  my $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' };
-  $error = $queue->insert($self->getfield('last'), $self->company);
+  $error = $self->queue_fuzzyfiles_update;
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
-    return "queueing job (transaction rolled back): $error";
+    return "updating fuzzy search cache: $error";
   }
 
-  if ( defined $self->dbdef_table->column('ship_last') && $self->ship_last ) {
-    $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' };
-    $error = $queue->insert($self->getfield('last'), $self->company);
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
+
+}
+
+=item order_pkgs HASHREF, [ , OPTION => VALUE ... ] ]
+
+Like the insert method on an existing record, this method orders a package
+and included services atomicaly.  Pass a Tie::RefHash data structure to this
+method containing FS::cust_pkg and FS::svc_I<tablename> objects.  There should
+be a better explanation of this, but until then, here's an example:
+
+  use Tie::RefHash;
+  tie %hash, 'Tie::RefHash'; #this part is important
+  %hash = (
+    $cust_pkg => [ $svc_acct ],
+    ...
+  );
+  $cust_main->order_pkgs( \%hash, 'noexport'=>1 );
+
+Currently available options are: I<noexport>
+
+If I<noexport> is set true, no provisioning jobs (exports) are scheduled.
+(You can schedule them later with the B<reexport> method for each
+cust_pkg object.  Using the B<reexport> method on the cust_main object is not
+recommended, as existing services will also be reexported.)
+
+=cut
+
+sub order_pkgs {
+  my $self = shift;
+  my $cust_pkgs = shift;
+  my $seconds = shift;
+  my %options = @_;
+
+  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;
+
+  local $FS::svc_Common::noexport_hack = 1 if $options{'noexport'};
+
+  foreach my $cust_pkg ( keys %$cust_pkgs ) {
+    $cust_pkg->custnum( $self->custnum );
+    my $error = $cust_pkg->insert;
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
-      return "queueing job (transaction rolled back): $error";
+      return "inserting cust_pkg (transaction rolled back): $error";
+    }
+    foreach my $svc_something ( @{$cust_pkgs->{$cust_pkg}} ) {
+      $svc_something->pkgnum( $cust_pkg->pkgnum );
+      if ( $seconds && $$seconds && $svc_something->isa('FS::svc_acct') ) {
+        $svc_something->seconds( $svc_something->seconds + $$seconds );
+        $$seconds = 0;
+      }
+      $error = $svc_something->insert;
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        #return "inserting svc_ (transaction rolled back): $error";
+        return $error;
+      }
+    }
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  ''; #no error
+}
+
+=item reexport
+
+Re-schedules all exports by calling the B<reexport> method of all associated
+packages (see L<FS::cust_pkg>).  If there is an error, returns the error;
+otherwise returns false.
+
+=cut
+
+sub reexport {
+  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 $cust_pkg ( $self->ncancelled_pkgs ) {
+    my $error = $cust_pkg->reexport;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
     }
   }
-  #eslaf
 
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
   '';
@@ -343,7 +441,7 @@ returns false.
 
 This will completely remove all traces of the customer record.  This is not
 what you want when a customer cancels service; for that, cancel all of the
-customer's packages (see L<FS::cust_pkg/cancel>).
+customer's packages (see L</cancel>).
 
 If the customer has any uncancelled packages, you need to pass a new (valid)
 customer number for those packages to be transferred to.  Cancelled packages
@@ -370,19 +468,19 @@ sub delete {
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
 
-  if ( qsearch( 'cust_bill', { 'custnum' => $self->custnum } ) ) {
+  if ( $self->cust_bill ) {
     $dbh->rollback if $oldAutoCommit;
     return "Can't delete a customer with invoices";
   }
-  if ( qsearch( 'cust_credit', { 'custnum' => $self->custnum } ) ) {
+  if ( $self->cust_credit ) {
     $dbh->rollback if $oldAutoCommit;
     return "Can't delete a customer with credits";
   }
-  if ( qsearch( 'cust_pay', { 'custnum' => $self->custnum } ) ) {
+  if ( $self->cust_pay ) {
     $dbh->rollback if $oldAutoCommit;
     return "Can't delete a customer with payments";
   }
-  if ( qsearch( 'cust_refund', { 'custnum' => $self->custnum } ) ) {
+  if ( $self->cust_refund ) {
     $dbh->rollback if $oldAutoCommit;
     return "Can't delete a customer with refunds";
   }
@@ -461,6 +559,12 @@ sub replace {
   local $SIG{TSTP} = 'IGNORE';
   local $SIG{PIPE} = 'IGNORE';
 
+  if ( $self->payby eq 'COMP' && $self->payby ne $old->payby
+       && $conf->config('users-allow_comp')                  ) {
+    return "You are not permitted to create complimentary accounts."
+      unless grep { $_ eq getotaker } $conf->config('users-allow_comp');
+  }
+
   my $oldAutoCommit = $FS::UID::AutoCommit;
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
@@ -482,35 +586,49 @@ sub replace {
     $self->invoicing_list( $invoicing_list );
   }
 
-  if ( $self->payby eq 'CARD' &&
+  if ( $self->payby =~ /^(CARD|CHEK|LECB)$/ &&
        grep { $self->get($_) ne $old->get($_) } qw(payinfo paydate payname) ) {
-    # card info has changed, want to retry realtime_card invoice events
-    #false laziness w/collect
-    foreach my $cust_bill_event (
-      grep {
-             #$_->part_bill_event->plan eq 'realtime-card'
-             $_->part_bill_event->eventcode eq '$cust_bill->realtime_card();'
-               && $_->status eq 'done'
-               && $_->statustext
-           }
-        map { $_->cust_bill_event }
-          grep { $_->cust_bill_event }
-            $self->open_cust_bill
-
-    ) {
-      my $error = $cust_bill_event->retry;
-      if ( $error ) {
-        $dbh->rollback if $oldAutoCommit;
-        return "error scheduling invoice events for retry: $error";
-      }
+    # card/check/lec info has changed, want to retry realtime_ invoice events
+    my $error = $self->retry_realtime;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
     }
-    #eslaf
+  }
 
+  $error = $self->queue_fuzzyfiles_update;
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return "updating fuzzy search cache: $error";
   }
 
-  #false laziness with sub insert
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
+
+}
+
+=item queue_fuzzyfiles_update
+
+Used by insert & replace to update the fuzzy search cache
+
+=cut
+
+sub queue_fuzzyfiles_update {
+  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;
+
   my $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' };
-  $error = $queue->insert($self->getfield('last'), $self->company);
+  my $error = $queue->insert($self->getfield('last'), $self->company);
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return "queueing job (transaction rolled back): $error";
@@ -518,13 +636,12 @@ sub replace {
 
   if ( defined $self->dbdef_table->column('ship_last') && $self->ship_last ) {
     $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' };
-    $error = $queue->insert($self->getfield('last'), $self->company);
+    $error = $queue->insert($self->getfield('ship_last'), $self->ship_company);
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return "queueing job (transaction rolled back): $error";
     }
   }
-  #eslaf
 
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
   '';
@@ -561,7 +678,7 @@ sub check {
     || $self->ut_numbern('referral_custnum')
   ;
   #barf.  need message catalogs.  i18n.  etc.
-  $error .= "Please select a advertising source."
+  $error .= "Please select an advertising source."
     if $error =~ /^Illegal or empty \(numeric\) refnum: /;
   return $error if $error;
 
@@ -588,13 +705,13 @@ sub check {
 
 # bad idea to disable, causes billing to fail because of no tax rates later
 #  unless ( $import ) {
-    unless ( qsearchs('cust_main_county', {
+    unless ( qsearch('cust_main_county', {
       'country' => $self->country,
       'state'   => '',
      } ) ) {
       return "Unknown state/county/country: ".
         $self->state. "/". $self->county. "/". $self->country
-        unless qsearchs('cust_main_county',{
+        unless qsearch('cust_main_county',{
           'state'   => $self->state,
           'county'  => $self->county,
           'country' => $self->country,
@@ -664,11 +781,11 @@ sub check {
     }
   }
 
-  $self->payby =~ /^(CARD|BILL|COMP|PREPAY)$/
+  $self->payby =~ /^(CARD|DCRD|CHEK|DCHK|LECB|BILL|COMP|PREPAY)$/
     or return "Illegal payby: ". $self->payby;
   $self->payby($1);
 
-  if ( $self->payby eq 'CARD' ) {
+  if ( $self->payby eq 'CARD' || $self->payby eq 'DCRD' ) {
 
     my $payinfo = $self->payinfo;
     $payinfo =~ s/\D//g;
@@ -680,16 +797,56 @@ sub check {
       or return gettext('invalid_card'); # . ": ". $self->payinfo;
     return gettext('unknown_card_type')
       if cardtype($self->payinfo) eq "Unknown";
+    if ( defined $self->dbdef_table->column('paycvv') ) {
+      if ( length($self->paycvv) ) {
+        if ( cardtype($self->payinfo) eq 'American Express card' ) {
+          $self->paycvv =~ /^(\d{4})$/
+            or return "CVV2 (CID) for American Express cards is four digits.";
+          $self->paycvv($1);
+        } else {
+          $self->paycvv =~ /^(\d{3})$/
+            or return "CVV2 (CVC2/CID) is three digits.";
+          $self->paycvv($1);
+        }
+      } else {
+        $self->paycvv('');
+      }
+    }
+
+  } elsif ( $self->payby eq 'CHEK' || $self->payby eq 'DCHK' ) {
+
+    my $payinfo = $self->payinfo;
+    $payinfo =~ s/[^\d\@]//g;
+    $payinfo =~ /^(\d+)\@(\d{9})$/ or return 'invalid echeck account@aba';
+    $payinfo = "$1\@$2";
+    $self->payinfo($payinfo);
+    $self->paycvv('') if $self->dbdef_table->column('paycvv');
+
+  } elsif ( $self->payby eq 'LECB' ) {
+
+    my $payinfo = $self->payinfo;
+    $payinfo =~ s/\D//g;
+    $payinfo =~ /^1?(\d{10})$/ or return 'invalid btn billing telephone number';
+    $payinfo = $1;
+    $self->payinfo($payinfo);
+    $self->paycvv('') if $self->dbdef_table->column('paycvv');
 
   } elsif ( $self->payby eq 'BILL' ) {
 
     $error = $self->ut_textn('payinfo');
     return "Illegal P.O. number: ". $self->payinfo if $error;
+    $self->paycvv('') if $self->dbdef_table->column('paycvv');
 
   } elsif ( $self->payby eq 'COMP' ) {
 
+    if ( !$self->custnum && $conf->config('users-allow_comp') ) {
+      return "You are not permitted to create complimentary accounts."
+        unless grep { $_ eq getotaker } $conf->config('users-allow_comp');
+    }
+
     $error = $self->ut_textn('payinfo');
     return "Illegal comp account issuer: ". $self->payinfo if $error;
+    $self->paycvv('') if $self->dbdef_table->column('paycvv');
 
   } elsif ( $self->payby eq 'PREPAY' ) {
 
@@ -700,24 +857,33 @@ sub check {
     return "Illegal prepayment identifier: ". $self->payinfo if $error;
     return "Unknown prepayment identifier"
       unless qsearchs('prepay_credit', { 'identifier' => $self->payinfo } );
+    $self->paycvv('') if $self->dbdef_table->column('paycvv');
 
   }
 
   if ( $self->paydate eq '' || $self->paydate eq '-' ) {
     return "Expriation date required"
-      unless $self->payby eq 'BILL' || $self->payby eq 'PREPAY';
+      unless $self->payby =~ /^(BILL|PREPAY|CHEK|LECB)$/;
     $self->paydate('');
   } else {
-    $self->paydate =~ /^(\d{1,2})[\/\-](\d{2}(\d{2})?)$/
-      or return "Illegal expiration date: ". $self->paydate;
-    my $y = length($2) == 4 ? $2 : "20$2";
-    $self->paydate("$y-$1-01");
+    my( $m, $y );
+    if ( $self->paydate =~ /^(\d{1,2})[\/\-](\d{2}(\d{2})?)$/ ) {
+      ( $m, $y ) = ( $1, length($2) == 4 ? $2 : "20$2" );
+    } elsif ( $self->paydate =~ /^(20)?(\d{2})[\/\-](\d{2})[\/\-]\d+$/ ) {
+      ( $m, $y ) = ( $3, "20$2" );
+    } else {
+      return "Illegal expiration date: ". $self->paydate;
+    }
+    $self->paydate("$y-$m-01");
     my($nowm,$nowy)=(localtime(time))[4,5]; $nowm++; $nowy+=1900;
-    return gettext('expired_card') if $y<$nowy || ( $y==$nowy && $1<$nowm );
+    return gettext('expired_card')
+      if !$import && ( $y<$nowy || ( $y==$nowy && $1<$nowm ) );
   }
 
-  if ( $self->payname eq '' &&
-       ( ! $conf->exists('require_cardname') || $self->payby ne 'CARD' ) ) {
+  if ( $self->payname eq '' && $self->payby !~ /^(CHEK|DCHK)$/ &&
+       ( ! $conf->exists('require_cardname')
+         || $self->payby !~ /^(CARD|DCRD)$/  ) 
+  ) {
     $self->payname( $self->first. " ". $self->getfield('last') );
   } else {
     $self->payname =~ /^([\w \,\.\-\']+)$/
@@ -728,11 +894,11 @@ sub check {
   $self->tax =~ /^(Y?)$/ or return "Illegal tax: ". $self->tax;
   $self->tax($1);
 
-  $self->otaker(getotaker);
+  $self->otaker(getotaker) unless $self->otaker;
 
   #warn "AFTER: \n". $self->_dump;
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item all_pkgs
@@ -836,16 +1002,21 @@ sub suspend {
   grep { $_->suspend } $self->unsuspended_pkgs;
 }
 
-=item cancel
+=item cancel [ OPTION => VALUE ... ]
 
 Cancels all uncancelled packages (see L<FS::cust_pkg>) for this customer.
+
+Available options are: I<quiet>
+
+I<quiet> can be set true to supress email cancellation notices.
+
 Always returns a list: an empty list on success or a list of errors.
 
 =cut
 
 sub cancel {
   my $self = shift;
-  grep { $_->cancel } $self->ncancelled_pkgs;
+  grep { $_ } map { $_->cancel(@_) } $self->ncancelled_pkgs;
 }
 
 =item agent
@@ -866,15 +1037,19 @@ conjunction with the collect method.
 
 Options are passed as name-value pairs.
 
-The only currently available option is `time', which bills the customer as if
-it were that time.  It is specified as a UNIX timestamp; see
-L<perlfunc/"time">).  Also see L<Time::Local> and L<Date::Parse> for conversion
-functions.  For example:
+Currently available options are:
+
+resetup - if set true, re-charges setup fees.
+
+time - bills the customer as if it were that time.  Specified as a UNIX
+timestamp; see L<perlfunc/"time">).  Also see L<Time::Local> and
+L<Date::Parse> for conversion functions.  For example:
 
  use Date::Parse;
  ...
  $cust_main->bill( 'time' => str2time('April 20th, 2001') );
 
+
 If there is an error, returns the error, otherwise returns false.
 
 =cut
@@ -903,10 +1078,12 @@ sub bill {
   my( $total_setup, $total_recur ) = ( 0, 0 );
   #my( $taxable_setup, $taxable_recur ) = ( 0, 0 );
   my @cust_bill_pkg = ();
-  my $tax = 0;##
+  #my $tax = 0;##
   #my $taxable_charged = 0;##
   #my $charged = 0;##
 
+  my %tax;
+
   foreach my $cust_pkg (
     qsearch('cust_pkg', { 'custnum' => $self->custnum } )
   ) {
@@ -925,9 +1102,11 @@ sub bill {
     my %hash = $cust_pkg->hash;
     my $old_cust_pkg = new FS::cust_pkg \%hash;
 
+    my @details = ();
+
     # bill setup
     my $setup = 0;
-    unless ( $cust_pkg->setup ) {
+    if ( !$cust_pkg->setup || $options{'resetup'} ) {
       my $setup_prog = $part_pkg->getfield('setup');
       $setup_prog =~ /^(.*)$/ or do {
         $dbh->rollback if $oldAutoCommit;
@@ -935,6 +1114,7 @@ sub bill {
                ": $setup_prog";
       };
       $setup_prog = $1;
+      $setup_prog = '0' if $setup_prog =~ /^\s*$/;
 
         #my $cpt = new Safe;
         ##$cpt->permit(); #what is necessary?
@@ -946,16 +1126,16 @@ sub bill {
         return "Error eval-ing part_pkg->setup pkgpart ". $part_pkg->pkgpart.
                "(expression $setup_prog): $@";
       }
-      $cust_pkg->setfield('setup',$time);
+      $cust_pkg->setfield('setup', $time) unless $cust_pkg->setup;
       $cust_pkg_mod_flag=1; 
     }
 
     #bill recurring fee
     my $recur = 0;
     my $sdate;
-    if ( $part_pkg->getfield('freq') > 0 &&
+    if ( $part_pkg->getfield('freq') ne '0' &&
          ! $cust_pkg->getfield('susp') &&
-         ( $cust_pkg->getfield('bill') || 0 ) < $time
+         ( $cust_pkg->getfield('bill') || 0 ) <= $time
     ) {
       my $recur_prog = $part_pkg->getfield('recur');
       $recur_prog =~ /^(.*)$/ or do {
@@ -964,6 +1144,7 @@ sub bill {
                ": $recur_prog";
       };
       $recur_prog = $1;
+      $recur_prog = '0' if $recur_prog =~ /^\s*$/;
 
       # shared with $recur_prog
       $sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
@@ -987,11 +1168,24 @@ sub bill {
       # only for figuring next bill date, nothing else, so, reset $sdate again
       # here
       $sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
-
-      $mon += $part_pkg->freq;
-      until ( $mon < 12 ) { $mon -= 12; $year++; }
+      $cust_pkg->last_bill($sdate)
+        if $cust_pkg->dbdef_table->column('last_bill');
+
+      if ( $part_pkg->freq =~ /^\d+$/ ) {
+        $mon += $part_pkg->freq;
+        until ( $mon < 12 ) { $mon -= 12; $year++; }
+      } elsif ( $part_pkg->freq =~ /^(\d+)w$/ ) {
+        my $weeks = $1;
+        $mday += $weeks * 7;
+      } elsif ( $part_pkg->freq =~ /^(\d+)d$/ ) {
+        my $days = $1;
+        $mday += $days;
+      } else {
+        $dbh->rollback if $oldAutoCommit;
+        return "unparsable frequency: ". $part_pkg->freq;
+      }
       $cust_pkg->setfield('bill',
-        timelocal($sec,$min,$hour,$mday,$mon,$year));
+        timelocal_nocheck($sec,$min,$hour,$mday,$mon,$year));
       $cust_pkg_mod_flag = 1; 
     }
 
@@ -999,7 +1193,6 @@ sub bill {
     warn "\$recur is undefined" unless defined($recur);
     warn "\$cust_pkg->bill is undefined" unless defined($cust_pkg->bill);
 
-    my $taxable_charged = 0;
     if ( $cust_pkg_mod_flag ) {
       $error=$cust_pkg->replace($old_cust_pkg);
       if ( $error ) { #just in case
@@ -1008,105 +1201,133 @@ sub bill {
       }
       $setup = sprintf( "%.2f", $setup );
       $recur = sprintf( "%.2f", $recur );
-      if ( $setup < 0 ) {
+      if ( $setup < 0 && ! $conf->exists('allow_negative_charges') ) {
         $dbh->rollback if $oldAutoCommit;
         return "negative setup $setup for pkgnum ". $cust_pkg->pkgnum;
       }
-      if ( $recur < 0 ) {
+      if ( $recur < 0 && ! $conf->exists('allow_negative_charges') ) {
         $dbh->rollback if $oldAutoCommit;
         return "negative recur $recur for pkgnum ". $cust_pkg->pkgnum;
       }
-      if ( $setup > 0 || $recur > 0 ) {
+      if ( $setup != 0 || $recur != 0 ) {
         my $cust_bill_pkg = new FS::cust_bill_pkg ({
-          'pkgnum' => $cust_pkg->pkgnum,
-          'setup'  => $setup,
-          'recur'  => $recur,
-          'sdate'  => $sdate,
-          'edate'  => $cust_pkg->bill,
+          'pkgnum'  => $cust_pkg->pkgnum,
+          'setup'   => $setup,
+          'recur'   => $recur,
+          'sdate'   => $sdate,
+          'edate'   => $cust_pkg->bill,
+          'details' => \@details,
         });
         push @cust_bill_pkg, $cust_bill_pkg;
         $total_setup += $setup;
         $total_recur += $recur;
-        $taxable_charged += $setup
-          unless $part_pkg->setuptax =~ /^Y$/i;
-        $taxable_charged += $recur
-          unless $part_pkg->recurtax =~ /^Y$/i;
-          
-        unless ( $self->tax =~ /Y/i
-                 || $self->payby eq 'COMP'
-                 || $taxable_charged == 0 ) {
-
-          my $cust_main_county =
-            qsearchs('cust_main_county',{
-              'state'    => $self->state,
-              'county'   => $self->county,
-              'country'  => $self->country,
-              'taxclass' => $part_pkg->taxclass,
-            } )
-            or qsearchs('cust_main_county',{
-              'state'    => $self->state,
-              'county'   => $self->county,
-              'country'  => $self->country,
-              'taxclass' => '',
-            } )
-            or do {
-              $dbh->rollback if $oldAutoCommit;
-              return
-                "fatal: can't find tax rate for state/county/country/taxclass ".
-                join('/', ( map $self->$_(), qw(state county country) ),
-                          $part_pkg->taxclass ).  "\n";
-            };
-
-          if ( $cust_main_county->exempt_amount ) {
-            my ($mon,$year) = (localtime($sdate) )[4,5];
-            $mon++;
-            my $freq = $part_pkg->freq || 1;
-            my $taxable_per_month = sprintf("%.2f", $taxable_charged / $freq );
-            foreach my $which_month ( 1 .. $freq ) {
-              my %hash = (
-                'custnum' => $self->custnum,
-                'taxnum'  => $cust_main_county->taxnum,
-                'year'    => 1900+$year,
-                'month'   => $mon++,
-              );
-              #until ( $mon < 12 ) { $mon -= 12; $year++; }
-              until ( $mon < 13 ) { $mon -= 12; $year++; }
-              my $cust_tax_exempt =
-                qsearchs('cust_tax_exempt', \%hash)
-                || new FS::cust_tax_exempt( { %hash, 'amount' => 0 } );
-              my $remaining_exemption = sprintf("%.2f",
-                $cust_main_county->exempt_amount - $cust_tax_exempt->amount );
-              if ( $remaining_exemption > 0 ) {
-                my $addl = $remaining_exemption > $taxable_per_month
-                  ? $taxable_per_month
-                  : $remaining_exemption;
-                $taxable_charged -= $addl;
-                my $new_cust_tax_exempt = new FS::cust_tax_exempt ( {
-                  $cust_tax_exempt->hash,
-                  'amount' => sprintf("%.2f", $cust_tax_exempt->amount + $addl),
-                } );
-                $error = $new_cust_tax_exempt->exemptnum
-                  ? $new_cust_tax_exempt->replace($cust_tax_exempt)
-                  : $new_cust_tax_exempt->insert;
-                if ( $error ) {
-                  $dbh->rollback if $oldAutoCommit;
-                  return "fatal: can't update cust_tax_exempt: $error";
-                }
-
-              } # if $remaining_exemption > 0
-
-            } #foreach $which_month
-
-          } #if $cust_main_county->exempt_amount
-
-          $taxable_charged = sprintf( "%.2f", $taxable_charged);
-          $tax += $taxable_charged * $cust_main_county->tax / 100
-
-        } #unless $self->tax =~ /Y/i
-          #       || $self->payby eq 'COMP'
-          #       || $taxable_charged == 0
-
-      } #if $setup > 0 || $recur > 0
+
+        unless ( $self->tax =~ /Y/i || $self->payby eq 'COMP' ) {
+
+          my @taxes = qsearch( 'cust_main_county', {
+                                 'state'    => $self->state,
+                                 'county'   => $self->county,
+                                 'country'  => $self->country,
+                                 'taxclass' => $part_pkg->taxclass,
+                                                                      } );
+          unless ( @taxes ) {
+            @taxes =  qsearch( 'cust_main_county', {
+                                  'state'    => $self->state,
+                                  'county'   => $self->county,
+                                  'country'  => $self->country,
+                                  'taxclass' => '',
+                                                                      } );
+          }
+
+          #one more try at a whole-country tax rate
+          unless ( @taxes ) {
+            @taxes =  qsearch( 'cust_main_county', {
+                                  'state'    => '',
+                                  'county'   => '',
+                                  'country'  => $self->country,
+                                  'taxclass' => '',
+                                                                      } );
+          }
+
+          # maybe eliminate this entirely, along with all the 0% records
+          unless ( @taxes ) {
+            $dbh->rollback if $oldAutoCommit;
+            return
+              "fatal: can't find tax rate for state/county/country/taxclass ".
+              join('/', ( map $self->$_(), qw(state county country) ),
+                        $part_pkg->taxclass ).  "\n";
+          }
+  
+          foreach my $tax ( @taxes ) {
+
+            my $taxable_charged = 0;
+            $taxable_charged += $setup
+              unless $part_pkg->setuptax =~ /^Y$/i
+                  || $tax->setuptax =~ /^Y$/i;
+            $taxable_charged += $recur
+              unless $part_pkg->recurtax =~ /^Y$/i
+                  || $tax->recurtax =~ /^Y$/i;
+            next unless $taxable_charged;
+
+            if ( $tax->exempt_amount > 0 ) {
+              my ($mon,$year) = (localtime($sdate) )[4,5];
+              $mon++;
+              my $freq = $part_pkg->freq || 1;
+              if ( $freq !~ /(\d+)$/ ) {
+                $dbh->rollback if $oldAutoCommit;
+                return "daily/weekly package definitions not (yet?)".
+                       " compatible with monthly tax exemptions";
+              }
+              my $taxable_per_month = sprintf("%.2f", $taxable_charged / $freq );
+              foreach my $which_month ( 1 .. $freq ) {
+                my %hash = (
+                  'custnum' => $self->custnum,
+                  'taxnum'  => $tax->taxnum,
+                  'year'    => 1900+$year,
+                  'month'   => $mon++,
+                );
+                #until ( $mon < 12 ) { $mon -= 12; $year++; }
+                until ( $mon < 13 ) { $mon -= 12; $year++; }
+                my $cust_tax_exempt =
+                  qsearchs('cust_tax_exempt', \%hash)
+                  || new FS::cust_tax_exempt( { %hash, 'amount' => 0 } );
+                my $remaining_exemption = sprintf("%.2f",
+                  $tax->exempt_amount - $cust_tax_exempt->amount );
+                if ( $remaining_exemption > 0 ) {
+                  my $addl = $remaining_exemption > $taxable_per_month
+                    ? $taxable_per_month
+                    : $remaining_exemption;
+                  $taxable_charged -= $addl;
+                  my $new_cust_tax_exempt = new FS::cust_tax_exempt ( {
+                    $cust_tax_exempt->hash,
+                    'amount' =>
+                      sprintf("%.2f", $cust_tax_exempt->amount + $addl),
+                  } );
+                  $error = $new_cust_tax_exempt->exemptnum
+                    ? $new_cust_tax_exempt->replace($cust_tax_exempt)
+                    : $new_cust_tax_exempt->insert;
+                  if ( $error ) {
+                    $dbh->rollback if $oldAutoCommit;
+                    return "fatal: can't update cust_tax_exempt: $error";
+                  }
+  
+                } # if $remaining_exemption > 0
+  
+              } #foreach $which_month
+  
+            } #if $tax->exempt_amount
+
+            $taxable_charged = sprintf( "%.2f", $taxable_charged);
+
+            #$tax += $taxable_charged * $cust_main_county->tax / 100
+            $tax{ $tax->taxname || 'Tax' } +=
+              $taxable_charged * $tax->tax / 100
+
+          } #foreach my $tax ( @taxes )
+
+        } #unless $self->tax =~ /Y/i || $self->payby eq 'COMP'
+
+      } #if $setup != 0 || $recur != 0
       
     } #if $cust_pkg_mod_flag
 
@@ -1133,20 +1354,42 @@ sub bill {
 #      $taxable_charged * ( $cust_main_county->getfield('tax') / 100 )
 #    );
 
-  $tax = sprintf("%.2f", $tax);
-  if ( $tax > 0 ) {
-    $charged = sprintf( "%.2f", $charged+$tax );
+  if ( dbdef->table('cust_bill_pkg')->column('itemdesc') ) { #1.5 schema
+
+    foreach my $taxname ( grep { $tax{$_} > 0 } keys %tax ) {
+      my $tax = sprintf("%.2f", $tax{$taxname} );
+      $charged = sprintf( "%.2f", $charged+$tax );
+  
+      my $cust_bill_pkg = new FS::cust_bill_pkg ({
+        'pkgnum'   => 0,
+        'setup'    => $tax,
+        'recur'    => 0,
+        'sdate'    => '',
+        'edate'    => '',
+        'itemdesc' => $taxname,
+      });
+      push @cust_bill_pkg, $cust_bill_pkg;
+    }
+  
+  } else { #1.4 schema
+
+    my $tax = 0;
+    foreach ( values %tax ) { $tax += $_ };
+    $tax = sprintf("%.2f", $tax);
+    if ( $tax > 0 ) {
+      $charged = sprintf( "%.2f", $charged+$tax );
+
+      my $cust_bill_pkg = new FS::cust_bill_pkg ({
+        'pkgnum' => 0,
+        'setup'  => $tax,
+        'recur'  => 0,
+        'sdate'  => '',
+        'edate'  => '',
+      });
+      push @cust_bill_pkg, $cust_bill_pkg;
+    }
 
-    my $cust_bill_pkg = new FS::cust_bill_pkg ({
-      'pkgnum' => 0,
-      'setup'  => $tax,
-      'recur'  => 0,
-      'sdate'  => '',
-      'edate'  => '',
-    });
-    push @cust_bill_pkg, $cust_bill_pkg;
   }
-#  }
 
   my $cust_bill = new FS::cust_bill ( {
     'custnum' => $self->custnum,
@@ -1181,8 +1424,9 @@ sub bill {
 (Attempt to) collect money for this customer's outstanding invoices (see
 L<FS::cust_bill>).  Usually used after the bill method.
 
-Depending on the value of `payby', this may print an invoice (`BILL'), charge
-a credit card (`CARD'), or just add any necessary (pseudo-)payment (`COMP').
+Depending on the value of `payby', this may print or email an invoice (I<BILL>,
+I<DCRD>, or I<DCHK>), charge a credit card (I<CARD>), charge via electronic
+check/ACH (I<CHEK>), or just add any necessary (pseudo-)payment (I<COMP>).
 
 Most actions are now triggered by invoice events; see L<FS::part_bill_event>
 and the invoice events web interface.
@@ -1197,7 +1441,10 @@ invoice_time - Use this time when deciding when to print invoices and
 late notices on those invoices.  The default is now.  It is specified as a UNIX timestamp; see L<perlfunc/"time">).  Also see L<Time::Local> and L<Date::Parse>
 for conversion functions.
 
-retry_card - Retry cards even when not scheduled by invoice events.
+retry - Retry card/echeck/LEC transactions even when not scheduled by invoice
+events.
+
+retry_card - Deprecated alias for 'retry'
 
 batch_card - This option is deprecated.  See the invoice events web interface
 to control whether cards are batched or run against a realtime gateway.
@@ -1206,6 +1453,8 @@ report_badcard - This option is deprecated.
 
 force_print - This option is deprecated; see the invoice events web interface.
 
+quiet - set true to surpress email card/ACH decline notices.
+
 =cut
 
 sub collect {
@@ -1231,46 +1480,27 @@ sub collect {
     return '';
   }
 
-  if ( exists($options{'retry_card'}) && $options{'retry_card'} ) {
-    #false laziness w/replace
-    foreach my $cust_bill_event (
-      grep {
-             #$_->part_bill_event->plan eq 'realtime-card'
-             $_->part_bill_event->eventcode eq '$cust_bill->realtime_card();'
-               && $_->status eq 'done'
-               && $_->statustext
-           }
-        map { $_->cust_bill_event }
-          grep { $_->cust_bill_event }
-            $self->open_cust_bill
-    ) {
-      my $error = $cust_bill_event->retry;
-      if ( $error ) {
-        $dbh->rollback if $oldAutoCommit;
-        return "error scheduling invoice events for retry: $error";
-      }
+  if ( exists($options{'retry_card'}) ) {
+    carp 'retry_card option passed to collect is deprecated; use retry';
+    $options{'retry'} ||= $options{'retry_card'};
+  }
+  if ( exists($options{'retry'}) && $options{'retry'} ) {
+    my $error = $self->retry_realtime;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
     }
-    #eslaf
   }
 
-  foreach my $cust_bill ( $self->cust_bill ) {
-
-    #this has to be before next's
-    my $amount = sprintf( "%.2f", $balance < $cust_bill->owed
-                                  ? $balance
-                                  : $cust_bill->owed
-    );
-    $balance = sprintf( "%.2f", $balance - $amount );
-
-    next unless $cust_bill->owed > 0;
+  foreach my $cust_bill ( $self->open_cust_bill ) {
 
     # don't try to charge for the same invoice if it's already in a batch
     #next if qsearchs( 'cust_pay_batch', { 'invnum' => $cust_bill->invnum } );
 
-    warn "invnum ". $cust_bill->invnum. " (owed ". $cust_bill->owed. ", amount $amount, balance $balance)" if $Debug;
-
-    next unless $amount > 0;
+    last if $self->balance <= 0;
 
+    warn "invnum ". $cust_bill->invnum. " (owed ". $cust_bill->owed. ")"
+      if $Debug;
 
     foreach my $part_bill_event (
       sort {    $a->seconds   <=> $b->seconds
@@ -1287,12 +1517,18 @@ sub collect {
                                        'disabled' => '',           } )
     ) {
 
-      last unless $cust_bill->owed > 0; #don't run subsequent events if owed=0
+      last if $cust_bill->owed <= 0  # don't run subsequent events if owed<=0
+           || $self->balance   <= 0; # or if balance<=0
 
       warn "calling invoice event (". $part_bill_event->eventcode. ")\n"
         if $Debug;
       my $cust_main = $self; #for callback
-      my $error = eval $part_bill_event->eventcode;
+
+      my $error;
+      {
+        local $realtime_bop_decline_quiet = 1 if $options{'quiet'};
+        $error = eval $part_bill_event->eventcode;
+      }
 
       my $status = '';
       my $statustext = '';
@@ -1310,7 +1546,8 @@ sub collect {
       my $cust_bill_event = new FS::cust_bill_event {
         'invnum'     => $cust_bill->invnum,
         'eventpart'  => $part_bill_event->eventpart,
-        '_date'      => $invoice_time,
+        #'_date'      => $invoice_time,
+        '_date'      => time,
         'status'     => $status,
         'statustext' => $statustext,
       };
@@ -1339,6 +1576,322 @@ sub collect {
 
 }
 
+=item retry_realtime
+
+Schedules realtime credit card / electronic check / LEC billing events for
+for retry.  Useful if card information has changed or manual retry is desired.
+The 'collect' method must be called to actually retry the transaction.
+
+Implementation details: For each of this customer's open invoices, changes
+the status of the first "done" (with statustext error) realtime processing
+event to "failed".
+
+=cut
+
+sub retry_realtime {
+  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 $cust_bill (
+    grep { $_->cust_bill_event }
+      $self->open_cust_bill
+  ) {
+    my @cust_bill_event =
+      sort { $a->part_bill_event->seconds <=> $b->part_bill_event->seconds }
+        grep {
+               #$_->part_bill_event->plan eq 'realtime-card'
+               $_->part_bill_event->eventcode =~
+                   /\$cust_bill\->realtime_(card|ach|lec)/
+                 && $_->status eq 'done'
+                 && $_->statustext
+             }
+          $cust_bill->cust_bill_event;
+    next unless @cust_bill_event;
+    my $error = $cust_bill_event[0]->retry;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "error scheduling invoice event for retry: $error";
+    }
+
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
+
+}
+
+=item realtime_bop METHOD AMOUNT [ OPTION => VALUE ... ]
+
+Runs a realtime credit card, ACH (electronic check) or phone bill transaction
+via a Business::OnlinePayment realtime gateway.  See
+L<http://420.am/business-onlinepayment> for supported gateways.
+
+Available methods are: I<CC>, I<ECHECK> and I<LEC>
+
+Available options are: I<description>, I<invnum>, I<quiet>
+
+The additional options I<payname>, I<address1>, I<address2>, I<city>, I<state>,
+I<zip>, I<payinfo> and I<paydate> are also available.  Any of these options,
+if set, will override the value from the customer record.
+
+I<description> is a free-text field passed to the gateway.  It defaults to
+"Internet services".
+
+If an I<invnum> is specified, this payment (if sucessful) is applied to the
+specified invoice.  If you don't specify an I<invnum> you might want to
+call the B<apply_payments> method.
+
+I<quiet> can be set true to surpress email decline notices.
+
+(moved from cust_bill) (probably should get realtime_{card,ach,lec} here too)
+
+=cut
+
+sub realtime_bop {
+  my( $self, $method, $amount, %options ) = @_;
+  if ( $Debug ) {
+    warn "$self $method $amount\n";
+    warn "  $_ => $options{$_}\n" foreach keys %options;
+  }
+
+  $options{'description'} ||= 'Internet services';
+
+  #pre-requisites
+  die "Real-time processing not enabled\n"
+    unless $conf->exists('business-onlinepayment');
+  eval "use Business::OnlinePayment";  
+  die $@ if $@;
+
+  #overrides
+  $self->set( $_ => $options{$_} )
+    foreach grep { exists($options{$_}) }
+            qw( payname address1 address2 city state zip payinfo paydate );
+
+  #load up config
+  my $bop_config = 'business-onlinepayment';
+  $bop_config .= '-ach'
+    if $method eq 'ECHECK' && $conf->exists($bop_config. '-ach');
+  my ( $processor, $login, $password, $action, @bop_options ) =
+    $conf->config($bop_config);
+  $action ||= 'normal authorization';
+  pop @bop_options if scalar(@bop_options) % 2 && $bop_options[-1] =~ /^\s*$/;
+
+  #massage data
+
+  my $address = $self->address1;
+  $address .= ", ". $self->address2 if $self->address2;
+
+  my($payname, $payfirst, $paylast);
+  if ( $self->payname && $method ne 'ECHECK' ) {
+    $payname = $self->payname;
+    $payname =~ /^\s*([\w \,\.\-\']*)?\s+([\w\,\.\-\']+)\s*$/
+      or return "Illegal payname $payname";
+    ($payfirst, $paylast) = ($1, $2);
+  } else {
+    $payfirst = $self->getfield('first');
+    $paylast = $self->getfield('last');
+    $payname =  "$payfirst $paylast";
+  }
+
+  my @invoicing_list = grep { $_ ne 'POST' } $self->invoicing_list;
+  if ( $conf->exists('emailinvoiceauto')
+       || ( $conf->exists('emailinvoiceonly') && ! @invoicing_list ) ) {
+    push @invoicing_list, $self->all_emails;
+  }
+  my $email = $invoicing_list[0];
+
+  my %content;
+  if ( $method eq 'CC' ) { 
+
+    $content{card_number} = $self->payinfo;
+    $self->paydate =~ /^\d{2}(\d{2})[\/\-](\d+)[\/\-]\d+$/;
+    $content{expiration} = "$2/$1";
+
+    $content{cvv2} = $self->paycvv
+      if defined $self->dbdef_table->column('paycvv')
+         && length($self->paycvv);
+
+    $content{recurring_billing} = 'YES'
+      if qsearch('cust_pay', { 'custnum' => $self->custnum,
+                               'payby'   => 'CARD',
+                               'payinfo' => $self->payinfo, } );
+
+  } elsif ( $method eq 'ECHECK' ) {
+    my($account_number,$routing_code) = $self->payinfo;
+    ( $content{account_number}, $content{routing_code} ) =
+      split('@', $self->payinfo);
+    $content{bank_name} = $self->payname;
+    $content{account_type} = 'CHECKING';
+    $content{account_name} = $payname;
+    $content{customer_org} = $self->company ? 'B' : 'I';
+    $content{customer_ssn} = $self->ss;
+  } elsif ( $method eq 'LEC' ) {
+    $content{phone} = $self->payinfo;
+  }
+
+  #transaction(s)
+
+  my( $action1, $action2 ) = split(/\s*\,\s*/, $action );
+
+  my $transaction =
+    new Business::OnlinePayment( $processor, @bop_options );
+  $transaction->content(
+    'type'           => $method,
+    'login'          => $login,
+    'password'       => $password,
+    'action'         => $action1,
+    'description'    => $options{'description'},
+    'amount'         => $amount,
+    'invoice_number' => $options{'invnum'},
+    'customer_id'    => $self->custnum,
+    'last_name'      => $paylast,
+    'first_name'     => $payfirst,
+    'name'           => $payname,
+    'address'        => $address,
+    'city'           => $self->city,
+    'state'          => $self->state,
+    'zip'            => $self->zip,
+    'country'        => $self->country,
+    'referer'        => 'http://cleanwhisker.420.am/',
+    'email'          => $email,
+    'phone'          => $self->daytime || $self->night,
+    %content, #after
+  );
+  $transaction->submit();
+
+  if ( $transaction->is_success() && $action2 ) {
+    my $auth = $transaction->authorization;
+    my $ordernum = $transaction->can('order_number')
+                   ? $transaction->order_number
+                   : '';
+
+    my $capture =
+      new Business::OnlinePayment( $processor, @bop_options );
+
+    my %capture = (
+      %content,
+      type           => $method,
+      action         => $action2,
+      login          => $login,
+      password       => $password,
+      order_number   => $ordernum,
+      amount         => $amount,
+      authorization  => $auth,
+      description    => $options{'description'},
+    );
+
+    foreach my $field (qw( authorization_source_code returned_ACI                                          transaction_identifier validation_code           
+                           transaction_sequence_num local_transaction_date    
+                           local_transaction_time AVS_result_code          )) {
+      $capture{$field} = $transaction->$field() if $transaction->can($field);
+    }
+
+    $capture->content( %capture );
+
+    $capture->submit();
+
+    unless ( $capture->is_success ) {
+      my $e = "Authorization sucessful but capture failed, custnum #".
+              $self->custnum. ': '.  $capture->result_code.
+              ": ". $capture->error_message;
+      warn $e;
+      return $e;
+    }
+
+  }
+
+  #remove paycvv after initial transaction
+  #make this disable-able via a config option if anyone insists?  
+  # (though that probably violates cardholder agreements)
+  if ( defined $self->dbdef_table->column('paycvv')
+       && length($self->paycvv)
+       && ! grep { $_ eq cardtype($self->payinfo) } $conf->config('cvv-save')
+  ) {
+    my $new = new FS::cust_main { $self->hash };
+    $new->paycvv('');
+    my $error = $new->replace($self);
+    if ( $error ) {
+      warn "error removing cvv: $error\n";
+    }
+  }
+
+  #result handling
+  if ( $transaction->is_success() ) {
+
+    my %method2payby = (
+      'CC'     => 'CARD',
+      'ECHECK' => 'CHEK',
+      'LEC'    => 'LECB',
+    );
+
+    my $cust_pay = new FS::cust_pay ( {
+       'custnum'  => $self->custnum,
+       'invnum'   => $options{'invnum'},
+       'paid'     => $amount,
+       '_date'     => '',
+       'payby'    => $method2payby{$method},
+       'payinfo'  => $self->payinfo,
+       'paybatch' => "$processor:". $transaction->authorization,
+    } );
+    my $error = $cust_pay->insert;
+    if ( $error ) {
+      # gah, even with transactions.
+      my $e = 'WARNING: Card/ACH debited but database not updated - '.
+              'error applying payment, invnum #' . $self->invnum.
+              " ($processor): $error";
+      warn $e;
+      return $e;
+    } else {
+      return '';
+    }
+
+  } else {
+
+    my $perror = "$processor error: ". $transaction->error_message;
+
+    if ( !$options{'quiet'} && !$realtime_bop_decline_quiet
+         && $conf->exists('emaildecline')
+         && grep { $_ ne 'POST' } $self->invoicing_list
+         && ! grep { $_ eq $transaction->error_message }
+                   $conf->config('emaildecline-exclude')
+    ) {
+      my @templ = $conf->config('declinetemplate');
+      my $template = new Text::Template (
+        TYPE   => 'ARRAY',
+        SOURCE => [ map "$_\n", @templ ],
+      ) or return "($perror) can't create template: $Text::Template::ERROR";
+      $template->compile()
+        or return "($perror) can't compile template: $Text::Template::ERROR";
+
+      my $templ_hash = { error => $transaction->error_message };
+
+      my $error = send_email(
+        'from'    => $conf->config('invoice_from'),
+        'to'      => [ grep { $_ ne 'POST' } $self->invoicing_list ],
+        'subject' => 'Your payment could not be processed',
+        'body'    => [ $template->fill_in(HASH => $templ_hash) ],
+      );
+
+      $perror .= " (also received error sending decline notification: $error)"
+        if $error;
+
+    }
+  
+    return $perror;
+  }
+
+}
+
 =item total_owed
 
 Returns the total owed for this customer on all invoices
@@ -1583,7 +2136,6 @@ sub invoicing_list {
     }
     my %seen = map { $_->address => 1 } @cust_main_invoice;
     foreach my $address ( @{$arrayref} ) {
-      #unless ( grep { $address eq $_->address } @cust_main_invoice ) {
       next if exists $seen{$address} && $seen{$address};
       $seen{$address} = 1;
       my $cust_main_invoice = new FS::cust_main_invoice ( {
@@ -1625,24 +2177,36 @@ sub check_invoicing_list {
   '';
 }
 
-=item default_invoicing_list
+=item set_default_invoicing_list
 
-Sets the invoicing list to all accounts associated with this customer.
+Sets the invoicing list to all accounts associated with this customer,
+overwriting any previous invoicing list.
 
 =cut
 
-sub default_invoicing_list {
+sub set_default_invoicing_list {
   my $self = shift;
-  my @list = ();
+  $self->invoicing_list($self->all_emails);
+}
+
+=item all_emails
+
+Returns the email addresses of all accounts provisioned for this customer.
+
+=cut
+
+sub all_emails {
+  my $self = shift;
+  my %list;
   foreach my $cust_pkg ( $self->all_pkgs ) {
     my @cust_svc = qsearch('cust_svc', { 'pkgnum' => $cust_pkg->pkgnum } );
     my @svc_acct =
       map { qsearchs('svc_acct', { 'svcnum' => $_->svcnum } ) }
         grep { qsearchs('svc_acct', { 'svcnum' => $_->svcnum } ) }
           @cust_svc;
-    push @list, map { $_->email } @svc_acct;
+    $list{$_}=1 foreach map { $_->email } @svc_acct;
   }
-  $self->invoicing_list(\@list);
+  keys %list;
 }
 
 =item invoicing_list_addpost
@@ -1825,6 +2389,42 @@ sub open_cust_bill {
   grep { $_->owed > 0 } $self->cust_bill;
 }
 
+=item cust_credit
+
+Returns all the credits (see L<FS::cust_credit>) for this customer.
+
+=cut
+
+sub cust_credit {
+  my $self = shift;
+  sort { $a->_date <=> $b->_date }
+    qsearch( 'cust_credit', { 'custnum' => $self->custnum } )
+}
+
+=item cust_pay
+
+Returns all the payments (see L<FS::cust_pay>) for this customer.
+
+=cut
+
+sub cust_pay {
+  my $self = shift;
+  sort { $a->_date <=> $b->_date }
+    qsearch( 'cust_pay', { 'custnum' => $self->custnum } )
+}
+
+=item cust_refund
+
+Returns all the refunds (see L<FS::cust_refund>) for this customer.
+
+=cut
+
+sub cust_refund {
+  my $self = shift;
+  sort { $a->_date <=> $b->_date }
+    qsearch( 'cust_refund', { 'custnum' => $self->custnum } )
+}
+
 =back
 
 =head1 SUBROUTINES
@@ -1964,6 +2564,201 @@ sub append_fuzzyfiles {
   1;
 }
 
+=item batch_import
+
+=cut
+
+sub batch_import {
+  my $param = shift;
+  #warn join('-',keys %$param);
+  my $fh = $param->{filehandle};
+  my $agentnum = $param->{agentnum};
+  my $refnum = $param->{refnum};
+  my $pkgpart = $param->{pkgpart};
+  my @fields = @{$param->{fields}};
+
+  eval "use Date::Parse;";
+  die $@ if $@;
+  eval "use Text::CSV_XS;";
+  die $@ if $@;
+
+  my $csv = new Text::CSV_XS;
+  #warn $csv;
+  #warn $fh;
+
+  my $imported = 0;
+  #my $columns;
+
+  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;
+  
+  #while ( $columns = $csv->getline($fh) ) {
+  my $line;
+  while ( defined($line=<$fh>) ) {
+
+    $csv->parse($line) or do {
+      $dbh->rollback if $oldAutoCommit;
+      return "can't parse: ". $csv->error_input();
+    };
+
+    my @columns = $csv->fields();
+    #warn join('-',@columns);
+
+    my %cust_main = (
+      agentnum => $agentnum,
+      refnum   => $refnum,
+      country  => 'US', #default
+      payby    => 'BILL', #default
+      paydate  => '12/2037', #default
+    );
+    my $billtime = time;
+    my %cust_pkg = ( pkgpart => $pkgpart );
+    foreach my $field ( @fields ) {
+      if ( $field =~ /^cust_pkg\.(setup|bill|susp|expire|cancel)$/ ) {
+        #$cust_pkg{$1} = str2time( shift @$columns );
+        if ( $1 eq 'setup' ) {
+          $billtime = str2time(shift @columns);
+        } else {
+          $cust_pkg{$1} = str2time( shift @columns );
+        }
+      } else {
+        #$cust_main{$field} = shift @$columns; 
+        $cust_main{$field} = shift @columns; 
+      }
+    }
+
+    my $cust_pkg = new FS::cust_pkg ( \%cust_pkg ) if $pkgpart;
+    my $cust_main = new FS::cust_main ( \%cust_main );
+    use Tie::RefHash;
+    tie my %hash, 'Tie::RefHash'; #this part is important
+    $hash{$cust_pkg} = [] if $pkgpart;
+    my $error = $cust_main->insert( \%hash );
+
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "can't insert customer for $line: $error";
+    }
+
+    #false laziness w/bill.cgi
+    $error = $cust_main->bill( 'time' => $billtime );
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "can't bill customer for $line: $error";
+    }
+
+    $cust_main->apply_payments;
+    $cust_main->apply_credits;
+
+    $error = $cust_main->collect();
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "can't collect customer for $line: $error";
+    }
+
+    $imported++;
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+  return "Empty file!" unless $imported;
+
+  ''; #no error
+
+}
+
+=item batch_charge
+
+=cut
+
+sub batch_charge {
+  my $param = shift;
+  #warn join('-',keys %$param);
+  my $fh = $param->{filehandle};
+  my @fields = @{$param->{fields}};
+
+  eval "use Date::Parse;";
+  die $@ if $@;
+  eval "use Text::CSV_XS;";
+  die $@ if $@;
+
+  my $csv = new Text::CSV_XS;
+  #warn $csv;
+  #warn $fh;
+
+  my $imported = 0;
+  #my $columns;
+
+  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;
+  
+  #while ( $columns = $csv->getline($fh) ) {
+  my $line;
+  while ( defined($line=<$fh>) ) {
+
+    $csv->parse($line) or do {
+      $dbh->rollback if $oldAutoCommit;
+      return "can't parse: ". $csv->error_input();
+    };
+
+    my @columns = $csv->fields();
+    #warn join('-',@columns);
+
+    my %row = ();
+    foreach my $field ( @fields ) {
+      $row{$field} = shift @columns;
+    }
+
+    my $cust_main = qsearchs('cust_main', { 'custnum' => $row{'custnum'} } );
+    unless ( $cust_main ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "unknown custnum $row{'custnum'}";
+    }
+
+    if ( $row{'amount'} > 0 ) {
+      my $error = $cust_main->charge($row{'amount'}, $row{'pkg'});
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return $error;
+      }
+      $imported++;
+    } elsif ( $row{'amount'} < 0 ) {
+      my $error = $cust_main->credit( sprintf( "%.2f", 0-$row{'amount'} ),
+                                      $row{'pkg'}                         );
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return $error;
+      }
+      $imported++;
+    } else {
+      #hmm?
+    }
+
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+  return "Empty file!" unless $imported;
+
+  ''; #no error
+
+}
+
 =back
 
 =head1 BUGS
@@ -1991,4 +2786,3 @@ L<FS::cust_main_invoice>, L<FS::UID>, schema.html from the base documentation.
 
 1;
 
-
index e41564d..76c982a 100644 (file)
@@ -61,6 +61,12 @@ currently supported:
 
 =item exempt_amount
 
+=item taxname - if defined, printed on invoices instead of "Tax"
+
+=item setuptax - if 'Y', this tax does not apply to setup fees
+
+=item recurtax - if 'Y', this tax does not apply to recurring fees
+
 =back
 
 =head1 METHODS
@@ -110,8 +116,39 @@ sub check {
     || $self->ut_float('tax')
     || $self->ut_textn('taxclass') # ...
     || $self->ut_money('exempt_amount')
-  ;
+    || $self->ut_textn('taxname')
+    || $self->ut_enum('setuptax', [ '', 'Y' ] )
+    || $self->ut_enum('recurtax', [ '', 'Y' ] )
+    || $self->SUPER::check
+    ;
+
+}
+
+sub taxname {
+  my $self = shift;
+  if ( $self->dbdef_table->column('taxname') ) {
+    return $self->setfield('taxname', $_[0]) if @_;
+    return $self->getfield('taxname');
+  }  
+  return '';
+}
+
+sub setuptax {
+  my $self = shift;
+  if ( $self->dbdef_table->column('setuptax') ) {
+    return $self->setfield('setuptax', $_[0]) if @_;
+    return $self->getfield('setuptax');
+  }  
+  return '';
+}
 
+sub recurtax {
+  my $self = shift;
+  if ( $self->dbdef_table->column('recurtax') ) {
+    return $self->setfield('recurtax', $_[0]) if @_;
+    return $self->getfield('recurtax');
+  }  
+  return '';
 }
 
 =back
index a5533a0..add0cca 100644 (file)
@@ -107,7 +107,7 @@ sub check {
   return "Unknown customer"
     unless qsearchs('cust_main',{ 'custnum' => $self->custnum });
 
-  ''; #noerror
+  $self->SUPER::check;
 }
 
 =item checkdest
@@ -134,13 +134,6 @@ sub checkdest {
       unless qsearchs( 'svc_acct', { 'svcnum' => $self->dest } );
   } elsif ( $self->dest =~ /^([\w\.\-\&\+]+)\@(([\w\.\-]+\.)+\w+)$/ ) {
     my($user, $domain) = ($1, $2);
-#    if ( $domain eq $mydomain ) {
-#      my $svc_acct = qsearchs( 'svc_acct', { 'username' => $user } );
-#      return "Unknown local account: $user\@$domain (specified literally)"
-#        unless $svc_acct;
-#      $svc_acct->svcnum =~ /^(\d+)$/ or die "Non-numeric svcnum?!";
-#      $self->dest($1);
-#    }
     $self->dest("$1\@$2");
   } else {
     return gettext("illegal_email_invoice_address");
@@ -170,7 +163,7 @@ sub address {
 
 =head1 VERSION
 
-$Id: cust_main_invoice.pm,v 1.12 2002-04-12 13:22:02 ivan Exp $
+$Id: cust_main_invoice.pm,v 1.14 2003-08-05 00:20:42 khoff Exp $
 
 =head1 BUGS
 
index 98eba70..e1943ae 100644 (file)
@@ -1,13 +1,12 @@
 package FS::cust_pay;
 
 use strict;
-use vars qw( @ISA $conf $unsuspendauto $smtpmachine $invoice_from );
+use vars qw( @ISA $conf $unsuspendauto );
 use Date::Format;
-use Mail::Header;
-use Mail::Internet 1.44;
 use Business::CreditCard;
 use FS::UID qw( dbh );
 use FS::Record qw( dbh qsearch qsearchs dbh );
+use FS::Misc qw(send_email);
 use FS::cust_bill;
 use FS::cust_bill_pay;
 use FS::cust_main;
@@ -15,14 +14,10 @@ use FS::cust_main;
 @ISA = qw( FS::Record );
 
 #ask FS::UID to run this stuff for us later
-$FS::UID::callback{'FS::cust_pay'} = sub { 
-
+FS::UID->install_callback( sub { 
   $conf = new FS::Conf;
   $unsuspendauto = $conf->exists('unsuspendauto');
-  $smtpmachine = $conf->config('smtpmachine');
-  $invoice_from = $conf->config('invoice_from');
-
-};
+} );
 
 =head1 NAME
 
@@ -60,7 +55,8 @@ currently supported:
 =item _date - specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see
 L<Time::Local> and L<Date::Parse> for conversion functions.
 
-=item payby - `CARD' (credit cards), `BILL' (billing), or `COMP' (free)
+=item payby - `CARD' (credit cards), `CHEK' (electronic check/ACH),
+`LECB' (phone bill billing), `BILL' (billing), or `COMP' (free)
 
 =item payinfo - card number, check #, or comp issuer (4-8 lowercase alphanumerics; think username), respectively
 
@@ -264,19 +260,12 @@ sub delete {
   if ( $conf->config('deletepayments') ne '' ) {
 
     my $cust_main = qsearchs('cust_main',{ 'custnum' => $self->custnum });
-    #false laziness w/FS::cust_bill::send & fs_signup_server
-    $ENV{MAILADDRESS} = $invoice_from; #??? well as good as any
-    my $header = new Mail::Header ( [
-      "From: $invoice_from",
-      "To: ". $conf->config('deletepayments'),
-      "Sender: $invoice_from",
-      "Reply-To: $invoice_from",
-      "Date: ". time2str("%a, %d %b %Y %X %z", time),
-      "Subject: FREESIDE NOTIFICATION: Payment deleted",
-    ] );
-    my $message = new Mail::Internet (
-      'Header' => $header,
-      'Body' => [ 
+
+    my $error = send_email(
+      'from'    => $conf->config('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",
@@ -290,16 +279,12 @@ sub delete {
         'paybatch: '. $self->paybatch. "\n",
       ],
     );
-    $!=0;
-    $message->smtpsend( Host => $smtpmachine )
-      or $message->smtpsend( Host => $smtpmachine, Debug => 1 )
-        or do {
-          $dbh->rollback if $oldAutoCommit;
-          return "(customer # ". $self->custnum.
-                 ") can't send payment deletion email to ".
-                 $conf->config('deletepayments').
-                 " via server $smtpmachine with SMTP: $!";
-        };
+
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "can't send payment deletion notification: $error";
+    }
+
   }
 
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
@@ -346,7 +331,7 @@ sub check {
 
   $self->_date(time) unless $self->_date;
 
-  $self->payby =~ /^(CARD|BILL|COMP)$/ or return "Illegal payby";
+  $self->payby =~ /^(CARD|CHEK|LECB|BILL|COMP)$/ or return "Illegal payby";
   $self->payby($1);
 
   #false laziness with cust_refund::check
@@ -369,8 +354,7 @@ sub check {
     return $error if $error;
   }
 
-  ''; #no error
-
+  $self->SUPER::check;
 }
 
 =item cust_bill_pay
@@ -401,11 +385,23 @@ sub unapplied {
   sprintf("%.2f", $amount );
 }
 
+=item cust_main
+
+Returns the parent customer object (see L<FS::cust_main>).
+
+=cut
+
+sub cust_main {
+  my $self = shift;
+  qsearchs( 'cust_main', { 'custnum' => $self->custnum } );
+}
+
+
 =back
 
 =head1 VERSION
 
-$Id: cust_pay.pm,v 1.21 2002-06-04 14:35:52 ivan Exp $
+$Id: cust_pay.pm,v 1.26 2003-09-10 10:54:46 ivan Exp $
 
 =head1 BUGS
 
index c4427c3..8059f1c 100644 (file)
@@ -2,7 +2,7 @@ package FS::cust_pay_batch;
 
 use strict;
 use vars qw( @ISA );
-use FS::Record;
+use FS::Record qw(dbh qsearchs);
 use Business::CreditCard;
 
 @ISA = qw( FS::Record );
@@ -185,14 +185,202 @@ sub check {
 
   #check invnum, custnum, ?
 
-  ''; #no error
+  $self->SUPER::check;
+}
+
+=item cust_main
+
+Returns the customer (see L<FS::cust_main>) for this batched credit card
+payment.
+
+=cut
+
+sub cust_main {
+  my $self = shift;
+  qsearchs( 'cust_main', { 'custnum' => $self->custnum } );
 }
 
 =back
 
-=head1 VERSION
+=head1 SUBROUTINES
+
+=over 4
+
+=item import_results
+
+=cut
+
+sub import_results {
+  use Time::Local;
+  use FS::cust_pay;
+  eval "use Text::CSV_XS;";
+  die $@ if $@;
+#
+  my $param = shift;
+  my $fh = $param->{'filehandle'};
+  my $format = $param->{'format'};
+  my $paybatch = $param->{'paybatch'};
+
+  my @fields;
+  my $end_condition;
+  my $end_hook;
+  my $hook;
+  my $approved_condition;
+  my $declined_condition;
+
+  if ( $format eq 'csv-td_canada_trust-merchant_pc_batch' ) {
+
+    @fields = (
+      'paybatchnum', # Reference#:  Invoice number of the transaction
+      'paid',        # Amount:  Amount of the transaction.  Dollars and cents
+                     #          with no decimal entered.
+      '',            # Card Type:  0 - MCrd, 1 - Visa, 2 - AMEX, 3 - Discover,
+                     #             4 - Insignia, 5 - Diners/EnRoute, 6 - JCB
+      '_date',       # Transaction Date:  Date the Transaction was processed
+      'time',        # Transaction Time:  Time the transaction was processed
+      'payinfo',     # Card Number:  Card number for the transaction
+      '',            # Expiry Date:  Expiry date of the card
+      '',            # Auth#:  Authorization number entered for force post
+                     #         transaction
+      'type',        # Transaction Type:  0 - purchase, 40 - refund,
+                     #                    20 - force post
+      'result',      # Processing Result: 3 - Approval,
+                     #                    4 - Declined/Amount over limit,
+                     #                    5 - Invalid/Expired/stolen card,
+                     #                    6 - Comm Error
+      '',            # Terminal ID: Terminal ID used to process the transaction
+    );
+
+    $end_condition = sub {
+      my $hash = shift;
+      $hash->{'type'} eq '0BC';
+    };
+
+    $end_hook = sub {
+      my( $hash, $total) = @_;
+      $total = sprintf("%.2f", $total);
+      my $batch_total = sprintf("%.2f", $hash->{'paybatchnum'} / 100 );
+      return "Our total $total does not match bank total $batch_total!"
+        if $total != $batch_total;
+      '';
+    };
+
+    $hook = sub {
+      my $hash = shift;
+      $hash->{'paid'} = sprintf("%.2f", $hash->{'paid'} / 100 );
+      $hash->{'_date'} = timelocal( substr($hash->{'time'},  4, 2),
+                                    substr($hash->{'time'},  2, 2),
+                                    substr($hash->{'time'},  0, 2),
+                                    substr($hash->{'_date'}, 6, 2),
+                                    substr($hash->{'_date'}, 4, 2)-1,
+                                    substr($hash->{'_date'}, 0, 4)-1900, );
+    };
+
+    $approved_condition = sub {
+      my $hash = shift;
+      $hash->{'type'} eq '0' && $hash->{'result'} == 3;
+    };
+
+    $declined_condition = sub {
+      my $hash = shift;
+      $hash->{'type'} eq '0' && (    $hash->{'result'} == 4
+                                  || $hash->{'result'} == 5 );
+    };
+
+
+  } else {
+    return "Unknown format $format";
+  }
+
+  my $csv = new Text::CSV_XS;
+
+  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 $total = 0;
+  my $line;
+  while ( defined($line=<$fh>) ) {
+
+    next if $line =~ /^\s*$/; #skip blank lines
 
-$Id: cust_pay_batch.pm,v 1.6 2002-02-22 23:08:11 ivan Exp $
+    $csv->parse($line) or do {
+      $dbh->rollback if $oldAutoCommit;
+      return "can't parse: ". $csv->error_input();
+    };
+
+    my @values = $csv->fields();
+    my %hash;
+    foreach my $field ( @fields ) {
+      my $value = shift @values;
+      next unless $field;
+      $hash{$field} = $value;
+    }
+
+    if ( &{$end_condition}(\%hash) ) {
+      my $error = &{$end_hook}(\%hash, $total);
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return $error;
+      }
+      last;
+    }
+
+    my $cust_pay_batch =
+      qsearchs('cust_pay_batch', { 'paybatchnum' => $hash{'paybatchnum'} } );
+    unless ( $cust_pay_batch ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "unknown paybatchnum $hash{'paybatchnum'}\n";
+    }
+    my $custnum = $cust_pay_batch->custnum,
+
+    my $error = $cust_pay_batch->delete;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "error removing paybatchnum $hash{'paybatchnum'}: $error\n";
+    }
+
+    &{$hook}(\%hash);
+
+    if ( &{$approved_condition}(\%hash) ) {
+
+      my $cust_pay = new FS::cust_pay ( {
+        'custnum'  => $custnum,
+        'payby'    => 'CARD',
+        'paybatch' => $paybatch,
+        map { $_ => $hash{$_} } (qw( paid _date payinfo )),
+      } );
+      $error = $cust_pay->insert;
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return "error adding payment paybatchnum $hash{'paybatchnum'}: $error\n";
+      }
+      $total += $hash{'paid'};
+  
+      $cust_pay->cust_main->apply_payments;
+
+    } elsif ( &{$declined_condition}(\%hash) ) {
+
+      #this should be configurable... if anybody else ever uses batches
+      $cust_pay_batch->cust_main->suspend;
+
+    }
+
+  }
+  
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
+
+}
+
+=back
 
 =head1 BUGS
 
index 8b65ac4..c218211 100644 (file)
@@ -1,26 +1,34 @@
 package FS::cust_pkg;
 
 use strict;
-use vars qw(@ISA);
+use vars qw(@ISA $disable_agentcheck $DEBUG);
 use FS::UID qw( getotaker dbh );
 use FS::Record qw( qsearch qsearchs );
+use FS::Misc qw( send_email );
 use FS::cust_svc;
 use FS::part_pkg;
 use FS::cust_main;
 use FS::type_pkgs;
 use FS::pkg_svc;
+use FS::cust_bill_pkg;
 
 # need to 'use' these instead of 'require' in sub { cancel, suspend, unsuspend,
 # setup }
 # because they load configuraion by setting FS::UID::callback (see TODO)
 use FS::svc_acct;
-use FS::svc_acct_sm;
 use FS::svc_domain;
 use FS::svc_www;
 use FS::svc_forward;
 
+# for sending cancel emails in sub cancel
+use FS::Conf;
+
 @ISA = qw( FS::Record );
 
+$DEBUG = 0;
+
+$disable_agentcheck = 0;
+
 sub _cache {
   my $self = shift;
   my ( $hashref, $cache ) = @_;
@@ -91,7 +99,9 @@ inherits from FS::Record.  The following fields are currently supported:
 
 =item setup - date
 
-=item bill - date
+=item bill - date (next bill date)
+
+=item last_bill - last bill date
 
 =item susp - date
 
@@ -140,12 +150,15 @@ sub insert {
   return $error if $error;
 
   my $cust_main = $self->cust_main;
-  return "Unknown customer ". $self->custnum unless $cust_main;
-
-  my $agent = qsearchs( 'agent', { 'agentnum' => $cust_main->agentnum } );
-  my $pkgpart_href = $agent->pkgpart_hashref;
-  return "agent ". $agent->agentnum. " can't purchase pkgpart ". $self->pkgpart
-    unless $pkgpart_href->{ $self->pkgpart };
+  return "Unknown custnum: ". $self->custnum unless $cust_main;
+
+  unless ( $disable_agentcheck ) {
+    my $agent = qsearchs( 'agent', { 'agentnum' => $cust_main->agentnum } );
+    my $pkgpart_href = $agent->pkgpart_hashref;
+    return "agent ". $agent->agentnum.
+           " can't purchase pkgpart ". $self->pkgpart
+      unless $pkgpart_href->{ $self->pkgpart };
+  }
 
   $self->SUPER::insert;
 
@@ -229,29 +242,35 @@ sub check {
     unless qsearchs( 'part_pkg', { 'pkgpart' => $self->pkgpart } );
 
   $self->otaker(getotaker) unless $self->otaker;
-  $self->otaker =~ /^(\w{0,16})$/ or return "Illegal otaker";
+  $self->otaker =~ /^([\w\.\-]{0,16})$/ or return "Illegal otaker";
   $self->otaker($1);
 
   if ( $self->dbdef_table->column('manual_flag') ) {
-    $self->manual_flag =~ /^([01]?)$/ or return "Illegal manual_flag";
+    $self->manual_flag('') if $self->manual_flag eq ' ';
+    $self->manual_flag =~ /^([01]?)$/
+      or return "Illegal manual_flag ". $self->manual_flag;
     $self->manual_flag($1);
   }
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
-=item cancel
+=item cancel [ OPTION => VALUE ... ]
 
 Cancels and removes all services (see L<FS::cust_svc> and L<FS::part_svc>)
 in this package, then cancels the package itself (sets the cancel field to
 now).
 
+Available options are: I<quiet>
+
+I<quiet> can be set true to supress email cancellation notices.
+
 If there is an error, returns the error, otherwise returns false.
 
 =cut
 
 sub cancel {
-  my $self = shift;
+  my( $self, %options ) = @_;
   my $error;
 
   local $SIG{HUP} = 'IGNORE';
@@ -290,7 +309,21 @@ sub cancel {
 
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
 
+  my $conf = new FS::Conf;
+  my @invoicing_list = grep { $_ ne 'POST' } $self->cust_main->invoicing_list;
+  if ( !$options{'quiet'} && $conf->exists('emailcancel') && @invoicing_list ) {
+    my $conf = new FS::Conf;
+    my $error = send_email(
+      'from'    => $conf->config('invoice_from'),
+      'to'      => \@invoicing_list,
+      'subject' => $conf->config('cancelsubject'),
+      'body'    => [ map "$_\n", $conf->config('cancelmessage') ],
+    );
+    #should this do something on errors?
+  }
+
   ''; #no errors
+
 }
 
 =item suspend
@@ -419,6 +452,24 @@ sub unsuspend {
   ''; #no errors
 }
 
+=item last_bill
+
+Returns the last bill date, or if there is no last bill date, the setup date.
+Useful for billing metered services.
+
+=cut
+
+sub last_bill {
+  my $self = shift;
+  if ( $self->dbdef_table->column('last_bill') ) {
+    return $self->setfield('last_bill', $_[0]) if @_;
+    return $self->getfield('last_bill') if $self->getfield('last_bill');
+  }    
+  my $cust_bill_pkg = qsearchs('cust_bill_pkg', { 'pkgnum' => $self->pkgnum,
+                                                  'edate'  => $self->bill,  } );
+  $cust_bill_pkg ? $cust_bill_pkg->sdate : $self->setup || 0;
+}
+
 =item part_pkg
 
 Returns the definition for this billing item, as an FS::part_pkg object (see
@@ -476,7 +527,7 @@ sub cust_main {
 =item seconds_since TIMESTAMP
 
 Returns the number of seconds all accounts (see L<FS::svc_acct>) in this
-package have been online since TIMESTAMP.
+package have been online since TIMESTAMP, according to the session monitor.
 
 TIMESTAMP is specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see
 L<Time::Local> and L<Date::Parse> for conversion functions.
@@ -497,6 +548,160 @@ sub seconds_since {
 
 }
 
+=item seconds_since_sqlradacct TIMESTAMP_START TIMESTAMP_END
+
+Returns the numbers of seconds all accounts (see L<FS::svc_acct>) in this
+package have been online between TIMESTAMP_START (inclusive) and TIMESTAMP_END
+(exclusive).
+
+TIMESTAMP_START and TIMESTAMP_END are specified as UNIX timestamps; see
+L<perlfunc/"time">.  Also see L<Time::Local> and L<Date::Parse> for conversion
+functions.
+
+
+=cut
+
+sub seconds_since_sqlradacct {
+  my($self, $start, $end) = @_;
+
+  my $seconds = 0;
+
+  foreach my $cust_svc (
+    grep {
+      my $part_svc = $_->part_svc;
+      $part_svc->svcdb eq 'svc_acct'
+        && scalar($part_svc->part_export('sqlradius'));
+    } $self->cust_svc
+  ) {
+    $seconds += $cust_svc->seconds_since_sqlradacct($start, $end);
+  }
+
+  $seconds;
+
+}
+
+=item attribute_since_sqlradacct TIMESTAMP_START TIMESTAMP_END ATTRIBUTE
+
+Returns the sum of the given attribute for all accounts (see L<FS::svc_acct>)
+in this package for sessions ending between TIMESTAMP_START (inclusive) and
+TIMESTAMP_END
+(exclusive).
+
+TIMESTAMP_START and TIMESTAMP_END are specified as UNIX timestamps; see
+L<perlfunc/"time">.  Also see L<Time::Local> and L<Date::Parse> for conversion
+functions.
+
+=cut
+
+sub attribute_since_sqlradacct {
+  my($self, $start, $end, $attrib) = @_;
+
+  my $sum = 0;
+
+  foreach my $cust_svc (
+    grep {
+      my $part_svc = $_->part_svc;
+      $part_svc->svcdb eq 'svc_acct'
+        && scalar($part_svc->part_export('sqlradius'));
+    } $self->cust_svc
+  ) {
+    $sum += $cust_svc->attribute_since_sqlradacct($start, $end, $attrib);
+  }
+
+  $sum;
+
+}
+
+=item transfer DEST_PKGNUM
+
+Transfers as many services as possible from this package to another package.
+The destination package must already exist.  Services are moved only if 
+the destination allows services with the correct I<svcpart> (not svcdb).  
+Any services that can't be moved remain in the original package.
+
+Returns an error, if there is one; otherwise, returns the number of services 
+that couldn't be moved.
+
+=cut
+
+sub transfer {
+  my ($self, $dest_pkgnum) = @_;
+
+  my $remaining = 0;
+  my $dest;
+  my %target;
+  my $pkg_svc;
+
+  if (ref ($dest_pkgnum) eq 'FS::cust_pkg') {
+    $dest = $dest_pkgnum;
+    $dest_pkgnum = $dest->pkgnum;
+  } else {
+    $dest = qsearchs('cust_pkg', { pkgnum => $dest_pkgnum });
+  }
+
+  return ('Package does not exist: '.$dest_pkgnum) unless $dest;
+
+  foreach $pkg_svc (qsearch('pkg_svc', { pkgpart => $dest->pkgpart })) {
+    $target{$pkg_svc->svcpart} = $pkg_svc->quantity;
+  }
+
+  my $cust_svc;
+
+  foreach $cust_svc ($dest->cust_svc) {
+    $target{$cust_svc->svcpart}--;
+  }
+
+  foreach $cust_svc ($self->cust_svc) {
+    if($target{$cust_svc->svcpart} > 0) {
+      $target{$cust_svc->svcpart}--;
+      my $new = new FS::cust_svc {
+          svcnum  => $cust_svc->svcnum,
+          svcpart => $cust_svc->svcpart,
+          pkgnum  => $dest_pkgnum };
+      my $error = $new->replace($cust_svc);
+      return $error if $error;
+    } else {
+      $remaining++
+    }
+  }
+  return $remaining;
+}
+
+=item reexport
+
+=cut
+
+sub reexport {
+  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 $cust_svc ( $self->cust_svc ) {
+    #false laziness w/svc_Common::insert
+    my $svc_x = $cust_svc->svc_x;
+    foreach my $part_export ( $cust_svc->part_svc->part_export ) {
+      my $error = $part_export->export_insert($svc_x);
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return $error;
+      }
+    }
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
+
+}
+
 =back
 
 =head1 SUBROUTINES
@@ -523,97 +728,9 @@ newly-created cust_pkg objects.
 =cut
 
 sub order {
-  my($custnum, $pkgparts, $remove_pkgnums, $return_cust_pkg) = @_;
-  $remove_pkgnums = [] unless defined($remove_pkgnums);
-
-  my $oldAutoCommit = $FS::UID::AutoCommit;
-  local $FS::UID::AutoCommit = 0;
-  my $dbh = dbh;
-
-  # generate %part_pkg
-  # $part_pkg{$pkgpart} is true iff $custnum may purchase $pkgpart
-  #
-  my($cust_main)=qsearchs('cust_main',{'custnum'=>$custnum});
-  my($agent)=qsearchs('agent',{'agentnum'=> $cust_main->agentnum });
-  my %part_pkg = %{ $agent->pkgpart_hashref };
-
-  my(%svcnum);
-  # generate %svcnum
-  # for those packages being removed:
-  #@{ $svcnum{$svcpart} } goes from a svcpart to a list of FS::cust_svc objects
-  my($pkgnum);
-  foreach $pkgnum ( @{$remove_pkgnums} ) {
-    foreach my $cust_svc (qsearch('cust_svc',{'pkgnum'=>$pkgnum})) {
-      push @{ $svcnum{$cust_svc->getfield('svcpart')} }, $cust_svc;
-    }
-  }
-  
-  my @cust_svc;
-  #generate @cust_svc
-  # for those packages the customer is purchasing:
-  # @{$pkgparts} is a list of said packages, by pkgpart
-  # @cust_svc is a corresponding list of lists of FS::Record objects
-  foreach my $pkgpart ( @{$pkgparts} ) {
-    unless ( $part_pkg{$pkgpart} ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "Customer not permitted to purchase pkgpart $pkgpart!";
-    }
-    push @cust_svc, [
-      map {
-        ( $svcnum{$_} && @{ $svcnum{$_} } ) ? shift @{ $svcnum{$_} } : ();
-      } map { $_->svcpart }
-          qsearch('pkg_svc', { pkgpart  => $pkgpart,
-                               quantity => { op=>'>', value=>'0', } } )
-    ];
-  }
+  my ($custnum, $pkgparts, $remove_pkgnum, $return_cust_pkg) = @_;
 
-  #special-case until this can be handled better
-  # move services to new svcparts - even if the svcparts don't match (svcdb
-  # needs to...)
-  # looks like they're moved in no particular order, ewwwwwwww
-  # and looks like just one of each svcpart can be moved... o well
-
-  #start with still-leftover services
-  #foreach my $svcpart ( grep { scalar(@{ $svcnum{$_} }) } keys %svcnum ) {
-  foreach my $svcpart ( keys %svcnum ) {
-    next unless @{ $svcnum{$svcpart} };
-
-    my $svcdb = $svcnum{$svcpart}->[0]->part_svc->svcdb;
-
-    #find an empty place to put one
-    my $i = 0;
-    foreach my $pkgpart ( @{$pkgparts} ) {
-      my @pkg_svc =
-        qsearch('pkg_svc', { pkgpart  => $pkgpart,
-                             quantity => { op=>'>', value=>'0', } } );
-      #my @pkg_svc =
-      #  grep { $_->quantity > 0 } qsearch('pkg_svc', { pkgpart=>$pkgpart } );
-      if ( ! @{$cust_svc[$i]} #find an empty place to put them with 
-           && grep { $svcdb eq $_->part_svc->svcdb } #with appropriate svcdb
-                @pkg_svc
-      ) {
-        my $new_svcpart =
-          ( grep { $svcdb eq $_->part_svc->svcdb } @pkg_svc )[0]->svcpart; 
-        my $cust_svc = shift @{$svcnum{$svcpart}};
-        $cust_svc->svcpart($new_svcpart);
-        #warn "changing from $svcpart to $new_svcpart!!!\n";
-        $cust_svc[$i] = [ $cust_svc ];
-      }
-      $i++;
-    }
-
-  }
-  
-  #check for leftover services
-  foreach (keys %svcnum) {
-    next unless @{ $svcnum{$_} };
-    $dbh->rollback if $oldAutoCommit;
-    return "Leftover services, svcpart $_: svcnum ".
-           join(', ', map { $_->svcnum } @{ $svcnum{$_} } );
-  }
-
-  #no leftover services, let's make changes.
+  # Transactionize this whole mess
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE'; 
   local $SIG{QUIT} = 'IGNORE';
@@ -621,66 +738,59 @@ sub order {
   local $SIG{TSTP} = 'IGNORE'; 
   local $SIG{PIPE} = 'IGNORE'; 
 
-  #first cancel old packages
-  foreach my $pkgnum ( @{$remove_pkgnums} ) {
-    my($old) = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
-    unless ( $old ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "Package $pkgnum not found to remove!";
-    }
-    my(%hash) = $old->hash;
-    $hash{'cancel'}=time;   
-    my($new) = new FS::cust_pkg ( \%hash );
-    my($error)=$new->replace($old);
-    if ( $error ) {
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+  my $dbh = dbh;
+
+  my $error;
+  my $cust_main = qsearchs('cust_main', { custnum => $custnum });
+  return "Customer not found: $custnum" unless $cust_main;
+
+  # Create the new packages.
+  my $cust_pkg;
+  foreach (@$pkgparts) {
+    $cust_pkg = new FS::cust_pkg { custnum => $custnum,
+                                   pkgpart => $_ };
+    $error = $cust_pkg->insert;
+    if ($error) {
       $dbh->rollback if $oldAutoCommit;
-      return "Couldn't update package $pkgnum: $error";
+      return $error;
     }
+    push @$return_cust_pkg, $cust_pkg;
   }
-
-  #now add new packages, changing cust_svc records if necessary
-  my $pkgpart;
-  while ($pkgpart=shift @{$pkgparts} ) {
-    my $new = new FS::cust_pkg {
-                                 'custnum' => $custnum,
-                                 'pkgpart' => $pkgpart,
-                               };
-    my $error = $new->insert;
-    if ( $error ) {
+  # $return_cust_pkg now contains refs to all of the newly 
+  # created packages.
+
+  # Transfer services and cancel old packages.
+  foreach my $old_pkgnum (@$remove_pkgnum) {
+    my $old_pkg = qsearchs ('cust_pkg', { pkgnum => $old_pkgnum });
+    foreach my $new_pkg (@$return_cust_pkg) {
+      $error = $old_pkg->transfer($new_pkg);
+      if ($error and $error == 0) {
+        # $old_pkg->transfer failed.
+       $dbh->rollback if $oldAutoCommit;
+       return $error;
+      }
+    }
+    if ($error > 0) {
+      # Transfers were successful, but we went through all of the 
+      # new packages and still had services left on the old package.
+      # We can't cancel the package under the circumstances, so abort.
       $dbh->rollback if $oldAutoCommit;
-      return "Couldn't insert new cust_pkg record: $error";
+      return "Unable to transfer all services from package ".$old_pkg->pkgnum;
     }
-    push @{$return_cust_pkg}, $new if $return_cust_pkg;
-    my $pkgnum = $new->pkgnum;
-    foreach my $cust_svc ( @{ shift @cust_svc } ) {
-      my(%hash) = $cust_svc->hash;
-      $hash{'pkgnum'}=$pkgnum;
-      my $new = new FS::cust_svc ( \%hash );
-
-      #avoid Record diffing missing changed svcpart field from above.
-      my $old = qsearchs('cust_svc', { 'svcnum' => $cust_svc->svcnum } );
-
-      my $error = $new->replace($old);
-      if ( $error ) {
-        $dbh->rollback if $oldAutoCommit;
-        return "Couldn't link old service to new package: $error";
-      }
+    $error = $old_pkg->cancel;
+    if ($error) {
+      $dbh->rollback;
+      return $error;
     }
-  }  
-
+  }
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
-
-  ''; #no errors
+  '';
 }
 
 =back
 
-=head1 VERSION
-
-$Id: cust_pkg.pm,v 1.22 2002-05-22 12:17:06 ivan Exp $
-
 =head1 BUGS
 
 sub order is not OO.  Perhaps it should be moved to FS::cust_main and made so?
@@ -690,11 +800,12 @@ In sub order, the @pkgparts array (passed by reference) is clobbered.
 Also in sub order, no money is adjusted.  Once FS::part_pkg defines a standard
 method to pass dates to the recur_prog expression, it should do so.
 
-FS::svc_acct, FS::svc_acct_sm, and FS::svc_domain are loaded via 'use' at 
-compile time, rather than via 'require' in sub { setup, suspend, unsuspend,
-cancel } because they use %FS::UID::callback to load configuration values.
-Probably need a subroutine which decides what to do based on whether or not
-we've fetched the user yet, rather than a hash.  See FS::UID and the TODO.
+FS::svc_acct, FS::svc_domain, FS::svc_www, FS::svc_ip and FS::svc_forward are
+loaded via 'use' at compile time, rather than via 'require' in sub { setup,
+suspend, unsuspend, cancel } because they use %FS::UID::callback to load
+configuration values.  Probably need a subroutine which decides what to do
+based on whether or not we've fetched the user yet, rather than a hash.  See
+FS::UID and the TODO.
 
 Now that things are transactional should the check in the insert method be
 moved to check ?
index 8fe6876..250bd20 100644 (file)
@@ -47,7 +47,8 @@ inherits from FS::Record.  The following fields are currently supported:
 =item _date - specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see
 L<Time::Local> and L<Date::Parse> for conversion functions.
 
-=item payby - `CARD' (credit cards), `BILL' (billing), or `COMP' (free)
+=item payby - `CARD' (credit cards), `CHEK' (electronic check/ACH),
+`LECB' (Phone bill billing), `BILL' (billing), or `COMP' (free)
 
 =item payinfo - card number, P.O.#, or comp issuer (4-8 lowercase alphanumerics; think username)
 
@@ -234,7 +235,7 @@ sub check {
     unless $self->crednum 
            || qsearchs( 'cust_main', { 'custnum' => $self->custnum } );
 
-  $self->payby =~ /^(CARD|BILL|COMP)$/ or return "Illegal payby";
+  $self->payby =~ /^(CARD|CHEK|LECB|BILL|COMP)$/ or return "Illegal payby";
   $self->payby($1);
 
   #false laziness with cust_pay::check
@@ -259,14 +260,14 @@ sub check {
 
   $self->otaker(getotaker);
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =back
 
 =head1 VERSION
 
-$Id: cust_refund.pm,v 1.18 2002-02-19 03:22:39 jeff Exp $
+$Id: cust_refund.pm,v 1.21 2003-08-05 00:20:42 khoff Exp $
 
 =head1 BUGS
 
index c7cc4b3..0d8a121 100644 (file)
@@ -1,7 +1,7 @@
 package FS::cust_svc;
 
 use strict;
-use vars qw( @ISA );
+use vars qw( @ISA $ignore_quantity );
 use Carp qw( cluck );
 use FS::Record qw( qsearch qsearchs dbh );
 use FS::cust_pkg;
@@ -9,13 +9,16 @@ use FS::part_pkg;
 use FS::part_svc;
 use FS::pkg_svc;
 use FS::svc_acct;
-use FS::svc_acct_sm;
 use FS::svc_domain;
 use FS::svc_forward;
+use FS::svc_broadband;
 use FS::domain_record;
+use FS::part_export;
 
 @ISA = qw( FS::Record );
 
+$ignore_quantity = 0;
+
 sub _cache {
   my $self = shift;
   my ( $hashref, $cache ) = @_;
@@ -220,6 +223,7 @@ sub check {
     # or new FS::pkg_svc ( { 'pkgpart'  => $cust_pkg->pkgpart,
     #                        'svcpart'  => $self->svcpart,
     #                        'quantity' => 0                   } );
+    my $quantity = $pkg_svc ? $pkg_svc->quantity : 0;
 
     my @cust_svc = qsearch('cust_svc', {
       'pkgnum'  => $self->pkgnum,
@@ -227,10 +231,10 @@ sub check {
     });
     return "Already ". scalar(@cust_svc). " ". $part_svc->svc.
            " services for pkgnum ". $self->pkgnum
-      if scalar(@cust_svc) >= $pkg_svc->quantity;
+      if scalar(@cust_svc) >= $quantity && !$ignore_quantity;
   }
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item part_svc
@@ -276,16 +280,16 @@ sub label {
   my $tag;
   if ( $svcdb eq 'svc_acct' ) {
     $tag = $svc_x->email;
-  } elsif ( $svcdb eq 'svc_acct_sm' ) {
-    my $domuser = $svc_x->domuser eq '*' ? '(anything)' : $svc_x->domuser;
-    my $svc_domain = qsearchs ( 'svc_domain', { 'svcnum' => $svc_x->domsvc } );
-    my $domain = $svc_domain->domain;
-    $tag = "$domuser\@$domain";
   } elsif ( $svcdb eq 'svc_forward' ) {
-    my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $svc_x->srcsvc } );
-    $tag = $svc_acct->email. '->';
+    if ( $svc_x->srcsvc ) {
+      my $svc_acct = $svc_x->srcsvc_acct;
+      $tag = $svc_acct->email;
+    } else {
+      $tag = $svc_x->src;
+    }
+    $tag .= '->';
     if ( $svc_x->dstsvc ) {
-      $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $svc_x->dstsvc } );
+      my $svc_acct = $svc_x->dstsvc_acct;
       $tag .= $svc_acct->email;
     } else {
       $tag .= $svc_x->dst;
@@ -294,7 +298,11 @@ sub label {
     $tag = $svc_x->getfield('domain');
   } elsif ( $svcdb eq 'svc_www' ) {
     my $domain = qsearchs( 'domain_record', { 'recnum' => $svc_x->recnum } );
-    $tag = $domain->reczone;
+    $tag = $domain->zone;
+  } elsif ( $svcdb eq 'svc_broadband' ) {
+    $tag = $svc_x->ip_addr;
+  } elsif ( $svcdb eq 'svc_external' ) {
+    $tag = $svc_x->id. ': '. $svc_x->title;
   } else {
     cluck "warning: asked for label of unsupported svcdb; using svcnum";
     $tag = $svc_x->getfield('svcnum');
@@ -340,11 +348,249 @@ sub seconds_since {
   $sth->fetchrow_arrayref->[0];
 }
 
-=back
+=item seconds_since_sqlradacct TIMESTAMP_START TIMESTAMP_END
+
+See L<FS::svc_acct/seconds_since_sqlradacct>.  Equivalent to
+$cust_svc->svc_x->seconds_since_sqlradacct, but more efficient.  Meaningless
+for records where B<svcdb> is not "svc_acct".
+
+=cut
+
+#note: implementation here, POD in FS::svc_acct
+sub seconds_since_sqlradacct {
+  my($self, $start, $end) = @_;
+
+  my $svc_x = $self->svc_x;
+
+  my @part_export = $self->part_svc->part_export('sqlradius');
+  push @part_export, $self->part_svc->part_export('sqlradius_withdomain');
+  die "no sqlradius or sqlradius_withdomain export configured for this".
+      "service type"
+    unless @part_export;
+    #or return undef;
+
+  my $seconds = 0;
+  foreach my $part_export ( @part_export ) {
+
+    next if $part_export->option('ignore_accounting');
+
+    my $dbh = DBI->connect( map { $part_export->option($_) }
+                            qw(datasrc username password)    )
+      or die "can't connect to sqlradius database: ". $DBI::errstr;
+
+    #select a unix time conversion function based on database type
+    my $str2time;
+    if ( $dbh->{Driver}->{Name} eq 'mysql' ) {
+      $str2time = 'UNIX_TIMESTAMP(';
+    } elsif ( $dbh->{Driver}->{Name} eq 'Pg' ) {
+      $str2time = 'EXTRACT( EPOCH FROM ';
+    } else {
+      warn "warning: unknown database type ". $dbh->{Driver}->{Name}.
+           "; guessing how to convert to UNIX timestamps";
+      $str2time = 'extract(epoch from ';
+    }
+
+    my $username;
+    if ( $part_export->exporttype eq 'sqlradius' ) {
+      $username = $svc_x->username;
+    } elsif ( $part_export->exporttype eq 'sqlradius_withdomain' ) {
+      $username = $svc_x->email;
+    } else {
+      die 'unknown exporttype '. $part_export->exporttype;
+    }
+
+    my $query;
+  
+    #find closed sessions completely within the given range
+    my $sth = $dbh->prepare("SELECT SUM(acctsessiontime)
+                               FROM radacct
+                               WHERE UserName = ?
+                                 AND $str2time AcctStartTime) >= ?
+                                 AND $str2time AcctStopTime ) <  ?
+                                 AND $str2time AcctStopTime ) > 0
+                                 AND AcctStopTime IS NOT NULL"
+    ) or die $dbh->errstr;
+    $sth->execute($username, $start, $end) or die $sth->errstr;
+    my $regular = $sth->fetchrow_arrayref->[0];
+  
+    #find open sessions which start in the range, count session start->range end
+    $query = "SELECT SUM( ? - $str2time AcctStartTime ) )
+                FROM radacct
+                WHERE UserName = ?
+                  AND $str2time AcctStartTime ) >= ?
+                  AND $str2time AcctStartTime ) <  ?
+                  AND ( ? - $str2time AcctStartTime ) ) < 86400
+                  AND (    $str2time AcctStopTime ) = 0
+                                    OR AcctStopTime IS NULL )";
+    $sth = $dbh->prepare($query) or die $dbh->errstr;
+    $sth->execute($end, $username, $start, $end, $end)
+      or die $sth->errstr. " executing query $query";
+    my $start_during = $sth->fetchrow_arrayref->[0];
+  
+    #find closed sessions which start before the range but stop during,
+    #count range start->session end
+    $sth = $dbh->prepare("SELECT SUM( $str2time AcctStopTime ) - ? ) 
+                            FROM radacct
+                            WHERE UserName = ?
+                              AND $str2time AcctStartTime ) < ?
+                              AND $str2time AcctStopTime  ) >= ?
+                              AND $str2time AcctStopTime  ) <  ?
+                              AND $str2time AcctStopTime ) > 0
+                              AND AcctStopTime IS NOT NULL"
+    ) or die $dbh->errstr;
+    $sth->execute($start, $username, $start, $start, $end ) or die $sth->errstr;
+    my $end_during = $sth->fetchrow_arrayref->[0];
+  
+    #find closed (not anymore - or open) sessions which start before the range
+    # but stop after, or are still open, count range start->range end
+    # don't count open sessions (probably missing stop record)
+    $sth = $dbh->prepare("SELECT COUNT(*)
+                            FROM radacct
+                            WHERE UserName = ?
+                              AND $str2time AcctStartTime ) < ?
+                              AND ( $str2time AcctStopTime ) >= ?
+                                                                  )"
+                              #      OR AcctStopTime =  0
+                              #      OR AcctStopTime IS NULL       )"
+    ) or die $dbh->errstr;
+    $sth->execute($username, $start, $end ) or die $sth->errstr;
+    my $entire_range = ($end-$start) * $sth->fetchrow_arrayref->[0];
+
+    $seconds += $regular + $end_during + $start_during + $entire_range;
+
+  }
+
+  $seconds;
+
+}
+
+=item attribute_since_sqlradacct TIMESTAMP_START TIMESTAMP_END ATTRIBUTE
+
+See L<FS::svc_acct/attribute_since_sqlradacct>.  Equivalent to
+$cust_svc->svc_x->attribute_since_sqlradacct, but more efficient.  Meaningless
+for records where B<svcdb> is not "svc_acct".
+
+=cut
+
+#note: implementation here, POD in FS::svc_acct
+#(false laziness w/seconds_since_sqlradacct above)
+sub attribute_since_sqlradacct {
+  my($self, $start, $end, $attrib) = @_;
 
-=head1 VERSION
+  my $svc_x = $self->svc_x;
 
-$Id: cust_svc.pm,v 1.15 2002-05-22 12:17:06 ivan Exp $
+  my @part_export = $self->part_svc->part_export('sqlradius');
+  push @part_export, $self->part_svc->part_export('sqlradius_withdomain');
+  die "no sqlradius or sqlradius_withdomain export configured for this".
+      "service type"
+    unless @part_export;
+    #or return undef;
+
+  my $sum = 0;
+
+  foreach my $part_export ( @part_export ) {
+
+    next if $part_export->option('ignore_accounting');
+
+    my $dbh = DBI->connect( map { $part_export->option($_) }
+                            qw(datasrc username password)    )
+      or die "can't connect to sqlradius database: ". $DBI::errstr;
+
+    #select a unix time conversion function based on database type
+    my $str2time;
+    if ( $dbh->{Driver}->{Name} eq 'mysql' ) {
+      $str2time = 'UNIX_TIMESTAMP(';
+    } elsif ( $dbh->{Driver}->{Name} eq 'Pg' ) {
+      $str2time = 'EXTRACT( EPOCH FROM ';
+    } else {
+      warn "warning: unknown database type ". $dbh->{Driver}->{Name}.
+           "; guessing how to convert to UNIX timestamps";
+      $str2time = 'extract(epoch from ';
+    }
+
+    my $username;
+    if ( $part_export->exporttype eq 'sqlradius' ) {
+      $username = $svc_x->username;
+    } elsif ( $part_export->exporttype eq 'sqlradius_withdomain' ) {
+      $username = $svc_x->email;
+    } else {
+      die 'unknown exporttype '. $part_export->exporttype;
+    }
+
+    my $sth = $dbh->prepare("SELECT SUM($attrib)
+                               FROM radacct
+                               WHERE UserName = ?
+                                 AND $str2time AcctStopTime ) >= ?
+                                 AND $str2time AcctStopTime ) <  ?
+                                 AND AcctStopTime IS NOT NULL"
+    ) or die $dbh->errstr;
+    $sth->execute($username, $start, $end) or die $sth->errstr;
+
+    $sum += $sth->fetchrow_arrayref->[0];
+
+  }
+
+  $sum;
+
+}
+
+=item get_session_history_sqlradacct TIMESTAMP_START TIMESTAMP_END
+
+See L<FS::svc_acct/get_session_history_sqlradacct>.  Equivalent to
+$cust_svc->svc_x->get_session_history_sqlradacct, but more efficient.
+Meaningless for records where B<svcdb> is not "svc_acct".
+
+=cut
+
+sub get_session_history {
+  my($self, $start, $end, $attrib) = @_;
+
+  my $username = $self->svc_x->username;
+
+  my @part_export = $self->part_svc->part_export('sqlradius')
+    or die "no sqlradius export configured for this service type";
+    #or return undef;
+                     
+  my @sessions = ();
+
+  foreach my $part_export ( @part_export ) {
+                                            
+    my $dbh = DBI->connect( map { $part_export->option($_) }
+                            qw(datasrc username password)    )
+      or die "can't connect to sqlradius database: ". $DBI::errstr;
+
+    #select a unix time conversion function based on database type
+    my $str2time;                                                 
+    if ( $dbh->{Driver}->{Name} eq 'mysql' ) {
+      $str2time = 'UNIX_TIMESTAMP(';          
+    } elsif ( $dbh->{Driver}->{Name} eq 'Pg' ) {
+      $str2time = 'EXTRACT( EPOCH FROM ';       
+    } else {
+      warn "warning: unknown database type ". $dbh->{Driver}->{Name}.
+           "; guessing how to convert to UNIX timestamps";
+      $str2time = 'extract(epoch from ';                  
+    }
+
+    my @fields = qw( acctstarttime acctstoptime acctsessiontime
+                     acctinputoctets acctoutputoctets framedipaddress );
+     
+    my $sth = $dbh->prepare('SELECT '. join(', ', @fields).
+                            "  FROM radacct
+                               WHERE UserName = ?
+                                 AND $str2time AcctStopTime ) >= ?
+                                 AND $str2time AcctStopTime ) <=  ?
+                                 ORDER BY AcctStartTime DESC
+    ") or die $dbh->errstr;                                 
+    $sth->execute($username, $start, $end) or die $sth->errstr;
+
+    push @sessions, map { { %$_ } } @{ $sth->fetchall_arrayref({}) };
+
+  }
+  \@sessions
+
+}
+
+=back
 
 =head1 BUGS
 
@@ -356,6 +602,9 @@ pkg_svc records are not checked in general (here).
 Deleting this record doesn't check or delete the svc_* record associated
 with this record.
 
+In seconds_since_sqlradacct, specifying a DATASRC/USERNAME/PASSWORD instead of
+a DBI database handle is not yet implemented.
+
 =head1 SEE ALSO
 
 L<FS::Record>, L<FS::cust_pkg>, L<FS::part_svc>, L<FS::pkg_svc>, 
index ab873c0..da0de00 100644 (file)
@@ -111,6 +111,7 @@ sub check {
     || $self->ut_number('year') #check better
     || $self->ut_number('month') #check better
     || $self->ut_money('amount')
+    || $self->SUPER::check
   ;
 }
 
index 37cc6c9..ea0c48d 100644 (file)
@@ -241,7 +241,7 @@ sub check {
   if ( $self->rectype eq 'SOA' ) {
     my $recdata = $self->recdata;
     $recdata =~ s/\s+/ /g;
-    $recdata =~ /^([a-z0-9\.\-]+ [\w\-\+]+\.[a-z0-9\.\-]+ \( (\d+ ){5}\))$/i
+    $recdata =~ /^([a-z0-9\.\-]+ [\w\-\+]+\.[a-z0-9\.\-]+ \( ((\d+|((\d+[WDHMS])+)) ){5}\))$/i
       or return "Illegal data for SOA record: $recdata";
     $self->recdata($1);
   } elsif ( $self->rectype eq 'NS' ) {
@@ -261,7 +261,7 @@ sub check {
       or return "Illegal data for PTR record: ". $self->recdata;
     $self->recdata($1);
   } elsif ( $self->rectype eq 'CNAME' ) {
-    $self->recdata =~ /^([a-z0-9\.\-]+)$/i
+    $self->recdata =~ /^([a-z0-9\.\-]+|\@)$/i
       or return "Illegal data for CNAME record: ". $self->recdata;
     $self->recdata($1);
   } elsif ( $self->rectype eq '_mstr' ) {
@@ -271,7 +271,7 @@ sub check {
     die "ack!";
   }
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item increment_serial
@@ -309,11 +309,30 @@ sub svc_domain {
   qsearchs('svc_domain', { svcnum => $self->svcnum } );
 }
 
+=item zone
+
+Returns the canonical zone name.
+
+=cut
+
+sub zone {
+  my $self = shift;
+  my $zone = $self->reczone; # or die ?
+  if ( $zone =~ /\.$/ ) {
+    $zone =~ s/\.$//;
+  } else {
+    my $svc_domain = $self->svc_domain; # or die ?
+    $zone .= '.'. $svc_domain->domain;
+    $zone =~ s/^\@\.//;
+  }
+  $zone;
+}
+
 =back
 
 =head1 VERSION
 
-$Id: domain_record.pm,v 1.11 2002-06-23 19:16:45 ivan Exp $
+$Id: domain_record.pm,v 1.16 2003-08-05 00:20:43 khoff Exp $
 
 =head1 BUGS
 
index da9ac69..c104e45 100644 (file)
@@ -105,6 +105,7 @@ sub check {
     || $self->ut_foreign_key('exportnum', 'part_export', 'exportnum')
     || $self->ut_number('svcpart')
     || $self->ut_foreign_key('svcpart', 'part_svc', 'svcpart')
+    || $self->SUPER::check
   ;
 }
 
index fa10d34..855b8b2 100644 (file)
@@ -113,7 +113,7 @@ sub check {
   $self->locale =~ /^([\w\@]+)$/ or return "illegal locale: ". $self->locale;
   $self->locale($1);
 
-  ''; #no error
+  $self->SUPER::check
 }
 
 =back
index 58c6827..2d17df8 100644 (file)
@@ -114,7 +114,9 @@ sub check {
     || $self->ut_text('nas')
     || $self->ut_ip('nasip')
     || $self->ut_domain('nasfqdn')
-    || $self->ut_numbern('last');
+    || $self->ut_numbern('last')
+    || $self->SUPER::check
+    ;
 }
 
 =item heartbeat TIMESTAMP
@@ -136,7 +138,7 @@ sub heartbeat {
 
 =head1 VERSION
 
-$Id: nas.pm,v 1.6 2002-03-04 12:48:49 ivan Exp $
+$Id: nas.pm,v 1.7 2003-08-05 00:20:43 khoff Exp $
 
 =head1 BUGS
 
index a31b09b..86f9294 100644 (file)
@@ -37,7 +37,7 @@ FS::Record.  The following fields are currently supported:
 
 =item eventpart - primary key
 
-=item payby - CARD, BILL, or COMP
+=item payby - CARD, DCRD, CHEK, DCHK, LECB, BILL, or COMP
 
 =item event - event name
 
@@ -124,7 +124,7 @@ sub check {
 
     $c =~ /^\s*\$cust_main\->(suspend|cancel|invoicing_list_addpost|bill|collect)\(\);\s*("";)?\s*$/
 
-      or $c =~ /^\s*\$cust_bill\->(comp|realtime_card|realtime_card_cybercash|batch_card|send)\(\);\s*$/
+      or $c =~ /^\s*\$cust_bill\->(comp|realtime_(card|ach|lec)|realtime_card_cybercash|batch_card|send)\(\);\s*$/
 
       or $c =~ /^\s*\$cust_bill\->send\(\'\w+\'\);\s*$/
 
@@ -140,7 +140,7 @@ sub check {
   }
 
   my $error = $self->ut_numbern('eventpart')
-    || $self->ut_enum('payby', [qw( CARD BILL COMP )] )
+    || $self->ut_enum('payby', [qw( CARD DCRD CHEK DCHK LECB BILL COMP )] )
     || $self->ut_text('event')
     || $self->ut_anything('eventcode')
     || $self->ut_number('seconds')
@@ -160,10 +160,15 @@ sub check {
           join("\n", $conf->config('invoice_template') )
       );
     }
+    unless ( $conf->exists("invoice_latex_$name") ) {
+      $conf->set(
+        "invoice_latex_$name" =>
+          join("\n", $conf->config('invoice_latex') )
+      );
+    }
   }
 
-  '';
-
+  $self->SUPER::check;
 }
 
 =back
index 4f45fbe..8423da2 100644 (file)
@@ -274,12 +274,6 @@ sub check {
   ;
   return $error if $error;
 
-  warn $self->machine. "!!!\n";
-
-  $self->machine =~ /^([\w\-\.]*)$/
-    or return "Illegal machine: ". $self->machine;
-  $self->machine($1);
-
   $self->nodomain =~ /^(Y?)$/ or return "Illegal nodomain: ". $self->nodomain;
   $self->nodomain($1);
 
@@ -287,7 +281,7 @@ sub check {
 
   #check exporttype?
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 #=item part_svc
@@ -307,6 +301,30 @@ sub part_svc {
   #confess "FS::part_export::part_svc deprecated";
 }
 
+=item svc_x
+
+Returns a list of associated FS::svc_* records.
+
+=cut
+
+sub svc_x {
+  my $self = shift;
+  map { $_->svc_x } $self->cust_svc;
+}
+
+=item cust_svc
+
+Returns a list of associated FS::cust_svc records.
+
+=cut
+
+sub cust_svc {
+  my $self = shift;
+  map { qsearch('cust_svc', { 'svcpart' => $_->svcpart } ) }
+    grep { qsearch('cust_svc', { 'svcpart' => $_->svcpart } ) }
+      $self->export_svc;
+}
+
 =item export_svc
 
 Returns a list of associated FS::export_svc records.
@@ -450,18 +468,22 @@ sub _export_delete {
   return "_export_delete: unknown export type ". $self->exporttype;
 }
 
-#fallbacks providing null operations
+#call svcdb-specific fallbacks
 
 sub _export_suspend {
   my $self = shift;
   #warn "warning: _export_suspened unimplemented for". ref($self);
-  '';
+  my $svc_x = shift;
+  my $new = $svc_x->clone_suspended;
+  $self->_export_replace( $new, $svc_x );
 }
 
 sub _export_unsuspend {
   my $self = shift;
   #warn "warning: _export_unsuspend unimplemented for ". ref($self);
-  '';
+  my $svc_x = shift;
+  my $old = $svc_x->clone_kludge_unsuspend;
+  $self->_export_replace( $svc_x, $old );
 }
 
 =back
@@ -526,7 +548,7 @@ tie my %shellcommands_options, 'Tie::IxHash',
   #'machine' => { label=>'Remote machine' },
   'user' => { label=>'Remote username', default=>'root' },
   'useradd' => { label=>'Insert command',
-                 default=>'useradd -d $dir -m -s $shell -u $uid -p $crypt_password $username'
+                 default=>'useradd -c $finger -d $dir -m -s $shell -u $uid -p $crypt_password $username'
                 #default=>'cp -pr /etc/skel $dir; chown -R $uid.$gid $dir'
                },
   'useradd_stdin' => { label=>'Insert command STDIN',
@@ -542,7 +564,7 @@ tie my %shellcommands_options, 'Tie::IxHash',
                        default=>'',
                      },
   'usermod' => { label=>'Modify command',
-                 default=>'usermod -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -p $new_crypt_password $old_username',
+                 default=>'usermod -c $new_finger -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -p $new_crypt_password $old_username',
                 #default=>'[ -d $old_dir ] && mv $old_dir $new_dir || ( '.
                  #  'chmod u+t $old_dir; mkdir $new_dir; cd $old_dir; '.
                  #  'find . -depth -print | cpio -pdm $new_dir; '.
@@ -554,6 +576,21 @@ tie my %shellcommands_options, 'Tie::IxHash',
                        type =>'textarea',
                        default=>'',
                      },
+  'usermod_pwonly' => { label=>'Disallow username changes',
+                        type =>'checkbox',
+                      },
+  'suspend' => { label=>'Suspension command',
+                 default=>'usermod -L $username',
+               },
+  'suspend_stdin' => { label=>'Suspension command STDIN',
+                       default=>'',
+                     },
+  'unsuspend' => { label=>'Unsuspension command',
+                   default=>'usermod -U $username',
+                 },
+  'unsuspend_stdin' => { label=>'Unsuspension command STDIN',
+                         default=>'',
+                       },
 ;
 
 tie my %shellcommands_withdomain_options, 'Tie::IxHash',
@@ -579,10 +616,25 @@ tie my %shellcommands_withdomain_options, 'Tie::IxHash',
                        type =>'textarea',
                        #default=>"$_password\n$_password\n",
                      },
+  'usermod_pwonly' => { label=>'Disallow username changes',
+                        type =>'checkbox',
+                      },
+  'suspend' => { label=>'Suspension command',
+                 default=>'',
+               },
+  'suspend_stdin' => { label=>'Suspension command STDIN',
+                       default=>'',
+                     },
+  'unsuspend' => { label=>'Unsuspension command',
+                   default=>'',
+                 },
+  'unsuspend_stdin' => { label=>'Unsuspension command STDIN',
+                         default=>'',
+                       },
 ;
 
 tie my %www_shellcommands_options, 'Tie::IxHash',
-  'user' => { lable=>'Remote username', default=>'root' },
+  'user' => { label=>'Remote username', default=>'root' },
   'useradd' => { label=>'Insert command',
                  default=>'mkdir /var/www/$zone; chown $username /var/www/$zone; ln -s /var/www/$zone $homedir/$zone',
                },
@@ -594,6 +646,53 @@ tie my %www_shellcommands_options, 'Tie::IxHash',
                 },
 ;
 
+tie my %apache_options, 'Tie::IxHash',
+  'user'       => { label=>'Remote username', default=>'root' },
+  'httpd_conf' => { label=>'httpd.conf snippet location',
+                    default=>'/etc/apache/httpd-freeside.conf', },
+  'template'   => {
+    label   => 'Template',
+    type    => 'textarea',
+    default => <<'END',
+<VirtualHost $domain> #generic
+#<VirtualHost ip.addr> #preferred, http://httpd.apache.org/docs/dns-caveats.html
+DocumentRoot /var/www/$zone
+ServerName $zone
+ServerAlias *.$zone
+#BandWidthModule On
+#LargeFileLimit 4096 12288
+</VirtualHost>
+
+END
+  },
+;
+
+tie my %router_options, 'Tie::IxHash',
+  'protocol' => {
+         label=>'Protocol',
+         type =>'select',
+         options => [qw(telnet ssh)],
+         default => 'telnet'},
+  'insert' => {label=>'Insert command', default=>'' },
+  'delete' => {label=>'Delete command', default=>'' },
+  'replace' => {label=>'Replace command', default=>'' },
+  'Timeout' => {label=>'Time to wait for prompt', default=>'20' },
+  'Prompt' => {label=>'Prompt string', default=>'#' }
+;
+
+tie my %domain_shellcommands_options, 'Tie::IxHash',
+  'user' => { label=>'Remote username', default=>'root' },
+  'useradd' => { label=>'Insert command',
+                 default=>'',
+               },
+  'userdel'  => { label=>'Delete command',
+                  default=>'',
+                },
+  'usermod'  => { label=>'Modify command',
+                  default=>'',
+                },
+;
+
 tie my %textradius_options, 'Tie::IxHash',
   'user' => { label=>'Remote username', default=>'root' },
   'users' => { label=>'users file location', default=>'/etc/raddb/users' },
@@ -603,6 +702,20 @@ tie my %sqlradius_options, 'Tie::IxHash',
   'datasrc'  => { label=>'DBI data source ' },
   'username' => { label=>'Database username' },
   'password' => { label=>'Database password' },
+  'ignore_accounting' => {
+     type => 'checkbox',
+     label=>'Ignore accounting records from this database'
+  },
+;
+
+tie my %sqlradius_withdomain_options, 'Tie::IxHash',
+  'datasrc'  => { label=>'DBI data source ' },
+  'username' => { label=>'Database username' },
+  'password' => { label=>'Database password' },
+  'ignore_accounting' => {
+     type => 'checkbox',
+     label=>'Ignore accounting records from this database'
+  },
 ;
 
 tie my %cyrus_options, 'Tie::IxHash',
@@ -612,7 +725,6 @@ tie my %cyrus_options, 'Tie::IxHash',
 ;
 
 tie my %cp_options, 'Tie::IxHash',
-  'host'      => { label=>'Hostname' },
   'port'      => { label=>'Port number' },
   'username'  => { label=>'Username' },
   'password'  => { label=>'Password' },
@@ -628,25 +740,75 @@ tie my %infostreet_options, 'Tie::IxHash',
 ;
 
 tie my %vpopmail_options, 'Tie::IxHash',
-  'machine' => { label=>'vpopmail machine', },
+  #'machine' => { label=>'vpopmail machine', },
   'dir'     => { label=>'directory', }, # ?more info? default?
   'uid'     => { label=>'vpopmail uid' },
   'gid'     => { label=>'vpopmail gid' },
+  'restart' => { label=> 'vpopmail restart command',
+                 default=> 'cd /home/vpopmail/domains; for domain in *; do /home/vpopmail/bin/vmkpasswd $domain; done; /var/qmail/bin/qmail-newu; killall -HUP qmail-send',
+               },
+;
+
+tie my %communigate_pro_options, 'Tie::IxHash',
+  'port'     => { label=>'Port number', default=>'106', },
+  'login'    => { label=>'The administrator account name.  The name can contain a domain part.', },
+  'password' => { label=>'The administrator account password.', },
+  'accountType' => { label=>'Type for newly-created accounts',
+                     type=>'select',
+                     options=>[qw( MultiMailbox TextMailbox MailDirMailbox )],
+                     default=>'MultiMailbox',
+                   },
+  'externalFlag' => { label=> 'Create accounts with an external (visible for legacy mailers) INBOX.',
+                      type=>'checkbox',
+                    },
+  'AccessModes' => { label=>'Access modes',
+                     default=>'Mail POP IMAP PWD WebMail WebSite',
+                   },
+;
+
+tie my %communigate_pro_singledomain_options, 'Tie::IxHash',
+  'port'     => { label=>'Port number', default=>'106', },
+  'login'    => { label=>'The administrator account name.  The name can contain a domain part.', },
+  'password' => { label=>'The administrator account password.', },
+  'domain'   => { label=>'Domain', },
+  'accountType' => { label=>'Type for newly-created accounts',
+                     type=>'select',
+                     options=>[qw( MultiMailbox TextMailbox MailDirMailbox )],
+                     default=>'MultiMailbox',
+                   },
+  'externalFlag' => { label=> 'Create accounts with an external (visible for legacy mailers) INBOX.',
+                      type=>'checkbox',
+                    },
+  'AccessModes' => { label=>'Access modes',
+                     default=>'Mail POP IMAP PWD WebMail WebSite',
+                   },
 ;
 
 tie my %bind_options, 'Tie::IxHash',
-  #'machine'    => { label=>'named machine' },
-  'named_conf' => { label  => 'named.conf location',
-                    default=> '/etc/bind/named.conf' },
-  'zonepath'   => { label => 'path to zone files',
-                    default=> '/etc/bind/', },
+  #'machine'     => { label=>'named machine' },
+  'named_conf'   => { label  => 'named.conf location',
+                      default=> '/etc/bind/named.conf' },
+  'zonepath'     => { label => 'path to zone files',
+                      default=> '/etc/bind/', },
+  'bind_release' => { label => 'ISC BIND Release',
+                      type  => 'select',
+                      options => [qw(BIND8 BIND9)],
+                      default => 'BIND8' },
+  'bind9_minttl' => { label => 'The minttl required by bind9 and RFC1035.',
+                      default => '1D' },
 ;
 
 tie my %bind_slave_options, 'Tie::IxHash',
-  #'machine'    => { label=> 'Slave machine' },
-  'master'      => { label=> 'Master IP address(s) (semicolon-separated)' },
-  'named_conf'  => { label   => 'named.conf location',
-                     default => '/etc/bind/named.conf' },
+  #'machine'     => { label=> 'Slave machine' },
+  'master'       => { label=> 'Master IP address(s) (semicolon-separated)' },
+  'named_conf'   => { label   => 'named.conf location',
+                      default => '/etc/bind/named.conf' },
+  'bind_release' => { label => 'ISC BIND Release',
+                      type  => 'select',
+                      options => [qw(BIND8 BIND9)],
+                      default => 'BIND8' },
+  'bind9_minttl' => { label => 'The minttl required by bind9 and RFC1035.',
+                      default => '1D' },
 ;
 
 tie my %http_options, 'Tie::IxHash',
@@ -681,11 +843,76 @@ tie my %http_options, 'Tie::IxHash',
 ;
 
 tie my %sqlmail_options, 'Tie::IxHash',
-  'datasrc'  => { label=>'DBI data source' },
-  'username' => { label=>'Database username' },
-  'password' => { label=>'Database password' },
+  'datasrc'            => { label => 'DBI data source' },
+  'username'           => { label => 'Database username' },
+  'password'           => { label => 'Database password' },
+  'server_type'        => {
+    label   => 'Server type',
+    type    => 'select',
+    options => [qw(dovecot_plain dovecot_crypt dovecot_digest_md5 courier_plain
+                   courier_crypt)],
+    default => ['dovecot_plain'], },
+  'svc_acct_table'     => { label => 'User Table', default => 'user_acct' },
+  'svc_forward_table'  => { label => 'Forward Table', default => 'forward' },
+  'svc_domain_table'   => { label => 'Domain Table', default => 'domain' },
+  'svc_acct_fields'    => { label => 'svc_acct Export Fields',
+                            default => 'username _password domsvc svcnum' },
+  'svc_forward_fields' => { label => 'svc_forward Export Fields',
+                            default => 'domain svcnum catchall' },
+  'svc_domain_fields'  => { label => 'svc_domain Export Fields',
+                            default => 'srcsvc dstsvc dst' },
+  'resolve_dstsvc'     => { label => q{Resolve svc_forward.dstsvc to an email address and store it in dst. (Doesn't require that you also export dstsvc.)},
+                            type => 'checkbox' },
+
+;
+
+tie my %ldap_options, 'Tie::IxHash',
+  'dn'         => { label=>'Root DN' },
+  'password'   => { label=>'Root DN password' },
+  'userdn'     => { label=>'User DN' },
+  'attributes' => { label=>'Attributes',
+                    type=>'textarea',
+                    default=>join("\n",
+                      'uid $username',
+                      'mail $username\@$domain',
+                      'uidno $uid',
+                      'gidno $gid',
+                      'cn $first',
+                      'sn $last',
+                      'mailquota $quota',
+                      'vmail',
+                      'location',
+                      'mailtag',
+                      'mailhost',
+                      'mailmessagestore $dir',
+                      'userpassword $crypt_password',
+                      'hint',
+                      'answer $sec_phrase',
+                      'objectclass top,person,inetOrgPerson',
+                    ),
+                  },
+  'radius'     => { label=>'Export RADIUS attributes', type=>'checkbox', },
+;
+
+tie my %forward_shellcommands_options, 'Tie::IxHash',
+  'user' => { label=>'Remote username', default=>'root' },
+  'useradd' => { label=>'Insert command',
+                 default=>'',
+               },
+  'userdel'  => { label=>'Delete command',
+                  default=>'',
+                },
+  'usermod'  => { label=>'Modify command',
+                  default=>'',
+                },
 ;
 
+tie my %postfix_options, 'Tie::IxHash',
+  'user' => { label=>'Remote username', default=>'root' },
+  'aliases' => { label=>'aliases file location', default=>'/etc/aliases' },
+  'virtual' => { label=>'virtual file location', default=>'/etc/postfix/virtual' },
+  'mydomain' => { label=>'local domain', default=>'' },
+;
 
 #export names cannot have dashes...
 %exports = (
@@ -719,26 +946,39 @@ tie my %sqlmail_options, 'Tie::IxHash',
       'desc' => 'Real-time export via remote SSH (i.e. useradd, userdel, etc.)',
       'options' => \%shellcommands_options,
       'nodomain' => 'Y',
-      'notes' => 'Run remote commands via SSH.  Usernames are considered unique (also see shellcommands_withdomain).  You probably want this if the commands you are running will not accept a domain as a parameter.  You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="Linux/NetBSD" onClick=\'this.form.useradd.value = "useradd -c $finger -d $dir -m -s $shell -u $uid -p $crypt_password $username"; this.form.useradd_stdin.value = ""; this.form.userdel.value = "userdel -r $username"; this.form.userdel_stdin.value=""; this.form.usermod.value = "usermod -c $new_finger -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -p $new_crypt_password $old_username"; this.form.usermod_stdin.value = "";\'><LI><INPUT TYPE="button" VALUE="FreeBSD" onClick=\'this.form.useradd.value = "pw useradd $username -d $dir -m -s $shell -u $uid -c $finger -h 0"; this.form.useradd_stdin.value = "$_password\n"; this.form.userdel.value = "pw userdel $username -r"; this.form.userdel_stdin.value=""; this.form.usermod.value = "pw usermod $old_username -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -c $new_finger -h 0"; this.form.usermod_stdin.value = "$new__password\n";\'><LI><INPUT TYPE="button" VALUE="Just maintain directories (use with sysvshell or bsdshell)" onClick=\'this.form.useradd.value = "cp -pr /etc/skel $dir; chown -R $uid.$gid $dir"; this.form.useradd_stdin.value = ""; this.form.usermod.value = "[ -d $old_dir ] && mv $old_dir $new_dir || ( chmod u+t $old_dir; mkdir $new_dir; cd $old_dir; find . -depth -print | cpio -pdm $new_dir; chmod u-t $new_dir; chown -R $uid.$gid $new_dir; rm -rf $old_dir )"; this.form.usermod_stdin.value = ""; this.form.userdel.value = "rm -rf $dir"; this.form.userdel_stdin.value="";\'></UL>',
+      'notes' => 'Run remote commands via SSH.  Usernames are considered unique (also see shellcommands_withdomain).  You probably want this if the commands you are running will not accept a domain as a parameter.  You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="Linux" onClick=\'this.form.useradd.value = "useradd -c $finger -d $dir -m -s $shell -u $uid -p $crypt_password $username"; this.form.useradd_stdin.value = ""; this.form.userdel.value = "userdel -r $username"; this.form.userdel_stdin.value=""; this.form.usermod.value = "usermod -c $new_finger -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -p $new_crypt_password $old_username"; this.form.usermod_stdin.value = ""; this.form.suspend.value = "usermod -L $username"; this.form.suspend_stdin.value=""; this.form.unsuspend.value = "usermod -U $username"; this.form.unsuspend_stdin.value="";\'><LI><INPUT TYPE="button" VALUE="FreeBSD" onClick=\'this.form.useradd.value = "lockf /etc/passwd.lock pw useradd $username -d $dir -m -s $shell -u $uid -g $gid -c $finger -h 0"; this.form.useradd_stdin.value = "$_password\n"; this.form.userdel.value = "lockf /etc/passwd.lock pw userdel $username -r"; this.form.userdel_stdin.value=""; this.form.usermod.value = "lockf /etc/passwd.lock pw usermod $old_username -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -c $new_finger -h 0"; this.form.usermod_stdin.value = "$new__password\n"; this.form.suspend.value = "lockf /etc/passwd.lock pw lock $username"; this.form.suspend_stdin.value=""; this.form.unsuspend.value = "lockf /etc/passwd.lock pw unlock $username"; this.form.unsuspend_stdin.value="";\'> Note: On FreeBSD, due to deficient locking in pw(1), you must disable the chpass(1), chsh(1), chfn(1), passwd(1), and vipw(1) commands, or replace them with wrappers that prepend "lockf /etc/passwd.lock".  Alternatively, apply the patch in <A HREF="http://www.freebsd.org/cgi/query-pr.cgi?pr=23501">FreeBSD PR#23501</A> and remove the "lockf /etc/passwd.lock" from these default commands.<LI><INPUT TYPE="button" VALUE="NetBSD/OpenBSD" onClick=\'this.form.useradd.value = "useradd -c $finger -d $dir -m -s $shell -u $uid -p $crypt_password $username"; this.form.useradd_stdin.value = ""; this.form.userdel.value = "userdel -r $username"; this.form.userdel_stdin.value=""; this.form.usermod.value = "usermod -c $new_finger -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -p $new_crypt_password $old_username"; this.form.usermod_stdin.value = ""; this.form.suspend.value = ""; this.form.suspend_stdin.value=""; this.form.unsuspend.value = ""; this.form.unsuspend_stdin.value="";\'><LI><INPUT TYPE="button" VALUE="Just maintain directories (use with sysvshell or bsdshell)" onClick=\'this.form.useradd.value = "cp -pr /etc/skel $dir; chown -R $uid.$gid $dir"; this.form.useradd_stdin.value = ""; this.form.usermod.value = "[ -d $old_dir ] && mv $old_dir $new_dir || ( chmod u+t $old_dir; mkdir $new_dir; cd $old_dir; find . -depth -print | cpio -pdm $new_dir; chmod u-t $new_dir; chown -R $new_uid.$new_gid $new_dir; rm -rf $old_dir )"; this.form.usermod_stdin.value = ""; this.form.userdel.value = "rm -rf $dir"; this.form.userdel_stdin.value=""; this.form.suspend.value = ""; this.form.suspend_stdin.value=""; this.form.unsuspend.value = ""; this.form.unsuspend_stdin.value="";\'></UL>The following variables are available for interpolation (prefixed with new_ or old_ for replace operations): <UL><LI><code>$username</code><LI><code>$_password</code><LI><code>$quoted_password</code> - unencrypted password quoted for the shell<LI><code>$crypt_password</code> - encrypted password<LI><code>$uid</code><LI><code>$gid</code><LI><code>$finger</code> - GECOS, already quoted for the shell (do not add additional quotes)<LI><code>$dir</code> - home directory<LI><code>$shell</code><LI><code>$quota</code><LI>All other fields in <a href="../docs/schema.html#svc_acct">svc_acct</a> are also available.</UL>',
     },
 
     'shellcommands_withdomain' => {
-      'desc' => 'Real-time export via remote SSH.',
+      'desc' => 'Real-time export via remote SSH (vpopmail, etc.).',
       'options' => \%shellcommands_withdomain_options,
-      'notes' => 'Run remote commands via SSH.  username@domain (rather than just usernames) are considered unique (also see shellcommands).  You probably want this if the commands you are running will accept a domain as a parameter, and will allow the same username with different domains.  You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.',
+      'notes' => 'Run remote commands via SSH.  username@domain (rather than just usernames) are considered unique (also see shellcommands).  You probably want this if the commands you are running will accept a domain as a parameter, and will allow the same username with different domains.  You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="vpopmail" onClick=\'this.form.useradd.value = "/home/vpopmail/bin/vadduser $username\\\@$domain $quoted_password"; this.form.useradd_stdin.value = ""; this.form.userdel.value = "/home/vpopmail/bin/vdeluser $username\\\@$domain"; this.form.userdel_stdin.value=""; this.form.usermod.value = "/home/vpopmail/bin/vpasswd $new_username\\\@$new_domain $new_quoted_password"; this.form.usermod_stdin.value = ""; this.form.usermod_pwonly.checked = true;\'></UL>The following variables are available for interpolation (prefixed with <code>new_</code> or <code>old_</code> for replace operations): <UL><LI><code>$username</code><LI><code>$domain</code><LI><code>$_password</code><LI><code>$quoted_password</code> - unencrypted password quoted for the shell<LI><code>$crypt_password</code> - encrypted password<LI><code>$uid</code><LI><code>$gid</code><LI><code>$finger</code> - GECOS, already quoted for the shell (do not add additional quotes)<LI><code>$dir</code> - home directory<LI><code>$shell</code><LI><code>$quota</code><LI>All other fields in <a href="../docs/schema.html#svc_acct">svc_acct</a> are also available.</UL>',
+    },
+
+    'ldap' => {
+      'desc' => 'Real-time export to LDAP',
+      'options' => \%ldap_options,
+      'notes' => 'Real-time export to arbitrary LDAP attributes.  Requires installation of <a href="http://search.cpan.org/search?dist=Net-LDAP">Net::LDAP</a> from CPAN.',
     },
 
     'sqlradius' => {
-      'desc' => 'Real-time export to SQL-backed RADIUS (ICRADIUS, FreeRADIUS)',
+      'desc' => 'Real-time export to SQL-backed RADIUS (FreeRADIUS, ICRADIUS, Radiator)',
       'options' => \%sqlradius_options,
       'nodomain' => 'Y',
-      'notes' => 'Real-time export of radcheck, radreply and usergroup tables to any SQL database for <a href="http://www.freeradius.org/">FreeRADIUS</a> or <a href="http://radius.innercite.com/">ICRADIUS</a>.  An existing RADIUS database will be updated in realtime, but you can use <a href="../docs/man/bin/freeside-sqlradius-reset">freeside-sqlradius-reset</a> to delete the entire RADIUS database and repopulate the tables from the Freeside database.  See the <a href="http://search.cpan.org/doc/TIMB/DBI-1.23/DBI.pm">DBI documentation</a> and the <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">documentation for your DBD</a> for the exact syntax of a DBI data source.  If using <a href="http://www.freeradius.org/">FreeRADIUS</a> 0.5 or above, make sure your <b>op</b> fields are set to allow NULL values.',
+      'notes' => 'Real-time export of radcheck, radreply and usergroup tables to any SQL database for <a href="http://www.freeradius.org/">FreeRADIUS</a>, <a href="http://radius.innercite.com/">ICRADIUS</a> or <a href="http://www.open.com.au/radiator/">Radiator</a>.  This export does not export RADIUS realms (see also sqlradius_withdomain).  An existing RADIUS database will be updated in realtime, but you can use <a href="../docs/man/bin/freeside-sqlradius-reset">freeside-sqlradius-reset</a> to delete the entire RADIUS database and repopulate the tables from the Freeside database.  See the <a href="http://search.cpan.org/doc/TIMB/DBI/DBI.pm#connect">DBI documentation</a> and the <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">documentation for your DBD</a> for the exact syntax of a DBI data source.<ul><li>Using FreeRADIUS 0.9.0 with the PostgreSQL backend, the db_postgresql.sql schema and postgresql.conf queries contain incompatible changes.  This is fixed in 0.9.1.  Only new installs with 0.9.0 and PostgreSQL are affected - upgrades and other database backends and versions are unaffected.<li>Using ICRADIUS, add a dummy "op" column to your database: <blockquote><code>ALTER&nbsp;TABLE&nbsp;radcheck&nbsp;ADD&nbsp;COLUMN&nbsp;op&nbsp;VARCHAR(2)&nbsp;NOT&nbsp;NULL&nbsp;DEFAULT&nbsp;\'==\'<br>ALTER&nbsp;TABLE&nbsp;radreply&nbsp;ADD&nbsp;COLUMN&nbsp;op&nbsp;VARCHAR(2)&nbsp;NOT&nbsp;NULL&nbsp;DEFAULT&nbsp;\'==\'<br>ALTER&nbsp;TABLE&nbsp;radgroupcheck&nbsp;ADD&nbsp;COLUMN&nbsp;op&nbsp;VARCHAR(2)&nbsp;NOT&nbsp;NULL&nbsp;DEFAULT&nbsp;\'==\'<br>ALTER&nbsp;TABLE&nbsp;radgroupreply&nbsp;ADD&nbsp;COLUMN&nbsp;op&nbsp;VARCHAR(2)&nbsp;NOT&nbsp;NULL&nbsp;DEFAULT&nbsp;\'==\'</code></blockquote><li>Using Radiator, see the <a href="http://www.open.com.au/radiator/faq.html#38">Radiator FAQ</a> for configuration information.</ul>',
+    },
+
+    'sqlradius_withdomain' => {
+      'desc' => 'Real-time export to SQL-backed RADIUS (FreeRADIUS, ICRADIUS, Radiator) with realms',
+      'options' => \%sqlradius_withdomain_options,
+      'nodomain' => '',
+      'notes' => 'Real-time export of radcheck, radreply and usergroup tables to any SQL database for <a href="http://www.freeradius.org/">FreeRADIUS</a>, <a href="http://radius.innercite.com/">ICRADIUS</a> or <a href="http://www.open.com.au/radiator/">Radiator</a>.  This export exports domains to RADIUS realms (see also sqlradius).  An existing RADIUS database will be updated in realtime, but you can use <a href="../docs/man/bin/freeside-sqlradius-reset">freeside-sqlradius-reset</a> to delete the entire RADIUS database and repopulate the tables from the Freeside database.  See the <a href="http://search.cpan.org/doc/TIMB/DBI/DBI.pm#connect">DBI documentation</a> and the <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">documentation for your DBD</a> for the exact syntax of a DBI data source.<ul><li>Using FreeRADIUS 0.9.0 with the PostgreSQL backend, the db_postgresql.sql schema and postgresql.conf queries contain incompatible changes.  This is fixed in 0.9.1.  Only new installs with 0.9.0 and PostgreSQL are affected - upgrades and other database backends and versions are unaffected.<li>Using ICRADIUS, add a dummy "op" column to your database: <blockquote><code>ALTER&nbsp;TABLE&nbsp;radcheck&nbsp;ADD&nbsp;COLUMN&nbsp;op&nbsp;VARCHAR(2)&nbsp;NOT&nbsp;NULL&nbsp;DEFAULT&nbsp;\'==\'<br>ALTER&nbsp;TABLE&nbsp;radreply&nbsp;ADD&nbsp;COLUMN&nbsp;op&nbsp;VARCHAR(2)&nbsp;NOT&nbsp;NULL&nbsp;DEFAULT&nbsp;\'==\'<br>ALTER&nbsp;TABLE&nbsp;radgroupcheck&nbsp;ADD&nbsp;COLUMN&nbsp;op&nbsp;VARCHAR(2)&nbsp;NOT&nbsp;NULL&nbsp;DEFAULT&nbsp;\'==\'<br>ALTER&nbsp;TABLE&nbsp;radgroupreply&nbsp;ADD&nbsp;COLUMN&nbsp;op&nbsp;VARCHAR(2)&nbsp;NOT&nbsp;NULL&nbsp;DEFAULT&nbsp;\'==\'</code></blockquote><li>Using Radiator, see the <a href="http://www.open.com.au/radiator/faq.html#38">Radiator FAQ</a> for configuration information.</ul>',
     },
 
     'sqlmail' => {
       'desc' => 'Real-time export to SQL-backed mail server',
       'options' => \%sqlmail_options,
-      'nodomain' => 'Y',
+      'nodomain' => '',
       'notes' => 'Database schema can be made to work with Courier IMAP and Exim.  Others could work but are untested. (...extended description from pc-intouch?...)',
     },
 
@@ -765,7 +1005,20 @@ tie my %sqlmail_options, 'Tie::IxHash',
     'vpopmail' => {
       'desc' => 'Real-time export to vpopmail text files',
       'options' => \%vpopmail_options,
-      'notes' => 'Real time export to <a href="http://inter7.com/vpopmail/">vpopmail</a> text files (...extended description from jeff?...)',
+      'notes' => 'Real time export to <a href="http://inter7.com/vpopmail/">vpopmail</a> text files.  <a href="http://search.cpan.org/search?dist=File-Rsync">File::Rsync</a> must be installed, and you will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a> to <b>vpopmail</b>@<i>export.host</i>.',
+    },
+
+    'communigate_pro' => {
+      'desc' => 'Real-time export to a CommuniGate Pro mail server',
+      'options' => \%communigate_pro_options,
+      'notes' => 'Real time export to a <a href="http://www.stalker.com/CommuniGatePro/">CommuniGate Pro</a> mail server.  The <a href="http://www.stalker.com/CGPerl/">CommuniGate Pro Perl Interface</a> must be installed as CGP::CLI.',
+    },
+
+    'communigate_pro_singledomain' => {
+      'desc' => 'Real-time export to a CommuniGate Pro mail server, one domain only',
+      'options' => \%communigate_pro_singledomain_options,
+      'nodomain' => 'Y',
+      'notes' => 'Real time export to a <a href="http://www.stalker.com/CommuniGatePro/">CommuniGate Pro</a> mail server.  This is an unusual export to CommuniGate Pro that forces all accounts into a single domain.  As CommuniGate Pro supports multiple domains, unless you have a specific reason for using this export, you probably want to use the communigate_pro export instead.  The <a href="http://www.stalker.com/CGPerl/">CommuniGate Pro Perl Interface</a> must be installed as CGP::CLI.',
     },
 
   },
@@ -797,27 +1050,61 @@ tie my %sqlmail_options, 'Tie::IxHash',
       'notes' => 'Database schema can be made to work with Courier IMAP and Exim.  Others could work but are untested. (...extended description from pc-intouch?...)',
     },
 
+    'domain_shellcommands' => {
+      'desc' => 'Run remote commands via SSH, for domains.',
+      'options' => \%domain_shellcommands_options,
+      'notes'    => 'Run remote commands via SSH, for domains.  You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="qmail catchall .qmail-domain-default maintenance" onClick=\'this.form.useradd.value = "[ \"$uid\" -a \"$gid\" -a \"$dir\" -a \"$qdomain\" ] && [ -e $dir/.qmail-$qdomain-default ] || { touch $dir/.qmail-$qdomain-default; chown $uid:$gid $dir/.qmail-$qdomain-default; }"; this.form.userdel.value = ""; this.form.usermod.value = "";\'></UL>The following variables are available for interpolation (prefixed with <code>new_</code> or <code>old_</code> for replace operations): <UL><LI><code>$domain</code><LI><code>$qdomain</code> - domain with periods replaced by colons<LI><code>$uid</code> - of catchall account<LI><code>$gid</code> - of catchall account<LI><code>$dir</code> - home directory of catchall account<LI>All other fields in <a href="../docs/schema.html#svc_domain">svc_domain</a> are also available.</UL>',
+    },
+
 
   },
 
-  'svc_acct_sm' => {},
-
   'svc_forward' => {
     'sqlmail' => {
       'desc' => 'Real-time export to SQL-backed mail server',
       'options' => \%sqlmail_options,
       #'nodomain' => 'Y',
-      'notes' => 'Database schema can be made to work with Courier IMAP and Exim.  Others could work but are untested. (...extended description from pc-intouch?...)',
+      'notes' => 'Database schema can be made to work with Courier IMAP and Exim.  Others could work but are untested. (...extended description from fire2wire?...)',
     },
+
+    'forward_shellcommands' => {
+      'desc' => 'Run remote commands via SSH, for forwards',
+      'options' => \%forward_shellcommands_options,
+      'notes' => 'Run remote commands via SSH, for forwards.  You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="text vpopmail maintenance" onClick=\'this.form.useradd.value = "[ -d /home/vpopmail/domains/$domain/$username ] && { echo \"$destination\" > /home/vpopmail/domains/$domain/$username/.qmail; chown vpopmail:vchkpw /home/vpopmail/domains/$domain/$username/.qmail; }"; this.form.userdel.value = "rm /home/vpopmail/domains/$domain/$username/.qmail"; this.form.usermod.value = "mv /home/vpopmail/domains/$old_domain/$old_username/.qmail /home/vpopmail/domains/$new_domain/$new_username; [ \"$old_destination\" != \"$new_destination\" ] && { echo \"$new_destination\" > /home/vpopmail/domains/$new_domain/$new_username/.qmail; chown vpopmail:vchkpw /home/vpopmail/domains/$new_domain/$new_username/.qmail; }";\'></UL>The following variables are available for interpolation (prefixed with <code>new_</code> or <code>old_</code> for replace operations): <UL><LI><code>$username</code><LI><code>$domain</code><LI><code>$destination</code> - forward destination<LI>All other fields in <a href="../docs/schema.html#svc_forward">svc_forward</a> are also available.</UL>',
+    },
+
+    'postfix' => {
+      'desc' => 'Real-time export to Postfix text files',
+      'options' => \%postfix_options,
+      #'nodomain' => 'Y',
+      'notes' => 'Batch export of Postfix aliases and virtual files.  <a href="http://search.cpan.org/search?dist=File-Rsync">File::Rsync</a> must be installed.  Run bin/postfix.export to export the files.',
+    },
+
   },
 
   'svc_www' => {
     'www_shellcommands' => {
       'desc' => 'Run remote commands via SSH, for virtual web sites.',
       'options' => \%www_shellcommands_options,
-      'notes'    => 'Run remote commands via SSH, for virtual web sites.  You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.',
+      'notes'    => 'Run remote commands via SSH, for virtual web sites.  You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>The following variables are available for interpolation (prefixed with <code>new_</code> or <code>old_</code> for replace operations): <UL><LI><code>$zone</code><LI><code>$username</code><LI><code>$homedir</code><LI>All other fields in <a href="../docs/schema.html#svc_www">svc_www</a> are also available.</UL>',
     },
 
+    'apache' => {
+      'desc' => 'Export an Apache httpd.conf file snippet.',
+      'options' => \%apache_options,
+      'notes' => 'Batch export of an httpd.conf snippet from a template.  Typically used with something like <code>Include /etc/apache/httpd-freeside.conf</code> in httpd.conf.  <a href="http://search.cpan.org/search?dist=File-Rsync">File::Rsync</a> must be installed.  Run bin/apache.export to export the files.',
+    },
+  },
+
+  'svc_broadband' => {
+    'router' => {
+      'desc' => 'Send a command to a router.',
+      'options' => \%router_options,
+      'notes' => '',
+    },
+  },
+
+  'svc_external' => {
   },
 
 );
diff --git a/FS/FS/part_export/apache.pm b/FS/FS/part_export/apache.pm
new file mode 100644 (file)
index 0000000..9161d72
--- /dev/null
@@ -0,0 +1,7 @@
+package FS::part_export::apache;
+
+use vars qw(@ISA);
+use FS::part_export::null;
+
+@ISA = qw(FS::part_export::null);
+
diff --git a/FS/FS/part_export/communigate_pro.pm b/FS/FS/part_export/communigate_pro.pm
new file mode 100644 (file)
index 0000000..557aad9
--- /dev/null
@@ -0,0 +1,144 @@
+package FS::part_export::communigate_pro;
+
+use vars qw(@ISA);
+use FS::part_export;
+use FS::queue;
+
+@ISA = qw(FS::part_export);
+
+sub rebless { shift; }
+
+sub export_username {
+  my($self, $svc_acct) = (shift, shift);
+  $svc_acct->email;
+}
+
+sub _export_insert {
+  my( $self, $svc_acct ) = (shift, shift);
+  my @options = ( $svc_acct->svcnum, 'CreateAccount',
+    'accountName'    => $self->export_username($svc_acct),
+    'accountType'    => $self->option('accountType'),
+    'AccessModes'    => $self->option('AccessModes'),
+    'RealName'       => $svc_acct->finger,
+    'Password'       => $svc_acct->_password,
+  );
+  push @options, 'MaxAccountSize' => $svc_acct->quota if $svc_acct->quota;
+  push @options, 'externalFlag'   => $self->option('externalFlag')
+    if $self->option('externalFlag');
+
+  $self->communigate_pro_queue( @options );
+}
+
+sub _export_replace {
+  my( $self, $new, $old ) = (shift, shift, shift);
+  return "can't (yet) change username with CommuniGate Pro"
+    if $old->username ne $new->username;
+  return "can't (yet) change domain with CommuniGate Pro"
+    if $self->export_username($old) ne $self->export_username($new);
+  return "can't (yet) change GECOS with CommuniGate Pro"
+    if $old->finger ne $new->finger;
+  return "can't (yet) change quota with CommuniGate Pro"
+    if $old->quota ne $new->quota;
+  return '' unless $old->username ne $new->username
+                || $old->_password ne $new->_password
+                || $old->finger ne $new->finger
+                || $old->quota ne $new->quota;
+
+  return '' if '*SUSPENDED* '. $old->_password eq $new->_password;
+
+  #my $err_or_queue = $self->communigate_pro_queue( $new->svcnum,'RenameAccount',
+  #  $old->email, $new->email );
+  #return $err_or_queue unless ref($err_or_queue);
+  #my $jobnum = $err_or_queue->jobnum;
+
+  $self->communigate_pro_queue( $new->svcnum, 'SetAccountPassword',
+                                $self->export_username($new), $new->_password        )
+    if $new->_password ne $old->_password;
+
+}
+
+sub _export_delete {
+  my( $self, $svc_acct ) = (shift, shift);
+  $self->communigate_pro_queue( $svc_acct->svcnum, 'DeleteAccount',
+    $self->export_username($svc_acct),
+  );
+}
+
+sub _export_suspend {
+  my( $self, $svc_acct ) = (shift, shift);
+  $self->communigate_pro_queue( $svc_acct->svcnum, 'UpdateAccountSettings',
+    'accountName' => $self->export_username($svc_acct),
+    'AccessModes' => 'Mail',
+  );
+}
+
+sub _export_unsuspend {
+  my( $self, $svc_acct ) = (shift, shift);
+  $self->communigate_pro_queue( $svc_acct->svcnum, 'UpdateAccountSettings',
+    'accountName' => $self->export_username($svc_acct),
+    'AccessModes' => $self->option('AccessModes'),
+  );
+}
+
+sub communigate_pro_queue {
+  my( $self, $svcnum, $method ) = (shift, shift, shift);
+  my @kludge_methods = qw(CreateAccount UpdateAccountSettings);
+  my $sub = 'communigate_pro_command';
+  $sub = $method if grep { $method eq $_ } @kludge_methods;
+  my $queue = new FS::queue {
+    'svcnum' => $svcnum,
+    'job'    => "FS::part_export::communigate_pro::$sub",
+  };
+  $queue->insert(
+    $self->machine,
+    $self->option('port'),
+    $self->option('login'),
+    $self->option('password'),
+    $method,
+    @_,
+  );
+
+}
+
+sub CreateAccount {
+  my( $machine, $port, $login, $password, $method, %args ) = @_;
+  my $accountName  = delete $args{'accountName'};
+  my $accountType  = delete $args{'accountType'};
+  my $externalFlag = delete $args{'externalFlag'};
+  $args{'AccessModes'} = [ split(' ', $args{'AccessModes'}) ];
+  my @args = ( accountName => $accountName,
+               accountType  => $accountType,
+               settings     => \%args,
+             );
+               #externalFlag => $externalFlag,
+  push @args, externalFlag => $externalFlag if $externalFlag;
+
+  communigate_pro_command( $machine, $port, $login, $password, $method, @args );
+
+}
+
+sub UpdateAccountSettings {
+  my( $machine, $port, $login, $password, $method, %args ) = @_;
+  my $accountName  = delete $args{'accountName'};
+  $args{'AccessModes'} = [ split(' ', $args{'AccessModes'}) ];
+  @args = ( $accountName, \%args );
+  communigate_pro_command( $machine, $port, $login, $password, $method, @args );
+}
+
+sub communigate_pro_command { #subroutine, not method
+  my( $machine, $port, $login, $password, $method, @args ) = @_;
+
+  eval "use CGP::CLI";
+
+  my $cli = new CGP::CLI( {
+    'PeerAddr' => $machine,
+    'PeerPort' => $port,
+    'login'    => $login,
+    'password' => $password,
+  } ) or die "Can't login to CGPro: $CGP::ERR_STRING\n";
+
+  $cli->$method(@args) or die "CGPro error: ". $cli->getErrMessage;
+
+  $cli->Logout or die "Can't logout of CGPro: $CGP::ERR_STRING\n";
+
+}
diff --git a/FS/FS/part_export/communigate_pro_singledomain.pm b/FS/FS/part_export/communigate_pro_singledomain.pm
new file mode 100644 (file)
index 0000000..11574af
--- /dev/null
@@ -0,0 +1,11 @@
+package FS::part_export::communigate_pro_singledomain;
+
+use vars qw(@ISA);
+use FS::part_export::communigate_pro;
+
+@ISA = qw(FS::part_export::communigate_pro);
+
+sub export_username {
+  my($self, $svc_acct) = (shift, shift);
+  $svc_acct->username. '@'. $self->option('domain');
+}
index d998c1d..c4750dd 100644 (file)
@@ -10,10 +10,10 @@ sub rebless { shift; }
 sub _export_insert {
   my( $self, $svc_acct ) = (shift, shift);
   $self->cp_queue( $svc_acct->svcnum, 'create_mailbox',
-    Mailbox   => $svc_acct->username,
-    Password  => $svc_acct->_password,
-    Workgroup => $self->option('workgroup'),
-    Domain    => $svc_acct->domain,
+    'Mailbox'   => $svc_acct->username,
+    'Password'  => $svc_acct->_password,
+    'Workgroup' => $self->option('workgroup'),
+    'Domain'    => $svc_acct->domain,
   );
 }
 
@@ -30,8 +30,30 @@ sub _export_replace {
 sub _export_delete {
   my( $self, $svc_acct ) = (shift, shift);
   $self->cp_queue( $svc_acct->svcnum, 'delete_mailbox',
-    Mailbox   => $svc_acct->username,
-    Domain    => $svc_acct->domain,
+    'Mailbox'   => $svc_acct->username,
+    'Domain'    => $svc_acct->domain,
+  );
+}
+
+sub _export_suspend {
+  my( $self, $svc_acct ) = (shift, shift);
+  $self->cp_queue( $svc_acct->svcnum, 'set_mailbox_status',
+    'Mailbox'       => $svc_acct->username,
+    'Domain'        => $svc_acct->domain,
+    'OTHER'         => 'T',
+    'OTHER_SUSPEND' => 'T',
+  );
+}
+
+sub _export_unsuspend {
+  my( $self, $svc_acct ) = (shift, shift);
+  $self->cp_queue( $svc_acct->svcnum, 'set_mailbox_status',
+    'Mailbox'       => $svc_acct->username,
+    'Domain'        => $svc_acct->domain,
+    'PAYMENT'       => 'F',
+    'OTHER'         => 'F',
+    'OTHER_SUSPEND' => 'F',
+    'OTHER_BOUNCE'  => 'F',
   );
 }
 
@@ -42,7 +64,7 @@ sub cp_queue {
     'job'    => 'FS::part_export::cp::cp_command',
   };
   $queue->insert(
-    $self->option('host'),
+    $self->machine,
     $self->option('port'),
     $self->option('username'),
     $self->option('password'),
@@ -69,20 +91,22 @@ sub cp_command { #subroutine, not method
       );
     }
 
-    my $other = 'F';
+    #my $other = 'F';
     if ( $new_password =~ /^\*SUSPENDED\* (.*)$/ ) {
       $new_password = $1;
-      $other = 'T';
+    #  $other = 'T';
     }
-    cp_command($host, $port, $username, $password, 'set_mailbox_status',
-      Domain       => $domain,
-      Mailbox      => $new_username,
-      Other        => $other,
-      Other_Bounce => $other,
-    );
+    #cp_command($host, $port, $username, $password, $login_domain,
+    #  'set_mailbox_status',
+    #  Domain       => $domain,
+    #  Mailbox      => $new_username,
+    #  Other        => $other,
+    #  Other_Bounce => $other,
+    #);
 
     if ( $old_password ne $new_password ) {
-      cp_command($host, $port, $username, $password, 'change_mailbox',
+      cp_command($host, $port, $username, $password, $login_domain,
+        'change_mailbox',
         Domain    => $domain,
         Mailbox   => $new_username,
         Password  => $new_password,
diff --git a/FS/FS/part_export/domain_shellcommands.pm b/FS/FS/part_export/domain_shellcommands.pm
new file mode 100644 (file)
index 0000000..d295eec
--- /dev/null
@@ -0,0 +1,110 @@
+package FS::part_export::domain_shellcommands;
+
+use strict;
+use vars qw(@ISA);
+use FS::part_export;
+
+@ISA = qw(FS::part_export);
+
+sub rebless { shift; }
+
+sub _export_insert {
+  my($self) = shift;
+  $self->_export_command('useradd', @_);
+}
+
+sub _export_delete {
+  my($self) = shift;
+  $self->_export_command('userdel', @_);
+}
+
+sub _export_command {
+  my ( $self, $action, $svc_domain) = (shift, shift, shift);
+  my $command = $self->option($action);
+
+  #set variable for the command
+  no strict 'vars';
+  {
+    no strict 'refs';
+    ${$_} = $svc_domain->getfield($_) foreach $svc_domain->fields;
+  }
+  ( $qdomain = $domain ) =~ s/\./:/g; #see dot-qmail(5): EXTENSION ADDRESSES
+
+  if ( $svc_domain->catchall ) {
+    no strict 'refs';
+    my $svc_acct = $svc_domain->catchall_svc_acct;
+    ${$_} = $svc_acct->getfield($_) foreach qw(uid gid dir);
+  } else {
+    no strict 'refs';
+    ${$_} = '' foreach qw(uid gid dir);
+  }
+
+  #done setting variables for the command
+
+  $self->shellcommands_queue( $svc_domain->svcnum,
+    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('usermod');
+  
+  #set variable for the command
+  no strict 'vars';
+  {
+    no strict 'refs';
+    ${"old_$_"} = $old->getfield($_) foreach $old->fields;
+    ${"new_$_"} = $new->getfield($_) foreach $new->fields;
+  }
+  ( $old_qdomain = $old_domain ) =~ s/\./:/g; #see dot-qmail(5): EXTENSION ADDRESSES
+  ( $new_qdomain = $new_domain ) =~ s/\./:/g; #see dot-qmail(5): EXTENSION ADDRESSES
+
+  if ( $old->catchall ) {
+    no strict 'refs';
+    my $svc_acct = $old->catchall_svc_acct;
+    ${"old_$_"} = $svc_acct->getfield($_) foreach qw(uid gid dir);
+  } else {
+    ${"old_$_"} = '' foreach qw(uid gid dir);
+  }
+  if ( $new->catchall ) {
+    no strict 'refs';
+    my $svc_acct = $new->catchall_svc_acct;
+    ${"new_$_"} = $svc_acct->getfield($_) foreach qw(uid gid dir);
+  } else {
+    ${"new_$_"} = '' foreach qw(uid gid dir);
+  }
+
+  #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
+sub shellcommands_queue {
+  my( $self, $svcnum ) = (shift, shift);
+  my $queue = new FS::queue {
+    'svcnum' => $svcnum,
+    'job'    => "FS::part_export::domain_shellcommands::ssh_cmd",
+  };
+  $queue->insert( @_ );
+}
+
+sub ssh_cmd { #subroutine, not method
+  use Net::SSH '0.08';
+  &Net::SSH::ssh_cmd( { @_ } );
+}
+
+#sub shellcommands_insert { #subroutine, not method
+#}
+#sub shellcommands_replace { #subroutine, not method
+#}
+#sub shellcommands_delete { #subroutine, not method
+#}
+
diff --git a/FS/FS/part_export/forward_shellcommands.pm b/FS/FS/part_export/forward_shellcommands.pm
new file mode 100644 (file)
index 0000000..5d31457
--- /dev/null
@@ -0,0 +1,110 @@
+package FS::part_export::forward_shellcommands;
+
+use strict;
+use vars qw(@ISA);
+use FS::part_export;
+
+@ISA = qw(FS::part_export);
+
+sub rebless { shift; }
+
+sub _export_insert {
+  my($self) = shift;
+  $self->_export_command('useradd', @_);
+}
+
+sub _export_delete {
+  my($self) = shift;
+  $self->_export_command('userdel', @_);
+}
+
+sub _export_command {
+  my ( $self, $action, $svc_forward ) = (shift, shift, shift);
+  my $command = $self->option($action);
+
+  #set variable for the command
+  no strict 'vars';
+  {
+    no strict 'refs';
+    ${$_} = $svc_forward->getfield($_) foreach $svc_forward->fields;
+  }
+
+  my $svc_acct = $svc_forward->srcsvc_acct;
+  $username = $svc_acct->username;
+  $domain = $svc_acct->domain;
+  if ($svc_forward->dstsvc_acct) {
+    $destination = $svc_forward->dstsvc_acct->email;
+  } else {
+    $destination = $svc_forward->dst;
+  }
+
+  #done setting variables for the command
+
+  $self->shellcommands_queue( $svc_forward->svcnum,
+    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('usermod');
+  
+  #set variable for the command
+  no strict 'vars';
+  {
+    no strict 'refs';
+    ${"old_$_"} = $old->getfield($_) foreach $old->fields;
+    ${"new_$_"} = $new->getfield($_) foreach $new->fields;
+  }
+
+  my $old_svc_acct = $old->srcsvc_acct;
+  $old_username = $old_svc_acct->username;
+  $old_domain = $old_svc_acct->domain;
+  if ($old->dstsvc_acct) {
+    $old_destination = $old->dstsvc_acct->email;
+  } else {
+    $old_destination = $old->dst;
+  }
+
+  my $new_svc_acct = $new->srcsvc_acct;
+  $new_username = $new_svc_acct->username;
+  $new_domain = $new_svc_acct->domain;
+  if ($new->dstsvc) {
+    $new_destination = $new->dstsvc_acct->email;
+  } else {
+    $new_destination = $new->dst;
+  }
+
+  #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
+sub shellcommands_queue {
+  my( $self, $svcnum ) = (shift, shift);
+  my $queue = new FS::queue {
+    'svcnum' => $svcnum,
+    'job'    => "FS::part_export::forward_shellcommands::ssh_cmd",
+  };
+  $queue->insert( @_ );
+}
+
+sub ssh_cmd { #subroutine, not method
+  use Net::SSH '0.08';
+  &Net::SSH::ssh_cmd( { @_ } );
+}
+
+#sub shellcommands_insert { #subroutine, not method
+#}
+#sub shellcommands_replace { #subroutine, not method
+#}
+#sub shellcommands_delete { #subroutine, not method
+#}
+
index f2d5199..caca7c5 100644 (file)
@@ -55,6 +55,12 @@ sub _export_insert {
   $err_or_queue = $self->infostreet_queueContact( $svc_acct->svcnum,
     $svc_acct->username, %contact_info );
   return $err_or_queue unless ref($err_or_queue);
+
+  # If a quota has been specified set the quota because it is not the default
+  $err_or_queue = $self->infostreet_queueSetQuota( $svc_acct->svcnum, 
+    $svc_acct->username, $svc_acct->quota ) if $svc_acct->quota;
+  return $err_or_queue unless ref($err_or_queue);
+
   my $error = $err_or_queue->depend_insert( $jobnum );
   return $error if $error;
 
@@ -68,6 +74,13 @@ sub _export_replace {
   my( $self, $new, $old ) = (shift, shift, shift);
   return "can't change username with InfoStreet"
     if $old->username ne $new->username;
+
+  # If the quota has changed then do the export to setQuota
+  my $err_or_queue = $self->infostreet_queueSetQuota( $new->svcnum, $new->username, $new->quota ) 
+        if ( $old->quota != $new->quota );  
+  return $err_or_queue unless ref($err_or_queue);
+
+
   return '' unless $old->_password ne $new->_password;
   $self->infostreet_queue( $new->svcnum,
     'passwd', $new->username, $new->_password );
@@ -150,6 +163,30 @@ sub infostreet_setContact {
 
 }
 
+sub infostreet_queueSetQuota {
+
+ my( $self, $svcnum) = (shift, shift);
+ my $queue = new FS::queue {
+    'svcnum' => $svcnum,
+    'job'    => 'FS::part_export::infostreet::infostreet_setQuota',
+ };
+
+ $queue->insert(
+    $self->option('url'),
+    $self->option('login'),
+    $self->option('password'),
+    $self->option('groupID'),
+    @_,
+ ) or $queue;
+
+}
+
+sub infostreet_setQuota {
+  my($url, $is_username, $is_password, $groupID, $username, $quota) = @_;
+  infostreet_command($url, $is_username, $is_password, $groupID, 'setQuota', $username, [ 'int'=> $quota ]  );
+}
+
+
 sub infostreet_command { #subroutine, not method
   my($url, $username, $password, $groupID, $method, @args) = @_;
 
diff --git a/FS/FS/part_export/ldap.pm b/FS/FS/part_export/ldap.pm
new file mode 100644 (file)
index 0000000..57fd1f3
--- /dev/null
@@ -0,0 +1,253 @@
+package FS::part_export::ldap;
+
+use vars qw(@ISA @saltset);
+use FS::Record qw( dbh );
+use FS::part_export;
+
+@ISA = qw(FS::part_export);
+
+@saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
+
+sub rebless { shift; }
+
+sub _export_insert {
+  my($self, $svc_acct) = (shift, shift);
+
+  #false laziness w/shellcommands.pm
+  {
+    no strict 'refs';
+    ${$_} = $svc_acct->getfield($_) foreach $svc_acct->fields;
+    ${$_} = $svc_acct->$_() foreach qw( domain );
+    my $cust_pkg = $svc_acct->cust_svc->cust_pkg;
+    if ( $cust_pkg ) {
+      my $cust_main = $cust_pkg->cust_main;
+      ${$_} = $cust_main->getfield($_) foreach qw(first last);
+    }
+  }
+  $crypt_password = ''; #surpress "used only once" warnings
+  $crypt_password = '{crypt}'. crypt( $svc_acct->_password,
+                             $saltset[int(rand(64))].$saltset[int(rand(64))] );
+
+  my $username_attrib;
+  my %attrib = map    { /^\s*(\w+)\s+(.*\S)\s*$/;
+                        $username_attrib = $1 if $2 eq '$username';
+                        ( $1 => eval(qq("$2")) );                   }
+                 grep { /^\s*(\w+)\s+(.*\S)\s*$/ }
+                   split("\n", $self->option('attributes'));
+
+  if ( $self->option('radius') ) {
+    foreach my $table (qw(reply check)) {
+      my $method = "radius_$table";
+      my %radius = $svc_acct->$method();
+      foreach my $radius ( keys %radius ) {
+        ( my $ldap = $radius ) =~ s/\-//g;
+        $attrib{$ldap} = $radius{$radius};
+      }
+    }
+  }
+
+  my $err_or_queue = $self->ldap_queue( $svc_acct->svcnum, 'insert',
+    #$svc_acct->username,
+    $username_attrib,
+    %attrib );
+  return $err_or_queue unless ref($err_or_queue);
+
+  #groups with LDAP?
+  #my @groups = $svc_acct->radius_groups;
+  #if ( @groups ) {
+  #  my $err_or_queue = $self->ldap_queue(
+  #    $svc_acct->svcnum, 'usergroup_insert',
+  #    $svc_acct->username, @groups );
+  #  return $err_or_queue unless ref($err_or_queue);
+  #}
+
+  '';
+}
+
+sub _export_replace {
+  my( $self, $new, $old ) = (shift, shift, 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';
+
+  return "can't (yet?) change username with ldap"
+    if $old->username ne $new->username;
+
+  return "ldap replace unimplemented";
+
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+  my $dbh = dbh;
+
+  my $jobnum = '';
+  #if ( $old->username ne $new->username ) {
+  #  my $err_or_queue = $self->ldap_queue( $new->svcnum, 'rename',
+  #    $new->username, $old->username );
+  #  unless ( ref($err_or_queue) ) {
+  #    $dbh->rollback if $oldAutoCommit;
+  #    return $err_or_queue;
+  #  }
+  #  $jobnum = $err_or_queue->jobnum;
+  #}
+
+  foreach my $table (qw(reply check)) {
+    my $method = "radius_$table";
+    my %new = $new->$method();
+    my %old = $old->$method();
+    if ( grep { !exists $old{$_} #new attributes
+                || $new{$_} ne $old{$_} #changed
+              } keys %new
+    ) {
+      my $err_or_queue = $self->ldap_queue( $new->svcnum, 'insert',
+        $table, $new->username, %new );
+      unless ( ref($err_or_queue) ) {
+        $dbh->rollback if $oldAutoCommit;
+        return $err_or_queue;
+      }
+      if ( $jobnum ) {
+        my $error = $err_or_queue->depend_insert( $jobnum );
+        if ( $error ) {
+          $dbh->rollback if $oldAutoCommit;
+          return $error;
+        }
+      }
+    }
+
+    my @del = grep { !exists $new{$_} } keys %old;
+    if ( @del ) {
+      my $err_or_queue = $self->ldap_queue( $new->svcnum, 'attrib_delete',
+        $table, $new->username, @del );
+      unless ( ref($err_or_queue) ) {
+        $dbh->rollback if $oldAutoCommit;
+        return $err_or_queue;
+      }
+      if ( $jobnum ) {
+        my $error = $err_or_queue->depend_insert( $jobnum );
+        if ( $error ) {
+          $dbh->rollback if $oldAutoCommit;
+          return $error;
+        }
+      }
+    }
+  }
+
+  # (sorta) false laziness with FS::svc_acct::replace
+  my @oldgroups = @{$old->usergroup}; #uuuh
+  my @newgroups = $new->radius_groups;
+  my @delgroups = ();
+  foreach my $oldgroup ( @oldgroups ) {
+    if ( grep { $oldgroup eq $_ } @newgroups ) {
+      @newgroups = grep { $oldgroup ne $_ } @newgroups;
+      next;
+    }
+    push @delgroups, $oldgroup;
+  }
+
+  if ( @delgroups ) {
+    my $err_or_queue = $self->ldap_queue( $new->svcnum, 'usergroup_delete',
+      $new->username, @delgroups );
+    unless ( ref($err_or_queue) ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $err_or_queue;
+    }
+    if ( $jobnum ) {
+      my $error = $err_or_queue->depend_insert( $jobnum );
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return $error;
+      }
+    }
+  }
+
+  if ( @newgroups ) {
+    my $err_or_queue = $self->ldap_queue( $new->svcnum, 'usergroup_insert',
+      $new->username, @newgroups );
+    unless ( ref($err_or_queue) ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $err_or_queue;
+    }
+    if ( $jobnum ) {
+      my $error = $err_or_queue->depend_insert( $jobnum );
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return $error;
+      }
+    }
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+  '';
+}
+
+sub _export_delete {
+  my( $self, $svc_acct ) = (shift, shift);
+  return "ldap delete unimplemented";
+  my $err_or_queue = $self->ldap_queue( $svc_acct->svcnum, 'delete',
+    $svc_acct->username );
+  ref($err_or_queue) ? '' : $err_or_queue;
+}
+
+sub ldap_queue {
+  my( $self, $svcnum, $method ) = (shift, shift, shift);
+  my $queue = new FS::queue {
+    'svcnum' => $svcnum,
+    'job'    => "FS::part_export::ldap::ldap_$method",
+  };
+  $queue->insert(
+    $self->machine,
+    $self->option('dn'),
+    $self->option('password'),
+    $self->option('userdn'),
+    @_,
+  ) or $queue;
+}
+
+sub ldap_insert { #subroutine, not method
+  my $ldap = ldap_connect(shift, shift, shift);
+  my( $userdn, $username_attrib, %attrib ) = @_;
+
+  $userdn = "$username_attrib=$attrib{$username_attrib}, $userdn"
+    if $username_attrib;
+  #icky hack, but should be unsurprising to the LDAPers
+  foreach my $key ( grep { $attrib{$_} =~ /,/ } keys %attrib ) {
+    $attrib{$key} = [ split(/,/, $attrib{$key}) ]; 
+  }
+
+  my $status = $ldap->add( $userdn, attrs => [ %attrib ] );
+  die 'LDAP error: '. $status->error. "\n" if $status->is_error;
+
+  $ldap->unbind;
+}
+
+#sub ldap_delete { #subroutine, not method
+#  my $dbh = ldap_connect(shift, shift, shift);
+#  my $username = shift;
+#
+#  foreach my $table (qw( radcheck radreply usergroup )) {
+#    my $sth = $dbh->prepare( "DELETE FROM $table WHERE UserName = ?" );
+#    $sth->execute($username)
+#      or die "can't delete from $table table: ". $sth->errstr;
+#  }
+#  $dbh->disconnect;
+#}
+
+sub ldap_connect {
+  my( $machine, $dn, $password ) = @_;
+  my %bind_options;
+  $bind_options{password} = $password if length($password);
+
+  eval "use Net::LDAP";
+  die $@ if $@;
+
+  my $ldap = Net::LDAP->new($machine) or die $@;
+  my $status = $ldap->bind( $dn, %bind_options );
+  die 'LDAP error: '. $status->error. "\n" if $status->is_error;
+
+  $ldap;
+}
+
diff --git a/FS/FS/part_export/postfix.pm b/FS/FS/part_export/postfix.pm
new file mode 100644 (file)
index 0000000..6d5e449
--- /dev/null
@@ -0,0 +1,7 @@
+package FS::part_export::postfix;
+
+use vars qw(@ISA);
+use FS::part_export::null;
+
+@ISA = qw(FS::part_export::null);
+
diff --git a/FS/FS/part_export/router.pm b/FS/FS/part_export/router.pm
new file mode 100644 (file)
index 0000000..07b5b9e
--- /dev/null
@@ -0,0 +1,166 @@
+package FS::part_export::router;
+
+=head1 FS::part_export::router
+
+This export connects to a router and transmits commands via telnet or SSH.
+It requires the following custom router fields:
+
+=over 4
+
+=item admin_address - IP address (or hostname) to connect
+
+=item admin_user - username for admin access
+
+=item admin_password - password for admin access
+
+=back
+
+The export itself needs the following options:
+
+=over 4
+
+=item insert, replace, delete - command strings (to be interpolated)
+
+=item Prompt - prompt string to expect from router after successful login
+
+=item Timeout - time to wait for prompt string
+
+=back
+
+(Prompt and Timeout are required only for telnet connections.)
+
+=cut
+
+use vars qw(@ISA @saltset);
+use String::ShellQuote;
+use FS::part_export;
+
+@ISA = qw(FS::part_export);
+
+@saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
+
+sub rebless { shift; }
+
+sub _export_insert {
+  my($self) = shift;
+  $self->_export_command('insert', @_);
+}
+
+sub _export_delete {
+  my($self) = shift;
+  $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_broadband) = (shift, shift, shift);
+  my $command = $self->option($action);
+  return '' if $command =~ /^\s*$/;
+
+  no strict 'vars';
+  {
+    no strict 'refs';
+    ${$_} = $svc_broadband->getfield($_) foreach $svc_broadband->fields;
+  }
+  # fetch router info
+  my $router = $svc_broadband->addr_block->router;
+  my %r;
+  $r{$_} = $router->getfield($_) foreach $router->virtual_fields;
+  #warn qq("$command");
+  #warn eval(qq("$command"));
+
+  warn "admin_address: '$r{admin_address}'";
+
+  if ($r{admin_address} ne '') {
+    $self->router_queue( $svc_broadband->svcnum, $self->option('protocol'),
+      user         => $r{admin_user},
+      password     => $r{admin_password},
+      host         => $r{admin_address},
+      Timeout      => $self->option('Timeout'),
+      Prompt       => $self->option('Prompt'),
+      command      => eval(qq("$command")),
+    );
+  } else {
+    return '';
+  }
+}
+
+sub _export_replace {
+
+  # We don't handle the case of a svc_broadband moving between routers.
+  # If you want to do that, reprovision the service.
+
+  my($self, $new, $old ) = (shift, shift, shift);
+  my $command = $self->option('replace');
+  no strict 'vars';
+  {
+    no strict 'refs';
+    ${"old_$_"} = $old->getfield($_) foreach $old->fields;
+    ${"new_$_"} = $new->getfield($_) foreach $new->fields;
+  }
+
+  my $router = $new->addr_block->router;
+  my %r;
+  $r{$_} = $router->getfield($_) foreach $router->virtual_fields;
+
+  if ($r{admin_address} ne '') {
+    $self->router_queue( $new->svcnum, $self->option('protocol'),
+      user         => $r{admin_user},
+      password     => $r{admin_password},
+      host         => $r{admin_address},
+      Timeout      => $self->option('Timeout'),
+      Prompt       => $self->option('Prompt'),
+      command      => eval(qq("$command")),
+    );
+  } else {
+    return '';
+  }
+}
+
+#a good idea to queue anything that could fail or take any time
+sub router_queue {
+  #warn join ':', @_;
+  my( $self, $svcnum, $protocol ) = (shift, shift, shift);
+  my $queue = new FS::queue {
+    'svcnum' => $svcnum,
+  };
+  $queue->job ("FS::part_export::router::".$protocol."_cmd");
+  $queue->insert( @_ );
+}
+
+sub ssh_cmd { #subroutine, not method
+  use Net::SSH '0.08';
+  &Net::SSH::ssh_cmd( { @_ } );
+}
+
+sub telnet_cmd {
+  use Net::Telnet;
+
+  warn join(', ', @_);
+
+  my %arg = @_;
+
+  my $t = new Net::Telnet (Timeout => $arg{Timeout},
+                           Prompt  => $arg{Prompt});
+  $t->open($arg{host});
+  $t->login($arg{user}, $arg{password});
+  my @error = $t->cmd($arg{command});
+  die @error if (grep /^ERROR/, @error);
+}
+
+#sub router_insert { #subroutine, not method
+#}
+#sub router_replace { #subroutine, not method
+#}
+#sub router_delete { #subroutine, not method
+#}
+
index e400576..db2e7aa 100644 (file)
@@ -20,18 +20,49 @@ sub _export_delete {
   $self->_export_command('userdel', @_);
 }
 
+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_acct) = (shift, shift, shift);
   my $command = $self->option($action);
+  return '' if $command =~ /^\s*$/;
   my $stdin = $self->option($action."_stdin");
+
+  no strict 'vars';
   {
     no strict 'refs';
     ${$_} = $svc_acct->getfield($_) foreach $svc_acct->fields;
+
+    my $count = 1;
+    foreach my $acct_snarf ( $svc_acct->acct_snarf ) {
+      ${"snarf_$_$count"} = shell_quote( $acct_snarf->get($_) )
+        foreach qw( machine username _password );
+      $count++;
+    }
+  }
+
+  my $cust_pkg = $svc_acct->cust_svc->cust_pkg;
+  if ( $cust_pkg ) {
+    $email = ( grep { $_ ne 'POST' } $cust_pkg->cust_main->invoicing_list )[0];
+  } else {
+    $email = '';
   }
+
   $finger = shell_quote $finger;
+  $quoted_password = shell_quote $_password;
+  $domain = $svc_acct->domain;
   $crypt_password = ''; #surpress "used only once" warnings
   $crypt_password = crypt( $svc_acct->_password,
                              $saltset[int(rand(64))].$saltset[int(rand(64))] );
+
   $self->shellcommands_queue( $svc_acct->svcnum,
     user         => $self->option('user')||'root',
     host         => $self->machine,
@@ -44,15 +75,37 @@ sub _export_replace {
   my($self, $new, $old ) = (shift, shift, shift);
   my $command = $self->option('usermod');
   my $stdin = $self->option('usermod_stdin');
+  no strict 'vars';
   {
     no strict 'refs';
     ${"old_$_"} = $old->getfield($_) foreach $old->fields;
     ${"new_$_"} = $new->getfield($_) foreach $new->fields;
   }
   $new_finger = shell_quote $new_finger;
+  $quoted_new__password = shell_quote $new__password; #old, wrong?
+  $new_quoted_password = shell_quote $new__password; #new, better?
+  $old_domain = $old->domain;
+  $new_domain = $new->domain;
   $new_crypt_password = ''; #surpress "used only once" warnings
   $new_crypt_password = crypt( $new->_password,
                                $saltset[int(rand(64))].$saltset[int(rand(64))]);
+  if ( $self->option('usermod_pwonly') ) {
+    my $error = '';
+    if ( $old_username ne $new_username ) {
+      $error ||= "can't change username";
+    }
+    if ( $old_domain ne $new_domain ) {
+      $error ||= "can't change domain";
+    }
+    if ( $old_uid != $new_uid ) {
+      $error ||= "can't change uid";
+    }
+    if ( $old_dir ne $new_dir ) {
+      $error ||= "can't change dir";
+    }
+    return $error. ' ('. $self->exporttype. ' to '. $self->machine. ')'
+      if $error;
+  }
   $self->shellcommands_queue( $new->svcnum,
     user         => $self->option('user')||'root',
     host         => $self->machine,
@@ -72,7 +125,7 @@ sub shellcommands_queue {
 }
 
 sub ssh_cmd { #subroutine, not method
-  use Net::SSH '0.06';
+  use Net::SSH '0.08';
   &Net::SSH::ssh_cmd( { @_ } );
 }
 
index 4194daf..8ccad3c 100644 (file)
@@ -1,54 +1,75 @@
 package FS::part_export::sqlmail;
 
-use vars qw(@ISA %fs_mail_table %fields);
+use vars qw(@ISA);
+use Digest::MD5 qw(md5_hex);
+use FS::Record qw(qsearchs);
 use FS::part_export;
+use FS::svc_domain;
 
 @ISA = qw(FS::part_export);
 
-%fs_mail_table = ( svc_acct => 'user',
-                   svc_domain => 'domain' );
-
-# fields that need to be copied into the fs_mail tables
-$fields{user} = [qw(username _password finger domsvc svcnum )];
-$fields{domain} = [qw(domain svcnum catchall )];
-
 sub rebless { shift; }
 
 sub _export_insert {
   my($self, $svc) = (shift, shift);
   # this is a svc_something.
 
-  my $table = $fs_mail_table{$svc->cust_svc->part_svc->svcdb};
-  my @attrib = map {$svc->$_} @{$fields{$table}};
+  my $svcdb = $svc->cust_svc->part_svc->svcdb;
+  my $export_table = $self->option($svcdb . '_table')
+    or die('Export table not defined for svcdb: ' . $svcdb);
+  my @export_fields = split(/\s+/, $self->option($svcdb . '_fields'));
+  my $svchash = update_values($self, $svc, $svcdb);
+
+  foreach my $key (keys(%$svchash)) {
+    unless (grep { $key eq $_ } @export_fields) {
+      delete $svchash->{$key};
+    }
+  }
+
   my $error = $self->sqlmail_queue( $svc->svcnum, 'insert',
-      $table, @attrib );
+    $self->option('server_type'), $export_table,
+    (map { ($_, $svchash->{$_}); } keys(%$svchash)));
   return $error if $error;
   '';
+
 }
 
 sub _export_replace {
   my( $self, $new, $old ) = (shift, shift, shift);
 
-  my $table = $fs_mail_table{$new->cust_svc->part_svc->svcdb};
-
-  my @old = ($old->svcnum, 'delete', $table, $old->svcnum);
-  my @narf = map {$new->$_} @{$fields{$table}};
-  $self->sqlmail_queue($new->svcnum, 'replace', $table, 
-      $new->svcnum, @narf);
-
+  my $svcdb = $new->cust_svc->part_svc->svcdb;
+  my $export_table = $self->option($svcdb . '_table')
+    or die('Export table not defined for svcdb: ' . $svcdb);
+  my @export_fields = split(/\s+/, $self->option($svcdb . '_fields'));
+  my $svchash = update_values($self, $new, $svcdb);
+
+  foreach my $key (keys(%$svchash)) {
+    unless (grep { $key eq $_ } @export_fields) {
+      delete $svchash->{$key};
+    }
+  }
+
+  my $error = $self->sqlmail_queue( $new->svcnum, 'replace',
+    $old->svcnum, $self->option('server_type'), $export_table,
+    (map { ($_, $svchash->{$_}); } keys(%$svchash)));
   return $error if $error;
   '';
+
 }
 
 sub _export_delete {
   my( $self, $svc ) = (shift, shift);
-  my $table = $fs_mail_table{$new->cust_svc->part_svc->svcdb};
+
+  my $svcdb = $svc->cust_svc->part_svc->svcdb;
+  my $table = $self->option($svcdb . '_table')
+    or die('Export table not defined for svcdb: ' . $svcdb);
+
   $self->sqlmail_queue( $svc->svcnum, 'delete', $table,
     $svc->svcnum );
 }
 
 sub sqlmail_queue {
-  my( $self, $svcnum, $method, $table ) = (shift, shift, shift);
+  my( $self, $svcnum, $method ) = (shift, shift, shift);
   my $queue = new FS::queue {
     'svcnum' => $svcnum,
     'job'    => "FS::part_export::sqlmail::sqlmail_$method",
@@ -63,49 +84,99 @@ sub sqlmail_queue {
 
 sub sqlmail_insert { #subroutine, not method
   my $dbh = sqlmail_connect(shift, shift, shift);
-  my( $table, @attrib ) = @_;
+  my( $server_type, $table ) = (shift, shift);
 
-  my $sth = $dbh->prepare(
-    "INSERT INTO $table (" . join (',', @{$fields{$table}}) .
-    ") VALUES ('" . join ("','", @attrib) . "')"
-  ) or die $dbh->errstr;
-  $sth->execute() or die $sth->errstr;
+  my %attrs = @_;
 
+  map { $attrs{$_} = $attrs{$_} ? qq!'$attrs{$_}'! : 'NULL'; } keys(%attrs);
+  my $query = sprintf("INSERT INTO %s (%s) values (%s)",
+                      $table, join(",", keys(%attrs)),
+                      join(',', values(%attrs)));
+
+  $dbh->do($query) or die $dbh->errstr;
   $dbh->disconnect;
+
+  '';
 }
 
 sub sqlmail_delete { #subroutine, not method
   my $dbh = sqlmail_connect(shift, shift, shift);
   my( $table, $svcnum ) = @_;
 
-  my $sth = $dbh->prepare(
-    "DELETE FROM $table WHERE svcnum = $svcnum"
-  ) or die $dbh->errstr;
-  $sth->execute() or die $sth->errstr;
-
+  $dbh->do("DELETE FROM $table WHERE svcnum = $svcnum") or die $dbh->errstr;
   $dbh->disconnect;
+
+  '';
 }
 
 sub sqlmail_replace {
   my $dbh = sqlmail_connect(shift, shift, shift);
-  my( $table, $svcnum, @attrib ) = @_;
-
-  my %data;
-  @data{@{$fields{$table}}} = @attrib;
-
-  my $sth = $dbh->prepare(
-    "UPDATE $table SET " .
-    ( join ',',  map {$_ . "='" . $data{$_} . "'"} keys(%data) ) .
-    " WHERE svcnum = $svcnum"
-    ) or die $dbh->errstr;
-  $sth->execute() or die $sth->errstr;
+  my($oldsvcnum, $server_type, $table) = (shift, shift, shift);
+
+  my %attrs = @_;
+  map { $attrs{$_} = $attrs{$_} ? qq!'$attrs{$_}'! : 'NULL'; } keys(%attrs);
+
+  my $query = "SELECT COUNT(*) FROM $table WHERE svcnum = $oldsvcnum";
+  my $result = $dbh->selectrow_arrayref($query) or die $dbh->errstr;
+  
+  if (@$result[0] == 0) {
+    $query = sprintf("INSERT INTO %s (%s) values (%s)",
+                     $table, join(",", keys(%attrs)),
+                     join(',', values(%attrs)));
+    $dbh->do($query) or die $dbh->errstr;
+  } else {
+    $query = sprintf('UPDATE %s SET %s WHERE svcnum = %s',
+                     $table, join(', ', map {"$_ = $attrs{$_}"} keys(%attrs)),
+                     $oldsvcnum);
+    $dbh->do($query) or die $dbh->errstr;
+  }
 
   $dbh->disconnect;
+
+  '';
 }
 
 sub sqlmail_connect {
-  #my($datasrc, $username, $password) = @_;
-  #DBI->connect($datasrc, $username, $password) or die $DBI::errstr;
   DBI->connect(@_) or die $DBI::errstr;
 }
 
+sub update_values {
+
+  # Update records to conform to a particular server_type.
+
+  my ($self, $svc, $svcdb) = (shift,shift,shift);
+  my $svchash = { %{$svc->hashref} } or return ''; # We need a copy.
+
+  if ($svcdb eq 'svc_acct') {
+    if ($self->option('server_type') eq 'courier_crypt') {
+      my $salt = join '', ('.', '/', 0..9,'A'..'Z', 'a'..'z')[rand 64, rand 64];
+      $svchash->{_password} = crypt($svchash->{_password}, $salt);
+
+    } elsif ($self->option('server_type') eq 'dovecot_plain') {
+      $svchash->{_password} = '{PLAIN}' . $svchash->{_password};
+      
+    } elsif ($self->option('server_type') eq 'dovecot_crypt') {
+      my $salt = join '', ('.', '/', 0..9,'A'..'Z', 'a'..'z')[rand 64, rand 64];
+      $svchash->{_password} = '{CRYPT}' . crypt($svchash->{_password}, $salt);
+
+    } elsif ($self->option('server_type') eq 'dovecot_digest_md5') {
+      my $svc_domain = qsearchs('svc_domain', { svcnum => $svc->domsvc });
+      die('Unable to lookup svc_domain with domsvc: ' . $svc->domsvc)
+        unless ($svc_domain);
+
+      my $domain = $svc_domain->domain;
+      my $md5hash = '{DIGEST-MD5}' . md5_hex(join(':', $svchash->{username},
+                                             $domain, $svchash->{_password}));
+      $svchash->{_password} = $md5hash;
+    }
+  } elsif ($svcdb eq 'svc_forward') {
+    if ($self->option('resolve_dstsvc') && $svc->dstsvc_acct) {
+      $svchash->{dst} = $svc->dstsvc_acct->username . '@' .
+                        $svc->dstsvc_acct->svc_domain->domain;
+    }
+  }
+
+  return($svchash);
+
+}
+
index 3c781c0..8a8f9be 100644 (file)
@@ -8,6 +8,11 @@ use FS::part_export;
 
 sub rebless { shift; }
 
+sub export_username {
+  my($self, $svc_acct) = (shift, shift);
+  $svc_acct->username;
+}
+
 sub _export_insert {
   my($self, $svc_acct) = (shift, shift);
 
@@ -16,14 +21,14 @@ sub _export_insert {
     my %attrib = $svc_acct->$method();
     next unless keys %attrib;
     my $err_or_queue = $self->sqlradius_queue( $svc_acct->svcnum, 'insert',
-      $table, $svc_acct->username, %attrib );
+      $table, $self->export_username($svc_acct), %attrib );
     return $err_or_queue unless ref($err_or_queue);
   }
   my @groups = $svc_acct->radius_groups;
   if ( @groups ) {
     my $err_or_queue = $self->sqlradius_queue(
       $svc_acct->svcnum, 'usergroup_insert',
-      $svc_acct->username, @groups );
+      $self->export_username($svc_acct), @groups );
     return $err_or_queue unless ref($err_or_queue);
   }
   '';
@@ -44,9 +49,9 @@ sub _export_replace {
   my $dbh = dbh;
 
   my $jobnum = '';
-  if ( $old->username ne $new->username ) {
+  if ( $self->export_username($old) ne $self->export_username($new) ) {
     my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'rename',
-      $new->username, $old->username );
+      $self->export_username($new), $self->export_username($old) );
     unless ( ref($err_or_queue) ) {
       $dbh->rollback if $oldAutoCommit;
       return $err_or_queue;
@@ -63,7 +68,7 @@ sub _export_replace {
               } keys %new
     ) {
       my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'insert',
-        $table, $new->username, %new );
+        $table, $self->export_username($new), %new );
       unless ( ref($err_or_queue) ) {
         $dbh->rollback if $oldAutoCommit;
         return $err_or_queue;
@@ -80,7 +85,7 @@ sub _export_replace {
     my @del = grep { !exists $new{$_} } keys %old;
     if ( @del ) {
       my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'attrib_delete',
-        $table, $new->username, @del );
+        $table, $self->export_username($new), @del );
       unless ( ref($err_or_queue) ) {
         $dbh->rollback if $oldAutoCommit;
         return $err_or_queue;
@@ -109,7 +114,7 @@ sub _export_replace {
 
   if ( @delgroups ) {
     my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'usergroup_delete',
-      $new->username, @delgroups );
+      $self->export_username($new), @delgroups );
     unless ( ref($err_or_queue) ) {
       $dbh->rollback if $oldAutoCommit;
       return $err_or_queue;
@@ -125,7 +130,7 @@ sub _export_replace {
 
   if ( @newgroups ) {
     my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'usergroup_insert',
-      $new->username, @newgroups );
+      $self->export_username($new), @newgroups );
     unless ( ref($err_or_queue) ) {
       $dbh->rollback if $oldAutoCommit;
       return $err_or_queue;
@@ -147,7 +152,7 @@ sub _export_replace {
 sub _export_delete {
   my( $self, $svc_acct ) = (shift, shift);
   my $err_or_queue = $self->sqlradius_queue( $svc_acct->svcnum, 'delete',
-    $svc_acct->username );
+    $self->export_username($svc_acct) );
   ref($err_or_queue) ? '' : $err_or_queue;
 }
 
@@ -187,11 +192,15 @@ sub sqlradius_insert { #subroutine, not method
     } else {
 
       my $i_sth = $dbh->prepare(
-        "INSERT INTO rad$table ( id, UserName, Attribute, Value ) ".
+        "INSERT INTO rad$table ( UserName, Attribute, op, Value ) ".
           "VALUES ( ?, ?, ?, ? )"
       ) or die $dbh->errstr;
-      $i_sth->execute( '', $username, $attribute, $attributes{$attribute} )
-        or die $i_sth->errstr;
+      $i_sth->execute(
+        $username,
+        $attribute,
+        ( $attribute =~ /Password/i ? '==' : ':=' ),
+        $attributes{$attribute},
+      ) or die $i_sth->errstr;
 
     }
 
@@ -204,10 +213,10 @@ sub sqlradius_usergroup_insert { #subroutine, not method
   my( $username, @groups ) = @_;
 
   my $sth = $dbh->prepare( 
-    "INSERT INTO usergroup ( id, UserName, GroupName ) VALUES ( ?, ?, ? )"
+    "INSERT INTO usergroup ( UserName, GroupName ) VALUES ( ?, ? )"
   ) or die $dbh->errstr;
   foreach my $group ( @groups ) {
-    $sth->execute( '', $username, $group )
+    $sth->execute( $username, $group )
       or die "can't insert into groupname table: ". $sth->errstr;
   }
   $dbh->disconnect;
diff --git a/FS/FS/part_export/sqlradius_withdomain.pm b/FS/FS/part_export/sqlradius_withdomain.pm
new file mode 100644 (file)
index 0000000..1c8f38c
--- /dev/null
@@ -0,0 +1,12 @@
+package FS::part_export::sqlradius_withdomain;
+
+use vars qw(@ISA);
+use FS::part_export::sqlradius;
+
+@ISA = qw(FS::part_export::sqlradius);
+
+sub export_username {
+  my($self, $svc_acct) = (shift, shift);
+  $svc_acct->email;
+}
+
index 6a486fa..a505a0f 100644 (file)
@@ -1,6 +1,7 @@
 package FS::part_export::vpopmail;
 
-use vars qw(@ISA @saltset $exportdir $rsync $ssh);
+use vars qw(@ISA @saltset $exportdir);
+use Fcntl qw(:flock);
 use File::Path;
 use FS::UID qw( datasrc );
 use FS::part_export;
@@ -9,9 +10,6 @@ use FS::part_export;
 
 @saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
 
-$rsync = "rsync";
-$ssh = "ssh";
-
 sub rebless { shift; }
 
 sub _export_insert {
@@ -20,6 +18,8 @@ sub _export_insert {
     $svc_acct->username,
     crypt($svc_acct->_password,$saltset[int(rand(64))].$saltset[int(rand(64))]),
     $svc_acct->domain,
+    $svc_acct->quota,
+    $svc_acct->finger,
   );
 }
 
@@ -47,7 +47,7 @@ sub _export_replace {
   return '' unless $old->_password ne $new->_password;
 
   $self->vpopmail_queue( $new->svcnum, 'replace',
-    $new->username, $cpassword, $new->domain );
+    $new->username, $cpassword, $new->domain, $new->quota, $new->finger );
 }
 
 sub _export_delete {
@@ -59,25 +59,37 @@ sub _export_delete {
 #a good idea to queue anything that could fail or take any time
 sub vpopmail_queue {
   my( $self, $svcnum, $method ) = (shift, shift, shift);
+
   my $exportdir = "/usr/local/etc/freeside/export." . datasrc;
+  mkdir $exportdir, 0700 or die $! unless -d $exportdir;
+  $exportdir .= "/vpopmail";
+  mkdir $exportdir, 0700 or die $! unless -d $exportdir;
+  $exportdir .= '/'. $self->machine;
+  mkdir $exportdir, 0700 or die $! unless -d $exportdir;
+  mkdir "$exportdir/domains", 0700 or die $! unless -d "$exportdir/domains";
+
   my $queue = new FS::queue {
     'svcnum' => $svcnum,
     'job'    => "FS::part_export::vpopmail::vpopmail_$method",
   };
   $queue->insert(
     $exportdir,
-    $self->option('machine'),
+    $self->machine,
     $self->option('dir'),
     $self->option('uid'),
     $self->option('gid'),
+    $self->option('restart'),
     @_
   );
 }
 
 sub vpopmail_insert { #subroutine, not method
-  my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
-  my( $username, $password, $domain ) = @_;
-  
+  my( $exportdir, $machine, $dir, $uid, $gid, $restart ) = splice @_,0,6;
+  my( $username, $password, $domain, $quota, $finger ) = @_;
+
+  mkdir "$exportdir/domains/$domain", 0700 or die $!
+    unless -d "$exportdir/domains/$domain";
+
   (open(VPASSWD, ">>$exportdir/domains/$domain/vpasswd")
     and flock(VPASSWD,LOCK_EX)
   ) or die "can't open vpasswd file for $username\@$domain: ".
@@ -87,28 +99,28 @@ sub vpopmail_insert { #subroutine, not method
     $password,
     '1',
     '0',
-    $username,
+    $finger,
     "$dir/domains/$domain/$username",
-    'NOQUOTA',
+    $quota ? $quota.'S' : 'NOQUOTA',
   ), "\n";
 
   flock(VPASSWD,LOCK_UN);
   close(VPASSWD);
 
   for my $mkdir (
-    map { "$exportdir/domains/$domain/$username$_" }
-      ( '', qw( /Maildir /Maildir/cur /Maildir/new /Maildir/tmp ) )
+    grep { ! -d $_ } map { "$exportdir/domains/$domain/$username$_" }
+        ( '', qw( /Maildir /Maildir/cur /Maildir/new /Maildir/tmp ) )
   ) {
     mkdir $mkdir, 0700 or die "can't mkdir $mkdir: $!";
   }
 
-  vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid );
+  vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid, $restart );
 
 }
 
 sub vpopmail_replace { #subroutine, not method
-  my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
-  my( $username, $password, $domain ) = @_;
+  my( $exportdir, $machine, $dir, $uid, $gid, $restart ) = splice @_,0,6;
+  my( $username, $password, $domain, $quota, $finger ) = @_;
   
   (open(VPASSWD, "$exportdir/domains/$domain/vpasswd")
     and flock(VPASSWD,LOCK_EX)
@@ -118,10 +130,21 @@ sub vpopmail_replace { #subroutine, not method
     or die "Can't open $exportdir/domains/$domain/vpasswd.tmp: $!";
 
   while (<VPASSWD>) {
-    my ($mailbox, $pw, @rest) = split(':', $_);
-    print VPASSWDTMP $_ unless $username eq $mailbox;
-    print VPASSWDTMP join (':', ($mailbox, $password, @rest))
-      if $username eq $mailbox;
+    my ($mailbox, $pw, $vuid, $vgid, $vfinger, $vdir, $vquota, @rest) =
+      split(':', $_);
+    if ( $username ne $mailbox ) {
+      print VPASSWDTMP $_;
+      next
+    }
+    print VPASSWDTMP join (':',
+      $mailbox,
+      $password,
+      '1',
+      '0',
+      $finger,
+      "$dir/domains/$domain/$username", #$vdir
+      $quota ? $quota.'S' : 'NOQUOTA',
+    ), "\n";
   }
 
   close(VPASSWDTMP);
@@ -132,12 +155,12 @@ sub vpopmail_replace { #subroutine, not method
   flock(VPASSWD,LOCK_UN);
   close(VPASSWD);
 
-  vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid );
+  vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid, $restart );
 
 }
 
 sub vpopmail_delete { #subroutine, not method
-  my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
+  my( $exportdir, $machine, $dir, $uid, $gid, $restart ) = splice @_,0,6;
   my( $username, $domain ) = @_;
   
   (open(VPASSWD, "$exportdir/domains/$domain/vpasswd")
@@ -164,16 +187,40 @@ sub vpopmail_delete { #subroutine, not method
   rmtree "$exportdir/domains/$domain/$username"
     or die "can't rmtree $exportdir/domains/$domain/$username: $!";
 
-  vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid );
+  vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid, $restart );
 }
 
 sub vpopmail_sync {
-  my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
+  my( $exportdir, $machine, $dir, $uid, $gid, $restart ) = splice @_,0,6;
   
   chdir $exportdir;
-  my @args = ( $rsync, "-rlpt", "-e", $ssh, "domains/",
-               "vpopmail\@$machine:$dir/domains/"  );
-  system {$args[0]} @args;
+#  my @args = ( $rsync, "-rlpt", "-e", $ssh, "domains/",
+#               "vpopmail\@$machine:$dir/domains/"  );
+#  system {$args[0]} @args;
+
+  eval "use File::Rsync;";
+  die $@ if $@;
+
+  my $rsync = File::Rsync->new({ rsh => 'ssh' });
+
+  $rsync->exec( {
+    recursive => 1,
+    perms     => 1,
+    times     => 1,
+    src       => "$exportdir/domains/",
+    dest      => "vpopmail\@$machine:$dir/domains/",
+  } ); # true/false return value from exec is not working, alas
+  if ( $rsync->err ) {
+    die "error uploading to vpopmail\@$machine:$dir/domains/ : ".
+        'exit status: '. $rsync->status. ', '.
+        'STDERR: '. join(" / ", $rsync->err). ', '.
+        'STDOUT: '. join(" / ", $rsync->out);
+  }
+
+  eval "use Net::SSH qw(ssh);";
+  die $@ if $@;
+
+  ssh("vpopmail\@$machine", $restart) if $restart;
 }
 
 
index 84c1627..3e00874 100644 (file)
@@ -23,17 +23,13 @@ sub _export_command {
   my $command = $self->option($action);
 
   #set variable for the command
+  no strict 'vars';
   {
     no strict 'refs';
     ${$_} = $svc_www->getfield($_) foreach $svc_www->fields;
   }
   my $domain_record = $svc_www->domain_record; # or die ?
-  my $zone = $domain_record->reczone; # or die ?
-  unless ( $zone =~ /\.$/ ) {
-    my $svc_domain = $domain_record->svc_domain; # or die ?
-    $zone .= '.'. $svc_domain->domain;
-  }
-
+  my $zone = $domain_record->zone; # or die ?
   my $svc_acct = $svc_www->svc_acct; # or die ?
   my $username = $svc_acct->username;
   my $homedir = $svc_acct->dir; # or die ?
@@ -52,6 +48,7 @@ sub _export_replace {
   my $command = $self->option('usermod');
   
   #set variable for the command
+  no strict 'vars';
   {
     no strict 'refs';
     ${"old_$_"} = $old->getfield($_) foreach $old->fields;
@@ -99,7 +96,7 @@ sub shellcommands_queue {
 }
 
 sub ssh_cmd { #subroutine, not method
-  use Net::SSH '0.06';
+  use Net::SSH '0.08';
   &Net::SSH::ssh_cmd( { @_ } );
 }
 
index a0b19fd..33b5e5a 100644 (file)
@@ -115,7 +115,7 @@ sub check {
 
   #check options & values?
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =back
index e914636..dcce66b 100644 (file)
@@ -2,7 +2,7 @@ package FS::part_pkg;
 
 use strict;
 use vars qw( @ISA );
-use FS::Record qw( qsearch dbh );
+use FS::Record qw( qsearch dbh dbdef );
 use FS::pkg_svc;
 use FS::agent_type;
 use FS::type_pkgs;
@@ -180,6 +180,8 @@ insert and replace methods.
 sub check {
   my $self = shift;
 
+  for (qw(setup recur)) { $self->set($_=>0) if $self->get($_) =~ /^\s*$/; }
+
   my $conf = new FS::Conf;
   if ( $conf->exists('safe-part_pkg') ) {
 
@@ -218,6 +220,8 @@ sub check {
 
       or $r =~ /^my \$min = \$cust_pkg\->seconds_since\(\$cust_pkg\->bill \|\| 0\) \/ 60 \- \s*\d*\.?\d*\s*; \$min = 0 if \$min < 0; \s*\d*\.?\d*\s* \+ \s*\d*\.?\d*\s* \* \$min;\s*$/
 
+      or $r =~ /^my \$last_bill = \$cust_pkg\->last_bill; my \$hours = \$cust_pkg\->seconds_since_sqlradacct\(\$last_bill, \$sdate \) \/ 3600 - \s*\d\.?\d*\s*; \$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 \- \s*\d\.?\d*\s*; \$total = 0 if \$total < 0; my \$input = \$input - \s*\d\.?\d*\s*; \$input = 0 if \$input < 0; my \$output = \$output - \s*\d\.?\d*\s*; \$output = 0 if \$output < 0; \s*\d\.?\d*\s* \+ \s*\d\.?\d*\s* \* \$hours \+ \s*\d\.?\d*\s* \* \$input \+ \s*\d\.?\d*\s* \* \$output \+ \s*\d\.?\d*\s* \* \$total *;\s*$/
+
       or do {
         #log!
         return "illegal recur: $r";
@@ -225,11 +229,19 @@ sub check {
 
   }
 
+  if ( $self->dbdef_table->column('freq')->type =~ /(int)/i ) {
+    my $error = $self->ut_number('freq');
+    return $error if $error;
+  } else {
+    $self->freq =~ /^(\d+[dw]?)$/
+      or return "Illegal or empty freq: ". $self->freq;
+    $self->freq($1);
+  }
+
     $self->ut_numbern('pkgpart')
       || $self->ut_text('pkg')
       || $self->ut_text('comment')
       || $self->ut_anything('setup')
-      || $self->ut_number('freq')
       || $self->ut_anything('recur')
       || $self->ut_alphan('plan')
       || $self->ut_anything('plandata')
@@ -237,6 +249,7 @@ sub check {
       || $self->ut_enum('recurtax', [ '', 'Y' ] )
       || $self->ut_textn('taxclass')
       || $self->ut_enum('disabled', [ '', 'Y' ] )
+      || $self->SUPER::check
     ;
 }
 
@@ -254,20 +267,25 @@ sub pkg_svc {
 
 =item svcpart [ SVCDB ]
 
-Returns the svcpart of a single service definition (see L<FS::part_svc>)
+Returns the svcpart of the primary service definition (see L<FS::part_svc>)
 associated with this billing item definition (see L<FS::pkg_svc>).  Returns
-false if there not exactly one service definition with quantity 1, or if 
-SVCDB is specified and does not match the svcdb of the service definition, 
+false if there not a primary service definition or exactly one service
+definition with quantity 1, or if SVCDB is specified and does not match the
+svcdb of the service definition, 
 
 =cut
 
 sub svcpart {
   my $self = shift;
-  my $svcdb = shift;
-  my @pkg_svc = $self->pkg_svc;
-  return '' if scalar(@pkg_svc) != 1
-               || $pkg_svc[0]->quantity != 1
-               || ( $svcdb && $pkg_svc[0]->part_svc->svcdb ne $svcdb );
+  my $svcdb = scalar(@_) ? shift : '';
+  my @svcdb_pkg_svc =
+    grep { ( $svcdb eq $_->part_svc->svcdb || !$svcdb ) } $self->pkg_svc;
+  my @pkg_svc = ();
+  @pkg_svc = grep { $_->primary_svc =~ /^Y/i } @svcdb_pkg_svc
+    if dbdef->table('pkg_svc')->column('primary_svc');
+  @pkg_svc = grep {$_->quantity == 1 } @svcdb_pkg_svc
+    unless @pkg_svc;
+  return '' if scalar(@pkg_svc) != 1;
   $pkg_svc[0]->svcpart;
 }
 
@@ -280,6 +298,8 @@ following logic instead;
 If the package has B<0> setup and B<0> recur, the single item B<BILL> is
 returned, otherwise, the single item B<CARD> is returned.
 
+(CHEK?  LEC?  Probably shouldn't accept those by default, prone to abuse)
+
 =cut
 
 sub payby {
@@ -295,10 +315,6 @@ sub payby {
 
 =back
 
-=head1 VERSION
-
-$Id: part_pkg.pm,v 1.16 2002-06-10 01:39:50 khoff Exp $
-
 =head1 BUGS
 
 The delete method is unimplemented.
index 0b7cdf6..f7d5eac 100644 (file)
@@ -92,6 +92,7 @@ sub check {
       or $self->ut_text('state')
       or $self->ut_number('npa')
       or $self->ut_number('nxx')
+      or $self->SUPER::check
   ;
 
 }
@@ -100,7 +101,7 @@ sub check {
 
 =head1 VERSION
 
-$Id: part_pop_local.pm,v 1.1 2001-09-26 09:17:06 ivan Exp $
+$Id: part_pop_local.pm,v 1.2 2003-08-05 00:20:44 khoff Exp $
 
 =head1 BUGS
 
index 23885df..c0858c0 100644 (file)
@@ -38,6 +38,8 @@ The following fields are currently supported:
 
 =item referral - Text name of this advertising source
 
+=item disabled - Disabled flag, empty or 'Y'
+
 =back
 
 =head1 NOTE
@@ -91,9 +93,17 @@ replace methods.
 sub check {
   my $self = shift;
 
-  $self->ut_numbern('refnum')
+  my $error = $self->ut_numbern('refnum')
     || $self->ut_text('referral')
   ;
+  return $error if $error;
+
+  if ( $self->dbdef_table->column('disabled') ) {
+    $error = $self->ut_enum('disabled', [ '', 'Y' ] );
+    return $error if $error;
+  }
+
+  $self->SUPER::check;
 }
 
 =back
index 959a3f8..aacc3ab 100644 (file)
@@ -68,7 +68,7 @@ TODOC:
 
 =item I<svcdb>__I<field> - Default or fixed value for I<field> in I<svcdb>.
 
-=item I<svcdb>__I<field>_flag - defines I<svcdb>__I<field> action: null, `D' for default, or `F' for fixed
+=item I<svcdb>__I<field>_flag - defines I<svcdb>__I<field> action: null, `D' for default, or `F' for fixed.  For virtual fields, can also be 'X' for excluded.
 
 TODOC: EXTRA_FIELDS_ARRAYREF
 
@@ -113,7 +113,7 @@ sub insert {
     } );
 
     my $flag = $self->getfield($svcdb.'__'.$field.'_flag');
-    if ( uc($flag) =~ /^([DF])$/ ) {
+    if ( uc($flag) =~ /^([DFX])$/ ) {
       $part_svc_column->setfield('columnflag', $1);
       $part_svc_column->setfield('columnvalue',
         $self->getfield($svcdb.'__'.$field)
@@ -201,7 +201,7 @@ sub replace {
       } );
 
       my $flag = $new->getfield($svcdb.'__'.$field.'_flag');
-      if ( uc($flag) =~ /^([DF])$/ ) {
+      if ( uc($flag) =~ /^([DFX])$/ ) {
         $part_svc_column->setfield('columnflag', $1);
         $part_svc_column->setfield('columnvalue',
           $new->getfield($svcdb.'__'.$field)
@@ -254,32 +254,7 @@ sub check {
   my @fields = eval { fields( $recref->{svcdb} ) }; #might die
   return "Unknown svcdb!" unless @fields;
 
-##REPLACED BY part_svc_column
-#  my $svcdb;
-#  foreach $svcdb ( qw(
-#    svc_acct svc_acct_sm svc_domain
-#  ) ) {
-#    my @rows = map { /^${svcdb}__(.*)$/; $1 }
-#      grep ! /_flag$/,
-#        grep /^${svcdb}__/,
-#          fields('part_svc');
-#    foreach my $row (@rows) {
-#      unless ( $svcdb eq $recref->{svcdb} ) {
-#        $recref->{$svcdb.'__'.$row}='';
-#        $recref->{$svcdb.'__'.$row.'_flag'}='';
-#        next;
-#      }
-#      $recref->{$svcdb.'__'.$row.'_flag'} =~ /^([DF]?)$/
-#        or return "Illegal flag for $svcdb $row";
-#      $recref->{$svcdb.'__'.$row.'_flag'} = $1;
-#
-#      my $error = $self->ut_anything($svcdb.'__'.$row);
-#      return $error if $error;
-#
-#    }
-#  }
-
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item part_svc_column COLUMNNAME
@@ -290,12 +265,12 @@ COLUMNNAME, or a new part_svc_column object if none exists.
 =cut
 
 sub part_svc_column {
-  my $self = shift;
-  my $columnname = shift;
-  qsearchs('part_svc_column',  {
-                                 'svcpart'    => $self->svcpart,
-                                 'columnname' => $columnname,
-                               }
+  my( $self, $columnname) = @_;
+  $self->svcpart &&
+    qsearchs('part_svc_column',  {
+                                   'svcpart'    => $self->svcpart,
+                                   'columnname' => $columnname,
+                                 }
   ) or new FS::part_svc_column {
                                  'svcpart'    => $self->svcpart,
                                  'columnname' => $columnname,
@@ -311,22 +286,23 @@ sub all_part_svc_column {
   qsearch('part_svc_column', { 'svcpart' => $self->svcpart } );
 }
 
-=item part_export
+=item part_export [ EXPORTTYPE ]
+
+Returns all exports (see L<FS::part_export>) for this service, or, if an
+export type is specified, only returns exports of the given type.
 
 =cut
 
 sub part_export {
   my $self = shift;
-  map { qsearchs('part_export', { 'exportnum' => $_->exportnum } ) }
+  my %search;
+  $search{'exporttype'} = shift if @_;
+  map { qsearchs('part_export', { 'exportnum' => $_->exportnum, %search } ) }
     qsearch('export_svc', { 'svcpart' => $self->svcpart } );
 }
 
 =back
 
-=head1 VERSION
-
-$Id: part_svc.pm,v 1.13 2002-04-11 22:05:31 ivan Exp $
-
 =head1 BUGS
 
 Delete is unimplemented.
@@ -334,7 +310,7 @@ Delete is unimplemented.
 The list of svc_* tables is hardcoded.  When svc_acct_pop is renamed, this
 should be fixed.
 
-all_part_svc_column and part_export methods should be documented
+all_part_svc_column method should be documented
 
 =head1 SEE ALSO
 
index 37e841e..885155b 100644 (file)
@@ -41,7 +41,7 @@ fields are currently supported:
 
 =item columnvalue - default or fixed value for the column
 
-=item columnflag - null, D or F
+=item columnflag - null, D, F, X (virtual fields)
 
 =back
 
@@ -91,18 +91,18 @@ sub check {
   ;
   return $error if $error;
 
-  $self->columnflag =~ /^([DF])$/
+  $self->columnflag =~ /^([DFX])$/
     or return "illegal columnflag ". $self->columnflag;
   $self->columnflag(uc($1));
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =back
 
 =head1 VERSION
 
-$Id: part_svc_column.pm,v 1.1 2001-09-07 20:49:15 ivan Exp $
+$Id: part_svc_column.pm,v 1.2 2003-08-05 00:20:44 khoff Exp $
 
 =head1 BUGS
 
diff --git a/FS/FS/part_svc_router.pm b/FS/FS/part_svc_router.pm
new file mode 100755 (executable)
index 0000000..0b23ab5
--- /dev/null
@@ -0,0 +1,32 @@
+package FS::part_svc_router;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record qw(qsearchs);
+use FS::router;
+use FS::part_svc;
+
+@ISA = qw(FS::Record);
+
+sub table { 'part_svc_router'; }
+
+sub check {
+  my $self = shift;
+  my $error =
+    $self->ut_foreign_key('svcpart', 'part_svc', 'svcpart')
+    || $self->ut_foreign_key('routernum', 'router', 'routernum');
+  return $error if $error;
+  ''; #no error
+}
+
+sub router {
+  my $self = shift;
+  return qsearchs('router', { routernum => $self->routernum });
+}
+
+sub part_svc {
+  my $self = shift;
+  return qsearchs('part_svc', { svcpart => $self->svcpart });
+}
+
+1;
diff --git a/FS/FS/part_virtual_field.pm b/FS/FS/part_virtual_field.pm
new file mode 100755 (executable)
index 0000000..03c34cc
--- /dev/null
@@ -0,0 +1,303 @@
+package FS::part_virtual_field;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record qw( qsearchs qsearch dbdef );
+
+@ISA = qw( FS::Record );
+
+=head1 NAME
+
+FS::part_virtual_field - Object methods for part_virtual_field records
+
+=head1 SYNOPSIS
+
+  use FS::part_virtual_field;
+
+  $record = new FS::part_virtual_field \%hash;
+  $record = new FS::part_virtual_field { 'column' => 'value' };
+
+  $error = $record->insert;
+
+  $error = $new_record->replace($old_record);
+
+  $error = $record->delete;
+
+  $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::part_virtual_field object represents the definition of a virtual field 
+(see the BACKGROUND section).  FS::part_virtual_field contains the name and 
+base table of the field, as well as validation rules and UI hints about the 
+display of the field.  The actual data is stored in FS::virtual_field; see 
+its manpage for details.
+
+FS::part_virtual_field inherits from FS::Record.  The following fields are 
+currently supported:
+
+=over 2
+
+=item vfieldpart - primary key (assigned automatically)
+
+=item name - name of the field
+
+=item dbtable - table for which this virtual field is defined
+
+=item check_block - Perl code to validate/normalize data
+
+=item list_source - Perl code to generate a list of values (UI hint)
+
+=item length - expected length of the value (UI hint)
+
+=item label - descriptive label for the field (UI hint)
+
+=item sequence - sort key (UI hint; unimplemented)
+
+=back
+
+=head1 BACKGROUND
+
+"Form is none other than emptiness,
+ and emptiness is none other than form."
+-- Heart Sutra
+
+The virtual field mechanism allows site admins to make trivial changes to 
+the Freeside database schema without modifying the code.  Specifically, the 
+user can add custom-defined 'fields' to the set of data tracked by Freeside 
+about objects such as customers and services.  These fields are not associated 
+with any logic in the core Freeside system, but may be referenced in peripheral 
+code such as exports, price calculations, or alternate interfaces, or may just 
+be stored in the database for future reference.
+
+This system was originally devised for svc_broadband, which (by necessity) 
+comprises such a wide range of access technologies that no static set of fields 
+could contain all the information needed by the exports.  In an appalling 
+display of False Laziness, a parallel mechanism was implemented for the 
+router table, to store properties such as passwords to configure routers.
+
+The original system treated svc_broadband custom fields (sb_fields) as records 
+in a completely separate table.  Any code that accessed or manipulated these 
+fields had to be aware that they were I<not> fields in svc_broadband, but 
+records in sb_field.  For example, code that inserted a svc_broadband with 
+several custom fields had to create an FS::svc_broadband object, call its 
+insert() method, and then create several FS::sb_field objects and call I<their>
+insert() methods.
+
+This created a problem for exports.  The insert method on any FS::svc_Common 
+object (including svc_broadband) automatically triggers exports after the 
+record has been inserted.  However, at this point, the sb_fields had not yet 
+been inserted, so the export could not rely on their presence, which was the 
+original purpose of sb_fields.
+
+Hence the new system.  Virtual fields are appended to the field list of every 
+record at the FS::Record level, whether the object is created ex nihilo with 
+new() or fetched with qsearch().  The fields() method now returns a list of 
+both real and virtual fields.  The insert(), replace(), and delete() methods 
+now update both the base table and the virtual fields, in a single transaction.
+
+A new method is provided, virtual_fields(), which gives only the virtual 
+fields.  UI code that dynamically generates form widgets to edit virtual field
+data should use this to figure out what fields are defined.  (See below.)
+
+Subclasses may override virtual_fields() to restrict the set of virtual 
+fields available.  Some discipline and sanity on the part of the programmer 
+are required; in particular, this function should probably not depend on any 
+fields in the record other than the primary key, since the others may change 
+after the object is instantiated.  (Making it depend on I<virtual> fields is 
+just asking for pain.)  One use of this is seen in FS::svc_Common; another 
+possibility is field-level access control based on FS::UID::getotaker().
+
+As a trivial case, a subclass may opt out of supporting virtual fields with 
+the following code:
+
+sub virtual_fields { () }
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Create a new record.  To add the record to the database, see "insert".
+
+=cut
+
+sub table { 'part_virtual_field'; }
+sub virtual_fields { () }
+
+=item insert
+
+Adds this record to the database.  If there is an error, returns the error,
+otherwise returns false.
+
+=item delete
+
+Deletes this record from the database.  If there is an error, returns the
+error, otherwise returns false.
+
+=item replace OLD_RECORD
+
+Replaces OLD_RECORD with this one in the database.  If there is an error,
+returns the error, otherwise returns false.
+
+=item check
+
+If there is an error, returns the error, otherwise returns false.
+Called by the insert and replace methods.
+
+=back
+
+=cut
+
+sub check {
+  my $self = shift;
+
+  my $error = $self->ut_text('name') ||
+              $self->ut_text('dbtable') ||
+              $self->ut_number('length')
+              ;
+  return $error if $error;
+
+  # Make sure it's a real table with a numeric primary key
+  my ($table, $pkey);
+  if($table = $FS::Record::dbdef->table($self->dbtable)) {
+    if($pkey = $table->primary_key) {
+      if($table->column($pkey)->type =~ /int/i) {
+        # this is what it should be
+      } else {
+        $error = "$table.$pkey is not an integer";
+      }
+    } else {
+      $error = "$table does not have a single-field primary key";
+    }
+  } else {
+    $error = "$table does not exist in the schema";
+  }
+  return $error if $error;
+
+  # Possibly some sanity checks for check_block and list_source?
+
+  $self->SUPER::check;  
+}
+
+=item list
+
+Evaluates list_source.
+
+=cut
+
+sub list {
+  my $self = shift;
+  return () unless $self->list_source;
+
+  my @opts = eval($self->list_source);
+  if($@) {
+    warn $@;
+    return ();
+  } else {
+    return @opts;
+  }
+}
+
+=item widget UI_TYPE MODE [ VALUE ]
+
+Generates UI code for a widget suitable for editing/viewing the field, based on 
+list_source and length.  
+
+The only UI_TYPE currently supported is 'HTML', and the only MODE is 'view'.
+Others will be added later.
+
+In HTML, all widgets are assumed to be table rows.  View widgets look like
+<TR><TD ALIGN="right">Label</TD><TD BGCOLOR="#ffffff">Value</TD></TR>
+
+(Most of the display style stuff, such as the colors, should probably go into 
+a separate module specific to the UI.  That can wait, though.  The API for 
+this function won't change.)
+
+VALUE (optional) is the current value of the field.
+
+=cut
+
+sub widget {
+  my $self = shift;
+  my ($ui_type, $mode, $value) = @_;
+  my $text;
+  my $label = $self->label || $self->name;
+
+  if ($ui_type eq 'HTML') {
+    if ($mode eq 'view') {
+      $text = q!<TR><TD ALIGN="right">! . $label . 
+              q!</TD><TD BGCOLOR="#ffffff">! . $value .
+              q!</TD></TR>! . "\n";
+    } elsif ($mode eq 'edit') {
+      $text = q!<TR><TD ALIGN="right">! . $label .
+              q!</TD><TD>!;
+      if ($self->list_source) {
+        $text .= q!<SELECT NAME="! . $self->name . 
+                q!" SIZE=1>! . "\n";
+        foreach ($self->list) {
+          $text .= q!<OPTION VALUE="! . $_ . q!"!;
+          $text .= ' SELECTED' if ($_ eq $value);
+          $text .= '>' . $_ . '</OPTION>' . "\n";
+        }
+      } else {
+        $text .= q!<INPUT NAME="! . $self->name .
+                q!" VALUE="! . $value . q!"!;
+        if ($self->length) {
+          $text .= q! SIZE="! . $self->length . q!"!;
+        }
+        $text .= '>';
+      }
+      $text .= q!</TD></TR>! . "\n";
+    } else {
+      return '';
+    }
+  } else {
+    return '';
+  }
+  return $text;
+}
+
+=head1 VERSION
+
+$Id: part_virtual_field.pm,v 1.2 2003-08-05 00:20:45 khoff Exp $
+
+=head1 NOTES
+
+=head2 Semantics of check_block:
+
+This has been changed from the sb_field implementation to make check_blocks 
+simpler and more natural to Perl programmers who work on things other than 
+Freeside.
+
+The check_block is eval'd with the (proposed) new value of the field in $_, 
+and the object to be updated in $self.  Its return value is ignored.  The 
+check_block may change the value of $_ to override the proposed value, or 
+call die() (with an appropriate error message) to reject the update entirely;
+the error string will be returned as the output of the check() method.
+
+This makes check_blocks like
+
+C<s/foo/bar/>
+
+do what you expect.
+
+The check_block is expected NOT to do anything freaky to $self, like modifying 
+other fields or calling $self->check().  You have been warned.
+
+(FIXME: Rewrite some of the warnings from part_sb_field and insert here.)
+
+=head1 BUGS
+
+None.  It's absolutely falwless.
+
+=head1 SEE ALSO
+
+L<FS::Record>, L<FS::virtual_field>
+
+=cut
+
+1;
+
+
index 3c544ff..ea52176 100644 (file)
@@ -46,6 +46,8 @@ FS::Record.  The following fields are currently supported:
 =item quantity - Quantity of this service definition that this billing item
 definition includes
 
+=item primary_svc - primary flag, empty or 'Y'
+
 =back
 
 =head1 METHODS
@@ -108,7 +110,12 @@ sub check {
   return "Unknown pkgpart!" unless $self->part_pkg;
   return "Unknown svcpart!" unless $self->part_svc;
 
-  ''; #no error
+  if ( $self->dbdef_table->column('primary_svc') ) {
+    $error = $self->ut_enum('primary_svc', [ '', 'Y' ] );
+    return $error if $error;
+  }
+
+  $self->SUPER::check;
 }
 
 =item part_pkg
@@ -135,10 +142,6 @@ sub part_svc {
 
 =back
 
-=head1 VERSION
-
-$Id: pkg_svc.pm,v 1.3 2002-06-10 01:39:50 khoff Exp $
-
 =head1 BUGS
 
 =head1 SEE ALSO
index 13455ca..620030a 100644 (file)
@@ -113,7 +113,7 @@ sub check {
     unless $self->ip || $self->nasport;
   return "Unknown nasnum"
     unless qsearchs('nas', { 'nasnum' => $self->nasnum } );
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item session
@@ -133,7 +133,7 @@ sub session {
 
 =head1 VERSION
 
-$Id: port.pm,v 1.5 2001-02-14 04:33:06 ivan Exp $
+$Id: port.pm,v 1.6 2003-08-05 00:20:45 khoff Exp $
 
 =head1 BUGS
 
index 7ed9b83..a9d26d1 100644 (file)
@@ -108,6 +108,7 @@ sub check {
   || $self->ut_alpha('identifier')
   || $self->ut_money('amount')
   || $self->utnumbern('seconds')
+  || $self->SUPER::check
   ;
 
 }
index d35dc88..634f7f4 100644 (file)
@@ -207,7 +207,7 @@ sub check {
   $self->status('new') unless $self->status;
   $self->_date(time) unless $self->_date;
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item args
@@ -385,7 +385,7 @@ END
 
 =head1 VERSION
 
-$Id: queue.pm,v 1.15 2002-07-02 06:48:59 ivan Exp $
+$Id: queue.pm,v 1.16 2003-08-05 00:20:46 khoff Exp $
 
 =head1 BUGS
 
index 08fe473..d23ee2a 100644 (file)
@@ -100,14 +100,14 @@ sub check {
   ;
   return $error if $error;
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =back
 
 =head1 VERSION
 
-$Id: queue_arg.pm,v 1.1 2001-09-11 00:08:18 ivan Exp $
+$Id: queue_arg.pm,v 1.2 2003-08-05 00:20:46 khoff Exp $
 
 =head1 BUGS
 
index 4a4e3c5..bc910d8 100644 (file)
@@ -103,6 +103,7 @@ sub check {
   $self->ut_numbern('dependnum')
     || $self->ut_foreign_key('jobnum',        'queue', 'jobnum')
     || $self->ut_foreign_key('depend_jobnum', 'queue', 'jobnum')
+    || $self->SUPER::check
   ;
 }
 
index 497d984..efeb739 100644 (file)
@@ -2,1090 +2,1598 @@ package FS::raddb;
 use vars qw(%attrib);
 
 %attrib = (
-  'ascend_bi_directional_au' => 'Ascend-Bi-Directional-Auth',
-  'h323_connect_time' => 'h323-connect-time',
-  'connect_rate' => 'Connect-Rate',
-  'bind_auth_service_grp' => 'Bind_Auth_Service_Grp',
-  'usr_callback_type' => 'USR-Callback-Type',
-  'erx_primary_wins' => 'ERX-Primary-Wins',
-  'ascend_x25_x121_address' => 'Ascend-X25-X121-Address',
-  'usr_log_filter_packets' => 'USR-Log-Filter-Packets',
-  'annex_addr_resolution_pr' => 'Annex-Addr-Resolution-Protocol',
-  'usr_ip_rip_simple_auth_p' => 'USR-IP-RIP-Simple-Auth-Password',
-  'dialback_name' => 'Dialback-Name',
-  'x_ascend_fr_dce_n392' => 'X-Ascend-FR-DCE-N392',
-  'usr_host_type' => 'USR-Host-Type',
-  'le_modem_info' => 'LE-Modem-Info',
-  'x_ascend_menu_selector' => 'X-Ascend-Menu-Selector',
-  'x_ascend_fr_dce_n393' => 'X-Ascend-FR-DCE-N393',
-  'ascend_ip_direct' => 'Ascend-IP-Direct',
-  'x_ascend_pre_output_octe' => 'X-Ascend-Pre-Output-Octets',
-  'x_ascend_ft1_caller' => 'X-Ascend-FT1-Caller',
-  'usr_last_callers_number_' => 'USR-Last-Callers-Number-ANI',
-  'usr_rmmie_product_code' => 'USR-RMMIE-Product-Code',
-  'usr_igmp_robustness' => 'USR-IGMP-Robustness',
-  'ms_chap2_success' => 'MS-CHAP2-Success',
-  'ascend_home_agent_passwo' => 'Ascend-Home-Agent-Password',
-  'acc_bridging_support' => 'Acc-Bridging-Support',
-  'annex_transmit_speed' => 'Annex-Transmit-Speed',
-  'old_password' => 'Old-Password',
-  'x_ascend_metric' => 'X-Ascend-Metric',
-  'acc_clearing_location' => 'Acc-Clearing-Location',
-  'ascend_multilink_id' => 'Ascend-Multilink-ID',
-  'ascend_egress_enabled' => 'Ascend-Egress-Enabled',
-  'usr_bridging' => 'USR-Bridging',
-  'ascend_assign_ip_server' => 'Ascend-Assign-IP-Server',
-  'acc_dns_server_sec' => 'Acc-Dns-Server-Sec',
-  'ascend_home_agent_ip_add' => 'Ascend-Home-Agent-IP-Addr',
-  'usr_dnis_reauthenticatio' => 'USR-DNIS-ReAuthentication',
-  'acc_modem_error_protocol' => 'Acc-Modem-Error-Protocol',
-  'ascend_backup' => 'Ascend-Backup',
-  'usr_connect_time' => 'USR-Connect-Time',
-  'ascend_cbcp_mode' => 'Ascend-CBCP-Mode',
-  'usr_rmmie_x2_status' => 'USR-RMMIE-x2-Status',
-  'ascend_multicast_gleave_' => 'Ascend-Multicast-GLeave-Delay',
-  'erx_ingress_statistics' => 'ERX-Ingress-Statistics',
-  'cisco_nas_port' => 'Cisco-NAS-Port',
-  'le_admin_group' => 'LE-Admin-Group',
-  'annex_mrru' => 'Annex-MRRU',
-  'x_ascend_add_seconds' => 'X-Ascend-Add-Seconds',
-  'ascend_token_expiry' => 'Ascend-Token-Expiry',
-  'usr_igmp_maximum_respons' => 'USR-IGMP-Maximum-Response-Time',
-  'ascend_calling_id_presen' => 'Ascend-Calling-Id-Presentatn',
-  'connect_info' => 'Connect-Info',
-  'ascend_access_intercept_' => 'Ascend-Access-Intercept-LEA',
-  'x_ascend_dba_monitor' => 'X-Ascend-DBA-Monitor',
-  'client_dns_pri' => 'Client_DNS_Pri',
-  'ip_host_addr' => 'Ip_Host_Addr',
-  'callback_id' => 'Callback-Id',
-  'acct_mcast_out_octets' => 'Acct_Mcast_Out_Octets',
-  'acct_input_octets_64' => 'Acct_Input_Octets_64',
-  'tunnel_function' => 'Tunnel_Function',
-  'ascend_fr_direct_profile' => 'Ascend-FR-Direct-Profile',
-  'h323_incoming_conf_id' => 'h323-incoming-conf-id',
-  'ascend_ppp_vj_1172' => 'Ascend-PPP-VJ-1172',
-  'ms_new_arap_password' => 'MS-New-ARAP-Password',
-  'h323_voice_quality' => 'h323-voice-quality',
-  'framed_appletalk_network' => 'Framed-AppleTalk-Network',
-  'bind_int_interface_name' => 'Bind_Int_Interface_Name',
-  'event_timestamp' => 'Event-Timestamp',
-  'ascend_bir_enable' => 'Ascend-BIR-Enable',
-  'usr_fallback_enabled' => 'USR-Fallback-Enabled',
-  'ascend_dhcp_pool_number' => 'Ascend-DHCP-Pool-Number',
-  'acct_session_id' => 'Acct-Session-Id',
-  'ascend_private_route_req' => 'Ascend-Private-Route-Required',
-  'usr_rmmie_pwrlvl_farecho' => 'USR-RMMIE-PwrLvl-FarEcho-Canc',
-  'usr_at_input_filter' => 'USR-AT-Input-Filter',
-  'erx_egress_statistics' => 'ERX-Egress-Statistics',
-  'x_ascend_call_type' => 'X-Ascend-Call-Type',
-  'acct_tunnel_client_endpo' => 'Acct-Tunnel-Client-Endpoint',
-  'x_ascend_assign_ip_clien' => 'X-Ascend-Assign-IP-Client',
-  'ascend_if_netmask' => 'Ascend-IF-Netmask',
-  'ascend_dhcp_maximum_leas' => 'Ascend-DHCP-Maximum-Leases',
-  'usr_at_output_filter' => 'USR-AT-Output-Filter',
-  'usr_rad_dvmrp_metric' => 'USR-Rad-Dvmrp-Metric',
-  'rate_limit_rate' => 'Rate_Limit_Rate',
-  'prefix' => 'Prefix',
-  'ascend_x25_pad_banner' => 'Ascend-X25-Pad-Banner',
-  'usr_rmmie_rcv_pwrlvl_375' => 'USR-RMMIE-Rcv-PwrLvl-3750Hz',
-  'x_ascend_user_acct_key' => 'X-Ascend-User-Acct-Key',
-  'group_name' => 'Group-Name',
-  'ascend_receive_secret' => 'Ascend-Receive-Secret',
-  'reply_message' => 'Reply-Message',
-  'le_nat_sess_dir_fail_act' => 'LE-NAT-Sess-Dir-Fail-Action',
-  'framed_callback_id' => 'Framed-Callback-Id',
-  'cisco_disconnect_cause' => 'Cisco-Disconnect-Cause',
-  'stripped_user_name' => 'Stripped-User-Name',
-  'annex_keypress_timeout' => 'Annex-Keypress-Timeout',
-  'annex_receive_speed' => 'Annex-Receive-Speed',
-  'ms_chap_domain' => 'MS-CHAP-Domain',
-  'ascend_atm_connect_group' => 'Ascend-ATM-Connect-Group',
-  'usr_send_name' => 'USR-Send-Name',
-  'usr_local_framed_ip_addr' => 'USR-Local-Framed-IP-Addr',
-  'erx_alternate_cli_vroute' => 'ERX-Alternate-Cli-Vrouter-Name',
-  'usr_fallback_limit' => 'USR-Fallback-Limit',
-  'ascend_pri_number_type' => 'Ascend-PRI-Number-Type',
-  'x_ascend_minimum_channel' => 'X-Ascend-Minimum-Channels',
-  'x_ascend_fr_direct_dlci' => 'X-Ascend-FR-Direct-DLCI',
-  'ascend_fr_link_mgt' => 'Ascend-FR-Link-Mgt',
-  'annex_host_allow' => 'Annex-Host-Allow',
-  'x_ascend_force_56' => 'X-Ascend-Force-56',
-  'police_burst' => 'Police_Burst',
-  'pvc_profile_name' => 'PVC_Profile_Name',
+  'usr_at_zip_output_filter' => 'USR-AT-Zip-Output-Filter',
   'ms_filter' => 'MS-Filter',
-  'rate_limit_burst' => 'Rate_Limit_Burst',
-  'ascend_number_sessions' => 'Ascend-Number-Sessions',
-  'cisco_call_filter' => 'Cisco-Call-Filter',
-  'erx_igmp_enable' => 'ERX-Igmp-Enable',
-  'ascend_filter_required' => 'Ascend-Filter-Required',
-  'erx_cli_allow_all_vr_acc' => 'ERX-Cli-Allow-All-VR-Access',
-  'acc_callback_delay' => 'Acc-Callback-Delay',
-  'usr_default_dte_data_rat' => 'USR-Default-DTE-Data-Rate',
+  'annex_compression_protoc' => 'Annex-Compression-Protocol',
+  'xedia_ssh_privileges' => 'Xedia-SSH-Privileges',
+  'usr_blocks_received' => 'USR-Blocks-Received',
+  'shiva_called_number' => 'Shiva-Called-Number',
+  'annex_filter' => 'Annex-Filter',
+  'usr_channel_expansion' => 'USR-Channel-Expansion',
+  'erx_tunnel_tos' => 'ERX-Tunnel-Tos',
+  'session_timeout' => 'Session-Timeout',
+  'ascend_route_ipx' => 'Ascend-Route-IPX',
+  'annex_error_correction_p' => 'Annex-Error-Correction-Prot',
+  'acc_callback_mode' => 'Acc-Callback-Mode',
+  'usr_filter_zones' => 'USR-Filter-Zones',
+  'erx_input_gigapkts' => 'ERX-Input-Gigapkts',
+  'ascend_session_svr_key' => 'Ascend-Session-Svr-Key',
+  'bind_l2tp_tunnel_namf' => 'Bind_L2TP_Tunnel_Name',
+  'ascend_dsl_cir_recv_limi' => 'Ascend-Dsl-CIR-Recv-Limit',
+  'altiga_secondary_wins_g' => 'Altiga-Secondary-WINS-G',
+  'ascend_ts_idle_limit' => 'Ascend-TS-Idle-Limit',
+  'usr_port_tap_priority' => 'USR-Port-Tap-Priority',
+  'cvpn3000_ipsec_client_fw' => 'CVPN3000-IPSec-Client-Fw-Filter-Name',
+  'ascend_private_route_req' => 'Ascend-Private-Route-Required',
+  'ascend_private_route' => 'Ascend-Private-Route',
+  'prompt' => 'Prompt',
+  'acct_link_count' => 'Acct-Link-Count',
+  'bind_auth_service_grq' => 'Bind_Auth_Service_Grp',
+  'itk_tunnel_ip' => 'ITK-Tunnel-IP',
+  'login_lat_node' => 'Login-LAT-Node',
+  'usr_mbi_ct_pri_card_slot' => 'USR-Mbi_Ct_PRI_Card_Slot',
+  'lac_real_poru' => 'LAC_Real_Port',
+  'erx_ingress_statistics' => 'ERX-Ingress-Statistics',
+  'digest_nonce' => 'Digest-Nonce',
+  'annex_system_disc_reason' => 'Annex-System-Disc-Reason',
+  'pool_name' => 'Pool-Name',
+  'altiga_use_client_addres' => 'Altiga-Use-Client-Address-G/U',
+  'police_bursu' => 'Police_Burst',
+  'usr_call_arrival_time' => 'USR-Call-Arrival-Time',
+  'ascend_disconnect_cause' => 'Ascend-Disconnect-Cause',
+  'ascend_user_acct_time' => 'Ascend-User-Acct-Time',
+  'chap_challenge' => 'CHAP-Challenge',
+  'ascend_mpp_idle_percent' => 'Ascend-MPP-Idle-Percent',
+  'ascend_user_acct_port' => 'Ascend-User-Acct-Port',
+  'ldap_group' => 'Ldap-Group',
+  'ascend_numbering_plan_id' => 'Ascend-Numbering-Plan-ID',
+  'usr_last_number_dialed_o' => 'USR-Last-Number-Dialed-Out',
+  'pvc_encapsulation_type' => 'PVC-Encapsulation-Type',
+  'ascend_bir_bridge_group' => 'Ascend-BIR-Bridge-Group',
+  'ascend_atm_group' => 'Ascend-ATM-Group',
+  'ascend_fr_svc_addr' => 'Ascend-FR-SVC-Addr',
+  'x_ascend_send_auth' => 'X-Ascend-Send-Auth',
   'le_ip_pool' => 'LE-IP-Pool',
-  'cisco_pre_output_packets' => 'Cisco-Pre-Output-Packets',
-  'x_ascend_group' => 'X-Ascend-Group',
-  'usr_channel_connected_to' => 'USR-Channel-Connected-To',
-  'usr_ipx_rip_output_filte' => 'USR-IPX-RIP-Output-Filter',
-  'usr_esn' => 'USR-ESN',
-  'annex_user_level' => 'Annex-User-Level',
-  'x_ascend_primary_home_ag' => 'X-Ascend-Primary-Home-Agent',
-  'no_such_attribute' => 'No-Such-Attribute',
-  'x_ascend_pri_number_type' => 'X-Ascend-PRI-Number-Type',
-  'ms_mppe_send_key' => 'MS-MPPE-Send-Key',
-  'usr_actual_voltage' => 'USR-Actual-Voltage',
-  'annex_acct_servers' => 'Annex-Acct-Servers',
-  'ascend_handle_ipx' => 'Ascend-Handle-IPX',
-  'cisco_xmit_rate' => 'Cisco-Xmit-Rate',
-  'acc_service_profile' => 'Acc-Service-Profile',
-  'x_ascend_ara_pw' => 'X-Ascend-Ara-PW',
-  'ascend_ckt_type' => 'Ascend-Ckt-Type',
-  'cisco_data_rate' => 'Cisco-Data-Rate',
-  'group' => 'Group',
-  'nas_port' => 'NAS-Port',
-  'usr_ipx_call_output_filt' => 'USR-IPX-Call-Output-Filter',
-  'tunnel_type' => 'Tunnel-Type',
-  'usr_rmmie_manufacturer_i' => 'USR-RMMIE-Manufacturer-ID',
-  'user_name_is_star' => 'User-Name-Is-Star',
-  'usr_call_arrival_in_gmt' => 'USR-Call-Arrival-in-GMT',
-  'x_ascend_number_sessions' => 'X-Ascend-Number-Sessions',
-  'ascend_send_auth' => 'Ascend-Send-Auth',
-  'user_service_type' => 'User-Service-Type',
-  'annex_cli_filter' => 'Annex-CLI-Filter',
-  'erx_cli_initial_access_l' => 'ERX-Cli-Initial-Access-Level',
-  'ascend_call_direction' => 'Ascend-Call-Direction',
-  'usr_chassis_temp_thresho' => 'USR-Chassis-Temp-Threshold',
-  'usr_pw_usr_ofilter_ipx' => 'USR-PW_USR_OFilter_IPX',
-  'tunnel_session_auth' => 'Tunnel_Session_Auth',
-  'x_ascend_connect_progres' => 'X-Ascend-Connect-Progress',
-  'ascend_atm_connect_vci' => 'Ascend-ATM-Connect-Vci',
-  'x_ascend_maximum_call_du' => 'X-Ascend-Maximum-Call-Duration',
-  'usr_rmmie_planned_discon' => 'USR-RMMIE-Planned-Disconnect',
-  'x_ascend_fr_dte_n392' => 'X-Ascend-FR-DTE-N392',
-  'login_host' => 'Login-Host',
-  'ascend_user_acct_host' => 'Ascend-User-Acct-Host',
-  'x_ascend_fr_dte_n393' => 'X-Ascend-FR-DTE-N393',
-  'acc_tunnel_secret' => 'Acc-Tunnel-Secret',
-  'usr_at_rtmp_input_filter' => 'USR-AT-RTMP-Input-Filter',
+  'post_proxy_type' => 'Post-Proxy-Type',
+  'wispr_session_terminate_' => 'WISPr-Session-Terminate-Time',
+  'bintec_pppextiftable' => 'BinTec-pppExtIfTable',
+  'nomadix_subnet' => 'Nomadix-Subnet',
+  'login_port' => 'Login-Port',
+  'ms_chap2_response' => 'MS-CHAP2-Response',
+  'ascend_ipsec_profile' => 'Ascend-IPSEC-Profile',
+  'usr_compression_algorith' => 'USR-Compression-Algorithm',
+  'usr_accm_type' => 'USR-ACCM-Type',
+  'simultaneous_use' => 'Simultaneous-Use',
+  'cisco_account_info' => 'Cisco-Account-Info',
   'framed_protocol' => 'Framed-Protocol',
-  'login_callback_number' => 'Login-Callback-Number',
-  'ascend_dsl_rate_type' => 'Ascend-Dsl-Rate-Type',
+  'erx_tunnel_maximum_sessi' => 'ERX-Tunnel-Maximum-Sessions',
+  'redcreek_tunneled_wins_t' => 'RedCreek-Tunneled-WINS-Server2',
+  'ascend_recv_name' => 'Ascend-Recv-Name',
+  'usr_call_connecting_time' => 'USR-Call-Connecting-Time',
+  'quintum_h323_gw_id' => 'Quintum-h323-gw-id',
+  'acct_dyn_ac_ent' => 'Acct-Dyn-Ac-Ent',
+  'tunnel_remote_name' => 'Tunnel-Remote-Name',
+  'annex_ppp_trace_level' => 'Annex-PPP-Trace-Level',
+  'cisco_call_type' => 'Cisco-Call-Type',
+  'cisco_fax_recipient_coun' => 'Cisco-Fax-Recipient-Count',
+  'altiga_ipsec_authenticat' => 'Altiga-IPSec-Authentication-G',
+  'wispr_location_id' => 'WISPr-Location-ID',
+  'itk_start_delay' => 'ITK-Start-Delay',
   'ascend_pre_output_packet' => 'Ascend-Pre-Output-Packets',
-  'proxy_state' => 'Proxy-State',
-  'usr_pw_usr_ofilter_ip' => 'USR-PW_USR_OFilter_IP',
-  'cisco_data_filter' => 'Cisco-Data-Filter',
-  'cisco_target_util' => 'Cisco-Target-Util',
-  'usr_ids0_call_type' => 'USR-IDS0-Call-Type',
-  'usr_blocks_resent' => 'USR-Blocks-Resent',
-  'usr_terminal_type' => 'USR-Terminal-Type',
-  'ascend_history_weigh_typ' => 'Ascend-History-Weigh-Type',
-  'framed_routing' => 'Framed-Routing',
-  'ascend_client_assign_dns' => 'Ascend-Client-Assign-DNS',
-  'ascend_atm_group' => 'Ascend-ATM-Group',
-  'bind_bypass_bypass' => 'Bind_Bypass_Bypass',
-  'le_ip_gateway' => 'LE-IP-Gateway',
-  'cisco_ip_pool_definition' => 'Cisco-IP-Pool-Definition',
-  'x_ascend_maximum_time' => 'X-Ascend-Maximum-Time',
-  'usr_request_type' => 'USR-Request-Type',
-  'usr_call_arrival_time' => 'USR-Call-Arrival-Time',
-  'tunnel_domain' => 'Tunnel_Domain',
-  'ms_chap_nt_enc_pw' => 'MS-CHAP-NT-Enc-PW',
-  'shiva_calling_number' => 'Shiva-Calling-Number',
-  'ip_address_pool_name' => 'Ip_Address_Pool_Name',
+  'usr_rmmie_firmware_versi' => 'USR-RMMIE-Firmware-Version',
+  'usr_vts_session_key' => 'USR-VTS-Session-Key',
+  'ascend_fr_dce_n393' => 'Ascend-FR-DCE-N393',
+  'login_host' => 'Login-Host',
+  'usr_reply_script3' => 'USR-Reply-Script3',
+  'cvpn3000_ipsec_split_tuo' => 'CVPN3000-IPSec-Split-Tunneling-Policy',
+  'ascend_pppoe_enable' => 'Ascend-PPPoE-Enable',
+  'annex_primary_dns_server' => 'Annex-Primary-DNS-Server',
+  'x_ascend_bridge_address' => 'X-Ascend-Bridge-Address',
+  'usr_number_of_link_naks' => 'USR-Number-of-Link-NAKs',
+  'altiga_priority_on_sep_g' => 'Altiga-Priority-on-SEP-G/U',
+  'annex_cli_command' => 'Annex-CLI-Command',
+  'usr_pw_framed_routing_v2' => 'USR-PW_Framed_Routing_V2',
+  'session_error_codf' => 'Session_Error_Code',
+  'annex_user_server_locati' => 'Annex-User-Server-Location',
+  'cisco_fax_mdn_address' => 'Cisco-Fax-Mdn-Address',
+  'ascend_calling_subaddres' => 'Ascend-Calling-Subaddress',
+  'ascend_call_by_call' => 'Ascend-Call-By-Call',
+  'ascend_first_dest' => 'Ascend-First-Dest',
+  'annex_tunnel_authen_type' => 'Annex-Tunnel-Authen-Type',
+  'acct_type' => 'Acct-Type',
+  'sql_user_name' => 'SQL-User-Name',
   'erx_secondary_dns' => 'ERX-Secondary-Dns',
-  'x_ascend_pre_input_octet' => 'X-Ascend-Pre-Input-Octets',
-  'ascend_home_agent_udp_po' => 'Ascend-Home-Agent-UDP-Port',
-  'le_nat_outsource_inmap' => 'LE-NAT-Outsource-Inmap',
-  'x_ascend_home_agent_pass' => 'X-Ascend-Home-Agent-Password',
-  'tunnel_password' => 'Tunnel-Password',
-  'usr_compression_type' => 'USR-Compression-Type',
-  'usr_connect_speed' => 'USR-Connect-Speed',
-  'usr_connect_time_limit' => 'USR-Connect-Time-Limit',
-  'arap_challenge_response' => 'ARAP-Challenge-Response',
-  'ms_link_utilization_thre' => 'MS-Link-Utilization-Threshold',
-  'usr_mp_edo' => 'USR-MP-EDO',
-  'usr_primary_nbns_server' => 'USR-Primary_NBNS_Server',
-  'usr_imsi' => 'USR-IMSI',
-  'ascend_fr_direct' => 'Ascend-FR-Direct',
-  'ascend_vrouter_name' => 'Ascend-VRouter-Name',
-  'ascend_preempt_limit' => 'Ascend-Preempt-Limit',
-  'ascend_ip_pool_definitio' => 'Ascend-IP-Pool-Definition',
-  'h323_gw_id' => 'h323-gw-id',
-  'usr_framed_ipx_route' => 'USR-Framed-IPX-Route',
-  'x_ascend_maximum_channel' => 'X-Ascend-Maximum-Channels',
-  'login_lat_node' => 'Login-LAT-Node',
-  'acct_session_time' => 'Acct-Session-Time',
-  'ascend_disconnect_cause' => 'Ascend-Disconnect-Cause',
-  'ms_mppe_encryption_polic' => 'MS-MPPE-Encryption-Policy',
-  'ms_ras_version' => 'MS-RAS-Version',
-  'class' => 'Class',
-  'caller_id' => 'Caller-ID',
-  'ascend_access_intercept_' => 'Ascend-Access-Intercept-Log',
-  'ascend_service_type' => 'Ascend-Service-Type',
-  'ascend_h323_dialed_time' => 'Ascend-H323-Dialed-Time',
-  'exec_program_wait' => 'Exec-Program-Wait',
-  'ascend_x25_nui_password_' => 'Ascend-X25-Nui-Password-Prompt',
-  'ascend_appletalk_peer_mo' => 'Ascend-Appletalk-Peer-Mode',
-  'login_lat_group' => 'Login-LAT-Group',
-  'strip_user_name' => 'Strip-User-Name',
-  'nas_ip_address' => 'NAS-IP-Address',
-  'ascend_maximum_time' => 'Ascend-Maximum-Time',
-  'erx_atm_pcr' => 'ERX-Atm-PCR',
-  'ascend_client_primary_dn' => 'Ascend-Client-Primary-DNS',
-  'auth_type' => 'Auth-Type',
-  'ascend_secondary_home_ag' => 'Ascend-Secondary-Home-Agent',
-  'x_ascend_idle_limit' => 'X-Ascend-Idle-Limit',
-  'ms_ras_vendor' => 'MS-RAS-Vendor',
-  'ascend_pre_input_packets' => 'Ascend-Pre-Input-Packets',
-  'ascend_bridge' => 'Ascend-Bridge',
-  'h323_redirect_number' => 'h323-redirect-number',
-  'usr_simplified_mnp_level' => 'USR-Simplified-MNP-Levels',
+  'bridge_grouq' => 'Bridge_Group',
+  'h323_return_code' => 'h323-return-code',
+  'annex_host_allow' => 'Annex-Host-Allow',
+  'cvx_modem_end_recv_line_' => 'CVX-Modem-End-Recv-Line-Lvl',
+  'sip_method' => 'Sip-Method',
+  'x_ascend_require_auth' => 'X-Ascend-Require-Auth',
+  'cvpn3000_sep_card_assign' => 'CVPN3000-SEP-Card-Assignment',
+  'le_ipsec_deny_action' => 'LE-IPSec-Deny-Action',
   'annex_edo' => 'Annex-EDO',
-  'acc_nbns_server_sec' => 'Acc-Nbns-Server-Sec',
-  'ascend_cbcp_trunk_group' => 'Ascend-CBCP-Trunk-Group',
-  'x_ascend_data_svc' => 'X-Ascend-Data-Svc',
-  'le_terminate_detail' => 'LE-Terminate-Detail',
-  'acct_output_octets' => 'Acct-Output-Octets',
-  'usr_calling_party_number' => 'USR-Calling-Party-Number',
-  'x_ascend_dhcp_maximum_le' => 'X-Ascend-DHCP-Maximum-Leases',
+  'acct_delay_time' => 'Acct-Delay-Time',
+  'login_tcp_port' => 'Login-TCP-Port',
+  'ascend_temporary_rtes' => 'Ascend-Temporary-Rtes',
+  'versanet_termination_cau' => 'Versanet-Termination-Cause',
+  'ascend_dialed_number' => 'Ascend-Dialed-Number',
+  'cvpn3000_ipsec_authentic' => 'CVPN3000-IPSec-Authentication',
+  'ascend_fr_dlci' => 'Ascend-FR-DLCI',
+  'annex_modem_disc_reason' => 'Annex-Modem-Disc-Reason',
+  'x_ascend_receive_secret' => 'X-Ascend-Receive-Secret',
+  'usr_ospf_addressless_ind' => 'USR-OSPF-Addressless-Index',
+  'usr_ip_default_route_opt' => 'USR-IP-Default-Route-Option',
+  'char_noecho' => 'Char-Noecho',
+  'redcreek_tunneled_search' => 'RedCreek-Tunneled-Search-List',
+  'ascend_pri_number_type' => 'Ascend-PRI-Number-Type',
+  'aat_ip_tos_apply_to' => 'AAT-IP-TOS-Apply-To',
+  'x_ascend_modem_shelfno' => 'X-Ascend-Modem-ShelfNo',
+  'prefix' => 'Prefix',
+  'usr_rad_dvmrp_metric' => 'USR-Rad-Dvmrp-Metric',
+  'x_ascend_call_attempt_li' => 'X-Ascend-Call-Attempt-Limit',
+  'usr_ip_saa_filter' => 'USR-IP-SAA-Filter',
+  'itk_prompt' => 'ITK-Prompt',
+  'ascend_port_redir_protoc' => 'Ascend-Port-Redir-Protocol',
+  'cvx_modem_tx_packets' => 'CVX-Modem-Tx-Packets',
+  'usr_tunnel_switch_endpoi' => 'USR-Tunnel-Switch-Endpoint',
+  'ascend_home_network_name' => 'Ascend-Home-Network-Name',
+  'acc_customer_id' => 'Acc-Customer-Id',
+  'message_authenticator' => 'Message-Authenticator',
+  'cisco_fax_coverpage_flag' => 'Cisco-Fax-Coverpage-Flag',
+  'usr_multicast_forwarding' => 'USR-Multicast-Forwarding',
+  'cvpn3000_allow_network_e' => 'CVPN3000-Allow-Network-Extension-Mode',
+  'ascend_call_direction' => 'Ascend-Call-Direction',
+  'acc_connect_rx_speed' => 'Acc-Connect-Rx-Speed',
   'ascend_force_56' => 'Ascend-Force-56',
-  'shiva_acct_serv_switch' => 'Shiva-Acct-Serv-Switch',
-  'tunnel_algorithm' => 'Tunnel_Algorithm',
-  'usr_max_channels' => 'USR-Max-Channels',
-  'usr_port_tap_priority' => 'USR-Port-Tap-Priority',
-  'le_nat_outmap' => 'LE-NAT-Outmap',
-  'usr_call_connecting_time' => 'USR-Call-Connecting-Time',
-  'usr_supports_tags' => 'USR-Supports-Tags',
-  'idle_timeout' => 'Idle-Timeout',
-  'usr_ip_rip_input_filter' => 'USR-IP-RIP-Input-Filter',
-  'erx_ingress_policy_name' => 'ERX-Ingress-Policy-Name',
-  'usr_pw_cutoff' => 'USR-PW_Cutoff',
-  'usr_channel_expansion' => 'USR-Channel-Expansion',
-  'x_ascend_send_secret' => 'X-Ascend-Send-Secret',
-  'h323_call_origin' => 'h323-call-origin',
-  'h323_preferred_lang' => 'h323-preferred-lang',
-  'ascend_base_channel_coun' => 'Ascend-Base-Channel-Count',
-  'bind_auth_context' => 'Bind_Auth_Context',
-  'ascend_calling_id_number' => 'Ascend-Calling-Id-Number-Plan',
-  'ascend_modem_shelfno' => 'Ascend-Modem-ShelfNo',
-  'tunnel_police_burst' => 'Tunnel_Police_Burst',
-  'pvc_circuit_padding' => 'PVC_Circuit_Padding',
-  'acc_ml_call_threshold' => 'Acc-ML-Call-Threshold',
-  'usr_end_time' => 'USR-End-Time',
-  'usr_ipx' => 'USR-IPX',
-  'ms_primary_dns_server' => 'MS-Primary-DNS-Server',
-  'ascend_dsl_upstream_limi' => 'Ascend-Dsl-Upstream-Limit',
-  'usr_blocks_sent' => 'USR-Blocks-Sent',
-  'bind_dot1q_vlan_tag_id' => 'Bind_Dot1q_Vlan_Tag_Id',
-  'ascend_private_route' => 'Ascend-Private-Route',
-  'usr_back_channel_data_ra' => 'USR-Back-Channel-Data-Rate',
-  'ascend_dropped_packets' => 'Ascend-Dropped-Packets',
-  'cisco_route_ip' => 'Cisco-Route-IP',
-  'nas_identifier' => 'NAS-Identifier',
-  'ascend_presession_time' => 'Ascend-PreSession-Time',
-  'usr_call_type' => 'USR-Call-Type',
-  'usr_acct_reason_code' => 'USR-Acct-Reason-Code',
-  'acc_dialout_auth_passwor' => 'Acc-Dialout-Auth-Password',
-  'acc_connect_tx_speed' => 'Acc-Connect-Tx-Speed',
-  'cisco_pre_input_octets' => 'Cisco-Pre-Input-Octets',
-  'x_ascend_send_passwd' => 'X-Ascend-Send-Passwd',
-  'ascend_bir_bridge_group' => 'Ascend-BIR-Bridge-Group',
-  'ascend_fr_profile_name' => 'Ascend-FR-Profile-Name',
+  'st_service_domain' => 'ST-Service-Domain',
+  'usr_harc_disconnect_code' => 'USR-HARC-Disconnect-Code',
+  'shasta_service_profile' => 'Shasta-Service-Profile',
+  'cisco_maximum_time' => 'Cisco-Maximum-Time',
+  'usr_tunnel_auth_hostname' => 'USR-Tunnel-Auth-Hostname',
+  'acc_ip_gateway_pri' => 'Acc-Ip-Gateway-Pri',
+  'ascend_bridge_address' => 'Ascend-Bridge-Address',
+  'altiga_pptp_min_authenti' => 'Altiga-PPTP-Min-Authentication-G/U',
+  'ns_secondary_wins' => 'NS-Secondary-WINS',
+  'cbbsm_bandwidth' => 'CBBSM-Bandwidth',
+  'x_ascend_fr_link_mgt' => 'X-Ascend-FR-Link-Mgt',
+  'altiga_ipsec_banner_g' => 'Altiga-IPSec-Banner-G',
+  'ascend_handle_ipx' => 'Ascend-Handle-IPX',
+  'ascend_x25_pad_alias_2' => 'Ascend-X25-Pad-Alias-2',
+  'st_policy_name' => 'ST-Policy-Name',
   'ascend_group' => 'Ascend-Group',
-  'crypt_password' => 'Crypt-Password',
-  'usr_port_tap_address' => 'USR-Port-Tap-Address',
-  'le_nat_outsource_outmap' => 'LE-NAT-Outsource-Outmap',
+  'ascend_dsl_rate_type' => 'Ascend-Dsl-Rate-Type',
+  'tunnel_contexu' => 'Tunnel_Context',
+  'ascend_require_auth' => 'Ascend-Require-Auth',
+  'cvx_modem_local_retrains' => 'CVX-Modem-Local-Retrains',
+  'cvpn5000_echo' => 'CVPN5000-Echo',
+  'cvx_secondary_dns' => 'CVX-Secondary-DNS',
+  'x_ascend_billing_number' => 'X-Ascend-Billing-Number',
+  'usr_orig_nas_type' => 'USR-Orig-NAS-Type',
+  'ascend_remote_fw' => 'Ascend-Remote-FW',
+  'acct_output_packets' => 'Acct-Output-Packets',
+  'lm_password' => 'LM-Password',
+  'tunnel_window' => 'Tunnel-Window',
+  'cisco_avpair' => 'Cisco-AVPair',
+  'st_service_name' => 'ST-Service-Name',
+  'shiva_event_flags' => 'Shiva-Event-Flags',
+  'annex_retrain_requests_s' => 'Annex-Retrain-Requests-Sent',
+  'ascend_ts_idle_mode' => 'Ascend-TS-Idle-Mode',
+  'usr_ip_rip_simple_auth_p' => 'USR-IP-RIP-Simple-Auth-Password',
+  'tunnel_deadtimf' => 'Tunnel_Deadtime',
+  'state' => 'State',
+  'usr_keypress_timeout' => 'USR-Keypress-Timeout',
+  'usr_pw_vpn_neighbor' => 'USR-PW_VPN_Neighbor',
+  'erx_pppoe_description' => 'ERX-Pppoe-Description',
+  'ldap_userdn' => 'Ldap-UserDn',
+  'x_ascend_fr_n391' => 'X-Ascend-FR-N391',
+  'ascend_calling_id_presen' => 'Ascend-Calling-Id-Presentatn',
+  'erx_local_loopback_inter' => 'ERX-Local-Loopback-Interface',
+  'x_ascend_fr_direct' => 'X-Ascend-FR-Direct',
+  'nas_ip_address' => 'NAS-IP-Address',
+  'usr_call_end_time' => 'USR-Call-End-Time',
+  'acct_mcast_out_packett' => 'Acct_Mcast_Out_Packets',
+  'tunnel_algorithm' => 'Tunnel-Algorithm',
   'usr_vpn_encrypter' => 'USR-VPN-Encrypter',
-  'usr_blocks_received' => 'USR-Blocks-Received',
-  'tunnel_group' => 'Tunnel_Group',
-  'ascend_shared_profile_en' => 'Ascend-Shared-Profile-Enable',
-  'replicate_to_realm' => 'Replicate-To-Realm',
+  'tunnel_grouq' => 'Tunnel_Group',
+  'ascend_atm_connect_group' => 'Ascend-ATM-Connect-Group',
+  'x_ascend_ft1_caller' => 'X-Ascend-FT1-Caller',
+  'usr_dnis_reauthenticatio' => 'USR-DNIS-ReAuthentication',
+  'login_callback_number' => 'Login-Callback-Number',
+  'usr_ip_rip_input_filter' => 'USR-IP-RIP-Input-Filter',
+  'usr_rmmie_rcv_pwrlvl_330' => 'USR-RMMIE-Rcv-PwrLvl-3300Hz',
+  'h323_disconnect_cause' => 'h323-disconnect-cause',
+  'x_ascend_handle_ipx' => 'X-Ascend-Handle-IPX',
+  'usr_igmp_version' => 'USR-IGMP-Version',
+  'usr_imsi' => 'USR-IMSI',
+  'group_name' => 'Group-Name',
+  'usr_nas_type' => 'USR-NAS-Type',
+  'context_namf' => 'Context-Name',
+  'ascend_ip_tos' => 'Ascend-IP-TOS',
+  'x_ascend_token_immediate' => 'X-Ascend-Token-Immediate',
+  'tunnel_session_auth_serw' => 'Tunnel_Session_Auth_Service_Grp',
+  'ms_chap2_cpw' => 'MS-CHAP2-CPW',
+  'tunnel_session_auth_ctx' => 'Tunnel-Session-Auth-Ctx',
+  'usr_mobile_numbytes_rxed' => 'USR-Mobile-NumBytes-Rxed',
+  'usr_mbi_ct_tdm_time_slot' => 'USR-Mbi_Ct_TDM_Time_Slot',
+  'ascend_x25_nui' => 'Ascend-X25-Nui',
+  'x_ascend_first_dest' => 'X-Ascend-First-Dest',
+  'usr_send_password' => 'USR-Send-Password',
+  'x_ascend_fr_direct_profi' => 'X-Ascend-FR-Direct-Profile',
+  'x_ascend_fr_t391' => 'X-Ascend-FR-T391',
+  'altiga_ipsec_sec_associa' => 'Altiga-IPSec-Sec-Association-G/U',
+  'ip_address_pool_namf' => 'Ip_Address_Pool_Name',
+  'acct_input_octets' => 'Acct-Input-Octets',
+  'cvx_modem_begin_modulati' => 'CVX-Modem-Begin-Modulation',
+  'wispr_session_terminatea' => 'WISPr-Session-Terminate-End-Of-Day',
+  'cvpn3000_use_client_addr' => 'CVPN3000-Use-Client-Address',
+  'bridge_group' => 'Bridge-Group',
+  'annex_sec_profile_index' => 'Annex-Sec-Profile-Index',
+  'acc_dns_server_pri' => 'Acc-Dns-Server-Pri',
+  'ms_acct_auth_type' => 'MS-Acct-Auth-Type',
+  'x_ascend_maximum_call_du' => 'X-Ascend-Maximum-Call-Duration',
+  'tunnel_password' => 'Tunnel-Password',
+  'framed_ipv6_prefix' => 'Framed-IPv6-Prefix',
+  'usr_reply_script5' => 'USR-Reply-Script5',
+  'shiva_links_in_bundle' => 'Shiva-Links-In-Bundle',
+  'ascend_fr_profile_name' => 'Ascend-FR-Profile-Name',
+  'ascend_mtu' => 'Ascend-MTU',
+  'nokia_charging_id' => 'Nokia-Charging-Id',
+  'cvpn3000_ms_client_subne' => 'CVPN3000-MS-Client-Subnet-Mask',
+  'cvpn3000_ipsec_sec_assoc' => 'CVPN3000-IPSec-Sec-Association',
+  'cisco_ppp_async_map' => 'Cisco-PPP-Async-Map',
+  'cvpn3000_user_auth_servf' => 'CVPN3000-User-Auth-Server-Port',
+  'cisco_num_in_multilink' => 'Cisco-Num-In-Multilink',
+  'wispr_logoff_url' => 'WISPr-Logoff-URL',
   'usr_mobile_ip_address' => 'USR-Mobile-IP-Address',
-  'x_ascend_authen_alias' => 'X-Ascend-Authen-Alias',
-  'ascend_fr_linkup' => 'Ascend-FR-LinkUp',
-  'tunnel_rate_limit_rate' => 'Tunnel_Rate_Limit_Rate',
-  'acc_access_community' => 'Acc-Access-Community',
+  'usr_final_tx_link_data_r' => 'USR-Final-Tx-Link-Data-Rate',
+  'itk_ppp_compression_prot' => 'ITK-PPP-Compression-Prot',
+  'ascend_bridge' => 'Ascend-Bridge',
   'x_ascend_presession_time' => 'X-Ascend-PreSession-Time',
-  'ms_chap_cpw_1' => 'MS-CHAP-CPW-1',
-  'ms_chap_cpw_2' => 'MS-CHAP-CPW-2',
-  'erx_primary_dns' => 'ERX-Primary-Dns',
-  'ascend_fr_circuit_name' => 'Ascend-FR-Circuit-Name',
-  'ascend_token_immediate' => 'Ascend-Token-Immediate',
-  'cisco_idle_limit' => 'Cisco-Idle-Limit',
+  'aat_client_primary_dns' => 'AAT-Client-Primary-DNS',
+  'cvpn3000_strip_realm' => 'CVPN3000-Strip-Realm',
+  'tunnel_cmd_timeout' => 'Tunnel-Cmd-Timeout',
+  'ascend_multicast_client' => 'Ascend-Multicast-Client',
+  'cvx_modem_remote_rate_ne' => 'CVX-Modem-Remote-Rate-Negs',
+  'tunnel_private_group_id' => 'Tunnel-Private-Group-Id',
+  'usr_rmmie_rcv_tot_pwrlvl' => 'USR-RMMIE-Rcv-Tot-PwrLvl',
+  'calling_station_id' => 'Calling-Station-Id',
+  'tunnel_rate_limit_burst' => 'Tunnel-Rate-Limit-Burst',
+  'usr_device_connected_to' => 'USR-Device-Connected-To',
+  'aat_source_ip_check' => 'AAT-Source-IP-Check',
+  'login_lat_service' => 'Login-LAT-Service',
+  'ascend_h323_fegw_address' => 'Ascend-H323-Fegw-Address',
+  'usr_called_party_number' => 'USR-Called-Party-Number',
+  'bintec_ipnatpresettable' => 'BinTec-ipNatPresetTable',
+  'ascend_remove_seconds' => 'Ascend-Remove-Seconds',
+  'shiva_user_attributes' => 'Shiva-User-Attributes',
+  'cisco_fax_dsn_flag' => 'Cisco-Fax-Dsn-Flag',
+  'x_ascend_route_ipx' => 'X-Ascend-Route-IPX',
+  'acc_route_policy' => 'Acc-Route-Policy',
+  'bind_l2tp_flow_controm' => 'Bind_L2TP_Flow_Control',
+  'erx_qos_profile_name' => 'ERX-Qos-Profile-Name',
+  'x_ascend_client_gateway' => 'X-Ascend-Client-Gateway',
+  'pre_proxy_type' => 'Pre-Proxy-Type',
+  'smb_account_ctrl_text' => 'SMB-Account-CTRL-TEXT',
+  'x_ascend_data_filter' => 'X-Ascend-Data-Filter',
+  'usr_rmmie_last_update_ti' => 'USR-RMMIE-Last-Update-Time',
+  'ascend_atm_direct' => 'Ascend-ATM-Direct',
+  'ascend_session_type' => 'Ascend-Session-Type',
+  'x_ascend_fr_linkup' => 'X-Ascend-FR-LinkUp',
+  'ascend_metric' => 'Ascend-Metric',
+  'x_ascend_assign_ip_clien' => 'X-Ascend-Assign-IP-Client',
   'usr_speed_of_connection' => 'USR-Speed-Of-Connection',
-  'shiva_links_in_bundle' => 'Shiva-Links-In-Bundle',
-  'x_ascend_fr_profile_name' => 'X-Ascend-FR-Profile-Name',
-  'cisco_multilink_id' => 'Cisco-Multilink-ID',
-  'x_ascend_preempt_limit' => 'X-Ascend-Preempt-Limit',
-  'ascend_assign_ip_client' => 'Ascend-Assign-IP-Client',
-  'usr_iwf_ip_address' => 'USR-IWF-IP-Address',
+  'cvpn3000_require_hw_clie' => 'CVPN3000-Require-HW-Client-Auth',
+  'session_type' => 'Session-Type',
+  'acct_input_octets_65' => 'Acct_Input_Octets_64',
+  'le_nat_outsource_outmap' => 'LE-NAT-Outsource-Outmap',
+  'cvx_modem_local_rate_neg' => 'CVX-Modem-Local-Rate-Negs',
+  'mcast_sene' => 'Mcast_Send',
+  'pppoe_url' => 'PPPOE-URL',
+  'erx_service_bundle' => 'ERX-Service-Bundle',
+  'altiga_secondary_dns_g' => 'Altiga-Secondary-DNS-G',
+  'bg_trans_bpdv' => 'BG_Trans_BPDU',
+  'cvx_data_filter' => 'CVX-Data-Filter',
+  'acct_mcast_out_octets' => 'Acct-Mcast-Out-Octets',
+  'ascend_callback' => 'Ascend-Callback',
+  'tunnel_client_auth_id' => 'Tunnel-Client-Auth-Id',
   'acct_unique_session_id' => 'Acct-Unique-Session-Id',
-  'framed_pool' => 'Framed-Pool',
-  'usr_igmp_version' => 'USR-IGMP-Version',
-  'tunnel_max_tunnels' => 'Tunnel_Max_Tunnels',
-  'annex_unauthenticated_ti' => 'Annex-Unauthenticated-Time',
-  'bg_path_cost' => 'BG_Path_Cost',
-  'ascend_client_assign_win' => 'Ascend-Client-Assign-WINS',
-  'x_ascend_dial_number' => 'X-Ascend-Dial-Number',
-  'cisco_maximum_channels' => 'Cisco-Maximum-Channels',
-  'usr_pw_framed_routing_v2' => 'USR-PW_Framed_Routing_V2',
-  'usr_channel_decrement' => 'USR-Channel-Decrement',
-  'x_ascend_route_ipx' => 'X-Ascend-Route-IPX',
+  'usr_port_tap_format' => 'USR-Port-Tap-Format',
+  'ascend_ckt_type' => 'Ascend-Ckt-Type',
+  'ascend_ppp_async_map' => 'Ascend-PPP-Async-Map',
+  'usr_rmmie_rcv_pwrlvl_375' => 'USR-RMMIE-Rcv-PwrLvl-3750Hz',
+  'usr_acct_reason_code' => 'USR-Acct-Reason-Code',
+  'ascend_filter' => 'Ascend-Filter',
+  'h323_redirect_number' => 'h323-redirect-number',
   'port_limit' => 'Port-Limit',
-  'ascend_dsl_downstream_li' => 'Ascend-Dsl-Downstream-Limit',
-  'ascend_ip_tos_precedence' => 'Ascend-IP-TOS-Precedence',
-  'usr_multicast_receive' => 'USR-Multicast-Receive',
-  'usr_auth_mode' => 'USR-Auth-Mode',
-  'expiration' => 'Expiration',
-  'x_ascend_fr_circuit_name' => 'X-Ascend-FR-Circuit-Name',
-  'x_ascend_token_immediate' => 'X-Ascend-Token-Immediate',
-  'ascend_ft1_caller' => 'Ascend-FT1-Caller',
-  'shiva_event_flags' => 'Shiva-Event-Flags',
-  'framed_netmask' => 'Framed-Netmask',
-  'ascend_minimum_channels' => 'Ascend-Minimum-Channels',
-  'acc_ml_damping_factor' => 'Acc-ML-Damping-Factor',
-  'bind_sub_password' => 'Bind_Sub_Password',
-  'ascend_ip_tos_apply_to' => 'Ascend-IP-TOS-Apply-To',
-  'x_ascend_home_agent_udp_' => 'X-Ascend-Home-Agent-UDP-Port',
-  'x_ascend_menu_item' => 'X-Ascend-Menu-Item',
-  'ascend_session_type' => 'Ascend-Session-Type',
-  'usr_pw_packet' => 'USR-PW_Packet',
-  'session' => 'Session',
-  'usr_mic' => 'USR-MIC',
-  'usr_line_reversals' => 'USR-Line-Reversals',
-  'assigned_ip_address' => 'Assigned_IP_Address',
-  'cisco_ip_direct' => 'Cisco-IP-Direct',
-  'le_ipsec_log_options' => 'LE-IPSec-Log-Options',
-  'tunnel_rate_limit_burst' => 'Tunnel_Rate_Limit_Burst',
-  'x_ascend_assign_ip_globa' => 'X-Ascend-Assign-IP-Global-Pool',
-  'x_ascend_inc_channel_cou' => 'X-Ascend-Inc-Channel-Count',
-  'h323_return_code' => 'h323-return-code',
-  'shiva_disconnect_reason' => 'Shiva-Disconnect-Reason',
-  'filter_id' => 'Filter-Id',
-  'usr_appletalk_network_ra' => 'USR-Appletalk-Network-Range',
-  'ascend_temporary_rtes' => 'Ascend-Temporary-Rtes',
-  'ascend_h323_conference_i' => 'Ascend-H323-Conference-Id',
-  'h323_billing_model' => 'h323-billing-model',
-  'usr_bearer_capabilities' => 'USR-Bearer-Capabilities',
-  'framed_appletalk_zone' => 'Framed-AppleTalk-Zone',
-  'usr_harc_disconnect_code' => 'USR-HARC-Disconnect-Code',
-  'usr_ipx_rip_input_filter' => 'USR-IPX-RIP-Input-Filter',
-  'usr_rad_multicast_routin' => 'USR-Rad-Multicast-Routing-Bound',
-  'ascend_pw_lifetime' => 'Ascend-PW-Lifetime',
-  'acc_dialout_auth_usernam' => 'Acc-Dialout-Auth-Username',
-  'ascend_x25_pad_x3_parame' => 'Ascend-X25-Pad-X3-Parameters',
-  'bind_dot1q_slot' => 'Bind_Dot1q_Slot',
-  'usr_rad_multicast_routin' => 'USR-Rad-Multicast-Routing-RtLim',
-  'x_ascend_multicast_clien' => 'X-Ascend-Multicast-Client',
-  'ascend_authen_alias' => 'Ascend-Authen-Alias',
-  'ascend_dec_channel_count' => 'Ascend-Dec-Channel-Count',
-  'dhcp_max_leases' => 'DHCP_Max_Leases',
-  'shiva_called_number' => 'Shiva-Called-Number',
-  'annex_tunnel_authen_mode' => 'Annex-Tunnel-Authen-Mode',
-  'usr_call_error_code' => 'USR-Call-Error-Code',
-  'x_ascend_user_acct_type' => 'X-Ascend-User-Acct-Type',
-  'ascend_atm_connect_vpi' => 'Ascend-ATM-Connect-Vpi',
-  'ascend_x25_pad_x3_profil' => 'Ascend-X25-Pad-X3-Profile',
-  'usr_mobileip_home_agent_' => 'USR-MobileIP-Home-Agent-Address',
-  'suffix' => 'Suffix',
-  'bind_tun_context' => 'Bind_Tun_Context',
-  'x_ascend_ppp_address' => 'X-Ascend-PPP-Address',
-  'usr_dtr_false_timeout' => 'USR-DTR-False-Timeout',
-  'usr_final_rx_link_data_r' => 'USR-Final-Rx-Link-Data-Rate',
+  'rewrite_rule' => 'Rewrite-Rule',
+  'tunnel_police_rate' => 'Tunnel-Police-Rate',
+  'usr_multicast_proxy' => 'USR-Multicast-Proxy',
+  'ascend_max_shared_users' => 'Ascend-Max-Shared-Users',
+  'usr_bridging' => 'USR-Bridging',
+  'cvx_presession_time' => 'CVX-PreSession-Time',
+  'cvpn5000_vpn_groupinfo' => 'CVPN5000-VPN-GroupInfo',
+  'autz_type' => 'Autz-Type',
+  'x_ascend_fr_dlci' => 'X-Ascend-FR-DLCI',
+  'usr_request_type' => 'USR-Request-Type',
+  'acc_igmp_admin_state' => 'Acc-Igmp-Admin-State',
+  'ascend_host_info' => 'Ascend-Host-Info',
+  'ascend_dhcp_maximum_leas' => 'Ascend-DHCP-Maximum-Leases',
+  'usr_rmmie_num_of_updates' => 'USR-RMMIE-Num-Of-Updates',
+  'x_ascend_fr_profile_name' => 'X-Ascend-FR-Profile-Name',
+  'ascend_fr_direct_profile' => 'Ascend-FR-Direct-Profile',
+  'x_ascend_bridge' => 'X-Ascend-Bridge',
+  'tunnel_deadtime' => 'Tunnel-Deadtime',
   'ms_chap_error' => 'MS-CHAP-Error',
-  'x_ascend_home_agent_ip_a' => 'X-Ascend-Home-Agent-IP-Addr',
-  'ascend_data_svc' => 'Ascend-Data-Svc',
-  'usr_rmmie_pwrlvl_noise_l' => 'USR-RMMIE-PwrLvl-Noise-Lvl',
-  'usr_dtr_true_timeout' => 'USR-DTR-True-Timeout',
-  'context_name' => 'Context-Name',
-  'usr_card_type' => 'USR-Card-Type',
-  'ascend_fr_link_status_dl' => 'Ascend-FR-Link-Status-DLCI',
-  'annex_sec_profile_index' => 'Annex-Sec-Profile-Index',
-  'usr_pw_usr_ofilter_sap' => 'USR-PW_USR_OFilter_SAP',
-  'tunnel_medium_type' => 'Tunnel-Medium-Type',
-  'x_ascend_require_auth' => 'X-Ascend-Require-Auth',
-  'ascend_connect_progress' => 'Ascend-Connect-Progress',
-  'x_ascend_modem_shelfno' => 'X-Ascend-Modem-ShelfNo',
-  'cisco_pre_input_packets' => 'Cisco-Pre-Input-Packets',
-  'ascend_fr_dce_n392' => 'Ascend-FR-DCE-N392',
-  'ascend_fr_dce_n393' => 'Ascend-FR-DCE-N393',
-  'ascend_client_primary_wi' => 'Ascend-Client-Primary-WINS',
-  'shiva_link_protocol' => 'Shiva-Link-Protocol',
-  'bridge_group' => 'Bridge_Group',
-  'client_port_dnis' => 'Client-Port-DNIS',
-  'usr_mpip_tunnel_originat' => 'USR-MPIP-Tunnel-Originator',
-  'le_nat_log_options' => 'LE-NAT-Log-Options',
-  'usr_number_of_rings_limi' => 'USR-Number-of-Rings-Limit',
-  'usr_retrains_granted' => 'USR-Retrains-Granted',
-  'acc_ip_gateway_pri' => 'Acc-Ip-Gateway-Pri',
-  'usr_number_of_fallbacks' => 'USR-Number-of-Fallbacks',
-  'usr_tunnel_auth_hostname' => 'USR-Tunnel-Auth-Hostname',
-  'annex_filter' => 'Annex-Filter',
-  'ascend_mtu' => 'Ascend-MTU',
-  'ms_arap_pw_change_reason' => 'MS-ARAP-PW-Change-Reason',
-  'private_group_id' => 'Private-Group-Id',
-  'ascend_cache_time' => 'Ascend-Cache-Time',
-  'acc_ml_clear_threshold' => 'Acc-ML-Clear-Threshold',
-  'x_ascend_dhcp_reply' => 'X-Ascend-DHCP-Reply',
-  'ascend_h323_gatekeeper' => 'Ascend-H323-Gatekeeper',
-  'x_ascend_xmit_rate' => 'X-Ascend-Xmit-Rate',
-  'usr_last_number_dialed_o' => 'USR-Last-Number-Dialed-Out',
-  'acc_connect_rx_speed' => 'Acc-Connect-Rx-Speed',
-  'acc_clearing_cause' => 'Acc-Clearing-Cause',
-  'ascend_call_attempt_limi' => 'Ascend-Call-Attempt-Limit',
-  'x_ascend_data_rate' => 'X-Ascend-Data-Rate',
-  'termination_action' => 'Termination-Action',
-  'ascend_pre_input_octets' => 'Ascend-Pre-Input-Octets',
-  'x_ascend_ipx_route' => 'X-Ascend-IPX-Route',
-  'x_ascend_ts_idle_mode' => 'X-Ascend-TS-Idle-Mode',
-  'client_ip_address' => 'Client-IP-Address',
-  'ascend_add_seconds' => 'Ascend-Add-Seconds',
-  'login_ip_host' => 'Login-IP-Host',
-  'annex_sw_version' => 'Annex-SW-Version',
-  'huntgroup_name' => 'Huntgroup-Name',
-  'usr_pw_vpn_gateway' => 'USR-PW_VPN_Gateway',
-  'ascend_x25_reverse_charg' => 'Ascend-X25-Reverse-Charging',
-  'lac_real_port' => 'LAC_Real_Port',
-  'ascend_dba_monitor' => 'Ascend-DBA-Monitor',
-  'annex_user_server_locati' => 'Annex-User-Server-Location',
-  'ascend_h323_fegw_address' => 'Ascend-H323-Fegw-Address',
-  'acct_output_gigawords' => 'Acct-Output-Gigawords',
-  'bind_l2tp_tunnel_name' => 'Bind_L2TP_Tunnel_Name',
-  'x_ascend_token_idle' => 'X-Ascend-Token-Idle',
-  'acc_apsm_oversubscribed' => 'Acc-Apsm-Oversubscribed',
-  'ip_tos_field' => 'IP_TOS_Field',
-  'ascend_dsl_cir_xmit_limi' => 'Ascend-Dsl-CIR-Xmit-Limit',
-  'usr_number_of_link_naks' => 'USR-Number-of-Link-NAKs',
-  'framed_address' => 'Framed-Address',
-  'x_ascend_num_in_multilin' => 'X-Ascend-Num-In-Multilink',
-  'hint' => 'Hint',
-  'ascend_source_ip_check' => 'Ascend-Source-IP-Check',
-  'arap_zone_access' => 'ARAP-Zone-Access',
-  'x_ascend_fr_direct_profi' => 'X-Ascend-FR-Direct-Profile',
-  'x_ascend_bridge_address' => 'X-Ascend-Bridge-Address',
-  'usr_iwf_call_identifier' => 'USR-IWF-Call-Identifier',
-  'ascend_home_network_name' => 'Ascend-Home-Network-Name',
-  'ascend_require_auth' => 'Ascend-Require-Auth',
-  'source_validation' => 'Source_Validation',
-  'ms_primary_nbns_server' => 'MS-Primary-NBNS-Server',
-  'h323_setup_time' => 'h323-setup-time',
-  'tunnel_remote_name' => 'Tunnel_Remote_Name',
-  'ascend_maximum_channels' => 'Ascend-Maximum-Channels',
-  'ascend_tunneling_protoco' => 'Ascend-Tunneling-Protocol',
-  'arap_security_data' => 'ARAP-Security-Data',
-  'ascend_ipx_peer_mode' => 'Ascend-IPX-Peer-Mode',
+  'framed_route' => 'Framed-Route',
+  'sip_from' => 'Sip-From',
+  'expiration' => 'Expiration',
+  'ascend_backup' => 'Ascend-Backup',
+  'ascend_pre_output_octets' => 'Ascend-Pre-Output-Octets',
+  'ascend_calling_id_number' => 'Ascend-Calling-Id-Number-Plan',
+  'framed_appletalk_zone' => 'Framed-AppleTalk-Zone',
+  'annex_audit_level' => 'Annex-Audit-Level',
+  'digest_algorithm' => 'Digest-Algorithm',
+  'bind_auth_context' => 'Bind-Auth-Context',
+  'ascend_user_acct_base' => 'Ascend-User-Acct-Base',
+  'st_secondary_dns_server' => 'ST-Secondary-DNS-Server',
+  'mcast_receive' => 'Mcast-Receive',
+  'usr_ds0' => 'USR-DS0',
+  'aat_atm_traffic_profile' => 'AAT-ATM-Traffic-Profile',
+  'ms_ras_vendor' => 'MS-RAS-Vendor',
+  'tunnel_domain' => 'Tunnel-Domain',
+  'tunnel_max_sessions' => 'Tunnel-Max-Sessions',
+  'ascend_ip_direct' => 'Ascend-IP-Direct',
+  'xedia_address_pool' => 'Xedia-Address-Pool',
+  'idle_timeout' => 'Idle-Timeout',
+  'tunnel_rate_limit_ratf' => 'Tunnel_Rate_Limit_Rate',
+  'annex_rate_reneg_req_sen' => 'Annex-Rate-Reneg-Req-Sent',
+  'usr_initial_tx_link_data' => 'USR-Initial-Tx-Link-Data-Rate',
+  'tunnel_server_auth_id' => 'Tunnel-Server-Auth-Id',
+  'cvpn3000_ipsec_banner1' => 'CVPN3000-IPSec-Banner1',
+  'usr_start_time' => 'USR-Start-Time',
+  'usr_ip' => 'USR-IP',
+  'cvpn3000_reqrd_client_fw' => 'CVPN3000-Reqrd-Client-Fw-Vendor-Code',
+  'altiga_ipsec_secondary_d' => 'Altiga-IPSec-Secondary-Domains-G',
+  'usr_gateway_ip_address' => 'USR-Gateway-IP-Address',
+  'ascend_dba_monitor' => 'Ascend-DBA-Monitor',
+  'ms_link_utilization_thre' => 'MS-Link-Utilization-Threshold',
+  'st_primary_dns_server' => 'ST-Primary-DNS-Server',
+  'acc_ace_token_ttl' => 'Acc-Ace-Token-Ttl',
+  'ms_chap_domain' => 'MS-CHAP-Domain',
+  'cisco_pre_input_octets' => 'Cisco-Pre-Input-Octets',
+  'ascend_primary_home_agen' => 'Ascend-Primary-Home-Agent',
+  'acct_session_time' => 'Acct-Session-Time',
+  'framed_ip_address' => 'Framed-IP-Address',
+  'ns_admin_privilege' => 'NS-Admin-Privilege',
+  'medium_type' => 'Medium-Type',
+  'acct_output_octets_64' => 'Acct-Output-Octets-64',
   'ascend_cir_timer' => 'Ascend-CIR-Timer',
-  'ascend_ts_idle_limit' => 'Ascend-TS-Idle-Limit',
-  'ascend_cache_refresh' => 'Ascend-Cache-Refresh',
-  'usr_rmmie_status' => 'USR-RMMIE-Status',
-  'annex_callback_portlist' => 'Annex-Callback-Portlist',
-  'usr_port_tap' => 'USR-Port-Tap',
-  'ascend_client_secondary_' => 'Ascend-Client-Secondary-DNS',
-  'x_ascend_first_dest' => 'X-Ascend-First-Dest',
-  'lac_port' => 'LAC_Port',
-  'acc_callback_cbcp_type' => 'Acc-Callback-CBCP-Type',
-  'usr_call_reference_numbe' => 'USR-Call-Reference-Number',
-  'mcast_receive' => 'Mcast_Receive',
-  'x_ascend_link_compressio' => 'X-Ascend-Link-Compression',
-  'ascend_inter_arrival_jit' => 'Ascend-Inter-Arrival-Jitter',
-  'x_ascend_assign_ip_pool' => 'X-Ascend-Assign-IP-Pool',
-  'usr_chassis_call_span' => 'USR-Chassis-Call-Span',
-  'arap_password' => 'ARAP-Password',
-  'usr_ip_default_route_opt' => 'USR-IP-Default-Route-Option',
+  'police_rate' => 'Police-Rate',
+  'tunnel_functioo' => 'Tunnel_Function',
+  'quintum_h323_time_and_da' => 'Quintum-h323-time-and-day',
+  'ip_tos_fiele' => 'IP_TOS_Field',
+  'erx_framed_ip_route_tag' => 'ERX-Framed-Ip-Route-Tag',
+  'ms_mppe_send_key' => 'MS-MPPE-Send-Key',
+  'ascend_maximum_call_dura' => 'Ascend-Maximum-Call-Duration',
+  'pppoe_motn' => 'PPPOE_MOTM',
+  'lac_poru' => 'LAC_Port',
+  'bind_dot1q_slou' => 'Bind_Dot1q_Slot',
+  'ascend_secondary_home_ag' => 'Ascend-Secondary-Home-Agent',
+  'usr_ip_call_output_filte' => 'USR-IP-Call-Output-Filter',
+  'x_ascend_host_info' => 'X-Ascend-Host-Info',
+  'erx_egress_policy_name' => 'ERX-Egress-Policy-Name',
+  'erx_ppp_password' => 'ERX-PPP-Password',
+  'user_name' => 'User-Name',
+  'usr_number_of_characters' => 'USR-Number-Of-Characters-Lost',
+  'bind_bypass_bypass' => 'Bind-Bypass-Bypass',
+  'usr_rad_multicast_routip' => 'USR-Rad-Multicast-Routing-Proto',
+  'annex_acct_servers' => 'Annex-Acct-Servers',
+  'cvpn5000_tunnel_throughp' => 'CVPN5000-Tunnel-Throughput',
+  'usr_chassis_call_channel' => 'USR-Chassis-Call-Channel',
+  'annex_input_filter' => 'Annex-Input-Filter',
+  'wispr_billing_class_of_s' => 'WISPr-Billing-Class-Of-Service',
+  'nas_port_type' => 'NAS-Port-Type',
+  'cvx_client_assign_dns' => 'CVX-Client-Assign-DNS',
+  'nomadix_maxbytesdown' => 'Nomadix-MaxBytesDown',
   'ascend_endpoint_disc' => 'Ascend-Endpoint-Disc',
-  'tunnel_dnis' => 'Tunnel_DNIS',
-  'ms_acct_auth_type' => 'MS-Acct-Auth-Type',
-  'ascend_ts_idle_mode' => 'Ascend-TS-Idle-Mode',
-  'shasta_service_profile' => 'Shasta-Service-Profile',
-  'usr_cdma_call_reference_' => 'USR-CDMA-Call-Reference-Number',
-  'usr_at_zip_input_filter' => 'USR-AT-Zip-Input-Filter',
-  'x_ascend_pw_warntime' => 'X-Ascend-PW-Warntime',
-  'ascend_fr_direct_dlci' => 'Ascend-FR-Direct-DLCI',
-  'usr_dte_ring_no_answer_l' => 'USR-DTE-Ring-No-Answer-Limit',
-  'ascend_multicast_rate_li' => 'Ascend-Multicast-Rate-Limit',
-  'usr_routing_protocol' => 'USR-Routing-Protocol',
-  'pam_auth' => 'Pam-Auth',
-  'client_dns_sec' => 'Client_DNS_Sec',
-  'bg_trans_bpdu' => 'BG_Trans_BPDU',
-  'police_rate' => 'Police_Rate',
-  'calling_station_id' => 'Calling-Station-Id',
-  'usr_called_party_number' => 'USR-Called-Party-Number',
-  'shiva_network_protocols' => 'Shiva-Network-Protocols',
-  'x_ascend_client_gateway' => 'X-Ascend-Client-Gateway',
-  'acct_input_octets' => 'Acct-Input-Octets',
-  'ascend_call_type' => 'Ascend-Call-Type',
-  'annex_product_name' => 'Annex-Product-Name',
-  'framed_compression' => 'Framed-Compression',
-  'ascend_atm_direct' => 'Ascend-ATM-Direct',
-  'x_ascend_remote_addr' => 'X-Ascend-Remote-Addr',
-  'usr_tunneled_mlpp' => 'USR-Tunneled-MLPP',
-  'le_ipsec_outsource_profi' => 'LE-IPSec-Outsource-Profile',
-  'ascend_atm_vci' => 'Ascend-ATM-Vci',
-  'usr_number_of_link_timeo' => 'USR-Number-of-Link-Timeouts',
-  'usr_et_bridge_input_filt' => 'USR-ET-Bridge-Input-Filter',
-  'x_ascend_fr_t391' => 'X-Ascend-FR-T391',
-  'x_ascend_fr_t392' => 'X-Ascend-FR-T392',
-  'h323_conf_id' => 'h323-conf-id',
-  'usr_call_end_date_time' => 'USR-Call-End-Date-Time',
-  'ascend_fr_t391' => 'Ascend-FR-T391',
-  'bg_aging_time' => 'BG_Aging_Time',
-  'x_ascend_pre_output_pack' => 'X-Ascend-Pre-Output-Packets',
-  'acc_dialout_auth_mode' => 'Acc-Dialout-Auth-Mode',
-  'ascend_calling_subaddres' => 'Ascend-Calling-Subaddress',
-  'ascend_fr_t392' => 'Ascend-FR-T392',
-  'acct_link_count' => 'Acct-Link-Count',
-  'usr_chassis_call_slot' => 'USR-Chassis-Call-Slot',
-  'h323_credit_time' => 'h323-credit-time',
-  'nas_port_id' => 'NAS-Port-Id',
-  'x_ascend_call_filter' => 'X-Ascend-Call-Filter',
-  'ascend_destination_nas_p' => 'Ascend-Destination-Nas-Port',
-  'arap_features' => 'ARAP-Features',
-  'x_ascend_history_weigh_t' => 'X-Ascend-History-Weigh-Type',
-  'annex_host_restrict' => 'Annex-Host-Restrict',
-  'usr_compression_reset_mo' => 'USR-Compression-Reset-Mode',
-  'cisco_maximum_time' => 'Cisco-Maximum-Time',
-  'tunnel_max_sessions' => 'Tunnel_Max_Sessions',
-  'bind_ses_context' => 'Bind_Ses_Context',
-  'x_ascend_ppp_vj_slot_com' => 'X-Ascend-PPP-VJ-Slot-Comp',
-  'usr_mobile_numbytes_rxed' => 'USR-Mobile-NumBytes-Rxed',
-  'usr_rmmie_last_update_ti' => 'USR-RMMIE-Last-Update-Time',
-  'ascend_atm_loopback_cell' => 'Ascend-ATM-Loopback-Cell-Loss',
-  'ascend_bir_proxy' => 'Ascend-BIR-Proxy',
-  'acct_mcast_in_packets' => 'Acct_Mcast_In_Packets',
-  'shiva_type_of_service' => 'Shiva-Type-Of-Service',
-  'ascend_fr_dte_n392' => 'Ascend-FR-DTE-N392',
-  'usr_at_call_input_filter' => 'USR-AT-Call-Input-Filter',
-  'ascend_fr_dte_n393' => 'Ascend-FR-DTE-N393',
-  'x_ascend_backup' => 'X-Ascend-Backup',
-  'char_noecho' => 'Char-Noecho',
-  'usr_rmmie_last_update_ev' => 'USR-RMMIE-Last-Update-Event',
-  'le_advice_of_charge' => 'LE-Advice-of-Charge',
+  'tunnel_police_burst' => 'Tunnel-Police-Burst',
+  'bind_auth_max_sessions' => 'Bind-Auth-Max-Sessions',
+  'cvx_identification' => 'CVX-Identification',
+  'cvpn3000_ipsec_allow_pas' => 'CVPN3000-IPSec-Allow-Passwd-Store',
   'ascend_calling_id_type_o' => 'Ascend-Calling-Id-Type-Of-Num',
-  'ascend_pppoe_enable' => 'Ascend-PPPoE-Enable',
+  'x_ascend_fr_dce_n392' => 'X-Ascend-FR-DCE-N392',
+  'usr_connect_term_reason' => 'USR-Connect-Term-Reason',
+  'erx_egress_statistics' => 'ERX-Egress-Statistics',
+  'ascend_fr_dte_n392' => 'Ascend-FR-DTE-N392',
+  'usr_esn' => 'USR-ESN',
+  'x_ascend_fr_dte_n392' => 'X-Ascend-FR-DTE-N392',
+  'itk_modem_init_string' => 'ITK-Modem-Init-String',
+  'x_ascend_fr_nailed_grp' => 'X-Ascend-FR-Nailed-Grp',
+  'ascend_bridge_non_pppoe' => 'Ascend-Bridge-Non-PPPoE',
+  'cvpn3000_ipsec_reqrd_cli' => 'CVPN3000-IPSec-Reqrd-Client-Fw-Cap',
+  'ascend_ipx_alias' => 'Ascend-IPX-Alias',
+  'acc_tunnel_port' => 'Acc-Tunnel-Port',
+  'quintum_h323_return_code' => 'Quintum-h323-return-code',
+  'cvpn3000_l2tp_encryption' => 'CVPN3000-L2TP-Encryption',
+  'acct_input_gigawords' => 'Acct-Input-Gigawords',
+  'bind_dot1q_poru' => 'Bind_Dot1q_Port',
+  'altiga_primary_wins_g' => 'Altiga-Primary-WINS-G',
+  'ascend_maximum_channels' => 'Ascend-Maximum-Channels',
+  'x_ascend_home_agent_pass' => 'X-Ascend-Home-Agent-Password',
+  'x_ascend_ppp_async_map' => 'X-Ascend-PPP-Async-Map',
+  'usr_rmmie_manufacturer_i' => 'USR-RMMIE-Manufacturer-ID',
+  'usr_retrains_requested' => 'USR-Retrains-Requested',
+  'x_ascend_metric' => 'X-Ascend-Metric',
+  'acc_apsm_oversubscribed' => 'Acc-Apsm-Oversubscribed',
+  'usr_originate_answer_mod' => 'USR-Originate-Answer-Mode',
+  'erx_atm_pcr' => 'ERX-Atm-PCR',
+  'itk_nas_name' => 'ITK-NAS-Name',
+  'usr_ipx_routing' => 'USR-IPX-Routing',
+  'usr_tunneled_mlpp' => 'USR-Tunneled-MLPP',
+  'usr_send_script5' => 'USR-Send-Script5',
+  'ascend_traffic_shaper' => 'Ascend-Traffic-Shaper',
+  'ascend_client_secondarya' => 'Ascend-Client-Secondary-DNS',
+  'ascend_bacp_enable' => 'Ascend-BACP-Enable',
+  'usr_call_terminate_in_gm' => 'USR-Call-Terminate-in-GMT',
+  'login_time' => 'Login-Time',
+  'bg_path_cosu' => 'BG_Path_Cost',
+  'aat_require_auth' => 'AAT-Require-Auth',
+  'cvpn3000_reqrd_client_fy' => 'CVPN3000-Reqrd-Client-Fw-Description',
+  'ascend_call_type' => 'Ascend-Call-Type',
+  'erx_address_pool_name' => 'ERX-Address-Pool-Name',
+  'cvpn3000_ipsec_backup_sf' => 'CVPN3000-IPSec-Backup-Server-List',
+  'h323_incoming_conf_id' => 'h323-incoming-conf-id',
+  'user_profile' => 'User-Profile',
+  'ip_host_adds' => 'Ip_Host_Addr',
+  'ns_primary_wins' => 'NS-Primary-WINS',
+  'packet_type' => 'Packet-Type',
+  'bind_auth_max_sessiont' => 'Bind_Auth_Max_Sessions',
+  'altiga_allow_alpha_only_' => 'Altiga-Allow-Alpha-Only-Passwords-G',
+  'usr_security_resp_limit' => 'USR-Security-Resp-Limit',
+  'ip_address_pool_name' => 'Ip-Address-Pool-Name',
+  'ascend_ipx_node_addr' => 'Ascend-IPX-Node-Addr',
+  'ascend_cbcp_trunk_group' => 'Ascend-CBCP-Trunk-Group',
+  'ascend_menu_selector' => 'Ascend-Menu-Selector',
+  'ascend_assign_ip_global_' => 'Ascend-Assign-IP-Global-Pool',
+  'usr_ds0s' => 'USR-DS0s',
+  'usr_actual_voltage' => 'USR-Actual-Voltage',
+  'quintum_h323_call_type' => 'Quintum-h323-call-type',
+  'annex_sw_version' => 'Annex-SW-Version',
+  'ascend_receive_secret' => 'Ascend-Receive-Secret',
+  'bintec_qospolicytable' => 'BinTec-qosPolicyTable',
+  'usr_ip_rip_policies' => 'USR-IP-RIP-Policies',
+  'redcreek_tunneled_ip_add' => 'RedCreek-Tunneled-IP-Addr',
+  'ascend_pw_warntime' => 'Ascend-PW-Warntime',
+  'x_ascend_inc_channel_cou' => 'X-Ascend-Inc-Channel-Count',
+  'usr_blocks_resent' => 'USR-Blocks-Resent',
+  'usr_fallback_enabled' => 'USR-Fallback-Enabled',
+  'arap_challenge_response' => 'ARAP-Challenge-Response',
+  'tunnel_session_auth' => 'Tunnel-Session-Auth',
   'usr_sync_async_mode' => 'USR-Sync-Async-Mode',
-  'state' => 'State',
-  'x_ascend_user_acct_base' => 'X-Ascend-User-Acct-Base',
-  'x_ascend_ipx_alias' => 'X-Ascend-IPX-Alias',
-  'ascend_ip_tos' => 'Ascend-IP-TOS',
-  'annex_secondary_dns_serv' => 'Annex-Secondary-DNS-Server',
-  'tunnel_session_auth_ctx' => 'Tunnel_Session_Auth_Ctx',
-  'usr_mbi_ct_pri_card_span' => 'USR-Mbi_Ct_PRI_Card_Span_Line',
+  'itk_dialout_type' => 'ITK-Dialout-Type',
+  'extreme_netlogin_url' => 'Extreme-Netlogin-Url',
+  'client_port_dnis' => 'Client-Port-DNIS',
+  'digest_realm' => 'Digest-Realm',
+  'ascend_ppp_vj_1172' => 'Ascend-PPP-VJ-1172',
+  'ascend_fr_n391' => 'Ascend-FR-N391',
+  'ascend_remote_addr' => 'Ascend-Remote-Addr',
+  'client_port_id' => 'Client-Port-Id',
+  'digest_body_digest' => 'Digest-Body-Digest',
+  'le_ipsec_active_profile' => 'LE-IPSec-Active-Profile',
+  'digest_cnonce' => 'Digest-CNonce',
+  'usr_port_tap_facility' => 'USR-Port-Tap-Facility',
+  'usr_callback_type' => 'USR-Callback-Type',
+  'client_dns_prj' => 'Client_DNS_Pri',
+  'digest_response' => 'Digest-Response',
+  'login_lat_group' => 'Login-LAT-Group',
+  'x_ascend_call_type' => 'X-Ascend-Call-Type',
+  'ascend_route_ip' => 'Ascend-Route-IP',
+  'usr_rad_multicast_routio' => 'USR-Rad-Multicast-Routing-RtLim',
+  'usr_pw_vpn_id' => 'USR-PW_VPN_ID',
+  'cvx_modem_end_modulation' => 'CVX-Modem-End-Modulation',
+  'cvpn3000_pptp_mppc_compr' => 'CVPN3000-PPTP-MPPC-Compression',
+  'cisco_pre_output_octets' => 'Cisco-Pre-Output-Octets',
+  'h323_billing_model' => 'h323-billing-model',
+  'usr_equalization_type' => 'USR-Equalization-Type',
+  'acc_clearing_cause' => 'Acc-Clearing-Cause',
+  'altiga_access_hours_g_u' => 'Altiga-Access-Hours-G/U',
+  'cvpn3000_ipsec_user_grou' => 'CVPN3000-IPSec-User-Group-Lock',
+  'x_ascend_menu_selector' => 'X-Ascend-Menu-Selector',
+  'x_ascend_netware_timeout' => 'X-Ascend-Netware-timeout',
+  'ascend_fr_linkup' => 'Ascend-FR-LinkUp',
+  'annex_num_in_multilink' => 'Annex-Num-In-Multilink',
+  'police_burst' => 'Police-Burst',
+  'altiga_l2tp_min_authenti' => 'Altiga-L2TP-Min-Authentication-G/U',
+  'ascend_filter_required' => 'Ascend-Filter-Required',
+  'x_ascend_idle_limit' => 'X-Ascend-Idle-Limit',
+  'nomadix_logoff_url' => 'Nomadix-Logoff-URL',
+  'cvpn3000_ms_client_icpt_' => 'CVPN3000-MS-Client-Icpt-DHCP-Conf-Msg',
+  'ip_tos_field' => 'IP-TOS-Field',
+  'ascend_ip_tos_apply_to' => 'Ascend-IP-TOS-Apply-To',
   'usr_call_event_code' => 'USR-Call-Event-Code',
-  'chap_password' => 'CHAP-Password',
-  'le_nat_tcp_session_timeo' => 'LE-NAT-TCP-Session-Timeout',
-  'usr_call_start_date_time' => 'USR-Call-Start-Date-Time',
-  'usr_multicast_forwarding' => 'USR-Multicast-Forwarding',
-  'client_id' => 'Client-Id',
-  'sql_user_name' => 'SQL-User-Name',
-  'x_ascend_billing_number' => 'X-Ascend-Billing-Number',
-  'ms_secondary_nbns_server' => 'MS-Secondary-NBNS-Server',
-  'cisco_num_in_multilink' => 'Cisco-Num-In-Multilink',
-  'x_ascend_client_assign_d' => 'X-Ascend-Client-Assign-DNS',
+  'usr_et_bridge_output_fil' => 'USR-ET-Bridge-Output-Filter',
+  'le_nat_sess_dir_fail_act' => 'LE-NAT-Sess-Dir-Fail-Action',
+  'usr_rmmie_product_code' => 'USR-RMMIE-Product-Code',
+  'usr_host_type' => 'USR-Host-Type',
+  'erx_tunnel_interface_id' => 'ERX-Tunnel-Interface-Id',
+  'ascend_send_auth' => 'Ascend-Send-Auth',
+  'shiva_compression_type' => 'Shiva-Compression-Type',
+  'itk_banner' => 'ITK-Banner',
+  'ascend_ft1_caller' => 'Ascend-FT1-Caller',
+  'filter_id' => 'Filter-Id',
+  'annex_pre_output_octets' => 'Annex-Pre-Output-Octets',
+  'acct_mcast_in_octett' => 'Acct_Mcast_In_Octets',
+  'usr_log_filter_packets' => 'USR-Log-Filter-Packets',
+  'ascend_fr_nailed_grp' => 'Ascend-FR-Nailed-Grp',
+  'ascend_atm_loopback_cell' => 'Ascend-ATM-Loopback-Cell-Loss',
+  'usr_at_rtmp_output_filte' => 'USR-AT-RTMP-Output-Filter',
+  'acc_input_errors' => 'Acc-Input-Errors',
   'x_ascend_user_acct_port' => 'X-Ascend-User-Acct-Port',
-  'usr_local_ip_address' => 'USR-Local-IP-Address',
-  'x_ascend_ip_pool_definit' => 'X-Ascend-IP-Pool-Definition',
-  'ascend_metric' => 'Ascend-Metric',
-  'x_ascend_bacp_enable' => 'X-Ascend-BACP-Enable',
-  'x_ascend_user_acct_time' => 'X-Ascend-User-Acct-Time',
-  'x_ascend_mpp_idle_percen' => 'X-Ascend-MPP-Idle-Percent',
-  'annex_authen_servers' => 'Annex-Authen-Servers',
-  'x_ascend_data_filter' => 'X-Ascend-Data-Filter',
-  'ascend_idle_limit' => 'Ascend-Idle-Limit',
-  'ldap_userdn' => 'Ldap-UserDn',
-  'x_ascend_target_util' => 'X-Ascend-Target-Util',
-  'shiva_connect_reason' => 'Shiva-Connect-Reason',
-  'usr_ds0' => 'USR-DS0',
-  'annex_re_chap_timeout' => 'Annex-Re-CHAP-Timeout',
-  'shasta_vpn_name' => 'Shasta-VPN-Name',
-  'acct_tunnel_connection_i' => 'Acct-Tunnel-Connection-Id',
-  'h323_prompt_id' => 'h323-prompt-id',
-  'x_ascend_ipx_peer_mode' => 'X-Ascend-IPX-Peer-Mode',
-  'ascend_numbering_plan_id' => 'Ascend-Numbering-Plan-ID',
-  'x_ascend_ts_idle_limit' => 'X-Ascend-TS-Idle-Limit',
-  'ascend_atm_fault_managem' => 'Ascend-ATM-Fault-Management',
-  'annex_primary_nbns_serve' => 'Annex-Primary-NBNS-Server',
-  'lac_port_type' => 'LAC_Port_Type',
+  'erx_secondary_wins' => 'ERX-Secondary-Wins',
+  'usr_rmmie_serial_number' => 'USR-RMMIE-Serial-Number',
+  'usr_et_bridge_input_filt' => 'USR-ET-Bridge-Input-Filter',
+  'ns_primary_dns' => 'NS-Primary-DNS',
+  'usr_slot_connected_to' => 'USR-Slot-Connected-To',
+  'shiva_disconnect_reason' => 'Shiva-Disconnect-Reason',
+  'cvpn5000_client_assignee' => 'CVPN5000-Client-Assigned-IPX',
+  'cvx_radius_redirect' => 'CVX-Radius-Redirect',
+  'usr_receive_acc_map' => 'USR-Receive-Acc-Map',
+  'x_ascend_tunneling_proto' => 'X-Ascend-Tunneling-Protocol',
+  'itk_acct_serv_ip' => 'ITK-Acct-Serv-IP',
+  'ascend_fr_type' => 'Ascend-FR-Type',
+  'ascend_client_assign_dns' => 'Ascend-Client-Assign-DNS',
+  'annex_retrain_requests_r' => 'Annex-Retrain-Requests-Rcvd',
+  'x_ascend_assign_ip_globa' => 'X-Ascend-Assign-IP-Global-Pool',
+  'tunnel_client_endpoint' => 'Tunnel-Client-Endpoint',
+  'alteon_service_type' => 'Alteon-Service-Type',
+  'x_ascend_send_secret' => 'X-Ascend-Send-Secret',
+  'x_ascend_call_filter' => 'X-Ascend-Call-Filter',
+  'usr_ipx_rip_input_filter' => 'USR-IPX-RIP-Input-Filter',
+  'x_ascend_maximum_time' => 'X-Ascend-Maximum-Time',
+  'pvc_profile_name' => 'PVC-Profile-Name',
+  'usr_framed_ip_address_po' => 'USR-Framed_IP_Address_Pool_Name',
+  'cvpn3000_ipsec_split_dns' => 'CVPN3000-IPSec-Split-DNS-Names',
+  'ascend_global_call_id' => 'Ascend-Global-Call-Id',
   'usr_initial_rx_link_data' => 'USR-Initial-Rx-Link-Data-Rate',
-  'usr_interface_index' => 'USR-Interface-Index',
-  'usr_expansion_algorithm' => 'USR-Expansion-Algorithm',
-  'ascend_tunnel_vrouter_na' => 'Ascend-Tunnel-VRouter-Name',
-  'usr_pw_vpn_neighbor' => 'USR-PW_VPN_Neighbor',
-  'bind_type' => 'Bind_Type',
-  'acc_ccp_option' => 'Acc-Ccp-Option',
+  'st_primary_nbns_server' => 'ST-Primary-NBNS-Server',
+  'usr_number_of_rings_limi' => 'USR-Number-of-Rings-Limit',
+  'tunnel_local_name' => 'Tunnel-Local-Name',
+  'ascend_fr_t392' => 'Ascend-FR-T392',
+  'annex_pool_id' => 'Annex-Pool-Id',
+  'ascend_token_immediate' => 'Ascend-Token-Immediate',
+  'usr_rmmie_firmware_build' => 'USR-RMMIE-Firmware-Build-Date',
+  'wispr_bandwidth_min_down' => 'WISPr-Bandwidth-Min-Down',
+  'usr_chassis_call_slot' => 'USR-Chassis-Call-Slot',
+  'rate_limit_burst' => 'Rate-Limit-Burst',
+  'cisco_route_ip' => 'Cisco-Route-IP',
+  'xedia_netbios_server' => 'Xedia-NetBios-Server',
+  'session_error_msg' => 'Session-Error-Msg',
+  'dhcp_max_leases' => 'DHCP-Max-Leases',
+  'acc_vpsm_reject_cause' => 'Acc-Vpsm-Reject-Cause',
+  'user_category' => 'User-Category',
+  'x_ascend_multicast_rate_' => 'X-Ascend-Multicast-Rate-Limit',
+  'cvpn3000_ipsec_auth_on_r' => 'CVPN3000-IPSec-Auth-On-Rekey',
+  'altiga_min_password_leng' => 'Altiga-Min-Password-Length-G',
+  'bind_type' => 'Bind-Type',
+  'ascend_tunneling_protoco' => 'Ascend-Tunneling-Protocol',
+  'cvx_modem_retx_packets' => 'CVX-Modem-ReTx-Packets',
+  'usr_framed_ipx_route' => 'USR-Framed-IPX-Route',
+  'rate_limit_rate' => 'Rate-Limit-Rate',
+  'ascend_atm_connect_vpi' => 'Ascend-ATM-Connect-Vpi',
+  'connect_info' => 'Connect-Info',
+  'usr_port_tap_address' => 'USR-Port-Tap-Address',
+  'usr_simplified_mnp_level' => 'USR-Simplified-MNP-Levels',
+  'mcast_receivf' => 'Mcast_Receive',
+  'annex_begin_modulation' => 'Annex-Begin-Modulation',
+  'usr_pw_usr_ifilter_ip' => 'USR-PW_USR_IFilter_IP',
   'ascend_route_appletalk' => 'Ascend-Route-Appletalk',
-  'erx_alternate_cli_access' => 'ERX-Alternate-Cli-Access-Level',
-  'usr_at_rtmp_output_filte' => 'USR-AT-RTMP-Output-Filter',
-  'erx_atm_mbs' => 'ERX-Atm-MBS',
-  'usr_at_call_output_filte' => 'USR-AT-Call-Output-Filter',
-  'ms_old_arap_password' => 'MS-Old-ARAP-Password',
-  'x_ascend_client_primary_' => 'X-Ascend-Client-Primary-DNS',
-  'x_ascend_host_info' => 'X-Ascend-Host-Info',
-  'bind_auth_protocol' => 'Bind_Auth_Protocol',
-  'cisco_link_compression' => 'Cisco-Link-Compression',
-  'annex_syslog_tap' => 'Annex-Syslog-Tap',
-  'tunnel_window' => 'Tunnel_Window',
-  'usr_gateway_ip_address' => 'USR-Gateway-IP-Address',
-  'ascend_redirect_number' => 'Ascend-Redirect-Number',
-  'x_ascend_secondary_home_' => 'X-Ascend-Secondary-Home-Agent',
-  'usr_pw_index' => 'USR-PW_Index',
-  'le_multicast_client' => 'LE-Multicast-Client',
-  'annex_modem_disc_reason' => 'Annex-Modem-Disc-Reason',
-  'annex_primary_dns_server' => 'Annex-Primary-DNS-Server',
-  'erx_secondary_wins' => 'ERX-Secondary-Wins',
-  'fall_through' => 'Fall-Through',
-  'acct_mcast_out_packets' => 'Acct_Mcast_Out_Packets',
-  'x_ascend_transit_number' => 'X-Ascend-Transit-Number',
-  'usr_unauthenticated_time' => 'USR-Unauthenticated-Time',
-  'le_ipsec_active_profile' => 'LE-IPSec-Active-Profile',
-  'ascend_ip_pool_chaining' => 'Ascend-IP-Pool-Chaining',
-  'usr_syslog_tap' => 'USR-Syslog-Tap',
-  'ascend_multicast_client' => 'Ascend-Multicast-Client',
-  'usr_device_connected_to' => 'USR-Device-Connected-To',
-  'tunnel_l2f_second_passwo' => 'Tunnel_L2F_Second_Password',
-  'add_prefix' => 'Add-Prefix',
-  'tunnel_cmd_timeout' => 'Tunnel_Cmd_Timeout',
-  'x_ascend_remove_seconds' => 'X-Ascend-Remove-Seconds',
-  'acct_mcast_in_octets' => 'Acct_Mcast_In_Octets',
-  'ascend_appletalk_route' => 'Ascend-Appletalk-Route',
-  'ascend_fcp_parameter' => 'Ascend-FCP-Parameter',
-  'acc_ip_compression' => 'Acc-Ip-Compression',
-  'usr_modem_training_time' => 'USR-Modem-Training-Time',
-  'usr_primary_dns_server' => 'USR-Primary_DNS_Server',
-  'erx_egress_policy_name' => 'ERX-Egress-Policy-Name',
-  'x_ascend_base_channel_co' => 'X-Ascend-Base-Channel-Count',
-  'x_ascend_pre_input_packe' => 'X-Ascend-Pre-Input-Packets',
-  'password_retry' => 'Password-Retry',
-  'ascend_source_auth' => 'Ascend-Source-Auth',
-  'cisco_pw_lifetime' => 'Cisco-PW-Lifetime',
-  'acc_dns_server_pri' => 'Acc-Dns-Server-Pri',
-  'ascend_netware_timeout' => 'Ascend-Netware-timeout',
-  'ascend_ppp_async_map' => 'Ascend-PPP-Async-Map',
-  'usr_rad_multicast_routin' => 'USR-Rad-Multicast-Routing-Ttl',
-  'x_ascend_modem_slotno' => 'X-Ascend-Modem-SlotNo',
-  'x_ascend_ip_direct' => 'X-Ascend-IP-Direct',
-  'simultaneous_use' => 'Simultaneous-Use',
-  'erx_virtual_router_name' => 'ERX-Virtual-Router-Name',
-  'ascend_bridge_non_pppoe' => 'Ascend-Bridge-Non-PPPoE',
-  'ascend_fr_08_mode' => 'Ascend-FR-08-Mode',
-  'h323_call_type' => 'h323-call-type',
-  'tunnel_context' => 'Tunnel_Context',
-  'usr_transmit_acc_map' => 'USR-Transmit-Acc-Map',
+  'ms_chap_lm_enc_pw' => 'MS-CHAP-LM-Enc-PW',
+  'altiga_ipsec_over_nat_po' => 'Altiga-IPSec-Over-NAT-Port-Num-G',
+  'itk_isdn_prot' => 'ITK-ISDN-Prot',
+  'ascend_callback_delay' => 'Ascend-Callback-Delay',
+  'session_error_code' => 'Session-Error-Code',
+  'nomadix_endofsession' => 'Nomadix-EndofSession',
+  'x_ascend_bacp_enable' => 'X-Ascend-BACP-Enable',
+  'bg_trans_bpdu' => 'BG-Trans-BPDU',
+  'bind_int_interface_namf' => 'Bind_Int_Interface_Name',
+  'foundry_privilege_level' => 'Foundry-Privilege-Level',
+  'huntgroup_name' => 'Huntgroup-Name',
+  'x_ascend_ipx_alias' => 'X-Ascend-IPX-Alias',
+  'tunnel_l2f_second_passwp' => 'Tunnel_L2F_Second_Password',
+  'xedia_dns_server' => 'Xedia-DNS-Server',
   'usr_ipx_wan' => 'USR-IPX-WAN',
-  'usr_ip_call_input_filter' => 'USR-IP-Call-Input-Filter',
+  'annex_addr_resolution_se' => 'Annex-Addr-Resolution-Servers',
+  'acct_output_octets_65' => 'Acct_Output_Octets_64',
+  'menu' => 'Menu',
+  'erx_tunnel_nas_port_meth' => 'ERX-Tunnel-Nas-Port-Method',
+  'aat_output_octets_diff' => 'AAT-Output-Octets-Diff',
+  'x_ascend_fr_direct_dlci' => 'X-Ascend-FR-Direct-DLCI',
+  'acct_status_type' => 'Acct-Status-Type',
+  'ascend_port_redir_server' => 'Ascend-Port-Redir-Server',
+  'telebit_port_name' => 'Telebit-Port-Name',
+  'acc_dns_server_sec' => 'Acc-Dns-Server-Sec',
+  'cvx_modem_remote_retrain' => 'CVX-Modem-Remote-Retrains',
+  'ascend_minimum_channels' => 'Ascend-Minimum-Channels',
+  'ascend_ipx_route' => 'Ascend-IPX-Route',
+  'ascend_telnet_profile' => 'Ascend-Telnet-Profile',
   'usr_call_connect_in_gmt' => 'USR-Call-Connect-in-GMT',
-  'acct_multi_session_id' => 'Acct-Multi-Session-Id',
-  'usr_reply_script1' => 'USR-Reply-Script1',
-  'cisco_ppp_vj_slot_comp' => 'Cisco-PPP-VJ-Slot-Comp',
-  'usr_reply_script2' => 'USR-Reply-Script2',
-  'usr_reply_script3' => 'USR-Reply-Script3',
-  'usr_reply_script4' => 'USR-Reply-Script4',
-  'usr_reply_script5' => 'USR-Reply-Script5',
-  'usr_reply_script6' => 'USR-Reply-Script6',
-  'user_category' => 'User-Category',
-  'mcast_send' => 'Mcast_Send',
-  'ascend_send_secret' => 'Ascend-Send-Secret',
-  'usr_tunnel_switch_endpoi' => 'USR-Tunnel-Switch-Endpoint',
-  'tunnel_retransmit' => 'Tunnel_Retransmit',
-  'add_port_to_ip_address' => 'Add-Port-To-IP-Address',
-  'ascend_ipx_node_addr' => 'Ascend-IPX-Node-Addr',
-  'x_ascend_netware_timeout' => 'X-Ascend-Netware-timeout',
-  'erx_sa_validate' => 'ERX-Sa-Validate',
-  'le_ipsec_passive_profile' => 'LE-IPSec-Passive-Profile',
-  'usr_chassis_slot' => 'USR-Chassis-Slot',
-  'usr_final_tx_link_data_r' => 'USR-Final-Tx-Link-Data-Rate',
+  'usr_cusr_hat_script_rule' => 'USR-CUSR-hat-Script-Rules',
+  'x_ascend_dba_monitor' => 'X-Ascend-DBA-Monitor',
+  'response_packet_type' => 'Response-Packet-Type',
+  'usr_event_id' => 'USR-Event-Id',
+  'cvpn3000_ipsec_over_udp_' => 'CVPN3000-IPSec-Over-UDP-Port',
+  'ascend_inc_channel_count' => 'Ascend-Inc-Channel-Count',
+  'usr_send_script3' => 'USR-Send-Script3',
+  'annex_pre_input_packets' => 'Annex-Pre-Input-Packets',
+  'framed_callback_id' => 'Framed-Callback-Id',
+  'xedia_client_access_netw' => 'Xedia-Client-Access-Network',
+  'arap_zone_access' => 'ARAP-Zone-Access',
+  'ascend_port_redir_portnu' => 'Ascend-Port-Redir-Portnum',
+  'service_type' => 'Service-Type',
   'usr_nfas_id' => 'USR-NFAS-ID',
-  'called_station_id' => 'Called-Station-Id',
-  'login_lat_port' => 'Login-LAT-Port',
-  'ascend_dialed_number' => 'Ascend-Dialed-Number',
-  'h323_credit_amount' => 'h323-credit-amount',
-  'tunnel_local_name' => 'Tunnel_Local_Name',
-  'framed_ip_netmask' => 'Framed-IP-Netmask',
-  'client_port_id' => 'Client-Port-Id',
-  'bg_span_dis' => 'BG_Span_Dis',
-  'multi_link_flag' => 'Multi-Link-Flag',
-  'bind_sub_user_at_context' => 'Bind_Sub_User_At_Context',
-  'usr_ipx_routing' => 'USR-IPX-Routing',
-  'ascend_fr_nailed_grp' => 'Ascend-FR-Nailed-Grp',
-  'ascend_pre_output_octets' => 'Ascend-Pre-Output-Octets',
-  'pppoe_url' => 'PPPOE_URL',
-  'ascend_ara_pw' => 'Ascend-Ara-PW',
-  'acc_callback_mode' => 'Acc-Callback-Mode',
-  'usr_server_time' => 'USR-Server-Time',
-  'ascend_seconds_of_histor' => 'Ascend-Seconds-Of-History',
-  'ns_mta_md5_password' => 'NS-MTA-MD5-Password',
-  'tunnel_server_endpoint' => 'Tunnel-Server-Endpoint',
-  'usr_channel' => 'USR-Channel',
-  'ascend_dsl_cir_recv_limi' => 'Ascend-Dsl-CIR-Recv-Limit',
-  'acct_session_start_time' => 'Acct-Session-Start-Time',
-  'ascend_send_passwd' => 'Ascend-Send-Passwd',
-  'ascend_num_in_multilink' => 'Ascend-Num-In-Multilink',
-  'usr_ip_rip_policies' => 'USR-IP-RIP-Policies',
-  'vendor_specific' => 'Vendor-Specific',
-  'x_ascend_event_type' => 'X-Ascend-Event-Type',
-  'lac_real_port_type' => 'LAC_Real_Port_Type',
-  'x_ascend_modem_portno' => 'X-Ascend-Modem-PortNo',
-  'usr_originate_answer_mod' => 'USR-Originate-Answer-Mode',
-  'framed_ipx_network' => 'Framed-IPX-Network',
+  'shiva_calling_number' => 'Shiva-Calling-Number',
+  'ascend_user_acct_host' => 'Ascend-User-Acct-Host',
+  'tunnel_session_auth_serv' => 'Tunnel-Session-Auth-Service-Grp',
+  'juniper_deny_commands' => 'Juniper-Deny-Commands',
+  'ascend_fr_link_mgt' => 'Ascend-FR-Link-Mgt',
+  'nokia_imsi' => 'Nokia-IMSI',
+  'quintum_h323_prompt_id' => 'Quintum-h323-prompt-id',
+  'cvpn3000_require_individ' => 'CVPN3000-Require-Individual-User-Auth',
+  'tunnel_retransmiu' => 'Tunnel_Retransmit',
+  'source_validatioo' => 'Source_Validation',
+  'sip_to' => 'Sip-To',
+  'ms_primary_nbns_server' => 'MS-Primary-NBNS-Server',
+  'quintum_avpair' => 'Quintum-AVPair',
+  'ascend_transit_number' => 'Ascend-Transit-Number',
+  'ascend_cache_refresh' => 'Ascend-Cache-Refresh',
+  'ascend_user_acct_type' => 'Ascend-User-Acct-Type',
+  'usr_num_fax_pages_proces' => 'USR-Num-Fax-Pages-Processed',
+  'usr_mic' => 'USR-MIC',
+  'usr_failure_to_connect_r' => 'USR-Failure-to-Connect-Reason',
+  'cisco_fax_auth_status' => 'Cisco-Fax-Auth-Status',
+  'bind_dot1q_vlan_tag_ie' => 'Bind_Dot1q_Vlan_Tag_Id',
+  'ms_chap2_success' => 'MS-CHAP2-Success',
+  'erx_tunnel_virtual_route' => 'ERX-Tunnel-Virtual-Router',
+  'cisco_idle_limit' => 'Cisco-Idle-Limit',
+  'ascend_pw_lifetime' => 'Ascend-PW-Lifetime',
+  'cvpn3000_access_hours' => 'CVPN3000-Access-Hours',
+  'bintec_sapcirctable' => 'BinTec-sapCircTable',
+  'usr_packet_bus_session' => 'USR-Packet-Bus-Session',
+  'acct_input_packets_64' => 'Acct-Input-Packets-64',
+  'ascend_x25_pad_x3_parame' => 'Ascend-X25-Pad-X3-Parameters',
+  'usr_secondary_nbns_serve' => 'USR-Secondary_NBNS_Server',
   'ascend_modem_slotno' => 'Ascend-Modem-SlotNo',
-  'ms_mppe_encryption_type' => 'MS-MPPE-Encryption-Type',
-  'annex_cli_command' => 'Annex-CLI-Command',
-  'acct_status_type' => 'Acct-Status-Type',
-  'usr_et_bridge_call_outpu' => 'USR-ET-Bridge-Call-Output-Filte',
-  'usr_pw_vpn_id' => 'USR-PW_VPN_ID',
+  'digest_qop' => 'Digest-QOP',
+  'usr_characters_received' => 'USR-Characters-Received',
+  'rate_limit_ratf' => 'Rate_Limit_Rate',
+  'ms_bap_usage' => 'MS-BAP-Usage',
+  'cisco_data_filter' => 'Cisco-Data-Filter',
+  'usr_simplified_v42bis_us' => 'USR-Simplified-V42bis-Usage',
+  'h323_setup_time' => 'h323-setup-time',
+  'annex_wan_number' => 'Annex-Wan-Number',
+  'cvx_vpop_id' => 'CVX-VPOP-ID',
+  'usr_pw_tunnel_authentica' => 'USR-PW_Tunnel_Authentication',
+  'le_nat_outsource_inmap' => 'LE-NAT-Outsource-Inmap',
+  'cvx_modem_begin_recv_lin' => 'CVX-Modem-Begin-Recv-Line-Lvl',
+  'telebit_login_command' => 'Telebit-Login-Command',
+  'cisco_command_code' => 'Cisco-Command-Code',
+  'itk_ppp_auth_type' => 'ITK-PPP-Auth-Type',
+  'bintec_qosiftable' => 'BinTec-qosIfTable',
+  'x_ascend_mpp_idle_percen' => 'X-Ascend-MPP-Idle-Percent',
   'usr_sap_filter_in' => 'USR-SAP-Filter-In',
-  'usr_rad_multicast_routin' => 'USR-Rad-Multicast-Routing-Proto',
-  'annex_audit_level' => 'Annex-Audit-Level',
-  'x_ascend_shared_profile_' => 'X-Ascend-Shared-Profile-Enable',
+  'framed_appletalk_link' => 'Framed-AppleTalk-Link',
+  'tunnel_domaio' => 'Tunnel_Domain',
+  'usr_ipx' => 'USR-IPX',
+  'nas_real_poru' => 'NAS_Real_Port',
+  'shiva_connect_reason' => 'Shiva-Connect-Reason',
+  'x_ascend_pre_output_octe' => 'X-Ascend-Pre-Output-Octets',
+  'cisco_ppp_vj_slot_comp' => 'Cisco-PPP-VJ-Slot-Comp',
+  'freeradius_proxied_to' => 'Freeradius-Proxied-To',
+  'ascend_atm_vpi' => 'Ascend-ATM-Vpi',
+  'acc_ml_mlx_admin_state' => 'Acc-ML-MLX-Admin-State',
+  'cvx_modem_snr' => 'CVX-Modem-SNR',
+  'usr_igmp_robustness' => 'USR-IGMP-Robustness',
+  'annex_rate_reneg_req_rcv' => 'Annex-Rate-Reneg-Req-Rcvd',
+  'add_prefix' => 'Add-Prefix',
+  'x_ascend_call_by_call' => 'X-Ascend-Call-By-Call',
+  'usr_last_callers_number_' => 'USR-Last-Callers-Number-ANI',
+  'postauth_type' => 'PostAuth-Type',
+  'pvc_circuit_paddinh' => 'PVC_Circuit_Padding',
+  'usr_at_rtmp_input_filter' => 'USR-AT-RTMP-Input-Filter',
+  'erx_igmp_enable' => 'ERX-Igmp-Enable',
+  'bind_bypass_contexu' => 'Bind_Bypass_Context',
+  'x_ascend_num_in_multilin' => 'X-Ascend-Num-In-Multilink',
+  'usr_pw_packet' => 'USR-PW_Packet',
+  'dialback_no' => 'Dialback-No',
+  'ascend_ip_tos_precedence' => 'Ascend-IP-TOS-Precedence',
+  'cvpn5000_vpn_password' => 'CVPN5000-VPN-Password',
+  'annex_cli_filter' => 'Annex-CLI-Filter',
+  'x_ascend_dial_number' => 'X-Ascend-Dial-Number',
+  'usr_iwf_call_identifier' => 'USR-IWF-Call-Identifier',
+  'ms_secondary_dns_server' => 'MS-Secondary-DNS-Server',
+  'shiva_type_of_service' => 'Shiva-Type-Of-Service',
+  'bind_ses_context' => 'Bind-Ses-Context',
+  'acc_reason_code' => 'Acc-Reason-Code',
+  'ms_chap_cpw_1' => 'MS-CHAP-CPW-1',
+  'wispr_bandwidth_max_down' => 'WISPr-Bandwidth-Max-Down',
+  'h323_call_type' => 'h323-call-type',
+  'bind_bypass_bypast' => 'Bind_Bypass_Bypass',
+  'usr_number_of_link_timeo' => 'USR-Number-of-Link-Timeouts',
+  'ascend_fr_08_mode' => 'Ascend-FR-08-Mode',
+  'usr_calling_party_number' => 'USR-Calling-Party-Number',
+  'usr_reply_script2' => 'USR-Reply-Script2',
+  'usr_security_login_limit' => 'USR-Security-Login-Limit',
+  'cisco_link_compression' => 'Cisco-Link-Compression',
+  'ascend_vrouter_name' => 'Ascend-VRouter-Name',
+  'erx_ppp_auth_protocol' => 'ERX-PPP-Auth-Protocol',
+  'x_ascend_call_block_dura' => 'X-Ascend-Call-Block-Duration',
+  'usr_modem_setup_time' => 'USR-Modem-Setup-Time',
+  'pppoe_urm' => 'PPPOE_URL',
+  'cisco_ip_direct' => 'Cisco-IP-Direct',
+  'x_ascend_temporary_rtes' => 'X-Ascend-Temporary-Rtes',
+  'ascend_x25_pad_alias_3' => 'Ascend-X25-Pad-Alias-3',
+  'annex_multilink_id' => 'Annex-Multilink-Id',
+  'mcast_maxgroupt' => 'Mcast_MaxGroups',
+  'configuration_token' => 'Configuration-Token',
+  'ascend_h323_conference_i' => 'Ascend-H323-Conference-Id',
+  'ascend_ipx_header_compre' => 'Ascend-IPX-Header-Compression',
+  'stripped_user_name' => 'Stripped-User-Name',
+  'usr_ipx_rip_output_filte' => 'USR-IPX-RIP-Output-Filter',
+  'cisco_call_filter' => 'Cisco-Call-Filter',
+  'nas_ipv6_address' => 'NAS-IPv6-Address',
+  'termination_menu' => 'Termination-Menu',
+  'ascend_shared_profile_en' => 'Ascend-Shared-Profile-Enable',
+  'port_message' => 'Port-Message',
+  'erx_ingress_policy_name' => 'ERX-Ingress-Policy-Name',
+  'acc_service_profile' => 'Acc-Service-Profile',
+  'ascend_bir_proxy' => 'Ascend-BIR-Proxy',
+  'aat_ppp_address' => 'AAT-PPP-Address',
+  'usr_mbi_ct_pri_card_span' => 'USR-Mbi_Ct_PRI_Card_Span_Line',
+  'ascend_x25_nui_prompt' => 'Ascend-X25-Nui-Prompt',
+  'itk_modem_pool_id' => 'ITK-Modem-Pool-Id',
+  'usr_compression_reset_mo' => 'USR-Compression-Reset-Mode',
+  'usr_unauthenticated_time' => 'USR-Unauthenticated-Time',
+  'ascend_multicast_gleave_' => 'Ascend-Multicast-GLeave-Delay',
+  'acc_callback_cbcp_type' => 'Acc-Callback-CBCP-Type',
+  'medium_typf' => 'Medium_Type',
+  'login_service' => 'Login-Service',
+  'itk_username_prompt' => 'ITK-Username-Prompt',
   'ascend_dial_number' => 'Ascend-Dial-Number',
-  'ascend_link_compression' => 'Ascend-Link-Compression',
-  'usr_event_date_time' => 'USR-Event-Date-Time',
-  'usr_mp_edo_hiper' => 'USR-MP-EDO-HIPER',
-  'usr_re_chap_timeout' => 'USR-Re-Chap-Timeout',
-  'x_ascend_third_prompt' => 'X-Ascend-Third-Prompt',
-  'x_ascend_ppp_vj_1172' => 'X-Ascend-PPP-VJ-1172',
-  'annex_disconnect_reason' => 'Annex-Disconnect-Reason',
-  'ascend_fr_svc_addr' => 'Ascend-FR-SVC-Addr',
-  'nas_real_port' => 'NAS_Real_Port',
+  'framed_ipv6_route' => 'Framed-IPv6-Route',
+  'x_ascend_remote_addr' => 'X-Ascend-Remote-Addr',
+  'usr_call_end_date_time' => 'USR-Call-End-Date-Time',
+  'bind_dot1q_slot' => 'Bind-Dot1q-Slot',
+  'le_connect_detail' => 'LE-Connect-Detail',
+  'annex_user_level' => 'Annex-User-Level',
+  'tunnel_dnis' => 'Tunnel-DNIS',
+  'assigned_ip_address' => 'Assigned-IP-Address',
+  'acc_bridging_support' => 'Acc-Bridging-Support',
+  'usr_channel' => 'USR-Channel',
+  'arap_security_data' => 'ARAP-Security-Data',
+  'bind_auth_service_grp' => 'Bind-Auth-Service-Grp',
+  'cisco_abort_cause' => 'Cisco-Abort-Cause',
+  'bg_span_dit' => 'BG_Span_Dis',
+  'h323_voice_quality' => 'h323-voice-quality',
+  'lac_real_port_typf' => 'LAC_Real_Port_Type',
+  'usr_channel_connected_to' => 'USR-Channel-Connected-To',
+  'ascend_client_assign_win' => 'Ascend-Client-Assign-WINS',
+  'redcreek_tunneled_gatewa' => 'RedCreek-Tunneled-Gateway',
+  'usr_number_of_fallbacks' => 'USR-Number-of-Fallbacks',
+  'nokia_prepaid_ind' => 'Nokia-Prepaid-Ind',
+  'nomadix_maxbytesup' => 'Nomadix-MaxBytesUp',
+  'login_hosu' => 'Login-Host',
+  'ascend_bir_enable' => 'Ascend-BIR-Enable',
+  'usr_connect_time_limit' => 'USR-Connect-Time-Limit',
+  'ascend_presession_time' => 'Ascend-PreSession-Time',
+  'altiga_simultaneous_logi' => 'Altiga-Simultaneous-Logins-G/U',
+  'cvpn3000_ipsec_default_d' => 'CVPN3000-IPSec-Default-Domain',
+  'aat_atm_vci' => 'AAT-ATM-VCI',
+  'extreme_netlogin_url_des' => 'Extreme-Netlogin-Url-Desc',
+  'itk_auth_serv_ip' => 'ITK-Auth-Serv-IP',
+  'erx_alternate_cli_vroute' => 'ERX-Alternate-Cli-Vrouter-Name',
+  'framed_compression' => 'Framed-Compression',
+  'ascend_svc_enabled' => 'Ascend-SVC-Enabled',
+  'proxy_state' => 'Proxy-State',
+  'aat_vrouter_name' => 'AAT-Vrouter-Name',
+  'usr_rmmie_pwrlvl_farecho' => 'USR-RMMIE-PwrLvl-FarEcho-Canc',
+  'nas_poru' => 'NAS-Port',
+  'wispr_location_name' => 'WISPr-Location-Name',
+  'digest_user_name' => 'Digest-User-Name',
+  'ascend_modem_shelfno' => 'Ascend-Modem-ShelfNo',
+  'shasta_user_privilege' => 'Shasta-User-Privilege',
+  'bind_auth_protocol' => 'Bind-Auth-Protocol',
+  'ascend_home_agent_passwo' => 'Ascend-Home-Agent-Password',
+  'acct_interim_interval' => 'Acct-Interim-Interval',
+  'ascend_history_weigh_typ' => 'Ascend-History-Weigh-Type',
+  'ms_link_drop_time_limit' => 'MS-Link-Drop-Time-Limit',
+  'hint' => 'Hint',
+  'x_ascend_target_util' => 'X-Ascend-Target-Util',
+  'acc_access_partition' => 'Acc-Access-Partition',
   'usr_power_supply_number' => 'USR-Power-Supply-Number',
-  'ms_secondary_dns_server' => 'MS-Secondary-DNS-Server',
-  'ascend_port_redir_server' => 'Ascend-Port-Redir-Server',
+  'x_ascend_multilink_id' => 'X-Ascend-Multilink-ID',
+  'redcreek_tunneled_domain' => 'RedCreek-Tunneled-DomainName',
+  'nomadix_bw_down' => 'Nomadix-Bw-Down',
+  'acc_ipx_compression' => 'Acc-Ipx-Compression',
+  'quintum_h323_setup_time' => 'Quintum-h323-setup-time',
+  'cisco_target_util' => 'Cisco-Target-Util',
+  'acc_ip_gateway_sec' => 'Acc-Ip-Gateway-Sec',
+  'ascend_dsl_cir_xmit_limi' => 'Ascend-Dsl-CIR-Xmit-Limit',
+  'ascend_ip_pool_definitio' => 'Ascend-IP-Pool-Definition',
+  'bind_sub_user_at_contexu' => 'Bind_Sub_User_At_Context',
+  'itk_dest_no' => 'ITK-Dest-No',
+  'usr_connect_time' => 'USR-Connect-Time',
+  'usr_call_start_date_time' => 'USR-Call-Start-Date-Time',
+  'altiga_l2tp_encryption_g' => 'Altiga-L2TP-Encryption-G',
+  'ascend_auth_delay' => 'Ascend-Auth-Delay',
+  'ascend_x25_pad_x3_profil' => 'Ascend-X25-Pad-X3-Profile',
+  'ascend_access_intercepta' => 'Ascend-Access-Intercept-Log',
+  'ascend_home_agent_udp_po' => 'Ascend-Home-Agent-UDP-Port',
+  'bind_tun_context' => 'Bind-Tun-Context',
+  'dialback_name' => 'Dialback-Name',
+  'h323_redirect_ip_address' => 'h323-redirect-ip-address',
+  'annex_keypress_timeout' => 'Annex-Keypress-Timeout',
+  'x_ascend_home_network_na' => 'X-Ascend-Home-Network-Name',
   'ascend_x25_pad_alias_1' => 'Ascend-X25-Pad-Alias-1',
+  'ascend_call_attempt_limi' => 'Ascend-Call-Attempt-Limit',
+  'quintum_h323_currency_ty' => 'Quintum-h323-currency-type',
+  'ms_chap_response' => 'MS-CHAP-Response',
+  'st_secondary_nbns_server' => 'ST-Secondary-NBNS-Server',
+  'x_ascend_history_weigh_t' => 'X-Ascend-History-Weigh-Type',
+  'usr_max_channels' => 'USR-Max-Channels',
+  'ascend_fr_dte_n393' => 'Ascend-FR-DTE-N393',
+  'ascend_pre_input_octets' => 'Ascend-Pre-Input-Octets',
+  'erx_atm_mbs' => 'ERX-Atm-MBS',
+  'cvpn3000_simultaneous_lo' => 'CVPN3000-Simultaneous-Logins',
+  'juniper_allow_commands' => 'Juniper-Allow-Commands',
+  'usr_line_reversals' => 'USR-Line-Reversals',
+  'itk_users_default_pw' => 'ITK-Users-Default-Pw',
+  'x_ascend_third_prompt' => 'X-Ascend-Third-Prompt',
+  'cisco_fax_msg_id' => 'Cisco-Fax-Msg-Id',
+  'x_ascend_pw_warntime' => 'X-Ascend-PW-Warntime',
+  'ascend_data_filter' => 'Ascend-Data-Filter',
+  'framed_address' => 'Framed-Address',
+  'context_name' => 'Context-Name',
+  'usr_send_script2' => 'USR-Send-Script2',
+  'ms_arap_pw_change_reason' => 'MS-ARAP-PW-Change-Reason',
+  'tunnel_session_auth_cty' => 'Tunnel_Session_Auth_Ctx',
+  'acct_session_id' => 'Acct-Session-Id',
+  'annex_port' => 'Annex-Port',
+  'quintum_h323_call_origin' => 'Quintum-h323-call-origin',
+  'erx_cli_initial_access_l' => 'ERX-Cli-Initial-Access-Level',
+  'x_ascend_shared_profile_' => 'X-Ascend-Shared-Profile-Enable',
+  'tunnel_cmd_timeouu' => 'Tunnel_Cmd_Timeout',
+  'initial_modulation_type' => 'Initial-Modulation-Type',
+  'ascend_h323_gatekeeper' => 'Ascend-H323-Gatekeeper',
   'x_ascend_fcp_parameter' => 'X-Ascend-FCP-Parameter',
-  'ascend_x25_pad_alias_2' => 'Ascend-X25-Pad-Alias-2',
-  'ascend_ipsec_profile' => 'Ascend-IPSEC-Profile',
-  'ascend_x25_pad_alias_3' => 'Ascend-X25-Pad-Alias-3',
-  'usr_mobile_numbytes_txed' => 'USR-Mobile-NumBytes-Txed',
-  'ascend_atm_vpi' => 'Ascend-ATM-Vpi',
-  'annex_input_filter' => 'Annex-Input-Filter',
-  'menu' => 'Menu',
-  'x_ascend_route_ip' => 'X-Ascend-Route-IP',
-  'usr_rmmie_num_of_updates' => 'USR-RMMIE-Num-Of-Updates',
-  'acc_request_type' => 'Acc-Request-Type',
-  'ascend_dhcp_reply' => 'Ascend-DHCP-Reply',
-  'usr_number_of_upshifts' => 'USR-Number-of-Upshifts',
-  'usr_rmmie_firmware_versi' => 'USR-RMMIE-Firmware-Version',
-  'bind_bypass_context' => 'Bind_Bypass_Context',
-  'ascend_dialout_allowed' => 'Ascend-Dialout-Allowed',
-  'annex_tunnel_authen_type' => 'Annex-Tunnel-Authen-Type',
-  'x_ascend_bridge' => 'X-Ascend-Bridge',
-  'ascend_client_secondary_' => 'Ascend-Client-Secondary-WINS',
-  'erx_local_loopback_inter' => 'ERX-Local-Loopback-Interface',
-  'acct_input_gigawords' => 'Acct-Input-Gigawords',
-  'usr_equalization_type' => 'USR-Equalization-Type',
-  'usr_port_tap_format' => 'USR-Port-Tap-Format',
-  'x_ascend_ppp_async_map' => 'X-Ascend-PPP-Async-Map',
-  'acc_ipx_compression' => 'Acc-Ipx-Compression',
-  'ascend_nas_port_format' => 'Ascend-NAS-Port-Format',
-  'acc_modem_modulation_typ' => 'Acc-Modem-Modulation-Type',
-  'ascend_modem_portno' => 'Ascend-Modem-PortNo',
-  'usr_et_bridge_output_fil' => 'USR-ET-Bridge-Output-Filter',
-  'ascend_ipx_header_compre' => 'Ascend-IPX-Header-Compression',
-  'framed_appletalk_link' => 'Framed-AppleTalk-Link',
-  'x_ascend_receive_secret' => 'X-Ascend-Receive-Secret',
-  'ascend_route_ipx' => 'Ascend-Route-IPX',
-  'ascend_user_acct_type' => 'Ascend-User-Acct-Type',
-  'ascend_token_idle' => 'Ascend-Token-Idle',
-  'framed_ip_address' => 'Framed-IP-Address',
-  'ascend_call_block_durati' => 'Ascend-Call-Block-Duration',
-  'ascend_ppp_address' => 'Ascend-PPP-Address',
-  'usr_mbi_ct_pri_card_slot' => 'USR-Mbi_Ct_PRI_Card_Slot',
-  'x_ascend_dec_channel_cou' => 'X-Ascend-Dec-Channel-Count',
-  'x_ascend_send_auth' => 'X-Ascend-Send-Auth',
-  'usr_characters_received' => 'USR-Characters-Received',
-  'usr_pw_tunnel_authentica' => 'USR-PW_Tunnel_Authentication',
-  'usr_call_end_time' => 'USR-Call-End-Time',
+  'multi_link_flag' => 'Multi-Link-Flag',
+  'tunnel_type' => 'Tunnel-Type',
+  'erx_output_gigapkts' => 'ERX-Output-Gigapkts',
+  'ascend_idle_limit' => 'Ascend-Idle-Limit',
+  'ns_user_group' => 'NS-User-Group',
+  'password_retry' => 'Password-Retry',
+  'h323_remote_address' => 'h323-remote-address',
+  'erx_atm_service_category' => 'ERX-Atm-Service-Category',
+  'acct_input_packets' => 'Acct-Input-Packets',
+  'h323_disconnect_time' => 'h323-disconnect-time',
+  'usr_syslog_tap' => 'USR-Syslog-Tap',
+  'telebit_accounting_info' => 'Telebit-Accounting-Info',
+  'ascend_billing_number' => 'Ascend-Billing-Number',
+  'ascend_tunnel_vrouter_na' => 'Ascend-Tunnel-VRouter-Name',
+  'ms_mppe_encryption_type' => 'MS-MPPE-Encryption-Type',
+  'quintum_h323_credit_amou' => 'Quintum-h323-credit-amount',
+  'acc_ace_token' => 'Acc-Ace-Token',
+  'ascend_assign_ip_pool' => 'Ascend-Assign-IP-Pool',
+  'annex_end_modulation' => 'Annex-End-Modulation',
+  'usr_routing_protocol' => 'USR-Routing-Protocol',
+  'cvx_assign_ip_pool' => 'CVX-Assign-IP-Pool',
+  'usr_rad_location_type' => 'USR-Rad-Location-Type',
+  'usr_rmmie_pwrlvl_noise_l' => 'USR-RMMIE-PwrLvl-Noise-Lvl',
+  'usr_characters_sent' => 'USR-Characters-Sent',
+  'usr_mp_edo_hiper' => 'USR-MP-EDO-HIPER',
+  'ascend_x25_nui_password_' => 'Ascend-X25-Nui-Password-Prompt',
+  'annex_host_restrict' => 'Annex-Host-Restrict',
+  'user_service_type' => 'User-Service-Type',
+  'acct_multi_session_id' => 'Acct-Multi-Session-Id',
+  'ms_chap_cpw_2' => 'MS-CHAP-CPW-2',
+  'x_ascend_secondary_home_' => 'X-Ascend-Secondary-Home-Agent',
   'x_ascend_dialout_allowed' => 'X-Ascend-Dialout-Allowed',
-  'x_ascend_call_attempt_li' => 'X-Ascend-Call-Attempt-Limit',
-  'initial_modulation_type' => 'Initial-Modulation-Type',
-  'usr_packet_bus_session' => 'USR-Packet-Bus-Session',
-  'x_ascend_ipx_node_addr' => 'X-Ascend-IPX-Node-Addr',
-  'ascend_ppp_vj_slot_comp' => 'Ascend-PPP-VJ-Slot-Comp',
-  'ascend_menu_item' => 'Ascend-Menu-Item',
-  'x_ascend_fr_link_mgt' => 'X-Ascend-FR-Link-Mgt',
-  'usr_rmmie_serial_number' => 'USR-RMMIE-Serial-Number',
-  'message_authenticator' => 'Message-Authenticator',
-  'usr_dte_data_idle_timout' => 'USR-DTE-Data-Idle-Timout',
-  'usr_port_tap_facility' => 'USR-Port-Tap-Facility',
-  'acc_ml_mlx_admin_state' => 'Acc-ML-MLX-Admin-State',
-  'usr_modem_group' => 'USR-Modem-Group',
-  'x_ascend_callback' => 'X-Ascend-Callback',
-  'acct_input_packets_64' => 'Acct_Input_Packets_64',
-  'ascend_third_prompt' => 'Ascend-Third-Prompt',
-  'configuration_token' => 'Configuration-Token',
-  'x_ascend_fr_nailed_grp' => 'X-Ascend-FR-Nailed-Grp',
-  'acct_output_octets_64' => 'Acct_Output_Octets_64',
-  'h323_time_and_day' => 'h323-time-and-day',
-  'ascend_port_redir_portnu' => 'Ascend-Port-Redir-Portnum',
-  'acct_interim_interval' => 'Acct-Interim-Interval',
-  'ascend_uu_info' => 'Ascend-UU-Info',
-  'usr_pw_vpn_name' => 'USR-PW_VPN_Name',
-  'ascend_maximum_call_dura' => 'Ascend-Maximum-Call-Duration',
-  'ascend_atm_direct_profil' => 'Ascend-ATM-Direct-Profile',
-  'acc_input_errors' => 'Acc-Input-Errors',
-  'bind_dot1q_port' => 'Bind_Dot1q_Port',
-  'ascend_first_dest' => 'Ascend-First-Dest',
+  'ascend_connect_progress' => 'Ascend-Connect-Progress',
+  'x_ascend_ara_pw' => 'X-Ascend-Ara-PW',
+  'cisco_fax_modem_time' => 'Cisco-Fax-Modem-Time',
+  'sql_group' => 'Sql-Group',
+  'annex_multicast_rate_lim' => 'Annex-Multicast-Rate-Limit',
+  'cvpn3000_user_auth_servg' => 'CVPN3000-User-Auth-Server-Secret',
+  'ns_mta_md5_password' => 'NS-MTA-MD5-Password',
+  'annex_addr_resolution_pr' => 'Annex-Addr-Resolution-Protocol',
+  'callback_number' => 'Callback-Number',
+  'cvx_multilink_match_info' => 'CVX-Multilink-Match-Info',
+  'tunnel_max_tunnelt' => 'Tunnel_Max_Tunnels',
+  'tunnel_local_namf' => 'Tunnel_Local_Name',
+  'quintum_h323_conf_id' => 'Quintum-h323-conf-id',
+  'acct_output_packets_64' => 'Acct-Output-Packets-64',
+  'annex_signal_to_noise_ra' => 'Annex-Signal-to-Noise-Ratio',
+  'acct_output_packets_65' => 'Acct_Output_Packets_64',
+  'x_ascend_user_acct_key' => 'X-Ascend-User-Acct-Key',
+  'erx_dial_out_number' => 'ERX-Dial-Out-Number',
+  'ascend_modem_portno' => 'Ascend-Modem-PortNo',
+  'ascend_assign_ip_server' => 'Ascend-Assign-IP-Server',
+  'ascend_fcp_parameter' => 'Ascend-FCP-Parameter',
+  'usr_chassis_temp_thresho' => 'USR-Chassis-Temp-Threshold',
+  'usr_mpip_tunnel_originat' => 'USR-MPIP-Tunnel-Originator',
+  'tunnel_rate_limit_bursu' => 'Tunnel_Rate_Limit_Burst',
+  'client_ip_address' => 'Client-IP-Address',
+  'le_nat_tcp_session_timeo' => 'LE-NAT-TCP-Session-Timeout',
+  'quintum_h323_redirect_ip' => 'Quintum-h323-redirect-ip-address',
+  'ms_acct_eap_type' => 'MS-Acct-EAP-Type',
+  'usr_rmmie_x2_status' => 'USR-RMMIE-x2-Status',
+  'x_ascend_user_acct_type' => 'X-Ascend-User-Acct-Type',
+  'shiva_customer_id' => 'Shiva-Customer-Id',
+  'pvc_encapsulation_typf' => 'PVC_Encapsulation_Type',
+  'st_acct_vc_connection_id' => 'ST-Acct-VC-Connection-Id',
+  'lac_real_port' => 'LAC-Real-Port',
+  'h323_connect_time' => 'h323-connect-time',
+  'usr_vpn_gw_location_id' => 'USR-VPN-GW-Location-Id',
+  'old_password' => 'Old-Password',
   'x_ascend_if_netmask' => 'X-Ascend-IF-Netmask',
-  'tunnel_session_auth_serv' => 'Tunnel_Session_Auth_Service_Grp',
-  'annex_local_ip_address' => 'Annex-Local-IP-Address',
-  'termination_menu' => 'Termination-Menu',
-  'ms_chap2_cpw' => 'MS-CHAP2-CPW',
-  'ascend_mpp_idle_percent' => 'Ascend-MPP-Idle-Percent',
-  'usr_characters_sent' => 'USR-Characters-Sent',
-  'eap_message' => 'EAP-Message',
-  'acct_delay_time' => 'Acct-Delay-Time',
-  'ascend_remote_fw' => 'Ascend-Remote-FW',
-  'x_ascend_tunneling_proto' => 'X-Ascend-Tunneling-Protocol',
-  'shiva_session_id' => 'Shiva-Session-Id',
-  'usr_igmp_query_interval' => 'USR-IGMP-Query-Interval',
-  'usr_accm_type' => 'USR-ACCM-Type',
-  'usr_call_terminate_in_gm' => 'USR-Call-Terminate-in-GMT',
-  'usr_rad_location_type' => 'USR-Rad-Location-Type',
-  'ascend_filter' => 'Ascend-Filter',
-  'ascend_primary_home_agen' => 'Ascend-Primary-Home-Agent',
-  'x_ascend_user_acct_host' => 'X-Ascend-User-Acct-Host',
-  'chap_challenge' => 'CHAP-Challenge',
-  'acct_output_packets_64' => 'Acct_Output_Packets_64',
-  'bind_auth_max_sessions' => 'Bind_Auth_Max_Sessions',
-  'cisco_pre_output_octets' => 'Cisco-Pre-Output-Octets',
-  'x_ascend_fr_direct' => 'X-Ascend-FR-Direct',
-  'x_ascend_client_secondar' => 'X-Ascend-Client-Secondary-DNS',
-  'usr_rmmie_pwrlvl_nearech' => 'USR-RMMIE-PwrLvl-NearEcho-Canc',
-  'ascend_bridge_address' => 'Ascend-Bridge-Address',
-  'user_name' => 'User-Name',
-  'usr_rmmie_firmware_build' => 'USR-RMMIE-Firmware-Build-Date',
-  'ms_chap_mppe_keys' => 'MS-CHAP-MPPE-Keys',
-  'usr_number_of_characters' => 'USR-Number-Of-Characters-Lost',
-  'usr_physical_state' => 'USR-Physical-State',
-  'x_ascend_assign_ip_serve' => 'X-Ascend-Assign-IP-Server',
-  'bind_int_context' => 'Bind_Int_Context',
-  'erx_tunnel_virtual_route' => 'ERX-Tunnel-Virtual-Router',
+  'add_suffix' => 'Add-Suffix',
+  'lac_port_typf' => 'LAC_Port_Type',
+  'acc_ip_pool_name' => 'Acc-Ip-Pool-Name',
+  'usr_terminal_type' => 'USR-Terminal-Type',
+  'usr_spoofing' => 'USR-Spoofing',
+  'erx_tunnel_password' => 'ERX-Tunnel-Password',
+  'ascend_inter_arrival_jit' => 'Ascend-Inter-Arrival-Jitter',
+  'ascend_call_block_durati' => 'Ascend-Call-Block-Duration',
+  'itk_channel_binding' => 'ITK-Channel-Binding',
+  'usr_server_time' => 'USR-Server-Time',
+  'ascend_assign_ip_client' => 'Ascend-Assign-IP-Client',
+  'erx_pppoe_max_sessions' => 'ERX-Pppoe-Max-Sessions',
+  'cvx_multilink_group_numb' => 'CVX-Multilink-Group-Number',
+  'x_ascend_client_assign_d' => 'X-Ascend-Client-Assign-DNS',
+  'erx_pppoe_url' => 'ERX-Pppoe-Url',
+  'police_ratf' => 'Police_Rate',
+  'ascend_data_svc' => 'Ascend-Data-Svc',
+  'annex_authen_servers' => 'Annex-Authen-Servers',
+  'nomadix_bw_up' => 'Nomadix-Bw-Up',
+  'cvx_modem_data_compressi' => 'CVX-Modem-Data-Compression',
+  'shiva_link_speed' => 'Shiva-Link-Speed',
+  'usr_reply_script6' => 'USR-Reply-Script6',
+  'usr_expansion_algorithm' => 'USR-Expansion-Algorithm',
+  'cabletron_protocol_calla' => 'Cabletron-Protocol-Callable',
+  'cisco_data_rate' => 'Cisco-Data-Rate',
+  'usr_primary_dns_server' => 'USR-Primary_DNS_Server',
+  'juniper_deny_configurati' => 'Juniper-Deny-Configuration',
+  'ascend_target_util' => 'Ascend-Target-Util',
+  'digest_method' => 'Digest-Method',
+  'altiga_ipsec_split_tunne' => 'Altiga-IPSec-Split-Tunnel-List-G',
+  'erx_alternate_cli_access' => 'ERX-Alternate-Cli-Access-Level',
+  'x_ascend_event_type' => 'X-Ascend-Event-Type',
+  'usr_q931_call_reference_' => 'USR-Q931-Call-Reference-Value',
+  'usr_mp_mrru' => 'USR-MP-MRRU',
+  'cvx_ipsvc_mask' => 'CVX-IPSVC-Mask',
+  'bind_bypass_context' => 'Bind-Bypass-Context',
+  'usr_rmmie_last_update_ev' => 'USR-RMMIE-Last-Update-Event',
+  'no_such_attribute' => 'No-Such-Attribute',
+  'acct_mcast_out_packets' => 'Acct-Mcast-Out-Packets',
+  'tunnel_medium_type' => 'Tunnel-Medium-Type',
+  'quintum_h323_remote_addr' => 'Quintum-h323-remote-address',
+  'acc_callback_delay' => 'Acc-Callback-Delay',
+  'acct_input_octets_64' => 'Acct-Input-Octets-64',
+  'ascend_base_channel_coun' => 'Ascend-Base-Channel-Count',
+  'ascend_atm_connect_vci' => 'Ascend-ATM-Connect-Vci',
+  'erx_primary_dns' => 'ERX-Primary-Dns',
+  'altiga_ipsec_over_nat_g' => 'Altiga-IPSec-Over-NAT-G',
+  'cvx_multicast_rate_limit' => 'CVX-Multicast-Rate-Limit',
   'ascend_xmit_rate' => 'Ascend-Xmit-Rate',
-  'usr_secondary_dns_server' => 'USR-Secondary_DNS_Server',
+  'ms_new_arap_password' => 'MS-New-ARAP-Password',
+  'usr_call_error_code' => 'USR-Call-Error-Code',
+  'acct_output_octets' => 'Acct-Output-Octets',
+  'ascend_client_primary_wi' => 'Ascend-Client-Primary-WINS',
+  'cvpn3000_primary_wins' => 'CVPN3000-Primary-WINS',
+  'bintec_ipextrttable' => 'BinTec-ipExtRtTable',
+  'cisco_fax_mdn_flag' => 'Cisco-Fax-Mdn-Flag',
+  'ascend_destination_nas_p' => 'Ascend-Destination-Nas-Port',
+  'ascend_num_in_multilink' => 'Ascend-Num-In-Multilink',
+  'digest_attributes' => 'Digest-Attributes',
+  'cvpn3000_ipsec_tunnel_ty' => 'CVPN3000-IPSec-Tunnel-Type',
+  'x_ascend_number_sessions' => 'X-Ascend-Number-Sessions',
+  'usr_ip_rip_output_filter' => 'USR-IP-RIP-Output-Filter',
+  'tunnel_police_bursu' => 'Tunnel_Police_Burst',
+  'redcreek_tunneled_wins_s' => 'RedCreek-Tunneled-WINS-Server1',
+  'usr_blocks_sent' => 'USR-Blocks-Sent',
+  'erx_cli_allow_all_vr_acc' => 'ERX-Cli-Allow-All-VR-Access',
+  'tunnel_police_ratf' => 'Tunnel_Police_Rate',
+  'usr_ids0_call_type' => 'USR-IDS0-Call-Type',
+  'acc_ccp_option' => 'Acc-Ccp-Option',
+  'ascend_client_gateway' => 'Ascend-Client-Gateway',
+  'cvx_maximum_channels' => 'CVX-Maximum-Channels',
+  'bg_aging_timf' => 'BG_Aging_Time',
+  'annex_secondary_dns_serv' => 'Annex-Secondary-DNS-Server',
+  'le_ipsec_passive_profile' => 'LE-IPSec-Passive-Profile',
+  'usr_chassis_call_span' => 'USR-Chassis-Call-Span',
+  'aat_client_primary_wins_' => 'AAT-Client-Primary-WINS-NBNS',
+  'h323_currency' => 'h323-currency',
+  'password' => 'Password',
+  'le_nat_log_options' => 'LE-NAT-Log-Options',
+  'usr_fallback_limit' => 'USR-Fallback-Limit',
+  'x_ascend_ppp_address' => 'X-Ascend-PPP-Address',
+  'suffix' => 'Suffix',
+  'usr_multicast_receive' => 'USR-Multicast-Receive',
+  'client_dns_sec' => 'Client-DNS-Sec',
+  'annex_product_name' => 'Annex-Product-Name',
+  'cisco_pw_lifetime' => 'Cisco-PW-Lifetime',
+  'x_ascend_fr_dce_n393' => 'X-Ascend-FR-DCE-N393',
+  'x_ascend_ts_idle_limit' => 'X-Ascend-TS-Idle-Limit',
+  'mcast_send' => 'Mcast-Send',
+  'x_ascend_primary_home_ag' => 'X-Ascend-Primary-Home-Agent',
+  'tunnel_max_sessiont' => 'Tunnel_Max_Sessions',
+  'pppoe_motm' => 'PPPOE-MOTM',
+  'usr_pw_usr_ifilter_ipx' => 'USR-PW_USR_IFilter_IPX',
+  'ms_ras_version' => 'MS-RAS-Version',
+  'ascend_source_ip_check' => 'Ascend-Source-IP-Check',
+  'bintec_ospfiftable' => 'BinTec-ospfIfTable',
+  'acc_ml_call_threshold' => 'Acc-ML-Call-Threshold',
+  'x_ascend_modem_slotno' => 'X-Ascend-Modem-SlotNo',
+  'ascend_menu_item' => 'Ascend-Menu-Item',
+  'callback_id' => 'Callback-Id',
+  'framed_ipx_network' => 'Framed-IPX-Network',
+  'altiga_pptp_encryption_g' => 'Altiga-PPTP-Encryption-G',
+  'ascend_x25_reverse_charg' => 'Ascend-X25-Reverse-Charging',
+  'ascend_user_acct_key' => 'Ascend-User-Acct-Key',
+  'x_ascend_pw_lifetime' => 'X-Ascend-PW-Lifetime',
+  'user_name_is_star' => 'User-Name-Is-Star',
+  'nomadix_url_redirection' => 'Nomadix-URL-Redirection',
+  'framed_pool' => 'Framed-Pool',
+  'x_ascend_authen_alias' => 'X-Ascend-Authen-Alias',
+  'cisco_fax_dsn_address' => 'Cisco-Fax-Dsn-Address',
+  'ms_primary_dns_server' => 'MS-Primary-DNS-Server',
+  'acc_dialout_auth_usernam' => 'Acc-Dialout-Auth-Username',
+  'realm' => 'Realm',
+  'arap_features' => 'ARAP-Features',
+  'bind_auth_protocom' => 'Bind_Auth_Protocol',
+  'acc_connect_tx_speed' => 'Acc-Connect-Tx-Speed',
+  'usr_chassis_temperature' => 'USR-Chassis-Temperature',
+  'altiga_ipsec_mode_config' => 'Altiga-IPSec-Mode-Config-G',
+  'ascend_home_agent_ip_add' => 'Ascend-Home-Agent-IP-Addr',
+  'x_ascend_xmit_rate' => 'X-Ascend-Xmit-Rate',
+  'cvpn3000_secondary_dns' => 'CVPN3000-Secondary-DNS',
+  'x_ascend_send_passwd' => 'X-Ascend-Send-Passwd',
+  'bind_int_contexu' => 'Bind_Int_Context',
+  'cisco_fax_account_id_ori' => 'Cisco-Fax-Account-Id-Origin',
+  'le_modem_info' => 'LE-Modem-Info',
+  'ascend_ipx_peer_mode' => 'Ascend-IPX-Peer-Mode',
+  'juniper_local_user_name' => 'Juniper-Local-User-Name',
+  'tunnel_rate_limit_rate' => 'Tunnel-Rate-Limit-Rate',
+  'quintum_h323_credit_time' => 'Quintum-h323-credit-time',
+  'acc_modem_modulation_typ' => 'Acc-Modem-Modulation-Type',
+  'x_ascend_seconds_of_hist' => 'X-Ascend-Seconds-Of-History',
+  'ascend_dhcp_pool_number' => 'Ascend-DHCP-Pool-Number',
+  'redcreek_tunneled_ip_net' => 'RedCreek-Tunneled-IP-Netmask',
+  'x_ascend_callback' => 'X-Ascend-Callback',
+  'usr_iwf_ip_address' => 'USR-IWF-IP-Address',
+  'aat_input_octets_diff' => 'AAT-Input-Octets-Diff',
+  'nas_port_id' => 'NAS-Port-Id',
+  'le_advice_of_charge' => 'LE-Advice-of-Charge',
+  'x_ascend_dhcp_pool_numbe' => 'X-Ascend-DHCP-Pool-Number',
+  'ascend_add_seconds' => 'Ascend-Add-Seconds',
+  'annex_transmit_speed' => 'Annex-Transmit-Speed',
+  'usr_port_tap' => 'USR-Port-Tap',
+  'usr_at_call_input_filter' => 'USR-AT-Call-Input-Filter',
+  'framed_ipv6_pool' => 'Framed-IPv6-Pool',
+  'ascend_qos_downstream' => 'Ascend-QOS-Downstream',
+  'lac_port' => 'LAC-Port',
+  'tunnel_assignment_id' => 'Tunnel-Assignment-Id',
+  'acct_mcast_out_octett' => 'Acct_Mcast_Out_Octets',
+  'ascend_bi_directional_au' => 'Ascend-Bi-Directional-Auth',
+  'fall_through' => 'Fall-Through',
+  'cvpn3000_ipsec_ip_compre' => 'CVPN3000-IPSec-IP-Compression',
+  'cisco_disconnect_cause' => 'Cisco-Disconnect-Cause',
+  'usr_rad_multicast_routiq' => 'USR-Rad-Multicast-Routing-Bound',
+  'altiga_tunneling_protoco' => 'Altiga-Tunneling-Protocols-G/U',
+  'itk_tunnel_prot' => 'ITK-Tunnel-Prot',
+  'client_dns_sed' => 'Client_DNS_Sec',
+  'framed_ip_netmask' => 'Framed-IP-Netmask',
+  'usr_call_reference_numbe' => 'USR-Call-Reference-Number',
+  'ascend_egress_enabled' => 'Ascend-Egress-Enabled',
   'ascend_dsl_rate_mode' => 'Ascend-Dsl-Rate-Mode',
-  'ascend_data_rate' => 'Ascend-Data-Rate',
-  'realm' => 'Realm',
-  'usr_ipx_call_input_filte' => 'USR-IPX-Call-Input-Filter',
-  'ascend_ipx_route' => 'Ascend-IPX-Route',
-  'usr_failure_to_connect_r' => 'USR-Failure-to-Connect-Reason',
-  'x_ascend_home_network_na' => 'X-Ascend-Home-Network-Name',
-  'acc_nbns_server_pri' => 'Acc-Nbns-Server-Pri',
+  'usr_pw_usr_ofilter_sap' => 'USR-PW_USR_OFilter_SAP',
+  'bintec_iproutetable' => 'BinTec-ipRouteTable',
+  'acct_terminate_cause' => 'Acct-Terminate-Cause',
+  'x_ascend_fr_dte_n393' => 'X-Ascend-FR-DTE-N393',
+  'ascend_ppp_address' => 'Ascend-PPP-Address',
+  'erx_maximum_bps' => 'ERX-Maximum-BPS',
+  'caller_id' => 'Caller-ID',
+  'bintec_ipfiltertable' => 'BinTec-ipFilterTable',
+  'x_ascend_base_channel_co' => 'X-Ascend-Base-Channel-Count',
+  'bind_int_interface_name' => 'Bind-Int-Interface-Name',
+  'usr_modem_group' => 'USR-Modem-Group',
+  'cisco_maximum_channels' => 'Cisco-Maximum-Channels',
+  'erx_ppp_username' => 'ERX-PPP-Username',
+  'ascend_link_compression' => 'Ascend-Link-Compression',
+  'annex_retransmitted_pack' => 'Annex-Retransmitted-Packets',
+  'usr_retrains_granted' => 'USR-Retrains-Granted',
+  'ascend_dropped_packets' => 'Ascend-Dropped-Packets',
+  'erx_bearer_type' => 'ERX-Bearer-Type',
+  'usr_pw_usr_ofilter_ip' => 'USR-PW_USR_OFilter_IP',
+  'quintum_nas_port' => 'Quintum-NAS-Port',
+  'x_ascend_pre_output_pack' => 'X-Ascend-Pre-Output-Packets',
+  'usr_cdma_call_reference_' => 'USR-CDMA-Call-Reference-Number',
+  'tunnel_function' => 'Tunnel-Function',
+  'annex_tunnel_authen_mode' => 'Annex-Tunnel-Authen-Mode',
+  'usr_mp_edo' => 'USR-MP-EDO',
+  'le_nat_outmap' => 'LE-NAT-Outmap',
+  'cvpn3000_primary_dns' => 'CVPN3000-Primary-DNS',
   'usr_modulation_type' => 'USR-Modulation-Type',
-  'service_type' => 'Service-Type',
-  'ascend_callback_delay' => 'Ascend-Callback-Delay',
-  'ascend_owner_ip_addr' => 'Ascend-Owner-IP-Addr',
-  'x_ascend_handle_ipx' => 'X-Ascend-Handle-IPX',
-  'usr_connect_term_reason' => 'USR-Connect-Term-Reason',
-  'x_ascend_multicast_rate_' => 'X-Ascend-Multicast-Rate-Limit',
-  'h323_disconnect_time' => 'h323-disconnect-time',
-  'acc_ip_gateway_sec' => 'Acc-Ip-Gateway-Sec',
-  'usr_number_of_blers' => 'USR-Number-of-Blers',
-  'x_ascend_fr_type' => 'X-Ascend-FR-Type',
-  'ascend_assign_ip_pool' => 'Ascend-Assign-IP-Pool',
-  'ascend_qos_upstream' => 'Ascend-QOS-Upstream',
-  'usr_nas_type' => 'USR-NAS-Type',
-  'acc_dial_port_index' => 'Acc-Dial-Port-Index',
-  'usr_initial_tx_link_data' => 'USR-Initial-Tx-Link-Data-Rate',
-  'ascend_fr_type' => 'Ascend-FR-Type',
-  'usr_mbi_ct_tdm_time_slot' => 'USR-Mbi_Ct_TDM_Time_Slot',
-  'usr_rmmie_pwrlvl_xmit_lv' => 'USR-RMMIE-PwrLvl-Xmit-Lvl',
-  'erx_atm_service_category' => 'ERX-Atm-Service-Category',
-  'usr_appletalk' => 'USR-Appletalk',
-  'usr_send_script1' => 'USR-Send-Script1',
-  'usr_send_script2' => 'USR-Send-Script2',
-  'usr_send_script3' => 'USR-Send-Script3',
-  'usr_ospf_addressless_ind' => 'USR-OSPF-Addressless-Index',
-  'acct_input_packets' => 'Acct-Input-Packets',
-  'usr_send_script4' => 'USR-Send-Script4',
-  'usr_send_script5' => 'USR-Send-Script5',
+  'ascend_calling_id_screen' => 'Ascend-Calling-Id-Screening',
+  'ascend_maximum_time' => 'Ascend-Maximum-Time',
+  'user_password' => 'User-Password',
+  'annex_callback_portlist' => 'Annex-Callback-Portlist',
+  'cvpn3000_ipsec_split_tun' => 'CVPN3000-IPSec-Split-Tunnel-List',
+  'annex_pre_output_packets' => 'Annex-Pre-Output-Packets',
+  'usr_at_call_output_filte' => 'USR-AT-Call-Output-Filter',
+  'x_ascend_client_primary_' => 'X-Ascend-Client-Primary-DNS',
+  'tunnel_server_endpoint' => 'Tunnel-Server-Endpoint',
+  'x_ascend_remove_seconds' => 'X-Ascend-Remove-Seconds',
+  'cvpn3000_user_auth_serve' => 'CVPN3000-User-Auth-Server-Name',
+  'arap_password' => 'ARAP-Password',
+  'x_ascend_assign_ip_serve' => 'X-Ascend-Assign-IP-Server',
+  'cisco_fax_pages' => 'Cisco-Fax-Pages',
+  'ms_chap_mppe_keys' => 'MS-CHAP-MPPE-Keys',
+  'ascend_source_auth' => 'Ascend-Source-Auth',
+  'group' => 'Group',
   'usr_send_script6' => 'USR-Send-Script6',
-  'usr_service_option' => 'USR-Service-Option',
-  'ascend_dropped_octets' => 'Ascend-Dropped-Octets',
-  'usr_ip' => 'USR-IP',
-  'usr_tunnel_security' => 'USR-Tunnel-Security',
+  'le_nat_inmap' => 'LE-NAT-Inmap',
+  'chap_password' => 'CHAP-Password',
+  'annex_receive_speed' => 'Annex-Receive-Speed',
+  'usr_mobileip_home_agent_' => 'USR-MobileIP-Home-Agent-Address',
+  'bind_l2tp_flow_control' => 'Bind-L2TP-Flow-Control',
+  'smb_account_ctrl' => 'SMB-Account-CTRL',
+  'ascend_ip_pool_chaining' => 'Ascend-IP-Pool-Chaining',
+  'le_admin_group' => 'LE-Admin-Group',
+  'tunnel_connection_id' => 'Tunnel-Connection-Id',
+  'tunnel_windox' => 'Tunnel_Window',
+  'nas_identifier' => 'NAS-Identifier',
+  'dhcp_max_leaset' => 'DHCP_Max_Leases',
+  'digest_nonce_count' => 'Digest-Nonce-Count',
+  'nas_real_port' => 'NAS-Real-Port',
+  'ms_old_arap_password' => 'MS-Old-ARAP-Password',
+  'usr_pw_index' => 'USR-PW_Index',
+  'erx_primary_wins' => 'ERX-Primary-Wins',
+  'ascend_appletalk_peer_mo' => 'Ascend-Appletalk-Peer-Mode',
+  'le_ipsec_log_options' => 'LE-IPSec-Log-Options',
+  'x_ascend_maximum_channel' => 'X-Ascend-Maximum-Channels',
+  'cvx_ipsvc_aznlvl' => 'CVX-IPSVC-AZNLVL',
+  'x_ascend_client_secondar' => 'X-Ascend-Client-Secondary-DNS',
+  'annex_re_chap_timeout' => 'Annex-Re-CHAP-Timeout',
+  'aat_ip_pool_definition' => 'AAT-IP-Pool-Definition',
+  'client_dns_pri' => 'Client-DNS-Pri',
+  'cisco_service_info' => 'Cisco-Service-Info',
+  'usr_primary_nbns_server' => 'USR-Primary_NBNS_Server',
+  'aat_atm_direct' => 'AAT-ATM-Direct',
+  'bind_ses_contexu' => 'Bind_Ses_Context',
+  'sip_translated_request_u' => 'Sip-Translated-Request-URI',
   'acc_acct_on_off_reason' => 'Acc-Acct-On-Off-Reason',
-  'shiva_compression_type' => 'Shiva-Compression-Type',
-  'ascend_pw_warntime' => 'Ascend-PW-Warntime',
-  'usr_security_resp_limit' => 'USR-Security-Resp-Limit',
-  'ascend_x25_pad_prompt' => 'Ascend-X25-Pad-Prompt',
-  'cisco_asing_ip_pool' => 'Cisco-Asing-IP-Pool',
-  'acc_route_policy' => 'Acc-Route-Policy',
+  'le_multicast_client' => 'LE-Multicast-Client',
+  'bind_sub_passwore' => 'Bind_Sub_Password',
+  'cvpn3000_cisco_ip_phone_' => 'CVPN3000-Cisco-IP-Phone-Bypass',
+  'ascend_send_passwd' => 'Ascend-Send-Passwd',
+  'tunnel_remote_namf' => 'Tunnel_Remote_Name',
+  'cvx_disconnect_cause' => 'CVX-Disconnect-Cause',
+  'itk_auth_serv_prot' => 'ITK-Auth-Serv-Prot',
+  'tunnel_context' => 'Tunnel-Context',
+  'digest_uri' => 'Digest-URI',
+  'usr_channel_decrement' => 'USR-Channel-Decrement',
+  'acc_nbns_server_sec' => 'Acc-Nbns-Server-Sec',
+  'ms_chap_challenge' => 'MS-CHAP-Challenge',
+  'cisco_assign_ip_pool' => 'Cisco-Assign-IP-Pool',
+  'ascend_cbcp_mode' => 'Ascend-CBCP-Mode',
+  'ascend_x25_rpoa' => 'Ascend-X25-Rpoa',
+  'usr_dtr_false_timeout' => 'USR-DTR-False-Timeout',
+  'acct_dyn_ac_enu' => 'Acct_Dyn_Ac_Ent',
+  'usr_physical_state' => 'USR-Physical-State',
+  'x_ascend_ppp_vj_slot_com' => 'X-Ascend-PPP-VJ-Slot-Comp',
+  'x_ascend_link_compressio' => 'X-Ascend-Link-Compression',
+  'ascend_fr_t391' => 'Ascend-FR-T391',
+  'bind_dot1q_port' => 'Bind-Dot1q-Port',
+  'ns_secondary_dns' => 'NS-Secondary-DNS',
+  'altiga_ipsec_tunnel_type' => 'Altiga-IPSec-Tunnel-Type-G',
+  'lac_port_type' => 'LAC-Port-Type',
+  'bg_aging_time' => 'BG-Aging-Time',
+  'erx_atm_scr' => 'ERX-Atm-SCR',
+  'x_ascend_pre_input_octet' => 'X-Ascend-Pre-Input-Octets',
+  'cisco_fax_connect_speed' => 'Cisco-Fax-Connect-Speed',
+  'x_ascend_menu_item' => 'X-Ascend-Menu-Item',
+  'quintum_h323_voice_quali' => 'Quintum-h323-voice-quality',
+  'ascend_x25_pad_banner' => 'Ascend-X25-Pad-Banner',
+  'module_failure_message' => 'Module-Failure-Message',
+  'h323_gw_id' => 'h323-gw-id',
+  'h323_preferred_lang' => 'h323-preferred-lang',
+  'usr_min_compression_size' => 'USR-Min-Compression-Size',
+  'usr_compression_type' => 'USR-Compression-Type',
+  'bintec_ipxstaticroutetab' => 'BinTec-ipxStaticRouteTable',
+  'ascend_dialout_allowed' => 'Ascend-Dialout-Allowed',
   'annex_local_username' => 'Annex-Local-Username',
-  'x_ascend_call_by_call' => 'X-Ascend-Call-By-Call',
-  'ascend_calling_id_screen' => 'Ascend-Calling-Id-Screening',
-  'x_ascend_dhcp_pool_numbe' => 'X-Ascend-DHCP-Pool-Number',
-  'nas_port_type' => 'NAS-Port-Type',
-  'ascend_route_ip' => 'Ascend-Route-IP',
-  'ascend_client_gateway' => 'Ascend-Client-Gateway',
-  'ascend_qos_downstream' => 'Ascend-QOS-Downstream',
-  'ms_bap_usage' => 'MS-BAP-Usage',
-  'usr_vts_session_key' => 'USR-VTS-Session-Key',
-  'usr_receive_acc_map' => 'USR-Receive-Acc-Map',
-  'ascend_expect_callback' => 'Ascend-Expect-Callback',
-  'password' => 'Password',
-  'packet_type' => 'Packet-Type',
-  'ascend_remote_addr' => 'Ascend-Remote-Addr',
-  'ascend_recv_name' => 'Ascend-Recv-Name',
-  'ms_acct_eap_type' => 'MS-Acct-EAP-Type',
-  'usr_filter_zones' => 'USR-Filter-Zones',
+  'cisco_pre_input_packets' => 'Cisco-Pre-Input-Packets',
+  'shiva_function' => 'Shiva-Function',
+  'ascend_send_secret' => 'Ascend-Send-Secret',
+  'usr_number_of_blers' => 'USR-Number-of-Blers',
+  'usr_dte_data_idle_timout' => 'USR-DTE-Data-Idle-Timout',
+  'usr_card_type' => 'USR-Card-Type',
+  'x_ascend_connect_progres' => 'X-Ascend-Connect-Progress',
+  'x_ascend_group' => 'X-Ascend-Group',
+  'ascend_token_idle' => 'Ascend-Token-Idle',
+  'erx_qos_profile_interfac' => 'ERX-Qos-Profile-Interface-Type',
+  'ascend_private_route_tab' => 'Ascend-Private-Route-Table-ID',
+  'nt_password' => 'NT-Password',
+  'acct_mcast_in_packets' => 'Acct-Mcast-In-Packets',
+  'x_ascend_multicast_clien' => 'X-Ascend-Multicast-Client',
+  'usr_supports_tags' => 'USR-Supports-Tags',
+  'cvpn3000_authd_user_idle' => 'CVPN3000-Authd-User-Idle-Timeout',
+  'ascend_number_sessions' => 'Ascend-Number-Sessions',
+  'x_ascend_add_seconds' => 'X-Ascend-Add-Seconds',
+  'usr_number_of_upshifts' => 'USR-Number-of-Upshifts',
+  'proxy_to_realm' => 'Proxy-To-Realm',
+  'aat_client_secondary_win' => 'AAT-Client-Secondary-WINS-NBNS',
+  'aat_ip_tos_precedence' => 'AAT-IP-TOS-Precedence',
+  'acc_callback_num_valid' => 'Acc-Callback-Num-Valid',
+  'nokia_ggsn_ip_address' => 'Nokia-GGSN-IP-Address',
+  'acc_access_community' => 'Acc-Access-Community',
+  'ascend_multicast_rate_li' => 'Ascend-Multicast-Rate-Limit',
+  'usr_default_dte_data_rat' => 'USR-Default-DTE-Data-Rate',
+  'usr_rmmie_pwrlvl_nearech' => 'USR-RMMIE-PwrLvl-NearEcho-Canc',
+  'usr_send_name' => 'USR-Send-Name',
+  'usr_chassis_slot' => 'USR-Chassis-Slot',
+  'login_ip_host' => 'Login-IP-Host',
+  'ascend_netware_timeout' => 'Ascend-Netware-timeout',
+  'bind_sub_user_at_context' => 'Bind-Sub-User-At-Context',
+  'vendor_specific' => 'Vendor-Specific',
+  'ascend_fr_direct_dlci' => 'Ascend-FR-Direct-DLCI',
+  'ascend_qos_upstream' => 'Ascend-QOS-Upstream',
+  'aat_user_mac_address' => 'AAT-User-MAC-Address',
+  'source_validation' => 'Source-Validation',
+  'x_ascend_token_expiry' => 'X-Ascend-Token-Expiry',
+  'altiga_ipsec_user_group_' => 'Altiga-IPSec-User-Group-Lock-G',
+  'ascend_dec_channel_count' => 'Ascend-Dec-Channel-Count',
+  'assigned_ip_addrest' => 'Assigned_IP_Address',
+  'usr_local_framed_ip_addr' => 'USR-Local-Framed-IP-Addr',
+  'usr_service_option' => 'USR-Service-Option',
+  'usr_transmit_acc_map' => 'USR-Transmit-Acc-Map',
+  'ascend_fr_direct' => 'Ascend-FR-Direct',
+  'usr_final_rx_link_data_r' => 'USR-Final-Rx-Link-Data-Rate',
+  'x_ascend_expect_callback' => 'X-Ascend-Expect-Callback',
+  'x_ascend_disconnect_caus' => 'X-Ascend-Disconnect-Cause',
+  'acc_ml_damping_factor' => 'Acc-ML-Damping-Factor',
+  'framed_netmask' => 'Framed-Netmask',
+  'usr_connect_speed' => 'USR-Connect-Speed',
+  'x_ascend_home_agent_ip_a' => 'X-Ascend-Home-Agent-IP-Addr',
+  'usr_disconnect_cause_ind' => 'USR-Disconnect-Cause-Indicator',
+  'bg_span_dis' => 'BG-Span-Dis',
+  'cisco_multilink_id' => 'Cisco-Multilink-ID',
+  'tunnel_max_tunnels' => 'Tunnel-Max-Tunnels',
+  'ascend_dsl_downstream_li' => 'Ascend-Dsl-Downstream-Limit',
+  'ascend_multilink_id' => 'Ascend-Multilink-ID',
+  'altiga_ipsec_default_dom' => 'Altiga-IPSec-Default-Domain-G',
+  'ascend_dhcp_reply' => 'Ascend-DHCP-Reply',
+  'login_ipv6_host' => 'Login-IPv6-Host',
+  'ascend_x25_cug' => 'Ascend-X25-Cug',
+  'shiva_network_protocols' => 'Shiva-Network-Protocols',
+  'cvpn3000_ipsec_mode_conf' => 'CVPN3000-IPSec-Mode-Config',
+  'extreme_netlogin_vlan' => 'Extreme-Netlogin-Vlan',
+  'ascend_ara_pw' => 'Ascend-Ara-PW',
+  'tunnel_l2f_second_passwo' => 'Tunnel-L2F-Second-Password',
+  'altiga_sep_card_assignme' => 'Altiga-SEP-Card-Assignment-G/U',
+  'ip_host_addr' => 'Ip-Host-Addr',
+  'le_ip_gateway' => 'LE-IP-Gateway',
+  'usr_mobile_numbytes_txed' => 'USR-Mobile-NumBytes-Txed',
+  'altiga_ipsec_allow_passw' => 'Altiga-IPSec-Allow-Passwd-Store-G/U',
+  'itk_users_default_entry' => 'ITK-Users-Default-Entry',
+  'quintum_h323_redirect_nu' => 'Quintum-h323-redirect-number',
+  'x_ascend_fr_t392' => 'X-Ascend-FR-T392',
+  'acc_igmp_version' => 'Acc-Igmp-Version',
+  'cisco_pre_output_packets' => 'Cisco-Pre-Output-Packets',
+  'tunnel_group' => 'Tunnel-Group',
+  'x_ascend_home_agent_udp_' => 'X-Ascend-Home-Agent-UDP-Port',
+  'cvpn3000_tunneling_proto' => 'CVPN3000-Tunneling-Protocols',
+  'usr_igmp_maximum_respons' => 'USR-IGMP-Maximum-Response-Time',
+  'bind_sub_password' => 'Bind-Sub-Password',
+  'eap_message' => 'EAP-Message',
+  'exec_program' => 'Exec-Program',
+  'cvpn3000_reqrd_client_fx' => 'CVPN3000-Reqrd-Client-Fw-Product-Code',
+  'bg_path_cost' => 'BG-Path-Cost',
+  'usr_modem_training_time' => 'USR-Modem-Training-Time',
+  'auth_type' => 'Auth-Type',
+  'itk_acct_serv_prot' => 'ITK-Acct-Serv-Prot',
+  'x_ascend_ipx_route' => 'X-Ascend-IPX-Route',
+  'altiga_primary_dns_g' => 'Altiga-Primary-DNS-G',
+  'ascend_cbcp_enable' => 'Ascend-CBCP-Enable',
+  'ms_mppe_encryption_polic' => 'MS-MPPE-Encryption-Policy',
+  'annex_unauthenticated_ti' => 'Annex-Unauthenticated-Time',
+  'annex_begin_receive_line' => 'Annex-Begin-Receive-Line-Level',
+  'ascend_atm_direct_profil' => 'Ascend-ATM-Direct-Profile',
+  'redcreek_tunneled_dns_se' => 'RedCreek-Tunneled-DNS-Server',
+  'ascend_redirect_number' => 'Ascend-Redirect-Number',
+  'h323_credit_time' => 'h323-credit-time',
+  'cvx_idle_limit' => 'CVX-Idle-Limit',
+  'ascend_appletalk_route' => 'Ascend-Appletalk-Route',
+  'aat_ip_tos' => 'AAT-IP-TOS',
+  'cvx_ppp_address' => 'CVX-PPP-Address',
+  'aat_data_filter' => 'AAT-Data-Filter',
+  'cvx_primary_dns' => 'CVX-Primary-DNS',
+  'shiva_link_protocol' => 'Shiva-Link-Protocol',
+  'x_ascend_fr_circuit_name' => 'X-Ascend-FR-Circuit-Name',
+  'usr_appletalk' => 'USR-Appletalk',
+  'client_id' => 'Client-Id',
+  'tunnel_algorithn' => 'Tunnel_Algorithm',
+  'aat_assign_ip_pool' => 'AAT-Assign-IP-Pool',
+  'quintum_h323_incoming_co' => 'Quintum-h323-incoming-conf-id',
+  'aat_atm_vpi' => 'AAT-ATM-VPI',
   'annex_output_filter' => 'Annex-Output-Filter',
-  'usr_rmmie_rcv_tot_pwrlvl' => 'USR-RMMIE-Rcv-Tot-PwrLvl',
-  'usr_mp_mrru' => 'USR-MP-MRRU',
+  'pvc_circuit_padding' => 'PVC-Circuit-Padding',
+  'usr_ipx_call_output_filt' => 'USR-IPX-Call-Output-Filter',
+  'usr_rmmie_planned_discon' => 'USR-RMMIE-Planned-Disconnect',
+  'session_error_msh' => 'Session_Error_Msg',
+  'usr_rad_multicast_routin' => 'USR-Rad-Multicast-Routing-Ttl',
+  'h323_time_and_day' => 'h323-time-and-day',
+  'cvpn3000_ipsec_backup_se' => 'CVPN3000-IPSec-Backup-Servers',
+  'termination_action' => 'Termination-Action',
+  'cvpn3000_ipsec_client_fx' => 'CVPN3000-IPSec-Client-Fw-Filter-Opt',
+  'aat_client_primary_dnt' => 'AAT-Client-Primary-DNS',
+  'acct_tunnel_packets_lost' => 'Acct-Tunnel-Packets-Lost',
+  'x_ascend_modem_portno' => 'X-Ascend-Modem-PortNo',
+  'framed_filter_id' => 'Framed-Filter-Id',
+  'usr_ccp_algorithm' => 'USR-CCP-Algorithm',
+  'quintum_h323_preferred_l' => 'Quintum-h323-preferred-lang',
+  'ascend_fr_link_status_dl' => 'Ascend-FR-Link-Status-DLCI',
+  'ascend_token_expiry' => 'Ascend-Token-Expiry',
+  'itk_auth_req_type' => 'ITK-Auth-Req-Type',
+  'acc_modem_error_protocol' => 'Acc-Modem-Error-Protocol',
+  'acc_request_type' => 'Acc-Request-Type',
+  'usr_last_number_dialed_i' => 'USR-Last-Number-Dialed-In-DNIS',
+  'x_ascend_ipx_peer_mode' => 'X-Ascend-IPX-Peer-Mode',
+  'ascend_ppp_vj_slot_comp' => 'Ascend-PPP-VJ-Slot-Comp',
+  'cisco_presession_time' => 'Cisco-PreSession-Time',
+  'usr_chat_script_name' => 'USR-Chat-Script-Name',
+  'tunnel_session_auti' => 'Tunnel_Session_Auth',
+  'ascend_fr_circuit_name' => 'Ascend-FR-Circuit-Name',
+  'ascend_expect_callback' => 'Ascend-Expect-Callback',
+  'framed_mtu' => 'Framed-MTU',
+  'usr_pw_vpn_name' => 'USR-PW_VPN_Name',
+  'nomadix_ip_upsell' => 'Nomadix-IP-Upsell',
+  'ascend_nas_port_format' => 'Ascend-NAS-Port-Format',
+  'usr_dtr_true_timeout' => 'USR-DTR-True-Timeout',
+  'shasta_vpn_name' => 'Shasta-VPN-Name',
+  'connect_rate' => 'Connect-Rate',
+  'ascend_third_prompt' => 'Ascend-Third-Prompt',
+  'cabletron_protocol_enabl' => 'Cabletron-Protocol-Enable',
+  'annex_pre_input_octets' => 'Annex-Pre-Input-Octets',
+  'cvx_modem_error_correcti' => 'CVX-Modem-Error-Correction',
+  'cvx_ss7_session_id_type' => 'CVX-SS7-Session-ID-Type',
+  'called_station_id' => 'Called-Station-Id',
+  'itk_ddi' => 'ITK-DDI',
+  'usr_pw_cutoff' => 'USR-PW_Cutoff',
+  'ascend_data_rate' => 'Ascend-Data-Rate',
+  'acct_input_packets_65' => 'Acct_Input_Packets_64',
+  'x_ascend_ts_idle_mode' => 'X-Ascend-TS-Idle-Mode',
+  'ascend_x25_pad_prompt' => 'Ascend-X25-Pad-Prompt',
+  'x_ascend_dhcp_reply' => 'X-Ascend-DHCP-Reply',
+  'acc_nbns_server_pri' => 'Acc-Nbns-Server-Pri',
+  'post_auth_type' => 'Post-Auth-Type',
   'ascend_call_filter' => 'Ascend-Call-Filter',
-  'usr_keypress_timeout' => 'USR-Keypress-Timeout',
-  'usr_modem_setup_time' => 'USR-Modem-Setup-Time',
-  'acct_authentic' => 'Acct-Authentic',
-  'pppoe_motm' => 'PPPOE_MOTM',
-  'x_ascend_expect_callback' => 'X-Ascend-Expect-Callback',
-  'erx_atm_scr' => 'ERX-Atm-SCR',
-  'erx_address_pool_name' => 'ERX-Address-Pool-Name',
+  'acc_tunnel_secret' => 'Acc-Tunnel-Secret',
+  'colubris_avpair' => 'Colubris-AVPair',
+  'bind_int_context' => 'Bind-Int-Context',
+  'annex_logical_channel_nu' => 'Annex-Logical-Channel-Number',
+  'erx_virtual_router_name' => 'ERX-Virtual-Router-Name',
+  'wispr_redirection_url' => 'WISPr-Redirection-URL',
+  'bintec_ipextiftable' => 'BinTec-ipExtIfTable',
+  'crypt_password' => 'Crypt-Password',
   'challenge_state' => 'Challenge-State',
-  'usr_multicast_proxy' => 'USR-Multicast-Proxy',
-  'framed_filter_id' => 'Framed-Filter-Id',
-  'add_suffix' => 'Add-Suffix',
+  'x_ascend_pre_input_packe' => 'X-Ascend-Pre-Input-Packets',
+  'altiga_ipsec_l2l_keepali' => 'Altiga-IPSec-L2L-Keepalives-G',
+  'x_ascend_dhcp_maximum_le' => 'X-Ascend-DHCP-Maximum-Leases',
+  'acc_dialout_auth_passwor' => 'Acc-Dialout-Auth-Password',
+  'itk_ip_pool' => 'ITK-IP-Pool',
+  'pvc_profile_namf' => 'PVC_Profile_Name',
+  'x_ascend_user_acct_host' => 'X-Ascend-User-Acct-Host',
+  'strip_user_name' => 'Strip-User-Name',
+  'itk_ppp_client_server_mo' => 'ITK-PPP-Client-Server-Mode',
+  'usr_mbi_ct_bchannel_used' => 'USR-Mbi_Ct_BChannel_Used',
+  'x_ascend_route_ip' => 'X-Ascend-Route-IP',
+  'ascend_seconds_of_histor' => 'Ascend-Seconds-Of-History',
+  'cvx_data_rate' => 'CVX-Data-Rate',
+  'ascend_x25_profile_name' => 'Ascend-X25-Profile-Name',
+  'itk_ftp_auth_ip' => 'ITK-Ftp-Auth-IP',
+  'cisco_control_info' => 'Cisco-Control-Info',
+  'cvpn3000_secondary_wins' => 'CVPN3000-Secondary-WINS',
+  'usr_call_type' => 'USR-Call-Type',
+  'x_ascend_user_acct_base' => 'X-Ascend-User-Acct-Base',
+  'acct_mcast_in_packett' => 'Acct_Mcast_In_Packets',
+  'ns_vsys_name' => 'NS-VSYS-Name',
+  'acct_output_gigawords' => 'Acct-Output-Gigawords',
+  'bind_typf' => 'Bind_Type',
+  'bintec_ipqostable' => 'BinTec-ipQoSTable',
+  'bintec_ipxstaticservtabl' => 'BinTec-ipxStaticServTable',
+  'cvpn3000_l2tp_mppc_compr' => 'CVPN3000-L2TP-MPPC-Compression',
+  'login_lat_port' => 'Login-LAT-Port',
+  'usr_call_arrival_in_gmt' => 'USR-Call-Arrival-in-GMT',
+  'acct_mcast_in_octets' => 'Acct-Mcast-In-Octets',
+  'erx_sa_validate' => 'ERX-Sa-Validate',
+  'ascend_service_type' => 'Ascend-Service-Type',
+  'usr_pw_vpn_gateway' => 'USR-PW_VPN_Gateway',
+  'acc_ip_compression' => 'Acc-Ip-Compression',
+  'ascend_fr_dce_n392' => 'Ascend-FR-DCE-N392',
+  'bintec_ipxcirctable' => 'BinTec-ipxCircTable',
+  'lac_real_port_type' => 'LAC-Real-Port-Type',
+  'ascend_client_primary_dn' => 'Ascend-Client-Primary-DNS',
+  'acct_session_start_time' => 'Acct-Session-Start-Time',
+  'ascend_if_netmask' => 'Ascend-IF-Netmask',
+  'ms_chap_nt_enc_pw' => 'MS-CHAP-NT-Enc-PW',
+  'ms_mppe_encryption_types' => 'MS-MPPE-Encryption-Types',
+  'cisco_fax_process_abort_' => 'Cisco-Fax-Process-Abort-Flag',
+  'mcast_maxgroups' => 'Mcast-MaxGroups',
+  'annex_end_receive_line_l' => 'Annex-End-Receive-Line-Level',
+  'usr_ipx_call_input_filte' => 'USR-IPX-Call-Input-Filter',
+  'usr_back_channel_data_ra' => 'USR-Back-Channel-Data-Rate',
+  'ascend_cache_time' => 'Ascend-Cache-Time',
+  'x_ascend_data_svc' => 'X-Ascend-Data-Svc',
+  'usr_re_chap_timeout' => 'USR-Re-Chap-Timeout',
+  'bintec_bibodialtable' => 'BinTec-biboDialTable',
+  'annex_connect_progress' => 'Annex-Connect-Progress',
+  'x_ascend_ppp_vj_1172' => 'X-Ascend-PPP-VJ-1172',
+  'usr_igmp_routing' => 'USR-IGMP-Routing',
+  'x_ascend_ip_pool_definit' => 'X-Ascend-IP-Pool-Definition',
+  'h323_prompt_id' => 'h323-prompt-id',
+  'foundry_command_string' => 'Foundry-Command-String',
+  'le_terminate_detail' => 'LE-Terminate-Detail',
+  'cvpn3000_pptp_encryption' => 'CVPN3000-PPTP-Encryption',
+  'quintum_h323_disconnect_' => 'Quintum-h323-disconnect-time',
+  'acc_ml_clear_threshold' => 'Acc-ML-Clear-Threshold',
+  'x_ascend_ip_direct' => 'X-Ascend-IP-Direct',
+  'usr_ip_call_input_filter' => 'USR-IP-Call-Input-Filter',
+  'x_ascend_data_rate' => 'X-Ascend-Data-Rate',
+  'nas_port' => 'NAS-Port',
+  'ascend_client_secondary_' => 'Ascend-Client-Secondary-WINS',
   'ascend_auth_type' => 'Ascend-Auth-Type',
-  'session_timeout' => 'Session-Timeout',
-  'ascend_callback' => 'Ascend-Callback',
-  'usr_chat_script_name' => 'USR-Chat-Script-Name',
-  'port_message' => 'Port-Message',
-  'acct_output_packets' => 'Acct-Output-Packets',
-  'ascend_session_svr_key' => 'Ascend-Session-Svr-Key',
-  'login_tcp_port' => 'Login-TCP-Port',
-  'erx_tunnel_password' => 'ERX-Tunnel-Password',
-  'shasta_user_privilege' => 'Shasta-User-Privilege',
-  'usr_secondary_nbns_serve' => 'USR-Secondary_NBNS_Server',
-  'usr_security_login_limit' => 'USR-Security-Login-Limit',
-  'usr_start_time' => 'USR-Start-Time',
-  'acc_access_partition' => 'Acc-Access-Partition',
-  'versanet_termination_cau' => 'Versanet-Termination-Cause',
-  'x_ascend_call_block_dura' => 'X-Ascend-Call-Block-Duration',
-  'mcast_maxgroups' => 'Mcast_MaxGroups',
-  'ascend_user_acct_base' => 'Ascend-User-Acct-Base',
-  'usr_vpn_gw_location_id' => 'USR-VPN-GW-Location-Id',
-  'usr_block_error_count_li' => 'USR-Block-Error-Count-Limit',
-  'ascend_telnet_profile' => 'Ascend-Telnet-Profile',
-  'ascend_port_redir_protoc' => 'Ascend-Port-Redir-Protocol',
-  'ascend_call_by_call' => 'Ascend-Call-By-Call',
-  'usr_disconnect_cause_ind' => 'USR-Disconnect-Cause-Indicator',
-  'x_ascend_fr_linkup' => 'X-Ascend-FR-LinkUp',
-  'ascend_billing_number' => 'Ascend-Billing-Number',
-  'usr_ds0s' => 'USR-DS0s',
-  'usr_at_zip_output_filter' => 'USR-AT-Zip-Output-Filter',
-  'ascend_user_acct_port' => 'Ascend-User-Acct-Port',
-  'login_port' => 'Login-Port',
-  'arap_security' => 'ARAP-Security',
-  'tunnel_deadtime' => 'Tunnel_Deadtime',
-  'ascend_user_acct_time' => 'Ascend-User-Acct-Time',
-  'ms_chap_challenge' => 'MS-CHAP-Challenge',
-  'ascend_x25_rpoa' => 'Ascend-X25-Rpoa',
-  'login_time' => 'Login-Time',
+  'x_ascend_preempt_limit' => 'X-Ascend-Preempt-Limit',
+  'cvx_xmit_rate' => 'CVX-Xmit-Rate',
+  'annex_transmitted_packet' => 'Annex-Transmitted-Packets',
+  'h323_credit_amount' => 'h323-credit-amount',
+  'usr_reply_script1' => 'USR-Reply-Script1',
   'current_time' => 'Current-Time',
-  'login_service' => 'Login-Service',
-  'ascend_menu_selector' => 'Ascend-Menu-Selector',
-  'ascend_bacp_enable' => 'Ascend-BACP-Enable',
-  'shiva_link_speed' => 'Shiva-Link-Speed',
-  'ascend_private_route_tab' => 'Ascend-Private-Route-Table-ID',
+  'cisco_xmit_rate' => 'Cisco-Xmit-Rate',
   'x_ascend_session_svr_key' => 'X-Ascend-Session-Svr-Key',
-  'ascend_data_filter' => 'Ascend-Data-Filter',
-  'ascend_target_util' => 'Ascend-Target-Util',
-  'shiva_function' => 'Shiva-Function',
-  'usr_pw_usr_ifilter_ip' => 'USR-PW_USR_IFilter_IP',
-  'usr_igmp_routing' => 'USR-IGMP-Routing',
-  'acc_tunnel_port' => 'Acc-Tunnel-Port',
-  'x_ascend_fr_n391' => 'X-Ascend-FR-N391',
-  'medium_type' => 'Medium_Type',
-  'annex_domain_name' => 'Annex-Domain-Name',
-  'ascend_fr_n391' => 'Ascend-FR-N391',
-  'callback_number' => 'Callback-Number',
-  'usr_chassis_temperature' => 'USR-Chassis-Temperature',
-  'dialback_no' => 'Dialback-No',
-  'ms_mppe_recv_key' => 'MS-MPPE-Recv-Key',
-  'ascend_ipx_alias' => 'Ascend-IPX-Alias',
-  'le_nat_inmap' => 'LE-NAT-Inmap',
-  'tunnel_police_rate' => 'Tunnel_Police_Rate',
-  'acct_terminate_cause' => 'Acct-Terminate-Cause',
-  'le_nat_other_session_tim' => 'LE-NAT-Other-Session-Timeout',
-  'usr_ip_rip_output_filter' => 'USR-IP-RIP-Output-Filter',
-  'exec_program' => 'Exec-Program',
-  'h323_disconnect_cause' => 'h323-disconnect-cause',
-  'usr_chassis_call_channel' => 'USR-Chassis-Call-Channel',
-  'x_ascend_fr_dlci' => 'X-Ascend-FR-DLCI',
-  'ms_link_drop_time_limit' => 'MS-Link-Drop-Time-Limit',
-  'acc_callback_num_valid' => 'Acc-Callback-Num-Valid',
-  'cisco_presession_time' => 'Cisco-PreSession-Time',
-  'ms_chap_response' => 'MS-CHAP-Response',
-  'usr_spoofing' => 'USR-Spoofing',
-  'usr_num_fax_pages_proces' => 'USR-Num-Fax-Pages-Processed',
-  'ascend_x25_cug' => 'Ascend-X25-Cug',
-  'ascend_fr_dlci' => 'Ascend-FR-DLCI',
-  'shiva_user_attributes' => 'Shiva-User-Attributes',
-  'ms_chap_lm_enc_pw' => 'MS-CHAP-LM-Enc-PW',
-  'ascend_transit_number' => 'Ascend-Transit-Number',
-  'usr_last_number_dialed_i' => 'USR-Last-Number-Dialed-In-DNIS',
-  'usr_ip_saa_filter' => 'USR-IP-SAA-Filter',
-  'usr_pw_usr_ifilter_ipx' => 'USR-PW_USR_IFilter_IPX',
-  'ascend_remove_seconds' => 'Ascend-Remove-Seconds',
-  'le_connect_detail' => 'LE-Connect-Detail',
-  'ascend_assign_ip_global_' => 'Ascend-Assign-IP-Global-Pool',
-  'proxy_to_realm' => 'Proxy-To-Realm',
-  'usr_retrains_requested' => 'USR-Retrains-Requested',
-  'h323_remote_address' => 'h323-remote-address',
-  'ascend_x25_nui_prompt' => 'Ascend-X25-Nui-Prompt',
-  'acc_customer_id' => 'Acc-Customer-Id',
-  'ms_chap2_response' => 'MS-CHAP2-Response',
-  'ascend_host_info' => 'Ascend-Host-Info',
-  'annex_addr_resolution_se' => 'Annex-Addr-Resolution-Servers',
-  'x_ascend_multilink_id' => 'X-Ascend-Multilink-ID',
-  'login_lat_service' => 'Login-LAT-Service',
-  'usr_rmmie_rcv_pwrlvl_330' => 'USR-RMMIE-Rcv-PwrLvl-3300Hz',
-  'ascend_event_type' => 'Ascend-Event-Type',
-  'ascend_inc_channel_count' => 'Ascend-Inc-Channel-Count',
-  'cisco_ppp_async_map' => 'Cisco-PPP-Async-Map',
-  'usr_min_compression_size' => 'USR-Min-Compression-Size',
-  'ascend_traffic_shaper' => 'Ascend-Traffic-Shaper',
-  'ascend_user_acct_key' => 'Ascend-User-Acct-Key',
-  'usr_port_tap_output' => 'USR-Port-Tap-Output',
-  'ascend_x25_nui' => 'Ascend-X25-Nui',
-  'x_ascend_disconnect_caus' => 'X-Ascend-Disconnect-Cause',
-  'ascend_cbcp_enable' => 'Ascend-CBCP-Enable',
-  'usr_framed_ip_address_po' => 'USR-Framed_IP_Address_Pool_Name',
-  'ascend_x25_profile_name' => 'Ascend-X25-Profile-Name',
-  'usr_orig_nas_type' => 'USR-Orig-NAS-Type',
+  'ascend_authen_alias' => 'Ascend-Authen-Alias',
+  'erx_redirect_vr_name' => 'ERX-Redirect-VR-Name',
+  'module_success_message' => 'Module-Success-Message',
+  'acc_dialout_auth_mode' => 'Acc-Dialout-Auth-Mode',
+  'bind_auth_contexu' => 'Bind_Auth_Context',
+  'x_ascend_minimum_channel' => 'X-Ascend-Minimum-Channels',
+  'usr_event_date_time' => 'USR-Event-Date-Time',
+  'x_ascend_ipx_node_addr' => 'X-Ascend-IPX-Node-Addr',
+  'cvpn3000_ipsec_over_udp' => 'CVPN3000-IPSec-Over-UDP',
+  'x_ascend_user_acct_time' => 'X-Ascend-User-Acct-Time',
+  'cisco_email_server_ack_f' => 'Cisco-Email-Server-Ack-Flag',
+  'telebit_activate_command' => 'Telebit-Activate-Command',
   'acc_output_errors' => 'Acc-Output-Errors',
-  'h323_redirect_ip_address' => 'h323-redirect-ip-address',
-  'usr_ip_call_output_filte' => 'USR-IP-Call-Output-Filter',
-  'cisco_avpair' => 'Cisco-AVPair',
-  'usr_slot_connected_to' => 'USR-Slot-Connected-To',
-  'framed_route' => 'Framed-Route',
-  'ascend_global_call_id' => 'Ascend-Global-Call-Id',
-  'x_ascend_seconds_of_hist' => 'X-Ascend-Seconds-Of-History',
-  'x_ascend_temporary_rtes' => 'X-Ascend-Temporary-Rtes',
-  'h323_currency_type' => 'h323-currency-type',
-  'x_ascend_token_expiry' => 'X-Ascend-Token-Expiry',
-  'pvc_encapsulation_type' => 'PVC_Encapsulation_Type',
-  'x_ascend_pw_lifetime' => 'X-Ascend-PW-Lifetime',
+  'juniper_allow_configurat' => 'Juniper-Allow-Configuration',
+  'bind_l2tp_tunnel_name' => 'Bind-L2TP-Tunnel-Name',
+  'x_ascend_pri_number_type' => 'X-Ascend-PRI-Number-Type',
+  'bintec_biboppptable' => 'BinTec-biboPPPTable',
+  'le_ipsec_outsource_profi' => 'LE-IPSec-Outsource-Profile',
+  'usr_at_zip_input_filter' => 'USR-AT-Zip-Input-Filter',
+  'replicate_to_realm' => 'Replicate-To-Realm',
+  'annex_mrru' => 'Annex-MRRU',
+  'event_timestamp' => 'Event-Timestamp',
+  'nokia_sgsn_ip_address' => 'Nokia-SGSN-IP-Address',
+  'ascend_pre_input_packets' => 'Ascend-Pre-Input-Packets',
+  'cvpn5000_client_assigned' => 'CVPN5000-Client-Assigned-IP',
+  'tunnel_dnit' => 'Tunnel_DNIS',
+  'h323_call_origin' => 'h323-call-origin',
+  'x_ascend_fr_type' => 'X-Ascend-FR-Type',
+  'itk_provider_id' => 'ITK-Provider-Id',
+  'cvx_ppp_log_mask' => 'CVX-PPP-Log-Mask',
+  'x_ascend_token_idle' => 'X-Ascend-Token-Idle',
+  'usr_rmmie_pwrlvl_xmit_lv' => 'USR-RMMIE-PwrLvl-Xmit-Lvl',
+  'usr_igmp_query_interval' => 'USR-IGMP-Query-Interval',
+  'quintum_h323_billing_mod' => 'Quintum-h323-billing-model',
+  'ascend_atm_vci' => 'Ascend-ATM-Vci',
+  'usr_port_tap_output' => 'USR-Port-Tap-Output',
+  'session' => 'Session',
+  'itk_welcome_message' => 'ITK-Welcome-Message',
+  'cvpn3000_ike_keep_alives' => 'CVPN3000-IKE-Keep-Alives',
+  'ascend_uu_info' => 'Ascend-UU-Info',
+  'usr_et_bridge_call_outpu' => 'USR-ET-Bridge-Call-Output-Filte',
+  'usr_secondary_dns_server' => 'USR-Secondary_DNS_Server',
+  'ms_mppe_recv_key' => 'MS-MPPE-Recv-Key',
+  'bintec_ripcirctable' => 'BinTec-ripCircTable',
+  'acc_dial_port_index' => 'Acc-Dial-Port-Index',
+  'cisco_nas_port' => 'Cisco-NAS-Port',
+  'itk_username' => 'ITK-Username',
+  'usr_send_script1' => 'USR-Send-Script1',
+  'cvpn3000_ipsec_ike_peer_' => 'CVPN3000-IPSec-IKE-Peer-ID-Check',
+  'ascend_dsl_upstream_limi' => 'Ascend-Dsl-Upstream-Limit',
+  'x_ascend_dec_channel_cou' => 'X-Ascend-Dec-Channel-Count',
+  'usr_tunnel_security' => 'USR-Tunnel-Security',
+  'arap_security' => 'ARAP-Security',
+  'tunnel_preference' => 'Tunnel-Preference',
+  'cisco_port_used' => 'Cisco-Port-Used',
+  'usr_reply_script4' => 'USR-Reply-Script4',
+  'cvpn5000_client_real_ip' => 'CVPN5000-Client-Real-IP',
+  'usr_rmmie_status' => 'USR-RMMIE-Status',
+  'usr_send_script4' => 'USR-Send-Script4',
+  'quintum_h323_connect_tim' => 'Quintum-h323-connect-time',
+  'annex_syslog_tap' => 'Annex-Syslog-Tap',
+  'redcreek_tunneled_hostna' => 'RedCreek-Tunneled-HostName',
+  'acc_clearing_location' => 'Acc-Clearing-Location',
+  'ascend_access_intercept_' => 'Ascend-Access-Intercept-LEA',
+  'annex_disconnect_reason' => 'Annex-Disconnect-Reason',
+  'usr_at_input_filter' => 'USR-AT-Input-Filter',
+  'usr_auth_mode' => 'USR-Auth-Mode',
   'usr_expected_voltage' => 'USR-Expected-Voltage',
-  'usr_simplified_v42bis_us' => 'USR-Simplified-V42bis-Usage',
-  'shiva_customer_id' => 'Shiva-Customer-Id',
-  'usr_compression_algorith' => 'USR-Compression-Algorithm',
-  'annex_system_disc_reason' => 'Annex-System-Disc-Reason',
+  'shiva_session_id' => 'Shiva-Session-Id',
+  'annex_maximum_call_durat' => 'Annex-Maximum-Call-Duration',
+  'usr_block_error_count_li' => 'USR-Block-Error-Count-Limit',
+  'ascend_owner_ip_addr' => 'Ascend-Owner-IP-Addr',
+  'bind_tun_contexu' => 'Bind_Tun_Context',
+  'usr_pw_usr_ofilter_ipx' => 'USR-PW_USR_OFilter_IPX',
+  'framed_routing' => 'Framed-Routing',
+  'annex_primary_nbns_serve' => 'Annex-Primary-NBNS-Server',
+  'usr_interface_index' => 'USR-Interface-Index',
+  'pam_auth' => 'Pam-Auth',
+  'usr_end_time' => 'USR-End-Time',
+  'rate_limit_bursu' => 'Rate_Limit_Burst',
+  'nomadix_expiration' => 'Nomadix-Expiration',
+  'x_ascend_transit_number' => 'X-Ascend-Transit-Number',
+  'itk_usergroup' => 'ITK-Usergroup',
+  'x_ascend_assign_ip_pool' => 'X-Ascend-Assign-IP-Pool',
   'annex_secondary_nbns_ser' => 'Annex-Secondary-NBNS-Server',
-  'usr_q931_call_reference_' => 'USR-Q931-Call-Reference-Value',
-  'usr_send_password' => 'USR-Send-Password',
-  'prompt' => 'Prompt',
-  'usr_cusr_hat_script_rule' => 'USR-CUSR-hat-Script-Rules',
-  'usr_event_id' => 'USR-Event-Id',
-  'usr_ccp_algorithm' => 'USR-CCP-Algorithm',
-  'usr_mbi_ct_bchannel_used' => 'USR-Mbi_Ct_BChannel_Used',
-  'ascend_svc_enabled' => 'Ascend-SVC-Enabled',
-  'framed_mtu' => 'Framed-MTU',
-  'acc_reason_code' => 'Acc-Reason-Code',
-  'bind_l2tp_flow_control' => 'Bind_L2TP_Flow_Control',
+  'bind_dot1q_vlan_tag_id' => 'Bind-Dot1q-Vlan-Tag-Id',
+  'ms_secondary_nbns_server' => 'MS-Secondary-NBNS-Server',
+  'tunnel_retransmit' => 'Tunnel-Retransmit',
+  'acct_tunnel_connection' => 'Acct-Tunnel-Connection',
+  'x_ascend_backup' => 'X-Ascend-Backup',
+  'xedia_ppp_echo_interval' => 'Xedia-PPP-Echo-Interval',
+  'usr_bearer_capabilities' => 'USR-Bearer-Capabilities',
+  'shiva_acct_serv_switch' => 'Shiva-Acct-Serv-Switch',
+  'acct_authentic' => 'Acct-Authentic',
+  'le_nat_other_session_tim' => 'LE-NAT-Other-Session-Timeout',
+  'cvpn3000_ipsec_banner2' => 'CVPN3000-IPSec-Banner2',
+  'x_ascend_force_56' => 'X-Ascend-Force-56',
+  'framed_appletalk_network' => 'Framed-AppleTalk-Network',
+  'reply_message' => 'Reply-Message',
+  'class' => 'Class',
+  'h323_conf_id' => 'h323-conf-id',
+  'quintum_h323_disconnecta' => 'Quintum-h323-disconnect-cause',
+  'itk_filter_rule' => 'ITK-Filter-Rule',
+  'wispr_bandwidth_max_up' => 'WISPr-Bandwidth-Max-Up',
+  'usr_appletalk_network_ra' => 'USR-Appletalk-Network-Range',
   'ascend_cbcp_delay' => 'Ascend-CBCP-Delay',
-  'le_ipsec_deny_action' => 'LE-IPSec-Deny-Action',
+  'usr_dte_ring_no_answer_l' => 'USR-DTE-Ring-No-Answer-Limit',
+  'pre_acct_type' => 'Pre-Acct-Type',
+  'usr_local_ip_address' => 'USR-Local-IP-Address',
+  'ascend_dropped_octets' => 'Ascend-Dropped-Octets',
+  'ascend_h323_dialed_time' => 'Ascend-H323-Dialed-Time',
+  'cisco_email_server_addre' => 'Cisco-Email-Server-Address',
+  'ascend_x25_x121_address' => 'Ascend-X25-X121-Address',
+  'cvx_multicast_client' => 'CVX-Multicast-Client',
+  'wispr_bandwidth_min_up' => 'WISPr-Bandwidth-Min-Up',
+  'usr_at_output_filter' => 'USR-AT-Output-Filter',
+  'annex_local_ip_address' => 'Annex-Local-IP-Address',
+  'cisco_ip_pool_definition' => 'Cisco-IP-Pool-Definition',
+  'cisco_gateway_id' => 'Cisco-Gateway-Id',
+  'itk_password_prompt' => 'ITK-Password-Prompt',
+  'annex_domain_name' => 'Annex-Domain-Name',
+  'foundry_command_exceptio' => 'Foundry-Command-Exception-Flag',
+  'ascend_preempt_limit' => 'Ascend-Preempt-Limit',
+  'erx_minimum_bps' => 'ERX-Minimum-BPS',
+  'aat_mcast_client' => 'AAT-MCast-Client',
+  'ascend_atm_fault_managem' => 'Ascend-ATM-Fault-Management',
+  'ascend_event_type' => 'Ascend-Event-Type',
+  'exec_program_wait' => 'Exec-Program-Wait',
+  'framed_interface_id' => 'Framed-Interface-Id',
+
+  #NETC.NET.AU (RADIATOR?)
+  'authentication_type' => 'Authentication-Type',
 
-  #NOMENT
-  'nomadix_bw_down' => 'Nomadix-Bw-Down',
-  'nomadix_bw_up' => 'Nomadix-Bw-Up',
-  'nomadix_ip_upsell' => 'Nomadix-IP-Upsell',
 );
 
 1;
index 647621d..9bba057 100644 (file)
@@ -100,6 +100,7 @@ sub check {
     || $self->ut_number('svcnum')
     || $self->ut_foreign_key('svcnum','svc_acct','svcnum')
     || $self->ut_text('groupname')
+    || $self->SUPER::check
   ;
 }
 
diff --git a/FS/FS/router.pm b/FS/FS/router.pm
new file mode 100755 (executable)
index 0000000..2554ce8
--- /dev/null
@@ -0,0 +1,144 @@
+package FS::router;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record qw( qsearchs qsearch );
+use FS::addr_block;
+
+@ISA = qw( FS::Record );
+
+=head1 NAME
+
+FS::router - Object methods for router records
+
+=head1 SYNOPSIS
+
+  use FS::router;
+
+  $record = new FS::router \%hash;
+  $record = new FS::router { 'column' => 'value' };
+
+  $error = $record->insert;
+
+  $error = $new_record->replace($old_record);
+
+  $error = $record->delete;
+
+  $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::router record describes a broadband router, such as a DSLAM or a wireless
+ access point.  FS::router inherits from FS::Record.  The following 
+fields are currently supported:
+
+=over 4
+
+=item routernum - primary key
+
+=item routername - descriptive name for the router
+
+=item svcnum - svcnum of the owning FS::svc_broadband, if appropriate
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Create a new record.  To add the record to the database, see "insert".
+
+=cut
+
+sub table { 'router'; }
+
+=item insert
+
+Adds this record to the database.  If there is an error, returns the error,
+otherwise returns false.
+
+=item delete
+
+Deletes this record from the database.  If there is an error, returns the
+error, otherwise returns false.
+
+=item replace OLD_RECORD
+
+Replaces 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('routernum')
+    || $self->ut_text('routername');
+  return $error if $error;
+
+  $self->SUPER::check;
+}
+
+=item addr_block
+
+Returns a list of FS::addr_block objects (address blocks) associated
+with this object.
+
+=cut
+
+sub addr_block {
+  my $self = shift;
+  return qsearch('addr_block', { routernum => $self->routernum });
+}
+
+=item part_svc_router
+
+Returns a list of FS::part_svc_router objects associated with this 
+object.  This is unlikely to be useful for any purpose other than retrieving 
+the associated FS::part_svc objects.  See below.
+
+=cut
+
+sub part_svc_router {
+  my $self = shift;
+  return qsearch('part_svc_router', { routernum => $self->routernum });
+}
+
+=item part_svc
+
+Returns a list of FS::part_svc objects associated with this object.
+
+=cut
+
+sub part_svc {
+  my $self = shift;
+  return map { qsearchs('part_svc', { svcpart => $_->svcpart }) }
+      $self->part_svc_router;
+}
+
+=back
+
+=head1 VERSION
+
+$Id:
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+FS::svc_broadband, FS::router, FS::addr_block, FS::part_svc,
+schema.html from the base documentation.
+
+=cut
+
+1;
+
index de0f2a7..2ad594c 100644 (file)
@@ -216,7 +216,7 @@ sub check {
   return $error if $error;
   return "Unknown svcnum"
     unless qsearchs('svc_acct', { 'svcnum' => $self->svcnum } );
-  '';
+  $self->SUPER::check;
 }
 
 =item nas_heartbeat
@@ -247,7 +247,7 @@ sub svc_acct {
 
 =head1 VERSION
 
-$Id: session.pm,v 1.7 2001-04-15 13:35:12 ivan Exp $
+$Id: session.pm,v 1.8 2003-08-05 00:20:46 khoff Exp $
 
 =head1 BUGS
 
index 87b6097..a154f3f 100644 (file)
@@ -2,7 +2,7 @@ package FS::svc_Common;
 
 use strict;
 use vars qw( @ISA $noexport_hack );
-use FS::Record qw( qsearchs fields dbh );
+use FS::Record qw( qsearch qsearchs fields dbh );
 use FS::cust_svc;
 use FS::part_svc;
 use FS::queue;
@@ -28,7 +28,61 @@ inherit from, i.e. FS::svc_acct.  FS::svc_Common inherits from FS::Record.
 
 =over 4
 
-=item insert [ JOBNUM_ARRAYREF ]
+=cut
+
+sub virtual_fields {
+
+  # This restricts the fields based on part_svc_column and the svcpart of 
+  # the service.  There are four possible cases:
+  # 1.  svcpart passed as part of the svc_x hash.
+  # 2.  svcpart fetched via cust_svc based on svcnum.
+  # 3.  No svcnum or svcpart.  In this case, return ALL the fields with 
+  #     dbtable eq $self->table.
+  # 4.  Called via "fields('svc_acct')" or something similar.  In this case
+  #     there is no $self object.
+
+  my $self = shift;
+  my $svcpart;
+  my @vfields = $self->SUPER::virtual_fields;
+
+  return @vfields unless (ref $self); # Case 4
+
+  if ($self->svcpart) { # Case 1
+    $svcpart = $self->svcpart;
+  } elsif ( $self->svcnum
+            && qsearchs('cust_svc',{'svcnum'=>$self->svcnum} )
+          ) { #Case 2
+    $svcpart = $self->cust_svc->svcpart;
+  } else { # Case 3
+    $svcpart = '';
+  }
+
+  if ($svcpart) { #Cases 1 and 2
+    my %flags = map { $_->columnname, $_->columnflag } (
+        qsearch ('part_svc_column', { svcpart => $svcpart } )
+      );
+    return grep { not ($flags{$_} eq 'X') } @vfields;
+  } else { # Case 3
+    return @vfields;
+  } 
+  return ();
+}
+
+=item check
+
+Checks the validity of fields in this record.
+
+At present, this does nothing but call FS::Record::check (which, in turn, 
+does nothing but run virtual field checks).
+
+=cut
+
+sub check {
+  my $self = shift;
+  $self->SUPER::check;
+}
+
+=item insert [ JOBNUM_ARRAYREF [ OBJECTS_ARRAYREF ] ]
 
 Adds this record to the database.  If there is an error, returns the error,
 otherwise returns false.
@@ -39,11 +93,16 @@ defined.  An FS::cust_svc record will be created and inserted.
 If an arrayref is passed as parameter, the B<jobnum>s of any export jobs will
 be added to the array.
 
+If an arrayref of FS::tablename objects (for example, FS::acct_snarf objects)
+is passed as the optional second parameter, they will have their svcnum fields
+set and will be inserted after this record, but before any exports are run.
+
 =cut
 
 sub insert {
   my $self = shift;
   local $FS::queue::jobnums = shift if @_;
+  my $objects = scalar(@_) ? shift : [];
   my $error;
 
   local $SIG{HUP} = 'IGNORE';
@@ -61,10 +120,12 @@ sub insert {
   return $error if $error;
 
   my $svcnum = $self->svcnum;
-  my $cust_svc;
-  unless ( $svcnum ) {
+  my $cust_svc = $svcnum ? qsearchs('cust_svc',{'svcnum'=>$self->svcnum}) : '';
+  #unless ( $svcnum ) {
+  if ( !$svcnum or !$cust_svc ) {
     $cust_svc = new FS::cust_svc ( {
       #hua?# 'svcnum'  => $svcnum,
+      'svcnum'  => $self->svcnum,
       'pkgnum'  => $self->pkgnum,
       'svcpart' => $self->svcpart,
     } );
@@ -75,7 +136,7 @@ sub insert {
     }
     $svcnum = $self->svcnum($cust_svc->svcnum);
   } else {
-    $cust_svc = qsearchs('cust_svc',{'svcnum'=>$self->svcnum});
+    #$cust_svc = qsearchs('cust_svc',{'svcnum'=>$self->svcnum});
     unless ( $cust_svc ) {
       $dbh->rollback if $oldAutoCommit;
       return "no cust_svc record found for svcnum ". $self->svcnum;
@@ -90,6 +151,15 @@ sub insert {
     return $error;
   }
 
+  foreach my $object ( @$objects ) {
+    $object->svcnum($self->svcnum);
+    $error = $object->insert;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
+    }
+  }
+
   #new-style exports!
   unless ( $noexport_hack ) {
     foreach my $part_export ( $self->cust_svc->part_svc->part_export ) {
@@ -242,7 +312,7 @@ sub setx {
 
   #get part_svc
   my $svcpart;
-  if ( $self->svcnum ) {
+  if ( $self->svcnum && qsearchs('cust_svc', {'svcnum'=>$self->svcnum}) ) {
     my $cust_svc = $self->cust_svc;
     return "Unknown svcnum" unless $cust_svc; 
     $svcpart = $cust_svc->svcpart;
@@ -254,7 +324,7 @@ sub setx {
 
   #set default/fixed/whatever fields from part_svc
   my $table = $self->table;
-  foreach my $field ( grep { $_ ne 'svcnum' } fields($table) ) {
+  foreach my $field ( grep { $_ ne 'svcnum' } $self->fields ) {
     my $part_svc_column = $part_svc->part_svc_column($field);
     if ( $part_svc_column->columnflag eq $x ) {
       $self->setfield( $field, $part_svc_column->columnvalue );
@@ -360,11 +430,31 @@ methods.  Called by the cancel method of FS::cust_pkg (see L<FS::cust_pkg>).
 
 sub cancel { ''; }
 
-=back
+=item clone_suspended
+
+Constructor used by FS::part_export::_export_suspend fallback.  Stub returning
+same object for svc_ classes which don't implement a suspension fallback
+(everything except svc_acct at the moment).  Document better.
+
+=cut
+
+sub clone_suspended {
+  shift;
+}
 
-=head1 VERSION
+=item clone_kludge_unsuspend 
 
-$Id: svc_Common.pm,v 1.12 2002-06-14 11:22:53 ivan Exp $
+Constructor used by FS::part_export::_export_unsuspend fallback.  Stub returning
+same object for svc_ classes which don't implement a suspension fallback
+(everything except svc_acct at the moment).  Document better.
+
+=cut
+
+sub clone_kludge_unsuspend {
+  shift;
+}
+
+=back
 
 =head1 BUGS
 
index c95df94..32d8720 100644 (file)
@@ -1,28 +1,26 @@
 package FS::svc_acct;
 
 use strict;
-use vars qw( @ISA $noexport_hack $conf
+use vars qw( @ISA $DEBUG $me $conf
              $dir_prefix @shells $usernamemin
              $usernamemax $passwordmin $passwordmax
              $username_ampersand $username_letter $username_letterfirst
              $username_noperiod $username_nounderscore $username_nodash
              $username_uppercase
-             $mydomain
              $welcome_template $welcome_from $welcome_subject $welcome_mimetype
              $smtpmachine
+             $radius_password $radius_ip
              $dirhash
              @saltset @pw_set );
 use Carp;
 use Fcntl qw(:flock);
 use FS::UID qw( datasrc );
 use FS::Conf;
-use FS::Record qw( qsearch qsearchs fields dbh );
+use FS::Record qw( qsearch qsearchs fields dbh dbdef );
 use FS::svc_Common;
-use Net::SSH;
 use FS::cust_svc;
 use FS::part_svc;
 use FS::svc_acct_pop;
-use FS::svc_acct_sm;
 use FS::cust_main_invoice;
 use FS::svc_domain;
 use FS::raddb;
@@ -34,6 +32,9 @@ use FS::Msgcat qw(gettext);
 
 @ISA = qw( FS::svc_Common );
 
+$DEBUG = 0;
+$me = '[FS::svc_acct]';
+
 #ask FS::UID to run this stuff for us later
 $FS::UID::callback{'FS::svc_acct'} = sub { 
   $conf = new FS::Conf;
@@ -50,7 +51,6 @@ $FS::UID::callback{'FS::svc_acct'} = sub {
   $username_nodash = $conf->exists('username-nodash');
   $username_uppercase = $conf->exists('username-uppercase');
   $username_ampersand = $conf->exists('username-ampersand');
-  $mydomain = $conf->config('domain');
   $dirhash = $conf->config('dirhash') || 0;
   if ( $conf->exists('welcome_email') ) {
     $welcome_template = new Text::Template (
@@ -62,8 +62,13 @@ $FS::UID::callback{'FS::svc_acct'} = sub {
     $welcome_mimetype = $conf->config('welcome_email-mimetype') || 'text/plain';
   } else {
     $welcome_template = '';
+    $welcome_from = '';
+    $welcome_subject = '';
+    $welcome_mimetype = '';
   }
   $smtpmachine = $conf->config('smtpmachine');
+  $radius_password = $conf->config('radius-password') || 'Password';
+  $radius_ip = $conf->config('radius-ip') || 'Framed-IP-Address';
 };
 
 @saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
@@ -183,9 +188,15 @@ The additional field I<usergroup> can optionally be defined; if so it should
 contain an arrayref of group names.  See L<FS::radius_usergroup>.  (used in
 sqlradius export only)
 
+The additional field I<child_objects> can optionally be defined; if so it
+should contain an arrayref of FS::tablename objects.  They will have their
+svcnum fields set and will be inserted after this record, but before any
+exports are run.
+
 (TODOC: L<FS::queue> and L<freeside-queued>)
 
-(TODOC: new exports! $noexport_hack)
+(TODOC: new exports!)
+
 
 =cut
 
@@ -215,7 +226,7 @@ sub insert {
   #                             'domsvc'   => $self->domsvc,
   #                           } );
 
-  if ( $self->svcnum ) {
+  if ( $self->svcnum && qsearchs('cust_svc',{'svcnum'=>$self->svcnum}) ) {
     my $cust_svc = qsearchs('cust_svc',{'svcnum'=>$self->svcnum});
     unless ( $cust_svc ) {
       $dbh->rollback if $oldAutoCommit;
@@ -246,7 +257,8 @@ sub insert {
 
   if ( @dup_user || @dup_userdomain || @dup_uid ) {
     my $exports = FS::part_export::export_info('svc_acct');
-    my( %conflict_user_svcpart, %conflict_userdomain_svcpart );
+    my %conflict_user_svcpart;
+    my %conflict_userdomain_svcpart = ( $self->svcpart => 'SELF', );
 
     foreach my $part_export ( $part_svc->part_export ) {
 
@@ -264,7 +276,11 @@ sub insert {
       #    qsearch('export_svc', { 'exportnum' => $part_export->exportnum });
       #}
 
-      my $nodomain = $exports->{$part_export->exporttype}{'nodomain'};
+      #my $nodomain = $exports->{$part_export->exporttype}{'nodomain'};
+      #silly kludge to avoid uninitialized value errors
+      my $nodomain = exists( $exports->{$part_export->exporttype}{'nodomain'} )
+                     ? $exports->{$part_export->exporttype}{'nodomain'}
+                     : '';
       if ( $nodomain =~ /^Y/i ) {
         $conflict_user_svcpart{$_} = $part_export->exportnum
           foreach @svcparts;
@@ -309,7 +325,7 @@ sub insert {
   #see?  i told you it was more complicated
 
   my @jobnums;
-  $error = $self->SUPER::insert(\@jobnums);
+  $error = $self->SUPER::insert(\@jobnums, $self->child_objects || [] );
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return $error;
@@ -340,47 +356,58 @@ sub insert {
     return "queueing job (transaction rolled back): $error";
   }
 
-  #welcome email
   my $cust_pkg = $self->cust_svc->cust_pkg;
-  my( $cust_main, $to ) = ( '', '' );
-  if ( $welcome_template && $cust_pkg ) {
+
+  if ( $cust_pkg ) {
     my $cust_main = $cust_pkg->cust_main;
-    my $to = join(', ', grep { $_ ne 'POST' } $cust_main->invoicing_list );
-    if ( $to ) {
-      my $wqueue = new FS::queue {
-        'svcnum' => $self->svcnum,
-        'job'    => 'FS::svc_acct::send_email'
-      };
-      warn "attempting to queue email to $to";
-      my $error = $wqueue->insert(
-        'to'       => $to,
-        'from'     => $welcome_from,
-        'subject'  => $welcome_subject,
-        'mimetype' => $welcome_mimetype,
-        'body'     => $welcome_template->fill_in( HASH => {
-                        'username' => $self->username,
-                        'password' => $self->_password,
-                        'first'    => $cust_main->first,
-                        'last'     => $cust_main->getfield('last'),
-                        'pkg'      => $cust_pkg->part_pkg->pkg,
-                      } ),
-      );
-      if ( $error ) {
-        $dbh->rollback if $oldAutoCommit;
-        return "queuing welcome email: $error";
-      }
-  
-      foreach my $jobnum ( @jobnums ) {
-        my $error = $wqueue->depend_insert($jobnum);
+
+    if ( $conf->exists('emailinvoiceauto') ) {
+      my @invoicing_list = $cust_main->invoicing_list;
+      push @invoicing_list, $self->email;
+      $cust_main->invoicing_list(\@invoicing_list);
+    }
+
+    #welcome email
+    my $to = '';
+    if ( $welcome_template && $cust_pkg ) {
+      my $to = join(', ', grep { $_ ne 'POST' } $cust_main->invoicing_list );
+      if ( $to ) {
+        my $wqueue = new FS::queue {
+          'svcnum' => $self->svcnum,
+          'job'    => 'FS::svc_acct::send_email'
+        };
+        my $error = $wqueue->insert(
+          'to'       => $to,
+          'from'     => $welcome_from,
+          'subject'  => $welcome_subject,
+          'mimetype' => $welcome_mimetype,
+          'body'     => $welcome_template->fill_in( HASH => {
+                          'custnum'  => $self->custnum,
+                          'username' => $self->username,
+                          'password' => $self->_password,
+                          'first'    => $cust_main->first,
+                          'last'     => $cust_main->getfield('last'),
+                          'pkg'      => $cust_pkg->part_pkg->pkg,
+                        } ),
+        );
         if ( $error ) {
           $dbh->rollback if $oldAutoCommit;
-          return "queuing welcome email job dependancy: $error";
+          return "error queuing welcome email: $error";
         }
+
+        foreach my $jobnum ( @jobnums ) {
+          my $error = $wqueue->depend_insert($jobnum);
+          if ( $error ) {
+            $dbh->rollback if $oldAutoCommit;
+            return "error queuing welcome email job dependancy: $error";
+          }
+        }
+
       }
 
     }
-  
-  }
+
+  } # if ( $cust_pkg )
 
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
   ''; #no error
@@ -393,17 +420,14 @@ error, otherwise returns false.
 
 The corresponding FS::cust_svc record will be deleted as well.
 
-(TODOC: new exports! $noexport_hack)
+(TODOC: new exports!)
 
 =cut
 
 sub delete {
   my $self = shift;
 
-  if ( defined( $FS::Record::dbdef->table('svc_acct_sm') ) ) {
-    return "Can't delete an account which has (svc_acct_sm) mail aliases!"
-      if $self->uid && qsearch( 'svc_acct_sm', { 'domuid' => $self->uid } );
-  }
+  return "can't delete system account" if $self->_check_system;
 
   return "Can't delete an account which is a (svc_forward) source!"
     if qsearch( 'svc_forward', { 'srcsvc' => $self->svcnum } );
@@ -491,6 +515,9 @@ sqlradius export only)
 sub replace {
   my ( $new, $old ) = ( shift, shift );
   my $error;
+  warn "$me replacing $old with $new\n" if $DEBUG;
+
+  return "can't modify system account" if $old->_check_system;
 
   return "Username in use"
     if $old->username ne $new->username &&
@@ -517,7 +544,13 @@ sub replace {
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
 
+  # redundant, but so $new->usergroup gets set
+  $error = $new->check;
+  return $error if $error;
+
   $old->usergroup( [ $old->radius_groups ] );
+  warn "old groups: ". join(' ',@{$old->usergroup}). "\n" if $DEBUG;
+  warn "new groups: ". join(' ',@{$new->usergroup}). "\n" if $DEBUG;
   if ( $new->usergroup ) {
     #(sorta) false laziness with FS::part_export::sqlradius::_export_replace
     my @newgroups = @{$new->usergroup};
@@ -557,26 +590,27 @@ sub replace {
     return $error if $error;
   }
 
-  #false laziness with sub insert (and cust_main)
-  my $queue = new FS::queue {
-    'svcnum' => $new->svcnum,
-    'job'    => 'FS::svc_acct::append_fuzzyfiles'
-  };
-  $error = $queue->insert($new->username);
-  if ( $error ) {
-    $dbh->rollback if $oldAutoCommit;
-    return "queueing job (transaction rolled back): $error";
+  if ( $new->username ne $old->username ) {
+    #false laziness with sub insert (and cust_main)
+    my $queue = new FS::queue {
+      'svcnum' => $new->svcnum,
+      'job'    => 'FS::svc_acct::append_fuzzyfiles'
+    };
+    $error = $queue->insert($new->username);
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "queueing job (transaction rolled back): $error";
+    }
   }
 
-
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
   ''; #no error
 }
 
 =item suspend
 
-Suspends this account by prefixing *SUSPENDED* to the password.  If there is an
-error, returns the error, otherwise returns false.
+Suspends this account by calling export-specific suspend hooks.  If there is
+an error, returns the error, otherwise returns false.
 
 Called by the suspend method of FS::cust_pkg (see L<FS::cust_pkg>).
 
@@ -584,23 +618,14 @@ Called by the suspend method of FS::cust_pkg (see L<FS::cust_pkg>).
 
 sub suspend {
   my $self = shift;
-  my %hash = $self->hash;
-  unless ( $hash{_password} =~ /^\*SUSPENDED\* /
-           || $hash{_password} eq '*'
-         ) {
-    $hash{_password} = '*SUSPENDED* '.$hash{_password};
-    my $new = new FS::svc_acct ( \%hash );
-    my $error = $new->replace($self);
-    return $error if $error;
-  }
-
+  return "can't suspend system account" if $self->_check_system;
   $self->SUPER::suspend;
 }
 
 =item unsuspend
 
-Unsuspends this account by removing *SUSPENDED* from the password.  If there is
-an error, returns the error, otherwise returns false.
+Unsuspends this account by by calling export-specific suspend hooks.  If there
+is an error, returns the error, otherwise returns false.
 
 Called by the unsuspend method of FS::cust_pkg (see L<FS::cust_pkg>).
 
@@ -650,7 +675,8 @@ sub check {
   }
 
   my $error = $self->ut_numbern('svcnum')
-              || $self->ut_number('domsvc')
+              #|| $self->ut_number('domsvc')
+              || $self->ut_foreign_key('domsvc', 'svc_domain', 'svcnum' )
               || $self->ut_textn('sec_phrase')
   ;
   return $error if $error;
@@ -705,15 +731,9 @@ sub check {
          && $recref->{username} ne 'root'
          && $recref->{username} ne 'toor';
 
-#    $error = $self->ut_textn('finger');
-#    return $error if $error;
-    $self->getfield('finger') =~
-      /^([\w \t\!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\*\<\>]*)$/
-        or return "Illegal finger: ". $self->getfield('finger');
-    $self->setfield('finger', $1);
 
     $recref->{dir} =~ /^([\/\w\-\.\&]*)$/
-      or return "Illegal directory";
+      or return "Illegal directory: ". $recref->{dir};
     $recref->{dir} = $1;
     return "Illegal directory"
       if $recref->{dir} =~ /(^|\/)\.+(\/|$)/; #no .. component
@@ -745,29 +765,34 @@ sub check {
       $recref->{shell} = '/bin/sync';
     }
 
-    $recref->{quota} =~ /^(\d*)$/ or return "Illegal quota (unimplemented)";
-    $recref->{quota} = $1;
-
   } else {
     $recref->{gid} ne '' ? 
       return "Can't have gid without uid" : ( $recref->{gid}='' );
-    $recref->{finger} ne '' ? 
-      return "Can't have finger-name without uid" : ( $recref->{finger}='' );
     $recref->{dir} ne '' ? 
       return "Can't have directory without uid" : ( $recref->{dir}='' );
     $recref->{shell} ne '' ? 
       return "Can't have shell without uid" : ( $recref->{shell}='' );
-    $recref->{quota} ne '' ? 
-      return "Can't have quota without uid" : ( $recref->{quota}='' );
   }
 
+  #  $error = $self->ut_textn('finger');
+  #  return $error if $error;
+  $self->getfield('finger') =~
+    /^([\w \t\!\@\#\$\%\&\(\)\-\+\;\'\"\,\.\?\/\*\<\>]*)$/
+      or return "Illegal finger: ". $self->getfield('finger');
+  $self->setfield('finger', $1);
+
+  $recref->{quota} =~ /^(\w*)$/ or return "Illegal quota";
+  $recref->{quota} = $1;
+
   unless ( $part_svc->part_svc_column('slipip')->columnflag eq 'F' ) {
-    unless ( $recref->{slipip} eq '0e0' ) {
+    if ( $recref->{slipip} eq '' ) {
+      $recref->{slipip} = '';
+    } elsif ( $recref->{slipip} eq '0e0' ) {
+      $recref->{slipip} = '0e0';
+    } else {
       $recref->{slipip} =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/
-        or return "Illegal slipip". $self->slipip;
+        or return "Illegal slipip". $self->slipip;
       $recref->{slipip} = $1;
-    } else {
-      $recref->{slipip} = '0e0';
     }
 
   }
@@ -791,10 +816,12 @@ sub check {
     #$recref->{password} = $1.
     #  crypt($3,$saltset[int(rand(64))].$saltset[int(rand(64))]
     #;
-  } elsif ( $recref->{_password} =~ /^((\*SUSPENDED\* )?)([\w\.\/\$]{13,34})$/ ) {
+  } elsif ( $recref->{_password} =~ /^((\*SUSPENDED\* )?)([\w\.\/\$\;\+]{13,60})$/ ) {
     $recref->{_password} = $1.$3;
   } elsif ( $recref->{_password} eq '*' ) {
     $recref->{_password} = '*';
+  } elsif ( $recref->{_password} eq '!' ) {
+    $recref->{_password} = '!';
   } elsif ( $recref->{_password} eq '!!' ) {
     $recref->{_password} = '!!';
   } else {
@@ -804,7 +831,18 @@ sub check {
            ": ". $recref->{_password};
   }
 
-  ''; #no error
+  $self->SUPER::check;
+}
+
+=item _check_system
+
+=cut
+
+sub _check_system {
+  my $self = shift;
+  scalar( grep { $self->username eq $_ || $self->email eq $_ }
+               $conf->config('system_usernames')
+        );
 }
 
 =item radius
@@ -839,7 +877,7 @@ sub radius_reply {
       ( $FS::raddb::attrib{lc($attrib)}, $self->getfield($column) );
     } grep { /^radius_/ && $self->getfield($_) } fields( $self->table );
   if ( $self->slipip && $self->slipip ne '0e0' ) {
-    $reply{'Framed-IP-Address'} = $self->slipip;
+    $reply{$radius_ip} = $self->slipip;
   }
   %reply;
 }
@@ -857,7 +895,9 @@ expected to change in the future.
 
 sub radius_check {
   my $self = shift;
-  ( 'Password' => $self->_password,
+  my $password = $self->_password;
+  my $pw_attrib = length($password) <= 12 ? $radius_password : 'Crypt-Password';
+  ( $pw_attrib => $password,
     map {
       /^(rc_(.*))$/;
       my($column, $attrib) = ($1, $2);
@@ -875,14 +915,10 @@ Returns the domain associated with this account.
 
 sub domain {
   my $self = shift;
-  if ( $self->domsvc ) {
-    #$self->svc_domain->domain;
-    my $svc_domain = $self->svc_domain
-      or die "no svc_domain.svcnum for svc_acct.domsvc ". $self->domsvc;
-    $svc_domain->domain;
-  } else {
-    $mydomain or die "svc_acct.domsvc is null and no legacy domain config file";
-  }
+  die "svc_acct.domsvc is null for svcnum ". $self->svcnum unless $self->domsvc;
+  my $svc_domain = $self->svc_domain
+    or die "no svc_domain.svcnum for svc_acct.domsvc ". $self->domsvc;
+  $svc_domain->domain;
 }
 
 =item svc_domain
@@ -903,6 +939,8 @@ sub svc_domain {
 
 Returns the FS::cust_svc record for this account (see L<FS::cust_svc>).
 
+=cut
+
 sub cust_svc {
   my $self = shift;
   qsearchs( 'cust_svc', { 'svcnum' => $self->svcnum } );
@@ -919,10 +957,26 @@ sub email {
   $self->username. '@'. $self->domain;
 }
 
+=item acct_snarf
+
+Returns an array of FS::acct_snarf records associated with the account.
+If the acct_snarf table does not exist or there are no associated records,
+an empty list is returned
+
+=cut
+
+sub acct_snarf {
+  my $self = shift;
+  return () unless dbdef->table('acct_snarf');
+  eval "use FS::acct_snarf;";
+  die $@ if $@;
+  qsearch('acct_snarf', { 'svcnum' => $self->svcnum } );
+}
+
 =item seconds_since TIMESTAMP
 
-Returns the number of seconds this account has been online since TIMESTAMP.
-See L<FS::session>
+Returns the number of seconds this account has been online since TIMESTAMP,
+according to the session monitor (see L<FS::Session>).
 
 TIMESTAMP is specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see
 L<Time::Local> and L<Date::Parse> for conversion functions.
@@ -935,6 +989,60 @@ sub seconds_since {
   $self->cust_svc->seconds_since(@_);
 }
 
+=item seconds_since_sqlradacct TIMESTAMP_START TIMESTAMP_END
+
+Returns the numbers of seconds this account has been online between
+TIMESTAMP_START (inclusive) and TIMESTAMP_END (exclusive), according to an
+external SQL radacct table, specified via sqlradius export.  Sessions which
+started in the specified range but are still open are counted from session
+start to the end of the range (unless they are over 1 day old, in which case
+they are presumed missing their stop record and not counted).  Also, sessions
+which end in the range but started earlier are counted from the start of the
+range to session end.  Finally, sessions which start before the range but end
+after are counted for the entire range.
+
+TIMESTAMP_START and TIMESTAMP_END are specified as UNIX timestamps; see
+L<perlfunc/"time">.  Also see L<Time::Local> and L<Date::Parse> for conversion
+functions.
+
+=cut
+
+#note: POD here, implementation in FS::cust_svc
+sub seconds_since_sqlradacct {
+  my $self = shift;
+  $self->cust_svc->seconds_since_sqlradacct(@_);
+}
+
+=item attribute_since_sqlradacct TIMESTAMP_START TIMESTAMP_END ATTRIBUTE
+
+Returns the sum of the given attribute for all accounts (see L<FS::svc_acct>)
+in this package for sessions ending between TIMESTAMP_START (inclusive) and
+TIMESTAMP_END (exclusive).
+
+TIMESTAMP_START and TIMESTAMP_END are specified as UNIX timestamps; see
+L<perlfunc/"time">.  Also see L<Time::Local> and L<Date::Parse> for conversion
+functions.
+
+=cut
+
+#note: POD here, implementation in FS::cust_svc
+sub attribute_since_sqlradacct {
+  my $self = shift;
+  $self->cust_svc->attribute_since_sqlradacct(@_);
+}
+
+=item get_session_history_sqlradacct TIMESTAMP_START TIMESTAMP_END
+
+Returns an array of hash references of this customers login history for the
+given time range.  (document this better)
+
+=cut
+
+sub get_session_history_sqlradacct {
+  my $self = shift;
+  $self->cust_svc->get_session_history_sqlradacct(@_);
+}
+
 =item radius_groups
 
 Returns all RADIUS groups for this account (see L<FS::radius_usergroup>).
@@ -953,6 +1061,34 @@ sub radius_groups {
   }
 }
 
+=item clone_suspended
+
+Constructor used by FS::part_export::_export_suspend fallback.  Document
+better.
+
+=cut
+
+sub clone_suspended {
+  my $self = shift;
+  my %hash = $self->hash;
+  $hash{_password} = join('',map($pw_set[ int(rand $#pw_set) ], (0..7) ) );
+  new FS::svc_acct \%hash;
+}
+
+=item clone_kludge_unsuspend 
+
+Constructor used by FS::part_export::_export_unsuspend fallback.  Document
+better.
+
+=cut
+
+sub clone_kludge_unsuspend {
+  my $self = shift;
+  my %hash = $self->hash;
+  $hash{_password} = '';
+  new FS::svc_acct \%hash;
+}
+
 =back
 
 =head1 SUBROUTINES
@@ -961,36 +1097,28 @@ sub radius_groups {
 
 =item send_email
 
+This is the FS::svc_acct job-queue-able version.  It still uses
+FS::Misc::send_email under-the-hood.
+
 =cut
 
 sub send_email {
   my %opt = @_;
 
-  use Date::Format;
-  use Mail::Internet 1.44;
-  use Mail::Header;
+  eval "use FS::Misc qw(send_email)";
+  die $@ if $@;
 
   $opt{mimetype} ||= 'text/plain';
   $opt{mimetype} .= '; charset="iso-8859-1"' unless $opt{mimetype} =~ /charset/;
 
-  $ENV{MAILADDRESS} = $opt{from};
-  my $header = new Mail::Header ( [
-    "From: $opt{from}",
-    "To: $opt{to}",
-    "Sender: $opt{from}",
-    "Reply-To: $opt{from}",
-    "Date: ". time2str("%a, %d %b %Y %X %z", time),
-    "Subject: $opt{subject}",
-    "Content-Type: $opt{mimetype}",
-  ] );
-  my $message = new Mail::Internet (
-    'Header' => $header,
-    'Body' => [ map "$_\n", split("\n", $opt{body}) ],
+  my $error = send_email(
+    'from'         => $opt{from},
+    'to'           => $opt{to},
+    'subject'      => $opt{subject},
+    'content-type' => $opt{mimetype},
+    'body'         => [ map "$_\n", split("\n", $opt{body}) ],
   );
-  $!=0;
-  $message->smtpsend( Host => $smtpmachine )
-    or $message->smtpsend( Host => $smtpmachine, Debug => 1 )
-      or die "can't send email to $opt{to} via $smtpmachine with SMTP: $!";
+  die $error if $error;
 }
 
 =item check_and_rebuild_fuzzyfiles
@@ -1141,7 +1269,7 @@ probably live somewhere else...
 L<FS::svc_Common>, edit/part_svc.cgi from an installed web interface,
 export.html from the base documentation, L<FS::Record>, L<FS::Conf>,
 L<FS::cust_svc>, L<FS::part_svc>, L<FS::cust_pkg>, L<FS::queue>,
-L<freeside-queued>), L<Net::SSH>, L<ssh>, L<FS::svc_acct_pop>,
+L<freeside-queued>), L<FS::svc_acct_pop>,
 schema.html from the base documentation.
 
 =cut
index 3c9ea01..f98f91a 100644 (file)
@@ -93,6 +93,7 @@ sub check {
       or $self->ut_number('ac')
       or $self->ut_number('exch')
       or $self->ut_numbern('loc')
+      or $self->SUPER::check
   ;
 
 }
@@ -142,8 +143,7 @@ sub popselector {
     
     function popstate_changed(what) {
       state = what.options[what.selectedIndex].text;
-      for (var i = what.form.popnum.length;i > 0;i--)
-                what.form.popnum.options[i] = null;
+      what.form.popnum.options.length = 0
       what.form.popnum.options[0] = new Option("", "", false, true);
 END
 
@@ -167,7 +167,13 @@ END
   $text .= '</SELECT>'; #callback? return 3 html pieces?  #'</TD><TD>';
 
   $text .= qq!<SELECT NAME="popnum" SIZE=1><OPTION> !;
-  foreach my $pop ( @svc_acct_pop ) {
+  my @initial_select;
+  if ( scalar(@svc_acct_pop) > 100 ) {
+    @initial_select = qsearchs( 'svc_acct_pop', { 'popnum' => $popnum } );
+  } else {
+    @initial_select = @svc_acct_pop;
+  }
+  foreach my $pop ( @initial_select ) {
     $text .= qq!<OPTION VALUE="!. $pop->popnum. '"'.
              ( ( $popnum && $pop->popnum == $popnum ) ? ' SELECTED' : '' ). ">".
              $pop->text;
@@ -182,7 +188,7 @@ END
 
 =head1 VERSION
 
-$Id: svc_acct_pop.pm,v 1.7 2002-04-10 13:42:48 ivan Exp $
+$Id: svc_acct_pop.pm,v 1.10 2003-08-05 00:20:47 khoff Exp $
 
 =head1 BUGS
 
diff --git a/FS/FS/svc_acct_sm.pm b/FS/FS/svc_acct_sm.pm
deleted file mode 100644 (file)
index c92f142..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-package FS::svc_acct_sm;
-
-use strict;
-use vars qw( @ISA $nossh_hack $conf $shellmachine @qmailmachines );
-use FS::Record qw( fields qsearch qsearchs );
-use FS::svc_Common;
-use FS::cust_svc;
-use Net::SSH qw(ssh);
-use FS::Conf;
-use FS::svc_acct;
-use FS::svc_domain;
-
-@ISA = qw( FS::svc_Common );
-
-#ask FS::UID to run this stuff for us later
-#$FS::UID::callback{'FS::svc_acct_sm'} = sub { 
-#  $conf = new FS::Conf;
-#  $shellmachine = $conf->exists('qmailmachines')
-#                  ? $conf->config('shellmachine')
-#                  : '';
-#};
-
-=head1 NAME
-
-FS::svc_acct_sm - Object methods for svc_acct_sm records
-
-=head1 SYNOPSIS
-
-  use FS::svc_acct_sm;
-
-  $record = new FS::svc_acct_sm \%hash;
-  $record = new FS::svc_acct_sm { 'column' => 'value' };
-
-  $error = $record->insert;
-
-  $error = $new_record->replace($old_record);
-
-  $error = $record->delete;
-
-  $error = $record->check;
-
-  $error = $record->suspend;
-
-  $error = $record->unsuspend;
-
-  $error = $record->cancel;
-
-=head1 WARNING
-
-FS::svc_acct_sm is B<depreciated>.  This class is only included for migration
-purposes.  See L<FS::svc_forward>.
-
-=head1 DESCRIPTION
-
-An FS::svc_acct_sm object represents a virtual mail alias.  FS::svc_acct_sm
-inherits from FS::Record.  The following fields are currently supported:
-
-=over 4
-
-=item svcnum - primary key (assigned automatcially for new accounts)
-
-=item domsvc - svcnum of the virtual domain (see L<FS::svc_domain>)
-
-=item domuid - uid of the target account (see L<FS::svc_acct>)
-
-=item domuser - virtual username
-
-=back
-
-=head1 METHODS
-
-=over 4
-
-=item new HASHREF
-
-Creates a new virtual mail alias.  To add the virtual mail alias to the
-database, see L<"insert">.
-
-=cut
-
-sub table { 'svc_acct_sm'; }
-
-=item insert
-
-Adds this virtual mail alias to the database.  If there is an error, returns
-the error, otherwise returns false.
-
-The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be 
-defined.  An FS::cust_svc record will be created and inserted.
-
- #If the configuration values (see L<FS::Conf>) shellmachine and qmailmachines
- #exist, and domuser is `*' (meaning a catch-all mailbox), the command:
- #
- #  [ -e $dir/.qmail-$qdomain-default ] || {
- #    touch $dir/.qmail-$qdomain-default;
- #    chown $uid:$gid $dir/.qmail-$qdomain-default;
- #  }
- #
- #is executed on shellmachine via ssh (see L<dot-qmail/"EXTENSION ADDRESSES">).
- #This behaviour can be surpressed by setting $FS::svc_acct_sm::nossh_hack true.
-
-=cut
-
-sub insert {
-  my $self = shift;
-  my $error;
-
-  local $SIG{HUP} = 'IGNORE';
-  local $SIG{INT} = 'IGNORE';
-  local $SIG{QUIT} = 'IGNORE';
-  local $SIG{TERM} = 'IGNORE';
-  local $SIG{TSTP} = 'IGNORE';
-  local $SIG{PIPE} = 'IGNORE';
-
-  $error=$self->check;
-  return $error if $error;
-
-  return "Domain username (domuser) in use for this domain (domsvc)"
-    if qsearchs('svc_acct_sm',{ 'domuser'=> $self->domuser,
-                                'domsvc' => $self->domsvc,
-                              } );
-
-  return "First domain username (domuser) for domain (domsvc) must be " .
-         qq='*' (catch-all)!=
-    if $self->domuser ne '*'
-       && ! qsearch('svc_acct_sm',{ 'domsvc' => $self->domsvc } )
-       && ! $conf->exists('maildisablecatchall');
-
-  $error = $self->SUPER::insert;
-  return $error if $error;
-
-  #my $svc_domain = qsearchs( 'svc_domain', { 'svcnum' => $self->domsvc } );
-  #my $svc_acct = qsearchs( 'svc_acct', { 'uid' => $self->domuid } );
-  #my ( $uid, $gid, $dir, $domain ) = (
-  #  $svc_acct->uid,
-  #  $svc_acct->gid,
-  #  $svc_acct->dir,
-  #  $svc_domain->domain,
-  #);
-  #my $qdomain = $domain;
-  #$qdomain =~ s/\./:/g; #see manpage for 'dot-qmail': EXTENSION ADDRESSES
-  #ssh("root\@$shellmachine","[ -e $dir/.qmail-$qdomain-default ] || { touch $dir/.qmail-$qdomain-default; chown $uid:$gid $dir/.qmail-$qdomain-default; }")  
-  #  if ( ! $nossh_hack && $shellmachine && $dir && $self->domuser eq '*' );
-
-  ''; #no error
-
-}
-
-=item delete
-
-Deletes this virtual mail alias from the database.  If there is an error,
-returns the error, otherwise returns false.
-
-The corresponding FS::cust_svc record will be deleted as well.
-
-=item replace OLD_RECORD
-
-Replaces OLD_RECORD with this one in the database.  If there is an error,
-returns the error, otherwise returns false.
-
-=cut
-
-sub replace {
-  my ( $new, $old ) = ( shift, shift );
-  my $error;
-
-  return "Domain username (domuser) in use for this domain (domsvc)"
-    if ( $old->domuser ne $new->domuser
-         || $old->domsvc != $new->domsvc
-       )  && qsearchs('svc_acct_sm',{
-         'domuser'=> $new->domuser,
-         'domsvc' => $new->domsvc,
-       } )
-     ;
-
- $new->SUPER::replace($old);
-
-}
-
-=item suspend
-
-Just returns false (no error) for now.
-
-Called by the suspend method of FS::cust_pkg (see L<FS::cust_pkg>).
-
-=item unsuspend
-
-Just returns false (no error) for now.
-
-Called by the unsuspend method of FS::cust_pkg (see L<FS::cust_pkg>).
-
-=item cancel
-
-Just returns false (no error) for now.
-
-Called by the cancel method of FS::cust_pkg (see L<FS::cust_pkg>).
-
-=item check
-
-Checks all fields to make sure this is a valid virtual mail alias.  If there is
-an error, returns the error, otherwise returns false.  Called by the insert and
-replace methods.
-
-Sets any fixed values; see L<FS::part_svc>.
-
-=cut
-
-sub check {
-  my $self = shift;
-  my $error;
-
-  my $x = $self->setfixed;
-  return $x unless ref($x);
-  #my $part_svc = $x;
-
-  my($recref) = $self->hashref;
-
-  $recref->{domuser} =~ /^(\*|[a-z0-9_\-]{2,32})$/
-    or return "Illegal domain username (domuser)";
-  $recref->{domuser} = $1;
-
-  $recref->{domsvc} =~ /^(\d+)$/ or return "Illegal domsvc";
-  $recref->{domsvc} = $1;
-  my($svc_domain);
-  return "Unknown domsvc" unless
-    $svc_domain=qsearchs('svc_domain',{'svcnum'=> $recref->{domsvc} } );
-
-  $recref->{domuid} =~ /^(\d+)$/ or return "Illegal uid";
-  $recref->{domuid} = $1;
-  my($svc_acct);
-  return "Unknown uid" unless
-    $svc_acct=qsearchs('svc_acct',{'uid'=> $recref->{domuid} } );
-
-  ''; #no error
-}
-
-=back
-
-=head1 VERSION
-
-$Id: svc_acct_sm.pm,v 1.5 2001-09-06 20:41:59 ivan Exp $
-
-=head1 BUGS
-
-The remote commands should be configurable.
-
-The $recref stuff in sub check should be cleaned up.
-
-=head1 SEE ALSO
-
-L<FS::svc_forward>
-
-L<FS::Record>, L<FS::Conf>, L<FS::cust_svc>, L<FS::part_svc>, L<FS::cust_pkg>,
-L<FS::svc_acct>, L<FS::svc_domain>, L<Net::SSH>, L<ssh>, L<dot-qmail>,
-schema.html from the base documentation.
-
-=cut
-
-1;
-
diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm
new file mode 100755 (executable)
index 0000000..ec91532
--- /dev/null
@@ -0,0 +1,235 @@
+package FS::svc_broadband;
+
+use strict;
+use vars qw(@ISA $conf);
+use FS::Record qw( qsearchs qsearch dbh );
+use FS::svc_Common;
+use FS::cust_svc;
+use FS::addr_block;
+use NetAddr::IP;
+
+@ISA = qw( FS::svc_Common );
+
+$FS::UID::callback{'FS::svc_broadband'} = sub { 
+  $conf = new FS::Conf;
+};
+
+=head1 NAME
+
+FS::svc_broadband - Object methods for svc_broadband records
+
+=head1 SYNOPSIS
+
+  use FS::svc_broadband;
+
+  $record = new FS::svc_broadband \%hash;
+  $record = new FS::svc_broadband { 'column' => 'value' };
+
+  $error = $record->insert;
+
+  $error = $new_record->replace($old_record);
+
+  $error = $record->delete;
+
+  $error = $record->check;
+
+  $error = $record->suspend;
+
+  $error = $record->unsuspend;
+
+  $error = $record->cancel;
+
+=head1 DESCRIPTION
+
+An FS::svc_broadband object represents a 'broadband' Internet connection, such
+as a DSL, cable modem, or fixed wireless link.  These services are assumed to
+have the following properties:
+
+FS::svc_broadband inherits from FS::svc_Common.  The following fields are
+currently supported:
+
+=over 4
+
+=item svcnum - primary key
+
+=item blocknum - see FS::addr_block
+
+=item
+speed_up - maximum upload speed, in bits per second.  If set to zero, upload
+speed will be unlimited.  Exports that do traffic shaping should handle this
+correctly, and not blindly set the upload speed to zero and kill the customer's
+connection.
+
+=item
+speed_down - maximum download speed, as above
+
+=item ip_addr - the customer's IP address.  If the customer needs more than one
+IP address, set this to the address of the customer's router.  As a result, the
+customer's router will have the same address for both its internal and external
+interfaces thus saving address space.  This has been found to work on most NAT
+routers available.
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new svc_broadband.  To add the record to the database, see
+"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<hash> method.
+
+=cut
+
+sub table { 'svc_broadband'; }
+
+=item insert
+
+Adds this record to the database.  If there is an error, returns the error,
+otherwise returns false.
+
+The additional fields pkgnum and svcpart (see FS::cust_svc) should be 
+defined.  An FS::cust_svc record will be created and inserted.
+
+=cut
+
+# Standard FS::svc_Common::insert
+
+=item delete
+
+Delete this record from the database.
+
+=cut
+
+# Standard FS::svc_Common::delete
+
+=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
+
+# Standard FS::svc_Common::replace
+
+=item suspend
+
+Called by the suspend method of FS::cust_pkg (see FS::cust_pkg).
+
+=item unsuspend
+
+Called by the unsuspend method of FS::cust_pkg (see FS::cust_pkg).
+
+=item cancel
+
+Called by the cancel method of FS::cust_pkg (see FS::cust_pkg).
+
+=item check
+
+Checks all fields to make sure this is a valid broadband service.  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 $x = $self->setfixed;
+
+  return $x unless ref($x);
+
+  my $error =
+    $self->ut_numbern('svcnum')
+    || $self->ut_foreign_key('blocknum', 'addr_block', 'blocknum')
+    || $self->ut_number('speed_up')
+    || $self->ut_number('speed_down')
+    || $self->ut_ipn('ip_addr')
+  ;
+  return $error if $error;
+
+  if($self->speed_up < 0) { return 'speed_up must be positive'; }
+  if($self->speed_down < 0) { return 'speed_down must be positive'; }
+
+  if (not($self->ip_addr) or $self->ip_addr eq '0.0.0.0') {
+    $self->ip_addr($self->addr_block->next_free_addr->addr);
+    if (not $self->ip_addr) {
+      return "No free addresses in addr_block (blocknum: ".$self->blocknum.")";
+    }
+  }
+
+  # This should catch errors in the ip_addr.  If it doesn't,
+  # they'll almost certainly not map into the block anyway.
+  my $self_addr = $self->NetAddr; #netmask is /32
+  return ('Cannot parse address: ' . $self->ip_addr) unless $self_addr;
+
+  my $block_addr = $self->addr_block->NetAddr;
+  unless ($block_addr->contains($self_addr)) {
+    return 'blocknum '.$self->blocknum.' does not contain address '.$self->ip_addr;
+  }
+
+  my $router = $self->addr_block->router 
+    or return 'Cannot assign address from unallocated block:'.$self->addr_block->blocknum;
+  if(grep { $_->routernum == $router->routernum} $self->allowed_routers) {
+  } # do nothing
+  else {
+    return 'Router '.$router->routernum.' cannot provide svcpart '.$self->svcpart;
+  }
+
+  $self->SUPER::check;
+}
+
+=item NetAddr
+
+Returns a NetAddr::IP object containing the IP address of this service.  The netmask 
+is /32.
+
+=cut
+
+sub NetAddr {
+  my $self = shift;
+  return 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;
+
+  return qsearchs('addr_block', { blocknum => $self->blocknum });
+}
+
+=back
+
+=item allowed_routers
+
+Returns a list of allowed FS::router objects.
+
+=cut
+
+sub allowed_routers {
+  my $self = shift;
+
+  return map { $_->router } qsearch('part_svc_router', { svcpart => $self->svcpart });
+}
+
+=head1 BUGS
+
+The business with sb_field has been 'fixed', in a manner of speaking.
+
+=head1 SEE ALSO
+
+FS::svc_Common, FS::Record, FS::addr_block,
+FS::part_svc, schema.html from the base documentation.
+
+=cut
+
+1;
+
index b06d030..10d5d8f 100644 (file)
@@ -1,16 +1,13 @@
 package FS::svc_domain;
 
 use strict;
-use vars qw( @ISA $whois_hack $conf $smtpmachine
+use vars qw( @ISA $whois_hack $conf
   @defaultrecords $soadefaultttl $soaemail $soaexpire $soamachine
-  $soarefresh $soaretry $qshellmachine $nossh_hack 
+  $soarefresh $soaretry
 );
 use Carp;
-use Mail::Internet 1.44;
-use Mail::Header;
 use Date::Format;
 use Net::Whois 1.0;
-use Net::SSH;
 use FS::Record qw(fields qsearch qsearchs dbh);
 use FS::Conf;
 use FS::svc_Common;
@@ -27,8 +24,6 @@ use FS::queue;
 $FS::UID::callback{'FS::domain'} = sub { 
   $conf = new FS::Conf;
 
-  $smtpmachine = $conf->config('smtpmachine');
-
   @defaultrecords = $conf->config('defaultrecords');
   $soadefaultttl = $conf->config('soadefaultttl');
   $soaemail      = $conf->config('soaemail');
@@ -37,9 +32,6 @@ $FS::UID::callback{'FS::domain'} = sub {
   $soarefresh    = $conf->config('soarefresh');
   $soaretry      = $conf->config('soaretry');
 
-  $qshellmachine = $conf->exists('qmailmachines')
-                   ? $conf->config('shellmachine')
-                   : '';
 };
 
 =head1 NAME
@@ -120,21 +112,6 @@ If any records are defined in the I<defaultrecords> configuration file,
 appropriate records are added to the domain_record table (see
 L<FS::domain_record>).
 
-If a machine is defined in the I<shellmachine> configuration value, the
-I<qmailmachines> configuration file exists, and the I<catchall> field points
-to an an account with a home directory (see L<FS::svc_acct>), the command:
-
-  [ -e $dir/.qmail-$qdomain-defualt ] || {
-    touch $dir/.qmail-$qdomain-default;
-    chown $uid:$gid $dir/.qmail-$qdomain-default;
-  }
-
-is executed on shellmachine via ssh (see L<dot-qmail/"EXTENSION ADDRESSES">).
-This behaviour can be supressed by setting $FS::svc_domain::nossh_hack true.
-
-a machine is defined
-in the 
-
 =cut
 
 sub insert {
@@ -211,28 +188,6 @@ sub insert {
 
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
 
-  if ( $qshellmachine && $self->catchall && ! $nossh_hack ) {
-
-    my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->catchall } )
-      or warn "WARNING: inserted unknown catchall: ". $self->catchall;
-    if ( $svc_acct && $svc_acct->dir ) {
-      my $qdomain = $self->domain;
-      $qdomain =~ s/\./:/g; #see manpage for 'dot-qmail': EXTENSION ADDRESSES
-      my ( $uid, $gid, $dir ) = (
-        $svc_acct->uid,
-        $svc_acct->gid,
-        $svc_acct->dir,
-      );
-  
-    my $queue = new FS::queue {
-      'svcnum' => $self->svcnum,
-      'job'    => 'Net::SSH::ssh_cmd',
-    };
-    $error = $queue->insert("root\@$qshellmachine", "[ -e $dir/.qmail-$qdomain-default ] || { touch $dir/.qmail-$qdomain-default; chown $uid:$gid $dir/.qmail-$qdomain-default; }" );
-
-    }
-  }
-
   ''; #no error
 }
 
@@ -251,10 +206,6 @@ sub delete {
   return "Can't delete a domain which has accounts!"
     if qsearch( 'svc_acct', { 'domsvc' => $self->svcnum } );
 
-  return "Can't delete a domain with (svc_acct_sm) mail aliases!"
-    if defined( $FS::Record::dbdef->table('svc_acct_sm') )
-       && qsearch('svc_acct_sm', { 'domsvc' => $self->svcnum } );
-
   #return "Can't delete a domain with (domain_record) zone entries!"
   #  if qsearch('domain_record', { 'svcnum' => $self->svcnum } );
 
@@ -269,12 +220,6 @@ sub delete {
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
 
-  my $error = $self->SUPER::delete;
-  if ( $error ) {
-    $dbh->rollback if $oldAutoCommit;
-    return $error;
-  }
-
   foreach my $domain_record ( reverse $self->domain_record ) {
     my $error = $domain_record->delete;
     if ( $error ) {
@@ -282,6 +227,13 @@ sub delete {
       return $error;
     }
   }
+
+  my $error = $self->SUPER::delete;
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return $error;
+  }
+
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
 }
 
@@ -372,7 +324,7 @@ sub check {
   }
 
   #if ( $recref->{domain} =~ /^([\w\-\.]{1,22})\.(com|net|org|edu)$/ ) {
-  if ( $recref->{domain} =~ /^([\w\-]{1,22})\.(com|net|org|edu)$/ ) {
+  if ( $recref->{domain} =~ /^([\w\-]{1,63})\.(com|net|org|edu)$/ ) {
     $recref->{domain} = "$1.$2";
   # hmmmmmmmm.
   } elsif ( $whois_hack && $recref->{domain} =~ /^([\w\-\.]+)$/ ) {
@@ -385,10 +337,13 @@ sub check {
   $recref->{action} =~ /^(M|N)$/ or return "Illegal action";
   $recref->{action} = $1;
 
-  my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $recref->{catchall} } );
-  return "Unknown catchall" unless $svc_acct || ! $recref->{catchall};
+  if ( $recref->{catchall} ne '' ) {
+    my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $recref->{catchall} } );
+    return "Unknown catchall" unless $svc_acct;
+  }
 
-  $self->ut_textn('purpose');
+  $self->ut_textn('purpose')
+    or $self->SUPER::check;
 
 }
 
@@ -412,6 +367,15 @@ sub domain_record {
 
 }
 
+sub catchall_svc_acct {
+  my $self = shift;
+  if ( $self->catchall ) {
+    qsearchs( 'svc_acct', { 'svcnum' => $self->catchall } );
+  } else {
+    '';
+  }
+}
+
 =item whois
 
 Returns the Net::Whois::Domain object (see L<Net::Whois>) for this domain, or
@@ -448,14 +412,8 @@ sub submit_internic {
 
 =back
 
-=head1 VERSION
-
-$Id: svc_domain.pm,v 1.31 2002-06-10 02:52:48 ivan Exp $
-
 =head1 BUGS
 
-All BIND/DNS fields should be included (and exported).
-
 Delete doesn't send a registration template.
 
 All registries should be supported.
@@ -467,9 +425,8 @@ The $recref stuff in sub check should be cleaned up.
 =head1 SEE ALSO
 
 L<FS::svc_Common>, L<FS::Record>, L<FS::Conf>, L<FS::cust_svc>,
-L<FS::part_svc>, L<FS::cust_pkg>, L<Net::Whois>, L<ssh>,
-L<dot-qmail>, schema.html from the base documentation, config.html from the
-base documentation.
+L<FS::part_svc>, L<FS::cust_pkg>, L<Net::Whois>, schema.html from the base
+documentation, config.html from the base documentation.
 
 =cut
 
diff --git a/FS/FS/svc_external.pm b/FS/FS/svc_external.pm
new file mode 100644 (file)
index 0000000..fe4ea1d
--- /dev/null
@@ -0,0 +1,174 @@
+package FS::svc_external;
+
+use strict;
+use vars qw(@ISA); # $conf
+use FS::UID;
+#use FS::Record qw( qsearch qsearchs dbh);
+use FS::svc_Common;
+
+@ISA = qw( FS::svc_Common );
+
+#FS::UID::install_callback( sub {
+#  $conf = new FS::Conf;
+#};
+
+=head1 NAME
+
+FS::svc_external - Object methods for svc_external records
+
+=head1 SYNOPSIS
+
+  use FS::svc_external;
+
+  $record = new FS::svc_external \%hash;
+  $record = new FS::svc_external { 'column' => 'value' };
+
+  $error = $record->insert;
+
+  $error = $new_record->replace($old_record);
+
+  $error = $record->delete;
+
+  $error = $record->check;
+
+  $error = $record->suspend;
+
+  $error = $record->unsuspend;
+
+  $error = $record->cancel;
+
+=head1 DESCRIPTION
+
+An FS::svc_external object represents a externally tracked service.
+FS::svc_external inherits from FS::svc_Common.  The following fields are
+currently supported:
+
+=over 4
+
+=item svcnum - primary key
+
+=item id - unique number of external record
+
+=item title - for invoice line items
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new external service.  To add the external service 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<hash> method.
+
+=cut
+
+sub table { 'svc_external'; }
+
+=item insert
+
+Adds this external service to the database.  If there is an error, returns the
+error, otherwise returns false.
+
+The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be 
+defined.  An FS::cust_svc record will be created and inserted.
+
+=cut
+
+sub insert {
+  my $self = shift;
+  my $error;
+
+  $error = $self->SUPER::insert;
+  return $error if $error;
+
+  '';
+}
+
+=item delete
+
+Delete this record from the database.
+
+=cut
+
+sub delete {
+  my $self = shift;
+  my $error;
+
+  $error = $self->SUPER::delete;
+  return $error if $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
+
+sub replace {
+  my ( $new, $old ) = ( shift, shift );
+  my $error;
+
+  $error = $new->SUPER::replace($old);
+  return $error if $error;
+
+  '';
+}
+
+=item suspend
+
+Called by the suspend method of FS::cust_pkg (see L<FS::cust_pkg>).
+
+=item unsuspend
+
+Called by the unsuspend method of FS::cust_pkg (see L<FS::cust_pkg>).
+
+=item cancel
+
+Called by the cancel method of FS::cust_pkg (see L<FS::cust_pkg>).
+
+=item check
+
+Checks all fields to make sure this is a valid external service.  If there is
+an error, returns the error, otherwise returns false.  Called by the insert
+and repalce methods.
+
+=cut
+
+sub check {
+  my $self = shift;
+
+  my $x = $self->setfixed;
+  return $x unless ref($x);
+  my $part_svc = $x;
+
+  my $error = 
+    $self->ut_numbern('svcnum')
+    || $self->ut_number('id')
+    || $self->ut_textn('title')
+  ;
+
+  $self->SUPER::check;
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::svc_Common>, L<FS::Record>, L<FS::cust_svc>, L<FS::part_svc>,
+L<FS::cust_pkg>, schema.html from the base documentation.
+
+=cut
+
+1;
+
index 1c5b5c4..b9e8ff8 100644 (file)
@@ -1,9 +1,7 @@
 package FS::svc_forward;
 
 use strict;
-use vars qw( @ISA $nossh_hack $conf $shellmachine @qmailmachines
-             @vpopmailmachines );
-use Net::SSH qw(ssh);
+use vars qw( @ISA );
 use FS::Conf;
 use FS::Record qw( fields qsearch qsearchs dbh );
 use FS::svc_Common;
@@ -13,21 +11,6 @@ use FS::svc_domain;
 
 @ISA = qw( FS::svc_Common );
 
-#ask FS::UID to run this stuff for us later
-$FS::UID::callback{'FS::svc_forward'} = sub { 
-  $conf = new FS::Conf;
-  if ( $conf->exists('qmailmachines') ) {
-    $shellmachine = $conf->config('shellmachine')
-  } else {
-    $shellmachine = '';
-  }
-  if ( $conf->exists('vpopmailmachines') ) {
-    @vpopmailmachines = $conf->config('vpopmailmachines');
-  } else {
-    @vpopmailmachines = ();
-  }
-};
-
 =head1 NAME
 
 FS::svc_forward - Object methods for svc_forward records
@@ -64,9 +47,11 @@ inherits from FS::Record.  The following fields are currently supported:
 
 =item srcsvc - svcnum of the source of the forward (see L<FS::svc_acct>)
 
+=item src - literal source (username or full email address)
+
 =item dstsvc - svcnum of the destination of the forward (see L<FS::svc_acct>)
 
-=item dst - foreign destination (email address) - forward not local to freeside
+=item dst - literal destination (username or full email address)
 
 =back
 
@@ -91,17 +76,6 @@ the error, otherwise returns false.
 The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be 
 defined.  An FS::cust_svc record will be created and inserted.
 
-If the configuration value (see L<FS::Conf>) vpopmailmachines exists, then
-the command:
-
-  [ -d $vpopdir/domains/$domain/$source ] && {
-    echo "$destination" >> $vpopdir/domains/$domain/$username/.$qmail
-    chown $vpopuid:$vpopgid $vpopdir/domains/$domain/$username/.$qmail
-  }
-
-is executed on each vpopmailmachine via ssh (see the vpopmail documentation).
-This behaviour can be supressed by setting $FS::svc_forward::nossh_hack true.
-
 =cut
 
 sub insert {
@@ -128,32 +102,6 @@ sub insert {
     return $error;
   }
 
-  my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->srcsvc } );
-  my $username = $svc_acct->username;
-  my $domain = $svc_acct->domain;
-  my $destination;
-  if ($self->dstsvc) {
-    $destination = $self->dstsvc_acct->email;
-  } else {
-    $destination = $self->dst;
-  }
-    
-  foreach my $vpopmailmachine ( @vpopmailmachines ) {
-    my($machine, $vpopdir, $vpopuid, $vpopgid) = split(/\s+/, $vpopmailmachine);
-    my $queue = new FS::queue {
-      'svcnum' => $self->svcnum,
-      'job'    => 'Net::SSH::ssh_cmd',
-    };
-    # should be neater
-    my $error = $queue->insert("root\@$machine","[ -d $vpopdir/domains/$domain/$username ] && { echo \"$destination\" >> $vpopdir/domains/$domain/$username/.qmail; chown $vpopuid:$vpopgid $vpopdir/domains/$domain/$username/.qmail; }") 
-      unless $nossh_hack;
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "queueing job (transaction rolled back): $error";
-    }
-
-  }
-
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
   ''; #no error
 
@@ -166,19 +114,6 @@ returns the error, otherwise returns false.
 
 The corresponding FS::cust_svc record will be deleted as well.
 
-If the configuration value vpopmailmachines exists, then the command:
-
-  { sed -e '/^$destination/d' < 
-      $vpopdir/domains/$srcdomain/$srcusername/.qmail >
-      $vpopdir/domains/$srcdomain/$srcusername/.qmail.temp;
-    mv $vpopdir/domains/$srcdomain/$srcusername/.qmail.temp
-      $vpopdir/domains/$srcdomain/$srcusername/.qmail;
-    chown $vpopuid.$vpopgid $vpopdir/domains/$srcdomain/$srcusername/.qmail; }
-    
-
-is executed on each vpopmailmachine via ssh.  This behaviour can be supressed
-by setting $FS::svc_forward_nossh_hack true.
-
 =cut
 
 sub delete {
@@ -201,37 +136,6 @@ sub delete {
     return $error;
   }
 
-  my $svc_acct = $self->srcsvc_acct;
-  my $username = $svc_acct->username;
-  my $domain = $svc_acct->domain;
-  my $destination;
-  if ($self->dstsvc) {
-    $destination = $self->dstsvc_acct->email;
-  } else {
-    $destination = $self->dst;
-  }
-  foreach my $vpopmailmachine ( @vpopmailmachines ) {
-    my($machine, $vpopdir, $vpopuid, $vpopgid) =
-      split(/\s+/, $vpopmailmachine);
-    my $queue = new FS::queue { 'job' => 'Net::SSH::ssh_cmd' };
-    # should be neater
-    my $error = $queue->insert("root\@$machine",
-      "sed -e '/^$destination/d' " .
-        "< $vpopdir/domains/$domain/$username/.qmail" .
-        "> $vpopdir/domains/$domain/$username/.qmail.temp; " .
-      "mv $vpopdir/domains/$domain/$username/.qmail.temp " .
-        "$vpopdir/domains/$domain/$username/.qmail; " .
-      "chown $vpopuid.$vpopgid $vpopdir/domains/$domain/$username/.qmail;"
-    )
-      unless $nossh_hack;
-
-    if ($error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "queueing job (transaction rolled back): $error";
-    }
-
-  }
-
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
   '';
 }
@@ -242,29 +146,6 @@ sub delete {
 Replaces OLD_RECORD with this one in the database.  If there is an error,
 returns the error, otherwise returns false.
 
-If the configuration value vpopmailmachines exists, then the command:
-
-  { sed -e '/^$destination/d' < 
-      $vpopdir/domains/$srcdomain/$srcusername/.qmail >
-      $vpopdir/domains/$srcdomain/$srcusername/.qmail.temp;
-    mv $vpopdir/domains/$srcdomain/$srcusername/.qmail.temp
-      $vpopdir/domains/$srcdomain/$srcusername/.qmail; 
-    chown $vpopuid.$vpopgid $vpopdir/domains/$srcdomain/$srcusername/.qmail; }
-    
-
-is executed on each vpopmailmachine via ssh.  This behaviour can be supressed
-by setting $FS::svc_forward_nossh_hack true.
-
-Also, if the configuration value vpopmailmachines exists, then the command:
-
-  [ -d $vpopdir/domains/$domain/$source ] && {
-    echo "$destination" >> $vpopdir/domains/$domain/$username/.$qmail
-    chown $vpopuid:$vpopgid $vpopdir/domains/$domain/$username/.$qmail
-  }
-
-is executed on each vpopmailmachine via ssh.  This behaviour can be supressed
-by setting $FS::svc_forward_nossh_hack true.
-
 =cut
 
 sub replace {
@@ -295,66 +176,6 @@ sub replace {
     return $error;
   }
 
-  my $old_svc_acct = $old->srcsvc_acct;
-  my $old_username = $old_svc_acct->username;
-  my $old_domain = $old_svc_acct->domain;
-  my $destination;
-  if ($old->dstsvc) {
-    $destination = $old->dstsvc_acct->email;
-  } else {
-    $destination = $old->dst;
-  }
-  foreach my $vpopmailmachine ( @vpopmailmachines ) {
-    my($machine, $vpopdir, $vpopuid, $vpopgid) =
-      split(/\s+/, $vpopmailmachine);
-    my $queue = new FS::queue {
-      'svcnum' => $new->svcnum,
-      'job'    => 'Net::SSH::ssh_cmd',
-    };
-    # should be neater
-    my $error = $queue->insert("root\@$machine",
-      "sed -e '/^$destination/d' " .
-        "< $vpopdir/domains/$old_domain/$old_username/.qmail" .
-        "> $vpopdir/domains/$old_domain/$old_username/.qmail.temp; " .
-      "mv $vpopdir/domains/$old_domain/$old_username/.qmail.temp " .
-        "$vpopdir/domains/$old_domain/$old_username/.qmail; " .
-      "chown $vpopuid.$vpopgid " .
-        "$vpopdir/domains/$old_domain/$old_username/.qmail;"
-    )
-      unless $nossh_hack;
-
-    if ( $error ) {
-       $dbh->rollback if $oldAutoCommit;
-       return "queueing job (transaction rolled back): $error";
-    }
-  }
-
-  #false laziness with stuff in insert, should subroutine
-  my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $new->srcsvc } );
-  my $username = $svc_acct->username;
-  my $domain = $svc_acct->domain;
-  if ($new->dstsvc) {
-    $destination = $new->dstsvc_acct->email;
-  } else {
-    $destination = $new->dst;
-  }
-  
-  foreach my $vpopmailmachine ( @vpopmailmachines ) {
-    my($machine, $vpopdir, $vpopuid, $vpopgid) = split(/\s+/, $vpopmailmachine);
-    my $queue = new FS::queue {
-      'svcnum' => $new->svcnum,
-      'job'    => 'Net::SSH::ssh_cmd',
-    };
-    # should be neater
-    my $error = $queue->insert("root\@$machine","[ -d $vpopdir/domains/$domain/$username ] && { echo \"$destination\" >> $vpopdir/domains/$domain/$username/.qmail; chown $vpopuid:$vpopgid $vpopdir/domains/$domain/$username/.qmail; }") 
-      unless $nossh_hack;
-    if ( $error ) {
-       $dbh->rollback if $oldAutoCommit;
-       return "queueing job (transaction rolled back): $error";
-    }
-  }
-  #end subroutinable bits
-
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
   '';
 }
@@ -395,12 +216,19 @@ sub check {
   #my $part_svc = $x;
 
   my $error = $self->ut_numbern('svcnum')
-              || $self->ut_number('srcsvc')
+              || $self->ut_numbern('srcsvc')
               || $self->ut_numbern('dstsvc')
   ;
   return $error if $error;
 
-  return "Unknown srcsvc" unless $self->srcsvc_acct;
+  return "Both srcsvc and src were defined; only one can be specified"
+    if $self->srcsvc && $self->src;
+
+  return "one of srcsvc or src is required"
+    unless $self->srcsvc || $self->src;
+
+  return "Unknown srcsvc: ". $self->srcsvc
+    unless ! $self->srcsvc || $self->srcsvc_acct;
 
   return "Both dstsvc and dst were defined; only one can be specified"
     if $self->dstsvc && $self->dst;
@@ -408,26 +236,35 @@ sub check {
   return "one of dstsvc or dst is required"
     unless $self->dstsvc || $self->dst;
 
-  #return "Unknown dstsvc: $dstsvc" unless $self->dstsvc_acct || ! $self->dstsvc;
-  return "Unknown dstsvc"
-    unless qsearchs('svc_acct', { 'svcnum' => $self->dstsvc } )
-           || ! $self->dstsvc;
+  return "Unknown dstsvc: ". $self->dstsvc
+    unless ! $self->dstsvc || $self->dstsvc_acct;
+  #return "Unknown dstsvc"
+  #  unless qsearchs('svc_acct', { 'svcnum' => $self->dstsvc } )
+  #         || ! $self->dstsvc;
 
+  if ( $self->src ) {
+    $self->src =~ /^([\w\.\-\&]*)(\@([\w\-]+\.)+\w+)?$/
+       or return "Illegal src: ". $self->dst;
+    $self->src("$1$2");
+  } else {
+    $self->src('');
+  }
 
   if ( $self->dst ) {
-    $self->dst =~ /^([\w\.\-]+)\@(([\w\-]+\.)+\w+)$/
+    $self->dst =~ /^([\w\.\-\&]*)(\@([\w\-]+\.)+\w+)?$/
        or return "Illegal dst: ". $self->dst;
-    $self->dst("$1\@$2");
+    $self->dst("$1$2");
   } else {
     $self->dst('');
   }
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =item srcsvc_acct
 
-Returns the FS::svc_acct object referenced by the srcsvc column.
+Returns the FS::svc_acct object referenced by the srcsvc column, or false for
+literally specified forwards.
 
 =cut
 
@@ -439,7 +276,7 @@ sub srcsvc_acct {
 =item dstsvc_acct
 
 Returns the FS::svc_acct object referenced by the srcsvc column, or false for
-forwards not local to freeside.
+literally specified forwards.
 
 =cut
 
@@ -450,19 +287,12 @@ sub dstsvc_acct {
 
 =back
 
-=head1 VERSION
-
-$Id: svc_forward.pm,v 1.12 2002-05-31 17:50:37 ivan Exp $
-
 =head1 BUGS
 
-The remote commands should be configurable.
-
 =head1 SEE ALSO
 
 L<FS::Record>, L<FS::Conf>, L<FS::cust_svc>, L<FS::part_svc>, L<FS::cust_pkg>,
-L<FS::svc_acct>, L<FS::svc_domain>, L<Net::SSH>, L<ssh>, L<dot-qmail>,
-schema.html from the base documentation.
+L<FS::svc_acct>, L<FS::svc_domain>, schema.html from the base documentation.
 
 =cut
 
index d7a42c8..7e89083 100644 (file)
@@ -234,7 +234,8 @@ sub check {
   return "Unknown usersvc (svc_acct.svcnum): ". $self->usersvc
     unless qsearchs('svc_acct', { 'svcnum' => $self->usersvc } );
 
-  ''; #no error
+  $self->SUPER::check;
+
 }
 
 =item domain_record
index 8e0d4ef..5b3b11c 100644 (file)
@@ -91,14 +91,27 @@ sub check {
   return "Unknown pkgpart"
     unless qsearchs( 'part_pkg', { 'pkgpart' => $self->pkgpart } );
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
+=item part_pkg
+
+Returns the FS::part_pkg object associated with this record.
+
+=cut
+
+sub part_pkg {
+  my $self = shift;
+  qsearchs( 'part_pkg', { 'pkgpart' => $self->pkgpart } );
+}
+
+=cut
+
 =back
 
 =head1 VERSION
 
-$Id: type_pkgs.pm,v 1.1 1999-08-04 09:03:53 ivan Exp $
+$Id: type_pkgs.pm,v 1.3 2003-08-05 00:20:48 khoff Exp $
 
 =head1 BUGS
 
index 8355e40..3cbf0e9 100644 (file)
@@ -3,20 +3,30 @@ MANIFEST
 MANIFEST.SKIP
 Makefile.PL
 README
+bin/freeside-addoutsource
+bin/freeside-addoutsourceuser
+bin/freeside-adduser
+bin/freeside-apply-credits
 bin/freeside-bill
+bin/freeside-cc-receipts-report
+bin/freeside-count-active-customers
+bin/freeside-credit-report
 bin/freeside-daily
+bin/freeside-deloutsource
+bin/freeside-deloutsourceuser
+bin/freeside-deluser
 bin/freeside-email
+bin/freeside-expiration-alerter
 bin/freeside-queued
-bin/freeside-apply-credits
-bin/freeside-adduser
+bin/freeside-radgroup
+bin/freeside-reexport
+bin/freeside-selfservice-server
 bin/freeside-setinvoice
-bin/freeside-overdue
-bin/freeside-receivables-report
+bin/freeside-setup
+bin/freeside-sqlradius-radacctd
+bin/freeside-sqlradius-reset
+bin/freeside-sqlradius-seconds
 bin/freeside-tax-report
-bin/freeside-cc-receipts-report
-bin/freeside-credit-report
-bin/freeside-expiration-alerter
-bin/freeside-reexport
 FS.pm
 FS/CGI.pm
 FS/InitHandler.pm
@@ -25,6 +35,7 @@ FS/ClientAPI/passwd.pm
 FS/ClientAPI/MyAccount.pm
 FS/Conf.pm
 FS/ConfItem.pm
+FS/Misc.pm
 FS/Record.pm
 FS/SearchCache.pm
 FS/UI/Base.pm
@@ -33,10 +44,12 @@ FS/UI/Gtk.pm
 FS/UI/agent.pm
 FS/UID.pm
 FS/Msgcat.pm
+FS/acct_snarf.pm
 FS/agent.pm
 FS/agent_type.pm
 FS/cust_bill.pm
 FS/cust_bill_pkg.pm
+FS/cust_bill_pkg_detail.pm
 FS/cust_credit.pm
 FS/cust_credit_bill.pm
 FS/cust_main.pm
@@ -54,13 +67,19 @@ FS/part_bill_event.pm
 FS/export_svc.pm
 FS/part_export.pm
 FS/part_export_option.pm
+FS/part_export/apache.pm
 FS/part_export/bind.pm
 FS/part_export/bind_slave.pm
 FS/part_export/bsdshell.pm
+FS/part_export/communigate_pro.pm
+FS/part_export/communigate_pro_singledomain.pm
 FS/part_export/cp.pm
 FS/part_export/cyrus.pm
+FS/part_export/domain_shellcommands.pm
+FS/part_export/forward_shellcommands.pm
 FS/part_export/http.pm
 FS/part_export/infostreet.pm
+FS/part_export/ldap.pm
 FS/part_export/null.pm
 FS/part_export/shellcommands.pm
 FS/part_export/shellcommands_withdomain.pm
@@ -75,12 +94,16 @@ FS/part_pop_local.pm
 FS/part_referral.pm
 FS/part_svc.pm
 FS/part_svc_column.pm
+FS/part_svc_router.pm
+FS/part_virtual_field.pm
 FS/pkg_svc.pm
 FS/svc_Common.pm
 FS/svc_acct.pm
 FS/svc_acct_pop.pm
-FS/svc_acct_sm.pm
+FS/svc_broadband.pm
 FS/svc_domain.pm
+FS/svc_external.pm
+FS/router.pm
 FS/type_pkgs.pm
 FS/nas.pm
 FS/port.pm
@@ -103,13 +126,16 @@ t/InitHandler.t
 t/ClientAPI.t
 t/Conf.t
 t/ConfItem.t
+t/Misc.t
 t/Record.t
 t/UID.t
 t/Msgcat.t
+t/SearchCache.t
 t/cust_bill.t
 t/cust_bill_event.t
 t/cust_bill_pay.t
 t/cust_bill_pkg.t
+t/cust_bill_pkg_detail.t
 t/cust_credit.t
 t/cust_credit_bill.t
 t/cust_credit_refund.t
@@ -121,6 +147,7 @@ t/cust_pay_batch.t
 t/cust_pkg.t
 t/cust_refund.t
 t/cust_svc.t
+t/cust_tax_exempt.t
 t/domain_record.t
 t/nas.t
 t/part_bill_event.t
@@ -132,8 +159,11 @@ t/part_export-bind_slave.t
 t/part_export-bsdshell.t
 t/part_export-cp.t
 t/part_export-cyrus.t
+t/part_export-domain_shellcommands.t
+t/part_export-forward_shellcommands.t
 t/part_export-http.t
 t/part_export-infostreet.t
+t/part_export-ldap.t
 t/part_export-null.t
 t/part_export-shellcommands.t
 t/part_export-shellcommands_withdomain.t
@@ -155,14 +185,15 @@ t/radius_usergroup.t
 t/session.t
 t/svc_acct.t
 t/svc_acct_pop.t
-t/svc_acct_sm.t
+t/svc_broadband.t
 t/svc_Common.t
 t/svc_domain.t
+t/svc_external.t
 t/svc_forward.t
 t/svc_www.t
 t/type_pkgs.t
 t/queue.t
 t/queue_arg.t
+t/queue_depend.t
 t/msgcat.t
 t/raddb.t
-t/cust_tax_exempt.t
index ab4c228..1647f8e 100644 (file)
@@ -5,4 +5,6 @@ WriteMakefile(
     'NAME'        => 'FS',
     'VERSION_FROM' => 'FS.pm', # finds $VERSION
     'EXE_FILES'    => [ glob 'bin/*' ],
+    'INSTALLSCRIPT'  => '/usr/local/bin',
+    'INSTALLSITEBIN' => '/usr/local/bin',
 );
diff --git a/FS/bin/freeside-addoutsource b/FS/bin/freeside-addoutsource
new file mode 100644 (file)
index 0000000..5cec17f
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+domain=$1
+
+createdb $domain && \
+\
+mkdir /usr/local/etc/freeside/conf.DBI:Pg:host=localhost\;dbname=$domain && \
+\
+chown freeside /usr/local/etc/freeside/conf.DBI:Pg:host=localhost\;dbname=$domain && \
+\
+cp /home/ivan/freeside/conf/[a-z]* /usr/local/etc/freeside/conf.DBI:Pg:host=localhost\;dbname=$domain && \
+\
+touch /usr/local/etc/freeside/conf.DBI:Pg:host=localhost\;dbname=$domain/secrets && \
+\
+chown freeside /usr/local/etc/freeside/conf.DBI:Pg:host=localhost\;dbname=$domain/secrets && \
+\
+chmod 600 /usr/local/etc/freeside/conf.DBI:Pg:host=localhost\;dbname=$domain/secrets && \
+\
+echo -e "DBI:Pg:host=localhost;dbname=$domain\nfreeside\n" >/usr/local/etc/freeside/conf.DBI:Pg:host=localhost\;dbname=$domain/secrets && \
+\
+mkdir /usr/local/etc/freeside/counters.DBI:Pg:host=localhost\;dbname=$domain && \
+mkdir /usr/local/etc/freeside/cache.DBI:Pg:host=localhost\;dbname=$domain && \
+mkdir /usr/local/etc/freeside/export.DBI:Pg:host=localhost\;dbname=$domain
+
diff --git a/FS/bin/freeside-addoutsourceuser b/FS/bin/freeside-addoutsourceuser
new file mode 100644 (file)
index 0000000..abb515b
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+username=$1
+domain=$2
+password=$3
+
+freeside-adduser -h /usr/local/etc/freeside/htpasswd \
+                 -s conf.DBI:Pg:host=localhost\;dbname=$domain/secrets \
+                 -b \
+                 $username $password 2>/dev/null
+
+[ -e /usr/local/etc/freeside/dbdef.DBI:Pg:host=localhost\;dbname=$domain ] \
+ || ( freeside-setup -s $username 2>/dev/null; \
+      /home/ivan/freeside/bin/populate-msgcat $username 2>/dev/null )
+
index 9d42463..c3ee05b 100644 (file)
@@ -1,33 +1,37 @@
 #!/usr/bin/perl -w
 #
-# $Id: freeside-adduser,v 1.4 2002-02-06 14:58:05 ivan Exp $
+# $Id: freeside-adduser,v 1.8 2002-09-27 05:36:29 ivan Exp $
 
 use strict;
-use vars qw($opt_h $opt_c $opt_s);
+use vars qw($opt_h $opt_b $opt_c $opt_s);
+use Fcntl qw(:flock);
 use Getopt::Std;
 
 my $FREESIDE_CONF = "/usr/local/etc/freeside";
 
-getopts("ch:s:");
+getopts("bch:s:");
 die &usage if $opt_c && ! $opt_h;
 my $user = shift or die &usage;
 
 if ( $opt_h ) {
   my @args = ( 'htpasswd' );
+  push @args, '-b' if $opt_b;
   push @args, '-c' if $opt_c;
   push @args, $opt_h, $user;
+  push @args, shift if $opt_b;
   system(@args) == 0 or die "htpasswd failed: $?";
 }
 
 my $secretfile = $opt_s || 'secrets';
 
 open(MAPSECRETS,">>$FREESIDE_CONF/mapsecrets")
-  or die "can't open $FREESIDE_CONF/mapsecrets: $!";
+  and flock(MAPSECRETS,LOCK_EX)
+    or die "can't open $FREESIDE_CONF/mapsecrets: $!";
 print MAPSECRETS "$user $secretfile\n";
 close MAPSECRETS or die "can't close $FREESIDE_CONF/mapsecrets: $!";
 
 sub usage {
-  die "Usage:\n\n  freeside-adduser [ -h htpasswd_file [ -c ] ] [ -s secretfile ] username"
+  die "Usage:\n\n  freeside-adduser [ -h htpasswd_file [ -c ] [ -b ] ] [ -s secretfile ] username"
 }
 
 =head1 NAME
@@ -45,13 +49,15 @@ sales/tech folks) to the web interface, not for adding customer accounts.
 
   -h: Also call htpasswd for this user with the given filename
 
-  -c: Passed to htpasswd
+  -c: Passed to htpasswd(1)
 
   -s: Specify an alternate secret file
 
+  -b: same as htpasswd(1), probably insecure, not recommended
+
 =head1 SEE ALSO
 
-L<htpasswd>, base Freeside documentation
+L<htpasswd>(1), base Freeside documentation
 
 =cut
 
index 06e3aba..136851a 100755 (executable)
@@ -206,7 +206,7 @@ if($email && $opt_m)
 # subroutines
 sub untaint_argv {
   foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
-    $ARGV[$_] =~ /^([\w\-\/ :]*)$/ || die "Illegal argument \"$ARGV[$_]\"";
+    $ARGV[$_] =~ /^([\w\-\/ :\.]*)$/ || die "Illegal argument \"$ARGV[$_]\"";
     $ARGV[$_]=$1;
   }
 }
@@ -245,7 +245,7 @@ user: From the mapsecrets file - see config.html from the base documentation
 
 =head1 VERSION
 
-$Id: freeside-cc-receipts-report,v 1.4 2002-03-07 19:50:23 jeff Exp $
+$Id: freeside-cc-receipts-report,v 1.5 2002-09-09 22:57:34 ivan Exp $
 
 =head1 BUGS
 
diff --git a/FS/bin/freeside-count-active-customers b/FS/bin/freeside-count-active-customers
new file mode 100755 (executable)
index 0000000..759085a
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+domain=$1
+
+echo "\t
+select count(*) from cust_main where 
+          0 < ( SELECT COUNT(*) FROM cust_pkg
+                       WHERE cust_pkg.custnum = cust_main.custnum
+                         AND ( cust_pkg.cancel IS NULL
+                               OR cust_pkg.cancel = 0
+                             )
+                   )
+            OR 0 = ( SELECT COUNT(*) FROM cust_pkg
+                       WHERE cust_pkg.custnum = cust_main.custnum
+                   );
+" | psql -U freeside -q $domain | head -1
+
index 7699daf..410dabe 100755 (executable)
@@ -160,7 +160,7 @@ if($email && $opt_m)
 # subroutines
 sub untaint_argv {
   foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
-    $ARGV[$_] =~ /^([\w\-\/ :]*)$/ || die "Illegal argument \"$ARGV[$_]\"";
+    $ARGV[$_] =~ /^([\w\-\/ :\.]*)$/ || die "Illegal argument \"$ARGV[$_]\"";
     $ARGV[$_]=$1;
   }
 }
@@ -199,7 +199,7 @@ user: From the mapsecrets file - see config.html from the base documentation
 
 =head1 VERSION
 
-$Id: freeside-credit-report,v 1.4 2002-03-07 19:50:24 jeff Exp $
+$Id: freeside-credit-report,v 1.5 2002-09-09 22:57:34 ivan Exp $
 
 =head1 BUGS
 
index 142b0c7..5fb9666 100755 (executable)
@@ -4,50 +4,81 @@ use strict;
 use Fcntl qw(:flock);
 use Date::Parse;
 use Getopt::Std;
-use FS::UID qw(adminsuidsetup driver_name dbh);
+use FS::UID qw(adminsuidsetup driver_name dbh datasrc);
 use FS::Record qw(qsearch qsearchs);
+use FS::Conf;
 use FS::cust_main;
 
 &untaint_argv; #what it sounds like  (eww)
-use vars qw($opt_d $opt_v);
-getopts("d:v");
+use vars qw($opt_d $opt_v $opt_p $opt_s $opt_y);
+getopts("p:d:vsy:");
 my $user = shift or die &usage;
 
 adminsuidsetup $user;
 
 $FS::cust_main::Debug = 1 if $opt_v;
 
+my %search;
+$search{'payby'} = $opt_p if $opt_p;
+
 my @cust_main = @ARGV
-  ? map { qsearchs('cust_main', { custnum => $_ } ) } @ARGV
-  : qsearch('cust_main', {} )
+  ? map { qsearchs('cust_main', { custnum => $_, %search } ) } @ARGV
+  : qsearch('cust_main', \%search )
 ;
 
 #we're at now now (and later).
 my($time)= $opt_d ? str2time($opt_d) : $^T;
+$time += $opt_y * 86400 if $opt_y;
 
 my($cust_main,%saw);
 foreach $cust_main ( @cust_main ) {
 
-  my $error;
+  # $^T not $time because -d is for pre-printing invoices
+  foreach my $cust_pkg (
+    grep { $_->expire && $_->expire <= $^T } $cust_main->ncancelled_pkgs
+  ) {
+    my $error = $cust_pkg->cancel;
+    warn "Error cancelling expired pkg ". $cust_pkg->pkgnum. " for custnum ".
+         $cust_main->custnum. ": $error"
+      if $error;
+  }
 
-  $error = $cust_main->bill( 'time' => $time );
+  my $error = $cust_main->bill( 'time'    => $time,
+                                'resetup' => $opt_s, );
   warn "Error billing, custnum ". $cust_main->custnum. ": $error" if $error;
 
   $cust_main->apply_payments;
   $cust_main->apply_credits;
 
-  $error=$cust_main->collect( 'invoice_time' => $time );
+  $error = $cust_main->collect( 'invoice_time' => $time );
   warn "Error collecting, custnum". $cust_main->custnum. ": $error" if $error;
 
 }
 
 if ( driver_name eq 'Pg' ) {
+  dbh->{AutoCommit} = 1; #so we can vacuum
   foreach my $statement ( 'vacuum', 'vacuum analyze' ) {
     my $sth = dbh->prepare($statement) or die dbh->errstr;
     $sth->execute or die $sth->errstr;
   }
 }
 
+#local hack
+my $conf = new FS::Conf;
+my $dest = $conf->config('dump-scpdest');
+if ( $dest ) {
+  datasrc =~ /dbname=([\w\.]+)$/ or die "unparsable datasrc ". datasrc;
+  my $database = $1;
+  eval "use Net::SCP qw(scp);";
+  if ( driver_name eq 'Pg' ) {
+    system("pg_dump $database >/var/tmp/$database.sql")
+  } else {
+    die "database dumps not yet supported for ". driver_name;
+  }
+  scp("/var/tmp/$database.sql", $dest);
+  unlink "/var/tmp/$database.sql" or die $!;
+}
+
 # subroutines
 
 sub untaint_argv {
@@ -69,7 +100,7 @@ freeside-daily - Run daily billing and invoice collection events.
 
 =head1 SYNOPSIS
 
-  freeside-daily [ -d 'date' ] user [ custnum custnum ... ]
+  freeside-daily [ -d 'date' ] [ -y days ] [ -p 'payby' ] [ -s ] [ -v ] user [ custnum custnum ... ]
 
 =head1 DESCRIPTION
 
@@ -84,6 +115,17 @@ the bill and collect methods of a cust_main object.  See L<FS::cust_main>.
   -d: Pretend it's 'date'.  Date is in any format Date::Parse is happy with,
       but be careful.
 
+  -y: In addition to -d, which specifies an absolute date, the -y switch
+      specifies an offset, in days.  For example, "-y 15" would increment the
+      "pretend date" 15 days from whatever was specified by the -d switch
+      (or now, if no -d switch was given).
+
+  -p: Only process customers with the specified payby (I<CARD>, I<DCRD>, I<CHEK>, I<DCHK>, I<BILL>, I<COMP>, I<LECB>)
+
+  -s: re-charge setup fees
+
+  -v: enable debugging
+
 user: From the mapsecrets file - see config.html from the base documentation
 
 custnum: if one or more customer numbers are specified, only bills those
diff --git a/FS/bin/freeside-deloutsource b/FS/bin/freeside-deloutsource
new file mode 100644 (file)
index 0000000..5618535
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+domain=$1
+
+dropdb $domain && \
+rm -rf /usr/local/etc/freeside/conf.DBI:Pg:host=localhost\;dbname=$domain && \
+rm -rf /usr/local/etc/freeside/counters.DBI:Pg:host=localhost\;dbname=$domain && \
+rm -rf /usr/local/etc/freeside/cache.DBI:Pg:host=localhost\;dbname=$domain && \
+rm -rf /usr/local/etc/freeside/export.DBI:Pg:host=localhost\;dbname=$domain && \
+rm /usr/local/etc/freeside/dbdef.DBI:Pg:host=localhost\;dbname=$domain
+
diff --git a/FS/bin/freeside-deloutsourceuser b/FS/bin/freeside-deloutsourceuser
new file mode 100644 (file)
index 0000000..96871e5
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+username=$1
+
+freeside-deluser -h /usr/local/etc/freeside/htpasswd $username 2>/dev/null
+
diff --git a/FS/bin/freeside-deluser b/FS/bin/freeside-deluser
new file mode 100644 (file)
index 0000000..57d6ce1
--- /dev/null
@@ -0,0 +1,64 @@
+#!/usr/bin/perl -w
+
+use strict;
+use vars qw($opt_h);
+use Fcntl qw(:flock);
+use Getopt::Std;
+
+my $FREESIDE_CONF = "/usr/local/etc/freeside";
+
+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 (<HTPASSWD>) {
+    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 (<MAPSECRETS>) {
+  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<freeside-adduser>, L<htpasswd>(1), base Freeside documentation
+
+=cut
+
index c7ff411..400dc2a 100755 (executable)
@@ -12,11 +12,9 @@ my $user = shift or die &usage;
 adminsuidsetup $user;
 
 my $conf = new FS::Conf;
-my $domain = $conf->config('domain');
 
 my @svc_acct = qsearch('svc_acct', {});
-my @usernames = map $_->username, @svc_acct;
-my @emails = map "$_\@$domain", @usernames;
+my @emails = map $_->email, @svc_acct;
 
 print join("\n", @emails), "\n";
 
@@ -51,7 +49,7 @@ user: From the mapsecrets file - see config.html from the base documentation
 
 =head1 VERSION
 
-$Id: freeside-email,v 1.1 2001-05-15 07:52:34 ivan Exp $
+$Id: freeside-email,v 1.2 2002-09-18 22:50:44 ivan Exp $
 
 =head1 BUGS
 
index ee3c1fb..691fd3a 100755 (executable)
@@ -80,22 +80,24 @@ $alerter->compile() or die "can't compile template:  Text::Template::ERROR";
 # Now I can start looping
 foreach my $customer (@customers)
 {
+  my $paydate = $customer->getfield('paydate');
+  next if $paydate =~ /^\s*$/; #skip empty expiration dates
+
   my $custnum = $customer->getfield('custnum');
   my $first = $customer->getfield('first');
   my $last = $customer->getfield('last');
   my $company = $customer->getfield('company');
   my $payby = $customer->getfield('payby');
   my $payinfo = $customer->getfield('payinfo');
-  my $paydate = $customer->getfield('paydate');
   my $daytime = $customer->getfield('daytime');
   my $night = $customer->getfield('night');
-       
+
   my ($payyear,$paymonth,$payday) = split (/-/,$paydate);
 
   my $expire_time = timelocal(0,0,0,$payday,--$paymonth,$payyear);
 
   #credit cards expire at the end of the month/year of their exp date
-  if ($payby eq 'CARD') {
+  if ($payby eq 'CARD' || $payby eq 'DCRD') {
     ($paymonth < 11) ? $paymonth++ : ($paymonth=0, $payyear++);
     $expire_time = timelocal(0,0,0,$payday,$paymonth,$payyear);
     $expire_time--;
@@ -125,7 +127,7 @@ foreach my $customer (@customers)
         $FS::alerter::_template::first = $first;
         $FS::alerter::_template::last = $last;
         $FS::alerter::_template::company = $company;
-        if ($payby eq 'CARD') {
+        if ($payby eq 'CARD' || $payby eq 'DCRD') {
           $FS::alerter::_template::payby = "credit card (" .
             substr($payinfo, 0, 2) . "xxxxxxxxxx" .
             substr($payinfo, -4) . ")";
@@ -200,7 +202,7 @@ user: From the mapsecrets file - see config.html from the base documentation
 
 =head1 VERSION
 
-$Id: freeside-expiration-alerter,v 1.3 2002-04-16 09:38:19 ivan Exp $
+$Id: freeside-expiration-alerter,v 1.5 2003-04-21 20:53:57 ivan Exp $
 
 =head1 BUGS
 
diff --git a/FS/bin/freeside-overdue b/FS/bin/freeside-overdue
deleted file mode 100755 (executable)
index 116245f..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict;
-use vars qw( $days_to_pay $cust_main $cust_pkg 
-             $cust_svc $svc_acct );
-use Getopt::Std;
-use FS::cust_main;
-use FS::cust_pkg;
-use FS::cust_svc;
-use FS::svc_acct;
-use FS::Record qw(qsearch qsearchs);
-use FS::UID qw(adminsuidsetup);
-
-&untaint_argv;
-my %opt;
-getopts('ed:qpl:scbyoi', \%opt);
-my $user = shift or die &usage;
-
-adminsuidsetup $user;
-
-my $now = time; #eventually take a time option like freeside-bill
-my ($sec,$min,$hour,$mday,$mon,$year) =
-  (localtime($now) )[0,1,2,3,4,5];
-$mon++;
-$year += 1900;
-
-foreach $cust_main ( qsearch('cust_main',{} ) ) {
-
-  my ( $eyear, $emon, $eday ) = ( 2037, 12, 31 );
-  if ( $cust_main->paydate =~ /^(\d{4})\-(\d{1,2})\-(\d{1,2})$/
-       && $cust_main->payby eq 'BILL') {
-    ( $eyear, $emon, $eday ) = ( $1, $2, $3 );
-  }
-
-  if ( ( $opt{d}
-           && $cust_main->balance_date(time - $opt{d} * 86400) > 0
-           && qsearchs( 'cust_pkg', { 'custnum' => $cust_main->custnum,
-                                      'susp' => "" } ) )
-       || ( $opt{e}
-            && $cust_main->payby eq 'BILL'
-            && ( $eyear < $year
-                 || ( $eyear == $year && $emon < $mon ) ) )
-  ) { 
-
-    unless ( $opt{q} ) {
-      print $cust_main->custnum, "\t",
-            $cust_main->last, "\t", $cust_main->first, "\t",
-            $cust_main->balance_date(time-$opt{d} * 86400);
-    }
-
-    if ( $opt{p} && ! grep { $_ eq 'POST' } $cust_main->invoicing_list ) {
-      print "\n\tAdding postal invoicing" unless $opt{q};
-      my @invoicing_list = $cust_main->invoicing_list;
-      push @invoicing_list, 'POST';
-      $cust_main->invoicing_list(\@invoicing_list);
-    }
-
-    if ( $opt{l} ) {
-      print "\n\tCharging late fee of \$$opt{l}" unless $opt{q};
-      my $error = $cust_main->charge($opt{l}, 'Late fee');
-      # comment or plandata with info so we don't redo the same late fee every
-      # day
-    }
-
-    foreach $cust_pkg ( qsearch( 'cust_pkg', 
-                                 { 'custnum' => $cust_main->custnum } ) ) {
-
-      if ($opt{s}) {
-        print "\n\tSuspending pkgnum " . $cust_pkg->pkgnum unless $opt{q};
-        $cust_pkg->suspend;
-      }
-
-      if ($opt{c}) {
-        print "\n\tCancelling pkgnum " . $cust_pkg->pkgnum unless $opt{q};
-        $cust_pkg->cancel;
-      }
-      
-    }
-
-    if ( $opt{b} ) {
-      print "\n\tBilling" unless $opt{q};
-      my $error = $cust_main->bill('time'=>$now);
-      warn "Error billing,  customer #" . $cust_main->custnum . 
-        ":" . $error if $error;
-    }
-
-    if ( $opt{y} ) {
-      print "\n\tApplying outstanding payments and credits" unless $opt{q};
-      $cust_main->apply_payments;
-      $cust_main->apply_credits;
-    }
-
-    if ( $opt{o} ) {
-      print "\n\tCollecting" unless $opt{q};
-      my $error = $cust_main->collect(
-        'invoice_time' => $now,
-        'batch_card'   => $opt{i} ? 'no' : 'yes',
-        'force_print'  => 'yes',
-      );
-      warn "Error collecting from customer #" . $cust_main->custnum.  ":$error"
-        if $error;
-    }
-
-    print "\n" unless $opt{q};
-
-  }
-
-}
-
-sub untaint_argv {
-  foreach $_ ( $[ .. $#ARGV ) { 
-    $ARGV[$_] =~ /^([\w\-\/\.]*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
-    $ARGV[$_]=$1;
-  }
-}
-
-sub usage {
-  die "Usage:\n\n    freeside-overdue [ -e ] [ -d days ] [ -q ] [ -p ] [ -l amount ] [ -s ] [ -c ] [ -b ] [ -y ] [ -o [ -i ] ] user\n";
-}
-
-
-=head1 NAME
-
-freeside-overdue - Perform actions on overdue and/or expired accounts.
-
-=head1 SYNOPSIS
-
-  freeside-overdue [ -e ] [ -d days ] [ -q ] [ -p ] [ -l amount ] [ -s ] [ -c ] [ -b ] [ -y ] [ -o [ -i ] ] user
-
-=head1 DESCRIPTION
-
-This script is deprecated in 1.4.0.  You should use freeside-daily and invoice
-events instead.
-
-Performs actions on overdue and/or expired accounts.
-
-Selection options (at least one selection option is required):
-
-  -d:  Customers with a balance due on invoices older than the supplied number
-       of days.  Requires an integer argument.
-
-  -e:  Customers with a billing expiration date in the past.
-
-Action options: 
-
-  -q:  Be quiet (by default, selected accounts are printed).
-
-  -p:  Add postal invoicing to the relevant customers.
-
-  -l:  Add a charge of the given amount to the relevant customers.
-
-  -s:  Suspend accounts.
-
-  -c:  Cancel accounts.
-
-  -b:  Bill customers (create invoices)
-
-  -y:  Apply unapplied payments and credits
-
-  -o:  Collect from customers (charge cards, print invoices)
-
-    -i:  real-time billing (as opposed to batch billing).  only relevant
-         for credit cards.
-
-  user: From the mapsecrets file - see config.html from the base documentation
-
-=head1 CRONTAB
-
-Example crontab entries:
-
-# suspend expired accounts
-20 4 * * * freeside-overdue -e -s user
-
-# quietly add postal invoicing to customers over 30 days past due
-20 4 * * * freeside-overdue -d 30 -p -q user
-
-# suspend accounts and charge a $10.23 fee for customers over 60 days past due
-20 4 * * * freeside-overdue -d 60 -s -l 10.23 user
-
-# cancel accounts over 90 days past due
-20 4 * * * freeside-overdue -d 90 -c user
-
-=head1 ORIGINAL AUTHORS
-
-Original disable-overdue version by mw/kwh: Mark W.? and Kristian Hoffmann ?
-
-Ivan seems to be turning it into the "do-everything" CLI.
-
-=head1 BUGS
-
-Hell now that this is the do-everything CLI it should have --longoptions
-
-=cut
-
-1;
-
index 83074b9..6ea27c0 100644 (file)
@@ -1,10 +1,10 @@
 #!/usr/bin/perl -w
 
 use strict;
-use vars qw( $log_file $sigterm $sigint $kids $max_kids );
+use vars qw( $log_file $sigterm $sigint $kids $max_kids %kids );
 use subs qw( _die _logmsg );
 use Fcntl qw(:flock);
-use POSIX qw(setsid);
+use POSIX qw(:sys_wait_h setsid);
 use Date::Format;
 use IO::File;
 use FS::UID qw(adminsuidsetup forksuidsetup driver_name dbh);
@@ -15,7 +15,7 @@ use FS::queue_depend;
 # no autoloading just yet
 use FS::cust_main;
 use FS::svc_acct;
-use Net::SSH 0.06;
+use Net::SSH 0.07;
 use FS::part_export;
 
 $max_kids = '10'; #guess it should be a config file...
@@ -28,8 +28,8 @@ my $pid_file = "/var/run/freeside-queued.pid";
 
 &daemonize1;
 
-sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; $kids--; }
-$SIG{CHLD} =  \&REAPER;
+#sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; $kids--; }
+#$SIG{CHLD} =  \&REAPER;
 
 $sigterm = 0;
 $sigint = 0;
@@ -65,9 +65,11 @@ warn "freeside-queued starting\n";
 my $warnkids=0;
 while (1) {
 
+  &reap_kids;
   #prevent runaway forking
   if ( $kids >= $max_kids ) {
     warn "WARNING: maximum $kids children reached\n" unless $warnkids++;
+    &reap_kids;
     sleep 1; #waiting for signals is cheap
     next;
   }
@@ -131,6 +133,7 @@ while (1) {
 
   if ( $pid ) {
     $kids++;
+    $kids{$pid} = 1;
   } else { #kid time
 
     #get new db handle
@@ -230,6 +233,16 @@ sub daemonize2 {
   open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
 }
 
+sub reap_kids {
+  foreach my $pid ( keys %kids ) {
+    my $kid = waitpid($pid, WNOHANG);
+    if ( $kid > 0 ) {
+      $kids--;
+      delete $kids{$kid};
+    }
+  }
+}
+
 =head1 NAME
 
 freeside-queued - Job queue daemon
diff --git a/FS/bin/freeside-radgroup b/FS/bin/freeside-radgroup
new file mode 100644 (file)
index 0000000..ed85626
--- /dev/null
@@ -0,0 +1,76 @@
+#!/usr/bin/perl -w
+
+use strict;
+use FS::UID qw(adminsuidsetup);
+use FS::Record qw(qsearch);
+use FS::cust_svc;
+use FS::svc_acct;
+
+&untaint_argv;  #what it sounds like  (eww)
+
+my($user, $action, $groupname, $svcpart) = @ARGV;
+
+adminsuidsetup $user;
+
+my @svc_acct = map { $_->svc_x } qsearch('cust_svc', { svcpart => $svcpart } );
+
+if ( lc($action) eq 'add' ) {
+  foreach my $svc_acct ( @svc_acct ) {
+    my @groups = $svc_acct->radius_groups;
+    next if grep { $_ eq $groupname } @groups;
+    push @groups, $groupname;
+    my %hash = $svc_acct->hash;
+    $hash{usergroup} = \@groups;
+    my $new = new FS::svc_acct \%hash;
+    my $error = $new->replace($svc_acct);
+    die $error if $error;
+  }
+} else {
+  die &usage;
+}
+
+# subroutines
+
+sub untaint_argv {
+  foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
+    $ARGV[$_] =~ /^(.*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
+    $ARGV[$_]=$1;
+  }
+}
+
+sub usage {
+  die "Usage:\n\n  freeside-radgroup user action groupname svcpart\n";
+}
+
+=head1 NAME
+
+freeside-radgroup - Command line utility to manipulate radius groups
+
+=head1 SYNOPSIS
+
+  freeside-addgroup user action groupname svcpart 
+
+=head1 DESCRIPTION
+
+  B<user> is a freeside user as added with freeside-adduser.
+
+  B<command> is the action to take.  Available actions are: I<add>
+
+  B<groupname> is the group to add (or remove, etc.)
+
+  B<svcpart> specifies which accounts will be updated.
+
+=head1 EXAMPLES
+
+freeside-radgroup freesideuser add groupname 3
+
+Adds I<groupname> to all accounts with service definition 3.
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<freeside-adduser>, L<FS::svc_acct>, L<FS::part_svc>
+
+=cut
+
diff --git a/FS/bin/freeside-receivables-report b/FS/bin/freeside-receivables-report
deleted file mode 100755 (executable)
index b5a4903..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-#!/usr/bin/perl -Tw
-
-use strict;
-use Date::Parse;
-use Time::Local;
-use Getopt::Std;
-use Text::Template;
-use Net::SMTP;
-use Mail::Header;
-use Mail::Internet;
-use FS::Conf;
-use FS::UID qw(adminsuidsetup);
-use FS::Record qw(qsearch);
-use FS::cust_main;
-
-
-&untaint_argv; #what it sounds like  (eww)
-use vars qw($opt_v $opt_p $opt_m $opt_e $opt_t $report_lines $report_template @buf $header);
-getopts("vpmet:");     #switches
-
-#we're at now now (and later).
-my($_date)= $^T;
-
-# Get the current month
-my ($sec,$min,$hour,$mday,$mon,$year) =
-       (localtime($_date) )[0,1,2,3,4,5]; 
-$mon++;
-$year += 1900;
-
-# Login to the database
-my $user = shift or die &usage;
-adminsuidsetup $user;
-
-# Get the needed configuration files
-my $conf = new FS::Conf;
-my $lpr = $conf->config('lpr');
-my $email = $conf->config('email');
-my $smtpmachine = $conf->config('smtpmachine');
-my $mail_sender = $conf->exists('invoice_from') ? $conf->config('invoice_from') :
-  'postmaster';
-my @report_template = $conf->config('report_template')
-  or die "cannot load config file report_template";
-$report_lines = 0;
-  foreach ( grep /report_lines\(\d+\)/, @report_template ) { #kludgy :/
-  /report_lines\((\d+)\)/;
-  $report_lines += $1;
-}
-die "no report_lines() functions in template?" unless $report_lines;
-$report_template = new Text::Template (
-  TYPE   => 'ARRAY',
-  SOURCE => [ map "$_\n", @report_template ],
-) or die "can't create new Text::Template object: $Text::Template::ERROR";
-
-
-my(@customers)=qsearch('cust_main',{});
-if (scalar(@customers) == 0)
-{
-       exit 1;
-}
-
-# Open print and email pipes
-# $lpr and opt_p for printing
-# $email and opt_m for email
-
-if ($lpr && $opt_p)
-{
-        open(LPR, "|$lpr");
-}
-
-if ($email && $opt_m)
-{
-  $ENV{MAILADDRESS} = $mail_sender;
-  $header = new Mail::Header ( [
-    "From: Account Processor",
-    "To: $email",
-    "Sender: $mail_sender",
-    "Reply-To: $mail_sender",
-    "Subject: Receivables",
-  ] );
-}
-
-my $total = 0;
-
-
-# Now I can start looping
-foreach my $customer (@customers)
-{
-  my $custnum = $customer->getfield('custnum');
-  my $first = $customer->getfield('first');
-  my $last = $customer->getfield('last');
-  my $company = $customer->getfield('company');
-  my $daytime = $customer->getfield('daytime');
-  my $balance = $customer->balance;
-
-
-  if ($balance != 0) {
-    $total += $balance;
-    push @buf, sprintf(qq{%8d %-32.32s %12s %9.2f},
-      $custnum,
-      $first . " " . $last . "   " . $company,
-      $daytime,
-      $balance);
-
-  }
-
-}
-
-push @buf, ('', sprintf(qq{%61s}, "========="), sprintf(qq{%61.2f}, $total));
-
-sub FS::receivables_report::_template::report_lines {
-  my $lines = shift;
-  map {
-    scalar(@buf) ? shift @buf : '' ;
-  }
-  ( 1 .. $lines );
-}
-
-$FS::receivables_report::_template::title = " R E C E I V A B L E S ";
-$FS::receivables_report::_template::title = $opt_t if $opt_t;
-$FS::receivables_report::_template::page = 1;
-$FS::receivables_report::_template::date = $_date;
-$FS::receivables_report::_template::date = $_date;
-$FS::receivables_report::_template::total_pages = 
-  int( scalar(@buf) / $report_lines);
-$FS::receivables_report::_template::total_pages++ if scalar(@buf) % $report_lines;
-
-my @report;
-while (@buf) {
-  push @report, split("\n", 
-    $report_template->fill_in( PACKAGE => 'FS::receivables_report::_template' )
-  );
-  $FS::receivables_report::_template::page++;
-}
-
-if ($opt_v) {
-  print map "$_\n", @report;
-}
-if($lpr && $opt_p)
-{
-  print LPR map "$_\n", @report;
-  print LPR "\f" if $opt_e;
-  close LPR || die "Could not close printer: $lpr\n";
-}
-if($email && $opt_m)
-{
-  my $message = new Mail::Internet (
-    'Header' => $header,
-    'Body' => [ (@report) ],
-  );
-  $!=0;
-  $message->smtpsend( Host => "$smtpmachine" )
-    or die "can't send report to $email via $smtpmachine: $!";
-}
-
-
-# subroutines
-
-sub untaint_argv {
-  foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
-    $ARGV[$_] =~ /^([\w\-\/ ]*)$/ || die "Illegal argument \"$ARGV[$_]\"";
-    $ARGV[$_]=$1;
-  }
-}
-
-sub usage {
-  die "Usage:\n\n  freeside-receivables-report [-v] [-p] [-e] user\n";
-}
-
-=head1 NAME
-
-freeside-receivables-report - Prints or emails outstanding receivables.
-
-=head1 SYNOPSIS
-
-  freeside-receivables-report [-v] [-p] [-m] [-e] [-t "title"] user
-
-=head1 DESCRIPTION
-
-Prints or emails outstanding receivables
-
-B<-v>: Verbose - Prints records to STDOUT.
-
-B<-p>: Print to printer lpr as found in the conf directory.
-
-B<-m>: Mail output to user found in the Conf email file.
-
-B<-e>: Print a final form feed to the printer.
-
-B<-t>: supply a title for the top of each page.
-
-user: From the mapsecrets file - see config.html from the base documentation
-
-=head1 VERSION
-
-$Id: freeside-receivables-report,v 1.5 2002-03-07 19:50:24 jeff Exp $
-
-=head1 BUGS
-
-Yes..... Use at your own risk. No guarantees or warrantees of any
-kind apply to this program. Parts of this program are hacked from
-other GNU licensed software created mainly by Ivan Kohler.
-
-This is released under the GNU Public License. See www.gnu.org
-for more information regarding this license.
-
-=head1 SEE ALSO
-
-L<FS::cust_main>, config.html from the base documentation
-
-=head1 AUTHOR
-
-Jeff Finucane <jeff@cmh.net>
-
-based on print-batch by Joel Griffiths <griff@aver-computer.com>
-
-=cut
-
diff --git a/FS/bin/freeside-selfservice-server b/FS/bin/freeside-selfservice-server
new file mode 100644 (file)
index 0000000..371a646
--- /dev/null
@@ -0,0 +1,266 @@
+#!/usr/bin/perl -w
+#
+# freeside-selfservice-server
+
+# alas, much false laziness with freeside-queued and fs_signup_server.  at
+# least it is slated to replace fs_{signup,passwd,mailadmin}_server
+# should probably generalize the version in here, or better yet use
+# Proc::Daemon or somesuch
+
+use strict;
+use vars qw( $Debug %kids $kids $max_kids $shutdown $log_file $ssh_pid );
+use subs qw( lock_write unlock_write );
+use Fcntl qw(:flock);
+use POSIX qw(:sys_wait_h setsid);
+use IO::Handle;
+use IO::Select;
+use IO::File;
+use Storable qw(nstore_fd fd_retrieve);
+use Net::SSH qw(sshopen2);
+use FS::UID qw(adminsuidsetup forksuidsetup);
+use FS::ClientAPI;
+
+use FS::Conf;
+use FS::cust_bill;
+use FS::cust_pkg;
+
+$Debug = 2; # >= 2 will log packet contents, including potentially compromising
+            # information
+
+$shutdown = 0;
+$max_kids = '10'; #?
+$kids = 0;
+
+my $user = shift or die &usage;
+my $machine = shift or die &usage;
+my $tag = scalar(@ARGV) ? shift : '';
+
+# $FS::UID::datasrc not posible
+my $pid_file = "/var/run/freeside-selfservice-server.$user.$machine.pid";
+
+my $lock_file = "/usr/local/etc/freeside/selfservice.$machine.writelock";
+open(LOCKFILE,">$lock_file") or die "can't open $lock_file: $!";
+
+&init($user);
+
+my $conf = new FS::Conf;
+
+my $clientd = "/usr/local/sbin/freeside-selfservice-clientd"; #better name?
+
+my $warnkids=0;
+while (1) {
+  my($writer,$reader,$error) = (new IO::Handle, new IO::Handle, new IO::Handle);
+  warn "connecting to $machine\n" if $Debug;
+
+  $ssh_pid = sshopen2($machine,$reader,$writer,$clientd,$tag);
+
+#  nstore_fd(\*writer, {'hi'=>'there'});
+
+  warn "entering main loop\n" if $Debug;
+  my $undisp = 0;
+  my $s = IO::Select->new( $reader );
+  while (1) {
+
+    &reap_kids;
+
+    warn "waiting for packet from client\n" if $Debug && !$undisp;
+    $undisp = 1;
+    my @handles = $s->can_read(5);
+    unless ( @handles ) {
+      &shutdown if $shutdown;
+      next;
+    }
+
+    $undisp = 0;
+
+    warn "receiving packet from client\n" if $Debug;
+
+    my $packet = eval { fd_retrieve($reader); };
+    if ( $@ ) {
+      warn "Storable error receiving packet from client".
+           " (assuming lost connection): $@\n"
+        if $Debug;
+      if ( $ssh_pid ) {
+        warn "sending TERM signal to ssh process $ssh_pid\n" if $Debug;
+        kill 'TERM', $ssh_pid;
+        $ssh_pid = 0;
+      }
+      last;
+    }
+    warn "packet received\n".
+         join('', map { " $_=>$packet->{$_}\n" } keys %$packet )
+      if $Debug > 1;
+
+    #prevent runaway forking
+    my $warnkids = 0;
+    while ( $kids >= $max_kids ) {
+      warn "WARNING: maximum $kids children reached\n" unless $warnkids++;
+      &reap_kids;
+      sleep 1;
+    }
+
+    warn "forking child\n" if $Debug;
+    defined( my $pid = fork ) or die "can't fork: $!";
+    if ( $pid ) {
+      $kids++;
+      $kids{$pid} = 1;
+      warn "child $pid spawned\n" if $Debug;
+    } else { #kid time
+
+      #get new db handle
+      $FS::UID::dbh->{InactiveDestroy} = 1;
+      forksuidsetup($user);
+
+      my $type = $packet->{_packet};
+      warn "calling $type handler\n" if $Debug; 
+      my $rv = eval { FS::ClientAPI->dispatch($type, $packet); };
+      if ( $@ ) {
+        warn my $error = "WARNING: error dispatching $type: $@";
+        $rv = { _error => $error };
+      }
+      $rv->{_token} = $packet->{_token}; #identifier
+
+      warn "sending response\n" if $Debug;
+      lock_write;
+      nstore_fd($rv, $writer) or die "FATAL: can't send response: $!";
+      $writer->flush or die "FATAL: can't flush: $!";
+      unlock_write;
+
+      warn "child exiting\n" if $Debug;
+      exit; #end-of-kid
+    }
+
+  }
+
+  warn "connection lost, reconnecting\n" if $Debug;
+  sleep 3;
+
+}
+
+###
+# utility subroutines
+###
+
+sub reap_kids {
+  #warn "reaping kids\n";
+  foreach my $pid ( keys %kids ) {
+    my $kid = waitpid($pid, WNOHANG);
+    if ( $kid > 0 ) {
+      $kids--;
+      delete $kids{$kid};
+    }
+  }
+  #warn "done reaping\n";
+}
+
+sub init {
+  my $user = shift;
+
+  chdir "/" or die "Can't chdir to /: $!";
+  open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
+  defined(my $pid = fork) or die "Can't fork: $!";
+  if ( $pid ) {
+    print "freeside-selfservice-server to $machine started with pid $pid\n"; #logging to $log_file
+    exit unless $pid_file;
+    my $pidfh = new IO::File ">$pid_file" or exit;
+    print $pidfh "$pid\n";
+    exit;
+  }
+
+#  sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; $kids--; }
+#  #sub REAPER { my $pid = wait; $kids--; $SIG{CHLD} = \&REAPER; }
+#  $SIG{CHLD} =  \&REAPER;
+
+  $shutdown = 0;
+  $SIG{HUP} = sub { warn "SIGHUP received; shutting down\n"; $shutdown++; };
+  $SIG{INT} = sub { warn "SIGINT received; shutting down\n"; $shutdown++; };
+  $SIG{TERM} = sub { warn "SIGTERM received; shutting down\n"; $shutdown++; };
+  $SIG{QUIT} = sub { warn "SIGQUIT received; shutting down\n"; $shutdown++; };
+  $SIG{PIPE} = sub { warn "SIGPIPE received; shutting down\n"; $shutdown++; };
+
+  #false laziness w/freeside-queued
+  my $freeside_gid = scalar(getgrnam('freeside'))
+    or die "can't setgid to freeside group\n";
+  $) = $freeside_gid;
+  $( = $freeside_gid;
+  #if freebsd can't setuid(), presumably it can't setgid() either.  grr fleabsd
+  ($(,$)) = ($),$();
+  $) = $freeside_gid;
+
+  $> = $FS::UID::freeside_uid;
+  $< = $FS::UID::freeside_uid;
+  #freebsd is sofa king broken, won't setuid()
+  ($<,$>) = ($>,$<);
+  $> = $FS::UID::freeside_uid;
+  #eslaf
+
+  $ENV{HOME} = (getpwuid($>))[7]; #for ssh
+  adminsuidsetup $user;
+
+  #$log_file = "/usr/local/etc/freeside/selfservice.". $FS::UID::datasrc; #MACHINE NAME
+  $log_file = "/usr/local/etc/freeside/selfservice.$machine.log";
+
+  open STDOUT, '>/dev/null'
+                            or die "Can't write to /dev/null: $!";
+  setsid                  or die "Can't start a new session: $!";
+  open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
+
+  $SIG{__DIE__} = \&_die;
+  $SIG{__WARN__} = \&_logmsg;
+
+  warn "freeside-selfservice-server starting\n";
+
+}
+
+sub shutdown {
+  my $wait = 12; #wait up to 1 minute
+  while ( $kids > 0 && $wait-- ) {
+    warn "waiting for $kids children to terminate";
+    sleep 5;
+  }
+  warn "abandoning $kids children" if $kids;
+  kill 'TERM', $ssh_pid if $ssh_pid;
+  die "exiting";
+}
+
+sub _die {
+  my $msg = shift;
+  unlink $pid_file if -e $pid_file;
+  _logmsg($msg);
+}
+
+sub _logmsg {
+  chomp( my $msg = shift );
+  _do_logmsg( "[server] [". scalar(localtime). "] [$$] $msg\n" );
+}
+
+sub _do_logmsg {
+  chomp( my $msg = shift );
+  my $log = new IO::File ">>$log_file";
+  flock($log, LOCK_EX);
+  seek($log, 0, 2);
+  print $log "$msg\n";
+  flock($log, LOCK_UN);
+  close $log;
+}
+
+sub lock_write {
+  #broken on freebsd?
+  #flock($writer, LOCK_EX) or die "FATAL: can't lock write stream: $!";
+
+  flock(LOCKFILE, LOCK_EX) or die "FATAL: can't lock $lock_file: $!";
+
+}
+
+sub unlock_write {
+  #broken on freebsd?
+  #flock($writer, LOCK_UN) or die "WARNING: can't release write lock: $!";
+
+  flock(LOCKFILE, LOCK_UN) or die "FATAL: can't unlock $lock_file: $!";
+
+}
+
+sub usage {
+  die "Usage:\n\n  freeside-selfservice-server user machine\n";
+}
+
diff --git a/FS/bin/freeside-setup b/FS/bin/freeside-setup
new file mode 100755 (executable)
index 0000000..7512cc1
--- /dev/null
@@ -0,0 +1,1141 @@
+#!/usr/bin/perl -Tw
+
+#to delay loading dbdef until we're ready
+BEGIN { $FS::Record::setup_hack = 1; }
+
+use strict;
+use vars qw($opt_s);
+use Getopt::Std;
+use DBI;
+use DBIx::DBSchema 0.21;
+use DBIx::DBSchema::Table;
+use DBIx::DBSchema::Column;
+use DBIx::DBSchema::ColGroup::Unique;
+use DBIx::DBSchema::ColGroup::Index;
+use FS::UID qw(adminsuidsetup datasrc checkeuid getsecrets);
+use FS::Record;
+use FS::cust_main_county;
+use FS::raddb;
+use FS::part_bill_event;
+
+die "Not running uid freeside!" unless checkeuid();
+
+my %attrib2db =
+  map { lc($FS::raddb::attrib{$_}) => $_ } keys %FS::raddb::attrib;
+
+getopts("s");
+my $user = shift or die &usage;
+getsecrets($user);
+
+#needs to match FS::Record
+my($dbdef_file) = "/usr/local/etc/freeside/dbdef.". datasrc;
+
+###
+
+#print "\nEnter the maximum username length: ";
+#my($username_len)=&getvalue;
+my $username_len = 32; #usernamemax config file
+
+#print "\n\n", <<END, ":";
+#Freeside tracks the RADIUS User-Name, check attribute Password and
+#reply attribute Framed-IP-Address for each user.  You can specify additional
+#check and reply attributes (or you can add them later with the
+#fs-radius-add-check and fs-radius-add-reply programs).
+#
+#First enter any additional RADIUS check attributes you need to track for each 
+#user, separated by whitespace.
+#END
+#my @check_attributes = map { $attrib2db{lc($_)} or die "unknown attribute $_"; }
+#                         split(" ",&getvalue);
+#
+#print "\n\n", <<END, ":";
+#Now enter any additional reply attributes you need to track for each user,
+#separated by whitespace.
+#END
+#my @attributes = map { $attrib2db{lc($_)} or die "unknown attribute $_"; }
+#                   split(" ",&getvalue);
+#
+#print "\n\n", <<END, ":";
+#Do you wish to enable the tracking of a second, separate shipping/service
+#address?
+#END
+#my $ship = &_yesno;
+#
+#sub getvalue {
+#  my($x)=scalar(<STDIN>);
+#  chop $x;
+#  $x;
+#}
+#
+#sub _yesno {
+#  print " [y/N]:";
+#  my $x = scalar(<STDIN>);
+#  $x =~ /^y/i;
+#}
+
+my @check_attributes = (); #add later
+my @attributes = (); #add later
+my $ship = $opt_s;
+
+###
+
+my($char_d) = 80; #default maxlength for text fields
+
+#my(@date_type)  = ( 'timestamp', '', ''     );
+my(@date_type)  = ( 'int', 'NULL', ''     );
+my(@perl_type) = ( 'text', 'NULL', ''  ); 
+my @money_type = ( 'decimal',   '', '10,2' );
+
+###
+# create a dbdef object from the old data structure
+###
+
+my(%tables)=&tables_hash_hack;
+
+#turn it into objects
+my($dbdef) = new DBIx::DBSchema ( map {  
+  my(@columns);
+  while (@{$tables{$_}{'columns'}}) {
+    my($name,$type,$null,$length)=splice @{$tables{$_}{'columns'}}, 0, 4;
+    push @columns, new DBIx::DBSchema::Column ( $name,$type,$null,$length );
+  }
+  DBIx::DBSchema::Table->new(
+    $_,
+    $tables{$_}{'primary_key'},
+    DBIx::DBSchema::ColGroup::Unique->new($tables{$_}{'unique'}),
+    DBIx::DBSchema::ColGroup::Index->new($tables{$_}{'index'}),
+    @columns,
+  );
+} (keys %tables) );
+
+my $cust_main = $dbdef->table('cust_main');
+unless ($ship) { #remove ship_ from cust_main
+  $cust_main->delcolumn($_) foreach ( grep /^ship_/, $cust_main->columns );
+} else { #add indices
+  push @{$cust_main->index->lol_ref},
+    map { [ "ship_$_" ] } qw( last company daytime night fax );
+}
+
+#add radius attributes to svc_acct
+
+my($svc_acct)=$dbdef->table('svc_acct');
+
+my($attribute);
+foreach $attribute (@attributes) {
+  $svc_acct->addcolumn ( new DBIx::DBSchema::Column (
+    'radius_'. $attribute,
+    'varchar',
+    'NULL',
+    $char_d,
+  ));
+}
+
+foreach $attribute (@check_attributes) {
+  $svc_acct->addcolumn( new DBIx::DBSchema::Column (
+    'rc_'. $attribute,
+    'varchar',
+    'NULL',
+    $char_d,
+  ));
+}
+
+#create history tables (false laziness w/create-history-tables)
+foreach my $table ( grep { ! /^h_/ } $dbdef->tables ) {
+  my $tableobj = $dbdef->table($table)
+    or die "unknown table $table";
+
+  die "unique->lol_ref undefined for $table"
+    unless defined $tableobj->unique->lol_ref;
+  die "index->lol_ref undefined for $table"
+    unless defined $tableobj->index->lol_ref;
+
+  my $h_tableobj = DBIx::DBSchema::Table->new( {
+    name        => "h_$table",
+    primary_key => 'historynum',
+    unique      => DBIx::DBSchema::ColGroup::Unique->new( [] ),
+    'index'     => DBIx::DBSchema::ColGroup::Index->new( [
+                     @{$tableobj->unique->lol_ref},
+                     @{$tableobj->index->lol_ref}
+                   ] ),
+    columns     => [
+                     DBIx::DBSchema::Column->new( {
+                       'name'    => 'historynum',
+                       'type'    => 'serial',
+                       'null'    => 'NOT NULL',
+                       'length'  => '',
+                       'default' => '',
+                       'local'   => '',
+                     } ),
+                     DBIx::DBSchema::Column->new( {
+                       'name'    => 'history_date',
+                       'type'    => 'int',
+                       'null'    => 'NULL',
+                       'length'  => '',
+                       'default' => '',
+                       'local'   => '',
+                     } ),
+                     DBIx::DBSchema::Column->new( {
+                       'name'    => 'history_user',
+                       'type'    => 'varchar',
+                       'null'    => 'NOT NULL',
+                       'length'  => '80',
+                       'default' => '',
+                       'local'   => '',
+                     } ),
+                     DBIx::DBSchema::Column->new( {
+                       'name'    => 'history_action',
+                       'type'    => 'varchar',
+                       'null'    => 'NOT NULL',
+                       'length'  => '80',
+                       'default' => '',
+                       'local'   => '',
+                     } ),
+                     map {
+                       my $column = $tableobj->column($_);
+
+                       #clone so as to not disturb the original
+                       $column = DBIx::DBSchema::Column->new( {
+                         map { $_ => $column->$_() }
+                           qw( name type null length default local )
+                       } );
+
+                       $column->type('int')
+                         if $column->type eq 'serial';
+                       #$column->default('')
+                       #  if $column->default =~ /^nextval\(/i;
+                       #( my $local = $column->local ) =~ s/AUTO_INCREMENT//i;
+                       #$column->local($local);
+                       $column;
+                     } $tableobj->columns
+                   ],
+  } );
+  $dbdef->addtable($h_tableobj);
+}
+
+#important
+$dbdef->save($dbdef_file);
+&FS::Record::reload_dbdef($dbdef_file);
+
+###
+# create 'em
+###
+
+my($dbh)=adminsuidsetup $user;
+
+#create tables
+$|=1;
+
+foreach my $statement ( $dbdef->sql($dbh) ) {
+  $dbh->do( $statement )
+    or die "CREATE error: ". $dbh->errstr. "\ndoing statement: $statement";
+}
+
+#not really sample data (and shouldn't default to US)
+
+#cust_main_county
+
+#USPS state codes
+foreach ( qw(
+AL AK AS AZ AR CA CO CT DC DE FM FL GA GU HI ID IL IN IA KS KY LA
+ME MH MD MA MI MN MS MO MT NC ND NE NH NJ NM NV NY MP OH OK OR PA PW PR RI 
+SC SD TN TX UT VT VI VA WA WV WI WY AE AA AP
+) ) {
+  my($cust_main_county)=new FS::cust_main_county({
+    'state' => $_,
+    'tax'   => 0,
+    'country' => 'US',
+  });  
+  my($error);
+  $error=$cust_main_county->insert;
+  die $error if $error;
+}
+
+#AU "offical" state codes ala mark.williamson@ebbs.com.au (Mark Williamson)
+foreach ( qw(
+VIC NSW NT QLD TAS ACT WA SA
+) ) {
+  my($cust_main_county)=new FS::cust_main_county({
+    'state' => $_,
+    'tax'   => 0,
+    'country' => 'AU',
+  });  
+  my($error);
+  $error=$cust_main_county->insert;
+  die $error if $error;
+}
+
+#ISO 2-letter country codes (same as country TLDs) except US and AU
+foreach ( qw(
+AF AL DZ AS AD AO AI AQ AG AR AM AW AT AZ BS BH BD BB BY BE BZ BJ BM BT BO
+BA BW BV BR IO BN BG BF BI KH CM CA CV KY CF TD CL CN CX CC CO KM CG CK CR CI
+HR CU CY CZ DK DJ DM DO TP EC EG SV GQ ER EE ET FK FO FJ FI FR FX GF PF TF GA
+GM GE DE GH GI GR GL GD GP GU GT GN GW GY HT HM HN HK HU IS IN ID IR IQ IE IL
+IT JM JP JO KZ KE KI KP KR KW KG LA LV LB LS LR LY LI LT LU MO MK MG MW MY MV
+ML MT MH MQ MR MU YT MX FM MD MC MN MS MA MZ MM NA NR NP NL AN NC NZ NI NE NG
+NU NF MP NO OM PK PW PA PG PY PE PH PN PL PT PR QA RE RO RU RW KN LC VC WS SM
+ST SA SN SC SL SG SK SI SB SO ZA GS ES LK SH PM SD SR SJ SZ SE CH SY TW TJ TZ
+TH TG TK TO TT TN TR TM TC TV UG UA AE GB UM UY UZ VU VA VE VN VG VI WF EH
+YE YU ZR ZM ZW
+) ) {
+  my($cust_main_county)=new FS::cust_main_county({
+    'tax'   => 0,
+    'country' => $_,
+  });  
+  my($error);
+  $error=$cust_main_county->insert;
+  die $error if $error;
+}
+
+#billing events
+foreach my $aref ( 
+  [ 'COMP', 'Comp invoice', '$cust_bill->comp();', 30, 'comp' ],
+  [ 'CARD', 'Batch card', '$cust_bill->batch_card();', 40, 'batch-card' ],
+  [ 'BILL', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
+  [ 'DCRD', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
+  [ 'DCHK', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
+) {
+
+  my $part_bill_event = new FS::part_bill_event({
+    'payby' => $aref->[0],
+    'event' => $aref->[1],
+    'eventcode' => $aref->[2],
+    'seconds' => 0,
+    'weight' => $aref->[3],
+    'plan' => $aref->[4],
+  });
+  my($error);
+  $error=$part_bill_event->insert;
+  die $error if $error;
+
+}
+
+$dbh->commit or die $dbh->errstr;
+$dbh->disconnect or die $dbh->errstr;
+
+#print "Freeside database initialized sucessfully\n";
+
+sub usage {
+  die "Usage:\n  freeside-setup [ -s ] user\n"; 
+}
+
+###
+# Now it becomes an object.  much better.
+###
+sub tables_hash_hack {
+
+  #note that s/(date|change)/_$1/; to avoid keyword conflict.
+  #put a kludge in FS::Record to catch this or? (pry need some date-handling
+  #stuff anyway also)
+
+  my(%tables)=( #yech.}
+
+    'agent' => {
+      'columns' => [
+        'agentnum', 'serial',            '',     '',
+        'agent',    'varchar',           '',     $char_d,
+        'typenum',  'int',            '',     '',
+        'freq',     'int',       'NULL', '',
+        'prog',     @perl_type,
+        'disabled',     'char', 'NULL', 1,
+        'username', 'varchar',       'NULL',     $char_d,
+        '_password','varchar',       'NULL',     $char_d,
+      ],
+      'primary_key' => 'agentnum',
+      'unique' => [],
+      'index' => [ ['typenum'], ['disabled'] ],
+    },
+
+    'agent_type' => {
+      'columns' => [
+        'typenum',   'serial',  '', '',
+        'atype',     'varchar', '', $char_d,
+      ],
+      'primary_key' => 'typenum',
+      'unique' => [],
+      'index' => [],
+    },
+
+    'type_pkgs' => {
+      'columns' => [
+        'typenum',   'int',  '', '',
+        'pkgpart',   'int',  '', '',
+      ],
+      'primary_key' => '',
+      'unique' => [ ['typenum', 'pkgpart'] ],
+      'index' => [ ['typenum'] ],
+    },
+
+    'cust_bill' => {
+      'columns' => [
+        'invnum',    'serial',  '', '',
+        'custnum',   'int',  '', '',
+        '_date',     @date_type,
+        'charged',   @money_type,
+        'printed',   'int',  '', '',
+        'closed',    'char', 'NULL', 1,
+      ],
+      'primary_key' => 'invnum',
+      'unique' => [],
+      'index' => [ ['custnum'], ['_date'] ],
+    },
+
+    'cust_bill_event' => {
+      'columns' => [
+        'eventnum',    'serial',  '', '',
+        'invnum',   'int',  '', '',
+        'eventpart',   'int',  '', '',
+        '_date',     @date_type,
+        'status', 'varchar', '', $char_d,
+        'statustext', 'text', 'NULL', '',
+      ],
+      'primary_key' => 'eventnum',
+      #no... there are retries now #'unique' => [ [ 'eventpart', 'invnum' ] ],
+      'unique' => [],
+      'index' => [ ['invnum'], ['status'] ],
+    },
+
+    'part_bill_event' => {
+      'columns' => [
+        'eventpart',    'serial',  '', '',
+        'payby',       'char',  '', 4,
+        'event',       'varchar',           '',     $char_d,
+        'eventcode',    @perl_type,
+        'seconds',     'int', 'NULL', '',
+        'weight',      'int', '', '',
+        'plan',       'varchar', 'NULL', $char_d,
+        'plandata',   'text', 'NULL', '',
+        'disabled',     'char', 'NULL', 1,
+      ],
+      'primary_key' => 'eventpart',
+      'unique' => [],
+      'index' => [ ['payby'], ['disabled'], ],
+    },
+
+    'cust_bill_pkg' => {
+      'columns' => [
+        'pkgnum',  'int', '', '',
+        'invnum',  'int', '', '',
+        'setup',   @money_type,
+        'recur',   @money_type,
+        'sdate',   @date_type,
+        'edate',   @date_type,
+        'itemdesc', 'varchar', 'NULL', $char_d,
+      ],
+      'primary_key' => '',
+      'unique' => [],
+      'index' => [ ['invnum'] ],
+    },
+
+    'cust_bill_pkg_detail' => {
+      'columns' => [
+        'detailnum', 'serial', '', '',
+        'pkgnum',  'int', '', '',
+        'invnum',  'int', '', '',
+        'detail',  'varchar', '', $char_d,
+      ],
+      'primary_key' => 'detailnum',
+      'unique' => [],
+      'index' => [ [ 'pkgnum', 'invnum' ] ],
+    },
+
+    'cust_credit' => {
+      'columns' => [
+        'crednum',  'serial', '', '',
+        'custnum',  'int', '', '',
+        '_date',    @date_type,
+        'amount',   @money_type,
+        'otaker',   'varchar', '', 32,
+        'reason',   'text', 'NULL', '',
+        'closed',    'char', 'NULL', 1,
+      ],
+      'primary_key' => 'crednum',
+      'unique' => [],
+      'index' => [ ['custnum'] ],
+    },
+
+    'cust_credit_bill' => {
+      'columns' => [
+        'creditbillnum', 'serial', '', '',
+        'crednum',  'int', '', '',
+        'invnum',  'int', '', '',
+        '_date',    @date_type,
+        'amount',   @money_type,
+      ],
+      'primary_key' => 'creditbillnum',
+      'unique' => [],
+      'index' => [ ['crednum'], ['invnum'] ],
+    },
+
+    'cust_main' => {
+      'columns' => [
+        'custnum',  'serial',  '',     '',
+        'agentnum', 'int',  '',     '',
+#        'titlenum', 'int',  'NULL',   '',
+        'last',     'varchar', '',     $char_d,
+#        'middle',   'varchar', 'NULL', $char_d,
+        'first',    'varchar', '',     $char_d,
+        'ss',       'varchar', 'NULL', 11,
+        'company',  'varchar', 'NULL', $char_d,
+        'address1', 'varchar', '',     $char_d,
+        'address2', 'varchar', 'NULL', $char_d,
+        'city',     'varchar', '',     $char_d,
+        'county',   'varchar', 'NULL', $char_d,
+        'state',    'varchar', 'NULL', $char_d,
+        'zip',      'varchar', '',     10,
+        'country',  'char', '',     2,
+        'daytime',  'varchar', 'NULL', 20,
+        'night',    'varchar', 'NULL', 20,
+        'fax',      'varchar', 'NULL', 12,
+        'ship_last',     'varchar', 'NULL', $char_d,
+#        'ship_middle',   'varchar', 'NULL', $char_d,
+        'ship_first',    'varchar', 'NULL', $char_d,
+        'ship_company',  'varchar', 'NULL', $char_d,
+        'ship_address1', 'varchar', 'NULL', $char_d,
+        'ship_address2', 'varchar', 'NULL', $char_d,
+        'ship_city',     'varchar', 'NULL', $char_d,
+        'ship_county',   'varchar', 'NULL', $char_d,
+        'ship_state',    'varchar', 'NULL', $char_d,
+        'ship_zip',      'varchar', 'NULL', 10,
+        'ship_country',  'char', 'NULL', 2,
+        'ship_daytime',  'varchar', 'NULL', 20,
+        'ship_night',    'varchar', 'NULL', 20,
+        'ship_fax',      'varchar', 'NULL', 12,
+        'payby',    'char', '',     4,
+        'payinfo',  'varchar', 'NULL', $char_d,
+        'paycvv',   'varchar', 'NULL', 4,
+        #'paydate',  @date_type,
+        'paydate',  'varchar', 'NULL', 10,
+        'payname',  'varchar', 'NULL', $char_d,
+        'tax',      'char', 'NULL', 1,
+        'otaker',   'varchar', '',    32,
+        'refnum',   'int',  '',     '',
+        'referral_custnum', 'int',  'NULL', '',
+        'comments', 'text', 'NULL', '',
+      ],
+      'primary_key' => 'custnum',
+      'unique' => [],
+      #'index' => [ ['last'], ['company'] ],
+      'index' => [ ['last'], [ 'company' ], [ 'referral_custnum' ],
+                   [ 'daytime' ], [ 'night' ], [ 'fax' ],
+                 ],
+    },
+
+    'cust_main_invoice' => {
+      'columns' => [
+        'destnum',  'serial',  '',     '',
+        'custnum',  'int',  '',     '',
+        'dest',     'varchar', '',  $char_d,
+      ],
+      'primary_key' => 'destnum',
+      'unique' => [],
+      'index' => [ ['custnum'], ],
+    },
+
+    'cust_main_county' => { #county+state+country are checked off the
+                            #cust_main_county for validation and to provide
+                            # a tax rate.
+      'columns' => [
+        'taxnum',   'serial',   '',    '',
+        'state',    'varchar',  'NULL',    $char_d,
+        'county',   'varchar',  'NULL',    $char_d,
+        'country',  'char',  '', 2, 
+        'taxclass',   'varchar', 'NULL', $char_d,
+        'exempt_amount', @money_type,
+        'tax',      'real',  '',    '', #tax %
+        'taxname',  'varchar',  'NULL',    $char_d,
+        'setuptax',  'char', 'NULL', 1, # Y = setup tax exempt
+        'recurtax',  'char', 'NULL', 1, # Y = recur tax exempt
+      ],
+      'primary_key' => 'taxnum',
+      'unique' => [],
+  #    'unique' => [ ['taxnum'], ['state', 'county'] ],
+      'index' => [],
+    },
+
+    'cust_pay' => {
+      'columns' => [
+        'paynum',   'serial',    '',   '',
+        #now cust_bill_pay #'invnum',   'int',    '',   '',
+        'custnum',  'int',    '',   '',
+        'paid',     @money_type,
+        '_date',    @date_type,
+        'payby',    'char',   '',     4, # CARD/BILL/COMP, should be index into
+                                         # payment type table.
+        'payinfo',  'varchar',   'NULL', $char_d,  #see cust_main above
+        'paybatch', 'varchar',   'NULL', $char_d, #for auditing purposes.
+        'closed',    'char', 'NULL', 1,
+      ],
+      'primary_key' => 'paynum',
+      'unique' => [],
+      'index' => [ [ 'custnum' ], [ 'paybatch' ], [ 'payby' ], [ '_date' ] ],
+    },
+
+    'cust_bill_pay' => {
+      'columns' => [
+        'billpaynum', 'serial',     '',   '',
+        'invnum',  'int',     '',   '',
+        'paynum',  'int',     '',   '',
+        'amount',  @money_type,
+        '_date',   @date_type
+      ],
+      'primary_key' => 'billpaynum',
+      'unique' => [],
+      'index' => [ [ 'paynum' ], [ 'invnum' ] ],
+    },
+
+    'cust_pay_batch' => { #what's this used for again?  list of customers
+                          #in current CARD batch? (necessarily CARD?)
+      'columns' => [
+        'paybatchnum',   'serial',    '',   '',
+        'invnum',   'int',    '',   '',
+        'custnum',   'int',    '',   '',
+        'last',     'varchar', '',     $char_d,
+        'first',    'varchar', '',     $char_d,
+        'address1', 'varchar', '',     $char_d,
+        'address2', 'varchar', 'NULL', $char_d,
+        'city',     'varchar', '',     $char_d,
+        'state',    'varchar', 'NULL', $char_d,
+        'zip',      'varchar', '',     10,
+        'country',  'char', '',     2,
+#        'trancode', 'int', '', '',
+        'cardnum',  'varchar', '',     16,
+        #'exp',      @date_type,
+        'exp',      'varchar', '',     11,
+        'payname',  'varchar', 'NULL', $char_d,
+        'amount',   @money_type,
+      ],
+      'primary_key' => 'paybatchnum',
+      'unique' => [],
+      'index' => [ ['invnum'], ['custnum'] ],
+    },
+
+    'cust_pkg' => {
+      'columns' => [
+        'pkgnum',    'serial',    '',   '',
+        'custnum',   'int',    '',   '',
+        'pkgpart',   'int',    '',   '',
+        'otaker',    'varchar', '', 32,
+        'setup',     @date_type,
+        'bill',      @date_type,
+        'last_bill', @date_type,
+        'susp',      @date_type,
+        'cancel',    @date_type,
+        'expire',    @date_type,
+        'manual_flag', 'char', 'NULL', 1,
+      ],
+      'primary_key' => 'pkgnum',
+      'unique' => [],
+      'index' => [ ['custnum'] ],
+    },
+
+    'cust_refund' => {
+      'columns' => [
+        'refundnum',    'serial',    '',   '',
+        #now cust_credit_refund #'crednum',      'int',    '',   '',
+        'custnum',  'int',    '',   '',
+        '_date',        @date_type,
+        'refund',       @money_type,
+        'otaker',       'varchar',   '',   32,
+        'reason',       'varchar',   '',   $char_d,
+        'payby',        'char',   '',     4, # CARD/BILL/COMP, should be index
+                                             # into payment type table.
+        'payinfo',      'varchar',   'NULL', $char_d,  #see cust_main above
+        'paybatch',     'varchar',   'NULL', $char_d,
+        'closed',    'char', 'NULL', 1,
+      ],
+      'primary_key' => 'refundnum',
+      'unique' => [],
+      'index' => [],
+    },
+
+    'cust_credit_refund' => {
+      'columns' => [
+        'creditrefundnum', 'serial',     '',   '',
+        'crednum',  'int',     '',   '',
+        'refundnum',  'int',     '',   '',
+        'amount',  @money_type,
+        '_date',   @date_type
+      ],
+      'primary_key' => 'creditrefundnum',
+      'unique' => [],
+      'index' => [ [ 'crednum', 'refundnum' ] ],
+    },
+
+
+    'cust_svc' => {
+      'columns' => [
+        'svcnum',    'serial',    '',   '',
+        'pkgnum',    'int',    'NULL',   '',
+        'svcpart',   'int',    '',   '',
+      ],
+      'primary_key' => 'svcnum',
+      'unique' => [],
+      'index' => [ ['svcnum'], ['pkgnum'], ['svcpart'] ],
+    },
+
+    'part_pkg' => {
+      'columns' => [
+        'pkgpart',    'serial',    '',   '',
+        'pkg',        'varchar',   '',   $char_d,
+        'comment',    'varchar',   '',   $char_d,
+        'setup',      @perl_type,
+        'freq',       'varchar',   '',   $char_d,  #billing frequency
+        'recur',      @perl_type,
+        'setuptax',  'char', 'NULL', 1,
+        'recurtax',  'char', 'NULL', 1,
+        'plan',       'varchar', 'NULL', $char_d,
+        'plandata',   'text', 'NULL', '',
+        'disabled',   'char', 'NULL', 1,
+        'taxclass',   'varchar', 'NULL', $char_d,
+      ],
+      'primary_key' => 'pkgpart',
+      'unique' => [],
+      'index' => [ [ 'disabled' ], ],
+    },
+
+#    'part_title' => {
+#      'columns' => [
+#        'titlenum',   'int',    '',   '',
+#        'title',      'varchar',   '',   $char_d,
+#      ],
+#      'primary_key' => 'titlenum',
+#      'unique' => [ [] ],
+#      'index' => [ [] ],
+#    },
+
+    'pkg_svc' => {
+      'columns' => [
+        'pkgpart',    'int',    '',   '',
+        'svcpart',    'int',    '',   '',
+        'quantity',   'int',    '',   '',
+        'primary_svc','char', 'NULL',  1,
+      ],
+      'primary_key' => '',
+      'unique' => [ ['pkgpart', 'svcpart'] ],
+      'index' => [ ['pkgpart'] ],
+    },
+
+    'part_referral' => {
+      'columns' => [
+        'refnum',   'serial',    '',   '',
+        'referral', 'varchar',   '',   $char_d,
+        'disabled',     'char', 'NULL', 1,
+      ],
+      'primary_key' => 'refnum',
+      'unique' => [],
+      'index' => [ ['disabled'] ],
+    },
+
+    'part_svc' => {
+      'columns' => [
+        'svcpart',    'serial',    '',   '',
+        'svc',        'varchar',   '',   $char_d,
+        'svcdb',      'varchar',   '',   $char_d,
+        'disabled',   'char',  'NULL',   1,
+      ],
+      'primary_key' => 'svcpart',
+      'unique' => [],
+      'index' => [ [ 'disabled' ] ],
+    },
+
+    'part_svc_column' => {
+      'columns' => [
+        'columnnum',   'serial',         '', '',
+        'svcpart',     'int',         '', '',
+        'columnname',  'varchar',     '', 64,
+        'columnvalue', 'varchar', 'NULL', $char_d,
+        'columnflag',  'char',    'NULL', 1, 
+      ],
+      'primary_key' => 'columnnum',
+      'unique' => [ [ 'svcpart', 'columnname' ] ],
+      'index' => [ [ 'svcpart' ] ],
+    },
+
+    #(this should be renamed to part_pop)
+    'svc_acct_pop' => {
+      'columns' => [
+        'popnum',    'serial',    '',   '',
+        'city',      'varchar',   '',   $char_d,
+        'state',     'varchar',   '',   $char_d,
+        'ac',        'char',   '',   3,
+        'exch',      'char',   '',   3,
+        'loc',       'char',   'NULL',   4, #NULL for legacy purposes
+      ],
+      'primary_key' => 'popnum',
+      'unique' => [],
+      'index' => [ [ 'state' ] ],
+    },
+
+    'part_pop_local' => {
+      'columns' => [
+        'localnum',  'serial',     '',     '',
+        'popnum',    'int',     '',     '',
+        'city',      'varchar', 'NULL', $char_d,
+        'state',     'char',    'NULL', 2,
+        'npa',       'char',    '',     3,
+        'nxx',       'char',    '',     3,
+      ],
+      'primary_key' => 'localnum',
+      'unique' => [],
+      'index' => [ [ 'npa', 'nxx' ], [ 'popnum' ] ],
+    },
+
+    'svc_acct' => {
+      'columns' => [
+        'svcnum',    'int',    '',   '',
+        'username',  'varchar',   '',   $username_len, #unique (& remove dup code)
+        '_password', 'varchar',   '',   72, #13 for encryped pw's plus ' *SUSPENDED* (md5 passwords can be 34, blowfish 60)
+        'sec_phrase', 'varchar',  'NULL',   $char_d,
+        'popnum',    'int',    'NULL',   '',
+        'uid',       'int', 'NULL',   '',
+        'gid',       'int', 'NULL',   '',
+        'finger',    'varchar',   'NULL',   $char_d,
+        'dir',       'varchar',   'NULL',   $char_d,
+        'shell',     'varchar',   'NULL',   $char_d,
+        'quota',     'varchar',   'NULL',   $char_d,
+        'slipip',    'varchar',   'NULL',   15, #four TINYINTs, bah.
+        'seconds',   'int', 'NULL',   '', #uhhhh
+        'domsvc',    'int', '',   '',
+      ],
+      'primary_key' => 'svcnum',
+      #'unique' => [ [ 'username', 'domsvc' ] ],
+      'unique' => [],
+      'index' => [ ['username'], ['domsvc'] ],
+    },
+
+    #'svc_charge' => {
+    #  'columns' => [
+    #    'svcnum',    'int',    '',   '',
+    #    'amount',    @money_type,
+    #  ],
+    #  'primary_key' => 'svcnum',
+    #  'unique' => [ [] ],
+    #  'index' => [ [] ],
+    #},
+
+    'svc_domain' => {
+      'columns' => [
+        'svcnum',    'int',    '',   '',
+        'domain',    'varchar',    '',   $char_d,
+        'catchall',  'int', 'NULL',    '',
+      ],
+      'primary_key' => 'svcnum',
+      'unique' => [ ['domain'] ],
+      'index' => [],
+    },
+
+    'domain_record' => {
+      'columns' => [
+        'recnum',    'serial',     '',  '',
+        'svcnum',    'int',     '',  '',
+        #'reczone',   'varchar', '',  $char_d,
+        'reczone',   'varchar', '',  255,
+        'recaf',     'char',    '',  2,
+        'rectype',   'varchar',    '',  5,
+        #'recdata',   'varchar', '',  $char_d,
+        'recdata',   'varchar', '',  255,
+      ],
+      'primary_key' => 'recnum',
+      'unique'      => [],
+      'index'       => [ ['svcnum'] ],
+    },
+
+    'svc_forward' => {
+      'columns' => [
+        'svcnum',   'int',            '',   '',
+        'srcsvc',   'int',        'NULL',   '',
+        'src',      'varchar',    'NULL',  255,
+        'dstsvc',   'int',        'NULL',   '',
+        'dst',      'varchar',    'NULL',  255,
+      ],
+      'primary_key' => 'svcnum',
+      'unique'      => [],
+      'index'       => [ ['srcsvc'], ['dstsvc'] ],
+    },
+
+    'svc_www' => {
+      'columns' => [
+        'svcnum',   'int',    '',  '',
+        'recnum',   'int',    '',  '',
+        'usersvc',  'int',    '',  '',
+      ],
+      'primary_key' => 'svcnum',
+      'unique'      => [],
+      'index'       => [],
+    },
+
+    #'svc_wo' => {
+    #  'columns' => [
+    #    'svcnum',    'int',    '',   '',
+    #    'svcnum',    'int',    '',   '',
+    #    'svcnum',    'int',    '',   '',
+    #    'worker',    'varchar',   '',   $char_d,
+    #    '_date',     @date_type,
+    #  ],
+    #  'primary_key' => 'svcnum',
+    #  'unique' => [ [] ],
+    #  'index' => [ [] ],
+    #},
+
+    'prepay_credit' => {
+      'columns' => [
+        'prepaynum',   'serial',     '',   '',
+        'identifier',  'varchar', '', $char_d,
+        'amount',      @money_type,
+        'seconds',     'int',     'NULL', '',
+      ],
+      'primary_key' => 'prepaynum',
+      'unique'      => [ ['identifier'] ],
+      'index'       => [],
+    },
+
+    'port' => {
+      'columns' => [
+        'portnum',  'serial',     '',   '',
+        'ip',       'varchar', 'NULL', 15,
+        'nasport',  'int',     'NULL', '',
+        'nasnum',   'int',     '',   '',
+      ],
+      'primary_key' => 'portnum',
+      'unique'      => [],
+      'index'       => [],
+    },
+
+    'nas' => {
+      'columns' => [
+        'nasnum',   'serial',     '',    '',
+        'nas',      'varchar', '',    $char_d,
+        'nasip',    'varchar', '',    15,
+        'nasfqdn',  'varchar', '',    $char_d,
+        'last',     'int',     '',    '',
+      ],
+      'primary_key' => 'nasnum',
+      'unique'      => [ [ 'nas' ], [ 'nasip' ] ],
+      'index'       => [ [ 'last' ] ],
+    },
+
+    'session' => {
+      'columns' => [
+        'sessionnum', 'serial',       '',   '',
+        'portnum',    'int',       '',   '',
+        'svcnum',     'int',       '',   '',
+        'login',      @date_type,
+        'logout',     @date_type,
+      ],
+      'primary_key' => 'sessionnum',
+      'unique'      => [],
+      'index'       => [ [ 'portnum' ] ],
+    },
+
+    'queue' => {
+      'columns' => [
+        'jobnum', 'serial', '', '',
+        'job', 'text', '', '',
+        '_date', 'int', '', '',
+        'status', 'varchar', '', $char_d,
+        'statustext', 'text', 'NULL', '',
+        'svcnum', 'int', 'NULL', '',
+      ],
+      'primary_key' => 'jobnum',
+      'unique'      => [],
+      'index'       => [ [ 'svcnum' ], [ 'status' ] ],
+    },
+
+    'queue_arg' => {
+      'columns' => [
+        'argnum', 'serial', '', '',
+        'jobnum', 'int', '', '',
+        'arg', 'text', 'NULL', '',
+      ],
+      'primary_key' => 'argnum',
+      'unique'      => [],
+      'index'       => [ [ 'jobnum' ] ],
+    },
+
+    'queue_depend' => {
+      'columns' => [
+        'dependnum', 'serial', '', '',
+        'jobnum', 'int', '', '',
+        'depend_jobnum', 'int', '', '',
+      ],
+      'primary_key' => 'dependnum',
+      'unique'      => [],
+      'index'       => [ [ 'jobnum' ], [ 'depend_jobnum' ] ],
+    },
+
+    'export_svc' => {
+      'columns' => [
+        'exportsvcnum' => 'serial', '', '',
+        'exportnum'    => 'int', '', '',
+        'svcpart'      => 'int', '', '',
+      ],
+      'primary_key' => 'exportsvcnum',
+      'unique'      => [ [ 'exportnum', 'svcpart' ] ],
+      'index'       => [ [ 'exportnum' ], [ 'svcpart' ] ],
+    },
+
+    'part_export' => {
+      'columns' => [
+        'exportnum', 'serial', '', '',
+        #'svcpart',   'int', '', '',
+        'machine', 'varchar', '', $char_d,
+        'exporttype', 'varchar', '', $char_d,
+        'nodomain',     'char', 'NULL', 1,
+      ],
+      'primary_key' => 'exportnum',
+      'unique'      => [],
+      'index'       => [ [ 'machine' ], [ 'exporttype' ] ],
+    },
+
+    'part_export_option' => {
+      'columns' => [
+        'optionnum', 'serial', '', '',
+        'exportnum', 'int', '', '',
+        'optionname', 'varchar', '', $char_d,
+        'optionvalue', 'text', 'NULL', '',
+      ],
+      'primary_key' => 'optionnum',
+      'unique'      => [],
+      'index'       => [ [ 'exportnum' ], [ 'optionname' ] ],
+    },
+
+    'radius_usergroup' => {
+      'columns' => [
+        'usergroupnum', 'serial', '', '',
+        'svcnum',       'int', '', '',
+        'groupname',    'varchar', '', $char_d,
+      ],
+      'primary_key' => 'usergroupnum',
+      'unique'      => [],
+      'index'       => [ [ 'svcnum' ], [ 'groupname' ] ],
+    },
+
+    'msgcat' => {
+      'columns' => [
+        'msgnum', 'serial', '', '',
+        'msgcode', 'varchar', '', $char_d,
+        'locale', 'varchar', '', 16,
+        'msg', 'text', '', '',
+      ],
+      'primary_key' => 'msgnum',
+      'unique'      => [ [ 'msgcode', 'locale' ] ],
+      'index'       => [],
+    },
+
+    'cust_tax_exempt' => {
+      'columns' => [
+        'exemptnum', 'serial', '', '',
+        'custnum',   'int', '', '',
+        'taxnum',    'int', '', '',
+        'year',      'int', '', '',
+        'month',     'int', '', '',
+        'amount',   @money_type,
+      ],
+      'primary_key' => 'exemptnum',
+      'unique'      => [ [ 'custnum', 'taxnum', 'year', 'month' ] ],
+      'index'       => [],
+    },
+
+    'router' => {
+      'columns' => [
+        'routernum', 'serial', '', '',
+        'routername', 'varchar', '', $char_d,
+        'svcnum', 'int', 'NULL', '',
+      ],
+      'primary_key' => 'routernum',
+      'unique'      => [],
+      'index'       => [],
+    },
+
+    'part_svc_router' => {
+      'columns' => [
+        'svcpart', 'int', '', '',
+       'routernum', 'int', '', '',
+      ],
+      'primary_key' => '',
+      'unique'      => [],
+      'index'       => [],
+    },
+
+    'addr_block' => {
+      'columns' => [
+        'blocknum', 'serial', '', '',
+       'routernum', 'int', '', '',
+        'ip_gateway', 'varchar', '', 15,
+        'ip_netmask', 'int', '', '',
+      ],
+      'primary_key' => 'blocknum',
+      'unique'      => [ [ 'blocknum', 'routernum' ] ],
+      'index'       => [],
+    },
+
+    'svc_broadband' => {
+      'columns' => [
+        'svcnum', 'int', '', '',
+        'blocknum', 'int', '', '',
+        'speed_up', 'int', '', '',
+        'speed_down', 'int', '', '',
+        'ip_addr', 'varchar', '', 15,
+      ],
+      'primary_key' => 'svcnum',
+      'unique'      => [],
+      'index'       => [],
+    },
+
+    'part_virtual_field' => {
+      'columns' => [
+        'vfieldpart', 'int', '', '',
+        'dbtable', 'varchar', '', 32,
+        'name', 'varchar', '', 32,
+        'check_block', 'text', 'NULL', '',
+        'length', 'int', 'NULL', '',
+        'list_source', 'text', 'NULL', '',
+        'label', 'varchar', 'NULL', 80,
+      ],
+      'primary_key' => 'vfieldpart',
+      'unique' => [],
+      'index' => [],
+    },
+
+    'virtual_field' => {
+      'columns' => [
+        'recnum', 'int', '', '',
+        'vfieldpart', 'int', '', '',
+        'value', 'varchar', '', 128,
+      ],
+      'primary_key' => '',
+      'unique' => [ [ 'vfieldpart', 'recnum' ] ],
+      'index' => [],
+    },
+
+    'acct_snarf' => {
+      'columns' => [
+        'snarfnum',  'int', '', '',
+        'svcnum',    'int', '', '',
+        'machine',   'varchar', '', 255,
+        'protocol',  'varchar', '', $char_d,
+        'username',  'varchar', '', $char_d,
+        '_password', 'varchar', '', $char_d,
+      ],
+      'primary_key' => 'snarfnum',
+      'unique' => [],
+      'index'  => [ [ 'svcnum' ] ],
+    },
+
+    'svc_external' => {
+      'columns' => [
+        'svcnum', 'int', '', '',
+        'id',     'int', '', '',
+        'title',  'varchar', 'NULL', $char_d,
+      ],
+      'primary_key' => 'svcnum',
+      'unique'      => [],
+      'index'       => [],
+    },
+
+  );
+
+  %tables;
+
+}
+
diff --git a/FS/bin/freeside-sqlradius-radacctd b/FS/bin/freeside-sqlradius-radacctd
new file mode 100644 (file)
index 0000000..4e8d57c
--- /dev/null
@@ -0,0 +1,180 @@
+#!/usr/bin/perl -Tw
+
+use strict;
+use vars qw( $log_file $sigterm $sigint );
+use subs qw( _die _logmsg );
+use Fcntl qw(:flock);
+use POSIX qw(setsid);
+use Date::Format;
+use IO::File;
+use FS::UID qw(adminsuidsetup);
+#use FS::Record qw(qsearch qsearchs);
+#use FS::part_export;
+#use FS::svc_acct;
+#use FS::cust_svc;
+
+#lots of false laziness w/freeside-queued
+
+my $user = shift or die &usage;
+
+#my $pid_file = "/var/run/freeside-sqlradius-radacctd.$user.pid";
+my $pid_file = "/var/run/freeside-sqlradius-radacctd.pid";
+
+&daemonize1;
+
+#sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; $kids--; }
+#$SIG{CHLD} =  \&REAPER;
+
+$sigterm = 0;
+$sigint = 0;
+$SIG{INT} = sub { warn "SIGINT received; shutting down\n"; $sigint++; };
+$SIG{TERM} = sub { warn "SIGTERM received; shutting down\n"; $sigterm++; };
+
+my $freeside_gid = scalar(getgrnam('freeside'))
+  or die "can't setgid to freeside group\n";
+$) = $freeside_gid;
+$( = $freeside_gid;
+#if freebsd can't setuid(), presumably it can't setgid() either.  grr fleabsd
+($(,$)) = ($),$();
+$) = $freeside_gid;
+
+$> = $FS::UID::freeside_uid;
+$< = $FS::UID::freeside_uid;
+#freebsd is sofa king broken, won't setuid()
+($<,$>) = ($>,$<);
+$> = $FS::UID::freeside_uid;
+
+#$ENV{HOME} = (getpwuid($>))[7]; #for ssh
+adminsuidsetup $user;
+
+$log_file= "/usr/local/etc/freeside/sqlradius-radacctd-log.". $FS::UID::datasrc;
+
+&daemonize2;
+
+$SIG{__DIE__} = \&_die;
+$SIG{__WARN__} = \&_logmsg;
+
+warn "freeside-sqlradius-radacctd starting\n";
+
+#eslaf
+
+#my $machine = shift or die &usage; #would need to be up higher for real
+my @exports = qsearch('part_export', { 'exporttype' => 'sqlradius' } );
+
+while (1) {
+
+  my %seen = ();
+  foreach my $export ( @exports ) {
+    next if $seen{$export->option('datasrc')}++;
+    my $dbh = DBI->connect(
+      map { $export->option($_) } qw( datasrc username password )
+    ) or do {
+      warn "can't connect to ". $export->option('datasrc'). ": ". $DBI::errstr;
+      next;
+    }
+
+    # find old radacct position
+    #$lastid = 0;
+
+    # get new radacct records
+    my $sth = $dbh->prepare('SELECT * FROM radacct WHERE radacctid > ?') or do {
+      warn "can't select in radacct table from ". $export->option('datasrc').
+           ": ". $dbh->errstr;
+      next;
+    };
+
+    while ( my $radacct = $sth->fetchrow_arrayref({}) ) {
+
+      my $session = new FS::session {
+        portnum =>
+        svcnum  => 
+        login   =>
+        #logout  =>
+      };
+
+    }
+
+    # look for updated radacct records & replace them
+
+  }
+
+  sleep 5;
+
+}
+
+#more false laziness w/freeside-queued
+
+sub usage {
+  die "Usage:\n\n  freeside-sqlradius-radacctd user\n";
+}
+
+sub _die {
+  my $msg = shift;
+  unlink $pid_file if -e $pid_file;
+  _logmsg($msg);
+}
+
+sub _logmsg {
+  chomp( my $msg = shift );
+  my $log = new IO::File ">>$log_file";
+  flock($log, LOCK_EX);
+  seek($log, 0, 2);
+  print $log "[". time2str("%a %b %e %T %Y",time). "] [$$] $msg\n";
+  flock($log, LOCK_UN);
+  close $log;
+}
+
+sub daemonize1 {
+
+  chdir "/" or die "Can't chdir to /: $!";
+  open STDIN, '/dev/null'   or die "Can't read /dev/null: $!";
+  defined(my $pid = fork) or die "Can't fork: $!";
+  if ( $pid ) {
+    print "freeside-sqlradius-radacctd started with pid $pid\n";
+          #logging to $log_file\n";
+    exit unless $pid_file;
+    my $pidfh = new IO::File ">$pid_file" or exit;
+    print $pidfh "$pid\n";
+    exit;
+  }
+  #open STDOUT, '>/dev/null'
+  #                          or die "Can't write to /dev/null: $!";
+  #setsid                  or die "Can't start a new session: $!";
+  #open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
+
+}
+
+sub daemonize2 {
+  open STDOUT, '>/dev/null'
+                            or die "Can't write to /dev/null: $!";
+  setsid                  or die "Can't start a new session: $!";
+  open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
+}
+
+
+#eslaf
+
+=head1 NAME
+
+freeside-sqlradius-radacctd - Real-time radacct import daemon
+
+=head1 SYNOPSIS
+
+  freeside-sqlradius-radacctd username
+
+=head1 DESCRIPTION
+
+Imports records from an SQL radacct table in real-time into the session
+monitor.
+
+This enables per-minute or per-hour charges as well as the
+"View active NAS ports" function.
+
+B<username> is a username added by freeside-adduser.
+
+=head1 SEE ALSO
+
+session.html from the base documentation.
+
+=cut
+
index 9d3a6a7..74f90a5 100755 (executable)
@@ -12,7 +12,9 @@ adminsuidsetup $user;
 
 #my $machine = shift or die &usage;
 
-my @exports = qsearch('part_export', { 'exporttype' => 'sqlradius' } );
+my @exports =  qsearch('part_export', { exporttype=>'sqlradius' } );
+push @exports, qsearch('part_export', { exporttype=>'sqlradius_withdomain' } );
+
 
 foreach my $export ( @exports ) {
   my $icradius_dbh = DBI->connect(
diff --git a/FS/bin/freeside-sqlradius-seconds b/FS/bin/freeside-sqlradius-seconds
new file mode 100644 (file)
index 0000000..1c978fa
--- /dev/null
@@ -0,0 +1,58 @@
+#!/usr/bin/perl -Tw
+
+use strict;
+use Date::Parse;
+use FS::UID qw(adminsuidsetup);
+use FS::Record qw(qsearchs);
+use FS::svc_acct;
+
+my $fs_user = shift or die &usage;
+adminsuidsetup( $fs_user );
+
+my $target_user = shift or die &usage;
+my $start = shift or die &usage;
+$start = str2time($start);
+my $stop =  scalar(@ARGV) ? str2time(shift) : time;
+
+my $svc_acct = qsearchs( 'svc_acct', { 'username' => $target_user } );
+die "username $target_user not found\n" unless $svc_acct;
+
+print $svc_acct->seconds_since_sqlradacct( $start, $stop ). "\n";
+
+sub usage {
+  die "Usage:\n\n  freeside-sqlradius-seconds freeside_username target_username start_date stop_date\n";
+}
+
+
+=head1 NAME
+
+freeside-sqlradius-seconds - Real-time radacct import daemon
+
+=head1 SYNOPSIS
+
+  freeside-sqlradius-seconds freeside_username target_username start_date [ stop_date ]
+
+=head1 DESCRIPTION
+
+Returns the number of seconds the specified username has been online between
+start_date (inclusive) and stop_date (exclusive).
+See L<FS::svc_acct/seconds_since_sqlradacct>
+
+B<freeside_username> is a username added by freeside-adduser.
+B<target_username> is the username of the user account to query.
+B<start_date> and B<stop_date> are in any format Date::Parse is happy with.
+B<stop_date> defaults to now if not specified.
+
+=head1 BUGS
+
+Selection of the account in question is rather simplistic in that
+B<target_username> doesn't necessarily identify a unique account (and wouldn't
+even if a domain was specified), and no sqlradius export is checked for.
+
+=head1 SEE ALSO
+
+L<FS::svc_acct/seconds_since_sqlradacct>
+
+=cut
+
+1;
index 8d50213..240f3ad 100755 (executable)
@@ -228,7 +228,7 @@ if($email && $opt_m)
 # subroutines
 sub untaint_argv {
   foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
-    $ARGV[$_] =~ /^([\w\-\/ :]*)$/ || die "Illegal argument \"$ARGV[$_]\"";
+    $ARGV[$_] =~ /^([\w\-\/ :\.]*)$/ || die "Illegal argument \"$ARGV[$_]\"";
     $ARGV[$_]=$1;
   }
 }
@@ -267,7 +267,7 @@ user: From the mapsecrets file - see config.html from the base documentation
 
 =head1 VERSION
 
-$Id: freeside-tax-report,v 1.4 2002-03-07 19:50:24 jeff Exp $
+$Id: freeside-tax-report,v 1.5 2002-09-09 22:57:34 ivan Exp $
 
 =head1 BUGS
 
diff --git a/FS/t/Misc.t b/FS/t/Misc.t
new file mode 100644 (file)
index 0000000..cc7751a
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::Misc;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/acct_snarf.t b/FS/t/acct_snarf.t
new file mode 100644 (file)
index 0000000..642760f
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::acct_snarf;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/cust_bill_pkg_detail.t b/FS/t/cust_bill_pkg_detail.t
new file mode 100644 (file)
index 0000000..ea6e3d1
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::cust_bill_pkg_detail;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/part_export-apache.t b/FS/t/part_export-apache.t
new file mode 100644 (file)
index 0000000..b999508
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::part_export::apache;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/part_export-domain_shellcommands.t b/FS/t/part_export-domain_shellcommands.t
new file mode 100644 (file)
index 0000000..a2a44fb
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::part_export::domain_shellcommands;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/part_export-forward_shellcommands.t b/FS/t/part_export-forward_shellcommands.t
new file mode 100644 (file)
index 0000000..78ca68d
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::part_export::forward_shellcommands;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/part_export-ldap.t b/FS/t/part_export-ldap.t
new file mode 100644 (file)
index 0000000..826c341
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::part_export::ldap;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/part_export-sqlradius_withdomain.t b/FS/t/part_export-sqlradius_withdomain.t
new file mode 100644 (file)
index 0000000..504bf67
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::part_export::sqlradius_withdomain;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/svc_acct_sm.t b/FS/t/svc_acct_sm.t
deleted file mode 100644 (file)
index 1082f2c..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-BEGIN { $| = 1; print "1..1\n" }
-END {print "not ok 1\n" unless $loaded;}
-use FS::svc_acct_sm;
-$loaded=1;
-print "ok 1\n";
diff --git a/FS/t/svc_broadband.t b/FS/t/svc_broadband.t
new file mode 100644 (file)
index 0000000..02dc112
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::svc_broadband;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/svc_external.t b/FS/t/svc_external.t
new file mode 100644 (file)
index 0000000..20a6767
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::svc_external;
+$loaded=1;
+print "ok 1\n";
index a3f6158..72b3e58 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,47 +1,66 @@
 #!/usr/bin/make
 
-DATASOURCE = DBI:Pg:host=localhost;dbname=freeside
+DATASOURCE = DBI:Pg:dbname=freeside
 #DATASOURCE=DBI:mysql:freeside
 
 DB_USER = freeside
 DB_PASSWORD=
 
-TEMPLATE = asp
-#TEMPLATE = mason
+#TEMPLATE = asp
+TEMPLATE = mason
 
 ASP_GLOBAL = /usr/local/etc/freeside/asp-global
+MASON_HANDLER = /usr/local/etc/freeside/handler.pl
+MASONDATA = /usr/local/etc/freeside/masondata
 
+#deb
 FREESIDE_DOCUMENT_ROOT = /var/www/freeside
-
+#redhat, mandrake
+#FREESIDE_DOCUMENT_ROOT = /var/www/html/freeside
+#freebsd
+#FREESIDE_DOCUMENT_ROOT = /usr/local/www/data/freeside
+#openbsd
+#FREESIDE_DOCUMENT_ROOT = /var/www/htdocs/freeside
+
+#deb, redhat, mandrake, others?
 INIT_FILE = /etc/init.d/freeside
+#freebsd
+#INIT_FILE = /usr/local/etc/rc.d/011.freeside.sh
 
+#deb
 HTTPD_RESTART = /etc/init.d/apache restart
-FREESIDE_RESTART = /etc/init.d/freeside restart
+#redhat, mandrake
+#HTTPD_RESTART = /etc/init.d/httpd restart
+#freebsd
+#HTTPD_RESTART = /usr/local/etc/rc.d/apache.sh stop; sleep 1; /usr/local/etc/rc.d/apache.sh start
+#openbsd
+#HTTPD_RESTART = kill -TERM `cat /var/www/logs/httpd.pid`; sleep 1; /usr/sbin/httpd -u -DSSL
+
+FREESIDE_RESTART = ${INIT_FILE} restart
 
+#deb, redhat, mandrake, others?
 INSTALLGROUP = root
+#freebsd, openbsd
+#INSTALLGROUP = wheel
 
 #edit the stuff below to have the daemons start
 
-QUEUED_USER=ivan
+QUEUED_USER=fs_queue
 
 #eventually this shouldn't be needed
 FREESIDE_PATH = `pwd`
 
-PASSWD_USER = nostart
-PASSWD_MACHINE = localhost
-
-SIGNUP_USER = nostart
-SIGNUP_MACHINE = localhost
-SIGNUP_AGENTNUM = 2
-SIGNUP_REFNUM = 2
+SELFSERVICE_USER = fs_selfservice
+SELFSERVICE_MACHINES = localhost
+# SELFSERVICE_MACHINES = web1.example.com web2.example.com
 
 #---
 
 #not changable yet
 FREESIDE_CONF = /usr/local/etc/freeside
 
-VERSION=1.4.0
-TAG=freeside_1_4_0
+VERSION=1.5.0pre4
+TAG=freeside_1_5_0pre4
 
 help:
        @echo "supported targets: aspdocs masondocs alldocs docs install-docs"
@@ -54,14 +73,21 @@ help:
 aspdocs: htmlman httemplate/* httemplate/*/* httemplate/*/*/* httemplate/*/*/*/* httemplate/*/*/*/*/*
        rm -rf aspdocs
        cp -pr httemplate aspdocs
+       perl -p -i -e "\
+         s/%%%VERSION%%%/${VERSION}/g;\
+       " aspdocs/index.html
        touch aspdocs
 
+
 masondocs: htmlman httemplate/* httemplate/*/* httemplate/*/*/* httemplate/*/*/*/* httemplate/*/*/*/*/*
        rm -rf masondocs
        cp -pr httemplate masondocs
        ( cd masondocs; \
          ../bin/masonize; \
        )
+       perl -p -i -e "\
+         s/%%%VERSION%%%/${VERSION}/g;\
+       " masondocs/index.html
        touch masondocs
 
 alldocs: aspdocs masondocs
@@ -75,6 +101,7 @@ htmlman:
        [ -e ./httemplate/docs/man/FS ] || mkdir httemplate/docs/man/FS
        [ -e ./httemplate/docs/man/FS/UI ] || mkdir httemplate/docs/man/FS/UI
        [ -e ./httemplate/docs/man/FS/part_export ] || mkdir httemplate/docs/man/FS/part_export
+       chmod a+rx bin/pod2x
        [ -e DONT_REBUILD_DOCS ] || bin/pod2x
 
 forcehtmlman:
@@ -91,6 +118,9 @@ install-docs: docs
        [ "${TEMPLATE}" = "asp" -a ! -e ${ASP_GLOBAL} ] && mkdir ${ASP_GLOBAL} || true
        [ "${TEMPLATE}" = "asp" ] && chown -R freeside ${ASP_GLOBAL} || true
        [ "${TEMPLATE}" = "asp" ] && cp htetc/global.asa ${ASP_GLOBAL} || true
+       [ "${TEMPLATE}" = "mason" ] && cp htetc/handler.pl ${MASON_HANDLER} || true
+       [ "${TEMPLATE}" = "mason" -a ! -e ${MASONDATA} ] && mkdir ${MASONDATA} || true
+       [ "${TEMPLATE}" = "mason" ] && chown -R freeside ${MASONDATA} || true
 
 perl-modules:
        cd FS; \
@@ -107,12 +137,8 @@ install-init:
        perl -p -i -e "\
          s/%%%QUEUED_USER%%%/${QUEUED_USER}/g;\
          s'%%%FREESIDE_PATH%%%'${FREESIDE_PATH}'g;\
-         s/%%%PASSWD_USER%%%/${PASSWD_USER}/g;\
-         s/%%%PASSWD_MACHINE%%%/${PASSWD_MACHINE}/g;\
-         s/%%%SIGNUP_USER%%%/${SIGNUP_USER}/g;\
-         s/%%%SIGNUP_MACHINE%%%/${SIGNUP_MACHINE}/g;\
-         s/%%%SIGNUP_AGENTNUM%%%/${SIGNUP_AGENTNUM}/g;\
-         s/%%%SIGNUP_REFNUM%%%/${SIGNUP_REFNUM}/g;\
+         s/%%%SELFSERVICE_USER%%%/${SELFSERVICE_USER}/g;\
+         s/%%%SELFSERVICE_MACHINES%%%/${SELFSERVICE_MACHINES}/g;\
        " ${INIT_FILE}
 
 install: install-perl-modules install-docs install-init
@@ -126,8 +152,7 @@ create-database:
 
 create-config: install-perl-modules
        [ -e ${FREESIDE_CONF} ] && mv ${FREESIDE_CONF} ${FREESIDE_CONF}.`date +%Y%m%d%H%M%S` || true
-       mkdir ${FREESIDE_CONF}
-       chown freeside ${FREESIDE_CONF}
+       install -d -o freeside ${FREESIDE_CONF}
 
        touch ${FREESIDE_CONF}/secrets
        chown freeside ${FREESIDE_CONF}/secrets
@@ -138,7 +163,9 @@ create-config: install-perl-modules
        chown freeside ${FREESIDE_CONF}/secrets
 
        mkdir "${FREESIDE_CONF}/conf.${DATASOURCE}"
-       cp conf/[a-z]* "${FREESIDE_CONF}/conf.${DATASOURCE}"
+       rm -rf conf/registries #old dirs just won't go away
+       #cp conf/[a-z]* "${FREESIDE_CONF}/conf.${DATASOURCE}"
+       cp `ls -d conf/[a-z]* | grep -v CVS` "${FREESIDE_CONF}/conf.${DATASOURCE}"
        chown -R freeside "${FREESIDE_CONF}/conf.${DATASOURCE}"
 
        mkdir "${FREESIDE_CONF}/counters.${DATASOURCE}"
@@ -158,11 +185,11 @@ clean:
 #these are probably only useful if you're me...
 
 upload-docs: forcehtmlman
-       ssh cleanwhisker.420.am rm -rf /var/www/www.sisd.com/freeside/devdocs
-       scp -pr httemplate/docs cleanwhisker.420.am:/var/www/www.sisd.com/freeside/devdocs
+       ssh pouncequick.420.am rm -rf /var/www/www.sisd.com/freeside/devdocs
+       scp -pr httemplate/docs pouncequick.420.am:/var/www/www.sisd.com/freeside/devdocs
 
 release: upload-docs
-       cd /home/ivan/freeside_current
+       cd /home/ivan/freeside
        #cvs tag ${TAG}
        cvs tag -F ${TAG}
 
@@ -170,7 +197,7 @@ release: upload-docs
        cvs export -r ${TAG} -d freeside-${VERSION} freeside
        tar czvf freeside-${VERSION}.tar.gz freeside-${VERSION}
 
-       scp freeside-${VERSION}.tar.gz ivan@cleanwhisker.420.am:/var/www/sisd.420.am/freeside/
+       scp freeside-${VERSION}.tar.gz ivan@pouncequick.420.am:/var/www/sisd.420.am/freeside/
        mv freeside-${VERSION} freeside-${VERSION}.tar.gz ..
 
 update-webdemo:
diff --git a/README b/README
index 91e6253..1030b38 100644 (file)
--- a/README
+++ b/README
@@ -1,32 +1,26 @@
-Freeside 1.4.0
+Freeside
 
-Copyright (C) 2000,2001 Ivan Kohler
+Copyright (C) 2000,2001,2002,2003 Ivan Kohler
 Copyright (C) 1999 Silicon Interactive Software Design
 All rights reserved
 
     This program is free software; you can redistribute it and/or modify
-    it under the terms of either:
+    it under the terms of:
 
         a) the GNU General Public License as published by the Free
         Software Foundation; either version 2, or (at your option) any
-        later version, or
-
-        b) the "Artistic License"
+        later version
 
     This program 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 either the
-    GNU General Public License or the Artistic License for more details.
+    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, in the file `GPL'; if not,
     write to the Free Software Foundation, Inc., 59 Temple Place - Suite
     330, Boston, MA 02111-1307, USA.
 
-    You should have received a copy of the Artistic License along with
-    this program, in the file `Artistic'; if not, download it from
-    http://www.perl.com/CPAN/doc/misc/license/Artistic
-
 Freeside is a billing and administration package for Internet Service 
 Providers.
 
diff --git a/README.1.5.0pre1 b/README.1.5.0pre1
new file mode 100644 (file)
index 0000000..0de86bc
--- /dev/null
@@ -0,0 +1,17 @@
+preliminary upgrade instructions
+
+schema changes:
+  *** get svc_broadband changes from pc-intouch
+  *** otaker changes s/8/32 all otkaer fields
+  *** optional: sequence changes
+  *** add column cust_main_county.taxname
+  *** add column cust_bill_pkg.itemdesc
+  *** drop index cust_bill_pkg1
+  *** add index part_pkg1 and part_svc1
+
+install DBIx::DBSchema 0.21
+install NetAddr::IP
+
+Run dbdef-create
+something about history tables
+Restart apache and freeside-queued
diff --git a/bin/apache.export b/bin/apache.export
new file mode 100755 (executable)
index 0000000..f0a6bee
--- /dev/null
@@ -0,0 +1,65 @@
+#!/usr/bin/perl -w
+
+use strict;
+#use File::Path;
+use File::Rsync;
+use Net::SSH qw(ssh);
+use FS::UID qw(adminsuidsetup datasrc);
+use FS::Record qw(qsearch qsearchs);
+use FS::part_export;
+use FS::cust_svc;
+use FS::svc_www;
+
+my $user = shift or die &usage;
+adminsuidsetup $user;
+
+#needs the export number in there somewhere too...?
+my $spooldir = "/usr/local/etc/freeside/export.". datasrc. "/apache";
+mkdir $spooldir, 0700 unless -d $spooldir;
+
+my @exports = qsearch('part_export', { 'exporttype' => 'apache' } );
+
+my $rsync = File::Rsync->new({
+  rsh     => 'ssh',
+#  dry_run => 1,
+});
+
+foreach my $export ( @exports ) {
+
+  my $machine = $export->machine;
+  my $file = "$spooldir/$machine.conf";
+
+  open(HTTPD_CONF,">$file") or die "can't open $file: $!";
+
+  my $template = $export->option('template');
+
+  my @svc_www = $export->svc_x;
+
+  foreach my $svc_www ( @svc_www ) {
+    use vars qw($zone $username);
+    $zone = $svc_www->domain_record->zone;
+    $username = $svc_www->svc_acct->username;
+    print HTTPD_CONF eval(qq("$template")). "\n\n";
+  }
+
+  my $user = $export->option('user');
+  my $httpd_conf = $export->option('httpd_conf');
+
+  $rsync->exec( {
+    src       => $file,
+    dest      => "$user\@$machine:$httpd_conf",
+  } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err);
+ # warn $rsync->out;
+
+  ssh("root\@$machine", 'apachectl graceful');
+
+}
+
+close HTTPD_CONF;
+
+# -----
+
+sub usage {
+  die "Usage:\n  apache.export user\n"; 
+}
+
index 7d1452d..64d4406 100755 (executable)
@@ -30,6 +30,10 @@ foreach my $export ( @exports ) {
   my $machine = $export->machine;
   my $prefix = "$spooldir/$machine";
 
+  my $bind_rel = $export->option('bind_release');
+  my $ndc_cmd = ($bind_rel eq 'BIND9') ? 'rndc' : 'ndc';
+  my $minttl = $export->option('bind9_minttl');
+
   #prevent old domain files from piling up
   #rmtree "$prefix" or die "can't rmtree $prefix.db: $!";
 
@@ -38,19 +42,15 @@ foreach my $export ( @exports ) {
   open(NAMED_CONF,">$prefix/named.conf")
     or die "can't open $prefix/named.conf: $!";
 
-  open(CONF_HEADER,"<$prefix/named.conf.HEADER"); #or die
+  open(CONF_HEADER,"<$prefix/named.conf.HEADER")
+    or die "can't open $prefix/named.conf.HEADER: $!";
   while (<CONF_HEADER>) { print NAMED_CONF $_; }
   close CONF_HEADER;
 
   my $zonepath = $export->option('zonepath');
   $zonepath =~ s/\/$//;
 
-  #false laziness with  freeside-sqlradius-reset and shell.export
-  my @svc_domain =
-    map { qsearchs('svc_domain', { 'svcnum' => $_->svcnum } ) }
-      map { qsearch('cust_svc', { 'svcpart' => $_->svcpart } ) }
-        grep { qsearch('cust_svc', { 'svcpart' => $_->svcpart } ) }
-          $export->export_svc;
+  my @svc_domain = $export->svc_x;
 
   foreach my $svc_domain ( @svc_domain ) {
     my $domain = $svc_domain->domain;
@@ -83,6 +83,10 @@ END
       open (DB_MASTER,">$prefix/db.$domain")
         or die "can't open $prefix/db.$domain: $!";
 
+      if ($bind_rel eq 'BIND9') {
+        print DB_MASTER "\$TTL $minttl\n\$ORIGIN $domain.\n";
+      }
+
       my @domain_records =
         qsearch('domain_record', { 'svcnum' => $svc_domain->svcnum } );
       foreach my $domain_record (
@@ -118,7 +122,7 @@ END
   } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err);
 #  warn $rsync->out;
 
-  ssh("root\@$machine", 'ndc reload');
+  ssh("root\@$machine", "$ndc_cmd reload");
 
 }
 
@@ -129,6 +133,9 @@ foreach my $sexport ( @sexports ) { #false laziness with above
   my $machine = $sexport->machine;
   my $prefix = "$spooldir/$machine";
 
+  my $bind_rel = $sexport->option('bind_release');
+  my $ndc_cmd = ($bind_rel eq 'BIND9') ? 'rndc' : 'ndc';
+
   #prevent old domain files from piling up
   #rmtree "$prefix" or die "can't rmtree $prefix.db: $!";
 
@@ -137,7 +144,8 @@ foreach my $sexport ( @sexports ) { #false laziness with above
   open(NAMED_CONF,">$prefix/named.conf")
     or die "can't open $prefix/named.conf: $!";
 
-  open(CONF_HEADER,"<$prefix/named.conf.HEADER"); #or die
+  open(CONF_HEADER,"<$prefix/named.conf.HEADER")
+    or die "can't open $prefix/named.conf.HEADER: $!";
   while (<CONF_HEADER>) { print NAMED_CONF $_; }
   close CONF_HEADER;
 
@@ -169,7 +177,7 @@ END
   } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err);
 #  warn $rsync->out;
 
-  ssh("root\@$machine", 'ndc reload');
+  ssh("root\@$machine", "$ndc_cmd reload");
 
 }
 close NAMED_CONF;
index 57eca2b..3287b01 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -w
 #
-# $Id: bind.import,v 1.3 2002-07-15 01:44:23 ivan Exp $
+# $Id: bind.import,v 1.4 2004-02-12 10:44:11 ivan Exp $
 
 #need to manually put header in /usr/local/etc/freeside/export.<datasrc./bind/<machine>/named.conf.HEADER
 
@@ -79,7 +79,7 @@ print "\nBIND import completed.\n";
 ##
 
 sub usage {
-  die "Usage:\n\n  svc_domain.import user\n";
+  die "Usage:\n\n  bind.import user\n";
 }
 
 ########
index 10c2767..6e0d103 100755 (executable)
@@ -43,12 +43,7 @@ foreach my $export ( @bsd_exports ) {
   chmod 0644, "$prefix/passwd";
   chmod 0600, "$prefix/master.passwd";
 
-  #false laziness with  freeside-sqlradius-reset and bind.export
-  my @svc_acct = 
-    map { qsearchs('svc_acct', { 'svcnum' => $_->svcnum } ) }
-      map { qsearch('cust_svc', { 'svcpart' => $_->svcpart } ) }
-        grep { qsearch('cust_svc', { 'svcpart' => $_->svcpart } ) }
-          $export->export_svc;
+  my @svc_acct = $export->svc_x;
 
   next unless @svc_acct;
 
diff --git a/bin/create-fetchmailrc b/bin/create-fetchmailrc
new file mode 100644 (file)
index 0000000..e929711
--- /dev/null
@@ -0,0 +1,45 @@
+#!/usr/bin/perl -w
+# this quick hack helps you generate/maintain .fetchmailrc files from
+# FS::acct_snarf data.  it is run from a shellcommands export as:
+# create-fetchmailrc $username $dir $snarf_machine1 $snarf_username1 $snarf__password1 $snarf_machine2 $snarf_username2 $snarf__password2 ...
+
+use strict;
+use POSIX qw( setuid setgid );
+
+my $header = <<END;
+# Configuration created by create-fetchmailrc
+set postmaster "postmaster"
+set bouncemail
+set no spambounce
+set properties ""
+set daemon 240
+END
+
+my $username = shift @ARGV or die "no username specified\n";
+my $homedir  = shift @ARGV or die "no homedir specified\n";
+my $filename = "$homedir/.fetchmailrc";
+
+my $gid = scalar(getgrnam($username)) or die "can't find $username's gid\n";
+my $uid = scalar(getpwnam($username)) or die "can't find $username's uid\n";
+
+open(FETCHMAILRC, ">$filename") or die "can't open $filename: $!\n";
+chown $uid, $gid, $filename     or die "can't chown $uid.$gid $filename: $!\n";
+chmod 0600, $filename           or die "can't chmod 600 $filename: $!\n";
+print FETCHMAILRC $header;
+
+while ($ARGV[0]) {
+  my( $s_machine, $s_username, $s_password ) = splice( @ARGV, 0, 3 );
+  print FETCHMAILRC <<END;
+poll $s_machine
+       user '$s_username' there with password '$s_password' is '$username' here
+END
+}
+
+close FETCHMAILRC;
+
+setgid($gid) or die "can't setgid $gid\n";
+setuid($uid) or die "can't setuid $uid\n";
+$ENV{HOME} = $homedir;
+
+system(qq(fetchmail -a -K --antispam "550,451" -d 180 -f $filename));
+
index d37d682..39248bf 100755 (executable)
@@ -2,7 +2,7 @@
 
 use strict;
 use DBI;
-use DBIx::DBSchema 0.20;
+use DBIx::DBSchema 0.21;
 use DBIx::DBSchema::Table;
 use DBIx::DBSchema::Column;
 use DBIx::DBSchema::ColGroup::Unique;
@@ -18,8 +18,9 @@ my $schema = dbdef();
 #false laziness w/fs-setup
 my @tables = scalar(@ARGV)
                ? @ARGV
-               : grep { ! /^h_/ } $schema->tables;
+               : grep { ! /^(h|pg)_/ } $schema->tables;
 foreach my $table ( @tables ) {
+  next if grep { /^h_$table/ } $schema->tables;
   warn "creating history table for $table\n";
   my $tableobj = $schema->table($table)
     or die "unknown table $table (did you run dbdef-create?)\n";
@@ -64,7 +65,16 @@ foreach my $table ( @tables ) {
                        'default' => '',
                        'local'   => '',
                      } ),
-                     map { $tableobj->column($_) } $tableobj->columns
+                     map {
+                       my $column = $tableobj->column($_);
+                       $column->type('int')
+                         if $column->type eq 'serial';
+                       $column->default('')
+                         if $column->default =~ /^nextval\(/i;
+                       ( my $local = $column->local ) =~ s/AUTO_INCREMENT//i;
+                       $column->local($local);
+                       $column;
+                     } $tableobj->columns
                    ],
   } );
   foreach my $statement ( $h_tableobj->sql_create_table($dbh) ) {
index 0b297b9..a449d67 100755 (executable)
@@ -1,10 +1,8 @@
 #!/usr/bin/perl -Tw
-#
-# $Id: dbdef-create,v 1.5 2001-08-21 02:43:18 ivan Exp $
 
 use strict;
 use DBI;
-use DBIx::DBSchema;
+use DBIx::DBSchema 0.22;
 use FS::UID qw(adminsuidsetup datasrc driver_name);
 
 my $user = shift or die &usage;
diff --git a/bin/fix-sequences b/bin/fix-sequences
new file mode 100755 (executable)
index 0000000..2ff89d3
--- /dev/null
@@ -0,0 +1,69 @@
+#!/usr/bin/perl -Tw
+
+# run dbdef-create first!
+
+use strict;
+use DBI;
+use DBIx::DBSchema 0.21;
+use DBIx::DBSchema::Table;
+use DBIx::DBSchema::Column;
+use DBIx::DBSchema::ColGroup::Unique;
+use DBIx::DBSchema::ColGroup::Index;
+use FS::UID qw(adminsuidsetup driver_name);
+use FS::Record qw(dbdef);
+
+my $user = shift or die &usage;
+my $dbh = adminsuidsetup $user;
+
+my $schema = dbdef();
+
+#false laziness w/fs-setup
+my @tables = scalar(@ARGV)
+               ? @ARGV
+               : grep { ! /^h_/ } $schema->tables;
+foreach my $table ( @tables ) {
+  my $tableobj = $schema->table($table)
+    or die "unknown table $table (did you run dbdef-create?)\n";
+
+  my $primary_key = $tableobj->primary_key;
+  next unless $primary_key;
+
+  my $col = $tableobj->column($primary_key);
+
+
+  next unless uc($col->type) eq 'SERIAL'
+              || ( driver_name eq 'Pg'
+                     && defined($col->default)
+                     && $col->default =~ /^nextval\(/i
+                 )
+              || ( driver_name eq 'mysql'
+                     && defined($col->local)
+                     && $col->local =~ /AUTO_INCREMENT/i
+                 );
+
+  my $seq = "${table}_${primary_key}_seq";
+  if ( driver_name eq 'Pg'
+       && defined($col->default) 
+       && $col->default =~ /^nextval\('"(public\.)?(\w+_seq)"'::text\)$/
+     ) {
+    $seq = $2;
+  }
+
+  warn "fixing sequence for $table\n";
+
+
+  my $sql = "SELECT setval( '$seq',
+                            ( SELECT max($primary_key) FROM $table ) );";
+
+  #warn $col->default. " $seq\n$sql\n";
+  $dbh->do( $sql ) or die $dbh->errstr;
+
+}
+
+$dbh->commit or die $dbh->errstr;
+$dbh->disconnect or die $dbh->errstr;
+
+sub usage {
+  die "Usage:\n  fix-sequences user [ table table ... ] \n";
+}
+
diff --git a/bin/fs-setup b/bin/fs-setup
deleted file mode 100755 (executable)
index 9522ce3..0000000
+++ /dev/null
@@ -1,1033 +0,0 @@
-#!/usr/bin/perl -Tw
-#
-# $Id: fs-setup,v 1.96 2002-07-06 12:13:49 ivan Exp $
-
-#to delay loading dbdef until we're ready
-BEGIN { $FS::Record::setup_hack = 1; }
-
-use strict;
-use DBI;
-use DBIx::DBSchema 0.20;
-use DBIx::DBSchema::Table;
-use DBIx::DBSchema::Column;
-use DBIx::DBSchema::ColGroup::Unique;
-use DBIx::DBSchema::ColGroup::Index;
-use FS::UID qw(adminsuidsetup datasrc checkeuid getsecrets);
-use FS::Record;
-use FS::cust_main_county;
-use FS::raddb;
-use FS::part_bill_event;
-
-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);
-
-#needs to match FS::Record
-my($dbdef_file) = "/usr/local/etc/freeside/dbdef.". datasrc;
-
-###
-
-#print "\nEnter the maximum username length: ";
-#my($username_len)=&getvalue;
-my $username_len = 32; #usernamemax config file
-
-print "\n\n", <<END, ":";
-Freeside tracks the RADIUS User-Name, check attribute Password and
-reply attribute Framed-IP-Address for each user.  You can specify additional
-check and reply attributes (or you can add them later with the
-fs-radius-add-check and fs-radius-add-reply programs).
-
-First enter any additional RADIUS check attributes you need to track for each 
-user, separated by whitespace.
-END
-my @check_attributes = map { $attrib2db{lc($_)} or die "unknown attribute $_"; }
-                         split(" ",&getvalue);
-
-print "\n\n", <<END, ":";
-Now enter any additional reply attributes you need to track for each user,
-separated by whitespace.
-END
-my @attributes = map { $attrib2db{lc($_)} or die "unknown attribute $_"; }
-                   split(" ",&getvalue);
-
-print "\n\n", <<END, ":";
-Do you wish to enable the tracking of a second, separate shipping/service
-address?
-END
-my $ship = &_yesno;
-
-sub getvalue {
-  my($x)=scalar(<STDIN>);
-  chop $x;
-  $x;
-}
-
-sub _yesno {
-  print " [y/N]:";
-  my $x = scalar(<STDIN>);
-  $x =~ /^y/i;
-}
-
-###
-
-my($char_d) = 80; #default maxlength for text fields
-
-#my(@date_type)  = ( 'timestamp', '', ''     );
-my(@date_type)  = ( 'int', 'NULL', ''     );
-my(@perl_type) = ( 'text', 'NULL', ''  ); 
-my @money_type = ( 'decimal',   '', '10,2' );
-
-###
-# create a dbdef object from the old data structure
-###
-
-my(%tables)=&tables_hash_hack;
-
-#turn it into objects
-my($dbdef) = new DBIx::DBSchema ( map {  
-  my(@columns);
-  while (@{$tables{$_}{'columns'}}) {
-    my($name,$type,$null,$length)=splice @{$tables{$_}{'columns'}}, 0, 4;
-    push @columns, new DBIx::DBSchema::Column ( $name,$type,$null,$length );
-  }
-  DBIx::DBSchema::Table->new(
-    $_,
-    $tables{$_}{'primary_key'},
-    DBIx::DBSchema::ColGroup::Unique->new($tables{$_}{'unique'}),
-    DBIx::DBSchema::ColGroup::Index->new($tables{$_}{'index'}),
-    @columns,
-  );
-} (keys %tables) );
-
-my $cust_main = $dbdef->table('cust_main');
-unless ($ship) { #remove ship_ from cust_main
-  $cust_main->delcolumn($_) foreach ( grep /^ship_/, $cust_main->columns );
-} else { #add indices on ship_last and ship_company
-  push @{$cust_main->index->lol_ref}, ( ['ship_last'], ['ship_company'] ) 
-}
-
-#add radius attributes to svc_acct
-
-my($svc_acct)=$dbdef->table('svc_acct');
-
-my($attribute);
-foreach $attribute (@attributes) {
-  $svc_acct->addcolumn ( new DBIx::DBSchema::Column (
-    'radius_'. $attribute,
-    'varchar',
-    'NULL',
-    $char_d,
-  ));
-}
-
-foreach $attribute (@check_attributes) {
-  $svc_acct->addcolumn( new DBIx::DBSchema::Column (
-    'rc_'. $attribute,
-    'varchar',
-    'NULL',
-    $char_d,
-  ));
-}
-
-##make part_svc table (but now as object)
-#
-#my($part_svc)=$dbdef->table('part_svc');
-#
-##because of svc_acct_pop
-##foreach (grep /^svc_/, $dbdef->tables) { 
-##foreach (qw(svc_acct svc_acct_sm svc_charge svc_domain svc_wo)) {
-#foreach (qw(svc_acct svc_domain svc_forward svc_www)) {
-#  my($table)=$dbdef->table($_);
-#  my($col);
-#  foreach $col ( $table->columns ) {
-#    next if $col =~ /^svcnum$/;
-#    $part_svc->addcolumn( new DBIx::DBSchema::Column (
-#      $table->name. '__' . $table->column($col)->name,
-#      'varchar', #$table->column($col)->type, 
-#      'NULL',
-#      $char_d, #$table->column($col)->length,
-#    ));
-#    $part_svc->addcolumn ( new DBIx::DBSchema::Column (
-#      $table->name. '__'. $table->column($col)->name . "_flag",
-#      'char',
-#      'NULL',
-#      1,
-#    ));
-#  }
-#}
-
-#create history tables (false laziness w/create-history-tables)
-foreach my $table ( grep { ! /^h_/ } $dbdef->tables ) {
-  my $tableobj = $dbdef->table($table)
-    or die "unknown table $table";
-
-  die "unique->lol_ref undefined for $table"
-    unless defined $tableobj->unique->lol_ref;
-  die "index->lol_ref undefined for $table"
-    unless defined $tableobj->index->lol_ref;
-
-  my $h_tableobj = DBIx::DBSchema::Table->new( {
-    name        => "h_$table",
-    primary_key => 'historynum',
-    unique      => DBIx::DBSchema::ColGroup::Unique->new( [] ),
-    'index'     => DBIx::DBSchema::ColGroup::Index->new( [
-                     @{$tableobj->unique->lol_ref},
-                     @{$tableobj->index->lol_ref}
-                   ] ),
-    columns     => [
-                     DBIx::DBSchema::Column->new( {
-                       'name'    => 'historynum',
-                       'type'    => 'serial',
-                       'null'    => 'NOT NULL',
-                       'length'  => '',
-                       'default' => '',
-                       'local'   => '',
-                     } ),
-                     DBIx::DBSchema::Column->new( {
-                       'name'    => 'history_date',
-                       'type'    => 'int',
-                       'null'    => 'NULL',
-                       'length'  => '',
-                       'default' => '',
-                       'local'   => '',
-                     } ),
-                     DBIx::DBSchema::Column->new( {
-                       'name'    => 'history_user',
-                       'type'    => 'varchar',
-                       'null'    => 'NOT NULL',
-                       'length'  => '80',
-                       'default' => '',
-                       'local'   => '',
-                     } ),
-                     DBIx::DBSchema::Column->new( {
-                       'name'    => 'history_action',
-                       'type'    => 'varchar',
-                       'null'    => 'NOT NULL',
-                       'length'  => '80',
-                       'default' => '',
-                       'local'   => '',
-                     } ),
-                     map { $tableobj->column($_) } $tableobj->columns
-                   ],
-  } );
-  $dbdef->addtable($h_tableobj);
-}
-
-#important
-$dbdef->save($dbdef_file);
-&FS::Record::reload_dbdef($dbdef_file);
-
-###
-# create 'em
-###
-
-my($dbh)=adminsuidsetup $user;
-
-#create tables
-$|=1;
-
-foreach my $statement ( $dbdef->sql($dbh) ) {
-  $dbh->do( $statement )
-    or die "CREATE error: ". $dbh->errstr. "\ndoing statement: $statement";
-}
-
-#not really sample data (and shouldn't default to US)
-
-#cust_main_county
-
-#USPS state codes
-foreach ( qw(
-AL AK AS AZ AR CA CO CT DC DE FM FL GA GU HI ID IL IN IA KS KY LA
-ME MH MD MA MI MN MS MO MT NC ND NE NH NJ NM NV NY MP OH OK OR PA PW PR RI 
-SC SD TN TX UT VT VI VA WA WV WI WY AE AA AP
-) ) {
-  my($cust_main_county)=new FS::cust_main_county({
-    'state' => $_,
-    'tax'   => 0,
-    'country' => 'US',
-  });  
-  my($error);
-  $error=$cust_main_county->insert;
-  die $error if $error;
-}
-
-#AU "offical" state codes ala mark.williamson@ebbs.com.au (Mark Williamson)
-foreach ( qw(
-VIC NSW NT QLD TAS ACT WA SA
-) ) {
-  my($cust_main_county)=new FS::cust_main_county({
-    'state' => $_,
-    'tax'   => 0,
-    'country' => 'AU',
-  });  
-  my($error);
-  $error=$cust_main_county->insert;
-  die $error if $error;
-}
-
-#ISO 2-letter country codes (same as country TLDs) except US and AU
-foreach ( qw(
-AF AL DZ AS AD AO AI AQ AG AR AM AW AT AZ BS BH BD BB BY BE BZ BJ BM BT BO
-BA BW BV BR IO BN BG BF BI KH CM CA CV KY CF TD CL CN CX CC CO KM CG CK CR CI
-HR CU CY CZ DK DJ DM DO TP EC EG SV GQ ER EE ET FK FO FJ FI FR FX GF PF TF GA
-GM GE DE GH GI GR GL GD GP GU GT GN GW GY HT HM HN HK HU IS IN ID IR IQ IE IL
-IT JM JP JO KZ KE KI KP KR KW KG LA LV LB LS LR LY LI LT LU MO MK MG MW MY MV
-ML MT MH MQ MR MU YT MX FM MD MC MN MS MA MZ MM NA NR NP NL AN NC NZ NI NE NG
-NU NF MP NO OM PK PW PA PG PY PE PH PN PL PT PR QA RE RO RU RW KN LC VC WS SM
-ST SA SN SC SL SG SK SI SB SO ZA GS ES LK SH PM SD SR SJ SZ SE CH SY TW TJ TZ
-TH TG TK TO TT TN TR TM TC TV UG UA AE GB UM UY UZ VU VA VE VN VG VI WF EH
-YE YU ZR ZM ZW
-) ) {
-  my($cust_main_county)=new FS::cust_main_county({
-    'tax'   => 0,
-    'country' => $_,
-  });  
-  my($error);
-  $error=$cust_main_county->insert;
-  die $error if $error;
-}
-
-#billing events
-foreach my $aref ( 
-  [ 'COMP', 'Comp invoice', '$cust_bill->comp();', 30, 'comp' ],
-  [ 'CARD', 'Batch card', '$cust_bill->batch_card();', 40, 'batch-card' ],
-  [ 'BILL', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
-) {
-
-  my $part_bill_event = new FS::part_bill_event({
-    'payby' => $aref->[0],
-    'event' => $aref->[1],
-    'eventcode' => $aref->[2],
-    'seconds' => 0,
-    'weight' => $aref->[3],
-    'plan' => $aref->[4],
-  });
-  my($error);
-  $error=$part_bill_event->insert;
-  die $error if $error;
-
-}
-
-$dbh->commit or die $dbh->errstr;
-$dbh->disconnect or die $dbh->errstr;
-
-print "Freeside database initialized sucessfully\n";
-
-sub usage {
-  die "Usage:\n  fs-setup user\n"; 
-}
-
-###
-# Now it becomes an object.  much better.
-###
-sub tables_hash_hack {
-
-  #note that s/(date|change)/_$1/; to avoid keyword conflict.
-  #put a kludge in FS::Record to catch this or? (pry need some date-handling
-  #stuff anyway also)
-
-  my(%tables)=( #yech.}
-
-    'agent' => {
-      'columns' => [
-        'agentnum', 'int',            '',     '',
-        'agent',    'varchar',           '',     $char_d,
-        'typenum',  'int',            '',     '',
-        'freq',     'int',       'NULL', '',
-        'prog',     @perl_type,
-      ],
-      'primary_key' => 'agentnum',
-      'unique' => [],
-      'index' => [ ['typenum'] ],
-    },
-
-    'agent_type' => {
-      'columns' => [
-        'typenum',   'int',  '', '',
-        'atype',     'varchar', '', $char_d,
-      ],
-      'primary_key' => 'typenum',
-      'unique' => [],
-      'index' => [],
-    },
-
-    'type_pkgs' => {
-      'columns' => [
-        'typenum',   'int',  '', '',
-        'pkgpart',   'int',  '', '',
-      ],
-      'primary_key' => '',
-      'unique' => [ ['typenum', 'pkgpart'] ],
-      'index' => [ ['typenum'] ],
-    },
-
-    'cust_bill' => {
-      'columns' => [
-        'invnum',    'int',  '', '',
-        'custnum',   'int',  '', '',
-        '_date',     @date_type,
-        'charged',   @money_type,
-        'printed',   'int',  '', '',
-        'closed',    'char', 'NULL', 1,
-      ],
-      'primary_key' => 'invnum',
-      'unique' => [],
-      'index' => [ ['custnum'] ],
-    },
-
-    'cust_bill_event' => {
-      'columns' => [
-        'eventnum',    'int',  '', '',
-        'invnum',   'int',  '', '',
-        'eventpart',   'int',  '', '',
-        '_date',     @date_type,
-        'status', 'varchar', '', $char_d,
-        'statustext', 'text', 'NULL', '',
-      ],
-      'primary_key' => 'eventnum',
-      #no... there are retries now #'unique' => [ [ 'eventpart', 'invnum' ] ],
-      'unique' => [],
-      'index' => [ ['invnum'], ['status'] ],
-    },
-
-    'part_bill_event' => {
-      'columns' => [
-        'eventpart',    'int',  '', '',
-        'payby',       'char',  '', 4,
-        'event',       'varchar',           '',     $char_d,
-        'eventcode',    @perl_type,
-        'seconds',     'int', 'NULL', '',
-        'weight',      'int', '', '',
-        'plan',       'varchar', 'NULL', $char_d,
-        'plandata',   'text', 'NULL', '',
-        'disabled',     'char', 'NULL', 1,
-      ],
-      'primary_key' => 'eventpart',
-      'unique' => [],
-      'index' => [ ['payby'] ],
-    },
-
-    'cust_bill_pkg' => {
-      'columns' => [
-        'pkgnum',  'int', '', '',
-        'invnum',  'int', '', '',
-        'setup',   @money_type,
-        'recur',   @money_type,
-        'sdate',   @date_type,
-        'edate',   @date_type,
-      ],
-      'primary_key' => '',
-      'unique' => [ ['pkgnum', 'invnum'] ],
-      'index' => [ ['invnum'] ],
-    },
-
-    'cust_credit' => {
-      'columns' => [
-        'crednum',  'int', '', '',
-        'custnum',  'int', '', '',
-        '_date',    @date_type,
-        'amount',   @money_type,
-        'otaker',   'varchar', '', 8,
-        'reason',   'text', 'NULL', '',
-        'closed',    'char', 'NULL', 1,
-      ],
-      'primary_key' => 'crednum',
-      'unique' => [],
-      'index' => [ ['custnum'] ],
-    },
-
-    'cust_credit_bill' => {
-      'columns' => [
-        'creditbillnum', 'int', '', '',
-        'crednum',  'int', '', '',
-        'invnum',  'int', '', '',
-        '_date',    @date_type,
-        'amount',   @money_type,
-      ],
-      'primary_key' => 'creditbillnum',
-      'unique' => [],
-      'index' => [ ['crednum'], ['invnum'] ],
-    },
-
-    'cust_main' => {
-      'columns' => [
-        'custnum',  'int',  '',     '',
-        'agentnum', 'int',  '',     '',
-#        'titlenum', 'int',  'NULL',   '',
-        'last',     'varchar', '',     $char_d,
-#        'middle',   'varchar', 'NULL', $char_d,
-        'first',    'varchar', '',     $char_d,
-        'ss',       'char', 'NULL', 11,
-        'company',  'varchar', 'NULL', $char_d,
-        'address1', 'varchar', '',     $char_d,
-        'address2', 'varchar', 'NULL', $char_d,
-        'city',     'varchar', '',     $char_d,
-        'county',   'varchar', 'NULL', $char_d,
-        'state',    'varchar', 'NULL', $char_d,
-        'zip',      'varchar', '',     10,
-        'country',  'char', '',     2,
-        'daytime',  'varchar', 'NULL', 20,
-        'night',    'varchar', 'NULL', 20,
-        'fax',      'varchar', 'NULL', 12,
-        'ship_last',     'varchar', 'NULL', $char_d,
-#        'ship_middle',   'varchar', 'NULL', $char_d,
-        'ship_first',    'varchar', 'NULL', $char_d,
-        'ship_company',  'varchar', 'NULL', $char_d,
-        'ship_address1', 'varchar', 'NULL', $char_d,
-        'ship_address2', 'varchar', 'NULL', $char_d,
-        'ship_city',     'varchar', 'NULL', $char_d,
-        'ship_county',   'varchar', 'NULL', $char_d,
-        'ship_state',    'varchar', 'NULL', $char_d,
-        'ship_zip',      'varchar', 'NULL', 10,
-        'ship_country',  'char', 'NULL', 2,
-        'ship_daytime',  'varchar', 'NULL', 20,
-        'ship_night',    'varchar', 'NULL', 20,
-        'ship_fax',      'varchar', 'NULL', 12,
-        'payby',    'char', '',     4,
-        'payinfo',  'varchar', 'NULL', $char_d,
-        #'paydate',  @date_type,
-        'paydate',  'varchar', 'NULL', 10,
-        'payname',  'varchar', 'NULL', $char_d,
-        'tax',      'char', 'NULL', 1,
-        'otaker',   'varchar', '',     8,
-        'refnum',   'int',  '',     '',
-        'referral_custnum', 'int',  'NULL', '',
-        'comments', 'text', 'NULL', '',
-      ],
-      'primary_key' => 'custnum',
-      'unique' => [],
-      #'index' => [ ['last'], ['company'] ],
-      'index' => [ ['last'], [ 'company' ], [ 'referral_custnum' ] ],
-    },
-
-    'cust_main_invoice' => {
-      'columns' => [
-        'destnum',  'int',  '',     '',
-        'custnum',  'int',  '',     '',
-        'dest',     'varchar', '',  $char_d,
-      ],
-      'primary_key' => 'destnum',
-      'unique' => [],
-      'index' => [ ['custnum'], ],
-    },
-
-    'cust_main_county' => { #county+state+country are checked off the
-                            #cust_main_county for validation and to provide
-                            # a tax rate.
-      'columns' => [
-        'taxnum',   'int',   '',    '',
-        'state',    'varchar',  'NULL',    $char_d,
-        'county',   'varchar',  'NULL',    $char_d,
-        'country',  'char',  '', 2, 
-        'taxclass',   'varchar', 'NULL', $char_d,
-        'exempt_amount', @money_type,
-        'tax',      'real',  '',    '', #tax %
-      ],
-      'primary_key' => 'taxnum',
-      'unique' => [],
-  #    'unique' => [ ['taxnum'], ['state', 'county'] ],
-      'index' => [],
-    },
-
-    'cust_pay' => {
-      'columns' => [
-        'paynum',   'int',    '',   '',
-        #now cust_bill_pay #'invnum',   'int',    '',   '',
-        'custnum',  'int',    '',   '',
-        'paid',     @money_type,
-        '_date',    @date_type,
-        'payby',    'char',   '',     4, # CARD/BILL/COMP, should be index into
-                                         # payment type table.
-        'payinfo',  'varchar',   'NULL', 16,  #see cust_main above
-        'paybatch', 'varchar',   'NULL', $char_d, #for auditing purposes.
-        'closed',    'char', 'NULL', 1,
-      ],
-      'primary_key' => 'paynum',
-      'unique' => [],
-      'index' => [ [ 'custnum' ], [ 'paybatch' ] ],
-    },
-
-    'cust_bill_pay' => {
-      'columns' => [
-        'billpaynum', 'int',     '',   '',
-        'invnum',  'int',     '',   '',
-        'paynum',  'int',     '',   '',
-        'amount',  @money_type,
-        '_date',   @date_type
-      ],
-      'primary_key' => 'billpaynum',
-      'unique' => [],
-      'index' => [ [ 'paynum' ], [ 'invnum' ] ],
-    },
-
-    'cust_pay_batch' => { #what's this used for again?  list of customers
-                          #in current CARD batch? (necessarily CARD?)
-      'columns' => [
-        'paybatchnum',   'int',    '',   '',
-        'invnum',   'int',    '',   '',
-        'custnum',   'int',    '',   '',
-        'last',     'varchar', '',     $char_d,
-        'first',    'varchar', '',     $char_d,
-        'address1', 'varchar', '',     $char_d,
-        'address2', 'varchar', 'NULL', $char_d,
-        'city',     'varchar', '',     $char_d,
-        'state',    'varchar', 'NULL', $char_d,
-        'zip',      'varchar', '',     10,
-        'country',  'char', '',     2,
-#        'trancode', 'int', '', '',
-        'cardnum',  'varchar', '',     16,
-        #'exp',      @date_type,
-        'exp',      'varchar', '',     11,
-        'payname',  'varchar', 'NULL', $char_d,
-        'amount',   @money_type,
-      ],
-      'primary_key' => 'paybatchnum',
-      'unique' => [],
-      'index' => [ ['invnum'], ['custnum'] ],
-    },
-
-    'cust_pkg' => {
-      'columns' => [
-        'pkgnum',    'int',    '',   '',
-        'custnum',   'int',    '',   '',
-        'pkgpart',   'int',    '',   '',
-        'otaker',    'varchar', '', 8,
-        'setup',     @date_type,
-        'bill',      @date_type,
-        'susp',      @date_type,
-        'cancel',    @date_type,
-        'expire',    @date_type,
-        'manual_flag', 'char', 'NULL', 1,
-      ],
-      'primary_key' => 'pkgnum',
-      'unique' => [],
-      'index' => [ ['custnum'] ],
-    },
-
-    'cust_refund' => {
-      'columns' => [
-        'refundnum',    'int',    '',   '',
-        #now cust_credit_refund #'crednum',      'int',    '',   '',
-        'custnum',  'int',    '',   '',
-        '_date',        @date_type,
-        'refund',       @money_type,
-        'otaker',       'varchar',   '',   8,
-        'reason',       'varchar',   '',   $char_d,
-        'payby',        'char',   '',     4, # CARD/BILL/COMP, should be index
-                                             # into payment type table.
-        'payinfo',      'varchar',   'NULL', 16,  #see cust_main above
-        'paybatch',     'varchar',   'NULL', $char_d,
-        'closed',    'char', 'NULL', 1,
-      ],
-      'primary_key' => 'refundnum',
-      'unique' => [],
-      'index' => [],
-    },
-
-    'cust_credit_refund' => {
-      'columns' => [
-        'creditrefundnum', 'int',     '',   '',
-        'crednum',  'int',     '',   '',
-        'refundnum',  'int',     '',   '',
-        'amount',  @money_type,
-        '_date',   @date_type
-      ],
-      'primary_key' => 'creditrefundnum',
-      'unique' => [],
-      'index' => [ [ 'crednum', 'refundnum' ] ],
-    },
-
-
-    'cust_svc' => {
-      'columns' => [
-        'svcnum',    'int',    '',   '',
-        'pkgnum',    'int',    'NULL',   '',
-        'svcpart',   'int',    '',   '',
-      ],
-      'primary_key' => 'svcnum',
-      'unique' => [],
-      'index' => [ ['svcnum'], ['pkgnum'], ['svcpart'] ],
-    },
-
-    'part_pkg' => {
-      'columns' => [
-        'pkgpart',    'int',    '',   '',
-        'pkg',        'varchar',   '',   $char_d,
-        'comment',    'varchar',   '',   $char_d,
-        'setup',      @perl_type,
-        'freq',       'int', '', '',  #billing frequency (months)
-        'recur',      @perl_type,
-        'setuptax',  'char', 'NULL', 1,
-        'recurtax',  'char', 'NULL', 1,
-        'plan',       'varchar', 'NULL', $char_d,
-        'plandata',   'text', 'NULL', '',
-        'disabled',   'char', 'NULL', 1,
-        'taxclass',   'varchar', 'NULL', $char_d,
-      ],
-      'primary_key' => 'pkgpart',
-      'unique' => [],
-      'index' => [],
-    },
-
-#    'part_title' => {
-#      'columns' => [
-#        'titlenum',   'int',    '',   '',
-#        'title',      'varchar',   '',   $char_d,
-#      ],
-#      'primary_key' => 'titlenum',
-#      'unique' => [ [] ],
-#      'index' => [ [] ],
-#    },
-
-    'pkg_svc' => {
-      'columns' => [
-        'pkgpart',    'int',    '',   '',
-        'svcpart',    'int',    '',   '',
-        'quantity',   'int',    '',   '',
-      ],
-      'primary_key' => '',
-      'unique' => [ ['pkgpart', 'svcpart'] ],
-      'index' => [ ['pkgpart'] ],
-    },
-
-    'part_referral' => {
-      'columns' => [
-        'refnum',   'int',    '',   '',
-        'referral', 'varchar',   '',   $char_d,
-      ],
-      'primary_key' => 'refnum',
-      'unique' => [],
-      'index' => [],
-    },
-
-    'part_svc' => {
-      'columns' => [
-        'svcpart',    'int',    '',   '',
-        'svc',        'varchar',   '',   $char_d,
-        'svcdb',      'varchar',   '',   $char_d,
-        'disabled',   'char',  'NULL',   1,
-      ],
-      'primary_key' => 'svcpart',
-      'unique' => [],
-      'index' => [],
-    },
-
-    'part_svc_column' => {
-      'columns' => [
-        'columnnum',   'int',         '', '',
-        'svcpart',     'int',         '', '',
-        'columnname',  'varchar',     '', 64,
-        'columnvalue', 'varchar', 'NULL', $char_d,
-        'columnflag',  'char',    'NULL', 1, 
-      ],
-      'primary_key' => 'columnnum',
-      'unique' => [ [ 'svcpart', 'columnname' ] ],
-      'index' => [ [ 'svcpart' ] ],
-    },
-
-    #(this should be renamed to part_pop)
-    'svc_acct_pop' => {
-      'columns' => [
-        'popnum',    'int',    '',   '',
-        'city',      'varchar',   '',   $char_d,
-        'state',     'varchar',   '',   $char_d,
-        'ac',        'char',   '',   3,
-        'exch',      'char',   '',   3,
-        'loc',       'char',   'NULL',   4, #NULL for legacy purposes
-      ],
-      'primary_key' => 'popnum',
-      'unique' => [],
-      'index' => [ [ 'state' ] ],
-    },
-
-    'part_pop_local' => {
-      'columns' => [
-        'localnum',  'int',     '',     '',
-        'popnum',    'int',     '',     '',
-        'city',      'varchar', 'NULL', $char_d,
-        'state',     'char',    'NULL', 2,
-        'npa',       'char',    '',     3,
-        'nxx',       'char',    '',     3,
-      ],
-      'primary_key' => 'localnum',
-      'unique' => [],
-      'index' => [ [ 'npa', 'nxx' ], [ 'popnum' ] ],
-    },
-
-    'svc_acct' => {
-      'columns' => [
-        'svcnum',    'int',    '',   '',
-        'username',  'varchar',   '',   $username_len, #unique (& remove dup code)
-        '_password', 'varchar',   '',   50, #13 for encryped pw's plus ' *SUSPENDED* (mp5 passwords can be 34)
-        'sec_phrase', 'varchar',  'NULL',   $char_d,
-        'popnum',    'int',    'NULL',   '',
-        'uid',       'int', 'NULL',   '',
-        'gid',       'int', 'NULL',   '',
-        'finger',    'varchar',   'NULL',   $char_d,
-        'dir',       'varchar',   'NULL',   $char_d,
-        'shell',     'varchar',   'NULL',   $char_d,
-        'quota',     'varchar',   'NULL',   $char_d,
-        'slipip',    'varchar',   'NULL',   15, #four TINYINTs, bah.
-        'seconds',   'int', 'NULL',   '', #uhhhh
-        'domsvc',    'int', '',   '',
-      ],
-      'primary_key' => 'svcnum',
-      #'unique' => [ [ 'username', 'domsvc' ] ],
-      'unique' => [],
-      'index' => [ ['username'], ['domsvc'] ],
-    },
-
-#    'svc_acct_sm' => {
-#      'columns' => [
-#        'svcnum',    'int',    '',   '',
-#        'domsvc',    'int',    '',   '',
-#        'domuid',    'int', '',   '',
-#        'domuser',   'varchar',   '',   $char_d,
-#      ],
-#      'primary_key' => 'svcnum',
-#      'unique' => [ [] ],
-#      'index' => [ ['domsvc'], ['domuid'] ], 
-#    },
-
-    #'svc_charge' => {
-    #  'columns' => [
-    #    'svcnum',    'int',    '',   '',
-    #    'amount',    @money_type,
-    #  ],
-    #  'primary_key' => 'svcnum',
-    #  'unique' => [ [] ],
-    #  'index' => [ [] ],
-    #},
-
-    'svc_domain' => {
-      'columns' => [
-        'svcnum',    'int',    '',   '',
-        'domain',    'varchar',    '',   $char_d,
-        'catchall',  'int', 'NULL',    '',
-      ],
-      'primary_key' => 'svcnum',
-      'unique' => [ ['domain'] ],
-      'index' => [],
-    },
-
-    'domain_record' => {
-      'columns' => [
-        'recnum',    'int',     '',  '',
-        'svcnum',    'int',     '',  '',
-        'reczone',   'varchar', '',  $char_d,
-        'recaf',     'char',    '',  2,
-        'rectype',   'char',    '',  5,
-        'recdata',   'varchar', '',  $char_d,
-      ],
-      'primary_key' => 'recnum',
-      'unique'      => [],
-      'index'       => [ ['svcnum'] ],
-    },
-
-    'svc_forward' => {
-      'columns' => [
-        'svcnum',   'int',    '',  '',
-        'srcsvc',   'int',    '',  '',
-        'dstsvc',   'int',    '',  '',
-        'dst',      'varchar',    'NULL',  $char_d,
-      ],
-      'primary_key' => 'svcnum',
-      'unique'      => [],
-      'index'       => [ ['srcsvc'], ['dstsvc'] ],
-    },
-
-    'svc_www' => {
-      'columns' => [
-        'svcnum',   'int',    '',  '',
-        'recnum',   'int',    '',  '',
-        'usersvc',  'int',    '',  '',
-      ],
-      'primary_key' => 'svcnum',
-      'unique'      => [],
-      'index'       => [],
-    },
-
-    #'svc_wo' => {
-    #  'columns' => [
-    #    'svcnum',    'int',    '',   '',
-    #    'svcnum',    'int',    '',   '',
-    #    'svcnum',    'int',    '',   '',
-    #    'worker',    'varchar',   '',   $char_d,
-    #    '_date',     @date_type,
-    #  ],
-    #  'primary_key' => 'svcnum',
-    #  'unique' => [ [] ],
-    #  'index' => [ [] ],
-    #},
-
-    'prepay_credit' => {
-      'columns' => [
-        'prepaynum',   'int',     '',   '',
-        'identifier',  'varchar', '', $char_d,
-        'amount',      @money_type,
-        'seconds',     'int',     'NULL', '',
-      ],
-      'primary_key' => 'prepaynum',
-      'unique'      => [ ['identifier'] ],
-      'index'       => [],
-    },
-
-    'port' => {
-      'columns' => [
-        'portnum',  'int',     '',   '',
-        'ip',       'varchar', 'NULL', 15,
-        'nasport',  'int',     'NULL', '',
-        'nasnum',   'int',     '',   '',
-      ],
-      'primary_key' => 'portnum',
-      'unique'      => [],
-      'index'       => [],
-    },
-
-    'nas' => {
-      'columns' => [
-        'nasnum',   'int',     '',    '',
-        'nas',      'varchar', '',    $char_d,
-        'nasip',    'varchar', '',    15,
-        'nasfqdn',  'varchar', '',    $char_d,
-        'last',     'int',     '',    '',
-      ],
-      'primary_key' => 'nasnum',
-      'unique'      => [ [ 'nas' ], [ 'nasip' ] ],
-      'index'       => [ [ 'last' ] ],
-    },
-
-    'session' => {
-      'columns' => [
-        'sessionnum', 'int',       '',   '',
-        'portnum',    'int',       '',   '',
-        'svcnum',     'int',       '',   '',
-        'login',      @date_type,
-        'logout',     @date_type,
-      ],
-      'primary_key' => 'sessionnum',
-      'unique'      => [],
-      'index'       => [ [ 'portnum' ] ],
-    },
-
-    'queue' => {
-      'columns' => [
-        'jobnum', 'int', '', '',
-        'job', 'text', '', '',
-        '_date', 'int', '', '',
-        'status', 'varchar', '', $char_d,
-        'statustext', 'text', 'NULL', '',
-        'svcnum', 'int', 'NULL', '',
-      ],
-      'primary_key' => 'jobnum',
-      'unique'      => [],
-      'index'       => [ [ 'svcnum' ], [ 'status' ] ],
-    },
-
-    'queue_arg' => {
-      'columns' => [
-        'argnum', 'int', '', '',
-        'jobnum', 'int', '', '',
-        'arg', 'text', 'NULL', '',
-      ],
-      'primary_key' => 'argnum',
-      'unique'      => [],
-      'index'       => [ [ 'jobnum' ] ],
-    },
-
-    'queue_depend' => {
-      'columns' => [
-        'dependnum', 'int', '', '',
-        'jobnum', 'int', '', '',
-        'depend_jobnum', 'int', '', '',
-      ],
-      'primary_key' => 'dependnum',
-      'unique'      => [],
-      'index'       => [ [ 'jobnum' ], [ 'depend_jobnum' ] ],
-    },
-
-    'export_svc' => {
-      'columns' => [
-        'exportsvcnum' => 'int', '', '',
-        'exportnum'    => 'int', '', '',
-        'svcpart'      => 'int', '', '',
-      ],
-      'primary_key' => 'exportsvcnum',
-      'unique'      => [ [ 'exportnum', 'svcpart' ] ],
-      'index'       => [ [ 'exportnum' ], [ 'svcpart' ] ],
-    },
-
-    'part_export' => {
-      'columns' => [
-        'exportnum', 'int', '', '',
-        #'svcpart',   'int', '', '',
-        'machine', 'varchar', '', $char_d,
-        'exporttype', 'varchar', '', $char_d,
-        'nodomain',     'char', 'NULL', 1,
-      ],
-      'primary_key' => 'exportnum',
-      'unique'      => [],
-      'index'       => [ [ 'machine' ], [ 'exporttype' ] ],
-    },
-
-    'part_export_option' => {
-      'columns' => [
-        'optionnum', 'int', '', '',
-        'exportnum', 'int', '', '',
-        'optionname', 'varchar', '', $char_d,
-        'optionvalue', 'text', 'NULL', '',
-      ],
-      'primary_key' => 'optionnum',
-      'unique'      => [],
-      'index'       => [ [ 'exportnum' ], [ 'optionname' ] ],
-    },
-
-    'radius_usergroup' => {
-      'columns' => [
-        'usergroupnum', 'int', '', '',
-        'svcnum',       'int', '', '',
-        'groupname',    'varchar', '', $char_d,
-      ],
-      'primary_key' => 'usergroupnum',
-      'unique'      => [],
-      'index'       => [ [ 'svcnum' ], [ 'groupname' ] ],
-    },
-
-    'msgcat' => {
-      'columns' => [
-        'msgnum', 'int', '', '',
-        'msgcode', 'varchar', '', $char_d,
-        'locale', 'varchar', '', 16,
-        'msg', 'text', '', '',
-      ],
-      'primary_key' => 'msgnum',
-      'unique'      => [ [ 'msgcode', 'locale' ] ],
-      'index'       => [],
-    },
-
-    'cust_tax_exempt' => {
-      'columns' => [
-        'exemptnum', 'int', '', '',
-        'custnum',   'int', '', '',
-        'taxnum',    'int', '', '',
-        'year',      'int', '', '',
-        'month',     'int', '', '',
-        'amount',   @money_type,
-      ],
-      'primary_key' => 'exemptnum',
-      'unique'      => [ [ 'custnum', 'taxnum', 'year', 'month' ] ],
-      'index'       => [],
-    },
-
-
-
-  );
-
-  %tables;
-
-}
-
index 1d0053a..f946b05 100755 (executable)
@@ -13,10 +13,18 @@ END
 while (<>) {
   next if /^(#|\s*$|\$INCLUDE\s+)/;
   next if /^(VALUE|VENDOR|BEGIN\-VENDOR|END\-VENDOR)\s+/;
-  /^(ATTRIBUTE|ATTRIB_NMC)\s+([\w\-]+)\s+/ or die $_;
+  /^(ATTRIBUTE|ATTRIB_NMC)\s+([\w\-\/]+)\s+/ or die $_;
   $attrib = $2;
   $dbname = lc($2);
-  $dbname =~ s/\-/_/g;
+  $dbname =~ s/[\-\/]/_/g;
+  $dbname = substr($dbname,0,24);
+  while ( exists $hash{$dbname} ) {
+    #warn $dbname;
+    $dbname =~ s/(.)$//;
+    my $w = $1;
+    $w =~ tr/_a-z0-9/a-z0-9_/;
+    $dbname = "$dbname$w";
+  }
   $hash{$dbname} = $attrib;
   #print "$2\n";
 }
@@ -25,8 +33,10 @@ foreach ( keys %hash ) {
 #  print "$_\n" if length($_)>24;
 #  print substr($_,0,24),"\n" if length($_)>24; 
 #  $max = length($_) if length($_)>$max;
-#everything >24 is still unique, at least with freeradius comprehensive dataset
-  print "  '". substr($_,0,24). "' => '$hash{$_}',\n";
+# have to fudge things since everything >24 is *not* unique
+
+  #print "  '". substr($_,0,24). "' => '$hash{$_}',\n";
+  print "  '$_' => '$hash{$_}',\n";
 }
 
 print <<END;
index 475c9a6..3139e0a 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/perl
 
-foreach $file ( split(/\n/, `find . -depth -print | grep cgi\$`) ) {
+foreach $file ( split(/\n/, `find . -depth -print`) ) {
+  next unless $file =~ /(cgi|html)$/;
   open(F,$file) or die "can't open $file for reading: $!";
   @file = <F>;
   #print "$file ". scalar(@file). "\n";
@@ -8,6 +9,7 @@ foreach $file ( split(/\n/, `find . -depth -print | grep cgi\$`) ) {
   system("chmod u+w $file");
   open(W,">$file") or die "can't open $file for writing: $!";
   select W; $| = 1; select STDOUT;
+  $newline = ''; #avoid prepending extraneous newlines
   $all = join('',@file);
 
   $mode = 'html';
@@ -26,7 +28,7 @@ foreach $file ( split(/\n/, `find . -depth -print | grep cgi\$`) ) {
         #die;
         next;
       } elsif ( $all =~ /^<%(.*)$/s ) {
-        print W "\n";
+        print W $newline; $newline = "\n";
         $all = $1;
         $mode = 'perlc';
         next;
index fbf2737..093f8ba 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -Tw
-# $Id: passwd.import,v 1.5 2002-06-21 09:57:05 ivan Exp $
+# $Id: passwd.import,v 1.8 2003-06-12 14:08:00 ivan Exp $
 
 use strict;
 use vars qw(%part_svc);
@@ -14,7 +14,7 @@ use FS::part_svc;
 my $user = shift or die &usage;
 adminsuidsetup $user;
 
-push @FS::svc_acct::shells, qw(/bin/sync /sbin/shuddown /bin/halt); #others?
+push @FS::svc_acct::shells, qw(/bin/sync /sbin/shutdown /bin/halt /sbin/halt); #others?
 
 my($spooldir)="/usr/local/etc/freeside/export.". datasrc;
 
@@ -104,7 +104,13 @@ while (<PASSWD>) {
   });
   my($error);
   $error=$svc_acct->insert;
-  die $error if $error;
+  if ( $error ) {
+    if ( $error =~ /duplicate/i ) {
+      warn "$username: $error";
+    } else {
+      die "$username: $error";
+    }
+  }
 
 }
 
index f8e23cf..719d330 100755 (executable)
@@ -27,7 +27,7 @@ foreach my $msgcode ( keys %messages ) {
   }
 }
 
-print "Message catalog initialized sucessfully\n";
+#print "Message catalog initialized sucessfully\n";
 
 sub messages {
 
@@ -110,6 +110,14 @@ sub messages {
       'en_US' => 'Expired card',
     },
 
+    'daytime' => {
+      'en_US' => 'Day Phone',
+    },
+
+    'night' => {
+      'en_US' => 'Night Phone',
+    },
+
   );
 }
 
diff --git a/bin/postfix.export b/bin/postfix.export
new file mode 100755 (executable)
index 0000000..64d9738
--- /dev/null
@@ -0,0 +1,121 @@
+#!/usr/bin/perl -w
+
+use strict;
+#use File::Path;
+use File::Rsync;
+use Net::SSH qw(ssh);
+use FS::UID qw(adminsuidsetup datasrc);
+use FS::Record qw(qsearch); # qsearchs);
+use FS::part_export;
+#use FS::cust_pkg;
+use FS::cust_svc;
+#use FS::svc_domain;
+
+my $user = shift or die &usage;
+adminsuidsetup $user;
+
+my $spooldir = "/usr/local/etc/freeside/export.". datasrc. "/postfix";
+mkdir $spooldir, 0700 unless -d $spooldir;
+
+my @exports = qsearch('part_export', { 'exporttype' => 'postfix' } );
+
+my $rsync = File::Rsync->new({
+  rsh     => 'ssh',
+#  dry_run => 1,
+});
+
+foreach my $export ( @exports ) {
+
+  my $machine = $export->machine;
+  my $prefix = "$spooldir/$machine";
+  mkdir $prefix, 0700 unless -d $prefix;
+
+  #construct %domain hash
+
+  my $mydomain = $export->option('mydomain');
+  my %domain;
+  foreach my $svc_forward ( $export->svc_x ) {
+
+    my( $username, $domain );
+    my $srcsvc_acct = $svc_forward->srcsvc_acct;
+    if ( $srcsvc_acct ) {
+      ( $username, $domain ) = ( $srcsvc_acct->username, $srcsvc_acct->domain );
+    } elsif ( $svc_forward->src =~ /([^@]*)\@([^@]+)$/ ) {
+      ( $username, $domain ) = ( $1, $2 );
+    } else {
+      die "bad svc_forward record?  svcnum ". $svc_forward->svcnum. "\n";
+    }
+
+    my( $dusername, $ddomain );
+    my $dstsvc_acct = $svc_forward->dstsvc_acct;
+    if ( $dstsvc_acct ) {
+      $dusername = $dstsvc_acct->username;
+      $ddomain = $dstsvc_acct->domain;
+    } elsif ( $svc_forward->dst =~ /([^@]+)\@([^@]+)$/ ) {
+      ( $dusername, $ddomain ) = ( $1, $2 );
+    } else {
+      die "bad svc_forward record?  svcnum ". $svc_forward->svcnum. "\n";
+    }
+    my $dest;
+    if ( $ddomain eq $mydomain ) {
+      $dest = $dusername;
+    } else {
+      $dest = "$dusername\@$ddomain";
+    }
+
+    push @{$domain{$domain}{$username}}, $dest;
+
+  }
+
+  #write aliases
+
+  my $aliases = delete $domain{$mydomain};
+  open(ALIASES, ">$prefix/aliases") or die "can't open $prefix/aliases: $!";
+  foreach my $alias ( keys %$aliases ) {
+    print ALIASES "$alias: ". join(',', @{ $aliases->{$alias} } ). "\n";
+  }
+  close ALIASES;
+
+  #write virtual
+
+  open(VIRTUAL, ">$prefix/virtual") or die "can't open $prefix/virtual: $!";
+  foreach my $domain ( keys %domain ) {
+    print VIRTUAL "$domain DOMAIN\n";
+    #foreach my $virtual ( sort { $a ne '' <=> $b ne '' } keys %{$domain{$domain}} ) {
+    foreach my $virtual ( sort { ( ($b ne '') <=> ($a ne '') ) || $a cmp $b } keys %{$domain{$domain}} ) {
+      print VIRTUAL "$virtual\@$domain ".
+                    join(',', @{ $domain{$domain}{$virtual} } ). "\n";
+    }
+    print VIRTUAL "\n";
+  }
+  close VIRTUAL;
+
+  #rsync
+
+  my $user = $export->option('user');
+  $rsync->exec( {
+    src     => "$prefix/aliases",
+    dest    => "$user\@$machine:". $export->option('aliases'),
+  } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err);
+#  warn $rsync->out;
+
+  ssh("$user\@$machine", "newaliases");
+#  ssh("$user\@$machine", "postfix reload");
+
+  $rsync->exec( {
+    src     => "$prefix/virtual",
+    dest    => "$user\@$machine:". $export->option('virtual'),
+  } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err);
+#  warn $rsync->out;
+  ssh("$user\@$machine", "postmap hash:/etc/postfix/virtual");
+  ssh("$user\@$machine", "postfix reload");
+
+}
+
+# -----
+
+sub usage {
+  die "Usage:\n  postfix.export user\n"; 
+}
+
+
diff --git a/bin/sendmail.import b/bin/sendmail.import
new file mode 100644 (file)
index 0000000..8a9de9f
--- /dev/null
@@ -0,0 +1,176 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Term::Query qw(query);
+use Net::SCP qw(iscp);
+use FS::UID qw(adminsuidsetup datasrc);
+use FS::Record qw(qsearch qsearchs);
+##use FS::svc_acct_sm;
+#use FS::svc_domain;
+#use FS::domain_record;
+use FS::svc_acct;
+##use FS::part_svc;
+use FS::svc_forward;
+use FS::svc_domain;
+
+my $user = shift or die &usage;
+adminsuidsetup $user;
+
+#$FS::svc_Common::noexport_hack = 1;
+#$FS::domain_record::noserial_hack = 1;
+
+use vars qw($defaultdomain);
+$defaultdomain = 'surferz.net';
+
+use vars qw($svcpart $forward_svcpart);
+$svcpart = 2;
+$forward_svcpart = 4;
+
+use vars qw($spooldir);
+$spooldir = "/usr/local/etc/freeside/export.". datasrc. "/sendmail";
+mkdir $spooldir unless -d $spooldir;
+
+print "\n\n", <<END;
+Enter the location and name of your Sendmail aliases file, for example
+"mail.isp.com:/etc/mail/aliases"
+END
+my($aliases)=&getvalue(":");
+
+use vars qw($aliases_machine $aliases_prefix);
+$aliases_machine = (split(/:/, $aliases))[0];
+$aliases_prefix = "$spooldir/$aliases_machine";
+mkdir $aliases_prefix unless -d $aliases_prefix;
+
+#iscp("root\@$aliases","$aliases_prefix/aliases.import");
+iscp("ivan\@$aliases","$aliases_prefix/aliases.import");
+
+print "\n\n", <<END;
+Enter the location and name of your Sendmail virtusertable directory, for example
+"mail.isp.com:/etc/mail/virtusertable"
+END
+my($virtusertable)=&getvalue(":");
+
+use vars qw($virtusertable_machine $virtusertable_prefix);
+$virtusertable_machine = (split(/:/, $virtusertable))[0];
+$virtusertable_prefix = "$spooldir/$virtusertable_machine";
+mkdir $virtusertable_prefix unless -d $virtusertable_prefix;
+mkdir "$virtusertable_prefix/virtusertable.import"
+  unless -d "$virtusertable_prefix/virtusertable.import";
+
+#iscp("root\@$virtusertable/*","$aliases_prefix/virtusertable.import/");
+iscp("ivan\@$virtusertable/*","$aliases_prefix/virtusertable.import/");
+
+sub getvalue {
+  my $prompt = shift;
+  $^W=0; # Term::Query isn't -w-safe
+  my $return = query $prompt, '';
+  $^W=1;
+  $return;
+}
+
+print "\n\n";
+
+##
+
+foreach my $file ( 
+  "$aliases_prefix/aliases.import",
+  glob("$aliases_prefix/virtusertable.import/*"),
+) {
+
+  warn "importing $file\n";
+  
+  open(FILE,"<$file") or die $!;
+  while (<FILE>) {
+    next if /^\s*#/ || /^\s*$/; #skip comments & blank lines
+  
+    unless ( /^([\w\@\.\-]+)[:\s]\s*(.*\S)\s*$/ ) {
+      warn "Unparsable line: $_";
+      next;
+    }
+    my($rawusername, $rawdest) = ($1, $2);
+  
+    my($username, $domain);
+    if ( $rawusername =~ /^([\w\-\.\&]*)\@([\w\.\-]+)$/ ) {
+      $username = $1;
+      $domain = $2;
+    } elsif ( $rawusername =~ /\@/ ) {
+      die "Unparsable username: $rawusername\n";
+    } else {
+      $username = $rawusername;
+      $domain = $defaultdomain;
+    }
+  
+    #find svc_acct record or set $src
+    my($srcsvc, $src) = &svcnum_or_literal($username, $domain);
+
+    foreach my $dest ( split(/,/, $rawdest) ) {
+
+      my($dusername, $ddomain);
+      if ( $dest =~ /^([\w\-\.\&]+)\@([\w\.\-]+)$/ ) {
+        $dusername = $1;
+        $ddomain = $2;          
+      } elsif ( $dest =~ /\@/ ) {
+        die "Unparsable username: $dest\n";
+      } else {                 
+        $dusername = $dest;
+        $ddomain = $defaultdomain;
+      }
+      my($dstsvc, $dst) = &svcnum_or_literal($dusername, $ddomain);
+
+      my $svc_forward = new FS::svc_forward ({
+        svcpart => $forward_svcpart,
+        srcsvc => $srcsvc,
+        src    => $src,
+        dstsvc => $dstsvc,
+        dst    => $dst,
+      });
+      my $error = $svc_forward->insert;
+      #my $error = $svc_forward->check;
+      if ( $error ) {
+        die "$rawusername: $rawdest: $error\n";
+      }
+    }
+
+
+  } #next entry
+
+} #next file
+  
+##
+
+sub svcnum_or_literal {
+  my($username, $domain) = @_;
+
+  my $svc_domain = qsearchs('svc_domain', { 'domain' => $domain } );
+  my $domsvc = $svc_domain ? $svc_domain->svcnum : '';
+
+  my @svc_acct = grep { $_->cust_svc->svcpart == $svcpart }
+                   qsearch('svc_acct', {
+                     'username' => $username,
+                     'domsvc'   => $domsvc,
+                   });
+
+  if ( scalar(@svc_acct) > 1 ) {
+    die "multiple sources found for $username\@$domain !\n";
+  }
+
+  my( $svcnum, $literal ) = ('', '');
+  if ( @svc_acct ) {
+    my $svc_acct = $svc_acct[0];
+    $svcnum = $svc_acct->svcnum;
+  } else {
+    $literal = "$username\@$domain";
+  }
+
+  return( $svcnum, $literal );
+
+}
+
+sub usage {
+  die "Usage:\n\n  sendmail.import user\n";
+}
+
+
+
+
+
diff --git a/bin/shadow.reimport b/bin/shadow.reimport
new file mode 100755 (executable)
index 0000000..2c0ad1f
--- /dev/null
@@ -0,0 +1,98 @@
+#!/usr/bin/perl -Tw
+# $Id: shadow.reimport,v 1.1 2004-02-03 00:19:45 ivan Exp $
+
+use strict;
+use vars qw(%part_svc);
+use Term::Query qw(query);
+use Net::SCP qw(iscp);
+use FS::UID qw(adminsuidsetup datasrc);
+use FS::Record qw(qsearch qsearchs);
+use FS::svc_acct;
+use FS::part_svc;
+
+my $user = shift or die &usage;
+adminsuidsetup $user;
+
+push @FS::svc_acct::shells, qw(/bin/sync /sbin/shutdown /bin/halt /sbin/halt); #others?
+
+my($spooldir)="/usr/local/etc/freeside/export.". datasrc;
+
+#$FS::svc_acct::nossh_hack = 1;
+$FS::svc_Common::noexport_hack = 1;
+
+###
+
+%part_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_acct'});
+
+die "No services with svcdb svc_acct!\n" unless %part_svc;
+
+print "\n\n", &menu_svc, "\n", <<END;
+Enter part number to import.
+END
+my($shell_svcpart)=&getpart;
+
+print "\n\n", <<END;
+Enter the location and name of your _user_ shadow file, for example
+"mail.isp.com:/etc/shadow" or "bsd.isp.com:/etc/master.passwd"
+END
+my($loc_shadow)=&getvalue(":");
+iscp("root\@$loc_shadow", "$spooldir/shadow.import");
+
+sub menu_svc {
+  ( join "\n", map "$_: ".$part_svc{$_}->svc, sort keys %part_svc ). "\n";
+}
+sub getpart {
+  $^W=0; # Term::Query isn't -w-safe
+  my $return = query "Enter part number:", 'irk', [ keys %part_svc ];
+  $^W=1;
+  $return;
+}
+sub getvalue {
+  my $prompt = shift;
+  $^W=0; # Term::Query isn't -w-safe
+  my $return = query $prompt, '';
+  $^W=1;
+  $return;
+}
+
+print "\n\n";
+
+###
+
+open(SHADOW,"<$spooldir/shadow.import");
+
+my($line, $updated);
+while (<SHADOW>) {
+  $line++;
+  chop;
+  my($username,$password)=split(/:/);
+
+  my @svc_acct = grep { $_->cust_svc->svcpart == $shell_svcpart } 
+                 qsearch('svc_acct', { 'username' => $username } );
+
+  next unless @svc_acct;
+
+  if ( scalar(@svc_acct) > 1 ) {
+    warn "more than one $username found!\n";
+    next;
+  }
+
+  my $svc_acct = shift @svc_acct;
+
+  next if $svc_acct->_password eq $password;
+
+  my $new_svc_acct = new FS::svc_acct( { $svc_acct->hash } );
+  $new_svc_acct->_password($password);
+  #my $error = $new_svc_acct->replace($svc_acct);
+  #die "$username: $error" if $error;
+
+  $updated++;
+
+}
+
+warn "$updated of $line passwords changed\n";
+
+sub usage {
+  die "Usage:\n\n  shadow.reimport user\n";
+}
+
diff --git a/bin/svc_acct_sm.import b/bin/svc_acct_sm.import
deleted file mode 100755 (executable)
index b668405..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-#!/usr/bin/perl -Tw
-#
-# $Id: svc_acct_sm.import,v 1.10 2001-08-21 02:43:18 ivan Exp $
-
-use strict;
-use vars qw(%d_part_svc %m_part_svc);
-use Term::Query qw(query);
-use Net::SCP qw(iscp);
-use FS::UID qw(adminsuidsetup datasrc);
-use FS::Record qw(qsearch qsearchs);
-use FS::svc_acct_sm;
-use FS::svc_domain;
-use FS::svc_acct;
-use FS::part_svc;
-
-my $user = shift or die &usage;
-adminsuidsetup $user;
-
-my($spooldir)="/usr/local/etc/freeside/export.". datasrc;
-
-my(%mta) = (
-  1 => "qmail",
-  2 => "sendmail",
-);
-
-###
-
-%d_part_svc =
-  map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_domain'});
-%m_part_svc =
-  map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_acct_sm'});
-
-die "No services with svcdb svc_domain!\n" unless %d_part_svc;
-die "No services with svcdb svc_svc_acct_sm!\n" unless %m_part_svc;
-
-print "\n\n", 
-      ( join "\n", map "$_: ".$d_part_svc{$_}->svc, sort keys %d_part_svc ),
-      "\n\n";
-$^W=0; #Term::Query isn't -w-safe
-my $domain_svcpart = 
-  query "Enter part number for domains: ", 'irk', [ keys %d_part_svc ];
-$^W=1;
-
-print "\n\n", 
-      ( join "\n", map "$_: ".$m_part_svc{$_}->svc, sort keys %m_part_svc ),
-      "\n\n";
-$^W=0; #Term::Query isn't -w-safe
-my $mailalias_svcpart = 
-  query "Enter part number for mail aliases: ", 'irk', [ keys %m_part_svc ];
-$^W=1;
-
-print "\n\n", <<END;
-Select your MTA from the following list.
-END
-print join "\n", map "$_: $mta{$_}", sort keys %mta;
-print "\n\n";
-$^W=0; #Term::Query isn't -w-safe
-my $mta = query ":", 'irk', [ keys %mta ];
-$^W=1;
-
-if ( $mta{$mta} eq "qmail" ) {
-
-  print "\n\n", <<END;
-Enter the location and name of your qmail control directory, for example
-"mail.isp.com:/var/qmail/control"
-END
-  my($control)=&getvalue(":");
-  iscp("root\@$control/rcpthosts","$spooldir/rcpthosts.import");
-#  iscp("root\@$control/recipientmap","$spooldir/recipientmap.import");
-  iscp("root\@$control/virtualdomains","$spooldir/virtualdomains.import");
-
-#  print "\n\n", <<END;
-#Enter the name of the machine with your user .qmail files, for example
-#"mail.isp.com"
-#END
-#  print ":";
-#  my($shellmachine)=&getvalue;
-
-} elsif ( $mta{$mta} eq "sendmail" ) {
-
-  print "\n\n", <<END;
-Enter the location and name of your sendmail virtual user table, for example
-"mail.isp.com:/etc/virtusertable"
-END
-  my($virtusertable)=&getvalue(":");
-  iscp("root\@$virtusertable","$spooldir/virtusertable.import");
-
-  print "\n\n", <<END;
-Enter the location and name of your sendmail.cw file, for example
-"mail.isp.com:/etc/sendmail.cw"
-END
-  my($sendmail_cw)=&getvalue(":");
-  iscp("root\@$sendmail_cw","$spooldir/sendmail.cw.import");
-
-} else {
-  die "Unknown MTA!\n";
-}
-
-sub getvalue {
-  my $prompt = shift;
-  $^W=0; #Term::Query isn't -w-safe
-  my $data = query $prompt, '';
-  $^W=1;
-  $data;
-}
-
-print "\n\n";
-
-###
-
-$FS::svc_domain::whois_hack=1;
-$FS::svc_acct_sm::nossh_hack=1;
-
-if ( $mta{$mta} eq "qmail" ) {
-  open(RCPTHOSTS,"<$spooldir/rcpthosts.import")
-    or die "Can't open $spooldir/rcpthosts.import: $!";
-} elsif ( $mta{$mta} eq "sendmail" ) {
-  open(RCPTHOSTS,"<$spooldir/sendmail.cw.import")
-    or die "Can't open $spooldir/sendmail.cw.import: $!";
-} else {
-  die "Unknown MTA!\n";
-}
-
-my(%svcnum);
-
-while (<RCPTHOSTS>) {
-  next if /^(#|$)/;
-  next if $mta{$mta} eq 'sendmail' && /^\s*$/; #blank lines
-  /^\.?([\w\-\.]+)$/
-    #or do { warn "Strange rcpthosts/sendmail.cw line: $_"; next; };
-    or die "Strange rcpthosts/sendmail.cw line: $_";
-  my $domain = $1;
-  my($svc_domain);
-  unless ( $svc_domain = qsearchs('svc_domain', {'domain'=>$domain} ) ) {
-    $svc_domain = new FS::svc_domain ({
-      'domain'  => $domain,
-      'svcpart' => $domain_svcpart,
-      'action'  => 'N',
-    });
-    my $error = $svc_domain->insert;
-    #warn $error if $error;
-    die $error if $error;
-  }
-  $svcnum{$domain}=$svc_domain->svcnum;
-}
-close RCPTHOSTS; 
-
-#these two loops have enough similar parts they should probably be merged
-if ( $mta{$mta} eq "qmail" ) {
-
-  open(VD_FIX,">$spooldir/virtualdomains.FIX");
-  print VD_FIX "#!/usr/bin/perl\n";
-
-  open(VIRTUALDOMAINS,"<$spooldir/virtualdomains.import")
-    or die "Can't open $spooldir/virtualdomains.import: $!";
-  while (<VIRTUALDOMAINS>) {
-    next if /^#/;
-    /^\.?([\w\-\.]+):(\w+)(\-([\w\-\.]+))?$/
-      #or do { warn "Strange virtualdomains line: $_"; next; };
-      or die "Strange virtualdomains line: $_";
-    my($domain,$username,$dash_ext,$extension)=($1,$2,$3,$4);
-    $dash_ext ||= '';
-    $extension ||= '';
-    my($svc_acct)=qsearchs('svc_acct',{'username'=>$username});
-    unless ( $svc_acct ) {
-      #warn "Unknown user $username in virtualdomains; skipping\n";
-      #die "Unknown user $username in virtualdomains; skipping\n";
-      next;
-    }
-    if ( $domain ne $extension ) {
-      #warn "virtualdomains line $domain:$username$dash_ext changed to $domain:$username-$domain\n";
-      my($dir)=$svc_acct->dir;
-      my($qdomain)=$domain;
-      $qdomain =~ s/\./:/g; #see manpage for 'dot-qmail': EXTENSION ADDRESSES
-      #example to move .qmail files for virtual domains to their new location 
-      #dry run
-      #issh("root\@$shellmachine",'perl -e \'foreach $a (<'. $dir. '/.qmail'. $dash_ext. '-*>) { $old=$a; $a =~ s/\\.qmail'. $dash_ext. '\\-/\\.qmail\\-'. $qdomain. '\\-/; print " $old -> $a\n"; }\'');
-      #the real thing
-      #issh("root\@$shellmachine",'perl -e \'foreach $a (<'. $dir. '/.qmail'. $dash_ext. '-*>) { $old=$a; $a =~ s/\\.qmail'. $dash_ext. '\\-/\\.qmail\\-'. $qdomain. '\\-/; rename $old, $a; }\'');
-      print VD_FIX <<END;
-foreach \$file (<$dir/.qmail$dash_ext-*>) {
-  \$old = \$file;
-  \$file =~ s/\.qmail$dash_ext\-/\.qmail\-$qdomain\-/;
-  rename \$old, \$file;
-}
-END
-    }
-
-    unless ( exists $svcnum{$domain} ) {
-      my($svc_domain) = new FS::svc_domain ({
-        'domain'  => $domain,
-        'svcpart' => $domain_svcpart,
-        'action'  => 'N',
-      });
-      my $error = $svc_domain->insert;
-      #warn $error if $error;
-      die $error if $error;
-      $svcnum{$domain}=$svc_domain->svcnum;
-    }
-
-    my($svc_acct_sm)=new FS::svc_acct_sm ({
-      'domsvc'  => $svcnum{$domain},
-      'domuid'  => $svc_acct->uid,
-      'domuser' => '*',
-      'svcpart' => $mailalias_svcpart,
-    });
-    my($error)='';
-    $error=$svc_acct_sm->insert;
-    #warn $error if $error;
-    die $error, ", domain $domain" if $error;
-  }
-  close VIRTUALDOMAINS;
-  close VD_FIX;
-
-} elsif ( $mta{$mta} eq "sendmail" ) {
-
-  open(VIRTUSERTABLE,"<$spooldir/virtusertable.import")
-    or die "Can't open $spooldir/virtusertable.import: $!";
-  while (<VIRTUSERTABLE>) {
-    next if /^#/; #comments?
-    next if /^\s*$/; #blank lines
-    /^([\w\-\.]+)?\@([\w\-\.]+)\t+([\w\-\.]+)$/
-      #or do { warn "Strange virtusertable line: $_"; next; };
-      or die "Strange virtusertable line: $_";
-    my($domuser,$domain,$username)=($1,$2,$3);
-    my($svc_acct)=qsearchs('svc_acct',{'username'=>$username});
-    unless ( $svc_acct ) {
-      #warn "Unknown user $username in virtusertable";
-      die "Unknown user $username in virtusertable";
-      next;
-    }
-    my($svc_acct_sm)=new FS::svc_acct_sm ({
-      'domsvc'  => $svcnum{$domain},
-      'domuid'  => $svc_acct->uid,
-      'domuser' => $domuser || '*',
-      'svcpart' => $mailalias_svcpart,
-    });
-    my($error)='';
-    $error=$svc_acct_sm->insert;
-    #warn $error if $error;
-    die $error if $error;
-  }
-  close VIRTUSERTABLE;
-
-} else {
-  die "Unknown MTA!\n";
-}
-
-#open(RECIPIENTMAP,"<$spooldir/recipientmap.import");
-#close RECIPIENTMAP;
-
-print "\n\n", <<END if $mta{$mta} eq "qmail";
-Don\'t forget to run $spooldir/virtualdomains.FIX before using
-$spooldir/virtualdomains !
-END
-
-#
-
-sub usage {
-  die "Usage:\n\n  svc_acct_sm.import user\n";
-}
-
index 8597661..c13912c 100755 (executable)
@@ -43,12 +43,7 @@ foreach my $export ( @sysv_exports ) {
   chmod 0644, "$prefix/passwd";
   chmod 0600, "$prefix/shadow";
 
-  #false laziness with  freeside-sqlradius-reset and bind.export
-  my @svc_acct = 
-    map { qsearchs('svc_acct', { 'svcnum' => $_->svcnum } ) }
-      map { qsearch('cust_svc', { 'svcpart' => $_->svcpart } ) }
-        grep { qsearch('cust_svc', { 'svcpart' => $_->svcpart } ) }
-          $export->export_svc;
+  my @svc_acct = $export->svc_x;
 
   next unless @svc_acct;
 
diff --git a/conf/invoice_latex b/conf/invoice_latex
new file mode 100644 (file)
index 0000000..f63ab32
--- /dev/null
@@ -0,0 +1,155 @@
+%% file: Standard Multipage.tex\r
+%% Purpose: Multipage bill template for e-Bills\r
+%% \r
+%% Created by Mark Asplen-Taylor\r
+%% Asplen Management Ltd\r
+%% www.asplen.co.uk\r
+%%\r
+%% Modified for Freeside by Ivan Kohler\r
+%%\r
+%% Changes\r
+%%     0.1     4/12/00 Created\r
+%%     0.2     18/10/01        More fields added\r
+%%     1.0     16/11/01        RELEASED\r
+%%     1.2     16/10/02        Invoice number added\r
+%%     1.3     2/12/02 Logo graphic added\r
+%%     1.4     7/2/03  Multipage headers/footers added\r
+%%      n/a     10/12/03 forked for Freeside; checked into CVS\r
+%%\r
+\r
+\documentclass[letterpaper]{article}\r
+\r
+\usepackage{fancyhdr,lastpage,ifthen,longtable,afterpage}\r
+\usepackage{graphicx}                  % required for logo graphic\r
+\r
+\addtolength{\voffset}{-0.0in} % top margin to top of header\r
+\addtolength{\hoffset}{-0.60in}        %left margin on page\r
+\addtolength{\topmargin}{-0.6in}       % top margin to top of header\r
+\setlength{\headheight}{1in}           % height of header\r
+\setlength{\headsep}{0.5in}            % between header and text\r
+\addtolength{\textheight}{-0.4in}      % height of main text\r
+\r
+\addtolength{\textheight}{-0.5in}      % height of main text\r
+\setlength{\footskip}{0.5in}           % bottom of footer from bottom of text\r
+\r
+\addtolength{\textwidth}{2.1in}        % width of text\r
+\setlength{\oddsidemargin}{0in}        % odd page left margin\r
+\setlength{\evensidemargin}{0in}       % even page left margin\r
+\r
+\renewcommand{\headrulewidth}{0pt}\r
+\renewcommand{\footrulewidth}{1pt}\r
+\r
+                                               % New command for address lines i.e. skip them if blank\r
+\r
+\newcommand{\addressline}[1]{\ifthenelse{\equal{#1}{}}{}{#1\newline}}\r
+\newcommand{\dollar}[1][]{\symbol{36}} % Inserts dollar symbol\r
+\r
+\pagestyle{fancy}\r
+\r
+%% Font options are:\r
+%%     bch     Bitsream Charter\r
+%%     put     Utopia\r
+%%     phv     Adobe Helvetica\r
+%%     pnc     New Century Schoolbook\r
+%%     ptm     Times\r
+%%     pcr     Courier\r
+\r
+\renewcommand{\familydefault}{phv}             \r
+\r
+\begin{document}\r
+%\r
+%%     Headers and footers defined for the first page\r
+\fancyfoot[CO,CE]{\small{\r
+\begin{tabular}{c}\r
+$footer\r
+\end{tabular}}}\r
+%\r
+%%     The LH Heading comprising logo\r
+%%     UNCOMMENT the following FOUR lines and change the path if necssary to provide a logo\r
+\fancyhead[LO,LE]{\r
+\begin{tabular}{l}\r
+\includegraphics{/usr/local/etc/freeside/logo.eps}\r
+\end{tabular}}\r
+%\r
+%%     The Heading comprising isue date, customer ref & INVOICE name\r
+\fancyhead[RO,RE]{\r
+\begin{tabular}{rcl}\r
+Invoice date & & Invoice number \\\r
+\vspace{0.2cm}\r
+\textbf{$date} & & \textbf{$invnum} \\\hline\r
+\rule{0pt}{5ex} &~~ \huge{\textsc{Invoice}}& \\\r
+\vspace{-0.2cm}\r
+ & & \\\hline\r
+\end{tabular}}\r
+%\r
+%%     Header & footer changes for subsequent pages\r
+%\r
+\afterpage{ \fancyfoot[RO,RE]{\small{\thepage\ of \pageref{LastPage}}} }\r
+\afterpage{ \fancyfoot[CO,CE]{\small{$smallfooter}} }\r
+\afterpage{ \fancyhead[LO,LE]{\small{}} }\r
+\afterpage{ \fancyhead[RO,RE]{\small{\r
+\begin{tabular}{ll}\r
+Invoice date & Invoice number\\\r
+\textbf{$date} & \textbf{$invnum}\\\r
+\end{tabular}}} }\r
+%\r
+%\r
+\makebox{\r
+\begin{minipage}[t]{2.9in}\r
+\vspace{0.20in}\r
+\textbf{$payname}\\\r
+\addressline{$company}\r
+\addressline{$address1}\r
+\addressline{$address2}\r
+\addressline{$city, $state  $zip}\r
+\addressline{$country}\r
+\end{minipage}}\r
+\hfill\r
+\makebox{\r
+\begin{minipage}[t]{2.5in}\r
+\begin{flushright}\r
+Terms: $terms\\\r
+$po_line\\\r
+\end{flushright}\r
+\end{minipage}}\r
+\vspace{0.5cm}\r
+%\r
+\section*{\textsc{Charges}}\r
+\begin{longtable}{|c|l|c|r|r|}\r
+\hline\r
+\rule{0pt}{2.5ex}\r
+\makebox[1.4cm]{\textbf{Ref}} & \r
+\makebox[7.9cm][l]{\textbf{Description}} & \r
+\makebox[1.3cm][c]{\textbf{Quantity}} & \r
+\makebox[2.5cm][r]{\textbf{Unit Price}} & \r
+\makebox[2.5cm][r]{\textbf{Amount}} \\\r
+\hline\r
+\endfirsthead\r
+\multicolumn{5}{r}{\rule{0pt}{2.5ex}Continued from previous page}\\\r
+\hline\r
+\rule{0pt}{2.5ex}\r
+\makebox[1.4cm]{\textbf{Ref}} & \r
+\makebox[7.9cm][l]{\textbf{Description}} & \r
+\makebox[1.3cm][c]{\textbf{Quantity}} & \r
+\makebox[2.5cm][r]{\textbf{Unit Price}} & \r
+\makebox[2.5cm][r]{\textbf{Amount}} \\\r
+\hline\r
+\endhead\r
+\multicolumn{5}{r}{\rule{0pt}{2.5ex}/cont...}\\\r
+\endfoot\r
+%%TotalDetails\r
+ & \multicolumn{3}{l}{$total_item}    & $total_amount\\\r
+%%EndTotalDetails\r
+\hline\r
+\endlastfoot\r
+%%Detail\r
+\rule{0pt}{2.5ex}$ref & \r
+\begin{tabular}{l}\r
+$description\tabularnewline\r
+\end{tabular}\r
+& $quantity & \dollar $amount & \dollar $amount\\\hline\r
+%%EndDetail\r
+\end{longtable}\r
+\vfill\r
+$notes\r
+\end{document}\r
diff --git a/conf/invoice_latexfooter b/conf/invoice_latexfooter
new file mode 100644 (file)
index 0000000..110b1e6
--- /dev/null
@@ -0,0 +1,5 @@
+Ivan Kohler\\
+P.O. Box 1272\\
+Carnelian Bay, CA~~96140\\
+ivan@sisd.com~~~~+1 415 462 1624\\
+Freeside - open-source billing - http://www.sisd.com/freeside\\
diff --git a/conf/invoice_latexnotes b/conf/invoice_latexnotes
new file mode 100644 (file)
index 0000000..29e1731
--- /dev/null
@@ -0,0 +1,9 @@
+%%
+%%     Add any customer specific notes in here
+%%
+\section*{\textsc{Notes}}
+\begin{enumerate}
+\item PLEASE NOTE NEW ADDRESS BELOW!
+\item Please make your check payable to \textbf{Ivan Kohler}.
+\item If you have any questions please email or telephone.
+\end{enumerate}
diff --git a/conf/invoice_latexsmallfooter b/conf/invoice_latexsmallfooter
new file mode 100644 (file)
index 0000000..527c356
--- /dev/null
@@ -0,0 +1 @@
+Ivan Kohler~~~Freeside - open-source billing
diff --git a/conf/soadefaultttl b/conf/soadefaultttl
new file mode 100644 (file)
index 0000000..92f616f
--- /dev/null
@@ -0,0 +1 @@
+259200
diff --git a/conf/soaexpire b/conf/soaexpire
new file mode 100644 (file)
index 0000000..d235b91
--- /dev/null
@@ -0,0 +1 @@
+3600000
diff --git a/conf/soarefresh b/conf/soarefresh
new file mode 100644 (file)
index 0000000..9f35f8e
--- /dev/null
@@ -0,0 +1 @@
+10800
diff --git a/conf/soaretry b/conf/soaretry
new file mode 100644 (file)
index 0000000..bb08106
--- /dev/null
@@ -0,0 +1 @@
+1800
index 5734b1f..d8283b5 100644 (file)
@@ -1,4 +1,4 @@
-freeside (1.3.1-1) unstable; urgency=low
+freeside (1.4.1-1) unstable; urgency=low
 
   * Initial Release.
 
index 2f66fd3..d7873b2 100644 (file)
@@ -8,14 +8,14 @@ Standards-Version: 3.5.2
 Package: freeside
 Architecture: any
 Depends: freeside-lib
-Recommends: freeside-doc, freeside-ui-webui, libterm-query-perl
-Suggests: freeside-passwd-server, freeside-signup-server, freeside-session-server
+Recommends: freeside-doc, freeside-ui-web
+Suggests: freeside-selfservice-server
 Description: Billing and administration package for ISPs.
  Freeside is a billing and account administration package for ISPs.  It stores
  customer information in an SQL database, and will update UNIX passwd and
- shadow files, and configuration for sendmail, qmail, BIND and/or Apache.
It is also useful as a central database of accounts/domains/web-space
- for a large number of machines.
+ shadow files, RADIUS users file and SQL databases, and configuration for
sendmail, qmail, BIND and/or Apache.  It is also useful as a central database
of accounts/domains/web-space for a large number of machines.
 
 Package: freeside-doc
 Architecture: all
@@ -25,58 +25,35 @@ Description: Documentation for freeside
 
 Package: freeside-lib
 Architecture: all
-Depends: libdigest-md5-perl, liburi-perl, libhtml-parser-perl, libnet-perl, liblocale-codes-perl, libnet-whois-perl, libwww-perl, libbusiness-creditcard-perl, mailtools, libtimedate-perl, libdate-manip-perl, libfile-counterfile-perl, libfreezethaw-perl, libtext-template-perl, libdbd-pg-perl
+Depends: libmime-base64-perl, libdigest-md5-perl, liburi-perl, libhtml-tagset-perl, libhtml-parser-perl, libnet-perl, liblocale-codes-perl, libnet-whois-perl, libwww-perl, libbusiness-creditcard-perl, libmailtools-perl, libtimedate-perl, libdate-manip-perl, libfile-counterfile-perl, libfreezethaw-perl, libtext-template-perl, libdbd-pg-perl, libdbix-datasource-perl, libdbix-dbschema-perl, libnet-ssh-perl, libnet-scp-perl, libapache-asp-perl, libtie-ixhash-perl, libtime-duration-perl, libhtml-widgets-selectlayers-perl, libstorable-perl, libapache-dbi-perl
 Description: Freeside libraries and extension API
  This package contains the libraries which implement the business logic and
  backend functions of Freeside, a billing and account administration package
  for ISPs.  This package also contains the manual pages for the library API.
+ (? like a libmodule-perl package)
 
 Package: freeside-ui-web
 Architecture: all
-Depends: libstring-approx-perl, freeside-lib, libapache-mod-perl|apache-perl
+Depends: libhtml-mason-perl, libstring-approx-perl, freeside-lib, libapache-mod-perl|apache-perl
 Suggests: libapache-mod-ssl|apache-ssl
 Description: Easy-to-use web interface for Freeside
  This package contains the web interface for Freeside, a billing and account
  administration package for ISPs.  This is what sales or support folks will
  typically use to add new accounts, edit exiting accounts and so on.
 
-Package: freeside-passwd-server
+Package: freeside-selfservice-server
 Architecture: all
-Depends: freeside-lib
-Description: Freeside password server 
- This component of Freeside, a billing and account administration package for
- ISPs, 
-
-Package: freeside-passwd-client
-Architecture: all
-Depends: 
-Description: 
- <rar>
-
-Package: freeside-signup-server
-Architecture: all
-Depends: freeside-lib
+Depends: freeside-lib, libnet-ssh-perl, ssh
 Description:
- <rar>
+ This package contains the server side of the customer self-service interface.
+ It is installed on a private backend machine, and opens an outgoing ssh
+ connection to one or more public web server(s).
 
-Package: freeside-signup-client
+Package: freeside-selfservice-client
 Architecture: all
-Depends: 
+Depends: libstorable-perl, libhttp-browserdetect-perl, libbusiness-creditcard-perl, ssh
 Description:
- <rar>
+ This package contains the client side of the customer self-service interface.
+ It is typically installed on a public webserver and interfaces with
+ freeside-selfservice-server installed on a private backend machine.
 
-Package: freeside-signup-client-webui
-Architecture: all
-Depends: freeside-signup-client-lib, httpd
-Description: 
- <rar>
-
-Package: freeside-session-server
-Architecture: all
-Depends: freeside-lib
-Description:
- <rar>
-
-Package: freeside-session-client
-Architecture: all
-Depends: ssh
index 00942fd..ca58d4b 100644 (file)
@@ -42,9 +42,15 @@ sub myexport_queue {
 }
 
 sub myexport_insert { #subroutine, not method
+  my( $username, $password ) = @_;
+  #do things with $username and $password
 }
+
 sub myexport_replace { #subroutine, not method
 }
+
 sub myexport_delete { #subroutine, not method
+  my( $username ) = @_;
+  #do things with $username
 }
 
index ebf7299..7f7ef4b 100644 (file)
@@ -6,7 +6,7 @@ use vars qw(@ISA);
 use FS::svc_Common;
 use FS::cust_svc;
 
-@ISA = qw(svc_Common);
+@ISA = qw(FS::svc_Common);
 
 =head1 NAME
 
@@ -141,7 +141,7 @@ sub check {
   my $part_svc = $x;
 
 
-  ''; #no error
+  $self->SUPER::check;
 }
 
 =back
diff --git a/eg/vpopmailrestart b/eg/vpopmailrestart
deleted file mode 100755 (executable)
index c716e2e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-for domain in /home/vpopmail/domains/*
-do
-  /home/vpopmail/bin/vmkpasswd `/bin/basename $domain`
-done
-
-/var/qmail/bin/qmail-newu
-
-killall -HUP qmail-send
-
diff --git a/etc/abbr_state.txt b/etc/abbr_state.txt
new file mode 100644 (file)
index 0000000..7e4f57f
--- /dev/null
@@ -0,0 +1,72 @@
+State/Possession               Abbreviation
+
+ALABAMA                         AL
+ALASKA                          AK
+AMERICAN SAMOA                  AS
+ARIZONA                         AZ
+ARKANSAS                        AR
+CALIFORNIA                      CA
+COLORADO                        CO
+CONNECTICUT                     CT
+DELAWARE                        DE
+DISTRICT OF COLUMBIA            DC
+FEDERATED STATES OF MICRONESIA  FM
+FLORIDA                         FL
+GEORGIA                         GA
+GUAM                            GU
+HAWAII                          HI
+IDAHO                           ID
+ILLINOIS                        IL
+INDIANA                         IN
+IOWA                            IA
+KANSAS                          KS
+KENTUCKY                        KY
+LOUISIANA                       LA
+MAINE                           ME
+MARSHALL ISLANDS                MH
+MARYLAND                        MD
+MASSACHUSETTS                   MA
+MICHIGAN                        MI
+MINNESOTA                       MN
+MISSISSIPPI                     MS
+MISSOURI                        MO
+MONTANA                         MT
+NEBRASKA                        NE
+NEVADA                          NV
+NEW HAMPSHIRE                   NH
+NEW JERSEY                      NJ
+NEW MEXICO                      NM
+NEW YORK                        NY
+NORTH CAROLINA                  NC
+NORTH DAKOTA                    ND
+NORTHERN MARIANA ISLANDS        MP
+OHIO                            OH
+OKLAHOMA                        OK
+OREGON                          OR
+PALAU                           PW
+PENNSYLVANIA                    PA
+PUERTO RICO                     PR
+RHODE ISLAND                    RI
+SOUTH CAROLINA                  SC
+SOUTH DAKOTA                    SD
+TENNESSEE                       TN
+TEXAS                           TX
+UTAH                            UT
+VERMONT                         VT
+VIRGIN ISLANDS                  VI
+VIRGINIA                        VA
+WASHINGTON                      WA
+WEST VIRGINIA                   WV
+WISCONSIN                       WI
+WYOMING                         WY
+
+
+Military "State"               Abbreviation
+
+Armed Forces Africa            AE
+Armed Forces Americas          AA
+(except Canada)
+Armed Forces Canada            AE
+Armed Forces Europe            AE
+Armed Forces Middle East       AE
+Armed Forces Pacific           AP
diff --git a/etc/acp_logfile-parse b/etc/acp_logfile-parse
deleted file mode 100755 (executable)
index 5e25899..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-#!/usr/bin/perl
-
-###
-# WHO WROTE THIS???
-###
-
-#require "perldb.pl";
-
-#    Compute SLIP/PPP log times
-#     Arguments    -a   Process entire file with totals
-#                  -t   Process only totals
-#                  -f   File to be processed if not current
-#                  -d   processing start date (default is entire file)
-#                  -l   to return all totals for dayuse
-#                  -w   name of tmp work file for dayuse
-#                  user names
-
-require "time.pl";
-
-$space='        ';
-
-unless (@ARGV[0]) {
-       print "Missing Arguments\n";
-       print    "-a - entire file\n";
-       print    "-t - totals only\n";
-       print    "-f - file name to be processed\n";
-       print    "-d - processing start date (yymmdd)\n";
-       print    "-l - return totals for dayuse\n";
-       print    "-w - tmp work file for dayuse\n";
-       exit;
-}     # end if test for missing arguments
-
-$infile = "/usr/annex/acp_logfile";
-$tmpfile = "/tmp/ppp";
-$n = $#ARGV;
-$start_yymmdd = "";
-for ($i = 0; $i <= $n; $i++) {
-    if ($ARGV[$i] eq "-a") {
-             $allflag = "true";
-        }
-       elsif ($ARGV[$i] eq "-t") {
-                      $totalflag = "true";
-             }
-       elsif ($ARGV[$i] eq "-f") {
-        $i++;
-          $infile = $ARGV[$i];
-             }
-        elsif ($ARGV[$i] eq "-d") {
-          $i++;
-          $start_yymmdd = $ARGV[$i];
-          }   #end start yymmdd
-        elsif ($ARGV[$i] eq "-l") {
-           $logflag = "true";
-           $totalflag = "true";
-         }  #  end log 
-       elsif ($ARGV[$i] eq "-w") {
-        $i++;
-          $tmpfile = $ARGV[$i];
-             } #  end tmp file 
-        else    {
-            ($arg_user,$arg_yymmdd) = split (/:/, $ARGV[$i]);
-                 $ip_user_date {$arg_user} = $ARGV[$i];
-             $userflag = "true";
-                }   # end else
- } # end for 1 = 1 to n
-
-open (IN,$infile)
-        || die "Can't open acp_logfile";
-
-NEXTUSER: while (<IN>) {        
-        chop;
-        ($add,$ether,$port,$date,$time,$type,$action,$user) = split(/:/);
-
-        if ($logflag) {
-          $start_yymmdd = '';
-          if ($ip_user_date{$user}) {
-             ($ip_user, $start_yymmdd) = 
-                      split (/:/, $ip_user_date{$user});
-           }  # end get date
-        }   #  end log flag
-        if ($start_yymmdd) {
-           if ($date < $start_yymmdd) {
-               next NEXTUSER;
-           }  #end date compare
-        }  #end if date
-        if ($userflag){
-          if (!$ip_user_date{$user}) {
-               next NEXTUSER;
-          }  #  end user test
-        }  #   end by user or all
-        if (($totalflag) ||
-           ($allflag) ||
-           ($ip_user_date{$user})) {
-         if (($type eq 'ppp') || ($type eq 'slip'))  {
-
-            if ($action eq 'login') {
-                        $login{$user} = "$time:$date";
-
-                }
-                  elsif ($action eq 'logout') {
-                     if (!$login{$user}) {
-                          $login{$user} = "010101:$date";
-                      } #end pad user if carry over
-                        ($stime,$sdate) = split(':',$login{$user});
-                        $start = &annex2sec($stime);
-                        $end = &annex2sec($time);
-                        
-                        #If we went through midnight, add a day;
-                        if ($end < $start) {$end += 86400;}
-                        $timeon = $end - $start;
-
-                        $elapsed{$user} += $timeon;
-                        
-                      if (!$totalflag) {
-                        print (&fmt_user($user),
-                              '  ', &fmt_date($sdate), '  In: ', 
-                                &fmt_time($stime),'  Out: ',
-                                &fmt_time($time),
-                       '  Elapsed: ', &fmt_sec($timeon), "\n");
-                      }  # end total test
-                }  #end elsif action
-        }  #  type = ppp of slip
-    }  #  check arguments
-} 
-close IN;
-
-if ($logflag) {
-    open (TMPPPP, ">$tmpfile")
-               || die "Can't open ppp tmp file";
-    foreach $user ( sort((keys(%elapsed))) ) {
-        $log_time = &fmt_sec($elapsed{$user});
-        $tmp = join (':',
-                    $user, 
-                    $log_time);
-        print (TMPPPP "$tmp\n");
-    }
-    close (TMPPPP);
-}
-    else {
-        print "\n\nTotal Time On For Period:\n";
-        print     "-------------------------\n";
-
-        foreach $user ( sort((keys(%elapsed))) ) {
-           print (&fmt_user($user), "  ",&fmt_sec($elapsed{$user}), "\n");
-        }
-    }
-exit(0);
-
-#-------------------------------------------------------
-#--------------- Subroutines Start Here ----------------
-#-------------------------------------------------------
-
-sub annex2sec {
-        local($time) = @_;
-        return( &time2sec( &break_annex($time) ) );
-}
-
-sub fmt_date {
-        local($date) = @_;
-
-        return( substr($date,2,2).'/'.substr($date,4,2).'/'.substr($date,0,2) );
-}
-
-sub fmt_time {
-        local($time) = @_;
-        local($s,$m,$h) = &break_annex($time);
-        return ("$h:$m:$s");
-}
-
-
-sub break_annex {
-        local($time) = @_;
-        local($h,$m,$s);
-
-        $h=substr($time,0,2);
-        $m=substr($time,2,2);
-        $s=substr($time,4,2);
-
-        return ($s,$m,$h);
-}       
-
-sub fmt_sec {
-        local(@t) = &sec2time(@_);
-        @t[2] += (@t[3]*24);
-
-        foreach $a (@t) {
-                if ($a < 10) {$a = "0$a";}
-        }
-
-        return ("@t[2]:@t[1]:@t[0]");
-}
-
-sub fmt_user {
-        local($user) = @_;
-        return( $user.substr($space,0,8 - length($user) ).'  ' );
-}
-
diff --git a/etc/example-direct-cardin b/etc/example-direct-cardin
deleted file mode 100755 (executable)
index 1a40972..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/local/bin/perl
-
-###
-# THIS IS FROM CYBERCASH (is there a newer version?)
-###
-
-$paymentserverhost = 'localhost';
-$paymentserverport = 8000;
-$paymentserversecret = 'two-turntables';
-use CCLib qw(sendmserver);
-
-# first lets fake up some data 
-# use time of day and pid to give me my pretend
-# order number
-# you obviously need to get real data from somewhere...
-
-$oid = "test$$"; #fake order number.
-$amount = 'usd 42.42';
-$ramount = 'usd 24.24';
-$pan = '4111111111111111';
-$name = 'John Q. Doe';
-$addr = '17 Richard Rd.';
-$city = 'Ivyland';
-$state = 'PA';
-$zip = '18974';
-$country = 'USA';
-$exp = '7/97';
-
-
-%result = &sendmserver('mauthcapture', 
-                       'Order-ID', $oid,
-                      'Amount', $amount,
-                      'Card-Number', $pan,
-                      'Card-Name', $name,
-                      'Card-Address', $addr,
-                      'Card-City', $city,
-                      'Card-State', $state,
-                      'Card-Zip', $zip,
-                      'Card-Country', $country,
-                      'Card-Exp', $exp);
-
-#
-# just dump results to stdout.
-# you should process them...
-# to allow results to affect operation of your fulfillment...
-#
-foreach (keys(%result)) {
-   print " $_ ==> $result{$_}\n";
-}
-
-print "\n";
-
-exit;
-
-$trans=$result{'MTransactionNumber'};
-$code=$result{'MRetrievalCode'};
-
-%result = &sendmserver('return',
-                        'Order-ID', $oid,
-                       'Return-Amount',$ramount,
-                       'Amount',$amount,
-                       );
-
-foreach (keys(%result)) {
-   print " $_ ==> $result{$_}\n";
-}
-
index 7c68e78..4aef4cf 100755 (executable)
@@ -1,15 +1,13 @@
 #!/bin/sh
 
+kill `cat /var/run/freeside-selfservice-server.fs_selfservice.pid`
+
 ( cd ..; make deploy; cd fs_selfservice )
 
 cd FS-SelfService
 perl Makefile.PL && make && make install
 
-cd ..
-kill `cat /var/run/freeside-selfservice-server.ivan.pid`; sleep 3
-./freeside-selfservice-server ivan localhost
-
-cp /home/ivan/freeside_current/fs_selfservice/FS-SelfService/cgi/* /var/www/MyAccount
+cp /home/ivan/freeside/fs_selfservice/FS-SelfService/cgi/* /var/www/MyAccount
 chown freeside /var/www/MyAccount/selfservice.cgi
-chmod 4755 /var/www/MyAccount/selfservice.cgi
-ln -s /var/www/MyAccount/selfservice.cgi /var/www/MyAccount/index.cgi
+chmod 755 /var/www/MyAccount/selfservice.cgi
+ln -s /var/www/MyAccount/selfservice.cgi /var/www/MyAccount/index.cgi || true
index da0a0aa..e5cbd1a 100644 (file)
@@ -8,7 +8,9 @@ WriteMakefile(
     'INSTALLSCRIPT'     => '/usr/local/sbin',
     'INSTALLSITEBIN'    => '/usr/local/sbin',
     'PERM_RWX'          => '750',
-    'PREREQ_PM'                => {}, # e.g., Module::Name => 1.1
+    'PREREQ_PM'                => {
+                             'Storable' => 0,
+                           }, # e.g., Module::Name => 1.1
     ($] >= 5.005 ?    ## Add these new keywords supported since 5.005
       (ABSTRACT_FROM => 'SelfService.pm', # retrieve abstract from module
        AUTHOR     => 'Ivan Kohler <ivan-freeside-selfservice@420.am>') : ()),
index 9019ea4..715f935 100644 (file)
@@ -1,7 +1,7 @@
 package FS::SelfService;
 
 use strict;
-use vars qw($VERSION @ISA @EXPORT_OK $socket %autoload );
+use vars qw($VERSION @ISA @EXPORT_OK $socket %autoload $tag);
 use Exporter;
 use Socket;
 use FileHandle;
@@ -14,14 +14,25 @@ $VERSION = '0.03';
 @ISA = qw( Exporter );
 
 $socket =  "/usr/local/freeside/selfservice_socket";
+$socket .= '.'.$tag if defined $tag && length($tag);
 
+#maybe should ask ClientAPI for this list
 %autoload = (
-  'passwd'        => 'passwd/passwd',
-  'chfn'          => 'passwd/passwd',
-  'chsh'          => 'passwd/passwd',
-  'login'         => 'MyAccount/login',
-  'customer_info' => 'MyAccount/customer_info',
-  'invoice'       => 'MyAccount/invoice',
+  'passwd'          => 'passwd/passwd',
+  'chfn'            => 'passwd/passwd',
+  'chsh'            => 'passwd/passwd',
+  'login'           => 'MyAccount/login',
+  'customer_info'   => 'MyAccount/customer_info',
+  'edit_info'       => 'MyAccount/edit_info',
+  'invoice'         => 'MyAccount/invoice',
+  'cancel'          => 'MyAccount/cancel',
+  'payment_info'    => 'MyAccount/payment_info',
+  'process_payment' => 'MyAccount/process_payment',
+  'list_pkgs'       => 'MyAccount/list_pkgs',
+  'order_pkg'       => 'MyAccount/order_pkg',
+  'cancel_pkg'      => 'MyAccount/cancel_pkg',
+  'signup_info'     => 'Signup/signup_info',
+  'new_customer'    => 'Signup/new_customer',
 );
 @EXPORT_OK = keys %autoload;
 
@@ -35,29 +46,6 @@ $ENV{'BASH_ENV'} = '';
 my $freeside_uid = scalar(getpwnam('freeside'));
 die "not running as the freeside user\n" if $> != $freeside_uid;
 
-=head1 NAME
-
-FS::SelfService - Freeside self-service API
-
-=head1 SYNOPSIS
-
-=head1 DESCRIPTION
-
-Use this API to implement your own client "self-service" module.
-
-If you just want to customize the look of the existing "self-service" module,
-see XXXX instead.
-
-=head1 FUNCTIONS
-
-=over 4
-
-=item passwd
-
-Returns the empty value on success, or an error message on errors.
-
-=cut
-
 foreach my $autoload ( keys %autoload ) {
 
   my $eval =
@@ -98,6 +86,554 @@ sub simple_packet {
   $return;
 }
 
+=head1 NAME
+
+FS::SelfService - Freeside self-service API
+
+=head1 SYNOPSIS
+
+  # password and shell account changes
+  use FS::SelfService qw(passwd chfn chsh);
+
+  # "my account" functionality
+  use FS::SelfService qw( login customer_info invoice cancel payment_info process_payment );
+
+  my $rv = login( { 'username' => $username,
+                    'domain'   => $domain,
+                    'password' => $password,
+                  }
+                );
+
+  if ( $rv->{'error'} ) {
+    #handle login error...
+  } else {
+    #successful login
+    my $session_id = $rv->{'session_id'};
+  }
+
+  my $customer_info = customer_info( { 'session_id' => $session_id } );
+
+  #payment_info and process_payment are available in 1.5+ only
+  my $payment_info = payment_info( { 'session_id' => $session_id } );
+
+  #!!! process_payment example
+
+  #!!! list_pkgs example
+
+  #!!! order_pkg example
+
+  #!!! cancel_pkg example
+
+  # signup functionality
+  use FS::SelfService qw( signup_info new_customer );
+
+  my $signup_info = signup_info;
+
+  $rv = new_customer( {
+                        'first'            => $first,
+                        'last'             => $last,
+                        'company'          => $company,
+                        'address1'         => $address1,
+                        'address2'         => $address2,
+                        'city'             => $city,
+                        'state'            => $state,
+                        'zip'              => $zip,
+                        'country'          => $country,
+                        'daytime'          => $daytime,
+                        'night'            => $night,
+                        'fax'              => $fax,
+                        'payby'            => $payby,
+                        'payinfo'          => $payinfo,
+                        'paycvv'           => $paycvv,
+                        'paydate'          => $paydate,
+                        'payname'          => $payname,
+                        'invoicing_list'   => $invoicing_list,
+                        'referral_custnum' => $referral_custnum,
+                        'pkgpart'          => $pkgpart,
+                        'username'         => $username,
+                        '_password'        => $password,
+                        'popnum'           => $popnum,
+                        'agentnum'         => $agentnum,
+                      }
+                    );
+  
+  my $error = $rv->{'error'};
+  if ( $error eq '_decline' ) {
+    print_decline();
+  } elsif ( $error ) {
+    reprint_signup();
+  } else {
+    print_success();
+  }
+
+=head1 DESCRIPTION
+
+Use this API to implement your own client "self-service" module.
+
+If you just want to customize the look of the existing "self-service" module,
+see XXXX instead.
+
+=head1 PASSWORD, GECOS, SHELL CHANGING FUNCTIONS
+
+=over 4
+
+=item passwd
+
+=item chfn
+
+=item chsh
+
+=back
+
+=head1 "MY ACCOUNT" FUNCTIONS
+
+=over 4
+
+=item login HASHREF
+
+Creates a user session.  Takes a hash reference as parameter with the
+following keys:
+
+=over 4
+
+=item username
+
+=item domain
+
+=item password
+
+=back
+
+Returns a hash reference with the following keys:
+
+=over 4
+
+=item error
+
+Empty on success, or an error message on errors.
+
+=item session_id
+
+Session identifier for successful logins
+
+=back
+
+=item customer_info HASHREF
+
+Returns general customer information.
+
+Takes a hash reference as parameter with a single key: B<session_id>
+
+Returns a hash reference with the following keys:
+
+=over 4
+
+=item name
+
+Customer name
+
+=item balance
+
+Balance owed
+
+=item open
+
+Array reference of hash references of open inoices.  Each hash reference has
+the following keys: invnum, date, owed
+
+=item small_custview
+
+An HTML fragment containing shipping and billing addresses.
+
+=item The following fields are also returned: first last company address1 address2 city county state zip country daytime night fax ship_first ship_last ship_company ship_address1 ship_address2 ship_city ship_state ship_zip ship_country ship_daytime ship_night ship_fax
+
+=back
+
+=item edit_info HASHREF
+
+Takes a hash reference as parameter with any of the following keys:
+
+first last company address1 address2 city county state zip country daytime night fax ship_first ship_last ship_company ship_address1 ship_address2 ship_city ship_state ship_zip ship_country ship_daytime ship_night ship_fax
+
+If a field exists, the customer record is updated with the new value of that
+field.  If a field does not exist, that field is not changed on the customer
+record.
+
+Returns a hash reference with a single key, B<error>, empty on success, or an
+error message on errors
+
+=item invoice HASHREF
+
+Returns an invoice.  Takes a hash reference as parameter with two keys:
+session_id and invnum
+
+Returns a hash reference with the following keys:
+
+=over 4
+
+=item error
+
+Empty on success, or an error message on errors
+
+=item invnum
+
+Invoice number
+
+=item invoice_text
+
+Invoice text
+
+=back
+
+=item cancel HASHREF
+
+Cancels this customer.
+
+Takes a hash reference as parameter with a single key: B<session_id>
+
+Returns a hash reference with a single key, B<error>, which is empty on
+success or an error message on errors.
+
+=item payment_info HASHREF
+
+Returns information that may be useful in displaying a payment page.
+
+Takes a hash reference as parameter with a single key: B<session_id>.
+
+Returns a hash reference with the following keys:
+
+=over 4
+
+=item error
+
+Empty on success, or an error message on errors
+
+=item balance
+
+Balance owed
+
+=item payname
+
+Exact name on credit card (CARD/DCRD)
+
+=item address1
+
+=item address2
+
+=item city
+
+=item state
+
+=item zip
+
+=item payby
+
+Customer's current default payment type.
+
+=item card_type
+
+For CARD/DCRD payment types, the card type (Visa card, MasterCard, Discover card, American Express card, etc.)
+
+=item payinfo
+
+For CARD/DCRD payment types, the card number
+
+=item month
+
+For CARD/DCRD payment types, expiration month
+
+=item year
+
+For CARD/DCRD payment types, expiration year
+
+=item cust_main_county
+
+County/state/country data - array reference of hash references, each of which has the fields of a cust_main_county record (see L<FS::cust_main_county>).  Note these are not FS::cust_main_county objects, but hash references of columns and values.
+
+=item states
+
+Array reference of all states in the current default country.
+
+=item card_types
+
+Hash reference of card types; keys are card types, values are the exact strings
+passed to the process_payment function
+
+=item paybatch
+
+Unique transaction identifier (prevents multiple charges), passed to the
+process_payment function
+
+=back
+
+=item process_payment HASHREF
+
+Processes a payment and possible change of address or payment type.  Takes a
+hash reference as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+=item save
+
+If true, address and card information entered will be saved for subsequent
+transactions.
+
+=item auto
+
+If true, future credit card payments will be done automatically (sets payby to
+CARD).  If false, future credit card payments will be done on-demand (sets
+payby to DCRD).  This option only has meaning if B<save> is set true.  
+
+=item payname
+
+=item address1
+
+=item address2
+
+=item city
+
+=item state
+
+=item zip
+
+=item payinfo
+
+Card number
+
+=item month
+
+Card expiration month
+
+=item year
+
+Card expiration year
+
+=item paybatch
+
+Unique transaction identifier, returned from the payment_info function.
+Prevents multiple charges.
+
+=back
+
+Returns a hash reference with a single key, B<error>, empty on success, or an
+error message on errors
+
+=item list_pkgs
+
+Returns package information for this customer.
+
+Takes a hash reference as parameter with a single key: B<session_id>
+
+Returns a hash reference containing customer package information.  The hash reference contains the following keys:
+
+=over 4
+
+=item cust_pkg HASHREF
+
+Array reference of hash references, each of which has the fields of a cust_pkg record (see L<FS::cust_pkg>).  Note these are not FS::cust_pkg objects, but hash references of columns and values.
+
+=back
+
+=item order_pkg
+
+Orders a package for this customer.
+
+Takes a hash reference as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+=item pkgpart
+
+=item svcpart
+
+optional svcpart, required only if the package definition does not contain
+one svc_acct service definition with quantity 1 (it may contain others with
+quantity >1)
+
+=item username
+
+=item _password
+
+=item sec_phrase
+
+=item popnum
+
+=back
+
+Returns a hash reference with a single key, B<error>, empty on success, or an
+error message on errors.  The special error '_decline' is returned for
+declined transactions.
+
+=item cancel_pkg
+
+Cancels a package for this customer.
+
+Takes a hash reference as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+=item pkgpart
+
+=back
+
+Returns a hash reference with a single key, B<error>, empty on success, or an
+error message on errors.
+
+=back
+
+=head1 SIGNUP FUNCTIONS
+
+=over 4
+
+=item signup_info
+
+Returns a hash reference containing information that may be useful in
+displaying a signup page.  The hash reference contains the following keys:
+
+=over 4
+
+=item cust_main_county
+
+County/state/country data - array reference of hash references, each of which has the fields of a cust_main_county record (see L<FS::cust_main_county>).  Note these are not FS::cust_main_county objects, but hash references of columns and values.
+
+=item part_pkg
+
+Available packages - array reference of hash references, each of which has the fields of a part_pkg record (see L<FS::part_pkg>).  Each hash reference also has an additional 'payby' field containing an array reference of acceptable payment types specific to this package (see below and L<FS::part_pkg/payby>).  Note these are not FS::part_pkg objects, but hash references of columns and values.  Requires the 'signup_server-default_agentnum' configuration value to be set.
+
+=item agent
+
+Array reference of hash references, each of which has the fields of an agent record (see L<FS::agent>).  Note these are not FS::agent objects, but hash references of columns and values.
+
+=item agentnum2part_pkg
+
+Hash reference; keys are agentnums, values are array references of available packages for that agent, in the same format as the part_pkg arrayref above.
+
+=item svc_acct_pop
+
+Access numbers - array reference of hash references, each of which has the fields of an svc_acct_pop record (see L<FS::svc_acct_pop>).  Note these are not FS::svc_acct_pop objects, but hash references of columns and values.
+
+=item security_phrase
+
+True if the "security_phrase" feature is enabled
+
+=item payby
+
+Array reference of acceptable payment types for signup
+
+=over 4
+
+=item CARD (credit card - automatic)
+
+=item DCRD (credit card - on-demand - version 1.5+ only)
+
+=item CHEK (electronic check - automatic)
+
+=item DCHK (electronic check - on-demand - version 1.5+ only)
+
+=item LECB (Phone bill billing)
+
+=item BILL (billing, not recommended for signups)
+
+=item COMP (free, definately not recommended for signups)
+
+=item PREPAY (special billing type: applies a credit (see FS::prepay_credit) and sets billing type to BILL)
+
+=back
+
+=item cvv_enabled
+
+True if CVV features are available (1.5+ or 1.4.2 with CVV schema patch)
+
+=item msgcat
+
+Hash reference of message catalog values, to support error message customization.  Currently available keys are: passwords_dont_match, invalid_card, unknown_card_type, and not_a (as in "Not a Discover card").  Values are configured in the web interface under "View/Edit message catalog".
+
+=item statedefault
+
+Default state
+
+=item countrydefault
+
+Default country
+
+=back
+
+=item new_customer HASHREF
+
+Creates a new customer.  Takes a hash reference as parameter with the
+following keys:
+
+=over 4
+
+=item first - first name (required)
+
+=item last - last name (required)
+
+=item ss (not typically collected; mostly used for ACH transactions)
+
+=item company
+
+=item address1 (required)
+
+=item address2
+
+=item city (required)
+
+=item county
+
+=item state (required)
+
+=item zip (required)
+
+=item daytime - phone
+
+=item night - phone
+
+=item fax - phone
+
+=item payby - CARD, DCRD, CHEK, DCHK, LECB, BILL, COMP or PREPAY (see L</signup_info> (required)
+
+=item payinfo - Card number for CARD/DCRD, account_number@aba_number for CHEK/DCHK, prepaid "pin" for PREPAY, purchase order number for BILL
+
+=item paycvv - Credit card CVV2 number (1.5+ or 1.4.2 with CVV schema patch)
+
+=item paydate - Expiration date for CARD/DCRD
+
+=item payname - Exact name on credit card for CARD/DCRD, bank name for CHEK/DCHK
+
+=item invoicing_list - comma-separated list of email addresses for email invoices.  The special value 'POST' is used to designate postal invoicing (it may be specified alone or in addition to email addresses),
+
+=item referral_custnum - referring customer number
+
+=item pkgpart - pkgpart of initial package
+
+=item username
+
+=item _password
+
+=item sec_phrase - security phrase
+
+=item popnum - access number (index, not the literal number)
+
+=item agentnum - agent number
+
+=back
+
+Returns a hash reference with the following keys:
+
+=over 4
+
+=item error Empty on success, or an error message on errors.  The special error '_decline' is returned for declined transactions; other error messages should be suitable for display to the user (and are customizable in under Sysadmin | View/Edit message catalog)
+
+=back
+
+
 =back
 
 =head1 BUGS
index dfbd013..5607de7 100644 (file)
@@ -6,16 +6,22 @@
 <TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=2 CELLPADDING=0>
 <TR>
   <TH ALIGN="right">Username </TH>
-  <TD><INPUT TYPE="text" NAME="username" VALUE="<%= $username %>"></TD>
+  <TD>
+    <INPUT TYPE="text" NAME="username" VALUE="<%= $username %>">
+  </TD>
 </TR>
 <TR>
   <TH ALIGN="right">Domain </TH>
-  <TD><INPUT TYPE="text" NAME="domain" VALUE="<%= $domain %>"></TD>
+  <TD>
+    <INPUT TYPE="text" NAME="domain" VALUE="<%= $domain %>">
+  </TD>
 </TR>
 <!--<INPUT TYPE="hidden" NAME="domain" VALUE="myisp.com">-->
 <TR>
   <TH ALIGN="right">Password </TH>
-  <TD><INPUT TYPE="password" NAME="password"></TD>
+  <TD>
+    <INPUT TYPE="password" NAME="password">
+  </TD>
 </TR>
 </TABLE>
 <BR><BR><INPUT TYPE="submit" VALUE="Login">
diff --git a/fs_selfservice/FS-SelfService/cgi/make_payment.html b/fs_selfservice/FS-SelfService/cgi/make_payment.html
new file mode 100644 (file)
index 0000000..a1cda6d
--- /dev/null
@@ -0,0 +1,120 @@
+<HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
+<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
+<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<TABLE BORDER=0 CELLPADDING=4><TR><TD VALIGN="top" HEIGHT=384 BGCOLOR="#dddddd">
+<A HREF="<%= $url %>myaccount">MyAccount</A><BR>
+<!-- <A HREF="<%= $url %>other">SomethingElse</A><BR> -->
+</TD><TD VALIGN="top">
+<FONT SIZE=4>Make a payment</FONT><BR><BR>
+<FORM NAME="OneTrueForm" METHOD="POST" ACTION="<%=$selfurl%>" onSubmit="document.OneTrueForm.process.disabled=true">
+<INPUT TYPE="hidden" NAME="session" VALUE="<%=$session_id%>">
+<INPUT TYPE="hidden" NAME="action" VALUE="payment_results">
+<TABLE BGCOLOR="#cccccc">
+<TR>
+  <TD ALIGN="right">Amount&nbsp;Due</TD>
+  <TD>
+    <TABLE><TR><TD BGCOLOR="#ffffff">
+      $<%=sprintf("%.2f",$balance)%>
+    </TD></TR></TABLE>
+  </TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Payment&nbsp;amount</TD>
+  <TD>
+    <TABLE><TR><TD BGCOLOR="#ffffff">
+      $<INPUT TYPE="text" NAME="amount" SIZE=8 VALUE="<%=sprintf("%.2f",$balance)%>">
+    </TD></TR></TABLE>
+  </TD>
+</TR><TR>
+  <TD ALIGN="right">Card&nbsp;type</TD>
+  <TD>
+    <SELECT NAME="card_type"><OPTION></OPTION>
+      <%= foreach ( keys %card_types ) {
+            $selected = $card_type eq $card_types{$_} ? ' SELECTED' : '';
+            $OUT .= qq(<OPTION$selected VALUE="). $card_types{$_}. qq(">$_\n);
+      } %>
+    </SELECT>
+  </TD>
+</TD><TR>
+  <TD ALIGN="right">Card&nbsp;number</TD>
+  <TD>
+    <TABLE>
+      <TR>
+        <TD>
+          <INPUT TYPE="text" NAME="payinfo" SIZE=20 MAXLENGTH=19 VALUE="<%=$payinfo%>"> </TD>
+        <TD>Exp.</TD>
+        <TD>
+          <SELECT NAME="month">
+            <%= for ( ( map "0$_", 1 .. 9 ), 11, 12 ) {
+                  $OUT .= '<OPTION'. ($_ eq $month ? ' SELECTED' : ''). ">$_\n";
+            } %>
+          </SELECT>
+        </TD>
+        <TD> / </TD>
+        <TD>
+          <SELECT NAME="year">
+            <%= for ( 2003 .. 2012 ) {
+                  $OUT .= '<OPTION'. ($_ eq $year ? ' SELECTED' : ''). ">$_\n";
+            } %>
+          </SELECT>
+        </TD>
+      </TR>
+    </TABLE>
+  </TD>
+</TR><TR>
+  <TD ALIGN="right">Exact&nbsp;name&nbsp;on&nbsp;card</TD>
+  <TD><INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="payname" VALUE="<%=$payname%>"></TD>
+</TR><TR>
+  <TD ALIGN="right">Card&nbsp;billing&nbsp;address</TD>
+  <TD>
+    <INPUT TYPE="text" SIZE=40 MAXLENGTH=80 NAME="address1" VALUE="<%=$address1%>">
+  </TD>
+</TR><TR>
+  <TD ALIGN="right">Address&nbsp;line&nbsp;2</TD>
+  <TD>
+    <INPUT TYPE="text" SIZE=40 MAXLENGTH=80 NAME="address2" VALUE="<%=$address2%>">
+  </TD>
+</TR><TR>
+  <TD ALIGN="right">City</TD>
+  <TD>
+    <TABLE>
+      <TR>
+        <TD>
+          <INPUT TYPE="text" NAME="city" SIZE="12" MAXLENGTH=80 VALUE="<%=$city%>">
+        </TD>
+        <TD>State</TD>
+        <TD>
+          <SELECT NAME="state">
+            <%= for ( @states ) {
+              $OUT .= '<OPTION'. ($_ eq $state ? ' SELECTED' : '' ). ">$_\n";
+            } %>
+          </SELECT>
+        </TD>
+        <TD>Zip</TD>
+        <TD>
+          <INPUT TYPE="text" NAME="zip" SIZE=11 MAXLENGTH=10 VALUE="<%=$zip%>">
+        </TD>
+      </TR>
+    </TABLE>
+  </TD>
+</TR><TR>
+  <TD COLSPAN=2>
+    <INPUT TYPE="checkbox" CHECKED NAME="save" VALUE="1">
+    Remember this information
+  </TD>
+</TR><TR>
+  <TD COLSPAN=2>
+    <INPUT TYPE="checkbox"<%= $payby eq 'CARD' ? ' CHECKED' : '' %> NAME="auto" VALUE="1" onClick="if (this.checked) { document.OneTrueForm.save.checked=true; }">
+    Charge future payments to this card automatically
+  </TD>
+</TR>
+</TABLE>
+<BR>
+<INPUT TYPE="hidden" NAME="paybatch" VALUE="<%=$paybatch%>">
+<INPUT TYPE="submit" NAME="process" VALUE="Process payment"> <!-- onClick="this.disabled=true"> -->
+</FORM>
+</TD></TR></TABLE>
+<HR>
+<FONT SIZE="-2">powered by <a href="http://www.sisd.com/freeside">freeside</a></FONT>
+</BODY></HTML>
+
index f8a916e..f48fded 100644 (file)
@@ -3,20 +3,20 @@
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <TABLE BORDER=0 CELLPADDING=4><TR><TD VALIGN="top" HEIGHT=384 BGCOLOR="#dddddd">
 <A HREF="<%= $url %>myaccount">MyAccount</A><BR>
-<A HREF="<%= $url %>other">SomethingElse</A><BR>
+<!-- <A HREF="<%= $url %>other">SomethingElse</A><BR> -->
 </TD><TD VALIGN="top">
 
 Hello <%= $name %>!<BR><BR>
-Your customer number is <%= $custnum %><BR><BR>
-Your contact information<BR><%= $small_custview %>
-Your outstanding balance is $<%= $balance %><BR><BR>
-<!--<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2 BORDERCOLOR="#999999">
-<TR><TH>Invoice</TH><TH>Date</TH><TH>Owed</TH></TR>-->
+<%= $small_custview %>
+<BR>
+<%= if ( $balance > 0 ) {
+  $OUT .= qq! <B><A HREF="${url}make_payment">Make a payment</A></B><BR><BR>!;
+} %>
 <%=
   if ( @open_invoices ) {
     $OUT .= '<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 BGCOLOR="#eeeeee">'.
             '<TR><TH BGCOLOR="#ff3333" COLSPAN=5>Open Invoices</TH><TD>';
-    my $link = qq!<A HREF="<%= $selfurl %>?session=<%= $session_id %>;action=myaccount!;
+    my $link = qq!<A HREF="<%= $url %>myaccount!;
     my $col1 = "ffffff";
     my $col2 = "dddddd";
     my $col = $col1;
@@ -40,7 +40,7 @@ Your outstanding balance is $<%= $balance %><BR><BR>
 
 </TD></TR></TABLE>
 <HR>
-<FONT SIZE="-2">small text</FONT>
+<FONT SIZE="-2">powered by <a href="http://www.sisd.com/freeside">freeside</a></FONT>
 </BODY></HTML>
 
 
diff --git a/fs_selfservice/FS-SelfService/cgi/payment_results.html b/fs_selfservice/FS-SelfService/cgi/payment_results.html
new file mode 100644 (file)
index 0000000..92c8cf5
--- /dev/null
@@ -0,0 +1,18 @@
+<HTML><HEAD><TITLE>MyAccount</TITLE></HEAD>
+<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR>
+<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<TABLE BORDER=0 CELLPADDING=4><TR><TD VALIGN="top" HEIGHT=384 BGCOLOR="#dddddd">
+<A HREF="<%= $url %>myaccount">MyAccount</A><BR>
+<!-- <A HREF="<%= $url %>other">SomethingElse</A><BR> -->
+</TD><TD VALIGN="top">
+<FONT SIZE=4>Payment results</FONT><BR><BR>
+<%= if ( $error ) {
+  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error processing your payment: $error</FONT>!;
+} else {
+  $OUT .= 'Your payment was processed sucessfully.  Thank you.';
+} %>
+</TD></TR></TABLE>
+<HR>
+<FONT SIZE="-2">powered by <a href="http://www.sisd.com/freeside">freeside</a></FONT>
+</BODY></HTML>
+
index eae3739..6d6716d 100644 (file)
@@ -6,7 +6,8 @@ use subs qw(do_template);
 use CGI;
 use CGI::Carp qw(fatalsToBrowser);
 use Text::Template;
-use FS::SelfService qw(login customer_info invoice);
+use FS::SelfService qw( login customer_info invoice payment_info
+                        process_payment );
 
 $template_dir = '.';
 
@@ -53,7 +54,8 @@ if ( $cgi->param('session') eq 'login' ) {
 
 $session_id = $cgi->param('session');
 
-$cgi->param('action') =~ /^(myaccount|view_invoice)$/
+$cgi->param('action') =~
+    /^(myaccount|view_invoice|make_payment|payment_results)$/
   or die "unknown action ". $cgi->param('action');
 my $action = $1;
 
@@ -68,6 +70,7 @@ if ( $result->{error} eq "Can't resume session" ) { #ick
 #warn $result->{'open_invoices'};
 #warn scalar(@{$result->{'open_invoices'}});
 
+warn "processing template $action\n";
 do_template($action, {
   'session_id' => $session_id,
   %{$result}
@@ -88,6 +91,82 @@ sub view_invoice {
 
 }
 
+sub make_payment {
+  payment_info( 'session_id' => $session_id );
+}
+
+sub payment_results {
+
+  use Business::CreditCard;
+
+  $cgi->param('amount') =~ /^\s*(\d+(\.\d{2})?)\s*$/
+    or die "illegal amount"; #!!!
+  my $amount = $1;
+
+  my $payinfo = $cgi->param('payinfo');
+  $payinfo =~ s/\D//g;
+  $payinfo =~ /^(\d{13,16})$/
+    #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
+    or die "illegal card"; #!!!
+  $payinfo = $1;
+  validate($payinfo)
+    #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
+    or die "invalid card"; #!!!
+  cardtype($payinfo) eq $cgi->param('card_type')
+    #or $error ||= $init_data->{msgcat}{not_a}. $cgi->param('CARD_type');
+    or die "not a ". $cgi->param('card_type');
+
+  $cgi->param('month') =~ /^(\d{2})$/ or die "illegal month";
+  my $month = $1;
+  $cgi->param('year') =~ /^(\d{4})$/ or die "illegal year";
+  my $year = $1;
+
+  $cgi->param('payname') =~ /^(.{0,80})$/ or die "illegal payname";
+  my $payname = $1;
+
+  $cgi->param('address1') =~ /^(.{0,80})$/ or die "illegal address1";
+  my $address1 = $1;
+
+  $cgi->param('address2') =~ /^(.{0,80})$/ or die "illegal address2";
+  my $address2 = $1;
+
+  $cgi->param('city') =~ /^(.{0,80})$/ or die "illegal city";
+  my $city = $1;
+
+  $cgi->param('state') =~ /^(.{2})$/ or die "illegal state";
+  my $state = $1;
+
+  $cgi->param('zip') =~ /^(.{0,10})$/ or die "illegal zip";
+  my $zip = $1;
+
+  my $save = 0;
+  $save = 1 if $cgi->param('save');
+
+  my $auto = 0;
+  $auto = 1 if $cgi->param('auto');
+
+  $cgi->param('paybatch') =~ /^([\w\-\.]+)$/ or die "illegal paybatch";
+  my $paybatch = $1;
+
+  process_payment(
+    'session_id' => $session_id,
+    'amount'     => $amount,
+    'payinfo'    => $payinfo,
+    'month'      => $month,
+    'year'       => $year,
+    'payname'    => $payname,
+    'address1'   => $address1,
+    'address2'   => $address2,
+    'city'       => $city,
+    'state'      => $state,
+    'zip'        => $zip,
+    'save'       => $save,
+    'auto'       => $auto,
+    'paybatch'   => $paybatch,
+  );
+
+}
+
 #--
 
 sub do_template {
@@ -95,7 +174,7 @@ sub do_template {
   my $fill_in = shift;
 
   $cgi->delete_all();
-  $fill_in->{'self_url'} = $cgi->self_url;
+  $fill_in->{'selfurl'} = $cgi->self_url;
 
   my $template = new Text::Template( TYPE    => 'FILE',
                                      SOURCE  => "$template_dir/$name.html",
index 33388de..d2b012b 100644 (file)
@@ -3,7 +3,7 @@
 <%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <TABLE BORDER=0 CELLPADDING=4><TR><TD VALIGN="top" HEIGHT=384 BGCOLOR="#dddddd">
 <A HREF="<%= $url %>myaccount">MyAccount</A><BR>
-<A HREF="<%= $url %>other">SomethingElse</A><BR>
+<!-- <A HREF="<%= $url %>other">SomethingElse</A><BR> -->
 </TD><TD VALIGN="top">
 
 <A HREF="<%= $url %>myaccount"><-- back to MyAccount</A><BR><BR>
@@ -14,7 +14,7 @@
 
 </TD></TR></TABLE>
 <HR>
-<FONT SIZE="-2">small text</FONT>
+<FONT SIZE="-2">powered by <a href="http://www.sisd.com/freeside">freeside</a></FONT>
 </BODY></HTML>
 
 
index 0c25c34..925bce6 100644 (file)
@@ -5,7 +5,7 @@
 # This is run REMOTELY over ssh by freeside-selfservice-server
 
 use strict;
-use subs qw(spawn logmsg);
+use subs qw(spawn logmsg lock_write unlock_write);
 use Fcntl qw(:flock);
 use POSIX qw(:sys_wait_h);
 use Socket;
@@ -14,16 +14,20 @@ use IO::Handle qw(_IONBF);
 use IO::Select;
 use IO::File;
 
-STDOUT->setbuf('');
+#STDOUT->setbuf('');
+
+my $tag = scalar(@ARGV) ? '.'.shift : '';
 
 use vars qw( $Debug );
-$Debug = 3; #2 will turn on child logging, 3 will log packet contents,
+$Debug = 2; #2 will turn on child logging, 3 will log packet contents,
             #including potentially compromising information
 
-my $socket = "/usr/local/freeside/selfservice_socket";
+my $socket = "/usr/local/freeside/selfservice_socket$tag";
 my $pid_file = "$socket.pid";
 
-my $log_file = "/usr/local/freeside/selfservice.log";
+my $log_file = "/usr/local/freeside/selfservice$tag.log";
+
+my $lock_file = "/usr/local/freeside/selfservice$tag.writelock";
 
 #my $me = '[client]';
 
@@ -35,6 +39,9 @@ $SIG{__WARN__} = \&_logmsg;
 #warn "$me Reading init data\n" if $Debug;
 #my $signup_init = 
 
+warn "Creating $lock_file\n" if $Debug;
+open(LOCKFILE,">$lock_file") or die "can't open $lock_file: $!";
+
 warn "Creating $socket\n" if $Debug;
 my $uaddr = sockaddr_un($socket);
 my $proto = getprotobyname('tcp');
@@ -138,14 +145,22 @@ while (1) {
         #handle some commands weirdly?
         $packet->{_token}=$$;
 
-        warn "[child-$$] sending packet to remote server" if $Debug > 1;
-        flock(STDOUT, LOCK_EX) or die "FATAL: can't lock write stream: $!";
+        warn "[child-$$] locking write stream\n" if $Debug > 1;
+        lock_write;
+
+        warn "[child-$$] sending packet to remote server\n" if $Debug > 1;
         nstore_fd($packet, \*STDOUT) or die "FATAL: can't send response: $!";
+        
+        warn "[child-$$] flushing write stream\n" if $Debug > 1;
         STDOUT->flush or die "FATAL: can't flush: $!";
-        flock(STDOUT, LOCK_UN) or die "FATAL: can't release write lock: $!";
+        
+        warn "[child-$$] releasing write lock\n" if $Debug > 1;
+        unlock_write;
+
+        warn "[child-$$] closing write stream\n" if $Debug > 1;
         close STDOUT or die "FATAL: can't close write stream: $!"; #??!
 
-        warn "[child-$$] waiting for response from parent" if $Debug > 1;
+        warn "[child-$$] waiting for response from parent\n" if $Debug > 1;
         my $w = new IO::Select;
         $w->add(\*STDIN);
         until ( $w->can_read ) {
@@ -224,3 +239,17 @@ sub _logmsg {
   flock($log, LOCK_UN);
   close $log;
 }
+
+sub lock_write {
+  #broken on freebsd?
+  #flock(STDOUT, LOCK_EX) or die "FATAL: can't lock write stream: $!";
+
+  flock(LOCKFILE, LOCK_EX) or die "FATAL: can't lock $lock_file: $!";
+}
+
+sub unlock_write {
+  #broken on freebsd?
+  #flock(STDOUT, LOCK_UN) or die "FATAL: can't release write lock: $!";
+
+  flock(LOCKFILE, LOCK_UN) or die "FATAL: can't unlock $lock_file: $!";
+}
diff --git a/fs_selfservice/freeside-selfservice-server b/fs_selfservice/freeside-selfservice-server
deleted file mode 100644 (file)
index e55ca49..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-#!/usr/bin/perl -w
-#
-# freeside-selfservice-server
-
-# alas, much false laziness with freeside-queued and fs_signup_server.  at
-# least it is slated to replace fs_{signup,passwd,mailadmin}_server
-# should probably generalize the version in here, or better yet use
-# Proc::Daemon or somesuch
-
-use strict;
-use vars qw( $Debug %kids $kids $max_kids $shutdown $log_file $ssh_pid );
-use Fcntl qw(:flock);
-use POSIX qw(:sys_wait_h setsid);
-use IO::Handle;
-use IO::Select;
-use IO::File;
-use Storable qw(nstore_fd fd_retrieve);
-use Net::SSH qw(sshopen2);
-use FS::UID qw(adminsuidsetup forksuidsetup);
-use FS::ClientAPI;
-
-$Debug = 2; # >= 2 will log packet contents, including potentially compromising
-            # information
-
-$shutdown = 0;
-$max_kids = '10'; #?
-$kids = 0;
-
-my $user = shift or die &usage;
-my $machine = shift or die &usage;
-my $pid_file = "/var/run/freeside-selfservice-server.$user.pid";
-#my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; $FS::UID::datasrc not posible, but should include machine name at least, hmm
-
-&init($user);
-
-my $clientd = "/usr/local/sbin/freeside-selfservice-clientd"; #better name?
-
-my $warnkids=0;
-while (1) {
-  my($writer,$reader,$error) = (new IO::Handle, new IO::Handle, new IO::Handle);
-  warn "connecting to $machine\n" if $Debug;
-
-  $ssh_pid = sshopen2($machine,$reader,$writer,$clientd);
-
-#  nstore_fd(\*writer, {'hi'=>'there'});
-
-  warn "entering main loop\n" if $Debug;
-  my $undisp = 0;
-  my $s = IO::Select->new( $reader );
-  while (1) {
-
-    &reap_kids;
-
-    warn "waiting for packet from client\n" if $Debug && !$undisp;
-    $undisp = 1;
-    my @handles = $s->can_read(5);
-    unless ( @handles ) {
-      &shutdown if $shutdown;
-      next;
-    }
-
-    $undisp = 0;
-
-    warn "receiving packet from client\n" if $Debug;
-
-    my $packet = fd_retrieve($reader);
-    warn "packet received\n".
-         join('', map { " $_=>$packet->{$_}\n" } keys %$packet )
-      if $Debug > 1;
-
-    #prevent runaway forking
-    my $warnkids = 0;
-    while ( $kids >= $max_kids ) {
-      warn "WARNING: maximum $kids children reached\n" unless $warnkids++;
-      &reap_kids;
-      sleep 1;
-    }
-
-    warn "forking child\n" if $Debug;
-    defined( my $pid = fork ) or die "can't fork: $!";
-    if ( $pid ) {
-      $kids++;
-      $kids{$pid} = 1;
-      warn "child $pid spawned\n" if $Debug;
-    } else { #kid time
-
-      #get new db handle
-      $FS::UID::dbh->{InactiveDestroy} = 1;
-      forksuidsetup($user);
-
-      my $type = $packet->{_packet};
-      warn "calling $type handler\n" if $Debug; 
-      my $rv = eval { FS::ClientAPI->dispatch($type, $packet); };
-      if ( $@ ) {
-        warn my $error = "WARNING: error dispatching $type: $@";
-        $rv = { _error => $error };
-      }
-      $rv->{_token} = $packet->{_token}; #identifier
-
-      warn "sending response\n" if $Debug;
-      flock($writer, LOCK_EX) or die "FATAL: can't lock write stream: $!";
-      nstore_fd($rv, $writer) or die "FATAL: can't send response: $!";
-      $writer->flush or die "FATAL: can't flush: $!";
-      flock($writer, LOCK_UN) or die "WARNING: can't release write lock: $!";
-
-      warn "child exiting\n" if $Debug;
-      exit; #end-of-kid
-    }
-
-  }
-
-}
-
-###
-# utility subroutines
-###
-
-sub reap_kids {
-  #warn "reaping kids\n";
-  foreach my $pid ( keys %kids ) {
-    my $kid = waitpid($pid, WNOHANG);
-    if ( $kid > 0 ) {
-      $kids--;
-      delete $kids{$kid};
-    }
-  }
-  #warn "done reaping\n";
-}
-
-sub init {
-  my $user = shift;
-
-  chdir "/" or die "Can't chdir to /: $!";
-  open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
-  defined(my $pid = fork) or die "Can't fork: $!";
-  if ( $pid ) {
-    print "freeside-selfservice-server to $machine started with pid $pid\n"; #logging to $log_file
-    exit unless $pid_file;
-    my $pidfh = new IO::File ">$pid_file" or exit;
-    print $pidfh "$pid\n";
-    exit;
-  }
-
-#  sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; $kids--; }
-#  #sub REAPER { my $pid = wait; $kids--; $SIG{CHLD} = \&REAPER; }
-#  $SIG{CHLD} =  \&REAPER;
-
-  $shutdown = 0;
-  $SIG{HUP} = sub { warn "SIGHUP received; shutting down\n"; $shutdown++; };
-  $SIG{INT} = sub { warn "SIGINT received; shutting down\n"; $shutdown++; };
-  $SIG{TERM} = sub { warn "SIGTERM received; shutting down\n"; $shutdown++; };
-  $SIG{QUIT} = sub { warn "SIGQUIT received; shutting down\n"; $shutdown++; };
-  $SIG{PIPE} = sub { warn "SIGPIPE received; shutting down\n"; $shutdown++; };
-
-  #false laziness w/freeside-queued
-  my $freeside_gid = scalar(getgrnam('freeside'))
-    or die "can't setgid to freeside group\n";
-  $) = $freeside_gid;
-  $( = $freeside_gid;
-  #if freebsd can't setuid(), presumably it can't setgid() either.  grr fleabsd
-  ($(,$)) = ($),$();
-  $) = $freeside_gid;
-
-  $> = $FS::UID::freeside_uid;
-  $< = $FS::UID::freeside_uid;
-  #freebsd is sofa king broken, won't setuid()
-  ($<,$>) = ($>,$<);
-  $> = $FS::UID::freeside_uid;
-  #eslaf
-
-  $ENV{HOME} = (getpwuid($>))[7]; #for ssh
-  adminsuidsetup $user;
-
-  #$log_file = "/usr/local/etc/freeside/selfservice.". $FS::UID::datasrc; #MACHINE NAME
-  $log_file = "/usr/local/etc/freeside/selfservice.$machine.log";
-
-  open STDOUT, '>/dev/null'
-                            or die "Can't write to /dev/null: $!";
-  setsid                  or die "Can't start a new session: $!";
-  open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
-
-  $SIG{__DIE__} = \&_die;
-  $SIG{__WARN__} = \&_logmsg;
-
-  warn "freeside-selfservice-server starting\n";
-
-}
-
-sub shutdown {
-  my $wait = 12; #wait up to 1 minute
-  while ( $kids > 0 && $wait-- ) {
-    warn "waiting for $kids children to terminate";
-    sleep 5;
-  }
-  warn "abandoning $kids children" if $kids;
-  kill 'TERM', $ssh_pid if $ssh_pid;
-  die "exiting";
-}
-
-sub _die {
-  my $msg = shift;
-  unlink $pid_file if -e $pid_file;
-  _logmsg($msg);
-}
-
-sub _logmsg {
-  chomp( my $msg = shift );
-  _do_logmsg( "[server] [". scalar(localtime). "] [$$] $msg\n" );
-}
-
-sub _do_logmsg {
-  chomp( my $msg = shift );
-  my $log = new IO::File ">>$log_file";
-  flock($log, LOCK_EX);
-  seek($log, 0, 2);
-  print $log "$msg\n";
-  flock($log, LOCK_UN);
-  close $log;
-}
-
-sub usage {
-  die "Usage:\n\n  fs_signup_server user machine\n";
-}
-
index e740519..310200b 100644 (file)
@@ -11,8 +11,7 @@ WriteMakefile(
     'PREREQ_PM'     => {
                          'Business::CreditCard' => 0,
                          'HTTP::BrowserDetect' => 0,
-                         'HTTP::Headers::UserAgent' => 3,
-                         'Storable' => 0,
                          'Text::Template' => 0,
+                         'FS::SelfService' => 0,
                        },
 );
index 0a6cbfb..fb2b12f 100644 (file)
@@ -1,30 +1,19 @@
 package FS::SignupClient;
 
 use strict;
-use vars qw($VERSION @ISA @EXPORT_OK $fs_signupd_socket);
+use vars qw($VERSION @ISA @EXPORT_OK); # $fs_signupd_socket);
 use Exporter;
-use Socket;
-use FileHandle;
-use IO::Handle;
-use Storable qw(nstore_fd fd_retrieve);
+#use Socket;
+#use FileHandle;
+#use IO::Handle;
+#use Storable qw(nstore_fd fd_retrieve);
+use FS::SelfService; # qw( new_customer signup_info );
 
-$VERSION = '0.03';
+$VERSION = '0.04';
 
 @ISA = qw( Exporter );
 @EXPORT_OK = qw( signup_info new_customer );
 
-$fs_signupd_socket = "/usr/local/freeside/fs_signupd_socket";
-
-$ENV{'PATH'} ='/usr/bin:/usr/ucb:/bin';
-$ENV{'SHELL'} = '/bin/sh';
-$ENV{'IFS'} = " \t\n";
-$ENV{'CDPATH'} = '';
-$ENV{'ENV'} = '';
-$ENV{'BASH_ENV'} = '';
-
-my $freeside_uid = scalar(getpwnam('freeside'));
-die "not running as the freeside user\n" if $> != $freeside_uid;
-
 =head1 NAME
 
 FS::SignupClient - Freeside signup client API
@@ -33,8 +22,10 @@ FS::SignupClient - Freeside signup client API
 
   use FS::SignupClient qw( signup_info new_customer );
 
-  ( $locales, $packages, $pops ) = signup_info;
+  #this is the backwards-compatibility bit
+  ( $locales, $packages, $pops, $real_signup_info ) = signup_info;
 
+  #this is compatible with FS::SelfService::new_customer
   $error = new_customer ( {
     'first'            => $first,
     'last'             => $last,
@@ -52,10 +43,12 @@ FS::SignupClient - Freeside signup client API
     'fax'              => $fax,
     'payby'            => $payby,
     'payinfo'          => $payinfo,
+    'paycvv'           => $paycvv,
     'paydate'          => $paydate,
     'payname'          => $payname,
     'invoicing_list'   => $invoicing_list,
     'referral_custnum' => $referral_custnum,
+    'comments'         => $comments,
     'pkgpart'          => $pkgpart,
     'username'         => $username,
     '_password'        => $password,
@@ -103,14 +96,10 @@ Each hash reference has the following keys:
 
 =cut
 
+#compatibility bit
 sub signup_info {
-  socket(SOCK, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!";
-  connect(SOCK, sockaddr_un($fs_signupd_socket)) or die "connect: $!";
-  print SOCK "signup_info\n";
-  SOCK->flush;
 
-  my $init_data = fd_retrieve(\*SOCK);
-  close SOCK;
+  my $init_data = FS::SelfService::signup_info();
 
   (map { $init_data->{$_} } qw( cust_main_county part_pkg svc_acct_pop ) ),
   $init_data;
@@ -137,10 +126,12 @@ a paramater with the following keys:
   fax
   payby
   payinfo
+  paycvv
   paydate
   payname
   invoicing_list
   referral_custnum
+  comments
   pkgpart
   username
   _password
@@ -151,26 +142,10 @@ Returns a scalar error message, or the empty string for success.
 
 =cut
 
-sub new_customer {
-  my $hashref = shift;
-
-  socket(SOCK, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!";
-  connect(SOCK, sockaddr_un($fs_signupd_socket)) or die "connect: $!";
-  print SOCK "new_customer\n";
-
-  my $signup_data = { map { $_ => $hashref->{$_} } qw(
-    first last ss company address1 address2 city county state zip country
-    daytime night fax payby payinfo paydate payname invoicing_list
-    referral_custnum pkgpart username _password sec_phrase popnum
-  ) };
-
-  $signup_data->{agentnum} = $hashref->{agentnum} if $hashref->{agentnum};
-
-  nstore_fd($signup_data, \*SOCK) or die "can't send customer signup: $!";
-  SOCK->flush;
-
-  chop( my $error = <SOCK> );
-  $error;
+#compatibility bit
+sub new_customer { 
+  my $hash = FS::SelfService::new_customer(@_);
+  $hash->{'error'};
 }
 
 =back
diff --git a/fs_signup/FS-SignupClient/cgi/cvv2.html b/fs_signup/FS-SignupClient/cgi/cvv2.html
new file mode 100644 (file)
index 0000000..b178c85
--- /dev/null
@@ -0,0 +1,25 @@
+<HTML>
+  <HEAD>
+    <TITLE>
+      CVV2 information
+    </TITLE>
+  </HEAD>
+  <BODY BGCOLOR="#e8e8e8">
+  The CVV2 number (also called CVC2 or CID) is a three- or four-digit
+  security code used to reduce credit card fraud.<BR><BR>
+  <TABLE BORDER=0 CELLSPACING=4>
+    <TR>
+      <TH>Visa / MasterCard / Discover</TH>
+      <TH>American Express</TH>
+    </TR>
+    <TR>
+      <TD>
+        <IMG BORDER=0 ALT="Visa/MasterCard/Discover" SRC="cvv2.png">
+      </TD>
+      <TD>
+        <IMG BORDER=0 ALT="American Express" SRC="cvv2_amex.png">
+      </TD>
+  </TABLE>
+    <CENTER><A HREF="javascript:close()">(close window)</A></CENTER>
+  </BODY>
+</HTML>
diff --git a/fs_signup/FS-SignupClient/cgi/cvv2.png b/fs_signup/FS-SignupClient/cgi/cvv2.png
new file mode 100644 (file)
index 0000000..4610dcb
Binary files /dev/null and b/fs_signup/FS-SignupClient/cgi/cvv2.png differ
diff --git a/fs_signup/FS-SignupClient/cgi/cvv2_amex.png b/fs_signup/FS-SignupClient/cgi/cvv2_amex.png
new file mode 100644 (file)
index 0000000..21c36a0
Binary files /dev/null and b/fs_signup/FS-SignupClient/cgi/cvv2_amex.png differ
diff --git a/fs_signup/FS-SignupClient/cgi/signup-agentselect.html b/fs_signup/FS-SignupClient/cgi/signup-agentselect.html
new file mode 100755 (executable)
index 0000000..2451361
--- /dev/null
@@ -0,0 +1,195 @@
+<HTML><HEAD><TITLE>ISP Signup form</TITLE></HEAD>
+<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>ISP Signup form</FONT><BR><BR>
+<FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT>
+<FORM ACTION="<%= $self_url %>" METHOD=POST>
+<INPUT TYPE="hidden" NAME="magic" VALUE="process">
+<INPUT TYPE="hidden" NAME="ref" VALUE="<%= $referral_custnum %>">
+<INPUT TYPE="hidden" NAME="ss" VALUE="">
+Agent <SELECT NAME="agentnum">
+<%=
+  warn $init_data;
+  warn $init_data->{'agent'};
+  foreach my $agent ( @{$init_data->{'agent'}} ) {
+    $OUT .= '<OPTION VALUE="'. $agent->{'agentnum'}. '"';
+    $OUT .= ' SELECTED' if $agent->{'agentnum'} eq $agentnum;
+    $OUT .= '>'. $agent->{'agent'};
+  }
+%>
+</SELECT><BR><BR>
+Contact Information
+<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
+<TR>
+  <TH ALIGN="right"><font color="#ff0000">*</font>Contact name<BR>(last, first)</TH>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="last" VALUE="<%= $last %>">,
+                <INPUT TYPE="text" NAME="first" VALUE="<%= $first %>"></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Company</TD>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="company" SIZE=70 VALUE="<%= $company %>"></TD>
+</TR>
+<TR>
+  <TH ALIGN="right"><font color="#ff0000">*</font>Address</TH>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="address1" SIZE=70 VALUE="<%= $address1 %>"></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">&nbsp;</TD>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="address2" SIZE=70 VALUE="<%= $address2 %>"></TD>
+</TR>
+<TR>
+  <TH ALIGN="right"><font color="#ff0000">*</font>City</TH>
+  <TD><INPUT TYPE="text" NAME="city" VALUE="<%= $city %>"></TD>
+  <TH ALIGN="right"><font color="#ff0000">*</font>State/Country</TH>
+  <TD>
+    <%=
+        ($county_html, $state_html, $country_html) =
+          regionselector( $county, $state, $country );
+        "$county_html $state_html";
+    %>
+  </TD>
+  <TH><font color="#ff0000">*</font>Zip</TH>
+  <TD><INPUT TYPE="text" NAME="zip" SIZE=10 VALUE="<%= $zip %>"></TD>
+</TR>
+<TR>
+  <TH ALIGN="right"><font color="#ff0000">*</font>Country</TH>
+  <TD><%= $country_html %></TD>
+<TR>
+  <TD ALIGN="right">Day Phone</TD>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="<%= $daytime %>" SIZE=18></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Night Phone</TD>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="<%= $night %>" SIZE=18></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Fax</TD>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="fax" VALUE="<%= $fax %>" SIZE=12></TD>
+</TR>
+</TABLE><font color="#ff0000">*</font> required fields<BR>
+<BR>Billing information<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
+<TR><TD>
+
+  <%=
+    $OUT .= '<INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST"';
+    my @invoicing_list = split(', ', $invoicing_list );
+    $OUT .= ' CHECKED'
+      if ! @invoicing_list || grep { $_ eq 'POST' } @invoicing_list;
+    $OUT .= '>';
+  %>
+
+  Postal mail invoice
+</TD></TR>
+<TR><TD>Email invoice <INPUT TYPE="text" NAME="invoicing_list" VALUE="<%= join(', ', grep { $_ ne 'POST' } split(', ', $invoicing_list ) ) %>">
+</TD></TR>
+<%= scalar(@payby) > 1 ? '<TR><TD>Billing type</TD></TR>' : '' %>
+</TABLE>
+<TABLE BGCOLOR="#c0c0c0" BORDER=1 WIDTH="100%">
+<TR>
+
+  <%=
+
+    my $cardselect = '<SELECT NAME="CARD_type"><OPTION></OPTION>';
+    my %types = (
+                  'VISA' => 'VISA card',
+                  'MasterCard' => 'MasterCard',
+                  'Discover' => 'Discover card',
+                  'American Express' => 'American Express card',
+                );
+    foreach ( keys %types ) {
+      $selected = $cgi->param('CARD_type') eq $types{$_} ? 'SELECTED' : '';
+      $cardselect .= qq!<OPTION $selected VALUE="$types{$_}">$_</OPTION>!;
+    }
+    $cardselect .= '</SELECT>';
+  
+    my %payby = (
+      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!,
+      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="">!,
+      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="">!,
+      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="">!,
+      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!,
+      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", "12-2037"). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="Accounts Payable">!,
+      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("COMP"),
+      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="" MAXLENGTH=80>!,
+    );
+
+    my( $account, $aba ) = split('@', $payinfo);
+    my %paybychecked = (
+      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname">!,
+      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="$payname">!,
+      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="$payname">!,
+      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="$payname">!,
+      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="$payinfo" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!,
+      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", $paydate). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="$payname">!,
+      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("COMP", $paydate),
+      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="$payinfo" MAXLENGTH=80>!,
+    );
+
+    for (@payby) {
+      if ( scalar(@payby) == 1) {
+        $OUT .= '<TD VALIGN=TOP>'.
+                qq!<INPUT TYPE="hidden" NAME="payby" VALUE="$_">!.
+                "$paybychecked{$_}</TD>";
+      } else {
+        $OUT .= qq!<TD VALIGN=TOP><INPUT TYPE="radio" NAME="payby" VALUE="$_"!;
+        if ($payby eq $_) {
+          $OUT .= qq! CHECKED> $paybychecked{$_}</TD>!;
+        } else {
+          $OUT .= qq!> $payby{$_}</TD>!;
+        }
+
+      }
+    }
+  %>
+
+</TR></TABLE><font color="#ff0000">*</font> required fields for each billing type
+<BR><BR>First package
+<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
+<TR>
+  <TD COLSPAN=2><SELECT NAME="pkgpart"><OPTION VALUE="">(none)
+
+  <%=
+    foreach my $package ( @{$packages} ) {
+      $OUT .= '<OPTION VALUE="'. $package->{'pkgpart'}. '"';
+      $OUT .= ' SELECTED' if $pkgpart && $package->{'pkgpart'} == $pkgpart;
+      $OUT .= '>'. $package->{'pkg'};
+    }
+  %>
+
+  </SELECT></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Username</TD>
+  <TD><INPUT TYPE="text" NAME="username" VALUE="<%= $username %>"></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Password</TD>
+  <TD><INPUT TYPE="password" NAME="_password" VALUE="<%= $password %>"></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Re-enter Password</TD>
+  <TD><INPUT TYPE="password" NAME="_password2" VALUE="<%= $password2 %>"></TD>
+</TR>
+<%=
+  if ( $init_data->{'security_phrase'} ) {
+    $OUT .= <<ENDOUT;
+<TR>
+  <TD ALIGN="right">Security Phrase</TD>
+  <TD><INPUT TYPE="text" NAME="sec_phrase" VALUE="$sec_phrase">
+  </TD>
+</TR>
+ENDOUT
+  } else {
+    $OUT .= '<INPUT TYPE="hidden" NAME="sec_phrase" VALUE="">';
+  }
+%>
+<%=
+  if ( scalar(@$pops) ) {
+    $OUT .= '<TR><TD ALIGN="right">Access number</TD><TD>'.
+            popselector($popnum). '</TD></TR>';
+  } else {
+    $OUT .= popselector($popnum);
+  }
+%>
+</TABLE>
+<BR><BR><INPUT TYPE="submit" VALUE="Signup">
+</FORM></BODY></HTML>
diff --git a/fs_signup/FS-SignupClient/cgi/signup-snarf.html b/fs_signup/FS-SignupClient/cgi/signup-snarf.html
new file mode 100755 (executable)
index 0000000..d167efb
--- /dev/null
@@ -0,0 +1,228 @@
+<HTML><HEAD><TITLE>ISP Signup form</TITLE></HEAD>
+<BODY BGCOLOR="#e8e8e8" onUnload="myclose()">
+<script language="JavaScript"><!--
+  var mywindow = -1;
+  function myopen(filename,windowname,properties) {
+    myclose();
+    mywindow = window.open(filename,windowname,properties);
+  }
+  function myclose() {
+    if ( mywindow != -1 )
+      mywindow.close();
+    mywindow = -1
+  }
+//--></script>
+<FONT SIZE=7>ISP Signup form</FONT><BR><BR>
+<FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT>
+<FORM ACTION="<%= $self_url %>" METHOD=POST>
+<INPUT TYPE="hidden" NAME="magic" VALUE="process">
+<INPUT TYPE="hidden" NAME="ref" VALUE="<%= $referral_custnum %>">
+<INPUT TYPE="hidden" NAME="ss" VALUE="">
+Contact Information
+<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
+<TR>
+  <TH ALIGN="right"><font color="#ff0000">*</font>Contact name<BR>(last, first)</TH>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="last" VALUE="<%= $last %>">,
+                <INPUT TYPE="text" NAME="first" VALUE="<%= $first %>"></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Company</TD>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="company" SIZE=70 VALUE="<%= $company %>"></TD>
+</TR>
+<TR>
+  <TH ALIGN="right"><font color="#ff0000">*</font>Address</TH>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="address1" SIZE=70 VALUE="<%= $address1 %>"></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">&nbsp;</TD>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="address2" SIZE=70 VALUE="<%= $address2 %>"></TD>
+</TR>
+<TR>
+  <TH ALIGN="right"><font color="#ff0000">*</font>City</TH>
+  <TD><INPUT TYPE="text" NAME="city" VALUE="<%= $city %>"></TD>
+  <TH ALIGN="right"><font color="#ff0000">*</font>State/Country</TH>
+  <TD>
+    <%=
+        ($county_html, $state_html, $country_html) =
+          regionselector( $county, $state, $country );
+        "$county_html $state_html";
+    %>
+  </TD>
+  <TH><font color="#ff0000">*</font>Zip</TH>
+  <TD><INPUT TYPE="text" NAME="zip" SIZE=10 VALUE="<%= $zip %>"></TD>
+</TR>
+<TR>
+  <TH ALIGN="right"><font color="#ff0000">*</font>Country</TH>
+  <TD><%= $country_html %></TD>
+<TR>
+  <TD ALIGN="right">Day Phone</TD>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="<%= $daytime %>" SIZE=18></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Night Phone</TD>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="<%= $night %>" SIZE=18></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Fax</TD>
+  <TD COLSPAN=5><INPUT TYPE="text" NAME="fax" VALUE="<%= $fax %>" SIZE=12></TD>
+</TR>
+</TABLE><font color="#ff0000">*</font> required fields<BR>
+<BR>Billing information<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
+<TR><TD>
+
+  <%=
+    $OUT .= '<INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST"';
+    my @invoicing_list = split(', ', $invoicing_list );
+    $OUT .= ' CHECKED'
+      if ! @invoicing_list || grep { $_ eq 'POST' } @invoicing_list;
+    $OUT .= '>';
+  %>
+
+  Postal mail invoice
+</TD></TR>
+<TR><TD>Email invoice <INPUT TYPE="text" NAME="invoicing_list" VALUE="<%= join(', ', grep { $_ ne 'POST' } split(', ', $invoicing_list ) ) %>">
+</TD></TR>
+<%= scalar(@payby) > 1 ? '<TR><TD>Billing type</TD></TR>' : '' %>
+</TABLE>
+<TABLE BGCOLOR="#c0c0c0" BORDER=1 WIDTH="100%">
+<TR>
+
+  <%=
+
+    my $cardselect = '<SELECT NAME="CARD_type"><OPTION></OPTION>';
+    my %types = (
+                  'VISA' => 'VISA card',
+                  'MasterCard' => 'MasterCard',
+                  'Discover' => 'Discover card',
+                  'American Express' => 'American Express card',
+                );
+    foreach ( keys %types ) {
+      $selected = $cgi->param('CARD_type') eq $types{$_} ? 'SELECTED' : '';
+      $cardselect .= qq!<OPTION $selected VALUE="$types{$_}">$_</OPTION>!;
+    }
+    $cardselect .= '</SELECT>';
+  
+    my %payby = (
+      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!,
+      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="">!,
+      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="">!,
+      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="">!,
+      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!,
+      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", "12-2037"). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="Accounts Payable">!,
+      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("COMP"),
+      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="" MAXLENGTH=80>!,
+    );
+
+    if ( $init_data->{'cvv_enabled'} ) {
+      foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5
+        $payby{$payby} .= qq!<BR>CVV2&nbsp;(<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>)&nbsp;<INPUT TYPE="text" NAME=${payby}_paycvv VALUE="" SIZE=4 MAXLENGTH=4>!;
+      }
+    }
+
+    my( $account, $aba ) = split('@', $payinfo);
+    my %paybychecked = (
+      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname">!,
+      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="$payname">!,
+      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="$payname">!,
+      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="$payname">!,
+      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="$payinfo" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!,
+      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", $paydate). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="$payname">!,
+      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("COMP", $paydate),
+      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="$payinfo" MAXLENGTH=80>!,
+    );
+
+    if ( $init_data->{'cvv_enabled'} ) {
+      foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5
+        $paybychecked{$payby} .= qq!<BR>CVV2&nbsp;(<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>)&nbsp;<INPUT TYPE="text" NAME=${payby}_paycvv VALUE="$paycvv" SIZE=4 MAXLENGTH=4>!;
+      }
+    }
+
+    for (@payby) {
+      if ( scalar(@payby) == 1) {
+        $OUT .= '<TD VALIGN=TOP>'.
+                qq!<INPUT TYPE="hidden" NAME="payby" VALUE="$_">!.
+                "$paybychecked{$_}</TD>";
+      } else {
+        $OUT .= qq!<TD VALIGN=TOP><INPUT TYPE="radio" NAME="payby" VALUE="$_"!;
+        if ($payby eq $_) {
+          $OUT .= qq! CHECKED> $paybychecked{$_}</TD>!;
+        } else {
+          $OUT .= qq!> $payby{$_}</TD>!;
+        }
+
+      }
+    }
+  %>
+
+</TR></TABLE><font color="#ff0000">*</font> required fields for each billing type
+<BR><BR>First package
+<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
+<TR>
+  <TD COLSPAN=2><SELECT NAME="pkgpart"><OPTION VALUE="">(none)
+
+  <%=
+    foreach my $package ( @{$packages} ) {
+      $OUT .= '<OPTION VALUE="'. $package->{'pkgpart'}. '"';
+      $OUT .= ' SELECTED' if $pkgpart && $package->{'pkgpart'} == $pkgpart;
+      $OUT .= '>'. $package->{'pkg'};
+    }
+  %>
+
+  </SELECT></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Username</TD>
+  <TD><INPUT TYPE="text" NAME="username" VALUE="<%= $username %>"></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Password</TD>
+  <TD><INPUT TYPE="password" NAME="_password" VALUE="<%= $password %>"></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Re-enter Password</TD>
+  <TD><INPUT TYPE="password" NAME="_password2" VALUE="<%= $password2 %>"></TD>
+</TR>
+<%=
+  if ( $init_data->{'security_phrase'} ) {
+    $OUT .= <<ENDOUT;
+<TR>
+  <TD ALIGN="right">Security Phrase</TD>
+  <TD><INPUT TYPE="text" NAME="sec_phrase" VALUE="$sec_phrase">
+  </TD>
+</TR>
+ENDOUT
+  } else {
+    $OUT .= '<INPUT TYPE="hidden" NAME="sec_phrase" VALUE="">';
+  }
+%>
+<%=
+  if ( scalar(@$pops) ) {
+    $OUT .= '<TR><TD ALIGN="right">Access number</TD><TD>'.
+            popselector($popnum). '</TD></TR>';
+  } else {
+    $OUT .= popselector($popnum);
+  }
+%>
+</TABLE>
+<BR><BR>Enter up to ten external accounts from which to retrieve email
+<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
+<TR>
+  <TH ALIGN="left">Mail server</TH>
+  <TH ALIGN="left">Username</TH>
+  <TH ALIGN="left">Password</TH>
+</TR>
+<%=
+  for my $num ( 1..10 ) {
+    no strict 'vars';
+    $OUT .= qq!<TR><TD><INPUT TYPE="text" NAME="snarf_machine$num" VALUE="${"snarf_machine$num"}"></TD>!.
+            qq!<INPUT TYPE="hidden" NAME="snarf_protocol$num" VALUE="pop3">!.
+            qq!<TD><INPUT TYPE="text" NAME="snarf_username$num" VALUE="${"snarf_username$num"}"></TD>!.
+            qq!<TD><INPUT TYPE="password" NAME="snarf_password$num" VALUE="${"snarf_password$num"}"></TD>!.
+            qq!</TR>!;
+  }
+%>
+</TABLE>
+
+<BR><BR><INPUT TYPE="submit" VALUE="Signup">
+</FORM></BODY></HTML>
index 08d8a4d..0a9a510 100755 (executable)
@@ -1,15 +1,17 @@
 #!/usr/bin/perl -Tw
 #
-# $Id: signup.cgi,v 1.29 2002-05-30 22:45:20 ivan Exp $
+# $Id: signup.cgi,v 1.50 2004-01-04 03:52:54 ivan Exp $
 
 use strict;
-use vars qw( @payby $cgi $locales $packages $pops $init_data $error
+use vars qw( @payby $cgi $locales $packages
+             $pops %pop %popnum2pop
+             $init_data $error
              $last $first $ss $company $address1 $address2 $city $state $county
              $country $zip $daytime $night $fax $invoicing_list $payby $payinfo
-             $paydate $payname $referral_custnum
+             $paycvv $paydate $payname $referral_custnum $init_popstate
              $pkgpart $username $password $password2 $sec_phrase $popnum
-             $agentnum
-             $ieak_file $ieak_template $cck_file $cck_template
+             $agentnum $refnum
+             $ieak_file $ieak_template
              $signup_html $signup_template
              $success_html $success_template
              $decline_html $decline_template
@@ -18,13 +20,13 @@ use vars qw( @payby $cgi $locales $packages $pops $init_data $error
              $self_url
            );
 use subs qw( print_form print_okay print_decline
-             signup_default success_default decline_default
+             success_default decline_default
              expselect );
 use CGI;
 #use CGI::Carp qw(fatalsToBrowser);
 use Text::Template;
 use Business::CreditCard;
-use HTTP::Headers::UserAgent 2.00;
+use HTTP::BrowserDetect;
 use FS::SignupClient 0.03 qw( signup_info new_customer );
 
 #acceptable payment methods
@@ -35,7 +37,6 @@ use FS::SignupClient 0.03 qw( signup_info new_customer );
 @payby = qw( CARD PREPAY );
 
 $ieak_file = '/usr/local/freeside/ieak.template';
-$cck_file = '/usr/local/freeside/cck.template';
 $signup_html = -e 'signup.html'
                  ? 'signup.html'
                  : '/usr/local/freeside/signup.html';
@@ -60,17 +61,6 @@ if ( -e $ieak_file ) {
   $ieak_template = '';
 }
 
-if ( -e $cck_file ) {
-  my $cck_txt = Text::Template::_load_text($cck_file)
-    or die $Text::Template::ERROR;
-  $cck_txt =~ /^(.*)$/s; #untaint the template source - it's trusted
-  $cck_txt = $1;
-  $cck_template = new Text::Template ( TYPE => 'STRING', SOURCE => $cck_txt )
-    or die $Text::Template::ERROR;
-} else {
-  $cck_template = '';
-}
-
 $agentnum = '';
 if ( -e $signup_html ) {
   my $signup_txt = Text::Template::_load_text($signup_html)
@@ -88,11 +78,13 @@ if ( -e $signup_html ) {
     $agentnum = $1;
   }
 } else {
-  $signup_template = new Text::Template ( TYPE => 'STRING',
-                                          SOURCE => &signup_default,
-                                          DELIMITERS => [ '<%=', '%>' ]
-                                        )
-    or die $Text::Template::ERROR;
+  #too much maintenance hassle to keep in this file
+  die "can't find ./signup.html or /usr/local/freeside/signup.html";
+  #$signup_template = new Text::Template ( TYPE => 'STRING',
+  #                                        SOURCE => &signup_default,
+  #                                        DELIMITERS => [ '<%=', '%>' ]
+  #                                      )
+  #  or die $Text::Template::ERROR;
 }
 
 if ( -e $success_html ) {
@@ -135,23 +127,48 @@ if ( -e $decline_html ) {
 ( $locales, $packages, $pops, $init_data ) = signup_info();
 @payby = @{$init_data->{'payby'}} if @{$init_data->{'payby'}};
 $packages = $init_data->{agentnum2part_pkg}{$agentnum} if $agentnum;
+%pop = ();
+%popnum2pop = ();
+foreach (@$pops) {
+  push @{ $pop{ $_->{state} }->{ $_->{ac} } }, $_;
+  $popnum2pop{$_->{popnum}} = $_;
+}
 
 $cgi = new CGI;
 
 if ( defined $cgi->param('magic') ) {
   if ( $cgi->param('magic') eq 'process' ) {
 
-    $cgi->param('state') =~ /^(\w*)( \(([\w ]+)\))? ?\/ ?(\w+)$/
-      or die "Oops, illegal \"state\" param: ". $cgi->param('state');
-    $state = $1;
-    $county = $3 || '';
-    $country = $4;
+    if ( $cgi->param('state') =~ /^(\w*)( \(([\w ]+)\))? ?\/ ?(\w+)$/ ) {
+      $state = $1;
+      $county = $3 || '';
+      $country = $4;
+    } elsif ( $cgi->param('state') =~ /^(\w*)$/ ) {
+      $state = $1;
+      $cgi->param('county') =~ /^([\w ]*)$/
+        or die "illegal county: ". $cgi->param('county');
+      $county = $1;
+      $cgi->param('country') =~ /^(\w+)$/
+        or die "illegal country: ". $cgi->param('country');
+      $country = $1;
+    } else {
+      die "illegal state: ". $cgi->param('state');
+    }
 
     $payby = $cgi->param('payby');
-    $payinfo = $cgi->param( $payby. '_payinfo' );
+    if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) {
+      #$payinfo = join('@', map { $cgi->param( $payby. "_payinfo$_" ) } (1,2) );
+      $payinfo = $cgi->param($payby. '_payinfo1'). '@'. 
+                 $cgi->param($payby. '_payinfo2');
+    } else {
+      $payinfo = $cgi->param( $payby. '_payinfo' );
+    }
     $paydate =
       $cgi->param( $payby. '_month' ). '-'. $cgi->param( $payby. '_year' );
     $payname = $cgi->param( $payby. '_payname' );
+    $paycvv = defined $cgi->param( $payby. '_paycvv' )
+                ? $cgi->param( $payby. '_paycvv' )
+                : '';
 
     if ( $invoicing_list = $cgi->param('invoicing_list') ) {
       $invoicing_list .= ', POST' if $cgi->param('invoicing_list_POST');
@@ -187,6 +204,9 @@ if ( defined $cgi->param('magic') ) {
     $password         = $cgi->param('_password');
     $popnum           = $cgi->param('popnum');
     #$agentnum, #         = $cgi->param('agentnum'),
+    $agentnum         ||= $cgi->param('agentnum');
+    $init_popstate    = $cgi->param('init_popstate');
+    $refnum           = $cgi->param('refnum');
 
     if ( $cgi->param('_password') ne $cgi->param('_password2') ) {
       $error = $init_data->{msgcat}{passwords_dont_match}; #msgcat
@@ -195,7 +215,7 @@ if ( defined $cgi->param('magic') ) {
     } else {
       $password2 = $cgi->param('_password2');
 
-      if ( $payby eq 'CARD' && $cgi->param('CARD_type') ) {
+      if ( $payby =~ /^(CARD|DCRD)$/ && $cgi->param('CARD_type') ) {
         $payinfo =~ s/\D//g;
 
         $payinfo =~ /^(\d{13,16})$/
@@ -224,6 +244,7 @@ if ( defined $cgi->param('magic') ) {
         'fax'              => $fax,
         'payby'            => $payby,
         'payinfo'          => $payinfo,
+        'paycvv'           => $paycvv,
         'paydate'          => $paydate,
         'payname'          => $payname,
         'invoicing_list'   => $invoicing_list,
@@ -234,6 +255,8 @@ if ( defined $cgi->param('magic') ) {
         '_password'        => $password,
         'popnum'           => $popnum,
         'agentnum'         => $agentnum,
+        'refnum'           => $refnum,
+        map { $_ => $cgi->param($_) } grep { /^snarf_/ } $cgi->param
       } );
 
     }
@@ -241,6 +264,9 @@ if ( defined $cgi->param('magic') ) {
     if ( $error eq '_decline' ) {
       print_decline();
     } elsif ( $error ) {
+      #fudge the snarf info
+      no strict 'refs';
+      ${$_} = $cgi->param($_) foreach grep { /^snarf_/ } $cgi->param;
       print_form();
     } else {
       print_okay();
@@ -258,9 +284,9 @@ if ( defined $cgi->param('magic') ) {
   $address1 = '';
   $address2 = '';
   $city = '';
-  $state = '';
+  $state = $init_data->{statedefault};
   $county = '';
-  $country = '';
+  $country = $init_data->{countrydefault};
   $zip = '';
   $daytime = '';
   $night = '';
@@ -277,12 +303,15 @@ if ( defined $cgi->param('magic') ) {
   $sec_phrase = '';
   $popnum = '';
   $referral_custnum = $cgi->param('ref') || '';
+  $init_popstate = $cgi->param('init_popstate') || '';
+  $refnum = $init_data->{'refnum'};
   print_form;
 }
 
 sub print_form {
 
   $cgi->delete('ref');
+  $cgi->delete('init_popstate');
   $self_url = $cgi->self_url;
 
   $error = "Error: $error" if $error;
@@ -298,7 +327,7 @@ sub print_decline {
 }
 
 sub print_okay {
-  my $user_agent = new HTTP::Headers::UserAgent $ENV{HTTP_USER_AGENT};
+  my $user_agent = new HTTP::BrowserDetect $ENV{HTTP_USER_AGENT};
 
   $cgi->param('username') =~ /^(.+)$/
     or die "fatal: invalid username got past FS::SignupClient::new_customer";
@@ -310,7 +339,7 @@ sub print_okay {
     or die "fatal: invalid email_name got past FS::SignupClient::new_customer";
   $email_name = $1; #global for template
 
-  my $pop = pop_info($cgi->param('popnum'));
+  my $pop = $popnum2pop{$cgi->param('popnum')};
     #or die "fatal: invalid popnum got past FS::SignupClient::new_customer";
   if ( $pop ) {
     ( $ac, $exch, $loc ) = ( $pop->{'ac'}, $pop->{'exch'}, $pop->{'loc'} );
@@ -321,54 +350,33 @@ sub print_okay {
   #global for template
   $pkg = ( grep { $_->{'pkgpart'} eq $pkgpart } @$packages )[0]->{'pkg'};
 
-  if ( $ieak_template
-       && $user_agent->platform eq 'ia32'
-       && $user_agent->os =~ /^win/
-       && ($user_agent->browser)[0] eq 'IE'
-     )
-  { #send an IEAK config
+  if ( $ieak_template && $user_agent->windows && $user_agent->ie ) {
+    #send an IEAK config
     print $cgi->header('application/x-Internet-signup'),
           $ieak_template->fill_in();
-  } elsif ( $cck_template
-            && $user_agent->platform eq 'ia32'
-            && $user_agent->os =~ /^win/
-            && ($user_agent->browser)[0] eq 'Netscape'
-          )
-  { #send a Netscape config
-    my $cck_data = $cck_template->fill_in();
-    print $cgi->header('application/x-netscape-autoconfigure-dialer-v2'),
-          map {
-            m/(.*)\s+(.*)$/;
-            pack("N", length($1)). $1. pack("N", length($2)). $2;
-          } split(/\n/, $cck_data);
-
   } else { #send a simple confirmation
     print $cgi->header( '-expires' => 'now' ),
           $success_template->fill_in();
   }
 }
 
-sub pop_info {
-  my $popnum = shift;
-  my $pop;
-  foreach $pop ( @{$pops} ) {
-    if ( $pop->{'popnum'} == $popnum ) { return $pop; }
-  }
-  '';
-}
-
 #horrible false laziness with FS/FS/svc_acct_pop.pm::popselector
 sub popselector {
-  my( $popnum, $state ) = @_;
+
+  my( $popnum ) = @_;
 
   return '<INPUT TYPE="hidden" NAME="popnum" VALUE="">' unless @$pops;
   return $pops->[0]{city}. ', '. $pops->[0]{state}.
-         ' ('. $pops->[0]{ac}. ')/'. $pops->[0]{exch}.
+         ' ('. $pops->[0]{ac}. ')/'. $pops->[0]{exch}. '-'. $pops->[0]{loc}.
          '<INPUT TYPE="hidden" NAME="popnum" VALUE="'. $pops->[0]{popnum}. '">'
     if scalar(@$pops) == 1;
 
-  my %pop = ();
-  push @{ $pop{$_->{state}} }, $_ foreach @$pops;
+  #my %pop = ();
+  #my %popnum2pop = ();
+  #foreach (@$pops) {
+  #  push @{ $pop{ $_->{state} }->{ $_->{ac} } }, $_;
+  #  $popnum2pop{$_->{popnum}} = $_;
+  #}
 
   my $text = <<END;
     <SCRIPT>
@@ -377,45 +385,95 @@ sub popselector {
       var length = what.length;
       what.options[length] = optionName;
     }
-    
-    function popstate_changed(what) {
-      state = what.options[what.selectedIndex].text;
-      for (var i = what.form.popnum.length;i > 0;i--)
-                what.form.popnum.options[i] = null;
-      what.form.popnum.options[0] = new Option("", "", false, true);
 END
 
-  foreach my $popstate ( sort { $a cmp $b } keys %pop ) {
-    $text .= "\nif ( state == \"$popstate\" ) {\n";
+  if ( $init_popstate ) {
+    $text .= '<INPUT TYPE="hidden" NAME="init_popstate" VALUE="'.
+             $init_popstate. '">';
+  } else {
+    $text .= <<END;
+      function acstate_changed(what) {
+        state = what.options[what.selectedIndex].text;
+        what.form.popac.options.length = 0
+        what.form.popac.options[0] = new Option("Area code", "-1", false, true);
+END
+  } 
 
-    foreach my $pop ( @{$pop{$popstate}}) {
-      my $o_popnum = $pop->{popnum};
-      my $poptext =  $pop->{city}. ', '. $pop->{state}.
-                     ' ('. $pop->{ac}. ')/'. $pop->{exch};
+  my @states = $init_popstate ? ( $init_popstate ) : keys %pop;
+  foreach my $state ( sort { $a cmp $b } @states ) {
+    $text .= "\nif ( state == \"$state\" ) {\n" unless $init_popstate;
 
-      $text .= "opt(what.form.popnum, \"$o_popnum\", \"$poptext\");\n"
+    foreach my $ac ( sort { $a cmp $b } keys %{ $pop{$state} }) {
+      $text .= "opt(what.form.popac, \"$ac\", \"$ac\");\n";
+      if ($ac eq $cgi->param('popac')) {
+        $text .= "what.form.popac.options[what.form.popac.length-1].selected = true;\n";
+      }
     }
-    $text .= "}\n";
+    $text .= "}\n" unless $init_popstate;
   }
+  $text .= "popac_changed(what.form.popac)}\n";
+
+  $text .= <<END;
+  function popac_changed(what) {
+    ac = what.options[what.selectedIndex].text;
+    what.form.popnum.options.length = 0;
+    what.form.popnum.options[0] = new Option("City", "-1", false, true);
+
+END
+
+  foreach my $state ( @states ) {
+    foreach my $popac ( keys %{ $pop{$state} } ) {
+      $text .= "\nif ( ac == \"$popac\" ) {\n";
+
+      foreach my $pop ( @{$pop{$state}->{$popac}}) {
+        my $o_popnum = $pop->{popnum};
+        my $poptext =  $pop->{city}. ', '. $pop->{state}.
+                       ' ('. $pop->{ac}. ')/'. $pop->{exch}. '-'. $pop->{loc};
+
+        $text .= "opt(what.form.popnum, \"$o_popnum\", \"$poptext\");\n";
+        if ($popnum == $o_popnum) {
+          $text .= "what.form.popnum.options[what.form.popnum.length-1].selected = true;\n";
+        }
+      }
+      $text .= "}\n";
+    }
+  }
+
 
   $text .= "}\n</SCRIPT>\n";
 
   $text .=
-    qq!<SELECT NAME="popstate" SIZE=1 onChange="popstate_changed(this)">!.
-    qq!<OPTION> !;
-  $text .= "<OPTION>$_" foreach sort { $a cmp $b } keys %pop;
-  $text .= '</SELECT>'; #callback? return 3 html pieces?  #'</TD><TD>';
+    qq!<TABLE CELLPADDING="0"><TR><TD><SELECT NAME="acstate"! .
+    qq!SIZE=1 onChange="acstate_changed(this)"><OPTION VALUE=-1>State!;
+  $text .= "<OPTION" . ($_ eq $cgi->param('acstate') ? " SELECTED" : "") .
+           ">$_" foreach sort { $a cmp $b } @states;
+  $text .= '</SELECT>'; #callback? return 3 html pieces?  #'</TD>';
+
+  $text .=
+    qq!<SELECT NAME="popac" SIZE=1 onChange="popac_changed(this)">!.
+    qq!<OPTION>Area code</SELECT></TR><TR VALIGN="top">!;
 
-  $text .= qq!<SELECT NAME="popnum" SIZE=1><OPTION> !;
-  foreach my $pop ( @$pops ) {
+  $text .= qq!<TR><TD><SELECT NAME="popnum" SIZE=1 STYLE="width: 20em"><OPTION>City!;
+
+
+  #comment this block to disable initial list polulation
+  my @initial_select = ();
+  if ( scalar( @$pops ) > 100 ) {
+    push @initial_select, $popnum2pop{$popnum} if $popnum2pop{$popnum};
+  } else {
+    @initial_select = @$pops;
+  }
+  foreach my $pop ( sort { $a->{state} cmp $b->{state} } @initial_select ) {
     $text .= qq!<OPTION VALUE="!. $pop->{popnum}. '"'.
              ( ( $popnum && $pop->{popnum} == $popnum ) ? ' SELECTED' : '' ). ">".
              $pop->{city}. ', '. $pop->{state}.
-               ' ('. $pop->{ac}. ')/'. $pop->{exch};
+               ' ('. $pop->{ac}. ')/'. $pop->{exch}. '-'. $pop->{loc};
   }
-  $text .= '</SELECT>';
+
+  $text .= qq!</SELECT></TD></TR></TABLE>!;
 
   $text;
+
 }
 
 sub expselect {
@@ -444,6 +502,123 @@ sub expselect {
   $return;
 }
 
+#false laziness w/FS::cust_main_county
+sub regionselector {
+  my ( $selected_county, $selected_state, $selected_country,
+       $prefix, $onchange ) = @_;
+
+  $prefix = '' unless defined $prefix;
+
+  my $countyflag = 0;
+
+  my %cust_main_county;
+
+#  unless ( @cust_main_county ) { #cache 
+    #@cust_main_county = qsearch('cust_main_county', {} );
+    #foreach my $c ( @cust_main_county ) {
+    foreach my $c ( @$locales ) {
+      #$countyflag=1 if $c->county;
+      $countyflag=1 if $c->{county};
+      #push @{$cust_main_county{$c->country}{$c->state}}, $c->county;
+      #$cust_main_county{$c->country}{$c->state}{$c->county} = 1;
+      $cust_main_county{$c->{country}}{$c->{state}}{$c->{county}} = 1;
+    }
+#  }
+  $countyflag=1 if $selected_county;
+
+  my $script_html = <<END;
+    <SCRIPT>
+    function opt(what,value,text) {
+      var optionName = new Option(text, value, false, false);
+      var length = what.length;
+      what.options[length] = optionName;
+    }
+    function ${prefix}country_changed(what) {
+      country = what.options[what.selectedIndex].text;
+      for ( var i = what.form.${prefix}state.length; i >= 0; i-- )
+          what.form.${prefix}state.options[i] = null;
+END
+      #what.form.${prefix}state.options[0] = new Option('', '', false, true);
+
+  foreach my $country ( sort keys %cust_main_county ) {
+    $script_html .= "\nif ( country == \"$country\" ) {\n";
+    foreach my $state ( sort keys %{$cust_main_county{$country}} ) {
+      my $text = $state || '(n/a)';
+      $script_html .= qq!opt(what.form.${prefix}state, "$state", "$text");\n!;
+    }
+    $script_html .= "}\n";
+  }
+
+  $script_html .= <<END;
+    }
+    function ${prefix}state_changed(what) {
+END
+
+  if ( $countyflag ) {
+    $script_html .= <<END;
+      state = what.options[what.selectedIndex].text;
+      country = what.form.${prefix}country.options[what.form.${prefix}country.selectedIndex].text;
+      for ( var i = what.form.${prefix}county.length; i >= 0; i-- )
+          what.form.${prefix}county.options[i] = null;
+END
+
+    foreach my $country ( sort keys %cust_main_county ) {
+      $script_html .= "\nif ( country == \"$country\" ) {\n";
+      foreach my $state ( sort keys %{$cust_main_county{$country}} ) {
+        $script_html .= "\nif ( state == \"$state\" ) {\n";
+          #foreach my $county ( sort @{$cust_main_county{$country}{$state}} ) {
+          foreach my $county ( sort keys %{$cust_main_county{$country}{$state}} ) {
+            my $text = $county || '(n/a)';
+            $script_html .=
+              qq!opt(what.form.${prefix}county, "$county", "$text");\n!;
+          }
+        $script_html .= "}\n";
+      }
+      $script_html .= "}\n";
+    }
+  }
+
+  $script_html .= <<END;
+    }
+    </SCRIPT>
+END
+
+  my $county_html = $script_html;
+  if ( $countyflag ) {
+    $county_html .= qq!<SELECT NAME="${prefix}county" onChange="$onchange">!;
+    $county_html .= '</SELECT>';
+  } else {
+    $county_html .=
+      qq!<INPUT TYPE="hidden" NAME="${prefix}county" VALUE="$selected_county">!;
+  }
+
+  my $state_html = qq!<SELECT NAME="${prefix}state" !.
+                   qq!onChange="${prefix}state_changed(this); $onchange">!;
+  foreach my $state ( sort keys %{ $cust_main_county{$selected_country} } ) {
+    my $text = $state || '(n/a)';
+    my $selected = $state eq $selected_state ? 'SELECTED' : '';
+    $state_html .= "\n<OPTION $selected VALUE=$state>$text</OPTION>"
+  }
+  $state_html .= '</SELECT>';
+
+  $state_html .= '</SELECT>';
+
+  my $country_html = qq!<SELECT NAME="${prefix}country" !.
+                     qq!onChange="${prefix}country_changed(this); $onchange">!;
+  my $countrydefault = $init_data->{countrydefault} || 'US';
+  foreach my $country (
+    sort { ($b eq $countrydefault) <=> ($a eq $countrydefault) or $a cmp $b }
+      keys %cust_main_county
+  ) {
+    my $selected = $country eq $selected_country ? ' SELECTED' : '';
+    $country_html .= "\n<OPTION$selected>$country</OPTION>"
+  }
+  $country_html .= '</SELECT>';
+
+  ($county_html, $state_html, $country_html);
+
+}
+
 sub success_default { #html to use if you don't specify a success file
   <<'END';
 <HTML><HEAD><TITLE>Signup successful</TITLE></HEAD>
@@ -454,7 +629,7 @@ Signup information for <%= $email_name %>:
 <BR><BR>
 Username: <%= $username %><BR>
 Password: <%= $password %><BR>
-Access number: (<%= $ac %>) / $exch - $local<BR>
+Access number: (<%= $ac %>) / <%= $exch %> - <%= $local %><BR>
 Package: <%= $pkg %><BR>
 </BODY></HTML>
 END
@@ -470,187 +645,3 @@ support.
 END
 }
 
-sub signup_default { #html to use if you don't specify a template file
-  <<'END';
-<HTML><HEAD><TITLE>ISP Signup form</TITLE></HEAD>
-<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>ISP Signup form</FONT><BR><BR>
-<FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT>
-<FORM ACTION="<%= $self_url %>" METHOD=POST>
-<INPUT TYPE="hidden" NAME="magic" VALUE="process">
-<INPUT TYPE="hidden" NAME="ref" VALUE="<%= $referral_custnum %>">
-<INPUT TYPE="hidden" NAME="ss" VALUE="">
-Contact Information
-<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
-<TR>
-  <TH ALIGN="right"><font color="#ff0000">*</font>Contact name<BR>(last, first)</TH>
-  <TD COLSPAN=5><INPUT TYPE="text" NAME="last" VALUE="<%= $last %>">,
-                <INPUT TYPE="text" NAME="first" VALUE="<%= $first %>"></TD>
-</TR>
-<TR>
-  <TD ALIGN="right">Company</TD>
-  <TD COLSPAN=5><INPUT TYPE="text" NAME="company" SIZE=70 VALUE="<%= $company %>"></TD>
-</TR>
-<TR>
-  <TH ALIGN="right"><font color="#ff0000">*</font>Address</TH>
-  <TD COLSPAN=5><INPUT TYPE="text" NAME="address1" SIZE=70 VALUE="<%= $address1 %>"></TD>
-</TR>
-<TR>
-  <TD ALIGN="right">&nbsp;</TD>
-  <TD COLSPAN=5><INPUT TYPE="text" NAME="address2" SIZE=70 VALUE="<%= $address2 %>"></TD>
-</TR>
-<TR>
-  <TH ALIGN="right"><font color="#ff0000">*</font>City</TH>
-  <TD><INPUT TYPE="text" NAME="city" VALUE="<%= $city %>"></TD>
-  <TH ALIGN="right"><font color="#ff0000">*</font>State/Country</TH>
-  <TD><SELECT NAME="state" SIZE="1">
-
-  <%=
-    foreach ( @{$locales} ) {
-      $OUT .= '<OPTION';
-      $OUT .= ' SELECTED' if ( $state eq $_->{'state'}
-                               && $county eq $_->{'county'}
-                               && $country eq $_->{'country'}
-                             );
-      $OUT .= '>'. $_->{'state'};
-      $OUT .= ' ('. $_->{'county'}. ')' if $_->{'county'};
-      $OUT .= ' / '. $_->{'country'};
-    }
-  %>
-
-  </SELECT></TD>
-  <TH><font color="#ff0000">*</font>Zip</TH>
-  <TD><INPUT TYPE="text" NAME="zip" SIZE=10 VALUE="<%= $zip %>"></TD>
-</TR>
-<TR>
-  <TD ALIGN="right">Day Phone</TD>
-  <TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="<%= $daytime %>" SIZE=18></TD>
-</TR>
-<TR>
-  <TD ALIGN="right">Night Phone</TD>
-  <TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="<%= $night %>" SIZE=18></TD>
-</TR>
-<TR>
-  <TD ALIGN="right">Fax</TD>
-  <TD COLSPAN=5><INPUT TYPE="text" NAME="fax" VALUE="<%= $fax %>" SIZE=12></TD>
-</TR>
-</TABLE><font color="#ff0000">*</font> required fields<BR>
-<BR>Billing information<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
-<TR><TD>
-
-  <%=
-    $OUT .= '<INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST"';
-    my @invoicing_list = split(', ', $invoicing_list );
-    $OUT .= ' CHECKED'
-      if ! @invoicing_list || grep { $_ eq 'POST' } @invoicing_list;
-    $OUT .= '>';
-  %>
-
-  Postal mail invoice
-</TD></TR>
-<TR><TD>Email invoice <INPUT TYPE="text" NAME="invoicing_list" VALUE="<%= join(', ', grep { $_ ne 'POST' } split(', ', $invoicing_list ) ) %>">
-</TD></TR>
-<%= scalar(@payby) > 1 ? '<TR><TD>Billing type</TD></TR>' : '' %>
-</TABLE>
-<TABLE BGCOLOR="#c0c0c0" BORDER=1 WIDTH="100%">
-<TR>
-
-  <%=
-
-    my $cardselect = '<SELECT NAME="CARD_type"><OPTION></OPTION>';
-    my %types = (
-                  'VISA' => 'VISA card',
-                  'MasterCard' => 'MasterCard',
-                  'Discover' => 'Discover card',
-                  'American Express' => 'American Express card',
-                );
-    foreach ( keys %types ) {
-      $selected = $cgi->param('CARD_type') eq $types{$_} ? 'SELECTED' : '';
-      $cardselect .= qq!<OPTION $selected VALUE="$types{$_}">$_</OPTION>!;
-    }
-    $cardselect .= '</SELECT>';
-  
-    my %payby = (
-      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!,
-      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", "12-2037"). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="Accounts Payable">!,
-      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("COMP"),
-      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="" MAXLENGTH=80>!,
-    );
-
-    my %paybychecked = (
-      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname">!,
-      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", $paydate). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="$payname">!,
-      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("COMP", $paydate),
-      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="$payinfo" MAXLENGTH=80>!,
-    );
-
-    for (@payby) {
-      if ( scalar(@payby) == 1) {
-        $OUT .= '<TD VALIGN=TOP>'.
-                qq!<INPUT TYPE="hidden" NAME="payby" VALUE="$_">!.
-                "$paybychecked{$_}</TD>";
-      } else {
-        $OUT .= qq!<TD VALIGN=TOP><INPUT TYPE="radio" NAME="payby" VALUE="$_"!;
-        if ($payby eq $_) {
-          $OUT .= qq! CHECKED> $paybychecked{$_}</TD>!;
-        } else {
-          $OUT .= qq!> $payby{$_}</TD>!;
-        }
-
-      }
-    }
-  %>
-
-</TR></TABLE><font color="#ff0000">*</font> required fields for each billing type
-<BR><BR>First package
-<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
-<TR>
-  <TD COLSPAN=2><SELECT NAME="pkgpart"><OPTION VALUE="">(none)
-
-  <%=
-    foreach my $package ( @{$packages} ) {
-      $OUT .= '<OPTION VALUE="'. $package->{'pkgpart'}. '"';
-      $OUT .= ' SELECTED' if $pkgpart && $package->{'pkgpart'} == $pkgpart;
-      $OUT .= '>'. $package->{'pkg'};
-    }
-  %>
-
-  </SELECT></TD>
-</TR>
-<TR>
-  <TD ALIGN="right">Username</TD>
-  <TD><INPUT TYPE="text" NAME="username" VALUE="<%= $username %>"></TD>
-</TR>
-<TR>
-  <TD ALIGN="right">Password</TD>
-  <TD><INPUT TYPE="password" NAME="_password" VALUE="<%= $password %>"></TD>
-</TR>
-<TR>
-  <TD ALIGN="right">Re-enter Password</TD>
-  <TD><INPUT TYPE="password" NAME="_password2" VALUE="<%= $password2 %>"></TD>
-</TR>
-<%=
-  if ( $init_data->{'security_phrase'} ) {
-    $OUT .= <<ENDOUT;
-<TR>
-  <TD ALIGN="right">Security Phrase</TD>
-  <TD><INPUT TYPE="text" NAME="sec_phrase" VALUE="$sec_phrase">
-  </TD>
-</TR>
-ENDOUT
-  } else {
-    $OUT .= '<INPUT TYPE="hidden" NAME="sec_phrase" VALUE="">';
-  }
-%>
-<%=
-  if ( scalar(@$pops) ) {
-    $OUT .= '<TR><TD ALIGN="right">Access number</TD><TD>'.
-            popselector($popnum). '</TD></TR>';
-  } else {
-    $OUT .= popselector($popnum);
-  }
-%>
-</TABLE>
-<BR><BR><INPUT TYPE="submit" VALUE="Signup">
-</FORM></BODY></HTML>
-END
-}
index 6c60141..96bdac6 100755 (executable)
@@ -1,10 +1,33 @@
 <HTML><HEAD><TITLE>ISP Signup form</TITLE></HEAD>
-<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>ISP Signup form</FONT><BR><BR>
+<BODY BGCOLOR="#e8e8e8" onUnload="myclose()">
+<script language="JavaScript"><!--
+  var mywindow = -1;
+  function myopen(filename,windowname,properties) {
+    myclose();
+    mywindow = window.open(filename,windowname,properties);
+  }
+  function myclose() {
+    if ( mywindow != -1 )
+      mywindow.close();
+    mywindow = -1
+  }
+//--></script>
+<FONT SIZE=7>ISP Signup form</FONT><BR><BR>
 <FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT>
 <FORM ACTION="<%= $self_url %>" METHOD=POST>
 <INPUT TYPE="hidden" NAME="magic" VALUE="process">
 <INPUT TYPE="hidden" NAME="ref" VALUE="<%= $referral_custnum %>">
 <INPUT TYPE="hidden" NAME="ss" VALUE="">
+Where did you hear about our service? <SELECT NAME="refnum">
+<%=
+  $OUT .= '<OPTION VALUE="">' unless $refnum;
+  foreach my $part_referral ( @{$init_data->{'part_referral'}} ) {
+    $OUT .= '<OPTION VALUE="'. $part_referral->{'refnum'}. '"';
+    $OUT .= ' SELECTED' if $part_referral->{'refnum'} eq $refnum;
+    $OUT .= '>'. $part_referral->{'referral'};
+  }
+%>
+</SELECT><BR><BR>
 Contact Information
 <TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
 <TR>
@@ -28,26 +51,21 @@ Contact Information
   <TH ALIGN="right"><font color="#ff0000">*</font>City</TH>
   <TD><INPUT TYPE="text" NAME="city" VALUE="<%= $city %>"></TD>
   <TH ALIGN="right"><font color="#ff0000">*</font>State/Country</TH>
-  <TD><SELECT NAME="state" SIZE="1">
-
-  <%=
-    foreach ( @{$locales} ) {
-      $OUT .= '<OPTION';
-      $OUT .= ' SELECTED' if ( $state eq $_->{'state'}
-                               && $county eq $_->{'county'}
-                               && $country eq $_->{'country'}
-                             );
-      $OUT .= '>'. $_->{'state'};
-      $OUT .= ' ('. $_->{'county'}. ')' if $_->{'county'};
-      $OUT .= ' / '. $_->{'country'};
-    }
-  %>
-
-  </SELECT></TD>
+  <TD>
+    <%=
+        ($county_html, $state_html, $country_html) =
+          regionselector( $county, $state, $country );
+        "$county_html $state_html";
+    %>
+  </TD>
   <TH><font color="#ff0000">*</font>Zip</TH>
   <TD><INPUT TYPE="text" NAME="zip" SIZE=10 VALUE="<%= $zip %>"></TD>
 </TR>
 <TR>
+  <TH ALIGN="right"><font color="#ff0000">*</font>Country</TH>
+  <TD><%= $country_html %></TD>
+<TR>
   <TD ALIGN="right">Day Phone</TD>
   <TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="<%= $daytime %>" SIZE=18></TD>
 </TR>
@@ -97,18 +115,39 @@ Contact Information
   
     my %payby = (
       'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!,
+      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="">!,
+      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="">!,
+      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="">!,
+      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!,
       'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", "12-2037"). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="Accounts Payable">!,
       'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("COMP"),
       'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="" MAXLENGTH=80>!,
     );
 
+    if ( $init_data->{'cvv_enabled'} ) {
+      foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5
+        $payby{$payby} .= qq!<BR>CVV2&nbsp;(<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>)&nbsp;<INPUT TYPE="text" NAME=${payby}_paycvv VALUE="" SIZE=4 MAXLENGTH=4>!;
+      }
+    }
+
+    my( $account, $aba ) = split('@', $payinfo);
     my %paybychecked = (
       'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname">!,
+      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="$payname">!,
+      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="$payname">!,
+      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="$payname">!,
+      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="$payinfo" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!,
       'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", $paydate). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="$payname">!,
       'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("COMP", $paydate),
       'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="$payinfo" MAXLENGTH=80>!,
     );
 
+    if ( $init_data->{'cvv_enabled'} ) {
+      foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5
+        $paybychecked{$payby} .= qq!<BR>CVV2&nbsp;(<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>)&nbsp;<INPUT TYPE="text" NAME=${payby}_paycvv VALUE="$paycvv" SIZE=4 MAXLENGTH=4>!;
+      }
+    }
+
     for (@payby) {
       if ( scalar(@payby) == 1) {
         $OUT .= '<TD VALIGN=TOP>'.
diff --git a/fs_signup/FS-SignupClient/cgi/stateselect.html b/fs_signup/FS-SignupClient/cgi/stateselect.html
new file mode 100644 (file)
index 0000000..39823be
--- /dev/null
@@ -0,0 +1,80 @@
+<HTML><HEAD><TITLE>ISP Signup</TITLE></HEAD>
+<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>ISP Signup - state selection</FONT><BR><BR>
+<SCRIPT>
+function gotoURL(object) {
+    window.location.href = object.options[object.selectedIndex].value;
+}
+</SCRIPT>
+<FORM>
+Select your state: 
+<SELECT NAME="init_popstate" onChange="gotoURL(this.form.init_popstate)">
+<OPTION VALUE="stateselect.html"></OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=AL">ALABAMA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=AK">ALASKA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=AS">AMERICAN SAMOA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=AZ">ARIZONA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=AR">ARKANSAS</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=CA">CALIFORNIA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=CO">COLORADO</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=CT">CONNECTICUT</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=DE">DELAWARE</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=DC">DISTRICT OF COLUMBIA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=FM">FEDERATED STATES OF MICRONESIA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=FL">FLORIDA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=GA">GEORGIA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=GU">GUAM</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=HI">HAWAII</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=ID">IDAHO</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=IL">ILLINOIS</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=IN">INDIANA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=IA">IOWA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=KS">KANSAS</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=KY">KENTUCKY</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=LA">LOUISIANA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=ME">MAINE</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=MH">MARSHALL ISLANDS</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=MD">MARYLAND</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=MA">MASSACHUSETTS</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=MI">MICHIGAN</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=MN">MINNESOTA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=MS">MISSISSIPPI</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=MO">MISSOURI</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=MT">MONTANA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=NE">NEBRASKA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=NV">NEVADA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=NH">NEW HAMPSHIRE</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=NJ">NEW JERSEY</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=NM">NEW MEXICO</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=NY">NEW YORK</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=NC">NORTH CAROLINA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=ND">NORTH DAKOTA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=MP">NORTHERN MARIANA ISLANDS</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=OH">OHIO</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=OK">OKLAHOMA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=OR">OREGON</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=PW">PALAU</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=PA">PENNSYLVANIA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=PR">PUERTO RICO</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=RI">RHODE ISLAND</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=SC">SOUTH CAROLINA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=SD">SOUTH DAKOTA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=TN">TENNESSEE</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=TX">TEXAS</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=UT">UTAH</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=VT">VERMONT</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=VI">VIRGIN ISLANDS</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=VA">VIRGINIA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=WA">WASHINGTON</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=WV">WEST VIRGINIA</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=WI">WISCONSIN</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=WY">WYOMING</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=AE">Armed Forces Africa</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=AA">Armed Forces Americas</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=AE">Armed Forces Canada</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=AE">Armed Forces Europe</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=AE">Armed Forces Middle East</OPTION>
+<OPTION VALUE="signup.cgi?init_popstate=AP">Armed Forces Pacific</OPTION>
+</SELECT>
+</FORM>
+</BODY>
+</HTML>
diff --git a/fs_signup/fs_signup_server b/fs_signup/fs_signup_server
deleted file mode 100755 (executable)
index 7f962e0..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-#!/usr/bin/perl -Tw
-#
-# fs_signup_server
-#
-
-use strict;
-use vars qw($pid);
-use IO::Handle;
-use Storable qw(nstore_fd fd_retrieve);
-use Tie::RefHash;
-use Net::SSH qw(sshopen2);
-use FS::UID qw(adminsuidsetup);
-use FS::Conf;
-use FS::Record qw( qsearch qsearchs );
-use FS::cust_main_county;
-use FS::cust_main;
-use FS::Msgcat qw(gettext);
-
-use vars qw( $opt $Debug );
-
-$Debug = 2;
-
-my $user = shift or die &usage;
-&adminsuidsetup( $user ); 
-
-my $conf = new FS::Conf;
-
-#my @payby = qw(CARD PREPAY);
-my @payby = $conf->config('signup_server-payby');
-my $smtpmachine = $conf->config('smtpmachine');
-
-my $machine = shift or die &usage;
-
-my $agentnum = shift or die &usage;
-my $agent = qsearchs( 'agent', { 'agentnum' => $agentnum } ) or die &usage;
-my $pkgpart_href = $agent->pkgpart_hashref;
-
-my $refnum = shift or die &usage;
-
-#causing trouble for some folks
-#$SIG{CHLD} = sub { wait() };
-
-$SIG{HUP} = \&killssh;
-$SIG{INT} = \&killssh;
-$SIG{QUIT} = \&killssh;
-$SIG{TERM} = \&killssh;
-$SIG{PIPE} = \&killssh;
-sub killssh { kill 'TERM', $pid if $pid; exit; };
-
-my($fs_signupd)="/usr/local/sbin/fs_signupd";
-
-while (1) {
-  my($reader,$writer)=(new IO::Handle, new IO::Handle);
-  #seems to be broken - calling ->flush explicitly# $writer->autoflush(1);
-  warn "[fs_signup_server] Connecting to $machine...\n" if $Debug;
-  $pid = sshopen2($machine,$reader,$writer,$fs_signupd);
-
-  my @pops = qsearch('svc_acct_pop',{} );
-  my $init_data = {
-
-    #'_protocol' => 'signup',
-    #'_version' => '0.1',
-    #'_packet' => 'init'
-  
-    'cust_main_county' =>
-      [ map { $_->hashref } qsearch('cust_main_county', {}) ],
-      
-    'part_pkg' =>
-      [
-        #map { $_->hashref }
-        map { { 'payby' => [ $_->payby ], %{$_->hashref} } }
-          grep { $_->svcpart('svc_acct') && $pkgpart_href->{ $_->pkgpart } }
-            qsearch( 'part_pkg', { 'disabled' => '' } )
-      ],
-
-    'agentnum2part_pkg' =>
-      {
-        map {
-          my $href = $_->pkgpart_hashref;
-          $_->agentnum =>
-            [
-              map { { 'payby' => [ $_->payby ], %{$_->hashref} } }
-                grep { $_->svcpart('svc_acct') && $href->{ $_->pkgpart } }
-                  qsearch( 'part_pkg', { 'disabled' => '' } )
-            ];
-        } qsearch('agent', {} )
-      },
-
-    'svc_acct_pop' => [ map { $_->hashref } @pops ],
-
-    'security_phrase' => $conf->exists('security_phrase'),
-
-    'payby' => [ $conf->config('signup_server-payby') ],
-
-    'msgcat' => { map { $_=>gettext($_) } qw(
-      passwords_dont_match invalid_card unknown_card_type not_a
-    ) }
-
-  };
-
-  warn "[fs_signup_server] Sending init data...\n" if $Debug;
-  nstore_fd($init_data, $writer) or die "can't send init data: $!";
-  $writer->flush;
-
-  warn "[fs_signup_server] Entering main loop...\n" if $Debug;
-  while (1) {
-    warn "[fs_signup_server] Reading (waiting for) signup data...\n" if $Debug;
-    my $signup_data = fd_retrieve($reader);
-
-    if ( $Debug > 1 ) {
-      warn join('',
-        map { "  $_ => ". $signup_data->{$_}. "\n" } keys %$signup_data );
-    }
-
-    warn "[fs_signup_server] Processing signup...\n" if $Debug;
-
-    my $error = '';
-
-    #things that aren't necessary in base class, but are for signup server
-      #return "Passwords don't match"
-      #  if $hashref->{'_password'} ne $hashref->{'_password2'}
-    $error ||= gettext('empty_password') unless $signup_data->{'_password'};
-    $error ||= gettext('no_access_number_selected')
-      unless $signup_data->{'popnum'} || !scalar(@pops);
-
-    #shares some stuff with htdocs/edit/process/cust_main.cgi... take any
-    # common that are still here and library them.
-    my $cust_main = new FS::cust_main ( {
-      #'custnum'          => '',
-      'agentnum'         => $signup_data->{agentnum} || $agentnum,
-      'refnum'           => $refnum,
-
-      map { $_ => $signup_data->{$_} } qw(
-        last first ss company address1 address2 city county state zip country
-        daytime night fax payby payinfo paydate payname referral_custnum
-      ),
-
-    } );
-
-    $error ||= "Illegal payment type"
-      unless grep { $_ eq $signup_data->{'payby'} } @payby;
-
-    my @invoicing_list = split( /\s*\,\s*/, $signup_data->{'invoicing_list'} );
-
-    $signup_data->{'pkgpart'} =~ /^(\d+)$/ or '' =~ /^()$/;
-    my $pkgpart = $1;
-
-    my $part_pkg =
-      qsearchs( 'part_pkg', { 'pkgpart' => $pkgpart } )
-        or $error ||= "WARNING: unknown pkgpart: $pkgpart";
-    my $svcpart = $part_pkg->svcpart unless $error;
-
-    my $cust_pkg = new FS::cust_pkg ( {
-      #later#'custnum' => $custnum,
-      'pkgpart' => $signup_data->{'pkgpart'},
-    } );
-    $error ||= $cust_pkg->check;
-
-    my $svc_acct = new FS::svc_acct ( {
-      'svcpart'   => $svcpart,
-      map { $_ => $signup_data->{$_} }
-        qw( username _password sec_phrase popnum ),
-    } );
-
-    my $y = $svc_acct->setdefault; # arguably should be in new method
-    $error ||= $y unless ref($y);
-
-    $error ||= $svc_acct->check;
-
-    use Tie::RefHash;
-    tie my %hash, 'Tie::RefHash';
-    %hash = ( $cust_pkg => [ $svc_acct ] );
-    $error ||= $cust_main->insert( \%hash, \@invoicing_list ); #msgcat
-
-    if ( ! $error && $conf->exists('signup_server-realtime') ) {
-
-      warn "[fs_signup_server] Billing customer...\n" if $Debug;
-
-      my $bill_error = $cust_main->bill;
-      warn "[fs_signup_server] error billing new customer: $bill_error"
-        if $bill_error;
-
-      $cust_main->apply_payments;
-      $cust_main->apply_credits;
-
-      $bill_error = $cust_main->collect;
-      warn "[fs_signup_server] error collecting from new customer: $bill_error"
-        if $bill_error;
-
-      if ( $cust_main->balance > 0 ) {
-        #should check list for errors...
-        #$cust_main->suspend;
-        $cust_main->cancel;
-        $error = '_decline';
-      }
-    }
-
-    warn "[fs_signup_server] Sending results...\n" if $Debug;
-    print $writer $error, "\n";
-
-    next if $error;
-
-    if ( $conf->config('signup_server-email') ) {
-      warn "[fs_signup_server] Sending email...\n" if $Debug;
-
-      #false laziness w/FS::cust_bill::send & FS::cust_pay::delete
-      use Mail::Header;
-      use Mail::Internet 1.44;
-      use Date::Format;
-      my $from = $conf->config('invoice_from'); #??? as good as any
-      $ENV{MAILADDRESS} = $from;
-      my $header = new Mail::Header ( [
-        "From: $from",
-        "To: ". $conf->config('signup_server-email'),
-        "Sender: $from",
-        "Reply-To: $from",
-        "Date: ". time2str("%a, %d %b %Y %X %z", time),
-        "Subject: FREESIDE NOTIFICATION: Signup Server",
-      ] );
-      my $body = [
-        "This is an automatic message from your Freeside installation\n",
-        "informing you a customer has signed up via the signup server:\n",
-        "\n",
-        'custnum     : '. $cust_main->custnum. "\n",
-        'Name        : '. $cust_main->last. ", ". $cust_main->first. "\n",
-        'Agent       : '. $cust_main->agent->agent. "\n",
-        'Package     : '. $part_pkg->pkg. ' - '. $part_pkg->comment. "\n",
-        'Signup Date : '. time2str('%C', time). "\n",
-        'Username    : '. $svc_acct->username. "\n",
-        #'Password    : '. # config file to turn this on if noment insists
-        'Day phone   : '. $cust_main->daytime. "\n",
-        'Night phone : '. $cust_main->night. "\n",
-        'Address     : '. $cust_main->address1. "\n",
-        ( $cust_main->address2
-            ? '              '. $cust_main->address2. "\n"
-            : ''                                           ),
-        '              '. $cust_main->city. ', '. $cust_main->state. '  '.
-                          $cust_main->zip. "\n",
-        ( $cust_main->country eq 'US'
-            ? ''
-            : '              '. $cust_main->country. "\n" ),
-        "\n",
-      ];
-      #if ( $cust_main->balance > 0 ) {
-      #  push @$body,
-      #    "This customer has an outstanding balance and has been suspended.\n";
-      #}
-      my $message = new Mail::Internet ( 'Header' => $header, 'Body' => $body );
-      $!=0;
-      $message->smtpsend( Host => $smtpmachine )
-        or $message->smtpsend( Host => $smtpmachine, Debug => 1 )
-          or warn "[fs_signup_server] can't send email to ".
-                   $conf->config('signup_server-email').
-                   " via server $smtpmachine with SMTP: $!";
-      #end-of-send mail
-    }
-
-  }
-  close $writer;
-  close $reader;
-  warn "connection to $machine lost!  waiting 60 seconds...\n";
-  sleep 60;
-  warn "reconnecting...\n";
-}
-
-sub usage {
-  die "Usage:\n\n  fs_signup_server user machine agentnum refnum\n";
-}
-
index d04a5ed..8027ae3 100644 (file)
@@ -1,21 +1,29 @@
+BEGIN { eval "use Devel::AutoProfiler;"; } #only if installed...
+#BEGIN { package Devel::AutoProfiler; use vars qw(%caller_info); }
+#use Devel::AutoProfiler;
+
 use strict;
 use vars qw( $cgi $p );
-use CGI;
+use Apache::ASP 2.55;
+use CGI 2.47;
 #use CGI::Carp qw(fatalsToBrowser);
 use Date::Format;
 use Date::Parse;
+use Time::Local;
 use Tie::IxHash;
 use HTML::Entities;
 use IO::Handle;
 use IO::File;
 use String::Approx qw(amatch);
-use HTML::Widgets::SelectLayers 0.02;
+use Chart::LinesPoints;
+use HTML::Widgets::SelectLayers 0.03;
 use FS::UID qw(cgisuidsetup dbh getotaker datasrc driver_name);
 use FS::Record qw(qsearch qsearchs fields dbdef);
 use FS::Conf;
 use FS::CGI qw(header menubar popurl table itable ntable idiot eidiot
-               small_custview myexit);
+               small_custview myexit http_header);
 use FS::Msgcat qw(gettext geterror);
+use FS::Misc qw( send_email );
 
 use FS::agent;
 use FS::agent_type;
@@ -35,6 +43,8 @@ use FS::part_bill_event;
 use FS::part_pkg;
 use FS::part_referral;
 use FS::part_svc;
+use FS::part_svc_router;
+use FS::part_virtual_field;
 use FS::pkg_svc;
 use FS::port;
 use FS::queue qw(joblisting);
@@ -42,10 +52,13 @@ use FS::raddb;
 use FS::session;
 use FS::svc_acct;
 use FS::svc_acct_pop qw(popselector);
-use FS::svc_acct_sm;
 use FS::svc_domain;
 use FS::svc_forward;
 use FS::svc_www;
+use FS::router;
+use FS::addr_block;
+use FS::svc_broadband;
+use FS::svc_external;
 use FS::type_pkgs;
 use FS::part_export;
 use FS::part_export_option;
@@ -62,22 +75,159 @@ sub Script_OnStart {
   &cgisuidsetup($cgi);
   $p = popurl(2);
   #print $cgi->header( '-expires' => 'now' );
+  #dbh->{'private_profile'} = {} if dbh->can('sprintProfile');
+  dbh->{'private_profile'} = {} if UNIVERSAL::can(dbh, 'sprintProfile');
+
+  #really should check for FS::Profiler or something
+    # Devel::AutoProfiler _our_ VERSION?  thanks a fucking lot
+  if ( Devel::AutoProfiler->can('__recursively_fetch_subs_in_package') ) {
+    #should check to see it's my special version.  well, switch to FS::Profiler
+
+    #nicked from Devel::AutoProfiler::INIT
+    my %subs = Devel::AutoProfiler::__recursively_fetch_subs_in_package('main');
+
+
+    SUB : while( my ($name, $ref) = each(%subs) )
+      {
+        #next if $name =~ /^(main::)?Apache::/;
+        next unless $name =~ /FS/;
+        foreach my $sub (@Devel::AutoProfiler::do_not_instrument_this_sub)
+          {
+            if ($name =~ /$sub/)
+              {
+                next SUB;
+              }
+          }
+        next if ($Devel::AutoProfiler::do_not_instrument_this_sub{$name});
+        #warn "INIT name is $name \n";
+        Devel::AutoProfiler::__instrument_sub($name, $ref);
+      }
+
+  }
+
 }
 
 sub Script_OnFlush {
   my $ref = $Response->{BinaryRef};
-  $$ref = $cgi->header( @FS::CGI::header ) . $$ref;
-  if ( dbh->can('sprintProfile') ) {
-
-    $$ref =~ s/<\/BODY>[\s\n]*<\/HTML>[\s\n]*$//i
-      or warn "can't remove";
+  #$$ref = $cgi->header( @FS::CGI::header ) . $$ref;
+  #$$ref = $cgi->header() . $$ref;
+  #warn "Script_OnFlush called with dbh ". dbh. "\n";
+  #if ( dbh->can('sprintProfile') ) {
+  if ( UNIVERSAL::can(dbh, 'sprintProfile') ) {
+    #warn "dbh can sprintProfile\n";
+    if ( lc($Response->{ContentType}) eq 'text/html' ) { #con
+      #warn "contenttype is sprintProfile\n";
+      $$ref =~ s/<\/BODY>[\s\n]*<\/HTML>[\s\n]*$//i
+        or warn "can't remove";
   
-    #$$ref .= '<PRE>'. ("\n"x96). encode_entities(dbh->sprintProfile()). '</PRE>';
-    #  wtf?  konqueror...
-    $$ref .= '<PRE>'. ("\n"x4096). encode_entities(dbh->sprintProfile()). '</PRE>';
+      #$$ref .= '<PRE>'. ("\n"x96). encode_entities(dbh->sprintProfile()). '</PRE>';
+      #  wtf?  konqueror...
+      $$ref .= '<PRE>'. ("\n"x4096). encode_entities(dbh->sprintProfile()).
+               "\n\n". &sprintAutoProfile(). '</PRE>';
 
-    $$ref .= '</BODY></HTML>';
-    
+      $$ref .= '</BODY></HTML>';
+    }
     dbh->{'private_profile'} = {};
   }
 }
+
+#if ( defined(@DBIx::Profile::ISA) && DBIx::Profile::db->can('sprintProfile') ) {
+#if ( defined(@DBIx::Profile::ISA) && UNIVERSAL::can('DBIx::Profile::db', 'sprintProfile') ) {
+if ( defined(@DBIx::Profile::ISA) ) {
+
+  #warn "enabling profiling redirects";
+  *CGI::redirect = sub {
+    my( $self, $location) = @_;
+    my $page =
+      $cgi->header.
+      qq!<HTML><BODY>Redirect to <A HREF="$location">$location</A>!.
+      '<BR><BR><PRE>'.
+        ( UNIVERSAL::can(dbh, 'sprintProfile')
+            ? encode_entities(dbh->sprintProfile())
+            : 'DBIx::Profile missing sprintProfile method;'.
+              'unpatched or too old?'                        ).
+      "\n\n". &sprintAutoProfile().  '</PRE>'.
+      '</BODY></HTML>';
+    dbh->{'private_profile'} = {};
+    return $page;
+  };
+
+}
+
+sub by_total_time 
+{ 
+  return $a->{total_time_in_sub} <=> $b->{total_time_in_sub}; 
+}
+
+sub sprintAutoProfile {
+  my %caller_info = %Devel::AutoProfiler::caller_info;
+  return unless keys %caller_info;
+
+  %Devel::AutoProfiler::caller_info = ();
+
+  my @keys = keys(%caller_info);
+
+  foreach my $key (@keys)
+    {
+      my $href = $caller_info{$key};
+
+      $href->{who_am_i} = $key;
+    }
+
+  my @subs = values(%caller_info);
+
+  #my @sorted = sort by_total_time ( @subs );
+  my @sorted = reverse sort by_total_time ( @subs );
+
+  # print Dumper \@sorted;
+
+  my @readable_info;
+
+  foreach my $sort (@sorted)
+    {
+      push(@readable_info, delete($sort->{who_am_i}));
+      push(@readable_info, $sort);
+    }
+
+  use Data::Dumper;
+  return encode_entities(Dumper(\@readable_info));
+
+}
+
+sub include {
+  $Response->Include(@_);
+}
+
+if ( defined(@DBIx::Profile::ISA) ) {
+
+  #false laziness w/above
+  *redirect = sub {
+    my($location) = @_;
+
+    ${$Response->{BinaryRef}} = 
+      $cgi->header.
+      qq!<HTML><BODY>Redirect to <A HREF="$location">$location</A>!.
+      '<BR><BR><PRE>'.
+        ( UNIVERSAL::can(dbh, 'sprintProfile')
+            ? encode_entities(dbh->sprintProfile())
+            : 'DBIx::Profile missing sprintProfile method;'.
+              'unpatched or too old?'                        ).
+      "\n\n". &sprintAutoProfile().  '</PRE>'.
+      '</BODY></HTML>';
+
+    dbh->{'private_profile'} = {};
+
+    $Response->End;
+
+  };
+
+} else {
+
+  *redirect = sub {
+    $Response->Redirect(@_);
+  }
+
+}
+
+1;
+
index 49bcbc0..618c585 100644 (file)
@@ -7,7 +7,7 @@
 package HTML::Mason;
 
 # Bring in main Mason package.
-use HTML::Mason;
+use HTML::Mason 1.1;
 
 # Bring in ApacheHandler, necessary for mod_perl integration.
 # Uncomment the second line (and comment the first) to use
@@ -28,20 +28,25 @@ use strict;
 
 # Create Mason objects
 #
-my $parser = new HTML::Mason::Parser;
-my $interp = new HTML::Mason::Interp (parser=>$parser,
-                                      comp_root=>'/var/www/masondocs',
-                                      data_dir=>'/home/ivan/freeside_current/masondata',
-                                      out_mode=>'stream',
-                                     );
-my $ah = new HTML::Mason::ApacheHandler ( interp => $interp,
-                                          #auto_send_headers => 0,
-                                        );
+
+#my $parser = new HTML::Mason::Parser;
+#my $interp = new HTML::Mason::Interp (parser=>$parser,
+#                                      comp_root=>'/var/www/masondocs',
+#                                      data_dir=>'/usr/local/etc/freeside/masondata',
+#                                      out_mode=>'stream',
+#                                     );
+my $ah = new HTML::Mason::ApacheHandler (
+  #interp => $interp,
+  #auto_send_headers => 0,
+  comp_root=>'/var/www/freeside',
+  data_dir=>'/usr/local/etc/freeside/masondata',
+  #out_mode=>'stream',
+);
 
 # Activate the following if running httpd as root (the normal case).
 # Resets ownership of all files created by Mason at startup.
 #
-chown (Apache->server->uid, Apache->server->gid, $interp->files_written);
+#chown (Apache->server->uid, Apache->server->gid, $interp->files_written);
 
 sub handler
 {
@@ -57,22 +62,25 @@ sub handler
     { package HTML::Mason::Commands;
       use strict;
       use vars qw( $cgi $p );
-      use CGI;
+      use CGI 2.47;
       #use CGI::Carp qw(fatalsToBrowser);
       use Date::Format;
       use Date::Parse;
+      use Time::Local;
       use Tie::IxHash;
       use HTML::Entities;
       use IO::Handle;
       use IO::File;
       use String::Approx qw(amatch);
-      use HTML::Widgets::SelectLayers 0.02;
+      use Chart::LinesPoints;
+      use HTML::Widgets::SelectLayers 0.03;
       use FS::UID qw(cgisuidsetup dbh getotaker datasrc driver_name);
       use FS::Record qw(qsearch qsearchs fields dbdef);
       use FS::Conf;
       use FS::CGI qw(header menubar popurl table itable ntable idiot eidiot
-                     small_custview myexit);
+                     small_custview myexit http_header);
       use FS::Msgcat qw(gettext geterror);
+      use FS::Misc qw( send_email );
 
       use FS::agent;
       use FS::agent_type;
@@ -92,6 +100,8 @@ sub handler
       use FS::part_pkg;
       use FS::part_referral;
       use FS::part_svc;
+      use FS::part_svc_router;
+      use FS::part_virtual_field;
       use FS::pkg_svc;
       use FS::port;
       use FS::queue qw(joblisting);
@@ -99,10 +109,13 @@ sub handler
       use FS::session;
       use FS::svc_acct;
       use FS::svc_acct_pop qw(popselector);
-      use FS::svc_acct_sm;
       use FS::svc_domain;
       use FS::svc_forward;
       use FS::svc_www;
+      use FS::router;
+      use FS::addr_block;
+      use FS::svc_broadband;
+      use FS::svc_external;
       use FS::type_pkgs;
       use FS::part_export;
       use FS::part_export_option;
@@ -111,27 +124,73 @@ sub handler
 
       *CGI::redirect = sub {
         my( $self, $location ) = @_;
+        use vars qw($m);
+
+        if ( defined(@DBIx::Profile::ISA) ) { #profiling redirect
+
+          my $page =
+            qq!<HTML><BODY>Redirect to <A HREF="$location">$location</A>!.
+            '<BR><BR><PRE>'.
+              ( UNIVERSAL::can(dbh, 'sprintProfile')
+                  ? encode_entities(dbh->sprintProfile())
+                  : 'DBIx::Profile missing sprintProfile method;'.
+                    'unpatched or too old?'                        ).
+            #"\n\n". &sprintAutoProfile().  '</PRE>'.
+            "\n\n".                         '</PRE>'.
+            '</BODY></HTML>';
+          dbh->{'private_profile'} = {};
+          return $page;
+
+        } else { #normal redirect
+
+          $m->redirect($location);
+          '';
+
+        }
 
-        #http://www.masonhq.com/docs/faq/#how_do_i_do_an_external_redirect
-        $m->clear_buffer;
-        # The next two lines are necessary to stop Apache from re-reading
-        # POSTed data.
-        $r->method('GET');
-        $r->headers_in->unset('Content-length');
-        $r->content_type('text/html');
-        #$r->err_header_out('Location' => $location);
-        $r->header_out('Location' => $location);
-         $r->header_out('Content-Type' => 'text/html');
-         $m->abort(302);
-
-        '';
       };
 
       $cgi = new CGI;
       &cgisuidsetup($cgi);
       #&cgisuidsetup($r);
       $p = popurl(2);
-    }
+
+      sub include {
+        use vars qw($m);
+        $m->scomp(@_);
+      }
+
+      sub redirect {
+        my( $location ) = @_;
+        use vars qw($m);
+        $m->clear_buffer;
+        #false laziness w/above
+        if ( defined(@DBIx::Profile::ISA) ) { #profiling redirect
+
+          $m->print(
+            qq!<HTML><BODY>Redirect to <A HREF="$location">$location</A>!.
+            '<BR><BR><PRE>'.
+              ( UNIVERSAL::can(dbh, 'sprintProfile')
+                  ? encode_entities(dbh->sprintProfile())
+                  : 'DBIx::Profile missing sprintProfile method;'.
+                    'unpatched or too old?'                        ).
+            #"\n\n". &sprintAutoProfile().  '</PRE>'.
+            "\n\n".                         '</PRE>'.
+            '</BODY></HTML>'
+          );
+          dbh->{'private_profile'} = {};
+
+          $m->abort(200);
+
+        } else { #normal redirect
+
+          $m->redirect($location);
+
+        }
+
+      }
+
+    } # end package HTML::Mason::Commands;
 
     $r->content_type('text/html');
     #eorar
diff --git a/httemplate/autohandler b/httemplate/autohandler
new file mode 100644 (file)
index 0000000..2bd3adf
--- /dev/null
@@ -0,0 +1,21 @@
+% $m->call_next;
+<%init>
+  dbh->{'private_profile'} = {} if UNIVERSAL::can(dbh, 'sprintProfile');
+</%init>
+<%filter>
+
+my $profile = '';
+if ( UNIVERSAL::can(dbh, 'sprintProfile') ) {
+
+  if ( lc($r->content_type) eq 'text/html' ) {
+
+    $profile = '<PRE>'. ("\n"x4096). encode_entities(dbh->sprintProfile()).
+               #"\n\n". &sprintAutoProfile(). '</PRE>';
+               "\n\n".                        '</PRE>';
+  } 
+
+  dbh->{'private_profile'} = {};
+}
+
+s/(<\/BODY>[\s\n]*<\/HTML>[\s\n]*)$/$profile$1/i;
+</%filter>
diff --git a/httemplate/browse/addr_block.cgi b/httemplate/browse/addr_block.cgi
new file mode 100644 (file)
index 0000000..06ac556
--- /dev/null
@@ -0,0 +1,76 @@
+<%= header('Address Blocks', menubar('Main Menu'   => $p)) %>
+<%
+
+use NetAddr::IP;
+
+my @addr_block = qsearch('addr_block', {});
+my @router = qsearch('router', {});
+my $block;
+my $p2 = popurl(2);
+my $path = $p2 . "edit/process/addr_block";
+
+%>
+
+<% if ($cgi->param('error')) { %>
+   <FONT SIZE="+1" COLOR="#ff0000">Error: <%=$cgi->param('error')%></FONT>
+   <BR><BR>
+<% } %>
+
+<%=table()%>
+
+<% foreach $block (sort {$a->NetAddr cmp $b->NetAddr} @addr_block) { %>
+  <TR>
+    <TD><%=$block->NetAddr%></TD>
+  <% if (my $router = $block->router) { %>
+    <% if (scalar($block->svc_broadband) == 0) { %>
+    <TD>
+      <%=$router->routername%>
+    </TD>
+    <TD>
+      <FORM ACTION="<%=$path%>/deallocate.cgi" METHOD="POST">
+        <INPUT TYPE="hidden" NAME="blocknum" VALUE="<%=$block->blocknum%>">
+        <INPUT TYPE="submit" NAME="submit" VALUE="Deallocate">
+      </FORM>
+    </TD>
+    <% } else { %>
+    <TD COLSPAN="2">
+    <%=$router->routername%>
+    </TD>
+    <% } %>
+  <% } else { %>
+    <TD>
+      <FORM ACTION="<%=$path%>/allocate.cgi" METHOD="POST">
+        <INPUT TYPE="hidden" NAME="blocknum" VALUE="<%=$block->blocknum%>">
+        <SELECT NAME="routernum" SIZE="1">
+    <% foreach (@router) { %>
+          <OPTION VALUE="<%=$_->routernum %>"><%=$_->routername%></OPTION>
+    <% } %>
+        </SELECT>
+        <INPUT TYPE="submit" NAME="submit" VALUE="Allocate">
+      </FORM>
+    </TD>
+    <TD>
+      <FORM ACTION="<%=$path%>/split.cgi" METHOD="POST">
+        <INPUT TYPE="hidden" NAME="blocknum" VALUE="<%=$block->blocknum%>">
+        <INPUT TYPE="submit" NAME="submit" VALUE="Split">
+      </FORM>
+    </TD>
+  </TR>
+<% }
+ } %>
+  <TR><TD COLSPAN="3"><BR></TD></TR>
+  <TR>
+    <FORM ACTION="<%=$path%>/add.cgi" METHOD="POST">
+    <TD>Gateway/Netmask</TD>
+    <TD>
+      <INPUT TYPE="text" NAME="ip_gateway" SIZE="15">/<INPUT TYPE="text" NAME="ip_netmask" SIZE="2">
+    </TD>
+    <TD>
+      <INPUT TYPE="submit" NAME="submit" VALUE="Add">
+    </TD>
+    </FORM>
+  </TR>
+</TABLE>
+</BODY>
+</HTML>
+
index cff111c..2eef5bb 100755 (executable)
@@ -1,15 +1,38 @@
 <!-- mason kludge -->
+
 <%
-#Begin silliness
-#
-#use FS::UI::CGI;
-#use FS::UI::agent;
-#
-#$ui = new FS::UI::agent;
-#$ui->browse;
-#exit;
-#__END__
-#End silliness
+
+  my %search;
+  if ( $cgi->param('showdisabled')
+       || !dbdef->table('agent')->column('disabled') ) {
+    %search = ();
+  } else {
+    %search = ( 'disabled' => '' );
+  }
+
+  #bad false laziness with search/cust_main.cgi (also needs fixing up for
+  #old mysql)
+  my $ncancelled = "
+     0 < ( SELECT COUNT(*) FROM cust_pkg
+                  WHERE cust_pkg.custnum = cust_main.custnum
+                    AND ( cust_pkg.cancel IS NULL
+                          OR cust_pkg.cancel = 0
+                        )
+              )
+       OR 0 = ( SELECT COUNT(*) FROM cust_pkg
+                  WHERE cust_pkg.custnum = cust_main.custnum
+              )
+  ";
+
+  my $ncancelled_sth = dbh->prepare("SELECT COUNT(*) FROM cust_main
+                                       WHERE agentnum = ?
+                                         AND ( $ncancelled )         ")
+    or die dbh->errstr;
+
+  my $total_sth = dbh->prepare("SELECT COUNT(*) FROM cust_main
+                                  WHERE agentnum = ?           ")
+    or die dbh->errstr;
+
 %>
 
 <%= header('Agent Listing', menubar(
@@ -21,10 +44,20 @@ Agents are resellers of your service. Agents may be limited to a subset of your
 full offerings (via their type).<BR><BR>
 <A HREF="<%= $p %>edit/agent.cgi"><I>Add a new agent</I></A><BR><BR>
 
+<% if ( dbdef->table('agent')->column('disabled') ) { %>
+  <%= $cgi->param('showdisabled')
+      ? do { $cgi->param('showdisabled', 0);
+             '( <a href="'. $cgi->self_url. '">hide disabled agents</a> )'; }
+      : do { $cgi->param('showdisabled', 1);
+             '( <a href="'. $cgi->self_url. '">show disabled agents</a> )'; }
+  %>
+<% } %>
+
 <%= table() %>
 <TR>
-  <TH COLSPAN=2>Agent</TH>
+  <TH COLSPAN=<%= ( $cgi->param('showdisabled') || !dbdef->table('agent')->column('disabled') ) ? 2 : 3 %>>Agent</TH>
   <TH>Type</TH>
+  <TH>Customers</TH>
   <TH><FONT SIZE=-1>Freq.</FONT></TH>
   <TH><FONT SIZE=-1>Prog.</FONT></TH>
 </TR>
@@ -35,29 +68,44 @@ full offerings (via their type).<BR><BR>
 foreach my $agent ( sort { 
   #$a->getfield('agentnum') <=> $b->getfield('agentnum')
   $a->getfield('agent') cmp $b->getfield('agent')
-} qsearch('agent',{}) ) {
-  my($hashref)=$agent->hashref;
-  my($typenum)=$hashref->{typenum};
-  my($agent_type)=qsearchs('agent_type',{'typenum'=>$typenum});
-  my($atype)=$agent_type->getfield('atype');
-  print <<END;
+} qsearch('agent', \%search ) ) {
+
+  $ncancelled_sth->execute($agent->agentnum) or die $ncancelled_sth->errstr;
+  my $num_ncancelled = $ncancelled_sth->fetchrow_arrayref->[0];
+
+  $total_sth->execute($agent->agentnum) or die $total_sth->errstr;
+  my $num_total = $total_sth->fetchrow_arrayref->[0];
+
+  my $num_cancelled = $num_total - $num_ncancelled;
+
+  my $cust_main_link = $p. 'search/cust_main.cgi?agentnum_on=1&'.
+                       'agentnum='. $agent->agentnum;
+
+%>
+
       <TR>
-        <TD><A HREF="${p}edit/agent.cgi?$hashref->{agentnum}">
-          $hashref->{agentnum}</A></TD>
-        <TD><A HREF="${p}edit/agent.cgi?$hashref->{agentnum}">
-          $hashref->{agent}</A></TD>
-        <TD><A HREF="${p}edit/agent_type.cgi?$typenum">$atype</A></TD>
-        <TD>$hashref->{freq}</TD>
-        <TD>$hashref->{prog}</TD>
+        <TD><A HREF="<%=$p%>edit/agent.cgi?<%= $agent->agentnum %>">
+          <%= $agent->agentnum %></A></TD>
+<% if ( dbdef->table('agent')->column('disabled')
+        && !$cgi->param('showdisabled')           ) { %>
+        <TD><%= $agent->disabled ? 'DISABLED' : '' %></TD>
+<% } %>
+
+        <TD><A HREF="<%=$p%>edit/agent.cgi?<%= $agent->agentnum %>">
+          <%= $agent->agent %></A></TD>
+        <TD><A HREF="<%=$p%>edit/agent_type.cgi?<%= $agent->typenum %>"><%= $agent->agent_type->atype %></A></TD>
+        <TD>
+          <FONT COLOR="#00CC00"><B><%= $num_ncancelled %></B></FONT>
+            <A HREF="<%= $cust_main_link %>&showcancelledcustomers=0">active</A>
+          <BR><FONT COLOR="#FF0000"><B><%= $num_cancelled %></B></FONT>
+            <A HREF="<%= $cust_main_link %>&showcancelledcustomers=1&cancelled=1">cancelled</A>
+        </TD>
+        <TD><%= $agent->freq %></TD>
+        <TD><%= $agent->prog %></TD>
       </TR>
-END
 
-}
+<% } %>
 
-print <<END;
     </TABLE>
   </BODY>
 </HTML>
-END
-
-%>
index 5a84385..5473804 100755 (executable)
@@ -17,9 +17,11 @@ agents.<BR><BR>
 foreach my $agent_type ( sort { 
   $a->getfield('typenum') <=> $b->getfield('typenum')
 } qsearch('agent_type',{}) ) {
-  my($hashref)=$agent_type->hashref;
-  my(@type_pkgs)=qsearch('type_pkgs',{'typenum'=> $hashref->{typenum} });
-  my($rowspan)=scalar(@type_pkgs);
+  my $hashref = $agent_type->hashref;
+  #more efficient to do this with SQL...
+  my @type_pkgs = grep { $_->part_pkg and ! $_->part_pkg->disabled }
+                       qsearch('type_pkgs',{'typenum'=> $hashref->{typenum} });
+  my $rowspan = scalar(@type_pkgs);
   $rowspan = int($rowspan/2+0.5) ;
   print <<END;
       <TR>
index 9916060..1e0e088 100755 (executable)
@@ -21,9 +21,10 @@ print '<BR><BR>'. &table(). <<END;
         <TH><FONT SIZE=-1>Country</FONT></TH>
         <TH><FONT SIZE=-1>State</FONT></TH>
         <TH>County</TH>
-        <TH>Taxclass</TH>
+        <TH>Taxclass<BR><FONT SIZE=-1>(per-package classification)</FONT></TH>
+        <TH>Tax name<BR><FONT SIZE=-1>(printed on invoices)</FONT></TH>
         <TH><FONT SIZE=-1>Tax</FONT></TH>
-        <TH><FONT SIZE=-1>Exempt<BR>per<BR>month</TH>
+        <TH><FONT SIZE=-1>Exemption</TH>
       </TR>
 END
 
@@ -53,7 +54,9 @@ END
       last if $hashref->{country} ne $regions[$i+$j]->country
            || $hashref->{state} ne $regions[$i+$j]->state
            || $hashref->{tax} != $regions[$i+$j]->tax
-           || $hashref->{exempt_amount} != $regions[$i+$j]->exempt_amount;
+           || $hashref->{exempt_amount} != $regions[$i+$j]->exempt_amount
+           || $hashref->{setuptax} ne $regions[$i+$j]->setuptax
+           || $hashref->{recurtax} ne $regions[$i+$j]->recurtax;
     }
 
     my $newsup=0;
@@ -111,10 +114,22 @@ END
   }
   print "</TD>";
 
+  print "<TD";
+  if ( $hashref->{taxname} ) {
+    print ' BGCOLOR="#ffffff">'. $hashref->{taxname};
+  } else {
+    print ' BGCOLOR="#cccccc">Tax';
+  }
+  print "</TD>";
+
   print "<TD BGCOLOR=\"#ffffff\">$hashref->{tax}%</TD>".
-        '<TD BGCOLOR="#ffffff">$'.
-          sprintf("%.2f", $hashref->{exempt_amount} || 0). '</TD>'.
-        '</TR>';
+        '<TD BGCOLOR="#ffffff">';
+  print '$'. sprintf("%.2f", $hashref->{exempt_amount} ).
+        '&nbsp;per&nbsp;month<BR>'
+    if $hashref->{exempt_amount} > 0;
+  print 'Setup&nbsp;fee<BR>' if $hashref->{setuptax} =~ /^Y$/i;
+  print 'Recurring&nbsp;fee<BR>' if $hashref->{recurtax} =~ /^Y$/i;
+  print '</TD></TR>';
 
 }
 
index 608a58d..3420e97 100755 (executable)
@@ -1,10 +1,38 @@
 <!-- mason kludge -->
+<%= header("Pending credit card batch", menubar( 'Main Menu' => $p,)) %>
+
+<FORM ACTION="<%=$p%>misc/download-batch.cgi" METHOD="POST">
+Download batch in format <SELECT NAME="format">
+<OPTION VALUE="csv-td_canada_trust-merchant_pc_batch">CSV file for TD Canada Trust Merchant PC Batch</OPTION>
+</SELECT><INPUT TYPE="submit" VALUE="Download"></FORM>
+<BR><BR>
+
+<FORM ACTION="<%=$p%>misc/upload-batch.cgi" METHOD="POST" ENCTYPE="multipart/form-data">
+Upload results<BR>
+Filename <INPUT TYPE="file" NAME="batch_results"><BR>
+Format <SELECT NAME="format">
+<OPTION VALUE="csv-td_canada_trust-merchant_pc_batch">CSV results from TD Canada Trust Merchant PC Batch</OPTION>
+</SELECT><BR>
+<INPUT TYPE="submit" VALUE="Upload"></FORM>
+<BR>
+
 <%
+  my $statement = "SELECT SUM(amount) from cust_pay_batch";
+  my $sth = dbh->prepare($statement) or die dbh->errstr. "doing $statement";
+  $sth->execute or die "Error executing \"$statement\": ". $sth->errstr;
+  my $total = $sth->fetchrow_arrayref->[0];
 
-print header("Pending credit card batch", menubar(
-  'Main Menu' => $p,
-#  'Add new referral' => "../edit/part_referral.cgi",
-)), &table(), <<END;
+  my $c_statement = "SELECT COUNT(*) from cust_pay_batch";
+  my $c_sth = dbh->prepare($c_statement)
+    or die dbh->errstr. "doing $c_statement";
+  $c_sth->execute or die "Error executing \"$c_statement\": ". $c_sth->errstr;
+  my $cards = $c_sth->fetchrow_arrayref->[0];
+%>
+<%= $cards %> credit card payments batched<BR>
+$<%= sprintf("%.2f", $total) %> total in pending batch<BR>
+
+<BR>
+<%= &table() %>
       <TR>
         <TH>#</TH>
         <TH><font size=-1>inv#</font></TH>
@@ -14,39 +42,35 @@ print header("Pending credit card batch", menubar(
         <TH>Exp</TH>
         <TH>Amount</TH>
       </TR>
-END
-
-foreach my $cust_pay_batch ( sort { 
-  $a->getfield('paybatchnum') <=> $b->getfield('paybatchnum')
-} qsearch('cust_pay_batch',{}) ) {
-#  my $date = time2str( "%a %b %e %T %Y", $queue->_date );
-#  my $status = $hashref->{status};
-#  if ( $status eq 'failed' || $status eq 'locked' ) {
-#    $status .=
-#      qq! ( <A HREF="$p/edit/cust_pay_batch.cgi?jobnum=$jobnum&action=new">retry</A> |!.
-#      qq! <A HREF="$p/edit/cust_pay_batch.cgi?jobnum$jobnum&action=del">remove </A> )!;
-#  }
-  my $cardnum = $cust_pay_batch->{cardnum};
-  $cardnum =~ s/.{4}$/xxxx/;
-  print <<END;
+
+<%
+foreach my $cust_pay_batch ( sort { $a->paybatchnum <=> $b->paybatchnum }
+                             qsearch('cust_pay_batch', {} )
+) {
+  my $cardnum = $cust_pay_batch->cardnum;
+  #$cardnum =~ s/.{4}$/xxxx/;
+  $cardnum = 'x'x(length($cardnum)-4). substr($cardnum,(length($cardnum)-4));
+
+  $cust_pay_batch->exp =~ /^\d{2}(\d{2})[\/\-](\d+)[\/\-]\d+$/;
+  my( $mon, $year ) = ( $2, $1 );
+  $mon = "0$mon" if $mon < 10;
+  my $exp = "$mon/$year";
+
+%>
+
       <TR>
-        <TD>$cust_pay_batch->{paybatchnum}</TD>
-        <TD><A HREF="../view/cust_bill.cgi?$cust_pay_batch->{invnum}">$cust_pay_batch->{invnum}</TD>
-        <TD><A HREF="../view/cust_main.cgi?$cust_pay_batch->{custnum}">$cust_pay_batch->{custnum}</TD>
-        <TD>$cust_pay_batch->{last}, $cust_pay_batch->{last}</TD>
-        <TD>$cust_pay_batch->{payname}</TD>
-        <TD>$cardnum</TD>
-        <TD>$cust_pay_batch->{exp}</TD>
-        <TD align="right">\$$cust_pay_batch->{amount}</TD>
+        <TD><%= $cust_pay_batch->paybatchnum %></TD>
+        <TD><A HREF="../view/cust_bill.cgi?<%= $cust_pay_batch->invnum %>"><%= $cust_pay_batch->invnum %></TD>
+        <TD><A HREF="../view/cust_main.cgi?<%= $cust_pay_batch->custnum %>"><%= $cust_pay_batch->custnum %></TD>
+        <TD><%= $cust_pay_batch->get('last'). ', '. $cust_pay_batch->first %></TD>
+        <TD><%= $cust_pay_batch->payname %></TD>
+        <TD><%= $cardnum %></TD>
+        <TD><%= $exp %></TD>
+        <TD align="right">$<%= $cust_pay_batch->amount %></TD>
       </TR>
-END
 
-}
+<% } %>
 
-print <<END;
     </TABLE>
   </BODY>
 </HTML>
-END
-
-%>
diff --git a/httemplate/browse/generic.cgi b/httemplate/browse/generic.cgi
new file mode 100644 (file)
index 0000000..9ac0f23
--- /dev/null
@@ -0,0 +1,46 @@
+<%
+
+use FS::Record qw(qsearch dbdef);
+use DBIx::DBSchema;
+use DBIx::DBSchema::Table;
+
+my $error;
+my $p2 = popurl(2);
+my ($table) = $cgi->keywords;
+my $dbdef = dbdef or die "Cannot fetch dbdef!";
+my $dbdef_table = $dbdef->table($table) or die "Cannot fetch schema for $table";
+
+my $pkey = $dbdef_table->primary_key or die "Cannot fetch pkey for $table";
+print header("Browse $table", menubar('Main Menu'   => $p));
+
+my @rec = qsearch($table, {});
+my @col = $dbdef_table->columns;
+
+if ($cgi->param('error')) { %>
+   <FONT SIZE="+1" COLOR="#ff0000">Error: <%=$cgi->param('error')%></FONT>
+   <BR><BR>
+<% } 
+%>
+<A HREF="<%=$p2%>edit/<%=$table%>.cgi"><I>Add a new <%=$table%></I></A><BR><BR>
+
+<%=table()%>
+<TH>
+<% foreach (grep { $_ ne $pkey } @col) {
+  %><TD><%=$_%></TD>
+  <% } %>
+</TH>
+<% foreach $rec (sort {$a->getfield($pkey) cmp $b->getfield($pkey) } @rec) { 
+  %>
+  <TR>
+    <TD>
+      <A HREF="<%=$p2%>edit/<%=$table%>.cgi?<%=$rec->getfield($pkey)%>">
+      <%=$rec->getfield($pkey)%></A> </TD> <%
+  foreach $col (grep { $_ ne $pkey } @col)  { %>
+    <TD><%=$rec->getfield($col)%></TD> <% } %>
+  </A>
+  </TR>
+<% } %>
+</TABLE>
+</BODY>
+</HTML>
+
index 76662e0..79c57ae 100755 (executable)
@@ -26,7 +26,7 @@ function part_export_areyousure(href) {
       <%= itable() %>
       <% my %opt = $part_export->options;
          foreach my $opt ( keys %opt ) { %>
-           <TR><TD><%= $opt %></TD><TD><%= $opt{$opt} %></TD></TR>
+           <TR><TD><%= $opt %></TD><TD><%= encode_entities($opt{$opt}) %></TD></TR>
       <% } %>
       </TABLE>
     </TD>
index 58422c6..180f182 100755 (executable)
@@ -11,15 +11,50 @@ if ( $cgi->param('showdisabled') ) {
 my @part_pkg = qsearch('part_pkg', \%search );
 my $total = scalar(@part_pkg);
 
+my $sortby;
+my %num_active_cust_pkg = ();
+my( $suspended_sth, $canceled_sth ) = ( '', '' );
+if ( $cgi->param('active') ) {
+  my $active_sth = dbh->prepare(
+    'SELECT COUNT(*) FROM cust_pkg WHERE pkgpart = ?'.
+    ' AND ( cancel IS NULL OR cancel = 0 )'.
+    ' AND ( susp IS NULL OR susp = 0 )'
+  ) or die dbh->errstr;
+  foreach my $part_pkg ( @part_pkg ) {
+    $active_sth->execute($part_pkg->pkgpart) or die $active_sth->errstr;
+    $num_active_cust_pkg{$part_pkg->pkgpart} =
+      $active_sth->fetchrow_arrayref->[0];
+  }
+  $sortby = sub {
+    $num_active_cust_pkg{$b->pkgpart} <=> $num_active_cust_pkg{$a->pkgpart};
+  };
+
+  $suspended_sth = dbh->prepare(
+    'SELECT COUNT(*) FROM cust_pkg WHERE pkgpart = ?'.
+    ' AND ( cancel IS NULL OR cancel = 0 )'.
+    ' AND susp IS NOT NULL AND susp != 0'
+  ) or die dbh->errstr;
+
+  $canceled_sth = dbh->prepare(
+    'SELECT COUNT(*) FROM cust_pkg WHERE pkgpart = ?'.
+    ' AND cancel IS NOT NULL AND cancel != 0'
+  ) or die dbh->errstr;
+
+} else {
+  $sortby = \*pkgpart_sort;
+}
+
 %>
 <%= header("Package Definition Listing",menubar( 'Main Menu' => $p )) %>
-One or more services are grouped together into a package and given pricing
-information. Customers purchase packages rather than purchase services
-directly.<BR><BR>
-<A HREF="<%= $p %>edit/part_pkg.cgi"><I>Add a new package definition</I></A>
-<BR><BR>
+<% unless ( $cgi->param('active') ) { %>
+  One or more service definitions are grouped together into a package 
+  definition and given pricing information.  Customers purchase packages
+  rather than purchase services directly.<BR><BR>
+  <A HREF="<%= $p %>edit/part_pkg.cgi"><I>Add a new package definition</I></A>
+  <BR><BR>
+<% } %>
 
-<%= $total %> packages
+<%= $total %> package definitions
 <%
 if ( $cgi->param('showdisabled') ) {
   $cgi->param('showdisabled', 0);
@@ -34,17 +69,21 @@ print &table(), <<END;
       <TR>
         <TH COLSPAN=$colspan>Package</TH>
         <TH>Comment</TH>
+END
+print '        <TH><FONT SIZE=-1>Customer<BR>packages</FONT></TH>'
+  if $cgi->param('active');
+print <<END;
         <TH><FONT SIZE=-1>Freq.</FONT></TH>
         <TH><FONT SIZE=-1>Plan</FONT></TH>
         <TH><FONT SIZE=-1>Data</FONT></TH>
         <TH>Service</TH>
         <TH><FONT SIZE=-1>Quan.</FONT></TH>
-      </TR>
 END
+print '<TH><FONT SIZE=-1>Primary</FONT></TH>'
+   if dbdef->table('pkg_svc')->column('primary_svc');
+print '</TR>';
 
-foreach my $part_pkg ( sort { 
-  $a->getfield('pkgpart') <=> $b->getfield('pkgpart')
-} @part_pkg ) {
+foreach my $part_pkg ( sort $sortby @part_pkg ) {
   my($hashref)=$part_pkg->hashref;
   my(@pkg_svc)=grep $_->getfield('quantity'),
     qsearch('pkg_svc',{'pkgpart'=> $hashref->{pkgpart} });
@@ -73,6 +112,27 @@ END
   print <<END;
         <TD ROWSPAN=$rowspan><A HREF="${p}edit/part_pkg.cgi?$hashref->{pkgpart}">$hashref->{pkg}</A></TD>
         <TD ROWSPAN=$rowspan>$hashref->{comment}</TD>
+END
+  if ( $cgi->param('active') ) {
+    print "        <TD ROWSPAN=$rowspan>";
+    print '<FONT COLOR="#00CC00"><B>'.
+          $num_active_cust_pkg{$hashref->{'pkgpart'}}.
+          qq!</B></FONT>&nbsp;<A HREF="${p}search/cust_pkg.cgi?magic=active;pkgpart=$hashref->{pkgpart}">active</A><BR>!;
+
+    $suspended_sth->execute( $part_pkg->pkgpart ) or die $suspended_sth->errstr;
+    my $num_suspended = $suspended_sth->fetchrow_arrayref->[0];
+    print '<FONT COLOR="#FF9900"><B>'. $num_suspended.
+          qq!</B></FONT>&nbsp;<A HREF="${p}search/cust_pkg.cgi?magic=suspended;pkgpart=$hashref->{pkgpart}">suspended</A><BR>!;
+
+    $canceled_sth->execute( $part_pkg->pkgpart ) or die $canceled_sth->errstr;
+    my $num_canceled = $canceled_sth->fetchrow_arrayref->[0];
+    print '<FONT COLOR="#FF0000"><B>'. $num_canceled.
+          qq!</B></FONT>&nbsp;<A HREF="${p}search/cust_pkg.cgi?magic=canceled;pkgpart=$hashref->{pkgpart}">canceled</A>!;
+
+
+    print '</TD>';
+  }
+  print <<END;
         <TD ROWSPAN=$rowspan>$hashref->{freq}</TD>
         <TD ROWSPAN=$rowspan>$hashref->{plan}</TD>
         <TD ROWSPAN=$rowspan>$plandata</TD>
@@ -85,7 +145,13 @@ END
     my($part_svc) = qsearchs('part_svc',{'svcpart'=> $svcpart });
     print $n,qq!<TD><A HREF="${p}edit/part_svc.cgi?$svcpart">!,
           $part_svc->getfield('svc'),"</A></TD><TD>",
-          $pkg_svc->getfield('quantity'),"</TD></TR>\n";
+          $pkg_svc->getfield('quantity'),"</TD>";
+    if ( dbdef->table('pkg_svc')->column('primary_svc') ) {
+      print '<TD>';
+      print 'PRIMARY' if $pkg_svc->primary_svc =~ /^Y/i;
+      print '</TD>';
+    }
+    print "</TR>\n";
     $n="<TR>";
   }
 
@@ -99,4 +165,9 @@ print <<END;
   </BODY>
 </HTML>
 END
+
+sub pkgpart_sort {
+  $a->pkgpart <=> $b->pkgpart;
+}
+
 %>
index 084c21b..3f59abc 100755 (executable)
@@ -8,31 +8,57 @@ Where a customer heard about your service. Tracked for informational purposes.
 <A HREF="<%= $p %>edit/part_referral.cgi"><I>Add a new advertising source</I></A>
 <BR><BR>
 
+<%
+  my $today = timelocal(0, 0, 0, (localtime(time))[3..5] );
+  my %past;
+  tie %past, 'Tie::IxHash',
+    'Today'         =>        0,
+    'Past week'     =>   518400, # 60sec * 60min * 24hrs * 6days
+    'Past 30 days'  =>  2505600, # 60sec * 60min * 24hrs * 29days 
+    'Past 60 days'  =>  5097600, # 60sec * 60min * 24hrs * 29days 
+    'Past 90 days'  =>  7689600, # 60sec * 60min * 24hrs * 29days 
+    'Past 6 months' => 15724800, # 60sec * 60min * 24hrs * 182days 
+    'Past year'     => 31486000, # 60sec * 60min * 24hrs * 364days 
+    'Total'         => $today,
+  ;
+
+  my $sth = dbh->prepare("SELECT COUNT(*) FROM h_cust_main
+                            WHERE history_action = 'insert'
+                              AND refnum = ?
+                              AND history_date > ?         ")
+    or die dbh->errstr;
+%>
+
 <%= table() %>
 <TR>
-  <TH COLSPAN=2>Advertising source</TH>
+  <TH COLSPAN=2 ROWSPAN=2>Advertising source</TH>
+  <TH COLSPAN=<%= scalar(keys %past) %>>Customers</TH>
+</TR>
+<% for my $period ( keys %past ) { %>
+  <TH><FONT SIZE=-1><%= $period %></FONT></TH>
+<% } %>
 </TR>
 
 <%
 foreach my $part_referral ( sort { 
   $a->getfield('refnum') <=> $b->getfield('refnum')
 } qsearch('part_referral',{}) ) {
-  my($hashref)=$part_referral->hashref;
-  print <<END;
+%>
       <TR>
-        <TD><A HREF="${p}edit/part_referral.cgi?$hashref->{refnum}">
-          $hashref->{refnum}</A></TD>
-        <TD><A HREF="${p}edit/part_referral.cgi?$hashref->{refnum}">
-          $hashref->{referral}</A></TD>
+        <TD><A HREF="<%= $p %>edit/part_referral.cgi?<%= $part_referral->refnum %>">
+          <%= $part_referral->refnum %></A></TD>
+        <TD><A HREF="<%= $p %>edit/part_referral.cgi?<%= $part_referral->refnum %>">
+          <%= $part_referral->referral %></A></TD>
+        <% for my $period ( values %past ) {
+          $sth->execute($part_referral->refnum, $today-$period)
+            or die $sth->errstr;
+          my $number = $sth->fetchrow_arrayref->[0];
+        %>
+          <TD ALIGN="right"><%= $number %></TD>
+        <% } %>
       </TR>
-END
-
-}
+<% } %>
 
-print <<END;
     </TABLE>
   </BODY>
 </HTML>
-END
-
-%>
index 9fb359d..ef0de13 100755 (executable)
@@ -13,6 +13,20 @@ my @part_svc =
     qsearch('part_svc', \%search );
 my $total = scalar(@part_svc);
 
+my %num_active_cust_svc = ();
+if ( $cgi->param('active') ) {
+  my $active_sth = dbh->prepare(
+    'SELECT COUNT(*) FROM cust_svc WHERE svcpart = ?'
+  ) or die dbh->errstr;
+  foreach my $part_svc ( @part_svc ) {
+    $active_sth->execute($part_svc->svcpart) or die $active_sth->errstr;
+    $num_active_cust_svc{$part_svc->svcpart} =
+      $active_sth->fetchrow_arrayref->[0];
+  }
+  @part_svc = sort { $num_active_cust_svc{$b->svcpart} <=>
+                     $num_active_cust_svc{$a->svcpart}     } @part_svc;
+}
+
 %>
 <%= header('Service Definition Listing', menubar( 'Main Menu' => $p) ) %>
 
@@ -23,16 +37,18 @@ function part_export_areyousure(href) {
 }
 </SCRIPT>
 
-    Services are items you offer to your customers.<BR><BR>
+    Service definitions are the templates for items you offer to your customers.<BR><BR>
 
-<FORM METHOD="POST" ACTION="<%= $p %>edit/part_svc.cgi"><A HREF="<%= $p %>edit/part_svc.cgi"><I>Add a new service definition</I></A>&nbsp;or&nbsp;<SELECT NAME="clone"><OPTION></OPTION>
+<FORM METHOD="POST" ACTION="<%= $p %>edit/part_svc.cgi">
+<A HREF="<%= $p %>edit/part_svc.cgi"><I>Add a new service definition</I></A><% if ( @part_svc ) { %>&nbsp;or&nbsp;<SELECT NAME="clone"><OPTION></OPTION>
 <% foreach my $part_svc ( @part_svc ) { %>
   <OPTION VALUE="<%= $part_svc->svcpart %>"><%= $part_svc->svc %></OPTION>
 <% } %>
 </SELECT><INPUT TYPE="submit" VALUE="Clone existing service">
+<% } %>
 </FORM><BR>
 
-<%= $total %> services
+<%= $total %> service definitions
 <%= $cgi->param('showdisabled')
       ? do { $cgi->param('showdisabled', 0);
              '( <a href="'. $cgi->self_url. '">hide disabled services</a> )'; }
@@ -43,6 +59,9 @@ function part_export_areyousure(href) {
   <TR>
     <TH COLSPAN=<%= $cgi->param('showdisabled') ? 2 : 3 %>>Service</TH>
     <TH>Table</TH>
+<% if ( $cgi->param('active') ) { %>
+    <TH><FONT SIZE=-1>Customer<BR>Services</FONT></TH>
+<% } %>
     <TH>Export</TH>
     <TH>Field</TH>
     <TH COLSPAN=2>Modifier</TH>
@@ -51,12 +70,13 @@ function part_export_areyousure(href) {
 <% foreach my $part_svc ( @part_svc ) {
      my $hashref = $part_svc->hashref;
      my $svcdb = $hashref->{svcdb};
-     my @dfields = fields($svcdb);
+     my $svc_x = "FS::$svcdb"->new( { svcpart => $part_svc->svcpart } );
+     my @dfields = $svc_x->fields;
      push @dfields, 'usergroup' if $svcdb eq 'svc_acct'; #kludge
      my @fields =
-       grep { $_ ne 'svcnum' && $part_svc->part_svc_column($_)->columnflag }
-            @dfields;
-
+       grep { $svc_x->pvf($_)
+           or $_ ne 'svcnum' && $part_svc->part_svc_column($_)->columnflag }
+            @dfields ;
      my $rowspan = scalar(@fields) || 1;
      my $url = "${p}edit/part_svc.cgi?$hashref->{svcpart}";
 %>
@@ -72,6 +92,11 @@ function part_export_areyousure(href) {
       <%= $hashref->{svc} %></A></TD>
     <TD ROWSPAN=<%= $rowspan %>>
       <%= $hashref->{svcdb} %></TD>
+<% if ( $cgi->param('active') ) { %>
+    <TD ROWSPAN=<%= $rowspan %>>
+      <FONT COLOR="#00CC00"><B><%= $num_active_cust_svc{$hashref->{svcpart}} %></B></FONT>&nbsp;<A HREF="<%=$p%>search/<%= $hashref->{svcdb} %>.cgi?svcpart=<%= $hashref->{svcpart} %>">active</A>
+    </TD>
+<% } %>
     <TD ROWSPAN=<%= $rowspan %>><%= itable() %>
 <%
 #  my @part_export =
@@ -82,7 +107,7 @@ map { qsearchs('part_export', { exportnum => $_->exportnum } ) } qsearch('export
   ) {
 %>
       <TR>
-        <TD><A HREF="<%= $p %>edit/part_export.cgi?<%= $part_export->exportnum %>"><%= $part_export->exporttype %>&nbsp;to&nbsp;<%= $part_export->machine %></A></TD></TR>
+        <TD><A HREF="<%= $p %>edit/part_export.cgi?<%= $part_export->exportnum %>"><%= $part_export->exportnum %>:&nbsp;<%= $part_export->exporttype %>&nbsp;to&nbsp;<%= $part_export->machine %></A></TD></TR>
 <%  } %>
       </TABLE></TD>
 
@@ -94,6 +119,7 @@ map { qsearchs('part_export', { exportnum => $_->exportnum } ) } qsearch('export
 
 <%     if ( $flag eq "D" ) { print "Default"; }
          elsif ( $flag eq "F" ) { print "Fixed"; }
+         elsif ( not $flag ) { }
          else { print "(Unknown!)"; }
 %>
        </TD><TD><%= $part_svc->part_svc_column($field)->columnvalue%></TD>
diff --git a/httemplate/browse/part_virtual_field.cgi b/httemplate/browse/part_virtual_field.cgi
new file mode 100644 (file)
index 0000000..9bb5c13
--- /dev/null
@@ -0,0 +1,39 @@
+<%= header('Virtual field definitions', menubar('Main Menu'   => $p)) %>
+<%
+
+my %pvfs;
+my $block;
+my $p2 = popurl(2);
+my $dbtable;
+
+foreach (qsearch('part_virtual_field', {})) {
+  push @{ $pvfs{$_->dbtable} }, $_;
+}
+%>
+
+<% if ($cgi->param('error')) { %>
+   <FONT SIZE="+1" COLOR="#ff0000">Error: <%=$cgi->param('error')%></FONT>
+   <BR><BR>
+<% } %>
+
+<A HREF="<%=$p2%>edit/part_virtual_field.cgi"><I>Add a new field</I></A><BR><BR>
+
+<% foreach $dbtable (sort { $a cmp $b } keys (%pvfs)) { %>
+<H3><%=$dbtable%></H3>
+
+<%=table()%>
+<TH><TD>Field name</TD><TD>Description</TD></TH>
+<% foreach $pvf (sort {$a->name cmp $b->name} @{ $pvfs{$dbtable} }) { %>
+  <TR>
+    <TD></TD>
+    <TD>
+      <A HREF="<%=$p2%>edit/part_virtual_field.cgi?<%=$pvf->vfieldpart%>">
+        <%=$pvf->name%></A></TD>
+    <TD><%=$pvf->label%></TD>
+  </TR>
+<%   } %>
+</TABLE>
+<% } %>
+</BODY>
+</HTML>
+
diff --git a/httemplate/browse/router.cgi b/httemplate/browse/router.cgi
new file mode 100644 (file)
index 0000000..feee4ec
--- /dev/null
@@ -0,0 +1,38 @@
+<%= header('Routers', menubar('Main Menu'   => $p)) %>
+<%
+
+my @router = qsearch('router', {});
+my $p2 = popurl(2);
+
+%>
+
+<% if ($cgi->param('error')) { %>
+   <FONT SIZE="+1" COLOR="#ff0000">Error: <%=$cgi->param('error')%></FONT>
+   <BR><BR>
+<% } %>
+
+<A HREF="<%=$p2%>edit/router.cgi"><I>Add a new router</I></A><BR><BR>
+
+<%=table()%>
+  <TR>
+    <TD><B>Router name</B></TD>
+    <TD><B>Address block(s)</B></TD>
+  </TR>
+<% foreach my $router (sort {$a->routernum <=> $b->routernum} @router) {
+     my @addr_block = $router->addr_block;
+%>
+  <TR>
+    <TD ROWSPAN="<%=scalar(@addr_block)%>">
+      <A HREF="<%=$p2%>edit/router.cgi?<%=$router->routernum%>"><%=$router->routername%></A>
+    </TD>
+    <TD>
+    <% foreach my $block ( @addr_block ) { %>
+      <%=$block->NetAddr%></BR>
+    <% } %>
+    </TD>
+  </TR>
+<% } %>
+</TABLE>
+</BODY>
+</HTML>
+
index e890f07..44cda81 100755 (executable)
@@ -1,9 +1,10 @@
 <!-- mason kludge -->
 <%
-
-print header('Access Number Listing', menubar(
-  'Main Menu' => $p,
-)) %>
+  my $accounts_sth = dbh->prepare("SELECT COUNT(*) FROM svc_acct
+                                     WHERE popnum = ?           ")
+    or die dbh->errstr;
+%>
+<%= header('Access Number Listing', menubar( 'Main Menu' => $p )) %>
 Points of Presence<BR><BR>
 <A HREF="<%= $p %>edit/svc_acct_pop.cgi"><I>Add new Access Number</I></A><BR><BR>
 <%= table() %>
@@ -14,6 +15,7 @@ Points of Presence<BR><BR>
         <TH>Area code</TH>
         <TH>Exchange</TH>
         <TH>Local</TH>
+        <TH>Accounts</TH>
       </TR>
 
 <%
@@ -22,32 +24,40 @@ foreach my $svc_acct_pop ( sort {
   $a->state cmp $b->state || $a->city cmp $b->city
     || $a->ac <=> $b->ac || $a->exch <=> $b->exch || $a->loc <=> $b->loc
 } qsearch('svc_acct_pop',{}) ) {
-  my($hashref)=$svc_acct_pop->hashref;
-  print <<END;
+
+  my $svc_acct_pop_link = $p . 'edit/svc_acct_pop.cgi?'. $svc_acct_pop->popnum;
+
+  $accounts_sth->execute($svc_acct_pop->popnum) or die $accounts_sth->errstr;
+  my $num_accounts = $accounts_sth->fetchrow_arrayref->[0];
+
+  my $svc_acct_link = $p. 'search/svc_acct.cgi?popnum='. $svc_acct_pop->popnum;
+
+%>
       <TR>
-        <TD><A HREF="${p}edit/svc_acct_pop.cgi?$hashref->{popnum}">
-          $hashref->{popnum}</A></TD>
-        <TD><A HREF="${p}edit/svc_acct_pop.cgi?$hashref->{popnum}">
-          $hashref->{city}</A></TD>
-        <TD><A HREF="${p}edit/svc_acct_pop.cgi?$hashref->{popnum}">
-          $hashref->{state}</A></TD>
-        <TD><A HREF="${p}edit/svc_acct_pop.cgi?$hashref->{popnum}">
-          $hashref->{ac}</A></TD>
-        <TD><A HREF="${p}edit/svc_acct_pop.cgi?$hashref->{popnum}">
-          $hashref->{exch}</A></TD>
-        <TD><A HREF="${p}edit/svc_acct_pop.cgi?$hashref->{popnum}">
-          $hashref->{loc}</A></TD>
+        <TD><A HREF="<%= $svc_acct_pop_link %>">
+          <%= $svc_acct_pop->popnum %></A></TD>
+        <TD><A HREF="<%= $svc_acct_pop_link %>">
+          <%= $svc_acct_pop->city %></A></TD>
+        <TD><A HREF="<%= $svc_acct_pop_link %>">
+          <%= $svc_acct_pop->state %></A></TD>
+        <TD><A HREF="<%= $svc_acct_pop_link %>">
+          <%= $svc_acct_pop->ac %></A></TD>
+        <TD><A HREF="<%= $svc_acct_pop_link %>">
+          <%= $svc_acct_pop->exch %></A></TD>
+        <TD><A HREF="<%= $svc_acct_pop_link %>">
+          <%= $svc_acct_pop->loc %></A></TD>
+        <TD>
+          <FONT COLOR="#00CC00"><B><%= $num_accounts %></B></FONT>
+            <% if ( $num_accounts ) { %><A HREF="<%= $svc_acct_link %>"><% } %>
+            active
+            <% if ( $num_accounts ) { %></A><% } %>
+        </TD>
       </TR>
-END
+<% } %>
 
-}
-
-print <<END;
       <TR>
       </TR>
     </TABLE>
   </BODY>
 </HTML>
-END
 
-%>
index bafe5a8..9a00067 100644 (file)
@@ -5,13 +5,13 @@
 <% my $conf = new FS::Conf; my @config_items = $conf->config_items; %>
 
 <% foreach my $section ( qw(required billing username password UI session
-                            shell mail apache BIND
+                            shell BIND
                            ),
                          '', 'deprecated') { %>
   <A NAME="<%= $section || 'unclassified' %>"></A>
   <FONT SIZE="-2">
   <% foreach my $nav_section ( qw(required billing username password UI session
-                                  shell mail apache BIND
+                                  shell BIND
                                  ),
                                '', 'deprecated') { %>
     <% if ( $section eq $nav_section ) { %>
index fd9a829..409869e 100644 (file)
@@ -25,13 +25,13 @@ function SafeOnsubmit() {
 <form name="OneTrueForm" action="config-process.cgi" METHOD="POST" onSubmit="SafeOnsubmit()">
 
 <% foreach my $section ( qw(required billing username password UI session
-                            shell mail apache BIND
+                            shell BIND
                            ),
                          '', 'deprecated') { %>
   <A NAME="<%= $section || 'unclassified' %>"></A>
   <FONT SIZE="-2">
   <% foreach my $nav_section ( qw(required billing username password UI session
-                                  shell mail apache BIND
+                                  shell BIND
                                  ),
                                '', 'deprecated') { %>
     <% if ( $section eq $nav_section ) { %>
index c78a87f..1d6f8c4 100644 (file)
@@ -11,7 +11,7 @@
     <li>Credit card decline alerts: Customize the <a href="../config/config.cgi#declinetemplate">declinetemplate</a> configuration option and set the <a href="../config/config.cgi#emaildecline">emaildecline</a> configuration option.
     <li>Optional: Invoice template customization
       <ul>
-        <li>See the <a href="http://search.cpan.org/doc/MJD/Text-Template-1.42/Template.pm">Text::Template</a> documentation for details on the substitution language.
+        <li>See the <a href="http://search.cpan.org/~mjd/Text-Template/lib/Text/Template.pm">Text::Template</a> documentation for details on the substitution language.
         <li>You <b>must</b> call the invoice_lines() function at least once - pass it a number of lines, and it returns a list of array references, each of two elements: a service description column, and a price column.  Alternatively, call invoice_lines() with no arguments, and pagination will be disabled - all invoice line items will print on one page, with no padding (recommended for email invoices).
         <li>In addition, the following variables are available:
           <ul>
diff --git a/httemplate/docs/cvv2.html b/httemplate/docs/cvv2.html
new file mode 100644 (file)
index 0000000..fe8a17f
--- /dev/null
@@ -0,0 +1,25 @@
+<HTML>
+  <HEAD>
+    <TITLE>
+      CVV2 information
+    </TITLE>
+  </HEAD>
+  <BODY BGCOLOR="#e8e8e8">
+  The CVV2 number (also called CVC2 or CID) is a three- or four-digit
+  security code used to reduce credit card fraud.<BR><BR>
+  <TABLE BORDER=0 CELLSPACING=4>
+    <TR>
+      <TH>Visa / MasterCard / Discover</TH>
+      <TH>American Express</TH>
+    </TR>
+    <TR>
+      <TD>
+        <IMG BORDER=0 ALT="Visa/MasterCard/Discover" SRC="../images/cvv2.png">
+      </TD>
+      <TD>
+        <IMG BORDER=0 ALT="American Express" SRC="../images/cvv2_amex.png">
+      </TD>
+  </TABLE>
+    <CENTER><A HREF="javascript:close()">(close window)</A></CENTER>
+  </BODY>
+</HTML>
diff --git a/httemplate/docs/ieak.html b/httemplate/docs/ieak.html
new file mode 100644 (file)
index 0000000..00c5342
--- /dev/null
@@ -0,0 +1,75 @@
+<pre>
+this is incomplete
+mostly it should be merged into signup.html and fs_signup/ieak.template
+
+- download and install the IEAK from
+  http://www.microsoft.com/windows/ieak/default.asp
+
+- Good examples may be found in 
+  C:\Program Files\IEAK\toolkit\isp\server\ICW\signup\perl\signup08.pl
+  C:\Program Files\IEAK\toolkit\isp\server\ICW\reconfig\perl\reconfig04.pl
+  C:\Program Files\IEAK6\toolkit\isp\servless\basic\sample.ins
+  C:\Program Files\IEAK6\toolkit\isp\servless\advanced\4567.ins
+  C:\Program Files\IEAK6\toolkit\isp\servless\advanced\4568.ins
+  C:\Program Files\IEAK6\toolkit\isp\servless\advanced\7890.ins
+  C:\Program Files\IEAK6\toolkit\isp\servless\advanced\7891.ins
+
+- Full documentation on all the settings available in .INS files is
+  avaialble under Program Files | Microsoft IEAK 6 | IEAK Help 
+                  | Reference | Internet Settings (.ins) Files
+
+- Freeside will make the following substitutions before sending the file
+  to the user:
+
+  { $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
+
+- Simple example follows:
+
+[Entry]
+Entry Name = IEAK Sample
+[Phone]
+Dial_As_Is = No
+Phone_Number = { $exch }{ $loc }
+Area_Code = { $ac }
+Country_Code = 1
+Country_Id = 1
+[Server]
+Type = PPP
+SW_Compress = Yes
+PW_Encrypt = Yes
+Negotiate_TCP/IP = Yes
+Disable_LCP = No
+[TCP/IP]
+Specity_IP_Address = No
+Specity_Server_Address = No
+IP_Header_Compress = Yes
+Gateway_On_Remote = Yes
+[User]
+Name = { $username }
+Passowrd = { $password }
+Display_Password = Yes
+[Internet_Mail]
+Email_Name = { $email_name }
+Email_Address = { $username }@example.com
+POP_Server = mail.example.com
+POP_Server_Port_Number = 110
+POP_Logon_Password = { $password }
+SMTP_Server = mail.example.com
+SMTP_Server_Port_Number = 25
+Install_Mail = 1
+[URL]
+Help_Page = http://www.ieaksample.net/helpdesk
+Home_Page = http://www.ieaksample.net
+Search_Page = http://www.ieaksample,net/search
+[Favorites]
+IEAK Sample \\ IEAK Sample Home Page.url = http://acme.ieaksample.net/
+[Branding]
+Window_Title = Internet Explorer from Acme Internet Services
+
+</pre>
index 00c863b..648cb98 100644 (file)
@@ -6,11 +6,11 @@
 <img src="overview.png">
 <ul>
   <li><a href="install.html">New Installation</a>
-  <li><a href="upgrade4.html">Upgrading from 1.2.x to 1.2.2</a>
-  <li><a href="upgrade5.html">Upgrading from 1.2.2 to 1.2.3</a>
-  <li><a href="upgrade6.html">Upgrading from 1.2.3 to 1.3.0</a>
   <li><a href="upgrade7.html">Upgrading from 1.3.0 to 1.3.1</a>
   <li><a href="upgrade8.html">Upgrading from 1.3.1 to 1.4.0</a>
+  <li><a href="upgrade9.html">Upgrading from 1.4.0 to 1.4.1</a>
+  <li><a href="upgrade-1.4.2.html">Upgrading from 1.4.1 to 1.4.2</a>
+  <li><a href="upgrade10.html">Upgrading from 1.4.1 (or 1.4.2?) to 1.5.0</a>
 <!--
   <li><a href="config.html">Configuration files</a>
 !-->
index 75f039d..ed306f2 100644 (file)
@@ -3,21 +3,22 @@
 </head>
 <body>
 <h1>Installation</h1>
+<i>Note: Install Freeside on a firewalled, private server, not a public (web, RADIUS, etc.) server.</i><br><br>
 Before installing, you need:
 <ul>
-  <li><a href="http://www.perl.com/">Perl</a>  Don't enable experimental features like threads or the PerlIO abstraction layer.
+  <li><a href="http://www.perl.com/">Perl</a>
   <li><a href="http://www.apache.org">Apache</a> (<a href="http://www.modssl.org/">mod_ssl</a> or <a href="http://www.apache-ssl.org">Apache-SSL</a> highly recommended)
   <li><a href="http://perl.apache.org/">mod_perl</a> (if compiling your own mod_perl, make sure you set the <a href="http://perl.apache.org/guide/install.html#EVERYTHING">EVERYTHING</a>=1 compile-time option)
   <li><a href="http://www.openssh.com/">SSH</a> (<a href="http://www.openssh.com//">OpenSSH</a> is recommended.  SSH Communications Security <a href="http://www.ssh.com/products/ssh/download.cfm">commercial SSH version 3</a> has been reported incompatible with Freeside.)
   <li><a href="http://rsync.samba.org/">rsync</a>
   <li>A <b>transactional</b> database engine <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">supported</a> by Perl's <a href="http://dbi.perl.org">DBI</a>.
     <ul>
-      <li><a href="http://www.postgresql.org/">PostgreSQL</a> (v7 or higher) is recommended.
-      <li>MySQL versions before 4.1 do not support standard SQL subqueries and are <b>NOT SUPPORTED</b>.  If you are a developer who wishes to contribute MySQL 3.x/4.0 support, see <a href="http://pouncequick.420.am/rt/Ticket/Display.html?id=438">ticket #438</a> in the bug-tracking system and ask on the -devel mailing list.
-<!--       <li>MySQL has been reported to work.
-         <b>MySQL's default <a href="http://www.mysql.com/doc/M/y/MyISAM.html">MyISAM</a> and <a href="http://www.mysql.com/doc/I/S/ISAM.html">ISAM</a> table types are not supported</b>.  If you want to use MySQL, you <b>must</b> use one of the new <a href="http://www.mysql.com/doc/T/a/Table_types.html">transaction-safe table types</a> such as <a href="http://www.mysql.com/doc/B/D/BDB.html">BDB</a> or <a href="http://www.mysql.com/doc/I/n/InnoDB.html">InnoDB</a>, and set it as the default table type using the <code>--default-table-type=BDB</code> or <code>--default-table-type=InnoDB</code> <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Command-line_options">mysqld command-line option</a> or by setting <code>default-table-type=BDB</code> or <code>default-table-type=InnoDB</code> in the <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Option_files">my.cnf option file</a>. -->
+      <li><a href="http://www.postgresql.org/">PostgreSQL</a> is recommended (v7or later).
+      <li><a href="http://www.mysql.com/">MySQL</a> <b>MINIMUM VERSION 4.1</b> is untested but may work.   Versions before 4.1 do not support standard SQL subqueries and are <b>NOT SUPPORTED</b>.  If you are a developer who wishes to contribute MySQL 3.x/4.0 support, see <a href="http://pouncequick.420.am/rt/Ticket/Display.html?id=438">ticket #438</a> in the bug-tracking system and ask on the -devel mailing list.
+<!--       <li>MySQL has been reported to work. -->
+         <b>MySQL's default <a href="http://www.mysql.com/doc/M/y/MyISAM.html">MyISAM</a> and <a href="http://www.mysql.com/doc/I/S/ISAM.html">ISAM</a> table types are not supported</b>.  If you want to use MySQL, you <b>must</b> use one of the new <a href="http://www.mysql.com/doc/T/a/Table_types.html">transaction-safe table types</a> such as <a href="http://www.mysql.com/doc/B/D/BDB.html">BDB</a> or <a href="http://www.mysql.com/doc/I/n/InnoDB.html">InnoDB</a>, and set it as the default table type using the <code>--default-table-type=BDB</code> or <code>--default-table-type=InnoDB</code> <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Command-line_options">mysqld command-line option</a> or by setting <code>default-table-type=BDB</code> or <code>default-table-type=InnoDB</code> in the <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Option_files">my.cnf option file</a>.
     </ul>
-  <li>Perl modules (<a href="http://theoryx5.uwinnipeg.ca/CPAN/perl/CPAN.html">CPAN</a> will query, download and build perl modules automatically)
+  <li>Perl modules (<a href="http://search.cpan.org/~andk/CPAN/lib/CPAN.pm">CPAN</a> will query, download and build perl modules automatically)
     <ul>
 <!--      <li><a href="http://search.cpan.org/search?dist=Array-PrintCols">Array-PrintCols</a>
       <li><a href="http://search.cpan.org/search?dist=Term-Query">Term-Query</a> (make test broken; install manually) -->
@@ -41,18 +42,20 @@ Before installing, you need:
       <li><a href="http://search.cpan.org/search?dist=String-Approx">String-Approx</a>
       <li><a href="http://search.cpan.org/search?dist=Text-Template">Text-Template</a>
       <li><a href="http://search.cpan.org/search?dist=DBI">DBI</a>
-      <li><a href="http://search.cpan.org/search?mode=module&query=DBD">DBD for your database engine</a> (<a href="http://search.cpan.org/search?dist=DBD-Pg">DBD::Pg</a> for PostgreSQL<!--, <a href="http://search.cpan.org/search?dist=DBD-mysql">DBD::mysql</a> for MySQL-->)
+      <li><a href="http://search.cpan.org/search?mode=module&query=DBD">DBD for your database engine</a> (<a href="http://search.cpan.org/search?dist=DBD-Pg">DBD::Pg</a> for PostgreSQL, <a href="http://search.cpan.org/search?dist=DBD-mysql">DBD::mysql</a> for MySQL)
       <li><a href="http://search.cpan.org/search?dist=DBIx-DataSource">DBIx-DataSource</a>
       <li><a href="http://search.cpan.org/search?dist=DBIx-DBSchema">DBIx-DBSchema</a>
       <li><a href="http://search.cpan.org/search?dist=Net-SSH">Net-SSH</a>
       <li><a href="http://search.cpan.org/search?dist=String-ShellQuote">String-ShellQuote</a>
       <li><a href="http://search.cpan.org/search?dist=Net-SCP">Net-SCP</a>
-      <li><a href="http://www.apache-asp.org/">Apache::ASP</a> or <a href="http://www.masonhq.com/">HTML::Mason</a> (use version 1.0x - Freeside is not yet compatible with version 1.1x)
+      <li><a href="http://www.apache-asp.org/">Apache::ASP</a> or <a href="http://www.masonhq.com/">HTML::Mason</a>
       <li><a href="http://search.cpan.org/search?dist=Tie-IxHash">Tie-IxHash</a>
       <li><a href="http://search.cpan.org/search?dist=Time-Duration">Time-Duration</a>
       <li><a href="http://search.cpan.org/search?dist=HTML-Widgets-SelectLayers">HTML-Widgets-SelectLayers</a>
       <li><a href="http://search.cpan.org/search?dist=Storable">Storable</a>
 <!-- MyAccounts, maybe only for dev     <li><a href="http://search.cpan.org/search?dist=Cache-Cache">Cache::Cache</a> -->
+      <li><a href="http://search.cpan.org/search?dist=NetAddr-IP">NetAddr-IP</a>
+      <li><a href="http://search.cpan.org/search?dist=Chart">Chart</a>
       <li><a href="http://search.cpan.org/search?dist=ApacheDBI">Apache::DBI</a> <i>(optional but recommended for better webinterface performance)</i>
     </ul>
 </ul>
@@ -63,24 +66,23 @@ Install the Freeside distribution:
     <ul>
       <li> with <a href="http://www.postgresql.org/users-lounge/docs/7.1/postgres/user-manag.html#DATABASE-USERS">PostgreSQL</a>:
         <pre>
-$ su postgres
+$ su postgres (pgsql on some distributions)
 $ createuser -P freeside
 Enter password for user "freeside": 
 Enter it again: 
 Shall the new user be allowed to create databases? (y/n) y
 Shall the new user be allowed to create more new users? (y/n) n
 CREATE USER</pre>
-<!--      <li> with <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#User_Account_Management">MySQL</a>:
+      <li> with <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#User_Account_Management">MySQL</a>:
         <pre>
 $ mysqladmin -u root password '<i>set_a_root_database_password</i>'
 $ mysql -u root -p
 mysql> GRANT SELECT,INSERT,UPDATE,DELETE,INDEX,ALTER,CREATE,DROP on freeside.* TO freeside@localhost IDENTIFIED BY '<i>set_a_freeside_database_password</i>';</pre>
--->
     </ul>
 <!--  <li>Unpack the tarball: <pre>gunzip -c fs-x.y.z.tar.gz | tar xvf -</pre>-->
   <li>Edit the top-level Makefile:
     <ul>
-      <li>Set <tt>DATASOURCE</tt> to your <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI data source</a>, for example, <tt>DBI:Pg:host=localhost;dbname=freeside</tt> for PostgresSQL<!-- or <tt>DBI:mysql:freeside</tt> for MySQL-->.  See the <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI manpage</a> and the <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">manpage for your DBD</a> for the exact syntax of your DBI data source.
+      <li>Set <tt>DATASOURCE</tt> to your <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI data source</a>, for example, <tt>DBI:Pg:dbname=freeside</tt> for PostgresSQL or <tt>DBI:mysql:freeside</tt> for MySQL.  See the <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI manpage</a> and the <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">manpage for your DBD</a> for the exact syntax of your DBI data source.
       <li>Set <tt>DB_PASSWORD</tt> to the freeside database user's password.
     </ul>
   <li>Add the freeside database to your database engine:
@@ -91,10 +93,9 @@ $ su
     <pre>
 $ su freeside
 $ createdb freeside</pre>
-<!--    (with MySQL:)
+    (with MySQL:)
     <pre>
 $ mysqladmin -u freeside -p create freeside </pre>
--->
   <li>Build and install the Perl modules:
     <pre>
 $ make perl-modules
@@ -113,7 +114,10 @@ $ su
   <tr>
     <td><ul>
       <li>Run <tt>make aspdocs</tt>
-      <li>Copy <tt>aspdocs/</tt> to your web server's document space.
+      <li>Copy <tt>aspdocs/</tt> to your web server's document space:
+<font size="-1"><pre>
+cp&nbsp;aspdocs&nbsp;/usr/local/apache/htdocs/freeside-asp
+</pre></font>
       <li>Create a <a href="http://www.apache-asp.org/config.html#Global">Global</a> directory, such as <tt>/usr/local/etc/freeside/asp-global/</tt>:
 <font size="-1"><pre>
 mkdir&nbsp;/usr/local/etc/freeside/asp-global/
@@ -125,34 +129,41 @@ cp&nbsp;htetc/global.asa&nbsp;/usr/local/etc/freeside/asp-global/global.asa
 </pre></font>
       <li>Configure Apache for the Global directory and to execute .cgi files using Apache::ASP.  For example:
 <font size="-1"><pre>
+PerlModule Apache::ASP
 &lt;Directory&nbsp;/usr/local/apache/htdocs/freeside-asp&gt;
-&lt;Files ~ (\.cgi)&gt;
-AddHandler perl-script .cgi
+&lt;Files ~ (\.cgi|\.html)&gt;
+SetHandler perl-script
 PerlHandler Apache::ASP
 &lt;/Files&gt;
 &lt;Perl&gt;
 $MLDBM::RemoveTaint = 1;
 &lt;/Perl&gt;
 PerlSetVar&nbsp;Global&nbsp;/usr/local/etc/freeside/asp-global/
-PerlSetVar Debug 2
+PerlSetVar&nbsp;Debug&nbsp;2
+PerlSetVar&nbsp;RequestBinaryRead&nbsp;Off
 &lt;/Directory&gt;
 </pre></font>
     </ul></td>
     <td><ul>
-      <li>(use version 1.0x - Freeside is not yet compatible with version 1.1x)
       <li>Run <tt>make masondocs</tt>
-      <li>Copy <tt>masondocs/</tt> to your web server's document space.
-      <li>Copy <tt>htetc/handler.pl</tt> to your web server's configuration directory.
-      <li>Edit <tt>handler.pl</tt> and set an appropriate <tt>data_dir</tt>, such as <tt>/usr/local/etc/freeside/mason-data</tt>
+      <li>Copy <tt>masondocs/</tt> to your web server's document space. (For example: <tt>/usr/local/apache/htdocs/freeside-mason</tt>)
+      <li>Copy <tt>htetc/handler.pl</tt> to <tt>/usr/local/etc/freeside</tt>
+      <li>Edit <tt>handler.pl</tt> and:
+      <ul>
+        <li> set an appropriate <tt>comp_root</tt>, such as <tt>/usr/local/apache/htdocs/freeside-mason</tt>
+        <li> set an appropriate <tt>data_dir</tt>, such as <tt>/usr/local/etc/freeside/masondata</tt>
+      </ul>
+
       <li>Configure Apache to use the <tt>handler.pl</tt> file and to execute .cgi files using HTML::Mason.  For example:
 <font size="-1"><pre>
+PerlModule HTML::Mason
 &lt;Directory&nbsp;/usr/local/apache/htdocs/freeside-mason&gt;
-&lt;Files ~ (\.cgi)&gt;
-AddHandler perl-script .cgi
+&lt;Files ~ (\.cgi|.html)&gt;
+SetHandler perl-script
 PerlHandler HTML::Mason
 &lt;/Files&gt;
 &lt;Perl&gt;
-require&nbsp;"/usr/local/apache/conf/handler.pl";
+require&nbsp;"/usr/local/etc/freeside/handler.pl";
 &lt;/Perl&gt;
 &lt;/Directory&gt;
 </pre></font>
@@ -163,7 +174,6 @@ require&nbsp;"/usr/local/apache/conf/handler.pl";
 <li>Restrict access to this web interface - see the <a href="http://httpd.apache.org/docs/misc/FAQ.html#user-authentication">Apache documentation on user authentication</a>.    For example, to configure user authentication with <a href="http://httpd.apache.org/docs/mod/mod_auth.html">mod_auth</a> (flat files):
 <pre>
 &lt;Directory /usr/local/apache/htdocs/freeside-asp&gt;
-PerlSetVar Global /usr/local/etc/freeside/asp-global/
 AuthName Freeside
 AuthType Basic
 AuthUserFile /usr/local/etc/freeside/htpasswd
@@ -180,16 +190,16 @@ $ <a href="man/bin/freeside-adduser.html">freeside-adduser</a> -c -h /usr/local/
 $ <a href="man/bin/freeside-adduser.html">freeside-adduser</a> -h /usr/local/etc/freeside/htpasswd <i>username</i></pre></font>
     </ul>
   <i>(using other auth types, add each user to your <a href="http://httpd.apache.org/docs/misc/FAQ.html#user-authentication">Apache authentication</a> and then run: <tt>freeside-adduser <b>username</b></tt></i>
-  <li>As the freeside UNIX user, run <tt>bin/fs-setup <b>username</b></tt> (in the untar'ed freeside directory) to create the database tables, passing the username of a Freeside user you created above:
+  <li>As the freeside UNIX user, run <tt>freeside-setup <b>username</b></tt> to create the database tables, passing the username of a Freeside user you created above:
 <pre>
 $ su freeside
-$ cd <b>/path/to/freeside-1.4.0/</b>
-$ bin/fs-setup <b>username</b>
+$ freeside-setup <b>username</b>
 </pre>
+  Alternately, use the -s option to enable shipping addresses: <tt>freeside-setup -s <b>username</b></tt>
   <li>As the freeside UNIX user, run <tt>bin/populate-msgcat <b>username</b></tt> (in the untar'ed freeside directory) to populate the message catalog, passing the username of a Freeside user you created above:
 <pre>
 $ su freeside
-$ cd <b>/path/to/freeside-1.4.0/</b>
+$ cd <b>/path/to/freeside/</b>
 $ bin/populate-msgcat <b>username</b>
 </pre>
   <li><tt>freeside-queued</tt> was installed with the Perl modules.  Start it now and ensure that is run upon system startup (Do this manually, or edit the top-level Makefile, replacing INIT_FILE with the appropriate location on your systemand QUEUED_USER with the username of a Freeside user you created above, and run <tt>make install-init</tt>)
index 2db9edb..94efe53 100755 (executable)
@@ -3,7 +3,7 @@
 </head>
 <body>
   <h1>Importing legacy data</h1>
-<font size="+2">In most cases, legacy data import all cases will require writing custom code to deal with your particular legacy data.  The example scripts here will not work "out-of-the-box".  Importing your legacy data will most probably involve some hacking on the example scripts noted below.  Contributions to the import process are welcome.</font>
+<font size="+2">In almost all cases, legacy data import will require writing custom code to deal with your particular legacy data.  The example scripts here will probably <b>not</b> work "out-of-the-box", and are provided <b>as a starting point only</b>.</font>
 <br><br><i>Some import scripts may require installation of the <a href="http://search.cpan.org/search?dist=Array-PrintCols">Array-PrintCols</a> and <a href="http://search.cpan.org/search?dist=Term-Query">Term-Query</a> (make test broken; install manually) modules.</i><br>
 <ul>
   <li><a name="bind">bin/bind.import</a> - Import domain information from BIND named
       <li>POP mail accounts have entries in passwd only, and have a particular shell.
       <li>Everything else in passwd is a shell account.
     </ul>
-  <li><a name="svc_acct_sm">bin/svc_acct_sm.import</a> - Import qmail ( `virtualdomains' and `rcpthosts' ), or sendmail ( `virtusertable' and `sendmail.cw' ) files.  Before running bin/svc_acct_sm.import, you need <a href="../browse/part_svc.cgi">services</a> as follows:
+<!--  <li><a name="svc_acct_sm">bin/svc_acct_sm.import</a> - Import qmail ( `virtualdomains' and `rcpthosts' ), or sendmail ( `virtusertable' and `sendmail.cw' ) files.  Before running bin/svc_acct_sm.import, you need <a href="../browse/part_svc.cgi">services</a> as follows:
     <ul>
       <li>Domain (table svc_acct)
       <li>Mail alias (table svc_acct_sm)
     </ul>
+-->
   <li><a name="cust_main">Importing customer data</a>
     <ul>
       <li>Manually
diff --git a/httemplate/docs/man/FS/part_export/.cvs_is_on_crack b/httemplate/docs/man/FS/part_export/.cvs_is_on_crack
new file mode 100644 (file)
index 0000000..e69de29
index 092d2f8..7465615 100644 (file)
Binary files a/httemplate/docs/schema.dia and b/httemplate/docs/schema.dia differ
index 2b8b3a1..b380317 100644 (file)
@@ -12,6 +12,9 @@
         <li>typenum - <a href="#agent_type">agent type</a>
         <li>prog - (unimplemented)
         <li>freq - (unimplemented)
+        <li>disabled - Disabled flag, empty or 'Y'
+        <li>username - Username for the Agent interface
+        <li>_password - Password for the Agent interface
       </ul>
     <li><a name="agent_type" href="man/FS/agent_type.html">agent_type</a> - Agent types define groups of packages that you can then assign to particular agents.
       <ul>
@@ -39,7 +42,7 @@
     <li><a name="part_bill_event" href="man/FS/part_bill_event.html">part_bill_event</a> - Invoice event definitions
       <ul>
         <li>eventpart - primary key
-        <li>payby - CARD, BILL, or COMP
+        <li>payby - CARD, DCRD, CHEK, DCHK, LECB, BILL, or COMP
         <li>event - event name
         <li>eventcode - event action
         <li>seconds - how long after the invoice date (<a href="#cust_bill">cust_bill</a>._date) events of this type are triggered
         <li>recur - recurring fee
         <li>sdate - starting date
         <li>edate - ending date
+        <li>itemdesc - Line item description (currently used only when pkgnum is 0)
+      </ul>
+    <li><a name="cust_bill_pkg_detail" href="man/FS/cust_bill_pkg_detail.html">cust_bill_pkg_detail</a> - Invoice line items detail
+      <ul>
+        <li>detailnum - primary key
+        <li>pkgnum -
+        <li>invnum - 
+        <li>detail - Detail description
       </ul>
     <li><a name="cust_credit" href="man/FS/cust_credit.html">cust_credit</a> - Credits.  The equivalent of a negative <a href="#cust_bill">cust_bill</a> record.
       <ul>
         <li><i>ship_daytime</i>
         <li><i>ship_night</i>
         <li><i>ship_fax</i>
-        <li>payby - CARD, BILL, or COMP
+        <li>payby - CARD, DCHK, CHEK, DCHK, LECB, BILL, or COMP
         <li>payinfo - card number, P.O.#, or comp issuer
+        <li>paycvv - Card Verification Value, "CVV2" (also known as CVC2 or CID), the 3 or 4 digit number on the back (or front, for American Express) of the credit card
         <li>paydate - expiration date
         <li>payname - billing name (name on card)
         <li>tax - tax exempt, Y or null
         <li>tax - % rate
         <li>taxclass
         <li>exempt_amount
+        <li>taxname - if defined, printed on invoices instead of "Tax"
+        <li>setuptax - if 'Y', this tax does not apply to setup fees
+        <li>recurtax - if 'Y', this tax does not apply to recurring fees
       </ul>
     <li><a name="cust_tax_exempt" href="man/FS/cust_tax_exempt.html">cust_tax_exempt</a> - Tax exemption record
       <ul>
         <li>custnum - <a href="#cust_main">customer</a>
         <li>paid - amount
         <li>_date
-        <li>payby - CARD, BILL, or COMP
+        <li>payby - CARD, CHEK, LECB, BILL, or COMP
         <li>payinfo - card number, P.O.#, or comp issuer
         <li>paybatch - text field for tracking card processor batches
         <li>closed - books closed flag, empty or `Y'
         <li>pkgpart - <a href="#part_pkg">Package definition</a>
         <li>setup - date
         <li>bill - next bill date
+        <li>last_bill - last bill date
         <li>susp - (past) suspension date
         <li>expire - (future) cancellation date
         <li>cancel - (past) cancellation date
         <li>custnum - <a href="#cust_main">customer</a>
         <li>refund - amount
         <li>_date
-        <li>payby - CARD, BILL or COMP
+        <li>payby - CARD, CHEK, LECB, BILL or COMP
         <li>payinfo - card number, P.O.#, or comp issuer
         <li>otaker - order taker
         <li>closed - books closed flag, empty or `Y'
       <ul>
         <li>svcpart - primary key
         <li>svc - name of this service
-        <li>svcdb - table used for this service: svc_acct, svc_acct_sm, svc_forward, svc_domain, svc_charge or svc_wo
+        <li>svcdb - table used for this service: svc_acct, svc_forward, svc_domain, svc_charge or svc_wo
         <li>disabled - Disabled flag, empty or `Y'
 <!--        <li><i>table</i>__<i>field</i> - Default or fixed value for <i>field</i> in <i>table</i>
         <li><i>table</i>__<i>field</i>_flag - null, D or F
         <li>pkgpart - <a href="#part_pkg">Package definition</a>
         <li>svcpart - <a href="#part_svc">Service definition</a>
         <li>quantity - quantity of this service that this package includes
+        <li>primary_svc - blank or Y: primary service
       </ul>
     <li><a name="export_svc" href="man/FS/export_svc.html">export_svc</a>
       <ul>
         <li>npa - area code
         <li>nxx - exchange
       </ul>
-    <li><a name="svc_acct_sm" href="man/FS/svc_acct_sm.html">svc_acct_sm</a> - <b>DEPRECIATED</b> Domain mail aliases
-      <ul>
-        <li>svcnum - <a href="#cust_svc">primary key</a>
-        <li>domsvc - <a href="#svc_domain">Domain</a> (by svcnum)
-        <li>domuid - <a href="#svc_acct">Account</a> (by uid)
-        <li>domuser - domuser @ <a href="#svc_domain">Domain</a> forwards to <a href="#svc_acct">Account</a>
-      </ul>
     <li><a name="svc_domain" href="man/FS/svc_domain.html">svc_domain</a> - Domains
       <ul>
         <li>svcnum - <a href="#cust_svc">primary key</a>
       <ul>
         <li>svcnum - <a href="#cust_svc">primary key</a>
         <li>srcsvc - <a href="#svc_acct">svcnum of the source of this forward</a>
+        <li>src - literal source (username or full email address)
         <li>dstsvc - <a href="#svc_acct">svcnum of the destination of this forward</a>
-        <li>dst - foreign destination (email address) - forward not local to freeside
+        <li>dst - literal destination (username or full email address)
       </ul>
     <li><a name="domain_record" href="man/FS/domain_record.html">domain_record</a> - Domain zone detail
       <ul>
index 7dac5fd..72e1642 100644 (file)
@@ -38,9 +38,14 @@ freeside-logout username ( portnum | ip | nasnum nasport )</pre>
       <li><i>username</i> is a customer username from the svc_acct table
       <li><i>portnum</i>, <i>ip</i> or <i>nasport</i> and <i>nasnum</i> uniquely identify a port in the <a href="schema.html#port">port</a> database table.
     </ul>
-  <li>RADIUS
+  <li>RADIUS - One of:
     <ul>
+      <li>Run the <b>freeside-sqlradius-radacctd</b> daemon to import radacct
+        records from all configured sqlradius exports:
+          <tt>freeside-sqlradius-radacctd username</tt>
       <li>Configure your RADIUS server's login and logout callbacks to use the command-line <tt>freeside-login</tt> and <tt>freeside-logout</tt> utilites.
+      <li> <i>(incomplete)</i>Use the <b>fs_radlog/fs_radlogd</b> tool to
+        import records from a text radacct file.
     </ul>
 </ul>
 <h2>Callbacks</h2>
index 5168f47..97d7aa7 100644 (file)
@@ -12,7 +12,7 @@ webserver.  On this machine, install:
   <li><a href="http://search.cpan.org/search?dist=Text-Template">Text::Template</a>
   <li><a href="http://search.cpan.org/search?dist=Storable">Storable</a>
   <li><a href="http://search.cpan.org/search?dist=Business-CreditCard">Business-CreditCard</a>
-  <li><a href="http://www.sisd.com/useragent">HTTP::Headers::UserAgent</a> (version 2.0 or higher; not yet indexed correctly on CPAN)
+  <li><a href="http://search.cpan.org/search?dist=HTTP-BrowserDetect">HTTP::BrowserDetect</a>
 
   <li><a href="man/FS/SignupClient.html">FS::SignupClient</a> (copy the fs_signup/FS-SignupClient directory to the external machine, then: perl Makefile.PL; make; make install)
 </ul>
@@ -36,9 +36,7 @@ Then:
 Optional:
 <ul>
   <li>If you create a <b>/usr/local/freeside/ieak.template</b> file on the external machine, it will be sent to IE users with MIME type <i>application/x-Internet-signup</i>.  This file will be processed with <a href="http://search.cpan.org/doc/MJD/Text-Template-1.23/Template.pm">Text::Template</a> with the variables listed below available.
-  (an example file is included as <b>fs_signup/ieak.template</b>)  See the <a href="http://www.microsoft.com/windows/ieak/techinfo/deploy/60/en/toc.asp">IEAK documentation</a> for more information.
-  <li>If you create a <b>/usr/local/freeside/cck.template</b> file on the external machine, the variables defined will be sent to Netscape users with MIME type <i>application/x-netscape-autoconfigure-dialer-v2</i>.  This file will be processed with <a href="http://search.cpan.org/doc/MJD/Text-Template-1.23/Template.pm">Text::Template</a> with the variables listed below available.
-  (an example file is included as <b>fs_signup/cck.template</b>).  See the <a href="http://help.netscape.com/products/client/mc/acctproc4.html">Netscape documentation</a> for more information.
+  (an example file is included as <b>fs_signup/ieak.template</b>)  See the section on <a href="http://www.microsoft.com/windows/ieak/techinfo/deploy/60/en/INS.HTM">internet settings files</a> in the <a href="http://www.microsoft.com/windows/ieak/techinfo/deploy/60/en/toc.asp">IEAK documentation</a> for more information.
   <li>If you create a <b>/usr/local/freeside/success.html</b> 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 <b>fs_signup/FS-SignupClient/cgi/success.html</b>
   <li>Variable substitutions available in <b>ieak.template</b>, <b>cck.template</b> and <b>success.html</b>:
     <ul>
index 5503a24..d2c501e 100755 (executable)
@@ -6,9 +6,10 @@
   <br><a name=ssh>Unattended remote login</a> - Freeside can login to remote machines unattended using SSH.  This can pose a security risk if not configured correctly, and will allow an intruder who breaks into your freeside machine full access to your remote machines.  <b>Do not use this feature unless you understand what you are doing!</b>
     <ul>
       <li>As the freeside user (on your freeside machine), generate an authentication key using <a href="http://www.tac.eu.org/cgi-bin/man-cgi?ssh-keygen+1">ssh-keygen</a>.  Since this is for unattended operation, use a blank passphrase.
-      <li>Append the newly-created <code>identity.pub</code> file to <code>~root/.ssh/authorized_keys</code> on the remote machine(s).
-      <li>Some new SSH v2 implementation accept v2 style keys only.  Use the <code>-t</code> option to <a href="http://www.tac.eu.org/cgi-bin/man-cgi?ssh-keygen+1">ssh-keygen</a>, and append the created <code>id_dsa.pub</code> or <code>id_rsa.pub</code> to <code>~root/.ssh/authorized_keys2</code> on the remote machine(s).
+      <li>Append the newly-created <code>identity.pub</code> file to <code>~root/.ssh/authorized_keys</code> (or the appopriate <code>~username/.ssh/authorized_keys</code>) on the remote machine(s).
+      <li>Some new SSH v2 implementation accept v2 style keys only.  Use the <code>-t</code> option to <a href="http://www.tac.eu.org/cgi-bin/man-cgi?ssh-keygen+1">ssh-keygen</a>, and append the created <code>id_dsa.pub</code> or <code>id_rsa.pub</code> to <code>~root/.ssh/authorized_keys2</code> (or the appopriate <code>~username/.ssh/authorized_keys</code>) on the remote machine(s).
       <li>You may need to set <code>PermitRootLogin without-password</code> (meaning with keys only) in your <code>sshd_config</code> file on the remote machine(s).
+      <li>You may want to set <code>ForwardX11 = no</code> in <code>~root/.ssh/config</code> to prevent spurious errors if your distribution turns on X11 forwarding by default.
     </ul>
 
 </body>
diff --git a/httemplate/docs/upgrade-1.4.2.html b/httemplate/docs/upgrade-1.4.2.html
new file mode 100644 (file)
index 0000000..1feaa80
--- /dev/null
@@ -0,0 +1,20 @@
+<head>
+  <title>Upgrading to 1.4.2</title>
+</head>
+<body>
+<h1>Upgrading to 1.4.2 from 1.4.1</h1>
+<ul>
+  <li>If migrating from less than 1.4.1, see these <a href="upgrade9.html">instructions</a> first.
+  <li>Back  up your data and current Freeside installation.
+  <li>Install <a href="http://search.cpan.org/search?dist=Locale-SubCountry">Locale::SubCountry</a>
+  <li>Install <a href="http://search.cpan.org/search?dist=IPC-ShareLite">IPC::ShareLite</a>
+  <li>Install <a href="http://search.cpan.org/search?dist=HTML-Widgets-SelectLayers">HTML::Widgets::SelectLayers</a> 0.03.
+  <li>CGI.pm minimum version 2.47 is required.  You will probably need to install a current CGI.pm from CPAN if you are using Perl 5.005 or earlier.
+  <li>If using Apache::ASP, add <code>PerlSetVar RequestBinaryRead Off</code> to your Apache configuration and make sure you are using Apache::ASP minimum version 2.55.
+  <li>Run <code>make aspdocs</code> or <code>make masondocs</code>.
+  <li>Copy <code>aspdocs/</code> or <code>masondocs/</code> to your web server's document space.
+  <li>Run <code>make install-perl-modules</code>.
+  <li>The signup server and password server are deprecated in 1.4.2.  Their functionality has been incorperated into the self-service server.  Edit or reinstall your init script, and set the "signup_server-default_agentnum" and "signup_server-default_refnum" configuration options.  The FS::SignupClient interface is still available as a compatibility wrapper, so you should be able to continue to use your current signup.cgi.
+  <li>Optional: To use typeset invoices, install tetex and ghostscript, and copy conf/invoice_latex, conf/invoice_latexnotes, and conf/invoice_latexfooter to /usr/local/etc/freeside/conf.<datasrc>/
+  <li>Restart Apache and freeside-queued.
+</body>
diff --git a/httemplate/docs/upgrade10.html b/httemplate/docs/upgrade10.html
new file mode 100644 (file)
index 0000000..774babb
--- /dev/null
@@ -0,0 +1,204 @@
+<pre>
+this is incomplete
+
+install DBIx::DBSchema 0.22
+
+install NetAddr::IP, Chart::Base, IPC::ShareLite and Locale::SubCountry
+
+CREATE TABLE cust_bill_pkg_detail (
+  detailnum serial,
+  pkgnum int NOT NULL,
+  invnum int NOT NULL,
+  detail varchar(80),
+  PRIMARY KEY (detailnum)
+);
+CREATE INDEX cust_bill_pkg_detail1 ON cust_bill_pkg_detail ( pkgnum, invnum );
+
+CREATE TABLE part_virtual_field (
+  vfieldpart int NOT NULL,
+  dbtable varchar(32) NOT NULL,
+  name varchar(32) NOT NULL,
+  check_block text,
+  list_source text,
+  length integer,
+  label varchar(80),
+  PRIMARY KEY (vfieldpart)
+);
+
+CREATE TABLE virtual_field (
+  recnum integer NOT NULL,
+  vfieldpart integer NOT NULL,
+  value varchar(128) NOT NULL,
+  PRIMARY KEY (vfieldpart, recnum)
+);
+
+CREATE TABLE router (
+  routernum serial,
+  routername varchar(80),
+  svcnum int,
+  PRIMARY KEY (routernum)
+);
+
+CREATE TABLE part_svc_router (
+  svcpart int NOT NULL,
+  routernum int NOT NULL
+);
+
+CREATE TABLE addr_block (
+  blocknum serial,
+  routernum int NOT NULL,
+  ip_gateway varchar(15) NOT NULL,
+  ip_netmask int NOT NULL,
+  PRIMARY KEY (blocknum)
+);
+CREATE UNIQUE INDEX addr_block1 ON addr_block ( blocknum, routernum );
+
+CREATE TABLE svc_broadband (
+  svcnum int NOT NULL,
+  blocknum int NOT NULL,
+  speed_up int NOT NULL,
+  speed_down int NOT NULL,
+  ip_addr varchar(15),
+  PRIMARY KEY (svcnum)
+);
+
+CREATE TABLE acct_snarf (
+  snarfnum serial,
+  svcnum int NOT NULL,
+  machine varchar(255) NULL,
+  protocol varchar(80) NULL,
+  username varchar(80) NULL,
+  _password varchar(80) NULL,
+  PRIMARY KEY (snarfnum)
+);
+CREATE INDEX acct_snarf1 ON acct_snarf ( svcnum );
+
+CREATE TABLE svc_external (
+  svcnum int NOT NULL,
+  id int NOT NULL,
+  title varchar(80),
+  PRIMARY KEY (svcnum)
+);
+
+CREATE TABLE part_pkg_temp (
+    pkgpart serial NOT NULL,
+    pkg varchar(80) NOT NULL,
+    "comment" varchar(80) NOT NULL,
+    setup text NULL,
+    freq varchar(80) NOT NULL,
+    recur text NULL,
+    setuptax char(1) NULL,
+    recurtax char(1) NULL,
+    plan varchar(80) NULL,
+    plandata text NULL,
+    disabled char(1) NULL,
+    taxclass varchar(80) NULL,
+    PRIMARY KEY (pkgpart),
+);
+INSERT INTO part_pkg_temp SELECT * from part_pkg;
+DROP TABLE part_pkg;
+ALTER TABLE part_pkg_temp RENAME TO part_pkg;
+ALTER TABLE part_pkg DROP CONSTRAINT part_pkg_temp_pkey;
+ALTER TABLE part_pkg ADD PRIMARY KEY (pkgpart);
+CREATE INDEX part_pkg1 ON part_pkg(disabled);
+select setval('public.part_pkg_temp_pkgpart_seq', ( select max(pkgpart) from part_pkg) ); #?
+
+CREATE TABLE h_part_pkg_temp (
+    historynum serial NOT NULL,
+    history_date int,
+    history_user varchar(80) NOT NULL,
+    history_action varchar(80) NOT NULL,
+    pkgpart int NOT NULL,
+    pkg varchar(80) NOT NULL,
+    "comment" varchar(80) NOT NULL,
+    setup text NULL,
+    freq varchar(80) NOT NULL,
+    recur text NULL,
+    setuptax char(1) NULL,
+    recurtax char(1) NULL,
+    plan varchar(80) NULL,
+    plandata text NULL,
+    disabled char(1) NULL,
+    taxclass varchar(80) NULL,
+    PRIMARY KEY (historynum)
+);
+INSERT INTO h_part_pkg_temp SELECT * from h_part_pkg;
+DROP TABLE h_part_pkg;
+ALTER TABLE h_part_pkg_temp RENAME TO h_part_pkg;
+ALTER TABLE h_part_pkg DROP CONSTRAINT h_part_pkg_temp_pkey;
+ALTER TABLE h_part_pkg ADD PRIMARY KEY (historynum);
+CREATE INDEX h_part_pkg1 ON h_part_pkg(disabled);
+select setval('public.h_part_pkg_temp_historynum_seq', ( select max(historynum) from h_part_pkg) );
+
+
+DROP INDEX cust_bill_pkg1;
+
+ALTER TABLE cust_bill_pkg ADD itemdesc varchar(80) NULL;
+ALTER TABLE h_cust_bill_pkg ADD itemdesc varchar(80) NULL;
+ALTER TABLE cust_main_county ADD taxname varchar(80) NULL;
+ALTER TABLE h_cust_main_county ADD taxname varchar(80) NULL;
+ALTER TABLE cust_main_county ADD setuptax char(1) NULL;
+ALTER TABLE h_cust_main_county ADD setuptax char(1) NULL;
+ALTER TABLE cust_main_county ADD recurtax char(1) NULL;
+ALTER TABLE h_cust_main_county ADD recurtax char(1) NULL;
+ALTER TABLE cust_pkg ADD last_bill int NULL;
+ALTER TABLE h_cust_pkg ADD last_bill int NULL;
+ALTER TABLE agent ADD disabled char(1) NULL;
+ALTER TABLE h_agent ADD disabled char(1) NULL;
+ALTER TABLE agent ADD username varchar(80) NULL;
+ALTER TABLE h_agent ADD username varchar(80) NULL;
+ALTER TABLE agent ADD _password varchar(80) NULL;
+ALTER TABLE h_agent ADD _password varchar(80) NULL;
+ALTER TABLE cust_main ADD paycvv varchar(4) NULL;
+ALTER TABLE h_cust_main ADD paycvv varchar(4) NULL;
+ALTER TABLE part_referral ADD disabled char(1) NULL;
+ALTER TABLE h_part_referral ADD disabled char(1) NULL;
+CREATE INDEX part_referral1 ON part_referral ( disabled );
+ALTER TABLE pkg_svc ADD primary_svc char(1) NULL;
+ALTER TABLE h_pkg_svc ADD primary_svc char(1) NULL;
+ALTER TABLE svc_forward ADD src varchar(255) NULL;
+ALTER TABLE h_svc_forward ADD src varchar(255) NULL;
+
+On recent Pg versions:
+
+ALTER TABLE svc_forward ALTER COLUMN srcsvc DROP NOT NULL;
+ALTER TABLE h_svc_forward ALTER COLUMN srcsvc DROP NOT NULL;
+ALTER TABLE svc_forward ALTER COLUMN dstsvc DROP NOT NULL;
+ALTER TABLE h_svc_forward ALTER COLUMN dstsvc DROP NOT NULL;
+
+Or on Pg versions that don't support DROP NOT NULL (tested only on 7.2 so far):
+UPDATE pg_attribute SET attnotnull = FALSE WHERE ( attname = 'srcsvc' OR attname = 'dstsvc' ) AND ( attrelid = ( SELECT oid FROM pg_class WHERE relname = 'svc_forward' ) OR attrelid = ( SELECT oid FROM pg_class WHERE relname = 'h_svc_forward' ) );
+
+dump database, edit:
+- cust_main: increase otaker from 8 to 32
+- cust_main: change ss from char(11) to varchar(11)
+- cust_credit: increase otaker from 8 to 32
+- cust_pkg: increase otaker from 8 to 32
+- cust_refund: increase otaker from 8 to 32
+- domain_record: increase reczone from 80 to 255
+- domain_record: change rectype from char to varchar
+- domain_record: increase recdata from 80 to 255
+then reload
+
+optionally:
+
+  CREATE INDEX cust_main6 ON cust_main ( daytime );
+  CREATE INDEX cust_main7 ON cust_main ( night );
+  CREATE INDEX cust_main8 ON cust_main ( fax );
+  CREATE INDEX cust_main9 ON cust_main ( ship_daytime );
+  CREATE INDEX cust_main10 ON cust_main ( ship_night );
+  CREATE INDEX cust_main11 ON cust_main ( ship_fax );
+  CREATE INDEX agent2 ON agent ( disabled );
+  CREATE INDEX part_bill_event2 ON part_bill_event ( disabled );
+
+  serial columns
+
+mandatory again:
+
+dbdef-create username
+create-history-tables username cust_bill_pkg_detail router part_svc_router addr_block svc_broadband acct_snarf svc_external
+dbdef-create username
+
+apache - fix <Files> sections to include .html also
+
+</pre>
diff --git a/httemplate/docs/upgrade4.html b/httemplate/docs/upgrade4.html
deleted file mode 100644 (file)
index 1d70f8b..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<head>
-  <title>Upgrading to 1.2.2</title>
-</head>
-<body>
-<h1>Upgrading to 1.2.2 from 1.2.x</h1>
-<ul>
-  <li>If migrating from 1.0.0, see these <a href="upgrade.html">instructions</a> first.
-  <li>If migrating from less than 1.1.4, see these <a href="upgrade2.html">instructions</a> first.
-  <li>If migrating from less than 1.2.0, see these <a href="upgrade3.html">instructions</a> first.
-  <li>Back up your data and current Freeside installation.
-  <li>Install the Perl modules <a href="http://www.perl.com/CPAN/modules/by-module/Locale/">Locale-Codes</a> and <a href="http://www.perl.com/CPAN/modules/by-module/Net/">Net-Whois</a>.
-  <li>Apply the following changes to your database:
-<pre>
-ALTER TABLE cust_pay_batch CHANGE exp exp VARCHAR(11);
-</pre>
-  <li>Copy or symlink htdocs to the new copy.
-  <li>Remove the symlink or directory <i>(your_site_perl_directory)</i>/FS.
-  <li>Change to the FS directory in the new tarball, and build and install the
-      Perl modules:
-    <pre>
-$ cd FS/
-$ perl Makefile.PL
-$ make
-$ su
-# make install</pre>
-  <li>Run bin/dbdef-create.  This file uses MySQL-specific syntax.  If you are running a different database engine you will need to modify it slightly.
-</body>
diff --git a/httemplate/docs/upgrade5.html b/httemplate/docs/upgrade5.html
deleted file mode 100644 (file)
index 3f34316..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<head>
-  <title>Upgrading to 1.3.0</title>
-</head>
-<body>
-<h1>Upgrading to 1.2.3 from 1.2.2</h1>
-<ul>
-  <li>If migrating from 1.0.0, see these <a href="upgrade.html">instructions</a> first.
-  <li>If migrating from less than 1.1.4, see these <a href="upgrade2.html">instructions</a> first.
-  <li>If migrating from less than 1.2.0, see these <a href="upgrade3.html">instructions</a> first.
-  <li>If migrating from less than 1.2.2, see these <a href="upgrade4.html">instructions</a> first.
-  <li>Back up your data and current Freeside installation.
-  <li>Apply the following changes to your database:
-<pre>
-ALTER TABLE svc_acct_pop ADD loc CHAR(4);
-CREATE TABLE prepay_credit (
-  prepaynum int NOT NULL,
-  identifier varchar(80) NOT NULL,
-  amount decimal(10,2) NOT NULL,
-  PRIMARY KEY (prepaynum),
-  INDEX (identifier)
-);
-</pre>
-  <li>Copy or symlink htdocs to the new copy.
-  <li>Remove the symlink or directory <i>(your_site_perl_directory)</i>/FS.
-  <li>Change to the FS directory in the new tarball, and build and install the
-      Perl modules:
-    <pre>
-$ cd FS/
-$ perl Makefile.PL
-$ make
-$ su
-# make install</pre>
-  <li>Run bin/dbdef-create.  This file uses MySQL-specific syntax.  If you are running a different database engine you will need to modify it slightly.
-</body>
diff --git a/httemplate/docs/upgrade6.html b/httemplate/docs/upgrade6.html
deleted file mode 100644 (file)
index dc82975..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<head>
-  <title>Upgrading to 1.3.0</title>
-</head>
-<body>
-<h1>Upgrading to 1.3.0 from 1.2.3</h1>
-<ul>
-  <li>If migrating from 1.0.0, see these <a href="upgrade.html">instructions</a> first.
-  <li>If migrating from less than 1.1.4, see these <a href="upgrade2.html">instructions</a> first.
-  <li>If migrating from less than 1.2.0, see these <a href="upgrade3.html">instructions</a> first.
-  <li>If migrating from less than 1.2.2, see these <a href="upgrade4.html">instructions</a> first.
-  <li>If migrating from less than 1.2.3, see these <a href="upgrade5.html">instructions</a> first.
-  <li>Back up your data and current Freeside installation.
-  <li>As 1.3.0 requires transactions, <b>MySQL's default <a href="http://www.mysql.com/doc/M/y/MyISAM.html">MyISAM</a> and <a href="http://www.mysql.com/doc/I/S/ISAM.html">ISAM</a> table types are no longer supported</b>.  Converting to <a href="http://www.postgresql.org/">PostgreSQL</a> is recommended.  If you really want to use MySQL, convert your tables to one of the <a href="http://www.mysql.com/doc/T/a/Table_types.html">transaction-safe table types</a> such as <a href="http://www.mysql.com/doc/B/D/BDB.html">BDB</a>.
-  <li>Copy the <i>invoice_template</i> file from the <i>conf/</i> directory in the distribution to your <a href="config.html">configuration directory</a>.
-  <li>Install the <a href="http://search.cpan.org/search?dist=Text-Template">Text-Template</a>, <a href="http://search.cpan.org/search?dist=DBIx-DBSchema">DBIx-DBSchema</a>, <a href="http://search.cpan.org/search?dist=Net-SSH">Net-SSH</a>, <a href="http://search.cpan.org/search?dist=String-ShellQuote">String-ShellQuote</a> and <a href="http://search.cpan.org/search?dist=Net-SCP">Net-SCP</a> Perl modules.
-  <li>Apply the following changes to your database:
-<pre>
-CREATE TABLE domain_record (
-  recnum int NOT NULL,
-  svcnum int NOT NULL,
-  reczone varchar(80) NOT NULL,
-  recaf char(2) NOT NULL,
-  rectype char(5) NOT NULL,
-  recdata varchar(80) NOT NULL,
-  PRIMARY KEY (recnum)
-);
-CREATE TABLE svc_www (
-  svcnum int NOT NULL,
-  recnum int NOT NULL,
-  usersvc int NOT NULL,
-  PRIMARY KEY (svcnum)
-);
-ALTER TABLE part_svc ADD svc_www__recnum varchar(80) NULL;
-ALTER TABLE part_svc ADD svc_www__recnum_flag char(1) NULL;
-ALTER TABLE part_svc ADD svc_www__usersvc varchar(80) NULL;
-ALTER TABLE part_svc ADD svc_www__uesrsvc_flag char(1) NULL;
-ALTER TABLE svc_acct CHANGE _password _password varchar(50) NULL;
-ALTER TABLE svc_acct ADD seconds integer NULL;
-ALTER TABLE part_svc ADD svc_acct__seconds integer NULL;
-ALTER TABLE part_svc ADD svc_acct__seconds_flag char(1) NULL;
-ALTER TABLE prepay_credit ADD seconds integer NULL;
-
-</pre>
-  <li>If your database supports dropping columns:
-<pre>
-ALTER TABLE cust_bill DROP owed;
-ALTER TABLE cust_credit DROP credited;
-</pre>
-     Or, if your database does not support dropping columns, you can do this:
-<pre>
-ALTER TABLE cust_bill CHANGE owed depriciated decimal(10,2);
-ALTER TABLE cust_credit CHANGE credited depriciated2 decimal(10,2);
-</pre>
-
-  <li>Copy or symlink htdocs to the new copy.
-  <li>Remove the symlink or directory <i>(your_site_perl_directory)</i>/FS.
-  <li>Change to the FS directory in the new tarball, and build and install the
-      Perl modules:
-    <pre>
-$ cd FS/
-$ perl Makefile.PL
-$ make
-$ su
-# make install</pre>
-  <li>Run bin/dbdef-create.
-</body>
index 0210430..cf60a85 100644 (file)
@@ -369,7 +369,7 @@ ALTER TABLE cust_refund DROP COLUMN crednum;
   <li><b>IMPORTANT: After running bin/create-history-tables</b>, run <tt>bin/dbdef-create <i>username</i></tt> again.
   <li>As the freeside UNIX user, run <tt>bin/populate-msgcat <i>username</i></tt
 > to populate the message catalog
-  <li>set the <a href="../config/config.cgi#username_policy">user_policy configuration value</a> as appropriate for your site.
+<!--  <li>set the <a href="../config/config.cgi#username_policy">user_policy configuration value</a> as appropriate for your site. -->
   <li>set the <a href="../config/config.cgi#locale">locale configuration value</a> to en_US.
   <li>the mxmachines, nsmachines, arecords and cnamerecords configuration values have been deprecated.  Set the <a href="../config/config.cgi#defaultrecords">defaultrecords configuration value</a> instead.
   <li>Create the `/usr/local/etc/freeside/cache.<i>datasrc</i>' directory
diff --git a/httemplate/docs/upgrade9.html b/httemplate/docs/upgrade9.html
new file mode 100644 (file)
index 0000000..6a8fd96
--- /dev/null
@@ -0,0 +1,28 @@
+<head>
+  <title>Upgrading to 1.4.1</title>
+</head>
+<body>
+<h1>Upgrading to 1.4.1 from 1.4.0</h1>
+<ul>
+  <li>If migrating from less than 1.4.0, see these <a href="upgrade8.html">instructions</a> first.
+  <li>Back up your data and current Freeside installation.
+  <li>Run <code>make aspdocs</code> or <code>make masondocs</code>.
+  <li>Copy <code>aspdocs/</code> or <code>masondocs/</code> to your web server's document space.
+  <li>Run <code>make install-perl-modules</code>.
+  <li>Install <a href="http://search.cpan.org/search?dist=Net-SSH">Net::SSH</a> minimum version 0.07
+  <li>Apply the following changes to your database:
+<pre>
+INSERT INTO msgcat ( msgnum, msgcode, locale, msg ) VALUES ( 18, 'daytime', 'en_US', 'Day Phone' );
+INSERT INTO msgcat ( msgnum, msgcode, locale, msg ) VALUES ( 19, 'night', 'en_US', 'Night Phone' );
+</pre>
+  <li>Optionally, apply the following changes to your database (performance improvements):
+<pre>
+CREATE INDEX part_pkg1 ON part_pkg ( disabled );
+CREATE INDEX part_svc1 ON part_svc ( disabled );
+CREATE INDEX cust_bill2 ON cust_bill ( _date );
+</pre>
+  <li>If you want to use ACH (electronic checks), you will need to make changes to your database.  The easiest way to make these changes is to dump your database (with pg_dump), change the payinfo field in the cust_pay, cust_refund, h_cust_pay and h_cust_refund tables from varchar(16) to varchar(80), reload the database from the dump.
+  <li>If you will be doing bind exports you should make additional changes to your database. Follow the directions above to dump the database and change the reczone and recdata fields in the domain_record and h_domain_record tables from varchar(80) to varchar(255).
+  <li>If you made changes to your db schema from a dump as listed above run dbdef-create.
+  <li>Restart Apache and freeside-queued.
+</body>
index 0d2f1c2..d9b7579 100755 (executable)
@@ -1,6 +1,6 @@
 <!-- mason kludge -->
 <%
-# <!-- $Id: REAL_cust_pkg.cgi,v 1.4 2002-07-08 13:07:40 ivan Exp $ -->
+# <!-- $Id: REAL_cust_pkg.cgi,v 1.7 2003-11-19 12:21:09 ivan Exp $ -->
 
 my $error ='';
 my $pkgnum = '';
@@ -30,6 +30,15 @@ print header('Package Edit'); #, menubar(
 #  'Main Menu' => popurl(2)
 #));
 
+%>
+
+    <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2">
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT>
+
+<%
+
 #print info
 my($susp,$cancel,$expire)=(
   $cust_pkg->getfield('susp'),
@@ -45,6 +54,9 @@ print '<FORM NAME="formname" ACTION="process/REAL_cust_pkg.cgi" METHOD="POST">',
 print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: $error</FONT>!
   if $error;
 
+#my $format = "%c %z (%Z)";
+my $format = "%m/%d/%Y %T %z (%Z)";
+
 print ntable("#cccccc",2),
       '<TR><TD ALIGN="right">Package number</TD><TD BGCOLOR="#ffffff">',
       $pkgnum, '</TD></TR>',
@@ -55,15 +67,29 @@ print ntable("#cccccc",2),
       '<TR><TD ALIGN="right">Order taker</TD><TD BGCOLOR="#ffffff">',
       $otaker,  '</TD></TR>',
       '<TR><TD ALIGN="right">Setup date</TD><TD>'.
-      '<INPUT TYPE="text" NAME="setup" SIZE=32 VALUE="',
-      ( $setup ? time2str("%c %z (%Z)",$setup) : "" ), '"></TD></TR>',
-      '<TR><TD ALIGN="right">Next bill date</TD><TD>',
-      '<INPUT TYPE="text" NAME="bill" SIZE=32 VALUE="',
-      ( $bill ? time2str("%c %z (%Z)",$bill) : "" ), '"></TD></TR>',
-;
+      '<INPUT TYPE="text" NAME="setup" SIZE=32 ID="setup_text" VALUE="',
+      ( $setup ? time2str($format, $setup) : "" ), '">'.
+      ' <IMG SRC="../images/calendar.png" ID="setup_button" STYLE="cursor: pointer" TITLE="Select date">'.
+      '</TD></TR>';
+
+print '<TR><TD ALIGN="right">Last bill date</TD><TD>',
+      '<INPUT TYPE="text" NAME="last_bill" SIZE=32 ID="last_bill_text" VALUE="',
+      ( $cust_pkg->last_bill
+        ? time2str($format, $cust_pkg->last_bill)
+        : ""                                          ),
+      '">'.
+      ' <IMG SRC="../images/calendar.png" ID="last_bill_button" STYLE="cursor: pointer" TITLE="Select date">'.
+      '</TD></TR>'
+  if $cust_pkg->dbdef_table->column('last_bill');
+
+print '<TR><TD ALIGN="right">Next bill date</TD><TD>',
+      '<INPUT TYPE="text" NAME="bill" SIZE=32 ID="bill_text" VALUE="',
+      ( $bill ? time2str($format, $bill) : "" ), '">'.
+      ' <IMG SRC="../images/calendar.png" ID="bill_button" STYLE="cursor: pointer" TITLE="Select date">'.
+      '</TD></TR>';
 
 print '<TR><TD ALIGN="right">Suspension date</TD><TD BGCOLOR="#ffffff">',
-       time2str("%D",$susp), '</TD></TR>'
+       time2str($format, $susp), '</TD></TR>'
   if $susp;
 
 #print '<TR><TD ALIGN="right">Expiration date</TD><TD BGCOLOR="#ffffff">',
@@ -71,18 +97,34 @@ print '<TR><TD ALIGN="right">Suspension date</TD><TD BGCOLOR="#ffffff">',
 #  if $expire;
 print '<TR><TD ALIGN="right">Expiration date'.
       '</TD><TD>',
-      '<INPUT TYPE="text" NAME="expire" SIZE=32 VALUE="',
-      ( $expire ? time2str("%c %z (%Z)",$expire) : "" ), '">'.
+      '<INPUT TYPE="text" NAME="expire" SIZE=32 ID="expire_text" VALUE="',
+      ( $expire ? time2str($format, $expire) : "" ), '">'.
+      ' <IMG SRC="../images/calendar.png" ID="expire_button" STYLE="cursor: pointer" TITLE="Select date">'.
       '<BR><FONT SIZE=-1>(will <b>cancel</b> this package'.
       ' when the date is reached)</FONT>'.
       '</TD></TR>';
 
 print '<TR><TD ALIGN="right">Cancellation date</TD><TD BGCOLOR="#ffffff">',
-       time2str("%D",$cancel), '</TD></TR>'
+       time2str($format, $cancel), '</TD></TR>'
   if $cancel;
 
 %>
 </TABLE>
+<SCRIPT TYPE="text/javascript">
+<%
+  my @cal = qw( setup bill expire );
+  push @cal, 'last_bill'
+    if $cust_pkg->dbdef_table->column('last_bill');
+  foreach my $cal (@cal) {
+%>
+  Calendar.setup({
+    inputField: "<%= $cal %>_text",
+    ifFormat:   "%m/%d/%Y",
+    button:     "<%= $cal %>_button",
+    align:      "BR"
+  });
+<% } %>
+</SCRIPT>
 <BR><INPUT TYPE="submit" VALUE="Apply Changes">
 </FORM>
 </BODY>
index 449456c..8a1cb2a 100755 (executable)
@@ -16,59 +16,64 @@ if ( $cgi->param('error') ) {
 my $action = $agent->agentnum ? 'Edit' : 'Add';
 my $hashref = $agent->hashref;
 
-print header("$action Agent", menubar(
+%>
+
+<%= header("$action Agent", menubar(
   'Main Menu' => $p,
   'View all agents' => $p. 'browse/agent.cgi',
-));
+)) %>
 
-print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'),
-      "</FONT>"
-  if $cgi->param('error');
+<% if ( $cgi->param('error') ) { %>
+<FONT SIZE="+1" COLOR="#ff0000">Error: <%= $cgi->param('error') %></FONT>
+<% } %>
 
-print '<FORM ACTION="', popurl(1), 'process/agent.cgi" METHOD=POST>',
-      qq!<INPUT TYPE="hidden" NAME="agentnum" VALUE="$hashref->{agentnum}">!,
-      "Agent #", $hashref->{agentnum} ? $hashref->{agentnum} : "(NEW)";
+<FORM ACTION="<%=popurl(1)%>process/agent.cgi" METHOD=POST>
+<INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $hashref->{agentnum} %>">
+Agent #<%= $hashref->{agentnum} ? $hashref->{agentnum} : "(NEW)" %>
 
-print &ntable("#cccccc", 2, ''), <<END;
+<%= &ntable("#cccccc", 2, '') %>
 <TR>
   <TH ALIGN="right">Agent</TH>
-  <TD><INPUT TYPE="text" NAME="agent" SIZE=32 VALUE="$hashref->{agent}"></TD>
+  <TD><INPUT TYPE="text" NAME="agent" SIZE=32 VALUE="<%= $hashref->{agent} %>"></TD>
 </TR>
 <TR>
   <TH ALIGN="right">Agent type</TH>
   <TD><SELECT NAME="typenum" SIZE=1>
-END
 
-foreach my $agent_type (qsearch('agent_type',{})) {
-  print "<OPTION VALUE=". $agent_type->typenum;
-  print " SELECTED"
-    if $hashref->{typenum} && ( $hashref->{typenum} == $agent_type->typenum );
-  print ">", $agent_type->getfield('typenum'), ": ",
-        $agent_type->getfield('atype'),"\n";
-}
+<% foreach my $agent_type (qsearch('agent_type',{})) { %>
+  <OPTION VALUE="<%= $agent_type->typenum %>"<%= ( $hashref->{typenum} && ( $hashref->{typenum} == $agent_type->typenum ) ) ? ' SELECTED' : '' %>>
+  <%= $agent_type->getfield('typenum') %>: <%= $agent_type->getfield('atype') %>
+<% } %>
 
-print <<END;
 </SELECT></TD>
 </TR>
+<% if ( dbdef->table('agent')->column('disabled') ) { %>
+  <TR>
+    <TD ALIGN="right">Disable</TD>
+    <TD><INPUT TYPE="checkbox" NAME="disabled" VALUE="Y"<%= $hashref->{disabled} eq 'Y' ? ' CHECKED' : '' %>></TD>
+  </TR>
+<% } %>
 <TR>
   <TD ALIGN="right"><!--Frequency--></TD>
-  <TD><INPUT TYPE="hidden" NAME="freq" VALUE="$hashref->{freq}"></TD>
+  <TD><INPUT TYPE="hidden" NAME="freq" VALUE="<%= $hashref->{freq} %>"></TD>
 </TR>
 <TR>
   <TD ALIGN="right"><!--Program--></TD>
-  <TD><INPUT TYPE="hidden" NAME="prog" VALUE="$hashref->{prog}"></TD>
+  <TD><INPUT TYPE="hidden" NAME="prog" VALUE="<%= $hashref->{prog} %>"></TD>
 </TR>
+<% if ( dbdef->table('agent')->column('username') ) { %>
+  <TR>
+    <TD ALIGN="right">Agent interface username</TD>
+    <TD><INPUT TYPE="text" NAME="username" VALUE="<%= $hashref->{username} %>"></TD>
+  </TR>
+  <TR>
+    <TD ALIGN="right">Agent interface password</TD>
+    <TD><INPUT TYPE="text" NAME="_password" VALUE="<%= $hashref->{_password} %>"></TD>
+  </TR>
+<% } %>
 </TABLE>
-END
 
-print qq!<BR><INPUT TYPE="submit" VALUE="!,
-      $hashref->{agentnum} ? "Apply changes" : "Add agent",
-      qq!">!;
-
-print <<END;
+<BR><INPUT TYPE="submit" VALUE="<%= $hashref->{agentnum} ? "Apply changes" : "Add agent" %>">
     </FORM>
   </BODY>
 </HTML>
-END
-
-%>
index cf8de2f..857e769 100755 (executable)
@@ -17,6 +17,7 @@ my $conf = new FS::Conf;
 
 my $error = '';
 my($custnum, $username, $password, $popnum, $cust_main, $saved_pkgpart);
+my(@invoicing_list);
 if ( $cgi->param('error') ) {
   $error = $cgi->param('error');
   $cust_main = new FS::cust_main ( {
@@ -32,15 +33,23 @@ if ( $cgi->param('error') ) {
   $username = $cgi->param('username');
   $password = $cgi->param('_password');
   $popnum = $cgi->param('popnum');
+  @invoicing_list = split( /\s*,\s*/, $cgi->param('invoicing_list') );
 } elsif ( $cgi->keywords ) { #editing
   my( $query ) = $cgi->keywords;
   $query =~ /^(\d+)$/;
   $custnum=$1;
   $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } );
+  if ( $cust_main->dbdef_table->column('paycvv')
+       && length($cust_main->paycvv)             ) {
+    my $paycvv = $cust_main->paycvv;
+    $paycvv =~ s/./*/g;
+    $cust_main->paycvv($paycvv);
+  }
   $saved_pkgpart = 0;
   $username = '';
   $password = '';
   $popnum = 0;
+  @invoicing_list = $cust_main->invoicing_list;
 } else {
   $custnum='';
   $cust_main = new FS::cust_main ( {} );
@@ -50,6 +59,7 @@ if ( $cgi->param('error') ) {
   $username = '';
   $password = '';
   $popnum = 0;
+  @invoicing_list = ();
 }
 $cgi->delete_all();
 my $action = $custnum ? 'Edit' : 'Add';
@@ -57,7 +67,7 @@ my $action = $custnum ? 'Edit' : 'Add';
 # top
 
 my $p1 = popurl(1);
-print header("Customer $action", '');
+print header("Customer $action", '', ' onUnload="myclose()"');
 print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $error, "</FONT>"
   if $error;
 
@@ -71,9 +81,11 @@ print qq!<FORM ACTION="${p1}process/cust_main.cgi" METHOD=POST NAME="form1">!,
 
 my $r = qq!<font color="#ff0000">*</font>&nbsp;!;
 
-my @agents = qsearch( 'agent', {} );
+my %agent_search = dbdef->table('agent')->column('disabled')
+                     ? ( 'disabled' => '' ) : ();
+my @agents = qsearch( 'agent', \%agent_search );
 #die "No agents created!" unless @agents;
-die "You have not created any agents.  You must create at least one agent before adding a customer.  Go to ". popurl(2). "browse/agent.cgi and create one or more agents." unless @agents;
+eidiot "You have not created any agents (or all agents are disabled).  You must create at least one agent before adding a customer.  Go to ". popurl(2). "browse/agent.cgi and create one or more agents." unless @agents;
 my $agentnum = $cust_main->agentnum || $agents[0]->agentnum; #default to first
 if ( scalar(@agents) == 1 ) {
   print qq!<INPUT TYPE="hidden" NAME="agentnum" VALUE="$agentnum">!;
@@ -99,7 +111,7 @@ if ( $custnum && ! $conf->exists('editreferrals') ) {
 } else {
   my(@referrals) = qsearch('part_referral',{});
   if ( scalar(@referrals) == 0 ) {
-    die "You have not created any advertising sources.  You must create at least one advertising source before adding a customer.  Go to ". popurl(2). "browse/part_referral.cgi and create one or more advertising sources.";
+    eidiot "You have not created any advertising sources.  You must create at least one advertising source before adding a customer.  Go to ". popurl(2). "browse/part_referral.cgi and create one or more advertising sources.";
   } elsif ( scalar(@referrals) == 1 ) {
     $refnum ||= $referrals[0]->refnum;
     print qq!<INPUT TYPE="hidden" NAME="refnum" VALUE="$refnum">!;
@@ -120,9 +132,11 @@ if ( $custnum && ! $conf->exists('editreferrals') ) {
 #referring customer
 
 #print qq!<BR><BR>Referring Customer: !;
-if ( $cust_main->referral_custnum ) {
-  my $referring_cust_main =
-    qsearchs('cust_main', { custnum => $cust_main->referral_custnum } );
+my $referring_cust_main = '';
+if ( $cust_main->referral_custnum
+     and $referring_cust_main =
+           qsearchs('cust_main', { custnum => $cust_main->referral_custnum } )
+) {
   print '<BR><BR>Referring Customer: <A HREF="'. popurl(1). '/cust_main.cgi?'.
         $cust_main->referral_custnum. '">'.
         $cust_main->referral_custnum. ': '.
@@ -177,8 +191,10 @@ END
 my $countrydefault = $conf->config('countrydefault') || 'US';
 $cust_main->country( $countrydefault ) unless $cust_main->country;
 
-$cust_main->state( $conf->config('statedefault') || 'CA' )
-  unless $cust_main->state || $cust_main->country ne 'US';
+my $statedefault = $conf->config('statedefault')
+                   || ($countrydefault eq 'US' ? 'CA' : '');
+$cust_main->state( $statedefault )
+  unless $cust_main->state || $cust_main->country ne $countrydefault;
 
 my($county_html, $state_html, $country_html) =
   FS::cust_main_county::regionselector( $cust_main->county,
@@ -195,10 +211,13 @@ my($daytime,$night,$fax)=(
   $cust_main->fax,
 );
 
+my $daytime_label = FS::Msgcat::_gettext('daytime') || 'Day Phone';
+my $night_label = FS::Msgcat::_gettext('night') || 'Night Phone';
+
 print <<END;
 <TR><TH ALIGN="right">${r}Country</TH><TD>$country_html</TD></TR>
-<TR><TD ALIGN="right">Day Phone</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="$daytime" SIZE=18></TD></TR>
-<TR><TD ALIGN="right">Night Phone</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="$night" SIZE=18></TD></TR>
+<TR><TD ALIGN="right">$daytime_label</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="$daytime" SIZE=18></TD></TR>
+<TR><TD ALIGN="right">$night_label</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="$night" SIZE=18></TD></TR>
 <TR><TD ALIGN="right">Fax</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="fax" VALUE="$fax" SIZE=12></TD></TR>
 END
 
@@ -231,7 +250,7 @@ END
 
   print '<BR>Service address ',
         '(<INPUT TYPE="checkbox" NAME="same" VALUE="Y" onClick="samechanged(this)"';
-  unless ( $cust_main->ship_last ) {
+  unless ( $cust_main->ship_last && $cgi->param('same') ne 'Y' ) {
     print ' CHECKED';
     foreach (
       qw( last first company address1 address2 city county state zip country
@@ -272,8 +291,9 @@ END
   #false laziness with regular state
   $cust_main->ship_country( $countrydefault ) unless $cust_main->ship_country;
 
-  $cust_main->ship_state( $conf->config('statedefault') || 'CA' )
-    unless $cust_main->ship_state || $cust_main->ship_country ne 'US';
+  $cust_main->ship_state( $statedefault )
+    unless $cust_main->ship_state
+           || $cust_main->ship_country ne $countrydefault;
 
   my($ship_county_html, $ship_state_html, $ship_country_html) =
     FS::cust_main_county::regionselector( $cust_main->ship_county,
@@ -294,8 +314,8 @@ END
 
   print <<END;
   <TR><TH ALIGN="right">${r}Country</TH><TD>$ship_country_html</TD></TR>
-  <TR><TD ALIGN="right">Day Phone</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="ship_daytime" VALUE="$ship_daytime" SIZE=18 onChange="changed(this)"></TD></TR>
-  <TR><TD ALIGN="right">Night Phone</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="ship_night" VALUE="$ship_night" SIZE=18 onChange="changed(this)"></TD></TR>
+  <TR><TD ALIGN="right">$daytime_label</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="ship_daytime" VALUE="$ship_daytime" SIZE=18 onChange="changed(this)"></TD></TR>
+  <TR><TD ALIGN="right">$night_label</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="ship_night" VALUE="$ship_night" SIZE=18 onChange="changed(this)"></TD></TR>
   <TR><TD ALIGN="right">Fax</TD><TD COLSPAN=5><INPUT TYPE="text" NAME="ship_fax" VALUE="$ship_fax" SIZE=12 onChange="changed(this)"></TD></TR>
 END
 
@@ -326,7 +346,9 @@ sub expselect {
     $return .= ">$_";
   }
   $return .= qq!</SELECT>/<SELECT NAME="$prefix!. qq!_year" SIZE="1">!;
-  for ( 2001 .. 2037 ) {
+  my @t = localtime;
+  my $thisYear = $t[5] + 1900;
+  for ( ($thisYear > $y && $y > 0 ? $y : $thisYear) .. 2037 ) {
     $return .= "<OPTION";
     $return .= " SELECTED" if $_ == $y;
     $return .= ">$_";
@@ -336,48 +358,129 @@ sub expselect {
   $return;
 }
 
-print "<BR>Billing information", &itable("#cccccc"),
-      qq!<TR><TD><INPUT TYPE="checkbox" NAME="tax" VALUE="Y"!;
-print qq! CHECKED! if $cust_main->tax eq "Y";
-print qq!>Tax Exempt</TD></TR>!;
-print qq!<TR><TD><INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST"!;
-my @invoicing_list = $cust_main->invoicing_list;
-print qq! CHECKED!
-  if ( ! @invoicing_list && ! $conf->exists('disablepostalinvoicedefault') )
-     || grep { $_ eq 'POST' } @invoicing_list;
-print qq!>Postal mail invoice</TD></TR>!;
-my $invoicing_list = join(', ', grep { $_ ne 'POST' } @invoicing_list );
-print qq!<TR><TD>Email invoice <INPUT TYPE="text" NAME="invoicing_list" VALUE="$invoicing_list"></TD></TR>!;
-
-print "<TR><TD>Billing type</TD></TR>",
-      "</TABLE>",
-      &table("#cccccc"), "<TR>";
-
-my($payinfo, $payname)=(
-  $cust_main->payinfo,
-  $cust_main->payname,
-);
+my $payby_default = $conf->config('payby-default');
+
+if ( $payby_default eq 'HIDE' ) {
+
+  $cust_main->payby('BILL') unless $cust_main->payby;
+
+  foreach my $field (qw( tax payby )) {
+    print qq!<INPUT TYPE="hidden" NAME="$field" VALUE="!.
+          $cust_main->getfield($field). '">';
+  }
+
+  print qq!<INPUT TYPE="hidden" NAME="invoicing_list" VALUE="!.
+        join(', ', $cust_main->invoicing_list). '">';
+
+  foreach my $payby (qw( CARD DCRD CHEK DCHK LECB BILL COMP )) {
+    foreach my $field (qw( payinfo payname )) {
+      print qq!<INPUT TYPE="hidden" NAME="${payby}_$field" VALUE="!.
+            $cust_main->getfield($field). '">';
+    }
+
+    #false laziness w/expselect
+    my( $m, $y );
+    my $date = $cust_main->paydate || '12-2037';
+    if ( $date  =~ /^(\d{4})-(\d{1,2})-\d{1,2}$/ ) { #PostgreSQL date format
+      ( $m, $y ) = ( $2, $1 );
+    } elsif ( $date =~ /^(\d{1,2})-(\d{1,2}-)?(\d{4}$)/ ) {
+      ( $m, $y ) = ( $1, $3 );
+    } else {
+      die "unrecognized expiration date format: $date";
+    }
+
+    print qq!<INPUT TYPE="hidden" NAME="${payby}_month" VALUE="$m">!.
+          qq!<INPUT TYPE="hidden" NAME="${payby}_year"  VALUE="$y">!;
+
+  }
 
-my %payby = (
-  'CARD' => qq!Credit card<BR>${r}<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR>${r}Exp !. expselect("CARD"). qq!<BR>${r}Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!,
-  'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE=""><BR>${r}Exp !. expselect("BILL", "12-2037"). qq!<BR>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="">!,
-  'COMP' => qq!Complimentary<BR>${r}Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR>${r}Exp !. expselect("COMP"),
+} else {
+
+  print "<BR>Billing information", &itable("#cccccc"),
+        qq!<TR><TD><INPUT TYPE="checkbox" NAME="tax" VALUE="Y"!;
+  print qq! CHECKED! if $cust_main->tax eq "Y";
+  print qq!>Tax Exempt</TD></TR><TR><TD>!.
+        qq!<INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST"!;
+
+  #my @invoicing_list = $cust_main->invoicing_list;
+  print qq! CHECKED!
+    if ( ! @invoicing_list && ! $conf->exists('disablepostalinvoicedefault') )
+       || grep { $_ eq 'POST' } @invoicing_list;
+  print qq!>Postal mail invoice</TD></TR>!;
+  my $invoicing_list = join(', ', grep { $_ ne 'POST' } @invoicing_list );
+  print qq!<TR><TD>Email invoice <INPUT TYPE="text" NAME="invoicing_list" VALUE="$invoicing_list"></TD></TR>!;
+
+  print "<TR><TD>Billing type</TD></TR>",
+        "</TABLE>", '<script language="JavaScript"><!--
+                       var mywindow = -1;
+                       function myopen(filename,windowname,properties) {
+                         myclose();
+                         mywindow = window.open(filename,windowname,properties);
+                       }
+                       function myclose() {
+                         if ( mywindow != -1 )
+                           mywindow.close();
+                         mywindow = -1;
+                       }
+
+                     //--></script>',
+        &table("#cccccc"), "<TR>";
+
+  my($payinfo, $payname)=(
+    $cust_main->payinfo,
+    $cust_main->payname,
+  );
+
+  my %payby = (
+    'CARD' => qq!Credit card (automatic)<BR>${r}<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR>${r}Exp !. expselect("CARD"). qq!<BR>${r}Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!,
+    'DCRD' => qq!Credit card (on-demand)<BR>${r}<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="" MAXLENGTH=19><BR>${r}Exp !. expselect("DCRD"). qq!<BR>${r}Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="">!,
+    'CHEK' => qq!Electronic check (automatic)<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE=""><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="">!,
+    'DCHK' => qq!Electronic check (on-demand)<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE=""><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="">!,
+    'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!,
+    'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE=""><BR><INPUT TYPE="hidden" NAME="BILL_month" VALUE="12"><INPUT TYPE="hidden" NAME="BILL_year" VALUE="2037">Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="">!,
+    'COMP' => qq!Complimentary<BR>${r}Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR>${r}Exp !. expselect("COMP"),
 );
-my %paybychecked = (
-  'CARD' => qq!Credit card<BR>${r}<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR>${r}Exp !. expselect("CARD", $cust_main->paydate). qq!<BR>${r}Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname">!,
-  'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE="$payinfo"><BR>${r}Exp !. expselect("BILL", $cust_main->paydate). qq!<BR>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="$payname">!,
-  'COMP' => qq!Complimentary<BR>${r}Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR>${r}Exp !. expselect("COMP", $cust_main->paydate),
+
+  if ( $cust_main->dbdef_table->column('paycvv') ) {
+    foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 bs
+      $payby{$payby} .= qq!<BR>CVV2&nbsp;(<A HREF="javascript:myopen('../docs/cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>)&nbsp;<INPUT TYPE="text" NAME=${payby}_paycvv VALUE="" SIZE=4 MAXLENGTH=4>!;
+    }
+  }
+
+  my( $account, $aba ) = split('@', $payinfo);
+
+  my %paybychecked = (
+    'CARD' => qq!Credit card (automatic)<BR>${r}<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR>${r}Exp !. expselect("CARD", $cust_main->paydate). qq!<BR>${r}Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname">!,
+    'DCRD' => qq!Credit card (on-demand)<BR>${r}<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR>${r}Exp !. expselect("DCRD", $cust_main->paydate). qq!<BR>${r}Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="$payname">!,
+    'CHEK' => qq!Electronic check (automatic)<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="$account"><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="$payname">!,
+    'DCHK' => qq!Electronic check (on-demand)<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="$account"><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="$payname">!,
+    'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="$payinfo" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!,
+    'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE="$payinfo"><BR><INPUT TYPE="hidden" NAME="BILL_month" VALUE="12"><INPUT TYPE="hidden" NAME="BILL_year" VALUE="2037">Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="$payname">!,
+    'COMP' => qq!Complimentary<BR>${r}Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR>${r}Exp !. expselect("COMP", $cust_main->paydate),
 );
-for (qw(CARD BILL COMP)) {
-  print qq!<TD VALIGN=TOP><INPUT TYPE="radio" NAME="payby" VALUE="$_"!;
-  if ($cust_main->payby eq "$_") {
-    print qq! CHECKED> $paybychecked{$_}</TD>!;
-  } else {
-    print qq!> $payby{$_}</TD>!;
+
+  if ( $cust_main->dbdef_table->column('paycvv') ) {
+    my $paycvv = $cust_main->paycvv;
+
+    foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 bs
+      $paybychecked{$payby} .= qq!<BR>CVV2&nbsp;(<A HREF="javascript:myopen('../docs/cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>)&nbsp;<INPUT TYPE="text" NAME=${payby}_paycvv VALUE="$paycvv" SIZE=4 MAXLENGTH=4>!;
+    }
+  }
+
+
+  $cust_main->payby($payby_default) unless $cust_main->payby;
+  for (qw(CARD DCRD CHEK DCHK LECB BILL COMP)) {
+    print qq!<TD VALIGN=TOP><INPUT TYPE="radio" NAME="payby" VALUE="$_"!;
+    if ($cust_main->payby eq "$_") {
+      print qq! CHECKED> $paybychecked{$_}</TD>!;
+    } else {
+      print qq!> $payby{$_}</TD>!;
+    }
   }
-}
 
-print "</TR></TABLE>$r required fields for each billing type";
+  print "</TR></TABLE>$r required fields for each billing type";
+
+}
 
 if ( defined $cust_main->dbdef_table->column('comments') ) {
     print "<BR><BR>Comments", &itable("#cccccc"),
@@ -422,7 +525,7 @@ unless ( $custnum ) {
     foreach my $part_pkg ( @part_pkg ) {
       print qq!<OPTION VALUE="!,
 #              $part_pkg->pkgpart. "_". $pkgpart{ $part_pkg->pkgpart }, '"';
-              $part_pkg->pkgpart. "_". $part_pkg->svcpart, '"';
+              $part_pkg->pkgpart. "_". $part_pkg->svcpart('svc_acct'), '"';
       print " SELECTED" if $saved_pkgpart && ( $part_pkg->pkgpart == $saved_pkgpart );
       print ">", $part_pkg->pkg, " - ", $part_pkg->comment;
     }
index 7ef37a4..4bcfcbe 100755 (executable)
@@ -15,12 +15,27 @@ print qq!<FORM ACTION="!, popurl(1),
         <TH><FONT SIZE=-1>Country</FONT></TH>
         <TH><FONT SIZE=-1>State</FONT></TH>
         <TH><FONT SIZE=-1>County</FONT></TH>
-        <TH><FONT SIZE=-1>Taxclass</FONT></TH>
+        <TH><FONT SIZE=-1>Taxclass</FONT><BR><FONT SIZE=-2>(per-package classification)</FONT></TH>
+END
+
+if ( dbdef->table('cust_main_county')->column('taxname') ) {
+  print '<TH><FONT SIZE=-1>Tax name</FONT><BR><FONT SIZE=-2>(printed on invoices)</FONT></TH>';
+}
+
+print <<END;
         <TH><FONT SIZE=-1>Tax</FONT></TH>
         <TH><FONT SIZE=-1>Exempt<BR>per<BR>month</TH>
-      </TR>
 END
 
+if ( dbdef->table('cust_main_county')->column('setuptax') ) {
+  print '<TH><FONT SIZE=-1>Setup<BR>fee<BR>exempt</TH>';
+}
+if ( dbdef->table('cust_main_county')->column('recurtax') ) {
+  print '<TH><FONT SIZE=-1>Recurring<BR>fee<BR>exempt</TH>';
+}
+
+print '</TR>';
+
 foreach my $cust_main_county ( sort {    $a->country cmp $b->country
                                       or $a->state   cmp $b->state
                                       or $a->county  cmp $b->county
@@ -46,10 +61,27 @@ END
       : ' BGCOLOR="#cccccc">(ALL)'
     , "</TD>";
 
-  print qq!<TD><INPUT TYPE="text" NAME="tax!, $hashref->{taxnum},
-        qq!" VALUE="!, $hashref->{tax}, qq!" SIZE=6 MAXLENGTH=6>%</TD>!;
-  print qq!<TD>\$<INPUT TYPE="text" NAME="exempt_amount!, $hashref->{taxnum},
-        qq!" VALUE="!, $hashref->{exempt_amount}||0, qq!" SIZE=6></TD>!;
+  print qq!<TD><INPUT TYPE="text" NAME="taxname!, $hashref->{taxnum},
+        qq!" VALUE="!, $hashref->{taxname}, qq!"></TD>!
+    if dbdef->table('cust_main_county')->column('taxname');
+
+  print qq!<TD><TABLE><TR><TD><INPUT TYPE="text" NAME="tax!, $hashref->{taxnum},
+        qq!" VALUE="!, $hashref->{tax}, qq!" SIZE=6 MAXLENGTH=6></TD><TD>%</TD></TR></TABLE></TD>!;
+  print qq!<TD><TABLE><TR><TD>\$</TD><TD><INPUT TYPE="text" NAME="exempt_amount!, $hashref->{taxnum},
+        qq!" VALUE="!, $hashref->{exempt_amount}||0, qq!" SIZE=6></TD></TR></TABLE></TD>!;
+
+  print qq!<TD><INPUT TYPE="checkbox" NAME="setuptax!. $hashref->{taxnum}.
+        '" VALUE="Y"'.
+        ( $hashref->{setuptax} =~ /^Y$/i ? ' CHECKED' : '' ).
+        '></TD>'
+    if dbdef->table('cust_main_county')->column('setuptax');
+
+  print qq!<TD><INPUT TYPE="checkbox" NAME="recurtax!. $hashref->{taxnum}.
+        '" VALUE="Y"'.
+        ( $hashref->{recurtax} =~ /^Y$/i ? ' CHECKED' : '' ).
+        '></TD>'
+    if dbdef->table('cust_main_county')->column('recurtax');
+
   print '</TR>';
 
 }
index 324daeb..48ed791 100755 (executable)
@@ -20,7 +20,7 @@ if ( $query && $query =~ /^(\d+)$/ ) {
 } else {
   $part_bill_event ||= new FS::part_bill_event {};
 }
-$action ||= $part_bill_event->pkgpart ? 'Edit' : 'Add';
+$action ||= $part_bill_event->eventpart ? 'Edit' : 'Add';
 my $hashref = $part_bill_event->hashref;
 
 print header("$action Invoice Event Definition", menubar(
@@ -41,7 +41,7 @@ print ntable("#cccccc",2), <<END;
 <TR><TD ALIGN="right">Payby</TD><TD><SELECT NAME="payby">
 END
 
-for (qw(CARD BILL COMP)) {
+for (qw(CARD DCRD CHEK DCHK LECB BILL COMP)) {
   print qq!<OPTION VALUE="$_"!;
   if ($part_bill_event->payby eq $_) {
     print " SELECTED>$_</OPTION>";
@@ -108,9 +108,15 @@ tie my %events, 'Tie::IxHash',
     'weight' => 30,
   },
 
-  'realtime-card-cybercash' => {
-    'name' => '(<b>deprecated</b>) Run card with <a href="http://www.cybercash.com/cashregister">CyberCash CashRegister</a> realtime gateway',
-    'code' => '$cust_bill->realtime_card_cybercash();',
+  'realtime-check' => {
+    'name' => 'Run check with a <a href="http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment">Business::OnlinePayment</a> realtime gateway',
+    'code' => '$cust_bill->realtime_ach();',
+    'weight' => 30,
+  },
+
+  'realtime-lec' => {
+    'name' => 'Run phone bill ("LEC") billing with a <a href="http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment">Business::OnlinePayment</a> realtime gateway',
+    'code' => '$cust_bill->realtime_lec();',
     'weight' => 30,
   },
 
@@ -134,6 +140,30 @@ tie my %events, 'Tie::IxHash',
     'weight' => 50,
   },
 
+  'send_csv_ftp' => {
+    'name' => 'Upload CSV invoice data to an FTP server',
+    'code' => '$cust_bill->send_csv( protocol => \'ftp\',
+                                     server   => \'%%%ftpserver%%%\',
+                                     username => \'%%%ftpusername%%%\',
+                                     password => \'%%%ftppassword%%%\',
+                                     dir      => \'%%%ftpdir%%%\'       );',
+    'html' =>
+        '<TABLE BORDER=0><TR><TD ALIGN="right">FTP server: </TD>'.
+          '<TD><INPUT TYPE="text" NAME="ftpserver" VALUE="%%%ftpserver%%%">'.
+          '</TD></TR>'.
+        '<TR><TD ALIGN="right">FTP username: </TD><TD>'.
+          '<INPUT TYPE="text" NAME="ftpusername" VALUE="%%%ftpusername%%%">'.
+          '</TD></TR>'.
+        '<TR><TD ALIGN="right">FTP password: </TD><TD>'.
+          '<INPUT TYPE="text" NAME="ftppassword" VALUE="%%%ftppassword%%%">'.
+          '</TD></TR>'.
+        '<TR><TD ALIGN="right">FTP directory: </TD>'.
+          '<TD><INPUT TYPE="text" NAME="ftpdir" VALUE="%%%ftpdir%%%">'.
+          '</TD></TR>'.
+        '</TABLE>',
+    'weight' => 50,
+  },
+
   'bill' => {
     'name' => 'Generate invoices (normally only used with a <i>Late Fee</i> event)',
     'code' => '$cust_main->bill();',
index 486bd43..4d0c739 100644 (file)
@@ -49,24 +49,33 @@ my $widget = new HTML::Widgets::SelectLayers(
       my $label = $optinfo->{label};
       my $type = defined($optinfo->{type}) ? $optinfo->{type} : 'text';
       my $value = $cgi->param($option)
-                  || $part_export->option($option)
-                  || (exists $optinfo->{default} ? $optinfo->{default} : '');
+                 || ( $part_export->exportnum && $part_export->option($option) )
+                 || ( (exists $optinfo->{default} && !$part_export->exportnum)
+                      ? $optinfo->{default}
+                      : ''
+                    );
       $html .= qq!<TR><TD ALIGN="right">$label</TD><TD>!;
       if ( $type eq 'select' ) {
         $html .= qq!<SELECT NAME="$option">!;
         foreach my $select_option ( @{$optinfo->{options}} ) {
           #if ( ref($select_option) ) {
           #} else {
-            $selected = $select_option eq $value ? ' SELECTED' : '';
+            my $selected = $select_option eq $value ? ' SELECTED' : '';
             $html .= qq!<OPTION VALUE="$select_option"$selected>!.
                      qq!$select_option</OPTION>!;
           #}
         }
         $html .= '</SELECT>';
       } elsif ( $type eq 'textarea' ) {
-        $html .= qq!<TEXTAREA NAME="$option">$value</TEXTAREA>!;
+        $html .= qq!<TEXTAREA NAME="$option" COLS=80 ROWS=8 WRAP="virtual">!.
+                 encode_entities($value). '</TEXTAREA>';
       } elsif ( $type eq 'text' ) {
-        $html .= qq!<INPUT TYPE="text" NAME="$option" VALUE="$value" SIZE=64>!;
+        $html .= qq!<INPUT TYPE="text" NAME="$option" VALUE="!.
+                 encode_entities($value). '" SIZE=64>';
+      } elsif ( $type eq 'checkbox' ) {
+        $html .= qq!<INPUT TYPE="checkbox" NAME="$option" VALUE="1"!;
+        $html .= ' CHECKED' if $value;
+        $html .= '>';
       } else {
         $html .= "unknown type $type";
       }
index b6ecff2..8416b35 100755 (executable)
@@ -66,12 +66,52 @@ print '<FORM NAME="dummy">';
 #print qq!<INPUT TYPE="hidden" NAME="pkgpart" VALUE="$hashref->{pkgpart}">!,
 print "Package Part #", $hashref->{pkgpart} ? $hashref->{pkgpart} : "(NEW)";
 
-print ntable("#cccccc",2), <<END;
-<TR><TD ALIGN="right">Package (customer-visable)</TD><TD><INPUT TYPE="text" NAME="pkg" SIZE=32 VALUE="$hashref->{pkg}"></TD></TR>
-<TR><TD ALIGN="right">Comment (customer-hidden)</TD><TD><INPUT TYPE="text" NAME="comment" SIZE=32 VALUE="$hashref->{comment}"></TD></TR>
-<TR><TD ALIGN="right">Frequency (months) of recurring fee</TD><TD><INPUT TYPE="text" NAME="freq" VALUE="$hashref->{freq}" SIZE=3>&nbsp;&nbsp;<I>0=no recurring fee, 1=monthly, 3=quarterly, 12=yearly</TD></TR>
-<TR><TD ALIGN="right">Setup fee tax exempt</TD><TD>
-END
+#false laziness w/view/cust_main.cgi
+my %freq;
+tie %freq, 'Tie::IxHash', 
+  '0'  => '(no recurring fee)',
+  '1d' => 'daily',
+  '1w' => 'weekly',
+  '2w' => 'biweekly (every 2 weeks)',
+  '1'  => 'monthly',
+  '2'  => 'bimonthly (every 2 months)',
+  '3'  => 'quarterly (every 3 months)',
+  '6'  => 'semiannually (every 6 months)',
+  '12' => 'annually',
+  '24' => 'biannually (every 2 years)',
+;
+if ( $part_pkg->dbdef_table->column('freq')->type =~ /(int)/i ) {
+  delete $freq{$_} foreach grep { ! /^\d+$/ } keys %freq;
+}
+
+%>
+<%= ntable("#cccccc",2) %>
+  <TR>
+    <TD ALIGN="right">Package (customer-visible)</TD>
+    <TD>
+      <INPUT TYPE="text" NAME="pkg" SIZE=32 VALUE="<%= $part_pkg->pkg %>">
+    </TD>
+  </TR>
+  <TR>
+    <TD ALIGN="right">Comment (customer-hidden)</TD>
+    <TD>
+      <INPUT TYPE="text" NAME="comment" SIZE=32 VALUE="<%=$part_pkg->comment%>">
+    </TD>
+  </TR>
+  <TR>
+    <TD ALIGN="right">Recurring fee frequency </TD>
+    <TD>
+      <SELECT NAME="freq">
+        <% foreach my $freq ( keys %freq ) { %>
+          <OPTION VALUE="<%= $freq %>"<%= $freq eq $part_pkg->freq ? ' SELECTED' : '' %>><%= $freq{$freq} %>
+        <% } %>
+      </SELECT>
+    </TD>
+  </TR>
+  <TR>
+    <TD ALIGN="right">Setup fee tax exempt</TD>
+    <TD>
+<%
 
 print '<INPUT TYPE="checkbox" NAME="setuptax" VALUE="Y"';
 print ' CHECKED' if $hashref->{setuptax} eq "Y";
@@ -112,9 +152,11 @@ print ' CHECKED' if $hashref->{disabled} eq "Y";
 print '>';
 print '</TD></TR></TABLE>';
 
-my $thead =  "\n\n". ntable('#cccccc', 2). <<END;
-<TR><TH BGCOLOR="#dcdcdc"><FONT SIZE=-1>Quan.</FONT></TH><TH BGCOLOR="#dcdcdc">Service</TH></TR>
-END
+my $thead =  "\n\n". ntable('#cccccc', 2).
+             '<TR><TH BGCOLOR="#dcdcdc"><FONT SIZE=-1>Quan.</FONT></TH>';
+$thead .=  '<TH BGCOLOR="#dcdcdc"><FONT SIZE=-1>Primary</FONT></TH>'
+  if dbdef->table('pkg_svc')->column('primary_svc');
+$thead .= '<TH BGCOLOR="#dcdcdc">Service</TH></TR>';
 
 #unless ( $cgi->param('clone') ) {
 #dunno why...
@@ -131,13 +173,15 @@ my $columns = 3;
 my @part_svc = qsearch( 'part_svc', { 'disabled' => '' } );
 foreach my $part_svc ( @part_svc ) {
   my $svcpart = $part_svc->svcpart;
-  my $pkg_svc = qsearchs( 'pkg_svc', {
-    'pkgpart'  => $cgi->param('clone') || $part_pkg->pkgpart,
+  my $pkgpart = $cgi->param('clone') || $part_pkg->pkgpart;
+  my $pkg_svc = $pkgpart && qsearchs( 'pkg_svc', {
+    'pkgpart'  => $pkgpart,
     'svcpart'  => $svcpart,
   } ) || new FS::pkg_svc ( {
-    'pkgpart'  => $cgi->param('clone') || $part_pkg->pkgpart,
-    'svcpart'  => $svcpart,
-    'quantity' => 0,
+    'pkgpart'     => $pkgpart,
+    'svcpart'     => $svcpart,
+    'quantity'    => 0,
+    'primary_svc' => '',
   });
   #? #next unless $pkg_svc;
 
@@ -149,7 +193,13 @@ foreach my $part_svc ( @part_svc ) {
     print '<TR>'; # if $count == 0 ;
     print qq!<TD><INPUT TYPE="text" NAME="pkg_svc$svcpart" SIZE=4 MAXLENGTH=3 VALUE="!,
           $cgi->param("pkg_svc$svcpart") || $pkg_svc->quantity || 0,
-          qq!"></TD><TD><A HREF="part_svc.cgi?!,$part_svc->svcpart,
+          qq!"></TD>!;
+    if ( dbdef->table('pkg_svc')->column('primary_svc') ) {
+      print qq!<TD><INPUT TYPE="radio" NAME="pkg_svc_primary" VALUE="$svcpart"!;
+      print ' CHECKED' if $pkg_svc->primary_svc =~ /^Y/i;
+      print '></TD>';
+    }
+    print qq!<TD><A HREF="part_svc.cgi?!,$part_svc->svcpart,
           qq!">!, $part_svc->getfield('svc'), "</A></TD></TR>";
 #    print "</TABLE></TD><TD>$thead" if ++$count == int(scalar(@part_svc) / 2);
     $count+=1;
@@ -355,6 +405,114 @@ tie my %plans, 'Tie::IxHash',
 
   },
 
+  'sqlradacct_hour' => {
+    'name' => 'Base charge plus charge per-hour (and for data) from an external sqlradius radacct table',
+    'fields' => {
+      'setup_fee' => { 'name' => 'Setup fee for this package',
+                       'default' => 0,
+                     },
+      'recur_flat' => { 'name' => 'Base monthly charge for this package',
+                        'default' => 0,
+                      },
+      'recur_included_hours' => { 'name' => 'Hours included',
+                                  'default' => 0,
+                                },
+      'recur_hourly_charge' => { 'name' => 'Additional charge per hour',
+                                 'default' => 0,
+                               },
+      'recur_included_input' => { 'name' => 'Input megabytes included',
+                                  'default' => 0,
+                                },
+      'recur_input_charge' => { 'name' =>
+                                        'Additional charge per input megabyte',
+                                'default' => 0,
+                              },
+      'recur_included_output' => { 'name' => 'Output megabytes included',
+                                   'default' => 0,
+                                },
+      'recur_output_charge' => { 'name' =>
+                                       'Additional charge per output megabyte',
+                                'default' => 0,
+                              },
+      'recur_included_total' => { 'name' =>
+                                       'Total input+output megabytes included',
+                                  'default' => 0,
+                                },
+      'recur_total_charge' => { 'name' =>
+                                 'Additional charge per input+output megabyte',
+                                'default' => 0,
+                              },
+    },
+    'fieldorder' => [qw( setup_fee recur_flat recur_included_hours recur_hourly_charge recur_included_input recur_input_charge recur_included_output recur_output_charge recur_included_total recur_total_charge )],
+    '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 $hourscharge = sprintf(\"%.2f\", \' + what.recur_hourly_charge.value + \' * $hours); push @details, \"Last month\\\'s excess data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\", \"Last month\\\'s excess time \". sprintf(\"%.1f\", $hours). \" hours: \\\$$hourscharge\"; \' + what.recur_flat.value + \' + $hourscharge + \' + what.recur_input_charge.value + \' * $input + \' + what.recur_output_charge.value + \' * $output + $totalcharge ;\'',
+  },
+
+  'sql_generic' => {
+    'name' => 'Base charge plus a metered rate from a configurable SQL query',
+    'fields' => {
+      'setup_fee' => { 'name' => 'Setup fee for this package',
+                       'default' => 0,
+                     },
+      'recur_flat' => { 'name' => 'Base monthly charge for this package',
+                        'default' => 0,
+                      },
+      'recur_included' => { 'name' => 'Units included',
+                            'default' => 0,
+                          },
+      'recur_unit_charge' => { 'name' => 'Additional charge per unit',
+                               'default' => 0,
+                             },
+      'datasrc' => { 'name' => 'DBI data source',
+                     'default' => '',
+                   },
+      'db_username' => { 'name' => 'Database username',
+                         'default' => '',
+                       },
+      'db_password' => { 'name' => 'Database username',
+                         'default' => '',
+                       },
+      'query' => { 'name' => 'SQL query',
+                   'default' => '',
+                 },
+    },
+    'fieldorder' => [qw( setup_fee recur_flat recur_included recur_unit_charge datasrc db_username db_password query )],
+    'setup' => 'what.setup_fee.value',
+   # 'recur' => '\'my $dbh = DBI->connect(\"\' + what.datasrc.value + \'\", \"\' + what.db_username.value + \'\") or die $DBI::errstr; \'',
+   'recur' => '\'my $dbh = DBI->connect(\"\' + what.datasrc.value + \'\", \"\' + what.db_username.value + \'\", \"\' + what.db_password.value + \'\" ) or die $DBI::errstr; my $sth = $dbh->prepare(\"\' + what.query.value + \'\") or die $dbh->errstr; my $units = 0; foreach my $cust_svc ( grep { $_->part_svc->svcdb eq \"svc_domain\" } $cust_pkg->cust_svc ) { my $domain = $cust_svc->svc_x->domain; $sth->execute($domain) or die $sth->errstr; $units += $sth->fetchrow_arrayref->[0]; } $units -= \' + what.recur_included.value + \'; $units = 0 if $units < 0; \' + what.recur_flat.value + \' + $units * \' + what.recur_unit_charge.value + \';\'',
+    #'recur' => '\'my $dbh = DBI->connect("\' + what.datasrc.value + \'", "\' + what.db_username.value + \'", "\' what.db_password.value + \'" ) or die $DBI::errstr; my $sth = $dbh->prepare("\' + what.query.value + \'") or die $dbh->errstr; my $units = 0; foreach my $cust_svc ( grep { $_->part_svc->svcdb eq "svc_domain" } $cust_pkg->cust_svc ) { my $domain = $cust_svc->svc_x->domain; $sth->execute($domain) or die $sth->errstr; $units += $sth->fetchrow_arrayref->[0]; } $units -= \' + what.recur_included.value + \'; $units = 0 if $units < 0; \' + what.recur_flat.value + \' + $units * \' + what.recur_unit_charge + \';\'',
+  },
+
+
+
+  'sql_external' => {
+    'name' => 'Base charge plus additional fees for external services from a configurable SQL query',
+    'fields' => {
+      'setup_fee' => { 'name' => 'Setup fee for this package',
+                       'default' => 0,
+                     },
+      'recur_flat' => { 'name' => 'Base monthly charge for this package',
+                        'default' => 0,
+                      },
+      'datasrc' => { 'name' => 'DBI data source',
+                     'default' => '',
+                   },
+      'db_username' => { 'name' => 'Database username',
+                         'default' => '',
+                       },
+      'db_password' => { 'name' => 'Database password',
+                         'default' => '',
+                       },
+      'query' => { 'name' => 'SQL query',
+                   'default' => '',
+                 },
+    },
+    'fieldorder' => [qw( setup_fee recur_flat datasrc db_username db_password query )],
+    'setup' => 'what.setup_fee.value',
+    'recur' => q!'my $dbh = DBI->connect("' + what.datasrc.value + '", "' + what.db_username.value + '", "' + what.db_password.value + '" ) or die $DBI::errstr; my $sth = $dbh->prepare("' + what.query.value + '") or die $dbh->errstr; my $price = ' + what.recur_flat.value + '; foreach my $cust_svc ( grep { $_->part_svc->svcdb eq "svc_external" } $cust_pkg->cust_svc ){ my $id = $cust_svc->svc_x->id; $sth->execute($id) or die $sth->errstr; $price += $sth->fetchrow_arrayref->[0]; } $price;'!,
+
+  },
+
 ;
 
 my %plandata = map { /^(\w+)=(.*)$/; ( $1 => $2 ); }
@@ -369,6 +527,10 @@ if ( $conf->exists('enable_taxclasses') ) {
   push @fixups, 'taxclass'; #hidden
 }
 
+my @form_radio = ();
+if ( dbdef->table('pkg_svc')->column('primary_svc') ) {
+  push @form_radio, 'pkg_svc_primary';
+}
 
 my $widget = new HTML::Widgets::SelectLayers(
   'selected_layer' => $part_pkg->plan,
@@ -377,7 +539,8 @@ my $widget = new HTML::Widgets::SelectLayers(
   'form_action'    => 'process/part_pkg.cgi',
   'form_text'      => [ qw(pkg comment freq clone pkgnum pkgpart), @fixups ],
   'form_checkbox'  => [ qw(setuptax recurtax disabled) ],
-  'form_select'    => [ @form_select ],
+  'form_radio'     => \@form_radio,
+  'form_select'    => \@form_select,
   'fixup_callback' => sub {
                         #my $ = @_;
                         my $html = '';
@@ -442,11 +605,11 @@ my $widget = new HTML::Widgets::SelectLayers(
              '<TR><TD>'.
              '<FONT SIZE="1">Setup expression<BR>'.
              '<INPUT TYPE="text" NAME="setup" SIZE="160" VALUE="'.
-               $hashref->{setup}. '" onLoad="fchanged(this)">'.
+               encode_entities($hashref->{setup}). '" onLoad="fchanged(this)">'.
              '</FONT><BR>'.
              '<FONT SIZE="1">Recurring espression<BR>'.
              '<INPUT TYPE="text" NAME="recur" SIZE="160" VALUE="'.
-               $hashref->{recur}. '" onLoad="fchanged(this)">'.
+               encode_entities($hashref->{recur}). '" onLoad="fchanged(this)">'.
              '</FONT>'.
              '</TR></TD>'.
              '</TABLE>';
index 4ccb770..6868ffd 100755 (executable)
@@ -50,9 +50,10 @@ Disable new orders <INPUT TYPE="checkbox" NAME="disabled" VALUE="Y"<%= $hashref-
 Services are items you offer to your customers.
 <UL><LI>svc_acct - Shell accounts, POP mailboxes, SLIP/PPP and ISDN accounts
     <LI>svc_domain - Domains
-    <LI>svc_acct_sm - <B>deprecated</B> (use svc_forward for new installations) Virtual domain mail aliasing.
     <LI>svc_forward - mail forwarding
     <LI>svc_www - Virtual domain website
+    <LI>svc_broadband - Broadband/High-speed Internet service
+    <LI>svc_external - Externally-tracked service
 <!--   <LI>svc_charge - One-time charges (Partially unimplemented)
        <LI>svc_wo - Work orders (Partially unimplemented)
 -->
@@ -65,6 +66,9 @@ blank <B>slipip</B> as well as a fixed shell something like <B>/bin/true</B> or
 <BR><BR>
 
 <%
+
+my %vfields;
+
 #these might belong somewhere else for other user interfaces 
 #pry need to eventually create stuff that's shared amount UIs
 my %defs = (
@@ -80,7 +84,10 @@ my %defs = (
                      select_key   => 'popnum',
                      select_label => 'city',
                    },
-    'username'  => 'Username',
+    'username'  => {
+                      desc => 'Username',
+                      type => 'disabled',
+                   },
     'quota'     => '',
     '_password' => 'Password',
     'gid'       => 'GID (when blank, defaults to UID)',
@@ -101,34 +108,57 @@ my %defs = (
   'svc_domain' => {
     'domain'    => 'Domain',
   },
-  'svc_acct_sm' => {
-    'domuser'   => 'domuser@virtualdomain.com',
-    'domuid'    => 'UID where domuser@virtualdomain.com mail is forwarded',
-    'domsvc'    => 'svcnum from svc_domain for virtualdomain.com',
-  },
   'svc_forward' => {
     'srcsvc'    => 'service from which mail is to be forwarded',
     'dstsvc'    => 'service to which mail is to be forwarded',
     'dst'       => 'someone@another.domain.com to use when dstsvc is 0',
   },
-  'svc_charge' => {
-    'amount'    => 'amount',
-  },
-  'svc_wo' => {
-    'worker'    => 'Worker',
-    '_date'      => 'Date',
-  },
+#  'svc_charge' => {
+#    'amount'    => 'amount',
+#  },
+#  'svc_wo' => {
+#    'worker'    => 'Worker',
+#    '_date'      => 'Date',
+#  },
   'svc_www' => {
     #'recnum' => '',
     #'usersvc' => '',
   },
+  'svc_broadband' => {
+    'speed_down' => 'Maximum download speed for this service in Kbps.  0 denotes unlimited.',
+    'speed_up' => 'Maximum upload speed for this service in Kbps.  0 denotes unlimited.',
+    'ip_addr' => 'IP address.  Leave blank for automatic assignment.',
+    'blocknum' => 'Address block.',
+  },
+  'svc_external' => {
+    #'id' => '',
+    #'title' => '',
+  },
 );
 
+  foreach my $svcdb (grep dbdef->table($_), keys %defs ) {
+    my $self = "FS::$svcdb"->new;
+    $vfields{$svcdb} = {};
+    foreach my $field ($self->virtual_fields) { # svc_Common::virtual_fields with a null svcpart returns all of them
+      my $pvf = $self->pvf($field);
+      my @list = $pvf->list;
+      if (scalar @list) {
+        $defs{$svcdb}->{$field} = { desc        => $pvf->label,
+                                    type        => 'select',
+                                    select_list => \@list };
+      } else {
+        $defs{$svcdb}->{$field} = $pvf->label;
+      } #endif
+      $vfields{$svcdb}->{$field} = $pvf;
+      warn "\$vfields{$svcdb}->{$field} = $pvf";
+    } #next $field
+  } #next $svcdb
+  
   my @dbs = $hashref->{svcdb}
              ? ( $hashref->{svcdb} )
-             : qw( svc_acct svc_domain svc_acct_sm svc_forward svc_www );
+             : qw( svc_acct svc_domain svc_forward svc_www svc_broadband svc_external );
 
-  tie my %svcdb, 'Tie::IxHash', map { $_=>$_ } @dbs;
+  tie my %svcdb, 'Tie::IxHash', map { $_=>$_ } grep dbdef->table($_), @dbs;
   my $widget = new HTML::Widgets::SelectLayers(
     #'selected_layer' => $p_svcdb,
     'selected_layer' => $hashref->{svcdb} || 'svc_acct',
@@ -146,17 +176,18 @@ my %defs = (
       my @part_export =
         map { qsearch( 'part_export', {exporttype => $_ } ) }
           keys %{FS::part_export::export_info($layer)};
-     $html .= '<BR><BR>'. table().
+      $html .= '<BR><BR>'. table().
                table(). "<TR><TH COLSPAN=$columns>Exports</TH></TR><TR>";
       foreach my $part_export ( @part_export ) {
         $html .= '<TD><INPUT TYPE="checkbox"'.
                  ' NAME="exportnum'. $part_export->exportnum. '"  VALUE="1" ';
         $html .= 'CHECKED'
-          if qsearchs( 'export_svc', {
+          if ( $clone || $part_svc->svcpart ) #null svcpart search causing error
+              && qsearchs( 'export_svc', {
                                    exportnum => $part_export->exportnum,
                                    svcpart   => $clone || $part_svc->svcpart });
-        $html .= '> '. $part_export->exporttype. ' to '. $part_export->machine.
-                 '</TD>';
+        $html .= '>'. $part_export->exportnum. ': '. $part_export->exporttype.
+                 ' to '. $part_export->machine. '</TD>';
         $count++;
         $html .= '</TR><TR>' unless $count % $columns;
       }
@@ -183,28 +214,44 @@ my %defs = (
         $html .= "<TR><TD>$field";
         $html .= "- <FONT SIZE=-1>$desc</FONT>" if $desc;
         $html .=  "</TD>";
+        $flag = '' if ref($def) && $def->{type} eq 'disabled';
         $html .=
           qq!<TD><INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE=""!.
           ' CHECKED'x($flag eq ''). ">Off</TD>".
-          qq!<TD><INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE="D"!.
-          ' CHECKED'x($flag eq 'D'). ">Default ".
-          qq!<INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE="F"!.
-          ' CHECKED'x($flag eq 'F'). ">Fixed ".
-          '<BR>';
+          '<TD>';
+        unless ( ref($def) && $def->{type} eq 'disabled' ) {
+          $html .= 
+            qq!<INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE="D"!.
+            ' CHECKED'x($flag eq 'D'). ">Default ".
+            qq!<INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE="F"!.
+            ' CHECKED'x($flag eq 'F'). ">Fixed ";
+          $html .= '<BR>';
+        }
         if ( ref($def) ) {
           if ( $def->{type} eq 'select' ) {
             $html .= qq!<SELECT NAME="${layer}__${field}">!;
             $html .= '<OPTION> </OPTION>' unless $value;
-            foreach my $record ( qsearch( $def->{select_table}, {} ) ) {
-              my $rvalue = $record->getfield($def->{select_key});
-              $html .= qq!<OPTION VALUE="$rvalue"!.
-                       ( $rvalue==$value ? ' SELECTED>' : '>' ).
-                       $record->getfield($def->{select_label}). '</OPTION>';
-            }
+            if ( $def->{select_table} ) {
+              foreach my $record ( qsearch( $def->{select_table}, {} ) ) {
+                my $rvalue = $record->getfield($def->{select_key});
+                $html .= qq!<OPTION VALUE="$rvalue"!.
+                         ( $rvalue==$value ? ' SELECTED>' : '>' ).
+                         $record->getfield($def->{select_label}). '</OPTION>';
+              } #next $record
+            } else { # select_list
+              foreach my $item ( @{$def->{select_list}} ) {
+                $html .= qq!<OPTION VALUE="$item"!.
+                         ( $item eq $value ? ' SELECTED>' : '>' ).
+                         $item. '</OPTION>';
+              } #next $item
+            } #endif
             $html .= '</SELECT>';
           } elsif ( $def->{type} eq 'radius_usergroup_selector' ) {
             $html .= FS::svc_acct::radius_usergroup_selector(
               [ split(',', $value) ], "${layer}__${field}" );
+          } elsif ( $def->{type} eq 'disabled' ) {
+            $html .=
+              qq!<INPUT TYPE="hidden" NAME="${layer}__${field}" VALUE="">!;
           } else {
             $html .= '<font color="#ff0000">unknown type'. $def->{type};
           }
@@ -212,6 +259,11 @@ my %defs = (
           $html .=
             qq!<INPUT TYPE="text" NAME="${layer}__${field}" VALUE="$value">!;
         }
+
+        if($vfields{$layer}->{$field}) {
+          $html .= qq!<BR><INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE="X"!.
+          ' CHECKED'x($flag eq 'X'). ">Excluded ";
+        }
         $html .= "</TD></TR>\n";
       }
       $part_svc->svcpart('') if $clone; #undone
diff --git a/httemplate/edit/part_virtual_field.cgi b/httemplate/edit/part_virtual_field.cgi
new file mode 100644 (file)
index 0000000..8bc8438
--- /dev/null
@@ -0,0 +1,92 @@
+<!-- mason kludge -->
+<%
+my ($vfieldpart, $part_virtual_field);
+
+if ( $cgi->param('error') ) {
+  $part_virtual_field = new FS::part_virtual_field ( {
+    map { $_, scalar($cgi->param($_)) } fields('part_virtual_field')});
+  $vfieldpart = $part_virtual_field->vfieldpart;
+} else {
+  my($query) = $cgi->keywords;
+  if ( $query =~ /^(\d+)$/ ) { #editing
+    $vfieldpart=$1;
+    $part_virtual_field=qsearchs('part_virtual_field',
+        {'vfieldpart' => $vfieldpart})
+      or die "Unknown vfieldpart!";
+  
+  } else { #adding
+    $part_virtual_field = new FS::part_virtual_field({});
+  }
+}
+my $action = $part_virtual_field->vfieldpart ? 'Edit' : 'Add';
+
+my $p1 = popurl(1);
+print header("$action Virtual Field Definition", '');
+
+print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'),
+      "</FONT>"
+  if $cgi->param('error');
+%>
+<FORM ACTION="<%=$p1%>process/generic.cgi" METHOD="POST">
+
+<INPUT TYPE="hidden" NAME="table" VALUE="part_virtual_field">
+<INPUT TYPE="hidden" NAME="redirect_ok" 
+    VALUE="<%=popurl(2)%>browse/part_virtual_field.cgi">
+<INPUT TYPE="hidden" NAME="vfieldpart" VALUE="<%=
+  $vfieldpart%>">
+Field #<B><%=$vfieldpart or "(NEW)"%></B><BR><BR>
+
+<%=ntable("#cccccc",2)%>
+  <TR>
+    <TD ALIGN="right">Name</TD>
+    <TD><INPUT TYPE="text" NAME="name" MAXLENGTH=15 VALUE="<%=
+    $part_virtual_field->name%>"></TD>
+  </TR>
+  <TR>
+    <TD ALIGN="right">Table</TD>
+    <TD><% if ($action eq 'Add') { %>
+      <SELECT SIZE=1 NAME="dbtable"><%
+        my $dbdef = dbdef;  # ick
+        foreach my $dbtable ($dbdef->tables) {
+          if ($dbtable !~ /^h_/
+          and $dbdef->table($dbtable)->primary_key) { %>
+            <OPTION VALUE="<%=$dbtable%>"><%=$dbtable%></OPTION><%
+          }
+        }
+      %></SELECT><%
+    } else { # Edit
+    %><%=$part_virtual_field->dbtable%>
+    <INPUT TYPE="hidden" NAME="dbtable" VALUE="<%=$part_virtual_field->dbtable%>">
+ <% } %>
+    </TD>
+  <TR>
+    <TD ALIGN="right">Label</TD>
+    <TD><INPUT TYPE="text" NAME="label" MAXLENGTH="20" VALUE="<%=
+    $part_virtual_field->label%>"></TD>
+  </TR>
+  <TR>
+    <TD ALIGN="right">Length</TD>
+    <TD><INPUT TYPE="text" NAME="length" MAXLENGTH=4 VALUE="<%=
+    $part_virtual_field->length%>"></TD>
+  </TR>
+  <TR>
+    <TD ALIGN="right">Check</TD>
+    <TD><TEXTAREA COLS="20" ROWS="4" NAME="check_block"><%=
+    $part_virtual_field->check_block%></TEXTAREA></TD>
+  </TR>
+  <TR>
+    <TD ALIGN="right">List source</TD>
+    <TD><TEXTAREA COLS="20" ROWS="4" NAME="list_source"><%=
+    $part_virtual_field->list_source%></TEXTAREA></TD>
+  </TR>
+</TABLE><BR><INPUT TYPE="submit" VALUE="Submit">
+
+</FORM>
+
+<BR><BR>
+<FONT SIZE=-2>If you don't understand what <I>check_block</I> and 
+<I>list_source</I> mean, <B>LEAVE THEM BLANK</B>.  We mean it.</FONT>
+
+
+</BODY>
+</HTML>
index 2e0352c..7f5c5e4 100755 (executable)
@@ -5,6 +5,8 @@ my $old = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
 my %hash = $old->hash;
 $hash{'setup'} = $cgi->param('setup') ? str2time($cgi->param('setup')) : '';
 $hash{'bill'} = $cgi->param('bill') ? str2time($cgi->param('bill')) : '';
+$hash{'last_bill'} =
+  $cgi->param('last_bill') ? str2time($cgi->param('last_bill')) : '';
 $hash{'expire'} = $cgi->param('expire') ? str2time($cgi->param('expire')) : '';
 my $new = new FS::cust_pkg \%hash;
 
diff --git a/httemplate/edit/process/addr_block/add.cgi b/httemplate/edit/process/addr_block/add.cgi
new file mode 100755 (executable)
index 0000000..34d799c
--- /dev/null
@@ -0,0 +1,20 @@
+<%
+
+my $error = '';
+my $ip_gateway = $cgi->param('ip_gateway');
+my $ip_netmask = $cgi->param('ip_netmask');
+
+my $new = new FS::addr_block {
+    ip_gateway => $ip_gateway,
+    ip_netmask => $ip_netmask,
+    routernum  => 0 };
+
+$error = $new->insert;
+
+if ( $error ) {
+  $cgi->param('error', $error);
+  print $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string );
+} else { 
+  print $cgi->redirect(popurl(4). "browse/addr_block.cgi");
+} 
+%>
diff --git a/httemplate/edit/process/addr_block/allocate.cgi b/httemplate/edit/process/addr_block/allocate.cgi
new file mode 100755 (executable)
index 0000000..85b0d7a
--- /dev/null
@@ -0,0 +1,25 @@
+<%
+my $error = '';
+my $blocknum = $cgi->param('blocknum');
+my $routernum = $cgi->param('routernum');
+
+my $addr_block = qsearchs('addr_block', { blocknum => $blocknum });
+my $router = qsearchs('router', { routernum => $routernum });
+
+if($addr_block) {
+  if ($router) {
+    $error = $addr_block->allocate($router);
+  } else {
+    $error = "Cannot find router with routernum $routernum";
+  }
+} else {
+  $error = "Cannot find block with blocknum $blocknum";
+}
+
+if ( $error ) {
+  $cgi->param('error', $error);
+  print $cgi->redirect(popurl(4). "browse/addr_block.cgi?" . $cgi->query_string);
+} else { 
+  print $cgi->redirect(popurl(4). "browse/addr_block.cgi");
+}
+%>
diff --git a/httemplate/edit/process/addr_block/deallocate.cgi b/httemplate/edit/process/addr_block/deallocate.cgi
new file mode 100755 (executable)
index 0000000..cfb7ed0
--- /dev/null
@@ -0,0 +1,24 @@
+<%
+my $error = '';
+my $blocknum = $cgi->param('blocknum');
+
+my $addr_block = qsearchs('addr_block', { blocknum => $blocknum });
+
+if($addr_block) {
+  my $router = $addr_block->router;
+  if ($router) {
+    $error = $addr_block->deallocate($router);
+  } else {
+    $error = "Block is not allocated to a router";
+  }
+} else {
+  $error = "Cannot find block with blocknum $blocknum";
+}
+
+if ( $error ) {
+  $cgi->param('error', $error);
+  print $cgi->redirect(popurl(4). "browse/addr_block.cgi?" . $cgi->query_string);
+} else { 
+  print $cgi->redirect(popurl(4). "browse/addr_block.cgi");
+}
+%>
diff --git a/httemplate/edit/process/addr_block/split.cgi b/httemplate/edit/process/addr_block/split.cgi
new file mode 100755 (executable)
index 0000000..bb6d4ba
--- /dev/null
@@ -0,0 +1,19 @@
+<%
+my $error = '';
+my $blocknum = $cgi->param('blocknum');
+my $addr_block = qsearchs('addr_block', { blocknum => $blocknum });
+
+if ( $addr_block) {
+  $error = $addr_block->split_block;
+} else {
+  $error = "Unknown blocknum: $blocknum";
+}
+
+
+if ( $error ) {
+  $cgi->param('error', $error);
+  print $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string );
+} else { 
+  print $cgi->redirect(popurl(4). "browse/addr_block.cgi");
+} 
+%>
index 6ce60d1..25c346e 100755 (executable)
@@ -10,16 +10,25 @@ $cgi->param('refnum', (split(/:/, ($cgi->param('refnum'))[0] ))[0] );
 
 my $payby = $cgi->param('payby');
 if ( $payby ) {
-  $cgi->param('payinfo', $cgi->param( $payby. '_payinfo' ) );
+  if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) {
+    $cgi->param('payinfo',
+      $cgi->param($payby. '_payinfo1'). '@'. $cgi->param($payby. '_payinfo2') );
+  } else {
+    $cgi->param('payinfo', $cgi->param( $payby. '_payinfo' ) );
+  }
   $cgi->param('paydate',
-  $cgi->param( $payby. '_month' ). '-'. $cgi->param( $payby. '_year' ) );
+    $cgi->param( $payby. '_month' ). '-'. $cgi->param( $payby. '_year' ) );
   $cgi->param('payname', $cgi->param( $payby. '_payname' ) );
+  $cgi->param('paycvv', $cgi->param( $payby. '_paycvv' ) )
+    if defined $cgi->param( $payby. '_paycvv' );
 }
 
 $cgi->param('otaker', &getotaker );
 
 my @invoicing_list = split( /\s*\,\s*/, $cgi->param('invoicing_list') );
 push @invoicing_list, 'POST' if $cgi->param('invoicing_list_POST');
+$cgi->param('invoicing_list', join(',', @invoicing_list) );
+
 
 #create new record object
 
@@ -46,7 +55,7 @@ if ( $new->custnum eq '' ) {
 
   if ( $cgi->param('pkgpart_svcpart') ) {
     my $x = $cgi->param('pkgpart_svcpart');
-    $x =~ /^(\d+)_(\d+)$/;
+    $x =~ /^(\d+)_(\d+)$/ or die "illegal pkgpart_svcpart $x\n";
     my($pkgpart, $svcpart) = ($1, $2);
     #false laziness: copied from FS::cust_pkg::order (which should become a
     #FS::cust_main method)
@@ -64,7 +73,7 @@ if ( $new->custnum eq '' ) {
     #eslaf
 
     # this should wind up in FS::cust_pkg!
-    $error ||= "Agent ". $new->agentnum. " (type ". $agent->typenum. ") can't".
+    $error ||= "Agent ". $new->agentnum. " (type ". $agent->typenum. ") can't ".
                "purchase pkgpart ". $pkgpart
       #unless $part_pkg{ $pkgpart };
       unless $pkgpart_href->{ $pkgpart };
@@ -107,6 +116,11 @@ if ( $new->custnum eq '' ) {
 } else { #create old record object
   my $old = qsearchs( 'cust_main', { 'custnum' => $new->custnum } ); 
   $error ||= "Old record not found!" unless $old;
+  if ( defined dbdef->table('cust_main')->column('paycvv')
+       && length($old->paycvv)
+       && $new->paycvv =~ /^\s*\*+\s*$/ ) {
+    $new->paycvv($old->paycvv);
+  }
   $error ||= $new->replace($old, \@invoicing_list);
 }
 
index 8e67140..5da9dea 100755 (executable)
@@ -3,8 +3,8 @@
 my($query) = $cgi->keywords;
 $query =~ /^(\d+)$/ or die "Illegal taxnum!";
 my $taxnum = $1;
-my $cust_main_county = qsearchs('cust_main_county',{'taxnum'=>$taxnum})
-  or die ("Unknown taxnum!");
+my $cust_main_county = qsearchs('cust_main_county', { 'taxnum' => $taxnum } )
+  or die "Unknown taxnum $taxnum";
 
 #really should do this in a .pm & start transaction
 
index 990a239..9287ed1 100755 (executable)
@@ -2,17 +2,22 @@
 
 foreach ( grep { /^tax\d+$/ } $cgi->param ) {
   /^tax(\d+)$/ or die "Illegal form $_!";
-  my($taxnum)=$1;
-  my($old)=qsearchs('cust_main_county',{'taxnum'=>$taxnum})
+  my $taxnum = $1;
+  my $old = qsearchs('cust_main_county', { 'taxnum' => $taxnum })
     or die "Couldn't find taxnum $taxnum!";
-  my $exempt_amount = $cgi->param("exempt_amount$taxnum");
-  next unless $old->tax ne $cgi->param("tax$taxnum")
-              || $old->exempt_amount ne $exempt_amount;
+  next unless    $old->tax           != $cgi->param("tax$taxnum")
+              || $old->exempt_amount != $cgi->param("exempt_amount$taxnum")
+              || $old->taxname       ne $cgi->param("taxname$taxnum")
+              || $old->setuptax      ne $cgi->param("setuptax$taxnum")
+              || $old->recurtax      ne $cgi->param("recurtax$taxnum");
   my %hash = $old->hash;
   $hash{tax} = $cgi->param("tax$taxnum");
-  $hash{exempt_amount} = $exempt_amount;
-  my($new)=new FS::cust_main_county \%hash;
-  my($error)=$new->replace($old);
+  $hash{exempt_amount} = $cgi->param("exempt_amount$taxnum");
+  $hash{taxname} = $cgi->param("taxname$taxnum");
+  $hash{setuptax} = $cgi->param("setuptax$taxnum");
+  $hash{recurtax} = $cgi->param("recurtax$taxnum");
+  my $new = new FS::cust_main_county \%hash;
+  my $error = $new->replace($old);
   if ( $error ) {
     $cgi->param('error', $error);
     print $cgi->redirect(popurl(2). "cust_main_county.cgi?". $cgi->query_string );
index f8c9f51..df8471c 100755 (executable)
@@ -11,16 +11,23 @@ my @remove_pkgnums = map {
   $1;
 } $cgi->param('remove_pkg');
 
+my $error_redirect;
 my @pkgparts;
-foreach my $pkgpart ( map /^pkg(\d+)$/ ? $1 : (), $cgi->param ) {
-  if ( $cgi->param("pkg$pkgpart") =~ /^(\d+)$/ ) {
-    my $num_pkgs = $1;
-    while ( $num_pkgs-- ) {
-      push @pkgparts,$pkgpart;
+if ( $cgi->param('new_pkgpart') =~ /^(\d+)$/ ) { #came from misc/change_pkg.cgi
+  $error_redirect = "misc/change_pkg.cgi";
+  @pkgparts = ($1);
+} else { #came from edit/cust_pkg.cgi
+  $error_redirect = "edit/cust_pkg.cgi";
+  foreach my $pkgpart ( map /^pkg(\d+)$/ ? $1 : (), $cgi->param ) {
+    if ( $cgi->param("pkg$pkgpart") =~ /^(\d+)$/ ) {
+      my $num_pkgs = $1;
+      while ( $num_pkgs-- ) {
+        push @pkgparts,$pkgpart;
+      }
+    } else {
+      $error = "Illegal quantity";
+      last;
     }
-  } else {
-    $error = "Illegal quantity";
-    last;
   }
 }
 
@@ -28,7 +35,7 @@ $error ||= FS::cust_pkg::order($custnum,\@pkgparts,\@remove_pkgnums);
 
 if ($error) {
   $cgi->param('error', $error);
-  print $cgi->redirect(popurl(2). "cust_pkg.cgi?". $cgi->query_string );
+  print $cgi->redirect(popurl(3). $error_redirect. '?'. $cgi->query_string );
 } else {
   print $cgi->redirect(popurl(3). "view/cust_main.cgi?$custnum");
 }
diff --git a/httemplate/edit/process/generic.cgi b/httemplate/edit/process/generic.cgi
new file mode 100644 (file)
index 0000000..9c54feb
--- /dev/null
@@ -0,0 +1,70 @@
+<%
+
+# Welcome to generic.cgi.
+# 
+# This script provides a generic edit/process/ backend for simple table 
+# editing.  All it knows how to do is take the values entered into 
+# the script and insert them into the table specified by $cgi->param('table').
+# If there's an existing record with the same primary key, it will be 
+# replaced.  (Deletion will be added in the future.)
+# 
+# Special cgi params for this script:
+# table: the name of the table to be edited.  The script will die horribly 
+#        if it can't find the table.
+# redirect_ok: URL to be displayed after a successful edit.  The value of 
+#              the record's primary key will be passed as a keyword.
+#              Defaults to (freeside root)/view/$table.cgi.
+# redirect_error: URL to be displayed if there's an error.  The original 
+#                 query string, plus the error message, will be passed.
+#                 Defaults to $cgi->referer() (i.e. go back where you 
+#                 came from).
+
+
+use FS::Record qw(qsearchs dbdef);
+use DBIx::DBSchema;
+use DBIx::DBSchema::Table;
+
+
+my $error;
+my $p2 = popurl(2);
+my $p3 = popurl(3);
+my $table = $cgi->param('table');
+my $dbdef = dbdef or die "Cannot fetch dbdef!";
+
+my $dbdef_table = $dbdef->table($table) or die "Cannot fetch schema for $table";
+
+my $pkey = $dbdef_table->primary_key or die "Cannot fetch pkey for $table";
+my $pkey_val = $cgi->param($pkey);
+
+
+#warn "new FS::Record ( $table, (hashref) )";
+my $new = FS::Record::new ( "FS::$table", {
+    map { $_, scalar($cgi->param($_)) } fields($table) 
+} );
+
+#warn 'created $new of class '.ref($new);
+
+if($pkey_val and (my $old = qsearchs($table, { $pkey, $pkey_val} ))) {
+  # edit
+  $error = $new->replace($old);
+} else {
+  #add
+  $error = $new->insert;
+  $pkey_val = $new->getfield($pkey);
+  # New records usually don't have their primary keys set until after 
+  # they've been checked/inserted, so grab the new $pkey_val so we can 
+  # redirect to it.
+}
+
+my $redirect_ok = (($cgi->param('redirect_ok')) ?
+                    $cgi->param('redirect_ok') : $p3."browse/generic.cgi?$table");
+my $redirect_error = (($cgi->param('redirect_error')) ?
+                       $cgi->param('redirect_error') : $cgi->referer());
+
+if($error) {
+  $cgi->param('error', $error);
+  print $cgi->redirect($redirect_error . '?' . $cgi->query_string);
+} else {
+  print $cgi->redirect($redirect_ok);
+}
+%>
index 4049ade..e224bf6 100755 (executable)
@@ -12,7 +12,7 @@ if ( ! $cgi->param('plan_weight_eventcode') ) {
   $error = "Must select an action";
 } else {
 
-  $cgi->param('plan_weight_eventcode') =~ /^([\w\-]+):(\d+):(.*)$/
+  $cgi->param('plan_weight_eventcode') =~ /^([\w\-]+):(\d+):(.*)$/s
     or die "illegal plan_weight_eventcode:".
            $cgi->param('plan_weight_eventcode');
   $cgi->param('plan', $1);
index d489426..7eada7b 100755 (executable)
@@ -62,16 +62,24 @@ if ( $error ) {
 
 foreach my $part_svc (qsearch('part_svc',{})) {
   my $quantity = $cgi->param('pkg_svc'. $part_svc->svcpart) || 0;
+  my $primary_svc =
+    $cgi->param('pkg_svc_primary') == $part_svc->svcpart ? 'Y' : '';
   my $old_pkg_svc = qsearchs('pkg_svc', {
     'pkgpart' => $pkgpart,
     'svcpart' => $part_svc->svcpart,
   } );
   my $old_quantity = $old_pkg_svc ? $old_pkg_svc->quantity : 0;
-  next unless $old_quantity != $quantity; #!here
+  my $old_primary_svc =
+    ( $old_pkg_svc && $old_pkg_svc->dbdef_table->column('primary_svc') )
+      ? $old_pkg_svc->primary_svc
+      : '';
+  next unless $old_quantity != $quantity || $old_primary_svc ne $primary_svc;
+
   my $new_pkg_svc = new FS::pkg_svc( {
-    'pkgpart'  => $pkgpart,
-    'svcpart'  => $part_svc->svcpart,
-    'quantity' => $quantity, 
+    'pkgpart'     => $pkgpart,
+    'svcpart'     => $part_svc->svcpart,
+    'quantity'    => $quantity, 
+    'primary_svc' => $primary_svc,
   } );
   if ( $old_pkg_svc ) {
     my $myerror = $new_pkg_svc->replace($old_pkg_svc);
index 859670b..9633fab 100755 (executable)
@@ -17,7 +17,7 @@ my $new = new FS::part_svc ( {
             push @fields, 'usergroup' if $svcdb eq 'svc_acct'; #kludge
             map { ( $svcdb.'__'.$_, $svcdb.'__'.$_.'_flag' )  } @fields;
           } grep defined( $FS::Record::dbdef->table($_) ),
-                 qw( svc_acct svc_domain svc_acct_sm svc_forward svc_www )
+                 qw( svc_acct svc_domain svc_forward svc_www svc_broadband )
     )
 } );
 
diff --git a/httemplate/edit/process/router.cgi b/httemplate/edit/process/router.cgi
new file mode 100644 (file)
index 0000000..a2fa46d
--- /dev/null
@@ -0,0 +1,67 @@
+<%
+
+local $FS::UID::AutoCommit=0;
+
+sub check {
+  my $error = shift;
+  if($error) {
+    $cgi->param('error', $error);
+    print $cgi->redirect(popurl(3) . "edit/router.cgi?". $cgi->query_string);
+    dbh->rollback;
+    exit;
+  }
+}
+
+my $error = '';
+my $routernum  = $cgi->param('routernum');
+my $routername = $cgi->param('routername');
+my $old = qsearchs('router', { routernum => $routernum });
+my @old_psr;
+
+my $new = new FS::router {
+  map {
+    ($_, scalar($cgi->param($_)));
+  } fields('router')
+};
+
+if($old) {
+  $error = $new->replace($old);
+} else {
+  $error = $new->insert;
+  $routernum = $new->routernum;
+}
+
+check($error);
+
+if ($old) {
+  @old_psr = $old->part_svc_router;
+  foreach my $psr (@old_psr) {
+    if($cgi->param('svcpart_'.$psr->svcpart) eq 'ON') {
+      # do nothing
+    } else {
+      $error = $psr->delete;
+    }
+  }
+  check($error);
+}
+
+foreach($cgi->param) {
+  if($cgi->param($_) eq 'ON' and /^svcpart_(\d+)$/) {
+    my $svcpart = $1;
+    if(grep {$_->svcpart == $svcpart} @old_psr) {
+      # do nothing
+    } else {
+      my $new_psr = new FS::part_svc_router { svcpart   => $svcpart,
+                                              routernum => $routernum };
+      $error = $new_psr->insert;
+    }
+    check($error);
+  }
+}
+
+
+# Yay, everything worked!
+dbh->commit or die dbh->errstr;
+print $cgi->redirect(popurl(3). "browse/router.cgi");
+
+%>
diff --git a/httemplate/edit/process/svc_acct_sm.cgi b/httemplate/edit/process/svc_acct_sm.cgi
deleted file mode 100755 (executable)
index 41d03fb..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<%
-
-$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!";
-my $svcnum =$1;
-
-my $old = qsearchs('svc_acct_sm',{'svcnum'=>$svcnum}) if $svcnum;
-
-#unmunge domsvc and domuid
-#$cgi->param('domsvc',(split(/:/, $cgi->param('domsvc') ))[0] );
-#$cgi->param('domuid',(split(/:/, $cgi->param('domuid') ))[0] );
-
-my $new = new FS::svc_acct_sm ( {
-  map {
-    ($_, scalar($cgi->param($_)));
-  #} qw(svcnum pkgnum svcpart domuser domuid domsvc)
-  } ( fields('svc_acct_sm'), qw( pkgnum svcpart ) )
-} );
-
-my $error = '';
-if ( $svcnum ) {
-  $error = $new->replace($old);
-} else {
-  $error = $new->insert;
-  $svcnum = $new->getfield('svcnum');
-} 
-
-if ($error) {
-  $cgi->param('error', $error);
-  print $cgi->redirect(popurl(2). "svc_acct_sm.cgi?". $cgi->query_string );
-} else {
-  print $cgi->redirect(popurl(3). "view/svc_acct_sm.cgi?$svcnum");
-}
-
-%>
diff --git a/httemplate/edit/process/svc_broadband.cgi b/httemplate/edit/process/svc_broadband.cgi
new file mode 100644 (file)
index 0000000..4912a3a
--- /dev/null
@@ -0,0 +1,45 @@
+<%
+
+# If it's stupid but it works, it's not stupid.
+# -- U.S. Army
+
+local $FS::UID::AutoCommit = 0;
+my $dbh = FS::UID::dbh;
+
+$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!";
+my $svcnum = $1;
+
+my $old;
+if ( $svcnum ) {
+  $old = qsearchs('svc_broadband', { 'svcnum' => $svcnum } )
+    or die "fatal: can't find broadband service (svcnum $svcnum)!";
+} else {
+  $old = '';
+}
+
+my $new = new FS::svc_broadband ( {
+  map {
+    ($_, scalar($cgi->param($_)));
+  } ( fields('svc_broadband'), qw( pkgnum svcpart ) )
+} );
+
+my $error;
+if ( $svcnum ) {
+  $error = $new->replace($old);
+} else {
+  $error = $new->insert;
+  $svcnum = $new->svcnum;
+}
+
+
+if ( $error ) {
+  $cgi->param('error', $error);
+  $cgi->param('ip_addr', $new->ip_addr);
+  $dbh->rollback;
+  print $cgi->redirect(popurl(2). "svc_broadband.cgi?". $cgi->query_string );
+} else {
+  $dbh->commit or die $dbh->errstr;
+  print $cgi->redirect(popurl(3). "view/svc_broadband.cgi?" . $svcnum );
+}
+
+%>
diff --git a/httemplate/edit/process/svc_external.cgi b/httemplate/edit/process/svc_external.cgi
new file mode 100755 (executable)
index 0000000..728cd21
--- /dev/null
@@ -0,0 +1,29 @@
+<%
+
+$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!";
+my $svcnum =$1;
+
+my $old = qsearchs('svc_external',{'svcnum'=>$svcnum}) if $svcnum;
+
+my $new = new FS::svc_external ( {
+  map {
+    ($_, scalar($cgi->param($_)));
+  } ( fields('svc_external'), qw( pkgnum svcpart ) )
+} );
+
+my $error = '';
+if ( $svcnum ) {
+  $error = $new->replace($old);
+} else {
+  $error = $new->insert;
+  $svcnum = $new->getfield('svcnum');
+} 
+
+if ($error) {
+  $cgi->param('error', $error);
+  print $cgi->redirect(popurl(2). "svc_external.cgi?". $cgi->query_string );
+} else {
+  print $cgi->redirect(popurl(3). "view/svc_external.cgi?$svcnum");
+}
+
+%>
diff --git a/httemplate/edit/router.cgi b/httemplate/edit/router.cgi
new file mode 100755 (executable)
index 0000000..a573c65
--- /dev/null
@@ -0,0 +1,77 @@
+<HTML><BODY>
+
+<%
+
+my $router;
+if ( $cgi->keywords ) {
+  my($query) = $cgi->keywords;
+  $query =~ /^(\d+)$/;
+  $router = qsearchs('router', { routernum => $1 }) 
+      or print $cgi->redirect(popurl(2)."browse/router.cgi") ;
+} else {
+  $router = new FS::router ( {
+    map { $_, scalar($cgi->param($_)) } fields('router')
+  } );
+}
+
+my $routernum = $router->routernum;
+my $action = $routernum ? 'Edit' : 'Add';
+
+print header("$action Router", menubar(
+  'Main Menu' => "$p",
+  'View all routers' => "${p}browse/router.cgi",
+));
+
+my $p3 = popurl(3);
+
+if($cgi->param('error')) {
+%> <FONT SIZE="+1" COLOR="#ff0000">Error: <%=$cgi->param('error')%></FONT>
+<% } %>
+
+<FORM ACTION="<%=popurl(1)%>process/router.cgi" METHOD=POST>
+  <INPUT TYPE="hidden" NAME="table" VALUE="router">
+  <INPUT TYPE="hidden" NAME="redirect_ok" VALUE="<%=$p3%>/browse/router.cgi">
+  <INPUT TYPE="hidden" NAME="redirect_error" VALUE="<%=$p3%>/edit/router.cgi">
+  <INPUT TYPE="hidden" NAME="routernum" VALUE="<%=$routernum%>">
+  <INPUT TYPE="hidden" NAME="svcnum" VALUE="<%=$router->svcnum%>">
+    Router #<%=$routernum or "(NEW)"%>
+
+<BR><BR>Name <INPUT TYPE="text" NAME="routername" SIZE=32 VALUE="<%=$router->routername%>">
+
+<BR><BR>
+Custom fields:
+<BR>
+<%=table() %>
+
+<%
+foreach my $field ($router->virtual_fields) {
+  print $router->pvf($field)->widget('HTML', 'edit', 
+        $router->getfield($field));
+}
+%>
+</TABLE>
+
+
+<%
+unless ($router->svcnum) {
+%>
+<BR><BR>Select the service types available on this router<BR>
+<%
+
+  foreach my $part_svc ( qsearch('part_svc', { svcdb    => 'svc_broadband',
+                                               disabled => '' }) ) {
+  %>
+  <BR>
+  <INPUT TYPE="checkbox" NAME="svcpart_<%=$part_svc->svcpart%>"<%=
+      qsearchs('part_svc_router', { svcpart   => $part_svc->svcpart, 
+                                    routernum => $routernum } ) ? ' CHECKED' : ''%> VALUE="ON">
+  <A HREF="<%=${p}%>edit/part_svc.cgi?<%=$part_svc->svcpart%>">
+    <%=$part_svc->svcpart%>: <%=$part_svc->svc%></A>
+  <% } %>
+
+<% } %>
+
+  <BR><BR><INPUT TYPE="submit" VALUE="Apply changes">
+  </FORM>
+</BODY></HTML>
+
index 90b2632..f1b8b80 100755 (executable)
@@ -35,8 +35,6 @@ if ( $cgi->param('error') ) {
 
   } else { #adding
 
-    $svc_acct = new FS::svc_acct({}); 
-
     foreach $_ (split(/-/,$query)) {
       $pkgnum=$1 if /^pkgnum(\d+)$/;
       $svcpart=$1 if /^svcpart(\d+)$/;
@@ -44,6 +42,8 @@ if ( $cgi->param('error') ) {
     $part_svc = qsearchs( 'part_svc', { 'svcpart' => $svcpart } );
     die "No part_svc entry for svcpart $svcpart!" unless $part_svc;
 
+    $svc_acct = new FS::svc_acct({svcpart => $svcpart}); 
+
     $svcnum='';
 
     #set gecos
@@ -72,6 +72,12 @@ if ( $cgi->param('error') ) {
 
   }
 }
+
+#fixed radius groups always override & display
+if ( $part_svc->part_svc_column('usergroup')->columnflag eq "F" ) {
+  @groups = split(',', $part_svc->part_svc_column('usergroup')->columnvalue);
+}
+
 my $action = $svcnum ? 'Edit' : 'Add';
 
 my $svc = $part_svc->getfield('svc');
@@ -163,7 +169,7 @@ if ( $part_svc->part_svc_column('domsvc')->columnflag eq 'F' ) {
   }
 
   my $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $pkgnum } );
-  if ($cust_pkg) {
+  if ($cust_pkg && !$conf->exists('svc_acct-alldomains') ) {
     my @cust_svc =
       map { qsearch('cust_svc', { 'pkgnum' => $_->pkgnum } ) }
           qsearch('cust_pkg', { 'custnum' => $cust_pkg->custnum } );
@@ -238,7 +244,16 @@ my($quota,$slipip)=(
   $svc_acct->slipip,
 );
 
-print qq!<INPUT TYPE="hidden" NAME="quota" VALUE="$quota">!;
+if ( $part_svc->part_svc_column('quota')->columnflag eq "F" )
+{
+  print qq!<INPUT TYPE="hidden" NAME="quota" VALUE="$quota">!;
+} else {
+  print <<END;
+    <TR><TD ALIGN="right">Quota:</TD>
+        <TD> <INPUT TYPE="text" NAME="quota" VALUE="$quota" ></TD>
+    </TR>
+END
+}
 
 if ( $part_svc->part_svc_column('slipip')->columnflag eq "F" ) {
   print qq!<INPUT TYPE="hidden" NAME="slipip" VALUE="$slipip">!;
@@ -266,6 +281,14 @@ if ( $part_svc->part_svc_column('usergroup')->columnflag eq "F" ) {
 }
 print '</TD></TR>';
 
+foreach my $field ($svc_acct->virtual_fields) {
+  if ( $part_svc->part_svc_column($field)->columnflag ne 'F' ) {
+    # If the flag is X, it won't even show up in $svc_acct->virtual_fields.
+    print $svc_acct->pvf($field)->widget('HTML', 'edit', 
+        $svc_acct->getfield($field));
+  }
+}
+  
 #submit
 print qq!</TABLE><BR><INPUT TYPE="submit" VALUE="Submit">!; 
 
diff --git a/httemplate/edit/svc_acct_sm.cgi b/httemplate/edit/svc_acct_sm.cgi
deleted file mode 100755 (executable)
index 0fd5f76..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-<!-- mason kludge -->
-<%
-
-my $conf = new FS::Conf;
-my $mydomain = $conf->config('domain');
-
-my($svcnum, $pkgnum, $svcpart, $part_svc, $svc_acct_sm );
-if ( $cgi->param('error') ) {
-  $svc_acct_sm = new FS::svc_acct_sm ( {
-    map { $_, scalar($cgi->param($_)) } fields('svc_acct_sm')
-  } );
-  $svcnum = $svc_acct_sm->svcnum;
-  $pkgnum = $cgi->param('pkgnum');
-  $svcpart = $cgi->param('svcpart');
-  #$part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
-  #die "No part_svc entry!" unless $part_svc;
-} else {
-  my($query) = $cgi->keywords;
-  if ( $query =~ /^(\d+)$/ ) { #editing
-    $svcnum=$1;
-    $svc_acct_sm=qsearchs('svc_acct_sm',{'svcnum'=>$svcnum})
-      or die "Unknown (svc_acct_sm) svcnum!";
-
-    my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
-      or die "Unknown (cust_svc) svcnum!";
-
-    $pkgnum=$cust_svc->pkgnum;
-    $svcpart=$cust_svc->svcpart;
-  
-    #$part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
-    #die "No part_svc entry!" unless $part_svc;
-
-  } else { #adding
-
-    $svc_acct_sm = new FS::svc_acct_sm({});
-
-    foreach $_ (split(/-/,$query)) { #get & untaint pkgnum & svcpart
-      $pkgnum=$1 if /^pkgnum(\d+)$/;
-      $svcpart=$1 if /^svcpart(\d+)$/;
-    }
-    my $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
-    die "No part_svc entry!" unless $part_svc;
-
-    $svcnum='';
-
-    #set fixed and default fields from part_svc
-    foreach my $part_svc_column (
-      grep { $_->columnflag } $part_svc->all_part_svc_column
-    ) {
-      $svc_acct_sm->setfield( $part_svc_column->columnname,
-                              $part_svc_column->columnvalue,
-                            );
-    }
-
-  }
-}
-my $action = $svc_acct_sm->svcnum ? 'Edit' : 'Add';
-
-my %username = ();
-my %domain = ();
-if ($pkgnum) {
-
-  #find all possible uids (and usernames)
-
-  my @u_acct_svcparts = ();
-  foreach my $u_part_svc ( qsearch('part_svc',{'svcdb'=>'svc_acct'}) ) {
-    push @u_acct_svcparts,$u_part_svc->getfield('svcpart');
-  }
-
-  my($cust_pkg)=qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
-  my($custnum)=$cust_pkg->getfield('custnum');
-  foreach my $i_cust_pkg ( qsearch('cust_pkg',{'custnum'=>$custnum}) ) {
-    my($cust_pkgnum)=$i_cust_pkg->getfield('pkgnum');
-    my($acct_svcpart);
-    foreach $acct_svcpart (@u_acct_svcparts) {   #now find the corresponding 
-                                              #record(s) in cust_svc ( for this
-                                              #pkgnum ! )
-      my($i_cust_svc);
-      foreach $i_cust_svc ( qsearch('cust_svc',{'pkgnum'=>$cust_pkgnum,'svcpart'=>$acct_svcpart}) ) {
-        my($svc_acct)=qsearchs('svc_acct',{'svcnum'=>$i_cust_svc->getfield('svcnum')});
-        $username{$svc_acct->getfield('uid')}=$svc_acct->getfield('username');
-      }  
-    }
-  }
-
-  #find all possible domains (and domsvc's)
-
-  my @d_acct_svcparts = ();
-  foreach my $d_part_svc ( qsearch('part_svc',{'svcdb'=>'svc_domain'}) ) {
-    push @d_acct_svcparts,$d_part_svc->getfield('svcpart');
-  }
-
-  foreach $i_cust_pkg ( qsearch('cust_pkg',{'custnum'=>$custnum}) ) {
-    my($cust_pkgnum)=$i_cust_pkg->getfield('pkgnum');
-    my($acct_svcpart);
-    foreach $acct_svcpart (@d_acct_svcparts) {
-      my($i_cust_svc);
-      foreach $i_cust_svc ( qsearch('cust_svc',{'pkgnum'=>$cust_pkgnum,'svcpart'=>$acct_svcpart}) ) {
-        my($svc_domain)=qsearch('svc_domain',{'svcnum'=>$i_cust_svc->getfield('svcnum')});
-        $domain{$svc_domain->getfield('svcnum')}=$svc_domain->getfield('domain');
-      }
-    }
-  }
-
-} elsif ( $action eq 'Edit' ) {
-
-  my($svc_acct)=qsearchs('svc_acct',{'uid'=>$svc_acct_sm->domuid});
-  $username{$svc_acct_sm->uid} = $svc_acct->username;
-
-  my($svc_domain)=qsearchs('svc_domain',{'svcnum'=>$svc_acct_sm->domsvc});
-  $domain{$svc_acct_sm->domsvc} = $svc_domain->domain;
-
-} else {
-  die "\$action eq Add, but \$pkgnum is null!\n";
-}
-
-my $p1 = popurl(1);
-print header("Mail Alias $action", '');
-
-print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'),
-      "</FONT>"
-  if $cgi->param('error');
-
-print qq!<FORM ACTION="${p1}process/svc_acct_sm.cgi" METHOD=POST>!;
-
-#display
-
-       #formatting
-       print "<PRE>";
-
-#svcnum
-print qq!<INPUT TYPE="hidden" NAME="svcnum" VALUE="$svcnum">!;
-print qq!Service #<FONT SIZE=+1><B>!, $svcnum ? $svcnum : " (NEW)", "</B></FONT>";
-
-#pkgnum
-print qq!<INPUT TYPE="hidden" NAME="pkgnum" VALUE="$pkgnum">!;
-#svcpart
-print qq!<INPUT TYPE="hidden" NAME="svcpart" VALUE="$svcpart">!;
-
-my($domuser,$domsvc,$domuid)=(
-  $svc_acct_sm->domuser,
-  $svc_acct_sm->domsvc,
-  $svc_acct_sm->domuid,
-);
-
-#domuser
-print qq!\n\nMail to <INPUT TYPE="text" NAME="domuser" VALUE="$domuser"> <I>( * for anything )</I>!;
-
-#domsvc
-print qq! \@ <SELECT NAME="domsvc" SIZE=1>!;
-foreach $_ (keys %domain) {
-  print "<OPTION", $_ eq $domsvc ? " SELECTED" : "",
-        qq! VALUE="$_">$domain{$_}!;
-}
-print "</SELECT>";
-
-#uid
-print qq!\nforwards to <SELECT NAME="domuid" SIZE=1>!;
-foreach $_ (keys %username) {
-  print "<OPTION", ($_ eq $domuid) ? " SELECTED" : "",
-        qq! VALUE="$_">$username{$_}!;
-}
-print "</SELECT>\@$mydomain mailbox.";
-
-       #formatting
-       print "</PRE>\n";
-
-print qq!<CENTER><INPUT TYPE="submit" VALUE="Submit"></CENTER>!;
-
-print <<END;
-
-    </FORM>
-  </BODY>
-</HTML>
-END
-
-%>
diff --git a/httemplate/edit/svc_broadband.cgi b/httemplate/edit/svc_broadband.cgi
new file mode 100644 (file)
index 0000000..db27b32
--- /dev/null
@@ -0,0 +1,172 @@
+<!-- mason kludge -->
+<%
+
+# If it's stupid but it works, it's still stupid.
+#  -Kristian
+
+
+use HTML::Widgets::SelectLayers;
+use Tie::IxHash;
+
+my( $svcnum,  $pkgnum, $svcpart, $part_svc, $svc_broadband );
+if ( $cgi->param('error') ) {
+  $svc_broadband = new FS::svc_broadband ( {
+    map { $_, scalar($cgi->param($_)) } fields('svc_broadband')
+  } );
+  $svcnum = $svc_broadband->svcnum;
+  $pkgnum = $cgi->param('pkgnum');
+  $svcpart = $cgi->param('svcpart');
+  $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+  die "No part_svc entry!" unless $part_svc;
+} else {
+  my($query) = $cgi->keywords;
+  if ( $query =~ /^(\d+)$/ ) { #editing
+    $svcnum=$1;
+    $svc_broadband=qsearchs('svc_broadband',{'svcnum'=>$svcnum})
+      or die "Unknown (svc_broadband) svcnum!";
+
+    my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
+      or die "Unknown (cust_svc) svcnum!";
+
+    $pkgnum=$cust_svc->pkgnum;
+    $svcpart=$cust_svc->svcpart;
+  
+    $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+    die "No part_svc entry!" unless $part_svc;
+
+  } else { #adding
+
+    foreach $_ (split(/-/,$query)) { #get & untaint pkgnum & svcpart
+      $pkgnum=$1 if /^pkgnum(\d+)$/;
+      $svcpart=$1 if /^svcpart(\d+)$/;
+    }
+    $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+    die "No part_svc entry!" unless $part_svc;
+
+    $svc_broadband = new FS::svc_broadband({ svcpart => $svcpart });
+
+    $svcnum='';
+
+    #set fixed and default fields from part_svc
+    foreach my $part_svc_column (
+      grep { $_->columnflag } $part_svc->all_part_svc_column
+    ) {
+      $svc_broadband->setfield( $part_svc_column->columnname,
+                                $part_svc_column->columnvalue,
+                              );
+    }
+
+  }
+}
+my $action = $svc_broadband->svcnum ? 'Edit' : 'Add';
+
+if ($pkgnum) {
+
+  #Nothing?
+
+} elsif ( $action eq 'Edit' ) {
+
+  #Nothing?
+
+} else {
+  die "\$action eq Add, but \$pkgnum is null!\n";
+}
+
+my $p1 = popurl(1);
+
+my ($ip_addr, $speed_up, $speed_down, $blocknum) =
+    ($svc_broadband->ip_addr,
+     $svc_broadband->speed_up,
+     $svc_broadband->speed_down,
+     $svc_broadband->blocknum);
+
+%>
+
+<%=header("Broadband Service $action", '')%>
+
+<% if ($cgi->param('error')) { %>
+<FONT SIZE="+1" COLOR="#ff0000">Error: <%=$cgi->param('error')%></FONT><BR>
+<% } %>
+
+Service #<B><%=$svcnum ? $svcnum : "(NEW)"%></B><BR><BR>
+
+<FORM ACTION="<%=${p1}%>process/svc_broadband.cgi" METHOD=POST>
+  <INPUT TYPE="hidden" NAME="svcnum" VALUE="<%=$svcnum%>">
+  <INPUT TYPE="hidden" NAME="pkgnum" VALUE="<%=$pkgnum%>">
+  <INPUT TYPE="hidden" NAME="svcpart" VALUE="<%=$svcpart%>">
+
+  <%=&ntable("#cccccc",2)%>
+    <TR>
+      <TD ALIGN="right">IP Address</TD>
+      <TD BGCOLOR="#ffffff">
+<% if ( $part_svc->part_svc_column('ip_addr')->columnflag eq 'F' ) { %>
+        <INPUT TYPE="hidden" NAME="ip_addr" VALUE="<%=$ip_addr%>"><%=$ip_addr%>
+<% } else { %>
+        <INPUT TYPE="text" NAME="ip_addr" VALUE="<%=$ip_addr%>">
+<% } %>
+      </TD>
+    </TR>
+    <TR>
+      <TD ALIGN="right">Download speed</TD>
+      <TD BGCOLOR="#ffffff">
+<% if ( $part_svc->part_svc_column('speed_down')->columnflag eq 'F' ) { %>
+        <INPUT TYPE="hidden" NAME="speed_down" VALUE="<%=$speed_down%>"><%=$speed_down%>Kbps
+<% } else { %>
+    <INPUT TYPE="text" NAME="speed_down" SIZE=5 VALUE="<%=$speed_down%>">Kbps
+<% } %>
+      </TD>
+    </TR>
+    <TR>
+      <TD ALIGN="right">Upload speed</TD>
+      <TD BGCOLOR="#ffffff">
+<% if ( $part_svc->part_svc_column('speed_up')->columnflag eq 'F' ) { %>
+        <INPUT TYPE="hidden" NAME="speed_up" VALUE="<%=$speed_up%>"><%=$speed_up%>Kbps
+<% } else { %>
+        <INPUT TYPE="text" NAME="speed_up" SIZE=5 VALUE="<%=$speed_up%>">Kbps
+<% } %>
+      </TD>
+    </TR>
+<% if ($action eq 'Add') { %>
+    <TR>
+      <TD ALIGN="right">Router/Block</TD>
+      <TD BGCOLOR="#ffffff">
+        <SELECT NAME="blocknum">
+<%
+  foreach my $router ($svc_broadband->allowed_routers) {
+    foreach my $addr_block ($router->addr_block) {
+%>
+        <OPTION VALUE="<%=$addr_block->blocknum%>"<%=($addr_block->blocknum eq $blocknum) ? ' SELECTED' : ''%>>
+          <%=$router->routername%>:<%=$addr_block->ip_gateway%>/<%=$addr_block->ip_netmask%></OPTION>
+<%
+    }
+  }
+%>
+        </SELECT>
+      </TD>
+    </TR>
+<% } else { %>
+
+    <TR>
+      <TD ALIGN="right">Router/Block</TD>
+      <TD BGCOLOR="#ffffff">
+        <%=$svc_broadband->addr_block->router->routername%>:<%=$svc_broadband->addr_block->NetAddr%>
+        <INPUT TYPE="hidden" NAME="blocknum" VALUE="<%=$svc_broadband->blocknum%>">
+      </TD>
+    </TR>
+
+<% } %>
+
+<%
+foreach my $field ($svc_broadband->virtual_fields) {
+  if ( $part_svc->part_svc_column($field)->columnflag ne 'F' ) {
+    print $svc_broadband->pvf($field)->widget('HTML', 'edit',
+        $svc_broadband->getfield($field));
+  }
+} %>
+  </TABLE>
+  <BR>
+  <INPUT TYPE="submit" NAME="submit" VALUE="Submit">
+</FORM>
+</BODY>
+</HTML>
+
index d20e1f3..ca0e339 100755 (executable)
@@ -87,7 +87,7 @@ print ' CHECKED' if $kludge_action eq 'M';
 print qq!>Transfer!;
 
 print <<END;
-<P>Domain <INPUT TYPE="text" NAME="domain" VALUE="$domain" SIZE=28 MAXLENGTH=26>
+<P>Domain <INPUT TYPE="text" NAME="domain" VALUE="$domain" SIZE=28 MAXLENGTH=63>
 <BR>Purpose/Description: <INPUT TYPE="text" NAME="purpose" VALUE="$purpose" SIZE=64>
 <P><INPUT TYPE="submit" VALUE="Submit">
     </FORM>
diff --git a/httemplate/edit/svc_external.cgi b/httemplate/edit/svc_external.cgi
new file mode 100644 (file)
index 0000000..bcfc85e
--- /dev/null
@@ -0,0 +1,105 @@
+<!-- mason kludge -->
+<%
+
+my( $svcnum,  $pkgnum, $svcpart, $part_svc, $svc_external );
+if ( $cgi->param('error') ) {
+  $svc_external = new FS::svc_external ( {
+    map { $_, scalar($cgi->param($_)) } fields('svc_external')
+  } );
+  $svcnum = $svc_external->svcnum;
+  $pkgnum = $cgi->param('pkgnum');
+  $svcpart = $cgi->param('svcpart');
+  $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+  die "No part_svc entry!" unless $part_svc;
+} else {
+  my($query) = $cgi->keywords;
+  if ( $query =~ /^(\d+)$/ ) { #editing
+    $svcnum=$1;
+    $svc_external=qsearchs('svc_external',{'svcnum'=>$svcnum})
+      or die "Unknown (svc_external) svcnum!";
+
+    my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
+      or die "Unknown (cust_svc) svcnum!";
+
+    $pkgnum=$cust_svc->pkgnum;
+    $svcpart=$cust_svc->svcpart;
+  
+    $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+    die "No part_svc entry!" unless $part_svc;
+
+  } else { #adding
+
+    foreach $_ (split(/-/,$query)) { #get & untaint pkgnum & svcpart
+      $pkgnum=$1 if /^pkgnum(\d+)$/;
+      $svcpart=$1 if /^svcpart(\d+)$/;
+    }
+    $svc_external = new FS::svc_external { svcpart => $svcpart };
+
+    $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+    die "No part_svc entry!" unless $part_svc;
+
+    $svcnum='';
+
+    #set fixed and default fields from part_svc
+    foreach my $part_svc_column (
+      grep { $_->columnflag } $part_svc->all_part_svc_column
+    ) {
+      $svc_external->setfield( $part_svc_column->columnname,
+                               $part_svc_column->columnvalue,
+                             );
+    }
+
+  }
+}
+my $action = $svc_external->svcnum ? 'Edit' : 'Add';
+
+my $p1 = popurl(1);
+print header("External service $action", '');
+
+print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'),
+      "</FONT>"
+  if $cgi->param('error');
+
+print qq!<FORM ACTION="${p1}process/svc_external.cgi" METHOD=POST>!;
+
+#display
+
+#svcnum
+print qq!<INPUT TYPE="hidden" NAME="svcnum" VALUE="$svcnum">!;
+print qq!Service #<B>!, $svcnum ? $svcnum : "(NEW)", "</B><BR><BR>";
+
+#pkgnum
+print qq!<INPUT TYPE="hidden" NAME="pkgnum" VALUE="$pkgnum">!;
+#svcpart
+print qq!<INPUT TYPE="hidden" NAME="svcpart" VALUE="$svcpart">!;
+
+my($id,$title)=(
+  $svc_external->id,
+  $svc_external->title,
+);
+
+print &ntable("#cccccc",2),
+      '<TR><TD ALIGN="right">External ID</TD><TD>'.
+      qq!<INPUT TYPE="text" NAME="id" VALUE="$id">!.
+      '</TD></TR>'.
+      '<TR><TD ALIGN="right">Title</TD><TD>'.
+      qq!<INPUT TYPE="text" NAME="title" VALUE="$title">!.
+      '</TD></TR>';
+
+foreach my $field ($svc_external->virtual_fields) {
+  if ( $part_svc->part_svc_column($field)->columnflag ne 'F' ) {
+    # If the flag is X, it won't even show up in $svc_acct->virtual_fields.
+    print $svc_external->pvf($field)->widget('HTML', 'edit', 
+        $svc_external->getfield($field));
+  }
+}
+
+%>
+
+</TABLE><BR><INPUT TYPE="submit" VALUE="Submit">
+    </FORM>
+  </BODY>
+</HTML>
+
index bc19fe1..2e6c5f1 100755 (executable)
@@ -2,7 +2,6 @@
 <%
 
 my $conf = new FS::Conf;
-my $mydomain = $conf->config('domain');
 
 my($svcnum, $pkgnum, $svcpart, $part_svc, $svc_forward);
 if ( $cgi->param('error') ) {
@@ -59,20 +58,17 @@ if ( $cgi->param('error') ) {
 my $action = $svc_forward->svcnum ? 'Edit' : 'Add';
 
 my %email;
+
+#starting with those currently attached
+foreach my $method (qw( srcsvc_acct dstsvc_acct )) {
+  my $svc_acct = $svc_forward->$method();
+  $email{$svc_acct->svcnum} = $svc_acct->email if $svc_acct;
+}
+
 if ($pkgnum) {
 
   #find all possible user svcnums (and emails)
 
-  #starting with those currently attached
-  if ( $svc_forward->srcsvc ) {
-    my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $svc_forward->srcsvc } );
-    $email{$svc_forward->srcsvc} = $svc_acct->email;
-  }
-  if ( $svc_forward->dstsvc ) {
-    my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $svc_forward->dstsvc } );
-    $email{$svc_forward->dstsvc} = $svc_acct->email;
-  }
-
   #and including the rest for this customer
   my($u_part_svc,@u_acct_svcparts);
   foreach $u_part_svc ( qsearch('part_svc',{'svcdb'=>'svc_acct'}) ) {
@@ -99,15 +95,7 @@ if ($pkgnum) {
     }
   }
 
-} elsif ( $action eq 'Edit' ) {
-
-  my($svc_acct)=qsearchs('svc_acct',{'svcnum'=>$svc_forward->srcsvc});
-  $email{$svc_forward->srcsvc} = $svc_acct->email;
-
-  $svc_acct=qsearchs('svc_acct',{'svcnum'=>$svc_forward->dstsvc});
-  $email{$svc_forward->dstsvc} = $svc_acct->email;
-
-} else {
+} elsif ( $action eq 'Add' ) {
   die "\$action eq Add, but \$pkgnum is null!\n";
 }
 
@@ -116,6 +104,7 @@ my($srcsvc,$dstsvc,$dst)=(
   $svc_forward->dstsvc,
   $svc_forward->dst,
 );
+my $src = $svc_forward->dbdef_table->column('src') ? $svc_forward->src : '';
 
 #display
 
@@ -131,46 +120,54 @@ my($srcsvc,$dstsvc,$dst)=(
 Service #<%= $svcnum ? "<B>$svcnum</B>" : " (NEW)" %><BR>
 Service: <B><%= $part_svc->svc %></B><BR><BR>
 
-<FORM NAME="dummy">
+<FORM ACTION="process/svc_forward.cgi" METHOD="POST">
+<INPUT TYPE="hidden" NAME="svcnum" VALUE="<%= $svcnum %>">
+<INPUT TYPE="hidden" NAME="pkgnum" VALUE="<%= $pkgnum %>">
+<INPUT TYPE="hidden" NAME="svcpart" VALUE="<%= $svcpart %>">
+
+<SCRIPT TYPE="text/javascript">
+function srcchanged(what) {
+  if ( what.options[what.selectedIndex].value == 0 ) {
+    what.form.src.disabled = false;
+  } else {
+    what.form.src.disabled = true;
+  }
+}
+function dstchanged(what) {
+  if ( what.options[what.selectedIndex].value == 0 ) {
+    what.form.dst.disabled = false;
+  } else {
+    what.form.dst.disabled = true;
+  }
+}
+</SCRIPT>
 
 <%= ntable("#cccccc",2) %>
-<TR><TD ALIGN="right">Email to</TD><TD><SELECT NAME="srcsvc" SIZE=1>
+<TR><TD ALIGN="right">Email to</TD>
+<TD><SELECT NAME="srcsvc" SIZE=1 onChange="srcchanged(this)">
 <% foreach $_ (keys %email) { %>
   <OPTION<%= $_ eq $srcsvc ? " SELECTED" : "" %> VALUE="<%= $_ %>"><%= $email{$_} %></OPTION>
 <% } %>
-</SELECT></TD></TR>
-
-<%
-  tie my %tied_email, 'Tie::IxHash',
-    ''  => 'SELECT DESTINATION',
-    %email,
-    '0' => '(other email address)';
-  my $widget = new HTML::Widgets::SelectLayers(
-    'selected_layer' => $dstsvc,
-    'options'        => \%tied_email,
-    'form_name'      => 'dummy',
-    'form_action'    => 'process/svc_forward.cgi',
-    'form_select'    => ['srcsvc'],
-    'html_between'   => '</TD></TR></TABLE>',
-    'layer_callback' => sub {
-      my $layer = shift;
-      my $html = qq!<INPUT TYPE="hidden" NAME="svcnum" VALUE="$svcnum">!.
-                 qq!<INPUT TYPE="hidden" NAME="pkgnum" VALUE="$pkgnum">!.
-                 qq!<INPUT TYPE="hidden" NAME="svcpart" VALUE="$svcpart">!.
-                 qq!<INPUT TYPE="hidden" NAME="dstsvc" VALUE="$layer">!;
-      if ( $layer eq '0' ) {
-        $html .= ntable("#cccccc",2).
-                 '<TR><TD ALIGN="right">Destination email</TD>'.
-                 qq!<TD><INPUT TYPE="text" NAME="dst" VALUE="$dst"></TD>!.
-                 '</TR></TABLE>';
-      }
-      $html .= '<BR><INPUT TYPE="submit" VALUE="Submit">';
-      $html;
-    },
-  );
-%>
+<% if ( $svc_forward->dbdef_table->column('src') ) { %>
+  <OPTION <%= $src ? 'SELECTED' : '' %> VALUE="0">(other email address)</OPTION>
+<% } %>
+</SELECT>
+<% if ( $svc_forward->dbdef_table->column('src') ) { %>
+<INPUT TYPE="text" NAME="src" VALUE="<%= $src %>" <%= ( $src || !scalar(%email) ) ? '' : 'DISABLED' %>>
+<% } %>
+</TD></TR>
 
 <TR><TD ALIGN="right">Forwards to</TD>
-<TD><%= $widget->html %>
+<TD><SELECT NAME="dstsvc" SIZE=1 onChange="dstchanged(this)">
+<% foreach $_ (keys %email) { %>
+  <OPTION<%= $_ eq $dstsvc ? " SELECTED" : "" %> VALUE="<%= $_ %>"><%= $email{$_} %></OPTION>
+<% } %>
+<OPTION <%= $dst ? 'SELECTED' : '' %> VALUE="0">(other email address)</OPTION>
+</SELECT>
+<INPUT TYPE="text" NAME="dst" VALUE="<%= $dst %>" <%= ( $dst || !scalar(%email) ) ? '' : 'DISABLED' %>>
+</TD></TR>
+    </TABLE>
+<BR><INPUT TYPE="submit" VALUE="Submit">
+</FORM>
   </BODY>
 </HTML>
index d2c9ade..ec5169e 100644 (file)
@@ -29,12 +29,12 @@ if ( $cgi->param('error') ) {
 
   } else { #adding
 
-    $svc_www = new FS::svc_www({});
-
     foreach $_ (split(/-/,$query)) { #get & untaint pkgnum & svcpart
       $pkgnum=$1 if /^pkgnum(\d+)$/;
       $svcpart=$1 if /^svcpart(\d+)$/;
     }
+    $svc_www = new FS::svc_www { svcpart => $svcpart };
+
     $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
     die "No part_svc entry!" unless $part_svc;
 
@@ -167,6 +167,14 @@ foreach $_ (keys %username) {
 }
 print "</SELECT></TD></TR>";
 
+foreach my $field ($svc_www->virtual_fields) {
+  if ( $part_svc->part_svc_column($field)->columnflag ne 'F' ) {
+    # If the flag is X, it won't even show up in $svc_acct->virtual_fields.
+    print $svc_www->pvf($field)->widget('HTML', 'edit', 
+        $svc_www->getfield($field));
+  }
+}
+
 print '</TABLE><BR><INPUT TYPE="submit" VALUE="Submit">';
 
 print <<END;
diff --git a/httemplate/elements/calendar-en.js b/httemplate/elements/calendar-en.js
new file mode 100644 (file)
index 0000000..e9291e1
--- /dev/null
@@ -0,0 +1,114 @@
+// ** I18N
+
+// Calendar EN language
+// Author: Mihai Bazon, <mishoo@infoiasi.ro>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible.  We strongly believe that
+// Unicode is the answer to a real internationalized world.  Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+ "Sunday");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary.  We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+//   Calendar._SDN_len = N; // short day name length
+//   Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat",
+ "Sun");
+
+// full month names
+Calendar._MN = new Array
+("January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December");
+
+// short month names
+Calendar._SMN = new Array
+("Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "About the calendar";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2003\n" + // don't translate this this ;-)
+"For latest version visit: http://dynarch.com/mishoo/calendar.epl\n" +
+"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Date selection:\n" +
+"- Use the \xab, \xbb buttons to select year\n" +
+"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
+"- Hold mouse button on any of the above buttons for faster selection.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Time selection:\n" +
+"- Click on any of the time parts to increase it\n" +
+"- or Shift-click to decrease it\n" +
+"- or click and drag for faster selection.";
+
+Calendar._TT["PREV_YEAR"] = "Prev. year (hold for menu)";
+Calendar._TT["PREV_MONTH"] = "Prev. month (hold for menu)";
+Calendar._TT["GO_TODAY"] = "Go Today";
+Calendar._TT["NEXT_MONTH"] = "Next month (hold for menu)";
+Calendar._TT["NEXT_YEAR"] = "Next year (hold for menu)";
+Calendar._TT["SEL_DATE"] = "Select date";
+Calendar._TT["DRAG_TO_MOVE"] = "Drag to move";
+Calendar._TT["PART_TODAY"] = " (today)";
+Calendar._TT["MON_FIRST"] = "Display Monday first";
+Calendar._TT["SUN_FIRST"] = "Display Sunday first";
+Calendar._TT["CLOSE"] = "Close";
+Calendar._TT["TODAY"] = "Today";
+Calendar._TT["TIME_PART"] = "(Shift-)Click or drag to change value";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "wk";
diff --git a/httemplate/elements/calendar-setup.js b/httemplate/elements/calendar-setup.js
new file mode 100644 (file)
index 0000000..0dc3caa
--- /dev/null
@@ -0,0 +1,163 @@
+/*  Copyright Mihai Bazon, 2002, 2003  |  http://dynarch.com/mishoo/
+ * ---------------------------------------------------------------------------
+ *
+ * The DHTML Calendar
+ *
+ * Details and latest version at:
+ * http://dynarch.com/mishoo/calendar.epl
+ *
+ * This script is distributed under the GNU Lesser General Public License.
+ * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
+ *
+ * This file defines helper functions for setting up the calendar.  They are
+ * intended to help non-programmers get a working calendar on their site
+ * quickly.  This script should not be seen as part of the calendar.  It just
+ * shows you what one can do with the calendar, while in the same time
+ * providing a quick and simple method for setting it up.  If you need
+ * exhaustive customization of the calendar creation process feel free to
+ * modify this code to suit your needs (this is recommended and much better
+ * than modifying calendar.js itself).
+ */
+
+// $Id: calendar-setup.js,v 1.3 2003-11-07 10:53:35 ivan Exp $
+
+/**
+ *  This function "patches" an input field (or other element) to use a calendar
+ *  widget for date selection.
+ *
+ *  The "params" is a single object that can have the following properties:
+ *
+ *    prop. name   | description
+ *  -------------------------------------------------------------------------------------------------
+ *   inputField    | the ID of an input field to store the date
+ *   displayArea   | the ID of a DIV or other element to show the date
+ *   button        | ID of a button or other element that will trigger the calendar
+ *   eventName     | event that will trigger the calendar, without the "on" prefix (default: "click")
+ *   ifFormat      | date format that will be stored in the input field
+ *   daFormat      | the date format that will be used to display the date in displayArea
+ *   singleClick   | (true/false) wether the calendar is in single click mode or not (default: true)
+ *   mondayFirst   | (true/false) if true Monday is the first day of week, Sunday otherwise (default: true)
+ *   align         | alignment (default: "Bl"); if you don't know what's this see the calendar documentation
+ *   range         | array with 2 elements.  Default: [1900, 2999] -- the range of years available
+ *   weekNumbers   | (true/false) if it's true (default) the calendar will display week numbers
+ *   flat          | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID
+ *   flatCallback  | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar)
+ *   disableFunc   | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
+ *   onSelect      | function that gets called when a date is selected.  You don't _have_ to supply this (the default is generally okay)
+ *   onClose       | function that gets called when the calendar is closed.  [default]
+ *   onUpdate      | function that gets called after the date is updated in the input field.  Receives a reference to the calendar.
+ *   date          | the date that the calendar will be initially displayed to
+ *   showsTime     | default: false; if true the calendar will include a time selector
+ *   timeFormat    | the time format; can be "12" or "24", default is "12"
+ *
+ *  None of them is required, they all have default values.  However, if you
+ *  pass none of "inputField", "displayArea" or "button" you'll get a warning
+ *  saying "nothing to setup".
+ */
+Calendar.setup = function (params) {
+       function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };
+
+       param_default("inputField",     null);
+       param_default("displayArea",    null);
+       param_default("button",         null);
+       param_default("eventName",      "click");
+       param_default("ifFormat",       "%Y/%m/%d");
+       param_default("daFormat",       "%Y/%m/%d");
+       param_default("singleClick",    true);
+       param_default("disableFunc",    null);
+       param_default("dateStatusFunc", params["disableFunc"]); // takes precedence if both are defined
+       param_default("mondayFirst",    true);
+       param_default("align",          "Bl");
+       param_default("range",          [1900, 2999]);
+       param_default("weekNumbers",    true);
+       param_default("flat",           null);
+       param_default("flatCallback",   null);
+       param_default("onSelect",       null);
+       param_default("onClose",        null);
+       param_default("onUpdate",       null);
+       param_default("date",           null);
+       param_default("showsTime",      false);
+       param_default("timeFormat",     "24");
+
+       var tmp = ["inputField", "displayArea", "button"];
+       for (var i in tmp) {
+               if (typeof params[tmp[i]] == "string") {
+                       params[tmp[i]] = document.getElementById(params[tmp[i]]);
+               }
+       }
+       if (!(params.flat || params.inputField || params.displayArea || params.button)) {
+               alert("Calendar.setup:\n  Nothing to setup (no fields found).  Please check your code");
+               return false;
+       }
+
+       function onSelect(cal) {
+               if (cal.params.flat) {
+                       if (typeof cal.params.flatCallback == "function") {
+                               cal.params.flatCallback(cal);
+                       } else {
+                               alert("No flatCallback given -- doing nothing.");
+                       }
+                       return false;
+               }
+               if (cal.params.inputField) {
+                       cal.params.inputField.value = cal.date.print(cal.params.ifFormat);
+               }
+               if (cal.params.displayArea) {
+                       cal.params.displayArea.innerHTML = cal.date.print(cal.params.daFormat);
+               }
+               if (cal.params.singleClick && cal.dateClicked) {
+                       cal.callCloseHandler();
+               }
+               if (typeof cal.params.onUpdate == "function") {
+                       cal.params.onUpdate(cal);
+               }
+       };
+
+       if (params.flat != null) {
+               params.flat = document.getElementById(params.flat);
+               if (!params.flat) {
+                       alert("Calendar.setup:\n  Flat specified but can't find parent.");
+                       return false;
+               }
+               var cal = new Calendar(params.mondayFirst, params.date, params.onSelect || onSelect);
+               cal.showsTime = params.showsTime;
+               cal.time24 = (params.timeFormat == "24");
+               cal.params = params;
+               cal.weekNumbers = params.weekNumbers;
+               cal.setRange(params.range[0], params.range[1]);
+               cal.setDateStatusHandler(params.dateStatusFunc);
+               cal.create(params.flat);
+               cal.show();
+               return false;
+       }
+
+       var triggerEl = params.button || params.displayArea || params.inputField;
+       triggerEl["on" + params.eventName] = function() {
+               var dateEl = params.inputField || params.displayArea;
+               var dateFmt = params.inputField ? params.ifFormat : params.daFormat;
+               var mustCreate = false;
+               var cal = window.calendar;
+               if (!window.calendar) {
+                       window.calendar = cal = new Calendar(params.mondayFirst,
+                                                            params.date,
+                                                            params.onSelect || onSelect,
+                                                            params.onClose || function(cal) { cal.hide(); });
+                       cal.showsTime = params.showsTime;
+                       cal.time24 = (params.timeFormat == "24");
+                       cal.weekNumbers = params.weekNumbers;
+                       mustCreate = true;
+               } else {
+                       cal.hide();
+               }
+               cal.setRange(params.range[0], params.range[1]);
+               cal.params = params;
+               cal.setDateStatusHandler(params.dateStatusFunc);
+               cal.setDateFormat(dateFmt);
+               if (mustCreate)
+                       cal.create();
+               cal.parseDate(dateEl.value || dateEl.innerHTML);
+               cal.refresh();
+               cal.showAtElement(params.displayArea || params.inputField, params.align);
+               return false;
+       };
+};
diff --git a/httemplate/elements/calendar-win2k-2.css b/httemplate/elements/calendar-win2k-2.css
new file mode 100644 (file)
index 0000000..9727d1b
--- /dev/null
@@ -0,0 +1,263 @@
+/* The main calendar widget.  DIV containing a table. */
+
+.calendar {
+  position: relative;
+  display: none;
+  border-top: 2px solid #fff;
+  border-right: 2px solid #000;
+  border-bottom: 2px solid #000;
+  border-left: 2px solid #fff;
+  font-size: 11px;
+  color: #000;
+  cursor: default;
+  background: #d4c8d0;
+  font-family: tahoma,verdana,sans-serif;
+}
+
+.calendar table {
+  border-top: 1px solid #000;
+  border-right: 1px solid #fff;
+  border-bottom: 1px solid #fff;
+  border-left: 1px solid #000;
+  font-size: 11px;
+  color: #000;
+  cursor: default;
+  background: #d4c8d0;
+  font-family: tahoma,verdana,sans-serif;
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+  text-align: center;
+  padding: 1px;
+  border-top: 1px solid #fff;
+  border-right: 1px solid #000;
+  border-bottom: 1px solid #000;
+  border-left: 1px solid #fff;
+}
+
+.calendar .nav {
+  background: transparent url(menuarrow.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+  font-weight: bold;
+  padding: 1px;
+  border: 1px solid #000;
+  background: #847880;
+  color: #fff;
+  text-align: center;
+}
+
+.calendar thead .headrow { /* Row <TR> containing navigation buttons */
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+  border-bottom: 1px solid #000;
+  padding: 2px;
+  text-align: center;
+  background: #f4e8f0;
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+  color: #f00;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+  border-top: 2px solid #fff;
+  border-right: 2px solid #000;
+  border-bottom: 2px solid #000;
+  border-left: 2px solid #fff;
+  padding: 0px;
+  background-color: #e4d8e0;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+  padding: 2px 0px 0px 2px;
+  border-top: 1px solid #000;
+  border-right: 1px solid #fff;
+  border-bottom: 1px solid #fff;
+  border-left: 1px solid #000;
+  background-color: #c4b8c0;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+  width: 2em;
+  text-align: right;
+  padding: 2px 4px 2px 2px;
+}
+
+.calendar table .wn {
+  padding: 2px 3px 2px 2px;
+  border-right: 1px solid #000;
+  background: #f4e8f0;
+}
+
+.calendar tbody .rowhilite td {
+  background: #e4d8e0;
+}
+
+.calendar tbody .rowhilite td.wn {
+  background: #d4c8d0;
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+  padding: 1px 3px 1px 1px;
+  border-top: 1px solid #fff;
+  border-right: 1px solid #000;
+  border-bottom: 1px solid #000;
+  border-left: 1px solid #fff;
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+  padding: 2px 2px 0px 2px;
+  border-top: 1px solid #000;
+  border-right: 1px solid #fff;
+  border-bottom: 1px solid #fff;
+  border-left: 1px solid #000;
+}
+
+.calendar tbody td.selected { /* Cell showing selected date */
+  font-weight: bold;
+  border-top: 1px solid #000;
+  border-right: 1px solid #fff;
+  border-bottom: 1px solid #fff;
+  border-left: 1px solid #000;
+  padding: 2px 2px 0px 2px;
+  background: #e4d8e0;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+  color: #f00;
+}
+
+.calendar tbody td.today { /* Cell showing today date */
+  font-weight: bold;
+  color: #00f;
+}
+
+.calendar tbody .disabled { color: #999; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+  visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+  display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+  background: #f4e8f0;
+  padding: 1px;
+  border: 1px solid #000;
+  background: #847880;
+  color: #fff;
+  text-align: center;
+}
+
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+  border-top: 1px solid #fff;
+  border-right: 1px solid #000;
+  border-bottom: 1px solid #000;
+  border-left: 1px solid #fff;
+  padding: 1px;
+  background: #e4d8e0;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+  padding: 2px 0px 0px 2px;
+  border-top: 1px solid #000;
+  border-right: 1px solid #fff;
+  border-bottom: 1px solid #fff;
+  border-left: 1px solid #000;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.combo {
+  position: absolute;
+  display: none;
+  width: 4em;
+  top: 0px;
+  left: 0px;
+  cursor: default;
+  border-top: 1px solid #fff;
+  border-right: 1px solid #000;
+  border-bottom: 1px solid #000;
+  border-left: 1px solid #fff;
+  background: #e4d8e0;
+  font-size: smaller;
+  padding: 1px;
+}
+
+.combo .label,
+.combo .label-IEfix {
+  text-align: center;
+  padding: 1px;
+}
+
+.combo .label-IEfix {
+  width: 4em;
+}
+
+.combo .active {
+  background: #d4c8d0;
+  padding: 0px;
+  border-top: 1px solid #000;
+  border-right: 1px solid #fff;
+  border-bottom: 1px solid #fff;
+  border-left: 1px solid #000;
+}
+
+.combo .hilite {
+  background: #408;
+  color: #fea;
+}
+
+.calendar td.time {
+  border-top: 1px solid #000;
+  padding: 1px 0px;
+  text-align: center;
+  background-color: #f4f0e8;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+  padding: 0px 3px 0px 4px;
+  border: 1px solid #889;
+  font-weight: bold;
+  background-color: #fff;
+}
+
+.calendar td.time .ampm {
+  text-align: center;
+}
+
+.calendar td.time .colon {
+  padding: 0px 2px 0px 3px;
+  font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+  border-color: #000;
+  background-color: #766;
+  color: #fff;
+}
+
+.calendar td.time span.active {
+  border-color: #f00;
+  background-color: #000;
+  color: #0f0;
+}
diff --git a/httemplate/elements/calendar.js b/httemplate/elements/calendar.js
new file mode 100644 (file)
index 0000000..3c028cc
--- /dev/null
@@ -0,0 +1,1641 @@
+/*  Copyright Mihai Bazon, 2002, 2003  |  http://dynarch.com/mishoo/
+ * ------------------------------------------------------------------
+ *
+ * The DHTML Calendar, version 0.9.5 "Your favorite time, bis"
+ *
+ * Details and latest version at:
+ * http://dynarch.com/mishoo/calendar.epl
+ *
+ * This script is distributed under the GNU Lesser General Public License.
+ * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
+ */
+
+// $Id: calendar.js,v 1.3 2003-11-07 10:53:35 ivan Exp $
+
+/** The Calendar object constructor. */
+Calendar = function (mondayFirst, dateStr, onSelected, onClose) {
+       // member variables
+       this.activeDiv = null;
+       this.currentDateEl = null;
+       this.getDateStatus = null;
+       this.timeout = null;
+       this.onSelected = onSelected || null;
+       this.onClose = onClose || null;
+       this.dragging = false;
+       this.hidden = false;
+       this.minYear = 1970;
+       this.maxYear = 2050;
+       this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"];
+       this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"];
+       this.isPopup = true;
+       this.weekNumbers = true;
+       this.mondayFirst = mondayFirst;
+       this.dateStr = dateStr;
+       this.ar_days = null;
+       this.showsTime = false;
+       this.time24 = true;
+       // HTML elements
+       this.table = null;
+       this.element = null;
+       this.tbody = null;
+       this.firstdayname = null;
+       // Combo boxes
+       this.monthsCombo = null;
+       this.yearsCombo = null;
+       this.hilitedMonth = null;
+       this.activeMonth = null;
+       this.hilitedYear = null;
+       this.activeYear = null;
+       // Information
+       this.dateClicked = false;
+
+       // one-time initializations
+       if (typeof Calendar._SDN == "undefined") {
+               // table of short day names
+               if (typeof Calendar._SDN_len == "undefined")
+                       Calendar._SDN_len = 3;
+               var ar = new Array();
+               for (var i = 8; i > 0;) {
+                       ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len);
+               }
+               Calendar._SDN = ar;
+               // table of short month names
+               if (typeof Calendar._SMN_len == "undefined")
+                       Calendar._SMN_len = 3;
+               ar = new Array();
+               for (var i = 12; i > 0;) {
+                       ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len);
+               }
+               Calendar._SMN = ar;
+       }
+};
+
+// ** constants
+
+/// "static", needed for event handlers.
+Calendar._C = null;
+
+/// detect a special case of "web browser"
+Calendar.is_ie = ( /msie/i.test(navigator.userAgent) &&
+                  !/opera/i.test(navigator.userAgent) );
+
+/// detect Opera browser
+Calendar.is_opera = /opera/i.test(navigator.userAgent);
+
+/// detect KHTML-based browsers
+Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);
+
+// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate
+//        library, at some point.
+
+Calendar.getAbsolutePos = function(el) {
+       var SL = 0, ST = 0;
+       var is_div = /^div$/i.test(el.tagName);
+       if (is_div && el.scrollLeft)
+               SL = el.scrollLeft;
+       if (is_div && el.scrollTop)
+               ST = el.scrollTop;
+       var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
+       if (el.offsetParent) {
+               var tmp = Calendar.getAbsolutePos(el.offsetParent);
+               r.x += tmp.x;
+               r.y += tmp.y;
+       }
+       return r;
+};
+
+Calendar.isRelated = function (el, evt) {
+       var related = evt.relatedTarget;
+       if (!related) {
+               var type = evt.type;
+               if (type == "mouseover") {
+                       related = evt.fromElement;
+               } else if (type == "mouseout") {
+                       related = evt.toElement;
+               }
+       }
+       while (related) {
+               if (related == el) {
+                       return true;
+               }
+               related = related.parentNode;
+       }
+       return false;
+};
+
+Calendar.removeClass = function(el, className) {
+       if (!(el && el.className)) {
+               return;
+       }
+       var cls = el.className.split(" ");
+       var ar = new Array();
+       for (var i = cls.length; i > 0;) {
+               if (cls[--i] != className) {
+                       ar[ar.length] = cls[i];
+               }
+       }
+       el.className = ar.join(" ");
+};
+
+Calendar.addClass = function(el, className) {
+       Calendar.removeClass(el, className);
+       el.className += " " + className;
+};
+
+Calendar.getElement = function(ev) {
+       if (Calendar.is_ie) {
+               return window.event.srcElement;
+       } else {
+               return ev.currentTarget;
+       }
+};
+
+Calendar.getTargetElement = function(ev) {
+       if (Calendar.is_ie) {
+               return window.event.srcElement;
+       } else {
+               return ev.target;
+       }
+};
+
+Calendar.stopEvent = function(ev) {
+       ev || (ev = window.event);
+       if (Calendar.is_ie) {
+               ev.cancelBubble = true;
+               ev.returnValue = false;
+       } else {
+               ev.preventDefault();
+               ev.stopPropagation();
+       }
+       return false;
+};
+
+Calendar.addEvent = function(el, evname, func) {
+       if (el.attachEvent) { // IE
+               el.attachEvent("on" + evname, func);
+       } else if (el.addEventListener) { // Gecko / W3C
+               el.addEventListener(evname, func, true);
+       } else {
+               el["on" + evname] = func;
+       }
+};
+
+Calendar.removeEvent = function(el, evname, func) {
+       if (el.detachEvent) { // IE
+               el.detachEvent("on" + evname, func);
+       } else if (el.removeEventListener) { // Gecko / W3C
+               el.removeEventListener(evname, func, true);
+       } else {
+               el["on" + evname] = null;
+       }
+};
+
+Calendar.createElement = function(type, parent) {
+       var el = null;
+       if (document.createElementNS) {
+               // use the XHTML namespace; IE won't normally get here unless
+               // _they_ "fix" the DOM2 implementation.
+               el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
+       } else {
+               el = document.createElement(type);
+       }
+       if (typeof parent != "undefined") {
+               parent.appendChild(el);
+       }
+       return el;
+};
+
+// END: UTILITY FUNCTIONS
+
+// BEGIN: CALENDAR STATIC FUNCTIONS
+
+/** Internal -- adds a set of events to make some element behave like a button. */
+Calendar._add_evs = function(el) {
+       with (Calendar) {
+               addEvent(el, "mouseover", dayMouseOver);
+               addEvent(el, "mousedown", dayMouseDown);
+               addEvent(el, "mouseout", dayMouseOut);
+               if (is_ie) {
+                       addEvent(el, "dblclick", dayMouseDblClick);
+                       el.setAttribute("unselectable", true);
+               }
+       }
+};
+
+Calendar.findMonth = function(el) {
+       if (typeof el.month != "undefined") {
+               return el;
+       } else if (typeof el.parentNode.month != "undefined") {
+               return el.parentNode;
+       }
+       return null;
+};
+
+Calendar.findYear = function(el) {
+       if (typeof el.year != "undefined") {
+               return el;
+       } else if (typeof el.parentNode.year != "undefined") {
+               return el.parentNode;
+       }
+       return null;
+};
+
+Calendar.showMonthsCombo = function () {
+       var cal = Calendar._C;
+       if (!cal) {
+               return false;
+       }
+       var cal = cal;
+       var cd = cal.activeDiv;
+       var mc = cal.monthsCombo;
+       if (cal.hilitedMonth) {
+               Calendar.removeClass(cal.hilitedMonth, "hilite");
+       }
+       if (cal.activeMonth) {
+               Calendar.removeClass(cal.activeMonth, "active");
+       }
+       var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];
+       Calendar.addClass(mon, "active");
+       cal.activeMonth = mon;
+       var s = mc.style;
+       s.display = "block";
+       if (cd.navtype < 0)
+               s.left = cd.offsetLeft + "px";
+       else
+               s.left = (cd.offsetLeft + cd.offsetWidth - mc.offsetWidth) + "px";
+       s.top = (cd.offsetTop + cd.offsetHeight) + "px";
+};
+
+Calendar.showYearsCombo = function (fwd) {
+       var cal = Calendar._C;
+       if (!cal) {
+               return false;
+       }
+       var cal = cal;
+       var cd = cal.activeDiv;
+       var yc = cal.yearsCombo;
+       if (cal.hilitedYear) {
+               Calendar.removeClass(cal.hilitedYear, "hilite");
+       }
+       if (cal.activeYear) {
+               Calendar.removeClass(cal.activeYear, "active");
+       }
+       cal.activeYear = null;
+       var Y = cal.date.getFullYear() + (fwd ? 1 : -1);
+       var yr = yc.firstChild;
+       var show = false;
+       for (var i = 12; i > 0; --i) {
+               if (Y >= cal.minYear && Y <= cal.maxYear) {
+                       yr.firstChild.data = Y;
+                       yr.year = Y;
+                       yr.style.display = "block";
+                       show = true;
+               } else {
+                       yr.style.display = "none";
+               }
+               yr = yr.nextSibling;
+               Y += fwd ? 2 : -2;
+       }
+       if (show) {
+               var s = yc.style;
+               s.display = "block";
+               if (cd.navtype < 0)
+                       s.left = cd.offsetLeft + "px";
+               else
+                       s.left = (cd.offsetLeft + cd.offsetWidth - yc.offsetWidth) + "px";
+               s.top = (cd.offsetTop + cd.offsetHeight) + "px";
+       }
+};
+
+// event handlers
+
+Calendar.tableMouseUp = function(ev) {
+       var cal = Calendar._C;
+       if (!cal) {
+               return false;
+       }
+       if (cal.timeout) {
+               clearTimeout(cal.timeout);
+       }
+       var el = cal.activeDiv;
+       if (!el) {
+               return false;
+       }
+       var target = Calendar.getTargetElement(ev);
+       ev || (ev = window.event);
+       Calendar.removeClass(el, "active");
+       if (target == el || target.parentNode == el) {
+               Calendar.cellClick(el, ev);
+       }
+       var mon = Calendar.findMonth(target);
+       var date = null;
+       if (mon) {
+               date = new Date(cal.date);
+               if (mon.month != date.getMonth()) {
+                       date.setMonth(mon.month);
+                       cal.setDate(date);
+                       cal.dateClicked = false;
+                       cal.callHandler();
+               }
+       } else {
+               var year = Calendar.findYear(target);
+               if (year) {
+                       date = new Date(cal.date);
+                       if (year.year != date.getFullYear()) {
+                               date.setFullYear(year.year);
+                               cal.setDate(date);
+                               cal.dateClicked = false;
+                               cal.callHandler();
+                       }
+               }
+       }
+       with (Calendar) {
+               removeEvent(document, "mouseup", tableMouseUp);
+               removeEvent(document, "mouseover", tableMouseOver);
+               removeEvent(document, "mousemove", tableMouseOver);
+               cal._hideCombos();
+               _C = null;
+               return stopEvent(ev);
+       }
+};
+
+Calendar.tableMouseOver = function (ev) {
+       var cal = Calendar._C;
+       if (!cal) {
+               return;
+       }
+       var el = cal.activeDiv;
+       var target = Calendar.getTargetElement(ev);
+       if (target == el || target.parentNode == el) {
+               Calendar.addClass(el, "hilite active");
+               Calendar.addClass(el.parentNode, "rowhilite");
+       } else {
+               if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2)))
+                       Calendar.removeClass(el, "active");
+               Calendar.removeClass(el, "hilite");
+               Calendar.removeClass(el.parentNode, "rowhilite");
+       }
+       ev || (ev = window.event);
+       if (el.navtype == 50 && target != el) {
+               var pos = Calendar.getAbsolutePos(el);
+               var w = el.offsetWidth;
+               var x = ev.clientX;
+               var dx;
+               var decrease = true;
+               if (x > pos.x + w) {
+                       dx = x - pos.x - w;
+                       decrease = false;
+               } else
+                       dx = pos.x - x;
+
+               if (dx < 0) dx = 0;
+               var range = el._range;
+               var current = el._current;
+               var count = Math.floor(dx / 10) % range.length;
+               for (var i = range.length; --i >= 0;)
+                       if (range[i] == current)
+                               break;
+               while (count-- > 0)
+                       if (decrease) {
+                               if (!(--i in range))
+                                       i = range.length - 1;
+                       } else if (!(++i in range))
+                               i = 0;
+               var newval = range[i];
+               el.firstChild.data = newval;
+
+               cal.onUpdateTime();
+       }
+       var mon = Calendar.findMonth(target);
+       if (mon) {
+               if (mon.month != cal.date.getMonth()) {
+                       if (cal.hilitedMonth) {
+                               Calendar.removeClass(cal.hilitedMonth, "hilite");
+                       }
+                       Calendar.addClass(mon, "hilite");
+                       cal.hilitedMonth = mon;
+               } else if (cal.hilitedMonth) {
+                       Calendar.removeClass(cal.hilitedMonth, "hilite");
+               }
+       } else {
+               if (cal.hilitedMonth) {
+                       Calendar.removeClass(cal.hilitedMonth, "hilite");
+               }
+               var year = Calendar.findYear(target);
+               if (year) {
+                       if (year.year != cal.date.getFullYear()) {
+                               if (cal.hilitedYear) {
+                                       Calendar.removeClass(cal.hilitedYear, "hilite");
+                               }
+                               Calendar.addClass(year, "hilite");
+                               cal.hilitedYear = year;
+                       } else if (cal.hilitedYear) {
+                               Calendar.removeClass(cal.hilitedYear, "hilite");
+                       }
+               } else if (cal.hilitedYear) {
+                       Calendar.removeClass(cal.hilitedYear, "hilite");
+               }
+       }
+       return Calendar.stopEvent(ev);
+};
+
+Calendar.tableMouseDown = function (ev) {
+       if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) {
+               return Calendar.stopEvent(ev);
+       }
+};
+
+Calendar.calDragIt = function (ev) {
+       var cal = Calendar._C;
+       if (!(cal && cal.dragging)) {
+               return false;
+       }
+       var posX;
+       var posY;
+       if (Calendar.is_ie) {
+               posY = window.event.clientY + document.body.scrollTop;
+               posX = window.event.clientX + document.body.scrollLeft;
+       } else {
+               posX = ev.pageX;
+               posY = ev.pageY;
+       }
+       cal.hideShowCovered();
+       var st = cal.element.style;
+       st.left = (posX - cal.xOffs) + "px";
+       st.top = (posY - cal.yOffs) + "px";
+       return Calendar.stopEvent(ev);
+};
+
+Calendar.calDragEnd = function (ev) {
+       var cal = Calendar._C;
+       if (!cal) {
+               return false;
+       }
+       cal.dragging = false;
+       with (Calendar) {
+               removeEvent(document, "mousemove", calDragIt);
+               removeEvent(document, "mouseover", stopEvent);
+               removeEvent(document, "mouseup", calDragEnd);
+               tableMouseUp(ev);
+       }
+       cal.hideShowCovered();
+};
+
+Calendar.dayMouseDown = function(ev) {
+       var el = Calendar.getElement(ev);
+       if (el.disabled) {
+               return false;
+       }
+       var cal = el.calendar;
+       cal.activeDiv = el;
+       Calendar._C = cal;
+       if (el.navtype != 300) with (Calendar) {
+               if (el.navtype == 50)
+                       el._current = el.firstChild.data;
+               addClass(el, "hilite active");
+               addEvent(document, "mouseover", tableMouseOver);
+               addEvent(document, "mousemove", tableMouseOver);
+               addEvent(document, "mouseup", tableMouseUp);
+       } else if (cal.isPopup) {
+               cal._dragStart(ev);
+       }
+       if (el.navtype == -1 || el.navtype == 1) {
+               if (cal.timeout) clearTimeout(cal.timeout);
+               cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250);
+       } else if (el.navtype == -2 || el.navtype == 2) {
+               if (cal.timeout) clearTimeout(cal.timeout);
+               cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250);
+       } else {
+               cal.timeout = null;
+       }
+       return Calendar.stopEvent(ev);
+};
+
+Calendar.dayMouseDblClick = function(ev) {
+       Calendar.cellClick(Calendar.getElement(ev), ev || window.event);
+       if (Calendar.is_ie) {
+               document.selection.empty();
+       }
+};
+
+Calendar.dayMouseOver = function(ev) {
+       var el = Calendar.getElement(ev);
+       if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) {
+               return false;
+       }
+       if (el.ttip) {
+               if (el.ttip.substr(0, 1) == "_") {
+                       var date = null;
+                       with (el.calendar.date) {
+                               date = new Date(getFullYear(), getMonth(), el.caldate);
+                       }
+                       el.ttip = date.print(el.calendar.ttDateFormat) + el.ttip.substr(1);
+               }
+               el.calendar.tooltips.firstChild.data = el.ttip;
+       }
+       if (el.navtype != 300) {
+               Calendar.addClass(el, "hilite");
+               if (el.caldate) {
+                       Calendar.addClass(el.parentNode, "rowhilite");
+               }
+       }
+       return Calendar.stopEvent(ev);
+};
+
+Calendar.dayMouseOut = function(ev) {
+       with (Calendar) {
+               var el = getElement(ev);
+               if (isRelated(el, ev) || _C || el.disabled) {
+                       return false;
+               }
+               removeClass(el, "hilite");
+               if (el.caldate) {
+                       removeClass(el.parentNode, "rowhilite");
+               }
+               el.calendar.tooltips.firstChild.data = _TT["SEL_DATE"];
+               return stopEvent(ev);
+       }
+};
+
+/**
+ *  A generic "click" handler :) handles all types of buttons defined in this
+ *  calendar.
+ */
+Calendar.cellClick = function(el, ev) {
+       var cal = el.calendar;
+       var closing = false;
+       var newdate = false;
+       var date = null;
+       if (typeof el.navtype == "undefined") {
+               Calendar.removeClass(cal.currentDateEl, "selected");
+               Calendar.addClass(el, "selected");
+               closing = (cal.currentDateEl == el);
+               if (!closing) {
+                       cal.currentDateEl = el;
+               }
+               cal.date.setDate(el.caldate);
+               date = cal.date;
+               newdate = true;
+               // a date was clicked
+               cal.dateClicked = true;
+       } else {
+               if (el.navtype == 200) {
+                       Calendar.removeClass(el, "hilite");
+                       cal.callCloseHandler();
+                       return;
+               }
+               date = (el.navtype == 0) ? new Date() : new Date(cal.date);
+               // unless "today" was clicked, we assume no date was clicked so
+               // the selected handler will know not to close the calenar when
+               // in single-click mode.
+               // cal.dateClicked = (el.navtype == 0);
+               cal.dateClicked = false;
+               var year = date.getFullYear();
+               var mon = date.getMonth();
+               function setMonth(m) {
+                       var day = date.getDate();
+                       var max = date.getMonthDays(m);
+                       if (day > max) {
+                               date.setDate(max);
+                       }
+                       date.setMonth(m);
+               };
+               switch (el.navtype) {
+                   case 400:
+                       Calendar.removeClass(el, "hilite");
+                       var text = Calendar._TT["ABOUT"];
+                       if (typeof text != "undefined") {
+                               text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : "";
+                       } else {
+                               // FIXME: this should be removed as soon as lang files get updated!
+                               text = "Help and about box text is not translated into this language.\n" +
+                                       "If you know this language and you feel generous please update\n" +
+                                       "the corresponding file in \"lang\" subdir to match calendar-en.js\n" +
+                                       "and send it back to <mishoo@infoiasi.ro> to get it into the distribution  ;-)\n\n" +
+                                       "Thank you!\n" +
+                                       "http://dynarch.com/mishoo/calendar.epl\n";
+                       }
+                       alert(text);
+                       return;
+                   case -2:
+                       if (year > cal.minYear) {
+                               date.setFullYear(year - 1);
+                       }
+                       break;
+                   case -1:
+                       if (mon > 0) {
+                               setMonth(mon - 1);
+                       } else if (year-- > cal.minYear) {
+                               date.setFullYear(year);
+                               setMonth(11);
+                       }
+                       break;
+                   case 1:
+                       if (mon < 11) {
+                               setMonth(mon + 1);
+                       } else if (year < cal.maxYear) {
+                               date.setFullYear(year + 1);
+                               setMonth(0);
+                       }
+                       break;
+                   case 2:
+                       if (year < cal.maxYear) {
+                               date.setFullYear(year + 1);
+                       }
+                       break;
+                   case 100:
+                       cal.setMondayFirst(!cal.mondayFirst);
+                       return;
+                   case 50:
+                       var range = el._range;
+                       var current = el.firstChild.data;
+                       for (var i = range.length; --i >= 0;)
+                               if (range[i] == current)
+                                       break;
+                       if (ev && ev.shiftKey) {
+                               if (!(--i in range))
+                                       i = range.length - 1;
+                       } else if (!(++i in range))
+                               i = 0;
+                       var newval = range[i];
+                       el.firstChild.data = newval;
+                       cal.onUpdateTime();
+                       return;
+                   case 0:
+                       // TODAY will bring us here
+                       if ((typeof cal.getDateStatus == "function") && cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) {
+                               // remember, "date" was previously set to new
+                               // Date() if TODAY was clicked; thus, it
+                               // contains today date.
+                               return false;
+                       }
+                       break;
+               }
+               if (!date.equalsTo(cal.date)) {
+                       cal.setDate(date);
+                       newdate = true;
+               }
+       }
+       if (newdate) {
+               cal.callHandler();
+       }
+       if (closing) {
+               Calendar.removeClass(el, "hilite");
+               cal.callCloseHandler();
+       }
+};
+
+// END: CALENDAR STATIC FUNCTIONS
+
+// BEGIN: CALENDAR OBJECT FUNCTIONS
+
+/**
+ *  This function creates the calendar inside the given parent.  If _par is
+ *  null than it creates a popup calendar inside the BODY element.  If _par is
+ *  an element, be it BODY, then it creates a non-popup calendar (still
+ *  hidden).  Some properties need to be set before calling this function.
+ */
+Calendar.prototype.create = function (_par) {
+       var parent = null;
+       if (! _par) {
+               // default parent is the document body, in which case we create
+               // a popup calendar.
+               parent = document.getElementsByTagName("body")[0];
+               this.isPopup = true;
+       } else {
+               parent = _par;
+               this.isPopup = false;
+       }
+       this.date = this.dateStr ? new Date(this.dateStr) : new Date();
+
+       var table = Calendar.createElement("table");
+       this.table = table;
+       table.cellSpacing = 0;
+       table.cellPadding = 0;
+       table.calendar = this;
+       Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown);
+
+       var div = Calendar.createElement("div");
+       this.element = div;
+       div.className = "calendar";
+       if (this.isPopup) {
+               div.style.position = "absolute";
+               div.style.display = "none";
+       }
+       div.appendChild(table);
+
+       var thead = Calendar.createElement("thead", table);
+       var cell = null;
+       var row = null;
+
+       var cal = this;
+       var hh = function (text, cs, navtype) {
+               cell = Calendar.createElement("td", row);
+               cell.colSpan = cs;
+               cell.className = "button";
+               if (navtype != 0 && Math.abs(navtype) <= 2)
+                       cell.className += " nav";
+               Calendar._add_evs(cell);
+               cell.calendar = cal;
+               cell.navtype = navtype;
+               if (text.substr(0, 1) != "&") {
+                       cell.appendChild(document.createTextNode(text));
+               }
+               else {
+                       // FIXME: dirty hack for entities
+                       cell.innerHTML = text;
+               }
+               return cell;
+       };
+
+       row = Calendar.createElement("tr", thead);
+       var title_length = 6;
+       (this.isPopup) && --title_length;
+       (this.weekNumbers) && ++title_length;
+
+       hh("?", 1, 400).ttip = Calendar._TT["INFO"];
+       this.title = hh("", title_length, 300);
+       this.title.className = "title";
+       if (this.isPopup) {
+               this.title.ttip = Calendar._TT["DRAG_TO_MOVE"];
+               this.title.style.cursor = "move";
+               hh("&#x00d7;", 1, 200).ttip = Calendar._TT["CLOSE"];
+       }
+
+       row = Calendar.createElement("tr", thead);
+       row.className = "headrow";
+
+       this._nav_py = hh("&#x00ab;", 1, -2);
+       this._nav_py.ttip = Calendar._TT["PREV_YEAR"];
+
+       this._nav_pm = hh("&#x2039;", 1, -1);
+       this._nav_pm.ttip = Calendar._TT["PREV_MONTH"];
+
+       this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0);
+       this._nav_now.ttip = Calendar._TT["GO_TODAY"];
+
+       this._nav_nm = hh("&#x203a;", 1, 1);
+       this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"];
+
+       this._nav_ny = hh("&#x00bb;", 1, 2);
+       this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"];
+
+       // day names
+       row = Calendar.createElement("tr", thead);
+       row.className = "daynames";
+       if (this.weekNumbers) {
+               cell = Calendar.createElement("td", row);
+               cell.className = "name wn";
+               cell.appendChild(document.createTextNode(Calendar._TT["WK"]));
+       }
+       for (var i = 7; i > 0; --i) {
+               cell = Calendar.createElement("td", row);
+               cell.appendChild(document.createTextNode(""));
+               if (!i) {
+                       cell.navtype = 100;
+                       cell.calendar = this;
+                       Calendar._add_evs(cell);
+               }
+       }
+       this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild;
+       this._displayWeekdays();
+
+       var tbody = Calendar.createElement("tbody", table);
+       this.tbody = tbody;
+
+       for (i = 6; i > 0; --i) {
+               row = Calendar.createElement("tr", tbody);
+               if (this.weekNumbers) {
+                       cell = Calendar.createElement("td", row);
+                       cell.appendChild(document.createTextNode(""));
+               }
+               for (var j = 7; j > 0; --j) {
+                       cell = Calendar.createElement("td", row);
+                       cell.appendChild(document.createTextNode(""));
+                       cell.calendar = this;
+                       Calendar._add_evs(cell);
+               }
+       }
+
+       if (this.showsTime) {
+               row = Calendar.createElement("tr", tbody);
+               row.className = "time";
+
+               cell = Calendar.createElement("td", row);
+               cell.className = "time";
+               cell.colSpan = 2;
+               cell.innerHTML = "&nbsp;";
+
+               cell = Calendar.createElement("td", row);
+               cell.className = "time";
+               cell.colSpan = this.weekNumbers ? 4 : 3;
+
+               (function(){
+                       function makeTimePart(className, init, range_start, range_end) {
+                               var part = Calendar.createElement("span", cell);
+                               part.className = className;
+                               part.appendChild(document.createTextNode(init));
+                               part.calendar = cal;
+                               part.ttip = Calendar._TT["TIME_PART"];
+                               part.navtype = 50;
+                               part._range = [];
+                               if (typeof range_start != "number")
+                                       part._range = range_start;
+                               else {
+                                       for (var i = range_start; i <= range_end; ++i) {
+                                               var txt;
+                                               if (i < 10 && range_end >= 10) txt = '0' + i;
+                                               else txt = '' + i;
+                                               part._range[part._range.length] = txt;
+                                       }
+                               }
+                               Calendar._add_evs(part);
+                               return part;
+                       };
+                       var hrs = cal.date.getHours();
+                       var mins = cal.date.getMinutes();
+                       var t12 = !cal.time24;
+                       var pm = (hrs > 12);
+                       if (t12 && pm) hrs -= 12;
+                       var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23);
+                       var span = Calendar.createElement("span", cell);
+                       span.appendChild(document.createTextNode(":"));
+                       span.className = "colon";
+                       var M = makeTimePart("minute", mins, 0, 59);
+                       var AP = null;
+                       cell = Calendar.createElement("td", row);
+                       cell.className = "time";
+                       cell.colSpan = 2;
+                       if (t12)
+                               AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]);
+                       else
+                               cell.innerHTML = "&nbsp;";
+
+                       cal.onSetTime = function() {
+                               var hrs = this.date.getHours();
+                               var mins = this.date.getMinutes();
+                               var pm = (hrs > 12);
+                               if (pm && t12) hrs -= 12;
+                               H.firstChild.data = (hrs < 10) ? ("0" + hrs) : hrs;
+                               M.firstChild.data = (mins < 10) ? ("0" + mins) : mins;
+                               if (t12)
+                                       AP.firstChild.data = pm ? "pm" : "am";
+                       };
+
+                       cal.onUpdateTime = function() {
+                               var date = this.date;
+                               var h = parseInt(H.firstChild.data, 10);
+                               if (t12) {
+                                       if (/pm/i.test(AP.firstChild.data) && h < 12)
+                                               h += 12;
+                                       else if (/am/i.test(AP.firstChild.data) && h == 12)
+                                               h = 0;
+                               }
+                               var d = date.getDate();
+                               var m = date.getMonth();
+                               var y = date.getFullYear();
+                               date.setHours(h);
+                               date.setMinutes(parseInt(M.firstChild.data, 10));
+                               date.setFullYear(y);
+                               date.setMonth(m);
+                               date.setDate(d);
+                               this.dateClicked = false;
+                               this.callHandler();
+                       };
+               })();
+       } else {
+               this.onSetTime = this.onUpdateTime = function() {};
+       }
+
+       var tfoot = Calendar.createElement("tfoot", table);
+
+       row = Calendar.createElement("tr", tfoot);
+       row.className = "footrow";
+
+       cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300);
+       cell.className = "ttip";
+       if (this.isPopup) {
+               cell.ttip = Calendar._TT["DRAG_TO_MOVE"];
+               cell.style.cursor = "move";
+       }
+       this.tooltips = cell;
+
+       div = Calendar.createElement("div", this.element);
+       this.monthsCombo = div;
+       div.className = "combo";
+       for (i = 0; i < Calendar._MN.length; ++i) {
+               var mn = Calendar.createElement("div");
+               mn.className = Calendar.is_ie ? "label-IEfix" : "label";
+               mn.month = i;
+               mn.appendChild(document.createTextNode(Calendar._SMN[i]));
+               div.appendChild(mn);
+       }
+
+       div = Calendar.createElement("div", this.element);
+       this.yearsCombo = div;
+       div.className = "combo";
+       for (i = 12; i > 0; --i) {
+               var yr = Calendar.createElement("div");
+               yr.className = Calendar.is_ie ? "label-IEfix" : "label";
+               yr.appendChild(document.createTextNode(""));
+               div.appendChild(yr);
+       }
+
+       this._init(this.mondayFirst, this.date);
+       parent.appendChild(this.element);
+};
+
+/** keyboard navigation, only for popup calendars */
+Calendar._keyEvent = function(ev) {
+       if (!window.calendar) {
+               return false;
+       }
+       (Calendar.is_ie) && (ev = window.event);
+       var cal = window.calendar;
+       var act = (Calendar.is_ie || ev.type == "keypress");
+       if (ev.ctrlKey) {
+               switch (ev.keyCode) {
+                   case 37: // KEY left
+                       act && Calendar.cellClick(cal._nav_pm);
+                       break;
+                   case 38: // KEY up
+                       act && Calendar.cellClick(cal._nav_py);
+                       break;
+                   case 39: // KEY right
+                       act && Calendar.cellClick(cal._nav_nm);
+                       break;
+                   case 40: // KEY down
+                       act && Calendar.cellClick(cal._nav_ny);
+                       break;
+                   default:
+                       return false;
+               }
+       } else switch (ev.keyCode) {
+           case 32: // KEY space (now)
+               Calendar.cellClick(cal._nav_now);
+               break;
+           case 27: // KEY esc
+               act && cal.hide();
+               break;
+           case 37: // KEY left
+           case 38: // KEY up
+           case 39: // KEY right
+           case 40: // KEY down
+               if (act) {
+                       var date = cal.date.getDate() - 1;
+                       var el = cal.currentDateEl;
+                       var ne = null;
+                       var prev = (ev.keyCode == 37) || (ev.keyCode == 38);
+                       switch (ev.keyCode) {
+                           case 37: // KEY left
+                               (--date >= 0) && (ne = cal.ar_days[date]);
+                               break;
+                           case 38: // KEY up
+                               date -= 7;
+                               (date >= 0) && (ne = cal.ar_days[date]);
+                               break;
+                           case 39: // KEY right
+                               (++date < cal.ar_days.length) && (ne = cal.ar_days[date]);
+                               break;
+                           case 40: // KEY down
+                               date += 7;
+                               (date < cal.ar_days.length) && (ne = cal.ar_days[date]);
+                               break;
+                       }
+                       if (!ne) {
+                               if (prev) {
+                                       Calendar.cellClick(cal._nav_pm);
+                               } else {
+                                       Calendar.cellClick(cal._nav_nm);
+                               }
+                               date = (prev) ? cal.date.getMonthDays() : 1;
+                               el = cal.currentDateEl;
+                               ne = cal.ar_days[date - 1];
+                       }
+                       Calendar.removeClass(el, "selected");
+                       Calendar.addClass(ne, "selected");
+                       cal.date.setDate(ne.caldate);
+                       cal.callHandler();
+                       cal.currentDateEl = ne;
+               }
+               break;
+           case 13: // KEY enter
+               if (act) {
+                       cal.callHandler();
+                       cal.hide();
+               }
+               break;
+           default:
+               return false;
+       }
+       return Calendar.stopEvent(ev);
+};
+
+/**
+ *  (RE)Initializes the calendar to the given date and style (if mondayFirst is
+ *  true it makes Monday the first day of week, otherwise the weeks start on
+ *  Sunday.
+ */
+Calendar.prototype._init = function (mondayFirst, date) {
+       var today = new Date();
+       var year = date.getFullYear();
+       if (year < this.minYear) {
+               year = this.minYear;
+               date.setFullYear(year);
+       } else if (year > this.maxYear) {
+               year = this.maxYear;
+               date.setFullYear(year);
+       }
+       this.mondayFirst = mondayFirst;
+       this.date = new Date(date);
+       var month = date.getMonth();
+       var mday = date.getDate();
+       var no_days = date.getMonthDays();
+       date.setDate(1);
+       var wday = date.getDay();
+       var MON = mondayFirst ? 1 : 0;
+       var SAT = mondayFirst ? 5 : 6;
+       var SUN = mondayFirst ? 6 : 0;
+       if (mondayFirst) {
+               wday = (wday > 0) ? (wday - 1) : 6;
+       }
+       var iday = 1;
+       var row = this.tbody.firstChild;
+       var MN = Calendar._SMN[month];
+       var hasToday = ((today.getFullYear() == year) && (today.getMonth() == month));
+       var todayDate = today.getDate();
+       var week_number = date.getWeekNumber();
+       var ar_days = new Array();
+       for (var i = 0; i < 6; ++i) {
+               if (iday > no_days) {
+                       row.className = "emptyrow";
+                       row = row.nextSibling;
+                       continue;
+               }
+               var cell = row.firstChild;
+               if (this.weekNumbers) {
+                       cell.className = "day wn";
+                       cell.firstChild.data = week_number;
+                       cell = cell.nextSibling;
+               }
+               ++week_number;
+               row.className = "daysrow";
+               for (var j = 0; j < 7; ++j) {
+                       cell.className = "day";
+                       if ((!i && j < wday) || iday > no_days) {
+                               // cell.className = "emptycell";
+                               cell.innerHTML = "&nbsp;";
+                               cell.disabled = true;
+                               cell = cell.nextSibling;
+                               continue;
+                       }
+                       cell.disabled = false;
+                       cell.firstChild.data = iday;
+                       if (typeof this.getDateStatus == "function") {
+                               date.setDate(iday);
+                               var status = this.getDateStatus(date, year, month, iday);
+                               if (status === true) {
+                                       cell.className += " disabled";
+                                       cell.disabled = true;
+                               } else {
+                                       if (/disabled/i.test(status))
+                                               cell.disabled = true;
+                                       cell.className += " " + status;
+                               }
+                       }
+                       if (!cell.disabled) {
+                               ar_days[ar_days.length] = cell;
+                               cell.caldate = iday;
+                               cell.ttip = "_";
+                               if (iday == mday) {
+                                       cell.className += " selected";
+                                       this.currentDateEl = cell;
+                               }
+                               if (hasToday && (iday == todayDate)) {
+                                       cell.className += " today";
+                                       cell.ttip += Calendar._TT["PART_TODAY"];
+                               }
+                               if (wday == SAT || wday == SUN) {
+                                       cell.className += " weekend";
+                               }
+                       }
+                       ++iday;
+                       ((++wday) ^ 7) || (wday = 0);
+                       cell = cell.nextSibling;
+               }
+               row = row.nextSibling;
+       }
+       this.ar_days = ar_days;
+       this.title.firstChild.data = Calendar._MN[month] + ", " + year;
+       this.onSetTime();
+       // PROFILE
+       // this.tooltips.firstChild.data = "Generated in " + ((new Date()) - today) + " ms";
+};
+
+/**
+ *  Calls _init function above for going to a certain date (but only if the
+ *  date is different than the currently selected one).
+ */
+Calendar.prototype.setDate = function (date) {
+       if (!date.equalsTo(this.date)) {
+               this._init(this.mondayFirst, date);
+       }
+};
+
+/**
+ *  Refreshes the calendar.  Useful if the "disabledHandler" function is
+ *  dynamic, meaning that the list of disabled date can change at runtime.
+ *  Just * call this function if you think that the list of disabled dates
+ *  should * change.
+ */
+Calendar.prototype.refresh = function () {
+       this._init(this.mondayFirst, this.date);
+};
+
+/** Modifies the "mondayFirst" parameter (EU/US style). */
+Calendar.prototype.setMondayFirst = function (mondayFirst) {
+       this._init(mondayFirst, this.date);
+       this._displayWeekdays();
+};
+
+/**
+ *  Allows customization of what dates are enabled.  The "unaryFunction"
+ *  parameter must be a function object that receives the date (as a JS Date
+ *  object) and returns a boolean value.  If the returned value is true then
+ *  the passed date will be marked as disabled.
+ */
+Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) {
+       this.getDateStatus = unaryFunction;
+};
+
+/** Customization of allowed year range for the calendar. */
+Calendar.prototype.setRange = function (a, z) {
+       this.minYear = a;
+       this.maxYear = z;
+};
+
+/** Calls the first user handler (selectedHandler). */
+Calendar.prototype.callHandler = function () {
+       if (this.onSelected) {
+               this.onSelected(this, this.date.print(this.dateFormat));
+       }
+};
+
+/** Calls the second user handler (closeHandler). */
+Calendar.prototype.callCloseHandler = function () {
+       if (this.onClose) {
+               this.onClose(this);
+       }
+       this.hideShowCovered();
+};
+
+/** Removes the calendar object from the DOM tree and destroys it. */
+Calendar.prototype.destroy = function () {
+       var el = this.element.parentNode;
+       el.removeChild(this.element);
+       Calendar._C = null;
+       window.calendar = null;
+};
+
+/**
+ *  Moves the calendar element to a different section in the DOM tree (changes
+ *  its parent).
+ */
+Calendar.prototype.reparent = function (new_parent) {
+       var el = this.element;
+       el.parentNode.removeChild(el);
+       new_parent.appendChild(el);
+};
+
+// This gets called when the user presses a mouse button anywhere in the
+// document, if the calendar is shown.  If the click was outside the open
+// calendar this function closes it.
+Calendar._checkCalendar = function(ev) {
+       if (!window.calendar) {
+               return false;
+       }
+       var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev);
+       for (; el != null && el != calendar.element; el = el.parentNode);
+       if (el == null) {
+               // calls closeHandler which should hide the calendar.
+               window.calendar.callCloseHandler();
+               return Calendar.stopEvent(ev);
+       }
+};
+
+/** Shows the calendar. */
+Calendar.prototype.show = function () {
+       var rows = this.table.getElementsByTagName("tr");
+       for (var i = rows.length; i > 0;) {
+               var row = rows[--i];
+               Calendar.removeClass(row, "rowhilite");
+               var cells = row.getElementsByTagName("td");
+               for (var j = cells.length; j > 0;) {
+                       var cell = cells[--j];
+                       Calendar.removeClass(cell, "hilite");
+                       Calendar.removeClass(cell, "active");
+               }
+       }
+       this.element.style.display = "block";
+       this.hidden = false;
+       if (this.isPopup) {
+               window.calendar = this;
+               Calendar.addEvent(document, "keydown", Calendar._keyEvent);
+               Calendar.addEvent(document, "keypress", Calendar._keyEvent);
+               Calendar.addEvent(document, "mousedown", Calendar._checkCalendar);
+       }
+       this.hideShowCovered();
+};
+
+/**
+ *  Hides the calendar.  Also removes any "hilite" from the class of any TD
+ *  element.
+ */
+Calendar.prototype.hide = function () {
+       if (this.isPopup) {
+               Calendar.removeEvent(document, "keydown", Calendar._keyEvent);
+               Calendar.removeEvent(document, "keypress", Calendar._keyEvent);
+               Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar);
+       }
+       this.element.style.display = "none";
+       this.hidden = true;
+       this.hideShowCovered();
+};
+
+/**
+ *  Shows the calendar at a given absolute position (beware that, depending on
+ *  the calendar element style -- position property -- this might be relative
+ *  to the parent's containing rectangle).
+ */
+Calendar.prototype.showAt = function (x, y) {
+       var s = this.element.style;
+       s.left = x + "px";
+       s.top = y + "px";
+       this.show();
+};
+
+/** Shows the calendar near a given element. */
+Calendar.prototype.showAtElement = function (el, opts) {
+       var self = this;
+       var p = Calendar.getAbsolutePos(el);
+       if (!opts || typeof opts != "string") {
+               this.showAt(p.x, p.y + el.offsetHeight);
+               return true;
+       }
+       this.element.style.display = "block";
+       Calendar.continuation_for_the_fucking_khtml_browser = function() {
+               var w = self.element.offsetWidth;
+               var h = self.element.offsetHeight;
+               self.element.style.display = "none";
+               var valign = opts.substr(0, 1);
+               var halign = "l";
+               if (opts.length > 1) {
+                       halign = opts.substr(1, 1);
+               }
+               // vertical alignment
+               switch (valign) {
+                   case "T": p.y -= h; break;
+                   case "B": p.y += el.offsetHeight; break;
+                   case "C": p.y += (el.offsetHeight - h) / 2; break;
+                   case "t": p.y += el.offsetHeight - h; break;
+                   case "b": break; // already there
+               }
+               // horizontal alignment
+               switch (halign) {
+                   case "L": p.x -= w; break;
+                   case "R": p.x += el.offsetWidth; break;
+                   case "C": p.x += (el.offsetWidth - w) / 2; break;
+                   case "r": p.x += el.offsetWidth - w; break;
+                   case "l": break; // already there
+               }
+               self.showAt(p.x, p.y);
+       };
+       if (Calendar.is_khtml)
+               setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
+       else
+               Calendar.continuation_for_the_fucking_khtml_browser();
+};
+
+/** Customizes the date format. */
+Calendar.prototype.setDateFormat = function (str) {
+       this.dateFormat = str;
+};
+
+/** Customizes the tooltip date format. */
+Calendar.prototype.setTtDateFormat = function (str) {
+       this.ttDateFormat = str;
+};
+
+/**
+ *  Tries to identify the date represented in a string.  If successful it also
+ *  calls this.setDate which moves the calendar to the given date.
+ */
+Calendar.prototype.parseDate = function (str, fmt) {
+       var y = 0;
+       var m = -1;
+       var d = 0;
+       var a = str.split(/\W+/);
+       if (!fmt) {
+               fmt = this.dateFormat;
+       }
+       var b = [];
+       fmt.replace(/(%.)/g, function(str, par) {
+               return b[b.length] = par;
+       });
+       var i = 0, j = 0;
+       var hr = 0;
+       var min = 0;
+       for (i = 0; i < a.length; ++i) {
+               if (b[i] == "%a" || b[i] == "%A") {
+                       continue;
+               }
+               if (b[i] == "%d" || b[i] == "%e") {
+                       d = parseInt(a[i], 10);
+               }
+               if (b[i] == "%m") {
+                       m = parseInt(a[i], 10) - 1;
+               }
+               if (b[i] == "%Y" || b[i] == "%y") {
+                       y = parseInt(a[i], 10);
+                       (y < 100) && (y += (y > 29) ? 1900 : 2000);
+               }
+               if (b[i] == "%b" || b[i] == "%B") {
+                       for (j = 0; j < 12; ++j) {
+                               if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
+                       }
+               } else if (/%[HIkl]/.test(b[i])) {
+                       hr = parseInt(a[i], 10);
+               } else if (/%[pP]/.test(b[i])) {
+                       if (/pm/i.test(a[i]) && hr < 12)
+                               hr += 12;
+               } else if (b[i] == "%M") {
+                       min = parseInt(a[i], 10);
+               }
+       }
+       if (y != 0 && m != -1 && d != 0) {
+               this.setDate(new Date(y, m, d, hr, min, 0));
+               return;
+       }
+       y = 0; m = -1; d = 0;
+       for (i = 0; i < a.length; ++i) {
+               if (a[i].search(/[a-zA-Z]+/) != -1) {
+                       var t = -1;
+                       for (j = 0; j < 12; ++j) {
+                               if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
+                       }
+                       if (t != -1) {
+                               if (m != -1) {
+                                       d = m+1;
+                               }
+                               m = t;
+                       }
+               } else if (parseInt(a[i], 10) <= 12 && m == -1) {
+                       m = a[i]-1;
+               } else if (parseInt(a[i], 10) > 31 && y == 0) {
+                       y = parseInt(a[i], 10);
+                       (y < 100) && (y += (y > 29) ? 1900 : 2000);
+               } else if (d == 0) {
+                       d = a[i];
+               }
+       }
+       if (y == 0) {
+               var today = new Date();
+               y = today.getFullYear();
+       }
+       if (m != -1 && d != 0) {
+               this.setDate(new Date(y, m, d, hr, min, 0));
+       }
+};
+
+Calendar.prototype.hideShowCovered = function () {
+       var self = this;
+       Calendar.continuation_for_the_fucking_khtml_browser = function() {
+               function getVisib(obj){
+                       var value = obj.style.visibility;
+                       if (!value) {
+                               if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
+                                       if (!Calendar.is_khtml)
+                                               value = document.defaultView.
+                                                       getComputedStyle(obj, "").getPropertyValue("visibility");
+                                       else
+                                               value = '';
+                               } else if (obj.currentStyle) { // IE
+                                       value = obj.currentStyle.visibility;
+                               } else
+                                       value = '';
+                       }
+                       return value;
+               };
+
+               var tags = new Array("applet", "iframe", "select");
+               var el = self.element;
+
+               var p = Calendar.getAbsolutePos(el);
+               var EX1 = p.x;
+               var EX2 = el.offsetWidth + EX1;
+               var EY1 = p.y;
+               var EY2 = el.offsetHeight + EY1;
+
+               for (var k = tags.length; k > 0; ) {
+                       var ar = document.getElementsByTagName(tags[--k]);
+                       var cc = null;
+
+                       for (var i = ar.length; i > 0;) {
+                               cc = ar[--i];
+
+                               p = Calendar.getAbsolutePos(cc);
+                               var CX1 = p.x;
+                               var CX2 = cc.offsetWidth + CX1;
+                               var CY1 = p.y;
+                               var CY2 = cc.offsetHeight + CY1;
+
+                               if (self.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
+                                       if (!cc.__msh_save_visibility) {
+                                               cc.__msh_save_visibility = getVisib(cc);
+                                       }
+                                       cc.style.visibility = cc.__msh_save_visibility;
+                               } else {
+                                       if (!cc.__msh_save_visibility) {
+                                               cc.__msh_save_visibility = getVisib(cc);
+                                       }
+                                       cc.style.visibility = "hidden";
+                               }
+                       }
+               }
+       };
+       if (Calendar.is_khtml)
+               setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
+       else
+               Calendar.continuation_for_the_fucking_khtml_browser();
+};
+
+/** Internal function; it displays the bar with the names of the weekday. */
+Calendar.prototype._displayWeekdays = function () {
+       var MON = this.mondayFirst ? 0 : 1;
+       var SUN = this.mondayFirst ? 6 : 0;
+       var SAT = this.mondayFirst ? 5 : 6;
+       var cell = this.firstdayname;
+       for (var i = 0; i < 7; ++i) {
+               cell.className = "day name";
+               if (!i) {
+                       cell.ttip = this.mondayFirst ? Calendar._TT["SUN_FIRST"] : Calendar._TT["MON_FIRST"];
+                       cell.navtype = 100;
+                       cell.calendar = this;
+                       Calendar._add_evs(cell);
+               }
+               if (i == SUN || i == SAT) {
+                       Calendar.addClass(cell, "weekend");
+               }
+               cell.firstChild.data = Calendar._SDN[i + 1 - MON];
+               cell = cell.nextSibling;
+       }
+};
+
+/** Internal function.  Hides all combo boxes that might be displayed. */
+Calendar.prototype._hideCombos = function () {
+       this.monthsCombo.style.display = "none";
+       this.yearsCombo.style.display = "none";
+};
+
+/** Internal function.  Starts dragging the element. */
+Calendar.prototype._dragStart = function (ev) {
+       if (this.dragging) {
+               return;
+       }
+       this.dragging = true;
+       var posX;
+       var posY;
+       if (Calendar.is_ie) {
+               posY = window.event.clientY + document.body.scrollTop;
+               posX = window.event.clientX + document.body.scrollLeft;
+       } else {
+               posY = ev.clientY + window.scrollY;
+               posX = ev.clientX + window.scrollX;
+       }
+       var st = this.element.style;
+       this.xOffs = posX - parseInt(st.left);
+       this.yOffs = posY - parseInt(st.top);
+       with (Calendar) {
+               addEvent(document, "mousemove", calDragIt);
+               addEvent(document, "mouseover", stopEvent);
+               addEvent(document, "mouseup", calDragEnd);
+       }
+};
+
+// BEGIN: DATE OBJECT PATCHES
+
+/** Adds the number of days array to the Date object. */
+Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
+
+/** Constants used for time computations */
+Date.SECOND = 1000 /* milliseconds */;
+Date.MINUTE = 60 * Date.SECOND;
+Date.HOUR   = 60 * Date.MINUTE;
+Date.DAY    = 24 * Date.HOUR;
+Date.WEEK   =  7 * Date.DAY;
+
+/** Returns the number of days in the current month */
+Date.prototype.getMonthDays = function(month) {
+       var year = this.getFullYear();
+       if (typeof month == "undefined") {
+               month = this.getMonth();
+       }
+       if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
+               return 29;
+       } else {
+               return Date._MD[month];
+       }
+};
+
+/** Returns the number of day in the year. */
+Date.prototype.getDayOfYear = function() {
+       var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
+       var then = new Date(this.getFullYear(), 0, 1, 0, 0, 0);
+       var time = now - then;
+       return Math.floor(time / Date.DAY);
+};
+
+/** Returns the number of the week in year, as defined in ISO 8601. */
+Date.prototype.getWeekNumber = function() {
+       var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
+       var then = new Date(this.getFullYear(), 0, 1, 0, 0, 0);
+       var time = now - then;
+       var day = then.getDay(); // 0 means Sunday
+       if (day == 0) day = 7;
+       (day > 4) && (day -= 4) || (day += 3);
+       return Math.round(((time / Date.DAY) + day) / 7);
+};
+
+/** Checks dates equality (ignores time) */
+Date.prototype.equalsTo = function(date) {
+       return ((this.getFullYear() == date.getFullYear()) &&
+               (this.getMonth() == date.getMonth()) &&
+               (this.getDate() == date.getDate()) &&
+               (this.getHours() == date.getHours()) &&
+               (this.getMinutes() == date.getMinutes()));
+};
+
+/** Prints the date in a string according to the given format. */
+Date.prototype.print = function (str) {
+       var m = this.getMonth();
+       var d = this.getDate();
+       var y = this.getFullYear();
+       var wn = this.getWeekNumber();
+       var w = this.getDay();
+       var s = {};
+       var hr = this.getHours();
+       var pm = (hr >= 12);
+       var ir = (pm) ? (hr - 12) : hr;
+       var dy = this.getDayOfYear();
+       if (ir == 0)
+               ir = 12;
+       var min = this.getMinutes();
+       var sec = this.getSeconds();
+       s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N]
+       s["%A"] = Calendar._DN[w]; // full weekday name
+       s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N]
+       s["%B"] = Calendar._MN[m]; // full month name
+       // FIXME: %c : preferred date and time representation for the current locale
+       s["%C"] = 1 + Math.floor(y / 100); // the century number
+       s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
+       s["%e"] = d; // the day of the month (range 1 to 31)
+       // FIXME: %D : american date style: %m/%d/%y
+       // FIXME: %E, %F, %G, %g, %h (man strftime)
+       s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
+       s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
+       s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
+       s["%k"] = hr;           // hour, range 0 to 23 (24h format)
+       s["%l"] = ir;           // hour, range 1 to 12 (12h format)
+       s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
+       s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
+       s["%n"] = "\n";         // a newline character
+       s["%p"] = pm ? "PM" : "AM";
+       s["%P"] = pm ? "pm" : "am";
+       // FIXME: %r : the time in am/pm notation %I:%M:%S %p
+       // FIXME: %R : the time in 24-hour notation %H:%M
+       s["%s"] = Math.floor(this.getTime() / 1000);
+       s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
+       s["%t"] = "\t";         // a tab character
+       // FIXME: %T : the time in 24-hour notation (%H:%M:%S)
+       s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
+       s["%u"] = w + 1;        // the day of the week (range 1 to 7, 1 = MON)
+       s["%w"] = w;            // the day of the week (range 0 to 6, 0 = SUN)
+       // FIXME: %x : preferred date representation for the current locale without the time
+       // FIXME: %X : preferred time representation for the current locale without the date
+       s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
+       s["%Y"] = y;            // year with the century
+       s["%%"] = "%";          // a literal '%' character
+       var re = Date._msh_formatRegexp;
+       if (typeof re == "undefined") {
+               var tmp = "";
+               for (var i in s)
+                       tmp += tmp ? ("|" + i) : i;
+               Date._msh_formatRegexp = re = new RegExp("(" + tmp + ")", 'g');
+       }
+       return str.replace(re, function(match, par) { return s[par]; });
+};
+
+// END: DATE OBJECT PATCHES
+
+// global object that remembers the calendar
+window.calendar = null;
diff --git a/httemplate/elements/calendar_stripped.js b/httemplate/elements/calendar_stripped.js
new file mode 100644 (file)
index 0000000..029496a
--- /dev/null
@@ -0,0 +1,12 @@
+/*  Copyright Mihai Bazon, 2002, 2003  |  http://dynarch.com/mishoo/
+ * ------------------------------------------------------------------
+ *
+ * The DHTML Calendar, version 0.9.5 "Your favorite time, bis"
+ *
+ * Details and latest version at:
+ * http://dynarch.com/mishoo/calendar.epl
+ *
+ * This script is distributed under the GNU Lesser General Public License.
+ * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
+ */
+ Calendar=function(mondayFirst,dateStr,onSelected,onClose){this.activeDiv=null;this.currentDateEl=null;this.getDateStatus=null;this.timeout=null;this.onSelected=onSelected||null;this.onClose=onClose||null;this.dragging=false;this.hidden=false;this.minYear=1970;this.maxYear=2050;this.dateFormat=Calendar._TT["DEF_DATE_FORMAT"];this.ttDateFormat=Calendar._TT["TT_DATE_FORMAT"];this.isPopup=true;this.weekNumbers=true;this.mondayFirst=mondayFirst;this.dateStr=dateStr;this.ar_days=null;this.showsTime=false;this.time24=true;this.table=null;this.element=null;this.tbody=null;this.firstdayname=null;this.monthsCombo=null;this.yearsCombo=null;this.hilitedMonth=null;this.activeMonth=null;this.hilitedYear=null;this.activeYear=null;this.dateClicked=false;if(typeof Calendar._SDN=="undefined"){if(typeof Calendar._SDN_len=="undefined")Calendar._SDN_len=3;var ar=new Array();for(var i=8;i>0;){ar[--i]=Calendar._DN[i].substr(0,Calendar._SDN_len);}Calendar._SDN=ar;if(typeof Calendar._SMN_len=="undefined")Calendar._SMN_len=3;ar=new Array();for(var i=12;i>0;){ar[--i]=Calendar._MN[i].substr(0,Calendar._SMN_len);}Calendar._SMN=ar;}};Calendar._C=null;Calendar.is_ie=(/msie/i.test(navigator.userAgent)&&!/opera/i.test(navigator.userAgent));Calendar.is_opera=/opera/i.test(navigator.userAgent);Calendar.is_khtml=/Konqueror|Safari|KHTML/i.test(navigator.userAgent);Calendar.getAbsolutePos=function(el){var SL=0,ST=0;var is_div=/^div$/i.test(el.tagName);if(is_div&&el.scrollLeft)SL=el.scrollLeft;if(is_div&&el.scrollTop)ST=el.scrollTop;var r={x:el.offsetLeft-SL,y:el.offsetTop-ST};if(el.offsetParent){var tmp=Calendar.getAbsolutePos(el.offsetParent);r.x+=tmp.x;r.y+=tmp.y;}return r;};Calendar.isRelated=function(el,evt){var related=evt.relatedTarget;if(!related){var type=evt.type;if(type=="mouseover"){related=evt.fromElement;}else if(type=="mouseout"){related=evt.toElement;}}while(related){if(related==el){return true;}related=related.parentNode;}return false;};Calendar.removeClass=function(el,className){if(!(el&&el.className)){return;}var cls=el.className.split(" ");var ar=new Array();for(var i=cls.length;i>0;){if(cls[--i]!=className){ar[ar.length]=cls[i];}}el.className=ar.join(" ");};Calendar.addClass=function(el,className){Calendar.removeClass(el,className);el.className+=" "+className;};Calendar.getElement=function(ev){if(Calendar.is_ie){return window.event.srcElement;}else{return ev.currentTarget;}};Calendar.getTargetElement=function(ev){if(Calendar.is_ie){return window.event.srcElement;}else{return ev.target;}};Calendar.stopEvent=function(ev){ev||(ev=window.event);if(Calendar.is_ie){ev.cancelBubble=true;ev.returnValue=false;}else{ev.preventDefault();ev.stopPropagation();}return false;};Calendar.addEvent=function(el,evname,func){if(el.attachEvent){el.attachEvent("on"+evname,func);}else if(el.addEventListener){el.addEventListener(evname,func,true);}else{el["on"+evname]=func;}};Calendar.removeEvent=function(el,evname,func){if(el.detachEvent){el.detachEvent("on"+evname,func);}else if(el.removeEventListener){el.removeEventListener(evname,func,true);}else{el["on"+evname]=null;}};Calendar.createElement=function(type,parent){var el=null;if(document.createElementNS){el=document.createElementNS("http://www.w3.org/1999/xhtml",type);}else{el=document.createElement(type);}if(typeof parent!="undefined"){parent.appendChild(el);}return el;};Calendar._add_evs=function(el){with(Calendar){addEvent(el,"mouseover",dayMouseOver);addEvent(el,"mousedown",dayMouseDown);addEvent(el,"mouseout",dayMouseOut);if(is_ie){addEvent(el,"dblclick",dayMouseDblClick);el.setAttribute("unselectable",true);}}};Calendar.findMonth=function(el){if(typeof el.month!="undefined"){return el;}else if(typeof el.parentNode.month!="undefined"){return el.parentNode;}return null;};Calendar.findYear=function(el){if(typeof el.year!="undefined"){return el;}else if(typeof el.parentNode.year!="undefined"){return el.parentNode;}return null;};Calendar.showMonthsCombo=function(){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var mc=cal.monthsCombo;if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}if(cal.activeMonth){Calendar.removeClass(cal.activeMonth,"active");}var mon=cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];Calendar.addClass(mon,"active");cal.activeMonth=mon;var s=mc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else s.left=(cd.offsetLeft+cd.offsetWidth-mc.offsetWidth)+"px";s.top=(cd.offsetTop+cd.offsetHeight)+"px";};Calendar.showYearsCombo=function(fwd){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var yc=cal.yearsCombo;if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}if(cal.activeYear){Calendar.removeClass(cal.activeYear,"active");}cal.activeYear=null;var Y=cal.date.getFullYear()+(fwd?1:-1);var yr=yc.firstChild;var show=false;for(var i=12;i>0;--i){if(Y>=cal.minYear&&Y<=cal.maxYear){yr.firstChild.data=Y;yr.year=Y;yr.style.display="block";show=true;}else{yr.style.display="none";}yr=yr.nextSibling;Y+=fwd?2:-2;}if(show){var s=yc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else s.left=(cd.offsetLeft+cd.offsetWidth-yc.offsetWidth)+"px";s.top=(cd.offsetTop+cd.offsetHeight)+"px";}};Calendar.tableMouseUp=function(ev){var cal=Calendar._C;if(!cal){return false;}if(cal.timeout){clearTimeout(cal.timeout);}var el=cal.activeDiv;if(!el){return false;}var target=Calendar.getTargetElement(ev);ev||(ev=window.event);Calendar.removeClass(el,"active");if(target==el||target.parentNode==el){Calendar.cellClick(el,ev);}var mon=Calendar.findMonth(target);var date=null;if(mon){date=new Date(cal.date);if(mon.month!=date.getMonth()){date.setMonth(mon.month);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}else{var year=Calendar.findYear(target);if(year){date=new Date(cal.date);if(year.year!=date.getFullYear()){date.setFullYear(year.year);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}}with(Calendar){removeEvent(document,"mouseup",tableMouseUp);removeEvent(document,"mouseover",tableMouseOver);removeEvent(document,"mousemove",tableMouseOver);cal._hideCombos();_C=null;return stopEvent(ev);}};Calendar.tableMouseOver=function(ev){var cal=Calendar._C;if(!cal){return;}var el=cal.activeDiv;var target=Calendar.getTargetElement(ev);if(target==el||target.parentNode==el){Calendar.addClass(el,"hilite active");Calendar.addClass(el.parentNode,"rowhilite");}else{if(typeof el.navtype=="undefined"||(el.navtype!=50&&(el.navtype==0||Math.abs(el.navtype)>2)))Calendar.removeClass(el,"active");Calendar.removeClass(el,"hilite");Calendar.removeClass(el.parentNode,"rowhilite");}ev||(ev=window.event);if(el.navtype==50&&target!=el){var pos=Calendar.getAbsolutePos(el);var w=el.offsetWidth;var x=ev.clientX;var dx;var decrease=true;if(x>pos.x+w){dx=x-pos.x-w;decrease=false;}else dx=pos.x-x;if(dx<0)dx=0;var range=el._range;var current=el._current;var count=Math.floor(dx/10)%range.length;for(var i=range.length;--i>=0;)if(range[i]==current)break;while(count-->0)if(decrease){if(!(--i in range))i=range.length-1;}else if(!(++i in range))i=0;var newval=range[i];el.firstChild.data=newval;cal.onUpdateTime();}var mon=Calendar.findMonth(target);if(mon){if(mon.month!=cal.date.getMonth()){if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}Calendar.addClass(mon,"hilite");cal.hilitedMonth=mon;}else if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}}else{if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}var year=Calendar.findYear(target);if(year){if(year.year!=cal.date.getFullYear()){if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}Calendar.addClass(year,"hilite");cal.hilitedYear=year;}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}return Calendar.stopEvent(ev);};Calendar.tableMouseDown=function(ev){if(Calendar.getTargetElement(ev)==Calendar.getElement(ev)){return Calendar.stopEvent(ev);}};Calendar.calDragIt=function(ev){var cal=Calendar._C;if(!(cal&&cal.dragging)){return false;}var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft;}else{posX=ev.pageX;posY=ev.pageY;}cal.hideShowCovered();var st=cal.element.style;st.left=(posX-cal.xOffs)+"px";st.top=(posY-cal.yOffs)+"px";return Calendar.stopEvent(ev);};Calendar.calDragEnd=function(ev){var cal=Calendar._C;if(!cal){return false;}cal.dragging=false;with(Calendar){removeEvent(document,"mousemove",calDragIt);removeEvent(document,"mouseover",stopEvent);removeEvent(document,"mouseup",calDragEnd);tableMouseUp(ev);}cal.hideShowCovered();};Calendar.dayMouseDown=function(ev){var el=Calendar.getElement(ev);if(el.disabled){return false;}var cal=el.calendar;cal.activeDiv=el;Calendar._C=cal;if(el.navtype!=300)with(Calendar){if(el.navtype==50)el._current=el.firstChild.data;addClass(el,"hilite active");addEvent(document,"mouseover",tableMouseOver);addEvent(document,"mousemove",tableMouseOver);addEvent(document,"mouseup",tableMouseUp);}else if(cal.isPopup){cal._dragStart(ev);}if(el.navtype==-1||el.navtype==1){if(cal.timeout)clearTimeout(cal.timeout);cal.timeout=setTimeout("Calendar.showMonthsCombo()",250);}else if(el.navtype==-2||el.navtype==2){if(cal.timeout)clearTimeout(cal.timeout);cal.timeout=setTimeout((el.navtype>0)?"Calendar.showYearsCombo(true)":"Calendar.showYearsCombo(false)",250);}else{cal.timeout=null;}return Calendar.stopEvent(ev);};Calendar.dayMouseDblClick=function(ev){Calendar.cellClick(Calendar.getElement(ev),ev||window.event);if(Calendar.is_ie){document.selection.empty();}};Calendar.dayMouseOver=function(ev){var el=Calendar.getElement(ev);if(Calendar.isRelated(el,ev)||Calendar._C||el.disabled){return false;}if(el.ttip){if(el.ttip.substr(0,1)=="_"){var date=null;with(el.calendar.date){date=new Date(getFullYear(),getMonth(),el.caldate);}el.ttip=date.print(el.calendar.ttDateFormat)+el.ttip.substr(1);}el.calendar.tooltips.firstChild.data=el.ttip;}if(el.navtype!=300){Calendar.addClass(el,"hilite");if(el.caldate){Calendar.addClass(el.parentNode,"rowhilite");}}return Calendar.stopEvent(ev);};Calendar.dayMouseOut=function(ev){with(Calendar){var el=getElement(ev);if(isRelated(el,ev)||_C||el.disabled){return false;}removeClass(el,"hilite");if(el.caldate){removeClass(el.parentNode,"rowhilite");}el.calendar.tooltips.firstChild.data=_TT["SEL_DATE"];return stopEvent(ev);}};Calendar.cellClick=function(el,ev){var cal=el.calendar;var closing=false;var newdate=false;var date=null;if(typeof el.navtype=="undefined"){Calendar.removeClass(cal.currentDateEl,"selected");Calendar.addClass(el,"selected");closing=(cal.currentDateEl==el);if(!closing){cal.currentDateEl=el;}cal.date.setDate(el.caldate);date=cal.date;newdate=true;cal.dateClicked=true;}else{if(el.navtype==200){Calendar.removeClass(el,"hilite");cal.callCloseHandler();return;}date=(el.navtype==0)?new Date():new Date(cal.date);cal.dateClicked=false;var year=date.getFullYear();var mon=date.getMonth();function setMonth(m){var day=date.getDate();var max=date.getMonthDays(m);if(day>max){date.setDate(max);}date.setMonth(m);};switch(el.navtype){case 400:Calendar.removeClass(el,"hilite");var text=Calendar._TT["ABOUT"];if(typeof text!="undefined"){text+=cal.showsTime?Calendar._TT["ABOUT_TIME"]:"";}else{text="Help and about box text is not translated into this language.\n"+"If you know this language and you feel generous please update\n"+"the corresponding file in \"lang\" subdir to match calendar-en.js\n"+"and send it back to <mishoo@infoiasi.ro> to get it into the distribution  ;-)\n\n"+"Thank you!\n"+"http://dynarch.com/mishoo/calendar.epl\n";}alert(text);return;case-2:if(year>cal.minYear){date.setFullYear(year-1);}break;case-1:if(mon>0){setMonth(mon-1);}else if(year-->cal.minYear){date.setFullYear(year);setMonth(11);}break;case 1:if(mon<11){setMonth(mon+1);}else if(year<cal.maxYear){date.setFullYear(year+1);setMonth(0);}break;case 2:if(year<cal.maxYear){date.setFullYear(year+1);}break;case 100:cal.setMondayFirst(!cal.mondayFirst);return;case 50:var range=el._range;var current=el.firstChild.data;for(var i=range.length;--i>=0;)if(range[i]==current)break;if(ev&&ev.shiftKey){if(!(--i in range))i=range.length-1;}else if(!(++i in range))i=0;var newval=range[i];el.firstChild.data=newval;cal.onUpdateTime();return;case 0:if((typeof cal.getDateStatus=="function")&&cal.getDateStatus(date,date.getFullYear(),date.getMonth(),date.getDate())){return false;}break;}if(!date.equalsTo(cal.date)){cal.setDate(date);newdate=true;}}if(newdate){cal.callHandler();}if(closing){Calendar.removeClass(el,"hilite");cal.callCloseHandler();}};Calendar.prototype.create=function(_par){var parent=null;if(!_par){parent=document.getElementsByTagName("body")[0];this.isPopup=true;}else{parent=_par;this.isPopup=false;}this.date=this.dateStr?new Date(this.dateStr):new Date();var table=Calendar.createElement("table");this.table=table;table.cellSpacing=0;table.cellPadding=0;table.calendar=this;Calendar.addEvent(table,"mousedown",Calendar.tableMouseDown);var div=Calendar.createElement("div");this.element=div;div.className="calendar";if(this.isPopup){div.style.position="absolute";div.style.display="none";}div.appendChild(table);var thead=Calendar.createElement("thead",table);var cell=null;var row=null;var cal=this;var hh=function(text,cs,navtype){cell=Calendar.createElement("td",row);cell.colSpan=cs;cell.className="button";if(navtype!=0&&Math.abs(navtype)<=2)cell.className+=" nav";Calendar._add_evs(cell);cell.calendar=cal;cell.navtype=navtype;if(text.substr(0,1)!="&"){cell.appendChild(document.createTextNode(text));}else{cell.innerHTML=text;}return cell;};row=Calendar.createElement("tr",thead);var title_length=6;(this.isPopup)&&--title_length;(this.weekNumbers)&&++title_length;hh("?",1,400).ttip=Calendar._TT["INFO"];this.title=hh("",title_length,300);this.title.className="title";if(this.isPopup){this.title.ttip=Calendar._TT["DRAG_TO_MOVE"];this.title.style.cursor="move";hh("&#x00d7;",1,200).ttip=Calendar._TT["CLOSE"];}row=Calendar.createElement("tr",thead);row.className="headrow";this._nav_py=hh("&#x00ab;",1,-2);this._nav_py.ttip=Calendar._TT["PREV_YEAR"];this._nav_pm=hh("&#x2039;",1,-1);this._nav_pm.ttip=Calendar._TT["PREV_MONTH"];this._nav_now=hh(Calendar._TT["TODAY"],this.weekNumbers?4:3,0);this._nav_now.ttip=Calendar._TT["GO_TODAY"];this._nav_nm=hh("&#x203a;",1,1);this._nav_nm.ttip=Calendar._TT["NEXT_MONTH"];this._nav_ny=hh("&#x00bb;",1,2);this._nav_ny.ttip=Calendar._TT["NEXT_YEAR"];row=Calendar.createElement("tr",thead);row.className="daynames";if(this.weekNumbers){cell=Calendar.createElement("td",row);cell.className="name wn";cell.appendChild(document.createTextNode(Calendar._TT["WK"]));}for(var i=7;i>0;--i){cell=Calendar.createElement("td",row);cell.appendChild(document.createTextNode(""));if(!i){cell.navtype=100;cell.calendar=this;Calendar._add_evs(cell);}}this.firstdayname=(this.weekNumbers)?row.firstChild.nextSibling:row.firstChild;this._displayWeekdays();var tbody=Calendar.createElement("tbody",table);this.tbody=tbody;for(i=6;i>0;--i){row=Calendar.createElement("tr",tbody);if(this.weekNumbers){cell=Calendar.createElement("td",row);cell.appendChild(document.createTextNode(""));}for(var j=7;j>0;--j){cell=Calendar.createElement("td",row);cell.appendChild(document.createTextNode(""));cell.calendar=this;Calendar._add_evs(cell);}}if(this.showsTime){row=Calendar.createElement("tr",tbody);row.className="time";cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=2;cell.innerHTML="&nbsp;";cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=this.weekNumbers?4:3;(function(){function makeTimePart(className,init,range_start,range_end){var part=Calendar.createElement("span",cell);part.className=className;part.appendChild(document.createTextNode(init));part.calendar=cal;part.ttip=Calendar._TT["TIME_PART"];part.navtype=50;part._range=[];if(typeof range_start!="number")part._range=range_start;else{for(var i=range_start;i<=range_end;++i){var txt;if(i<10&&range_end>=10)txt='0'+i;else txt=''+i;part._range[part._range.length]=txt;}}Calendar._add_evs(part);return part;};var hrs=cal.date.getHours();var mins=cal.date.getMinutes();var t12=!cal.time24;var pm=(hrs>12);if(t12&&pm)hrs-=12;var H=makeTimePart("hour",hrs,t12?1:0,t12?12:23);var span=Calendar.createElement("span",cell);span.appendChild(document.createTextNode(":"));span.className="colon";var M=makeTimePart("minute",mins,0,59);var AP=null;cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=2;if(t12)AP=makeTimePart("ampm",pm?"pm":"am",["am","pm"]);else cell.innerHTML="&nbsp;";cal.onSetTime=function(){var hrs=this.date.getHours();var mins=this.date.getMinutes();var pm=(hrs>12);if(pm&&t12)hrs-=12;H.firstChild.data=(hrs<10)?("0"+hrs):hrs;M.firstChild.data=(mins<10)?("0"+mins):mins;if(t12)AP.firstChild.data=pm?"pm":"am";};cal.onUpdateTime=function(){var date=this.date;var h=parseInt(H.firstChild.data,10);if(t12){if(/pm/i.test(AP.firstChild.data)&&h<12)h+=12;else if(/am/i.test(AP.firstChild.data)&&h==12)h=0;}var d=date.getDate();var m=date.getMonth();var y=date.getFullYear();date.setHours(h);date.setMinutes(parseInt(M.firstChild.data,10));date.setFullYear(y);date.setMonth(m);date.setDate(d);this.dateClicked=false;this.callHandler();};})();}else{this.onSetTime=this.onUpdateTime=function(){};}var tfoot=Calendar.createElement("tfoot",table);row=Calendar.createElement("tr",tfoot);row.className="footrow";cell=hh(Calendar._TT["SEL_DATE"],this.weekNumbers?8:7,300);cell.className="ttip";if(this.isPopup){cell.ttip=Calendar._TT["DRAG_TO_MOVE"];cell.style.cursor="move";}this.tooltips=cell;div=Calendar.createElement("div",this.element);this.monthsCombo=div;div.className="combo";for(i=0;i<Calendar._MN.length;++i){var mn=Calendar.createElement("div");mn.className=Calendar.is_ie?"label-IEfix":"label";mn.month=i;mn.appendChild(document.createTextNode(Calendar._SMN[i]));div.appendChild(mn);}div=Calendar.createElement("div",this.element);this.yearsCombo=div;div.className="combo";for(i=12;i>0;--i){var yr=Calendar.createElement("div");yr.className=Calendar.is_ie?"label-IEfix":"label";yr.appendChild(document.createTextNode(""));div.appendChild(yr);}this._init(this.mondayFirst,this.date);parent.appendChild(this.element);};Calendar._keyEvent=function(ev){if(!window.calendar){return false;}(Calendar.is_ie)&&(ev=window.event);var cal=window.calendar;var act=(Calendar.is_ie||ev.type=="keypress");if(ev.ctrlKey){switch(ev.keyCode){case 37:act&&Calendar.cellClick(cal._nav_pm);break;case 38:act&&Calendar.cellClick(cal._nav_py);break;case 39:act&&Calendar.cellClick(cal._nav_nm);break;case 40:act&&Calendar.cellClick(cal._nav_ny);break;default:return false;}}else switch(ev.keyCode){case 32:Calendar.cellClick(cal._nav_now);break;case 27:act&&cal.hide();break;case 37:case 38:case 39:case 40:if(act){var date=cal.date.getDate()-1;var el=cal.currentDateEl;var ne=null;var prev=(ev.keyCode==37)||(ev.keyCode==38);switch(ev.keyCode){case 37:(--date>=0)&&(ne=cal.ar_days[date]);break;case 38:date-=7;(date>=0)&&(ne=cal.ar_days[date]);break;case 39:(++date<cal.ar_days.length)&&(ne=cal.ar_days[date]);break;case 40:date+=7;(date<cal.ar_days.length)&&(ne=cal.ar_days[date]);break;}if(!ne){if(prev){Calendar.cellClick(cal._nav_pm);}else{Calendar.cellClick(cal._nav_nm);}date=(prev)?cal.date.getMonthDays():1;el=cal.currentDateEl;ne=cal.ar_days[date-1];}Calendar.removeClass(el,"selected");Calendar.addClass(ne,"selected");cal.date.setDate(ne.caldate);cal.callHandler();cal.currentDateEl=ne;}break;case 13:if(act){cal.callHandler();cal.hide();}break;default:return false;}return Calendar.stopEvent(ev);};Calendar.prototype._init=function(mondayFirst,date){var today=new Date();var year=date.getFullYear();if(year<this.minYear){year=this.minYear;date.setFullYear(year);}else if(year>this.maxYear){year=this.maxYear;date.setFullYear(year);}this.mondayFirst=mondayFirst;this.date=new Date(date);var month=date.getMonth();var mday=date.getDate();var no_days=date.getMonthDays();date.setDate(1);var wday=date.getDay();var MON=mondayFirst?1:0;var SAT=mondayFirst?5:6;var SUN=mondayFirst?6:0;if(mondayFirst){wday=(wday>0)?(wday-1):6;}var iday=1;var row=this.tbody.firstChild;var MN=Calendar._SMN[month];var hasToday=((today.getFullYear()==year)&&(today.getMonth()==month));var todayDate=today.getDate();var week_number=date.getWeekNumber();var ar_days=new Array();for(var i=0;i<6;++i){if(iday>no_days){row.className="emptyrow";row=row.nextSibling;continue;}var cell=row.firstChild;if(this.weekNumbers){cell.className="day wn";cell.firstChild.data=week_number;cell=cell.nextSibling;}++week_number;row.className="daysrow";for(var j=0;j<7;++j){cell.className="day";if((!i&&j<wday)||iday>no_days){cell.innerHTML="&nbsp;";cell.disabled=true;cell=cell.nextSibling;continue;}cell.disabled=false;cell.firstChild.data=iday;if(typeof this.getDateStatus=="function"){date.setDate(iday);var status=this.getDateStatus(date,year,month,iday);if(status===true){cell.className+=" disabled";cell.disabled=true;}else{if(/disabled/i.test(status))cell.disabled=true;cell.className+=" "+status;}}if(!cell.disabled){ar_days[ar_days.length]=cell;cell.caldate=iday;cell.ttip="_";if(iday==mday){cell.className+=" selected";this.currentDateEl=cell;}if(hasToday&&(iday==todayDate)){cell.className+=" today";cell.ttip+=Calendar._TT["PART_TODAY"];}if(wday==SAT||wday==SUN){cell.className+=" weekend";}}++iday;((++wday)^ 7)||(wday=0);cell=cell.nextSibling;}row=row.nextSibling;}this.ar_days=ar_days;this.title.firstChild.data=Calendar._MN[month]+", "+year;this.onSetTime();};Calendar.prototype.setDate=function(date){if(!date.equalsTo(this.date)){this._init(this.mondayFirst,date);}};Calendar.prototype.refresh=function(){this._init(this.mondayFirst,this.date);};Calendar.prototype.setMondayFirst=function(mondayFirst){this._init(mondayFirst,this.date);this._displayWeekdays();};Calendar.prototype.setDateStatusHandler=Calendar.prototype.setDisabledHandler=function(unaryFunction){this.getDateStatus=unaryFunction;};Calendar.prototype.setRange=function(a,z){this.minYear=a;this.maxYear=z;};Calendar.prototype.callHandler=function(){if(this.onSelected){this.onSelected(this,this.date.print(this.dateFormat));}};Calendar.prototype.callCloseHandler=function(){if(this.onClose){this.onClose(this);}this.hideShowCovered();};Calendar.prototype.destroy=function(){var el=this.element.parentNode;el.removeChild(this.element);Calendar._C=null;window.calendar=null;};Calendar.prototype.reparent=function(new_parent){var el=this.element;el.parentNode.removeChild(el);new_parent.appendChild(el);};Calendar._checkCalendar=function(ev){if(!window.calendar){return false;}var el=Calendar.is_ie?Calendar.getElement(ev):Calendar.getTargetElement(ev);for(;el!=null&&el!=calendar.element;el=el.parentNode);if(el==null){window.calendar.callCloseHandler();return Calendar.stopEvent(ev);}};Calendar.prototype.show=function(){var rows=this.table.getElementsByTagName("tr");for(var i=rows.length;i>0;){var row=rows[--i];Calendar.removeClass(row,"rowhilite");var cells=row.getElementsByTagName("td");for(var j=cells.length;j>0;){var cell=cells[--j];Calendar.removeClass(cell,"hilite");Calendar.removeClass(cell,"active");}}this.element.style.display="block";this.hidden=false;if(this.isPopup){window.calendar=this;Calendar.addEvent(document,"keydown",Calendar._keyEvent);Calendar.addEvent(document,"keypress",Calendar._keyEvent);Calendar.addEvent(document,"mousedown",Calendar._checkCalendar);}this.hideShowCovered();};Calendar.prototype.hide=function(){if(this.isPopup){Calendar.removeEvent(document,"keydown",Calendar._keyEvent);Calendar.removeEvent(document,"keypress",Calendar._keyEvent);Calendar.removeEvent(document,"mousedown",Calendar._checkCalendar);}this.element.style.display="none";this.hidden=true;this.hideShowCovered();};Calendar.prototype.showAt=function(x,y){var s=this.element.style;s.left=x+"px";s.top=y+"px";this.show();};Calendar.prototype.showAtElement=function(el,opts){var self=this;var p=Calendar.getAbsolutePos(el);if(!opts||typeof opts!="string"){this.showAt(p.x,p.y+el.offsetHeight);return true;}this.element.style.display="block";Calendar.continuation_for_the_fucking_khtml_browser=function(){var w=self.element.offsetWidth;var h=self.element.offsetHeight;self.element.style.display="none";var valign=opts.substr(0,1);var halign="l";if(opts.length>1){halign=opts.substr(1,1);}switch(valign){case "T":p.y-=h;break;case "B":p.y+=el.offsetHeight;break;case "C":p.y+=(el.offsetHeight-h)/2;break;case "t":p.y+=el.offsetHeight-h;break;case "b":break;}switch(halign){case "L":p.x-=w;break;case "R":p.x+=el.offsetWidth;break;case "C":p.x+=(el.offsetWidth-w)/2;break;case "r":p.x+=el.offsetWidth-w;break;case "l":break;}self.showAt(p.x,p.y);};if(Calendar.is_khtml)setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()",10);else Calendar.continuation_for_the_fucking_khtml_browser();};Calendar.prototype.setDateFormat=function(str){this.dateFormat=str;};Calendar.prototype.setTtDateFormat=function(str){this.ttDateFormat=str;};Calendar.prototype.parseDate=function(str,fmt){var y=0;var m=-1;var d=0;var a=str.split(/\W+/);if(!fmt){fmt=this.dateFormat;}var b=[];fmt.replace(/(%.)/g,function(str,par){return b[b.length]=par;});var i=0,j=0;var hr=0;var min=0;for(i=0;i<a.length;++i){if(b[i]=="%a"||b[i]=="%A"){continue;}if(b[i]=="%d"||b[i]=="%e"){d=parseInt(a[i],10);}if(b[i]=="%m"){m=parseInt(a[i],10)-1;}if(b[i]=="%Y"||b[i]=="%y"){y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);}if(b[i]=="%b"||b[i]=="%B"){for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){m=j;break;}}}else if(/%[HIkl]/.test(b[i])){hr=parseInt(a[i],10);}else if(/%[pP]/.test(b[i])){if(/pm/i.test(a[i])&&hr<12)hr+=12;}else if(b[i]=="%M"){min=parseInt(a[i],10);}}if(y!=0&&m!=-1&&d!=0){this.setDate(new Date(y,m,d,hr,min,0));return;}y=0;m=-1;d=0;for(i=0;i<a.length;++i){if(a[i].search(/[a-zA-Z]+/)!=-1){var t=-1;for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){t=j;break;}}if(t!=-1){if(m!=-1){d=m+1;}m=t;}}else if(parseInt(a[i],10)<=12&&m==-1){m=a[i]-1;}else if(parseInt(a[i],10)>31&&y==0){y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);}else if(d==0){d=a[i];}}if(y==0){var today=new Date();y=today.getFullYear();}if(m!=-1&&d!=0){this.setDate(new Date(y,m,d,hr,min,0));}};Calendar.prototype.hideShowCovered=function(){var self=this;Calendar.continuation_for_the_fucking_khtml_browser=function(){function getVisib(obj){var value=obj.style.visibility;if(!value){if(document.defaultView&&typeof(document.defaultView.getComputedStyle)=="function"){if(!Calendar.is_khtml)value=document.defaultView. getComputedStyle(obj,"").getPropertyValue("visibility");else value='';}else if(obj.currentStyle){value=obj.currentStyle.visibility;}else value='';}return value;};var tags=new Array("applet","iframe","select");var el=self.element;var p=Calendar.getAbsolutePos(el);var EX1=p.x;var EX2=el.offsetWidth+EX1;var EY1=p.y;var EY2=el.offsetHeight+EY1;for(var k=tags.length;k>0;){var ar=document.getElementsByTagName(tags[--k]);var cc=null;for(var i=ar.length;i>0;){cc=ar[--i];p=Calendar.getAbsolutePos(cc);var CX1=p.x;var CX2=cc.offsetWidth+CX1;var CY1=p.y;var CY2=cc.offsetHeight+CY1;if(self.hidden||(CX1>EX2)||(CX2<EX1)||(CY1>EY2)||(CY2<EY1)){if(!cc.__msh_save_visibility){cc.__msh_save_visibility=getVisib(cc);}cc.style.visibility=cc.__msh_save_visibility;}else{if(!cc.__msh_save_visibility){cc.__msh_save_visibility=getVisib(cc);}cc.style.visibility="hidden";}}}};if(Calendar.is_khtml)setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()",10);else Calendar.continuation_for_the_fucking_khtml_browser();};Calendar.prototype._displayWeekdays=function(){var MON=this.mondayFirst?0:1;var SUN=this.mondayFirst?6:0;var SAT=this.mondayFirst?5:6;var cell=this.firstdayname;for(var i=0;i<7;++i){cell.className="day name";if(!i){cell.ttip=this.mondayFirst?Calendar._TT["SUN_FIRST"]:Calendar._TT["MON_FIRST"];cell.navtype=100;cell.calendar=this;Calendar._add_evs(cell);}if(i==SUN||i==SAT){Calendar.addClass(cell,"weekend");}cell.firstChild.data=Calendar._SDN[i+1-MON];cell=cell.nextSibling;}};Calendar.prototype._hideCombos=function(){this.monthsCombo.style.display="none";this.yearsCombo.style.display="none";};Calendar.prototype._dragStart=function(ev){if(this.dragging){return;}this.dragging=true;var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft;}else{posY=ev.clientY+window.scrollY;posX=ev.clientX+window.scrollX;}var st=this.element.style;this.xOffs=posX-parseInt(st.left);this.yOffs=posY-parseInt(st.top);with(Calendar){addEvent(document,"mousemove",calDragIt);addEvent(document,"mouseover",stopEvent);addEvent(document,"mouseup",calDragEnd);}};Date._MD=new Array(31,28,31,30,31,30,31,31,30,31,30,31);Date.SECOND=1000;Date.MINUTE=60*Date.SECOND;Date.HOUR=60*Date.MINUTE;Date.DAY=24*Date.HOUR;Date.WEEK=7*Date.DAY;Date.prototype.getMonthDays=function(month){var year=this.getFullYear();if(typeof month=="undefined"){month=this.getMonth();}if(((0==(year%4))&&((0!=(year%100))||(0==(year%400))))&&month==1){return 29;}else{return Date._MD[month];}};Date.prototype.getDayOfYear=function(){var now=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var then=new Date(this.getFullYear(),0,1,0,0,0);var time=now-then;return Math.floor(time/Date.DAY);};Date.prototype.getWeekNumber=function(){var now=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var then=new Date(this.getFullYear(),0,1,0,0,0);var time=now-then;var day=then.getDay();if(day==0)day=7;(day>4)&&(day-=4)||(day+=3);return Math.round(((time/Date.DAY)+day)/7);};Date.prototype.equalsTo=function(date){return((this.getFullYear()==date.getFullYear())&&(this.getMonth()==date.getMonth())&&(this.getDate()==date.getDate())&&(this.getHours()==date.getHours())&&(this.getMinutes()==date.getMinutes()));};Date.prototype.print=function(str){var m=this.getMonth();var d=this.getDate();var y=this.getFullYear();var wn=this.getWeekNumber();var w=this.getDay();var s={};var hr=this.getHours();var pm=(hr>=12);var ir=(pm)?(hr-12):hr;var dy=this.getDayOfYear();if(ir==0)ir=12;var min=this.getMinutes();var sec=this.getSeconds();s["%a"]=Calendar._SDN[w];s["%A"]=Calendar._DN[w];s["%b"]=Calendar._SMN[m];s["%B"]=Calendar._MN[m];s["%C"]=1+Math.floor(y/100);s["%d"]=(d<10)?("0"+d):d;s["%e"]=d;s["%H"]=(hr<10)?("0"+hr):hr;s["%I"]=(ir<10)?("0"+ir):ir;s["%j"]=(dy<100)?((dy<10)?("00"+dy):("0"+dy)):dy;s["%k"]=hr;s["%l"]=ir;s["%m"]=(m<9)?("0"+(1+m)):(1+m);s["%M"]=(min<10)?("0"+min):min;s["%n"]="\n";s["%p"]=pm?"PM":"AM";s["%P"]=pm?"pm":"am";s["%s"]=Math.floor(this.getTime()/1000);s["%S"]=(sec<10)?("0"+sec):sec;s["%t"]="\t";s["%U"]=s["%W"]=s["%V"]=(wn<10)?("0"+wn):wn;s["%u"]=w+1;s["%w"]=w;s["%y"]=(''+y).substr(2,2);s["%Y"]=y;s["%%"]="%";var re=Date._msh_formatRegexp;if(typeof re=="undefined"){var tmp="";for(var i in s)tmp+=tmp?("|"+i):i;Date._msh_formatRegexp=re=new RegExp("("+tmp+")",'g');}return str.replace(re,function(match,par){return s[par];});};window.calendar=null;
\ No newline at end of file
diff --git a/httemplate/elements/header.html b/httemplate/elements/header.html
new file mode 100644 (file)
index 0000000..581bbab
--- /dev/null
@@ -0,0 +1,19 @@
+<%
+  my($title, $menubar) = @_;
+  my $etc = @_ ? shift : ''; #$etc is for things like onLoad= etc.
+%>
+    <HTML>
+      <HEAD>
+        <TITLE>
+          <%= $title %>
+        </TITLE>
+        <META HTTP-Equiv="Cache-Control" Content="no-cache">
+        <META HTTP-Equiv="Pragma" Content="no-cache">
+        <META HTTP-Equiv="Expires" Content="0"> 
+      </HEAD>
+      <BODY BGCOLOR="#e8e8e8"<%= $etc %>>
+          <FONT SIZE=7>
+            <%= $title %>
+          </FONT>
+          <BR><BR>
+          <%= $menubar ? "$menubar<BR><BR>" : '' %>
diff --git a/httemplate/elements/menubar.html b/httemplate/elements/menubar.html
new file mode 100644 (file)
index 0000000..87a5031
--- /dev/null
@@ -0,0 +1,8 @@
+<%
+  my($item, $url, @html);
+  while (@_) {
+    ($item, $url) = splice(@_,0,2);
+    push @html, qq!<A HREF="$url">$item</A>!;
+  }
+%>
+<%= join(' | ', @html) %>
diff --git a/httemplate/elements/pager.html b/httemplate/elements/pager.html
new file mode 100644 (file)
index 0000000..db9ff83
--- /dev/null
@@ -0,0 +1,42 @@
+<%
+
+  my %opt = @_;
+
+  my $pager = '';
+  if ( $opt{'total'} != $opt{'num_rows'} && $opt{'maxrecords'} ) {
+    unless ( $opt{'offset'} == 0 ) {
+      $cgi->param('offset', $opt{'offset'} - $opt{'maxrecords'});
+%>
+
+      <A HREF="<%= $cgi->self_url %>"><B><FONT SIZE="+1">Previous</FONT></B></A>
+
+<%
+    }
+    my $page = 0;
+    for ( my $poff = 0; $poff < $opt{'total'}; $poff += $opt{'maxrecords'} ) {
+      $page++;
+      if ( $opt{'offset'} == $poff ) {
+%>
+
+        <FONT SIZE="+2"><%= $page %></FONT>
+
+<%
+      } else {
+        $cgi->param('offset', $poff);
+%>
+
+        <A HREF="<%= $cgi->self_url %>">$page</A>
+
+<%
+      }
+    }
+    unless ( $opt{'offset'} + $opt{'maxrecords'} > $opt{'total'} ) {
+      $cgi->param('offset', $opt{'offset'} + $opt{'maxrecords'});
+%>
+
+      <A HREF="<%= $cgi->self_url %>"><B><FONT SIZE="+1">Next</FONT></B></A>
+
+<%
+    }
+  }
+%>
diff --git a/httemplate/elements/table.html b/httemplate/elements/table.html
new file mode 100644 (file)
index 0000000..3b61087
--- /dev/null
@@ -0,0 +1,8 @@
+<%
+   my $color = shift;
+   if ( $color ) {
+%>
+    <TABLE BGCOLOR="<%= $color %>" BORDER=1 WIDTH="100%" CELLSPACING=0 CELLPADDING=2 BORDERCOLOR="#999999">
+<% } else { %>
+    <TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2 BORDERCOLOR="#999999">
+<% } %>
diff --git a/httemplate/graph/money_time-graph.cgi b/httemplate/graph/money_time-graph.cgi
new file mode 100755 (executable)
index 0000000..76f1bd7
--- /dev/null
@@ -0,0 +1,108 @@
+<%
+
+#my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
+my ($curmon,$curyear) = (localtime(time))[4,5];
+
+#find first month
+my $syear = $cgi->param('syear') || 1899+$curyear;
+my $smonth = $cgi->param('smonth') || $curmon+1;
+
+#find last month
+my $eyear = $cgi->param('eyear') || 1900+$curyear;
+my $emonth = $cgi->param('emonth') || $curmon+1;
+if ( $emonth++>12 ) { $emonth-=12; $eyear++; }
+
+my @labels;
+my %data;
+
+while ( $syear < $eyear || ( $syear == $eyear && $smonth < $emonth ) ) {
+  push @labels, "$smonth/$syear";
+
+  my $speriod = timelocal(0,0,0,1,$smonth-1,$syear);
+  if ( ++$smonth == 13 ) { $syear++; $smonth=1; }
+  my $eperiod = timelocal(0,0,0,1,$smonth-1,$syear);
+
+  my $where = "WHERE _date >= $speriod AND _date < $eperiod";
+
+  # Invoiced
+  my $charged_sql = "SELECT SUM(charged) FROM cust_bill $where";
+  my $charged_sth = dbh->prepare($charged_sql) or die dbh->errstr;
+  $charged_sth->execute or die $charged_sth->errstr;
+  my $charged = $charged_sth->fetchrow_arrayref->[0] || 0;
+
+  push @{$data{charged}}, $charged;
+
+  #accounts receivable
+#  my $ar_sql2 = "SELECT SUM(amount) FROM cust_credit $where";
+  my $credited_sql = "SELECT SUM(cust_credit_bill.amount) FROM cust_credit_bill, cust_bill WHERE cust_bill.invnum = cust_credit_bill.invnum AND cust_bill._date >= $speriod AND cust_bill._date < $eperiod";
+  my $credited_sth = dbh->prepare($credited_sql) or die dbh->errstr;
+  $credited_sth->execute or die $credited_sth->errstr;
+  my $credited = $credited_sth->fetchrow_arrayref->[0] || 0;
+
+    #horrible local kludge
+    my $expenses_sql = "SELECT SUM(cust_bill_pkg.setup) FROM cust_bill_pkg, cust_bill, cust_pkg, part_pkg WHERE cust_bill.invnum = cust_bill_pkg.invnum AND cust_bill._date >= $speriod AND cust_bill._date < $eperiod AND cust_pkg.pkgnum = cust_bill_pkg.pkgnum AND cust_pkg.pkgpart = part_pkg.pkgpart AND LOWER(part_pkg.pkg) LIKE 'expense _%'";
+    my $expenses_sth = dbh->prepare($expenses_sql) or die dbh->errstr;
+    $expenses_sth->execute or die $expenses_sth->errstr;
+    my $expenses = $expenses_sth->fetchrow_arrayref->[0] || 0;
+
+  push @{$data{ar}}, $charged-$credited-$expenses;
+
+  #deferred revenue
+#  push @{$data{defer}}, '0';
+
+  #cashflow
+  my $paid_sql = "SELECT SUM(paid) FROM cust_pay $where";
+  my $paid_sth = dbh->prepare($paid_sql) or die dbh->errstr;
+  $paid_sth->execute or die $paid_sth->errstr;
+  my $paid = $paid_sth->fetchrow_arrayref->[0] || 0;
+
+  my $refunded_sql = "SELECT SUM(refund) FROM cust_refund $where";
+  my $refunded_sth = dbh->prepare($refunded_sql) or die dbh->errstr;
+  $refunded_sth->execute or die $refunded_sth->errstr;
+  my $refunded = $refunded_sth->fetchrow_arrayref->[0] || 0;
+
+    #horrible local kludge that doesn't even really work right
+    my $expenses_sql2 = "SELECT SUM(cust_bill_pay.amount) FROM cust_bill_pay, cust_bill WHERE cust_bill_pay.invnum = cust_bill.invnum AND cust_bill_pay._date >= $speriod AND cust_bill_pay._date < $eperiod AND 0 < ( select count(*) from cust_bill_pkg, cust_pkg, part_pkg WHERE cust_bill.invnum = cust_bill_pkg.invnum AND cust_pkg.pkgnum = cust_bill_pkg.pkgnum AND cust_pkg.pkgpart = part_pkg.pkgpart AND LOWER(part_pkg.pkg) LIKE 'expense _%' )";
+
+#    my $expenses_sql2 = "SELECT SUM(cust_bill_pay.amount) FROM cust_bill_pay, cust_bill_pkg, cust_bill, cust_pkg, part_pkg WHERE cust_bill_pay.invnum = cust_bill.invnum AND cust_bill.invnum = cust_bill_pkg.invnum AND cust_bill_pay._date >= $speriod AND cust_bill_pay._date < $eperiod AND cust_pkg.pkgnum = cust_bill_pkg.pkgnum AND cust_pkg.pkgpart = part_pkg.pkgpart AND LOWER(part_pkg.pkg) LIKE 'expense _%'";
+    my $expenses_sth2 = dbh->prepare($expenses_sql2) or die dbh->errstr;
+    $expenses_sth2->execute or die $expenses_sth2->errstr;
+    my $expenses2 = $expenses_sth2->fetchrow_arrayref->[0] || 0;
+
+  push @{$data{cash}}, $paid-$refunded-$expenses2;
+
+}
+
+#my $chart = Chart::LinesPoints->new(1024,480);
+my $chart = Chart::LinesPoints->new(768,480);
+
+$chart->set(
+  #'min_val' => 0,
+  'legend' => 'bottom',
+  'legend_labels' => [ #'Invoiced (cust_bill)',
+                       'Accounts receivable (invoices - applied credits)',
+                       #'Deferred revenue',
+                       'Actual cashflow (payments - refunds)' ],
+);
+
+my @data = ( \@labels,
+             #map $data{$_}, qw( ar defer cash )
+             #map $data{$_}, qw( charged ar cash )
+             map $data{$_}, qw( ar cash )
+           );
+
+#my $gd = $chart->plot(\@data);
+#open (IMG, ">i_r_c.png");
+#print IMG $gd->png;
+#close IMG;
+
+#$chart->png("i_r_c.png", \@data);
+
+#$chart->cgi_png(\@data);
+
+http_header('Content-Type' => 'image/png' );
+#$Response->{ContentType} = 'image/png';
+
+$chart->_set_colors();
+
+%><%= $chart->scalar_png(\@data) %>
diff --git a/httemplate/graph/money_time.cgi b/httemplate/graph/money_time.cgi
new file mode 100644 (file)
index 0000000..de8f6ee
--- /dev/null
@@ -0,0 +1,59 @@
+<!-- mason kludge -->
+<%
+
+#my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
+my ($curmon,$curyear) = (localtime(time))[4,5];
+
+#find first month
+my $syear = $cgi->param('syear') || 1899+$curyear;
+my $smonth = $cgi->param('smonth') || $curmon+1;
+
+#find last month
+my $eyear = $cgi->param('eyear') || 1900+$curyear;
+my $emonth = $cgi->param('emonth') || $curmon+1;
+
+%>
+
+<HTML>
+  <HEAD>
+    <TITLE>Graphing monetary values over time</TITLE>
+  </HEAD>
+<BODY BGCOLOR="#e8e8e8">
+<IMG SRC="money_time-graph.cgi?<%= $cgi->query_string %>" WIDTH="768" HEIGHT="480">
+<BR>
+<FORM METHOD="POST">
+<INPUT TYPE="checkbox" NAME="ar">
+  Accounts receivable (invoices - applied credits)<BR>
+<INPUT TYPE="checkbox" NAME="charged">
+  Just Invoices<BR>
+<INPUT TYPE="checkbox" NAME="defer">
+  Accounts receivable, with deferred revenue (invoices - applied credits, with charges for annual/semi-annual/quarterly/etc. services deferred over applicable time period) (there has got to be a shorter description for this)<BR>
+<INPUT TYPE="checkbox" NAME="cash">
+  Cashflow (payments - refunds)<BR>
+<BR>
+From <SELECT NAME="smonth">
+<% my @mon = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); %>
+<% foreach my $mon ( 1..12 ) { %>
+<OPTION VALUE="<%= $mon %>"<%= $mon == $smonth ? ' SELECTED' : '' %>><%= $mon[$mon-1] %>
+<% } %>
+</SELECT>
+<SELECT NAME="syear">
+<% foreach my $y ( 1999 .. 2010 ) { %>
+<OPTION VALUE="<%= $y %>"<%= $y == $syear ? ' SELECTED' : '' %>><%= $y %>
+<% } %>
+</SELECT>
+ to <SELECT NAME="emonth">
+<% foreach my $mon ( 1..12 ) { %>
+<OPTION VALUE="<%= $mon %>"<%= $mon == $emonth ? ' SELECTED' : '' %>><%= $mon[$mon-1] %>
+<% } %>
+</SELECT>
+<SELECT NAME="eyear">
+<% foreach my $y ( 1999 .. 2010 ) { %>
+<OPTION VALUE="<%= $y %>"<%= $y == $eyear ? ' SELECTED' : '' %>><%= $y %>
+<% } %>
+</SELECT>
+
+<INPUT TYPE="submit" VALUE="Graph">
+</FORM>
+</BODY>
+</HTML>
diff --git a/httemplate/images/calendar.png b/httemplate/images/calendar.png
new file mode 100644 (file)
index 0000000..1632661
Binary files /dev/null and b/httemplate/images/calendar.png differ
diff --git a/httemplate/images/cvv2.png b/httemplate/images/cvv2.png
new file mode 100644 (file)
index 0000000..4610dcb
Binary files /dev/null and b/httemplate/images/cvv2.png differ
diff --git a/httemplate/images/cvv2_amex.png b/httemplate/images/cvv2_amex.png
new file mode 100644 (file)
index 0000000..21c36a0
Binary files /dev/null and b/httemplate/images/cvv2_amex.png differ
index 29dd3b4..d39f8b0 100644 (file)
@@ -11,8 +11,8 @@
     </td><td>
       <font color="#ff0000" size=7>freeside main menu</font>
     </td><td align=right valign=bottom>
-      version 1.4.0
-      <BR><A HREF="http://www.sisd.com/freeside">Freeside home page</A>
+       version %%%VERSION%%%
+      <BR><A HREF="http://www.sisd.com/freeside">Freeside&nbsp;home&nbsp;page</A>
       <BR><A HREF="docs/">Documentation</A>
     </td></tr>
   </table>
@@ -22,7 +22,7 @@
 [ <A HREF="#bookkeeping">Bookkeeping / Collections</A> ]
 [ <A HREF="#reports">Reports</A> ]
 [ <A HREF="#sysadmin">Sysadmin</A> ]
-    <TABLE CELLSPACING=2 CELLPADDING=0 BORDERCOLOR="#000000" WIDTH="100%" BGCOLOR="#eeeeee">
+    <TABLE CELLSPACING=2 CELLPADDING=0 BORDER=0" WIDTH="100%" BGCOLOR="#eeeeee">
     <TR><TH BGCOLOR="#cccccc">Sales / Customer service</TH></TR>
     <TR><TD>
         <BR><FONT SIZE="+1"><A HREF="edit/cust_main.cgi">New Customer</A></FONT>
@@ -34,8 +34,8 @@
         <FORM ACTION="search/cust_main.cgi" METHOD="POST"><INPUT TYPE="hidden" NAME="phone_on" VALUE="1">Phone # <INPUT TYPE="text" NAME="phone_text"><INPUT TYPE="submit" VALUE="Search"></FORM>
         <BR><FORM ACTION="search/svc_acct.cgi" METHOD="POST">Username <INPUT TYPE="text" NAME="username"><SELECT NAME="username_type"><OPTION VALUE="All">(all)</OPTION><OPTION>Fuzzy</OPTION><OPTION>Substring</OPTION><OPTION SELECTED>Exact</OPTION></SELECT><INPUT TYPE="submit" VALUE="Search"> or <A HREF="search/svc_acct.cgi?username">all accounts by username</A> or <A HREF="search/svc_acct.cgi?uid">uid</A></FORM>
         <BR><FORM ACTION="search/svc_domain.cgi" METHOD="POST">Domain <INPUT TYPE="text" NAME="domain"><INPUT TYPE="submit" VALUE="Search"> or <A HREF="search/svc_domain.cgi?domain">all domains</A></FORM>
-<!--        <LI><A HREF="search/svc_acct_sm.html">mail aliases (by domain, and optionally username)</A>-->
-<!--        <LI><A HREF="search/svc_forward.html">mail forwards (by ?)</A>-->
+        <BR><A HREF="search/svc_forward.cgi?svcnum">all mail forwards by svcnum</A><BR>
+
       <BR>
     </TD></TR>
     </TABLE>
@@ -49,7 +49,7 @@
 [<A NAME="bookkeeping" style="background-color: #cccccc"> Bookkeeping / Collections </A>]
 [ <A HREF="#reports">Reports</A> ]
 [ <A HREF="#sysadmin">Sysadmin</A> ]
-    <TABLE CELLSPACING=2 CELLPADDING=0 BORDERCOLOR="#000000" WIDTH="100%" BGCOLOR="#eeeeee">
+    <TABLE CELLSPACING=2 CELLPADDING=0 BORDER=0 WIDTH="100%" BGCOLOR="#eeeeee">
     <TR><TH BGCOLOR="#cccccc">Bookkeeping / Collections</TH></TR>
     <TR><TD>
       <BR><A HREF="search/cust_main-quickpay.html">Quick payment entry</A>
@@ -57,7 +57,7 @@
       <BR><FORM ACTION="search/cust_main.cgi" METHOD="POST">Credit card # <INPUT TYPE="hidden" NAME="card_on" VALUE="1"><INPUT TYPE="text" NAME="card"><INPUT TYPE="submit" VALUE="Search"></FORM>
       <FORM ACTION="search/cust_bill.cgi" METHOD="POST">Invoice # <INPUT TYPE="text" NAME="invnum" SIZE="8"><INPUT TYPE="submit" VALUE="Search"></FORM>
       <FORM ACTION="search/cust_pay.cgi" METHOD="POST">Check # <INPUT TYPE="text" NAME="payinfo" SIZE="8"><INPUT TYPE="hidden" NAME="payby" VALUE="BILL"><INPUT TYPE="submit" VALUE="Search"></FORM>
-      <BR><A HREF="browse/cust_pay_batch.cgi">View pending credit card batch</A>      <BR><BR><A HREF="search/cust_pkg.html">Packages (by next bill date range)</A>
+      <BR><A HREF="browse/cust_pay_batch.cgi">View pending credit card batch</A>      <BR><BR><A HREF="search/cust_pkg_report.cgi">Packages (by next bill date range)</A>
       <BR><BR>Invoice reports
             <UL>
               <LI><a href="search/cust_bill_event.html">Invoice event errors (failed credit cards)</a>
               <LI>120 day open invoices (<A HREF="search/cust_bill.cgi?OPEN120_invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?OPEN120_date">by date</A>) (<A HREF="search/cust_bill.cgi?OPEN120_custnum">by customer number</A>)
               <LI>all invoices (<A HREF="search/cust_bill.cgi?invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?date">by date</A>) (<A HREF="search/cust_bill.cgi?custnum">by customer number</A>)
             </UL>
-      Financial reports
+      <A HREF="search/report_cust_pay.html">Payment report (by type and/or date range)</A>
+      <BR><BR><A HREF="search/report_receivables.cgi">Accounts Receivable Aging Summary</A>
+      <BR><BR><A HREF="search/report_prepaid_income.html">Prepaid Income (Unearned Revenue) Report</A>
+      <BR><BR>(old) Financial reports (being rewritten)
             <UL>
-              <LI> <A HREF="search/report_receivables.cgi">current receivables</A>
               <LI> <A HREF="search/report_tax.html">tax reports</A>
               <LI> <A HREF="search/report_cc.html">credit card receipts</A>
               <LI> <A HREF="search/report_credit.html">credit memos</A>
 [ <A HREF="#bookkeeping">Bookkeeping / Collections</A> ]
 [<A NAME="reports" style="background-color: #cccccc"> Reports </A>]
 [ <A HREF="#sysadmin">Sysadmin</A> ]
-    <TABLE CELLSPACING=2 CELLPADDING=0 BORDERCOLOR="#000000" WIDTH="100%" BGCOLOR="#eeeeee">
+    <TABLE CELLSPACING=2 CELLPADDING=0 BORDER=0 WIDTH="100%" BGCOLOR="#eeeeee">
     <TR><TH BGCOLOR="#cccccc">Reports</TH></TR>
     <TR><TD>
       <BR>
       Auditing pre-Freeside services with no customer record
       <UL>
         <LI>unlinked accounts (<A HREF="search/svc_acct.cgi?UN_svcnum">by service number</A>) (<A HREF="search/svc_acct.cgi?UN_username">by username</A>) (<A HREF="search/svc_acct.cgi?UN_uid">by uid</A>)
-        <LI>unlinked mail forwards (<A HREF="search/svc_forward.cgi?UN_svcnum">by service number</A>) (by ?))
+<!--        <LI>unlinked mail forwards (<A HREF="search/svc_forward.cgi?UN_svcnum">by service number</A>) (by ?)) -->
         <LI>unlinked domains (<A HREF="search/svc_domain.cgi?UN_svcnum">by service number</A>) (<A HREF="search/svc_domain.cgi?UN_domain">by domain</A>)
       </UL>
       Packages
       <UL>
-        <LI><A HREF="search/cust_pkg.cgi?pkgnum">packages (by package number)</A>
+        <LI><A HREF="search/cust_pkg.cgi?pkgnum">all packages (by package number)</A>
+        <LI><A HREF="search/cust_pkg.cgi?magic=suspended">suspended packages (by package number)</A>
         <LI><A HREF="search/cust_pkg.cgi?APKG_pkgnum">packages with unconfigured services (by package number)</A>
-        <LI><A HREF="search/cust_pkg.html">packages (by next bill date range)</A>
-      </UL>
-      Invoices
-      <UL>
-        <LI><a href="search/cust_bill_event.html">Invoice event errors (failed credit cards)</a>
-        <LI>open invoices (<A HREF="search/cust_bill.cgi?OPEN_invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?OPEN_date">by date</A>) (<A HREF="search/cust_bill.cgi?OPEN_custnum">by customer number</A>)
-        <LI>30 day open invoices (<A HREF="search/cust_bill.cgi?OPEN30_invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?OPEN30_date">by date</A>) (<A HREF="search/cust_bill.cgi?OPEN30_custnum">by customer number</A>)
-        <LI>60 day open invoices (<A HREF="search/cust_bill.cgi?OPEN60_invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?OPEN60_date">by date</A>) (<A HREF="search/cust_bill.cgi?OPEN60_custnum">by customer number</A>)
-        <LI>90 day open invoices (<A HREF="search/cust_bill.cgi?OPEN90_invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?OPEN90_date">by date</A>) (<A HREF="search/cust_bill.cgi?OPEN90_custnum">by customer number</A>)
-        <LI>120 day open invoices (<A HREF="search/cust_bill.cgi?OPEN120_invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?OPEN120_date">by date</A>) (<A HREF="search/cust_bill.cgi?OPEN120_custnum">by customer number</A>)
-        <LI>all invoices (<A HREF="search/cust_bill.cgi?invnum">by invoice number</A>) (<A HREF="search/cust_bill.cgi?date">by date</A>) (<A HREF="search/cust_bill.cgi?custnum">by customer number</A>)
+        <LI><A HREF="search/cust_pkg_report.cgi">packages (by next bill date range)</A>
       </UL>
-    Financial reports
-            <UL>
-              <LI> <A HREF="search/report_receivables.cgi">current receivables</A>
-              <LI> <A HREF="search/report_tax.html">tax reports</A>
-              <LI> <A HREF="search/report_cc.html">credit card receipts</A>
-              <LI> <A HREF="search/report_credit.html">credit memos</A>
-            </UL>
+      <A HREF="browse/part_pkg.cgi?active=1">Package definitions (by number of active packages)</A><BR><BR>
+      <A HREF="browse/part_svc.cgi?active=1">Service definitions (by number of active services)</A><BR><BR>
     Customers
       <UL>
         <LI><A HREF="search/cust_main-otaker.cgi">Search customers by order-taker</A>
       </UL>
-    <FORM ACTION="search/sql.cgi" METHOD="POST">SQL query: <TT>SELECT </TT><INPUT TYPE="text" NAME="sql" SIZE=32><INPUT TYPE="submit" VALUE="Query"></FORM>
+    <FORM ACTION="search/sql.html" METHOD="POST">SQL query: <TT>SELECT </TT><INPUT TYPE="text" NAME="sql" SIZE=32><INPUT TYPE="submit" VALUE="Query"></FORM>
 
     <BR>
     </TD></TR>
 [ <A HREF="#bookkeeping">Bookkeeping / Collections</A> ]
 [ <A HREF="#reports">Reports</A> ]
 [<A NAME="sysadmin" style="background-color: #cccccc"> Sysadmin </A>]
-    <TABLE CELLSPACING=2 CELLPADDING=0 BORDERCOLOR="#000000" WIDTH="100%" BGCOLOR="#eeeeee">
+    <TABLE CELLSPACING=2 CELLPADDING=0 BORDER=0 WIDTH="100%" BGCOLOR="#eeeeee">
     <TR><TH BGCOLOR="#cccccc">Sysadmin</TH></TR>
     <TR><TD>
       <BR>
       <A HREF="browse/nas.cgi">View active NAS ports</A>
       <BR><A HREF="browse/queue.cgi">View pending job queue</A>
+      <BR><A HREF="misc/cust_main-import.cgi">Batch import customers from CSV file</A>
+      <BR><A HREF="misc/cust_main-import_charges.cgi">Batch import charges from CSV file</A>
+      <BR><A HREF="misc/dump.cgi">Download database dump</A>
       <BR><BR><CENTER><HR WIDTH="94%" NOSHADE></CENTER><BR>
       <A NAME="config" HREF="config/config-view.cgi">Configuration</a><!-- - <font size="+2" color="#ff0000">start here</font> -->
       <BR><BR><A NAME="admin">Administration</a>
           <LI><A HREF="browse/cust_main_county.cgi">View/Edit locales and tax rates</A>
             - Change tax rates, or break down a country into states, or a state
               into counties and assign different tax rates to each.
-          <LI><A HREF="browse/svc_acct_pop.cgi">View/Edit Access Numbers</A>
+          <LI><A HREF="browse/svc_acct_pop.cgi">View/Edit access numbers</A>
             - Points of Presence 
           <LI><A HREF="browse/part_bill_event.cgi">View/Edit invoice events</A> - Actions for overdue invoices
-          <LI><A HREF="browse/msgcat.cgi">View/Edit message catalog</A> - Change error messages and other customizable labels.
+         <LI><A HREF="browse/msgcat.cgi">View/Edit message catalog</A> - Change error messages and other customizable labels.
+    <LI><A HREF="browse/part_virtual_field.cgi">View/Edit virtual fields</A>
+         - Locally defined fields
+         <LI><A HREF="browse/router.cgi">View/Edit routers</A>
+         - Broadband access routers
+         <LI><A HREF="browse/addr_block.cgi">View/Edit address blocks</A>
+         - Manage address blocks and block assignments to broadband routers.
         </ul>
         <BR>
       </TD></TR>
index f048e55..44d85b8 100755 (executable)
@@ -21,7 +21,8 @@ unless ( $error ) {
                                #'batch_card'=> 'yes',
                                #'batch_card'=> 'no',
                                #'report_badcard'=> 'yes',
-                               'retry_card' => 'yes',
+                               #'retry_card' => 'yes',
+                               'retry' => 'yes',
                               );
 }
 #&eidiot($error) if $error;
index 9aa84be..3402b61 100755 (executable)
@@ -77,7 +77,7 @@ if ($pkgnum) {
 }
 
 # add an absence of a catchall
-$email{0} = "(none)";
+$email{''} = "(none)";
 
 my $p1 = popurl(1);
 print header("Domain Catchall Edit", '');
diff --git a/httemplate/misc/change_pkg.cgi b/httemplate/misc/change_pkg.cgi
new file mode 100755 (executable)
index 0000000..5346fd9
--- /dev/null
@@ -0,0 +1,66 @@
+<!-- mason kludge -->
+<%
+
+my $pkgnum;
+if ( $cgi->param('error') ) {
+  #$custnum = $cgi->param('custnum');
+  #%remove_pkg = map { $_ => 1 } $cgi->param('remove_pkg');
+  $pkgnum = ($cgi->param('remove_pkg'))[0];
+} else {
+  my($query) = $cgi->keywords;
+  $query =~ /^(\d+)$/;
+  #$custnum = $1;
+  $pkgnum = $1;
+  #%remove_pkg = ();
+}
+
+my $cust_pkg = qsearchs( 'cust_pkg', { 'pkgnum' => $pkgnum } )
+  or die "unknown pkgnum $pkgnum";
+my $custnum = $cust_pkg->custnum;
+
+my $conf = new FS::Conf;
+
+my $p1 = popurl(1);
+
+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 $agent = $cust_main->agent;
+
+print header("Change Package",  menubar(
+  "View this customer (#$custnum)" => "${p}view/cust_main.cgi?$custnum",
+  'Main Menu' => $p,
+));
+
+print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'),
+      "</FONT><BR><BR>"
+  if $cgi->param('error');
+
+my $part_pkg = $cust_pkg->part_pkg;
+
+print small_custview( $cust_main, $conf->config('countrydefault') ).
+      qq!<FORM ACTION="${p}edit/process/cust_pkg.cgi" METHOD=POST>!.
+      qq!<INPUT TYPE="hidden" NAME="custnum" VALUE="$custnum">!.
+      qq!<INPUT TYPE="hidden" NAME="remove_pkg" VALUE="$pkgnum">!.
+      '<BR>Current package: '. $part_pkg->pkg. ' - '. $part_pkg->comment.
+      qq!<BR>New package: <SELECT NAME="new_pkgpart"><OPTION VALUE=0></OPTION>!;
+
+foreach my $part_pkg (
+  grep { ! $_->disabled && $_->pkgpart != $cust_pkg->pkgpart }
+    map { $_->part_pkg } $agent->agent_type->type_pkgs
+) {
+  my $pkgpart = $part_pkg->pkgpart;
+  print qq!<OPTION VALUE="$pkgpart"!;
+  print ' SELECTED' if $cgi->param('error')
+                       && $cgi->param('new_pkgpart') == $pkgpart;
+  print qq!>$pkgpart: !. $part_pkg->pkg. ' - '. $part_pkg->comment. '</OPTION>';
+}
+
+print <<END;
+</SELECT>
+<BR><BR><INPUT TYPE="submit" VALUE="Change package">
+    </FORM>
+  </BODY>
+</HTML>
+END
+%>
diff --git a/httemplate/misc/cust_main-cancel.cgi b/httemplate/misc/cust_main-cancel.cgi
new file mode 100755 (executable)
index 0000000..257c338
--- /dev/null
@@ -0,0 +1,16 @@
+<%
+
+#untaint custnum
+my($query) = $cgi->keywords;
+$query =~ /^(\d+)$/ || die "Illegal custnum";
+my $custnum = $1;
+
+my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } );
+
+my @errors = $cust_main->cancel;
+eidiot(join(' / ', @errors)) if scalar(@errors);
+
+#print $cgi->redirect($p. "view/cust_main.cgi?". $cust_main->custnum);
+print $cgi->redirect($p);
+
+%>
diff --git a/httemplate/misc/cust_main-import.cgi b/httemplate/misc/cust_main-import.cgi
new file mode 100644 (file)
index 0000000..6b36f47
--- /dev/null
@@ -0,0 +1,51 @@
+<!-- mason kludge -->
+<%= header('Batch Customer Import') %>
+<FORM ACTION="process/cust_main-import.cgi" METHOD="post" ENCTYPE="multipart/form-data">
+Import a CSV file containing customer records.<BR><BR>
+Default file format is CSV, with the following field order: <i>cust_pkg.setup, dayphone, first, last, address1, address2, city, state, zip, comments</i><BR><BR>
+
+<%
+  #false laziness with edit/cust_main.cgi
+  my @agents = qsearch( 'agent', {} );
+  die "No agents created!" unless @agents;
+  my $agentnum = $agents[0]->agentnum; #default to first
+
+  if ( scalar(@agents) == 1 ) {
+%>
+    <INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agentnum %>">
+<% } else { %>
+    <BR><BR>Agent <SELECT NAME="agentnum" SIZE="1">
+  <% foreach my $agent (sort { $a->agent cmp $b->agent } @agents) { %>
+    <OPTION VALUE="<%= $agent->agentnum %>" <%= " SELECTED"x($agent->agentnum==$agentnum) %>><%= $agent->agent %></OPTION>
+  <% } %>
+    </SELECT><BR><BR>
+<% } %>
+
+<%
+  my @referrals = qsearch('part_referral',{});
+  die "No advertising sources created!" unless @referrals;
+  my $refnum = $referrals[0]->refnum; #default to first
+
+  if ( scalar(@referrals) == 1 ) {
+%>
+    <INPUT TYPE="hidden" NAME="refnum" VALUE="<%= $refnum %>">
+<% } else { %>
+    <BR><BR>Advertising source <SELECT NAME="refnum" SIZE="1">
+  <% foreach my $referral ( sort { $a->referral <=> $b->referral } @referrals) { %>
+    <OPTION VALUE="<%= $referral->refnum %>" <%= " SELECTED"x($referral->refnum==$refnum) %>><%= $referral->refnum %>: <%= $referral->referral %></OPTION>
+  <% } %>
+    </SELECT><BR><BR>
+<% } %>
+
+    First package: <SELECT NAME="pkgpart"><OPTION VALUE="">(none)</OPTION>
+<% foreach my $part_pkg ( qsearch('part_pkg',{'disabled'=>'' }) ) { %>
+     <OPTION VALUE="<%= $part_pkg->pkgpart %>"><%= $part_pkg->pkg. ' - '. $part_pkg->comment %></OPTION>
+<% } %>
+</SELECT><BR><BR>
+
+    CSV Filename: <INPUT TYPE="file" NAME="csvfile"><BR><BR>
+    <INPUT TYPE="submit" VALUE="Import">
+    </FORM>
+  </BODY>
+<HTML>
+
diff --git a/httemplate/misc/cust_main-import_charges.cgi b/httemplate/misc/cust_main-import_charges.cgi
new file mode 100644 (file)
index 0000000..0822b9e
--- /dev/null
@@ -0,0 +1,14 @@
+<!-- mason kludge -->
+<%= header('Batch Customer Charge') %>
+<FORM ACTION="process/cust_main-import_charges.cgi" METHOD="post" ENCTYPE="multipart/form-data">
+Import a CSV file containing customer charges.<BR><BR>
+Default file format is CSV, with the following field order: <i>custnum, amount, description</i><BR><BR>
+If <i>amount</i> is negative, a credit will be applied instead.<BR><BR>
+<BR><BR>
+
+    CSV Filename: <INPUT TYPE="file" NAME="csvfile"><BR><BR>
+    <INPUT TYPE="submit" VALUE="Import">
+    </FORM>
+  </BODY>
+<HTML>
+
diff --git a/httemplate/misc/delete-cust_credit.cgi b/httemplate/misc/delete-cust_credit.cgi
new file mode 100755 (executable)
index 0000000..30de04d
--- /dev/null
@@ -0,0 +1,16 @@
+<%
+
+#untaint crednum
+my($query) = $cgi->keywords;
+$query =~ /^(\d+)$/ || die "Illegal crednum";
+my $crednum = $1;
+
+my $cust_credit = qsearchs('cust_credit',{'crednum'=>$crednum});
+my $custnum = $cust_credit->custnum;
+
+my $error = $cust_credit->delete;
+eidiot($error) if $error;
+
+print $cgi->redirect($p. "view/cust_main.cgi?". $custnum);
+
+%>
diff --git a/httemplate/misc/download-batch.cgi b/httemplate/misc/download-batch.cgi
new file mode 100644 (file)
index 0000000..306ef5d
--- /dev/null
@@ -0,0 +1,16 @@
+<%
+
+#http_header('Content-Type' => 'text/comma-separated-values' ); #IE chokes
+http_header('Content-Type' => 'text/plain' );
+
+for my $cust_pay_batch ( sort { $a->paybatchnum <=> $b->paybatchnum }
+                              qsearch('cust_pay_batch', {} )
+) {
+
+$cust_pay_batch->exp =~ /^\d{2}(\d{2})[\/\-](\d+)[\/\-]\d+$/;
+my( $mon, $y ) = ( $2, $1 );
+$mon = "0$mon" if $mon < 10;
+my $exp = "$mon$y";
+
+%>,,,,<%= $cust_pay_batch->cardnum %>,<%= $exp %>,<%= $cust_pay_batch->amount %>,<%= $cust_pay_batch->paybatchnum %>
+<% } %>
diff --git a/httemplate/misc/dump.cgi b/httemplate/misc/dump.cgi
new file mode 100644 (file)
index 0000000..dc1323b
--- /dev/null
@@ -0,0 +1,19 @@
+<%
+  if ( driver_name =~ /^Pg$/ ) {
+    my $dbname = (split(':', datasrc))[2];
+    if ( $dbname =~ /[;=]/ ) {
+      my %elements = map { /^(\w+)=(.*)$/; $1=>$2 } split(';', $dbname);
+      $dbname = $elements{'dbname'};
+    }
+    open(DUMP,"pg_dump $dbname |");
+  } else {
+    eidiot "don't (yet) know how to dump ". driver_name. " databases\n";
+  }
+
+  http_header('Content-Type' => 'text/plain' );
+
+  while (<DUMP>) {
+    print $_;
+  }
+  close DUMP;
+%>
diff --git a/httemplate/misc/email-invoice.cgi b/httemplate/misc/email-invoice.cgi
new file mode 100755 (executable)
index 0000000..7ab1613
--- /dev/null
@@ -0,0 +1,23 @@
+<%
+
+my $conf = new FS::Conf;
+
+#untaint invnum
+my($query) = $cgi->keywords;
+$query =~ /^(\d*)$/;
+my $invnum = $1;
+my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum});
+die "Can't find invoice!\n" unless $cust_bill;
+
+my $error = send_email(
+  'from'    => $conf->config('invoice_from'),
+  'to'      => [ grep { $_ ne 'POST' } $cust_bill->cust_main->invoicing_list ],
+  'subject' => 'Invoice',
+  'body'    => [ $cust_bill->print_text ],
+);
+eidiot($error) if $error;
+
+my $custnum = $cust_bill->getfield('custnum');
+print $cgi->redirect("${p}view/cust_main.cgi?$custnum");
+
+%>
index efc762c..79adce8 100755 (executable)
@@ -4,7 +4,6 @@
 my %link_field = (
   'svc_acct'    => 'username',
   'svc_domain'  => 'domain',
-  'svc_acct_sm' => '',
   'svc_charge'  => '',
   'svc_wo'      => '',
 );
diff --git a/httemplate/misc/meta-import.cgi b/httemplate/misc/meta-import.cgi
new file mode 100644 (file)
index 0000000..2f3b738
--- /dev/null
@@ -0,0 +1,64 @@
+<!-- mason kludge -->
+<%= header('Import') %>
+<FORM ACTION="process/meta-import.cgi" METHOD="post" ENCTYPE="multipart/form-data">
+Import data from a DBI data source<BR><BR>
+
+<%
+  #false laziness with edit/cust_main.cgi
+  my @agents = qsearch( 'agent', {} );
+  die "No agents created!" unless @agents;
+  my $agentnum = $agents[0]->agentnum; #default to first
+
+  if ( scalar(@agents) == 1 ) {
+%>
+    <INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agentnum %>">
+<% } else { %>
+    <BR><BR>Agent <SELECT NAME="agentnum" SIZE="1">
+  <% foreach my $agent (sort { $a->agent cmp $b->agent } @agents) { %>
+    <OPTION VALUE="<%= $agent->agentnum %>" <%= " SELECTED"x($agent->agentnum==$agentnum) %>><%= $agent->agent %></OPTION>
+  <% } %>
+    </SELECT><BR><BR>
+<% } %>
+
+<%
+  my @referrals = qsearch('part_referral',{});
+  die "No advertising sources created!" unless @referrals;
+  my $refnum = $referrals[0]->refnum; #default to first
+
+  if ( scalar(@referrals) == 1 ) {
+%>
+    <INPUT TYPE="hidden" NAME="refnum" VALUE="<%= $refnum %>">
+<% } else { %>
+    <BR><BR>Advertising source <SELECT NAME="refnum" SIZE="1">
+  <% foreach my $referral ( sort { $a->referral <=> $b->referral } @referrals) { %>
+    <OPTION VALUE="<%= $referral->refnum %>" <%= " SELECTED"x($referral->refnum==$refnum) %>><%= $referral->refnum %>: <%= $referral->referral %></OPTION>
+  <% } %>
+    </SELECT><BR><BR>
+<% } %>
+
+    First package: <SELECT NAME="pkgpart"><OPTION VALUE="">(none)</OPTION>
+<% foreach my $part_pkg ( qsearch('part_pkg',{'disabled'=>'' }) ) { %>
+     <OPTION VALUE="<%= $part_pkg->pkgpart %>"><%= $part_pkg->pkg. ' - '. $part_pkg->comment %></OPTION>
+<% } %>
+</SELECT><BR><BR>
+
+  <table>
+    <tr>
+      <td align="right">DBI data source: </td>
+      <td><INPUT TYPE="text" NAME="data_source"></td>
+    </tr>
+    <tr>
+      <td align="right">DBI username: </td>
+      <td><INPUT TYPE="text" NAME="username"></td>
+    </tr>
+    <tr>
+      <td align="right">DBI password: </td>
+      <td><INPUT TYPE="text" NAME="password"></td>
+    </tr>
+  </table>
+  <INPUT TYPE="submit" VALUE="Import">
+
+  </FORM>
+  </BODY>
+<HTML>
+
index a5500bf..144f615 100755 (executable)
@@ -11,13 +11,19 @@ my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum});
 die "Can't find invoice!\n" unless $cust_bill;
 
         open(LPR,"|$lpr") or die "Can't open $lpr: $!";
-        print LPR $cust_bill->print_text; #( date )
+
+        if ( $conf->exists('invoice_latex') ) {
+          print LPR $cust_bill->print_ps; #( date )
+        } else {
+          print LPR $cust_bill->print_text; #( date )
+        }
+
         close LPR
           or die $! ? "Error closing $lpr: $!"
                        : "Exit status $? from $lpr";
 
 my $custnum = $cust_bill->getfield('custnum');
 
-print $cgi->redirect(popurl(2). "view/cust_main.cgi?$custnum#history");
+print $cgi->redirect("${p}view/cust_main.cgi?$custnum");
 
 %>
diff --git a/httemplate/misc/process/cust_main-import.cgi b/httemplate/misc/process/cust_main-import.cgi
new file mode 100644 (file)
index 0000000..9e1adce
--- /dev/null
@@ -0,0 +1,30 @@
+<%
+
+  my $fh = $cgi->upload('csvfile');
+  #warn $cgi;
+  #warn $fh;
+
+  my $error = defined($fh)
+    ? FS::cust_main::batch_import( {
+        filehandle => $fh,
+        agentnum   => scalar($cgi->param('agentnum')),
+        refnum     => scalar($cgi->param('refnum')),
+        pkgpart    => scalar($cgi->param('pkgpart')),
+        'fields'    => [qw( cust_pkg.setup dayphone first last address1 address2
+                           city state zip comments                          )],
+      } )
+    : 'No file';
+
+  if ( $error ) {
+    %>
+    <!-- mason kludge -->
+    <%
+    eidiot($error);
+#    $cgi->param('error', $error);
+#    print $cgi->redirect( "${p}cust_main-import.cgi
+  } else {
+    %>
+    <!-- mason kludge -->
+    <%= header('Import sucessful') %> <%
+  }
+%>
diff --git a/httemplate/misc/process/cust_main-import_charges.cgi b/httemplate/misc/process/cust_main-import_charges.cgi
new file mode 100644 (file)
index 0000000..14df1bd
--- /dev/null
@@ -0,0 +1,26 @@
+<%
+
+  my $fh = $cgi->upload('csvfile');
+  #warn $cgi;
+  #warn $fh;
+
+  my $error = defined($fh)
+    ? FS::cust_main::batch_charge( {
+        filehandle => $fh,
+        'fields'    => [qw( custnum amount pkg )],
+      } )
+    : 'No file';
+
+  if ( $error ) {
+    %>
+    <!-- mason kludge -->
+    <%
+    eidiot($error);
+#    $cgi->param('error', $error);
+#    print $cgi->redirect( "${p}cust_main-import_charges.cgi
+  } else {
+    %>
+    <!-- mason kludge -->
+    <%= header('Import sucessful') %> <%
+  }
+%>
index 4b220a8..5d80ade 100755 (executable)
@@ -8,12 +8,15 @@ $cgi->param('svcnum') =~ /^(\d*)$/;
 my $svcnum = $1;
 
 unless ( $svcnum ) {
-  my($part_svc) = qsearchs('part_svc',{'svcpart'=>$svcpart});
-  my($svcdb) = $part_svc->getfield('svcdb');
-  $cgi->param('link_field') =~ /^(\w+)$/; my($link_field)=$1;
-  my($svc_x)=qsearchs($svcdb,{$link_field => $cgi->param('link_value') });
+  my $part_svc = qsearchs('part_svc',{'svcpart'=>$svcpart});
+  my $svcdb = $part_svc->getfield('svcdb');
+  $cgi->param('link_field') =~ /^(\w+)$/;
+  my $link_field = $1;
+  my $svc_x = ( grep { $_->cust_svc->svcpart == $svcpart } 
+                  qsearch( $svcdb, { $link_field => $cgi->param('link_value') })
+              )[0];
   eidiot("$link_field not found!") unless $svc_x;
-  $svcnum=$svc_x->svcnum;
+  $svcnum = $svc_x->svcnum;
 }
 
 my $old = qsearchs('cust_svc',{'svcnum'=>$svcnum});
diff --git a/httemplate/misc/process/meta-import.cgi b/httemplate/misc/process/meta-import.cgi
new file mode 100644 (file)
index 0000000..59d236f
--- /dev/null
@@ -0,0 +1,178 @@
+<!-- mason kludge -->
+<%= header('Map tables') %>
+
+<SCRIPT>
+var gSafeOnload = new Array();
+var gSafeOnsubmit = new Array();
+window.onload = SafeOnload;
+function SafeAddOnLoad(f) {
+  gSafeOnload[gSafeOnload.length] = f;
+}
+function SafeOnload() {
+  for (var i=0;i<gSafeOnload.length;i++)
+    gSafeOnload[i]();
+}
+function SafeAddOnSubmit(f) {
+  gSafeOnsubmit[gSafeOnsubmit.length] = f;
+}
+function SafeOnsubmit() {
+  for (var i=0;i<gSafeOnsubmit.length;i++)
+    gSafeOnsubmit[i]();
+}
+</SCRIPT>
+
+<FORM NAME="OneTrueForm" METHOD="POST" ACTION="meta-import.cgi">
+
+<%
+  #use DBIx::DBSchema;
+  my $schema = new_native DBIx::DBSchema
+                 map { $cgi->param($_) } qw( data_source username password );
+  foreach my $field (qw( data_source username password )) { %>
+    <INPUT TYPE="hidden" NAME=<%= $field %> VALUE="<%= $cgi->param($field) %>">
+  <% }
+
+  my %schema;
+  use Tie::DxHash;
+  tie %schema, 'Tie::DxHash';
+  if ( $cgi->param('schema') ) {
+    my $schema_string = $cgi->param('schema');
+    %> <INPUT TYPE="hidden" NAME="schema" VALUE="<%=$schema_string%>"> <%
+    %schema = map { /^\s*(\w+)\s*=>\s*(\w+)\s*$/
+                      or die "guru meditation #420: $_";
+                    ( $1 => $2 );
+                  }
+              split( /\n/, $schema_string );
+  }
+
+  #first page
+  unless ( $cgi->param('magic') ) { %>
+
+    <INPUT TYPE="hidden" NAME="magic" VALUE="process">
+    <%= hashmaker('schema', [ $schema->tables ],
+                            [ grep !/^h_/, dbdef->tables ],  ) %>
+    <br><INPUT TYPE="submit" VALUE="done">
+    <%
+
+  #second page
+  } elsif ( $cgi->param('magic') eq 'process' ) { %>
+
+    <INPUT TYPE="hidden" NAME="magic" VALUE="process2">
+    <%
+
+    my %unique;
+    foreach my $table ( keys %schema ) {
+
+      my @from_columns = $schema->table($table)->columns;
+      my @fs_columns = dbdef->table($schema{$table})->columns;
+
+      %>
+      <%= hashmaker( $table.'__'.$unique{$table}++,
+                     \@from_columns => \@fs_columns,
+                     $table         =>  $schema{$table}, ) %>
+      <br><hr><br>
+      <%
+
+    }
+
+    %>
+    <br><INPUT TYPE="submit" VALUE="done">
+    <%
+
+  #third (results)
+  } elsif ( $cgi->param('magic') eq 'process2' ) {
+
+    print "<pre>\n";
+
+    my %unique;
+    foreach my $table ( keys %schema ) {
+      ( my $spaces = $table ) =~ s/./ /g;
+      print "'$table' => { 'table' => '$schema{$table}',\n".
+            #(length($table) x ' '). "         'map'   => {\n";
+            "$spaces        'map'   => {\n";
+      my %map = map { /^\s*(\w+)\s*=>\s*(\w+)\s*$/
+                         or die "guru meditation #420: $_";
+                       ( $1 => $2 );
+                     }
+                 split( /\n/, $cgi->param($table.'__'.$unique{$table}++) );
+      foreach ( keys %map ) {
+        print "$spaces                     '$_' => '$map{$_}',\n";
+      }
+      print "$spaces                   },\n";
+      print "$spaces      },\n";
+
+    }
+    print "\n</pre>";
+
+  } else {
+    warn "unrecognized magic: ". $cgi->param('magic');
+  }
+
+  %>
+</FORM>
+</BODY>
+</HTML>
+
+  <%
+  #hashmaker widget
+  sub hashmaker {
+    my($name, $from, $to, $labelfrom, $labelto) = @_;
+    my $fromsize = scalar(@$from);
+    my $tosize = scalar(@$to);
+    "<TABLE><TR><TH>$labelfrom</TH><TH>$labelto</TH></TR><TR><TD>".
+        qq!<SELECT NAME="${name}_from" SIZE=$fromsize>\n!.
+        join("\n", map { qq!<OPTION VALUE="$_">$_</OPTION>! } sort { $a cmp $b } @$from ).
+        "</SELECT>\n<BR>".
+      qq!<INPUT TYPE="button" VALUE="refill" onClick="repack_${name}_from()">!.
+      '</TD><TD>'.
+        qq!<SELECT NAME="${name}_to" SIZE=$tosize>\n!.
+        join("\n", map { qq!<OPTION VALUE="$_">$_</OPTION>! } sort { $a cmp $b } @$to ).
+        "</SELECT>\n<BR>".
+      qq!<INPUT TYPE="button" VALUE="refill" onClick="repack_${name}_to()">!.
+      '</TD></TR>'.
+      '<TR><TD COLSPAN=2>'.
+        qq!<INPUT TYPE="button" VALUE="map" onClick="toke_$name(this.form)">!.
+      '</TD></TR><TR><TD COLSPAN=2>'.
+      qq!<TEXTAREA NAME="$name" COLS=80 ROWS=8></TEXTAREA>!.
+      '</TD></TR></TABLE>'.
+      "<script>
+            function toke_$name() {
+              fromObject = document.OneTrueForm.${name}_from;
+              for (var i=fromObject.options.length-1;i>-1;i--) {
+                if (fromObject.options[i].selected)
+                  fromname = deleteOption_$name(fromObject,i);
+              }
+              toObject = document.OneTrueForm.${name}_to;
+              for (var i=toObject.options.length-1;i>-1;i--) {
+                if (toObject.options[i].selected)
+                  toname = deleteOption_$name(toObject,i);
+              }
+              document.OneTrueForm.$name.value = document.OneTrueForm.$name.value + fromname + ' => ' + toname + '\\n';
+            }
+            function deleteOption_$name(object,index) {
+              value = object.options[index].value;
+              object.options[index] = null;
+              return value;
+            }
+            function repack_${name}_from() {
+              var object = document.OneTrueForm.${name}_from;
+              object.options.length = 0;
+              ". join("\n", 
+                   map { "addOption_$name(object, '$_');\n" }
+                       ( sort { $a cmp $b } @$from )           ). "
+            }
+            function repack_${name}_to() {
+              var object = document.OneTrueForm.${name}_to;
+              object.options.length = 0;
+              ". join("\n", 
+                   map { "addOption_$name(object, '$_');\n" }
+                       ( sort { $a cmp $b } @$to )           ). "
+            }
+            function addOption_$name(object,value) {
+              var length = object.length;
+              object.options[length] = new Option(value, value, false, false);
+            }
+      </script>".
+      '';
+  }
+
+%>
diff --git a/httemplate/misc/unapply-cust_pay.cgi b/httemplate/misc/unapply-cust_pay.cgi
new file mode 100755 (executable)
index 0000000..28643ef
--- /dev/null
@@ -0,0 +1,18 @@
+<%
+
+#untaint paynum
+my($query) = $cgi->keywords;
+$query =~ /^(\d+)$/ || die "Illegal paynum";
+my $paynum = $1;
+
+my $cust_pay = qsearchs('cust_pay', { 'paynum' => $paynum } );
+my $custnum = $cust_pay->custnum;
+
+foreach my $cust_bill_pay ( $cust_pay->cust_bill_pay ) {
+  my $error = $cust_bill_pay->delete;
+  eidiot($error) if $error;
+}
+
+print $cgi->redirect($p. "view/cust_main.cgi?". $custnum);
+
+%>
diff --git a/httemplate/misc/unprovision.cgi b/httemplate/misc/unprovision.cgi
new file mode 100755 (executable)
index 0000000..8f2a7d1
--- /dev/null
@@ -0,0 +1,33 @@
+<%
+
+my $dbh = dbh;
+#untaint svcnum
+my($query) = $cgi->keywords;
+$query =~ /^(\d+)$/;
+my $svcnum = $1;
+
+#my $svc_acct = qsearchs('svc_acct',{'svcnum'=>$svcnum});
+#die "Unknown svcnum!" unless $svc_acct;
+
+my $cust_svc = qsearchs('cust_svc',{'svcnum'=>$svcnum});
+die "Unknown svcnum!" unless $cust_svc;
+#&eidiot(qq!This account has already been audited.  Cancel the 
+#    <A HREF="!. popurl(2). qq!view/cust_pkg.cgi?! . $cust_svc->getfield('pkgnum') .
+#    qq!pkgnum"> package</A> instead.!) 
+#  if $cust_svc->pkgnum ne '' && $cust_svc->pkgnum ne '0';
+
+my $custnum = $cust_svc->cust_pkg->custnum;
+
+my $error = $cust_svc->cancel;
+
+if ( $error ) {
+  %>
+<!-- mason kludge -->
+<%
+  &eidiot($error);
+} else {
+  print $cgi->redirect(popurl(2)."view/cust_main.cgi?$custnum");
+}
+
+%>
diff --git a/httemplate/misc/upload-batch.cgi b/httemplate/misc/upload-batch.cgi
new file mode 100644 (file)
index 0000000..cc53466
--- /dev/null
@@ -0,0 +1,29 @@
+<%
+
+  my $fh = $cgi->upload('batch_results');
+  my $filename = $cgi->param('batch_results');
+  $filename =~ /^.*[\/\\]([^\/\\]+)$/ or die;
+  my $paybatch = $1;
+
+  my $error = defined($fh)
+    ? FS::cust_pay_batch::import_results( {
+        'filehandle' => $fh,
+        'format'     => $cgi->param('format'),
+        'paybatch'   => $paybatch,
+      } )
+    : 'No file';
+
+  if ( $error ) {
+    %>
+    <!-- mason kludge -->
+    <%
+    eidiot($error);
+#    $cgi->param('error', $error);
+#    print $cgi->redirect( "${p}cust_main-import.cgi
+  } else {
+    %>
+    <!-- mason kludge -->
+    <%= header('Batch results upload sucessful') %> <%
+  }
+%>
+
index 586399a..985e3db 100755 (executable)
@@ -11,7 +11,7 @@ $limit .= "LIMIT $maxrecords" if $maxrecords;
 my $offset = $cgi->param('offset') || 0;
 $limit .= " OFFSET $offset" if $offset;
 
-my $total;
+my($total, $tot_amount, $tot_balance);
 
 my(@cust_bill);
 if ( $cgi->keywords ) {
index 9cb36d2..ec952ea 100644 (file)
@@ -4,10 +4,10 @@
 #false laziness with view/cust_bill.cgi
 
 $cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/;
-my $beginning = str2time($1);
+my $beginning = str2time($1) || 0;
 
 $cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/;
-my $ending = str2time($1) + 86400;
+my $ending = str2time($1) + 86399;
 
 my @cust_bill_event =
   sort { $a->_date <=> $b->_date }
index 9f39db9..d48f1d0 100755 (executable)
@@ -7,27 +7,28 @@
       Quick payment entry
     </FONT>
     <BR><BR>
+    <A HREF="../">Main Menu</A><BR><BR>
     <FORM ACTION="cust_main.cgi" METHOD="post">
       <INPUT TYPE="hidden" NAME="quickpay" VALUE="yes">
       <INPUT TYPE="checkbox" NAME="last_on" CHECKED> Search for <B>last name</B>: 
       <INPUT TYPE="text" NAME="last_text">
       using search method: <SELECT NAME="last_type">
-        <OPTION SELECTED>All
+        <OPTION>All
         <OPTION>Fuzzy
         <OPTION>Substring
-        <OPTION>Exact
+        <OPTION SELECTED>Exact
       </SELECT>
 
       <P><INPUT TYPE="checkbox" NAME="company_on" CHECKED> Search for <B>company</B>: 
       <INPUT TYPE="text" NAME="company_text">
       using search methods: <SELECT NAME="company_type">
-        <OPTION SELECTED>All
+        <OPTION>All
         <OPTION>Fuzzy
         <OPTION>Substring
-        <OPTION>Exact
+        <OPTION SELECTED>Exact
       </SELECT>
 
-      <P><INPUT TYPE="submit" VALUE="Search"> Note: Fuzzy searching can take a while.  Please be patient.
+      <P><INPUT TYPE="submit" VALUE="Search">
 
     </FORM>
 
index 586f8d9..50d367e 100755 (executable)
@@ -50,6 +50,7 @@ my $total = 0;
 my(@cust_main, $sortby, $orderby);
 if ( $cgi->param('browse')
      || $cgi->param('otaker_on')
+     || $cgi->param('agentnum_on')
 ) {
 
   my %search = ();
@@ -73,6 +74,9 @@ if ( $cgi->param('browse')
     if ( $cgi->param('otaker_on') ) {
       $cgi->param('otaker') =~ /^(\w{1,32})$/ or eidiot "Illegal otaker\n";
       $search{otaker} = $1;
+    } elsif ( $cgi->param('agentnum_on') ) {
+      $cgi->param('agentnum') =~ /^(\d+)$/ or eidiot "Illegal agentnum\n";
+      $search{agentnum} = $1;
     } else {
       die "unknown query...";
     }
@@ -82,22 +86,22 @@ if ( $cgi->param('browse')
 
   if ( driver_name eq 'mysql' ) {
 
-       my $query = "CREATE TEMPORARY TABLE temp1_$$ TYPE=MYISAM
-                      SELECT cust_pkg.custnum,COUNT(*) as count
-                        FROM cust_pkg,cust_main
-                          WHERE cust_pkg.custnum = cust_main.custnum
-                                AND ( cust_pkg.cancel IS NULL
-                                      OR cust_pkg.cancel = 0 )
-                          GROUP BY cust_pkg.custnum";
-       my $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query";
-       $sth->execute or die "Error executing \"$query\": ". $sth->errstr;
-       $query = "CREATE TEMPORARY TABLE temp2_$$ TYPE=MYISAM
-                   SELECT cust_pkg.custnum,COUNT(*) as count
-                     FROM cust_pkg,cust_main
-                       WHERE cust_pkg.custnum = cust_main.custnum
-                       GROUP BY cust_pkg.custnum";
-       my $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query";
-       $sth->execute or die "Error executing \"$query\": ". $sth->errstr;
+       my $sql = "CREATE TEMPORARY TABLE temp1_$$ TYPE=MYISAM
+                    SELECT cust_pkg.custnum,COUNT(*) as count
+                      FROM cust_pkg,cust_main
+                        WHERE cust_pkg.custnum = cust_main.custnum
+                              AND ( cust_pkg.cancel IS NULL
+                                    OR cust_pkg.cancel = 0 )
+                        GROUP BY cust_pkg.custnum";
+       my $sth = dbh->prepare($sql) or die dbh->errstr. " preparing $sql";
+       $sth->execute or die "Error executing \"$sql\": ". $sth->errstr;
+       $sql = "CREATE TEMPORARY TABLE temp2_$$ TYPE=MYISAM
+                 SELECT cust_pkg.custnum,COUNT(*) as count
+                   FROM cust_pkg,cust_main
+                     WHERE cust_pkg.custnum = cust_main.custnum
+                     GROUP BY cust_pkg.custnum";
+       $sth = dbh->prepare($sql) or die dbh->errstr. " preparing $sql";
+       $sth->execute or die "Error executing \"$sql\": ". $sth->errstr;
   }
 
   if (  $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me
@@ -112,6 +116,7 @@ if ( $cgi->param('browse')
                AND (temp1_$$.count > 0
                        OR temp2_$$.count = 0 )
        ";
+
     } else {
        $ncancelled = "
           0 < ( SELECT COUNT(*) FROM cust_pkg
@@ -124,15 +129,32 @@ if ( $cgi->param('browse')
                        WHERE cust_pkg.custnum = cust_main.custnum
                    )
        ";
-    }
-
+     }
+   }
+
+  my $cancelled = '';
+  if ( $cgi->param('cancelled') ) {
+    $cancelled = "
+      0 = ( SELECT COUNT(*) FROM cust_pkg
+                   WHERE cust_pkg.custnum = cust_main.custnum
+                      AND ( cust_pkg.cancel IS NULL
+                            OR cust_pkg.cancel = 0
+                          )
+          )
+        AND 0 < ( SELECT COUNT(*) FROM cust_pkg
+                    WHERE cust_pkg.custnum = cust_main.custnum
+                )
+    ";
   }
 
   #EWWWWWW
   my $qual = join(' AND ',
             map { "$_ = ". dbh->quote($search{$_}) } keys %search );
 
-  if ( $ncancelled ) {
+  if ( $cancelled ) {
+    $qual .= ' AND ' if $qual;
+    $qual .= $cancelled;
+  } elsif ( $ncancelled ) {
     $qual .= ' AND ' if $qual;
     $qual .= $ncancelled;
   }
@@ -150,26 +172,27 @@ if ( $cgi->param('browse')
 
   $total = $sth->fetchrow_arrayref->[0];
 
-  if ( $ncancelled ) {
+  my $rqual = $cancelled || $ncancelled;
+  if ( $rqual ) {
     if ( %search ) {
-      $ncancelled = " AND $ncancelled";
+      $rqual = " AND $rqual";
     } else {
-      $ncancelled = " WHERE $ncancelled";
+      $rqual = " WHERE $rqual";
     }
   }
 
   my @just_cust_main;
   if ( driver_name eq 'mysql' ) {
     @just_cust_main = qsearch('cust_main', \%search, 'cust_main.*',
-                              ",temp1_$$,temp2_$$ $ncancelled $orderby $limit");
+                              ",temp1_$$,temp2_$$ $rqual $orderby $limit");
   } else {
     @just_cust_main = qsearch('cust_main', \%search, '',   
-                              "$ncancelled $orderby $limit" );
+                              "$rqual $orderby $limit" );
   }
   if ( driver_name eq 'mysql' ) {
-    $query = "DROP TABLE temp1_$$,temp2_$$;";
-    my $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query";
-    $sth->execute or die "Error executing \"$query\": ". $sth->errstr;
+    my $sql = "DROP TABLE temp1_$$,temp2_$$;";
+    my $sth = dbh->prepare($sql) or die dbh->errstr. " preparing $sql";
+    $sth->execute or die "Error executing \"$sql\": ". $sth->errstr;
   }
   @cust_main = @just_cust_main;
 
@@ -213,9 +236,12 @@ if ( $cgi->param('browse')
   }
 
   @cust_main = grep { $_->ncancelled_pkgs || ! $_->all_pkgs } @cust_main
-    if $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me
-       || ( $conf->exists('hidecancelledcustomers')
-             && ! $cgi->param('showcancelledcustomers') );
+    if ! $cgi->param('cancelled')
+       && (
+         $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me
+         || ( $conf->exists('hidecancelledcustomers')
+               && ! $cgi->param('showcancelledcustomers') )
+       );
 
   my %saw = ();
   @cust_main = grep { !$saw{$_->custnum}++ } @cust_main;
@@ -277,19 +303,22 @@ if ( scalar(@cust_main) == 1 && ! $cgi->param('referral_custnum') ) {
     }
   }
   #end pager
-  
-  if ( $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me
-       || ( $conf->exists('hidecancelledcustomers')
-            && ! $cgi->param('showcancelledcustomers')
-          )
-     ) {
-    $cgi->param('showcancelledcustomers', 1);
-    $cgi->param('offset', 0);
-    print qq!( <a href="!. $cgi->self_url. qq!">show cancelled customers</a> )!;
-  } else {
-    $cgi->param('showcancelledcustomers', 0);
-    $cgi->param('offset', 0);
-    print qq!( <a href="!. $cgi->self_url. qq!">hide cancelled customers</a> )!;
+
+  unless ( $cgi->param('cancelled') ) {
+    if ( $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me
+         || ( $conf->exists('hidecancelledcustomers')
+              && ! $cgi->param('showcancelledcustomers')
+            )
+       ) {
+      $cgi->param('showcancelledcustomers', 1);
+      $cgi->param('offset', 0);
+      print qq!( <a href="!. $cgi->self_url. qq!">show!;
+    } else {
+      $cgi->param('showcancelledcustomers', 0);
+      $cgi->param('offset', 0);
+      print qq!( <a href="!. $cgi->self_url. qq!">hide!;
+    }
+    print ' cancelled customers</a> )';
   }
   if ( $cgi->param('referral_custnum') ) {
     $cgi->param('referral_custnum') =~ /^(\d+)$/
@@ -457,7 +486,7 @@ sub custnumsearch {
   my $custnum = $cgi->param('custnum_text');
   $custnum =~ s/\D//g;
   $custnum =~ /^(\d{1,23})$/ or eidiot "Illegal customer number\n";
-  my $custnum = $1;
+  $custnum = $1;
   
   [ qsearchs('cust_main', { 'custnum' => $custnum } ) ];
 }
@@ -469,7 +498,9 @@ sub cardsearch {
   $card =~ /^(\d{13,16})$/ or eidiot "Illegal card number\n";
   my($payinfo)=$1;
 
-  [ qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'CARD'}) ];
+  [ qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'CARD'}),
+    qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'DCRD'})
+  ];
 }
 
 sub referralsearch {
@@ -636,12 +667,19 @@ sub phonesearch {
 
   my $phone = $cgi->param('phone_text');
 
-  #false laziness with Record::ut_phonen, only works with US/CA numbers...
+  #(no longer really) false laziness with Record::ut_phonen
+  #only works with US/CA numbers...
   $phone =~ s/\D//g;
-  $phone =~ /^(\d{3})(\d{3})(\d{4})(\d*)$/
-    or eidiot gettext('illegal_phone'). ": $phone";
-  $phone = "$1-$2-$3";
-  $phone .= " x$4" if $4;
+  if ( $phone =~ /^(\d{3})(\d{3})(\d{4})(\d*)$/ ) {
+    $phone = "$1-$2-$3";
+    $phone .= " x$4" if $4;
+  } elsif ( $phone =~ /^(\d{3})(\d{4})$/ ) {
+    $phone = "$1-$2";
+  } elsif ( $phone =~ /^(\d{3,4})$/ ) {
+    $phone = $1;
+  } else {
+    eidiot gettext('illegal_phone'). ": $phone";
+  }
 
   my @fields = qw(daytime night fax);
   push @fields, qw(ship_daytime ship_night ship_fax)
@@ -650,7 +688,7 @@ sub phonesearch {
   for my $field ( @fields ) {
     push @cust_main, qsearch ( 'cust_main', 
                                { $field => { 'op'    => 'LIKE',
-                                             'value' => "$phone%" } } );
+                                             'value' => "%$phone%" } } );
   }
 
   \@cust_main;
index b5bdf82..51dd3b3 100755 (executable)
@@ -1,12 +1,73 @@
 <%
 
-$cgi->param('payinfo') =~ /^\s*(\d+)\s*$/ or die "illegal payinfo";
-my $payinfo = $1;
-$cgi->param('payby') =~ /^(\w+)$/ or die "illegal payby";
-my $payby = $1;
-my @cust_pay = qsearch('cust_pay', { 'payinfo' => $payinfo,
+my $sortby;
+my @cust_pay;
+if ( $cgi->param('magic') && $cgi->param('magic') eq '_date' ) {
+
+  my %search;
+  my @search;
+
+  if ( $cgi->param('payby') ) {
+    $cgi->param('payby') =~ /^(CARD|CHEK|BILL)(-(VisaMC|Amex|Discover))?$/
+      or die "illegal payby ". $cgi->param('payby');
+    $search{'payby'} = $1;
+    if ( $3 ) {
+      if ( $3 eq 'VisaMC' ) {
+        #avoid posix regexes for portability
+        push @search, " (    substring(payinfo from 1 for 1) = '4'  ".
+                      "   OR substring(payinfo from 1 for 2) = '51' ".
+                      "   OR substring(payinfo from 1 for 2) = '52' ".
+                      "   OR substring(payinfo from 1 for 2) = '53' ".
+                      "   OR substring(payinfo from 1 for 2) = '54' ".
+                      "   OR substring(payinfo from 1 for 2) = '54' ".
+                      "   OR substring(payinfo from 1 for 2) = '55' ".
+                      " ) ";
+      } elsif ( $3 eq 'Amex' ) {
+        push @search, " (    substring(payinfo from 1 for 2 ) = '34' ".
+                      "   OR substring(payinfo from 1 for 2 ) = '37' ".
+                      " ) ";
+      } elsif ( $3 eq 'Discover' ) {
+        push @search, " substring(payinfo from 1 for 4 ) = '6011' ";
+      } else {
+        die "unknown card type $3";
+      }
+    }
+  }
+
+  #false laziness with cust_pkg.cgi
+  if ( $cgi->param('beginning')
+       && $cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/ ) {
+    my $beginning = str2time($1);
+    push @search, "_date >= $beginning ";
+  }
+  if ( $cgi->param('ending')
+            && $cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/ ) {
+    my $ending = str2time($1) + 86399;
+    push @search, " _date <= $ending ";
+  }
+  my $search;
+  if ( @search ) {
+    $search = ( scalar(keys %search) ? ' AND ' : ' WHERE ' ).
+              join(' AND ', @search);
+  }
+
+  @cust_pay = qsearch('cust_pay', \%search, '', $search );
+
+  $sortby = \*date_sort;
+
+} else {
+
+  $cgi->param('payinfo') =~ /^\s*(\d+)\s*$/ or die "illegal payinfo";
+  my $payinfo = $1;
+
+  $cgi->param('payby') =~ /^(\w+)$/ or die "illegal payby";
+  my $payby = $1;
+
+  @cust_pay = qsearch('cust_pay', { 'payinfo' => $payinfo,
                                      'payby'   => $payby    } );
-my $sortby = \*date_sort;
+  $sortby = \*date_sort;
+
+}
 
 if (0) {
 #if ( scalar(@cust_pay) == 1 ) {
@@ -16,7 +77,7 @@ if (0) {
 %>
 <!-- mason kludge -->
 <%
-  idiot("Check # not found.");
+  idiot("Payment not found.");
   #exit;
 } else {
   my $total = scalar(@cust_pay);
@@ -24,9 +85,9 @@ if (0) {
 %>
 <!-- mason kludge -->
 <%
-  print header("Check # Search Results", menubar(
+  print header("Payment Search Results", menubar(
           'Main Menu', popurl(2)
-        )), "$total matching check$s found<BR>", &table(), <<END;
+        )), "$total matching payment$s found<BR>", &table(), <<END;
       <TR>
         <TH></TH>
         <TH>Amount</TH>
@@ -37,26 +98,41 @@ if (0) {
 END
 
   my(%saw, $cust_pay);
+  my $tot_amount = 0;
   foreach my $cust_pay (
     sort $sortby grep(!$saw{$_->paynum}++, @cust_pay)
   ) {
-    my($paynum, $custnum, $payinfo, $amount, $date ) = (
+    my($paynum, $custnum, $payby, $payinfo, $amount, $date ) = (
       $cust_pay->paynum,
       $cust_pay->custnum,
+      $cust_pay->payby,
       $cust_pay->payinfo,
       sprintf("%.2f", $cust_pay->paid),
       $cust_pay->_date,
     );
-    my $pdate = time2str("%b %d %Y", $date);
+    $tot_amount += $amount;
+    my $pdate = time2str("%b&nbsp;%d&nbsp;%Y", $date);
 
     my $rowspan = 1;
 
     my $view = popurl(2). "view/cust_main.cgi?". $custnum. 
                "#". $payby. $payinfo;
 
+    my $payment_info;
+    if ( $payby eq 'CARD' ) {
+      $payment_info = 'Card&nbsp;#'. 'x'x(length($payinfo)-4).
+                      substr($payinfo,(length($payinfo)-4));
+    } elsif ( $payby eq 'CHEK' ) {
+      $payment_info = "E-check&nbsp;acct#$payinfo";
+    } elsif ( $payby eq 'BILL' ) {
+      $payment_info = "Check&nbsp;#$payinfo";
+    } else {
+      $payment_info = "$payby&nbsp;$payinfo";
+    }
+
     print <<END;
       <TR>
-        <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$payinfo</FONT></A></TD>
+        <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$payment_info</FONT></A></TD>
         <TD ROWSPAN=$rowspan ALIGN="right"><A HREF="$view"><FONT SIZE=-1>\$$amount</FONT></A></TD>
         <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$pdate</FONT></A></TD>
 END
@@ -79,7 +155,13 @@ END
 
     print "</TR>";
   }
-  print <<END;
+
+  $tot_amount = sprintf("%.2f", $tot_amount);
+  print '</TABLE><BR>'. table(). <<END;
+      <TR>
+        <TH>Total&nbsp;Amount</TH>
+        <TD ALIGN="right">\$$tot_amount</TD>
+      </TR>
     </TABLE>
   </BODY>
 </HTML>
index abf6eee..45420f4 100755 (executable)
@@ -19,6 +19,8 @@ my @cust_pkg;
 
 if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) {
   $sortby=\*bill_sort;
+
+  #false laziness with cust_pay.cgi
   my $range = '';
   if ( $cgi->param('beginning')
        && $cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/ ) {
@@ -27,10 +29,18 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) {
   }
   if ( $cgi->param('ending')
             && $cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/ ) {
-    my $ending = str2time($1) + 86400;
+    my $ending = str2time($1) + 86399;
     $range .= ( $range ? ' AND ' : ' WHERE ' ). " bill <= $ending ";
   }
 
+  $range .= ( $range ? 'AND ' : ' WHERE ' ). '( cancel IS NULL OR cancel = 0 )';
+
+  if ( $cgi->param('agentnum') =~ /^(\d+)$/ and $1 ) {
+    $range .= ( $range ? 'AND ' : ' WHERE ' ). 
+              "$1 = ( SELECT agentnum FROM cust_main".
+                    " WHERE cust_main.custnum = cust_pkg.custnum )";
+  }
+
   #false laziness with below
   my $statement = "SELECT COUNT(*) FROM cust_pkg $range";
   warn $statement;
@@ -43,8 +53,31 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) {
 
 } else {
 
-  my $unconf = '';
-  if ( $query eq 'pkgnum' ) {
+  my $qual = '';
+  if ( $cgi->param('magic') &&
+       $cgi->param('magic') =~ /^(active|suspended|canceled)$/
+  ) {
+
+    if ( $cgi->param('magic') eq 'active' ) {
+      $qual = 'WHERE ( susp IS NULL OR susp = 0 )'.
+              ' AND ( cancel IS NULL OR cancel = 0)';
+    } elsif ( $cgi->param('magic') eq 'suspended' ) {
+      $qual = 'WHERE susp IS NOT NULL AND susp != 0'.
+              ' AND ( cancel IS NULL OR cancel = 0)';
+    } elsif ( $cgi->param('magic') eq 'canceled' ) {
+      $qual = 'WHERE cancel IS NOT NULL AND cancel != 0';
+    } else {
+      die "guru meditation #420";
+    }
+
+    $sortby = \*pkgnum_sort;
+
+    if ( $cgi->param('pkgpart') =~ /^(\d+)$/ ) {
+      $qual .= " AND pkgpart = $1";
+    }
+
+  } elsif ( $query eq 'pkgnum' ) {
+
     $sortby=\*pkgnum_sort;
 
   } elsif ( $query eq 'APKG_pkgnum' ) {
@@ -87,7 +120,7 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) {
                       AND cust_svc.svcpart = pkg_svc.svcpart
                       AND cust_pkg.pkgpart = pkg_svc.pkgpart
                       GROUP BY cust_svc.pkgnum,cust_svc.svcpart";
-      $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query";
+      my $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query";
          
       $sth->execute or die "Error executing \"$query\": ". $sth->errstr;
   
@@ -101,12 +134,12 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) {
                           AND pkg_svc.quantity != 0;";
       $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query";   
       $sth->execute or die "Error executing \"$query\": ". $sth->errstr;
-      $unconf = " LEFT JOIN temp2_$$ ON cust_pkg.pkgnum = temp2_$$.pkgnum
-                    WHERE temp2_$$.pkgnum IS NOT NULL";
+      $qual = " LEFT JOIN temp2_$$ ON cust_pkg.pkgnum = temp2_$$.pkgnum
+                  WHERE temp2_$$.pkgnum IS NOT NULL";
 
     } else {
 
-     $unconf = "
+     $qual = "
        WHERE 0 <
          ( SELECT count(*) FROM pkg_svc
              WHERE pkg_svc.pkgpart = cust_pkg.pkgpart
@@ -120,10 +153,10 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) {
     }
     
   } else {
-    die "Empty QUERY_STRING!";
+    die "Empty or unknown QUERY_STRING!";
   }
   
-  my $statement = "SELECT COUNT(*) FROM cust_pkg $unconf";
+  my $statement = "SELECT COUNT(*) FROM cust_pkg $qual";
   my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement";
   $sth->execute or die "Error executing \"$statement\": ". $sth->errstr;
   
@@ -131,7 +164,7 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) {
 
   my $tblname = driver_name eq 'mysql' ? 'cust_pkg.' : '';
   @cust_pkg =
-    qsearch('cust_pkg',{}, '', "$unconf ORDER BY ${tblname}pkgnum $limit" );
+    qsearch('cust_pkg',{}, '', "$qual ORDER BY ${tblname}pkgnum $limit" );
 
   if ( driver_name eq 'mysql' ) {
     $query = "DROP TABLE temp1_$$,temp2_$$;";
@@ -188,6 +221,12 @@ if ( scalar(@cust_pkg) == 1 ) {
       <TR>
         <TH>Package</TH>
         <TH><FONT SIZE=-1>Setup</FONT></TH>
+END
+
+  print '<TH><FONT SIZE=-1>Last<BR>bill</FONT></TH>'
+    if defined dbdef->table('cust_pkg')->column('last_bill');
+
+  print <<END;
         <TH><FONT SIZE=-1>Next<BR>bill</FONT></TH>
         <TH><FONT SIZE=-1>Susp.</FONT></TH>
         <TH><FONT SIZE=-1>Expire</FONT></TH>
@@ -197,17 +236,10 @@ if ( scalar(@cust_pkg) == 1 ) {
         <TH>company</TH>
 END
 
-if ( defined dbdef->table('cust_main')->column('ship_last') ) {
-  print <<END;
-      <TH>(service) name</TH>
-      <TH>company</TH>
-END
-}
+  print '<TH>(service) name</TH><TH>company</TH>'
+    if defined dbdef->table('cust_main')->column('ship_last');
 
-print <<END;
-        <TH COLSPAN=2>Services</TH>
-      </TR>
-END
+  print '<TH COLSPAN=2>Services</TH></TR>';
 
   my $n1 = '<TR>';
   my(%saw,$cust_pkg);
@@ -238,6 +270,12 @@ END
       $cust_main ? $cust_main->first : '',
       $cust_main ? $cust_main->company : '',
     );
+
+    my $last_bill = $cust_pkg->getfield('last_bill')
+                      ? time2str("%D", $cust_pkg->getfield('last_bill') )
+                      : ''
+      if defined dbdef->table('cust_pkg')->column('last_bill');
+
     my($ship_last, $ship_first, $ship_company);
     if ( defined dbdef->table('cust_main')->column('ship_last') ) {
       ($ship_last, $ship_first, $ship_company) = (
@@ -263,11 +301,17 @@ END
     my $p = popurl(2);
     print $n1, <<END;
       <TD ROWSPAN=$rowspan><A HREF="${p}view/cust_pkg.cgi?$pkgnum"><FONT SIZE=-1>$pkgnum - $pkg</FONT></A></TD>
-      <TD>$setup</TD>
-      <TD>$bill</TD>
-      <TD>$susp</TD>
-      <TD>$expire</TD>
-      <TD>$cancel</TD>
+      <TD ROWSPAN=$rowspan>$setup</TD>
+END
+
+    print "<TD ROWSPAN=$rowspan>$last_bill</TD>"
+      if defined dbdef->table('cust_pkg')->column('last_bill');
+
+    print <<END;
+      <TD ROWSPAN=$rowspan>$bill</TD>
+      <TD ROWSPAN=$rowspan>$susp</TD>
+      <TD ROWSPAN=$rowspan>$expire</TD>
+      <TD ROWSPAN=$rowspan>$cancel</TD>
 END
     if ( $cust_main ) {
       print <<END;
diff --git a/httemplate/search/cust_pkg.html b/httemplate/search/cust_pkg.html
deleted file mode 100755 (executable)
index bb0a540..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-<HTML>
-  <HEAD>
-    <TITLE>Packages</TITLE>
-  </HEAD>
-  <BODY>
-    <CENTER>
-      <H1>Packages</H1>
-    </CENTER>
-    <HR>
-    <FORM ACTION="cust_pkg.cgi" METHOD="post">
-    <INPUT TYPE="hidden" NAME="magic" VALUE="bill">
-      Return <B>packages</B> with next bill date: 
-      from <INPUT TYPE="text" NAME="beginning"> <i>m/d/y</i>
-      to <INPUT TYPE="text" NAME="ending"> <i>m/d/y</i>
-
-      <P><INPUT TYPE="submit" VALUE="Get Report">
-
-    </FORM>
-
-  <HR>
-
-  </BODY>
-</HTML>
-
diff --git a/httemplate/search/cust_pkg_report.cgi b/httemplate/search/cust_pkg_report.cgi
new file mode 100755 (executable)
index 0000000..b316745
--- /dev/null
@@ -0,0 +1,63 @@
+<HTML>
+  <HEAD>
+    <TITLE>Packages</TITLE>
+    <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2">
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT>
+  </HEAD>
+  <BODY BGCOLOR="#e8e8e8">
+    <H1>Packages</H1>
+    <FORM ACTION="cust_pkg.cgi" METHOD="post">
+    <INPUT TYPE="hidden" NAME="magic" VALUE="bill">
+      Return packages with next bill date:<BR><BR>
+      <TABLE>
+        <TR>
+          <TD ALIGN="right">From: </TD>
+          <TD><INPUT TYPE="text" NAME="beginning" ID="beginning_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="beginning_button" STYLE="cursor: pointer" TITLE="Select date"><BR><I>m/d/y</I></TD>
+<SCRIPT TYPE="text/javascript">
+  Calendar.setup({
+    inputField: "beginning_text",
+    ifFormat:   "%m/%d/%Y",
+    button:     "beginning_button",
+    align:      "BR"
+  });
+</SCRIPT>
+        </TR>
+        <TR>
+          <TD ALIGN="right">To: </TD>
+          <TD><INPUT TYPE="text" NAME="ending" ID="ending_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="ending_button" STYLE="cursor: pointer" TITLE="Select date"><BR><I>m/d/y</I></TD>
+<SCRIPT TYPE="text/javascript">
+  Calendar.setup({
+    inputField: "ending_text",
+    ifFormat:   "%m/%d/%Y",
+    button:     "ending_button",
+    align:      "BR"
+  });
+</SCRIPT>
+        </TR>
+<% my %agent_search = dbdef->table('agent')->column('disabled')
+                        ? ( 'disabled' => '' ) : ();
+   my @agents = qsearch( 'agent', \%agent_search );
+   if ( scalar(@agents) == 1 ) {
+%>
+     <INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agents[0]->agentnum %>">
+<% } else { %>
+
+        <TR>
+          <TD ALIGN="right">Agent: </TD>
+          <TD><SELECT NAME="agentnum"><OPTION VALUE="">(all)
+          <% foreach my $agent ( sort { $a->agent cmp $b->agent; } @agents) { %>
+            <OPTION VALUE="<%= $agent->agentnum %>"><%= $agent->agent %>
+          <% } %>
+          </TD>
+        </TR>
+<% } %>
+      </TABLE>
+      <BR><INPUT TYPE="submit" VALUE="Get Report">
+
+    </FORM>
+
+  </BODY>
+</HTML>
+
diff --git a/httemplate/search/elements/search.html b/httemplate/search/elements/search.html
new file mode 100644 (file)
index 0000000..fbedcaa
--- /dev/null
@@ -0,0 +1,59 @@
+<%
+
+  my %opt = @_;
+  unless (exists($opt{'count_query'}) && length($opt{'count_query'})) {
+    ( $opt{'count_query'} = $opt{'query'} ) =~
+      s/^\s*SELECT\s*(.*)\s+FROM\s/SELECT COUNT(*) FROM /i;
+  }
+
+  my $conf = new FS::Conf;
+  my $maxrecords = $conf->config('maxsearchrecordsperpage');
+
+  my $limit = $maxrecords ? "LIMIT $maxrecords" : '';
+
+  my $offset = $cgi->param('offset') || 0;
+  $limit .= " OFFSET $offset" if $offset;
+
+  my $count_sth = dbh->prepare($opt{'count_query'})
+    or die "Error preparing $opt{'count_query'}: ". dbh->errstr;
+  $count_sth->execute
+    or die "Error executing $opt{'count_query'}: ". $count_sth->errstr;
+  my $total = $count_sth->fetchrow_arrayref->[0];
+
+  my $sth = dbh->prepare("$opt{'query'} $limit")
+    or die "Error preparing $opt{'query'}: ". dbh->errstr;
+  $sth->execute
+    or die "Error executing $opt{'query'}: ". $sth->errstr;
+
+  #can get # of rows without fetching them all?
+  my $rows = $sth->fetchall_arrayref;
+
+%>
+<!-- mason kludge -->
+<% my $pager = include ( '/elements/pager.html',
+                           'offset'     => $offset,
+                           'num_rows'   => scalar(@$rows),
+                           'total'      => $total,
+                           'maxrecords' => $maxrecords,
+                       );
+%>
+
+<%= $total %> total <%= $opt{'name'} %><BR><BR><%= $pager %>
+<%= include( '/elements/table.html' ) %>
+  <TR>
+  <% foreach ( @{$sth->{NAME}} ) { %>
+       <TH><%= $_ %></TH>
+  <% } %>
+  </TR>
+  <% foreach my $row ( @$rows ) { %>
+       <TR>
+       <% foreach ( @$row ) { %>
+            <TD><%= $_ %></TD>
+       <% } %>
+       </TR>
+  <% } %>
+
+</TABLE>
+<%= $pager %>
+</BODY>
+</HTML>
index 8653dcc..595a7b1 100755 (executable)
@@ -1,23 +1,43 @@
 <HTML>
   <HEAD>
     <TITLE>Credit Card Receipt Report Criteria</TITLE>
-  </HEAD>
-  <BODY>
-    <CENTER>
-      <H1>Credit Card Receipt Report Criteria</H1>
-    </CENTER>
-    <HR>
+    <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2">
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT>  </HEAD>
+  <BODY BGCOLOR="#e8e8e8">
+    <H1>Credit Card Receipt Report Criteria</H1>
     <FORM ACTION="report_cc.cgi" METHOD="post">
       Return <B>credit card receipt report</B> for period: 
-      from <INPUT TYPE="text" NAME="beginning"> <i>m/d/y</i>
-      to <INPUT TYPE="text" NAME="ending"> <i>m/d/y</i>
+    <TABLE>
+      <TR>
+        <TD ALIGN="right">From: </TD>
+        <TD><INPUT TYPE="text" NAME="beginning" ID="beginning_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="beginning_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD>
+<SCRIPT TYPE="text/javascript">
+  Calendar.setup({
+    inputField: "beginning_text",
+    ifFormat:   "%m/%d/%Y",
+    button:     "beginning_button",
+    align:      "BR"
+  });
+</SCRIPT>
+      </TR>
+        <TD ALIGN="right">To: </TD>
+        <TD><INPUT TYPE="text" NAME="ending" ID="ending_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="ending_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD>
+<SCRIPT TYPE="text/javascript">
+  Calendar.setup({
+    inputField: "ending_text",
+    ifFormat:   "%m/%d/%Y",
+    button:     "ending_button",
+    align:      "BR"
+  });
+</SCRIPT>
+      </TR>
+    </TABLE>
 
-      <P><INPUT TYPE="submit" VALUE="Get Report">
+      <BR><INPUT TYPE="submit" VALUE="Get Report">
 
     </FORM>
-
-  <HR>
-
   </BODY>
 </HTML>
 
index df9b958..11cb32e 100755 (executable)
@@ -1,23 +1,43 @@
 <HTML>
   <HEAD>
     <TITLE>In House Credit Report Criteria</TITLE>
-  </HEAD>
-  <BODY>
-    <CENTER>
-      <H1>In House Credit Report Criteria</H1>
-    </CENTER>
-    <HR>
+    <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2">
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT>  </HEAD>
+  <BODY BGCOLOR="#e8e8e8">
+    <H1>In House Credit Report Criteria</H1>
     <FORM ACTION="report_credit.cgi" METHOD="post">
       Return <B>in house credit report</B> for period: 
-      from <INPUT TYPE="text" NAME="beginning"> <i>m/d/y</i>
-      to <INPUT TYPE="text" NAME="ending"> <i>m/d/y</i>
+    <TABLE>
+      <TR>
+        <TD ALIGN="right">From: </TD>
+        <TD><INPUT TYPE="text" NAME="beginning" ID="beginning_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="beginning_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD>
+<SCRIPT TYPE="text/javascript">
+  Calendar.setup({
+    inputField: "beginning_text",
+    ifFormat:   "%m/%d/%Y",
+    button:     "beginning_button",
+    align:      "BR"
+  });
+</SCRIPT>
+      </TR>
+        <TD ALIGN="right">To: </TD>
+        <TD><INPUT TYPE="text" NAME="ending" ID="ending_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="ending_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD>
+<SCRIPT TYPE="text/javascript">
+  Calendar.setup({
+    inputField: "ending_text",
+    ifFormat:   "%m/%d/%Y",
+    button:     "ending_button",
+    align:      "BR"
+  });
+</SCRIPT>
+      </TR>
+    </TABLE>
 
-      <P><INPUT TYPE="submit" VALUE="Get Report">
+    <BR><INPUT TYPE="submit" VALUE="Get Report">
 
     </FORM>
-
-  <HR>
-
   </BODY>
 </HTML>
 
diff --git a/httemplate/search/report_cust_pay.html b/httemplate/search/report_cust_pay.html
new file mode 100644 (file)
index 0000000..1b30685
--- /dev/null
@@ -0,0 +1,54 @@
+<HTML>
+  <HEAD>
+    <TITLE>Payment report criteria</TITLE>
+    <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2">
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT>
+  </HEAD>
+  <BODY BGCOLOR="#e8e8e8">
+    <H1>Payment report criteria</H1>
+    <FORM ACTION="cust_pay.cgi" METHOD="post">
+    <INPUT TYPE="hidden" NAME="magic" VALUE="_date">
+    <TABLE>
+      <TR>
+        <TD ALIGN="right">Payments of type: </TD>
+        <TD><SELECT NAME="payby">
+              <OPTION VALUE="">all</OPTION>
+              <OPTION VALUE="CARD">credit card (all)</OPTION>
+              <OPTION VALUE="CARD-VisaMC">credit card (Visa/MasterCard)</OPTION>
+              <OPTION VALUE="CARD-Amex">credit card (American Express)</OPTION>
+              <OPTION VALUE="CARD-Discover">credit card (Discover)</OPTION>
+              <OPTION VALUE="CHEK">electronic check / ACH</OPTION>
+              <OPTION VALUE="BILL">check / cash</OPTION>
+            </SELECT>
+        </TD>
+      </TR>
+      <TR>
+        <TD ALIGN="right">From: </TD>
+        <TD><INPUT TYPE="text" NAME="beginning" ID="beginning_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="beginning_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD>
+<SCRIPT TYPE="text/javascript">
+  Calendar.setup({
+    inputField: "beginning_text",
+    ifFormat:   "%m/%d/%Y",
+    button:     "beginning_button",
+    align:      "BR"
+  });
+</SCRIPT>
+      </TR>
+        <TD ALIGN="right">To: </TD>
+        <TD><INPUT TYPE="text" NAME="ending" ID="ending_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="ending_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD>
+<SCRIPT TYPE="text/javascript">
+  Calendar.setup({
+    inputField: "ending_text",
+    ifFormat:   "%m/%d/%Y",
+    button:     "ending_button",
+    align:      "BR"
+  });
+</SCRIPT>
+      </TR>
+    </TABLE>
+    <BR><INPUT TYPE="submit" VALUE="Get Report">
+    </FORM>
+  </BODY>
+</HTML>
diff --git a/httemplate/search/report_prepaid_income.cgi b/httemplate/search/report_prepaid_income.cgi
new file mode 100644 (file)
index 0000000..eb8bbb5
--- /dev/null
@@ -0,0 +1,75 @@
+<!-- mason kludge -->
+<%
+
+  #doesn't yet deal with daily/weekly packages
+
+  #needs to be re-written in sql for efficiency
+
+  my $now = $cgi->param('date') && str2time($cgi->param('date')) || time;
+  $now =~ /^(\d+)$/ or die "unparsable date?";
+  $now = $1;
+
+  my %prepaid;
+
+  my @cust_bill_pkg =
+    grep { $_->cust_pkg && $_->cust_pkg->part_pkg->freq !~ /^([01]|\d+[dw])$/ }
+      qsearch( 'cust_bill_pkg', {
+                                  'recur' => { op=>'!=', value=>0 },
+                                  'edate' => { op=>'>', value=>$now },
+                                }, );
+
+  foreach my $cust_bill_pkg ( @cust_bill_pkg ) {
+
+    #conceptual false laziness w/texas tax exempt_amount stuff in
+    #FS::cust_main::bill
+
+    my $freq = $cust_bill_pkg->cust_pkg->part_pkg->freq;
+    my $per_month = sprintf("%.2f", $cust_bill_pkg->recur / $freq);
+
+    my($mon, $year) = (localtime($cust_bill_pkg->sdate) )[4,5];
+    $mon+=2; $year+=1900;
+
+    foreach my $which_month ( 2 .. $freq ) {
+      until ( $mon < 13 ) { $mon -= 12; $year++; }
+      $prepaid{"$year-$mon"} += $per_month;
+      $mon++;
+    }
+
+  }
+
+  my @mon = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
+
+%>
+
+<%= header( 'Prepaid Income (Unearned Revenue) Report',
+            menubar( 'Main Menu'=>$p, ) )               %>
+<%= table() %>
+<%
+
+  my $total = 0;
+
+  my ($now_mon, $now_year) = (localtime($now))[4,5];
+  $now_mon+=2; $now_year+=1900;
+  until ( $now_mon < 13 ) { $now_mon -= 12; $now_year++; }
+
+  my $subseq = 0;
+  for my $year ( $now_year .. 2037 ) {
+    for my $mon ( ( $subseq++ ? 1 : $now_mon ) .. 12 ) {
+      if ( $prepaid{"$year-$mon"} ) {
+        $total += $prepaid{"$year-$mon"};
+        %> <TR><TD ALIGN="right"><%= $mon[$mon-1]. ' '. $year %></TD>
+               <TD ALIGN="right">
+                 <%= sprintf("%.2f", $prepaid{"$year-$mon"} ) %>
+               </TD>
+           </TR>
+        <%
+      }
+    }
+
+  }
+
+%>
+<TR><TH>Total</TH><TD ALIGN="right"><%= sprintf("%.2f", $total) %></TD></TR>
+</TABLE>
+</BODY>
+</HTML>
diff --git a/httemplate/search/report_prepaid_income.html b/httemplate/search/report_prepaid_income.html
new file mode 100644 (file)
index 0000000..b85a481
--- /dev/null
@@ -0,0 +1,17 @@
+<HTML>
+  <HEAD>
+    <TITLE>Prepaid Income (Unearned Revenue) Report</TITLE>
+    <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2">
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT>
+  </HEAD>
+  <BODY BGCOLOR="#e8e8e8">
+    <H1>Prepaid Income (Unearned Revenue) Report</H1>
+    <FORM ACTION="report_prepaid_income.cgi" METHOD="post">
+    Prepaid income (unearned revenue) as of <INPUT TYPE="text" NAME="date" VALUE="now">
+    <INPUT TYPE="submit" VALUE="Generate report">
+  </BODY>
+</HTML>
+    <TABLE>
+
index fdd3779..ad353a1 100755 (executable)
 <!-- mason kludge -->
 <%
 
-my $user = getotaker;
+  my $charged = <<END;
+  sum( charged
+       - coalesce(
+           ( select sum(amount) from cust_bill_pay
+             where cust_bill.invnum = cust_bill_pay.invnum )
+           ,0
+         )
+       - coalesce(
+           ( select sum(amount) from cust_credit_bill
+             where cust_bill.invnum = cust_credit_bill.invnum )
+           ,0
+         )
 
-print header('Current Receivables Report Results');
+     )
+END
 
-open (REPORT, "freeside-receivables-report -v $user |");
+  my $owed_cols = <<END;
+       coalesce(
+         ( select $charged from cust_bill
+           where cust_bill._date > extract(epoch from now())-2592000
+             and cust_main.custnum = cust_bill.custnum
+         )
+         ,0
+       ) as owed_0_30,
 
-print '<PRE>';
-while(<REPORT>) {
-  print $_;
-}
-print '</PRE>';
+       coalesce(
+         ( select $charged from cust_bill
+           where cust_bill._date >  extract(epoch from now())-5184000
+             and cust_bill._date <= extract(epoch from now())-2592000
+             and cust_main.custnum = cust_bill.custnum
+         )
+         ,0
+       ) as owed_30_60,
 
-print '</BODY></HTML>';
+       coalesce(
+         ( select $charged from cust_bill
+           where cust_bill._date >  extract(epoch from now())-7776000
+             and cust_bill._date <= extract(epoch from now())-5184000
+             and cust_main.custnum = cust_bill.custnum
+         )
+         ,0
+       ) as owed_60_90,
 
-%>
+       coalesce(
+         ( select $charged from cust_bill
+           where cust_bill._date <= extract(epoch from now())-7776000
+             and cust_main.custnum = cust_bill.custnum
+         )
+         ,0
+       ) as owed_90_plus,
+
+       coalesce(
+         ( select $charged from cust_bill
+           where cust_main.custnum = cust_bill.custnum
+         )
+         ,0
+       ) as owed_total
+END
+
+  my $recurring = <<END;
+        0 < ( select freq from part_pkg
+                where cust_pkg.pkgpart = part_pkg.pkgpart )
+END
+
+  my $packages_cols = <<END;
+
+       ( select count(*) from cust_pkg
+           where cust_main.custnum = cust_pkg.custnum
+             and $recurring
+             and ( cancel = 0 or cancel is null )
+       ) as uncancelled_pkgs,
+
+       ( select count(*) from cust_pkg
+           where cust_main.custnum = cust_pkg.custnum
+             and $recurring
+             and ( cancel = 0 or cancel is null )
+             and ( susp = 0 or susp is null )
+       ) as active_pkgs
+
+END
+
+  my $sql = <<END;
 
+select *, $owed_cols, $packages_cols from cust_main
+where 0 <
+  coalesce(
+           ( select $charged from cust_bill
+             where cust_main.custnum = cust_bill.custnum
+           )
+           ,0
+         )
+
+order by lower(company), lower(last)
+
+END
+
+  my $total_sql = "select $owed_cols";
+
+  my $sth = dbh->prepare($sql) or die dbh->errstr;
+  $sth->execute or die $sth->errstr;
+
+  my $total_sth = dbh->prepare($total_sql) or die dbh->errstr;
+  $total_sth->execute or die $total_sth->errstr;
+
+%>
+<%= header('Accounts Receivable Aging Summary', menubar( 'Main Menu'=>$p, ) ) %>
+<%= table() %>
+  <TR>
+    <TH>Customer</TH>
+    <TH>Status</TH>
+    <TH>0-30</TH>
+    <TH>30-60</TH>
+    <TH>60-90</TH>
+    <TH>90+</TH>
+    <TH>Total</TH>
+  </TR>
+<% while ( my $row = $sth->fetchrow_hashref() ) {
+     my $status = 'Cancelled';
+     my $statuscol = 'FF0000';
+     if ( $row->{uncancelled_pkgs} ) {
+       $status = 'Suspended';
+       $statuscol = 'FF9900';
+       if ( $row->{active_pkgs} ) {
+         $status = 'Active';
+         $statuscol = '00CC00';
+       }
+     }
+%>
+  <TR>
+    <TD><A HREF="<%= $p %>view/cust_main.cgi?<%= $row->{'custnum'} %>"><%= $row->{'custnum'} %>:
+        <%= $row->{'company'} ? $row->{'company'}. ' (' : '' %><%= $row->{'last'}. ', '. $row->{'first'} %><%= $row->{'company'} ? ')' : '' %></A>
+    </TD>
+    <TD><B><FONT SIZE=-1 COLOR="#<%= $statuscol %>"><%= $status %></FONT></B></TD>
+    <TD ALIGN="right">$<%= sprintf("%.2f", $row->{'owed_0_30'} ) %></TD>
+    <TD ALIGN="right">$<%= sprintf("%.2f", $row->{'owed_30_60'} ) %></TD>
+    <TD ALIGN="right">$<%= sprintf("%.2f", $row->{'owed_60_90'} ) %></TD>
+    <TD ALIGN="right">$<%= sprintf("%.2f", $row->{'owed_90_plus'} ) %></TD>
+    <TD ALIGN="right"><B>$<%= sprintf("%.2f", $row->{'owed_total'} ) %></B></TD>
+  </TR>
+<% } %>
+<% my $row = $total_sth->fetchrow_hashref(); %>
+  <TR>
+    <TD COLSPAN=6>&nbsp;</TD>
+  </TR>
+  <TR>
+    <TD COLSPAN=2><I>Total</I></TD>
+    <TD ALIGN="right"><I>$<%= sprintf("%.2f", $row->{'owed_0_30'} ) %></TD>
+    <TD ALIGN="right"><I>$<%= sprintf("%.2f", $row->{'owed_30_60'} ) %></TD>
+    <TD ALIGN="right"><I>$<%= sprintf("%.2f", $row->{'owed_60_90'} ) %></TD>
+    <TD ALIGN="right"><I>$<%= sprintf("%.2f", $row->{'owed_90_plus'} ) %></TD>
+    <TD ALIGN="right"><I><B>$<%= sprintf("%.2f", $row->{'owed_total'} ) %></B></I></TD>
+  </TR>
+</TABLE>
+</BODY>
+</HTML>
index 7bf681b..7bc35e3 100755 (executable)
@@ -1,23 +1,43 @@
 <HTML>
   <HEAD>
     <TITLE>Tax Report Criteria</TITLE>
-  </HEAD>
-  <BODY>
-    <CENTER>
-      <H1>Tax Report Criteria</H1>
-    </CENTER>
-    <HR>
+    <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2">
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT>
+    <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT>  </HEAD>
+  <BODY BGCOLOR="#e8e8e8">
+    <H1>Tax Report Criteria</H1>
     <FORM ACTION="report_tax.cgi" METHOD="post">
-      Return <B>tax report</B> for period: 
-      from <INPUT TYPE="text" NAME="beginning"> <i>m/d/y</i>
-      to <INPUT TYPE="text" NAME="ending"> <i>m/d/y</i>
+      Return <B>tax report</B> for period:
+    <TABLE>
+      <TR>
+        <TD ALIGN="right">From: </TD>
+        <TD><INPUT TYPE="text" NAME="beginning" ID="beginning_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="beginning_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD>
+<SCRIPT TYPE="text/javascript">
+  Calendar.setup({
+    inputField: "beginning_text",
+    ifFormat:   "%m/%d/%Y",
+    button:     "beginning_button",
+    align:      "BR"
+  });
+</SCRIPT>
+      </TR>
+        <TD ALIGN="right">To: </TD>
+        <TD><INPUT TYPE="text" NAME="ending" ID="ending_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="ending_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD>
+<SCRIPT TYPE="text/javascript">
+  Calendar.setup({
+    inputField: "ending_text",
+    ifFormat:   "%m/%d/%Y",
+    button:     "ending_button",
+    align:      "BR"
+  });
+</SCRIPT>
+      </TR>
+    </TABLE>
 
-      <P><INPUT TYPE="submit" VALUE="Get Report">
+      <BR><INPUT TYPE="submit" VALUE="Get Report">
 
     </FORM>
-
-  <HR>
-
   </BODY>
 </HTML>
 
diff --git a/httemplate/search/sql.cgi b/httemplate/search/sql.cgi
deleted file mode 100755 (executable)
index b83ef03..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-<%
-
-my $conf = new FS::Conf;
-my $maxrecords = $conf->config('maxsearchrecordsperpage');
-
-my $limit = '';
-$limit .= "LIMIT $maxrecords" if $maxrecords;
-
-my $offset = $cgi->param('offset') || 0;
-$limit .= " OFFSET $offset" if $offset;
-
-my $total;
-
-my $sql = $cgi->param('sql');
-$sql =~ s/^\s*SELECT//i;
-
-my $count_sql = $sql;
-$count_sql =~ s/^(.*)\s+FROM\s/COUNT(*) FROM /i;
-
-my $sth = dbh->prepare("SELECT $count_sql")
-  or eidiot dbh->errstr. " doing $count_sql\n";
-$sth->execute or eidiot "Error executing \"$count_sql\": ". $sth->errstr;
-
-$total = $sth->fetchrow_arrayref->[0];
-
-my $sth = dbh->prepare("SELECT $sql $limit")
-  or eidiot dbh->errstr. " doing $sql\n";
-$sth->execute or eidiot "Error executing \"$sql\": ". $sth->errstr;
-my $rows = $sth->fetchall_arrayref;
-
-%>
-<!-- mason kludge -->
-<%
-
-  #begin pager
-  my $pager = '';
-  if ( $total != scalar(@$rows) && $maxrecords ) {
-    unless ( $offset == 0 ) {
-      $cgi->param('offset', $offset - $maxrecords);
-      $pager .= '<A HREF="'. $cgi->self_url.
-                '"><B><FONT SIZE="+1">Previous</FONT></B></A> ';
-    }
-    my $poff;
-    my $page;
-    for ( $poff = 0; $poff < $total; $poff += $maxrecords ) {
-      $page++;
-      if ( $offset == $poff ) {
-        $pager .= qq!<FONT SIZE="+2">$page</FONT> !;
-      } else {
-        $cgi->param('offset', $poff);
-        $pager .= qq!<A HREF="!. $cgi->self_url. qq!">$page</A> !;
-      }
-    }
-    unless ( $offset + $maxrecords > $total ) {
-      $cgi->param('offset', $offset + $maxrecords);
-      $pager .= '<A HREF="'. $cgi->self_url.
-                '"><B><FONT SIZE="+1">Next</FONT></B></A> ';
-    }
-  }
-  #end pager
-
-  print header('Query Results', menubar('Main Menu'=>$p) ).
-        "$total total rows<BR><BR>$pager". table().
-        "<TR>";
-  print "<TH>$_</TH>" foreach @{$sth->{NAME}};
-  print "</TR>";
-
-  foreach $row ( @$rows ) {
-    print "<TR>";
-    print "<TD>$_</TD>" foreach @$row;
-    print "</TR>";
-  }
-
-  print "</TABLE>$pager</BODY></HTML>";
-
-%>
diff --git a/httemplate/search/sql.html b/httemplate/search/sql.html
new file mode 100644 (file)
index 0000000..7d7fc08
--- /dev/null
@@ -0,0 +1,12 @@
+<%= include( '/elements/header.html', 'Query Results',
+               include( '/elements/menubar.html', 'Main Menu' => $p )
+    )
+%>
+
+<%= include( 'elements/search.html',
+               'name'  => 'rows',
+               'query' => 'SELECT '. ( $cgi->param('sql')
+                                       || eidiot('Empty query') ),
+    )
+%>
+
index 549231d..1e4a03d 100755 (executable)
@@ -1,7 +1,5 @@
 <%
 
-my $mydomain = '';
-
 my $conf = new FS::Conf;
 my $maxrecords = $conf->config('maxsearchrecordsperpage');
 
@@ -32,7 +30,7 @@ if ( $query =~ /^UN_(.*)$/ ) {
       WHERE 0 <
         ( SELECT count(*) FROM cust_svc
             WHERE cust_svc.svcnum = svc_acct.svcnum
-              AND ( pkgnum IS NULL OR pkgnum = 0 OR pkgnum = $empty )
+              AND ( pkgnum IS NULL OR pkgnum = 0 )
         )
     ";
   }
@@ -48,14 +46,31 @@ if ( $query eq 'svcnum' ) {
   $orderby = "ORDER BY ${tblname}username";
 } elsif ( $query eq 'uid' ) {
   $sortby=\*uid_sort;
-  $orderby = ( $unlinked ? 'AND' : 'WHERE' ).
+  $orderby = ( $unlinked ? ' AND' : ' WHERE' ).
              " ${tblname}uid IS NOT NULL ORDER BY ${tblname}uid";
+} elsif ( $cgi->param('popnum') =~ /^(\d+)$/ ) {
+  $unlinked .= ( $unlinked ? 'AND' : 'WHERE' ).
+               " popnum = $1";
+  $sortby=\*username_sort;
+  $orderby = "ORDER BY ${tblname}username";
+} elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) {
+  $unlinked .= ( $unlinked ? ' AND' : ' WHERE' ).
+               " $1 = ( SELECT svcpart FROM cust_svc ".
+               "        WHERE cust_svc.svcnum = svc_acct.svcnum ) ";
+  $sortby=\*uid_sort;
+  #$sortby=\*svcnum_sort;
 } else {
   $sortby=\*uid_sort;
   @svc_acct = @{&usernamesearch};
 }
 
-if ( $query eq 'svcnum' || $query eq 'username' || $query eq 'uid' ) {
+
+if (    $query eq 'svcnum'
+     || $query eq 'username'
+     || $query eq 'uid'
+     || $cgi->param('popnum') =~ /^(\d+)$/
+     || $cgi->param('svcpart') =~ /^(\d+)$/
+   ) {
 
   my $statement = "SELECT COUNT(*) FROM svc_acct $unlinked";
   my $sth = dbh->prepare($statement)
@@ -147,14 +162,8 @@ END
       $domain = "<A HREF=\"${p}view/svc_domain.cgi?". $svc_domain->svcnum.
                 "\">". $svc_domain->domain. "</A>";
     } else {
-      unless ( $mydomain ) {
-        my $conf = new FS::Conf;
-        unless ( $mydomain = $conf->config('domain') ) {
-          die "No legacy domain config file and no svc_domain.svcnum record ".
-              "for svc_acct.domsvc: ". $svc_acct->domsvc;
-        }
-      }
-      $domain = "<i>$mydomain</i><FONT COLOR=\"#FF0000\">*</FONT>";
+      die "No svc_domain.svcnum record for svc_acct.domsvc: ".
+          $svc_acct->domsvc;
     }
     my($cust_pkg,$cust_main);
     if ( $cust_svc->pkgnum ) {
@@ -216,17 +225,8 @@ END
 
   }
  
-  print "</TABLE>$pager<BR>";
-
-  if ( $mydomain ) {
-    print "<BR><FONT COLOR=\"#FF0000\">*</FONT> The <I>$mydomain</I> domain ".
-          "is contained in your legacy <CODE>domain</CODE> ".
-          "<A HREF=\"${p}docs/config.html#domain\">configuration file</A>.  ".
-          "You should run the <CODE>bin/fs-migrate-svc_acct_sm</CODE> script ".
-          "to create a proper svc_domain record for this domain.";
-  }
-
-  print '</BODY></HTML>';
+  print "</TABLE>$pager<BR>".
+        '</BODY></HTML>';
 
 }
 
diff --git a/httemplate/search/svc_acct_sm.cgi b/httemplate/search/svc_acct_sm.cgi
deleted file mode 100755 (executable)
index 4ee3006..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-<%
-
-my $conf = new FS::Conf;
-my $mydomain = $conf->config('domain');
-
-$cgi->param('domuser') =~ /^([a-z0-9_\-]{0,32})$/;
-my $domuser = $1;
-
-$cgi->param('domain') =~ /^([\w\-\.]+)$/ or die "Illegal domain";
-my $svc_domain = qsearchs('svc_domain',{'domain'=>$1})
-  or die "Unknown domain";
-my $domsvc = $svc_domain->svcnum;
-
-my @svc_acct_sm;
-if ($domuser) {
-  @svc_acct_sm=qsearch('svc_acct_sm',{
-    'domuser' => $domuser,
-    'domsvc'  => $domsvc,
-  });
-} else {
-  @svc_acct_sm=qsearch('svc_acct_sm',{'domsvc' => $domsvc});
-}
-
-if ( scalar(@svc_acct_sm) == 1 ) {
-  my($svcnum)=$svc_acct_sm[0]->svcnum;
-  print $cgi->redirect(popurl(2). "view/svc_acct_sm.cgi?$svcnum");
-} elsif ( scalar(@svc_acct_sm) > 1 ) {
-%>
-<!-- mason kludge -->
-<%
-  print header('Mail Alias Search Results'), &table(), <<END;
-      <TR>
-        <TH>Mail to<BR><FONT SIZE=-1>(click to view mail alias)</FONT></TH>
-        <TH>Forwards to<BR><FONT SIZE=-1>(click to view account)</FONT></TH>
-      </TR>
-END
-
-  my($svc_acct_sm);
-  foreach $svc_acct_sm (@svc_acct_sm) {
-    my($svcnum,$domuser,$domuid,$domsvc)=(
-      $svc_acct_sm->svcnum,
-      $svc_acct_sm->domuser,
-      $svc_acct_sm->domuid,
-      $svc_acct_sm->domsvc,
-    );
-
-    my $svc_domain = qsearchs( 'svc_domain', { 'svcnum' => $domsvc } );
-    if ( $svc_domain ) {
-      my $domain = $svc_domain->domain;
-
-      print qq!<TR><TD><A HREF="!. popurl(2). qq!view/svc_acct_sm.cgi?$svcnum">!,
-      #print '', ( ($domuser eq '*') ? "<I>(anything)</I>" : $domuser );
-            ( ($domuser eq '*') ? "<I>(anything)</I>" : $domuser ),
-            qq!\@$domain</A> </TD>!,
-      ;
-    } else {
-      my $warning = "couldn't find svc_domain.svcnum $svcnum ( svc_acct_sm.svcnum $svcnum";
-      warn $warning;
-      print "<TR><TD>WARNING: $warning</TD>";
-    }
-
-    my $svc_acct = qsearchs( 'svc_acct', { 'uid' => $domuid } );
-    if ( $svc_acct ) {
-      my $username = $svc_acct->username;
-      my $svc_acct_svcnum =$svc_acct->svcnum;
-      print qq!<TD><A HREF="!, popurl(2),
-            qq!view/svc_acct.cgi?$svc_acct_svcnum">$username\@$mydomain</A>!,
-            qq!</TD></TR>!
-      ;
-    } else {
-      my $warning = "couldn't find svc_acct.uid $domuid (svc_acct_sm.svcnum $svcnum)!";
-      warn $warning;
-      print "<TD>WARNING: $warning</TD></TR>";
-    }
-
-  }
-
-  print '</TABLE></BODY></HTML>';
-
-} else { #error
-  idiot("Mail Alias not found");
-}
-
-%>
diff --git a/httemplate/search/svc_acct_sm.html b/httemplate/search/svc_acct_sm.html
deleted file mode 100755 (executable)
index 0719856..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<HTML>
-  <HEAD>
-    <TITLE>Mail Alias Search</TITLE>
-  </HEAD>
-  <BODY>
-    <CENTER>
-      <H1>Mail Alias Search</H1>
-    </CENTER>
-    <HR>
-    <FORM ACTION="svc_acct_sm.cgi" METHOD="post">
-      Search for <B>mail alias</B>: 
-      <INPUT TYPE="text" NAME="domuser"><FONT SIZE=-1>(opt.)</FONT> @
-      <INPUT TYPE="text" NAME="domain"><FONT SIZE=-1>(req.)</FONT>
-
-      <P><INPUT TYPE="submit" VALUE="Search">
-
-    </FORM>
-
-  <HR>
-
-  </BODY>
-</HTML>
-
index fb372db..948b1d9 100755 (executable)
@@ -1,7 +1,6 @@
 <%
 
 my $conf = new FS::Conf;
-my $mydomain = $conf->config('domain');
 
 my($query)=$cgi->keywords;
 $query ||= ''; #to avoid use of unitialized value errors
@@ -24,6 +23,13 @@ if ( $query eq 'svcnum' ) {
       'svcnum' => $_->svcnum,
       'pkgnum' => '',
     }), qsearch('svc_domain',{});
+} elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) {
+  @svc_domain =
+    qsearch( 'svc_domain', {}, '',
+               " WHERE $1 = ( SELECT svcpart FROM cust_svc ".
+               "              WHERE cust_svc.svcnum = svc_domain.svcnum ) "
+    );
+  $sortby=\*svcnum_sort;
 } else {
   $cgi->param('domain') =~ /^([\w\-\.]+)$/; 
   my($domain)=$1;
@@ -51,8 +57,9 @@ if ( scalar(@svc_domain) == 1 ) {
       <TR>
         <TH>Service #</TH>
         <TH>Domain</TH>
-        <TH>Mail to<BR><FONT SIZE=-1>(click to view account)</FONT></TH>
+<!--        <TH>Mail to<BR><FONT SIZE=-1>(click to view account)</FONT></TH>
         <TH>Forwards to<BR><FONT SIZE=-1>(click to view account)</FONT></TH>
+-->
       </TR>
 END
 
@@ -67,78 +74,69 @@ END
       $svc_domain->svcnum,
       $svc_domain->domain,
     );
-    #my($malias);
-    #if ( qsearch('svc_acct_sm',{'domsvc'=>$svcnum}) ) {
-    #  $malias=(
-    #    qq|<FORM ACTION="svc_acct_sm.cgi" METHOD="post">|.
-    #      qq|<INPUT TYPE="hidden" NAME="domuser" VALUE="">|.
-    #      qq|<INPUT TYPE="hidden" NAME="domain" VALUE="$domain">|.
-    #      qq|<INPUT TYPE="submit" VALUE="(mail aliases)">|.
-    #      qq|</FORM>|
+
+    #don't display all accounts here
+    my $rowspan = 1;
+
+    #my @svc_acct=qsearch('svc_acct',{'domsvc' => $svcnum});
+    #my $rowspan = 0;
+    #
+    #my $n1 = '';
+    #my($svc_acct, @rows);
+    #foreach $svc_acct (
+    #  sort {$b->getfield('username') cmp $a->getfield('username')} (@svc_acct)
+    #) {
+    #
+    #  my (@forwards) = ();
+    #
+    #  my($svcnum,$username)=(
+    #    $svc_acct->svcnum,
+    #    $svc_acct->username,
     #  );
-    #} else {
-    #  $malias='';
+    #
+    #  my @svc_forward = qsearch( 'svc_forward', { 'srcsvc' => $svcnum } );
+    #  my $svc_forward;
+    #  foreach $svc_forward (@svc_forward) {
+    #    my($dstsvc,$dst) = (
+    #      $svc_forward->dstsvc,
+    #      $svc_forward->dst,
+    #    );
+    #    if ($dstsvc) {
+    #      my $dst_svc_acct=qsearchs( 'svc_acct', { 'svcnum' => $dstsvc } );
+    #      my $destination=$dst_svc_acct->email;
+    #      push @forwards, qq!<TD><A HREF="!, popurl(2),
+    #            qq!view/svc_acct.cgi?$dstsvc">$destination</A>!,
+    #            qq!</TD></TR>!
+    #      ;
+    #    }else{
+    #      push @forwards, qq!<TD>$dst</TD></TR>!
+    #      ;
+    #    }
+    #  }
+    #
+    #  push @rows, qq!$n1<TD ROWSPAN=!, (scalar(@svc_forward) || 1),
+    #        qq!><A HREF="!. popurl(2). qq!view/svc_acct.cgi?$svcnum">!,
+    #  #print '', ( ($domuser eq '*') ? "<I>(anything)</I>" : $domuser );
+    #        ( ($username eq '*') ? "<I>(anything)</I>" : $username ),
+    #        qq!\@$domain</A> </TD>!,
+    #  ;
+    #
+    #  push @rows, @forwards;
+    #
+    #  $rowspan += (scalar(@svc_forward) || 1);
+    #  $n1 = "</TR><TR>";
     #}
-
-    my @svc_acct=qsearch('svc_acct',{'domsvc' => $svcnum});
-    my $rowspan = 0;
-
-    my $n1 = '';
-    my($svc_acct, @rows);
-    foreach $svc_acct (
-      sort {$b->getfield('username') cmp $a->getfield('username')} (@svc_acct)
-    ) {
-
-      my (@forwards) = ();
-
-      my($svcnum,$username)=(
-        $svc_acct->svcnum,
-        $svc_acct->username,
-      );
-
-      my @svc_forward = qsearch( 'svc_forward', { 'srcsvc' => $svcnum } );
-      my $svc_forward;
-      foreach $svc_forward (@svc_forward) {
-        my($dstsvc,$dst) = (
-          $svc_forward->dstsvc,
-          $svc_forward->dst,
-        );
-        if ($dstsvc) {
-          my $dst_svc_acct=qsearchs( 'svc_acct', { 'svcnum' => $dstsvc } );
-          my $destination=$dst_svc_acct->email;
-          push @forwards, qq!<TD><A HREF="!, popurl(2),
-                qq!view/svc_acct.cgi?$dstsvc">$destination</A>!,
-                qq!</TD></TR>!
-          ;
-        }else{
-          push @forwards, qq!<TD>$dst</TD></TR>!
-          ;
-        }
-      }
-
-      push @rows, qq!$n1<TD ROWSPAN=!, (scalar(@svc_forward) || 1),
-            qq!><A HREF="!. popurl(2). qq!view/svc_acct.cgi?$svcnum">!,
-      #print '', ( ($domuser eq '*') ? "<I>(anything)</I>" : $domuser );
-            ( ($username eq '*') ? "<I>(anything)</I>" : $username ),
-            qq!\@$domain</A> </TD>!,
-      ;
-
-      push @rows, @forwards;
-
-      $rowspan += (scalar(@svc_forward) || 1);
-      $n1 = "</TR><TR>";
-    }
-    #end of false laziness
-
-
+    ##end of false laziness
+    #
+    #
 
     print <<END;
     <TR>
-      <TD ROWSPAN=$rowspan><A HREF="${p}view/svc_domain.cgi?$svcnum"><FONT SIZE=-1>$svcnum</FONT></A></TD>
-      <TD ROWSPAN=$rowspan>$domain</TD>
+      <TD ROWSPAN=$rowspan><A HREF="${p}view/svc_domain.cgi?$svcnum">$svcnum</A></TD>
+      <TD ROWSPAN=$rowspan><A HREF="${p}view/svc_domain.cgi?$svcnum">$domain</A></TD>
 END
 
-    print @rows;
+    #print @rows;
     print "</TR>";
 
   }
diff --git a/httemplate/search/svc_forward.cgi b/httemplate/search/svc_forward.cgi
new file mode 100755 (executable)
index 0000000..10094bc
--- /dev/null
@@ -0,0 +1,79 @@
+<%
+
+my $conf = new FS::Conf;
+
+my($query)=$cgi->keywords;
+$query ||= ''; #to avoid use of unitialized value errors
+my(@svc_forward,$sortby);
+if ( $query eq 'svcnum' ) {
+  $sortby=\*svcnum_sort;
+  @svc_forward=qsearch('svc_forward',{});
+} else {
+  eidiot('unimplemented');
+}
+
+if ( scalar(@svc_forward) == 1 ) {
+  print $cgi->redirect(popurl(2). "view/svc_forward.cgi?". $svc_forward[0]->svcnum);
+  #exit;
+} elsif ( scalar(@svc_forward) == 0 ) {
+%>
+<!-- mason kludge -->
+<%
+  eidiot "No matching forwards found!\n";
+} else {
+%>
+<!-- mason kludge -->
+<%
+  my $total = scalar(@svc_forward);
+  print header("Mail forward Search Results",''), <<END;
+
+    $total matching mail forwards found
+    <TABLE BORDER=4 CELLSPACING=0 CELLPADDING=0>
+      <TR>
+        <TH>Service #<BR><FONT SIZE=-1>(click to view forward)</FONT></TH>
+        <TH>Mail to<BR><FONT SIZE=-1>(click to view account)</FONT></TH>
+        <TH>Forwards to<BR><FONT SIZE=-1>(click to view account)</FONT></TH>
+      </TR>
+END
+
+  foreach my $svc_forward (
+    sort $sortby (@svc_forward)
+  ) {
+    my $svcnum = $svc_forward->svcnum;
+
+    my $src = $svc_forward->src;
+    $src = "<I>(anything)</I>$src" if $src =~ /^@/;
+    if ( $svc_forward->srcsvc_acct ) {
+      $src = qq!<A HREF="${p}view/svc_acct.cgi?!. $svc_forward->srcsvc. '">'.
+             $svc_forward->srcsvc_acct->email. '</A>';
+    }
+
+    my $dst = $svc_forward->dst;
+    if ( $svc_forward->dstsvc_acct ) {
+      $dst = qq!<A HREF="${p}view/svc_acct.cgi?!. $svc_forward->dstsvc. '">'.
+             $svc_forward->dstsvc_acct->email. '</A>';
+    }
+
+    print <<END;
+      <TR>
+        <TD><A HREF="${p}view/svc_forward.cgi?$svcnum">$svcnum</A></TD>
+        <TD>$src</TD>
+        <TD>$dst</TD>
+      </TR>
+END
+
+  }
+  print <<END;
+    </TABLE>
+  </BODY>
+</HTML>
+END
+
+}
+
+sub svcnum_sort {
+  $a->getfield('svcnum') <=> $b->getfield('svcnum');
+}
+
+%>
diff --git a/httemplate/view/cust_bill-pdf.cgi b/httemplate/view/cust_bill-pdf.cgi
new file mode 100755 (executable)
index 0000000..7aa6910
--- /dev/null
@@ -0,0 +1,13 @@
+<%
+
+#untaint invnum
+my($query) = $cgi->keywords;
+$query =~ /^(\d+)$/;
+my $invnum = $1;
+
+my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum});
+die "Invoice #$invnum not found!" unless $cust_bill;
+
+http_header('Content-Type' => 'application/pdf' );
+%>
+<%= $cust_bill->print_pdf %>
diff --git a/httemplate/view/cust_bill-ps.cgi b/httemplate/view/cust_bill-ps.cgi
new file mode 100755 (executable)
index 0000000..03340a1
--- /dev/null
@@ -0,0 +1,13 @@
+<%
+
+#untaint invnum
+my($query) = $cgi->keywords;
+$query =~ /^(\d+)$/;
+my $invnum = $1;
+
+my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum});
+die "Invoice #$invnum not found!" unless $cust_bill;
+
+http_header('Content-Type' => 'application/postscript' );
+%>
+<%= $cust_bill->print_ps %>
index 53d7bc0..50ee8b3 100755 (executable)
@@ -20,7 +20,20 @@ print header('Invoice View', menubar(
 print qq!<A HREF="${p}edit/cust_pay.cgi?$invnum">Enter payments (check/cash) against this invoice</A> | !
   if $cust_bill->owed > 0;
 
-print qq!<A HREF="${p}misc/print-invoice.cgi?$invnum">Reprint this invoice</A>!.      '<BR><BR>';
+print qq!<A HREF="${p}misc/print-invoice.cgi?$invnum">Reprint this invoice</A>!;
+if ( grep { $_ ne 'POST' } $cust_bill->cust_main->invoicing_list ) {
+  print qq! | <A HREF="${p}misc/email-invoice.cgi?$invnum">!.
+        qq!Re-email this invoice</A>!;
+}
+
+print '<BR><BR>';
+
+my $conf = new FS::Conf;
+if ( $conf->exists('invoice_latex') ) {
+  print menubar(
+    'View typeset invoice' => "${p}view/cust_bill-pdf.cgi?$invnum",
+  ), '<BR><BR>';
+}
 
 #false laziness with search/cust_bill_event.cgi
 
index 421bd98..ee5f869 100755 (executable)
@@ -15,6 +15,15 @@ print header("Customer View", menubar(
   'Main Menu' => popurl(2)
 ));
 
+print <<END;
+<STYLE TYPE="text/css">
+.package TH { font-size: medium }
+.package TR { font-size: smaller }
+.package .pkgnum { font-size: medium }
+.package .provision { font-weight: bold }
+</STYLE>
+END
+
 die "No customer specified (bad URL)!" unless $cgi->keywords;
 my($query) = $cgi->keywords; # needs parens with my, ->keywords returns array
 $query =~ /^(\d+)$/;
@@ -22,10 +31,23 @@ my $custnum = $1;
 my $cust_main = qsearchs('cust_main',{'custnum'=>$custnum});
 die "Customer not found!" unless $cust_main;
 
-print qq!<A HREF="!, popurl(2), 
-      qq!edit/cust_main.cgi?$custnum">Edit this customer</A>!;
-print qq! | <A HREF="!, popurl(2), 
-      qq!misc/delete-customer.cgi?$custnum"> Delete this customer</A>!
+print qq!<A HREF="${p}edit/cust_main.cgi?$custnum">Edit this customer</A>!;
+
+print <<END;
+<SCRIPT>
+function cancel_areyousure(href) {
+    if (confirm("Perminantly delete all services and cancel this customer?") == true)
+        window.location.href = href;
+}
+</SCRIPT>
+END
+
+print qq! | <A HREF="javascript:cancel_areyousure('${p}misc/cust_main-cancel.cgi?$custnum')">!.
+      'Cancel this customer</A>'
+  if $cust_main->ncancelled_pkgs;
+
+print qq! | <A HREF="${p}misc/delete-customer.cgi?$custnum">!.
+      'Delete this customer</A>'
   if $conf->exists('deletecustomers');
 
 unless ( $conf->exists('disable_customer_referrals') ) {
@@ -54,7 +76,7 @@ print '<TD VALIGN="top">';
 
   print "Billing address", &ntable("#cccccc"), "<TR><TD>",
         &ntable("#cccccc",2),
-    '<TR><TD ALIGN="right">Contact name</TD>',
+    '<TR><TD ALIGN="right">Contact&nbsp;name</TD>',
       '<TD COLSPAN=3 BGCOLOR="#ffffff">',
       $cust_main->last, ', ', $cust_main->first,
       '</TD>';
@@ -83,9 +105,13 @@ print '</TR>',
           $cust_main->country,
           '</TD></TR>',
   ;
-  print '<TR><TD ALIGN="right">Day Phone</TD><TD COLSPAN=5 BGCOLOR="#ffffff">',
+  my $daytime_label = FS::Msgcat::_gettext('daytime') || 'Day&nbsp;Phone';
+  my $night_label = FS::Msgcat::_gettext('night') || 'Night&nbsp;Phone';
+  print '<TR><TD ALIGN="right">'. $daytime_label.
+          '</TD><TD COLSPAN=5 BGCOLOR="#ffffff">',
           $cust_main->daytime || '&nbsp', '</TD></TR>',
-       '<TR><TD ALIGN="right">Night Phone</TD><TD COLSPAN=5 BGCOLOR="#ffffff">',
+        '<TR><TD ALIGN="right">'. $night_label. 
+          '</TD><TD COLSPAN=5 BGCOLOR="#ffffff">',
           $cust_main->night || '&nbsp', '</TD></TR>',
         '<TR><TD ALIGN="right">Fax</TD><TD COLSPAN=5 BGCOLOR="#ffffff">',
           $cust_main->fax || '&nbsp', '</TD></TR>',
@@ -122,10 +148,10 @@ print '</TR>',
             $cust_main->get("${pre}country"),
             '</TD></TR>',
     ;
-    print '<TR><TD ALIGN="right">Day Phone</TD>',
+    print '<TR><TD ALIGN="right">'. $daytime_label. '</TD>',
           '<TD COLSPAN=5 BGCOLOR="#ffffff">',
             $cust_main->get("${pre}daytime") || '&nbsp', '</TD></TR>',
-          '<TR><TD ALIGN="right">Night Phone</TD>'.
+          '<TR><TD ALIGN="right">'. $night_label. '</TD>'.
           '<TD COLSPAN=5 BGCOLOR="#ffffff">',
             $cust_main->get("${pre}night") || '&nbsp', '</TD></TR>',
           '<TR><TD ALIGN="right">Fax</TD><TD COLSPAN=5 BGCOLOR="#ffffff">',
@@ -140,7 +166,7 @@ print '</TD>';
 print '<TD VALIGN="top">';
 
   print &ntable("#cccccc"), "<TR><TD>", &ntable("#cccccc",2),
-        '<TR><TD ALIGN="right">Customer number</TD><TD BGCOLOR="#ffffff">',
+        '<TR><TD ALIGN="right">Customer&nbsp;number</TD><TD BGCOLOR="#ffffff">',
         $custnum, '</TD></TR>',
   ;
 
@@ -158,13 +184,13 @@ print '<TD VALIGN="top">';
     my $referral = qsearchs('part_referral', {
       'refnum' => $cust_main->refnum
     } );
-    print '<TR><TD ALIGN="right">Advertising source</TD><TD BGCOLOR="#ffffff">',
+    print '<TR><TD ALIGN="right">Advertising&nbsp;source</TD><TD BGCOLOR="#ffffff">',
           $referral->refnum, ": ", $referral->referral, '</TD></TR>';
   }
   print '<TR><TD ALIGN="right">Order taker</TD><TD BGCOLOR="#ffffff">',
     $cust_main->otaker, '</TD></TR>';
 
-  print '<TR><TD ALIGN="right">Referring Customer</TD><TD BGCOLOR="#ffffff">';
+  print '<TR><TD ALIGN="right">Referring&nbsp;Customer</TD><TD BGCOLOR="#ffffff">';
   my $referring_cust_main = '';
   if ( $cust_main->referral_custnum
        && ( $referring_cust_main =
@@ -188,26 +214,30 @@ print '<TD VALIGN="top">';
 
 print '<BR>';
 
+if ( $conf->config('payby-default') ne 'HIDE' ) {
+
   my @invoicing_list = $cust_main->invoicing_list;
   print "Billing information (",
        qq!<A HREF="!, popurl(2), qq!misc/bill.cgi?$custnum">!, "Bill now</A>)",
         &ntable("#cccccc"), "<TR><TD>", &ntable("#cccccc",2),
-        '<TR><TD ALIGN="right">Tax exempt</TD><TD BGCOLOR="#ffffff">',
+        '<TR><TD ALIGN="right">Tax&nbsp;exempt</TD><TD BGCOLOR="#ffffff">',
         $cust_main->tax ? 'yes' : 'no',
         '</TD></TR>',
-        '<TR><TD ALIGN="right">Postal invoices</TD><TD BGCOLOR="#ffffff">',
+        '<TR><TD ALIGN="right">Postal&nbsp;invoices</TD><TD BGCOLOR="#ffffff">',
         ( grep { $_ eq 'POST' } @invoicing_list ) ? 'yes' : 'no',
         '</TD></TR>',
-        '<TR><TD ALIGN="right">Email invoices</TD><TD BGCOLOR="#ffffff">',
+        '<TR><TD ALIGN="right">Email&nbsp;invoices</TD><TD BGCOLOR="#ffffff">',
         join(', ', grep { $_ ne 'POST' } @invoicing_list ) || 'no',
         '</TD></TR>',
-        '<TR><TD ALIGN="right">Billing type</TD><TD BGCOLOR="#ffffff">',
+        '<TR><TD ALIGN="right">Billing&nbsp;type</TD><TD BGCOLOR="#ffffff">',
   ;
 
-  if ( $cust_main->payby eq 'CARD' ) {
+  if ( $cust_main->payby eq 'CARD' || $cust_main->payby eq 'DCRD' ) {
     my $payinfo = $cust_main->payinfo;
     $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4));
-    print 'Credit card</TD></TR>',
+    print 'Credit&nbsp;card&nbsp;',
+          ( $cust_main->payby eq 'CARD' ? '(automatic)' : '(on-demand)' ),
+          '</TD></TR>',
           '<TR><TD ALIGN="right">Card number</TD><TD BGCOLOR="#ffffff">',
           $payinfo, '</TD></TR>',
           '<TR><TD ALIGN="right">Expiration</TD><TD BGCOLOR="#ffffff">',
@@ -215,6 +245,25 @@ print '<BR>';
           '<TR><TD ALIGN="right">Name on card</TD><TD BGCOLOR="#ffffff">',
           $cust_main->payname, '</TD></TR>'
     ;
+  } elsif ( $cust_main->payby eq 'CHEK' || $cust_main->payby eq 'DCHK') {
+    my( $account, $aba ) = split('@', $cust_main->payinfo );
+    print 'Electronic&nbsp;check&nbsp;',
+          ( $cust_main->payby eq 'CHEK' ? '(automatic)' : '(on-demand)' ),
+          '</TD></TR>',
+          '<TR><TD ALIGN="right">Account number</TD><TD BGCOLOR="#ffffff">',
+          $account, '</TD></TR>',
+          '<TR><TD ALIGN="right">ABA/Routing code</TD><TD BGCOLOR="#ffffff">',
+          $aba, '</TD></TR>',
+          '<TR><TD ALIGN="right">Bank name</TD><TD BGCOLOR="#ffffff">',
+          $cust_main->payname, '</TD></TR>'
+    ;
+  } elsif ( $cust_main->payby eq 'LECB' ) {
+    $cust_main->payinfo =~ /^(\d{3})(\d{3})(\d{4})$/;
+    my $payinfo = "$1-$2-$3";
+    print 'Phone&nbsp;bill&nbsp;billing</TD></TR>',
+          '<TR><TD ALIGN="right">Phone number</TD><TD BGCOLOR="#ffffff">',
+          $payinfo, '</TD></TR>',
+    ;
   } elsif ( $cust_main->payby eq 'BILL' ) {
     print 'Billing</TD></TR>';
     print '<TR><TD ALIGN="right">P.O. </TD><TD BGCOLOR="#ffffff">',
@@ -227,7 +276,7 @@ print '<BR>';
     ;
   } elsif ( $cust_main->payby eq 'COMP' ) {
     print 'Complimentary</TD></TR>',
-          '<TR><TD ALIGN="right">Authorized by</TD><TD BGCOLOR="#ffffff">',
+          '<TR><TD ALIGN="right">Authorized&nbsp;by</TD><TD BGCOLOR="#ffffff">',
           $cust_main->payinfo, '</TD></TR>',
           '<TR><TD ALIGN="right">Expiration</TD><TD BGCOLOR="#ffffff">',
           $cust_main->paydate, '</TD></TR>',
@@ -236,14 +285,17 @@ print '<BR>';
 
   print "</TABLE></TD></TR></TABLE>";
 
+}
+
 print '</TD></TR></TABLE>';
 
 if ( defined $cust_main->dbdef_table->column('comments')
-     && $cust_main->comments )
+     && $cust_main->comments =~ /[^\s\n\r]/ )
 {
-  print "<BR>Comments", &ntable("#cccccc"), "<TR><TD>",
-        &ntable("#cccccc",2),
-        '<TR><TD BGCOLOR="#ffffff"><PRE>', $cust_main->comments,
+  print "<BR>Comments". &ntable("#cccccc"). "<TR><TD>".
+        &ntable("#cccccc",2).
+        '<TR><TD BGCOLOR="#ffffff"><PRE>'.
+        encode_entities($cust_main->comments).
         '</PRE></TD></TR></TABLE></TABLE>';
 }
 
@@ -254,43 +306,47 @@ print '<BR>'.
   qq!<INPUT TYPE="hidden" NAME="custnum" VALUE="$custnum">!.
   '<SELECT NAME="pkgpart"><OPTION> ';
 
-foreach my $type_pkgs ( qsearch('type_pkgs',{'typenum'=> $agent->typenum }) ) {
-  my $pkgpart = $type_pkgs->pkgpart;
-#  my $part_pkg = qsearchs('part_pkg', { 'pkgpart' => $pkgpart } )
-#    or do { warn "unknown type_pkgs.pkgpart $pkgpart"; next; };
-  my $part_pkg =
-    qsearchs('part_pkg', { 'pkgpart' => $pkgpart, 'disabled' => '' } )
-    or next;
-  print qq!<OPTION VALUE="$pkgpart">!. $part_pkg->pkg. ' - '.
+foreach my $part_pkg (
+  qsearch( 'part_pkg', { 'disabled' => '' }, '',
+           ' AND 0 < ( SELECT COUNT(*) FROM type_pkgs '.
+           '             WHERE typenum = '. $agent->typenum.
+           '             AND type_pkgs.pkgpart = part_pkg.pkgpart )'
+         )
+) {
+  print '<OPTION VALUE="'. $part_pkg->pkgpart. '">'. $part_pkg->pkg. ' - '.
         $part_pkg->comment;
 }
 
 print '</SELECT><INPUT TYPE="submit" VALUE="Order Package"></FORM><BR>';
 
-print '<BR>'.
-  qq!<FORM ACTION="${p}edit/process/quick-charge.cgi" METHOD="POST">!.
-  qq!<INPUT TYPE="hidden" NAME="custnum" VALUE="$custnum">!.
-  qq!Description:<INPUT TYPE="text" NAME="pkg">!.
-  qq!&nbsp;Amount:<INPUT TYPE="text" NAME="amount" SIZE=6>!.
-  qq!&nbsp;!;
-
-#false laziness w/ edit/part_pkg.cgi
-if ( $conf->exists('enable_taxclasses') ) {
-  print '<SELECT NAME="taxclass">';
-  my $sth = dbh->prepare('SELECT DISTINCT taxclass FROM cust_main_county')
-    or die dbh->errstr;
-  $sth->execute or die $sth->errstr;
-  foreach my $taxclass ( map $_->[0], @{$sth->fetchall_arrayref} ) {
-    print qq!<OPTION VALUE="$taxclass"!;
-    #print ' SELECTED' if $taxclass eq $hashref->{taxclass};
-    print qq!>$taxclass</OPTION>!;
+if ( $conf->config('payby-default') ne 'HIDE' ) {
+
+  print '<BR>'.
+    qq!<FORM ACTION="${p}edit/process/quick-charge.cgi" METHOD="POST">!.
+    qq!<INPUT TYPE="hidden" NAME="custnum" VALUE="$custnum">!.
+    qq!Description:<INPUT TYPE="text" NAME="pkg">!.
+    qq!&nbsp;Amount:<INPUT TYPE="text" NAME="amount" SIZE=6>!.
+    qq!&nbsp;!;
+  
+  #false laziness w/ edit/part_pkg.cgi
+  if ( $conf->exists('enable_taxclasses') ) {
+    print '<SELECT NAME="taxclass">';
+    my $sth = dbh->prepare('SELECT DISTINCT taxclass FROM cust_main_county')
+      or die dbh->errstr;
+    $sth->execute or die $sth->errstr;
+    foreach my $taxclass ( map $_->[0], @{$sth->fetchall_arrayref} ) {
+      print qq!<OPTION VALUE="$taxclass"!;
+      #print ' SELECTED' if $taxclass eq $hashref->{taxclass};
+      print qq!>$taxclass</OPTION>!;
+    }
+    print '</SELECT>';
+  } else {
+    print '<INPUT TYPE="hidden" NAME="taxclass" VALUE="">';
   }
-  print '</SELECT>';
-} else {
-  print '<INPUT TYPE="hidden" NAME="taxclass" VALUE="">';
-}
+  
+  print qq!<INPUT TYPE="submit" VALUE="One-time charge"></FORM><BR>!;
 
-print qq!<INPUT TYPE="submit" VALUE="One-time charge"></FORM><BR>!;
+}
 
 print <<END;
 <SCRIPT>
@@ -298,6 +354,10 @@ function cust_pkg_areyousure(href) {
     if (confirm("Permanently delete included services and cancel this package?") == true)
         window.location.href = href;
 }
+function svc_areyousure(href) {
+    if (confirm("Permanently unprovision and delete this service?") == true)
+        window.location.href = href;
+}
 </SCRIPT>
 END
 
@@ -306,131 +366,181 @@ print qq!<BR><A NAME="cust_pkg">Packages</A> !,
       qq!( <A HREF="!, popurl(2), qq!edit/cust_pkg.cgi?$custnum">Order and cancel packages</A> (preserves services) )!,
 ;
 
-#display packages
-
-#formatting
-print qq!!, &table(), "\n",
-      qq!<TR><TH COLSPAN=2 ROWSPAN=2>Package</TH><TH COLSPAN=5>!,
-      qq!Dates</TH><TH COLSPAN=2 ROWSPAN=2>Services</TH></TR>\n!,
-      qq!<TR><TH><FONT SIZE=-1>Setup</FONT></TH><TH>!,
-      qq!<FONT SIZE=-1>Next bill</FONT>!,
-      qq!</TH><TH><FONT SIZE=-1>Susp.</FONT></TH><TH><FONT SIZE=-1>Expire!,
-      qq!</FONT></TH>!,
-      qq!<TH><FONT SIZE=-1>Cancel</FONT></TH>!,
-      qq!</TR>\n!;
+#begin display packages
 
 #get package info
-my @packages;
-if ( $conf->exists('hidecancelledpackages') ) {
-  @packages = sort { $a->pkgnum <=> $b->pkgnum } ($cust_main->ncancelled_pkgs);
-} else {
-  @packages = sort { $a->pkgnum <=> $b->pkgnum } ($cust_main->all_pkgs);
-}
 
-my $n1 = '<TR>';
-foreach my $package (@packages) {
-  my $pkgnum = $package->pkgnum;
-  my $pkg = $package->part_pkg->pkg;
-  my $comment = $package->part_pkg->comment;
-  my $pkgview = popurl(2). "view/cust_pkg.cgi?$pkgnum";
+my $packages = get_packages($cust_main, $conf);
 
-  #my @cust_svc = qsearch( 'cust_svc', { 'pkgnum' => $pkgnum } );
-  #my $rowspan = scalar(@cust_svc) || 1;
-  my @cust_svc = ();
+if ( @$packages ) {
+%>
+<TABLE CLASS="package" BORDER=1 CELLSPACING=0 CELLPADDING=2 BORDERCOLOR="#999999">
+<TR>
+  <TH COLSPAN=2>Package</TH>
+  <TH>Status</TH>
+  <TH COLSPAN=2>Services</TH>
+</TR>
+<%
+foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) {
   my $rowspan = 0;
-  my %pkg_svc = ();
-  unless ( $package->getfield('cancel') ) {
-    foreach my $pkg_svc (
-      grep { $_->quantity }
-        qsearch('pkg_svc',{'pkgpart'=> $package->pkgpart })
-    ) {
-      $rowspan += ( $pkg_svc{$pkg_svc->svcpart} = $pkg_svc->quantity );
-    }
+
+  if ($pkg->{cancel}) {
+    $rowspan = 0;
   } else {
-    #@cust_svc = qsearch( 'cust_svc', { 'pkgnum' => $pkgnum } );
-    @cust_svc = ();
-    $rowspan = scalar(@cust_svc) || 1;
-  }
-  $rowspan ||= 1;
-
-  my $button_cgi = new CGI;
-  $button_cgi->param('clone', $package->part_pkg->pkgpart);
-  $button_cgi->param('pkgnum', $package->pkgnum);
-  my $button_url = popurl(2). "edit/part_pkg.cgi?". $button_cgi->query_string;
-
-  #print $n1, qq!<TD ROWSPAN=$rowspan><A HREF="$pkgview">$pkgnum</A></TD>!,
-  print $n1, qq!<TD ROWSPAN=$rowspan>$pkgnum</TD>!,
-        qq!<TD ROWSPAN=$rowspan><FONT SIZE=-1>!,
-        #qq!<A HREF="$pkgview">$pkg - $comment</A>!,
-        qq!$pkg - $comment (&nbsp;<a href="$pkgview">Details</a>&nbsp;)!;
-       # | !;
-
-  #false laziness with view/cust_pkg.cgi, but i'm trying to make that go away so
-  unless ( $package->getfield('cancel') ) {
-    print ' (&nbsp;';
-    if ( $package->getfield('susp') ) {
-      print qq!<A HREF="${p}misc/unsusp_pkg.cgi?$pkgnum">Unsuspend</A>!;
-    } else {
-      print qq!<A HREF="${p}misc/susp_pkg.cgi?$pkgnum">Suspend</A>!;
+    foreach my $svcpart (@{$pkg->{svcparts}}) {
+      $rowspan += $svcpart->{count};
+      $rowspan++ if ($svcpart->{count} < $svcpart->{quantity});
     }
-    print '&nbsp;|&nbsp;<A HREF="javascript:cust_pkg_areyousure(\''. popurl(2).
-          'misc/cancel_pkg.cgi?'. $pkgnum.  '\')">Cancel</A>';
-  
-    print '&nbsp;) ';
+  } 
 
-    print ' (&nbsp;<A HREF="'. popurl(2). 'edit/REAL_cust_pkg.cgi?'. $pkgnum.
-          '">Edit&nbsp;dates</A>&nbsp;|&nbsp;';
-        
-    print qq!<A HREF="$button_url">Customize</A>&nbsp;)!;
+%>
+<!--pkgnum: <%=$pkg->{pkgnum}%>-->
+<TR>
+  <TD ROWSPAN=<%=$rowspan%> CLASS="pkgnum"><%=$pkg->{pkgnum}%></TD>
+  <TD ROWSPAN=<%=$rowspan%>>
+    <%=$pkg->{pkg}%> - <%=$pkg->{comment}%> (&nbsp;<%=pkg_details_link($pkg)%>&nbsp;)<BR>
+<% unless ($pkg->{cancel}) { %>
+    (&nbsp;<%=pkg_change_link($pkg)%>&nbsp;)
+    (&nbsp;<%=pkg_dates_link($pkg)%>&nbsp;|&nbsp;<%=pkg_customize_link($pkg,$custnum)%>&nbsp;)
+<% } %>
+  </TD>
+<%
+  #foreach (qw(setup last_bill next_bill susp expire cancel)) {
+  #  print qq!  <TD ROWSPAN=$rowspan>! . pkg_datestr($pkg,$_,$conf) . qq!</TD>\n!;
+  #}
+  print "<TD ROWSPAN=$rowspan>". &itable('');
+
+  sub freq {
+
+    #false laziness w/edit/part_pkg.cgi
+    my %freq = ( #move this
+      '1d' => 'daily',
+      '1w' => 'weekly',
+      '2w' => 'biweekly (every 2 weeks)',
+      '1'  => 'monthly',
+      '2'  => 'bimonthly (every 2 months)',
+      '3'  => 'quarterly (every 3 months)',
+      '6'  => 'semiannually (every 6 months)',
+      '12' => 'annually',
+      '24' => 'biannually (every 2 years)',
+    );
 
+    my $freq = shift;
+    exists $freq{$freq} ? $freq{$freq} : "every&nbsp;$freq&nbsp;months";
   }
-  print '</FONT></TD>';
-
-  for ( qw( setup bill susp expire cancel ) ) {
-    print "<TD ROWSPAN=$rowspan><FONT SIZE=-1>", ( $package->getfield($_)
-            ? time2str("%D</FONT><BR><FONT SIZE=-3>%l:%M:%S%P&nbsp;%z</FONT>",
-              $package->getfield($_) )
-            :  '&nbsp'
-          ), '</FONT></TD>',
-    ;
-  }
 
-  my $n2 = '';
-  #false laziness with view/cust_pkg.cgi, but i'm trying to make that go away so
-  #foreach my $cust_svc ( @cust_svc ) {
-  foreach my $svcpart ( sort { $a<=>$b } keys %pkg_svc ) {
-    my $svc = qsearchs('part_svc',{'svcpart'=>$svcpart})->getfield('svc');
-    my(@cust_svc)=qsearch('cust_svc',{'pkgnum'=>$pkgnum, 
-                                      'svcpart'=>$svcpart,
-                                    });
-    for my $enum ( 1 .. $pkg_svc{$svcpart} ) {
-      my $cust_svc;
-      if ( $cust_svc = shift @cust_svc ) {
-        my($label, $value, $svcdb) = $cust_svc->label;
-        my($svcnum) = $cust_svc->svcnum;
-        my($sview) = popurl(2). "view";
-        print $n2,qq!<TD><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$label</FONT></A></TD>!,
-              qq!<TD><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$value</FONT></A></TD>!;
+  #eomove
+
+  if ( $pkg->{cancel} ) { #status: cancelled
+
+    print '<TR><TD><FONT COLOR="#ff0000"><B>Cancelled&nbsp;</B></FONT></TD>'.
+          '<TD>'. pkg_datestr($pkg,'cancel',$conf). '</TD></TR>';
+    unless ( $pkg->{setup} ) {
+      print '<TR><TD COLSPAN=2>Never billed</TD></TR>';
+    } else {
+      print "<TR><TD>Setup&nbsp;</TD><TD>".
+            pkg_datestr($pkg, 'setup',$conf). '</TD></TR>';
+      print "<TR><TD>Last&nbsp;bill&nbsp;</TD><TD>".
+            pkg_datestr($pkg, 'last_bill',$conf). '</TD></TR>'
+        if $pkg->{'last_bill'};
+      print "<TR><TD>Suspended&nbsp;</TD><TD>".
+            pkg_datestr($pkg, 'susp',$conf). '</TD></TR>'
+        if $pkg->{'susp'};
+    }
+
+  } else {
+
+    if ( $pkg->{susp} ) { #status: suspended
+      print '<TR><TD><FONT COLOR="#FF9900"><B>Suspended</B>&nbsp;</FONT></TD>'.
+            '<TD>'. pkg_datestr($pkg,'susp',$conf). '</TD></TR>';
+      unless ( $pkg->{setup} ) {
+        print '<TR><TD COLSPAN=2>Never billed</TD></TR>';
       } else {
-        print $n2, qq!<TD COLSPAN=2><A HREF="$uiadd{$svcpart}?pkgnum$pkgnum-svcpart$svcpart"><b><font size="+1" color="#ff0000">!.
-              qq!Provision $svc</A></b></font>!;
+        print "<TR><TD>Setup&nbsp;</TD><TD>". 
+              pkg_datestr($pkg, 'setup',$conf). '</TD></TR>';
+      }
+      print "<TR><TD>Last&nbsp;bill&nbsp;</TD><TD>".
+            pkg_datestr($pkg, 'last_bill',$conf). '</TD></TR>'
+        if $pkg->{'last_bill'};
+      # next bill ??
+      print "<TR><TD>Expires&nbsp;</TD><TD>".
+            pkg_datestr($pkg, 'expire',$conf). '</TD></TR>'
+        if $pkg->{'expire'};
+      print '<TR><TD COLSPAN=2>(&nbsp;'. pkg_unsuspend_link($pkg).
+            '&nbsp;|&nbsp;'. pkg_cancel_link($pkg). '&nbsp;)</TD></TR>';
+
+    } else { #status: active
+
+      unless ( $pkg->{setup} ) { #not setup
+
+        print '<TR><TD COLSPAN=2>Not&nbsp;yet&nbsp;billed&nbsp;(';
+        unless ( $pkg->{freq} ) {
+          print 'one-time&nbsp;charge)</TD></TR>';
+          print '<TR><TD COLSPAN=2>(&nbsp;'. pkg_cancel_link($pkg).
+                '&nbsp;)</TD</TR>';
+        } else {
+          print 'billed&nbsp;'. freq($pkg->{freq}). ')</TD></TR>';
+        }
+
+      } else { #setup
+
+        unless ( $pkg->{freq} ) {
+          print "<TR><TD COLSPAN=2>One-time&nbsp;charge</TD></TR>".
+                '<TR><TD>Billed&nbsp;</TD><TD>'.
+                pkg_datestr($pkg,'setup',$conf). '</TD></TR>';
+        } else {
+          print '<TR><TD COLSPAN=2><FONT COLOR="#00CC00"><B>Active</B></FONT>'.
+                ',&nbsp;billed&nbsp;'. freq($pkg->{freq}). '</TD></TR>'.
+                '<TR><TD>Setup&nbsp;</TD><TD>'.
+                pkg_datestr($pkg, 'setup',$conf). '</TD></TR>';
+        }
 
-        print qq!<BR><A HREF="../misc/link.cgi?pkgnum$pkgnum-svcpart$svcpart">!.
-              qq!<b><font size="+1" color="#ff0000">Link to legacy $svc</A></b></font>!
-          if $conf->exists('legacy_link');
+      }
 
-        print '</TD>';
+      print "<TR><TD>Last&nbsp;bill&nbsp;</TD><TD>".
+            pkg_datestr($pkg, 'last_bill',$conf). '</TD></TR>'
+        if $pkg->{'last_bill'};
+      print "<TR><TD>Next&nbsp;bill&nbsp;</TD><TD>".
+            pkg_datestr($pkg, 'next_bill',$conf). '</TD></TR>'
+        if $pkg->{'next_bill'};
+      print "<TR><TD>Expires&nbsp;</TD><TD>".
+            pkg_datestr($pkg, 'expire',$conf). '</TD></TR>'
+        if $pkg->{'expire'};
+      if ( $pkg->{freq} ) {
+        print '<TR><TD COLSPAN=2>(&nbsp;'. pkg_suspend_link($pkg).
+              '&nbsp;|&nbsp;'. pkg_cancel_link($pkg). '&nbsp;)</TD></TR>';
       }
-      $n2="</TR><TR>";
+
+    }
+
+  }
+
+  print "</TABLE></TD>\n";
+
+  if ($rowspan == 0) { print qq!</TR>\n!; next; }
+
+  my $cnt = 0;
+  foreach my $svcpart (sort {$a->{svcpart} <=> $b->{svcpart}} @{$pkg->{svcparts}}) {
+    foreach my $service (@{$svcpart->{services}}) {
+      print '<TR>' if ($cnt > 0);
+%>
+  <TD><%=svc_link($svcpart,$service)%></TD>
+  <TD><%=svc_label_link($svcpart,$service)%><BR>(&nbsp;<%=svc_unprovision_link($service)%>&nbsp;)</TD>
+</TR>
+<%
+      $cnt++;
+    }
+    if ($svcpart->{count} < $svcpart->{quantity}) {
+      print qq!<TR>\n! if ($cnt > 0);
+      print qq!  <TD COLSPAN=2>!.svc_provision_link($pkg,$svcpart).qq!</TD>\n</TR>\n!;
     }
   }
+}
+print '</TABLE>'
+}
 
-  $n1="</TR><TR>";
-}  
-print "</TR>";
+#end display packages
 
-#formatting
-print "</TABLE>";
 
 print <<END;
 <SCRIPT>
@@ -439,51 +549,157 @@ function cust_pay_areyousure(href) {
  == true)
         window.location.href = href;
 }
+function cust_pay_unapply_areyousure(href) {
+    if (confirm("Are you sure you want to unapply this payment?")
+ == true)
+        window.location.href = href;
+}
+function cust_credit_areyousure(href) {
+    if (confirm("Are you sure you want to delete this credit?")
+ == true)
+        window.location.href = href;
+}
 </SCRIPT>
 END
 
-#formatting
-print qq!<BR><BR><A NAME="history">Payment History!.
-      qq!</A> ( !.
-      qq!<A HREF="!. popurl(2). qq!edit/cust_pay.cgi?custnum=$custnum">!.
-      qq!Post payment</A> | !.
-      qq!<A HREF="!. popurl(2). qq!edit/cust_credit.cgi?$custnum">!.
-      qq!Post credit</A> )!;
-
-#get payment history
-#
-# major problem: this whole thing is way too sloppy.
-# minor problem: the description lines need better formatting.
-
-my @history = (); #needed for mod_perl :)
-
-my %target = ();
-
-my @bills = qsearch('cust_bill',{'custnum'=>$custnum});
-foreach my $bill (@bills) {
-  my($bref)=$bill->hashref;
-  my $bpre = ( $bill->owed > 0 )
-               ? '<b><font size="+1" color="#ff0000"> Open '
-               : '';
-  my $bpost = ( $bill->owed > 0 ) ? '</font></b>' : '';
-  push @history,
-    $bref->{_date} . qq!\t<A HREF="!. popurl(2). qq!view/cust_bill.cgi?! .
-    $bref->{invnum} . qq!">${bpre}Invoice #! . $bref->{invnum} .
-    qq! (Balance \$! . $bill->owed . qq!)$bpost</A>\t! .
-    $bref->{charged} . qq!\t\t\t!;
-
-  my(@cust_bill_pay)=qsearch('cust_bill_pay',{'invnum'=> $bref->{invnum} } );
-#  my(@payments)=qsearch('cust_pay',{'invnum'=> $bref->{invnum} } );
-#  my($payment);
-#  foreach $payment (@payments) {
-  foreach my $cust_bill_pay (@cust_bill_pay) {
-    my $payment = $cust_bill_pay->cust_pay;
-    my($date,$invnum,$payby,$payinfo,$paid)=($payment->_date,
-                                             $cust_bill_pay->invnum,
-                                             $payment->payby,
-                                             $payment->payinfo,
-                                             $cust_bill_pay->amount,
-                      );
+if ( $conf->config('payby-default') ne 'HIDE' ) {
+  
+  #formatting
+  print qq!<BR><BR><A NAME="history">Payment History!.
+        qq!</A> ( !.
+        qq!<A HREF="!. popurl(2). qq!edit/cust_pay.cgi?custnum=$custnum">!.
+        qq!Post payment</A> | !.
+        qq!<A HREF="!. popurl(2). qq!edit/cust_credit.cgi?$custnum">!.
+        qq!Post credit</A> )!;
+  
+  #get payment history
+  #
+  # major problem: this whole thing is way too sloppy.
+  # minor problem: the description lines need better formatting.
+  
+  my @history = (); #needed for mod_perl :)
+  
+  my %target = ();
+  
+  my @bills = qsearch('cust_bill',{'custnum'=>$custnum});
+  foreach my $bill (@bills) {
+    my($bref)=$bill->hashref;
+    my $bpre = ( $bill->owed > 0 )
+                 ? '<b><font size="+1" color="#ff0000"> Open '
+                 : '';
+    my $bpost = ( $bill->owed > 0 ) ? '</font></b>' : '';
+    push @history,
+      $bref->{_date} . qq!\t<A HREF="!. popurl(2). qq!view/cust_bill.cgi?! .
+      $bref->{invnum} . qq!">${bpre}Invoice #! . $bref->{invnum} .
+      qq! (Balance \$! . $bill->owed . qq!)$bpost</A>\t! .
+      $bref->{charged} . qq!\t\t\t!;
+  
+    my(@cust_bill_pay)=qsearch('cust_bill_pay',{'invnum'=> $bref->{invnum} } );
+  #  my(@payments)=qsearch('cust_pay',{'invnum'=> $bref->{invnum} } );
+  #  my($payment);
+    foreach my $cust_bill_pay (@cust_bill_pay) {
+      my $payment = $cust_bill_pay->cust_pay;
+      my($date,$invnum,$payby,$payinfo,$paid)=($payment->_date,
+                                               $cust_bill_pay->invnum,
+                                               $payment->payby,
+                                               $payment->payinfo,
+                                               $cust_bill_pay->amount,
+                        );
+      $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4))
+        if $payby eq 'CARD';
+      my $target = "$payby$payinfo";
+      $payby =~ s/^BILL$/Check #/ if $payinfo;
+      $payby =~ s/^(CARD|COMP)$/$1 /;
+      my $delete = $payment->closed !~ /^Y/i && $conf->exists('deletepayments')
+                     ? qq! (<A HREF="javascript:cust_pay_areyousure('${p}misc/delete-cust_pay.cgi?!. $payment->paynum. qq!')">delete</A>)!
+                     : '';
+      my $unapply =
+        $payment->closed !~ /^Y/i && $conf->exists('unapplypayments')
+          ? qq! (<A HREF="javascript:cust_pay_unapply_areyousure('${p}misc/unapply-cust_pay.cgi?!. $payment->paynum. qq!')">unapply</A>)!
+          : '';
+      push @history,
+        "$date\tPayment, Invoice #$invnum ($payby$payinfo)$delete$unapply\t\t$paid\t\t\t$target";
+    }
+  
+    my(@cust_credit_bill)=
+      qsearch('cust_credit_bill', { 'invnum'=> $bref->{invnum} } );
+    foreach my $cust_credit_bill (@cust_credit_bill) {
+      my $cust_credit = $cust_credit_bill->cust_credit;
+      my($date, $invnum, $crednum, $amount, $reason, $app_date ) = (
+        $cust_credit->_date,
+        $cust_credit_bill->invnum,
+        $cust_credit_bill->crednum,
+        $cust_credit_bill->amount,
+        $cust_credit->reason,
+        time2str("%D", $cust_credit_bill->_date),
+      );
+      my $delete =
+        $cust_credit->closed !~ /^Y/i && $conf->exists('deletecredits')
+          ? qq! (<A HREF="javascript:cust_credit_areyousure('${p}misc/delete-cust_credit.cgi?!. $cust_credit->crednum. qq!')">delete</A>)!
+          : '';
+      push @history,
+        "$date\tCredit #$crednum: $reason<BR>".
+        "(applied to invoice #$invnum on $app_date)$delete\t\t\t$amount\t";
+    }
+  }
+  
+  my @credits = grep { scalar(my @array = $_->cust_credit_refund) }
+             qsearch('cust_credit',{'custnum'=>$custnum});
+  foreach my $credit (@credits) {
+    my($cref)=$credit->hashref;
+    my(@cust_credit_refund)=
+      qsearch('cust_credit_refund', { 'crednum'=> $cref->{crednum} } );
+    foreach my $cust_credit_refund (@cust_credit_refund) {
+      my $cust_refund = $cust_credit_refund->cust_credit;
+      my($date, $crednum, $amount, $reason, $app_date ) = (
+        $credit->_date,
+        $credit->crednum,
+        $cust_credit_refund->amount,
+        $credit->reason,
+        time2str("%D", $cust_credit_refund->_date),
+      );
+      push @history,
+        "$date\tCredit #$crednum: $reason<BR>".
+        "(applied to refund on $app_date)\t\t\t$amount\t";
+    }
+  }
+  
+  @credits = grep { $_->credited  > 0 }
+             qsearch('cust_credit',{'custnum'=>$custnum});
+  foreach my $credit (@credits) {
+    my($cref)=$credit->hashref;
+    my $delete =
+      $credit->closed !~ /^Y/i && $conf->exists('deletecredits')
+        ? qq! (<A HREF="javascript:cust_credit_areyousure('${p}misc/delete-cust_credit.cgi?!. $credit->crednum. qq!')">delete</A>)!
+        : '';
+    push @history,
+      $cref->{_date} . "\t" .
+      qq!<A HREF="! . popurl(2). qq!edit/cust_credit_bill.cgi?!. $cref->{crednum} . qq!">!.
+      '<b><font size="+1" color="#ff0000">Unapplied credit #' .
+      $cref->{crednum} . "</font></b></A>: ".
+      $cref->{reason} . "$delete\t\t\t" . $credit->credited . "\t";
+  }
+  
+  my(@refunds)=qsearch('cust_refund',{'custnum'=> $custnum } );
+  foreach my $refund (@refunds) {
+    my($rref)=$refund->hashref;
+    my($refundnum) = (
+      $refund->refundnum,
+    );
+  
+    push @history,
+      $rref->{_date} . "\tRefund #$refundnum, (" .
+      $rref->{payby} . " " . $rref->{payinfo} . ") by " .
+      $rref->{otaker} . " - ". $rref->{reason} . "\t\t\t\t" .
+      $rref->{refund};
+  }
+  
+  my @unapplied_payments =
+    grep { $_->unapplied > 0 } qsearch('cust_pay', { 'custnum' => $custnum } );
+  foreach my $payment (@unapplied_payments) {
+    my $payby = $payment->payby;
+    my $payinfo = $payment->payinfo;
+    #false laziness w/above
     $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4))
       if $payby eq 'CARD';
     my $target = "$payby$payinfo";
@@ -493,161 +709,257 @@ foreach my $bill (@bills) {
                    ? qq! (<A HREF="javascript:cust_pay_areyousure('${p}misc/delete-cust_pay.cgi?!. $payment->paynum. qq!')">delete</A>)!
                    : '';
     push @history,
-      "$date\tPayment, Invoice #$invnum ($payby$payinfo)$delete\t\t$paid\t\t\t$target";
+      $payment->_date. "\t".
+      '<b><font size="+1" color="#ff0000">Unapplied payment #' .
+      $payment->paynum . " ($payby$payinfo)</font></b> ".
+      '(<A HREF="'. popurl(2). 'edit/cust_bill_pay.cgi?'. $payment->paynum. '">'.
+      "apply</A>)$delete".
+      "\t\t" . $payment->unapplied . "\t\t\t$target";
   }
-
-  my(@cust_credit_bill)=
-    qsearch('cust_credit_bill', { 'invnum'=> $bref->{invnum} } );
-  foreach my $cust_credit_bill (@cust_credit_bill) {
-    my $cust_credit = $cust_credit_bill->cust_credit;
-    my($date, $invnum, $crednum, $amount, $reason, $app_date ) = (
-      $cust_credit->_date,
-      $cust_credit_bill->invnum,
-      $cust_credit_bill->crednum,
-      $cust_credit_bill->amount,
-      $cust_credit->reason,
-      time2str("%D", $cust_credit_bill->_date),
-    );
-    push @history,
-      "$date\tCredit #$crednum: $reason<BR>".
-      "(applied to invoice #$invnum on $app_date)\t\t\t$amount\t";
+  
+          #formatting
+          print &table(), <<END;
+  <TR>
+    <TH>Date</TH>
+    <TH>Description</TH>
+    <TH><FONT SIZE=-1>Charge</FONT></TH>
+    <TH><FONT SIZE=-1>Payment</FONT></TH>
+    <TH><FONT SIZE=-1>In-house<BR>Credit</FONT></TH>
+    <TH><FONT SIZE=-1>Refund</FONT></TH>
+    <TH><FONT SIZE=-1>Balance</FONT></TH>
+  </TR>
+END
+  
+  #display payment history
+  
+  my $balance = 0;
+  foreach my $item (sort keyfield_numerically @history) {
+    my($date,$desc,$charge,$payment,$credit,$refund,$target)=split(/\t/,$item);
+    $charge ||= 0;
+    $payment ||= 0;
+    $credit ||= 0;
+    $refund ||= 0;
+    $balance += $charge - $payment;
+    $balance -= $credit - $refund;
+    $balance = sprintf("%.2f", $balance);
+    $balance =~ s/^\-0\.00$/0.00/; #yay ieee fp
+    $target = '' unless defined $target;
+  
+    print "<TR><TD><FONT SIZE=-1>";
+    print qq!<A NAME="$target">! unless $target && $target{$target}++;
+    print time2str("%D",$date);
+    print '</A>' if $target && $target{$target} == 1;
+    print "</FONT></TD>",
+       "<TD><FONT SIZE=-1>$desc</FONT></TD>",
+       "<TD><FONT SIZE=-1>",
+          ( $charge ? "\$".sprintf("%.2f",$charge) : '' ),
+          "</FONT></TD>",
+       "<TD><FONT SIZE=-1>",
+          ( $payment ? "-&nbsp;\$".sprintf("%.2f",$payment) : '' ),
+          "</FONT></TD>",
+       "<TD><FONT SIZE=-1>",
+          ( $credit ? "-&nbsp;\$".sprintf("%.2f",$credit) : '' ),
+          "</FONT></TD>",
+       "<TD><FONT SIZE=-1>",
+          ( $refund ? "\$".sprintf("%.2f",$refund) : '' ),
+          "</FONT></TD>",
+       "<TD><FONT SIZE=-1>\$" . $balance,
+          "</FONT></TD>",
+          "\n";
   }
+  
+  print "</TABLE>";
+
 }
 
-my @credits = grep { scalar(my @array = $_->cust_credit_refund) }
-           qsearch('cust_credit',{'custnum'=>$custnum});
-foreach my $credit (@credits) {
-  my($cref)=$credit->hashref;
-  my(@cust_credit_refund)=
-    qsearch('cust_credit_refund', { 'crednum'=> $cref->{crednum} } );
-  foreach my $cust_credit_refund (@cust_credit_refund) {
-    my $cust_refund = $cust_credit_refund->cust_credit;
-    my($date, $crednum, $amount, $reason, $app_date ) = (
-      $credit->_date,
-      $credit->crednum,
-      $cust_credit_refund->amount,
-      $credit->reason,
-      time2str("%D", $cust_credit_refund->_date),
-    );
-    push @history,
-      "$date\tCredit #$crednum: $reason<BR>".
-      "(applied to refund on $app_date)\t\t\t$amount\t";
+print '</BODY></HTML>';
+
+#subroutiens
+sub keyfield_numerically { (split(/\t/,$a))[0] <=> (split(/\t/,$b))[0]; }
+
+%>
+
+<%
+
+
+sub get_packages {
+  my $cust_main = shift or return undef;
+  my $conf = shift;
+  
+  my @packages = ();
+  
+  foreach my $cust_pkg (
+    $conf->exists('hidecancelledpackages')
+      ? $cust_main->ncancelled_pkgs
+      : $cust_main->all_pkgs
+  ) { 
+  
+    my $part_pkg = $cust_pkg->part_pkg;
+  
+    my %pkg = ();
+    $pkg{pkgnum} = $cust_pkg->pkgnum;
+    $pkg{pkg} = $part_pkg->pkg;
+    $pkg{pkgpart} = $part_pkg->pkgpart;
+    $pkg{comment} = $part_pkg->getfield('comment');
+    $pkg{freq} = $part_pkg->freq;
+    $pkg{setup} = $cust_pkg->getfield('setup');
+    $pkg{last_bill} = $cust_pkg->getfield('last_bill');
+    $pkg{next_bill} = $cust_pkg->getfield('bill');
+    $pkg{susp} = $cust_pkg->getfield('susp');
+    $pkg{expire} = $cust_pkg->getfield('expire');
+    $pkg{cancel} = $cust_pkg->getfield('cancel');
+  
+    my %svcparts = ();
+
+    foreach my $pkg_svc (
+      qsearch('pkg_svc', { 'pkgpart' => $part_pkg->pkgpart })
+    ) {
+  
+      next if ($pkg_svc->quantity == 0);
+  
+      my $part_svc = qsearchs('part_svc', { 'svcpart' => $pkg_svc->svcpart });
+  
+      my $svcpart = {};
+      $svcpart->{svcpart} = $part_svc->svcpart;
+      $svcpart->{svc} = $part_svc->svc;
+      $svcpart->{svcdb} = $part_svc->svcdb;
+      $svcpart->{quantity} = $pkg_svc->quantity;
+      $svcpart->{count} = 0;
+  
+      $svcpart->{services} = [];
+
+      $svcparts{$svcpart->{svcpart}} = $svcpart;
+
+    }
+
+    foreach my $cust_svc (
+      qsearch( 'cust_svc', {
+                             'pkgnum' => $cust_pkg->pkgnum,
+                             #'svcpart' => $part_svc->svcpart,
+                           }
+      )
+    ) {
+
+      warn "svcnum ". $cust_svc->svcnum. " / svcpart ". $cust_svc->svcpart. "\n";
+      my $svc = {
+        'svcnum' => $cust_svc->svcnum,
+        'label'  => ($cust_svc->label)[1],
+      };
+
+      #false laziness with above, to catch extraneous services.  whole
+      #damn thing should be OO...
+      my $svcpart = ( $svcparts{$cust_svc->svcpart} ||= {
+        'svcpart'  => $cust_svc->svcpart,
+        'svc'      => $cust_svc->part_svc->svc,
+        'svcdb'    => $cust_svc->part_svc->svcdb,
+        'quantity' => 0,
+        'count'    => 0,
+        'services' => [],
+      } );
+
+      push @{$svcpart->{services}}, $svc;
+
+      $svcpart->{count}++;
+
+    }
+
+    $pkg{svcparts} = [ values %svcparts ];
+
+    push @packages, \%pkg;
+  
   }
+  
+  return \@packages;
+
+}
+
+sub svc_link {
+
+  my ($svcpart, $svc) = (shift,shift) or return '';
+  return qq!<A HREF="${p}view/$svcpart->{svcdb}.cgi?$svc->{svcnum}">$svcpart->{svc}</A>!;
+
 }
 
-@credits = grep { $_->credited  > 0 }
-           qsearch('cust_credit',{'custnum'=>$custnum});
-foreach my $credit (@credits) {
-  my($cref)=$credit->hashref;
-  push @history,
-    $cref->{_date} . "\t" .
-    qq!<A HREF="! . popurl(2). qq!edit/cust_credit_bill.cgi?!. $cref->{crednum} . qq!">!.
-    '<b><font size="+1" color="#ff0000">Unapplied credit #' .
-    $cref->{crednum} . "</font></b></A>: ".
-    $cref->{reason} . "\t\t\t" . $credit->credited . "\t";
+sub svc_label_link {
+
+  my ($svcpart, $svc) = (shift,shift) or return '';
+  return qq!<A HREF="${p}view/$svcpart->{svcdb}.cgi?$svc->{svcnum}">$svc->{label}</A>!;
+
 }
 
-my(@refunds)=qsearch('cust_refund',{'custnum'=> $custnum } );
-foreach my $refund (@refunds) {
-  my($rref)=$refund->hashref;
-  my($refundnum) = (
-    $refund->refundnum,
-  );
-
-  push @history,
-    $rref->{_date} . "\tRefund #$refundnum, (" .
-    $rref->{payby} . " " . $rref->{payinfo} . ") by " .
-    $rref->{otaker} . " - ". $rref->{reason} . "\t\t\t\t" .
-    $rref->{refund};
+sub svc_provision_link {
+  my ($pkg, $svcpart) = (shift,shift) or return '';
+  ( my $svc_nbsp = $svcpart->{svc} ) =~ s/\s+/&nbsp;/g;
+  return qq!<A CLASS="provision" HREF="${p}edit/$svcpart->{svcdb}.cgi?! .
+         qq!pkgnum$pkg->{pkgnum}-svcpart$svcpart->{svcpart}">! .
+         "Provision&nbsp;$svc_nbsp&nbsp;(".
+         ($svcpart->{quantity} - $svcpart->{count}).
+         ')</A>';
 }
 
-my @unapplied_payments =
-  grep { $_->unapplied > 0 } qsearch('cust_pay', { 'custnum' => $custnum } );
-foreach my $payment (@unapplied_payments) {
-  my $payby = $payment->payby;
-  my $payinfo = $payment->payinfo;
-  #false laziness w/above
-  $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4))
-    if $payby eq 'CARD';
-  my $target = "$payby$payinfo";
-  $payby =~ s/^BILL$/Check #/ if $payinfo;
-  $payby =~ s/^(CARD|COMP)$/$1 /;
-  my $delete = $payment->closed !~ /^Y/i && $conf->exists('deletepayments')
-                 ? qq! (<A HREF="javascript:cust_pay_areyousure('${p}misc/delete-cust_pay.cgi?!. $payment->paynum. qq!')">delete</A>)!
-                 : '';
-  push @history,
-    $payment->_date. "\t".
-    '<b><font size="+1" color="#ff0000">Unapplied payment #' .
-    $payment->paynum . " ($payby$payinfo)</font></b> ".
-    '(<A HREF="'. popurl(2). 'edit/cust_bill_pay.cgi?'. $payment->paynum. '">'.
-    "apply</A>)$delete".
-    "\t\t" . $payment->unapplied . "\t\t\t$target";
+sub svc_unprovision_link {
+  my $svc = shift or return '';
+  return qq!<A HREF="javascript:svc_areyousure('${p}misc/unprovision.cgi?$svc->{svcnum}')">Unprovision</A>!;
 }
 
-        #formatting
-        print &table(), <<END;
-<TR>
-  <TH>Date</TH>
-  <TH>Description</TH>
-  <TH><FONT SIZE=-1>Charge</FONT></TH>
-  <TH><FONT SIZE=-1>Payment</FONT></TH>
-  <TH><FONT SIZE=-1>In-house<BR>Credit</FONT></TH>
-  <TH><FONT SIZE=-1>Refund</FONT></TH>
-  <TH><FONT SIZE=-1>Balance</FONT></TH>
-</TR>
-END
+# This should be generalized to use config options to determine order.
+sub pkgsort_pkgnum_cancel {
+  if ($a->{cancel} and $b->{cancel}) {
+    return ($a->{pkgnum} <=> $b->{pkgnum});
+  } elsif ($a->{cancel} or $b->{cancel}) {
+    return (-1) if ($b->{cancel});
+    return (1) if ($a->{cancel});
+    return (0);
+  } else {
+    return($a->{pkgnum} <=> $b->{pkgnum});
+  }
+}
+
+sub pkg_datestr {
+  my($pkg, $field, $conf) = @_ or return '';
+  return '&nbsp;' unless $pkg->{$field};
+  my $format = $conf->exists('pkg_showtimes')
+               ? '<B>%D</B>&nbsp;<FONT SIZE=-3>%l:%M:%S%P&nbsp;%z</FONT>'
+               : '<B>%b&nbsp;%o,&nbsp;%Y</B>';
+  ( my $strip = time2str($format, $pkg->{$field}) ) =~ s/ (\d)/$1/g;
+  $strip;
+}
 
-#display payment history
-
-my $balance = 0;
-foreach my $item (sort keyfield_numerically @history) {
-  my($date,$desc,$charge,$payment,$credit,$refund,$target)=split(/\t/,$item);
-  $charge ||= 0;
-  $payment ||= 0;
-  $credit ||= 0;
-  $refund ||= 0;
-  $balance += $charge - $payment;
-  $balance -= $credit - $refund;
-  $balance = sprintf("%.2f", $balance);
-  $balance =~ s/^\-0\.00$/0.00/; #yay ieee fp
-  $target = '' unless defined $target;
-
-  print "<TR><TD><FONT SIZE=-1>";
-  print qq!<A NAME="$target">! unless $target && $target{$target}++;
-  print time2str("%D",$date);
-  print '</A>' if $target && $target{$target} == 1;
-  print "</FONT></TD>",
-       "<TD><FONT SIZE=-1>$desc</FONT></TD>",
-       "<TD><FONT SIZE=-1>",
-        ( $charge ? "\$".sprintf("%.2f",$charge) : '' ),
-        "</FONT></TD>",
-       "<TD><FONT SIZE=-1>",
-        ( $payment ? "-&nbsp;\$".sprintf("%.2f",$payment) : '' ),
-        "</FONT></TD>",
-       "<TD><FONT SIZE=-1>",
-        ( $credit ? "-&nbsp;\$".sprintf("%.2f",$credit) : '' ),
-        "</FONT></TD>",
-       "<TD><FONT SIZE=-1>",
-        ( $refund ? "\$".sprintf("%.2f",$refund) : '' ),
-        "</FONT></TD>",
-       "<TD><FONT SIZE=-1>\$" . $balance,
-        "</FONT></TD>",
-        "\n";
+sub pkg_details_link {
+  my $pkg = shift or return '';
+  return qq!<a href="${p}view/cust_pkg.cgi?$pkg->{pkgnum}">Details</a>!;
 }
 
-#formatting
-print "</TABLE>";
+sub pkg_change_link {
+  my $pkg = shift or return '';
+  return qq!<a href="${p}misc/change_pkg.cgi?$pkg->{pkgnum}">Change&nbsp;package</a>!;
+}
 
-#end
+sub pkg_suspend_link {
+  my $pkg = shift or return '';
+  return qq!<a href="${p}misc/susp_pkg.cgi?$pkg->{pkgnum}">Suspend</a>!;
+}
 
-#formatting
-print <<END;
+sub pkg_unsuspend_link {
+  my $pkg = shift or return '';
+  return qq!<a href="${p}misc/unsusp_pkg.cgi?$pkg->{pkgnum}">Unsuspend</a>!;
+}
 
-  </BODY>
-</HTML>
-END
+sub pkg_cancel_link {
+  my $pkg = shift or return '';
+  return qq!<A HREF="javascript:cust_pkg_areyousure('${p}misc/cancel_pkg.cgi?$pkg->{pkgnum}')">Cancel</A>!;
+}
 
-#subroutiens
-sub keyfield_numerically { (split(/\t/,$a))[0] <=> (split(/\t/,$b))[0] ; }
+sub pkg_dates_link {
+  my $pkg = shift or return '';
+  return qq!<A HREF="${p}edit/REAL_cust_pkg.cgi?$pkg->{pkgnum}">Edit&nbsp;dates</A>!;
+}
+
+sub pkg_customize_link {
+  my $pkg = shift or return '';
+  my $custnum = shift;
+  return qq!<A HREF="${p}edit/part_pkg.cgi?keywords=$custnum;clone=$pkg->{pkgpart};pkgnum=$pkg->{pkgnum}">Customize</A>!;
+}
 
 %>
+
index 09a2a7a..5f0e6bf 100755 (executable)
@@ -68,10 +68,16 @@ print &ntable("#cccccc"), '<TR><TD>', &ntable("#cccccc",2),
       '<TR><TD ALIGN="right">Comment</TD><TD BGCOLOR="#ffffff">',
       $comment,  '</TD></TR>',
       '<TR><TD ALIGN="right">Setup date</TD><TD BGCOLOR="#ffffff">',
-      ( $setup ? time2str("%D",$setup) : "(Not setup)" ), '</TD></TR>',
-      '<TR><TD ALIGN="right">Next bill date</TD><TD BGCOLOR="#ffffff">',
-      ( $bill ? time2str("%D",$bill) : "&nbsp;" ), '</TD></TR>',
-;
+      ( $setup ? time2str("%D",$setup) : "(Not setup)" ), '</TD></TR>';
+
+print '<TR><TD ALIGN="right">Last bill date</TD><TD BGCOLOR="#ffffff">',
+      ( $cust_pkg->get('last_bill') ? time2str("%D",$cust_pkg->get('last_bill')) : "&nbsp;" ),
+      '</TD></TR>'
+  if $cust_pkg->dbdef_table->column('last_bill');
+
+print '<TR><TD ALIGN="right">Next bill date</TD><TD BGCOLOR="#ffffff">',
+      ( $bill ? time2str("%D",$bill) : "&nbsp;" ), '</TD></TR>';
+      
 print '<TR><TD ALIGN="right">Suspension date</TD><TD BGCOLOR="#ffffff">',
        time2str("%D",$susp), '</TD></TR>' if $susp;
 print '<TR><TD ALIGN="right">Expiration date</TD><TD BGCOLOR="#ffffff">',
@@ -80,15 +86,16 @@ print '<TR><TD ALIGN="right">Cancellation date</TD><TD BGCOLOR="#ffffff">',
        time2str("%D",$cancel), '</TD></TR>' if $cancel;
 print  '<TR><TD ALIGN="right">Order taker</TD><TD BGCOLOR="#ffffff">',
       $otaker,  '</TD></TR>',
-      '</TABLE></TD></TR></TABLE>'
-;
-
-#  print <<END;
-#<FORM ACTION="../misc/expire_pkg.cgi" METHOD="post">
-#<INPUT TYPE="hidden" NAME="pkgnum" VALUE="$pkgnum">
-#Expire (date): <INPUT TYPE="text" NAME="date" VALUE="" >
-#<INPUT TYPE="submit" VALUE="Cancel later">
-#END
+      '</TABLE></TD></TR></TABLE>';
+
+unless ($expire) {
+  print <<END;
+<FORM ACTION="../misc/expire_pkg.cgi" METHOD="post">
+<INPUT TYPE="hidden" NAME="pkgnum" VALUE="$pkgnum">
+Expire (date): <INPUT TYPE="text" NAME="date" VALUE="" >
+<INPUT TYPE="submit" VALUE="Cancel later">
+END
+}
 
 unless ($cancel) {
 
index f6c1b02..58591fc 100755 (executable)
@@ -2,7 +2,6 @@
 <%
 
 my $conf = new FS::Conf;
-my $mydomain = $conf->config('domain');
 
 my($query) = $cgi->keywords;
 $query =~ /^(\d+)$/;
@@ -32,11 +31,7 @@ if ( $svc_acct->domsvc ) {
   die "Unknown domain" unless $svc_domain;
   $domain = $svc_domain->domain;
 } else {
-  unless ( $mydomain ) {
-    die "No legacy domain config file and no svc_domain.svcnum record ".
-        "for svc_acct.domsvc: ". $cust_svc->domsvc;
-  }
-  $domain = $mydomain;
+  die "No svc_domain.svcnum record for svc_acct.domsvc: ". $cust_svc->domsvc;
 }
 
 %>
@@ -61,6 +56,57 @@ function areyousure(href) {
 
 <%
 
+#if ( $cust_pkg && $cust_pkg->part_pkg->plan eq 'sqlradacct_hour' ) {
+if (    $part_svc->part_export('sqlradius')
+     || $part_svc->part_export('sqlradius_withdomain')
+) {
+
+  my $last_bill;
+  my %plandata;
+  if ( $cust_pkg ) {
+    #false laziness w/httemplate/edit/part_pkg... this stuff doesn't really
+    #belong in plan data
+    %plandata = map { /^(\w+)=(.*)$/; ( $1 => $2 ); }
+                    split("\n", $cust_pkg->part_pkg->plandata );
+
+    $last_bill = $cust_pkg->last_bill;
+  } else {
+    $last_bill = 0;
+    %plandata = ();
+  }
+
+  my $seconds = $svc_acct->seconds_since_sqlradacct( $last_bill, time );
+  my $hour = int($seconds/3600);
+  my $min = int( ($seconds%3600) / 60 );
+  my $sec = $seconds%60;
+
+  my $input = $svc_acct->attribute_since_sqlradacct(
+    $last_bill, time, 'AcctInputOctets'
+  ) / 1048576;
+  my $output = $svc_acct->attribute_since_sqlradacct(
+    $last_bill, time, 'AcctOutputOctets'
+  ) / 1048576;
+
+  if ( $seconds ) {
+    print "Online <B>$hour</B>h <B>$min</B>m <B>$sec</B>s";
+  } else {
+    print 'Has not logged on';
+  }
+
+  if ( $cust_pkg ) {
+    print ' since last bill ('. time2str("%C", $last_bill). ') - '. 
+          $plandata{recur_included_hours}. ' total hours in plan<BR>';
+  } else {
+    print ' (no billing cycle available for unaudited account)<BR>';
+  }
+
+  print 'Input: <B>'. sprintf("%.3f", $input). '</B> megabytes<BR>';
+  print 'Output: <B>'. sprintf("%.3f", $output). '</B> megabytes<BR>';
+
+  print '<BR>';
+
+}
+
 #print qq!<BR><A HREF="../misc/sendconfig.cgi?$svcnum">Send account information</A>!;
 
 print qq!<A HREF="${p}edit/svc_acct.cgi?$svcnum">Edit this information</A><BR>!.
@@ -83,7 +129,7 @@ if ( $password =~ /^\*\w+\* (.*)$/ ) {
   print "<I>(login disabled)</I> ";
 }
 if ( $conf->exists('showpasswords') ) {
-  print "$password";
+  print '<PRE>'. encode_entities($password). '</PRE>';
 } else {
   print "<I>(hidden)</I>";
 }
@@ -96,7 +142,9 @@ if ( $conf->exists('security_phrase') ) {
         $svc_acct->sec_phrase. '</TD></TR>';
 }
 
-my $svc_acct_pop = qsearchs('svc_acct_pop',{'popnum'=>$svc_acct->popnum});
+my $svc_acct_pop = $svc_acct->popnum
+                     ? qsearchs('svc_acct_pop',{'popnum'=>$svc_acct->popnum})
+                     : '';
 print "<TR><TD ALIGN=\"right\">Access number</TD>".
       "<TD BGCOLOR=\"#ffffff\">". $svc_acct_pop->text. '</TD></TR>'
   if $svc_acct_pop;
@@ -126,7 +174,7 @@ if ($svc_acct->slipip) {
           : $svc_acct->slipip
         ). "</TD>";
   my($attribute);
-  foreach $attribute ( grep /^radius_/, fields('svc_acct') ) {
+  foreach $attribute ( grep /^radius_/, $svc_acct->fields ) {
     #warn $attribute;
     $attribute =~ /^radius_(.*)$/;
     my $pattribute = $FS::raddb::attrib{$1};
@@ -134,7 +182,7 @@ if ($svc_acct->slipip) {
           "<TD BGCOLOR=\"#ffffff\">". $svc_acct->getfield($attribute).
           "</TD></TR>";
   }
-  foreach $attribute ( grep /^rc_/, fields('svc_acct') ) {
+  foreach $attribute ( grep /^rc_/, $svc_acct->fields ) {
     #warn $attribute;
     $attribute =~ /^rc_(.*)$/;
     my $pattribute = $FS::raddb::attrib{$1};
@@ -149,8 +197,21 @@ if ($svc_acct->slipip) {
 print '<TR><TD ALIGN="right">RADIUS groups</TD><TD BGCOLOR="#ffffff">'.
       join('<BR>', $svc_acct->radius_groups). '</TD></TR>';
 
-print "</TABLE></TD></TR></TABLE>".
-      '<BR>'. joblisting({'svcnum'=>$svcnum}, 1).
-      "</BODY></HTML>";
+# Can this be abstracted further?  Maybe a library function like
+# widget('HTML', 'view', $svc_acct) ?  It would definitely make UI 
+# style management easier.
+
+foreach (sort { $a cmp $b } $svc_acct->virtual_fields) {
+  print $svc_acct->pvf($_)->widget('HTML', 'view', $svc_acct->getfield($_)),
+      "\n";
+}
+%>
+</TABLE></TD></TR></TABLE>
+<%
+
+print '<BR><BR>';
+
+print join("\n", $conf->config('svc_acct-notes') ). '<BR><BR>'.
+      joblisting({'svcnum'=>$svcnum}, 1). '</BODY></HTML>';
 
 %>
diff --git a/httemplate/view/svc_acct_sm.cgi b/httemplate/view/svc_acct_sm.cgi
deleted file mode 100755 (executable)
index 4e5acc4..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<!-- mason kludge -->
-<%
-
-my $conf = new FS::Conf;
-my $mydomain = $conf->config('domain');
-
-my($query) = $cgi->keywords;
-$query =~ /^(\d+)$/;
-my $svcnum = $1;
-my $svc_acct_sm = qsearchs('svc_acct_sm',{'svcnum'=>$svcnum});
-die "Unknown svcnum" unless $svc_acct_sm;
-
-my $cust_svc = qsearchs('cust_svc',{'svcnum'=>$svcnum});
-my $pkgnum = $cust_svc->getfield('pkgnum');
-my($cust_pkg, $custnum);
-if ($pkgnum) {
-  $cust_pkg=qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
-  $custnum=$cust_pkg->getfield('custnum');
-} else {
-  $cust_pkg = '';
-  $custnum = '';
-}
-
-my $part_svc = qsearchs('part_svc',{'svcpart'=> $cust_svc->svcpart } )
-  or die "Unkonwn svcpart";
-
-print header('Mail Alias View', menubar(
-  ( ( $pkgnum || $custnum )
-    ? ( "View this package (#$pkgnum)" => "${p}view/cust_pkg.cgi?$pkgnum",
-        "View this customer (#$custnum)" => "${p}view/cust_main.cgi?$custnum",
-      )
-    : ( "Cancel this (unaudited) account" =>
-          "${p}misc/cancel-unaudited.cgi?$svcnum" )
-  ),
-  "Main menu" => $p,
-));
-
-my($domsvc,$domuid,$domuser) = (
-  $svc_acct_sm->domsvc,
-  $svc_acct_sm->domuid,
-  $svc_acct_sm->domuser,
-);
-my $svc = $part_svc->svc;
-my $svc_domain = qsearchs('svc_domain',{'svcnum'=>$domsvc})
-  or die "Corrupted database: no svc_domain.svcnum matching domsvc $domsvc";
-my $domain = $svc_domain->domain;
-my $svc_acct = qsearchs('svc_acct',{'uid'=>$domuid})
-  or die "Corrupted database: no svc_acct.uid matching domuid $domuid";
-my $username = $svc_acct->username;
-
-print qq!<A HREF="${p}edit/svc_acct_sm.cgi?$svcnum">Edit this information</A>!,
-      "<BR>Service #$svcnum",
-      "<BR>Service: <B>$svc</B>",
-      qq!<BR>Mail to <B>!, ( ($domuser eq '*') ? "<I>(anything)</I>" : $domuser ) , qq!</B>\@<B>$domain</B> forwards to <B>$username</B>\@$mydomain mailbox.!,
-      '</BODY></HTML>'
-;
-
-%>
diff --git a/httemplate/view/svc_broadband.cgi b/httemplate/view/svc_broadband.cgi
new file mode 100644 (file)
index 0000000..a4ec756
--- /dev/null
@@ -0,0 +1,143 @@
+<!-- mason kludge -->
+<%
+
+my($query) = $cgi->keywords;
+$query =~ /^(\d+)$/;
+my $svcnum = $1;
+my $svc_broadband = qsearchs( 'svc_broadband', { 'svcnum' => $svcnum } )
+  or die "svc_broadband: Unknown svcnum $svcnum";
+
+#false laziness w/all svc_*.cgi
+my $cust_svc = qsearchs( 'cust_svc', { 'svcnum' => $svcnum } );
+my $pkgnum = $cust_svc->getfield('pkgnum');
+my($cust_pkg, $custnum);
+if ($pkgnum) {
+  $cust_pkg = qsearchs( 'cust_pkg', { 'pkgnum' => $pkgnum } );
+  $custnum = $cust_pkg->custnum;
+} else {
+  $cust_pkg = '';
+  $custnum = '';
+}
+#eofalse
+
+my $router = $svc_broadband->addr_block->router;
+
+if (not $router) { die "Could not lookup router for svc_broadband (svcnum $svcnum)" };
+
+my (
+     $routername,
+     $routernum,
+     $speed_down,
+     $speed_up,
+     $ip_addr
+   ) = (
+     $router->getfield('routername'),
+     $router->getfield('routernum'),
+     $svc_broadband->getfield('speed_down'),
+     $svc_broadband->getfield('speed_up'),
+     $svc_broadband->getfield('ip_addr')
+   );
+%>
+
+<%=header('Broadband Service View', menubar(
+  ( ( $custnum )
+    ? ( "View this package (#$pkgnum)" => "${p}view/cust_pkg.cgi?$pkgnum",
+        "View this customer (#$custnum)" => "${p}view/cust_main.cgi?$custnum",
+      )                                                                       
+    : ( "Cancel this (unaudited) website" =>
+          "${p}misc/cancel-unaudited.cgi?$svcnum" )
+  ),
+  "Main menu" => $p,
+))
+%>
+
+<A HREF="<%=${p}%>edit/svc_broadband.cgi?<%=$svcnum%>">Edit this information</A>
+<BR>
+<%=ntable("#cccccc")%>
+  <TR>
+    <TD>
+      <%=ntable("#cccccc",2)%>
+        <TR>
+          <TD ALIGN="right">Service number</TD>
+          <TD BGCOLOR="#ffffff"><%=$svcnum%></TD>
+        </TR>
+        <TR>
+          <TD ALIGN="right">Router</TD>
+          <TD BGCOLOR="#ffffff"><%=$routernum%>: <%=$routername%></TD>
+        </TR>
+        <TR>
+          <TD ALIGN="right">Download Speed</TD>
+          <TD BGCOLOR="#ffffff"><%=$speed_down%></TD>
+        </TR>
+        <TR>
+          <TD ALIGN="right">Upload Speed</TD>
+          <TD BGCOLOR="#ffffff"><%=$speed_up%></TD>
+        </TR>
+        <TR>
+          <TD ALIGN="right">IP Address</TD>
+          <TD BGCOLOR="#ffffff"><%=$ip_addr%></TD>
+        </TR>
+        <TR COLSPAN="2"><TD></TD></TR>
+
+<%
+foreach (sort { $a cmp $b } $svc_broadband->virtual_fields) {
+  print $svc_broadband->pvf($_)->widget('HTML', 'view',
+                                        $svc_broadband->getfield($_)), "\n";
+}
+
+%>
+      </TABLE>
+    </TD>
+  </TR>
+</TABLE>
+
+<BR>
+<%=ntable("#cccccc", 2)%>
+<%
+  my $sb_router = qsearchs('router', { svcnum => $svcnum });
+  if ($sb_router) {
+  %>
+  <B>Router associated: <%=$sb_router->routername%> </B>
+  <A HREF="<%=popurl(2)%>edit/router.cgi?<%=$sb_router->routernum%>">
+    (details)
+  </A>
+  <BR>
+  <% my @addr_block;
+     if (@addr_block = $sb_router->addr_block) {
+     %>
+  <B>Address space </B>
+  <A HREF="<%=popurl(2)%>browse/addr_block.cgi">
+    (edit)
+  </A>
+  <BR>
+  <%   print ntable("#cccccc", 1);
+       foreach (@addr_block) { %>
+    <TR>
+      <TD><%=$_->ip_gateway%>/<%=$_->ip_netmask%></TD>
+    </TR>
+    <% } %>
+  </TABLE>
+  <% } else { %>
+  <B>No address space allocated.</B>
+    <% } %>
+  <BR>
+  <%
+  } else {
+%>
+
+<FORM METHOD="GET" ACTION="<%=popurl(2)%>edit/router.cgi">
+  <INPUT TYPE="hidden" NAME="svcnum" VALUE="<%=$svcnum%>">
+Add router named 
+  <INPUT TYPE="text" NAME="routername" SIZE="32" VALUE="Broadband router (<%=$svcnum%>)">
+  <INPUT TYPE="submit" VALUE="Add router">
+</FORM>
+
+<%
+}
+%>
+
+<BR>
+<%=joblisting({'svcnum'=>$svcnum}, 1)%>
+  </BODY>
+</HTML>
+
index b70ac8f..fd017de 100755 (executable)
@@ -46,7 +46,7 @@ my $domain = $svc_domain->domain;
 Service #<%= $svcnum %>
 <BR>Service: <B><%= $part_svc->svc %></B>
 <BR>Domain name: <B><%= $domain %></B>
-<BR>Catch all email <A HREF="${p}misc/catchall.cgi?<%= $svcnum %>">(change)</A>:
+<BR>Catch all email <A HREF="<%= ${p} %>misc/catchall.cgi?<%= $svcnum %>">(change)</A>:
 <%= $email ? "<B>$email</B>" : "<I>(none)<I>" %>
 <BR><BR><A HREF="http://www.geektools.com/cgi-bin/proxy.cgi?query=<%=$domain%>;targetnic=auto">View whois information.</A>
 <BR><BR>
@@ -85,7 +85,7 @@ Service #<%= $svcnum %>
 <INPUT TYPE="text" NAME="reczone"> 
 <INPUT TYPE="hidden" NAME="recaf" VALUE="IN"> IN 
  <SELECT NAME="rectype">
-<% foreach (qw( A NS CNAME MX) ) { %>
+<% foreach (qw( A NS CNAME MX PTR) ) { %>
   <OPTION VALUE="<%=$_%>"><%=$_%></OPTION>
 <% } %>
  </SELECT>
diff --git a/httemplate/view/svc_external.cgi b/httemplate/view/svc_external.cgi
new file mode 100644 (file)
index 0000000..e5c977f
--- /dev/null
@@ -0,0 +1,52 @@
+<!-- mason kludge -->
+<%
+
+my($query) = $cgi->keywords;
+$query =~ /^(\d+)$/;
+my $svcnum = $1;
+my $svc_external = qsearchs( 'svc_external', { 'svcnum' => $svcnum } )
+  or die "svc_external: Unknown svcnum $svcnum";
+
+#false laziness w/all svc_*.cgi
+my $cust_svc = qsearchs( 'cust_svc', { 'svcnum' => $svcnum } );
+my $pkgnum = $cust_svc->getfield('pkgnum');
+my($cust_pkg, $custnum);
+if ($pkgnum) {
+  $cust_pkg = qsearchs( 'cust_pkg', { 'pkgnum' => $pkgnum } );
+  $custnum = $cust_pkg->custnum;
+} else {
+  $cust_pkg = '';
+  $custnum = '';
+}
+#eofalse
+
+%>
+
+<%= header('External Service View', menubar(
+  ( ( $custnum )
+    ? ( "View this package (#$pkgnum)" => "${p}view/cust_pkg.cgi?$pkgnum",
+        "View this customer (#$custnum)" => "${p}view/cust_main.cgi?$custnum",
+      )                                                                       
+    : ( "Cancel this (unaudited) external service" =>
+          "${p}misc/cancel-unaudited.cgi?$svcnum" )
+  ),
+  "Main menu" => $p,
+)) %>
+
+<A HREF="<%=$p%>edit/svc_external.cgi?<%=$svcnum%>">Edit this information</A><BR>
+<%= ntable("#cccccc") %><TR><TD><%= ntable("#cccccc",2) %>
+
+<TR><TD ALIGN="right">Service number</TD>
+  <TD BGCOLOR="#ffffff"><%= $svcnum %></TD></TR>
+<TR><TD ALIGN="right">External ID</TD>
+  <TD BGCOLOR="#ffffff"><%= $svc_external->id %></TD></TR>
+<TR><TD ALIGN="right">Title</TD>
+  <TD BGCOLOR="#ffffff"><%= $svc_external->title %></TD></TR>
+
+<% foreach (sort { $a cmp $b } $svc_external->virtual_fields) { %>
+  <%= $svc_external->pvf($_)->widget('HTML', 'view', $svc_external->getfield($_)) %>
+<% } %>
+
+</TABLE></TD></TR></TABLE>
+<BR><%= joblisting({'svcnum'=>$svcnum}, 1) %>
+</BODY></HTML>
index c8d1d62..6509724 100755 (executable)
@@ -28,7 +28,7 @@ print header('Mail Forward View', menubar(
     ? ( "View this package (#$pkgnum)" => "${p}view/cust_pkg.cgi?$pkgnum",
         "View this customer (#$custnum)" => "${p}view/cust_main.cgi?$custnum",
       )
-    : ( "Cancel this (unaudited) account" =>
+    : ( "Cancel this (unaudited) mail forward" =>
           "${p}misc/cancel-unaudited.cgi?$svcnum" )
   ),
   "Main menu" => $p,
@@ -39,16 +39,25 @@ my($srcsvc,$dstsvc,$dst) = (
   $svc_forward->dstsvc,
   $svc_forward->dst,
 );
+my $src = $svc_forward->dbdef_table->column('src') ? $svc_forward->src : '';
+
 my $svc = $part_svc->svc;
-my $svc_acct = qsearchs('svc_acct',{'svcnum'=>$srcsvc})
-  or die "Corrupted database: no svc_acct.svcnum matching srcsvc $srcsvc";
-my $source = $svc_acct->email;
+
+my $source;
+if ($srcsvc) {
+  my $svc_acct = qsearchs('svc_acct',{'svcnum'=>$srcsvc})
+    or die "Corrupted database: no svc_acct.svcnum matching srcsvc $srcsvc";
+  $source = $svc_acct->email;
+} else {
+  $source = $src;
+}
+
 my $destination;
 if ($dstsvc) {
   my $svc_acct = qsearchs('svc_acct',{'svcnum'=>$dstsvc})
     or die "Corrupted database: no svc_acct.svcnum matching dstsvc $dstsvc";
   $destination = $svc_acct->email;
-}else{
+} else {
   $destination = $dst;
 }
 
@@ -61,7 +70,14 @@ print qq!<A HREF="${p}edit/svc_forward.cgi?$svcnum">Edit this information</A>!.
       qq!<TR><TD ALIGN="right">Email to</TD>!.
         qq!<TD BGCOLOR="#ffffff">$source</TD></TR>!.
       qq!<TR><TD ALIGN="right">Forwards to </TD>!.
-        qq!<TD BGCOLOR="#ffffff">$destination</TD></TR></TABLE>!.
+        qq!<TD BGCOLOR="#ffffff">$destination</TD></TR>!;
+
+foreach (sort { $a cmp $b } $svc_forward->virtual_fields) {
+  print $svc_forward->pvf($_)->widget('HTML', 'view', $svc_forward->getfield($_)),
+      "\n";
+}
+
+print qq!  </TABLE>!.
       '<BR>'. joblisting({'svcnum'=>$svcnum}, 1).
       '</BODY></HTML>'
 ;
index 9fa9661..7a716b4 100644 (file)
@@ -28,11 +28,7 @@ my $email = $svc_acct->email;
 my $domain_record = qsearchs('domain_record', { 'recnum' => $svc_www->recnum } )
   or die "svc_www: Unknown recnum ". $svc_www->recnum;
 
-my $www = $domain_record->reczone;
-unless ( $www =~ /\.$/ ) {
-  my $svc_domain = qsearchs('svc_domain', { svcnum=>$domain_record->svcnum } );
-  $www .= '.'. $svc_domain->domain;
-}
+my $www = $domain_record->zone;
 
 print header('Website View', menubar(
   ( ( $custnum )
@@ -51,8 +47,15 @@ print header('Website View', menubar(
       qq!<TR><TD ALIGN="right">Website name</TD>!.
         qq!<TD BGCOLOR="#ffffff"><A HREF="http://$www">$www<A></TD></TR>!.
       qq!<TR><TD ALIGN="right">Account</TD>!.
-        qq!<TD BGCOLOR="#ffffff"><A HREF="${p}view/svc_acct.cgi?$usersvc">$email</A></TD></TR>!.
-      '</TABLE></TD></TR></TABLE>'.
+        qq!<TD BGCOLOR="#ffffff"><A HREF="${p}view/svc_acct.cgi?$usersvc">$email</A></TD></TR>!;
+
+foreach (sort { $a cmp $b } $svc_www->virtual_fields) {
+  print $svc_www->pvf($_)->widget('HTML', 'view', $svc_www->getfield($_)),
+      "\n";
+}
+
+
+print '</TABLE></TD></TR></TABLE>'.
       '<BR>'. joblisting({'svcnum'=>$svcnum}, 1).
       '</BODY></HTML>'
 ;
index d3016b2..1ca7dff 100644 (file)
@@ -7,13 +7,8 @@ QUEUED_USER=%%%QUEUED_USER%%%
 
 FREESIDE_PATH="%%%FREESIDE_PATH%%%"
 
-PASSWD_USER=%%%PASSWD_USER%%%
-PASSWD_MACHINE=%%%PASSWD_MACHINE%%%
-
-SIGNUP_USER=%%%SIGNUP_USER%%%
-SIGNUP_MACHINE=%%%SIGNUP_MACHINE%%%
-SIGNUP_AGENTNUM=%%%SIGNUP_AGENTNUM%%%
-SIGNUP_REFNUM=%%%SIGNUP_REFNUM%%%
+SELFSERVICE_USER=%%%SELFSERVICE_USER%%%
+SELFSERVICE_MACHINES="%%%SELFSERVICE_MACHINES%%%"
 
 case "$1" in
   start)
@@ -22,13 +17,12 @@ case "$1" in
         freeside-queued $QUEUED_USER
         echo "done."
 
-        echo -n "Starting fs_passwd_server: "
-        su freeside -c "$FREESIDE_PATH/fs_passwd/fs_passwd_server $PASSWD_USER $PASSWD_MACHINE" &
-        echo "done."
+        for MACHINE in $SELFSERVICE_MACHINES; do
+          echo -n "Starting freeside-selfservice-server to $MACHINE: "
+          freeside-selfservice-server $SELFSERVICE_USER $MACHINE
+          echo "done."
+        done
 
-        echo -n "Starting fs_signup_server: "
-        su freeside -c "$FREESIDE_PATH/fs_signup/fs_signup_server $SIGNUP_USER $SIGNUP_MACHINE $SIGNUP_AGENTNUM $SIGNUP_REFNUM" &
-        echo "done."
         ;;
   stop)
         # Stop daemons.
@@ -36,13 +30,19 @@ case "$1" in
         kill `cat /var/run/freeside-queued.pid`
         echo "done."
 
-        echo -n "Stopping fs_passwd_server: "
-        killall fs_passwd_server
-        echo "done."
+        if [ -e /var/run/freeside-selfservice-server.$SELFSERVICE_USER.pid ]
+        then
+          echo -n "Stopping (old) freeside-selfservice-server: "
+          kill `cat /var/run/freeside-selfservice-server.$SELFSERVICE_USER.pid`
+          rm /var/run/freeside-selfservice-server.$SELFSERVICE_USER.pid
+        fi
+
+        for MACHINE in $SELFSERVICE_MACHINES; do
+          echo -n "Stopping freeside-selfservice-server to $MACHINE: "
+          kill `cat /var/run/freeside-selfservice-server.$SELFSERVICE_USER.$MACHINE.pid`
+          echo "done."
+        done
 
-        echo -n "Stopping fs_signup_server: "
-        killall fs_signup_server
-        echo "done."
         ;;
 
   restart)
diff --git a/install/debian/3.0/INSTALL b/install/debian/3.0/INSTALL
new file mode 100644 (file)
index 0000000..96991e8
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+echo "deb http://pouncequick.420.am/~ivan/freeside-woody/ ./" >>/etc/apt/sources.list
+
+apt-get update
+apt-get install screen zsh libapache-mod-ssl libapache-mod-perl rsync \
+        postgresql cvs fsh \
+        liburi-perl libhtml-tagset-perl libnet-perl liblocale-codes-perl \
+        libnet-whois-perl libwww-perl libbusiness-creditcard-perl \
+        libmailtools-perl libtimedate-perl libdate-manip-perl \
+        libfile-counterfile-perl libfreezethaw-perl libstring-approx-perl \
+        libtext-template-perl libdbi-perl libdbd-pg-perl \
+        libdbix-datasource-perl libdbix-dbschema-perl libnet-ssh-perl \
+        libstring-shellquote-perl libnet-scp-perl libapache-asp-perl \
+        libtie-ixhash-perl libtime-duration-perl \
+        libhtml-widgets-selectlayers-perl libstorable-perl \
+        libapache-dbi-perl libcache-cache-perl libdbd-mysql-perl
+
+useradd freeside
+su postgres -c "createuser -P freeside"
+
+su freeside -c "createdb freeside"
+
+#?
+cd ../../..
+make install-perl-modules
+make create-config
+freeside-adduser -c -h /usr/local/etc/freeside/htpasswd ivan
+su freeside -c 'freeside-setup ivan'
+su freeside -c '/home/ivan/freeside/bin/populate-msgcat ivan'
+make deploy
diff --git a/install/freebsd/INSTALL b/install/freebsd/INSTALL
new file mode 100755 (executable)
index 0000000..53fc613
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+( cd /usr/ports/sysutils/portupgrade
+  make install
+)
+
+pkgdb -u
+
+portinstall -PR cvsup-without-gui
+
+cp /usr/share/examples/cvsup/ports-supfile /root
+perl -pi -e 's/CHANGE_THIS/cvsup1/;' /root/ports-supfile
+cvsup /root/ports-supfile
+
+for port in `grep -v '^ *#' ports`; do
+  #cd /usr/ports/$port
+  #make install || exit
+  portinstall -P -R $port || exit
+done
+
+for a in Net::SSH DBIx::DBSchema HTML::Widgets::SelectLayers Time::Duration Business::CreditCard; do perl -MCPAN -e"install $a"; done
+
+su -l pgsql -c initdb
+
+/usr/local/etc/rc.d/010.pgsql.sh start
+
+pw user add freeside -m
+
+su -l pgsql -c 'createuser -P freeside'
+
+su -l freeside -c 'createdb freeside'
+
+#?
+cd ../..
+make install-perl-modules
+make create-config
+make deploy
+
+#edit apache config, etc.
+
diff --git a/install/freebsd/ports b/install/freebsd/ports
new file mode 100644 (file)
index 0000000..019c5e1
--- /dev/null
@@ -0,0 +1,44 @@
+shells/zsh
+misc/screen
+ftp/lftp
+www/apache13-modssl
+www/mod_perl
+net/rsync
+databases/postgresql7
+misc/p5-Array-PrintCols
+devel/p5-Term-Query
+converters/p5-MIME-Base64
+security/p5-Digest-MD5
+security/p5-MD5
+net/p5-URI
+www/p5-HTML-Tagset
+www/p5-HTML-Parser
+net/p5-Net
+misc/p5-Locale-Codes
+net/p5-Net-Whois
+www/p5-libwww
+     #misc/p5-Business-CreditCard
+devel/p5-Data-ShowTable
+mail/p5-Mail-Tools
+devel/p5-TimeDate
+devel/p5-Date-Manip
+misc/p5-File-CounterFile
+devel/p5-FreezeThaw
+devel/p5-String-Approx
+textproc/p5-Text-Template
+databases/p5-DBI
+databases/p5-DBD-Pg
+#databases/p5-DBD-mysql
+databases/p5-DBIx-DataSource
+    #database/p5-DBIx-DBSchema
+    #net/p5-Net-SSH
+textproc/p5-String-ShellQuote
+net/p5-Net-SCP
+www/p5-Apache-ASP
+    #www/p5-HTML-Mason
+devel/p5-Tie-IxHash
+    #devel/p5-Time-Duration
+    #www/p5-HTML-Widgets-SelectLayers
+devel/p5-Storable
+www/p5-Apache-DBI
+devel/p5-Cache-Cache
diff --git a/install/openbsd/INSTALL b/install/openbsd/INSTALL
new file mode 100644 (file)
index 0000000..1beef92
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+DIR=`pwd`
+
+#cd /usr/ports
+#cvs -q -d anoncvs@anoncvs6.usa.openbsd.org:/cvs up -r OPENBSD_`uname -r | perl -pe 's/\./_/g;'` -Pd
+
+for a in `grep -v '^ *#' $DIR/ports`
+do cd /usr/ports/$a
+  make install
+done
+
+for a in `grep -v '^ *#' $DIR/cpan`
+do perl -MCPAN -e "install $a"
+done
+
+#from /usr/local/share/doc/postgresql/README.OpenBSD
+useradd -c "PostgreSQL Admin User" -g =uid -m -d /var/postgresql -s /bin/sh postgresql
+
+su -l postgresql -c 'mkdir /var/postgresql/data'
+su -l postgresql -c 'initdb -D /var/postgresql/data'
+
+cat <<END >>/etc/rc.local
+if [ -x /usr/local/bin/pg_ctl ]; then
+        su -l postgresql -c "/usr/local/bin/pg_ctl start \
+                -D /var/postgresql/data -l /var/postgresql/logfile \
+                -o '-D /var/postgresql/data'"
+        echo -n ' postgresql'
+fi
+END
+
+cat <<END >>/etc/rc.shutdown
+if [ -f /var/postgresql/data/postmaster.pid ]; then
+        su -l postgresql -c "/usr/local/bin/pg_ctl stop -m fast \
+                -D /var/postgresql/data"
+        rm -f /var/postgresql/data/postmaster.pid
+fi
+
+su -l postgresql -c "/usr/local/bin/pg_ctl start \
+        -D /var/postgresql/data -l /var/postgresql/logfile \
+        -o '-D /var/postgresql/data'"
+
+useradd -c "Freeside" -g =uid -m freeside
+su -l postgresql -c 'createuser -P freeside'
+su -l freeside -c 'createdb freeside'
+
+#?
+cd ../..
+make install-perl-modules
+make create-config
+make deploy
+
+#edit apache config, etc.
+
diff --git a/install/openbsd/cpan b/install/openbsd/cpan
new file mode 100644 (file)
index 0000000..4304b72
--- /dev/null
@@ -0,0 +1,15 @@
+DBIx::DBSchema
+Time::Duration
+Business::CreditCard
+String::ShellQuote
+Net::SSH
+HTML::Mason
+HTML::Widgets::SelectLayers
+DBIx::DataSource
+Date::Manip
+String::Approx
+Tie::IxHash
+Date::Parse
+File::CounterFile
+Net::SCP
+Mail::Internet
diff --git a/install/openbsd/ports b/install/openbsd/ports
new file mode 100644 (file)
index 0000000..3e17d82
--- /dev/null
@@ -0,0 +1,24 @@
+shells/zsh
+misc/screen
+#www/apache13-modssl
+www/mod_perl
+net/rsync
+databases/postgresql
+converters/p5-MIME-Base64
+security/p5-Digest-MD5
+security/p5-MD5
+www/p5-HTML-Tagset
+www/p5-HTML-Parser
+net/p5-libnet
+misc/p5-Locale-Codes
+net/p5-Net-Whois
+www/p5-libwww
+#mail/p5-Mail-Tools
+devel/p5-FreezeThaw
+textproc/p5-Text-Template
+databases/p5-DBI
+databases/p5-DBD-Pg
+#databases/p5-DBD-Msql-Mysql
+www/p5-Apache-ASP
+devel/p5-Storable
+www/p5-Apache-DBI
diff --git a/install/redhat/7.3/INSTALL b/install/redhat/7.3/INSTALL
new file mode 100644 (file)
index 0000000..6befc05
--- /dev/null
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+wget --passive-ftp ftp://apt-rpm.tuxfamily.org/apt/redhat/7.3/en/i386/RPMS.extra/apt-*i386.rpm
+rpm -i apt*i386.rpm
+cp sources.list /etc/apt/
+apt-get update; apt-get update
+apt-get install apache mod_ssl mod_perl perl-CGI perl-CPAN perl-DBD-MySQL perl-DBD-Pg perl-DBI perl-DateManip perl-Digest-MD5 perl-HTML-Parser perl-HTML-Tagset perl-MIME-Base64 perl-Storable perl-TimeDate perl-URI perl-libnet perl-libwww-perl perl-suidperl rsync postgresql postgresql-docs postgresql-libs postgresql-server screen zsh lftp cvs #openssh
+
+perl -MCPAN -e"install Locale::Country, Net::Whois, Business::CreditCard, \
+                       Mail::Internet, File::CounterFile, FreezeThaw, \
+                       String::Approx, Text::Template, DBIx::DataSource, \
+                       DBIx::DBSchema, Net::SSH, String::ShellQuote, \
+                       Net::SCP, Apache::ASP, Tie::IxHash, Time::Duration, \
+                       HTML::Widgets::SelectLayers, Apache::DBI, Cache::Cache"
+
+useradd freeside
+
+chkconfig postgresql on
+/etc/init.d/postgresql start
+
+su postgres -c "createuser -P freeside"
+
+su freeside -c "createdb freeside"
+
+#?
+cd ../..
+make install-perl-modules
+make create-config
+freeside-adduser -c -h /usr/local/etc/freeside/htpasswd ivan
+su freeside -c 'freeside-setup ivan'
+su freeside -c '/home/ivan/freeside/bin/populate-msgcat ivan'
+make deploy
+
diff --git a/install/redhat/7.3/sources.list b/install/redhat/7.3/sources.list
new file mode 100644 (file)
index 0000000..9a9ad5c
--- /dev/null
@@ -0,0 +1,2 @@
+rpm ftp://apt-rpm.tuxfamily.org/apt redhat/7.3/en/i386 os updates extra
+rpm-src ftp://apt-rpm.tuxfamily.org/apt redhat/7.3/en/i386 os updates extra
diff --git a/install/redhat/9/INSTALL b/install/redhat/9/INSTALL
new file mode 100644 (file)
index 0000000..ee3cba9
--- /dev/null
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+
+wget --passive-ftp --continue ftp://apt-rpm.tuxfamily.org/apt/redhat/9/en/i386/RPMS.extra/apt-*i386.rpm
+rpm -i apt*i386.rpm
+cp sources.list /etc/apt/
+apt-get update; apt-get update
+#apt-get install apache mod_ssl mod_perl perl-CGI perl-CPAN perl-DBD-MySQL perl-DBD-Pg perl-DBI perl-DateManip perl-Digest-MD5 perl-HTML-Parser perl-HTML-Tagset perl-MIME-Base64 perl-Storable perl-TimeDate perl-URI perl-libnet perl-libwww-perl perl-suidperl rsync postgresql postgresql-docs postgresql-libs postgresql-server screen zsh lftp cvs #openssh
+
+apt-get install perl-Devel-Symdump perl-BSD-Resource rpm-build gdbm-devel expat-devel openssl-devel krb5-devel db4-devel
+
+wget --passive-ftp --continue http://reb00t.com/linux/RPMS/redhat-9/apache/apache-1.3.28-0.n0i.src.rpm http://reb00t.com/linux/RPMS/redhat-9/mm/mm-1.2.1-0.n0i.i686.rpm http://reb00t.com/linux/RPMS/redhat-9/mm/mm-devel-1.2.1-0.n0i.i686.rpm
+rpm -i mm-1.2.1-0.n0i.i686.rpm mm-devel-1.2.1-0.n0i.i686.rpm apache-1.3.28-0.n0i.src.rpm
+
+install -d /usr/src/redhat
+for a in BUILD RPMS SOURCES SPECS SRPMS; do install -d /usr/src/redhat/$a; done
+for a in athlon i386 i486 i586 i686 noarch; do install -d /usr/src/redhat/RPMS/$a; done
+
+cd /usr/src/redhat/SPECS  
+rpmbuild -ba apache.spec
+
+cd /usr/src/redhat/RPMS/i386
+rpm -i apache-1.3.28-0.n0i.i386.rpm
+
+apt-get install perl-CGI perl-CPAN perl-DBD-MySQL perl-DBD-Pg perl-DBI perl-DateManip perl-HTML-Parser perl-HTML-Tagset perl-TimeDate perl-URI perl-libwww-perl perl-suidperl rsync postgresql postgresql-docs postgresql-libs postgresql-server screen zsh lftp cvs gcc gd #openssh
+
+wget --passive-ftp --continue http://atrpms.physik.fu-berlin.de/dist/rh9/perl-GD/perl-GD-2.11-7.rh9.at.i386.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/atrpms/atrpms-45-1.rh9.at.noarch.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/yum/yum-2.0.4-28.rh9.at.noarch.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/gd/gd-2.0.15-1_6.rh9.at.i386.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/atrpms/atrpms-package-config-45-1.rh9.at.noarch.rpm
+
+cp /etc/apt/apt.conf /etc/apt/apt.conf.real
+
+rpm -i --replacefiles atrpms-package-config-45-1.rh9.at.noarch.rpm yum-2.0.4-28.rh9.at.noarch.rpm atrpms-45-1.rh9.at.noarch.rpm gd-2.0.15-1_6.rh9.at.i386.rpm perl-GD-2.11-7.rh9.at.i386.rpm
+
+mv /etc/apt/apt.conf.real /etc/apt/apt.conf
+
+perl -MCPAN -e"install Locale::Country, Net::Whois, Business::CreditCard, \
+                       Mail::Internet, File::CounterFile, FreezeThaw, \
+                       String::Approx, Text::Template, DBIx::DataSource, \
+                       DBIx::DBSchema, Net::SSH, String::ShellQuote, \
+                       Net::SCP, Apache::ASP, Tie::IxHash, Time::Duration, \
+                       HTML::Widgets::SelectLayers, Apache::DBI, Cache::Cache \
+                       Test::Pod NetAddr::IP IPC::ShareLite Chart::LinesPoints"
+
+echo 'OPTIONS="-DHAVE_PERL -DHAVE_SSL"' >>/etc/sysconfig/apache
+
+#remove perl & ssl LoadModule lines from /etc/httpd/conf/httpd.conf
+#as they're statically linked
+
+/usr/sbin/useradd freeside
+
+/sbin/chkconfig postgresql on
+/etc/init.d/postgresql start
+
+su postgres -c "createuser -P freeside"
+
+su freeside -c "createdb freeside"
+
+#?
+cd ../../..
+make install-perl-modules
+make create-config
+freeside-adduser -c -h /usr/local/etc/freeside/htpasswd ivan
+su freeside -c 'freeside-setup ivan'
+su freeside -c '/home/ivan/freeside/bin/populate-msgcat ivan'
+make deploy
+
diff --git a/install/redhat/9/sources.list b/install/redhat/9/sources.list
new file mode 100644 (file)
index 0000000..f6f21f4
--- /dev/null
@@ -0,0 +1,2 @@
+rpm ftp://apt-rpm.tuxfamily.org/apt redhat/9/en/i386 os updates extra
+rpm-src ftp://apt-rpm.tuxfamily.org/apt redhat/9/en/i386 os updates extra
diff --git a/rt/ChangeLog b/rt/ChangeLog
deleted file mode 100644 (file)
index 549a5ca..0000000
+++ /dev/null
@@ -1,16016 +0,0 @@
-2002-07-19 22:47  jesse
-
-       * README:
-
-       Fixed the readme about fastcgi
-       
-2002-07-19 22:42  jesse
-
-       * Makefile:
-
-       Bumped the version to 2.0.14
-       
-2002-07-19 01:22  jesse
-
-       * Makefile, bin/rt, webrt/Search/Bulk.html:
-
-       RT-Ticket: 1547
-       
-       Bumping the version to 2.0.14-pre4
-       Fixing a typo that pdh caught in Tickets/Bulk.html
-       
-2002-07-13 00:22  jesse
-
-       * Makefile:
-
-       Bumped to 2.0.14-pre3
-       
-2002-07-13 00:19  jesse
-
-       * bin/webmux.pl:
-
-       modperl handler now speaks Mason 1.11 properly.
-       
-2002-07-13 00:00  jesse
-
-       * etc/config.pm:
-
-       Shifted some config defaults to make things easier for newbie users
-       
-2002-07-12 13:31  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Now we properly strip long pathnames from attachments uploaded from windows boxes.
-       
-2002-07-11 01:41  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Fixing a typo in the mason 11 handler
-       
-2002-07-10 14:41  jesse
-
-       * Makefile:
-
-       Bumping the version to 2.0.14-pre2
-       
-2002-07-10 14:36  jesse
-
-       * lib/RT/User.pm:
-
-       [no log message]
-       
-2002-07-10 14:35  jesse
-
-       * lib/RT/: Queue.pm, Ticket.pm:
-
-       RT-Ticket: 1418
-       RT-Status: resolved
-       
-       minor perldoc cleanups from pdh@snapgear
-       
-2002-07-10 14:32  jesse
-
-       * bin/rt-mailgate, lib/RT/Action/SendEmail.pm:
-
-       RT-Ticket: 1425
-       RT-Status: resolved
-       RT-Milestone: 2.0.x
-       RT-Subsystem: Mail Sending
-       
-       Fixes to create more proper message ids.
-       
-2002-07-10 14:28  jesse
-
-       * lib/RT/Ticket.pm:
-
-       RT-Ticket: 1431
-       RT-Status: resolved
-       
-       Importing tickets now lets you set the "Resolved" date
-       
-2002-07-10 14:17  jesse
-
-       * lib/RT/Tickets.pm:
-
-       RT-Ticket: 1434
-       RT-Status: resolved
-       RT-Subsystem: Core
-       RT-Milestone: 2.0.x
-       
-       RT is now smarter about letting you do "or" searches on single-value
-       keyword selections. Thanks to sam hartman.
-       
-2002-07-10 14:15  jesse
-
-       * webrt/Ticket/: Display.html, ModifyAll.html:
-
-       RT-Ticket: 1433
-       RT-Status: resolved
-       RT-Milestone: 2.0.x
-       RT-Subsystem: HTML::Mason frontend
-       RT-Severity: Nice to have
-       RT-Broken In: 2.0.13
-       RT-Broken In: 2.0.12
-       RT-Broken In: 2.0.11
-       RT-Broken In: 2.0.10
-       RT-Broken In: 2.0.0
-       RT-Broken In: 2.0.1
-       RT-Broken In: 2.0.2
-       RT-Broken In: 2.0.3
-       RT-Broken In: 2.0.4
-       RT-Broken In: 2.0.5
-       RT-Broken In: 2.0.6
-       RT-Broken In: 2.0.7
-       RT-Broken In: 2.0.8
-       RT-Broken In: 2.0.9
-       
-       Some signatures weren't setting off the "don't record comments if the update
-       is only a signature" code. Fixed.
-       
-2002-07-10 13:59  jesse
-
-       * lib/RT/Transaction.pm:
-
-       RT-Ticket: 1501
-       RT-Status: resolved
-       
-       Fixing docs in Transaction.pm's Message method
-       
-2002-07-10 13:19  jesse
-
-       * bin/rt:
-
-       RT-Ticket: 1528
-       RT-Milestone: 2.0.x
-       RT-Subsystem: CLI
-       RT-Severity: Normal
-       RT-Status: resolved
-       
-       Fixed docs for cli to say that --limit-status=dead isn't a valid option
-       
-2002-06-26 15:22  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       support for mason 1.1
-       
-2002-06-26 15:19  jesse
-
-       * Makefile, bin/mason_handler.fcgi, bin/webmux.pl,
-       webrt/Admin/Queues/GroupRights.html,
-       webrt/Admin/Queues/UserRights.html, webrt/Elements/ListActions,
-       webrt/Ticket/Elements/ShowBasics, webrt/Ticket/Elements/ToolBar:
-
-       Adding support for mason 1.10
-       
-2002-06-26 15:15  jesse
-
-       * lib/RT/Action/Notify.pm:
-
-       Fixed notify cc behavior
-       
-2002-06-26 15:13  jesse
-
-       * lib/RT/Action/SendEmail.pm:
-
-       Fixed pseudo-list syntax in To: lines
-       
-2002-06-26 15:09  jesse
-
-       * webrt/Search/Bulk.html:
-
-       Added support for bulk comment/reply
-       
-2002-05-03 02:07  jesse
-
-       * lib/RT/Ticket.pm:
-
-       RT-Ticket: 1369
-       RT-Status: resolved
-       
-       When a ticket has another merged into it, it now has its "LastUpdated" date
-       updated
-       
-2002-05-03 01:58  jesse
-
-       * lib/RT/Ticket.pm:
-
-       RT-Ticket: 1412
-       RT-status: resolved
-       
-       Fixed a docs bug in Ticket->Import which didn't make it clear that Import
-       took an "Id" parameter and "Create" didn't.
-       
-2002-05-03 01:54  jesse
-
-       * webrt/autohandler:
-
-       rt-ticket: 1410
-       rt-status: resolved
-       
-       Applied a patch from rich lafferty which prevented NoAuth from not
-       requiring authentication on some fastcgi setups.
-       
-       A similar bug bit SelfService.
-       
-       This commit fixes that one too.
-       
-2002-05-03 01:51  jesse
-
-       * Makefile:
-
-       RT-Ticket: 1272
-       rt-status: resolved
-       
-       Applied a patch from Ilya Martynov which allows make insert to work
-       in a scenario where DESTDIR is being set to something funny This may be necessary when installing into AFS
-       
-2002-05-03 01:36  jesse
-
-       * lib/RT/Action/SendEmail.pm:
-
-       RT-Ticket: 1367
-       RT-Status: resolved
-       
-       Added a check which only sets precedence to bulk if it's not already set,
-       say by a template.
-       
-2002-05-03 01:30  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       RT-Ticket: 1370
-       RT-Status: resolved
-       
-       From: Jason Edgecombe <jedgecombe@carolina.rr.com>
-       To: rt-devel@lists.fsck.com
-       Subject: [rt-devel] An oversite in Interface/Email.pm
-       
-       Hi,
-       
-          I found an problem in Interface/Email.pm when I was modifying
-          enhanced mailgate. I have attached a diff of the modifications.
-       
-          In the function MailError, it assumes MIMIEOBJ is defined. I added a
-          simple "if" test to only run $MIMEOBJ->sync_headers if $MIMEOBJ is defined.
-       
-2002-05-03 01:24  jesse
-
-       * lib/RT/Action/SendEmail.pm:
-
-       RT-Ticket: 1348
-       RT-Status: resolved
-       
-       Fixed a bug in mail sending that improperly quoted the usernames of users
-       who had " in their names
-       
-2002-04-29 00:39  jesse
-
-       * lib/RT.pm:
-
-       Fixed a tiny typo
-       
-2002-04-28 23:46  jesse
-
-       * lib/RT.pm:
-
-       Fixed up the rt log messages.
-       
-2002-04-21 02:14  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Fixed a couple bugs in setting owners that were only revealed by the poor data
-       validation on rt.cpan.org
-       
-2002-04-21 02:06  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Fixed a couple bugs in setting owners that were only revealed by the poor data
-       validation on rt.cpan.org
-       
-2002-04-19 00:32  jesse
-
-       * Makefile:
-
-       Adding a new Makefile target to ease packaging.
-       
-2002-04-18 12:47  jesse
-
-       * lib/RT/GroupMember.pm:
-
-       RT-Ticket: 1385
-       RT-Broken-In: 2.0.0
-       RT-Broken-In: 2.0.1
-       RT-Broken-In: 2.0.2
-       RT-Broken-In: 2.0.3
-       RT-Broken-In: 2.0.4
-       RT-Broken-In: 2.0.5
-       RT-Broken-In: 2.0.6
-       RT-Broken-In: 2.0.7
-       RT-Broken-In: 2.0.8
-       RT-Broken-In: 2.0.9
-       RT-Broken-In: 2.0.10
-       RT-Broken-In: 2.0.11
-       RT-Broken-In: 2.0.12
-       RT-Broken-In: 2.0.13
-       RT-Status: resolved
-       
-       GroupMemmber was looking for the "ModifyGroups" right, when it should have
-       been looking for the "AdminGroups" right
-       
-2002-04-05 10:24  jesse
-
-       * webrt/Ticket/Update.html:
-
-       RT-Ticket: 1330
-       RT-Status: Resolved
-       
-       Fixed an html escaping bug in Ticket/Update.html
-       
-2002-03-27 22:59  jesse
-
-       * Makefile, lib/RT/User.pm:
-
-       Fixed a CRITICAL security bug that allowed remote administrative access
-       to RT without a password.  (Security advisory to follow)
-       
-2002-03-14 16:15  jesse
-
-       * Makefile:
-
-       Bumped the version to 2.0.12
-       
-2002-03-06 18:57  jesse
-
-       * Makefile:
-
-       Bumped the version to 2.0.12pre6
-       
-2002-03-06 18:57  jesse
-
-       * lib/RT/Transaction.pm:
-
-       Added an update that will make dates changed as parts of transaction updates show up in local time
-       
-2002-03-06 18:56  jesse
-
-       * webrt/Admin/Queues/Modify.html:
-
-       Added a note to the queue creation screen about defaults.
-       
-2002-03-01 01:41  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       This patch fixes a small problem with printing a message.It checks if themessage is true, not if it has length, so a message containing 0 will notbe printed.  From Blair Zajac <blair@orcaware.com>
-       
-2002-03-01 01:39  jesse
-
-       * bin/rt:
-
-       RT-Ticket:438
-       RT-Status: resolved
-       
-       Added brandon's patch to allow searching for tickets by keyword on the commandline
-       
-2002-02-28 02:03  jesse
-
-       * bin/rt:
-
-       RT-Ticket: 1258
-       RT-Milestone: 2.0.x
-       RT-Subsystem: CLI
-       RT-Severity: normal
-       RT-Broken in: 2.0-beta3
-       RT-Broken in: 2.0.1
-       RT-Broken in: 2.0.2
-       RT-Broken in: 2.0.3
-       RT-Broken in: 2.0.4
-       RT-Broken in: 2.0.5
-       RT-Broken in: 2.0.6
-       RT-Broken in: 2.0.7
-       RT-Broken in: 2.0.8
-       RT-Broken in: 2.0.9
-       RT-Broken in: 2.0.10
-       RT-Broken in: 2.0.11
-       
-       Removed a line that make --limit-priority and --limit-final-priority not
-       work
-       
-2002-02-28 01:49  jesse
-
-       * lib/RT/Action/: Autoreply.pm, SendEmail.pm:
-
-       RT-Ticket: 1196
-       RT-Status: resolved
-       
-2002-02-28 01:38  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       RT-Ticket: 1246
-       RT-Status: resolved
-       
-2002-02-28 01:38  jesse
-
-       * tools/testdeps:
-
-       Added a couple explicit dependencies to testdeps that should have been there
-       forever ago. you'll only run into this if your cpan doesn't do recursive deps.
-       
-2002-02-20 20:45  jesse
-
-       * Makefile, lib/RT/Interface/Web.pm, webrt/Admin/Users/index.html,
-       webrt/Ticket/Update.html:
-
-       Bumped the version to 2.0.12-pre5.
-       
-       Web: Fixed a typo in user administration that prevented user listing
-       
-       Web: fixed recieve to receive in ticket/update
-       
-2002-02-19 03:23  jesse
-
-       * lib/RT/Scrips.pm:
-
-       Fixed a typo. (Added a missing ;)
-       
-2002-02-19 01:04  jesse
-
-       * Makefile:
-
-       Bumped version to 2.0.12pre4
-       
-2002-02-18 18:35  jesse
-
-       * lib/RT/Condition/Generic.pm:
-
-       RT-Ticket: 1194
-       
-       cleaned up a reference to "ApplicableTypes", a nonexistent parameter to Condition->new
-       
-2002-02-18 18:30  jesse
-
-       * webrt/Elements/Login:
-
-       RT-Ticket: 1226
-       RT-Status: resolved
-       
-       Added an explicit reset of the content-type to 'text/html' when displaying hte login page
-       
-2002-02-18 18:25  jesse
-
-       * webrt/Admin/Users/index.html:
-
-       rt-ticket: 1190
-       rt-status: resolved
-       
-       Modified administrative userlist to make it easier to click on users who have no Name attribute defined
-       
-2002-02-18 18:18  jesse
-
-       * webrt/: Elements/Header, SelfService/Elements/Header:
-
-       rt-ticket: 1176
-       rt-status: resolved
-       
-       Applied tom's patch which hides the preferences link if the user doesn't have the right to "modify self"
-       
-2002-02-18 18:14  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       RT-Ticket: 1165
-       RT-Status: resolved
-       
-       exporting the ParseAddressFromHeader subroutine so others can play with it
-       
-2002-02-18 18:06  jesse
-
-       * webrt/Ticket/Update.html:
-
-       RT-Ticket:1209
-       RT-Milestone: 2.0.x
-       RT-Status: resolved
-       
-       Removed  a bogus font tag from the Ticket update screen
-       
-2002-02-18 18:00  jesse
-
-       * lib/RT/Interface/Web.pm, webrt/Search/Listing.html:
-
-       RT-Ticket: 1243
-       RT-Status: resolved
-       RT-Milestone: 2.0.x
-       RT-Broken-In: 2.0.8
-       RT-Broken-In: 2.0.9
-       RT-Broken-In: 2.0.10
-       RT-Broken-In: 2.0.11
-       RT-Subsystem: HTML::Mason Frontend
-       RT-Severity: Normal
-       
-       Switched the web frontend to use an in-core scalar for uploaded attachment content,
-       rather than a tempfile which wasn't getting cleaned up properly
-       
-2002-02-18 16:53  jesse
-
-       * webrt/Search/Listing.html:
-
-       RT-Ticket: 1245
-       Rt-status: resolved
-       
-       Applied a patch to nuke duplicate restrictions in the webui.
-       
-2002-02-18 16:47  jesse
-
-       * webrt/Admin/Groups/Members.html:
-
-       RT-Ticket: 1421
-       RT-Status: resolved
-       
-       moved a label inside a loop to make the ui easier to understand
-       
-2002-02-18 16:36  jesse
-
-       * etc/config.pm:
-
-       Set Default for UseFriendlyToLines to 0 by default, to deal with users running
-       redhat who have trouble configuring RT.
-       
-2002-02-18 16:31  jesse
-
-       * Makefile, lib/RT/Scrip.pm, tools/insertdata:
-
-       Edited insertdata to insert scrips by default, so that users don't need
-       to go through the configuration task themselves.
-       
-       Change the Makefile's WEB_GROUP to www by default for redhat and OSX.
-       
-       Correced docs for lib/RT/Scrip new() method
-       
-2002-02-08 01:23  jesse
-
-       * webrt/SelfService/Display.html:
-
-       cleanup to "last trans" in SelfService
-       
-2002-02-08 00:53  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Generalized "Abort" function to allow other non-html error messages with
-       proper handlers
-       
-2002-02-08 00:49  jesse
-
-       * etc/: schema.Pg, schema.mysql:
-
-       removed duplicate indices
-       
-2002-02-07 16:41  jesse
-
-       * etc/config.pm:
-
-       Added some docs to the config file from Rich Lafferty
-       
-2002-02-04 12:37  jesse
-
-       * lib/RT/Template.pm:
-
-       Output template content to core rather than disk when parsing.
-       
-2002-01-28 01:01  jesse
-
-       * webrt/Ticket/Elements/ShowHistory:
-
-       closing lasttrans anchor
-       
-2002-01-28 00:59  jesse
-
-       * webrt/Ticket/Elements/ShowHistory:
-
-       Closing the #lasttrans anchor
-       
-2002-01-28 00:58  jesse
-
-       * lib/RT/Record.pm:
-
-       RT-Ticket: 1156
-       
-       Pulling forward the patch for 1156
-       
-2002-01-28 00:57  jesse
-
-       * lib/RT/Record.pm:
-
-       RT-Ticket: 1156
-       RT-Status: resolved
-       
-2002-01-28 00:47  jesse
-
-       * bin/mason_handler.fcgi:
-
-       Small fix to the fastcgi handler to make attachment display work better,
-       thanks to rich lafferty.
-       
-2002-01-28 00:47  jesse
-
-       * etc/config.pm:
-
-       Removed some extraneous slashes from the config file.
-       
-2002-01-28 00:46  jesse
-
-       * README:
-
-       Clarified some readme stuff
-       
-2002-01-28 00:44  jesse
-
-       * bin/rt-commit-handler:
-
-       Bringing forward a fix to the cvs commit handler to deal with branched
-       version #s.
-       
-2002-01-28 00:40  jesse
-
-       * Makefile:
-
-       Bumped the version to 2.1.1
-       
-2002-01-28 00:27  jesse
-
-       * etc/RT_Config.pm:
-
-       file RT_Config.pm was initially added on branch rt-2-1.
-       
-2002-01-28 00:27  jesse
-
-       * bin/enhanced-mailgate:
-
-       file enhanced-mailgate was initially added on branch rt-2-1.
-       
-2002-01-28 00:27  jesse
-
-       * bin/rt-commit-handler:
-
-       file rt-commit-handler was initially added on branch rt-2-1.
-       
-2002-01-28 00:27  jesse
-
-       * Makefile, bin/enhanced-mailgate, bin/mason_handler.fcgi, bin/rt,
-       bin/rt-commit-handler, bin/rt-mailgate, bin/rtadmin, bin/webmux.pl,
-       etc/RT_Config.pm, etc/acl.Oracle, etc/acl.Pg, etc/acl.mysql,
-       etc/config.pm, lib/RT.pm, lib/RT/Handle.pm, lib/RT/User.pm,
-       lib/RT/Watcher.pm, lib/RT/Interface/CLI.pm,
-       lib/RT/Interface/Email.pm, tools/cpan2rpm, tools/initdb,
-       tools/insertdata, tools/testdeps:
-
-       First RT 2.1 checkin. don't expect this to run.  (though it does here)
-       
-2002-01-25 17:37  jesse
-
-       * README:
-
-       Added a warning to the readme that 2.1 is scary and people shouldn't use it
-       
-2002-01-25 17:24  jesse
-
-       * Makefile:
-
-       Branching 2.1.0  and incrementing the makefile to 2.1.
-       
-       Welcome to the future.
-       
-2002-01-24 13:30  jesse
-
-       * lib/RT/Transaction.pm:
-
-       RT-Ticket: 1201
-       RT-Status: resolved
-       
-       Better transaction display for "text" and "message" parts.
-       
-2002-01-24 13:00  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       RT-Ticket: 1166
-       RT-Status: resolved
-       
-       Implemented better URL regexp matching.
-       
-2002-01-24 10:39  jesse
-
-       * bin/rt-mailgate:
-
-       Fixed a typo in a debug message in rt-mailgate
-       
-2002-01-24 10:34  jesse
-
-       * lib/RT/Template.pm:
-
-       Switched from bogus mime parsing to using MIME::Parser like we should have
-       from the get-go.
-       
-       Used perltidy to clean up template.pm before we started working on it.
-       
-2002-01-24 10:28  jesse
-
-       * lib/RT/Record.pm:
-
-       Added a check to LoadByCols which causes postgres mode to not try to lookup
-       lc(undef)
-       
-2002-01-24 10:23  jesse
-
-       * webrt/NoAuth/webrt.css:
-
-       Added a new style to the stylesheet to support some new reports
-       
-2002-01-24 10:21  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       mail gateway now unfolds long headers on parse.
-       
-2002-01-11 15:20  jesse
-
-       * Makefile, lib/RT/Transaction.pm:
-
-       RT-Ticket: 950
-       
-       Aoolyed the recommended patch to make blank bodies not get
-       mailed in lieu of the real message
-       
-2002-01-11 15:00  jesse
-
-       * Makefile, webrt/Ticket/ModifyAll.html:
-
-       Fixed a small bug that broke the "jumbo" page after 2.0.11
-       
-2002-01-11 01:17  jesse
-
-       * bin/rt-mailgate:
-
-       Added a new flag to rt-mailgate to enable setting the owner of new tickets based on +extension
-       
-2002-01-11 01:13  jesse
-
-       * webrt/Ticket/: Modify.html, ModifyAll.html:
-
-       Adding a couple ACL checks to better deal with moving tickets to queues the user can't see
-       
-2002-01-11 01:11  jesse
-
-       * webrt/Admin/Queues/index.html:
-
-       Fixed typo in ACL check that resulted in "Create Queue" being more restrictive than
-       it needed to be
-       
-2002-01-10 19:07  jesse
-
-       * webrt/Ticket/Update.html:
-
-       more tweaking
-       
-2002-01-10 19:05  jesse
-
-       * webrt/Ticket/Update.html:
-
-       Cleaned up the Ticekt Update ui some
-       
-2002-01-10 19:02  jesse
-
-       * lib/RT/: Attachment.pm, Action/Notify.pm, Condition/Generic.pm:
-
-       Cleanups to make Also-Cc and Also-Bcc go
-       
-2002-01-10 19:01  jesse
-
-       * lib/RT/Queue.pm:
-
-       Changed a test to work the way that Test::Inline does now
-       
-2002-01-10 18:34  jesse
-
-       * lib/RT/Attachment.pm:
-
-       Changes to attachment to provide the header frobbing necessary to send mail to ccs and bccs
-       
-2002-01-10 18:32  jesse
-
-       * Makefile, README, lib/RT/Ticket.pm, tools/insertdata,
-       webrt/Ticket/Update.html, lib/RT/Action/Notify.pm:
-
-       Work on "Explicit Cc" and "Explicit Bcc" for a client
-       
-2002-01-10 18:27  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       abstracting out a number to a named variable
-       
-2002-01-09 02:24  jesse
-
-       * webrt/Admin/: Groups/index.html, Keywords/index.html:
-
-       A couple tiny ui cleanups (removed some object ids from the UI where they were just being clutter
-       
-2002-01-02 21:58  jesse
-
-       * Makefile, README, webrt/Elements/Login:
-
-       Bumped some copyright notices to 2002. bumped version to 2.0.11
-       
-2001-12-26 14:59  jesse
-
-       * Makefile:
-
-       Bumping version to 2.0.11pre1
-       
-2001-12-26 14:51  jesse
-
-       * lib/RT/Tickets.pm:
-
-       Merges were being over-zealous in what they twiddled the effective id of.
-       
-       this meant that far too many tickets would show up in ticket listings.
-       
-2001-12-24 18:58  jesse
-
-       * Makefile:
-
-       Bumped the version to 2.0.10
-       
-2001-12-19 00:24  jesse
-
-       * Makefile:
-
-       Bumped version to 2.0.10pre4
-       
-       fix to makefile to genereate changelog for head
-       
-2001-12-18 03:58  jesse
-
-       * lib/RT/Tickets.pm:
-
-       The "null search" was finding all tickets in 2.0.10pre3.  Fixed in CVS
-       
-2001-12-18 03:53  jesse
-
-       * bin/rt:
-
-       fixed typos in bin/rt that stopped --limit-subject --limit-requestors and --limit-body from
-       working
-       
-2001-12-17 15:13  jesse
-
-       * Makefile:
-
-       Bumped the version to 2.0.10-test3
-       
-2001-12-17 14:58  jesse
-
-       * lib/RT/User.pm, tools/insertdata, webrt/Admin/Users/Modify.html:
-
-       RT-Ticket: 935
-       RT-Status: resolved
-       
-       cleaned up seph's patch. this enabled me to actually really properly support
-       users with no email address, which meant there were a couple other cleanups
-       to go through too.
-       
-2001-12-17 14:26  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Some small cleanups to the IsWatcher stuff.
-       
-       Added checks to make sure that watchers aren't duplicated to ticket.pm
-       
-2001-12-17 13:04  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       Fixed an unclosed anchor which caused IE to render ticket listings wrong.
-       
-2001-12-14 18:29  jesse
-
-       * lib/Makefile.PL, tools/testdeps:
-
-       Bumped DBIx::SearchBuilder dependency to 0.48
-       
-2001-12-14 18:28  jesse
-
-       * tools/testdeps, webrt/Elements/Login:
-
-       Removed code to special case for bugs in mason < 1.01.
-       Moved us up to a mason 1.02 dependency
-       
-2001-12-14 18:26  jesse
-
-       * bin/rt:
-
-       bin/rt: added support for --version, fixed --status = !closed, docced --merge-into
-       
-2001-12-14 18:25  jesse
-
-       * Makefile:
-
-       Some stylistic cleanups  to the makefile from blair.
-       
-2001-12-14 16:42  jesse
-
-       * bin/rtadmin:
-
-       rtadmin had some issues where it would assume a 'name' if called without --name for user group and queue editing.
-       
-2001-12-14 16:06  jesse
-
-       * lib/RT/Tickets.pm:
-
-       
-       Ticket listings will no longer show tickets which have been merged into others.
-       
-               -j
-       
-2001-12-14 15:27  jesse
-
-       * lib/RT/User.pm:
-
-       Prevent users from futzing with nobody or rt_System, unless you're setting an email address.
-       (Arguably, that's a bug too)
-       
-2001-12-14 14:03  jesse
-
-       * lib/RT/: ACE.pm, Group.pm, GroupMember.pm, Keyword.pm,
-       KeywordSelect.pm, Queue.pm, Scrip.pm, Template.pm, Ticket.pm:
-
-       Standardised on "Permission Denied" instead of having some "Permission denied". Thanks simon.
-       
-               -j
-       
-2001-12-14 13:46  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Reordered the order that Basics actions are committed, so that Queue changes
-       come after other changes, so that users don't move tickets out of a queue before they have a
-       chance to update them.
-       
-2001-12-13 02:18  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Addition to Ticket->Import, so you can set owner by name.
-       
-       Fix for a bug in Ticket->AddWatcher that would let privileged watchers without
-       email addresses add others as watchers.
-       
-2001-12-03 20:13  jesse
-
-       * Makefile, lib/RT/EasySearch.pm, lib/RT/Keyword.pm,
-       lib/RT/Record.pm, lib/RT/Tickets.pm, lib/RT/User.pm:
-
-       more work on making sure that only the things we want are case sensitive
-       (IE name, content email address should always be insensitive.  when loading a row by any field other than ID, that should be case-insensitive)
-       
-2001-12-03 19:17  jesse
-
-       * Makefile:
-
-       bumped the version  to 2.0.10-test1
-       
-2001-12-03 19:14  jesse
-
-       * lib/RT/EasySearch.pm:
-
-       We now default to case sensitive searches, rather than case-insensitive ones.
-       (This should speed up Pg a LOT. We'll be adding in case-insensitive searching
-       for the 13 attributes that matter:
-       
-       Watcher->Email
-       User->name
-       User->email
-       User->gecos
-       Ticket->Subject
-       Queue->name
-       KeywordSelect->name
-       Keyword->Name
-       ObjectKeyword->Name
-       Attachment->Subject
-       Attachment->Content
-       Attachment->Headers
-       
-2001-12-03 19:13  jesse
-
-       * webrt/: Admin/Queues/Modify.html, Admin/Queues/People.html,
-       Elements/GotoTicket:
-
-       Some small UI cleanups from Hakke
-       
-2001-11-29 03:50  jesse
-
-       * webrt/: Elements/SelectEqualityOperator, Elements/SelectOwner,
-       Search/PickRestriction:
-
-       SelectOwner now passes a ticket up the line.
-       
-       Priority can now have = and != searches
-       
-2001-11-29 03:49  jesse
-
-       * tools/insertdata:
-
-       Cleaned up a template to display Ticket subject, if no transaction subject is given.
-       
-2001-11-29 03:48  jesse
-
-       * webrt/Ticket/: Update.html, Elements/EditPeople:
-
-       Now pass in ticket Id, so that "owner" can be someone who only has rights to that tikcet.
-       
-2001-11-29 03:47  jesse
-
-       * lib/RT/Ticket.pm:
-
-       FinalPriority should never get set to null if a ticket doesn't have the attribute set on create
-       
-       Untake's arguments were debognifed
-       
-2001-11-29 03:45  jesse
-
-       * webrt/SelfService/Elements/Header:
-
-       "Logout" no longer shows up when using external auth with SelfService
-       
-2001-11-29 03:44  jesse
-
-       * bin/rt:
-
-       Fix for setting priority when creating tickets with the cli
-       
-2001-11-29 03:42  jesse
-
-       * bin/rt-mailgate:
-
-       Added support for --ticket-id-from-extension to rt-mailgate
-       
-2001-11-14 14:28  jesse
-
-       * Makefile:
-
-       Bumped the version to 2.0.9
-       
-2001-11-13 11:33  jesse
-
-       * Makefile, bin/initacls.Pg, bin/rt:
-
-       rt-ticket:1007
-       rt-status: resolved
-       
-       initacls.pg no longer has extranious spaces which break variable assignment for port and host.
-       
-       Bumped version to 2.0.9pre9
-       
-2001-11-12 13:19  jesse
-
-       * Makefile, bin/initacls.Pg:
-
-       Fix for #1007 (Typo in bin/initacls.Pg)
-       Bumped version to 2.0.9pre8
-       
-2001-11-09 18:24  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       URL higlighting should now work with mailto: urls
-       
-2001-11-09 18:15  jesse
-
-       * Makefile, webrt/Ticket/Elements/ShowTransaction:
-
-       Cleaned up the url highlighting code
-       
-       Bumped the version to 2.0.9pre7
-       
-2001-11-09 17:27  jesse
-
-       * Makefile:
-
-       Fixing the new taggy stuff
-       
-2001-11-09 17:23  jesse
-
-       * Makefile:
-
-       Fixing the new branchy stuff
-       
-2001-11-09 17:07  jesse
-
-       * Makefile, bin/rtadmin, etc/config.pm,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       Added a bit of doc to etc/config.pm
-       
-       Modified ShowTransaction to more properly escape html
-       
-       Fixed some of the cli help for rtadmin
-       
-       Added support for branch specification to the makefile
-       
-2001-11-08 15:15  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       I can commit on the head. really.
-       
-2001-11-08 15:06  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Dealing with defined but blank Owner fields
-       
-2001-11-06 18:06  jesse
-
-       * tools/cpan2rpm, tools/initdb, tools/insertdata, tools/testdeps,
-       webrt/autohandler, webrt/index.html, webrt/Admin/index.html,
-       webrt/Admin/Elements/CreateQueueCalled,
-       webrt/Admin/Elements/CreateUserCalled,
-       webrt/Admin/Elements/EditUserComments,
-       webrt/Admin/Elements/GrantQueueRightsTo,
-       webrt/Admin/Elements/GroupTabs, webrt/Admin/Elements/Header,
-       webrt/Admin/Elements/ListGlobalKeywordSelects,
-       webrt/Admin/Elements/ListGlobalScrips,
-       webrt/Admin/Elements/ModifyKeyword,
-       webrt/Admin/Elements/ModifyKeywordSelect,
-       webrt/Admin/Elements/ModifyQueue,
-       webrt/Admin/Elements/ModifyTemplate,
-       webrt/Admin/Elements/ModifyUser,
-       webrt/Admin/Elements/QueueRightsForUser,
-       webrt/Admin/Elements/QueueTabs,
-       webrt/Admin/Elements/SelectKeywordSelect,
-       webrt/Admin/Elements/SelectModifyGroup,
-       webrt/Admin/Elements/SelectModifyKeyword,
-       webrt/Admin/Elements/SelectModifyKeywordSelect,
-       webrt/Admin/Elements/SelectModifyQueue,
-       webrt/Admin/Elements/SelectModifyUser,
-       webrt/Admin/Elements/SelectQueueRights,
-       webrt/Admin/Elements/SelectRights,
-       webrt/Admin/Elements/SelectScrip,
-       webrt/Admin/Elements/SelectScripAction,
-       webrt/Admin/Elements/SelectScripCondition,
-       webrt/Admin/Elements/SelectSingleOrMultiple,
-       webrt/Admin/Elements/SelectTemplate,
-       webrt/Admin/Elements/SelectUsers, webrt/Admin/Elements/SystemTabs,
-       webrt/Admin/Elements/Tabs, webrt/Admin/Elements/UserTabs,
-       webrt/Admin/Global/GroupRights.html,
-       webrt/Admin/Global/Keywords.html, webrt/Admin/Global/Scrips.html,
-       webrt/Admin/Global/Template.html,
-       webrt/Admin/Global/Templates.html,
-       webrt/Admin/Global/UserRights.html, webrt/Admin/Global/index.html,
-       webrt/Admin/Groups/Members.html, webrt/Admin/Groups/Modify.html,
-       webrt/Admin/Groups/Rights.html, webrt/Admin/Groups/index.html,
-       webrt/Admin/KeywordSelects/Modify.html,
-       webrt/Admin/KeywordSelects/index.html,
-       webrt/Admin/Keywords/Modify.html, webrt/Admin/Keywords/index.html,
-       webrt/Admin/Queues/Create.html,
-       webrt/Admin/Queues/GroupRights.html,
-       webrt/Admin/Queues/Keywords.html, webrt/Admin/Queues/Modify.html,
-       webrt/Admin/Queues/People.html, webrt/Admin/Queues/Scrips.html,
-       webrt/Admin/Queues/Template.html,
-       webrt/Admin/Queues/Templates.html,
-       webrt/Admin/Queues/UserRights.html, webrt/Admin/Queues/index.html,
-       webrt/Admin/Users/Modify.html, webrt/Admin/Users/Prefs.html,
-       webrt/Admin/Users/Rights.html, webrt/Admin/Users/index.html,
-       webrt/Elements/Checkbox, webrt/Elements/CreateTicket,
-       webrt/Elements/CustomHomepageHeader, webrt/Elements/Error,
-       webrt/Elements/Footer, webrt/Elements/GotoTicket,
-       webrt/Elements/Header, webrt/Elements/ListActions,
-       webrt/Elements/Login, webrt/Elements/MessageBox,
-       webrt/Elements/MyRequests, webrt/Elements/MyTickets,
-       webrt/Elements/Quicksearch, webrt/Elements/Refresh,
-       webrt/Elements/Section, webrt/Elements/SelectBoolean,
-       webrt/Elements/SelectDate, webrt/Elements/SelectDateRelation,
-       webrt/Elements/SelectDateType, webrt/Elements/SelectKeyword,
-       webrt/Elements/SelectKeywordOptions, webrt/Elements/SelectLinkType,
-       webrt/Elements/SelectMatch, webrt/Elements/SelectNewTicketQueue,
-       webrt/Elements/SelectOwner, webrt/Elements/SelectQueue,
-       webrt/Elements/SelectResultsPerPage,
-       webrt/Elements/SelectSortOrder, webrt/Elements/SelectStatus,
-       webrt/Elements/SelectTicketSortBy, webrt/Elements/SelectUsers,
-       webrt/Elements/SelectWatcherType, webrt/Elements/ShadedBox,
-       webrt/Elements/Submit, webrt/Elements/Tabs,
-       webrt/Elements/TitleBoxEnd, webrt/Elements/TitleBoxStart,
-       webrt/Elements/ViewUser, webrt/Elements/dayMenu,
-       webrt/Elements/monthMenu, webrt/Elements/yearMenu,
-       webrt/NoAuth/Logout.html, webrt/NoAuth/Reminder.html,
-       webrt/NoAuth/webrt.css, webrt/NoAuth/images/rt.jpg,
-       webrt/NoAuth/images/spacer.gif, webrt/Search/Bulk.html,
-       webrt/Search/Listing.html, webrt/Search/PickRestriction,
-       webrt/Search/RestrictSearch.html, webrt/Search/TicketCell,
-       webrt/SelfService/Closed.html, webrt/SelfService/Create.html,
-       webrt/SelfService/Display.html, webrt/SelfService/Error.html,
-       webrt/SelfService/Prefs.html, webrt/SelfService/Update.html,
-       webrt/SelfService/index.html,
-       webrt/SelfService/Attachment/dhandler,
-       webrt/SelfService/Elements/GotoTicket,
-       webrt/SelfService/Elements/Header,
-       webrt/SelfService/Elements/MyRequests,
-       webrt/SelfService/Elements/Tabs, webrt/Ticket/Create.html,
-       webrt/Ticket/Display.html, webrt/Ticket/History.html,
-       webrt/Ticket/Modify.html, webrt/Ticket/ModifyAll.html,
-       webrt/Ticket/ModifyDates.html, webrt/Ticket/ModifyLinks.html,
-       webrt/Ticket/ModifyPeople.html, webrt/Ticket/Update.html,
-       webrt/Ticket/Attachment/dhandler,
-       webrt/Ticket/Elements/AddWatchers,
-       webrt/Ticket/Elements/EditBasics, webrt/Ticket/Elements/EditDates,
-       webrt/Ticket/Elements/EditKeywordSelects,
-       webrt/Ticket/Elements/EditLinks, webrt/Ticket/Elements/EditPeople,
-       webrt/Ticket/Elements/EditWatchers,
-       webrt/Ticket/Elements/ShowBasics, webrt/Ticket/Elements/ShowDates,
-       webrt/Ticket/Elements/ShowDependencies,
-       webrt/Ticket/Elements/ShowHistory,
-       webrt/Ticket/Elements/ShowKeywordSelects,
-       webrt/Ticket/Elements/ShowLinks,
-       webrt/Ticket/Elements/ShowMemberOf,
-       webrt/Ticket/Elements/ShowMembers,
-       webrt/Ticket/Elements/ShowPeople,
-       webrt/Ticket/Elements/ShowReferences,
-       webrt/Ticket/Elements/ShowRequestor,
-       webrt/Ticket/Elements/ShowSummary,
-       webrt/Ticket/Elements/ShowTransaction, webrt/Ticket/Elements/Tabs,
-       webrt/Ticket/Elements/ToolBar, webrt/User/Prefs.html:
-
-       Merging rt-1-1 to the head.
-       
-       RT 1.0 now lives on the rt-1-0 branch.
-       
-2001-11-06 18:03  jesse
-
-       * Makefile, NEWS, README, TODO, bin/initacls.Oracle,
-       bin/initacls.Pg, bin/initacls.mysql, bin/mason_handler.fcgi,
-       bin/mason_handler.scgi, bin/rt, bin/rt-mailgate, bin/rtadmin,
-       bin/rtmux.pl, bin/testdeps.pl, bin/webmux.pl, docs/FAQ,
-       docs/FAQ.html, docs/README.docs, docs/Security,
-       docs/rt-templates.html, docs/rt_users_guide.html,
-       docs/design_docs/CARS, docs/design_docs/TransactionTypes.txt,
-       docs/design_docs/acls, docs/design_docs/basic-definitions.txt,
-       docs/design_docs/cli_spec, docs/design_docs/cvs_integration,
-       docs/design_docs/evil_plans, docs/design_docs/link-definitions.txt,
-       docs/design_docs/local_hacking,
-       docs/design_docs/subscription-definitions.txt,
-       docs/design_docs/users, etc/acl.Oracle, etc/acl.Pg, etc/acl.mysql,
-       etc/config.pm, etc/mysql.acl, etc/rt.spec, etc/schema,
-       etc/schema.Oracle, etc/schema.Pg, etc/schema.mysql, etc/schema.pm,
-       etc/suidrt.c, lib/MANIFEST, lib/MANIFEST.SKIP, lib/Makefile.PL,
-       lib/RT.pm, lib/test.pl, lib/RT/ACE.pm, lib/RT/ACL.pm,
-       lib/RT/Attachment.pm, lib/RT/Attachments.pm, lib/RT/CurrentUser.pm,
-       lib/RT/Date.pm, lib/RT/EasySearch.pm, lib/RT/Group.pm,
-       lib/RT/GroupMember.pm, lib/RT/GroupMembers.pm, lib/RT/Groups.pm,
-       lib/RT/Handle.pm, lib/RT/Keyword.pm, lib/RT/KeywordSelect.pm,
-       lib/RT/KeywordSelects.pm, lib/RT/Keywords.pm, lib/RT/Link.pm,
-       lib/RT/Links.pm, lib/RT/ObjectKeyword.pm, lib/RT/ObjectKeywords.pm,
-       lib/RT/Queue.pm, lib/RT/Queues.pm, lib/RT/Record.pm,
-       lib/RT/Scrip.pm, lib/RT/ScripAction.pm, lib/RT/ScripActions.pm,
-       lib/RT/ScripCondition.pm, lib/RT/ScripConditions.pm,
-       lib/RT/Scrips.pm, lib/RT/Template.pm, lib/RT/Templates.pm,
-       lib/RT/TestHarness.pm, lib/RT/Ticket.pm, lib/RT/Tickets.pm,
-       lib/RT/Transaction.pm, lib/RT/Transactions.pm, lib/RT/User.pm,
-       lib/RT/Users.pm, lib/RT/Watcher.pm, lib/RT/Watchers.pm,
-       lib/RT/Action/Autoreply.pm, lib/RT/Action/Generic.pm,
-       lib/RT/Action/Notify.pm, lib/RT/Action/NotifyAsComment.pm,
-       lib/RT/Action/OpenDependent.pm, lib/RT/Action/README.hackers,
-       lib/RT/Action/ResolveMembers.pm, lib/RT/Action/SendEmail.pm,
-       lib/RT/Action/SendPasswordEmail.pm,
-       lib/RT/Action/StallDependent.pm,
-       lib/RT/Condition/AnyTransaction.pm, lib/RT/Condition/Generic.pm,
-       lib/RT/Condition/NewDependency.pm,
-       lib/RT/Condition/StatusChange.pm, lib/RT/Interface/CLI.pm,
-       lib/RT/Interface/Email.pm, lib/RT/Interface/Web.pm:
-
-       Merging rt-1-1 to the head.
-       
-       RT 1.0 now lives on the rt-1-0 branch.
-       
-2001-11-06 17:57  jesse
-
-       * rt.spec, etc/rt.spec:
-
-       Cleaned up spec file goodness
-       
-2001-11-06 16:28  jesse
-
-       * Makefile:
-
-       Bumped version to 2.0.9pre5
-       
-2001-11-05 00:55  jesse
-
-       * rt.spec, lib/Makefile.PL, tools/testdeps:
-
-       Bumped the searchbuilder dependency to 0.47
-       
-2001-11-05 00:54  jesse
-
-       * webrt/Ticket/Update.html:
-
-       Named the ticket update form.
-       
-2001-11-05 00:52  jesse
-
-       * etc/config.pm, lib/RT/Handle.pm:
-
-       Added support for postgres' connections-over-ssl
-       
-2001-11-05 00:49  jesse
-
-       * webrt/Admin/Elements/SelectRights:
-
-       Updated ACL selecting UI to work properly with browsers that try to auto-select
-       a value in a SELECT
-       
-2001-11-02 01:39  jesse
-
-       * Makefile:
-
-       bumped the version to 2.0.9pre4
-       
-2001-11-02 01:31  jesse
-
-       * webrt/Ticket/: Display.html, ModifyAll.html:
-
-       Fix to not automatically record comments if nothing was typed.
-       
-2001-11-02 00:52  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Fix for duplicated requestors on merge. #791
-       
-2001-11-01 17:40  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       More tweaking transaction display
-       
-2001-11-01 17:36  jesse
-
-       * webrt/: Admin/Users/Modify.html, Ticket/Elements/ShowTransaction:
-
-       Fixed newlines between ticket body and headers.
-       
-       Fix for 934: creating users doesn't completely fail (new)
-       
-2001-11-01 17:24  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       Cleanups to ShowTransaction
-       
-2001-11-01 17:10  jesse
-
-       * lib/RT/: Keyword.pm, Interface/Web.pm:
-
-       Fix for loading queue (post 2.0.8) when called by name
-       Fix for _not_ trying to load keywords when called with no value.
-       
-2001-10-31 17:38  jesse
-
-       * Makefile:
-
-       Fixed the make dist
-       
-2001-10-31 02:56  jesse
-
-       * Makefile:
-
-       Bumped the version to 2.0.9pre3
-       
-2001-10-31 02:54  jesse
-
-       * lib/RT/Action/SendPasswordEmail.pm:
-
-       file SendPasswordEmail.pm was initially added on branch rt-1-1.
-       
-2001-10-31 02:54  jesse
-
-       * lib/RT/Action/SendPasswordEmail.pm:
-
-       Added an action to mail a password to the user.
-       
-2001-10-31 02:54  jesse
-
-       * bin/rt-mailgate:
-
-       added support to rt-mailgate for putting the queue name in a +extension
-       
-2001-10-31 02:52  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Tickets which are created in a "resolved" state will now have their "resolved"
-       date set right.
-       
-2001-10-31 02:51  jesse
-
-       * lib/RT/User.pm:
-
-       Started work on "Email password to user"
-       
-2001-10-31 02:48  jesse
-
-       * lib/RT/Watcher.pm:
-
-       Added a patch from Simon Cozens which makes sure that a requestor is always a user, rather than an email address.
-       
-2001-10-31 02:47  jesse
-
-       * lib/RT/Keyword.pm:
-
-       Added a helper Load function to Keyword to load by Id or Path
-       
-2001-10-31 02:42  jesse
-
-       * lib/RT/Template.pm:
-
-       
-       Template got new helper functions for loading queue and system templates.
-       
-2001-10-31 02:40  jesse
-
-       * bin/rt, bin/rtadmin, lib/RT/Interface/CLI.pm,
-       lib/RT/Interface/Email.pm:
-
-       Bringing forward a security fix from 2.0.8_01.  (nonusers could get superuser permissions from the CLI)
-       
-2001-10-31 02:37  jesse
-
-       * webrt/: Elements/MyRequests, Elements/MyTickets,
-       Ticket/Create.html:
-
-       Fixed a display bug in mytickets and myrequests which prevented clicking on
-       subjectless email
-       
-2001-10-31 02:04  jesse
-
-       * etc/: config.pm, schema.Pg, schema.mysql, schema.pm:
-
-       Lengthened queue name and email addresses in the default DB schema
-       
-2001-10-31 02:02  jesse
-
-       * webrt/Ticket/Update.html, lib/RT/Interface/Web.pm:
-
-       Now show the current ticket subject by default in the update subject box.
-       But don't include it in the transaction if it hasn't changed.
-       
-2001-10-31 01:09  jesse
-
-       * Makefile, bin/rt, bin/rt-mailgate, bin/rtadmin,
-       lib/RT/Interface/CLI.pm, lib/RT/Interface/Email.pm:
-
-       Security fixes per Jay at mojomole
-       
-2001-10-25 17:40  jesse
-
-       * webrt/Search/Listing.html:
-
-       Fixed a bug in new listing display. introduced after 2.0.8
-       
-2001-10-24 14:10  jesse
-
-       * Makefile, lib/RT/Ticket.pm:
-
-       Fixed the ticket status changes from open to open bug, thanks to raphael
-       at linkvest.
-       
-2001-10-23 17:34  jesse
-
-       * webrt/Ticket/Create.html:
-
-       Some cleanups to the Create form. No new functionality, just a little bit prettier
-       
-2001-10-23 17:34  jesse
-
-       * webrt/Elements/SelectTicketSortBy:
-
-       Elements/SelectTicketsSortBy now uses new list of sortable Tickets fields
-       in Tickets.pm
-       
-2001-10-23 17:32  jesse
-
-       * webrt/Search/Listing.html:
-
-       Column headings in searches are now clicky, where possible
-       
-2001-10-23 17:31  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       URLs in ticket history should now be clicky
-       
-2001-10-23 17:26  jesse
-
-       * webrt/Elements/CustomHomepageHeader:
-
-       file CustomHomepageHeader was initially added on branch rt-1-1.
-       
-2001-10-23 17:26  jesse
-
-       * webrt/: index.html, Elements/CustomHomepageHeader:
-
-       Added a hook for sites to put their own html in the top of the "Home" page
-       
-2001-10-23 17:24  jesse
-
-       * webrt/Elements/: SelectNewTicketQueue, SelectQueue:
-
-       Frefactored SelectQueue to elimintate dupicate code and enable a "too many queues" option
-       
-2001-10-23 17:22  jesse
-
-       * lib/: RT.pm, RT/Date.pm, RT/Keyword.pm, RT/KeywordSelect.pm,
-       RT/Keywords.pm, RT/Link.pm, RT/Links.pm, RT/ObjectKeywords.pm,
-       RT/Record.pm, RT/Scrip.pm, RT/ScripActions.pm,
-       RT/ScripConditions.pm, RT/Ticket.pm, RT/Action/SendEmail.pm,
-       RT/Condition/Generic.pm, RT/Interface/CLI.pm,
-       RT/Interface/Email.pm:
-
-       Simple fixes to POD from Feargal Reilly to fix complaints from pod2man
-       
-2001-10-23 17:08  jesse
-
-       * lib/RT/Tickets.pm:
-
-       Refactored Tickets.pm a bit to provide better access to fields
-       that tickets can be sorted on.
-       
-2001-10-23 17:06  jesse
-
-       * etc/: config.pm, schema.Pg, schema.mysql, schema.pm:
-
-       Added some new indices, based on recommendations from Nobel Tse at Outblaze
-       
-       Started to cleanup config.pm to not use deprecated methods when displaying
-       ticket columns.
-       
-2001-10-19 15:44  jesse
-
-       * Makefile, bin/initacls.Pg, bin/initacls.mysql, tools/initdb:
-
-       Reverting last patch. it lead to too much brokenness
-       
-2001-10-19 15:16  jesse
-
-       * Makefile, bin/initacls.Pg, bin/initacls.mysql, tools/initdb:
-
-       Work on the install procedure to automate it some more. (automatically supply
-       passwords defined in the makefile)
-       
-2001-10-19 00:49  jesse
-
-       * Makefile:
-
-       Bumped version to 2.0.9pre1
-       
-2001-10-19 00:46  jesse
-
-       * docs/design_docs/cvs_integration:
-
-       file cvs_integration was initially added on branch rt-1-1.
-       
-2001-10-19 00:46  jesse
-
-       * webrt/NoAuth/images/rt.jpg:
-
-       file rt.jpg was initially added on branch rt-1-1.
-       
-2001-10-19 00:46  jesse
-
-       * rt.spec, docs/design_docs/cvs_integration, etc/config.pm,
-       webrt/rt.jpg, webrt/Elements/Header, webrt/Elements/TitleBoxEnd,
-       webrt/Elements/TitleBoxStart, webrt/NoAuth/images/rt.jpg,
-       webrt/SelfService/Elements/Header:
-
-       Refactored images path to have a configurable URL, so it will work with fastcgi ;)
-       
-2001-10-19 00:37  jesse
-
-       * webrt/: Elements/Footer, autohandler:
-
-       Added support for timing of page display with &Debug=1
-       
-2001-10-19 00:29  jesse
-
-       * lib/RT/User.pm:
-
-       User.pm: a fix to allow you to create multiple users with no email address.
-       
-2001-10-19 00:25  jesse
-
-       * lib/RT/Tickets.pm:
-
-       Added sub Due to Tickets.pm. fixes #910
-       
-2001-10-19 00:17  jesse
-
-       * etc/rt.spec:
-
-       file rt.spec was initially added on branch rt-1-1.
-       
-2001-10-19 00:17  jesse
-
-       * Makefile, rt.spec, etc/rt.spec:
-
-       Some work on the rpm build infrastructure
-       
-2001-10-19 00:03  jesse
-
-       * tools/cpan2rpm:
-
-       cpan2rpm doesn't repeat builds of the same distribution, even if we're looking for differnet  modules
-       
-2001-10-18 23:30  jesse
-
-       * tools/cpan2rpm:
-
-       cpan2rpm has been cleaned up a whole lot. it should actually be somewhat smarter about not doing the same work twice
-       
-2001-10-18 22:42  jesse
-
-       * tools/cpan2rpm:
-
-       Added cpan2rpm to the tools directory, for autogenerating rpms of cpan modules
-       
-2001-10-18 22:42  jesse
-
-       * tools/cpan2rpm:
-
-       file cpan2rpm was initially added on branch rt-1-1.
-       
-2001-10-18 21:20  jesse
-
-       * Makefile, rt.spec:
-
-       Added support for autobuilding an rpm with "make rpm"
-       
-2001-10-18 02:15  jesse
-
-       * tools/insertdata:
-
-       Fixed templates to include the ticket subject if it was otherwise blank
-       
-2001-10-18 02:14  jesse
-
-       * lib/RT/Interface/Web.pm, webrt/Ticket/Display.html:
-
-       work on web-based ticket creation. fixed bugs setting due dates, etc
-       
-2001-10-18 02:13  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       fixed a user creation race condition in the mail gateway
-       
-2001-10-18 02:11  jesse
-
-       * webrt/Elements/SelectStatus:
-
-       use the new status abstraction in the web ui
-       
-2001-10-18 02:08  jesse
-
-       * tools/testdeps:
-
-       moved to a dbix::searchbuilder 0.46 dependency
-       
-2001-10-18 02:07  jesse
-
-       * lib/RT/Tickets.pm:
-
-       Movign away from a deprecated API
-       
-2001-10-18 02:07  jesse
-
-       * tools/initdb:
-
-       initdb won't whine if you don't set a host
-       
-2001-10-18 02:05  jesse
-
-       * docs/design_docs/evil_plans:
-
-       Added some docs about what 2.2 might hold
-       
-2001-10-18 02:00  jesse
-
-       * lib/RT/: Ticket.pm, Queue.pm:
-
-       Abstracted out status enumeration and validation
-       
-2001-10-18 01:57  jesse
-
-       * webrt/Ticket/Elements/EditLinks:
-
-       added WebPath to fix some links in showlinks
-       
-2001-10-17 16:34  jesse
-
-       * lib/Makefile.PL:
-
-       Bumped searchbuilder dependency to 0.46
-       
-2001-10-17 16:33  jesse
-
-       * webrt/Ticket/Elements/ShowHistory:
-
-       Added an optional bit of configuration to not show the "History" header
-       
-2001-10-06 03:01  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       Added a new option "Show commands" to show tranasaction
-       
-2001-10-06 03:00  jesse
-
-       * webrt/Admin/: Keywords/index.html, Queues/index.html:
-
-       Added support for reenabling deleted queues and keywords
-       
-2001-10-06 02:57  jesse
-
-       * lib/RT/Condition/Generic.pm:
-
-       Added test harness glue
-       
-2001-10-06 02:55  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Added code to detect bogus ticket update types
-       
-2001-10-06 02:54  jesse
-
-       * lib/RT/Interface/: CLI.pm, Email.pm:
-
-       Added support for unit testing
-       
-2001-10-06 02:51  jesse
-
-       * lib/RT/Handle.pm:
-
-       Added support for unit testing
-       
-       Added a test for Database Port definition to stop perl from whining
-       
-2001-10-06 02:49  jesse
-
-       * lib/RT/: ACE.pm, ACL.pm, Action/Generic.pm, Action/SendEmail.pm,
-       Attachment.pm, Attachments.pm:
-
-       Added support for unit testing
-       
-2001-10-06 02:46  jesse
-
-       * lib/RT/: Tickets.pm, Transaction.pm, Transactions.pm, User.pm,
-       Users.pm, Watcher.pm, Watchers.pm, Queues.pm, Record.pm, Scrip.pm,
-       ScripAction.pm, ScripActions.pm, ScripCondition.pm,
-       ScripConditions.pm, Scrips.pm, Template.pm, Templates.pm:
-
-       Added support for unit testing
-       
-2001-10-06 02:43  jesse
-
-       * lib/RT/: Keyword.pm, KeywordSelect.pm, KeywordSelects.pm,
-       Keywords.pm, Link.pm, Links.pm, ObjectKeyword.pm,
-       ObjectKeywords.pm, CurrentUser.pm, Date.pm, EasySearch.pm,
-       Group.pm, GroupMember.pm, GroupMembers.pm, Groups.pm:
-
-       Added support for unit testing
-       
-2001-10-06 02:38  jesse
-
-       * lib/RT.pm:
-
-       Added the beginnings of test support to RT.pm
-       
-2001-10-06 02:22  jesse
-
-       * lib/RT/TestHarness.pm:
-
-       file TestHarness.pm was initially added on branch rt-1-1.
-       
-2001-10-06 02:22  jesse
-
-       * lib/: Makefile.PL, RT/TestHarness.pm:
-
-       First bits of glue for new RT unit testing infrastructure
-       
-2001-10-06 02:19  jesse
-
-       * bin/rt:
-
-       bin/rt: Documentation cleanups. removing an unnecessary data tainting check
-       
-2001-10-06 02:18  jesse
-
-       * bin/initacls.Pg:
-
-       Fixes to initacls.Pg to allow installation with Unix Domain sockets
-       
-2001-10-04 02:01  jesse
-
-       * Makefile:
-
-       Bumped the version to 2.0.8
-       
-2001-10-01 02:44  jesse
-
-       * rt.spec:
-
-       Revved the version of DBIx::SearchBuilder needed in the .spec file
-       
-2001-10-01 02:42  jesse
-
-       * Makefile, lib/RT/Interface/Email.pm:
-
-       Fixed the call to MIME::Entity::Build in Email.pm
-       
-       Bumped the version to 2.0.8pre3
-       
-2001-09-30 23:03  jesse
-
-       * README, bin/rt, lib/RT/Tickets.pm, lib/RT/Interface/Email.pm,
-       webrt/Search/PickRestriction, webrt/Ticket/History.html,
-       webrt/Ticket/Elements/EditBasics,
-       webrt/Ticket/Elements/ShowHistory:
-
-       Code refactoring to allow searching for nonlocal links
-       Cleanup to the Loop prevention stuff (v. 2.0.8pre2)
-       Readme cleanup
-       CLI cleanups.  changed "return" to "exit"
-       
-2001-09-26 16:31  jesse
-
-       * tools/testdeps:
-
-       Bumped the searchbuilder dependency.  to 0.43
-       
-2001-09-26 16:28  jesse
-
-       * Makefile, bin/rt, lib/RT/Tickets.pm,
-       webrt/Admin/Queues/Scrips.html:
-
-       Added a fix for ItemsArrayRef to Tickets which causes the Next/Prev links in
-       the web ui to be smarter.
-       
-       Fixed a typo in SCrips.html
-       
-       Bumped the version to 2.0.8pre2
-       
-2001-09-24 20:10  jesse
-
-       * rt.spec:
-
-       file rt.spec was initially added on branch rt-1-1.
-       
-2001-09-24 20:10  jesse
-
-       * Makefile, rt.spec:
-
-       Added destdir support to allow building of RPMS.
-       added rt.spec for building of RPMS.
-       
-2001-09-21 16:51  jesse
-
-       * Makefile:
-
-       Bumped makefule version to 2.0.8pre1
-       
-2001-09-21 16:45  jesse
-
-       * bin/rt, lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       lib/RT/Interface/Web.pm, webrt/Ticket/Elements/ShowTransaction:
-
-       Fixed a typo in the bin/rt docs
-       Allowed "Force owner change" from bulk update screen.
-       
-2001-09-20 22:34  jesse
-
-       * bin/rt, lib/RT/Action/SendEmail.pm, lib/RT/Interface/Email.pm,
-       webrt/Search/Bulk.html, webrt/Ticket/Elements/ShowTransaction:
-
-       Fixes for:
-       
-       888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888862 Re: [rt-users] how does rt --limit-last-updated work?
-       
-       863 Ticket/Elements/ShowTransaction doesn't show headers sometimes
-       
-       Fix for a bug in the code that prevents RT from looping with itself.
-       
-       Start of work for "force change owner" in Bulk.html
-       
-2001-09-19 16:49  jesse
-
-       * bin/initacls.Pg, bin/rt, etc/config.pm, lib/RT/Queue.pm,
-       lib/RT/Ticket.pm, lib/RT/Tickets.pm, webrt/Elements/Header,
-       webrt/Search/Listing.html, webrt/Ticket/Create.html,
-       webrt/Ticket/Display.html, webrt/Ticket/ModifyAll.html,
-       webrt/Ticket/Update.html, webrt/Ticket/Elements/ShowLinks:
-
-       Fixed a bug that would cause installation on postgres to lose if $PORT wasn't
-       specified
-       
-       Changed " to ' in a few places in the config file, to make file and variable
-       names with embedded metacharacters not lose as badly
-       
-       Set some logical defaults for Queue->Create, so it's not as likely to fail
-       to create a queue if you leave out some fields
-       
-       Ticket->Create: now takes a Starts date.  Also, fixed some API docs.
-       
-       Tickets: Negative searching on fields like "subject" should now work
-       
-       WebUI:  Added a pragma NO-CACHE pseudo-header, to stop overzealous browsers from caching RT's pages
-       
-       WebUI: changed the "Bookmark this search" link to "Bookmarkable URL for this search"
-       
-       WebUI: ticket create now has a "more detail" section
-       
-       WebUI: ticket updates no longer have a default subject preset.
-       
-       WebUI: fixed a bug in ShowLinks that generated bogus urls within RT if RT wasn't at / on your server
-       
-2001-09-13 00:03  jesse
-
-       * Makefile:
-
-       Bumping the version to 2.0.7
-       
-2001-09-10 02:18  jesse
-
-       * Makefile:
-
-       Bumped the makefile version to 2.0.7pre1
-       
-2001-09-10 02:11  jesse
-
-       * bin/mason_handler.fcgi, lib/RT/User.pm:
-
-       Fixed #883, a permissions caching bug.
-       
-       Added the Text::Wrapper dependency to mason_handler.fcgi
-       
-2001-09-06 15:59  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Reverted reopen on correspondence to 1.0 behaviour
-       
-2001-09-06 15:41  jesse
-
-       * webrt/SelfService/Display.html:
-
-       make row coloring alternate in selfservice transaction history
-       
-2001-09-06 15:39  jesse
-
-       * webrt/SelfService/Display.html:
-
-       Fixed cell spacing in selfservice transaction display
-       
-2001-09-06 15:33  jesse
-
-       * bin/webmux.pl, webrt/SelfService/Display.html,
-       webrt/Ticket/Display.html, webrt/Ticket/Elements/ShowHistory,
-       webrt/Ticket/Elements/ShowKeywordSelects,
-       webrt/Ticket/Elements/ShowSummary,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       Cleaned up the web ticket transaction display.
-       
-2001-09-06 15:32  jesse
-
-       * lib/RT/: ObjectKeyword.pm, Queue.pm:
-
-       Added some docs.
-       Started refactoring Ticket statuses.
-       
-2001-09-06 15:32  jesse
-
-       * lib/RT/Ticket.pm:
-
-       $Ticket->SetTold  now optionally takes a date to set it to.
-       
-2001-09-06 15:30  jesse
-
-       * bin/rt:
-
-       Fixing some docs in bin/rt
-       
-2001-09-05 11:00  jesse
-
-       * webrt/Elements/: Header, Refresh:
-
-       Fix for #823 from martin@schapendonk.org
-               Refresh now allows you to turn off refresh.
-       
-2001-09-01 19:01  jesse
-
-       * webrt/Elements/MessageBox:
-
-       Fix for [fsck.com #803] Jumbo recording comments accidentally
-       
-2001-09-01 18:23  jesse
-
-       * Makefile:
-
-       Bumped the version to 2.0.6
-       
-2001-08-28 15:49  jesse
-
-       * Makefile:
-
-       Bumped the version to pre7, fixed a typo in the makefile's install instructions.
-       
-2001-08-24 00:13  jesse
-
-       * lib/RT/Attachment.pm:
-
-       importing the Crit->crit typo fix from 2.0.5_01
-       
-2001-08-24 00:08  jesse
-
-       * Makefile, lib/RT/Interface/Email.pm:
-
-       Rolled in the 2.05 perl 5.005 compatibility fix.
-       bumped the version to 2.0.6pre6
-       
-2001-08-23 19:49  jesse
-
-       * bin/rt-mailgate, tools/initdb:
-
-       fixed initdb to not append a port= to the db connect string unless it needs one.
-       
-       added support for $SenderMustExistInExternalDatabase to mailgate.
-       
-2001-08-23 19:46  jesse
-
-       * lib/RT/Groups.pm:
-
-       Added a default alphabetical sort order to lib/RT/Groups
-       
-2001-08-23 19:45  jesse
-
-       * etc/: config.pm, schema.Pg, schema.mysql, schema.pm:
-
-       Added new indices to schema. Regenerated mysql and postgres schema.
-       
-       Cleaned up etc/config.pm's docs some more, based on comments from Christian Gimore
-       Added a default value for RT::OwnerEmail, which was documented by not defined
-       by default
-       
-2001-08-22 18:48  jesse
-
-       * bin/rt, lib/RT/Ticket.pm, webrt/Ticket/Update.html:
-
-       bin/rt --create now deals with watchers.
-       
-       fixed a typo in Ticket/Update.html introduced after 2.0.5_03
-       
-2001-08-22 01:37  jesse
-
-       * Makefile, lib/RT/Tickets.pm, webrt/Admin/Global/Keywords.html:
-
-       Bumped version to 2.0.6-pre5
-       
-       Fixed 'deep' merges.
-       
-       Fixed a typo in Global/Keywords
-       
-2001-08-22 00:41  jesse
-
-       * Makefile, lib/RT/Interface/Email.pm:
-
-       Fixed a couple of bugs in the new email db lookups
-       
-2001-08-21 23:57  jesse
-
-       * Makefile, bin/initacls.Oracle, bin/initacls.Pg,
-       bin/initacls.mysql, tools/initdb:
-
-       Added support for setting the database port for postgres and mysql
-       
-2001-08-21 23:48  jesse
-
-       * README:
-
-       Updated jesse's email address and shuffled things around a bit.
-       
-2001-08-21 23:45  jesse
-
-       * etc/config.pm:
-
-       Added more docs and updated the default config for the external db lookups
-       
-2001-08-21 23:35  jesse
-
-       * webrt/: index.html, NoAuth/webrt.css, Search/Listing.html,
-       Search/PickRestriction, Ticket/ModifyDates.html,
-       Ticket/Update.html, Ticket/Elements/ShowHistory,
-       Ticket/Elements/ShowTransaction:
-
-       Added support for autorefresh to / and /Search/Listing.html
-       
-       Tightened up Transaction display. Fixed 'full headers' display.
-       
-       Cleaned up the ui in ModifyDates a bit
-       
-       Cleaned up the ui in Ticket/Update.html
-       
-       fixed a few typos in the css file
-       
-2001-08-21 23:30  jesse
-
-       * lib/RT/Attachment.pm:
-
-       Added some documentation
-       
-2001-08-21 23:25  jesse
-
-       * bin/rt-mailgate:
-
-       Bringing forward a patch to the mailgate from 2.0.5_01
-       
-2001-08-21 23:19  jesse
-
-       * webrt/Elements/Refresh:
-
-       file Refresh was initially added on branch rt-1-1.
-       
-2001-08-21 23:19  jesse
-
-       * webrt/Elements/Refresh:
-
-       Commiting a Refresh control to cvs
-       
-2001-08-21 23:17  jesse
-
-       * bin/rtadmin:
-
-       Fixed cli group creation
-       
-2001-08-21 23:12  jesse
-
-       * webrt/Elements/MessageBox:
-
-       Fixed transaction quoting to use the new transaction content quoting method.
-       
-2001-08-21 23:07  jesse
-
-       * webrt/Elements/Login:
-
-       Display a version string in the login box.
-       
-2001-08-21 23:06  jesse
-
-       * webrt/Elements/Header:
-
-       Added support for refresh to webrt/Elements/Header
-       Don't display the logout link if using external auth.
-       
-2001-08-21 23:05  jesse
-
-       * webrt/Admin/Users/Modify.html:
-
-       Little bit of ui and code cleanup to the User editing page
-       
-2001-08-21 23:04  jesse
-
-       * lib/RT/Record.pm:
-
-       Fixed broken caching of the CreatorObj
-       
-2001-08-21 23:03  jesse
-
-       * lib/RT/Handle.pm:
-
-       Added support for Database port to Handle.pm
-       
-2001-08-21 22:50  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Added vivek khera's patch to clean up newline processing for incoming messages
-       
-       Removed debugging output from file attachment subroutine
-       
-       Added support for setting refresh interval to the search page
-       
-2001-08-21 22:46  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       Fixed the bug fixed in 2.0.5_?? which called the wrong function for finding
-       sender name
-       
-       Altered the mail interface's external user lookup function to be returned
-        a hash of parameters
-       
-2001-08-21 22:43  jesse
-
-       * lib/RT/Transaction.pm:
-
-       Added support for Quoting a transaction to the Content sub.
-       
-2001-08-16 00:23  jesse
-
-       * Makefile, tools/testdeps:
-
-       dependency on CGI::Cookie 1.20 had reverted.
-       Bumped version to 2.0.5_03
-       
-2001-08-15 16:44  jesse
-
-       * Makefile, bin/rt-mailgate, lib/RT/Interface/Email.pm:
-
-       A couple of fixes to the mail gateway to deal with proper processing
-       of sender email addresses
-       
-2001-08-15 16:12  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       Trying for 2.0.5-01 again
-       Fixed a perl 5.6ism in Interface/Email
-       Fixed a bug in Attachment.pm that would cause a DIE on a fatal error
-       
-2001-08-15 16:12  jesse
-
-       * lib/RT/Attachment.pm:
-
-       Trying for 2.0.5-01 again
-       Fixed a bug in Attachment.pm that would cause a DIE on a fatal error
-       
-2001-08-15 16:12  jesse
-
-       * Makefile:
-
-       Trying for 2.0.5-01 again
-       
-2001-08-15 15:44  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       Fixed an error message in Attachment that should never be reached
-       Bumped the Makefile version to 2.0.5_01
-       Fixed an inadvertent perl 5.6ism in the mail gateway.
-       
-2001-08-15 15:42  jesse
-
-       * lib/RT/Attachment.pm:
-
-       Fixed an error message in Attachment that should never be reached
-       
-       Bumped the Makefile version to 2.0.5_01
-       
-2001-08-15 15:42  jesse
-
-       * Makefile:
-
-       Bumped the Makefile version to 2.0.5_01
-       
-2001-08-15 01:01  jesse
-
-       * Makefile:
-
-       Bumped version to 2.0.6-pre1
-       
-2001-08-15 01:00  jesse
-
-       * webrt/: autohandler, Admin/Users/Modify.html, Elements/Login,
-       SelfService/Prefs.html, User/Prefs.html:
-
-       Added support for external authentication to the web ui
-       
-2001-08-15 01:00  jesse
-
-       * bin/rt-mailgate, lib/RT/Interface/Email.pm:
-
-       Added support for looking up new users in an external datasource
-       
-2001-08-15 00:58  jesse
-
-       * etc/config.pm:
-
-       Added new configuration variables for external authentication for the web ui and
-       to support looking up new users in the mail gateway from a site-defined external datasource.
-       
-2001-08-15 00:17  jesse
-
-       * tools/testdeps:
-
-       Fixed testdeps to depend on the right version of CGI.pm
-       
-2001-08-14 23:55  jesse
-
-       * Makefile:
-
-       Released RT 2.0.5  No changes since 2.0.5-test3.
-       
-2001-08-12 21:13  jesse
-
-       * Makefile, bin/webmux.pl:
-
-       Fixed a typo in webmux.pl created after 2.0.4
-       Bumped the version to 2.0.5-test3
-       
-2001-08-12 20:00  jesse
-
-       * docs/manual.pod, lib/RT/Transaction.pm:
-
-       Core:  Updated Transaction->Content to be smarter about showing the first
-       message in the transaction.
-       
-       Removed the old manual skeleton in docs in favor of the web based docs.
-       
-2001-08-12 19:58  jesse
-
-       * lib/RT/Attachment.pm:
-
-       Core: Added a convenience function to RT::Attachemnt to find Children of this attachment.
-       Core: Added code to RT::Attachemnt to allow access to the 'Parent' attribute
-       
-2001-08-12 19:55  jesse
-
-       * lib/RT/Attachments.pm:
-
-       Core: A convenience function to search for Attachments by ContentType.
-       Core: Added some docs to RT::Attachments
-       
-2001-08-12 19:53  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       WebUI: Show 'comment' and 'correspond' for multipart messages in the per-transaction listing.
-       
-2001-08-10 23:59  jesse
-
-       * README:
-
-       README: added more pointers to the 'complete' docs.
-       README: Removed the little bit of configuration info in the readme in favor of the 'complete' docs on the web
-       
-2001-08-10 23:58  jesse
-
-       * bin/rt-mailgate:
-
-       mailgate: RT is now less likely to try to send mail to senders which will cause loops
-       
-2001-08-10 23:57  jesse
-
-       * webrt/index.html:
-
-       Webui: [home] now gets greyed out when you're there
-       
-2001-08-10 15:32  jesse
-
-       * Makefile, webrt/Elements/MessageBox:
-
-       Added a pair of () in webrt/Elements/MessageBox to correct a typo in an if
-       Bumped version to 2.0.5-test2
-       
-2001-08-10 00:24  jesse
-
-       * Makefile:
-
-       Bumped version to 2.0.5test1
-       
-2001-08-10 00:24  jesse
-
-       * lib/RT/Users.pm, webrt/Elements/MessageBox,
-       webrt/Ticket/Elements/AddWatchers, webrt/Ticket/Elements/EditDates:
-
-       Cleanup to date editing ui
-       
-       Code cleanups to Elements/MessageBox for more readable and maintainable code
-       Code cleanups to TicketElements/AddWatchers for more readable and maintainable code
-       
-2001-08-10 00:23  jesse
-
-       * webrt/Ticket/Elements/: EditLinks, ShowLinks:
-
-       Cleanup to Relationship editing and display ui
-       
-2001-08-10 00:21  jesse
-
-       * webrt/Ticket/ModifyDates.html:
-
-       UI cleanups in Ticket/ModifyDates.html
-       
-2001-08-10 00:20  jesse
-
-       * webrt/Ticket/ModifyAll.html:
-
-       Jumbo no longer loses ticket update contents.
-       
-2001-08-09 20:07  jesse
-
-       * webrt/Admin/Users/index.html:
-
-       Cleaned up Admin/Users search functionality and made it look more like
-       other user searching screens and enables searching for disabled users.
-       
-2001-08-09 20:02  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Properly strip trailing spaces from things we're trying to link to.
-       
-2001-08-09 20:00  jesse
-
-       * lib/RT/Links.pm:
-
-       By default, try to sort Links by something intelligent when displaying them
-       
-2001-08-03 01:52  jesse
-
-       * lib/RT/Action/Autoreply.pm:
-
-       Autoreplies are now from "Queuename" rather than from "RT"
-       
-2001-08-02 04:57  jesse
-
-       * webrt/: Admin/Queues/People.html, Elements/Quicksearch,
-       Elements/SelectResultsPerPage, Elements/SelectStatus,
-       Search/PickRestriction:
-
-       WebUI: Fixed a typo in hte 'bookmark this search' link display.
-       WebUI: By default, limit displayed results to 50 per page.
-       
-2001-08-02 04:57  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Documented a function in the web ui library
-       
-2001-08-02 04:56  jesse
-
-       * etc/config.pm:
-
-       Fixed a typo in the docs in the config file, thanks to sheeri.
-       
-2001-08-02 04:55  jesse
-
-       * bin/rt-mailgate:
-
-       rt-mailgate: bug-fix to properly grab 'from' addresses for purposes of determinigng whether something's a mailer-daemon
-       
-2001-08-02 04:54  jesse
-
-       * bin/rt:
-
-       Added support for merging to the CLI
-       Cli now works as described when linking tickets. Formerly, you couldn't admit the "+" before an added link
-       
-2001-08-02 04:53  jesse
-
-       * webrt/User/Prefs.html:
-
-       Bugfix to allow users to fully delete their rt signatures
-       
-2001-07-30 03:54  jesse
-
-       * docs/design_docs/evil_plans:
-
-       file evil_plans was initially added on branch rt-1-1.
-       
-2001-07-30 03:54  jesse
-
-       * Makefile, docs/design_docs/evil_plans:
-
-       bumped the version, so as not to get confused users complaining to the lists
-       
-       added some notes about what may happen for 2.2
-       
-2001-07-30 03:52  jesse
-
-       * webrt/SelfService/Display.html:
-
-       file Display.html was initially added on branch rt-1-1.
-       
-2001-07-30 03:52  jesse
-
-       * bin/mason_handler.fcgi, bin/webmux.pl, lib/RT/Interface/Web.pm,
-       webrt/SelfService/Create.html, webrt/SelfService/Details.html,
-       webrt/SelfService/Display.html, webrt/SelfService/Update.html,
-       webrt/SelfService/Elements/GotoTicket,
-       webrt/SelfService/Elements/MyRequests, webrt/Ticket/Create.html,
-       webrt/Ticket/Display.html, webrt/Ticket/Modify.html,
-       webrt/Ticket/ModifyAll.html, webrt/Ticket/ModifyDates.html,
-       webrt/Ticket/ModifyLinks.html, webrt/Ticket/ModifyPeople.html,
-       webrt/Ticket/Update.html, webrt/Ticket/Elements/EditBasics,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       Switched SelfService/Details to SelfService/Display  to better jibe
-       with the regular UI.
-       
-       Added better current-page navigation hints to most per-ticket pages.
-       
-       Added support for uploading attachments on ticket create or update.
-       
-2001-07-30 03:51  jesse
-
-       * webrt/Admin/Elements/ListGlobalScrips:
-
-       file ListGlobalScrips was initially added on branch rt-1-1.
-       
-2001-07-30 03:51  jesse
-
-       * webrt/Admin/: Elements/ListGlobalKeywordSelects,
-       Elements/ListGlobalScrips, Global/Scrips.html,
-       Queues/Keywords.html, Queues/Scrips.html:
-
-       Added some ui to show global scrips and keywordselects in the queue
-       uis for adminning the same.
-       
-2001-07-30 03:51  jesse
-
-       * webrt/Admin/Elements/ListGlobalKeywordSelects:
-
-       file ListGlobalKeywordSelects was initially added on branch rt-1-1.
-       
-2001-07-30 03:49  jesse
-
-       * TODO:
-
-       Clarified the errata urls
-       
-2001-07-30 03:48  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Cleaned up the return values from Ticket->CreateLink. (always return $status, $msg);
-       
-2001-07-30 03:48  jesse
-
-       * lib/RT/Action/SendEmail.pm:
-
-       changed the case of the Managed-by header to be less grating
-       
-2001-07-30 03:45  jesse
-
-       * bin/rt-mailgate, lib/RT/Interface/Email.pm:
-
-       Moving a bunch of mail gateway library routines to the library where they
-       belong
-       
-2001-07-27 01:06  jesse
-
-       * README:
-
-       fixed a typo in the cronjob
-       
-2001-07-25 01:05  jesse
-
-       * bin/rt-mailgate, lib/RT/Tickets.pm:
-
-       Fix for mailgateway being unable to send error mail with 'sendmailpipe' mailing
-       Fix for 'blank' searches when using search bookmarking.
-       
-2001-07-25 01:00  jesse
-
-       * Makefile:
-
-       Bumped version to 2.0.4
-       Fixed bookmarkable searches
-       Fix for sendmailpipe errors in mailgateway
-       
-2001-07-24 12:10  jesse
-
-       * Makefile, webrt/Search/PickRestriction:
-
-       Fixed a bug in Search/PickRestriction, thanks to Vivek Khera
-       Bumped version to 2.0.3
-       
-2001-07-24 00:28  jesse
-
-       * Makefile:
-
-       Bumped version to 2.0.2
-       
-2001-07-24 00:21  jesse
-
-       * lib/RT/Tickets.pm, webrt/Elements/Submit,
-       webrt/Search/Listing.html, webrt/Search/PickRestriction:
-
-       Bookmarked searches now keep track of sorting and record count limits
-       New "Refine" button to allow faster updates of search criteria.
-       
-2001-07-24 00:01  jesse
-
-       * bin/rt:
-
-       Added support for --limit-queue to  RT cli tool
-       
-2001-07-23 10:43  jesse
-
-       * Makefile, tools/testdeps:
-
-       Testdeps was accidentally looking for Freeze::Thaw, rather than FreezeThaw
-       
-2001-07-23 00:31  jesse
-
-       * Makefile:
-
-       bumped version to 2.0.2test2
-       
-2001-07-23 00:30  jesse
-
-       * lib/RT/Tickets.pm, lib/RT/Interface/Web.pm, tools/testdeps,
-       webrt/Search/Listing.html:
-
-       Added support for bookmarkable searches.
-       
-2001-07-22 22:12  jesse
-
-       * lib/RT/: KeywordSelect.pm, User.pm:
-
-       Better error checking in User ACL checking
-       
-       Fixed an ACL check bug in KeywordSelect.pm, thanks to Matthew Stock.
-       
-2001-07-22 22:09  jesse
-
-       * webrt/Admin/Users/index.html:
-
-       Fix for a users search bug and a clarification of another search option.
-       
-2001-07-22 22:06  jesse
-
-       * lib/RT/: Keywords.pm, Queues.pm, Users.pm:
-
-       By default, order Queues, Users and Keywords alphabetically
-       
-2001-07-22 22:05  jesse
-
-       * Makefile:
-
-       Permissions fix for the data dirs for the fastcgi handler
-       
-       rt/etc is now mode 755, rather than 555.
-       
-2001-07-22 22:03  jesse
-
-       * bin/mason_handler.fcgi:
-
-       fastcgi handler no longer drops setgidness, so it can deal with session files.
-       
-2001-07-22 21:55  jesse
-
-       * etc/config.pm:
-
-       Cleaned up the config file a bit to make installation easier.
-       
-2001-07-22 21:52  jesse
-
-       * webrt/Elements/MyRequests:
-
-       Clean up phrasing of the "Tickets I own dialogbox"
-       
-2001-07-19 00:57  jesse
-
-       * Makefile:
-
-       Changed Makefile to not use MAN[13]INSTALLSITEPATH per Robert Shaw's changes
-       
-2001-07-18 16:20  jesse
-
-       * Makefile, lib/RT/Queue.pm:
-
-       Added a newline to Queue.pm to fix a pod bug
-       
-       Bumped version to 2.0.2-test1  to get some feedback
-       
-2001-07-18 16:16  jesse
-
-       * lib/RT/User.pm:
-
-       RT should now honor queue-level pseudogroup memebership for ACL checks.
-       Also, simplified some of the queue related ACL checking code.
-       
-       Reduced the ACL permissions cache from 30sec to 10sec.
-       
-2001-07-18 16:13  jesse
-
-       * lib/RT/Transaction.pm:
-
-       Added BriefDescription, which is just like Description without the "By actor"
-       at the end
-       
-       Descriptions Keyword operations should include _which_ keyword select from
-       here on in (also touched the last update to Ticket.pm)
-       
-2001-07-18 16:06  jesse
-
-       * lib/RT/Ticket.pm:
-
-       TTicket->Create no longer just adds admin ccs..unless the person doing the add
-       has the right to do so.  otherwise, there was an ACL related attack that
-       could happen. luckily none of the UI exposedd this hole yet.
-       
-       Ticket->Create should now be able to set keywords on create
-       
-       Ticket->Create now reports back non-fatal errors and how they were dealt with
-       
-       Ticket->AddKeyword got split into AddKeyword and _AddKeyword. The former
-       has the acl check and calls the latter. the latter just does the adding.
-       
-       Ticket->AddKeyword got a Silent flag, which causes a transaction not
-       to be written. useful on ticket create.
-       
-2001-07-18 15:59  jesse
-
-       * tools/testdeps:
-
-       Added tests for Apache::Cookie
-       and DBI 1.18 to testdeps
-       
-2001-07-18 15:53  jesse
-
-       * webrt/SelfService/: Details.html, Update.html:
-
-       Added the ability for requestors to use the self-service ui to comment on / reply to tickets.
-       
-2001-07-18 15:53  jesse
-
-       * webrt/SelfService/Update.html:
-
-       file Update.html was initially added on branch rt-1-1.
-       
-2001-07-17 22:12  jesse
-
-       * webrt/Admin/Queues/People.html:
-
-       Fixed a link to Users/Modify.html in Queue/People.html
-       
-2001-07-17 22:01  jesse
-
-       * bin/webmux.pl:
-
-       Fix to the solaris chown problem
-       
-2001-07-17 18:37  jesse
-
-       * README:
-
-       Fixed typo in the cron job description
-       
-2001-07-13 02:17  jesse
-
-       * lib/RT/Tickets.pm:
-
-       Work on tickets.pm to support some new searching options
-       
-2001-07-12 19:43  jesse
-
-       * Makefile:
-
-       Bumped version to 2.0.1
-       
-2001-07-11 23:17  jesse
-
-       * etc/config.pm:
-
-       No longer log things of less than 'error' to the logfile
-       
-2001-07-11 23:16  jesse
-
-       * Makefile, bin/mason_handler.fcgi, bin/rt, bin/rt-mailgate,
-       bin/rtadmin, lib/Makefile.PL, lib/RT.pm, lib/RT/Interface/CLI.pm,
-       lib/RT/Interface/Email.pm:
-
-       Make sure that the setgid programs don't drop setgidness before trying to open logfiles
-       
-2001-07-10 20:15  jesse
-
-       * Makefile, lib/Makefile.PL, lib/RT/Tickets.pm,
-       lib/RT/Interface/Web.pm, tools/testdeps:
-
-       Fixes to allow search-by-requestor to search for requestors who don't have RT accounts
-       
-2001-07-10 13:53  jesse
-
-       * bin/webmux.pl:
-
-       Fix for the weird sessiondata permissions bug folks have seen on solaris
-       
-2001-07-10 11:47  jesse
-
-       * lib/RT/Tickets.pm:
-
-       Change to Tickets.pm to fix description of watcher limits
-       
-2001-07-10 11:36  jesse
-
-       * bin/webmux.pl, webrt/Elements/SelectMatch:
-
-       Fixed a bug in webmux.pl that prevented Apache::Cookie support from working
-       
-       Fixed a bug in the enw SelectMatch code
-       
-2001-07-10 11:20  jesse
-
-       * lib/RT/Ticket.pm, webrt/Elements/SelectMatch,
-       webrt/Search/PickRestriction:
-
-       Cleanup to SelectMatch and PickRestriction to clear up the UI issues
-       with searching for Tickets from a give nrequestor
-       
-2001-07-09 10:36  jesse
-
-       * lib/RT/Template.pm:
-
-       Fixed a typo in Template.pm that squashed templates on outgoing mail. (Bug in my untainting fix)
-       
-       Bumped version to 2.0.1-test2
-       
-2001-07-09 10:36  jesse
-
-       * Makefile:
-
-       Fixed a typo in Template.pm that squashed templates on outgoing mail. (Bug in my untainting fix)
-       
-2001-07-08 22:31  jesse
-
-       * README:
-
-       Added some polite comments about supporting the development of RT
-       with contracts, cash or gifts
-       
-2001-07-08 20:14  jesse
-
-       * Makefile, bin/mason_handler.fcgi,
-       webrt/SelfService/Elements/ShowTransaction:
-
-       Bumped version to 2.01pre1
-       
-       Fixed mason_handler header newlines
-       
-2001-07-08 20:12  jesse
-
-       * lib/RT/: ScripAction.pm, ScripCondition.pm, Template.pm,
-       Ticket.pm:
-
-       Taint fixes for ScripAction, ScripCondtion,Template.
-       Header wrapping fix in Template.pm.
-       Fix in Ticket.pm to make EffectiveId a public field.
-       
-2001-07-06 18:32  jesse
-
-       * lib/RT/Attachment.pm:
-
-       Applied a patch from ivan to deal with poorly formed mime messages
-       and clean up the attachment proccessing code.
-       
-2001-07-06 18:26  jesse
-
-       * webrt/SelfService/Attachment/dhandler:
-
-       file dhandler was initially added on branch rt-1-1.
-       
-2001-07-06 18:26  jesse
-
-       * webrt/: SelfService/Details.html,
-       Ticket/Elements/ShowTransaction, SelfService/Attachment/dhandler:
-
-       ShowTransaction now no longer displays 'Comment' and 'Reply' if the user
-       doesn't have the right rights.
-       
-       SelfService uses the 'standard' ShowTransaction.
-       
-       SelfService now displays Attachments
-       
-2001-07-06 18:21  jesse
-
-       * etc/schema.mysql:
-
-       Switched mysql to use LONGTEXT rather than LONGBLOB to get
-       case insensitive searching.
-       
-2001-07-06 18:19  jesse
-
-       * bin/mason_handler.fcgi, lib/RT/Interface/Web.pm,
-       webrt/NoAuth/Logout.html:
-
-       Cleanups to deal better with the fastcgi handler.
-       
-       Switched to CGI::Fast from FCGI
-       
-       ContentType fixes.
-       
-       Logging out now clears the session hash, rather than detaching a perfectly good session. (This gets around an obnoxious tainting issue too)
-       
-2001-07-06 16:14  jesse
-
-       * webrt/Ticket/Attachment/dhandler:
-
-       Changed default attachment type to text/plain from text/html
-       
-2001-07-05 16:48  jesse
-
-       * bin/rt-mailgate, lib/RT/Ticket.pm:
-
-       Updates to make Correspondence on a closed or stalled ticket reopen the ticket
-       
-2001-07-04 00:51  jesse
-
-       * bin/rt:
-
-       bin/rt will now show transactions of type 'text'
-       
-2001-07-04 00:36  jesse
-
-       * bin/webmux.pl:
-
-       Minor fixes to webmux.pl for content type stuff.
-       
-2001-07-03 23:15  jesse
-
-       * lib/RT/Interface/Web.pm, webrt/Admin/Queues/index.html,
-       webrt/Search/PickRestriction:
-
-       Web ui now supports 'SearchByPriority'
-       
-2001-07-03 23:14  jesse
-
-       * etc/config.pm:
-
-       Added a few comments about configuration variables
-       
-2001-07-03 23:12  jesse
-
-       * webrt/SelfService/Elements/ShowTransaction:
-
-       Now SelfService displays attachments of type 'text'
-       
-2001-07-03 23:08  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       With the web ticket display, now display attachments of type 'text' properly.
-       Also, always have a download link.
-       
-2001-07-03 23:00  jesse
-
-       * webrt/Ticket/Elements/ShowLinks:
-
-       Changed SubTickets/SuperTickets to Parents/Children
-       
-2001-07-03 22:57  jesse
-
-       * Makefile:
-
-       Added notes to the effect that the speedycgi and fastcgi handlers aren't
-       supported.
-       
-2001-07-03 22:52  jesse
-
-       * bin/webmux.pl, bin/mason_handler.fcgi,
-       webrt/Ticket/Attachment/dhandler:
-
-       Switched mod_perl hander to use Apache::Cookie
-       
-       Refactored mime type handling to properly set the mime type with the modperl
-       handler and the fastcgi handler
-       
-       Added untainting for the requirred parts of the fastcgi wrapper.
-       I'm not yet confident that it works properly, but it does the right
-       thing in the trivial case.
-       
-2001-06-27 00:11  jesse
-
-       * Makefile:
-
-       Bumped version to 2.0 for release to the unsuspecting masses
-       
-2001-06-25 16:28  jesse
-
-       * Makefile, lib/RT/Ticket.pm:
-
-       Fix for a bug introduced by RC2  (while fixing another bug with _Links)
-        which caused Links listings to recurse rather infinitely.
-       
-       Bumped RC2 to RC3
-       
-2001-06-25 16:25  jesse
-
-       * webrt/Admin/Elements/SelectRights:
-
-       Fix for a crashing bug when editing ACLs without permission
-       
-2001-06-25 12:19  jesse
-
-       * Makefile, lib/RT/Ticket.pm:
-
-       Fixed bug in Ticket.pm -> _Links that caused it to return an error
-       rather than an empty links object if permission denied.
-       
-       Bumped version to RC2
-       
-2001-06-23 02:48  jesse
-
-       * Makefile, README, tools/import-1.0-to-2.0:
-
-       removed 1.0-2.0 importer. (it's now in the contrib archive)
-       updated readme and makefile to know about the change.
-       
-       Bumped the version to 2.0.0-RC1. Yeah. That's right. the major version
-       number just got incremented.
-       
-2001-06-22 14:50  jesse
-
-       * Makefile, lib/RT/Ticket.pm:
-
-       hopefully a fix for everyone's favorite import bug.
-       
-2001-06-20 23:56  jesse
-
-       * webrt/Search/Bulk.html:
-
-       Display cleanups to Bulk.html.
-       Removed bogus nav items
-       
-2001-06-20 17:33  jesse
-
-       * NEWS, lib/Makefile.PL:
-
-       Removed the out of date NEWS file. It's been superceeded by the changelog
-       
-2001-06-20 17:27  jesse
-
-       * Makefile, README, lib/RT/Ticket.pm, lib/RT/User.pm,
-       lib/RT/Interface/Web.pm, tools/import-1.0-to-2.0, tools/testdeps,
-       webrt/Ticket/Display.html, webrt/Ticket/History.html:
-
-       Fixes for the import problems some folks have been seeing
-       Fixes for the Can't click on URL issues reported by mixo and Carl Potter.
-       Turned off some overly verbose debugging.
-       
-       Bumped the version to 1.3.105
-       
-2001-06-19 00:34  jesse
-
-       * Makefile:
-
-       Bumped version to 1.3.104
-       
-2001-06-19 00:25  jesse
-
-       * lib/RT/Tickets.pm:
-
-       A fix for search based on keywords that don't exist. (Some rows would be lost, due to poorly constructed SELECT statements.  This change requires DBIx::SearchBuilder 0.39
-       
-2001-06-18 15:39  jesse
-
-       * Makefile, README, webrt/Ticket/Elements/ShowTransaction:
-
-       Updated README to note new RT2 Errata list
-       Bumped version to 1.3.103
-       Added comments in ShowTransaction to let you see exact transaction / ticket Ids
-       if you view source.
-       
-2001-06-18 15:32  jesse
-
-       * bin/rt:
-
-       Better fomating for cli queue listing.
-       
-2001-06-17 16:45  jesse
-
-       * lib/RT/: Transaction.pm, User.pm:
-
-       Added PurgeTransaction datatype for Transactions.
-       
-       Removed debugging code from User.pm
-       
-2001-06-17 14:36  jesse
-
-       * webrt/Ticket/Elements/Tabs:
-
-       Fix for webui error when displaying next/prev tabs on new tix.
-       
-2001-06-15 22:23  jesse
-
-       * Makefile, README:
-
-       Bumped the version to a private pre-test 1.3.103
-       
-2001-06-15 22:19  jesse
-
-       * README, lib/RT/Ticket.pm, lib/RT/User.pm:
-
-       Debugging fixes for import oddness folks are having
-       
-2001-06-15 01:13  jesse
-
-       * webrt/Search/Bulk.html:
-
-       removed debugging output from bulk.html
-       
-2001-06-14 15:53  jesse
-
-       * Makefile, lib/RT/Transactions.pm,
-       webrt/Ticket/Elements/AddWatchers:
-
-       Installation path of man pages is now configurable
-       By default Transactions should now be ordered by date, no matter what their id sequence is.
-       Fixed an html typo in Tickets/Elements/AddWatchers
-       
-       Bumped version to 1.3.102
-       
-2001-06-14 03:21  jesse
-
-       * Makefile:
-
-       Bumped the version to 1.3.101
-       
-2001-06-14 02:47  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/Interface/Web.pm, webrt/Elements/Tabs,
-       webrt/Ticket/Elements/Tabs:
-
-       Comments in Ticket.pm about less than optimal design
-       Enhancments to Interface/Web for the bulk ticket manipulation tool.
-       Search navigation was cleaned up a bunch.
-       
-2001-06-14 01:52  jesse
-
-       * webrt/Search/Bulk.html:
-
-       file Bulk.html was initially added on branch rt-1-1.
-       
-2001-06-14 01:52  jesse
-
-       * webrt/Search/: BuildSearch, Bulk.html, Listing.html, QueueFooter,
-       QueueHeader, QueueItem:
-
-       Be vewwy vewwy quiet. I'm hunting cweeping features.
-       Like the brand new Bulk Ticket manipulator
-       
-       Removed some cruft from the repository. (unused files from tobix' first
-       search implementation)
-       
-2001-06-13 03:53  jesse
-
-       * Makefile:
-
-       Bumped version to 1.3.100
-       
-2001-06-13 03:52  jesse
-
-       * bin/mason_handler.fcgi:
-
-       The fastcgi handler works for everything except attachment viewing.  I'm going to have to think a bit about how to set
-       content type properly in a nice handler-agnostic manner.
-       
-2001-06-13 03:51  jesse
-
-       * bin/rt-mailgate:
-
-       Fixed a warn -> warning in mailgate's logging
-       
-2001-06-13 03:50  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Adjusting spacing
-       
-2001-06-13 03:50  jesse
-
-       * webrt/Ticket/Elements/Tabs:
-
-       
-       Added an error check to the new navigation bars to deal with a possible lack of active search
-       
-2001-06-12 21:28  jesse
-
-       * etc/config.pm:
-
-       Clarified required permissions for the RT Logdir
-       
-2001-06-12 19:12  jesse
-
-       * etc/config.pm, lib/RT/Queue.pm, lib/RT/Transaction.pm:
-
-       Cleaned up some docs in config.pm and Queue.pm
-       Updated the Transaction Descriptions in transaction.pm to make sure
-       that the Actor is listed.
-       
-2001-06-12 18:08  jesse
-
-       * webrt/Ticket/Elements/Tabs:
-
-       Added links to navigate within an existing search.
-       
-2001-06-08 23:57  jesse
-
-       * webrt/Ticket/Elements/EditKeywordSelects:
-
-       Made "(empty)" the same between "EditKeywordSelects" and "SearchByKeywordSelect"
-       
-2001-06-08 23:51  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Ability to set owner by name when creating tickets.
-       Ability to set timeleft when creating tickets
-       
-2001-06-08 23:00  jesse
-
-       * Makefile, README, etc/schema.Pg, lib/RT/Ticket.pm:
-
-       Added an index to etc/schema.Pg
-       Ticket.pm->Create now passes through a few more values that were missing.
-       
-       Added doc on imports w/ postgres to the readme.
-       
-       bumped the version to 1.3.99
-       
-2001-06-08 18:32  jesse
-
-       * Makefile, tools/import-1.0-to-2.0:
-
-       Fix for merging more than one ticket.
-       Fix for req2rt which imported transactions in reverse order.
-       
-2001-06-07 16:02  jesse
-
-       * Makefile, lib/RT/Queue.pm, tools/import-1.0-to-2.0:
-
-       Catch a possibly undefined value in Queue::AddWatcher
-       Bumped verion to 1.3.97
-       another attempt at fixing the owner change generation code in import.
-       
-2001-06-07 14:59  jesse
-
-       * tools/import-1.0-to-2.0:
-
-       The importer now imports the root user and the general queue.
-       
-2001-06-07 12:44  jesse
-
-       * Makefile, etc/config.pm, lib/RT/Interface/Web.pm:
-
-       Support for a seperate local component root for local WebRT mods and additions.
-       
-2001-06-06 17:25  jesse
-
-       * README:
-
-       Added instructions for migrating  1.0 instances to 2.0
-       
-2001-06-06 16:15  jesse
-
-       * Makefile:
-
-       Bumped version to 1.3.95
-       
-2001-06-06 16:15  jesse
-
-       * tools/import-1.0-to-2.0:
-
-       Importer should now import tickets created by the req importer
-       
-2001-06-06 16:12  jesse
-
-       * bin/initacls.Pg:
-
-       initacls.Pg should now handle pg database on remote machine
-       
-2001-06-06 16:05  jesse
-
-       * webrt/Ticket/Elements/ShowRequestor:
-
-       Don't show the 'About this Requestor' box if the user is privileged.
-       
-2001-06-06 15:37  jesse
-
-       * lib/RT/Date.pm:
-
-       Now date comparisons against never dtrt.
-       
-2001-06-06 15:30  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Search by content now works on the web
-       
-2001-06-06 14:22  jesse
-
-       * webrt/Admin/Groups/Members.html:
-
-       Fix for #552: spurious warning when going into group membership editor
-       
-2001-06-06 14:14  jesse
-
-       * webrt/Ticket/Elements/EditKeywordSelects:
-
-       keywordSelect selction fix (fsck #555)
-       
-2001-06-06 10:57  jesse
-
-       * Makefile, tools/import-1.0-to-2.0:
-
-       Removed spurious 'u' from line 1 of importer.
-       bumped version to 1.3.95-test2
-       
-2001-06-06 09:39  jesse
-
-       * Makefile, tools/import-1.0-to-2.0:
-
-       Possible fix for jens' user import troubles.
-       bounced version to 1.3.95-test1
-       
-2001-06-06 02:12  jesse
-
-       * Makefile, tools/import-1.0-to-2.0:
-
-       Importer wasn't properly grabbing ACLs. Bumped version to 1.3.94
-       
-2001-06-06 01:33  jesse
-
-       * tools/import-1.0-to-2.0:
-
-       Fixed a bug in the 'Make users superusers' code in the importer
-       
-2001-06-06 00:41  jesse
-
-       * lib/RT/Ticket.pm:
-
-       fixed a missing =cut (end of perldoc in ticket.pm
-       
-2001-06-06 00:40  jesse
-
-       * Makefile, tools/import-1.0-to-2.0:
-
-       fixing a typo in importer's mime parser
-       
-2001-06-06 00:19  jesse
-
-       * Makefile, lib/Makefile.PL, lib/RT/Action/Notify.pm,
-       lib/RT/Action/SendEmail.pm, tools/testdeps:
-
-       Cleaned up some dependencies
-       RT should no longer send mail when there are no recipients. thanks to the nice folks at Sensarray.com for some good debugging.
-       
-2001-06-05 23:16  jesse
-
-       * Makefile, bin/webmux.pl, tools/import-1.0-to-2.0:
-
-       Fixed some bogus header parsing in import.
-       web mux now tries to chown files again. (christian's going to test it again ;)
-       Bumped to 1.3.91 for a release
-       
-2001-06-05 11:34  jesse
-
-       * webrt/Admin/Users/Modify.html:
-
-       Rephrased the "Privileged" checkbox in AdminUsers.
-       
-2001-06-05 11:18  jesse
-
-       * Makefile, bin/webmux.pl, tools/import-1.0-to-2.0,
-       webrt/NoAuth/Logout.html:
-
-       webmux no longer tries to chown its data directories on startup
-       import now handles final_priority
-       Logout.html now refreshes to a login page
-       
-2001-06-05 10:42  jesse
-
-       * Makefile, tools/import-1.0-to-2.0:
-
-       When we added support for 'priority' transactions, we accidentally broke
-       support for 'subject' transactions.  fixed now.
-       
-2001-06-05 03:25  jesse
-
-       * Makefile, tools/import-1.0-to-2.0:
-
-       Import tool now handles priority changes.
-       
-2001-06-05 02:56  jesse
-
-       * Makefile, tools/import-1.0-to-2.0:
-
-       Minor tweak to importer to try even harder to find users in the database before creating new ones.
-       
-2001-06-05 02:32  jesse
-
-       * Makefile, tools/import-1.0-to-2.0:
-
-       importer is now less likely to try to greate nonexitent empty users.
-       
-       Makefile now chgrps web ui datafiles
-       
-2001-06-05 00:06  jesse
-
-       * Makefile, tools/import-1.0-to-2.0:
-
-       Removed out of date comments in the importer
-       Made the importer grab its libraries from the makefile. (Turned off testing code)
-       
-2001-06-05 00:01  jesse
-
-       * Makefile:
-
-       Bumped the version # to 1.3.84 for immediate release
-       
-2001-06-04 23:50  jesse
-
-       * Makefile, lib/RT/Ticket.pm, tools/import-1.0-to-2.0:
-
-       Cleanups to Ticket->Import
-       import-1.0-to-2.0 now deals with dates right.
-       
-2001-06-04 20:52  jesse
-
-       * lib/RT/Link.pm, lib/RT/Ticket.pm, lib/RT/User.pm,
-       tools/import-1.0-to-2.0:
-
-       Cleanup to Ticket, Link and User.
-       
-       merge now works on import.
-       
-       most everything in import other than ticket dates should work now.
-       
-2001-06-04 01:34  jesse
-
-       * tools/import-1.0-to-2.0:
-
-       more cleanup
-       
-2001-06-04 00:03  jesse
-
-       * tools/import-1.0-to-2.0:
-
-       First cut at importing queue adminccs and acls
-       
-2001-06-03 22:16  jesse
-
-       * tools/import-1.0-to-2.0:
-
-       Cleanup and better progress indication
-       
-2001-06-03 13:33  jesse
-
-       * lib/RT/Record.pm, lib/RT/Ticket.pm, tools/import-1.0-to-2.0:
-
-       More work on the importer. now it gets transaction creators right and catches requestor email addreses.
-       
-2001-06-03 03:43  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/Transaction.pm, tools/import-1.0-to-2.0:
-
-       Transaction.pm now allows the caller to turn off scrips (for import)
-       Ticket.pm now has a mostly working import method.
-       import-1.0-to-2.0 seems to have some basic functionality.  it's not _working_ yet, but it
-       will do most of what we want it to.
-       
-2001-06-02 20:36  jesse
-
-       * webrt/Ticket/Display.html:
-
-       Fix for Ticket #537 Crash when creating ticket without permission to view ticket
-       
-2001-06-02 14:22  jesse
-
-       * tools/import-1.0-to-2.0:
-
-       added a couple of todos to the import tool
-       
-2001-06-02 14:14  jesse
-
-       * Makefile, tools/import-1.0-to-2.0:
-
-       Work on the importer. it now runs.  (note that it probably won't yet _import_ anything)
-       
-2001-06-02 12:58  jesse
-
-       * Makefile, bin/webmux.pl, lib/RT/Ticket.pm, lib/RT/Transaction.pm:
-
-       Bumped the version to 1.3.84
-       
-       Once again chown mason data directory in webmux.pl, this time
-       using more reliable, dynamic userids, rather than compiled in defaults.
-       
-       Added an 'import' method to Ticket, for the RT1 importer.
-       
-       Added a Subject method to transaction, to simplify the lives of template authors
-       
-2001-06-01 23:38  jesse
-
-       * tools/: import-1.0-to-2.0, insertdata:
-
-       Cleaned up some names and descriptions in insertdata
-       
-       First checkin of outline of code of import tool. It's never been run.
-       It's incomplete.
-       
-2001-06-01 23:38  jesse
-
-       * tools/import-1.0-to-2.0:
-
-       file import-1.0-to-2.0 was initially added on branch rt-1-1.
-       
-2001-05-31 23:27  jesse
-
-       * lib/RT/Tickets.pm:
-
-       Cleaned up Tickets->LimitQueue a bit
-       
-2001-05-31 21:22  jesse
-
-       * Makefile, tools/testdeps:
-
-       Fixed testdeps to use new searchbuilder. bumped version to 1.3.83
-       
-2001-05-31 21:14  jesse
-
-       * lib/RT/Tickets.pm, lib/RT/Interface/Web.pm,
-       webrt/Elements/SelectKeyword:
-
-       Logic fixes for keyword select negation
-       
-2001-05-31 20:30  jesse
-
-       * lib/RT/Tickets.pm, lib/RT/Interface/Web.pm,
-       webrt/Elements/SelectKeyword:
-
-       Added support for "Tickets without keyword 'foo'.
-       
-2001-05-31 17:32  jesse
-
-       * bin/webmux.pl, lib/RT/Interface/Web.pm,
-       webrt/Ticket/Attachment/dhandler:
-
-       Fix for #522: attachments without names got short shrift.
-       webRT now dies rather than run when users can't log in due to a permissions
-       bug.
-       
-2001-05-31 02:57  jesse
-
-       * etc/: schema.Pg, schema.mysql:
-
-       Cleaned up the table indices a bit. for mysql, yanked duplicate indices.
-       for Pg, added an index (we need to regen the schema for pg soon)
-       
-2001-05-31 02:46  jesse
-
-       * Makefile, lib/RT/Interface/Web.pm, webrt/Ticket/ModifyAll.html,
-       webrt/Ticket/ModifyPeople.html, webrt/Ticket/Elements/AddWatchers,
-       webrt/Ticket/Elements/EditPeople:
-
-       You can now add watchers by email address
-       Bumped version to 1.3.82
-       
-2001-05-29 15:58  jesse
-
-       * webrt/Ticket/Attachment/dhandler:
-
-       Fixed the attachments display bug.
-       
-2001-05-29 15:48  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Fix for #513 - status update without permissions returns no error message
-       
-2001-05-29 00:38  jesse
-
-       * Makefile:
-
-       Bumped version to 1.3.81
-       
-2001-05-28 20:39  jesse
-
-       * bin/webmux.pl:
-
-       Removed a bogus line from webmux
-       
-2001-05-28 20:29  jesse
-
-       * lib/RT/: Ticket.pm, Interface/Web.pm:
-
-       Work to solve 325: updating detritus in update listing
-       
-2001-05-28 17:35  jesse
-
-       * bin/rt, etc/schema.mysql, etc/schema.pm, lib/RT/Ticket.pm,
-       lib/RT/Interface/CLI.pm, webrt/Ticket/Attachment/dhandler:
-
-       Work on the CLI to resolve #482.  Can't add content when creating tix with the CLI
-       Do a bunch of better error checking on ticket creation.
-       
-       Generalized the ticket status checking code.
-       
-       Added another index on Attachments for increased speed.
-       
-2001-05-28 15:49  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Removed code which auto-opened tickets that were new.  It should
-       be a scrip and it's too late in teh release cycle to do this right now.
-       
-2001-05-28 15:24  jesse
-
-       * webrt/SelfService/: Details.html, Elements/MyRequests:
-
-       Fixed #506. Non-priv user can't see tickets
-       
-2001-05-23 23:53  jesse
-
-       * webrt/SelfService/Elements/MyRequests:
-
-       Fixed MyRequest so it shows your tickets.
-       
-2001-05-23 23:18  jesse
-
-       * Makefile:
-
-       Bumped the version to 1.3.80
-       
-2001-05-23 23:01  jesse
-
-       * bin/webmux.pl, docs/manual.pod, webrt/Elements/MyRequests,
-       webrt/Elements/MyTickets, webrt/NoAuth/Logout.html,
-       webrt/Ticket/ModifyAll.html:
-
-       Fixed logout bug from 1.3.79 http://fsck.com/rt2/Ticket/Display.html?id=500
-       Fixed bug in jumbo from 1.3.79 http://fsck.com/rt2/Ticket/Display.html?id=496
-       Added a bit of docs about templates to the manual
-       
-       Cleaned up the ui for MyRequests and MyTickets a bit.
-       
-2001-05-23 12:34  jesse
-
-       * webrt/SelfService/: Prefs.html, index.html:
-
-       Little bit of cleanup to SelfService. added prefs.
-       
-2001-05-23 12:34  jesse
-
-       * webrt/SelfService/Prefs.html:
-
-       file Prefs.html was initially added on branch rt-1-1.
-       
-2001-05-23 12:07  jesse
-
-       * Makefile:
-
-       Bumped version to 1.3.79.
-       
-2001-05-23 12:06  jesse
-
-       * README, tools/testdeps:
-
-       Added dependecy on DBIx::SearchBuilder 0.34
-       
-2001-05-23 11:43  jesse
-
-       * bin/: rt-mailgate, webmux.pl:
-
-       Made sure that the webui always writes sessions to disk
-       Fixed a typo in the mail gateway.
-       
-2001-05-23 00:09  jesse
-
-       * Makefile, bin/rt-mailgate:
-
-       Added a bit of code to rt-mailgate to deal with not properly loading users on
-       ticket creation.
-       
-2001-05-22 23:01  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Within Ticket->Create, always get a Queue object as SystemUser for like, defaults and stuff.
-       
-2001-05-21 18:12  jesse
-
-       * etc/config.pm:
-
-       Added comments from Feargal about how to configure RT for http urls.
-       
-2001-05-21 16:37  jesse
-
-       * Makefile:
-
-       bumped version to 1.3.78
-       
-2001-05-21 16:36  jesse
-
-       * lib/RT/Ticket.pm, webrt/Ticket/Display.html:
-
-       Tickets now open when they're new and get acted on.
-       
-2001-05-21 16:09  jesse
-
-       * lib/RT/Action/: Autoreply.pm, SendEmail.pm:
-
-       Fix for Ticket #481 $CorrespondAddress= variable in config.pm doesn't work
-       
-2001-05-21 15:54  jesse
-
-       * webrt/Elements/MessageBox:
-
-       Added a space at teh end of the line, per the standard convention for signature
-       dashes.
-       
-2001-05-21 15:54  jesse
-
-       * webrt/Elements/MessageBox:
-
-       If the user doesn't have a signature, don't include signature dashes
-       
-2001-05-21 15:17  jesse
-
-       * lib/RT/Tickets.pm, webrt/Ticket/ModifyAll.html:
-
-       Dead tickets aren't searchable via the ui anymore.
-       ModifyAll is a bit smarter about what to let people do.
-       
-2001-05-21 14:02  jesse
-
-       * lib/RT/Keyword.pm, webrt/Admin/Keywords/index.html:
-
-       Editing keywords without permission now actually tells you so.
-       
-2001-05-21 13:32  jesse
-
-       * webrt/Admin/: Global/Scrips.html, Queues/Scrips.html:
-
-       Users without permission to delete scrips now get a proper permission denied.
-       
-2001-05-21 13:20  jesse
-
-       * webrt/Ticket/: Update.html, Elements/Tabs:
-
-       The ticket update form is now a little smarter about only letting people perform
-       updates that they have the right to perform.
-       
-2001-05-17 23:09  jesse
-
-       * Makefile:
-
-       Chmod the makefile in the make dist procedure.
-       
-2001-05-17 23:05  jesse
-
-       * README:
-
-       Cleaned up some instructions. Thanks Feargal.
-       
-2001-05-17 22:50  jesse
-
-       * Makefile, lib/RT/Transaction.pm, lib/RT/Action/SendEmail.pm,
-       tools/insertdata:
-
-       Fixed scrip actions to activate when there's a missing scripcontent.
-       
-       Added a Content method to Transaction.pm
-       Fixed Tempates to use new Content method.
-       
-2001-05-17 16:19  jesse
-
-       * lib/RT/Transaction.pm, lib/RT/Action/SendEmail.pm,
-       webrt/Ticket/Display.html, webrt/Ticket/Update.html:
-
-       Better debugging info for some scrips.
-       
-       Fixed bugs which prevented status and owner to change on correspondence
-       and comment.
-       
-2001-05-17 12:36  jesse
-
-       * Makefile, README:
-
-       Bumped the version. Added Mark Vevers to the thansk in the readme.
-       
-2001-05-17 12:34  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Removed some obsolete code. fixed a bug in Comment recording from Mark Vevers
-       
-2001-05-16 18:51  jesse
-
-       * Makefile, tools/testdeps:
-
-       Fixed testdeps to not install bogus new DBD::mysql rev.
-       Bumped rev to 1.3.75
-       
-2001-05-16 17:30  jesse
-
-       * Makefile:
-
-       bumped to 1.3.74
-       
-2001-05-16 17:30  jesse
-
-       * webrt/Admin/Groups/Modify.html:
-
-       Fixed a small bug in Groups editing
-       
-2001-05-16 17:21  jesse
-
-       * tools/testdeps:
-
-       Bumped version to 1.3.73.
-       Bumped dependency on searchbuilder to 0.33
-       
-2001-05-16 17:15  jesse
-
-       * webrt/: Elements/TitleBoxStart, Ticket/Update.html,
-       Ticket/Elements/Tabs:
-
-       The quick link for 'Resolve' now requests that the user enter a ticket update
-       
-2001-05-16 15:45  jesse
-
-       * README, lib/RT/Interface/Web.pm, tools/testdeps,
-       webrt/Ticket/Display.html:
-
-       Added some documentation about what to do if the install fails.
-       
-       Specified a minimum working version of DBD::mysql.
-       
-       Fixed support for entering updates via the webui.
-       
-2001-05-15 00:55  jesse
-
-       * lib/RT/Action/Autoreply.pm:
-
-       Fixed a typo that broke autoreplies
-       
-2001-05-15 00:37  jesse
-
-       * tools/testdeps:
-
-       added Errno dependency
-       
-2001-05-14 23:44  jesse
-
-       * etc/config.pm, tools/insertdata, webrt/Admin/Queues/People.html:
-
-       Cleaned up a bit of phrasing. cleaned up some extra /s in urls.
-       
-2001-05-14 22:49  jesse
-
-       * Makefile, bin/mason_handler.fcgi, bin/mason_handler.scgi, bin/rt,
-       bin/webmux.pl, lib/Makefile.PL, lib/RT/Date.pm,
-       lib/RT/Interface/Web.pm, tools/testdeps:
-
-       Switched from Date::Manip To Graham Barr's Date::Parse
-       
-2001-05-14 18:58  jesse
-
-       * lib/RT/Scrips.pm, lib/RT/Ticket.pm, lib/RT/Interface/Web.pm,
-       webrt/Ticket/Display.html, webrt/Ticket/Elements/Tabs:
-
-       Work on the web frontend. the "quick" links have been cleaned up and decomplexified.
-       
-2001-05-14 17:11  jesse
-
-       * lib/RT/User.pm, lib/RT/Interface/Web.pm,
-       webrt/Admin/Groups/Modify.html, webrt/Admin/Users/Modify.html:
-
-       Cleaned up bugs related to spurious extra display of information in user and group modification and ACL deletion
-       when the user didn't have the right to do so.
-       
-2001-05-13 23:05  jesse
-
-       * webrt/Admin/Users/index.html:
-
-       no longer provide a link to create a new user to someone who doesn't have rights to do so.
-       
-2001-05-13 22:49  jesse
-
-       * lib/RT/Ticket.pm, tools/insertdata, webrt/Ticket/Modify.html:
-
-       yanked bogus Ticket Queue caching
-       rephrased ticket creation autoreply
-       
-2001-05-13 22:15  jesse
-
-       * webrt/User/Prefs.html:
-
-       Added a hack to make sure that session gets written to disk
-       
-2001-05-13 22:11  jesse
-
-       * webrt/User/Prefs.html:
-
-       more work on letting users edit their own passwords
-       
-2001-05-13 21:40  jesse
-
-       * webrt/Ticket/: Attachment/dhandler, Elements/ShowTransaction:
-
-       Fix for #433. now attachements are displayable after merges.
-       
-2001-05-12 17:46  jesse
-
-       * Makefile, lib/Makefile.PL, tools/testdeps, webrt/User/Prefs.html:
-
-       Started work on user prefs. password changing is untested
-       
-       Fixed dependency on SB to .31 and bumped version
-       
-2001-05-11 12:32  jesse
-
-       * lib/RT/Record.pm:
-
-       turned on use of DBIx::SearchBuilder::Record::Cachable
-       
-2001-05-11 12:30  jesse
-
-       * lib/RT/User.pm, webrt/Elements/Quicksearch:
-
-       Redid how the ACL checking works for great perf gains.
-       Added stalled lists to quicksearch.
-       
-2001-05-09 20:11  jesse
-
-       * Makefile:
-
-       Bumping the version # so people working off cvs get less confused.
-       
-2001-05-09 20:11  jesse
-
-       * bin/rt-mailgate, lib/RT/Queue.pm, lib/RT/Action/Autoreply.pm,
-       lib/RT/Action/Notify.pm, lib/RT/Action/NotifyAsComment.pm,
-       lib/RT/Action/SendEmail.pm:
-
-       Cleanup in the mail sending stuff.
-               fix for ticket 403:  RT should no longer send mail when it has
-               no recipients
-       
-               fix for #404: Squelch-Replies-To should be a bit more intelligent,
-               since it was rewritten from scratch
-       
-               RT should now properly send mail to queue ccs and queue admin ccs
-               when you ask it to
-       
-               internally, RT's mail sending stuff now lets you pass around
-               arrays of addresses to send mail to, rather than comma delimited
-               strings. More flexible down the line.
-       
-2001-05-09 16:39  jesse
-
-       * README:
-
-       Updated the readme to note the dependency on setuid perl
-       
-2001-05-09 16:08  jesse
-
-       * webrt/Ticket/Elements/ShowLinks:
-
-       fix for RT/fsck.com: Ticket #440 [rt-devel] 'Depended on by' doesn't work
-       
-2001-05-08 20:48  jesse
-
-       * etc/schema.mysql, etc/schema.pm, lib/RT/Ticket.pm,
-       lib/RT/Transaction.pm, webrt/Admin/Elements/UserTabs,
-       webrt/Admin/Queues/People.html, webrt/Elements/MyRequests,
-       webrt/Elements/MyTickets, webrt/Elements/Tabs,
-       webrt/Ticket/Elements/ShowBasics,
-       webrt/Ticket/Elements/ShowRequestor:
-
-       Schema.pm now has a few more indices. the mysql schema has been regenerated, but not
-       the Pg or oracle schemas.
-       
-       in Ticket.pm, a message got the queue id replaced with the queue name
-       
-       removed a spurious variable localization in Transaction.pm
-       
-       Removed a pointer to a nonexistent page  on admin/user/modify
-       
-       Modifying queue watchers now has a more coherent title
-       
-       "This user's tickets, My requests and My tickets are now limited to the 25 highest priority items
-       attached to you.
-       
-       The "Administration" tab has been changed to the "Configuration" tab
-       
-2001-04-04 16:55  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Fixing a comment in the web interface. no functional changes.
-       
-2001-04-04 16:52  jesse
-
-       * Makefile:
-
-       
-       Bumping the version to 1.3.70 for release
-       
-2001-04-04 16:51  jesse
-
-       * lib/RT/User.pm:
-
-       lib/RT/User no longer treats "ModifySelf" as equivalent to "AdminUsers" for the current user.
-       
-2001-04-04 15:08  jesse
-
-       * lib/RT/KeywordSelect.pm, lib/RT/Action/Autoreply.pm,
-       webrt/Admin/Global/Keywords.html, webrt/Admin/Queues/Keywords.html:
-
-       Fixed a crashing bug and an ACL violation on keywordselect deletion
-       
-2001-04-04 00:19  jesse
-
-       * Makefile:
-
-       bumping version for release
-       
-2001-04-03 21:14  jesse
-
-       * Makefile:
-
-       Bumped the version
-       
-2001-04-03 21:08  jesse
-
-       * etc/config.pm, lib/RT/Action/Notify.pm:
-
-       Added configuration tweak to not set a :; To header if the user doesn't want it.
-       
-2001-04-03 17:32  jesse
-
-       * lib/RT/Action/Notify.pm:
-
-       Fix for sendmail null list syntax.  : ;  is not the same as :; to sendmail
-       
-2001-04-03 17:05  jesse
-
-       * webrt/Admin/Queues/: GroupRights.html, UserRights.html:
-
-       removed a couple of stray 's in the html
-       
-2001-04-03 16:50  jesse
-
-       * webrt/Elements/Header:
-
-       Dropped doctype back to 4.0 because 4.01 makes mozilla render things funny
-       
-2001-04-03 16:47  jesse
-
-       * webrt/Elements/Quicksearch:
-
-       <TABLE>
-       should have been </TABLE>
-       
-2001-04-03 16:30  jesse
-
-       * webrt/Elements/Quicksearch:
-
-       Added a feature request/patch from nick@netability.ie
-       http://fsck.com/rt2/Ticket/Display.html?id=345
-       
-2001-04-03 16:01  jesse
-
-       * tools/testdeps:
-
-       Adding in testing for params::validate 0.02
-       
-2001-04-03 15:46  jesse
-
-       * Makefile:
-
-       Bumped the version slightly for a prerelease
-       
-2001-04-03 15:40  jesse
-
-       * lib/RT/Action/Autoreply.pm, lib/RT/Action/SendEmail.pm,
-       tools/insertdata:
-
-       Fixed autoreply by adding a new scrip. some misc. cleanup in SendEmail (method calls were on the wrong object)
-       
-2001-04-03 15:40  jesse
-
-       * lib/RT/Action/Autoreply.pm:
-
-       file Autoreply.pm was initially added on branch rt-1-1.
-       
-2001-04-03 15:15  jesse
-
-       * lib/RT/Action/SendEmail.pm:
-
-       Fixed a bug in the 'blacklist' regexp
-       
-2001-04-03 15:04  jesse
-
-       * etc/config.pm, lib/RT/Action/SendEmail.pm,
-       lib/RT/Interface/Web.pm, webrt/Ticket/Elements/ShowRequestor:
-
-       Two seperate fixes for the "RT doesn't send mail" problem. One that helps fix Mail::Internet->send
-       and one that provides an alternative.
-       
-       A fix for a bad link in ShowRequestor.
-       
-       Updating fields via the web ui should now be a bit more descriptive
-       
-2001-04-03 02:31  jesse
-
-       * webrt/Ticket/ModifyPeople.html:
-
-       Missed one of the mason fixes
-       
-2001-04-03 02:31  jesse
-
-       * Makefile, bin/rt-mailgate, etc/config.pm, lib/RT/Date.pm,
-       lib/RT/Ticket.pm, lib/RT/Transaction.pm, lib/RT/Watcher.pm,
-       lib/RT/Interface/Web.pm, webrt/Admin/Global/GroupRights.html,
-       webrt/Admin/Global/Keywords.html, webrt/Admin/Global/Scrips.html,
-       webrt/Admin/Global/UserRights.html,
-       webrt/Admin/Keywords/index.html,
-       webrt/Admin/Queues/GroupRights.html,
-       webrt/Admin/Queues/Keywords.html, webrt/Admin/Queues/People.html,
-       webrt/Admin/Queues/Scrips.html, webrt/Admin/Queues/UserRights.html,
-       webrt/Ticket/Modify.html, webrt/Ticket/ModifyAll.html,
-       webrt/Ticket/ModifyDates.html, webrt/Ticket/ModifyPeople.html:
-
-       Added support for parsing Cc and To in the mail gateway
-       (resolves the last work item for beta 2 - #219)
-       
-       Ticket due date is no longer set to "right now" if the queue has an
-       undefined "default due in"
-       
-       Cleanup warnings in date, ticket and watcher
-       
-       fixes for a bunch of mason 1.01 related bugs (Mason changed handling of combined GET and POST, thus breaking RT)
-       
-2001-04-02 23:15  jesse
-
-       * README, bin/webmux.pl:
-
-       Cleanup for mason 1.01.
-       Moved Apache::DBI out of the webmux into the instructions
-       
-2001-04-02 17:56  jesse
-
-       * tools/initdb:
-
-       Typo fix from  "Nick Hilliard" <nick@netability.ie>
-       
-2001-04-02 15:32  jesse
-
-       * Makefile, lib/RT/Keyword.pm, webrt/NoAuth/Logout.html:
-
-       Makefile cleanup.
-       Fix for #342 - reported by ivan
-       
-       Fix for a bug that clobbered logouts.
-       
-2001-04-02 03:09  jesse
-
-       * Makefile:
-
-       Bumped version for release
-       
-2001-04-01 19:19  jesse
-
-       * bin/rtadmin, lib/RT/ACE.pm, lib/RT/Interface/Web.pm,
-       webrt/Admin/Elements/SelectRights,
-       webrt/Admin/Global/GroupRights.html,
-       webrt/Admin/Global/UserRights.html,
-       webrt/Admin/Queues/GroupRights.html,
-       webrt/Admin/Queues/UserRights.html:
-
-       Redid the ACL editor so that it's much much faster. and easier to use...if not quite as pretty.
-       
-2001-04-01 17:31  jesse
-
-       * webrt/Ticket/Elements/: ShowDates, ShowRequestor:
-
-       fixing a couple of html typos
-       
-2001-03-31 03:07  jesse
-
-       * Makefile:
-
-       fixing Changelog generation
-       
-2001-03-31 02:52  jesse
-
-       * Makefile:
-
-       Bumped the version.
-       
-2001-03-31 02:52  jesse
-
-       * webrt/User/Prefs.html:
-
-       Cleaned up user preferences somewhat. removed things that don't do anything.
-       
-               -j
-       
-2001-03-31 01:59  jesse
-
-       * bin/rt:
-
-       Fix for #88   RT now lets you use the CLI to search for tickets, based on links to other tickets
-       
-2001-03-31 01:20  jesse
-
-       * README:
-
-       Fix for #216: Web session files need better handling and cleanup
-       
-2001-03-31 00:49  jesse
-
-       * Makefile, README, bin/rtadmin, bin/webmux.pl, etc/config.pm:
-
-       Moved RT Session data out of /tmp to somewhere that makes more sense.
-       This is the first half of the fix for #216.  Now we just need to document the cronjob reaper to kill old sessions
-       
-       Cleaned up creation of queues and users in bin/rtadmin
-       
-       Updates to the README
-       
-2001-03-30 23:44  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Fix for http://fsck.com/rt2/Ticket/Display.html?id=324
-       mail from requestors does not reopen ticket
-       
-2001-03-30 23:19  jesse
-
-       * bin/rtadmin, lib/RT/Queue.pm, lib/RT/Watcher.pm:
-
-       Work on Watchers and editing watchers from the CLI tool.  added support for --list-{queues|users|groups}
-       
-2001-03-30 19:31  jesse
-
-       * bin/rt, lib/RT/ACE.pm, lib/RT/Queue.pm, lib/RT/Ticket.pm,
-       lib/RT/Tickets.pm, lib/RT/Watcher.pm, lib/RT/Action/SendEmail.pm,
-       lib/RT/Interface/Web.pm:
-
-       A bunch of reworking of access control for watchers. should be much more robust
-       and more flexible.
-       
-       Resolves http://fsck.com/rt2/Ticket/Display.html?id=253 by adding the "Watch" and "WatchAsAdminCc" rights.
-       
-2001-03-30 15:41  jesse
-
-       * lib/RT/: Action/Notify.pm, Interface/Web.pm:
-
-       Tiny cleanup in Interface/Web.pm.  no functional difference there just being more explicit.
-       
-       Fix for #292: Sender of a message is no longer notified of that message.
-       
-2001-03-30 02:55  jesse
-
-       * Makefile:
-
-       Bumped the version
-       
-2001-03-30 02:37  jesse
-
-       * webrt/Elements/SelectDate:
-
-       Fixed an as-yet-untickled bug in SelectDate that incremented things too much
-       
-2001-03-30 02:32  jesse
-
-       * lib/RT/Template.pm, webrt/Admin/Global/Scrips.html:
-
-       Fixes to template creation. stupid typo.
-       Global scrips creation should now work better
-       
-2001-03-30 02:12  jesse
-
-       * webrt/: Admin/Elements/GroupTabs, Admin/Groups/Members.html,
-       Admin/Groups/Modify.html, Admin/Users/Modify.html,
-       Elements/ListActions:
-
-       Fix for PseudoGroups having a prompt to add members.
-       some cleanups to not make the "Results" box pop up when it's not wanted.
-       
-2001-03-30 01:41  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Attached is a patch to implement the ShowTicketComments in the
-       display of transactions of a ticket.
-       
-                       Arthur de Jong <arthur@West.NL>
-       
-2001-03-30 01:34  jesse
-
-       * lib/RT/Scrip.pm, webrt/Admin/Global/Scrips.html,
-       webrt/Admin/Queues/Scrips.html:
-
-       Fix for 328: Re: [rt-users] 1.3.64 & postgres & scrips
-       there was an ACL bug.
-       
-2001-03-28 22:15  jesse
-
-       * Makefile, webrt/autohandler:
-
-       Fixed a tiny bug in the new authandler that caused logout to fail
-       
-2001-03-27 22:30  jesse
-
-       * webrt/index.html:
-
-       fixed index.html
-       
-2001-03-27 22:26  jesse
-
-       * Makefile, webrt/Admin/Groups/Members.html,
-       webrt/Ticket/Update.html:
-
-       Added a couple of fixes from Arthur at west.nl
-       Groups/Members deals better with multiple selections
-       Ticket/Update now displays queue watchers.
-       bumped the version to 1.3.63
-       
-2001-03-27 04:25  jesse
-
-       * docs/manual.pod, webrt/autohandler, webrt/index.html,
-       webrt/Admin/Users/index.html, webrt/Elements/ShadedBox,
-       webrt/Search/Listing.html:
-
-       Lots of cleanup of the auothandler.
-       a tiny bit of doc about an alternative apache configuration.
-       some web ui cleanup so that when you are on a page, your location is more properly hilighted.
-       admin/users includes some more verbiage explaining what's going on.
-       
-2001-03-25 00:44  jesse
-
-       * Makefile, lib/RT/Interface/Web.pm:
-
-       Bumped the version.
-       cosmetic fix in Interface/Web.pm
-       
-2001-03-23 20:33  jesse
-
-       * lib/RT/: Action/SendEmail.pm, Interface/Web.pm:
-
-       Fixed for TEXTAREA newline bug and Correspondence subject bug.
-       
-2001-03-23 00:34  jesse
-
-       * lib/RT/Action/Notify.pm:
-
-       : goes outside the '' in undisclosed recipients
-       
-2001-03-23 00:30  jesse
-
-       * lib/RT/: ACL.pm, ObjectKeywords.pm:
-
-       Removed some very loud uneccesary debugging statements
-       
-2001-03-23 00:27  jesse
-
-       * Makefile, lib/RT/Action/Notify.pm, lib/RT/Action/SendEmail.pm:
-
-       Work on mail sending routines to be more careful about newlines in subjects.
-       And about Undisclosed recipients
-       
-2001-03-22 23:17  jesse
-
-       * lib/RT/Action/Notify.pm:
-
-       yet another typo in notify.pm
-       
-2001-03-22 23:12  jesse
-
-       * lib/RT/Action/Notify.pm:
-
-       typo fix
-       
-2001-03-22 23:09  jesse
-
-       * lib/RT/Action/: Notify.pm, SendEmail.pm:
-
-       Cleanups and fixes to Notify and SendEmail
-       
-2001-03-22 19:46  jesse
-
-       * webrt/Ticket/ModifyAll.html:
-
-       TicketObj->Ticket
-       
-2001-03-22 19:42  jesse
-
-       * lib/RT/Action/Notify.pm:
-
-       A more functional Undisclosed Recipients;
-       
-2001-03-22 19:28  jesse
-
-       * webrt/Ticket/: ModifyAll.html, Elements/Tabs:
-
-       Elements/Tabs now does better access control checking before making
-       buttons available to people.
-       
-       ModifyAll.html has a better title and should now update objectkeywords.
-       
-2001-03-22 18:18  jesse
-
-       * lib/RT/: Date.pm, Ticket.pm:
-
-       Added  a routine to Date.pm to advance the date N days
-       
-       Started using queue defaults on Ticket->Create
-       
-2001-03-22 18:17  jesse
-
-       * webrt/: autohandler, Elements/Login, NoAuth/Login.html,
-       Search/autohandler, Ticket/autohandler:
-
-       Cleanup of the login process. now you can't accidentally call "Login.html"
-       when you're already logged in.
-       removed a couple of bogus old autohandlers
-       
-2001-03-22 18:17  jesse
-
-       * webrt/Elements/Login:
-
-       file Login was initially added on branch rt-1-1.
-       
-2001-03-22 14:45  jesse
-
-       * webrt/Ticket/Elements/EditPeople:
-
-       EditPeople should now enforce a list of possible owners reasonably
-       
-2001-03-21 21:40  jesse
-
-       * Makefile:
-
-       bumped the version to .60
-       
-2001-03-21 21:22  jesse
-
-       * docs/manual.pod:
-
-       Adding some content to the manual. and even more places where the manual is
-       missing content. :/
-       
-2001-03-21 12:21  jesse
-
-       * lib/RT/Action/NotifyAsComment.pm:
-
-       NotifyAsComment should now DTRT and send mail from the comments email address
-       
-2001-03-21 02:46  jesse
-
-       * Makefile:
-
-       yanked some cruft from the ChangeLog creator
-       
-2001-03-21 02:44  jesse
-
-       * Makefile, README:
-
-       Bumped the version. added some people to the readme
-       
-2001-03-21 02:39  jesse
-
-       * webrt/Ticket/Elements/ShowBasics:
-
-       Fix for 242: time left displayed via the web ui is now more intuitive
-       
-2001-03-21 02:37  jesse
-
-       * bin/rt, bin/rt-mailgate, lib/RT.pm, lib/RT/Attachment.pm,
-       lib/RT/Date.pm, lib/RT/Tickets.pm, lib/RT/User.pm:
-
-       Added more error checking and error handling to the mail gateway
-       finished code in Attachment.pm to handle too-long attachments
-       
-       added support for limiting by date to the CLI
-       
-       fixed little bugs in user, date and tickets.
-       
-2001-03-20 19:02  jesse
-
-       * docs/manual.pod:
-
-       file manual.pod was initially added on branch rt-1-1.
-       
-2001-03-20 19:02  jesse
-
-       * docs/manual.pod:
-
-       actually adding the outline of the manual
-       
-2001-03-20 19:01  jesse
-
-       * Makefile, bin/rt, docs/API, docs/README.docs, docs/Security,
-       docs/keywords, etc/config.pm:
-
-       Starting the doc cleanup
-       
-2001-03-20 15:26  jesse
-
-       * webrt/Elements/SelectTicketSortBy:
-
-       LastUpdated, not LastUpdate
-       
-2001-03-20 15:21  jesse
-
-       * webrt/Elements/: SelectDate, SelectTicketSortBy:
-
-       more things to sort by.
-       select date shouldn't insert spurious null dates.
-       
-2001-03-20 13:27  jesse
-
-       * lib/RT/Action/SendEmail.pm:
-
-       fixed a typo. $defined is not useful perl ;)
-       
-2001-03-20 13:21  jesse
-
-       * lib/RT/Action/: Notify.pm, SendEmail.pm:
-
-       Fixed a couple bugs in Notify and SendEmail that should get mail flowing
-       for transactions without content.
-       
-2001-03-20 13:08  jesse
-
-       * webrt/Ticket/: Attachment/dhandler, Elements/ShowTransaction:
-
-       Making web based attachment display deal nicely with too-long message bodies
-       
-2001-03-20 04:26  jesse
-
-       * Makefile:
-
-       bumping the version
-       
-2001-03-20 04:20  jesse
-
-       * lib/RT/Action/SendEmail.pm:
-
-       regexps with three /s need a leading s ;)
-       
-2001-03-20 04:16  jesse
-
-       * bin/rt-mailgate, lib/RT/Template.pm:
-
-       fixing scrips-related mailing stuff. some transaction mailing used to bomb out.
-       
-2001-03-20 02:46  jesse
-
-       * Makefile, bin/rt-mailgate, etc/config.pm,
-       lib/RT/Action/SendEmail.pm, tools/insertdata:
-
-       Work on robustification of the mail gateway. including single-transaction
-       blacklisting of addresses that might generate bounces.
-       
-2001-03-20 00:41  jesse
-
-       * lib/RT/User.pm:
-
-       Work on user.pm to allow users to be disabled.
-       
-2001-03-19 18:03  jesse
-
-       * webrt/: autohandler, Elements/MyRequests, NoAuth/Login.html,
-       NoAuth/Reminder.html:
-
-       fixed the MyRequests bug that caused them not to be listed.
-       nonexistent users no longer get shunted to SelfService.
-       
-2001-03-19 15:30  jesse
-
-       * Makefile, bin/mason_handler.fcgi, bin/mason_handler.scgi, bin/rt,
-       bin/rt-mailgate, bin/rtadmin, webrt/Admin/Elements/ModifyTemplate,
-       webrt/Admin/Elements/ModifyUser, webrt/Admin/Global/Template.html,
-       webrt/Admin/Queues/Template.html, webrt/Admin/Users/Modify.html,
-       webrt/Elements/MessageBox:
-
-       Fixes for perl path and textarea bugs noted by Arthur de Jong
-       
-2001-03-18 14:58  jesse
-
-       * lib/RT/Attachment.pm:
-
-       Removed an extra signature attachment
-       
-2001-03-17 14:57  jesse
-
-       * Makefile:
-
-       bumped version
-       
-2001-03-17 14:55  jesse
-
-       * lib/Makefile.PL, lib/RT/Tickets.pm, lib/RT/Interface/Web.pm,
-       webrt/Elements/Quicksearch, webrt/Elements/SelectDate,
-       webrt/Elements/SelectDateType, webrt/Elements/TitleBoxEnd,
-       webrt/Search/PickRestriction:
-
-       Fixed a bug on simple actions reported by christian.
-       Implemented search by date via web ui
-       
-2001-03-16 03:55  jesse
-
-       * Makefile, lib/RT/Interface/Web.pm, webrt/Elements/Header:
-
-       Fixed a tiny typo that prevented objectkeyword editing
-       
-2001-03-16 02:29  jesse
-
-       * Makefile:
-
-       Bumped the version.
-       
-2001-03-16 02:27  jesse
-
-       * Makefile, README, bin/initacls.Oracle, bin/initacls.Pg,
-       bin/initacls.mysql, bin/initdb.Oracle, tools/initdb:
-
-       some clarifications to the install procedure.
-       
-2001-03-16 02:10  jesse
-
-       * lib/RT/Tickets.pm, webrt/Search/Listing.html:
-
-       Fixed #2 WebRT doesn't refresh searches properly. the oldest bug in the bug tracking
-       system ;)
-       
-       Fixed Tickets->Count
-       
-2001-03-16 01:39  jesse
-
-       * webrt/Admin/: Global/Template.html, Global/Templates.html,
-       Queues/Modify.html, Queues/Template.html, Queues/Templates.html:
-
-       now you can create templates with the web ui.
-       
-2001-03-16 00:39  jesse
-
-       * webrt/Ticket/Elements/EditLinks:
-
-       file EditLinks was initially added on branch rt-1-1.
-       
-2001-03-16 00:39  jesse
-
-       * webrt/Ticket/ModifyAll.html:
-
-       file ModifyAll.html was initially added on branch rt-1-1.
-       
-2001-03-16 00:39  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/Interface/Web.pm, webrt/Elements/Tabs,
-       webrt/Ticket/Modify.html, webrt/Ticket/ModifyAll.html,
-       webrt/Ticket/ModifyDates.html, webrt/Ticket/ModifyLinks.html,
-       webrt/Ticket/ModifyPeople.html, webrt/Ticket/ValidateUpdate.html,
-       webrt/Ticket/Elements/EditKeywordSelects,
-       webrt/Ticket/Elements/EditLinks, webrt/Ticket/Elements/EditPeople,
-       webrt/Ticket/Elements/Tabs:
-
-       A bunch of Ticket modification refactoring and cleanup.
-       Added a "ModifyAll" at sam hartman's suggestion
-       
-2001-03-14 21:20  jesse
-
-       * bin/rt:
-
-       --id=43-45 should now work. there was a regex typo
-       
-2001-03-14 04:37  jesse
-
-       * Makefile, bin/initacls.Oracle, etc/acl.Oracle, etc/acl.mysql,
-       etc/schema.Oracle, etc/user.Oracle, tools/initdb, tools/testdeps:
-
-       reworked init procedures, oracle schema and
-       acl setup for mysql and postgres and oracle.
-       
-       RT2 now runs on oracle.
-       
-2001-03-14 02:08  jesse
-
-       * etc/acl.Oracle, etc/schema.Oracle, tools/initdb:
-
-       hacking to make oracle work. we're much of the way there. next up:
-       schema updates
-       
-2001-03-14 02:08  jesse
-
-       * etc/acl.Oracle:
-
-       file acl.Oracle was initially added on branch rt-1-1.
-       
-2001-03-14 01:03  jesse
-
-       * webrt/Admin/Queues/GroupRights.html:
-
-       file GroupRights.html was initially added on branch rt-1-1.
-       
-2001-03-14 01:03  jesse
-
-       * webrt/Admin/Queues/UserRights.html:
-
-       file UserRights.html was initially added on branch rt-1-1.
-       
-2001-03-14 01:03  jesse
-
-       * Makefile, lib/RT/ACE.pm, lib/RT/Interface/Web.pm, tools/initdb,
-       webrt/Admin/Elements/QueueTabs,
-       webrt/Admin/Global/GroupRights.html, webrt/Admin/Queues/ACL.html,
-       webrt/Admin/Queues/GroupRights.html,
-       webrt/Admin/Queues/UserRights.html, webrt/Elements/Tabs,
-       webrt/NoAuth/webrt.css:
-
-       Cleanup to the ACL editors (consistency)
-       a bit of web ui tuning.
-       
-       fixes for initdb issues (thanks, jhutz)
-       
-       minor cleanups to ACE.pm
-       
-2001-03-13 22:44  jesse
-
-       * lib/RT/Transaction.pm, lib/RT/Transactions.pm, tools/testdeps:
-
-       Updated DBIx::SearchBuilder dependency
-       
-       code cleanup and sketching in Transaction.pm and Transactions.pm
-       
-2001-03-12 21:14  jesse
-
-       * Makefile, etc/schema.Pg, etc/schema.mysql, tools/initdb,
-       tools/testdeps:
-
-       initdb now caches schema, eliminating the install-time dependency on DBIx::DBSchema.
-       
-       this is 1.3.50, folks. it has what I believe to be functional postgres support
-       
-2001-03-11 21:58  jesse
-
-       * etc/config.pm, etc/schema.pm, lib/RT/Attachment.pm,
-       lib/RT/Ticket.pm, tools/initdb:
-
-       Cleanup in Ticket.pm
-       Bugfixes to Attachment.pm (for postgres mimencoding supporT)
-       
-       reconfigured to use the new DBIx::DBSchema (which isn't out yet. but should
-       be soon)
-       
-       still need to do a bit more work on attachments configuration.
-       
-2001-03-11 02:45  jesse
-
-       * bin/rt-mailgate:
-
-       file rt-mailgate was initially added on branch rt-1-1.
-       
-2001-03-11 02:45  jesse
-
-       * Makefile, README, bin/rt-mailgate, bin/rtmux.pl, bin/webmux.pl,
-       etc/config.pm, etc/schema.Oracle, etc/schema.pm, lib/RT.pm,
-       lib/RT/Attachment.pm, lib/RT/ScripAction.pm, lib/RT/Ticket.pm,
-       lib/RT/Action/SendEmail.pm, lib/RT/Interface/CLI.pm,
-       lib/RT/Interface/Email.pm, tools/insertdata:
-
-       This is a bit more of a 'comprehensive' diff than I'd intended. That's what
-       I get for working for 1/2 a week at my parents place without real net ;)
-       
-       Cleanups in the makefile and readme to make installation simpler and more
-       sensical.
-       
-       removed outdated rtmux.pl
-       moved old Interface/Email.pm to bin/rt-mailgate
-       started new baseclass for new mail gateways (Interface/Email.pm)
-       
-       first cut implementation of attachment size limits.
-       
-       switched mysql to use 'longblob' rather than just 'blob', so
-       that users can submit > 64k attachments.  with the next release
-       of DBIx::DBSchema, we should have what we need to get
-       PG attachmetns of more reasonable sizes working.
-       
-       first cut implementation of base64 encoding for MIME objects
-       on databases that don't support BLOBs (postgres)
-       
-       restructured initdb so we'll be able to support databases
-       for which we need to hand-hack schema.
-       
-       added the 'Owner' pseudogroup to insertdata
-       
-       fixed the bug in logging for the mail gateway that caused
-       lots of warnings about joins.
-       
-       lots of work on the mail gateway to start to clean up and restructure
-       things.
-       
-2001-03-10 18:53  jesse
-
-       * tools/initdb:
-
-       Refactoring initdb to make it easier to do things like add oracle support. yay
-       
-2001-03-09 15:19  jesse
-
-       * lib/RT/Condition/StatusChange.pm:
-
-       file StatusChange.pm was initially added on branch rt-1-1.
-       
-2001-03-09 15:19  jesse
-
-       * Makefile, etc/config.pm, lib/RT/Attachment.pm, lib/RT/Link.pm,
-       lib/RT/Ticket.pm, lib/RT/Transaction.pm, lib/RT/Watcher.pm,
-       lib/RT/Action/SendEmail.pm, lib/RT/Condition/AnyTransaction.pm,
-       lib/RT/Condition/Generic.pm, lib/RT/Condition/StatusChange.pm,
-       tools/insertdata, tools/testdeps:
-
-       OnResolve scrip now works.
-       some cleanup on Scrips and Watchers.
-       commented out some debug messages that aren't immediately useful
-       
-2001-03-09 15:15  jesse
-
-       * webrt/Ticket/: ModifyDates.html, Elements/EditWatchers:
-
-       Two bugfixes:
-               one, editdates no longer errors out on 5.005
-               two, links from watchers to the ModifyUser page now work properly
-       
-2001-03-08 15:21  jesse
-
-       * Makefile, lib/RT/User.pm, tools/insertdata:
-
-       
-       Fixed a bootstrapping bug introduced with the new acls on Create.
-       bumped version to 1.3.49_01
-       
-2001-03-07 00:40  jesse
-
-       * lib/: test.pl, RT/ACE.pm, RT/CurrentUser.pm, RT/Group.pm,
-       RT/GroupMember.pm, RT/Keyword.pm, RT/KeywordSelect.pm, RT/Link.pm,
-       RT/Queue.pm, RT/Scrip.pm, RT/ScripAction.pm, RT/Template.pm,
-       RT/Ticket.pm, RT/Transaction.pm, RT/User.pm, RT/Watcher.pm:
-
-       acls for Delete methods that needed them.
-       flat lockouts on Delete methods that needed them.
-       
-       test.pl got 'use *' added to it
-       
-2001-03-06 18:07  jesse
-
-       * lib/RT/Attachment.pm:
-
-       Backing out changes that broke ->Content
-       
-2001-03-06 17:42  jesse
-
-       * Makefile, lib/RT/Attachment.pm, lib/RT/Record.pm,
-       lib/RT/Interface/Web.pm, webrt/Elements/SelectSortOrder,
-       webrt/Search/Listing.html, webrt/Search/PickRestriction:
-
-       work on Attachments.
-       cleanup on sorting and limiting.
-       
-2001-03-06 16:26  jesse
-
-       * webrt/Search/PickRestriction:
-
-       adding a header
-       
-2001-03-04 19:46  jesse
-
-       * etc/schema.pm:
-
-       Schema change to support postgres
-       
-2001-03-04 19:44  jesse
-
-       * lib/RT/Record.pm:
-
-       Small change for new DBIx::SearchBuilder::Record PrimaryKey behaviors..
-       
-2001-03-04 19:15  jesse
-
-       * bin/rt:
-
-       rt --id=<int> should work now
-       
-2001-03-02 00:26  jesse
-
-       * etc/config.pm, lib/RT/Date.pm, lib/RT/Ticket.pm,
-       webrt/Ticket/ModifyDates.html:
-
-       first pass on dates and timezones...seems to work. for common ops
-       
-2001-02-28 16:34  jesse
-
-       * lib/RT/User.pm:
-
-       fix for RT/fsck.com: Ticket #208 User->Create needs more argument checking
-               added a check to User->Create to make sure a name was specified
-       
-2001-02-28 08:56  jesse
-
-       * Makefile, bin/rtadmin:
-
-       Enabled the ability to set a user's password via the CLI
-       
-2001-02-27 22:09  jesse
-
-       * lib/Makefile.PL, tools/testdeps:
-
-       Bumping required version of searchbuilder in testdeps and lib/Makefile.pl
-       
-2001-02-27 22:00  jesse
-
-       * webrt/Elements/SelectKeyword:
-
-       allowing undef keywords
-       
-2001-02-27 21:43  jesse
-
-       * webrt/Admin/Queues/Scrips.html:
-
-       Fix for ticket #50. grammar in per queue scrip descriptions
-       
-2001-02-27 21:41  jesse
-
-       * tools/insertdata:
-
-       resolving ticket #181- extra \s in the autoreply template
-       
-2001-02-27 21:36  jesse
-
-       * Makefile, lib/RT/Transaction.pm, tools/testdeps:
-
-       testdeps now erorrs out if you don't specify a db type.
-       
-       queue change transaction descriptions are better.
-       
-       bumped the version
-       
-2001-02-27 21:12  jesse
-
-       * webrt/Elements/SelectTicketSortBy:
-
-       file SelectTicketSortBy was initially added on branch rt-1-1.
-       
-2001-02-27 21:12  jesse
-
-       * webrt/Elements/SelectSortOrder:
-
-       file SelectSortOrder was initially added on branch rt-1-1.
-       
-2001-02-27 21:12  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/Tickets.pm, lib/RT/Interface/Web.pm,
-       webrt/Elements/SelectKeyword, webrt/Elements/SelectResultsPerPage,
-       webrt/Elements/SelectSortOrder, webrt/Elements/SelectTicketSortBy,
-       webrt/Search/Listing.html, webrt/Search/PickRestriction:
-
-       Basic ticket sorting has been implemented.
-       Ticket listing by pages works too.
-       
-       a bit of cleanup in the ticket listing.  now select by keywords uses the component designed for that purpose
-       
-2001-02-26 15:44  jesse
-
-       * lib/RT/Ticket.pm:
-
-       No longer generate spurious watchers transactions when merging tickets.
-       
-2001-02-26 03:08  jesse
-
-       * lib/RT/Ticket.pm:
-
-       fixed a typo in a debug message that prevented compilation
-       
-2001-02-26 02:53  jesse
-
-       * Makefile:
-
-       bumped the version for release. again.
-       
-2001-02-26 02:52  jesse
-
-       * lib/RT/: ACE.pm, Ticket.pm:
-
-       Fixed a variable redef in ticket and an acl granting bug in ACE
-       
-2001-02-26 01:24  jesse
-
-       * Makefile, webrt/Ticket/ModifyLinks.html:
-
-       A bit more merging support.
-       Bumped version for release
-       
-2001-02-25 22:28  jesse
-
-       * webrt/Ticket/Elements/: ShowHistory, ShowTransaction:
-
-       Cleaning up the transaction display.
-       
-2001-02-25 22:22  jesse
-
-       * lib/RT/: Scrip.pm, ScripCondition.pm, Ticket.pm:
-
-       Some bug fixes for merging.
-       Fixed a bug in Scrips that caused an infinite loop if the user had no rights.
-       
-2001-02-24 02:42  jesse
-
-       * Makefile, lib/RT/Ticket.pm:
-
-       Fixed a bug that prevented ticket loading from appearing to work
-       
-2001-02-23 19:17  jesse
-
-       * Makefile, lib/RT/Ticket.pm, lib/RT/Interface/Web.pm:
-
-       Fixed a typo in Ticket.pm that prevented transaction lists from working
-       fixed a paste error in Web.pm
-       
-2001-02-23 17:41  jesse
-
-       * Makefile:
-
-       Bumped the version # for release
-       
-2001-02-23 17:31  jesse
-
-       * Makefile, README, bin/initacls.mysql, bin/webmux.pl,
-       lib/RT/ACE.pm, lib/RT/ACL.pm, lib/RT/Link.pm, lib/RT/Queue.pm,
-       lib/RT/Ticket.pm, lib/RT/User.pm, lib/RT/Interface/Web.pm,
-       tools/initdb, tools/testdeps:
-
-       Fixed a bug that made a first install with mysql fail
-       yanked a UNIVERSAL::AUTOLOADER handler I inserted to test things out.
-       Fixed several ACL creation bugs.
-       Initial implementation of merge for the core.
-       Testdeps now does database testing.
-       
-       Made Ticket->Load smarter. (nolonger needs a seperate LoadByURI sub.
-       
-       fixed bugs in the readme
-       
-2001-02-22 01:03  jesse
-
-       * tools/testdeps:
-
-       Updated dependencies.
-       
-2001-02-21 17:49  jesse
-
-       * lib/RT/: Ticket.pm, Tickets.pm:
-
-       Cache Queue in Ticket.pm for added perf.
-       formatting cleanup in Tickets.pm
-       
-2001-02-20 14:38  jesse
-
-       * webrt/Ticket/Display.html:
-
-       Uncompressed history on summary page...
-       
-2001-02-20 14:18  jesse
-
-       * lib/RT/ScripCondition.pm:
-
-       fixed a pod typo
-       
-2001-02-20 14:07  jesse
-
-       * Makefile, etc/schema.pm, lib/MANIFEST, tools/insertdata,
-       webrt/Admin/Users/Modify.html,
-       webrt/SelfService/Elements/ShowTransaction,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       removed a false unique index from schema. pm.
-       make web interface and insertdata deal properly with the fact that email addresses
-       should be unique.
-       
-       cleaned up ShowTransaction for the webui. (now uses CreatorObj rather than Creator,
-       as it was confusing
-       
-2001-02-20 01:42  jesse
-
-       * lib/RT/: ACE.pm, ACL.pm, Attachment.pm, Attachments.pm,
-       CurrentUser.pm, EasySearch.pm, Group.pm, GroupMember.pm,
-       GroupMembers.pm, Groups.pm, Keyword.pm, KeywordSelect.pm,
-       Keywords.pm, Link.pm, Links.pm, ObjectKeyword.pm,
-       ObjectKeywords.pm, Queue.pm, Queues.pm, Record.pm, Scrip.pm,
-       ScripAction.pm, ScripActions.pm, ScripCondition.pm,
-       ScripConditions.pm, Scrips.pm, Template.pm, Templates.pm,
-       Ticket.pm, Tickets.pm, Transaction.pm, Transactions.pm, User.pm,
-       Users.pm, Utils.pm, Watcher.pm, Watchers.pm, Action/SendEmail.pm:
-
-       A major security audit of the codebase has taken place.  I was primarily out for
-       ACL related issues, but took care of a number of other minor cleanups at the same time.
-       
-2001-02-19 17:16  jesse
-
-       * NEWS:
-
-       fixed a typo in cli_respond_req
-       
-2001-02-15 18:02  jesse
-
-       * webrt/SelfService/: Details.html, Error.html:
-
-       fixing bug #90: SelfService calls to Abort use the 'standard' handler. which includes the wrong header.
-       
-2001-02-15 18:02  jesse
-
-       * webrt/SelfService/Error.html:
-
-       file Error.html was initially added on branch rt-1-1.
-       
-2001-02-15 17:39  jesse
-
-       * webrt/Admin/Elements/SelectSingleOrMultiple:
-
-       file SelectSingleOrMultiple was initially added on branch rt-1-1.
-       
-2001-02-15 17:39  jesse
-
-       * lib/RT/Keyword.pm, lib/RT/KeywordSelect.pm,
-       webrt/Admin/Elements/SelectKeywordSelect,
-       webrt/Admin/Elements/SelectSingleOrMultiple,
-       webrt/Admin/Global/Keywords.html, webrt/Admin/Queues/Keywords.html,
-       webrt/Elements/SelectKeyword, webrt/Elements/SelectKeywordOptions,
-       webrt/Ticket/Elements/ModifyTicket:
-
-       KeywordSelect.pm got an ACL bug fixed.
-       Keyword.pm now does recursive searches in Descendants properly.
-       
-       KeyworSelect editing via the webui is now much smarter. and cleaner. and better. and faster, and resolving bug 123
-       
-2001-02-15 17:39  jesse
-
-       * webrt/Admin/Elements/SelectKeywordSelect:
-
-       file SelectKeywordSelect was initially added on branch rt-1-1.
-       
-2001-02-13 22:54  jesse
-
-       * lib/: Makefile.PL, RT/ACE.pm, RT/Keyword.pm, RT/KeywordSelect.pm,
-       RT/Scrip.pm:
-
-       Better ACL handling for ACEs, Keywords and KeywordSelects.
-       specified more accurate versions of some dependencies in lib/Makefile.PL
-       
-2001-02-13 12:51  jesse
-
-       * bin/rtadmin, etc/schema.pm, lib/RT/Keyword.pm,
-       lib/RT/KeywordSelect.pm, lib/RT/KeywordSelects.pm,
-       lib/RT/Keywords.pm, lib/RT/Queue.pm, lib/RT/Queues.pm,
-       lib/RT/User.pm, lib/RT/Users.pm, webrt/Admin/Global/Keywords.html,
-       webrt/Admin/Keywords/index.html, webrt/Admin/Queues/Keywords.html,
-       webrt/Admin/Queues/Modify.html, webrt/Admin/Users/Modify.html:
-
-       Implemented 'Disabled' for Keywords, KeywordSelects, Queues and Users.
-       This supplants 'Delete' for these objects which need to exist to guarantee
-       referential integrity.
-       
-       Implemented cli and web interfaces to support the new code.
-       
-2001-02-12 18:27  jesse
-
-       * README, bin/rtadmin, etc/schema.pm, lib/RT/Attachment.pm,
-       lib/RT/EasySearch.pm, lib/RT/Link.pm, lib/RT/ObjectKeyword.pm,
-       lib/RT/Queue.pm, lib/RT/Queues.pm, lib/RT/Record.pm,
-       lib/RT/ScripAction.pm, lib/RT/ScripCondition.pm,
-       lib/RT/Template.pm, lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       lib/RT/Watcher.pm, tools/testdeps:
-
-       Cleaned up LastUpdated / Created/ LastUpdatedBy / Creator to all get set on
-       create for all relevant objects.
-       
-       Based on discussions with ivan, changed the 'Deleted' flag on various objects to 'Disabled'
-       to better represent its purpose.
-       
-       Fully implemented Disable for queue as a prototype.
-       
-       fixed queue attribute editing in cli.
-       
-2001-02-12 13:59  jesse
-
-       * tools/testdeps:
-
-       specified a minimum known good version of Getopt::Long
-       
-2001-02-12 12:38  jesse
-
-       * lib/RT/Queue.pm, webrt/Ticket/Elements/ShowTransaction:
-
-       transaction links work again.
-       admin ccs get listed.
-       
-2001-02-11 22:16  jesse
-
-       * Makefile:
-
-       bumped the version # for a new release
-       
-2001-02-11 22:13  jesse
-
-       * lib/RT/Queue.pm, lib/RT/Template.pm, tools/insertdata:
-
-       cleaning up queue create.
-       
-2001-02-11 22:12  jesse
-
-       * etc/schema.pm:
-
-       started the work on dealing with Deleting records that need to exist to guarantee ref. integrity
-       
-2001-02-11 18:40  jesse
-
-       * NEWS:
-
-       imported brandon's url importing code
-       
-2001-02-06 22:59  jesse
-
-       * lib/RT/Queue.pm, webrt/Admin/Queues/Modify.html,
-       webrt/Admin/Users/index.html:
-
-       Fixes to Queue.pm to stop it from clobbering the Name.
-       
-       fixed a typo in the webui Admin/Users/index.html
-       
-2001-02-06 15:22  jesse
-
-       * lib/RT/Queue.pm, webrt/Admin/Elements/QueueRightsForUser,
-       webrt/Admin/Elements/SelectRights,
-       webrt/Ticket/Elements/ShowMembers:
-
-       ACL fixes in Queue.pm.
-       ACL search fies for the web ui.
-       fixed a recursive subticket display bug.
-       
-2001-02-06 12:49  jesse
-
-       * Makefile:
-
-       removed the old rt 1.0 lib/rt directory forever. yay
-       
-2001-02-06 12:48  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       Added a tiny patch from ivan to not extract nested messages. not totally sure about this one yet.
-       
-2001-02-02 01:26  jesse
-
-       * Makefile:
-
-       version bumpin
-       
-2001-02-02 01:11  jesse
-
-       * bin/rtadmin, lib/RT/Keyword.pm:
-
-       keyword creation, editing and deletion now works via the cli tool.
-       
-       This means that for alpha 4, we're *gasp* feature complete.  now to fix lots of bugs.
-       
-2001-02-01 02:46  jesse
-
-       * bin/rtadmin, lib/RT/Group.pm, lib/RT/Keyword.pm,
-       lib/RT/KeywordSelect.pm, tools/testdeps, webrt/Ticket/Display.html,
-       webrt/Ticket/Elements/ShowHistory,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       Commandline editing of keywordselects now works.
-       
-       Added in a patch to collapse history on the ticket listing
-       page from Byron Ellacott
-       
-       Bumped a few dependecy versions. added a File::Spec dependency, since File::Temp
-       gets it not quote right.
-       
-2001-01-31 02:08  jesse
-
-       * bin/rtadmin, lib/RT/Group.pm, webrt/Admin/Groups/Members.html:
-
-       Commandline group editing now works. yay. group membership even.
-       the api changed to be easier to work with and more consistent with other functions
-       
-2001-01-30 23:12  jesse
-
-       * lib/RT/Interface/Email.pm, webrt/Ticket/Elements/ShowLinks,
-       webrt/Ticket/Elements/ShowRequestor:
-
-       The email interface now uses tempdir from File::Temp for increased security.
-       
-       A couple of webui cleanups to display more sensible things.
-       
-2001-01-30 16:42  jesse
-
-       * etc/config.pm, lib/RT/User.pm, lib/RT/Interface/Email.pm:
-
-       Added mail-on-error to the mail gateway. now it should tell you when it fails.
-       
-       turned off debugging output from ACLs....
-       
-2001-01-29 23:58  jesse
-
-       * bin/rtadmin, lib/RT/ACE.pm, lib/RT/ACL.pm, lib/RT/Scrip.pm,
-       lib/RT/ScripAction.pm, lib/RT/ScripCondition.pm, lib/RT/Scrips.pm,
-       lib/RT/Template.pm, lib/RT/Templates.pm, lib/RT/User.pm,
-       lib/RT/Interface/CLI.pm, lib/RT/Interface/Web.pm,
-       webrt/Admin/Elements/SelectTemplate,
-       webrt/Admin/Global/Template.html,
-       webrt/Admin/Global/Templates.html,
-       webrt/Admin/Queues/Template.html:
-
-       A bunch of work on the admin cli (acl editor now works)
-       
-       a couple API changes to standardize method names across classes
-       template editing via the web should work better now.
-       
-2001-01-29 23:56  jesse
-
-       * webrt/Elements/: TitleBoxEnd, TitleBoxStart:
-
-       Futzing with the title box to make it a bit more consistent
-       
-2001-01-29 23:54  jesse
-
-       * lib/RT/Record.pm:
-
-       Removed a redundant sub new
-       
-2001-01-29 22:22  jesse
-
-       * lib/RT/Group.pm:
-
-       Groups can now be loaded by name.
-       
-2001-01-23 15:46  jesse
-
-       * bin/rtadmin, etc/schema.pm, lib/RT/Queue.pm, lib/RT/Template.pm,
-       lib/RT/Ticket.pm, lib/RT/User.pm, lib/RT/Interface/CLI.pm,
-       tools/initdb:
-
-       initdb now punts on database creation for oracle.
-       
-       Ticket->Name removed from code (retargeted to post 2.0 and its own table)
-       Some better error checking in User and Queue.
-       
-       Can now edit templates (And create them) from the CLI.
-       
-2001-01-22 12:51  jesse
-
-       * lib/RT/Action/Notify.pm:
-
-       
-       It's amazing how much effect 3 little letters can have. with this patch,
-       scrips that depend on notify (most everything other than autoreply)
-       just work. woo!
-       
-2001-01-22 06:18  jesse
-
-       * lib/RT/Template.pm:
-
-       Fixed a couple ACL bugs in Template::_Set
-       
-2001-01-22 05:04  jesse
-
-       * Makefile:
-
-       Bumped the version # because of the schema change
-       
-2001-01-22 04:51  jesse
-
-       * lib/RT/Interface/CLI.pm:
-
-       file CLI.pm was initially added on branch rt-1-1.
-       
-2001-01-22 04:51  jesse
-
-       * lib/RT/Interface/CLI.pm:
-
-       Added CLI.pm, which rt and adminrt are dependant on
-       
-2001-01-22 04:46  jesse
-
-       * bin/rtadmin, lib/MANIFEST, lib/RT/Template.pm:
-
-       a bit more work on rtadmin (the start of template editing)
-       
-       added Interface/CLI to the manifest.
-       added a comment to Template.pm
-       
-2001-01-22 02:51  jesse
-
-       * Makefile, TODO, bin/mason_handler.scgi, bin/rt, bin/rtadmin,
-       bin/rtmux.pl, bin/webmux.pl, etc/config.pm, etc/schema.Oracle,
-       etc/schema.pm, lib/RT.pm, lib/RT/Attachment.pm,
-       lib/RT/CurrentUser.pm, lib/RT/Group.pm, lib/RT/Link.pm,
-       lib/RT/ObjectKeywords.pm, lib/RT/Queue.pm, lib/RT/Template.pm,
-       lib/RT/Ticket.pm, lib/RT/Tickets.pm, lib/RT/Transaction.pm,
-       lib/RT/User.pm, lib/RT/Users.pm, lib/RT/Watchers.pm,
-       lib/RT/Interface/Email.pm, tools/insertdata,
-       webrt/Admin/Elements/CreateQueueCalled,
-       webrt/Admin/Elements/CreateUserCalled,
-       webrt/Admin/Elements/GrantQueueRightsTo,
-       webrt/Admin/Elements/ModifyKeywordSelect,
-       webrt/Admin/Elements/ModifyQueue,
-       webrt/Admin/Elements/ModifyTemplate,
-       webrt/Admin/Elements/ModifyUser,
-       webrt/Admin/Elements/SelectModifyQueue,
-       webrt/Admin/Elements/SelectModifyUser,
-       webrt/Admin/Elements/SelectTemplate,
-       webrt/Admin/Elements/SelectUsers, webrt/Admin/Global/Scrips.html,
-       webrt/Admin/Global/Template.html,
-       webrt/Admin/Global/Templates.html,
-       webrt/Admin/Global/UserRights.html,
-       webrt/Admin/Groups/Members.html,
-       webrt/Admin/KeywordSelects/index.html, webrt/Admin/Queues/ACL.html,
-       webrt/Admin/Queues/Create.html, webrt/Admin/Queues/Keywords.html,
-       webrt/Admin/Queues/Modify.html, webrt/Admin/Queues/People.html,
-       webrt/Admin/Queues/Scrips.html, webrt/Admin/Queues/Template.html,
-       webrt/Admin/Queues/Templates.html, webrt/Admin/Queues/index.html,
-       webrt/Admin/Users/Modify.html, webrt/Admin/Users/Prefs.html,
-       webrt/Admin/Users/index.html, webrt/Elements/Header,
-       webrt/Elements/MyRequests, webrt/Elements/MyTickets,
-       webrt/Elements/Quicksearch, webrt/Elements/SelectNewTicketQueue,
-       webrt/Elements/SelectOwner, webrt/Elements/SelectQueue,
-       webrt/Elements/SelectUsers, webrt/SelfService/Details.html,
-       webrt/SelfService/Elements/Header,
-       webrt/SelfService/Elements/MyRequests,
-       webrt/SelfService/Elements/ShowTransaction,
-       webrt/Ticket/Create.html, webrt/Ticket/ModifyLinks.html,
-       webrt/Ticket/autohandler, webrt/Ticket/Elements/AddWatchers,
-       webrt/Ticket/Elements/ShowBasics, webrt/Ticket/Elements/ShowDates,
-       webrt/Ticket/Elements/ShowDependencies,
-       webrt/Ticket/Elements/ShowLinks, webrt/Ticket/Elements/ShowPeople,
-       webrt/Ticket/Elements/ShowReferences,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       In prep for a true schema freeze, I fixed a number of attribute names that were troublesome for
-       one reason or another.
-       
-               Queue->QueueId and User->UserId have been changed to Queue->Name and User->Name, so
-               as not to conflict with queue->id and user->id any more.  A number of tables
-               used "Alias" and "Title" and things like that, rather than the somewhat
-               more standard "Name" and "Description"
-       
-       Abstracted a bunch of the CLI setup stuff out into lib/RT/Interface/CLI
-       
-       Abstracted some of the core DB startup code into RT.pm
-       
-       fixed the makefile to handle the new rtadmin.
-       
-       lots of updates to the new rtadmin (which works for user editing!)
-       
-       fixed a bug in ObjectKeywords->LoadByName....
-       
-2001-01-19 04:23  jesse
-
-       * bin/rtadmin:
-
-       A bit of cleanup and a bit more docs.  it's now actually implementable with getopt::long
-       
-2001-01-19 04:16  jesse
-
-       * bin/rtadmin:
-
-       file rtadmin was initially added on branch rt-1-1.
-       
-2001-01-19 04:16  jesse
-
-       * bin/rtadmin:
-
-       Docced the proposed cli for the new rtadmin tool. It's rather more intense than I'd intended
-       
-2001-01-19 02:15  jesse
-
-       * lib/RT/User.pm:
-
-       Fixed ACL bug that prevented by-group auth from working
-       
-2001-01-19 00:52  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/User.pm, webrt/SelfService/Details.html:
-
-       Work on SelfService (fixing the a permission denied bug)
-       
-2001-01-19 00:21  jesse
-
-       * webrt/NoAuth/webrt.css:
-
-       file webrt.css was initially added on branch rt-1-1.
-       
-2001-01-19 00:21  jesse
-
-       * webrt/: webrt.css, Elements/Header, NoAuth/webrt.css,
-       SelfService/Details.html, SelfService/Elements/Header:
-
-       webui cleanups
-       
-2001-01-19 00:07  jesse
-
-       * bin/rt:
-
-       bug-fixing in bin/rt
-       
-2001-01-18 23:47  jesse
-
-       * lib/RT/Link.pm, lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       webrt/Ticket/ModifyLinks.html, webrt/Ticket/Elements/ShowLinks,
-       webrt/Ticket/Elements/ShowMembers,
-       webrt/Ticket/Elements/ShowReferences,
-       webrt/Ticket/Elements/ShowSummary:
-
-       A bunch of work on links.
-       API cleanups.
-       Ticket-> Members and MemberOf  now return Links objects rather than Tickets Objects
-       Edit links via the webui works now
-       
-2001-01-18 15:11  jesse
-
-       * HACKING, docs/API:
-
-       Added a bit more documentation and philosophy
-       to the API file. yanked tobix' old out of date "HACKING"
-       doc
-       
-2001-01-18 03:18  jesse
-
-       * Makefile, NEWS:
-
-       Headers in incoming mail are now parsed case insensitively.
-       
-       Version is now 1.0.7
-       
-2001-01-17 16:41  jesse
-
-       * Makefile, tools/testdeps:
-
-       updated searchbuilder dependency in testdeps
-       
-       revved version in Makefile for release.
-       
-2001-01-17 14:27  jesse
-
-       * Makefile, bin/rt, lib/RT/Date.pm:
-
-       Fixed #45 Permissions bug on redhat 6.0
-       Fixed #51 RT CLI doesn't check for valid user
-       
-       Implemented a bunch more searching in bin/rt
-       
-       Refactored RT::Date a bit.
-       
-       Fixed some unreported permissions eits.
-       
-2001-01-16 11:43  jesse
-
-       * webrt/Ticket/Elements/: ShowLinks, ShowMemberOf, ShowMembers,
-       ShowPeople, ShowSummary:
-
-       Cleaned up and shortened the Ticket Display screen
-       
-2001-01-16 10:56  jesse
-
-       * lib/RT/Ticket.pm, webrt/Ticket/Modify.html:
-
-       Cleaned up and better documented Ticket->SetStatus
-       Ticket/Modify.html got rid of a whole bunch of evals.
-       
-2001-01-15 23:57  jesse
-
-       * Makefile, lib/MANIFEST, lib/RT/Tickets.pm:
-
-       Removed a deleted file from the manifest. revved the version
-       
-2001-01-15 15:19  jesse
-
-       * lib/RT/: KeywordSelect.pm, Queue.pm:
-
-       Adding the ability to load keyword selects by name.
-       
-2001-01-15 03:49  jesse
-
-       * lib/RT/Ticket.pm, webrt/Ticket/Elements/EditKeywordSelects:
-
-       keyword display now cleaner. doesn't force you to select a keyword if none
-       is selected yet.
-       
-2001-01-15 03:36  jesse
-
-       * lib/RT/Ticket.pm:
-
-       SetQueue is no-longer heinously broken. thanks eoin
-       
-2001-01-15 03:10  jesse
-
-       * lib/RT/: Queue.pm, User.pm, Action/Notify.pm, Action/Spam.pm:
-
-       removed an old RT::Action that didn't actually do anything useful these days.  it'll get replaced later.
-       
-       Scrips which sign watchers up for things _actually seem to work_
-       (required some frobbing of watchers)
-       
-2001-01-15 02:44  jesse
-
-       * bin/rt, etc/schema.pm, lib/RT/ObjectKeywords.pm, lib/RT/Queue.pm,
-       lib/RT/Template.pm, lib/RT/Ticket.pm, lib/RT/Tickets.pm,
-       lib/RT/Watchers.pm, webrt/Elements/ViewUser,
-       webrt/Ticket/Elements/ShowRequestor:
-
-       Added a 'Type' column to templates, to more easily allow for insertable templates for quick responses from customer service folks ,etc.
-       Reworked a bunch of the watchers code to not do its own potentially very bogus caching and to reuse more core code.
-       Oh. and it always returns the expected object type now.
-       
-       Redid tobias' old "ViewUser" box to use a set of tickets, rather than a bogus search for watchers (ignoring tickets).
-       
-       Fixed a bug in searching for tickets by watcher.
-       
-2001-01-15 00:53  jesse
-
-       * bin/rt, webrt/Elements/SelectOwner, webrt/Elements/TitleBoxStart,
-       webrt/NoAuth/Login.html, webrt/Ticket/Elements/ShowSummary:
-
-       Added a bunch of doc to bin/rt. probably should have check to see if it runs ;)
-       TitleBoxStart got the attributes:  class, title_href and titleright_href. makes calls to it cleaner.
-       showsummary got a few more links to the places things should go.
-       selectOwner now will actually default to nobody if that's the right value.
-       
-2001-01-13 03:22  jesse
-
-       * TODO:
-
-       Changed the TODO file to point to the current TODO list
-       
-2001-01-13 03:18  jesse
-
-       * Makefile:
-
-       Bumped version # for release
-       
-2001-01-13 03:11  jesse
-
-       * bin/rtmux.pl, lib/RT/Queue.pm, lib/RT/Action/SendEmail.pm:
-
-       Fixing a couple minor things in rtmux and Queue.pm so that the mail interfaces work ok.
-       
-2001-01-13 02:34  jesse
-
-       * lib/RT/User.pm:
-
-       Added the ability to generate a random password to RT::User.  we don't yet
-       have a nice way to email this information to the user. which is a real bummer.
-       
-2001-01-12 17:35  jesse
-
-       * etc/config.pm, lib/RT/Ticket.pm, lib/RT/User.pm,
-       lib/RT/Interface/Web.pm, webrt/Admin/Users/Modify.html,
-       webrt/SelfService/Create.html, webrt/SelfService/Details.html,
-       webrt/SelfService/Elements/Header, webrt/SelfService/Elements/Tabs:
-
-       Made ACLs for 'Everyone' work. fixed a few other small ACL bugs.
-       Made the 'Requestor-mode' ticket create tool work.
-       
-2001-01-12 12:27  jesse
-
-       * webrt/Elements/: SelectDate, SelectOwner:
-
-       Commented out unimplemented select relative date bits.
-       SelectOwner now lets you pick nobody.
-       
-2001-01-12 03:16  jesse
-
-       * bin/rt, bin/rtmux.pl, lib/RT/Ticket.pm, tools/testdeps:
-
-       Comments and Correspondence work from the cli now. with and without --source (for source data) and --no-edit (to disable invocation of $EDITOR)
-       
-       rt and rtmux.pl now drop setgidness as soon as they can. it's happier this
-       way. really :)
-       
-       testdeps now installs File::Temp, which is needed to do safe tempfile usage.
-       
-2001-01-12 00:11  jesse
-
-       * webrt/Elements/: MyRequests, MyTickets:
-
-       Bug fix for #47 (Id flows into subject on 'home' screen)
-       
-2001-01-11 03:34  jesse
-
-       * webrt/Elements/Header:
-
-       Removed extra spaces from the header
-       
-2001-01-11 02:57  jesse
-
-       * webrt/Elements/SelectOwner:
-
-       Made SelectOwner actually show all the right people
-       
-2001-01-11 02:53  jesse
-
-       * tools/testdeps:
-
-       Added a requirement for the current DBIx::SearchBuilder to testdeps
-       
-2001-01-11 02:28  jesse
-
-       * Makefile:
-
-       revved the version for distribution
-       
-2001-01-11 02:28  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/Interface/Web.pm,
-       webrt/Elements/Quicksearch, webrt/Elements/TitleBoxStart,
-       webrt/Ticket/Display.html, webrt/Ticket/Elements/EditBasics:
-
-       fixed a couple of UI bugs. the 'quick' links in the web ticket view should now all work.
-       Logger->warn  -> Logger->warning in the web ui
-       
-2001-01-10 17:42  jesse
-
-       * Makefile:
-
-       Bumped to 1.3.33
-       
-2001-01-10 01:46  jesse
-
-       * webrt/Ticket/Attachment/dhandler:
-
-       Date: Wed, 10 Jan 2001 16:22:43 +1000 (EST)                                     From: Byron Ellacott <bje@apnic.net>                                            To: rt-devel@fsck.com                                                           Subject: Re: [rt-devel] [rt-announce] RT 1.3.30 released                        List-Id: RT Development <rt-devel.lists.fsck.com>                                                                                                               [-- Attachment #1 --]                                                           [-- Type: text/PLAIN, Encoding: 7bit, Size: 0.7K --]                                                                                                            On Wed, 3 Jan 2001, Jesse wrote:                                                                                                                                [snip]                                                                                                                                                          I noticed 1-3-31 sitting around, so I installed that.  I'm giving a             demonstration tomorrow, so I've been running through the web UI.  I             noticed a problem with attachments - HTML::Mason was munging everything to      be HTML-nice, but a jpg doesn't display if its < characters are changed to      &lt;, and it's not good to have </BODY></HTML> on the end of binary             attachments.
-       
-2001-01-10 00:24  jesse
-
-       * Makefile:
-
-       Revved the version to 1.3.32
-       
-2001-01-09 23:57  jesse
-
-       * webrt/Admin/Users/Rights.html:
-
-       file Rights.html was initially added on branch rt-1-1.
-       
-2001-01-09 23:57  jesse
-
-       * lib/RT/Record.pm, lib/RT/User.pm, lib/RT/Interface/Email.pm,
-       tools/insertdata, webrt/Admin/Elements/UserTabs,
-       webrt/Admin/Users/Modify.html, webrt/Admin/Users/Rights.html,
-       webrt/Elements/Quicksearch, webrt/Elements/TitleBoxEnd,
-       webrt/Elements/TitleBoxStart:
-
-       Did some work on User creation to check for duplicate userids on create.
-       Better user create error checking.
-       Switched the TitleBox UI to a compromise between new and old.
-       
-       Did a bit of ui work on web based user modification
-       
-2001-01-09 02:15  jesse
-
-       * Makefile, lib/RT/User.pm, tools/insertdata,
-       webrt/Admin/Users/Modify.html:
-
-       shuffling around hte user password stuff. hopefully the user modification issues seen in 1.3.30 will be fixed.
-       
-2001-01-09 00:48  jesse
-
-       * webrt/Ticket/History.html:
-
-       file History.html was initially added on branch rt-1-1.
-       
-2001-01-09 00:48  jesse
-
-       * docs/keywords:
-
-       file keywords was initially added on branch rt-1-1.
-       
-2001-01-09 00:48  jesse
-
-       * bin/mason_handler.scgi:
-
-       file mason_handler.scgi was initially added on branch rt-1-1.
-       
-2001-01-09 00:48  jesse
-
-       * Makefile, bin/mason_handler.scgi, bin/webmux.pl, docs/keywords,
-       lib/RT/Tickets.pm, lib/RT/Interface/Web.pm,
-       webrt/Admin/Elements/GrantQueueRightsTo~,
-       webrt/Ticket/History.html:
-
-       Started to write out notes on a testsuite.
-       Started work on a CGI/SpeedyCGI frontend
-       added a file that was missing in 1.3.30
-       
-2001-01-08 14:04  jesse
-
-       * NEWS, README:
-
-       Added a web based due-date patch.
-       
-2001-01-06 15:17  jesse
-
-       * etc/schema.pm:
-
-       Added 'Deleted' attributes for tables whose entries can not be safely
-       removed from the database for ref. integrity problems.
-       
-2001-01-03 23:07  jesse
-
-       * Makefile:
-
-       Bumped version to 1.3.30
-       
-2001-01-03 23:02  jesse
-
-       * tools/testdeps:
-
-       file testdeps was initially added on branch rt-1-1.
-       
-2001-01-03 23:02  jesse
-
-       * README, bin/testdeps.pl, lib/Makefile.PL, tools/testdeps,
-       webrt/Elements/TitleBoxStart:
-
-       a bit of quick UI work.
-       an update to depend on DBIx::SearchBuilder 0.15 (just releaseD)
-       testdeps moved to tools
-       
-2001-01-03 03:21  jesse
-
-       * bin/rt, lib/RT/Tickets.pm:
-
-       ticket searches for integers are a bit more flexible now (and the code's tighter)
-       
-       the rtq section of the new bin/rt appears functional, if underdocced.
-       
-2001-01-02 22:55  jesse
-
-       * lib/RT/Tickets.pm, lib/RT/Interface/Web.pm,
-       webrt/Search/PickRestriction:
-
-       Imported ivan's keyword search patch, along with a modification to allow
-       for _not_ selecting keywords.
-       
-2001-01-02 21:45  jesse
-
-       * Makefile, bin/testdeps.pl, lib/RT/KeywordSelect.pm,
-       lib/RT/ObjectKeyword.pm, lib/RT/ObjectKeywords.pm,
-       lib/RT/Ticket.pm, lib/RT/Tickets.pm, lib/RT/Watchers.pm,
-       lib/RT/Interface/Web.pm, tools/insertdata, webrt/webrt.css,
-       webrt/Elements/Header, webrt/Elements/TitleBoxStart,
-       webrt/Elements/ViewUser, webrt/Search/Listing.html,
-       webrt/Search/PickRestriction, webrt/Ticket/Create.html,
-       webrt/Ticket/Display.html, webrt/Ticket/Elements/ShowBasics,
-       webrt/Ticket/Elements/ShowSummary,
-       webrt/Ticket/Elements/ShowTransaction, webrt/Ticket/Elements/Tabs:
-
-       Fixed a warning in testdeps (Well, worked around it, anyway)
-       Added some helper functions for keywords and keyword selects.
-       
-       did a bunch of UI cleanup. started to color-code the webui
-       
-       started work on a generic queue listing format in Tickets.pm
-       
-2001-01-02 15:02  jesse
-
-       * webrt/SelfService/Elements/ShowTransaction:
-
-       file ShowTransaction was initially added on branch rt-1-1.
-       
-2001-01-02 15:02  jesse
-
-       * webrt/SelfService/: Create.html, Details.html,
-       Elements/GotoTicket, Elements/Header, Elements/ShowTransaction,
-       Elements/Tabs:
-
-       Fleshed out more of the requestor UI.
-       It's good enough for the alpha. yay!
-       
-2001-01-02 15:02  jesse
-
-       * webrt/SelfService/Elements/GotoTicket:
-
-       file GotoTicket was initially added on branch rt-1-1.
-       
-2001-01-01 19:06  jesse
-
-       * webrt/Ticket/: Modify.html, ModifyDates.html, ModifyPeople.html,
-       Elements/EditBasics, Elements/EditKeywordSelects,
-       Elements/ShowDates, Elements/ShowSummary:
-
-       Even yet still more Technicolor!
-       
-2001-01-01 18:42  jesse
-
-       * webrt/NoAuth/images/spacer.gif:
-
-       file spacer.gif was initially added on branch rt-1-1.
-       
-2001-01-01 18:42  jesse
-
-       * webrt/NoAuth/Reminder.html:
-
-       file Reminder.html was initially added on branch rt-1-1.
-       
-2001-01-01 18:42  jesse
-
-       * webrt/Elements/Section:
-
-       file Section was initially added on branch rt-1-1.
-       
-2001-01-01 18:42  jesse
-
-       * lib/RT/CurrentUser.pm, lib/RT/KeywordSelect.pm, webrt/webrt.css,
-       webrt/Admin/Keywords/index.html, webrt/Admin/Queues/People.html,
-       webrt/Elements/Header, webrt/Elements/ListActions,
-       webrt/Elements/MyRequests, webrt/Elements/MyTickets,
-       webrt/Elements/Section, webrt/Elements/Submit,
-       webrt/Elements/TitleBoxEnd, webrt/Elements/TitleBoxStart,
-       webrt/NoAuth/Login.html, webrt/NoAuth/Reminder.html,
-       webrt/NoAuth/images/spacer.gif, webrt/Ticket/Display.html,
-       webrt/Ticket/ModifyPeople.html, webrt/Ticket/Elements/ShowSummary,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       A bunch of UI work.
-       Ticket Display is significantly different. and _much_ faster loading.
-       A color style guide for the web ui is forthcoming.
-       
-       removed a Die from CurrentUser.
-       
-2000-12-30 03:27  jesse
-
-       * webrt/Elements/Tabs:
-
-       fixed a ui nit from ivan
-       
-2000-12-30 03:03  jesse
-
-       * webrt/Ticket/Elements/ShowSummary:
-
-       fixed a hyperlink.
-       
-2000-12-30 00:07  jesse
-
-       * Makefile:
-
-       bumped version for release
-       
-2000-12-30 00:03  jesse
-
-       * etc/config.pm, lib/RT/User.pm,
-       webrt/Admin/Elements/ModifyKeywordSelect,
-       webrt/Admin/Global/Keywords.html,
-       webrt/Admin/KeywordSelects/index.html,
-       webrt/Admin/Keywords/Modify.html, webrt/Admin/Keywords/index.html,
-       webrt/Admin/Queues/Keywords.html, webrt/Admin/Users/index.html:
-
-       Fixed a bug in keyword creation that caused urls and param values to get buggered.
-       
-       Passwords are now encrypted in the database
-       
-2000-12-29 05:54  jesse
-
-       * bin/rt, lib/RT/Link.pm, lib/RT/Ticket.pm,
-       lib/RT/Interface/Web.pm, webrt/Ticket/Display.html,
-       webrt/Ticket/Elements/ShowDependencies,
-       webrt/Ticket/Elements/ShowLinks:
-
-       Did a bunch of work on the linking interface. It's now got
-       a much easier API. and it's twice as functional (you can delete links)
-       
-       Did the proof-of concept for the link code in the CLI. it'll need
-       fleshing out tomorrow.
-       
-       Fleshed out other parts of the CLI.
-       
-       stayed up way too late.
-       
-2000-12-29 00:30  jesse
-
-       * Makefile, bin/rt, lib/RT/Keyword.pm, lib/RT/Ticket.pm:
-
-       Added keyword support to the CLI.
-       fixed a couple of Keyword core bugs
-       
-2000-12-28 03:56  jesse
-
-       * bin/rt, bin/testdeps.pl, lib/RT/Keyword.pm,
-       lib/RT/KeywordSelect.pm, lib/RT/User.pm:
-
-       Removed unused keyword related code. added in a bit of
-       new keyword related code to get "relative" paths of keywords.
-       
-       fixed a longstanding warning in ACL checking.
-       
-       first 1/2 of keywords support for the new rt cli.
-       
-       added Tie::IxHash to testdeps.pl (keywords needs it)
-       
-2000-12-27 02:19  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       missed a comma
-       
-2000-12-27 01:21  jesse
-
-       * webrt/Admin/Global/Keywords.html:
-
-       file Keywords.html was initially added on branch rt-1-1.
-       
-2000-12-27 01:21  jesse
-
-       * etc/schema.pm, lib/RT/ACE.pm, lib/RT/KeywordSelect.pm,
-       lib/RT/KeywordSelects.pm, lib/RT/Queue.pm, lib/RT/Ticket.pm,
-       lib/RT/Transaction.pm, webrt/Admin/Elements/SystemTabs,
-       webrt/Admin/Global/Keywords.html, webrt/Admin/Queues/Keywords.html,
-       webrt/Ticket/Create.html, webrt/Ticket/ModifyPeople.html,
-       webrt/Ticket/Elements/EditKeywordSelects,
-       webrt/Ticket/Elements/ShowKeywordSelects,
-       webrt/Ticket/Elements/ShowSummary,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       Added the ability to name keyword selects.
-       first round of ACLing for keywords.
-       
-       Added the ability to create KeywordSelects which apply to all queues (Rather than just
-       a single queue)
-       
-       misc bigfixes.
-       
-2000-12-26 02:56  jesse
-
-       * webrt/Elements/SelectKeywordOptions:
-
-       file SelectKeywordOptions was initially added on branch rt-1-1.
-       
-2000-12-26 02:56  jesse
-
-       * webrt/Admin/Keywords/index.html:
-
-       file index.html was initially added on branch rt-1-1.
-       
-2000-12-26 02:56  jesse
-
-       * webrt/Admin/Queues/Keywords.html:
-
-       file Keywords.html was initially added on branch rt-1-1.
-       
-2000-12-26 02:56  jesse
-
-       * webrt/Elements/SelectKeyword:
-
-       file SelectKeyword was initially added on branch rt-1-1.
-       
-2000-12-26 02:56  jesse
-
-       * bin/webmux.pl, etc/schema.pm, lib/RT/Keyword.pm,
-       lib/RT/KeywordSelect.pm, lib/RT/KeywordSelects.pm,
-       lib/RT/Keywords.pm, lib/RT/ObjectKeyword.pm,
-       lib/RT/ObjectKeywords.pm, lib/RT/Queue.pm, lib/RT/Ticket.pm,
-       lib/RT/Watchers.pm, webrt/Admin/Elements/ModifyKeyword,
-       webrt/Admin/Elements/ModifyKeywordSelect,
-       webrt/Admin/Elements/QueueTabs, webrt/Admin/Elements/Tabs,
-       webrt/Admin/KeywordSelects/index.html,
-       webrt/Admin/Keywords/Modify.html, webrt/Admin/Keywords/index.html,
-       webrt/Admin/Queues/Keywords.html, webrt/Elements/SelectKeyword,
-       webrt/Elements/SelectKeywordOptions, webrt/Ticket/Modify.html,
-       webrt/Ticket/Elements/EditKeywordSelects,
-       webrt/Ticket/Elements/ShowKeywordSelects:
-
-       My first pass at making the keywords stuff work more like the rest of the RT core.
-       A couple of minor fixes on non-keywords things, but mostly this was an
-       edit of the keywords code to:
-               1. make the admin UI work more like the rest of the admin ui
-               (still need to do "global" keyword selections)
-       
-               2. bring the coding style of the keywords stuff more into line
-               with the rest of the codebase
-       
-               3. flesh out the helper methods in the keywords modules.
-       
-2000-12-24 02:04  jesse
-
-       * lib/RT/: Keyword.pm, KeywordSelect.pm, ObjectKeyword.pm:
-
-       A first round of commentary and cleanup on a few modules
-       
-2000-12-24 01:34  jesse
-
-       * webrt/Ticket/Elements/ShowKeywordSelects:
-
-       file ShowKeywordSelects was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * webrt/Ticket/Elements/EditKeywordSelects:
-
-       file EditKeywordSelects was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * webrt/Admin/: KeywordSelects/Modify.html, Keywords/Modify.html:
-
-       file Modify.html was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * webrt/Admin/KeywordSelects/index.html:
-
-       file index.html was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * webrt/Admin/Elements/ModifyKeyword:
-
-       file ModifyKeyword was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * webrt/Admin/Elements/ModifyKeywordSelect:
-
-       file ModifyKeywordSelect was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * webrt/Admin/Elements/SelectModifyKeyword:
-
-       file SelectModifyKeyword was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * webrt/Admin/Elements/SelectModifyKeywordSelect:
-
-       file SelectModifyKeywordSelect was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * lib/RT/ObjectKeyword.pm:
-
-       file ObjectKeyword.pm was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * lib/RT/Keyword.pm:
-
-       file Keyword.pm was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * lib/RT/KeywordSelect.pm:
-
-       file KeywordSelect.pm was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * lib/test.pl:
-
-       file test.pl was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * lib/RT/ObjectKeywords.pm:
-
-       file ObjectKeywords.pm was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * lib/RT/KeywordSelects.pm:
-
-       file KeywordSelects.pm was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * lib/RT/Keywords.pm:
-
-       file Keywords.pm was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * Makefile, etc/acl.Pg, etc/schema.pm, lib/MANIFEST,
-       lib/MANIFEST.SKIP, lib/Makefile.PL, lib/RT.pm, lib/test.pl,
-       lib/RT/Keyword.pm, lib/RT/KeywordSelect.pm,
-       lib/RT/KeywordSelects.pm, lib/RT/Keywords.pm,
-       lib/RT/ObjectKeyword.pm, lib/RT/ObjectKeywords.pm,
-       lib/RT/Ticket.pm, webrt/Admin/Elements/ModifyKeyword,
-       webrt/Admin/Elements/ModifyKeywordSelect,
-       webrt/Admin/Elements/SelectModifyKeyword,
-       webrt/Admin/Elements/SelectModifyKeywordSelect,
-       webrt/Admin/Elements/Tabs, webrt/Admin/KeywordSelects/Modify.html,
-       webrt/Admin/KeywordSelects/index.html,
-       webrt/Admin/Keywords/Modify.html, webrt/Ticket/Modify.html,
-       webrt/Ticket/Elements/EditBasics,
-       webrt/Ticket/Elements/EditKeywordSelects,
-       webrt/Ticket/Elements/ShowKeywordSelects,
-       webrt/Ticket/Elements/ShowSummary:
-
-       Importing two largish patches from ivan@420.am:
-               First up, ivan switched lib/RT over to using MakeMaker..so now
-               we get man pages for the core modules and a bunch of other cool stuff.
-       
-               Second: ivan handed us an almost complete keywords system.  Over the next
-               week or two, I'm going to be adding ACL support to the keywords system
-               and starting to integrate bits of it better into the rest of the core
-               (though it's nearly all done already).
-       
-                       Thanks, ivan!
-       
-2000-12-24 01:34  jesse
-
-       * lib/MANIFEST:
-
-       file MANIFEST was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * lib/Makefile.PL:
-
-       file Makefile.PL was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * lib/RT.pm:
-
-       file RT.pm was initially added on branch rt-1-1.
-       
-2000-12-24 01:34  jesse
-
-       * lib/MANIFEST.SKIP:
-
-       file MANIFEST.SKIP was initially added on branch rt-1-1.
-       
-2000-12-23 23:45  jesse
-
-       * Makefile, webrt/Ticket/Elements/Tabs:
-
-       made the links in the ticket tool bar point to the right places.
-       
-2000-12-23 23:15  jesse
-
-       * lib/RT/Ticket.pm:
-
-       fixing a typo and the docs.
-       
-2000-12-23 23:12  jesse
-
-       * lib/RT/Ticket.pm:
-
-       the internal function _SetTold shouldn't be hitting an ACL check.
-       
-2000-12-23 17:37  jesse
-
-       * lib/RT/Ticket.pm, webrt/Ticket/Display.html,
-       webrt/Ticket/Modify.html, webrt/Ticket/ModifyDates.html,
-       webrt/Ticket/ModifyLinks.html, webrt/Ticket/ModifyPeople.html,
-       webrt/Ticket/Update.html, webrt/Ticket/Elements/Tabs,
-       webrt/Ticket/Elements/TicketToolBox:
-
-       Cleaned up a bit of date diff related functionality.
-       
-       Did work on the ticket tool bar.
-       
-2000-12-23 16:46  jesse
-
-       * lib/RT/Record.pm:
-
-       Lets try that again..
-       
-2000-12-23 16:39  jesse
-
-       * lib/RT/Record.pm:
-
-       LongSinceUpdatedAsString is now actually relative :)
-       
-2000-12-23 16:09  jesse
-
-       * lib/RT/Tickets.pm:
-
-       added a default to LimitStatus.
-       
-2000-12-23 01:47  jesse
-
-       * bin/: rt, testdeps.pl:
-
-       updated testdeps to require the latest mason (for ease of debugging)
-       the new combined bin/rt actually implements the behavior of rtq and rt -show
-       fully (I believe). next up, more ticket modification and a code cleanup
-       
-2000-12-22 18:37  jesse
-
-       * Makefile:
-
-       bumped to 1.3.28 for release
-       
-2000-12-19 22:38  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/Tickets.pm, lib/RT/Transaction.pm,
-       lib/RT/Interface/Web.pm, webrt/Elements/Tabs,
-       webrt/Ticket/ModifyPeople.html, webrt/Ticket/Elements/EditPeople,
-       webrt/User/Prefs.html:
-
-       Removed outdated CC request to and BCC request to
-       did some UI touchups.
-       
-       started a bit of work in tickets.pm for the new CLI (more explicit searching)
-       
-2000-12-19 21:50  jesse
-
-       * bin/rt:
-
-       Modifying ticket requestors from the commandline works. yay.
-       Simplified the commandline arguments a bit too.
-       
-2000-12-19 18:37  jesse
-
-       * bin/: mason_handler.fcgi, webmux.pl:
-
-       updaes to webmux.pl to work on with new versions of HTML::Mason
-       
-2000-12-19 14:05  jesse
-
-       * webrt/Ticket/Display.html:
-
-       Fixed a bug in Ticket/Display.html that caused navigation not to work within new tickets.
-       
-2000-12-19 04:03  jesse
-
-       * bin/rt:
-
-       implemented --history (show ticket history)
-       and --limit-status (limit to a ticket status)
-       just to make sure that this works at all.  it does.
-       
-       With the new ui, you'll be able to trivially perform actions on large #s of tickets.
-       
-2000-12-19 03:38  jesse
-
-       * bin/rt:
-
-       After playing with a few Getopt variants, I've settled on Getopt::Long for now...
-       and implemented the skeleton of the new RT cli.  I suspect that with another day's work,
-       it should be mostly functional. yay.
-       
-2000-12-19 03:38  jesse
-
-       * bin/rt:
-
-       file rt was initially added on branch rt-1-1.
-       
-2000-12-18 19:34  jesse
-
-       * docs/design_docs/cli_spec:
-
-       file cli_spec was initially added on branch rt-1-1.
-       
-2000-12-18 19:34  jesse
-
-       * docs/design_docs/cli_spec:
-
-       Added the CLI spec from deborah.
-       
-2000-12-18 02:11  jesse
-
-       * webrt/Elements/: CreateTicket, GotoTicket:
-
-       Fixed a basepath error.
-       
-2000-12-18 01:19  jesse
-
-       * webrt/Elements/CreateTicket:
-
-       file CreateTicket was initially added on branch rt-1-1.
-       
-2000-12-18 01:19  jesse
-
-       * webrt/Elements/GotoTicket:
-
-       file GotoTicket was initially added on branch rt-1-1.
-       
-2000-12-18 01:19  jesse
-
-       * README, webrt/Admin/Queues/Modify.html,
-       webrt/Admin/Users/Modify.html, webrt/Elements/CreateTicket,
-       webrt/Elements/GotoTicket, webrt/Search/Listing.html:
-
-       A few more changes from Lee Ann and a couple of files I missed on the earlier  checkins.
-       
-2000-12-18 01:14  jesse
-
-       * webrt/Admin/Groups/Rights.html:
-
-       file Rights.html was initially added on branch rt-1-1.
-       
-2000-12-18 01:14  jesse
-
-       * webrt/Admin/Groups/: Members.html, Rights.html:
-
-       a couple UI tweaks from Lee Ann Goldstein
-       
-2000-12-18 00:51  jesse
-
-       * webrt/: Admin/Elements/SystemTabs, Admin/Groups/index.html,
-       Admin/Users/index.html, Elements/Submit, Elements/Tabs:
-
-       More UI hacking. whee
-       
-2000-12-17 23:55  jesse
-
-       * webrt/: Elements/SelectNewTicketQueue, Elements/SelectOwner,
-       Elements/Tabs, Ticket/Create.html, Ticket/Elements/Tabs:
-
-       ui hacking to add the "Create Ticket" and "Goto Ticket" ui elements at the top.
-       
-2000-12-17 22:17  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       webrt/Elements/MessageBox, webrt/Ticket/Modify.html,
-       webrt/Ticket/ModifyPeople.html:
-
-       Fixing bugs 7,8,28
-       
-2000-12-17 02:38  jesse
-
-       * webrt/Ticket/Elements/ShowDates:
-
-       *sigh* typo in ShowDates.
-       
-2000-12-17 02:34  jesse
-
-       * lib/RT/Date.pm, webrt/Ticket/Elements/EditDates,
-       webrt/Ticket/Elements/ShowDates:
-
-       A bit of work on Dates. a postgres fix from ivan and some display prettification.
-       
-2000-12-17 02:15  jesse
-
-       * Makefile, webrt/Ticket/Elements/TicketToolBox:
-
-       commeted out some toolbar actions which don't work yet.
-       
-       bumped the version to 1.3.27 for imminent release.
-       
-2000-12-17 01:51  jesse
-
-       * lib/RT/Attachment.pm:
-
-       The ACL problem on attachments was a bootstrapping issue. couldn't check acls because it
-       couldn't necessarily see what to check
-       
-2000-12-17 01:44  jesse
-
-       * lib/RT/Attachment.pm:
-
-       acl fix for attachments.
-       
-2000-12-17 01:15  jesse
-
-       * lib/RT/Ticket.pm:
-
-       fixing ugly disgusting ACL bugs
-       
-2000-12-17 00:35  jesse
-
-       * lib/RT/Transaction.pm, lib/RT/User.pm,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       Fixing bugs in Transaction ACLs.
-       
-2000-12-16 03:56  jesse
-
-       * webrt/Admin/Groups/Members.html:
-
-       ui nit in admin/groups/members.
-       
-2000-12-16 03:31  jesse
-
-       * lib/RT/: Group.pm, GroupMember.pm:
-
-       $object->$SUPER::Foo is wrong. $object->SUPER::Foo is not.
-       
-2000-12-16 03:28  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Rights checks for ticket ownership work best when the right that's set is the same
-       as the right that's checked for *sigh*
-       
-2000-12-16 03:26  jesse
-
-       * webrt/Admin/Groups/Members.html:
-
-       Fixed a couple bugs in Group mebership administration code.
-       
-2000-12-16 03:04  jesse
-
-       * webrt/: Admin/Elements/GroupTabs, Admin/Elements/QueueTabs,
-       Admin/Elements/SystemTabs, Admin/Elements/Tabs,
-       Admin/Elements/UserTabs, Admin/Global/index.html,
-       Admin/Groups/Modify.html, Admin/Groups/index.html,
-       Admin/Queues/People.html, Admin/Queues/index.html,
-       Admin/Users/Modify.html, Admin/Users/index.html,
-       Elements/SelectWatcherType, Elements/Tabs, Ticket/Create.html,
-       Ticket/Display.html, Ticket/Elements/Tabs:
-
-       Bugfix in user admin (no longer automatically revokes "privileged status)
-       a bunch of tab-related UI cleanup. the start of tabs that reflect the current page.
-       
-       added the ability to configure queue watchers from the web ui
-       
-2000-12-16 03:04  jesse
-
-       * webrt/Admin/Queues/People.html:
-
-       file People.html was initially added on branch rt-1-1.
-       
-2000-12-16 00:58  jesse
-
-       * webrt/Admin/Users/index.html:
-
-       typo fixing.
-       
-2000-12-15 19:12  jesse
-
-       * webrt/Admin/Global/GroupRights.html:
-
-       file GroupRights.html was initially added on branch rt-1-1.
-       
-2000-12-15 19:12  jesse
-
-       * webrt/Admin/Global/UserRights.html:
-
-       file UserRights.html was initially added on branch rt-1-1.
-       
-2000-12-15 19:12  jesse
-
-       * webrt/Admin/Elements/GroupTabs:
-
-       file GroupTabs was initially added on branch rt-1-1.
-       
-2000-12-15 19:12  jesse
-
-       * lib/RT/ACE.pm, lib/RT/Group.pm, lib/RT/Groups.pm,
-       lib/RT/Record.pm, lib/RT/Scrip.pm, lib/RT/ScripAction.pm,
-       lib/RT/Ticket.pm, lib/RT/Transaction.pm, lib/RT/User.pm,
-       lib/RT/Users.pm, tools/insertdata, webrt/Admin/Elements/GroupTabs,
-       webrt/Admin/Elements/SystemTabs, webrt/Admin/Global/ACL.html,
-       webrt/Admin/Global/GroupRights.html,
-       webrt/Admin/Global/UserRights.html,
-       webrt/Admin/Groups/Members.html, webrt/Admin/Groups/Modify.html,
-       webrt/Admin/Groups/index.html, webrt/Admin/Users/Modify.html,
-       webrt/Admin/Users/index.html:
-
-       A bunch of cleanup work on Users and Groups (and a couple of small bugfixes, one
-       which might prevent install of Alpha 2) mostly aimed at improving the admin ui.
-       
-       We now have two levels of "Privileged" for a user, 1 which means "can be granted rights"
-       and 2 which means "should not be futzed with by the user"
-       
-2000-12-14 23:04  jesse
-
-       * webrt/Ticket/Attachment/dhandler:
-
-       Accidentally left out of the last rev. sorry about that.
-       
-2000-12-14 23:04  jesse
-
-       * webrt/Ticket/Attachment/dhandler:
-
-       file dhandler was initially added on branch rt-1-1.
-       
-2000-12-12 20:44  jesse
-
-       * Makefile:
-
-       Bumped version to 1.3.26. This is RT2 Alpha 2, folks.
-       
-2000-12-12 20:34  jesse
-
-       * lib/RT/Attachment.pm, lib/RT/Record.pm, lib/RT/Ticket.pm,
-       lib/RT/Transaction.pm, lib/RT/User.pm,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       Attachment display in the webui now just works [tm] RT2 Alpha 2 will be rolled later tonight.
-       
-2000-12-12 19:03  jesse
-
-       * webrt/Admin/Global/Template.html:
-
-       file Template.html was initially added on branch rt-1-1.
-       
-2000-12-12 19:03  jesse
-
-       * webrt/Admin/Global/Templates.html:
-
-       file Templates.html was initially added on branch rt-1-1.
-       
-2000-12-12 19:03  jesse
-
-       * README, bin/webmux.pl, lib/RT/Attachment.pm, lib/RT/Template.pm,
-       lib/RT/Transaction.pm, webrt/Admin/Elements/SelectTemplate,
-       webrt/Admin/Elements/SystemTabs, webrt/Admin/Global/Template.html,
-       webrt/Admin/Global/Templates.html,
-       webrt/Admin/Queues/Templates.html,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       Working on attachments support.
-       
-       did some work on global templates
-       
-2000-12-12 15:15  jesse
-
-       * lib/RT/Template.pm, lib/RT/Templates.pm, tools/insertdata:
-
-       Core support for system-scoped templates
-       
-2000-12-12 14:12  jesse
-
-       * webrt/Admin/: Queues/Modify.html, Users/Create.html,
-       Users/Modify.html:
-
-       Fixed queue and user creation problems.
-       
-2000-12-12 03:05  jesse
-
-       * webrt/Ticket/: Link.html, ModifyLinks.html, Elements/ShowSummary,
-       Elements/Tabs:
-
-       Brought the still basic link editing ui into conformance with the rest of the ticket ui
-       
-2000-12-12 03:05  jesse
-
-       * webrt/Ticket/ModifyLinks.html:
-
-       file ModifyLinks.html was initially added on branch rt-1-1.
-       
-2000-12-12 02:41  jesse
-
-       * webrt/Ticket/: ModifyDates.html, ModifyPeople.html:
-
-       split out the ticket modify screen into 3 more bite-sized pages.
-       
-2000-12-12 02:41  jesse
-
-       * webrt/Ticket/ModifyPeople.html:
-
-       file ModifyPeople.html was initially added on branch rt-1-1.
-       
-2000-12-12 02:41  jesse
-
-       * webrt/Ticket/ModifyDates.html:
-
-       file ModifyDates.html was initially added on branch rt-1-1.
-       
-2000-12-12 02:41  jesse
-
-       * webrt/Ticket/: Modify.html, Elements/Tabs:
-
-       [no log message]
-       
-2000-12-11 15:01  jesse
-
-       * webrt/NoAuth/Login.html:
-
-       file Login.html was initially added on branch rt-1-1.
-       
-2000-12-11 15:01  jesse
-
-       * webrt/NoAuth/Logout.html:
-
-       file Logout.html was initially added on branch rt-1-1.
-       
-2000-12-11 15:01  jesse
-
-       * webrt/: Login.html, Logout.html, autohandler, Elements/Footer,
-       Elements/Header, NoAuth/Login.html, NoAuth/Logout.html:
-
-       Moving Login and Logout around so they work right with the new NoAuth scheme
-       
-2000-12-11 05:00  jesse
-
-       * webrt/: Login.html, autohandler:
-
-       fixed a couple login bugs. implemented some logic to deal with different auth classes:
-       /NoAuth/ and /SelfService/
-       
-2000-12-11 01:46  jesse
-
-       * webrt/: rt.jpg, Elements/Header, Elements/MyRequests,
-       Elements/MyTickets, Search/Listing.html, Ticket/Create.html,
-       Ticket/Create_Detail.html, Ticket/Display.html, Ticket/Modify.html,
-       Ticket/Update.html, Ticket/Elements/ShowTransaction,
-       Ticket/Elements/Tabs, Ticket/Elements/TicketToolBox:
-
-        Work on ticket display. we're getting there.
-       
-2000-12-10 23:53  jesse
-
-       * webrt/Admin/Queues/Template.html:
-
-       file Template.html was initially added on branch rt-1-1.
-       
-2000-12-10 23:53  jesse
-
-       * webrt/Admin/Queues/Templates.html:
-
-       file Templates.html was initially added on branch rt-1-1.
-       
-2000-12-10 23:53  jesse
-
-       * webrt/Admin/Elements/QueueTabs:
-
-       file QueueTabs was initially added on branch rt-1-1.
-       
-2000-12-10 23:53  jesse
-
-       * webrt/Admin/Elements/SystemTabs:
-
-       file SystemTabs was initially added on branch rt-1-1.
-       
-2000-12-10 23:53  jesse
-
-       * webrt/Admin/: Global/Scrips.html, Queues/Scrips.html:
-
-       file Scrips.html was initially added on branch rt-1-1.
-       
-2000-12-10 23:53  jesse
-
-       * webrt/Admin/Elements/UserTabs:
-
-       file UserTabs was initially added on branch rt-1-1.
-       
-2000-12-10 23:53  jesse
-
-       * webrt/Admin/: Global/ACL.html, Queues/ACL.html:
-
-       file ACL.html was initially added on branch rt-1-1.
-       
-2000-12-10 23:53  jesse
-
-       * webrt/Admin/Global/index.html:
-
-       file index.html was initially added on branch rt-1-1.
-       
-2000-12-10 23:53  jesse
-
-       * Makefile, webrt/index.html, webrt/Admin/ModifyUser,
-       webrt/Admin/index.html, webrt/Admin/Elements/Header,
-       webrt/Admin/Elements/QueueTabs, webrt/Admin/Elements/SystemTabs,
-       webrt/Admin/Elements/Tabs, webrt/Admin/Elements/UserTabs,
-       webrt/Admin/Global/ACL.html, webrt/Admin/Global/Scrips.html,
-       webrt/Admin/Global/index.html, webrt/Admin/Queues/ACL.html,
-       webrt/Admin/Queues/Modify.html, webrt/Admin/Queues/Scrips.html,
-       webrt/Admin/Queues/Template.html,
-       webrt/Admin/Queues/Templates.html, webrt/Admin/Queues/index.html,
-       webrt/Admin/Users/Modify.html, webrt/Admin/Users/index.html,
-       webrt/Elements/Header, webrt/Elements/Tabs:
-
-       Bunch of work on the web administration framework.
-       Lots of stuff should be much cleaner now.
-       
-2000-12-10 01:21  jesse
-
-       * Makefile:
-
-       Bumped version to 1.3.25 for release
-       
-2000-12-10 01:15  jesse
-
-       * webrt/: Elements/TitleBoxEnd, Elements/TitleBoxStart,
-       SelfService/Elements/MyRequests, SelfService/Elements/Tabs,
-       Ticket/Update.html, User/Prefs.html:
-
-       Work on SSRI and a bit of overall UI tweaking
-       
-2000-12-09 22:48  jesse
-
-       * webrt/SelfService/Elements/Header:
-
-       file Header was initially added on branch rt-1-1.
-       
-2000-12-09 22:48  jesse
-
-       * webrt/SelfService/Elements/: Header, MyRequests, Tabs:
-
-       Missed a couple files for SSRI
-       
-2000-12-09 22:48  jesse
-
-       * webrt/SelfService/Elements/MyRequests:
-
-       file MyRequests was initially added on branch rt-1-1.
-       
-2000-12-09 22:48  jesse
-
-       * webrt/SelfService/Elements/Tabs:
-
-       file Tabs was initially added on branch rt-1-1.
-       
-2000-12-09 22:43  jesse
-
-       * webrt/SelfService/Create.html:
-
-       file Create.html was initially added on branch rt-1-1.
-       
-2000-12-09 22:43  jesse
-
-       * webrt/SelfService/Details.html:
-
-       file Details.html was initially added on branch rt-1-1.
-       
-2000-12-09 22:43  jesse
-
-       * webrt/SelfService/index.html:
-
-       file index.html was initially added on branch rt-1-1.
-       
-2000-12-09 22:43  jesse
-
-       * webrt/SelfService/Closed.html:
-
-       file Closed.html was initially added on branch rt-1-1.
-       
-2000-12-09 22:43  jesse
-
-       * webrt/Elements/SelectNewTicketQueue:
-
-       file SelectNewTicketQueue was initially added on branch rt-1-1.
-       
-2000-12-09 22:43  jesse
-
-       * webrt/Admin/Groups/Members.html:
-
-       file Members.html was initially added on branch rt-1-1.
-       
-2000-12-09 22:43  jesse
-
-       * webrt/Admin/Elements/SelectUsers:
-
-       file SelectUsers was initially added on branch rt-1-1.
-       
-2000-12-09 22:43  jesse
-
-       * lib/RT/CurrentUser.pm, lib/RT/Group.pm, lib/RT/GroupMember.pm,
-       lib/RT/Record.pm, lib/RT/User.pm, lib/RT/Users.pm,
-       webrt/Login.html, webrt/autohandler,
-       webrt/Admin/Elements/SelectModifyGroup,
-       webrt/Admin/Elements/SelectUsers, webrt/Admin/Groups/Members.html,
-       webrt/Admin/Groups/Modify.html, webrt/Admin/Groups/index.html,
-       webrt/Admin/Users/Modify.html, webrt/Admin/Users/index.html,
-       webrt/Elements/Header, webrt/Elements/SelectNewTicketQueue,
-       webrt/SelfService/Closed.html, webrt/SelfService/Create.html,
-       webrt/SelfService/Details.html, webrt/SelfService/index.html,
-       webrt/User/Prefs.html:
-
-       First rev of SSRI, the Self Service Requestor Interface.
-       Did a bunch of work on groups and the admin UI
-       
-2000-12-05 23:24  jesse
-
-       * webrt/Admin/Groups/Modify.html:
-
-       file Modify.html was initially added on branch rt-1-1.
-       
-2000-12-05 23:24  jesse
-
-       * webrt/Admin/Groups/index.html:
-
-       file index.html was initially added on branch rt-1-1.
-       
-2000-12-05 23:24  jesse
-
-       * webrt/Admin/Elements/SelectModifyGroup:
-
-       file SelectModifyGroup was initially added on branch rt-1-1.
-       
-2000-12-05 23:24  jesse
-
-       * lib/RT/Action/NotifyAsComment.pm:
-
-       file NotifyAsComment.pm was initially added on branch rt-1-1.
-       
-2000-12-05 23:24  jesse
-
-       * lib/RT/Group.pm, lib/RT/GroupMembers.pm, lib/RT/Scrip.pm,
-       lib/RT/Action/Notify.pm, lib/RT/Action/NotifyAsComment.pm,
-       lib/RT/Action/SendEmail.pm, tools/insertdata,
-       webrt/Admin/Elements/SelectModifyGroup,
-       webrt/Admin/Groups/Modify.html, webrt/Admin/Groups/index.html,
-       webrt/Admin/Queues/Modify.html, webrt/Admin/Queues/index.html:
-
-       Lots of work on groups. I think the core is basically set.  UI has been started
-       
-       Scrips got even more work and more code. they now work at least as well as
-       they ever have _and_ they now do it for the right reasons.
-       
-2000-12-02 13:44  jesse
-
-       * Makefile:
-
-       
-       fixed a local customization in the makefile
-       
-2000-12-02 13:34  jesse
-
-       * Makefile:
-
-       bumped version to 1.0.6
-       
-2000-12-02 03:22  jesse
-
-       * webrt/Ticket/Link.html:
-
-       file Link.html was initially added on branch rt-1-1.
-       
-2000-12-02 03:22  jesse
-
-       * lib/RT/Scrip.pm, lib/RT/ScripActions.pm, lib/RT/Scrips.pm,
-       webrt/Ticket/Link.html:
-
-       catching some stragglers.
-       
-2000-12-02 03:22  jesse
-
-       * lib/RT/ScripActions.pm:
-
-       file ScripActions.pm was initially added on branch rt-1-1.
-       
-2000-12-02 03:20  jesse
-
-       * webrt/Admin/Elements/SelectScripAction:
-
-       file SelectScripAction was initially added on branch rt-1-1.
-       
-2000-12-02 03:20  jesse
-
-       * webrt/Admin/Elements/SelectScripCondition:
-
-       file SelectScripCondition was initially added on branch rt-1-1.
-       
-2000-12-02 03:20  jesse
-
-       * lib/RT/: Action/Generic.pm, Condition/Generic.pm:
-
-       file Generic.pm was initially added on branch rt-1-1.
-       
-2000-12-02 03:20  jesse
-
-       * lib/RT/Condition/AnyTransaction.pm:
-
-       file AnyTransaction.pm was initially added on branch rt-1-1.
-       
-2000-12-02 03:20  jesse
-
-       * lib/RT/Condition/NewDependency.pm:
-
-       file NewDependency.pm was initially added on branch rt-1-1.
-       
-2000-12-02 03:20  jesse
-
-       * lib/RT/ScripAction.pm:
-
-       file ScripAction.pm was initially added on branch rt-1-1.
-       
-2000-12-02 03:20  jesse
-
-       * lib/RT/ScripCondition.pm:
-
-       file ScripCondition.pm was initially added on branch rt-1-1.
-       
-2000-12-02 03:20  jesse
-
-       * lib/RT/ScripConditions.pm:
-
-       file ScripConditions.pm was initially added on branch rt-1-1.
-       
-2000-12-02 03:20  jesse
-
-       * bin/webmux.pl, docs/design_docs/subscription-definitions.txt,
-       etc/schema.pm, lib/RT/Action.pm, lib/RT/Scrip.pm,
-       lib/RT/ScripAction.pm, lib/RT/ScripCondition.pm,
-       lib/RT/ScripConditions.pm, lib/RT/ScripScope.pm,
-       lib/RT/ScripScopes.pm, lib/RT/Scrips.pm, lib/RT/Transaction.pm,
-       lib/RT/Action/Generic.pm, lib/RT/Action/Notify.pm,
-       lib/RT/Action/OpenDependent.pm, lib/RT/Action/ResolveMembers.pm,
-       lib/RT/Action/SendEmail.pm, lib/RT/Action/SendEmailOnResolve.pm,
-       lib/RT/Action/StallDependent.pm,
-       lib/RT/Condition/AnyTransaction.pm, lib/RT/Condition/Generic.pm,
-       lib/RT/Condition/NewDependency.pm, tools/insertdata,
-       webrt/Admin/Elements/SelectScripAction,
-       webrt/Admin/Elements/SelectScripCondition:
-
-       Major major major work on scrips
-       scrips now specify a 'Stage' which has only one value for now but should be easier to add in other
-       points in the code where they get called
-       
-       What used to be called Scrip got split into ScripCondition and ScripAction
-       
-       ScripScope got renamed 'Scrip', like it should have been from the getgo.
-       
-       Did some work to the scrip mailing routines.All in all, scrips are much
-       cleaner and more flexible. and at least as functional as they were last night.
-       
-       I'll be adjusting the templates as I get to them
-       
-2000-12-01 14:02  jesse
-
-       * NEWS:
-
-       fixed a display bug in how we split messages for the webui
-       
-2000-11-30 02:18  jesse
-
-       * lib/RT/Action/AutoReply.pm, lib/RT/Action/SendEmail.pm,
-       tools/insertdata:
-
-       Working on cleaning up the Scrips system.  The whole templating system
-       was really, really incredibly overdesigned and badly implemented on the first go-round.
-       Over the next few checkins, I'll be cleaning it up and cleaning it out...
-       
-2000-11-29 16:31  jesse
-
-       * bin/testdeps.pl:
-
-       updated apache::session dependency
-       
-2000-11-29 01:32  jesse
-
-       * lib/RT/ACE.pm, lib/RT/ScripScope.pm, lib/RT/Ticket.pm,
-       lib/RT/Transaction.pm, lib/RT/User.pm, lib/RT/Action/AutoReply.pm,
-       lib/RT/Action/SendEmail.pm, lib/RT/Interface/Email.pm,
-       webrt/Admin/Elements/SelectScrip,
-       webrt/Admin/Elements/SelectTemplate,
-       webrt/Ticket/Create_Detail.html:
-
-       Work on scrips all around:
-               web ui cleanups
-               Action::SendEmail cleanups
-       
-       work on acls for Ticket creation.
-       now users who only have "CreateTicket" can actually create tickets,
-       even if they can't see the ticket once created.
-       RT1's "allow nonmembers to create requests" can be replicated by
-       granting  the metagroup 'requestors' the right "CreateTicket".
-       
-       Mail gateway got a lot of debugging stubs. mail gateway now uses
-       modern semantics for Create.
-       
-2000-11-28 17:46  jesse
-
-       * lib/RT/User.pm:
-
-       cacheed acl decisions are now properly granular.
-       
-2000-11-28 17:39  jesse
-
-       * lib/RT/User.pm:
-
-       Cached ACL decisions are now expire after 2 minutes.
-       
-2000-11-28 03:37  jesse
-
-       * etc/config.pm, lib/RT/Ticket.pm, webrt/Ticket/Update.html,
-       webrt/Ticket/Elements/ShowReferences,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       fixed a small bug in ticket update.
-       fixed a set of bugs in "external" links that were discovered when my roommate suggested
-       that RT could be used as an mp3 playlist server.  Now it can. no, you really don't want to.
-       At least until we have asset managment.
-       
-2000-11-28 00:20  jesse
-
-       * Makefile, lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       lib/RT/Action/SendEmail.pm:
-
-       a couple little tweask to transaction and sendemail.
-       
-       bumped the version #
-       
-2000-11-28 00:12  jesse
-
-       * webrt/Ticket/: Display.html, LinkIt.html, ProcessUpdate.html,
-       Update.html, Elements/ShowSummary, Elements/ShowTransaction,
-       Elements/TicketToolBox:
-
-       Work on cleaning up the web ui. got rid of processupdate.html.
-       cleaned up the code in display.html..  linking is no longer nearly as offensive.
-       
-2000-11-27 20:26  jesse
-
-       * webrt/Ticket/Elements/ShowRequestor:
-
-       small display fix to not show nobody as a possible requestor
-       
-2000-11-27 20:05  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/User.pm, webrt/Ticket/Display.html:
-
-       Updates to how Create handles Requestor, Cc and Admin Cc.
-       it's now much more flexible, cleaner and simpler. yay.
-       
-2000-11-27 04:01  jesse
-
-       * webrt/Elements/: Error, Header, MyRequests:
-
-       Web error reporting tweaks.
-       added MyRequests to the front page
-       
-2000-11-27 04:01  jesse
-
-       * webrt/Elements/MyRequests:
-
-       file MyRequests was initially added on branch rt-1-1.
-       
-2000-11-27 03:30  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/Interface/Web.pm,
-       webrt/Ticket/Display.html, webrt/Ticket/Elements/ShowHistory:
-
-       more work on ACLs
-       
-       Ticket.pm has been fully ACLed.
-       Did work on web ticket create.  it's no longer a festering pile of garbage.
-       Now it's more of an office wastepaper basket full of clean white 20lb paper.
-       Seriously, though, it's cleaner. I got rid of some of Tobias' temporary ticket creation
-       code.
-       
-2000-11-26 23:45  jesse
-
-       * lib/RT/ACE.pm, lib/RT/GroupMember.pm, lib/RT/Queue.pm,
-       lib/RT/Queues.pm, lib/RT/Template.pm, lib/RT/Ticket.pm,
-       lib/RT/User.pm, lib/RT/Interface/Web.pm, tools/insertdata,
-       webrt/Admin/Elements/ModifyQueue, webrt/Elements/Header,
-       webrt/Elements/Tabs:
-
-       
-       
-       lots more ACL work.
-       a little bit of UI cleanup.
-       
-2000-11-25 01:56  jesse
-
-       * lib/RT/Tickets.pm, webrt/index.html,
-       webrt/Ticket/Elements/ShowDates:
-
-       made "my requests" doable.
-       fixed some ui in showdates.
-       
-2000-11-24 20:14  jesse
-
-       * lib/RT/: Queue.pm, User.pm:
-
-       Fixed a couple of bugs in HasSystemRight that make RT install correctly again.
-       
-2000-11-24 19:21  jesse
-
-       * etc/schema.pm:
-
-       schema fix to make pg happy
-       
-2000-11-22 03:08  jesse
-
-       * webrt/Ticket/Update.html:
-
-       cleaned up the ticket udpdate form. made it more concise.::
-       
-2000-11-22 03:04  jesse
-
-       * webrt/Ticket/Update.html:
-
-       cleaning up the ticket update form
-       
-2000-11-22 02:49  jesse
-
-       * bin/testdeps.pl:
-
-       bumped searchbuilder dependency to the version now in CPAN...
-       
-2000-11-22 02:31  jesse
-
-       * Makefile, lib/RT/ACE.pm, lib/RT/ACL.pm, lib/RT/Action.pm,
-       lib/RT/Attachment.pm, lib/RT/Attachments.pm, lib/RT/CurrentUser.pm,
-       lib/RT/Date.pm, lib/RT/EasySearch.pm, lib/RT/Group.pm,
-       lib/RT/GroupMember.pm, lib/RT/GroupMembers.pm, lib/RT/Groups.pm,
-       lib/RT/Handle.pm, lib/RT/Link.pm, lib/RT/Links.pm, lib/RT/Queue.pm,
-       lib/RT/Queues.pm, lib/RT/Record.pm, lib/RT/Scrip.pm,
-       lib/RT/ScripScope.pm, lib/RT/ScripScopes.pm, lib/RT/Scrips.pm,
-       lib/RT/Template.pm, lib/RT/Templates.pm, lib/RT/Ticket.pm,
-       lib/RT/Tickets.pm, lib/RT/Transaction.pm, lib/RT/Transactions.pm,
-       lib/RT/User.pm, lib/RT/Users.pm, lib/RT/Utils.pm,
-       lib/RT/Watcher.pm, lib/RT/Watchers.pm:
-
-       Bumped version to 1.3.23
-       Added pod headers to most core modules?
-       
-2000-11-21 23:05  jesse
-
-       * webrt/Ticket/Elements/ShowSummary:
-
-       removed a dead link
-       
-2000-11-21 04:07  jesse
-
-       * Makefile, lib/RT/Queue.pm, lib/RT/Scrip.pm, lib/RT/ScripScope.pm,
-       lib/RT/Transaction.pm, lib/RT/User.pm:
-
-       tmp logfiles now go in /tmp
-       oh. and SCRIPS NOW WORK. RT can send mail.
-       and recieve mail. life is good.
-       
-2000-11-21 02:55  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Implemented Ticket->IsWatcher.
-       This is what we needed to make pseudogroup based ACLs work
-       
-2000-11-21 00:55  jesse
-
-       * lib/RT/Queue.pm, lib/RT/Ticket.pm, lib/RT/User.pm,
-       webrt/Elements/Tabs:
-
-       fixed a couple of bugs while I was out and about.
-       Oh. and most of the rest of the ACL core is implemented now.
-       rights for requestor/owner/cc/admincc should now work.
-       
-2000-11-20 11:59  jesse
-
-       * lib/RT/ACE.pm, lib/RT/User.pm, tools/insertdata:
-
-       Added "Requestor" and "Everyone" metagroups to tools/insertdata
-       
-       Fixed a bug with yet another way to call HasQueueRight.
-       
-2000-11-20 00:39  jesse
-
-       * Makefile:
-
-       bumped to 1.3.22 for release
-       
-2000-11-20 00:24  jesse
-
-       * webrt/Search/Listing.html:
-
-       fixed a big triggered when clearing empty ticket searches
-       
-2000-11-19 23:55  jesse
-
-       * bin/webmux.pl, lib/RT/User.pm:
-
-       fixed a bug that stopped you from specifying an owner on ticket create
-       Watcher and Watchers are now preloaded in the App server.
-       
-2000-11-19 23:20  jesse
-
-       * webrt/Ticket/Elements/Tabs:
-
-       file Tabs was initially added on branch rt-1-1.
-       
-2000-11-19 23:20  jesse
-
-       * webrt/: index.html, Admin/Elements/Tabs, Elements/Header,
-       Elements/Tabs, Search/Listing.html, Search/RestrictSearch.html,
-       Ticket/Create.html, Ticket/Create_Detail.html, Ticket/Display.html,
-       Ticket/EditWatchers.html, Ticket/Modify.html, Ticket/Update.html,
-       Ticket/Elements/Tabs:
-
-       more UI tweaking. yay.
-       
-2000-11-19 17:57  jesse
-
-       * webrt/Elements/Quicksearch:
-
-       file Quicksearch was initially added on branch rt-1-1.
-       
-2000-11-19 17:57  jesse
-
-       * webrt/Elements/MyTickets:
-
-       file MyTickets was initially added on branch rt-1-1.
-       
-2000-11-19 17:57  jesse
-
-       * webrt/rt.jpg:
-
-       file rt.jpg was initially added on branch rt-1-1.
-       
-2000-11-19 17:57  jesse
-
-       * lib/RT/ACE.pm, lib/RT/Ticket.pm, lib/RT/Tickets.pm,
-       lib/RT/Interface/Web.pm, webrt/index.html, webrt/rt.jpg,
-       webrt/Elements/MyTickets, webrt/Elements/Quicksearch,
-       webrt/Search/Listing.html:
-
-       A bunch of UI work. we now have a placeholder logo
-       
-2000-11-18 03:03  jesse
-
-       * lib/RT/: User.pm, Interface/Web.pm:
-
-       ACL  change messages are now properly scoped. so now they don't hang out
-       between sessions
-       
-       if a user has a system right, that right now applies to all queues.
-       
-2000-11-17 00:19  jesse
-
-       * Makefile:
-
-       Rolled rev 1.3.21. now with an ACL editor.
-       
-2000-11-17 00:15  jesse
-
-       * webrt/Admin/Elements/SelectRights:
-
-       file SelectRights was initially added on branch rt-1-1.
-       
-2000-11-17 00:15  jesse
-
-       * lib/RT/ACE.pm, lib/RT/Group.pm, lib/RT/Queue.pm,
-       lib/RT/Template.pm, lib/RT/Ticket.pm, lib/RT/User.pm,
-       lib/RT/Interface/Web.pm, webrt/Admin/Elements/SelectRights:
-
-       Woo! the ACL editor is now much cleaner. and it works. :)
-       
-2000-11-16 01:17  jesse
-
-       * lib/RT/: ACE.pm, ACL.pm, Attachment.pm, Attachments.pm,
-       CurrentUser.pm, EasySearch.pm, Group.pm, GroupMember.pm,
-       GroupMembers.pm, Groups.pm, Link.pm, Links.pm, Queue.pm, Queues.pm,
-       Record.pm, Scrip.pm, ScripScope.pm, ScripScopes.pm, Scrips.pm,
-       Template.pm, Templates.pm, Ticket.pm, Transaction.pm,
-       Transactions.pm, User.pm, Users.pm, Watcher.pm, Watchers.pm,
-       Interface/Web.pm:
-
-       
-       LEANED UP A WHOLE BUNCH OF NEW ROUTINES. FIXED A FREW ACL BUGS.
-       
-2000-11-15 02:29  jesse
-
-       * lib/RT/ACE.pm, lib/RT/ACL.pm, lib/RT/CurrentUser.pm,
-       lib/RT/Queue.pm, lib/RT/Ticket.pm, lib/RT/User.pm,
-       webrt/Admin/Elements/Tabs, webrt/Elements/Submit:
-
-       refactored ACLS to take out a layer of complexity or two.
-       
-2000-11-14 13:17  jesse
-
-       * Makefile:
-
-       bumped the makefuile version
-       
-2000-11-13 23:19  jesse
-
-       * bin/webmux.pl, lib/RT/ACL.pm, lib/RT/EasySearch.pm,
-       lib/RT/Group.pm, lib/RT/GroupMember.pm, lib/RT/Record.pm,
-       lib/RT/User.pm:
-
-       A bunch of refactoring to make ACL editable. Lots of work on the ACL editor.
-       Basic user ACLs are now editable.
-       It needs some more refactoring, since I stopped being on quite as much crack
-       over the wekeend and figured out a much less intense way to do a bunch of stuff. Yay.
-       
-2000-11-08 14:55  jesse
-
-       * Makefile, NEWS:
-
-       all mail sent out is now sent out precedence "bulk" like it should be.
-       
-2000-11-08 01:24  jesse
-
-       * webrt/Admin/Elements/SelectScrip:
-
-       file SelectScrip was initially added on branch rt-1-1.
-       
-2000-11-08 01:24  jesse
-
-       * webrt/Admin/Elements/SelectTemplate:
-
-       file SelectTemplate was initially added on branch rt-1-1.
-       
-2000-11-08 01:24  jesse
-
-       * etc/schema.pm, lib/RT/ACE.pm, lib/RT/ACL.pm,
-       lib/RT/CurrentUser.pm, lib/RT/Group.pm, lib/RT/Ticket.pm,
-       lib/RT/Tickets.pm, lib/RT/Transaction.pm, lib/RT/User.pm,
-       lib/RT/Users.pm, tools/insertdata,
-       webrt/Admin/Elements/SelectScrip,
-       webrt/Admin/Elements/SelectTemplate:
-
-       A whole slew of work on ACLs and assorted other related things.
-       This involved a lot of cleanup of ACL related code and things it touched.
-       ACL decisions are now being made. (Yes, you're all still superusers) but I
-       think I've got a bunch of the infrastructure cleaned up, so it should be
-       easier to finish off the ACL editor. yay!
-       
-       As part of this, I had to add more groups support. all you groups-maniacs should be pleased ;)
-       
-2000-11-06 11:55  jesse
-
-       * Makefile:
-
-       Fixed yet another typo in manipulate.pm.
-       
-       Bumped version to 1.0.5
-       
-2000-11-05 15:24  jesse
-
-       * Makefile:
-
-       A fix for action vs actions in mail manipulate.
-       fixed a typo normailize -> normalize in database/manipulate.pm
-       
-2000-11-03 17:54  jesse
-
-       * README, etc/schema.pm, lib/RT/ACE.pm, lib/RT/ACL.pm,
-       lib/RT/CurrentUser.pm, lib/RT/GroupMember.pm, lib/RT/Queue.pm,
-       lib/RT/Ticket.pm, lib/RT/User.pm, lib/RT/Users.pm,
-       lib/RT/Interface/Email.pm, lib/RT/Interface/Web.pm,
-       tools/insertdata, webrt/Admin/ModifyUser,
-       webrt/Admin/Elements/QueueRightsForUser, webrt/Admin/Elements/Tabs,
-       webrt/Elements/SelectOwner:
-
-       A bunch of work on the ACLs. we're getting closer to having a workable ACL
-       editor.
-       
-2000-11-03 15:37  jesse
-
-       * Makefile, NEWS:
-
-       We now deal better with merging merged tickets.
-       
-       We now properly ignore Precedence: {junk|bulk} headers
-       
-2000-10-31 00:06  jesse
-
-       * lib/RT/: ACE.pm, ScripScope.pm:
-
-       Added ACL support to the ScripScope system.
-       
-2000-10-29 21:31  jesse
-
-       * Makefile, README, bin/webmux.pl, lib/RT/ACE.pm, lib/RT/Group.pm,
-       lib/RT/Groups.pm, lib/RT/Queue.pm, lib/RT/ScripScope.pm,
-       lib/RT/ScripScopes.pm, lib/RT/Scrips.pm, lib/RT/Template.pm,
-       lib/RT/Templates.pm, lib/RT/Transaction.pm, tools/insertdata:
-
-       A bunch of hacking to the ScripScopes system.
-       
-       You can now edit scrips for a given queue.
-       but hey, scrips have no ACL checking yet.
-       
-2000-10-29 17:51  jesse
-
-       * etc/schema.pm:
-
-       Added a whole lot of documentation to schema.pm.
-       
-2000-10-25 21:09  jesse
-
-       * Makefile, bin/testdeps.pl, etc/schema.pm:
-
-       Updated schema.pm and testdeps to jibe with the current CPAN versions of things.
-       And I bumped the version to 1.3.20
-       
-2000-10-23 16:53  jesse
-
-       * Makefile, lib/RT/Date.pm:
-
-       Reverted to using mysql by default.
-       Finished off the postgresql support in the rt core. (well, at least finished the initial support)
-       
-2000-10-23 16:35  jesse
-
-       * Makefile, lib/RT/ACE.pm, lib/RT/Ticket.pm, tools/insertdata:
-
-       Cleanups related to making postgres support work right.
-       
-2000-10-22 20:57  jesse
-
-       * Makefile, bin/initacls.Pg, bin/testdeps.pl, etc/acl.Pg,
-       etc/config.pm, etc/schema.pm, lib/RT/Link.pm, lib/RT/Ticket.pm,
-       lib/RT/Tickets.pm, tools/initdb, tools/insertdata,
-       webrt/Ticket/Display.html:
-
-       merged in ivan's postgres patches.
-       made local ticket links work again. *sigh* SQL evil. eeeeevil.
-       
-2000-10-16 16:32  jesse
-
-       * docs/Security:
-
-       file Security was initially added on branch rt-1-1.
-       
-2000-10-16 16:32  jesse
-
-       * docs/Security:
-
-       some initial notes on security. targetted at RT admins.
-       
-2000-10-16 03:01  jesse
-
-       * lib/RT/: Link.pm, Links.pm, Ticket.pm:
-
-       Fixed a couple of typos in link and links.
-       Ticket->Load will now do the right hting with ticket uris or aliases.
-       
-2000-10-16 00:47  jesse
-
-       * etc/config.pm, lib/RT/Link.pm, lib/RT/Links.pm, lib/RT/Ticket.pm:
-
-       The linking interface now uses URIs internally. and it does lots of
-       sanity checking.
-       
-       Tickets now understand what their uris should be. you can load tickets by
-       uri. and by alias.
-       
-       We need a bit more work to make alias support just transparent, but we're
-       getting really close.
-       
-       You shouldn't be able to link to nonexistent local objects any mroe.
-       
-2000-10-15 01:57  jesse
-
-       * lib/RT/CurrentUser.pm:
-
-       Added CurrentUser->LoadByGecos.
-       The CLI now uses LoadByGecos to load the currentuser.
-       This means that users other than root might actually be able to use the cli now
-       VS: ----------------------------------------------------------------------
-       
-2000-10-15 01:11  jesse
-
-       * Makefile:
-
-       Significantly redid the installation procedure. we're now _much_
-       more careful about what gets installed where and what's owned by whom.
-       
-       Oh. and RT's now setgid, rather than setuid. and there's no setuid wrapper anymore
-       
-2000-10-15 01:08  jesse
-
-       * etc/: config.pm, suidrt.c:
-
-       Yanked suidrt.c, since we now run setgid.
-       
-       rt now logs to /tmp/rt.log.pid.userid
-       
-2000-10-14 02:56  jesse
-
-       * bin/rtmux.pl, bin/webmux.pl, etc/schema.pm,
-       lib/RT/CurrentUser.pm, lib/RT/Interface/Email.pm, tools/initdb,
-       tools/insertdata:
-
-       CurrentUser.pm had LoadByEmail and LoadByUserId methods added and they're now
-       actually used most everywhere.
-       
-       insertdata doesn't force ids for users now.
-       
-       the schema now actually enforces a lot of important uniqueness constraints.
-       
-2000-10-13 10:59  jesse
-
-       * etc/schema.mysql:
-
-       Removed the old schema.mysql, lest it lead people astray
-       
-2000-10-13 02:27  jesse
-
-       * webrt/Ticket/Elements/: EditPeople, ShowMembers:
-
-       Removed some old warning text that's not true any more.
-       Fixed a relative url problem in "show memebers"
-       
-2000-10-12 23:22  jesse
-
-       * Makefile, bin/testdeps.pl:
-
-       updated testdeps.
-       Makefile now defaults to installing rt2 in /opt/rt2
-       
-2000-10-12 22:54  jesse
-
-       * Makefile, lib/RT/ACL.pm, lib/RT/Queue.pm, lib/RT/Ticket.pm,
-       lib/RT/User.pm, lib/RT/Users.pm, tools/insertdata,
-       webrt/index.html:
-
-       A couple of links on the front page.
-       Makefile now assumes www-data instead of nobody as the web user. this is not quite right.
-       
-       Fixed a little bit of the POD in User.pm.
-       
-       Redid how Ticket.pm deals with Owner on create. the new logic should actually catch errors
-       instead of easily letting referential integrity checks just _fail_.
-       
-       Insertdata got cleaned up a little bit.
-       
-       ACL got its cleaned up a bit
-       
-2000-10-11 23:22  jesse
-
-       * webrt/Admin/Elements/QueueRightsForUser:
-
-       file QueueRightsForUser was initially added on branch rt-1-1.
-       
-2000-10-11 23:22  jesse
-
-       * lib/RT/Users.pm, webrt/Admin/Elements/QueueRightsForUser:
-
-       Work on ACLs. and the ACL editor
-       
-2000-10-11 21:23  jesse
-
-       * tools/insertdata:
-
-       gave root a password
-       
-2000-10-11 12:28  jesse
-
-       * Makefile, tools/initdb:
-
-       Databasename changed from RT2 to rt2 to make postgres happier.
-       
-       initdb quoting bug fixed.
-       
-       debug mode in initdb turned off.
-       
-       If you're using mysql and running with ivan's current CVS version of DBIx::DBSchema, RT should once again work.
-       
-2000-10-09 02:32  jesse
-
-       * etc/schema.pm, tools/initdb:
-
-       a debugging hook in initdb and defaults (though they don't work just right yet)
-       in schema.pm. Note that we now need DBIx::DBSchema from CVS.
-       
-2000-10-09 01:59  jesse
-
-       * Makefile, NEWS, etc/suidrt.c:
-
-       Jan Kujawa fixed a bug in the setuid wrapper
-       Jan Okrouhly fixed some bugs in the merged ticket resolution in the cli.
-       
-       Rolled 1.0.5pre3
-       
-2000-10-05 17:30  jesse
-
-       * lib/RT/: ACE.pm, ACL.pm:
-
-       more work on RT's acl core
-       
-2000-10-05 17:30  jesse
-
-       * webrt/Admin/Elements/: GrantQueueRightsTo, GrantQueueRightsTo~,
-       SelectQueueRights:
-
-       more acl work
-       
-2000-10-05 17:30  jesse
-
-       * webrt/Admin/Elements/GrantQueueRightsTo~:
-
-       file GrantQueueRightsTo~ was initially added on branch rt-1-1.
-       
-2000-10-05 17:30  jesse
-
-       * webrt/Admin/Elements/GrantQueueRightsTo:
-
-       file GrantQueueRightsTo was initially added on branch rt-1-1.
-       
-2000-10-05 17:30  jesse
-
-       * webrt/Admin/Elements/SelectQueueRights:
-
-       file SelectQueueRights was initially added on branch rt-1-1.
-       
-2000-10-05 15:49  jesse
-
-       * etc/suidrt.c:
-
-       reordering things in suidrt.c seemed to make them happier.
-       
-2000-10-05 15:39  jesse
-
-       * etc/suidrt.c:
-
-       missed a comma
-       
-2000-10-05 15:03  jesse
-
-       * bin/testdeps.pl:
-
-       added a dependency test script to make installation by newbies easier.
-       
-2000-10-05 15:03  jesse
-
-       * Makefile, README, etc/suidrt.c:
-
-       Major rewrite of suidrt.c by jan kujawa.
-       A couple of bugfixes from Jan Okrouhly
-               Public history should now work right in the cli
-               Web viewing of merged tickets by their old # should now work better.
-       
-2000-10-03 20:22  jesse
-
-       * bin/testdeps.pl:
-
-       cleaned up testedeps.pl output
-       
-2000-10-03 02:41  jesse
-
-       * tools/insertdata:
-
-       file insertdata was initially added on branch rt-1-1.
-       
-2000-10-03 02:41  jesse
-
-       * tools/initdb:
-
-       file initdb was initially added on branch rt-1-1.
-       
-2000-10-03 02:41  jesse
-
-       * etc/schema.pm:
-
-       file schema.pm was initially added on branch rt-1-1.
-       
-2000-10-03 02:41  jesse
-
-       * Makefile, bin/initdb.Oracle, bin/initdb.Pg, bin/initdb.mysql,
-       bin/testdeps.pl, etc/schema.Pg, etc/schema.pm, lib/RT/ACE.pm,
-       lib/RT/Queue.pm, lib/RT/Scrip.pm, lib/RT/User.pm, tools/initdb,
-       tools/insertdata:
-
-       Fairly massive installation changes.
-               We now use ivan's really cool DBIx::DBschema, which, when things
-       settle out a bit mean that the oracle and postgres (and possibly other) ports
-       get their schema updated automatically.
-       
-       The initial seed data is now inserted by tools/insertdata through the RT API.
-       
-       ACE::Create now actually works.
-       Same with Scrip::Create.
-       and Queue::Create.
-       
-       There are a couple of new installation-only dependencies. One of them (DBSchema) may become a build-only
-       dependency if people whine enough :)
-       
-       date/time handling was a casualty of the changes. some things will be handled oddly for now.
-       Once Ivan releases the next DBSchema update, this should get better again. it was
-       the result of a namespace collision between pg and mysql. the timestamp column has
-       different behavior. go fig.
-       
-       This version will require DBIx::SearchBuilder 0.06 (aka what I'm about to check in)
-       
-2000-10-03 02:07  jesse
-
-       * tools/test:
-
-       blew away old, crufty "extras"
-       
-2000-09-28 13:55  jesse
-
-       * lib/RT/Group.pm:
-
-       file Group.pm was initially added on branch rt-1-1.
-       
-2000-09-28 13:55  jesse
-
-       * lib/RT/: Group.pm, GroupMember.pm, GroupMembers.pm, Groups.pm:
-
-       Long overdue adding of completely untested (and unused) code for groups in RT.
-       note that this implementation does not assume recursive group membership
-       
-2000-09-28 13:55  jesse
-
-       * lib/RT/GroupMember.pm:
-
-       file GroupMember.pm was initially added on branch rt-1-1.
-       
-2000-09-28 13:55  jesse
-
-       * lib/RT/GroupMembers.pm:
-
-       file GroupMembers.pm was initially added on branch rt-1-1.
-       
-2000-09-28 13:55  jesse
-
-       * lib/RT/Groups.pm:
-
-       file Groups.pm was initially added on branch rt-1-1.
-       
-2000-09-18 01:57  jesse
-
-       * lib/RT/: ACE.pm, Queue.pm, Ticket.pm:
-
-       Lots of work on Queue.pm  Most cleanups related to queue watchers, but I
-       also added a bit more documentation and fixed a bug that could cause DelWatcher
-       in ticket.pm to delete watchers it shouldn't
-       
-2000-09-18 00:03  jesse
-
-       * docs/API, docs/FAQ, docs/README.oracle, lib/RT/Ticket.pm,
-       lib/RT/Transaction.pm:
-
-       More documentation. removed outdated docs.
-       
-       docs/API now talks about what those of you writing your own RT client
-       code shouldn't be doing. (Which objects you shouldn't touch).
-       
-2000-09-18 00:00  jesse
-
-       * README:
-
-       Clarified license terms. RT is available under Version 2 of the GPL.
-       Not version 1. Not some as-yet-unwritten version 3 that says you can only
-       use it if you agree to license your children under the GPL. Version 2.
-       
-2000-09-17 19:57  jesse
-
-       * lib/RT/: TicketCollection.pm, User.pm, Interface/Email.pm:
-
-       Removed bogus signature code.
-       Documented User->IsPassword
-       removed --area flag from Mailgateway (We ain't got no stinking areas)
-       
-2000-09-17 19:21  jesse
-
-       * etc/schema.Oracle, etc/schema.mysql, lib/RT/ACE.pm,
-       lib/RT/ACL.pm, lib/RT/Scrip.pm, lib/RT/User.pm:
-
-       Ugh. Mysql isn't respecting SQL92 reserved words. which meant that I didn't
-       notice that I was using "Type" and "Action" in my schema.
-       This required a bit of churn to the ACE and User modules.
-       
-2000-09-17 17:38  jesse
-
-       * Makefile:
-
-       Ok. I think I've got it now. This is RT 1.3.18. aka RT2 - Alpha 1.
-               The "Bear Suit" Release.
-       
-               A formal release announcement is forthcoming.
-       
-2000-09-17 17:29  jesse
-
-       * Makefile:
-
-       work on the changelog generator
-       
-2000-09-17 17:19  jesse
-
-       * HACKING, Makefile, README, bin/initdb.mysql, bin/testdeps.pl:
-
-       Bumped the required version of SearchBuilder in testdeps, now that it's
-       propagated throughout CPAN
-       
-       Replaced initdb.mysql with ivan's new version.
-       
-       Tweaked ivan's initdb.mysql to be a little friendlier, create the schema
-       (it was missing a FILEHANDLE in a print statement and deal
-       better with omitted passwords.
-       
-       Updated the readme some more.
-       
-       Added experimental ChangeLog generation to the make dist process
-       
-       Bumped the version number to 1.3.18 for release as alpha1 for RT2 today.
-       
-2000-09-17 01:40  jesse
-
-       * Makefile, README, bin/initacls.mysql, bin/testdeps.pl,
-       bin/webmux.pl:
-
-       Bumped the Mason version requirement up, so we avoid the poisoned v 0.88
-       Applied ivan's alpha-1 patches.
-       Did some tweaking for the alpha 1 release.
-       Cleaned up the readme a bit
-       
-2000-09-15 01:21  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-2000-09-15 01:17  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       Mail gateway now handles followup correspondence properly
-       (It gets the ticket # right)
-       
-2000-09-15 01:06  jesse
-
-       * lib/RT/Watcher.pm:
-
-       fixed a typo (left off a > ) in Watcher.pm
-       
-2000-09-15 00:59  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/Watcher.pm, webrt/Ticket/Modify.html:
-
-       Editing ticket watchers from the webui now works.
-       this required a bunch of work on the internal wathers stuff
-       in ticket.pm.
-       Also added documentation and watcher-related sanity checks
-       
-2000-09-14 00:04  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/Watcher.pm,
-       webrt/Elements/SelectWatcherType, webrt/Ticket/Elements/EditPeople,
-       webrt/Ticket/Elements/EditWatchers,
-       webrt/Ticket/Elements/ModifyTicket:
-
-       Some cleanup to Watcher and Ticket. (mainly documentation updates)
-       Added an IsUser sub to Watcher.pm (which tells you if the watcher
-       object refers to a local user or a remote email address)
-       
-       the ui for editing tickets should work now.
-       note that the backend for the watchers side of this isn't there
-       yet.
-       
-               -j
-       
-2000-09-13 18:10  jesse
-
-       * etc/config.pm:
-
-       fixed a configfile typo that would break a new installation
-       
-2000-09-12 01:28  jesse
-
-       * lib/RT/Date.pm, lib/RT/Ticket.pm, webrt/Elements/ListActions,
-       webrt/Elements/SelectDate, webrt/Elements/SelectUsers,
-       webrt/Elements/SelectWatcherType, webrt/Ticket/Modify.html,
-       webrt/Ticket/Elements/AddWatchers, webrt/Ticket/Elements/EditDates,
-       webrt/Ticket/Elements/EditPeople,
-       webrt/Ticket/Elements/ModifyTicket:
-
-       TimeWorked is now read/write (which may be a bad idea. but I'm willing to try it.
-       RT::Date now better understands that "never" doesn't mean 1970.
-       
-       The web modify interface is getting closer to working.
-       I mainly need to finish making the watchers column go.
-       
-2000-09-11 00:37  jesse
-
-       * etc/config.pm:
-
-       Some sanity cleanups to the web queue listing.
-       
-2000-09-11 00:35  jesse
-
-       * webrt/Ticket/Elements/EditDates:
-
-       file EditDates was initially added on branch rt-1-1.
-       
-2000-09-11 00:35  jesse
-
-       * webrt/Ticket/Elements/EditWatchers:
-
-       file EditWatchers was initially added on branch rt-1-1.
-       
-2000-09-11 00:35  jesse
-
-       * webrt/Ticket/Elements/AddWatchers:
-
-       file AddWatchers was initially added on branch rt-1-1.
-       
-2000-09-11 00:35  jesse
-
-       * webrt/Ticket/Elements/EditBasics:
-
-       file EditBasics was initially added on branch rt-1-1.
-       
-2000-09-11 00:35  jesse
-
-       * webrt/Ticket/Elements/EditPeople:
-
-       file EditPeople was initially added on branch rt-1-1.
-       
-2000-09-11 00:35  jesse
-
-       * webrt/Ticket/Elements/ModifyTicket:
-
-       file ModifyTicket was initially added on branch rt-1-1.
-       
-2000-09-11 00:35  jesse
-
-       * webrt/: Login.html, webrt.css, Elements/SelectDate,
-       Elements/SelectMatch, Elements/SelectQueue, Elements/SelectUsers,
-       Elements/ShadedBox, Ticket/EditWatchers.html, Ticket/Modify.html,
-       Ticket/Elements/AddWatchers, Ticket/Elements/EditBasics,
-       Ticket/Elements/EditDates, Ticket/Elements/EditPeople,
-       Ticket/Elements/EditWatcherList, Ticket/Elements/EditWatchers,
-       Ticket/Elements/ModifyTicket, Ticket/Elements/ShowBasics,
-       Ticket/Elements/ShowDates, Ticket/Elements/ShowDependencies,
-       Ticket/Elements/ShowHistory, Ticket/Elements/ShowPeople,
-       Ticket/Elements/ShowSummary, Ticket/Elements/TicketToolBox:
-
-       Lots and lots of work on the webui.
-       The display UI has been cleaned up a bit and the modify UI has been started.
-       It's not in its final for yet, nor is there any logic backing many of the new ui features, but those will come next.
-       
-       If I'm remebering my list correctly, this is the one "biggie" before Alpha 1.
-       
-       Yay!
-       
-2000-09-11 00:35  jesse
-
-       * webrt/Elements/SelectUsers:
-
-       file SelectUsers was initially added on branch rt-1-1.
-       
-2000-09-07 00:52  jesse
-
-       * webrt/: Login.html, autohandler, Ticket/Elements/ShowSummary:
-
-       Replaced tobias' web arg preservation code with something that's actually based on _mason_ rather than the external apache object. This should make the fastcgi port easier
-       
-       Fixed a bug in showsummary (unqualified WebPath)
-       
-2000-09-07 00:30  jesse
-
-       * Makefile, bin/rtmux.pl, lib/RT/Handle.pm:
-
-       Look ma! it should install again (i'd flubbed a bit of the
-       fastcgi mason handler install.
-       
-       Oh. and oracle support should work now.
-       
-2000-09-06 00:52  jesse
-
-       * webrt/Logout.html:
-
-       Logout.html links you to the right place now
-       
-2000-09-05 23:47  jesse
-
-       * webrt/Search/Listing.html:
-
-       YA typo fix
-       
-2000-09-05 23:45  jesse
-
-       * webrt/Search/Listing.html:
-
-       Damn I wish I could type tonight. :/ missed an $RT::
-       
-2000-09-05 23:43  jesse
-
-       * webrt/: Search/Listing.html, Ticket/Elements/ShowSummary:
-
-       Fixed a few more Absolute url bugs
-       
-2000-09-05 23:35  jesse
-
-       * webrt/Elements/Tabs:
-
-       Tabs needed / as the final character for transparent proxying
-       
-2000-09-05 22:39  jesse
-
-       * webrt/: Login.html, Admin/Elements/CreateUserCalled,
-       Admin/Elements/ModifyQueue, Admin/Elements/ModifyTemplate,
-       Admin/Elements/ModifyUser, Admin/Users/index.html:
-
-       more work on proper absolute pathing
-       
-2000-09-05 22:08  jesse
-
-       * webrt/: Login.html, Admin/Elements/CreateQueueCalled,
-       Admin/Elements/CreateUserCalled, Admin/Elements/ModifyUser,
-       Admin/Users/index.html:
-
-       A bunch of the admin tools weren't properly dealing with absolute pathed requests. it made it impossible to have RT2 anywhere other than at the / of your webserver
-       
-2000-09-05 21:40  jesse
-
-       * lib/RT/Handle.pm:
-
-       file Handle.pm was initially added on branch rt-1-1.
-       
-2000-09-05 21:40  jesse
-
-       * bin/mason_handler.fcgi:
-
-       file mason_handler.fcgi was initially added on branch rt-1-1.
-       
-2000-09-05 21:40  jesse
-
-       * Makefile, bin/mason_handler.fcgi, bin/testdeps.pl,
-       lib/RT/Handle.pm:
-
-       Updated testdeps to ask for the new version of mailtools
-       Added in the new fastcgi handler (not working yet)
-       and RT::Handle, which is a wrapper for SearchBuilder::Handle
-       
-2000-09-04 22:52  jesse
-
-       * Makefile, TODO, bin/rtmux.pl, bin/webmux.pl, etc/config.pm,
-       lib/RT/Record.pm, lib/RT/User.pm, lib/RT/Interface/Web.pm,
-       webrt/Ticket/Display.html, webrt/Ticket/Elements/ShowRequestor,
-       webrt/Ticket/Elements/TicketToolBox:
-
-       A couple of bugfixes related to the switch to SearchBuilder.
-       A few webui cleanups.
-       A bit of abstraction to make the eventual fastcgi port easier.
-       
-2000-09-04 12:48  jesse
-
-       * bin/testdeps.pl, lib/RT/Attachments.pm, lib/RT/Ticket.pm,
-       lib/RT/Transaction.pm, lib/RT/Watcher.pm, lib/RT/Watchers.pm,
-       lib/RT/Interface/Web.pm, webrt/Ticket/Elements/ShowDates:
-
-       Several batched updates from when pallas was off-net
-       
-       UpdateTold changed to SetTold.
-       A bunch of work to get Scrips working.
-       Lots more POD in Ticket.pm
-       Transaction->Describe  is better about printing what really happened.
-       Attachments.pm had a typo that prevented it from dealing with multipart messages.
-       
-2000-08-31 02:18  jesse
-
-       * Makefile, NEWS, etc/suidrt.c:
-
-       Added ENV squashing to suidrt.c
-       
-2000-08-30 14:46  jesse
-
-       * bin/rtmux.pl:
-
-       Rolling in some oracle changes...they're not done yet, but nothing should
-       break with mysql. fixed a typo in rtmux.pl that was introduced with the switch to searchbuilder.
-       
-2000-08-29 17:02  jesse
-
-       * README, bin/rtmux.pl, bin/testdeps.pl, bin/webmux.pl,
-       lib/RT/EasySearch.pm, lib/RT/Record.pm:
-
-       MAJOR CHANGE: Switched to the new name of the DBIx:: modules.
-       We now use DBIx::SearchBuilder rather than DBIx::EasySearch and friends.
-       Note that this is only a name and structure change for the module set.
-       The functionality is the same...though seperating out oracle and mysql
-       specific features comes soon.
-       
-2000-08-29 16:57  jesse
-
-       * etc/schema.Oracle:
-
-       updated the schema.Oracle
-       
-2000-08-29 02:02  jesse
-
-       * webrt/: Elements/SelectWatcherType, Ticket/EditWatchers.html,
-       Ticket/Update.html:
-
-       Started hacking on watchers and ticket update webui a bit.
-       they need a lot more work
-       
-2000-08-29 01:51  jesse
-
-       * webrt/Ticket/: Display.html, DisplayHistory, DisplayTransaction,
-       Elements/ShowHistory, Elements/ShowTransaction:
-
-       Made FullHeaders/BriefHeaders work in the webui
-       
-2000-08-28 01:46  jesse
-
-       * webrt/Admin/Elements/: CreateUserCalled, ModifyUser:
-
-       Fixed some display buglets from tobi oetiker
-       
-2000-08-28 01:31  jesse
-
-       * webrt/Ticket/Update.html:
-
-       Removed some text that harassed the user. that's generally bad policy
-       
-2000-08-27 23:56  jesse
-
-       * webrt/: Admin/Elements/Header, Admin/Elements/ModifyTemplate,
-       Admin/Elements/Tabs, Elements/ListActions, Elements/Tabs:
-
-       A few more added helper elements from the webui
-       
-2000-08-27 23:56  jesse
-
-       * webrt/Admin/Elements/Header:
-
-       file Header was initially added on branch rt-1-1.
-       
-2000-08-27 23:56  jesse
-
-       * webrt/: Admin/Elements/Tabs, Elements/Tabs:
-
-       file Tabs was initially added on branch rt-1-1.
-       
-2000-08-27 23:56  jesse
-
-       * webrt/Admin/Elements/ModifyTemplate:
-
-       file ModifyTemplate was initially added on branch rt-1-1.
-       
-2000-08-27 23:56  jesse
-
-       * webrt/Elements/ListActions:
-
-       file ListActions was initially added on branch rt-1-1.
-       
-2000-08-27 23:54  jesse
-
-       * webrt/Admin/Users/Prefs.html:
-
-       file Prefs.html was initially added on branch rt-1-1.
-       
-2000-08-27 23:54  jesse
-
-       * webrt/Admin/: Queues/Create.html, Users/Create.html:
-
-       file Create.html was initially added on branch rt-1-1.
-       
-2000-08-27 23:54  jesse
-
-       * webrt/Admin/: Queues/Modify.html, Users/Modify.html:
-
-       file Modify.html was initially added on branch rt-1-1.
-       
-2000-08-27 23:54  jesse
-
-       * webrt/Admin/: Queues/index.html, Users/index.html:
-
-       file index.html was initially added on branch rt-1-1.
-       
-2000-08-27 23:54  jesse
-
-       * bin/webmux.pl, lib/RT/Area.pm, lib/RT/Areas.pm, lib/RT/Queue.pm,
-       lib/RT/ScripScopes.pm, lib/RT/Template.pm, lib/RT/Templates.pm,
-       webrt/Admin/CreateQueue.html, webrt/Admin/CreateUser.html,
-       webrt/Admin/EditUser.html, webrt/Admin/ModifyQueue.html,
-       webrt/Admin/ModifyUser.html, webrt/Admin/index.html,
-       webrt/Admin/Elements/CreateQueueCalled,
-       webrt/Admin/Elements/CreateUserCalled,
-       webrt/Admin/Elements/ModifyQueue, webrt/Admin/Elements/ModifyUser,
-       webrt/Admin/Elements/SelectModifyQueue,
-       webrt/Admin/Elements/SelectModifyUser,
-       webrt/Admin/Queues/Create.html, webrt/Admin/Queues/Modify.html,
-       webrt/Admin/Queues/index.html, webrt/Admin/Users/Create.html,
-       webrt/Admin/Users/Modify.html, webrt/Admin/Users/Prefs.html,
-       webrt/Admin/Users/index.html:
-
-       Lots of work on the web admin ui. basic user and queue editing working.
-       and template editing
-       
-2000-08-24 15:53  jesse
-
-       * Makefile, README, bin/rtmux.pl, etc/config.pm,
-       lib/RT/Action/SendEmail.pm, webrt/Elements/Footer,
-       webrt/Elements/Header, webrt/Elements/ViewUser,
-       webrt/Ticket/Elements/EditWatcherList:
-
-       The first cut at better configuration.
-       
-       Updated the readme
-       
-       Made the mail send routine in lib/RT/Action/Email.pm somewhat
-       more configurable (though we're still using printing to a pipe
-       because Mail::Mailer is busted :/)
-       
-       Most options moved out of the makefile..this will make packaging
-       possible.
-       
-       Fixed a couple places where tobias had been using a non-relative
-       url unnecessarily.
-       
-2000-08-22 03:08  jesse
-
-       * Makefile:
-
-       Getting version #s in sync for RT 1.3.15
-       
-2000-08-22 03:05  jesse
-
-       * lib/RT/: Scrip.pm, Transaction.pm, Action/AutoReply.pm,
-       Action/SendEmail.pm:
-
-       Work on making sure mail gets sent. It's not "right" yet but it's getting
-       closer.
-       
-2000-08-21 19:46  jesse
-
-       * webrt/autohandler:
-
-       Fixed a minor issue that let people "log in as ''"
-       
-2000-08-21 01:12  jesse
-
-       * bin/rtmux.pl, etc/config.pm, lib/RT/Ticket.pm, lib/RT/Tickets.pm:
-
-       Set a default type in ticket.pm
-       allowed restriction based on type in tickets.pm
-       
-       now set the timezone in the config file rather than the rtmux.
-       means it effects webmux.pl too.
-       
-2000-08-20 23:41  jesse
-
-       * etc/schema.mysql, lib/RT/Date.pm, webrt/Elements/SelectOwner:
-
-       Standardized StartsBy to Starts.
-       Removed a warning from SelectOwner
-       Fixed a bug in RT::Date->Set(Format => 'unknown')
-       
-2000-08-20 01:46  jesse
-
-       * lib/RT/Ticket.pm, webrt/Search/Listing.html,
-       webrt/Ticket/Elements/ShowMemberOf,
-       webrt/Ticket/Elements/ShowMembers:
-
-       Work on MemberOf and Members in Ticket.pm
-       they're both now Tickets objects rather than links objects.
-       and the things that use them have been updated
-       
-2000-08-19 03:03  jesse
-
-       * Makefile:
-
-       Bumped the version 1.3.14
-       
-2000-08-19 02:49  jesse
-
-       * README, etc/config.pm, lib/RT/Ticket.pm:
-
-       Did some work on logging. switched some carping to some logging.
-       
-2000-08-18 02:04  jesse
-
-       * Makefile, README:
-
-       Minor readme updates.
-       
-       Bumped the version to 1.3.13
-       
-2000-08-18 01:04  jesse
-
-       * lib/RT/Transaction.pm:
-
-       CurrentUser objects act on things. not user Objects.  Thanks, Jens
-       
-2000-08-17 23:55  jesse
-
-       * webrt/Elements/: SelectOwner, Submit:
-
-       notes in select owner. a bit of tweaking in submit ot make it more visible
-       
-2000-08-17 16:16  jesse
-
-       * Makefile:
-
-       Changes to rt-mailgate to properly respect authenticated users
-       when performing %RT RESOLVE commands.
-       
-2000-08-17 03:01  jesse
-
-       * lib/RT/Interface/Web.pm:
-
-       Missed a checkin on Web.pm. sorry about that
-       
-2000-08-17 02:53  jesse
-
-       * bin/webmux.pl, lib/RT/Database.pm, lib/RT/Date.pm,
-       lib/RT/Ticket.pm, lib/RT/Interface/Web.pm:
-
-       Yanked the ancient lib/RT/Database.pm. It  never served any purpose
-       added some functionality to RT::Date. it can now take a date type
-       of 'unknown.'  This will "require" Date::Manip and parse it into
-       an ISO style date.  note that this should NEVER be called from RT's
-       core due to overhead. It is useful from web interfaces and CLI tools....
-       
-       added date::manip as a requirement to webmux.pl (so it gets loaded before
-       client hits)
-       
-       cleaned up Interface/Web.pm
-       
-       rationalized some of the routines dealing with date stuff in ticket.pm.
-       
-       Actual working web date changing should be coming "soon." (where soon is
-       defined as sometime this week)
-       
-2000-08-16 14:46  jesse
-
-       * webrt/Elements/Submit:
-
-       file Submit was initially added on branch rt-1-1.
-       
-2000-08-16 14:46  jesse
-
-       * webrt/: Login.html, index.html, Elements/Footer, Elements/Header,
-       Elements/Submit, Ticket/Elements/ShowBasics,
-       Ticket/Elements/ShowTransaction:
-
-       Various bits of webui cleanup
-       
-2000-08-16 14:16  jesse
-
-       * lib/RT/: Tickets.pm, Interface/Email.pm:
-
-       We can now search for tickets by relationship
-       
-2000-08-16 13:18  jesse
-
-       * lib/RT/CurrentUser.pm:
-
-       the real oneline patch that should make rt-mailgate work for new users again.
-       
-2000-08-15 01:17  jesse
-
-       * lib/RT/: Tickets.pm, Interface/Web.pm:
-
-       The first round of convenience methods in RT/Tickets.pm
-       Still need to do the ticket relations methods and the
-       date methods
-       
-2000-08-14 23:47  jesse
-
-       * webrt/Elements/SelectDateType:
-
-       file SelectDateType was initially added on branch rt-1-1.
-       
-2000-08-14 23:47  jesse
-
-       * webrt/Elements/SelectDateType:
-
-       ack. missed this in the wackiness with tonight's earlier checkin.
-       
-2000-08-14 19:35  jesse
-
-       * webrt/: Elements/Header, Elements/SelectDate,
-       Elements/SelectQueue, Elements/TitleBoxStart, Search/Listing.html,
-       Search/PickRestriction:
-
-       The rest of the previous commit.
-       
-2000-08-14 19:27  jesse
-
-       * etc/config.pm, webrt/Login.html, webrt/Logout.html,
-       webrt/autohandler, webrt/index.html, webrt/webrt.css,
-       webrt/Ticket/autohandler, webrt/Ticket/Elements/ShowMemberOf,
-       webrt/Ticket/Elements/ShowMembers,
-       webrt/Ticket/Elements/ShowSummary,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       Cleaned up the ticket display a bit.
-       made logout actually properly erase session data
-       protected _everything_ with an autohandler in /
-       prettified Login.html
-       added some options to /Elements/TitleBoxHead...which seems to have been missed
-       
-2000-08-14 14:37  jesse
-
-       * README:
-
-       Added a warning about postmaster from JD
-       
-2000-08-13 21:57  jesse
-
-       * lib/RT/TicketCollection.pm, lib/RT/Tickets.pm,
-       lib/RT/Interface/Web.pm, webrt/Elements/SelectBoolean,
-       webrt/Elements/SelectDate, webrt/Elements/SelectMatch,
-       webrt/Elements/SelectOwner, webrt/Elements/SelectQueue,
-       webrt/Elements/SelectStatus, webrt/Elements/SelectWatcherType,
-       webrt/Search/Listing.html, webrt/Search/PickRestriction,
-       webrt/Search/TicketCell:
-
-       Significant work on the search and display code.
-       I'm not convinced that this doesn't introduce new bugs.
-       However, you can now search by ticket content.
-       
-       I will be reworking Tickets.pm a bit more to add a bunch of convenience methods
-       over then next week or so.
-       
-2000-08-12 18:07  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Fixed a bug in WatchersAsString. (RT::Watchers wasn't required early enough)
-       this whole routine needs to be redone :/
-       
-2000-08-12 18:06  jesse
-
-       * lib/RT/User.pm:
-
-       User->Create CanManipulate now defaults to 0.
-       
-2000-08-12 18:05  jesse
-
-       * etc/schema.mysql:
-
-       Updated the default user entries in schema.mysql to have the "CanManipulate"
-       flag set so they'd show up in owner lists.
-       
-2000-08-10 19:16  jesse
-
-       * README:
-
-       updated instructions for Apache install
-       
-2000-08-10 18:59  jesse
-
-       * etc/schema.mysql:
-
-       the queue values for the first queue were wrong
-       
-2000-08-10 17:55  jesse
-
-       * lib/RT/Ticket.pm:
-
-       BUGFIX: _UpdateTold now doesn't record a transaction, as things should be
-       
-2000-08-10 15:43  jesse
-
-       * etc/config.pm, etc/schema.Oracle, etc/schema.mysql,
-       lib/RT/Attachment.pm, lib/RT/Record.pm, lib/RT/Scrip.pm,
-       lib/RT/ScripScope.pm, lib/RT/Ticket.pm, lib/RT/TicketCollection.pm,
-       lib/RT/Tickets.pm, lib/RT/Transaction.pm, lib/RT/User.pm,
-       lib/RT/Action/AutoReply.pm, lib/RT/Action/Notify.pm,
-       lib/RT/Action/SendEmail.pm, lib/RT/Interface/Web.pm,
-       webrt/autohandler, webrt/Elements/Error,
-       webrt/Elements/SelectStatus, webrt/Ticket/Update.html,
-       webrt/Ticket/Elements/ShowBasics,
-       webrt/Ticket/Elements/ShowDependencies,
-       webrt/Ticket/Elements/ShowMemberOf,
-       webrt/Ticket/Elements/ShowMembers,
-       webrt/Ticket/Elements/ShowPeople,
-       webrt/Ticket/Elements/ShowReferences,
-       webrt/Ticket/Elements/ShowRequestor,
-       webrt/Ticket/Elements/TicketToolBox:
-
-       Fixed ACL caching bugs
-       Finished adding status "new"
-       cli searching based on status works better.
-       
-       API Change. Queue is NO LONGER the Queue Object for a ticket
-       API Change. Owner is NO LONGER the Owner Object for a ticket
-       
-       instead, both point to their proper database values and OwnerObj and QueueObj
-       do the right thing throughout. This was rather more code churn than I was hoping for, but we've now got a cleaner, more consistent API that's easier to work
-       with.
-       
-       little bits of POD update.
-       
-       Cleaned out some unused code.
-       
-       Made some error messages more professional.
-       
-       We now keep track of date started as well as a "start by" date.  these both
-       need a bit more work.
-       
-       Calling convention for _Set changed. Rather than three different calling
-       conventions which weren't very extensible, DBIx::Record::_Set and all its
-       subclasses now use paramhash style calling. it's much more extensible and
-       flexible now. (This was necessary for some ACL work, among other things)
-       
-2000-08-09 01:11  jesse
-
-       * lib/RT/Record.pm, lib/RT/Ticket.pm, lib/RT/User.pm,
-       webrt/Elements/SelectStatus, webrt/Elements/dayMenu,
-       webrt/Elements/monthMenu, webrt/Elements/yearMenu:
-
-       ACL Decisions are now cached
-       date menus have a "never" option in the webui
-       added a new status. "new" for tickets that aren't yet open
-       
-2000-08-08 01:45  jesse
-
-       * etc/schema.mysql, lib/RT/Queue.pm:
-
-       schema updates.
-       fixed queue->Create
-       
-2000-08-08 01:44  jesse
-
-       * webrt/Admin/ModifyQueue.html:
-
-       file ModifyQueue.html was initially added on branch rt-1-1.
-       
-2000-08-08 01:44  jesse
-
-       * webrt/Admin/: CreateQueue.html, CreateUser.html,
-       ModifyQueue.html, ModifyUser.html, index.html,
-       Elements/CreateQueueCalled, Elements/CreateUserCalled,
-       Elements/ModifyQueue, Elements/ModifyUser,
-       Elements/SelectModifyQueue, Elements/SelectModifyUser:
-
-       Started the new web admin interface.
-       it can now edit queues and users and create queues and users
-       I'm fairly leery of its user handling stuff. particularly passwords
-       
-2000-08-08 01:44  jesse
-
-       * webrt/Admin/CreateUser.html:
-
-       file CreateUser.html was initially added on branch rt-1-1.
-       
-2000-08-08 01:44  jesse
-
-       * webrt/Admin/Elements/SelectModifyUser:
-
-       file SelectModifyUser was initially added on branch rt-1-1.
-       
-2000-08-08 01:44  jesse
-
-       * webrt/Admin/Elements/ModifyUser:
-
-       file ModifyUser was initially added on branch rt-1-1.
-       
-2000-08-08 01:44  jesse
-
-       * webrt/Admin/Elements/CreateUserCalled:
-
-       file CreateUserCalled was initially added on branch rt-1-1.
-       
-2000-08-08 01:44  jesse
-
-       * webrt/Admin/ModifyUser.html:
-
-       file ModifyUser.html was initially added on branch rt-1-1.
-       
-2000-08-08 01:44  jesse
-
-       * webrt/Admin/index.html:
-
-       file index.html was initially added on branch rt-1-1.
-       
-2000-08-08 01:44  jesse
-
-       * webrt/Admin/CreateQueue.html:
-
-       file CreateQueue.html was initially added on branch rt-1-1.
-       
-2000-08-08 01:44  jesse
-
-       * webrt/Admin/Elements/ModifyQueue:
-
-       file ModifyQueue was initially added on branch rt-1-1.
-       
-2000-08-08 01:44  jesse
-
-       * webrt/Admin/Elements/SelectModifyQueue:
-
-       file SelectModifyQueue was initially added on branch rt-1-1.
-       
-2000-08-08 01:44  jesse
-
-       * webrt/Admin/Elements/CreateQueueCalled:
-
-       file CreateQueueCalled was initially added on branch rt-1-1.
-       
-2000-08-07 22:28  jesse
-
-       * etc/schema.mysql, lib/RT/Date.pm, lib/RT/Ticket.pm,
-       lib/RT/Users.pm:
-
-       added a few ticket attributes for forwards compatibility
-       fixed another ACL problem in users.pm
-       fixed a date display bug
-       
-2000-08-07 01:03  jesse
-
-       * lib/RT/Transaction.pm, webrt/Ticket/Create.html,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       Transaction.pm had some lingering ACL bugs ($CurrentUser) isn't a reasonable
-       global in core library routines :/
-       
-       Working on spawning subtickets.
-       
-2000-08-07 00:31  jesse
-
-       * webrt/User/Prefs.html:
-
-       file Prefs.html was initially added on branch rt-1-1.
-       
-2000-08-07 00:31  jesse
-
-       * webrt/Ticket/Elements/ShowDependencies:
-
-       file ShowDependencies was initially added on branch rt-1-1.
-       
-2000-08-07 00:31  jesse
-
-       * webrt/Ticket/Elements/ShowReferences:
-
-       file ShowReferences was initially added on branch rt-1-1.
-       
-2000-08-07 00:31  jesse
-
-       * webrt/Ticket/Elements/ShowMembers:
-
-       file ShowMembers was initially added on branch rt-1-1.
-       
-2000-08-07 00:31  jesse
-
-       * webrt/Ticket/Elements/ShowMemberOf:
-
-       file ShowMemberOf was initially added on branch rt-1-1.
-       
-2000-08-07 00:31  jesse
-
-       * webrt/Admin/EditUser.html:
-
-       file EditUser.html was initially added on branch rt-1-1.
-       
-2000-08-07 00:31  jesse
-
-       * webrt/Admin/Elements/EditUserComments:
-
-       file EditUserComments was initially added on branch rt-1-1.
-       
-2000-08-07 00:31  jesse
-
-       * etc/config.pm, lib/RT/Ticket.pm, webrt/EditUserComments.html,
-       webrt/ViewUser.html, webrt/webrt.css, webrt/Admin/EditUser.html,
-       webrt/Admin/ModifyUser, webrt/Admin/Elements/EditUserComments,
-       webrt/Elements/Error, webrt/Elements/Header,
-       webrt/Elements/SelectOwner, webrt/Ticket/Create.html,
-       webrt/Ticket/Create_Detail.html, webrt/Ticket/Display.html,
-       webrt/Ticket/Elements/EditWatcherList,
-       webrt/Ticket/Elements/ShowDependencies,
-       webrt/Ticket/Elements/ShowMemberOf,
-       webrt/Ticket/Elements/ShowMembers,
-       webrt/Ticket/Elements/ShowPeople,
-       webrt/Ticket/Elements/ShowReferences,
-       webrt/Ticket/Elements/ShowSummary, webrt/User/Prefs.html:
-
-       Did a bunch of work on the webui. cleaned up a lot of the link display stuff
-       did some work on ticket create
-       
-       dependencies and subtickets are now listed in the ticketview. yay!
-       
-2000-08-05 19:47  jesse
-
-       * lib/RT/Ticket.pm, webrt/Ticket/Elements/ShowSummary:
-
-       more Nobody fixes in Ticket.pm
-       justification fixes in ShowSummary
-       
-2000-08-05 18:50  jesse
-
-       * webrt/Ticket/ProcessUpdate.html:
-
-       The webui can now process updates.
-       it needed YA currentuser fix
-       
-2000-08-05 18:43  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Ticket::Create(Owner =>  now takes either a user object or a userid.
-       and defaults to nobody.
-       
-2000-08-05 17:51  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-2000-08-05 17:49  jesse
-
-       * lib/RT/: Date.pm, Interface/Email.pm:
-
-       fixed a few more bugs in the mailgateway. it can create tickets now.
-       fixed an undefined default in the cli query
-       made the date routine not spit out a stupid warning
-       
-2000-08-05 17:21  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       fixed typos in the mailgate. thanks gary
-       
-2000-08-05 00:16  jesse
-
-       * Makefile, NEWS, webrt/Login.html, webrt/autohandler,
-       webrt/webrt.css:
-
-       little tweaks to the webui.
-       bumped the version to 1.3.11 for distribution
-       
-2000-08-04 18:45  jesse
-
-       * README, bin/rtmux.pl, bin/webmux.pl, lib/RT/Areas.pm,
-       lib/RT/Attachments.pm, lib/RT/Date.pm, lib/RT/Link.pm,
-       lib/RT/Links.pm, lib/RT/Queue.pm, lib/RT/Queues.pm,
-       lib/RT/Record.pm, lib/RT/ScripScopes.pm, lib/RT/Scrips.pm,
-       lib/RT/Template.pm, lib/RT/Ticket.pm, lib/RT/Tickets.pm,
-       lib/RT/Transaction.pm, lib/RT/Transactions.pm, lib/RT/Users.pm,
-       lib/RT/Watchers.pm, lib/RT/Interface/Web.pm,
-       webrt/Admin/ModifyUser, webrt/Elements/SelectOwner,
-       webrt/Elements/SelectQueue, webrt/Elements/ViewUser,
-       webrt/Ticket/Display.html, webrt/Ticket/LinkIt.html,
-       webrt/Ticket/Elements/ShowPeople:
-
-       When creating an object, you ALWAYS need to pass in the current user
-       or acls break. we were a bit too lax about this before.
-       
-       this was a major round of bugfixing for the webui
-       
-2000-08-04 15:41  jesse
-
-       * Makefile, lib/RT/CurrentUser.pm, lib/RT/User.pm, webrt/webrt.css,
-       webrt/Elements/Header, webrt/Search/Listing.html,
-       webrt/Search/autohandler, webrt/Ticket/autohandler:
-
-       Queue listing doesn't have that ugly blue any more. And its code for
-       setting row color is a bit cleaner.
-       
-       we now actually _check_ passwords for web logins.
-       
-       webrt.css now has slightly darker hyperlinks.
-       
-       CurrentUser->IsPassword now uses the UserObj
-       
-       users can't use null passwords for authentication.
-       
-2000-08-03 02:19  jesse
-
-       * lib/RT/Interface/Web.pm, webrt/Elements/ShadedBox,
-       webrt/Elements/TitleBoxStart:
-
-       misc fixes to the webui and a leftover fix to the cli.
-       
-       the webui needs to have some of its internals gutted and
-       put back together. it feels very kludgy and not really "planned"
-       
-2000-08-03 02:04  jesse
-
-       * lib/RT/: Record.pm, Scrip.pm, Ticket.pm, Tickets.pm,
-       Transaction.pm, Action/SendEmail.pm:
-
-       made status changes work. (RT::Action::SendEmail was being stupid
-       and not error checking until it was too late)
-       
-       removed more use of hardwired SQL "now()"
-       
-       moved the handling of LastUpdated into RT::Record. from DBIx::Record
-       
-2000-08-03 01:09  jesse
-
-       * lib/RT/Queue.pm:
-
-       fixed a bug in the cli that kept ticket creates from working.
-       queue->hasright's calling convention changed.
-       
-2000-08-03 00:59  jesse
-
-       * Makefile:
-
-       fixed a makefile typo. added back the comment about pg
-       
-2000-08-03 00:42  jesse
-
-       * docs/design_docs/users:
-
-       file users was initially added on branch rt-1-1.
-       
-2000-08-03 00:42  jesse
-
-       * etc/user.Oracle:
-
-       file user.Oracle was initially added on branch rt-1-1.
-       
-2000-08-03 00:42  jesse
-
-       * etc/schema.Oracle:
-
-       file schema.Oracle was initially added on branch rt-1-1.
-       
-2000-08-03 00:42  jesse
-
-       * bin/initacls.Oracle, bin/initdb.Oracle, docs/README.oracle,
-       docs/design_docs/users, etc/schema.Oracle, etc/user.Oracle:
-
-       A first cut at oracle support from Dave Morgan <dmorgan@bartertrust.com>.
-       It is pretty much untested and guaranteed to break. Among other
-       things, the schema isn't current. but it's a start.
-       Thanks, Dave!
-       
-2000-08-03 00:42  jesse
-
-       * docs/README.oracle:
-
-       file README.oracle was initially added on branch rt-1-1.
-       
-2000-08-03 00:42  jesse
-
-       * bin/initacls.Oracle:
-
-       file initacls.Oracle was initially added on branch rt-1-1.
-       
-2000-08-03 00:42  jesse
-
-       * bin/initdb.Oracle:
-
-       file initdb.Oracle was initially added on branch rt-1-1.
-       
-2000-08-03 00:31  jesse
-
-       * docs/design_docs/local_hacking:
-
-       file local_hacking was initially added on branch rt-1-1.
-       
-2000-08-03 00:31  jesse
-
-       * HACKING, Makefile, docs/FAQ.html, docs/actions.html,
-       docs/admin.html, docs/attributes.html, docs/outline.html,
-       docs/rt_users_guide.html, docs/design_docs/local_hacking:
-
-       doc updates. removed outdated 1.x docs
-       
-2000-08-02 23:53  jesse
-
-       * etc/config.pm:
-
-       added some comments from tobias
-       
-2000-08-02 00:20  jesse
-
-       * Makefile, NEWS, TODO, etc/config.pm, etc/schema.mysql,
-       lib/RT/ACE.pm, lib/RT/ACL.pm, lib/RT/CurrentUser.pm,
-       lib/RT/Date.pm, lib/RT/Queue.pm, lib/RT/Record.pm,
-       lib/RT/Ticket.pm, lib/RT/Tickets.pm, lib/RT/User.pm,
-       lib/RT/Interface/Email.pm:
-
-       
-       Weekend of 1 Aug 2000
-       ---------------------
-       I spent the weekend in DC visiting family.   This meant I got a bit of
-       code written ;)  Sadly, I have no access to the CVS server,
-       so I'll be batching a bunch of commits.
-       
-       1. Enabled CLI admin tool
-       2. Added ACL listing functionality to the CLI admin tool.
-       3. Enhanced RT::Queue->Grant such that it works with the structure of RT2
-          ACLs
-       4. Made the Logging framework actually log errors to STDERR.
-          (This makes debugging the CLI tools much easier. It also means
-           that the cli tools explain _why_ they're dying.)
-       5. Fully expunged use of Mysql's SQL keyword "now()". I'd have left this
-          stuff in, except mysql doesn't seem to deal well with the idea that the
-          entire world isn't one timezone.  On top of that, it doesn't seem to
-          have a way to force it into GMT mode that doesn't involve modifying init
-          scripts. *sigh*
-       6. Did a whole bunch more work on the ACL checking in RT::User
-       7. Wrote up some preliminary docs on local hacks to RT
-       8. Added in a routine to allow local canonicalization of email addresses
-       9. Added in the concept of "Disabled users"  To preserve RT2's database
-          Integrity, whacking user accounts would be a bad thing. So, instead,
-          we've got the concept of 'disabled' users. A disabled user fails ANY
-          ACL check, ANY password check and doesn't appear in any lists of ACLs.
-          (note that the lastmost statement isn't yet true)
-       
-       10. rtadmin user -enable and rtadmin user -disable now work.
-       11. ACLs are now enforced for many ticket related actions.
-           (this does mean that you'll want to insert some acls like those below)
-       
-       INSERT INTO ACL VALUES (1,0,'User','SuperUser','Queue',0);
-       INSERT INTO ACL VALUES (2,3,'User','CreateTicket','Queue',0);
-       INSERT INTO ACL VALUES (3,3,'User','ShowTicket','Ticket',0);
-       INSERT INTO ACL VALUES (4,3,'User','ShowTicketHistory','Ticket',0);
-       INSERT INTO ACL VALUES (6,3,'User','CreateTicket','Queue',1);
-       INSERT INTO ACL VALUES (7,3,'User','ModifyTicket','Ticket',1);
-       INSERT INTO ACL VALUES (8,1,'User','Superuser','System',0);
-       INSERT INTO ACL VALUES (9,0,'Everyone','Superuser','System',0);
-       
-2000-08-02 00:17  jesse
-
-       * bin/: rtmux.pl, testdeps.pl:
-
-       Bumped us up to requiring Log::Dispatch 1.6.
-       Cleaned up testdeps a bit. Now, you knwo it passes.
-       
-2000-07-27 03:01  jesse
-
-       * Makefile:
-
-       Bumped the version to 1.3.9
-       Rolled RT 1.3.9
-       
-2000-07-27 02:37  jesse
-
-       * lib/RT/Date.pm, lib/RT/Ticket.pm, webrt/Elements/ViewUser,
-       webrt/Ticket/Elements/ShowDates, webrt/Ticket/Elements/ShowSummary,
-       webrt/Ticket/Elements/ShowTransaction, bin/webmux.pl:
-
-       Fixed a bug with null due dates.
-       Made RT/Date deal with a time of -1 as "Never"
-       made html escaping on included entities on webrt default.
-       
-2000-07-27 02:01  jesse
-
-       * lib/RT/Date.pm:
-
-       file Date.pm was initially added on branch rt-1-1.
-       
-2000-07-27 02:01  jesse
-
-       * README, lib/RT/Date.pm, lib/RT/Record.pm, lib/RT/Ticket.pm,
-       bin/testdeps.pl:
-
-       Moved Date managment routines from DBIx::Record to RT::Record.
-       Initial Checkin of RT::Date, a lightweight Date object capable
-       of doing everything RT needs. Oh. and it's fully documented in POD.
-       
-       Converted RT::Record and RT::Ticket and the cli to use RT::Date instead
-       of Date::Kronos.  The CLI now feels _much_ zippier and code within
-       RT::Ticket is a bit easier to read.
-       
-2000-07-27 01:55  jesse
-
-       * etc/schema.mysql:
-
-       removed extraneous whitespace
-       
-2000-07-27 01:51  jesse
-
-       * lib/RT/Attachment.pm:
-
-       changed the header on attachment.pm
-       
-2000-07-24 10:17  tobiasb
-
-       * lib/RT/Interface/Web.pm, webrt/ViewUser.html,
-       webrt/Search/TicketCell, webrt/Ticket/Display.html,
-       webrt/Ticket/ProcessUpdate.html, webrt/Ticket/Update.html:
-
-       Moved some things to Web.pm, made some nifty options for getting tickets from the listing in a new window
-       
-2000-07-24 06:56  tobiasb
-
-       * lib/RT/User.pm:
-
-       Some TODOs
-       
-2000-07-24 06:54  tobiasb
-
-       * lib/RT/Interface/Email.pm:
-
-       Some comments and TODOs.
-       
-       I fixed one simple TODO about putting in pid + rand into the name of
-       the temp directory needed for parsing the mime entity.
-       
-2000-07-24 00:52  jesse
-
-       * lib/RT/User.pm:
-
-       Added a few comments where they really should be
-       
-2000-07-24 00:48  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       Did a bunch of cleanup work on Interface/Email.pm
-               It could still use more.
-       
-2000-07-23 03:50  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Added the method 'TimeWorkedAsString'.  Ok, I'll start looking into Date::Kronos shortly :)
-       
-2000-07-22 20:10  tobiasb
-
-       * lib/RT/Interface/Email.pm:
-
-       [no log message]
-       
-2000-07-22 20:05  tobiasb
-
-       * lib/RT/Interface/Email.pm:
-
-       Inserted a reference to [fsck 290] in a TODO-comment.
-       
-2000-07-22 13:06  tobiasb
-
-       * lib/RT/Interface/Web.pm, webrt/Search/Listing.html:
-
-       Moved stuff from Listing.html to Web.pm, sub ProcessSearchQuery (suggestions to a better name for the sub?)
-       
-2000-07-21 15:11  tobiasb
-
-       * lib/RT/Ticket.pm, lib/RT/Interface/Web.pm,
-       webrt/Search/Listing.html:
-
-       bugfixing
-       
-2000-07-21 11:09  tobiasb
-
-       * etc/schema.mysql:
-
-       Bugfix
-       
-2000-07-21 10:57  tobiasb
-
-       * webrt/index.html:
-
-       Now it's possible to select queue from the start page
-       
-2000-07-21 10:35  tobiasb
-
-       * lib/RT/Attachment.pm, lib/RT/Ticket.pm, webrt/Elements/Header,
-       webrt/Elements/SelectOwner, webrt/Ticket/Elements/EditWatcherList:
-
-       bugfixes, comments.  I restricted the Owner-list to those that CanManipulate - this should eventually go away when we have proper access control.  Tiny improvement of EditWatcherList - it's now possible to edit user information if the user is found.
-       
-2000-07-21 05:48  tobiasb
-
-       * lib/RT/CurrentUser.pm:
-
-       bugfix
-       
-2000-07-21 00:08  jesse
-
-       * lib/RT/ACE.pm, lib/RT/Attachment.pm, lib/RT/Queue.pm,
-       lib/RT/Ticket.pm, lib/RT/User.pm, webrt/EditUserComments.html:
-
-       Cleaned up language in EditUserComments
-       
-       did work on watchers in ui/cli/admin and Ticket.pm and User.pm
-       cleaned up code in Ticket.pm
-       
-       Start of some work on acls in Queue.pm
-       
-2000-07-20 22:13  tobiasb
-
-       * lib/RT/Interface/Web.pm, webrt/Elements/SelectWatcherType,
-       webrt/Ticket/Display.html, webrt/Ticket/EditWatchers.html,
-       webrt/Ticket/Elements/EditWatcherList,
-       webrt/Ticket/Elements/ShowHistory, webrt/Ticket/Elements/ShowLinks,
-       webrt/Ticket/Elements/TicketToolBox:
-
-       Some code improvements, added one popular demand here; to avoid spending too much time clicking around, it should be possible to show all histoies of member requests at the same page.
-       
-2000-07-20 18:31  tobiasb
-
-       * lib/RT/CurrentUser.pm:
-
-       Fixing a bit.  Please try to remember to test code before committing
-       it :)
-       
-2000-07-20 18:09  tobiasb
-
-       * webrt/Ticket/ProcessUpdate.html:
-
-       once more I've committed without testing..
-       
-2000-07-20 18:02  tobiasb
-
-       * lib/RT/CurrentUser.pm:
-
-       Removed a compile-time bug
-       
-2000-07-20 17:48  tobiasb
-
-       * lib/RT/User.pm:
-
-       bugfix
-       
-2000-07-20 17:39  tobiasb
-
-       * etc/config.pm, lib/RT/Ticket.pm, lib/RT/User.pm,
-       lib/RT/Watcher.pm, lib/RT/Interface/Web.pm,
-       webrt/Ticket/Display.html:
-
-       bugfixes + conflict resolving at the signature + moved something to Web.pm from Display.html
-       
-2000-07-20 17:31  jesse
-
-       * lib/RT/: CurrentUser.pm, User.pm:
-
-       Culled some not-for-now signature stuff.
-       Cleaned up and optimised CurrentUser->UserObj
-       
-2000-07-20 16:39  jesse
-
-       * Makefile, NEWS:
-
-       doing some work for a customer.  rt-mailgate --help should tell you
-       about the fabulous new mail mode
-       
-2000-07-20 15:39  tobiasb
-
-       * lib/RT/Interface/Web.pm, webrt/Ticket/Display.html:
-
-       moving things from the template to Web.pm was not as straight-forwarded as I had hoped.
-       
-2000-07-20 15:20  tobiasb
-
-       * lib/RT/Attachment.pm, lib/RT/CurrentUser.pm, lib/RT/User.pm,
-       lib/RT/Interface/Web.pm, webrt/Ticket/Display.html:
-
-       Started moving stuff to Web.pm, fixed and tested signatures
-       
-2000-07-20 14:50  tobiasb
-
-       * lib/RT/: CurrentUser.pm, User.pm:
-
-       moved signature from currentuser to user (but does it make sense, anyway?  Signatures is something 'personal' that belongs only to the current user?)
-       
-2000-07-20 14:43  tobiasb
-
-       * webrt/ViewUser.html:
-
-       bugfix ... hmpf, always test before committing .. always test before committing ...
-       
-2000-07-20 14:33  tobiasb
-
-       * lib/RT/Interface/Web.pm, webrt/ViewUser.html:
-
-       bugfix
-       
-2000-07-20 14:11  tobiasb
-
-       * lib/RT/Interface/Web.pm:
-
-       file Web.pm was initially added on branch rt-1-1.
-       
-2000-07-20 14:11  tobiasb
-
-       * lib/RT/Interface/Web.pm:
-
-       I'm considering to move things from Display.html and ProcessUpdate.html to Web.pm.  Comments?
-       
-2000-07-20 14:06  jesse
-
-       * lib/RT/Watcher.pm:
-
-       Removed the bogus code frol lib/RT/Watcher.pm
-       
-2000-07-20 13:39  jesse
-
-       * lib/RT/User.pm:
-
-       reversed some bogus code
-       
-2000-07-20 11:44  tobiasb
-
-       * webrt/Ticket/Elements/EditWatcherList:
-
-       file EditWatcherList was initially added on branch rt-1-1.
-       
-2000-07-20 11:44  tobiasb
-
-       * webrt/Elements/SelectWatcherType:
-
-       file SelectWatcherType was initially added on branch rt-1-1.
-       
-2000-07-20 11:44  tobiasb
-
-       * webrt/: Elements/SelectWatcherType,
-       Ticket/Elements/EditWatcherList:
-
-       Now it's possible to edit ticket and queue watchers.  It's really horrible, but at least it works
-       
-2000-07-20 11:43  tobiasb
-
-       * webrt/Ticket/: EditWatchers.html, Update.html:
-
-       Small comment
-       
-2000-07-20 11:40  tobiasb
-
-       * webrt/Ticket/Update.html:
-
-       Linked in the 'edit watchers' functionality
-       
-2000-07-20 11:27  tobiasb
-
-       * lib/RT/Ticket.pm, lib/RT/Watcher.pm,
-       webrt/Ticket/EditWatchers.html:
-
-       Now it's possible to edit ticket and queue watchers.  It's really horrible, but at least it works
-       
-2000-07-20 11:27  tobiasb
-
-       * lib/RT/User.pm:
-
-       bugfix
-       
-2000-07-20 11:23  tobiasb
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       This is sort of a local hack, I guess it should be separated ... but maybe not.  if content-type =~ /^text/(?\!plain)/, there is now a link for 'view this as plain text', which might be useful for unknown text formats and for viewing 'code'
-       
-2000-07-20 02:59  jesse
-
-       * lib/RT/: ACE.pm, ACL.pm:
-
-       I'm committing ACE.pm and ACL.pm so people can get a bit of a taste of what I'm doing. They don't work, they probably don't even compile yet, but they're not getting called from the rest of the code yet.
-       
-       These aren't the droids you're looking for.
-       
-2000-07-20 02:58  jesse
-
-       * lib/RT/User.pm:
-
-       updated User.pm to match the schema
-       
-2000-07-19 16:45  tobiasb
-
-       * webrt/Ticket/EditWatchers.html:
-
-       file EditWatchers.html was initially added on branch rt-1-1.
-       
-2000-07-19 16:45  tobiasb
-
-       * webrt/Ticket/EditWatchers.html:
-
-       This should be a template for adding and removing watchers; will be completed tomorrow
-       
-2000-07-19 16:10  tobiasb
-
-       * webrt/: Logout.html, ViewUser.html, Search/Listing.html,
-       Ticket/Display.html, Ticket/Update.html,
-       Ticket/Elements/ShowPeople, Ticket/Elements/ShowSummary:
-
-       It's now possible to edit user data (realname, userid, email) from the web ui
-       
-2000-07-19 16:04  tobiasb
-
-       * lib/RT/: CurrentUser.pm, Ticket.pm, Watcher.pm,
-       Interface/Email.pm:
-
-       Worked a bit with requestors; 1) if we already have a user object at the requestor, we should use it.  2) it should be possible to edit the users email without also updating the watcher email if those are the same.  3) if a user enters an email with a different from address, but can be identified as a previous user (by equal real name or other means of authentication), the email field in the watcher table should be used
-       
-2000-07-19 10:06  tobiasb
-
-       * webrt/Elements/Header:
-
-       bugfixing
-       
-2000-07-19 08:53  tobiasb
-
-       * webrt/webrt.css:
-
-       Our web designer didn't like red table borders
-       
-2000-07-19 08:52  tobiasb
-
-       * webrt/: Elements/Header, Search/Listing.html:
-
-       Fun #440: Popular wish: Fixed alternating colours at the lines in Listing.html
-       
-2000-07-19 07:41  tobiasb
-
-       * webrt/webrt.css:
-
-       oddline for use in Listing.html
-       
-2000-07-19 06:54  tobiasb
-
-       * webrt/Elements/Header:
-
-       nicer
-       
-2000-07-19 06:51  tobiasb
-
-       * webrt/: index.html, Elements/Header:
-
-       Fun #666; Form 'view bug #xxx' from display and the front page
-       
-2000-07-18 04:17  tobiasb
-
-       * etc/schema.mysql:
-
-       bug #286; two nines in schema.sql
-       
-2000-07-14 11:40  tobiasb
-
-       * webrt/Search/TicketCell:
-
-       I'm currently trying to fix it so that each user can put in options in the session information (or should it rather be in the DB?) about whether they want tickets to pop up in separate windows or not.
-       
-2000-07-14 10:47  tobiasb
-
-       * etc/schema.mysql, lib/RT/Link.pm, lib/RT/Ticket.pm,
-       lib/RT/Action/StallDependent.pm,
-       webrt/Ticket/Elements/TicketToolBox:
-
-       added a scrip for stalling members upon membership linking ... now it's impossible for a request to make a link to itself ... now it's possible to open a request from the ticket display
-       
-2000-07-14 09:29  tobiasb
-
-       * webrt/Ticket/ProcessUpdate.html:
-
-       TODO: Public comments are currently beeing threated as private
-       comments (that's better than it beeing ignored ... at least at the
-       moment)
-       
-       Now it skips trying to build a MIME entity if there are no message.
-       
-2000-07-14 09:11  tobiasb
-
-       * webrt/ViewUser.html:
-
-       Bugfix
-       
-2000-07-14 09:09  tobiasb
-
-       * webrt/Search/Listing.html:
-
-       Killed a warning
-       
-2000-07-13 13:31  tobiasb
-
-       * webrt/index.html:
-
-       Typo
-       
-2000-07-13 11:44  tobiasb
-
-       * webrt/Elements/Header:
-
-       huh?  seems like I've lost the control of CVS a bit today :)
-       
-2000-07-13 11:43  tobiasb
-
-       * webrt/Elements/Header:
-
-       [no log message]
-       
-2000-07-13 11:36  jesse
-
-       * webrt/index.html:
-
-       tobix missed a &>
-       
-2000-07-13 11:08  tobiasb
-
-       * webrt/: Search/RestrictSearch.html, Ticket/Display.html,
-       Ticket/ProcessUpdate.html, Ticket/Update.html:
-
-       Dealt with the footer; it does not need overriding anywhere, and is thus placed in the autohandler
-       
-2000-07-13 11:04  tobiasb
-
-       * webrt/: Logout.html, ViewUser.html, autohandler, index.html,
-       Elements/Header, Search/Listing.html, Ticket/Modify.html,
-       Ticket/ValidateUpdate.html:
-
-       Dealt with the header module; it's now in the .html templates, not in autohandler ... the title should be nice and informative in all the templates ... and the instance name is viewed along with the header
-       
-2000-07-13 07:26  tobiasb
-
-       * lib/RT/Link.pm, lib/RT/Ticket.pm, webrt/index.html,
-       webrt/Elements/SelectResultsPerPage, webrt/Search/Listing.html,
-       webrt/Search/PickRestriction:
-
-       small bugfix + better handling of LimitResultsOnPage
-       
-2000-07-12 14:09  tobiasb
-
-       * lib/RT/: Ticket.pm, Transaction.pm:
-
-       bugfix'es.  duplicated linking actions are now turned down.
-       
-2000-07-12 01:39  jesse
-
-       * etc/schema.mysql:
-
-       updated the schema for User objects. now they've got _even more_ data.
-       and better extension capabilities.
-       
-2000-07-12 00:10  tobiasb
-
-       * lib/RT/Attachment.pm, lib/RT/Scrip.pm, lib/RT/ScripScope.pm,
-       lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       lib/RT/Action/SendEmail.pm, lib/RT/Action/StallDependent.pm,
-       webrt/Elements/SelectResultsPerPage, webrt/Elements/ViewUser,
-       webrt/Ticket/Create.html, webrt/Ticket/Elements/ShowTransaction:
-
-       Debugged a bit and removed some critical bugs
-       
-2000-07-11 14:43  tobiasb
-
-       * webrt/Elements/ViewUser:
-
-               <% $User->Comments || "No comment entered about this user" |h %>
-       
-       "|h" seems like some random noise, or have I misunderstood something?
-       
-2000-07-11 12:19  tobiasb
-
-       * etc/schema.mysql:
-
-       Comments
-       
-2000-07-11 11:30  tobiasb
-
-       * lib/RT/Transaction.pm, lib/RT/Action/AutoReply.pm,
-       webrt/Logout.html, webrt/ViewUser.html:
-
-       more debug logging + some bugfixing (exception handling)
-       
-2000-07-10 20:09  jesse
-
-       * bin/testdeps.pl, etc/schema.mysql, lib/RT/Ticket.pm:
-
-       work on ACLs. some acl decisions are now made.
-       
-2000-07-10 17:13  jesse
-
-       * etc/schema.mysql, lib/RT/ACL.pm, lib/RT/CurrentUser.pm,
-       lib/RT/Queue.pm, lib/RT/Record.pm, lib/RT/Ticket.pm,
-       lib/RT/Transaction.pm, lib/RT/User.pm, lib/RT/Interface/Email.pm,
-       webrt/Ticket/Display.html:
-
-       Wow. all kinds of work.
-       
-       Beginning of implementation of ACLs. lots of code cleanup.
-       
-       schema changes for Groups and Acls.
-       
-       we now use MIMEObj EVERYWHERE instead of MIMEEntity.
-       
-2000-06-29 20:36  jesse
-
-       * Makefile:
-
-       bumped to 1.0.4pre2
-       fixed perms issue for lib/templates
-       
-2000-06-29 16:11  jesse
-
-       * Makefile, etc/schema:
-
-       makefile fixes. bump to 1.0.4pre1
-       schema.mysql has a longer phone number field
-       
-2000-06-26 15:35  jesse
-
-       * README:
-
-       [no log message]
-       
-2000-06-26 15:10  jesse
-
-       * Makefile, bin/rtmux.pl, bin/testdeps.pl:
-
-       added Date::Manip to testdeps.pl
-       set $ENV{'TZ'} in bin/rtmux.pl to deal with a bug in Date::Manip
-       bumped the version to 1.3.8
-       
-2000-06-26 14:38  jesse
-
-       * bin/testdeps.pl:
-
-       added Date::Kronos to testdeps.pl
-       
-2000-06-26 14:36  jesse
-
-       * bin/testdeps.pl:
-
-       added Time::Seconds to testdeps.pl
-       
-2000-06-26 14:31  jesse
-
-       * bin/testdeps.pl, webrt/autohandler, webrt/webrt.css,
-       webrt/Elements/ViewUser, webrt/Ticket/Elements/ShowTransaction:
-
-       various hacking for RTCon pilsen. a much enhanced testdeps.pl
-       
-2000-06-16 10:51  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       some commentary.
-       
-2000-06-16 08:57  tobiasb
-
-       * lib/RT/Interface/Email.pm:
-
-       Sort of a bugfix
-       
-2000-06-16 08:56  tobiasb
-
-       * lib/RT/Action/SendEmail.pm:
-
-       Removed some old garbage
-       
-       TODO: Fix message trailer
-       
-2000-06-16 04:37  tobiasb
-
-       * lib/RT/: Attachment.pm, Record.pm, Ticket.pm, Transaction.pm:
-
-       It's no longer mandatory to have a Creator in every RT table.  It's just to set them 'read/auto'-accessible.  This should fix bug #275
-       
-2000-06-15 16:43  tobiasb
-
-       * etc/config.pm, lib/RT/Attachment.pm, lib/RT/Link.pm,
-       lib/RT/Ticket.pm, webrt/Elements/MessageBox,
-       webrt/Ticket/Display.html, webrt/Ticket/LinkIt.html,
-       webrt/Ticket/ProcessUpdate.html, webrt/Ticket/Update.html,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       some few bugfixes + some work to get 'reply-linking' working.  In my local version of RT (only changes in the config.pm) people can now enter a 'FAQ-tag', and the right article from KB is automaticly inserted in the reply.
-       
-2000-06-15 12:22  tobiasb
-
-       * webrt/ViewUser.html:
-
-       file ViewUser.html was initially added on branch rt-1-1.
-       
-2000-06-15 12:22  tobiasb
-
-       * lib/RT/Attachment.pm, lib/RT/CurrentUser.pm, lib/RT/Ticket.pm,
-       lib/RT/User.pm, lib/RT/Interface/Email.pm, webrt/ViewUser.html,
-       webrt/autohandler, webrt/Elements/Error, webrt/Elements/Footer,
-       webrt/Elements/Header, webrt/Elements/ViewUser,
-       webrt/Ticket/ProcessUpdate.html, webrt/Ticket/Update.html,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       lots of bugfixes and some enhancements:
-       - signature in replies
-       - Creator, LastUpdated etc. should be updated in User.pm
-       - The message headers of inbound requests is now decoded ... this is
-         some sort of a hack as it discards charset information in the header.
-         Anyway, in those cases where the header data will be in the same charset
-         as the body, this works out nicely.
-       - I'm allowing a user to see what data is stored at him.  We might need ACLs
-         for the user comment.  Also, this one is placed directly on the root, so
-         it will break if the user is not logged in.  Also, the page and the module
-         is 'ViewUser', 'ShowUser' would be more consistent.
-       - Prettified the ShowTransaction header
-       
-2000-06-15 09:02  tobiasb
-
-       * etc/schema.mysql:
-
-       Added "Signature" to the Users table and worked a bit at the comments
-       
-2000-06-14 09:24  tobiasb
-
-       * lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       webrt/Ticket/Display.html, webrt/Ticket/Elements/TicketToolBox:
-
-       Tons of minor bugfixes and enhancements
-       
-2000-06-14 09:19  tobiasb
-
-       * etc/schema.mysql:
-
-       Added this:
-       
-       ##TODO: Get Notify.pm to support OldOwner + fix a template
-       #INSERT INTO Scrips VALUES (20, 'NotifyOldOwnerOnSteal',
-       #                         'Sends mail to the old owner when the ticket is stolen',
-       #                         'Steal','Notify',10,'OldOwner',1,NULL,1,NULL);
-       
-2000-06-14 06:54  tobiasb
-
-       * etc/schema.mysql, lib/RT/Attachment.pm, lib/RT/Record.pm,
-       lib/RT/Ticket.pm, webrt/Ticket/Display.html,
-       webrt/Ticket/Elements/ShowDates:
-
-       minor enhancements and bugfixes
-       
-2000-06-14 03:30  tobiasb
-
-       * etc/schema.mysql:
-
-       I just noticed that Jesse already had a 'resolution' attribute in the ticket.  I guess that covers the same as my 'state' attribute
-       
-2000-06-14 00:12  tobiasb
-
-       * lib/RT/Attachment.pm, webrt/Elements/ViewUser,
-       webrt/Search/Listing.html, webrt/Search/PickRestriction,
-       webrt/Ticket/Elements/ShowDates:
-
-       Some enhancements and bugfixes
-       
-2000-06-13 23:26  tobiasb
-
-       * webrt/Ticket/Elements/ShowDates:
-
-       improved
-       
-2000-06-13 20:42  tobiasb
-
-       * etc/schema.mysql:
-
-       Bugfix
-       
-2000-06-13 15:53  tobiasb
-
-       * lib/RT/TicketCollection.pm, webrt/Search/Listing.html:
-
-       Trying to get search on requestor to work - unsuccessful so far :/
-       
-2000-06-13 10:23  tobiasb
-
-       * webrt/: autohandler, Ticket/Display.html,
-       Ticket/Elements/TicketToolBox:
-
-       Some bugfixes
-       
-2000-06-13 06:41  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Bugfix
-       
-2000-06-09 14:43  tobiasb
-
-       * webrt/EditUserComments.html:
-
-       Hm, aaaalways check if everything is working before committing.  Argh.
-       
-2000-06-09 14:30  tobiasb
-
-       * webrt/: EditUserComments.html, autohandler, Elements/Error,
-       Elements/ViewUser:
-
-       added a minimum interface for editing comments about users
-       
-2000-06-09 12:53  tobiasb
-
-       * webrt/Ticket/Elements/ShowRequestor:
-
-       file ShowRequestor was initially added on branch rt-1-1.
-       
-2000-06-09 12:53  tobiasb
-
-       * webrt/Elements/ViewUser:
-
-       file ViewUser was initially added on branch rt-1-1.
-       
-2000-06-09 12:53  tobiasb
-
-       * webrt/EditUserComments.html:
-
-       file EditUserComments.html was initially added on branch rt-1-1.
-       
-2000-06-09 12:53  tobiasb
-
-       * etc/schema.mysql, lib/RT/Ticket.pm, lib/RT/User.pm,
-       lib/RT/Users.pm, lib/RT/Watcher.pm, lib/RT/Interface/Email.pm,
-       webrt/EditUserComments.html, webrt/Elements/ViewUser,
-       webrt/Ticket/ProcessUpdate.html, webrt/Ticket/Elements/ShowPeople,
-       webrt/Ticket/Elements/ShowRequestor,
-       webrt/Ticket/Elements/ShowSummary:
-
-       added a large section in the ticket view for earlier requests (stubbed) by the same requestor and comments about the requestor (the interface for editing those comments are stubbed)
-       
-2000-06-09 04:32  tobiasb
-
-       * etc/schema.mysql:
-
-       Added "Lang" to the users table
-       
-2000-06-08 10:17  tobiasb
-
-       * etc/config.pm, etc/schema.mysql, lib/RT/Ticket.pm,
-       webrt/Elements/SelectMatch, webrt/Ticket/Display.html,
-       webrt/Ticket/Elements/TicketToolBox:
-
-       Added 'UpdateTold' sub to Tickets.  Some minor bugfixes and enhancements.  Not much testing done.
-       
-2000-06-08 08:19  tobiasb
-
-       * lib/RT/Ticket.pm, lib/RT/Transaction.pm, lib/RT/Watcher.pm,
-       lib/RT/Action/SendEmail.pm, lib/RT/Interface/Email.pm,
-       webrt/Ticket/Update.html:
-
-       A bit of debugging, and I managed to remove some annoying warnings
-       
-2000-06-08 08:10  tobiasb
-
-       * etc/schema.mysql:
-
-       bugfix
-       
-2000-06-08 07:59  tobiasb
-
-       * etc/schema.mysql:
-
-       Removed the area in one template.
-       
-2000-06-08 07:55  tobiasb
-
-       * etc/schema.mysql:
-
-       # I think it might make sense replacing "TIMESTAMP" with "DATETIME"
-       # for mysql.  Yes, indeed, I'll do that right away.
-       
-2000-06-08 06:53  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Removed some redundant lines.
-       
-2000-06-08 06:38  tobiasb
-
-       * etc/schema.mysql:
-
-       Inserted table AlternateEmails (commented out as for now).
-       
-       One bugfix (typo) in the ACL table.
-       
-2000-06-08 06:31  tobiasb
-
-       * etc/schema.mysql:
-
-       Grouped into folders
-       
-2000-06-08 05:47  tobiasb
-
-       * lib/RT/Attachment.pm, lib/RT/Ticket.pm, webrt/Login.html,
-       webrt/Search/Listing.html, webrt/Ticket/ProcessUpdate.html,
-       webrt/Ticket/Elements/ShowTransaction,
-       webrt/Ticket/Elements/TicketToolBox:
-
-       bugfixes + improvements requested from the support team; kill & take link from the front page, table borders in listing, reduced header printing ...
-       
-2000-06-07 16:15  tobiasb
-
-       * lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       webrt/Elements/MessageBox, webrt/Ticket/Elements/ShowTransaction:
-
-       bugfixes
-       
-2000-06-07 15:46  tobiasb
-
-       * etc/schema.mysql:
-
-       bugfix
-       
-2000-06-07 15:42  tobiasb
-
-       * lib/RT/: Ticket.pm, Transaction.pm:
-
-       bugfixes
-       
-2000-06-07 15:22  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Now, if some Record decendant can _Accessible('Created', auto) and _Accessible('LastUpdated', auto), they will be set automaticly (at least, that's the theory)
-       
-2000-06-07 14:16  tobiasb
-
-       * etc/schema.mysql:
-
-       mysql autosets the first TIMESTAMP in the table on every
-       update/insert.
-       
-2000-06-07 12:33  tobiasb
-
-       * webrt/autohandler:
-
-       The error handling here seems to work now ... but only for documents
-       at the root.  I thought those autohandlers were called recursively?
-       
-2000-06-07 12:12  tobiasb
-
-       * etc/config.pm, lib/RT/Record.pm, lib/RT/Ticket.pm:
-
-       working with those pesky dates
-       
-2000-06-07 11:51  tobiasb
-
-       * bin/webmux.pl:
-
-       bugfix
-       
-2000-06-07 08:37  tobiasb
-
-       * README:
-
-       Added Date::Kronos (not on CPAN yet) to README
-       
-2000-06-07 08:17  tobiasb
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       Different Comment and Reply links.  They link to the same page, but the default
-       action is changed.
-       
-2000-06-07 07:36  tobiasb
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       Now it doesn't display looooong text/plain attachments.
-       
-       We have a lot of ~1M text/plain attachments in our RT queue.
-       
-       I'm trying to hack my webrt.cgi to show attachments upon a
-       "PickUpTransaction" parameter.  I don't know how to do it in the
-       mason/mod_perl model.
-       
-2000-06-07 04:09  tobiasb
-
-       * webrt/Elements/MessageBox:
-
-       bugfix
-       
-2000-06-06 18:44  jesse
-
-       * etc/schema.mysql:
-
-       removed an outdated table
-       
-2000-06-06 15:42  jesse
-
-       * webrt/Login.html:
-
-       changed the name of the mason package to RT::Mason, so it didn't conflict with other instances
-       on the same webserver
-       
-       fixed a couple of Log::Dispatch(warn)s to (warning)s
-       
-       removed tobix' weird session crunching code that was messign me up
-       
-2000-06-06 15:42  jesse
-
-       * etc/config.pm, lib/RT/Ticket.pm:
-
-       changed the name of the mason package to RT::Mason, so it didn't conflict with other instances
-       on the same webserver
-       
-       fixed a couple of Log::Dispatch(warn)s to (warning)s
-       
-2000-06-06 15:41  jesse
-
-       * bin/webmux.pl:
-
-       changed the name of the mason package to RT::Mason, so it didn't conflict with other instances
-       on the same webserver
-       
-       f
-       
-2000-06-06 15:41  jesse
-
-       * README:
-
-       changed the name of the mason package to RT::Mason, so it didn't conflict with other instances
-       on the same webserver
-       
-2000-06-06 14:40  tobiasb
-
-       * webrt/Ticket/: Update.html, Elements/TicketToolBox:
-
-       I'm trying to set default action in Update.html dependent on which link the
-       user clicked at (update, comment or reply).  I'll continue tomorrow (dinnertime
-       now :)
-       
-2000-06-06 14:11  tobiasb
-
-       * webrt/Ticket/ProcessUpdate.html:
-
-       bugfix
-       
-2000-06-06 13:48  jesse
-
-       * etc/config.pm:
-
-       changed Log::Dispatch::VERSION (1.2) which didn't work
-       to the more standard perl syntax:  use Log::Dispatch 1.2;
-       
-       \ed an @ that tobix left in rtmux.pl
-       
-2000-06-06 13:47  jesse
-
-       * bin/rtmux.pl:
-
-       \ed an @ that tobix left in rtmux.pl
-       
-2000-06-06 13:32  jesse
-
-       * Makefile:
-
-       :%s/        /   / in the makefile (convert spaces to tabs)
-       
-2000-06-06 13:15  tobiasb
-
-       * README:
-
-       Mostly doc changes
-       
-2000-06-06 11:36  tobiasb
-
-       * etc/config.pm:
-
-       bugfix
-       
-2000-06-06 11:15  tobiasb
-
-       * docs/FAQ:
-
-       Added some few tips
-       
-2000-06-06 11:05  tobiasb
-
-       * bin/rtmux.pl:
-
-       putted in some warnings about things that doesn't work
-       
-2000-06-06 04:21  tobiasb
-
-       * README:
-
-       added comments about DBMS'es
-       
-2000-06-05 16:54  tobiasb
-
-       * Makefile:
-
-       more bugfixes
-       
-2000-06-05 16:46  tobiasb
-
-       * Makefile:
-
-       bgfx
-       
-2000-06-05 14:01  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-2000-06-05 09:26  tobiasb
-
-       * README, etc/config.pm, etc/schema.mysql, webrt/autohandler:
-
-       done some documentation fixes
-       
-2000-06-05 07:14  tobiasb
-
-       * README:
-
-       updated the STATUS
-       
-2000-06-02 03:32  tobiasb
-
-       * etc/schema.mysql, lib/RT/Action/SendEmail.pm,
-       lib/RT/Interface/Email.pm, webrt/autohandler, webrt/Elements/Error:
-
-       bugfix
-       
-2000-06-01 23:28  tobiasb
-
-       * webrt/Ticket/Elements/TicketToolBox:
-
-       file TicketToolBox was initially added on branch rt-1-1.
-       
-2000-06-01 23:28  tobiasb
-
-       * etc/config.pm, etc/schema.mysql, lib/RT/Link.pm,
-       lib/RT/Ticket.pm, lib/RT/Action/SendEmail.pm,
-       lib/RT/Interface/Email.pm, webrt/autohandler, webrt/Elements/Error,
-       webrt/Elements/SelectOwner, webrt/Ticket/Create_Detail.html,
-       webrt/Ticket/Display.html, webrt/Ticket/ProcessUpdate.html,
-       webrt/Ticket/Update.html, webrt/Ticket/Elements/TicketToolBox:
-
-        ... better logging (logs a warning when it's dieing during an eval) ... maybe the URL in the mails will work now ... misc bugfixes ... some better foldings ... better error handling in the WebUI (not tested!  You should absolutely see this, I have a feeling it's unsmart.  Check autohandler and Elements/Error) ... misc features added (default values on selectowners now work, auto-fill-in of requestor on create, auto-fill-in of subject on spawn, viewing actions on the ProcessUpdate, ProcessUpdate fixed up a bit ... hm, that's it)
-       
-2000-06-01 20:54  tobiasb
-
-       * bin/testdeps.pl:
-
-       Added Text::Wrapper for quoting of wide messages
-       
-2000-06-01 20:50  tobiasb
-
-       * lib/RT/Transaction.pm, lib/RT/Action/StallDependent.pm,
-       lib/RT/Interface/Email.pm, webrt/Login.html,
-       webrt/Ticket/autohandler, webrt/Ticket/Elements/ShowLinks:
-
-       lots of bugfixes and minor enhancements
-       
-2000-06-01 02:58  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-2000-06-01 02:20  jesse
-
-       * Makefile, NEWS:
-
-       work on the web ui. cleanups to the comment and reply pages as well as the
-       queue view and the ticket detail page
-       
-2000-05-31 14:28  tobiasb
-
-       * etc/config.pm, webrt/Search/Listing.html,
-       webrt/Search/TicketCell, webrt/Ticket/Display.html:
-
-       Popular demand: A link for taking an action from the listing page (reduces the change for concurrency problems)
-       
-2000-05-31 13:59  tobiasb
-
-       * webrt/Search/autohandler:
-
-       Uh, some weird debugging stuff came into the last commit - I should
-       have checked better.
-       
-       Some of those autohandlers seems like copies of each other.  There
-       must be better ways to do this (i.e. separating all the common stuff
-       into some module)?
-       
-2000-05-31 13:52  tobiasb
-
-       * lib/RT/Transaction.pm, lib/RT/Interface/Email.pm,
-       webrt/Search/Listing.html, webrt/Search/PickRestriction,
-       webrt/Search/autohandler, webrt/Ticket/Display.html,
-       webrt/Ticket/Elements/ShowHistory:
-
-       popular demands; more navigation ({back to listing} and {last transaction}) and misc details
-       
-2000-05-31 12:20  tobiasb
-
-       * webrt/Elements/SelectMatch:
-
-       This one is plain ugly at the moment.  Anyway, it's ment for a more advanced 'regexp match / glob match / word match / substring match / total match'
-       
-2000-05-31 12:20  tobiasb
-
-       * webrt/Elements/SelectMatch:
-
-       file SelectMatch was initially added on branch rt-1-1.
-       
-2000-05-31 11:55  tobiasb
-
-       * lib/RT/Action/SendEmail.pm:
-
-       bugfix
-       
-2000-05-31 09:53  tobiasb
-
-       * webrt/: Elements/SelectStatus, Ticket/Update.html:
-
-       Some popular demands from the support dept;
-       
-       I've made it possible to kill by selecting status dead
-       
-       Response is the default action.  I've added a cryptical line which
-       might or might not give a warning.  Ideally, I guess we should do the comment /
-       reply selection through submit buttons rather than through a select menu - what
-       di you think?
-       
-2000-05-30 22:46  tobiasb
-
-       * etc/config.pm, lib/RT/Attachment.pm:
-
-       Ah ... I had forgotten signatures.  Some stubbed work, I'll continue tomorrow
-       
-2000-05-30 22:31  tobiasb
-
-       * lib/RT/Attachment.pm, lib/RT/Attachments.pm, lib/RT/Record.pm,
-       lib/RT/Ticket.pm, lib/RT/Transaction.pm, webrt/Login.html,
-       webrt/Elements/MessageBox, webrt/Search/Listing.html,
-       webrt/Ticket/autohandler, webrt/Ticket/Elements/ShowTransaction:
-
-       Quoting works now ... fixed some other misc details + bugfixes ... and I've moved the date handling to RT::Record, it will be completed tomorrow (I hopecvs diff -uw | less)
-       
-2000-05-30 20:31  tobiasb
-
-       * webrt/Ticket/Create_Detail.html:
-
-       Removed those annoying blink tags.. :)
-       
-2000-05-30 20:14  tobiasb
-
-       * webrt/: Elements/MessageBox, Ticket/Create_Detail.html:
-
-       Still working on that MessageBox
-       
-2000-05-30 20:09  tobiasb
-
-       * webrt/: Elements/MessageBox, Ticket/Update.html:
-
-       Separated out the MessageBox
-       
-2000-05-30 20:09  tobiasb
-
-       * webrt/Elements/MessageBox:
-
-       file MessageBox was initially added on branch rt-1-1.
-       
-2000-05-30 19:56  tobiasb
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       Changed <BLOCKQUOTE> to <pre> for the message content.
-       
-       TODO: We really should HTML'ify and/or HTML-escape the Content.
-       
-2000-05-29 06:59  tobiasb
-
-       * Makefile:
-
-       Some bugfixes, but absolutely not tested.
-       
-2000-05-26 12:11  tobiasb
-
-       * webrt/Search/Listing.html:
-
-       Now it runs /Elements/Header - I was a bit annoyed because it was missing Title
-       
-2000-05-26 10:11  tobiasb
-
-       * webrt/Ticket/Display.html:
-
-       Seems like I had introduced an error here
-       
-2000-05-24 21:50  jesse
-
-       * lib/RT/Ticket.pm, lib/RT/TicketCollection.pm, lib/RT/Tickets.pm,
-       webrt/Search/Listing.html, webrt/Ticket/Display.html:
-
-       Working on persistable web queries. Introduced RT::TicketCollection
-       Arguably this should be in RT::Tickets. and may be some day
-       
-2000-05-24 21:50  jesse
-
-       * lib/RT/TicketCollection.pm:
-
-       file TicketCollection.pm was initially added on branch rt-1-1.
-       
-2000-05-24 08:00  tobiasb
-
-       * lib/RT/Interface/Email.pm:
-
-       It should also be possible to "unlink" something (i.e. if a link was
-       wrongly set).  This is not implemented, but at least mails with
-       an "unlink" command will not bounce now.
-       
-2000-05-23 18:49  tobiasb
-
-       * lib/RT/Transaction.pm:
-
-       Made the transaction text from a link action a bit more readable,
-       though this still needs quite some work.
-       
-2000-05-23 16:57  jesse
-
-       * Makefile:
-
-       Bumped to 1.3.7
-       
-2000-05-23 10:12  tobiasb
-
-       * etc/config.pm, lib/RT/Link.pm, lib/RT/Ticket.pm,
-       lib/RT/Interface/Email.pm, webrt/Ticket/Display.html:
-
-       I've started looking at the mail interface.  Now linking works through the mailgate, though we need some info in the docs.  I'm proposing that it should accept both commands in the headerlines ("RT-Command: Link/Resolve/Whatever blahblah") and traditional commands in the mail ("%RT Link", "%RT Resolve", etc), though I've only supported the first one yet.  Look at the comments in Email.pm for details.
-       
-2000-05-23 10:04  tobiasb
-
-       * lib/RT/Scrip.pm:
-
-       Bugfix/optimalization or something?
-       
-2000-05-22 19:09  tobiasb
-
-       * lib/RT/Ticket.pm, webrt/Ticket/Create_Detail.html,
-       webrt/Ticket/Display.html, webrt/Ticket/LinkIt.html:
-
-       I'm not very happy about some comprimises, choises and short-cuts I've done here, but anyway linking & spawning seems to work now.
-       
-2000-05-22 18:05  tobiasb
-
-       * lib/RT/Transaction.pm, lib/RT/Action/AutoReply.pm,
-       webrt/Ticket/Create.html, webrt/Ticket/Create_Detail.html,
-       webrt/Ticket/Display.html, webrt/Ticket/LinkIt.html:
-
-       all changes here are either related to getting the Create working from the web, or harmless details
-       
-2000-05-22 17:39  tobiasb
-
-       * webrt/Ticket/Display.html:
-
-       $Subject => $Subject||(no subject given)
-       
-       TODO: HTML-escape
-       
-2000-05-22 17:38  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Removed VerboseSubject and HTMLSubject
-       
-2000-05-22 17:24  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       I do use $Ticket->Subject (and other stuff as well) frequently when
-       I'm editing Mason.  There is two issues;
-       
-       1) Things might look freaked if the ticket has no subject, i.e. Display.html
-       
-       2) Things might get totally whacko if the subject contains HTML code.
-       
-       I could ensure the "right" behaviour all the places by using
-       HTML::Entities::encode (I've done it one place), and by always using
-       $Subject||"(No subject)".  Anyway, I think it might be more
-       appropriate to have a sub RT::Ticket::VerboseSubject and
-       RT::Ticket::HTMLSubject.
-       
-       What do you think?
-       
-2000-05-22 16:51  tobiasb
-
-       * webrt/Ticket/Display.html:
-
-       It seems like it can create and view new transactions now.
-       
-       My next step will be to fix linking
-       
-2000-05-22 16:47  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       I should never commit before testing ... I should never commit before testing ... I should never commit before ...
-       
-       bugfix.
-       
-2000-05-22 16:38  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       I'm trying to get a better propagation of error messages.  I'm a bit
-       amused to find lots of things that shouldn't pass `perl -w' and `use
-       strict'?
-       
-2000-05-22 15:52  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Removed a debug (?) line that was commented out:
-       
-       #      print "From is $From\n";
-       
-       ...and inserted some other logging:
-       
-       - logs an info message with ticket id, subject and queue upon
-       successful message creation.
-       
-       - logs a warning if it couldn't be created.
-       
-2000-05-22 14:11  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       In RT::Ticket::Create: Defaulting queue to 'general', and warning when it's not set
-       
-2000-05-22 14:06  tobiasb
-
-       * README:
-
-       Added a 'rt-comment' to the recommended mail configuration
-       
-2000-05-22 14:04  tobiasb
-
-       * Makefile:
-
-       added a comment-mail-alias
-       
-2000-05-22 14:03  tobiasb
-
-       * etc/config.pm:
-
-       Hm ... $RT::CorrespondAddress is used in AutoReply.pm, while only
-       $MailAlias is set in config.pm.  I'm not sure if this is the Right(tm)
-       solution, but anyway ... I added those two lines, additions to the
-       Makefile and README file is coming up shortly ...
-       
-       $CorrespondAddress=$MailAlias;
-       $CommentAddress="!!RT_COMMENT_MAIL_ALIAS!!";
-       
-2000-05-22 12:53  tobiasb
-
-       * webrt/Ticket/Create_Detail.html:
-
-       fixed up a bug caused by too quick usage of cut&paste
-       
-2000-05-22 12:01  tobiasb
-
-       * webrt/Ticket/Create_Detail.html:
-
-       Done some work making this page look OK.  Now I will put in some logic
-       in Display.html for creating and linking requests.
-       
-2000-05-22 05:30  tobiasb
-
-       * webrt/Elements/SelectOwner:
-
-       # TODO: respect the ACLs!!
-       # This will be a list of some thousands requestors with the current scheme.
-       
-2000-05-19 12:37  tobiasb
-
-       * webrt/Ticket/Create.html:
-
-       Added a box for setting link information.  Only a web mockup, the
-       logic doesn't work yet.  Feel free to do whatever you'd like with this
-       one.  It might make sense to move this to the details page.
-       
-2000-05-19 12:17  jesse
-
-       * webrt/Ticket/LinkIt.html:
-
-       Code and formatting cleanups
-       
-2000-05-19 11:23  tobiasb
-
-       * etc/config.pm:
-
-       Removed some weird stuff
-       
-2000-05-19 10:59  jesse
-
-       * webrt/: index.html, Search/PickRestriction:
-
-       fixed some typos
-       
-2000-05-19 10:59  jesse
-
-       * etc/config.pm:
-
-       cleaned up the config file a bit
-       
-       <M-}>CVS:       etc/config.pm
-       
-2000-05-19 08:42  tobiasb
-
-       * bin/testdeps.pl, bin/webmux.pl, webrt/Elements/SelectLinkType,
-       webrt/Ticket/Display.html, webrt/Ticket/LinkIt.html,
-       webrt/Ticket/ProcessUpdate.html, webrt/Ticket/Elements/ShowSummary,
-       webrt/Ticket/Elements/ShowTransaction:
-
-       Started the work getting links to work.  While the linking doesn't work yet, this is a hint about how I think things might work
-       
-2000-05-19 08:42  tobiasb
-
-       * webrt/Elements/SelectLinkType:
-
-       file SelectLinkType was initially added on branch rt-1-1.
-       
-2000-05-19 08:42  tobiasb
-
-       * webrt/Ticket/LinkIt.html:
-
-       file LinkIt.html was initially added on branch rt-1-1.
-       
-2000-05-18 14:46  jesse
-
-       * lib/RT/Ticket.pm:
-
-       a tiny bit of doc added to Ticket.pm
-       still not happy with the format
-       
-2000-05-18 10:56  tobiasb
-
-       * webrt/Ticket/autohandler:
-
-       undo of last commit; only local modifications for debugging
-       
-2000-05-18 10:51  tobiasb
-
-       * webrt/: Search/Listing.html, Ticket/Elements/ShowTransaction:
-
-       the previous commit had wrong loginfo; those files are modified according to the latest changes in etc/config.pm
-       
-2000-05-18 10:42  jesse
-
-       * webrt/Elements/SelectResultsPerPage:
-
-       adding missing file
-       
-2000-05-18 10:41  tobiasb
-
-       * webrt/: index.html, Search/Listing.html, Ticket/autohandler,
-       Ticket/Elements/ShowTransaction:
-
-       A front page for navigation.  This one needs work; Masonifying, generalizing and possibilities for customizations needs to be implemented
-       
-2000-05-18 10:41  tobiasb
-
-       * webrt/index.html:
-
-       file index.html was initially added on branch rt-1-1.
-       
-2000-05-18 10:36  tobiasb
-
-       * webrt/Elements/SelectResultsPerPage:
-
-       Added an empty file as for now
-       
-2000-05-18 10:36  tobiasb
-
-       * webrt/Elements/SelectResultsPerPage:
-
-       file SelectResultsPerPage was initially added on branch rt-1-1.
-       
-2000-05-18 05:48  tobiasb
-
-       * etc/config.pm:
-
-       I'm planning to deal with web customizations with one hash RT::WebOptions in config.pm.  This hash might contain callbacks and maybe names of extra Mason modules to pull in.  What do you think?
-       
-2000-05-17 19:08  jesse
-
-       * webrt/Search/autohandler:
-
-       file autohandler was initially added on branch rt-1-1.
-       
-2000-05-17 19:08  jesse
-
-       * webrt/Search/: Listing.html, PickRestriction, autohandler:
-
-       Work on searches. in the cli  -maxitems <n> now does the right thing
-       
-2000-05-16 17:48  jesse
-
-       * webrt/Ticket/Elements/ShowLinks:
-
-       file ShowLinks was initially added on branch rt-1-1.
-       
-2000-05-16 17:48  jesse
-
-       * bin/rtmux.pl, bin/webmux.pl, lib/RT/Link.pm, lib/RT/Ticket.pm,
-       lib/RT/Action/OpenDependent.pm, lib/RT/Action/ResolveMembers.pm,
-       lib/RT/Action/Spam.pm, lib/RT/Action/StallDependent.pm,
-       webrt/Elements/Error, webrt/Ticket/Elements/ShowLinks,
-       webrt/Ticket/Elements/ShowSummary:
-
-       Converted the new link code to a fully oo setup, rahter than a mishmash of
-       procedural and oo.  seperated out webrt/Ticket/Elements/ShowLinks
-       
-       It's by no means done, but it does seem to work.
-       
-       jesse
-       
-2000-05-16 12:30  tobiasb
-
-       * Makefile, etc/config.pm, lib/RT/Link.pm, lib/RT/Ticket.pm,
-       webrt/Ticket/Elements/ShowSummary:
-
-       Done quite some work at the right hand 'Other Links' window (well, it's not good enough, and it also lists dependencies as for now).  Jesse, you might want to do something with ShowSummary, my Mason code seems horribly ugly.
-       
-2000-05-16 09:18  tobiasb
-
-       * etc/config.pm:
-
-       (...)
-       # A hash table of convertion subs to be used for transforming RT Link
-       # URIs to URLs in the web interface.  If you want to use RT towards
-       # locally installed databases, this is the right place to configure it.
-       # (TODO!)
-       my %URI2HTML=
-           (
-            'fsck.com-rt' => sub {warn "stub!";},
-            'mozilla.com-bugzilla' => sub {warn "stub!";},
-            'fsck.com-kb' => sub {warn "stub!"}
-            );
-       (...)
-       
-       I will also make a sub RT::Links::URI2HTML which gives smart links to
-       internal references, and passes other URIs to this hash table, and
-       eventually we should make default subs for KB and RT.
-       
-       What do you think of this idea?
-       
-2000-05-16 04:58  tobiasb
-
-       * lib/RT/: Link.pm, Ticket.pm:
-
-       Enabled link display in the CLI
-       
-2000-05-16 04:43  tobiasb
-
-       * lib/RT/Transaction.pm:
-
-       Seems like I had broken something...(bugfix)
-       
-2000-05-13 19:56  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Right, we need to work a bit with the links API.
-       
-       - we need an AllLinks sub.  How to tell EasySearch to give both links
-       where we're BASE and were we're TARGET?
-       
-       - we need an "unresolved dependencies" according to the current
-       design.  How to tell if a dependency is unresolved?  Dependencies can
-       point out of this RT instance!
-       
-       - we might need more subs, but not right now anyway.
-       
-2000-05-12 11:32  tobiasb
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       partly a bugfix; 'QouteTransaction=attachment-id' doesn't work very well for transactions without attachment.  Maybe that link should only be for attachments, and not for transactions.  Anyway, I changed it to transaction-id instead.  And I also added 'spawn' to the title; I think 'spawning' should be done through the same page.  'spawn' is when creating a new request that is linked up somehow to the old one.  Maybe it rather should be titled 'forward' or 'create new' or something?
-       
-2000-05-12 07:54  tobiasb
-
-       * webrt/: Elements/Error, Ticket/Display.html:
-
-       Bugfixing ... ehrm, why don't I test things before committing? :)
-       
-2000-05-12 07:34  tobiasb
-
-       * webrt/Elements/Error:
-
-       It logs errors now
-       
-2000-05-12 07:32  tobiasb
-
-       * webrt/Ticket/Display.html:
-
-       dies if element can't be loaded
-       
-2000-05-12 06:55  tobiasb
-
-       * webrt/Login.html:
-
-       seems like CGI won't take a combined get+post
-       
-2000-05-12 06:51  tobiasb
-
-       * etc/config.pm:
-
-       bugfix
-       
-2000-05-11 12:45  jesse
-
-       * webrt/Elements/ShadedBox:
-
-       file ShadedBox was initially added on branch rt-1-1.
-       
-2000-05-11 12:45  jesse
-
-       * webrt/Elements/ShadedBox:
-
-       missed this one before. it's somewhat misnamed right now. basically, it
-       prints a title and content.
-       
-2000-05-11 12:39  jesse
-
-       * webrt/Elements/: TitleBoxEnd, TitleBoxStart:
-
-       the title box for webui
-       
-2000-05-11 12:39  jesse
-
-       * webrt/Elements/TitleBoxStart:
-
-       file TitleBoxStart was initially added on branch rt-1-1.
-       
-2000-05-11 12:39  jesse
-
-       * webrt/Elements/TitleBoxEnd:
-
-       file TitleBoxEnd was initially added on branch rt-1-1.
-       
-2000-05-11 12:37  jesse
-
-       * webrt/Ticket/: Display.html, Elements/ShowSummary:
-
-       hrml cleanup. it's not as pretty, but man does it render faster
-       
-2000-05-11 01:07  jesse
-
-       * webrt/: Elements/Footer, Elements/Header, Ticket/Display.html,
-       Ticket/Elements/ShowHistory, Ticket/Elements/ShowSummary,
-       Ticket/Elements/ShowTransaction:
-
-       
-       Cleanup
-       \
-       
-2000-05-11 00:46  tobiasb
-
-       * TODO:
-
-       Added a list
-       
-2000-05-10 23:43  jesse
-
-       * webrt/webrt.css:
-
-       file webrt.css was initially added on branch rt-1-1.
-       
-2000-05-10 23:43  jesse
-
-       * webrt/webrt.css:
-
-       The base stylesheet.
-       
-2000-05-10 23:41  jesse
-
-       * webrt/Ticket/Elements/ShowSummary:
-
-       file ShowSummary was initially added on branch rt-1-1.
-       
-2000-05-10 23:41  jesse
-
-       * webrt/Ticket/Elements/ShowTransaction:
-
-       file ShowTransaction was initially added on branch rt-1-1.
-       
-2000-05-10 23:41  jesse
-
-       * webrt/Ticket/Elements/ShowDates:
-
-       file ShowDates was initially added on branch rt-1-1.
-       
-2000-05-10 23:41  jesse
-
-       * webrt/Ticket/Elements/ShowHistory:
-
-       file ShowHistory was initially added on branch rt-1-1.
-       
-2000-05-10 23:41  jesse
-
-       * webrt/Ticket/Elements/ToolBar:
-
-       file ToolBar was initially added on branch rt-1-1.
-       
-2000-05-10 23:41  jesse
-
-       * webrt/Ticket/Elements/ShowBasics:
-
-       file ShowBasics was initially added on branch rt-1-1.
-       
-2000-05-10 23:41  jesse
-
-       * webrt/Ticket/Elements/ShowPeople:
-
-       file ShowPeople was initially added on branch rt-1-1.
-       
-2000-05-10 23:41  jesse
-
-       * webrt/: Elements/Header, Ticket/Display.html,
-       Ticket/DisplayHeader, Ticket/DisplaySummary, Ticket/DisplayTicket,
-       Ticket/ProcessUpdate.html, Ticket/ToolBar, Ticket/autohandler,
-       Ticket/Elements/ShowBasics, Ticket/Elements/ShowDates,
-       Ticket/Elements/ShowHistory, Ticket/Elements/ShowPeople,
-       Ticket/Elements/ShowSummary, Ticket/Elements/ShowTransaction,
-       Ticket/Elements/ToolBar:
-
-       Work on the web ui. mostly on the ticket display interface
-       
-2000-05-10 15:43  tobiasb
-
-       * README:
-
-       Added a comment about how to do the CGI :) Well:
-       
-               To get it up running even without mod_perl, you will need to
-       consult Tobix or the rt-devel mailinglist.  Tobix is actively working
-       on a (Fast)CGI version, but as for now he has been too lazy to update
-       the template for the cgi executable.
-       
-2000-05-10 15:39  tobiasb
-
-       * webrt/Ticket/Create_Detail.html:
-
-       added a require statement.  No effect for the mod_perl version, but makes sense for a CGI version.
-       
-2000-05-09 05:35  tobiasb
-
-       * bin/webmux.pl:
-
-       Better formatting
-       
-2000-05-08 05:01  tobiasb
-
-       * lib/RT/Interface/Email.pm:
-
-       bugfix
-       
-2000-05-05 19:20  tobiasb
-
-       * lib/RT/Action/SendEmail.pm:
-
-       This one shouldn't loop now - though it's not tested :)
-       
-2000-05-05 19:15  tobiasb
-
-       * lib/RT/Interface/Email.pm:
-
-       Fixing up the loop control.  When a possible loop occurs, an error
-       flag is set, and a new header field RT-Loop-Alarm appears.  I feel a
-       bit bad about the latter, we are indeed changing an email after it
-       arrived to the system, which I think is a bad thing - but anyway not
-       as bad as dropping the email completely.  My idea is that the Actions,
-       particularly the SendEmail.pm Action remain silent when this header
-       field is set.
-       
-2000-05-05 19:01  tobiasb
-
-       * etc/config.pm:
-
-       Added this about logging to the comments:
-       
-       # It might generally make sense to send error and higher by email to
-       # some administrator.  For heavens sake; be sure that the email goes
-       # directly to a mailbox, and not via RT :) Mail loops will generate a
-       # critical log message.
-       
-2000-05-05 16:47  jesse
-
-       * bin/testdeps.pl:
-
-       Added Log::Dispatch to testdeps.pl
-       
-2000-05-05 13:04  tobiasb
-
-       * lib/RT/Transaction.pm:
-
-       bugfix
-       
-2000-05-05 12:47  tobiasb
-
-       * etc/config.pm:
-
-       I need help, I can't really figure out from this;
-       
-       When commenting out the $SIG{__DIE__} stuff, everything works fine.
-       
-       When having this line in the config:
-       
-       $SIG{__DIE__}  = sub {$RT::Logger->log(level=>'crit',message=>$_[0]); print STDERR $_[0]; exit(-1);};
-       
-       I get this error:
-       
-       Can't locate Mail/Field/addrlist.pm in @INC (@INC contains: /tmp/FunRT /tmp/DBIx /etc/rt /usr/local/lib/perl5/5.6.0/i686-linux /usr/local/lib/perl5/5.6.0 /usr/local/lib/perl5/site_perl/5.6.0/i686-linux /usr/local/lib/perl5/site_perl/5.6.0 /usr/local/lib/perl5/site_perl .) at (eval 115)[/usr/local/lib/perl5/site_perl/5.6.0/Mail/Field.pm:87] line 3.
-       
-       WTF???
-       
-2000-05-05 10:29  tobiasb
-
-       * bin/rtmux.pl:
-
-       I guess this should block that stupid warnings
-       
-2000-05-05 10:01  tobiasb
-
-       * etc/config.pm:
-
-       Added Log::Dispatch.  I also have added those comments, which I would
-       like comments on (:
-       
-       # Most (if not all?) $RT:: global variables should be here.  I'd
-       # suggest putting session information in another Namespace (main:: or
-       # RT::main or maybe something like that).
-       
-       #use strict;
-       
-       #use vars qw/%SitePolicy $dirmode $transactionmode $DatabasePassword $rtname $domain $host $DatabaseHost $DatabaseUser $RT::DatabaseName $DatabaseType $user_passwd_min $MailAlias $WebrtImagePath $web_auth_mechanism $web_auth_cookies_allow_no_path $DefaultLocale $LocalePath $Nobody $Logger/;
-       
-       I'm not sure if "use strict" breaks, but at least "use vars" breaks
-       bigtime as we are using it other places (like rtmux.pl).  I suggest
-       using another package name for the execution logic.  What do you
-       think?
-       
-2000-05-05 08:07  tobiasb
-
-       * Makefile:
-
-       Added RT_LOGFILE, and comments on how to fix advanced logging
-       
-2000-05-05 02:31  jesse
-
-       * bin/rtmux.pl:
-
-       a bit of performance hacking. now require mason and cgi rather than 'use'ing them
-       
-2000-05-05 02:22  jesse
-
-       * lib/RT/: Action.pm, Scrip.pm, ScripScope.pm, Template.pm,
-       Ticket.pm, Transaction.pm, Action/AutoReply.pm,
-       Action/SendEmail.pm, Action/Spam.pm:
-
-       Cleaned up a couple minor things (like precedence, again) and changed "FixSubject" to "SetSubjectTag"
-       
-       Fixed the memory leak in Transaction.pm (it wasn't letting go of Scrip objects)
-       The fix was a bit of a "large mallet on a small nail" in that I'm now _explicitly_ destroying ScripObjects two different ways and don't quite understand why I have to do it. It does, however, work.
-       
-2000-05-04 09:00  tobiasb
-
-       * lib/RT/Action/Spam.pm:
-
-       Completely untested - but I guess this should do real spamming, that
-       is one email for each request(or).
-       
-2000-05-04 08:59  tobiasb
-
-       * lib/RT/Action/SendEmail.pm:
-
-       bugfix
-       
-2000-05-04 07:04  tobiasb
-
-       * lib/RT/Action/: AutoReply.pm, SendEmail.pm:
-
-       Precedence: Bulk should only be set for AutoReply
-       
-2000-05-04 05:29  tobiasb
-
-       * lib/RT/Action/SendEmail.pm:
-
-       sub FixSubject sets the RT tag (unless it is already there).  I moved
-       it out from Prepare because I need to override this behaviour when
-       Spamming people.
-       
-2000-05-04 01:34  jesse
-
-       * etc/schema.mysql:
-
-       spec some defaults in the schema
-       
-2000-05-04 01:32  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Bugfix to ticket.pm for better handling of default values for some queue fields
-       
-2000-05-03 14:19  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Sorry, the last commit on this file was not really a bugfix.  I'd say all Ticket (Transaction) Actions should return status, message and eventually optional things after the message.
-       
-2000-05-03 14:16  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Bugfix
-       
-2000-05-03 14:13  tobiasb
-
-       * lib/RT/Action/: ResolveMembers.pm, Spam.pm:
-
-       Those actually seems to work :)
-       
-2000-05-03 14:13  tobiasb
-
-       * lib/RT/Action/Spam.pm:
-
-       file Spam.pm was initially added on branch rt-1-1.
-       
-2000-05-03 14:13  tobiasb
-
-       * lib/RT/Action/ResolveMembers.pm:
-
-       file ResolveMembers.pm was initially added on branch rt-1-1.
-       
-2000-05-03 14:13  tobiasb
-
-       * lib/RT/Action/SendEmail.pm:
-
-       gubfix
-       
-2000-05-03 14:00  tobiasb
-
-       * etc/schema.mysql:
-
-       Bugfix
-       
-2000-05-03 13:29  tobiasb
-
-       * etc/schema.mysql:
-
-       Commented out the AutoReplies table.
-       
-2000-05-03 13:17  tobiasb
-
-       * lib/RT/Action/AutoReply.pm:
-
-       Putted in "#TODO: " comments for avoiding duplicate AutoReplies.
-       
-2000-05-03 13:15  tobiasb
-
-       * etc/schema.mysql:
-
-       Added a table AutoReplies to avoid sending the same autoreply template
-       more than once to each requestor.
-       
-       Eventually entries should be removed (i.e. after a week) through the
-       (upcoming?) timer system (eventually through the good, old crontab(5))
-       
-2000-05-03 11:48  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       LinkTo and LinkFrom are tested a bit, and they seem to work OK now.
-       
-2000-05-03 11:02  tobiasb
-
-       * etc/schema.mysql:
-
-       Bugfix.
-       
-2000-05-03 07:40  tobiasb
-
-       * etc/schema.mysql:
-
-       I'm putting ResolveGroupTicket on hold.  It's just not important.
-       
-2000-05-02 18:05  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Starting to add a bit of inline pod documentation. the style isn't finalized yet
-       
-2000-05-02 14:30  tobiasb
-
-       * lib/RT/Action/OpenDependent.pm:
-
-       file OpenDependent.pm was initially added on branch rt-1-1.
-       
-2000-05-02 14:30  tobiasb
-
-       * etc/schema.mysql, lib/RT/Link.pm, lib/RT/Ticket.pm,
-       lib/RT/Action/OpenDependent.pm, lib/RT/Action/StallDependent.pm:
-
-       I just got DependsOn Links to work as they should in the CLI :)
-       
-2000-05-02 13:36  tobiasb
-
-       * lib/RT/Links.pm:
-
-       file Links.pm was initially added on branch rt-1-1.
-       
-2000-05-02 13:36  tobiasb
-
-       * lib/RT/: Links.pm, Ticket.pm, Action/StallDependent.pm:
-
-       [no log message]
-       
-2000-05-02 13:07  tobiasb
-
-       * lib/RT/Action/StallDependent.pm:
-
-       Bugfix.  Also, only Open requests should be Stalled.
-       
-2000-05-02 13:01  tobiasb
-
-       * lib/RT/: Ticket.pm, Action/StallDependent.pm:
-
-       Bugfixing
-       
-2000-05-02 12:21  tobiasb
-
-       * lib/RT/: Ticket.pm, Action/StallDependent.pm:
-
-       bugfixes
-       
-2000-05-02 11:55  tobiasb
-
-       * etc/schema.mysql:
-
-       Added TobiX-style logic scrips for DependsOn link and MemberOf link.
-       
-2000-05-02 07:55  tobiasb
-
-       * lib/RT/: Link.pm, Ticket.pm:
-
-       oup, forgot to keep a consistant style
-       base => Base
-       target => Target
-       etc
-       
-2000-05-02 07:55  tobiasb
-
-       * Makefile, etc/config.pm:
-
-       forgot to commit those changes ... configuration for the URI method
-       
-2000-05-02 05:45  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Agh, compile error.
-       
-2000-05-02 05:30  tobiasb
-
-       * lib/RT/Action/StallDependent.pm:
-
-       file StallDependent.pm was initially added on branch rt-1-1.
-       
-2000-05-02 05:30  tobiasb
-
-       * lib/RT/Action/: README.hackers, StallDependent.pm:
-
-       Ok, so lets put all Actions into one directory - though I'd say it would be better for future hackers to orient themselves if we grouped them somehow.
-       
-2000-05-02 00:11  jesse
-
-       * Makefile:
-
-       Version bumping
-       
-2000-05-01 17:16  jesse
-
-       * lib/RT/Ticket.pm:
-
-       moved URIIsLocal closer to other linking routines.
-       
-2000-05-01 10:16  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Made the transaction data a bit "nicer", should look something like:
-       
-       THIS DependsOn 4323 as of 342
-       <URI> DependsOn THIS as of 343
-       
-2000-05-01 08:58  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Changed URL -> URI
-       
-       Changed NewLink and ReverseLink to LinkTo and LinkFrom
-       
-       Added one byte to indicate if it's a From-link or a To-link in the
-       transaction data.
-       
-2000-05-01 01:52  jesse
-
-       * etc/schema.mysql:
-
-       fixed a few typos in the schema
-       
-2000-05-01 01:50  jesse
-
-       * lib/RT/ACL.pm:
-
-       Initial sketches at RT::ACL.pm. there's no running code here yet.
-       
-2000-05-01 01:48  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Fixed Ticket->URL. changed queue->load to queue->Load
-       
-2000-05-01 01:04  jesse
-
-       * bin/rtmux.pl:
-
-       Fixed improper rt program selection code.
-       
-2000-05-01 00:14  jesse
-
-       * lib/RT/Queue.pm:
-
-       a stub for ACL work.
-       
-2000-04-30 13:28  tobiasb
-
-       * lib/RT/Link.pm:
-
-       file Link.pm was initially added on branch rt-1-1.
-       
-2000-04-30 13:28  tobiasb
-
-       * lib/RT/: Link.pm, Ticket.pm:
-
-       Link.pm
-       
-2000-04-30 13:13  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Added a static method URIIsLocal which checks if it's a local URI or not.
-       
-2000-04-28 14:20  jesse
-
-       * lib/RT/Transaction.pm:
-
-       Cleaned up some comments and formatting. and did a bit of reorganizing
-       of routines to more closely model other files. Oh. i finally have
-       emacs doing proper indenting per perlstyle. so we'll hopefully start
-       to get better about that :) Tobix has only been bugging me for a year
-       
-2000-04-28 09:05  tobiasb
-
-       * lib/RT/Action/README.hackers:
-
-       Just some documentation for future hackers :)
-       
-2000-04-28 09:05  tobiasb
-
-       * lib/RT/Action/README.hackers:
-
-       file README.hackers was initially added on branch rt-1-1.
-       
-2000-04-28 08:20  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Started the work of implementing links
-       
-2000-04-28 04:40  tobiasb
-
-       * etc/schema.mysql:
-
-       Didn't we once agree that we needed "state" (user-configurable logic)
-       and "status" (fixed open/stalled/resolved/dead)? :)
-       
-2000-04-28 01:17  jesse
-
-       * lib/RT/Ticket.pm:
-
-       didn't balance parens. grr
-       
-2000-04-28 00:54  jesse
-
-       * lib/RT/Ticket.pm:
-
-       a bunch of cleanup.. a bunch more folding mode braces.
-       a few minor (still not in any codepath) changes for the start of some
-       acls work
-       
-2000-04-28 00:51  jesse
-
-       * docs/design_docs/link-definitions.txt:
-
-       a few comments, additions and clarifications. nothing really major
-       
-2000-04-27 02:06  jesse
-
-       * docs/design_docs/acls:
-
-       more thoughts on ACLs. this time including some code snippits.
-       
-2000-04-27 02:01  jesse
-
-       * etc/schema.mysql:
-
-       added the schema for the new ACL system.
-       responded to tobix' comments about GECOS.
-       
-2000-04-26 14:58  tobiasb
-
-       * docs/design_docs/subscription-definitions.txt:
-
-       marginal updates to reflect that scrips/actions can be used for more things than subscriptions (the whole document might need a rename)
-       
-2000-04-26 14:50  tobiasb
-
-       * docs/design_docs/link-definitions.txt, etc/schema.mysql:
-
-       only insignificant comments - some made weeks ago
-       
-2000-04-26 12:59  jesse
-
-       * docs/design_docs/link-definitions.txt:
-
-       some comments on link definitions
-       my comments are marked with # as the first character of the line.
-       
-2000-04-26 02:27  tobiasb
-
-       * docs/design_docs/: link-definitions.txt,
-       subscription-definitions.txt:
-
-       updates
-       
-2000-04-26 00:14  jesse
-
-       * docs/design_docs/acls:
-
-       some more hacking on acls design
-       
-2000-04-25 17:58  jesse
-
-       * docs/design_docs/acls:
-
-       thoughts on acls
-       
-2000-04-24 00:17  jesse
-
-       * webrt/Ticket/Create_Detail.html:
-
-       file Create_Detail.html was initially added on branch rt-1-1.
-       
-2000-04-24 00:17  jesse
-
-       * webrt/Ticket/Create_Detail.html:
-
-       some work on create. nothing ready for consumption yet.
-       
-2000-04-24 00:16  jesse
-
-       * webrt/: Logout.html, Elements/Footer, Elements/Header,
-       Elements/SelectQueue, Ticket/Create.html, Ticket/Display.html,
-       Ticket/ProcessUpdate.html, Ticket/SetOwner, Ticket/SetStatus,
-       Ticket/Update.html, Ticket/autohandler:
-
-       Look ma, $session{'CurrentUser'} contains the current user object.
-       you can depend on this being set if the user's authenticated.
-       
-2000-04-24 00:16  jesse
-
-       * webrt/Logout.html:
-
-       file Logout.html was initially added on branch rt-1-1.
-       
-2000-04-24 00:14  jesse
-
-       * Makefile, bin/testdeps.pl, bin/webmux.pl:
-
-       Added Apache::Session support to the HTML::Mason version of things.
-       
-2000-04-23 19:45  jesse
-
-       * bin/testdeps.pl:
-
-       added a little script to test perl dependencies.
-       it should probably get integrated into the makefile
-       
-2000-04-23 19:45  jesse
-
-       * bin/testdeps.pl:
-
-       file testdeps.pl was initially added on branch rt-1-1.
-       
-2000-04-23 17:28  jesse
-
-       * Makefile, docs/design_docs/acls, etc/schema.mysql:
-
-       installation seems to work a bit better now
-       
-2000-04-20 02:18  jesse
-
-       * webrt/Login.html:
-
-       Removing cruft from login.html
-       
-2000-04-20 02:17  jesse
-
-       * webrt/Ticket/autohandler:
-
-       Look ma! this autohandler seems to make webauth (with $pass = $user ) work.
-       
-2000-04-20 02:09  jesse
-
-       * webrt/: autohandler, Ticket/autohandler:
-
-       file autohandler was initially added on branch rt-1-1.
-       
-2000-04-20 02:09  jesse
-
-       * webrt/Login.html:
-
-       file Login.html was initially added on branch rt-1-1.
-       
-2000-04-20 02:09  jesse
-
-       * Makefile, bin/webmux.pl, webrt/Login.html, webrt/autohandler,
-       webrt/Ticket/autohandler:
-
-       Doing work on cookie-based authentication for WebRT. The basic idea
-       is that the autohandler in each directory (unless the global handlers can be made to work) will check to see if the user is authenticated. If they are, then it keeps going happily. otherwise, it forces the user to login with the form in /Login.html, which should eventually be smart enough to put them back to where they want to go.
-       
-2000-04-18 02:43  jesse
-
-       * docs/design_docs/acls:
-
-       checking in design work on ACLs. a bit more work, such as notes
-       on order of evaluation and a rough implementation plan and then I'll
-       implement
-       
-2000-04-13 11:58  tobiasb
-
-       * etc/config.pm:
-
-       Introduced all columns we need locally, that is all columns as of RT
-       1.0, except due, area and priorities.  I guess somebody might want to
-       add those columns as well :)
-       
-2000-04-13 11:52  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       hrmwell, you did introduse a slight bug here.. :)
-       
-2000-04-13 11:26  tobiasb
-
-       * webrt/Search/: Listing.html, TicketCell:
-
-       Looks gruesome, but hey - it works\!
-       
-2000-04-13 11:26  tobiasb
-
-       * webrt/Search/TicketCell:
-
-       file TicketCell was initially added on branch rt-1-1.
-       
-2000-04-13 10:52  tobiasb
-
-       * etc/config.pm:
-
-       agh..
-       
-2000-04-13 10:50  tobiasb
-
-       * etc/config.pm:
-
-       Added the site configurable option "QueueListingCols".  It should also
-       be possible to override this one at least through the query, but it
-       might not be trivial.  (maybe you have better suggestions?)
-       
-2000-04-13 10:23  tobiasb
-
-       * webrt/Search/QueueItem:
-
-       I think I want to remove this one, I have other thoughts about how to
-       handle this - let's discuss it more when I've made some implementation :)
-       
-2000-04-13 10:05  tobiasb
-
-       * webrt/Search/Listing.html:
-
-       Added this:
-       
-       # TODO: This one should _not_ be here, rather somewhere else
-       # (suggestions?).  It might eventually read the cookies, user
-       # configuration information from the DB, queue configuration information
-       # from the DB, etc.  It should be object oriented.  But what object can
-       # it belong to, and how should it get access to all this data?
-       
-       sub _cfg {
-         my $key=shift;
-         return $ARGS{$key} || $RT::SitePolicy{$key};
-       }
-       
-2000-04-13 10:05  tobiasb
-
-       * etc/config.pm:
-
-       Added a hash for "tunable" configurations:
-       
-       # This is where RT's preferences are kept track of
-       
-       package RT;
-       
-       # Different "tunable" configuration options should be in this hash:
-       %SitePolicy=();
-       
-2000-04-13 02:30  jesse
-
-       * lib/RT/Ticket.pm:
-
-       Ticket::clean became Ticket::_CleanAddressesAsString
-       references to clean changed accordingly. i feel a bit dirty not
-       making this $self->_CleanAddressesAsString.
-       
-2000-04-12 08:53  tobiasb
-
-       * webrt/: Elements/SelectStatus, Ticket/ProcessUpdate.html,
-       Ticket/Update.html:
-
-       bugfixes and insignificant enhancements
-       
-2000-04-12 07:14  tobiasb
-
-       * webrt/Elements/yearMenu:
-
-       "Last year" is now (by default) available
-       
-2000-04-12 07:11  tobiasb
-
-       * webrt/Search/PickRestriction:
-
-       Changed the default to select one queue, not select "anything but" a queue.
-       
-2000-04-12 07:07  tobiasb
-
-       * webrt/Search/PickRestriction:
-
-       Added a stupid "under construction" message.
-       
-2000-04-12 07:00  tobiasb
-
-       * lib/RT/Interface/Email.pm:
-
-       Ehm .. the last commit message should be more descriptive;
-       
-       From the README:
-       
-               rt:     |"/path/to/rt/bin/rt-mailgate general correspond"
-                                                           |          |
-                                          <<queue-name>----/          |
-                                                                      |
-                       <<correspond or comment depending on whether   |
-                        the mail shoud be resent to the requestor>---/
-                        "action" here will make this address only
-                         parse actions in the message without
-                         recording the message as a transaction
-                         of its own"
-       
-       ...while the implementation required "correspond general"
-       
-2000-04-12 06:58  tobiasb
-
-       * lib/RT/Interface/Email.pm:
-
-       This was not in sync with the README
-       
-2000-04-12 06:50  tobiasb
-
-       * webrt/Search/PickRestriction:
-
-       Bugfix
-       
-2000-04-12 06:45  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Agh, should have tested before committing :)
-       
-2000-04-12 06:44  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Fixd SetOwner to allow stealing and to respect the new Nobody user
-       
-2000-04-12 05:19  tobiasb
-
-       * webrt/Elements/SelectQueue:
-
-       Now this one actually works
-       
-2000-04-11 07:30  tobiasb
-
-       * webrt/Elements/SelectQueue:
-
-       This won't work yet.
-       
-2000-04-11 07:17  tobiasb
-
-       * lib/RT/Transaction.pm:
-
-       Ehr...right.  Still fixing at the same bug; the IsInbound sub didn't work....well
-       
-2000-04-11 07:08  tobiasb
-
-       * lib/RT/: Ticket.pm, Transaction.pm:
-
-       argh .. I should learn to test the bugfixes before committing
-       
-2000-04-11 06:46  tobiasb
-
-       * lib/RT/Transaction.pm:
-
-       bugfix
-       
-2000-04-11 06:42  tobiasb
-
-       * lib/RT/Template.pm, lib/RT/Ticket.pm, webrt/Elements/SelectOwner,
-       webrt/Ticket/ProcessUpdate.html:
-
-       bugfixes
-       
-2000-04-11 05:47  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       bugfixing
-       
-2000-04-11 04:46  tobiasb
-
-       * lib/RT/Watchers.pm:
-
-       Bugfix
-       
-2000-04-11 04:41  tobiasb
-
-       * etc/config.pm, lib/RT/Ticket.pm:
-
-       I'm trying to fix this nobody user..
-       
-2000-04-11 04:36  tobiasb
-
-       * etc/schema.mysql:
-
-       I'm trying to fix this nobody user..
-       
-2000-04-11 04:29  tobiasb
-
-       * lib/RT/Queue.pm, webrt/Ticket/ProcessUpdate.html:
-
-       Bugfixing
-       
-2000-04-11 03:16  tobiasb
-
-       * webrt/Search/Listing.html:
-
-       Insignificant.  Oh, how should errors be trapped?
-       
-2000-04-11 00:40  jesse
-
-       * lib/RT/: Queue.pm, Ticket.pm, Watchers.pm:
-
-       all the watcher types now have AsString methods. this was done by dropping
-       an EmailsAsString method into RT::Watcher
-       
-2000-04-10 23:04  tobiasb
-
-       * webrt/Ticket/ProcessUpdate.html:
-
-       Added those use statements
-       
-       This page seems very broken in Netscape.
-       
-2000-04-10 23:00  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Darn, I thought I had tested this.  Well, now it should work!?
-       
-2000-04-10 22:54  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       ...some work is needed to get Watchers work OK.  I commented out my
-       try on it, so now it will ignore queue watchers (it simply ignored all
-       watchers as it was).
-       
-2000-04-10 14:29  tobiasb
-
-       * webrt/Ticket/: DisplayTicket, DisplayTransaction:
-
-       Update and Modify-links
-       
-2000-04-10 14:20  tobiasb
-
-       * webrt/Ticket/DisplayTransaction:
-
-       Added an "act" link and touched the comments
-       
-2000-04-10 14:11  tobiasb
-
-       * webrt/Ticket/DisplaySummary:
-
-       Reinserted the "Last Contact" and "Last Update" lines, but they're "cleaned" a bit.
-       
-       (btw, this seems like a crude copy from the cli, does the cli have similar problems?)
-       
-2000-04-10 13:51  tobiasb
-
-       * webrt/Ticket/DisplaySummary:
-
-       Hacking a bit on this
-       
-2000-04-10 13:48  tobiasb
-
-       * webrt/Ticket/: DisplayTransaction, Update.html:
-
-       Hacking a bit on this
-       
-2000-04-10 13:18  tobiasb
-
-       * webrt/Ticket/Modify.html:
-
-       'undo' (well, not really :)
-       
-2000-04-10 13:13  tobiasb
-
-       * webrt/Ticket/Update.html:
-
-       This 'fix' is maybe only temporary?
-       
-2000-04-10 13:08  tobiasb
-
-       * webrt/Ticket/Modify.html:
-
-       I'd daresay this one is superceded by Update.html?
-       
-2000-04-10 13:07  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       just added some comments
-       
-2000-04-10 12:52  tobiasb
-
-       * webrt/Ticket/DisplaySummary:
-
-       This 'fix' is maybe only temporary?
-       
-2000-04-10 10:35  tobiasb
-
-       * webrt/: Elements/SelectBoolean, Search/Listing.html:
-
-       insignificant changes
-       
-2000-04-10 06:53  tobiasb
-
-       * webrt/Elements/SelectOwner:
-
-       Insignificant fix (wouldn't work here without)
-       
-2000-04-10 05:38  tobiasb
-
-       * bin/rtmux.pl:
-
-       Might be a bugfix
-       
-2000-04-09 16:56  jesse
-
-       * lib/RT/Users.pm, webrt/Elements/SelectBoolean,
-       webrt/Elements/SelectOwner, webrt/Search/Listing.html,
-       webrt/Search/PickRestriction:
-
-       I can now get a listing of tickets whose owner is or isn't a given owner.
-       and it even lists them. Next, I'll probably make searches for
-       other attributes work.
-       the plan of attack is requestor, then probably ticket content (as a test
-       of whether this whole system works ;)
-       
-2000-04-07 20:41  jesse
-
-       * webrt/Search/Listing.html:
-
-       Added the first bit of code to support queue/owner/requestor/subject search.
-       This will make up the core of the  web search functionality of the first release of the webui. (not the 2.0 release, but the "tobix needs it now) release.
-       
-2000-04-07 14:53  tobiasb
-
-       * etc/schema.mysql, lib/RT/Ticket.pm, lib/RT/Watchers.pm,
-       lib/RT/Action/SendEmail.pm:
-
-       hm ... seems like I forgot to commit my last work
-       
-2000-04-07 03:55  tobiasb
-
-       * lib/RT/: Ticket.pm, Transaction.pm:
-
-       it almost works now
-       
-2000-04-06 17:40  tobiasb
-
-       * lib/RT/Transaction.pm:
-
-       development
-       
-2000-04-06 17:21  tobiasb
-
-       * lib/RT/: Ticket.pm, Transaction.pm, Action/Notify.pm,
-       Action/SendEmail.pm:
-
-       ouch, found a lot of fatal stubs
-       
-2000-04-06 16:54  tobiasb
-
-       * etc/schema.mysql, lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       lib/RT/Action/Notify.pm, lib/RT/Action/SendEmail.pm:
-
-       still fighting with the mail handling
-       
-2000-04-06 16:12  tobiasb
-
-       * etc/schema.mysql, lib/RT/Scrips.pm, lib/RT/Ticket.pm,
-       lib/RT/Transaction.pm, lib/RT/Action/Notify.pm:
-
-       New snapshot of development.  Note the change I've done in the Type recognizion
-       when selecting the right Scrips in Transaction::Create - it should be more
-       flexible this way (replaced "ne" with "!~").  Check the change to schema for
-       an example of how this is more flexible.
-       
-2000-04-06 15:36  tobiasb
-
-       * lib/RT/Action/Notify.pm:
-
-       Recipient finder
-       
-2000-04-06 15:35  tobiasb
-
-       * etc/schema.mysql, lib/RT/Template.pm, lib/RT/Action/SendEmail.pm:
-
-       Snapshot; I'm not finished debugging yet, but this should (hopefully) be
-       very close to actually work.
-       
-2000-04-06 11:38  tobiasb
-
-       * docs/FAQ:
-
-       this clearly needs a lot more work ...
-       
-2000-04-06 11:31  tobiasb
-
-       * lib/RT/Action/SendEmail.pm:
-
-       ...ah, this felt good.
-       
-       Checked the recent version of Mailtools at CPAN, so I used the "right"
-       method for sending emails.
-       
-       I also added back again the SetRecipients method, and documented it in
-       the POD.
-       
-       I think I will get this working in a couple of hours, so please don't
-       disturb me saying that you disagree very much to those changes.. :)
-       
-2000-04-06 10:46  tobiasb
-
-       * etc/schema.mysql:
-
-       Bugfixing
-       
-2000-04-06 10:40  tobiasb
-
-       * etc/schema.mysql:
-
-       I think that I will get this up working during the next few hours.
-       
-       If I eventually get it working, I'd really appreciate that you don't
-       wreck it until the web interface is working and until we've discussed
-       the design thoroughly and come down to some consensus about it.
-       
-2000-04-06 06:22  tobiasb
-
-       * webrt/Elements/Checkbox:
-
-       This is not my turf ... and I don't know what I'm doing ... anyway, it didn't work, but now it works (?) :)
-       
-2000-04-06 01:49  jesse
-
-       * lib/RT/Action/SendEmailOnResolve.pm:
-
-       file SendEmailOnResolve.pm was initially added on branch rt-1-1.
-       
-2000-04-06 01:49  jesse
-
-       * Makefile, etc/schema.mysql, lib/RT/Template.pm,
-       lib/RT/Action/MailComment.pm, lib/RT/Action/MailCorrespondence.pm,
-       lib/RT/Action/Notify.pm, lib/RT/Action/NotifyOnResolve.pm,
-       lib/RT/Action/SendEmail.pm, lib/RT/Action/SendEmailOnResolve.pm:
-
-       Ok, i think i significantly cut down the complexity of the actions we've got
-       so far. I nuked the old notify rules, as they were superceeded by my more
-       capable SendEmail.pm There are still a few things I'm not happy with...
-       like, the way that scrips, scripscopes and templates are related. it needs
-       some thought and cleanup. but i think it'll work just fine for now.
-       
-       I redid the templates and scrips to fit with the revised actions and added
-       some more docs to SendEmail.pm
-       
-       the generic RT::Action should deal with templates, not SendEmail, I think,
-       but I'm leaving that abstraction for another day.
-       
-       Oh, the Argument from the scrip is now passed into the template as $T::Argument.
-       
-2000-04-05 23:24  jesse
-
-       * webrt/Elements/Checkbox:
-
-       stylistic cleanup
-       using an explicit defined ($foo)
-       
-2000-04-05 18:02  tobiasb
-
-       * webrt/: Elements/Checkbox, Search/PickRestriction:
-
-       Only minor corrections
-       
-2000-04-05 17:43  tobiasb
-
-       * webrt/Search/PickRestriction:
-
-       It certainly doesn't work okay ... I think I should look into it a bit ...
-       
-2000-04-05 17:08  tobiasb
-
-       * webrt/Search/PickRestriction:
-
-       Added ugly submit button
-       
-2000-04-05 10:34  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Temporary implementation of kill
-       
-       As mentionated earlier, I think the right thing is to just set status
-       'dead' and then eventually do some garbage collection later.
-       
-2000-04-05 08:55  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       More error handling
-       
-2000-04-05 08:51  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       added some comments around the dies pointing out that we need better error handling.
-       
-2000-04-05 05:34  tobiasb
-
-       * lib/RT/Interface/Email.pm:
-
-       Doh...I'm really stupid sometimes...
-       
-2000-04-05 05:31  tobiasb
-
-       * lib/RT/Interface/Email.pm:
-
-       For some weird reason (perl 5.6.0 bug?) it wouldn't work here without this fix.
-       
-2000-04-05 00:35  jesse
-
-       * docs/design_docs/acls:
-
-       initial musings on acls for 2.0
-       
-2000-04-05 00:35  jesse
-
-       * docs/design_docs/acls:
-
-       file acls was initially added on branch rt-1-1.
-       
-2000-04-04 09:52  tobiasb
-
-       * etc/schema.mysql:
-
-       Language idea
-       
-2000-04-04 02:17  jesse
-
-       * Makefile, README, bin/rtmux.pl, etc/config.pm:
-
-       The first little bits of structure for future L10n support
-       
-2000-04-03 12:40  tobiasb
-
-       * Makefile, bin/rtmux.pl:
-
-       Cleaned out yet some more visible configuration bugs
-       
-2000-04-03 12:29  tobiasb
-
-       * README:
-
-       Some fixes
-       
-2000-04-03 10:44  tobiasb
-
-       * Makefile, bin/rtmux.pl:
-
-       Just a configuration fix.
-       
-2000-04-03 01:26  jesse
-
-       * Makefile, bin/rtmux.pl:
-
-       Ok, I've modified rtmux.pl and Makefile to add in the first bits of stub
-       code for running Mason as a cgi. it compiles and appears to invoke.
-       but I haven't tested it under a webserver. I've gotta get to sleep now, but
-       figured this would give tobias a leg up with his testing today.
-       
-       Subject:      RE: [Mason] Mason under CGI (was: replacing storyserver)
-       Author:       Ilmari Karonen <iltzu@sci.fi>
-       Date:         Fri, 17 Sep 1999 15:10:20 +0300 (EET DST)
-       
-       On Thu, 16 Sep 1999, Ben Munoz wrote:
-       > I'm running Apache 1.3.6 on NT.  I'm looking to install HTML::Mason and see
-       > what it can do, but from what I've read, I can't install mod_perl with the
-       > current version of ActiveState's Perl, which I have installed on my machine.
-       
-       I realize this is probably not what you were asking for, but I'd like to
-       mention here my recent (yesterday) experience in setting up Mason under
-       plain ol' CGI.
-       
-       Setting: One Mason top level component plus a few subcomponents on a
-       development server with mod_perl and Mason. One production server with the
-       least possible selection of modules. (Not even mod_so!)
-       
-       Needed to quickly get the Mason component up and running on the second
-       server. Installing Mason itself and a few other perl modules was easy.
-       But adding mod_perl was definitely out of the question.
-       
-       What I did was take the usual handler.pl, copy it to cgi-bin, deleting
-       everything from "my $ah = new HTML::Mason::ApacheHandler" onward
-       inclusive, and replacing it with the following:
-       
-           use CGI;
-           my $q = new CGI;
-       
-           # This routine comes from ApacheHandler.pm:
-           my (%args);
-           foreach my $key ( $q->param ) {
-             foreach my $value ( $q->param($key) ) {
-               if (exists($args{$key})) {
-                 if (ref($args{$key})) {
-                   $args{$key} = [@{$args{$key}}, $value];
-                 } else {
-                   $args{$key} = [$args{$key}, $value];
-                 }
-               } else {
-                 $args{$key} = $value;
-               }
-           }
-       
-           my $comp = $ENV{'PATH_TRANSLATED'};
-           my $root = $interp->comp_root;
-           $comp ~= s/^$root//  or die "Component outside comp_root";
-       
-           $interp->exec($comp, %args);
-       
-       This, plus an Action line in httpd.conf mapping *.mas to this script, has
-       so far done the job just fine.
-       
-       One problem I noticed was that this all would've been much harder if I
-       hadn't been familiar with the way ApacheHandler.pm uses CGI.pm and hadn't
-       known where to find that parsing routine. IMHO it'd be a good idea to
-       separate this loop into a user-callable subroutine.
-       
-       (Note: this was Mason 0.6.mumble - I have no experience with the newer
-       versions.)
-       
-       --
-       Ilmari Karonen (iltzu@sci.fi)
-       http://www.sci.fi/~iltzu/
-       
-       _______________________________________________
-       Mason maillist  -  Mason@netizen.com.au
-       http://netizen.com.au/mailman/listinfo/mason
-       
-2000-04-03 00:49  jesse
-
-       * bin/rtmux.pl, etc/schema.mysql, lib/RT/Action.pm,
-       lib/RT/CurrentUser.pm, lib/RT/Scrip.pm, lib/RT/ScripScopes.pm,
-       lib/RT/Template.pm, lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       lib/RT/Watchers.pm, lib/RT/Action/AutoReply.pm,
-       lib/RT/Action/SendEmail.pm:
-
-       Well, that was an exciting afternoon! Er, an exciting evening!
-       *grin* AutoReply now works. which means that all the infrastructure for
-       scrips is back in place.  It required refactoring things a bit. as cool
-       as making RT::Template a MIME::Entity seemed, I just couldn't get it to work
-       right, so now, it just creates a MIME::Entity when it needs it, which is
-       probably better anyway.  I simplified templates a bit. Now they only have
-       access to the Ticket and Transaction. This may not be wise, but we'll see.
-       
-       Also, I merged the two blobs per template (headers and body).
-       
-2000-03-31 08:25  tobiasb
-
-       * bin/webmux.pl:
-
-       rmvd dupl line
-       
-2000-03-31 02:47  jesse
-
-       * Makefile:
-
-       removed old webui hooks from the makefile. bumped the version to 1.3.0
-       
-2000-03-31 02:32  jesse
-
-       * webrt/Elements/Error:
-
-       file Error was initially added on branch rt-1-1.
-       
-2000-03-31 02:32  jesse
-
-       * webrt/Ticket/DisplayTicket:
-
-       file DisplayTicket was initially added on branch rt-1-1.
-       
-2000-03-31 02:32  jesse
-
-       * webrt/: Elements/Error, Elements/SelectStatus,
-       Ticket/Display.html, Ticket/DisplayTicket,
-       Ticket/DisplayTransaction, Ticket/ProcessUpdate.html,
-       Ticket/Update.html:
-
-       Ticket/Update.html will now allow you to submit a ticket update.
-       It's the RT2 equivalent of RT1.0's "comment" and "correspond" pages...
-       with a bit of added value. it's not a global "modify ticket" page. that comes
-       next. but it's where 90% of your single-ticket action will take place.
-       
-2000-03-31 02:28  jesse
-
-       * lib/RT/Ticket.pm:
-
-       TimeTaken should increment now
-       
-2000-03-31 02:26  jesse
-
-       * README:
-
-       added the mason dependency to the README
-       
-2000-03-31 02:25  jesse
-
-       * bin/webmux.pl:
-
-       added some uses to the webmux so I don't have to add them to each page that
-       calls them
-       
-2000-03-30 00:44  jesse
-
-       * webrt/Search/PickRestriction:
-
-       made the variable names in PickRestriction look more like the parameter names
-       in EasySearch. Wanna guess why?
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Search/RestrictSearch.html:
-
-       file RestrictSearch.html was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Search/PickRestriction:
-
-       file PickRestriction was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Elements/Footer:
-
-       file Footer was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/: Elements/Checkbox, Elements/Footer, Elements/Header,
-       Elements/SelectBoolean, Elements/SelectDate,
-       Elements/SelectDateRelation, Elements/SelectOwner,
-       Elements/SelectQueue, Elements/SelectStatus, Elements/dayMenu,
-       Elements/monthMenu, Elements/yearMenu, Search/PickRestriction,
-       Search/RestrictSearch.html:
-
-       A bunch of infrasturcture work on the Ticket Search interface. it doesn't
-       have any real logic behind it. that's next.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Elements/SelectBoolean:
-
-       file SelectBoolean was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Elements/dayMenu:
-
-       file dayMenu was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Elements/SelectStatus:
-
-       file SelectStatus was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Elements/SelectQueue:
-
-       file SelectQueue was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Elements/yearMenu:
-
-       file yearMenu was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Elements/Checkbox:
-
-       file Checkbox was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Elements/Header:
-
-       file Header was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Elements/SelectOwner:
-
-       file SelectOwner was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Elements/monthMenu:
-
-       file monthMenu was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Elements/SelectDateRelation:
-
-       file SelectDateRelation was initially added on branch rt-1-1.
-       
-2000-03-29 23:52  jesse
-
-       * webrt/Elements/SelectDate:
-
-       file SelectDate was initially added on branch rt-1-1.
-       
-2000-03-29 00:33  jesse
-
-       * etc/schema.mysql:
-
-       added a generic "RefersTo" ticket type to the comments.
-       changed the types of Link.Base and Link.Target to VARCHAR(255) from INT(11)
-       
-2000-03-28 05:16  tobiasb
-
-       * README, tools/test:
-
-       darn, it seems like I'll need to install mod-perl ... actually I haven't done that earlier..
-       
-2000-03-28 00:13  jesse
-
-       * Makefile, lib/RT/Record.pm, lib/RT/Transaction.pm,
-       webrt/Search/Listing.html, webrt/Search/QueueItem:
-
-       webrt/Search/Listing.html now gives a basic listing of all open tickets
-       It even has links to the _still display only_ Display.html for each ticket
-       
-2000-03-27 23:55  jesse
-
-       * webrt/Ticket/DisplayTransaction:
-
-       missed this one. sorry.
-       
-2000-03-27 23:55  jesse
-
-       * webrt/Ticket/DisplayTransaction:
-
-       file DisplayTransaction was initially added on branch rt-1-1.
-       
-2000-03-27 23:54  jesse
-
-       * webrt/Ticket/: Display.html, DisplayHistory:
-
-       Hey. Look Ticket/Display.html?id=<int> works!
-       
-2000-03-27 22:35  jesse
-
-       * webrt/Ticket/ToolBar:
-
-       file ToolBar was initially added on branch rt-1-1.
-       
-2000-03-27 22:35  jesse
-
-       * webrt/Ticket/DisplaySummary:
-
-       file DisplaySummary was initially added on branch rt-1-1.
-       
-2000-03-27 22:35  jesse
-
-       * webrt/Ticket/DisplayHistory:
-
-       file DisplayHistory was initially added on branch rt-1-1.
-       
-2000-03-27 22:35  jesse
-
-       * README, webrt/Ticket/DisplayHistory, webrt/Ticket/DisplaySummary,
-       webrt/Ticket/ToolBar:
-
-       Work on WebRT, including a README update!
-       
-       check out  http://s.ly/~jesse/2000_03_28_171606_shot.jpg
-       
-2000-03-27 22:31  jesse
-
-       * lib/RT/Watchers.pm:
-
-       Bugfix in Watchers AdministrativeCc -> AdminCc
-       
-2000-03-27 22:30  jesse
-
-       * webrt/Ticket/: Display.html, Displaysummary, Update.html:
-
-       Work on WebUI. Display.html has slight functionality
-       
-2000-03-27 22:13  tobiasb
-
-       * docs/design_docs/basic-definitions.txt, tools/test:
-
-       minor
-       
-2000-03-27 21:50  tobiasb
-
-       * tools/test:
-
-       added some stuff to the test script
-       
-2000-03-27 21:32  tobiasb
-
-       * lib/RT/: ScripScope.pm, Transaction.pm:
-
-       bugfixing
-       
-2000-03-27 21:22  tobiasb
-
-       * lib/RT/Transaction.pm:
-
-       ...well, even more bugs...
-       
-2000-03-27 21:09  tobiasb
-
-       * lib/RT/: Scrip.pm, ScripScope.pm, Template.pm, Transaction.pm:
-
-       First level bugfixing completed; Now the create (from the cli) calls up the action (though as earlier mentionated no emails are sent).
-       
-2000-03-27 20:54  tobiasb
-
-       * lib/RT/Scrip.pm:
-
-       bgfx
-       
-2000-03-27 20:47  tobiasb
-
-       * lib/RT/Scrip.pm:
-
-       Bugfix
-       
-2000-03-27 20:22  tobiasb
-
-       * lib/RT/ScripScope.pm:
-
-       bugfix
-       
-2000-03-27 20:19  tobiasb
-
-       * docs/design_docs/basic-definitions.txt:
-
-       clarified
-       
-2000-03-27 18:58  tobiasb
-
-       * lib/RT/Action/SendEmail.pm:
-
-       The recipients aren't set anywhere as far as I can see ... and I'm really uncertain what you've thought of with SetEnvelopeTo vs SetTo, etc.  You'd better take a look.  Obviously, this won't work until the recipients are set somehow
-       
-2000-03-27 18:40  tobiasb
-
-       * lib/RT/Action/SendEmail.pm:
-
-       I've mostly only added comments.  Anyway, I must say that I like this
-       code. (maybe I'll say something different when I've tried debugging it
-       ;)
-       
-2000-03-27 17:59  tobiasb
-
-       * lib/RT/ScripScope.pm:
-
-       bugfix
-       
-2000-03-27 17:57  tobiasb
-
-       * lib/RT/Action.pm:
-
-       comment/folding bugfix
-       
-2000-03-27 17:56  tobiasb
-
-       * docs/design_docs/basic-definitions.txt:
-
-       file basic-definitions.txt was initially added on branch rt-1-1.
-       
-2000-03-27 17:56  tobiasb
-
-       * docs/design_docs/basic-definitions.txt:
-
-       (no comment :)
-       
-2000-03-27 17:55  tobiasb
-
-       * docs/design_docs/link-definitions.txt:
-
-       I think maybe those additions might be appreciated by Rouillard ... and this was (hopefully) the last thing I do with design documentation/discussion until 1.3 is finished :)
-       
-2000-03-27 17:33  tobiasb
-
-       * docs/design_docs/link-definitions.txt:
-
-       Doh ... I really shouldn't waste my time on this now ...
-       
-2000-03-27 17:17  tobiasb
-
-       * lib/RT/Scrip.pm:
-
-       Did you ever try to see if those modules would pass `perl -c'? :)
-       
-2000-03-27 16:44  jesse
-
-       * etc/schema.mysql, lib/RT/Action.pm, lib/RT/Scrip.pm,
-       lib/RT/ScripScope.pm, lib/RT/Action/AutoReply.pm,
-       lib/RT/Action/SendEmail.pm:
-
-       Lots of works on Scrip, ScripScope, Action. Tobias: wanna take a look?
-       Basically, now Templates are autoloaded by RT::Scrip.pm and passed into
-       the Action as TemplateObj.  Also, Templates are now of type MIME::Entity,
-       which means that they have all the attributes of mail messages and can
-       just be sent.
-       
-2000-03-27 16:20  tobiasb
-
-       * docs/design_docs/: TransactionTypes.txt, link-definitions.txt:
-
-       Linking definitions
-       
-2000-03-27 16:20  tobiasb
-
-       * docs/design_docs/link-definitions.txt:
-
-       file link-definitions.txt was initially added on branch rt-1-1.
-       
-2000-03-27 16:01  tobiasb
-
-       * docs/README.docs:
-
-       Updated the README to reflect that the docs are old :)
-       
-2000-03-27 15:45  tobiasb
-
-       * README:
-
-       status update
-       
-2000-03-27 15:41  tobiasb
-
-       * lib/RT/ScripScope.pm:
-
-       minor string fix
-       
-2000-03-27 15:36  tobiasb
-
-       * docs/design_docs/subscription-definitions.txt:
-
-       How does the system determinate whom to send mail to?
-       
-       The ScripScope table in the DB should indicate whether a Scrip is relevant
-       for a queue or not /* TobiX thinks that this might eventually be extended to
-       keywords, tickets, etc, and not only Queues */ ... the Scope table should
-       indicate whether the Scrip is relevant for a given transaction type ... then
-       the given Action should determinate whether it applies or not, and finally
-       the Action has to find out (via the Watchers table) whom it applies to, and
-       how to contact them ... and the Template tells how the mails that are sent
-       out should look like.
-       
-2000-03-27 12:33  jesse
-
-       * lib/RT/ScripScopes.pm:
-
-       file ScripScopes.pm was initially added on branch rt-1-1.
-       
-2000-03-27 12:33  jesse
-
-       * lib/RT/: ScripScope.pm, ScripScopes.pm:
-
-       a bit more stub work on ScripScopes for tobias.
-       more work after lunch
-       
-2000-03-27 07:18  tobiasb
-
-       * lib/RT/ScripScope.pm:
-
-       test..?
-       
-2000-03-27 07:04  tobiasb
-
-       * lib/RT/: ScripScope.pm, Scrips.pm:
-
-       Initiated work to get the code understand the Scrips/Scripscope split
-       
-2000-03-27 07:04  tobiasb
-
-       * lib/RT/ScripScope.pm:
-
-       file ScripScope.pm was initially added on branch rt-1-1.
-       
-2000-03-27 06:55  tobiasb
-
-       * etc/schema.mysql:
-
-       Added yet a stupid design thought as a comment:
-       
-       # {{{ TABLE ScripScope
-         (...)
-         Queue INT(11), #Queue Id 0 for global
-                        # (maybe there might be conditions where otherb
-                        # Scopes apply, i.e. a ticket, keyword, owner, etc?)
-       
-2000-03-27 00:45  jesse
-
-       * lib/RT/Action/Notify.pm:
-
-       Oops. forgot to commit Notify.pm
-       
-2000-03-27 00:45  jesse
-
-       * lib/RT/Action/Notify.pm:
-
-       file Notify.pm was initially added on branch rt-1-1.
-       
-2000-03-27 00:44  jesse
-
-       * lib/RT/Action/NotifyOnResolve.pm:
-
-       file NotifyOnResolve.pm was initially added on branch rt-1-1.
-       
-2000-03-27 00:44  jesse
-
-       * etc/schema.mysql, lib/RT/Ticket.pm,
-       lib/RT/Action/NotifyOnResolve.pm, lib/RT/Action/NotifyWatchers.pm:
-
-       Work on Notify (Formerly NotifyWatchers)
-       Work on NotifyOnResolve (Formerly NotifyWatchersOnResolve)
-       
-       They don't _work_ per se. But they're getting closer. I'm wondering
-       whether we want to do something smarter with all the addresses we're passing
-       in to make it easier to remove specific ones...for example, we currently
-       have no way to _not_ send mail to the reuqestor.
-       
-2000-03-26 18:13  jesse
-
-       * lib/RT/Action/: AutoReply.pm, SendEmail.pm:
-
-       AutoReply is now a proper subclass of SendEmail.pm
-       Maybe tonight, I'll try to get through some work on the Scrips and ScripScope stuff to make it work again.
-       then to wrok on NotifyWatchers.pm
-       
-2000-03-25 01:03  jesse
-
-       * Makefile, lib/RT/Template.pm, lib/RT/Ticket.pm,
-       lib/RT/Action/SendEmail.pm:
-
-       Work on the templating system. I actually gutted Template.pm and SendEmail.pm
-       (sorry tobix :/)  Basically RT::Template is now A MIME::Entity object, which
-       means that the various things one can do to mail messages can now be done to
-       RT::Template objects, once you run $TemplateObj->Parse on them..
-       SendEmail was cleaned up somewhat to be less intimidating to people who aren't
-       as comfortable with big chunks of fairly dense perl.  Oh and it's a heck of a
-       lot more subclassable now ;)
-       
-       Fixed a tiny bug in Ticket.pm resulting from the changes to Watchers.
-       
-2000-03-24 08:29  tobiasb
-
-       * tools/test:
-
-       I'm making a test suite which is intended to be run off from the Makefile after an install
-       
-2000-03-24 08:29  tobiasb
-
-       * tools/test:
-
-       file test was initially added on branch rt-1-1.
-       
-2000-03-24 08:06  tobiasb
-
-       * etc/schema.mysql:
-
-       Added some more noise
-       
-2000-03-23 23:41  jesse
-
-       * subscription-definitions.txt,
-       docs/design_docs/subscription-definitions.txt, etc/schema.mysql,
-       lib/RT/Action/NotifyWatchers.pm, lib/RT/Action/SendEmail.pm:
-
-       A little bit of cleanup to the SendEmail and NotifyWatchers actions.
-       I probably did more damage than good, but that's what I get for messing
-       with code that makes little sense to me.
-       
-2000-03-23 23:41  jesse
-
-       * docs/design_docs/subscription-definitions.txt:
-
-       file subscription-definitions.txt was initially added on branch rt-1-1.
-       
-2000-03-23 22:19  jesse
-
-       * webrt/Search/BuildSearch:
-
-       Testing the setgid repository. commiting an empty file
-       
-2000-03-23 22:19  jesse
-
-       * webrt/Search/BuildSearch:
-
-       file BuildSearch was initially added on branch rt-1-1.
-       
-2000-03-23 00:50  jesse
-
-       * webrt/Search/QueueFooter:
-
-       file QueueFooter was initially added on branch rt-1-1.
-       
-2000-03-23 00:50  jesse
-
-       * webrt/Search/QueueItem:
-
-       file QueueItem was initially added on branch rt-1-1.
-       
-2000-03-23 00:50  jesse
-
-       * webrt/Search/QueueHeader:
-
-       file QueueHeader was initially added on branch rt-1-1.
-       
-2000-03-23 00:50  jesse
-
-       * webrt/Admin/ModifyUser:
-
-       file ModifyUser was initially added on branch rt-1-1.
-       
-2000-03-23 00:50  jesse
-
-       * lib/RT/Action/NotifyWatchers.pm:
-
-       file NotifyWatchers.pm was initially added on branch rt-1-1.
-       
-2000-03-23 00:50  jesse
-
-       * Makefile, bin/rtmux.pl, etc/schema.mysql, lib/RT/Queue.pm,
-       lib/RT/Scrip.pm, lib/RT/Ticket.pm, lib/RT/Watcher.pm,
-       lib/RT/Action/NotifyWatchers.pm, webrt/Admin/ModifyUser,
-       webrt/Search/Listing.html, webrt/Search/QueueFooter,
-       webrt/Search/QueueHeader, webrt/Search/QueueItem,
-       webrt/Ticket/Displaysummary:
-
-       Did a bit of hacking on webrt2
-       Redid the watchers system according to what I posted earlier to rt-devel
-       Scrips have now broken..but we'll get them working again really soon.
-       Queue Cc and AdminCc now exist in cli adminrt.
-       
-2000-03-22 14:56  tobiasb
-
-       * subscription-definitions.txt:
-
-       definitions in the subscription system
-       
-2000-03-22 14:56  tobiasb
-
-       * subscription-definitions.txt:
-
-       file subscription-definitions.txt was initially added on branch rt-1-1.
-       
-2000-03-22 14:42  tobiasb
-
-       * etc/schema.mysql:
-
-       This is a suggestion about a simple splitting of the Scrips table.  I
-       think the admin tools will be significantly easier to set up if we do
-       it this way.  An administrator can through some UI just add and remove
-       Scrips from a queue.
-       
-2000-03-22 01:02  jesse
-
-       * lib/RT/: ACE.pm, ACL.pm, Action.pm, Area.pm, Areas.pm,
-       Attachment.pm, Attachments.pm, CurrentUser.pm, EasySearch.pm,
-       Queue.pm, Queues.pm, Record.pm, Scrip.pm, Scrips.pm, Template.pm,
-       Templates.pm, Ticket.pm, Tickets.pm, Transaction.pm,
-       Transactions.pm, User.pm, Users.pm, Utils.pm, Watcher.pm,
-       Watchers.pm, Action/AutoReply.pm, Action/MailComment.pm,
-       Action/SendEmail.pm, Interface/Email.pm:
-
-       This may look like a lot of code. but it's not.
-       It's merely the result of running
-       
-       perl -pi.bak -e 's/sub (.*?){\n/# {{{ sub $1\nsub $1 {\n/; s/^}$/}\n# }}}/'
-       
-       basically, this adds # {{{ sub function
-                        and # }}}
-       around all the function names. The main reason to do this is for
-       emacs fold-minor-mode.  It makes things a lot easier to read.
-       In an ideal world, we'd have perl-aware folding editor and there'd be
-       no need for this markup
-       
-2000-03-21 20:38  jesse
-
-       * lib/RT/: Queue.pm, Ticket.pm, Watcher.pm, Watchers.pm:
-
-       Work on watchers.
-       
-2000-03-20 15:21  jesse
-
-       * etc/schema.mysql:
-
-       Modified the schema for my "New Improved Watchers" system. Basically,
-       now you'll be able to tie a template to a given watch. along with a
-       boolean "send mail" flag.  We'll need a special "Mail Watchers" action to
-       make this all work..but the code should be pretty easy.
-       
-               jesse
-       
-2000-03-20 05:27  tobiasb
-
-       * bin/initdb.mysql:
-
-       bugfix
-       
-2000-03-17 15:20  jesse
-
-       * webrt/Ticket/Create.html:
-
-       file Create.html was initially added on branch rt-1-1.
-       
-2000-03-17 15:20  jesse
-
-       * webrt/Ticket/DisplayHeader:
-
-       file DisplayHeader was initially added on branch rt-1-1.
-       
-2000-03-17 15:20  jesse
-
-       * webrt/Ticket/SetOwner:
-
-       file SetOwner was initially added on branch rt-1-1.
-       
-2000-03-17 15:20  jesse
-
-       * webrt/Ticket/SetStatus:
-
-       file SetStatus was initially added on branch rt-1-1.
-       
-2000-03-17 15:20  jesse
-
-       * webrt/Ticket/: Create.html, Display.html, DisplayHeader,
-       Displaysummary, SetOwner, SetStatus, Update.html:
-
-       More work on the basic webui
-       
-2000-03-17 15:20  jesse
-
-       * webrt/Ticket/Displaysummary:
-
-       file Displaysummary was initially added on branch rt-1-1.
-       
-2000-03-17 11:32  tobiasb
-
-       * bin/initdb.mysql:
-
-       Bugfix, the password passing didn't work as it should.
-       
-2000-03-17 10:52  tobiasb
-
-       * etc/schema.mysql:
-
-       - Slashed away the old "MailQueueMembersOn..." junk.
-       
-       - Added Scrips to the Watchers table.  ... the Watchers/Scrips system
-       seems quite flexible .. BUT .. I have a certain feeling that it might
-       be hard to make administration tools that helps a non-hacking
-       administrator to find out which mails are sent where, etc.  Well,
-       that's something we'll have to worry about later :)
-       
-2000-03-17 08:47  tobiasb
-
-       * Makefile, etc/schema.mysql:
-
-       removed some instanses of 'su' that really shouldn't be needed, and which also broke on anything but GNU shellutils
-       
-2000-03-17 07:32  tobiasb
-
-       * README:
-
-       Some additions and changes to reflect that this is, after all, a
-       development version.  Meri, do you subscribe to cvs-commit? :)
-       
-2000-03-17 06:01  tobiasb
-
-       * etc/schema.mysql:
-
-       # Those subscription field are not used in RT 1.1 as I see it.
-       # I think we should modify the Scrips system so it by default
-       # respects those fields.
-        MailOwnerOnTransaction INT,             # notify owner on transaction
-        MailMembersOnTransaction INT,          # notify list members on transaction
-        MailRequestorOnTransaction INT,        # notify requestor on transaction
-        MailRequestorOnCreation INT,           # notify user on creation
-        MailMembersOnCorrespondence INT,               # notify members on creation
-        MailMembersOnComment INT,              # notify members on comment
-       
-2000-03-16 16:31  jesse
-
-       * webrt/: Search/Listing.html, Ticket/Display.html,
-       Ticket/Modify.html, Ticket/ProcessUpdate.html, Ticket/Update.html,
-       Ticket/ValidateUpdate.html:
-
-       The beginnings of the All New! Web UI based around HTML::Mason
-       There's nothing functional here yet. but it's a start at a framework.
-       Ticket/Update.html is probably the closest to "real" code so far.
-       
-2000-03-16 16:31  jesse
-
-       * webrt/Ticket/ValidateUpdate.html:
-
-       file ValidateUpdate.html was initially added on branch rt-1-1.
-       
-2000-03-16 16:31  jesse
-
-       * webrt/Ticket/Display.html:
-
-       file Display.html was initially added on branch rt-1-1.
-       
-2000-03-16 16:31  jesse
-
-       * webrt/Ticket/Modify.html:
-
-       file Modify.html was initially added on branch rt-1-1.
-       
-2000-03-16 16:31  jesse
-
-       * webrt/Search/Listing.html:
-
-       file Listing.html was initially added on branch rt-1-1.
-       
-2000-03-16 16:31  jesse
-
-       * webrt/Ticket/ProcessUpdate.html:
-
-       file ProcessUpdate.html was initially added on branch rt-1-1.
-       
-2000-03-16 16:31  jesse
-
-       * webrt/Ticket/Update.html:
-
-       file Update.html was initially added on branch rt-1-1.
-       
-2000-03-16 14:46  tobiasb
-
-       * Makefile:
-
-       Changed the default database name from rt to RT to avoid confusion with previously installed versions of rt
-       
-2000-03-16 02:34  tobiasb
-
-       * lib/RT/User.pm:
-
-       Bugfixes:  It was impossible not to give requests to somebody.
-       
-2000-03-16 01:32  tobiasb
-
-       * lib/RT/Interface/Email.pm:
-
-       Bugfixes
-       
-       was
-       
-         if ($CurrentUser->Id == 0) {
-           #If it fails, create a user
-       
-       now
-       
-         unless ($CurrentUser->Id) {
-           #If it fails, create a user
-       
-       as Id returned undef.
-       
-       Changed 'Queue' to 'QueueTag'.
-       
-       Added some few comments
-       
-2000-03-14 00:40  jesse
-
-       * README:
-
-       Modified the README for the beginnings of the new webui
-       
-2000-03-14 00:39  jesse
-
-       * bin/: rtmux.pl, webmux.pl:
-
-       added webmux. modified rtmux.pl to clean out some cruft
-       
-2000-03-14 00:39  jesse
-
-       * bin/webmux.pl:
-
-       file webmux.pl was initially added on branch rt-1-1.
-       
-2000-03-13 12:53  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       rt-mailgate has now recieved and logged correspondence and comments with current schema.
-       
-2000-03-08 23:26  jesse
-
-       * lib/RT/: Ticket.pm, Transaction.pm:
-
-       DBIx cleanups to deal with load by id when id is null
-       Work on comment and correspond. Eventually, we'll get the
-       per-transaction cc and bcc working.
-       
-2000-03-08 18:22  jesse
-
-       * bin/rtmux.pl, lib/RT/Queue.pm, lib/RT/Ticket.pm,
-       lib/RT/Transaction.pm, lib/RT/User.pm:
-
-       rtq works a bit better
-       rtadmin works again.
-       rtadmin -user create
-               -user modify
-        both seem to work ok
-       
-       rt -create now makes sure a queue exists and permits ticket creation
-       rt -create now make sure a prospective owner has queue membership.
-       
-2000-03-02 17:23  tobiasb
-
-       * lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       lib/RT/Action/SendEmail.pm, etc/schema.mysql:
-
-       resolve, open, take (if unowned, at least) seems to work
-       
-2000-03-02 16:10  tobiasb
-
-       * lib/RT/: Ticket.pm, Ticket.pm:
-
-       Bugfixing
-       
-2000-03-02 14:35  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Correspondence almost works
-       
-2000-03-02 13:26  tobiasb
-
-       * lib/RT/Ticket.pm, lib/RT/Action/MailComment.pm, etc/schema.mysql:
-
-       Comments almost work now (from the cli)
-       
-2000-03-02 12:38  tobiasb
-
-       * lib/RT/Action/: MailComment.pm, MailCorrespondence.pm:
-
-       one minor bugfix + some comments
-       
-2000-03-01 23:58  jesse
-
-       * NEWS:
-
-       brought the news up to date.
-       nuked old /contrib
-       nuked old /etc/templates.
-       
-       bedtime now.
-       
-2000-03-01 23:57  jesse
-
-       * NEWS:
-
-       brought the news up to date (a bit)
-       
-2000-03-01 23:50  jesse
-
-       * Makefile:
-
-       removed a lot of outdated cruft.
-       Bumped the version to 1.1.11 for a release later this week.
-       
-2000-03-01 23:18  jesse
-
-       * lib/RT/: Ticket.pm, Interface/Email.pm:
-
-       The mail gateway now lets you create, comment and correspond on tickets.
-       Ticket->Owner now deals better when the owner is NULL
-       
-2000-03-01 21:27  jesse
-
-       * HACKING:
-
-       minor comments added to hacking
-       
-2000-03-01 21:20  jesse
-
-       * HACKING:
-
-       Trivial change to HACKING to test commitinfo
-       
-2000-03-01 21:09  jesse
-
-       * lib/RT/Interface/Email.pm:
-
-       file Email.pm was initially added on branch rt-1-1.
-       
-2000-03-01 21:09  jesse
-
-       * bin/rtmux.pl, lib/RT/Interface/Email.pm:
-
-       work on mailgate
-       
-2000-03-01 18:36  tobiasb
-
-       * docs/design_docs/TransactionTypes.txt, etc/schema.mysql:
-
-       Some loose thoughts only ... as comments and a doc which I'm not sure
-       if it's possible to understand by others than me anyway :)
-       
-       Anyway, it is too complex.  We'll just continue following the current design.
-       
-2000-03-01 18:36  tobiasb
-
-       * docs/design_docs/TransactionTypes.txt:
-
-       file TransactionTypes.txt was initially added on branch rt-1-1.
-       
-2000-03-01 17:51  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Seems like it's a lot of things that doesn't work here.
-       
-2000-03-01 16:26  tobiasb
-
-       * etc/schema.mysql:
-
-       Ehm ... maybe I forgot to commit this one.  It contains some fixes.
-       
-2000-03-01 16:08  jesse
-
-       * TODO:
-
-       ripped a bit of obsolete code from rtmux.pl
-       updated the TODO to reference the production instance of RT.
-       
-2000-03-01 14:48  jesse
-
-       * bin/rtmux.pl:
-
-       removed the old web ui hooks from rtmux.pl
-       
-2000-03-01 12:12  tobiasb
-
-       * lib/RT/: Action.pm, Scrip.pm, Template.pm, Ticket.pm,
-       Watchers.pm, Action/AutoReply.pm, Action/SendEmail.pm:
-
-       I've done some debugging and polishing.  I hope it won't break with stuff you're eventually working with
-       
-2000-02-29 16:58  tobiasb
-
-       * lib/RT/: Queue.pm, Ticket.pm, Watchers.pm:
-
-       One sort of bugfix..
-       
-2000-02-29 16:35  tobiasb
-
-       * lib/RT/: Queue.pm, Template.pm, Ticket.pm, Watcher.pm,
-       Watchers.pm, Action/SendEmail.pm:
-
-       Scrips work for me.  Well, I'm not that sure anyway.  I had actually
-       expected one email to drop in for each Scrip - but I only got the
-       AutoReply and the Correspondence.  Maybe I should debug even more.
-       
-2000-02-29 14:29  tobiasb
-
-       * lib/RT/Watchers.pm:
-
-       LimitToTicket updated (not tested, though)
-       LimitToQueue added     (not tested, though)
-       
-2000-02-29 14:27  tobiasb
-
-       * etc/schema.mysql:
-
-       
-       # Primarly used by RT::Actions::SendEmail as well as some subclasses
-       # to determinate whom to send emails to.  This scheme should work out
-       # better than the scheme under RT 1.0, and should suit most users.
-       # For more fine grained control, it's possible to create tables as you
-       # like and make a new subclass of RT::Actions::SendEmail where the
-       # SetRecepients sub is overloaded :)
-       
-       CREATE TABLE Watchers (
-          id int(11) AUTO_INCREMENT PRIMARY KEY,
-          Value int(11),
-          Scope varchar(16), # Might be "Queue" and "Ticket" as for now
-                             # ... might be extended to "Keywords", "Owners", etc.
-          Email VARCHAR(255),
-          Type VARCHAR(16), #Requestor, Cc, Bcc
-          Creator INT(11),
-          Created TIMESTAMP,
-          LastUpdatedBy INT(11),
-          LastUpdated TIMESTAMP
-       )\g
-       
-2000-02-29 13:40  tobiasb
-
-       * etc/schema.mysql:
-
-       CREATE TABLE Watchers (
-          id int(11) AUTO_INCREMENT PRIMARY KEY,
-          Ticket int(11), # 0 for all
-          Queue int(11), # 0 for all
-               # We might consider adding more power here,
-               # i.e. TransactionType, Scrip, etc
-          Email VARCHAR(255),
-          Type VARCHAR(16), #Requestor, Cc, Bcc
-          Creator INT(11),
-          Created TIMESTAMP,
-          LastUpdatedBy INT(11),
-          LastUpdated TIMESTAMP
-       )\g
-       
-2000-02-29 10:43  tobiasb
-
-       * etc/schema.mysql:
-
-       Template.{content and title} => Content and Title - since we use
-       UpperCase in the rest of the DD.
-       
-2000-02-29 10:31  tobiasb
-
-       * etc/schema.mysql:
-
-       Blob, that is..
-       
-2000-02-29 10:12  tobiasb
-
-       * etc/schema.mysql:
-
-       Added ExtraHeaders as VARCHAR(255).  255 characters should be enough
-       for storing some few extra header lines, but anyway maybe it should
-       have been blob instead?
-       
-2000-02-29 09:51  tobiasb
-
-       * lib/RT/: Attachment.pm, Action/AutoReply.pm, Action/SendEmail.pm:
-
-       I've continued the work on mail sending.  There is still some missing
-       stuff:
-       
-       1. EasySearch/Scrips issue - currently it doesn't properly output "
-       all scrips that has (queue=0 or queue=this) and (type="any" or type=this)".
-       
-       2. A serious stub in RT::Action::SendEmail - I don't know where to find
-       "interessted parties".  I think it could be nice putting queue watchers
-       in the same table as ticket watchers.
-       
-2000-02-29 09:42  tobiasb
-
-       * lib/RT/Scrips.pm:
-
-       Hack - everything that applies for a Correspondence action also
-       applies for a Create action (I'd daresay).
-       
-2000-02-29 07:02  tobiasb
-
-       * lib/RT/Transaction.pm:
-
-       Some insignificant changes.  Well, one marginally significant; it
-       shouldn't $Scrip->Commit unless $Scrip->Prepare()
-       
-2000-02-29 04:12  tobiasb
-
-       * etc/schema.mysql:
-
-       I've started at general transaction emails.
-       
-2000-02-29 03:58  tobiasb
-
-       * lib/RT/Watchers.pm:
-
-       Added an Emails method.  It can be used like:
-       
-          print join(",", @{$Watchers->Emails("Requestors")});
-       
-       or
-       
-          $Watchers->LimitToRequestors;
-          $Emails=$Watchers->Emails;
-       
-       ...
-       
-2000-02-29 02:31  tobiasb
-
-       * lib/RT/Action/SendEmail.pm:
-
-       Sender => RT-Originator
-       
-2000-02-29 00:40  jesse
-
-       * README:
-
-       Added Into Netowrks and Funcom to the thanks at the top of the readme
-       `
-       
-2000-02-28 23:20  jesse
-
-       * Makefile:
-
-       RT 1.1.10 released. Tobix has autoreply basically working :)
-       
-2000-02-28 22:49  jesse
-
-       * Makefile, NEWS, README:
-
-       Fixed a longstanding bug in the WebRT administrator
-       added a note about stripmime to the readme.
-       added a bit of code from curl.com that adds functionality to rtq for reporting
-       
-2000-02-28 22:17  jesse
-
-       * Makefile, NEWS:
-
-       bumped the version for release of 1.0.2
-       
-2000-02-28 11:33  tobiasb
-
-       * lib/RT/: Template.pm, Transaction.pm, Action/AutoReply.pm,
-       Action/SendEmail.pm:
-
-       AutoReply seems to work now ... except that rtadmin didn't set email
-       aliases for the queue, so the mail bounces with invalid from address.
-       I won't look more at this until tomorrow.  You're very welcome to take
-       over for a while if you feel like it :)
-       
-2000-02-28 11:29  tobiasb
-
-       * etc/schema.mysql:
-
-       AutoReply seems to work now
-       
-2000-02-28 08:18  tobiasb
-
-       * HACKING:
-
-       Added some hints and misc.  Please look through.
-       
-2000-02-28 05:25  tobiasb
-
-       * lib/RT/: Ticket.pm, Transaction.pm, Action/AutoReply.pm,
-       Action/SendEmail.pm:
-
-       - The queue tag rather than queue id is delievered from the cli, this
-         broke in Ticket::Create.  Fixed.
-       
-       - The Attachments have to be assigned to a transaction before Scrips
-          is run.  Now the Attachments are delievered as a part of the parameters
-          to Transaction::Create
-       
-2000-02-27 23:28  tobiasb
-
-       * etc/schema.mysql:
-
-       Fixed the AutoReply template ... still not tested, though.
-       
-2000-02-27 22:04  tobiasb
-
-       * lib/RT/Action/: AutoReply.pm, SendEmail.pm:
-
-       I think we can nuke the old rt/lib/rt/support/mail.pm now - everything
-       should be located in SendEmail.pm, AutoReply.pm and Template.pm by now :)
-       
-       It's not tested yet, and the templates needs upgrading.  Anyway, I will
-       probably not mess more around with the perl code as for now.
-       
-2000-02-27 21:43  tobiasb
-
-       * bin/rtmux.pl:
-
-       Seems like $rtversion="!!RT_VERSION!!" had disappeared.  I renamed the
-       variable to $VERSION.
-       
-2000-02-27 21:22  jesse
-
-       * lib/RT/Ticket.pm:
-
-       dates now display in the cli.
-       
-2000-02-27 20:53  tobiasb
-
-       * lib/RT/Templates.pm:
-
-       Fixed DBIx::EasySearch => RT::EasySearch
-       
-2000-02-27 20:53  tobiasb
-
-       * lib/RT/Template.pm:
-
-       Method Template::Parse added, Text::Template used for the moment.
-       
-       (sigh ... that means my next worktask will be to update the
-       templates...)
-       
-2000-02-27 20:49  jesse
-
-       * lib/RT/Ticket.pm:
-
-       so. Ticket->Create now actually figures out ccs and bccs and requestors from the mime
-       object passed in to it.
-       
-2000-02-27 19:05  jesse
-
-       * lib/RT/Transaction.pm:
-
-       added a comment for tobias about a new line that didn't make sense.
-       
-2000-02-27 18:46  jesse
-
-       * lib/RT/: Ticket.pm, Watchers.pm:
-
-       watchers updates.
-       
-2000-02-27 17:25  tobiasb
-
-       * lib/RT/Template.pm:
-
-       file Template.pm was initially added on branch rt-1-1.
-       
-2000-02-27 17:25  tobiasb
-
-       * lib/RT/: Attachment.pm, Template.pm, Templates.pm,
-       Action/AutoReply.pm, Action/SendEmail.pm:
-
-       Development snapshot.  I guess I'll have it working in half an hour
-       with _efficient_ working, that is some four hours working at my
-       current efficiency rate :/
-       
-2000-02-27 17:25  tobiasb
-
-       * lib/RT/Templates.pm:
-
-       file Templates.pm was initially added on branch rt-1-1.
-       
-2000-02-27 16:43  tobiasb
-
-       * etc/schema.mysql:
-
-       Added some templates
-       
-2000-02-27 11:19  tobiasb
-
-       * lib/RT/: Scrip.pm, Transaction.pm:
-
-       development snapshot
-       
-2000-02-27 10:31  tobiasb
-
-       * lib/RT/Action/: AutoReply.pm, MailComment.pm,
-       MailCorrespondence.pm, SendEmail.pm:
-
-       I've started bashing at the mail sending functionallity.  It seemed quite
-       stubbed to me.
-       
-2000-02-24 03:44  tobiasb
-
-       * etc/schema.mysql:
-
-       minor bug in comment
-       
-2000-02-24 03:24  tobiasb
-
-       * lib/RT/Action/SendEmail.pm:
-
-       clearing out a potential weird bug
-       
-2000-02-24 00:27  jesse
-
-       * lib/RT/Scrips.pm:
-
-       Fixed a typo in my code near tobix' changes to Scrips.pm. his changes look good.
-       
-2000-02-24 00:03  jesse
-
-       * Makefile, NEWS, README:
-
-       little fix to mail manipulate from "Heather L. Sherman" <heather@idealab.com>
-       
-2000-02-23 17:06  tobiasb
-
-       * lib/RT/: Scrips.pm, Action/SendEmail.pm:
-
-       Some small fixes.  You'd better look through it, as I'm not completely sure what I'm doing :)
-       
-2000-02-23 16:07  tobiasb
-
-       * etc/schema.mysql:
-
-       An insert entry here reffers to SendMail.pm, while the file is SendEmail.pm
-       
-2000-02-23 15:26  jesse
-
-       * docs/rt-templates.html:
-
-       [no log message]
-       
-2000-02-23 11:38  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Could not get 'rt -create' working.  It seems more sane now, but I'm not really sure what I'm doing ... so you should have a peek at it.  I changed  $Id->SUPER::_Set("EffectiveId",$id); to $self->SUPER::_Set etc
-       
-2000-02-22 23:35  jesse
-
-       * lib/RT/InterestedParty.pm:
-
-       removed vestigal code
-       
-2000-02-22 23:25  jesse
-
-       * etc/schema.mysql, lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       lib/RT/Transactions.pm, lib/RT/Watchers.pm:
-
-       A bit more work on watchers. we're getting close.
-       rtq works today.
-       rt -create basically works.
-       rt -take works.
-       
-       rt -show will now start to show ownership changes.
-       
-2000-02-22 08:06  jesse
-
-       * Makefile, etc/schema.mysql, lib/RT/Ticket.pm:
-
-       Work on Watchers.  Most of the code needed to make this work is now
-       present. sadly I haven't even _tried_ to run it yet.
-       
-2000-02-21 01:33  jesse
-
-       * lib/RT/Watcher.pm:
-
-       file Watcher.pm was initially added on branch rt-1-1.
-       
-2000-02-21 01:33  jesse
-
-       * lib/RT/: InterestedParties.pm, InterestedParties.pm~,
-       Notification.pm, Ticket.pm, Watcher.pm, Watchers.pm:
-
-       Renamed interested parties to "Watchers"
-       Watchers are now keyed by EmailAddress rather than UserId. Not every CC will have an rt account, i think
-       
-2000-02-21 01:33  jesse
-
-       * lib/RT/Watchers.pm:
-
-       file Watchers.pm was initially added on branch rt-1-1.
-       
-2000-02-20 18:28  jesse
-
-       * lib/RT/InterestedParties.pm~:
-
-       file InterestedParties.pm~ was initially added on branch rt-1-1.
-       
-2000-02-20 18:28  jesse
-
-       * lib/RT/InterestedParties.pm:
-
-       file InterestedParties.pm was initially added on branch rt-1-1.
-       
-2000-02-20 18:28  jesse
-
-       * lib/RT/InterestedParty.pm:
-
-       file InterestedParty.pm was initially added on branch rt-1-1.
-       
-2000-02-20 18:28  jesse
-
-       * lib/RT/: InterestedParties.pm, InterestedParties.pm~,
-       InterestedParty.pm:
-
-       [no log message]
-       
-2000-02-20 18:24  jesse
-
-       * etc/schema.mysql, lib/RT/Ticket.pm:
-
-       [no log message]
-       
-2000-02-20 15:27  jesse
-
-       * etc/schema.mysql, lib/RT/Action.pm, lib/RT/Scrip.pm,
-       lib/RT/Action/AutoReply.pm, lib/RT/Action/SendEmail.pm:
-
-       Work on scrips. stubs for the webui
-       
-2000-02-19 17:45  jesse
-
-       * lib/RT/: Action.pm, Scrip.pm:
-
-       work on actions. checking in for eric to take a look
-       
-2000-02-19 16:48  jesse
-
-       * lib/RT/Action/AutoReply.pm:
-
-       file AutoReply.pm was initially added on branch rt-1-1.
-       
-2000-02-19 16:48  jesse
-
-       * lib/RT/Action/MailCorrespondence.pm:
-
-       file MailCorrespondence.pm was initially added on branch rt-1-1.
-       
-2000-02-19 16:48  jesse
-
-       * lib/RT/Action.pm:
-
-       file Action.pm was initially added on branch rt-1-1.
-       
-2000-02-19 16:48  jesse
-
-       * lib/RT/Action/MailComment.pm:
-
-       file MailComment.pm was initially added on branch rt-1-1.
-       
-2000-02-19 16:48  jesse
-
-       * lib/RT/: Action.pm, Action/AutoReply.pm, Action/MailComment.pm,
-       Action/MailCorrespondence.pm, Action/SendEmail.pm:
-
-       As it turns out, Action needed to be abstracted a bit and renamed.
-       
-       I'm also making the Object syntax a bit.
-       
-2000-02-19 16:48  jesse
-
-       * lib/RT/Action/SendEmail.pm:
-
-       file SendEmail.pm was initially added on branch rt-1-1.
-       
-2000-02-17 09:19  jesse
-
-       * etc/schema.mysql, lib/RT/Scrip.pm, lib/RT/Scrips.pm,
-       lib/RT/Transaction.pm:
-
-       The base architecture for Scrips to work should now be in place.
-       Next up: write example "Actions" (gotta move the Scrips directory to Actions)
-       for the scrip handlers to use.
-       
-2000-02-16 09:59  jesse
-
-       * lib/RT/: Scrip.pm, Transaction.pm:
-
-       Starting to make scrips actually work
-       
-2000-02-10 23:24  jesse
-
-       * lib/RT/Scrips.pm:
-
-       file Scrips.pm was initially added on branch rt-1-1.
-       
-2000-02-10 23:24  jesse
-
-       * lib/RT/: Scrip.pm, Scrips.pm, Transaction.pm:
-
-       more work stubbing scrips. but now my arms hurt badly enough that i'm going to log out.
-       
-2000-02-10 23:24  jesse
-
-       * lib/RT/Scrip.pm:
-
-       file Scrip.pm was initially added on branch rt-1-1.
-       
-2000-01-31 02:38  tobiasb
-
-       * README, lib/RT/Attachments.pm:
-
-       does the commit automail work now?
-       
-2000-01-30 23:54  jesse
-
-       * NEWS, README, etc/schema.mysql, lib/RT/CurrentUser.pm,
-       lib/RT/Record.pm, lib/RT/User.pm:
-
-       Work on the User object.
-       The mail gateway now autocreates users. (This will make more sense
-       once we start tying tickets to users by means of the InterestedParties table.
-       
-2000-01-29 01:33  jesse
-
-       * Makefile:
-
-       makefile cleanup. including removing the C compiler and template and
-       transaction directories
-       
-2000-01-29 01:30  jesse
-
-       * Makefile:
-
-       removed C compiler from the makefile
-       
-2000-01-29 01:25  jesse
-
-       * Makefile:
-
-       Removed C compiler from the makefile. we just don't need it anymore
-       
-2000-01-29 01:22  jesse
-
-       * Makefile:
-
-       bumped version to 1-1-8
-       
-2000-01-29 01:20  jesse
-
-       * Makefile:
-
-       removed template and transaction paths from the makefile.
-       (to test new cvs wrappers and cuz they should be gona anyway)
-       
-2000-01-29 00:26  jesse
-
-       * etc/schema.mysql:
-
-       Started to do work on scrips. see the schema for how it would work.
-       
-2000-01-28 20:04  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Some modifications and bugfixes on the messages popping up after a `successful' correspondence/comment
-       
-2000-01-28 19:47  tobiasb
-
-       * lib/RT/Ticket.pm:
-
-       Removed some annoying warnings.  I don't know if this is the "right"
-       way to remove them, but it works (for me, at least), it's an easy
-       way to do it, and it's harmless;
-       
-       instead of writing
-               $var_that_might_be_undef
-       I write
-               $var_that_might_be_undef || ""
-       eventually with parantheses, and eventually with "" replaced by 0, or maybe
-       (not tested) even undef.
-       
-2000-01-28 13:22  tobiasb
-
-       * Makefile:
-
-       Two substitution parameters was forgotten in config.pm
-       
-2000-01-28 13:12  tobiasb
-
-       * etc/schema.mysql:
-
-       Oups, committed the wrong file
-       
-2000-01-28 13:10  tobiasb
-
-       * Makefile, etc/schema.mysql:
-
-       Two substitution parameters was forgotten in config.pm
-       
-2000-01-27 04:09  tobiasb
-
-       * Makefile, bin/initdb.mysql:
-
-       small password fix
-       
-2000-01-25 23:26  jesse
-
-       * Makefile:
-
-       bumped the version to 1.1.7 for tonight's release.
-       
-2000-01-25 23:12  jesse
-
-       * lib/RT/: Attachments.pm, Ticket.pm, Transaction.pm:
-
-       DBIx::EasySearch now has a -> First method. which is like -> Next, but picks
-       the first element
-       
-       DBIx::Record -> now returns '' rather than undef for null values. it's less
-       likely to break interfaces.
-       
-2000-01-25 16:36  tobiasb
-
-       * README:
-
-       aargh
-       
-2000-01-25 16:31  tobiasb
-
-       * TODO:
-
-       test
-       
-2000-01-25 14:57  tobiasb
-
-       * etc/schema.mysql:
-
-       bugfix
-       
-2000-01-25 14:44  tobiasb
-
-       * Makefile:
-
-       removed obsoleteness
-       
-2000-01-25 14:37  tobiasb
-
-       * README:
-
-       The UPGRADE section of the README was inaccurate
-       
-2000-01-25 14:31  tobiasb
-
-       * lib/RT/Transaction.pm:
-
-       comment bug
-       
-2000-01-24 01:45  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-2000-01-24 01:43  jesse
-
-       * Makefile, NEWS, lib/RT/Attachment.pm, lib/RT/Attachments.pm,
-       lib/RT/Record.pm, lib/RT/Ticket.pm, lib/RT/Tickets.pm,
-       lib/RT/Transaction.pm, lib/RT/Transactions.pm:
-
-       
-       * Attachments support in code. rtq now basically works
-         Mailgate creates new tickets
-         rt -show now works a bit (doesn't display transaction content yet)
-         rt -subject works. several other commandline tools work
-       
-2000-01-23 18:32  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-2000-01-23 18:27  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-2000-01-23 18:19  jesse
-
-       * etc/schema.mysql, lib/RT/Attachment.pm, lib/RT/Attachments.pm,
-       lib/RT/Ticket.pm, lib/RT/Transaction.pm:
-
-       Work to make attachments work. So far we've got something that puts attachments
-       in the database.
-       
-2000-01-21 12:25  tobiasb
-
-       * README:
-
-       doc-bugfix
-       
-2000-01-18 23:56  jesse
-
-       * lib/RT/Ticket.pm:
-
-       work on the mail gateway. (mainly disemboweled it)
-       
-2000-01-18 00:34  jesse
-
-       * lib/RT/Attachments.pm:
-
-       file Attachments.pm was initially added on branch rt-1-1.
-       
-2000-01-18 00:34  jesse
-
-       * docs/API:
-
-       file API was initially added on branch rt-1-1.
-       
-2000-01-18 00:34  jesse
-
-       * lib/RT/Attachment.pm:
-
-       file Attachment.pm was initially added on branch rt-1-1.
-       
-2000-01-18 00:34  jesse
-
-       * HACKING:
-
-       file HACKING was initially added on branch rt-1-1.
-       
-2000-01-18 00:34  jesse
-
-       * HACKING, Makefile, docs/API, etc/schema.mysql,
-       lib/RT/Attachment.pm, lib/RT/Attachments.pm, lib/RT/CurrentUser.pm,
-       lib/RT/Queue.pm, lib/RT/Record.pm, lib/RT/Ticket.pm,
-       lib/RT/Transaction.pm, lib/RT/Utils.pm:
-
-       work on attachments.
-       work on structure
-       
-2000-01-17 12:59  jesse
-
-       * Makefile, etc/schema.mysql, lib/RT/ACE.pm, lib/RT/ACL.pm,
-       lib/RT/CurrentUser.pm, lib/RT/Queue.pm, lib/RT/Queues.pm,
-       lib/RT/Ticket.pm, lib/RT/Tickets.pm, lib/RT/Transaction.pm,
-       lib/RT/Transactions.pm, lib/RT/User.pm, lib/RT/Users.pm:
-
-       work on create. work on attachments. upcased the table names.
-       
-2000-01-14 15:34  jesse
-
-       * etc/schema.mysql:
-
-       work on schema
-       
-2000-01-14 14:47  jesse
-
-       * NEWS, etc/schema:
-
-       schema change to make long email addresses work better for queue members.
-       
-2000-01-14 01:07  jesse
-
-       * lib/RT/: EasySearch.pm, Record.pm, Ticket.pm, Tickets.pm,
-       Transaction.pm:
-
-       basic searches now work.
-       comments almost work.
-       creates are having an issue with effectiveid not getting set.
-       
-2000-01-13 18:04  jesse
-
-       * Makefile, lib/RT/EasySearch.pm, lib/RT/Tickets.pm:
-
-       [no log message]
-       
-2000-01-13 15:03  jesse
-
-       * lib/RT/Utils.pm:
-
-       file Utils.pm was initially added on branch rt-1-1.
-       
-2000-01-13 15:03  jesse
-
-       * lib/RT/Utils.pm:
-
-       [no log message]
-       
-2000-01-09 20:38  jesse
-
-       * lib/RT/EasySearch.pm:
-
-       file EasySearch.pm was initially added on branch rt-1-1.
-       
-2000-01-09 20:38  jesse
-
-       * lib/RT/: EasySearch.pm, Queue.pm, Queues.pm, Record.pm,
-       Tickets.pm:
-
-       added RT/EasySearch.pm
-       
-       rtadmin queue -list will now show all queues.
-       removed some debugging output
-       
-2000-01-04 01:21  jesse
-
-       * etc/schema.mysql, lib/RT/CurrentUser.pm, lib/RT/Queue.pm,
-       lib/RT/Record.pm, lib/RT/Ticket.pm, lib/RT/Transaction.pm,
-       lib/RT/User.pm:
-
-       Lots of work. first working ticket update.
-       
-2000-01-04 01:21  jesse
-
-       * lib/RT/CurrentUser.pm:
-
-       file CurrentUser.pm was initially added on branch rt-1-1.
-       
-2000-01-03 07:40  tobiasb
-
-       * README, README:
-
-       bugfix
-       
-2000-01-03 01:39  jesse
-
-       * lib/RT/: Record.pm, Ticket.pm, User.pm:
-
-       basic create support working.
-       more boackend and abstraction work
-       
-2000-01-02 22:04  jesse
-
-       * lib/RT/Ticket.pm:
-
-       [no log message]
-       
-2000-01-02 20:31  jesse
-
-       * lib/RT/: ACE.pm, Area.pm, Queue.pm, Record.pm, Ticket.pm,
-       Transaction.pm, User.pm:
-
-       work on a buit more abstraction
-       
-2000-01-01 19:01  jesse
-
-       * etc/schema.mysql, lib/RT/ACE.pm, lib/RT/Ticket.pm,
-       lib/RT/User.pm:
-
-       work on Ticket.pm, schema.
-       things are starting to use immutable ids when referring to other tables.
-       
-1999-12-30 02:13  jesse
-
-       * Makefile, etc/schema.mysql, lib/RT/Queue.pm, lib/RT/Record.pm,
-       lib/RT/User.pm:
-
-       reworked things to use autoloaded functions.
-       
-1999-12-29 00:24  jesse
-
-       * Makefile, bin/rtmux.pl, etc/schema.mysql, lib/RT/ACE.pm,
-       lib/RT/Area.pm, lib/RT/Queue.pm, lib/RT/Record.pm,
-       lib/RT/Ticket.pm, lib/RT/Transaction.pm, lib/RT/User.pm:
-
-       lots of changes. some of them not quite done perfectly.
-       but admin is closer
-       
-1999-12-28 01:39  jesse
-
-       * bin/rtmux.pl, etc/config.pm, lib/RT/ACE.pm, lib/RT/ACL.pm,
-       lib/RT/Area.pm, lib/RT/Areas.pm, lib/RT/Notification.pm,
-       lib/RT/Queue.pm, lib/RT/Queues.pm, lib/RT/Record.pm,
-       lib/RT/Ticket.pm, lib/RT/Tickets.pm, lib/RT/Transaction.pm,
-       lib/RT/Transactions.pm, lib/RT/User.pm, lib/RT/Users.pm:
-
-       rtadmin will now invoke and exit.
-       
-1999-12-27 19:54  jesse
-
-       * Makefile, bin/initacls.mysql, bin/rtmux.pl, etc/acl.mysql,
-       etc/config.pm, lib/RT/Record.pm:
-
-       first steps toward runability
-       
-1999-12-27 01:51  jesse
-
-       * Makefile, bin/rtmux.pl, etc/config.pm:
-
-       trying to get the config worked out
-       
-1999-12-26 21:58  jesse
-
-       * Makefile, Makefile:
-
-       [no log message]
-       
-1999-12-26 21:55  jesse
-
-       * Makefile, Makefile:
-
-       [no log message]
-       
-1999-12-26 21:53  jesse
-
-       * Makefile, Makefile, Makefile:
-
-       [no log message]
-       
-1999-12-26 21:51  jesse
-
-       * Makefile, Makefile, Makefile:
-
-       [no log message]
-       
-1999-12-26 21:45  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1999-12-26 21:42  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1999-12-26 21:34  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1999-12-26 21:19  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1999-12-26 18:35  jesse
-
-       * Makefile:
-
-       work on the makefile
-       
-1999-12-26 17:42  jesse
-
-       * lib/RT/User.pm:
-
-       more fixes for the new Handle object
-       
-1999-12-26 17:03  jesse
-
-       * bin/rtmux.pl, lib/RT/ACL.pm, lib/RT/Areas.pm, lib/RT/Queues.pm,
-       lib/RT/Tickets.pm, lib/RT/Transactions.pm, lib/RT/Users.pm:
-
-       more work on making everything use DBIx::Handle
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/Ticket.pm:
-
-       file Ticket.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/Queue.pm:
-
-       file Queue.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/Transaction.pm:
-
-       file Transaction.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/Notification.pm:
-
-       file Notification.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/ACE.pm:
-
-       file ACE.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/Areas.pm:
-
-       file Areas.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/ACL.pm:
-
-       file ACL.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/Users.pm:
-
-       file Users.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/Database.pm:
-
-       file Database.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/Tickets.pm:
-
-       file Tickets.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/Queues.pm:
-
-       file Queues.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/Transactions.pm:
-
-       file Transactions.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/Area.pm:
-
-       file Area.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/: ACE.pm, ACL.pm, Area.pm, Areas.pm, Database.pm,
-       Notification.pm, Queue.pm, Queues.pm, Record.pm, Ticket.pm,
-       Tickets.pm, Transaction.pm, Transactions.pm, User.pm, Users.pm:
-
-       moving things to a more sane directory
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/Record.pm:
-
-       file Record.pm was initially added on branch rt-1-1.
-       
-1999-12-26 15:58  jesse
-
-       * lib/RT/User.pm:
-
-       file User.pm was initially added on branch rt-1-1.
-       
-1999-12-23 01:05  jesse
-
-       * Makefile, NEWS:
-
-       23 Dec 1999
-       -----------
-       
-       * Enabled a status = unresolved option for the web ui. thanks to
-         brandon allbery <allbery@ece.cmu.edu> and Marion Hakanson <hakanson@cse.ogi.edu>
-       
-       * Made most of the permissions and directory changes from Marion
-         Hakanson <hakanson@cse.ogi.edu> generally cleaned things up. but DID not
-         include the changes to the directory creation, file copying and permission
-         fixing code to enable RT_VAR_DIR
-       
-       * Made the web ui use $MESSAGE_FONT when putting up the compose window.
-           Marion Hakanson <hakanson@cse.ogi.edu>
-       
-       * Genericised the templates to not mention the mythical "systems group"
-       
-1999-12-19 01:54  jesse
-
-       * Makefile, etc/schema.mysql:
-
-       work on ticket, transaction.
-       schema cleanup
-       
-1999-12-18 13:25  jesse
-
-       * etc/schema:
-
-       removed obsolete schema
-       
-1999-12-17 01:28  jesse
-
-       * Makefile:
-
-       set version
-       
-1999-12-17 01:27  jesse
-
-       * etc/: config.pm, schema.mysql:
-
-       more cleanup. we're getting there. just another zillion hours or so
-       
-1999-12-15 23:56  jesse
-
-       * docs/: FAQ, FAQ.html:
-
-       faq updates committed
-       
-1999-12-15 23:26  jesse
-
-       * README:
-
-       updates to tobix' additions
-       
-1999-12-15 18:32  tobiasb
-
-       * README:
-
-       duh
-       
-1999-12-15 18:04  tobiasb
-
-       * README:
-
-       Some few pitfalls mentionated
-       
-1999-12-09 00:38  jesse
-
-       * etc/schema.mysql:
-
-       work on Ticket and Transaction.
-       we're getting there.
-       
-1999-12-08 03:40  tobiasb
-
-       * etc/suidrt.c:
-
-       bugfixes
-       
-1999-12-06 21:41  jesse
-
-       * Makefile, NEWS:
-
-       [no log message]
-       
-1999-12-06 06:27  tobiasb
-
-       * Makefile:
-
-       insignificant output fix
-       
-1999-12-04 03:30  jesse
-
-       * NEWS, etc/schema.mysql:
-
-       [no log message]
-       
-1999-12-04 01:46  jesse
-
-       * NEWS:
-
-       Fixed tobix-induced bug in lib/rt/database/manipulate.pm
-       that'll teach him to make untested fixes to the stable branch.
-       
-1999-12-02 13:18  tobiasb
-
-       * etc/schema:
-
-       I'm unfortunately not even half on the way in my merging. I'm in a hurry, some small notes:
-       
-       1.1:
-       - work on dependencies done
-       - work on mail distribution done.
-       - requires sub dist_list
-       - requires sub open_parents
-       - requires sub add_link
-       
-       Dependencies & linking in general.
-       
-       Mail distribution. The distribution list is set by a &dist_list
-       sub. The transaction mail is never sent out for comments and
-       correspondence, but people who subscribe all transactions will get the
-       comments and correspondence.
-       
-1999-12-02 03:10  tobiasb
-
-       * etc/mysql.acl:
-
-       This file is renamed
-       
-1999-12-02 03:05  tobiasb
-
-       * etc/: schema.Pg, schema.mysql:
-
-       This file was fucked up, I don't know why. I'll just truncate it for now
-       
-1999-12-02 02:56  jesse
-
-       * Makefile:
-
-       bumped version
-       
-1999-12-02 02:54  tobiasb
-
-       * etc/schema:
-
-       Added links (dependency + knowledge db)
-       
-1999-12-02 01:42  jesse
-
-       * Makefile:
-
-       some makefile cleanup
-       
-1999-12-01 23:16  jesse
-
-       * NEWS:
-
-       [no log message]
-       
-1999-12-01 23:10  jesse
-
-       * bin/rtmux.pl, etc/schema.mysql:
-
-       mots of work on the new backend.
-       cliadmin is mostly up to date.
-       no, i haven't run any of the code :)
-       
-1999-11-30 21:52  jesse
-
-       * etc/: acl.Pg, schema.mysql:
-
-       [no log message]
-       
-1999-11-23 17:21  jesse
-
-       * docs/design_docs/CARS:
-
-       file CARS was initially added on branch rt-1-1.
-       
-1999-11-23 17:21  jesse
-
-       * README, docs/design_docs/CARS, etc/schema.mysql:
-
-       schema hacking for rt-1-1 features.
-       
-1999-11-18 21:40  jesse
-
-       * Makefile, Makefile, Makefile:
-
-       [no log message]
-       
-1999-11-17 17:36  tobiasb
-
-       * NEWS:
-
-       merged in changes from 1.0
-       
-1999-11-16 23:09  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1999-11-08 20:54  jesse
-
-       * NEWS:
-
-       fixed a longstanding bug in cli/query
-       
-1999-11-08 18:02  jesse
-
-       * Makefile, NEWS, etc/config.pm:
-
-       [no log message]
-       
-1999-11-05 03:50  tobiasb
-
-       * Makefile, NEWS, README, bin/initacls.mysql, bin/initdb.mysql,
-       etc/acl.mysql, etc/config.pm:
-
-       patch from khamer integrated - no testing done, however
-       
-1999-10-22 14:09  tobiasb
-
-       * etc/schema:
-
-       merged 1.1-changes
-       
-1999-10-22 12:14  tobiasb
-
-       * NEWS, etc/mysql.acl, etc/schema:
-
-       Merged in changes from 1.0. I haven't checked that things works quite well, anyway.
-       
-1999-10-21 16:21  jesse
-
-       * Makefile, NEWS:
-
-       changes to date_diff, some of the oldest code in RT
-       
-1999-10-21 07:07  tobiasb
-
-       * docs/actions.txt, docs/admin.txt, docs/attributes.txt,
-       docs/outline.txt, docs/rt_users_guide.html, etc/config.pm:
-
-       merged from 1.0
-       
-1999-10-20 23:16  jesse
-
-       * NEWS:
-
-       [no log message]
-       
-1999-10-20 22:25  jesse
-
-       * NEWS:
-
-       [no log message]
-       
-1999-10-20 21:58  jesse
-
-       * NEWS:
-
-       [no log message]
-       
-1999-10-20 21:43  jesse
-
-       * Makefile, NEWS:
-
-       [no log message]
-       
-1999-10-20 10:33  tobiasb
-
-       * Makefile, NEWS, README, README.91UPGRADE, TODO,
-       bin/initacls.mysql, bin/initdb.mysql, docs/README.docs:
-
-       Merged 1.0-development into 1.1
-       
-1999-10-20 01:23  jesse
-
-       * Makefile, NEWS:
-
-       
-       20 Oct 1999
-       -----------
-       * RT now uses a queue's mail alias when sending mail.
-       
-1999-10-20 00:44  jesse
-
-       * Makefile, NEWS:
-
-       
-       20 Oct 1999
-       -----------
-       
-       * Using the web UI to send correspondence should no longer not
-         sent the correspondence if there are CCs, BCCs or the actor is
-         the same as the requestor. thanks to <douglas@arepa.com> for
-         pointing out the deficiency.
-       
-1999-10-13 19:32  jesse
-
-       * Makefile, TODO:
-
-       Released version 1.0 Updated the TODO file.
-       
-1999-10-06 18:01  jesse
-
-       * Makefile:
-
-       bumped version
-       
-1999-10-06 17:57  jesse
-
-       * Makefile, NEWS, README, docs/README.docs:
-
-       [no log message]
-       
-1999-10-06 17:48  jesse
-
-       * docs/: FAQ, FAQ.html, README.docs, actions.html, actions.txt,
-       admin.html, admin.txt, attributes.html, attributes.txt,
-       outline.html, outline.txt, rt_users_guide.html:
-
-       major documentation updates from mbrader
-       
-1999-10-04 14:22  jesse
-
-       * Makefile, NEWS:
-
-       bumped the version to 1.0.0pre2
-       
-1999-10-01 01:39  jesse
-
-       * Makefile:
-
-       fixed a makefile typo
-       
-1999-10-01 01:37  jesse
-
-       * NEWS, README, README.91UPGRADE:
-
-       updated readme
-       
-1999-10-01 01:07  jesse
-
-       * NEWS:
-
-       [no log message]
-       
-1999-10-01 00:22  jesse
-
-       * NEWS, etc/config.pm:
-
-       
-       30 Sep 1999
-       -----------
-       
-       *  Fixed a bug which caused RT to go crazy when comments were submitted
-          by may without a ticket #.
-       
-       The following changes are from johnl@microware.com
-       
-          1. Directories were not getting created with the correct modes under            /usr/local/rt/transactions.                                                         The umask() takes an octal file mode mask, not a file mode.                                                                                                     In addition I read the comments about $dirmode not working when             doing the mkdir's in content.pm.  I also fixed content.pm to use                $dirmode.  The main problem was the $dirmode was being set to a string          instead of an octal number.
-       
-         Fixes to database.pm
-           1.  The first hunk fixes problem where the call to write_content is             passing $time.  This variable does not exist.   It looked like $time was        supposed to be the current time.  ($time always == 0).  I changed all           occurances of $time to time (IE: time()).                                                                                                                       2.  The first hunk also passes $in_time instead of $time.                                                                                                       3.  The rest of the hunks fix $time and replace them with time().
-       
-       27 Sep 1999
-       -----------
-       Fixed a bug which caused the priority not to get set to the default
-       when requests were created in the webui. Thanks to <Elmar.Knipp@knipp.de>
-       
-1999-09-23 23:16  anoncvs
-
-       * Makefile:
-
-       [no log message]
-       
-1999-09-23 23:09  anoncvs
-
-       * Makefile, Makefile:
-
-       [no log message]
-       
-1999-09-23 23:07  anoncvs
-
-       * Makefile:
-
-       [no log message]
-       
-1999-09-23 23:01  anoncvs
-
-       * Makefile:
-
-       [no log message]
-       
-1999-09-23 22:52  anoncvs
-
-       * Makefile:
-
-       [no log message]
-       
-1999-08-08 22:20  tobiasb
-
-       * etc/schema:
-
-       ups
-       
-1999-08-07 02:27  tobiasb
-
-       * etc/schema:
-
-       in-work
-       
-1999-08-04 02:48  tobiasb
-
-       * Makefile, NEWS:
-
-       Merge
-       
-1999-08-03 22:38  jesse
-
-       * NEWS:
-
-       first cut of -trans
-       
-1999-08-03 22:27  jesse
-
-       * Makefile, NEWS:
-
-       reved the version to .99.9. tiny mail manipulate fix
-       
-1999-08-03 11:31  tobiasb
-
-       * bin/initdb.mysql:
-
-       file initdb.mysql was initially added on branch rt-1-1.
-       
-1999-08-03 11:31  tobiasb
-
-       * bin/initdb.Pg:
-
-       file initdb.Pg was initially added on branch rt-1-1.
-       
-1999-08-03 11:31  tobiasb
-
-       * bin/initacls.mysql:
-
-       file initacls.mysql was initially added on branch rt-1-1.
-       
-1999-08-03 11:31  tobiasb
-
-       * bin/: initacls.Pg, initacls.mysql, initdb.Pg, initdb.mysql:
-
-       Scripts for initing the DB
-       
-1999-08-03 11:31  tobiasb
-
-       * bin/initacls.Pg:
-
-       file initacls.Pg was initially added on branch rt-1-1.
-       
-1999-08-03 10:31  tobiasb
-
-       * etc/schema.mysql:
-
-       file schema.mysql was initially added on branch rt-1-1.
-       
-1999-08-03 10:31  tobiasb
-
-       * etc/schema.Pg:
-
-       file schema.Pg was initially added on branch rt-1-1.
-       
-1999-08-03 10:31  tobiasb
-
-       * etc/acl.mysql:
-
-       file acl.mysql was initially added on branch rt-1-1.
-       
-1999-08-03 10:31  tobiasb
-
-       * etc/acl.Pg:
-
-       file acl.Pg was initially added on branch rt-1-1.
-       
-1999-08-03 10:31  tobiasb
-
-       * Makefile, etc/acl.Pg, etc/acl.mysql, etc/mysql.acl, etc/schema,
-       etc/schema.Pg, etc/schema.mysql:
-
-       More work on the move to a DBMS-independent RT. The Makefile and executables _really_ need some testing and eventually debugging.
-       
-1999-08-03 02:14  tobiasb
-
-       * Makefile, etc/config.pm:
-
-       It seems to me that I've somehow managed to go to DBI...WebRT seems to work locally, but that's the only testing I've done
-       
-1999-08-02 07:07  tobiasb
-
-       * etc/schema:
-
-       in-work
-       
-1999-07-29 02:55  tobiasb
-
-       * etc/schema:
-
-       uuuurghh
-       
-1999-07-28 10:42  tobiasb
-
-       * README:
-
-       One small update on the work to link requests...
-       
-1999-07-27 07:08  tobiasb
-
-       * NEWS:
-
-       1.0-gospel
-       
-1999-07-27 06:48  tobiasb
-
-       * etc/schema:
-
-       asdfjlsadfhjkhdfawhi
-       
-1999-07-26 21:21  jesse
-
-       * Makefile, NEWS:
-
-       fixes to the mail gateway header handling
-       added cli rtq flags to the help
-       
-1999-07-26 07:03  tobiasb
-
-       * NEWS:
-
-       Merge
-       
-1999-07-24 20:43  jesse
-
-       * Makefile:
-
-       bumpted the version
-       
-1999-07-24 20:40  jesse
-
-       * NEWS:
-
-       added a few options to the cli query engine. area limitying and display of due dates.
-       
-1999-07-23 03:20  tobiasb
-
-       * NEWS:
-
-       Some merges
-       
-1999-07-23 02:56  tobiasb
-
-       * etc/schema:
-
-       With generic links
-       
-1999-07-22 23:13  jesse
-
-       * Makefile, NEWS:
-
-       22 Jul 99 (Jesse)
-       -----------------
-       Inital cleanup to the web ticket view. I'd like to significantly
-       compact and simplify that display.  More tables are probably in
-       order.  Additionally, I want to get rid of all those buttons "I
-       changed this." There's just no need for them. we can write logic
-       to do that for us.  Also, I bumped the version to 1.1.1.  I'd like
-       to do this 'linux-kernel-esque' The 1.1.x
-       series will be a development series leading toward 1.2.  Once we
-       get the DB changes in, I'll feel comfortable rolling a 'releaseable'
-       1.1 version for people who like pain.
-       
-1999-07-21 23:47  jesse
-
-       * Makefile, NEWS:
-
-       21 July 1999
-       ------------
-       
-       Fix for [fsck #102] Better checks in is_not_a_requestor. this should fix
-               issues with external users being equated with queue members.
-       
-       Fix for [fsck #114] Comment from bin/rt was accidentaly access controlled.
-       
-       Fix for [fsck #113] Display of requests users can't manipulate should now give
-               ian error
-       
-1999-07-20 23:40  tobiasb
-
-       * etc/schema:
-
-       For a general way of linking WebRT requests to other web-based DBs
-       
-1999-07-20 21:42  tobiasb
-
-       * NEWS:
-
-       [no log message]
-       
-1999-07-20 21:11  tobiasb
-
-       * NEWS:
-
-       Hmf.
-       
-1999-07-20 21:07  tobiasb
-
-       * README, etc/config.pm:
-
-       updated for Internet::Mail
-       
-1999-07-20 21:01  tobiasb
-
-       * Makefile:
-
-       updated for Internet::Mail
-       
-1999-07-20 01:21  jesse
-
-       * NEWS:
-
-       Fix for [fsck #88] WebUI area SELECT bug.
-       
-       Fix for [fsck #90] A small html bug in WebRT
-       
-       Fix for [fsck #92] "Allow non-members to create requests" appeared twice
-               in the WebAdmin
-       
-       Fix for [fsck #94] web ui forms are now 78 chars wide
-       
-1999-07-20 00:09  jesse
-
-       * NEWS:
-
-       19 July 1999
-       ------------
-       Fix for [fsck #104]  We no longer try to reset the user's uid after writing
-               transaction content to the filesystem. This should help out Net/OpenBSD
-               compatibility
-       
-       Removed some legacy support for glimpse searching
-       
-       Fix for [fsck #115] The web ticket list should now wrap reasonably, so it's
-               printable.
-       
-1999-07-19 03:26  tobiasb
-
-       * NEWS:
-
-       some updates
-       
-1999-07-17 13:14  tobiasb
-
-       * NEWS:
-
-       Updated a bit
-       
-1999-07-16 23:42  tobiasb
-
-       * Makefile:
-
-       Version number 1.pre1.1 - what do you think about it?
-       
-1999-07-16 22:49  tobiasb
-
-       * bin/rtmux.pl:
-
-       Filled in a missing comment
-       
-1999-07-16 22:46  tobiasb
-
-       * Makefile:
-
-       Set version to 1.1.0pre1, and changed /opt/rt to /usr/local/rt, I'd
-       daresay the next is more widely preffered.
-       
-1999-07-16 18:36  tobiasb
-
-       * COPYING, Makefile, NEWS, README, README.91UPGRADE, TODO,
-       bin/rtmux.pl, docs/FAQ, docs/FAQ.html, docs/README.docs,
-       docs/actions.html, docs/actions.txt, docs/admin.html,
-       docs/admin.txt, docs/attributes.html, docs/attributes.txt,
-       docs/outline.html, docs/outline.txt, etc/config.pm, etc/mysql.acl,
-       etc/schema, etc/suidrt.c:
-
-       Imported Tobix' current version
-       
-1999-07-08 02:10  jesse
-
-       * Makefile, NEWS, TODO:
-
-       Rolled .99.8
-       
-1999-07-07 15:37  jesse
-
-       * NEWS:
-
-       [no log message]
-       
-1999-07-07 00:45  jesse
-
-       * Makefile, NEWS:
-
-       updated makefile and news.
-       
-1999-07-06 22:58  jesse
-
-       * NEWS:
-
-       6 Jul 99
-       --------
-       Now, if you move a request to a new queue, it won't disown it if the same person can own reqs in the new queue. [fsck #75] (untested)
-       
-       Fixed a problem with cli create not properly handling due dates ([fsck #67])
-       Fixed a duplicate --help entry for bin/rt [fsck #69]
-       Fixed bugs fsck  #68/77: Odness Merging RT requests
-       
-       Transactions from merged requests will now be displayed along with the request id of the request that transaction was originially associated with.
-       
-       Fixed [fsck #74], which was reported by charlie brady:
-          Messages are sent out from the mail interface with content first, then
-          "--- Headers Follow ---", then the headers. In our vanilla sendmail setup,
-          before the headers is a UUCP style deliver notification "From blah Tue Jul
-          6 18:13:01 1999" line. This is interpreted by many mail agents as a
-          message delimiter, so that what is seen in the mail agent is not one, but
-          two messages. This is easily fixed by using the conventional quoting
-          mechanism...
-       Fixed [fsck #71] WebRT: "User" should be "Requestor"
-       
-1999-07-06 21:35  jesse
-
-       * NEWS:
-
-       resovled #71, #74. worked on merge functionality
-       
-1999-06-29 17:39  jesse
-
-       * Makefile, NEWS:
-
-       [no log message]
-       
-1999-06-29 17:20  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1999-06-24 00:52  jesse
-
-       * Makefile, NEWS, README, TODO:
-
-       lots of touchups.
-       
-1999-06-23 23:29  jesse
-
-       * NEWS:
-
-       moved to CGI.pm's form parser.
-       
-1999-06-17 01:49  jesse
-
-       * NEWS:
-
-       edited news
-       
-1999-06-16 23:21  jesse
-
-       * Makefile, NEWS:
-
-       Fixed an auth bug.
-       
-1999-06-15 02:13  jesse
-
-       * Makefile:
-
-       upped the version to .99.8pre5
-       
-1999-06-15 02:09  jesse
-
-       * Makefile, NEWS:
-
-       lots of misc changes. see the diff to the news file
-       
-1999-05-12 20:37  jesse
-
-       * Makefile, NEWS:
-
-       cookies hacked to deal with the fact that netscape can't handle path=/
-       
-1999-05-12 01:57  jesse
-
-       * Makefile:
-
-       bumped the version number to .99.8pre3
-       
-1999-05-12 01:56  jesse
-
-       * NEWS:
-
-       Made error messages on the web admin interface more prominent.
-       
-       All the following changes are from tobix:
-       
-               Correspondence from RT now properly reflect the name of the sender
-               in the "from" header.
-       
-               Automated messages now properly have a "Precedence: bulk" header
-       
-               A stupid error with rt::mail_alias has been fixed
-       
-               Tobix' patch removes headers from all correspondence.  I'm relatively
-               afraid of this change, so I'm going to comment it out for now.
-       
-               rtadmin (the commandline has a new tool) :
-                    -update <passwd> <admin> [<users>]  updates user(s) from the
-                          /etc/passwd file. If no users are specified, ALL
-                          of /etc/passwd will be processed.
-       
-1999-05-11 16:46  jesse
-
-       * Makefile, NEWS, README:
-
-       mail loop fix from toby
-       
-1999-05-09 20:35  jesse
-
-       * Makefile:
-
-       bumped version numbers
-       
-1999-05-09 20:35  jesse
-
-       * Makefile, NEWS, README:
-
-       updated makefile and news
-       
-1999-05-09 20:17  jesse
-
-       * bin/rtmux.pl:
-
-       modifications to cookies support to md5 hash the password.
-       modification to allow non-nph web ui
-       
-1999-05-05 02:39  jesse
-
-       * NEWS:
-
-       fixed some cookies/frames problems
-       
-1999-05-05 02:10  jesse
-
-       * Makefile, NEWS:
-
-       fixed bugs in web auth from charlie brady
-       
-1999-05-03 21:44  jesse
-
-       * Makefile:
-
-       bumped the version #
-       
-1999-04-28 16:03  jesse
-
-       * Makefile:
-
-       bumped version
-       
-1999-04-28 16:03  jesse
-
-       * NEWS:
-
-       updated content.pm to spit errors.
-       
-1999-04-27 02:58  jesse
-
-       * Makefile:
-
-       downed the makefile version
-       
-1999-04-27 02:57  jesse
-
-       * Makefile:
-
-       fixed a makefile bug
-       
-1999-04-26 21:57  jesse
-
-       * NEWS, README:
-
-       added configuration info about mod_auth_mysql
-       
-1999-04-26 21:45  jesse
-
-       * Makefile, etc/config.pm:
-
-       Updated authetication stuff with patches from ingo. updated them further.
-       Added the ability to configure whether external authentication is done for webrt
-       added the ability to turn off ie compatibility mode
-       
-1999-04-23 19:31  jesse
-
-       * Makefile, NEWS, README, TODO:
-
-       started to update the README and Makefile
-       
-1999-04-13 04:00  jesse
-
-       * Makefile:
-
-       fixed totally fuxored makefile
-       
-1999-04-13 03:28  jesse
-
-       * README:
-
-       noted that there's a dependency on gnu make
-       
-1999-04-13 03:07  jesse
-
-       * Makefile:
-
-       bumped version
-       
-1999-04-13 03:06  jesse
-
-       * NEWS:
-
-       updated news
-       
-1999-04-08 04:36  jesse
-
-       * docs/rt.gif:
-
-       added the gif to the docs
-       
-1999-04-08 04:35  jesse
-
-       * NEWS:
-
-       fixes for new mysql modules
-       
-1999-04-07 23:57  jesse
-
-       * NEWS:
-
-       updates
-       
-1999-04-07 02:14  jesse
-
-       * NEWS:
-
-       [no log message]
-       
-1999-04-07 02:09  jesse
-
-       * Makefile, README:
-
-       fixes for cookie auth from charlie brady
-       
-1999-04-06 06:30  jesse
-
-       * Makefile, NEWS, README:
-
-       misc changes to support cookie authentication
-       
-1999-04-03 04:57  jesse
-
-       * NEWS, docs/FAQ, docs/FAQ.html, docs/README.docs,
-       docs/actions.html, docs/actions.txt, docs/admin.html,
-       docs/admin.txt, docs/attributes.html, docs/attributes.txt,
-       docs/outline.html, docs/outline.txt:
-
-       major update of the docs from adam.
-       
-1999-04-03 04:49  jesse
-
-       * Makefile:
-
-       makefile hackery to ease installs slightly.
-       
-1999-03-21 20:24  jesse
-
-       * Makefile:
-
-       updated makefile
-       
-1999-03-21 20:22  jesse
-
-       * NEWS, README:
-
-       mail changes
-       
-1999-03-08 14:50  jesse
-
-       * NEWS:
-
-       turned off the troll
-       
-1999-03-08 14:02  jesse
-
-       * Makefile:
-
-       fixed makefile bogosity for ACLs
-       
-1999-03-04 01:50  jesse
-
-       * Makefile, NEWS:
-
-       fixed a subject line parsing error.
-       
-1999-02-26 22:29  jesse
-
-       * NEWS:
-
-       added a check to make sure you don't merge ar equest into a non-existent other request
-       
-1999-02-26 21:43  jesse
-
-       * README.91UPGRADE, README.FIRST, TODO:
-
-       moved readme.fdirst to readmne.91upgrade
-       
-1999-02-26 19:59  jesse
-
-       * Makefile, NEWS:
-
-       updated makefile: added upgrade-noclobber
-       
-1999-02-24 19:11  jesse
-
-       * NEWS:
-
-       [no log message]
-       
-1999-02-23 14:41  jesse
-
-       * NEWS:
-
-       updated bnews
-       
-1999-02-23 03:20  jesse
-
-       * docs/: actions.txt, admin.txt, attributes.txt:
-
-       added updates for adam for the docs.
-       
-       updated the news
-       
-1999-02-23 03:20  jesse
-
-       * NEWS:
-
-       updated the news
-       
-1999-02-21 01:56  jesse
-
-       * Makefile:
-
-       fixed the .4
-       
-1999-02-21 01:53  jesse
-
-       * Makefile:
-
-       fixed make pre
-       
-1999-02-20 23:27  jesse
-
-       * Makefile:
-
-       addded back predist
-       
-1999-02-20 16:36  jesse
-
-       * NEWS:
-
-       edited the news to reflect changes
-       
-1999-02-20 14:56  jesse
-
-       * Makefile, NEWS:
-
-       bumped the version to .99.4 for testing.
-       
-1999-02-20 14:48  jesse
-
-       * etc/mysql.acl:
-
-       updated acls so they'll work with newer versions of mysql 3.22
-       
-1999-01-20 02:21  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1999-01-20 02:13  jesse
-
-       * Makefile:
-
-       On another note, here is a fix for the "HTML turd" reported by Benji
-       Cline in lib/rt/ui/web/forms.pm:
-       ==========                                                                      diff -r0.99.2 forms.pm
-       87c87                                                                           <               $u = 0;
-       ---                                                                             >               $u = 1;
-       91c91                                                                           <                       $u = 1;                                                 ---                                                                             >                       $u = 0;
-       ==========
-       
-       With this patch applied, v0.99.2 (0.99.3?)                                      appears to be as solid as v0.9.18, if not more
-       so.
-       
-       Upgraded the version to .99.3
-       
-1999-01-16 20:44  jesse
-
-       * NEWS:
-
-       [no log message]
-       
-1999-01-16 20:39  jesse
-
-       * Makefile:
-
-       fixed a web acls bug. incremented the version.
-       
-1999-01-16 01:22  jesse
-
-       * Makefile:
-
-       bumped version to .99.1
-       
-1999-01-16 01:20  jesse
-
-       * Makefile, NEWS:
-
-       fixed some web admin sillyness..acls work better.
-       we no longer dump back to the main menu quite as gratuitously.
-       acls are no longer broken on the CLI either.
-       
-1998-12-16 01:31  jesse
-
-       * Makefile:
-
-       fixed the following things:
-       
-       From owner-rt-users@horked.fsck.com  Tue Nov 24 02:24:03 1998
-       Return-Path: <owner-rt-users@lists.fsck.com>
-       Received: (from majordomo@localhost)
-               by horked.fsck.com (8.8.7/8.8.7) id CAA11181
-               for rt-users-outgoing; Tue, 24 Nov 1998 02:24:01 -0500
-       X-Authentication-Warning: horked.fsck.com: majordomo set sender to owner-rt-users@lists.fsck.com using -f
-       Received: from modgud.nordicdms.com (h21-168-107.nordicdms.com [207.21.168.107] (may be forged))
-               by horked.fsck.com (8.8.7/8.8.7) with SMTP id CAA11177
-               for <rt-users@lists.fsck.com>; Tue, 24 Nov 1998 02:23:58 -0500
-       Received: (qmail 6211 invoked by alias); 24 Nov 1998 07:25:59 -0000
-       Message-ID: <19981124072559.6209.qmail@modgud.nordicdms.com>
-       Received: (qmail 6197 invoked from network); 24 Nov 1998 07:25:59 -0000
-       Received: from mail-ftp.nordicdms.com (HELO mail-ftp) (207.21.168.100)
-         by mail.nordicdms.com with SMTP; 24 Nov 1998 07:25:59 -0000
-       From: "Dave Walton" <walton@nordicdms.com>
-       Organization: Nordic Entertainment Worldwide
-       To: Jesse <jrvincent@wesleyan.edu>, rt-users@lists.fsck.com
-       Date: Mon, 23 Nov 1998 23:25:58 -0800
-       MIME-Version: 1.0
-       Content-type: text/plain; charset=US-ASCII
-       Content-transfer-encoding: 7BIT
-       Subject: Two bugfixes
-       Reply-to: walton@nordicdms.com
-       In-reply-to: <19981013013318.H18644@horked.fsck.com>
-       References: <19981013042506.9798.qmail@modgud.nordicdms.com>; from Dave Walton on Mon, Oct 12, 1998 at 09:25:06PM -0700
-       X-mailer: Pegasus Mail for Win32 (v3.01d)
-       Sender: owner-rt-users@lists.fsck.com
-       Precedence: bulk
-       
-       1.  A backwards search was causing lib/rt/ui/web/support.pm to
-       crash when data that looks like an invalid regex is present in the
-       message headers.
-       ------------------------------------------------------------
-       # diff support.old.pm support.pm
-       44c44
-       <               ($headers_ignore !~ /$field/i)) {
-       ---
-       >               ($field !~ /$headers_ignore/i)) {
-       ------------------------------------------------------------
-       
-       2.  HTML buglet in lib/rt/ui/web/manipulate.pm.
-       ------------------------------------------------------------
-       # diff manipulate.old.pm manipulate.pm
-       894c894
-       < <font color=\"\$fg_color\">
-       ---
-       > <font color=\"$fg_color\">
-       ------------------------------------------------------------
-       
-       Dave
-       
-       ----------------------------------------------------------------------
-       Dave Walton
-       Webmaster, Postmaster                   Nordic Entertainment Worldwide
-       walton@nordicdms.com                          http://www.nordicdms.com
-       ----------------------------------------------------------------------
-       
-       From benji@hnt.com  Fri Nov 20 14:28:44 1998
-       Return-Path: <benji@hnt.com>
-       Received: from horked.fsck.com (jesse@localhost [127.0.0.1])
-               by horked.fsck.com (8.8.7/8.8.7) with ESMTP id OAA04739
-               for <jesse@localhost>; Fri, 20 Nov 1998 14:28:44 -0500
-       Received: from mail.wesleyan.edu
-               by horked.fsck.com (fetchmail-4.3.2 POP3 run by jrvincent)
-               for <jesse@localhost> (single-drop); Fri Nov 20 14:28:44 1998
-       Received: from columbus.hnt.com (columbus.hnt.com [208.221.11.10]) by mail.wesleyan.edu (8.8.6/8.7.3) with ESMTP id OAA18408 for <jrvincent@wesleyan.edu>; Fri, 20 Nov 1998 14:30:34 -0500 (EST)
-       Received: from peppermint.hnt.com (peppermint.hnt.com [208.221.11.51])
-               by columbus.hnt.com (8.9.1/8.9.1/HnT-980729) with ESMTP id OAA26134
-               for <jrvincent@wesleyan.edu>; Fri, 20 Nov 1998 14:30:32 -0500 (EST)
-       Received: from localhost by peppermint.hnt.com (8.9.1/8.9.1/HnT-nullclient-980724) with ESMTP id OAA02733
-               for <jrvincent@wesleyan.edu>; Fri, 20 Nov 1998 14:30:32 -0500 (EST)
-       X-Authentication-Warning: peppermint.hnt.com: benji owned process doing -bs
-       Date: Fri, 20 Nov 1998 14:30:31 -0500 (EST)
-       From: Benjamin Cline <benji@hnt.com>
-       To: Jesse <jrvincent@mail.wesleyan.edu>
-       Subject: Re: 0.9.20 is out
-       In-Reply-To: <19981120005718.F28841@horked.fsck.com>
-       Message-ID: <Pine.GSO.4.05.9811201427100.2438-100000@peppermint.hnt.com>
-       MIME-Version: 1.0
-       Content-Type: TEXT/PLAIN; charset=US-ASCII
-       X-UIDL: 4f1695a69f7cdbefcfce9198121fef95
-       
-       I think I've found a buglet in 0.9.20, I had to add an extra curly bracket
-       ("}") to the end of lib/rt/database/admin.pm (just before the "1;") to get
-       it to work right.
-       
-               benji
-       
-       P.S. Sorry if that's not the most coherent bug report/fix, I'm afraid I'm
-       not much of a perl hacker.
-       
-       On Fri, 20 Nov 1998, Jesse wrote:
-       
-       > ftp://horked.fsck.com/pub/rt/devel/rt-0.9.20.tar.gz
-       >
-       > 19 Nov 98
-       > ---------
-       >
-       > Incorportated patches from Dave Walton to fix a typo, replace an
-       > accidentally
-       > blown away library and add a "last acted" column to the web ui.
-       > incremented version to .9.20
-       >
-       >
-       >       jesse
-       >
-       > --
-       > jesse reed vincent -- jrvincent@wesleyan.edu -- jesse@fsck.com
-       > pgp keyprint:  50 41 9C 03 D0 BC BC C8 2C B9 77 26 6F E1 EB 91
-       > --------------------------------------------------------------
-       > They'll take my private key when they pry it from my cold dead fingers!
-       >
-       
-       --
-       Benjamin R. Cline       Harrison & Troxell, Inc.         benji@hnt.com
-                            Quis Custodiet Ipsos Custodes?
-       
-       From adam@baz.org  Fri Nov 13 17:07:09 1998
-       Return-Path: <adam@baz.org>
-       Received: from horked.fsck.com (jesse@localhost [127.0.0.1])
-               by horked.fsck.com (8.8.7/8.8.7) with ESMTP id RAA10943
-               for <jesse@localhost>; Fri, 13 Nov 1998 17:07:09 -0500
-       Received: from mail.wesleyan.edu
-               by horked.fsck.com (fetchmail-4.3.2 POP3 run by jrvincent)
-               for <jesse@localhost> (single-drop); Fri Nov 13 17:07:09 1998
-       Received: from impei.baz.org (adam@impei.baz.org [139.167.64.229]) by mail.wesleyan.edu (8.8.6/8.7.3) with ESMTP id RAA08425 for <jrvincent@wesleyan.edu>; Fri, 13 Nov 1998 17:08:38 -0500 (EST)
-       Received: (from adam@localhost)
-               by impei.baz.org (8.8.7/8.8.8) id RAA18674
-               for jrvincent@wesleyan.edu; Fri, 13 Nov 1998 17:08:38 -0500
-       Message-ID: <19981113170837.A18668@baz.org>
-       Date: Fri, 13 Nov 1998 17:08:37 -0500
-       From: secret agent man <adam@baz.org>
-       To: "J.R.Ewing" <jrvincent@mail.wesleyan.edu>
-       Subject: RT bug, mebbe?
-       Mime-Version: 1.0
-       X-Mailer: Mutt 0.93.2i
-       Content-Type: text/plain; charset=us-ascii
-       X-UIDL: 5563064ca159a5eee88e16843932a45f
-       
-       <jailbait> q: If you leave the field blank when clicking on "create new
-       (queue|user) named", it goes to the create screen with an empty field that
-       can't be filled. It should either be editable there or it should reject
-       you.
-       
-       A
-       
-       --
-       Everything I needed to know about life I learned       <adam@baz.org>
-       from killing smarter people and eating their brains.    adam hirsch
-       
-1998-11-20 00:45  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1998-11-20 00:28  jesse
-
-       * Makefile, NEWS:
-
-       19 Nov 98
-       ---------
-       
-       Incorportated patches from Dave Walton to fix a typo, replace an accidentally
-       blown away library and add a "last acted" column to the web ui.
-       incremented version to .9.20
-       
-1998-11-18 02:26  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1998-10-13 03:37  jesse
-
-       * Makefile, README, etc/mysql.acl:
-
-       shiny:% cat >> changes                                          ~ 10:53PM:tt
-       2.  Made comments and replies update date_acted.
-       
-               -- Dave Walton
-       
-       Ok.. I know this is being picky, but, in rt/lib/ui/web/support.pm, the
-       subroutine "content_header", at line 290, should have:
-           print "<head><title>WebRT</title></head>\n";
-       
-       Otherwise, when running in frames, you never get a title on the page. :(
-       
-       No biggie...
-       
-       -Rich
-       
-       Oh, one other.
-       
-       8.  etc/mysql.acl, line 5
-       The RT_MYSQL_HOST entry on that line doesn't make any sense
-       when MySQL is on a different host than RT.  That should be
-       RT_HOST, or some such thing.
-       
-       Dave
-       
-       After just upgrading to Apache 1.3.0 from 1.2.5, I figured I would make it
-       known that, in the file <apache_src_dir>/src/main/util_script.c, you have
-       to define SECURITY_HOLE_PASS_AUTHORIZATION to allow for RT's authorization
-       to work properly.
-       -Rich
-       
-       On Tue, Oct 06, 1998 at 09:19:07PM -0700, Dave Walton wrote:
-       > I just discovered that if there is an error in add_correspondence, the
-       > mail interface discards the incoming mail without comment.  To
-       > correct this, I took the following steps:
-       >
-       In mail.pm, there's a space before :
-       
-       From: $rt::mail_alias
-       
-       This causes problems in some mail clients, putting the From: line on the
-       same line as the subject.  If the spaces are removed this is fixed.
-       
-       Regards,
-       From: "Andrew Foster" <adf@fl.net.au>
-       
-1998-09-11 01:15  jesse
-
-       * docs/README.docs:
-
-       updated lists for rt docs.
-       
-1998-09-08 03:23  jesse
-
-       * NEWS:
-
-       updated news\18
-       
-1998-09-08 03:18  jesse
-
-       * Makefile, NEWS, README, etc/config.pm:
-
-       Final bug fixes for .9.18
-       
-1998-08-09 17:43  jesse
-
-       * NEWS, README, TODO:
-
-       All kinds of crazy updates for .9.18. Mostly from serge zhuk
-       
-1998-08-04 03:09  jesse
-
-       * NEWS:
-
-       first round of updates from serge
-       
-1998-06-26 17:07  jesse
-
-       * Makefile, NEWS:
-
-       modified makefile and news
-       
-1998-06-26 16:34  jesse
-
-       * docs/: README.docs, actions.txt, admin.txt, attributes.txt,
-       outline.txt:
-
-       Added documentation from <adam@apocalypse.org>
-       
-1998-06-25 17:06  jesse
-
-       * Makefile, README, etc/config.pm:
-
-       removed refs to glimpse
-       
-1998-06-25 15:46  jesse
-
-       * Makefile:
-
-       dist fixes
-       
-1998-06-25 15:44  jesse
-
-       * Makefile:
-
-       dist fixes
-       
-1998-06-25 14:09  jesse
-
-       * Makefile:
-
-       edited dist. maker
-       
-1998-05-21 22:40  jesse
-
-       * Makefile:
-
-       added httpd.conf configurator for cern
-       
-1998-04-27 20:17  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1998-04-20 14:53  jesse
-
-       * Makefile:
-
-       bumped version to .9.14.
-       
-1998-04-20 14:53  jesse
-
-       * Makefile:
-
-       bumped version to .9.13.1
-       
-1998-04-19 03:14  jesse
-
-       * Makefile:
-
-       updated version number.
-       now explicitly create rt-etc-dir
-       
-1998-04-16 21:40  jesse
-
-       * bin/rtmux.pl:
-
-       removed a spurious addition to the lib path from the mux
-       abstracted a bunch of stuff out of the mux and throughout the makefile.
-       like program names.
-       
-1998-04-16 21:39  jesse
-
-       * Makefile:
-
-       abstracted a bunch of stuff out of the mux and throughout the makefile.
-       like program names.
-       
-1998-04-16 19:47  jesse
-
-       * COPYING, Makefile, NEWS, README, README.FIRST, TODO:
-
-       commiting updates
-       
-1998-04-08 13:35  jesse
-
-       * etc/config.pm:
-
-       fixed typos in config.pm that prevented mail from working with .9.11
-       bumped version to .12
-       
-1998-04-08 13:34  jesse
-
-       * Makefile:
-
-       bumped version to .12
-       
-1998-04-02 21:30  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1998-04-02 21:27  jesse
-
-       * Makefile:
-
-       fixed make dist
-       
-1998-04-02 15:36  jesse
-
-       * Makefile, Makefile:
-
-       [no log message]
-       
-1998-04-02 15:29  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1998-04-02 15:25  jesse
-
-       * etc/config.pm:
-
-       split mail program and mail program flags
-       hopefully fixed make dist
-       
-1998-04-02 15:25  jesse
-
-       * Makefile:
-
-       hopefully fixed make dist
-       
-1998-04-02 11:02  jesse
-
-       * Makefile, NEWS:
-
-       updated news
-       
-1998-04-02 10:55  jesse
-
-       * Makefile:
-
-       [no log message]
-       
-1998-04-02 10:31  jesse
-
-       * etc/config.pm:
-
-       reshuffled files that the user won't be changing out of etc and into lib
-       this includes generic templates and images for the web ui
-       updated src and makefiles accordingly.
-       verbosifoed part of config.pm
-       
-1998-04-02 10:31  jesse
-
-       * Makefile:
-
-       reshuffled files that the user won't be changing out of etc and into lib
-       this includes generic templates and images for the web ui
-       updated src and makefiles accordingly.
-       
-1998-04-02 10:20  jesse
-
-       * Makefile:
-
-       built more auto-dist stuff
-       
-1998-04-02 03:22  jesse
-
-       * README:
-
-       added apache patch to readme
-       
-1998-04-02 03:13  jesse
-
-       * Makefile, README, TODO, etc/config.pm:
-
-       updated makefile and readme and todo
-       added toggle for mysql 3.21
-       moved sendmail flags to makefile for compat w 8.6
-       
-1998-02-08 21:12  jesse
-
-       * Makefile:
-
-       make upgrade now calls mux-install
-       
-1998-01-30 22:31  jesse
-
-       * Makefile, README, README.FIRST:
-
-       added bits to upgrade from .9.1
-       made make upgrade upgrade the conf file
-       
-1998-01-27 01:56  jesse
-
-       * NEWS:
-
-       updated news
-       
-1998-01-27 01:48  jesse
-
-       * Makefile:
-
-       started a make dist
-       
-1998-01-26 17:59  jesse
-
-       * Makefile, README, README.FIRST:
-
-       updated readme
-       
-1998-01-21 18:37  jesse
-
-       * Makefile:
-
-       fixes to makefile to allow for proper specification of database as local.
-       added "you are logged in as..." to web/support...
-       changed sendmail options in mail.pm/
-       
-1998-01-14 23:49  jesse
-
-       * Makefile, etc/mysql.acl:
-
-       incremented version number
-       
-1998-01-09 14:48  jesse
-
-       * bin/rtmux.pl:
-
-       added taint safeness for $ENV{'ENV}
-       updated makefile version number
-       
-1998-01-09 14:47  jesse
-
-       * Makefile:
-
-       updated makefile version number
-       
-1998-01-08 16:17  jesse
-
-       * README.FIRST:
-
-       ipdated readme.first.
-       
-1998-01-08 14:53  jesse
-
-       * etc/suidrt.c:
-
-       made suidrt.c work
-       updated the mux
-       
-1998-01-08 14:53  jesse
-
-       * bin/rtmux.pl:
-
-       updated the mux
-       
-1998-01-08 13:10  jesse
-
-       * Makefile:
-
-       more fixes to make suid wrapper stuff work.
-       
-1998-01-08 12:51  jesse
-
-       * bin/rtmux.pl:
-
-       made rtmux attempt to work with the suid wrapper
-       
-1998-01-08 12:48  jesse
-
-       * etc/suidrt.c:
-
-       added back suidrt.c. blech.
-       
-1998-01-08 12:44  jesse
-
-       * Makefile, bin/rtmux.pl:
-
-       brought back suidrt.c
-       bleck.
-       
-1998-01-07 18:06  jesse
-
-       * Makefile:
-
-       added a sane mode for $(RT_PATH)
-       
-1998-01-07 00:37  jesse
-
-       * Makefile, README.FIRST:
-
-       added basic old upgrade instructions.
-       added info to README.FIRST about upgrading.
-       
-1998-01-07 00:31  jesse
-
-       * bin/rtmux.pl:
-
-       made mailing work.
-       
-1998-01-06 10:27  jesse
-
-       * bin/rtmux.pl:
-
-       made the mux require ui::mail before it tried to invoke it.
-       
-1998-01-04 02:26  jesse
-
-       * README:
-
-       told users to read readme.first.
-       
-1998-01-04 02:25  jesse
-
-       * README, README.FIRST:
-
-       added readme.first
-       
-1998-01-04 02:12  jesse
-
-       * Makefile:
-
-       updated webadmin interface. fixed some logout problems. fixed an html bug in web-manip.
-       
-1998-01-02 01:14  jesse
-
-       * Makefile, bin/rtmux.pl:
-
-       fixed more problems w/ making cliadmin run
-       merged mux-install and mux-links into one section of makefile
-       
-1998-01-02 00:59  jesse
-
-       * Makefile, NEWS, README, TODO, bin/rtmux.pl, etc/config.pm:
-
-       fixed typo in Makefile: install-libs -> libs-install
-       
-1998-01-01 03:07  jesse
-
-       * Makefile, bin/rtmux.pl:
-
-       commented makefile better
-       added more stuff for taint checks to rtmux.pl
-       fixed a non-frames web bug in FormComment
-       
-1997-12-31 01:55  jesse
-
-       * Makefile, bin/rtmux.pl, etc/config.pm:
-
-       lots of cleanup to get web interface running.
-       beginnigs of taint-safe scripts.
-       
-1997-12-30 23:49  jesse
-
-       * Makefile, bin/rtmux.pl:
-
-       cleanup in cli admin.pm, cli query.pm, the mux, the makefile
-       database routines now assign an effective serial # to a request when you get
-       the fact's serial number
-       
-1997-12-30 22:56  jesse
-
-       * Makefile, README, bin/rtmux.pl:
-
-       remodded rtmux to use correct vars for command line arguments.
-       moved RT_VERSION to makefile.
-       updated README for new install procedure
-       
-1997-12-30 01:09  jesse
-
-       * Makefile, etc/config.pm, etc/mysql.acl:
-
-       fixed typo in web/admin.pm
-       set up config.pm mysql.acl and rtmux.pl to get themselves parsed from the makefile.
-       removed last vestiges of C
-       
-1997-12-28 18:59  jesse
-
-       * Makefile, etc/schema:
-
-       removed suidrt for a preparation to move to a c-free system
-       added provisions for token-parsing to makefile
-       
-1997-12-28 03:10  jesse
-
-       * etc/schema:
-
-       added tags to schema
-       
-1997-12-28 02:48  jesse
-
-       * Makefile:
-
-       started to modify toplevel makefile
-       
-1997-12-19 03:04  jesse
-
-       * lib/rtmux.pl:
-
-       moved the executable rtmux.pl to bin, where it belongs.
-       made sure bin/cgi gets created on checkout
-       
-1997-12-19 03:03  jesse
-
-       * bin/rtmux.pl:
-
-       moved the executable rtmux.pl to bin, where it belongs.
-       
-1997-12-18 19:05  jesse
-
-       * lib/rtmux.pl:
-
-       worked on the mux
-       
-1997-12-09 15:14  jesse
-
-       * TODO:
-
-       added things for v1.0 to the todo list
-       
-1997-12-09 02:03  jesse
-
-       * etc/config.pm:
-
-       broke configuration out into config.pm
-       
-1997-12-09 01:54  jesse
-
-       * COPYING, Makefile, NEWS, README, TODO, etc/mysql.acl, etc/schema:
-
-       initial commit after i nuked the repository
-       
-1997-12-09 01:54  jesse
-
-       * COPYING, Makefile, NEWS, README, TODO, etc/mysql.acl, etc/schema:
-
-       Initial revision
-       
diff --git a/rt/Changelog b/rt/Changelog
new file mode 100644 (file)
index 0000000..d8d73fd
--- /dev/null
@@ -0,0 +1,1286 @@
+
+
+
+Project "rt.3", Branch 0                                                 Page 1
+Change Log                                             Sat Jul 12 04:24:41 2003
+
+rt.3.D000, C0, jesse, Thu Mar 13 20:43:23 2003, RT: Request Tracker, branch 3.0.
+    RT: Request Tracker, branch 3.0.
+
+    Change Delta  Brief Description
+      10      1          Bumping the version to rt.3.0.0rc0
+      11      2          Minor CSS update. rollback fix; new database indices;
+                 copyright update
+      15      3          removing the old REST API
+      16      4          Performance work on 'WhoHaveRight'; bumping to 3.0.0rc2
+      12      5          fixing indices for postgres
+      17      6          fixing fastcgi's ability to load webmux.pl on some platforms
+      18      7          More performance work; backing out 'enhancements' that killed
+                 system performance
+      19      8          Caving in to the masses and making 'notify sender'
+                 configurable
+      20      9          finishing the notify stuff
+      22     10          Bumping to RC3; fixing the display of 'This user's n highest
+                 priority tix'
+      23     11          New french translation
+      25     12          Brazilian Portuguese translation
+      26     13          Postgres fixes
+      27     14          Postgres schema tweak
+      28     15          Further postgres tweaks and fixes
+      29     16          RT should now be less overzealous about opening and then
+                 marking a ticket 'new' again
+      30     17          Bumping to 3.0.0rc4
+      31     18          Minor fixes - Bumped to 3.0.0;
+                 2266 - postgres scrip creation bug
+                 2267 - Tickets not reopened after being stalled
+                 2265 - Fixed css nits from blaise
+                 Unreported - Fixed quick-search bug
+      32     19          Added better error checking for failed ticket creation
+      33     20          A tiny bit of extra data passing for some callbacks
+      35     21          New czech translation
+      37     22          Updated dependencies
+      36     23          Updated Spanish translation
+      38     24          Updates for RT RPC interface from AMS
+      39     25          Many users should be able to have a blank address; neew test
+                 suite to ensure this
+      50     26          Integrating rafael's failing test suite and proposed fix from
+                 autrijus
+      51     27          Changing address used in example to not send mail to author
+      52     28          More I18N testing  for rafael
+      53     29          Added preliminary left to right hebrew translation
+      55     30          #2365 Removing outdated Mason setup parameter
+      56     31          Testing fixes for mail authentication/authorization
+      57     32          Testing and fixing binary attachment corruption
+      58     33          Better binary attachment handling fix from autrijus
+      59     34          Bumping to RT 3.0.1pre2
+      60     35          SMTP and I18N fixes from autrijus tang. Updated chinese
+                 translations
+      61     36          New speedycgi support from vivek khera
+      62     37          Bumping to version 3.0.1
+      63     38          Fixing a showmessagestanza bug found in RTIR
+      65     39          Fixing an untainting bug in 3.0.1
+      66     40          Quicksearch bug fix from Stan
+      67     41          updating autrijus' autohandler patch. seems to break lots of
+                 stuff
+      68     42          Bumping to 3.0.2pre1
+      69     43          make ids clicky
+      70     44          fixing utf8 tainting issue in autohandler; bumped to 3.0.2pre2
+      71     45          Another go at fixing the ARRAY()  issue; bumping to 3.0.2pre3
+      72     46          bulk links
+      73     47          I18N patches from autrijus; bouncing to 3.0.2pre4
+      75     48          bumped version to 3.0.2pre5; attachments performance fixes;
+                 utf-8 mailgateway fixes; more extension hooks; template
+                 updates for approvals
+      76     49          [#2437] CanonicalizeEmailAddress fixes; [# 2449] html fixes
+                 for right editing; [# 2457] email addresses weren't always
+                 being canonicalized
+      77     50          Fixing bogus anchor tags
+      78     51          More performance work on WhoHaveRight; removing an extra join
+      79     52          Cleaning up RT tag processing
+      80     53          Importing utf8 fixes, _Vendor overlay support from ourinternet
+      81     54          Bumping the version to 3.0.2pre6
+      82     55          Bumping the version to RT 3.0.2
+      83     56          merge from ourinternet; one CreateTickets fix and some utf8
+                 updates
+      85     57          Robert's updated search stuff
+      86     58          Fix for #2602 - make test fails on _Config.pm
+      87     59          Including norwegian bokmal translation
+      14     60          #2539: Re: [rt-users] unexpected usage: change sort order with
+                 column headers in search window
+      88     61          Fix to honor '$LogDir' for LogToFile
+      89     62          #2603: /opt/rt3/share/doc should not be a file.
+      90     63          Merging utf8 fixes from autrijus tang
+      91     64          Fixing an upgrade bug from 3.0.2->3.0.3
+      92     65          MIME::Words encoding fixes for mail sending
+      93     66          Additional work on the SQLite port
+      95     67          Merge from ourinternet: UTF8 fixes; more configurable apache
+                 sessions;
+      96     68          ACL HasRight system replaced with an algorithm that does more
+                 looking ahead
+      97     69          A fix to Tickets_Overlay.pm to make the 'Count' methods
+                 actually do a count, not a full SELECT
+      98     70          Further UTF8-fixed from autrijus
+      99     71          Bumping the version to 3.0.3pre1
+     100     72          update layout fix
+     101     73          #2662 Fixing an overly restrictive ACL check on group creation
+     102     74          #2657 Web UI Scrip creation bug
+     103     75          #2652 - de.po updates
+     105     76          #2658 Cosmetic issue with Scrip menu listing
+     106     77          fix for FastCGI and SpeedyCGI setgidness with weird
+                 environments
+     107     78          Continued performance improvements for caching
+     108     79          Log path enhancment to deal more gracefully with absolutely
+                 specified logfile paths
+     109     80          CF defaults; fix Starts set
+     110     81          ACL cache made postgres safe
+     111     82          Fixing an acl bug in Principal_Overlay introduced after 3.0.2
+                 and a possible 'Deep' transaction issue. now requires
+                 DBIx::SearchBuilder 0.83_05 or newer
+     112     83          #2678 Fixing crit messages in RT::User
+     113     84          Bumping DBIx::SearchBuilder requirement to 0.84
+     115     85          The "rt" program, branch 3.0.
+     117     86          pass title to Header
+     116     87          Better testing for internationalization of outoging messages;
+                 slight refactoring to SendEmail to be more testable; added
+                 missing deps to EmailParser
+     118     88          Bump to 3.0.3pre2; fix a misspelled right in Queue.pm (#2686)
+     119     89          #2721 - 'id' attribute had mixed casing. this bothers certain
+                 databases (Sybase)
+     120     90          Header & Logout take URL
+     121     91          Fixes for: Bogus message headers containing high-bit
+                 characters; database handle reconnections; postgres test suite
+                 failures
+     123     92          support group & queue acl setting from rt-setup-database
+     125     93          add TakeTicket, StealTicket rights
+     122     94          Bumping version to 3.0.3pre3, bumping searchbuilder dependency
+     126     95          Really bumping the version to 3.0.3pre3
+     129     96          Various fixes from a pull-up of the ourinternet branch
+     128     97          #2605 - SpamAssassin Filter returns the wrong codes on
+                 success/failure
+     127     98          Fixes the cascading style sheet to properly reference message
+                 bodies
+     130     99          Attempting to be smarter about guessing encodings for outgoing
+                 mail
+     131    100          Fixing search navigation links (they were made to disappear)
+     132    101          #2776 - 'new' ACL cache had bad behaviour. rolled back to
+                 older cache and added tests
+     133    102          On postgres, RT didn't previously cope well with multipart
+                 messages including non-plain parts containing non-ascii
+     135    103          Efficiency tweaks for WhoHaveRight
+     136    104          Bumping version to RT 3.0.3pre4
+     137    105          #2813 Duplicate tickets created at the same time could cause a
+                 user creation race condition
+     138    106          Importing minor bugfixes from ourinternet
+     139    107          #2816 new callback to ShowLinks
+     150    108          #2799: Display URIs instead of HREFs in ticket display
+     151    109          #2797 Clean up automatich chmodding on installation
+     152    110          ShowRequestor takes path
+     153    111          SystemInternal group ACLs in setup
+     155    112          Better encoding and error checking for message headers
+     156    113          better handle notification messages containing only text/html
+                 content.
+     157    114          Bumping to 3.0.3pre5
+     158    115          More I18N fixes from ourinternet
+     159    116          Bumping version to RC-1
+     160    117          Another shot at the header encoding fix
+     161    118          Mitya's failing processing of html email
+     162    119          Bumping to 3.0.3rc2
+     163    120          Anonymizing addresses in mitya's submitted testcases
+     165    121          Better handling of malformed email messages
+     166    122          Bumping version to 3.0rc3
+     167    123          #2850 - With some configurations, users could not create new
+                 tickets with 'new' requestors - Bumped to 3.0 RC 4
+     168    124          Scrip data updates weren't propagating to parent Ticket
+                 objects; Bumping to 3.0.3
+     169    125          CustomField rights checking was overly restrictive for users
+                 without queue-specific rights
+     170    126          I18N mail testing was was being cavalier with the state of
+                 acls after its testing.  (clone of 3.0.C167)
+     171    127          Ticket Update.html fix to not doubly load content
+     172    128          Fixing postgres sortorder bug unmased by searchbuilder fix
+     176    129          Applying POD patches from ourinternet (clone of 3.0.C173)
+     177    130          UTF8, Custom Field and text message rendering fixes from
+                 ourinternet
+     178    131          #2843 Date relations were too strict in RT::Tickets searches
+     179    132          #2847: allow URI Resolver to render itself
+     173    133          ShowMessageHeaders; make headers clicky
+     180    134          use RTIR callbacks
+     175    135          Updating rt-setup-database to take acl and schema file names
+                 on the commandline
+     181    136          Refactored Users::WhoHaveRight from Chris Audley at Blackrock
+     182    137          Download link in ShowTransaction
+     185    138          Fix for speedycgi disappearing database connections
+     183    139          #2873: Fix for insufficently agressive loop culling
+     186    140          Fix for nested email message parsing
+     187    141          Split the HasRight ACL query into two parts. It's now two
+                 small and light SQL queries, instead of one big one that
+                 overwhelmed databases
+     188    142          Stylistic cleanups for HasRight optimizations
+     189    143          Relationship transactions are recorded and displayed more
+                 robustly
+     190    144          Bumping the version to 3.0.4pre1
+     191    145          Updated french translation from Blaise Thauvin
+      13    146          Bumping to 3.0.4RC1
+     192    147          Attachment display bug fix from autrijus tang
+     193    148          Bumping the version to 3.0.4RC2
+     198    149          ShowAttachments had a relative path which hurt extensions
+     199    150          README updates to indicate deprecated dependencies
+     200    151          Debugging framework cleanup
+     201    152          Bumping version to 3.0.4
+
+  rt.3.0.D152, C201, jesse, Sat Jul 12 02:41:34 2003, Bumping version to 3.0.4
+      From: Jesse Vincent <jesse@localhost>
+      Date: Fri Jul 11 23:35:03 2003
+
+      none
+
+  rt.3.0.D151, C200, jesse, Sat Jul 12 01:34:41 2003, Debugging framework
+  cleanup
+      From: Jesse Vincent <jesse@localhost>
+      Date: Fri Jul 11 22:31:37 2003
+
+      none
+
+  rt.3.0.D150, C199, jesse, Sat Jul 12 01:17:57 2003, README updates to indicate
+  deprecated dependencies
+      From: Jesse Vincent <jesse@localhost>
+      Date: Fri Jul 11 22:14:37 2003
+
+      none
+
+  rt.3.0.D149, C198, leira, Sat Jul 12 01:17:08 2003, ShowAttachments had a
+  relative path which hurt extensions
+      From: Linda L. Julien <leira@starsong.org>
+      Date: Wed Jul  9 23:33:21 2003
+      Warning: the original change was in the 'being_developed' state
+
+      none
+
+  rt.3.0.D148, C193, jesse, Sat Jul  5 17:34:46 2003, Bumping the version to
+  3.0.4RC2
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Sat Jul  5 17:22:07 2003
+
+      none
+
+  rt.3.0.D147, C192, jesse, Sat Jul  5 17:11:25 2003, Attachment display bug fix
+  from autrijus tang
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Sat Jul  5 17:09:07 2003
+
+      none
+
+  rt.3.0.D146, C13, jesse, Fri Jul  4 14:54:43 2003, Bumping to 3.0.4RC1
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Jul  4 14:52:56 2003
+
+      none
+
+  rt.3.0.D145, C191, jesse, Fri Jul  4 14:50:26 2003, Updated french translation
+  from Blaise Thauvin
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Jul  4 14:48:56 2003
+
+      none
+
+  rt.3.0.D144, C190, jesse, Thu Jul  3 01:48:45 2003, Bumping the version to
+  3.0.4pre1
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Thu Jul  3 01:47:25 2003
+
+      none
+
+  rt.3.0.D143, C189, jesse, Thu Jul  3 01:44:51 2003, Relationship transactions
+  are recorded and displayed more robustly
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Thu Jul  3 01:44:08 2003
+
+      none
+
+  rt.3.0.D142, C188, jesse, Wed Jul  2 21:01:44 2003, Stylistic cleanups for
+  HasRight optimizations
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Wed Jul  2 20:58:51 2003
+
+      none
+
+  rt.3.0.D141, C187, jesse, Wed Jul  2 02:48:21 2003, Split the HasRight ACL
+  query into two parts. It's now two small and light SQL queries, instead of one
+  big one that overwhelmed databases
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Wed Jul  2 02:45:49 2003
+
+      none
+
+  rt.3.0.D140, C186, jesse, Wed Jul  2 02:19:47 2003, Fix for nested email
+  message parsing
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Wed Jul  2 02:17:38 2003
+
+      none
+
+  rt.3.0.D139, C183, jesse, Tue Jul  1 23:18:28 2003, #2873: Fix for
+  insufficently agressive loop culling
+      From: Jesse Vincent <jesse@eris>
+      Date: Mon Jun 30 21:12:50 2003
+
+      none
+
+  rt.3.0.D138, C185, jesse, Tue Jul  1 19:08:47 2003, Fix for speedycgi
+  disappearing database connections
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Tue Jul  1 19:05:19 2003
+
+      none
+
+  rt.3.0.D137, C182, leira, Tue Jul  1 16:10:33 2003, Download link in
+  ShowTransaction
+      From: Linda L. Julien <leira@starsong.org>
+      Date: Mon Jun 30 18:04:52 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D136, C181, jesse, Mon Jun 30 15:25:46 2003, Refactored
+  Users::WhoHaveRight from Chris Audley at Blackrock
+      From: Jesse Vincent <jesse@eris>
+      Date: Mon Jun 30 15:23:18 2003
+
+      none
+
+  rt.3.0.D135, C175, jesse, Mon Jun 30 15:24:56 2003, Updating rt-setup-database
+  to take acl and schema file names on the commandline
+      From: Jesse Vincent <jesse@eris>
+      Date: Mon Jun 30 13:41:12 2003
+
+      none
+
+  rt.3.0.D134, C180, leira, Mon Jun 30 02:19:05 2003, use RTIR callbacks
+      From: Linda Julien <leira@hawthorn.local.>
+      Date: Mon Jun 30 02:11:25 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D133, C173, leira, Mon Jun 30 02:17:05 2003, ShowMessageHeaders; make
+  headers clicky
+      From: Linda Julien <leira@hawthorn.local.>
+      Date: Sun Jun 29 23:31:39 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D132, C179, jesse, Sun Jun 29 03:06:36 2003, #2847: allow URI Resolver
+  to render itself
+      From: Jesse Vincent <jesse@eris>
+      Date: Sun Jun 29 03:04:30 2003
+
+      none
+
+  rt.3.0.D131, C178, jesse, Sun Jun 29 02:59:13 2003, #2843 Date relations were
+  too strict in RT::Tickets searches
+      From: Jesse Vincent <jesse@eris>
+      Date: Sun Jun 29 02:57:53 2003
+
+      none
+
+  rt.3.0.D130, C177, jesse, Sat Jun 28 18:17:28 2003, UTF8, Custom Field and
+  text message rendering fixes from ourinternet
+      From: Jesse Vincent <jesse@eris>
+      Date: Sat Jun 28 18:15:09 2003
+
+      none
+
+  rt.3.0.D129, C176, jesse, Sat Jun 28 17:23:01 2003, Applying POD patches from
+  ourinternet (clone of 3.0.C173)
+      From: Jesse Vincent <jesse@eris>
+      Date: Sat Jun 28 17:15:38 2003
+
+      none
+
+  rt.3.0.D128, C172, jesse, Sat Jun 28 17:17:53 2003, Fixing postgres sortorder
+  bug unmased by searchbuilder fix
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Jun 27 01:12:13 2003
+
+      none
+
+  rt.3.0.D127, C171, jesse, Tue Jun 24 16:42:07 2003, Ticket Update.html fix to
+  not doubly load content
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun 24 16:28:49 2003
+
+      none
+
+  rt.3.0.D126, C170, jesse, Tue Jun 24 16:23:49 2003, I18N mail testing was was
+  being cavalier with the state of acls after its testing.  (clone of 3.0.C167)
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun 24 16:22:16 2003
+
+      none
+
+  rt.3.0.D125, C169, jesse, Tue Jun 24 16:23:37 2003, CustomField rights
+  checking was overly restrictive for users without queue-specific rights
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun 24 16:18:05 2003
+
+      none
+
+  rt.3.0.D124, C168, jesse, Sat Jun 21 13:01:18 2003, Scrip data updates weren't
+  propagating to parent Ticket objects; Bumping to 3.0.3
+      From: Jesse Vincent <jesse@eris>
+      Date: Sat Jun 21 12:55:04 2003
+
+      none
+
+  rt.3.0.D123, C167, jesse, Thu Jun 19 22:23:01 2003, #2850 - With some
+  configurations, users could not create new tickets with 'new' requestors -
+  Bumped to 3.0 RC 4
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Jun 19 22:22:20 2003
+
+      none
+
+  rt.3.0.D122, C166, jesse, Thu Jun 19 14:25:03 2003, Bumping version to 3.0rc3
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Jun 19 14:18:19 2003
+
+      none
+
+  rt.3.0.D121, C165, jesse, Thu Jun 19 12:25:20 2003, Better handling of
+  malformed email messages
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Jun 19 12:21:56 2003
+
+      none
+
+  rt.3.0.D120, C163, jesse, Thu Jun 19 03:17:20 2003, Anonymizing addresses in
+  mitya's submitted testcases
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Jun 19 03:16:47 2003
+
+      none
+
+  rt.3.0.D119, C162, jesse, Thu Jun 19 03:03:16 2003, Bumping to 3.0.3rc2
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Jun 19 03:01:10 2003
+
+      none
+
+  rt.3.0.D118, C161, jesse, Thu Jun 19 02:58:24 2003, Mitya's failing processing
+  of html email
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Jun 19 02:56:48 2003
+
+      none
+
+  rt.3.0.D117, C160, jesse, Wed Jun 18 17:58:34 2003, Another shot at the header
+  encoding fix
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Jun 18 17:58:01 2003
+
+      none
+
+  rt.3.0.D116, C159, jesse, Wed Jun 18 01:27:03 2003, Bumping version to RC-1
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Jun 18 01:25:13 2003
+
+      none
+
+  rt.3.0.D115, C158, jesse, Wed Jun 18 01:01:22 2003, More I18N fixes from
+  ourinternet
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Jun 18 01:00:11 2003
+
+      none
+
+  rt.3.0.D114, C157, jesse, Tue Jun 17 22:24:03 2003, Bumping to 3.0.3pre5
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun 17 22:20:51 2003
+
+      none
+
+  rt.3.0.D113, C156, jesse, Tue Jun 17 22:14:35 2003, better handle notification
+  messages containing only text/html content.
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun 17 21:55:06 2003
+
+      none
+
+  rt.3.0.D112, C155, jesse, Tue Jun 17 21:55:16 2003, Better encoding and error
+  checking for message headers
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun 17 21:26:27 2003
+      Warning: the original change was in the 'being_developed' state
+
+      none
+
+  rt.3.0.D111, C153, leira, Tue Jun 17 17:47:18 2003, SystemInternal group ACLs
+  in setup
+      From: Linda L. Julien <leira@starsong.org>
+      Date: Tue Jun 17 18:19:58 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D110, C152, leira, Tue Jun 17 16:46:34 2003, ShowRequestor takes path
+      From: Linda L. Julien <leira@oak.starsong.org>
+      Date: Tue Jun 17 12:53:35 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D109, C151, jesse, Mon Jun 16 23:48:53 2003, #2797 Clean up automatich
+  chmodding on installation
+      From: Jesse Vincent <jesse@eris>
+      Date: Mon Jun 16 23:48:19 2003
+
+      none
+
+  rt.3.0.D108, C150, jesse, Mon Jun 16 23:36:29 2003, #2799: Display URIs
+  instead of HREFs in ticket display
+      From: Jesse Vincent <jesse@eris>
+      Date: Mon Jun 16 23:35:00 2003
+
+      none
+
+  rt.3.0.D107, C139, jesse, Mon Jun 16 23:16:45 2003, #2816 new callback to
+  ShowLinks
+      From: Jesse Vincent <jesse@eris>
+      Date: Mon Jun 16 23:14:05 2003
+
+      none
+
+  rt.3.0.D106, C138, jesse, Mon Jun 16 23:16:29 2003, Importing minor bugfixes
+  from ourinternet
+      From: Jesse Vincent <jesse@eris>
+      Date: Mon Jun 16 23:06:00 2003
+
+      none
+
+  rt.3.0.D105, C137, jesse, Mon Jun 16 19:41:13 2003, #2813 Duplicate tickets
+  created at the same time could cause a user creation race condition
+      From: Jesse Vincent <jesse@eris>
+      Date: Mon Jun 16 19:39:57 2003
+
+      none
+
+  rt.3.0.D104, C136, jesse, Fri Jun 13 18:27:11 2003, Bumping version to RT
+  3.0.3pre4
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Jun 13 18:25:57 2003
+
+      none
+
+  rt.3.0.D103, C135, jesse, Fri Jun 13 18:22:33 2003, Efficiency tweaks for
+  WhoHaveRight
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Jun 13 18:19:02 2003
+
+      none
+
+  rt.3.0.D102, C133, jesse, Fri Jun 13 18:18:32 2003, On postgres, RT didn't
+  previously cope well with multipart messages including non-plain parts
+  containing non-ascii
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Jun 13 18:17:37 2003
+
+      none
+
+  rt.3.0.D101, C132, jesse, Fri Jun 13 01:41:24 2003, #2776 - 'new' ACL cache
+  had bad behaviour. rolled back to older cache and added tests
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Jun 13 01:40:26 2003
+
+      none
+
+  rt.3.0.D100, C131, jesse, Thu Jun 12 13:22:10 2003, Fixing search navigation
+  links (they were made to disappear)
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Jun 12 13:19:37 2003
+
+      none
+
+  rt.3.0.D099, C130, jesse, Wed Jun 11 16:44:16 2003, Attempting to be smarter
+  about guessing encodings for outgoing mail
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Jun 11 16:42:50 2003
+      Warning: the original change was in the 'being_developed' state
+
+      none
+
+  rt.3.0.D098, C127, jesse, Wed Jun 11 16:39:39 2003, Fixes the cascading style
+  sheet to properly reference message bodies
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Jun 11 15:43:39 2003
+      Warning: the original change was in the 'being_developed' state
+
+  rt.3.0.D097, C128, jesse, Wed Jun 11 16:37:38 2003, #2605 - SpamAssassin
+  Filter returns the wrong codes on success/failure
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Jun 11 15:53:58 2003
+
+      none
+
+  rt.3.0.D096, C129, jesse, Wed Jun 11 16:36:53 2003, Various fixes from a pull-
+  up of the ourinternet branch
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Jun 11 16:17:44 2003
+
+      none
+
+  rt.3.0.D095, C126, jesse, Tue Jun 10 16:17:50 2003, Really bumping the version
+  to 3.0.3pre3
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun 10 16:17:08 2003
+
+      none
+
+  rt.3.0.D094, C122, jesse, Tue Jun 10 15:58:32 2003, Bumping version to
+  3.0.3pre3, bumping searchbuilder dependency
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun 10 15:56:41 2003
+
+      none
+
+  rt.3.0.D093, C125, jesse, Tue Jun 10 15:54:52 2003, add TakeTicket,
+  StealTicket rights
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun 10 15:41:43 2003
+      Warning: the original change was in the 'being_developed' state
+
+      From: Jesse <jesse@fsck.com>
+      Date: Tue Jun 10 11:01:04 2003
+      Warning: the original change was in the 'being_reviewed' state
+
+      From: Linda L. Julien <leira@oak.starsong.org>
+      Date: Tue Jun 10 11:58:03 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D092, C123, leira, Tue Jun 10 15:54:10 2003, support group & queue acl
+  setting from rt-setup-database
+      From: Linda L. Julien <leira@oak.starsong.org>
+      Date: Tue Jun 10 14:13:46 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D091, C121, jesse, Sun Jun  8 00:41:47 2003, Fixes for: Bogus message
+  headers containing high-bit characters; database handle reconnections;
+  postgres test suite failures
+      From: Jesse Vincent <jesse@eris>
+      Date: Sun Jun  8 00:32:40 2003
+
+      none
+
+  rt.3.0.D090, C120, leira, Sun Jun  8 00:34:40 2003, Header & Logout take URL
+      From: Linda L. Julien <leira@oak.starsong.org>
+      Date: Fri Jun  6 19:06:41 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D089, C119, jesse, Fri Jun  6 17:33:37 2003, #2721 - 'id' attribute had
+  mixed casing. this bothers certain databases (Sybase)
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Jun  6 17:32:16 2003
+
+      none
+
+  rt.3.0.D088, C118, jesse, Wed Jun  4 17:21:24 2003, Bump to 3.0.3pre2; fix a
+  misspelled right in Queue.pm (#2686)
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Jun  4 17:19:39 2003
+      Warning: the original change was in the 'being_developed' state
+
+      The "rt" program, branch 3.0.
+
+  rt.3.0.D087, C116, jesse, Wed Jun  4 17:17:08 2003, Better testing for
+  internationalization of outoging messages; slight refactoring to SendEmail to
+  be more testable; added missing deps to EmailParser
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Jun  4 16:53:07 2003
+
+      none
+
+  rt.3.0.D086, C117, leira, Wed Jun  4 00:23:20 2003, pass title to Header
+      From: Linda L. Julien <leira@oak.starsong.org>
+      Date: Tue Jun  3 18:09:39 2003
+      Warning: the original change was in the 'being_developed' state
+
+      none
+
+  rt.3.0.D085, C115, jesse, Tue Jun  3 00:45:12 2003, The "rt" program, branch
+  3.0.
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun  3 00:43:15 2003
+      Warning: the original change was in the 'being_developed' state
+
+      The "rt" program, branch 3.0.
+
+  rt.3.0.D084, C113, jesse, Tue Jun  3 00:20:07 2003, Bumping
+  DBIx::SearchBuilder requirement to 0.84
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun  3 00:19:50 2003
+
+      none
+
+  rt.3.0.D083, C112, jesse, Tue Jun  3 00:18:43 2003, #2678 Fixing crit messages
+  in RT::User
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun  3 00:18:12 2003
+
+      none
+
+  rt.3.0.D082, C111, jesse, Tue Jun  3 00:04:45 2003, Fixing an acl bug in
+  Principal_Overlay introduced after 3.0.2 and a possible 'Deep' transaction
+  issue. now requires DBIx::SearchBuilder 0.83_05 or newer
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Jun  3 00:02:23 2003
+
+      none
+
+  rt.3.0.D081, C110, jesse, Mon Jun  2 22:40:34 2003, ACL cache made postgres
+  safe
+      From: Jesse Vincent <jesse@eris>
+      Date: Mon Jun  2 22:39:03 2003
+
+      none
+
+  rt.3.0.D080, C109, leira, Mon Jun  2 17:10:05 2003, CF defaults; fix Starts
+  set
+      From: Linda L. Julien <leira@oak.starsong.org>
+      Date: Mon Jun  2 17:32:11 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D079, C108, jesse, Sat May 31 00:28:37 2003, Log path enhancment to
+  deal more gracefully with absolutely specified logfile paths
+      From: Jesse Vincent <jesse@eris>
+      Date: Sat May 31 00:27:38 2003
+
+      none
+
+  rt.3.0.D078, C107, jesse, Sat May 31 00:20:53 2003, Continued performance
+  improvements for caching
+      From: Jesse Vincent <jesse@eris>
+      Date: Sat May 31 00:19:32 2003
+
+      none
+
+  rt.3.0.D077, C106, jesse, Sat May 31 00:20:32 2003, fix for FastCGI and
+  SpeedyCGI setgidness with weird environments
+      From: Jesse Vincent <jesse@eris>
+      Date: Sat May 31 00:19:15 2003
+
+      none
+
+  rt.3.0.D076, C105, jesse, Fri May 30 16:21:14 2003, #2658 Cosmetic issue with
+  Scrip menu listing
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri May 30 16:14:02 2003
+
+      none
+
+  rt.3.0.D075, C103, jesse, Fri May 30 16:20:57 2003, #2652 - de.po updates
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri May 30 15:57:44 2003
+
+      none
+
+  rt.3.0.D074, C102, jesse, Fri May 30 16:18:57 2003, #2657 Web UI Scrip
+  creation bug
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri May 30 15:50:16 2003
+
+      none
+
+  rt.3.0.D073, C101, jesse, Fri May 30 16:17:43 2003, #2662 Fixing an overly
+  restrictive ACL check on group creation
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri May 30 15:46:22 2003
+
+      none
+
+  rt.3.0.D072, C100, leira, Fri May 30 16:17:05 2003, update layout fix
+      From: Linda L. Julien <leira@oak.starsong.org>
+      Date: Thu May 29 14:30:01 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D071, C99, jesse, Wed May 28 17:54:48 2003, Bumping the version to
+  3.0.3pre1
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed May 28 17:52:51 2003
+
+      none
+
+  rt.3.0.D070, C98, jesse, Wed May 28 17:54:40 2003, Further UTF8-fixed from
+  autrijus
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed May 28 17:49:32 2003
+
+      none
+
+  rt.3.0.D069, C97, jesse, Wed May 28 17:07:10 2003, A fix to Tickets_Overlay.pm
+  to make the 'Count' methods actually do a count, not a full SELECT
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed May 28 17:04:50 2003
+
+      none
+
+  rt.3.0.D068, C96, jesse, Wed May 28 17:06:43 2003, ACL HasRight system
+  replaced with an algorithm that does more looking ahead
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed May 28 16:36:10 2003
+
+      none
+
+  rt.3.0.D067, C95, jesse, Tue May 27 13:22:19 2003, Merge from ourinternet:
+  UTF8 fixes; more configurable apache sessions;
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Tue May 27 13:07:41 2003
+
+      none
+
+  rt.3.0.D066, C93, jesse, Sat May 24 18:05:36 2003, Additional work on the
+  SQLite port
+      From: Jesse Vincent <jesse@eris>
+      Date: Sat May 24 18:04:50 2003
+
+      none
+
+  rt.3.0.D065, C92, jesse, Fri May 23 16:45:23 2003, MIME::Words encoding fixes
+  for mail sending
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri May 23 16:44:28 2003
+
+      none
+
+  rt.3.0.D064, C91, jesse, Fri May 23 16:12:26 2003, Fixing an upgrade bug from
+  3.0.2->3.0.3
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri May 23 15:57:50 2003
+
+      none
+
+  rt.3.0.D063, C90, jesse, Fri May 23 15:27:47 2003, Merging utf8 fixes from
+  autrijus tang
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri May 23 15:25:23 2003
+
+      none
+
+  rt.3.0.D062, C89, jesse, Wed May 21 00:58:34 2003, #2603: /opt/rt3/share/doc
+  should not be a file.
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Wed May 21 00:29:55 2003
+
+      none
+
+  rt.3.0.D061, C88, jesse, Wed May 21 00:57:45 2003, Fix to honor '$LogDir' for
+  LogToFile
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Wed May 21 00:17:18 2003
+
+      none
+
+  rt.3.0.D060, C14, jesse, Wed May 21 00:56:31 2003, #2539: Re: [rt-users]
+  unexpected usage: change sort order with column headers in search window
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Tue May 20 23:19:46 2003
+
+      none
+
+  rt.3.0.D059, C87, jesse, Wed May 21 00:55:08 2003, Including norwegian bokmal
+  translation
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Tue May 20 23:05:17 2003
+
+      none
+
+  rt.3.0.D058, C86, jesse, Wed May 21 00:54:06 2003, Fix for #2602 - make test
+  fails on _Config.pm
+      From: Jesse Vincent <jesse@Jesse-Vincents-Computer.local.>
+      Date: Tue May 20 22:32:52 2003
+
+      none
+
+  rt.3.0.D057, C85, leira, Tue May 20 12:15:11 2003, Robert's updated search
+  stuff
+      From: Linda L. Julien <leira@oak.starsong.org>
+      Date: Mon May 19 18:19:14 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D056, C83, jesse, Sat May 17 17:34:32 2003, merge from ourinternet; one
+  CreateTickets fix and some utf8 updates
+      From: Jesse Vincent <jesse@eris>
+      Date: Sat May 17 17:31:43 2003
+
+      none
+
+  rt.3.0.D055, C82, jesse, Mon May 12 20:30:45 2003, Bumping the version to RT
+  3.0.2
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue May 13 02:29:44 2003
+
+      none
+
+  rt.3.0.D054, C81, jesse, Wed May  7 09:18:28 2003, Bumping the version to
+  3.0.2pre6
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed May  7 15:16:55 2003
+      Warning: the original change was in the 'being_developed' state
+
+      none
+
+  rt.3.0.D053, C80, jesse, Wed May  7 09:02:24 2003, Importing utf8 fixes, _
+  Vendor overlay support from ourinternet
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed May  7 14:52:58 2003
+
+      none
+
+  rt.3.0.D052, C79, jesse, Wed May  7 07:05:14 2003, Cleaning up RT tag
+  processing
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed May  7 13:04:17 2003
+
+      none
+
+  rt.3.0.D051, C78, jesse, Wed May  7 07:03:27 2003, More performance work on
+  WhoHaveRight; removing an extra join
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed May  7 13:00:43 2003
+
+      none
+
+  rt.3.0.D050, C77, jesse, Fri May  2 11:23:23 2003, Fixing bogus anchor tags
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri May  2 17:19:54 2003
+
+      none
+
+  rt.3.0.D049, C76, jesse, Fri May  2 10:26:30 2003, [#2437]
+  CanonicalizeEmailAddress fixes; [# 2449] html fixes for right editing; [#
+  2457] email addresses weren't always being canonicalized
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri May  2 16:24:40 2003
+
+      none
+
+  rt.3.0.D048, C75, jesse, Fri May  2 08:35:38 2003, bumped version to
+  3.0.2pre5; attachments performance fixes; utf-8 mailgateway fixes; more
+  extension hooks; template updates for approvals
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri May  2 14:32:57 2003
+
+      none
+
+  rt.3.0.D047, C73, jesse, Sun Apr 27 19:06:46 2003, I18N patches from autrijus;
+  bouncing to 3.0.2pre4
+      From: Jesse Vincent <jesse@eris>
+      Date: Mon Apr 28 01:02:18 2003
+
+      none
+
+  rt.3.0.D046, C72, leira, Sun Apr 27 19:06:04 2003, bulk links
+      From: Linda L. Julien <leira@oak.starsong.org>
+      Date: Thu Apr 24 01:23:01 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D045, C71, jesse, Sat Apr 19 03:42:39 2003, Another go at fixing the
+  ARRAY()  issue; bumping to 3.0.2pre3
+      From: Jesse Vincent <jesse@eris>
+      Date: Sat Apr 19 08:39:19 2003
+
+      none
+
+  rt.3.0.D044, C70, jesse, Fri Apr 18 16:37:00 2003, fixing utf8 tainting issue
+  in autohandler; bumped to 3.0.2pre2
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Apr 18 21:32:04 2003
+
+      none
+
+  rt.3.0.D043, C69, leira, Thu Apr 17 18:51:41 2003, make ids clicky
+      From: Linda L. Julien <leira@oak.starsong.org>
+      Date: Thu Apr 17 18:31:40 2003
+      Warning: the original change was in the 'awaiting_integration' state
+
+      none
+
+  rt.3.0.D042, C68, jesse, Thu Apr 17 18:39:54 2003, Bumping to 3.0.2pre1
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Apr 17 23:37:59 2003
+
+      none
+
+  rt.3.0.D041, C67, jesse, Thu Apr 17 18:33:15 2003, updating autrijus'
+  autohandler patch. seems to break lots of stuff
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Apr 17 23:21:02 2003
+
+      none
+
+  rt.3.0.D040, C66, jesse, Thu Apr 17 18:32:24 2003, Quicksearch bug fix from
+  Stan
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Apr 17 23:16:58 2003
+
+      none
+
+  rt.3.0.D039, C65, jesse, Thu Apr 17 18:29:31 2003, Fixing an untainting bug in
+  3.0.1
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Apr 17 23:15:01 2003
+      Warning: the original change was in the 'being_developed' state
+
+      none
+
+  rt.3.0.D038, C63, jesse, Thu Apr 17 04:46:42 2003, Fixing a showmessagestanza
+  bug found in RTIR
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Apr 17 09:45:48 2003
+
+      none
+
+  rt.3.0.D037, C62, jesse, Tue Apr 15 11:53:58 2003, Bumping to version 3.0.1
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Apr 15 11:52:00 2003
+
+      none
+
+  rt.3.0.D036, C61, jesse, Mon Apr 14 18:18:03 2003, New speedycgi support from
+  vivek khera
+      From: Jesse Vincent <jesse@eris>
+      Date: Mon Apr 14 14:49:49 2003
+
+      none
+
+  rt.3.0.D035, C60, jesse, Sun Apr 13 21:43:32 2003, SMTP and I18N fixes from
+  autrijus tang. Updated chinese translations
+      From: Jesse Vincent <jesse@eris>
+      Date: Sun Apr 13 21:32:55 2003
+
+      none
+
+  rt.3.0.D034, C59, jesse, Fri Apr 11 21:58:36 2003, Bumping to RT 3.0.1pre2
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Apr 11 21:58:06 2003
+
+      none
+
+  rt.3.0.D033, C58, jesse, Fri Apr 11 21:56:11 2003, Better binary attachment
+  handling fix from autrijus
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Apr 11 21:52:12 2003
+
+      none
+
+  rt.3.0.D032, C57, jesse, Fri Apr 11 21:35:17 2003, Testing and fixing binary
+  attachment corruption
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Apr 11 21:34:28 2003
+
+      none
+
+  rt.3.0.D031, C56, jesse, Fri Apr 11 21:34:56 2003, Testing fixes for mail
+  authentication/authorization
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Apr 10 00:08:29 2003
+
+      none
+
+  rt.3.0.D030, C55, jesse, Wed Apr  9 13:55:18 2003, #2365 Removing outdated
+  Mason setup parameter
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Apr  9 13:54:43 2003
+
+      none
+
+  rt.3.0.D029, C53, jesse, Wed Apr  9 13:22:35 2003, Added preliminary left to
+  right hebrew translation
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Apr  9 13:18:16 2003
+
+      none
+
+  rt.3.0.D028, C52, jesse, Fri Apr  4 02:10:01 2003, More I18N testing for
+  rafael
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Apr  4 02:08:49 2003
+
+      none
+
+  rt.3.0.D027, C51, jesse, Thu Apr  3 19:33:34 2003, Changing address used in
+  example to not send mail to author
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Apr  3 19:29:02 2003
+      Warning: the original change was in the 'being_integrated' state
+
+      none
+
+  rt.3.0.D026, C50, jesse, Thu Apr  3 19:16:37 2003, Integrating rafael's
+  failing test suite and proposed fix from autrijus
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Apr  3 19:15:03 2003
+
+      none
+
+  rt.3.0.D025, C39, jesse, Thu Apr  3 19:16:15 2003, Many users should be able
+  to have a blank address; neew test suite to ensure this
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Apr  3 13:27:36 2003
+
+      none
+
+  rt.3.0.D024, C38, jesse, Thu Apr  3 13:30:37 2003, Updates for RT RPC
+  interface from AMS
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Apr  2 15:32:15 2003
+
+      none
+
+  rt.3.0.D023, C36, jesse, Wed Apr  2 14:14:07 2003, Updated Spanish translation
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Apr  1 14:02:36 2003
+
+      none
+
+  rt.3.0.D022, C37, jesse, Wed Apr  2 14:13:55 2003, Updated dependencies
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Apr  2 14:09:41 2003
+
+      none
+
+  rt.3.0.D021, C35, jesse, Tue Apr  1 13:00:22 2003, New czech translation
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Apr  1 12:58:57 2003
+
+      none
+
+  rt.3.0.D020, C33, jesse, Fri Mar 28 14:48:20 2003, A tiny bit of extra data
+  passing for some callbacks
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Mar 28 14:43:28 2003
+
+      none
+
+  rt.3.0.D019, C32, jesse, Fri Mar 28 14:35:10 2003, Added better error checking
+  for failed ticket creation
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Mar 28 14:32:52 2003
+
+      none
+
+  rt.3.0.D018, C31, jesse, Sun Mar 23 17:21:45 2003, Minor fixes - Bumped to
+  3.0.0;
+  2266 - postgres scrip creation bug
+  2267 - Tickets not reopened after being stalled
+  2265 - Fixed css nits from blaise
+  Unreported - Fixed quick-search bug
+      From: Jesse Vincent <jesse@eris>
+      Date: Sun Mar 23 17:17:55 2003
+
+      none
+
+  rt.3.0.D017, C30, jesse, Thu Mar 20 21:38:30 2003, Bumping to 3.0.0rc4
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Mar 20 21:28:01 2003
+
+      none
+
+  rt.3.0.D016, C29, jesse, Thu Mar 20 21:18:27 2003, RT should now be less
+  overzealous about opening and then marking a ticket 'new' again
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Mar 20 21:14:47 2003
+
+      none
+
+  rt.3.0.D015, C28, jesse, Thu Mar 20 15:21:49 2003, Further postgres tweaks and
+  fixes
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Mar 20 15:20:21 2003
+
+      none
+
+  rt.3.0.D014, C27, jesse, Thu Mar 20 01:48:42 2003, Postgres schema tweak
+      From: Jesse Vincent <jesse@eris>
+      Date: Thu Mar 20 01:47:20 2003
+
+      none
+
+  rt.3.0.D013, C26, jesse, Wed Mar 19 21:26:47 2003, Postgres fixes
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Mar 19 21:26:24 2003
+
+      none
+
+  rt.3.0.D012, C25, jesse, Wed Mar 19 16:27:29 2003, Brazilian Portuguese
+  translation
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Mar 19 16:25:48 2003
+
+      none
+
+  rt.3.0.D011, C23, jesse, Wed Mar 19 13:03:15 2003, New french translation
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Mar 19 13:02:47 2003
+
+      none
+
+  rt.3.0.D010, C22, jesse, Wed Mar 19 01:01:24 2003, Bumping to RC3; fixing the
+  display of 'This user's n highest priority tix'
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Mar 19 01:00:33 2003
+
+      none
+
+  rt.3.0.D009, C20, jesse, Wed Mar 19 00:46:17 2003, finishing the notify stuff
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Mar 19 00:45:09 2003
+
+      none
+
+  rt.3.0.D008, C19, jesse, Wed Mar 19 00:40:45 2003, Caving in to the masses and
+  making 'notify sender' configurable
+      From: Jesse Vincent <jesse@eris>
+      Date: Wed Mar 19 00:38:50 2003
+
+      none
+
+  rt.3.0.D007, C18, jesse, Tue Mar 18 16:29:45 2003, More performance work;
+  backing out 'enhancements' that killed system performance
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Mar 18 16:26:07 2003
+
+      none
+
+  rt.3.0.D006, C17, jesse, Tue Mar 18 11:29:28 2003, fixing fastcgi's ability to
+  load webmux.pl on some platforms
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Mar 18 11:28:11 2003
+
+      none
+
+  rt.3.0.D005, C12, jesse, Tue Mar 18 00:58:52 2003, fixing indices for postgres
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Mar 18 00:53:06 2003
+
+      none
+
+  rt.3.0.D004, C16, jesse, Tue Mar 18 00:41:26 2003, Performance work on
+  'WhoHaveRight'; bumping to 3.0.0rc2
+      From: Jesse Vincent <jesse@eris>
+      Date: Tue Mar 18 00:37:30 2003
+
+      none
+
+  rt.3.0.D003, C15, jesse, Fri Mar 14 17:07:28 2003, removing the old REST API
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Mar 14 16:50:38 2003
+
+      none
+
+  rt.3.0.D002, C11, jesse, Fri Mar 14 16:42:46 2003, Minor CSS update. rollback
+  fix; new database indices; copyright update
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Mar 14 16:35:01 2003
+
+      none
+
+  rt.3.0.D001, C10, jesse, Fri Mar 14 01:26:22 2003, Bumping the version to
+  rt.3.0.0rc0
+      From: Jesse Vincent <jesse@eris>
+      Date: Fri Mar 14 01:25:51 2003
+
+      none
diff --git a/rt/HOWTO/README b/rt/HOWTO/README
new file mode 100644 (file)
index 0000000..942096b
--- /dev/null
@@ -0,0 +1,14 @@
+Here you'll find plain text documentation of how to handle various
+project procedures.  Files contained herein:
+
+change.txt
+        How changes are integrated, including generating and
+        distributing aedist change sets, and updating the CVS repository.
+
+release.txt
+       Steps to go through when releasing a new version of RT.
+
+
+These procedures are based on documentation from the scons project
+as http://www.scons.org/
+
diff --git a/rt/HOWTO/change.txt b/rt/HOWTO/change.txt
new file mode 100644 (file)
index 0000000..de31645
--- /dev/null
@@ -0,0 +1,67 @@
+Handling a change set:
+
+    -- Start the change:
+
+               aedist -r       [if it's a remote submission]
+                
+                -or-
+
+               aedb {cnum}     [if it's initiated locally]
+
+    -- Normal development cycle:
+
+                aecd -c {cnum}                   
+                aecp .          # Copy the baseline to your working dir
+                # work on your change
+                aenf {new file names}
+
+                aecpu -unch   # Remove unchanged files, for faster diffs
+               aeb # Currently does nothing
+               aet # Currently does nothing
+               aed # Diff your change
+               aede # End the change
+
+    -- As the reviewer:
+               aerpass {cnum}
+
+    -- As the integrator:
+
+               aeib {cnum}
+               aeb
+               aet
+               aed
+                cd ~ # Get out of the current working directory
+               aeipass
+
+
+
+
+    -- Update the aedist baseline on the web site:
+
+               aedist -s -bl -p rt.2.1 > rt.2.1.ae
+               scp rt.2.1.ae jesse@fsck.com:/home/ftp/pub/rt/devel/rt.2.1.ae
+               rm rt.2.1.ae
+
+       [This will eventually be automated.]
+
+    -- Distribute the change to CVS:
+
+        WARNING. DOES NOT YET WORK
+
+               export CVS_RSH=ssh
+               ae2cvs -n -aegis -p rt.2.1 -c {cnum} -u ~/SCons/scons
+               ae2cvs -X -aegis -p rt.2.1 -c {cnum} -u ~/SCons/scons
+
+        If you need the "ae2cvs" Perl script, you can find a copy
+        checked in to the bin/subdirectory.
+
+       [This may eventually be automated.]
+
+
+
+       -- Grabbing the latest dev sources over ssh 
+
+       ssh fsck.com "aedist -s -p rt.2.1 -naa -bl -entire-source" | aedist -r
+
+
diff --git a/rt/HOWTO/release.txt b/rt/HOWTO/release.txt
new file mode 100644 (file)
index 0000000..285041c
--- /dev/null
@@ -0,0 +1,124 @@
+Things to do to release a new version of rt:
+
+       Build and test candidate packages
+
+       Read through the README and src/README.txt files for any updates
+
+       Prepare ChangeLog
+
+               date -R the latest release
+
+               should be current if this has been updated as each
+               change went in.
+
+                [ Should be automated ]
+
+
+        TODO: nothing below this line is accurate for RT
+
+       END THE BRANCH
+
+               ae_p rt.2
+               aede {5}
+               aerpass {5}
+               aeib {5}
+               aeb
+               aet
+               aet -reg
+               aed
+               aeipass
+
+       START THE NEW BRANCH
+
+               aenbr -p rt.2 {6}
+               aenc -p rt.2.{6}
+
+                        Call it something like, "Initialize the new
+                        branch."  Cause = internal_enhancement.  Exempt
+                        it from all tests (*_exempt = true).
+
+               ae_p rt.2.{6}
+
+               aedb 100
+
+               aecd
+
+               # Change the hard-coded package version numbers
+               # in the following files.
+               aecp rttruct debian/changelog rpm/rt.spec
+
+               vi rttruct debian/changelog rpm/rt.spec
+
+               # Optionally, do the same in the following:
+               [optional] aecp HOWTO/change.txt
+               [optional] aecp HOWTO/release.txt
+               [optional] aecp debian/rt.postinst
+
+               [optional] vi HOWTO/change.txt
+               [optional] vi HOWTO/release.txt
+               [optional] vi debian/rt.postinst
+
+               aeb
+
+               aet -reg
+
+               aed
+
+               aede
+
+               etc.
+
+
+       Read through the FAQ for any updates
+
+       Test downloading from the web site download page
+
+
+       In the Bugs Tracker, add a Group for the new release (0.05)
+
+       Announce to the following mailing lists (template below):
+
+               rt-announce@lists.fsck.com
+
+
+       Notify www.cmtoday.com/contribute.html
+
+                [This guy wants an announcement no more frequently than
+                once a month, so save it for a future release if it's
+                been too soon since the previous one.]
+
+       Notify freshmeat.net
+
+                [Wait until the morning so the announcement hits the
+                main freshmeat.net page while people in the U.S. are
+                awake and working]
+
+
+
+
+=======================
+
+Template release announcement:
+
+
+
+Version 2.1.XXX of rt has been released and is available for download
+from the rt web site:
+
+        http://bestpractical.com/rt/
+
+
+
+WHAT'S NEW IN THIS RELEASE?
+
+Version 2.1.XXX of rt contains the following important changes:
+
+  - XXX
+
+For a complete list of changes in version 2.1.XXX, see the CHANGES.txt
+file in the release itself.
+
+
+WHAT IS RT? 
+
+        FILL THIS IN
diff --git a/rt/HOWTO/version-control.txt b/rt/HOWTO/version-control.txt
new file mode 100644 (file)
index 0000000..06babfd
--- /dev/null
@@ -0,0 +1,41 @@
+Using Aegis for RT development
+
+   1. The main line of RT development will be under the control
+      of the Aegis change management system, as administered by
+       Best Practical Solutions, LLC
+
+   2. We will use aedist to generate change sets for each change
+      checked in to the main Aegis repository. These change sets will be
+      either distributed by a mailing list or made available via the web,
+      or both.
+
+   3. Remote developers using Aegis will send aedist output for
+      their changes to rt-patches@bestpractical.com for review and
+      integration.
+
+   4. The aedist output should be sent to rt-patches@bestpractical.com
+      after the change has completed its local aede, but before aerpass.
+
+   5. If the change is rejected, the developer can aedeu to reopen
+      the change and fix whatever problems caused the review to not pass.
+
+   6. A baseline snapshot (aedist -bl) of the main Aegis repository
+      will be generated at least daily and made available via http
+      to provide a central location for synchronizing remote Aegis
+      repositories.
+
+   7. Changes to the main Aegis repository will also be propagated
+      automatically to the tracking CVS repository.
+
+Using CVS for RT development
+
+   1. CVS is accessed via anonymous cvs with the following CVSROOT:
+
+      :pserver:anoncvs@cvs.fsck.com:/raid/cvsroot/rt-2-1
+
+   2. Remote developers using CVS will send patches (cvs -diff
+      output) to rt-patches@bestpractical.com  for integration into the
+      main Aegis repository. This allows anonymous CVS access to be used
+      for RT development by developers who are unable to use Aegis.
+
+
index fe01b71..6447221 100644 (file)
@@ -1,18 +1,49 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/Makefile,v 1.1 2002-08-12 06:17:06 ivan Exp $
-# RT is Copyright 1996-2002 Jesse Vincent <jesse@bestpractical.com>
-# It is distributed under the terms of the GNU General Public License, version 2
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+
+#
+# DO NOT HAND-EDIT the file named 'Makefile'. This file is autogenerated.
+# Have a look at "configure" and "Makefile.in" instead
+#
+
 
 PERL                   =       /usr/bin/perl
 
-RT_VERSION_MAJOR       =       2
-RT_VERSION_MINOR       =       0
-RT_VERSION_PATCH       =       14
+CONFIG_FILE_PATH       =       /opt/rt3/etc
+CONFIG_FILE            =       $(CONFIG_FILE_PATH)/RT_Config.pm
+SITE_CONFIG_FILE               =       $(CONFIG_FILE_PATH)/RT_SiteConfig.pm
 
 
+RT_VERSION_MAJOR       =       3
+RT_VERSION_MINOR       =       0
+RT_VERSION_PATCH       =       4
+
 RT_VERSION =   $(RT_VERSION_MAJOR).$(RT_VERSION_MINOR).$(RT_VERSION_PATCH)
 TAG       =    rt-$(RT_VERSION_MAJOR)-$(RT_VERSION_MINOR)-$(RT_VERSION_PATCH)
 
-BRANCH                 =       HEAD
 
 # This is the group that all of the installed files will be chgrp'ed to.
 RTGROUP                        =       rt
@@ -27,7 +58,8 @@ LIBS_OWNER            =       root
 # Group that should own all of RT's libraries, generally root.
 LIBS_GROUP             =       bin
 
-
+WEB_USER               =       www
+WEB_GROUP              =       www
 
 # {{{ Files and directories 
 
@@ -37,33 +69,22 @@ LIBS_GROUP          =       bin
 DESTDIR                        =       
 
 
-# RT_PATH is the name of the directory you want make to install RT in
-# RT must be installed in its own directory (don't set this to /usr/local)
-
-RT_PATH                        =       /opt/rt2
-
-# The rest of these paths are all configurable, but you probably don't want to 
-# put them elsewhere
-
-RT_LIB_PATH            =       $(RT_PATH)/lib
-RT_ETC_PATH            =       $(RT_PATH)/etc
-RT_CONFIG_PATH         =       $(RT_ETC_PATH)
-RT_BIN_PATH            =       $(RT_PATH)/bin
-RT_MAN_PATH            =       $(RT_PATH)/man
-MASON_HTML_PATH                =       $(RT_PATH)/WebRT/html
-
-
-# RT allows sites to overlay the default web ui with 
-# local customizations Those files can be placed in MASON_LOCAL_HTML_PATH
-
-MASON_LOCAL_HTML_PATH  =       $(RT_PATH)/local/WebRT/html
-
-# RT needs to be able to write to MASON_DATA_PATH and MASON_SESSION_PATH
-# RT will create and chown these directories. Don't just set them to /tmp
-MASON_DATA_PATH                =       $(RT_PATH)/WebRT/data
-MASON_SESSION_PATH     =       $(RT_PATH)/WebRT/sessiondata
-
-RT_LOG_PATH             =       /tmp
+RT_PATH                        =       /opt/rt3
+RT_ETC_PATH            =       /opt/rt3/etc
+RT_BIN_PATH            =       /opt/rt3/bin
+RT_SBIN_PATH           =       /opt/rt3/sbin
+RT_LIB_PATH            =       /opt/rt3/lib
+RT_MAN_PATH            =       /opt/rt3/man
+RT_VAR_PATH            =       /opt/rt3/var
+RT_DOC_PATH            =       /opt/rt3/share/doc
+RT_LOCAL_PATH          =       /opt/rt3/local
+LOCAL_ETC_PATH         =       /opt/rt3/local/etc
+LOCAL_LEXICON_PATH     =       /opt/rt3/local/po
+MASON_HTML_PATH                =       /opt/rt3/share/html
+MASON_LOCAL_HTML_PATH  =       /opt/rt3/local/html
+MASON_DATA_PATH                =       /opt/rt3/var/mason_data
+MASON_SESSION_PATH     =       /opt/rt3/var/session_data
+RT_LOG_PATH        =       /opt/rt3/var/log
 
 # RT_READABLE_DIR_MODE is the mode of directories that are generally meant
 # to be accessable
@@ -71,25 +92,33 @@ RT_READABLE_DIR_MODE        =       0755
 
 
 
-# The location of your rt configuration file
-RT_CONFIG              =       $(RT_CONFIG_PATH)/config.pm
+
+# {{{ all these define the places that RT's binaries should get installed
 
 # RT_MODPERL_HANDLER is the mason handler script for mod_perl
 RT_MODPERL_HANDLER     =       $(RT_BIN_PATH)/webmux.pl
-
 # RT_FASTCGI_HANDLER is the mason handler script for FastCGI
-# THIS HANDLER IS NOT CURRENTLY SUPPORTED
 RT_FASTCGI_HANDLER     =       $(RT_BIN_PATH)/mason_handler.fcgi
+# RT_WIN32_FASTCGI_HANDLER is the mason handler script for FastCGI
+RT_WIN32_FASTCGI_HANDLER       =       $(RT_BIN_PATH)/mason_handler.svc
+# RT's admin CLI
+RT_CLI_ADMIN_BIN       =       $(RT_BIN_PATH)/rtadmin
+# RT's mail gateway
+RT_MAILGATE_BIN                =       $(RT_BIN_PATH)/rt-mailgate
+# RT's cron tool
+RT_CRON_BIN            =       $(RT_BIN_PATH)/rt-crontool
 
-# RT_SPEEDYCGI_HANDLER is the mason handler script for SpeedyCGI
-# THIS HANDLER IS NOT CURRENTLY SUPPORTED
-RT_SPEEDYCGI_HANDLER   =       $(RT_BIN_PATH)/mason_handler.scgi
+# }}}
 
-# The following are the names of the various binaries which make up RT 
+SETGID_BINARIES                =       $(DESTDIR)/$(RT_FASTCGI_HANDLER) \
+                               $(DESTDIR)/$(RT_WIN32_FASTCGI_HANDLER)
+
+BINARIES               =       $(DESTDIR)/$(RT_MODPERL_HANDLER) \
+                               $(DESTDIR)/$(RT_MAILGATE_BIN) \
+                               $(DESTDIR)/$(RT_CRON_BIN) \
+                               $(SETGID_BINARIES)
+SYSTEM_BINARIES                =       $(DESTDIR)/$(RT_SBIN_PATH)/
 
-RT_CLI_BIN             =       $(RT_BIN_PATH)/rt
-RT_CLI_ADMIN_BIN       =       $(RT_BIN_PATH)/rtadmin
-RT_MAILGATE_BIN                =       $(RT_BIN_PATH)/rt-mailgate
 
 # }}}
 
@@ -99,34 +128,19 @@ RT_MAILGATE_BIN            =       $(RT_BIN_PATH)/rt-mailgate
 # DB_TYPE defines what sort of database RT trys to talk to
 # "mysql" is known to work.
 # "Pg" is known to work
-# "Oracle" is in the early stages of working.
 
 DB_TYPE                        =       mysql
 
-# DB_HOME is where the Database's commandline tools live.  $DB_HOME/bin
-# should contain the binaries themselves, e.g. if "which mysql" gives
-# "/usr/local/mysql/bin/mysql", $DB_HOME should be "/usr/local/mysql"
-
-DB_HOME                        = /usr
-
 # Set DBA to the name of a unix account with the proper permissions and 
-# environment to run your commandline SQL tools
+# environment to run your commandline SQL sbin
 
 # Set DB_DBA to the name of a DB user with permission to create new databases 
-# Set DB_DBA_PASSWORD to that user's password (if you don't, you'll be prompted
-# later)
 
 # For mysql, you probably want 'root'
 # For Pg, you probably want 'postgres' 
 # For oracle, you want 'system'
 
 DB_DBA                 =       root
-DB_DBA_PASSWORD                =       
-#
-# Set this to the Fully Qualified Domain Name of your database server.
-# If the database is local, rather than on a remote host, using "localhost" 
-# will greatly enhance performance.
 
 DB_HOST                        =       localhost
 
@@ -136,6 +150,9 @@ DB_HOST                     =       localhost
 
 DB_PORT                        =       
 
+
+
+
 #
 # Set this to the canonical name of the interface RT will be talking to the 
 # database on.  If you said that the RT_DB_HOST above was "localhost," this 
@@ -149,81 +166,72 @@ DB_RT_HOST                =       localhost
 # set this to the name you want to give to the RT database in 
 # your database server. For Oracle, this should be the name of your sid
 
-DB_DATABASE            =       rt2
-
-# Set this to the name of the rt database user
-
+DB_DATABASE            =       rt3
 DB_RT_USER             =       rt_user
-
-# Set this to the password used by the rt database user
-# *** Change This Before Installation***
-
 DB_RT_PASS             =       rt_pass
 
 # }}}
 
-# {{{ Web configuration 
-
-# The user your webserver runs as. needed so that webrt can cache mason
-# objectcode
 
-WEB_USER               =       www
-WEB_GROUP              =       rt
-
-# }}}
-
-
-####################################################################
-# No user servicable parts below this line.  Frob at your own risk #
 ####################################################################
 
+all: default
+
 default:
        @echo "Please read RT's readme before installing. Not doing so could"
        @echo "be dangerous."
 
-install: dirs initialize.$(DB_TYPE) upgrade insert instruct
+
 
 instruct:
        @echo "Congratulations. RT has been installed. "
-       @echo "You must now configure it by editing $(RT_CONFIG)."
-       @echo "From here on in, you should refer to the users guide."
+       @echo ""
+       @echo ""
+       @echo "You must now configure RT by editing $(SITE_CONFIG_FILE)."
+       @echo ""
+       @echo "(You will definitely need to set RT's database password before continuing."
+       @echo " Not doing so could be very dangerous)"
+       @echo ""
+       @echo "After that, you need to initialize RT's database by running" 
+       @echo " 'make initialize-database'"
 
+#      @echo " or by executing "       
+#      @echo " '$(RT_SBIN_PATH)/rt-setup-database --action init \ "
+#      @echo "     --dba $(DB_DBA) --prompt-for-dba-password'"
 
-insert: insert-install
-       $(PERL) -I$(DESTDIR)/$(RT_ETC_PATH) -I$(DESTDIR)/$(RT_LIB_PATH) $(DESTDIR)/$(RT_ETC_PATH)/insertdata
 
-upgrade: dirs config-replace upgrade-noclobber  upgrade-instruct
 
 upgrade-instruct: 
        @echo "Congratulations. RT has been upgraded. You should now check-over"
-       @echo "$(RT_CONFIG) for any necessary site customization. Additionally,"
+       @echo "$(CONFIG_FILE) for any necessary site customization. Additionally,"
        @echo "you should update RT's system database objects by running "
-       @echo "    $(RT_ETC_PATH)/insertdata <version>"
-       @echo "where <version> is the version of RT you're upgrading from."
+       @echo "   ls etc/upgrade"
+       @echo "For each file in that directory whose name is greater than"
+       @echo "your previously installed RT version, run:"
+       @echo "    $(RT_SBIN_PATH)/rt-setup-database --action insert --datafile etc/upgrade/<version>"
 
-upgrade-noclobber: insert-install libs-install html-install bin-install nondestruct
 
-nondestruct: fixperms
+upgrade: dirs upgrade-noclobber upgrade-instruct
 
-testdeps:
-       $(PERL) ./tools/testdeps -warn $(DB_TYPE)
+upgrade-noclobber: config-install libs-install html-install bin-install local-install doc-install fixperms
 
-fixdeps:
-       $(PERL) ./tools/testdeps -fix $(DB_TYPE)
 
+# {{{ dependencies
+testdeps:
+       $(PERL) ./sbin/rt-test-dependencies --with-$(DB_TYPE)
 
+fixdeps:
+       $(PERL) ./sbin/rt-test-dependencies --install --with-$(DB_TYPE)
 
-all:
-       @echo "Read the readme."
+#}}}
 
+# {{{ fixperms
 fixperms:
        # Make the libraries readable
-       chmod -R $(RT_READABLE_DIR_MODE) $(DESTDIR)/$(RT_PATH)
+       chmod $(RT_READABLE_DIR_MODE) $(DESTDIR)/$(RT_PATH)
        chown -R $(LIBS_OWNER) $(DESTDIR)/$(RT_LIB_PATH)
        chgrp -R $(LIBS_GROUP) $(DESTDIR)/$(RT_LIB_PATH)
-
-       chown -R $(BIN_OWNER) $(DESTDIR)/$(RT_BIN_PATH)
-       chgrp -R $(RTGROUP) $(DESTDIR)/$(RT_BIN_PATH)
+       chmod -R  u+rwX,go-w,go+rX      $(DESTDIR)/$(RT_LIB_PATH)
 
 
        chmod $(RT_READABLE_DIR_MODE) $(DESTDIR)/$(RT_BIN_PATH)
@@ -237,36 +245,19 @@ fixperms:
        chown -R $(BIN_OWNER) $(DESTDIR)/$(RT_ETC_PATH)
        chgrp -R $(RTGROUP) $(DESTDIR)/$(RT_ETC_PATH)
 
-       chmod 0550 $(DESTDIR)/$(RT_CONFIG)
+       chmod 0550 $(DESTDIR)/$(CONFIG_FILE)
+       chmod 0550 $(DESTDIR)/$(SITE_CONFIG_FILE)
 
        # Make the interfaces executable and setgid rt
-       chown $(BIN_OWNER) $(DESTDIR)/$(RT_MAILGATE_BIN) \
-                       $(DESTDIR)/$(RT_FASTCGI_HANDLER) \
-                       $(DESTDIR)/$(RT_SPEEDYCGI_HANDLER) \
-                       $(DESTDIR)/$(RT_CLI_BIN) \
-                       $(DESTDIR)/$(RT_CLI_ADMIN_BIN)
-
-       chgrp $(RTGROUP) $(DESTDIR)/$(RT_MAILGATE_BIN) \
-                       $(DESTDIR)/$(RT_FASTCGI_HANDLER) \
-                       $(DESTDIR)/$(RT_SPEEDYCGI_HANDLER) \
-                       $(DESTDIR)/$(RT_CLI_BIN) \
-                       $(DESTDIR)/$(RT_CLI_ADMIN_BIN)
-
-       chmod 0755      $(DESTDIR)/$(RT_MAILGATE_BIN) \
-                       $(DESTDIR)/$(RT_FASTCGI_HANDLER) \
-                       $(DESTDIR)/$(RT_SPEEDYCGI_HANDLER) \
-                       $(DESTDIR)/$(RT_CLI_BIN) \
-                       $(DESTDIR)/$(RT_CLI_ADMIN_BIN)
-
-       chmod g+s       $(DESTDIR)/$(RT_MAILGATE_BIN) \
-                       $(DESTDIR)/$(RT_FASTCGI_HANDLER) \
-                       $(DESTDIR)/$(RT_SPEEDYCGI_HANDLER) \
-                       $(DESTDIR)/$(RT_CLI_BIN) \
-                       $(DESTDIR)/$(RT_CLI_ADMIN_BIN)
+       chown $(BIN_OWNER) $(BINARIES)
+       chgrp $(RTGROUP) $(BINARIES)
+       chmod 0755  $(BINARIES)
+       chmod g+s $(SETGID_BINARIES)
 
        # Make the web ui readable by all. 
        chmod -R  u+rwX,go-w,go+rX      $(DESTDIR)/$(MASON_HTML_PATH) \
-                                       $(DESTDIR)/$(MASON_LOCAL_HTML_PATH)
+                                       $(DESTDIR)/$(MASON_LOCAL_HTML_PATH) \
+                                       $(DESTDIR)/$(LOCAL_LEXICON_PATH)
        chown -R $(LIBS_OWNER)  $(DESTDIR)/$(MASON_HTML_PATH) \
                                $(DESTDIR)/$(MASON_LOCAL_HTML_PATH)
        chgrp -R $(LIBS_GROUP)  $(DESTDIR)/$(MASON_HTML_PATH) \
@@ -279,140 +270,216 @@ fixperms:
                                $(DESTDIR)/$(MASON_SESSION_PATH)
        chgrp -R $(WEB_GROUP)   $(DESTDIR)/$(MASON_DATA_PATH) \
                                $(DESTDIR)/$(MASON_SESSION_PATH)
+# }}}
+
+fixperms-nosetgid: fixperms
+       @echo "You should never be running RT this way. it's unsafe"
+       chmod 0555 $(SETGID_BINARIES)
+       chmod 0555 $(DESTDIR)/$(CONFIG_FILE)
+       chmod 0555 $(DESTDIR)/$(SITE_CONFIG_FILE)
+
+# {{{ dirs
 dirs:
-       mkdir -p $(DESTDIR)/$(RT_BIN_PATH)
+       mkdir -p $(DESTDIR)/$(RT_LOG_PATH)
        mkdir -p $(DESTDIR)/$(MASON_DATA_PATH)
+       mkdir -p $(DESTDIR)/$(MASON_DATA_PATH)/cache
+       mkdir -p $(DESTDIR)/$(MASON_DATA_PATH)/etc
+       mkdir -p $(DESTDIR)/$(MASON_DATA_PATH)/obj
        mkdir -p $(DESTDIR)/$(MASON_SESSION_PATH)
-       mkdir -p $(DESTDIR)/$(RT_ETC_PATH)
-       mkdir -p $(DESTDIR)/$(RT_LIB_PATH)
        mkdir -p $(DESTDIR)/$(MASON_HTML_PATH)
        mkdir -p $(DESTDIR)/$(MASON_LOCAL_HTML_PATH)
+       mkdir -p $(DESTDIR)/$(LOCAL_ETC_PATH)
+       mkdir -p $(DESTDIR)/$(LOCAL_LEXICON_PATH)
+# }}}
 
-libs-install: 
-       [ -d $(DESTDIR)/$(RT_LIB_PATH) ] || mkdir $(DESTDIR)/$(RT_LIB_PATH)
-       chown -R $(LIBS_OWNER) $(DESTDIR)/$(RT_LIB_PATH)
-       chgrp -R $(LIBS_GROUP) $(DESTDIR)/$(RT_LIB_PATH)
-       chmod -R $(RT_READABLE_DIR_MODE) $(DESTDIR)/$(RT_LIB_PATH)
-       ( cd ./lib; \
-         $(PERL) Makefile.PL INSTALLSITELIB=$(DESTDIR)/$(RT_LIB_PATH) \
-                             INSTALLMAN1DIR=$(DESTDIR)/$(RT_MAN_PATH)/man1 \
-                             INSTALLMAN3DIR=$(DESTDIR)/$(RT_MAN_PATH)/man3 \
-           && make \
-           && make test \
-           && $(PERL) -p -i -e " s'!!RT_VERSION!!'$(RT_VERSION)'g;" blib/lib/RT.pm ;\
-           make install \
-                          INSTALLSITEMAN1DIR=$(DESTDIR)/$(RT_MAN_PATH)/man1 \
-                          INSTALLSITEMAN3DIR=$(DESTDIR)/$(RT_MAN_PATH)/man3 \
-       )
+install: config-install dirs files-install fixperms instruct
 
-html-install:
-       cp -rp ./webrt/* $(DESTDIR)/$(MASON_HTML_PATH)
+files-install: libs-install etc-install bin-install sbin-install html-install local-install doc-install
+
+config-install:
+       mkdir -p $(DESTDIR)/$(CONFIG_FILE_PATH) 
+       cp etc/RT_Config.pm $(DESTDIR)/$(CONFIG_FILE)
+       [ -f $(DESTDIR)/$(SITE_CONFIG_FILE) ] || cp etc/RT_SiteConfig.pm $(DESTDIR)/$(SITE_CONFIG_FILE) 
+
+       chgrp $(RTGROUP) $(DESTDIR)/$(CONFIG_FILE)
+       chown $(BIN_OWNER) $(DESTDIR)/$(CONFIG_FILE)
 
+       chgrp $(RTGROUP) $(DESTDIR)/$(SITE_CONFIG_FILE)
+       chown $(BIN_OWNER) $(DESTDIR)/$(SITE_CONFIG_FILE)
 
+       @echo "Installed configuration. about to install rt in  $(RT_PATH)"
 
-genschema:
-       $(PERL) tools/initdb '$(DB_TYPE)' '$(DB_HOME)' '$(DB_HOST)' '$(DB_PORT)' '$(DB_DBA)' '$(DB_DATABASE)' generate
+test: 
+       $(PERL) -Ilib lib/t/00smoke.t
 
+regression-nosetgid-quiet: config-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db  testify-pods fixperms-nosetgid apachectl
+       $(PERL) sbin/regression_harness
 
-initialize.Pg: createdb initdb.dba acls 
+regression-nosetgid: config-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db  testify-pods fixperms-nosetgid apachectl
+       $(PERL) lib/t/02regression.t
 
-initialize.mysql: createdb acls initdb.rtuser
+regression: config-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db  testify-pods apachectl
+       $(PERL) lib/t/02regression.t
 
-initialize.Oracle: acls initdb.rtuser
+regression-quiet:
+       $(PERL) sbin/regression_harness
 
-acls:
-       cp etc/acl.$(DB_TYPE) '$(DESTDIR)/$(RT_ETC_PATH)/acl.$(DB_TYPE)'
-       $(PERL) -p -i -e " s'!!DB_TYPE!!'"$(DB_TYPE)"'g;\
-                               s'!!DB_HOST!!'"$(DB_HOST)"'g;\
-                               s'!!DB_RT_PASS!!'"$(DB_RT_PASS)"'g;\
-                               s'!!DB_RT_HOST!!'"$(DB_RT_HOST)"'g;\
-                               s'!!DB_RT_USER!!'"$(DB_RT_USER)"'g;\
-                               s'!!DB_DATABASE!!'"$(DB_DATABASE)"'g;" $(DESTDIR)/$(RT_ETC_PATH)/acl.$(DB_TYPE)
-       bin/initacls.$(DB_TYPE) '$(DB_HOME)' '$(DB_HOST)' '$(DB_PORT)' '$(DB_DBA)' '$(DB_DBA_PASSWORD)' '$(DB_DATABASE)' '$(DESTDIR)/$(RT_ETC_PATH)/acl.$(DB_TYPE)' 
+regression-instruct:
+       @echo "About to wipe your database for a regression test. ABORT NOW with Control-C"
 
 
+# {{{ database-installation
+
+regression-reset-db:
+       $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action drop --dba $(DB_DBA) --dba-password ''
+       $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action init --dba $(DB_DBA) --dba-password ''
+
+initialize-database: 
+       $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action init --dba $(DB_DBA) --prompt-for-dba-password
 
 dropdb: 
-       $(PERL) tools/initdb '$(DB_TYPE)' '$(DB_HOME)' '$(DB_HOST)' '$(DB_PORT)' '$(DB_DBA)' '$(DB_DATABASE)' drop
+       $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action drop --dba $(DB_DBA) --prompt-for-dba-password
+
+insert-approval-data: 
+       $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/insert_approval_scrips
+# }}}
+
+# {{{ libs-install
+libs-install: 
+       [ -d $(DESTDIR)/$(RT_LIB_PATH) ] || mkdir $(DESTDIR)/$(RT_LIB_PATH)
+       -cp -rp lib/* $(DESTDIR)/$(RT_LIB_PATH)
+# }}}
+
+# {{{ html-install
+html-install:
+       [ -d $(DESTDIR)/$(MASON_HTML_PATH) ] || mkdir $(DESTDIR)/$(MASON_HTML_PATH)
+       -cp -rp ./html/* $(DESTDIR)/$(MASON_HTML_PATH)
+# }}}
+
+# {{{ doc-install
+doc-install:
+       # RT 3.0.0 - RT 3.0.2 would accidentally create a file instead of a dir
+       -[ -f $(DESTDIR)/$(RT_DOC_PATH) ] && rm $(DESTDIR)/$(RT_DOC_PATH) 
+       [ -d $(DESTDIR)/$(RT_DOC_PATH) ] || mkdir $(DESTDIR)/$(RT_DOC_PATH)
+       -cp -rp ./README $(DESTDIR)/$(RT_DOC_PATH)
+# }}}
 
+# {{{ etc-install
 
-createdb: 
-       $(PERL) tools/initdb '$(DB_TYPE)' '$(DB_HOME)' '$(DB_HOST)' '$(DB_PORT)' '$(DB_DBA)' '$(DB_DATABASE)' create
-initdb.dba:
-       $(PERL) tools/initdb '$(DB_TYPE)' '$(DB_HOME)' '$(DB_HOST)' '$(DB_PORT)' '$(DB_DBA)' '$(DB_DATABASE)' insert
+etc-install:
+       mkdir -p $(DESTDIR)/$(RT_ETC_PATH)
+       -cp -rp \
+               etc/acl.* \
+               etc/initialdata \
+               etc/schema.* \
+               $(DESTDIR)/$(RT_ETC_PATH)
+# }}}
 
-initdb.rtuser:
-       $(PERL) tools/initdb '$(DB_TYPE)' '$(DB_HOME)' '$(DB_HOST)' '$(DB_PORT)' '$(DB_RT_USER)' '$(DB_DATABASE)' insert
+# {{{ sbin-install
 
+sbin-install:
+       mkdir -p $(DESTDIR)/$(RT_SBIN_PATH)
+       chmod +x sbin/rt-setup-database \
+               sbin/rt-test-dependencies
+       -cp -rp \
+               sbin/rt-setup-database \
+               sbin/rt-test-dependencies \
+               $(DESTDIR)/$(RT_SBIN_PATH)
 
+# }}}
 
-insert-install:
-       cp -rp ./tools/insertdata \
-                $(DESTDIR)/$(RT_ETC_PATH)
-       $(PERL) -p -i -e " s'!!RT_ETC_PATH!!'$(RT_ETC_PATH)'g;\
-                          s'!!RT_LIB_PATH!!'$(RT_LIB_PATH)'g;"\
-               $(DESTDIR)/$(RT_ETC_PATH)/insertdata
+# {{{ bin-install
 
 bin-install:
-       cp -p ./bin/webmux.pl $(DESTDIR)/$(RT_MODPERL_HANDLER)
-       cp -p ./bin/rt-mailgate $(DESTDIR)/$(RT_MAILGATE_BIN)
-       cp -p ./bin/rtadmin $(DESTDIR)/$(RT_CLI_ADMIN_BIN)
-       cp -p ./bin/rt $(DESTDIR)/$(RT_CLI_BIN)
-       cp -p ./bin/mason_handler.fcgi $(DESTDIR)/$(RT_FASTCGI_HANDLER)
-       cp -p ./bin/mason_handler.scgi $(DESTDIR)/$(RT_SPEEDYCGI_HANDLER)
-
-       $(PERL) -p -i -e "s'!!RT_PATH!!'"$(RT_PATH)"'g;\
-                               s'!!PERL!!'"$(PERL)"'g;\
-                               s'!!RT_VERSION!!'"$(RT_VERSION)"'g;\
-                               s'!!RT_ETC_PATH!!'"$(RT_CONFIG_PATH)"'g;\
-                               s'!!RT_LIB_PATH!!'"$(RT_LIB_PATH)"'g;"\
-               $(DESTDIR)/$(RT_MODPERL_HANDLER) \
-               $(DESTDIR)/$(RT_FASTCGI_HANDLER) \
-               $(DESTDIR)/$(RT_SPEEDYCGI_HANDLER) \
-               $(DESTDIR)/$(RT_CLI_BIN) \
-               $(DESTDIR)/$(RT_CLI_ADMIN_BIN) \
-               $(DESTDIR)/$(RT_MAILGATE_BIN)
-
-
-config-replace:
-       -[ -f $(DESTDIR)/$(RT_CONFIG) ] && \
-               mv $(DESTDIR)/$(RT_CONFIG) $(DESTDIR)/$(RT_CONFIG).old && \
-               chmod 000 $(DESTDIR)/$(RT_CONFIG).old
-       cp -rp ./etc/config.pm $(DESTDIR)/$(RT_CONFIG)
-       $(PERL) -p -i -e "\
-       s'!!DB_TYPE!!'"$(DB_TYPE)"'g;\
-       s'!!DB_HOST!!'"$(DB_HOST)"'g;\
-       s'!!DB_PORT!!'"$(DB_PORT)"'g;\
-       s'!!DB_RT_PASS!!'"$(DB_RT_PASS)"'g;\
-       s'!!DB_RT_USER!!'"$(DB_RT_USER)"'g;\
-       s'!!DB_DATABASE!!'"$(DB_DATABASE)"'g;\
-       s'!!MASON_HTML_PATH!!'"$(MASON_HTML_PATH)"'g;\
-       s'!!MASON_LOCAL_HTML_PATH!!'"$(MASON_LOCAL_HTML_PATH)"'g;\
-       s'!!MASON_SESSION_PATH!!'"$(MASON_SESSION_PATH)"'g;\
-       s'!!MASON_DATA_PATH!!'"$(MASON_DATA_PATH)"'g;\
-       s'!!RT_LOG_PATH!!'"$(RT_LOG_PATH)"'g;\
-       s'!!RT_VERSION!!'"$(RT_VERSION)"'g;\
-       " $(DESTDIR)/$(RT_CONFIG)
+       mkdir -p $(DESTDIR)/$(RT_BIN_PATH)
+       chmod +x bin/rt-mailgate \
+               bin/rt-crontool
+       -cp -rp \
+               bin/rt-mailgate \
+               bin/mason_handler.fcgi \
+               bin/mason_handler.svc \
+               bin/webmux.pl \
+               bin/rt-crontool \
+               $(DESTDIR)/$(RT_BIN_PATH)
+# }}}
+
+# {{{ local-install
+local-install:
+       -cp -rp ./local/html/* $(DESTDIR)/$(MASON_LOCAL_HTML_PATH)
+       -cp -rp ./local/po/* $(DESTDIR)/$(LOCAL_LEXICON_PATH)
+       -cp -rp ./local/etc/* $(DESTDIR)/$(LOCAL_ETC_PATH)
+# }}}
+
+# {{{ Best Practical Build targets -- no user servicable parts inside
+
+
+POD2TEST_EXE = sbin/extract_pod_tests
+
+testify-pods:
+       [ -d lib/t/autogen ] || mkdir lib/t/autogen
+       find lib -name \*pm |grep -v \*.in |xargs -n 1 $(PERL) $(POD2TEST_EXE)
+       find bin -type f |grep -v \~ | grep -v "\.in" | xargs -n 1 $(PERL) $(POD2TEST_EXE)
+
 
 
+regenerate-catalogs:
+       $(PERL) sbin/extract-message-catalog
+
+license-tag:
+       $(PERL) sbin/license_tag
+
+factory: initialize-database
+       cd lib; $(PERL) ../sbin/factory  $(DB_DATABASE) RT
+
 commit:
-       cvs commit
+       aegis -build ; aegis -diff ; aegis -test; aegis -develop_end
+
+integrate:
+       aegis -integrate_begin; aegis -build; aegis -diff; aegis -test ; aegis -integrate_pass
+
+predist: commit tag-and-tar
+
+tag-and-release-baseline:
+       aegis -cp -ind Makefile -output /tmp/Makefile.tagandrelease; \
+       $(MAKE) -f /tmp/Makefile.tagandrelease tag-and-release-never-by-hand
 
-predist: commit
-       cvs tag -r $(BRANCH) -F $(TAG)
+
+# Running this target in a working directory is 
+# WRONG WRONG WRONG.
+# it will tag the current baseline with the version of RT defined 
+# in the currently-being-worked-on makefile. which is wrong.
+#  you want tag-and-release-baseline
+
+tag-and-release-never-by-hand:
+       aegis --delta-name $(TAG)
        rm -rf /tmp/$(TAG)
-       cvs co -d /tmp/$(TAG) -r $(TAG) rt
-       cd /tmp/$(TAG); chmod 600 Makefile; /usr/local/bin/cvs2cl.pl \
-               --no-wrap --separate-header \
-               --window 120
+       mkdir /tmp/$(TAG)
+       cd /tmp/$(TAG); \
+               aegis -cp -ind -delta $(TAG) . ;\
+               make reconfigure;\
+               chmod 600 Makefile;\
+               aegis --report --project rt.$(RT_VERSION_MAJOR) \
+                     --page_width 80 \
+                     --page_length 9999 \
+                     --change $(RT_VERSION_MINOR) --output Changelog Change_Log
+
        cd /tmp; tar czvf /home/ftp/pub/rt/devel/$(TAG).tar.gz $(TAG)/
        chmod 644 /home/ftp/pub/rt/devel/$(TAG).tar.gz
 
-dist: commit predist
-       rm -rf /home/ftp/pub/rt/devel/rt.tar.gz
-       ln -s ./$(TAG).tar.gz /home/ftp/pub/rt/devel/rt.tar.gz
 
+reconfigure:
+       aclocal -I m4
+       autoconf
+       chmod 755 ./configure
+       ./configure
 
 rpm:
        (cd ..; tar czvf /usr/src/redhat/SOURCES/rt.tar.gz rt)
        rpm -ba etc/rt.spec
+
+
+apachectl:
+       apachectl stop
+       sleep 3
+       apachectl start
+# }}}
diff --git a/rt/Makefile.in b/rt/Makefile.in
new file mode 100644 (file)
index 0000000..245ec5e
--- /dev/null
@@ -0,0 +1,485 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+
+#
+# DO NOT HAND-EDIT the file named 'Makefile'. This file is autogenerated.
+# Have a look at "configure" and "Makefile.in" instead
+#
+
+
+PERL                   =       @PERL@
+
+CONFIG_FILE_PATH       =       @CONFIG_FILE_PATH@
+CONFIG_FILE            =       $(CONFIG_FILE_PATH)/RT_Config.pm
+SITE_CONFIG_FILE               =       $(CONFIG_FILE_PATH)/RT_SiteConfig.pm
+
+
+RT_VERSION_MAJOR       =       @RT_VERSION_MAJOR@
+RT_VERSION_MINOR       =       @RT_VERSION_MINOR@
+RT_VERSION_PATCH       =       @RT_VERSION_PATCH@
+
+RT_VERSION =   $(RT_VERSION_MAJOR).$(RT_VERSION_MINOR).$(RT_VERSION_PATCH)
+TAG       =    rt-$(RT_VERSION_MAJOR)-$(RT_VERSION_MINOR)-$(RT_VERSION_PATCH)
+
+
+# This is the group that all of the installed files will be chgrp'ed to.
+RTGROUP                        =       @RTGROUP@
+
+
+# User which should own rt binaries.
+BIN_OWNER              =       @BIN_OWNER@
+
+# User that should own all of RT's libraries, generally root.
+LIBS_OWNER             =       @LIBS_OWNER@
+
+# Group that should own all of RT's libraries, generally root.
+LIBS_GROUP             =       @LIBS_GROUP@
+
+WEB_USER               =       @WEB_USER@
+WEB_GROUP              =       @WEB_GROUP@
+
+# {{{ Files and directories 
+
+# DESTDIR allows you to specify that RT be installed somewhere other than
+# where it will eventually reside
+
+DESTDIR                        =       
+
+
+RT_PATH                        =       @RT_PATH@
+RT_ETC_PATH            =       @RT_ETC_PATH@
+RT_BIN_PATH            =       @RT_BIN_PATH@
+RT_SBIN_PATH           =       @RT_SBIN_PATH@
+RT_LIB_PATH            =       @RT_LIB_PATH@
+RT_MAN_PATH            =       @RT_MAN_PATH@
+RT_VAR_PATH            =       @RT_VAR_PATH@
+RT_DOC_PATH            =       @RT_DOC_PATH@
+RT_LOCAL_PATH          =       @RT_LOCAL_PATH@
+LOCAL_ETC_PATH         =       @LOCAL_ETC_PATH@
+LOCAL_LEXICON_PATH     =       @LOCAL_LEXICON_PATH@
+MASON_HTML_PATH                =       @MASON_HTML_PATH@
+MASON_LOCAL_HTML_PATH  =       @MASON_LOCAL_HTML_PATH@
+MASON_DATA_PATH                =       @MASON_DATA_PATH@
+MASON_SESSION_PATH     =       @MASON_SESSION_PATH@
+RT_LOG_PATH        =       @RT_LOG_PATH@
+
+# RT_READABLE_DIR_MODE is the mode of directories that are generally meant
+# to be accessable
+RT_READABLE_DIR_MODE   =       0755
+
+
+
+
+# {{{ all these define the places that RT's binaries should get installed
+
+# RT_MODPERL_HANDLER is the mason handler script for mod_perl
+RT_MODPERL_HANDLER     =       $(RT_BIN_PATH)/webmux.pl
+# RT_FASTCGI_HANDLER is the mason handler script for FastCGI
+RT_FASTCGI_HANDLER     =       $(RT_BIN_PATH)/mason_handler.fcgi
+# RT_WIN32_FASTCGI_HANDLER is the mason handler script for FastCGI
+RT_WIN32_FASTCGI_HANDLER       =       $(RT_BIN_PATH)/mason_handler.svc
+# RT's admin CLI
+RT_CLI_ADMIN_BIN       =       $(RT_BIN_PATH)/rtadmin
+# RT's mail gateway
+RT_MAILGATE_BIN                =       $(RT_BIN_PATH)/rt-mailgate
+# RT's cron tool
+RT_CRON_BIN            =       $(RT_BIN_PATH)/rt-crontool
+
+# }}}
+
+SETGID_BINARIES                =       $(DESTDIR)/$(RT_FASTCGI_HANDLER) \
+                               $(DESTDIR)/$(RT_WIN32_FASTCGI_HANDLER)
+
+BINARIES               =       $(DESTDIR)/$(RT_MODPERL_HANDLER) \
+                               $(DESTDIR)/$(RT_MAILGATE_BIN) \
+                               $(DESTDIR)/$(RT_CRON_BIN) \
+                               $(SETGID_BINARIES)
+SYSTEM_BINARIES                =       $(DESTDIR)/$(RT_SBIN_PATH)/
+
+
+# }}}
+
+# {{{ Database setup
+
+#
+# DB_TYPE defines what sort of database RT trys to talk to
+# "mysql" is known to work.
+# "Pg" is known to work
+
+DB_TYPE                        =       @DB_TYPE@
+
+# Set DBA to the name of a unix account with the proper permissions and 
+# environment to run your commandline SQL sbin
+
+# Set DB_DBA to the name of a DB user with permission to create new databases 
+
+# For mysql, you probably want 'root'
+# For Pg, you probably want 'postgres' 
+# For oracle, you want 'system'
+
+DB_DBA                 =       @DB_DBA@
+
+DB_HOST                        =       @DB_HOST@
+
+# If you're not running your database server on its default port, 
+# specifiy the port the database server is running on below.
+# It's generally safe to leave this blank 
+
+DB_PORT                        =       @DB_PORT@
+
+
+
+
+#
+# Set this to the canonical name of the interface RT will be talking to the 
+# database on.  If you said that the RT_DB_HOST above was "localhost," this 
+# should be too. This value will be used to grant rt access to the database.
+# If you want to access the RT database from multiple hosts, you'll need
+# to grant those database rights by hand.
+#
+
+DB_RT_HOST             =       @DB_RT_HOST@
+
+# set this to the name you want to give to the RT database in 
+# your database server. For Oracle, this should be the name of your sid
+
+DB_DATABASE            =       @DB_DATABASE@
+DB_RT_USER             =       @DB_RT_USER@
+DB_RT_PASS             =       @DB_RT_PASS@
+
+# }}}
+
+
+####################################################################
+
+all: default
+
+default:
+       @echo "Please read RT's readme before installing. Not doing so could"
+       @echo "be dangerous."
+
+
+
+instruct:
+       @echo "Congratulations. RT has been installed. "
+       @echo ""
+       @echo ""
+       @echo "You must now configure RT by editing $(SITE_CONFIG_FILE)."
+       @echo ""
+       @echo "(You will definitely need to set RT's database password before continuing."
+       @echo " Not doing so could be very dangerous)"
+       @echo ""
+       @echo "After that, you need to initialize RT's database by running" 
+       @echo " 'make initialize-database'"
+
+#      @echo " or by executing "       
+#      @echo " '$(RT_SBIN_PATH)/rt-setup-database --action init \ "
+#      @echo "     --dba $(DB_DBA) --prompt-for-dba-password'"
+
+
+
+upgrade-instruct: 
+       @echo "Congratulations. RT has been upgraded. You should now check-over"
+       @echo "$(CONFIG_FILE) for any necessary site customization. Additionally,"
+       @echo "you should update RT's system database objects by running "
+       @echo "   ls etc/upgrade"
+       @echo "For each file in that directory whose name is greater than"
+       @echo "your previously installed RT version, run:"
+       @echo "    $(RT_SBIN_PATH)/rt-setup-database --action insert --datafile etc/upgrade/<version>"
+
+
+upgrade: dirs upgrade-noclobber upgrade-instruct
+
+upgrade-noclobber: config-install libs-install html-install bin-install local-install doc-install fixperms
+
+
+# {{{ dependencies
+testdeps:
+       $(PERL) ./sbin/rt-test-dependencies --with-$(DB_TYPE)
+
+fixdeps:
+       $(PERL) ./sbin/rt-test-dependencies --install --with-$(DB_TYPE)
+
+#}}}
+
+# {{{ fixperms
+fixperms:
+       # Make the libraries readable
+       chmod $(RT_READABLE_DIR_MODE) $(DESTDIR)/$(RT_PATH)
+       chown -R $(LIBS_OWNER) $(DESTDIR)/$(RT_LIB_PATH)
+       chgrp -R $(LIBS_GROUP) $(DESTDIR)/$(RT_LIB_PATH)
+       chmod -R  u+rwX,go-w,go+rX      $(DESTDIR)/$(RT_LIB_PATH)
+
+
+       chmod $(RT_READABLE_DIR_MODE) $(DESTDIR)/$(RT_BIN_PATH)
+       chmod $(RT_READABLE_DIR_MODE) $(DESTDIR)/$(RT_BIN_PATH) 
+
+       chmod 0755 $(DESTDIR)/$(RT_ETC_PATH)
+       chmod 0500 $(DESTDIR)/$(RT_ETC_PATH)/*
+
+       #TODO: the config file should probably be able to have its
+       # owner set seperately from the binaries.
+       chown -R $(BIN_OWNER) $(DESTDIR)/$(RT_ETC_PATH)
+       chgrp -R $(RTGROUP) $(DESTDIR)/$(RT_ETC_PATH)
+
+       chmod 0550 $(DESTDIR)/$(CONFIG_FILE)
+       chmod 0550 $(DESTDIR)/$(SITE_CONFIG_FILE)
+
+       # Make the interfaces executable and setgid rt
+       chown $(BIN_OWNER) $(BINARIES)
+       chgrp $(RTGROUP) $(BINARIES)
+       chmod 0755  $(BINARIES)
+       chmod g+s $(SETGID_BINARIES)
+
+       # Make the web ui readable by all. 
+       chmod -R  u+rwX,go-w,go+rX      $(DESTDIR)/$(MASON_HTML_PATH) \
+                                       $(DESTDIR)/$(MASON_LOCAL_HTML_PATH) \
+                                       $(DESTDIR)/$(LOCAL_LEXICON_PATH)
+       chown -R $(LIBS_OWNER)  $(DESTDIR)/$(MASON_HTML_PATH) \
+                               $(DESTDIR)/$(MASON_LOCAL_HTML_PATH)
+       chgrp -R $(LIBS_GROUP)  $(DESTDIR)/$(MASON_HTML_PATH) \
+                               $(DESTDIR)/$(MASON_LOCAL_HTML_PATH)
+
+       # Make the web ui's data dir writable
+       chmod 0770      $(DESTDIR)/$(MASON_DATA_PATH) \
+                       $(DESTDIR)/$(MASON_SESSION_PATH)
+       chown -R $(WEB_USER)    $(DESTDIR)/$(MASON_DATA_PATH) \
+                               $(DESTDIR)/$(MASON_SESSION_PATH)
+       chgrp -R $(WEB_GROUP)   $(DESTDIR)/$(MASON_DATA_PATH) \
+                               $(DESTDIR)/$(MASON_SESSION_PATH)
+# }}}
+
+fixperms-nosetgid: fixperms
+       @echo "You should never be running RT this way. it's unsafe"
+       chmod 0555 $(SETGID_BINARIES)
+       chmod 0555 $(DESTDIR)/$(CONFIG_FILE)
+       chmod 0555 $(DESTDIR)/$(SITE_CONFIG_FILE)
+
+# {{{ dirs
+dirs:
+       mkdir -p $(DESTDIR)/$(RT_LOG_PATH)
+       mkdir -p $(DESTDIR)/$(MASON_DATA_PATH)
+       mkdir -p $(DESTDIR)/$(MASON_DATA_PATH)/cache
+       mkdir -p $(DESTDIR)/$(MASON_DATA_PATH)/etc
+       mkdir -p $(DESTDIR)/$(MASON_DATA_PATH)/obj
+       mkdir -p $(DESTDIR)/$(MASON_SESSION_PATH)
+       mkdir -p $(DESTDIR)/$(MASON_HTML_PATH)
+       mkdir -p $(DESTDIR)/$(MASON_LOCAL_HTML_PATH)
+       mkdir -p $(DESTDIR)/$(LOCAL_ETC_PATH)
+       mkdir -p $(DESTDIR)/$(LOCAL_LEXICON_PATH)
+# }}}
+
+install: config-install dirs files-install fixperms instruct
+
+files-install: libs-install etc-install bin-install sbin-install html-install local-install doc-install
+
+config-install:
+       mkdir -p $(DESTDIR)/$(CONFIG_FILE_PATH) 
+       cp etc/RT_Config.pm $(DESTDIR)/$(CONFIG_FILE)
+       [ -f $(DESTDIR)/$(SITE_CONFIG_FILE) ] || cp etc/RT_SiteConfig.pm $(DESTDIR)/$(SITE_CONFIG_FILE) 
+
+       chgrp $(RTGROUP) $(DESTDIR)/$(CONFIG_FILE)
+       chown $(BIN_OWNER) $(DESTDIR)/$(CONFIG_FILE)
+
+       chgrp $(RTGROUP) $(DESTDIR)/$(SITE_CONFIG_FILE)
+       chown $(BIN_OWNER) $(DESTDIR)/$(SITE_CONFIG_FILE)
+
+       @echo "Installed configuration. about to install rt in  $(RT_PATH)"
+
+test: 
+       $(PERL) -Ilib lib/t/00smoke.t
+
+regression-nosetgid-quiet: config-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db  testify-pods fixperms-nosetgid apachectl
+       $(PERL) sbin/regression_harness
+
+regression-nosetgid: config-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db  testify-pods fixperms-nosetgid apachectl
+       $(PERL) lib/t/02regression.t
+
+regression: config-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db  testify-pods apachectl
+       $(PERL) lib/t/02regression.t
+
+regression-quiet:
+       $(PERL) sbin/regression_harness
+
+regression-instruct:
+       @echo "About to wipe your database for a regression test. ABORT NOW with Control-C"
+
+
+# {{{ database-installation
+
+regression-reset-db:
+       $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action drop --dba $(DB_DBA) --dba-password ''
+       $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action init --dba $(DB_DBA) --dba-password ''
+
+initialize-database: 
+       $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action init --dba $(DB_DBA) --prompt-for-dba-password
+
+dropdb: 
+       $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action drop --dba $(DB_DBA) --prompt-for-dba-password
+
+insert-approval-data: 
+       $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/insert_approval_scrips
+# }}}
+
+# {{{ libs-install
+libs-install: 
+       [ -d $(DESTDIR)/$(RT_LIB_PATH) ] || mkdir $(DESTDIR)/$(RT_LIB_PATH)
+       -cp -rp lib/* $(DESTDIR)/$(RT_LIB_PATH)
+# }}}
+
+# {{{ html-install
+html-install:
+       [ -d $(DESTDIR)/$(MASON_HTML_PATH) ] || mkdir $(DESTDIR)/$(MASON_HTML_PATH)
+       -cp -rp ./html/* $(DESTDIR)/$(MASON_HTML_PATH)
+# }}}
+
+# {{{ doc-install
+doc-install:
+       # RT 3.0.0 - RT 3.0.2 would accidentally create a file instead of a dir
+       -[ -f $(DESTDIR)/$(RT_DOC_PATH) ] && rm $(DESTDIR)/$(RT_DOC_PATH) 
+       [ -d $(DESTDIR)/$(RT_DOC_PATH) ] || mkdir $(DESTDIR)/$(RT_DOC_PATH)
+       -cp -rp ./README $(DESTDIR)/$(RT_DOC_PATH)
+# }}}
+
+# {{{ etc-install
+
+etc-install:
+       mkdir -p $(DESTDIR)/$(RT_ETC_PATH)
+       -cp -rp \
+               etc/acl.* \
+               etc/initialdata \
+               etc/schema.* \
+               $(DESTDIR)/$(RT_ETC_PATH)
+# }}}
+
+# {{{ sbin-install
+
+sbin-install:
+       mkdir -p $(DESTDIR)/$(RT_SBIN_PATH)
+       chmod +x sbin/rt-setup-database \
+               sbin/rt-test-dependencies
+       -cp -rp \
+               sbin/rt-setup-database \
+               sbin/rt-test-dependencies \
+               $(DESTDIR)/$(RT_SBIN_PATH)
+
+# }}}
+
+# {{{ bin-install
+
+bin-install:
+       mkdir -p $(DESTDIR)/$(RT_BIN_PATH)
+       chmod +x bin/rt-mailgate \
+               bin/rt-crontool
+       -cp -rp \
+               bin/rt-mailgate \
+               bin/mason_handler.fcgi \
+               bin/mason_handler.svc \
+               bin/webmux.pl \
+               bin/rt-crontool \
+               $(DESTDIR)/$(RT_BIN_PATH)
+# }}}
+
+# {{{ local-install
+local-install:
+       -cp -rp ./local/html/* $(DESTDIR)/$(MASON_LOCAL_HTML_PATH)
+       -cp -rp ./local/po/* $(DESTDIR)/$(LOCAL_LEXICON_PATH)
+       -cp -rp ./local/etc/* $(DESTDIR)/$(LOCAL_ETC_PATH)
+# }}}
+
+# {{{ Best Practical Build targets -- no user servicable parts inside
+
+
+POD2TEST_EXE = sbin/extract_pod_tests
+
+testify-pods:
+       [ -d lib/t/autogen ] || mkdir lib/t/autogen
+       find lib -name \*pm |grep -v \*.in |xargs -n 1 $(PERL) $(POD2TEST_EXE)
+       find bin -type f |grep -v \~ | grep -v "\.in" | xargs -n 1 $(PERL) $(POD2TEST_EXE)
+
+
+
+regenerate-catalogs:
+       $(PERL) sbin/extract-message-catalog
+
+license-tag:
+       $(PERL) sbin/license_tag
+
+factory: initialize-database
+       cd lib; $(PERL) ../sbin/factory  $(DB_DATABASE) RT
+
+commit:
+       aegis -build ; aegis -diff ; aegis -test; aegis -develop_end
+
+integrate:
+       aegis -integrate_begin; aegis -build; aegis -diff; aegis -test ; aegis -integrate_pass
+
+predist: commit tag-and-tar
+
+tag-and-release-baseline:
+       aegis -cp -ind Makefile -output /tmp/Makefile.tagandrelease; \
+       $(MAKE) -f /tmp/Makefile.tagandrelease tag-and-release-never-by-hand
+
+
+# Running this target in a working directory is 
+# WRONG WRONG WRONG.
+# it will tag the current baseline with the version of RT defined 
+# in the currently-being-worked-on makefile. which is wrong.
+#  you want tag-and-release-baseline
+
+tag-and-release-never-by-hand:
+       aegis --delta-name $(TAG)
+       rm -rf /tmp/$(TAG)
+       mkdir /tmp/$(TAG)
+       cd /tmp/$(TAG); \
+               aegis -cp -ind -delta $(TAG) . ;\
+               make reconfigure;\
+               chmod 600 Makefile;\
+               aegis --report --project rt.$(RT_VERSION_MAJOR) \
+                     --page_width 80 \
+                     --page_length 9999 \
+                     --change $(RT_VERSION_MINOR) --output Changelog Change_Log
+
+       cd /tmp; tar czvf /home/ftp/pub/rt/devel/$(TAG).tar.gz $(TAG)/
+       chmod 644 /home/ftp/pub/rt/devel/$(TAG).tar.gz
+
+
+reconfigure:
+       aclocal -I m4
+       autoconf
+       chmod 755 ./configure
+       ./configure
+
+rpm:
+       (cd ..; tar czvf /usr/src/redhat/SOURCES/rt.tar.gz rt)
+       rpm -ba etc/rt.spec
+
+
+apachectl:
+       apachectl stop
+       sleep 3
+       apachectl start
+# }}}
diff --git a/rt/README b/rt/README
deleted file mode 100755 (executable)
index d16100c..0000000
--- a/rt/README
+++ /dev/null
@@ -1,336 +0,0 @@
-$Header: /home/cvs/cvsroot/freeside/rt/README,v 1.1 2002-08-12 06:17:06 ivan Exp $
-RT is (c) 1996-2002 by Jesse Vincent <jesse@bestpractical.com>
-
-RT is licensed to you under the terms of version 2 of the GNU General 
-Public License. 
-
-If you don't have a copy of the GPL, you've been living in a cave,
-but one should be included in this distribution.
-
-
-INSTALLATION INSTRUCTIONS
--------------------------
-
-These instructions are a summary of those at http://www.fsck.com/rtfm/
-The docs on the web at www.fsck.com/rtfm/ are likely to be more up to
-date and complete than this document. You should consult them before 
-proceeding.
-
-REQUIRED PACKAGES:
-------------------
-
-o   Perl5.005_03 or later with support for setgid perl scripts
-        RT's command line and mail gateway tools run setgid to the 'rt' group
-       to protect RT's database password.  You may need to install a special 
-       "suidperl" package or reconfigure your perl setup to support
-        "setuid scripts".
-
-o   A DB backend; MySQL is recommended ( http://www.mysql.com ) 
-        Currently supported:    Mysql 3.23.38 or newer. 
-                                (Some older releases had crippling SQL bugs)
-                               Postgres 7.1 or newer.
-
-o   Apache + mod_perl -- ( http://perl.apache.org) 
-    or A webserver with FastCGI support (www.fastcgi.com)
-
-       If you compile mod_perl as a DSO, you're on your own. It's known
-       to have massive stability problems. 
-        mod_perl must be build with EVERYTHING=1
-
-o    Various and sundry perl modules
-        RT takes care of the installation of most of these automatically
-        during the "make testdeps" and "make fixdeps" stages below
-
-
-GENERAL INSTALLATION
---------------------
-
-1   Unpack this distribution SOMWHERE OTHER THAN where you want to install RT
-
-        Granted, you've already got it open. To do this cleanly:
-
-               tar xzvf rt.tar.gz -C /tmp
-
-2   Check over /tmp/rt/Makefile
-
-       There are many variables you NEED to customize for your site.
-       Even if you are just upgrading, you must set ALL variables.
-
-3   Satisfy RT's myriad dependencies.  There's a perl script in rt/tools
-    called testdeps that uses CPAN to automate all of this.
-
-3.1   Check for compliance:
-       make testdeps
-
-3.2   If there are unsatisfied dependencies, install them by hand or run
-       make fixdeps
-       
-       (You may need to install Apache::Session and Apache::DBI by hand.
-
-       You might need to install Msql-Mysql-Modules by hand.
-       perl -MCPAN -e'install DBD::mysql::Install' should do it for you.
-       )
-
-3.3   Check to make sure everything was installed properly:
-       make testdeps
-
-4   Create a group called 'rt'
-
-5a  FOR A NEW INSTALLATION: 
-        
-        As root, type:
-                make install   (replace "make" with the local name for 
-                                Make, if you need to)
-
-       If the make fails, type:
-               make dropdb 
-       and start over from step 5a
-
-5b  FOR UPGRADING: (Within the RT 2.0.x series)
-
-       Make a backup of /path/to/rt/etc/config.pm
-        As root, type: 
-               make upgrade     (replace "make" with the local name for 
-                                 Make, if you need to)
-
-       This will build new binaries, config files and libraries without
-       overwriting your RT database. 
-
-        WARNING: This WILL clobber your existing configuration file!
-        
-        The install process will then instruct you to update your RT system 
-        database objects by running rt/etc/insertdata <version> where 
-        <version> is the version of RT you're upgrading from.
-
-        
-       
-5c  FOR UPGRADING (From 1.0.x):
-
-       Follow the instructions for installing RT 2.0.
-
-       Once you have installed RT 2.0, download import-1.0-to-2.0
-       from http://www.fsck.com/pub/rt/contrib/2.0/rt-addons
-
-       Edit the configuration defaults in import-1.0-to-2.0
-
-       If you don't set $DEFAULTQUEUE to the name of one of your
-       RT 1.0 queues, THE IMPORT WILL FAIL.
-
-       perl ./import-1.0-to-2.0
-
-       The import tool will do its thing. If you're using postgres, you'll
-       need to execute the following SQL statement within your RT2 database:
-
-       select setval('tickets_id_seq', (select max(id) from tickets));
-       
-       It imports:
-               Queues, Areas, Users, Acls, Mailing Rules, Queue Members,
-               Tickets and Transactions.
-
-       It DOES NOT IMPORT:
-               Attachments removed by stripmime or Templates.
-       
-6   Edit etc/config.pm in your RT installation directory.  In many
-    cases sensible defaults have been included. In others, you MUST
-    supply a value.
-
-7   Configure the email and web gateways, as described below. 
-
-8   Stop and start your webserver, so it picks up your configuration changes.
-
-    NOTE: root's password for the web interface is "password" 
-    (without the quotes.)  Not changing this is a SECURITY risk
-    
-9   Configure RT per the instructions at http://www.fsck.com/rtfm/
-
-    Until you do this, RT will not be able to send or recieve email,
-    nor will it be more than marginally functional.  This is not an
-    optional step.
-
-
-SETTING UP THE MAIL GATEWAY 
----------------------------
-
-An alias for the initial queue will need to be made in either your
-global mail aliases file (if you are using NIS) or locally on your
-machine.
-Add the following lines to /etc/aliases (or your local equivalent) :
-
-rt:         "|/path/to/rt2/bin/rt-mailgate --queue general --action correspond"
-rt-comment: "|/path/to/rt2/bin/rt-mailgate --queue general --action comment"
-                                                   |                |
-                                   <queue-name>----/                |
-                                                                    |
-                      <correspond or comment depending on whether   |
-                      the mail should be resent to the requestor>---/
-
-
-
-THE WEB UI
-----------
-
-RT's web ui is based around HTML::Mason, which works well with the mod_perl
-perl interpreter within Apache httpd as well as with a webserver which
-supports FastCGI. (Instructions for configuring RT for use with FastCGI
-are available at http://www.fsck.com/rtfm/ )
-
-Apache 
-        RT Uses HTML::Mason.  You'll need to add a few lines to your
-        httpd.conf telling it to use rt's web ui.  If you have mod-perl
-       (you should, the perl scripts will go quite a bit faster around with
-       it), you can do something like this:
-
-
-<VirtualHost your.ip.address>
-DocumentRoot /path/to/rt2/WebRT/html
-ServerName your.rt.server.hostname
-PerlModule Apache::DBI
-PerlFreshRestart On
-PerlRequire /path/to/rt2/bin/webmux.pl
-<Location />
- SetHandler perl-script
- PerlHandler RT::Mason
-</Location>
-</VirtualHost>
-
-Additionally, you should set up a cron job to remove stale session data.
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- WARNING: Don't install this cron job or run this find command if your
- MASON_SESSION_PATH (known in config.pm as $MasonSessionDir) 
- points to a directory that could  EVER contain any file that's not 
- a Apache::Session datafile.
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-# Every hour, nuke session files and lockfiles that haven't been 
-# touched in 10 hours
-
-0 * * * * find /path/to/rt2/WebRT/sessiondata -type f -amin +600 -exec rm {} \;
-
-
-THE CLI
--------
-        Binaries for the CLI are located in rt/bin
-        You've got:
-
-                "rt" (manipulate or display requests) 
-                "rtadmin" (modify queues, users and acls)
-
-        Both of these programs take --help as an option.
-
-
-BUGS
-----
-
-Known issues with releases of RT2 are listed at 
-<URL:http://fsck.com/rt2/NoAuth/Errata.html>.  This includes every bug known
-to exist in each release of RT.  (When prompted, login as guest/guest)
-
-To find out more about currently open bugs, check out the live 
-Buglist at  <URL:http://fsck.com/rt2/NoAuth/Buglist.html>.
-(When prompted, login as guest/guest)
-
-To report a bug, send an email to rt-2.0-bugs@fsck.com.
-
-GETTING HELP
-------------
-
-If RT is mission-critical for you or if you use it heavily, we recommend that
-you purchase a commercial support contract.  Details on support contracts
-are available at http://www.bestpractical.com.
-
-If you're interested in having RT extended or customized or would like more
-information about commercial support options, please send email to 
-<sales@bestpractical.com> to discuss rates and availability.
-
-
-RT-USERS MAILINGLIST
---------------------
-
-To keep up to date on the latest RT tips, techniques and extections,
-you probably want to join the rt-users mailinglist.  Send a message to:
-
-         rt-users-request@lists.fsck.com 
-
-With the body of the message consisting of only the word:
-
-        subscribe
-
-If you're interested in hacking on rt, you'll want to subscribe to
-rt-devel@lists.fsck.com.  Subscribe to it with instructions similar to
-those above.
-
-Address questions about the stable release to the rt-users list, and
-questions about the development version to the rt-devel list.  If you feel
-your questions are best not asked publically, send them personally to
-<jesse@bestpractical.com>.
-
-If you want to be informed of every commit to the CVS repository,
-subscribe to rt-commit@fsck.com using similar instructions to those above.
-
-
-RT WEBSITE
-----------
-
-For current information about RT, check out the RT website at 
-http://www.bestpractical.com/rt  You'll find screenshots, a pointer
-to the current version of rt, contributed patches and lots of other great
-stuff.
-
-
-TROUBLESHOOTING
----------------
-
-All errors will be appended to a logfile, which lives in /tmp/rt.log.* unless 
-you've reconfigured it.  Check etc/config.pm for details.
-
-If the solution to the problem you're running into isn't obvious and you've 
-checked the FAQ, feel free to send mail to rt-users@fsck.com (for release 
-versions of RT) or rt-devel@fsck.com (for development versions).
-
-GIVING SOMETHING BACK
----------------------
-
-RT is free software. You are not obligated to pay for it.  You should be 
-aware, however, that bestpractical.com's sole source of revenue is commercial
-work related to RT. If you are able, either a contract to extend RT in some 
-way that would be useful to your organization, a financial contribution, or 
-even something off the author's amazon wishlist 
-       ( http://www.amazon.com/exec/obidos/wishlist/2GMHUDAFBT2XR/ )
-would be much appreciated. 
-
-Thanks!
-
-
-CREDITS
--------
-
-A lot of people are responsible for making RT a better program.  Many
-thanks to Lauren Burka, who originally tasked me with writing this beast.
-She forced me to use a database backend.  I've thanked her for it every
-day since.  Rich West rewrote this readme and did some UI hacking.  Adam
-Hirsch, Kit Kraysha, Robin Garner, Jens Glaser, John Adams, Trey Belew, 
-Sean Dague, Nathan Mehl, Kee Hinckley, Rich West, Dale Bewley, Serge Zhuk,
-John Lengeling, Elmar Knipp, Gerald Abshez, Dave Hull, Dave Schenet,
-Dave Walton, Jan Okrouhly, Tobias Brox, Lamont Lucas, Charlie Brady,
-Robin Shostack, Eric Mumpower, Jerrod Wiesman, Adam Hammer, Ivan Kohler, Alex
-Pilosov, Mary Alderdice, Deborah Kaplan, Jens von Bülow, Tristan Horn,
-Lee Ann Goldstein, Karel P Kerezman, Feargal Reilly, Christian Steger,
-Christian Kurz, JD Falk, Arthur de Jong, Ben Carter, Mark Vevers
-and many others
-have all contributed bug reports, code or ideas that have helped RT along.  
-
-Arepa, Inc, Utopia Inc, Wesleyan University and The Leftbank Operation 
-have paid me to maintain RT and release it to the public.  Without their 
-support RT would not exist.  
-
-If I've left you out, please drop me a line ....it wasn't intentional. 
-
-        Enjoy
-
-        Jesse Vincent
-       <jesse@bestpractical.com>
-        Best Practical Solutions, LLC
diff --git a/rt/TODO b/rt/TODO
deleted file mode 100755 (executable)
index 3d1b7d0..0000000
--- a/rt/TODO
+++ /dev/null
@@ -1,9 +0,0 @@
-Errata for RT 2.x can be found at http://fsck.com/rt2/NoAuth/Errata.html
-
-A list of all open issues, including those which haven't been added
-to the official Errata lists,  can be found at 
-http://fsck.com/rt2/NoAuth/Buglist.html
-
-If you want to look at bugs in more detail, you may need to login as guest with a password of 'guest'
-
-
diff --git a/rt/aclocal.m4 b/rt/aclocal.m4
new file mode 100644 (file)
index 0000000..475b389
--- /dev/null
@@ -0,0 +1,158 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4-p4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+dnl
+dnl @synopsis RT_ENABLE_LAYOUT()
+dnl
+dnl Enable a specific directory layout for the installation to use.
+dnl This configures a command-line parameter that can be specified
+dnl at ./configure invocation.
+dnl
+dnl The use of this feature in this way is a little hackish, but
+dnl better than a heap of options for every directory.
+dnl
+dnl This code is heavily borrowed *cough* from the Apache 2 code.
+dnl
+
+AC_DEFUN([RT_ENABLE_LAYOUT],[
+AC_ARG_ENABLE(layout,
+             AC_HELP_STRING([--enable-layout=LAYOUT],
+                            [Use a specific directory layout (Default: RT3)]),
+             LAYOUT=$enableval)
+
+if test "x$LAYOUT" = "x"; then
+       LAYOUT="RT3"
+fi
+RT_LAYOUT($srcdir/config.layout, $LAYOUT)
+AC_MSG_CHECKING(for chosen layout)
+if test "x$rt_layout_name" = "xno"; then
+       if test "x$LAYOUT" = "xno"; then
+               AC_MSG_RESULT(none)
+       else
+               AC_MSG_RESULT($LAYOUT)
+       fi
+       AC_MSG_ERROR([a valid layout must be specified (or the default used)])
+else
+       AC_SUBST(rt_layout_name)
+       AC_MSG_RESULT($rt_layout_name)
+fi
+])
+
+dnl
+dnl @synopsis RT_LAYOUT(configlayout, layoutname)
+dnl
+dnl This macro reads an Apache-style layout file (specified as the
+dnl configlayout parameter), and searches for a specific layout
+dnl (named using the layoutname parameter).
+dnl
+dnl The entries for a given layout are then inserted into the
+dnl environment such that they become available as substitution
+dnl variables. In addition, the rt_layout_name variable is set
+dnl (but not exported) if the layout is valid.
+dnl
+dnl This code is heavily borrowed *cough* from the Apache 2 codebase.
+dnl
+
+AC_DEFUN([RT_LAYOUT],[
+       if test ! -f $srcdir/config.layout; then
+               AC_MSG_WARN([Layout file $srcdir/config.layout not found])
+               rt_layout_name=no
+       else
+               pldconf=./config.pld
+               $PERL  -0777 -p -e "\$layout = '$2';"  -e '
+               s/.*<Layout\s+$layout>//gims; 
+               s/\<\/Layout\>.*//s; 
+               s/^#.*$//m;
+               s/^\s+//gim;
+               s/\s+$/\n/gim;
+               s/\+$/\/rt3/gim;
+               # m4 will not let us just use $1, we need @S|@1
+               s/^\s*((?:bin|sbin|libexec|data|sysconf|sharedstate|localstate|lib|include|oldinclude|info|man)dir)\s*:\s*(.*)$/@S|@1=@S|@2/gim;
+               s/^\s*(.*?)\s*:\s*(.*)$/\(test "x\@S|@@S|@1" = "xNONE" || test "x\@S|@@S|@1" = "x") && @S|@1=@S|@2/gim;
+                ' < $1 > $pldconf
+
+               if test -s $pldconf; then
+                       rt_layout_name=$2
+                       . $pldconf
+                       changequote({,})
+                       for var in prefix exec_prefix bindir sbindir \
+                                sysconfdir mandir libdir datadir htmldir \
+                                localstatedir logfiledir masonstatedir \
+                                sessionstatedir customdir custometcdir customhtmldir \
+                                customlexdir customlibdir manualdir; do
+                               eval "val=\"\$$var\""
+                               val=`echo $val | sed -e 's:\(.\)/*$:\1:'`
+                               val=`echo $val | 
+                                       sed -e 's:[\$]\([a-z_]*\):${\1}:g'`
+                               eval "$var='$val'"
+                       done
+                       changequote([,])
+               else
+                       rt_layout_name=no
+               fi
+               #rm $pldconf
+       fi
+       RT_SUBST_EXPANDED_ARG(prefix)
+       RT_SUBST_EXPANDED_ARG(exec_prefix)
+       RT_SUBST_EXPANDED_ARG(bindir)
+       RT_SUBST_EXPANDED_ARG(sbindir)
+       RT_SUBST_EXPANDED_ARG(sysconfdir)
+       RT_SUBST_EXPANDED_ARG(mandir)
+       RT_SUBST_EXPANDED_ARG(libdir)
+       RT_SUBST_EXPANDED_ARG(datadir)
+       RT_SUBST_EXPANDED_ARG(htmldir)
+       RT_SUBST_EXPANDED_ARG(manualdir)
+       RT_SUBST_EXPANDED_ARG(localstatedir)
+       RT_SUBST_EXPANDED_ARG(logfiledir)
+       RT_SUBST_EXPANDED_ARG(masonstatedir)
+       RT_SUBST_EXPANDED_ARG(sessionstatedir)
+       RT_SUBST_EXPANDED_ARG(customdir)
+       RT_SUBST_EXPANDED_ARG(custometcdir)
+       RT_SUBST_EXPANDED_ARG(customhtmldir)
+       RT_SUBST_EXPANDED_ARG(customlexdir)
+       RT_SUBST_EXPANDED_ARG(customlibdir)
+])dnl
+
+dnl
+dnl @synopsis  RT_SUBST_EXPANDED_ARG(var)
+dnl
+dnl Export (via AC_SUBST) a given variable, along with an expanded
+dnl version of the variable (same name, but with exp_ prefix).
+dnl
+dnl This code is heavily borrowed *cough* from the Apache 2 source.
+dnl
+
+AC_DEFUN([RT_SUBST_EXPANDED_ARG],[
+       RT_EXPAND_VAR(exp_$1, [$]$1)
+       AC_SUBST($1)
+       AC_SUBST(exp_$1)
+])
+
+dnl
+dnl @synopsis  RT_EXPAND_VAR(baz, $fraz)
+dnl
+dnl Iteratively expands the second parameter, until successive iterations
+dnl yield no change. The result is then assigned to the first parameter.
+dnl
+dnl This code is heavily borrowed from the Apache 2 codebase.
+dnl
+
+AC_DEFUN([RT_EXPAND_VAR],[
+       ap_last=''
+       ap_cur='$2'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       $1="${ap_cur}"
+])
+
diff --git a/rt/autom4te.cache/output.0 b/rt/autom4te.cache/output.0
new file mode 100644 (file)
index 0000000..51a8aaf
--- /dev/null
@@ -0,0 +1,2747 @@
+@%:@! /bin/sh
+@%:@ From configure.ac Revision: 1.1 .
+@%:@ Guess values for system-dependent variables and create Makefiles.
+@%:@ Generated by GNU Autoconf 2.53 for RT 3.0.4.
+@%:@
+@%:@ Report bugs to <rt-3.0-bugs@fsck.com>.
+@%:@ 
+@%:@ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+@%:@ Free Software Foundation, Inc.
+@%:@ This configure script is free software; the Free Software Foundation
+@%:@ gives unlimited permission to copy, distribute and modify it.
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# NLS nuisances.
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
+    { $as_unset LANG || test "${LANG+set}" != set; } ||
+      { LANG=C; export LANG; }
+(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
+    { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
+      { LC_ALL=C; export LC_ALL; }
+(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
+    { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
+      { LC_TIME=C; export LC_TIME; }
+(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
+    { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
+      { LC_CTYPE=C; export LC_CTYPE; }
+(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
+    { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
+      { LANGUAGE=C; export LANGUAGE; }
+(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
+    { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
+      { LC_COLLATE=C; export LC_COLLATE; }
+(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
+    { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
+      { LC_NUMERIC=C; export LC_NUMERIC; }
+(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
+    { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
+      { LC_MESSAGES=C; export LC_MESSAGES; }
+
+
+# Name of the executable.
+as_me=`(basename "$0") 2>/dev/null ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conftest.sh
+  echo  "exit 0"   >>conftest.sh
+  chmod +x conftest.sh
+  if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conftest.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='RT'
+PACKAGE_TARNAME='rt'
+PACKAGE_VERSION='3.0.4'
+PACKAGE_STRING='RT 3.0.4'
+PACKAGE_BUGREPORT='rt-3.0-bugs@fsck.com'
+
+ac_unique_file="lib/RT.pm.in"
+ac_default_prefix=/opt/rt3
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+              localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$0" : 'X\(//\)[^/]' \| \
+         X"$0" : 'X\(//\)$' \| \
+         X"$0" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_PERL_set=${PERL+set}
+ac_env_PERL_value=$PERL
+ac_cv_env_PERL_set=${PERL+set}
+ac_cv_env_PERL_value=$PERL
+
+#
+# Report the --help message.
+#
+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 3.0.4 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of RT 3.0.4:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-layout=LAYOUT  Use a specific directory layout (Default: RT3)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-speedycgi=/path/to/speedy 
+                          path to your speedycgi binary, if it exists
+  --with-rt-group=GROUP   group to own all files (default: rt)
+  --with-bin-owner=OWNER  user that will own rt binaries (default root)
+  --with-libs-owner=OWNER user that will own RT libraries (default root)
+  --with-libs-group=GROUP group that will own rt binaries (default bin)
+  --with-db-type=TYPE     sort of database RT will use (default: mysql) (mysql
+                          and Pg are valid)
+  --with-db-host=HOSTNAME FQDN of database server (default: localhost)
+  --with-db-port=PORT     port on which the database listens on
+  --with-db-rt-host=HOSTNAME 
+                          FQDN of RT server which talks to the database server
+                          (default: localhost)
+  --with-db-dba=DBA       name of database administrator (default: root)
+  --with-db-database=DBNAME 
+                          name of the database to use (default: rt3)
+  --with-db-rt-user=DBUSER 
+                          name of database user (default: rt_user)
+  --with-db-rt-pass=PASSWORD 
+                          password for database user (default: rt_pass)
+  --with-web-user=USER    user the web server runs as (default: www)
+  --with-web-group=GROUP  group the web server runs as (default: www)
+
+Some influential environment variables:
+  PERL        Perl interpreter command
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <rt-3.0-bugs@fsck.com>.
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+           test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+RT configure 3.0.4
+generated by GNU Autoconf 2.53
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_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 3.0.4, which was
+generated by GNU Autoconf 2.53.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+@%:@@%:@ --------- @%:@@%:@
+@%:@@%:@ Platform. @%:@@%:@
+@%:@@%:@ --------- @%:@@%:@
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+@%:@@%:@ ----------- @%:@@%:@
+@%:@@%:@ Core tests. @%:@@%:@
+@%:@@%:@ ----------- @%:@@%:@
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell meta-characters.
+ac_configure_args=
+ac_sep=
+for ac_arg
+do
+  case $ac_arg in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n ) continue ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    continue ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+    ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  case " $ac_configure_args " in
+    *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+    *) ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+       ac_sep=" " ;;
+  esac
+  # Get rid of the leading space.
+done
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+    cat <<\_ASBOX
+@%:@@%:@ ---------------- @%:@@%:@
+@%:@@%:@ Cache variables. @%:@@%:@
+@%:@@%:@ ---------------- @%:@@%:@
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+        "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+@%:@@%:@ ----------- @%:@@%:@
+@%:@@%:@ confdefs.h. @%:@@%:@
+@%:@@%:@ ----------- @%:@@%:@
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core core.* *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+               sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+        { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+        { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+        { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+        ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+rt_version_major=3
+
+rt_version_minor=0
+
+rt_version_patch=4
+
+test "x$rt_version_major" = 'x' && rt_version_major=0
+test "x$rt_version_minor" = 'x' && rt_version_minor=0
+test "x$rt_version_patch" = 'x' && rt_version_patch=0
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+          if test $ac_prog = install &&
+            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # AIX install.  It has an incompatible calling convention.
+            :
+          elif test $ac_prog = install &&
+            grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # program-specific install script used by HP pwplus--don't use.
+            :
+          else
+            ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+            break 3
+          fi
+        fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_PERL+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $PERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="not found"
+  ;;
+esac
+fi
+PERL=$ac_cv_path_PERL
+
+if test -n "$PERL"; then
+  echo "$as_me:$LINENO: result: $PERL" >&5
+echo "${ECHO_T}$PERL" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test "$PERL" = 'not found'; then
+       { { echo "$as_me:$LINENO: error: cannot use $PACKAGE_NAME without perl" >&5
+echo "$as_me: error: cannot use $PACKAGE_NAME without perl" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# Check whether --with-speedycgi or --without-speedycgi was given.
+if test "${with_speedycgi+set}" = set; then
+  withval="$with_speedycgi"
+  SPEEDY_BIN=$withval
+else
+  SPEEDY_BIN=/usr/local/bin/speedy
+fi;  
+
+
+
+
+
+# Check whether --enable-layout or --disable-layout was given.
+if test "${enable_layout+set}" = set; then
+  enableval="$enable_layout"
+  LAYOUT=$enableval
+fi; 
+
+if test "x$LAYOUT" = "x"; then
+       LAYOUT="RT3"
+fi
+
+       if test ! -f $srcdir/config.layout; then
+               { echo "$as_me:$LINENO: WARNING: Layout file $srcdir/config.layout not found" >&5
+echo "$as_me: WARNING: Layout file $srcdir/config.layout not found" >&2;}
+               rt_layout_name=no
+       else
+               pldconf=./config.pld
+               $PERL  -0777 -p -e "\$layout = '$LAYOUT';"  -e '
+               s/.*<Layout\s+$layout>//gims; 
+               s/\<\/Layout\>.*//s; 
+               s/^#.*$//m;
+               s/^\s+//gim;
+               s/\s+$/\n/gim;
+               s/\+$/\/rt3/gim;
+               # m4 will not let us just use $srcdir/config.layout, we need @S|@1
+               s/^\s*((?:bin|sbin|libexec|data|sysconf|sharedstate|localstate|lib|include|oldinclude|info|man)dir)\s*:\s*(.*)$/@S|@1=@S|@2/gim;
+               s/^\s*(.*?)\s*:\s*(.*)$/\(test "x\@S|@@S|@1" = "xNONE" || test "x\@S|@@S|@1" = "x") && @S|@1=@S|@2/gim;
+                ' < $srcdir/config.layout > $pldconf
+
+               if test -s $pldconf; then
+                       rt_layout_name=$LAYOUT
+                       . $pldconf
+                       
+                       for var in prefix exec_prefix bindir sbindir \
+                                sysconfdir mandir libdir datadir htmldir \
+                                localstatedir logfiledir masonstatedir \
+                                sessionstatedir customdir custometcdir customhtmldir \
+                                customlexdir customlibdir manualdir; do
+                               eval "val=\"\$$var\""
+                               val=`echo $val | sed -e 's:\(.\)/*$:\1:'`
+                               val=`echo $val | 
+                                       sed -e 's:[\$]\([a-z_]*\):$\1:g'`
+                               eval "$var='$val'"
+                       done
+                       
+               else
+                       rt_layout_name=no
+               fi
+               #rm $pldconf
+       fi
+       
+       
+       ap_last=''
+       ap_cur='$prefix'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_prefix="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$exec_prefix'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_exec_prefix="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$bindir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_bindir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$sbindir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_sbindir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$sysconfdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_sysconfdir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$mandir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_mandir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$libdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_libdir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$datadir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_datadir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$htmldir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_htmldir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$manualdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_manualdir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$localstatedir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_localstatedir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$logfiledir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_logfiledir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$masonstatedir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_masonstatedir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$sessionstatedir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_sessionstatedir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$customdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_customdir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$custometcdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_custometcdir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$customhtmldir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_customhtmldir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$customlexdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_customlexdir="${ap_cur}"
+
+       
+       
+
+       
+       
+       ap_last=''
+       ap_cur='$customlibdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_customlibdir="${ap_cur}"
+
+       
+       
+
+
+echo "$as_me:$LINENO: checking for chosen layout" >&5
+echo $ECHO_N "checking for chosen layout... $ECHO_C" >&6
+if test "x$rt_layout_name" = "xno"; then
+       if test "x$LAYOUT" = "xno"; then
+               echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6
+       else
+               echo "$as_me:$LINENO: result: $LAYOUT" >&5
+echo "${ECHO_T}$LAYOUT" >&6
+       fi
+       { { echo "$as_me:$LINENO: error: a valid layout must be specified (or the default used)" >&5
+echo "$as_me: error: a valid layout must be specified (or the default used)" >&2;}
+   { (exit 1); exit 1; }; }
+else
+       
+       echo "$as_me:$LINENO: result: $rt_layout_name" >&5
+echo "${ECHO_T}$rt_layout_name" >&6
+fi
+
+
+
+# Check whether --with-rt-group or --without-rt-group was given.
+if test "${with_rt_group+set}" = set; then
+  withval="$with_rt_group"
+  RTGROUP=$withval
+else
+  RTGROUP=rt
+fi; 
+
+
+
+# Check whether --with-bin-owner or --without-bin-owner was given.
+if test "${with_bin_owner+set}" = set; then
+  withval="$with_bin_owner"
+  BIN_OWNER=$withval
+else
+  BIN_OWNER=root
+fi; 
+
+
+
+# Check whether --with-libs-owner or --without-libs-owner was given.
+if test "${with_libs_owner+set}" = set; then
+  withval="$with_libs_owner"
+  LIBS_OWNER=$withval
+else
+  LIBS_OWNER=root
+fi; 
+
+
+
+# Check whether --with-libs-group or --without-libs-group was given.
+if test "${with_libs_group+set}" = set; then
+  withval="$with_libs_group"
+  LIBS_GROUP=$withval
+else
+  LIBS_GROUP=bin
+fi; 
+
+
+
+# Check whether --with-db-type or --without-db-type was given.
+if test "${with_db_type+set}" = set; then
+  withval="$with_db_type"
+  DB_TYPE=$withval
+else
+  DB_TYPE=mysql
+fi; 
+if test "$DB_TYPE" != 'mysql' -a "$DB_TYPE" != 'Pg' -a "$DB_TYPE" != 'SQLite'; then
+       { { echo "$as_me:$LINENO: error: Only Pg and mysql are valid db types" >&5
+echo "$as_me: error: Only Pg and mysql are valid db types" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+
+# Check whether --with-db-host or --without-db-host was given.
+if test "${with_db_host+set}" = set; then
+  withval="$with_db_host"
+  DB_HOST=$withval
+else
+  DB_HOST=localhost
+fi; 
+
+
+
+# Check whether --with-db-port or --without-db-port was given.
+if test "${with_db_port+set}" = set; then
+  withval="$with_db_port"
+  DB_PORT=$withval
+else
+  DB_PORT=
+fi; 
+
+
+
+# Check whether --with-db-rt-host or --without-db-rt-host was given.
+if test "${with_db_rt_host+set}" = set; then
+  withval="$with_db_rt_host"
+  DB_RT_HOST=$withval
+else
+  DB_RT_HOST=localhost
+fi; 
+
+
+
+# Check whether --with-db-dba or --without-db-dba was given.
+if test "${with_db_dba+set}" = set; then
+  withval="$with_db_dba"
+  DB_DBA=$withval
+else
+  DB_DBA=root
+fi; 
+
+
+
+# Check whether --with-db-database or --without-db-database was given.
+if test "${with_db_database+set}" = set; then
+  withval="$with_db_database"
+  DB_DATABASE=$withval
+else
+  DB_DATABASE=rt3
+fi; 
+
+
+
+# Check whether --with-db-rt-user or --without-db-rt-user was given.
+if test "${with_db_rt_user+set}" = set; then
+  withval="$with_db_rt_user"
+  DB_RT_USER=$withval
+else
+  DB_RT_USER=rt_user
+fi; 
+
+
+
+# Check whether --with-db-rt-pass or --without-db-rt-pass was given.
+if test "${with_db_rt_pass+set}" = set; then
+  withval="$with_db_rt_pass"
+  DB_RT_PASS=$withval
+else
+  DB_RT_PASS=rt_pass
+fi; 
+
+
+
+# Check whether --with-web-user or --without-web-user was given.
+if test "${with_web_user+set}" = set; then
+  withval="$with_web_user"
+  WEB_USER=$withval
+else
+  WEB_USER=www
+fi; 
+
+
+
+# Check whether --with-web-group or --without-web-group was given.
+if test "${with_web_group+set}" = set; then
+  withval="$with_web_group"
+  WEB_GROUP=$withval
+else
+  WEB_GROUP=www
+fi; 
+
+
+
+RT_VERSION_MAJOR=${rt_version_major}
+
+RT_VERSION_MINOR=${rt_version_minor}
+
+RT_VERSION_PATCH=${rt_version_patch}
+
+
+RT_PATH=${exp_prefix}
+
+RT_DOC_PATH=${exp_manualdir}
+
+RT_LOCAL_PATH=${exp_customdir}
+
+RT_LIB_PATH=${exp_libdir}
+
+RT_ETC_PATH=${exp_sysconfdir}
+
+CONFIG_FILE_PATH=${exp_sysconfdir}
+
+RT_BIN_PATH=${exp_bindir}
+
+RT_SBIN_PATH=${exp_sbindir}
+
+RT_VAR_PATH=${exp_localstatedir}
+
+RT_MAN_PATH=${exp_mandir}
+
+MASON_DATA_PATH=${exp_masonstatedir}
+
+MASON_SESSION_PATH=${exp_sessionstatedir}
+
+MASON_HTML_PATH=${exp_htmldir}
+
+LOCAL_ETC_PATH=${exp_custometcdir}
+
+MASON_LOCAL_HTML_PATH=${exp_customhtmldir}
+
+LOCAL_LEXICON_PATH=${exp_customlexdir}
+
+LOCAL_LIB_PATH=${exp_customlibdir}
+
+DESTDIR=${exp_prefix}
+
+RT_LOG_PATH=${exp_logfiledir}
+
+
+
+ac_config_files="$ac_config_files sbin/rt-setup-database sbin/rt-test-dependencies Makefile etc/RT_Config.pm lib/RT.pm lib/t/00smoke.t lib/t/01harness.t lib/t/02regression.t lib/t/03web.pl lib/t/04_send_email.pl bin/mason_handler.fcgi bin/mason_handler.scgi bin/mason_handler.svc bin/rt-commit-handler bin/rt-crontool bin/rt-mailgate bin/webmux.pl"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overriden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+        "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if cmp -s $cache_file confcache; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[   ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[     ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[   ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
+t quote
+s,^[   ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[    `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# NLS nuisances.
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
+    { $as_unset LANG || test "${LANG+set}" != set; } ||
+      { LANG=C; export LANG; }
+(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
+    { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
+      { LC_ALL=C; export LC_ALL; }
+(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
+    { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
+      { LC_TIME=C; export LC_TIME; }
+(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
+    { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
+      { LC_CTYPE=C; export LC_CTYPE; }
+(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
+    { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
+      { LANGUAGE=C; export LANGUAGE; }
+(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
+    { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
+      { LC_COLLATE=C; export LC_COLLATE; }
+(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
+    { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
+      { LC_NUMERIC=C; export LC_NUMERIC; }
+(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
+    { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
+      { LC_MESSAGES=C; export LC_MESSAGES; }
+
+
+# Name of the executable.
+as_me=`(basename "$0") 2>/dev/null ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conftest.sh
+  echo  "exit 0"   >>conftest.sh
+  chmod +x conftest.sh
+  if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conftest.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../@%:@@%:@ /;s/...$/ @%:@@%:@/;p;x;p;x' <<_ASBOX
+@%:@@%:@ Running $as_me. @%:@@%:@
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by RT $as_me 3.0.4, which was
+generated by GNU Autoconf 2.53.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+RT config.status 3.0.4
+configured by $0, generated by GNU Autoconf 2.53,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    shift
+    set dummy "$ac_option" "$ac_optarg" ${1+"$@"}
+    shift
+    ;;
+  -*);;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_need_defaults=false;;
+  esac
+
+  case $1 in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion"
+    exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;;
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    shift
+    CONFIG_FILES="$CONFIG_FILES $1"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $1"
+    ac_need_defaults=false;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "sbin/rt-setup-database" ) CONFIG_FILES="$CONFIG_FILES sbin/rt-setup-database" ;;
+  "sbin/rt-test-dependencies" ) CONFIG_FILES="$CONFIG_FILES sbin/rt-test-dependencies" ;;
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "etc/RT_Config.pm" ) CONFIG_FILES="$CONFIG_FILES etc/RT_Config.pm" ;;
+  "lib/RT.pm" ) CONFIG_FILES="$CONFIG_FILES lib/RT.pm" ;;
+  "lib/t/00smoke.t" ) CONFIG_FILES="$CONFIG_FILES lib/t/00smoke.t" ;;
+  "lib/t/01harness.t" ) CONFIG_FILES="$CONFIG_FILES lib/t/01harness.t" ;;
+  "lib/t/02regression.t" ) CONFIG_FILES="$CONFIG_FILES lib/t/02regression.t" ;;
+  "lib/t/03web.pl" ) CONFIG_FILES="$CONFIG_FILES lib/t/03web.pl" ;;
+  "lib/t/04_send_email.pl" ) CONFIG_FILES="$CONFIG_FILES lib/t/04_send_email.pl" ;;
+  "bin/mason_handler.fcgi" ) CONFIG_FILES="$CONFIG_FILES bin/mason_handler.fcgi" ;;
+  "bin/mason_handler.scgi" ) CONFIG_FILES="$CONFIG_FILES bin/mason_handler.scgi" ;;
+  "bin/mason_handler.svc" ) CONFIG_FILES="$CONFIG_FILES bin/mason_handler.svc" ;;
+  "bin/rt-commit-handler" ) CONFIG_FILES="$CONFIG_FILES bin/rt-commit-handler" ;;
+  "bin/rt-crontool" ) CONFIG_FILES="$CONFIG_FILES bin/rt-crontool" ;;
+  "bin/rt-mailgate" ) CONFIG_FILES="$CONFIG_FILES bin/rt-mailgate" ;;
+  "bin/webmux.pl" ) CONFIG_FILES="$CONFIG_FILES bin/webmux.pl" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+: ${TMPDIR=/tmp}
+{
+  tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=$TMPDIR/cs$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in $TMPDIR" >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@rt_version_major@,$rt_version_major,;t t
+s,@rt_version_minor@,$rt_version_minor,;t t
+s,@rt_version_patch@,$rt_version_patch,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@PERL@,$PERL,;t t
+s,@SPEEDY_BIN@,$SPEEDY_BIN,;t t
+s,@exp_prefix@,$exp_prefix,;t t
+s,@exp_exec_prefix@,$exp_exec_prefix,;t t
+s,@exp_bindir@,$exp_bindir,;t t
+s,@exp_sbindir@,$exp_sbindir,;t t
+s,@exp_sysconfdir@,$exp_sysconfdir,;t t
+s,@exp_mandir@,$exp_mandir,;t t
+s,@exp_libdir@,$exp_libdir,;t t
+s,@exp_datadir@,$exp_datadir,;t t
+s,@htmldir@,$htmldir,;t t
+s,@exp_htmldir@,$exp_htmldir,;t t
+s,@manualdir@,$manualdir,;t t
+s,@exp_manualdir@,$exp_manualdir,;t t
+s,@exp_localstatedir@,$exp_localstatedir,;t t
+s,@logfiledir@,$logfiledir,;t t
+s,@exp_logfiledir@,$exp_logfiledir,;t t
+s,@masonstatedir@,$masonstatedir,;t t
+s,@exp_masonstatedir@,$exp_masonstatedir,;t t
+s,@sessionstatedir@,$sessionstatedir,;t t
+s,@exp_sessionstatedir@,$exp_sessionstatedir,;t t
+s,@customdir@,$customdir,;t t
+s,@exp_customdir@,$exp_customdir,;t t
+s,@custometcdir@,$custometcdir,;t t
+s,@exp_custometcdir@,$exp_custometcdir,;t t
+s,@customhtmldir@,$customhtmldir,;t t
+s,@exp_customhtmldir@,$exp_customhtmldir,;t t
+s,@customlexdir@,$customlexdir,;t t
+s,@exp_customlexdir@,$exp_customlexdir,;t t
+s,@customlibdir@,$customlibdir,;t t
+s,@exp_customlibdir@,$exp_customlibdir,;t t
+s,@rt_layout_name@,$rt_layout_name,;t t
+s,@RTGROUP@,$RTGROUP,;t t
+s,@BIN_OWNER@,$BIN_OWNER,;t t
+s,@LIBS_OWNER@,$LIBS_OWNER,;t t
+s,@LIBS_GROUP@,$LIBS_GROUP,;t t
+s,@DB_TYPE@,$DB_TYPE,;t t
+s,@DB_HOST@,$DB_HOST,;t t
+s,@DB_PORT@,$DB_PORT,;t t
+s,@DB_RT_HOST@,$DB_RT_HOST,;t t
+s,@DB_DBA@,$DB_DBA,;t t
+s,@DB_DATABASE@,$DB_DATABASE,;t t
+s,@DB_RT_USER@,$DB_RT_USER,;t t
+s,@DB_RT_PASS@,$DB_RT_PASS,;t t
+s,@WEB_USER@,$WEB_USER,;t t
+s,@WEB_GROUP@,$WEB_GROUP,;t t
+s,@RT_VERSION_MAJOR@,$RT_VERSION_MAJOR,;t t
+s,@RT_VERSION_MINOR@,$RT_VERSION_MINOR,;t t
+s,@RT_VERSION_PATCH@,$RT_VERSION_PATCH,;t t
+s,@RT_PATH@,$RT_PATH,;t t
+s,@RT_DOC_PATH@,$RT_DOC_PATH,;t t
+s,@RT_LOCAL_PATH@,$RT_LOCAL_PATH,;t t
+s,@RT_LIB_PATH@,$RT_LIB_PATH,;t t
+s,@RT_ETC_PATH@,$RT_ETC_PATH,;t t
+s,@CONFIG_FILE_PATH@,$CONFIG_FILE_PATH,;t t
+s,@RT_BIN_PATH@,$RT_BIN_PATH,;t t
+s,@RT_SBIN_PATH@,$RT_SBIN_PATH,;t t
+s,@RT_VAR_PATH@,$RT_VAR_PATH,;t t
+s,@RT_MAN_PATH@,$RT_MAN_PATH,;t t
+s,@MASON_DATA_PATH@,$MASON_DATA_PATH,;t t
+s,@MASON_SESSION_PATH@,$MASON_SESSION_PATH,;t t
+s,@MASON_HTML_PATH@,$MASON_HTML_PATH,;t t
+s,@LOCAL_ETC_PATH@,$LOCAL_ETC_PATH,;t t
+s,@MASON_LOCAL_HTML_PATH@,$MASON_LOCAL_HTML_PATH,;t t
+s,@LOCAL_LEXICON_PATH@,$LOCAL_LEXICON_PATH,;t t
+s,@LOCAL_LIB_PATH@,$LOCAL_LIB_PATH,;t t
+s,@DESTDIR@,$DESTDIR,;t t
+s,@RT_LOG_PATH@,$RT_LOG_PATH,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { case "$ac_dir" in
+  [\\/]* | ?:[\\/]* ) as_incr_dir=;;
+  *)                      as_incr_dir=.;;
+esac
+as_dummy="$ac_dir"
+for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
+  case $as_mkdir_dir in
+    # Skip DOS drivespec
+    ?:) as_incr_dir=$as_mkdir_dir ;;
+    *)
+      as_incr_dir=$as_incr_dir/$as_mkdir_dir
+      test -d "$as_incr_dir" ||
+        mkdir "$as_incr_dir" ||
+       { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }
+    ;;
+  esac
+done; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/rt/autom4te.cache/requests b/rt/autom4te.cache/requests
new file mode 100644 (file)
index 0000000..fad7b54
--- /dev/null
@@ -0,0 +1,94 @@
+# This file was created by autom4te.
+# It contains the lists of macros which have been traced.
+# It can be safely removed.
+
+@request = (
+             bless( [
+                      '0',
+                      1,
+                      [
+                        '/usr/share/autoconf'
+                      ],
+                      [
+                        '--reload-state=/usr/share/autoconf/autoconf/autoconf.m4f',
+                        'aclocal.m4',
+                        'configure.ac'
+                      ],
+                      {
+                        'AC_HEADER_STAT' => 1,
+                        'AC_FUNC_STRFTIME' => 1,
+                        'AC_PROG_RANLIB' => 1,
+                        'AC_FUNC_WAIT3' => 1,
+                        'AC_FUNC_SETPGRP' => 1,
+                        'AC_HEADER_TIME' => 1,
+                        'AC_FUNC_SETVBUF_REVERSED' => 1,
+                        'AC_HEADER_SYS_WAIT' => 1,
+                        'AC_TYPE_UID_T' => 1,
+                        'AM_CONDITIONAL' => 1,
+                        'AC_CHECK_LIB' => 1,
+                        'AC_PROG_LN_S' => 1,
+                        'AC_FUNC_MEMCMP' => 1,
+                        'AC_FUNC_FORK' => 1,
+                        'AC_FUNC_GETGROUPS' => 1,
+                        'AC_HEADER_MAJOR' => 1,
+                        'AC_FUNC_STRTOD' => 1,
+                        'AC_HEADER_DIRENT' => 1,
+                        'AC_FUNC_UTIME_NULL' => 1,
+                        'AC_CONFIG_FILES' => 1,
+                        'AC_FUNC_ALLOCA' => 1,
+                        'AC_C_CONST' => 1,
+                        'include' => 1,
+                        'AC_FUNC_OBSTACK' => 1,
+                        'AC_FUNC_LSTAT' => 1,
+                        'AC_STRUCT_TIMEZONE' => 1,
+                        'AC_FUNC_GETPGRP' => 1,
+                        'AC_DEFINE_TRACE_LITERAL' => 1,
+                        'AC_CHECK_HEADERS' => 1,
+                        'AC_TYPE_MODE_T' => 1,
+                        'AC_CHECK_TYPES' => 1,
+                        'AC_PROG_YACC' => 1,
+                        'AC_TYPE_PID_T' => 1,
+                        'AC_FUNC_STRERROR_R' => 1,
+                        'AC_STRUCT_ST_BLOCKS' => 1,
+                        'AC_PROG_GCC_TRADITIONAL' => 1,
+                        'AC_TYPE_SIGNAL' => 1,
+                        'AC_FUNC_FNMATCH' => 1,
+                        'AC_PROG_CPP' => 1,
+                        'AM_PROG_LIBTOOL' => 1,
+                        'AC_FUNC_STAT' => 1,
+                        'AC_PROG_INSTALL' => 1,
+                        'AM_GNU_GETTEXT' => 1,
+                        'AC_FUNC_STRCOLL' => 1,
+                        'AC_LIBSOURCE' => 1,
+                        'AC_C_INLINE' => 1,
+                        'AC_FUNC_CHOWN' => 1,
+                        'AC_PROG_LEX' => 1,
+                        'AH_OUTPUT' => 1,
+                        'AC_HEADER_STDC' => 1,
+                        'AC_FUNC_GETLOADAVG' => 1,
+                        'AC_CHECK_FUNCS' => 1,
+                        'AC_TYPE_SIZE_T' => 1,
+                        'AC_DECL_SYS_SIGLIST' => 1,
+                        'AC_FUNC_MKTIME' => 1,
+                        'AC_PROG_MAKE_SET' => 1,
+                        'AC_PROG_CXX' => 1,
+                        'm4_pattern_allow' => 1,
+                        'm4_include' => 1,
+                        'm4_pattern_forbid' => 1,
+                        'AC_PROG_AWK' => 1,
+                        'AC_FUNC_VPRINTF' => 1,
+                        'AC_CONFIG_HEADERS' => 1,
+                        'AC_PATH_X' => 1,
+                        'AC_TYPE_OFF_T' => 1,
+                        'AC_FUNC_MALLOC' => 1,
+                        'AC_FUNC_ERROR_AT_LINE' => 1,
+                        'AC_FUNC_FSEEKO' => 1,
+                        'AC_FUNC_MMAP' => 1,
+                        'AC_STRUCT_TM' => 1,
+                        'AC_SUBST' => 1,
+                        'AC_PROG_CC' => 1,
+                        'AC_PROG_LIBTOOL' => 1
+                      }
+                    ], 'Request' )
+           );
+
diff --git a/rt/autom4te.cache/traces.0 b/rt/autom4te.cache/traces.0
new file mode 100644 (file)
index 0000000..962f400
--- /dev/null
@@ -0,0 +1,156 @@
+m4trace:configure.ac:9: -1- m4_pattern_forbid([^_?A[CHUM]_])
+m4trace:configure.ac:9: -1- m4_pattern_forbid([_AC_])
+m4trace:configure.ac:9: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs. LIBOBJS'])
+m4trace:configure.ac:9: -1- m4_pattern_allow([^AS_FLAGS$])
+m4trace:configure.ac:9: -1- m4_pattern_forbid([^_?m4_])
+m4trace:configure.ac:9: -1- m4_pattern_forbid([^dnl$])
+m4trace:configure.ac:9: -1- m4_pattern_forbid([^_?AS_])
+m4trace:configure.ac:9: -1- AC_SUBST([SHELL], [${CONFIG_SHELL-/bin/sh}])
+m4trace:configure.ac:9: -1- AC_SUBST([PATH_SEPARATOR])
+m4trace:configure.ac:9: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME],      ['AC_PACKAGE_NAME'])])
+m4trace:configure.ac:9: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME],   ['AC_PACKAGE_TARNAME'])])
+m4trace:configure.ac:9: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION],   ['AC_PACKAGE_VERSION'])])
+m4trace:configure.ac:9: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING],    ['AC_PACKAGE_STRING'])])
+m4trace:configure.ac:9: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])])
+m4trace:configure.ac:9: -1- AC_SUBST([exec_prefix], [NONE])
+m4trace:configure.ac:9: -1- AC_SUBST([prefix], [NONE])
+m4trace:configure.ac:9: -1- AC_SUBST([program_transform_name], [s,x,x,])
+m4trace:configure.ac:9: -1- AC_SUBST([bindir], ['${exec_prefix}/bin'])
+m4trace:configure.ac:9: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin'])
+m4trace:configure.ac:9: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec'])
+m4trace:configure.ac:9: -1- AC_SUBST([datadir], ['${prefix}/share'])
+m4trace:configure.ac:9: -1- AC_SUBST([sysconfdir], ['${prefix}/etc'])
+m4trace:configure.ac:9: -1- AC_SUBST([sharedstatedir], ['${prefix}/com'])
+m4trace:configure.ac:9: -1- AC_SUBST([localstatedir], ['${prefix}/var'])
+m4trace:configure.ac:9: -1- AC_SUBST([libdir], ['${exec_prefix}/lib'])
+m4trace:configure.ac:9: -1- AC_SUBST([includedir], ['${prefix}/include'])
+m4trace:configure.ac:9: -1- AC_SUBST([oldincludedir], ['/usr/include'])
+m4trace:configure.ac:9: -1- AC_SUBST([infodir], ['${prefix}/info'])
+m4trace:configure.ac:9: -1- AC_SUBST([mandir], ['${prefix}/man'])
+m4trace:configure.ac:9: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME])
+m4trace:configure.ac:9: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */
+#undef PACKAGE_NAME])
+m4trace:configure.ac:9: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME])
+m4trace:configure.ac:9: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME])
+m4trace:configure.ac:9: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION])
+m4trace:configure.ac:9: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */
+#undef PACKAGE_VERSION])
+m4trace:configure.ac:9: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING])
+m4trace:configure.ac:9: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING])
+m4trace:configure.ac:9: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT])
+m4trace:configure.ac:9: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT])
+m4trace:configure.ac:9: -1- AC_SUBST([build_alias])
+m4trace:configure.ac:9: -1- AC_SUBST([host_alias])
+m4trace:configure.ac:9: -1- AC_SUBST([target_alias])
+m4trace:configure.ac:9: -1- AC_SUBST([DEFS])
+m4trace:configure.ac:9: -1- AC_SUBST([ECHO_C])
+m4trace:configure.ac:9: -1- AC_SUBST([ECHO_N])
+m4trace:configure.ac:9: -1- AC_SUBST([ECHO_T])
+m4trace:configure.ac:9: -1- AC_SUBST([LIBS])
+m4trace:configure.ac:14: -1- AC_SUBST([rt_version_major], [3])
+m4trace:configure.ac:16: -1- AC_SUBST([rt_version_minor], [0])
+m4trace:configure.ac:18: -1- AC_SUBST([rt_version_patch], [4])
+m4trace:configure.ac:24: -1- AC_PROG_INSTALL
+m4trace:configure.ac:24: -1- AC_SUBST([INSTALL_PROGRAM])
+m4trace:configure.ac:24: -1- AC_SUBST([INSTALL_SCRIPT])
+m4trace:configure.ac:24: -1- AC_SUBST([INSTALL_DATA])
+m4trace:configure.ac:25: -1- AC_SUBST([PERL])
+m4trace:configure.ac:26: -1- AC_SUBST([PERL], [$ac_cv_path_PERL])
+m4trace:configure.ac:36: -1- AC_SUBST([SPEEDY_BIN])
+m4trace:configure.ac:41: -1- AC_SUBST([prefix])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_prefix])
+m4trace:configure.ac:41: -1- AC_SUBST([exec_prefix])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_exec_prefix])
+m4trace:configure.ac:41: -1- AC_SUBST([bindir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_bindir])
+m4trace:configure.ac:41: -1- AC_SUBST([sbindir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_sbindir])
+m4trace:configure.ac:41: -1- AC_SUBST([sysconfdir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_sysconfdir])
+m4trace:configure.ac:41: -1- AC_SUBST([mandir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_mandir])
+m4trace:configure.ac:41: -1- AC_SUBST([libdir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_libdir])
+m4trace:configure.ac:41: -1- AC_SUBST([datadir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_datadir])
+m4trace:configure.ac:41: -1- AC_SUBST([htmldir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_htmldir])
+m4trace:configure.ac:41: -1- AC_SUBST([manualdir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_manualdir])
+m4trace:configure.ac:41: -1- AC_SUBST([localstatedir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_localstatedir])
+m4trace:configure.ac:41: -1- AC_SUBST([logfiledir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_logfiledir])
+m4trace:configure.ac:41: -1- AC_SUBST([masonstatedir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_masonstatedir])
+m4trace:configure.ac:41: -1- AC_SUBST([sessionstatedir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_sessionstatedir])
+m4trace:configure.ac:41: -1- AC_SUBST([customdir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_customdir])
+m4trace:configure.ac:41: -1- AC_SUBST([custometcdir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_custometcdir])
+m4trace:configure.ac:41: -1- AC_SUBST([customhtmldir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_customhtmldir])
+m4trace:configure.ac:41: -1- AC_SUBST([customlexdir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_customlexdir])
+m4trace:configure.ac:41: -1- AC_SUBST([customlibdir])
+m4trace:configure.ac:41: -1- AC_SUBST([exp_customlibdir])
+m4trace:configure.ac:41: -1- AC_SUBST([rt_layout_name])
+m4trace:configure.ac:49: -1- AC_SUBST([RTGROUP])
+m4trace:configure.ac:57: -1- AC_SUBST([BIN_OWNER])
+m4trace:configure.ac:65: -1- AC_SUBST([LIBS_OWNER])
+m4trace:configure.ac:73: -1- AC_SUBST([LIBS_GROUP])
+m4trace:configure.ac:84: -1- AC_SUBST([DB_TYPE])
+m4trace:configure.ac:92: -1- AC_SUBST([DB_HOST])
+m4trace:configure.ac:100: -1- AC_SUBST([DB_PORT])
+m4trace:configure.ac:108: -1- AC_SUBST([DB_RT_HOST])
+m4trace:configure.ac:116: -1- AC_SUBST([DB_DBA])
+m4trace:configure.ac:124: -1- AC_SUBST([DB_DATABASE])
+m4trace:configure.ac:132: -1- AC_SUBST([DB_RT_USER])
+m4trace:configure.ac:140: -1- AC_SUBST([DB_RT_PASS])
+m4trace:configure.ac:148: -1- AC_SUBST([WEB_USER])
+m4trace:configure.ac:156: -1- AC_SUBST([WEB_GROUP])
+m4trace:configure.ac:163: -1- AC_SUBST([RT_VERSION_MAJOR], [${rt_version_major}])
+m4trace:configure.ac:164: -1- AC_SUBST([RT_VERSION_MINOR], [${rt_version_minor}])
+m4trace:configure.ac:165: -1- AC_SUBST([RT_VERSION_PATCH], [${rt_version_patch}])
+m4trace:configure.ac:168: -1- AC_SUBST([RT_PATH], [${exp_prefix}])
+m4trace:configure.ac:169: -1- AC_SUBST([RT_DOC_PATH], [${exp_manualdir}])
+m4trace:configure.ac:170: -1- AC_SUBST([RT_LOCAL_PATH], [${exp_customdir}])
+m4trace:configure.ac:171: -1- AC_SUBST([RT_LIB_PATH], [${exp_libdir}])
+m4trace:configure.ac:172: -1- AC_SUBST([RT_ETC_PATH], [${exp_sysconfdir}])
+m4trace:configure.ac:173: -1- AC_SUBST([CONFIG_FILE_PATH], [${exp_sysconfdir}])
+m4trace:configure.ac:174: -1- AC_SUBST([RT_BIN_PATH], [${exp_bindir}])
+m4trace:configure.ac:175: -1- AC_SUBST([RT_SBIN_PATH], [${exp_sbindir}])
+m4trace:configure.ac:176: -1- AC_SUBST([RT_VAR_PATH], [${exp_localstatedir}])
+m4trace:configure.ac:177: -1- AC_SUBST([RT_MAN_PATH], [${exp_mandir}])
+m4trace:configure.ac:178: -1- AC_SUBST([MASON_DATA_PATH], [${exp_masonstatedir}])
+m4trace:configure.ac:179: -1- AC_SUBST([MASON_SESSION_PATH], [${exp_sessionstatedir}])
+m4trace:configure.ac:180: -1- AC_SUBST([MASON_HTML_PATH], [${exp_htmldir}])
+m4trace:configure.ac:181: -1- AC_SUBST([LOCAL_ETC_PATH], [${exp_custometcdir}])
+m4trace:configure.ac:182: -1- AC_SUBST([MASON_LOCAL_HTML_PATH], [${exp_customhtmldir}])
+m4trace:configure.ac:183: -1- AC_SUBST([LOCAL_LEXICON_PATH], [${exp_customlexdir}])
+m4trace:configure.ac:184: -1- AC_SUBST([LOCAL_LIB_PATH], [${exp_customlibdir}])
+m4trace:configure.ac:185: -1- AC_SUBST([DESTDIR], [${exp_prefix}])
+m4trace:configure.ac:186: -1- AC_SUBST([RT_LOG_PATH], [${exp_logfiledir}])
+m4trace:configure.ac:208: -1- AC_CONFIG_FILES([
+                sbin/rt-setup-database
+                 sbin/rt-test-dependencies
+                 Makefile
+                etc/RT_Config.pm
+                lib/RT.pm
+                 lib/t/00smoke.t
+                 lib/t/01harness.t
+                 lib/t/02regression.t
+                 lib/t/03web.pl
+                 lib/t/04_send_email.pl
+                bin/mason_handler.fcgi
+                bin/mason_handler.scgi
+                bin/mason_handler.svc
+                bin/rt-commit-handler
+                bin/rt-crontool
+                bin/rt-mailgate
+                bin/webmux.pl
+                ])
diff --git a/rt/bin/initacls.Oracle b/rt/bin/initacls.Oracle
deleted file mode 100644 (file)
index 8d05f45..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-DATABASEHOME=$1
-HOSTNAME=$2
-PORT=$3
-DATABASEADMIN=$4
-DBAPASSWD=$5
-DATABASENAME=$6
-DATABASEACLS=$7
-
-BINDIR=${DATABASEHOME}/bin
-
-echo "DBHOME = $DATABASEHOME"
-echo "HOSTNAME = $HOSTNAME"
-echo "PORT = $PORT"
-echo "DATABASEADMIN = $DATABASEADMIN"
-echo "DBAPASSWD = $DBAPASSWD"
-echo "DATABASENAME = $DATABASENAME"
-
-PATH=$PATH:$BINDIR
-export PATH
-
-echo "Please enter ${DATABASEADMIN}'s  password for the SID ${DATABASENAME} to create an rt user";
-
-$BINDIR/sqlplus ${DATABASEADMIN}@${DATABASENAME}  @$DATABASEACLS
-
diff --git a/rt/bin/initacls.Pg b/rt/bin/initacls.Pg
deleted file mode 100755 (executable)
index 82e32de..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-DATABASEHOME=$1
-HOSTNAME=$2
-PORT=$3
-DATABASEADMIN=$4
-DBAPASSWD=$5
-DATABASENAME=$6
-DATABASEACLS=$7
-
-BINDIR=${DATABASEHOME}/bin
-
-
-PATH=$PATH:$BINDIR
-export PATH
-
-echo "Enter the postgres administrator's database password to create a new user for rt"
-
-if [ "fnord$PORT" != "fnord" ]; then
-       PORT="-p $PORT"
-fi;
-
-if [ "fnord$HOSTNAME" != "fnord" ]; then
-       HOSTNAME="-h $HOSTNAME"
-fi;
-
-psql $HOSTNAME $PORT -d $DATABASENAME -f $DATABASEACLS -U $DATABASEADMIN
-
diff --git a/rt/bin/initacls.mysql b/rt/bin/initacls.mysql
deleted file mode 100755 (executable)
index 17e63f8..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-
-DATABASEHOME=$1
-HOSTNAME=$2
-PORT=$3
-DATABASEADMIN=$4
-DBAPASSWD=$5
-DATABASENAME=$6
-DATABASEACLS=$7
-
-BINDIR=${DATABASEHOME}/bin
-
-PATH=$PATH:$BINDIR
-export PATH
-
-echo "Enter the mysql administrator's database password to create a new user for RT"
-$BINDIR/mysql --host=${HOSTNAME} --port=${PORT} --user=${DATABASEADMIN} -p${DBAPASSWD} mysql < $DATABASEACLS
-
-echo "Enter the mysql administrator's database password to nondestructively reload the database"
-$BINDIR/mysqladmin --host=${HOSTNAME} --port=${PORT} --user=${DATABASEADMIN} -p${DBAPASSWD} reload
index e8a4e12..431eccb 100755 (executable)
-#!!!PERL!!
-# $Header: /home/cvs/cvsroot/freeside/rt/bin/mason_handler.fcgi,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# RT is (c) 1996-2001 Jesse Vincent (jesse@fsck.com);
+#!/usr/bin/perl
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 
 use strict;
-$ENV{'PATH'} = '/bin:/usr/bin';    # or whatever you need
-$ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
-$ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'};
-$ENV{'ENV'} = '' if defined $ENV{'ENV'};
-$ENV{'IFS'} = ''          if defined $ENV{'IFS'};
+use File::Basename;
+require ('/opt/rt3/bin/webmux.pl');
 
+my $h = &RT::Interface::Web::NewCGIHandler();
 
-# We really don't want apache to try to eat all vm
-# see http://perl.apache.org/guide/control.html#Preventing_mod_perl_Processes_Fr
-
-
-package RT::Mason;
-#use CGI qw(-private_tempfiles);   # pull in CGI with the private tempfiles
-                                 #option predefined
-use HTML::Mason;  # brings in subpackages: Parser, Interp, etc.
-
-use vars qw($VERSION %session $Nobody $SystemUser $cgi);
-
-# List of modules that you want to use from components (see Admin
-# manual for details)
-
-#Clean up our umask...so that the session files aren't world readable, writable or executable
-umask(0077);
-
-
-  
-$VERSION="!!RT_VERSION!!";
-
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
-
-#This drags in  RT's config.pm
-use config;
-use Carp;
-
-{  
-    package HTML::Mason::Commands;
-    use vars qw(%session $ContentType);
-    
-    use RT; 
-    use RT::Ticket;
-    use RT::Tickets;
-    use RT::Transaction;
-    use RT::Transactions;
-    use RT::User;
-    use RT::Users;
-    use RT::CurrentUser;
-    use RT::Template;
-    use RT::Templates;
-    use RT::Queue;
-    use RT::Queues;
-    use RT::ScripAction;
-    use RT::ScripActions;
-    use RT::ScripCondition;
-    use RT::ScripConditions;
-    use RT::Scrip;
-    use RT::Scrips;
-    use RT::Group;
-    use RT::Groups;
-    use RT::Keyword;
-    use RT::Keywords;
-    use RT::ObjectKeyword;
-    use RT::ObjectKeywords;
-    use RT::KeywordSelect;
-    use RT::KeywordSelects;
-    use RT::GroupMember;
-    use RT::GroupMembers;
-    use RT::Watcher;
-    use RT::Watchers;
-    use RT::Handle;
-    use RT::Interface::Web;    
-    use MIME::Entity;
-    use CGI::Cookie;
-    use Date::Parse;
-    use HTML::Entities;
-    use Text::Wrapper;
-    #TODO: make this use DBI
-    use Apache::Session::File;
-    use CGI::Fast;
-
-    # set the page's content type.
-    # In this case, just save it to a variable that we can pull later;
-    sub SetContentType {
-       $ContentType = shift;
-    }
-    sub CGIObject {
-       return $RT::Mason::cgi;
-    }
-}
-
-
-my ($output, $parser, $interp);
-if ($HTML::Mason::VERSION < 1.0902) {
-        require HTML::Mason::ApacheHandler;
-
-         $parser = &RT::Interface::Web::NewParser(allow_globals => [%session]);
-
-         $interp = &RT::Interface::Web::NewInterp(parser=>$parser,
-                                             allow_recursive_autohandlers => 1,
-                                           out_method => \$output);
-}
-else {
-         $interp = &RT::Interface::Web::NewInterp(
-                                                  allow_globals => [%session],
-                                                  default_escape_flags => 'h',
-
-                                           out_method => \$output);
-}
-# Die if WebSessionDir doesn't exist or we can't write to it
-
-stat ($RT::MasonSessionDir);
-die "Can't read and write $RT::MasonSessionDir"
-  unless (( -d _ ) and ( -r _ ) and ( -w _ ));
-
+# Enter CGI::Fast mode, which should also work as a vanilla CGI script.
+require CGI::Fast;
 
 RT::Init();
 
 # Response loop
-while ($RT::Mason::cgi = new CGI::Fast) {
-    
-    $HTML::Mason::Commands::ContentType = 'text/html';
-        
-    # This routine comes from ApacheHandler.pm:
-    my (%args, $cookie);
-    foreach my $key ( $cgi->param ) {
-       foreach my $value ( $cgi->param($key) ) {
-           if (exists($args{$key})) {
-               if (ref($args{$key})) {
-                   $args{$key} = [@{$args{$key}}, $value];
-               } else {
-                   $args{$key} = [$args{$key}, $value];
-               }
-           } else {
-               $args{$key} = $value;
-           }
-
-       }
-       
-    }
-    
-
-    my $comp = $ENV{'PATH_INFO'};
-    
-    if ($comp =~ /^(.*)$/) {  # untaint the path info. apache should
-                             # never hand us a bogus path. 
-                             # We should be more careful here.
-       $comp = $1;
-    }    
-    
-    if ($comp =~ /\/$/) {
-       $comp .= "index.html";
-    }  
-    
-    #This is all largely cut and pasted from mason's session_handler.pl
-    
-    # {{{ Cookies
-    my %cookies = fetch CGI::Cookie();
-    
-    eval {
-       my $session_id = undef;
-
-       #Get the session id and untaint it
-       if ($cookies{'AF_SID'} && $cookies{'AF_SID'}->value() =~ /^(.*)$/) {
-               $session_id = $1;
-       }
-       tie %HTML::Mason::Commands::session, 'Apache::Session::File',
-               $session_id, 
-           { Directory => $RT::MasonSessionDir,
-             LockDirectory => $RT::MasonSessionDir,
-           }   ;
-    };
-    
-    if ( $@ ) {
-       # If the session is invalid, create a new session.
-       if ( $@ =~ m#^Object does not exist in the data store# ) {
-            tie %HTML::Mason::Commands::session, 'Apache::Session::File', undef,
-            { Directory => $RT::MasonSessionDir,
-              LockDirectory => $RT::MasonSessionDir,
-            };
-            undef $cookies{'AF_SID'};
-       }
-         else {
-             die "$@ \nProbably means that RT Couldn't write to session directory '$RT::MasonSessionDir'. Check that this directory's permissions are correct.";
-         }
+while ( my $cgi = CGI::Fast->new ) {
+    # the whole point of fastcgi requires the env to get reset here..
+    # So we must squash it again
+    $ENV{'PATH'}   = '/bin:/usr/bin';
+    $ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
+    $ENV{'SHELL'}  = '/bin/sh' if defined $ENV{'SHELL'};
+    $ENV{'ENV'}    = '' if defined $ENV{'ENV'};
+    $ENV{'IFS'}    = '' if defined $ENV{'IFS'};
+
+    unless ($h->interp->comp_exists($cgi->path_info)) {
+       $cgi->path_info($cgi->path_info . "/index.html");
     }
-    
-    if ( !$cookies{'AF_SID'} ) {
-       $cookie = new CGI::Cookie
-         (-name=>'AF_SID', 
-          -value=>$HTML::Mason::Commands::session{_session_id}, 
-          -path => '/',);
-       
-    } else {
-       $cookie = undef;
-    }
-    
-    # }}}
-    
-    $output = '';
-    eval {
-           my $status = $interp->exec($comp, %args);
-    };
-    if ($@) {
-       $output = "<PRE>$@</PRE>";
-    }
-    print "Content-Type: $HTML::Mason::Commands::ContentType\r\n";
-    print "Set-Cookie: $cookie\r\n" if ($cookie);
-    print "\r\n";
-    print $output;
-    untie %HTML::Mason::Commands::session;
-    
+    $h->handle_cgi_object($cgi);
+    # _should_ always be tied
 }
+
+1;
diff --git a/rt/bin/mason_handler.fcgi.in b/rt/bin/mason_handler.fcgi.in
new file mode 100644 (file)
index 0000000..e932bfc
--- /dev/null
@@ -0,0 +1,54 @@
+#!@PERL@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+use strict;
+use File::Basename;
+require ('@RT_BIN_PATH@/webmux.pl');
+
+my $h = &RT::Interface::Web::NewCGIHandler();
+
+# Enter CGI::Fast mode, which should also work as a vanilla CGI script.
+require CGI::Fast;
+
+RT::Init();
+
+# Response loop
+while ( my $cgi = CGI::Fast->new ) {
+    # the whole point of fastcgi requires the env to get reset here..
+    # So we must squash it again
+    $ENV{'PATH'}   = '/bin:/usr/bin';
+    $ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
+    $ENV{'SHELL'}  = '/bin/sh' if defined $ENV{'SHELL'};
+    $ENV{'ENV'}    = '' if defined $ENV{'ENV'};
+    $ENV{'IFS'}    = '' if defined $ENV{'IFS'};
+
+    unless ($h->interp->comp_exists($cgi->path_info)) {
+       $cgi->path_info($cgi->path_info . "/index.html");
+    }
+    $h->handle_cgi_object($cgi);
+    # _should_ always be tied
+}
+
+1;
index b9846c8..8e1135c 100755 (executable)
-#!!!PERL!! -w
-
-#!/usr/bin/speedy -- -t600 -M8
-# $Header: /home/cvs/cvsroot/freeside/rt/bin/mason_handler.scgi,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# RT is (c) 1996-2001 Jesse Vincent (jesse@fsck.com);
-#
-# Contains code derived from mason.cgi
-# mason.cgi is Copyright December 2000 Joshua Kronengold (mneme@io.com, 
-# mneme@cyberspace.org).  All Rights Reserved.
+#!/usr/local/bin/speedy
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 
 use strict;
-# {{{ Clean out the environment a little bit
-$ENV{'PATH'} = '/bin:/usr/bin';    # or whatever you need
-$ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
-$ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'};
-$ENV{'ENV'} = '' if defined $ENV{'ENV'};
-$ENV{'IFS'} = ''          if defined $ENV{'IFS'};
-# }}}
-
-package RT::Mason;
-use HTML::Mason;  # brings in subpackages: Parser, Interp, etc.
-use vars qw($VERSION %session $Nobody $SystemUser);
-
-# List of modules that you want to use from components (see Admin
-# manual for details)
-
-$VERSION="!!RT_VERSION!!";
-
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
-
-
-#This drags in  RT's config.pm
-use config;
-use Carp;
-
-use HTML::Mason::FakeApache;
-use CGI;
-
-# {{{ Set up CGI environment and grab CGI params:
+require ('/opt/rt3/bin/webmux.pl');
 
-my $r=new HTML::Mason::FakeApache;
+my $h = &RT::Interface::Web::NewCGIHandler();
 
-$|=1; # set output to non-buffered.
+require CGI;
 
-my %cgi;
-CGI::ReadParse(\%cgi); # %cgi is now a tied hash containing our params.
+RT::Init();
 
-my $q=$cgi{CGI}; # $q now contains the object tied to %cgi.
-# }}}
-
-# {{{ require what we need
-{  
-    package HTML::Mason::Commands;
-
-    use vars qw(%session);
-
-    use RT::Ticket;
-    use RT::Tickets;
-    use RT::Transaction;
-    use RT::Transactions;
-    use RT::User;
-    use RT::Users;
-    use RT::CurrentUser;
-    use RT::Template;
-    use RT::Templates;
-    use RT::Queue;
-    use RT::Queues;
-    use RT::ScripAction;
-    use RT::ScripActions;
-    use RT::ScripCondition;
-    use RT::ScripConditions;
-    use RT::Scrip;
-    use RT::Scrips;
-    use RT::Group;
-    use RT::Groups;
-    use RT::Keyword;
-    use RT::Keywords;
-    use RT::ObjectKeyword;
-    use RT::ObjectKeywords;
-    use RT::KeywordSelect;
-    use RT::KeywordSelects;
-    use RT::GroupMember;
-    use RT::GroupMembers;
-    use RT::Watcher;
-    use RT::Watchers;
-    use RT::Handle;
-    use RT::Interface::Web;    
-    use MIME::Entity;
-    use CGI::Cookie;
-    use Date::Parse;
-    use HTML::Entities;
-
-    
-    use Apache::Session::File;
-
-    
+my $cgi = CGI->new;
+unless ($h->interp->comp_exists($cgi->path_info)) {
+    $cgi->path_info($cgi->path_info . "/index.html");
 }
-# }}}
-
-# {{{ RT Database setup
-    $RT::Handle = new RT::Handle;
-    
-    $RT::Handle->Connect;
-   
-    use RT::CurrentUser;
-    
-    #RT's system user is a genuine database user. its id lives here
-    $RT::SystemUser = new RT::CurrentUser();
-    $RT::SystemUser->LoadByName('RT_System');
-
-    #RT's "nobody user" is a genuine database user. its ID lives here.
-    $RT::Nobody = new RT::CurrentUser();
-    $RT::Nobody->LoadByName('Nobody'); 
-     
-
-# }}}
-
-
-
-
-# {{{ Deal with cookies
-
-my %cookies = fetch CGI::Cookie();
-eval { 
-    tie %HTML::Mason::Commands::session, 'Apache::Session::File',
-      ( $cookies{'AF_SID'} ? $cookies{'AF_SID'}->value() : undef );
-};
-
-if ( $@ ) {
-    # If the session is invalid, create a new session.
-    if ( $@ =~ m#^Object does not exist in the data store# ) {
-        tie %HTML::Mason::Commands::session, 'Apache::Session::File', undef;
-        undef $cookies{'AF_SID'};
-    }
-}
-
-if ( !$cookies{'AF_SID'} ) {
-    my $cookie = new CGI::Cookie(
-        -name=>'AF_SID', 
-        -value=>$HTML::Mason::Commands::session{_session_id}, 
-         -path => '/');
-    print 'Set-Cookie: '. $cookie."\r\n";
-}
-
-# }}}
-
-my $path=$ENV{PATH_INFO} || "/"; $path=~s/\'/\\\'/g;
-
-my $type=`/usr/bin/file '$RT::MasonComponentRoot/$path'`;
-
-# {{{ if it's a text file, handle it with mason.
-if($type=~/text|directory/) { 
-       my ($out, %mason_params);
-        my $parser = RT::Interface::Web::NewParser(allow_globals=>[qw($r)]);
-       $mason_params{parser}=$parser;
-       $r->content_type('text/html');
-       # (get cookies line) ...
-       $r->access_hash('headers_in','Cookie',$ENV{HTTP_COOKIE});
-       $r->{'args@'}=[];
-       $mason_params{out_method}=\$out;
-
-       my $interp = RT::Interface::Web::NewInterp(%mason_params);
-
-       $interp->set_global(r=>$r);
-       $interp->exec($path,%cgi);
-       $r->send_http_header();
-        print $out;
-} 
-# }}} 
-
-# {{{ if it's not a text file, just stream it out.
-
-else { # file is binary, damn it
-       my $mime_type;
-       if ( $mime_type=
-            eval{ use MIME::Types;
-                  my($type,$encoding)=MIME::Types::by_suffix($path);
-                  $type; }) {
-           print $q->header($mime_type);       
-           $path=~s/[\|\>\<\&]//g;
-           open F,"$RT::MasonComponentRoot/$path" or 
-             die "couldn't open $path -- $!";
-           print while <F>; 
-           close F;
-       } else {
-           die "couldn't resolve type of non-text file (!@; $type) -- install Mime::Types\n";
-       }
-    }
-
-# }}}
+$h->handle_cgi_object($cgi);
 
-untie %HTML::Mason::Commands::session;
+1;
diff --git a/rt/bin/mason_handler.scgi.in b/rt/bin/mason_handler.scgi.in
new file mode 100644 (file)
index 0000000..37d8380
--- /dev/null
@@ -0,0 +1,41 @@
+#!@SPEEDY_BIN@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+use strict;
+require ('@RT_BIN_PATH@/webmux.pl');
+
+my $h = &RT::Interface::Web::NewCGIHandler();
+
+require CGI;
+
+RT::Init();
+
+my $cgi = CGI->new;
+unless ($h->interp->comp_exists($cgi->path_info)) {
+    $cgi->path_info($cgi->path_info . "/index.html");
+}
+$h->handle_cgi_object($cgi);
+
+1;
diff --git a/rt/bin/mason_handler.svc b/rt/bin/mason_handler.svc
new file mode 100644 (file)
index 0000000..e6d8378
--- /dev/null
@@ -0,0 +1,234 @@
+#!/usr/bin/perl
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+=head1 NAME
+
+mason_handler.svc - Win32 IIS Service handler for RT
+
+=head1 SYNOPSIS
+
+    perl mason_handler.svc --install   # install as service
+    perl mason_handler.svc --deinstall # deinstall this service
+    perl mason_handler.svc --help      # show this help
+    perl mason_handler.svc             # launch handler from command line
+
+=head1 DESCRIPTION
+
+This script manages a stand-alone FastCGI server, and populates the necessary
+registry settings to run it with Microsoft IIS Server 4.0 or above.
+
+Before running it, you need to install the B<FCGI> module from CPAN, as well as
+B<Win32::Daemon> from L<http://www.roth.net/perl/Daemon/> if you want to install
+itself as a service.
+
+This script will automatically create a virtual directory under the IIS root;
+its name is taken from C<$WebPath> in the F<RT_Config.pm> file.  Additionally,
+please install the ISAPI binary from L<http://www.caraveo.com/fastcgi/> and set
+up an ISAPI Script Map that maps F<.html> files to F<isapi_fcgi.dll>.
+
+Once the service is launched (either via C<net start RTFastCGI> or by running
+C<perl mason_handler.svc>), a FCGI server will start and bind to port C<8284>
+(mnemonics: the ASCII value of C<R> and C<T>); the ISAPI handler's C<BindPath>
+registry setting will also be automatically populated.
+
+=cut
+
+use strict;
+use File::Basename;
+require (dirname(__FILE__) . '/webmux.pl');
+
+use Cwd;
+use File::Spec;
+
+use Win32;
+use Win32::Process;
+use Win32::Service;
+use Win32::TieRegistry;
+
+my $ProcessObj;
+
+BEGIN {
+    my $runsvc = sub {
+       Win32::Process::Create(
+           $ProcessObj, $^X, "$^X $0 --run", 0, NORMAL_PRIORITY_CLASS, "."
+       ) or do {
+           die Win32::FormatMessage( Win32::GetLastError() );
+       };
+
+       chdir File::Basename::dirname($0);
+       my $path = Cwd::cwd();
+       $path =~ s|/|\\|g;
+       $path =~ s|bin$|share\\html|;
+
+       $Win32::TieRegistry::Registry->{
+           'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\\'.
+           'W3SVC\Parameters\Virtual Roots\\'
+       }->{$RT::WebPath || '/'} = "$path,,205";
+           
+       $Win32::TieRegistry::Registry->{
+           'HKEY_LOCAL_MACHINE\Software\FASTCGI\.html\\'
+       }->{'BindPath'} = $ENV{'FCGI_SOCKET_PATH'};
+
+       Win32::Service::StartService(Win32::NodeName, 'W3SVC');
+    };
+    
+    if ($ARGV[0] eq '--deinstall') {
+       chdir File::Basename::dirname($0);
+       my $path = Cwd::cwd();
+       $path =~ s|/|\\|g;
+
+       require Win32::Daemon;
+       Win32::Daemon::DeleteService('RTFastCGI');
+       warn "Service 'RTFastCGI' successfully deleted.\n";
+       exit;
+    }
+    elsif ($ARGV[0] eq '--install') {
+       chdir File::Basename::dirname($0);
+       my $path = Cwd::cwd();
+       $path =~ s|/|\\|g;
+
+       require Win32::Daemon;
+       Win32::Daemon::DeleteService('RTFastCGI');
+       
+       my $rv = Win32::Daemon::CreateService( {
+           machine =>  '',
+           name    =>  'RTFastCGI',
+           display =>  'RT FastCGI Handler',
+           path    =>  $^X,
+           user    =>  '',
+           pwd     =>  $path,
+           description => 'Enables port 8284 as the RT FastCGI handler.',
+           parameters  => File::Spec->catfile(
+                   $path, File::Basename::basename($0)
+           ) . ' --service',
+       } );
+    
+       if ($rv) {
+           warn "Service 'RTFastCGI' successfully created.\n";
+       }
+       else {
+           warn "Failed to add service: " . Win32::FormatMessage(
+               Win32::Daemon::GetLastError()
+           ) . "\n";
+       }
+       exit;
+    }
+    elsif ($ARGV[0] eq '--service') {
+       require Win32::Daemon;
+
+       my $PrevState = Win32::Daemon::SERVICE_START_PENDING();
+       Win32::Daemon::StartService() or die $^E;
+
+       while ( 1 ) {
+           my $State = Win32::Daemon::State();
+           last if $State == Win32::Daemon::SERVICE_STOPPED();
+           
+           if ( $State == Win32::Daemon::SERVICE_START_PENDING() ) {
+               $runsvc->();
+               Win32::Daemon::State( Win32::Daemon::SERVICE_RUNNING() );
+               $PrevState = Win32::Daemon::SERVICE_RUNNING();
+           }
+           elsif ( $State == Win32::Daemon::SERVICE_CONTINUE_PENDING() ) {
+               $ProcessObj->Resume;
+               Win32::Daemon::State( Win32::Daemon::SERVICE_RUNNING() );
+               $PrevState = Win32::Daemon::SERVICE_RUNNING();
+           }
+           elsif ( $State == Win32::Daemon::SERVICE_STOP_PENDING() ) {
+           $ProcessObj->Kill(0);
+               Win32::Daemon::State( Win32::Daemon::SERVICE_STOPPED() );
+               $PrevState = Win32::Daemon::SERVICE_STOPPED();
+           }
+           elsif ( $State == Win32::Daemon::SERVICE_RUNNING() ) {
+               my $Message = Win32::Daemon::QueryLastMessage(1);
+               if ( $Message == Win32::Daemon::SERVICE_CONTROL_INTERROGATE() ) {
+                   Win32::Daemon::State( $PrevState );
+               }
+               elsif ( $Message == Win32::Daemon::SERVICE_CONTROL_SHUTDOWN() ) {
+                   Win32::Daemon::State( Win32::Daemon::SERVICE_STOP_PENDING(), 15000 );
+               }
+               elsif ( $Message != Win32::Daemon::SERVICE_CONTROL_NONE() ) {
+                   Win32::Daemon::State( $PrevState );
+               }
+           }
+           
+           Win32::Sleep( 1000 );
+       }
+               
+       Win32::Daemon::StopService();
+       exit;
+    }
+    elsif ($ARGV[0] eq '--help') {
+       system("perldoc $0");
+       exit;
+    }
+    elsif ($ARGV[0] ne '--run') {
+       $SIG{__DIE__} = sub { $ProcessObj->Kill(0) if $ProcessObj };
+       $runsvc->();
+       warn "RT FastCGI Handler launched. Press [Enter] to terminate...\n";
+       <STDIN>;
+       exit;
+    }
+}
+
+###############################################################################
+
+warn "Begin listening on $ENV{'FCGI_SOCKET_PATH'}\n";
+
+require CGI::Fast;
+my $h = &RT::Interface::Web::NewCGIHandler();
+
+RT::Init();
+
+# Response loop
+while( my $cgi = CGI::Fast->new ) {
+    my $comp = $ENV{'PATH_INFO'};
+
+    $comp = $1 if ($comp =~ /^(.*)$/);
+    $comp =~ s|^$RT::WebPath\b||i;
+    $comp .= "index.html" if ($comp =~ /\/$/);
+    $comp =~ s/.pl$/.html/g;
+    
+    warn "Serving $comp\n";
+
+    $h->handle_cgi($comp);
+    # _should_ always be tied
+}
+
+1;
+
+=head1 AUTHORS
+
+Autrijus Tang E<lt>autrijus@autrijus.orgE<gt>
+
+=head1 COPYRIGHT
+
+Copyright 2002 by Autrijus Tang E<lt>autrijus@autrijus.orgE<gt>.
+
+This program is free software; you can redistribute it and/or 
+modify it under the same terms as Perl itself.
+
+See L<http://www.perl.com/perl/misc/Artistic.html>
+
+=cut
diff --git a/rt/bin/mason_handler.svc.in b/rt/bin/mason_handler.svc.in
new file mode 100644 (file)
index 0000000..cc12c0e
--- /dev/null
@@ -0,0 +1,234 @@
+#!@PERL@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+=head1 NAME
+
+mason_handler.svc - Win32 IIS Service handler for RT
+
+=head1 SYNOPSIS
+
+    perl mason_handler.svc --install   # install as service
+    perl mason_handler.svc --deinstall # deinstall this service
+    perl mason_handler.svc --help      # show this help
+    perl mason_handler.svc             # launch handler from command line
+
+=head1 DESCRIPTION
+
+This script manages a stand-alone FastCGI server, and populates the necessary
+registry settings to run it with Microsoft IIS Server 4.0 or above.
+
+Before running it, you need to install the B<FCGI> module from CPAN, as well as
+B<Win32::Daemon> from L<http://www.roth.net/perl/Daemon/> if you want to install
+itself as a service.
+
+This script will automatically create a virtual directory under the IIS root;
+its name is taken from C<$WebPath> in the F<RT_Config.pm> file.  Additionally,
+please install the ISAPI binary from L<http://www.caraveo.com/fastcgi/> and set
+up an ISAPI Script Map that maps F<.html> files to F<isapi_fcgi.dll>.
+
+Once the service is launched (either via C<net start RTFastCGI> or by running
+C<perl mason_handler.svc>), a FCGI server will start and bind to port C<8284>
+(mnemonics: the ASCII value of C<R> and C<T>); the ISAPI handler's C<BindPath>
+registry setting will also be automatically populated.
+
+=cut
+
+use strict;
+use File::Basename;
+require (dirname(__FILE__) . '/webmux.pl');
+
+use Cwd;
+use File::Spec;
+
+use Win32;
+use Win32::Process;
+use Win32::Service;
+use Win32::TieRegistry;
+
+my $ProcessObj;
+
+BEGIN {
+    my $runsvc = sub {
+       Win32::Process::Create(
+           $ProcessObj, $^X, "$^X $0 --run", 0, NORMAL_PRIORITY_CLASS, "."
+       ) or do {
+           die Win32::FormatMessage( Win32::GetLastError() );
+       };
+
+       chdir File::Basename::dirname($0);
+       my $path = Cwd::cwd();
+       $path =~ s|/|\\|g;
+       $path =~ s|bin$|share\\html|;
+
+       $Win32::TieRegistry::Registry->{
+           'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\\'.
+           'W3SVC\Parameters\Virtual Roots\\'
+       }->{$RT::WebPath || '/'} = "$path,,205";
+           
+       $Win32::TieRegistry::Registry->{
+           'HKEY_LOCAL_MACHINE\Software\FASTCGI\.html\\'
+       }->{'BindPath'} = $ENV{'FCGI_SOCKET_PATH'};
+
+       Win32::Service::StartService(Win32::NodeName, 'W3SVC');
+    };
+    
+    if ($ARGV[0] eq '--deinstall') {
+       chdir File::Basename::dirname($0);
+       my $path = Cwd::cwd();
+       $path =~ s|/|\\|g;
+
+       require Win32::Daemon;
+       Win32::Daemon::DeleteService('RTFastCGI');
+       warn "Service 'RTFastCGI' successfully deleted.\n";
+       exit;
+    }
+    elsif ($ARGV[0] eq '--install') {
+       chdir File::Basename::dirname($0);
+       my $path = Cwd::cwd();
+       $path =~ s|/|\\|g;
+
+       require Win32::Daemon;
+       Win32::Daemon::DeleteService('RTFastCGI');
+       
+       my $rv = Win32::Daemon::CreateService( {
+           machine =>  '',
+           name    =>  'RTFastCGI',
+           display =>  'RT FastCGI Handler',
+           path    =>  $^X,
+           user    =>  '',
+           pwd     =>  $path,
+           description => 'Enables port 8284 as the RT FastCGI handler.',
+           parameters  => File::Spec->catfile(
+                   $path, File::Basename::basename($0)
+           ) . ' --service',
+       } );
+    
+       if ($rv) {
+           warn "Service 'RTFastCGI' successfully created.\n";
+       }
+       else {
+           warn "Failed to add service: " . Win32::FormatMessage(
+               Win32::Daemon::GetLastError()
+           ) . "\n";
+       }
+       exit;
+    }
+    elsif ($ARGV[0] eq '--service') {
+       require Win32::Daemon;
+
+       my $PrevState = Win32::Daemon::SERVICE_START_PENDING();
+       Win32::Daemon::StartService() or die $^E;
+
+       while ( 1 ) {
+           my $State = Win32::Daemon::State();
+           last if $State == Win32::Daemon::SERVICE_STOPPED();
+           
+           if ( $State == Win32::Daemon::SERVICE_START_PENDING() ) {
+               $runsvc->();
+               Win32::Daemon::State( Win32::Daemon::SERVICE_RUNNING() );
+               $PrevState = Win32::Daemon::SERVICE_RUNNING();
+           }
+           elsif ( $State == Win32::Daemon::SERVICE_CONTINUE_PENDING() ) {
+               $ProcessObj->Resume;
+               Win32::Daemon::State( Win32::Daemon::SERVICE_RUNNING() );
+               $PrevState = Win32::Daemon::SERVICE_RUNNING();
+           }
+           elsif ( $State == Win32::Daemon::SERVICE_STOP_PENDING() ) {
+           $ProcessObj->Kill(0);
+               Win32::Daemon::State( Win32::Daemon::SERVICE_STOPPED() );
+               $PrevState = Win32::Daemon::SERVICE_STOPPED();
+           }
+           elsif ( $State == Win32::Daemon::SERVICE_RUNNING() ) {
+               my $Message = Win32::Daemon::QueryLastMessage(1);
+               if ( $Message == Win32::Daemon::SERVICE_CONTROL_INTERROGATE() ) {
+                   Win32::Daemon::State( $PrevState );
+               }
+               elsif ( $Message == Win32::Daemon::SERVICE_CONTROL_SHUTDOWN() ) {
+                   Win32::Daemon::State( Win32::Daemon::SERVICE_STOP_PENDING(), 15000 );
+               }
+               elsif ( $Message != Win32::Daemon::SERVICE_CONTROL_NONE() ) {
+                   Win32::Daemon::State( $PrevState );
+               }
+           }
+           
+           Win32::Sleep( 1000 );
+       }
+               
+       Win32::Daemon::StopService();
+       exit;
+    }
+    elsif ($ARGV[0] eq '--help') {
+       system("perldoc $0");
+       exit;
+    }
+    elsif ($ARGV[0] ne '--run') {
+       $SIG{__DIE__} = sub { $ProcessObj->Kill(0) if $ProcessObj };
+       $runsvc->();
+       warn "RT FastCGI Handler launched. Press [Enter] to terminate...\n";
+       <STDIN>;
+       exit;
+    }
+}
+
+###############################################################################
+
+warn "Begin listening on $ENV{'FCGI_SOCKET_PATH'}\n";
+
+require CGI::Fast;
+my $h = &RT::Interface::Web::NewCGIHandler();
+
+RT::Init();
+
+# Response loop
+while( my $cgi = CGI::Fast->new ) {
+    my $comp = $ENV{'PATH_INFO'};
+
+    $comp = $1 if ($comp =~ /^(.*)$/);
+    $comp =~ s|^$RT::WebPath\b||i;
+    $comp .= "index.html" if ($comp =~ /\/$/);
+    $comp =~ s/.pl$/.html/g;
+    
+    warn "Serving $comp\n";
+
+    $h->handle_cgi($comp);
+    # _should_ always be tied
+}
+
+1;
+
+=head1 AUTHORS
+
+Autrijus Tang E<lt>autrijus@autrijus.orgE<gt>
+
+=head1 COPYRIGHT
+
+Copyright 2002 by Autrijus Tang E<lt>autrijus@autrijus.orgE<gt>.
+
+This program is free software; you can redistribute it and/or 
+modify it under the same terms as Perl itself.
+
+See L<http://www.perl.com/perl/misc/Artistic.html>
+
+=cut
diff --git a/rt/bin/rt b/rt/bin/rt
deleted file mode 100755 (executable)
index 41220bb..0000000
--- a/rt/bin/rt
+++ /dev/null
@@ -1,1391 +0,0 @@
-#!!!PERL!! -w
-#
-# $Header: /home/cvs/cvsroot/freeside/rt/bin/Attic/rt,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# RT is (c) 1996-2001 Jesse Vincent <jesse@bestpractical.com>
-
-use strict;
-use Carp;
-use Getopt::Long;
-
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
-
-use RT::Interface::CLI  qw(CleanEnv LoadConfig DBConnect 
-                          GetCurrentUser GetMessageContent);
-
-#Clean out all the nasties from the environment
-CleanEnv();
-
-#Load etc/config.pm and drop privs
-LoadConfig();
-
-#Connect to the database and get RT::SystemUser and RT::Nobody loaded
-DBConnect();
-
-#Drop setgid permissions
-RT::DropSetGIDPermissions();
-
-#Get the current user all loaded
-my $CurrentUser = GetCurrentUser();
-
-unless ($CurrentUser->Id) {
-       print "No RT user found. Please consult your RT administrator.\n";
-       exit(1);
-}
-
-
-# {{{ commandline flags 
-
-my ( @id,
-     @limit_queue,
-     @limit_status,
-     @limit_owner,
-     @limit_priority,
-     @limit_final_priority,
-     @limit_requestor,
-     @limit_subject,
-     @limit_body,
-     @limit_created,
-     @limit_resolved,
-     @limit_lastupdated,
-     @limit_dependson,
-     @limit_dependedonby,
-     @limit_memberof,
-     @limit_hasmember,
-     @limit_refersto,
-     @limit_referredtoby,
-     @limit_keyword,
-     
-     @limit_due,
-     @limit_starts,
-     @limit_started,
-     $limit_first,
-     $limit_rows,
-     $history,
-     $summary,
-     $create,
-     @requestors,
-     @cc,
-     @admincc,
-     $status,
-     $subject,
-     $owner,
-     $steal,
-     $queue,
-     $time_left,
-     $priority,
-     $final_priority,
-     $due,
-     $starts,
-     $started,
-     $contacted,
-     $comment,
-     $reply,
-     $source,
-     $edit,
-     @dependson,
-     @memberof, 
-     @refersto,
-     $mergeinto,
-     @keywords,
-     $time_taken,
-     $verbose,
-     $debug,
-   $help,
-   $version);
-
-# }}}
-
-# Set defaults for cli args
-
-$edit = 1; # Assume the user wants to edit replies and comments 
-           # unless they specify --noedit
-
-# {{{    args
-
-my @args =("id=s" => \@id,
-          "limit-queue=s" => \@limit_queue,
-          "limit-status=s" => \@limit_status,
-          "limit-owner=s" => \@limit_owner,
-          "limit-priority=s" => \@limit_priority,
-          "limit-final-priority=s" => \@limit_final_priority,
-          "limit-requestor=s" => \@limit_requestor,
-          "limit-subject=s" => \@limit_subject,
-          "limit-body=s",      \@limit_body,
-          "limit-created=s" => \@limit_created,
-          "limit-due=s" =>     \@limit_due,
-          "limit-last-updated=s" => \@limit_lastupdated,
-          "limit-keyword=s" => \@limit_keyword,
-
-          "limit-member-of=s" => \@limit_memberof,
-          "limit-has-member=s" => \@limit_hasmember,
-          "limit-depended-on-by=s" => \@limit_dependedonby,
-          "limit-depends-on=s" => \@limit_dependson,
-          "limit-referred-to-by=s" => \@limit_referredtoby,
-          "limit-refers-to=s" => \@limit_refersto,
-
-          "limit-starts=s" => \@limit_starts,
-          "limit-started=s" => \@limit_started,
-          "limit-first=i" => \$limit_first,
-          "limit-rows=i" => \$limit_rows,
-          "history|show" => \$history,
-          "summary:s" => \$summary,
-          "create" => \$create,
-          "keywords=s" => \@keywords,
-          "requestor|requestors=s" => \@requestors,
-          "cc=s" => \@cc,
-          "admincc=s" => \@admincc,
-          "status=s" => \$status,
-          "subject=s" => \$subject,
-          "owner=s" => \$owner,
-          "steal" => \$steal,
-          "queue=s" => \$queue,
-
-          
-          "priority=i" => \$priority,
-          "final-priority=i" => \$final_priority,
-          "due=s" => \$due,
-          "starts=s" => \$starts,
-          "started=s" => \$started,
-          "contacted=s" => \$contacted,
-          "comment", \$comment,
-          "reply|respond", \$reply,
-          "source=s" => \$source,
-          "edit!" => \$edit,
-          "depends-on=s" => \@dependson,
-          "member-of=s" => \@memberof, 
-          "merge-into=s" => \$mergeinto, 
-          "refers-to=s" => \@refersto,
-          "time-left=i" => \$time_left,
-          "time-taken=i" => \$time_taken,
-          "verbose+" => \$verbose,
-          "debug" => \$debug,
-          "version" => \$version,
-          "help|h|usage" => \$help
-         );
-
-# }}}
-
-
-
-GetOptions(@args);
-
-print join(':',@keywords);
-# {{{ If they want it, print a usage message and get out
-
-if ($help) {
-
-
-print <<EOUSAGE;
-
-Limit the set of records returned:
-
---id=[first][-][last]
-  Specify a single ticket, a range, or to start with (n-) or end with (-n)
-a specific ticket.
-  
-  --limit-queue=<queue>
-         --limit-status=[!](new|open|stalled|resolved)
-
-         --limit-owner=[!]<userid>
-         --limit-priority=[starts][-][ends]
-         --limit-final-priority=[starts][-][ends]
-           starts is less than ends
-         --limit-requestor=[!]<userid>|<email>
-         --limit-subject=[!]<text>
-         --limit-body=[!]<text>
-         --limit-keyword=[!]<select>/<keyword>
-        
-       Links
-          --limit-member-of=<ticketid>
-          --limit-has-member=<ticketid>
-          --limit-refers-to=<ticketid>
-          --limit-referred-to-by=<ticketid>
-          --limit-depends-on=<ticketid>
-          --limit-depended-on-by=<ticketid>
-
-
-       Dates
-         --limit-created=[starts][-][ends]
-         --limit-due=[starts][-][ends]
-         --limit-starts=[starts][-][ends]
-         --limit-started=[starts][-][ends]
-          --limit-resolved=[starts][-][ends]
-          --limit-last-updated=[starts][-][ends]
-           starts and ends are dates.  starts can not be less than ends
-
-         --limit-first=<first row returned>
-         --limit-rows=<row count>
-
-         --history | --show
-            show a history of the tickets found
-
-         --summary [format-string]
-             show a listing-style summary of the tickets found. If format string
-             is ommitted, uses \$RT_SUMMARY_FORMAT or an internal default
-            
-
-             #TODO: doc summary 
-             format: <atom>%<format>
-             atom:   <name><size>
-             size: <integer>
-             name:  (grep for # {{{ attribs for the array of ok values)
-
-
-         --create
-            create a new ticket. Any attributes that you can modify on an existing ticket
-            can also be used for ticket creation.
-
-
-
-Attributes
-  Basics
-         --status=<new|open|stalled|resolved|dead>
-           sets status
-          --subject=<subject>
-           sets subject
-          --owner=<userid>
-           set owner to 
-           --steal
-           Become the owner, even if someone else owns the ticket
-          --queue=<queueid>
-           set queue to
-          
-          --priority=<int>
-         
-           --final-priority=<int>
-
-  Watchers
-         --requestors=[+|-]<userid|email address>
-          add or remove this user as a ticket requestor 
-         --cc=[+|-]<userid|email address>
-          add or remove this user as a ticket cc
-         --admincc=[+|-]<userid|email address>
-          add or remove this user as a ticket admincc
-
-       (When creating tickets, just leave off the + or - )
-
-  Keywords
-         --keywords[+|-]<keyword_select>/<keyword>
-          Add or remove a keyword.
-
-
-
-  Dates
-          --due=<date>
-          --starts=<date>
-          --started=<date>
-          --contacted=<date>
-
-          --time-left=<int>
-            
-          --time-taken=<int>
-
-
-   Link related manipulation:
-
-          --depends-on=[+|-]<ticketid>
-          --member-of=[+|-]<ticketid>
-          --refers-to=[+|-]<ticketid>
-           --merge-into=<ticketid>
-
-Comments and replies
-
-          --comment
-          --reply|respond
-            --source <path>
-                Specify the path to the source file for this ticket update
-
-             --noedit
-                Don't invoke \$EDITOR to edit the content of this update
-
-
-
-
-   Condiments
-
-          --verbose
-          --debug
-          --version
-          --help|h|usage
-             You're reading it.
-
-EOUSAGE
-
-    exit(0);
-}
-
-# Print version, and leave
-if ($version) {
-       print "RT $RT::VERSION for $RT::rtname. Copyright 1996-2001 Jesse Vincent <jesse\@fsck.com>\n";
-       exit(0);
-}
-
-# }}}
-
-# {{{ Validate any options that were passed in. normalize them.
-
-#if a queue was specified
-if ($queue) {
-    # make sure that $queue is a valid queue and load it into $queue_obj
-}
-
-#For each date in: $due, $starts, $started
-
-# load up an RT::Date object and parse it into a normalized form
-# if it can't parse it, log an error and null out the variable
-
-# }}}
-
-# {{{ Check if we're creating, if so, create the ticket and be done
-
-if ($create) {
-    $RT::Logger->debug("Creating a new ticket");
-
-    #Make sure the current user can create tickets in this queue
-    
-    #Make sure that the owner specified can own tickets in this queue
-
-
-           
-    my $linesref = GetMessageContent( Edit => $edit, Source => $source,
-                                     CurrentUser => $CurrentUser
-                                   );
-    
-    require MIME::Entity;
-    my $MIMEObj;
-    
-    if ($linesref) {
-       $MIMEObj = MIME::Entity->build(Data => $linesref);
-    }  
-    
-    use RT::Ticket;
-    my $Ticket=new RT::Ticket($CurrentUser);
-    my ($ticket, $trans, $msg) =
-      $Ticket->Create(Queue => $queue,
-                     Owner => $owner,
-                     Status => $status || 'new' ,
-                     Subject => $subject,
-                     Requestor => \@requestors,
-                     Cc => \@cc,
-                     AdminCc => \@admincc,
-                     Due => $due,
-                     Starts => $starts,
-                     Started => $started,
-                     TimeLeft => $time_left,
-                     InitialPriority => $priority,
-                     FinalPriority => $final_priority,
-                     MIMEObj => $MIMEObj
-                    );
-    print $msg . "\n";
-}
-
-# }}}
-
-else {
-    #Apply restrictions
-    use RT::Tickets;
-    my $Tickets = new RT::Tickets($CurrentUser);
-    
-    # {{{ Limit our search
-    my $value;                 #to use when iterating through restrictions
-    my $queue_id;              #to use when limiting by keyword
-    
-    # {{{ limit on id
-
-    foreach $value (@id) {
-       if ($value =~ /^(\d+)$/) {
-           $Tickets->LimitId ( VALUE => $1,
-                               OPERATOR => '=');
-       }       
-       elsif ($value =~ /^(\d*)\D?(\d*)$/) {
-           my $start = $1;
-           my $end = $2;
-           $Tickets->LimitId(
-                             VALUE => "$start",
-                             OPERATOR => '>=') if ($start);
-           $Tickets->LimitId(
-                             VALUE => "$end",
-                             OPERATOR => '<=') if ($end);
-       }       
-    }
-
-
-    # }}}
-    
-    # {{{ limit on status
-
-    foreach $value (@limit_status) {
-       if ($value =~ /^(=|!=|!|)(.*)$/) {
-           my $op = $1;
-           my $val = $2;
-                
-
-           $op = ParseBooleanOp($op);
-           $Tickets->LimitStatus(VALUE => "$val",
-                                 OPERATOR => "$op");
-       }       
-    }
-
-    # }}}
-
-
-
-    # {{{ limit on queue
-    foreach $value (@limit_queue) {
-       if ($value =~ /^(\W?)(.*?)$/i) {
-           my $op = $1;
-           my $val = $2;
-               
-           $op = ParseBooleanOp($op);
-
-           my $queue_obj = new RT::Queue($RT::SystemUser);
-               
-           unless ($queue_obj->Load($val)) {
-               $RT::Logger->debug("Queue '$val' not found");
-               print STDERR "Queue '$val' not found\n";        
-               exit(-1);
-           }
-           $RT::Logger->debug ("Limiting queue to $op ".$queue_obj->Name);
-           $Tickets->LimitQueue(VALUE => $queue_obj->Name,
-                                OPERATOR => $op);
-           $queue_id=$queue_obj->id;
-       }       
-    }  
-
-    # {{{ limit on keyword
-    foreach $value (@limit_keyword) {
-       if ($value =~ /^(\W?)(.*?)\/(.*)$/i) {
-           my $op = $1;
-           my $select = $2;
-           my $keyword = $3;
-
-           $op = ParseBooleanOp($op);
-
-           # load the keyword select
-           my $keyselect = RT::KeywordSelect->new($RT::SystemUser);
-           unless ($keyselect->LoadByName(Name=>$select, Queue=>$queue_id)) {
-               $RT::Logger->debug("KeywordSelect '$select' not found");
-               print STDERR "KeywordSelect '$select' not fount\n";
-               exit(-1);
-           }
-
-           # load the keyword
-           my $k = RT::Keyword->new($RT::SystemUser);
-           unless ($k->LoadByNameAndParentId($keyword, $keyselect->Keyword)) {
-               $RT::Logger->debug("Keyword '$keyword' not found");
-               print STDERR "Keyword '$keyword' not found\n";
-               exit(-1);
-           }
-           $Tickets->LimitKeyword(OPERATOR => $op,
-                                  KEYWORDSELECT => $keyselect->id,
-                                  KEYWORD => $k->id);
-           $RT::Logger->debug ("Limiting keyword to $op ".$k->Path);
-       }
-    }
-    # }}}
-    # {{{ limit on owner
-    foreach $value (@limit_owner) {
-       if ($value =~ /^(\W?)(.*?)$/i) {
-           my $op = $1;
-           my $val = $2;
-               
-           $op = ParseBooleanOp($op);
-
-           my $user_obj = new RT::User($RT::SystemUser);
-               
-           unless ($user_obj->Load($val)) {
-               $RT::Logger->debug("User '$val' not found");
-               print STDERR "User '$val' not found\n"; 
-               exit(-1);
-           }
-           $val = $user_obj->id();
-               
-           $RT::Logger->debug ("Limiting owner to $op $val");
-           $Tickets->LimitOwner(VALUE => "$val",
-                                OPERATOR => "$op");
-       }       
-    }  
-    # }}}
-    # {{{ limt on priority
-
-    foreach $value (@limit_priority) {
-       my ($start, $end) = ParseRange($value);
-       if ($start == $end) {
-           $Tickets->LimitPriority( VALUE => $start,
-                                    OPERATOR => '=');
-       } elsif ($start) {
-           $Tickets->LimitPriority( VALUE => $start,
-                                    OPERATOR => '>=');
-       } elsif ($end) {
-           $Tickets->LimitPriority( VALUE => $end,
-                                    OPERATOR => '<=');
-       }       
-           
-    }
-    foreach $value (@limit_final_priority) {
-       my ($start, $end) = ParseRange($value);
-       if ($start == $end) {
-           $Tickets->LimitFinalPriority( VALUE => $start,
-                                         OPERATOR => '=');
-       } elsif ($start) {
-           $Tickets->LimitFinalPriority( VALUE => $start,
-                                         OPERATOR => '>=');
-       } elsif ($end) {
-           $Tickets->LimitFinalPriority( VALUE => $end,
-                                         OPERATOR => '<=');
-       }       
-    }
-    # }}}
-
-    foreach $value (@limit_requestor) {
-       if ($value =~ /^(\W?)(.*?)$/i) {
-           my $op = $1;
-           my $val = $2;
-               
-           $op = ParseBooleanOp($op);
-           $Tickets->LimitRequestor(VALUE => $val,
-                                    OPERATOR => $op );
-       }
-           
-    }
-    foreach $value (@limit_subject) {
-       
-       if ($value =~ /^(\W?)(.*?)$/i) {
-           my $op = $1;
-           my $val = $2;
-           
-           $op = ParseLikeOp($op);
-           
-           $Tickets->LimitSubject(VALUE => $val,
-                                  OPERATOR => $op );
-           }
-    }
-    
-    foreach $value (@limit_body) {
-       if ($value =~ /^(\W?)(.*?)$/i) {
-           my $op = $1;
-           my $val = $2;
-           
-           $op = ParseLikeOp($op);
-           
-               $Tickets->LimitBody(VALUE => $val,
-                                   OPERATOR => $op );
-       }       
-       
-    }
-    
-    
-    
-    # Dates
-    foreach my $date (@limit_created) {
-       my ($start, $end) = ParseDateRange($date);
-       $Tickets->LimitCreated ( VALUE => $start,
-                                OPERATOR => '>=' ) if ($start);
-       $Tickets->LimitCreated ( VALUE => $end,
-                                OPERATOR => '<=' ) if ($end);
-    }
-
-    foreach my $date (@limit_due) {
-       my ($start, $end) = ParseDateRange($date);
-       $Tickets->LimitDue ( VALUE => $start,
-                                OPERATOR => '>=' ) if ($start);
-       $Tickets->LimitDue ( VALUE => $end,
-                                OPERATOR => '<=' ) if ($end);
-    }
-
-    foreach my $date (@limit_starts) {
-       my ($start, $end) = ParseDateRange($date);
-       $Tickets->LimitStarts ( VALUE => $start,
-                                OPERATOR => '>=' ) if ($start);
-       $Tickets->LimitStarts ( VALUE => $end,
-                                OPERATOR => '<=' ) if ($end);
-    }
-
-    foreach my $date (@limit_started) {
-       my ($start, $end) = ParseDateRange($date);
-       $Tickets->LimitStarted ( VALUE => $start,
-                                OPERATOR => '>=' ) if ($start);
-       $Tickets->LimitStarted ( VALUE => $end,
-                                OPERATOR => '<=' ) if ($end);
-    }
-
-    foreach my $date (@limit_resolved) {
-       my ($start, $end) = ParseDateRange($date);
-       $Tickets->LimitResolved ( VALUE => $start,
-                                OPERATOR => '>=' ) if ($start);
-       $Tickets->LimitResolved ( VALUE => $end,
-                                OPERATOR => '<=' ) if ($end);
-    }
-
-    foreach my $date (@limit_lastupdated) {
-       my ($start, $end) = ParseDateRange($date);
-       $Tickets->LimitLastUpdated( VALUE => $start,
-                                OPERATOR => '>=' ) if ($start);
-       $Tickets->LimitLastUpdated ( VALUE => $end,
-                                OPERATOR => '<=' ) if ($end);
-    }
-
-    foreach my $link (@limit_memberof) {
-       $Tickets->LimitMemberOf($link);
-    }  
-
-    foreach my $link (@limit_hasmember) {
-       $Tickets->LimitHasMember($link);
-    }  
-
-    foreach my $link (@limit_dependson) {
-       $Tickets->LimitDependsOn($link);
-    }  
-
-    foreach my $link (@limit_dependedonby) {
-       $Tickets->LimitDependedOnBy($link);
-    }
-    foreach my $link (@limit_refersto) {
-       $Tickets->LimitRefersTo($link);
-    }  
-    
-    foreach my $link (@limit_referredtoby) {
-       $Tickets->LimitReferredToBy($link);
-    }  
-
-    
-    if ($limit_first){
-    }
-    if ($limit_rows){
-    }
-
-# }}}
-    
-    # {{{ Iterate through all tickets we found
-
-
-    my ($format, $titles, $code);
-    
-    #Set up the summary format if we need to
-    if (defined $summary) {
-       my $format_string = $summary || $ENV{'RT_SUMMARY_FORMAT'} || "%id4%status4%queue7%subject40%requestor16";
-
-       ($format, $titles, $code) = BuildListingFormat($format_string);
-        printf "$format\n", eval "$titles";
-   }   
-
-
-    while (my $Ticket = $Tickets->Next()) {
-       $RT::Logger->debug ("Now working on ticket ". $Ticket->id);
-    
-       #Run through all the ticket modifications we might want to do
-       #TODO: these are all insufficiently lazy and should be replaced with some 
-       # nice foreaches.
-
-
-       # {{{ deal with watchers
-       
-       # add / delete requestors
-       foreach $value (@requestors) {
-           if ($value =~ /^(\W?)(.*)$/) {
-               my $op = $1;
-               my $addr = $2;
-               
-               $Ticket->AddRequestor(Email => $addr) if ($op eq '+');
-               $Ticket->DeleteRequestor( $addr) if ($op eq '-');
-           }   
-       }
-       
-       # add / delete ccs
-       foreach $value (@cc) {
-           if ($value =~ /^(\W?)(.*)$/) {
-               my $op = $1;
-               my $addr = $2;
-               $Ticket->AddCc(Email => $addr) if ($op eq '+');
-               $Ticket->DeleteCc($addr) if ($op eq '-');
-           }   
-       }       
-       
-       # add / delete adminccs
-        $RT::Logger->debug("Looking at admin ccs");
-       foreach $value (@admincc) {
-           if ($value =~ /^(\W?)(.*)$/) {
-               my $op = $1;
-               my $addr = $2;
-               $Ticket->AddAdminCc(Email => $addr) if ($op eq '+');
-               $Ticket->DeleteAdminCc($addr) if ($op eq '-');
-           }   
-       }       
-
-       # }}}
-       
-       # {{{ Deal with ticket keywords
-
-       my $KeywordSelects = $Ticket->QueueObj->KeywordSelects();
-        $RT::Logger->debug ("Looking at keywords");
-       foreach $value (@keywords) {
-           $RT::Logger->debug("Looking at --keyword=$value");
-           if ($value =~ /^(\W?)(.*?)\/(.*)$/) {
-               my $op = $1;
-               my $select = $2;
-               my $keyword = $3;
-               
-               $RT::Logger->debug("Going to $op Keyword $select / $keyword");  
-               while (my $ks = $KeywordSelects->Next) {
-                    $RT::Logger->debug("$select is select ".$ks->Name." is found");
-                   next unless ($ks->Name =~ /$select/i);
-                   $RT::Logger->debug ("Found a match for $select\n"); 
-                   my $kids = $ks->KeywordObj->Descendents;
-    
-                    my ($kid);
-                   foreach $kid (keys %{$kids}) {
-                        $RT::Logger->debug("Now comparing $keyword with ".$kids->{$kid}. "\n");
-                       next unless ($kids->{$kid} =~ /^$keyword$/i);
-                       $RT::Logger->debug("Going to $op $select / $keyword (".$kids->{$kid} .")");     
-                       $Ticket->DeleteKeyword(KeywordSelect => $ks->id,
-                                           Keyword => $kid) if ($op eq '-');
-                       
-                       $Ticket->AddKeyword(KeywordSelect => $ks->id,
-                                           Keyword => $kid) if ($op eq '+');
-                   }
-                   
-               }
-           }
-       }
-       # }}}
-       
-       # {{{ deal with links
-
-       # Deal with merging {
-       if ($mergeinto) {
-               my ($trans, $msg) =$Ticket->MergeInto($mergeinto);
-               print $msg."\n";
-       }       
-       # add /delete depends-ons
-
-       foreach my $value (@dependson) {
-           if ($value =~ /^(\W?)(.*)$/) {
-               my $op = $1;
-               my $ticket = $2;
-               if (!$op or ($op eq '+')) {
-                   my ($trans, $msg) =
-                     $Ticket->AddLink(Type => 'DependsOn', Target => $ticket);
-                   print $msg."\n";
-               }
-               elsif ($op eq '-') {
-                   my ($trans, $msg) = 
-                     $Ticket->DeleteLink(Type => 'DependsOn', Target => $ticket);
-                   print $msg."\n";
-               }
-
-           }
-       }
-       # add /delete member-of
-       foreach my $value (@memberof) {
-           if ($value =~ /^(\W?)(.*)$/) {
-               my $op = $1;
-               my $ticket = $2;
-               if ($op eq '+') {
-                   my ($trans, $msg) =
-                     $Ticket->AddLink(Type => 'MemberOf', Target => $ticket);
-                   print $msg;
-               }
-               elsif ($op eq '-') {
-                   my ($trans, $msg) = 
-                     $Ticket->DeleteLink(Type => 'MemberOf', Target => $ticket);
-                   print $msg;
-               }
-
-           }
-       }       
-       # add / delete refers-to
-               foreach my $value (@refersto) {
-           if ($value =~ /^(\W?)(.*)$/) {
-               my $op = $1;
-               my $ticket = $2;
-               if ($op eq '+') {
-                   my ($trans, $msg) =
-                     $Ticket->AddLink(Type => 'RefersTo', Target => $ticket);
-                   print $msg;
-               }
-               elsif ($op eq '-') {
-                   my ($trans, $msg) = 
-                     $Ticket->DeleteLink(Type => 'RefersTo', Target => $ticket);
-                   print $msg;
-               }
-
-           }
-       }
-
-       # }}}
-       
-       # {{{ deal with dates
-       
-       #set due 
-       if ($due) {
-           my $iso = ParseDateToISO($due);
-           if ($iso) {
-               $RT::Logger->debug("Setting due date to $iso ($due)");
-               my ($trans, $msg) = 
-                 $Ticket->SetDue($iso);
-               print $msg;
-           }
-           else {
-               print "Due date '$due' could not be parsed";
-           }
-       }
-
-       #set starts
-       if ($starts) {
-           my $iso = ParseDateToISO($due);
-           if ($iso) {
-               my ($trans, $msg) = 
-                 $Ticket->SetStarts($iso);
-               print $msg."\n";
-           }
-           else {
-               print "Starts date '$starts' could not be parsed";
-           }
-       }
-       #set started
-               if ($started) {
-           my $iso = ParseDateToISO($started);
-           if ($iso) {
-               my ($trans, $msg) = 
-                 $Ticket->SetStarted($iso);
-               print $msg."\n";
-           }
-           else {
-               print "Started date '$started' could not be parsed";
-           }
-       }
-       #set contacted
-               if ($contacted) {
-           my $iso = ParseDateToISO($contacted);
-           if ($iso) {
-               my ($trans, $msg) = 
-                 $Ticket->SetContacted($iso);
-               print $msg."\n";
-           }
-           else {
-               print "Contacted date '$contacted' could not be parsed";
-           }
-       }
-
-    # }}}
-       
-       # {{{ set other attributes
-
-       #Set subject
-       if ($subject) {
-           my ($trans, $msg) = $Ticket->SetSubject($subject);
-           print $msg."\n";
-       }
-       
-       #Set priority
-       if ($priority) {
-           my ($trans, $msg) = 
-             $Ticket->SetPriority($priority);
-           print $msg."\n";
-       }
-       
-       #Set final priority
-       if ($final_priority) {
-           my ($trans, $msg) =
-             $Ticket->SetFinalPriority($final_priority);
-           print $msg."\n";
-       }
-
-       #Set status
-       if ($status) {
-           my ($trans, $msg) = 
-             $Ticket->SetStatus($status);
-           print $msg."\n";
-       }
-       
-       #Set time left
-       if ($time_left) {
-           my ($trans, $msg) = 
-             $Ticket->SetTimeLeft($time_left);
-           print $msg."\n";
-       }
-
-       #Set time_taken 
-       if ($time_taken) {
-           my ($trans, $msg) = 
-             $Ticket->SetTimeTaken($time_taken);
-           print $msg."\n";
-       }
-       
-       #Set owner
-       if ($owner) {
-           my ($trans, $msg) =
-             $Ticket->SetOwner($owner);
-           print $msg."\n";
-       }
-
-        # Steal
-        if ($steal) {
-                my ($trans, $msg) =
-                 $Ticket->Steal();
-                 print $msg . "\n";
-        }
-       #Set queue 
-       if ($queue) {
-           my ($trans, $msg) = 
-             $Ticket->SetQueue($queue);
-           print $msg."\n";
-       }
-
-    # }}}
-       
-
-
-       # {{{ Perform ticket comments/replies
-       if ($reply) {
-           $RT::Logger->debug("Replying to ticket ".$Ticket->Id);
-           
-           my $linesref = GetMessageContent( Edit => $edit, Source => $source,
-                                            CurrentUser => $CurrentUser
-                                          );
-           
-           #TODO build this entity
-           require MIME::Entity;
-           my $MIMEObj = MIME::Entity->build(Data => $linesref);
-           
-           $Ticket->Correspond( MIMEObj => $MIMEObj ,
-                                TimeTaken => $time_taken);
-       }       
-       
-       elsif ($comment) {
-           $RT::Logger->debug("Commenting on ticket ".$Ticket->Id);
-       
-           my $linesref =GetMessageContent(Edit => $edit, Source => $source,
-                                           CurrentUser => $CurrentUser);
-           #TODO build this entity
-           require MIME::Entity;
-           my $MIMEObj = MIME::Entity->build(Data => $linesref);
-           
-           $Ticket->Comment( MIMEObj => $MIMEObj,
-                             TimeTaken => $time_taken);
-       }
-
-    # }}}
-       
-       # {{{ Display whatever we need to display
-
-       # {{{ Display a full ticket listing and history
-       if ($history) {
-           #Display the history
-           $RT::Logger->debug("Show history for ".$Ticket->id);
-           
-           if ($Ticket->CurrentUserHasRight("ShowTicket")) {
-               &ShowSummary($Ticket);
-               print "\n";
-               &ShowHistory($Ticket);
-           }
-           else {
-               print "You don't have permission to view that ticket.\n";
-           }
-       }       
-
-       # }}}
-       
-       # {{{ Display a summary if we need to
-       if (defined $summary) {
-           $RT::Logger->debug ("Show ticket summary with format $format");
-           
-           printf $format."\n", eval $code;
-           
-       }       
-       # }}}
-
-       # }}}
-       
-    }
-
-    # }}}
-    
-}
-
-
-$RT::Handle->Disconnect();
-
-
-
-
-
-
-
-# {{{ sub ParseBooleanOp
-
-=head2 ParseBooleanOp
-
-  Takes an option modifier. returns the apropriate SQL operator.
-  If it's handed ! or -, returns !=.  Otherwise returns =.
-
-=cut
-
-sub ParseBooleanOp {
-    
-    my $op = shift;
-    
-    #so that !new limits to not new, etc
-    if ($op =~ /^(\!|-)/) {
-       $op = "!=";
-    }
-    else {
-       $op = "=";
-    }
-    
-    return($op);
-}
-
-# }}}
-
-# {{{ sub ParseLikeOp
-=head2 ParseLikeOp
-
-  Takes an option modifier. returns the apropriate SQL operator.
-  If it's handed ! or -, returns NOT  LIKE.  Otherwise returns LIKE
-
-=cut
-
-sub ParseLikeOp {
-    
-    my $op = shift;
-    
-    #so that !new limits to not new, etc
-    if ($op =~ /^(\!|-)/) {
-       $op = "NOT LIKE";
-    }
-    else {
-       $op = "LIKE";
-    }
-    
-    return($op);
-}
-# }}}
-
-# {{{ sub ParseDateToISO
-
-=head2 ParseDateToISO
-
-Takes a date in an arbitrary format.
-Returns an ISO date and time in GMT
-
-=cut
-
-sub ParseDateToISO {
-    my $date = shift;
-
-       my $date_obj = new RT::Date($CurrentUser);
-       $date_obj->Set( Format => 'unknown',
-                       Value => $date
-                     );
-       return ($date_obj->ISO);
-}
-
-# }}}
-
-# {{{ sub ParseDateRange
-
-=head2 ParseDateRange [RANGE]
-
-Takes a range of dates of the form [<date>][-][<date>] and returns 
-starting and ending dates (as ISOs) If a date is specified as neither a starting nor ending 
-date, we parse it it as "midnight tonight to midnight tomorrow"
-
-=cut
-
-sub ParseDateRange {
-    my $in = shift;
-    my ($start, $end);
-    
-    
-    use RT::Date;
-    my $start_obj = new RT::Date($CurrentUser);
-    my $end_obj = new RT::Date($CurrentUser);
-    
-    if ($in =~ /^(.*?)-(.*?)$/) {
-       $start = $1;
-       $end = $2;
-
-       if ($start) {
-           $start_obj->Set(Format => 'unknown', 
-                           Value => $start);
-       }
-       if ($end) {
-           $end_obj->Set(Format => 'unknown', 
-                         Value => $end);
-       }
-    }
-    else {
-       $start = $in;
-       $end = $in;
-
-       $start_obj->Set(Format => 'unknown', 
-                       Value => $start);
-       
-       $end_obj->Set(Format => 'unknown', 
-                     Value => $end);
-       
-       $start_obj->SetToMidnight();
-       $end_obj->SetToMidnight();
-       $end_obj->AddDay();
-    }  
-    
-    if ($start) {
-       $start = $start_obj->ISO;
-    }
-    if ($end) {
-       $end = $end_obj->ISO;
-    }
-
-    return ($start, $end);
-}
-
-# }}}
-
-# {{{ ParseRange
-=head2 ParseRange [RANGE]
-
-Takes a range of the form [<int>][-][<int>] and returns 
-a first and a last value. If the - is omitted, both $start and $end are the same.
-=cut
-
-sub ParseRange {
-    my $in = shift;
-    my ($start, $end);
-    
-    if ($in =~ /(.*?)-(.*?)/) {
-       $start = $1;
-       $end = $2;
-    }
-    else {
-       $start = $in;
-       $end = $in;
-    }  
-    
-    return ($start, $end);
-    
-
-    
-}
-
-# }}}
-         
-# {{{ sub ShowSummary 
-
-sub ShowSummary  {
-    my $Ticket = shift;
-
-
-    print <<EOFORM;
-Serial Number: @{[$Ticket->Id]}   Status:@{[$Ticket->Status]} Worked: @{[$Ticket->TimeWorked]} minutes  Queue:@{[$Ticket->QueueObj->Name]}
-      Subject: @{[$Ticket->Subject]}
-   Requestors: @{[$Ticket->RequestorsAsString]}
-           Cc: @{[$Ticket->CcAsString]}
-     Admin Cc: @{[$Ticket->AdminCcAsString]}
-        Owner: @{[$Ticket->OwnerObj->Name]}
-     Priority: @{[$Ticket->Priority]} / @{[$Ticket->FinalPriority]}
-          Due: @{[$Ticket->DueAsString]}
-      Created: @{[$Ticket->CreatedAsString]} (@{[$Ticket->AgeAsString]})
- Last Contact: @{[$Ticket->ToldAsString]} (@{[$Ticket->LongSinceToldAsString]})
-  Last Update: @{[$Ticket->LastUpdatedAsString]} by @{[$Ticket->LastUpdatedByObj->Name]}
-                
-EOFORM
-
-my $selects = $Ticket->QueueObj->KeywordSelects();
-    #get the keyword selects
-    print "Keywords:\n";
-    while (my $select = $selects->Next) {
-       print "\t" .$select->Name .": ";
-       my $keys = $Ticket->KeywordsObj($select->id);   
-       while (my $key = $keys->Next) {
-           print $key->KeywordObj->RelativePath($select->KeywordObj) . "  ";
-           
-       }       
-       print "\n";
-    }
-    
-#iterate through the keyword selects.
-#print the keyword select and all the related keywords
-
-
-
-#TODO: finish link  descriptions
-print "Dependencies: \n";
-   while (my $l=$Ticket->DependedOnBy->Next) {
-       print $l->BaseObj->id," (",$l->BaseObj->Subject,") ",$l->Type," this ticket\n";
-   }
-   while (my $l=$Ticket->DependsOn->Next) {
-       print "This ticket ",$l->Type," ",$l->TargetObj->Id," (",$l->TargetObj->Subject,")\n";
-   }
-}
-
-# }}}
-
-# {{{ sub ShowHistory 
-sub ShowHistory  {
-    my $Ticket = shift;
-    my $Transaction;    
-    my $Transactions = $Ticket->Transactions;
-
-    while ($Transaction = $Transactions->Next) {
-      &ShowTransaction($Transaction);
-    }   
-  }
-# }}}
-
-# {{{ sub ShowTransaction 
-sub ShowTransaction  {
-  my $transaction = shift;
-  
-print <<EOFORM;
-==========================================================================
-Date: @{[$transaction->CreatedAsString]} (@{[$transaction->TimeTaken]} minutes)
-@{[$transaction->Description]}
-EOFORM
-    ;
-  my $attachments=$transaction->Attachments();
-  while (my $message=$attachments->Next) {
-    print <<EOFORM;
---------------------------------------------------------------------------
-@{[$message->Headers]}
-EOFORM
-
-    if ($message->ContentType =~ m{^(text/plain|message|text$)}) {
-       print $message->Content;
-    } else {
-       print $message->ContentType, " not shown";
-    }
-  }
-  print "\n";
-  return();
-}
-# }}}
-
-
-# {{{ sub BuildListingFormat
-
-sub BuildListingFormat {
-    my $format_string = shift;
-
-    my ($id, @format, @code, @titles);
-    my ($field,$titles,$length, $format);
-
-    my $code = "";
-
-    # {{{ attribs
-    my $attribs = { id => { chars => '4',
-                           justify => 'r',
-                           title => 'id',
-                           value => '$Ticket->id',
-                         },
-                   
-                   queue => { chars => '8',
-                              justify => 'l',
-                              title => 'Queue',
-                              value => '$Ticket->QueueObj->Name' 
-                            },
-                   subject => { chars => '30',
-                                justify => 'l',
-                                title => 'Subject',
-                                value => '$Ticket->Subject',
-                              },
-                   priority => { chars => '2',
-                                 justify => 'r',
-                                 title => 'Pri',
-                                 value => '$Ticket->Priority',
-                               },
-                   final_priority => {  chars => '2',
-                                        justify => 'r',
-                                        title => 'Fin',
-                                        value => '$Ticket->FinalPriority',
-                                     },
-                   time_worked => { chars => '6',
-                                    justify => 'r',
-                                    title => 'Worked',
-                                    value => '$Ticket->TimeWorked',
-                                  },
-                   time_left => { chars => '5',
-                                  justify => 'r',
-                                  title => 'Left',
-                                  value => '$Ticket->TimeLeft',
-                              
-                                },
-               
-                   status => {  chars => '6',
-                                justify => 'r',
-                                title => 'Status',
-                                value => '$Ticket->Status',
-                             },
-                   owner => {  chars => '10',
-                               justify => 'r',
-                               title => 'Owner',
-                               value => '$Ticket->OwnerObj->Name'
-                            },
-                   requestor => {  chars => '10',
-                                   justify => 'r',
-                                   title => 'Requestor',
-                                   value => '$Ticket->RequestorsAsString'
-                                },
-                   created => {  chars => '12',
-                                 justify => 'r',
-                                 title => 'Created',
-                                 value => '$Ticket->CreatedAsString'
-                              },
-                   updated => {  chars => '12',
-                                 justify => 'r',
-                                 title => 'Updated',
-                                 value => '$Ticket->LastUpdatedAsString'
-                              },
-                   due => {  chars => '12',
-                             justify => 'r',
-                             title => 'Due',
-                             value => '$Ticket->DueAsString'
-                          },
-                   told => {  chars => '12',
-                              justify => 'r',
-                              title => 'Told',
-                              value => '$Ticket->ToldAsString'
-                           },
-               
-               
-               
-                 };
-
-    # }}}
-    
-
-    foreach $field (split ('%',$format_string)) {
-       
-       if ($field =~ /^(\D*?)(\d*?)$/) {
-           $id = $1;
-           $length = $2;
-       }
-       else {  
-           $RT::Logger->debug ("Error parsing $field\n");
-       }
-       if ($length) {
-           push (@format, "%".$length.".".$length."s ");
-           
-           push (@code,  $attribs->{"$id"}->{'value'});
-                 
-           push (@titles, "'". $attribs->{"$id"}->{title}. "'");
-       }
-       
-       
-    }
-     $code = join (',', @code);
-     $format = join (" ", @format);
-     $titles = join (', ', @titles);
-    
-  
-    return ($format, $titles, $code);
-}
-
-# }}}
-
-
-
-1;
diff --git a/rt/bin/rt-commit-handler b/rt/bin/rt-commit-handler
new file mode 100644 (file)
index 0000000..29e443e
--- /dev/null
@@ -0,0 +1,846 @@
+#!/usr/bin/perl -w
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+# {{{ Docs
+# -*-Perl-*-
+#
+#ident "@(#)ccvs/contrib:$Name:  $:$Id: rt-commit-handler,v 1.1 2003-07-15 13:16:15 ivan Exp $"
+#
+# Perl filter to handle the log messages from the checkin of files in multiple
+# directories.  This script will group the lists of files by log message, and
+# send one piece of mail per unique message, no matter how many files are
+# committed.
+
+=head1 NAME rt-commit-handler
+
+=head1 USAGE
+
+
+
+=head2 Regular use
+
+Stick the following in in CVSROOT/commitinfo
+
+ ALL     /opt/rt3/bin/rt-commit-handler --record-last-dir
+
+Stick the following  in CVSROOT/loginfo
+
+ ALL     /opt/rt3/bin/rt-commit-handler --cvs-root /pathtocvs/root --rt %{Vvts}
+
+=head2 Invocation (advanced use)
+
+rt-commit-handler --cvs-root /path/to/cvs/root [-d] [-D] [-r] [-M module] \
+                [[-m mailto] ...] [[-R replyto] ...] [-f logfile] 
+
+
+       -d              - turn on debugging
+       -m mailto       - send mail to "mailto" (multiple)
+       -R replyto      - set the "Reply-To:" to "replyto" (multiple)
+       -M modulename   - set module name to "modulename"
+       -f logfile      - write commit messages to logfile too
+       -D              - generate diff commands
+        --rt              - invoke RT commit handler
+        --cvs-root       - specify your CVS root 
+
+        --record-last-dir -  Record the last directory with changes in
+                             pre-commit (commitinfo) mode
+
+
+=cut
+
+# }}}
+
+use strict;
+use Carp;
+use Getopt::Long;
+use Text::Wrap;
+use Digest::MD5;
+use MIME::Entity;
+
+use lib ("/opt/rt3/lib", "/opt/rt3/local/lib");
+
+use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc);
+
+use vars
+  qw(@MAILER $TMPDIR $FILE_PREFIX $LASTDIR_FILE $HASH_FILE $VERSION_FILE             $MESSAGE_FILE $MAIL_FILE $DEBUG $MAILTO $REPLYTO $id $MODULE_NAME
+  $LOGIN $COMMITLOG $CVS_ROOT $RT_HANDLER);
+
+#Clean out all the nasties from the environment
+CleanEnv();
+
+#Load etc/config.pm and drop privs
+RT::LoadConfig();
+
+#Drop setgid permissions
+RT::DropSetGIDPermissions();
+
+# {{{ Variable setup
+$TMPDIR      = '/tmp';
+$FILE_PREFIX = $TMPDIR . '/#cvs.';
+
+# The root of your CVS install. we should get this from some smarter place.
+# It needs a trailing /
+
+$LASTDIR_FILE = $FILE_PREFIX . "lastdir";
+$HASH_FILE    = $FILE_PREFIX . "hash";
+$VERSION_FILE = $FILE_PREFIX . "version";
+$MESSAGE_FILE = $FILE_PREFIX . "message";
+$MAIL_FILE    = $FILE_PREFIX . "mail";
+
+$DEBUG      = 0;
+$RT_HANDLER = 1;
+
+$MAILTO = '';
+
+my @files = ();
+my (@log_lines);
+my $do_diff = 0;
+my $id      = getpgrp();    # note, you *must* use a shell which does setpgrp()
+$LOGIN = getpwuid($<);
+
+# }}}
+
+die "User could not be found" unless ($LOGIN);
+
+# {{{ parse command line arguments (file list is seen as one arg)
+#
+while ( my $arg = shift @ARGV ) {
+
+    if ( $arg eq '-d' ) {
+        $DEBUG = 1;
+        warn "Debug turned on...\n";
+    }
+    elsif ( $arg =~ /^--record-last-dir$/i ) {
+        record_last_dir( $id, $ARGV[0] );
+        exit(0);
+    }
+    elsif ( $arg eq '-m' ) {
+        $MAILTO .= ", " if $MAILTO;
+        $MAILTO .= shift @ARGV;
+    }
+    elsif ( $arg eq '--rt' ) {
+        $RT_HANDLER = 1;
+    }
+    elsif ( $arg eq '-R' ) {
+        $REPLYTO .= ", " if $REPLYTO;
+        $REPLYTO .= shift @ARGV;
+    }
+    elsif ( $arg eq '-M' ) {
+        die ("too many '-M' args\n") if $MODULE_NAME;
+        $MODULE_NAME = shift @ARGV;
+    }
+    elsif ( $arg eq '--cvs-root' ) {
+        $CVS_ROOT = shift @ARGV;
+        $CVS_ROOT .= "/" unless ( $CVS_ROOT =~ /\/$/ );
+    }
+    elsif ( $arg eq '-f' ) {
+        die ("too many '-f' args\n") if $COMMITLOG;
+        $COMMITLOG = shift @ARGV;
+
+        # This is a disgusting hack to untaint $COMMITLOG if we're running from
+        # setgid cvs.
+        $COMMITLOG = untaint($COMMITLOG);
+    }
+    elsif ( $arg eq '-D' ) {
+        $do_diff = 1;
+    }
+    else {
+        @files = split ( ' ', $arg );
+        last;
+    }
+}
+
+# }}}
+
+$REPLYTO = $LOGIN unless ($REPLYTO);
+
+# for now, the first "file" is the repository directory being committed,
+# relative to the $CVSROOT location
+#
+my $dir = shift @files;
+
+# XXX there are some ugly assumptions in here about module names and
+# XXX directories relative to the $CVSROOT location -- really should
+# XXX read $CVSROOT/CVSROOT/modules, but that's not so easy to do, since
+# XXX we have to parse it backwards.
+#
+# XXX For now we set the `module' name to the top-level directory name.
+#
+unless ($MODULE_NAME) {
+    ($MODULE_NAME) = split ( '/', $dir, 2 );
+}
+
+if ($DEBUG) {
+    warn "module - ", $MODULE_NAME, "\n";
+    warn "dir    - ", $dir,         "\n";
+    warn "files  - ", join ( " ", @files ), "\n";
+    warn "id     - ", $id, "\n";
+}
+
+# {{{ Check for a new directory or an import command.
+
+#
+#    files[0] - "-"
+#    files[1] - "New"
+#    files[2] - "directory"
+#
+#    files[0] - "-"
+#    files[1] - "Imported"
+#    files[2] - "sources"
+#
+if ( $files[0] eq "-" ) {
+
+    #we just don't care about  New Directory notes
+    unless ( $files[1] eq "New" && $files[2] eq "directory" ) {
+
+        my @text = ();
+
+        push @text, build_header();
+        push @text, "";
+
+        while ( my $line = <STDIN> ) {
+            chop $line;    # Drop the newline
+            push @text, $line;
+        }
+
+        append_logfile( $COMMITLOG, @text ) if ($COMMITLOG);
+
+        mail_notification( $id, @text );
+    }
+
+    exit 0;
+}
+
+# }}}
+
+# {{{ Collect just the log message from stdin.
+#
+
+while ( my $line = <STDIN> ) {
+    chop $line;    # strip the newline
+    last if ( $line =~ /^Log Message:$/ );
+}
+while ( my $line = <STDIN> ) {
+    chop $line;    # strip the newline
+    $line =~ s/\s+$//;    # strip trailing white space
+    push @log_lines, $line;
+}
+
+my $md5 = Digest::MD5->new();
+foreach my $line (@log_lines) {
+    $md5->add( $line . "\n" );
+}
+my $hash = $md5->hexdigest();
+
+warn "hash = $hash\n" if ($DEBUG);
+
+if ( !-e "$MESSAGE_FILE.$id.$hash" ) {
+    append_logfile( "$HASH_FILE.$id",      $hash );
+    write_file( "$MESSAGE_FILE.$id.$hash", @log_lines );
+}
+
+# }}}
+
+# Spit out the information gathered in this pass.
+
+append_logfile( "$VERSION_FILE.$id.$hash", $dir . '/', @files );
+
+# {{{ Check whether this is the last directory.  If not, quit.
+
+warn "Checking current dir against last dir $LASTDIR_FILE.$id\n" if ($DEBUG);
+
+my @last_dir = read_file("$LASTDIR_FILE.$id");
+
+unless ($CVS_ROOT) {
+    die "No cvs root specified with --cvs-root. Can't continue.";
+}
+
+if ( $last_dir[0] ne $CVS_ROOT . $dir ) {
+    warn "Current directory $CVS_ROOT$dir is not last directory $last_dir[0].\n"
+      if ($DEBUG);
+    exit 0;
+}
+
+# }}}
+
+# {{{ End Of Commits!
+#
+
+# This is it.  The commits are all finished.  Lump everything together
+# into a single message, fire a copy off to the mailing list, and drop
+# it on the end of the Changes file.
+#
+
+#
+# Produce the final compilation of the log messages
+#
+
+my @hashes = read_file("$HASH_FILE.$id");
+my (@text);
+
+push @text, build_header();
+push @text, "";
+
+my ( @added_files, @modified_files, @removed_files );
+
+foreach my $hash (@hashes) {
+
+    # In case we're running setgid, make sure the hash file hasn't been hacked.
+    $hash =~ m/([a-z0-9]*)/ || die "*** Hacking attempt detected\n";
+    $hash = $1;
+
+    my @files     = read_file("$VERSION_FILE.$id.$hash");
+    my @log_lines = read_file("$MESSAGE_FILE.$id.$hash");
+
+    my $working_on_dir;    # gets set as we iterate through the files.
+    foreach my $file (@files) {
+
+        #If we've entered a new directory, make a note of that and remove the trailing /
+
+        if ( $file =~ s'\/$'' ) {
+            $working_on_dir = $file;
+            next;
+        }
+
+        my @file_entry = ( split ( ',', $file, 4 ), $working_on_dir );
+
+        # file_entry looks like ths:
+
+        # 0        1          2      3        4
+        # Old rev : new rev : tag:   file    :directory        
+        my $entry = {};
+        $entry->{'old'}  = $file_entry[0];
+        $entry->{'new'}  = $file_entry[1];
+        $entry->{'tag'}  = $file_entry[2];
+        $entry->{'file'} = $file_entry[3];
+        $entry->{'dir'}  = $file_entry[4];
+
+        if ( $file_entry[0] eq 'NONE' ) {
+            $entry->{'old'} = '0';
+            push @added_files, $entry;
+        }
+        elsif ( $file_entry[1] eq 'NONE' ) {
+            $entry->{'new'} = '0';
+            push @removed_files, $entry;
+        }
+        else {
+            push @modified_files, $entry;
+        }
+    }
+}
+
+# }}}
+
+# {{{ start building up the body
+
+# Strip leading and trailing blank lines from the log message.  Also
+# compress multiple blank lines in the body of the message down to a
+# single blank line.
+#
+
+my $blank = 1;
+@log_lines = map {
+    my $wasblank = $blank;
+    $blank = $_ eq '';
+    $blank && $wasblank ? () : $_;
+} @log_lines;
+
+pop @log_lines if $blank;
+
+@modified_files = order_and_summarize_diffs(@modified_files);
+@added_files    = order_and_summarize_diffs(@added_files);
+@removed_files  = order_and_summarize_diffs(@removed_files);
+
+push @text, "Modified Files:", format_lists(@modified_files)
+  if (@modified_files);
+
+push @text, "Added Files:", format_lists(@added_files) if (@added_files);
+
+push @text, "Removed Files:", format_lists(@removed_files) if (@removed_files);
+
+push @text, "", "Log Message", @log_lines if (@log_lines);
+
+push @text, "";
+
+if ($RT_HANDLER) {
+    rt_handler(
+        @log_lines,                             "\n",
+        loc("To generate a diff of this commit:\n"), "\n",
+        format_diffs( @modified_files, @added_files, @removed_files )
+    );
+}
+
+if ($COMMITLOG) {
+    append_logfile( $COMMITLOG, @text );
+}
+
+if ($do_diff) {
+    push @text, "";
+    push @text, loc("To generate a diff of this commit:");
+    push @text, format_diffs( @modified_files, @added_files, @removed_files );
+    push @text, "";
+}
+
+# }}}
+
+# {{{ Mail out the notification.
+
+mail_notification( $id, @text );
+
+# }}} 
+
+# {{{ clean up
+
+unless ($DEBUG) {
+    $hash = untaint($hash);
+    $id   = untaint($id);
+    unlink "$VERSION_FILE.$id.$hash";
+    unlink "$MESSAGE_FILE.$id.$hash";
+    unlink "$MAIL_FILE.$id";
+    unlink "$LASTDIR_FILE.$id";
+    unlink "$HASH_FILE.$id";
+}
+
+# }}}
+
+exit 0;
+
+# {{{ Subroutines
+#
+
+# {{{ append_logfile
+sub append_logfile {
+    my $filename = shift;
+    my (@lines) = @_;
+
+    $filename = untaint($filename);
+
+    open( FILE, ">>$filename" )
+      || die ("Cannot open file $filename for append.\n");
+    foreach my $line (@lines) {
+        print FILE $line . "\n";
+    }
+    close(FILE);
+}
+
+# }}}
+
+# {{{ write_file
+sub write_file {
+    my $filename = shift;
+    my (@lines) = @_;
+
+    $filename = untaint($filename);
+
+    open( FILE, ">$filename" )
+      || die ("Cannot open file $filename for write.\n");
+    foreach my $line (@lines) {
+        print FILE $line . "\n";
+    }
+    close(FILE);
+}
+
+# }}}
+
+# {{{ read_file
+sub read_file {
+    my $filename = shift;
+    my (@lines);
+
+    open( FILE, "<$filename" )
+      || die ("Cannot open file $filename for read.\n");
+    while ( my $line = <FILE> ) {
+        chop $line;
+        push @lines, $line;
+    }
+    close(FILE);
+
+    return (@lines);
+}
+
+# }}}
+
+# {{{ sub format_lists
+
+sub format_lists {
+    my @items = (@_);
+
+    my $files = "";
+    map {
+        $_->{'files'} && ( $files .= ' ' . join ( ' ', @{ $_->{'files'} } ) );
+    } @items;
+
+    my @lines = wrap( "\t", "\t\t", $files );
+    return (@lines);
+
+}
+
+# }}}
+
+# {{{ sub format_diffs
+
+sub format_diffs {
+    my @items = (@_);
+
+    my @lines;
+    foreach my $item (@items) {
+        next unless ( $item->{'files'} );
+        push ( @lines,
+            "cvs diff -r"
+              . $item->{'old'} . " -r"
+              . $item->{'new'} . " "
+              . join ( " ", @{ $item->{'files'} } ) . "\n" );
+
+    }
+
+    @lines = fill( "\t", "\t\t", @lines );
+
+    return (@lines);
+}
+
+# }}}
+
+# {{{ sub order_and_summarize_diffs {
+
+# takes an array of file items
+# returns a sorted array of fileset items, which are like file items, except they can have an array of files, rather than 
+# a singleton file.
+
+sub order_and_summarize_diffs {
+
+    my @files = (@_);
+
+    # Sort by tag, dir, file.
+    @files = sort {
+        $a->{'tag'} cmp $b->{'tag'}
+          || $a->{'dir'} cmp $b->{'dir'}
+          || $a->{'file'} cmp $b->{'file'};
+    } @files;
+
+    # Combine adjacent rows that are the same modulo the file name.
+
+    my @items = (undef);
+
+    foreach my $file (@files) {
+        if ( $#items == -1    #if it's empty
+            || ( !defined $items[-1]->{'old'}
+                || $items[-1]->{'old'} ne $file->{'old'} )
+            || ( !defined $items[-1]->{'new'}
+                || $items[-1]->{'new'} ne $file->{'new'} )
+            || ( !defined $items[-1]->{'tag'}
+                || $items[-1]->{'tag'} ne $file->{'tag'} ) )
+        {
+
+            push ( @items, $file );
+        }
+        push ( @{ $items[-1]->{'files'} },
+            $file->{'dir'} . "/" . $file->{'file'} );
+    }
+
+    return (@items);
+}
+
+# }}}
+
+# {{{ build_header
+
+sub build_header {
+    my $now    = gmtime;
+    my $header =
+      sprintf( "Module Name:\t%s\nCommitted By:\t%s\nDate:\t\t%s %s %s",
+        $MODULE_NAME, $LOGIN, substr( $now, 0, 19 ), "UTC",
+        substr( $now, 20, 4 ) );
+    return ($header);
+}
+
+# }}}
+
+# {{{ mail_notification
+sub mail_notification {
+    my $id = shift;
+    my (@text) = @_;
+    write_file( "$MAIL_FILE.$id", "From: " . $LOGIN,
+        "Subject: CVS commit: " . $MODULE_NAME, "To: " . $MAILTO,
+        "Reply-To: " . $REPLYTO,                "", "", @text );
+
+    my $entity = MIME::Entity->build(
+        From       => $LOGIN,
+        To         => $MAILTO,
+        Subject    => "CVS commit: " . $MODULE_NAME,
+        'Reply-To' => $REPLYTO,
+        Data       => join ( "\n", @text )
+    );
+    if ( $RT::MailCommand eq 'sendmailpipe' ) {
+        open( MAIL, "|$RT::SendmailPath $RT::SendmailArguments" )
+          || die "Couldn't send mail: " . $@ . "\n";
+        print MAIL $entity->as_string;
+        close(MAIL);
+    }
+    else {
+        $entity->send( $RT::MailCommand, $RT::MailParams );
+    }
+
+}
+
+# }}}
+
+# {{{ sub record_last_dir
+
+sub record_last_dir {
+    my $id  = shift;
+    my $dir = shift;
+
+    # make a note of this directory. later, we'll use this to 
+    # figure out if we've gone through the whole commit,
+    # for something that is a bad mockery of attomic commits.
+
+    warn "about to write $dir to $LASTDIR_FILE.$id" if ($DEBUG);
+
+    write_file( "$LASTDIR_FILE.$id", $dir );
+}
+
+# }}}
+
+# {{{ Get the RT stuff set up
+
+# {{{ sub rt_handler 
+
+sub rt_handler {
+    my (@LogMessage) = (@_);
+
+    #Connect to the database and get RT::SystemUser and RT::Nobody loaded
+    RT::Init;
+
+    require RT::Ticket;
+
+    #Get the current user all loaded
+    my $CurrentUser = GetCurrentUser();
+
+    if ( !$CurrentUser->Id ) {
+        print
+loc("No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\n");
+        return;
+    }
+
+    my (@commands) = find_commands( \@LogMessage );
+
+    my ( @tickets, @errors );
+
+    # Get the list of tickets we're working with out of commands
+    grep { $_ =~ /^RT-Ticket:\s*(.*?)$/i && push ( @tickets, $1 ) } @commands;
+
+    my $message = new MIME::Entity;
+    $message->build(
+        From    => $CurrentUser->EmailAddress,
+        Subject => 'CVS Commit',
+        Data    => \@LogMessage
+    );
+
+    # {{{ comment or correspond, as needed
+
+    foreach my $ticket (@tickets) {
+        my $TicketObj = RT::Ticket->new($CurrentUser);
+        $TicketObj->Load($ticket);
+        my ( $id, $msg );
+        unless ( $TicketObj->Id ) {
+            push ( @errors,
+"Couldn't load ticket #$ticket. Not adding commit log to ticket history.\n"
+            );
+        }
+
+        if ( $LogMessage[0] =~ /^(comment|private)$/ ) {
+            ( $id, $msg ) = $TicketObj->Comment( MIMEObj => $message );
+
+        }
+        else {
+            ( $id, $msg ) = $TicketObj->Correspond( MIMEObj => $message );
+        }
+
+        push ( @errors, ">> Log message",
+            "Ticket #" . $TicketObj->Id . ": " . $msg );
+
+    }
+
+    # }}}
+
+    my ($reply) = ActOnPseudoHeaders( $CurrentUser, @commands );
+    print "$reply\n" if ($reply);
+    print join ( "\n", @errors );
+    print "\n";
+
+}
+
+# }}}
+
+# {{{ sub find_commands
+
+sub find_commands {
+    my $lines = shift;
+    my (@pseudoheaders);
+
+    while ( my $line = shift @{$lines} ) {
+        next if $line =~ /^\s*?$/;
+        if ( $line =~ /^RT-/i ) {
+
+            push ( @pseudoheaders, $line );
+        }
+
+        #If we find a line that's not a command, get out.
+        else {
+            unshift ( @{$lines}, $line );
+            last;
+        }
+    }
+
+    return (@pseudoheaders);
+
+}
+
+# }}}
+
+# {{{ sub ActOnPseudoHeaders
+
+=item ActOnPseudoHeaders $PseudoHeaders
+
+Takes a string of pseudo-headers, iterates through them and does what they tell it to.
+
+=cut
+
+sub ActOnPseudoHeaders {
+    my $CurrentUser = shift;
+    my (@actions) = (@_);
+
+    my $ResultsMessage = '';
+    my $Ticket         = RT::Ticket->new($CurrentUser);
+
+    foreach my $action (@actions) {
+        my ($val);
+        my $msg = '';
+
+        $ResultsMessage .= ">>> $action\n";
+
+        if ( $action =~ /^RT-(.*?):\s*(.*)$/i ) {
+            my $command = $1;
+            my $args    = $2;
+
+            if ( $command =~ /^ticket$/i ) {
+
+                $val = $Ticket->Load($args);
+                unless ($val) {
+                    $ResultsMessage .=
+                      loc("ERROR: Couldn't load ticket '[_1]': [_2].\n", $1, $msg);
+                      . loc("Aborting to avoid unintended ticket modifications.\n")
+                      . loc("The following commands were not proccessed:\n\n")
+                      . join ( "\n", @actions );
+                    return ($ResultsMessage);
+                }
+                $ResultsMessage .= loc("Ticket [_1] loaded\n", $Ticket->Id);
+            }
+            else {
+                unless ( $Ticket->Id ) {
+                    $ResultsMessage .= loc("No Ticket specified. Aborting ticket ")
+                      . loc("modifications\n\n")
+                      . loc("The following commands were not proccessed:\n\n")
+                      . join ( "\n", @actions );
+                    return ($ResultsMessage);
+                }
+
+                # Deal with the basics
+                if ( $command =~ /^(Subject|Owner|Status|Queue)$/i ) {
+                    my $method = 'Set' . ucfirst( lc($1) );
+                    ( $val, $msg ) = $Ticket->$method($args);
+                }
+
+                # Deal with the dates
+                elsif ( $command =~ /^(due|starts|started|resolved)$/i ) {
+                    my $method = 'Set' . ucfirst( lc($1) );
+                    my $date   = new RT::Date($CurrentUser);
+                    $date->Set( Format => 'unknown', Value => $args );
+                    ( $val, $msg ) = $Ticket->$method( $date->ISO );
+                }
+
+                # Deal with the watchers
+                elsif ( $command =~ /^(requestor|requestors|cc|admincc)$/i ) {
+                    my $operator = "+";
+                    my ($type);
+                    if ( $args =~ /^(\+|\-)(.*)$/ ) {
+                        $operator = $1;
+                        $args     = $2;
+                    }
+                    $type = 'Requestor' if ( $command =~ /^requestor/i );
+                    $type = 'Cc'        if ( $command =~ /^cc/i );
+                    $type = 'AdminCc'   if ( $command =~ /^admincc/i );
+
+                       my $user = RT::User->new($CurrentUser);
+                    $user->Load($args);
+
+                    if ($operator eq '+') {
+                        ($val, $msg) = $Ticket->AddWatcher( Type => $type,
+                                                            PrincipalId => $user->PrincipalId);
+                    } elsif ($operator eq '-') {
+                        ($val, $msg) = $Ticket->DeleteWatcher( Type => $type,
+                                                               PrincipalId => $user->PrincipalId);
+                    }
+
+            }
+            $ResultsMessage .= $msg . "\n";
+        }
+
+    }
+    return ($ResultsMessage);
+
+}
+
+# }}}
+
+# {{{ sub untaint 
+sub untaint {
+    my $val = shift;
+
+    if ( $val =~ /^([-\#\/\w.]+)$/ ) {
+        $val = $1;    # $data now untainted
+    }
+    else {
+        die loc("Bad data in [_1]", $val);    # log this somewhere
+    }
+    return ($val);
+}
+
+# }}}
+
+=head1 AUTHOR
+
+
+
+  rt-commit-handler is a rewritten version of the NetBSD commit handler,
+  which was placed in the public domain by Charles Hannum. It bore the following
+  authors statement:
+
+ Contributed by David Hampton <hampton@cisco.com>
+ Hacked greatly by Greg A. Woods <woods@planix.com>
+ Rewritten by Charles M. Hannum <mycroft@netbsd.org>
+
+=cut
+
diff --git a/rt/bin/rt-commit-handler.in b/rt/bin/rt-commit-handler.in
new file mode 100644 (file)
index 0000000..02b01ab
--- /dev/null
@@ -0,0 +1,846 @@
+#!@PERL@ -w
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+# {{{ Docs
+# -*-Perl-*-
+#
+#ident "@(#)ccvs/contrib:$Name:  $:$Id: rt-commit-handler.in,v 1.1 2003-07-15 13:16:15 ivan Exp $"
+#
+# Perl filter to handle the log messages from the checkin of files in multiple
+# directories.  This script will group the lists of files by log message, and
+# send one piece of mail per unique message, no matter how many files are
+# committed.
+
+=head1 NAME rt-commit-handler
+
+=head1 USAGE
+
+
+
+=head2 Regular use
+
+Stick the following in in CVSROOT/commitinfo
+
+ ALL     @RT_BIN_PATH@/rt-commit-handler --record-last-dir
+
+Stick the following  in CVSROOT/loginfo
+
+ ALL     @RT_BIN_PATH@/rt-commit-handler --cvs-root /pathtocvs/root --rt %{Vvts}
+
+=head2 Invocation (advanced use)
+
+rt-commit-handler --cvs-root /path/to/cvs/root [-d] [-D] [-r] [-M module] \
+                [[-m mailto] ...] [[-R replyto] ...] [-f logfile] 
+
+
+       -d              - turn on debugging
+       -m mailto       - send mail to "mailto" (multiple)
+       -R replyto      - set the "Reply-To:" to "replyto" (multiple)
+       -M modulename   - set module name to "modulename"
+       -f logfile      - write commit messages to logfile too
+       -D              - generate diff commands
+        --rt              - invoke RT commit handler
+        --cvs-root       - specify your CVS root 
+
+        --record-last-dir -  Record the last directory with changes in
+                             pre-commit (commitinfo) mode
+
+
+=cut
+
+# }}}
+
+use strict;
+use Carp;
+use Getopt::Long;
+use Text::Wrap;
+use Digest::MD5;
+use MIME::Entity;
+
+use lib ("@RT_LIB_PATH@", "@LOCAL_LIB_PATH@");
+
+use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc);
+
+use vars
+  qw(@MAILER $TMPDIR $FILE_PREFIX $LASTDIR_FILE $HASH_FILE $VERSION_FILE             $MESSAGE_FILE $MAIL_FILE $DEBUG $MAILTO $REPLYTO $id $MODULE_NAME
+  $LOGIN $COMMITLOG $CVS_ROOT $RT_HANDLER);
+
+#Clean out all the nasties from the environment
+CleanEnv();
+
+#Load etc/config.pm and drop privs
+RT::LoadConfig();
+
+#Drop setgid permissions
+RT::DropSetGIDPermissions();
+
+# {{{ Variable setup
+$TMPDIR      = '/tmp';
+$FILE_PREFIX = $TMPDIR . '/#cvs.';
+
+# The root of your CVS install. we should get this from some smarter place.
+# It needs a trailing /
+
+$LASTDIR_FILE = $FILE_PREFIX . "lastdir";
+$HASH_FILE    = $FILE_PREFIX . "hash";
+$VERSION_FILE = $FILE_PREFIX . "version";
+$MESSAGE_FILE = $FILE_PREFIX . "message";
+$MAIL_FILE    = $FILE_PREFIX . "mail";
+
+$DEBUG      = 0;
+$RT_HANDLER = 1;
+
+$MAILTO = '';
+
+my @files = ();
+my (@log_lines);
+my $do_diff = 0;
+my $id      = getpgrp();    # note, you *must* use a shell which does setpgrp()
+$LOGIN = getpwuid($<);
+
+# }}}
+
+die "User could not be found" unless ($LOGIN);
+
+# {{{ parse command line arguments (file list is seen as one arg)
+#
+while ( my $arg = shift @ARGV ) {
+
+    if ( $arg eq '-d' ) {
+        $DEBUG = 1;
+        warn "Debug turned on...\n";
+    }
+    elsif ( $arg =~ /^--record-last-dir$/i ) {
+        record_last_dir( $id, $ARGV[0] );
+        exit(0);
+    }
+    elsif ( $arg eq '-m' ) {
+        $MAILTO .= ", " if $MAILTO;
+        $MAILTO .= shift @ARGV;
+    }
+    elsif ( $arg eq '--rt' ) {
+        $RT_HANDLER = 1;
+    }
+    elsif ( $arg eq '-R' ) {
+        $REPLYTO .= ", " if $REPLYTO;
+        $REPLYTO .= shift @ARGV;
+    }
+    elsif ( $arg eq '-M' ) {
+        die ("too many '-M' args\n") if $MODULE_NAME;
+        $MODULE_NAME = shift @ARGV;
+    }
+    elsif ( $arg eq '--cvs-root' ) {
+        $CVS_ROOT = shift @ARGV;
+        $CVS_ROOT .= "/" unless ( $CVS_ROOT =~ /\/$/ );
+    }
+    elsif ( $arg eq '-f' ) {
+        die ("too many '-f' args\n") if $COMMITLOG;
+        $COMMITLOG = shift @ARGV;
+
+        # This is a disgusting hack to untaint $COMMITLOG if we're running from
+        # setgid cvs.
+        $COMMITLOG = untaint($COMMITLOG);
+    }
+    elsif ( $arg eq '-D' ) {
+        $do_diff = 1;
+    }
+    else {
+        @files = split ( ' ', $arg );
+        last;
+    }
+}
+
+# }}}
+
+$REPLYTO = $LOGIN unless ($REPLYTO);
+
+# for now, the first "file" is the repository directory being committed,
+# relative to the $CVSROOT location
+#
+my $dir = shift @files;
+
+# XXX there are some ugly assumptions in here about module names and
+# XXX directories relative to the $CVSROOT location -- really should
+# XXX read $CVSROOT/CVSROOT/modules, but that's not so easy to do, since
+# XXX we have to parse it backwards.
+#
+# XXX For now we set the `module' name to the top-level directory name.
+#
+unless ($MODULE_NAME) {
+    ($MODULE_NAME) = split ( '/', $dir, 2 );
+}
+
+if ($DEBUG) {
+    warn "module - ", $MODULE_NAME, "\n";
+    warn "dir    - ", $dir,         "\n";
+    warn "files  - ", join ( " ", @files ), "\n";
+    warn "id     - ", $id, "\n";
+}
+
+# {{{ Check for a new directory or an import command.
+
+#
+#    files[0] - "-"
+#    files[1] - "New"
+#    files[2] - "directory"
+#
+#    files[0] - "-"
+#    files[1] - "Imported"
+#    files[2] - "sources"
+#
+if ( $files[0] eq "-" ) {
+
+    #we just don't care about  New Directory notes
+    unless ( $files[1] eq "New" && $files[2] eq "directory" ) {
+
+        my @text = ();
+
+        push @text, build_header();
+        push @text, "";
+
+        while ( my $line = <STDIN> ) {
+            chop $line;    # Drop the newline
+            push @text, $line;
+        }
+
+        append_logfile( $COMMITLOG, @text ) if ($COMMITLOG);
+
+        mail_notification( $id, @text );
+    }
+
+    exit 0;
+}
+
+# }}}
+
+# {{{ Collect just the log message from stdin.
+#
+
+while ( my $line = <STDIN> ) {
+    chop $line;    # strip the newline
+    last if ( $line =~ /^Log Message:$/ );
+}
+while ( my $line = <STDIN> ) {
+    chop $line;    # strip the newline
+    $line =~ s/\s+$//;    # strip trailing white space
+    push @log_lines, $line;
+}
+
+my $md5 = Digest::MD5->new();
+foreach my $line (@log_lines) {
+    $md5->add( $line . "\n" );
+}
+my $hash = $md5->hexdigest();
+
+warn "hash = $hash\n" if ($DEBUG);
+
+if ( !-e "$MESSAGE_FILE.$id.$hash" ) {
+    append_logfile( "$HASH_FILE.$id",      $hash );
+    write_file( "$MESSAGE_FILE.$id.$hash", @log_lines );
+}
+
+# }}}
+
+# Spit out the information gathered in this pass.
+
+append_logfile( "$VERSION_FILE.$id.$hash", $dir . '/', @files );
+
+# {{{ Check whether this is the last directory.  If not, quit.
+
+warn "Checking current dir against last dir $LASTDIR_FILE.$id\n" if ($DEBUG);
+
+my @last_dir = read_file("$LASTDIR_FILE.$id");
+
+unless ($CVS_ROOT) {
+    die "No cvs root specified with --cvs-root. Can't continue.";
+}
+
+if ( $last_dir[0] ne $CVS_ROOT . $dir ) {
+    warn "Current directory $CVS_ROOT$dir is not last directory $last_dir[0].\n"
+      if ($DEBUG);
+    exit 0;
+}
+
+# }}}
+
+# {{{ End Of Commits!
+#
+
+# This is it.  The commits are all finished.  Lump everything together
+# into a single message, fire a copy off to the mailing list, and drop
+# it on the end of the Changes file.
+#
+
+#
+# Produce the final compilation of the log messages
+#
+
+my @hashes = read_file("$HASH_FILE.$id");
+my (@text);
+
+push @text, build_header();
+push @text, "";
+
+my ( @added_files, @modified_files, @removed_files );
+
+foreach my $hash (@hashes) {
+
+    # In case we're running setgid, make sure the hash file hasn't been hacked.
+    $hash =~ m/([a-z0-9]*)/ || die "*** Hacking attempt detected\n";
+    $hash = $1;
+
+    my @files     = read_file("$VERSION_FILE.$id.$hash");
+    my @log_lines = read_file("$MESSAGE_FILE.$id.$hash");
+
+    my $working_on_dir;    # gets set as we iterate through the files.
+    foreach my $file (@files) {
+
+        #If we've entered a new directory, make a note of that and remove the trailing /
+
+        if ( $file =~ s'\/$'' ) {
+            $working_on_dir = $file;
+            next;
+        }
+
+        my @file_entry = ( split ( ',', $file, 4 ), $working_on_dir );
+
+        # file_entry looks like ths:
+
+        # 0        1          2      3        4
+        # Old rev : new rev : tag:   file    :directory        
+        my $entry = {};
+        $entry->{'old'}  = $file_entry[0];
+        $entry->{'new'}  = $file_entry[1];
+        $entry->{'tag'}  = $file_entry[2];
+        $entry->{'file'} = $file_entry[3];
+        $entry->{'dir'}  = $file_entry[4];
+
+        if ( $file_entry[0] eq 'NONE' ) {
+            $entry->{'old'} = '0';
+            push @added_files, $entry;
+        }
+        elsif ( $file_entry[1] eq 'NONE' ) {
+            $entry->{'new'} = '0';
+            push @removed_files, $entry;
+        }
+        else {
+            push @modified_files, $entry;
+        }
+    }
+}
+
+# }}}
+
+# {{{ start building up the body
+
+# Strip leading and trailing blank lines from the log message.  Also
+# compress multiple blank lines in the body of the message down to a
+# single blank line.
+#
+
+my $blank = 1;
+@log_lines = map {
+    my $wasblank = $blank;
+    $blank = $_ eq '';
+    $blank && $wasblank ? () : $_;
+} @log_lines;
+
+pop @log_lines if $blank;
+
+@modified_files = order_and_summarize_diffs(@modified_files);
+@added_files    = order_and_summarize_diffs(@added_files);
+@removed_files  = order_and_summarize_diffs(@removed_files);
+
+push @text, "Modified Files:", format_lists(@modified_files)
+  if (@modified_files);
+
+push @text, "Added Files:", format_lists(@added_files) if (@added_files);
+
+push @text, "Removed Files:", format_lists(@removed_files) if (@removed_files);
+
+push @text, "", "Log Message", @log_lines if (@log_lines);
+
+push @text, "";
+
+if ($RT_HANDLER) {
+    rt_handler(
+        @log_lines,                             "\n",
+        loc("To generate a diff of this commit:\n"), "\n",
+        format_diffs( @modified_files, @added_files, @removed_files )
+    );
+}
+
+if ($COMMITLOG) {
+    append_logfile( $COMMITLOG, @text );
+}
+
+if ($do_diff) {
+    push @text, "";
+    push @text, loc("To generate a diff of this commit:");
+    push @text, format_diffs( @modified_files, @added_files, @removed_files );
+    push @text, "";
+}
+
+# }}}
+
+# {{{ Mail out the notification.
+
+mail_notification( $id, @text );
+
+# }}} 
+
+# {{{ clean up
+
+unless ($DEBUG) {
+    $hash = untaint($hash);
+    $id   = untaint($id);
+    unlink "$VERSION_FILE.$id.$hash";
+    unlink "$MESSAGE_FILE.$id.$hash";
+    unlink "$MAIL_FILE.$id";
+    unlink "$LASTDIR_FILE.$id";
+    unlink "$HASH_FILE.$id";
+}
+
+# }}}
+
+exit 0;
+
+# {{{ Subroutines
+#
+
+# {{{ append_logfile
+sub append_logfile {
+    my $filename = shift;
+    my (@lines) = @_;
+
+    $filename = untaint($filename);
+
+    open( FILE, ">>$filename" )
+      || die ("Cannot open file $filename for append.\n");
+    foreach my $line (@lines) {
+        print FILE $line . "\n";
+    }
+    close(FILE);
+}
+
+# }}}
+
+# {{{ write_file
+sub write_file {
+    my $filename = shift;
+    my (@lines) = @_;
+
+    $filename = untaint($filename);
+
+    open( FILE, ">$filename" )
+      || die ("Cannot open file $filename for write.\n");
+    foreach my $line (@lines) {
+        print FILE $line . "\n";
+    }
+    close(FILE);
+}
+
+# }}}
+
+# {{{ read_file
+sub read_file {
+    my $filename = shift;
+    my (@lines);
+
+    open( FILE, "<$filename" )
+      || die ("Cannot open file $filename for read.\n");
+    while ( my $line = <FILE> ) {
+        chop $line;
+        push @lines, $line;
+    }
+    close(FILE);
+
+    return (@lines);
+}
+
+# }}}
+
+# {{{ sub format_lists
+
+sub format_lists {
+    my @items = (@_);
+
+    my $files = "";
+    map {
+        $_->{'files'} && ( $files .= ' ' . join ( ' ', @{ $_->{'files'} } ) );
+    } @items;
+
+    my @lines = wrap( "\t", "\t\t", $files );
+    return (@lines);
+
+}
+
+# }}}
+
+# {{{ sub format_diffs
+
+sub format_diffs {
+    my @items = (@_);
+
+    my @lines;
+    foreach my $item (@items) {
+        next unless ( $item->{'files'} );
+        push ( @lines,
+            "cvs diff -r"
+              . $item->{'old'} . " -r"
+              . $item->{'new'} . " "
+              . join ( " ", @{ $item->{'files'} } ) . "\n" );
+
+    }
+
+    @lines = fill( "\t", "\t\t", @lines );
+
+    return (@lines);
+}
+
+# }}}
+
+# {{{ sub order_and_summarize_diffs {
+
+# takes an array of file items
+# returns a sorted array of fileset items, which are like file items, except they can have an array of files, rather than 
+# a singleton file.
+
+sub order_and_summarize_diffs {
+
+    my @files = (@_);
+
+    # Sort by tag, dir, file.
+    @files = sort {
+        $a->{'tag'} cmp $b->{'tag'}
+          || $a->{'dir'} cmp $b->{'dir'}
+          || $a->{'file'} cmp $b->{'file'};
+    } @files;
+
+    # Combine adjacent rows that are the same modulo the file name.
+
+    my @items = (undef);
+
+    foreach my $file (@files) {
+        if ( $#items == -1    #if it's empty
+            || ( !defined $items[-1]->{'old'}
+                || $items[-1]->{'old'} ne $file->{'old'} )
+            || ( !defined $items[-1]->{'new'}
+                || $items[-1]->{'new'} ne $file->{'new'} )
+            || ( !defined $items[-1]->{'tag'}
+                || $items[-1]->{'tag'} ne $file->{'tag'} ) )
+        {
+
+            push ( @items, $file );
+        }
+        push ( @{ $items[-1]->{'files'} },
+            $file->{'dir'} . "/" . $file->{'file'} );
+    }
+
+    return (@items);
+}
+
+# }}}
+
+# {{{ build_header
+
+sub build_header {
+    my $now    = gmtime;
+    my $header =
+      sprintf( "Module Name:\t%s\nCommitted By:\t%s\nDate:\t\t%s %s %s",
+        $MODULE_NAME, $LOGIN, substr( $now, 0, 19 ), "UTC",
+        substr( $now, 20, 4 ) );
+    return ($header);
+}
+
+# }}}
+
+# {{{ mail_notification
+sub mail_notification {
+    my $id = shift;
+    my (@text) = @_;
+    write_file( "$MAIL_FILE.$id", "From: " . $LOGIN,
+        "Subject: CVS commit: " . $MODULE_NAME, "To: " . $MAILTO,
+        "Reply-To: " . $REPLYTO,                "", "", @text );
+
+    my $entity = MIME::Entity->build(
+        From       => $LOGIN,
+        To         => $MAILTO,
+        Subject    => "CVS commit: " . $MODULE_NAME,
+        'Reply-To' => $REPLYTO,
+        Data       => join ( "\n", @text )
+    );
+    if ( $RT::MailCommand eq 'sendmailpipe' ) {
+        open( MAIL, "|$RT::SendmailPath $RT::SendmailArguments" )
+          || die "Couldn't send mail: " . $@ . "\n";
+        print MAIL $entity->as_string;
+        close(MAIL);
+    }
+    else {
+        $entity->send( $RT::MailCommand, $RT::MailParams );
+    }
+
+}
+
+# }}}
+
+# {{{ sub record_last_dir
+
+sub record_last_dir {
+    my $id  = shift;
+    my $dir = shift;
+
+    # make a note of this directory. later, we'll use this to 
+    # figure out if we've gone through the whole commit,
+    # for something that is a bad mockery of attomic commits.
+
+    warn "about to write $dir to $LASTDIR_FILE.$id" if ($DEBUG);
+
+    write_file( "$LASTDIR_FILE.$id", $dir );
+}
+
+# }}}
+
+# {{{ Get the RT stuff set up
+
+# {{{ sub rt_handler 
+
+sub rt_handler {
+    my (@LogMessage) = (@_);
+
+    #Connect to the database and get RT::SystemUser and RT::Nobody loaded
+    RT::Init;
+
+    require RT::Ticket;
+
+    #Get the current user all loaded
+    my $CurrentUser = GetCurrentUser();
+
+    if ( !$CurrentUser->Id ) {
+        print
+loc("No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\n");
+        return;
+    }
+
+    my (@commands) = find_commands( \@LogMessage );
+
+    my ( @tickets, @errors );
+
+    # Get the list of tickets we're working with out of commands
+    grep { $_ =~ /^RT-Ticket:\s*(.*?)$/i && push ( @tickets, $1 ) } @commands;
+
+    my $message = new MIME::Entity;
+    $message->build(
+        From    => $CurrentUser->EmailAddress,
+        Subject => 'CVS Commit',
+        Data    => \@LogMessage
+    );
+
+    # {{{ comment or correspond, as needed
+
+    foreach my $ticket (@tickets) {
+        my $TicketObj = RT::Ticket->new($CurrentUser);
+        $TicketObj->Load($ticket);
+        my ( $id, $msg );
+        unless ( $TicketObj->Id ) {
+            push ( @errors,
+"Couldn't load ticket #$ticket. Not adding commit log to ticket history.\n"
+            );
+        }
+
+        if ( $LogMessage[0] =~ /^(comment|private)$/ ) {
+            ( $id, $msg ) = $TicketObj->Comment( MIMEObj => $message );
+
+        }
+        else {
+            ( $id, $msg ) = $TicketObj->Correspond( MIMEObj => $message );
+        }
+
+        push ( @errors, ">> Log message",
+            "Ticket #" . $TicketObj->Id . ": " . $msg );
+
+    }
+
+    # }}}
+
+    my ($reply) = ActOnPseudoHeaders( $CurrentUser, @commands );
+    print "$reply\n" if ($reply);
+    print join ( "\n", @errors );
+    print "\n";
+
+}
+
+# }}}
+
+# {{{ sub find_commands
+
+sub find_commands {
+    my $lines = shift;
+    my (@pseudoheaders);
+
+    while ( my $line = shift @{$lines} ) {
+        next if $line =~ /^\s*?$/;
+        if ( $line =~ /^RT-/i ) {
+
+            push ( @pseudoheaders, $line );
+        }
+
+        #If we find a line that's not a command, get out.
+        else {
+            unshift ( @{$lines}, $line );
+            last;
+        }
+    }
+
+    return (@pseudoheaders);
+
+}
+
+# }}}
+
+# {{{ sub ActOnPseudoHeaders
+
+=item ActOnPseudoHeaders $PseudoHeaders
+
+Takes a string of pseudo-headers, iterates through them and does what they tell it to.
+
+=cut
+
+sub ActOnPseudoHeaders {
+    my $CurrentUser = shift;
+    my (@actions) = (@_);
+
+    my $ResultsMessage = '';
+    my $Ticket         = RT::Ticket->new($CurrentUser);
+
+    foreach my $action (@actions) {
+        my ($val);
+        my $msg = '';
+
+        $ResultsMessage .= ">>> $action\n";
+
+        if ( $action =~ /^RT-(.*?):\s*(.*)$/i ) {
+            my $command = $1;
+            my $args    = $2;
+
+            if ( $command =~ /^ticket$/i ) {
+
+                $val = $Ticket->Load($args);
+                unless ($val) {
+                    $ResultsMessage .=
+                      loc("ERROR: Couldn't load ticket '[_1]': [_2].\n", $1, $msg);
+                      . loc("Aborting to avoid unintended ticket modifications.\n")
+                      . loc("The following commands were not proccessed:\n\n")
+                      . join ( "\n", @actions );
+                    return ($ResultsMessage);
+                }
+                $ResultsMessage .= loc("Ticket [_1] loaded\n", $Ticket->Id);
+            }
+            else {
+                unless ( $Ticket->Id ) {
+                    $ResultsMessage .= loc("No Ticket specified. Aborting ticket ")
+                      . loc("modifications\n\n")
+                      . loc("The following commands were not proccessed:\n\n")
+                      . join ( "\n", @actions );
+                    return ($ResultsMessage);
+                }
+
+                # Deal with the basics
+                if ( $command =~ /^(Subject|Owner|Status|Queue)$/i ) {
+                    my $method = 'Set' . ucfirst( lc($1) );
+                    ( $val, $msg ) = $Ticket->$method($args);
+                }
+
+                # Deal with the dates
+                elsif ( $command =~ /^(due|starts|started|resolved)$/i ) {
+                    my $method = 'Set' . ucfirst( lc($1) );
+                    my $date   = new RT::Date($CurrentUser);
+                    $date->Set( Format => 'unknown', Value => $args );
+                    ( $val, $msg ) = $Ticket->$method( $date->ISO );
+                }
+
+                # Deal with the watchers
+                elsif ( $command =~ /^(requestor|requestors|cc|admincc)$/i ) {
+                    my $operator = "+";
+                    my ($type);
+                    if ( $args =~ /^(\+|\-)(.*)$/ ) {
+                        $operator = $1;
+                        $args     = $2;
+                    }
+                    $type = 'Requestor' if ( $command =~ /^requestor/i );
+                    $type = 'Cc'        if ( $command =~ /^cc/i );
+                    $type = 'AdminCc'   if ( $command =~ /^admincc/i );
+
+                       my $user = RT::User->new($CurrentUser);
+                    $user->Load($args);
+
+                    if ($operator eq '+') {
+                        ($val, $msg) = $Ticket->AddWatcher( Type => $type,
+                                                            PrincipalId => $user->PrincipalId);
+                    } elsif ($operator eq '-') {
+                        ($val, $msg) = $Ticket->DeleteWatcher( Type => $type,
+                                                               PrincipalId => $user->PrincipalId);
+                    }
+
+            }
+            $ResultsMessage .= $msg . "\n";
+        }
+
+    }
+    return ($ResultsMessage);
+
+}
+
+# }}}
+
+# {{{ sub untaint 
+sub untaint {
+    my $val = shift;
+
+    if ( $val =~ /^([-\#\/\w.]+)$/ ) {
+        $val = $1;    # $data now untainted
+    }
+    else {
+        die loc("Bad data in [_1]", $val);    # log this somewhere
+    }
+    return ($val);
+}
+
+# }}}
+
+=head1 AUTHOR
+
+
+
+  rt-commit-handler is a rewritten version of the NetBSD commit handler,
+  which was placed in the public domain by Charles Hannum. It bore the following
+  authors statement:
+
+ Contributed by David Hampton <hampton@cisco.com>
+ Hacked greatly by Greg A. Woods <woods@planix.com>
+ Rewritten by Charles M. Hannum <mycroft@netbsd.org>
+
+=cut
+
diff --git a/rt/bin/rt-crontool b/rt/bin/rt-crontool
new file mode 100644 (file)
index 0000000..ede874a
--- /dev/null
@@ -0,0 +1,210 @@
+#!/usr/bin/perl
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+use strict;
+use Carp;
+
+use lib ("/opt/rt3/lib", "/opt/rt3/local/lib");
+
+package RT;
+
+use Getopt::Long;
+
+use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc);
+use RT::Tickets;
+use RT::Template;
+
+#Clean out all the nasties from the environment
+CleanEnv();
+
+# Load the config file
+RT::LoadConfig();
+
+#Connect to the database and get RT::SystemUser and RT::Nobody loaded
+RT::Init();
+
+#Drop setgid permissions
+RT::DropSetGIDPermissions();
+
+#Get the current user all loaded
+my $CurrentUser = GetCurrentUser();
+
+unless ( $CurrentUser->Id ) {
+    print loc("No RT user found. Please consult your RT administrator.\n");
+    exit(1);
+}
+
+my ( $search, $condition, $action, $search_arg, $condition_arg, $action_arg,
+     $template_id, $help, $verbose );
+GetOptions( "search=s"        => \$search,
+            "search-arg=s"    => \$search_arg,
+            "condition=s"     => \$condition,
+            "condition-arg=s" => \$condition_arg,
+            "action-arg=s"    => \$action_arg,
+            "action=s"        => \$action,
+           "template-id=s"   => \$template_id,
+            "help"            => \$help,
+            "verbose|v"       => \$verbose );
+
+help() if $help;
+
+# We _must_ have a search object
+load_module($search);
+load_module($action)    if ($action);
+load_module($condition) if ($condition);
+
+# load template if specified
+my $template_obj;
+if ($template_id) {
+    $template_obj = RT::Template->new($RT::Nobody);
+    $template_obj->LoadById($template_id);
+}
+
+#At the appointed time:
+
+#find a bunch of tickets
+my $tickets = RT::Tickets->new($CurrentUser);
+my $search  = $search->new( TicketsObj => $tickets, Argument => $search_arg );
+
+$search->Prepare();
+
+# TicketsFound is an RT::Tickets object
+my $tickets = $search->TicketsObj;
+
+#for each ticket we've found
+while ( my $ticket = $tickets->Next() ) {
+    print "\n" . $ticket->Id() . ": " if ($verbose);
+
+    # perform some more advanced check
+    if ($condition) {
+        my $condition_obj = $condition->new( TicketObj => $ticket,
+                                             Argument  => $condition_arg );
+
+        # if the condition doesn't apply, get out of here
+
+        next unless ( $condition_obj->IsApplicable );
+        print loc("Condition matches...") if ($verbose);
+    }
+
+    #prepare our action
+    my $action_obj = $action->new( TicketObj => $ticket,
+                                  TemplateObj => $template_obj,
+                                   Argument  => $action_arg );
+
+    #if our preparation, move onto the next ticket
+    next unless ( $action_obj->Prepare );
+    print loc("Action prepared...") if ($verbose);
+
+    #commit our action.
+    next unless ( $action_obj->Commit );
+    print loc("Action committed.") if ($verbose);
+}
+
+# {{{ load_module 
+
+=head2 load_module
+
+Loads a perl module, dying nicely if it can't find it.
+
+=cut
+
+sub load_module {
+    my $modname = shift;
+    eval "require $modname";
+    if ($@) {
+        die loc( "Failed to load module [_1]. ([_2])", $modname, $@ );
+    }
+
+}
+
+# }}}
+
+# {{{ loc 
+
+=head2 loc LIST
+
+Localize this string, with the current user's currentuser object
+
+=cut
+
+sub loc {
+    $CurrentUser->loc(@_);
+}
+
+# }}}
+
+sub help {
+
+    print loc( "[_1] is a tool to act on tickets from an external scheduling tool, such as cron.", $0 )
+      . "\n";
+    print loc("It takes several arguments:") . "\n\n";
+
+    print "    "
+      . loc( "[_1] - Specify the search module you want to use", "--search" )
+      . "\n";
+    print "    "
+      . loc( "[_1] - An argument to pass to [_2]", "--search-argument", "--search" )
+      . "\n";
+
+    print "    "
+      . loc( "[_1] - Specify the condition module you want to use", "--condition" )
+      . "\n";
+    print "    "
+      . loc( "[_1] - An argument to pass to [_2]", "--condition-argument", "--condition" )
+      . "\n";
+    print "    "
+      . loc( "[_1] - Specify the action module you want to use", "--action" )
+      . "\n";
+    print "    "
+      . loc( "[_1] - An argument to pass to [_2]", "--action-argument", "--action" )
+      . "\n";
+    print "    "
+      . loc( "[_1] - Output status updates to STDOUT", "--verbose" ) . "\n";
+    print "\n";
+    print "\n";
+    print loc("Security:")."\n";
+    print loc("This tool allows the user to run arbitrary perl modules from within RT.")." ". 
+        loc("If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT.")." ".
+        loc("It is incredibly important that nonprivileged users not be allowed to run this tool."). " " . 
+        loc("It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool.")."\n";
+    print "\n";
+    print loc("Example:");
+    print "\n";
+    print " "
+      . loc( "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+      )
+      . "\n\n";
+
+    print " sbin/cron_shim \\\n";
+    print
+      "  --search RT::Search::ActiveTicketsInQueue  --search-arg general \\\n";
+    print
+      "  --condition RT::Condition::UntouchedInHours --condition-arg 4 \\\n";
+    print "  --action RT::Action::SetPriority --action-arg 99 \\\n";
+    print "  --verbose\n";
+
+
+    exit(0);
+}
diff --git a/rt/bin/rt-crontool.in b/rt/bin/rt-crontool.in
new file mode 100644 (file)
index 0000000..73b80aa
--- /dev/null
@@ -0,0 +1,210 @@
+#!@PERL@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+use strict;
+use Carp;
+
+use lib ("@RT_LIB_PATH@", "@LOCAL_LIB_PATH@");
+
+package RT;
+
+use Getopt::Long;
+
+use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc);
+use RT::Tickets;
+use RT::Template;
+
+#Clean out all the nasties from the environment
+CleanEnv();
+
+# Load the config file
+RT::LoadConfig();
+
+#Connect to the database and get RT::SystemUser and RT::Nobody loaded
+RT::Init();
+
+#Drop setgid permissions
+RT::DropSetGIDPermissions();
+
+#Get the current user all loaded
+my $CurrentUser = GetCurrentUser();
+
+unless ( $CurrentUser->Id ) {
+    print loc("No RT user found. Please consult your RT administrator.\n");
+    exit(1);
+}
+
+my ( $search, $condition, $action, $search_arg, $condition_arg, $action_arg,
+     $template_id, $help, $verbose );
+GetOptions( "search=s"        => \$search,
+            "search-arg=s"    => \$search_arg,
+            "condition=s"     => \$condition,
+            "condition-arg=s" => \$condition_arg,
+            "action-arg=s"    => \$action_arg,
+            "action=s"        => \$action,
+           "template-id=s"   => \$template_id,
+            "help"            => \$help,
+            "verbose|v"       => \$verbose );
+
+help() if $help;
+
+# We _must_ have a search object
+load_module($search);
+load_module($action)    if ($action);
+load_module($condition) if ($condition);
+
+# load template if specified
+my $template_obj;
+if ($template_id) {
+    $template_obj = RT::Template->new($RT::Nobody);
+    $template_obj->LoadById($template_id);
+}
+
+#At the appointed time:
+
+#find a bunch of tickets
+my $tickets = RT::Tickets->new($CurrentUser);
+my $search  = $search->new( TicketsObj => $tickets, Argument => $search_arg );
+
+$search->Prepare();
+
+# TicketsFound is an RT::Tickets object
+my $tickets = $search->TicketsObj;
+
+#for each ticket we've found
+while ( my $ticket = $tickets->Next() ) {
+    print "\n" . $ticket->Id() . ": " if ($verbose);
+
+    # perform some more advanced check
+    if ($condition) {
+        my $condition_obj = $condition->new( TicketObj => $ticket,
+                                             Argument  => $condition_arg );
+
+        # if the condition doesn't apply, get out of here
+
+        next unless ( $condition_obj->IsApplicable );
+        print loc("Condition matches...") if ($verbose);
+    }
+
+    #prepare our action
+    my $action_obj = $action->new( TicketObj => $ticket,
+                                  TemplateObj => $template_obj,
+                                   Argument  => $action_arg );
+
+    #if our preparation, move onto the next ticket
+    next unless ( $action_obj->Prepare );
+    print loc("Action prepared...") if ($verbose);
+
+    #commit our action.
+    next unless ( $action_obj->Commit );
+    print loc("Action committed.") if ($verbose);
+}
+
+# {{{ load_module 
+
+=head2 load_module
+
+Loads a perl module, dying nicely if it can't find it.
+
+=cut
+
+sub load_module {
+    my $modname = shift;
+    eval "require $modname";
+    if ($@) {
+        die loc( "Failed to load module [_1]. ([_2])", $modname, $@ );
+    }
+
+}
+
+# }}}
+
+# {{{ loc 
+
+=head2 loc LIST
+
+Localize this string, with the current user's currentuser object
+
+=cut
+
+sub loc {
+    $CurrentUser->loc(@_);
+}
+
+# }}}
+
+sub help {
+
+    print loc( "[_1] is a tool to act on tickets from an external scheduling tool, such as cron.", $0 )
+      . "\n";
+    print loc("It takes several arguments:") . "\n\n";
+
+    print "    "
+      . loc( "[_1] - Specify the search module you want to use", "--search" )
+      . "\n";
+    print "    "
+      . loc( "[_1] - An argument to pass to [_2]", "--search-argument", "--search" )
+      . "\n";
+
+    print "    "
+      . loc( "[_1] - Specify the condition module you want to use", "--condition" )
+      . "\n";
+    print "    "
+      . loc( "[_1] - An argument to pass to [_2]", "--condition-argument", "--condition" )
+      . "\n";
+    print "    "
+      . loc( "[_1] - Specify the action module you want to use", "--action" )
+      . "\n";
+    print "    "
+      . loc( "[_1] - An argument to pass to [_2]", "--action-argument", "--action" )
+      . "\n";
+    print "    "
+      . loc( "[_1] - Output status updates to STDOUT", "--verbose" ) . "\n";
+    print "\n";
+    print "\n";
+    print loc("Security:")."\n";
+    print loc("This tool allows the user to run arbitrary perl modules from within RT.")." ". 
+        loc("If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT.")." ".
+        loc("It is incredibly important that nonprivileged users not be allowed to run this tool."). " " . 
+        loc("It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool.")."\n";
+    print "\n";
+    print loc("Example:");
+    print "\n";
+    print " "
+      . loc( "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+      )
+      . "\n\n";
+
+    print " sbin/cron_shim \\\n";
+    print
+      "  --search RT::Search::ActiveTicketsInQueue  --search-arg general \\\n";
+    print
+      "  --condition RT::Condition::UntouchedInHours --condition-arg 4 \\\n";
+    print "  --action RT::Action::SetPriority --action-arg 99 \\\n";
+    print "  --verbose\n";
+
+
+    exit(0);
+}
index e6f0d95..b304436 100755 (executable)
-#!!!PERL!! -w
+#!/usr/bin/perl -w
+# BEGIN LICENSE BLOCK
+#
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+#
+# (Except where explictly superceded by other copyright notices)
+#
+# 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.
+#
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+#
+#
+# END LICENSE BLOCK
+
+=head1 NAME
+
+rt-mailgate - Mail interface to RT3.
+
+=begin testing
+
+use RT::I18N;
+
+
+# {{{ Test new ticket creation by root who is privileged and superuser
+
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: root\@localhost
+To: rt\@example.com
+Subject: This is a test of new ticket creation
+
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+use RT::Tickets;
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok (UNIVERSAL::isa($tick,'RT::Ticket'));
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject eq 'This is a test of new ticket creation', "Created the ticket");
 
-# $Header: /home/cvs/cvsroot/freeside/rt/bin/rt-mailgate,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# (c) 1996-2001 Jesse Vincent <jesse@fsck.com>
-# This software is redistributable under the terms of the GNU GPL
+# }}}
 
 
-package RT;
-use strict;
-use vars qw($VERSION $Handle $Nobody $SystemUser);
-
-$VERSION="!!RT_VERSION!!";
-
-
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
-
-use RT::Interface::Email  qw(CleanEnv LoadConfig DBConnect
-                            GetCurrentUser
-                            GetMessageContent
-                            CheckForLoops 
-                            CheckForSuspiciousSender
-                            CheckForAutoGenerated 
-                            ParseMIMEEntityFromSTDIN
-                            ParseTicketId 
-                            MailError 
-                            ParseCcAddressesFromHead
-                            ParseSenderAddressFromHead 
-                            ParseErrorsToAddressFromHead
-                           );
-
-#Clean out all the nasties from the environment
-CleanEnv();
-
-#Load etc/config.pm and drop privs
-LoadConfig();
-
-#Connect to the database and get RT::SystemUser and RT::Nobody loaded
-DBConnect();
-
-#Drop setgid permissions
-RT::DropSetGIDPermissions();
-
-use RT::Ticket;
-use RT::Queue;
-use MIME::Parser;
-use File::Temp;
-use Mail::Address;
-
-
-#Set some sensible defaults 
-my $Queue = 1;
-my $time = time;
-my $Action = "correspond";  
-
-my ($Verbose, $ReturnTid, $Debug);
-my ($From, $TicketId, $Subject,$SquelchReplies);
-
-# using --owner-from-extension, this will let you set ticket owner on create
-my $AssignTicketTo = undef;
-my ($status, $msg);
-
-# {{{ parse commandline 
-
-while (my $flag = shift @ARGV) {
-    if (($flag eq '-v') or ($flag eq '--verbose')) {
-       $Verbose = 1;
-    }
-    if (($flag eq '-t') or ($flag eq '--ticketid')) {
-       $ReturnTid = 1;
-    }
-    
-    if (($flag eq '-d') or ($flag eq '--debug')) {
-       $RT::Logger->debug("Debug mode enabled\n");
-       $Debug = 1;
-      }
-    
-    if (($flag eq '-q') or ($flag eq '--queue')) {
-       $Queue = shift @ARGV;
-    } 
-    if ($flag eq '--ticket-id-from-extension') {
-       $TicketId = $ENV{'EXTENSION'};
-    }
-    if ($flag eq '--queue-from-extension') {
-       $Queue = $ENV{'EXTENSION'};
-    }
-    if ($flag eq '--owner-from-extension') {
-        $AssignTicketTo = $ENV{'EXTENSION'};
-    }
-
-    if (($flag eq '-a') or ($flag eq '--action')) {
-         $Action = shift @ARGV;
-    } 
-    
-    
-}
+# {{{This is a test of new ticket creation as an unknown user
+
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist\@example.com
+To: rt\@example.com
+Subject: This is a test of new ticket creation as an unknown user
+
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+$tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+$tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject ne 'This is a test of new ticket creation as an unknown user', "failed to create the new ticket from an unprivileged account");
+my $u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist@example.com');
+ok( $u->Id == 0, " user does not exist and was not created by failed ticket submission");
+
 
 # }}}
 
-# get the current mime entity from stdin
-my ($entity, $head) = ParseMIMEEntityFromSTDIN();
+# {{{ now everybody can create tickets.  can a random unkown user create tickets?
 
-#Get someone to send runtime errors to;
-my $ErrorsTo = ParseErrorsToAddressFromHead($head);
+my $g = RT::Group->new($RT::SystemUser);
+$g->LoadSystemInternalGroup('Everyone');
+ok( $g->Id, "Found 'everybody'");
 
-#Get us a current user object.
-my $CurrentUser = GetCurrentUser($head, $entity, $ErrorsTo);
+my ($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CreateTicket');
+ok ($val, "Granted everybody the right to create tickets - $msg");
 
-# We've already performed a warning and sent the mail off to somewhere safe ($RTOwner).
-#  this is _exceedingly_ unlikely but we don't want to keep going if we don't have a current user
+sleep(60); # gotta sleep so the remote process' ACL cache times out
 
-unless ($CurrentUser->Id) {
-       exit(1);
-}
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist\@example.com
+To: rt\@example.com
+Subject: This is a test of new ticket creation as an unknown user
 
-my $MessageId = $head->get('Message-Id') || 
-  "<no-message-id-".time.rand(2000)."\@.$RT::Organization>";
+Blah!
+Foob!
+EOF
+close (MAIL);
 
-#Pull apart the subject line
-$Subject = $head->get('Subject') || "[no subject]";
-chomp $Subject;
 
-# Get the ticket ID unless it's already set
-$TicketId = ParseTicketId($Subject) unless ($TicketId);
+$tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+$tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject eq 'This is a test of new ticket creation as an unknown user', "failed to create the new ticket from an unprivileged account");
+my $u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist@example.com');
+ok( $u->Id != 0, " user does not exist and was created by ticket submission");
 
-#Set up a queue object
-my $QueueObj = RT::Queue->new($CurrentUser);
-$QueueObj->Load($Queue);
-unless ($QueueObj->id ) {
+# }}}
 
-  MailError(To => $RT::OwnerEmail,
-                  Subject => "RT Bounce: $Subject",
-                  Explanation => "RT couldn't find the queue: $Queue",
-                  MIMEObj => $entity);
 
-}
+# {{{  can another random reply to a ticket without being granted privs? answer should be no.
 
-# {{{ Lets check for mail loops of various sorts.
 
-my $IsAutoGenerated = CheckForAutoGenerated($head);
+#($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CreateTicket');
+#ok ($val, "Granted everybody the right to create tickets - $msg");
+#sleep(60); # gotta sleep so the remote process' ACL cache times out
 
-my $IsSuspiciousSender = CheckForSuspiciousSender($head);
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist-2\@example.com
+To: rt\@example.com
+Subject: [example.com #@{[$tick->Id]}] This is a test of a reply as an unknown user
 
-my $IsALoop = CheckForLoops($head);
+Blah!
+Foob!
+EOF
+close (MAIL);
 
+$u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist-2@example.com');
+ok( $u->Id == 0, " user does not exist and was not created by ticket correspondence submission");
+# }}}
+# {{{  can another random reply to a ticket after being granted privs? answer should be yes
 
-#If the message is autogenerated, we need to know, so we can not 
-# send mail to the sender
-if ($IsSuspiciousSender || $IsAutoGenerated || $IsALoop) {
-    $SquelchReplies = 1;
 
-    $ErrorsTo = $RT::OwnerEmail;
-    
-    #TODO: Is what we want to do here really 
-    #  "Make the requestor cease to get mail from RT"?
-    # This might wreak havoc with vacation-mailing users.
-    # Maybe have a "disabled for bouncing" state that gets
-    # turned off when we get a legit incoming message
+($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'ReplyToTicket');
+ok ($val, "Granted everybody the right to reply to  tickets - $msg");
+sleep(60); # gotta sleep so the remote process' ACL cache times out
 
-}
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist-2\@example.com
+To: rt\@example.com
+Subject: [example.com #@{[$tick->Id]}] This is a test of a reply as an unknown user
 
+Blah!
+Foob!
+EOF
+close (MAIL);
 
-# {{{ Warn someone  if it's a loop
-
-# Warn someone if it's a loop, before we drop it on the ground
-if ($IsALoop) {
-    $RT::Logger->crit("RT Received mail ($MessageId) from itself.");
-    
-    #Should we mail it to RTOwner?
-    if ($RT::LoopsToRTOwner) {
-       MailError(To => $RT::OwnerEmail,
-                 Subject => "RT Bounce: $Subject",
-                 Explanation => "RT thinks this message may be a bounce",
-                 MIMEObj => $entity);
-       
-       #Do we actually want to store it?
-       exit unless ($RT::StoreLoops);
-    }
-}
+
+$u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist-2@example.com');
+ok( $u->Id != 0, " user exists and was created by ticket correspondence submission");
 
 # }}}
 
+# {{{  can another random comment on a ticket without being granted privs? answer should be no.
 
-   #Don't let the user stuff the RT-Squelch-Replies-To header.
-    if ($head->get('RT-Squelch-Replies-To')) {
-        $head->add('RT-Relocated-Squelch-Replies-To',
-                   $head->get('RT-Squelch-Replies-To'));
-        $head->delete('RT-Squelch-Replies-To')
-    }
 
+#($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CreateTicket');
+#ok ($val, "Granted everybody the right to create tickets - $msg");
+#sleep(60); # gotta sleep so the remote process' ACL cache times out
 
-if ($SquelchReplies) {
-    ## TODO: This is a hack.  It should be some other way to
-    ## indicate that the transaction should be "silent".
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action comment"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist-3\@example.com
+To: rt\@example.com
+Subject: [example.com #@{[$tick->Id]}] This is a test of a comment as an unknown user
 
-    my ($Sender, $junk) = ParseSenderAddressFromHead($head);
-    $head->add('RT-Squelch-Replies-To', $Sender);
-}
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+$u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist-3@example.com');
+ok( $u->Id == 0, " user does not exist and was not created by ticket comment submission");
 
 # }}}
+# {{{  can another random reply to a ticket after being granted privs? answer should be yes
 
 
-# {{{ If we require that the sender be found in an external DB and they're not
-# forward this message to RTOwner
+($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CommentOnTicket');
+ok ($val, "Granted everybody the right to reply to  tickets - $msg");
+sleep(60); # gotta sleep so the remote process' ACL cache times out
 
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action comment"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist-3\@example.com
+To: rt\@example.com
+Subject: [example.com #@{[$tick->Id]}] This is a test of a comment as an unknown user
 
+Blah!
+Foob!
+EOF
+close (MAIL);
 
-if ($RT::LookupSenderInExternalDatabase && 
-    $RT::SenderMustExistInExternalDatabase )  {
 
-    MailError(To => $RT::OwnerEmail,
-             Subject => "RT Bounce: $Subject",
-             Explanation => "RT couldn't find requestor via its external database lookup",
-             MIMEObj => $entity);
-    
-}
+$u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist-3@example.com');
+ok( $u->Id != 0, " user exists and was created by ticket comment submission");
 
 # }}}
 
-# {{{ elsif we don't have a ticket Id, we're creating a new ticket
-
-
-
-elsif (!defined($TicketId)) {
-    
-    # {{{ Create a new ticket
-    if ($Action =~ /correspond/) {
-       
-       #    open a new ticket 
-       my @Requestors = ($CurrentUser->id);
-       
-       my @Cc;
-       if ($RT::ParseNewMessageForTicketCcs) {
-               @Cc = ParseCcAddressesFromHead(Head => $head, 
-                                       CurrentUser => $CurrentUser,
-                                       QueueObj => $QueueObj );
-       }
-
-       my $Ticket = new RT::Ticket($CurrentUser);
-       my ($id, $Transaction, $ErrStr) = 
-         $Ticket->Create ( Queue => $Queue,
-                           Subject => $Subject,
-                            Owner => $AssignTicketTo,
-                           Requestor => \@Requestors,
-                           Cc => \@Cc,
-                           MIMEObj => $entity
-                         );
-       if ($id == 0 ) {
-           MailError( To => $ErrorsTo,
-                      Subject => "Ticket creation failed",
-                      Explanation => $ErrStr,
-                      MIMEObj => $entity
-                    );
-           $RT::Logger->error("Create failed: $id / $Transaction / $ErrStr ");
-       }       
-    }
-
-    # }}}
-    
-    else {
-       #TODO Return an error message
-       MailError( To => $ErrorsTo,
-                  Subject => "No ticket id specified",
-                  Explanation => "$Action aliases require a TicketId to work on",
-                  MIMEObj => $entity
-                );
-       
-       $RT::Logger->crit("$Action aliases require a TicketId to work on ".
-                         "(from ".$CurrentUser->UserObj->EmailAddress.") ".
-                         $MessageId);
-    }
-}
+# {{{ Testing preservation of binary attachments
+
+# Get a binary blob (Best Practical logo) 
+
+# Create a mime entity with an attachment
+
+use MIME::Entity;
+my $entity = MIME::Entity->build( From => 'root@localhost',
+                                 To => 'rt@localhost',
+                                Subject => 'binary attachment test',
+                                Data => ['This is a test of a binary attachment']);
+
+# currently in lib/t/autogen
+$entity->attach(Path => '../../../html/NoAuth/images/spacer.gif', 
+                Type => 'image/gif',
+                Encoding => 'base64');
+
+# Create a ticket with a binary attachment
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+
+$entity->print(\*MAIL);
+
+close (MAIL);
+
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0');
+ $tick = $tickets->First();
+ok (UNIVERSAL::isa($tick,'RT::Ticket'));
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject eq 'binary attachment test', "Created the ticket - ".$tick->Id);
+
+my $file = `cat ../../../html/NoAuth/images/spacer.gif`;
+ok ($file, "Read in the logo image");
+
+
+        use Digest::MD5;
+warn "for the raw file the content is ".Digest::MD5::md5_base64($file);
+
+
+
+# Verify that the binary attachment is valid in the database
+my $attachments = RT::Attachments->new($RT::SystemUser);
+$attachments->Limit(FIELD => 'ContentType', VALUE => 'image/gif');
+ok ($attachments->Count == 1, 'Found only one gif in the database');
+my $attachment = $attachments->First;
+my $acontent = $attachment->Content;
+
+        warn "coming from the  database, the content is ".Digest::MD5::md5_base64($acontent);
+
+is( $acontent, $file, 'The attachment isn\'t screwed up in the database.');
+# Log in as root
+use Getopt::Long;
+use LWP::UserAgent;
+
+
+# Grab the binary attachment via the web ui
+my $ua      = LWP::UserAgent->new();
+
+my $full_url = "http://localhost/Ticket/Attachment/".$attachment->TransactionId."/".$attachment->id."/spacer.gif?&user=root&pass=password";
+my $r = $ua->get( $full_url);
+
+
+# Verify that the downloaded attachment is the same as what we uploaded.
+is($file, $r->content, 'The attachment isn\'t screwed up in download');
+
+
 
 # }}}
 
-# {{{ If we've got a ticket ID, update the ticket
-
-else {
-    
-    #   If the action is comment, add a comment.
-    if ($Action =~ /comment/i){
-       
-       my $Ticket = new RT::Ticket($CurrentUser);
-       $Ticket->Load($TicketId);
-       unless ($Ticket->Id) {
-           MailError( To => $ErrorsTo,
-                      Subject => "Comment not recorded",
-                      Explanation => "Could not find a ticket with id $TicketId",
-                      MIMEObj => $entity
-                    );
-           #Return an error message saying that Ticket "#foo" wasn't found.
-       }
-       
-       ($status, $msg) = $Ticket->Comment(MIMEObj=>$entity);
-       unless ($status) {
-           #Warn the sender that we couldn't actually submit the comment.
-           MailError( To => $ErrorsTo,
-                      Subject => "Comment not recorded",
-                      Explanation => $msg,
-                      MIMEObj => $entity
-                    );
-       }       
-    }
-
-    # If the message is correspondence, add it to the ticket
-    elsif ($Action =~ /correspond/i) {
-       my $Ticket = RT::Ticket->new($CurrentUser);
-       $Ticket->Load($TicketId);
-       
-       #TODO: Check for error conditions
-       ($status, $msg) = $Ticket->Correspond(MIMEObj => $entity);
-       unless ($status) {
-
-           #Return mail to the sender with an error
-           MailError( To => $ErrorsTo,
-                      Subject => "Correspondence not recorded",
-                      Explanation => $msg,
-                      MIMEObj => $entity
-                    );
-       }
-    }
-
-    else {
-       #Return mail to the sender with an error
-           MailError( To => $ErrorsTo,
-                      Subject => "RT Configuration error",
-                      Explanation => "'$Action' not a recognized action.".
-                                     " Your RT administrator has misconfigured ".
-                                     "the mail aliases which invoke RT" ,
-                      MIMEObj => $entity
-                    );
-
-       $RT::Logger->crit("$Action type unknown for $MessageId");
-       
-    }
-    
-}
+# {{{ Simple I18N testing
+
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+                                                                         
+print MAIL <<EOF;
+From: root\@localhost
+To: rtemail\@example.com
+Subject: This is a test of I18N ticket creation
+Content-Type: text/plain; charset="utf-8"
+
+2 accented lines
+\303\242\303\252\303\256\303\264\303\273
+\303\241\303\251\303\255\303\263\303\272
+bye
+EOF
+close (MAIL);
+
+my $unitickets = RT::Tickets->new($RT::SystemUser);
+$unitickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$unitickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0');
+my $unitick = $unitickets->First();
+ok (UNIVERSAL::isa($unitick,'RT::Ticket'));
+ok ($unitick->Id, "found ticket ".$unitick->Id);
+ok ($unitick->Subject eq 'This is a test of I18N ticket creation', "Created the ticket - ". $unitick->Subject);
+
+
+
+my $unistring = "\303\241\303\251\303\255\303\263\303\272";
+Encode::_utf8_on($unistring);
+is ($unitick->Transactions->First->Content, $unitick->Transactions->First->Attachments->First->Content, "Content is ". $unitick->Transactions->First->Attachments->First->Content);
+ok($unitick->Transactions->First->Attachments->First->Content =~ /$unistring/i, $unitick->Id." appears to be unicode ". $unitick->Transactions->First->Attachments->First->Id);
+# supposedly I18N fails on the second message sent in.
+
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+                                                                         
+print MAIL <<EOF;
+From: root\@localhost
+To: rtemail\@example.com
+Subject: This is a test of I18N ticket creation
+Content-Type: text/plain; charset="utf-8"
+
+2 accented lines
+\303\242\303\252\303\256\303\264\303\273
+\303\241\303\251\303\255\303\263\303\272
+bye
+EOF
+close (MAIL);
+
+my $tickets2 = RT::Tickets->new($RT::SystemUser);
+$tickets2->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets2->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0');
+my $tick2 = $tickets2->First();
+ok (UNIVERSAL::isa($tick2,'RT::Ticket'));
+ok ($tick2->Id, "found ticket ".$tick2->Id);
+ok ($tick2->Subject eq 'This is a test of I18N ticket creation', "Created the ticket");
+
+
+
+my $unistring = "\303\241\303\251\303\255\303\263\303\272";
+Encode::_utf8_on($unistring);
+
+ok ($tick2->Transactions->First->Content =~ $unistring, "It appears to be unicode - ".$tick2->Transactions->First->Content);
 
 # }}}
 
-$RT::Handle->Disconnect();
 
+($val,$msg) = $g->PrincipalObj->RevokeRight(Right => 'CreateTicket');
+ok ($val, $msg);
+
+
+
+=end testing
+
+=cut
+
+
+use strict;
+use Getopt::Long;
+use LWP::UserAgent;
+
+use constant EX_TEMPFAIL => 75;
+
+my %opts;
+GetOptions( \%opts, "queue=s", "action=s", "url=s", "jar=s", "help", "debug", "extension=s" );
+
+if ( $opts{help} ) {
+    require Pod::Usage;
+    import Pod::Usage;
+    pod2usage("RT Mail Gateway\n");
+    exit 1;    # Don't want to succeed if this is really an email!
+}
+
+for (qw(url)) {
+    die "$0 invoked improperly\n\nNo $_ provided to mail gateway!\n" unless $opts{$_};
+}
+
+undef $/;
+my $message = <>;
+my $ua      = LWP::UserAgent->new();
+$ua->cookie_jar( { file => $opts{jar} } );
+
+my %args = (
+    queue   => $opts{queue},
+    action  => $opts{action},
+    message => $message,
+    SessionType => 'REST',    # Surpress login box
+);
+
+
+if ($opts{'extension'}) {
+        $args{$opts{'extension'}} = $ENV{'EXTENSION'};
+}
+
+# Set up cookie here.
+
+my $full_url = $opts{'url'}. "/REST/1.0/NoAuth/mail-gateway";
+warn "Connecting to $full_url" if $opts{'debug'};
+
+
+
+my $r = $ua->post( $full_url, {%args} );
+check_failure($r);
+
+my $content = $r->content;
+warn $content if ($opts{debug});
+
+if ( $content !~ /^(ok|not ok)/ ) {
+
+    # It's not the server's fault if the mail is bogus. We just want to know that
+    # *something* came out of the server.
+    die <<EOF
+RT server error.
+
+The RT server which handled your email did not behave as expected. It
+said:
+
+$content
+EOF
+
+}
+
+sub check_failure {
+    my $r = shift;
+    return if $r->is_success();
+
+    # This ordinarily oughtn't to be able to happen, suggests a bug in RT.
+    # So only load these heavy modules when they're needed.
+    require HTML::TreeBuilder;
+    require HTML::FormatText;
+
+    my $error = $r->error_as_HTML;
+    my $tree  = HTML::TreeBuilder->new->parse($error);
+    $tree->eof;
+
+    # It'll be a cold day in hell before RT sends out bounces in HTML
+    my $formatter = HTML::FormatText->new( leftmargin  => 0,
+                                           rightmargin => 50 );
+    warn $formatter->format($tree);
+    warn "This is $0 exiting because of an undefined server error" if ($opts{debug});
+    exit EX_TEMPFAIL;
+}
+
+
+=head1 SYNOPSIS
+
+    rt-mailgate --help : this text
+
+Usual invocation (from MTA):
+
+    rt-mailgate --action (correspond|comment) --queue queuename
+                --url http://your.rt.server/
+                [ --extension (queue|action|ticket)
+
+See C<man rt-mailgate> for more.
+
+=head1 OPTIONS
+
+=over 3
+
+=item C<--action>
+
+Specifies whether this is a correspondence or comment address.
+
+=item C<--queue>
+
+Reflects which queue this address handles.
+
+=item C<--url>
+
+The location of the web server for your RT instance.
+
+
+=item C<--extension> OPTIONAL
+
+Some MTAs will route mail sent to user-foo@host or user+foo@host to user@host
+and present "foo" in the environment variable $EXTENSION. By specifying
+the value "queue" for this parameter, the queue this message should be
+submitted to will be set to the value of $EXTENSION. By specifying
+"ticket", $EXTENSION will be interpreted as the id of the ticket this message
+is related to.  "action" will allow the user to specify either "comment" or
+"correspond" in the address extension.
+
+
+=head1 DESCRIPTION
+
+The RT mail gateway is the primary mechanism for communicating with RT
+via email. This program simply directs the email to the RT web server,
+which handles filing correspondence and sending out any required mail.
+It is designed to be run as part of the mail delivery process, either
+called directly by the MTA or C<procmail>, or in a F<.forward> or
+equivalent.
+
+=head1 SETUP
+
+Much of the set up of the mail gateway depends on your MTA and mail
+routing configuration. However, you will need first of all to create an
+RT user for the mail gateway and assign it a password; this helps to
+ensure that mail coming into the web server did originate from the
+gateway.
+
+Next, you need to route mail to C<rt-mailgate> for the queues you're
+monitoring. For instance, if you're using F</etc/aliases> and you have a
+"bugs" queue, you will want something like this:
+
+    bugs:         "|/opt/rt3/bin/rt-mailgate --queue bugs --action correspond
+              --url http://rt.mycorp.com/"
+
+    bugs-comment: "|/opt/rt3/bin/rt-mailgate --queue bugs --action comment
+              --url http://rt.mycorp.com/"
+
+Note that you don't have to run your RT server on your mail server, as
+the mail gateway will happily relay to a different machine.
+
+=head1 CUSTOMIZATION
+
+By default, the mail gateway will accept mail from anyone. However,
+there are situations in which you will want to authenticate users
+before allowing them to communicate with the system. You can do this
+via a plug-in mechanism in the RT configuration.
+
+You can set the array C<@RT::MailPlugins> to be a list of plugins. The
+default plugin, if this is not given, is C<Auth::MailFrom> - that is,
+authentication of the person is done based on the C<From> header of the
+email. If you have additional filters or authentication mechanisms, you
+can list them here and they will be called in order:
+
+    @RT::MailPlugins = (
+        "Filter::SpamAssassin",
+        "Auth::LDAP",
+        # ...
+    );
+
+See the documentation for any additional plugins you have.
+
+You may also put Perl subroutines into the C<@RT::MailPlugins> array, if
+they behave as described below.
+
+=head1 WRITING PLUGINS
+
+What's actually going on in the above is that C<@RT::MailPlugins> is a
+list of Perl modules; RT prepends C<RT::Interface::Email::> to the name,
+to form a package name, and then C<use>'s this module. The module is
+expected to provide a C<GetCurrentUser> subroutine, which takes a hash of
+several parameters:
+
+=over 4
+
+=item Message
+
+A C<MIME::Entity> object representing the email
+=item CurrentUser
+
+An C<RT::CurrentUser> object
+
+=item AuthStat
+
+The authentication level returned from the previous plugin.
+
+=item Ticket [OPTIONAL]
+
+The ticket under discussion
+
+=item Queue [OPTIONAL]
+
+If we don't already have a ticket id, we need to know which queue we're talking about
+
+=item Action
 
-# Everything below this line is a helper sub. most of them will eventually
-# move to Interface::Email
+The action being performed. At the moment, it's one of "comment" or "correspond"
 
-#When we call die, trap it and log->crit with the value of the die.
-$SIG{__DIE__}  = sub {
-    unless ($^S || !defined $^S ) {
-        $RT::Logger->crit("$_[0]");
-       MailError( To => $ErrorsTo,  
-                  Bcc => $RT::OwnerEmail,
-                  Subject => "RT Critical error. Message not recorded!",
-                  Explanation => "$_[0]",
-                  MIMEObj => $entity
-                );
-       exit(-1);
-    }
-    else {
-        #Get out of here if we're in an eval
-        die $_[0];
-    }
-};
+=back 4
 
+It returns two values, the new C<RT::CurrentUser> object, and the new
+authentication level. The authentication level can be zero, not allowed
+to communicate with RT at all, (a "permission denied" error is mailed to
+the correspondent) or one, which is the normal mode of operation.
+Additionally, if C<-1> is returned, then the processing of the plug-ins
+stops immediately and the message is ignored.
 
+=cut
 
-1;
diff --git a/rt/bin/rt-mailgate.in b/rt/bin/rt-mailgate.in
new file mode 100644 (file)
index 0000000..304fcbc
--- /dev/null
@@ -0,0 +1,587 @@
+#!@PERL@ -w
+# BEGIN LICENSE BLOCK
+#
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+#
+# (Except where explictly superceded by other copyright notices)
+#
+# 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.
+#
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+#
+#
+# END LICENSE BLOCK
+
+=head1 NAME
+
+rt-mailgate - Mail interface to RT3.
+
+=begin testing
+
+use RT::I18N;
+
+
+# {{{ Test new ticket creation by root who is privileged and superuser
+
+ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: root\@localhost
+To: rt\@example.com
+Subject: This is a test of new ticket creation
+
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+use RT::Tickets;
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok (UNIVERSAL::isa($tick,'RT::Ticket'));
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject eq 'This is a test of new ticket creation', "Created the ticket");
+
+# }}}
+
+
+# {{{This is a test of new ticket creation as an unknown user
+
+ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist\@example.com
+To: rt\@example.com
+Subject: This is a test of new ticket creation as an unknown user
+
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+$tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+$tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject ne 'This is a test of new ticket creation as an unknown user', "failed to create the new ticket from an unprivileged account");
+my $u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist@example.com');
+ok( $u->Id == 0, " user does not exist and was not created by failed ticket submission");
+
+
+# }}}
+
+# {{{ now everybody can create tickets.  can a random unkown user create tickets?
+
+my $g = RT::Group->new($RT::SystemUser);
+$g->LoadSystemInternalGroup('Everyone');
+ok( $g->Id, "Found 'everybody'");
+
+my ($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CreateTicket');
+ok ($val, "Granted everybody the right to create tickets - $msg");
+
+sleep(60); # gotta sleep so the remote process' ACL cache times out
+
+ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist\@example.com
+To: rt\@example.com
+Subject: This is a test of new ticket creation as an unknown user
+
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+
+$tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+$tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject eq 'This is a test of new ticket creation as an unknown user', "failed to create the new ticket from an unprivileged account");
+my $u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist@example.com');
+ok( $u->Id != 0, " user does not exist and was created by ticket submission");
+
+# }}}
+
+
+# {{{  can another random reply to a ticket without being granted privs? answer should be no.
+
+
+#($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CreateTicket');
+#ok ($val, "Granted everybody the right to create tickets - $msg");
+#sleep(60); # gotta sleep so the remote process' ACL cache times out
+
+ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist-2\@example.com
+To: rt\@example.com
+Subject: [example.com #@{[$tick->Id]}] This is a test of a reply as an unknown user
+
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+$u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist-2@example.com');
+ok( $u->Id == 0, " user does not exist and was not created by ticket correspondence submission");
+# }}}
+# {{{  can another random reply to a ticket after being granted privs? answer should be yes
+
+
+($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'ReplyToTicket');
+ok ($val, "Granted everybody the right to reply to  tickets - $msg");
+sleep(60); # gotta sleep so the remote process' ACL cache times out
+
+ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist-2\@example.com
+To: rt\@example.com
+Subject: [example.com #@{[$tick->Id]}] This is a test of a reply as an unknown user
+
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+
+$u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist-2@example.com');
+ok( $u->Id != 0, " user exists and was created by ticket correspondence submission");
+
+# }}}
+
+# {{{  can another random comment on a ticket without being granted privs? answer should be no.
+
+
+#($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CreateTicket');
+#ok ($val, "Granted everybody the right to create tickets - $msg");
+#sleep(60); # gotta sleep so the remote process' ACL cache times out
+
+ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action comment"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist-3\@example.com
+To: rt\@example.com
+Subject: [example.com #@{[$tick->Id]}] This is a test of a comment as an unknown user
+
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+$u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist-3@example.com');
+ok( $u->Id == 0, " user does not exist and was not created by ticket comment submission");
+
+# }}}
+# {{{  can another random reply to a ticket after being granted privs? answer should be yes
+
+
+($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CommentOnTicket');
+ok ($val, "Granted everybody the right to reply to  tickets - $msg");
+sleep(60); # gotta sleep so the remote process' ACL cache times out
+
+ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action comment"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist-3\@example.com
+To: rt\@example.com
+Subject: [example.com #@{[$tick->Id]}] This is a test of a comment as an unknown user
+
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+
+$u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist-3@example.com');
+ok( $u->Id != 0, " user exists and was created by ticket comment submission");
+
+# }}}
+
+# {{{ Testing preservation of binary attachments
+
+# Get a binary blob (Best Practical logo) 
+
+# Create a mime entity with an attachment
+
+use MIME::Entity;
+my $entity = MIME::Entity->build( From => 'root@localhost',
+                                 To => 'rt@localhost',
+                                Subject => 'binary attachment test',
+                                Data => ['This is a test of a binary attachment']);
+
+# currently in lib/t/autogen
+$entity->attach(Path => '../../../html/NoAuth/images/spacer.gif', 
+                Type => 'image/gif',
+                Encoding => 'base64');
+
+# Create a ticket with a binary attachment
+ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+
+$entity->print(\*MAIL);
+
+close (MAIL);
+
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0');
+ $tick = $tickets->First();
+ok (UNIVERSAL::isa($tick,'RT::Ticket'));
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject eq 'binary attachment test', "Created the ticket - ".$tick->Id);
+
+my $file = `cat ../../../html/NoAuth/images/spacer.gif`;
+ok ($file, "Read in the logo image");
+
+
+        use Digest::MD5;
+warn "for the raw file the content is ".Digest::MD5::md5_base64($file);
+
+
+
+# Verify that the binary attachment is valid in the database
+my $attachments = RT::Attachments->new($RT::SystemUser);
+$attachments->Limit(FIELD => 'ContentType', VALUE => 'image/gif');
+ok ($attachments->Count == 1, 'Found only one gif in the database');
+my $attachment = $attachments->First;
+my $acontent = $attachment->Content;
+
+        warn "coming from the  database, the content is ".Digest::MD5::md5_base64($acontent);
+
+is( $acontent, $file, 'The attachment isn\'t screwed up in the database.');
+# Log in as root
+use Getopt::Long;
+use LWP::UserAgent;
+
+
+# Grab the binary attachment via the web ui
+my $ua      = LWP::UserAgent->new();
+
+my $full_url = "http://localhost/Ticket/Attachment/".$attachment->TransactionId."/".$attachment->id."/spacer.gif?&user=root&pass=password";
+my $r = $ua->get( $full_url);
+
+
+# Verify that the downloaded attachment is the same as what we uploaded.
+is($file, $r->content, 'The attachment isn\'t screwed up in download');
+
+
+
+# }}}
+
+# {{{ Simple I18N testing
+
+ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+                                                                         
+print MAIL <<EOF;
+From: root\@localhost
+To: rtemail\@example.com
+Subject: This is a test of I18N ticket creation
+Content-Type: text/plain; charset="utf-8"
+
+2 accented lines
+\303\242\303\252\303\256\303\264\303\273
+\303\241\303\251\303\255\303\263\303\272
+bye
+EOF
+close (MAIL);
+
+my $unitickets = RT::Tickets->new($RT::SystemUser);
+$unitickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$unitickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0');
+my $unitick = $unitickets->First();
+ok (UNIVERSAL::isa($unitick,'RT::Ticket'));
+ok ($unitick->Id, "found ticket ".$unitick->Id);
+ok ($unitick->Subject eq 'This is a test of I18N ticket creation', "Created the ticket - ". $unitick->Subject);
+
+
+
+my $unistring = "\303\241\303\251\303\255\303\263\303\272";
+Encode::_utf8_on($unistring);
+is ($unitick->Transactions->First->Content, $unitick->Transactions->First->Attachments->First->Content, "Content is ". $unitick->Transactions->First->Attachments->First->Content);
+ok($unitick->Transactions->First->Attachments->First->Content =~ /$unistring/i, $unitick->Id." appears to be unicode ". $unitick->Transactions->First->Attachments->First->Id);
+# supposedly I18N fails on the second message sent in.
+
+ok(open(MAIL, "|@RT_BIN_PATH@/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+                                                                         
+print MAIL <<EOF;
+From: root\@localhost
+To: rtemail\@example.com
+Subject: This is a test of I18N ticket creation
+Content-Type: text/plain; charset="utf-8"
+
+2 accented lines
+\303\242\303\252\303\256\303\264\303\273
+\303\241\303\251\303\255\303\263\303\272
+bye
+EOF
+close (MAIL);
+
+my $tickets2 = RT::Tickets->new($RT::SystemUser);
+$tickets2->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets2->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0');
+my $tick2 = $tickets2->First();
+ok (UNIVERSAL::isa($tick2,'RT::Ticket'));
+ok ($tick2->Id, "found ticket ".$tick2->Id);
+ok ($tick2->Subject eq 'This is a test of I18N ticket creation', "Created the ticket");
+
+
+
+my $unistring = "\303\241\303\251\303\255\303\263\303\272";
+Encode::_utf8_on($unistring);
+
+ok ($tick2->Transactions->First->Content =~ $unistring, "It appears to be unicode - ".$tick2->Transactions->First->Content);
+
+# }}}
+
+
+($val,$msg) = $g->PrincipalObj->RevokeRight(Right => 'CreateTicket');
+ok ($val, $msg);
+
+
+
+=end testing
+
+=cut
+
+
+use strict;
+use Getopt::Long;
+use LWP::UserAgent;
+
+use constant EX_TEMPFAIL => 75;
+
+my %opts;
+GetOptions( \%opts, "queue=s", "action=s", "url=s", "jar=s", "help", "debug", "extension=s" );
+
+if ( $opts{help} ) {
+    require Pod::Usage;
+    import Pod::Usage;
+    pod2usage("RT Mail Gateway\n");
+    exit 1;    # Don't want to succeed if this is really an email!
+}
+
+for (qw(url)) {
+    die "$0 invoked improperly\n\nNo $_ provided to mail gateway!\n" unless $opts{$_};
+}
+
+undef $/;
+my $message = <>;
+my $ua      = LWP::UserAgent->new();
+$ua->cookie_jar( { file => $opts{jar} } );
+
+my %args = (
+    queue   => $opts{queue},
+    action  => $opts{action},
+    message => $message,
+    SessionType => 'REST',    # Surpress login box
+);
+
+
+if ($opts{'extension'}) {
+        $args{$opts{'extension'}} = $ENV{'EXTENSION'};
+}
+
+# Set up cookie here.
+
+my $full_url = $opts{'url'}. "/REST/1.0/NoAuth/mail-gateway";
+warn "Connecting to $full_url" if $opts{'debug'};
+
+
+
+my $r = $ua->post( $full_url, {%args} );
+check_failure($r);
+
+my $content = $r->content;
+warn $content if ($opts{debug});
+
+if ( $content !~ /^(ok|not ok)/ ) {
+
+    # It's not the server's fault if the mail is bogus. We just want to know that
+    # *something* came out of the server.
+    die <<EOF
+RT server error.
+
+The RT server which handled your email did not behave as expected. It
+said:
+
+$content
+EOF
+
+}
+
+sub check_failure {
+    my $r = shift;
+    return if $r->is_success();
+
+    # This ordinarily oughtn't to be able to happen, suggests a bug in RT.
+    # So only load these heavy modules when they're needed.
+    require HTML::TreeBuilder;
+    require HTML::FormatText;
+
+    my $error = $r->error_as_HTML;
+    my $tree  = HTML::TreeBuilder->new->parse($error);
+    $tree->eof;
+
+    # It'll be a cold day in hell before RT sends out bounces in HTML
+    my $formatter = HTML::FormatText->new( leftmargin  => 0,
+                                           rightmargin => 50 );
+    warn $formatter->format($tree);
+    warn "This is $0 exiting because of an undefined server error" if ($opts{debug});
+    exit EX_TEMPFAIL;
+}
+
+
+=head1 SYNOPSIS
+
+    rt-mailgate --help : this text
+
+Usual invocation (from MTA):
+
+    rt-mailgate --action (correspond|comment) --queue queuename
+                --url http://your.rt.server/
+                [ --extension (queue|action|ticket)
+
+See C<man rt-mailgate> for more.
+
+=head1 OPTIONS
+
+=over 3
+
+=item C<--action>
+
+Specifies whether this is a correspondence or comment address.
+
+=item C<--queue>
+
+Reflects which queue this address handles.
+
+=item C<--url>
+
+The location of the web server for your RT instance.
+
+
+=item C<--extension> OPTIONAL
+
+Some MTAs will route mail sent to user-foo@host or user+foo@host to user@host
+and present "foo" in the environment variable $EXTENSION. By specifying
+the value "queue" for this parameter, the queue this message should be
+submitted to will be set to the value of $EXTENSION. By specifying
+"ticket", $EXTENSION will be interpreted as the id of the ticket this message
+is related to.  "action" will allow the user to specify either "comment" or
+"correspond" in the address extension.
+
+
+=head1 DESCRIPTION
+
+The RT mail gateway is the primary mechanism for communicating with RT
+via email. This program simply directs the email to the RT web server,
+which handles filing correspondence and sending out any required mail.
+It is designed to be run as part of the mail delivery process, either
+called directly by the MTA or C<procmail>, or in a F<.forward> or
+equivalent.
+
+=head1 SETUP
+
+Much of the set up of the mail gateway depends on your MTA and mail
+routing configuration. However, you will need first of all to create an
+RT user for the mail gateway and assign it a password; this helps to
+ensure that mail coming into the web server did originate from the
+gateway.
+
+Next, you need to route mail to C<rt-mailgate> for the queues you're
+monitoring. For instance, if you're using F</etc/aliases> and you have a
+"bugs" queue, you will want something like this:
+
+    bugs:         "|/opt/rt3/bin/rt-mailgate --queue bugs --action correspond
+              --url http://rt.mycorp.com/"
+
+    bugs-comment: "|/opt/rt3/bin/rt-mailgate --queue bugs --action comment
+              --url http://rt.mycorp.com/"
+
+Note that you don't have to run your RT server on your mail server, as
+the mail gateway will happily relay to a different machine.
+
+=head1 CUSTOMIZATION
+
+By default, the mail gateway will accept mail from anyone. However,
+there are situations in which you will want to authenticate users
+before allowing them to communicate with the system. You can do this
+via a plug-in mechanism in the RT configuration.
+
+You can set the array C<@RT::MailPlugins> to be a list of plugins. The
+default plugin, if this is not given, is C<Auth::MailFrom> - that is,
+authentication of the person is done based on the C<From> header of the
+email. If you have additional filters or authentication mechanisms, you
+can list them here and they will be called in order:
+
+    @RT::MailPlugins = (
+        "Filter::SpamAssassin",
+        "Auth::LDAP",
+        # ...
+    );
+
+See the documentation for any additional plugins you have.
+
+You may also put Perl subroutines into the C<@RT::MailPlugins> array, if
+they behave as described below.
+
+=head1 WRITING PLUGINS
+
+What's actually going on in the above is that C<@RT::MailPlugins> is a
+list of Perl modules; RT prepends C<RT::Interface::Email::> to the name,
+to form a package name, and then C<use>'s this module. The module is
+expected to provide a C<GetCurrentUser> subroutine, which takes a hash of
+several parameters:
+
+=over 4
+
+=item Message
+
+A C<MIME::Entity> object representing the email
+=item CurrentUser
+
+An C<RT::CurrentUser> object
+
+=item AuthStat
+
+The authentication level returned from the previous plugin.
+
+=item Ticket [OPTIONAL]
+
+The ticket under discussion
+
+=item Queue [OPTIONAL]
+
+If we don't already have a ticket id, we need to know which queue we're talking about
+
+=item Action
+
+The action being performed. At the moment, it's one of "comment" or "correspond"
+
+=back 4
+
+It returns two values, the new C<RT::CurrentUser> object, and the new
+authentication level. The authentication level can be zero, not allowed
+to communicate with RT at all, (a "permission denied" error is mailed to
+the correspondent) or one, which is the normal mode of operation.
+Additionally, if C<-1> is returned, then the processing of the plug-ins
+stops immediately and the message is ignored.
+
+=cut
+
diff --git a/rt/bin/rtadmin b/rt/bin/rtadmin
deleted file mode 100644 (file)
index 25ba1b0..0000000
+++ /dev/null
@@ -1,1040 +0,0 @@
-#!!!PERL!! -w
-#
-# $Header: /home/cvs/cvsroot/freeside/rt/bin/Attic/rtadmin,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# RT is (c) 1996-2001 Jesse Vincent <jesse@fsck.com>
-
-use strict;
-use Carp;
-use Getopt::Long qw(:config pass_through);
-
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
-
-use RT::Interface::CLI  qw(CleanEnv LoadConfig DBConnect 
-                          GetCurrentUser GetMessageContent);
-
-#Clean out all the nasties from the environment
-CleanEnv();
-
-#Load etc/config.pm and drop privs
-LoadConfig();
-
-#Connect to the database and get RT::SystemUser and RT::Nobody loaded
-DBConnect();
-
-#Drop setgid permissions
-RT::DropSetGIDPermissions();
-
-#Get the current user all loaded
-my $CurrentUser = GetCurrentUser();
-
-unless ($CurrentUser->Id) {
-        print "No RT user found. Please consult your RT administrator.\n";   
-        exit(1);
-}
-
-
-
-
-PickMode();
-
-
-# {{{ Help
-
-sub Help {
-
-    # {{{ help_acl
-my $help_acl ="
-        Access control
-       --grant-right <right> 
-       --revoke-right <right>
-         --userid <user>
-          --groupid <group>
-       --list-rights";
-
-# }}}
-    
-    # {{{ help_keyword_sel
-my $help_keyword_sel = "
-       Keyword Selections
-       --add-keyword-select
-       --modify-keyword-select <name>
-          --ks-name <name>
-          --ks-keyword <keyword>
-          --ks-single 
-          --ks-multiple
-          --ks-depth  <int>
-
-        --disable-keyword-select <name>";
-# }}}
-    
-    # {{{ help_scrip
-my $help_scrip = "
-        Scrips
-        --create-scrip
-           --scrip-condition <condition name or id>
-           --scrip-action <action name or id>
-           --scrip-template <template name or id>
-
-        --delete-scrip <id>
-       --list-scrips";
-
-# }}}
-    
-    # {{{ help_template  
-my $help_template = "      
-        Templates
-        --delete-template [<id>|<name>]
-        --display-template [<id>|<name>]
-
-         --create-template
-         --modify-template [<id>|<name>]
-           Flags for --create-template and --modify-template
-           --template-name
-           --template-description
-           --template-edit-content
-         
-         --list-templates";
-
-# }}}
-    
-    
-print <<EOF;
-
-USAGE:  rtadmin --user <userid> [Userflags]
-       rtadmin --list-users
-       rtadmin --queue <queueid> [Queueflags]
-       rtadmin --list-queues
-       rtadmin --group [groupflags]
-       rtadmin --list-groups
-       rtadmin --system  [SystemFlags]
-       rtadmin --keyword [keywordflags]
-
-User configuration for --user <userid>
-   
-       --disable
-       --create
-       --display
-
-  Core Attributes
-       --userid
-       --gecos
-       --password
-       --emailaddress
-       --privileged
-       --comments
-       --signature
-       --organization
-
-  Names        
-       --realname
-       --nickname
-       
-  Auth and external info
-       --externalcontactinfoid
-       --contactinfosystem
-       --externalauthid
-       --authsystem
-
-  Phone numbers
-       --pagerphone
-       --workphone
-       --mobilemphone
-       --homephone
-
-  Paper address
-       --address1
-       --address2
-       --city
-       --state
-       --zip
-       --country
-       --freeformcontactqinfo  
-
-
-Group Configuration for --group <groupid>
-       --create 
-       --delete
-       --display
-
-       --name <new name>
-       --description <new description>
-
-
-
-       --add-member <userid>
-       --delete-member <userid>
-       --list-members  
-
-Queue Configuration for --queue <queueid>
-       --create
-       --disable
-       --display
-
-       --name <name>
-       --correspondaddress <email address>
-       --commentaddress <email address>
-       --initialpriority <int>
-       --finalpriority <int>
-       --defaultduein <days>
-
-       --add-cc <email address>
-       --delete-cc <email address>
-       --add-admincc <email address>
-       --delete-admincc <email address>
-        --list-watchers
-
-       
-
-$help_acl
-
-$help_keyword_sel
-
-$help_template
-
-$help_scrip
-
-
-System configuration for --system 
-
-$help_acl
-
-$help_keyword_sel
-
-$help_template
-
-$help_scrip
-
-
-Keyword configuration for --keyword  <fully qualified name>
-       --list-children
-       --create-child <name>
-       --disable
-       --name <new name>
-       --description <new description>
-
-EOF
-
-
-
-}
-
-# }}}
-
-# {{{ PickMode
-
-sub PickMode {
-    my ($user,$group, $queue, $system, $keyword, $listusers, 
-       $listgroups, $listqueues, $help);
-
-
-    GetOptions ('help|h|usage' => \$help,
-               'user=s' => \$user,
-               'queue=s' => \$queue,
-               'group=s' => \$group,
-               'system' => \$system,
-               'keyword=s', => \$keyword,
-               'list-users' => \$listusers,
-               'list-queues' => \$listqueues,
-               'list-groups' => \$listgroups,
-              );
-    
-
-    
-    if ($user)          { AdminUser($user) }  
-    elsif ($group)      { AdminGroup($group) }
-    elsif ($queue)      { AdminQueue($queue) }
-    elsif ($system)     { AdminSystem($system) }
-    elsif ($keyword)    { AdminKeywords($keyword) }
-    elsif ($listusers)  { ListUsers() }
-    elsif ($listgroups) { ListGroups()  }
-    elsif ($listqueues) { ListQueues() }
-    elsif ($help)       { Help()}
-    else {
-       print "No command found\n";
-    }
-    exit(0);
-}      
-
-# }}}
-
-# {{{ AdminUser
-
-sub AdminUser {
-    my $user=shift;
-    my %args;
-
-    GetOptions(\%args,
-          'create', 'disable|delete', 'display',
-          'Name=s', 'Gecos=s', 'Password=s',
-          'EmailAddress=s', 'Privileged=s', 'Comments=s', 'Signature=s',
-          'Organization=s', 'RealName=s', 'NickName=s',  
-          'ExternalContactInfoId=s', 'ContactInfoSystem=s', 
-           'ExternalAuthId=s', 'AuthSystem=s',
-          'HomePhone=s', 'WorkPhone=s', 'MobilePhone=s', 'PagerPhone=s',
-           'Address1=s', 'Address2=s', 'City=s', 'State=s', 'Zip=s', 
-           'Country=s', 'FreeformContactInfo=s');
-
-    my $user_obj = new RT::User($CurrentUser);
-    
-    #Create the user if we need to 
-    if ($args{'create'}) {
-       my ($status, $msg) = 
-         $user_obj->Create( Name => ($args{'Name'} || $user),
-                            Gecos => $args{'Gecos'},
-                            Password => $args{'Password'},
-                            EmailAddress => $args{'EmailAddress'},
-                            Privileged => $args{'Privileged'},
-                            Comments => $args{'Comments'},
-                            Signature => $args{'Signature'},
-                            Organization => $args{'Organization'},
-                            RealName => $args{'RealName'},
-                            NickName => $args{'NickName'},
-                            ExternalContactInfoId => $args{'ExternalContactInfoId'},
-                            ContactInfoSystem => $args{'ContactInfoSystem'},
-                            ExternalAuthId => $args{'ExternalAuthId'},
-                            AuthSystem => $args{'AuthSystem'},
-                            HomePhone => $args{'HomePhone'},
-                            WorkPhone => $args{'WorkPhone'},
-                            MobilePhone => $args{'MobilePhone'},
-                            PagerPhone => $args{'PagerPhone'},
-                            Address1 => $args{'Address1'},
-                            Address2 => $args{'Address2'},
-                            City  => $args{'City'},
-                            State => $args{'State'},
-                            Zip => $args{'Zip'},
-                            FreeformContactInfo => $args{'FreeformContactInfo'}
-                          );
-       
-       print "$msg\n";
-       return();
-       
-    }
-    else {
-       
-       
-       #Load the user
-       $user_obj->Load($user);
-       
-       unless ($user_obj->id) {
-           print "User '$user' not found\n";
-           return();
-       }       
-       
-       
-       
-       #modify the user if we need to
-       my @attributes = ('Name', 'Gecos',
-                         'EmailAddress', 'Privileged', 'Comments', 'Signature',
-                         'Organization', 'RealName', 'NickName',  
-                         'ExternalContactInfoId', 'ContactInfoSystem', 
-                         'ExternalAuthId', 'AuthSystem',
-                         'HomePhone', 'WorkPhone', 'MobilePhone', 'PagerPhone',
-                         'Address1', 'Address2', 'City', 'State', 'Zip', 
-                         'Country', 'FreeformContactInfo');
-       foreach my $attrib (@attributes) {
-           if ( (exists ($args{"$attrib"})) and
-                ($user_obj->$attrib() ne $args{"$attrib"})) {
-               
-               my $method = "Set$attrib";
-               my ($val, $msg) = $user_obj->$method($args{"$attrib"});
-               print "User ".$user_obj->Name. " $attrib:  $msg\n";
-               
-           }
-       }               
-       
-       if (exists ($args{'Password'})) {
-           my ($code, $msg);
-           ($code, $msg) = $user_obj->SetPassword($args{'Password'});
-           print "User ". $user_obj->Name. ' Password: '. $msg . "\n";
-       }
-       
-       #Check if we need to display the user
-       if ($args{'display'}) {
-           foreach my $attrib (@attributes) {
-               next if ($attrib eq 'Password'); #Can't see the password
-               printf("%22.22s %-64s\n",$attrib, ($user_obj->$attrib()||'(undefined)'));
-               
-           }   
-       }       
-       
-       #Check if we need to delete the user
-       if ($args{'disable'}) {
-           my ($val, $msg) = $user_obj->SetDisabled(1);
-           print "$msg\n";
-       }       
-       
-    }
-}
-
-# }}}
-
-# {{{ AdminQueue
-
-sub AdminQueue {
-    my $queue=shift;
-    my %args;
-
-    GetOptions(\%args,
-              'create', 'disable|delete', 'display',
-              'Name=s', 'CorrespondAddress=s', 'Description=s',
-              'CommentAddress=s', 'InitialPriority=n', 'FinalPriority=n',
-              'DefaultDueIn=n',
-              
-              'add-cc=s@', 'add-admincc=s@', 
-              'delete-cc=s@', 'delete-admincc=s@',
-              'list-watchers', 'create-template'
-              );
-
-    use RT::Queue;
-    my $queue_obj = new RT::Queue($CurrentUser);
-    
-    #Create the queue if we need to 
-    if ($args{'create'}) {
-       my ($status, $msg) = 
-         $queue_obj->Create(
-                            Name => ($args{'Name'} || $queue) ,
-                            CorrespondAddress => $args{'CorrespondAddress'},
-                            Description => $args{'Description'},
-                            CommentAddress  => $args{'CommentAddress'},
-                            InitialPriority => $args{'InitialPriority'},
-                            FinalPriority => $args{'FinalPriority'},
-                            DefaultDueIn => $args{'DefaultDueIn'}
-                           );
-       
-       print "$msg\n";
-    }
-    else {
-       #Load the queue
-       $queue_obj->Load($queue);
-       
-       unless ($queue_obj->id) {
-           print "Queue '$queue' not found\n";
-           return();
-       }       
-               
-        #modify if we need to
-       my @attributes = qw(Name CorrespondAddress Description
-                           CommentAddress InitialPriority FinalPriority
-                           DefaultDueIn
-                        );
-       foreach my $attrib (@attributes) {
-           if ( (exists ($args{"$attrib"})) and
-                ($queue_obj->$attrib() ne $args{"$attrib"})) {
-               
-               my $method = "Set$attrib";
-               my ($val, $msg) = $queue_obj->$method($args{"$attrib"});
-               print "Queue ".$queue_obj->Name. " $attrib:  $msg\n";
-               
-           }
-       }               
-           
-       
-       #Check if we need to display the queue
-       if ($args{'display'}) {
-           foreach my $attrib (@attributes) {
-               printf("%22.22s %-64s\n",$attrib, ($queue_obj->$attrib()||'(undefined)'));
-               
-           }   
-       }       
-               
-       foreach my $person (@{$args{'add-cc'}}) {
-           my ($val, $msg) = $queue_obj->AddCc(Email => $person);
-           print "$msg\n";
-       }
-       foreach my $person (@{$args{'add-admincc'}}) {
-           my ($val, $msg) = $queue_obj->AddAdminCc(Email => $person);
-           print "$msg\n";
-       }
-
-       foreach my $person (@{$args{'delete-cc'}}) {
-           my ($val, $msg) = $queue_obj->DeleteCc($person);
-           print "$msg\n";
-       }
-       foreach my $person (@{$args{'delete-admincc'}}) {
-           my ($val, $msg) = $queue_obj->DeleteAdminCc($person);
-           print "$msg\n";
-       }
-
-       if ($args{'list-watchers'}) {
-           require RT::Watchers;
-           my $watchers = new RT::Watchers($CurrentUser);
-           $watchers->LimitToQueue($queue_obj->id);
-           while (my $watcher = $watchers->Next()) {
-               printf("%10s %-60s\n",
-                      $watcher->Type, $watcher->Email );
-           }   
-       }       
-
-        AdminTemplates($queue_obj->Id());
-        AdminScrips($queue_obj->Id());
-       AdminRights($queue_obj->Id());
-       AdminKeywordSelects($queue_obj->Id());
-
-       #Check if we need to delete the queue
-       if ($args{'disable'}) {
-           my ($val, $msg) = $queue_obj->SetDisabled(1);
-           print "$msg\n";
-       }       
-       
-    }
-}
-
-# }}}
-
-# {{{ AdminKeywords
-
-sub AdminKeywords {
-    my $keyword = shift;
-    
-    my %args;
-    GetOptions(\%args, 'list-children', 'create-child=s', 'disable|delete', 'Name=s', 'Description=s');
-    
-    use RT::Keyword;
-    
-    my $key_obj = new RT::Keyword($CurrentUser);
-    my $key_id;
-    
-    #If we're dealing with the root of the keyword list
-    if ($keyword eq '/') {
-       $key_id=0;
-    }  
-    else {
-       my ($val, $msg) = $key_obj->LoadByPath( $keyword );
-       unless ($val) {
-           print $msg ."\n";
-       }
-       $key_id = $key_obj->Id();
-    }  
-    
-    if ($args{'create-child'}) {
-       my $child = new RT::Keyword($CurrentUser);
-       
-       my ($val, $msg) = $child->Create( Parent => $key_id,
-                                         Name => $args{'create-child'},
-                                       );
-       print $msg ."\n";
-    }  
-    
-    elsif ($args{'list-children'}) {
-       my $keywords;
-       if ($key_obj->id) {
-           $keywords = $key_obj->Children();
-       }       
-       #If we didn't actually have a keyword object, we need to create our own Keywords object.
-       else {
-           $keywords = new RT::Keywords($CurrentUser);
-           $keywords->LimitToParent(0); 
-       }
-       
-       while (my $key=$keywords->Next) {
-           print $key->Name;
-           if ($key->Description) {
-               print " (" . $key->Description .")";
-           }   
-           print "\n";
-       }       
-             
-
-    }  
-    
-    #Else we wanna do some modification.
-    else {
-       
-       #If we didn't load a keyword, get out
-       return(undef) unless ($key_obj->Id);
-       
-       
-       my @attributes = qw( Name Description );
-       foreach my $attrib (@attributes) {
-           if ( (exists ($args{"$attrib"})) and
-                ($key_obj->$attrib() ne $args{"$attrib"})) {
-               
-               my $method = "Set$attrib";
-               my ($val, $msg) = $key_obj->$method($args{"$attrib"});
-               
-               print "Keyword ".$key_obj->Name. " $attrib:  $msg\n";       }
-       }
-       
-       if ($args{'disable'}) {
-           $key_obj->SetDisabled(1);
-           
-       }
-       
-    }
-}
-
-# }}}
-
-# {{{ AdminKeywordSelects
-
-sub AdminKeywordSelects {
-    my $queue = shift;
-    # O for queue means global
-
-    my %args;
-    GetOptions(\%args, 'add-keyword-select','disable-keyword-select|delete-keyword-select=s',
-              'modify-keyword-select=s', 
-              'keyword-select-Keyword|ks-keyword=s', 
-              'keyword-select-Single|ks-single', 
-              'keyword-select-Multiple|ks-multiple', 
-              'keyword-select-Depth|ks-depth=i', 
-              'keyword-select-Name|ks-name=s'
-             );
-
-    # sanitize single vs multiple.
-    if ($args{'keyword-select-Multiple'}) {
-       $args{'keyword-select-Single'} = 0;
-    }
-    
-    use RT::KeywordSelect;
-    my $keysel_obj = new RT::KeywordSelect($CurrentUser);
-    if ($args{'add-keyword-select'}) {
-       
-       my ($val, $msg) = $keysel_obj->Create( Keyword => $args{'keyword-select-Keyword'},
-                                              Depth => $args{'keyword-select-Depth'},
-                                              Single => $args{'keyword-select-Single'},
-                                              Name => $args{'keyword-select-Name'},
-                                              ObjectType => 'Ticket',
-                                              ObjectField => 'Queue',
-                                              ObjectValue => $queue);
-       print $msg ."\n";
-    }  
-    elsif ($args{'modify-keyword-select'}) {
-       $keysel_obj->LoadByName(Name => $args{'modify-keyword-select'},
-                               Queue => $queue
-                              );
-       
-       unless ($keysel_obj->Id()) {
-           print "Keyword select not found\n";
-           return();
-       }       
-       my @attributes = qw( Name Keyword Single Depth );
-       foreach my $attrib (@attributes) {
-           if ( (exists ($args{"keyword-select-$attrib"})) and
-                ($keysel_obj->$attrib() ne $args{"keyword-select-$attrib"})) {
-               
-               my $method = "Set$attrib";
-               my ($val, $msg) = $keysel_obj->$method($args{"keyword-select-$attrib"});
-                               
-               print "Keyword select ".$keysel_obj->Name. " $attrib:  $msg\n";     }
-       }
-
-
-    }  
-
-    
-    elsif ($args{'disable-keyword-select'}) {
-       $keysel_obj->LoadByName(Name => $args{'disable-keyword-select'},
-                               Queue => $queue);
-       
-       $keysel_obj->SetDisabled(1);
-       
-    }
-}
-
-# }}}
-
-# {{{ AdminGroup
-
-sub AdminGroup {
-    my $group = shift;
-
-    my (%args);
-
-    GetOptions(\%args,
-              'create', 'delete', 'display',
-              'Name=s', 'Description=s',
-                      
-              'add-member=s@', 'delete-member=s@',
-              'list-members'
-              );
-
-
-    use RT::Group;
-    my $group_obj = new RT::Group($CurrentUser);
-    unless ($group) {
-       print "Group not specified.\n";
-       return();
-    }  
-    
-
-    #Create the group if we need to
-    if ($args{'create'}) {
-       my ($val, $msg) = $group_obj->Create( Name => ($args{'Name'} || $group),
-                                             Description => $args{'Description'} );
-       print $msg ."\n";
-    }  
-    #otherwise we load it
-    else {
-       $group_obj->Load($group);
-    }  
-    
-    #If we have no group object, get the hell out
-    unless ($group_obj->Id) {
-       print "Group not found.\n";
-    }
-
-    if ($args{'delete'}) {
-       my ($val, $msg) = $group_obj->Delete();
-       print $msg ."\n";
-       return();
-    }  
-
-
-    
-    #modify if we need to
-    my @attributes = qw(Name Description
-                       
-                      );
-    foreach my $attrib (@attributes) {
-       if ( (exists ($args{"$attrib"})) and
-            ($group_obj->$attrib() ne $args{"$attrib"})) {
-               
-           my $method = "Set$attrib";
-           my ($val, $msg) = $group_obj->$method($args{"$attrib"});
-           print "Group ".$group_obj->Name. " $attrib:  $msg\n";
-           
-           }
-    }          
-    
-    foreach my $user (@{$args{'add-member'}}) {
-       my ($val, $msg) = $group_obj->AddMember($user);
-       print $msg. "\n";
-    }
-    foreach my $user (@{$args{'delete-member'}}) {
-       my ($val, $msg) = $group_obj->DeleteMember($user);
-       print $msg ."\n";
-    }
-    
-    if ($args{'list-members'}) {
-       my $members = $group_obj->MembersObj();
-       while (my $member = $members->Next()) {
-           print $member->UserObj->Name() ."\n";
-       }
-    }  
-    
-}
-
-# }}}
-
-# {{{ AdminSystem
-sub AdminSystem {
-    print "In AdminSystem\n";
-
-    AdminTemplates(0);
-    AdminScrips(0);
-    AdminRights(0);
-    AdminKeywordSelects(0);
-}
-# }}}
-
-# {{{ sub AdminTemplates
-
-sub AdminTemplates {
-    my $queue = shift;
-    #Queue = 0 means 'global';
-
-    my %args;
-
-    
-    GetOptions(\%args, 'list-templates', 'create-template','modify-template=s',
-              'delete-template=s', 'display-template=s',
-              'template-Name=s', 'template-Description=s',
-              'template-edit-content!');
-    
-    # {{{ List templates
-    if ($args{'list-templates'}) {
-       print "Templates for $queue\n";
-       require RT::Templates;
-       my $templates = new RT::Templates($CurrentUser);
-       if ($queue != 0) {
-           $templates->LimitToQueue($queue);
-       }       
-       else {
-           $templates->LimitToGlobal();
-       }       
-       while (my $template = $templates->Next) {
-           print $template->Id.": ".$template->Name." - " . $template->Description ."\n";
-       }       
-    }
-
-    # }}}
-
-    require RT::Template;      
-    my $template = new RT::Template($CurrentUser);
-    if ($args{'delete-template'}) {
-       $template->Load($args{'delete-template'});
-       unless ($template->id) {
-           print "Couldn't load template";
-           return(undef);
-       }
-       my ($val, $msg) = $template->Delete();
-       print "$msg\n";
-    }
-    elsif ($args{'create-template'}) {
-       #TODO edit the template content
-       my $content;
-
-       my $linesref = GetMessageContent(CurrentUser => $CurrentUser,
-                                     Edit => 1);
-       
-       $content = join("\n", @{$linesref});
-       
-
-       my ($val, $msg) = $template->Create(Name => $args{'template-Name'},
-                                           Description => $args{'template-Description'},
-                                           Content => $content,
-                                           Queue => $queue);
-       print "$msg\n";
-    }  
-    elsif ($args{'modify-template'}) {
-       
-       $template->Load($args{'modify-template'});
-       unless ($template->Id()) {
-           print "Template not found\n";
-           return();
-       }       
-       my @attributes = qw( Name Description );
-       foreach my $attrib (@attributes) {
-           if ( (exists ($args{"template-$attrib"})) and
-                ($template->$attrib() ne $args{"template-$attrib"})) {
-               
-               my $method = "Set$attrib";
-               my $val = $template->$method($args{"template-$attrib"});
-                               
-           }
-       }
-       if ($args{'template-edit-content'}) {
-           
-           my $linesref = GetMessageContent(CurrentUser => $CurrentUser,
-                                            Content => $template->Content,
-                                            Edit => 1);
-           
-           my $content = join("\n", @{$linesref});         
-           my ($val) = $template->SetContent($content);
-           print $val."\n";
-       }       
-
-    }  
-    if ($args{'display-template'}) {
-       $template->Load($args{'display-template'});
-       print $template->Name . "\n". $template->Description ."\n". $template->Content."\n";
-    }  
-}      
-
-# }}}
-
-# {{{ sub AdminScrips
-
-sub AdminScrips {
-    my $queue = shift;
-    #Queue = 0 means 'global';
-
-    my %args;
-
-    
-    GetOptions(\%args, 'list-scrips', 'create-scrip','modify-scrip=s',
-              'scrip-action=s', 'scrip-template=s', 'scrip-condition=s',
-              'delete-scrip=s');
-
-    
-    # {{{ List entries
-    if ($args{'list-scrips'}) {
-       print "Scrips for $queue\n";
-       require RT::Scrips;
-       my $scrips = new RT::Scrips($CurrentUser);
-       if ($queue != 0) {
-           $scrips->LimitToQueue($queue);
-       }       
-       else {
-           $scrips->LimitToGlobal();
-       }       
-       while (my $scrip = $scrips->Next) {
-           print $scrip->Id.": If ".
-             $scrip->ConditionObj->Name." then " .
-               $scrip->ActionObj->Name." with template " .
-                 $scrip->TemplateObj->Name."\n";
-       }       
-    }
-
-    # }}}
-
-    require RT::Scrip;
-    my $scrip = new RT::Scrip($CurrentUser);
-    if ($args{'delete-scrip'}) {
-       $scrip->Load($args{'delete-scrip'});
-       unless ($scrip->id) {
-           print "Couldn't load scrip";
-             return(undef);
-       }
-       my ($val, $msg) = $scrip->Delete();
-       print "$msg\n";
-    }
-    elsif ($args{'create-scrip'}) {
-       my ($val, $msg) = $scrip->Create( ScripAction => $args{'scrip-action'},
-                                         ScripCondition => $args{'scrip-condition'},
-                                         Template => $args{'scrip-template'},
-                                         Queue => $queue);
-
-       print "$msg\n";
-    }  
-}      
-
-# }}}
-
-# {{{ sub AdminRights
-
-sub AdminRights {
-    my $queue = shift;
-    #Queue = 0 means 'global';
-
-    my ($scope, $appliesto);
-    if ($queue == 0) {
-       $scope = 'System';
-       $appliesto = 0;
-    }  
-    else {
-       $scope =  'Queue';
-       $appliesto = $queue;
-    }  
-
-    my %args;    
-    GetOptions(\%args, 
-              'grant-right|add-right|new-right|create-right=s@',
-              'revoke-right|del-right|delete-right=s@',
-              'list-rights', 'userid=s@', 'groupid=s@',
-             );
-    
-    
-    # {{{ List entries
-    if ($args{'list-rights'}) {
-       require RT::ACL;
-       my $acl = new RT::ACL($CurrentUser);
-       if ($queue != 0) {
-           $acl->LimitToQueue($queue);
-       }       
-       else {
-           $acl->LimitToSystem();
-       }       
-       while (my $ace = $acl->Next) {
-           print $ace->RightScope;
-           
-           #Print the queue name if we have it.
-           print " " . $ace->AppliesToObj->Name if (defined $ace->AppliesToObj);
-           
-           print ": ". $ace->PrincipalType . " " .$ace->PrincipalObj->Name .
-             " has right " . $ace->RightName ."\n";
-             
-       }       
-    }
-
-    # }}}
-
-    require RT::ACE;    
-
-    # {{{ Build up an array of principals
-    my (@principals);
-    my $i = 0;
-    foreach my $group (@{$args{'groupid'}}) { 
-
-
-       my $princ = new RT::Group($CurrentUser);
-       $princ->Load("$group");
-       if ($princ->id) {
-           $principals[$i]->{'type'} = 'Group';
-           $principals[$i]->{'id'} = $princ->id();
-           $i++;
-       }       
-       else {
-           print "Could not find group $group\n";
-       }       
-    }  
-
-
-    foreach my $user (@{$args{'userid'}}) { 
-       my $princ = new RT::User($CurrentUser);
-       $princ->Load("$user");
-       if ($princ->id) {
-           $principals[$i]->{'type'} = 'User';
-           $principals[$i]->{'id'} = $princ->id();
-           $i++;
-       }       
-       else {
-           print "Could not find user $user.\n";
-           }
-    }
-    # }}}
-
-
-    foreach my $principal (@principals) {
-
-       # {{{ Delete rights that need deleting
-       foreach my $right (@{$args{'revoke-right'}}) {
-           my $ace = new RT::ACE($CurrentUser);
-           $RT::Logger->debug("Trying to delete a right: $right \n");
-           my ($val, $msg) = $ace->LoadByValues( RightName => $right,
-                                                 RightScope => $scope,
-                                                 PrincipalType => $principal->{'type'},
-                                                 PrincipalId => $principal->{'id'},
-                                                 RightAppliesTo => $appliesto);
-           
-           unless ($val) {
-               print "Right $right not found for" . $principal->{'type'} . " " .
-                 $principal->{'id'} . " in scope $scope ($appliesto)\n";
-               next;
-           }   
-           my ($delval, $delmsg) =$ace->Delete;
-           print "$delmsg\n";
-           
-           
-       }
-
-       # }}}
-       
-       # {{{ grant rights that need granting
-       foreach my $right (@{$args{'grant-right'}}) {
-           my $ace = new RT::ACE($CurrentUser);
-           my ($val, $msg) = $ace->Create(RightName => $right,
-                                          PrincipalType => $principal->{'type'},
-                                          PrincipalId => $principal->{'id'},
-                                          RightScope => $scope,
-                                          RightAppliesTo => $appliesto);
-           
-           print $msg . "\n";
-       }
-
-       # }}}
-    }  
-
-}
-
-# }}}
-
-
-sub ListUsers {
-    require RT::Users;
-    my $users = new RT::Users($CurrentUser);
-    $users->UnLimit();
-    while (my $user = $users->Next()) {
-       printf ("%16s %-16s\n",$user->Name(), $user->EmailAddress());
-    }
-}
-sub ListQueues {
-    require RT::Queues;
-    my $queues = new RT::Queues($CurrentUser);
-    $queues->UnLimit();
-    while (my $queue = $queues->Next()) {
-       printf ("%16s %-16s\n",$queue->Name(), $queue->Description());
-    }
-}
-
-sub ListGroups {
-    require RT::Groups;
-    my $groups = new RT::Groups($CurrentUser);
-    $groups->UnLimit();
-    while (my $group = $groups->Next()) {
-       printf ("%16s %-16s\n",$group->Name(), $group->Description());
-    }  
-}
index 6e1ae06..21cb83f 100755 (executable)
-# $Header: /home/cvs/cvsroot/freeside/rt/bin/Attic/webmux.pl,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# RT is (c) 1996-2000 Jesse Vincent (jesse@fsck.com);
+#!/usr/bin/perl
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 
 use strict;
-$ENV{'PATH'} = '/bin:/usr/bin';    # or whatever you need
-$ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
-$ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'};
-$ENV{'ENV'} = '' if defined $ENV{'ENV'};
-$ENV{'IFS'} = ''          if defined $ENV{'IFS'};
 
+BEGIN {
+    $ENV{'PATH'}   = '/bin:/usr/bin';                      # or whatever you need
+    $ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
+    $ENV{'SHELL'}  = '/bin/sh' if defined $ENV{'SHELL'};
+    $ENV{'ENV'}    = '' if defined $ENV{'ENV'};
+    $ENV{'IFS'}    = '' if defined $ENV{'IFS'};
+}
 
-# We really don't want apache to try to eat all vm
-# see http://perl.apache.org/guide/control.html#Preventing_mod_perl_Processes_Fr
-
+use lib ("/opt/rt3/local/lib", "/opt/rt3/lib");
+use RT;
 
 package RT::Mason;
 
-use CGI qw(-private_tempfiles); #bring this in before mason, to make sure we
-                               #set private_tempfiles
-use HTML::Mason::ApacheHandler (args_method => 'CGI');
-use HTML::Mason;  # brings in subpackages: Parser, Interp, etc.
-
-use vars qw($VERSION %session $Nobody $SystemUser $r $m);
+use CGI qw(-private_tempfiles);    #bring this in before mason, to make sure we
+                                   #set private_tempfiles
 
-# List of modules that you want to use from components (see Admin
-# manual for details)
-
-#Clean up our umask...so that the session files aren't world readable, writable or executable
-umask(0077);
+BEGIN {
+    if ($CGI::MOD_PERL) {
+       require HTML::Mason::ApacheHandler;
+    }
+    else {
+       require HTML::Mason::CGIHandler;
+    }
+}
 
+use HTML::Mason;                   # brings in subpackages: Parser, Interp, etc.
 
-         
-$VERSION="!!RT_VERSION!!";
+use vars qw($Nobody $SystemUser $r);
 
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
+#This drags in RT's config.pm
+RT::LoadConfig();
 
-#This drags in  RT's config.pm
-use config;
 use Carp;
 
-{  
-           package HTML::Mason::Commands;
-           use vars qw(%session $m);
-         
-           use RT; 
-           use RT::Ticket;
-           use RT::Tickets;
-           use RT::Transaction;
-           use RT::Transactions;
-           use RT::User;
-           use RT::Users;
-           use RT::CurrentUser;
-           use RT::Template;
-           use RT::Templates;
-           use RT::Queue;
-           use RT::Queues;
-           use RT::ScripAction;
-           use RT::ScripActions;
-           use RT::ScripCondition;
-           use RT::ScripConditions;
-           use RT::Scrip;
-           use RT::Scrips;
-           use RT::Group;
-           use RT::Groups;
-           use RT::Keyword;
-           use RT::Keywords;
-           use RT::ObjectKeyword;
-           use RT::ObjectKeywords;
-           use RT::KeywordSelect;
-           use RT::KeywordSelects;
-           use RT::GroupMember;
-           use RT::GroupMembers;
-           use RT::Watcher;
-           use RT::Watchers;
-           use RT::Handle;
-           use RT::Interface::Web;    
-           use MIME::Entity;
-           use Text::Wrapper;
-           use Apache::Cookie;
-           use Date::Parse;
-           use HTML::Entities;
-           
-           #TODO: make this use DBI
-           use Apache::Session::File;
-
-           # Set this page's content type to whatever we are called with
-           sub SetContentType {
-               my $type = shift;
-               $RT::Mason::r->content_type($type);
-           }
-
-           sub CGIObject {
-               $m->cgi_object();
-           }
-
-       }
-my ($parser, $interp, $ah);
-if ($HTML::Mason::VERSION < 1.0902) {
- $parser = &RT::Interface::Web::NewParser(allow_globals => [%session]);
-
- $interp = &RT::Interface::Web::NewInterp(parser=>$parser,
-                                          allow_recursive_autohandlers => 1,
-                                                              );
-
- $ah = &RT::Interface::Web::NewApacheHandler($interp);
-} else {
- $ah = &RT::Interface::Web::NewMason11ApacheHandler();
+{
+    package HTML::Mason::Commands;
+    use vars qw(%session);
+
+    use RT::Tickets;
+    use RT::Transactions;
+    use RT::Users;
+    use RT::CurrentUser;
+    use RT::Templates;
+    use RT::Queues;
+    use RT::ScripActions;
+    use RT::ScripConditions;
+    use RT::Scrips;
+    use RT::Groups;
+    use RT::GroupMembers;
+    use RT::CustomFields;
+    use RT::CustomFieldValues;
+    use RT::TicketCustomFieldValues;
+
+    use RT::Interface::Web;
+    use MIME::Entity;
+    use Text::Wrapper;
+    use CGI::Cookie;
+    use Time::ParseDate;
+    use HTML::Entities;
 }
-# Activate the following if running httpd as root (the normal case).
-# Resets ownership of all files created by Mason at startup.
-#
-chown (Apache->server->uid, Apache->server->gid, 
-               [$RT::MasonSessionDir]);
-
-
-chown (Apache->server->uid, Apache->server->gid, 
-               $ah->interp->files_written);
 
-# Die if WebSessionDir doesn't exist or we can't write to it
 
-stat ($RT::MasonSessionDir);
-die "Can't read and write $RT::MasonSessionDir"
-  unless (( -d _ ) and ( -r _ ) and ( -w _ ));
+# Activate the following if running httpd as root (the normal case).
+# Resets ownership of all files created by Mason at startup.
+# Note that mysql uses DB for sessions, so there's no need to do this.
+unless ($RT::DatabaseType =~ /(mysql|Pg)/) {
+    # Clean up our umask to protect session files
+    umask(0077);
+
+if ( $CGI::MOD_PERL)  {
+    chown( Apache->server->uid, Apache->server->gid, [$RT::MasonSessionDir] )
+       if Apache->server->can('uid');
+        }
+    # Die if WebSessionDir doesn't exist or we can't write to it
+    stat($RT::MasonSessionDir);
+    die "Can't read and write $RT::MasonSessionDir"
+       unless ( ( -d _ ) and ( -r _ ) and ( -w _ ) );
+}
 
+my $ah = &RT::Interface::Web::NewApacheHandler() if $CGI::MOD_PERL;
 
 sub handler {
     ($r) = @_;
-    
+
     RT::Init();
+
     # We don't need to handle non-text items
-    return -1 if defined($r->content_type) && $r->content_type !~ m|^text/|io;
-    
-    #This is all largely cut and pasted from mason's session_handler.pl
-    
-    my %cookies = Apache::Cookie::parse($r->header_in('Cookie'));
-    
-    eval { 
-       tie %HTML::Mason::Commands::session, 'Apache::Session::File',
-         ( $cookies{'AF_SID'} ? $cookies{'AF_SID'}->value() : undef ), 
-           { Directory => $RT::MasonSessionDir,
-             LockDirectory => $RT::MasonSessionDir,
-           }   ;
-    };
-    
-    if ( $@ ) {
-       # If the session is invalid, create a new session.
-       if ( $@ =~ m#^Object does not exist in the data store# ) {
-            tie %HTML::Mason::Commands::session, 'Apache::Session::File', undef,
-            { Directory => $RT::MasonSessionDir,
-              LockDirectory => $RT::MasonSessionDir,
-            };
-            undef $cookies{'AF_SID'};
-       }
-         else {
-            die "RT Couldn't write to session directory '$RT::MasonSessionDir'. Check that this directory's permissions are correct.";
-         }
-    }
-    
-    if ( !$cookies{'AF_SID'} ) {
-       my $cookie = new Apache::Cookie
-         ($r,
-          -name=>'AF_SID', 
-          -value=>$HTML::Mason::Commands::session{_session_id}, 
-          -path => '/',);
-       $cookie->bake;
+    return -1 if defined( $r->content_type ) && $r->content_type !~ m|^text/|io;
 
-    }
+    my %session;
     my $status = $ah->handle_request($r);
-    untie %HTML::Mason::Commands::session;
-    
+    undef (%session);
+
+    $RT::Logger->crit("Transaction not committed. Usually indicates a software fault. Data loss may have occurred") if $RT::Handle->TransactionDepth;
     return $status;
-    
-  }
-1;
+}
 
+1;
diff --git a/rt/bin/webmux.pl.in b/rt/bin/webmux.pl.in
new file mode 100644 (file)
index 0000000..12aad85
--- /dev/null
@@ -0,0 +1,125 @@
+#!@PERL@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+use strict;
+
+BEGIN {
+    $ENV{'PATH'}   = '/bin:/usr/bin';                      # or whatever you need
+    $ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
+    $ENV{'SHELL'}  = '/bin/sh' if defined $ENV{'SHELL'};
+    $ENV{'ENV'}    = '' if defined $ENV{'ENV'};
+    $ENV{'IFS'}    = '' if defined $ENV{'IFS'};
+}
+
+use lib ("@LOCAL_LIB_PATH@", "@RT_LIB_PATH@");
+use RT;
+
+package RT::Mason;
+
+use CGI qw(-private_tempfiles);    #bring this in before mason, to make sure we
+                                   #set private_tempfiles
+
+BEGIN {
+    if ($CGI::MOD_PERL) {
+       require HTML::Mason::ApacheHandler;
+    }
+    else {
+       require HTML::Mason::CGIHandler;
+    }
+}
+
+use HTML::Mason;                   # brings in subpackages: Parser, Interp, etc.
+
+use vars qw($Nobody $SystemUser $r);
+
+#This drags in RT's config.pm
+RT::LoadConfig();
+
+use Carp;
+
+{
+    package HTML::Mason::Commands;
+    use vars qw(%session);
+
+    use RT::Tickets;
+    use RT::Transactions;
+    use RT::Users;
+    use RT::CurrentUser;
+    use RT::Templates;
+    use RT::Queues;
+    use RT::ScripActions;
+    use RT::ScripConditions;
+    use RT::Scrips;
+    use RT::Groups;
+    use RT::GroupMembers;
+    use RT::CustomFields;
+    use RT::CustomFieldValues;
+    use RT::TicketCustomFieldValues;
+
+    use RT::Interface::Web;
+    use MIME::Entity;
+    use Text::Wrapper;
+    use CGI::Cookie;
+    use Time::ParseDate;
+    use HTML::Entities;
+}
+
+
+# Activate the following if running httpd as root (the normal case).
+# Resets ownership of all files created by Mason at startup.
+# Note that mysql uses DB for sessions, so there's no need to do this.
+unless ($RT::DatabaseType =~ /(mysql|Pg)/) {
+    # Clean up our umask to protect session files
+    umask(0077);
+
+if ( $CGI::MOD_PERL)  {
+    chown( Apache->server->uid, Apache->server->gid, [$RT::MasonSessionDir] )
+       if Apache->server->can('uid');
+        }
+    # Die if WebSessionDir doesn't exist or we can't write to it
+    stat($RT::MasonSessionDir);
+    die "Can't read and write $RT::MasonSessionDir"
+       unless ( ( -d _ ) and ( -r _ ) and ( -w _ ) );
+}
+
+my $ah = &RT::Interface::Web::NewApacheHandler() if $CGI::MOD_PERL;
+
+sub handler {
+    ($r) = @_;
+
+    RT::Init();
+
+    # We don't need to handle non-text items
+    return -1 if defined( $r->content_type ) && $r->content_type !~ m|^text/|io;
+
+    my %session;
+    my $status = $ah->handle_request($r);
+    undef (%session);
+
+    $RT::Logger->crit("Transaction not committed. Usually indicates a software fault. Data loss may have occurred") if $RT::Handle->TransactionDepth;
+    return $status;
+}
+
+1;
diff --git a/rt/config b/rt/config
new file mode 100644 (file)
index 0000000..b9418a6
--- /dev/null
+++ b/rt/config
@@ -0,0 +1,256 @@
+/*
+ * This is the project ``config'' file.  It controls many aspects of
+ * how Aegis interacts with your project.
+ *
+ * There are several sections of this file, each dealing with a different
+ * aspect of the interaction between Aegis and the tools used to manage
+ * yout project.
+ */
+
+/*
+ * -------------------------------------------------------------------------
+ *
+ * The build tool is delegated.
+ */
+
+/*
+ * The build_command field of the config file is used to invoke the relevant
+ * build command.  The following command tells cook where to find the recipes.
+ * The ${s Howto.cook} expands to a path into the baseline during development
+ * if the file is not in the change.  Look in aesub(5) for more information
+ * about command substitutions.
+ */
+build_command =
+       "";
+        
+/*        cook -book ${s Howto.cook} search_path=$search_path \
+project=$p change=$c version=$v -star -no-log -action -notouch";
+
+/* 
+ * The recipes in the User Guide will all remove their targets before
+ * constructing them, which qualifies them to use the following entry in the
+ * config file.  The targets MUST be removed first if this field is true,
+ * otherwise the baseline would cease to be self-consistent.
+ *
+ * Fortunately, Cook has a nifty ``set unlink;'' statement which is
+ * placed at the top of the cookbook.
+ */ 
+link_integration_directory = true;
+
+
+/*
+ * -------------------------------------------------------------------------
+ *
+ * The history tool is delegated.
+ *
+ * The fhist program was written by David I. Bell and is admirably
+ * suited to providing a history mechanism with out the "cruft" that
+ * SCCS and RCS impose.  The fhist program also comes with two other
+ * utilities, fcomp and fmerge, which use the same minimal difference
+ * algorithm.
+ *
+ * Please note that the [# edit #] feature needs to be avoided, or the
+ * -Fored_Update (-fu) flag needs to be used in addition to the
+ * -Conditional_Update (-cu) flag, otherwise updates will complain that
+ * ``Input file "XXX" contains edit A instead of B for module "YYY"''
+ *
+ * The history_create_command and the history_put_command are
+ * intentionally identical.  This minimizes problems when using
+ * branches.
+ *
+ * The ${quote ...} construct is used to quote filesnames whicg contain
+ * shell special characters.  A minimum of quoting is performed, so if
+ * the filenames do not contail shell special characters, no quotes will
+ * be used.
+ */
+
+/*
+ * This command is used to create a new project history.  The command is
+ * always executed as the project owner.  Note he the source is left in
+ * the baseline.  The following substitutions are available:
+ *
+ * ${Input}
+ *     absolute path of the source file
+ * ${History}
+ *     absolute path of the history file
+ *
+ * The history_create_command and the history_put_command are
+ * intentionally identical.  This minimizes problems when using
+ * branches.
+ */
+history_create_command =
+       "fhist ${quote ${basename $input}} -cr -cu -i ${quote $input} \
+-p ${quote ${dirname $history}} -r";
+
+/*
+ * This command is used to get a specific edit back from history.  The
+ * command may be executed by developers.  The following substitutions
+ * are available:
+ *
+ * ${History}
+ *     absolute path of the history file
+ * ${Edit}
+ *     edit number, as given by history_query_command
+ * ${Output}
+ *     absolute path of the destination file
+ *
+ * Note that the destination filename will never look anything like the
+ * history source filename, so the -p is essential.
+ */
+history_get_command =
+       "fhist ${quote ${basename $history}} -e ${quote $e} \
+-o ${quote $output} -p ${quote ${dirname $history}}";
+
+/*
+ * This command is used to add a new "top-most" entry to the history
+ * file.  This command is always executed as the project owner.  Note
+ * that the source file is left in the baseline.  The following
+ * substitutions are available:
+ *
+ * ${Input}
+ *     absolute path of source file
+ * ${History}
+ *     absolute path of history file
+ *
+ * The history_create_command and the history_put_command are
+ * intentionally identical.  This minimizes problems when using
+ * branches.
+ */
+history_put_command =
+       "fhist ${quote ${basename $input}} -cr -cu -i ${quote $input} \
+-p ${quote ${dirname $history}} -r";
+
+/*
+ * This command is used to query what the history mechanism calls the
+ * "top-most" edit of a history file.  The result may be any arbitrary
+ * string, it need not be anything like a number, just so long as it
+ * uniquely identifies the edit for use by the history_get_command at a
+ * later date.  The edit number is to be printed on the standard output.
+ * This command may be executed by developers.  The following
+ * substitutions are available:
+ *
+ * ${History}
+ *     absolute path of the history file
+ */
+history_query_command =
+       "fhist ${quote ${basename $history}} -l 0 \
+-p ${quote ${dirname $history}} -q";
+
+/*
+ * -------------------------------------------------------------------------
+ *
+ * The difference and merge tools are delegated.
+ */
+
+/*
+ * Compare two files using fcomp.  The -w option produces an output of
+ * the entire file, with insertions an deletions marked by "change bars"
+ * in the left margin.  This is superior to context difference, as it
+ * shows the entire file as context.  The -s option could be added to
+ * compare runs of white space as equal.
+ *
+ * This command is used by aed(1) to produce a difference listing when
+ * file in the development directory was originally copied from the
+ * current version in the baseline.
+ *
+ * All of the command substitutions described in aesub(5) are available.
+ * In addition, the following substitutions are also available:
+ *
+ * ${ORiginal}
+ *     The absolute path name of a file containing the version
+ *     originally copied.  Usually in the baseline.
+ * ${Input}
+ *     The absolute path name of the edited version of the file.
+ *     Usually in the development directory.
+ * ${Output}
+ *     The absolute path name of the file in which to write the
+ *     difference listing.  Usually in the development directory.
+ *
+ * An exit status of 0 means successful, even of the files differ (and
+ * they usually do).  An exit status which is non-zero means something
+ * is wrong.
+ *
+ * The non-zero exit status may be used to overload this command with
+ * extra tests, such as line length limits.  The difference files must
+ * be produced in addition to these extra tests.
+ */
+diff_command =
+       "fcomp -w ${quote $original} ${quote $input} -o ${quote $output}";
+
+/*
+ * Compare three files using fmerge.  Conflicts are marked in the
+ * output.
+ *
+ * This command is used by aed(1) to produce a difference listing when a
+ * file in the development directory is out of date compared to the
+ * current version in the baseline.
+ *
+ * All of the command substitutions described in aesub(5) are available.
+ * In addition, the following substitutions are also available:
+ *
+ * ${ORiginal}
+ *     The absolute path name of a file containing the common ancestor
+ *     version of ${MostRecent} and {$Input}.  Usually the version
+ *     originally copied into the change.  Usually in a temporary file.
+ * ${Most_Recent}
+ *     The absolute path name of a file containing the most recent
+ *     version.  Usually in the baseline.
+ * ${Input}
+ *     The absolute path name of the edited version of the file.
+ *     Usually in the development directory.
+ * ${Output}
+ *     The absolute path name of the file in which to write the
+ *     difference listing.  Usually in the development directory.
+ *
+ * An exit status of 0 means successful, even of the files differ (and
+ * they usually do).  An exit status which is non-zero means something
+ * is wrong.
+ */
+merge_command =
+       "fmerge ${quote $original} ${quote $MostRecent} ${quote $input} \
+-o ${quote $output} -c /dev/null";
+
+/*
+ * -------------------------------------------------------------------------
+ *
+ * The new file templates are very handy.  They allow all sorts of things
+ * to be se automatically.  You need to edit them to add your own name,
+ * and copyright conditions.
+ */
+
+file_template =
+[
+       {
+               pattern = [ "*" ];
+                body = "${read_file ${source etc/template/generic abs}}";
+
+       }
+];
+
+/* -------------------------------------------------------------------------
+ *
+ * The integrate_begin_exceptions are files which are not hard linked
+ * from the baseline to the integration directory.  In this case, this
+ * is done to ensure the version stmp is updated appropriately.
+ */
+
+integrate_begin_exceptions = [ ];
+
+
+
+
+/* -------------------------------------------------------------------------
+ *
+ * The trojan_horse_suspect field is a list of filename patterns which
+ * indicate files which *could* host a Trojan horse attack.  It makes
+ * aedist --receive more cautions.  It is NOT a silver bullet: just
+ * about ANY file can host a Trojan, one way or the other.
+ */
+
+trojan_horse_suspect = [ ];
+
+build_covers_all_architectures = true;
+
+test_command = "make test";
+
+build_time_adjust=dont_adjust;
diff --git a/rt/config.layout b/rt/config.layout
new file mode 100644 (file)
index 0000000..81917f1
--- /dev/null
@@ -0,0 +1,83 @@
+##
+##  config.layout -- Pre-defined Installation Path Layouts
+##
+##  Hints:
+##  - layouts can be loaded with configure's --enable-layout=ID option
+##  - when no --enable-layout option is given, the default layout is `RT'
+##  - a trailing plus character (`+') on paths is replaced with a
+##    `/<target>' suffix where <target> is currently hardcoded to 'rt3'.
+##    (This may become a configurable parameter at some point.)
+##
+##  The following variables must _all_ be set:
+##     prefix exec_prefix bindir sbindir sysconfdir mandir libdir
+##     datadir htmldir localstatedir logfiledir masonstatedir
+##     sessionstatedir customdir customhtmldir customlexdir
+##  (This can be seen in m4/rt_layout.m4.)
+##
+
+#   Default RT3 path layout.
+<Layout RT3>
+  prefix:              /opt/rt3
+  exec_prefix:         ${prefix}
+  bindir:              ${exec_prefix}/bin
+  sbindir:             ${exec_prefix}/sbin
+  sysconfdir:          ${prefix}/etc
+  mandir:              ${prefix}/man
+  libdir:              ${prefix}/lib
+  datadir:             ${prefix}/share
+  htmldir:             ${datadir}/html
+  manualdir:           ${datadir}/doc
+  localstatedir:       ${prefix}/var
+  logfiledir:          ${localstatedir}/log
+  masonstatedir:       ${localstatedir}/mason_data
+  sessionstatedir:     ${localstatedir}/session_data
+  customdir:           ${prefix}/local
+  custometcdir:                ${customdir}/etc
+  customhtmldir:       ${customdir}/html
+  customlexdir:                ${customdir}/po
+  customlibdir:                ${customdir}/lib
+</Layout>
+
+<Layout FreeBSD>
+  prefix:              /usr/local
+  exec_prefix:         ${prefix}
+  bindir:              ${exec_prefix}/bin
+  sbindir:             ${exec_prefix}/sbin
+  sysconfdir:          ${prefix}/etc+
+  mandir:              ${prefix}/man
+  libdir:              ${prefix}/lib+
+  datadir:             ${prefix}/share+
+  htmldir:             ${datadir}/html
+  manualdir:           ${prefix}/share/doc+
+  logfiledir:          /var/log
+  localstatedir:       /var/run+
+  masonstatedir:       ${localstatedir}/mason_data
+  sessionstatedir:     ${localstatedir}/session_data
+  customdir:           ${prefix}/share+
+  custometcdir:                ${customdir}/local/etc
+  customhtmldir:       ${customdir}/local/html
+  customlexdir:                ${customdir}/local/po
+  customlibdir:                ${customdir}/local/lib
+</Layout>
+
+<Layout Win32>
+  prefix:              C:/Program Files/Request Tracker
+  exec_prefix:         ${prefix}
+  bindir:              ${exec_prefix}/bin
+  sbindir:             ${exec_prefix}/sbin
+  sysconfdir:          ${prefix}/etc
+  mandir:              ${prefix}/man
+  libdir:              ${prefix}/lib
+  datadir:             ${prefix}
+  htmldir:             ${datadir}/html
+  manualdir:           ${datadir}/doc
+  localstatedir:       ${prefix}/var
+  logfiledir:          ${localstatedir}/log
+  masonstatedir:       ${localstatedir}/mason_data
+  sessionstatedir:     ${localstatedir}/session_data
+  customdir:           ${prefix}/local
+  custometcdir:                ${customdir}/etc
+  customhtmldir:       ${customdir}/html
+  customlexdir:                ${customdir}/po
+  customlibdir:                ${customdir}/lib
+</Layout>
diff --git a/rt/config.log b/rt/config.log
new file mode 100644 (file)
index 0000000..f854948
--- /dev/null
@@ -0,0 +1,117 @@
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by RT configure 3.0.4, which was
+generated by GNU Autoconf 2.53.  Invocation command line was
+
+  $ ./configure 
+
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = pallas
+uname -m = i686
+uname -r = 2.4.18-686
+uname -s = Linux
+uname -v = #1 Sun Apr 14 11:32:47 EST 2002
+
+/usr/bin/uname -p = unknown
+/bin/uname -X     = unknown
+
+/bin/arch              = i686
+/usr/bin/arch -k       = unknown
+/usr/convex/getsysinfo = unknown
+hostinfo               = unknown
+/bin/machine           = unknown
+/usr/bin/oslevel       = unknown
+/bin/universe          = unknown
+
+PATH: /usr/X11R6/bin/
+PATH: /opt/rt/bin
+PATH: /usr/athena/bin
+PATH: /usr/local/bin
+PATH: /bin
+PATH: /usr/bin
+PATH: /usr/sbin
+PATH: /usr/bin
+PATH: /usr/games
+PATH: $HOME/bin
+PATH: /opt/kerberos/bin
+PATH: /opt/StarOffice-4.0/bin
+PATH: /opt/mysql/bin/
+PATH: .
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+configure:1217: checking for a BSD-compatible install
+configure:1271: result: /usr/bin/install -c
+configure:1285: checking for perl
+configure:1303: found /usr/bin/perl
+configure:1316: result: /usr/bin/perl
+configure:1638: checking for chosen layout
+configure:1653: result: RT3
+configure:1964: creating ./config.status
+
+## ---------------------- ##
+## Running config.status. ##
+## ---------------------- ##
+
+This file was extended by RT config.status 3.0.4, which was
+generated by GNU Autoconf 2.53.  Invocation command line was
+
+  CONFIG_FILES    = 
+  CONFIG_HEADERS  = 
+  CONFIG_LINKS    = 
+  CONFIG_COMMANDS = 
+  $ ./config.status 
+
+on pallas
+
+config.status:637: creating sbin/rt-setup-database
+config.status:637: creating sbin/rt-test-dependencies
+config.status:637: creating Makefile
+config.status:637: creating etc/RT_Config.pm
+config.status:637: creating lib/RT.pm
+config.status:637: creating lib/t/00smoke.t
+config.status:637: creating lib/t/01harness.t
+config.status:637: creating lib/t/02regression.t
+config.status:637: creating lib/t/03web.pl
+config.status:637: creating lib/t/04_send_email.pl
+config.status:637: creating bin/mason_handler.fcgi
+config.status:637: creating bin/mason_handler.scgi
+config.status:637: creating bin/mason_handler.svc
+config.status:637: creating bin/rt-commit-handler
+config.status:637: creating bin/rt-crontool
+config.status:637: creating bin/rt-mailgate
+config.status:637: creating bin/webmux.pl
+
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+
+ac_cv_env_PERL_set=
+ac_cv_env_PERL_value=
+ac_cv_env_build_alias_set=
+ac_cv_env_build_alias_value=
+ac_cv_env_host_alias_set=
+ac_cv_env_host_alias_value=
+ac_cv_env_target_alias_set=
+ac_cv_env_target_alias_value=
+ac_cv_path_PERL=/usr/bin/perl
+ac_cv_path_install='/usr/bin/install -c'
+
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+
+#define PACKAGE_NAME "RT"
+#define PACKAGE_TARNAME "rt"
+#define PACKAGE_VERSION "3.0.4"
+#define PACKAGE_STRING "RT 3.0.4"
+#define PACKAGE_BUGREPORT "rt-3.0-bugs@fsck.com"
+
+configure: exit 0
diff --git a/rt/config.pld b/rt/config.pld
new file mode 100644 (file)
index 0000000..c71c7bb
--- /dev/null
@@ -0,0 +1,19 @@
+(test "x$prefix" = "xNONE" || test "x$prefix" = "x") && prefix=/opt/rt3
+(test "x$exec_prefix" = "xNONE" || test "x$exec_prefix" = "x") && exec_prefix=${prefix}
+bindir=${exec_prefix}/bin
+sbindir=${exec_prefix}/sbin
+sysconfdir=${prefix}/etc
+mandir=${prefix}/man
+libdir=${prefix}/lib
+datadir=${prefix}/share
+(test "x$htmldir" = "xNONE" || test "x$htmldir" = "x") && htmldir=${datadir}/html
+(test "x$manualdir" = "xNONE" || test "x$manualdir" = "x") && manualdir=${datadir}/doc
+localstatedir=${prefix}/var
+(test "x$logfiledir" = "xNONE" || test "x$logfiledir" = "x") && logfiledir=${localstatedir}/log
+(test "x$masonstatedir" = "xNONE" || test "x$masonstatedir" = "x") && masonstatedir=${localstatedir}/mason_data
+(test "x$sessionstatedir" = "xNONE" || test "x$sessionstatedir" = "x") && sessionstatedir=${localstatedir}/session_data
+(test "x$customdir" = "xNONE" || test "x$customdir" = "x") && customdir=${prefix}/local
+(test "x$custometcdir" = "xNONE" || test "x$custometcdir" = "x") && custometcdir=${customdir}/etc
+(test "x$customhtmldir" = "xNONE" || test "x$customhtmldir" = "x") && customhtmldir=${customdir}/html
+(test "x$customlexdir" = "xNONE" || test "x$customlexdir" = "x") && customlexdir=${customdir}/po
+(test "x$customlibdir" = "xNONE" || test "x$customlibdir" = "x") && customlibdir=${customdir}/lib
diff --git a/rt/config.status b/rt/config.status
new file mode 100755 (executable)
index 0000000..e7d8358
--- /dev/null
@@ -0,0 +1,711 @@
+#! /bin/sh
+# Generated by configure.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# NLS nuisances.
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
+    { $as_unset LANG || test "${LANG+set}" != set; } ||
+      { LANG=C; export LANG; }
+(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
+    { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
+      { LC_ALL=C; export LC_ALL; }
+(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
+    { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
+      { LC_TIME=C; export LC_TIME; }
+(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
+    { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
+      { LC_CTYPE=C; export LC_CTYPE; }
+(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
+    { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
+      { LANGUAGE=C; export LANGUAGE; }
+(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
+    { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
+      { LC_COLLATE=C; export LC_COLLATE; }
+(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
+    { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
+      { LC_NUMERIC=C; export LC_NUMERIC; }
+(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
+    { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
+      { LC_MESSAGES=C; export LC_MESSAGES; }
+
+
+# Name of the executable.
+as_me=`(basename "$0") 2>/dev/null ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conftest.sh
+  echo  "exit 0"   >>conftest.sh
+  chmod +x conftest.sh
+  if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conftest.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by RT $as_me 3.0.4, which was
+generated by GNU Autoconf 2.53.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+config_files=" sbin/rt-setup-database sbin/rt-test-dependencies Makefile etc/RT_Config.pm lib/RT.pm lib/t/00smoke.t lib/t/01harness.t lib/t/02regression.t lib/t/03web.pl lib/t/04_send_email.pl bin/mason_handler.fcgi bin/mason_handler.scgi bin/mason_handler.svc bin/rt-commit-handler bin/rt-crontool bin/rt-mailgate bin/webmux.pl"
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+ac_cs_version="\
+RT config.status 3.0.4
+configured by ./configure, generated by GNU Autoconf 2.53,
+  with options \"\"
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=.
+INSTALL="/usr/bin/install -c"
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    shift
+    set dummy "$ac_option" "$ac_optarg" ${1+"$@"}
+    shift
+    ;;
+  -*);;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_need_defaults=false;;
+  esac
+
+  case $1 in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running /bin/sh ./configure "  " --no-create --no-recursion"
+    exec /bin/sh ./configure  --no-create --no-recursion ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    shift
+    CONFIG_FILES="$CONFIG_FILES $1"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $1"
+    ac_need_defaults=false;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "sbin/rt-setup-database" ) CONFIG_FILES="$CONFIG_FILES sbin/rt-setup-database" ;;
+  "sbin/rt-test-dependencies" ) CONFIG_FILES="$CONFIG_FILES sbin/rt-test-dependencies" ;;
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "etc/RT_Config.pm" ) CONFIG_FILES="$CONFIG_FILES etc/RT_Config.pm" ;;
+  "lib/RT.pm" ) CONFIG_FILES="$CONFIG_FILES lib/RT.pm" ;;
+  "lib/t/00smoke.t" ) CONFIG_FILES="$CONFIG_FILES lib/t/00smoke.t" ;;
+  "lib/t/01harness.t" ) CONFIG_FILES="$CONFIG_FILES lib/t/01harness.t" ;;
+  "lib/t/02regression.t" ) CONFIG_FILES="$CONFIG_FILES lib/t/02regression.t" ;;
+  "lib/t/03web.pl" ) CONFIG_FILES="$CONFIG_FILES lib/t/03web.pl" ;;
+  "lib/t/04_send_email.pl" ) CONFIG_FILES="$CONFIG_FILES lib/t/04_send_email.pl" ;;
+  "bin/mason_handler.fcgi" ) CONFIG_FILES="$CONFIG_FILES bin/mason_handler.fcgi" ;;
+  "bin/mason_handler.scgi" ) CONFIG_FILES="$CONFIG_FILES bin/mason_handler.scgi" ;;
+  "bin/mason_handler.svc" ) CONFIG_FILES="$CONFIG_FILES bin/mason_handler.svc" ;;
+  "bin/rt-commit-handler" ) CONFIG_FILES="$CONFIG_FILES bin/rt-commit-handler" ;;
+  "bin/rt-crontool" ) CONFIG_FILES="$CONFIG_FILES bin/rt-crontool" ;;
+  "bin/rt-mailgate" ) CONFIG_FILES="$CONFIG_FILES bin/rt-mailgate" ;;
+  "bin/webmux.pl" ) CONFIG_FILES="$CONFIG_FILES bin/webmux.pl" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+: ${TMPDIR=/tmp}
+{
+  tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=$TMPDIR/cs$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in $TMPDIR" >&2
+   { (exit 1); exit 1; }
+}
+
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t$/@;t t/; /@;t t$/s/[\\&,]/\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t$/,;t t/' >$tmp/subs.sed <<\CEOF
+s,@SHELL@,/bin/sh,;t t
+s,@PATH_SEPARATOR@,:,;t t
+s,@PACKAGE_NAME@,RT,;t t
+s,@PACKAGE_TARNAME@,rt,;t t
+s,@PACKAGE_VERSION@,3.0.4,;t t
+s,@PACKAGE_STRING@,RT 3.0.4,;t t
+s,@PACKAGE_BUGREPORT@,rt-3.0-bugs@fsck.com,;t t
+s,@exec_prefix@,/opt/rt3,;t t
+s,@prefix@,/opt/rt3,;t t
+s,@program_transform_name@,s,x,x,,;t t
+s,@bindir@,/opt/rt3/bin,;t t
+s,@sbindir@,/opt/rt3/sbin,;t t
+s,@libexecdir@,${exec_prefix}/libexec,;t t
+s,@datadir@,/opt/rt3/share,;t t
+s,@sysconfdir@,/opt/rt3/etc,;t t
+s,@sharedstatedir@,${prefix}/com,;t t
+s,@localstatedir@,/opt/rt3/var,;t t
+s,@libdir@,/opt/rt3/lib,;t t
+s,@includedir@,${prefix}/include,;t t
+s,@oldincludedir@,/usr/include,;t t
+s,@infodir@,${prefix}/info,;t t
+s,@mandir@,/opt/rt3/man,;t t
+s,@build_alias@,,;t t
+s,@host_alias@,,;t t
+s,@target_alias@,,;t t
+s,@DEFS@,-DPACKAGE_NAME=\"RT\" -DPACKAGE_TARNAME=\"rt\" -DPACKAGE_VERSION=\"3.0.4\" -DPACKAGE_STRING=\"RT\ 3.0.4\" -DPACKAGE_BUGREPORT=\"rt-3.0-bugs@fsck.com\" ,;t t
+s,@ECHO_C@,,;t t
+s,@ECHO_N@,-n,;t t
+s,@ECHO_T@,,;t t
+s,@LIBS@,,;t t
+s,@rt_version_major@,3,;t t
+s,@rt_version_minor@,0,;t t
+s,@rt_version_patch@,4,;t t
+s,@INSTALL_PROGRAM@,${INSTALL},;t t
+s,@INSTALL_SCRIPT@,${INSTALL},;t t
+s,@INSTALL_DATA@,${INSTALL} -m 644,;t t
+s,@PERL@,/usr/bin/perl,;t t
+s,@SPEEDY_BIN@,/usr/local/bin/speedy,;t t
+s,@exp_prefix@,/opt/rt3,;t t
+s,@exp_exec_prefix@,/opt/rt3,;t t
+s,@exp_bindir@,/opt/rt3/bin,;t t
+s,@exp_sbindir@,/opt/rt3/sbin,;t t
+s,@exp_sysconfdir@,/opt/rt3/etc,;t t
+s,@exp_mandir@,/opt/rt3/man,;t t
+s,@exp_libdir@,/opt/rt3/lib,;t t
+s,@exp_datadir@,/opt/rt3/share,;t t
+s,@htmldir@,/opt/rt3/share/html,;t t
+s,@exp_htmldir@,/opt/rt3/share/html,;t t
+s,@manualdir@,/opt/rt3/share/doc,;t t
+s,@exp_manualdir@,/opt/rt3/share/doc,;t t
+s,@exp_localstatedir@,/opt/rt3/var,;t t
+s,@logfiledir@,/opt/rt3/var/log,;t t
+s,@exp_logfiledir@,/opt/rt3/var/log,;t t
+s,@masonstatedir@,/opt/rt3/var/mason_data,;t t
+s,@exp_masonstatedir@,/opt/rt3/var/mason_data,;t t
+s,@sessionstatedir@,/opt/rt3/var/session_data,;t t
+s,@exp_sessionstatedir@,/opt/rt3/var/session_data,;t t
+s,@customdir@,/opt/rt3/local,;t t
+s,@exp_customdir@,/opt/rt3/local,;t t
+s,@custometcdir@,/opt/rt3/local/etc,;t t
+s,@exp_custometcdir@,/opt/rt3/local/etc,;t t
+s,@customhtmldir@,/opt/rt3/local/html,;t t
+s,@exp_customhtmldir@,/opt/rt3/local/html,;t t
+s,@customlexdir@,/opt/rt3/local/po,;t t
+s,@exp_customlexdir@,/opt/rt3/local/po,;t t
+s,@customlibdir@,/opt/rt3/local/lib,;t t
+s,@exp_customlibdir@,/opt/rt3/local/lib,;t t
+s,@rt_layout_name@,RT3,;t t
+s,@RTGROUP@,rt,;t t
+s,@BIN_OWNER@,root,;t t
+s,@LIBS_OWNER@,root,;t t
+s,@LIBS_GROUP@,bin,;t t
+s,@DB_TYPE@,mysql,;t t
+s,@DB_HOST@,localhost,;t t
+s,@DB_PORT@,,;t t
+s,@DB_RT_HOST@,localhost,;t t
+s,@DB_DBA@,root,;t t
+s,@DB_DATABASE@,rt3,;t t
+s,@DB_RT_USER@,rt_user,;t t
+s,@DB_RT_PASS@,rt_pass,;t t
+s,@WEB_USER@,www,;t t
+s,@WEB_GROUP@,www,;t t
+s,@RT_VERSION_MAJOR@,3,;t t
+s,@RT_VERSION_MINOR@,0,;t t
+s,@RT_VERSION_PATCH@,4,;t t
+s,@RT_PATH@,/opt/rt3,;t t
+s,@RT_DOC_PATH@,/opt/rt3/share/doc,;t t
+s,@RT_LOCAL_PATH@,/opt/rt3/local,;t t
+s,@RT_LIB_PATH@,/opt/rt3/lib,;t t
+s,@RT_ETC_PATH@,/opt/rt3/etc,;t t
+s,@CONFIG_FILE_PATH@,/opt/rt3/etc,;t t
+s,@RT_BIN_PATH@,/opt/rt3/bin,;t t
+s,@RT_SBIN_PATH@,/opt/rt3/sbin,;t t
+s,@RT_VAR_PATH@,/opt/rt3/var,;t t
+s,@RT_MAN_PATH@,/opt/rt3/man,;t t
+s,@MASON_DATA_PATH@,/opt/rt3/var/mason_data,;t t
+s,@MASON_SESSION_PATH@,/opt/rt3/var/session_data,;t t
+s,@MASON_HTML_PATH@,/opt/rt3/share/html,;t t
+s,@LOCAL_ETC_PATH@,/opt/rt3/local/etc,;t t
+s,@MASON_LOCAL_HTML_PATH@,/opt/rt3/local/html,;t t
+s,@LOCAL_LEXICON_PATH@,/opt/rt3/local/po,;t t
+s,@LOCAL_LIB_PATH@,/opt/rt3/local/lib,;t t
+s,@DESTDIR@,/opt/rt3,;t t
+s,@RT_LOG_PATH@,/opt/rt3/var/log,;t t
+CEOF
+
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { case "$ac_dir" in
+  [\\/]* | ?:[\\/]* ) as_incr_dir=;;
+  *)                      as_incr_dir=.;;
+esac
+as_dummy="$ac_dir"
+for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
+  case $as_mkdir_dir in
+    # Skip DOS drivespec
+    ?:) as_incr_dir=$as_mkdir_dir ;;
+    *)
+      as_incr_dir=$as_incr_dir/$as_mkdir_dir
+      test -d "$as_incr_dir" ||
+        mkdir "$as_incr_dir" ||
+       { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }
+    ;;
+  esac
+done; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  sed "/^[     ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[   ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[     ]*$//;
+}
+
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+
+{ (exit 0); exit 0; }
diff --git a/rt/configure b/rt/configure
new file mode 100755 (executable)
index 0000000..c89d759
--- /dev/null
@@ -0,0 +1,2747 @@
+#! /bin/sh
+# From configure.ac Revision: 1.1 .
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.53 for RT 3.0.4.
+#
+# Report bugs to <rt-3.0-bugs@fsck.com>.
+#
+# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# NLS nuisances.
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
+    { $as_unset LANG || test "${LANG+set}" != set; } ||
+      { LANG=C; export LANG; }
+(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
+    { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
+      { LC_ALL=C; export LC_ALL; }
+(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
+    { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
+      { LC_TIME=C; export LC_TIME; }
+(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
+    { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
+      { LC_CTYPE=C; export LC_CTYPE; }
+(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
+    { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
+      { LANGUAGE=C; export LANGUAGE; }
+(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
+    { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
+      { LC_COLLATE=C; export LC_COLLATE; }
+(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
+    { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
+      { LC_NUMERIC=C; export LC_NUMERIC; }
+(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
+    { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
+      { LC_MESSAGES=C; export LC_MESSAGES; }
+
+
+# Name of the executable.
+as_me=`(basename "$0") 2>/dev/null ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conftest.sh
+  echo  "exit 0"   >>conftest.sh
+  chmod +x conftest.sh
+  if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conftest.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='RT'
+PACKAGE_TARNAME='rt'
+PACKAGE_VERSION='3.0.4'
+PACKAGE_STRING='RT 3.0.4'
+PACKAGE_BUGREPORT='rt-3.0-bugs@fsck.com'
+
+ac_unique_file="lib/RT.pm.in"
+ac_default_prefix=/opt/rt3
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+              localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$0" : 'X\(//\)[^/]' \| \
+         X"$0" : 'X\(//\)$' \| \
+         X"$0" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_PERL_set=${PERL+set}
+ac_env_PERL_value=$PERL
+ac_cv_env_PERL_set=${PERL+set}
+ac_cv_env_PERL_value=$PERL
+
+#
+# Report the --help message.
+#
+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 3.0.4 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of RT 3.0.4:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-layout=LAYOUT  Use a specific directory layout (Default: RT3)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-speedycgi=/path/to/speedy
+                          path to your speedycgi binary, if it exists
+  --with-rt-group=GROUP   group to own all files (default: rt)
+  --with-bin-owner=OWNER  user that will own rt binaries (default root)
+  --with-libs-owner=OWNER user that will own RT libraries (default root)
+  --with-libs-group=GROUP group that will own rt binaries (default bin)
+  --with-db-type=TYPE     sort of database RT will use (default: mysql) (mysql
+                          and Pg are valid)
+  --with-db-host=HOSTNAME FQDN of database server (default: localhost)
+  --with-db-port=PORT     port on which the database listens on
+  --with-db-rt-host=HOSTNAME
+                          FQDN of RT server which talks to the database server
+                          (default: localhost)
+  --with-db-dba=DBA       name of database administrator (default: root)
+  --with-db-database=DBNAME
+                          name of the database to use (default: rt3)
+  --with-db-rt-user=DBUSER
+                          name of database user (default: rt_user)
+  --with-db-rt-pass=PASSWORD
+                          password for database user (default: rt_pass)
+  --with-web-user=USER    user the web server runs as (default: www)
+  --with-web-group=GROUP  group the web server runs as (default: www)
+
+Some influential environment variables:
+  PERL        Perl interpreter command
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <rt-3.0-bugs@fsck.com>.
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+           test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+RT configure 3.0.4
+generated by GNU Autoconf 2.53
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_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 3.0.4, which was
+generated by GNU Autoconf 2.53.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell meta-characters.
+ac_configure_args=
+ac_sep=
+for ac_arg
+do
+  case $ac_arg in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n ) continue ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    continue ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+    ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  case " $ac_configure_args " in
+    *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+    *) ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+       ac_sep=" " ;;
+  esac
+  # Get rid of the leading space.
+done
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+        "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core core.* *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+               sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+        { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+        { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+        { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+        ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+rt_version_major=3
+
+rt_version_minor=0
+
+rt_version_patch=4
+
+test "x$rt_version_major" = 'x' && rt_version_major=0
+test "x$rt_version_minor" = 'x' && rt_version_minor=0
+test "x$rt_version_patch" = 'x' && rt_version_patch=0
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+          if test $ac_prog = install &&
+            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # AIX install.  It has an incompatible calling convention.
+            :
+          elif test $ac_prog = install &&
+            grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # program-specific install script used by HP pwplus--don't use.
+            :
+          else
+            ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+            break 3
+          fi
+        fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_PERL+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $PERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="not found"
+  ;;
+esac
+fi
+PERL=$ac_cv_path_PERL
+
+if test -n "$PERL"; then
+  echo "$as_me:$LINENO: result: $PERL" >&5
+echo "${ECHO_T}$PERL" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test "$PERL" = 'not found'; then
+       { { echo "$as_me:$LINENO: error: cannot use $PACKAGE_NAME without perl" >&5
+echo "$as_me: error: cannot use $PACKAGE_NAME without perl" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# Check whether --with-speedycgi or --without-speedycgi was given.
+if test "${with_speedycgi+set}" = set; then
+  withval="$with_speedycgi"
+  SPEEDY_BIN=$withval
+else
+  SPEEDY_BIN=/usr/local/bin/speedy
+fi;
+
+
+
+
+
+# Check whether --enable-layout or --disable-layout was given.
+if test "${enable_layout+set}" = set; then
+  enableval="$enable_layout"
+  LAYOUT=$enableval
+fi;
+
+if test "x$LAYOUT" = "x"; then
+       LAYOUT="RT3"
+fi
+
+       if test ! -f $srcdir/config.layout; then
+               { echo "$as_me:$LINENO: WARNING: Layout file $srcdir/config.layout not found" >&5
+echo "$as_me: WARNING: Layout file $srcdir/config.layout not found" >&2;}
+               rt_layout_name=no
+       else
+               pldconf=./config.pld
+               $PERL  -0777 -p -e "\$layout = '$LAYOUT';"  -e '
+               s/.*<Layout\s+$layout>//gims;
+               s/\<\/Layout\>.*//s;
+               s/^#.*$//m;
+               s/^\s+//gim;
+               s/\s+$/\n/gim;
+               s/\+$/\/rt3/gim;
+               # m4 will not let us just use $srcdir/config.layout, we need $1
+               s/^\s*((?:bin|sbin|libexec|data|sysconf|sharedstate|localstate|lib|include|oldinclude|info|man)dir)\s*:\s*(.*)$/$1=$2/gim;
+               s/^\s*(.*?)\s*:\s*(.*)$/\(test "x\$$1" = "xNONE" || test "x\$$1" = "x") && $1=$2/gim;
+                ' < $srcdir/config.layout > $pldconf
+
+               if test -s $pldconf; then
+                       rt_layout_name=$LAYOUT
+                       . $pldconf
+
+                       for var in prefix exec_prefix bindir sbindir \
+                                sysconfdir mandir libdir datadir htmldir \
+                                localstatedir logfiledir masonstatedir \
+                                sessionstatedir customdir custometcdir customhtmldir \
+                                customlexdir customlibdir manualdir; do
+                               eval "val=\"\$$var\""
+                               val=`echo $val | sed -e 's:\(.\)/*$:\1:'`
+                               val=`echo $val |
+                                       sed -e 's:[\$]\([a-z_]*\):$\1:g'`
+                               eval "$var='$val'"
+                       done
+
+               else
+                       rt_layout_name=no
+               fi
+               #rm $pldconf
+       fi
+
+
+       ap_last=''
+       ap_cur='$prefix'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_prefix="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$exec_prefix'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_exec_prefix="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$bindir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_bindir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$sbindir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_sbindir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$sysconfdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_sysconfdir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$mandir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_mandir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$libdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_libdir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$datadir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_datadir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$htmldir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_htmldir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$manualdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_manualdir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$localstatedir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_localstatedir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$logfiledir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_logfiledir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$masonstatedir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_masonstatedir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$sessionstatedir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_sessionstatedir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$customdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_customdir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$custometcdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_custometcdir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$customhtmldir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_customhtmldir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$customlexdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_customlexdir="${ap_cur}"
+
+
+
+
+
+
+       ap_last=''
+       ap_cur='$customlibdir'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       exp_customlibdir="${ap_cur}"
+
+
+
+
+
+echo "$as_me:$LINENO: checking for chosen layout" >&5
+echo $ECHO_N "checking for chosen layout... $ECHO_C" >&6
+if test "x$rt_layout_name" = "xno"; then
+       if test "x$LAYOUT" = "xno"; then
+               echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6
+       else
+               echo "$as_me:$LINENO: result: $LAYOUT" >&5
+echo "${ECHO_T}$LAYOUT" >&6
+       fi
+       { { echo "$as_me:$LINENO: error: a valid layout must be specified (or the default used)" >&5
+echo "$as_me: error: a valid layout must be specified (or the default used)" >&2;}
+   { (exit 1); exit 1; }; }
+else
+
+       echo "$as_me:$LINENO: result: $rt_layout_name" >&5
+echo "${ECHO_T}$rt_layout_name" >&6
+fi
+
+
+
+# Check whether --with-rt-group or --without-rt-group was given.
+if test "${with_rt_group+set}" = set; then
+  withval="$with_rt_group"
+  RTGROUP=$withval
+else
+  RTGROUP=rt
+fi;
+
+
+
+# Check whether --with-bin-owner or --without-bin-owner was given.
+if test "${with_bin_owner+set}" = set; then
+  withval="$with_bin_owner"
+  BIN_OWNER=$withval
+else
+  BIN_OWNER=root
+fi;
+
+
+
+# Check whether --with-libs-owner or --without-libs-owner was given.
+if test "${with_libs_owner+set}" = set; then
+  withval="$with_libs_owner"
+  LIBS_OWNER=$withval
+else
+  LIBS_OWNER=root
+fi;
+
+
+
+# Check whether --with-libs-group or --without-libs-group was given.
+if test "${with_libs_group+set}" = set; then
+  withval="$with_libs_group"
+  LIBS_GROUP=$withval
+else
+  LIBS_GROUP=bin
+fi;
+
+
+
+# Check whether --with-db-type or --without-db-type was given.
+if test "${with_db_type+set}" = set; then
+  withval="$with_db_type"
+  DB_TYPE=$withval
+else
+  DB_TYPE=mysql
+fi;
+if test "$DB_TYPE" != 'mysql' -a "$DB_TYPE" != 'Pg' -a "$DB_TYPE" != 'SQLite'; then
+       { { echo "$as_me:$LINENO: error: Only Pg and mysql are valid db types" >&5
+echo "$as_me: error: Only Pg and mysql are valid db types" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+
+# Check whether --with-db-host or --without-db-host was given.
+if test "${with_db_host+set}" = set; then
+  withval="$with_db_host"
+  DB_HOST=$withval
+else
+  DB_HOST=localhost
+fi;
+
+
+
+# Check whether --with-db-port or --without-db-port was given.
+if test "${with_db_port+set}" = set; then
+  withval="$with_db_port"
+  DB_PORT=$withval
+else
+  DB_PORT=
+fi;
+
+
+
+# Check whether --with-db-rt-host or --without-db-rt-host was given.
+if test "${with_db_rt_host+set}" = set; then
+  withval="$with_db_rt_host"
+  DB_RT_HOST=$withval
+else
+  DB_RT_HOST=localhost
+fi;
+
+
+
+# Check whether --with-db-dba or --without-db-dba was given.
+if test "${with_db_dba+set}" = set; then
+  withval="$with_db_dba"
+  DB_DBA=$withval
+else
+  DB_DBA=root
+fi;
+
+
+
+# Check whether --with-db-database or --without-db-database was given.
+if test "${with_db_database+set}" = set; then
+  withval="$with_db_database"
+  DB_DATABASE=$withval
+else
+  DB_DATABASE=rt3
+fi;
+
+
+
+# Check whether --with-db-rt-user or --without-db-rt-user was given.
+if test "${with_db_rt_user+set}" = set; then
+  withval="$with_db_rt_user"
+  DB_RT_USER=$withval
+else
+  DB_RT_USER=rt_user
+fi;
+
+
+
+# Check whether --with-db-rt-pass or --without-db-rt-pass was given.
+if test "${with_db_rt_pass+set}" = set; then
+  withval="$with_db_rt_pass"
+  DB_RT_PASS=$withval
+else
+  DB_RT_PASS=rt_pass
+fi;
+
+
+
+# Check whether --with-web-user or --without-web-user was given.
+if test "${with_web_user+set}" = set; then
+  withval="$with_web_user"
+  WEB_USER=$withval
+else
+  WEB_USER=www
+fi;
+
+
+
+# Check whether --with-web-group or --without-web-group was given.
+if test "${with_web_group+set}" = set; then
+  withval="$with_web_group"
+  WEB_GROUP=$withval
+else
+  WEB_GROUP=www
+fi;
+
+
+
+RT_VERSION_MAJOR=${rt_version_major}
+
+RT_VERSION_MINOR=${rt_version_minor}
+
+RT_VERSION_PATCH=${rt_version_patch}
+
+
+RT_PATH=${exp_prefix}
+
+RT_DOC_PATH=${exp_manualdir}
+
+RT_LOCAL_PATH=${exp_customdir}
+
+RT_LIB_PATH=${exp_libdir}
+
+RT_ETC_PATH=${exp_sysconfdir}
+
+CONFIG_FILE_PATH=${exp_sysconfdir}
+
+RT_BIN_PATH=${exp_bindir}
+
+RT_SBIN_PATH=${exp_sbindir}
+
+RT_VAR_PATH=${exp_localstatedir}
+
+RT_MAN_PATH=${exp_mandir}
+
+MASON_DATA_PATH=${exp_masonstatedir}
+
+MASON_SESSION_PATH=${exp_sessionstatedir}
+
+MASON_HTML_PATH=${exp_htmldir}
+
+LOCAL_ETC_PATH=${exp_custometcdir}
+
+MASON_LOCAL_HTML_PATH=${exp_customhtmldir}
+
+LOCAL_LEXICON_PATH=${exp_customlexdir}
+
+LOCAL_LIB_PATH=${exp_customlibdir}
+
+DESTDIR=${exp_prefix}
+
+RT_LOG_PATH=${exp_logfiledir}
+
+
+
+ac_config_files="$ac_config_files sbin/rt-setup-database sbin/rt-test-dependencies Makefile etc/RT_Config.pm lib/RT.pm lib/t/00smoke.t lib/t/01harness.t lib/t/02regression.t lib/t/03web.pl lib/t/04_send_email.pl bin/mason_handler.fcgi bin/mason_handler.scgi bin/mason_handler.svc bin/rt-commit-handler bin/rt-crontool bin/rt-mailgate bin/webmux.pl"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overriden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+        "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if cmp -s $cache_file confcache; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[   ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[     ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[   ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
+t quote
+s,^[   ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[    `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# NLS nuisances.
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
+    { $as_unset LANG || test "${LANG+set}" != set; } ||
+      { LANG=C; export LANG; }
+(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
+    { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
+      { LC_ALL=C; export LC_ALL; }
+(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
+    { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
+      { LC_TIME=C; export LC_TIME; }
+(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
+    { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
+      { LC_CTYPE=C; export LC_CTYPE; }
+(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
+    { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
+      { LANGUAGE=C; export LANGUAGE; }
+(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
+    { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
+      { LC_COLLATE=C; export LC_COLLATE; }
+(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
+    { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
+      { LC_NUMERIC=C; export LC_NUMERIC; }
+(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
+    { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
+      { LC_MESSAGES=C; export LC_MESSAGES; }
+
+
+# Name of the executable.
+as_me=`(basename "$0") 2>/dev/null ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conftest.sh
+  echo  "exit 0"   >>conftest.sh
+  chmod +x conftest.sh
+  if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conftest.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by RT $as_me 3.0.4, which was
+generated by GNU Autoconf 2.53.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+RT config.status 3.0.4
+configured by $0, generated by GNU Autoconf 2.53,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    shift
+    set dummy "$ac_option" "$ac_optarg" ${1+"$@"}
+    shift
+    ;;
+  -*);;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_need_defaults=false;;
+  esac
+
+  case $1 in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion"
+    exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;;
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    shift
+    CONFIG_FILES="$CONFIG_FILES $1"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $1"
+    ac_need_defaults=false;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "sbin/rt-setup-database" ) CONFIG_FILES="$CONFIG_FILES sbin/rt-setup-database" ;;
+  "sbin/rt-test-dependencies" ) CONFIG_FILES="$CONFIG_FILES sbin/rt-test-dependencies" ;;
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "etc/RT_Config.pm" ) CONFIG_FILES="$CONFIG_FILES etc/RT_Config.pm" ;;
+  "lib/RT.pm" ) CONFIG_FILES="$CONFIG_FILES lib/RT.pm" ;;
+  "lib/t/00smoke.t" ) CONFIG_FILES="$CONFIG_FILES lib/t/00smoke.t" ;;
+  "lib/t/01harness.t" ) CONFIG_FILES="$CONFIG_FILES lib/t/01harness.t" ;;
+  "lib/t/02regression.t" ) CONFIG_FILES="$CONFIG_FILES lib/t/02regression.t" ;;
+  "lib/t/03web.pl" ) CONFIG_FILES="$CONFIG_FILES lib/t/03web.pl" ;;
+  "lib/t/04_send_email.pl" ) CONFIG_FILES="$CONFIG_FILES lib/t/04_send_email.pl" ;;
+  "bin/mason_handler.fcgi" ) CONFIG_FILES="$CONFIG_FILES bin/mason_handler.fcgi" ;;
+  "bin/mason_handler.scgi" ) CONFIG_FILES="$CONFIG_FILES bin/mason_handler.scgi" ;;
+  "bin/mason_handler.svc" ) CONFIG_FILES="$CONFIG_FILES bin/mason_handler.svc" ;;
+  "bin/rt-commit-handler" ) CONFIG_FILES="$CONFIG_FILES bin/rt-commit-handler" ;;
+  "bin/rt-crontool" ) CONFIG_FILES="$CONFIG_FILES bin/rt-crontool" ;;
+  "bin/rt-mailgate" ) CONFIG_FILES="$CONFIG_FILES bin/rt-mailgate" ;;
+  "bin/webmux.pl" ) CONFIG_FILES="$CONFIG_FILES bin/webmux.pl" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+: ${TMPDIR=/tmp}
+{
+  tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=$TMPDIR/cs$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in $TMPDIR" >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@rt_version_major@,$rt_version_major,;t t
+s,@rt_version_minor@,$rt_version_minor,;t t
+s,@rt_version_patch@,$rt_version_patch,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@PERL@,$PERL,;t t
+s,@SPEEDY_BIN@,$SPEEDY_BIN,;t t
+s,@exp_prefix@,$exp_prefix,;t t
+s,@exp_exec_prefix@,$exp_exec_prefix,;t t
+s,@exp_bindir@,$exp_bindir,;t t
+s,@exp_sbindir@,$exp_sbindir,;t t
+s,@exp_sysconfdir@,$exp_sysconfdir,;t t
+s,@exp_mandir@,$exp_mandir,;t t
+s,@exp_libdir@,$exp_libdir,;t t
+s,@exp_datadir@,$exp_datadir,;t t
+s,@htmldir@,$htmldir,;t t
+s,@exp_htmldir@,$exp_htmldir,;t t
+s,@manualdir@,$manualdir,;t t
+s,@exp_manualdir@,$exp_manualdir,;t t
+s,@exp_localstatedir@,$exp_localstatedir,;t t
+s,@logfiledir@,$logfiledir,;t t
+s,@exp_logfiledir@,$exp_logfiledir,;t t
+s,@masonstatedir@,$masonstatedir,;t t
+s,@exp_masonstatedir@,$exp_masonstatedir,;t t
+s,@sessionstatedir@,$sessionstatedir,;t t
+s,@exp_sessionstatedir@,$exp_sessionstatedir,;t t
+s,@customdir@,$customdir,;t t
+s,@exp_customdir@,$exp_customdir,;t t
+s,@custometcdir@,$custometcdir,;t t
+s,@exp_custometcdir@,$exp_custometcdir,;t t
+s,@customhtmldir@,$customhtmldir,;t t
+s,@exp_customhtmldir@,$exp_customhtmldir,;t t
+s,@customlexdir@,$customlexdir,;t t
+s,@exp_customlexdir@,$exp_customlexdir,;t t
+s,@customlibdir@,$customlibdir,;t t
+s,@exp_customlibdir@,$exp_customlibdir,;t t
+s,@rt_layout_name@,$rt_layout_name,;t t
+s,@RTGROUP@,$RTGROUP,;t t
+s,@BIN_OWNER@,$BIN_OWNER,;t t
+s,@LIBS_OWNER@,$LIBS_OWNER,;t t
+s,@LIBS_GROUP@,$LIBS_GROUP,;t t
+s,@DB_TYPE@,$DB_TYPE,;t t
+s,@DB_HOST@,$DB_HOST,;t t
+s,@DB_PORT@,$DB_PORT,;t t
+s,@DB_RT_HOST@,$DB_RT_HOST,;t t
+s,@DB_DBA@,$DB_DBA,;t t
+s,@DB_DATABASE@,$DB_DATABASE,;t t
+s,@DB_RT_USER@,$DB_RT_USER,;t t
+s,@DB_RT_PASS@,$DB_RT_PASS,;t t
+s,@WEB_USER@,$WEB_USER,;t t
+s,@WEB_GROUP@,$WEB_GROUP,;t t
+s,@RT_VERSION_MAJOR@,$RT_VERSION_MAJOR,;t t
+s,@RT_VERSION_MINOR@,$RT_VERSION_MINOR,;t t
+s,@RT_VERSION_PATCH@,$RT_VERSION_PATCH,;t t
+s,@RT_PATH@,$RT_PATH,;t t
+s,@RT_DOC_PATH@,$RT_DOC_PATH,;t t
+s,@RT_LOCAL_PATH@,$RT_LOCAL_PATH,;t t
+s,@RT_LIB_PATH@,$RT_LIB_PATH,;t t
+s,@RT_ETC_PATH@,$RT_ETC_PATH,;t t
+s,@CONFIG_FILE_PATH@,$CONFIG_FILE_PATH,;t t
+s,@RT_BIN_PATH@,$RT_BIN_PATH,;t t
+s,@RT_SBIN_PATH@,$RT_SBIN_PATH,;t t
+s,@RT_VAR_PATH@,$RT_VAR_PATH,;t t
+s,@RT_MAN_PATH@,$RT_MAN_PATH,;t t
+s,@MASON_DATA_PATH@,$MASON_DATA_PATH,;t t
+s,@MASON_SESSION_PATH@,$MASON_SESSION_PATH,;t t
+s,@MASON_HTML_PATH@,$MASON_HTML_PATH,;t t
+s,@LOCAL_ETC_PATH@,$LOCAL_ETC_PATH,;t t
+s,@MASON_LOCAL_HTML_PATH@,$MASON_LOCAL_HTML_PATH,;t t
+s,@LOCAL_LEXICON_PATH@,$LOCAL_LEXICON_PATH,;t t
+s,@LOCAL_LIB_PATH@,$LOCAL_LIB_PATH,;t t
+s,@DESTDIR@,$DESTDIR,;t t
+s,@RT_LOG_PATH@,$RT_LOG_PATH,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { case "$ac_dir" in
+  [\\/]* | ?:[\\/]* ) as_incr_dir=;;
+  *)                      as_incr_dir=.;;
+esac
+as_dummy="$ac_dir"
+for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
+  case $as_mkdir_dir in
+    # Skip DOS drivespec
+    ?:) as_incr_dir=$as_mkdir_dir ;;
+    *)
+      as_incr_dir=$as_incr_dir/$as_mkdir_dir
+      test -d "$as_incr_dir" ||
+        mkdir "$as_incr_dir" ||
+       { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }
+    ;;
+  esac
+done; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/rt/configure.ac b/rt/configure.ac
new file mode 100644 (file)
index 0000000..cd82c44
--- /dev/null
@@ -0,0 +1,209 @@
+dnl
+dnl Process this file with autoconf to produce a configure script
+dnl
+dnl Embed in generated ./configure script the following CVS info:
+AC_REVISION($Revision: 1.1 $)dnl
+
+dnl Setup autoconf
+AC_PREREQ(2.53)
+AC_INIT(RT, [3.0.4], [rt-3.0-bugs@fsck.com])
+AC_CONFIG_SRCDIR([lib/RT.pm.in])
+
+dnl Extract RT version number components
+AC_SUBST([rt_version_major],
+       m4_bregexp(AC_PACKAGE_VERSION,[^\(\w+\)\.\(\w+\)\(\.\(\w+\)\)?],[\1]))
+AC_SUBST([rt_version_minor],
+       m4_bregexp(AC_PACKAGE_VERSION,[^\(\w+\)\.\(\w+\)\(\.\(\w+\)\)?],[\2]))
+AC_SUBST([rt_version_patch],
+       m4_bregexp(AC_PACKAGE_VERSION,[^\(\w+\)\.\(\w+\)\(\.\(\w+\)\)?],[\4]))
+test "x$rt_version_major" = 'x' && rt_version_major=0
+test "x$rt_version_minor" = 'x' && rt_version_minor=0
+test "x$rt_version_patch" = 'x' && rt_version_patch=0
+
+dnl Check for programs
+AC_PROG_INSTALL
+AC_ARG_VAR([PERL],[Perl interpreter command])
+AC_PATH_PROG([PERL], [perl], [not found])
+if test "$PERL" = 'not found'; then
+       AC_MSG_ERROR([cannot use $PACKAGE_NAME without perl])
+fi
+dnl SPEED_BIN
+AC_ARG_WITH(speedycgi,
+           AC_HELP_STRING([--with-speedycgi=/path/to/speedy],
+                          [path to your speedycgi binary, if it exists]),
+            SPEEDY_BIN=$withval,
+            SPEEDY_BIN=/usr/local/bin/speedy) 
+AC_SUBST(SPEEDY_BIN)
+
+
+dnl Defaults paths for installation
+AC_PREFIX_DEFAULT([/opt/rt3])
+RT_ENABLE_LAYOUT
+
+dnl RTGROUP
+AC_ARG_WITH(rt-group,
+           AC_HELP_STRING([--with-rt-group=GROUP],
+                          [group to own all files (default: rt)]),
+            RTGROUP=$withval,
+            RTGROUP=rt)
+AC_SUBST(RTGROUP)
+
+dnl BIN_OWNER
+AC_ARG_WITH(bin-owner,
+           AC_HELP_STRING([--with-bin-owner=OWNER],
+                          [user that will own rt binaries (default root)]),
+            BIN_OWNER=$withval,
+            BIN_OWNER=root)
+AC_SUBST(BIN_OWNER)
+
+dnl LIBS_OWNER
+AC_ARG_WITH(libs-owner,
+           AC_HELP_STRING([--with-libs-owner=OWNER],
+                          [user that will own RT libraries (default root)]),
+            LIBS_OWNER=$withval,
+            LIBS_OWNER=root)
+AC_SUBST(LIBS_OWNER)
+
+dnl LIBS_GROUP
+AC_ARG_WITH(libs-group,
+           AC_HELP_STRING([--with-libs-group=GROUP],
+                          [group that will own rt binaries (default bin)]),
+            LIBS_GROUP=$withval,
+            LIBS_GROUP=bin)
+AC_SUBST(LIBS_GROUP)
+
+dnl DB_TYPE
+AC_ARG_WITH(db-type,
+           AC_HELP_STRING([--with-db-type=TYPE],
+                          [sort of database RT will use (default: mysql) (mysql and Pg are valid)]), 
+            DB_TYPE=$withval,
+            DB_TYPE=mysql)
+if test "$DB_TYPE" != 'mysql' -a "$DB_TYPE" != 'Pg' -a "$DB_TYPE" != 'SQLite'; then
+       AC_MSG_ERROR([Only Pg and mysql are valid db types])
+fi
+AC_SUBST(DB_TYPE)
+
+dnl DB_HOST
+AC_ARG_WITH(db-host,
+           AC_HELP_STRING([--with-db-host=HOSTNAME],
+                          [FQDN of database server (default: localhost)]),
+            DB_HOST=$withval,
+            DB_HOST=localhost)
+AC_SUBST(DB_HOST)
+
+dnl DB_PORT
+AC_ARG_WITH(db-port,
+           AC_HELP_STRING([--with-db-port=PORT],
+                          [port on which the database listens on]),
+            DB_PORT=$withval,
+            DB_PORT=)
+AC_SUBST(DB_PORT)
+
+dnl DB_RT_HOST
+AC_ARG_WITH(db-rt-host,
+           AC_HELP_STRING([--with-db-rt-host=HOSTNAME],
+                          [FQDN of RT server which talks to the database server (default: localhost)]),
+            DB_RT_HOST=$withval,
+            DB_RT_HOST=localhost)
+AC_SUBST(DB_RT_HOST)
+
+dnl DB_DATABASE_ADMIN
+AC_ARG_WITH(db-dba,
+           AC_HELP_STRING([--with-db-dba=DBA],
+                          [name of database administrator (default: root)]),
+            DB_DBA=$withval,
+            DB_DBA=root)
+AC_SUBST(DB_DBA)
+
+dnl DB_DATABASE
+AC_ARG_WITH(db-database,
+           AC_HELP_STRING([--with-db-database=DBNAME],
+                          [name of the database to use (default: rt3)]),
+            DB_DATABASE=$withval,
+            DB_DATABASE=rt3)
+AC_SUBST(DB_DATABASE)
+
+dnl DB_RT_USER
+AC_ARG_WITH(db-rt-user,
+           AC_HELP_STRING([--with-db-rt-user=DBUSER],
+                          [name of database user (default: rt_user)]),
+            DB_RT_USER=$withval,
+            DB_RT_USER=rt_user)
+AC_SUBST(DB_RT_USER)
+
+dnl DB_RT_PASS
+AC_ARG_WITH(db-rt-pass,
+           AC_HELP_STRING([--with-db-rt-pass=PASSWORD],
+                          [password for database user (default: rt_pass)]),
+            DB_RT_PASS=$withval,
+            DB_RT_PASS=rt_pass)
+AC_SUBST(DB_RT_PASS)
+
+dnl WEB_USER
+AC_ARG_WITH(web-user,
+           AC_HELP_STRING([--with-web-user=USER],
+                          [user the web server runs as (default: www)]),
+            WEB_USER=$withval,
+            WEB_USER=www)
+AC_SUBST(WEB_USER)
+
+dnl WEB_GROUP
+AC_ARG_WITH(web-group,
+            AC_HELP_STRING([--with-web-group=GROUP],
+                          [group the web server runs as (default: www)]),
+            WEB_GROUP=$withval,
+            WEB_GROUP=www)
+AC_SUBST(WEB_GROUP)
+
+dnl This section maps the variable names this script 'natively' generates
+dnl to their existing names. They should be removed from here as the .in
+dnl files are changed to use the new names.
+
+dnl version numbers
+AC_SUBST(RT_VERSION_MAJOR,             ${rt_version_major})
+AC_SUBST(RT_VERSION_MINOR,             ${rt_version_minor})
+AC_SUBST(RT_VERSION_PATCH,             ${rt_version_patch})
+
+dnl layout paths
+AC_SUBST([RT_PATH],                    ${exp_prefix})
+AC_SUBST([RT_DOC_PATH],                        ${exp_manualdir})
+AC_SUBST([RT_LOCAL_PATH],              ${exp_customdir})
+AC_SUBST([RT_LIB_PATH],                        ${exp_libdir})
+AC_SUBST([RT_ETC_PATH],                        ${exp_sysconfdir})
+AC_SUBST([CONFIG_FILE_PATH],           ${exp_sysconfdir})
+AC_SUBST([RT_BIN_PATH],                        ${exp_bindir})
+AC_SUBST([RT_SBIN_PATH],               ${exp_sbindir})
+AC_SUBST([RT_VAR_PATH],                        ${exp_localstatedir})
+AC_SUBST([RT_MAN_PATH],                        ${exp_mandir})
+AC_SUBST([MASON_DATA_PATH],            ${exp_masonstatedir})
+AC_SUBST([MASON_SESSION_PATH],         ${exp_sessionstatedir})
+AC_SUBST([MASON_HTML_PATH],            ${exp_htmldir})
+AC_SUBST([LOCAL_ETC_PATH],             ${exp_custometcdir})
+AC_SUBST([MASON_LOCAL_HTML_PATH],      ${exp_customhtmldir})
+AC_SUBST([LOCAL_LEXICON_PATH],         ${exp_customlexdir})
+AC_SUBST([LOCAL_LIB_PATH],             ${exp_customlibdir})
+AC_SUBST([DESTDIR],                    ${exp_prefix})
+AC_SUBST([RT_LOG_PATH],                        ${exp_logfiledir})
+
+dnl Configure the output files, and generate them.
+
+AC_CONFIG_FILES([
+                sbin/rt-setup-database
+                 sbin/rt-test-dependencies
+                 Makefile
+                etc/RT_Config.pm
+                lib/RT.pm
+                 lib/t/00smoke.t
+                 lib/t/01harness.t
+                 lib/t/02regression.t
+                 lib/t/03web.pl
+                 lib/t/04_send_email.pl
+                bin/mason_handler.fcgi
+                bin/mason_handler.scgi
+                bin/mason_handler.svc
+                bin/rt-commit-handler
+                bin/rt-crontool
+                bin/rt-mailgate
+                bin/webmux.pl]
+                )
+AC_OUTPUT
index 3b9d856..bb093ad 100644 (file)
-$Header: /home/cvs/cvsroot/freeside/rt/docs/design_docs/acls,v 1.1 2002-08-12 06:17:07 ivan Exp $
 
 
+Does principal baz have right foo for object bar
 
-# {{{ Requirements 
+What rights does user baz have for object bar
 
-Here's the rough scheme I was thinking of for RT2 acls. Thoughts? I think
-it's a lot more flexible than RT 1.0, but not so crazily complex that
-it will be impossible to implement.  One of the "interesting" features
-is the ability to grant acls based on watcher status. This now lives
-in design-docs/acls
+# {{{ Which principals have right foo for object bar
 
-        jesse
 
-Who can rights be granted to:
+if ($args{'ObjectType'} eq 'Ticket') {
+     $or_check_ticket_roles = " OR ( Groups.Domain = 'TicketRole' AND Groups.Instance = '".$args{'ObjectId'}."') ";
+     # If we're looking at ticket rights, we also want to look at the associated queue rights.
+     # this is a little bit hacky, but basically, now that we've done the ticket roles magic, we load the queue object
+     # and ask all the rest of our questions about the queue.
+     my $tick = RT::Ticket->new($RT::SystemUser);
+     $tick->Load($args{'ObjectId'});
+     $args{'ObjectType'} = 'Queue';
+     $args{'ObjectId'} = $tick->QueueObj->Id();
 
-       users whose id is <foo>
-       users who are watchers of type <requestor/cc/admincc> for <queue/ticket> <id>
-       users who are watchers of type <requestor/cc/admincc> for <this ticket / this queue>
-
-
-what scope do these rights apply to
-       queue <id>
-       system
-       
-
-What rights can be granted
-       Display Ticket
-       Manipulate Ticket
-               Only users with manipulate ticket level access will see comments
-       Maniplulate Ticket Status
-       Create Ticket   
-
-       Admin Queue Watchers 
-       Admin Ticket Watchers
-       Admin user accounts
-       Admin scrips
-       Admin scripscopes
-       Admin Queue ACLS
-       Admin System ACLs
-
-# }}}
-
-
-# {{{ Prinicpals  These are the entities in your Access Control Element
-#
-
-Principal: What user does this right apply to
-
-       Made up of: 
-               PrincipalScope, PrincipalType and PrincipalId
-
-       
-       User:   
-               Scope:  User    
-               Type:   null
-               Id:     A userid or 0
-
-       Owner:
-               Scope:  Owner
-               Type:   null
-               Id:     none
-
-
-       Watchers:
-
-               Scope: Ticket
-               Type:   Requestors; Cc; AdminCc
-               Id:     A ticket id or 0 for "this ticket"
-
-               Scope: Queue
-               Type:   Cc; AdminCc
-               Id:     A queue id or 0 for "this queue"
-
-
-# }}}
-
-# {{{ Object: What object does this right apply to
-
-       Object is composed of an ObjectType and an ObjectId
-
-       Type:   System  
-       Id:     NULL
-
-       Type:   Queue
-       Id:     Integer ref to queue id or 0 for all queues
-       
-# }}}
-
-# {{{ Right: (What does this entry give the principal the right to do)
-
-
-
-       For the Object System:
-               System::SetACL
-               System::AdminScrips
-
-               User::Display
-               User::Create
-               User::Destroy
-               User::Modify
-               User::SetPassword
-
-
-
-       For the Object "Queue":
-               Queue::Admin
-               Queue::SetACL
-               Queue::Create
-               Queue::Display
-               Queue::Destroy
-               Queue::ModifyWatchers
-               Ticket::Create
-               Ticket::Destory
-               Ticket::Display
-               Ticket::Update
-               Ticket::UpdateRequestors
-               Ticket::UpdateCc
-               Ticket::UpdateAdminCc
-               Ticket::NotifyWatchers
-
-               
-               DEFERRED
-
-               Ticket::SetStatus:      (Values)
-                                       Open
-                                       Resolved
-                                       Stalled
-                                       <null> means any
-
-
-# }}}
-
-
-# {{{ Implementation:
-
-# {{{ SQL Schema 
-CREATE TABLE ACL (
-       id int not null primary_key autoincrement,
-       PrinicpalId INT(11),
-       PrincipalType VARCHAR(16),
-       PrincipalScope VARCHAR(16),
-       ObjectType VARCHAR(16),
-       ObjectId  INT,
-       Right VARCHAR(16)
-);
-
-# }}}
-
-# {{{ perl implementation of rights searches
-
-sub Principals {
-if (defined $Ticket) {
-       return "($UserPrincipal) OR ($OwnerPrincipal) OR ($WatchersPrincipal)";
-       }
-else {
-       return   "($UserPrincipal) OR ($WatchersPrincipal)";
-       }  
 }
-       
-$Principals = " ($UserPrincipal) OR ($OwnerPrincipal) OR ($WatchersPrincipal)";
-
-$UserPrincipal = " ( ACE.PrincipalScope = 'User') AND 
-                  ( ACE.PrincipalId = $User OR ACE.PrincipalId = 0)";
-
-$OwnerPrincipal = " ( ACE.PrinciaplScope = 'Owner') AND 
-                     ( Tickets.Owner = "$User ) AND    
-                     ( Tickets.Id = $Ticket)";
-
-$WatchersPrincipal = " ( ACE.PrincipalScope = Watchers.Scope ) AND 
-                     ( ACE.PrincipalType = Watchers.Type ) AND 
-                     ( ACL.PrincipalId = Watchers.Value ) AND 
-                     ( Watchers.Owner = $User )";
-
-$QueueObject = "( ACE.ObjectType = 'Queue' and (ACE.ObjectId = $Queue OR ACE.ObjectId = 0)";
-
-$SystemObject = "( ACE.ObjectType = 'System' )";
-
-
-# This select statement would figure out if A user has $Right at the queue level
-
-SELECT ACE.id from ACE, Watchers, Tickets WHERE ( 
-            $QueueObject
-            AND ( ACE.Right = $Right) 
-            AND ($Principals))
+if ($args{'ObjectType'} eq 'Queue') {
+     $or_check_roles = " OR ( ( (Groups.Domain = 'QueueRole' AND Groups.Instance = '".$args{'ObjectId'}."') $or_check_ticket_roles ) 
+                            AND Groups.Type = ACL.PrincipalType AND Groups.Id = Principals.ObjectId AND Principals.PrincipalType = 'Group') ";
+}
 
-# This select statement would figure outif a user has $Right for the "System"
+if (defined $args{'ObjectType'} ) {
+     $or_look_at_object_rights = " OR (ACL.ObjectType = '".$args{'ObjectType'}."'  AND ACL.ObjectId = '".$args{'ObjectId'}."') ";
 
-SELECT ACE.id from ACE, Watchers, Tickets WHERE ( 
-            ($SystemObject) AND ( ACE.Right = $Right ) AND ($Principals))
+}
 
-# }}}
+my $query = "SELECT Users.*  from ACL, Groups, Users, Principals, Principals UserPrinc, CachedGroupMembers  WHERE  
+        Users.id = UserPrinc.ObjectId AND UserPrinc.PrincipalType = 'User' AND
+        Principals.Id = CachedGroupMembers.GroupId AND 
+        CachedGroupMembers.MemberId = UserPrinc.ObjectId AND 
+        UserPrinc.PrincipalType = 'User'  AND
+        (ACL.RightName = 'SuperUser' OR  ACL.RightName = '$right') AND
+        (ACL.ObjectType = 'System' $or_look_at_object_rights) AND 
+        (
+                (ACL.PrincipalId = Principals.Id AND 
+                 Principals.ObjectId = Groups.Id AND 
+                 ACL.PrincipalType = 'Group' AND 
+                 (Groups.Domain = 'SystemInternal' OR Groups.Domain = 'UserDefined' OR Groups.Domain = 'ACLEquivalence')
+                ) 
+           $or_check_roles
+        )";
 
 # }}}
 
-# {{{ Examples
-#
-
-# }}}  
-
-
-
-Unaddressed issues:
-
-       There needs to be a more refined method for grouping users, such that members of the customer service department
-can't change sysadmins' passwords.
+What objects does principal baz have right foo for
+;
diff --git a/rt/docs/design_docs/approval_notices b/rt/docs/design_docs/approval_notices
new file mode 100644 (file)
index 0000000..5e76119
--- /dev/null
@@ -0,0 +1,8 @@
+Notification on "your request approved by"
+Notification on "your request approved by all approvers"
+Notification on "your request denied by"
+Reject ticket on rejection of any approval
+
+"Ticket N is pending your approval"
+
+
diff --git a/rt/docs/design_docs/approval_template b/rt/docs/design_docs/approval_template
new file mode 100644 (file)
index 0000000..16a988c
--- /dev/null
@@ -0,0 +1,25 @@
+===Create-Ticket: approval
+ {  my $name = "HR";
+     my $groups = RT::Groups->new($RT::SystemUser);
+   $groups->LimitToUserDefinedGroups();
+   $groups->Limit(FIELD => 'Name', OPERATOR => '=', VALUE => "$name");
+   $groups->WithMember($TransactionObj->CreatorObj->Id);
+
+   my $groupid = $groups->First->Id;
+
+   my $adminccs = RT::Users->new($RT::SystemUser);
+   $adminccs->WhoHaveRight(Right => 'AdminGroup', IncludeSystemRights => undef, IncludeSuperusers => 0, IncludeSubgroupMembers => 0, Object => $groups->First);
+
+    my @admins;
+    while (my $admin = $adminccs->Next) {
+        push (@admins, $admin->Name); 
+    }
+ }
+ Queue: Approvals
+ Type: Approval
+ AdminCcs: {join (", ",@admins) }
+ Depended-On-By: {$tickets{'TOP'}->Id}
+ Refers-To: {$tickets{'TOP'}->Id}
+ Due: {time + 86400}
+ Content-Type: text/plain
+ Content: Your approval is requested for the ticket {%$tickets{'TOP'}->Id}: {$tickets{'TOP'}->Subject}
diff --git a/rt/docs/design_docs/basic-definitions.txt b/rt/docs/design_docs/basic-definitions.txt
deleted file mode 100644 (file)
index 23d2c57..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-(todo ... basically, those are untouched from 1.0)
-Ticket
-Queue
-(...more?)
-
-Requestor
-
-  (...definition of a requestor .. blahblah)
-
-  I'm often doing a distinction between "Internal Requestors" and "External
-  Requestors" (see below).  The system doesn't make any difference between
-  requestors, but the distinction might be useful to discuss usage patterns,
-  templates and configurations.
-
-
-External Requestor
-
-  Might be a customer or a potential customer.  The External Requestor
-  should be treated as a VIP.  (S)he shouldn't need to see too much of RT.
-  The support (s)he gets should be as personal as possible.  The external
-  requestor might eventually get access to the Web UI, but only to track
-  her/his own requests.  If you're not planning to use RT for handling
-  external customers, all your requestors are probably "Internal
-  Requestors".
-
-
-Watcher
-
-  Somebody that are "subscribing" to a queue or a ticket (or something
-  differently).  Basicly, somebody watching a queue or a ticket should get
-  all updates by email.  A requestor is a (special) watcher.
-
-
-Regular Watcher
-
-  People within the same organization, people that have read access to whole
-  queues.
-
-  I consider "Regular Watchers" as well as "Internal Requestors" as more
-  robust and capable human beeings than the fragile customers.  We don't
-  mind letting them get entagled with RT, and we let them access the Web UI.
-  They can live with beeing just the Cc or Bcc at an email.
-
-
-Internal Requestor
-
-  An Internal Requestor is usually internal to the company.  He might be 1st
-  line support sending matters to tech support or similar. Might be an
-  internal employee sending matters to tech support (or even 1st line
-  support if he's not sure where to send matters).  It might also be that
-  "ordinary" requestors actually might be treated as intelligent human
-  beeings rather than VIPs, i.e. in open source projects ... we'll still
-  call them "Internal Requestors" as they don't need the special VIP
-  treatment.
diff --git a/rt/docs/design_docs/cf_search b/rt/docs/design_docs/cf_search
new file mode 100644 (file)
index 0000000..456a9fe
--- /dev/null
@@ -0,0 +1,72 @@
+find all tickets where:
+
+
+        CF Foo 
+                Has values (talk or read) AND
+                Has values (bar and baz) AND 
+                doesn't have values (bing or bong) 
+
+
+LimitCustomFieldValues {
+        my %args = ( CustomField => undef, 
+                     ClauseId => 'CustomFields',
+                     OPERATOR => undef,
+                     ENTRYAGGREGATOR => undef,
+                     VALUES => undef,
+                     @_) ;
+
+        unless ( $self->{'TicketAliases'}{$args{'ClauseId'}}{'CustomField'} ) {
+        $self->{'TicketAliases'}{$args{'ClauseId'}}{'CustomField'} = $self->NewAlias('CustomFields');
+        $self->Join(TABLE1 =>$self->{'TicketAliases'}{$args{'ClauseId'}}{'CustomField' },  
+                    FIELD1 => 'QueueId',
+                    TABLE2 => 'main', FIELD2 => 'QueueId');
+
+        if ($args{'OPERATOR'} =~ /!=|IS/i) {
+        }
+        else {
+        }
+
+}
+        # {{{ if it's a keyword
+        elsif ( $TYPES{ $restriction->{'FIELD'} } eq 'CUSTOMFIELD' ) {
+
+            my $null_columns_ok;
+            my $TicketCFs = $self->Join( TYPE   => 'left',
+                                                ALIAS1 => 'main',
+                                                FIELD1 => 'id',
+                                                TABLE2 => 'TicketCustomFieldValues',
+                                                FIELD2 => 'Ticket' );
+
+            foreach my $value ( @{ $restriction->{'VALUES'} } ) {
+                $self->SUPER::Limit( ALIAS      => $TicketCFs,
+                                     FIELD      => 'Content',
+                                     OPERATOR   => $restriction->{'OPERATOR'},
+                                     VALUE      => $value,
+                                     QUOTEVALUE => $restriction->{'QUOTEVALUE'},
+                                     ENTRYAGGREGATOR => 'AND', );
+            }
+            if (    ( $restriction->{'OPERATOR'} =~ /^IS$/i ) or ( $restriction->{'OPERATOR'} eq '!=' ) ) {
+                $null_columns_ok = 1;
+            }
+
+            #If we're trying to find tickets where the keyword isn't somethng, also check ones where it _IS_ null
+            if ( $restriction->{'OPERATOR'} eq '!=' ) {
+                $self->SUPER::Limit( ALIAS           => $TicketCFs,
+                                     FIELD           => 'Content',
+                                     OPERATOR        => 'IS',
+                                     VALUE           => 'NULL',
+                                     QUOTEVALUE      => 0,
+                                     ENTRYAGGREGATOR => 'OR', );
+            }
+
+            $self->SUPER::Limit( LEFTJOIN => $TicketCFs,
+                                 FIELD    => 'CustomField',
+                                 VALUE    => $restriction->{'CUSTOMFIELD'},
+                                 ENTRYAGGREGATOR => 'OR' );
+
+        }
+
+        # }}}
+
+    }
+
index 48a7f34..ae5f29f 100644 (file)
 
-Find tickets to operate on:
-        --id=<tickets>          Find only tickets in the range <tickets>
-                synonyms:
-                --limit-id, --tickets, --limit-tickets
-        --limit-queue=<queue>
-        --limit-status=<status>
-        --limit-owner=<owner>
-        --limit-priority=<priority>
-        --limit-requestor=<email>
-        --limit-subject=<string>      (Subject contains)
-        --limit-body=<string>         (body contains)
-        --limit-created=(before/after) <date>
-        --limit-due=(before/after) <date>
-        --limit-starts=(before/after) <date>
-        --limit-started=(before/after) <date>
+Things the cli must do
+       create ticket
+       comment
+       reply
+       update ticket metadata
+       search for tickets
+       update a bunch of tickets.
+       list tickets
+        login/logout
 
-        --limit-first=<int>           Start on the <int>th row returned by the
-                                database  
-        --limit-rows=<int>      Find only <int> rows
 
-Display:
-        --show                  shows a ticket history
-        --history               ditto
+should support multiple rt servers
 
-        --summary               default option. shows a ticket summary
-                --format        Optional format string. If not specified,
-                                uses the value of ENV{'RT_LISTING_FORMAT'}
-                                or an internal default
-        
+create/edit/update should use EDITOR or take from a file or stdin
 
-Basic ticket editing:
+should be able to update ticket sttributes from a commandline without invoking an editor or needing to use stdin.
 
-       --status=(open|stall|resolve|kill)
-       --subject=<string>
-        --owner=<owner>
-       --queue=<queue>
-       --time-left=<minutes>
+login/logout should store RT session cookies rather than constantly transmitting the username/password combo.
 
-Watcher-related editing:
+rtserver and rt username should come from env variables. but should be able to be overridden by commandline options. 
 
-       --add-requestor=<email>
-       --del-requestor=<email>
-       --add-cc=<email>
-       --del-cc=<email>
-       --add-admincc=<email>
-       --del-admincc=<email>
+rt password should be able to be specified on the commandline (say from a script) or, failing that be prompted for within the application (as rt's sbin/initdb script does) ...or maybe able to be read from a stash file on disk.
 
-Priority related editing:
+must be able to dowaload attachments from cli.
+ it might also be cool to be able to generate session-length urls for attavhments so you can use a browser. but that's not necessary.
 
-       --priority=<int>
-       --final-priority=<int>
 
-Date related editing:
-
-       --due=date
-       --starts=date
-       --started=date
-       --contacted=date
-
-
-
-Ticket updates:
-
-       --comment 
-       --reply | --respond 
-
-
-Links
-
-       --add-link 
-               --type=<DependsOn|MemberOf|RelatedTo>
-               needs one of:
-                  --target=<ticketid> 
-                  --base=<ticketid>
-
-       --del-link <link-id>
-
-
-
-Condiments:
-       any update can take:
-
-               --time-taken <minutes>
-
-       Ticket updates can take:
-
-               --source        -- specify a source file to read the content from
-               --edit          = give me an editor to edit the message
-               --no-edit       = don't give me an editor to edit the message.
-
-
-
-
------ Forwarded message from deborah kaplan <deborah@curl.com> -----
-
-Date: Fri, 14 Apr 2000 11:43:18 -0400 (EDT)
-From: deborah kaplan <deborah@curl.com>
-To: Jesse <jesse@fsck.com>
-Subject: Re: [rt-devel] RT Projects list
-
-Finally, here is the functional spec for the command line
-interface.  This is for the user interface only; if you think
-this is right, I will add the administrative interface as well.
-Should I post to rt-devel, add to the ticket, or just modify
-based on your kibbitzing?  When you are happy with it I'll start
-the code.
-
--deborah
-
-
-RT command line interface functional specification
-Author: Deborah Kaplan (Deborah@suberic.net)
-Version:0.1
-
-Requirements: 
-
-RT needs a CLI for various reasons.  If a user is restricted to a
-dumb terminal, she needs to be able to access the RT database and
-manipulate it fully.  The full functionality of both the RT
-database and the RT administrative interface should be available
-from this CLI.
-
-There are two possible types of CLI which I will discuss here.
-The first is a curses-style interface, which allows the user to
-move about a series of menus and choices, usually using arrow
-keys.  As RT supplies a Web interface, there is no need for this
-curses-style interface to be written as part of RT.  Instead, the
-RT developers should pick one tty-based Web browser (e.g. lynx,
-w3m) and make sure that all of the RT pages are easily readable
-with that tty based browser.  Installation of that browser should
-be recommended in the RT installation documentation as a
-supported method of accessing RT from a tty.
-
-The second possible type of CLI is more minimal: a series of
-commands which can be run at a UNIX command prompt which provide
-full functionality to the RT database and administrative
-interface.  There are two major benefits to this second type of
-CLI.  First of all, in order to use this CLI, you need no extra
-tools (Web browsers, etc.).  All that is required is a UNIX
-command line prompt and an installation of RT.  Secondly, a user
-of RT who has a very specific command to run and who knows the
-appropriate CLI commands can accomplish her task much more
-quickly with a single command then she could navigating through a
-menu based interface.
-
-In the specification, I will describe the second type of CLI.
-
-Caveats:
-
-This specification draws heavily on the structure of formatting
-command line options for cvs.  RT faces a smaller version of the
-same kinds of problems cvs faces: we want to create a very rich
-command set without sacrificing ease-of-use. 
-
-I am not wedded to any specific command names if they seem
-impractical; I merely am proposing the command names that seem
-reasonable to me at this moment.
-
-Finally, I am finding the functioning of the web UI from RT 1.
-If the functionality differs greatly in RT 2, I will need to
-modify this specification.
-
-Specification:
-
-There are two commands: "rt", which is the primary interface to
-the database, and "rtadmin", which is the administrative
-interface to the database.
-
-The format of an rt command is as follows:
-
- rt <command> 
-    <command> is one of:
-
-    - help
-      print an overview of the commands which can be run
-
-    - print <queue> <options> 
-      with no options, dump to the screen a list of all open
-      requests in <queue> -- the equivalent of "Display Queue" in
-      the existing Web interface.
-
-      <queue> is the name of an RT queue
-      <option> is either:
-
-        -f <filename> |  --filename <filename>
-          where <filename> is the name of a file (defaulting to
-          ~/.rtrc) in which the options described below can be
-          placed in the format "^ <long option name> <option value>
-          $".
-
-        Or a series of the following options:
-
-        -o <owner name> |  --owner <owner name>: restrict tickets
-       viewed to those owned by <owner name>.
-          This option can be used multiple times in one call of
-          the rt command in order to produce a list which
-          contains tickets owned by multiple owners.  Giving the
-          empty string ("") as an option to this switch will
-          restrict tickets viewed to those which have no owner.
-          If this switch is given with no argument, the option
-          defaults to the user name of the currently running
-          process.
-
-        -r <requestor name> | --requestor <requestor name>:
-       restrict tickets viewed to those requested by <requestor
-       name>.
-          This option can be used multiple times in one call of
-          the rt command in order to produce a list which
-          contains tickets requested by multiple requesters.  If
-          this switch is given with no arguments, it produces an
-          error.
-
-        -s <status> | --status <status>: restrict tickets viewed
-       to those with the status named in <status>.
-          This option can be used multiple times in one call of
-          the rt command in order to produce a list which
-          contains tickets with multiple statuses (statii?
-          Dragon NaturallySpeaking recognizes "statuses" as a
-          word).  This option defaults to status "open".
-
-        -j <subject> | --subject <subject>: restrict tickets
-       viewed to those which contain <subject> as a substring in
-       the subject field of the ticket.
-          This command can be used multiple times in one call of
-          the rt command in order to produce a list which
-          contains tickets with various subject substrings.  If
-          the option is called with no argument, the result is
-          an error.
-
-        -h | --help: print a usage message.
-
-        -n | --number: print out a specific ticket.
-          This command can be used multiple times to produce a
-          list which contains multiple tickets.  If the option
-          is called with no argument, the result is an error.
-
-    This completes all of the print options which are available
-    in the Web interface, except the sort options.  I maintain
-    that this command is already excessively complex, and that
-    adding functionality which can be replicated easily by
-    standard UNIX tools is unnecessary added complexity.  I
-    recommend that the man pages and documentation for this
-    option contain an example of a command line run (e.g. of rt |
-    awk) which replicates the sorting functionality provided by
-    the Web interface.
-
-    - edit <ticket> <options>
-      with no options, or with no <ticket>, produces the same
-      output as the --help option.
-      Otherwise, edits the ticket with number <ticket> as
-      indicated in the options given.  All options listed below
-      except for --help and --number can be used in conjunction
-      with one another to change many features of the same ticket
-      all at once.
-
-        -h | --help: print usage message
-
-        -s <status> | --status <status>: change the status to the
-       status listed in <status>.
-          No <status> listed, or 1 listed it does not come from
-          a list of approve statuses, produces an error.
-
-        -o <owner name> |  --owner <owner name>: set to the owner
-       of the ticket the owner named.
-          Follows whatever convention is finally decided on for
-          the requirement to steal a ticket that is owned by
-          somebody else.  No <owner named> listed has the user
-          who is running the rt program take the ticket.  If
-          that user is not a valid owner, or the 1 listed does
-          not come from a list of approve names, produces an
-          error.
-
-        -r <requestor name> | --requestor <requestor name>: sets
-       the requestor to <requestor name>.
-          Follows any conventions that the Web UI follows to
-          make sure that this is a legal name.  If not legal, or
-          left blank, produces an error.
-
-        -j <subject> | --subject <subject>:  sets the subject of
-       the ticket to <subject>.
-          If the option is called with no argument, the result
-          is an error.
-
-        -n <number one> <number 2> | --number <number one>
-       <number 2>: merges ticket number <number one> into ticket
-       <number 2>.
-          If both arguments are not provided, the result is an
-          error.
-
-        -q <queue> | --queue <queue>: set the queue to that
-       named.
-          If <queue> is not listed, or the 1 listed does not
-          come from a list of approve queues, produces an
-          error.
-
-        -a <area> | --area <area>: set the area of the ticket to
-       that named.
-          If <area> is not listed, or the 1 listed does not come
-          from a list of approve areas, produces an error.
-
-        -c <time stamp> | --contact <time stamp>: sets the last
-       user contact field, and produces an error if the format
-       is invalid.
-          If the argument is left blank, sets the last user
-          contact field to now.
-
-        -p <priority> | --priority <priority>: sets the current
-       priority to the 1 listed.
-          Produces an error if the argument is left blank.
-
-        -f <priority> | --final <priority>: sets the final
-       priority to the 1 listed.
-          Produces an error if the arguments left blank.
-
-        -d <date due> | --datedue <date due>: sets the due date
-       to the 1 listed.
-          Produces an error if the argument is left blank, or if
-          the format is invalid.
-
-    - comment <options>
-      with no options, this command reads from standard input
-      until it sees EOF and appends that to the ticket as a
-      comment.
-
-        -h | --help: print usage message
-
-        -c | --comment: append as a comment.  This is the default behavior.
-
-        -r | --reply: append as a reply.
-
-        -f <filename> | --file <filename>: can be used with
-       either the comment or reply options.  Instead of reading
-       from standard input, read the text of the comment or
-       reply from the file <filename>.
-
-    - report <options>
-      this command is a place holder for reporting functionality
-      which does not yet exist.  It will probably have the
-      default behavior to select reports at the command line or
-      choose default reports from a .rtrc file.  In a future
-      version, it can output graphs in some graphical format.
-
-
-
------ End forwarded message -----
-
--- 
-jesse reed vincent -- root@eruditorum.org -- jesse@fsck.com 
-70EBAC90: 2A07 FC22 7DB4 42C1 9D71 0108 41A3 3FB3 70EB AC90
-
-"If IBM _wanted_ to make clones, we could make them cheaper and faster than
-anyone else!"  - An IBM Rep. visiting Vassar College's Comp Sci Department.
+I'm envisioning this as similar to the subversion cli, actually. 
 
diff --git a/rt/docs/design_docs/delegation b/rt/docs/design_docs/delegation
new file mode 100644 (file)
index 0000000..0e57059
--- /dev/null
@@ -0,0 +1,115 @@
+Group ACLs
+        
+        the rights:
+
+
+        CreatePersonalGroup
+        CreateGroup
+
+        AdminGroup
+                * Update group metadata and access control list
+        AdminGroupMembers
+                * Add ad delete members of this group
+        ModifyOwnMembership
+                * Join and quit this group
+
+
+        the primitives:
+       
+In user.pm
+
+=item HasRight  { Right => 'somerightname', ObjectType => 'Group', ObjectId => 'GroupId'
+
+        Returns true if this user has the right 'somerightname' for
+the group with id 'Id'
+
+=cut
+
+
+=item RightsForObject { ObjectType => 'Group', ObjectId =>'GroupId' }
+
+in users.pm
+
+=item WhoHaveRight { Right =>'somerightname', ObjectType => 'Group', ObjectId => 'GroupId' }
+
+
+        Finds all users who have the right 'somerightname' for the group
+in question.
+
+        If a user has "AdminGroupMembers" globally and we ask about 
+        group 23, that user should be found.
+
+=cut
+
+Users must be able to delegate individual rights 
+
+        * Is it that users can delegate any and all rights but it's
+        only rights they _have_ which actually grant rights.
+
+rights must not be redelegated
+
+users must be able to create groups to which rights can be delegated.
+
+Only users who have the "delegate rights" right can delegate rights.
+
+
+When a user's right to do something is revoked, the delegation must 
+be revoked
+
+        * For any delegated ACL check, the delegator's right must be 
+          checked immediately after the delegatee's right.
+          If a user has had a right delegated by multiple parties, 
+          this may mean that we need to actually loop through and check
+          a bunch of possible delegations. Or can we craft a "has delegated 
+          right" ACL check.
+          
+
+
+
+
+
+
+ACL 1 Group Q has the right to Frob ObjectI.
+ACL 2 User A has the right "DelegateRights"
+
+Group Q has the member Group S
+Group S has the member Group R
+Group S has the member Group T
+Group R has the member user A
+Group T has the member user A
+
+User A delegates to  Group P the right to Frob  ObjectI
+
+        New ACL rule:
+
+        ACL 3: Group P has the right to Frob ObjectI 
+                     as delegated from ACL1 by User A
+
+
+In the case where ACL1 is revoked:
+
+        find all acls which are delegated from ACL1.
+                Delete them
+
+In the case where User A is removed from group R
+
+        Get the list of all groups that A was in by way of group R before the removal
+        Get the list of all groups that A is in _after_ the removal.
+
+        Find all the ACEs granted to each group that A is no longer in.
+        For each ACE in that list, find all the rights that A has delegated.
+                Whack them.        
+
+In the case where Group S is removed from group Q
+
+
+        Get a list of all groups that S was in by way of Q before the removal
+        Call this list O.
+
+        For each user X who's a member of S (directly or indirectly):
+        Get a list of  all groups that X is in after removal.
+        For each group in O that X is no longer a member of:
+                Find all ACEs granted to O
+                For each ACE, look up all the delegations that X has made.
+                        For each delegation 
+                                WHACK IT
index 34b9f81..5b5cc58 100644 (file)
@@ -3,8 +3,7 @@ Current planned 2.2 feature list. subject to change.
 
 Core
 
-Should Make "Owner" a watcher type, rather than a special ticket attribute,
-       under the hood.  This wins for ACL and code consistency reasons.
+
 
 Web UI
 
@@ -67,8 +66,6 @@ nice  Scrips could apply to a list of queues, rather than just one queue or
 
 Custom fields
 
-Must   "KeywordSelects" become "Custom Fields"
-Should String and multi-string custom fields.
 Nice   Date custom fields
 Nice   Some way to order and group custom fields.
 Nice   Default values
@@ -79,8 +76,6 @@ Nice  Make custom fields apply to an enumerated list of queues,
 
 Web infrastructure
 
-Must   Full fastcgi support.
-
 
 Installation 
 
@@ -116,7 +111,7 @@ Nice        Export full ticket metadata and history as XML
 Note:  I currently favor the REST philosophy that GET and POST to specific,
        defined URLs provides everything one needs to build comprehensive
        web services without the massive added complexity of a SOAP or XML-RPC
-       framework.
+       framework. Sadly, the world doesn't agree with me
 
 
 ACLs:
diff --git a/rt/docs/design_docs/groups_notes b/rt/docs/design_docs/groups_notes
new file mode 100644 (file)
index 0000000..234fd37
--- /dev/null
@@ -0,0 +1,88 @@
+CREATE TABLE Prinicpals (
+        id int auto_increment 
+        PrincipalType VARCHAR(16) not_null,
+        PrincipalId int # foreign key to Users or Groups, depending
+)
+
+CREATE TABLE Groups (
+        id int auto_increment,
+        Domain varchar(255), 
+        Instance varchar(16),
+        Name varchar(255),
+        Description varchar(255),
+);
+CREATE TABLE ACL (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Principal integer NULL  , #Foreign key to principals
+  RightName varchar(25) NULL  ,
+  RightDomain varchar(25) NULL  ,
+  RightInstance integer NULL  ,
+  PRIMARY KEY (id)
+);      
+
+CREATE TABLE GroupMembers (
+        id int auto_increment,
+        Group int, # foreign key to Principals
+        Member int # foreign key to Principals
+)
+
+create table GroupMembersCache (
+        id int auto_increment,
+        Group int, # foreign key to Principals
+        Member int, # foreign key to Principals
+        Via int, #foreign key to g_m_u
+)
+
+insert into principals values ('bubbles);
+insert into principals values ('fubar');
+insert into principals values ('sheeri');
+insert into principals values ('sgw');
+
+insert into principals values ('staff');
+insert into principals values ('sysadmin');
+insert into principals values ('senior admin');
+
+
+insert into group_members values(1, 'staff', 'bubbles');
+insert into group_members values(2, 'sysadmin', 'sheeri');
+insert into group_members values(3,'senior admin', 'sgw');
+insert into group_members values(4,'senior admin', 'fubar');
+insert into group_members values(5, 'sysadmin', 'senior admin')
+        
+Groups
+
+
+      
+Domain          Queues
+Instance        <queueid#>
+Name            AdminCc, Cc
+
+/Queues/1/AdminCc
+/Queues/3/Cc
+
+Domain          Tickets
+Instance        <#n>
+Name            Owner, Requestor, Cc, AdminCc
+
+/Tickets/1/Owner
+/Tickets/1/Requestor
+/Tickets/1/Cc
+       Has members: /Queues/whatever queue the ticket has/Cc 
+/Tickets/1/AdminCc
+       Has members: /Queues/whatever queue the ticket has/AdminCc 
+
+
+Domain          Users
+Instance        <userid>
+
+/Users/1/MyDelegates
+/Users/1/MyOtherDelegates
+
+
+Domain          System
+Name            Admins, AdminManagers
+
+/System/Administrators
+/System/Blah
+
+
diff --git a/rt/docs/design_docs/local_hacking b/rt/docs/design_docs/local_hacking
deleted file mode 100644 (file)
index c06d112..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-To facilitate local hacking, RT needs a mechanism to allow site administrators
-to easily add HTML templates for the web ui and to replace sections
-of code in RT's core modules _without_ having to modify those modules
-
-We'll use several methods to achieve this goal.
-
-       Webui
-               HTML::Mason allows users to create multiple
-component hierarchies.  RT should ship with a local component root
-defined and available. This root should be configured as the "primary"
-component root.
-
-
-       Core modules
-
-       This gets a bit trickier. we want to allow people to trivially
-subclass core modules and to use those subclasses throughout the code.
-
-The way we're going to handle this is by setting up a number of subroutines
-in config.pm that look something like this:
-
-sub NewTicketObj {
-       eval "require $TicketClass";
-       my $object = new $TicketClass;
-       return ($object);
-}
-
-# This variable is used for ref type checking
-$TicketClass = "RT::Ticket";
-
-we could use an eval around the require and thus completely avoid specifying
-the object in two places. which feels like a win. but i'm worried about perf.
diff --git a/rt/docs/design_docs/recursive_group_membership_algorithm b/rt/docs/design_docs/recursive_group_membership_algorithm
new file mode 100644 (file)
index 0000000..250b9ad
--- /dev/null
@@ -0,0 +1,109 @@
+Group A has members 1, 2, 3
+
+       Cached members  1 is a member of A via ""
+                       2 is a member of A via ""
+                       3 is a member of A via ""
+
+
+Group B has members A, 4, 5
+
+       Cached members: 4 is a member of B via ""  $1
+                       5 is a member of B via ""  $2
+                       A is a member of B via ""  $3
+                               1 is a member of B via "$3" $4
+                               2 is a member of B via "$3" $5
+                               3 is a member of B via "$3" $6
+
+Group C has members A, B, 6
+                       6 is a member of C via "" $7
+                       A is a member of C via "" $8
+                               1 is a member of C via $8 $9
+                               2 is a member of C via $8 $10
+                               3 is a member of C via $8 $11
+                       B is a member of C via "" $12
+                               4 is a member of C via $12 $13
+                               5 is a member of C via $12 $14
+                               A is a member of C via $12 $15
+                                       1 is a member of C via $15 $16
+                                       2 is a member of C via $15 $17
+                                       3 is a member of C via $15 $18
+
+
+
+Group D has members A, C
+
+                       A is a member of D via "" $19
+                               1 is a member of D via $19 $20
+                               2 is a member of D via $19 $21
+                               3 is a member of D via $19 $22
+                       C is a member of D via "" $23
+                               6 is a member of D via $23 $24
+                               A is a member of D via $23 $25
+                                       1 is a member of D via $25 $26
+                                       2 is a member of D via $25 $27
+                                       3 is a member of D via $25 $28
+                               B is a member of D via $23 $29
+                                       4 is a member of D via $29 $30
+                                       5 is a member of D via $29 $31
+                                       A is a member of D via $29 $32
+                                               1 is a member of D via $32 $33
+                                               2 is a member of D via $32 $34
+                                               3 is a member of D via $32 $35
+
+                       
+
+Adding a new user, 7,  to group A.
+
+
+       Add the user to group A in the groups table.
+
+       Find all entries for group A in the cache table.
+
+       For each entry in that list:
+               Add "7 is a member of $entry->top  via $entry->id"
+
+Deleting a user, 7, from group A:
+
+       Remove the user from group A in the groups table.
+       find all entries in the cache table where the principal id is user 7 and
+       the parent id is A. (requires a self join)
+               nuke them
+
+       Alternatively:
+        find all entries for A in the cache table.
+               For each one, find the child whose id is 7. 
+                       Nuke it
+
+
+Adding a group, B to group D.
+
+       Add group B as a member of D in the groups table.
+       In the cache table:
+               $id = Add group B as a member of D via ""
+                
+                For each member of group B (4, 5, A):
+
+                       $sid= 4 is a member of D via $id
+                       $sid=  5 is a member of D via $id
+                       $sid=  A is a member of D via $id
+
+                        if the member is a group itself, recurse down:
+                                
+                                1 is a member of D via $sid
+                                2 is a member of D via $sid
+                                3 is a member of D via $sid
+                               
+                Find all places where D is a member of $foo.
+                        Repeat the above procedure, substituting $foo for D
+                        and making $id D's id.
+
+Removing B as a member of D:
+
+        Remove B as a member of D in the groups table.
+        Find all references to D in the pseudogroups table.
+                Find all children of D which are B:
+                        Recurse down with the following algorithm:
+                        If it's a user, delete it.
+                        If it's a group,  recurse through each member, 
+                                deleting its children and then deleting the
+                                group itself.
diff --git a/rt/docs/design_docs/rql_parser_machine.graphviz b/rt/docs/design_docs/rql_parser_machine.graphviz
new file mode 100644 (file)
index 0000000..36463ec
--- /dev/null
@@ -0,0 +1,32 @@
+
+/* GraphViz graph representing the state diagram of the RQL parser.
+*/
+
+digraph G {
+
+    PAREN -> PAREN;
+    PAREN -> KEYWORD;
+    PAREN -> AGGREG;
+
+    AGGREG -> KEYWORD;
+    AGGREG -> PAREN;
+
+    KEYWORD -> OP;
+
+    OP -> VALUE;
+
+    VALUE -> PAREN;
+    VALUE -> AGGREG;
+
+/*
+    Blue lines represent added complexity of q[IN (x,y,z)] support.
+    The only place that the "blue tree" can be entered is at IN, and
+    exited at PAREN.
+*/
+    KEYWORD -> IN [color=blue];
+    IN -> PAREN [color=blue];
+    PAREN -> VALUE [color=blue];
+    VALUE -> COMMA [color=blue];
+    COMMA -> VALUE [color=blue]; 
+    VALUE -> PAREN [color=blue];
+}
diff --git a/rt/docs/design_docs/string-extraction-guide.txt b/rt/docs/design_docs/string-extraction-guide.txt
new file mode 100644 (file)
index 0000000..bd60a43
--- /dev/null
@@ -0,0 +1,100 @@
+# $File: //depot/RT/rt-devel/docs/design_docs/string-extraction-guide.txt $ $Author: ivan $
+# $Revision: 1.1 $ $Change: 1431 $ $DateTime: 2002/10/15 17:24:45 $
+
+Run 'p4 edit lib/RT/I18N/zh_tw.pm' and 'perl l10n.pl' to add new
+extractions to the zh_tw.pm.
+
+Edit lib/RT/I18N/zh_tw.pm for chinese counterparts.
+
+Attached is a copy of the freshly rewritten string extraction style guide.
+Please point out anything that's unclear or underspecified.   I
+localized a number of the core modules in RT 2.1.3 (Starting with 
+Queue_Overlay.pm). I only touched a couple of the web templates in the 
+Elements/ directory of the web ui.
+
+RT String extraction styleguide:
+
+Web templates:
+
+Templates should use the /l filtering component to call the localisation
+framework
+
+The string             Foo!
+
+Should become          <&|/l&>Foo!</&>
+
+All newlines should be removed from localized strings, to make it easy to 
+grep the codebase for strings to be localized
+
+The string             Foo
+                       Bar
+                       Baz
+                       
+Should become          <&|/l&>Foo Bar Baz</&>
+
+
+Variable subsititutions should be moved to Locale::MakeText format
+
+The string             Hello, <%$name %>
+
+should become          <&|/l, $name &>Hello, [_1]</&>  
+
+
+Multiple variables work just like single variables
+The string             You found <%$num%> tickets in queue <%$queue%>
+
+should become          <&|/l, $num, $queue &>You found [_1] tickets in queue [_2]</&>
+
+When subcomponents are called in the middle of a phrase, they need to be escaped
+too:
+
+The string              <input type="submit" value="New ticket in">&nbsp<& /Elements/SelectNewTicketQueue&>
+
+should become          <&|/l, $m->scomp('/Elements/SelectNewTicketQueue')&><input type="submit" value="New ticket in">&nbsp;[_1]</&>
+
+
+
+There are places inside the web ui where strings are defined, which need to be
+localised. it is important to note here that each localized string is split out
+onto its own line, but never split across two lines and two localized strings
+are never included on the same line. It is also important to note
+that this will genereate code which will not work in RT 2.1.3. I need
+to add a bit of framework to make it work in 2.1.4
+
+
+The string     <& /Elements/TitleBoxStart, width=> "40%", titleright => "RT $RT::VERSION for   $RT::rtname", title => 'Login' &>
+
+should become  <& /Elements/TitleBoxStart, 
+                       width=> "40%",
+                       titleright => loc("RT [_1] for [_2]",$RT::VERSION, $RT::rtname),
+                       title => loc('Login'),
+               &>
+       
+
+                       
+
+
+
+Within RT's core code, every module has a localization handle available through the 'loc' method:
+
+The code       return ( $id, "Queue created" );
+
+should become  return ( $id, $self->loc("Queue created") );    
+
+When returning or localizing a single string, the "extra" set of parenthesis () should be omitted.
+
+The code       return ("Subject changed to ". $self->Data );
+
+should become   return $self->loc( "Subject changed to [_1]", $self->Data );
+
+
+It is important not to localize  the names of rights or statuses within RT's core, as there is logic that depends on them as string identifiers.  The proper place to localize these values is when they're presented for display in the web or commandline interfaces.
+
+
+
+
+
+-- 
+http://www.bestpractical.com/products/rt  -- Trouble Ticketing. Free.
+
diff --git a/rt/docs/design_docs/ticket_templates b/rt/docs/design_docs/ticket_templates
new file mode 100644 (file)
index 0000000..7850edf
--- /dev/null
@@ -0,0 +1,16 @@
+===Create-Ticket: foo
+ Subject: APPROVE <%TOP-Subject%>
+ Status: status
+ Queue: <%TOP-Queue%>
+ Owner: <%TOP-Owner%>
+ Depends-on: <%TOP-Id%>
+ Child-of: <%TOP-Id%>
+ Refers-to: <%TOP-Id%>
+ Content-Type: text/plain
+ Content: This is content
+blah
+blah
+blah
+===Create-Ticket: bar
+Subject:  <%foo-Subject%>
+
diff --git a/rt/docs/rt.gif b/rt/docs/rt.gif
deleted file mode 100755 (executable)
index 693b062..0000000
Binary files a/rt/docs/rt.gif and /dev/null differ
diff --git a/rt/etc/RT_Config.pm b/rt/etc/RT_Config.pm
new file mode 100644 (file)
index 0000000..2b3f4f9
--- /dev/null
@@ -0,0 +1,349 @@
+#
+# WARNING: NEVER EDIT RT_Config.pm. Instead, copy any sections you want to change to RT_SiteConfig.pm
+# and edit them there.
+#
+
+package RT;
+
+=head1 NAME
+
+RT::Config
+
+=for testing
+
+use RT::Config;
+
+=cut
+
+# {{{ Base Configuration
+
+# $rtname the string that RT will look for in mail messages to
+# figure out what ticket a new piece of mail belongs to
+
+# Your domain name is recommended, so as not to pollute the namespace.
+# once you start using a given tag, you should probably never change it.
+# (otherwise, mail for existing tickets won't get put in the right place
+
+Set($rtname , "example.com");
+
+# You should set this to your organization's DNS domain. For example,
+# fsck.com or asylum.arkham.ma.us. It's used by the linking interface to
+# guarantee that ticket URIs are unique and easy to construct.
+
+Set($Organization , "example.com");
+
+# $user_passwd_min defines the minimum length for user passwords. Setting
+# it to 0 disables this check
+Set($MinimumPasswordLength , "5");
+
+# $Timezone is used to convert times entered by users into GMT and back again
+# It should be set to a timezone recognized by your local unix box.
+Set($Timezone , 'US/Eastern');
+
+# }}}
+
+# }}}
+
+# {{{ Database Configuration
+
+# Database driver beeing used. Case matters
+# Valid types are "mysql" and "Pg"
+
+Set($DatabaseType , 'mysql');
+
+# The domain name of your database server
+# If you're running mysql and it's on localhost,
+# leave it blank for enhanced performance
+Set($DatabaseHost   , 'localhost');
+Set($DatabaseRTHost , 'localhost');
+
+# The port that your database server is running on.  Ignored unless it's
+# a positive integer. It's usually safe to leave this blank
+Set($DatabasePort , '');
+
+#The name of the database user (inside the database)
+Set($DatabaseUser , 'rt_user');
+
+# Password the DatabaseUser should use to access the database
+Set($DatabasePassword , 'rt_pass');
+
+# The name of the RT's database on your database server
+Set($DatabaseName , 'rt3');
+
+# If you're using Postgres and have compiled in SSL support,
+# set DatabaseRequireSSL to 1 to turn on SSL communication
+Set($DatabaseRequireSSL , undef);
+
+# }}}
+
+# {{{ Incoming mail gateway configuration
+
+# OwnerEmail is the address of a human who manages RT. RT will send
+# errors generated by the mail gateway to this address.  This address
+# should _not_ be an address that's managed by your RT instance.
+
+Set($OwnerEmail , 'root');
+
+# If $LoopsToRTOwner is defined, RT will send mail that it believes
+# might be a loop to $RT::OwnerEmail
+
+Set($LoopsToRTOwner , 1);
+
+# If $StoreLoopss is defined, RT will record messages that it believes
+# to be part of mail loops.
+# As it does this, it will try to be careful not to send mail to the
+# sender of these messages
+
+Set($StoreLoops , undef);
+
+# $MaxAttachmentSize sets the maximum size (in bytes) of attachments stored
+# in the database.
+
+# For mysql and oracle, we set this size at 10 megabytes.
+# If you're running a postgres version earlier than 7.1, you will need
+# to drop this to 8192. (8k)
+
+Set($MaxAttachmentSize , 10000000);
+
+# $TruncateLongAttachments: if this is set to a non-undef value,
+# RT will truncate attachments longer than MaxAttachmentLength.
+
+Set($TruncateLongAttachments , undef);
+
+# $DropLongAttachments: if this is set to a non-undef value,
+# RT will silently drop attachments longer than MaxAttachmentLength.
+
+Set($DropLongAttachments , undef);
+
+# If $ParseNewMessageForTicketCcs is true, RT will attempt to divine
+# Ticket 'Cc' watchers from the To and Cc lines of incoming messages
+# Be forewarned that if you have _any_ addresses which forward mail to
+# RT automatically and you enable this option without modifying
+# "RTAddressRegexp" below, you will get yourself into a heap of trouble.
+
+Set($ParseNewMessageForTicketCcs , undef);
+
+# RTAddressRegexp is used to make sure RT doesn't add itself as a ticket CC if
+# the setting above is enabled.
+
+Set($RTAddressRegexp , '^rt\@example.com$');
+
+# RT provides functionality which allows the system to rewrite
+# incoming email addresses.  In its simplest form,
+# you can substitute the value in CanonicalizeEmailAddressReplace
+# for the value in CanonicalizeEmailAddressMatch
+# (These values are passed to the CanonicalizeEmailAddress subroutine in RT/User.pm)
+# By default, that routine performs a s/$Match/$Replace/gi on any address passed to it
+
+Set($CanonicalizeEmailAddressMatch   , 'subdomain.example.com$');
+Set($CanonicalizeEmailAddressReplace , 'example.com');
+
+# If $SenderMustExistInExternalDatabase is true, RT will refuse to
+# create non-privileged accounts for unknown users if you are using
+# the "LookupSenderInExternalDatabase" option.
+# Instead, an error message will be mailed and RT will forward the
+# message to $RTOwner.
+#
+# If you are not using $LookupSenderInExternalDatabase, this option
+# has no effect.
+#
+# If you define an AutoRejectRequest template, RT will use this
+# template for the rejection message.
+
+Set($SenderMustExistInExternalDatabase , undef);
+
+# }}}
+
+# {{{ Outgoing mail configuration
+
+# RT is designed such that any mail which already has a ticket-id associated
+# with it will get to the right place automatically.
+
+# $CorrespondAddress and $CommentAddress are the default addresses
+# that will be listed in From: and Reply-To: headers of correspondence
+# and comment mail tracked by RT, unless overridden by a queue-specific
+# address.
+
+Set($CorrespondAddress , 'RT::CorrespondAddress.not.set');
+
+Set($CommentAddress , 'RT::CommentAddress.not.set');
+
+#Sendmail Configuration
+
+# $MailCommand defines which method RT will use to try to send mail
+# We know that 'sendmailpipe' works fairly well.
+# If 'sendmailpipe' doesn't work well for you, try 'sendmail'
+#
+# Note that you should remove the '-t' from $SendmailArguments
+# if you use 'sendmail rather than 'sendmailpipe'
+
+Set($MailCommand , 'sendmailpipe');
+
+# $SendmailArguments defines what flags to pass to $Sendmail
+# assuming you picked 'sendmail' or 'sendmailpipe' as the $MailCommand above.
+# If you picked 'sendmailpipe', you MUST add a -t flag to $SendmailArguments
+
+# These options are good for most sendmail wrappers and workalikes
+Set($SendmailArguments , "-oi -t");
+
+# These arguments are good for sendmail brand sendmail 8 and newer
+#Set($SendmailArguments,"-oi -t -ODeliveryMode=b -OErrorMode=m");
+
+# If you selected 'sendmailpipe' above, you MUST specify the path
+# to your sendmail binary in $SendmailPath.
+# !! If you did not # select 'sendmailpipe' above, this has no effect!!
+Set($SendmailPath , "/usr/sbin/sendmail");
+
+# By default, RT sets the outgoing mail's "From:" header to
+# "SenderName via RT".  Setting this option to 0 disables it.
+
+Set($UseFriendlyFromLine , 1);
+
+# sprintf() format of the friendly 'From:' header; its arguments
+# are SenderName and SenderEmailAddress.
+Set($FriendlyFromLineFormat , "\"%s via RT\" <%s>");
+
+# RT can optionally set a "Friendly" 'To:' header when sending messages to
+# Ccs or AdminCcs (rather than having a blank 'To:' header.
+
+# This feature DOES NOT WORK WITH SENDMAIL[tm] BRAND SENDMAIL
+# If you are using sendmail, rather than postfix, qmail, exim or some other MTA,
+# you _must_ disable this option.
+
+Set($UseFriendlyToLine , 0);
+
+# sprintf() format of the friendly 'From:' header; its arguments
+# are WatcherType and TicketId.
+Set($FriendlyToLineFormat, "\"%s of $RT::rtname Ticket #%s\":;");
+
+# By default RT doesn't notify the person who performs an update, as they
+# already know what they've done. If you'd like to change this behaviour,
+# Set $NotifyActor to 1
+
+Set($NotifyActor, 0);
+
+
+# }}}
+
+# {{{ Logging
+
+# Logging.  The default is to log anything except debugging
+# information to syslog.  Check the Log::Dispatch POD for
+# information about how to get things by syslog, mail or anything
+# else, get debugging info in the log, etc.
+
+#  It might generally make
+# sense to send error and higher by email to some administrator.
+# If you do this, be careful that this email isn't sent to this RT instance.
+
+# the minimum level error that will be logged to the specific device.
+# levels from lowest to highest:
+#  debug info notice warning error critical alert emergency
+
+#  Mail loops will generate a critical log message.
+Set($LogToSyslog    , 'debug');
+Set($LogToScreen    , 'error');
+Set($LogToFile      , undef);
+Set($LogDir, '/opt/rt3/var/log');
+Set($LogToFileNamed , "rt.log");    #log to rt.log
+
+# }}}
+
+# {{{ Web interface configuration
+
+# Define the directory name to be used for images in rt web
+# documents.
+
+# If you're putting the web ui somewhere other than at the root of
+# your server
+# $WebPath requires a leading / but no trailing /
+
+Set($WebPath , "");
+
+# This is the Scheme, server and port for constructing urls to webrt
+# $WebBaseURL doesn't need a trailing /
+
+Set($WebBaseURL , "http://RT::WebBaseURL.not.configured:80");
+
+Set($WebURL , $WebBaseURL . $WebPath . "/");
+
+# $WebImagesURL points to the base URL where RT can find its images.
+# If you're running the FastCGI version of the RT web interface,
+# you should make RT's WebRT/html/NoAuth/images directory available on
+# a static web server and supply that URL as $WebImagesURL.
+
+Set($WebImagesURL , $WebURL . "NoAuth/images/");
+
+# $RTLogoURL points to the URL of the RT logo displayed in the web UI
+
+Set($LogoURL , $WebImagesURL . "rt.jpg");
+
+# if TrustHTMLAttachments is not defined, we will display them
+# as text. This prevents malicious HTML and javascript from being
+# sent in a request (although there is probably more to it than that)
+Set($TrustHTMLAttachments , undef);
+
+# If $WebExternalAuth is defined, RT will defer to the environment's
+# REMOTE_USER variable.
+
+Set($WebExternalAuth , undef);
+
+# If $WebFallbackToInternalAuth is undefined, the user is allowed a chance
+# of fallback to the login screen, even if REMOTE_USER failed.
+
+Set($WebFallbackToInternalAuth , undef);
+
+# $WebExternalGecos means to match 'gecos' field as the user identity);
+# useful with mod_auth_pwcheck and IIS Integrated Windows logon.
+
+Set($WebExternalGecos , undef);
+
+# $WebExternalAuto will create users under the same name as REMOTE_USER
+# upon login, if it's missing in the Users table.
+
+Set($WebExternalAuto , undef);
+
+# $WebSessionClass is the class you wish to use for managing Sessions.
+# It defaults to use your SQL database, but if you are using MySQL 3.x and
+# plans to use non-ascii Queue names, uncomment and add this line to
+# RT_SiteConfig.pm will prevent session corruption.
+
+# Set($WebSessionClass , 'Apache::Session::File');
+
+# }}}
+
+# {{{ RT UTF-8 Settings
+
+# An array that contains languages supported by RT's internationalization
+# interface.  Defaults to all *.po lexicons; set it to qw(en ja) will make
+# RT bilingual instead of multilingual, but will save same memory.
+
+@LexiconLanguages = qw(*) unless (@LexiconLanguages);
+
+# An array that contains default encodings used to guess which charset
+# an attachment uses if not specified.  Must be recognized by
+# Encode::Guess.
+
+@EmailInputEncodings = qw(utf-8 iso-8859-1 us-ascii) unless (@EmailInputEncodings);
+
+# The charset for localized email.  Must be recognized by Encode.
+
+Set($EmailOutputEncoding , 'utf-8');
+
+# }}}
+
+# {{{ RT Date Handling Options (for Time::ParseDate)
+
+# Set this to 1 if your local date convention looks like "dd/mm/yy"
+# instead of "mm/dd/yy".
+
+Set($DateDayBeforeMonth , 1);
+
+# Should "Tuesday" default to meaning "Next Tuesday" or "Last Tuesday"?
+# Set to 0 for "Next" or 1 for "Last".
+
+Set($AmbiguousDayInPast , 1);
+
+# }}}
+
+1;
diff --git a/rt/etc/RT_Config.pm.in b/rt/etc/RT_Config.pm.in
new file mode 100644 (file)
index 0000000..5f97eb0
--- /dev/null
@@ -0,0 +1,349 @@
+#
+# WARNING: NEVER EDIT RT_Config.pm. Instead, copy any sections you want to change to RT_SiteConfig.pm
+# and edit them there.
+#
+
+package RT;
+
+=head1 NAME
+
+RT::Config
+
+=for testing
+
+use RT::Config;
+
+=cut
+
+# {{{ Base Configuration
+
+# $rtname the string that RT will look for in mail messages to
+# figure out what ticket a new piece of mail belongs to
+
+# Your domain name is recommended, so as not to pollute the namespace.
+# once you start using a given tag, you should probably never change it.
+# (otherwise, mail for existing tickets won't get put in the right place
+
+Set($rtname , "example.com");
+
+# You should set this to your organization's DNS domain. For example,
+# fsck.com or asylum.arkham.ma.us. It's used by the linking interface to
+# guarantee that ticket URIs are unique and easy to construct.
+
+Set($Organization , "example.com");
+
+# $user_passwd_min defines the minimum length for user passwords. Setting
+# it to 0 disables this check
+Set($MinimumPasswordLength , "5");
+
+# $Timezone is used to convert times entered by users into GMT and back again
+# It should be set to a timezone recognized by your local unix box.
+Set($Timezone , 'US/Eastern');
+
+# }}}
+
+# }}}
+
+# {{{ Database Configuration
+
+# Database driver beeing used. Case matters
+# Valid types are "mysql" and "Pg"
+
+Set($DatabaseType , '@DB_TYPE@');
+
+# The domain name of your database server
+# If you're running mysql and it's on localhost,
+# leave it blank for enhanced performance
+Set($DatabaseHost   , '@DB_HOST@');
+Set($DatabaseRTHost , '@DB_RT_HOST@');
+
+# The port that your database server is running on.  Ignored unless it's
+# a positive integer. It's usually safe to leave this blank
+Set($DatabasePort , '@DB_PORT@');
+
+#The name of the database user (inside the database)
+Set($DatabaseUser , '@DB_RT_USER@');
+
+# Password the DatabaseUser should use to access the database
+Set($DatabasePassword , '@DB_RT_PASS@');
+
+# The name of the RT's database on your database server
+Set($DatabaseName , '@DB_DATABASE@');
+
+# If you're using Postgres and have compiled in SSL support,
+# set DatabaseRequireSSL to 1 to turn on SSL communication
+Set($DatabaseRequireSSL , undef);
+
+# }}}
+
+# {{{ Incoming mail gateway configuration
+
+# OwnerEmail is the address of a human who manages RT. RT will send
+# errors generated by the mail gateway to this address.  This address
+# should _not_ be an address that's managed by your RT instance.
+
+Set($OwnerEmail , 'root');
+
+# If $LoopsToRTOwner is defined, RT will send mail that it believes
+# might be a loop to $RT::OwnerEmail
+
+Set($LoopsToRTOwner , 1);
+
+# If $StoreLoopss is defined, RT will record messages that it believes
+# to be part of mail loops.
+# As it does this, it will try to be careful not to send mail to the
+# sender of these messages
+
+Set($StoreLoops , undef);
+
+# $MaxAttachmentSize sets the maximum size (in bytes) of attachments stored
+# in the database.
+
+# For mysql and oracle, we set this size at 10 megabytes.
+# If you're running a postgres version earlier than 7.1, you will need
+# to drop this to 8192. (8k)
+
+Set($MaxAttachmentSize , 10000000);
+
+# $TruncateLongAttachments: if this is set to a non-undef value,
+# RT will truncate attachments longer than MaxAttachmentLength.
+
+Set($TruncateLongAttachments , undef);
+
+# $DropLongAttachments: if this is set to a non-undef value,
+# RT will silently drop attachments longer than MaxAttachmentLength.
+
+Set($DropLongAttachments , undef);
+
+# If $ParseNewMessageForTicketCcs is true, RT will attempt to divine
+# Ticket 'Cc' watchers from the To and Cc lines of incoming messages
+# Be forewarned that if you have _any_ addresses which forward mail to
+# RT automatically and you enable this option without modifying
+# "RTAddressRegexp" below, you will get yourself into a heap of trouble.
+
+Set($ParseNewMessageForTicketCcs , undef);
+
+# RTAddressRegexp is used to make sure RT doesn't add itself as a ticket CC if
+# the setting above is enabled.
+
+Set($RTAddressRegexp , '^rt\@example.com$');
+
+# RT provides functionality which allows the system to rewrite
+# incoming email addresses.  In its simplest form,
+# you can substitute the value in CanonicalizeEmailAddressReplace
+# for the value in CanonicalizeEmailAddressMatch
+# (These values are passed to the CanonicalizeEmailAddress subroutine in RT/User.pm)
+# By default, that routine performs a s/$Match/$Replace/gi on any address passed to it
+
+Set($CanonicalizeEmailAddressMatch   , 'subdomain.example.com$');
+Set($CanonicalizeEmailAddressReplace , 'example.com');
+
+# If $SenderMustExistInExternalDatabase is true, RT will refuse to
+# create non-privileged accounts for unknown users if you are using
+# the "LookupSenderInExternalDatabase" option.
+# Instead, an error message will be mailed and RT will forward the
+# message to $RTOwner.
+#
+# If you are not using $LookupSenderInExternalDatabase, this option
+# has no effect.
+#
+# If you define an AutoRejectRequest template, RT will use this
+# template for the rejection message.
+
+Set($SenderMustExistInExternalDatabase , undef);
+
+# }}}
+
+# {{{ Outgoing mail configuration
+
+# RT is designed such that any mail which already has a ticket-id associated
+# with it will get to the right place automatically.
+
+# $CorrespondAddress and $CommentAddress are the default addresses
+# that will be listed in From: and Reply-To: headers of correspondence
+# and comment mail tracked by RT, unless overridden by a queue-specific
+# address.
+
+Set($CorrespondAddress , 'RT::CorrespondAddress.not.set');
+
+Set($CommentAddress , 'RT::CommentAddress.not.set');
+
+#Sendmail Configuration
+
+# $MailCommand defines which method RT will use to try to send mail
+# We know that 'sendmailpipe' works fairly well.
+# If 'sendmailpipe' doesn't work well for you, try 'sendmail'
+#
+# Note that you should remove the '-t' from $SendmailArguments
+# if you use 'sendmail rather than 'sendmailpipe'
+
+Set($MailCommand , 'sendmailpipe');
+
+# $SendmailArguments defines what flags to pass to $Sendmail
+# assuming you picked 'sendmail' or 'sendmailpipe' as the $MailCommand above.
+# If you picked 'sendmailpipe', you MUST add a -t flag to $SendmailArguments
+
+# These options are good for most sendmail wrappers and workalikes
+Set($SendmailArguments , "-oi -t");
+
+# These arguments are good for sendmail brand sendmail 8 and newer
+#Set($SendmailArguments,"-oi -t -ODeliveryMode=b -OErrorMode=m");
+
+# If you selected 'sendmailpipe' above, you MUST specify the path
+# to your sendmail binary in $SendmailPath.
+# !! If you did not # select 'sendmailpipe' above, this has no effect!!
+Set($SendmailPath , "/usr/sbin/sendmail");
+
+# By default, RT sets the outgoing mail's "From:" header to
+# "SenderName via RT".  Setting this option to 0 disables it.
+
+Set($UseFriendlyFromLine , 1);
+
+# sprintf() format of the friendly 'From:' header; its arguments
+# are SenderName and SenderEmailAddress.
+Set($FriendlyFromLineFormat , "\"%s via RT\" <%s>");
+
+# RT can optionally set a "Friendly" 'To:' header when sending messages to
+# Ccs or AdminCcs (rather than having a blank 'To:' header.
+
+# This feature DOES NOT WORK WITH SENDMAIL[tm] BRAND SENDMAIL
+# If you are using sendmail, rather than postfix, qmail, exim or some other MTA,
+# you _must_ disable this option.
+
+Set($UseFriendlyToLine , 0);
+
+# sprintf() format of the friendly 'From:' header; its arguments
+# are WatcherType and TicketId.
+Set($FriendlyToLineFormat, "\"%s of $RT::rtname Ticket #%s\":;");
+
+# By default RT doesn't notify the person who performs an update, as they
+# already know what they've done. If you'd like to change this behaviour,
+# Set $NotifyActor to 1
+
+Set($NotifyActor, 0);
+
+
+# }}}
+
+# {{{ Logging
+
+# Logging.  The default is to log anything except debugging
+# information to syslog.  Check the Log::Dispatch POD for
+# information about how to get things by syslog, mail or anything
+# else, get debugging info in the log, etc.
+
+#  It might generally make
+# sense to send error and higher by email to some administrator.
+# If you do this, be careful that this email isn't sent to this RT instance.
+
+# the minimum level error that will be logged to the specific device.
+# levels from lowest to highest:
+#  debug info notice warning error critical alert emergency
+
+#  Mail loops will generate a critical log message.
+Set($LogToSyslog    , 'debug');
+Set($LogToScreen    , 'error');
+Set($LogToFile      , undef);
+Set($LogDir, '@RT_LOG_PATH@');
+Set($LogToFileNamed , "rt.log");    #log to rt.log
+
+# }}}
+
+# {{{ Web interface configuration
+
+# Define the directory name to be used for images in rt web
+# documents.
+
+# If you're putting the web ui somewhere other than at the root of
+# your server
+# $WebPath requires a leading / but no trailing /
+
+Set($WebPath , "");
+
+# This is the Scheme, server and port for constructing urls to webrt
+# $WebBaseURL doesn't need a trailing /
+
+Set($WebBaseURL , "http://RT::WebBaseURL.not.configured:80");
+
+Set($WebURL , $WebBaseURL . $WebPath . "/");
+
+# $WebImagesURL points to the base URL where RT can find its images.
+# If you're running the FastCGI version of the RT web interface,
+# you should make RT's WebRT/html/NoAuth/images directory available on
+# a static web server and supply that URL as $WebImagesURL.
+
+Set($WebImagesURL , $WebURL . "NoAuth/images/");
+
+# $RTLogoURL points to the URL of the RT logo displayed in the web UI
+
+Set($LogoURL , $WebImagesURL . "rt.jpg");
+
+# if TrustHTMLAttachments is not defined, we will display them
+# as text. This prevents malicious HTML and javascript from being
+# sent in a request (although there is probably more to it than that)
+Set($TrustHTMLAttachments , undef);
+
+# If $WebExternalAuth is defined, RT will defer to the environment's
+# REMOTE_USER variable.
+
+Set($WebExternalAuth , undef);
+
+# If $WebFallbackToInternalAuth is undefined, the user is allowed a chance
+# of fallback to the login screen, even if REMOTE_USER failed.
+
+Set($WebFallbackToInternalAuth , undef);
+
+# $WebExternalGecos means to match 'gecos' field as the user identity);
+# useful with mod_auth_pwcheck and IIS Integrated Windows logon.
+
+Set($WebExternalGecos , undef);
+
+# $WebExternalAuto will create users under the same name as REMOTE_USER
+# upon login, if it's missing in the Users table.
+
+Set($WebExternalAuto , undef);
+
+# $WebSessionClass is the class you wish to use for managing Sessions.
+# It defaults to use your SQL database, but if you are using MySQL 3.x and
+# plans to use non-ascii Queue names, uncomment and add this line to
+# RT_SiteConfig.pm will prevent session corruption.
+
+# Set($WebSessionClass , 'Apache::Session::File');
+
+# }}}
+
+# {{{ RT UTF-8 Settings
+
+# An array that contains languages supported by RT's internationalization
+# interface.  Defaults to all *.po lexicons; set it to qw(en ja) will make
+# RT bilingual instead of multilingual, but will save same memory.
+
+@LexiconLanguages = qw(*) unless (@LexiconLanguages);
+
+# An array that contains default encodings used to guess which charset
+# an attachment uses if not specified.  Must be recognized by
+# Encode::Guess.
+
+@EmailInputEncodings = qw(utf-8 iso-8859-1 us-ascii) unless (@EmailInputEncodings);
+
+# The charset for localized email.  Must be recognized by Encode.
+
+Set($EmailOutputEncoding , 'utf-8');
+
+# }}}
+
+# {{{ RT Date Handling Options (for Time::ParseDate)
+
+# Set this to 1 if your local date convention looks like "dd/mm/yy"
+# instead of "mm/dd/yy".
+
+Set($DateDayBeforeMonth , 1);
+
+# Should "Tuesday" default to meaning "Next Tuesday" or "Last Tuesday"?
+# Set to 0 for "Next" or 1 for "Last".
+
+Set($AmbiguousDayInPast , 1);
+
+# }}}
+
+1;
diff --git a/rt/etc/RT_SiteConfig.pm b/rt/etc/RT_SiteConfig.pm
new file mode 100644 (file)
index 0000000..0afc604
--- /dev/null
@@ -0,0 +1 @@
+1;
index 59d35a0..c8667c0 100644 (file)
@@ -1,9 +1,10 @@
-CREATE USER !!DB_RT_USER!! identified by !!DB_RT_PASS!!
-temporary tablespace TEMP
-default tablespace USERS
-quota unlimited on USERS;
-
-grant connect, resource to !!DB_RT_USER!!;
-
-exit;
-
+sub acl {
+return (
+"CREATE USER ${RT::DatabaseUser} identified by ${RT::DatabasePassword}".
+"temporary tablespace TEMP" .
+"default tablespace USERS" .
+"quota unlimited on USERS;" ,
+"grant connect, resource to ${RT::DatabaseUser};",
+"exit;");
+}
+1;
index 13ac41d..16ea71b 100755 (executable)
@@ -1,39 +1,63 @@
-drop user !!DB_RT_USER!!;
-create user !!DB_RT_USER!! with password '!!DB_RT_PASS!!' NOCREATEDB NOCREATEUSER;
+sub acl {
+    my $dbh = shift;
 
-grant select, insert, update, delete on Groups to !!DB_RT_USER!!;
-grant select, insert, update, delete on Groups_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on ACL to !!DB_RT_USER!!;
-grant select, insert, update, delete on ACL_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on Watchers to !!DB_RT_USER!!;
-grant select, insert, update, delete on Watchers_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on Links to !!DB_RT_USER!!;
-grant select, insert, update, delete on Links_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on Users to !!DB_RT_USER!!;
-grant select, insert, update, delete on Users_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on Tickets to !!DB_RT_USER!!;
-grant select, insert, update, delete on Tickets_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on GroupMembers to !!DB_RT_USER!!;
-grant select, insert, update, delete on GroupMembers_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on Queues to !!DB_RT_USER!!;
-grant select, insert, update, delete on Queues_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on Transactions to !!DB_RT_USER!!;
-grant select, insert, update, delete on Transactions_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on ScripActions to !!DB_RT_USER!!;
-grant select, insert, update, delete on ScripActions_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on ScripConditions to !!DB_RT_USER!!;
-grant select, insert, update, delete on ScripConditions_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on Scrips to !!DB_RT_USER!!;
-grant select, insert, update, delete on Scrips_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on Attachments to !!DB_RT_USER!!;
-grant select, insert, update, delete on Attachments_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on Templates to !!DB_RT_USER!!;
-grant select, insert, update, delete on Templates_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on Keywords to !!DB_RT_USER!!;
-grant select, insert, update, delete on Keywords_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on ObjectKeywords to !!DB_RT_USER!!;
-grant select, insert, update, delete on ObjectKeywords_id_seq to !!DB_RT_USER!!;
-grant select, insert, update, delete on KeywordSelects to !!DB_RT_USER!!;
-grant select, insert, update, delete on KeywordSelects_id_seq to !!DB_RT_USER!!;
+    my @acls;
 
+    my @tables = qw (
 
+      attachments_id_seq
+      Attachments
+      queues_id_seq
+      Queues
+      links_id_seq
+      Links
+      principals_id_seq
+      Principals
+      groups_id_seq
+      Groups
+      scripconditions_id_seq
+      ScripConditions
+      transactions_id_seq
+      Transactions
+      scrips_id_seq
+      Scrips
+      acl_id_seq
+      ACL
+      groupmembers_id_seq
+      GroupMembers
+      cachedgroupmembers_id_seq
+      CachedGroupMembers
+      users_id_seq
+      Users
+      tickets_id_seq
+      Tickets
+      scripactions_id_seq
+      ScripActions
+      templates_id_seq
+      Templates
+      ticketcustomfieldvalues_id_s
+      TicketCustomFieldValues
+      customfields_id_seq
+      CustomFields
+      customfieldvalues_id_seq
+      CustomFieldValues
+      sessions
+    );
+
+    # if there's already an rt_user, drop it.
+    my @row =
+      $dbh->selectrow_array( "select usename from pg_user where usename = '" . $RT::DatabaseUser."'" );
+    if ( $row[0] ) {
+        push @acls, "drop user ${RT::DatabaseUser};",;
+    }
+
+    push @acls, "create user ${RT::DatabaseUser} with password '${RT::DatabasePassword}' NOCREATEDB NOCREATEUSER;";
+    foreach my $table (@tables) {
+        push @acls,
+          "GRANT SELECT, INSERT, UPDATE, DELETE ON $table to "
+          . $RT::DatabaseUser . ";";
+
+    }
+    return (@acls);
+}
+1;
index 7feb376..0ecaa3b 100755 (executable)
@@ -1,4 +1,8 @@
-
-DELETE FROM user WHERE user like '!!DB_RT_USER!!';
-DELETE FROM db where db LIKE '!!DB_DATABASE!!';
-GRANT SELECT,INSERT,CREATE,INDEX,UPDATE,DELETE ON !!DB_DATABASE!!.* TO !!DB_RT_USER!!@!!DB_RT_HOST!! IDENTIFIED BY '!!DB_RT_PASS!!';
+sub acl {
+return  (
+"USE mysql;",
+"DELETE FROM user WHERE user = '${RT::DatabaseUser}';",
+"DELETE FROM db where db = '${RT::DatabaseName}';",
+"GRANT SELECT,INSERT,CREATE,INDEX,UPDATE,DELETE ON ${RT::DatabaseName}.* TO ${RT::DatabaseUser}\@${RT::DatabaseRTHost} IDENTIFIED BY '${RT::DatabasePassword}';");
+}
+1;
diff --git a/rt/etc/config.pm b/rt/etc/config.pm
deleted file mode 100755 (executable)
index 52b1a0b..0000000
+++ /dev/null
@@ -1,473 +0,0 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/etc/Attic/config.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $      
-
-package RT;
-
-# {{{ Base Configuration
-
-# $rtname the string that RT will look for in mail messages to
-# figure out what ticket a new piece of mail belongs to
-
-# Your domain name is recommended, so as not to pollute the namespace.
-# once you start using a given tag, you should probably never change it. 
-# (otherwise, mail for existing tickets won't get put in the right place
-
-$rtname="example.com";  
-
-# You should set this to your organization's DNS domain. For example,
-# fsck.com or asylum.arkham.ma.us. It's used by the linking interface to 
-# guarantee that ticket URIs are unique and easy to construct.
-
-$Organization = "example.com";
-
-# $user_passwd_min defines the minimum length for user passwords. Setting
-# it to 0 disables this check
-$MinimumPasswordLength = "5";
-
-# $Timezone is used to convert times entered by users into GMT and back again
-# It should be set to a timezone recognized by your local unix box.
-$Timezone =  'US/Eastern'; 
-
-# LogDir is where RT writes its logfiles.
-# This directory should be writable by your rt group
-$LogDir = "!!RT_LOG_PATH!!";
-
-# }}}
-
-# {{{ Database Configuration
-
-# Database driver beeing used - i.e. MySQL.
-$DatabaseType="!!DB_TYPE!!";
-
-# The domain name of your database server
-# If you're running mysql and it's on localhost,
-# leave it blank for enhanced performance
-$DatabaseHost="!!DB_HOST!!";
-
-# The port that your database server is running on.  Ignored unless it's 
-# a positive integer. It's usually safe to leave this blank
-$DatabasePort="!!DB_PORT!!";
-
-
-#The name of the database user (inside the database) 
-$DatabaseUser='!!DB_RT_USER!!';
-
-# Password the DatabaseUser should use to access the database
-$DatabasePassword='!!DB_RT_PASS!!';
-
-
-# The name of the RT's database on your database server
-$DatabaseName='!!DB_DATABASE!!';
-
-# If you're using Postgres and have compiled in SSL support, 
-# set DatabaseRequireSSL to 1 to turn on SSL communication
-$DatabaseRequireSSL=undef;
-
-# }}}
-
-# {{{ Incoming mail gateway configuration
-
-
-# OwnerEmail is the address of a human who manages RT. RT will send
-# errors generated by the mail gateway to this address.  This address
-# should _not_ be an address that's managed by your RT instance.
-
-$OwnerEmail = 'root';
-
-# If $LoopsToRTOwner is defined, RT will send mail that it believes 
-# might be a loop to $RT::OwnerEmail 
-
-$LoopsToRTOwner = 1;
-
-# If $StoreLoopss is defined, RT will record messages that it believes 
-# to be part of mail loops.
-# As it does this, it will try to be careful not to send mail to the 
-# sender of these messages 
-
-$StoreLoops = undef;
-
-
-# $MaxAttachmentSize sets the maximum size (in bytes) of attachments stored
-# in the database. 
-
-# For mysql and oracle, we set this size at 10 megabytes.
-# If you're running a postgres version earlier than 7.1, you will need
-# to drop this to 8192. (8k)
-
-$MaxAttachmentSize = 10000000;  
-
-# $TruncateLongAttachments: if this is set to a non-undef value,
-# RT will truncate attachments longer than MaxAttachmentLength. 
-
-$TruncateLongAttachments = undef;
-
-
-# $DropLongAttachments: if this is set to a non-undef value,
-# RT will silently drop attachments longer than MaxAttachmentLength. 
-
-$DropLongAttachments = undef;
-
-# If $ParseNewMessageForTicketCcs is true, RT will attempt to divine
-# Ticket 'Cc' watchers from the To and Cc lines of incoming messages
-# Be forewarned that if you have _any_ addresses which forward mail to
-# RT automatically and you enable this option without modifying 
-# "IsRTAddress" below, you will get yourself into a heap of trouble.
-# And well, this is free software, so there isn't a warrantee, but
-# I disclaim all ability to help you if you do enable this without
-# modifying IsRTAddress below.
-
-$ParseNewMessageForTicketCcs = undef;
-
-# IsRTAddress is used to make sure RT doesn't add itself as a ticket CC if
-# the setting above is enabled.
-
-sub IsRTAddress {
-    my $address = shift;
-
-    # Example: the following rule would tell RT not to Cc 
-    #  "tickets@noc.example.com"
-    # return(1) if ($address =~ /^tickets\@noc.example.com$/i);
-    
-    return(undef)
-}
-
-# CanonicalizeAddress converts email addresses into canonical form.
-# it takes one email address in and returns the proper canonical
-# form. You can dump whatever your proper local config is in here
-
-sub CanonicalizeAddress {
-    my $email = shift;
-    # Example: the following rule would treat all email
-    # coming from a subdomain as coming from second level domain
-    # foo.com
-    #$email =~ s/\@(.*).foo.com/\@foo.com/;
-    return ($email)
-}
-
-# If $LookupSenderInExternalDatabase is defined, RT will attempt to
-# verify the incoming message sender with a known source, using the 
-# LookupExternalUserInfo routine below
-
-$LookupSenderInExternalDatabase = undef;
-
-# If $SenderMustExistInExternalDatabase is true, RT will refuse to
-# create non-privileged accounts for unknown users if you are using 
-# the "LookupSenderInExternalDatabase" option.
-# Instead, an error message will be mailed and RT will forward the 
-# message to $RTOwner.
-#
-# If you are not using $LookupSenderInExternalDatabase, this option
-# has no effect.
-#
-# If you define an AutoRejectRequest template, RT will use this   
-# template for the rejection message.
-
-$SenderMustExistInExternalDatabase = undef;
-
-# LookupExternalUserInfo is a site-definable method for synchronizing
-# incoming users with an external data source. 
-#
-# This routine takes a tuple of EmailAddress and FriendlyName
-#      EmailAddress is the user's email address, ususally taken from
-#              an email message's From: header.
-#      FriendlyName is a freeform string, ususally taken from the "comment" 
-#              portion of an email message's From: header.
-#
-# It returns (FoundInExternalDatabase, ParamHash);
-#
-#   FoundInExternalDatabase must  be set to 1 before return if the user was
-#   found in the external database.
-#
-#   ParamHash is a Perl parameter hash which can contain at least the following
-#   fields. These fields are used to populate RT's users database when the user 
-#   is created
-#
-#      EmailAddress is the email address that RT should use for this user.  
-#      Name is the 'Name' attribute RT should use for this user. 
-#           'Name' is used for things like access control and user lookups.
-#      RealName is what RT should display as the user's name when displaying 
-#           'friendly' names
-
-sub LookupExternalUserInfo {
-  my ($EmailAddress, $RealName) = @_;
-
-  my $FoundInExternalDatabase = 1;
-  my %params = {};
-  
-  #Name is the RT username you want to use for this user.
-  $params{'Name'} = $EmailAddress;
-  $params{'EmailAddress'} = $EmailAddress;
-  $params{'RealName'} = $RealName;
-
-  # See RT's contributed code for examples.
-  # http://www.fsck.com/pub/rt/contrib/
-  return ($FoundInExternalDatabase, %params); 
-}
-
-# }}}
-
-# {{{ Outgoing mail configuration
-
-# RT is designed such that any mail which already has a ticket-id associated
-# with it will get to the right place automatically.
-
-# $CorrespondAddress and $CommentAddress are the default addresses 
-# that will be listed in From: and Reply-To: headers of correspondence
-# and comment mail tracked by RT, unless overridden by a queue-specific
-# address. 
-
-$CorrespondAddress='RT::CorrespondAddress.not.set';
-
-$CommentAddress='RT::CommentAddress.not.set';
-
-
-#Sendmail Configuration
-
-# $MailCommand defines which method RT will use to try to send mail
-# We know that 'sendmailpipe' works fairly well.
-# If 'sendmailpipe' doesn't work well for you, try 'sendmail' 
-#
-# Note that you should remove the '-t' from $SendmailArguments 
-# if you use 'sendmail rather than 'sendmailpipe'
-
-$MailCommand = 'sendmailpipe';
-
-# $SendmailArguments defines what flags to pass to $Sendmail
-# assuming you picked 'sendmail' or 'sendmailpipe' as the $MailCommand above.
-# If you picked 'sendmailpipe', you MUST add a -t flag to $SendmailArguments
-
-# These options are good for most sendmail wrappers and workalikes
-$SendmailArguments="-oi -t";
-
-# These arguments are good for sendmail brand sendmail 8 and newer
-#$SendmailArguments="-oi -t -ODeliveryMode=b -OErrorMode=m";
-
-# If you selected 'sendmailpipe' above, you MUST specify the path
-# to your sendmail binary in $SendmailPath.  
-# !! If you did not # select 'sendmailpipe' above, this has no effect!!
-$SendmailPath = "/usr/sbin/sendmail";
-
-# RT can optionally set a "Friendly" 'To:' header when sending messages to 
-# Ccs or AdminCcs (rather than having a blank 'To:' header.
-
-# This feature DOES NOT WORK WITH SENDMAIL[tm] BRAND SENDMAIL
-# If you are using sendmail, rather than postfix, qmail, exim or some other MTA,
-# you _must_ disable this option.
-
-$UseFriendlyToLine = 0;
-
-
-# }}}
-
-# {{{ Logging
-
-# Logging.  The default is to log anything except debugging
-# information to a logfile.  Check the Log::Dispatch POD for
-# information about how to get things by syslog, mail or anything
-# else, get debugging info in the log, etc. 
-
-#  It might generally make
-# sense to send error and higher by email to some administrator. 
-# If you do this, be careful that this email isn't sent to this RT instance.
-
-
-# the minimum level error that will be logged to the specific device.
-# levels from lowest to highest:  
-#  debug info notice warning error critical alert emergency 
-
-
-#  Mail loops will generate a critical log message.
-
-$LogToScreen = 'error';
-$LogToFile = 'error';
-#$LogToFileNamed = "$LogDir/rt.log.".$$.".".$<; #log to rt.log.<pid>.<user>
-$LogToFileNamed = "$LogDir/rt.log".$<; #log to rt.log.user;
-
-# }}}
-
-# {{{ Web interface configuration
-
-
-
-# Define the directory name to be used for images in rt web
-# documents.
-
-# If you're putting the web ui somewhere other than at the root of
-# your server
-# $WebPath requires a leading / but no trailing /     
-
-$WebPath = "";
-
-# This is the Scheme, server and port for constructing urls to webrt
-# $WebBaseURL doesn't need a trailing /                                                                            
-
-$WebBaseURL = "http://RT::WebBaseURL.not.configured:80";
-
-$WebURL = $WebBaseURL . $WebPath . "/";
-
-
-
-# $WebImagesURL points to the base URL where RT can find its images.
-# If you're running the FastCGI version of the RT web interface,
-# you should make RT's WebRT/html/NoAuth/images directory available on 
-# a static web server and supply that URL as $WebImagesURL.
-
-$WebImagesURL = $WebURL."NoAuth/images/";
-
-# $RTLogoURL points to the URL of the RT logo displayed in the web UI
-
-$LogoURL = $WebImagesURL."rt.jpg";
-
-# If $WebExternalAuth is defined, RT will defer to the environment's
-# REMOTE_USER variable.
-
-$WebExternalAuth = undef;
-
-# $MasonComponentRoot is where your rt instance keeps its mason html files
-# (this should be autoconfigured during 'make install' or 'make upgrade')
-
-$MasonComponentRoot = "!!MASON_HTML_PATH!!";
-
-# $MasonLocalComponentRoot is where your rt instance keeps its site-local
-# mason html files.
-# (this should be autoconfigured during 'make install' or 'make upgrade')
-
-$MasonLocalComponentRoot = "!!MASON_LOCAL_HTML_PATH!!";
-
-# $MasonDataDir Where mason keeps its datafiles
-# (this should be autoconfigured during 'make install' or 'make upgrade')
-
-$MasonDataDir = "!!MASON_DATA_PATH!!";
-
-# RT needs to put session data (for preserving state between connections
-# via the web interface)
-$MasonSessionDir = "!!MASON_SESSION_PATH!!";
-
-
-
-#This is from tobias' prototype web search UI. it may stay and it may go.
-%WebOptions=
-    (
-     # This is for putting in more user-actions at the Transaction
-     # bar.  I will typically add "Enter bug in Bugzilla" here.:
-     ExtraTransactionActions => sub { return ""; },
-
-     # Here you can modify the list view.  Be aware that the web
-     # interface might crash if TicketAttribute is wrongly set.
-     
-     QueueListingCols => 
-      [
-       { Header     => 'Id',
-        TicketLink => 1,
-        TicketAttribute => 'Id'
-        },
-
-      { Header     => 'Subject',
-        TicketAttribute => 'Subject'
-        },
-       { Header => 'Requestor(s)',
-        TicketAttribute => 'RequestorsAsString'
-        },
-       { Header => 'Status',
-        TicketAttribute => 'Status'
-        },
-
-
-       { Header => 'Queue',
-        TicketAttribute => 'QueueObj->Name'
-        },
-
-
-
-       { Header => 'Told',
-        TicketAttribute => 'ToldObj->AgeAsString'
-        },
-
-       { Header => 'Age',
-        TicketAttribute => 'CreatedObj->AgeAsString'
-        },
-
-       { Header => 'Last',
-        TicketAttribute => 'LastUpdatedObj->AgeAsString'
-        },
-
-       # TODO: It would be nice with a link here to the Owner and all
-       # other request owned by this Owner.
-       { Header => 'Owner',
-        TicketAttribute => 'OwnerObj->Name'
-       },
-   
-       { Header     => 'Take',
-        TicketLink => 1,
-        Constant   => 'Take',
-        ExtraLinks => '&Action=Take'
-        },
-
-      ]
-     );
-
-# }}}
-
-# {{{ RT Linking Interface
-
-# $TicketBaseURI is the Base path of the URI for local tickets
-
-# You shouldn't need to touch this. it's used to link tickets both locally
-# and remotely
-
-$TicketBaseURI = "fsck.com-rt://$Organization/$rtname/ticket/";
-
-# A hash table of conversion subs to be used for transforming RT Link
-# URIs to URLs in the web interface.  If you want to use RT towards
-# locally installed databases, this is the right place to configure it.
-
-%URI2HTTP=
-    (
-      'http' => sub {return @_;},
-      'https' => sub {return @_;},
-      'ftp' => sub {return @_;},
-     'fsck.com-rt' => sub {warn "stub!";},
-     'mozilla.org-bugzilla' => sub {warn "stub!"},
-     'fsck.com-kb' => sub {warn "stub!"}
-     );
-
-
-# A hash table of subs for fetching content from an URI
-%ContentFromURI=   
-    (
-     'fsck.com-rt' => sub {warn "stub!";},
-     'mozilla.org-bugzilla' => sub {warn "stub!"},
-     'fsck.com-kb' => sub {warn "stub!"}
-     );
-
-# }}}
-
-# {{{ No User servicable parts inside 
-
-############################################
-############################################
-############################################
-#
-#  Don't edit anything below this line unless you really know
-#  what you're doing
-#
-#
-############################################
-############################################
-
-# TODO: get this stuff out of the config file and into RT.pm
-
-#Set up us the timezone
-$ENV{'TZ'} = $Timezone; #TODO: Bogus hack to deal with Date::Manip whining
-
-# Configure sendmail if we're using Entity->send('sendmail')
-if ($MailCommand eq 'sendmail') {
-    $MailParams = $SendmailArguments;
-}
-
-
-
-# }}}
-
-
-1;
diff --git a/rt/etc/constraints.mysql b/rt/etc/constraints.mysql
new file mode 100644 (file)
index 0000000..33a0376
--- /dev/null
@@ -0,0 +1,52 @@
+#ALTER TABLE Users ADD FOREIGN KEY (Creator) REFERENCES Users(id);
+#ALTER TABLE Users ADD FOREIGN KEY (LastUpdatedBy) REFERENCES Users(id);
+  ALTER TABLE Links ADD FOREIGN KEY (LocalBase) REFERENCES Tickets(id) ;
+  ALTER TABLE Links ADD FOREIGN KEY (LocalTarget) REFERENCES Tickets(id);
+        ObjectId integer, #  FOREIGN KEY to Users or Groups, depending
+  ALTER TABLE Tickets ADD FOREIGN KEY (Queue) REFERENCES Queues(id);
+  ALTER TABLE Tickets ADD FOREIGN KEY (EffectiveId) REFERENCES Tickets(id);
+  ALTER TABLE Tickets ADD FOREIGN KEY (Owner) REFERENCES Principals(id);
+  ALTER TABLE Tickets ADD FOREIGN KEY (Creator) REFERENCES Users(id);
+  ALTER TABLE Tickets ADD FOREIGN KEY (LastUpdatedBy) REFERENCES Users(id);
+  ALTER TABLE Transactions ADD FOREIGN KEY (Creator) REFERENCES Users(id);
+  ALTER TABLE Transactions ADD FOREIGN KEY (Ticket) REFERENCES Tickets(id);
+  ALTER TABLE Transactions ADD FOREIGN KEY (EffectiveTicket) REFERENCES Tickets(id);
+  ALTER TABLE Attachments ADD FOREIGN KEY (TransactionId) REFERENCES Transactions(id);
+  ALTER TABLE Attachments ADD FOREIGN KEY (Parent) REFERENCES Attachments(id);
+  ALTER TABLE Scrips ADD FOREIGN KEY (ScripCondition) REFERENCES ScripConditions(id);
+  ALTER TABLE Scrips ADD FOREIGN KEY (ScripAction) REFERENCES ScripActions(id);
+  ALTER TABLE Scrips ADD FOREIGN KEY (Template) REFERENCES Templates(id);
+  ALTER TABLE Scrips ADD FOREIGN KEY (Queue) REFERENCES Queues(id);
+  ALTER TABLE Scrips ADD FOREIGN KEY (Creator) REFERENCES Users(id);
+  ALTER TABLE Scrips ADD FOREIGN KEY (LastUpdatedBy) REFERENCES Users(id);
+  PrincipalId integer NOT NULL  , #ALTER TABLE ADD FOREIGN KEY to principals
+  DelegatedBy integer NOT NULL default 0, #ALTER TABLE ADD FOREIGN KEY to principals with a userid
+  DelegatedFrom integer NOT NULL default 0, #ALTER TABLE ADD FOREIGN KEY to ACL
+  ALTER TABLE ACL ADD FOREIGN KEY (PrincipalId) REFERENCES Principals(id);
+  ALTER TABLE ACL ADD FOREIGN KEY (DelegatedBy) REFERENCES Principals(id);
+  ALTER TABLE ACL ADD FOREIGN KEY (DelegatedFrom) REFERENCES ACL(id);
+  ALTER TABLE GroupMembers ADD FOREIGN KEY (GroupId) REFERENCES Principals(id);
+  ALTER TABLE GroupMembers ADD FOREIGN KEY (MemberId) REFERENCES Principals(id);
+        GroupId int, # ALTER TABLE ADD FOREIGN KEY to Principals
+        MemberId int, # ALTER TABLE ADD FOREIGN KEY to Principals
+        Via int, #ALTER TABLE ADD FOREIGN KEY to CachedGroupMembers. (may point to $self->id)
+        ImmediateParentId int, #ALTER TABLE ADD FOREIGN KEY to prinicpals.         
+  ALTER TABLE CachedGroupMembers ADD FOREIGN KEY (ImmediateParentId) REFERENCES Principals(id);
+  ALTER TABLE CachedGroupMembers ADD FOREIGN KEY (GroupId) REFERENCES Principals(id);
+  ALTER TABLE CachedGroupMembers ADD FOREIGN KEY (MemberId) REFERENCES Principals(id);
+  ALTER TABLE CachedGroupMembers ADD FOREIGN KEY (Via) REFERENCES CachedGroupMembers(id);
+  ALTER TABLE ScripActions ADD FOREIGN KEY (Creator) REFERENCES Users(id);
+  ALTER TABLE ScripActions ADD FOREIGN KEY (LastUpdatedBy) REFERENCES Users(id);
+  ALTER TABLE Templates ADD FOREIGN KEY (Queue) REFERENCES Queues(id);
+  ALTER TABLE Templates ADD FOREIGN KEY (Creator) REFERENCES Users(id);
+  ALTER TABLE Templates ADD FOREIGN KEY (LastUpdatedBy) REFERENCES Users(id);
+  ALTER TABLE CustomFields ADD FOREIGN KEY (Queue) REFERENCES Queues(id);
+  ALTER TABLE CustomFields ADD FOREIGN KEY (Creator) REFERENCES Users(id);
+  ALTER TABLE CustomFields ADD FOREIGN KEY (LastUpdatedBy) REFERENCES Users(id);
+  ALTER TABLE TicketCustomFieldValues ADD FOREIGN KEY (Ticket) REFERENCES Ticketss(id);
+  ALTER TABLE TicketCustomFieldValues ADD FOREIGN KEY (CustomField) REFERENCES CustomFields(id);
+  ALTER TABLE TicketCustomFieldValues ADD FOREIGN KEY (Creator) REFERENCES Users(id);
+  ALTER TABLE TicketCustomFieldValues ADD FOREIGN KEY (LastUpdatedBy) REFERENCES Users(id);
+  ALTER TABLE CustomFieldValues ADD FOREIGN KEY (CustomField) REFERENCES CustomFields(id);
+  ALTER TABLE CustomFieldValues ADD FOREIGN KEY (Creator) REFERENCES Users(id);
+  ALTER TABLE CustomFieldValues ADD FOREIGN KEY (LastUpdatedBy) REFERENCES Users(id);
diff --git a/rt/etc/initialdata b/rt/etc/initialdata
new file mode 100644 (file)
index 0000000..62b35ac
--- /dev/null
@@ -0,0 +1,569 @@
+# Initial data for a fresh RT3 Installation.
+
+@Users = (
+    {  Name     => 'Nobody',
+       RealName => 'Nobody in particular',
+       Comments => 'Do not delete or modify this user. It is integral '
+         . 'to RT\'s internal data structures',
+       Privileged => '0', },
+
+    {  Name         => 'root',
+       Gecos        => 'root',
+       RealName     => 'Enoch Root',
+       Password     => 'password',
+       EmailAddress => "root\@localhost",
+       Comments     => 'SuperUser',
+       Privileged   => '1', } );
+
+@Groups = (
+    { Name        => '',
+      Type        => 'Everyone',                        # loc
+      Domain      => 'SystemInternal',
+      Instance    => '',
+      Description => 'Pseudogroup for internal use',    # loc
+    },
+    { Type        => 'Privileged',                      # loc
+      Domain      => 'SystemInternal',
+      Instance    => '',
+      Name        => '',
+      Description => 'Pseudogroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'Unprivileged',                    # loc
+      Domain      => 'SystemInternal',
+      Instance    => '',
+      Description => 'Pseudogroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'Owner',                               # loc
+      Domain      => 'RT::System-Role',
+      Instance    => '',
+      Description => 'SystemRolegroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'Requestor',                           # loc
+      Domain      => 'RT::System-Role',
+      Instance    => '',
+      Description => 'SystemRolegroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'Cc',                                  # loc
+      Domain      => 'RT::System-Role',
+      Instance    => '',
+      Description => 'SystemRolegroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'AdminCc',                             # loc
+      Domain      => 'RT::System-Role',
+      Instance    => '',
+      Description => 'Pseudogroup for internal use',        # loc
+    }, );
+
+@Queues = ({ Name              => 'General',
+             Description       => 'The default queue',
+             CorrespondAddress => "",
+             CommentAddress    => "", },
+           { Name        => '___Approvals',
+             Description => 'A system-internal queue for the approvals system',
+             Disabled    => 2, } );
+
+@ScripActions = (
+
+    {  Name        => 'Autoreply To Requestors',    # loc
+       Description =>
+'Always sends a message to the requestors independent of message sender' ,                                            # loc
+       ExecModule => 'Autoreply',
+       Argument   => 'Requestor' },
+    { Name        => 'Notify Requestors',                    # loc
+      Description => 'Sends a message to the requestors',    # loc
+      ExecModule  => 'Notify',
+      Argument    => 'Requestor' },
+    { Name        => 'Notify Owner as Comment',              # loc
+      Description => 'Sends mail to the owner',              # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'Owner' },
+    { Name        => 'Notify Owner',                         # loc
+      Description => 'Sends mail to the owner',              # loc
+      ExecModule  => 'Notify',
+      Argument    => 'Owner' },
+    { Name        => 'Notify AdminCcs as Comment',                        # loc
+      Description => 'Sends mail to the administrative Ccs as a comment', # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'AdminCc' },
+    { Name        => 'Notify AdminCcs',                                   # loc
+      Description => 'Sends mail to the administrative Ccs',              # loc
+      ExecModule  => 'Notify',
+      Argument    => 'AdminCc' },
+
+    { Name        => 'Notify Requestors and Ccs as Comment',              # loc
+      Description => 'Send mail to requestors and Ccs as a comment',      # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'Requestor,Cc' },
+
+    { Name        => 'Notify Requestors and Ccs',                         # loc
+      Description => 'Send mail to requestors and Ccs',                   # loc
+      ExecModule  => 'Notify',
+      Argument    => 'Requestor,Cc' },
+
+    { Name        => 'Notify Requestors, Ccs and AdminCcs as Comment',    # loc
+      Description => 'Send mail to all watchers as a "comment"',          # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'All' },
+    { Name        => 'Notify Requestors, Ccs and AdminCcs',               # loc
+      Description => 'Send mail to all watchers',                         # loc
+      ExecModule  => 'Notify',
+      Argument    => 'All' },
+    { Name        => 'Notify Other Recipients as Comment',                # loc
+      Description => 'Sends mail to explicitly listed Ccs and Bccs',      # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'OtherRecipients' },
+    { Name        => 'Notify Other Recipients',                           # loc
+      Description => 'Sends mail to explicitly listed Ccs and Bccs',      # loc
+      ExecModule  => 'Notify',
+      Argument    => 'OtherRecipients' },
+    { Name        => 'User Defined',                                      # loc
+      Description => 'Perform a user-defined action',                     # loc
+      ExecModule  => 'UserDefined', },
+    {  Name        => 'Create Tickets',                                    # loc
+       Description =>
+         'Create new tickets based on this scrip\'s template',             # loc
+       ExecModule => 'CreateTickets', },
+    { Name        => 'Open Tickets',
+      Description => 'Open tickets on correspondence',                    # loc
+      ExecModule  => 'AutoOpen' },
+);
+
+@ScripConditions = (
+    { Name                 => 'On Create',                                # loc
+      Description          => 'When a ticket is created',                 # loc
+      ApplicableTransTypes => 'Create',
+      ExecModule           => 'AnyTransaction', },
+
+    { Name                 => 'On Transaction',                           # loc
+      Description          => 'When anything happens',                    # loc
+      ApplicableTransTypes => 'Any',
+      ExecModule           => 'AnyTransaction', },
+    {
+
+      Name                 => 'On Correspond',                             # loc
+      Description          => 'Whenever correspondence comes in',          # loc
+      ApplicableTransTypes => 'Correspond',
+      ExecModule           => 'AnyTransaction', },
+
+    {
+
+      Name                 => 'On Comment',                                # loc
+      Description          => 'Whenever comments come in',                 # loc
+      ApplicableTransTypes => 'Comment',
+      ExecModule           => 'AnyTransaction' },
+    {
+
+      Name                 => 'On Status Change',                          # loc
+      Description          => 'Whenever a ticket\'s status changes',       # loc
+      ApplicableTransTypes => 'Status',
+      ExecModule           => 'AnyTransaction',
+
+    },
+    {
+
+      Name                 => 'On Owner Change',                           # loc
+      Description          => 'Whenever a ticket\'s owner changes',        # loc
+      ApplicableTransTypes => 'Any',
+      ExecModule           => 'OwnerChange',
+
+    },
+    {
+
+      Name                 => 'On Queue Change',                           # loc
+      Description          => 'Whenever a ticket\'s queue changes',        # loc
+      ApplicableTransTypes => 'Set',
+      ExecModule           => 'QueueChange',
+
+    },
+    {  Name                 => 'On Resolve',                               # loc
+       Description          => 'Whenever a ticket is resolved',            # loc
+       ApplicableTransTypes => 'Status',
+       ExecModule           => 'StatusChange',
+       Argument             => 'resolved'
+
+    },
+
+    {  Name                 => 'User Defined',                             # loc
+       Description          => 'Whenever a user-defined condition occurs', # loc
+       ApplicableTransTypes => 'Any',
+       ExecModule           => 'UserDefined'
+
+    },
+
+);
+
+@Templates = (
+    { Queue       => '0',
+      Name        => 'Blank',                                             # loc
+      Description => 'A blank template',                                  # loc
+      Content     => '', },
+    {  Queue       => '0',
+       Name        => 'Autoreply',                                         # loc
+       Description => 'Default Autoresponse template',                     # loc
+       Content     => 'Subject: AutoReply: {$Ticket->Subject}
+
+
+Greetings,
+
+This message has been automatically generated in response to the
+creation of a trouble ticket regarding:
+       "{$Ticket->Subject()}", 
+a summary of which appears below.
+
+There is no need to reply to this message right now.  Your ticket has been
+assigned an ID of [{$rtname} #{$Ticket->id()}].
+
+Please include the string:
+
+         [{$rtname} #{$Ticket->id}]
+
+in the subject line of all future correspondence about this issue. To do so, 
+you may reply to this message.
+
+                        Thank you,
+                        {$Ticket->QueueObj->CorrespondAddress()}
+
+-------------------------------------------------------------------------
+{$Transaction->Content()}
+'
+    },
+
+    {  Queue       => '0',
+       Name        => 'Transaction',                     # loc
+       Description => 'Default transaction template',    # loc
+       Content     => 'RT-Attach-Message: yes
+
+
+{$Transaction->CreatedAsString}: Request {$Ticket->id} was acted upon.
+Transaction: {$Transaction->Description}
+       Queue: {$Ticket->QueueObj->Name}
+     Subject: {$Transaction->Subject || $Ticket->Subject || "(No subject given)"}
+       Owner: {$Ticket->OwnerObj->Name}
+  Requestors: {$Ticket->RequestorAddresses}
+      Status: {$Ticket->Status}
+ Ticket <URL: {$RT::WebURL}Ticket/Display.html?id={$Ticket->id} >
+
+
+{$Transaction->Content()}
+'
+    },
+
+    {
+
+      Queue       => '0',
+      Name        => 'Admin Correspondence',                     # loc
+      Description => 'Default admin correspondence template',    # loc
+      Content     => 'RT-Attach-Message: yes
+
+
+<URL: {$RT::WebURL}Ticket/Display.html?id={$Ticket->id} >
+
+{$Transaction->Content()}
+'
+    },
+
+    {  Queue       => '0',
+       Name        => 'Correspondence',                          # loc
+       Description => 'Default correspondence template',         # loc
+       Content     => 'RT-Attach-Message: yes
+
+{$Transaction->Content()}
+'
+    },
+
+    {  Queue       => '0',
+       Name        => 'Admin Comment',                           # loc
+       Description => 'Default admin comment template',          # loc
+       Content     =>
+'Subject: [Comment] {my $s=($Transaction->Subject||$Ticket->Subject); $s =~ s/\\[Comment\\]//g; $comment =~ s/^Re//i; $s;}
+
+
+{$RT::WebURL}Ticket/Display.html?id={$Ticket->id}
+This is a comment.  It is not sent to the Requestor(s):
+
+{$Transaction->Content()}
+'
+    },
+
+    {  Queue       => '0',
+       Name        => 'Status Change',                                     # loc
+       Description => 'Ticket status changed',                             # loc
+       Content     => 'Subject: Status Changed to: {$Transaction->NewValue}
+
+
+{$RT::WebURL}Ticket/Display.html?id={$Ticket->id}
+
+{$Transaction->Content()}
+'
+    },
+
+    {
+
+      Queue       => '0',
+      Name        => 'Resolved',                 # loc
+      Description => 'Ticket Resolved',          # loc
+      Content     => 'Subject: Ticket Resolved
+
+According to our records, your request has been resolved. If you have any
+further questions or concerns, please respond to this message.
+'
+    },
+    {  Queue       => '___Approvals',
+       Name        => "New Pending Approval",    # loc
+       Description =>
+         "Notify Owners and AdminCcs of new items pending their approval", # loc
+       Content => 'Subject: New Pending Approval: {$Ticket->Subject}
+
+Greetings,
+
+There is a new item pending your approval: "{$Ticket->Subject()}", 
+a summary of which appears below.
+
+Please visit {$RT::WebURL}Approvals/Display.html?id={$Ticket->id}
+to approve or reject this ticket, or {$RT::WebURL}Approvals/ to
+batch-process all your pending approvals.
+
+-------------------------------------------------------------------------
+{$Transaction->Content()}
+'
+    },
+    {  Queue       => '___Approvals',
+       Name        => "Approval Passed",    # loc
+       Description =>
+         "Notify Owner of their ticket has been approved by some approver", # loc
+       Content => 'Subject: Ticket Rejected: {$Ticket->Subject}
+
+Greetings,
+
+Your ticket has been approved by { eval { $Approval->OwnerObj->Name } }.
+Other approvals may be pending.
+'
+    },
+    {  Queue       => '___Approvals',
+       Name        => "All Approvals Passed",    # loc
+       Description =>
+         "Notify Owner of their ticket has been approved by all approvers", # loc
+       Content => 'Subject: Ticket Rejected: {$Ticket->Subject}
+
+Greetings,
+
+Your ticket has been approved.  Its Owner may now start to act on it.
+'
+    },
+    {  Queue       => '___Approvals',
+       Name        => "Approval Rejected",    # loc
+       Description =>
+         "Notify Owner of their rejected ticket", # loc
+       Content => 'Subject: Ticket Rejected: {$Ticket->Subject}
+
+Greetings,
+
+Your ticket has been rejected by { eval { $Approval->OwnerObj->Name } }.
+'
+    },
+);
+# }}}
+
+@Scrips = (
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Open Tickets',
+       Template       => 'Blank' },
+    {  ScripCondition => 'On Create',
+       ScripAction    => 'AutoReply To Requestors',
+       Template       => 'AutoReply' },
+    {  ScripCondition => 'On Create',
+       ScripAction    => 'Notify AdminCcs',
+       Template       => 'Transaction' },
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Notify AdminCcs',
+       Template       => 'Admin Correspondence' },
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Notify Requestors And Ccs',
+       Template       => 'Correspondence' },
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Notify Other Recipients',
+       Template       => 'Correspondence' },
+    {  ScripCondition => 'On Comment',
+       ScripAction    => 'Notify AdminCcs As Comment',
+       Template       => 'Admin Comment' },
+    {  ScripCondition => 'On Comment',
+       ScripAction    => 'Notify Other Recipients As Comment',
+       Template       => 'Correspondence' },
+    {  ScripCondition => 'On Resolve',
+       ScripAction    => 'Notify Requestors',
+       Template       => 'Resolved' },
+    {  Description => "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval",    # loc
+       Queue          => '___Approvals',
+       ScripCondition => 'User Defined',
+       CustomIsApplicableCode => q[
+           $self->TicketObj->Type eq 'approval'        and
+           $self->TransactionObj->Field eq 'Status'    and
+           $self->TransactionObj->NewValue eq 'open'   and
+           eval { $T::Approving = ($self->TicketObj->AllDependedOnBy( Type => 'ticket' ))[0] }
+       ],
+       ScripAction    => 'Notify Owner',
+       Template       => 'New Pending Approval' },
+    {  Description => "If an approval is rejected, reject the original and delete pending approvals",    # loc
+       Queue            => '___Approvals',
+       ScripCondition   => 'On Status Change',
+       ScripAction      => 'User Defined',
+       CustomPrepareCode => q[
+# ------------------------------------------------------------------- #
+return(0) unless ( lc($self->TransactionObj->NewValue) eq "rejected" or
+                  lc($self->TransactionObj->NewValue) eq "deleted" );
+
+my $rejected = 0;
+my $links = $self->TicketObj->DependedOnBy;
+foreach my $link (@{ $links->ItemsArrayRef }) {
+    my $obj = $link->BaseObj;
+    if ($obj->QueueObj->IsActiveStatus($obj->Status)) {
+       if ($obj->Type eq 'ticket') {
+           $obj->Comment(
+               Content => $self->loc("Your request was rejected."),
+           );
+           $obj->SetStatus(
+               Status  => 'rejected',
+               Force   => 1,
+           );
+
+           $T::Approval = $self->TicketObj; # so we can access it inside templates
+           $self->{TicketObj} = $obj;  # we want the original id in the token line
+           $rejected = 1;
+       }
+       else {
+           $obj->SetStatus(
+               Status  => 'deleted',
+               Force   => 1,
+           );
+       }
+    }
+}
+
+$links = $self->TicketObj->DependsOn;
+foreach my $link (@{ $links->ItemsArrayRef }) {
+    my $obj = $link->TargetObj;
+    if ($obj->QueueObj->IsActiveStatus($obj->Status)) {
+       $obj->SetStatus(
+           Status      => 'deleted',
+           Force       => 1,
+       );
+    }
+}
+
+# Now magically turn myself into a Requestor Notify object...
+require RT::Action::Notify; bless($self, 'RT::Action::Notify');
+$self->{Argument} = 'Requestor'; $self->Prepare;
+
+return $rejected;
+# ------------------------------------------------------------------- #
+       ],
+       CustomCommitCode => '"never needed"',
+       Template          => 'Approval Rejected', },
+    {  Description => "When a ticket has been approved by any approver, add correspondence to the original ticket", # loc
+       Queue             => '___Approvals',
+       ScripCondition    => 'On Resolve',
+       ScripAction       => 'User Defined',
+       CustomPrepareCode => q[
+# ------------------------------------------------------------------- #
+return(0) unless ($self->TicketObj->Type eq 'approval');
+
+my $note;
+my $t = $self->TicketObj->Transactions;
+while (my $o = $t->Next) {
+    $note .= $o->Content . "\n" if $o->ContentObj
+           and $o->Content !~ /Default Approval/;
+}
+
+foreach my $obj ($self->TicketObj->AllDependedOnBy( Type => 'ticket' )) {
+    $obj->Comment(
+       Content => $self->loc( "Your request has been approved by [_1]. Other approvals may still be pending.", # loc
+           $self->TransactionObj->CreatorObj->Name,
+       ) . "\n" . $self->loc( "Approver's notes: [_1]", # loc
+           $note
+       ),
+    );
+    $T::Approval = $self->TicketObj; # so we can access it inside templates
+    $self->{TicketObj} = $obj;  # we want the original id in the token line
+}
+
+# Now magically turn myself into a Requestor Notify object...
+require RT::Action::Notify; bless($self, 'RT::Action::Notify');
+$self->{Argument} = 'Requestor'; $self->Prepare;
+
+return 1;
+# ------------------------------------------------------------------- #
+       ],
+       CustomCommitCode => '"never needed"',
+       Template => 'Approval Passed' },
+    {  Description => "When a ticket has been approved by all approvers, add correspondence to the original ticket", # loc
+       Queue             => '___Approvals',
+       ScripCondition    => 'On Resolve',
+       ScripAction       => 'User Defined',
+       CustomPrepareCode  => q[
+# ------------------------------------------------------------------- #
+# Find all the tickets that depend on this (that this is approving)
+
+my $Ticket = $self->TicketObj;
+my @TOP    = $Ticket->AllDependedOnBy( Type => 'ticket' );
+my $links  = $Ticket->DependedOnBy;
+my $passed = 0;
+
+while (my $link = $links->Next) {
+    my $obj = $link->BaseObj;
+    next if ($obj->HasUnresolvedDependencies( Type => 'approval' ));
+
+    if ($obj->Type eq 'ticket') {
+       $obj->Comment(
+           Content     => $self->loc("Your request has been approved."),
+       );
+       $T::Approval  = $Ticket;    # so we can access it inside templates
+       $self->{TicketObj} = $obj;  # we want the original id in the token line
+       $passed = 1;
+    }
+    elsif ($obj->Type eq 'approval') {
+       $obj->SetStatus( Status => 'open', Force => 1 );
+    }
+    elsif ($RT::UseCodeTickets and $obj->Type eq 'code') {
+       my $code = $obj->Transactions->First->Content;
+       my $rv;
+
+       foreach my $TOP (@TOP) {
+           local $@;
+           $rv++ if eval $code;
+           $RT::Logger->error("Cannot eval code: $@") if $@;
+       }
+
+       if ($rv or !@TOP) {
+           $obj->SetStatus( Status     => 'resolved', Force    => 1,);
+       }
+       else {
+           $obj->SetStatus( Status     => 'rejected', Force    => 1,);
+       }
+    }
+}
+
+# Now magically turn myself into a Requestor Notify object...
+require RT::Action::Notify; bless($self, 'RT::Action::Notify');
+$self->{Argument} = 'Requestor'; $self->Prepare;
+
+return $passed;
+# ------------------------------------------------------------------- #
+       ],
+       CustomCommitCode => '"never needed"',
+       Template => 'All Approvals Passed', },
+
+);
+
+@ACL = (
+    { UserId => 'Nobody',      # - principalId
+      Right  => 'OwnTicket', },
+
+    { UserId => 'root',        # - principalid
+      Right  => 'SuperUser', },
+
+);
diff --git a/rt/etc/schema.Oracle b/rt/etc/schema.Oracle
deleted file mode 100644 (file)
index 0c14cb3..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-CREATE SEQUENCE KEYWORDSELECTS_seq;
-CREATE TABLE KeywordSelects (
-       id              NUMBER(11, 0) PRIMARY KEY,
-       Name            VARCHAR2(255),
-       Keyword         NUMBER(11, 0),
-       Single          NUMBER(11, 0),
-       Depth           NUMBER(11, 0) DEFAULT 0,
-       ObjectType      VARCHAR2(32) NOT NULL,
-       ObjectField     VARCHAR2(32),
-       ObjectValue     VARCHAR2(255),
-       Disabled                NUMBER(11, 0) DEFAULT 0
-);
-
-CREATE INDEX KeywordSelects1 ON KeywordSelects (Keyword);
-CREATE INDEX KeywordSelects2 ON 
-       KeywordSelects(ObjectType, ObjectField, ObjectValue);
-
-
-CREATE SEQUENCE ATTACHMENTS_seq;
-CREATE TABLE Attachments (
-       id              NUMBER(11,0) PRIMARY KEY,
-       TransactionId   NUMBER(11,0) NOT NULL,
-       Parent          NUMBER(11,0),           
-       MessageId       VARCHAR2(160),
-       Subject         VARCHAR2(255),
-       Filename        VARCHAR2(255),
-       ContentType     VARCHAR2(80),
-       ContentEncoding         VARCHAR2(80),
-       Content         CLOB,
-       Headers         CLOB,
-       Creator         NUMBER(11,0),
-       Created         DATE,
-       Disabled        NUMBER(11,0) DEFAULT 0
-);
-
-CREATE SEQUENCE QUEUES_seq;
-CREATE TABLE Queues (
-       id                      NUMBER(11, 0) PRIMARY KEY,
-       Name                    VARCHAR2(40) NOT NULL UNIQUE,
-       Description             VARCHAR2(120),
-       CorrespondAddress       VARCHAR2(40),
-       CommentAddress          VARCHAR2(40),
-       InitialPriority         NUMBER(11, 0),          
-       FinalPriority           NUMBER(11, 0),
-       DefaultDueIn            NUMBER(11, 0),
-       Creator                 NUMBER(11, 0),
-       Created                 DATE,
-       LastUpdatedBy           NUMBER(11, 0),
-       LastUpdated             DATE,
-       Disabled                NUMBER(11,0) DEFAULT 0
-);
-
-CREATE SEQUENCE LINKS_seq;
-CREATE TABLE Links (
-       id              NUMBER(11,0) PRIMARY KEY,
-       Base            VARCHAR2(255),
-       Target          VARCHAR2(255),
-       Type            VARCHAR2(20) NOT NULL,
-       LocalTarget     NUMBER(11,0),
-       LocalBase       NUMBER(11,0),
-       LastUpdatedBy   NUMBER(11,0),
-       LastUpdated     DATE,
-       Creator         NUMBER(11,0),
-       Created         DATE
-);
-
-CREATE UNIQUE INDEX Links1 ON Links (Base, Target, Type);
-
-
-
-CREATE SEQUENCE GROUPS_seq;
-CREATE TABLE Groups (
-       id              NUMBER(11,0) PRIMARY KEY,
-       Name            VARCHAR2(16) UNIQUE,
-       Description     VARCHAR(64),
-       Pseudo          NUMBER(11,0) DEFAULT 0
-);
-
-CREATE SEQUENCE WATCHERS_seq;
-CREATE TABLE Watchers (
-       id              NUMBER(11,0) PRIMARY KEY,
-       Type            VARCHAR2(16),   
-       Scope           VARCHAR2(16),   
-       Value           NUMBER(11,0),   
-       Email           VARCHAR2(255),  
-       Quiet           NUMBER(11,0),   
-       Owner           NUMBER(11,0),   
-       Creator         NUMBER(11,0),
-       Created         DATE,
-       LastUpdatedBy   NUMBER(11,0),
-       LastUpdated     DATE
-);
-
-
-
-CREATE SEQUENCE SCRIPCONDITIONS_seq;
-CREATE TABLE ScripConditions (
-       id                      NUMBER(11, 0) PRIMARY KEY,
-       Name                    VARCHAR2(255),
-       Description             VARCHAR2(255),
-       ExecModule              VARCHAR2(60),
-       Argument                VARCHAR2(255),
-       ApplicableTransTypes    VARCHAR2(60),
-       Creator                 NUMBER(11, 0),
-       Created                 DATE,
-       LastUpdatedBy           NUMBER(11, 0),
-       LastUpdated             DATE
-);
-
-
-CREATE SEQUENCE TRANSACTIONS_seq;
-CREATE TABLE Transactions (
-       id                      NUMBER(11,0) PRIMARY KEY,
-       EffectiveTicket         NUMBER(11,0),
-       Ticket                  NUMBER(11,0),
-       TimeTaken               NUMBER(11,0),
-       Type                    VARCHAR2(20),
-       Field                   VARCHAR2(40),
-       OldValue                VARCHAR2(255),
-       NewValue                VARCHAR2(255),
-       Data                    VARCHAR2(100),
-       Creator                 NUMBER(11,0),
-       Created                 DATE,
-       Disabled                NUMBER(11,0) DEFAULT 0
-);
-
-CREATE SEQUENCE SCRIPS_seq;
-CREATE TABLE Scrips (
-       id              NUMBER(11,0) PRIMARY KEY,       
-       ScripCondition  NUMBER(11,0),
-       ScripAction     NUMBER(11,0),
-       Stage           VARCHAR2(32),
-       Queue           NUMBER(11,0),
-       Template        NUMBER(11,0),
-       Creator         NUMBER(11,0),
-       Created         DATE,
-       LastUpdatedBy   NUMBER(11,0),
-       LastUpdated     DATE  
-);
-
-
-
-
-CREATE SEQUENCE ACL_seq;
-CREATE TABLE ACL (
-       id              NUMBER(11,0) PRIMARY KEY,
-       PrincipalId     NUMBER(11,0),
-       PrincipalType   VARCHAR2(25),
-       RightName       VARCHAR2(25),
-       RightScope      VARCHAR2(25),
-       RightAppliesTo  NUMBER(11,0)
-);
-
-CREATE SEQUENCE GROUPMEMBERS_seq;
-CREATE TABLE GroupMembers (
-       id              NUMBER(11,0) PRIMARY KEY,
-       GroupId         NUMBER(11,0),
-       UserId          NUMBER(11,0) 
-);
-
-CREATE UNIQUE INDEX GroupMembers1 ON GroupMembers (GroupId, UserId);
-
-
-CREATE SEQUENCE OBJECTKEYWORDS_seq;
-CREATE TABLE ObjectKeywords (
-  id           NUMBER(11,0)  PRIMARY KEY,
-  Keyword      NUMBER(11,0) NOT NULL,
-  KeywordSelect NUMBER(11,0)  NOT NULL,
-  ObjectType   VARCHAR2(32) NOT NULL,
-  ObjectId     NUMBER(11,0) NOT NULL
-);
-
-CREATE UNIQUE INDEX ObjectKeywords1 ON ObjectKeywords
-       (ObjectId, ObjectType, KeywordSelect, Keyword);
-CREATE INDEX ObjectKeywords3 ON ObjectKeywords (Keyword);
-
-CREATE SEQUENCE KEYWORDS_seq;
-CREATE TABLE Keywords (
-       id              NUMBER(11, 0) PRIMARY KEY,
-       Name            VARCHAR2(255) NOT NULL,
-       Description     VARCHAR2(255),
-       Parent          NUMBER(11, 0),
-       Disabled                NUMBER(11, 0) DEFAULT 0
-);
-
-CREATE UNIQUE INDEX Keywords1 ON Keywords (Name, Parent);
-CREATE INDEX Keywords3 ON Keywords (Parent);
-
-CREATE SEQUENCE USERS_seq;
-CREATE TABLE Users (
-       id                      NUMBER(11,0) PRIMARY KEY,
-       Name                    VARCHAR2(120) NOT NULL UNIQUE,
-       Password                VARCHAR2(40),
-       Comments                CLOB,
-       Signature               CLOB,
-       EmailAddress            VARCHAR2(120),
-       FreeFormContactInfo     CLOB,
-       Organization            VARCHAR2(200),
-       Privileged              NUMBER(11,0),
-       RealName                VARCHAR2(120),
-       NickName                VARCHAR2(16),
-       Lang                    VARCHAR2(16),
-       EmailEncoding           VARCHAR2(16),
-       WebEncoding             VARCHAR2(16),
-       ExternalContactInfoId   VARCHAR2(100),
-       ContactInfoSystem       VARCHAR2(30),
-       ExternalAuthId          VARCHAR2(100),
-       AuthSystem              VARCHAR2(30),
-       Gecos                   VARCHAR2(16),
-       HomePhone               VARCHAR2(30),
-       WorkPhone               VARCHAR2(30),
-       MobilePhone             VARCHAR2(30),
-       PagerPhone              VARCHAR2(30),
-       Address1                VARCHAR2(200),
-       Address2                VARCHAR2(200),
-       City                    VARCHAR2(100),
-       State                   VARCHAR2(100),
-       Zip                     VARCHAR2(16),
-       Country                 VARCHAR2(50),
-       Creator                 NUMBER(11,0),
-       Created                 DATE,
-       LastUpdatedBy           NUMBER(11,0),
-       LastUpdated             DATE,
-       Disabled                        NUMBER(11,0) DEFAULT 0
-);
-
-
-
-
-CREATE SEQUENCE TICKETS_seq;
-CREATE TABLE Tickets (
-       id                      NUMBER(11, 0) PRIMARY KEY,
-       EffectiveId             NUMBER(11, 0),
-       Queue                   NUMBER(11,0),
-       Type                    VARCHAR2(16),           
-       IssueStatement          NUMBER(11,0),   
-       Resolution              NUMBER(11,0),           
-       Owner                   NUMBER(11,0),           
-       Subject                 VARCHAR2(200) DEFAULT '', 
-       InitialPriority         NUMBER(11,0) DEFAULT 0,
-       FinalPriority           NUMBER(11,0) DEFAULT 0,
-       Priority                NUMBER(11,0) DEFAULT 0,
-       Status                  VARCHAR2(10),           
-       TimeWorked              NUMBER(11,0) DEFAULT 0,
-       TimeLeft                NUMBER(11,0) DEFAULT 0,
-       Told                    DATE,
-       Starts                  DATE,
-       Started                 DATE,
-       Due                     DATE,
-       Resolved                DATE,
-       LastUpdatedBy           NUMBER(11,0),
-       LastUpdated             DATE,
-       Creator                 NUMBER(11,0),
-       Created                 DATE,
-       Disabled                NUMBER(11,0) DEFAULT 0
-);
-
-CREATE SEQUENCE SCRIPACTIONS_seq;
-CREATE TABLE ScripActions (
-  id           NUMBER(11,0) PRIMARY KEY,
-  Name         VARCHAR2(255),
-  Description  VARCHAR2(255),
-  ExecModule   VARCHAR2(60),
-  Argument     VARCHAR2(255),
-  Creator      NUMBER(11,0),
-  Created      DATE,
-  LastUpdatedBy        NUMBER(11,0),
-  LastUpdated  DATE
-);
-
-
-CREATE SEQUENCE TEMPLATES_seq;
-CREATE TABLE Templates (
-       id              NUMBER(11,0) PRIMARY KEY,
-       Queue           NUMBER(11,0) DEFAULT 0 NOT NULL,
-       Name            VARCHAR2(40) NOT NULL UNIQUE,
-       Description     VARCHAR2(120),
-       Type            VARCHAR2(16),
-       Language        VARCHAR2(16), 
-       TranslationOf   NUMBER(11,0),
-       Content         CLOB,
-       LastUpdated     DATE,
-       LastUpdatedBy   NUMBER(11,0),
-       Creator         NUMBER(11,0),
-       Created         DATE
-);
-
index 21d981b..ba0d6fc 100755 (executable)
-CREATE TABLE KeywordSelects (
-  id serial NOT NULL  ,
-  Name varchar(255)   ,
-  Keyword integer   ,
-  Single integer   ,
-  Depth integer NOT NULL DEFAULT 0 ,
-  ObjectType varchar(32) NOT NULL  ,
-  ObjectField varchar(32)   ,
-  ObjectValue varchar(255)   ,
-  Disabled int2 NOT NULL DEFAULT 0 ,
-  PRIMARY KEY (id)
-);
-CREATE INDEX KeywordSelects1 ON KeywordSelects (Keyword);
-CREATE INDEX KeywordSelects2 ON KeywordSelects (ObjectType, ObjectField, ObjectValue);
+------------------------------------------------------------------
+-- My2Pg 1.23 translated dump
+--
+------------------------------------------------------------------
+
+BEGIN;
+
+
+
+
+--
+-- Sequences for table ATTACHMENTS
+--
+
+CREATE SEQUENCE attachments_id_seq;
+
+-- {{{ Attachments
+
 CREATE TABLE Attachments (
-  id serial NOT NULL  ,
+  id INTEGER DEFAULT nextval('attachments_id_seq'),
   TransactionId integer NOT NULL  ,
-  Parent integer   ,
-  MessageId varchar(160)   ,
-  Subject varchar(255)   ,
-  Filename varchar(255)   ,
-  ContentType varchar(80)   ,
-  ContentEncoding varchar(80)   ,
-  Content TEXT   ,
-  Headers TEXT   ,
-  Creator integer   ,
-  Created timestamp   ,
+  Parent integer NOT NULL DEFAULT 0  ,
+  MessageId varchar(160) NULL  ,
+  Subject varchar(255) NULL  ,
+  Filename varchar(255) NULL  ,
+  ContentType varchar(80) NULL  ,
+  ContentEncoding varchar(80) NULL  ,
+  Content text NULL  ,
+  Headers text NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
   PRIMARY KEY (id)
+
 );
-CREATE INDEX Attachments1 ON Attachments (Parent);
-CREATE INDEX Attachments2 ON Attachments (TransactionId);
-CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId);
+
+CREATE INDEX Attachments1 ON Attachments (Parent) ;
+CREATE INDEX Attachments2 ON Attachments (TransactionId) ;
+CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId) ;
+-- }}}
+
+-- {{{ Queues
+
+
+--
+-- Sequences for table QUEUES
+--
+
+CREATE SEQUENCE queues_id_seq;
+
 CREATE TABLE Queues (
-  id serial NOT NULL  ,
-  Name varchar(120) NOT NULL  ,
-  Description varchar(120)   ,
-  CorrespondAddress varchar(120)   ,
-  CommentAddress varchar(120)   ,
-  InitialPriority integer   ,
-  FinalPriority integer   ,
-  DefaultDueIn integer   ,
-  Creator integer   ,
-  Created timestamp   ,
-  LastUpdatedBy integer   ,
-  LastUpdated timestamp   ,
+  id INTEGER DEFAULT nextval('queues_id_seq'),
+  Name varchar(200) NOT NULL  ,
+  Description varchar(255) NULL  ,
+  CorrespondAddress varchar(120) NULL  ,
+  CommentAddress varchar(120) NULL  ,
+  InitialPriority integer NOT NULL DEFAULT 0  ,
+  FinalPriority integer NOT NULL DEFAULT 0  ,
+  DefaultDueIn integer NOT NULL DEFAULT 0  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated TIMESTAMP NULL  ,
   Disabled int2 NOT NULL DEFAULT 0 ,
   PRIMARY KEY (id)
+
 );
-CREATE UNIQUE INDEX Queues1 ON Queues (Name);
+CREATE UNIQUE INDEX Queues1 ON Queues (Name) ;
+
+-- }}}
+
+-- {{{ Links
+
+
+
+--
+-- Sequences for table LINKS
+--
+
+CREATE SEQUENCE links_id_seq;
+
 CREATE TABLE Links (
-  id serial NOT NULL  ,
-  Base varchar(240)   ,
-  Target varchar(240)   ,
+  id INTEGER DEFAULT nextval('links_id_seq'),
+  Base varchar(240) NULL  ,
+  Target varchar(240) NULL  ,
   Type varchar(20) NOT NULL  ,
-  LocalTarget integer   ,
-  LocalBase integer   ,
-  LastUpdatedBy integer   ,
-  LastUpdated timestamp   ,
-  Creator integer   ,
-  Created timestamp   ,
+  LocalTarget integer NOT NULL DEFAULT 0  ,
+  LocalBase integer NOT NULL DEFAULT 0  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated TIMESTAMP NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
   PRIMARY KEY (id)
+
 );
-CREATE UNIQUE INDEX Links1 ON Links (Base, Target, Type);
-CREATE TABLE Groups (
-  id serial NOT NULL  ,
-  Name varchar(16)   ,
-  Description varchar(64)   ,
-  Pseudo integer NOT NULL DEFAULT 0 ,
-  PRIMARY KEY (id)
+CREATE UNIQUE INDEX Links1 ON Links (Base, Target, Type) ;
+
+-- }}}
+
+-- {{{ Principals
+
+
+
+--
+-- Sequences for table PRINCIPALS
+--
+
+CREATE SEQUENCE principals_id_seq;
+
+CREATE TABLE Principals (
+        id INTEGER DEFAULT nextval('principals_id_seq') not null,
+        PrincipalType VARCHAR(16) not null,
+        ObjectId integer, 
+        Disabled int2 NOT NULL DEFAULT 0 ,
+        PRIMARY KEY (id)
+
 );
-CREATE UNIQUE INDEX Groups1 ON Groups (Name);
-CREATE TABLE Watchers (
-  id serial NOT NULL  ,
-  Type varchar(16)   ,
-  Scope varchar(16)   ,
-  Value integer   ,
-  Email varchar(255)   ,
-  Quiet integer   ,
-  Owner integer   ,
-  Creator integer   ,
-  Created timestamp   ,
-  LastUpdatedBy integer   ,
-  LastUpdated timestamp   ,
+
+CREATE INDEX Principals2 ON Principals (ObjectId);
+
+
+-- }}}
+
+-- {{{ Groups
+
+
+
+--
+-- Sequences for table GROUPS
+--
+
+CREATE SEQUENCE groups_id_seq;
+
+CREATE TABLE Groups (
+  id INTEGER DEFAULT nextval('groups_id_seq'),
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  Domain varchar(64),
+  Type varchar(64),
+  Instance varchar(64),
   PRIMARY KEY (id)
+
 );
-CREATE INDEX Watchers1 ON Watchers (Scope, Value, Type, Owner);
+CREATE UNIQUE INDEX Groups1 ON Groups (Domain,Instance,Type,id, Name);
+CREATE INDEX Groups2 On Groups  (Type, Instance, Domain);
+
+
+-- }}}
+
+-- {{{ ScripConditions
+
+
+
+--
+-- Sequences for table SCRIPCONDITIONS
+--
+
+CREATE SEQUENCE scripconditions_id_seq;
+
 CREATE TABLE ScripConditions (
-  id serial NOT NULL  ,
-  Name varchar(255)   ,
-  Description varchar(255)   ,
-  ExecModule varchar(60)   ,
-  Argument varchar(255)   ,
-  ApplicableTransTypes varchar(60)   ,
-  Creator integer   ,
-  Created timestamp   ,
-  LastUpdatedBy integer   ,
-  LastUpdated timestamp   ,
+  id INTEGER DEFAULT nextval('scripconditions_id_seq'),
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  ExecModule varchar(60) NULL  ,
+  Argument varchar(255) NULL  ,
+  ApplicableTransTypes varchar(60) NULL  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated TIMESTAMP NULL  ,
   PRIMARY KEY (id)
+
 );
+
+-- }}}
+
+-- {{{ Transactions
+
+
+--
+-- Sequences for table TRANSACTIONS
+--
+
+CREATE SEQUENCE transactions_id_seq;
+
 CREATE TABLE Transactions (
-  id serial NOT NULL  ,
-  EffectiveTicket integer   ,
-  Ticket integer   ,
-  TimeTaken integer   ,
-  Type varchar(20)   ,
-  Field varchar(40)   ,
-  OldValue varchar(255)   ,
-  NewValue varchar(255)   ,
-  Data varchar(100)   ,
-  Creator integer   ,
-  Created timestamp   ,
+  id INTEGER DEFAULT nextval('transactions_id_seq'),
+  EffectiveTicket integer NOT NULL DEFAULT 0  ,
+  Ticket integer NOT NULL DEFAULT 0  ,
+  TimeTaken integer NOT NULL DEFAULT 0  ,
+  Type varchar(20) NULL  ,
+  Field varchar(40) NULL  ,
+  OldValue varchar(255) NULL  ,
+  NewValue varchar(255) NULL  ,
+  Data varchar(100) NULL  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
   PRIMARY KEY (id)
+
 );
 CREATE INDEX Transactions1 ON Transactions (Ticket);
 CREATE INDEX Transactions2 ON Transactions (EffectiveTicket);
+
+-- }}}
+
+-- {{{ Scrips 
+
+
+
+--
+-- Sequences for table SCRIPS
+--
+
+CREATE SEQUENCE scrips_id_seq;
+
 CREATE TABLE Scrips (
-  id serial NOT NULL  ,
-  ScripCondition integer   ,
-  ScripAction integer   ,
-  Stage varchar(32)   ,
-  Queue integer   ,
-  Template integer   ,
-  Creator integer   ,
-  Created timestamp   ,
-  LastUpdatedBy integer   ,
-  LastUpdated timestamp   ,
+  id INTEGER DEFAULT nextval('scrips_id_seq'),
+  Description varchar(255),
+  ScripCondition integer NOT NULL DEFAULT 0  ,
+  ScripAction integer NOT NULL DEFAULT 0  ,
+  ConditionRules text NULL  ,
+  ActionRules text NULL  ,
+  CustomIsApplicableCode text NULL  ,
+  CustomPrepareCode text NULL  ,
+  CustomCommitCode text NULL  ,
+  Stage varchar(32) NULL  ,
+  Queue integer NOT NULL DEFAULT 0  ,
+  Template integer NOT NULL DEFAULT 0  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated TIMESTAMP NULL  ,
   PRIMARY KEY (id)
+
 );
+
+-- }}}
+
+-- {{{ ACL
+
+
+--
+-- Sequences for table ACL
+--
+
+CREATE SEQUENCE acl_id_seq;
+
 CREATE TABLE ACL (
-  id serial NOT NULL  ,
-  PrincipalId integer   ,
-  PrincipalType varchar(25)   ,
-  RightName varchar(25)   ,
-  RightScope varchar(25)   ,
-  RightAppliesTo integer   ,
+  id INTEGER DEFAULT nextval('acl_id_seq'),
+  PrincipalType varchar(25) NOT NULL, 
+
+  PrincipalId integer NOT NULL  , 
+  RightName varchar(25) NOT NULL  ,
+  ObjectType varchar(25) NOT NULL  ,
+  ObjectId integer NOT NULL DEFAULT 0,
+  DelegatedBy integer NOT NULL DEFAULT 0, 
+  DelegatedFrom integer NOT NULL DEFAULT 0, 
   PRIMARY KEY (id)
+
 );
-CREATE INDEX ACL1 ON ACL (RightScope, PrincipalId);
-CREATE INDEX ACL2 ON ACL (RightScope, RightAppliesTo, RightName, PrincipalType, PrincipalId);
+
+CREATE INDEX  ACL1 on ACL(RightName, ObjectType, ObjectId,PrincipalType,PrincipalId);
+
+
+-- }}}
+
+-- {{{ GroupMembers 
+
+
+
+--
+-- Sequences for table GROUPMEMBERS
+--
+
+CREATE SEQUENCE groupmembers_id_seq;
+
 CREATE TABLE GroupMembers (
-  id serial NOT NULL  ,
-  GroupId integer   ,
-  UserId integer   ,
-  PRIMARY KEY (id)
-);
-CREATE UNIQUE INDEX GroupMembers1 ON GroupMembers (GroupId, UserId);
-CREATE TABLE ObjectKeywords (
-  id serial NOT NULL  ,
-  Keyword integer NOT NULL  ,
-  KeywordSelect integer NOT NULL  ,
-  ObjectType varchar(32) NOT NULL  ,
-  ObjectId integer NOT NULL  ,
+  id INTEGER DEFAULT nextval('groupmembers_id_seq'),
+  GroupId integer NOT NULL DEFAULT 0,
+  MemberId integer NOT NULL DEFAULT 0,  
   PRIMARY KEY (id)
+
 );
-CREATE UNIQUE INDEX ObjectKeywords1 ON ObjectKeywords (ObjectId, ObjectType, KeywordSelect, Keyword);
-CREATE INDEX ObjectKeywords2 ON ObjectKeywords (ObjectId, ObjectType);
-CREATE INDEX ObjectKeywords3 ON ObjectKeywords (Keyword);
-CREATE TABLE Keywords (
-  id serial NOT NULL  ,
-  Name varchar(255) NOT NULL  ,
-  Description varchar(255)   ,
-  Parent integer   ,
-  Disabled int2 NOT NULL DEFAULT 0 ,
-  PRIMARY KEY (id)
+
+-- }}}
+
+-- {{{ GroupMembersCache
+
+
+
+--
+-- Sequences for table CACHEDGROUPMEMBERS
+--
+
+CREATE SEQUENCE cachedgroupmembers_id_seq;
+
+CREATE TABLE CachedGroupMembers (
+        id int DEFAULT nextval('cachedgroupmembers_id_seq'),
+        GroupId int, 
+        MemberId int, 
+        Via int, 
+        ImmediateParentId int, 
+        Disabled int2 NOT NULL DEFAULT 0 , 
+        PRIMARY KEY (id)
+
 );
-CREATE UNIQUE INDEX Keywords1 ON Keywords (Name, Parent);
-CREATE INDEX Keywords2 ON Keywords (Name);
-CREATE INDEX Keywords3 ON Keywords (Parent);
+
+CREATE INDEX CachedGroupMembers2 on CachedGroupMembers (MemberId);
+CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (GroupId);
+CREATE INDEX DisGrouMem  on CachedGroupMembers (GroupId,MemberId,Disabled); 
+
+-- }}}
+
+-- {{{ Users
+
+
+
+--
+-- Sequences for table USERS
+--
+
+CREATE SEQUENCE users_id_seq;
+
 CREATE TABLE Users (
-  id serial NOT NULL  ,
-  Name varchar(120) NOT NULL  ,
-  Password varchar(40)   ,
-  Comments TEXT   ,
-  Signature TEXT   ,
-  EmailAddress varchar(120)   ,
-  FreeformContactInfo TEXT   ,
-  Organization varchar(200)   ,
-  Privileged integer   ,
-  RealName varchar(120)   ,
-  Nickname varchar(16)   ,
-  Lang varchar(16)   ,
-  EmailEncoding varchar(16)   ,
-  WebEncoding varchar(16)   ,
-  ExternalContactInfoId varchar(100)   ,
-  ContactInfoSystem varchar(30)   ,
-  ExternalAuthId varchar(100)   ,
-  AuthSystem varchar(30)   ,
-  Gecos varchar(16)   ,
-  HomePhone varchar(30)   ,
-  WorkPhone varchar(30)   ,
-  MobilePhone varchar(30)   ,
-  PagerPhone varchar(30)   ,
-  Address1 varchar(200)   ,
-  Address2 varchar(200)   ,
-  City varchar(100)   ,
-  State varchar(100)   ,
-  Zip varchar(16)   ,
-  Country varchar(50)   ,
-  Creator integer   ,
-  Created timestamp   ,
-  LastUpdatedBy integer   ,
-  LastUpdated timestamp   ,
-  Disabled int2 NOT NULL DEFAULT 0 ,
+  id INTEGER DEFAULT nextval('users_id_seq'),
+  Name varchar(200) NOT NULL  ,
+  Password varchar(40) NULL  ,
+  Comments text NULL  ,
+  Signature text NULL  ,
+  EmailAddress varchar(120) NULL  ,
+  FreeformContactInfo text NULL  ,
+  Organization varchar(200) NULL  ,
+  RealName varchar(120) NULL  ,
+  NickName varchar(16) NULL  ,
+  Lang varchar(16) NULL  ,
+  EmailEncoding varchar(16) NULL  ,
+  WebEncoding varchar(16) NULL  ,
+  ExternalContactInfoId varchar(100) NULL  ,
+  ContactInfoSystem varchar(30) NULL  ,
+  ExternalAuthId varchar(100) NULL  ,
+  AuthSystem varchar(30) NULL  ,
+  Gecos varchar(16) NULL  ,
+  HomePhone varchar(30) NULL  ,
+  WorkPhone varchar(30) NULL  ,
+  MobilePhone varchar(30) NULL  ,
+  PagerPhone varchar(30) NULL  ,
+  Address1 varchar(200) NULL  ,
+  Address2 varchar(200) NULL  ,
+  City varchar(100) NULL  ,
+  State varchar(100) NULL  ,
+  Zip varchar(16) NULL  ,
+  Country varchar(50) NULL  ,
+  Timezone varchar(50) NULL  ,
+  PGPKey text NULL,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated TIMESTAMP NULL  ,
   PRIMARY KEY (id)
+
 );
-CREATE UNIQUE INDEX Users1 ON Users (Name);
+
+
+CREATE UNIQUE INDEX Users1 ON Users (Name) ;
+CREATE INDEX Users2 ON Users (Name);
 CREATE INDEX Users3 ON Users (id, EmailAddress);
 CREATE INDEX Users4 ON Users (EmailAddress);
+
+
+-- }}}
+
+-- {{{ Tickets
+
+
+
+--
+-- Sequences for table TICKETS
+--
+
+CREATE SEQUENCE tickets_id_seq;
+
 CREATE TABLE Tickets (
-  id serial NOT NULL  ,
-  EffectiveId integer   ,
-  Queue integer   ,
-  Type varchar(16)   ,
-  IssueStatement integer   ,
-  Resolution integer   ,
-  Owner integer   ,
-  Subject varchar(200)  DEFAULT '[no subject]' ,
-  InitialPriority integer   ,
-  FinalPriority integer   ,
-  Priority integer   ,
-  Status varchar(10)   ,
-  TimeWorked integer   ,
-  TimeLeft integer   ,
-  Told timestamp   ,
-  Starts timestamp   ,
-  Started timestamp   ,
-  Due timestamp   ,
-  Resolved timestamp   ,
-  LastUpdatedBy integer   ,
-  LastUpdated timestamp   ,
-  Creator integer   ,
-  Created timestamp   ,
+  id INTEGER DEFAULT nextval('tickets_id_seq'),
+  EffectiveId integer NOT NULL DEFAULT 0  ,
+  Queue integer NOT NULL DEFAULT 0  ,
+  Type varchar(16) NULL  ,
+  IssueStatement integer NOT NULL DEFAULT 0  ,
+  Resolution integer NOT NULL DEFAULT 0  ,
+  Owner integer NOT NULL DEFAULT 0  ,
+  Subject varchar(200) NULL DEFAULT '[no subject]' ,
+  InitialPriority integer NOT NULL DEFAULT 0  ,
+  FinalPriority integer NOT NULL DEFAULT 0  ,
+  Priority integer NOT NULL DEFAULT 0  ,
+  TimeEstimated integer NOT NULL DEFAULT 0  ,
+  TimeWorked integer NOT NULL DEFAULT 0  ,
+  Status varchar(10) NULL  ,
+  TimeLeft integer NOT NULL DEFAULT 0  ,
+  Told TIMESTAMP NULL  ,
+  Starts TIMESTAMP NULL  ,
+  Started TIMESTAMP NULL  ,
+  Due TIMESTAMP NULL  ,
+  Resolved TIMESTAMP NULL  ,
+
+
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated TIMESTAMP NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
   Disabled int2 NOT NULL DEFAULT 0 ,
   PRIMARY KEY (id)
+
 );
-CREATE INDEX Tickets1 ON Tickets (Queue, Status);
-CREATE INDEX Tickets2 ON Tickets (Owner);
-CREATE INDEX Tickets3 ON Tickets (EffectiveId);
-CREATE INDEX Tickets4 ON Tickets (id, Status);
-CREATE INDEX Tickets5 ON Tickets (id, EffectiveId);
+
+CREATE INDEX Tickets1 ON Tickets (Queue, Status) ;
+CREATE INDEX Tickets2 ON Tickets (Owner) ;
+CREATE INDEX Tickets3 ON Tickets (EffectiveId) ;
+CREATE INDEX Tickets4 ON Tickets (id, Status) ;
+CREATE INDEX Tickets5 ON Tickets (id, EffectiveId) ;
+
+-- }}}
+
+-- {{{ ScripActions
+
+
+
+--
+-- Sequences for table SCRIPACTIONS
+--
+
+CREATE SEQUENCE scripactions_id_seq;
+
 CREATE TABLE ScripActions (
-  id serial NOT NULL  ,
-  Name varchar(255)   ,
-  Description varchar(255)   ,
-  ExecModule varchar(60)   ,
-  Argument varchar(255)   ,
-  Creator integer   ,
-  Created timestamp   ,
-  LastUpdatedBy integer   ,
-  LastUpdated timestamp   ,
+  id INTEGER DEFAULT nextval('scripactions_id_seq'),
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  ExecModule varchar(60) NULL  ,
+  Argument varchar(255) NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated TIMESTAMP NULL  ,
   PRIMARY KEY (id)
+
 );
+
+-- }}}
+
+-- {{{ Templates
+
+
+
+--
+-- Sequences for table TEMPLATES
+--
+
+CREATE SEQUENCE templates_id_seq;
+
 CREATE TABLE Templates (
-  id serial NOT NULL  ,
+  id INTEGER DEFAULT nextval('templates_id_seq'),
+  Queue integer NOT NULL DEFAULT 0 ,
+  Name varchar(200) NOT NULL  ,
+  Description varchar(255) NULL  ,
+  Type varchar(16) NULL  ,
+  Language varchar(16) NULL  ,
+  TranslationOf integer NOT NULL DEFAULT 0  ,
+  Content text NULL  ,
+  LastUpdated TIMESTAMP NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
+  PRIMARY KEY (id)
+
+);
+
+-- }}}
+
+-- {{{ TicketCustomFieldValues 
+
+
+
+--
+-- Sequences for table TICKETCUSTOMFIELDVALUES
+--
+
+CREATE SEQUENCE ticketcustomfieldvalues_id_s;
+
+CREATE TABLE TicketCustomFieldValues (
+  id INTEGER DEFAULT nextval('ticketcustomfieldvalues_id_s'),
+  Ticket int NOT NULL  ,
+  CustomField int NOT NULL  ,
+  Content varchar(255) NULL  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated TIMESTAMP NULL  ,
+  PRIMARY KEY (id)
+
+);
+
+-- }}}
+
+-- {{{ CustomFields
+
+
+
+--
+-- Sequences for table CUSTOMFIELDS
+--
+
+CREATE SEQUENCE customfields_id_seq;
+
+CREATE TABLE CustomFields (
+  id INTEGER DEFAULT nextval('customfields_id_seq'),
+  Name varchar(200) NULL  ,
+  Type varchar(200) NULL  ,
   Queue integer NOT NULL DEFAULT 0 ,
-  Name varchar(40) NOT NULL  ,
-  Description varchar(120)   ,
-  Type varchar(16)   ,
-  Language varchar(16)   ,
-  TranslationOf integer   ,
-  Content TEXT   ,
-  LastUpdated timestamp   ,
-  LastUpdatedBy integer   ,
-  Creator integer   ,
-  Created timestamp   ,
+  Description varchar(255) NULL  ,
+  SortOrder integer NOT NULL DEFAULT 0  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated TIMESTAMP NULL  ,
+  Disabled int2 NOT NULL DEFAULT 0 ,
   PRIMARY KEY (id)
+
+);
+
+-- }}}
+
+-- {{{ CustomFieldValues 
+
+
+
+--
+-- Sequences for table CUSTOMFIELDVALUES
+--
+
+CREATE SEQUENCE customfieldvalues_id_seq;
+
+CREATE TABLE CustomFieldValues (
+  id INTEGER DEFAULT nextval('customfieldvalues_id_seq'),
+  CustomField int NOT NULL  ,
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  SortOrder integer NOT NULL DEFAULT 0  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created TIMESTAMP NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated TIMESTAMP NULL  ,
+  PRIMARY KEY (id)
+
+);
+
+-- }}}
+
+-- {{{ Sessions
+
+-- sessions is used by Apache::Session to keep sessions in the database.
+-- We should have a reaper script somewhere.
+
+CREATE TABLE sessions (
+    id char(32) NOT NULL,
+    a_session bytea,
+    LastUpdated TIMESTAMP not null default current_timestamp,
+    PRIMARY KEY (id)
+
 );
+
+-- }}}
+
+
+
+COMMIT;
diff --git a/rt/etc/schema.SQLite b/rt/etc/schema.SQLite
new file mode 100644 (file)
index 0000000..f24bdbd
--- /dev/null
@@ -0,0 +1,384 @@
+--- {{{ Attachments
+
+CREATE TABLE Attachments (
+  id INTEGER PRIMARY KEY  ,
+  TransactionId INTEGER  ,
+  Parent integer NULL  ,
+  MessageId varchar(160) NULL  ,
+  Subject varchar(255) NULL  ,
+  Filename varchar(255) NULL  ,
+  ContentType varchar(80) NULL  ,
+  ContentEncoding varchar(80) NULL  ,
+  Content LONGTEXT NULL  ,
+  Headers LONGTEXT NULL  ,
+  Creator integer NULL  ,
+  Created DATETIME NULL 
+  
+) ;
+
+CREATE INDEX Attachments1 ON Attachments (Parent) ;
+CREATE INDEX Attachments2 ON Attachments (TransactionId) ;
+CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId) ;
+--- }}}
+
+--- {{{ Queues
+CREATE TABLE Queues (
+  id INTEGER PRIMARY KEY  ,
+  Name varchar(200) NOT NULL  ,
+  Description varchar(255) NULL  ,
+  CorrespondAddress varchar(120) NULL  ,
+  CommentAddress varchar(120) NULL  ,
+  InitialPriority integer NULL  ,
+  FinalPriority integer NULL  ,
+  DefaultDueIn integer NULL  ,
+  Creator integer NULL  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NULL  ,
+  LastUpdated DATETIME NULL  ,
+  Disabled int2 NOT NULL DEFAULT 0 
+) ;
+CREATE UNIQUE INDEX Queues1 ON Queues (Name) ;
+
+--- }}}
+
+--- {{{ Links
+
+CREATE TABLE Links (
+  id INTEGER PRIMARY KEY  ,
+  Base varchar(240) NULL  ,
+  Target varchar(240) NULL  ,
+  Type varchar(20) NOT NULL  ,
+  LocalTarget integer NULL  ,
+  LocalBase integer NULL  ,
+  LastUpdatedBy integer NULL  ,
+  LastUpdated DATETIME NULL  ,
+  Creator integer NULL  ,
+  Created DATETIME NULL  
+  
+) ;
+CREATE UNIQUE INDEX Links1 ON Links (Base, Target, Type) ;
+
+--- }}}
+
+--- {{{ Principals
+
+CREATE TABLE Principals (
+        id INTEGER PRIMARY KEY,
+        PrincipalType VARCHAR(16) not null,
+        ObjectId integer,
+        Disabled int2 NOT NULL DEFAULT 0 
+        
+) ;
+
+--- }}}
+
+--- {{{ Groups
+
+CREATE TABLE Groups (
+  id INTEGER ,
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  Domain varchar(64),
+  Type varchar(64),
+  Instance varchar(64)
+  
+) ;
+
+CREATE UNIQUE INDEX Groups1 ON Groups (Name,Domain,Type,Instance) ;
+
+--- }}}
+
+--- {{{ ScripConditions
+
+CREATE TABLE ScripConditions (
+  id INTEGER PRIMARY KEY  ,
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  ExecModule varchar(60) NULL  ,
+  Argument varchar(255) NULL  ,
+  ApplicableTransTypes varchar(60) NULL  ,
+
+  Creator integer NULL  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NULL  ,
+  LastUpdated DATETIME NULL  
+  
+) ;
+
+--- }}}
+
+--- {{{ Transactions
+CREATE TABLE Transactions (
+  id INTEGER PRIMARY KEY  ,
+  EffectiveTicket integer NULL  ,
+  Ticket integer NULL  ,
+  TimeTaken integer NULL  ,
+  Type varchar(20) NULL  ,
+  Field varchar(40) NULL  ,
+  OldValue varchar(255) NULL  ,
+  NewValue varchar(255) NULL  ,
+  Data varchar(100) NULL  ,
+
+  Creator integer NULL  ,
+  Created DATETIME NULL  
+  
+) ;
+CREATE INDEX Transactions1 ON Transactions (Ticket);
+CREATE INDEX Transactions2 ON Transactions (EffectiveTicket);
+
+--- }}}
+
+--- {{{ Scrips 
+
+CREATE TABLE Scrips (
+  id INTEGER PRIMARY KEY  ,
+  Description varchar(255),
+  ScripCondition integer NULL  ,
+  ScripAction integer NULL  ,
+  ConditionRules text NULL  ,
+  ActionRules text NULL  ,
+  CustomIsApplicableCode text NULL  ,
+  CustomPrepareCode text NULL  ,
+  CustomCommitCode text NULL  ,
+  Stage varchar(32) NULL  ,
+  Queue integer NULL  ,
+  Template integer NULL  ,
+  Creator integer NULL  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NULL  ,
+  LastUpdated DATETIME NULL  
+  
+) ;
+
+--- }}}
+
+--- {{{ ACL
+CREATE TABLE ACL (
+  id INTEGER PRIMARY KEY  ,
+  PrincipalType varchar(25) NOT NULL,
+
+  PrincipalId INTEGER,
+  RightName varchar(25) NOT NULL  ,
+  ObjectType varchar(25) NOT NULL  ,
+  ObjectId INTEGER default 0,
+  DelegatedBy integer NOT NULL default 0, 
+  DelegatedFrom integer NOT NULL default 0
+  
+) ;
+
+
+--- }}}
+
+--- {{{ GroupMembers 
+
+CREATE TABLE GroupMembers (
+  id INTEGER PRIMARY KEY  ,
+  GroupId integer NULL,
+  MemberId integer NULL
+  
+) ;
+
+--- }}}
+
+--- {{{ CachedGroupMembers
+
+create table CachedGroupMembers (
+        id integer primary key ,
+        GroupId int, 
+        MemberId int, 
+        Via int, 
+        ImmediateParentId int,
+        Disabled int2 NOT NULL DEFAULT 0  # if this cached group member is a member of this group by way of a disabled
+                                           # group or this group is disabled, this will be set to 1
+                                           # this allows us to not find members of disabled subgroups when listing off
+                                           # group members recursively.
+                                           # Also, this allows us to have the ACL system elide members of disabled groups
+
+        
+) ;
+
+--- }}}
+
+--- {{{ Users
+
+CREATE TABLE Users (
+  id INTEGER ,
+  Name varchar(200) NOT NULL  ,
+  Password varchar(40) NULL  ,
+  Comments blob NULL  ,
+  Signature blob NULL  ,
+  EmailAddress varchar(120) NULL  ,
+  FreeformContactInfo blob NULL  ,
+  Organization varchar(200) NULL  ,
+  RealName varchar(120) NULL  ,
+  NickName varchar(16) NULL  ,
+  Lang varchar(16) NULL  ,
+  EmailEncoding varchar(16) NULL  ,
+  WebEncoding varchar(16) NULL  ,
+  ExternalContactInfoId varchar(100) NULL  ,
+  ContactInfoSystem varchar(30) NULL  ,
+  ExternalAuthId varchar(100) NULL  ,
+  AuthSystem varchar(30) NULL  ,
+  Gecos varchar(16) NULL  ,
+  HomePhone varchar(30) NULL  ,
+  WorkPhone varchar(30) NULL  ,
+  MobilePhone varchar(30) NULL  ,
+  PagerPhone varchar(30) NULL  ,
+  Address1 varchar(200) NULL  ,
+  Address2 varchar(200) NULL  ,
+  City varchar(100) NULL  ,
+  State varchar(100) NULL  ,
+  Zip varchar(16) NULL  ,
+  Country varchar(50) NULL  ,
+  Timezone char(50) NULL  ,
+  PGPKey text NULL,
+
+  Creator integer NULL  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NULL  ,
+  LastUpdated DATETIME NULL  
+  
+) ;
+
+
+CREATE UNIQUE INDEX Users1 ON Users (Name) ;
+CREATE INDEX Users2 ON Users (Name);
+CREATE INDEX Users3 ON Users (id, EmailAddress);
+CREATE INDEX Users4 ON Users (EmailAddress);
+
+
+--- }}}
+
+--- {{{ Tickets
+
+CREATE TABLE Tickets (
+  id INTEGER PRIMARY KEY  ,
+  EffectiveId integer NULL  ,
+  Queue integer NULL  ,
+  Type varchar(16) NULL  ,
+  IssueStatement integer NULL  ,
+  Resolution integer NULL  ,
+  Owner integer NULL  ,
+  Subject varchar(200) NULL DEFAULT '[no subject]' ,
+  InitialPriority integer NULL  ,
+  FinalPriority integer NULL  ,
+  Priority integer NULL  ,
+  TimeEstimated integer NULL  ,
+  TimeWorked integer NULL  ,
+  Status varchar(10) NULL  ,
+  TimeLeft integer NULL  ,
+  Told DATETIME NULL  ,
+  Starts DATETIME NULL  ,
+  Started DATETIME NULL  ,
+  Due DATETIME NULL  ,
+  Resolved DATETIME NULL  ,
+
+
+  LastUpdatedBy integer NULL  ,
+  LastUpdated DATETIME NULL  ,
+  Creator integer NULL  ,
+  Created DATETIME NULL  ,
+  Disabled int2 NOT NULL DEFAULT 0
+  
+) ;
+
+CREATE INDEX Tickets1 ON Tickets (Queue, Status) ;
+CREATE INDEX Tickets2 ON Tickets (Owner) ;
+CREATE INDEX Tickets3 ON Tickets (EffectiveId) ;
+CREATE INDEX Tickets4 ON Tickets (id, Status) ;
+CREATE INDEX Tickets5 ON Tickets (id, EffectiveId) ;
+
+--- }}}
+
+--- {{{ ScripActions
+
+CREATE TABLE ScripActions (
+  id INTEGER PRIMARY KEY  ,
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  ExecModule varchar(60) NULL  ,
+  Argument varchar(255) NULL  ,
+  Creator integer NULL  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NULL  ,
+  LastUpdated DATETIME NULL  
+  
+) ;
+
+--- }}}
+
+--- {{{ Templates
+
+CREATE TABLE Templates (
+  id INTEGER PRIMARY KEY  ,
+  Queue integer NOT NULL DEFAULT 0 ,
+  Name varchar(200) NOT NULL  ,
+  Description varchar(255) NULL  ,
+  Type varchar(16) NULL  ,
+  Language varchar(16) NULL  ,
+  TranslationOf integer NULL  ,
+  Content blob NULL  ,
+  LastUpdated DATETIME NULL  ,
+  LastUpdatedBy integer NULL  ,
+  Creator integer NULL  ,
+  Created DATETIME NULL  
+  
+) ;
+
+--- }}}
+
+--- {{{ TicketCustomFieldValues 
+
+CREATE TABLE TicketCustomFieldValues (
+  id INTEGER PRIMARY KEY  ,
+  Ticket int NOT NULL  ,
+  CustomField int NOT NULL  ,
+  Content varchar(255) NULL  ,
+
+  Creator integer NULL  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NULL  ,
+  LastUpdated DATETIME NULL  
+  
+) ;
+
+--- }}}
+
+--- {{{ CustomFields
+
+CREATE TABLE CustomFields (
+  id INTEGER PRIMARY KEY  ,
+  Name varchar(200) NULL  ,
+  Type varchar(200) NULL  ,
+  Queue int NULL ,
+  Description varchar(255) NULL  ,
+  SortOrder integer NULL  ,
+
+  Creator integer NULL  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NULL  ,
+  LastUpdated DATETIME NULL ,
+  Disabled int2 NOT NULL DEFAULT 0 
+  
+) ;
+
+--- }}}
+
+--- {{{ CustomFieldValues 
+
+CREATE TABLE CustomFieldValues (
+  id INTEGER PRIMARY KEY  ,
+  CustomField int NOT NULL  ,
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  SortOrder integer NULL  ,
+
+  Creator integer NULL  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NULL  ,
+  LastUpdated DATETIME NULL 
+  
+) ;
+
+--- }}}
index 7e715c2..46f8ec5 100755 (executable)
@@ -1,21 +1,9 @@
-CREATE TABLE KeywordSelects (
-  id INTEGER NOT NULL  AUTO_INCREMENT,
-  Name varchar(255) NULL  ,
-  Keyword integer NULL  ,
-  Single integer NULL  ,
-  Depth integer NOT NULL DEFAULT 0 ,
-  ObjectType varchar(32) NOT NULL  ,
-  ObjectField varchar(32) NULL  ,
-  ObjectValue varchar(255) NULL  ,
-  Disabled int2 NOT NULL DEFAULT 0 ,
-  PRIMARY KEY (id)
-);
-CREATE INDEX KeywordSelects1 ON KeywordSelects (Keyword);
-CREATE INDEX KeywordSelects2 ON KeywordSelects (ObjectType, ObjectField, ObjectValue);
+# {{{ Attachments
+
 CREATE TABLE Attachments (
   id INTEGER NOT NULL  AUTO_INCREMENT,
   TransactionId integer NOT NULL  ,
-  Parent integer NULL  ,
+  Parent integer NOT NULL DEFAULT 0  ,
   MessageId varchar(160) NULL  ,
   Subject varchar(255) NULL  ,
   Filename varchar(255) NULL  ,
@@ -23,161 +11,222 @@ CREATE TABLE Attachments (
   ContentEncoding varchar(80) NULL  ,
   Content LONGTEXT NULL  ,
   Headers LONGTEXT NULL  ,
-  Creator integer NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,
   PRIMARY KEY (id)
-);
-CREATE INDEX Attachments1 ON Attachments (Parent);
-CREATE INDEX Attachments2 ON Attachments (TransactionId);
-CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId);
+) TYPE=InnoDB;
+
+CREATE INDEX Attachments1 ON Attachments (Parent) ;
+CREATE INDEX Attachments2 ON Attachments (TransactionId) ;
+CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId) ;
+# }}}
+
+# {{{ Queues
 CREATE TABLE Queues (
   id INTEGER NOT NULL  AUTO_INCREMENT,
-  Name varchar(120) NOT NULL  ,
-  Description varchar(120) NULL  ,
+  Name varchar(200) NOT NULL  ,
+  Description varchar(255) NULL  ,
   CorrespondAddress varchar(120) NULL  ,
   CommentAddress varchar(120) NULL  ,
-  InitialPriority integer NULL  ,
-  FinalPriority integer NULL  ,
-  DefaultDueIn integer NULL  ,
-  Creator integer NULL  ,
+  InitialPriority integer NOT NULL DEFAULT 0  ,
+  FinalPriority integer NOT NULL DEFAULT 0  ,
+  DefaultDueIn integer NOT NULL DEFAULT 0  ,
+  Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,
-  LastUpdatedBy integer NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
   LastUpdated DATETIME NULL  ,
   Disabled int2 NOT NULL DEFAULT 0 ,
   PRIMARY KEY (id)
-);
-CREATE UNIQUE INDEX Queues1 ON Queues (Name);
+) TYPE=InnoDB;
+CREATE UNIQUE INDEX Queues1 ON Queues (Name) ;
+CREATE INDEX Queues2 ON Queues (Disabled) ;
+
+# }}}
+
+# {{{ Links
+
 CREATE TABLE Links (
   id INTEGER NOT NULL  AUTO_INCREMENT,
   Base varchar(240) NULL  ,
   Target varchar(240) NULL  ,
   Type varchar(20) NOT NULL  ,
-  LocalTarget integer NULL  ,
-  LocalBase integer NULL  ,
-  LastUpdatedBy integer NULL  ,
+  LocalTarget integer NOT NULL DEFAULT 0  ,
+  LocalBase integer NOT NULL DEFAULT 0  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
   LastUpdated DATETIME NULL  ,
-  Creator integer NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,
   PRIMARY KEY (id)
-);
-CREATE UNIQUE INDEX Links1 ON Links (Base, Target, Type);
+) TYPE=InnoDB;
+
+CREATE UNIQUE INDEX Links1 ON Links (Base, Target, Type) ;
+CREATE INDEX Links2 ON Links (Base,  Type) ;
+CREATE INDEX Links3 ON Links (Target,  Type) ;
+
+# }}}
+
+# {{{ Principals
+
+CREATE TABLE Principals (
+        id INTEGER  AUTO_INCREMENT not null,
+        PrincipalType VARCHAR(16) not null,
+        ObjectId integer, # foreign key to Users or Groups, depending
+        Disabled int2 NOT NULL DEFAULT 0 ,
+        PRIMARY KEY (id)
+) TYPE=InnoDB;
+
+CREATE INDEX Principals2 ON Principals (ObjectId);
+
+# }}}
+
+# {{{ Groups
+
 CREATE TABLE Groups (
   id INTEGER NOT NULL  AUTO_INCREMENT,
-  Name varchar(16) NULL  ,
-  Description varchar(64) NULL  ,
-  Pseudo integer NOT NULL DEFAULT 0 ,
-  PRIMARY KEY (id)
-);
-CREATE UNIQUE INDEX Groups1 ON Groups (Name);
-CREATE TABLE Watchers (
-  id INTEGER NOT NULL  AUTO_INCREMENT,
-  Type varchar(16) NULL  ,
-  Scope varchar(16) NULL  ,
-  Value integer NULL  ,
-  Email varchar(255) NULL  ,
-  Quiet integer NULL  ,
-  Owner integer NULL  ,
-  Creator integer NULL  ,
-  Created DATETIME NULL  ,
-  LastUpdatedBy integer NULL  ,
-  LastUpdated DATETIME NULL  ,
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  Domain varchar(64),
+  Type varchar(64),
+  Instance varchar(64),
   PRIMARY KEY (id)
-);
-CREATE INDEX Watchers1 ON Watchers (Scope, Value, Type, Owner);
+) TYPE=InnoDB;
+
+CREATE INDEX Groups1 ON Groups (Domain,Instance,Type,id);
+CREATE INDEX Groups2 On Groups  (Type, Instance, Domain);   
+
+# }}}
+
+# {{{ ScripConditions
+
 CREATE TABLE ScripConditions (
   id INTEGER NOT NULL  AUTO_INCREMENT,
-  Name varchar(255) NULL  ,
+  Name varchar(200) NULL  ,
   Description varchar(255) NULL  ,
   ExecModule varchar(60) NULL  ,
   Argument varchar(255) NULL  ,
   ApplicableTransTypes varchar(60) NULL  ,
-  Creator integer NULL  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,
-  LastUpdatedBy integer NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
   LastUpdated DATETIME NULL  ,
   PRIMARY KEY (id)
-);
+) TYPE=InnoDB;
+
+# }}}
+
+# {{{ Transactions
 CREATE TABLE Transactions (
   id INTEGER NOT NULL  AUTO_INCREMENT,
-  EffectiveTicket integer NULL  ,
-  Ticket integer NULL  ,
-  TimeTaken integer NULL  ,
+  EffectiveTicket integer NOT NULL DEFAULT 0  ,
+  Ticket integer NOT NULL DEFAULT 0  ,
+  TimeTaken integer NOT NULL DEFAULT 0  ,
   Type varchar(20) NULL  ,
   Field varchar(40) NULL  ,
   OldValue varchar(255) NULL  ,
   NewValue varchar(255) NULL  ,
   Data varchar(100) NULL  ,
-  Creator integer NULL  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,
   PRIMARY KEY (id)
-);
+) TYPE=InnoDB;
 CREATE INDEX Transactions1 ON Transactions (Ticket);
 CREATE INDEX Transactions2 ON Transactions (EffectiveTicket);
+
+# }}}
+
+# {{{ Scrips 
+
 CREATE TABLE Scrips (
   id INTEGER NOT NULL  AUTO_INCREMENT,
-  ScripCondition integer NULL  ,
-  ScripAction integer NULL  ,
+  Description varchar(255),
+  ScripCondition integer NOT NULL DEFAULT 0  ,
+  ScripAction integer NOT NULL DEFAULT 0  ,
+  ConditionRules text NULL  ,
+  ActionRules text NULL  ,
+  CustomIsApplicableCode text NULL  ,
+  CustomPrepareCode text NULL  ,
+  CustomCommitCode text NULL  ,
   Stage varchar(32) NULL  ,
-  Queue integer NULL  ,
-  Template integer NULL  ,
-  Creator integer NULL  ,
+  Queue integer NOT NULL DEFAULT 0  ,
+  Template integer NOT NULL DEFAULT 0  ,
+  Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,
-  LastUpdatedBy integer NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
   LastUpdated DATETIME NULL  ,
   PRIMARY KEY (id)
-);
+) TYPE=InnoDB;
+
+# }}}
+
+# {{{ ACL
 CREATE TABLE ACL (
   id INTEGER NOT NULL  AUTO_INCREMENT,
-  PrincipalId integer NULL  ,
-  PrincipalType varchar(25) NULL  ,
-  RightName varchar(25) NULL  ,
-  RightScope varchar(25) NULL  ,
-  RightAppliesTo integer NULL  ,
+  PrincipalType varchar(25) NOT NULL, #"User" "Group", "Owner", "Cc" "AdminCc", "Requestor", "Requestor" 
+
+  PrincipalId integer NOT NULL  , #Foreign key to principals
+  RightName varchar(25) NOT NULL  ,
+  ObjectType varchar(25) NOT NULL  ,
+  ObjectId integer NOT NULL default 0,
+  DelegatedBy integer NOT NULL default 0, #foreign key to principals with a userid
+  DelegatedFrom integer NOT NULL default 0, #foreign key to ACL
   PRIMARY KEY (id)
-);
-CREATE INDEX ACL1 ON ACL (RightScope, PrincipalId);
-CREATE INDEX ACL2 ON ACL (RightScope, RightAppliesTo, RightName, PrincipalType, PrincipalId);
+) TYPE=InnoDB;
+
+CREATE INDEX  ACL1 on ACL(RightName, ObjectType, ObjectId,PrincipalType,PrincipalId);
+
+# }}}
+
+# {{{ GroupMembers 
+
 CREATE TABLE GroupMembers (
   id INTEGER NOT NULL  AUTO_INCREMENT,
-  GroupId integer NULL  ,
-  UserId integer NULL  ,
-  PRIMARY KEY (id)
-);
-CREATE UNIQUE INDEX GroupMembers1 ON GroupMembers (GroupId, UserId);
-CREATE TABLE ObjectKeywords (
-  id INTEGER NOT NULL  AUTO_INCREMENT,
-  Keyword integer NOT NULL  ,
-  KeywordSelect integer NOT NULL  ,
-  ObjectType varchar(32) NOT NULL  ,
-  ObjectId integer NOT NULL  ,
-  PRIMARY KEY (id)
-);
-CREATE UNIQUE INDEX ObjectKeywords1 ON ObjectKeywords (ObjectId, ObjectType, KeywordSelect, Keyword);
-CREATE INDEX ObjectKeywords2 ON ObjectKeywords (ObjectId, ObjectType);
-CREATE INDEX ObjectKeywords3 ON ObjectKeywords (Keyword);
-CREATE TABLE Keywords (
-  id INTEGER NOT NULL  AUTO_INCREMENT,
-  Name varchar(255) NOT NULL  ,
-  Description varchar(255) NULL  ,
-  Parent integer NULL  ,
-  Disabled int2 NOT NULL DEFAULT 0 ,
+  GroupId integer NOT NULL DEFAULT 0,
+  MemberId integer NOT NULL DEFAULT 0,  #Foreign key to Principals
   PRIMARY KEY (id)
-);
-CREATE UNIQUE INDEX Keywords1 ON Keywords (Name, Parent);
-CREATE INDEX Keywords2 ON Keywords (Name);
-CREATE INDEX Keywords3 ON Keywords (Parent);
+) TYPE=InnoDB;
+CREATE UNIQUE INDEX GroupMembers1 on GroupMembers (GroupId, MemberId);
+
+
+# }}}
+
+# {{{ GroupMembersCache
+
+create table CachedGroupMembers (
+        id int auto_increment,
+        GroupId int, # foreign key to Principals
+        MemberId int, # foreign key to Principals
+        Via int, #foreign key to CachedGroupMembers. (may point to $self->id)
+        ImmediateParentId int, #foreign key to prinicpals.         
+                               # this points to the group that the member is
+                               # a member of, for ease of deletes.
+        Disabled int2 NOT NULL DEFAULT 0 , # if this cached group member is a member of this group by way of a disabled
+                                           # group or this group is disabled, this will be set to 1
+                                           # this allows us to not find members of disabled subgroups when listing off
+                                           # group members recursively.
+                                           # Also, this allows us to have the ACL system elide members of disabled groups
+        PRIMARY KEY (id)
+) TYPE=InnoDB;
+
+CREATE INDEX DisGrouMem  on CachedGroupMembers (GroupId,MemberId,Disabled);
+CREATE INDEX GrouMem  on CachedGroupMembers (GroupId,MemberId);
+
+# }}}
+
+# {{{ Users
+
 CREATE TABLE Users (
   id INTEGER NOT NULL  AUTO_INCREMENT,
-  Name varchar(120) NOT NULL  ,
+  Name varchar(200) NOT NULL  ,
   Password varchar(40) NULL  ,
   Comments blob NULL  ,
   Signature blob NULL  ,
   EmailAddress varchar(120) NULL  ,
   FreeformContactInfo blob NULL  ,
   Organization varchar(200) NULL  ,
-  Privileged integer NULL  ,
   RealName varchar(120) NULL  ,
-  Nickname varchar(16) NULL  ,
+  NickName varchar(16) NULL  ,
   Lang varchar(16) NULL  ,
   EmailEncoding varchar(16) NULL  ,
   WebEncoding varchar(16) NULL  ,
@@ -196,72 +245,172 @@ CREATE TABLE Users (
   State varchar(100) NULL  ,
   Zip varchar(16) NULL  ,
   Country varchar(50) NULL  ,
-  Creator integer NULL  ,
+  Timezone varchar(50) NULL  ,
+  PGPKey text NULL,
+
+  Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,
-  LastUpdatedBy integer NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
   LastUpdated DATETIME NULL  ,
-  Disabled int2 NOT NULL DEFAULT 0 ,
   PRIMARY KEY (id)
-);
-CREATE UNIQUE INDEX Users1 ON Users (Name);
+) TYPE=InnoDB;
+
+
+CREATE UNIQUE INDEX Users1 ON Users (Name) ;
+CREATE INDEX Users2 ON Users (Name);
 CREATE INDEX Users3 ON Users (id, EmailAddress);
 CREATE INDEX Users4 ON Users (EmailAddress);
+
+
+# }}}
+
+# {{{ Tickets
+
 CREATE TABLE Tickets (
   id INTEGER NOT NULL  AUTO_INCREMENT,
-  EffectiveId integer NULL  ,
-  Queue integer NULL  ,
+  EffectiveId integer NOT NULL DEFAULT 0  ,
+  Queue integer NOT NULL DEFAULT 0  ,
   Type varchar(16) NULL  ,
-  IssueStatement integer NULL  ,
-  Resolution integer NULL  ,
-  Owner integer NULL  ,
+  IssueStatement integer NOT NULL DEFAULT 0  ,
+  Resolution integer NOT NULL DEFAULT 0  ,
+  Owner integer NOT NULL DEFAULT 0  ,
   Subject varchar(200) NULL DEFAULT '[no subject]' ,
-  InitialPriority integer NULL  ,
-  FinalPriority integer NULL  ,
-  Priority integer NULL  ,
+  InitialPriority integer NOT NULL DEFAULT 0  ,
+  FinalPriority integer NOT NULL DEFAULT 0  ,
+  Priority integer NOT NULL DEFAULT 0  ,
+  TimeEstimated integer NOT NULL DEFAULT 0  ,
+  TimeWorked integer NOT NULL DEFAULT 0  ,
   Status varchar(10) NULL  ,
-  TimeWorked integer NULL  ,
-  TimeLeft integer NULL  ,
+  TimeLeft integer NOT NULL DEFAULT 0  ,
   Told DATETIME NULL  ,
   Starts DATETIME NULL  ,
   Started DATETIME NULL  ,
   Due DATETIME NULL  ,
   Resolved DATETIME NULL  ,
-  LastUpdatedBy integer NULL  ,
+
+
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
   LastUpdated DATETIME NULL  ,
-  Creator integer NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,
   Disabled int2 NOT NULL DEFAULT 0 ,
   PRIMARY KEY (id)
-);
-CREATE INDEX Tickets1 ON Tickets (Queue, Status);
-CREATE INDEX Tickets2 ON Tickets (Owner);
-CREATE INDEX Tickets3 ON Tickets (EffectiveId);
-CREATE INDEX Tickets4 ON Tickets (id, Status);
-CREATE INDEX Tickets5 ON Tickets (id, EffectiveId);
+) TYPE=InnoDB;
+
+CREATE INDEX Tickets1 ON Tickets (Queue, Status) ;
+CREATE INDEX Tickets2 ON Tickets (Owner) ;
+CREATE INDEX Tickets3 ON Tickets (EffectiveId) ;
+CREATE INDEX Tickets4 ON Tickets (id, Status) ;
+CREATE INDEX Tickets5 ON Tickets (id, EffectiveId) ;
+CREATE INDEX Tickets6 ON Tickets (EffectiveId, Type) ;
+
+# }}}
+
+# {{{ ScripActions
+
 CREATE TABLE ScripActions (
   id INTEGER NOT NULL  AUTO_INCREMENT,
-  Name varchar(255) NULL  ,
+  Name varchar(200) NULL  ,
   Description varchar(255) NULL  ,
   ExecModule varchar(60) NULL  ,
   Argument varchar(255) NULL  ,
-  Creator integer NULL  ,
+  Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,
-  LastUpdatedBy integer NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
   LastUpdated DATETIME NULL  ,
   PRIMARY KEY (id)
-);
+) TYPE=InnoDB;
+
+# }}}
+
+# {{{ Templates
+
 CREATE TABLE Templates (
   id INTEGER NOT NULL  AUTO_INCREMENT,
   Queue integer NOT NULL DEFAULT 0 ,
-  Name varchar(40) NOT NULL  ,
-  Description varchar(120) NULL  ,
+  Name varchar(200) NOT NULL  ,
+  Description varchar(255) NULL  ,
   Type varchar(16) NULL  ,
   Language varchar(16) NULL  ,
-  TranslationOf integer NULL  ,
+  TranslationOf integer NOT NULL DEFAULT 0  ,
   Content blob NULL  ,
   LastUpdated DATETIME NULL  ,
-  LastUpdatedBy integer NULL  ,
-  Creator integer NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  PRIMARY KEY (id)
+) TYPE=InnoDB;
+
+# }}}
+
+# {{{ TicketCustomFieldValues 
+
+CREATE TABLE TicketCustomFieldValues (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Ticket int NOT NULL  ,
+  CustomField int NOT NULL  ,
+  Content varchar(255) NULL  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  PRIMARY KEY (id)
+) TYPE=InnoDB;
+
+# }}}
+
+# {{{ CustomFields
+
+CREATE TABLE CustomFields (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Name varchar(200) NULL  ,
+  Type varchar(200) NULL  ,
+  Queue integer NOT NULL DEFAULT 0 ,
+  Description varchar(255) NULL  ,
+  SortOrder integer NOT NULL DEFAULT 0  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
+  Disabled int2 NOT NULL DEFAULT 0 ,
+  PRIMARY KEY (id)
+) TYPE=InnoDB;
+
+CREATE INDEX CustomFields1 on CustomFields (Disabled, Queue);
+
+
+# }}}
+
+# {{{ CustomFieldValues 
+
+CREATE TABLE CustomFieldValues (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  CustomField int NOT NULL  ,
+  Name varchar(200) NULL  ,
+  Description varchar(255) NULL  ,
+  SortOrder integer NOT NULL DEFAULT 0  ,
+
+  Creator integer NOT NULL DEFAULT 0  ,
+  Created DATETIME NULL  ,
+  LastUpdatedBy integer NOT NULL DEFAULT 0  ,
+  LastUpdated DATETIME NULL  ,
   PRIMARY KEY (id)
+) TYPE=InnoDB;
+
+# }}}
+
+# {{{ Sessions
+
+# sessions is used by Apache::Session to keep sessions in the database.
+# We should have a reaper script somewhere.
+
+CREATE TABLE sessions (
+    id char(32) NOT NULL,
+    a_session LONGTEXT,
+    LastUpdated TIMESTAMP,
+    PRIMARY KEY (id)
 );
+
+# }}}
diff --git a/rt/etc/schema.pm b/rt/etc/schema.pm
deleted file mode 100644 (file)
index 44e143e..0000000
+++ /dev/null
@@ -1,349 +0,0 @@
-#   column, type, nullability, length, default, database-local
-
-my $gratuitous = {
-
-'Groups' => {
-  'columns' => [
-    'id', 'serial', '', '', '', '',
-    'Name', 'varchar', 'NULL', '16', '', '',
-    'Description', 'varchar', 'NULL', '64', '', '',
-    'Pseudo', 'integer', '', '', '0', '',
-  ],
-  'primary_key' => 'id',
-  'unique' => [ ['Name'] ],
-  'index' => [  ],
-},
-
-'ACL' => {
-  'columns' => [
-    'id', 'serial', '', '', '', '',
-    'PrincipalId', 'integer', 'NULL', '', '', '',
-    'PrincipalType', 'varchar', 'NULL', '25', '', '',
-    'RightName', 'varchar', 'NULL', '25', '', '',
-    'RightScope', 'varchar', 'NULL', '25', '', '',
-    'RightAppliesTo', 'integer', 'NULL', '', '', '',
-  ],
-  'primary_key' => 'id',
-  'unique' => [  ],
-  'index' => [ ['RightScope', 'PrincipalId'], 
-              ['RightScope','RightAppliesTo','RightName','PrincipalType','PrincipalId'] ],
-},
-
-'Watchers' => {
-  'columns' => [
-    'id', 'serial', '', '', '', '',
-    'Type', 'varchar', 'NULL', '16', '', '',
-    'Scope', 'varchar', 'NULL', '16', '', '',
-    'Value', 'integer', 'NULL', '', '', '',
-    'Email', 'varchar', 'NULL', '255', '', '',
-    'Quiet', 'integer', 'NULL', '', '', '',
-    'Owner', 'integer', 'NULL', '', '', '',
-    'Creator', 'integer', 'NULL', '', '', '',
-    'Created', 'timestamp', 'NULL', '', '', '',
-    'LastUpdatedBy', 'integer', 'NULL', '', '', '',
-    'LastUpdated', 'timestamp', 'NULL', '', '', '',
-  ],
-  'primary_key' => 'id',
-  'unique' => [  ],
-  'index' => [ ['Scope','Value','Type','Owner'] ],
-},
-
-'Links' => {
-  'columns' => [
-    'id', 'serial', '', '', '', '',
-    'Base', 'varchar', 'NULL', '240', '', '',
-    'Target', 'varchar', 'NULL', '240', '', '',
-    'Type', 'varchar', '', '20', '', '',
-    'LocalTarget', 'integer', 'NULL', '', '', '',
-    'LocalBase', 'integer', 'NULL', '', '', '',
-    'LastUpdatedBy', 'integer', 'NULL', '', '', '',
-    'LastUpdated', 'timestamp', 'NULL', '', '', '',
-    'Creator', 'integer', 'NULL', '', '', '',
-    'Created', 'timestamp', 'NULL', '', '', '',
-  ],
-  'primary_key' => 'id',
-  'unique' => [ ['Base', 'Target', 'Type'] ],
-  'index' => [  ],
-},
-
-'Users' => {
-  'columns' => [
-    'id', 'serial', '', '', '', '',
-    'Name', 'varchar', '', '120', '', '',
-    'Password', 'varchar', 'NULL', '40', '', '',
-    'Comments', 'blob', 'NULL', '', '', '',
-    'Signature', 'blob', 'NULL', '', '', '',
-    'EmailAddress', 'varchar', 'NULL', '120', '', '',
-    'FreeformContactInfo', 'blob', 'NULL', '', '', '',
-    'Organization', 'varchar', 'NULL', '200', '', '',
-    'Privileged', 'integer', 'NULL', '', '', '',
-    'RealName', 'varchar', 'NULL', '120', '', '',
-    'Nickname', 'varchar', 'NULL', '16', '', '',
-    'Lang', 'varchar', 'NULL', '16', '', '',
-    'EmailEncoding', 'varchar', 'NULL', '16', '', '',
-    'WebEncoding', 'varchar', 'NULL', '16', '', '',
-    'ExternalContactInfoId', 'varchar', 'NULL', '100', '', '',
-    'ContactInfoSystem', 'varchar', 'NULL', '30', '', '',
-    'ExternalAuthId', 'varchar', 'NULL', '100', '', '',
-    'AuthSystem', 'varchar', 'NULL', '30', '', '',
-    'Gecos', 'varchar', 'NULL', '16', '', '',
-    'HomePhone', 'varchar', 'NULL', '30', '', '',
-    'WorkPhone', 'varchar', 'NULL', '30', '', '',
-    'MobilePhone', 'varchar', 'NULL', '30', '', '',
-    'PagerPhone', 'varchar', 'NULL', '30', '', '',
-    'Address1', 'varchar', 'NULL', '200', '', '',
-    'Address2', 'varchar', 'NULL', '200', '', '',
-    'City', 'varchar', 'NULL', '100', '', '',
-    'State', 'varchar', 'NULL', '100', '', '',
-    'Zip', 'varchar', 'NULL', '16', '', '',
-    'Country', 'varchar', 'NULL', '50', '', '',
-    'Creator', 'integer', 'NULL', '', '', '',
-    'Created', 'timestamp', 'NULL', '', '', '',
-    'LastUpdatedBy', 'integer', 'NULL', '', '', '',
-    'LastUpdated', 'timestamp', 'NULL', '', '', '',
-    'Disabled', 'int2', '','','0','',
-  ],
-  'primary_key' => 'id',
-  'unique' => [ ['Name'] ],
-  'index' => [ ['Name'], 
-              ['id', 'EmailAddress'],
-              ['EmailAddress'] ],
-},
-
-'Tickets' => {
-  'columns' => [
-    'id', 'serial', '', '', '', '',
-    'EffectiveId', 'integer', 'NULL', '', '', '',
-    'Queue', 'integer', 'NULL', '', '', '',
-    'Type', 'varchar', 'NULL', '16', '', '',
-    'IssueStatement', 'integer', 'NULL', '', '', '',
-    'Resolution', 'integer', 'NULL', '', '', '',
-    'Owner', 'integer', 'NULL', '', '', '',
-    'Subject', 'varchar', 'NULL', '200', '[no subject]', '',
-    'InitialPriority', 'integer', 'NULL', '', '', '',
-    'FinalPriority', 'integer', 'NULL', '', '', '',
-    'Priority', 'integer', 'NULL', '', '', '',
-    'Status', 'varchar', 'NULL', '10', '', '',
-    'TimeWorked', 'integer', 'NULL', '', '', '',
-    'TimeLeft', 'integer', 'NULL', '', '', '',
-    'Told', 'timestamp', 'NULL', '', '', '',
-    'Starts', 'timestamp', 'NULL', '', '', '',
-    'Started', 'timestamp', 'NULL', '', '', '',
-    'Due', 'timestamp', 'NULL', '', '', '',
-    'Resolved', 'timestamp', 'NULL', '', '', '',
-    'LastUpdatedBy', 'integer', 'NULL', '', '', '',
-    'LastUpdated', 'timestamp', 'NULL', '', '', '',
-    'Creator', 'integer', 'NULL', '', '', '',
-    'Created', 'timestamp', 'NULL', '', '', '',
-    'Disabled', 'int2', '','','0','',
-  ],
-  'primary_key' => 'id',
-  'unique' => [ [] ],
-  'index' => [ ['Queue', 'Status'], 
-              ['Owner'], 
-              ['EffectiveId'], 
-              ['id', 'Status'], 
-              ['id', 'EffectiveId'] ],
-},
-
-'GroupMembers' => {
-  'columns' => [
-    'id', 'serial', '', '', '', '',
-    'GroupId', 'integer', 'NULL', '', '', '', #foreign key, Groups::id
-    'UserId', 'integer', 'NULL', '', '', '', #foreign key, Users::id
-  ],
-  'primary_key' => 'id',
-  'unique' => [ ['GroupId', 'UserId']  ],
-  'index' => [  ],
-},
-
-'Queues' => {
-  'columns' => [
-    'id', 'serial', '', '', '', '',
-    'Name', 'varchar', '', '120', '', '', #Textual 'name' for this queue
-    'Description', 'varchar', 'NULL', '120', '', '', #Textual descr. of this
-    #queue
-    'CorrespondAddress', 'varchar', 'NULL', '120', '', '',
-    'CommentAddress', 'varchar', 'NULL', '120', '', '',
-    'InitialPriority', 'integer', 'NULL', '', '', '',
-    'FinalPriority', 'integer', 'NULL', '', '', '',
-    'DefaultDueIn', 'integer', 'NULL', '', '', '',
-
-    'Creator', 'integer', 'NULL', '', '', '',
-    'Created', 'timestamp', 'NULL', '', '', '',
-    'LastUpdatedBy', 'integer', 'NULL', '', '', '',
-    'LastUpdated', 'timestamp', 'NULL', '', '', '',
-    'Disabled', 'int2', '','','0','',
-  ],
-  'primary_key' => 'id',
-  'unique' => [ ['Name'] ],
-  'index' => [  ],
-},
-
-'Transactions' => {
-  'columns' => [
-    'id', 'serial', '', '', '', '',
-    'EffectiveTicket', 'integer', 'NULL', '', '', '', 
-    'Ticket', 'integer', 'NULL', '', '', '',  #Foreign key Ticket::id
-    'TimeTaken', 'integer', 'NULL', '', '', '', #Time spent on this trans in min
-    'Type', 'varchar', 'NULL', '20', '', '',
-    'Field', 'varchar', 'NULL', '40', '', '', #If it's a "Set" transaction, what
-    #field was set.
-    'OldValue', 'varchar', 'NULL', '255', '', '', 
-    'NewValue', 'varchar', 'NULL', '255', '', '',
-    'Data', 'varchar', 'NULL', '100', '', '',
-
-
-    'Creator', 'integer', 'NULL', '', '', '',
-    'Created', 'timestamp', 'NULL', '', '', '',
-
-  ],
-  'primary_key' => 'id',
-  'unique' => [  ],
-  'index' => [ ['Ticket'], ['EffectiveTicket'] ],
-},
-
-'ScripActions' => {
-  'columns' => [
-               'id', 'serial', '', '', '', '',
-               'Name', 'varchar', 'NULL', '255', '', '',  # Alias
-               'Description', 'varchar', 'NULL', '255', '', '', #Textual description
-               'ExecModule', 'varchar', 'NULL', '60', '', '', #This calles RT::Action::___
-               'Argument', 'varchar', 'NULL', '255', '', '', #We can pass a single argument
-               #to the scrip. sometimes, it's who to send mail to.
-               'Creator', 'integer', 'NULL', '', '', '',
-               'Created', 'timestamp', 'NULL', '', '', '',
-               'LastUpdatedBy', 'integer', 'NULL', '', '', '',
-               'LastUpdated', 'timestamp', 'NULL', '', '', '',
-  ],
-  'primary_key' => 'id',
-  'unique' => [  ],
-  'index' => [  ],
-},
-
-'ScripConditions' => {
-  'columns' => [
-               'id', 'serial', '', '', '', '',
-               'Name', 'varchar', 'NULL', '255', '', '',  # Alias
-               'Description', 'varchar', 'NULL', '255', '', '', #Textual description
-               'ExecModule', 'varchar', 'NULL', '60', '', '', #This calles RT::Condition::
-               'Argument', 'varchar', 'NULL', '255', '', '', #We can pass a single argument
-               #to the scrip. sometimes, it's who to send mail to.
-               'ApplicableTransTypes', 'varchar', 'NULL', '60', '', '',#Transaction types this scrip
-               # acts on. comma or / delimited is just great.
-               'Creator', 'integer', 'NULL', '', '', '',
-               'Created', 'timestamp', 'NULL', '', '', '',
-               'LastUpdatedBy', 'integer', 'NULL', '', '', '',
-               'LastUpdated', 'timestamp', 'NULL', '', '', '',
-  ],
-  'primary_key' => 'id',
-  'unique' => [  ],
-  'index' => [  ],
-},
-'Scrips' => {
-                'columns' => [
-                              'id', 'serial', '', '', '', '',
-                              'ScripCondition', 'integer', 'NULL', '', '', '', #Foreign key ScripConditions::id
-                              'ScripAction', 'integer', 'NULL', '', '', '', #Foreign key ScripActions::id
-                              'Stage', 'varchar', 'NULL', '32','','', #What stage does this scrip
-                              #Happen in.  for now, everything is 'TransactionCreate',
-                              'Queue', 'integer', 'NULL', '', '', '', #Foreign key Queues::id
-                              'Template', 'integer', 'NULL', '', '', '', #Foreign key Templates::id
-                              
-                              'Creator', 'integer', 'NULL', '', '', '',
-                              'Created', 'timestamp', 'NULL', '', '', '',
-                              'LastUpdatedBy', 'integer', 'NULL', '', '', '',
-                              'LastUpdated', 'timestamp', 'NULL', '', '', '',
-                             ],
-                'primary_key' => 'id',
-                'unique' => [  ],
-                'index' => [  ],
-},
-
-'Attachments' => {
-  'columns' => [
-    'id', 'serial', '', '', '', '',
-    'TransactionId', 'integer', '', '', '', '', #Foreign key Transactions::Id
-    'Parent', 'integer', 'NULL', '', '', '', # Attachments::Id
-    'MessageId', 'varchar', 'NULL', '160', '', '', #RFC822 messageid, if any
-    'Subject', 'varchar', 'NULL', '255', '', '', 
-    'Filename', 'varchar', 'NULL', '255', '', '',
-    'ContentType', 'varchar', 'NULL', '80', '', '',
-    'ContentEncoding', 'varchar', 'NULL', '80', '', '',
-    'Content', 'long varbinary', 'NULL', '', '', '',
-    'Headers', 'long varbinary', 'NULL', '', '', '',
-
-    'Creator', 'integer', 'NULL', '', '', '',
-    'Created', 'timestamp', 'NULL', '', '', '',
-
-  ],
-  'primary_key' => 'id',
-  'unique' => [  ],
-  'index' => [ ['Parent'], ['TransactionId'], ['Parent', 'TransactionId'] ],
-},
-
-'Templates' => {
-  'columns' => [
-    'id', 'serial', '', '', '', '',
-    'Queue', 'integer', 'NOT NULL', '', '0', '',
-    'Name', 'varchar', '', '40', '', '',
-    'Description', 'varchar', 'NULL', '120', '', '',
-    'Type', 'varchar', 'NULL', '16', '','',
-    'Language', 'varchar', 'NULL', '16', '', '',
-    'TranslationOf', 'integer', 'NULL', '', '', '',
-    'Content', 'blob', 'NULL', '', '', '',
-    'LastUpdated', 'timestamp', 'NULL', '', '', '',
-    'LastUpdatedBy', 'integer', 'NULL', '', '', '',
-    'Creator', 'integer', 'NULL', '', '', '',
-    'Created', 'timestamp', 'NULL', '', '', '',
-  ],
-  'primary_key' => 'id',
-  'unique' => [ [''] ],
-  'index' => [  ],
-},
-
-'Keywords' => {
-  'columns' => [
-    'id', 'serial', '', '', '', '',
-    'Name', 'varchar', 'NOT NULL', '255', '', '',
-    'Description', 'varchar', 'NULL', '255', '', '',
-    'Parent', 'integer', 'NULL', '', '', '',
-    'Disabled', 'int2', '','','0','',
-],
-  'primary_key' => 'id',
-  'unique' => [ [ 'Name', 'Parent' ] ],
-  'index' => [ [ 'Name', ], [ 'Parent' ] ],
-},
-
-'ObjectKeywords' => {
-  'columns' =>  [
-    'id', 'serial', '', '', '', '',
-    'Keyword', 'integer', 'NOT NULL', '', '', '',
-    'KeywordSelect', 'integer', 'NOT NULL', '', '', '',
-    'ObjectType', 'varchar', 'NOT NULL', '32', '', '',
-    'ObjectId', 'integer', 'NOT NULL', '', '', '',
-  ],
-  'primary_key' => 'id',
-  'unique' => [ [  'ObjectId', 'ObjectType','KeywordSelect', 'Keyword' ] ],
-  'index' => [ [ 'ObjectId', 'ObjectType'  ] , ['Keyword'] ],
-
-},
-
-'KeywordSelects' => {
-  'columns' =>  [
-    'id', 'serial', '', '', '', '',
-    'Name','varchar','NULL','255','','',
-    'Keyword', 'integer', 'NULL', '', '', '',
-    'Single', 'integer', 'NULL', '', '', '',
-    'Depth', 'integer', 'NOT NULL', '', 0, '',
-    'ObjectType', 'varchar', 'NOT NULL',  '32', '', '',
-    'ObjectField', 'varchar', 'NULL', '32', '', '',
-    'ObjectValue', 'varchar', 'NULL', '255', '', '',
-    'Disabled', 'int2', '','','0','',
-  ],
-  'primary_key' => 'id',
-  'unique' => [ [ ] ],
-  'index' => [ [ 'Keyword' ], [ 'ObjectType', 'ObjectField', 'ObjectValue'] ],
-},
-
-};
diff --git a/rt/etc/upgrade/2.1.71 b/rt/etc/upgrade/2.1.71
new file mode 100644 (file)
index 0000000..cb89a3a
--- /dev/null
@@ -0,0 +1,211 @@
+@Queues = ( {
+        Name        => '___Approvals',
+    Description => 'A system-internal queue for the approvals system',
+        Disabled    => 2,
+        }
+);
+
+
+
+
+
+# {{{ Templates
+@Templates = (
+    {
+        Queue       => '___Approvals',
+        Name        => "New Pending Approval", # loc
+        Description => "Notify Owners and AdminCcs of new items pending their approval", # loc
+       Content     => 'Subject: New Pending Approval: {$Ticket->Subject}
+
+Greetings,
+
+There is a new item pending your approval: "{$Ticket->Subject()}", 
+a summary of which appears below.
+
+Please visit {$RT::WebURL}Approvals/Display.html?id={$Ticket->id}
+to approve or reject this ticket, or {$RT::WebURL}Approvals/ to
+batch-process all your pending approvals.
+
+-------------------------------------------------------------------------
+{$Transaction->Content()}
+'
+    },
+);
+
+# }}}
+
+1;
+
+@ScripActions = (
+     { Name => 'Open Tickets',
+       Description => 'Open tickets on correspondence',
+        ExecModule => 'AutoOpen' },
+
+);
+
+ @Scrips = (
+        { ScripCondition => 'On Correspond',
+          ScripAction => 'Open Tickets',
+          Template => 'Blank',
+          Queue => '0'
+        }, 
+    {  ScripCondition => 'On Create',
+       ScripAction    => 'AutoReply To Requestors',
+       Template       => 'AutoReply' },
+    {  ScripCondition => 'On Create',
+       ScripAction    => 'Notify AdminCcs',
+       Template       => 'Transaction' },
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Notify AdminCcs',
+       Template       => 'Admin Correspondence' },
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Notify Requestors And Ccs',
+       Template       => 'Correspondence' },
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Notify Other Recipients',
+       Template       => 'Correspondence' },
+    {  ScripCondition => 'On Comment',
+       ScripAction    => 'Notify AdminCcs As Comment',
+       Template       => 'Admin Comment' },
+    {  ScripCondition => 'On Comment',
+       ScripAction    => 'Notify Other Recipients As Comment',
+       Template       => 'Correspondence' },
+    {  ScripCondition => 'On Resolve',
+       ScripAction    => 'Notify Requestors',
+       Template       => 'Resolved' },
+
+
+    {
+        Description    => "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval", # loc
+        Queue          => '___Approvals',
+        ScripCondition => 'On Create',
+        ScripAction    => 'Notify AdminCcs',
+        Template       => 'New Pending Approval'
+    },
+    {
+        Description           => "If an approval is rejected, reject the original and delete pending approvals",       # loc
+        Queue                  => '___Approvals',
+        ScripCondition         => 'On Status Change',
+        ScripAction            => 'User Defined',
+        CustomCommitCode       => q[
+# ------------------------------------------------------------------- #
+return(1) unless ( lc($self->TransactionObj->NewValue) eq "rejected" or
+                  lc($self->TransactionObj->NewValue) eq "deleted" );
+
+my $links = $self->TicketObj->DependedOnBy;
+foreach my $link (@{ $links->ItemsArrayRef }) {
+    my $obj = $link->BaseObj;
+    if ($obj->QueueObj->IsActiveStatus($obj->Status)) {
+       if ($obj->Type eq 'ticket') {
+           $obj->Correspond(
+               Content => $self->loc("Your request was rejected."),
+           );
+           $obj->SetStatus(
+               Status  => 'rejected',
+               Force   => 1,
+           );
+       }
+       else {
+           $obj->SetStatus(
+               Status  => 'deleted',
+               Force   => 1,
+           );
+       }
+    }
+}
+
+$links = $self->TicketObj->DependsOn;
+foreach my $link (@{ $links->ItemsArrayRef }) {
+    my $obj = $link->TargetObj;
+    if ($obj->QueueObj->IsActiveStatus($obj->Status)) {
+       $obj->SetStatus(
+           Status      => 'deleted',
+           Force       => 1,
+       );
+    }
+}
+
+return 1;
+# ------------------------------------------------------------------- #
+       ],
+        CustomPrepareCode => '1',
+        Template          => 'Admin Comment',
+    },
+    {
+        Description      => "When a ticket has been approved by any approver, add correspondence to the original ticket", # loc
+        Queue             => '___Approvals',
+        ScripCondition    => 'On Resolve',
+        ScripAction       => 'User Defined',
+        CustomPrepareCode => 'return(1);',
+        CustomCommitCode  => q[
+# ------------------------------------------------------------------- #
+return(1) unless ($self->TicketObj->Type eq 'approval');
+
+foreach my $obj ($self->TicketObj->AllDependedOnBy( Type => 'ticket' )) {
+    $obj->Correspond(
+       Content => $self->loc( "Your request has been approved by [_1]. Other approvals may still be pending.", # loc
+           $self->TransactionObj->CreatorObj->Name,
+       ) . "\n" . $self->loc( "Approver's notes: [_1]", # loc
+           $self->TicketObj->Transactions->Last->Content,
+       ),
+       _reopen => 0,
+    );
+}
+
+return 1;
+# ------------------------------------------------------------------- #
+       ],
+       Template => 'Admin Comment'
+    },
+    {
+        Description      => "When a ticket has been approved by all approvers, add correspondence to the original ticket", # loc
+        Queue             => '___Approvals',
+        ScripCondition    => 'On Resolve',
+        ScripAction       => 'User Defined',
+        CustomPrepareCode => 'return(1);',
+        CustomCommitCode  => q[
+# ------------------------------------------------------------------- #
+# Find all the tickets that depend on this (that this is approving)
+
+my $Ticket = $self->TicketObj;
+my @TOP    = $Ticket->AllDependedOnBy( Type => 'ticket' );
+my $links  = $Ticket->DependedOnBy;
+
+while (my $link = $links->Next) {
+    my $obj = $link->BaseObj;
+    next if ($obj->HasUnresolvedDependencies( Type => 'approval' ));
+
+    if ($obj->Type eq 'ticket') {
+       $obj->Correspond(
+           Content     => $self->loc("Your request has been approved."),
+           _reopen     => 0,
+       );
+    }
+    elsif ($obj->Type eq 'code') {
+       my $code = $obj->Transactions->First->Content;
+       my $rv;
+
+       foreach my $TOP (@TOP) {
+           local $@;
+           $rv++ if eval $code;
+           $RT::Logger->error("Cannot eval code: $@") if $@;
+       }
+
+       if ($rv or !@TOP) {
+           $obj->SetStatus( Status     => 'resolved', Force    => 1,);
+       }
+       else {
+           $obj->SetStatus( Status     => 'rejected', Force    => 1,);
+       }
+    }
+}
+
+return 1;
+# ------------------------------------------------------------------- #
+       ],
+        Template    => 'Admin Comment',
+    },
+);
+
+# }}}
+
diff --git a/rt/html/Admin/Elements/AddCustomFieldValue b/rt/html/Admin/Elements/AddCustomFieldValue
new file mode 100644 (file)
index 0000000..8850734
--- /dev/null
@@ -0,0 +1,44 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<b><&|/l&>Add Value</&></b></b></b></b>
+<TABLE BORDER="0">
+<TR><TD><small>
+<&|/l&>Sort</&>:<br>
+<input name="CustomField-<% $CustomField->Id %>-AddValue-SortOrder" size="5">
+</TD>
+<TD><small>
+<&|/l&>Name</&>:<br>
+<input size=20 name="CustomField-<% $CustomField->Id %>-AddValue-Name">
+</TD>
+<TD><small>
+<&|/l&>Description</&>:<br>
+<input size="60" name="CustomField-<% $CustomField->Id %>-AddValue-Description">
+</TD></TR>
+</TABLE>
+
+<%init>
+</%init>
+<%args>
+$CustomField => undef
+</%args>
diff --git a/rt/html/Admin/Elements/CreateUserCalled b/rt/html/Admin/Elements/CreateUserCalled
new file mode 100644 (file)
index 0000000..8ceccca
--- /dev/null
@@ -0,0 +1,26 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<FORM METHOD=get ACTION="<% $RT::WebPath %>/Admin/Users/Create.html">
+<&|/l&>New user called</&> <INPUT NAME="Name" size=10><input type=submit value="<&|/l&>Create</&>">
+</form>
diff --git a/rt/html/Admin/Elements/EditCustomField b/rt/html/Admin/Elements/EditCustomField
new file mode 100644 (file)
index 0000000..a09600b
--- /dev/null
@@ -0,0 +1,127 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/ListActions, actions => \@results &>
+
+
+<FORM METHOD=GET ACTION="CustomField.html">
+<INPUT TYPE=HIDDEN NAME="CustomField" VALUE="<%$id %>">
+<INPUT TYPE=HIDDEN name="Queue" value="<%$Queue%>">
+
+<TABLE WIDTH="100%" BORDER="0">
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Name</&>:
+</TD><TD>
+<input name="Name" VALUE="<%$CustomFieldObj->Name%>" SIZE=20>
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Description</&>:
+</TD><TD>
+<input name="Description" VALUE="<%$CustomFieldObj->Description%>" SIZE=80>
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Type</&>:
+</TD><TD>
+<& /Admin/Elements/SelectCustomFieldType, Name => "Type", Default => $CustomFieldObj->Type &>
+</TD></TR>
+<TR><TD>
+</TD><TD>
+<INPUT TYPE=HIDDEN NAME="SetEnabled" VALUE="1">
+<INPUT TYPE=CHECKBOX NAME="Enabled" VALUE="1" <%$EnabledChecked%>> <&|/l&>Enabled (Unchecking this box disables this custom field)</&>
+</TD></TR>
+</TABLE>
+
+<P>
+% if ($CustomFieldObj->Id and $CustomFieldObj->Type =~ /Select/) {
+<h2><&|/l&>Values</&></h2>
+<font size=-1>
+<& /Admin/Elements/EditCustomFieldValues, CustomField => $CustomFieldObj &>
+<& /Admin/Elements/AddCustomFieldValue, CustomField => $CustomFieldObj &>
+</font>
+% }
+<&/Elements/Submit&>
+</FORM>
+
+
+
+<%INIT>
+
+my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
+my $EnabledChecked = "CHECKED";
+my (@results);
+
+if (! $CustomField ) { 
+  $title = loc("Create a CustomField");
+  $id = 'new';
+} else {
+
+    if ($CustomField eq 'new') {
+      my ($val, $msg) =  $CustomFieldObj->Create(Queue => $Queue, 
+                                                 Name => $Name, 
+                                                 Type => $Type,
+                                                 Description => $Description,
+                                                );
+      Abort(loc("Could not create CustomField", $msg)) unless ($val);
+     push @results, $msg;
+     $CustomFieldObj->SetSortOrder($CustomFieldObj->id);
+     $title = loc('Created CustomField [_1]', $CustomFieldObj->Name()); 
+    } else {
+       $CustomFieldObj->Load($CustomField) || Abort(loc('No CustomField'));
+      $title = loc('Editing CustomField [_1]', $CustomFieldObj->Name()); 
+
+      my @aresults = ProcessCustomFieldUpdates ( 
+                        CustomFieldObj => $CustomFieldObj,
+                        ARGSRef => \%ARGS );
+     push @results, @aresults;
+    }
+
+
+$id = $CustomFieldObj->id;
+
+  #we're asking about enabled on the web page but really care about disabled.
+  my $Disabled = ($Enabled ? 0 : 1);
+
+  if  ( ($SetEnabled) and ( $Disabled != $CustomFieldObj->Disabled) ) { 
+      my  ($code, $msg) = $CustomFieldObj->SetDisabled($Disabled);
+      push @results, loc('Enabled status [_1]', loc_fuzzy($msg));
+  }
+  
+  if ($CustomFieldObj->Disabled()) {
+      $EnabledChecked ="";
+  }
+
+}
+
+
+</%INIT>
+<%ARGS>
+$id => undef
+$title => undef
+$Queue => undef
+$CustomField => undef
+$Type => undef
+$Description => undef
+$Name => undef
+$SetEnabled => undef
+$Enabled => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/EditCustomFieldValues b/rt/html/Admin/Elements/EditCustomFieldValues
new file mode 100644 (file)
index 0000000..64564ad
--- /dev/null
@@ -0,0 +1,42 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<i><&|/l&>(Check box to delete)</&></i>
+<ul>
+% while (my $v = $values->Next) {
+<li>
+<font size=-1 color="#336699"><%$v->SortOrder%>:</font>
+<input type="checkbox" name="CustomField-<%$CustomField->Id%>-DeleteValue" value="<%$v->id%>">
+<%$v->Name%>
+% if ($v->Description) {
+<i>(<%$v->Description%>)</i>
+% }
+</li>
+% }
+</ul>
+<%init>
+my $values = $CustomField->Values();
+</%init>
+<%args>
+$CustomField => undef
+</%args>
diff --git a/rt/html/Admin/Elements/EditCustomFields b/rt/html/Admin/Elements/EditCustomFields
new file mode 100644 (file)
index 0000000..a86b051
--- /dev/null
@@ -0,0 +1,214 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/ListActions, actions => \@actions &>
+
+<TABLE>
+<TR>
+<TD VALIGN=TOP>
+<%$caption%>:<BR>
+</TD></TR></TABLE>
+% if ($CustomFields->Count == 0 ) {
+<P><i><&|/l&>(No custom fields)</&></i></P>
+% } else {
+<TABLE>
+
+<TR>
+<TD ROWSPAN="<% $CustomFields->Count %>">
+<UL>
+% while (my $CustomFieldObj = $CustomFields->Next) { 
+<LI><A HREF="CustomField.html?Queue=<%$id%>&CustomField=<%$CustomFieldObj->id()%>"><b><%$CustomFieldObj->Name%></b></a> (<% $CustomFieldObj->FriendlyType %>)<br>
+<%$CustomFieldObj->Description%>
+</LI>
+% }
+</UL>
+</TD>
+
+% my $count;
+% while (my $CustomFieldObj = $CustomFields->Next) { 
+%  # show 'move up' unless it's the first item
+%  if ($count++) {
+<TR><TD>
+<a href="CustomFields.html?id=<%$id%>&CustomField=<%$CustomFieldObj->id%>&Move=-1"><&|/l&>Move up</&></a>
+%  } else {
+<TD ALIGN=RIGHT>
+%  }
+
+%  # show 'move down' unless it's the last item
+%  if (!$CustomFields->IsLast) {
+%  $m->print(' | ') if $count > 1;
+<a href="CustomFields.html?id=<%$id%>&CustomField=<%$CustomFieldObj->id%>&Move=1"><&|/l&>Move down</&></a>
+%  }
+</TD></TR>
+% }
+
+</TD>
+</TR>
+</TABLE>
+% }
+<FORM METHOD=GET ACTION="CustomFields.html">
+% if ($id) {
+<INPUT TYPE="Hidden" NAME="id" VALUE="<%$id%>">
+% }
+<input type="checkbox" name="FindDisabledCustomFields"> <&|/l&>Include disabled custom fields in listing.</&>
+<input type=submit value="<&|/l&>Go!</&>">
+</FORM>
+
+
+<%INIT>
+my $CustomFields = RT::CustomFields->new($session{'CurrentUser'});
+my $QueueObj = RT::Queue->new($session{'CurrentUser'});
+my $caption;
+
+if ($id)  {
+        $QueueObj->Load($id);                        
+}
+
+if ($QueueObj->id) {
+       $CustomFields->LimitToQueue($id);
+}                                            
+else {                                       
+        $CustomFields->LimitToGlobal();
+}                                           
+
+if ($FindDisabledCustomFields) {
+    $caption = loc("All Custom Fields");
+    $CustomFields->{'find_disabled_rows'} = 1;
+} else {
+    $caption = loc("Enabled Custom Fields");
+}
+
+# {{{ deal with moving sortorder of custom fields
+if ($CustomField and $Move) {
+    my $SourceObj = RT::CustomField->new($session{'CurrentUser'});
+    $SourceObj->Load($CustomField) || Abort(loc('No CustomField'));
+
+    my $TargetObj;
+    my $target_order = $SourceObj->SortOrder + $Move;
+    while (my $CustomFieldObj = $CustomFields->Next) { 
+       my $this_order = $CustomFieldObj->SortOrder;
+
+       # if we have an exact match, finish the loop now
+       ($TargetObj = $CustomFieldObj, last) if $this_order == $target_order;
+
+       # otherwise, we need to apropos toward the general direction
+       # ... first, check the sign is correct
+       next unless ($this_order - $SourceObj->SortOrder) * $Move > 0;
+
+       # ... next, see if we already have a candidate
+       if ($TargetObj) {
+           # ... if yes, compare the delta and choose the smaller one
+           my $orig_delta = abs($TargetObj->SortOrder - $target_order);
+           my $this_delta = abs($this_order - $target_order);
+           next if $orig_delta < $this_delta;
+       }
+
+       $TargetObj = $CustomFieldObj;
+    }
+
+    if ($TargetObj) {
+       # swap their sort order
+       my ($s, $t) = ($SourceObj->SortOrder, $TargetObj->SortOrder);
+       $TargetObj->SetSortOrder($s);
+       $SourceObj->SetSortOrder($t);
+       # because order changed, we must redo search for subsequent uses
+       $CustomFields->RedoSearch;
+    }
+
+    $CustomFields->GotoFirstItem;
+}
+# }}}
+
+# {{{ now process the 'copy queue' action
+my @actions;
+if ($Source and $Source ne $id) {
+    my $SourceQueue = RT::Queue->new($session{'CurrentUser'});
+    $SourceQueue->Load($Source) || Abort(loc("Couldn't load queue"));
+    my $SourceCustomFields = RT::CustomFields->new($session{'CurrentUser'});
+    $SourceCustomFields->LimitToQueue($SourceQueue->id);
+
+    # delete old fields
+    foreach my $CustomFieldObj ( @{$CustomFields->ItemsArrayRef} ) { 
+       $CustomFieldObj->Delete;
+    }
+
+    # add new fields
+    while (my $SourceCustomFieldObj = $SourceCustomFields->Next) {
+       my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
+       my ($val, $msg) =  $CustomFieldObj->Create(
+           id => $SourceCustomFieldObj->id,
+           Queue => $id,
+           Name => $SourceCustomFieldObj->Name,
+           Type => $SourceCustomFieldObj->Type,
+           Description => $SourceCustomFieldObj->Description,
+       );
+       Abort(loc("Could not create CustomField") . ": $msg") unless ($val);
+       push @actions, $msg;
+
+       $CustomFieldObj->SetSortOrder($SourceCustomFieldObj->SortOrder);
+
+       # add new values
+       my $values = $SourceCustomFieldObj->Values();
+       while (my $v = $values->Next) {
+           my ( $addval, $addmsg ) = $CustomFieldObj->AddValue(
+               Name => $v->Name,
+               Description => $v->Description,
+               SortOrder => $v->SortOrder
+           );
+       }
+    }
+
+    # because content changed, we must redo search for subsequent uses
+    $CustomFields->RedoSearch;
+    $CustomFields->GotoFirstItem;
+}
+# }}}
+
+# {{{ deal with deleting existing custom fields
+foreach my $key (keys %ARGS) {
+  # {{{ if we're trying to delete the custom field
+  if ($key =~ /^DeleteCustomField-(\d+)/) {
+    my $id = $1;
+    my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
+    $CustomFieldObj->Load($id);
+    my ($retval, $msg) = $CustomFieldObj->Delete;
+    if ($retval) {
+      push @actions, loc("Custom field deleted");
+    }
+    else {
+      push @actions, $msg;
+    }
+  }
+  # }}}
+}
+# }}}
+
+</%INIT>
+<%ARGS>
+$id => 0
+$title => undef
+$Move => undef
+$Source => undef
+$CustomField => undef
+$FindDisabledCustomFields => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/EditQueueWatchers b/rt/html/Admin/Elements/EditQueueWatchers
new file mode 100644 (file)
index 0000000..db39bfb
--- /dev/null
@@ -0,0 +1,55 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+%if ($Members->Count == 0 ) {
+<ul>
+<li><i><&|/l&>none</&></i>
+% } else {
+<i><&|/l&>(Check box to delete)</&></i><br><BR>
+<ul>
+% while (my $watcher=$Members->Next) {
+<li>
+<INPUT  TYPE=CHECKBOX 
+        NAME="Queue-<%$QueueObj->Id%>-DelWatcher-Type-<%$Watchers->Type%>-Principal-<%$watcher->MemberId%>" 
+        UNCHECKED>
+% if ($watcher->MemberObj->IsUser) { 
+<a href="<%$RT::WebPath%>/Admin/Users/Modify.html?id=<%$watcher->MemberObj->ObjectId%>">
+% } else {
+<a href="<%$RT::WebPath%>/Admin/Groups/Modify.html?id=<%$watcher->MemberObj->ObjectId%>">
+% }
+<%$watcher->MemberObj->Object->Name%></a>
+% }
+% }
+</ul>
+
+<%INIT>
+my $Members = $Watchers->MembersObj;
+</%INIT>
+
+<%ARGS>
+$QueueObj => undef
+$Watchers => undef
+</%ARGS>
+
+
+
diff --git a/rt/html/Admin/Elements/EditScrip b/rt/html/Admin/Elements/EditScrip
new file mode 100644 (file)
index 0000000..5393ebf
--- /dev/null
@@ -0,0 +1,149 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/ListActions, actions => \@actions &>
+
+  
+<FORM METHOD=POST ACTION="Scrip.html">
+<input type="hidden" name="id" value="<%$id%>">
+<input type="hidden" name="Queue" value="<%$Queue%>">
+<TABLE>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Description</&>:
+</TD>
+<TD>
+<input Name="Scrip-<%$id%>-Description" value="<%$scrip->Description%>">
+</TR>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Condition</&>:
+</TD>
+<TD>
+<& /Admin/Elements/SelectScripCondition, Name => "Scrip-$id-ScripCondition", Default => $scrip->ConditionObj->Id &><BR>
+</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Custom condition</&>:
+</TD>
+<TD>
+<TEXTAREA COLS=80 ROWS=5 NAME="Scrip-<%$id%>-CustomIsApplicableCode"><%$scrip->CustomIsApplicableCode%></TEXTAREA>
+</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Action</&>:
+</TD>
+<TD>
+<& /Admin/Elements/SelectScripAction, Name => "Scrip-$id-ScripAction", Default => $scrip->ActionObj->Id &>
+</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Custom action preparation code</&>:
+</TD>
+<TD>
+<TEXTAREA COLS=80 ROWS=5 NAME="Scrip-<%$id%>-CustomPrepareCode"><%$scrip->CustomPrepareCode%></TEXTAREA>
+</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Custom action cleanup code</&>:
+</TD>
+<TD>
+<TEXTAREA COLS=80 ROWS=5 NAME="Scrip-<%$id%>-CustomCommitCode"><%$scrip->CustomCommitCode%></TEXTAREA>
+</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Template</&>: 
+</TD>
+<TD>
+<& /Admin/Elements/SelectTemplate, Name => "Scrip-$id-Template", Default => $scrip->TemplateObj->Id, Queue => $Queue &>
+</TD>
+</TR>
+
+<& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+</FORM>
+<%init>
+my (@actions);
+
+
+my $scrip = new RT::Scrip($session{'CurrentUser'});
+
+if ( $id eq 'new' ) {
+
+    my ( $retval, $msg ) = $scrip->Create(
+            Queue                  => $Queue,
+            ScripAction            => $ARGS{"Scrip-new-ScripAction"},
+            ScripCondition         => $ARGS{"Scrip-new-ScripCondition"},
+            Template               => $ARGS{"Scrip-new-Template"},
+            Description            => $ARGS{"Scrip-new-Description"},
+            CustomPrepareCode      => $ARGS{"Scrip-new-CustomPrepareCode"},
+            CustomCommitCode       => $ARGS{"Scrip-new-CustomCommitCode"},
+            CustomIsApplicableCode => $ARGS{"Scrip-new-CustomIsApplicableCode"},
+    );
+    if ( defined $retval ) {
+        push @actions, $msg;
+    }
+    else {
+        Abort( $msg);
+    }
+}
+elsif ($id) {
+    my ($val,$msg) =$scrip->Load($id);
+    if  ($val) {
+        $id = $scrip->id;
+    } else {
+       Abort ($msg);
+    }
+    my @attribs = qw (
+      Queue
+      ScripAction
+      ScripCondition
+      Template
+      Description
+      CustomPrepareCode
+      CustomCommitCode
+      CustomIsApplicableCode
+    );
+    my @results = UpdateRecordObject( AttributesRef => \@attribs,
+                                      AttributePrefix => 'Scrip-'.$scrip->Id,
+                                      Object        => $scrip,
+                                      ARGSRef       => \%ARGS );
+    push (@actions, @results);
+}
+
+elsif ($ARGS{'create'}) {
+    $id = 'new';
+}
+
+# }}}
+</%init>
+
+<%ARGS>
+$id => undef
+$title => undef
+$Queue => 0
+</%ARGS>
diff --git a/rt/html/Admin/Elements/EditScrips b/rt/html/Admin/Elements/EditScrips
new file mode 100644 (file)
index 0000000..24515d8
--- /dev/null
@@ -0,0 +1,97 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/ListActions, actions => \@actions &>
+
+<form action="Scrips.html" method="post">
+<input type="hidden" name="id" value="<%$id%>">
+
+<P><&|/l&>Current Scrips</&>:</P>
+% if ($Scrips->Count == 0 ) {
+<P><i><&|/l&>(No scrips)</&></i></P>
+% } else {
+<TABLE>
+<P><i><&|/l&>(Check box to delete)</&></i></P>
+
+%   while (my $scrip = $Scrips->Next ) {
+<TR>
+<TD>
+<input type="checkbox" name="DeleteScrip-<%$scrip->Id%>">
+</TD>
+<TD>
+<a href="Scrip.html?id=<%$scrip->Id%>&Queue=<%$id%>"><% $scrip->Description || "<i>(".loc('no value').")</i>" |n %></a><br>
+<small><&|/l, loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name) &>[_1] [_2] with template [_3]</&></small>
+</TD>
+</TR>
+%   }
+
+</TABLE>
+
+% }
+<& /Elements/Submit &>
+</form>
+<%init>
+my (@actions);
+
+my $Scrips = RT::Scrips->new($session{'CurrentUser'});
+
+
+my $QueueObj = RT::Queue->new($session{'CurrentUser'});
+if ($id)  {
+        $QueueObj->Load($id);                        
+}
+
+if ($QueueObj->id) {                         
+       $Scrips->LimitToQueue($id);
+}                                            
+else {                                       
+        $Scrips->LimitToGlobal();
+}                                           
+
+
+
+
+# {{{ deal with modifying and deleting existing scrips
+foreach my $key (keys %ARGS) {
+  # {{{ if we're trying to delete the scrip
+  if ($key =~ /^DeleteScrip-(\d+)/) {
+    my $id = $1;
+    my $scrip = new RT::Scrip($session{'CurrentUser'});
+    $scrip->Load($id);
+    my ($retval, $msg) = $scrip->Delete;
+    if ($retval) {
+      push @actions, loc("Scrip deleted");
+    }
+    else {
+      push @actions, $msg;
+    }
+  }
+  # }}}
+}
+# }}}
+</%init>
+
+<%ARGS>
+$id => undef
+$title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/EditTemplates b/rt/html/Admin/Elements/EditTemplates
new file mode 100644 (file)
index 0000000..12677ca
--- /dev/null
@@ -0,0 +1,104 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/ListActions, actions => \@actions &>
+
+<FORM METHOD=GET ACTION="Templates.html">
+<INPUT TYPE="Hidden" NAME="id" VALUE="<%$id%>">
+
+% if ($Templates->Count == 0 ) {
+<P><i><&|/l&>(No templates)</&></i></P>
+% } else {
+<TABLE>
+<TR>
+<TH>
+<i><&|/l&>(Check box to delete)</&></i>
+</TH>
+<TH>
+</TH>
+</TR>
+% my $count;
+% while (my $TemplateObj = $Templates->Next) { 
+<TR>
+<TD>
+<input type="checkbox" name="DeleteTemplate-<%$TemplateObj->Id%>">
+</TD>
+<TD>
+<A HREF="Template.html?Queue=<%$id%>&Template=<%$TemplateObj->id()%>">
+<B><% loc($TemplateObj->Name) %></B></A>
+<br><% loc($TemplateObj->Description) %>
+</TD>
+</TR>
+
+% }
+</TABLE>
+% }
+
+<& /Elements/Submit &>
+</FORM>
+
+<%INIT>
+my $Templates = RT::Templates->new($session{'CurrentUser'});
+my $QueueObj = RT::Queue->new($session{'CurrentUser'});
+my @actions;
+
+if ($id)  {
+        $QueueObj->Load($id);                        
+}
+
+if ($QueueObj->id) {
+       $Templates->LimitToQueue($id);
+}                                            
+else {                                       
+        $Templates->LimitToGlobal();
+}                                           
+
+# Now let callbacks add their extra limits
+$m->comp('/Elements/Callback', Templates => $Templates, %ARGS);
+
+# {{{ deal with deleting existing templates
+foreach my $key (keys %ARGS) {
+  # {{{ if we're trying to delete the template
+  if ($key =~ /^DeleteTemplate-(\d+)/) {
+    my $id = $1;
+    my $TemplateObj = RT::Template->new($session{'CurrentUser'});
+    $TemplateObj->Load($id);
+    my ($retval, $msg) = $TemplateObj->Delete;
+    if ($retval) {
+      push @actions, loc("Template deleted");
+    }
+    else {
+      push @actions, $msg;
+    }
+  }
+  # }}}
+}
+# }}}
+</%INIT>
+<%ARGS>
+$id => 0
+$title => undef
+$Move => undef
+$Source => undef
+$Template => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/EditUserComments b/rt/html/Admin/Elements/EditUserComments
new file mode 100644 (file)
index 0000000..f791876
--- /dev/null
@@ -0,0 +1,32 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => "Comments about $name" &>
+<&|/l&>These comments aren't generally visible to the user</&>:<br>
+<input type="hidden" name="id" value="<%$id%>">
+<TEXTAREA COLS=60 ROWS=15 WRAP=SOFT NAME="Comments"><% $UserObj->Comments %></TEXTAREA>
+</FORM>
+
+<%ARGS>
+$UserObj => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/GroupTabs b/rt/html/Admin/Elements/GroupTabs
new file mode 100644 (file)
index 0000000..8737782
--- /dev/null
@@ -0,0 +1,76 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Tabs, 
+    subtabs => $tabs, 
+    current_tab => 'Admin/Groups/', 
+    current_subtab => $current_tab, 
+    Title => $Title &>
+<%INIT>
+my $tabs;
+
+if ( $GroupObj and $GroupObj->id ) {
+$tabs->{"this"} = { class => "currentnav",                                                           
+                    path  => "Admin/Groups/Modify.html?id=" . $GroupObj->id,
+                    title => $GroupObj->Name,
+                    current_subtab => $current_subtab,
+        subtabs => {
+        C => { title => loc('Basics'),
+               path  => "Admin/Groups/Modify.html?id=" . $GroupObj->id },
+
+        D => { title => loc('Members'),
+               path  => "Admin/Groups/Members.html?id=" . $GroupObj->id },
+
+        F => { title => loc('Group Rights'),
+               path  => "Admin/Groups/GroupRights.html?id=" . $GroupObj->id, },
+        G => { title => loc('User Rights'),
+               path  => "Admin/Groups/UserRights.html?id=" . $GroupObj->id, },
+    }
+}
+}
+$tabs->{"A"} = { title => loc('Select group'),
+                 path  => "Admin/Groups/", };
+$tabs->{"B"} = { title     => loc('New group'),
+                 path      => "Admin/Groups/Modify.html?Create=1",
+                 separator => 1, };
+
+# Now let callbacks add their extra tabs
+$m->comp( '/Elements/Callback', tabs => $tabs, %ARGS );
+foreach my $tab ( sort keys %{$tabs->{'this'}->{'subtabs'}} ) {  
+    if ( $tabs->{'this'}->{'subtabs'}->{$tab}->{'path'} eq $current_tab ) {
+        $tabs->{'this'}->{'subtabs'}->{$tab}->{"subtabs"}        = $subtabs; 
+        $tabs->{'this'}->{'subtabs'}->{$tab}->{"current_subtab"} = $current_subtab; 
+    }                                                                           
+}   
+        $tabs->{'this'}->{"current_subtab"} = $current_tab; 
+        $current_tab = "Admin/Groups/Modify.html?id=".$GroupObj->id if $GroupObj;
+
+</%INIT>
+<%ARGS>
+$GroupObj => undef
+$subtabs => undef
+$current_subtab => undef
+$current_tab => undef
+$Title => undef
+</%ARGS>
+
diff --git a/rt/html/Admin/Elements/Header b/rt/html/Admin/Elements/Header
new file mode 100644 (file)
index 0000000..92a7c54
--- /dev/null
@@ -0,0 +1,28 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => $Title &>
+
+<%ARGS>
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/ListGlobalCustomFields b/rt/html/Admin/Elements/ListGlobalCustomFields
new file mode 100644 (file)
index 0000000..032f680
--- /dev/null
@@ -0,0 +1,37 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+%   my $count = 0;
+%   while (my $CustomFieldObj = $CustomFields->Next) { 
+%   $count++;
+<font size="-1"><%$CustomFieldObj->id%>/<% loc($CustomFieldObj->Type) %>/<%$CustomFieldObj->Name%>: <%$CustomFieldObj->Description%></font>
+<BR>
+%   }
+%   if (!$count) {
+<font size="-1"><&|/l&>(No custom fields)</&></font>
+%   }
+
+<%init>
+my $CustomFields = new RT::CustomFields ($session{'CurrentUser'});
+$CustomFields->LimitToGlobal();
+</%INIT>
diff --git a/rt/html/Admin/Elements/ListGlobalScrips b/rt/html/Admin/Elements/ListGlobalScrips
new file mode 100644 (file)
index 0000000..8dba3b6
--- /dev/null
@@ -0,0 +1,37 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+%   my $count = 0;
+%   while (my $scrip = $Scrips->Next ) {
+%   $count++;
+<font size="-1"><&|/l, loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name) &>[_1] [_2] with template [_3]</&></font>
+<BR>
+%   }
+%   if (!$count) {
+<font size="-1"><&|/l&>(No scrips)</&></font>
+%   }
+
+<%init>
+my $Scrips = new RT::Scrips ($session{'CurrentUser'});
+$Scrips->LimitToGlobal();
+</%INIT>
diff --git a/rt/html/Admin/Elements/ModifyQueue b/rt/html/Admin/Elements/ModifyQueue
new file mode 100644 (file)
index 0000000..e5761df
--- /dev/null
@@ -0,0 +1,78 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/TitleBoxStart, title => loc('Editing Configuration for queue [_1]', $QueueObj->Id) &>
+
+<FORM ACTION="<%$RT::WebPath%>/Admin/Queues/Modify.html" METHOD=POST>
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$QueueObj->Id%>">
+<TABLE>
+<TR><TD ALIGN=RIGHT>
+<&|/l&>Queue Name</&>:
+</TD>
+<TD><INPUT name="Name" value="<%$QueueObj->Name%>"></TD>
+</TR><TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Description</&>:</TD><TD COLSPAN=3><INPUT name="Description" value="<%$QueueObj->Description%>" size=60></TD></TR>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Correspondence Address</&>:
+</TD><TD>
+<INPUT name="CorrespondAddress" value="<%$QueueObj->CorrespondAddress%>">
+</TD>
+<TD ALIGN=RIGHT>
+
+<&|/l&>Comment Address</&>: </TD><TD>
+<INPUT NAME="CommentAddress" value="<%$QueueObj->CommentAddress%>">
+</TD>
+</TR><TR>
+
+<TD ALIGN=RIGHT>
+<&|/l&>Priority starts at</&>:
+</TD><TD><INPUT NAME="InitialPriority" value="<%$QueueObj->InitialPriority %>">
+</TD>
+<TD ALIGN=RIGHT>
+<&|/l&>Over time, priority moves toward</&>:
+</TD><TD><INPUT NAME="FinalPriority" value="<%$QueueObj->FinalPriority %>">
+</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Requests should be due in</&>:
+</TD><TD>
+<INPUT NAME="DefaultDueIn" VALUE="<%$QueueObj->DefaultDueIn%>"> <&|/l&>days</&>.
+</TD>
+</TR>
+</TABLE>
+<& /Elements/Submit &>
+</form>
+<& /Elements/TitleBoxEnd &>
+
+<%INIT>
+
+</%INIT>
+
+<%ARGS>
+
+
+$QueueObj => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/ModifyTemplate b/rt/html/Admin/Elements/ModifyTemplate
new file mode 100644 (file)
index 0000000..5f75bac
--- /dev/null
@@ -0,0 +1,60 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TABLE>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Name</&>:
+</TD>
+<TD>
+<input name="Name" VALUE="<%$Name%>" SIZE=20><BR>
+</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Description</&>: 
+</TD>
+<TD>
+<input name="Description" VALUE="<%$Description%>" SIZE=80><BR>
+</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=TOP>
+<&|/l&>Content</&>:<BR>
+</TD>
+<TD>
+<TEXTAREA NAME=Content ROWS=25 COLS=80 WRAP=SOFT>
+<%$Content%></TEXTAREA>
+</TD>
+</TR>
+</TABLE>
+
+<%INIT>
+
+</%INIT>
+
+<%ARGS>
+$Name => undef
+$Description => undef
+$Content => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/ModifyUser b/rt/html/Admin/Elements/ModifyUser
new file mode 100644 (file)
index 0000000..876e8a7
--- /dev/null
@@ -0,0 +1,99 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/TitleBoxStart, title => loc('Editing Configuration for user [_1]', $UserObj->Name) &>
+
+<FORM ACTION="<%$RT::WebPath%>/Admin/Users/Modify.html" METHOD=POST>
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$UserObj->Id%>">
+
+<&|/l&>Name</&>: <input name="Name" value="<%$UserObj->Name%>">
+<BR>
+<&|/l&>New Password</&>: <input type=password name="Pass1"><BR>
+<&|/l&>Retype Password</&>: <input type=password name="Pass2"><BR>
+
+<&|/l&>Comments</&>: <TEXTAREA name="Comments" COLS=80 ROWS=5 WRAP=VIRTUAL>
+<%$UserObj->Comments%></TEXTAREA>
+
+<BR>
+<&|/l&>Signature</&>: <TEXTAREA COLS=80 ROWS=5 name="Signature" WRAP=HARD>
+<%$UserObj->Signature%></TEXTAREA>
+<BR>
+<&|/l&>EmailAddress</&>: <input name="EmailAddress" value="<%$UserObj->EmailAddress%>">
+<BR>
+<&|/l&>FreeformContactInfo</&>: <input name="FreeformContactInfo" value="<%$UserObj->FreeformContactInfo%>">
+<BR>
+<&|/l&>Organization</&>: <input name="Organization" value="<%$UserObj->Organization%>">
+<BR>
+<&|/l&>RealName</&>: <input name="RealName" value="<%$UserObj->RealName%>">
+<BR>
+<&|/l&>NickName</&>: <input name="NickName" value="<%$UserObj->NickName%>">
+<BR>
+<&|/l&>Lang</&>: <input name="Lang" value="<%$UserObj->Lang%>">
+<BR>
+<&|/l&>EmailEncoding</&>: <input name="EmailEncoding" value="<%$UserObj->EmailEncoding%>">
+<BR>
+<&|/l&>WebEncoding</&>: <input name="WebEncoding" value="<%$UserObj->WebEncoding%>">
+<BR>
+<&|/l&>ExternalContactInfoId</&>: <input name="ExternalContactInfoId" value="<%$UserObj->ExternalContactInfoId%>">
+<BR>
+<&|/l&>ContactInfoSystem</&>: <input name="ContactInfoSystem" value="<%$UserObj->ContactInfoSystem%>">
+<BR>
+<&|/l&>UnixUsername</&>: <input name="Gecos" value="<%$UserObj->Gecos%>">
+<BR>
+<&|/l&>ExternalAuthId</&>: <input name="ExternalAuthId" value="<%$UserObj->ExternalAuthId%>">
+<BR>
+<&|/l&>AuthSystem</&>: <input name="AuthSystem" value="<%$UserObj->AuthSystem%>">
+<BR>
+<&|/l&>HomePhone</&>: <input name="HomePhone" value="<%$UserObj->HomePhone%>">
+<BR>
+<&|/l&>WorkPhone</&>: <input name="WorkPhone" value="<%$UserObj->WorkPhone%>">
+<BR>
+<&|/l&>MobilePhone</&>: <input name="MobilePhone" value="<%$UserObj->MobilePhone%>">
+<BR>
+<&|/l&>PagerPhone</&>: <input name="PagerPhone" value="<%$UserObj->PagerPhone%>">
+<BR>
+<&|/l&>Address1</&>: <input name="Address1" value="<%$UserObj->Address1%>">
+<BR>
+<&|/l&>Address2</&>: <input name="Address2" value="<%$UserObj->Address2%>">
+<BR>
+<&|/l&>City</&>: <input name="City" value="<%$UserObj->City%>">
+<BR>
+<&|/l&>State</&>: <input name="State" value="<%$UserObj->State%>">
+<BR>
+<&|/l&>Zip</&>: <input name="Zip" value="<%$UserObj->Zip%>">
+<BR>
+<&|/l&>Country</&>: <input name="Country" value="<%$UserObj->Country%>">
+<BR>
+<& /Elements/Submit &>
+</form>
+<& /Elements/TitleBoxEnd &>
+
+<%INIT>
+
+</%INIT>
+
+<%ARGS>
+
+
+$UserObj => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/QueueRightsForUser b/rt/html/Admin/Elements/QueueRightsForUser
new file mode 100644 (file)
index 0000000..05bb511
--- /dev/null
@@ -0,0 +1,40 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<UL>
+%while(my $ACE = $ACL->Next) {
+
+<LI><checkbox name="delete_ace_<%$ACE->id%>"> <% loc($ACE->RightName) %> (<%$ACE->UserObj->RealName%>)
+
+%}
+</UL>
+
+<%INIT>
+my $ACL = new RT::ACL($session{'CurrentUser'});
+$ACL->LimitToQueue($QueueObj->id);
+$ACL->LimitPrincipalToUser($PrincipalId);
+</%INIT>
+<%ARGS>
+$PrincipalId => undef
+$QueueObj => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/QueueTabs b/rt/html/Admin/Elements/QueueTabs
new file mode 100644 (file)
index 0000000..3b4805a
--- /dev/null
@@ -0,0 +1,93 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Tabs, 
+    subtabs => $tabs, 
+    current_tab => 'Admin/Queues/', 
+    current_subtab => $current_tab, 
+    Title => $Title &>
+
+<%INIT>
+my $tabs;
+if ($id) {
+  $tabs->{'this'}  = {
+                title => $QueueObj->Name,
+                       path => "Admin/Queues/Modify.html?id=".$id,
+                    current_subtab => $current_tab,     
+                subtabs => {
+                C => { title => loc('Basics'),
+                       path => "Admin/Queues/Modify.html?id=".$id,
+                          },
+                D => { title => loc('Watchers'),
+                       path => "Admin/Queues/People.html?id=".$id,
+                     },
+
+                E => { title => loc('Scrips'),
+                            path => "Admin/Queues/Scrips.html?id=".$id,
+                          },
+                F => { title => loc('Templates'),
+                               path => "Admin/Queues/Templates.html?id=".$id,
+                             },
+
+                 G => { title => loc('Custom Fields'),
+                        path => 'Admin/Queues/CustomFields.html?id='.$id,
+                        },
+
+                H => { title => loc('Group Rights'),
+                         path => "Admin/Queues/GroupRights.html?id=".$id,
+                       },      
+                I => { title => loc('User Rights'),
+                         path => "Admin/Queues/UserRights.html?id=".$id,
+                       }
+        }
+        };
+}
+if ($session{'CurrentUser'}->HasRight( Object => $RT::System, Right => 'AdminQueue')) {
+  $tabs->{"A"} = { title => loc('Select queue'),
+                       path => "Admin/Queues/",
+                          };
+  $tabs->{"B"} = { title => loc('New queue'),
+                       path => "Admin/Queues/Modify.html?Create=1",
+                       separator => 1,
+                          };
+}
+
+  # Now let callbacks add their extra tabs
+  $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+foreach my $tab ( sort keys %{$tabs->{'this'}->{'subtabs'}} ) {  
+    if ( $tabs->{'this'}->{'subtabs'}->{$tab}->{'path'} eq $current_tab ) {
+        $tabs->{'this'}->{'subtabs'}->{$tab}->{"subtabs"}        = $subtabs; 
+        $tabs->{'this'}->{'subtabs'}->{$tab}->{"current_subtab"} = $current_subtab; 
+    }                                                                           
+}   
+                       $current_tab = "Admin/Queues/Modify.html?id=".$id if $id;
+</%INIT>
+  
+<%ARGS>
+$QueueObj => undef
+$id => undef
+$subtabs => undef
+$current_subtab => undef
+$current_tab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectCustomFieldType b/rt/html/Admin/Elements/SelectCustomFieldType
new file mode 100644 (file)
index 0000000..b5f4c07
--- /dev/null
@@ -0,0 +1,36 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME ="<%$Name%>">
+%for my $option ($cf->Types) {
+<OPTION VALUE="<%$option%>" <%$option eq $Default && "SELECTED"%>><% $cf->FriendlyType($option) %></OPTION>
+%}
+</SELECT>
+<%INIT>
+my $cf = RT::CustomField->new($session{'CurrentUser'});
+
+</%INIT>
+<%ARGS>
+$Default=>undef
+$Name => 'Type'
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectGroups b/rt/html/Admin/Elements/SelectGroups
new file mode 100644 (file)
index 0000000..5df49ad
--- /dev/null
@@ -0,0 +1,37 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT MULTIPLE NAME="<%$Name%>"  SIZE=10>
+%while (my $group = $groups->Next) {
+<OPTION VALUE="<%$group->id%>"><%$group->Name%>
+%}
+</SELECT>
+
+<%INIT>
+my $groups = new RT::Groups($session{'CurrentUser'});
+$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'System');
+
+</%INIT>
+<%ARGS>
+$Name => 'groups'
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectModifyGroup b/rt/html/Admin/Elements/SelectModifyGroup
new file mode 100644 (file)
index 0000000..47978d3
--- /dev/null
@@ -0,0 +1,33 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+%while ( $Group = $Groups->Next) {
+<A HREF="Modify.html?id=<%$Group->id%>"><%$Group->id%>: <%$Group->Name%></a><BR>
+%}
+<%INIT>
+my ($Group);
+my $Groups = new RT::Groups($session{'CurrentUser'});
+$Groups->UnLimit;
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectModifyQueue b/rt/html/Admin/Elements/SelectModifyQueue
new file mode 100644 (file)
index 0000000..c5152ac
--- /dev/null
@@ -0,0 +1,33 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+%while ( $queue = $queues->Next) {
+<A HREF="Modify.html?id=<%$queue->id%>"><%$queue->id%>: <%$queue->Name%></a><BR>
+%}
+<%INIT>
+my ($queue);
+my $queues = new RT::Queues($session{'CurrentUser'});
+$queues->UnLimit;
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectModifyUser b/rt/html/Admin/Elements/SelectModifyUser
new file mode 100644 (file)
index 0000000..9e7789b
--- /dev/null
@@ -0,0 +1,49 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+%while ( $user = $users->Next) {
+<A HREF="Modify.html?id=<%$user->id%>"><%$user->id%>: <%$user->Name%></a><BR>
+%}
+<%INIT>
+my ($user);
+my $users = new RT::Users($session{'CurrentUser'});
+$users->Limit(FIELD => 'id',
+              VALUE => $RT::SystemUser->id,
+              OPERATOR => '!=' );
+
+if (defined $IdLike) {
+$users->Limit(FIELD => 'Name',
+              VALUE => $IdLike,
+              OPERATOR => 'LIKE' );
+}
+if (defined $EmailLike) {
+$users->Limit(FIELD => 'EmailAddress',
+              VALUE => $EmailLike,
+              OPERATOR => 'LIKE');
+
+}
+</%INIT>
+<%ARGS>
+$IdLike => undef
+$EmailLike => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectNewGroupMembers b/rt/html/Admin/Elements/SelectNewGroupMembers
new file mode 100644 (file)
index 0000000..e5c28e9
--- /dev/null
@@ -0,0 +1,61 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+% if ($Show ne 'Groups') {
+<b><&|/l&>Users</&></b>
+<SELECT MULTIPLE NAME="<%$Name%>Users"  SIZE=10>
+%while (my $user = $users->Next) {
+<OPTION VALUE="User-<%$user->id%>"><%$user->Name%></OPTION>
+%}
+</SELECT>
+<br>
+% }
+% if ($Show ne 'Users') {
+<b><&|/l&>Groups</&></b>
+<SELECT MULTIPLE NAME="<%$Name%>Groups"  SIZE=10>
+%while (my $group = $groups->Next) {
+<OPTION VALUE="Group-<%$group->id%>"><%$group->Name%></OPTION>
+%}
+</SELECT>
+% }
+
+<%INIT>
+my $users = new RT::Users($session{'CurrentUser'});
+
+$users->Limit(FIELD => 'id', VALUE => $RT::SystemUser->id, OPERATOR => '!=' );
+$users->Limit(FIELD => 'id', VALUE => $RT::Nobody->id, OPERATOR => '!=' );
+$users->LimitToPrivileged();
+
+my $groups = new RT::Groups($session{'CurrentUser'});
+
+# self-recursive group membership considered harmful!
+$groups->Limit(FIELD => 'id', VALUE => $Group->id, OPERATOR => '!=' );
+$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined');
+
+
+</%INIT>
+<%ARGS>
+$Name => 'Users'
+$Show => 'All'
+$Group
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectRights b/rt/html/Admin/Elements/SelectRights
new file mode 100644 (file)
index 0000000..37a06dc
--- /dev/null
@@ -0,0 +1,90 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<INPUT TYPE=HIDDEN NAME="CheckACL"  VALUE="<%$ACLDesc%>">
+     <TABLE BORDER=0>
+<TR>
+<TD valign=top width="180"> 
+<h3><&|/l&>Current rights</&></h3>
+% if ($ACLObj->Count() > 0) {
+<i>(<&|/l&>Check box to revoke right</&>)</i> <BR>
+% } else {
+<i><&|/l&>No rights granted.</&></i> <BR>    
+% }
+% while (my $right = $ACLObj->Next()) {
+% if ($right->RightName) {
+<input type=checkbox value="<%$right->Id%>" name="RevokeRight-<%$ACLDesc%>-<%$right->RightName%>"> <% loc($right->RightName) %><br>
+% }
+%  }
+</TD>
+<TD valign=top>
+<h3><&|/l&>New rights</&></h3> 
+<SELECT SIZE=5  MULTIPLE  NAME="GrantRight-<%$ACLDesc%>">
+% foreach $right (sort keys %Rights) {
+      <OPTION VALUE="<%$right%>"  
+       ><% loc($right) %></OPTION>
+% }
+<OPTION VALUE="" SELECTED><&|/l&>(no value)</&></OPTION>
+</SELECT>
+</TD>
+</TR>
+</TABLE>
+<%INIT>
+    my ($right, $ACLDesc, $AppliesTo, %Rights);
+
+    # if the principal id points to a user, we really want to point
+    # to their ACL equivalence group. The machinations we're going through
+    # lead me to start to suspect that we really want users and groups
+    # to just be the same table. or _maybe_ that we want an object db.
+    my $princ = RT::Principal->new($RT::SystemUser);
+    $princ->Load($PrincipalId);
+    if ($princ->PrincipalType eq 'User') {
+    my $group = RT::Group->new($RT::SystemUser);
+        $group->LoadACLEquivalenceGroup($princ);
+        $PrincipalId = $group->PrincipalId;
+    }
+
+
+    my $ACLObj = new RT::ACL($session{'CurrentUser'});
+    my $ACE = new RT::ACE($session{'CurrentUser'});
+
+
+    $ACLObj->LimitToObject( $Object);
+    $ACLObj->LimitToPrincipal( Id => $PrincipalId);
+
+    if (ref($Object) && UNIVERSAL::can($Object, 'AvailableRights')) { 
+        %Rights = %{$Object->AvailableRights};
+    } 
+
+        else {
+                %Rights = { loc('System Error') => loc("No rights found")};
+        }
+        
+    $ACLDesc = "$PrincipalId-".ref($Object)."-".$Object->Id;
+</%INIT>
+    
+<%ARGS>
+$PrincipalType => undef
+$PrincipalId => undef
+$Object =>undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectScrip b/rt/html/Admin/Elements/SelectScrip
new file mode 100644 (file)
index 0000000..18e4098
--- /dev/null
@@ -0,0 +1,48 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME=<%$Name%>>
+<OPTION VALUE="" 
+<% $Default eq undef && 'SELECTED' %>
+>-</OPTION>
+%while  (my $Scrip = $Scrips->Next) {
+<OPTION VALUE=<% $Scrip->Id %>
+<% $Scrip->Id == $Default && 'SELECTED' %>
+><% loc($Scrip->Name) %>
+</OPTION>
+%}
+</SELECT>
+
+<%INIT>
+my $Scrips = RT::Scrips->new($session{'CurrentUser'});
+$Scrips->UnLimit;
+
+
+
+</%INIT>
+<%ARGS>
+
+$Default => undef
+$Name => 'Scrip'
+
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectScripAction b/rt/html/Admin/Elements/SelectScripAction
new file mode 100644 (file)
index 0000000..0d7f8cc
--- /dev/null
@@ -0,0 +1,48 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME=<%$Name%>>
+<OPTION VALUE="" 
+<% $Default eq undef && 'SELECTED' %>
+>-</OPTION>
+%while  (my $ScripAction = $ScripActions->Next) {
+<OPTION VALUE=<%$ScripAction->Id%>
+<% $ScripAction->Id == $Default && 'SELECTED' %>
+><% loc($ScripAction->Name) %>
+</OPTION>
+%}
+</SELECT>
+
+<%INIT>
+my $ScripActions = RT::ScripActions->new($session{'CurrentUser'});
+$ScripActions->UnLimit;
+
+
+
+</%INIT>
+<%ARGS>
+
+$Default => undef
+$Name => 'ScripAction'
+
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectScripCondition b/rt/html/Admin/Elements/SelectScripCondition
new file mode 100644 (file)
index 0000000..aeb366a
--- /dev/null
@@ -0,0 +1,48 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME=<%$Name%>>
+<OPTION VALUE="" 
+<% $Default eq undef && 'SELECTED' %>
+>-</OPTION>
+%while  (my $ScripCondition = $ScripConditions->Next) {
+<OPTION VALUE=<%$ScripCondition->Id%>
+<% $ScripCondition->Id == $Default && 'SELECTED' %>
+><% loc($ScripCondition->Name) %>
+</OPTION>
+%}
+</SELECT>
+
+<%INIT>
+my $ScripConditions = RT::ScripConditions->new($session{'CurrentUser'});
+$ScripConditions->UnLimit;
+
+
+
+</%INIT>
+<%ARGS>
+
+$Default => undef
+$Name => 'ScripCondition'
+
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectSingleOrMultiple b/rt/html/Admin/Elements/SelectSingleOrMultiple
new file mode 100644 (file)
index 0000000..98e9ee7
--- /dev/null
@@ -0,0 +1,43 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+  <select name="<%$Name%>">
+    <option value="1" <%$SingleDefault%>><&|/l&>Single</&></option>
+    <option value="0" <%$MultipleDefault%>><&|/l&>Multiple</&></option>
+  </select>    
+
+
+<%INIT>
+my ($SingleDefault, $MultipleDefault);
+if ($Default == 1) {
+    $SingleDefault = "SELECTED";
+}
+elsif ($Default == 0 ) {
+    $MultipleDefault = "SELECTED";
+}
+
+</%INIT>
+<%ARGS>
+$Name => 'Single'
+$Default => 1
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectTemplate b/rt/html/Admin/Elements/SelectTemplate
new file mode 100644 (file)
index 0000000..70ff4d1
--- /dev/null
@@ -0,0 +1,61 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME=<%$Name%>>
+<OPTION VALUE="" 
+<% $Default eq 'none' && 'SELECTED' %>
+>-</OPTION>
+%while  (my $Template = $PrimaryTemplates->Next) {
+<OPTION VALUE=<%$Template->Id%>
+<% ($Template->Id == $Default) && 'SELECTED' %>
+><% loc($Template->Name) %>
+</OPTION>
+%}
+%while  (my $Template = $OtherTemplates->Next) {
+<OPTION VALUE=<%$Template->Id%>
+<% ($Template->Id == $Default)  && 'SELECTED'%>
+><&|/l, loc($Template->Name) &>Global template: [_1]</&>
+</OPTION>
+%}
+</SELECT>
+
+<%INIT>
+
+
+my $PrimaryTemplates = RT::Templates->new($session{'CurrentUser'});
+if ($Queue != 0) {
+$PrimaryTemplates->LimitToQueue($Queue);
+}
+
+my $OtherTemplates = RT::Templates->new($session{'CurrentUser'});
+$OtherTemplates->LimitToGlobal($DefaultQueue);
+
+</%INIT>
+<%ARGS>
+
+$Queue => undef
+$Default => 'none'
+$DefaultQueue => undef
+$Name => 'Template'
+
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectUsers b/rt/html/Admin/Elements/SelectUsers
new file mode 100644 (file)
index 0000000..d4c8a85
--- /dev/null
@@ -0,0 +1,40 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT MULTIPLE NAME="<%$Name%>"  SIZE=10>
+%while (my $user = $users->Next) {
+<OPTION VALUE="<%$user->id%>"><%$user->Name%>
+%}
+</SELECT>
+
+<%INIT>
+my $users = new RT::Users($session{'CurrentUser'});
+
+$users->Limit(FIELD => 'id', VALUE => $RT::SystemUser->id, OPERATOR => '!=' );
+$users->Limit(FIELD => 'id', VALUE => $RT::Nobody->id, OPERATOR => '!=' );
+$users->LimitToPrivileged();
+
+</%INIT>
+<%ARGS>
+$Name => 'Users'
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SystemTabs b/rt/html/Admin/Elements/SystemTabs
new file mode 100644 (file)
index 0000000..f38febd
--- /dev/null
@@ -0,0 +1,70 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Tabs, subtabs => $tabs, 
+    current_tab => 'Admin/Global/', 
+    current_subtab => $current_tab, 
+    Title => $Title &>
+
+<%INIT>
+  my $tabs = {
+                
+               A => { title => loc('Scrips'),
+                           path => 'Admin/Global/Scrips.html',
+                         },
+               B => { title => loc('Templates'),
+                        path => 'Admin/Global/Templates.html',
+                      },
+              
+                F => { title => loc('Custom Fields'),
+                        path => 'Admin/Global/CustomFields.html',
+                        },
+
+                G => { title => loc('Group Rights'),
+                                path => 'Admin/Global/GroupRights.html',
+                      },
+                H => { title => loc('User Rights'),
+                                path => 'Admin/Global/UserRights.html',
+                      }
+
+};
+
+  # Now let callbacks add their extra tabs
+  $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+  foreach my $tab (sort keys %{$tabs}) {
+    if ($tabs->{$tab}->{'path'} eq $current_tab) {
+      $tabs->{$tab}->{"subtabs"} = $subtabs;
+      $tabs->{$tab}->{"current_subtab"} = $current_subtab;
+    }
+  }
+</%INIT>
+
+  
+<%ARGS>
+$id => undef
+$current_tab => undef
+$subtabs => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/Tabs b/rt/html/Admin/Elements/Tabs
new file mode 100644 (file)
index 0000000..8fa2708
--- /dev/null
@@ -0,0 +1,63 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Tabs, 
+    tabs => $tabs, 
+    current_toptab => 'Admin/', 
+    current_tab => $current_tab, 
+    Title => $Title &>
+
+<%INIT>
+  my $tabs = { A => { title => loc('Users'),
+                         path => 'Admin/Users/',
+                       },
+              B => { title => loc('Groups'),
+                          path => 'Admin/Groups/',
+                        },
+              C => { title => loc('Queues'),
+                          path => 'Admin/Queues/',
+                        },
+              D => { 'title' => loc('Global'),
+                          path => 'Admin/Global/',
+                        },
+            };
+
+  # Now let callbacks add their extra tabs
+  $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+  foreach my $tab (sort keys %{$tabs}) {
+    if ($tabs->{$tab}->{'path'} eq $current_tab) {
+      $tabs->{$tab}->{"subtabs"} = $subtabs;
+      $tabs->{$tab}->{"current_subtab"} = $current_subtab;
+    }
+  }
+
+</%INIT>
+
+
+<%ARGS>
+$subtabs => undef
+$current_tab => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/UserTabs b/rt/html/Admin/Elements/UserTabs
new file mode 100644 (file)
index 0000000..764fdfc
--- /dev/null
@@ -0,0 +1,74 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Tabs, 
+    subtabs => $tabs,
+    current_tab => 'Admin/Users/', 
+    current_subtab => $current_subtab, 
+    Title => $Title &>
+<%INIT>
+my $tabs;
+my $subtabs;
+if ($id) {
+$tabs->{'this'} = { title => eval { $UserObj->Name },
+
+                          path => "Admin/Users/Modify.html?id=".$id,
+subtabs => {
+              Queues => { title => loc('Basics'),
+                          path => "Admin/Users/Modify.html?id=".$id
+                        },
+#             Scrips => { title => loc('Rights'),
+#                         path => "Admin/Users/Rights.html?id=".$id
+#                       }
+              
+             }
+}
+}
+if ($session{'CurrentUser'}->HasRight( Object => $RT::System, Right => 'AdminUsers')) {
+  $tabs->{"A"} = { title => loc('Select user'),
+                       path => "Admin/Users/",
+                          };
+  $tabs->{"B"} = { title => loc('New user'),
+                       path => "Admin/Users/Modify.html?Create=1",
+                       separator => 1,
+                          };
+}
+
+  # Now let callbacks add their extra tabs
+  $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+                                                                                
+foreach my $tab ( sort keys %{$tabs} ) {                                        
+    if ( $tabs->{$tab}->{'path'} eq $current_subtab ) {                         
+        $tabs->{$tab}->{"current_subtab"} = $current_subtab;                    
+    }                                                                           
+}                                                                               
+</%INIT>
+  
+  
+<%ARGS>
+$UserObj => undef
+$id => undef
+$current_tab => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Global/CustomField.html b/rt/html/Admin/Global/CustomField.html
new file mode 100644 (file)
index 0000000..0974af5
--- /dev/null
@@ -0,0 +1,61 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/SystemTabs, 
+    current_tab => 'Admin/Global/CustomFields.html',
+    current_subtab => $current_subtab, 
+    subtabs => $subtabs, 
+    Title => $title &>
+
+<& /Admin/Elements/EditCustomField, title => $title,  %ARGS &>
+
+<%INIT>
+my ($title, $current_subtab);
+
+my $subtabs = {
+                A => { title => loc('Select custom field'),
+                       path => "Admin/Global/CustomFields.html"
+                          },
+                B => { title => loc('New custom field'),
+                       path => "Admin/Global/CustomField.html?create=1&Queue=0",
+                       separator => 1,
+                          }
+             };
+if ( $ARGS{'create'} ) {
+    $current_subtab = "Admin/Global/CustomField.html?create=1&Queue=0";
+    $title          = loc('Create a CustomField which applies to all queues');
+}
+else {
+    $current_subtab =
+      "Admin/Global/CustomField.html?CustomField=" . $CustomField . "&Queue=0";
+    $title = loc('Modify a CustomField which applies to all queues');
+    $subtabs->{"C"} = {
+        title => loc( 'Custom Field #[_1]', $CustomField ),
+        path => "Admin/Global/CustomField.html?CustomField=" . $CustomField . "&Queue=0"
+    };
+}
+</%INIT>
+<%ARGS>
+$CustomField => undef
+</%ARGS>
diff --git a/rt/html/Admin/Global/CustomFields.html b/rt/html/Admin/Global/CustomFields.html
new file mode 100644 (file)
index 0000000..f6bbddf
--- /dev/null
@@ -0,0 +1,47 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/SystemTabs, 
+    current_tab => 'Admin/Global/CustomFields.html',
+    current_subtab => 'Admin/Global/CustomFields.html', 
+    subtabs => $subtabs, 
+    Title => $title &>
+
+<& /Admin/Elements/EditCustomFields, title => $title, %ARGS &>
+
+<%INIT>
+my $subtabs = {
+                A => { title => loc('Select custom field'),
+                       path => "Admin/Global/CustomFields.html"
+                          },
+                B => { title => loc('New custom field'),
+                       path => "Admin/Global/CustomField.html?create=1&Queue=0",
+                       separator => 1,
+                          }
+             };
+my $title = loc("Modify Custom Fields which apply to all queues");
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Global/GroupRights.html b/rt/html/Admin/Global/GroupRights.html
new file mode 100644 (file)
index 0000000..150e83f
--- /dev/null
@@ -0,0 +1,99 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => loc('Modify global group rights') &>
+<& /Admin/Elements/SystemTabs, 
+    current_tab => 'Admin/Global/GroupRights.html', 
+    Title => loc('Modify global group rights') &>  
+<& /Elements/ListActions, actions => \@results &>
+
+  <FORM METHOD=POST ACTION="GroupRights.html">
+      
+<& /Elements/TitleBoxStart, title => loc('Modify global group rights.')&>
+      
+<h1><&|/l&>System groups</&></h1>
+<TABLE>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToSystemInternalGroups();
+%      while (my $Group = $Groups->Next()) {
+  <TR ALIGN=RIGHT> 
+       <TD VALIGN=TOP>
+           <% loc($Group->Type) %>
+                 </TD>
+         <TD>
+           <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+        Object  =>$RT::System &>
+         </TD>
+       </TR>
+% }
+</TABLE>
+<h1><&|/l&>Roles</&></h1>
+<TABLE>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToRolesForSystem();
+%      while (my $Group = $Groups->Next()) {
+  <TR ALIGN=RIGHT> 
+       <TD VALIGN=TOP>
+           <% loc($Group->Type) %>
+                 </TD>
+         <TD>
+           <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+        Object  => $RT::System &>
+         </TD>
+       </TR>
+% }
+</TABLE>
+<h1><&|/l&>User defined groups</&></h1>
+<TABLE>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToUserDefinedGroups();    
+%      while (my $Group = $Groups->Next()) {
+  <TR ALIGN=RIGHT> 
+       <TD VALIGN=TOP>
+           <% $Group->Name %>
+                 </TD>
+         <TD>
+           <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+        Object  => $RT::System &>
+         </TD>
+       </TR>
+% }
+</TABLE>
+            
+      <& /Elements/TitleBoxEnd &>
+      <& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+      
+  </FORM>
+  
+<%INIT>
+  #Update the acls.
+  my @results =  ProcessACLChanges(\%ARGS);
+
+
+my $Groups;
+    
+</%INIT>
+
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/Admin/Global/Scrip.html b/rt/html/Admin/Global/Scrip.html
new file mode 100644 (file)
index 0000000..8b9cf6d
--- /dev/null
@@ -0,0 +1,56 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title  &>
+<& /Admin/Elements/SystemTabs, 
+    current_tab => 'Admin/Global/Scrips.html', 
+    current_subtab => $current_subtab, 
+    subtabs => $subtabs, 
+    Title => $title &>
+
+<& /Admin/Elements/EditScrip, title => $title,  %ARGS &>
+
+<%init>
+my ($title, $current_subtab);
+my $subtabs = {
+                A => { title => loc('Select scrip'),
+                       path => "Admin/Global/Scrips.html",
+                          },
+                B => { title => loc('New scrip'),
+                       path => "Admin/Global/Scrip.html?create=1&Queue=0",
+                       separator => 1,
+                          }
+             };
+
+if ($ARGS{'id'}) {
+    $current_subtab = "Admin/Global/Scrip.html?id=".$ARGS{'id'}."&Queue=0";
+    $title = loc("Modify a scrip which applies to all queues");
+    $subtabs->{"C"} = { title => loc('Scrip #[_1]', $ARGS{'id'}),
+                       path => "Admin/Global/Scrip.html?id=".$ARGS{'id'}."&Queue=0"
+                          }
+}
+else {
+    $current_subtab = "Admin/Global/Scrip.html?create=1&Queue=0";
+    $title = loc("Add a scrip which will apply to all queues");
+}
+</%init>
diff --git a/rt/html/Admin/Global/Scrips.html b/rt/html/Admin/Global/Scrips.html
new file mode 100644 (file)
index 0000000..7631980
--- /dev/null
@@ -0,0 +1,53 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title  &>
+<& /Admin/Elements/SystemTabs, 
+    current_tab => 'Admin/Global/Scrips.html', 
+    current_subtab => 'Admin/Global/Scrips.html', 
+    subtabs => $subtabs, 
+    Title => $title &>
+<& /Admin/Elements/EditScrips, title => $title, id => $id, %ARGS &>
+</form>
+<%init>
+
+my $subtabs = {
+                A => { title => loc('Select scrip'),
+                       path => "Admin/Global/Scrips.html",
+                          },
+                B => { title => loc('New scrip'),
+                       path => "Admin/Global/Scrip.html?create=1&Queue=0",
+                       separator => 1,
+                          }
+             };
+my $title = loc("Modify scrips which apply to all queues");
+
+my (@actions);
+
+</%init>
+
+
+
+<%ARGS>
+$id => 0
+</%ARGS>
diff --git a/rt/html/Admin/Global/Template.html b/rt/html/Admin/Global/Template.html
new file mode 100644 (file)
index 0000000..71f77e9
--- /dev/null
@@ -0,0 +1,101 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => loc("Modify template [_1]", $TemplateObj->id)  &>
+<& /Admin/Elements/SystemTabs, 
+    current_tab => 'Admin/Global/Templates.html', 
+    current_subtab => $current_subtab, 
+    subtabs => $subtabs, 
+    Title => loc("Modify template [_1]", $TemplateObj->id) &>
+<& /Elements/ListActions, actions => \@results &>
+
+
+<FORM METHOD=POST ACTION="Template.html">
+%if ($Create ) {
+<INPUT TYPE=HIDDEN NAME="Template" VALUE="new">
+% } else {
+<INPUT TYPE=HIDDEN NAME="Template" VALUE="<%$TemplateObj->Id%>">
+% }
+
+%# hang onto the queue id
+<INPUT TYPE=HIDDEN name="Queue" value="<%$Queue%>">
+
+<& /Admin/Elements/ModifyTemplate, Name => $TemplateObj->Name, Description => $TemplateObj->Description, Content => $TemplateObj->Content &>
+
+<& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+</FORM>
+
+
+
+<%INIT>
+
+my $TemplateObj = new RT::Template($session{'CurrentUser'});
+my  ($title, @results, $current_subtab);
+
+my $subtabs = {
+                A => { title => loc('Select template'),
+                       path => "Admin/Global/Templates.html"
+                          },
+                B => { title => loc('New template'),
+                       path => "Admin/Global/Template.html?Create=1&Queue=0",
+                       separator => 1,
+                          }
+             };
+
+
+if ($Create) {
+  $current_subtab = "Admin/Global/Template.html?Create=1&Queue=0";
+  $title = loc("Create a template");
+}
+
+else {
+  if ($Template eq 'new') {
+      my ($val, $msg) =  $TemplateObj->Create(Queue => $Queue, Name => $Name);
+      Abort(loc("Could not create template: [_1]", $msg)) unless ($val);
+     push @results, $msg;
+    }
+    else {
+       $TemplateObj->Load($Template) || Abort(loc('No Template'));
+    }
+      $title = loc('Modify template [_1]', loc($TemplateObj->Name())); 
+  
+    
+}
+if ($TemplateObj->Id()) {
+  my @attribs = qw( Description Content Queue Name);
+  my @aresults = UpdateRecordObject( AttributesRef => \@attribs, 
+                                    Object => $TemplateObj, 
+                                    ARGSRef => \%ARGS);
+  $current_subtab = "Admin/Global/Template.html?Queue=0&Template=".$TemplateObj->Id();
+  $subtabs->{"C"} = { title => loc('Template #[_1]', $TemplateObj->Id()),
+                       path => "Admin/Global/Template.html?Queue=0&Template=".$TemplateObj->Id(),
+                       };
+  push @results, @aresults;
+}
+</%INIT>
+<%ARGS>
+$Queue => undef
+$Template => undef
+$Create => undef
+$Name => undef
+</%ARGS>
diff --git a/rt/html/Admin/Global/Templates.html b/rt/html/Admin/Global/Templates.html
new file mode 100644 (file)
index 0000000..77aab07
--- /dev/null
@@ -0,0 +1,53 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/SystemTabs, 
+    current_tab => 'Admin/Global/Templates.html', 
+    current_subtab => 'Admin/Global/Templates.html', 
+    subtabs => $subtabs, 
+    Title => $title &>
+<& /Admin/Elements/EditTemplates, title => $title, %ARGS &>
+</form>
+<%init>
+
+my $subtabs = {
+                A => { title => loc('Select template'),
+                       path => "Admin/Global/Templates.html"
+                          },
+                B => { title => loc('New template'),
+                       path => "Admin/Global/Template.html?Create=1&Queue=0",
+                       separator => 1,
+                          }
+             };
+my $title = loc("Modify templates which apply to all queues");
+
+my (@actions);
+
+</%init>
+
+
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Global/UserRights.html b/rt/html/Admin/Global/UserRights.html
new file mode 100644 (file)
index 0000000..aee82d1
--- /dev/null
@@ -0,0 +1,77 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => loc('Modify global user rights') &>
+<& /Admin/Elements/SystemTabs, 
+    current_tab => 'Admin/Global/UserRights.html',
+    Title => loc('Modify global user rights') &>  
+<& /Elements/ListActions, actions => \@results &>
+
+  <FORM METHOD=POST ACTION="UserRights.html">
+      
+<& /Elements/TitleBoxStart, title => loc('Modify global user rights.') &>
+      
+<TABLE>
+        
+%      while (my $Member = $Users->Next()) {
+% my $UserObj = $Member->MemberObj->Object();
+% my $group = RT::Group->new($session{'CurrentUser'});
+% $group->LoadACLEquivalenceGroup($Member->MemberObj);
+  <TR ALIGN=RIGHT> 
+       <TD VALIGN=TOP>
+           <% $UserObj->Name %>
+                 </TD>
+         <TD>
+           <& /Admin/Elements/SelectRights, PrincipalId => $group->PrincipalId,
+        Object => $RT::System  &>
+         </TD>
+       </TR>
+% }
+</TABLE>
+            
+      <& /Elements/TitleBoxEnd &>
+      <& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+      
+  </FORM>
+  
+<%INIT>
+  #Update the acls.
+  my @results =  ProcessACLChanges(\%ARGS);
+
+# {{{ Deal with setting up the display of current rights.
+
+
+# Find out which users we want to display ACL selects for
+my $Privileged = RT::Group->new($session{'CurrentUser'});
+$Privileged->LoadSystemInternalGroup('Privileged');
+my $Users = $Privileged->MembersObj();
+
+    
+  
+# }}}
+    
+</%INIT>
+
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/Admin/Global/index.html b/rt/html/Admin/Global/index.html
new file mode 100644 (file)
index 0000000..1749f4f
--- /dev/null
@@ -0,0 +1,64 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Callback, tabs => $tabs, %ARGS &>
+<& /Admin/Elements/Header, Title => loc('Admin/Global configuration') &>
+<& /Admin/Elements/SystemTabs, 
+    Title => loc('Admin/Global configuration') &>
+
+<ul>
+% foreach my $key (sort keys %$tabs) {
+<li><font size="+2"><a href="<% $tabs->{$key}{path} %>"><% $tabs->{$key}{title} %></a></font><br>
+<% $tabs->{$key}{text} %>
+</li>
+% }
+</ul>
+
+<%INIT>
+  my $tabs = {
+                
+               A => { title => loc('Scrips'),
+                           text => loc('Modify scrips which apply to all queues'),
+                           path => 'Scrips.html',
+                         },
+               B => { title => loc('Templates'),
+                        text => loc('Edit system templates'),
+                        path => 'Templates.html',
+                      },
+              
+                F => { title => loc('Custom Fields'),
+                        text => loc('Modify Custom Fields which apply to all queues'),
+                        path => 'CustomFields.html',
+                        },
+
+                G => { title => loc('Group Rights'),
+                                text => loc('Modify global group rights'),
+                                path => 'GroupRights.html',
+                      },
+                H => { title => loc('User Rights'),
+                                text => loc('Modify global user rights'),
+                                path => 'UserRights.html',
+                      }
+
+};
+</%INIT>
diff --git a/rt/html/Admin/Groups/GroupRights.html b/rt/html/Admin/Groups/GroupRights.html
new file mode 100644 (file)
index 0000000..6220259
--- /dev/null
@@ -0,0 +1,95 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => loc('Modify group rights for group [_1]', $GroupObj->Name) &>
+<& /Admin/Elements/GroupTabs, 
+    GroupObj => $GroupObj, 
+    current_tab => 'Admin/Groups/GroupRights.html?id='.$id, 
+    Title => loc('Modify group rights for group [_1]', $GroupObj->Name) &>
+<& /Elements/ListActions, actions => \@results &>
+
+  <FORM METHOD=POST ACTION="GroupRights.html">
+    <INPUT TYPE=HIDDEN NAME=id VALUE="<% $GroupObj->id %>">
+      
+<& /Elements/TitleBoxStart, title => loc('Modify group rights for group [_1]', $GroupObj->Name) &>
+      
+<h1><&|/l&>System groups</&></h1>
+<TABLE>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToSystemInternalGroups();
+%      while (my $Group = $Groups->Next()) {
+  <TR ALIGN=RIGHT> 
+       <TD VALIGN=TOP>
+           <% loc($Group->Type) %>
+                 </TD>
+         <TD>
+           <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+        PrincipalType => 'Group',
+        Object => $GroupObj  &>
+         </TD>
+       </TR>
+% }
+</TABLE>
+<h1><&|/l&>User defined groups</&></h1>
+<TABLE>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToUserDefinedGroups();    
+%      while (my $Group = $Groups->Next()) {
+  <TR ALIGN=RIGHT> 
+       <TD VALIGN=TOP>
+           <% $Group->Name %>
+                 </TD>
+         <TD>
+           <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+        PrincipalType => 'Group',
+        Object => $GroupObj  &>
+         </TD>
+       </TR>
+% }
+</TABLE>
+            
+      <& /Elements/TitleBoxEnd &>
+      <& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+      
+  </FORM>
+  
+<%INIT>
+  #Update the acls.
+  my @results =  ProcessACLChanges(\%ARGS);
+
+
+if (!defined $id) {
+    Abort(loc("No Group defined"));
+}
+
+my $GroupObj = RT::Group->new($session{'CurrentUser'});
+$GroupObj->Load($id) || Abort(loc("Couldn't load group [_1]",$id));
+
+my $Groups;
+    
+</%INIT>
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Groups/Members.html b/rt/html/Admin/Groups/Members.html
new file mode 100644 (file)
index 0000000..6e66966
--- /dev/null
@@ -0,0 +1,134 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => "RT/Admin/Edit the group ". $Group->Name &>
+<& /Admin/Elements/GroupTabs, GroupObj => $Group, 
+    current_tab => 'Admin/Groups/Members.html?id='.$id, 
+    Title => "RT/Admin/Edit the group ". $Group->Name &>
+<& /Elements/ListActions, actions => \@results &>
+
+
+<& /Elements/TitleBoxStart, title => loc('Editing membership for group [_1]', $Group->Name) &>
+
+<FORM ACTION="<%$RT::WebPath%>/Admin/Groups/Members.html" METHOD=POST>
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$Group->Id%>">
+<TABLE WIDTH="100%">
+<TR>
+<TD>
+<h3><&|/l&>Current members</&></h3>
+</TD>
+<TD>
+<h3><&|/l&>Add members</&></h3>
+</TD>
+</TR>
+
+<TR>
+<TD VALIGN=TOP>
+
+% if ($Group->MembersObj->Count == 0 ) {
+<i><&|/l&>(No members)</&></i>
+% } else {
+<i><&|/l&>(Check box to delete)</&></i>
+<br>
+<br>
+<&|/l&>Users</&>
+% my $UserMembers = $Group->MembersObj;
+% $UserMembers->LimitToUsers();
+<UL>
+% while (my $member = $UserMembers->Next()) {
+<LI><INPUT TYPE=CHECKBOX Name="DeleteMember-<%$member->MemberId%>">
+<%$member->MemberObj->Object->Name%> (<%$member->MemberObj->Object->RealName%>)
+% }
+</ul>
+<&|/l&>Groups</&>
+<ul>
+% my $GroupMembers = $Group->MembersObj;
+% $GroupMembers->LimitToGroups();
+% while (my $member = $GroupMembers->Next()) {
+<LI><INPUT TYPE=CHECKBOX Name="DeleteMember-<%$member->MemberId%>">
+<%$member->MemberObj->Object->Name%>
+% }
+% }
+</UL>
+</TD>
+<TD VALIGN=TOP>
+<& /Admin/Elements/SelectNewGroupMembers, Name => "AddMembers", Group => $Group &>
+</TD>
+</TR>
+</TABLE>
+<& /Elements/TitleBoxEnd &>
+<& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+</form>
+
+
+<%INIT>
+
+my $Group = new RT::Group($session{'CurrentUser'});
+$Group->Load($id) || Abort(loc('Could not load group'));
+
+my (@results);
+
+my $key;
+foreach $key (keys %ARGS) {
+
+if ($key =~ /^DeleteMember-(\d+)$/) {
+    my $id = $1; 
+    my ($val,$msg) = $Group->DeleteMember($id);
+    push (@results, $msg);
+}
+}
+
+# Make sure AddMembers is always an array
+my @AddMembers = (
+    ((ref $AddMembersUsers eq 'ARRAY') ? @{$AddMembersUsers} : ($AddMembersUsers)),
+    ((ref $AddMembersGroups eq 'ARRAY') ? @{$AddMembersGroups} : ($AddMembersGroups)),
+);
+
+foreach my $member (@AddMembers) {
+    next unless ($member);
+
+    my $principal;
+
+    if ($member =~ /^Group-(\d+)$/) {
+        $principal = RT::Group->new($session{'CurrentUser'});
+        $principal->Load($1);
+    } elsif ($member =~ /^User-(\d+)$/) {
+        $principal = RT::User->new($session{'CurrentUser'});
+        $principal->Load($1);
+    } else {
+        next;
+    }
+
+
+    my ($val, $msg) = $Group->AddMember($principal->PrincipalId);
+    push (@results, $msg);
+}
+
+
+</%INIT>
+
+<%ARGS>
+$AddMembersUsers  => undef
+$AddMembersGroups => undef
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Groups/Modify.html b/rt/html/Admin/Groups/Modify.html
new file mode 100644 (file)
index 0000000..c5e9158
--- /dev/null
@@ -0,0 +1,134 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title  &>
+
+<& /Admin/Elements/GroupTabs, 
+    GroupObj => $Group, 
+    current_tab => $current_tab, 
+    Title => $title &>
+<& /Elements/ListActions, actions => \@results &>
+
+
+
+<FORM ACTION="<%$RT::WebPath%>/Admin/Groups/Modify.html" METHOD=POST>
+
+%unless ($Group->Id) {
+<INPUT TYPE=HIDDEN NAME=id VALUE="new">
+% } else {
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$Group->Id%>">
+% }
+<TABLE>
+<TR><TD ALIGN=RIGHT>
+<&|/l&>Name</&>:
+</TD>
+<TD><INPUT name="Name" value="<%$Group->Name%>"></TD>
+</TR><TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Description</&>:</TD><TD COLSPAN=3><INPUT name="Description" value="<%$Group->Description%>" size=60></TD>
+</TR><TR>
+<TD COLSPAN=2>
+<INPUT TYPE=HIDDEN NAME="SetEnabled" VALUE="1">
+<INPUT TYPE=CHECKBOX NAME="Enabled" VALUE="1" <%$EnabledChecked%>> <&|/l&>Enabled (Unchecking this box disables this group)</&><BR>
+</TR>
+</TABLE>
+<& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+</form>
+<%INIT>
+
+my $current_tab;
+my  ($title, @results, $Disabled, $EnabledChecked);
+
+my $Group = RT::Group->new($session{'CurrentUser'});
+
+if ($Create) {
+    $current_tab = 'Admin/Groups/Modify.html?Create=1';
+    $title = loc("Create a new group");
+} 
+
+else {
+    $current_tab = 'Admin/Groups/Modify.html?id='.$id;
+    if ($id eq 'new' ) {
+       
+       my ($create_id, $create_msg) = $Group->CreateUserDefinedGroup(Name =>
+    "$Name");
+        unless ($create_id) {
+            Abort (loc("Group could not be created: [_1]", $create_msg));
+     }
+       $id = $Group->Id;
+    }
+    else {
+       $Group->Load($id) || Abort('Could not load group');
+    }
+
+
+    if ($id) {
+       $title = loc("Modify the group [_1]", $Group->Name);
+
+    }  
+
+    # If the create failed
+    else {
+       $title = loc("Create a new group");
+       $Create = 1;
+    }    
+    
+}
+
+if ($id) {
+    
+    my @fields = qw(Description Name );
+    my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields,
+                                           Object => $Group,
+                                           ARGSRef => \%ARGS );
+    push (@results,@fieldresults);
+}
+
+#we're asking about enabled on the web page but really care about disabled.
+if ($Enabled == 1) {
+    $Disabled = 0;
+}      
+else {
+    $Disabled = 1;
+}
+if  ( ($SetEnabled) and ( $Disabled != $Group->Disabled) ) { 
+    my  ($code, $msg) = $Group->SetDisabled($Disabled);
+    push @results, loc('Enabled status [_1]', loc_fuzzy($msg));
+}
+
+unless ($Group->Disabled()) {
+    $EnabledChecked ="CHECKED";
+}
+
+
+</%INIT>
+
+
+<%ARGS>
+$Create => undef
+$Name => undef
+$Description => undef
+$SetEnabled => undef
+$Enabled => undef
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Groups/UserRights.html b/rt/html/Admin/Groups/UserRights.html
new file mode 100644 (file)
index 0000000..0a87ef8
--- /dev/null
@@ -0,0 +1,92 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => loc('Modify user rights for group [_1]', $GroupObj->Name) &>
+<& /Admin/Elements/GroupTabs, 
+    GroupObj => $GroupObj, 
+    current_tab => 'Admin/Groups/UserRights.html?id='.$id, 
+    Title => loc('Modify user rights for group [_1]', $GroupObj->Name) &>  
+<& /Elements/ListActions, actions => \@results &>
+
+  <FORM METHOD=POST ACTION="UserRights.html">
+    <INPUT TYPE=HIDDEN NAME=id VALUE="<% $GroupObj->id %>">
+      
+<& /Elements/TitleBoxStart, title => loc('Modify user rights for group [_1]', $GroupObj->Name) &>
+      
+<TABLE>
+        
+%      while (my $Member = $Users->Next()) {
+% my $UserObj = $Member->MemberObj->Object();
+  <TR ALIGN=RIGHT> 
+       <TD VALIGN=TOP>
+           <% $UserObj->Name %>
+                 </TD>
+         <TD>
+           <& /Admin/Elements/SelectRights, PrincipalId => $Member->MemberObj->Id,
+        PrincipalType => 'User', 
+        Object => $GroupObj  &>
+         </TD>
+       </TR>
+% }
+      </TABLE>
+            
+      <& /Elements/TitleBoxEnd &>
+      <& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+      
+  </FORM>
+  
+<%INIT>
+  #Update the acls.
+  my @results =  ProcessACLChanges(\%ARGS);
+
+# {{{ Deal with setting up the display of current rights.
+
+
+#Define vars used in html above
+
+
+if (!defined $id) {
+    Abort(loc("No Group defined"));
+}
+
+my $GroupObj = RT::Group->new($session{'CurrentUser'});
+$GroupObj->Load($id) || Abort(loc("Couldn't load group [_1]",$id));
+
+# Find out which users we want to display ACL selects for
+my $Privileged = RT::Group->new($session{'CurrentUser'});
+$Privileged->LoadSystemInternalGroup('Privileged');
+my $Users = $Privileged->MembersObj();
+
+    
+  
+# }}}
+    
+</%INIT>
+
+<%ARGS>
+$id => undef
+$UserString => undef
+$UserOp => undef
+$UserField => undef
+</%ARGS>
diff --git a/rt/html/Admin/Groups/index.html b/rt/html/Admin/Groups/index.html
new file mode 100644 (file)
index 0000000..57c86c9
--- /dev/null
@@ -0,0 +1,43 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/GroupTabs, current_tab => 'Admin/Groups/',
+    current_subtab => 'Admin/Groups/', 
+    Title => $title &>
+
+
+<UL>
+%while ( my $Group = $Groups->Next) {
+<LI><A HREF="Modify.html?id=<%$Group->id%>"><%$Group->Name || loc('(empty)')%></a><BR>
+%}
+</UL>
+
+<%INIT>
+my $Groups = RT::Groups->new($session{'CurrentUser'});
+$Groups->LimitToUserDefinedGroups();
+my $title = loc('Select a group');
+
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/Admin/Queues/CustomField.html b/rt/html/Admin/Queues/CustomField.html
new file mode 100644 (file)
index 0000000..2515c3e
--- /dev/null
@@ -0,0 +1,60 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs, id => $QueueObj->Id, 
+    QueueObj => $QueueObj,                                                      
+    current_tab => 'Admin/Queues/CustomFields.html?id='.$QueueObj->id, 
+    current_subtab => $current_subtab, 
+    subtabs => $subtabs, 
+    Title => $title &>
+
+<& /Admin/Elements/EditCustomField, title => $title,  %ARGS &>
+
+<%INIT>
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($Queue);
+
+my ($title, $current_subtab);
+
+unless($QueueObj->id) {
+    Abort(loc("Queue [_1] not found", $Queue));
+}
+if ($CustomField) {
+    $title = loc('Modify a CustomField for queue [_1]', $QueueObj->Name()); 
+}else {
+    $current_subtab = "Admin/Queues/CustomField.html?create=1&Queue=".$QueueObj->id;
+    $title = loc('Create a CustomField for queue [_1]', $QueueObj->Name()); 
+}
+
+my $subtabs = {
+                A => { title => loc('New custom field'),
+                       path => "Admin/Queues/CustomField.html?create=1&Queue=".$QueueObj->id
+                          }
+             };
+
+</%INIT>
+<%ARGS>
+$CustomField => undef
+$Queue => undef
+</%ARGS>
diff --git a/rt/html/Admin/Queues/CustomFields.html b/rt/html/Admin/Queues/CustomFields.html
new file mode 100644 (file)
index 0000000..78c6c27
--- /dev/null
@@ -0,0 +1,48 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs, id => $Queue->id, 
+    current_tab => 'Admin/Queues/CustomFields.html?id='.$id, 
+    QueueObj => $Queue,                                                      
+    subtabs => $subtabs,
+    Title => $title
+    &>
+
+<& /Admin/Elements/EditCustomFields, title => $title, %ARGS &>
+<%INIT>
+my $Queue = new RT::Queue($session{'CurrentUser'});
+$Queue->Load($id);
+my $CustomFields = RT::CustomFields->new($RT::SystemUser);
+$CustomFields->LimitToQueue($Queue->Id);
+my $subtabs = {
+        A => { title => loc('New custom field'),
+               path => "Admin/Queues/CustomField.html?create=1&Queue=".$id,
+                          }
+             };
+
+my $title=  loc('Edit Custom Fields for [_1]', $Queue->Name);
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Queues/GroupRights.html b/rt/html/Admin/Queues/GroupRights.html
new file mode 100644 (file)
index 0000000..a1ac709
--- /dev/null
@@ -0,0 +1,110 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => loc('Modify group rights for queue [_1]', $QueueObj->Name) &>
+<& /Admin/Elements/QueueTabs, id => $id, 
+    QueueObj => $QueueObj,                                                      
+    current_tab => $current_tab, 
+    Title => loc('Modify group rights for queue [_1]', $QueueObj->Name) &>
+<& /Elements/ListActions, actions => \@results &>
+
+  <FORM METHOD=POST ACTION="GroupRights.html">
+    <INPUT TYPE=HIDDEN NAME=id VALUE="<% $QueueObj->id %>">
+      
+      
+<h1><&|/l&>System groups</&></h1>
+<TABLE>
+<& /Elements/Callback, QueueObj => $QueueObj, results => \@results, %ARGS &>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToSystemInternalGroups();
+%      while (my $Group = $Groups->Next()) {
+  <TR ALIGN=RIGHT> 
+       <TD VALIGN=TOP>
+           <% loc($Group->Type) %>
+                 </TD>
+         <TD>
+           <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+        Object => $QueueObj  &>
+         </TD>
+       </TR>
+% }
+</TABLE>
+<h1><&|/l&>Roles</&></h1>
+<TABLE>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToRolesForQueue($QueueObj->Id);
+%      while (my $Group = $Groups->Next()) {
+  <TR ALIGN=RIGHT> 
+       <TD VALIGN=TOP>
+           <% loc($Group->Type) %>
+                 </TD>
+         <TD>
+           <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+        Object => $QueueObj  &>
+         </TD>
+       </TR>
+% }
+</TABLE>
+<h1><&|/l&>User defined groups</&></h1>
+<TABLE>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToUserDefinedGroups();    
+%      while (my $Group = $Groups->Next()) {
+  <TR ALIGN=RIGHT> 
+       <TD VALIGN=TOP>
+           <% $Group->Name %>
+                 </TD>
+         <TD>
+           <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+        Object => $QueueObj  &>
+         </TD>
+       </TR>
+% }
+</TABLE>
+            
+      <& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+      
+  </FORM>
+  
+<%INIT>
+  #Update the acls.
+  my @results =  ProcessACLChanges(\%ARGS);
+
+
+if (!defined $id) {
+    Abort(loc("No Queue defined"));
+}
+
+my $QueueObj = RT::Queue->new($session{'CurrentUser'});
+$QueueObj->Load($id) || Abort(loc("Couldn't load queue [_1]",$id));
+
+my $Groups;
+my $current_tab;
+$current_tab = 'Admin/Queues/GroupRights.html?id='.$QueueObj->id;
+    
+</%INIT>
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Queues/Modify.html b/rt/html/Admin/Queues/Modify.html
new file mode 100644 (file)
index 0000000..46608eb
--- /dev/null
@@ -0,0 +1,163 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => loc('Admin/Queue/Basics') &>
+<& /Admin/Elements/QueueTabs, id => $QueueObj->id, 
+    QueueObj => $QueueObj,
+    current_tab => $current_tab, 
+    Title => loc('Admin/Queue/Basics') &>
+<& /Elements/ListActions, actions => \@results &>
+
+
+
+<FORM ACTION="<%$RT::WebPath%>/Admin/Queues/Modify.html" METHOD=POST>
+%if ($Create ) { 
+<INPUT TYPE=HIDDEN NAME=id VALUE="new">
+% } else {
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$QueueObj->Id%>">
+% }
+
+<TABLE>
+<TR><TD ALIGN=RIGHT>
+<&|/l&>Queue Name</&>: 
+</TD>
+<TD><INPUT name="Name" value="<% ($Create) ? "" : $QueueObj->Name %>"></TD>
+</TR><TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Description</&>:</TD><TD COLSPAN=3><INPUT name="Description" value="<% ($Create) ? "" : $QueueObj->Description %>" size=60></TD></TR>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Correspondence Address</&>:
+</TD><TD>
+<INPUT name="CorrespondAddress" value="<% ($Create) ? "" : $QueueObj->CorrespondAddress %>">
+<BR><font size="-1"><i><&|/l , $RT::CorrespondAddress&>(If left blank, will default to [_1]</&></i></font>
+</TD>
+<TD ALIGN=RIGHT>
+
+<&|/l&>Comment Address</&>: </TD><TD>
+<INPUT NAME="CommentAddress" value="<% ($Create) ? "" : $QueueObj->CommentAddress %>">
+<BR><font size="-1"><i><&|/l , $RT::CommentAddress&>(If left blank, will default to [_1]</&></i></font>
+</TD>
+</TR><TR>
+
+<TD ALIGN=RIGHT>
+<&|/l&>Priority starts at</&>: 
+</TD><TD><INPUT NAME="InitialPriority" value="<% ($Create) ? "" : $QueueObj->InitialPriority %>">
+</TD>
+<TD ALIGN=RIGHT>
+<&|/l&>Over time, priority moves toward</&>:
+</TD><TD><INPUT NAME="FinalPriority" value="<% ($Create) ? "" : $QueueObj->FinalPriority %>">
+</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Requests should be due in</&>:
+</TD><TD>
+<INPUT NAME="DefaultDueIn" VALUE="<% ($Create) ? "" : $QueueObj->DefaultDueIn%>"> <&|/l&>days</&>.
+</TD>
+</TR>
+<TR>
+<TD>
+</TD>
+<TD COLSPAN=4><INPUT TYPE=HIDDEN NAME="SetEnabled" VALUE="1">
+<INPUT TYPE=CHECKBOX NAME="Enabled" VALUE="1" <%$EnabledChecked%>> <&|/l&>Enabled (Unchecking this box disables this queue)</&><BR>
+<& /Elements/Callback, QueueObj => $QueueObj, results => \@results, %ARGS &>
+</TD>
+</TR>
+
+</TABLE>
+<& /Elements/Submit &>
+</form>
+
+
+
+<%INIT>
+my $current_tab;
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($id);
+my  ($title, @results, $Disabled, $EnabledChecked);
+$EnabledChecked = "CHECKED";
+
+if ($Create) {
+    $current_tab = 'Admin/Queues/Modify.html?Create=1';
+    $title = loc("Create a queue");
+} else {
+    if ($id eq 'new') {
+       my ($val, $msg) =  $QueueObj->Create(Name => $Name);
+       delete $session{'create_in_queues'};
+       if ($val == 0 ) {
+           Abort("$msg");
+       }
+       else {
+               push @results, $msg;
+       }    
+     }
+     else {
+        $QueueObj->Load($id) || $QueueObj->Load($Name) || Abort("Couldn't load queue '$Name'");
+    }
+        $title = loc('Editing Configuration for queue [_1]', $QueueObj->Name);
+    
+    $current_tab = 'Admin/Queues/Modify.html?id='.$QueueObj->id;
+}
+if ($QueueObj->Id()) {
+    delete $session{'create_in_queues'};
+my @attribs= qw(Description CorrespondAddress CommentAddress Name 
+                InitialPriority FinalPriority DefaultDueIn);
+
+  @results = UpdateRecordObject( AttributesRef => \@attribs, 
+                                   Object => $QueueObj, 
+                                   ARGSRef => \%ARGS);
+
+  #we're asking about enabled on the web page but really care about disabled.
+  if ($Enabled == 1) {
+      $Disabled = 0;
+  }    
+  else {
+      $Disabled = 1;
+  }
+  if  ( ($SetEnabled) and ( $Disabled != $QueueObj->Disabled) ) { 
+      my  ($code, $msg) = $QueueObj->SetDisabled($Disabled);
+      push @results, loc('Enabled status [_1]', loc_fuzzy($msg));
+  }
+  
+  if ($QueueObj->Disabled()) {
+      $EnabledChecked ="";
+  }
+}
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+$result => undef
+$Name => undef
+$Create => undef
+$Description => undef
+$CorrespondAddress => undef
+$CommentAddress => undef
+$InitialPriority => undef
+$FinalPriority => undef
+$DefaultDueIn => undef
+$SetEnabled => undef
+$Enabled => undef
+</%ARGS>
diff --git a/rt/html/Admin/Queues/People.html b/rt/html/Admin/Queues/People.html
new file mode 100644 (file)
index 0000000..e0a7345
--- /dev/null
@@ -0,0 +1,186 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc('Modify people related to queue [_1]', $QueueObj->Name) &>
+<& /Admin/Elements/QueueTabs, id => $id, 
+    QueueObj => $QueueObj,                                                      
+    current_tab => $current_tab, 
+    Title => loc('Modify people related to queue [_1]', $QueueObj->Name) &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<FORM METHOD=POST ACTION="People.html">
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$QueueObj->Id%>">
+
+<TABLE WIDTH=100%>
+<TR>
+<TD VALIGN=TOP >
+
+<h3><&|/l&>Current watchers</&></h3>
+
+
+<&|/l&>Cc</&>:
+
+<& /Admin/Elements/EditQueueWatchers, QueueObj => $QueueObj, Watchers => $QueueObj->Cc &>
+
+<&|/l&>Administrative Cc</&>:
+
+<& /Admin/Elements/EditQueueWatchers, QueueObj => $QueueObj, Watchers => $QueueObj->AdminCc &>
+
+
+</TD>
+<TD VALIGN=TOP>
+<h3><&|/l&>New watchers</&></h3>
+
+<&|/l&>Find people whose</&><BR>
+<& /Elements/SelectUsers &>
+<input type=submit name="OnlySearchForPeople" value="<&|/l&>Go!</&>">
+<BR>
+<&|/l&>Find group whose</&><BR>
+<& /Elements/SelectGroups &>
+<input type=submit name="OnlySearchForGroup" value="<&|/l&>Go!</&>">
+
+<p>
+<&|/l&>Add new watchers</&>:<br>
+<p>
+<b><&|/l&>Users</&></b>
+% if ($user_msg) {
+<br>
+<i><%$user_msg%></i>
+% } elsif ($Users) {
+<ul>
+% while (my $u = $Users->Next ) {
+<li><&/Elements/SelectWatcherType, Scope=>'queue', Name =>
+"Queue-AddWatcher-Principal-".$u->PrincipalId &> <%$u->Name%>
+(<%$u->RealName%>)
+% }
+</ul>
+% }
+
+<p>
+<b><&|/l&>Groups</&></b>
+
+% if ($group_msg) {
+<br>
+<i><%$group_msg%></i>
+% } elsif ($Groups) {
+<ul>
+% while (my $g = $Groups->Next ) {
+<li><&/Elements/SelectWatcherType, Scope=>'queue', Name =>
+"Queue-AddWatcher-Principal-".$g->PrincipalId &> <%$g->Name%>
+(<%$g->Description%>)
+% }
+</ul>
+% }
+
+</TD>
+</TR>
+</TABLE>
+
+
+
+
+<& /Elements/Submit, Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), Reset => 1 &>
+</form>
+
+<%INIT>
+
+my $current_tab;
+my ($field, @results, $User, $Users, $Groups, $watcher, $user_msg, $group_msg);
+
+# {{{ Load the queue
+#If we get handed two ids, mason will make them an array. bleck.
+# We want teh first one. Just because there's no other sensible way
+# to deal
+
+
+
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($id) || Abort(loc("Couldn't load queue", $id));
+# }}}
+
+# {{{ Delete deletable watchers
+
+foreach my $key (keys %ARGS) {
+        my $id = $QueueObj->Id;
+
+    if (($key =~ /^Queue-$id-DelWatcher-Type-(.*?)-Principal-(\d*)$/)) {;
+           my ($code, $msg) = $QueueObj->DeleteWatcher(Type => $1,
+                                                    PrincipalId => $2);
+           push @results, $msg;
+    }
+}
+# }}}
+
+# {{{ Add new watchers
+foreach my  $key (keys %ARGS) {
+    #They're in this order because otherwise $1 gets clobbered :/
+    if ( ($ARGS{$key} =~ /^(AdminCc|Cc)$/) and
+        ($key =~ /^Queue-AddWatcher-Principal-(\d*)$/) ) {
+       $RT::Logger->debug("Adding a watcher $1 to ".$ARGS{$key}."\n");
+       my ($code, $msg) = $QueueObj->AddWatcher(Type => $ARGS{$key},
+                                                            PrincipalId => $1);
+       push @results, $msg;
+    }
+}
+
+# }}}
+
+
+if (!length $ARGS{'UserString'}) {
+$user_msg = loc("No principals selected.");
+ }
+else {
+    $Users = new RT::Users($session{'CurrentUser'});
+    $Users->Limit(FIELD => $ARGS{'UserField'},
+                 VALUE => $ARGS{'UserString'},
+                 OPERATOR => $ARGS{'UserOp'});
+     }
+
+if (!length $ARGS{'GroupString'}) {
+$group_msg = loc("No principals selected.");
+ }
+else {
+$Groups = new RT::Groups($session{'CurrentUser'});
+$Groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined');
+$Groups->Limit(FIELD => $ARGS{'GroupField'},
+               VALUE => $ARGS{'GroupString'},
+               OPERATOR => $ARGS{'GroupOp'});
+     }
+
+$current_tab = 'Admin/Queues/People.html?id='.$QueueObj->id;
+</%INIT>
+
+<%ARGS>
+$UserField => 'Name'
+$UserOp => '='
+$UserString => undef
+$GroupField => 'Name'
+$GroupOp => '='
+$GroupString => undef
+$Type => undef
+$id => undef
+</%ARGS>
+
diff --git a/rt/html/Admin/Queues/Scrip.html b/rt/html/Admin/Queues/Scrip.html
new file mode 100644 (file)
index 0000000..edbfcd6
--- /dev/null
@@ -0,0 +1,67 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs, id => $QueueObj->Id, 
+    QueueObj => $QueueObj,                                                      
+    current_tab => 'Admin/Queues/Scrips.html?id='.$QueueObj->id, 
+    current_subtab => $current_subtab, 
+    subtabs => $subtabs, 
+    Title => $title &>
+
+<& /Admin/Elements/EditScrip, title => $title,  %ARGS &>
+<%init>
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($Queue);
+
+my ($title, $current_subtab);
+my $subtabs = {                                                                               
+     A => { title => loc('Select scrip'),                                                     
+            path => "Admin/Queues/Scrips.html?id=".$QueueObj->id,
+               },                                                                             
+     B => { title => loc('New scrip'),                                                        
+            path => "Admin/Queues/Scrip.html?create=1&Queue=".$QueueObj->id,
+            separator => 1,                                                                   
+               }, 
+          };   
+
+unless($QueueObj->id) {
+    Abort(loc("Queue [_1] not found",$id));
+}
+if ($id) {
+    $current_subtab = "Admin/Queues/Scrip.html?id=".$id."&Queue=".$QueueObj->id;
+    $title = loc("Modify a scrip for queue [_1]", $QueueObj->Name);
+    $subtabs->{"C"} = { title => loc("Scrip #[_1]",$QueueObj->id),
+                       path => "Admin/Queues/Scrip.html?id=$id&Queue=".$QueueObj->id };
+} else {
+    $current_subtab = "Admin/Queues/Scrip.html?create=1&Queue=".$QueueObj->id;
+    $title = loc("Create a scrip for queue [_1]", $QueueObj->Name);
+}
+                                                                                             
+
+</%init>
+
+<%ARGS>
+$id => undef  
+$Queue => undef
+</%ARGS>
diff --git a/rt/html/Admin/Queues/Scrips.html b/rt/html/Admin/Queues/Scrips.html
new file mode 100644 (file)
index 0000000..60b2831
--- /dev/null
@@ -0,0 +1,63 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs, id => $QueueObj->id, 
+    QueueObj => $QueueObj,                                                      
+    current_tab => 'Admin/Queues/Scrips.html?id='.$id, 
+    current_subtab => 'Admin/Queues/Scrips.html?id='.$id, 
+    subtabs => $subtabs, 
+    Title => $title &>
+
+% if (!$QueueObj->Disabled) { # Global scrips does not apply to disabled queues
+<h2><&|/l&>Scrips which apply to all queues</&></h2>
+<& /Admin/Elements/ListGlobalScrips &>
+<BR> 
+% }
+<& /Admin/Elements/EditScrips, title => $title, %ARGS &>
+<%init>
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($id);
+
+my $title;
+
+if ($QueueObj->id) {
+    $title = loc("Modify scrips for queue [_1]", $QueueObj->Name);
+} else {
+    Abort(loc("Queue [_1] not found",$id));
+}
+
+my $subtabs = {
+        A => { title => loc('Select scrip'),
+               path => "Admin/Queues/Scrips.html?id=".$id,
+                          },
+        B => { title => loc('New scrip'),
+               path => "Admin/Queues/Scrip.html?create=1&Queue=".$id,
+            separator => 1,
+                          }
+             };
+</%init>
+
+<%ARGS>
+$id => undef         #some identifier that a Queue could 
+</%ARGS>
diff --git a/rt/html/Admin/Queues/Template.html b/rt/html/Admin/Queues/Template.html
new file mode 100644 (file)
index 0000000..994de61
--- /dev/null
@@ -0,0 +1,101 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs, id => $Queue, 
+    QueueObj => $TemplateObj->QueueObj,
+     current_tab => 'Admin/Queues/Templates.html?id='.$Queue,
+     current_subtab => $current_subtab, 
+     subtabs => $subtabs, 
+     Title => $title &>
+<& /Elements/ListActions, actions => \@results &>
+
+<FORM METHOD=POST ACTION="Template.html">
+%if ($Create ) {
+<INPUT TYPE=HIDDEN NAME="Template" VALUE="new">
+% } else {
+<INPUT TYPE=HIDDEN NAME="Template" VALUE="<%$TemplateObj->Id%>">
+% }
+
+%# hang onto the queue id
+<INPUT TYPE=HIDDEN name="Queue" value="<%$Queue%>">
+<& /Admin/Elements/ModifyTemplate, Name => $TemplateObj->Name, Description =>
+$TemplateObj->Description, Content => $TemplateObj->Content &> 
+<& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+</FORM>
+
+
+<%INIT>
+
+my $TemplateObj = new RT::Template($session{'CurrentUser'});
+my  ($title, @results, $current_subtab);
+
+my $subtabs = {
+                A => { title => loc('Select template'),
+                       path => "Admin/Queues/Templates.html?id=$Queue"
+                          },
+                B => { title => loc('New template'),
+                       path => "Admin/Queues/Template.html?Create=1&Queue=$Queue",
+                       separator => 1,
+                          }
+             };
+
+if ($Create) {
+  $title = loc("Create a template");
+  $current_subtab = "Admin/Queues/Template.html?create=1&Queue=".$Queue;
+}
+
+else {
+  if ($Template eq 'new') {
+      my ($val, $msg) =  $TemplateObj->Create(Queue => $Queue, Name => $Name);
+      Abort(loc("Could not create template: [_1]", $msg)) unless ($val);
+     push @results, $msg;
+    }
+    else {
+       $TemplateObj->Load($Template) || Abort(loc('No Template'));
+    }
+     $title = loc('Modify template [_1]', loc($TemplateObj->Name())); 
+  
+    
+}
+if ($TemplateObj->Id()) {
+  $Queue = $TemplateObj->Queue;
+
+  my @attribs = qw( Description Content Queue Name);
+  my @aresults = UpdateRecordObject( AttributesRef => \@attribs, 
+                                    Object => $TemplateObj, 
+                                    ARGSRef => \%ARGS);
+  $current_subtab = "Admin/Queues/Template.html?Queue=$Queue&Template=".$TemplateObj->Id();
+  $subtabs->{"C"} = { title => loc('Template #[_1]', $TemplateObj->Id()),
+                       path => "Admin/Queues/Template.html?Queue=$Queue&Template=".$TemplateObj->Id(),
+                       };
+  push @results, @aresults;
+}
+
+</%INIT>
+<%ARGS>
+$Queue => undef
+$Template => undef
+$Create => undef
+$Name => undef
+</%ARGS>
diff --git a/rt/html/Admin/Queues/Templates.html b/rt/html/Admin/Queues/Templates.html
new file mode 100644 (file)
index 0000000..98bdf24
--- /dev/null
@@ -0,0 +1,57 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs, id => $QueueObj->id, 
+    current_tab => 'Admin/Queues/Templates.html?id='.$id, 
+    current_subtab => 'Admin/Queues/Templates.html?id='.$id, 
+        QueueObj => $QueueObj,
+    subtabs => $subtabs, 
+    Title => $title &>
+
+<& /Admin/Elements/EditTemplates, title => $title, %ARGS &>
+
+<%INIT>
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($id);
+
+my ($title, $current_subtab);
+
+if ($QueueObj->id) {
+    $title = loc("Edit Templates for queue [_1]", $QueueObj->Name);
+} else {
+    Abort(loc("Queue [_1] not found",$id));
+}
+my $subtabs = {
+        A => { title => loc('Select template'),
+               path => "Admin/Queues/Templates.html?id=".$id,
+                  },
+        B => { title => loc('New template'),
+               path => "Admin/Queues/Template.html?Create=1&Queue=".$id,
+                  }
+             };
+
+</%INIT>
+<%ARGS>
+$id => undef         #some identifier that a Queue could 
+</%ARGS>
diff --git a/rt/html/Admin/Queues/UserRights.html b/rt/html/Admin/Queues/UserRights.html
new file mode 100644 (file)
index 0000000..aeb55c7
--- /dev/null
@@ -0,0 +1,90 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => loc('Modify user rights for queue [_1]', $QueueObj->Name) &>
+<& /Admin/Elements/QueueTabs, id => $id,
+    QueueObj => $QueueObj,                                                      
+    current_tab => $current_tab, 
+    Title => loc('Modify user rights for queue [_1]', $QueueObj->Name) &>
+<& /Elements/ListActions, actions => \@results &>
+
+  <FORM METHOD=POST ACTION="UserRights.html">
+    <INPUT TYPE=HIDDEN NAME=id VALUE="<% $QueueObj->id %>">
+      
+      
+<TABLE>
+<& /Elements/Callback, QueueObj => $QueueObj, results => \@results, %ARGS &>
+%      while (my $Member = $Users->Next()) {
+% my $UserObj = $Member->MemberObj->Object();
+% my $group = RT::Group->new($session{'CurrentUser'});
+% $group->LoadACLEquivalenceGroup($Member->MemberObj);
+  <TR ALIGN=RIGHT> 
+       <TD VALIGN=TOP>
+           <% $UserObj->Name %>
+                 </TD>
+         <TD>
+           <& /Admin/Elements/SelectRights, PrincipalId=> $group->PrincipalId,
+        Object => $QueueObj  &>
+         </TD>
+       </TR>
+% }
+      </TABLE>
+            
+      <& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+      
+  </FORM>
+  
+<%INIT>
+  #Update the acls.
+  my @results =  ProcessACLChanges(\%ARGS);
+
+# {{{ Deal with setting up the display of current rights.
+
+
+
+if (!defined $id) {
+    Abort(loc("No Queue defined"));
+}
+
+my $QueueObj = RT::Queue->new($session{'CurrentUser'});
+$QueueObj->Load($id) || Abort(loc("Couldn't load queue [_1]",$id));
+
+# Find out which users we want to display ACL selects for
+my $Privileged = RT::Group->new($session{'CurrentUser'});
+$Privileged->LoadSystemInternalGroup('Privileged');
+my $Users = $Privileged->MembersObj();
+
+    
+  
+# }}}
+my $current_tab;
+$current_tab = 'Admin/Queues/UserRights.html?id='.$QueueObj->id;
+</%INIT>
+
+<%ARGS>
+$id => undef
+$UserString => undef
+$UserOp => undef
+$UserField => undef
+</%ARGS>
diff --git a/rt/html/Admin/Queues/index.html b/rt/html/Admin/Queues/index.html
new file mode 100644 (file)
index 0000000..f733c25
--- /dev/null
@@ -0,0 +1,61 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => loc("Admin queues") &>
+<& /Admin/Elements/QueueTabs, current_tab => 'Admin/Queues/', 
+    current_subtab => 'Admin/Queues/', 
+    Title => loc("Admin queues") &>
+
+
+
+<%$caption%>:<BR>
+<UL>
+%if ($queues->Count == 0) {
+<LI> <i><&|/l&>No queues matching search criteria found.</&></i>
+% }
+%while ( $queue = $queues->Next) {
+<LI><A HREF="Modify.html?id=<%$queue->id%>"><%$queue->Name%></a></LI>
+%}
+</UL>
+<BR>
+<FORM METHOD=POST ACTION="<% $RT::WebPath %>/Admin/Queues/">
+<input type="checkbox" name="FindDisabledQueues"> <&|/l&>Include disabled queues in listing.</&>
+<div align=right><input type=submit value="<&|/l&>Go!</&>"></div> 
+</FORM>
+
+<%INIT>
+my ($queue, $caption);
+my $queues = new RT::Queues($session{'CurrentUser'});
+$queues->UnLimit();
+
+if ($FindDisabledQueues) {
+        $caption = loc("All Queues");
+        $queues->{'find_disabled_rows'} = 1;
+} else {
+    $caption = loc("Enabled Queues");
+}
+
+</%INIT>
+<%ARGS>
+$FindDisabledQueues => 0
+</%ARGS>
diff --git a/rt/html/Admin/Users/Modify.html b/rt/html/Admin/Users/Modify.html
new file mode 100644 (file)
index 0000000..370c2e8
--- /dev/null
@@ -0,0 +1,347 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title  &>
+<& /Admin/Elements/UserTabs, 
+    id => $id, 
+    UserObj => $UserObj,
+    current_subtab => $current_tab, 
+    Title => $title &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<FORM ACTION="<%$RT::WebPath%>/Admin/Users/Modify.html" METHOD=POST>
+%if ($Create) {
+<INPUT TYPE=HIDDEN NAME=id VALUE="new">
+% } else {
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$UserObj->Id%>">
+% }
+<TABLE WIDTH=100% BORDER=0>
+<TR>
+
+<TD VALIGN=TOP ROWSPAN=2>
+<& /Elements/TitleBoxStart, title => loc('Identity') &>
+
+<TABLE>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Username</&>:
+</TD><TD>
+<input name="Name" value="<%$UserObj->Name%>"> <b><&|/l&>(required)</&></b>
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Email</&>:
+</TD><TD>
+<input name="EmailAddress" value="<%$UserObj->EmailAddress%>">
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Real Name</&>: 
+</TD><TD>
+<input name="RealName" value="<%$UserObj->RealName%>">
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Nickname</&>: 
+</TD><TD>
+<input name="NickName" value="<%$UserObj->NickName%>">
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Unix login</&>: 
+</TD><TD>
+<input name="Gecos" value="<%$UserObj->Gecos%>">
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Extra info</&>: 
+</TD><TD>
+<textarea name="FreeformContactInfo" cols=20 rows=5><%$UserObj->FreeformContactInfo%></TEXTAREA>
+</TD></TR>
+</TABLE>
+<& /Elements/TitleBoxEnd &>
+<br>
+<& /Elements/TitleBoxStart, title => loc('Access control') &>
+<INPUT TYPE=HIDDEN NAME="SetEnabled" VALUE="1">
+<INPUT TYPE=CHECKBOX NAME="Enabled" VALUE="1" <%$EnabledChecked%>>
+<&|/l&>Let this user access RT</&><BR>
+
+
+<INPUT TYPE=HIDDEN NAME="SetPrivileged" VALUE="1">
+<INPUT TYPE=CHECKBOX NAME="Privileged" VALUE="1" <%$PrivilegedChecked%>> <&|/l&>Let this user be granted rights</&><BR>
+                   
+% unless ($RT::WebExternalAuth and !$RT::WebFallbackToInternalAuth) {
+<TABLE>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>New Password</&>:
+</TD>
+<TD ALIGN=LEFT>
+<input type=password name="Pass1">
+</TD>
+</TR>
+<TR><TD ALIGN=RIGHT>
+<&|/l&>Retype Password</&>:
+</TD>
+<TD>
+<input type=password name="Pass2">
+</TD>
+</TR>
+</TABLE>
+% }
+<& /Elements/TitleBoxEnd &>
+</TD>
+</TR>
+<TR>
+
+<TD VALIGN=TOP>
+<& /Elements/TitleBoxStart, title => loc('Location') &>
+<TABLE>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Organization</&>: 
+</TD><TD>
+<input name="Organization" value="<%$UserObj->Organization%>">
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Address1</&>: 
+</TD><TD>
+<input name="Address1" value="<%$UserObj->Address1%>">
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Address2</&>: 
+</TD><TD>
+<input name="Address2" value="<%$UserObj->Address2%>">
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>City</&>: 
+</TD><TD>
+<input name="City" value="<%$UserObj->City%>" size=14>
+
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>State</&>: 
+</TD><TD>
+<input name="State" value="<%$UserObj->State%>" size=3>
+
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Zip</&>: 
+</TD><TD>
+<input name="Zip" value="<%$UserObj->Zip%>" size=9>
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Country</&>: 
+</TD><TD>
+<input name="Country" value="<%$UserObj->Country%>">
+</TD></TR>
+</TABLE>
+<& /Elements/TitleBoxEnd &>
+<br>
+<& /Elements/TitleBoxStart, title => loc('Phone numbers') &>
+<TABLE>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Residence</&>: 
+</TD><TD>
+<input name="HomePhone" value="<%$UserObj->HomePhone%>" size=13><br>
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Work</&>: 
+</TD><TD>
+<input name="WorkPhone" value="<%$UserObj->WorkPhone%>" size=13><br>
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Mobile</&>: 
+</TD><TD>
+<input name="MobilePhone" value="<%$UserObj->MobilePhone%>" size=13><br>
+</TD></TR>
+<TR><TD ALIGN="RIGHT">
+<&|/l&>Pager</&>: 
+</TD><TD>
+<input name="PagerPhone" value="<%$UserObj->PagerPhone%>" size=13><br>
+<& /Elements/TitleBoxEnd &>
+</TD>
+
+<TR>
+</TR>
+</TABLE>
+<TR>
+<TD colspan="2">
+<& /Elements/TitleBoxStart, title => loc('Comments about this user') &>
+<TEXTAREA name="Comments" COLS=80 ROWS=5 WRAP=VIRTUAL><%$UserObj->Comments%>
+</TEXTAREA>
+<& /Elements/TitleBoxEnd &>
+%if ($UserObj->Privileged) {
+<BR>
+<& /Elements/TitleBoxStart, title => loc('Signature') &>
+<TEXTAREA COLS=80 ROWS=5 name="Signature" WRAP=HARD>
+<%$UserObj->Signature%></TEXTAREA>
+<& /Elements/TitleBoxEnd &>
+% }
+
+</TD>
+</TR>
+</TABLE>
+
+<& /Elements/Submit &>
+</form>
+
+<%INIT>
+
+my $current_tab;
+my $UserObj = new RT::User($session{'CurrentUser'});
+my ($title, $PrivilegedChecked, $EnabledChecked, $Disabled, $result, @results);
+
+my ($val, $msg);
+
+if ($Create) {
+    $current_tab = 'Admin/Users/Modify.html?Create=1';
+    $title = loc("Create a new user");
+} 
+else {
+
+    $current_tab = 'Admin/Users/Modify.html?id='.$id;
+    if ($id eq 'new') {
+       ($val, $msg) = $UserObj->Create( Name => $Name,
+                                        EmailAddress => $ARGS{'EmailAddress'}
+                                      );
+       if ($val) {
+               push @results, $msg;
+       } else {
+               push @results, loc('User could not be created: [_1]', $msg);
+       }       
+       
+    }
+    else {
+       $UserObj->Load($id) || $UserObj->Load($Name) || Abort("Couldn't load user '$Name'");
+       $val = $UserObj->Id();
+    }
+
+    if ($val) {
+       $title = loc("Modify the user [_1]", $UserObj->Name);
+    }  
+
+    # If the create failed
+    else {
+       $title = loc("Create a new user");
+       $Create = 1;
+    }    
+
+    
+
+}
+
+
+
+
+# If we have a user to modify, lets try. 
+if ($UserObj->Id) {
+    
+    my @fields = qw(Name Comments Signature EmailAddress FreeformContactInfo 
+                   Organization RealName NickName Lang EmailEncoding WebEncoding 
+                   ExternalContactInfoId ContactInfoSystem Gecos ExternalAuthId 
+                   AuthSystem HomePhone WorkPhone MobilePhone PagerPhone Address1
+               Address2 City State Zip Country 
+                  );
+    
+    my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields,
+                                           Object => $UserObj,
+                                           ARGSRef => \%ARGS );
+    push (@results,@fieldresults);
+
+
+# {{{ Deal with special fields: Privileged, Enabled and Password
+if  ( ($SetPrivileged) and ( $Privileged != $UserObj->Privileged) ) {
+my  ($code, $msg) = $UserObj->SetPrivileged($Privileged);
+     push @results, loc('Privileged status: [_1]', loc_fuzzy($msg));
+}
+
+#we're asking about enabled on the web page but really care about disabled.
+if ($Enabled == 1) {
+    $Disabled = 0;
+}      
+else {
+    $Disabled = 1;
+}
+if  ( ($SetEnabled) and ( $Disabled != $UserObj->Disabled) ) { 
+    my  ($code, $msg) = $UserObj->SetDisabled($Disabled);
+    push @results, loc('Enabled status [_1]', loc_fuzzy($msg));
+}
+
+
+#TODO: make this report errors properly
+if ((defined $Pass1) and ($Pass1 ne '') and ($Pass1 eq $Pass2) and (!$UserObj->IsPassword($Pass1))) {
+    my ($code, $msg);
+    ($code, $msg) = $UserObj->SetPassword($Pass1);
+    push @results, loc('Password: [_1]', loc_fuzzy($msg));
+} elsif ( $Pass1 && ($Pass1 ne $Pass2)) {
+    push @results, loc("Passwords do not match.");
+}
+
+# }}}
+}
+
+
+# {{{ Do some setup for the ui
+unless ($UserObj->Disabled()) {
+    $EnabledChecked ="CHECKED";
+}
+
+if ($UserObj->Privileged()) {  
+    $PrivilegedChecked = "CHECKED";
+}
+
+# }}}
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+$Name  => undef
+$Comments  => undef
+$Signature  => undef
+$EmailAddress  => undef
+$FreeformContactInfo => undef
+$Organization  => undef
+$RealName  => undef
+$NickName  => undef
+$Privileged => undef
+$SetPrivileged => undef
+$Enabled => undef
+$SetEnabled => undef
+$Lang  => undef
+$EmailEncoding  => undef
+$WebEncoding => undef
+$ExternalContactInfoId  => undef
+$ContactInfoSystem  => undef
+$Gecos => undef
+$ExternalAuthId  => undef
+$AuthSystem  => undef
+$HomePhone => undef
+$WorkPhone  => undef
+$MobilePhone  => undef
+$PagerPhone  => undef
+$Address1 => undef
+$Address2  => undef
+$City  => undef
+$State  => undef
+$Zip  => undef
+$Country => undef
+$Pass1 => undef
+$Pass2=> undef
+$Create=> undef
+</%ARGS>
diff --git a/rt/html/Admin/Users/Prefs.html b/rt/html/Admin/Users/Prefs.html
new file mode 100644 (file)
index 0000000..0bba9fa
--- /dev/null
@@ -0,0 +1,122 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc("User view") &>
+
+<& /Elements/ViewUser, User=>$u &>
+
+<h2 class="title"><%loc("User view")%></h2>
+
+%if ($session{CurrentUser} && ($session{CurrentUser}->Id == $id)) {
+       <& /Elements/TitleBoxStart, title => loc('Signature')  &>
+<form method=post>
+<input type="hidden" name="id" value=<%$id%>>
+<TEXTAREA COLS=72 ROWS=4 WRAP=HARD NAME="Signature"><% $u->Signature %></TEXTAREA><br><br>
+<input type="submit" value="<&|/l&>Update signature</&>">
+</form>
+         <& /Elements/TitleBoxEnd &>
+         <form method=post>
+         <&|/l&>Open tickets (from listing) in another window</&>: <input type="checkbox" name="NewWindowOption" <%exists $session{NewWindowOption} && "CHECKED"%>><br>
+         <&|/l&>Open tickets (from listing) in a new window</&>: <input type="checkbox" name="AlwaysNewWindowOption" <%exists $session{AlwaysNewWindowOption} && "CHECKED"%>><br>
+         <input type="submit" name="NewWindowSetting" value="<&|/l&>New window setting</&>">
+         </form>
+%}
+
+       <& /Elements/TitleBoxStart, title => loc('Email')  &>
+<form method=post>
+<input type="hidden" name="id" value="<%$id%>">
+<input name="Email" value="<% $u->EmailAddress %>"><input type="submit" value="<&|/l&>Update email</&>">
+</form>
+         <& /Elements/TitleBoxEnd &>
+       <& /Elements/TitleBoxStart, title => loc('Real Name')  &>
+<form method=post>
+<input type="hidden" name="id" value="<%$id%>">
+<input name="RealName" value="<% $u->RealName %>"><input type="submit" value="<&|/l&>Update name</&>">
+</form>
+         <& /Elements/TitleBoxEnd &>
+
+       <& /Elements/TitleBoxStart, title => loc('User ID')  &>
+<form method=post>
+<input type="hidden" name="id" value="<%$id%>">
+<input name="Name" value="<% $u->Name %>"><input type="submit" value="<&|/l&>Update ID</&>">
+</form>
+         <& /Elements/TitleBoxEnd &>
+
+%# TODO: alternative email addresses + merging users
+
+<%ARGS>
+$id => $session{CurrentUser} ? $session{CurrentUser}->Id : 0
+$Signature => undef
+$Email => undef
+$RealName => undef
+$Name => undef
+</%ARGS>
+
+<%INIT>
+require RT::User;
+my $u=RT::User->new($session{CurrentUser});
+$u->Load($id) || die loc("Couldn't load that user ([_1])", $id);
+if ($Signature) {
+my ($val, $msg)=$u->SetSignature($Signature);
+$RT::Logger->log(level=>($val ? 'info' : 'error'), message=>$msg);
+}
+
+if ($Email) {
+my ($val, $msg)=$u->SetEmailAddress($Email);
+$RT::Logger->log(level=>($val ? 'info' : 'error'), message=>$msg);
+}
+
+if ($RealName) {
+my ($val, $msg)=$u->SetRealName($RealName);
+$RT::Logger->log(level=>($val ? 'info' : 'error'), message=>$msg);
+}
+
+if ($Name) {
+my ($val, $msg)=$u->SetName($Name);
+$RT::Logger->log(level=>($val ? 'info' : 'error'), message=>$msg);
+}
+
+if ($ARGS{NewWindowSetting}) {
+if ($ARGS{NewWindowOption}) {
+$session{NewWindowOption}=1;
+} else {
+delete $session{NewWindowOption};
+}
+if ($ARGS{AlwaysNewWindowOption}) {
+$session{NewWindowOption}=1;
+$session{AlwaysNewWindowOption}=1;
+} else {
+delete $session{AlwaysNewWindowOption};
+}
+}
+
+</%INIT>
+
+
+
+
+
+
+
+
+
diff --git a/rt/html/Admin/Users/index.html b/rt/html/Admin/Users/index.html
new file mode 100644 (file)
index 0000000..a95d411
--- /dev/null
@@ -0,0 +1,81 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => loc('Select a user') &>
+<& /Admin/Elements/UserTabs, current_tab => 'Admin/Users/', 
+    current_subtab => 'Admin/Users/',
+    Title => loc('Select a user') &>
+
+
+
+
+<%$caption%>:<BR>
+<UL>
+%if ($users->Count == 0) {
+<LI> <i><&|/l&>No users matching search criteria found.</&></i>
+% }
+%while ( $user = $users->Next) {
+<LI><A HREF="Modify.html?id=<%$user->id%>"><%$user->Name || loc('(no name listed)')%></a></LI>
+%}
+
+</UL>
+<br><br>
+<FORM METHOD=POST ACTION="<% $RT::WebPath %>/Admin/Users/">
+
+<&|/l&>Find people whose</&> <& /Elements/SelectUsers &><BR>
+<input type="checkbox" name="FindDisabledUsers"> <&|/l&>Include disabled users in search.</&>
+<BR>
+<div align=right><input type=submit value="<&|/l&>Go!</&>"></div> 
+</FORM>
+
+<%INIT>
+my ($user, $caption);
+my $users = new RT::Users($session{'CurrentUser'});
+
+if ($FindDisabledUsers) {
+       $users->{'find_disabled_rows'} = 1;
+}
+
+unless (defined $UserString) {
+    $users->LimitToPrivileged();
+    $caption = loc("Privileged users");
+}
+else {
+    $caption = loc("Users matching search criteria");
+
+  if ($UserString) {
+       $users->Limit( FIELD => $UserField,
+                       OPERATOR => $UserOp,
+                      VALUE => $UserString); 
+
+}
+}
+</%INIT>
+<%ARGS>
+$UserString => undef
+$UserOp => '='
+$UserField => 'Name'
+$IdLike => undef
+$EmailLike => undef
+$FindDisabledUsers => 0
+</%ARGS>
diff --git a/rt/html/Admin/index.html b/rt/html/Admin/index.html
new file mode 100644 (file)
index 0000000..522ade8
--- /dev/null
@@ -0,0 +1,40 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => loc('RT Administration') &>
+<& /Admin/Elements/Tabs, Title => loc('RT Administration') &>
+
+<ul>
+<li><font size="+2"><a href="Users/"><&|/l&>Users</&></a></font><br>
+<&|/l&>Manage users and passwords</&>
+</li>
+<li><font size="+2"><a href="Groups/"><&|/l&>Groups</&></a></font><br>
+<&|/l&>Manage groups and group membership</&>
+</li>
+<li><font size="+2"><a href="Queues/"><&|/l&>Queues</&></a></font><br>
+<&|/l&>Manage queues and queue-specific properties</&>
+</li>
+<li><font size="+2"><a href="Global/"><&|/l&>Global</&></a></font><br>
+<&|/l&>Manage properties and configuration which apply to all queues</&>
+</li>
+</ul>
diff --git a/rt/html/Approvals/Display.html b/rt/html/Approvals/Display.html
new file mode 100644 (file)
index 0000000..921c1e3
--- /dev/null
@@ -0,0 +1,50 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title =>  $title &>
+
+<& Elements/Tabs, 
+    current_tab => "Approvals/Display.html", 
+    Title =>  $title &>
+<form method=post action="<%$RT::WebPath%>/Approvals/">
+
+<& /Elements/TitleBoxStart, title => $title &>
+<& /Ticket/Elements/ShowHistory , Ticket => $Ticket, Collapsed => 0, ShowTitle => 0, ShowHeaders => 0, ShowDisplayModes => 0, ShowTitleBarCommands => 0 &>
+<hr>
+<table width=100%>
+<& Elements/Approve, ticket => $Ticket, ShowApproving => 0 &>
+</table>
+<& /Elements/TitleBoxEnd &>
+<& /Elements/Submit&>
+</form>
+<& Elements/ShowDependency, Ticket => $Ticket &>
+
+<%init>
+my $Ticket = LoadTicket($id);
+
+my $title = loc("Approval #[_1]: [_2]", $Ticket->Id, $Ticket->Subject);
+
+</%init>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Approvals/Elements/Approve b/rt/html/Approvals/Elements/Approve
new file mode 100644 (file)
index 0000000..6a7cfa3
--- /dev/null
@@ -0,0 +1,56 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<tr bgcolor="#b9b9ff">
+<td colspan=2><font size="3">
+<a href="<%$RT::WebPath%>/Approvals/Display.html?id=<%$ticket->Id%>"><% loc("#[_1]: [_2]", $ticket->Id, $ticket->Subject) %></a> (<%loc($ticket->Status)%>)</font></td>
+</tr>
+% if ($ShowApproving) {
+%     foreach my $approving ( $ticket->AllDependedOnBy( Type => 'ticket' ) ) {
+<tr bgcolor="#e9e9e9">
+<td colspan=2>
+<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<% $approving->Id %>"><&|/l, $approving->Id, $approving->Subject &>Originating ticket: #[_1]</&></a>
+</td>
+</tr>
+<tr><td colspan=2>
+<& /Ticket/Elements/ShowCustomFields, Ticket => $approving &>
+<& /Ticket/Elements/ShowHistory, Ticket => $approving, Collapsed => 0, ShowTitle => 0, ShowHeaders => 0, ShowDisplayModes => 0, ShowTitleBarCommands => 0 &>
+</td></tr>
+%     }
+% }
+<tr <%$class && "class=\"$class\""%>>
+<td valign=top>
+<input type="radio" name="Approval-<%$ticket->Id%>-Action" value="approve"><&|/l&>Approve</&><br>
+<input type="radio" name="Approval-<%$ticket->Id%>-Action" value="deny"><&|/l&>Deny</&><br>
+<input type="radio" name="Approval-<%$ticket->Id%>-Action" value="none" checked><&|/l&>No action</&>
+</td>
+<td>
+<&|/l&>Notes</&><br>
+<textarea name="Approval-<%$ticket->Id%>-Notes" rows=2 cols=70></textarea>
+</td>
+</tr>
+<%ARGS>
+$ShowApproving => 1
+$ticket => undef
+$class => undef
+</%ARGS>
diff --git a/rt/html/Approvals/Elements/PendingMyApproval b/rt/html/Approvals/Elements/PendingMyApproval
new file mode 100644 (file)
index 0000000..b5cf007
--- /dev/null
@@ -0,0 +1,87 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<table width="100%">
+% my ($i, $class);
+% my %done;
+% foreach ($tickets, $group_tickets) {
+%   while (my $ticket = $_->Next() ) {
+%     next if !$ARGS{'ShowDependent'} and $ticket->HasUnresolvedDependencies( Type => 'approval' );
+%     next if $done{$ticket->Id}++; # don't show duplicate tickets
+%     $i++; 
+%     $class = ($i%2) ?  "oddline" : "evenline";
+<& Approve, ticket => $ticket, class => $class &>
+%   }
+% }
+</table>
+
+<& /Elements/TitleBoxStart, title => loc("Search for approvals") &>
+<input type=checkbox value="1" name="ShowPending"
+        <%((!$ARGS{'ShowRejected'} && !$ARGS{'ShowResolved'}) ||
+         $ARGS{'ShowPending'})
+        && "checked"%>> <&|/l&>Show pending requests</&><br>
+<input type=checkbox value="1" name="ShowResolved" <%$ARGS{'ShowResolved'} && "checked"%>> <&|/l&>Show approved requests</&><br>
+<input type=checkbox value="1" name="ShowRejected" <%$ARGS{'ShowRejected'} && "checked"%>> <&|/l&>Show denied requests</&><br>
+<input type=checkbox value="1" name="ShowDependent" <%$ARGS{'ShowDependent'} && "checked"%>> <&|/l&>Show requests awaiting other approvals</&><br>
+
+<&|/l,"<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>"&>Only show approvals for requests created before [_1]</&><br>
+
+<&|/l, "<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>"&>Only show approvals for requests created after [_1]</&>
+<& /Elements/TitleBoxEnd &>
+
+<%init>
+my $tickets = RT::Tickets->new( $session{'CurrentUser'} );
+$tickets->LimitOwner( VALUE => $session{'CurrentUser'}->Id );
+
+# also consider AdminCcs as potential approvers.
+my $group_tickets = RT::Tickets->new( $session{'CurrentUser'} );
+
+my $created_before = RT::Date->new( $session{'CurrentUser'} );
+my $created_after = RT::Date->new( $session{'CurrentUser'} );
+
+foreach ($tickets, $group_tickets) {
+    $_->Limit( FIELD      => 'Type', VALUE => 'approval' );
+
+    if ( $ARGS{'ShowResolved'} ) {
+       $_->LimitStatus( VALUE => 'resolved' );
+    }
+    if ( $ARGS{'ShowRejected'} ) {
+       $_->LimitStatus( VALUE => 'rejected' );
+    }
+    if ( $ARGS{'ShowPending'} || ( !$ARGS{'ShowRejected'} && !$ARGS{'Resolved'} ) ) {
+       $_->LimitStatus( VALUE => 'open' );
+       $_->LimitStatus( VALUE => 'new' );
+       $_->LimitStatus( VALUE => 'stalled' );
+    }
+
+    if ( $ARGS{'CreatedBefore'} ) {
+       $created_before->Set( Format => 'unknown', Value => $ARGS{'CreatedBefore'} );
+       $_->LimitCreated( OPERATOR => "<=", VALUE => $created_before->ISO );
+    }
+    if ( $ARGS{'CreatedAfter'} ) {
+       $created_after->Set( Format => 'unknown', Value => $ARGS{'CreatedAfter'} );
+       $_->LimitCreated( OPERATOR => ">=", VALUE => $created_after->ISO );
+    }
+}
+
+</%init>
diff --git a/rt/html/Approvals/Elements/ShowDependency b/rt/html/Approvals/Elements/ShowDependency
new file mode 100644 (file)
index 0000000..417cad1
--- /dev/null
@@ -0,0 +1,85 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+% my $approving = $Ticket->DependedOnBy();
+% if ($approving->Count) {
+<h3><&|/l&>Tickets which depend on this approval:</&></h3>
+
+<table width=100%>
+<TR>
+<TD WIDTH="25" bgcolor="#999999">&nbsp;</TD><TD>
+<%PERL>
+my %show;
+while (my $link = $approving->Next()) {
+    next unless ($link->BaseURI->IsLocal());
+    my $text = '<a name="' . $link->BaseObj->Id . '">';
+    my $head = '';
+    my $type = $link->BaseObj->Type;
+    my $dep  = $m->scomp('ShowDependency', Ticket => $link->BaseObj, _seen => $_seen);
+
+    if ($type eq 'approval') {
+       $head .= $m->scomp('/Elements/TitleBoxStart', title => loc("Approval #[_1]: [_2]", $link->BaseObj->Id, $link->BaseObj->Subject));
+       $text .= $head;
+       $text .= $m->scomp('/Ticket/Elements/ShowCustomFields', Ticket => $link->BaseObj);
+    } elsif ($type eq 'ticket') {
+       $head .= $m->scomp('/Elements/TitleBoxStart', title => loc("Ticket #[_1]: [_2]", $link->BaseObj->Id, $link->BaseObj->Subject));
+       $text .= $head;
+       $text .= $m->scomp('/Ticket/Elements/ShowSummary', Ticket => $link->BaseObj);
+    } else {
+       $head .= $m->scomp('/Elements/TitleBoxStart', title => loc("#[_1]: [_2]", $link->BaseObj->Id, $link->BaseObj->Subject));
+       $text .= $head;
+    }
+
+    $text .= $m->scomp('/Ticket/Elements/ShowHistory' , Ticket => $link->BaseObj, Collapsed => ($type ne 'ticket'), ShowTitle => 0, ShowHeaders => 0, ShowDisplayModes => 0, ShowTitleBarCommands => 0);
+
+    $head .= $m->scomp('/Elements/TitleBoxEnd');
+    $text .= $m->scomp('/Elements/TitleBoxEnd');
+    $text .= $dep;
+    $text .= '</a>';
+    $show{$link->BaseObj->Id} = {
+       text => $text,
+       head => $head,
+    };
+}
+
+my $refer;
+foreach my $id (sort keys %show) {
+    if ($_seen->{$id}++) {
+       $refer .= "<a href='#txn-$id'>" . $show{$id}{head} . "</a>";
+       next;
+    }
+
+    $m->print($show{$id}{text});
+}
+$m->print($refer);
+
+</%PERL>
+</TD>
+</TR>
+</TABLE>
+
+% }
+<%ARGS>
+$Ticket
+$_seen => {}
+</%ARGS>
diff --git a/rt/html/Approvals/Elements/Tabs b/rt/html/Approvals/Elements/Tabs
new file mode 100644 (file)
index 0000000..648ff75
--- /dev/null
@@ -0,0 +1,34 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Tabs,
+    tabs => $tabs, 
+    current_toptab => 'Approvals/', 
+    current_tab => $current_tab, 
+    Title => $Title &>
+
+<%ARGS>
+$tabs => undef
+$current_tab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Approvals/index.html b/rt/html/Approvals/index.html
new file mode 100644 (file)
index 0000000..b4156f3
--- /dev/null
@@ -0,0 +1,66 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc("My approvals") &>
+<& /Approvals/Elements/Tabs, Title => loc("My approvals") &>
+
+<& /Elements/ListActions, actions => \@actions &>
+<form method="post">
+<& Elements/PendingMyApproval, %ARGS &>
+<& /Elements/Submit &>
+</form>
+<%init>
+
+my (@actions);
+foreach my $arg ( keys %ARGS ) {
+
+    next unless ( $arg =~ /Approval-(\d+)-Action/ );
+
+    my ( $notesval, $notesmsg );
+
+    my $ticket = LoadTicket($1);
+
+    if ( $ARGS{ "Approval-" . $ticket->Id . "-Notes" } ) {
+        my $notes = MIME::Entity->build(
+           Data => [ $ARGS{ "Approval-" . $ticket->Id . "-Notes" } ]
+       );
+       RT::I18N::SetMIMEEntityToUTF8($notes); # convert text parts into utf-8
+
+        my ( $notesval, $notesmsg ) = $ticket->Correspond( MIMEObj => $notes );
+        if ($notesval) {
+                push ( @actions, loc("Approval #[_1]: Notes recorded",$ticket->Id ));
+        } else {
+                push ( @actions, loc("Approval #[_1]: Notes not recorded due to a system error",$ticket->Id ));
+        }
+    }
+
+    my ($val, $msg);
+    if ( $ARGS{$arg} eq 'deny' ) {
+         ( $val, $msg ) = $ticket->SetStatus('rejected');
+    }
+    elsif ( $ARGS{$arg} eq 'approve' ) {
+         ( $val, $msg ) = $ticket->SetStatus('resolved');
+    }
+    push ( @actions, loc("Approval #[_1]: [_2]",$ticket->id, $msg )) if ($msg);
+}
+</%init>
diff --git a/rt/html/Elements/BevelBoxRaisedEnd b/rt/html/Elements/BevelBoxRaisedEnd
new file mode 100644 (file)
index 0000000..ebf45df
--- /dev/null
@@ -0,0 +1,26 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+  </TD>
+</TR>
+</table>
diff --git a/rt/html/Elements/BevelBoxRaisedStart b/rt/html/Elements/BevelBoxRaisedStart
new file mode 100644 (file)
index 0000000..c4e6c55
--- /dev/null
@@ -0,0 +1,26 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<table cellspacing=0 cellpadding=0 width=100% height=100%>
+      <TR>
+        <TD width=100% height=100%> 
diff --git a/rt/html/Elements/Callback b/rt/html/Elements/Callback
new file mode 100644 (file)
index 0000000..93ac4c0
--- /dev/null
@@ -0,0 +1,65 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<%once>
+my (%cache, $check);
+</%once>
+<%init>
+# checks for inode change time for each callback directory
+my $new_check = join(
+    $;, map { $_->[1] => (stat("$_->[1]/Callbacks"))[10] } $m->interp->resolver->comp_root_array
+) or return;
+
+$Page = $m->callers(1)->path unless ($Page);
+
+my $callbacks;
+if ($new_check eq $check) {
+    $callbacks = $cache{$Page,$_CallbackName};
+}
+else {
+    $check = $new_check;
+}
+
+if (!$callbacks) {
+    my $path = "/Callbacks/*$Page/$_CallbackName";
+    $callbacks = [ $m->interp->resolver->glob_path($path) ];
+    @$callbacks = grep !/^\.|~$/, @$callbacks; #skip backup files
+
+    #skip files without a package
+    my $invalid_base = "/Callbacks/$Page/$_CallbackName";
+    @$callbacks = grep !/^$invalid_base$/, @$callbacks;
+
+
+
+    $cache{$Page,$_CallbackName} = $callbacks;
+}
+
+foreach my $comp (@$callbacks) {
+        $m->comp($comp, %ARGS) if $m->comp_exists($comp);
+}
+return(1);
+</%init>
+<%args>
+$_CallbackName => 'Default'
+$Page => undef
+</%args>
diff --git a/rt/html/Elements/Checkbox b/rt/html/Elements/Checkbox
new file mode 100644 (file)
index 0000000..ae3d765
--- /dev/null
@@ -0,0 +1,39 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<INPUT TYPE="Checkbox" NAME ="<%$Name%>" <%$IsChecked%>>
+
+<%ARGS>
+$Name => undef
+$Default => undef
+$True => undef
+$False => undef
+$IsChecked => undef
+</%ARGS>
+
+<%INIT>
+$IsChecked = 
+  ($Default && $Default =~ /checked/i)
+    ? " CHECKED " : "";
+1;
+</%INIT>
diff --git a/rt/html/Elements/CreateTicket b/rt/html/Elements/CreateTicket
new file mode 100644 (file)
index 0000000..7e1025d
--- /dev/null
@@ -0,0 +1,26 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<FORM ACTION="<% $RT::WebPath%>/Ticket/Create.html">
+<&|/l, $m->scomp('/Elements/SelectNewTicketQueue')&><input type="submit" value="New ticket in">&nbsp;[_1]</&>
+</FORM>
diff --git a/rt/html/Elements/Error b/rt/html/Elements/Error
new file mode 100644 (file)
index 0000000..dc44f12
--- /dev/null
@@ -0,0 +1,62 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Callback, %ARGS, error => $error &>
+<& /Elements/Header, Code => $Code, Why => $Why &>
+<& /Elements/Tabs &>
+<& /Elements/TitleBoxStart, class=> "error",  title => $Title &>
+<%$Why%>
+<br>
+<font size=-1>
+<%$Details%>
+</font>
+<& /Elements/TitleBoxEnd &>
+</body>
+</HTML>
+
+
+<%args>
+$Code => undef
+$Details => undef
+$Title => loc("RT Error")
+$Why => loc("the calling component did not specify why")
+</%args>
+
+<%INIT>
+my $error = "WebRT: $Why ($Details)";
+
+# TODO: Log::Dispatch isn't UTF-8 safe. Autrijus needs to talk to dave rolsky about getting this fixed
+if ($] >= 5.007001) {
+    require Encode;
+    Encode::_utf8_off($error);
+}
+
+$RT::Logger->error($error);
+
+if ( $session{'SessionType'} eq 'REST' ) {
+    $r->content_type('text/plain');
+    $m->out( "Error: " . $Why . "\n" );
+    $m->out( $Details . "\n" );
+    $m->abort();
+}
+</%INIT>
diff --git a/rt/html/Elements/Footer b/rt/html/Elements/Footer
new file mode 100644 (file)
index 0000000..5c833f8
--- /dev/null
@@ -0,0 +1,60 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+% if ($Menu) {
+</td>
+</tr>
+<tr>
+<td>
+% }
+<& /Elements/Callback, %ARGS &>
+<div class="bpscredits">
+&#187;&#124;&#171; <&|/l, $RT::VERSION &>RT [_1] from <a href="http://bestpractical.com">Best Practical Solutions, LLC</a>.</&>
+</div>
+% if ($Debug) {
+<HR>
+<b><&|/l&>Time to display</&>: <%Time::HiRes::tv_interval( $m->{'rt_base_time'} )%></b>
+% }
+% if ($Debug >= 2 ) {
+% require Data::Dumper;
+% my $d = Data::Dumper->new([\%ARGS], [qw(%ARGS)]);
+<pre>
+<%$d->Dump() %>
+</pre>
+% }
+% if ($Menu) {
+</TD>
+</TR>
+</TABLE>
+</TD>
+</TR>
+</TABLE>
+% }
+</BODY>
+</HTML>
+% $m->abort();
+
+<%ARGS>
+$Debug => 0
+$Menu => 1
+</%ARGS>
diff --git a/rt/html/Elements/GotoTicket b/rt/html/Elements/GotoTicket
new file mode 100644 (file)
index 0000000..bb0c04d
--- /dev/null
@@ -0,0 +1,24 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<FORM ACTION="<%$RT::WebPath%>/Ticket/Display.html"><input type=submit value="<&|/l&>Goto ticket</&>">&nbsp;<input size=5 name=id accesskey="0"></FORM>
diff --git a/rt/html/Elements/Header b/rt/html/Elements/Header
new file mode 100644 (file)
index 0000000..0fd91a2
--- /dev/null
@@ -0,0 +1,82 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE><%$Title%></TITLE>
+% if ($Refresh > 0) {
+<META HTTP-EQUIV="REFRESH" CONTENT="<%$Refresh%>">
+% }
+
+<link rel="shortcut icon" href="<%$RT::WebImagesURL%>/favicon.png" type="image/png">
+<link rel="stylesheet" href="<%$RT::WebPath%>/NoAuth/webrt.css" type="text/css">
+</HEAD>
+<BODY BGCOLOR="<%$BgColor%>"
+% if ($Focus) {
+ONLOAD="
+    var tmp = (document.getElementsByName('<% $Focus %>'));
+    if (tmp.length > 0) tmp[tmp.length-1].focus();
+"
+% }
+>
+<table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF">
+  <tr> 
+    <td colspan=2><a href="http://bestpractical.com"><img src="<%$RT::WebImagesURL%>/bplogo.gif" alt="" width="230" height="50"></a></td>
+    <td>&nbsp;</td>
+    <td>&nbsp;</td>
+    <td width="50%" align="right">
+% if ($session{'CurrentUser'} && $session{'CurrentUser'}->Id && $LoggedIn) {
+<SPAN STYLE="display: none"><A HREF="#skipnav"><&|/l&>Skip Menu</&></A> |</SPAN>
+<A  HREF="<%$RT::WebPath%><% $Prefs %>" ><&|/l&>Preferences</&></A>
+<& /Elements/Callback, %ARGS &>
+% unless ($RT::WebExternalAuth and !$RT::WebFallbackToInternalAuth) {
+| <A  HREF="<%$RT::WebPath%>/NoAuth/Logout.html<%$URL && "?URL=".$URL%>"><&|/l&>Logout</&></a>
+% }
+<BR>
+<&|/l, "<b>".$session{'CurrentUser'}->Name."</b>" &>Logged in as [_1]</&>
+% } else {
+<&|/l&>Not logged in.</&>
+% }
+</font>
+    </td>
+  </tr>
+</table>
+<%INIT>
+
+$r->header_out('Pragma' => 'no-cache');
+$r->header_out('Cache-control' => 'no-cache');
+</%INIT>
+
+<%ARGS>
+$Prefs => '/User/Prefs.html'
+$Focus => 'focus'
+$Title => undef
+$Code => undef
+$Refresh => 0
+$Why => undef
+$BgColor => '#ffffff'
+$ShowBar => 1
+$LoggedIn => 1
+$URL => undef
+</%ARGS>
diff --git a/rt/html/Elements/ListActions b/rt/html/Elements/ListActions
new file mode 100644 (file)
index 0000000..ffa09e2
--- /dev/null
@@ -0,0 +1,43 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+% if ($actions[0] ) {
+<& /Elements/TitleBoxStart, title => loc('Results') &>
+<UL>
+% foreach my $action (@actions) {
+% next unless ($action);
+% my $skip = 0;
+% $m->comp('/Elements/Callback', _CallbackName => 'ModifyRow', row => \$action, skip => \$skip, %ARGS);
+% next if $skip;
+<LI><%$action%></LI>
+% }
+</UL>
+<& /Elements/TitleBoxEnd &>
+<BR>
+% }
+<%init>
+@actions = grep (/./,@actions);
+</%init>
+<%ARGS>
+@actions => undef
+</%ARGS>
diff --git a/rt/html/Elements/Login b/rt/html/Elements/Login
new file mode 100644 (file)
index 0000000..42c49c4
--- /dev/null
@@ -0,0 +1,101 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<%INIT>
+if ($m->request_comp->path =~ '^/REST/\d+\.\d+/') {
+    $r->content_type("text/plain");
+    $m->error_format("text");
+    $m->out("RT/$RT::VERSION 401 Credentials required\n");
+    $m->out("\n$Error\n") if $Error;
+    $m->abort;
+}
+</%INIT>
+
+<& /Elements/Callback, %ARGS, _CallbackName => 'Header' &>
+<& /Elements/Header, Title => loc('Login'), Focus => 'user' &>
+
+<DIV ALIGN=CENTER>
+% if ($Error) {
+<& /Elements/TitleBoxStart, title => loc('Error') &>
+<% $Error %>
+<& /Elements/TitleBoxEnd &>
+% }
+<BR>
+<& /Elements/TitleBoxStart, width=> "40%", titleright => loc("RT [_1]", $RT::VERSION), title => loc('Login') ,
+contentbg=>"#cccccc" &>
+
+% unless ($RT::WebExternalAuth and !$RT::WebFallbackToInternalAuth) {
+<FORM METHOD=POST ACTION="<% (UNIVERSAL::can($r, 'uri') && ($r->uri) =~ m!.*/(.*)!) %>" >
+<TABLE BORDER=0 WIDTH=100%>
+<TR ALIGN=RIGHT>
+<TD ALIGN=RIGHT><&|/l&>Username</&>:</TD><TD ALIGN=LEFT><input name=user value="<%$user%>"></TD></TR>
+<TR><TD ALIGN=RIGHT><&|/l&>Password</&>:</TD><TD ALIGN=LEFT><input type=password name=pass></TD></TR>
+<TR><TD colspan=2 align=right>
+<input type=submit Value="<&|/l&>Login</&>">
+</TD></TR>
+</TABLE>
+
+%# Give callbacks a chance to add more control elements
+<& /Elements/Callback, %ARGS &>
+
+<&/Elements/TitleBoxEnd&>
+% # From mason 1.0.1 forward, this doesn't work. in fact, it breaks things.
+% # But on Mason 1.15 it's fixed again, so we still use it.
+% # The code below iterates through everything in the passed in arguments
+% # Preserving all the old parameters
+% # This would be easier, except mason is 'smart' and calls multiple values
+% # arrays rather than multiple hash keys
+% my $key; my $val;
+% foreach $key (keys %ARGS) {
+%  if (($key ne 'user') and ($key ne 'pass')) {
+%      if (ref($ARGS{$key}) =~ /ARRAY/) {
+%              foreach $val (@{$ARGS{$key}}) {
+<input type=hidden name="<%$key %>" value="<% $val %>">
+%              }
+%      }
+%      else {
+<input type="hidden" name="<% $key %>" value="<% $ARGS{$key} %>">
+%      }
+%  }
+% }
+</FORM>
+% }
+</DIV>
+
+<BR>
+<!-- TODO: not yet implemented
+If you've forgotten your username or password, RT can <A
+href="/NoAuth/Reminder.html">send you a reminder</a>.
+-->
+<BR>
+<BR>
+<BR>
+<HR>
+<&|/l, '2003'&>RT is &copy; Copyright 1996-[_1] Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href="http://www.gnu.org/copyleft/gpl.html">Version 2 of the GNU General Public License.</a></&>
+
+<%ARGS>
+$user => ""
+$pass => undef
+$goto => undef
+$Error => undef
+</%ARGS>
diff --git a/rt/html/Elements/Menu b/rt/html/Elements/Menu
new file mode 100644 (file)
index 0000000..963be13
--- /dev/null
@@ -0,0 +1,84 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+%# font size depends on level
+% if ($level ge 3) {
+%   $size = $basesize-(6);
+% } elsif ($level gt 0) {
+%   $size = $basesize-($level * 2);
+%   $padding = 2;
+% }
+%  else {
+%   $size = $basesize;
+%   $padding = 5;
+% }
+<ul class="topnav" >
+% my $sep=0;
+% my $accesskey="1";
+% foreach $tab (sort keys %{$toptabs}) {
+% my $current = $current_toptab || "";
+% my $path = $toptabs->{$tab}->{'path'} || "";
+% $path =~ s#/index.html$##gi;
+% $current =~ s#/index.html$##gi;
+% if ( $path eq $current) {
+%     $class="currenttopnav"
+% } else {
+%     $class="topnav"
+% } 
+% my $style="";
+% if ($sep) {
+% $style="border-top: solid #999 1px; padding-top: .1em; margin-top: .5em;";
+% } elsif ($level == 0 ) {
+% $style="border-bottom: solid white 1px; padding-top: .25em; padding-bottom: .5em;" ;
+% }
+% if ($toptabs->{$tab}->{'separator'}) {
+% $sep=1;
+% } else {
+% $sep=0;
+% }
+<li style="<%$style%>"><A HREF="<%$RT::WebPath%>/<%$toptabs->{$tab}->{'path'}|n%>" style="font-size: <%$size%>;" class="<%$class%>" 
+<%($class eq 'currenttopnav') ? "name='focus'" : ""|n %> 
+<% !$level && "accesskey='".$accesskey++."'" |n%>><% $toptabs->{$tab}->{'title'}%></A>
+%# Second-level items
+%# if ($current_toptab eq $toptabs->{$tab}->{'path'}) {
+%# commented out by jesse on 4 jan 2003 so that tickets/search and ticket/# can
+%# both have menu items
+% if ($toptabs->{$tab}->{'subtabs'}) {
+        <& /Elements/Menu, level => $level+1, 
+                current_toptab => $toptabs->{$tab}->{'current_subtab'},
+                toptabs => $toptabs->{$tab}->{'subtabs'} &></li>
+% }
+%# }
+% }
+</ul>
+
+<%INIT>
+my ($tab, $subtab, $class, $size, $padding);
+my $basesize=16;
+</%INIT>
+
+<%ARGS>
+$current_toptab => ""
+$toptabs => undef
+$level => 0
+</%ARGS>
diff --git a/rt/html/Elements/MessageBox b/rt/html/Elements/MessageBox
new file mode 100644 (file)
index 0000000..64fdf38
--- /dev/null
@@ -0,0 +1,47 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TEXTAREA COLS=<%$Width%> ROWS=15 WRAP=HARD NAME="<%$Name%>"><& /Elements/Callback, %ARGS &><% $Default %><%$message%><%$signature%></TEXTAREA>
+<%INIT>
+
+my ($message);
+
+if ($QuoteTransaction) {
+    my $transaction=RT::Transaction->new($session{'CurrentUser'});
+    $transaction->Load($QuoteTransaction);
+    $message=$transaction->Content(Quote => 1);
+}
+
+my $signature = '';
+if ($session{'CurrentUser'}->UserObj->Signature) {
+       $signature = "-- \n".$session{'CurrentUser'}->UserObj->Signature;
+}
+
+</%INIT>
+<%ARGS>
+$QuoteTransaction => undef
+$Name => 'Content'
+$Default => ''
+$Width => 72
+</%ARGS>
+
diff --git a/rt/html/Elements/MyRequests b/rt/html/Elements/MyRequests
new file mode 100644 (file)
index 0000000..05ae624
--- /dev/null
@@ -0,0 +1,78 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/TitleBoxStart, title => loc("[_1] highest priority tickets I requested...", $rows), bodyclass=> '' &>
+<TABLE BORDER=0 cellspacing=0 cellpadding=1 WIDTH=100%>
+<TR>
+<TH align=right><&|/l&>#</&></TH>
+<TH align=left><&|/l&>Subject</&></TH>
+<TH align=left><&|/l&>Queue</&></TH>
+<TH align=left><&|/l&>Status</&></TH>
+<TH align=left><&|/l&>Owner</&></TH>
+</TR>
+% my $i;
+% while (my $Ticket = $MyTickets->Next) {
+% $i++;
+<TR class="<% $i%2 ? 'oddline' : 'evenline'%>" >
+<TD ALIGN=RIGHT>
+<%$Ticket->Id%>
+</TD>
+<TD>
+<A HREF="<% $RT::WebPath %>/Ticket/Display.html?id=<%$Ticket->Id%>">
+<%$Ticket->Subject || loc('(no subject)')%>
+</A>
+</TD>
+<TD>
+<%$Ticket->QueueObj->Name%>
+</TD>
+<TD>
+% if ($Ticket->HasUnresolvedDependencies ) {
+%     if ($Ticket->HasUnresolvedDependencies( Type => 'approval'  )) { 
+<em><&|/l&>(pending approval)</&></em>
+%     } else {
+<em><&|/l&>(pending other tickets)</&></em>
+%     }
+% } else {
+<%loc($Ticket->Status)%>
+% }
+</TD>
+<TD>
+<%$Ticket->OwnerObj->Name%>
+</TD>
+</TR>
+% }
+</TABLE>
+<& /Elements/TitleBoxEnd &>
+
+
+<%INIT>
+my $rows = 10;
+my $MyTickets;
+$MyTickets = new RT::Tickets ($session{'CurrentUser'});
+$MyTickets->LimitWatcher(TYPE => 'Requestor', VALUE => $session{'CurrentUser'}->EmailAddress);
+$MyTickets->LimitStatus(VALUE => "open");
+$MyTickets->LimitStatus(VALUE => "new");
+$MyTickets->RowsPerPage($rows);
+$MyTickets->OrderBy(FIELD => 'Priority', ORDER => 'DESC');
+
+</%INIT>
diff --git a/rt/html/Elements/MyTickets b/rt/html/Elements/MyTickets
new file mode 100644 (file)
index 0000000..6e2ddc6
--- /dev/null
@@ -0,0 +1,81 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/TitleBoxStart, title => loc("[_1] highest priority tickets I own...", $rows), bodyclass=> '' &>
+<TABLE BORDER=0 cellspacing=0 cellpadding=1 WIDTH=100%>
+<TR>
+<TH ALIGN=RIGHT><&|/l&>#</&></TH>
+<TH ALIGN=LEFT><&|/l&>Subject</&></TH>
+<TH ALIGN=LEFT><&|/l&>Queue</&></TH>
+<TH ALIGN=LEFT><&|/l&>Status</&></TH>
+<TH ALIGN=LEFT>&nbsp;</TH>
+</TR>
+  <TR>    
+% my $i;
+% while (my $Ticket = $MyTickets->Next) {
+%     next if $Ticket->HasUnresolvedDependencies( Type => 'approval' );
+%     last if $i++ >= $rows;
+<TR class="<% $i%2 ? 'oddline' : 'evenline'%>" >                                
+<TD ALIGN=RIGHT>
+<%$Ticket->Id%>
+</TD>
+<TD>
+<A HREF="<% $RT::WebPath %>/Ticket/Display.html?id=<%$Ticket->Id%>">
+<%$Ticket->Subject || loc('(no subject)')%>
+</A>
+</TD>
+<TD>
+<%$Ticket->QueueObj->Name%>
+</TD>
+<TD>
+% if ($Ticket->HasUnresolvedDependencies ) {
+%     if ($Ticket->HasUnresolvedDependencies( Type => 'approval' ) or
+%         $Ticket->HasUnresolvedDependencies( Type => 'code' )) {
+<em><&|/l&>(pending approval)</&></em>
+%     } else {
+<em><&|/l&>(pending other tickets)</&></em>
+%     }
+% } else {
+<%loc($Ticket->Status)%>
+% }
+</TD>
+<TD ALIGN=RIGHT>
+[<A HREF="<% $RT::WebPath %>/Ticket/Update.html?id=<%$Ticket->Id%>"><&|/l&>Update</&></A>]
+</TD>
+</TR>
+% }
+</TABLE>
+<& /Elements/TitleBoxEnd &>
+
+
+<%INIT>
+my $rows = 10;
+my $MyTickets;
+$MyTickets = new RT::Tickets ($session{'CurrentUser'});
+$MyTickets->LimitOwner(VALUE => $session{'CurrentUser'}->Id);
+$MyTickets->LimitStatus(VALUE => "open");
+$MyTickets->LimitStatus(VALUE => "new");
+$MyTickets->RowsPerPage($rows);
+$MyTickets->OrderBy(FIELD => 'Priority', ORDER => 'DESC');
+
+</%INIT>
diff --git a/rt/html/Elements/PageLayout b/rt/html/Elements/PageLayout
new file mode 100644 (file)
index 0000000..6853175
--- /dev/null
@@ -0,0 +1,99 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<table class="darkblue" border=0 cellspacing=0 cellpadding=0 width="100%">
+  <th class="titlebox" align="left"><span class="rtname"><%$AppName%></span>
+  </th>
+      <span class="topactions">
+% foreach my $action (sort keys %{$topactions}) {
+        <td class="darkblueright">
+        <%$topactions->{"$action"}->{'html'} |n %>
+        </td>
+% }
+      </span>
+</table>
+<table border=0 cellspacing=0 cellpadding=0 width="100%" height="100%">
+%# Vertical menu
+<TR height="100%">
+<TD valign="top" width="140" class="blue">
+          <& /Elements/Menu, toptabs => $toptabs, current_toptab => $current_toptab &>
+</TD>
+<td valign="top">
+<table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0">
+<tr>
+  <td class="blue" valign="top">
+    <span class="title"><%$title%></span>
+</td>
+</tr>
+<tr>
+<td class="blueright" valign="top">
+    <span class="nav"> 
+% if ($actions) {
+% my @actions;
+% foreach my $action (sort keys %{$actions}) {
+% if ($actions->{"$action"}->{'html'}) {
+% push @actions, $actions->{"$action"}->{'html'}; 
+% } else {
+% push @actions,  "<A class='nav' HREF=\"".$RT::WebPath."/".$actions->{$action}->{'path'}."\">".$actions->{$action}->{'title'}."</A>";
+% }
+%  }
+<% join(" | ", @actions) | n %>
+% if ($subactions) {
+% my @actions;
+% foreach my $action (sort keys %{$subactions}) {
+% push @actions, $subactions->{"$action"}->{'html'}; 
+%  }
+<% join(" | ", @actions) | n %>
+% }
+% }
+    </span>
+  </td>
+</tr>
+<TR valign="top">
+<TD valign="top" width="100%" height="100%" class="mainbody" >
+
+<%INIT>
+
+  foreach my $tab (sort keys %{$toptabs}) {
+    if ($toptabs->{$tab}->{'path'} eq $current_toptab) {
+      $toptabs->{$tab}->{"subtabs"} = $tabs;
+      $toptabs->{$tab}->{"current_subtab"} = $current_tab;
+    }
+  }
+
+if (! defined($AppName)) {
+  $AppName = loc("RT for [_1]", $RT::rtname);
+}
+
+</%INIT>
+<%ARGS>
+$current_toptab => undef
+$current_tab => undef
+$toptabs => undef
+$topactions => undef
+$tabs => undef
+$actions => undef
+$subactions => undef
+$title => $m->callers(-1)->path
+$AppName => undef
+</%ARGS>
diff --git a/rt/html/Elements/Quicksearch b/rt/html/Elements/Quicksearch
new file mode 100644 (file)
index 0000000..b1a67ab
--- /dev/null
@@ -0,0 +1,61 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/TitleBoxStart, title => loc("Quick search"), bodyclass => "" &>
+
+<TABLE BORDER=0 cellspacing=0 cellpadding=1 WIDTH=100%>                       
+<tr>                                                                          
+       <th align=left><&|/l&>Queue</&></th>                                         
+       <th align=right><font size=-1><&|/l&>New</&></font></th>
+       <th align=right><font size=-1><&|/l&>Open</&></font></th>          
+</tr>
+
+<%PERL>
+my $i;
+while (my $queue = $Queues->Next) {
+     $Tickets->ClearRestrictions;                                           
+     $Tickets->LimitStatus(VALUE => "open");                                
+     $Tickets->LimitQueue(VALUE => $queue->Name, OPERATOR => '=');            
+     my $open = $Tickets->Count();
+
+     $Tickets->ClearRestrictions;                                           
+     $Tickets->LimitStatus(VALUE => "new");
+     $Tickets->LimitQueue(VALUE => $queue->Name, OPERATOR => '=');            
+     my $new = $Tickets->Count();
+
+</%PERL>
+% $i++;                                                                         
+<TR class="<% $i%2 ? 'oddline' : 'evenline'%>" >                                
+<td><A HREF="<% $RT::WebPath%>/Search/Listing.html?ValueOfStatus=open&ValueOfStatus=new&StatusOp=%3D&QueueOp=%3D&ValueOfQueue=<%$queue->Id%>&RowsPerPage=50&NewSearch=1" TITLE="<% $queue->Description %>"><%$queue->Name%></a></TD>
+<td align="right"><A HREF="<% $RT::WebPath%>/Search/Listing.html?ValueOfStatus=new&StatusOp=%3D&QueueOp=%3D&ValueOfQueue=<%$queue->Id%>&RowsPerPage=50&NewSearch=1"><%$new%></a></TD>
+<td align="right"><A HREF="<% $RT::WebPath%>/Search/Listing.html?ValueOfStatus=open&StatusOp=%3D&QueueOp=%3D&ValueOfQueue=<%$queue->Id%>&RowsPerPage=50&NewSearch=1"><%$open%></a></TD>
+</TR>
+% }
+</TABLE>
+<& /Elements/TitleBoxEnd &>
+
+<%INIT>
+my $Queues = RT::Queues->new($session{'CurrentUser'}); 
+$Queues->UnLimit();
+my $Tickets = RT::Tickets->new($session{'CurrentUser'});
+</%INIT>
diff --git a/rt/html/Elements/Refresh b/rt/html/Elements/Refresh
new file mode 100644 (file)
index 0000000..2b5376f
--- /dev/null
@@ -0,0 +1,45 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME="<%$Name%>">
+<OPTION VALUE="-1"
+%unless ($Default) {
+ SELECTED
+%}
+><&|/l&>Don't refresh this page.</&></OPTION>
+%foreach my $value (@refreshevery) {
+<OPTION VALUE="<%$value%>"
+% if ($value == $Default) {
+SELECTED 
+% }
+><&|/l, $value/60 &>Refresh this page every [_1] minutes.</&></OPTION>
+%}
+</SELECT>
+
+<%INIT>
+my @refreshevery = qw(120 300 600 1200 3600 7200);
+</%INIT>
+<%ARGS>
+$Name => undef
+$Default => 0
+</%ARGS>
diff --git a/rt/html/Elements/Section b/rt/html/Elements/Section
new file mode 100644 (file)
index 0000000..6912358
--- /dev/null
@@ -0,0 +1,34 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TABLE WIDTH=100%>
+<TR>
+<TD>
+<font size=+4><%$title%></font>
+</TD>
+</TR>
+</TABLE>
+
+<%ARGS>
+$title => undef
+</%ARGS>
diff --git a/rt/html/Elements/SelectAttachmentField b/rt/html/Elements/SelectAttachmentField
new file mode 100644 (file)
index 0000000..47bc532
--- /dev/null
@@ -0,0 +1,31 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME="<%$Name%>">
+<OPTION VALUE="Content"><&|/l&>content</&></OPTION>
+<OPTION VALUE="ContentType"><&|/l&>content-type</&></OPTION>
+<OPTION VALUE="Filename"><&|/l&>filename</&></OPTION>
+</SELECT>
+<%ARGS>
+$Name => 'AttachmentField'
+</%ARGS>
diff --git a/rt/html/Elements/SelectBoolean b/rt/html/Elements/SelectBoolean
new file mode 100644 (file)
index 0000000..8cf60dc
--- /dev/null
@@ -0,0 +1,46 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME ="<%$Name%>">
+<OPTION VALUE="<%$TrueVal%>" <%$TrueDefault%>><%$True%></OPTION>
+<OPTION VALUE="<%$FalseVal%>" <%$FalseDefault%>><%$False%></OPTION>
+</SELECT>
+
+<%ARGS>
+$Name => undef
+$True => loc("is")
+$Default => 'true'
+$TrueVal => 1
+$FalseVal => 0
+$False => loc("isn't")
+</%ARGS>
+
+<%INIT>
+my ($TrueDefault, $FalseDefault);
+if ($Default && $Default !~ /true/i) {
+       $FalseDefault = "SELECTED";
+}
+else {
+       $TrueDefault = "SELECTED";
+}
+</%INIT>
diff --git a/rt/html/Elements/SelectCustomFieldOperator b/rt/html/Elements/SelectCustomFieldOperator
new file mode 100644 (file)
index 0000000..e886cbe
--- /dev/null
@@ -0,0 +1,40 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME ="<%$Name%>">
+% while (my $option = shift @Options) {
+% my $value = shift @Values;
+<OPTION VALUE="<%$value%>"
+% if ($Default eq $value) {
+SELECTED
+% }
+><%$option%></OPTION>
+% }
+</SELECT>
+
+<%ARGS>
+$Name => undef
+@Options => ( loc('contains'), loc("doesn't contain"), loc('is'), loc("isn't"), loc('less than'), loc('greater than'))
+@Values => ('LIKE', 'NOT LIKE', '=', '!=', '<', '>')
+$Default => undef
+</%ARGS>
diff --git a/rt/html/Elements/SelectCustomFieldValue b/rt/html/Elements/SelectCustomFieldValue
new file mode 100644 (file)
index 0000000..60f65bc
--- /dev/null
@@ -0,0 +1,41 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Callback, %ARGS &>
+% if ($CustomField->Type =~ /Select/i) {
+% my $values = $CustomField->Values;
+<select name="<%$Name%>">
+<option value="" SELECTED>-</option>
+<option value="null"><&|/l&>(no value)</&></option>
+% while (my $value = $values->Next) {
+<option value="<%$value->Name%>"><%$value->Name%></option>
+% }
+</select>
+% }
+% else {
+<input name="<%$Name%>" size="20">
+% }
+<%args>
+$Name => undef
+$CustomField =>undef
+</%args>
diff --git a/rt/html/Elements/SelectDate b/rt/html/Elements/SelectDate
new file mode 100644 (file)
index 0000000..5f169fc
--- /dev/null
@@ -0,0 +1,48 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<INPUT NAME="<%$Name%>" VALUE="<%$Default%>" size=16> 
+
+<%init>
+unless ((defined $Default) or 
+       ($current <= 0)) {
+       my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
+                                            localtime($current);
+        $Default = sprintf("%04d-%02d-%02d %02d:%02d",                         
+                           $year+1900,$mon+1,$mday,                            
+                           $hour,$min);   
+}
+
+unless ($Name) {
+       $Name = $menu_prefix. "_Date";
+}
+</%init>
+
+<%args>
+
+$ShowTime => undef
+$menu_prefix=>''
+$current=>time
+$Default => undef
+$Name => undef
+</%args>
diff --git a/rt/html/Elements/SelectDateRelation b/rt/html/Elements/SelectDateRelation
new file mode 100644 (file)
index 0000000..ee26efe
--- /dev/null
@@ -0,0 +1,36 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME ="<%$Name%>">
+<OPTION VALUE="&lt;"><%$Before%></OPTION>
+<OPTION VALUE="="><%$On%></OPTION>
+<OPTION VALUE="&gt;"><%$After%></OPTION>
+</SELECT>
+
+<%ARGS>
+$Name => undef
+$Default => undef
+$Before => loc('Before')
+$On =>         loc('On')
+$After => loc('After')
+</%ARGS>
diff --git a/rt/html/Elements/SelectDateType b/rt/html/Elements/SelectDateType
new file mode 100644 (file)
index 0000000..afb9a70
--- /dev/null
@@ -0,0 +1,36 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME="<%$Name%>">
+<OPTION VALUE="Created"><&|/l&>Created</&></OPTION>
+<OPTION VALUE="Started"><&|/l&>Started</&></OPTION>
+<OPTION VALUE="Resolved"><&|/l&>Resolved</&></OPTION>
+<OPTION VALUE="Told"><&|/l&>Last Contacted</&></OPTION>
+<OPTION VALUE="LastUpdated"><&|/l&>Last Updated</&></OPTION>
+<OPTION VALUE="Starts"><&|/l&>Starts</&></OPTION>
+<OPTION VALUE="Due"><&|/l&>Due</&></OPTION>
+<OPTION VALUE="Updated"><&|/l&>Updated</&></OPTION>
+</SELECT>
+<%ARGS>
+$Name => 'DateType'
+</%ARGS>
diff --git a/rt/html/Elements/SelectEqualityOperator b/rt/html/Elements/SelectEqualityOperator
new file mode 100644 (file)
index 0000000..99c60d5
--- /dev/null
@@ -0,0 +1,40 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME ="<%$Name%>">
+% while (my $option = shift @Options) {
+% my $value = shift @Values;
+<OPTION VALUE="<%$value%>"
+% if ($Default eq $value) {
+SELECTED
+% }
+><%$option%></OPTION>
+% }
+</SELECT>
+
+<%ARGS>
+$Name => undef
+@Options => (loc('less than'), loc('equal to'), loc('greater than'), loc('not equal to'))
+@Values => qw(< = > !=)
+$Default => undef
+</%ARGS>
diff --git a/rt/html/Elements/SelectGroups b/rt/html/Elements/SelectGroups
new file mode 100644 (file)
index 0000000..8f33c1e
--- /dev/null
@@ -0,0 +1,29 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<select name="GroupField">
+<option value="Name"><&|/l&>Name</&>
+<option value="Description"><&|/l&>Description</&>
+</select>
+<& /Elements/SelectMatch, Name=> 'GroupOp' &>
+<input size=8 name="GroupString">
diff --git a/rt/html/Elements/SelectLinkType b/rt/html/Elements/SelectLinkType
new file mode 100644 (file)
index 0000000..9ebefda
--- /dev/null
@@ -0,0 +1,37 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME ="<%$Name%>">
+<OPTION VALUE="MemberOf"><&|/l&>Member of</&></OPTION>
+<OPTION VALUE="DependsOn"><&|/l&>Depends on</&></OPTION>
+<OPTION VALUE="RefersTo"><&|/l&>Refers to</&></OPTION>
+</SELECT>
+
+<%ARGS>
+$Name => "LinkType"
+$Default => undef
+</%ARGS>
+
+<%INIT>
+# TODO handle Default
+</%INIT>
diff --git a/rt/html/Elements/SelectMatch b/rt/html/Elements/SelectMatch
new file mode 100644 (file)
index 0000000..d58a963
--- /dev/null
@@ -0,0 +1,53 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME ="<%$Name%>">
+<OPTION VALUE="LIKE" <%$LikeDefault%>><%$Like%></OPTION>
+<OPTION VALUE="NOT LIKE" <%$NotLikeDefault%>><%$NotLike%></OPTION>
+<OPTION VALUE="=" <%$TrueDefault%>><%$True%></OPTION>
+<OPTION VALUE="!=" <%$FalseDefault%>><%$False%></OPTION>
+</SELECT>
+
+<%ARGS>
+$Name => undef
+$Like => loc('contains')
+$NotLike => loc("doesn't contain")
+$True => loc('is')
+$False => loc("isn't")
+$Default => undef
+</%ARGS>
+<%INIT>
+my ($TrueDefault, $FalseDefault, $LikeDefault, $NotLikeDefault);
+if ($Default && $Default !~ /true/i) {
+       $FalseDefault = "SELECTED";
+}
+elsif ($Default && $Default !~ /false/i) {
+       $TrueDefault = "SELECTED";
+} 
+elsif ($Default && $Default !~ /notlike/i) {
+       $NotLikeDefault = "SELECTED";
+}
+else {
+       $LikeDefault = "SELECTED";
+}
+</%INIT>
diff --git a/rt/html/Elements/SelectNewTicketQueue b/rt/html/Elements/SelectNewTicketQueue
new file mode 100644 (file)
index 0000000..a629b7b
--- /dev/null
@@ -0,0 +1,56 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<LABEL ACCESSKEY="9">
+<SELECT NAME ="<%$Name%>">
+% foreach my $queue (@{$session{'create_in_queues'}}) {
+<OPTION VALUE="<%$queue->{'id'}%>" <%($Default && ($queue->{'id'} == $Default)) && 'SELECTED'%>><%$queue->{'Name'}%>
+%   if (($Verbose) and ($queue->{'Description'}) ){
+(<%$queue->{'Description'}%>)
+%  }
+</OPTION>
+% }
+</SELECT>
+</LABEL>
+
+<%INIT>
+unless ($session{'create_in_queues'}) { 
+
+@{$session{'create_in_queues'}} = ();
+my $q=new RT::Queues($session{'CurrentUser'});
+$q->UnLimit;
+while (my $queue=$q->Next) {
+        if ($queue->CurrentUserHasRight('CreateTicket')) {
+                my $ds = { Name => $queue->Name, Description => $queue->Description, id => $queue->id };
+                push (@{$session{'create_in_queues'}}, $ds);
+        }        
+}
+}
+</%INIT>
+
+
+<%ARGS>
+$Name => 'Queue'
+$Verbose => undef
+$Default => undef
+</%ARGS>
diff --git a/rt/html/Elements/SelectOwner b/rt/html/Elements/SelectOwner
new file mode 100644 (file)
index 0000000..04b078d
--- /dev/null
@@ -0,0 +1,59 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME="<%$Name%>">
+<OPTION VALUE="">-</OPTION>
+<OPTION <% ($RT::Nobody->Id() == $Default) && "SELECTED" %> VALUE="<%$RT::Nobody->Id%>"><%$RT::Nobody->Name%></OPTION>
+%while ( my $User = $Users->Next())  {
+<OPTION VALUE="<%$User->Id()%>" <% ($User->Id() == $Default) && "SELECTED" %>><%$User->Name()%></OPTION>
+%}
+</SELECT>
+
+<%INIT>
+my $Users = RT::Users->new($session{CurrentUser});
+my $object;
+
+
+if ($TicketObj) {
+        $object = $TicketObj;
+}
+elsif ($QueueObj) {
+        $object = $QueueObj;
+}
+if ($object) {
+        $Users->WhoHaveRight(Right => 'OwnTicket',
+                     Object => $object,
+                     IncludeSystemRights => 1,
+                     IncludeSuperusers => 1);
+} else {
+        $Users->LimitToPrivileged;
+}
+</%INIT>
+
+<%ARGS>
+$QueueObj => undef
+$Name => undef
+$Default => undef
+$User => undef
+$TicketObj => undef
+</%ARGS>
diff --git a/rt/html/Elements/SelectQueue b/rt/html/Elements/SelectQueue
new file mode 100644 (file)
index 0000000..c45b9b5
--- /dev/null
@@ -0,0 +1,59 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+% if ($Lite) {
+<INPUT NAME="<%$Name%>" size=25 DEFAULT="<%$d->Name%>">
+% } else {
+<SELECT NAME ="<%$Name%>">
+% if ($ShowNullOption) {
+<OPTION VALUE="">-</OPTION>
+% }
+% while (my $queue=$q->Next) {
+% if ($ShowAllQueues || $queue->CurrentUserHasRight('CreateTicket')) {
+<OPTION VALUE="<%$queue->Id%>" <%($Default && ($queue->Id == $Default)) && 'SELECTED'%>><%$queue->Name%>
+%   if (($Verbose) and ($queue->Description) ){
+(<%$queue->Description%>)
+%  }
+</OPTION>
+% }
+% }
+</SELECT>
+% }
+<%ARGS>
+$ShowNullOption => 1
+$ShowAllQueues => 1
+$Name => undef
+$Verbose => undef
+$Default => 0
+$Lite => 0
+</%ARGS>
+
+<%INIT>
+
+my $q=new RT::Queues($session{'CurrentUser'});
+$q->UnLimit;
+
+my $d = new RT::Queue($session{'CurrentUser'});
+$d->Load($Default);
+
+</%INIT>
diff --git a/rt/html/Elements/SelectResultsPerPage b/rt/html/Elements/SelectResultsPerPage
new file mode 100644 (file)
index 0000000..1bde713
--- /dev/null
@@ -0,0 +1,43 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+%# TODO: Better default handling
+
+<SELECT NAME ="<%$Name%>">
+% foreach my $value (@values) {
+<OPTION VALUE="<%$value%>" <% $value == $Default && 'SELECTED' %>>
+<% shift @labels %>
+</OPTION>
+% }
+</SELECT>
+
+<%INIT>
+my @values = qw(0 10 25 50 100);
+my @labels = (loc('Unlimited'), qw(10 25 50 100));
+</%INIT>
+<%ARGS>
+
+$Name => undef
+$Default => 50
+
+</%ARGS>
diff --git a/rt/html/Elements/SelectSortOrder b/rt/html/Elements/SelectSortOrder
new file mode 100644 (file)
index 0000000..0ad999a
--- /dev/null
@@ -0,0 +1,41 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME="<%$Name%>">
+%foreach my $order (@orders) {
+<OPTION VALUE="<%$order%>" <%$order eq $Default && 'SELECTED' %>>
+<% shift @order_names %>
+</OPTION>
+% }
+</SELECT>
+
+<%INIT>
+my @orders = qw (ASC DESC);
+my @order_names = (loc('Ascending'), loc('Descending'));
+
+</%INIT>
+
+<%ARGS>
+$Name => 'SortOrder'
+$Default => 'ASC'
+</%ARGS>
diff --git a/rt/html/Elements/SelectStatus b/rt/html/Elements/SelectStatus
new file mode 100644 (file)
index 0000000..2c1ffad
--- /dev/null
@@ -0,0 +1,37 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME ="<%$Name%>">
+<OPTION VALUE="">-</OPTION>
+%foreach my $status (@status) {
+<OPTION VALUE="<%$status%>" <%($Default eq $status) && 'SELECTED'%>><%loc($status)%></OPTION>
+% }
+</SELECT>
+<%ONCE>
+my $queue = new RT::Queue($session{'CurrentUser'});
+my @status = $queue->StatusArray();
+</%ONCE>
+<%ARGS>
+$Name => undef
+$Default => undef
+</%ARGS>
diff --git a/rt/html/Elements/SelectTicketSortBy b/rt/html/Elements/SelectTicketSortBy
new file mode 100644 (file)
index 0000000..1d0b394
--- /dev/null
@@ -0,0 +1,38 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME="<%$Name%>">
+% foreach my $field (@sortfields) {
+<OPTION VALUE="<%$field%>" <% $field eq $Default && 'SELECTED'%>><% loc($field) %></OPTION>
+% }
+</SELECT>
+
+<%INIT>
+my $tickets = new RT::Tickets($session{'CurrentUser'});
+my @sortfields = $tickets->SortFields();
+
+</%INIT>
+<%ARGS>
+$Name => 'SortTicketsBy'
+$Default => 'id'
+</%ARGS>
diff --git a/rt/html/Elements/SelectTicketTypes b/rt/html/Elements/SelectTicketTypes
new file mode 100644 (file)
index 0000000..80aecac
--- /dev/null
@@ -0,0 +1,34 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME="<%$Name%>">
+%foreach (@Types) {
+<OPTION VALUE="<% $_ %>" <% ($_ eq $Default) && "SELECTED" %>><&|/l&><% $_ %></&>
+%}
+</SELECT>
+
+<%ARGS>
+$Name => 'TickType'
+$Default => undef
+@Types => qw(Approval Ticket)
+</%ARGS>
diff --git a/rt/html/Elements/SelectUsers b/rt/html/Elements/SelectUsers
new file mode 100644 (file)
index 0000000..7ed3835
--- /dev/null
@@ -0,0 +1,31 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<select name="UserField">
+<option value="Name"><&|/l&>User Id</&>
+<option value="EmailAddress"><&|/l&>Email</&>
+<option value="RealName"><&|/l&>Name</&>
+<option value="Organization"><&|/l&>Organization</&>
+</select>
+<& /Elements/SelectMatch, Name=> 'UserOp' &>
+<input size=8 name="UserString">
diff --git a/rt/html/Elements/SelectWatcherType b/rt/html/Elements/SelectWatcherType
new file mode 100644 (file)
index 0000000..26de8f7
--- /dev/null
@@ -0,0 +1,44 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME ="<%$Name%>">
+<OPTION VALUE="">-</OPTION>
+%for my $option (@types) {
+<OPTION VALUE="<%$option%>" <%$option eq $Default && "SELECTED"%>><%loc($option)%></OPTION>
+%}
+</SELECT>
+
+<%INIT>
+my @types;
+if ($Scope =~ 'queue') {
+   @types = qw(Cc AdminCc);
+}
+else { 
+   @types = qw(Requestor Cc AdminCc);
+}
+</%INIT>
+<%ARGS>
+$Default=>undef
+$Scope => 'ticket'
+$Name => 'WatcherType'
+</%ARGS>
diff --git a/rt/html/Elements/SetupSessionCookie b/rt/html/Elements/SetupSessionCookie
new file mode 100644 (file)
index 0000000..4d728ce
--- /dev/null
@@ -0,0 +1,77 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<%init>
+my %cookies = CGI::Cookie->fetch();
+my %backends = (
+    mysql      => 'Apache::Session::MySQL',
+    Pg         => 'Apache::Session::Postgres',
+    Oracle     => 'Apache::Session::Oracle',
+) unless $RT::WebSessionClass;
+my $session_class = $RT::WebSessionClass || $backends{$RT::DatabaseType} || 'Apache::Session::File';
+my $pm = "$session_class.pm"; $pm =~ s|::|/|g; require $pm;
+
+    eval {
+        tie %session, $session_class,
+          $SessionCookie || ( $cookies{'RT_SID'} ? $cookies{'RT_SID'}->value() : undef ),
+          $backends{$RT::DatabaseType} ? {
+            Handle     => $RT::Handle->dbh,
+            LockHandle => $RT::Handle->dbh,
+          } : {
+            Directory     => $RT::MasonSessionDir,
+            LockDirectory => $RT::MasonSessionDir,
+          };
+    };
+    if ($@) {
+
+        # If the session is invalid, create a new session.
+        if ( $@ =~ /Object does not/i ) {
+            tie %session, $session_class, undef,
+             $backends{$RT::DatabaseType} ? {
+                Handle     => $RT::Handle->dbh,
+                LockHandle => $RT::Handle->dbh,
+              } : {
+                Directory     => $RT::MasonSessionDir,
+                LockDirectory => $RT::MasonSessionDir,
+              };
+            undef $cookies{'RT_SID'};
+        }
+        else {
+            die "RT Couldn't write to session directory '$RT::MasonSessionDir': $@. Check that this dir ectory's permissions are correct.";
+        }
+    }
+
+    if ( !$cookies{'RT_SID'} ) {
+        my $cookie = new CGI::Cookie(
+            -name  => 'RT_SID',
+            -value => $session{_session_id},
+            -path  => '/',
+        );
+        $r->header_out('Set-Cookie', $cookie->as_string);
+
+    } 
+    return();
+</%init>
+<%args>
+$SessionCookie => ''
+</%args>
diff --git a/rt/html/Elements/ShadedBox b/rt/html/Elements/ShadedBox
new file mode 100644 (file)
index 0000000..36b9cae
--- /dev/null
@@ -0,0 +1,33 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<table>
+  <tr>
+    <td class="label"><%$title |n %>:</td>
+    <td class="value"><%$content |n %></td>
+  </tr>
+</table>
+<%ARGS>
+$title => undef
+$content => "&nbsp;"
+</%ARGS>
diff --git a/rt/html/Elements/ShadedInputRow b/rt/html/Elements/ShadedInputRow
new file mode 100644 (file)
index 0000000..e9fb69e
--- /dev/null
@@ -0,0 +1,35 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<tr>
+  <td class="label"><%$title |n %>:</td>
+  <td class="value">
+    <input name=<%$name%> value="<%$content|h%>" SIZE=<%$size%>>
+  </td>
+</tr>
+<%ARGS>
+$title => undef
+$content => "&nbsp;"
+$name => undef
+$size => undef
+</%ARGS>
diff --git a/rt/html/Elements/ShadedRow b/rt/html/Elements/ShadedRow
new file mode 100644 (file)
index 0000000..8947fcd
--- /dev/null
@@ -0,0 +1,31 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<tr>
+  <td class="label"><%$title |n %>:</td>
+  <td class="value"><%$content |n %></td>
+</tr>
+<%ARGS>
+$title => undef
+$content => "&nbsp;"
+</%ARGS>
diff --git a/rt/html/Elements/SimpleSearch b/rt/html/Elements/SimpleSearch
new file mode 100644 (file)
index 0000000..69541f8
--- /dev/null
@@ -0,0 +1,27 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<form action="<% $RT::WebPath %>/index.html">
+<input size="12" name="q" accesskey="0">
+<input type="submit" value="<&|/l&>Search</&>">&nbsp;
+</form>
diff --git a/rt/html/Elements/Submit b/rt/html/Elements/Submit
new file mode 100644 (file)
index 0000000..2c35ca0
--- /dev/null
@@ -0,0 +1,62 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TABLE WIDTH=100% BGCOLOR="<%$color%>" CELLSPACING=0 BORDER=0 CELLPADDING=0 >
+<TR>
+% if ($Reset) {
+<TD>
+<FONT COLOR=#ffd800 >
+<INPUT TYPE=RESET VALUE="<%$ResetLabel%>">
+</FONT>
+</TD>
+%}
+<TD>
+&nbsp;
+</TD>
+<TD ALIGN=RIGHT VALIGN=CENTER><FONT COLOR=#ffd800>
+% if ($AlternateLabel) {
+<B><%$AlternateCaption%>
+<INPUT TYPE=SUBMIT
+%if ($Name) {
+NAME="<%$Name%>"
+%}
+VALUE='<%$AlternateLabel%>'></B>
+% }
+<B><%$Caption%> <INPUT TYPE=SUBMIT
+%if ($Name) {
+NAME="<%$Name%>"
+% }
+ VALUE='<%$Label%>'></B></FONT>
+</TD>
+</TR>
+</TABLE>
+<%ARGS>
+$color => "#336699"
+$Caption => undef
+$AlternateCaption => undef
+$AlternateLabel => undef
+$Label => loc('Submit')
+$Name => undef
+$Reset => undef
+$ResetLabel => loc('Reset')
+</%ARGS>
diff --git a/rt/html/Elements/Tabs b/rt/html/Elements/Tabs
new file mode 100644 (file)
index 0000000..4db3849
--- /dev/null
@@ -0,0 +1,82 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/PageLayout,
+    current_toptab => $current_toptab,
+    current_tab => $current_tab,
+    toptabs => $toptabs,
+    topactions => $topactions,
+    tabs => $tabs,
+    actions => $actions,
+    subactions => $subactions,
+    title => $Title
+&>
+<a name="skipnav" id="skipnav" accesskey="8"></a>
+<%INIT>
+my $action;
+my $basetopactions = {
+       A => { html => $m->scomp('/Elements/CreateTicket')      
+               },
+       B => { html => $m->scomp('/Elements/SimpleSearch') 
+               }
+       };
+my $basetabs = {     A => { title => loc('Homepage'),
+                           path => '',
+                         },
+                    B => { title => loc('Tickets'),
+                        path => 'Search/Listing.html'
+                      },
+                    E => { title => loc('Configuration'),
+                           path => 'Admin/'
+                         },
+                    K => { title => loc('Preferences'),
+                        path => 'User/Prefs.html'
+                      },
+                    P => { title => loc('Approval'),
+                           path => 'Approvals/'
+                         },
+                 };
+
+if (!defined $toptabs) {
+   $toptabs = $basetabs;
+}
+if (!defined $topactions) {
+   $topactions = $basetopactions;
+}
+                    
+  # Now let callbacks add their extra tabs
+  $m->comp('/Elements/Callback', 
+    topactions => $topactions, 
+    toptabs => $toptabs, %ARGS);
+
+</%INIT>
+<%ARGS>
+$current_toptab => undef
+$current_tab => undef
+$toptabs => undef
+$topactions => undef
+$tabs => undef
+$actions => undef
+$subactions => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Elements/TitleBoxEnd b/rt/html/Elements/TitleBoxEnd
new file mode 100644 (file)
index 0000000..37f3744
--- /dev/null
@@ -0,0 +1,31 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+    </TD>
+  </TR>
+</TABLE>
+<%ARGS>
+$title => undef
+$content => undef
+</%ARGS>
+
diff --git a/rt/html/Elements/TitleBoxStart b/rt/html/Elements/TitleBoxStart
new file mode 100644 (file)
index 0000000..02c76a7
--- /dev/null
@@ -0,0 +1,60 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TABLE CLASS="<%$class|n%>" 
+        BGCOLOR="<%$color%>" 
+        CELLSPACING=0
+        BORDER=0
+        WIDTH="<%$width%>"
+        CELLPADDING="0">
+
+  <TR>
+    <TH 
+        <%$color && "style=\"color: $color;\""|n%>
+        <%$class ? "class=\"$class\"" : "class=\"titlebox\""|n%>>
+      <span class="titleboxtitle">
+        <b>
+         <% $title_href && "<A CLASS=\"$title_class\" HREF=\"$title_href\">"|n%><%$title |n %><%  $title_href && "</A>" |n%></b>
+      </span>
+    </TH>
+    <TH  
+         <%$color && "style=\"color: $color;\""|n%>
+         <%$class ? "class=\"$class\"": "class=\"titleboxright\""|n%>>
+      <span class="titleboxright"><%$titleright ? $titleright : '&nbsp;' |n %></span>
+    </TH>
+  </TR>
+  <tr>
+    <td bgcolor="<%$contentbg%>" colspan="2" class="<%defined($bodyclass) ? $bodyclass :  $class|n%>">
+<%ARGS>
+$width => "100%"
+$class =>  undef
+$bodyclass => undef
+$title_href => undef
+$title => undef
+$title_class => undef
+
+$titleright_href => undef
+$titleright => undef
+$contentbg => "#dddddd"
+$color => "#336699"
+</%ARGS>
diff --git a/rt/html/Elements/ViewUser b/rt/html/Elements/ViewUser
new file mode 100644 (file)
index 0000000..6572724
--- /dev/null
@@ -0,0 +1,51 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/TitleBoxStart, 
+       title => "<a class='inverse' href=\"$RT::WebPath/Search/Listing.html?LimitRequestorById=1&IdOfRequestor=".$User->id."\">".loc("Tickets from [_1]", $name)."</a>",
+       titleright=> "<a class='inverse' href=\"$RT::WebPath/EditUserComments.html?id=".$User->id."\">".loc("Comments about [_1]", $name)."</a>" &>
+<TABLE WIDTH="100%">
+<tr>
+<td halign=left valign=top>
+%while (my $w=$tickets->Next) {
+<%$w->Id%>: <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$w->id%>"><%$w->Subject%></a> (<%$w->Status%>)<BR>
+%}
+</td>
+<td align=right valign=top>
+       <% ($User->Comments || loc("No comment entered about this user")) %>
+</tr>
+</table>
+<& /Elements/TitleBoxEnd &>
+
+<%ARGS>
+$User=>undef
+</%ARGS>
+
+<%INIT>
+my $name=$User->RealName || $User->EmailAddress;       
+
+my $tickets = new RT::Tickets($session{'CurrentUser'});
+$tickets->LimitWatcher(TYPE => 'Requestor', VALUE => $User->EmailAddress);
+
+
+</%INIT>
diff --git a/rt/html/NoAuth/Logout.html b/rt/html/NoAuth/Logout.html
new file mode 100644 (file)
index 0000000..a4bb997
--- /dev/null
@@ -0,0 +1,46 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<HTML>
+<HEAD>
+<TITLE>RT: Logout</TITLE>
+ <META HTTP-EQUIV="Refresh" CONTENT="0;URL=<%$URL%>">
+</HEAD>
+<BODY>
+<p><&|/l&>You have been logged out of RT.</&>
+
+<br>
+<br>
+<A HREF="<%$URL%>"><&|/l&>You're welcome to login again</&></a>
+
+
+<%PERL>
+if (defined %session) {
+       tied(%session)->delete;
+}
+$m->abort();
+</%PERL>
+
+<%ARGS>
+$URL => $RT::WebPath."/"
+</%ARGS>
diff --git a/rt/html/NoAuth/Reminder.html b/rt/html/NoAuth/Reminder.html
new file mode 100644 (file)
index 0000000..35da66e
--- /dev/null
@@ -0,0 +1,26 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, title => loc('Password Reminder') &>
+
+<&|/l&>Not yet implemented.</&>
diff --git a/rt/html/NoAuth/images/back_home.gif b/rt/html/NoAuth/images/back_home.gif
new file mode 100644 (file)
index 0000000..40b19c1
Binary files /dev/null and b/rt/html/NoAuth/images/back_home.gif differ
diff --git a/rt/html/NoAuth/images/bplogo.gif b/rt/html/NoAuth/images/bplogo.gif
new file mode 100644 (file)
index 0000000..e2cf49c
Binary files /dev/null and b/rt/html/NoAuth/images/bplogo.gif differ
diff --git a/rt/html/NoAuth/images/favicon.png b/rt/html/NoAuth/images/favicon.png
new file mode 100644 (file)
index 0000000..ed1ee37
Binary files /dev/null and b/rt/html/NoAuth/images/favicon.png differ
diff --git a/rt/html/NoAuth/images/head_requestracker.gif b/rt/html/NoAuth/images/head_requestracker.gif
new file mode 100644 (file)
index 0000000..73315e9
Binary files /dev/null and b/rt/html/NoAuth/images/head_requestracker.gif differ
diff --git a/rt/html/NoAuth/images/rt.jpg b/rt/html/NoAuth/images/rt.jpg
new file mode 100644 (file)
index 0000000..a137a93
Binary files /dev/null and b/rt/html/NoAuth/images/rt.jpg differ
diff --git a/rt/html/NoAuth/images/space.gif b/rt/html/NoAuth/images/space.gif
new file mode 100644 (file)
index 0000000..1d11fa9
Binary files /dev/null and b/rt/html/NoAuth/images/space.gif differ
diff --git a/rt/html/NoAuth/images/spacer.gif b/rt/html/NoAuth/images/spacer.gif
new file mode 100644 (file)
index 0000000..5bfd67a
Binary files /dev/null and b/rt/html/NoAuth/images/spacer.gif differ
diff --git a/rt/html/NoAuth/images/squares_blue.gif b/rt/html/NoAuth/images/squares_blue.gif
new file mode 100644 (file)
index 0000000..a28da5c
Binary files /dev/null and b/rt/html/NoAuth/images/squares_blue.gif differ
diff --git a/rt/html/NoAuth/webrt.css b/rt/html/NoAuth/webrt.css
new file mode 100644 (file)
index 0000000..62c6d66
--- /dev/null
@@ -0,0 +1,338 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+SPAN.nav {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 12px;
+        color: #FFFFFF;
+        text-decoration: none;
+        white-space: nowrap}
+.nav2 {         font-size: 10px;
+        white-space: nowrap}
+.nav {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 13px;
+        font-weight: normal;
+        color: #FFFFFF;
+        text-decoration: none;
+        white-space: nowrap}
+.currentnav {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 13px;
+         font-weight: bold;
+        color: #FFFF66;
+        text-decoration: none;
+        white-space: nowrap}
+.topnav {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 16px;
+        font-weight: normal;
+        color: #FFFFFF;
+        text-decoration: none;
+        white-space: nowrap}
+.currenttopnav {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 16px;
+         font-weight: bold;
+        color: #FFFF66;
+        text-decoration: none;
+        white-space: nowrap}
+.topactions {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 10px;
+        color: #FFFFFF;
+        text-decoration: none;
+        white-space: nowrap}
+.subnav {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 11px;
+        font-weight: normal;
+        color: #FFFFFF;
+        text-decoration: none;
+        white-space: nowrap}
+.currentsubnav {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 11px;
+         font-weight: bold;
+        color: #FFFF66;
+        text-decoration: none;
+        white-space: nowrap}
+.error {  background-color: #ff0000;
+        background-position: left top;
+        vertical-align: top;
+        text-align: left;
+         }
+.oldblue {  background-color: #0066CC;
+        background-position: left top;
+        vertical-align: top;
+        text-align: left;
+         }
+.blue {  background-color: #4682B4;
+        background-position: left top;
+        vertical-align: top;
+        text-align: left;
+         }
+.blueright {  background-color: #4682B4;
+        background-position: left top;
+        vertical-align: top;
+        text-align: right;
+         }
+.olddarkblue {  background-color: #003399;
+        background-position: left top;
+        vertical-align: top;
+        text-align: left;
+         }
+.darkblue {  background-color: #000080;
+        background-position: left top;
+        vertical-align: top;
+        text-align: left;
+         }
+.darkblueright {  background-color: #000080;
+        background-position: left top;
+        vertical-align: top;
+        text-align: right;
+         }
+
+td {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 11px;
+        background-position: left top;
+         }
+.black { background-color: #000000;
+        background-position: left top;
+         }
+span.rtname {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 18px;
+        font-weight: normal;
+        color: #ffffff}
+span.title {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 20px;
+        font-weight: bold;
+        color: #ffffff}
+.header {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 12px;
+        font-weight: bold;
+        color: #0066CC}
+.subheader { font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 11px;
+        font-weight: bold;
+        color: #0066CC }
+.value {       font-weight: bold; }
+.entry {       font-weight: normal; }
+.label {       font-weight: normal;
+              text-align: right; }
+.labeltop {       font-weight: normal;
+              text-align: right;
+              vertical-align: top }
+.productnav {  font-family: Verdana, Arial, Helvetica, sans-serif;
+        font-size: 11px;
+        color: #000000;
+        text-align: center;
+        vertical-align: middle;
+        text-decoration: none}
+.rtblue { background-color: #3399FF;
+         margin-top: 0.2em;
+        background-position: left top;
+        vertical-align: top }
+
+
+.currenttab { margin: 0.2em; background: #336699; }
+.othertab { margin: 0.2em; background: #efefef; }
+.oddline { background-color : #ccccee; }
+
+UL.topnav LI :focus { text-decoration: underline; }
+
+TD.mainbody {
+        padding-top: 0.5em;
+        padding-left: 0em;
+        padding-right: 1em;
+        margin-left: 1em;
+        margin-right: 1em;
+}
+
+th.ticketheader { font-size: 80%;
+     font-weight: bold;
+     color: #336699;
+     background: #cccccc; 
+}
+
+th.titlebox {
+        text-align: left;
+        padding-left: 0.5em;
+        padding-right: 0.5em;
+        margin-left: 0.5em;
+        margin-right: 0.5em;
+        border-top: solid black 1px;
+        border-bottom: solid black 1px;
+}    
+th.titleboxright {
+        text-align: right;
+        padding-left: 0.5em;
+        padding-right: 0.5em;
+        margin-left: 0.5em;
+        margin-right: 0.5em;
+        border-top: solid black 1px;
+        border-bottom: solid black 1px;
+}    
+
+TD.titlebox {
+        padding-left: 1em;
+        padding-right: 1em;
+        padding-top: 1em;
+        padding-bottom: 1em;
+}
+
+SPAN.message {
+       font-size: 100%;
+        font-family: Verdana, Arial, Helvetica, sans-serif;
+}
+
+
+BODY {
+  color: #000;
+  background: #FFFFFF;
+  font-family: "Helvetica", sans-serif;
+  margin-top: 0px;
+  margin-bottom: 0px;
+  margin-left: 0px;
+  margin-right: 0px;
+  border-top: 0px;
+  border-bottom: 0px;
+  border-left: 0px;
+  border-right: 0px;
+}
+
+
+TR.oddline { 
+    background-color : #ffffff;
+}
+
+TR.evenline { 
+    background-color : #ccccee;
+}
+
+H1, H2, H3 { 
+  margin-top: 0.2em;
+  color: #336699;
+  font-family: "Helvetica", sans-serif;
+
+  clear: both;
+}
+
+
+DIV.endmatter { margin-left: -7% }
+.bpscredits {margin-top: 1em;
+             text-align: right; 
+             color: #666666;
+             }
+
+
+A { font-weight: bold; color: #000000;
+            }
+
+.currenttab { color: #ffffff;}
+.othertab { color: #336699; }
+
+.inverse { color: #ffffff; }
+
+
+
+A:link IMG, A:visited IMG { border-style: none }
+a:focus {text-decoration: underline }
+A IMG { color: white } /* The only way to hide the border in NS 4.x */
+
+a:link {  text-decoration: none}
+a:visited {  text-decoration: none}  
+a:hover {  text-decoration: underline}
+/* a:focus { background-color: #ccccee } */
+
+.hide {
+  display: none;
+  color: white;
+}
+
+SPAN.date { font-size: 0.8em }
+
+span.title { font-size: 1.6em;
+            vertical-align: middle;
+             color: #ffffff;}
+span.productname { font-size: 2em;
+             color: #0066cc;}
+SPAN.titleboxtitle {
+        font-size: 1.1em;
+        color: #ffffff;
+        vertical-align: middle;
+        text-align: left;
+        }
+
+SPAN.titleboxright {
+        font-size: 0.8em;
+        color: #ffffff;
+        vertical-align: middle;
+        text-align: right;
+        }
+
+SPAN.attribution {
+  font-weight: bold;
+}
+
+SPAN.label { font-size: 0.8em; 
+}
+
+BLOCKQUOTE {
+  font-style: italic;
+  /* color: #990; */
+}
+
+ADDRESS { 
+  text-align: right;
+  font-weight: bold;
+  font-style: italic 
+}
+
+BLOCKQUOTE P {                 /* Try to avoid space above the attribution */
+  margin-bottom: 0;
+}
+BLOCKQUOTE ADDRESS {
+  margin: 0;
+}
+
+
+.emphasized {
+  font-weight: bold
+}
+
+
+P.map-also { font-style: italic; margin-left: 15%; text-align: right }
+
+.oddline { 
+        background-color : #ccccee;
+}
+
+ul.topnav {
+       list-style: none;
+       margin-left: 0;
+       margin-right: 0.25em;           
+       padding-left: 0.25em;
+       padding-bottom: 0;      
+       padding-top:0;
+       margin-top: 0;
+       margin-bottom:0;
+}
+
+
+<%init>
+$r->content_type('text/css');
+$r->header_out('Expires' ,'+30m');
+</%init>
diff --git a/rt/html/REST/1.0/NoAuth/mail-gateway b/rt/html/REST/1.0/NoAuth/mail-gateway
new file mode 100644 (file)
index 0000000..8db80d5
--- /dev/null
@@ -0,0 +1,49 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<%ARGS>
+$message
+$queue => 1
+$action => "correspond"
+$ticket => undef
+</%ARGS>
+<%init>
+use RT::Interface::Email; 
+my ( $status, $error, $Ticket ) = RT::Interface::Email::Gateway( %ARGS);
+</%init>
+<%flags>
+inherit => undef # inhibit UTF8 conversion done in /autohandler
+</%flags>
+%    if ($status) {
+ok
+%        if ( $Ticket->Id ) {
+Ticket: <% $Ticket->Id %>
+Queue: <% $Ticket->QueueObj->Name %>
+Owner: <% $Ticket->OwnerObj->Name %>
+Status: <% $Ticket->Status %>
+Subject: <% $Ticket->Subject %>
+Requestor: <% $Ticket->Requestors->MemberEmailAddressesAsString %>
+%        }
+% }   else { 
+not ok - <%$error%> 
+% }
diff --git a/rt/html/Search/Bulk.html b/rt/html/Search/Bulk.html
new file mode 100644 (file)
index 0000000..df43cfa
--- /dev/null
@@ -0,0 +1,217 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc("Bulk ticket update") &>
+<& /Elements/Tabs, Title => loc("Bulk ticket update") &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<FORM METHOD=POST>
+<TABLE WIDTH=100% border=0 cellpadding=3 CELLSPACING=0>
+<TR>
+<TH><&|/l&>Update</&></TH>
+%foreach my $col (@cols) {
+% my $colalias = $col;
+% $colalias =~ s/(Obj\-\>|)(Name|AsString)//;
+
+<TH><% loc($colalias) %>&nbsp;</TH>
+%}
+</TR>
+
+<%PERL>
+
+my $i;
+
+
+      
+$session{'tickets'}->RedoSearch();
+while (my $Ticket = $session{'tickets'}->Next) {
+ $i++;
+ if ($i % 2) {
+     $bgcolor = "#dddddd";
+ }
+ else {
+     $bgcolor = "#ffffff";
+ }
+      </%PERL>
+<TR bgcolor="<%$bgcolor%>">
+<TD><input type=checkbox name="UpdateTicket<%$Ticket->Id%>" CHECKED></TD>
+%# The ticket view is controlled by config.pm, WebOptions
+%foreach my $col (@cols) {
+<TD>
+% if ($col eq 'id') {
+<A HREF="<% $RT::WebPath%>/Ticket/Display.html?id=<%$Ticket->Id%>"><%$Ticket->Id()%></A>
+% }
+%else {
+<% eval "\$Ticket->$col()" %>&nbsp;
+%}
+</TD>
+%}
+</TR>
+%}
+
+
+
+</TABLE>
+
+<HR>
+
+
+<& /Elements/TitleBoxStart, title => loc('Update selected tickets') &>
+<TABLE>
+<TR>
+<TD VALIGN=TOP>
+<table>
+<tr><td class=label> <&|/l&>Make Owner</&>: </td>
+<td class=value> <& /Elements/SelectOwner, Name => "Owner" &> (<input type=checkbox name="ForceOwnerChange"> <&|/l&>Force change</&>) </td></tr>
+<tr><td class=label> <&|/l&>Add Requestor</&>: </td>
+<td class=value> <INPUT Name="AddRequestor" SIZE=20> </td></tr>
+<tr><td class=label> <&|/l&>Remove Requestor</&>: </td>
+<td class=value> <INPUT Name="DeleteRequestor" SIZE=20> </td></tr>
+<tr><td class=label> <&|/l&>Add Cc</&>: </td>
+<td class=value> <INPUT Name="AddCc" SIZE=20> </td></tr>
+<tr><td class=label> <&|/l&>Remove Cc</&>: </td>
+<td class=value> <INPUT Name="DeleteCc" SIZE=20> </td></tr>
+<tr><td class=label> <&|/l&>Add AdminCc</&>: </td>
+<td class=value> <INPUT Name="AddAdminCc" SIZE=20> </td></tr>
+<tr><td class=label> <&|/l&>Remove AdminCc</&>: </td>
+<td class=value> <INPUT Name="DeleteAdminCc" SIZE=20> </td></tr>
+</table>
+</TD>
+<TD VALIGN=TOP>
+<table>
+<tr><td class=label> <&|/l&>Make subject</&>: </td>
+<td class=value> <INPUT Name="Subject" SIZE=20> </td></tr>
+<tr><td class=label> <&|/l&>Make priority</&>: </td>
+<td class=value> <INPUT Name="Priority" SIZE=4> </td></tr>
+<tr><td class=label> <&|/l&>Make queue</&>: </td>
+<td class=value> <& /Elements/SelectQueue, Name => "Queue" &> </td></tr>
+<tr><td class=label> <&|/l&>Make Status</&>: </td>
+<td class=value> <& /Elements/SelectStatus, Name => "Status" &> </td></tr>
+<tr><td class=label> <&|/l&>Make date Starts</&>: </td>
+<td class=value> <& /Elements/SelectDate, Name => "Starts_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class=label> <&|/l&>Make date Started</&>: </td>
+<td class=value> <& /Elements/SelectDate, Name => "Started_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class=label> <&|/l&>Make date Told</&>: </td>
+<td class=value> <& /Elements/SelectDate, Name => "Told_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class=label> <&|/l&>Make date Due</&>: </td>
+<td class=value> <& /Elements/SelectDate, Name => "Due_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class=label> <&|/l&>Make date Resolved</&>: </td>
+<td class=value> <& /Elements/SelectDate, Name => "Resolved_Date", ShowTime => 0, Default => '' &> </td></tr>
+</table>
+
+</TD>
+</TR>
+</table>
+<& /Elements/TitleBoxEnd&>
+<& /Elements/TitleBoxStart, title => loc('Add comments or replies to selected tickets') &>
+<table>
+<tr><td align=right><&|/l&>Update Type</&>:</td>
+<td><select name="UpdateType">
+  <option value="private" ><&|/l&>Comments (not sent to requestors)</&></option>
+<option value="response" ><&|/l&>Response to requestors</&></option>
+</select> 
+</td></tr>
+<tr><td align=right><&|/l&>Subject</&>:</td><td> <input name="UpdateSubject" size=60 value=""></td></tr>
+ <tr><td align=right><&|/l&>Attach</&>:</td><td><input name="UpdateAttachment" type="file"></td></tr>
+ <tr><td class=labeltop><&|/l&>Message</&>:</td><td>
+ <& /Elements/MessageBox, Name=>"UpdateContent"&>
+ </td></tr>
+ </table>
+<& /Elements/TitleBoxEnd &>
+
+<& /Elements/TitleBoxStart, title => loc('Edit Relationships'), color => "#336633"&>
+<i><&|/l&>Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces.</&></i><br>
+<& /Ticket/Elements/BulkLinks &>
+<& /Elements/TitleBoxEnd &>
+
+<& /Elements/Submit &>
+
+
+</FORM>
+<%INIT>
+
+# Iterate through the ARGS hash and remove anything with a null value.
+map ($ARGS{$_} =~ /^$/ && (delete $ARGS{$_}), keys %ARGS);
+
+my ($bgcolor, @results);
+my @cols = qw(id Status Priority Subject QueueObj->Name OwnerObj->Name RequestorAddresses DueAsString );
+
+Abort(loc("No search to operate on.")) unless ($session{'tickets'});
+
+
+my $do_comment_reply=0;
+# Prepare for ticket updates
+$ARGS{'UpdateContent'} =~ s/\r\n/\n/g;
+chomp ($ARGS{'UpdateContent'}) ;
+
+if ($ARGS{'UpdateContent'} &&
+    $ARGS{'UpdateContent'} ne '' &&
+    $ARGS{'UpdateContent'} ne  "-- \n" .
+    $session{'CurrentUser'}->UserObj->Signature) {
+            $do_comment_reply=1;
+}
+
+#Iterate through each ticket we've been handed
+my @linkresults;
+
+while (my $Ticket = $session{'tickets'}->Next) {
+    $RT::Logger->debug( "Checking Ticket ".$Ticket->Id ."\n");
+    next unless ($ARGS{"UpdateTicket".$Ticket->Id});
+    $RT::Logger->debug ("Matched\n");
+    #Update the basics.
+    my @basicresults = ProcessTicketBasics(TicketObj => $Ticket, ARGSRef => \%ARGS);
+    my @dateresults = ProcessTicketDates(TicketObj => $Ticket, ARGSRef => \%ARGS);
+    #Update the watchers
+    my @watchresults = ProcessTicketWatchers(TicketObj => $Ticket, ARGSRef => \%ARGS);    
+
+    #Update the links
+    $ARGS{'id'} = $Ticket;
+    $ARGS{$Ticket->Id.'-MergeInto'} = $ARGS{'Ticket-MergeInto'};
+    $ARGS{$Ticket->Id.'-DependsOn'} = $ARGS{'Ticket-DependsOn'};
+    $ARGS{'DependsOn-'.$Ticket->Id} = $ARGS{'DependsOn-Ticket'};
+    $ARGS{$Ticket->Id.'-MemberOf'} = $ARGS{'Ticket-MemberOf'};
+    $ARGS{'MemberOf-'.$Ticket->Id} = $ARGS{'MemberOf-Ticket'};
+    $ARGS{$Ticket->Id.'-RefersTo'} = $ARGS{'Ticket-RefersTo'};
+    $ARGS{'RefersTo-'.$Ticket->Id} = $ARGS{'RefersTo-Ticket'};
+    @linkresults = ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS);
+    delete $ARGS{'id'};
+    delete $ARGS{$Ticket->Id.'-MergeInto'};
+    delete $ARGS{$Ticket->Id.'-DependsOn'};
+    delete $ARGS{'DependsOn-'.$Ticket->Id};
+    delete $ARGS{$Ticket->Id.'-MemberOf'};
+    delete $ARGS{'MemberOf-'.$Ticket->Id};
+    delete $ARGS{$Ticket->Id.'-RefersTo'};
+    delete $ARGS{'RefersTo-'.$Ticket->Id};
+    
+    my @updateresults; 
+    if ($do_comment_reply) {
+    ProcessUpdateMessage(TicketObj => $Ticket, ARGSRef => \%ARGS, Actions => \@updateresults); 
+   } 
+   my @tempresults = (@watchresults, @basicresults, @dateresults, @updateresults, @linkresults);
+    @tempresults = map { loc("Ticket [_1]: [_2]",$Ticket->Id,$_) } @tempresults;
+
+    @results = (@results, @tempresults);
+}
+
+</%INIT>
diff --git a/rt/html/Search/Elements/PickRestriction b/rt/html/Search/Elements/PickRestriction
new file mode 100644 (file)
index 0000000..a6911df
--- /dev/null
@@ -0,0 +1,141 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<FORM ACTION="Listing.html" METHOD="GET">
+<INPUT TYPE=HIDDEN NAME="Bookmark" VALUE="<% $session{'tickets'}->FreezeLimits()|u %>">
+<& /Elements/TitleBoxStart, title => loc('Refine search')&>
+<INPUT TYPE=HIDDEN NAME="CompileRestriction" VALUE=1>
+
+<ul>
+<li><&|/l&>Owner is</&>  <& /Elements/SelectBoolean, Name => "OwnerOp", 
+                                         TrueVal=> '=', 
+                                         FalseVal => '!=' 
+&> 
+<& /Elements/SelectOwner, Name => "ValueOfOwner" &>
+
+<li>
+<&|/l&>Requestor email address</&> 
+<& /Elements/SelectMatch, Name => "RequestorOp" &>
+<INPUT Name="ValueOfRequestor" SIZE=20>
+
+<li>
+<&|/l&>Subject</&> <& /Elements/SelectMatch, Name => "SubjectOp" &> 
+<INPUT Name="ValueOfSubject" SIZE=20>
+
+<li><&|/l&>Queue</&>  <& /Elements/SelectBoolean,  Name => "QueueOp" , 
+                                       True => loc("is"), 
+                                       False => loc("isn't"), 
+                                       TrueVal=> '=', 
+                                       FalseVal => '!=' &>
+<& /Elements/SelectQueue, Name => loc("ValueOfQueue") &>
+
+
+<li><&|/l&>Priority</&> <& /Elements/SelectEqualityOperator, Name => "PriorityOp" &>
+
+<INPUT Name="ValueOfPriority" SIZE=5>
+
+<li>
+<& /Elements/SelectDateType, Name => 'DateType' &>
+<& /Elements/SelectDateRelation, Name=>"DateOp" &>
+<& /Elements/SelectDate, Name => "ValueOfDate", ShowTime => 0, Default => '' &>
+
+<li><&|/l&>Ticket attachment</&> 
+
+<& /Elements/SelectAttachmentField, Name => 'AttachmentField' &>
+<& /Elements/SelectBoolean, Name => "AttachmentFieldOp", 
+                           True => loc("matches"), 
+                           False => loc("does not match"), 
+                           TrueVal => 'LIKE', 
+                           FalseVal => 'NOT LIKE' 
+&> 
+<Input Name="ValueOfAttachmentField" Size=20>
+
+<li><&|/l&>Status</&> 
+<& /Elements/SelectBoolean, Name => "StatusOp", 
+                           True => loc("is"), 
+                           False => loc("isn't"), 
+                           TrueVal=> '=', 
+                           FalseVal => '!=' 
+&>  
+<& /Elements/SelectStatus, Name => "ValueOfStatus" &>
+
+
+% while ( my $CustomField = $CustomFields->Next ) {
+
+<li><% $CustomField->Name %> 
+        <& /Elements/SelectCustomFieldOperator, Name => "CustomFieldOp". $CustomField->id, 
+                                    True => loc("is"), 
+                                    False => loc("isn't"), 
+                                    TrueVal=> '=', FalseVal => '!=' &>
+
+<& /Elements/SelectCustomFieldValue, Name => "CustomField".$CustomField->id,
+                            CustomField => $CustomField,
+                            &>
+% }
+
+</UL>
+
+<& /Elements/TitleBoxEnd &>
+
+<& /Elements/TitleBoxStart, title => loc('Ordering and sorting')&>
+
+<UL>
+
+<li><&|/l&>Results per page</&> <& /Elements/SelectResultsPerPage, Name => "RowsPerPage", 
+                                                       Default => $session{'tickets_rows_per_page'} || '50'
+&>
+
+<li><&|/l&>Sort results by</&> <& /Elements/SelectTicketSortBy, Name => "TicketsSortBy", 
+                                                    Default => $session{'tickets_sort_by'} 
+&> 
+<& /Elements/SelectSortOrder, Name => 'TicketsSortOrder', Default => $session{'tickets_sort_order'} &>
+
+<li><input type="checkbox" name="HideResults" <%$ARGS{'HideResults'} && 'CHECKED'%>> <&|/l&>Don't show search results</&>
+<li><& /Elements/Refresh, Name => 'RefreshSearchInterval' , Default => $session{'tickets_refresh_interval'} &>
+
+</UL>
+
+
+</DIV>
+
+
+
+<& /Elements/TitleBoxEnd &>
+
+<& /Elements/Submit, Label => loc('Search'), Name => 'Action'&>
+
+</FORM>
+
+
+ <%INIT>
+my $CustomFields = RT::CustomFields->new( $session{'CurrentUser'});
+ foreach ( $session{'tickets'}->RestrictionValues('Queue') ) {
+        # Gotta load up the $queue object, since queues get stored by name now.
+        my $queue = RT::Queue->new($session{'CurrentUser'});
+        $queue->Load($_);
+        $CustomFields->LimitToQueue($queue->Id);
+ }
+
+ $CustomFields->LimitToGlobal();
+
+</%INIT>
diff --git a/rt/html/Search/Elements/TicketHeader b/rt/html/Search/Elements/TicketHeader
new file mode 100644 (file)
index 0000000..ed2f60e
--- /dev/null
@@ -0,0 +1,40 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TR>
+<& TicketHeaderCell , Attribute => 'id', Header => '#'&>
+<& TicketHeaderCell , Attribute => 'Subject'&>
+<& TicketHeaderCell , Attribute => 'Status'&>
+<& TicketHeaderCell , Attribute => 'Queue'&>
+<& TicketHeaderCell , Attribute => 'Owner'&>
+<& TicketHeaderCell , Attribute => 'Priority'&>
+</TR>
+<TR>
+<TH class="ticketheader">&nbsp;</TH>
+<& TicketHeaderCell , Attribute => 'Requestor(s)'&>
+<& TicketHeaderCell , Attribute => 'Created'&>
+<& TicketHeaderCell , Attribute => 'Told', Header => 'Last Contact'&>
+<& TicketHeaderCell , Attribute => 'LastUpdated', Header => 'Last Updated'&>
+<& TicketHeaderCell , Attribute => 'TimeLeft', Header => 'Left'&>
+</TR>
+%# loc('Last Notified');
diff --git a/rt/html/Search/Elements/TicketHeaderCell b/rt/html/Search/Elements/TicketHeaderCell
new file mode 100644 (file)
index 0000000..5def9ea
--- /dev/null
@@ -0,0 +1,55 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<%INIT> 
+my ($order,$curorder);
+ $Attribute =~ s/Obj->(Name|AsString|AgeAsString)//g;
+  if ($session{'tickets_sort_order'} =~ /^asc$/i) {
+   $order = 'DESC';
+   $curorder = 'ASC';
+ } else {
+   $order = 'ASC';
+   $curorder = 'DESC';
+ }
+$Header = $Attribute unless ($Header);
+
+</%INIT>
+<th class="ticketheader">
+% if (grep (/^$Attribute$/i, $session{'tickets'}->SortFields)) {
+<A 
+% if ($Attribute eq $session{'tickets_sort_by'}) {
+class="currenttab"
+HREF="<% $RT::WebPath%>/Search/Listing.html?Bookmark=<%$session{'tickets'}->FreezeLimits()|u%>&TicketsSortBy=<%$Attribute%>&TicketsSortOrder=<%$order%>&RowsPerPage=<%$session{'tickets_rows_per_page'}%>">
+% } else {
+HREF="<% $RT::WebPath%>/Search/Listing.html?Bookmark=<%$session{'tickets'}->FreezeLimits()|u%>&TicketsSortBy=<%$Attribute%>&TicketsSortOrder=<%$curorder%>&RowsPerPage=<%$session{'tickets_rows_per_page'}%>">
+% }
+<% loc($Header) %>
+</A>
+% } else {
+<% loc($Header) %>
+% }
+</th>
+<%ARGS>
+$Header => undef
+$Attribute => undef 
+</%ARGS>
diff --git a/rt/html/Search/Elements/TicketRow b/rt/html/Search/Elements/TicketRow
new file mode 100644 (file)
index 0000000..5d1ad20
--- /dev/null
@@ -0,0 +1,55 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SPAN class="search">
+<TR
+% if ($i%2) {
+CLASS="oddline"
+% } else {
+CLASS="evenline"
+% }
+>
+<TD ROWSPAN="2"><B><A HREF="<%$RT::WebPath%>/Ticket/Display.html?id=<%$Ticket->Id%>"><%$Ticket->id%></a></B></TD>
+<TD><B><A HREF="<%$RT::WebPath%>/Ticket/Display.html?id=<%$Ticket->Id%>"><%$Ticket->Subject%></a></B></TD>
+<TD><%loc($Ticket->Status)%></TD>
+<TD><%$Ticket->QueueObj->Name%></TD>
+<TD><%$Ticket->Owner == $RT::Nobody->Id ? loc('Nobody') : $Ticket->OwnerObj->Name%></TD>
+<TD><%$Ticket->Priority%></TD>
+</TR>
+<TR
+% if ($i%2) {
+CLASS="oddline"
+% } else {
+CLASS="evenline"
+% }
+><TD><small><%$Ticket->Requestors->MemberEmailAddressesAsString%></small></TD>
+<TD><SMALL><%$Ticket->CreatedObj->AgeAsString || '-'%></SMALL></TD>
+<TD><SMALL><%$Ticket->ToldObj->AgeAsString || '-'%></SMALL></TD>
+<TD><SMALL><%$Ticket->LastUpdatedObj->AgeAsString || '-'%></SMALL></TD>
+<TD><SMALL><%$Ticket->TimeLeft%></SMALL></TD>
+</TR>
+</SPAN>
+<%ARGS>
+$Ticket => undef
+$i => undef
+</%ARGS>
diff --git a/rt/html/Search/Listing.html b/rt/html/Search/Listing.html
new file mode 100644 (file)
index 0000000..5085345
--- /dev/null
@@ -0,0 +1,112 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => $title, Refresh => $session{'tickets_refresh_interval'} &>
+<& /Ticket/Elements/Tabs, 
+    current_tab => 'Search/Listing.html', 
+    Title => $title &>
+
+%if ($ticketcount && !  $ARGS{'HideResults'}) {
+<TABLE WIDTH=100% border=0 cellpadding=2 CELLSPACING=0>
+<& Elements/TicketHeader, %ARGS &>
+% my $i;
+%while (my $Ticket = $session{'tickets'}->Next) {
+% $i++;
+<& Elements/TicketRow, Ticket => $Ticket, i=> $i, %ARGS &>
+%}
+</TABLE>
+<div align=center>
+<font size=2>
+<a href="Listing.html?GotoPage=1"><&|/l&>First page</&></a>
+&nbsp;&nbsp;
+%  if ( $session{'tickets'}->FirstRow >= $session{'tickets_rows_per_page'}-1 ) {
+<a href="Listing.html?GotoPage=Prev">&lt;<&|/l&>Previous page</&></a>
+&nbsp;&nbsp;
+%  }                                                                           
+%  if ( $session{'tickets'}->FirstRow + $session{'tickets_rows_per_page'} < $ticketcount ) {                                                               
+<a href="Listing.html?GotoPage=Next"><&|/l&>Next page</&>&gt;</a>
+%  }
+%#&nbsp;&nbsp;<form method=get action="Listing.html"><&|/l&>Goto page</&> <input name=GotoPage size=2></form>
+</font>
+</div>
+<!--<div align=right>-->
+<table width="100%" border=0 cellpadding=3 CELLSPACING=1>
+<tr>
+<td align=left>
+(<&|/l, ($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ) &>[_1] - [_2] shown</&>)
+</td>
+<td align=right>
+
+<a href="Bulk.html"><&|/l&>Update all these tickets at once</&></a>
+<!--</div>-->
+</td>
+</tr>
+</table>
+
+% }
+<TABLE WIDTH="100%">
+<TR>
+<TD VALIGN="TOP">
+<& /Elements/TitleBoxStart, title => loc('Current search criteria')&>
+
+%my %restrictions=$session{'tickets'}->DescribeRestrictions();
+%foreach my $row (keys %restrictions){
+<%$restrictions{"$row"}%> <A HREF="<% $RT::WebPath %>/Search/Listing.html?DeleteRestriction=<%$row%>">[<&|/l&>delete</&>]</a><br>
+%}
+<BR>
+<BR>
+<A HREF="<% $RT::WebPath%>/Search/Listing.html?Bookmark=<%$session{'tickets'}->FreezeLimits()|u%>&TicketsSortBy=<%$session{'tickets_sort_by'}%>&TicketsSortOrder=<%$session{'tickets_sort_order'}%>&RowsPerPage=<%$session{'tickets_rows_per_page'}%>"><&|/l&>Bookmarkable URL for this search</&></a>
+<& /Elements/TitleBoxEnd&>
+</TD>
+<TD>
+
+<& Elements/PickRestriction, %ARGS &>
+
+</TD>
+</TR>
+</TABLE>
+
+<%INIT>
+
+my ($title, $ticketcount);
+$session{'i'}++;
+if ($session{'tickets'}) {
+    if ($ARGS{'DeleteRestriction'}) {
+           $session{'tickets'}->DeleteRestriction($ARGS{'DeleteRestriction'});
+    }
+    if ( ($ARGS{'ClearRestrictions'}) || ($ARGS{'NewSearch'}) ) {
+           $session{'tickets'}->ClearRestrictions;
+       }       
+}
+   ProcessSearchQuery(ARGS=>\%ARGS);
+   $session{'tickets'}->RedoSearch();
+   if ( $session{'tickets'}->DescribeRestrictions()) {
+       $ticketcount = $session{tickets}->CountAll();
+        $title = loc('Found [quant,_1,ticket]', $ticketcount);
+    } else {
+        $title = loc("Find tickets");
+   }
+</%INIT>
+<%CLEANUP>
+$session{'tickets'}->PrepForSerialization();
+</%CLEANUP>
diff --git a/rt/html/SelfService/Attachment/dhandler b/rt/html/SelfService/Attachment/dhandler
new file mode 100644 (file)
index 0000000..4bebbe5
--- /dev/null
@@ -0,0 +1,27 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<%init>
+$m->comp('/Ticket/Attachment/dhandler', %ARGS);
+$m->abort;
+</%init>
diff --git a/rt/html/SelfService/Closed.html b/rt/html/SelfService/Closed.html
new file mode 100644 (file)
index 0000000..b9b2ac6
--- /dev/null
@@ -0,0 +1,27 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /SelfService/Elements/Header, Title => loc('Closed Tickets') &>
+
+<& /SelfService/Elements/MyRequests, status => ['rejected', 'resolved'], friendly_status =>
+loc('closed') &>
diff --git a/rt/html/SelfService/Create.html b/rt/html/SelfService/Create.html
new file mode 100644 (file)
index 0000000..7bbc88a
--- /dev/null
@@ -0,0 +1,80 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& Elements/Header, Title => loc("Create a ticket") &>
+
+<FORM ACTION="Display.html" METHOD="POST" ENCTYPE="multipart/form-data">
+<INPUT TYPE=HIDDEN Name="id" VALUE="new">
+
+<TABLE>
+<TR>
+<TD>
+<&|/l&>Queue</&>:
+</TD>
+<TD>
+<& /Elements/SelectNewTicketQueue, Verbose => 'True' &>
+</TD>
+</TR>
+<TR>
+<TD>
+<&|/l&>Requestors</&>:
+</TD>
+<TD>
+<INPUT Name="Requestors" Value="<%$session{CurrentUser}->EmailAddress%>" SIZE=20>
+</TD>
+</TR>
+<TR>
+<TD>
+<&|/l&>Cc</&>:
+</TD>
+<TD>
+ <INPUT NAME="Cc" SIZE=20>
+</TD>
+</TR>
+<TR>
+<TD>
+<&|/l&>Subject</&>:
+</TD>
+<TD>
+<INPUT Name="Subject" SIZE=60 MAXSIZE=100 value="">
+</TD>
+</TR>
+<TR>
+<TD>
+<&|/l&>Attach file</&>:
+</TD>
+<TD>
+<INPUT Name="Attach" type=file>
+</TD>
+</TR>
+<TR>
+<TD COLSPAN=2>
+<&|/l&>Describe the issue below</&>:<br>
+<& /Elements/MessageBox &>
+</TD>
+</TR>
+</TABLE>
+<& /Elements/Submit, Label => loc("Create ticket")&>
+
+
+</FORM>
diff --git a/rt/html/SelfService/Display.html b/rt/html/SelfService/Display.html
new file mode 100644 (file)
index 0000000..fc3fcb2
--- /dev/null
@@ -0,0 +1,141 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /SelfService/Elements/Header, Title => loc('#[_1]: [_2]', $Ticket->id, $Ticket->Subject) &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+  <TABLE WIDTH="100%" class="ticketsummary" >
+      <TR>
+        <TD VALIGN=TOP WIDTH="50%">
+          <& /Elements/TitleBoxStart, title => loc('The Basics'), 
+                title_class=> 'inverse',  
+                color => "#993333" &>
+                <& /Ticket/Elements/ShowBasics, Ticket => $Ticket &>
+          <& /Elements/TitleBoxEnd &>
+</TD>
+        <TD VALIGN=TOP WIDTH="50%">
+          <& /Elements/TitleBoxStart, title => loc("Dates"),
+                title_class=> 'inverse',
+                 color => "#663366" &>
+          <& /Ticket/Elements/ShowDates, Ticket => $Ticket &>
+          <& /Elements/TitleBoxEnd &>
+</TD>
+</TR>
+</TABLE>
+
+
+
+<& /Ticket/Elements/ShowHistory, Ticket => $Ticket&>
+
+
+
+<%INIT>
+
+my ( $field, @results );
+
+# {{{ Load the ticket
+#If we get handed two ids, mason will make them an array. bleck.
+# We want teh first one. Just because there's no other sensible way
+# to deal
+my @id = ( ref $id eq 'ARRAY' ) ? @{$id} : ($id);
+
+my $Ticket = new RT::Ticket( $session{'CurrentUser'} );
+if ( $id[0] eq 'new' ) {
+
+    # {{{ Create a new ticket
+
+    my $Queue = new RT::Queue( $session{'CurrentUser'} );
+    unless ( $Queue->Load( $ARGS{'Queue'} ) ) {
+        $m->comp( 'Error.html', Why => loc('Queue not found') );
+        $m->abort;
+    }
+
+    unless ( $Queue->CurrentUserHasRight('CreateTicket') ) {
+        $m->comp( 'Error.html',
+             Why =>
+               loc('You have no permission to create tickets in that queue.') );
+        $m->abort;
+    }
+
+    my @Requestors = split ( /\s*,\s*/, $ARGS{'Requestors'} );
+    my @Cc         = split ( /\s*,\s*/, $ARGS{'Cc'} );
+
+    my $MIMEObj = MakeMIMEEntity( Subject             => $ARGS{'Subject'},
+                                  From                => $ARGS{'From'},
+                                  Cc                  => $ARGS{'Cc'},
+                                  Body                => $ARGS{'Content'},
+                                  AttachmentFieldName => 'Attach' );
+
+    #TODO in Create_Details.html: priorities and due-date
+    my ( $id, $Trans, $ErrMsg ) = $Ticket->Create( Queue     => $ARGS{Queue},
+                                                   Requestor => \@Requestors,
+                                                   Cc        => \@Cc,
+                                                   Subject   => $ARGS{Subject},
+                                                   MIMEObj   => $MIMEObj );
+    unless ( $id && $Trans ) {
+        $m->comp( 'Error.html', Why => $ErrMsg );
+        $m->abort();
+    }
+
+    push ( @results, $ErrMsg );
+
+    # }}}
+}
+else {
+    unless ( $Ticket->Load( $id[0] ) ) {
+        $m->comp( 'Error.html',
+                  Why => loc( "Couldn't load ticket '[_1]'", $id ) );
+        $m->abort();
+    }
+}
+
+# }}}
+
+unless ( $Ticket->CurrentUserHasRight('ShowTicket') ) {
+    $m->comp( 'Error.html',
+              Why => loc("No permission to display that ticket") );
+    $m->abort();
+}
+
+my ( $code, $msg );
+
+#Update the status
+if (     ( defined $ARGS{'Status'} )
+     and ( $ARGS{'Status'} ne $Ticket->Status ) ) {
+    ( $code, $msg ) = $Ticket->SetStatus( $ARGS{'Status'} );
+    push @results, "$msg";
+}
+
+ProcessUpdateMessage( ARGSRef   => \%ARGS,
+                      Actions   => \@results,
+                      TicketObj => $Ticket );
+
+my $Transactions = $Ticket->Transactions;
+
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/SelfService/Elements/GotoTicket b/rt/html/SelfService/Elements/GotoTicket
new file mode 100644 (file)
index 0000000..71da8c1
--- /dev/null
@@ -0,0 +1,24 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<FORM ACTION="<%$RT::WebPath%>/SelfService/Display.html"><input type=submit value="<&|/l&>Goto ticket</&>">&nbsp;<input size=4 name=id></FORM>
diff --git a/rt/html/SelfService/Elements/Header b/rt/html/SelfService/Elements/Header
new file mode 100644 (file)
index 0000000..6ad1379
--- /dev/null
@@ -0,0 +1,25 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, %ARGS, Prefs => '/SelfService/Prefs.html' &>
+<& /SelfService/Elements/Tabs, %ARGS &>
diff --git a/rt/html/SelfService/Elements/MyRequests b/rt/html/SelfService/Elements/MyRequests
new file mode 100644 (file)
index 0000000..95ede08
--- /dev/null
@@ -0,0 +1,62 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/TitleBoxStart, title =>  $title &>
+<TABLE BORDER=0 cellspacing=1 cellpadding=1 BGCOLOR="#eeeeee" WIDTH=100%>
+<TR>
+<TH><&|/l&>Subject</&></TH>
+<TH><&|/l&>Status</&></TH>
+<TH><&|/l&>Owner</&></TH>
+</TR>
+<TR>
+% while (my $Ticket = $MyTickets->Next) {
+<TR>
+<TD>
+<a href="<%$RT::WebPath%>/SelfService/Display.html?id=<%$Ticket->Id%>"><%$Ticket->Id%>: <%$Ticket->Subject%></a>
+</TD>
+<TD>
+<%$Ticket->Status%>
+</TD><TD>
+<%$Ticket->OwnerObj->Name%>
+</TR>
+% }
+</TABLE>
+<& /Elements/TitleBoxEnd &>
+
+
+<%INIT>
+$title ||= loc("My [_1] tickets", $friendly_status);
+my $MyTickets;
+$MyTickets = new RT::Tickets ($session{'CurrentUser'});
+$MyTickets->LimitWatcher(TYPE => 'Requestor', VALUE => $session{'CurrentUser'}->EmailAddress);
+
+foreach my $status (@status) {
+
+        $MyTickets->LimitStatus(VALUE => $status);
+}
+</%INIT>
+<%ARGS>
+$title => undef
+$friendly_status => loc('open')
+@status => ('open', 'new', 'stalled')
+</%ARGS>
diff --git a/rt/html/SelfService/Elements/Tabs b/rt/html/SelfService/Elements/Tabs
new file mode 100644 (file)
index 0000000..efab866
--- /dev/null
@@ -0,0 +1,64 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/PageLayout,
+    current_toptab => $current_toptab,
+    current_tab => $current_tab,
+    toptabs => $tabs,
+    topactions => $actions,
+    title => $Title
+&>
+<a name="skipnav" id="skipnav" accesskey="8"></a>
+<%INIT>
+
+if ($Title) {
+$Title = loc ("RT Self Service") . " / " . $Title;
+} else {
+$Title = loc ("RT Self Service");
+
+}
+my ($tab);
+my $tabs = { A  => { title => loc('Open tickets'),
+                        path => 'SelfService/',
+                      },
+             B => { title => loc('Closed tickets'),
+                         path => 'SelfService/Closed.html',
+                       },
+             C => { title => loc('New ticket'),
+                    path => 'SelfService/Create.html'
+                    },
+             Z => { title => loc('Preferences'),
+                    path => 'SelfService/Prefs.html'
+                    }
+           };
+my $actions = {
+       B => { html => $m->scomp('GotoTicket') 
+               }
+       };
+</%INIT>
+<%ARGS>
+$Title => undef
+$current_toptab => undef
+$current_tab => undef
+</%ARGS>
+
diff --git a/rt/html/SelfService/Error.html b/rt/html/SelfService/Error.html
new file mode 100644 (file)
index 0000000..ac93ace
--- /dev/null
@@ -0,0 +1,46 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /SelfService/Elements/Header, Title => loc('Error') &>
+<h2 class="title"><%loc('Error')%></h2>
+<& /Elements/TitleBoxStart, title => $Title &>
+<%$Why%>
+<br>
+<font size=-1>
+<%$Details%>
+</font>
+<& /Elements/TitleBoxEnd &>
+</body>
+</HTML>
+
+
+<%args>
+$Code => undef
+$Details => undef
+$Title => loc("RT Error")
+$Why => loc("the calling component did not specify why")
+</%args>
+
+<%INIT>
+$RT::Logger->error("WebRT: $Why ($Details)");
+</%INIT>
diff --git a/rt/html/SelfService/Prefs.html b/rt/html/SelfService/Prefs.html
new file mode 100644 (file)
index 0000000..3bbb9b9
--- /dev/null
@@ -0,0 +1,68 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /SelfService/Elements/Header, Title => loc('Preferences') &>
+
+<& /Elements/ListActions, actions => \@results &>
+<form method=post>
+
+% unless ($RT::WebExternalAuth and !$RT::WebFallbackToInternalAuth) {
+<& /Elements/TitleBoxStart, title => loc('Change password')  &>
+<&|/l&>New password</&>: <input type=password name="NewPass1" size=16>
+<&|/l&>Confirm</&>: <input type=password name="NewPass2" size=16>
+<& /Elements/TitleBoxEnd &>
+<BR>
+% }
+<& /Elements/Submit &>
+         </form>
+
+
+<%INIT>
+my @results;
+
+if ($NewPass1) {
+    if ($NewPass1 ne $NewPass2) {
+       push (@results, "Passwords did not match.");
+    }  
+    else {
+       my ($val, $msg)=$session{'CurrentUser'}->UserObj->SetPassword($NewPass1);
+       push (@results, "Password: ".$msg);
+    }  
+}
+if ($Signature) {
+    $Signature =~ s/(\r\n|\r)/\n/g;
+    if ($Signature ne $session{'CurrentUser'}->UserObj->Signature) {
+       my ($val, $msg)=$session{'CurrentUser'}->UserObj->SetSignature($Signature);
+       push (@results, "Signature: ".$msg);
+    }
+}
+#A hack to make sure that session gets rewritten.
+
+$session{'i'}++;
+</%INIT>
+
+<%ARGS>
+$Signature => undef
+$NewPass1 => undef
+$NewPass2 => undef
+</%ARGS>
diff --git a/rt/html/SelfService/Update.html b/rt/html/SelfService/Update.html
new file mode 100644 (file)
index 0000000..9ff3177
--- /dev/null
@@ -0,0 +1,61 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /SelfService/Elements/Header, Title =>loc('Update ticket #[_1]', $Ticket->id) &>
+
+
+<FORM ACTION="Display.html" METHOD=POST ENCTYPE="multipart/form-data">
+<input type=hidden name="UpdateType" value="response">
+
+<&|/l&>Status</&>: <& /Elements/SelectStatus, Name=>"Status", Default => $DefaultStatus &><br>
+<&|/l&>Subject</&>: <input name="UpdateSubject" size=60 value="Re: <% $Ticket->Subject %>"> <br>
+<&|/l&>Attach</&>: <input name="UpdateAttachment" type=file><br>
+<& /Elements/MessageBox, Name=>"UpdateContent", QuoteTransaction=>$ARGS{QuoteTransaction} &>
+               <INPUT TYPE=HIDDEN NAME=id VALUE="<%$Ticket->Id%>"><br>
+
+
+<& /Elements/Submit &>
+  </FORM>
+
+
+
+<%INIT>
+
+my $Ticket = LoadTicket($id);
+
+my $title = loc("Update ticket #[_1]", $Ticket->id);
+
+$DefaultStatus = $Ticket->Status() unless ($DefaultStatus);
+
+
+Abort(loc("No permission to view update ticket")) 
+       unless ( $Ticket->CurrentUserHasRight('ReplyToTicket') or
+                     $Ticket->CurrentUserHasRight('ModifyTicket') ); 
+
+</%INIT>
+
+<%ARGS>
+$id => undef
+$Action => undef
+$DefaultStatus => undef
+</%ARGS>
diff --git a/rt/html/SelfService/index.html b/rt/html/SelfService/index.html
new file mode 100644 (file)
index 0000000..71dc115
--- /dev/null
@@ -0,0 +1,26 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /SelfService/Elements/Header, Title => undef &>
+
+<& /SelfService/Elements/MyRequests &>
diff --git a/rt/html/Ticket/Attachment/dhandler b/rt/html/Ticket/Attachment/dhandler
new file mode 100644 (file)
index 0000000..e0f00f5
--- /dev/null
@@ -0,0 +1,68 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<%perl>
+     my ($ticket, $trans,$attach, $filename);
+     my $arg = $m->dhandler_arg;                # get rest of path
+     if ($arg =~ '^(\d+)/(\d+)') {
+        $trans = $1;
+        $attach = $2;
+     }
+    else {
+        Abort("Corrupted attachment URL.");
+        }
+     my $AttachmentObj = new RT::Attachment($session{'CurrentUser'});
+     $AttachmentObj->Load($attach) || Abort("Attachment '$attach' could not be loaded");
+
+
+     unless ($AttachmentObj->id) {
+        Abort("Bad attachment id. Couldn't find attachment '$attach'\n");
+    }
+     unless ($AttachmentObj->TransactionId() == $trans ) {
+        Abort("Bad transaction number for attachment. $trans should be".$AttachmentObj->TransactionId() ."\n");
+
+     }
+
+     my $content_type = $AttachmentObj->ContentType || 'text/plain';
+        
+     unless ($RT::TrustHTMLAttachments) {
+         $content_type = 'text/plain' if ($content_type =~ /^text\/html/i);
+     }
+
+     if (my $enc = $AttachmentObj->OriginalEncoding) {
+       # normalize Encode.pm convention with IANA ones
+        $enc = 'big5'  if $enc eq 'big5-eten';
+        $enc = 'utf-8' if $enc eq 'utf8';
+       $content_type .= ";charset=$enc";
+     }
+
+     # unless ($RT::TrustMIMEAttachments) {
+     #     $content_type = 'application/octet-stream';
+     # }
+
+     $r->content_type( $content_type );
+     $m->clear_buffer();
+     $m->out($AttachmentObj->OriginalContent);
+     $m->abort; 
+</%perl>
+
diff --git a/rt/html/Ticket/Create.html b/rt/html/Ticket/Create.html
new file mode 100644 (file)
index 0000000..5b8c908
--- /dev/null
@@ -0,0 +1,257 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc("Create a new ticket") &>
+<& /Elements/Tabs, 
+    current_toptab => "Ticket/Create.html", 
+    Title => loc("Create a new ticket") &>
+<FORM ACTION="<%$RT::WebPath%>/Ticket/Create.html" METHOD="POST" ENCTYPE="multipart/form-data">
+<INPUT TYPE=HIDDEN Name="id" VALUE="new">
+<A NAME="top">
+       
+       
+[<a class="currenttab"><&|/l&>Show basics</&></a>] [<A HREF="#detail"><&|/l&>Show details</&></a>]
+<BR>
+<& /Elements/TitleBoxStart, contentbg => "#cccccc", title => loc("Create a new ticket") &>
+<TABLE border=0 cellpadding=0 cellspacing=0>
+<TR><TD><&|/l&>Queue</&></TD>
+<TD><% $QueueObj->Name %>
+<INPUT TYPE=HIDDEN NAME=Queue Value="<%$QueueObj->Name%>">
+</TD>
+<TD><&|/l&>Status</&>:
+</TD>
+<TD>
+<& /Elements/SelectStatus, Name => "Status", Default => $ARGS{Status}||'new' &>
+</TD>
+<TD>
+<&|/l&>Owner</&>:
+</TD>
+<TD>
+<& /Elements/SelectOwner, Name => "Owner", QueueObj => $QueueObj, Default => $ARGS{Owner}||undef &>
+</TD>
+</TR>
+<TR>
+<TD>
+<&|/l&>Requestors</&>:
+</TD>
+<TD COLSPAN=5>
+<INPUT Name="Requestors" Value="<% ($ARGS{Requestors}) || $session{CurrentUser}->EmailAddress %>" SIZE=40>
+</TD>
+</TR>
+<TR>
+<TD>
+<&|/l&>Cc</&>:
+</TD>
+<TD COLSPAN=5>
+<INPUT NAME="Cc" SIZE=40<% $ARGS{Cc} && " VALUE=\"$ARGS{Cc}\""%>><BR>
+<i><font size=-2>
+<&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)</&></font></i>
+</TD>
+</TR>
+<TR>
+<TD>
+<&|/l&>Admin Cc</&>:
+</TD>
+<TD COLSPAN=5>
+<INPUT NAME="AdminCc" SIZE=40<% $ARGS{AdminCc} && " VALUE=\"$ARGS{AdminCc}\""%>><BR>
+<i><font size=-2>
+<&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)</&></font></i>
+</TD>
+</TR>
+<TR>
+<TD>
+<&|/l&>Subject</&>:
+</TD>
+<TD COLSPAN=5>
+<INPUT Name="Subject" SIZE=60 MAXSIZE=100 value="<%$ARGS{Subject} || ''%>">
+</TD>
+</TR>
+<TR>
+<TD COLSPAN=6>
+<& /Ticket/Elements/EditCustomFields, QueueObj => $QueueObj &>
+</TD>
+</TR>
+<TR>
+% if (exists $session{'Attachments'}) {
+<TD>
+<&|/l&>Attached file</&>:
+</TD>
+<TD COLSPAN=5>
+<&|/l&>Check box to delete</&><BR>
+% foreach my $attach_name (keys %{$session{'Attachments'}}) {
+<input type="checkbox" name="DeleteAttach-<%$attach_name%>"><%$attach_name%><BR>
+% } # end of foreach
+</TD>
+</TR>
+<TR>
+% } # end of if
+<TD>
+<&|/l&>Attach file</&>:
+</TD>
+<TD COLSPAN=5>
+<INPUT TYPE=FILE NAME="Attach">
+<INPUT TYPE=SUBMIT NAME="AddMoreAttach" VALUE="<&|/l&>Add More Files</&>">
+</TD>
+</TR>
+<TR>
+<TD COLSPAN=6>
+<&|/l&>Describe the issue below</&>:<br>
+% if (exists $ARGS{Content}) {
+<& /Elements/MessageBox, Default => $ARGS{Content} &>
+% } else {
+<& /Elements/MessageBox, QuoteTransaction => $QuoteTransaction &>
+%}
+
+<BR>
+</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT COLSPAN=2>
+</TD>
+</TR>
+</TABLE>
+<& /Elements/TitleBoxEnd &>
+<& /Elements/Submit, Label => loc("Create")&>
+
+<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
+<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
+<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
+<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
+<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
+
+<A NAME="detail">
+       [<A HREF="#top"><&|/l&>Show basics</&></a>] [<a class="currenttab"><&|/l&>Show details</&></a>]
+<BR>
+<TABLE WIDTH="100%" BORDER=0>
+<TR>
+<TD WIDTH="50%" VALIGN=TOP>
+
+         <& /Elements/TitleBoxStart, title => loc('The Basics'), 
+               title_class=> 'inverse',  
+               color => "#993333" &>
+<TABLE BORDER=0>
+<TR><TD ALIGN=RIGHT><&|/l&>Priority</&>:</TD><TD><input size=3 name="InitialPriority" value="<% $ARGS{InitialPriority} ? $ARGS{InitialPriority} : $QueueObj->InitialPriority %>"></TD></TR>
+<TR><TD ALIGN=RIGHT><&|/l&>Final Priority</&>:</TD><TD><input size=3 name="FinalPriority" value="<% $ARGS{FinalPriority} ? $ARGS{FinalPriority} : $QueueObj->FinalPriority %>"></TD></TR>
+<TR><TD ALIGN=RIGHT><&|/l&>Time Worked</&>:</TD><TD><input size=3 name="TimeWorked"<% $ARGS{TimeWorked} && " VALUE=\"$ARGS{TimeWorked}\""  %>></TD></TR>
+<TR><TD ALIGN=RIGHT><&|/l&>Time Left</&>:</TD><TD><input size=3 name="TimeLeft"<% $ARGS{TimeLeft} && " VALUE=\"$ARGS{TimeLeft}\"" %>></TD></TR>
+</TABLE>
+<& /Elements/TitleBoxEnd &>
+<br>
+<& /Elements/TitleBoxStart, title => loc("Dates"),
+               title_class=> 'inverse',  
+                color => "#663366" &>
+
+<TABLE BORDER=0>
+<TR><TD ALIGN=RIGHT><&|/l&>Starts</&>:</TD><TD><input size=10 name="Starts"<% $ARGS{Starts} && " VALUE=\"$ARGS{Starts}\"" %>></TD></TR>
+<TR><TD ALIGN=RIGHT><&|/l&>Due</&>:</TD><TD><input size=10 name="Due"<% $ARGS{Due} && " VALUE=\"$ARGS{Due}\"" %>></TD></TR>
+</TABLE>
+<& /Elements/TitleBoxEnd &>
+<BR>
+</TD>
+
+<TD VALIGN="TOP">
+<& /Elements/TitleBoxStart, title => loc('Relationships'), 
+       title_class=> 'inverse',  
+       titleright => '', color=> "#336633" &>
+
+<i><&|/l&>(Enter ticket ids or URLs, seperated with spaces)</&></i>
+<TABLE BORDER=0>
+<TR><TD ALIGN=RIGHT><&|/l&>Depends on</&></TD><TD><input size=10 name="new-DependsOn"<% $ARGS{'new-DependsOn'} && " VALUE=\"$ARGS{'new-DependsOn'}\""%>></TD></TR>
+<TR><TD ALIGN=RIGHT><&|/l&>Depended on by</&></TD><TD><input size=10 name="DependsOn-new"<% $ARGS{'DependsOn-new'} && " VALUE=\"$ARGS{'DependsOn-new'}\"" %>></TD></TR>
+<TR><TD ALIGN=RIGHT><&|/l&>Parents</&></TD><TD><input size=10 name="new-MemberOf"<% $ARGS{'new-MemberOf'} && " VALUE=\"$ARGS{'new-MemberOf'}\"" %>></TD></TR>
+<TR><TD ALIGN=RIGHT><&|/l&>Children</&></TD><TD><input size=10 name="MemberOf-new" <% $ARGS{'MemberOf-new'} && " VALUE=\"$ARGS{'MemberOf-new'}\"" %>></TD></TR>
+<TR><TD ALIGN=RIGHT><&|/l&>Refers to</&></TD><TD><input size=10 name="new-RefersTo"<% $ARGS{'new-RefersTo'} && " VALUE=\"$ARGS{'new-MemberOf'}\"" %>></TD></TR>
+<TR><TD ALIGN=RIGHT><&|/l&>Referred to by</&></TD><TD><input size=10 name="RefersTo-new"<% $ARGS{'RefersTo-new'} && " VALUE=\"$ARGS{'RefersTo-new'}\"" %>></TD></TR>
+
+
+</TABLE>
+<& /Elements/TitleBoxEnd &>
+<BR>
+
+</TD>
+</TR>
+</TABLE>
+<& /Elements/Submit, Label => loc("Create") &>
+</FORM>
+<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
+<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
+<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
+<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
+<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
+
+<%INIT>
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($Queue) || Abort(loc("Queue could not be loaded."));
+my $CFs = $QueueObj->CustomFields();
+
+# {{{ deal with deleting uploaded attachments
+foreach my $key (keys %ARGS) {
+    if ($key =~ m/^DeleteAttach-(.+)$/) {
+       delete $session{'Attachments'}{$1};
+    }
+    $session{'Attachments'} = { %{$session{'Attachments'} || {}} };
+}
+
+# {{{ store the uploaded attachment in session
+if ($ARGS{'Attach'}) {                 # attachment?
+    $session{'Attachments'} = {} unless defined $session{'Attachments'};
+
+    my $subject = "$ARGS{'Attach'}";
+
+    # since CGI.pm deutf8izes the magic field, we need to add it back.
+    Encode::_utf8_on($subject);
+    # strip leading directories
+    $subject =~ s#^.*[\\/]##;
+
+    my $attachment = MakeMIMEEntity(
+        Subject             => $subject,
+        Body                => "",
+        AttachmentFieldName => 'Attach'
+    );
+
+    $session{'Attachments'} = { %{$session{'Attachments'} || {}},
+                               $ARGS{'Attach'} => $attachment };
+}
+# }}}
+
+# delete temporary storage entry to make WebUI clean
+unless (keys %{$session{'Attachments'}} and $ARGS{'id'} eq 'new') {
+    delete $session{'Attachments'};
+}
+
+
+# }}}
+
+if ((!exists $ARGS{'AddMoreAttach'}) && ($ARGS{'id'} eq 'new')) { # new ticket?
+    $m->comp('Display.html', %ARGS);
+    $m->abort();
+}
+</%INIT>
+
+<%ARGS>
+$DependsOn => undef
+$DependedOnBy => undef
+$MemberOf => undef
+$QuoteTransaction => undef
+$Queue => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Display.html b/rt/html/Ticket/Display.html
new file mode 100644 (file)
index 0000000..cf32dce
--- /dev/null
@@ -0,0 +1,116 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, 
+    Title => loc("#[_1]: [_2]", $Ticket->Id, $Ticket->Subject) &>
+<& /Ticket/Elements/Tabs, 
+    Ticket => $Ticket, 
+    current_tab => 'Ticket/Display.html?id='.$Ticket->id,
+    Title => loc("#[_1]: [_2]", $Ticket->Id, $Ticket->Subject) &>
+
+<& /Elements/ListActions, actions => \@Actions &>
+
+<& /Ticket/Elements/ShowSummary,  Ticket => $Ticket &>
+
+
+<BR>
+<& /Ticket/Elements/ShowHistory , 
+      Ticket => $Ticket, 
+      Collapsed => $ARGS{'Collapsed'}, 
+      ShowHeaders => $ARGS{'ShowHeaders'} &> 
+
+  
+<%ARGS>
+$id => undef
+$Create => undef
+$ShowHeaders => undef
+$Collapsed => undef
+</%ARGS>
+
+<%INIT>
+  my ($linkid, $message, $tid, $Ticket, @Actions);  
+
+$Ticket = new RT::Ticket($session{'CurrentUser'});
+
+unless ($id) {
+    Abort('No ticket specified');
+}
+
+if ($ARGS{'id'} eq 'new') {
+    # {{{ Create a new ticket
+    
+    my $Queue = new RT::Queue($session{'CurrentUser'});        
+    unless ($Queue->Load($ARGS{'Queue'})) {
+       Abort('Queue not found');
+    }
+    
+    unless ($Queue->CurrentUserHasRight('CreateTicket')) {
+       Abort('You have no permission to create tickets in that queue.');
+    }
+    ($Ticket, @Actions) =
+       CreateTicket(Attachments => $session{'Attachments'}, %ARGS);
+    delete $session{'Attachments'};
+    unless ($Ticket->CurrentUserHasRight('ShowTicket')) {
+      Abort("No permission to view newly created ticket #".$Ticket->id.".");
+    }
+    # }}}
+}
+
+else { 
+    $Ticket = LoadTicket($ARGS{'id'});
+    unless ($Ticket->CurrentUserHasRight('ShowTicket')) {
+       Abort("No permission to view ticket");
+    }
+
+
+if (defined $ARGS{'Action'}) {
+  if ($ARGS{'Action'} =~ /^(Steal|Kill|Take|SetTold)$/) {
+    my $action = $1;
+    my ($res, $msg)=$Ticket->$action();
+    push(@Actions, $msg);
+  }
+}
+
+    if ( $ARGS{'UpdateContent'} ) {
+        $ARGS{'UpdateContent'} =~ s/\r\n/\n/g;
+        if (    $ARGS{'UpdateContent'} ne ''
+             && $ARGS{'UpdateContent'} ne "-- \n"
+             . $session{'CurrentUser'}->UserObj->Signature ) {
+            $ARGS{UpdateAttachments} = $session{'Attachments'};
+            ProcessUpdateMessage( ARGSRef   => \%ARGS,
+                                  Actions   => \@Actions,
+                                  TicketObj => $Ticket );
+            delete $session{'Attachments'};
+        }
+    }
+#Process status updates
+my @BasicActions = ProcessTicketBasics(ARGSRef => \%ARGS, TicketObj=>$Ticket);
+my @results = ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS);                            
+
+push (@Actions, @BasicActions, @results);
+}
+</%INIT>
+
+
+
+
diff --git a/rt/html/Ticket/Elements/AddWatchers b/rt/html/Ticket/Elements/AddWatchers
new file mode 100644 (file)
index 0000000..e9f6515
--- /dev/null
@@ -0,0 +1,97 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<BR>
+<%$msg%><br>
+
+<&|/l&>Add new watchers</&>:<br>
+
+<table>
+% if ($Users and $Users->Count) {
+<tr><td>
+<&|/l&>Type</&>
+</td><td>
+<&|/l&>Username</&>
+</td></tr>
+% while (my $u = $Users->Next ) {
+<tr><td><&/Elements/SelectWatcherType, Name => "Ticket-AddWatcher-Principal-".$u->PrincipalId &></td><td><%$u->Name%> (<%$u->RealName%>)</td></tr>
+% }
+% }
+
+% if ($Groups and $Groups->Count) {
+<tr><td>
+<&|/l&>Type</&>
+</td><td>
+<&|/l&>Group</&>
+</td></tr>
+% while (my $g = $Groups->Next ) {
+<tr><td><&/Elements/SelectWatcherType, Name => "Ticket-AddWatcher-Principal-".$g->PrincipalId, Scope => 'queue' &></td><td><%$g->Name%> (<%$g->Description%>)</td></tr>
+% }
+% }
+
+<tr><td>
+<&|/l&>Type</&>
+</td><td>
+<&|/l&>Email</&>
+</td></tr>
+<tr><td>
+<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail1" &>
+</td><td>
+<input name="WatcherAddressEmail1" size=15>
+</td></tr>
+<tr><td>
+<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail2" &> 
+</td><td>
+<input name="WatcherAddressEmail2" size=15>
+</td></tr>
+<tr><td>
+<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail3" &>
+</td><td>
+<input name="WatcherAddressEmail3" size=15>
+</td></tr>
+</table>
+
+<%INIT>
+my ($msg, $Users, $Groups);
+
+if ($UserString) {
+    $Users = RT::Users->new($session{'CurrentUser'});
+    $Users->Limit(FIELD => $UserField, VALUE => $UserString, OPERATOR => $UserOp);
+     }
+
+if ($GroupString) {
+    $Groups = RT::Groups->new($session{'CurrentUser'});
+    $Groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined');
+    $Groups->Limit(FIELD => $GroupField, VALUE => $GroupString, OPERATOR => $GroupOp);
+     }
+
+</%INIT>
+
+<%ARGS>
+$UserField => 'Name'
+$UserOp => '='
+$UserString => undef
+$GroupField => 'Name'
+$GroupOp => '='
+$GroupString => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/BulkLinks b/rt/html/Ticket/Elements/BulkLinks
new file mode 100644 (file)
index 0000000..e6b9cd5
--- /dev/null
@@ -0,0 +1,53 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TABLE>
+  <TR>
+    <TD class="label"><&|/l&>Merge into</&>:</TD>
+    <TD class="entry"><input name="Ticket-MergeInto"> <i><&|/l&>(only one ticket)</&></i></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Depends on</&>:</TD>
+    <TD class="entry"><input name="Ticket-DependsOn"></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Depended on by</&>:</TD>
+    <TD class="entry"><input name="DependsOn-Ticket"></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Parents</&>:</TD>
+    <TD class="entry"><input name="Ticket-MemberOf"></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Children</&>:</TD>
+    <TD class="entry"> <input name="MemberOf-Ticket"></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Refers to</&>:</TD>
+    <TD class="entry"><input name="Ticket-RefersTo"></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Referred to by</&>:</TD>
+    <TD class="entry"> <input name="RefersTo-Ticket"></TD>
+  </TR>
+</TABLE>
diff --git a/rt/html/Ticket/Elements/EditBasics b/rt/html/Ticket/Elements/EditBasics
new file mode 100644 (file)
index 0000000..5d66b1f
--- /dev/null
@@ -0,0 +1,79 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TABLE>
+  <TR><td>
+    <table>
+      <td class="label"><&|/l&>Subject</&>:</td>
+      <td class="value">
+        <input name=Subject value="<%$TicketObj->Subject|h%>" SIZE=50>
+      </td>
+    </table>
+  </td></TR>
+  <TR><td>
+    <table>
+      <TD>
+        <& /Elements/ShadedBox, 
+            title => loc('Status'),
+            content => $SelectStatus &>
+      </TD>
+      <TD>
+        <& /Elements/ShadedBox,
+           title => loc('Time Worked'),
+           content => "<input name=TimeWorked value=\"".$TicketObj->TimeWorked."\" SIZE=5>" &>
+      </TD>
+      <TD>
+        <& /Elements/ShadedBox,
+           title => loc('Time Left'),
+           content => "<input name=TimeLeft value=\"".$TicketObj->TimeLeft."\" SIZE=5>" 
+&>
+      </TD>
+      <TD>
+        <& /Elements/ShadedBox,
+           title => loc('Priority'),
+           content => "<input name=Priority value=\"".$TicketObj->Priority."\" SIZE=3>" &>
+      </TD>
+      <TD>
+        <& /Elements/ShadedBox,
+           title => loc('Final Priority'),
+           content => "<input name=FinalPriority value=\"".$TicketObj->FinalPriority."\" SIZE=3>" &>
+      </TD>
+      <TD>
+        <& /Elements/ShadedBox,
+            title => loc('Queue'),
+            content => "$SelectQueue" &>
+      </TD>
+    </table>
+  </td></TR>
+</TABLE>
+
+<%INIT>
+#It's hard to do this inline, so we'll preload the html of the selectstatus in here.
+my $SelectStatus = $m->scomp("/Elements/SelectStatus", Name => 'Status', Default=> $TicketObj->Status);
+my $SelectQueue = $m->scomp("/Elements/SelectQueue", Name => 'Queue', Default =>$TicketObj->QueueObj->Id);
+
+</%INIT>
+<%ARGS>
+
+$TicketObj => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/EditCustomField b/rt/html/Ticket/Elements/EditCustomField
new file mode 100644 (file)
index 0000000..1fc7d43
--- /dev/null
@@ -0,0 +1,70 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+% my $Values;
+% if ($TicketObj) {
+%          $Values  = $TicketObj->CustomFieldValues($CustomField->id);
+% }
+% if ($CustomField->Type eq 'FreeformSingle') {
+      <input name="<%$NamePrefix%><%$CustomField->Id%>-Value"
+        size="<%$Cols%>"
+% if ($TicketObj) {
+          value="<%$Values->Count ? $Values->First->Content : ''%>"
+% }
+>
+% } elsif ($CustomField->Type eq 'FreeformMultiple') {
+% my $content;
+% if ($TicketObj) {
+%          while (my $value = $Values->Next ) {
+%                 $content .= $value->Content;
+%           }
+%  }
+<input type="hidden" name="<%$NamePrefix%><%$CustomField->Id%>-Values-Magic" value="1">
+<textarea cols=<%$Cols%> rows=<%$Rows%> name="<%$NamePrefix%><%$CustomField->Id%>-Values"><%$content%></textarea>
+% } elsif ($CustomField->Type =~ /^Select/) {
+      <input type="hidden" name="<%$NamePrefix%><%$CustomField->Id%>-Values-Magic" value="1">
+      <select name="<%$NamePrefix%><%$CustomField->Id%>-Values"
+        size="<%$Rows%>"
+        <%$CustomField->Type eq 'SelectMultiple' && 'MULTIPLE'%>>
+% my $CustomFieldValues = $CustomField->Values();
+% my $selected;
+% while (my $value = $CustomFieldValues->Next) {
+        <option value="<%$value->Name%>" 
+% if ($TicketObj) {
+            <% $Values->HasEntry($value->Name) && ($selected = 1) && 'SELECTED' %>
+% } elsif ($Default) {
+            <% ($Default eq $value->Name) && ($selected = 1) && 'SELECTED' %>
+% }
+            ><% $value->Name%></option>
+% }
+        <option value="" <% !$selected && 'SELECTED' %>><&|/l&>(no value)</&></option>
+      </select>
+% }
+<%ARGS>
+$TicketObj => undef
+$CustomField => undef
+$NamePrefix => undef
+$Rows => 5
+$Cols=> 15
+$Default => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/EditCustomFields b/rt/html/Ticket/Elements/EditCustomFields
new file mode 100644 (file)
index 0000000..6b27389
--- /dev/null
@@ -0,0 +1,74 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<table>
+<tr>
+<td valign="top" width="50%">
+<table>
+
+% my @entry_fields;
+% my $i;
+% my $cfcount = $CustomFields->Count;
+%  $cfcount++ if ($cfcount % 2) ; # if we have an odd number of 
+% #custom fields, fudge it so we know where to put in the table break
+% while (my $CustomField = $CustomFields->Next()) {
+% if ($cfcount == 2 * $i) {
+</table>
+</td>
+<td valign="top" width="50%">
+<table>
+% }
+% $i++;
+  <tr>
+    <td class="labeltop">
+      <b><%$CustomField->Name%></b><br>
+      <i><%$CustomField->FriendlyType%></i>
+    </td>
+    <td class="entry"><& EditCustomField, TicketObj => $TicketObj, CustomField => $CustomField, NamePrefix => $NamePrefix &></td>
+  </tr>
+% }
+</table>
+</td>
+</tr>
+</table>
+
+<%INIT>
+my $CustomFields;
+my $NamePrefix;
+
+if ($TicketObj) {
+ $CustomFields = $TicketObj->QueueObj->CustomFields();
+  $NamePrefix = "Ticket-".$TicketObj->Id."-CustomField-";
+
+} else {
+ $CustomFields = $QueueObj->CustomFields();
+  $NamePrefix = "CustomField-";
+}
+
+
+
+</%INIT>
+<%ARGS>
+$TicketObj => undef
+$QueueObj => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/EditDates b/rt/html/Ticket/Elements/EditDates
new file mode 100644 (file)
index 0000000..1f3bf1b
--- /dev/null
@@ -0,0 +1,53 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TABLE>
+  <TR>
+    <TD class="label"><&|/l&>Starts</&>:</TD>
+    <TD class="entry"><& /Elements/SelectDate, menu_prefix => 'Starts', current => 0 &> 
+        (<% $TicketObj->StartsObj->AsString %>)</TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Started</&>:</TD>
+    <TD class="entry"><& /Elements/SelectDate, menu_prefix => 'Started', current => 0 &> (<%$TicketObj->StartedObj->AsString %>)</TD>
+  </TR>
+
+  <TR>
+    <TD class="label">
+      <&|/l&>Last Contact</&>:
+    </TD>
+    <TD class="entry">
+      <& /Elements/SelectDate, menu_prefix => 'Told', current => 0 &> (<% $TicketObj->ToldObj->AsString %>)
+    </TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Due</&>:</TD>
+    <TD class="entry">
+      <& /Elements/SelectDate, menu_prefix => 'Due', current => 0 &> (<% $TicketObj->DueObj->AsString %>)
+    </TD>
+  </TR>
+</TABLE>
+<%ARGS>
+$TicketObj => undef
+</%ARGS>
+
diff --git a/rt/html/Ticket/Elements/EditLinks b/rt/html/Ticket/Elements/EditLinks
new file mode 100644 (file)
index 0000000..7a522dd
--- /dev/null
@@ -0,0 +1,150 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TABLE width=100%>
+  <TR>
+    <TD VALIGN=TOP WIDTH=50%>
+      <h3><&|/l&>Current Relationships</&></h3>
+
+<table>
+  <tr>
+    <td></td>
+    <td><i><&|/l&>(Check box to delete)</&></i></td>
+  </tr>
+  <tr>
+    <td class="labeltop"><&|/l&>Depends on</&>:</td>
+    <td class="value">
+% while (my $link = $Ticket->DependsOn->Next) {
+% my $member = $link->TargetObj;
+      <INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>">
+      <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%>
+      [<%$member->Status%>]<br>
+% }
+    </td>
+  </tr>
+  <tr>
+    <td class="labeltop"><&|/l&>Depended on by</&>:</td>
+    <td class="value">
+% while (my $link = $Ticket->DependedOnBy->Next) {
+% my $member = $link->BaseObj;
+      <INPUT TYPE=CHECKBOX NAME="DeleteLink-<%$link->Base%>-<%$link->Type%>-">
+      <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> 
+      [<%$member->Status%>]<br>
+% }
+    </td>
+  </tr>
+  <tr>
+    <td class="labeltop"><&|/l&>Parents</&>:</td>
+    <td class="value">
+% while (my $link = $Ticket->MemberOf->Next) {
+% my $member = $link->TargetObj;
+      <INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>">
+      <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%>
+      [<%$member->Status%>]<br>
+% }
+    </td>
+  </tr>
+  <tr>
+    <td class="labeltop"><&|/l&>Children</&>:</td>
+    <td class="value">
+% while (my $link = $Ticket->Members->Next) {
+      <INPUT TYPE=CHECKBOX NAME="DeleteLink-<%$link->Base%>-<%$link->Type%>-">
+% my $member = $link->BaseObj;
+      <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> 
+      [<%$member->Status%>]<br>
+% }
+    </td>
+  </tr>
+  <tr>
+    <td class="labeltop"><&|/l&>Refers to</&>:</td>
+    <td class="value">
+% while (my $link = $Ticket->RefersTo->Next) {
+      <INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>">
+% if ($link->TargetURI->IsLocal) {
+% my $member = $link->TargetObj;
+      <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<%$member->Status%>]<br>
+% } else {
+      <A HREF="<%$link->TargetURI->Resolver->HREF%>"><%$link->TargetURI->Resolver->AsString%></A><br>
+% }
+%}
+    </td>
+  </tr>
+  <tr>
+    <td class="labeltop"><&|/l&>Referred to by</&>:</td>
+    <td class="value">
+% while (my $link = $Ticket->ReferredToBy->Next) {
+      <INPUT TYPE=CHECKBOX NAME="DeleteLink-<%$link->Base%>-<%$link->Type%>-">
+% if ($link->BaseURI->IsLocal) {
+% my $member = $link->BaseObj;
+      <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<%$member->Status%>]<br>
+% } else {
+      <A HREF="<%$link->BaseURI->Resolver->HREF%>"><%$link->BaseURI->Resolver->AsString%></A><br>
+%}
+% }
+    </td>
+  </tr>
+</table>
+                           
+</TD>
+<TD VALIGN=TOP>
+<h3><&|/l&>New Relationships</&></h3>
+<i><&|/l&>Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces.</&></i><br>
+<TABLE>
+  <TR>
+    <TD class="label"><&|/l&>Merge into</&>:</TD>
+    <TD class="entry"><input name="<%$Ticket->Id%>-MergeInto"> <i><&|/l&>(only one ticket)</&></i></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Depends on</&>:</TD>
+    <TD class="entry"><input name="<%$Ticket->Id%>-DependsOn"></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Depended on by</&>:</TD>
+    <TD class="entry"><input name="DependsOn-<%$Ticket->Id%>"></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Parents</&>:</TD>
+    <TD class="entry"><input name="<%$Ticket->Id%>-MemberOf"></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Children</&>:</TD>
+    <TD class="entry"> <input name="MemberOf-<%$Ticket->Id%>"></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Refers to</&>:</TD>
+    <TD class="entry"><input name="<%$Ticket->Id%>-RefersTo"></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Referred to by</&>:</TD>
+    <TD class="entry"> <input name="RefersTo-<%$Ticket->Id%>"></TD>
+  </TR>
+</TABLE>
+</TD>
+</TR>
+</TABLE>
+
+
+      
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/EditPeople b/rt/html/Ticket/Elements/EditPeople
new file mode 100644 (file)
index 0000000..1ab8f4a
--- /dev/null
@@ -0,0 +1,68 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TABLE>
+<TR>
+<TD VALIGN=TOP>
+
+<h3><&|/l&>New watchers</&></h3>
+<&|/l&>Find people whose</&><BR>
+<& /Elements/SelectUsers &>
+<input type=submit name="OnlySearchForPeople" value="<&|/l&>Go!</&>">
+<BR>
+<&|/l&>Find group whose</&><BR>
+<& /Elements/SelectGroups &>
+<input type=submit name="OnlySearchForGroup" value="<&|/l&>Go!</&>">
+
+<& AddWatchers, Ticket => $Ticket, UserString => $UserString,
+        UserOp => $UserOp, UserField => $UserField,
+       GroupString => $GroupString, GroupOp => $GroupOp,
+       GroupField => $GroupField &> 
+</TD><TD VALIGN=TOP>
+<h3><&|/l&>Owner</&></h3>
+<&|/l&>Owner</&>: <& /Elements/SelectOwner, Name => 'Owner', QueueObj => $Ticket->QueueObj, TicketObj => $Ticket, Default => $Ticket->OwnerObj->Id &>
+<h3><&|/l&>Current watchers</&></h3>
+<&|/l&>(Check box to delete)</&><br>
+
+<&|/l&>Requestors</&>:
+<& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->Requestors &>
+
+<&|/l&>Cc</&>:
+<& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->Cc &>
+
+<&|/l&>Administrative Cc</&>:
+<& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->AdminCc &>
+
+</TD>
+</TR>
+</TABLE>
+
+<%ARGS>
+$UserField => undef
+$UserOp => undef
+$UserString => undef
+$GroupField => undef
+$GroupOp => undef
+$GroupString => undef
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/EditWatchers b/rt/html/Ticket/Elements/EditWatchers
new file mode 100644 (file)
index 0000000..145071c
--- /dev/null
@@ -0,0 +1,52 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<ul>
+%# Print out a placeholder if there are none.
+%if ($Members->Count == 0 ) {
+<li><i><&|/l&>none</&></i>
+% }
+
+
+%while (my $watcher=$Members->Next) {
+<li>
+<INPUT TYPE=CHECKBOX NAME="Ticket-DelWatcher-Type-<%$Watchers->Type%>-Principal-<%$watcher->MemberId%>" UNCHECKED>
+%if ($watcher->MemberObj->IsUser) { 
+<a href="<%$RT::WebPath%>/Admin/Users/Modify.html?id=<%$watcher->MemberObj->Object->id%>">
+<%$watcher->MemberObj->Object->Name%></a>
+%} else {
+<a href="<%$RT::WebPath%>/Admin/Groups/Modify.html?id=<%$watcher->MemberObj->Object->id%>">
+<%$watcher->MemberObj->Object->Name%></a>
+%}
+% }
+</ul>
+<%INIT>
+my $Members = $Watchers->MembersObj;
+</%INIT>
+<%ARGS>
+$TicketObj => undef
+$Watchers => undef
+</%ARGS>
+
+
+
diff --git a/rt/html/Ticket/Elements/ShowAttachments b/rt/html/Ticket/Elements/ShowAttachments
new file mode 100644 (file)
index 0000000..22b60d1
--- /dev/null
@@ -0,0 +1,76 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+% if (keys %documents) {
+<& /Elements/TitleBoxStart, title => loc('Attachments'), 
+        title_class=> 'inverse',  
+        color => "#336699" &>
+
+% foreach my $key (keys %documents) {
+% my $fontsize='size="-1"';
+
+<%$key%><br>
+<ul>
+% foreach my $rev (@{$documents{$key}}) {
+
+<%PERL>
+my $size = $rev->ContentLength;
+
+if ($size) {
+    if ($size > 1024) {
+        $size = int($size/102.4)/10 . "k";
+    }
+    else {
+        $size = $size ."b";
+    }
+
+</%PERL>
+
+<li><font <%$fontsize%>>
+        <A HREF="<%$RT::WebPath%>/Ticket/Attachment/<%$rev->TransactionObj->Id%>/<%$rev->Id%>/<%$rev->Filename%>"><%$rev->CreatedAsString%> (<% $size %>)</a></font></li>
+% }
+% $fontsize='size="-2"';
+% }
+</ul>
+
+% }
+<& /Elements/TitleBoxEnd &>
+<BR>
+% }
+
+<%INIT>
+my %documents;
+my $transactions = $Ticket->Transactions();
+while (my $trans = $transactions->Next()) {
+        my $attachments = $trans->Attachments();
+        while (my $attach = $attachments->Next()) {
+              next unless ($attach->Filename());
+              # most recent at the top
+              unshift (@{$documents{$attach->Filename}}, $attach);
+        }
+}
+</%INIT>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
+
diff --git a/rt/html/Ticket/Elements/ShowBasics b/rt/html/Ticket/Elements/ShowBasics
new file mode 100644 (file)
index 0000000..ad23e8c
--- /dev/null
@@ -0,0 +1,54 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<table>
+  <tr>
+    <td class="label"><&|/l&>Id</&>:</td>
+    <td class="value"><%$Ticket->Id %></td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>Status</&>:</td>
+    <td class="value"><&|/l&><% $Ticket->Status%></&></td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>Worked</&>:</td>
+    <td class="value"><&|/l, $TimeWorked &>[_1] min</&></td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>Priority</&>:</td>
+    <td class="value"><%$Ticket->Priority%>/<%$Ticket->FinalPriority %></td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>Queue</&>:</td>
+    <td class="value"><%$Ticket->QueueObj->Name%></td>
+  </tr>
+</table>
+<%INIT>
+my $TimeWorked = $Ticket->TimeWorked;
+if ($Ticket->TimeLeft > 0 ) {
+  $TimeWorked = $Ticket->TimeWorked."/".$Ticket->TimeLeft;
+}
+</%INIT>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowCustomFields b/rt/html/Ticket/Elements/ShowCustomFields
new file mode 100644 (file)
index 0000000..50d28f0
--- /dev/null
@@ -0,0 +1,46 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<table>
+% my @entry_fields;
+% while (my $CustomField = $CustomFields->Next()) {
+% my $Values = $Ticket->CustomFieldValues($CustomField->Id);
+  <tr>
+    <td class="label"><%$CustomField->Name%>:</td>
+    <td class="value">
+% while (my $Value = $Values->Next()) {
+<%$Value->Content%><br>        
+% }
+% unless ($Values->Count()) {
+<i><&|/l&>(no value)</&></i>
+% }
+    </td>
+  </tr>
+% }
+</table>
+<%INIT>
+my $CustomFields = $Ticket->QueueObj->CustomFields();
+</%INIT>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowDates b/rt/html/Ticket/Elements/ShowDates
new file mode 100644 (file)
index 0000000..da7f75b
--- /dev/null
@@ -0,0 +1,56 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TABLE>
+  <TR>
+    <TD class="label"><&|/l&>Created</&>:</TD>
+    <TD class="value"><% $Ticket->CreatedObj->AsString %></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Starts</&>:</TD>
+    <TD class="value"><% $Ticket->StartsObj->AsString %></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Started</&>:</TD>
+    <TD class="value"><% $Ticket->StartedObj->AsString %></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Last Contact</&>:</TD>
+    <TD class="value"><% $Ticket->ToldObj->AsString %></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Due</&>:</TD>
+    <TD class="value"><% $Ticket->DueObj->AsString  %></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Closed</&>:</TD>
+    <TD class="value"><% $Ticket->ResolvedObj->AsString  %></TD>
+  </TR>
+  <TR>
+    <TD class="label"><&|/l&>Updated</&>:</TD>
+    <TD class="value"><A HREF="#lasttrans"><% $Ticket->LastUpdated ? (loc("[_1] by [_2]", $Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)) : loc("Never") | h %></a></TD>
+  </TR>
+</TABLE>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowDependencies b/rt/html/Ticket/Elements/ShowDependencies
new file mode 100644 (file)
index 0000000..b7f3968
--- /dev/null
@@ -0,0 +1,41 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<&|/l&>Depends on</&>:<BR>
+% while (my $Link = $Ticket->DependsOn->Next) {
+% my $member = $Link->TargetObj;
+<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%>
+[<%$member->Status%>]
+ <br>
+% }
+<&|/l&>Depended on by</&>:<BR>
+% while (my $Link = $Ticket->DependedOnBy->Next) {
+% my $member = $Link->TargetObj;
+<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> 
+[<%$member->Status%>]
+ <br>
+% }
+
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowHistory b/rt/html/Ticket/Elements/ShowHistory
new file mode 100644 (file)
index 0000000..2958f87
--- /dev/null
@@ -0,0 +1,86 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<%perl>
+ if ($ShowDisplayModes or $ShowTitle) {
+my $title;
+my $titleright;
+if ($ShowTitle) {
+    $title = loc('History');
+}
+else {
+    $title = '&nbsp;';
+}
+$titleright = loc('Display mode') . ":";
+if ($ShowHeaders &&  $ShowHeaders == $Ticket->Id ) {
+    $titleright .= "[<A HREF=\"" . $URIFile . "?id="
+      . $Ticket->id . "\">"
+      . loc("Brief headers")
+      . "</a>] <b>["
+      . loc("Full headers") . "]</b>";
+}
+else {
+    $titleright .= "<b>["
+      . loc("Brief headers")
+      . "]</b> [<A HREF=\""
+      . $URIFile
+      . "?ShowHeaders="
+      . $Ticket->Id . "&id="
+      . $Ticket->id . "\">"
+      . loc("Full headers") . "</a>]";
+}
+</%perl>
+<& /Elements/TitleBoxStart, title => $title, titleright => $titleright, bodyclass=> ''&>
+% }
+
+<TABLE WIDTH=100% CELLSPACING=0 CELLPADDING=2 BORDER=0>
+% while (my $Transaction = $Transactions->Next) {
+% my $skip = 0;
+% $m->comp('/Elements/Callback', _CallbackName => 'SkipTransaction', Transaction => $Transaction, skip => \$skip, %ARGS);
+% next if $skip;
+% $i++;
+%      if ($Transactions->IsLast) {
+       <a name="lasttrans"></a>
+%      }
+           <& ShowTransaction, Ticket => $Ticket, Transaction => $Transaction, ShowHeaders => $ShowHeaders, Collapsed => $Collapsed, RowNum => $i, ShowTitleBarCommands => $ShowTitleBarCommands  &>
+% }
+</TABLE>
+% if ($ShowDisplayModes or $ShowTitle) {
+<& /Elements/TitleBoxEnd &>
+% }
+<%INIT>
+
+my $Transactions = $Ticket->Transactions;
+my $i;
+
+
+</%INIT>
+<%ARGS>
+$URIFile => 'Display.html'
+$Ticket => undef
+$ShowHeaders => undef
+$Collapsed => undef
+$ShowTitle => 1
+$ShowDisplayModes => 1
+$ShowTitleBarCommands => 1
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowLink b/rt/html/Ticket/Elements/ShowLink
new file mode 100644 (file)
index 0000000..493fd95
--- /dev/null
@@ -0,0 +1,40 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<A href="<%$URI->Resolver->HREF%>">
+% if ($URI->IsLocal) {
+% my $member = $URI->Object;
+% if (UNIVERSAL::isa($member, "RT::Ticket")) {
+<%$member->Id%>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<% loc($member->Status) %>]
+% } elsif ( UNIVERSAL::can($member, 'Name')) {
+<%$URI->Resolver->AsString%>: <%$member->Name%>
+% } else {
+<%$URI->Resolver->AsString%>
+% }
+% } else {
+<%$URI->Resolver->AsString%>
+% }
+</a>
+<%ARGS>
+$URI => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowLinks b/rt/html/Ticket/Elements/ShowLinks
new file mode 100644 (file)
index 0000000..f88a600
--- /dev/null
@@ -0,0 +1,87 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<table>
+  <tr>
+    <td class="labeltop"><&|/l&>Depends on</&>:</td>
+    <td class="value">
+<ul>
+% while (my $Link = $Ticket->DependsOn->Next) {
+<li><& ShowLink, URI => $Link->TargetURI &>
+% }
+</ul>
+    </td>
+  </tr>
+  <tr>
+    <td class="labeltop"><&|/l&>Depended on by</&>:</td>
+    <td class="value">
+<ul>
+% while (my $Link = $Ticket->DependedOnBy->Next) {
+<li><& ShowLink, URI => $Link->BaseURI &>
+% }
+</ul>
+    </td>
+  </tr>
+  <tr>
+    <td class="labeltop"><&|/l&>Parents</&>:</td>
+    <td class="value">
+<ul>
+% while (my $Link = $Ticket->MemberOf->Next) {
+<li><& ShowLink, URI => $Link->TargetURI &>
+% }
+</ul>
+    </td>
+  </tr>
+  <tr>
+    <td class="labeltop"><&|/l&>Children</&>:</td>
+    <td class="value"><& /Ticket/Elements/ShowMembers, Ticket => $Ticket &></td>
+  </tr>
+  <tr>
+    <td class="labeltop"><&|/l&>Refers to</&>:</td>
+    <td class="value">
+<ul>
+% while (my $Link = $Ticket->RefersTo->Next) {
+<li><& ShowLink, URI => $Link->TargetURI &>
+% }
+</ul>
+    </td>
+  </tr>
+  <tr>
+    <td class="labeltop"><&|/l&>Referred to by</&>:</td>
+    <td class="value">
+    <ul>
+% while (my $Link = $Ticket->ReferredToBy->Next) {
+<li><& ShowLink, URI => $Link->BaseURI &>
+% }
+</ul>
+    </td>
+  </tr>
+
+% # Allow people to add more rows to the table                                                                                                                           
+%  $m->comp('/Elements/Callback', %ARGS );
+
+</table>
+
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowMemberOf b/rt/html/Ticket/Elements/ShowMemberOf
new file mode 100644 (file)
index 0000000..79e0a3b
--- /dev/null
@@ -0,0 +1,35 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<UL>
+% my $memberof = $Ticket->MemberOf;
+% while (my $member_of = $memberof->Next) {
+<LI><a href="/Ticket/Display.html?id=<%$member_of->Id%>"><%$member_of->Id%></a>: <%$member_of->Subject%> [<%$member_of->Status%>]
+% }
+</UL>
+
+<%INIT>
+</%INIT>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowMembers b/rt/html/Ticket/Elements/ShowMembers
new file mode 100644 (file)
index 0000000..e101662
--- /dev/null
@@ -0,0 +1,45 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+% if ($members->Count) {
+<UL>
+% while (my $link = $members->Next) {
+% my $member= $link->BaseObj;
+<LI><a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: <%$member->Subject%> [<%loc($member->Status)%>]<br>
+% if ($depth < 8) {
+<&/Ticket/Elements/ShowMembers, Ticket => $member, depth => ($depth+1) &> 
+% }
+% }
+</UL>
+% }
+
+<%INIT>
+
+my $members = $Ticket->Members;
+
+</%INIT>
+
+<%ARGS>
+$Ticket => undef
+$depth => 1
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowMessageHeaders b/rt/html/Ticket/Elements/ShowMessageHeaders
new file mode 100644 (file)
index 0000000..11d873c
--- /dev/null
@@ -0,0 +1,32 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<%$content |n%>
+<%INIT>
+my $content = $Headers;
+RT::Interface::Web::EscapeUTF8(\$content);
+$m->comp('/Elements/Callback', content => \$content, %ARGS);
+</%INIT>
+<%ARGS>
+$Headers => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowMessageStanza b/rt/html/Ticket/Elements/ShowMessageStanza
new file mode 100644 (file)
index 0000000..b099806
--- /dev/null
@@ -0,0 +1,51 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<%perl>
+foreach my $stanza (@$Message) {
+    if ( ref $stanza eq "ARRAY" ) {
+        $m->comp( 'ShowMessageStanza',
+                  Depth   => $Depth + 1,
+                  Transaction => $Transaction,
+                  Message => $stanza );
+    }
+    elsif ( ref $stanza eq "HASH" ) {
+        my $content = $stanza->{raw};
+        RT::Interface::Web::EscapeUTF8(\$content);
+        $m->comp('/Elements/Callback', content => \$content, %ARGS);
+                $content =~ s/\n/<br>/gi;
+
+</%perl>
+<font color="<%$colors[$Depth]%>"><%$content |n%><br></font>
+%       }
+% }
+<%INIT>
+use URI::URL;
+my $server = 'fsck.com';
+my @colors = ('#000000', '#660000', '#006600', '#000066', '#cc0000', '#00cc00', '#0000cc', '#ff0000', '#00ff00', '#0000ff');
+</%INIT>
+<%ARGS>
+$Message => undef
+$Depth => 0
+$Transaction => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowPeople b/rt/html/Ticket/Elements/ShowPeople
new file mode 100644 (file)
index 0000000..0b80269
--- /dev/null
@@ -0,0 +1,45 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<table>
+  <tr>
+    <td class="label"><&|/l&>Owner</&>:</td>
+    <td class="value"><%$Ticket->OwnerObj->Name%></td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>Requestors</&>:</td>
+    <td class="value"><%$Ticket->RequestorAddresses%></td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>Cc</&>:</td>
+    <td class="value"><%$Ticket->CcAddresses%></td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>AdminCc</&>:</td>
+    <td class="value"><%$Ticket->AdminCcAddresses%></td>
+  </tr>
+</table>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
+
diff --git a/rt/html/Ticket/Elements/ShowReferences b/rt/html/Ticket/Elements/ShowReferences
new file mode 100644 (file)
index 0000000..831923b
--- /dev/null
@@ -0,0 +1,50 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<UL>
+% while (my $Link = $Ticket->RefersTo->Next) {
+<LI>
+% if ($Link->TargetURI->IsLocal) {
+% my $member = $Link->TargetObj;
+
+<a href="/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<%$member->Status%>]<br>
+% } else {
+<A HREF="<%$Link->TargetURI->HREF%>"><%$Link->Target%></A>
+% }
+%}
+
+
+
+% while (my $Link = $Ticket->ReferredToBy->Next) {
+<LI>
+% if ($Link->BaseURI->IsLocal) {
+% my $member = $Link->BaseObj;
+<a href="/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<%$member->Status%>]<br>
+% } else {
+<A HREF="<%$Link->BaseURI->HREF%>"><%$Link->Base%></A>
+%}
+% }
+</UL>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowRequestor b/rt/html/Ticket/Elements/ShowRequestor
new file mode 100644 (file)
index 0000000..cc91f59
--- /dev/null
@@ -0,0 +1,59 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<%PERL>
+my $rows = 10;
+my $people = $Ticket->Requestors->MembersObj;
+while (my $member=$people->Next) {
+my $requestor = $member->MemberObj->Object;
+my $name=$requestor->RealName || $requestor->EmailAddress;     
+my $tickets = RT::Tickets->new($session{'CurrentUser'});
+$tickets->LimitWatcher(TYPE => 'Requestor', VALUE => $requestor->EmailAddress );
+$tickets->LimitStatus( VALUE => 'open');
+$tickets->LimitStatus( VALUE => 'new');
+$tickets->RowsPerPage($rows);
+$tickets->OrderBy(FIELD => 'Priority',
+                 ORDER => 'DESC');
+</%PERL>
+
+% unless ($requestor->Privileged) {
+<& /Elements/TitleBoxStart, 
+       title => "<a class='inverse' href=\"$RT::WebPath/Admin/Users/Modify.html?id=".$requestor->id."\">".loc("More about [_1]", $name)."</a>" &>
+
+<&|/l&>Comments about this user</&>:<BR>
+<B><% ($requestor->Comments || loc("No comment entered about this user")) %></B><BR>
+
+<&|/l, $rows &>This user's [_1] highest priority tickets</&>:<BR>
+<UL>
+%while (my $w=$tickets->Next) {
+<LI><a href="<%$RT::WebPath%><%$DisplayPath%>?id=<%$w->id%>"><%$w->Id%>: <%$w->Subject%></a> (<%$w->Status%>)
+%}
+</UL>
+<& /Elements/TitleBoxEnd &>
+
+% }
+%}
+<%ARGS>
+$Ticket=>undef
+$DisplayPath => "/Ticket/Display.html"
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowSummary b/rt/html/Ticket/Elements/ShowSummary
new file mode 100644 (file)
index 0000000..6ae8758
--- /dev/null
@@ -0,0 +1,82 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+      <TABLE WIDTH="100%" class="ticketsummary" >
+      <TR>
+       <TD VALIGN=TOP WIDTH="50%">
+         <& /Elements/TitleBoxStart, title => loc('The Basics'), 
+               title_href =>"$RT::WebPath/Ticket/Modify.html?id=".$Ticket->Id, 
+               title_class=> 'inverse',  
+               color => "#993333" &>
+               <& /Ticket/Elements/ShowBasics, Ticket => $Ticket &>
+         <& /Elements/TitleBoxEnd &>
+          <br>
+% if ($Ticket->QueueObj->CustomFields()->First) {
+         <& /Elements/TitleBoxStart, title => loc('Custom Fields'), 
+               title_href =>"$RT::WebPath/Ticket/Modify.html?id=".$Ticket->Id, 
+               title_class=> 'inverse',  
+               color => "#993333" &>
+               <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket &>
+         <& /Elements/TitleBoxEnd &>
+
+<br>
+% }
+         <& /Elements/TitleBoxStart, title => loc('People'), 
+               title_href =>"$RT::WebPath/Ticket/ModifyPeople.html?id=".$Ticket->Id, 
+               title_class=> 'inverse',  
+               color => "#333399" &>
+         <& /Ticket/Elements/ShowPeople, Ticket => $Ticket &>
+         <& /Elements/TitleBoxEnd &>
+       <BR>
+       </TD>
+       <TD VALIGN=TOP WIDTH="50%">
+
+         <& /Elements/TitleBoxStart, title => loc("Dates"),
+               title_href =>"$RT::WebPath/Ticket/ModifyDates.html?id=".$Ticket->Id, 
+               title_class=> 'inverse',  
+                color => "#663366" &>
+         <& /Ticket/Elements/ShowDates, Ticket => $Ticket &>
+         <& /Elements/TitleBoxEnd &>
+       <BR>  
+         <& /Elements/TitleBoxStart, title => loc('Relationships'), 
+               title_href => "$RT::WebPath/Ticket/ModifyLinks.html?id=".$Ticket->Id, 
+               title_class=> 'inverse',  
+               titleright => '', color=> "#336633" &>
+               <& /Ticket/Elements/ShowLinks, Ticket => $Ticket &>
+       <& /Elements/TitleBoxEnd &>
+        <BR>
+         <& /Ticket/Elements/ShowAttachments, Ticket => $Ticket &>
+
+         <& /Ticket/Elements/ShowRequestor, Ticket => $Ticket &>
+
+
+       </TD>
+      </TR>
+    </TABLE>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
+
+
+
+
diff --git a/rt/html/Ticket/Elements/ShowTransaction b/rt/html/Ticket/Elements/ShowTransaction
new file mode 100644 (file)
index 0000000..f2f89d3
--- /dev/null
@@ -0,0 +1,169 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<TR class="<% $RowNum%2 ? 'oddline' : 'evenline'%>" >
+<TD bgcolor="<%$bgcolor%>"><A NAME="txn-<%$Transaction->Id%>" href="#txn-<%$Transaction->Id%>">#</A>&nbsp;</TD>
+<TD>&nbsp&nbsp;</TD>
+<TD><font size=-2><% $transdate|n %></font>&nbsp;</TD>
+% my $desc = $Transaction->BriefDescription;
+% $m->comp('/Elements/Callback', _CallbackName => 'ModifyDisplay', text => \$desc, Transaction => $Transaction, %ARGS);
+<TD ALIGN="LEFT"><b><%$Transaction->CreatorObj->Name%> - <%$TicketString%> <%$desc%>
+
+</b></TD>
+<TD><%$TimeTaken%>&nbsp;</TD>
+<TD ALIGN="RIGHT"><font size=-1><%$titlebar_commands|n%></font></TD>
+</TR>
+<%PERL>
+
+unless ($Collapsed) {
+ $attachments->GotoFirstItem;
+ while (my $message=$attachments->Next) {
+     #we don't want to show any empty transactions, unless they have kids
+     next unless ($message->ContentLength || $message->Children->Count);
+
+  my ($headers, $quoted);
+      if ($ShowHeaders && ($ShowHeaders == $Ticket->Id)) {
+         $headers = $message->Headers;
+      } else {
+         $headers = $message->NiceHeaders;
+      }
+      chomp $headers;
+      if ($headers) {
+          # localize the common headers (like 'Subject:'), too.
+          eval {$headers =~ s/^([^:]+)(?=:)/loc($1)/em; } # we eval here to catch errors when 5.6 panics
+      }
+     # 13456 is a random # of about the biggest size we want to see inline text
+     my $MAX_INLINE_BODY = 13456;
+     if ($message->ContentType =~ m{^(text/plain|message|text$)}i && 
+                                   $message->ContentLength < $MAX_INLINE_BODY ) {
+         require Text::Quoted;
+        $quoted = Text::Quoted::extract($message->Content); 
+     }
+        
+</%PERL>
+<TR class="<% $RowNum%2 ? 'oddline' : 'evenline'%>" >                                
+      <TD BGCOLOR="<%$bgcolor%>">&nbsp;&nbsp;</TD>
+      <TD>&nbsp;&nbsp;</TD>
+      <TD COLSPAN=3 VALIGN=TOP>
+<span class="message">
+       <PRE>
+<& ShowMessageHeaders, Headers => $headers, Transaction => $Transaction &>
+</PRE>
+<& ShowMessageStanza, Depth => 0, Message => $quoted, Transaction => $Transaction &>
+</span>
+      </TD>
+      <TD VALIGN=TOP ALIGN=RIGHT>
+       
+% if ($message->Parent == 0  ) {
+<BR>
+% }
+<%PERL>
+my $size = $message->ContentLength;
+
+if ($size) {
+    if ($size > 1024) {
+       $size = loc("[_1]k", int($size/102.4)/10);
+    }
+    else {
+       $size = loc("[_1]b", $size);
+    }
+</%PERL>
+<font size=-1><A HREF="<%$RT::WebPath%>/Ticket/Attachment/<%$Transaction->Id%>/<%$message->Id%>/<%$message->Filename%>"><&|/l&>Download</&> <% $message->Filename|| loc('(untitled)') %></a> <% $size %></font>
+% }
+</TD>
+</TR>
+% }
+% }
+
+
+
+<%ARGS>
+$Ticket => undef
+$Transaction => undef
+$ShowHeaders => 0
+$Collapsed => undef
+$ShowTitleBarCommands => 1
+$RowNum => 1
+</%ARGS>
+
+<%INIT>
+
+
+my ($TimeTaken, $TicketString, $bgcolor);
+
+my $transdate = $Transaction->CreatedAsString();
+$transdate =~ s/\s/&nbsp;/g;
+
+if ($Transaction->Type =~ /^(Create|Correspond|Comment$)/) {
+       if ($Transaction->IsInbound) {
+               $bgcolor="#336699";
+       }
+       else {
+               $bgcolor="#339999";
+       }
+} elsif (($Transaction->Field =~ /^Owner$/) or 
+        ($Transaction->Type =~ /^(AddWatcher|DelWatcher)$/)) {
+       $bgcolor="#333399";
+
+} elsif ($Transaction->Type =~ /^(AddLink|DeleteLink)$/) {
+       $bgcolor="#336633";
+} elsif ($Transaction->Type =~ /^(Status|Set|Told)$/) {
+       if ($Transaction->Field =~ /^(Told|Starts|Started|Due)$/) {
+               $bgcolor="#663366";     
+       }
+       else {
+               $bgcolor="#993333";
+       }
+}
+else {
+       $bgcolor="#cccccc";
+}
+
+if ($Ticket->Id != $Transaction->Ticket) {
+       $TicketString = "Ticket ".$Transaction->Ticket .": ";
+}
+
+if ($Transaction->TimeTaken > 0) {
+       $TimeTaken = $Transaction->TimeTaken." min"
+}
+my $attachments = $Transaction->Attachments;
+
+my $titlebar_commands='&nbsp;';
+
+# If the transaction has anything attached to it at all
+if ($Transaction->Attachments->First && $ShowTitleBarCommands) {
+       if ($Transaction->TicketObj->CurrentUserHasRight('ReplyToTicket')) {
+               $titlebar_commands .= 
+                 "[<a href=\"Update.html?id=".
+                 $Transaction->Ticket . "&QuoteTransaction=".$Transaction->Id.
+                 "&Action=Respond\">". loc('Reply') ."</a>]&nbsp;";
+       }
+       if ($Transaction->TicketObj->CurrentUserHasRight('CommentOnTicket')) {
+            $titlebar_commands .= 
+            "[<a href=\"Update.html?id=".$Transaction->Ticket. 
+            "&QuoteTransaction=".$Transaction->Id.
+            "&Action=Comment\">". loc('Comment') ."</a>]";
+       }
+}
+
+</%INIT>
diff --git a/rt/html/Ticket/Elements/Tabs b/rt/html/Ticket/Elements/Tabs
new file mode 100644 (file)
index 0000000..81c92e8
--- /dev/null
@@ -0,0 +1,170 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Callback, Ticket => $Ticket, actions=> $actions, tabs => $tabs, %ARGS &>
+<& /Elements/Tabs, 
+    tabs => $tabs, 
+    actions => $actions, 
+    current_tab => $current_tab, 
+    current_toptab => $current_toptab,
+    Title => $Title &> 
+<%INIT>
+
+my $tabs = {};
+my $current_toptab = "Search/Listing.html",
+    my $searchtabs = { new => { title => loc('New Search'),
+                                path => 'Search/Listing.html?ClearRestrictions=1'}
+                        
+
+} ;
+my $actions;
+
+if ( $Ticket) {
+       
+my $id   = $Ticket->id();
+
+if ( defined $session{'tickets'} ) {
+
+
+my $item_map = $session{'tickets'}->ItemMap;
+
+            # Don't $current_toptab = display prev links if we're on the first ticket
+
+        if ($item_map->{$Ticket->Id}->{prev}) {
+                $searchtabs->{'_a'} = {
+                            class => "nav",
+                            path => "Ticket/Display.html?id=" . $item_map->{first},
+                            title => '<< ' . loc('First') };
+                $searchtabs->{"_b"} = { class => "nav",
+                            path => "Ticket/Display.html?id=" . $item_map->{$Ticket->Id}->{prev},
+                                  title => '< ' . loc('Prev') };
+       } 
+
+
+        # Don't display next links if we're on the last ticket
+        if ($item_map->{$Ticket->Id}->{next}) {
+            $searchtabs->{'d'} = { class => "nav",
+                            path => "Ticket/Display.html?id=" . $item_map->{$Ticket->Id}->{next},
+                             title => loc('Next') . ' >' };
+            $searchtabs->{'e'} = {
+                           class => "nav",
+                           path => "Ticket/Display.html?id=" . $item_map->{last},
+                           title => loc('Last') . ' >>' };
+        }
+}
+
+
+
+$tabs->{"this"} = { class => "currentnav",
+                    path  => "Ticket/Display.html?id=" . $Ticket->id,
+                    title => "#" . $id,
+                    current_subtab => $current_subtab };
+
+my $ticket_page_tabs = {
+    _A => { title => loc('Display'),
+            path  => "Ticket/Display.html?id=" . $id, },
+
+    _Ab => { title => loc('History'),
+             path  => "Ticket/History.html?id=" . $id, },
+    _B => { title => loc('Basics'),
+            path  => "Ticket/Modify.html?id=" . $id, },
+
+    _C => { title => loc('Dates'),
+            path  => "Ticket/ModifyDates.html?id=" . $id, },
+    _D =>
+      { title => loc('People'), path => "Ticket/ModifyPeople.html?id=" . $id, },
+    _E => { title => loc('Links'),
+            path  => "Ticket/ModifyLinks.html?id=" . $id, },
+    _F => { title => loc('Jumbo'),
+            path  => "Ticket/ModifyAll.html?id=" . $id,
+            seperator => 1
+ },
+
+};
+
+foreach my $tab ( sort keys %{$ticket_page_tabs} ) {
+    if ( $ticket_page_tabs->{$tab}->{'path'} eq $current_tab ) {
+        $ticket_page_tabs->{$tab}->{"subtabs"}        = $subtabs;
+        $tabs->{'this'}->{"current_subtab"}        = 
+        $ticket_page_tabs->{$tab}->{"path"};
+    }
+}
+$tabs->{'this'}->{"subtabs"} = $ticket_page_tabs;
+$current_tab = "Ticket/Display.html?id=" . $id;
+
+
+
+
+
+if (    $Ticket->CurrentUserHasRight('ModifyTicket')
+     or $Ticket->CurrentUserHasRight('ReplyToTicket') ) {
+    $actions->{'A'} = { title => loc('Reply'),
+                        path  => "Ticket/Update.html?Action=Respond&id=" . $id,
+    };
+}
+
+if ( $Ticket->CurrentUserHasRight('ModifyTicket') ) {
+    if ( $Ticket->Status ne 'resolved' ) {
+        $actions->{'B'} = {
+
+            path => "Ticket/Update.html?Action=Comment&DefaultStatus=resolved&id=" . $id,
+            title => loc('Resolve') };
+    }
+    if ( $Ticket->Status ne 'open' ) {
+        $actions->{'C'} = { path => "Ticket/Display.html?Status=open&id=" . $id,
+                            title => loc('Open it') };
+    }
+}
+
+if ( $Ticket->CurrentUserHasRight('OwnTicket') ) {
+    if ( $Ticket->OwnerObj->id == $RT::Nobody->id ) {
+        $actions->{'D'} = { path => "Ticket/Display.html?Action=Take&id=" . $id,
+                            title => loc('Take') };
+    }
+    elsif ( $Ticket->OwnerObj->id != $session{CurrentUser}->id ) {
+        $actions->{'E'} = {path => "Ticket/Display.html?Action=Steal&id=" . $id,
+                           title => loc('Steal') };
+    }
+}
+
+if (    $Ticket->CurrentUserHasRight('ModifyTicket')
+     or $Ticket->CurrentUserHasRight('CommentOnTicket') ) {
+    $actions->{'F'} = { title => loc('Comment'),
+                        path  => "Ticket/Update.html?Action=Comment&id=" . $id,
+    };
+}
+}
+$tabs->{"g"} = { path      => 'Search/Listing.html',
+                 title     => loc('Search'),
+                 separator => 1,
+                 subtabs   => $searchtabs };
+</%INIT>
+
+  
+<%ARGS>
+$Ticket => undef
+$subtabs => undef
+$current_tab => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Ticket/History.html b/rt/html/Ticket/History.html
new file mode 100644 (file)
index 0000000..cb02f1c
--- /dev/null
@@ -0,0 +1,52 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc("Ticket History # [_1] [_2]", $Ticket->Id, $Ticket->Subject) &>
+<& /Ticket/Elements/Tabs, 
+    Ticket => $Ticket, current_tab => 'Ticket/History.html?id='.$Ticket->id, 
+    Title => loc("Ticket History # [_1] [_2]", $Ticket->Id, $Ticket->Subject) &>
+
+<BR>
+      
+<& /Ticket/Elements/ShowHistory , Ticket => $Ticket, ShowHeaders => $ARGS{'ShowHeaders'}, URIFile => 'History.html' &> 
+
+
+<%ARGS>
+$id => undef
+</%ARGS>
+
+<%INIT>
+
+  
+
+my $Ticket = LoadTicket ($id);
+
+unless ($Ticket->CurrentUserHasRight('ShowTicket')) {
+       Abort("No permission to view ticket");
+}
+
+</%INIT>
+
+
+
+
diff --git a/rt/html/Ticket/Modify.html b/rt/html/Ticket/Modify.html
new file mode 100644 (file)
index 0000000..c97fd09
--- /dev/null
@@ -0,0 +1,63 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc('Modify ticket #[_1]', $TicketObj->Id) &>
+<& /Ticket/Elements/Tabs, 
+    Ticket => $TicketObj, current_subtab => "Ticket/Modify.html?id=".$TicketObj->Id, 
+    Title => loc('Modify ticket #[_1]', $TicketObj->Id) &>
+
+<& /Elements/ListActions, actions => \@results &>
+<FORM METHOD=POST ACTION="Modify.html">
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$TicketObj->Id%>">
+
+<& /Elements/TitleBoxStart, title => loc('Modify ticket #[_1]',$TicketObj->Id),   color=> "#993333", width => "100%" &>
+<& Elements/EditBasics, TicketObj => $TicketObj &>
+<& Elements/EditCustomFields, TicketObj => $TicketObj &>
+<& /Elements/TitleBoxEnd &>
+
+<& /Elements/Submit, Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), color => "#993333" &>
+</form>
+<%INIT>
+  
+my $TicketObj = LoadTicket($id);
+my $CustomFields = $TicketObj->QueueObj->CustomFields();
+
+# Now let callbacks have a chance at editing %ARGS
+$m->comp('/Elements/Callback', TicketObj => $TicketObj, CustomFields => $CustomFields, %ARGS);
+
+my @results = ProcessTicketBasics(TicketObj => $TicketObj, ARGSRef => \%ARGS);
+my @cf_results = ProcessTicketCustomFieldUpdates(ARGSRef => \%ARGS);
+push (@results, @cf_results);
+
+# TODO: display the results, even if we can't display the ticket
+
+unless ($TicketObj->CurrentUserHasRight('ShowTicket')) {
+    Abort("No permission to view ticket");
+} 
+
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Ticket/ModifyAll.html b/rt/html/Ticket/ModifyAll.html
new file mode 100644 (file)
index 0000000..a506893
--- /dev/null
@@ -0,0 +1,158 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc("Ticket #[_1] Jumbo update: [_2]", $Ticket->Id, $Ticket->Subject) &>
+<& /Ticket/Elements/Tabs, 
+    Ticket => $Ticket, 
+    current_tab => "Ticket/ModifyAll.html?id=".$Ticket->Id, 
+    Title => loc("Ticket #[_1] Jumbo update: [_2]", $Ticket->Id, $Ticket->Subject) &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<FORM METHOD=POST ACTION="ModifyAll.html" ENCTYPE="multipart/form-data">
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$Ticket->Id%>">
+
+
+<& /Elements/TitleBoxStart, title => loc('Modify ticket # [_1]', $Ticket->Id),   color=> "#993333", width => "100%" &>
+<& Elements/EditBasics, TicketObj => $Ticket &>
+<& Elements/EditCustomFields, TicketObj => $Ticket &>
+<& /Elements/TitleBoxEnd &>
+
+<BR>
+
+<& /Elements/TitleBoxStart, title => loc('Dates'),  width => "100%", color => "#663366"  &>
+<& Elements/EditDates, TicketObj => $Ticket &>
+<& /Elements/TitleBoxEnd &>
+
+<BR>
+
+
+<& /Elements/TitleBoxStart, title => loc('People'),width => "100%", color=> "#333399" &>
+<& Elements/EditPeople, Ticket => $Ticket, UserField => $UserField, UserString => $UserString, UserOp => $UserOp &>
+<& /Elements/TitleBoxEnd &>
+
+<BR>
+
+<& /Elements/TitleBoxStart, title => loc('Relationships'), color => "#336633"&>
+<& Elements/EditLinks, Ticket => $Ticket &>
+<& /Elements/TitleBoxEnd &>
+
+<BR>
+
+<& /Elements/TitleBoxStart, title => loc('Update ticket') &>
+<table>
+  <tr>
+    <td class="label"><&|/l&>Update Type</&>:</td>
+    <td class="entry">
+      <select name="UpdateType">
+% if ($CanComment) {
+        <option value="private" ><&|/l&>Comments (Not sent to requestors)</&></option>
+% }
+% if ($CanRespond) {
+        <option value="response"><&|/l&>Response to requestors</&></option>
+% }
+      </select> 
+    </td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>Subject</&>:</td>
+    <td class="entry"><input name="UpdateSubject" size=60 value=""></td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>Attach</&>:</td>
+    <td class="entry"><input name="UpdateAttachment" type=file></td>
+  </tr>
+  <tr>
+    <td class="labeltop"><&|/l&>Content</&>:</td>
+    <td class="entry"><& /Elements/MessageBox, Name=>"UpdateContent", QuoteTransaction=>$ARGS{QuoteTransaction} &></td>
+  </tr>
+</table>
+<& /Elements/TitleBoxEnd &>
+  
+
+<& /Elements/Submit, Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), color => "#333399" &>
+</form>
+
+<%INIT>
+
+
+
+my $Ticket = LoadTicket($id);
+
+my $CanRespond = 0;
+my $CanComment = 0;
+
+
+$CanRespond = 1 if ( $Ticket->CurrentUserHasRight('ReplyToTicket') or
+                     $Ticket->CurrentUserHasRight('ModifyTicket') ); 
+
+$CanComment = 1 if ( $Ticket->CurrentUserHasRight('CommentOnTicket') or
+                     $Ticket->CurrentUserHasRight('ModifyTicket') );
+
+
+my (@wresults, @results,  @dresults, @lresults, @cf_results);
+
+unless ($OnlySearchForPeople) {
+    @wresults = ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS);
+    @results = ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS);
+ @cf_results = ProcessTicketCustomFieldUpdates(ARGSRef => \%ARGS);
+    @dresults = ProcessTicketDates( TicketObj => $Ticket, ARGSRef => \%ARGS);
+    @lresults = ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS);
+
+    $ARGS{'UpdateContent'} =~ s/\r\n/\n/g;
+
+    if ($ARGS{'UpdateContent'} && 
+       $ARGS{'UpdateContent'} ne '' && 
+       $ARGS{'UpdateContent'} ne  "-- \n" . 
+                               $session{'CurrentUser'}->UserObj->Signature
+       ) {
+        ProcessUpdateMessage(TicketObj => $Ticket, 
+                             ARGSRef=>\%ARGS, 
+                              Actions=>\@results);
+       }
+}
+push @results, @wresults;
+push @results, @dresults;
+push @results, @lresults;
+push @results, @cf_results;
+
+# If they've gone and moved the ticket to somewhere they can't see, etc...
+# TODO: display the results, even if we can't display the ticket.
+
+unless ($Ticket->CurrentUserHasRight('ShowTicket')) {
+   Abort("No permission to view ticket");
+}
+
+
+</%INIT>
+
+
+
+<%ARGS>
+$OnlySearchForPeople => undef
+$UserField => undef
+$UserOp => undef
+$UserString => undef
+$id => undef
+</%ARGS>
+
diff --git a/rt/html/Ticket/ModifyDates.html b/rt/html/Ticket/ModifyDates.html
new file mode 100644 (file)
index 0000000..3ccae44
--- /dev/null
@@ -0,0 +1,52 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc('Modify dates for #[_1]', $TicketObj->Id) &>
+<& /Ticket/Elements/Tabs, 
+    Ticket => $TicketObj, 
+    current_tab => "Ticket/ModifyDates.html?id=".$TicketObj->Id, 
+    Title => loc('Modify dates for #[_1]', $TicketObj->Id) &> 
+
+<& /Elements/ListActions, actions => \@results &>
+
+<FORM METHOD=POST ACTION="ModifyDates.html">
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$TicketObj->Id%>">
+<& /Elements/TitleBoxStart, title => loc('Modify dates for ticket # [_1]', $TicketObj->Id),  width => "100%", color => "#663366"  &>
+
+<& Elements/EditDates, TicketObj => $TicketObj &>
+<& /Elements/TitleBoxEnd &>
+<& /Elements/Submit, color => "#663366" &>
+</form>
+
+
+<%INIT>
+
+my $TicketObj = LoadTicket($id);
+my @results = ProcessTicketDates( TicketObj => $TicketObj, ARGSRef => \%ARGS);
+
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Ticket/ModifyLinks.html b/rt/html/Ticket/ModifyLinks.html
new file mode 100644 (file)
index 0000000..1d05008
--- /dev/null
@@ -0,0 +1,54 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc("Link ticket #[_1]", $Ticket->Id) &>
+<& /Ticket/Elements/Tabs, 
+    Ticket => $Ticket, 
+    current_tab => "Ticket/ModifyLinks.html?id=".$Ticket->Id, 
+    Title => loc("Link ticket #[_1]", $Ticket->Id) &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<form action="ModifyLinks.html" method="post">
+<input type="hidden" name="id" value="<%$Ticket->id%>">
+
+<& /Elements/TitleBoxStart, title => loc('Edit Relationships'), color => "#336633"&>
+<& Elements/EditLinks, Ticket => $Ticket &>
+<& /Elements/TitleBoxEnd &>
+<& /Elements/Submit, color => "#336633", Caption=> loc('Save Changes') &>
+</form>
+
+
+
+
+<%INIT>
+  
+my $Ticket = LoadTicket($id);
+my @results = ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS);
+    
+</%INIT>
+      
+      
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Ticket/ModifyPeople.html b/rt/html/Ticket/ModifyPeople.html
new file mode 100644 (file)
index 0000000..2e41664
--- /dev/null
@@ -0,0 +1,67 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc('Modify people related to ticket #[_1]', $Ticket->id) &>
+<& /Ticket/Elements/Tabs, 
+    Ticket => $Ticket, 
+    current_tab => "Ticket/ModifyPeople.html?id=".$Ticket->Id, 
+    Title => loc('Modify people related to ticket #[_1]', $Ticket->id) &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<FORM METHOD=POST ACTION="ModifyPeople.html">
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$Ticket->Id%>">
+<& /Elements/TitleBoxStart, title => loc('Modify people related to ticket #[_1]', $Ticket->Id),   width => "100%", color=> "#333399" &>
+<& Elements/EditPeople, Ticket => $Ticket, UserField => $UserField, UserString => $UserString, UserOp => $UserOp, GroupString => $GroupString, GroupOp => $GroupOp, GroupField => $GroupField &> 
+<& /Elements/TitleBoxEnd &>
+<& /Elements/Submit, Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), color => "#333399" &>
+</form>
+
+<%INIT>
+
+my (@results, @wresults);
+
+my $Ticket = LoadTicket($id);
+
+# if we're trying to search for watchers and nothing else
+unless ($OnlySearchForPeople) {
+    @results = ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS);
+    @wresults = ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS);
+}
+
+push @results, @wresults;
+</%INIT>
+
+
+
+<%ARGS>
+$OnlySearchForPeople => undef
+$UserField => undef
+$UserOp => undef
+$UserString => undef
+$GroupField => undef
+$GroupOp => undef
+$GroupString => undef
+$id => undef
+</%ARGS>
+
diff --git a/rt/html/Ticket/Update.html b/rt/html/Ticket/Update.html
new file mode 100644 (file)
index 0000000..e19aacf
--- /dev/null
@@ -0,0 +1,205 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => $title &>
+<& /Ticket/Elements/Tabs, 
+    Ticket => $Ticket , 
+    Title=> $title &>
+
+<FORM ACTION="Update.html" NAME="TicketUpdate" 
+       METHOD=POST enctype="multipart/form-data">
+<input type="hidden" name="QuoteTransaction" value="<% $ARGS{QuoteTransaction} %>">
+<input type="hidden" name="DefaultStatus" value="<% $DefaultStatus %>">
+<input type="hidden" name="Action" value="<% $ARGS{Action} %>">
+<font size=-1>
+
+<TABLE>
+<TR><TD>
+<a href="ModifyPeople.html?id=<%$Ticket->Id%>"><&|/l&>Ticket watchers</&></A></TD><TD align=right>
+<&|/l&>Requestor</&>:
+</TD><TD>
+<b><% $Ticket->RequestorAddresses %></b>
+</TD></TR>
+<TR><TD>&nbsp;</TD><TD align=right>
+<&|/l&>Cc</&>:
+</TD><TD>
+<b><% $Ticket->CcAddresses %></b>
+</TD></TR>
+<TR><TD>&nbsp;</TD><TD align=right>
+<&|/l&>AdminCc</&>:
+</TD><TD>
+<b><% $Ticket->AdminCcAddresses %></b>
+</TD></TR>
+</TR>
+</TABLE>
+<hr>
+
+<TABLE BORDER=0>
+
+<tr><td align=right><&|/l&>Status</&>:</td>
+<td>
+<& /Elements/SelectStatus, Name=>"Status", Default => $DefaultStatus &>
+<&|/l&>Owner</&>:  
+<& /Elements/SelectOwner, Name=>"Owner", Default => ($ARGS{'Owner'} || $Ticket->OwnerObj->Id()), QueueObj => $Ticket->QueueObj, TicketObj => $Ticket &>
+<&|/l&>Worked</&>: <input size=4 name="UpdateTimeWorked" value="<% $ARGS{UpdateTimeWorked}%>"> <&|/l&>minutes</&></td></tr>
+<tr><td align=right><&|/l&>Update Type</&>:</td>
+<td><select name="UpdateType">
+% if ($CanComment) {
+  <option value="private" <%$CommentDefault%>><&|/l&>Comments (Not sent to requestors)</&></option>
+% }
+% if ($CanRespond) {
+   <option value="response" <%$ResponseDefault%>><&|/l&>Response to requestors</&></option>
+% }
+</select> 
+</td></tr>
+<tr><td align=right><&|/l&>Subject</&>:</td><td> <input name="UpdateSubject" size=60 value="<% ($ARGS{UpdateSubject}) ? $ARGS{UpdateSubject} : $Ticket->Subject()%>"></td></tr>
+<tr><td align=right><&|/l&>Cc</&>:</td><td> <input name="UpdateCc" size=60
+value=<% $ARGS{UpdateCc} %>><BR>
+<i><font size=-2>
+<&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)</&></font></i>
+</td></tr>
+<tr><td align=right><&|/l&>Bcc</&>:</td><td> <input name="UpdateBcc" size=60 VALUE="<%$ARGS{UpdateBcc}%>"><BR>
+<i><font size=-2>
+<&|/l&>(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)</&></font></i>
+</td></tr>
+% if (exists $session{'Attachments'}) {
+<TD>
+<&|/l&>Attached file</&>:
+</TD>
+<TD COLSPAN=5>
+<&|/l&>Check box to delete</&><BR>
+% foreach my $attach_name (keys %{$session{'Attachments'}}) {
+<input type="checkbox" name="DeleteAttach-<%$attach_name%>"><%$attach_name%><BR>
+% } # end of foreach
+</TD>
+</TR>
+<TR>
+% } # end of if
+<tr><td align=right><&|/l&>Attach</&>:</td><td><input name="Attach" type="file"><INPUT TYPE=SUBMIT NAME="AddMoreAttach" VALUE="<&|/l&>Add More Files</&>"><input type="hidden" name="UpdateAttach" value="1">
+</td></tr>
+<tr><td align="right" valign="top"><&|/l&>Message</&>:</td><td>
+<& /Elements/Callback, _CallbackName => 'BeforeMessageBox', %ARGS &>
+% if (exists $ARGS{UpdateContent}) {
+% delete $ARGS{'QuoteTransaction'};
+<& /Elements/MessageBox, Name=>"UpdateContent", Default=>$ARGS{UpdateContent}, %ARGS&>
+% } else {
+<& /Elements/MessageBox, Name=>"UpdateContent", %ARGS &>
+% }
+</td></tr>
+               <INPUT TYPE=HIDDEN NAME=id VALUE="<%$Ticket->Id%>"><br>
+</table>
+
+
+
+
+<& /Elements/Submit, Name => 'SubmitTicket' &>
+  </FORM>
+
+
+
+<%INIT>
+
+my $CanRespond = 0;
+my $CanComment = 0;
+my $title;
+
+my $Ticket = LoadTicket($id);
+
+unless($DefaultStatus){
+    $DefaultStatus=($ARGS{'Status'} ||$Ticket->Status());
+}
+
+if ($DefaultStatus =~ '^new$'){
+        $DefaultStatus='open';
+}
+
+if ($DefaultStatus eq 'resolved') {
+    $title = loc("Resolve ticket #[_1] ([_2])", $Ticket->id, $Ticket->Subject);
+} else {
+    $title = loc("Update ticket #[_1] ([_2])", $Ticket->id, $Ticket->Subject);
+}
+
+# Things needed in the template - we'll do the processing here, just
+# for the convenience:
+
+my ($CommentDefault, $ResponseDefault);
+if (($Action eq 'Comment') or ($ARGS{'UpdateType'} eq 'private')) {
+   $CommentDefault = "SELECTED"; 
+} else {
+    $ResponseDefault = "SELECTED";
+}
+
+
+$CanRespond = 1 if ( $Ticket->CurrentUserHasRight('ReplyToTicket') or
+                     $Ticket->CurrentUserHasRight('ModifyTicket') ); 
+
+$CanComment = 1 if ( $Ticket->CurrentUserHasRight('CommentOnTicket') or
+                     $Ticket->CurrentUserHasRight('ModifyTicket') ); 
+
+
+# {{{ deal with deleting uploaded attachments
+foreach my $key (keys %ARGS) {
+    if ($key =~ m/^DeleteAttach-(.+)$/) {
+       delete $session{'Attachments'}{$1};
+    }
+    $session{'Attachments'} = { %{$session{'Attachments'} || {}} };
+}
+
+# {{{ store the uploaded attachment in session
+if ($ARGS{'Attach'}) {                 # attachment?
+    $session{'Attachments'} = {} unless defined $session{'Attachments'};
+
+    my $subject = "$ARGS{'Attach'}";
+    # since CGI.pm deutf8izes the magic field, we need to add it back.
+    Encode::_utf8_on($subject);
+    # strip leading directories
+    $subject =~ s#^.*[\\/]##;
+
+    my $attachment = MakeMIMEEntity(
+        Subject             => $subject,
+        Body                => "",
+        AttachmentFieldName => 'Attach'
+    );
+
+    $session{'Attachments'} = { %{$session{'Attachments'} || {}},
+                               $ARGS{'Attach'} => $attachment };
+}
+# }}}
+
+# delete temporary storage entry to make WebUI clean
+unless (keys %{$session{'Attachments'}} and $ARGS{'UpdateAttach'}) {
+    delete $session{'Attachments'};
+}
+# }}}
+
+if ( exists $ARGS{SubmitTicket} ) {
+    $m->comp('Display.html', %ARGS);
+    return;
+}
+</%INIT>
+
+<%ARGS>
+$id => undef
+$Action => undef
+$DefaultStatus => undef
+</%ARGS>
diff --git a/rt/html/User/Delegation.html b/rt/html/User/Delegation.html
new file mode 100644 (file)
index 0000000..c036f78
--- /dev/null
@@ -0,0 +1,83 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc("Delegate rights") &>
+<& /User/Elements/Tabs, 
+    current_tab => 'User/Delegation.html', 
+    Title => loc("Delegate rights") &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post">
+<& Elements/DelegateRights, personalgroups => $personalgroups, objects => $objects, ObjectType => 'RT::System' &>
+<& Elements/DelegateRights, personalgroups => $personalgroups, objects => $objects, ObjectType => 'RT::Queue' &>
+<& Elements/DelegateRights, personalgroups => $personalgroups, objects => $objects, ObjectType => 'RT::Group' &>
+
+<& /Elements/Submit &>
+</form>
+<%INIT>
+
+my (@results, $arg);
+foreach $arg (keys %ARGS) {
+    next unless ($arg =~ /^Delegate-Existing-ACE-(\d+)-to-(\d+)-as-(\d+)$/);
+       my $parent = $1;
+       my $principal = $2;
+       my $delegation = $3;
+       unless ($ARGS{"Delegate-ACE-$1-to-$2"}) {
+            my $ace_to_del = RT::ACE->new($session{'CurrentUser'});
+            $ace_to_del->Load($delegation);
+            my ($delval, $delmsg) = $ace_to_del->Delete();
+            push (@results, $delmsg);
+       }
+}
+
+foreach $arg (keys %ARGS) { 
+    next unless ($arg =~ /^Delegate-ACE-(\d+)-to-(\d+)$/);
+    my $parent = $1;
+    my $principal = $2;
+    # if we already delegate it, we just don't care
+    next if (grep /^Delegate-Existing-ACE-$parent-to-$principal-/, keys %ARGS);
+    my $ace = RT::ACE->new($session{'CurrentUser'});
+    $ace->Load($1);
+    unless ($ace->Id) {
+        push (@results, loc('Right not found'));
+        next;
+    }
+    my ($delid, $delmsg) = $ace->Delegate(PrincipalId => $principal);
+    push (@results, $delmsg);
+}
+
+my $personalgroups = RT::Groups->new($session{'CurrentUser'});
+$personalgroups->LimitToPersonalGroupsFor($session{'CurrentUser'}->PrincipalId);
+
+my $objects;
+my $acl = RT::ACL->new ($session{'CurrentUser'});
+$acl->ExcludeDelegatedRights();
+$acl->LimitToPrincipal(Id => $session{'CurrentUser'}->PrincipalId, 
+                       IncludeGroupMembership => 1
+                       );
+
+while(my $right = $acl->Next) {
+       push @{$objects->{$right->ObjectType}{$right->ObjectId}},$right;
+}
+</%INIT>
diff --git a/rt/html/User/Elements/DelegateRights b/rt/html/User/Elements/DelegateRights
new file mode 100644 (file)
index 0000000..7ff8328
--- /dev/null
@@ -0,0 +1,85 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<h2><%$sectionheading%></h2>
+<%perl>
+
+foreach my $object (keys %{$objects->{$ObjectType}}) {
+unless ($ObjectType eq 'RT::System') {
+my $object_obj = @{$objects->{$ObjectType}{$object}}[0]->Object;
+
+</%perl>
+<h3><% $object_obj->Name %></h3>
+% }
+<table width="100%" border="0" cellspacing="0" cellpadding="3">
+<tr>
+        <th width=15%><&|/l&>Personal groups:</&></th>
+% while (my $pg = $personalgroups->Next) {
+<th><%$pg->Name%></th>
+% }
+</tr>
+<%perl>
+my $i;
+foreach my $right (@{$objects->{$ObjectType}{$object}}) {
+my $delegations = RT::ACL->new($session{'CurrentUser'});
+$delegations->DelegatedBy( Id => $session{'CurrentUser'}->PrincipalId);
+$delegations->DelegatedFrom ( Id => $right->Id);
+
+my $del_hash = {};
+while ( my $delegation = $delegations->Next) {
+        $del_hash->{$delegation->PrincipalId} = $delegation;
+}
+</%perl>
+% $i++;
+%
+<tr class="<%($i%2) && 'oddline'%>">
+<td>
+<% loc($right->RightName) %><br>
+<div align=right><font size="-2" color="#999999"><&|/l, $right->PrincipalObj->Object->SelfDescription &>as granted to [_1]</&></font></div>
+       </td>
+% while (my $pg = $personalgroups->Next) {
+<td align=center>
+        <input name="Delegate-ACE-<% $right->Id %>-to-<% $pg->PrincipalId%>" type=checkbox <%$ del_hash->{$pg->PrincipalId} && 'CHECKED' %>>
+% if ( $del_hash->{$pg->PrincipalId}) {
+<input type=hidden name="Delegate-Existing-ACE-<% $right->Id %>-to-<% $pg->PrincipalId%>-as-<%$del_hash->{$pg->PrincipalId}->Id%>">
+% }
+</td>
+% }
+<td>&nbsp;</td>
+</tr>
+%}
+</table> 
+% }
+<%init>
+
+my $sectionheading = loc("[_1] rights", loc($ObjectType =~ /^RT::(.*)$/));
+# 'System' # loc
+# 'Group'  # loc
+# 'Queue'  # loc
+
+</%init>
+<%args>
+$ObjectType => undef
+$objects => undef
+$personalgroups => undef
+</%args>
diff --git a/rt/html/User/Elements/GroupTabs b/rt/html/User/Elements/GroupTabs
new file mode 100644 (file)
index 0000000..89d7125
--- /dev/null
@@ -0,0 +1,60 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /User/Elements/Tabs, 
+    subtabs => $tabs, 
+    current_tab => 'User/Groups/', 
+    current_subtab => $current_subtab, 
+    Title => $Title &>
+
+<%INIT>
+my $tabs;
+if ( $GroupObj and $GroupObj->id ) {
+    $tabs->{"this"} = {
+        title   => $GroupObj->Name,
+        path    => "User/Groups/Modify.html?id=" . $GroupObj->id,
+        subtabs => {
+            Basics => { title => loc('Basics'),
+                        path  => "User/Groups/Modify.html?id=" . $GroupObj->id
+            },
+
+            Members => { title => loc('Members'),
+                         path  => "User/Groups/Members.html?id=" . $GroupObj->id
+            },
+
+        } };
+        $tabs->{'this'}->{'current_subtab'} = $current_subtab;
+         $current_subtab = "User/Groups/Modify.html?id=" . $GroupObj->id,
+}
+$tabs->{"A"} = { title => loc('Select group'),
+                 path  => "User/Groups/index.html" };
+$tabs->{"B"} = { title     => loc('New group'),
+                 path      => "User/Groups/Modify.html?Create=1",
+                 separator => 1 };
+
+</%INIT>
+<%ARGS>
+$GroupObj => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/User/Elements/Tabs b/rt/html/User/Elements/Tabs
new file mode 100644 (file)
index 0000000..195cf1c
--- /dev/null
@@ -0,0 +1,56 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Tabs, 
+    tabs => $tabs, 
+    current_toptab => 'User/Prefs.html', 
+    current_tab => $current_tab, 
+    Title => $Title &>
+
+<%INIT>
+  my $tabs = { a => { title => loc('About me'),
+                         path => 'User/Prefs.html',
+                       },
+              g => { title => loc('Personal Groups'),
+                          path => 'User/Groups/',
+                        },
+              h => { title => loc('Delegation'),
+                          path => 'User/Delegation.html',
+                        },
+            };
+
+  foreach my $tab (sort keys %{$tabs}) {
+    if ($tabs->{$tab}->{'path'} eq $current_tab) {
+      $tabs->{$tab}->{"subtabs"} = $subtabs;
+      $tabs->{$tab}->{"current_subtab"} = $current_subtab;
+    }
+  }
+</%INIT>
+
+
+<%ARGS>
+$subtabs => undef
+$current_tab => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/User/Groups/Members.html b/rt/html/User/Groups/Members.html
new file mode 100644 (file)
index 0000000..db83b8c
--- /dev/null
@@ -0,0 +1,136 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => $title &>
+<& /User/Elements/GroupTabs, 
+    GroupObj => $Group, 
+    current_subtab => "User/Groups/Members.html?id=".$Group->id, 
+    Title => $title &>
+<& /Elements/ListActions, actions => \@results &>
+
+
+
+<FORM ACTION="<%$RT::WebPath%>/User/Groups/Members.html" METHOD="POST">
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$Group->Id%>">
+<TABLE WIDTH="100%">
+<TR>
+<TD>
+<&|/l&>Add members</&>
+</TD>
+<TD>
+<&|/l&>Current members</&>
+</TD>
+</TR>
+
+<TR>
+<TD VALIGN=TOP>
+<& /Admin/Elements/SelectNewGroupMembers, Name => "AddMembers", Group => $Group &>
+</TD>
+<TD VALIGN=TOP>
+
+% if ($Group->MembersObj->Count == 0 ) {
+<i><&|/l&>(No members)</&></i>
+% } else {
+<i><&|/l&>(Check box to delete)</&></i>
+<br>
+<br>
+<&|/l&>Users</&>
+% my $UserMembers = $Group->MembersObj;
+% $UserMembers->LimitToUsers();
+<UL>
+% while (my $member = $UserMembers->Next()) {
+<LI><INPUT TYPE=CHECKBOX Name="DeleteMember-<%$member->MemberId%>">
+<%$member->MemberObj->Object->Name%> (<%$member->MemberObj->Object->RealName%>)
+% }
+</ul>
+<&|/l&>Groups</&>
+<ul>
+% my $GroupMembers = $Group->MembersObj;
+% $GroupMembers->LimitToGroups();
+% while (my $member = $GroupMembers->Next()) {
+<LI><INPUT TYPE=CHECKBOX Name="DeleteMember-<%$member->MemberId%>">
+<%$member->MemberObj->Object->Name%>
+% }
+% }
+</UL>
+</TD>
+</TR>
+</TABLE>
+<& /Elements/Submit &>
+</form>
+
+
+<%INIT>
+
+my $Group = new RT::Group($session{'CurrentUser'});
+$Group->Load($id) ;
+
+unless ($Group->id) {
+    Abort(loc('Could not load group'));
+}
+
+my (@results);
+
+foreach my $key (keys %ARGS) {
+
+if ($key =~ /^DeleteMember-(\d+)$/) {
+    my $mem_id = $1; 
+    my ($val,$msg) = $Group->DeleteMember($mem_id);
+    push (@results, $msg);
+}
+}
+
+# Make sure AddMembers is always an array
+my @AddMembersUsers = (ref $AddMembersUsers eq 'ARRAY') ? @{$AddMembersUsers} : ($AddMembersUsers);
+my @AddMembersGroups = (ref $AddMembersGroups eq 'ARRAY') ? @{$AddMembersGroups} : ($AddMembersGroups);
+
+foreach my $member (@AddMembersUsers, @AddMembersGroups) {
+    next unless ($member);
+
+    my $principal;
+
+    if ($member =~ /^Group-(\d+)$/) {
+        $principal = RT::Group->new($session{'CurrentUser'});
+        $principal->Load($1);
+    } elsif ($member =~ /^User-(\d+)$/) {
+        $principal = RT::User->new($session{'CurrentUser'});
+        $principal->Load($1);
+    } else {
+        next;
+    }
+
+
+    my ($val, $msg) = $Group->AddMember($principal->PrincipalId);
+    push (@results, $msg);
+}
+
+
+my $title = loc('Editing membership for personal group [_1]', $Group->Name);
+
+</%INIT>
+
+<%ARGS>
+$AddMembersUsers => undef
+$AddMembersGroups => undef
+$id => undef
+</%ARGS>
diff --git a/rt/html/User/Groups/Modify.html b/rt/html/User/Groups/Modify.html
new file mode 100644 (file)
index 0000000..f731e1a
--- /dev/null
@@ -0,0 +1,133 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => $title &>
+
+<& /User/Elements/GroupTabs, 
+    GroupObj => $Group, 
+    current_subtab => $current_tab, 
+    Title => $title &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+
+<FORM ACTION="<%$RT::WebPath%>/User/Groups/Modify.html" METHOD=POST>
+
+%unless ($Group->Id) {
+<INPUT TYPE=HIDDEN NAME=id VALUE="new">
+% } else {
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$Group->Id%>">
+% }
+<TABLE>
+<TR><TD ALIGN=RIGHT>
+<&|/l&>Name</&>:
+</TD>
+<TD><INPUT name="Name" value="<%$Group->Name%>"></TD>
+</TR><TR>
+<TD ALIGN=RIGHT>
+<&|/l&>Description</&>:</TD><TD COLSPAN=3><INPUT name="Description" value="<%$Group->Description%>" size=60></TD>
+</TR><TR>
+<TD COLSPAN=2>
+<INPUT TYPE=HIDDEN NAME="SetEnabled" VALUE="1">
+<INPUT TYPE=CHECKBOX NAME="Enabled" VALUE="1" <%$EnabledChecked%>> <&|/l&>Enabled (Unchecking this box disables this group)</&><BR>
+</TR>
+</TABLE>
+<& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+</form>
+<%INIT>
+
+my $current_tab;
+my  ($title, @results, $Disabled, $EnabledChecked);
+
+my $Group = RT::Group->new($session{'CurrentUser'});
+
+if ($Create) {
+    $current_tab = 'User/Groups/Modify.html?Create=1';
+    $title = loc("Create a new personal group");
+} 
+else {
+    if ( $id eq 'new' ) {
+
+        my ( $id, $msg ) = $Group->CreatePersonalGroup(
+                             Name        => "$Name",
+                             PrincipalId => $session{'CurrentUser'}->PrincipalId
+        );
+        unless ($id) {
+            Abort( loc("Could not create group") );
+        }
+        $id = $Group->Id;
+    }
+    else {
+        $Group->Load($id) || Abort( loc('Could not load group') );
+    }
+
+    if ($id) {
+        $title = loc( "Modify the group [_1]", $Group->Name );
+
+    }
+
+    # If the create failed
+    else {
+        $title  = loc("Create a new personal group");
+        $Create = 1;
+    }
+
+    $current_tab = 'User/Groups/Modify.html?id=' . $Group->Id;
+}
+
+if ($id) {
+    
+    my @fields = qw(Description Name );
+    my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields,
+                                           Object => $Group,
+                                           ARGSRef => \%ARGS );
+    push (@results,@fieldresults);
+}
+
+#we're asking about enabled on the web page but really care about disabled.
+if ($Enabled == 1) {
+    $Disabled = 0;
+}      
+else {
+    $Disabled = 1;
+}
+if  ( ($SetEnabled) and ( $Disabled != $Group->Disabled) ) { 
+    my  ($code, $msg) = $Group->SetDisabled($Disabled);
+    push @results, loc('Enabled status [_1]', loc_fuzzy($msg));
+}
+
+unless ($Group->Disabled()) {
+    $EnabledChecked ="CHECKED";
+}
+
+</%INIT>
+
+
+<%ARGS>
+$Create => undef
+$Name => undef
+$Description => undef
+$SetEnabled => undef
+$Enabled => undef
+$id => undef
+</%ARGS>
diff --git a/rt/html/User/Groups/index.html b/rt/html/User/Groups/index.html
new file mode 100644 (file)
index 0000000..12b43b4
--- /dev/null
@@ -0,0 +1,43 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => $title &>
+<& /User/Elements/GroupTabs, 
+    current_subtab => 'User/Groups/index.html', 
+    Title => $title &>
+
+<&|/l&>Personal groups</&>:<BR>
+<UL>
+%while ( my $Group = $Groups->Next) {
+<LI><A HREF="Modify.html?id=<%$Group->id%>"><%$Group->Name || loc('(empty)')%></a><BR>
+%}
+</UL>
+
+<%INIT>
+my $Groups = RT::Groups->new($session{'CurrentUser'});
+$Groups->LimitToPersonalGroupsFor($session{'CurrentUser'}->PrincipalId());
+my $title = loc('Personal groups');
+
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/User/Prefs.html b/rt/html/User/Prefs.html
new file mode 100644 (file)
index 0000000..b89fc40
--- /dev/null
@@ -0,0 +1,218 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title=>loc("Preferences") &>
+<& /User/Elements/Tabs, 
+    current_tab => 'User/Prefs.html', 
+    Title=>loc("Preferences") &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<FORM ACTION="<%$RT::WebPath%>/User/Prefs.html" METHOD=POST>
+<INPUT TYPE=HIDDEN NAME=id VALUE="<%$UserObj->Id%>">
+
+<TABLE WIDTH=100% BORDER=0>
+<TR>
+
+<TD VALIGN=TOP ROWSPAN=2>
+<& /Elements/TitleBoxStart, title => loc('Identity') &>
+
+<input type=hidden name="Name" value="<%$UserObj->Name%>">
+<&|/l&>Email</&>: <input name="EmailAddress" value="<%$UserObj->EmailAddress%>">
+<BR>
+<&|/l&>Real Name</&>: <input name="RealName" value="<%$UserObj->RealName%>"> 
+<BR>
+<&|/l&>Nickname</&>: <input name="NickName" value="<%$UserObj->NickName%>">
+<& /Elements/TitleBoxEnd &>
+<br>
+<& /Elements/TitleBoxStart, title => loc('Phone numbers') &>
+<&|/l&>Residence</&>: <input name="HomePhone" value="<%$UserObj->HomePhone%>" size=13>
+<BR>
+<&|/l&>Work</&>: <input name="WorkPhone" value="<%$UserObj->WorkPhone%>" size=13>
+<BR>
+<&|/l&>Mobile</&>: <input name="MobilePhone" value="<%$UserObj->MobilePhone%>" size=13>
+<BR>
+<&|/l&>Pager</&>: <input name="PagerPhone" value="<%$UserObj->PagerPhone%>" size=13>
+<& /Elements/TitleBoxEnd &>
+</TD>
+<TD VALIGN=TOP>
+% unless ($RT::WebExternalAuth and !$RT::WebFallbackToInternalAuth) {
+<& /Elements/TitleBoxStart, title => loc('Password') &>
+<TABLE>
+<TR>
+<TD ALIGN=RIGHT>
+<&|/l&>New Password</&>:
+</TD>
+<TD ALIGN=LEFT>
+<input type=password name="Pass1">
+</TD>
+</TR>
+<TR><TD ALIGN=RIGHT>
+<&|/l&>Retype Password</&>:
+</TD>
+<TD>
+<input type=password name="Pass2">
+</TD>
+</TR>
+</TABLE>
+% }
+<& /Elements/TitleBoxEnd &>
+</TD>
+<TR>
+
+<TD VALIGN=TOP>
+<& /Elements/TitleBoxStart, title => loc('Location') &>
+<&|/l&>Organization</&>: <input name="Organization" value="<%$UserObj->Organization%>">
+<BR>
+<&|/l&>Address1</&>: <input name="Address1" value="<%$UserObj->Address1%>">
+<BR>
+<&|/l&>Address2</&>: <input name="Address2" value="<%$UserObj->Address2%>">
+<BR>
+<&|/l&>City</&>: <input name="City" value="<%$UserObj->City%>" size=14>
+
+<&|/l&>State</&>: <input name="State" value="<%$UserObj->State%>" size=3>
+
+<&|/l&>Zip</&>: <input name="Zip" value="<%$UserObj->Zip%>" size=9>
+<BR>
+<&|/l&>Country</&>: <input name="Country" value="<%$UserObj->Country%>">
+<BR>
+
+
+<& /Elements/TitleBoxEnd &>
+</TD>
+</TR>
+<TR>
+
+
+
+<TD COLSPAN=2 VALIGN=TOP>
+%if ($UserObj->Privileged) {
+<BR>
+<& /Elements/TitleBoxStart, title => loc('Signature') &>
+<TEXTAREA COLS=80 ROWS=5 name="Signature" WRAP=HARD>
+<%$UserObj->Signature%></TEXTAREA>
+<& /Elements/TitleBoxEnd &>
+% }
+
+</TD>
+
+</TR>
+</TABLE>
+
+
+<& /Elements/Submit &>
+</form>
+
+
+<%INIT>
+
+my $UserObj = new RT::User($session{'CurrentUser'});
+my ($title, $PrivilegedChecked, $EnabledChecked, $Disabled, $result, @results);
+
+my ($val, $msg);
+
+
+       $UserObj->Load($id) || $UserObj->Load($Name) || Abort("Couldn't load user '$Name'");
+       $val = $UserObj->Id();
+    
+
+
+
+
+
+# If we have a user to modify, lets try. 
+if ($UserObj->Id) {
+    
+    my @fields = qw(Name Comments Signature EmailAddress FreeformContactInfo 
+                   Organization RealName NickName Lang EmailEncoding WebEncoding 
+                   ExternalContactInfoId ContactInfoSystem Gecos ExternalAuthId 
+                   AuthSystem HomePhone WorkPhone MobilePhone PagerPhone Address1
+               Address2 City State Zip Country 
+                  );
+    
+    my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields,
+                                           Object => $UserObj,
+                                           ARGSRef => \%ARGS );
+    push (@results,@fieldresults);
+
+
+# {{{ Deal with special fields: Privileged, Enabled and Password
+if  ( ($SetPrivileged) and ( $Privileged != $UserObj->Privileged) ) {
+my  ($code, $msg) = $UserObj->SetPrivileged($Privileged);
+     push @results, loc('Privileged status: [_1]', loc_fuzzy($msg));
+}
+
+
+
+#TODO: make this report errors properly
+if ((defined $Pass1) and ($Pass1 ne '') and ($Pass1 eq $Pass2) and (!$UserObj->IsPassword($Pass1))) {
+    my ($code, $msg);
+    ($code, $msg) = $UserObj->SetPassword($Pass1);
+    push @results, loc('Password: [_1]', loc_fuzzy($msg));
+} elsif ( $Pass1 && ($Pass1 ne $Pass2)) {
+    push @results, loc("Passwords do not match. Your password has not been changed");
+}
+
+# }}}
+}
+
+
+</%INIT>
+
+
+<%ARGS>
+$id => $session{'CurrentUser'}->Id
+$Name  => undef
+$Comments  => undef
+$Signature  => undef
+$EmailAddress  => undef
+$FreeformContactInfo => undef
+$Organization  => undef
+$RealName  => undef
+$NickName  => undef
+$Privileged => undef
+$SetPrivileged => undef
+$Enabled => undef
+$SetEnabled => undef
+$Lang  => undef
+$EmailEncoding  => undef
+$WebEncoding => undef
+$ExternalContactInfoId  => undef
+$ContactInfoSystem  => undef
+$Gecos => undef
+$ExternalAuthId  => undef
+$AuthSystem  => undef
+$HomePhone => undef
+$WorkPhone  => undef
+$MobilePhone  => undef
+$PagerPhone  => undef
+$Address1 => undef
+$Address2  => undef
+$City  => undef
+$State  => undef
+$Zip  => undef
+$Country => undef
+$Pass1 => undef
+$Pass2=> undef
+$Create=> undef
+</%ARGS>
diff --git a/rt/html/autohandler b/rt/html/autohandler
new file mode 100644 (file)
index 0000000..ce8b756
--- /dev/null
@@ -0,0 +1,178 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<%INIT>
+
+# Roll back any dangling transactions from a previous failed connection
+$RT::Handle->ForceRollback() if $RT::Handle->TransactionDepth;
+
+
+local *session;
+%ARGS = map {
+    # if they've passed multiple values, they'll be an array. if they've passed just one, a scalar
+    # whatever they are, mark them as utf8
+    my $type = ref($_);
+    (!$type)
+       ? Encode::decode(utf8 => $_, Encode::FB_PERLQQ) :
+    ($type eq 'ARRAY')
+       ? [ map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } @$_ ] :
+    ($type eq 'HASH')
+       ? { map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } %$_ } : $_
+} %ARGS;
+
+if ($ARGS{'Debug'}) {
+        require Time::HiRes;
+        $m->{'rt_base_time'} = [Time::HiRes::gettimeofday()];
+        
+}
+else {
+        $m->{'rt_base_time'} = time;
+}
+$m->comp('/Elements/SetupSessionCookie', %ARGS);
+
+unless ($session{'CurrentUser'} && $session{'CurrentUser'}->Id) {
+    $session{'CurrentUser'} = RT::CurrentUser->new();
+}
+
+# Set the proper encoding for the current language handle
+$r->content_type("text/html; charset=utf-8");
+
+# If it's a noauth file, don't ask for auth.
+if ($m->base_comp->path =~ '^/+NoAuth/' ||
+    $m->base_comp->path =~ '^/+REST/\d+\.\d+/NoAuth/')
+{
+    $m->call_next(%ARGS);
+    $m->abort();
+}
+
+# If RT is configured for external auth, let's get REMOTE_USER
+elsif ($RT::WebExternalAuth and length($ENV{'REMOTE_USER'})) {
+    my $orig_user = $user;
+
+    $user = $ENV{'REMOTE_USER'};
+    $session{'CurrentUser'} = RT::CurrentUser->new();
+    my $load_method = $RT::WebExternalGecos ? 'LoadByGecos' : 'Load';
+    
+    if ($^O eq 'MSWin32' and $RT::WebExternalGecos) {
+       my $NodeName = Win32::NodeName();
+       $user =~ s/^\Q$NodeName\E\\//i;
+    }
+
+    $session{'CurrentUser'}->$load_method($user);
+
+    if ($RT::WebExternalAuto and !$session{'CurrentUser'}->Id() ) {
+       # Create users on-the-fly with default attributes
+
+       my $UserObj = RT::User->new(RT::CurrentUser->new('root'));
+
+       my ($val, $msg) = $UserObj->Create(
+           %{ref($RT::AutoCreate) ? $RT::AutoCreate : {}},
+           Name         => $user,
+           Gecos        => $user,
+       );
+
+       if ($val) {
+           $UserObj->SetPrivileged(1);
+
+           if ($^O !~ /^(?:riscos|MacOS|MSWin32|dos|os2)$/) {
+               # Populate fields with information from Unix /etc/passwd
+
+               my ($comments, $realname) = (getpwnam($user))[5, 6];
+               $UserObj->SetComments($comments) if defined $comments;
+               $UserObj->SetRealName($realname) if defined $realname;
+           }
+           elsif ($^O eq 'MSWin32' and eval 'use Net::AdminMisc; 1') {
+               # Populate fields with information from NT domain controller
+           }
+
+           $session{'CurrentUser'}->Load($user);
+       }
+       else {
+           delete $session{'CurrentUser'};
+           $m->abort() unless $RT::WebFallbackToInternalAuth;
+           $m->comp('/Elements/Login', %ARGS, Error=> loc('Cannot create user: [_1]', $msg));
+       }
+    }
+
+    unless ( $session{'CurrentUser'}->Id() ) {
+        delete $session{'CurrentUser'};
+        $user = $orig_user;
+
+       if ( $RT::WebExternalOnly ) {           
+           $m->comp('/Elements/Login', %ARGS, Error=> loc('You are not an authorized user'));
+           $m->abort();
+       }
+    }
+}
+
+delete $session{'CurrentUser'}
+    unless $session{'CurrentUser'} and defined $session{'CurrentUser'}->Id;
+
+# Process per-page authentication callbacks
+$m->comp('/Elements/Callback', %ARGS, _CallbackName => 'Auth');
+
+# If the user is logging in, let's authenticate
+if (!$session{'CurrentUser'} && defined ($user) && defined ($pass) ){
+    $session{'CurrentUser'} = RT::CurrentUser->new();
+    $session{'CurrentUser'}->Load($user);
+
+    if (!$session{'CurrentUser'}->id() ||
+        !$session{'CurrentUser'}->IsPassword($pass))
+    {
+        delete $session{'CurrentUser'};
+        $m->comp('/Elements/Login', %ARGS,
+                 Error => loc('Your username or password is incorrect'));
+        $m->abort();
+    }
+}
+  
+# If we've got credentials, let's serve the file up.
+if ( (defined $session{'CurrentUser'}) and 
+     ( $session{'CurrentUser'}->Id) ) {
+    
+    # Process per-page global callbacks
+    $m->comp('/Elements/Callback', %ARGS);
+
+    # If the user isn't privileged, they can only see SelfService
+    if ((! $session{'CurrentUser'}->Privileged) and
+       ($m->base_comp->path !~ '^(/+)SelfService/') ) {
+       $m->comp('/SelfService/index.html');
+       $m->abort();
+    }
+    else {
+       $m->call_next(%ARGS);
+    }
+}
+
+# If we have no credentials
+else {
+    $m->comp('/Elements/Login', %ARGS);
+    $m->abort();
+}
+</%INIT>
+<& /Elements/Footer, %ARGS &>
+<%ARGS>
+$user => undef
+$pass => undef
+$menu => undef
+</%ARGS>
diff --git a/rt/html/index.html b/rt/html/index.html
new file mode 100644 (file)
index 0000000..39eac8d
--- /dev/null
@@ -0,0 +1,84 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Elements/Header, Title=>loc("RT at a glance"), Refresh => $session{'home_refresh_interval'} &>
+<& /Elements/Tabs, 
+    current_toptab => '', 
+    Title=>loc("RT at a glance") &>
+<TABLE BORDER=0 WIDTH=100%>
+<TR VALIGN=TOP>
+<TD WIDTH=70%>
+<& /Elements/MyTickets &>
+<BR>
+<& /Elements/MyRequests &>
+</TD>
+<TD>
+<& /Elements/Quicksearch &>
+<BR>
+<form method=get action="index.html">
+<& /Elements/Refresh, Name => 'HomeRefreshInterval', Default => $session {'home_refresh_interval'} &>
+<div align=right><input type=submit value="<&|/l&>Go!</&>"></div>
+</form>
+</TD>
+</TR>
+</TABLE>
+<%init>
+if ( $ARGS{'q'} ) {
+    my $query = $ARGS{'q'};
+
+    if ( $query =~ m/^\s*(\d+)\s*$/ ) {
+        $m->redirect("$RT::WebPath/Ticket/Display.html?id=$1");
+    }
+
+    $session{'tickets'} = RT::Tickets->new( $session{'CurrentUser'} );
+
+    if ( $query =~ m/\@/ ) {
+        $session{'tickets'}->LimitRequestor( VALUE    => $query,
+                                             OPERATOR => '=', );
+        $m->redirect("$RT::WebPath/Search/Listing.html");
+    }
+
+    #
+    # Any search on queue name or subject will be for new/open tickets
+    # only.
+    #
+    $session{'tickets'}->LimitStatus( VALUE    => $_,
+                                      OPERATOR => '=', ) for qw(open new);
+
+    my $queue = RT::Queue->new( $session{'CurrentUser'} );
+    if ( $queue->Load($query) && $queue->Id ) {
+        $session{'tickets'}->LimitQueue( VALUE    => $queue->Id,
+                                         OPERATOR => '=', );
+        $m->redirect("$RT::WebPath/Search/Listing.html");
+    }
+    $session{'tickets'}->LimitSubject( VALUE    =>  $query,
+                                       OPERATOR => 'LIKE' );
+
+    $m->redirect("$RT::WebPath/Search/Listing.html");
+}
+
+if ($ARGS{'HomeRefreshInterval'}) {
+       $session{'home_refresh_interval'} = $ARGS{'HomeRefreshInterval'};
+}
+
+</%init>
diff --git a/rt/html/l b/rt/html/l
new file mode 100644 (file)
index 0000000..712e38d
--- /dev/null
+++ b/rt/html/l
@@ -0,0 +1,26 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+% my $hand = ($session{'CurrentUser'} ||= RT::CurrentUser->new)->LanguageHandle;
+% $m->print($hand->maketext($m->content,@_));
+% return(1);
diff --git a/rt/install-sh b/rt/install-sh
new file mode 100644 (file)
index 0000000..11870f1
--- /dev/null
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       :
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+               chmodcmd=""
+       else
+               instcmd=$mkdirprog
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f "$src" ] || [ -d "$src" ]
+       then
+               :
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               :
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               :
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+       '
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               :
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               :
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/rt/lib/MANIFEST b/rt/lib/MANIFEST
deleted file mode 100644 (file)
index cda386b..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-MANIFEST
-MANIFEST.SKIP
-Makefile.PL
-RT.pm
-test.pl
-RT/ACE.pm
-RT/ACL.pm
-RT/Action/Generic.pm
-RT/Action/NotifyAsComment.pm
-RT/Action/OpenDependent.pm
-RT/Action/SendEmail.pm
-RT/Action/StallDependent.pm
-RT/Action/Notify.pm
-RT/Action/ResolveMembers.pm
-RT/Attachment.pm
-RT/Attachments.pm
-RT/Condition/AnyTransaction.pm
-RT/Condition/Generic.pm
-RT/Condition/NewDependency.pm
-RT/CurrentUser.pm
-RT/Date.pm
-RT/EasySearch.pm
-RT/Group.pm
-RT/GroupMember.pm
-RT/GroupMembers.pm
-RT/Groups.pm
-RT/Handle.pm
-RT/Interface/CLI.pm
-RT/Interface/Email.pm
-RT/Interface/Web.pm
-RT/Keyword.pm
-RT/Keywords.pm
-RT/KeywordSelect.pm
-RT/KeywordSelects.pm
-RT/Link.pm
-RT/Links.pm
-RT/ObjectKeyword.pm
-RT/ObjectKeywords.pm
-RT/Queue.pm
-RT/Queues.pm
-RT/Record.pm
-RT/Scrip.pm
-RT/Scrips.pm
-RT/ScripAction.pm
-RT/ScripActions.pm
-RT/ScripCondition.pm
-RT/ScripConditions.pm
-RT/Template.pm
-RT/Templates.pm
-RT/Ticket.pm
-RT/Tickets.pm
-RT/Transaction.pm
-RT/Transactions.pm
-RT/User.pm
-RT/Users.pm
-RT/Watcher.pm
-RT/Watchers.pm
diff --git a/rt/lib/MANIFEST.SKIP b/rt/lib/MANIFEST.SKIP
deleted file mode 100644 (file)
index ae335e7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-CVS/
diff --git a/rt/lib/Makefile.PL b/rt/lib/Makefile.PL
deleted file mode 100644 (file)
index c0e1af2..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-use ExtUtils::MakeMaker;
-# See lib/ExtUtils/MakeMaker.pm for details of how to influence
-# the contents of the Makefile that is written.
-WriteMakefile(
-    'NAME'      => 'RT',
-    'VERSION_FROM' => 'RT.pm', # finds $VERSION
-    'PREREQ_PM' => {
-                     'DBI'                 => 1.16,
-                     'DBIx::SearchBuilder' => '0.48',
-                     'Date::Parse'         => 0,
-                     'Date::Format'        => 0,
-                     'MIME::Entity'        => 5.108,
-                     'Mail::Mailer'        => '1.20',
-                     'Log::Dispatch'       => 1.6,
-                     'HTML::Entities'      => 0,
-                     'Text::Wrapper'       => 0,
-                     'Text::Template'      => 0,
-                    'Getopt::Long'        => 2.24,
-                   },
-);
-
-     {
-                   package MY;
-                   sub top_targets {
-                       my($self) = @_;
-                       my $out = "POD2TEST_EXE = pod2test\n";
-
-                       $out .= $self->SUPER::top_targets(@_);
-                       # $out =~ s/^(pure_all\b.*)/$1 testifypods/m;
-
-                       $out .= "\n\ntestifypods : \n";
-
-                       my @pods = (keys %{$self->{MAN1PODS}},
-                                    keys %{$self->{MAN3PODS}});
-
-                       foreach my $pod (@pods) {
-                           (my $test = $pod) =~ s/\.(pm|pod)$//;
-                           $test =~ s/^lib\W//;
-                           $test =~ s/\W/-/;
-                          $test =~ s/\//__/g;
-                           $test = "autogen-$test.t";
-                           $out .= "\t$self->{NOECHO}\$(POD2TEST_EXE) ".
-                                   "$pod t/$test \n";
-                       }
-
-                       return $out;
-                   }
-               }
-
index 1cfc428..90c332b 100644 (file)
@@ -1,11 +1,82 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+
 package RT;
-use RT::Handle;
-use RT::CurrentUser;
 use strict;
+use RT::I18N;
+use RT::CurrentUser;
+use RT::System;
+
+use vars qw($VERSION $System $SystemUser $Nobody $Handle $Logger
+        $CORE_CONFIG_FILE
+        $SITE_CONFIG_FILE
+        $VENDOR_CONFIG_FILE
+        $BasePath
+        $EtcPath
+        $VarPath
+        $LocalPath
+        $LocalEtcPath
+        $LocalLexiconPath
+        $LogDir
+        $MasonComponentRoot
+        $MasonLocalComponentRoot
+        $MasonDataDir
+        $MasonSessionDir
+);
+
+$VERSION = '3.0.4';
+$CORE_CONFIG_FILE = "/opt/rt3/etc/RT_Config.pm";
+$SITE_CONFIG_FILE = "/opt/rt3/etc/RT_SiteConfig.pm";
+
+$BasePath = '/opt/rt3';
+
+$EtcPath = '/opt/rt3/etc';
+$VarPath = '/opt/rt3/var';
+$LocalPath = '/opt/rt3/local';
+$LocalEtcPath = '/opt/rt3/local/etc';
+$LocalLexiconPath = '/opt/rt3/local/po';
+
+# $MasonComponentRoot is where your rt instance keeps its mason html files
+
+$MasonComponentRoot = '/opt/rt3/share/html';
+
+# $MasonLocalComponentRoot is where your rt instance keeps its site-local
+# mason html files.
+
+$MasonLocalComponentRoot = '/opt/rt3/local/html';
+
+# $MasonDataDir Where mason keeps its datafiles
+
+$MasonDataDir = '/opt/rt3/var/mason_data';
+
+# RT needs to put session data (for preserving state between connections
+# via the web interface)
+$MasonSessionDir = '/opt/rt3/var/session_data';
 
-use vars qw($VERSION $SystemUser $Nobody $Handle $Logger);
 
-$VERSION = '!!RT_VERSION!!';
 
 =head1 NAME
 
@@ -14,19 +85,45 @@ $VERSION = '!!RT_VERSION!!';
 =head1 SYNOPSIS
 
        A fully featured request tracker package
-       
 
 =head1 DESCRIPTION
 
 
 =cut
 
+=item LoadConfig
+
+Load RT's config file. First, go after the core config file. 
+After that, try to load the vendor config.
+After that, go after the site config.
+
+=cut
+
+sub LoadConfig {
+     local *Set = sub { $_[0] = $_[1] unless defined $_[0] }; 
+    if ( -f "$SITE_CONFIG_FILE" ) {
+        require $SITE_CONFIG_FILE
+          || die ("Couldn't load RT config file  '$SITE_CONFIG_FILE'\n$@");
+    }
+    require $CORE_CONFIG_FILE
+      || die ("Couldn't load RT config file '$CORE_CONFIG_FILE'\n$@");
+    RT::I18N->Init;
+}
+
+=item Init
+
+    Conenct to the database, set up logging.
+    
+=cut
+
 sub Init {
+    require RT::Handle;
     #Get a database connection
-    $Handle = new RT::Handle($RT::DatabaseType);
+        unless ($Handle && $Handle->dbh->ping) {
+    $Handle = RT::Handle->new();
+        } 
     $Handle->Connect();
     
-    
     #RT's system user is a genuine database user. its id lives here
     $SystemUser = new RT::CurrentUser();
     $SystemUser->LoadByName('RT_System');
@@ -34,7 +131,9 @@ sub Init {
     #RT's "nobody user" is a genuine database user. its ID lives here.
     $Nobody = new RT::CurrentUser();
     $Nobody->LoadByName('Nobody');
-   
+  
+    $System = RT::System->new();
+
    InitLogging(); 
 }
 
@@ -51,30 +150,81 @@ sub InitLogging {
 
     $, = '';
     use Log::Dispatch 1.6;
-    use Log::Dispatch::File;
-    use Log::Dispatch::Screen;
 
-    $Logger=Log::Dispatch->new();
+    unless ($RT::Logger) {
+
+    $RT::Logger=Log::Dispatch->new();
     
     if ($RT::LogToFile) {
-       my $filename = $RT::LogToFileNamed || "$RT::LogDir/rt.log";
 
-         $Logger->add(Log::Dispatch::File->new
+    unless (-d $RT::LogDir && -w $RT::LogDir) {
+        # localizing here would be hard when we don't have a current user yet
+        # die $self->loc("Log directory [_1] not found or couldn't be written.\n RT can't run.", $RT::LogDir);
+        die ("Log directory $RT::LogDir not found or couldn't be written.\n RT can't run.");
+    }
+
+       my $filename;
+       if ($RT::LogToFileNamed =~ m![/\\]!) {
+           # looks like an absolute path.
+           $filename = $RT::LogToFileNamed;
+       }
+       else {
+           $filename = "$RT::LogDir/$RT::LogToFileNamed";
+       }
+    require Log::Dispatch::File;
+
+
+         $RT::Logger->add(Log::Dispatch::File->new
                       ( name=>'rtlog',
                         min_level=> $RT::LogToFile,
                         filename=> $filename,
                         mode=>'append',
-            callbacks => sub {my %p=@_; return "[".gmtime(time)."] [".$p{level}."]: $p{message}\n"}
-
+                        callbacks => sub { my %p = @_;
+                                my ($package, $filename, $line) = caller(5);
+                                return "[".gmtime(time)."] [".$p{level}."]: $p{message} ($filename:$line)\n"}
+             
+             
+             
                       ));
     }
     if ($RT::LogToScreen) {
-       $Logger->add(Log::Dispatch::Screen->new
+       require Log::Dispatch::Screen;
+       $RT::Logger->add(Log::Dispatch::Screen->new
                     ( name => 'screen',
                       min_level => $RT::LogToScreen,
+                        callbacks => sub { my %p = @_;
+                                my ($package, $filename, $line) = caller(5);
+                                return "[".gmtime(time)."] [".$p{level}."]: $p{message} ($filename:$line)\n"
+                               },
+             
+                      stderr => 1
+                    ));
+    }
+    if ($RT::LogToSyslog) {
+       require Log::Dispatch::Syslog;
+       $RT::Logger->add(Log::Dispatch::Syslog->new
+                    ( name => 'syslog',
+                       ident => 'RT',
+                      min_level => $RT::LogToSyslog,
+                        callbacks => sub { my %p = @_;
+                                my ($package, $filename, $line) = caller(5);
+
+                               # syswrite() cannot take utf8; turn it off here.
+                               Encode::_utf8_off($p{message});
+
+                               if ($p{level} eq 'debug') {
+
+                                return "$p{message}\n" }
+                               else {
+                                return "$p{message} ($filename:$line)\n"}
+                               },
+             
                       stderr => 1
                     ));
     }
+
+    }
+
 # {{{ Signal handlers
 
 ## This is the default handling of warnings and die'ings in the code
@@ -88,6 +238,7 @@ $SIG{__WARN__} = sub {$RT::Logger->warning($_[0])};
 
 $SIG{__DIE__}  = sub {
     unless ($^S || !defined $^S ) {
+        $RT::Handle->Rollback();
         $RT::Logger->crit("$_[0]");
         exit(-1);
     }
@@ -127,10 +278,6 @@ sub DropSetGIDPermissions {
 }
 
 
-=head1 NAME
-
-RT - Request Tracker
-
 =head1 SYNOPSIS
 
 =head1 BUGS
@@ -140,7 +287,6 @@ RT - Request Tracker
 
 =begin testing
 
-ok (require RT::TestHarness);
 
 ok ($RT::Nobody->Name() eq 'Nobody', "Nobody is nobody");
 ok ($RT::Nobody->Name() ne 'root', "Nobody isn't named root");
@@ -152,4 +298,7 @@ ok ($RT::SystemUser->Name() ne 'noname', "The system user isn't noname");
 
 =cut
 
+eval "require RT_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT_Local.pm});
+
 1;
diff --git a/rt/lib/RT.pm.in b/rt/lib/RT.pm.in
new file mode 100644 (file)
index 0000000..065734e
--- /dev/null
@@ -0,0 +1,304 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+
+package RT;
+use strict;
+use RT::I18N;
+use RT::CurrentUser;
+use RT::System;
+
+use vars qw($VERSION $System $SystemUser $Nobody $Handle $Logger
+        $CORE_CONFIG_FILE
+        $SITE_CONFIG_FILE
+        $VENDOR_CONFIG_FILE
+        $BasePath
+        $EtcPath
+        $VarPath
+        $LocalPath
+        $LocalEtcPath
+        $LocalLexiconPath
+        $LogDir
+        $MasonComponentRoot
+        $MasonLocalComponentRoot
+        $MasonDataDir
+        $MasonSessionDir
+);
+
+$VERSION = '@RT_VERSION_MAJOR@.@RT_VERSION_MINOR@.@RT_VERSION_PATCH@';
+$CORE_CONFIG_FILE = "@CONFIG_FILE_PATH@/RT_Config.pm";
+$SITE_CONFIG_FILE = "@CONFIG_FILE_PATH@/RT_SiteConfig.pm";
+
+$BasePath = '@RT_PATH@';
+
+$EtcPath = '@RT_ETC_PATH@';
+$VarPath = '@RT_VAR_PATH@';
+$LocalPath = '@RT_LOCAL_PATH@';
+$LocalEtcPath = '@LOCAL_ETC_PATH@';
+$LocalLexiconPath = '@LOCAL_LEXICON_PATH@';
+
+# $MasonComponentRoot is where your rt instance keeps its mason html files
+
+$MasonComponentRoot = '@MASON_HTML_PATH@';
+
+# $MasonLocalComponentRoot is where your rt instance keeps its site-local
+# mason html files.
+
+$MasonLocalComponentRoot = '@MASON_LOCAL_HTML_PATH@';
+
+# $MasonDataDir Where mason keeps its datafiles
+
+$MasonDataDir = '@MASON_DATA_PATH@';
+
+# RT needs to put session data (for preserving state between connections
+# via the web interface)
+$MasonSessionDir = '@MASON_SESSION_PATH@';
+
+
+
+=head1 NAME
+
+       RT - Request Tracker
+
+=head1 SYNOPSIS
+
+       A fully featured request tracker package
+
+=head1 DESCRIPTION
+
+
+=cut
+
+=item LoadConfig
+
+Load RT's config file. First, go after the core config file. 
+After that, try to load the vendor config.
+After that, go after the site config.
+
+=cut
+
+sub LoadConfig {
+     local *Set = sub { $_[0] = $_[1] unless defined $_[0] }; 
+    if ( -f "$SITE_CONFIG_FILE" ) {
+        require $SITE_CONFIG_FILE
+          || die ("Couldn't load RT config file  '$SITE_CONFIG_FILE'\n$@");
+    }
+    require $CORE_CONFIG_FILE
+      || die ("Couldn't load RT config file '$CORE_CONFIG_FILE'\n$@");
+    RT::I18N->Init;
+}
+
+=item Init
+
+    Conenct to the database, set up logging.
+    
+=cut
+
+sub Init {
+    require RT::Handle;
+    #Get a database connection
+        unless ($Handle && $Handle->dbh->ping) {
+    $Handle = RT::Handle->new();
+        } 
+    $Handle->Connect();
+    
+    #RT's system user is a genuine database user. its id lives here
+    $SystemUser = new RT::CurrentUser();
+    $SystemUser->LoadByName('RT_System');
+    
+    #RT's "nobody user" is a genuine database user. its ID lives here.
+    $Nobody = new RT::CurrentUser();
+    $Nobody->LoadByName('Nobody');
+  
+    $System = RT::System->new();
+
+   InitLogging(); 
+}
+
+=head2 InitLogging
+
+Create the RT::Logger object. 
+
+=cut
+sub InitLogging {
+
+    # We have to set the record seperator ($, man perlvar)
+    # or Log::Dispatch starts getting
+    # really pissy, as some other module we use unsets it.
+
+    $, = '';
+    use Log::Dispatch 1.6;
+
+    unless ($RT::Logger) {
+
+    $RT::Logger=Log::Dispatch->new();
+    
+    if ($RT::LogToFile) {
+
+    unless (-d $RT::LogDir && -w $RT::LogDir) {
+        # localizing here would be hard when we don't have a current user yet
+        # die $self->loc("Log directory [_1] not found or couldn't be written.\n RT can't run.", $RT::LogDir);
+        die ("Log directory $RT::LogDir not found or couldn't be written.\n RT can't run.");
+    }
+
+       my $filename;
+       if ($RT::LogToFileNamed =~ m![/\\]!) {
+           # looks like an absolute path.
+           $filename = $RT::LogToFileNamed;
+       }
+       else {
+           $filename = "$RT::LogDir/$RT::LogToFileNamed";
+       }
+    require Log::Dispatch::File;
+
+
+         $RT::Logger->add(Log::Dispatch::File->new
+                      ( name=>'rtlog',
+                        min_level=> $RT::LogToFile,
+                        filename=> $filename,
+                        mode=>'append',
+                        callbacks => sub { my %p = @_;
+                                my ($package, $filename, $line) = caller(5);
+                                return "[".gmtime(time)."] [".$p{level}."]: $p{message} ($filename:$line)\n"}
+             
+             
+             
+                      ));
+    }
+    if ($RT::LogToScreen) {
+       require Log::Dispatch::Screen;
+       $RT::Logger->add(Log::Dispatch::Screen->new
+                    ( name => 'screen',
+                      min_level => $RT::LogToScreen,
+                        callbacks => sub { my %p = @_;
+                                my ($package, $filename, $line) = caller(5);
+                                return "[".gmtime(time)."] [".$p{level}."]: $p{message} ($filename:$line)\n"
+                               },
+             
+                      stderr => 1
+                    ));
+    }
+    if ($RT::LogToSyslog) {
+       require Log::Dispatch::Syslog;
+       $RT::Logger->add(Log::Dispatch::Syslog->new
+                    ( name => 'syslog',
+                       ident => 'RT',
+                      min_level => $RT::LogToSyslog,
+                        callbacks => sub { my %p = @_;
+                                my ($package, $filename, $line) = caller(5);
+
+                               # syswrite() cannot take utf8; turn it off here.
+                               Encode::_utf8_off($p{message});
+
+                               if ($p{level} eq 'debug') {
+
+                                return "$p{message}\n" }
+                               else {
+                                return "$p{message} ($filename:$line)\n"}
+                               },
+             
+                      stderr => 1
+                    ));
+    }
+
+    }
+
+# {{{ Signal handlers
+
+## This is the default handling of warnings and die'ings in the code
+## (including other used modules - maybe except for errors catched by
+## Mason).  It will log all problems through the standard logging
+## mechanism (see above).
+
+$SIG{__WARN__} = sub {$RT::Logger->warning($_[0])};
+
+#When we call die, trap it and log->crit with the value of the die.
+
+$SIG{__DIE__}  = sub {
+    unless ($^S || !defined $^S ) {
+        $RT::Handle->Rollback();
+        $RT::Logger->crit("$_[0]");
+        exit(-1);
+    }
+    else {
+        #Get out of here if we're in an eval
+        die $_[0];
+    }
+};
+
+# }}}
+
+}
+
+# }}}
+
+
+sub SystemUser {
+    return($SystemUser);
+}      
+
+sub Nobody {
+    return ($Nobody);
+}
+
+
+=head2 DropSetGIDPermissions
+
+Drops setgid permissions.
+
+=cut
+
+sub DropSetGIDPermissions {
+    # Now that we got the config read in, we have the database 
+    # password and don't need to be setgid
+    # make the effective group the real group
+    $) = $(;
+}
+
+
+=head1 SYNOPSIS
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+
+=begin testing
+
+
+ok ($RT::Nobody->Name() eq 'Nobody', "Nobody is nobody");
+ok ($RT::Nobody->Name() ne 'root', "Nobody isn't named root");
+ok ($RT::SystemUser->Name() eq 'RT_System', "The system user is RT_System");
+ok ($RT::SystemUser->Name() ne 'noname', "The system user isn't noname");
+
+
+=end testing
+
+=cut
+
+eval "require RT_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT_Local.pm});
+
+1;
index d4681cf..1501a12 100755 (executable)
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/ACE.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-=head1 NAME
 
-  RT::ACE - RT\'s ACE object
+=head1 NAME
 
-=head1 SYNOPSIS
+RT::ACE
 
-  use RT::ACE;
-  my $ace = new RT::ACE($CurrentUser);
 
+=head1 SYNOPSIS
 
 =head1 DESCRIPTION
 
-
 =head1 METHODS
 
-=begin testing
-
-ok(require RT::TestHarness);
-ok(require RT::ACE);
-
-=end testing
-
 =cut
 
 package RT::ACE;
-use RT::Record;
-@ISA= qw(RT::Record);
-
-use vars qw (%SCOPES
-            %QUEUERIGHTS
-            %SYSTEMRIGHTS
-            %LOWERCASERIGHTNAMES
-           ); 
-
-%SCOPES = (
-          System => 'System-level right',
-          Queue => 'Queue-level right'
-         );
-
-# {{{ Descriptions of rights
-
-# Queue rights are the sort of queue rights that can only be granted
-# to real people or groups
-%QUEUERIGHTS = ( 
-               SeeQueue => 'Can this principal see this queue',
-               AdminQueue => 'Create, delete and modify queues', 
-               ShowACL => 'Display Access Control List',
-               ModifyACL => 'Modify Access Control List',
-               ModifyQueueWatchers => 'Modify the queue watchers',
-                AdminKeywordSelects => 'Create, delete and modify keyword selections',
-
-               
-               ModifyTemplate => 'Modify email templates for this queue',
-               ShowTemplate => 'Display email templates for this queue',
-               ModifyScrips => 'Modify Scrips for this queue',
-               ShowScrips => 'Display Scrips for this queue',
-
-               ShowTicket => 'Show ticket summaries',
-               ShowTicketComments => 'Show ticket private commentary',
+use RT::Record; 
 
-               Watch => 'Sign up as a ticket Requestor or ticket or queue Cc',
-               WatchAsAdminCc => 'Sign up as a ticket or queue AdminCc',
-               CreateTicket => 'Create tickets in this queue',
-               ReplyToTicket => 'Reply to tickets',
-               CommentOnTicket => 'Comment on tickets',
-               OwnTicket => 'Own tickets',
-               ModifyTicket => 'Modify tickets',
-               DeleteTicket => 'Delete tickets'
 
-              );       
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
 
+sub _Init {
+  my $self = shift; 
 
-# System rights are rights granted to the whole system
-%SYSTEMRIGHTS = (
-                SuperUser => 'Do anything and everything',
-               AdminKeywords => 'Creatte, delete and modify keywords',  
-               AdminGroups => 'Create, delete and modify groups',
-               AdminUsers => 'Create, Delete and Modify users',
-               ModifySelf => 'Modify one\'s own RT account',
-
-               );
-
-# }}}
-
-# {{{ Descriptions of principals
-
-%TICKET_METAPRINCIPALS = ( Owner => 'The owner of a ticket',
-                                  Requestor => 'The requestor of a ticket',
-                                  Cc => 'The CC of a ticket',
-                                      AdminCc => 'The administrative CC of a ticket',
-                        );
-
-# }}}
-
-# {{{ We need to build a hash of all rights, keyed by lower case names
-
-#since you can't do case insensitive hash lookups
-
-foreach $right (keys %QUEUERIGHTS) {
-    $LOWERCASERIGHTNAMES{lc $right}=$right;
-}
-foreach $right (keys %SYSTEMRIGHTS) {
-    $LOWERCASERIGHTNAMES{lc $right}=$right;
+  $self->Table('ACL');
+  $self->SUPER::_Init(@_);
 }
 
-# }}}
-
-# {{{ sub _Init
-sub _Init  {
-  my $self = shift;
-  $self->{'table'} = "ACL";
-  return($self->SUPER::_Init(@_));
-}
-# }}}
 
-# {{{ sub LoadByValues
 
-=head2 LoadByValues PARAMHASH
 
-Load an ACE by specifying a paramhash with the following fields:
 
-              PrincipalId => undef,
-             PrincipalType => undef,
-             RightName => undef,
-             RightScope => undef,
-             RightAppliesTo => undef,
+=item Create PARAMHASH
 
-=cut
+Create takes a hash of values and creates a row in the database:
 
-sub LoadByValues {
-  my $self = shift;
-  my %args = (PrincipalId => undef,
-             PrincipalType => undef,
-             RightName => undef,
-             RightScope => undef,
-             RightAppliesTo => undef,
-             @_);
-  
-  $self->LoadByCols (PrincipalId => $args{'PrincipalId'},
-                    PrincipalType => $args{'PrincipalType'},
-                    RightName => $args{'RightName'},
-                    RightScope => $args{'RightScope'},
-                    RightAppliesTo => $args{'RightAppliesTo'}
-                   );
-  
-  #If we couldn't load it.
-  unless ($self->Id) {
-      return (0, "ACE not found");
-  }
-  # if we could
-  return ($self->Id, "ACE Loaded");
-  
-}
+  varchar(25) 'PrincipalType'.
+  int(11) 'PrincipalId'.
+  varchar(25) 'RightName'.
+  varchar(25) 'ObjectType'.
+  int(11) 'ObjectId'.
+  int(11) 'DelegatedBy'.
+  int(11) 'DelegatedFrom'.
 
-# }}}
-
-# {{{ sub Create
-
-=head2 Create <PARAMS>
+=cut
 
-PARAMS is a parameter hash with the following elements:
 
-   PrincipalType => "Queue"|"User"
-   PrincipalId => an intentifier you can use to ->Load a user or group
-   RightName => the name of a right. in any case
-   RightScope => "System" | "Queue"
-   RightAppliesTo => a queue id or undef
 
-=cut
 
 sub Create {
     my $self = shift;
-    my %args = ( PrincipalId => undef,
-                PrincipalType => undef,
-                RightName => undef,
-                RightScope => undef,
-                RightAppliesTo => undef,
-                @_
-              );
-    
-    # {{{ Validate the principal
-    my ($princ_obj);
-    if ($args{'PrincipalType'} eq 'User') {
-       $princ_obj = new RT::User($RT::SystemUser);
-       
-    }  
-    elsif ($args{'PrincipalType'} eq 'Group') {
-       require RT::Group;
-       $princ_obj = new RT::Group($RT::SystemUser);
-    }
-    else {
-       return (0, 'Principal type '.$args{'PrincipalType'} . ' is invalid.');
-    }  
-    
-    $princ_obj->Load($args{'PrincipalId'});
-    my $princ_id = $princ_obj->Id();
-    
-    unless ($princ_id) {
-       return (0, 'Principal '.$args{'PrincipalId'}.' not found.');
-    }
-
-    # }}}
-    
-    #TODO allow loading of queues by name.    
-    
-    # {{{ Check the ACL
-    if ($args{'RightScope'} eq 'System') {
-       
-       unless ($self->CurrentUserHasSystemRight('ModifyACL')) {
-           $RT::Logger->error("Permission Denied.");
-           return(undef);
-       }
-    }
-    
-    elsif ($args{'RightScope'} eq 'Queue') {
-       unless ($self->CurrentUserHasQueueRight( Queue => $args{'RightAppliesTo'},
-                                                Right => 'ModifyACL')) {
-           return (0, 'Permission Denied.');
-       }
-       
-       
-       
-       
-    }
-    #If it's not a scope we recognise, something scary is happening.
-    else {
-       $RT::Logger->err("RT::ACE->Create got a scope it didn't recognize: ".
-                        $args{'RightScope'}." Bailing. \n");
-       return(0,"System error. Unable to grant rights.");
-    }
-
-    # }}}
-
-    # {{{ Canonicalize and check the right name
-    $args{'RightName'} = $self->CanonicalizeRightName($args{'RightName'});
-    
-    #check if it's a valid RightName
-    if ($args{'RightScope'} eq 'Queue') {
-       unless (exists $QUEUERIGHTS{$args{'RightName'}}) {
-           return(0, 'Invalid right');
-       }       
-       }       
-    elsif ($args{'RightScope' eq 'System'}) {
-       unless (exists $SYSTEMRIGHTS{$args{'RightName'}}) {
-           return(0, 'Invalid right');
-       }                   
-    }  
-    # }}}
-    
-    # Make sure the right doesn't already exist.
-    $self->LoadByCols (PrincipalId => $princ_id,
-                      PrincipalType => $args{'PrincipalType'},
-                      RightName => $args{'RightName'},
-                      RightScope => $args {'RightScope'},
-                      RightAppliesTo => $args{'RightAppliesTo'}
-                     );
-    if ($self->Id) {
-       return (0, 'That user already has that right');
-    }  
-
-    my $id = $self->SUPER::Create( PrincipalId => $princ_id,
-                                  PrincipalType => $args{'PrincipalType'},
-                                  RightName => $args{'RightName'},
-                                  RightScope => $args {'RightScope'},
-                                  RightAppliesTo => $args{'RightAppliesTo'}
-                                );
-    
-    
-    if ($id > 0 ) {
-       return ($id, 'Right Granted');
-    }
-    else {
-       $RT::Logger->err('System error. right not granted.');
-       return(0, 'System Error. right not granted');
-    }
-}
-
-# }}}
-
+    my %args = ( 
+                PrincipalType => '',
+                PrincipalId => '0',
+                RightName => '',
+                ObjectType => '',
+                ObjectId => '0',
+                DelegatedBy => '0',
+                DelegatedFrom => '0',
+
+                 @_);
+    $self->SUPER::Create(
+                         PrincipalType => $args{'PrincipalType'},
+                         PrincipalId => $args{'PrincipalId'},
+                         RightName => $args{'RightName'},
+                         ObjectType => $args{'ObjectType'},
+                         ObjectId => $args{'ObjectId'},
+                         DelegatedBy => $args{'DelegatedBy'},
+                         DelegatedFrom => $args{'DelegatedFrom'},
+);
 
-# {{{ sub Delete 
-
-=head2 Delete
-
-Delete this object.
-
-=cut
-
-sub Delete {
-    my $self = shift;
-    
-    unless ($self->CurrentUserHasRight('ModifyACL')) {
-       return (0, 'Permission Denied');
-    }  
-    
-    
-    my ($val,$msg) = $self->SUPER::Delete(@_);
-    if ($val) {
-       return ($val, 'ACE Deleted');
-    }  
-    else {
-       return (0, 'ACE could not be deleted');
-    }
 }
 
-# }}}
 
-# {{{ sub _BootstrapRight 
 
-=head2 _BootstrapRight
+=item id
 
-Grant a right with no error checking and no ACL. this is _only_ for 
-installation. If you use this routine without jesse@fsck.com's explicit 
-written approval, he will hunt you down and make you spend eternity
-translating mozilla's code into FORTRAN or intercal.
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
 
-=cut
-
-sub _BootstrapRight {
-    my $self = shift;
-    my %args = @_;
-
-    my $id = $self->SUPER::Create( PrincipalId => $args{'PrincipalId'},
-                                  PrincipalType => $args{'PrincipalType'},
-                                  RightName => $args{'RightName'},
-                                  RightScope => $args {'RightScope'},
-                                  RightAppliesTo => $args{'RightAppliesTo'}
-                                );
-    
-    if ($id > 0 ) {
-       return ($id);
-    }
-    else {
-       $RT::Logger->err('System error. right not granted.');
-       return(undef);
-    }
-    
-}
-
-# }}}
-
-# {{{ sub CanonicalizeRightName
-
-=head2 CanonicalizeRightName <RIGHT>
-
-Takes a queue or system right name in any case and returns it in
-the correct case. If it's not found, will return undef.
 
 =cut
 
-sub CanonicalizeRightName {
-    my $self = shift;
-    my $right = shift;
-    $right = lc $right;
-    if (exists $LOWERCASERIGHTNAMES{"$right"}) {
-       return ($LOWERCASERIGHTNAMES{"$right"});
-    }
-    else {
-       return (undef);
-    }
-}
-
-# }}}
 
-# {{{ sub QueueRights
+=item PrincipalType
 
-=head2 QueueRights
+Returns the current value of PrincipalType. 
+(In the database, PrincipalType is stored as varchar(25).)
 
-Returns a hash of all the possible rights at the queue scope
 
-=cut
 
-sub QueueRights {
-        return (%QUEUERIGHTS);
-}
+=item SetPrincipalType VALUE
 
-# }}}
 
-# {{{ sub SystemRights
+Set PrincipalType to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, PrincipalType will be stored as a varchar(25).)
 
-=head2 SystemRights
-
-Returns a hash of all the possible rights at the system scope
 
 =cut
 
-sub SystemRights {
-       return (%SYSTEMRIGHTS);
-}
 
+=item PrincipalId
 
-# }}}
+Returns the current value of PrincipalId. 
+(In the database, PrincipalId is stored as int(11).)
 
-# {{{ sub _Accessible 
 
-sub _Accessible  {
-  my $self = shift;  
-  my %Cols = (
-             PrincipalId => 'read/write',
-             PrincipalType => 'read/write',
-             RightName => 'read/write', 
-             RightScope => 'read/write',
-             RightAppliesTo => 'read/write'
-           );
-  return($self->SUPER::_Accessible(@_, %Cols));
-}
-# }}}
 
-# {{{ sub AppliesToObj
+=item SetPrincipalId VALUE
 
-=head2 AppliesToObj
 
-If the AppliesTo is a queue, returns the queue object. If it's 
-the system object, returns undef. If the user has no rights, returns undef.
+Set PrincipalId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, PrincipalId will be stored as a int(11).)
 
-=cut
-
-sub AppliesToObj {
-    my $self = shift;
-    if ($self->RightScope eq 'Queue') {
-       my $appliesto_obj = new RT::Queue($self->CurrentUser);
-       $appliesto_obj->Load($self->RightAppliesTo);
-       return($appliesto_obj);
-    }
-    elsif ($self->RightScope eq 'System') {
-       return (undef);
-    }  
-    else {
-       $RT::Logger->warning("$self -> AppliesToObj called for an object ".
-                            "of an unknown scope:" . $self->RightScope);
-       return(undef);
-    }
-}      
-
-# }}}
-
-# {{{ sub PrincipalObj
-
-=head2 PrincipalObj
-
-If the AppliesTo is a group, returns the group object.
-If the AppliesTo is a user, returns the user object.
-Otherwise, it logs a warning and returns undef.
 
 =cut
 
-sub PrincipalObj {
-    my $self = shift;
-    my ($princ_obj);
-
-    if ($self->PrincipalType eq 'Group') {
-       use RT::Group;
-       $princ_obj = new RT::Group($self->CurrentUser);
-    }
-    elsif ($self->PrincipalType eq 'User') {
-       $princ_obj = new RT::User($self->CurrentUser);
-    }
-    else {
-       $RT::Logger->warning("$self -> PrincipalObj called for an object ".
-                            "of an unknown principal type:" . 
-                            $self->PrincipalType ."\n");
-       return(undef);
-    }
-    
-    $princ_obj->Load($self->PrincipalId);
-    return($princ_obj);
-
-}      
-
-# }}}
-
-# {{{ ACL related methods
-
-# {{{ sub _Set
-
-sub _Set {
-  my $self = shift;
-  return (0, "ACEs can only be created and deleted.");
-}
-
-# }}}
-
-# {{{ sub _Value
-
-sub _Value {
-    my $self = shift;
-
-    unless ($self->CurrentUserHasRight('ShowACL')) {
-       return (undef);
-    }
 
-    return ($self->__Value(@_));
-}
-
-# }}}
+=item RightName
 
+Returns the current value of RightName. 
+(In the database, RightName is stored as varchar(25).)
 
-# {{{ sub CurrentUserHasQueueRight 
 
-=head2 CurrentUserHasQueueRight ( Queue => QUEUEID, Right => RIGHTNANAME )
 
-Check to see whether the current user has the specified right for the specified queue.
-
-=cut
-
-sub CurrentUserHasQueueRight {
-    my $self = shift;
-    my %args = (Queue => undef,
-               Right => undef,
-               @_
-               );
-    return ($self->HasRight( Right => $args{'Right'},
-                            Principal => $self->CurrentUser->UserObj,
-                            Queue => $args{'Queue'}));
-}
+=item SetRightName VALUE
 
-# }}}
 
-# {{{ sub CurrentUserHasSystemRight 
-=head2 CurrentUserHasSystemRight RIGHTNAME
+Set RightName to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, RightName will be stored as a varchar(25).)
 
-Check to see whether the current user has the specified right for the 'system' scope.
 
 =cut
 
-sub CurrentUserHasSystemRight {
-    my $self = shift;
-    my $right = shift;
-    return ($self->HasRight( Right => $right,
-                            Principal => $self->CurrentUser->UserObj,
-                            System => 1
-                          ));
-}
-
 
-# }}}
+=item ObjectType
 
-# {{{ sub CurrentUserHasRight
+Returns the current value of ObjectType. 
+(In the database, ObjectType is stored as varchar(25).)
 
-=item CurrentUserHasRight RIGHT 
-Takes a rightname as a string.
-
-Helper menthod for HasRight. Presets Principal to CurrentUser then 
-calls HasRight.
-
-=cut
 
-sub CurrentUserHasRight {
-    my $self = shift;
-    my $right = shift;
-    return ($self->HasRight( Principal => $self->CurrentUser->UserObj,
-                             Right => $right,
-                          ));
-}
 
-# }}}
+=item SetObjectType VALUE
 
-# {{{ sub HasRight
 
-=item HasRight
+Set ObjectType to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ObjectType will be stored as a varchar(25).)
 
-Takes a param-hash consisting of "Right" and "Principal"  Principal is 
-an RT::User object or an RT::CurrentUser object. "Right" is a textual
-Right string that applies to KeywordSelects
 
 =cut
 
-sub HasRight {
-    my $self = shift;
-    my %args = ( Right => undef,
-                 Principal => undef,
-                Queue => undef,
-                System => undef,
-                 @_ ); 
-
-    #If we're explicitly specifying a queue, as we need to do on create
-    if (defined $args{'Queue'}) {
-       return ($args{'Principal'}->HasQueueRight(Right => $args{'Right'},
-                                                 Queue => $args{'Queue'}));
-    }
-    #else if we're specifying to check a system right
-    elsif ((defined $args{'System'}) and (defined $args{'Right'})) {
-        return( $args{'Principal'}->HasSystemRight( $args{'Right'} ));
-    }  
-    
-    elsif ($self->__Value('RightScope') eq 'System') {
-       return $args{'Principal'}->HasSystemRight($args{'Right'});
-    }
-    elsif ($self->__Value('RightScope') eq 'Queue') {
-       return $args{'Principal'}->HasQueueRight( Queue => $self->__Value('RightAppliesTo'),
-                                                 Right => $args{'Right'} );
-    }  
-    else {
-       $RT::Logger->warning("$self: Trying to check an acl for a scope we ".
-                            "don't understand:" . $self->__Value('RightScope') ."\n");
-       return undef;
-    }
-
-
-
-}
-# }}}
-
-# }}}
-
-1;
-
-__DATA__
-
-# {{{ POD
-
-=head1 Out of date docs
 
-=head2 Table Structure
+=item ObjectId
 
-PrincipalType, PrincipalId, Right,Scope,AppliesTo
+Returns the current value of ObjectId. 
+(In the database, ObjectId is stored as int(11).)
 
-=head1 The docs are out of date. so you know.
 
-=head1 Scopes
 
-Scope is the scope of the right granted, not the granularity of the grant.
-For example, Queue and Ticket rights are both granted for a "queue." 
-Rights with a scope of 'System' don't have an AppliesTo. (They're global).
-Rights with a scope of "Queue" are rights that act on a queue.
-Rights with a scope of "System" are rights that act on some other aspect
-of the system.
+=item SetObjectId VALUE
 
 
-=item Queue
-=item System
+Set ObjectId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ObjectId will be stored as a int(11).)
 
 
-=head1 Rights
-
-=head2 Scope: Queue
-
-=head2 Queue rights that apply to a ticket within a queue
-
-Create Ticket in <queue>
-
-        Name: Create
-       Principals: <user> <group>
-Display Ticket Summary in <queue>
-
-       Name: Show
-       Principals: <user> <group> Owner Requestor Cc AdminCc
-
-Display Ticket History  <queue>
-
-       Name: ShowHistory
-       Principals: <user> <group> Owner Requestor Cc AdminCc
-
-Display Ticket Private Comments  <queue>
+=cut
 
-       Name: ShowComments
-       Principals: <user> <group> Owner Requestor Cc AdminCc
 
-Reply to Ticket in <queue>
+=item DelegatedBy
 
-       Name: Reply
-       Principals: <user> <group> Owner Requestor Cc AdminCc
+Returns the current value of DelegatedBy. 
+(In the database, DelegatedBy is stored as int(11).)
 
-Comment on Ticket in <queue>
 
-       Name: Comment
-       Principals: <user> <group> Owner Requestor Cc AdminCc
 
-Modify Ticket in <queue>
+=item SetDelegatedBy VALUE
 
-       Name: Modify
-       Principals: <user> <group> Owner Requestor Cc AdminCc
 
-Delete Tickets in <queue>
+Set DelegatedBy to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, DelegatedBy will be stored as a int(11).)
 
-       Name: Delete
-       Principals: <user> <group> Owner Requestor Cc AdminCc
 
+=cut
 
-=head2 Queue Rights that apply to a whole queue
 
-These rights can only be granted to "real people"
+=item DelegatedFrom
 
-List Tickets in <queue>
+Returns the current value of DelegatedFrom. 
+(In the database, DelegatedFrom is stored as int(11).)
 
-       Name: ListQueue
-       Principals: <user> <group>
 
-Know that <queue> exists
-    
-    Name: See
-    Principals: <user> <group>
 
-Display queue settings
+=item SetDelegatedFrom VALUE
 
-    Name: Explore
-    Principals: <user> <group>
 
-Modify Queue Watchers for <queue>
+Set DelegatedFrom to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, DelegatedFrom will be stored as a int(11).)
 
-       Name: ModifyQueueWatchers
-       Principals: <user> <group>
 
-Modify Queue Attributes for <queue> 
+=cut
 
-       Name: ModifyQueue
-       Principals: <user> <group>
 
-Modify Queue ACL for queue <queue>
 
-       Name: ModifyACL
-       Principals: <user> <group>
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        PrincipalType => 
+               {read => 1, write => 1, type => 'varchar(25)', default => ''},
+        PrincipalId => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        RightName => 
+               {read => 1, write => 1, type => 'varchar(25)', default => ''},
+        ObjectType => 
+               {read => 1, write => 1, type => 'varchar(25)', default => ''},
+        ObjectId => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        DelegatedBy => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        DelegatedFrom => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
 
+ }
+};
 
-=head2 Rights that apply to the System scope
 
-=head2 SystemRights
+        eval "require RT::ACE_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/ACE_Overlay.pm}) {
+            die $@;
+        };
 
-Create Queue
-  
-        Name: CreateQueue
-       Principals: <user> <group>
-Delete Queue
-  
-        Name: DeleteQueue
-       Principals: <user> <group>
+        eval "require RT::ACE_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/ACE_Vendor.pm}) {
+            die $@;
+        };
 
-Create Users
-  
-        Name: CreateUser
-       Principals: <user> <group>
+        eval "require RT::ACE_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/ACE_Local.pm}) {
+            die $@;
+        };
 
-Delete Users
-  
-        Name: DeleteUser
-       Principals: <user> <group>
-  
-Modify Users
-  
-        Name: ModifyUser
-       Principals: <user> <group>
 
-Modify Self
-        Name: ModifySelf
-       Principals: <user> <group>
 
-Browse Users
 
-        Name: BrowseUsers (NOT IMPLEMENTED in 2.0)
-       Principals: <user> <group>
+=head1 SEE ALSO
 
-Modify Self
-                   
-       Name: ModifySelf
-       Principals: <user> <group>
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
 
-Modify System ACL
+These overlay files can contain new subs or subs to replace existing subs in this module.
 
-       Name: ModifyACL           
-       Principals: <user> <group>
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
 
-=head1 The Principal Side of the ACE
+   no warnings qw(redefine);
 
-=head2 PrincipalTypes,PrincipalIds in our Neighborhood
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
 
-  User,<userid>
-  Group,<groupip>
-  Everyone,NULL
+RT::ACE_Overlay, RT::ACE_Vendor, RT::ACE_Local
 
 =cut
 
-# }}}
+
+1;
diff --git a/rt/lib/RT/ACE_Overlay.pm b/rt/lib/RT/ACE_Overlay.pm
new file mode 100644 (file)
index 0000000..65e5a9c
--- /dev/null
@@ -0,0 +1,907 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 SYNOPSIS
+
+  use RT::ACE;
+  my $ace = new RT::ACE($CurrentUser);
+
+
+=head1 DESCRIPTION
+
+
+
+=head1 METHODS
+
+=begin testing
+
+ok(require RT::ACE);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+use RT::Principals;
+use RT::Queues;
+use RT::Groups;
+
+use vars qw (
+  %LOWERCASERIGHTNAMES
+  %OBJECT_TYPES
+  %TICKET_METAPRINCIPALS
+);
+
+
+# {{{ Descriptions of rights
+
+=head1 Rights
+
+# Queue rights are the sort of queue rights that can only be granted
+# to real people or groups
+
+
+=begin testing
+
+my $Queue = RT::Queue->new($RT::SystemUser);
+
+is ($Queue->AvailableRights->{'DeleteTicket'} , 'Delete tickets', "Found the delete ticket right");
+is ($RT::System->AvailableRights->{'SuperUser'},  'Do anything and everything', "Found the superuser right");
+
+
+=end testing
+
+=cut
+
+
+
+
+# }}}
+
+# {{{ Descriptions of principals
+
+%TICKET_METAPRINCIPALS = (
+    Owner     => 'The owner of a ticket',                             # loc_pair
+    Requestor => 'The requestor of a ticket',                         # loc_pair
+    Cc        => 'The CC of a ticket',                                # loc_pair
+    AdminCc   => 'The administrative CC of a ticket',                 # loc_pair
+);
+
+# }}}
+
+
+# {{{ sub LoadByValues
+
+=head2 LoadByValues PARAMHASH
+
+Load an ACE by specifying a paramhash with the following fields:
+
+              PrincipalId => undef,
+              PrincipalType => undef,
+             RightName => undef,
+
+        And either:
+
+             Object => undef,
+
+            OR
+
+        ObjectType => undef,
+        ObjectId => undef
+
+=cut
+
+sub LoadByValues {
+    my $self = shift;
+    my %args = ( PrincipalId   => undef,
+                 PrincipalType => undef,
+                 RightName     => undef,
+                 Object    => undef,
+                 ObjectId    => undef,
+                 ObjectType    => undef,
+                 @_ );
+
+    my $princ_obj;
+    ( $princ_obj, $args{'PrincipalType'} ) =
+      $self->_CanonicalizePrincipal( $args{'PrincipalId'},
+                                     $args{'PrincipalType'} );
+
+    unless ( $princ_obj->id ) {
+        return ( 0,
+                 $self->loc( 'Principal [_1] not found.', $args{'PrincipalId'} )
+        );
+    }
+
+    my ($object_type, $object_id);
+    
+    if ($args{'Object'} && UNIVERSAL::can($args{'Object'},'id')) {
+        $object_type = ref($args{'Object'});
+        $object_id = $args{'Object'}->id;
+    } elsif ($args{'ObjectId'} || $args{'ObjectType'}) {
+        $object_type = $args{'ObjectType'};
+        $object_id = $args{'ObjectId'};
+    } else {
+            return ( 0, $self->loc("System error. Right not granted.") );
+    }
+
+    $self->LoadByCols( PrincipalId   => $princ_obj->Id,
+                       PrincipalType => $args{'PrincipalType'},
+                       RightName     => $args{'RightName'},
+                       ObjectType    => $object_type,
+                       ObjectId      => $object_id);
+
+    #If we couldn't load it.
+    unless ( $self->Id ) {
+        return ( 0, $self->loc("ACE not found") );
+    }
+
+    # if we could
+    return ( $self->Id, $self->loc("Right Loaded") );
+
+}
+
+# }}}
+
+# {{{ sub Create
+
+=head2 Create <PARAMS>
+
+PARAMS is a parameter hash with the following elements:
+
+   PrincipalId => The id of an RT::Principal object
+   PrincipalType => "User" "Group" or any Role type
+   RightName => the name of a right. in any case
+   DelegatedBy => The Principal->Id of the user delegating the right
+   DelegatedFrom => The id of the ACE which this new ACE is delegated from
+
+
+    Either:
+
+   Object => An object to create rights for. ususally, an RT::Queue or RT::Group
+             This should always be a DBIx::SearchBuilder::Record subclass
+
+        OR
+
+   ObjectType => the type of the object in question (ref ($object))
+   ObjectId => the id of the object in question $object->Id
+
+=cut
+
+sub Create {
+    my $self = shift;
+    my %args = ( PrincipalId   => undef,
+                 PrincipalType => undef,
+                 RightName     => undef,
+                 Object    => $RT::System,
+                 @_ );
+
+    # {{{ Validate the principal
+    my $princ_obj;
+    ( $princ_obj, $args{'PrincipalType'} ) =
+      $self->_CanonicalizePrincipal( $args{'PrincipalId'},
+                                     $args{'PrincipalType'} );
+
+    unless ( $princ_obj->id ) {
+        return ( 0,
+                 $self->loc( 'Principal [_1] not found.', $args{'PrincipalId'} )
+        );
+    }
+
+    # }}}
+
+
+    if ($args{'Object'} && ($args{'ObjectId'} || $args{'ObjectType'})) {
+        use Carp;
+        $RT::Logger->crit(Carp::cluck("ACE::Create called with an ObjectType or an ObjectId"));
+    }
+
+
+    
+    unless ($args{'Object'} && UNIVERSAL::can($args{'Object'},'id')) {
+            return ( 0, $self->loc("System error. Right not granted.") );
+    }
+    # {{{ Check the ACL
+
+    if (ref( $args{'Object'}) eq 'RT::Group' ) {
+        unless ( $self->CurrentUser->HasRight( Object => $args{'Object'},
+                                                  Right => 'AdminGroup' )
+          ) {
+            return ( 0, $self->loc('Permission Denied') );
+        }
+    }
+
+    else {
+        unless ( $self->CurrentUser->HasRight( Object => $args{'Object'}, Right => 'ModifyACL' )) {
+            return ( 0, $self->loc('Permission Denied') );
+        }
+    }
+    # }}}
+
+    # {{{ Canonicalize and check the right name
+    unless ( $args{'RightName'} ) {
+        return ( 0, $self->loc('Invalid right') );
+    }
+
+    $args{'RightName'} = $self->CanonicalizeRightName( $args{'RightName'} );
+
+    #check if it's a valid RightName
+    if ( ref ($args{'Object'} eq 'RT::Queue'  )) {
+        unless ( exists $args{'Object'}->AvailableRights->{ $args{'RightName'} } ) {
+            $RT::Logger->warning("Couldn't validate right name". $args{'RightName'});
+            return ( 0, $self->loc('Invalid right') );
+        }
+    }
+    elsif ( ref ($args{'Object'} eq 'RT::Group'  )) {
+        unless ( exists $args{'Object'}->AvailableRights->{ $args{'RightName'} } ) {
+            $RT::Logger->warning("Couldn't validate group right name". $args{'RightName'});
+            return ( 0, $self->loc('Invalid right') );
+        }
+    }
+    elsif ( ref ($args{'Object'} eq 'RT::System'  )) {
+        my $q = RT::Queue->new($self->CurrentUser);
+        my $g = RT::Group->new($self->CurrentUser);
+
+        unless (( exists $g->AvailableRights->{ $args{'RightName'} } )
+        || ( exists $g->AvailableRights->{ $args{'RightName'} } )
+        || ( exists $RT::System->AvailableRights->{ $args{'RightName'} } ) ) {
+            $RT::Logger->warning("Couldn't validate system right name - ". $args{'RightName'});
+            return ( 0, $self->loc('Invalid right') );
+        }
+    }
+
+    unless ( $args{'RightName'} ) {
+        return ( 0, $self->loc('Invalid right') );
+    }
+    # }}}
+
+    # Make sure the right doesn't already exist.
+    $self->LoadByCols( PrincipalId   => $princ_obj->id,
+                       PrincipalType => $args{'PrincipalType'},
+                       RightName     => $args{'RightName'},
+                       ObjectType    => ref($args{'Object'}),
+                       ObjectId      => $args{'Object'}->id,
+                       DelegatedBy   => 0,
+                       DelegatedFrom => 0 );
+    if ( $self->Id ) {
+        return ( 0, $self->loc('That principal already has that right') );
+    }
+
+    my $id = $self->SUPER::Create( PrincipalId   => $princ_obj->id,
+                                   PrincipalType => $args{'PrincipalType'},
+                                   RightName     => $args{'RightName'},
+                                   ObjectType    => ref( $args{'Object'} ),
+                                   ObjectId      => $args{'Object'}->id,
+                                   DelegatedBy   => 0,
+                                   DelegatedFrom => 0 );
+
+    #Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space. 
+    RT::Principal->_InvalidateACLCache();
+
+    if ( $id > 0 ) {
+        return ( $id, $self->loc('Right Granted') );
+    }
+    else {
+        return ( 0, $self->loc('System error. Right not granted.') );
+    }
+}
+
+# }}}
+
+# {{{ sub Delegate
+
+=head2 Delegate <PARAMS>
+
+This routine delegates the current ACE to a principal specified by the
+B<PrincipalId>  parameter.
+
+Returns an error if the current user doesn't have the right to be delegated
+or doesn't have the right to delegate rights.
+
+Always returns a tuple of (ReturnValue, Message)
+
+=begin testing
+
+use_ok(RT::User);
+my $user_a = RT::User->new($RT::SystemUser);
+$user_a->Create( Name => 'DelegationA', Privileged => 1);
+ok ($user_a->Id, "Created delegation user a");
+
+my $user_b = RT::User->new($RT::SystemUser);
+$user_b->Create( Name => 'DelegationB', Privileged => 1);
+ok ($user_b->Id, "Created delegation user b");
+
+
+use_ok(RT::Queue);
+my $q = RT::Queue->new($RT::SystemUser);
+$q->Create(Name =>'DelegationTest');
+ok ($q->Id, "Created a delegation test queue");
+
+
+#------ First, we test whether a user can delegate a right that's been granted to him personally 
+my ($val, $msg) = $user_a->PrincipalObj->GrantRight(Object => $RT::System, Right => 'AdminOwnPersonalGroups');
+ok($val, $msg);
+
+($val, $msg) = $user_a->PrincipalObj->GrantRight(Object =>$q, Right => 'OwnTicket');
+ok($val, $msg);
+
+ok($user_a->HasRight( Object => $RT::System, Right => 'AdminOwnPersonalGroups')    ,"user a has the right 'AdminOwnPersonalGroups' directly");
+
+my $a_delegates = RT::Group->new($user_a);
+$a_delegates->CreatePersonalGroup(Name => 'Delegates');
+ok( $a_delegates->Id   ,"user a creates a personal group 'Delegates'");
+ok( $a_delegates->AddMember($user_b->PrincipalId)   ,"user a adds user b to personal group 'delegates'");
+
+ok( !$user_b->HasRight(Right => 'OwnTicket', Object => $q)    ,"user b does not have the right to OwnTicket' in queue 'DelegationTest'");
+ok(  $user_a->HasRight(Right => 'OwnTicket', Object => $q)  ,"user a has the right to 'OwnTicket' in queue 'DelegationTest'");
+ok(!$user_a->HasRight( Object => $RT::System, Right => 'DelegateRights')    ,"user a does not have the right 'delegate rights'");
+
+
+my $own_ticket_ace = RT::ACE->new($user_a);
+my $user_a_equiv_group = RT::Group->new($user_a);
+$user_a_equiv_group->LoadACLEquivalenceGroup($user_a->PrincipalObj);
+ok ($user_a_equiv_group->Id, "Loaded the user A acl equivalence group");
+my $user_b_equiv_group = RT::Group->new($user_b);
+$user_b_equiv_group->LoadACLEquivalenceGroup($user_b->PrincipalObj);
+ok ($user_b_equiv_group->Id, "Loaded the user B acl equivalence group");
+$own_ticket_ace->LoadByValues( PrincipalType => 'Group', PrincipalId => $user_a_equiv_group->PrincipalId, Object=>$q, RightName => 'OwnTicket');
+
+ok ($own_ticket_ace->Id, "Found the ACE we want to test with for now");
+
+
+($val, $msg) = $own_ticket_ace->Delegate(PrincipalId => $a_delegates->PrincipalId)  ;
+ok( !$val ,"user a tries and fails to delegate the right 'ownticket' in queue 'DelegationTest' to personal group 'delegates' - $msg");
+
+
+($val, $msg) = $user_a->PrincipalObj->GrantRight( Right => 'DelegateRights');
+ok($val, "user a is granted the right to 'delegate rights' - $msg");
+
+ok($user_a->HasRight( Object => $RT::System, Right => 'DelegateRights')    ,"user a has the right 'AdminOwnPersonalGroups' directly");
+
+($val, $msg) = $own_ticket_ace->Delegate(PrincipalId => $a_delegates->PrincipalId) ;
+
+ok( $val    ,"user a tries and succeeds to delegate the right 'ownticket' in queue 'DelegationTest' to personal group 'delegates' - $msg");
+ok(  $user_b->HasRight(Right => 'OwnTicket', Object => $q)  ,"user b has the right to own tickets in queue 'DelegationTest'");
+my $delegated_ace = RT::ACE->new($user_a);
+$delegated_ace->LoadByValues ( Object => $q, RightName => 'OwnTicket', PrincipalType => 'Group',
+PrincipalId => $a_delegates->PrincipalId, DelegatedBy => $user_a->PrincipalId, DelegatedFrom => $own_ticket_ace->Id);
+ok ($delegated_ace->Id, "Found the delegated ACE");
+
+ok(    $a_delegates->DeleteMember($user_b->PrincipalId)  ,"user a removes b from pg 'delegates'");
+ok(  !$user_b->HasRight(Right => 'OwnTicket', Object => $q)  ,"user b does not have the right to own tickets in queue 'DelegationTest'");
+ok(  $a_delegates->AddMember($user_b->PrincipalId)    ,"user a adds user b to personal group 'delegates'");
+ok(   $user_b->HasRight(Right => 'OwnTicket', Object=> $q) ,"user b has the right to own tickets in queue 'DelegationTest'");
+ok(   $delegated_ace->Delete ,"user a revokes pg 'delegates' right to 'OwnTickets' in queue 'DelegationTest'");
+ok( ! $user_b->HasRight(Right => 'OwnTicket', Object => $q)   ,"user b does not have the right to own tickets in queue 'DelegationTest'");
+
+($val, $msg) = $own_ticket_ace->Delegate(PrincipalId => $a_delegates->PrincipalId)  ;
+ok(  $val  ,"user a delegates pg 'delegates' right to 'OwnTickets' in queue 'DelegationTest' - $msg");
+
+ok( $user_a->HasRight(Right => 'OwnTicket', Object => $q)    ,"user a does not have the right to own tickets in queue 'DelegationTest'");
+
+($val, $msg) = $user_a->PrincipalObj->RevokeRight(Object=>$q, Right => 'OwnTicket');
+ok($val, "Revoked user a's right to own tickets in queue 'DelegationTest". $msg);
+
+ok( !$user_a->HasRight(Right => 'OwnTicket', Object => $q)    ,"user a does not have the right to own tickets in queue 'DelegationTest'");
+
+ ok( !$user_b->HasRight(Right => 'OwnTicket', Object => $q)   ,"user b does not have the right to own tickets in queue 'DelegationTest'");
+
+($val, $msg) = $user_a->PrincipalObj->GrantRight(Object=>$q, Right => 'OwnTicket');
+ok($val, $msg);
+
+ ok( $user_a->HasRight(Right => 'OwnTicket', Object => $q)   ,"user a has the right to own tickets in queue 'DelegationTest'");
+
+ ok(  !$user_b->HasRight(Right => 'OwnTicket', Object => $q)  ,"user b does not have the right to own tickets in queue 'DelegationTest'");
+
+# {{{ get back to a known clean state 
+($val, $msg) = $user_a->PrincipalObj->RevokeRight( Object => $q, Right => 'OwnTicket');
+ok($val, "Revoked user a's right to own tickets in queue 'DelegationTest -". $msg);
+ok( !$user_a->HasRight(Right => 'OwnTicket', Object => $q)    ,"make sure that user a can't own tickets in queue 'DelegationTest'");
+# }}}
+
+
+# {{{ Set up some groups and membership
+my $del1 = RT::Group->new($RT::SystemUser);
+($val, $msg) = $del1->CreateUserDefinedGroup(Name => 'Del1');
+ok( $val   ,"create a group del1 - $msg");
+
+my $del2 = RT::Group->new($RT::SystemUser);
+($val, $msg) = $del2->CreateUserDefinedGroup(Name => 'Del2');
+ok( $val   ,"create a group del2 - $msg");
+($val, $msg) = $del1->AddMember($del2->PrincipalId);
+ok( $val,"make del2 a member of del1 - $msg");
+
+my $del2a = RT::Group->new($RT::SystemUser);
+($val, $msg) = $del2a->CreateUserDefinedGroup(Name => 'Del2a');
+ok( $val   ,"create a group del2a - $msg");
+($val, $msg) = $del2->AddMember($del2a->PrincipalId);  
+ok($val    ,"make del2a a member of del2 - $msg");
+
+my $del2b = RT::Group->new($RT::SystemUser);
+($val, $msg) = $del2b->CreateUserDefinedGroup(Name => 'Del2b');
+ok( $val   ,"create a group del2b - $msg");
+($val, $msg) = $del2->AddMember($del2b->PrincipalId);  
+ok($val    ,"make del2b a member of del2 - $msg");
+
+($val, $msg) = $del2->AddMember($user_a->PrincipalId) ;
+ok($val,"make 'user a' a member of del2 - $msg");
+
+($val, $msg) = $del2b->AddMember($user_a->PrincipalId) ;
+ok($val,"make 'user a' a member of del2b - $msg");
+
+# }}}
+
+# {{{ Grant a right to a group and make sure that a submember can delegate the right and that it does not get yanked
+# when a user is removed as a submember, when they're a sumember through another path 
+($val, $msg) = $del1->PrincipalObj->GrantRight( Object=> $q, Right => 'OwnTicket');
+ok( $val   ,"grant del1  the right to 'OwnTicket' in queue 'DelegationTest' - $msg");
+
+ok(  $user_a->HasRight(Right => 'OwnTicket', Object => $q)  ,"make sure that user a can own tickets in queue 'DelegationTest'");
+
+my $group_ace= RT::ACE->new($user_a);
+$group_ace->LoadByValues( PrincipalType => 'Group', PrincipalId => $del1->PrincipalId, Object => $q, RightName => 'OwnTicket');
+
+ok ($group_ace->Id, "Found the ACE we want to test with for now");
+
+($val, $msg) = $group_ace->Delegate(PrincipalId => $a_delegates->PrincipalId);
+
+ok( $val   ,"user a tries and succeeds to delegate the right 'ownticket' in queue 'DelegationTest' to personal group 'delegates' - $msg");
+ok(  $user_b->HasRight(Right => 'OwnTicket', Object => $q)  ,"user b has the right to own tickets in queue 'DelegationTest'");
+
+
+($val, $msg) = $del2b->DeleteMember($user_a->PrincipalId);
+ok( $val   ,"remove user a from group del2b - $msg");
+ok(  $user_a->HasRight(Right => 'OwnTicket', Object => $q)  ,"user a has the right to own tickets in queue 'DelegationTest'");
+ok( $user_b->HasRight(Right => 'OwnTicket', Object => $q)    ,"user b has the right to own tickets in queue 'DelegationTest'");
+
+# }}}
+
+# {{{ When a  user is removed froom a group by the only path they're in there by, make sure the delegations go away
+($val, $msg) = $del2->DeleteMember($user_a->PrincipalId);
+ok( $val   ,"remove user a from group del2 - $msg");
+ok(  !$user_a->HasRight(Right => 'OwnTicket', Object => $q)  ,"user a does not have the right to own tickets in queue 'DelegationTest' ");
+ok(  !$user_b->HasRight(Right => 'OwnTicket', Object => $q)  ,"user b does not have the right to own tickets in queue 'DelegationTest' ");
+# }}}
+
+($val, $msg) = $del2->AddMember($user_a->PrincipalId);
+ok( $val   ,"make user a a member of group del2 - $msg");
+
+($val, $msg) = $del2->PrincipalObj->GrantRight(Object=>$q, Right => 'OwnTicket');
+ok($val, "grant the right 'own tickets' in queue 'DelegationTest' to group del2 - $msg");
+
+my $del2_right = RT::ACE->new($user_a);
+$del2_right->LoadByValues( PrincipalId => $del2->PrincipalId, PrincipalType => 'Group', Object => $q, RightName => 'OwnTicket');
+ok ($del2_right->Id, "Found the right");
+
+($val, $msg) = $del2_right->Delegate(PrincipalId => $a_delegates->PrincipalId);
+ok( $val   ,"user a tries and succeeds to delegate the right 'ownticket' in queue 'DelegationTest' gotten via del2 to personal group 'delegates' - $msg");
+
+# They have it via del1 and del2
+ok( $user_a->HasRight(Right => 'OwnTicket', Object => $q)   ,"user b has the right to own tickets in queue 'DelegationTest'");
+
+
+($val, $msg) = $del2->PrincipalObj->RevokeRight(Object=>$q, Right => 'OwnTicket');
+ok($val, "revoke the right 'own tickets' in queue 'DelegationTest' to group del2 - $msg");
+ok(  $user_a->HasRight(Right => 'OwnTicket', Object => $q)  ,"user a does has the right to own tickets in queue 'DelegationTest' via del1");
+ok(  !$user_b->HasRight(Right => 'OwnTicket', Object => $q)   ,"user b does not have the right to own tickets in queue 'DelegationTest'");
+
+($val, $msg) = $del2->PrincipalObj->GrantRight(Object=>$q, Right => 'OwnTicket');
+ok($val, "grant the right 'own tickets' in queue 'DelegationTest' to group del2 - $msg");
+
+
+$group_ace= RT::ACE->new($user_a);
+$group_ace->LoadByValues( PrincipalType => 'Group', PrincipalId => $del1->PrincipalId, Object=>$q, RightName => 'OwnTicket');
+
+ok ($group_ace->Id, "Found the ACE we want to test with for now");
+
+($val, $msg) = $group_ace->Delegate(PrincipalId => $a_delegates->PrincipalId);
+
+ok( $val   ,"user a tries and succeeds to delegate the right 'ownticket' in queue 'DelegationTest' to personal group 'delegates' - $msg");
+
+ok( $user_b->HasRight(Right => 'OwnTicket', Object => $q)    ,"user b has the right to own tickets in queue 'DelegationTest'");
+
+($val, $msg) = $del2->DeleteMember($user_a->PrincipalId);
+ok( $val   ,"remove user a from group del2 - $msg");
+
+ok(  !$user_a->HasRight(Right => 'OwnTicket', Object => $q)  ,"user a does not have the right to own tickets in queue 'DelegationTest'");
+
+ok(  !$user_b->HasRight(Right => 'OwnTicket', Object => $q)   ,"user b does not have the right to own tickets in queue 'DelegationTest'");
+
+
+
+=end testing
+
+=cut
+
+sub Delegate {
+    my $self = shift;
+    my %args = ( PrincipalId => undef,
+                 @_ );
+
+    unless ( $self->Id ) {
+        return ( 0, $self->loc("Right not loaded.") );
+    }
+    my $princ_obj;
+    ( $princ_obj, $args{'PrincipalType'} ) =
+      $self->_CanonicalizePrincipal( $args{'PrincipalId'},
+                                     $args{'PrincipalType'} );
+
+    unless ( $princ_obj->id ) {
+        return ( 0,
+                 $self->loc( 'Principal [_1] not found.', $args{'PrincipalId'} )
+        );
+    }
+
+    # }}}
+
+    # {{{ Check the ACL
+
+    # First, we check to se if the user is delegating rights and
+    # they have the permission to
+    unless ( $self->CurrentUser->HasRight(Right => 'DelegateRights', Object => $self->Object) ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+    unless ( $self->PrincipalObj->IsGroup ) {
+        return ( 0, $self->loc("System Error") );
+    }
+    unless ( $self->PrincipalObj->Object->HasMemberRecursively(
+                                                $self->CurrentUser->PrincipalObj
+             )
+      ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+    # }}}
+
+    my $concurrency_check = RT::ACE->new($RT::SystemUser);
+    $concurrency_check->Load( $self->Id );
+    unless ( $concurrency_check->Id ) {
+        $RT::Logger->crit(
+                   "Trying to delegate a right which had already been deleted");
+        return ( 0, $self->loc('Permission Denied') );
+    }
+
+    my $delegated_ace = RT::ACE->new( $self->CurrentUser );
+
+    # Make sure the right doesn't already exist.
+    $delegated_ace->LoadByCols( PrincipalId   => $princ_obj->Id,
+                                PrincipalType => 'Group',
+                                RightName     => $self->__Value('RightName'),
+                                ObjectType    => $self->__Value('ObjectType'),
+                                ObjectId      => $self->__Value('ObjectId'),
+                                DelegatedBy => $self->CurrentUser->PrincipalId,
+                                DelegatedFrom => $self->id );
+    if ( $delegated_ace->Id ) {
+        return ( 0, $self->loc('That principal already has that right') );
+    }
+    my $id = $delegated_ace->SUPER::Create(
+        PrincipalId   => $princ_obj->Id,
+        PrincipalType => 'Group',          # do we want to hardcode this?
+        RightName     => $self->__Value('RightName'),
+        ObjectType    => $self->__Value('ObjectType'),
+        ObjectId      => $self->__Value('ObjectId'),
+        DelegatedBy   => $self->CurrentUser->PrincipalId,
+        DelegatedFrom => $self->id );
+
+    #Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space. 
+    # TODO what about the groups key cache?
+    RT::Principal->_InvalidateACLCache();
+
+    if ( $id > 0 ) {
+        return ( $id, $self->loc('Right Delegated') );
+    }
+    else {
+        return ( 0, $self->loc('System error. Right not delegated.') );
+    }
+}
+
+# }}}
+
+# {{{ sub Delete 
+
+=head2 Delete { InsideTransaction => undef}
+
+Delete this object. This method should ONLY ever be called from RT::User or RT::Group (or from itself)
+If this is being called from within a transaction, specify a true value for the parameter InsideTransaction.
+Really, DBIx::SearchBuilder should use and/or fake subtransactions
+
+This routine will also recurse and delete any delegations of this right
+
+=cut
+
+sub Delete {
+    my $self = shift;
+
+    unless ( $self->Id ) {
+        return ( 0, $self->loc('Right not loaded.') );
+    }
+
+    # A user can delete an ACE if the current user has the right to modify it and it's not a delegated ACE
+    # or if it's a delegated ACE and it was delegated by the current user
+    unless (
+         (    $self->CurrentUser->HasRight(Right => 'ModifyACL', Object => $self->Object)
+           && $self->__Value('DelegatedBy') == 0 )
+         || ( $self->__Value('DelegatedBy') == $self->CurrentUser->PrincipalId )
+      ) {
+        return ( 0, $self->loc('Permission Denied') );
+    }
+    $self->_Delete(@_);
+}
+
+# Helper for Delete with no ACL check
+sub _Delete {
+    my $self = shift;
+    my %args = ( InsideTransaction => undef,
+                 @_ );
+
+    my $InsideTransaction = $args{'InsideTransaction'};
+
+    $RT::Handle->BeginTransaction() unless $InsideTransaction;
+
+    my $delegated_from_this = RT::ACL->new($RT::SystemUser);
+    $delegated_from_this->Limit( FIELD    => 'DelegatedFrom',
+                                 OPERATOR => '=',
+                                 VALUE    => $self->Id );
+
+    my $delete_succeeded = 1;
+    my $submsg;
+    while ( my $delegated_ace = $delegated_from_this->Next ) {
+        ( $delete_succeeded, $submsg ) =
+          $delegated_ace->_Delete( InsideTransaction => 1 );
+        last if ($delete_succeeded);
+    }
+
+    unless ($delete_succeeded) {
+        $RT::Handle->Rollback() unless $InsideTransaction;
+        return ( 0, $self->loc('Right could not be revoked') );
+    }
+
+    my ( $val, $msg ) = $self->SUPER::Delete(@_);
+
+    #Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space. 
+    # TODO what about the groups key cache?
+    RT::Principal->_InvalidateACLCache();
+
+    if ($val) {
+        $RT::Handle->Commit() unless $InsideTransaction;
+        return ( $val, $self->loc('Right revoked') );
+    }
+    else {
+        $RT::Handle->Rollback() unless $InsideTransaction;
+        return ( 0, $self->loc('Right could not be revoked') );
+    }
+}
+
+# }}}
+
+# {{{ sub _BootstrapCreate 
+
+=head2 _BootstrapCreate
+
+Grant a right with no error checking and no ACL. this is _only_ for 
+installation. If you use this routine without the author's explicit 
+written approval, he will hunt you down and make you spend eternity
+translating mozilla's code into FORTRAN or intercal.
+
+If you think you need this routine, you've mistaken. 
+
+=cut
+
+sub _BootstrapCreate {
+    my $self = shift;
+    my %args = (@_);
+
+    # When bootstrapping, make sure we get the _right_ users
+    if ( $args{'UserId'} ) {
+        my $user = RT::User->new( $self->CurrentUser );
+        $user->Load( $args{'UserId'} );
+        delete $args{'UserId'};
+        $args{'PrincipalId'}   = $user->PrincipalId;
+        $args{'PrincipalType'} = 'User';
+    }
+
+    my $id = $self->SUPER::Create(%args);
+
+    if ( $id > 0 ) {
+        return ($id);
+    }
+    else {
+        $RT::Logger->err('System error. right not granted.');
+        return (undef);
+    }
+
+}
+
+# }}}
+
+# {{{ sub CanonicalizeRightName
+
+=head2 CanonicalizeRightName <RIGHT>
+
+Takes a queue or system right name in any case and returns it in
+the correct case. If it's not found, will return undef.
+
+=cut
+
+sub CanonicalizeRightName {
+    my $self  = shift;
+    my $right = shift;
+    $right = lc $right;
+    if ( exists $LOWERCASERIGHTNAMES{"$right"} ) {
+        return ( $LOWERCASERIGHTNAMES{"$right"} );
+    }
+    else {
+        return (undef);
+    }
+}
+
+# }}}
+
+
+# {{{ sub Object
+
+=head2 Object
+
+If the object this ACE applies to is a queue, returns the queue object. 
+If the object this ACE applies to is a group, returns the group object. 
+If it's the system object, returns undef. 
+
+If the user has no rights, returns undef.
+
+=cut
+
+
+
+
+sub Object {
+    my $self = shift;
+
+    my $appliesto_obj;
+
+    if ($self->__Value('ObjectType') && $OBJECT_TYPES{$self->__Value('ObjectType')} ) {
+        $appliesto_obj =  $self->__Value('ObjectType')->new($self->CurrentUser);
+        unless (ref( $appliesto_obj) eq $self->__Value('ObjectType')) {
+            return undef;
+        }
+        $appliesto_obj->Load( $self->__Value('ObjectId') );
+        return ($appliesto_obj);
+     }
+    else {
+        $RT::Logger->warning( "$self -> Object called for an object "
+                              . "of an unknown type:"
+                              . $self->ObjectType );
+        return (undef);
+    }
+}
+
+# }}}
+
+# {{{ sub PrincipalObj
+
+=head2 PrincipalObj
+
+Returns the RT::Principal object for this ACE. 
+
+=cut
+
+sub PrincipalObj {
+    my $self = shift;
+
+    my $princ_obj = RT::Principal->new( $self->CurrentUser );
+    $princ_obj->Load( $self->__Value('PrincipalId') );
+
+    unless ( $princ_obj->Id ) {
+        $RT::Logger->err(
+                   "ACE " . $self->Id . " couldn't load its principal object" );
+    }
+    return ($princ_obj);
+
+}
+
+# }}}
+
+# {{{ ACL related methods
+
+# {{{ sub _Set
+
+sub _Set {
+    my $self = shift;
+    return ( 0, $self->loc("ACEs can only be created and deleted.") );
+}
+
+# }}}
+
+# {{{ sub _Value
+
+sub _Value {
+    my $self = shift;
+
+    if ( $self->__Value('DelegatedBy') eq $self->CurrentUser->PrincipalId ) {
+        return ( $self->__Value(@_) );
+    }
+    elsif ( $self->PrincipalObj->IsGroup
+            && $self->PrincipalObj->Object->HasMemberRecursively(
+                                                $self->CurrentUser->PrincipalObj
+            )
+      ) {
+        return ( $self->__Value(@_) );
+    }
+    elsif ( $self->CurrentUser->HasRight(Right => 'ShowACL', Object => $self->Object) ) {
+        return ( $self->__Value(@_) );
+    }
+    else {
+        return undef;
+    }
+}
+
+# }}}
+
+
+# }}}
+
+# {{{ _CanonicalizePrincipal 
+
+=head2 _CanonicalizePrincipal (PrincipalId, PrincipalType)
+
+Takes a principal id and a principal type.
+
+If the principal is a user, resolves it to the proper acl equivalence group.
+Returns a tuple of  (RT::Principal, PrincipalType)  for the principal we really want to work with
+
+=cut
+
+sub _CanonicalizePrincipal {
+    my $self       = shift;
+    my $princ_id   = shift;
+    my $princ_type = shift;
+
+    my $princ_obj = RT::Principal->new($RT::SystemUser);
+    $princ_obj->Load($princ_id);
+
+    unless ( $princ_obj->Id ) {
+        use Carp;
+        $RT::Logger->crit(Carp::cluck);
+        $RT::Logger->crit("Can't load a principal for id $princ_id");
+        return ( $princ_obj, undef );
+    }
+
+    # Rights never get granted to users. they get granted to their 
+    # ACL equivalence groups
+    if ( $princ_type eq 'User' ) {
+        my $equiv_group = RT::Group->new( $self->CurrentUser );
+        $equiv_group->LoadACLEquivalenceGroup($princ_obj);
+        unless ( $equiv_group->Id ) {
+            $RT::Logger->crit(
+                 "No ACL equiv group for princ " . $self->__Value('ObjectId') );
+            return ( 0, $self->loc('System error. Right not granted.') );
+        }
+        $princ_obj  = $equiv_group->PrincipalObj();
+        $princ_type = 'Group';
+
+    }
+    return ( $princ_obj, $princ_type );
+}
+
+# }}}
+1;
index 444a4c2..81f59c6 100755 (executable)
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/ACL.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# Distributed under the terms of the GNU GPL
-# Copyright (c) 2000 Jesse Vincent <jesse@fsck.com>
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-=head1 NAME
 
-  RT::ACL - collection of RT ACE objects
+=head1 NAME
 
+  RT::ACL -- Class Description
 =head1 SYNOPSIS
 
-  use RT::ACL;
-my $ACL = new RT::ACL($CurrentUser);
+  use RT::ACL
 
 =head1 DESCRIPTION
 
 
 =head1 METHODS
 
-=begin testing
-
-ok(require RT::TestHarness);
-ok(require RT::ACL);
-
-=end testing
-
 =cut
 
 package RT::ACL;
-use RT::EasySearch;
-use RT::ACE;
-@ISA= qw(RT::EasySearch);
-
-# {{{ sub _Init 
-sub _Init  {
-  my $self = shift;
-  $self->{'table'} = "ACL";
-  $self->{'primary_key'} = "id";
-  return ( $self->SUPER::_Init(@_));
-  
-}
-# }}}
-
-# {{{ sub NewItem 
-sub NewItem  {
-  my $self = shift;
-  return(RT::ACE->new($self->CurrentUser));
-}
-# }}}
-
-=head2 Next
-
-Hand out the next ACE that was found
-
-=cut
-
-# {{{ sub Next 
-sub Next {
-    my $self = shift;
-    
-    my $ACE = $self->SUPER::Next();
-    if ((defined($ACE)) and (ref($ACE))) {
-       
-       if ( $ACE->CurrentUserHasRight('ShowACL') or
-            $ACE->CurrentUserHasRight('ModifyACL')
-          ) {
-           return($ACE);
-       }
-       
-       #If the user doesn't have the right to show this ACE
-       else {  
-           return($self->Next());
-       }
-    }
-    #if there never was any ACE
-    else {
-       return(undef);
-    }  
-    
-}
 
-# }}}
-
-
-=head1 Limit the ACL to a specific scope
-
-There are two real scopes right now:
-
-=item Queue is for rights that apply to a single queue
-
-=item System is for rights that apply to the System (rights that aren't queue related)
-
-
-=head2 LimitToQueue
-
-Takes a single queueid as its argument.
+use RT::SearchBuilder;
+use RT::ACE;
 
-Limit the ACL to just a given queue when supplied with an integer queue id.
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
 
-=cut
 
-sub LimitToQueue {
+sub _Init {
     my $self = shift;
-    my $queue = shift;
-    
-    
-    
-    $self->Limit( FIELD =>'RightScope',
-                 ENTRYAGGREGATOR => 'OR',
-                 VALUE => 'Queue');
-    $self->Limit( FIELD =>'RightScope',
-                 ENTRYAGGREGATOR => 'OR',
-               VALUE => 'Ticket');
-    
-    $self->Limit(ENTRYAGGREGATOR => 'OR',
-                FIELD => 'RightAppliesTo',
-                VALUE => $queue );
-  
-}
-
-
-=head2 LimitToSystem()
-
-Limit the ACL to system rights
-
-=cut 
-
-sub LimitToSystem {
-  my $self = shift;
-  
-  $self->Limit( FIELD =>'RightScope',
-               VALUE => 'System');
-}
-
-
-=head2 LimitRightTo
-
-Takes a single RightName as its only argument.
-Limits the search to the right $right.
-$right is a right listed in perldoc RT::ACE
-
-=cut
-
-sub LimitRightTo {
-  my $self = shift;
-  my $right = shift;
-  
-  $self->Limit(ENTRYAGGREGATOR => 'OR',
-              FIELD => 'RightName',
-              VALUE => $right );
-  
-}
-
-=head1 Limit to a specifc set of principals
-
-=head2 LimitPrincipalToUser
-
-Takes a single userid as its only argument.
-Limit the ACL to a just a specific user.
-
-=cut
-
-sub LimitPrincipalToUser {
-  my $self = shift;
-  my $user = shift;
-  
-  $self->Limit(ENTRYAGGREGATOR => 'OR',
-              FIELD => 'PrincipalType',
-              VALUE => 'User' );
-  
-  $self->Limit(ENTRYAGGREGATOR => 'OR',
-              FIELD => 'PrincipalId',
-              VALUE => $user );
-  
-}
-
+    $self->{'table'} = 'ACL';
+    $self->{'primary_key'} = 'id';
 
-=head2 LimitPrincipalToGroup
-
-Takes a single group as its only argument.
-Limit the ACL to just a specific group.
-
-=cut
-  
-sub LimitPrincipalToGroup {
-  my $self = shift;
-  my $group = shift;
-  
-  $self->Limit(ENTRYAGGREGATOR => 'OR',
-              FIELD => 'PrincipalType',
-              VALUE => 'Group' );
-
-  $self->Limit(ENTRYAGGREGATOR => 'OR',
-              FIELD => 'PrincipalId',
-              VALUE => $group );
 
+    return ( $self->SUPER::_Init(@_) );
 }
 
-=head2 LimitPrincipalToType($type)
 
-Takes a single argument, $type.
-Limit the ACL to just a specific principal type
+=item NewItem
 
-$type is one of:
-  TicketOwner
-  TicketRequestor
-  TicketCc
-  TicketAdminCc
-  Everyone
-  User
-  Group
+Returns an empty new RT::ACE item
 
 =cut
 
-sub LimitPrincipalToType {
-  my $self=shift;
-  my $type=shift;  
-  $self->Limit(ENTRYAGGREGATOR => 'OR',
-               FIELD => 'PrincipalType',
-               VALUE => $type );
+sub NewItem {
+    my $self = shift;
+    return(RT::ACE->new($self->CurrentUser));
 }
 
+        eval "require RT::ACL_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/ACL_Overlay.pm}) {
+            die $@;
+        };
 
-=head2 LimitPrincipalToId 
+        eval "require RT::ACL_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/ACL_Vendor.pm}) {
+            die $@;
+        };
 
-Takes a single argument, the numeric Id of the principal to limit this ACL to. Repeated calls to this 
-function will broaden the scope of the search to include all principals listed.
-
-=cut
-
-sub LimitPrincipalToId {
-    my $self = shift;
-    my $id = shift;
-
-    if ($id =~ /^\d+$/) {
-       $self->Limit(ENTRYAGGREGATOR => 'OR',
-                    FIELD => 'PrincipalId',
-                    VALUE => $id );
-    }
-    else {
-       $RT::Logger->warn($self."->LimitPrincipalToId called with '$id' as an id");
-       return undef;
-    }
-}
+        eval "require RT::ACL_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/ACL_Local.pm}) {
+            die $@;
+        };
 
 
-#wrap around _DoSearch  so that we can build the hash of returned
-#values 
-sub _DoSearch {
-    my $self = shift;
-   # $RT::Logger->debug("Now in ".$self."->_DoSearch");
-    my $return = $self->SUPER::_DoSearch(@_);
-  #  $RT::Logger->debug("In $self ->_DoSearch. return from SUPER::_DoSearch was $return\n");
-    $self->_BuildHash();
-    return ($return);
-}
 
 
-#Build a hash of this ACL's entries.
-sub _BuildHash {
-    my $self = shift;
+=head1 SEE ALSO
 
-    while (my $entry = $self->Next) {
-       my $hashkey = $entry->RightScope . "-" .
-                             $entry->RightAppliesTo . "-" . 
-                             $entry->RightName . "-" .
-                             $entry->PrincipalId . "-" .
-                             $entry->PrincipalType;
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
 
-        $self->{'as_hash'}->{"$hashkey"} =1;
+These overlay files can contain new subs or subs to replace existing subs in this module.
 
-    }
-}
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
 
+   no warnings qw(redefine);
 
-# {{{ HasEntry
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
 
-=head2 HasEntry
+RT::ACL_Overlay, RT::ACL_Vendor, RT::ACL_Local
 
 =cut
 
-sub HasEntry {
-
-    my $self = shift;
-    my %args = ( RightScope => undef,
-                 RightAppliesTo => undef,
-                 RightName => undef,
-                 PrincipalId => undef,
-                 PrincipalType => undef,
-                 @_ );
-
-    #if we haven't done the search yet, do it now.
-    $self->_DoSearch();
-
-    if ($self->{'as_hash'}->{ $args{'RightScope'} . "-" .
-                             $args{'RightAppliesTo'} . "-" . 
-                             $args{'RightName'} . "-" .
-                             $args{'PrincipalId'} . "-" .
-                             $args{'PrincipalType'}
-                            } == 1) {
-       return(1);
-    }
-    else {
-       return(undef);
-    }
-}
 
-# }}}
 1;
diff --git a/rt/lib/RT/ACL_Overlay.pm b/rt/lib/RT/ACL_Overlay.pm
new file mode 100644 (file)
index 0000000..9775776
--- /dev/null
@@ -0,0 +1,295 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::ACL - collection of RT ACE objects
+
+=head1 SYNOPSIS
+
+  use RT::ACL;
+my $ACL = new RT::ACL($CurrentUser);
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=begin testing
+
+ok(require RT::ACL);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+
+=head2 Next
+
+Hand out the next ACE that was found
+
+=cut
+
+
+# {{{ LimitToObject 
+
+=head2 LimitToObject $object
+
+Limit the ACL to rights for the object $object. It needs to be an RT::Record class.
+
+=cut
+
+sub LimitToObject {
+    my $self = shift;
+    my $obj = shift;
+    unless (defined($obj) && ref($obj) && UNIVERSAL::can($obj, 'id')) {
+    return undef;
+    }
+    $self->Limit(FIELD => 'ObjectType', OPERATOR=> '=', VALUE => ref($obj), ENTRYAGGREGATOR => 'OR');
+    $self->Limit(FIELD => 'ObjectId', OPERATOR=> '=', VALUE => $obj->id, ENTRYAGGREGATOR => 'OR', QUOTEVALUE => 0);
+
+}
+
+# }}}
+
+# {{{ LimitToPrincipal 
+
+=head2 LimitToPrincipal { Type => undef, Id => undef, IncludeGroupMembership => undef }
+
+Limit the ACL to the principal with PrincipalId Id and PrincipalType Type
+
+Id is not optional.
+Type is.
+
+if IncludeGroupMembership => 1 is specified, ACEs which apply to the principal due to group membership will be included in the resultset.
+
+
+=cut
+
+sub LimitToPrincipal {
+    my $self = shift;
+    my %args = ( Type                               => undef,
+                 Id                                 => undef,
+                 IncludeGroupMembership => undef,
+                 @_ );
+    if ( $args{'IncludeGroupMembership'} ) {
+        my $cgm = $self->NewAlias('CachedGroupMembers');
+        $self->Join( ALIAS1 => 'main',
+                     FIELD1 => 'PrincipalId',
+                     ALIAS2 => $cgm,
+                     FIELD2 => 'GroupId' );
+        $self->Limit( ALIAS           => $cgm,
+                      FIELD           => 'MemberId',
+                      OPERATOR        => '=',
+                      VALUE           => $args{'Id'},
+                      ENTRYAGGREGATOR => 'OR' );
+    }
+    else {
+        if ( defined $args{'Type'} ) {
+            $self->Limit( FIELD           => 'PrincipalType',
+                          OPERATOR        => '=',
+                          VALUE           => $args{'Type'},
+                          ENTRYAGGREGATOR => 'OR' );
+        }
+    # if the principal id points to a user, we really want to point
+    # to their ACL equivalence group. The machinations we're going through
+    # lead me to start to suspect that we really want users and groups
+    # to just be the same table. or _maybe_ that we want an object db.
+    my $princ = RT::Principal->new($RT::SystemUser);
+    $princ->Load($args{'PrincipalId'});
+    if ($princ->PrincipalType eq 'User') {
+    my $group = RT::Group->new($RT::SystemUser);
+        $group->LoadACLEquivalenceGroup($princ);
+        $args{'PrincipalId'} = $group->PrincipalId;
+    }
+        $self->Limit( FIELD           => 'PrincipalId',
+                      OPERATOR        => '=',
+                      VALUE           => $args{'Id'},
+                      ENTRYAGGREGATOR => 'OR' );
+    }
+}
+
+# }}}
+
+
+
+# {{{ ExcludeDelegatedRights
+
+=head2 ExcludeDelegatedRights 
+
+Don't list rights which have been delegated.
+
+=cut
+
+sub ExcludeDelegatedRights {
+    my $self = shift;
+    $self->DelegatedBy(Id => 0);
+    $self->DelegatedFrom(Id => 0);
+}
+# }}}
+
+# {{{ DelegatedBy 
+
+=head2 DelegatedBy { Id => undef }
+
+Limit the ACL to rights delegated by the principal whose Principal Id is
+B<Id>
+
+Id is not optional.
+
+=cut
+
+sub DelegatedBy {
+    my $self = shift;
+    my %args = (
+        Id => undef,
+        @_
+    );
+    $self->Limit(
+        FIELD           => 'DelegatedBy',
+        OPERATOR        => '=',
+        VALUE           => $args{'Id'},
+        ENTRYAGGREGATOR => 'OR'
+    );
+
+}
+
+# }}}
+
+# {{{ DelegatedFrom 
+
+=head2 DelegatedFrom { Id => undef }
+
+Limit the ACL to rights delegate from the ACE which has the Id specified 
+by the Id parameter.
+
+Id is not optional.
+
+=cut
+
+sub DelegatedFrom {
+    my $self = shift;
+    my %args = (
+                 Id => undef,
+                 @_);
+    $self->Limit(FIELD => 'DelegatedFrom', OPERATOR=> '=', VALUE => $args{'Id'}, ENTRYAGGREGATOR => 'OR');
+
+}
+
+# }}}
+
+
+# {{{ sub Next 
+sub Next {
+    my $self = shift;
+
+    my $ACE = $self->SUPER::Next();
+    if ( ( defined($ACE) ) and ( ref($ACE) ) ) {
+
+        if ( $self->CurrentUser->HasRight( Right  => 'ShowACL',
+                                           Object => $ACE->Object )
+             or $self->CurrentUser->HasRight( Right  => 'ModifyACL',
+                                              Object => $ACE->Object )
+          ) {
+            return ($ACE);
+        }
+
+        #If the user doesn't have the right to show this ACE
+        else {
+            return ( $self->Next() );
+        }
+    }
+
+    #if there never was any ACE
+    else {
+        return (undef);
+    }
+
+}
+
+# }}}
+
+
+
+#wrap around _DoSearch  so that we can build the hash of returned
+#values 
+sub _DoSearch {
+    my $self = shift;
+   # $RT::Logger->debug("Now in ".$self."->_DoSearch");
+    my $return = $self->SUPER::_DoSearch(@_);
+  #  $RT::Logger->debug("In $self ->_DoSearch. return from SUPER::_DoSearch was $return\n");
+    $self->_BuildHash();
+    return ($return);
+}
+
+
+#Build a hash of this ACL's entries.
+sub _BuildHash {
+    my $self = shift;
+
+    while (my $entry = $self->Next) {
+       my $hashkey = $entry->ObjectType . "-" .  $entry->ObjectId . "-" .  $entry->RightName . "-" .  $entry->PrincipalId . "-" .  $entry->PrincipalType;
+
+        $self->{'as_hash'}->{"$hashkey"} =1;
+
+    }
+}
+
+
+# {{{ HasEntry
+
+=head2 HasEntry
+
+=cut
+
+sub HasEntry {
+
+    my $self = shift;
+    my %args = ( RightScope => undef,
+                 RightAppliesTo => undef,
+                 RightName => undef,
+                 PrincipalId => undef,
+                 PrincipalType => undef,
+                 @_ );
+
+    #if we haven't done the search yet, do it now.
+    $self->_DoSearch();
+
+    if ($self->{'as_hash'}->{ $args{'RightScope'} . "-" .
+                             $args{'RightAppliesTo'} . "-" . 
+                             $args{'RightName'} . "-" .
+                             $args{'PrincipalId'} . "-" .
+                             $args{'PrincipalType'}
+                            } == 1) {
+       return(1);
+    }
+    else {
+       return(undef);
+    }
+}
+
+# }}}
+1;
diff --git a/rt/lib/RT/Action/AutoOpen.pm b/rt/lib/RT/Action/AutoOpen.pm
new file mode 100644 (file)
index 0000000..ea6da19
--- /dev/null
@@ -0,0 +1,86 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# This Action will open the BASE if a dependent is resolved.
+
+package RT::Action::AutoOpen;
+require RT::Action::Generic;
+
+use strict;
+use vars qw/@ISA/;
+@ISA=qw(RT::Action::Generic);
+
+#Do what we need to do and send it out.
+
+#What does this type of Action does
+
+# {{{ sub Describe 
+sub Describe  {
+  my $self = shift;
+  return (ref $self );
+}
+# }}}
+
+
+# {{{ sub Prepare 
+sub Prepare {
+    my $self = shift;
+
+    # if the ticket is already open or the ticket is new and the message is more mail from the
+    # requestor, don't reopen it.
+
+    if ( ( $self->TicketObj->Status eq 'open' )
+         || ( ( $self->TicketObj->Status eq 'new' )
+              && $self->TransactionObj->IsInbound )
+      ) {
+
+        return undef;
+    }
+    else {
+        return (1);
+    }
+}
+# }}}
+
+sub Commit {
+    my $self = shift;
+      my $oldstatus = $self->TicketObj->Status();
+        $self->TicketObj->__Set( Field => 'Status', Value => 'open' );
+        $self->TicketObj->_NewTransaction(
+                         Type     => 'Set',
+                         Field    => 'Status',
+                         OldValue => $oldstatus,
+                         NewValue => 'open',
+                         Data => 'Ticket auto-opened on incoming correspondence'
+        );
+
+
+    return(1);
+}
+
+eval "require RT::Action::AutoOpen_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/AutoOpen_Vendor.pm});
+eval "require RT::Action::AutoOpen_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/AutoOpen_Local.pm});
+
+1;
index 624888e..81f7bdd 100755 (executable)
@@ -1,7 +1,31 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/Autoreply.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 package RT::Action::Autoreply;
 require RT::Action::SendEmail;
+
+use strict;
+use vars qw/@ISA/;
 @ISA = qw(RT::Action::SendEmail);
 
 
@@ -17,7 +41,7 @@ Sets the recipients of this message to this ticket's Requestor.
 sub SetRecipients {
     my $self=shift;
 
-    push(@{$self->{'To'}}, @{$self->TicketObj->Requestors->Emails});
+    push(@{$self->{'To'}}, $self->TicketObj->Requestors->MemberEmailAddresses);
     
     return(1);
 }
@@ -39,6 +63,7 @@ sub SetReturnAddress {
                 @_
               );
     
+    my $replyto;
     if ($args{'is_comment'}) { 
        $replyto = $self->TicketObj->QueueObj->CommentAddress || 
                     $RT::CommentAddress;
@@ -49,7 +74,9 @@ sub SetReturnAddress {
     }
     
     unless ($self->TemplateObj->MIMEObj->head->get('From')) {
-       my $friendly_name=$self->TicketObj->QueueObj->Name;
+       my $friendly_name = $self->TicketObj->QueueObj->Description ||
+               $self->TicketObj->QueueObj->Name;
+       $friendly_name =~ s/"/\\"/g;
        $self->SetHeader('From', "\"$friendly_name\" <$replyto>");
     }
     
@@ -61,4 +88,9 @@ sub SetReturnAddress {
   
 # }}}
 
+eval "require RT::Action::Autoreply_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/Autoreply_Vendor.pm});
+eval "require RT::Action::Autoreply_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/Autoreply_Local.pm});
+
 1;
diff --git a/rt/lib/RT/Action/CreateTickets.pm b/rt/lib/RT/Action/CreateTickets.pm
new file mode 100644 (file)
index 0000000..0ab2067
--- /dev/null
@@ -0,0 +1,564 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+package RT::Action::CreateTickets;
+require RT::Action::Generic;
+
+use strict;
+use vars qw/@ISA/;
+@ISA = qw(RT::Action::Generic);
+
+use MIME::Entity;
+
+=head1 NAME
+
+ RT::Action::CreateTickets
+
+Create one or more tickets according to an externally supplied template.
+
+
+=head1 SYNOPSIS
+
+ ===Create-Ticket: codereview
+ Subject: Code review for {$Tickets{'TOP'}->Subject}
+ Depended-On-By: {$Tickets{'TOP'}->Id}
+ Content: Someone has created a ticket. you should review and approve it,
+ so they can finish their work
+ ENDOFCONTENT
+
+=head1 DESCRIPTION
+
+
+Using the "CreateTickets" ScripAction and mandatory dependencies, RT now has 
+the ability to model complex workflow. When a ticket is created in a queue
+that has a "CreateTickets" scripaction, that ScripAction parses its "Template"
+
+
+
+=head2 FORMAT
+
+CreateTickets uses the template as a template for an ordered set of tickets 
+to create. The basic format is as follows:
+
+
+ ===Create-Ticket: identifier
+ Param: Value
+ Param2: Value
+ Param3: Value
+ Content: Blah
+ blah
+ blah
+ ENDOFCONTENT
+ ===Create-Ticket: id2
+ Param: Value
+ Content: Blah
+ ENDOFCONTENT
+
+
+Each ===Create-Ticket: section is evaluated as its own 
+Text::Template object, which means that you can embed snippets
+of perl inside the Text::Template using {} delimiters, but that 
+such sections absolutely can not span a ===Create-Ticket boundary.
+
+After each ticket is created, it's stuffed into a hash called %Tickets
+so as to be available during the creation of other tickets during the same 
+ScripAction.  The hash is prepopulated with the ticket which triggered the 
+ScripAction as $Tickets{'TOP'}; you can also access that ticket using the
+shorthand $TOP.
+
+A simple example:
+
+ ===Create-Ticket: codereview
+ Subject: Code review for {$Tickets{'TOP'}->Subject}
+ Depended-On-By: {$Tickets{'TOP'}->Id}
+ Content: Someone has created a ticket. you should review and approve it,
+ so they can finish their work
+ ENDOFCONTENT
+
+
+
+A convoluted example
+
+ ===Create-Ticket: approval
+ { # Find out who the administrators of the group called "HR" 
+   # of which the creator of this ticket is a member
+    my $name = "HR";
+   
+    my $groups = RT::Groups->new($RT::SystemUser);
+    $groups->LimitToUserDefinedGroups();
+    $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => "$name");
+    $groups->WithMember($TransactionObj->CreatorObj->Id);
+    my $groupid = $groups->First->Id;
+    my $adminccs = RT::Users->new($RT::SystemUser);
+    $adminccs->WhoHaveRight(
+       Right => "AdminGroup",
+       Object =>$groups->First,
+       IncludeSystemRights => undef,
+       IncludeSuperusers => 0,
+       IncludeSubgroupMembers => 0,
+    );
+     my @admins;
+     while (my $admin = $adminccs->Next) {
+         push (@admins, $admin->EmailAddress); 
+     }
+ }
+ Queue: Approvals
+ Type: Approval
+ AdminCc: {join ("\nAdminCc: ",@admins) }
+ Depended-On-By: {$Tickets{"TOP"}->Id}
+ Refers-To: {$Tickets{"TOP"}->Id}
+ Subject: Approval for ticket: {$Tickets{"TOP"}->Id} - {$Tickets{"TOP"}->Subject}
+ Due: {time + 86400}
+ Content-Type: text/plain
+ Content: Your approval is requested for the ticket {$Tickets{"TOP"}->Id}: {$Tickets{"TOP"}->Subject}
+ Blah
+ Blah
+ ENDOFCONTENT
+ ===Create-Ticket: two
+ Subject: Manager approval
+ Depended-On-By: {$Tickets{"TOP"}->Id}
+ Refers-On: {$Tickets{"approval"}->Id}
+ Queue: Approvals
+ Content-Type: text/plain
+ Content: 
+ Your approval is requred for this ticket, too.
+ ENDOFCONTENT
+=head2 Acceptable fields
+
+A complete list of acceptable fields for this beastie:
+
+
+    *  Queue           => Name or id# of a queue
+       Subject         => A text string
+     ! Status          => A valid status. defaults to 'new'
+       Due             => Dates can be specified in seconds since the epoch
+                          to be handled literally or in a semi-free textual
+                          format which RT will attempt to parse.
+                        
+                          
+                          
+       Starts          => 
+       Started         => 
+       Resolved        => 
+       Owner           => Username or id of an RT user who can and should own 
+                          this ticket
+   +   Requestor       => Email address
+   +   Cc              => Email address 
+   +   AdminCc         => Email address 
+       TimeWorked      => 
+       TimeEstimated   => 
+       TimeLeft        => 
+       InitialPriority => 
+       FinalPriority   => 
+       Type            => 
+    +! DependsOn       => 
+    +! DependedOnBy    =>
+    +! RefersTo        =>
+    +! ReferredToBy    => 
+    +! Members         =>
+    +! MemberOf        => 
+       Content         => content. Can extend to multiple lines. Everything
+                          within a template after a Content: header is treated
+                          as content until we hit a line containing only 
+                          ENDOFCONTENT
+       ContentType     => the content-type of the Content field
+       CustomField-<id#> => custom field value
+
+Fields marked with an * are required.
+
+Fields marked with a + man have multiple values, simply
+by repeating the fieldname on a new line with an additional value.
+
+Fields marked with a ! are postponed to be processed after all
+tickets in the same actions are created.  Except for 'Status', those
+field can also take a ticket name within the same action (i.e.
+the identifiers after ==Create-Ticket), instead of raw Ticket ID
+numbers.
+
+When parsed, field names are converted to lowercase and have -s stripped.
+Refers-To, RefersTo, refersto, refers-to and r-e-f-er-s-tO will all 
+be treated as the same thing.
+
+
+=begin testing
+
+ok (require RT::Action::CreateTickets);
+use_ok(RT::Scrip);
+use_ok(RT::Template);
+use_ok(RT::ScripAction);
+use_ok(RT::ScripCondition);
+use_ok(RT::Ticket);
+
+my $approvalsq = RT::Queue->new($RT::SystemUser);
+$approvalsq->Create(Name => 'Approvals');
+ok ($approvalsq->Id, "Created Approvals test queue");
+
+
+my $approvals = 
+'===Create-Ticket: approval
+{  my $name = "HR";
+     my $groups = RT::Groups->new($RT::SystemUser);
+   $groups->LimitToUserDefinedGroups();
+   $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => "$name");
+   $groups->WithMember($Transaction->CreatorObj->Id);
+
+   my $groupid = $groups->First->Id;
+
+   my $adminccs = RT::Users->new($RT::SystemUser);
+   $adminccs->WhoHaveRight(Right => "AdminGroup", IncludeSystemRights => undef, IncludeSuperusers => 0, IncludeSubgroupMembers => 0, Object => $groups->First);
+
+    my @admins;
+    while (my $admin = $adminccs->Next) {
+        push (@admins, $admin->EmailAddress); 
+    }
+}
+Queue: Approvals
+Type: Approval
+AdminCc: {join ("\nAdminCc: ",@admins) }
+Depended-On-By: {$Tickets{"TOP"}->Id}
+Refers-To: {$Tickets{"TOP"}->Id}
+Subject: Approval for ticket: {$Tickets{"TOP"}->Id} - {$Tickets{"TOP"}->Subject}
+Due: {time + 86400}
+Content-Type: text/plain
+Content: Your approval is requested for the ticket {$Tickets{"TOP"}->Id}: {$Tickets{"TOP"}->Subject}
+Blah
+Blah
+ENDOFCONTENT
+===Create-Ticket: two
+Subject: Manager approval.
+Depends-On: {$Tickets{"approval"}->Id}
+Queue: Approvals
+Content-Type: text/plain
+Content: 
+Your minion approved this ticket. you ok with that?
+ENDOFCONTENT
+';
+
+ok ($approvals =~ /Content/, "Read in the approvals template");
+
+my $apptemp = RT::Template->new($RT::SystemUser);
+$apptemp->Create( Content => $approvals, Name => "Approvals", Queue => "0");
+
+ok ($apptemp->Id);
+
+my $q = RT::Queue->new($RT::SystemUser);
+$q->Create(Name => 'WorkflowTest');
+ok ($q->Id, "Created workflow test queue");
+
+my $scrip = RT::Scrip->new($RT::SystemUser);
+my ($sval, $smsg) =$scrip->Create( ScripCondition => 'On Transaction',
+                ScripAction => 'Create Tickets',
+                Template => 'Approvals',
+                Queue => $q->Id);
+ok ($sval, $smsg);
+ok ($scrip->Id, "Created the scrip");
+ok ($scrip->TemplateObj->Id, "Created the scrip template");
+ok ($scrip->ConditionObj->Id, "Created the scrip condition");
+ok ($scrip->ActionObj->Id, "Created the scrip action");
+
+my $t = RT::Ticket->new($RT::SystemUser);
+$t->Create(Subject => "Sample workflow test",
+           Owner => "root",
+           Queue => $q->Id);
+
+
+=end testing
+
+
+=head1 AUTHOR
+
+Jesse Vincent <jesse@bestpractical.com> 
+
+=head1 SEE ALSO
+
+perl(1).
+
+=cut
+
+my %LINKTYPEMAP = (
+    MemberOf => { Type => 'MemberOf',
+                  Mode => 'Target', },
+    Members => { Type => 'MemberOf',
+                 Mode => 'Base', },
+    HasMember => { Type => 'MemberOf',
+                   Mode => 'Base', },
+    RefersTo => { Type => 'RefersTo',
+                  Mode => 'Target', },
+    ReferredToBy => { Type => 'RefersTo',
+                      Mode => 'Base', },
+    DependsOn => { Type => 'DependsOn',
+                   Mode => 'Target', },
+    DependedOnBy => { Type => 'DependsOn',
+                      Mode => 'Base', },
+
+);
+
+# {{{ Scrip methods (Commit, Prepare)
+
+# {{{ sub Commit 
+#Do what we need to do and send it out.
+sub Commit {
+    my $self = shift;
+    my (@links, @postponed);
+
+    # XXX: cargo cult programming that works. i'll be back.
+    use bytes;
+
+    # Create all the tickets we care about
+    return(1) unless $self->TicketObj->Type eq 'ticket';
+
+    %T::Tickets = ();
+
+    foreach my $template_id ( @{ $self->{'template_order'} } ) {
+       $T::Tickets{'TOP'} = $T::TOP = $self->TicketObj;
+       $RT::Logger->debug("Workflow: processing $template_id of $T::TOP");
+
+       $T::ID = $template_id;
+       @T::AllID = @{ $self->{'template_order'} };
+
+        my $template = Text::Template->new(
+             TYPE   => 'STRING',
+             SOURCE => $self->{'templates'}->{$template_id}
+        );
+
+       $RT::Logger->debug("Workflow: evaluating\n$self->{templates}{$template_id}");
+
+       my $err;
+        my $filled_in = $template->fill_in( PACKAGE => 'T', BROKEN => sub {
+           $err = { @_ }->{error};
+       } );
+
+       $RT::Logger->debug("Workflow: yielding\n$filled_in");
+
+       if ($err) {
+           $RT::Logger->error("Ticket creation failed for ".$self->TicketObj->Id." ".$err);
+           while (my ($k, $v) = each %T::X) {
+               $RT::Logger->debug("Eliminating $template_id from ${k}'s parents.");
+               delete $v->{$template_id};
+           }
+           next;
+       }
+
+        my %args;
+        my @lines = ( split ( /\n/, $filled_in ) );
+        while ( defined(my $line = shift @lines) ) {
+            if ( $line =~ /^(.*?):(?:\s+(.*))?$/ ) {
+                my $value = $2;
+                my $tag = lc ($1);
+                $tag =~ s/-//g;
+
+               if (ref($args{$tag})) { #If it's an array, we want to push the value
+                   push @{$args{$tag}}, $value;
+               }
+               elsif (defined ($args{$tag})) { #if we're about to get a second value, make it an array
+                   $args{$tag} = [$args{$tag}, $value];
+               }
+               else { #if there's nothing there, just set the value
+                   $args{ $tag } = $value;
+               }
+
+                if ( $tag eq 'content' ) { #just build up the content
+                        # convert it to an array
+                        $args{$tag} = defined($value) ? [ $value."\n" ] : [];
+                      while ( defined(my $l = shift @lines) ) {
+                        last if ($l =~  /^ENDOFCONTENT\s*$/) ;
+                        push @{$args{'content'}}, $l."\n";
+                        }
+                }
+            }
+       }
+
+       foreach my $date qw(due starts started resolved) {
+           my $dateobj = RT::Date->new($RT::SystemUser);
+           next unless $args{$date};
+           if ($args{$date} =~ /^\d+$/) {
+               $dateobj->Set(Format => 'unix', Value => $args{$date});
+           } else {
+               $dateobj->Set(Format => 'unknown', Value => $args{$date});
+           }
+           $args{$date} = $dateobj->ISO;
+       }
+       my $mimeobj = MIME::Entity->new();
+       $mimeobj->build(Type => $args{'contenttype'},
+                       Data => $args{'content'});
+       # Now we have a %args to work with. 
+       # Make sure we have at least the minimum set of 
+       # reasonable data and do our thang
+       $T::Tickets{$template_id} ||= RT::Ticket->new($RT::SystemUser);
+
+       # Deferred processing   
+       push @links, (
+           $T::Tickets{$template_id}, {
+               DependsOn               => $args{'dependson'},
+               DependedOnBy    => $args{'dependedonby'},
+               RefersTo                => $args{'refersto'},
+               ReferredToBy    => $args{'referredtoby'},
+               Members         => $args{'members'},
+               MemberOf                => $args{'memberof'},
+           }
+       );
+
+       push @postponed, (
+           # Status is postponed so we don't violate dependencies
+           $T::Tickets{$template_id}, {
+               Status          => $args{'status'},
+           }
+       );
+
+       $args{'requestor'} ||= $self->TicketObj->Requestors->MemberEmailAddresses;
+
+       my %ticketargs = ( Queue => $args{'queue'},
+                     Subject=> $args{'subject'},
+                   Status => 'new',
+                   Due => $args{'due'},
+                   Starts => $args{'starts'},
+                   Started => $args{'started'},
+                   Resolved => $args{'resolved'},
+                   Owner => $args{'owner'},
+                   Requestor => $args{'requestor'},
+                   Cc => $args{'cc'},
+                   AdminCc=> $args{'admincc'},
+                   TimeWorked =>$args{'timeworked'},
+                   TimeEstimated =>$args{'timeestimated'},
+                   TimeLeft =>$args{'timeleft'},
+                   InitialPriority => $args{'initialpriority'},
+                   FinalPriority => $args{'finalpriority'},
+                   Type => $args{'type'}, 
+                   MIMEObj => $mimeobj);
+
+
+       foreach my $key (keys(%args)) {
+           $key =~ /^customfield-(\d+)$/ or next;
+           $ticketargs{ "CustomField-" . $1 } = $args{$key};
+       }
+
+       my ($id, $transid, $msg) = $T::Tickets{$template_id}->Create(%ticketargs);
+       if (!$id) {
+           $RT::Logger->error(
+               "Couldn't create related ticket $template_id for ".
+               $self->TicketObj->Id." ".$msg
+           );
+           next;
+       }
+
+       $RT::Logger->debug("Assigned $template_id with $id");
+       $T::Tickets{$template_id}->SetOriginObj($self->TicketObj)
+           if $T::Tickets{$template_id}->can('SetOriginObj');
+    }
+
+    # postprocessing: add links
+
+    while (my $ticket = shift(@links)) {
+       $RT::Logger->debug("Handling links for " . $ticket->Id);
+       my %args = %{shift(@links)};
+
+       foreach my $type ( keys %LINKTYPEMAP ) {
+           next unless (defined $args{$type});
+           foreach my $link (
+               ref( $args{$type} ) ? @{ $args{$type} } : ( $args{$type} ) )
+           {
+               if (!exists $T::Tickets{$link}) {
+                   $RT::Logger->debug("Skipping $type link for $link (non-existent)");
+                   next;
+               }
+               $RT::Logger->debug("Building $type link for $link: " . $T::Tickets{$link}->Id);
+               $link = $T::Tickets{$link}->Id;
+
+               my ( $wval, $wmsg ) = $ticket->AddLink(
+                   Type                          => $LINKTYPEMAP{$type}->{'Type'},
+                   $LINKTYPEMAP{$type}->{'Mode'} => $link,
+                   Silent                        => 1
+               );
+
+               $RT::Logger->warning("AddLink thru $link failed: $wmsg") unless $wval;
+               # push @non_fatal_errors, $wmsg unless ($wval);
+           }
+
+       }
+    }
+
+    # postponed actions -- Status only, currently
+    while (my $ticket = shift(@postponed)) {
+       $RT::Logger->debug("Handling postponed actions for $ticket");
+       my %args = %{shift(@postponed)};
+
+       $ticket->SetStatus($args{Status}) if defined $args{Status};
+    }
+
+    return(1);
+}
+# }}}
+
+# {{{ sub Prepare 
+
+sub Prepare  {
+  my $self = shift;
+  
+  unless ($self->TemplateObj) {
+    $RT::Logger->warning("No template object handed to $self\n");
+  }
+  
+  unless ($self->TransactionObj) {
+    $RT::Logger->warning("No transaction object handed to $self\n");
+    
+  }
+  
+  unless ($self->TicketObj) {
+    $RT::Logger->warning("No ticket object handed to $self\n");
+      
+  }
+
+    
+
+my $template_id;
+foreach my $line (split(/\n/,$self->TemplateObj->Content)) {
+        if ($line =~ /^===Create-Ticket: (.*)$/) {
+                $template_id = $1;
+                push @{$self->{'template_order'}},$template_id;
+        } else {
+                $self->{'templates'}->{$template_id} .= $line."\n";
+        }       
+        
+        
+}
+  
+  return 1;
+  
+}
+
+# }}}
+
+# }}}
+
+eval "require RT::Action::CreateTickets_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/CreateTickets_Vendor.pm});
+eval "require RT::Action::CreateTickets_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/CreateTickets_Local.pm});
+
+1;
+
diff --git a/rt/lib/RT/Action/EscalatePriority.pm b/rt/lib/RT/Action/EscalatePriority.pm
new file mode 100644 (file)
index 0000000..7ed63ae
--- /dev/null
@@ -0,0 +1,142 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Action::EscalatePriority
+
+=head1 DESCRIPTION
+
+EscalatePriority is a ScripAction which is NOT intended to be called per 
+transaction. It's intended to be called by an RT escalation daemon.
+(The daemon is called escalator).
+
+EsclatePriority uses the following formula to change a ticket's priority:
+
+    Priority = Priority +  (( FinalPriority - Priority ) / ( DueDate-Today))
+
+Unless the duedate is past, in which case priority gets bumped straight
+to final priority.
+
+In this way, priority is either increased or decreased toward the final priority
+as the ticket heads toward its due date.
+
+
+=cut
+
+
+package RT::Action::EscalatePriority;
+require RT::Action::Generic;
+
+use strict;
+use vars qw/@ISA/;
+@ISA=qw(RT::Action::Generic);
+
+#Do what we need to do and send it out.
+
+#What does this type of Action does
+
+# {{{ sub Describe 
+sub Describe  {
+  my $self = shift;
+  return (ref $self . " will move a ticket's priority toward its final priority.");
+}
+# }}}
+       
+
+# {{{ sub Prepare 
+sub Prepare  {
+    my $self = shift;
+    
+    if ($self->TicketObj->Priority() == $self->TicketObj->FinalPriority()) {
+       # no update necessary.
+       return 0;
+    }
+   
+    #compute the number of days until the ticket is due
+    my $due = $self->TicketObj->DueObj();
+    
+
+    # If we don't have a due date, adjust the priority by one
+    # until we hit the final priority
+    if ($due->Unix() < 1) {
+       if ( $self->TicketObj->Priority > $self->TicketObj->FinalPriority ){
+           $self->{'prio'} = ($self->TicketObj->Priority - 1);
+           return 1;
+       }
+       elsif ( $self->TicketObj->Priority < $self->TicketObj->FinalPriority ){
+           $self->{'prio'} = ($self->TicketObj->Priority + 1);
+           return 1;
+       }
+       # otherwise the priority is at the final priority. we don't need to
+       # Continue
+       else {
+           return 0;
+       }
+    }
+
+    # we've got a due date. now there are other things we should do
+    else { 
+       my $diff_in_seconds = $due->Diff(time());    
+       my $diff_in_days = int( $diff_in_seconds / 86400);    
+       
+       #if we haven't hit the due date yet
+       if ($diff_in_days > 0 ) {       
+           
+           # compute the difference between the current priority and the
+           # final priority
+           
+           my $prio_delta = 
+             $self->TicketObj->FinalPriority() - $self->TicketObj->Priority;
+           
+           my $inc_priority_by = int( $prio_delta / $diff_in_days );
+           
+           #set the ticket's priority to that amount
+           $self->{'prio'} = $self->TicketObj->Priority + $inc_priority_by;
+           
+       }
+       #if $days is less than 1, set priority to final_priority
+       else {  
+           $self->{'prio'} = $self->TicketObj->FinalPriority();
+       }
+
+    }
+    return 1;
+}
+# }}}
+
+sub Commit {
+    my $self = shift;
+   my ($val, $msg) = $self->TicketObj->SetPriority($self->{'prio'});
+
+   unless ($val) {
+       $RT::Logger->debug($self . " $msg\n"); 
+   }
+}
+
+eval "require RT::Action::EscalatePriority_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/EscalatePriority_Vendor.pm});
+eval "require RT::Action::EscalatePriority_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/EscalatePriority_Local.pm});
+
+1;
index ecfd4ab..007d299 100755 (executable)
@@ -1,7 +1,26 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/Generic.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# (c) 1996-2000 Jesse Vincent <jesse@fsck.com>
-# This software is redistributable under the terms of the GNU GPL
-
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 =head1 NAME
 
   RT::Action::Generic - a generic baseclass for RT Actions
@@ -16,7 +35,6 @@
 
 =begin testing
 
-ok (require RT::TestHarness);
 ok (require RT::Action::Generic);
 
 =end testing
@@ -25,6 +43,8 @@ ok (require RT::Action::Generic);
 
 package RT::Action::Generic;
 
+use strict;
+
 # {{{ sub new 
 sub new  {
   my $proto = shift;
@@ -36,6 +56,13 @@ sub new  {
 }
 # }}}
 
+# {{{ sub new 
+sub loc {
+    my $self = shift;
+    return $self->{'ScripObj'}->loc(@_);
+}
+# }}}
+
 # {{{ sub _Init 
 sub _Init  {
   my $self = shift;
@@ -87,6 +114,13 @@ sub TemplateObj  {
 }
 # }}}
 
+# {{{ sub ScripObj
+sub ScripObj  {
+  my $self = shift;
+  return($self->{'ScripObj'});
+}
+# }}}
+
 # {{{ sub Type
 sub Type  {
   my $self = shift;
@@ -102,7 +136,7 @@ sub Type  {
 # {{{ sub Commit 
 sub Commit  {
   my $self = shift;
-  return(0,"Commit Stubbed");
+  return(0, $self->loc("Commit Stubbed"));
 }
 # }}}
 
@@ -112,7 +146,7 @@ sub Commit  {
 # {{{ sub Describe 
 sub Describe  {
   my $self = shift;
-  return ("No description for " . ref $self);
+  return $self->loc("No description for [_1]", ref $self);
 }
 # }}}
 
@@ -122,7 +156,7 @@ sub Describe  {
 # {{{ sub Prepare 
 sub Prepare  {
   my $self = shift;
-  return (0,"Prepare Stubbed");
+  return (0, $self->loc("Prepare Stubbed"));
 }
 # }}}
 
@@ -152,4 +186,10 @@ sub DESTROY {
 }
 
 # }}}
+
+eval "require RT::Action::Generic_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/Generic_Vendor.pm});
+eval "require RT::Action::Generic_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/Generic_Local.pm});
+
 1;
index 6dca4fd..1e4e4c0 100755 (executable)
@@ -1,7 +1,31 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/Notify.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 package RT::Action::Notify;
 require RT::Action::SendEmail;
+
+use strict;
+use vars qw/@ISA/;
 @ISA = qw(RT::Action::SendEmail);
 
 # {{{ sub SetRecipients
@@ -9,14 +33,14 @@ require RT::Action::SendEmail;
 =head2 SetRecipients
 
 Sets the recipients of this meesage to Owner, Requestor, AdminCc, Cc or All. 
-Explicitly B<does not> notify the creator of the transaction.
+Explicitly B<does not> notify the creator of the transaction by default
 
 =cut
 
 sub SetRecipients {
     my $self = shift;
 
-    $arg = $self->Argument;
+    my $arg = $self->Argument;
 
     $arg =~ s/\bAll\b/Owner,Requestor,AdminCc,Cc/;
 
@@ -24,14 +48,14 @@ sub SetRecipients {
 
 
     if ($arg =~ /\bOtherRecipients\b/) {
-        if ($self->TransactionObj->Message->First) {
-            push (@Cc, $self->TransactionObj->Message->First->GetHeader('RT-Send-Cc'));
-            push (@Bcc, $self->TransactionObj->Message->First->GetHeader('RT-Send-Bcc'));
+        if ($self->TransactionObj->Attachments->First) {
+            push (@Cc, $self->TransactionObj->Attachments->First->GetHeader('RT-Send-Cc'));
+            push (@Bcc, $self->TransactionObj->Attachments->First->GetHeader('RT-Send-Bcc'));
         }
     }
 
     if ( $arg =~ /\bRequestor\b/ ) {
-        push ( @To, @{ $self->TicketObj->Requestors->Emails } );
+        push ( @To, $self->TicketObj->Requestors->MemberEmailAddresses  );
     }
 
     
@@ -40,12 +64,12 @@ sub SetRecipients {
 
         #If we have a To, make the Ccs, Ccs, otherwise, promote them to To
         if (@To) {
-            push ( @Cc, @{ $self->TicketObj->Cc->Emails } );
-            push ( @Cc, @{ $self->TicketObj->QueueObj->Cc->Emails } );
+            push ( @Cc, $self->TicketObj->Cc->MemberEmailAddresses );
+            push ( @Cc, $self->TicketObj->QueueObj->Cc->MemberEmailAddresses  );
         }
         else {
-            push ( @Cc, @{ $self->TicketObj->Cc->Emails } );
-            push ( @To, @{ $self->TicketObj->QueueObj->Cc->Emails } );
+            push ( @Cc, $self->TicketObj->Cc->MemberEmailAddresses  );
+            push ( @To, $self->TicketObj->QueueObj->Cc->MemberEmailAddresses  );
         }
     }
 
@@ -65,15 +89,16 @@ sub SetRecipients {
     }
 
     if ( $arg =~ /\bAdminCc\b/ ) {
-        push ( @Bcc, @{ $self->TicketObj->AdminCc->Emails } );
-        push ( @Bcc, @{ $self->TicketObj->QueueObj->AdminCc->Emails } );
+        push ( @Bcc, $self->TicketObj->AdminCc->MemberEmailAddresses  );
+        push ( @Bcc, $self->TicketObj->QueueObj->AdminCc->MemberEmailAddresses  );
     }
 
     if ($RT::UseFriendlyToLine) {
         unless (@To) {
-            push ( @PseudoTo,
-                "\"$arg of $RT::rtname Ticket #"
-                  . $self->TicketObj->id . "\":;" );
+            push (
+               @PseudoTo,
+               sprintf($RT::FriendlyToLineFormat, $arg, $self->TicketObj->id),
+           );
         }
     }
 
@@ -81,14 +106,17 @@ sub SetRecipients {
 
     #Strip the sender out of the To, Cc and AdminCc and set the 
     # recipients fields used to build the message by the superclass.
-
-    $RT::Logger->debug("$self: To is ".join(",",@To));
-    $RT::Logger->debug("$self: Cc is ".join(",",@Cc));
-    $RT::Logger->debug("$self: Bcc is ".join(",",@Bcc));
-
-    @{ $self->{'To'} }  = grep ( !/^$creator$/, @To );
-    @{ $self->{'Cc'} }  = grep ( !/^$creator$/, @Cc );
-    @{ $self->{'Bcc'} } = grep ( !/^$creator$/, @Bcc );
+    # unless a flag is set 
+    if ($RT::NotifyActor) {
+        @{ $self->{'To'} }  = @To;
+        @{ $self->{'Cc'} }  = @Cc;
+        @{ $self->{'Bcc'} } = @Bcc;
+    }
+    else {
+        @{ $self->{'To'} }  = grep ( !/^$creator$/, @To );
+        @{ $self->{'Cc'} }  = grep ( !/^$creator$/, @Cc );
+        @{ $self->{'Bcc'} } = grep ( !/^$creator$/, @Bcc );
+    }
     @{ $self->{'PseudoTo'} } = @PseudoTo;
     return (1);
 
@@ -96,4 +124,9 @@ sub SetRecipients {
 
 # }}}
 
+eval "require RT::Action::Notify_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/Notify_Vendor.pm});
+eval "require RT::Action::Notify_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/Notify_Local.pm});
+
 1;
index c72bfff..210e4ab 100755 (executable)
@@ -1,7 +1,31 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/NotifyAsComment.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 package RT::Action::NotifyAsComment;
 require RT::Action::Notify;
+
+use strict;
+use vars qw/@ISA/;
 @ISA = qw(RT::Action::Notify);
 
 
@@ -21,5 +45,11 @@ sub SetReturnAddress {
        
        return($self->SUPER::SetReturnAddress(is_comment => 1));
 }
+
+eval "require RT::Action::NotifyAsComment_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/NotifyAsComment_Vendor.pm});
+eval "require RT::Action::NotifyAsComment_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/NotifyAsComment_Local.pm});
+
 1;
 
diff --git a/rt/lib/RT/Action/OpenDependent.pm b/rt/lib/RT/Action/OpenDependent.pm
deleted file mode 100644 (file)
index b271e47..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/Attic/OpenDependent.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# This Action will open the BASE if a dependent is resolved.
-
-package RT::Action::OpenDependent;
-require RT::Action::Generic;
-require RT::Links;
-@ISA=qw(RT::Action::Generic);
-
-#Do what we need to do and send it out.
-
-#What does this type of Action does
-
-# {{{ sub Describe 
-sub Describe  {
-  my $self = shift;
-  return (ref $self . " will stall a [local] BASE if it's open and a dependency link is created.");
-}
-# }}}
-
-
-# {{{ sub Prepare 
-sub Prepare  {
-    # nothing to prepare
-    return 1;
-}
-# }}}
-
-sub Commit {
-    my $self = shift;
-
-    my $Links=RT::Links->new($RT::SystemUser);
-    $Links->Limit(FIELD => 'Type', VALUE => 'DependsOn');
-    $Links->Limit(FIELD => 'Target', VALUE => $self->TicketObj->id);
-
-    while (my $Link=$Links->Next()) {
-       next unless $Link->BaseIsLocal;
-       my $base=RT::Ticket->new($self->TicketObj->CurrentUser);
-       # Todo: Only work if Base is a plain ticket num:
-       $base->Load($Link->Base);
-        $base->Open if $base->Status eq 'stalled';
-    }
-}
-
-
-# Applicability checked in Commit.
-
-# {{{ sub IsApplicable 
-sub IsApplicable  {
-  my $self = shift;
-  1;  
-  return 1;
-}
-# }}}
-
-1;
index 00547eb..02ff3a5 100644 (file)
@@ -1,8 +1,34 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 # This Action will resolve all members of a resolved group ticket
 
 package RT::Action::ResolveMembers;
 require RT::Action::Generic;
 require RT::Links;
+
+use strict;
+use vars qw/@ISA/;
 @ISA=qw(RT::Action::Generic);
 
 #Do what we need to do and send it out.
@@ -12,7 +38,7 @@ require RT::Links;
 # {{{ sub Describe 
 sub Describe  {
   my $self = shift;
-  return (ref $self . " will resolve all members of a resolved group ticket.");
+  return $self->loc("[_1] will resolve all members of a resolved group ticket.", ref $self);
 }
 # }}}
 
@@ -33,7 +59,7 @@ sub Commit {
 
     while (my $Link=$Links->Next()) {
        # Todo: Try to deal with remote URIs as well
-       next unless $Link->BaseIsLocal;
+       next unless $Link->BaseURI->IsLocal;
        my $base=RT::Ticket->new($self->TicketObj->CurrentUser);
        # Todo: Only work if Base is a plain ticket num:
        $base->Load($Link->Base);
@@ -53,5 +79,10 @@ sub IsApplicable  {
 }
 # }}}
 
+eval "require RT::Action::ResolveMembers_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/ResolveMembers_Vendor.pm});
+eval "require RT::Action::ResolveMembers_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/ResolveMembers_Local.pm});
+
 1;
 
index e3abb11..dac8fc8 100755 (executable)
@@ -1,20 +1,44 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/SendEmail.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# Copyright 1996-2002  Jesse Vincent <jesse@bestpractical.com> 
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 # Portions Copyright 2000 Tobias Brox <tobix@cpan.org>
-# Released under the terms of version 2 of the GNU Public License
 
 package RT::Action::SendEmail;
 require RT::Action::Generic;
 
+use strict;
+use vars qw/@ISA/;
 @ISA = qw(RT::Action::Generic);
 
+use MIME::Words qw(encode_mimeword);
 
-=head1 NAME
+use RT::EmailParser;
 
-  RT::Action::SendEmail - An Action which users can use to send mail 
-  or can subclassed for more specialized mail sending behavior. 
-  RT::Action::AutoReply is a good example subclass.
+=head1 NAME
 
+RT::Action::SendEmail - An Action which users can use to send mail 
+or can subclassed for more specialized mail sending behavior. 
+RT::Action::AutoReply is a good example subclass.
 
 =head1 SYNOPSIS
 
@@ -36,7 +60,6 @@ the comments for the SetRecipients sub).
 
 =begin testing
 
-ok (require RT::TestHarness);
 ok (require RT::Action::SendEmail);
 
 =end testing
@@ -54,158 +77,266 @@ perl(1).
 
 # {{{ Scrip methods (_Init, Commit, Prepare, IsApplicable)
 
-# {{{ sub _Init 
+# {{{ sub _Init
 # We use _Init from RT::Action
 # }}}
 
-# {{{ sub Commit 
+# {{{ sub Commit
 #Do what we need to do and send it out.
-sub Commit  {
+sub Commit {
     my $self = shift;
+
+    my $MIMEObj = $self->TemplateObj->MIMEObj;
+    my $msgid = $MIMEObj->head->get('Message-Id');
+    chomp $msgid;
+    $RT::Logger->info($msgid." #".$self->TicketObj->id."/".$self->TransactionObj->id." - Scrip ". $self->ScripObj->id ." ".$self->ScripObj->Description);
     #send the email
-    
+
+        # Weed out any RT addresses. We really don't want to talk to ourselves!
+        @{$self->{'To'}} = RT::EmailParser::CullRTAddresses("", @{$self->{'To'}});
+        @{$self->{'Cc'}} = RT::EmailParser::CullRTAddresses("", @{$self->{'Cc'}});
+        @{$self->{'Bcc'}} = RT::EmailParser::CullRTAddresses("", @{$self->{'Bcc'}});
     # If there are no recipients, don't try to send the message.
     # If the transaction has content and has the header RT-Squelch-Replies-To
-    
-    if (defined $self->TransactionObj->Message->First()) { 
-       my $headers = $self->TransactionObj->Message->First->Headers();
-       
-       if ($headers =~ /^RT-Squelch-Replies-To: (.*?)$/si) {
-           my @blacklist = split(/,/,$1);
-           
-           # Cycle through the people we're sending to and pull out anyone on the
-           # system blacklist
-           
-           foreach my $person_to_yank (@blacklist) {
-               $person_to_yank =~ s/\s//g;
-               @{$self->{'To'}} = grep (!/^$person_to_yank$/, @{$self->{'To'}});
-               @{$self->{'Cc'}} = grep (!/^$person_to_yank$/, @{$self->{'Cc'}});
-               @{$self->{'Bcc'}} = grep (!/^$person_to_yank$/, @{$self->{'Bcc'}});
-           }
-       }
+
+    if ( defined $self->TransactionObj->Attachments->First() ) {
+
+        my $squelch = $self->TransactionObj->Attachments->First->GetHeader( 'RT-Squelch-Replies-To');
+
+        if ($squelch) {
+            my @blacklist = split ( /,/, $squelch );
+
+            # Cycle through the people we're sending to and pull out anyone on the
+            # system blacklist
+
+            foreach my $person_to_yank (@blacklist) {
+                $person_to_yank =~ s/\s//g;
+                @{ $self->{'To'} } =
+                  grep ( !/^$person_to_yank$/, @{ $self->{'To'} } );
+                @{ $self->{'Cc'} } =
+                  grep ( !/^$person_to_yank$/, @{ $self->{'Cc'} } );
+                @{ $self->{'Bcc'} } =
+                  grep ( !/^$person_to_yank$/, @{ $self->{'Bcc'} } );
+            }
+        }
     }
-    
-    # Go add all the Tos, Ccs and Bccs that we need to to the message to 
+
+    # Go add all the Tos, Ccs and Bccs that we need to to the message to
     # make it happy, but only if we actually have values in those arrays.
-    
-    $self->SetHeader('To', join(',', @{$self->{'To'}})) 
-      if (@{$self->{'To'}});
-    $self->SetHeader('Cc', join(',' , @{$self->{'Cc'}})) 
-      if (@{$self->{'Cc'}});
-       $self->SetHeader('Bcc', join(',', @{$self->{'Bcc'}})) 
-         if (@{$self->{'Bcc'}});;
-    
-    my $MIMEObj = $self->TemplateObj->MIMEObj;
-    
 
-    $MIMEObj->make_singlepart;
-    
-    
+    $self->SetHeader( 'To', join ( ',', @{ $self->{'To'} } ) )
+      if ( $self->{'To'} && @{ $self->{'To'} } );
+    $self->SetHeader( 'Cc', join ( ',', @{ $self->{'Cc'} } ) )
+      if ( $self->{'Cc'} && @{ $self->{'Cc'} } );
+    $self->SetHeader( 'Bcc', join ( ',', @{ $self->{'Bcc'} } ) )
+      if ( $self->{'Cc'} && @{ $self->{'Bcc'} } );
+
+
+    $self->SetHeader('MIME-Version', '1.0');
+
+    # try to convert message body from utf-8 to $RT::EmailOutputEncoding
+    $self->SetHeader( 'Content-Type', 'text/plain; charset="utf-8"' );
+
+    RT::I18N::SetMIMEEntityToEncoding( $MIMEObj, $RT::EmailOutputEncoding, 'mime_words_ok' );
+    $self->SetHeader( 'Content-Type', 'text/plain; charset="' . $RT::EmailOutputEncoding . '"' );
+
+
+    # Build up a MIME::Entity that looks like the original message.
+
+    my $do_attach = $self->TemplateObj->MIMEObj->head->get('RT-Attach-Message');
+
+    if ($do_attach) {
+        $self->TemplateObj->MIMEObj->head->delete('RT-Attach-Message');
+
+        my $attachments = RT::Attachments->new($RT::SystemUser);
+        $attachments->Limit( FIELD => 'TransactionId',
+                             VALUE => $self->TransactionObj->Id );
+        $attachments->OrderBy('id');
+
+        my $transaction_content_obj = $self->TransactionObj->ContentObj;
+
+        # attach any of this transaction's attachments
+        while ( my $attach = $attachments->Next ) {
+
+            # Don't attach anything blank
+            next unless ( $attach->ContentLength );
+
+            # We want to make sure that we don't include the attachment that's being sued as the "Content" of this message"
+            next
+              if (    $transaction_content_obj
+                   && $transaction_content_obj->Id == $attach->Id 
+                   && $transaction_content_obj->ContentType =~ qr{text/plain}i
+                );
+            $MIMEObj->make_multipart('mixed');
+            $MIMEObj->attach( Type => $attach->ContentType,
+                              Charset => $attach->OriginalEncoding,
+                              Data => $attach->OriginalContent,
+                              Filename => $self->MIMEEncodeString( $attach->Filename, $RT::EmailOutputEncoding ),
+                              Encoding    => '-SUGGEST');
+        }
+
+    }
+
+
+    my $retval = $self->SendMessage($MIMEObj);
+
+
+    return ($retval);
+}
+
+# }}}
+
+# {{{ sub Prepare
+
+sub Prepare {
+    my $self = shift;
+
+    # This actually populates the MIME::Entity fields in the Template Object
+
+    unless ( $self->TemplateObj ) {
+        $RT::Logger->warning("No template object handed to $self\n");
+    }
+
+    unless ( $self->TransactionObj ) {
+        $RT::Logger->warning("No transaction object handed to $self\n");
+
+    }
+
+    unless ( $self->TicketObj ) {
+        $RT::Logger->warning("No ticket object handed to $self\n");
+
+    }
+
+    my ( $result, $message ) = $self->TemplateObj->Parse(
+                                         Argument       => $self->Argument,
+                                         TicketObj      => $self->TicketObj,
+                                         TransactionObj => $self->TransactionObj
+    );
+    if ($result) {
+
+        # Header
+        $self->SetSubject();
+        $self->SetSubjectToken();
+        $self->SetRecipients();
+        $self->SetReturnAddress();
+        $self->SetRTSpecialHeaders();
+        if ($RT::EmailOutputEncoding) {
+
+            # l10n related header
+            $self->SetHeaderAsEncoding( 'Subject', $RT::EmailOutputEncoding );
+        }
+    }
+
+    return $result;
+
+}
+
+# }}}
+
+# }}}
+
+# {{{ SendMessage
+=head2 SendMessage MIMEObj
+
+sends the message using RT's preferred API.
+TODO: Break this out to a seperate module
+
+=cut
+
+sub SendMessage {
+    my $self = shift;
+    my $MIMEObj = shift;
+
+    my $msgid = $MIMEObj->head->get('Message-Id');
+
+
     #If we don't have any recipients to send to, don't send a message;
-    unless ($MIMEObj->head->get('To') ||
-           $MIMEObj->head->get('Cc') || 
-           $MIMEObj->head->get('Bcc') ) {
-       $RT::Logger->debug("$self: No recipients found. Not sending.\n");
-       return(1);
+    unless (    $MIMEObj->head->get('To')
+             || $MIMEObj->head->get('Cc')
+             || $MIMEObj->head->get('Bcc') ) {
+        $RT::Logger->info($msgid.  " No recipients found. Not sending.\n");
+        return (1);
     }
 
     # PseudoTo (fake to headers) shouldn't get matched for message recipients.
     # If we don't have any 'To' header, drop in the pseudo-to header.
 
-    $self->SetHeader('To', join(',', @{$self->{'PseudoTo'}}))
-      if ( (@{$self->{'PseudoTo'}}) and (! $MIMEObj->head->get('To')));
-    
-    if ($RT::MailCommand eq 'sendmailpipe') {
-       open (MAIL, "|$RT::SendmailPath $RT::SendmailArguments") || return(0);
-       print MAIL $MIMEObj->as_string;
-       close(MAIL);
+    $self->SetHeader( 'To', join ( ',', @{ $self->{'PseudoTo'} } ) )
+      if ( $self->{'PseudoTo'} && ( @{ $self->{'PseudoTo'} } )
+           and ( !$MIMEObj->head->get('To') ) );
+    if ( $RT::MailCommand eq 'sendmailpipe' ) {
+        eval {
+            open( MAIL, "|$RT::SendmailPath $RT::SendmailArguments" );
+            print MAIL $MIMEObj->as_string;
+            close(MAIL);
+          };
+          if ($@) {
+            $RT::Logger->crit($msgid.  "Could not send mail. -".$@ );
+        }
     }
     else {
-       unless ($MIMEObj->send($RT::MailCommand, $RT::MailParams)) {
-           $RT::Logger->crit("$self: Could not send mail for ".
-                             $self->TransactionObj . "\n");
-           return(0);
+       my @mailer_args = ($RT::MailCommand);
+       local $ENV{MAILADDRESS};
+
+        if ( $RT::MailCommand eq 'sendmail' ) {
+           push @mailer_args, $RT::SendmailArguments;
+        }
+        elsif ( $RT::MailCommand eq 'smtp' ) {
+           $ENV{MAILADDRESS} = $RT::SMTPFrom || $MIMEObj->head->get('From');
+           push @mailer_args, (Server => $RT::SMTPServer);
+           push @mailer_args, (Debug => $RT::SMTPDebug);
+        }
+       else {
+           push @mailer_args, $RT::MailParams;
        }
+
+        unless ( $MIMEObj->send( @mailer_args ) ) {
+            $RT::Logger->crit($msgid.  "Could not send mail." );
+            return (0);
+        }
     }
-    
-    return (1);
-    
-}
-# }}}
 
-# {{{ sub Prepare 
 
-sub Prepare  {
-  my $self = shift;
-  
-  # This actually populates the MIME::Entity fields in the Template Object
-  
-  unless ($self->TemplateObj) {
-    $RT::Logger->warning("No template object handed to $self\n");
-  }
-  
-  unless ($self->TransactionObj) {
-    $RT::Logger->warning("No transaction object handed to $self\n");
-    
-  }
-  
-  unless ($self->TicketObj) {
-    $RT::Logger->warning("No ticket object handed to $self\n");
-      
-  }
-  
-  
-  $self->TemplateObj->Parse(Argument => $self->Argument,
-                           TicketObj => $self->TicketObj, 
-                           TransactionObj => $self->TransactionObj);
-  
-  # Header
-  
-  $self->SetSubject();
-  
-  $self->SetSubjectToken();
-  
-  $self->SetRecipients();  
-  
-  $self->SetReturnAddress();
+     my $success = ($msgid. " sent To: ".$MIMEObj->head->get('To') . " Cc: ".$MIMEObj->head->get('Cc') . " Bcc: ".$MIMEObj->head->get('Bcc'));
+    $success =~ s/\n//gi;
+    $RT::Logger->info($success);
 
-  $self->SetRTSpecialHeaders();
-  
-  return 1;
-  
+    return (1);
 }
 
 # }}}
 
-# }}}
-
 # {{{ Deal with message headers (Set* subs, designed for  easy overriding)
 
 # {{{ sub SetRTSpecialHeaders
 
-# This routine adds all the random headers that RT wants in a mail message
-# that don't matter much to anybody else.
+=head2 SetRTSpecialHeaders 
+
+This routine adds all the random headers that RT wants in a mail message
+that don't matter much to anybody else.
+
+=cut
 
 sub SetRTSpecialHeaders {
     my $self = shift;
-    
+
     $self->SetReferences();
 
     $self->SetMessageID();
-    
+
     $self->SetPrecedence();
 
-    $self->SetHeader('X-RT-Loop-Prevention', $RT::rtname); 
-    $self->SetHeader('RT-Ticket', $RT::rtname. " #".$self->TicketObj->id());
-    $self->SetHeader
-      ('Managed-by',"RT $RT::VERSION (http://bestpractical.com/rt/)");
-    
-    $self->SetHeader('RT-Originator', $self->TransactionObj->CreatorObj->EmailAddress);
-    return();
-    
-}
+    $self->SetHeader( 'X-RT-Loop-Prevention', $RT::rtname );
+    $self->SetHeader( 'RT-Ticket',
+                      $RT::rtname . " #" . $self->TicketObj->id() );
+    $self->SetHeader( 'Managed-by',
+                      "RT $RT::VERSION (http://www.bestpractical.com/rt/)" );
 
+    $self->SetHeader( 'RT-Originator',
+                      $self->TransactionObj->CreatorObj->EmailAddress );
+    return ();
 
+}
 
 # {{{ sub SetReferences
 
@@ -218,105 +349,126 @@ sub SetRTSpecialHeaders {
 =cut
 
 sub SetReferences {
-  my $self = shift;
-  
-  # TODO: this one is broken.  What is this email really a reply to?
-  # If it's a reply to an incoming message, we'll need to use the
-  # actual message-id from the appropriate Attachment object.  For
-  # incoming mails, we would like to preserve the In-Reply-To and/or
-  # References.
+    my $self = shift;
 
-  $self->SetHeader
-    ('In-Reply-To', "<rt-".$self->TicketObj->id().
-     "\@".$RT::rtname.">");
+    # TODO: this one is broken.  What is this email really a reply to?
+    # If it's a reply to an incoming message, we'll need to use the
+    # actual message-id from the appropriate Attachment object.  For
+    # incoming mails, we would like to preserve the In-Reply-To and/or
+    # References.
 
+    $self->SetHeader( 'In-Reply-To',
+                   "<rt-" . $self->TicketObj->id() . "\@" . $RT::rtname . ">" );
 
-  # TODO We should always add References headers for all message-ids
-  # of previous messages related to this ticket.
+    # TODO We should always add References headers for all message-ids
+    # of previous messages related to this ticket.
 }
 
 # }}}
 
 # {{{ sub SetMessageID
 
-# Without this one, threading won't work very nice in email agents.
-# Anyway, I'm not really sure it's that healthy if we need to send
-# several separate/different emails about the same transaction.
+=head2 SetMessageID 
 
-sub SetMessageID {
-  my $self = shift;
+Without this one, threading won't work very nice in email agents.
+Anyway, I'm not really sure it's that healthy if we need to send
+several separate/different emails about the same transaction.
 
-  # TODO this one might be sort of broken.  If we have several scrips +++
-  # sending several emails to several different persons, we need to
-  # pull out different message-ids.  I'd suggest message ids like
-  # "rt-ticket#-transaction#-scrip#-receipient#"
+=cut
+
+sub SetMessageID {
+    my $self = shift;
 
-  $self->SetHeader
-    ('Message-ID', "<rt-".$self->TicketObj->id().
-     "-".
-     $self->TransactionObj->id()."." .rand(20) . "\@".$RT::Organization.">")
+    # TODO this one might be sort of broken.  If we have several scrips +++
+    # sending several emails to several different persons, we need to
+    # pull out different message-ids.  I'd suggest message ids like
+    # "rt-ticket#-transaction#-scrip#-receipient#"
+
+    $self->SetHeader( 'Message-ID',
+                      "<rt-"
+                        . $RT::VERSION ."-"
+                        . $self->TicketObj->id() . "-"
+                        . $self->TransactionObj->id() . "."
+                        . rand(20) . "\@"
+                        . $RT::Organization . ">" )
       unless $self->TemplateObj->MIMEObj->head->get('Message-ID');
 }
 
-
 # }}}
 
 # }}}
 
-# {{{ sub SetReturnAddress 
+# {{{ sub SetReturnAddress
+
+=head2 SetReturnAddress is_comment => BOOLEAN
+
+Calculate and set From and Reply-To headers based on the is_comment flag.
+
+=cut
 
 sub SetReturnAddress {
 
-  my $self = shift;
-  my %args = ( is_comment => 0,
-              @_ );
-
-  # From and Reply-To
-  # $args{is_comment} should be set if the comment address is to be used.
-  my $replyto;
-
-  if ($args{'is_comment'}) { 
-      $replyto = $self->TicketObj->QueueObj->CommentAddress || 
-                 $RT::CommentAddress;
-  }
-  else {
-      $replyto = $self->TicketObj->QueueObj->CorrespondAddress ||
-                 $RT::CorrespondAddress;
-  }
-    
-  unless ($self->TemplateObj->MIMEObj->head->get('From')) {
-      my $friendly_name=$self->TransactionObj->CreatorObj->RealName;
-
-      if ($friendly_name =~ /^\S+\@\S+$/) { # A "bare" mail address
-          $friendly_name =~ s/"/\\"/g;
-          $friendly_name = qq|"$friendly_name"|;
-      }
-
-
-      # TODO: this "via RT" should really be site-configurable.
-      $self->SetHeader('From', "\"$friendly_name via RT\" <$replyto>");
-  }
-  
-  unless ($self->TemplateObj->MIMEObj->head->get('Reply-To')) {
-      $self->SetHeader('Reply-To', "$replyto");
-  }
-  
+    my $self = shift;
+    my %args = ( is_comment => 0,
+                 @_ );
+
+    # From and Reply-To
+    # $args{is_comment} should be set if the comment address is to be used.
+    my $replyto;
+
+    if ( $args{'is_comment'} ) {
+        $replyto = $self->TicketObj->QueueObj->CommentAddress
+          || $RT::CommentAddress;
+    }
+    else {
+        $replyto = $self->TicketObj->QueueObj->CorrespondAddress
+          || $RT::CorrespondAddress;
+    }
+
+    unless ( $self->TemplateObj->MIMEObj->head->get('From') ) {
+       if ($RT::UseFriendlyFromLine) {
+           my $friendly_name = $self->TransactionObj->CreatorObj->RealName;
+           if ( $friendly_name =~ /^"(.*)"$/ ) {    # a quoted string
+               $friendly_name = $1;
+           }
+
+           $friendly_name =~ s/"/\\"/g;
+           $self->SetHeader( 'From',
+                       sprintf($RT::FriendlyFromLineFormat, 
+                $self->MIMEEncodeString( $friendly_name, $RT::EmailOutputEncoding ), $replyto),
+           );
+       }
+       else {
+           $self->SetHeader( 'From', $replyto );
+       }
+    }
+
+    unless ( $self->TemplateObj->MIMEObj->head->get('Reply-To') ) {
+        $self->SetHeader( 'Reply-To', "$replyto" );
+    }
+
 }
 
 # }}}
 
 # {{{ sub SetHeader
 
+=head2 SetHeader FIELD, VALUE
+
+Set the FIELD of the current MIME object into VALUE.
+
+=cut
+
 sub SetHeader {
-  my $self = shift;
-  my $field = shift;
-  my $val = shift;
-
-  chomp $val;                                                                  
-  chomp $field;                                                                
-  $self->TemplateObj->MIMEObj->head->fold_length($field,10000);     
-  $self->TemplateObj->MIMEObj->head->add($field, $val);
-  return $self->TemplateObj->MIMEObj->head->get($field);
+    my $self  = shift;
+    my $field = shift;
+    my $val   = shift;
+
+    chomp $val;
+    chomp $field;
+    $self->TemplateObj->MIMEObj->head->fold_length( $field, 10000 );
+    $self->TemplateObj->MIMEObj->head->replace( $field,     $val );
+    return $self->TemplateObj->MIMEObj->head->get($field);
 }
 
 # }}}
@@ -331,21 +483,29 @@ Dummy method to be overriden by subclasses which want to set the recipients.
 
 sub SetRecipients {
     my $self = shift;
-    return();
+    return ();
 }
 
 # }}}
 
 # {{{ sub SetTo
 
+=head2 SetTo
+
+Takes a string that is the addresses you want to send mail to
+
+=cut
+
 sub SetTo {
-    my $self=shift;
+    my $self      = shift;
     my $addresses = shift;
-    return $self->SetHeader('To',$addresses);
+    return $self->SetHeader( 'To', $addresses );
 }
+
 # }}}
 
 # {{{ sub SetCc
+
 =head2 SetCc
 
 Takes a string that is the addresses you want to Cc
@@ -353,11 +513,12 @@ Takes a string that is the addresses you want to Cc
 =cut
 
 sub SetCc {
-    my $self=shift;
+    my $self      = shift;
     my $addresses = shift;
 
-    return $self->SetHeader('Cc', $addresses);
+    return $self->SetHeader( 'Cc', $addresses );
 }
+
 # }}}
 
 # {{{ sub SetBcc
@@ -367,23 +528,24 @@ sub SetCc {
 Takes a string that is the addresses you want to Bcc
 
 =cut
+
 sub SetBcc {
-    my $self=shift;
+    my $self      = shift;
     my $addresses = shift;
 
-    return $self->SetHeader('Bcc', $addresses);
+    return $self->SetHeader( 'Bcc', $addresses );
 }
 
 # }}}
 
-# {{{ sub SetPrecedence 
+# {{{ sub SetPrecedence
 
 sub SetPrecedence {
-  my $self = shift;
+    my $self = shift;
 
-  unless ($self->TemplateObj->MIMEObj->head->get("Precedence")) { 
-    $self->SetHeader('Precedence', "bulk");
-   }
+    unless ( $self->TemplateObj->MIMEObj->head->get("Precedence") ) {
+        $self->SetHeader( 'Precedence', "bulk" );
+    }
 }
 
 # }}}
@@ -399,70 +561,125 @@ the transaction's subject.
 =cut 
 
 sub SetSubject {
-  my $self = shift;
-  unless ($self->TemplateObj->MIMEObj->head->get('Subject')) {
-    my $message=$self->TransactionObj->Message;
-    my $ticket=$self->TicketObj->Id;
-    
+    my $self = shift;
     my $subject;
-    
-    if ($self->{'Subject'}) {
-      $subject = $self->{'Subject'};
-    }
-    elsif (($message->First()) &&
-          ($message->First->Headers)) {
-      $header = $message->First->Headers();
-      $header =~ s/\n\s+/ /g; 
-      if ( $header =~ /^Subject: (.*?)$/m ) {
-       $subject = $1;
-      }
-      else {
-       $subject = $self->TicketObj->Subject();
-      }
-      
-    }
-    else {
-      $subject = $self->TicketObj->Subject();
-    }
-    
-    $subject =~ s/(\r\n|\n|\s)/ /gi;
 
-    chomp $subject;
-    $self->SetHeader('Subject',$subject);
-    
+    unless ( $self->TemplateObj->MIMEObj->head->get('Subject') ) {
+        my $message = $self->TransactionObj->Attachments;
+        my $ticket  = $self->TicketObj->Id;
+
+        if ( $self->{'Subject'} ) {
+            $subject = $self->{'Subject'};
+        }
+        elsif (    ( $message->First() )
+                && ( $message->First->Headers ) ) {
+            my $header = $message->First->Headers();
+            $header =~ s/\n\s+/ /g;
+            if ( $header =~ /^Subject: (.*?)$/m ) {
+                $subject = $1;
+            }
+            else {
+                $subject = $self->TicketObj->Subject();
+            }
+
+        }
+        else {
+            $subject = $self->TicketObj->Subject();
+        }
+
+        $subject =~ s/(\r\n|\n|\s)/ /gi;
+
+        chomp $subject;
+        $self->SetHeader( 'Subject', $subject );
+
     }
-  return($subject);
+    return ($subject);
 }
+
 # }}}
 
 # {{{ sub SetSubjectToken
 
 =head2 SetSubjectToken
 
- This routine fixes the RT tag in the subject. It's unlikely that you want to overwrite this.
+This routine fixes the RT tag in the subject. It's unlikely that you want to overwrite this.
 
 =cut
 
 sub SetSubjectToken {
-  my $self=shift;
-  my $tag = "[$RT::rtname #".$self->TicketObj->id."]";
-  my $sub = $self->TemplateObj->MIMEObj->head->get('Subject');
-  unless ($sub =~ /\Q$tag\E/) {
-    $sub =~ s/(\r\n|\n|\s)/ /gi;
-    chomp $sub;
-    $self->TemplateObj->MIMEObj->head->replace('Subject', "$tag $sub");
-  }
+    my $self = shift;
+    my $tag  = "[$RT::rtname #" . $self->TicketObj->id . "]";
+    my $sub  = $self->TemplateObj->MIMEObj->head->get('Subject');
+    unless ( $sub =~ /\Q$tag\E/ ) {
+        $sub =~ s/(\r\n|\n|\s)/ /gi;
+        chomp $sub;
+        $self->TemplateObj->MIMEObj->head->replace( 'Subject', "$tag $sub" );
+    }
 }
 
 # }}}
 
 # }}}
 
-__END__
+# {{{
+
+=head2 SetHeaderAsEncoding($field_name, $charset_encoding)
+
+This routine converts the field into specified charset encoding.
+
+=cut
+
+sub SetHeaderAsEncoding {
+    my $self = shift;
+    my ( $field, $enc ) = ( shift, shift );
+
+    if ($field eq 'From' and $RT::SMTPFrom) {
+        $self->TemplateObj->MIMEObj->head->replace( $field, $RT::SMTPFrom );
+       return;
+    }
+
+    my $value = $self->TemplateObj->MIMEObj->head->get($field);
+
+    # don't bother if it's us-ascii
+
+    # See RT::I18N, 'NOTES:  Why Encode::_utf8_off before Encode::from_to'
+
+    $value =  $self->MIMEEncodeString($value, $enc);
+
+    $self->TemplateObj->MIMEObj->head->replace( $field, $value );
+
+
+} 
+# }}}
+
+# {{{ MIMENcodeString
+
+=head2 MIMEEncodeString STRING ENCODING
+
+Takes a string and a possible encoding and returns the string wrapped in MIME goo.
+
+=cut
+
+sub MIMEEncodeString {
+    my  $self = shift;
+    my $value = shift;
+    my $enc = shift;
 
-# {{{ POD
+    chomp $value;
+    return ($value) unless $value =~ /[^\x20-\x7e]/;
+
+    $value =~ s/\s*$//;
+    Encode::_utf8_off($value);
+    my $res = Encode::from_to( $value, "utf-8", $enc );
+    $value = encode_mimeword( $value,  'B', $enc );
+}
 
 # }}}
 
+eval "require RT::Action::SendEmail_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/SendEmail_Vendor.pm});
+eval "require RT::Action::SendEmail_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/SendEmail_Local.pm});
+
 1;
 
diff --git a/rt/lib/RT/Action/SendPasswordEmail.pm b/rt/lib/RT/Action/SendPasswordEmail.pm
deleted file mode 100755 (executable)
index 91bb3c1..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/Attic/SendPasswordEmail.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# Copyright 2001  Jesse Vincent <jesse@fsck.com>
-# Released under the terms of the GNU Public License
-
-package RT::Action::SendPasswordEmail;
-require RT::Action::Generic;
-
-@ISA = qw(RT::Action::Generic);
-
-
-=head1 NAME
-
-  RT::Action::SendGenericEmail - An Action which users can use to send mail 
-  or can subclassed for more specialized mail sending behavior. 
-
-
-
-=head1 SYNOPSIS
-
-  require RT::Action::SendPasswordEmail;
-
-
-=head1 DESCRIPTION
-
-Basically, you create another module RT::Action::YourAction which ISA
-RT::Action::SendEmail.
-
-If you want to set the recipients of the mail to something other than
-the addresses mentioned in the To, Cc, Bcc and headers in
-the template, you should subclass RT::Action::SendEmail and override
-either the SetRecipients method or the SetTo, SetCc, etc methods (see
-the comments for the SetRecipients sub).
-
-
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::Action::SendPasswordEmail);
-
-=end testing
-
-
-=head1 AUTHOR
-
-Jesse Vincent <jesse@bestpractical.com>
-
-=head1 SEE ALSO
-
-perl(1).
-
-=cut
-
-# {{{ Scrip methods (_Init, Commit, Prepare, IsApplicable)
-
-# {{{ sub Commit 
-
-#Do what we need to do and send it out.
-
-sub Commit  {
-    my $self = shift;
-    #send the email
-    
-    
-    
-
-    
-    my $MIMEObj = $self->TemplateObj->MIMEObj;
-    
-    
-    $MIMEObj->make_singlepart;
-    
-    #If we don\'t have any recipients to send to, don\'t send a message;
-    unless ($MIMEObj->head->get('To')) {
-       $RT::Logger->debug("$self: No recipients found. Not sending.\n");
-       return(1);
-    }
-    
-    if ($RT::MailCommand eq 'sendmailpipe') {
-       open (MAIL, "|$RT::SendmailPath $RT::SendmailArguments") || return(0);
-       print MAIL $MIMEObj->as_string;
-       close(MAIL);
-    }
-    else {
-       unless ($MIMEObj->send($RT::MailCommand, $RT::MailParams)) {
-           $RT::Logger->crit("$self: Could not send mail for ".
-                             $self->TransactionObj . "\n");
-           return(0);
-       }
-    }
-    
-    return (1);
-    
-}
-# }}}
-
-# {{{ sub Prepare 
-
-sub Prepare  {
-    my $self = shift;
-    
-    # This actually populates the MIME::Entity fields in the Template Object
-    
-    unless ($self->TemplateObj) {
-       $RT::Logger->warning("No template object handed to $self\n");
-    }
-    
-    
-    unless ($self->TemplateObj->MIMEObj->head->get('Reply-To')) {
-       $self->SetHeader('Reply-To',$RT::CorrespondAddress );
-    }
-
-    
-    $self->SetHeader('Precedence', "bulk");
-    $self->SetHeader('X-RT-Loop-Prevention', $RT::rtname); 
-    $self->SetHeader
-      ('Managed-by',"Request Tracker $RT::VERSION (http://www.fsck.com/projects/rt/)");
-    
-    $self->TemplateObj->Parse(Argument => $self->Argument);
-    
-    
-    return 1;
-}
-
-# }}}
-
-# }}}
-
-
-# {{{ sub SetTo
-
-=head2 SetTo EMAIL
-
-Sets this message's "To" field to EMAIL
-
-=cut
-
-sub SetTo {
-    my $self = shift;
-    my $to = shift;
-    $self->SetHeader('To',$to);
-}
-
-# }}}
-
-# {{{ sub SetHeader
-
-sub SetHeader {
-  my $self = shift;
-  my $field = shift;
-  my $val = shift;
-
-  chomp $val;                                                                  
-  chomp $field;                                                                
-  $self->TemplateObj->MIMEObj->head->fold_length($field,10000);     
-  $self->TemplateObj->MIMEObj->head->add($field, $val);
-  return $self->TemplateObj->MIMEObj->head->get($field);
-}
-
-# }}}
-
-
-
-__END__
-
-# {{{ POD
-
-# }}}
-
-1;
-
diff --git a/rt/lib/RT/Action/SetPriority.pm b/rt/lib/RT/Action/SetPriority.pm
new file mode 100644 (file)
index 0000000..515eeb5
--- /dev/null
@@ -0,0 +1,61 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+package RT::Action::SetPriority;
+require RT::Action::Generic;
+
+use strict;
+use vars qw/@ISA/;
+@ISA=qw(RT::Action::Generic);
+
+#Do what we need to do and send it out.
+
+#What does this type of Action does
+
+# {{{ sub Describe 
+sub Describe  {
+  my $self = shift;
+  return (ref $self . " will set a ticket's priority to the argument provided.");
+}
+# }}}
+
+
+# {{{ sub Prepare 
+sub Prepare  {
+    # nothing to prepare
+    return 1;
+}
+# }}}
+
+sub Commit {
+    my $self = shift;
+    $self->TicketObj->SetPriority($self->Argument);
+
+}
+
+eval "require RT::Action::SetPriority_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/SetPriority_Vendor.pm});
+eval "require RT::Action::SetPriority_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/SetPriority_Local.pm});
+
+1;
diff --git a/rt/lib/RT/Action/StallDependent.pm b/rt/lib/RT/Action/StallDependent.pm
deleted file mode 100644 (file)
index 09d3448..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-# This Action will stall the BASE if a dependency or membership link
-# (according to argument) is created and if BASE is open.
-
-# TODO: Rename this .pm
-
-package RT::Action::StallDependent;
-require RT::Action::Generic;
-@ISA=qw|RT::Action::Generic|;
-
-# {{{ sub Describe 
-sub Describe  {
-  my $self = shift;
-  return (ref $self . " will stall a [local] BASE if it's dependent [or member] of a linked up request.");
-}
-# }}}
-
-
-# {{{ sub Prepare 
-sub Prepare  {
-    # nothing to prepare
-    return 1;
-}
-# }}}
-
-sub Commit {
-    my $self = shift;
-    # Find all Dependent
-    my $arg=$self->Argument || "DependsOn";
-    unless ($self->TransactionObj->Data =~ /^([^ ]+) $arg /) {
-       warn; return 0;
-    }
-    my $base_id=$1;
-    my $base;
-    if ($1 eq "THIS") {
-       $base=$self->TicketObj;
-    } else {
-       $base_id=&RT::Link::_IsLocal(undef, $base_id) || return 0;
-       $base=RT::Ticket->new($self->TicketObj->CurrentUser);
-       $base->Load($base_id);
-    }
-    $base->Stall if $base->Status eq 'open';
-    return 0;
-}
-
-
-# {{{ sub IsApplicable 
-
-# Only applicable if:
-# 1. the link action is a dependency
-# 2. BASE is a local ticket
-
-sub IsApplicable  {
-  my $self = shift;
-
-  my $arg=$self->Argument || "DependsOn";
-
-  # 1:
-  $self->TransactionObj->Data =~ /^([^ ]*) $arg / || return 0;
-
-  # 2:
-  # (dirty!)
-  &RT::Link::_IsLocal(undef,$1) || return 0;
-
-  return 1;
-}
-# }}}
-
-1;
diff --git a/rt/lib/RT/Action/UserDefined.pm b/rt/lib/RT/Action/UserDefined.pm
new file mode 100644 (file)
index 0000000..e2e3d72
--- /dev/null
@@ -0,0 +1,71 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+package RT::Action::UserDefined;
+use RT::Action::Generic;
+
+use strict;
+use vars qw/@ISA/;
+@ISA = qw(RT::Action::Generic);
+
+=head2 Prepare
+
+This happens on every transaction. it's always applicable
+
+=cut
+
+sub Prepare {
+    my $self = shift;
+    my $retval = eval $self->ScripObj->CustomPrepareCode;
+    if ($@) {
+        $RT::Logger->error("Scrip ".$self->ScripObj->Id. " Prepare failed: ".$@);
+        return (undef);
+    }
+    return ($retval);
+}
+
+=head2 Commit
+
+This happens on every transaction. it's always applicable
+
+=cut
+
+sub Commit {
+    my $self = shift;
+    my $retval = eval $self->ScripObj->CustomCommitCode;
+    if ($@) {
+        $RT::Logger->error("Scrip ".$self->ScripObj->Id. " Commit failed: ".$@);
+        return (undef);
+    }
+    return ($retval);
+}
+
+eval "require RT::Action::UserDefined_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/UserDefined_Vendor.pm});
+eval "require RT::Action::UserDefined_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/UserDefined_Local.pm});
+
+1;
+
index 916ac35..2ed5201 100755 (executable)
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Attachment.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# Copyright 2000 Jesse Vincent <jesse@fsck.com>
-# Released under the terms of the GNU Public License
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
 
 =head1 NAME
 
-  RT::Attachment -- an RT attachment object
+RT::Attachment
+
 
 =head1 SYNOPSIS
 
-  use RT::Attachment;
+=head1 DESCRIPTION
 
+=head1 METHODS
 
-=head1 DESCRIPTION
+=cut
 
-This module should never be instantiated directly by client code. it's an internal 
-module which should only be instantiated through exported APIs in Ticket, Queue and other 
-similar objects.
+package RT::Attachment;
+use RT::Record; 
+
+
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
+
+sub _Init {
+  my $self = shift; 
+
+  $self->Table('Attachments');
+  $self->SUPER::_Init(@_);
+}
 
 
-=head1 METHODS
 
 
-=begin testing
 
-ok (require RT::TestHarness);
-ok (require RT::Attachment);
+=item Create PARAMHASH
 
-=end testing
+Create takes a hash of values and creates a row in the database:
+
+  int(11) 'TransactionId'.
+  int(11) 'Parent'.
+  varchar(160) 'MessageId'.
+  varchar(255) 'Subject'.
+  varchar(255) 'Filename'.
+  varchar(80) 'ContentType'.
+  varchar(80) 'ContentEncoding'.
+  longtext 'Content'.
+  longtext 'Headers'.
 
 =cut
 
-package RT::Attachment;
-use RT::Record;
-use MIME::Base64;
-use vars qw|@ISA|;
-@ISA= qw(RT::Record);
-
-# {{{ sub _Init
-sub _Init  {
-    my $self = shift; 
-    $self->{'table'} = "Attachments";
-    return($self->SUPER::_Init(@_));
-}
-# }}}
 
-# {{{ sub _ClassAccessible 
-sub _ClassAccessible {
-    {
-    TransactionId   => { 'read'=>1, 'public'=>1, },
-    MessageId       => { 'read'=>1, },
-    Parent          => { 'read'=>1, },
-    ContentType     => { 'read'=>1, },
-    Subject         => { 'read'=>1, },
-    Content         => { 'read'=>1, },
-    ContentEncoding => { 'read'=>1, },
-    Headers         => { 'read'=>1, },
-    Filename        => { 'read'=>1, },
-    Creator         => { 'read'=>1, 'auto'=>1, },
-    Created         => { 'read'=>1, 'auto'=>1, },
-  };
+
+
+sub Create {
+    my $self = shift;
+    my %args = ( 
+                TransactionId => '0',
+                Parent => '0',
+                MessageId => '',
+                Subject => '',
+                Filename => '',
+                ContentType => '',
+                ContentEncoding => '',
+                Content => '',
+                Headers => '',
+
+                 @_);
+    $self->SUPER::Create(
+                         TransactionId => $args{'TransactionId'},
+                         Parent => $args{'Parent'},
+                         MessageId => $args{'MessageId'},
+                         Subject => $args{'Subject'},
+                         Filename => $args{'Filename'},
+                         ContentType => $args{'ContentType'},
+                         ContentEncoding => $args{'ContentEncoding'},
+                         Content => $args{'Content'},
+                         Headers => $args{'Headers'},
+);
+
 }
-# }}}
 
-# {{{ sub TransactionObj 
 
-=head2 TransactionObj
 
-Returns the transaction object asscoiated with this attachment.
+=item id
+
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
+
 
 =cut
 
-sub TransactionObj {
-    require RT::Transaction;
-    my $self=shift;
-    unless (exists $self->{_TransactionObj}) {
-       $self->{_TransactionObj}=RT::Transaction->new($self->CurrentUser);
-       $self->{_TransactionObj}->Load($self->TransactionId);
-    }
-    return $self->{_TransactionObj};
-}
 
-# }}}
+=item TransactionId
+
+Returns the current value of TransactionId. 
+(In the database, TransactionId is stored as int(11).)
 
-# {{{ sub Create 
 
-=head2 Create
 
-Create a new attachment. Takes a paramhash:
-    
-    'Attachment' Should be a single MIME body with optional subparts
-    'Parent' is an optional Parent RT::Attachment object
-    'TransactionId' is the mandatory id of the Transaction this attachment is associated with.;
+=item SetTransactionId VALUE
+
+
+Set TransactionId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, TransactionId will be stored as a int(11).)
+
 
 =cut
 
-sub Create  {
-    my $self = shift;
-    my ($id);
-    my %args = ( id => 0,
-                TransactionId => 0,
-                Parent => 0,
-                Attachment => undef,
-                @_
-              );
-    
-    
-    #For ease of reference
-    my $Attachment = $args{'Attachment'};
-    
-    #if we didn't specify a ticket, we need to bail
-    if ( $args{'TransactionId'} == 0) {
-       $RT::Logger->crit("RT::Attachment->Create couldn't, as you didn't specify a transaction\n");
-       return (0);
-       
-    }
-    
-    #If we possibly can, collapse it to a singlepart
-    $Attachment->make_singlepart;
-    
-    #Get the subject
-    my $Subject = $Attachment->head->get('subject',0);
-    defined($Subject) or $Subject = '';
-    chomp($Subject);
-  
-    #Get the filename
-    my $Filename = $Attachment->head->recommended_filename;
-    
-    if ($Attachment->parts) {
-       $id = $self->SUPER::Create(TransactionId => $args{'TransactionId'},
-                                  Parent => 0,
-                                  ContentType  => $Attachment->mime_type,
-                                  Headers => $Attachment->head->as_string,
-                                  Subject => $Subject,
-                                  
-                                 );
-       foreach my $part ($Attachment->parts) { 
-           my $SubAttachment = new RT::Attachment($self->CurrentUser);
-           $SubAttachment->Create(TransactionId => $args{'TransactionId'},
-                                  Parent => $id,
-                                  Attachment => $part,
-                                  ContentType  => $Attachment->mime_type,
-                                  Headers => $Attachment->head->as_string(),
-                                  
-                                 );
-       }
-       return ($id);
-    }
-  
-  
-    #If it's not multipart
-    else {
-       
-       my $ContentEncoding = 'none'; 
-       
-       my $Body = $Attachment->bodyhandle->as_string;
-       
-       #get the max attachment length from RT
-       my $MaxSize = $RT::MaxAttachmentSize;
-       
-       #if the current attachment contains nulls and the 
-       #database doesn't support embedded nulls
-       
-       if ( (! $RT::Handle->BinarySafeBLOBs) &&
-            ( $Body =~ /\x00/ ) ) {
-           # set a flag telling us to mimencode the attachment
-           $ContentEncoding = 'base64';
-           
-           #cut the max attchment size by 25% (for mime-encoding overhead.
-           $RT::Logger->debug("Max size is $MaxSize\n");
-           $MaxSize = $MaxSize * 3/4;  
-       }
-       
-       #if the attachment is larger than the maximum size
-       if (($MaxSize) and ($MaxSize < length($Body))) {
-           # if we're supposed to truncate large attachments
-           if ($RT::TruncateLongAttachments) {
-               # truncate the attachment to that length.
-               $Body = substr ($Body, 0, $MaxSize);
-
-           }
-           
-           # elsif we're supposed to drop large attachments on the floor,
-           elsif ($RT::DropLongAttachments) {
-               # drop the attachment on the floor
-               $RT::Logger->info("$self: Dropped an attachment of size ". length($Body).
-                                 "\n". "It started: ". substr($Body, 0, 60) . "\n");
-               return(undef);
-           }
-       }
-       # if we need to mimencode the attachment
-       if ($ContentEncoding eq 'base64') {
-           # base64 encode the attachment
-           $Body = MIME::Base64::encode_base64($Body);
-           
-       }
-       
-       my $id = $self->SUPER::Create(TransactionId => $args{'TransactionId'},
-                                     ContentType  => $Attachment->mime_type,
-                                     ContentEncoding => $ContentEncoding,
-                                     Parent => $args{'Parent'},
-                                     Content => $Body,
-                                     Headers => $Attachment->head->as_string,
-                                     Subject => $Subject,
-                                     Filename => $Filename,
-                                    );
-       return ($id);
-    }
-}
 
-# }}}
+=item Parent
+
+Returns the current value of Parent. 
+(In the database, Parent is stored as int(11).)
+
 
 
-# {{{ sub Content
+=item SetParent VALUE
 
-=head2 Content
 
-Returns the attachment's content. if it's base64 encoded, decode it 
-before returning it.
+Set Parent to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Parent will be stored as a int(11).)
+
 
 =cut
 
-sub Content {
-  my $self = shift;
-  if ( $self->ContentEncoding eq 'none' || ! $self->ContentEncoding ) {
-      return $self->_Value('Content');
-  } elsif ( $self->ContentEncoding eq 'base64' ) {
-      return MIME::Base64::decode_base64($self->_Value('Content'));
-  } else {
-      return( "Unknown ContentEncoding ". $self->ContentEncoding);
-  }
-}
 
+=item MessageId
+
+Returns the current value of MessageId. 
+(In the database, MessageId is stored as varchar(160).)
 
-# }}}
 
-# {{{ sub Children
 
-=head2 Children
+=item SetMessageId VALUE
+
+
+Set MessageId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, MessageId will be stored as a varchar(160).)
 
-  Returns an RT::Attachments object which is preloaded with all Attachments objects with this Attachment\'s Id as their 'Parent'
 
 =cut
 
-sub Children {
-    my $self = shift;
-    
-    my $kids = new RT::Attachments($self->CurrentUser);
-    $kids->ChildrenOf($self->Id);
-    return($kids);
-}
 
-# }}}
+=item Subject
 
-# {{{ UTILITIES
+Returns the current value of Subject. 
+(In the database, Subject is stored as varchar(255).)
 
-# {{{ sub Quote 
 
 
+=item SetSubject VALUE
 
-sub Quote {
-    my $self=shift;
-    my %args=(Reply=>undef, # Prefilled reply (i.e. from the KB/FAQ system)
-             @_);
 
-    my ($quoted_content, $body, $headers);
-    my $max=0;
+Set Subject to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Subject will be stored as a varchar(255).)
 
-    # TODO: Handle Multipart/Mixed (eventually fix the link in the
-    # ShowHistory web template?)
-    if ($self->ContentType =~ m{^(text/plain|message)}i) {
-       $body=$self->Content;
 
-       # Do we need any preformatting (wrapping, that is) of the message?
+=cut
 
-       # Remove quoted signature.
-       $body =~ s/\n-- \n(.*)$//s;
 
-       # What's the longest line like?
-       foreach (split (/\n/,$body)) {
-           $max=length if ( length > $max);
-       }
+=item Filename
 
-       if ($max>76) {
-           require Text::Wrapper;
-           my $wrapper=new Text::Wrapper
-               (
-                columns => 70, 
-                body_start => ($max > 70*3 ? '   ' : ''),
-                par_start => ''
-                );
-           $body=$wrapper->wrap($body);
-       }
+Returns the current value of Filename. 
+(In the database, Filename is stored as varchar(255).)
 
-       $body =~ s/^/> /gm;
 
-       $body = '[' . $self->TransactionObj->CreatorObj->Name() . ' - ' . $self->TransactionObj->CreatedAsString()
-                   . "]:\n\n"
-               . $body . "\n\n";
 
-    } else {
-       $body = "[Non-text message not quoted]\n\n";
-    }
-    
-    $max=60 if $max<60;
-    $max=70 if $max>78;
-    $max+=2;
+=item SetFilename VALUE
+
+
+Set Filename to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Filename will be stored as a varchar(255).)
+
+
+=cut
+
+
+=item ContentType
+
+Returns the current value of ContentType. 
+(In the database, ContentType is stored as varchar(80).)
+
 
-    return (\$body, $max);
-}
-# }}}
 
-# {{{ sub NiceHeaders - pulls out only the most relevant headers
+=item SetContentType VALUE
 
-=head2 NiceHeaders
 
-Returns the To, From, Cc, Date and Subject headers.
+Set ContentType to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ContentType will be stored as a varchar(80).)
 
-It is a known issue that this breaks if any of these headers are not
-properly unfolded.
 
 =cut
 
-sub NiceHeaders {
-    my $self=shift;
-    my $hdrs="";
-    for (split(/\n/,$self->Headers)) {
-           $hdrs.="$_\n" if /^(To|From|RT-Send-Cc|Cc|Date|Subject): /i
-    }
-    return $hdrs;
-}
-# }}}
 
-# {{{ sub Headers
+=item ContentEncoding
+
+Returns the current value of ContentEncoding. 
+(In the database, ContentEncoding is stored as varchar(80).)
+
+
 
-=head2 Headers
+=item SetContentEncoding VALUE
+
+
+Set ContentEncoding to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ContentEncoding will be stored as a varchar(80).)
 
-Returns this object's headers as a string.  This method specifically
-removes the RT-Send-Bcc: header, so as to never reveal to whom RT sent a Bcc.
-We need to record the RT-Send-Cc and RT-Send-Bcc values so that we can actually send
-out mail. (The mailing rules are seperated from the ticket update code by
-an abstraction barrier that makes it impossible to pass this data directly
 
 =cut
 
-sub Headers {
-    my $self = shift;
-    my $hdrs="";
-    for (split(/\n/,$self->SUPER::Headers)) {
-           $hdrs.="$_\n" unless /^(RT-Send-Bcc): /i
-    }
-    return $hdrs;
-}
+
+=item Content
+
+Returns the current value of Content. 
+(In the database, Content is stored as longtext.)
 
 
-# }}}
 
-# {{{ sub GetHeader
+=item SetContent VALUE
 
-=head2 GetHeader ( 'Tag')
 
-Returns the value of the header Tag as a string. This bypasses the weeding out
-done in Headers() above.
+Set Content to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Content will be stored as a longtext.)
+
 
 =cut
 
-sub GetHeader {
-    my $self = shift;
-    my $tag = shift;
-    foreach my $line (split(/\n/,$self->SUPER::Headers)) {
-        $RT::Logger->debug( "Does $line match $tag\n");
-        if ($line =~ /^$tag:\s+(.*)$/i) { #if we find the header, return its value
-            return ($1);
-        }
-    }
-    
-    # we found no header. return an empty string
-    return undef;
-}
-# }}}
 
-# {{{ sub _Value 
+=item Headers
 
-=head2 _Value
+Returns the current value of Headers. 
+(In the database, Headers is stored as longtext.)
+
+
+
+=item SetHeaders VALUE
+
+
+Set Headers to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Headers will be stored as a longtext.)
 
-Takes the name of a table column.
-Returns its value as a string, if the user passes an ACL check
 
 =cut
 
-sub _Value  {
 
-    my $self = shift;
-    my $field = shift;
-    
-    
-    #if the field is public, return it.
-    if ($self->_Accessible($field, 'public')) {
-       #$RT::Logger->debug("Skipping ACL check for $field\n");
-       return($self->__Value($field));
-       
-    }
-    
-    #If it's a comment, we need to be extra special careful
-    elsif ( (($self->TransactionObj->CurrentUserHasRight('ShowTicketComments')) and
-            ($self->TransactionObj->Type eq 'Comment') )  or
-           ($self->TransactionObj->CurrentUserHasRight('ShowTicket'))) {
-       
-       return($self->__Value($field));
-    }
-    #if they ain't got rights to see, don't let em
-    else {
-           return(undef);
-       }
-       
-    
-}
+=item Creator
+
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
+
+
+=cut
+
+
+=item Created
 
-# }}}
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
+
+
+=cut
+
+
+
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        TransactionId => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Parent => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        MessageId => 
+               {read => 1, write => 1, type => 'varchar(160)', default => ''},
+        Subject => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        Filename => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        ContentType => 
+               {read => 1, write => 1, type => 'varchar(80)', default => ''},
+        ContentEncoding => 
+               {read => 1, write => 1, type => 'varchar(80)', default => ''},
+        Content => 
+               {read => 1, write => 1, type => 'longtext', default => ''},
+        Headers => 
+               {read => 1, write => 1, type => 'longtext', default => ''},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+
+ }
+};
+
+
+        eval "require RT::Attachment_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Attachment_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Attachment_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Attachment_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Attachment_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Attachment_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::Attachment_Overlay, RT::Attachment_Vendor, RT::Attachment_Local
+
+=cut
 
-# }}}
 
 1;
diff --git a/rt/lib/RT/Attachment_Overlay.pm b/rt/lib/RT/Attachment_Overlay.pm
new file mode 100644 (file)
index 0000000..d31aa75
--- /dev/null
@@ -0,0 +1,571 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 SYNOPSIS
+
+  use RT::Attachment;
+
+
+=head1 DESCRIPTION
+
+This module should never be instantiated directly by client code. it's an internal 
+module which should only be instantiated through exported APIs in Ticket, Queue and other 
+similar objects.
+
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::Attachment);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+use MIME::Base64;
+use MIME::QuotedPrint;
+
+# {{{ sub _ClassAccessible 
+sub _ClassAccessible {
+    {
+    TransactionId   => { 'read'=>1, 'public'=>1, },
+    MessageId       => { 'read'=>1, },
+    Parent          => { 'read'=>1, },
+    ContentType     => { 'read'=>1, },
+    Subject         => { 'read'=>1, },
+    Content         => { 'read'=>1, },
+    ContentEncoding => { 'read'=>1, },
+    Headers         => { 'read'=>1, },
+    Filename        => { 'read'=>1, },
+    Creator         => { 'read'=>1, 'auto'=>1, },
+    Created         => { 'read'=>1, 'auto'=>1, },
+  };
+}
+# }}}
+
+# {{{ sub TransactionObj 
+
+=head2 TransactionObj
+
+Returns the transaction object asscoiated with this attachment.
+
+=cut
+
+sub TransactionObj {
+    require RT::Transaction;
+    my $self=shift;
+    unless (exists $self->{_TransactionObj}) {
+       $self->{_TransactionObj}=RT::Transaction->new($self->CurrentUser);
+       $self->{_TransactionObj}->Load($self->TransactionId);
+    }
+    return $self->{_TransactionObj};
+}
+
+# }}}
+
+# {{{ sub Create 
+
+=head2 Create
+
+Create a new attachment. Takes a paramhash:
+    
+    'Attachment' Should be a single MIME body with optional subparts
+    'Parent' is an optional Parent RT::Attachment object
+    'TransactionId' is the mandatory id of the Transaction this attachment is associated with.;
+
+=cut
+
+sub Create {
+    my $self = shift;
+    my ($id);
+    my %args = ( id            => 0,
+                 TransactionId => 0,
+                 Parent        => 0,
+                 Attachment    => undef,
+                 @_ );
+
+    #For ease of reference
+    my $Attachment = $args{'Attachment'};
+
+    #if we didn't specify a ticket, we need to bail
+    if ( $args{'TransactionId'} == 0 ) {
+        $RT::Logger->crit( "RT::Attachment->Create couldn't, as you didn't specify a transaction\n" );
+        return (0);
+
+    }
+
+    #If we possibly can, collapse it to a singlepart
+    $Attachment->make_singlepart;
+
+    #Get the subject
+    my $Subject = $Attachment->head->get( 'subject', 0 );
+    defined($Subject) or $Subject = '';
+    chomp($Subject);
+
+    #Get the filename
+    my $Filename = $Attachment->head->recommended_filename || eval {
+       ${ $Attachment->head->{mail_hdr_hash}{'Content-Disposition'}[0] }
+           =~ /^.*\bfilename="(.*)"$/ ? $1 : ''
+    };
+
+    if ( $Attachment->parts ) {
+        $id = $self->SUPER::Create(
+            TransactionId => $args{'TransactionId'},
+            Parent        => 0,
+            ContentType   => $Attachment->mime_type,
+            Headers => $Attachment->head->as_string,
+            Subject => $Subject);
+
+        foreach my $part ( $Attachment->parts ) {
+            my $SubAttachment = new RT::Attachment( $self->CurrentUser );
+            $SubAttachment->Create(
+                TransactionId => $args{'TransactionId'},
+                Parent        => $id,
+                Attachment    => $part,
+                ContentType   => $Attachment->mime_type,
+                Headers       => $Attachment->head->as_string(),
+
+            );
+        }
+        return ($id);
+    }
+
+    #If it's not multipart
+    else {
+
+        my $ContentEncoding = 'none';
+
+        my $Body = $Attachment->bodyhandle->as_string;
+
+        #get the max attachment length from RT
+        my $MaxSize = $RT::MaxAttachmentSize;
+
+        #if the current attachment contains nulls and the 
+        #database doesn't support embedded nulls
+
+        if ( $RT::AlwaysUseBase64 or
+            ( !$RT::Handle->BinarySafeBLOBs ) && ( $Body =~ /\x00/ ) ) {
+
+            # set a flag telling us to mimencode the attachment
+            $ContentEncoding = 'base64';
+
+            #cut the max attchment size by 25% (for mime-encoding overhead.
+            $RT::Logger->debug("Max size is $MaxSize\n");
+            $MaxSize = $MaxSize * 3 / 4;
+        # Some databases (postgres) can't handle non-utf8 data 
+        } elsif (    !$RT::Handle->BinarySafeBLOBs
+                  && $Attachment->mime_type !~ /text\/plain/gi
+                  && !Encode::is_utf8( $Body, 1 ) ) {
+              $ContentEncoding = 'quoted-printable';
+        }
+
+        #if the attachment is larger than the maximum size
+        if ( ($MaxSize) and ( $MaxSize < length($Body) ) ) {
+
+            # if we're supposed to truncate large attachments
+            if ($RT::TruncateLongAttachments) {
+
+                # truncate the attachment to that length.
+                $Body = substr( $Body, 0, $MaxSize );
+
+            }
+
+            # elsif we're supposed to drop large attachments on the floor,
+            elsif ($RT::DropLongAttachments) {
+
+                # drop the attachment on the floor
+                $RT::Logger->info( "$self: Dropped an attachment of size " . length($Body) . "\n" . "It started: " . substr( $Body, 0, 60 ) . "\n" );
+                return (undef);
+            }
+        }
+
+        # if we need to mimencode the attachment
+        if ( $ContentEncoding eq 'base64' ) {
+
+            # base64 encode the attachment
+            Encode::_utf8_off($Body);
+            $Body = MIME::Base64::encode_base64($Body);
+
+        } elsif ($ContentEncoding eq 'quoted-printable') {
+                   Encode::_utf8_off($Body);
+            $Body = MIME::QuotedPrint::encode($Body);
+        }
+
+
+        my $id = $self->SUPER::Create( TransactionId => $args{'TransactionId'},
+                                       ContentType   => $Attachment->mime_type,
+                                       ContentEncoding => $ContentEncoding,
+                                       Parent          => $args{'Parent'},
+                                       Headers       =>  $Attachment->head->as_string, 
+                                       Subject       =>  $Subject,
+                                       Content         => $Body,
+                                       Filename => $Filename, );
+        return ($id);
+    }
+}
+
+# }}}
+
+
+=head2 Import
+
+Create an attachment exactly as specified in the named parameters.
+
+=cut
+
+
+sub Import {
+    my $self = shift;
+    return($self->SUPER::Create(@_));
+}
+
+# {{{ sub Content
+
+=head2 Content
+
+Returns the attachment's content. if it's base64 encoded, decode it 
+before returning it.
+
+=cut
+
+sub Content {
+  my $self = shift;
+  my $decode_utf8 = (($self->ContentType eq 'text/plain') ? 1 : 0);
+
+  if ( $self->ContentEncoding eq 'none' || ! $self->ContentEncoding ) {
+      return $self->_Value(
+         'Content',
+         decode_utf8 => $decode_utf8,
+      );
+  } elsif ( $self->ContentEncoding eq 'base64' ) {
+      return ( $decode_utf8
+        ? Encode::decode_utf8(MIME::Base64::decode_base64($self->_Value('Content')))
+        : MIME::Base64::decode_base64($self->_Value('Content'))
+      );
+  } elsif ( $self->ContentEncoding eq 'quoted-printable' ) {
+      return ( $decode_utf8
+        ? Encode::decode_utf8(MIME::QuotedPrint::decode($self->_Value('Content')))
+        : MIME::QuotedPrint::decode($self->_Value('Content'))
+      );
+  } else {
+      return( $self->loc("Unknown ContentEncoding [_1]", $self->ContentEncoding));
+  }
+}
+
+
+# }}}
+
+
+# {{{ sub OriginalContent
+
+=head2 OriginalContent
+
+Returns the attachment's content as octets before RT's mangling.
+Currently, this just means restoring text/plain content back to its
+original encoding.
+
+=cut
+
+sub OriginalContent {
+  my $self = shift;
+
+  return $self->Content unless $self->ContentType eq 'text/plain';
+  my $enc = $self->OriginalEncoding;
+
+  my $content;
+  if ( $self->ContentEncoding eq 'none' || ! $self->ContentEncoding ) {
+      $content = $self->_Value('Content', decode_utf8 => 0);
+  } elsif ( $self->ContentEncoding eq 'base64' ) {
+      $content = MIME::Base64::decode_base64($self->_Value('Content', decode_utf8 => 0));
+  } elsif ( $self->ContentEncoding eq 'quoted-printable' ) {
+      return MIME::QuotedPrint::decode($self->_Value('Content', decode_utf8 => 0));
+  } else {
+      return( $self->loc("Unknown ContentEncoding [_1]", $self->ContentEncoding));
+  }
+
+  # Encode::_utf8_on($content);
+  if (!$enc or $enc eq 'utf8' or $enc eq 'utf-8') {
+    # If we somehow fail to do the decode, at least push out the raw bits
+    eval {return( Encode::decode_utf8($content))} || return ($content);
+  }
+  Encode::from_to($content, 'utf8' => $enc);
+  return $content;
+}
+
+# }}}
+
+
+# {{{ sub OriginalEncoding
+
+=head2 OriginalEncoding
+
+Returns the attachment's original encoding.
+
+=cut
+
+sub OriginalEncoding {
+  my $self = shift;
+  return $self->GetHeader('X-RT-Original-Encoding');
+}
+
+# }}}
+
+# {{{ sub Children
+
+=head2 Children
+
+  Returns an RT::Attachments object which is preloaded with all Attachments objects with this Attachment\'s Id as their 'Parent'
+
+=cut
+
+sub Children {
+    my $self = shift;
+    
+    my $kids = new RT::Attachments($self->CurrentUser);
+    $kids->ChildrenOf($self->Id);
+    return($kids);
+}
+
+# }}}
+
+# {{{ UTILITIES
+
+# {{{ sub Quote 
+
+
+
+sub Quote {
+    my $self=shift;
+    my %args=(Reply=>undef, # Prefilled reply (i.e. from the KB/FAQ system)
+             @_);
+
+    my ($quoted_content, $body, $headers);
+    my $max=0;
+
+    # TODO: Handle Multipart/Mixed (eventually fix the link in the
+    # ShowHistory web template?)
+    if ($self->ContentType =~ m{^(text/plain|message)}i) {
+       $body=$self->Content;
+
+       # Do we need any preformatting (wrapping, that is) of the message?
+
+       # Remove quoted signature.
+       $body =~ s/\n-- \n(.*)$//s;
+
+       # What's the longest line like?
+       foreach (split (/\n/,$body)) {
+           $max=length if ( length > $max);
+       }
+
+       if ($max>76) {
+           require Text::Wrapper;
+           my $wrapper=new Text::Wrapper
+               (
+                columns => 70, 
+                body_start => ($max > 70*3 ? '   ' : ''),
+                par_start => ''
+                );
+           $body=$wrapper->wrap($body);
+       }
+
+       $body =~ s/^/> /gm;
+
+       $body = '[' . $self->TransactionObj->CreatorObj->Name() . ' - ' . $self->TransactionObj->CreatedAsString()
+                   . "]:\n\n"
+               . $body . "\n\n";
+
+    } else {
+       $body = "[Non-text message not quoted]\n\n";
+    }
+    
+    $max=60 if $max<60;
+    $max=70 if $max>78;
+    $max+=2;
+
+    return (\$body, $max);
+}
+# }}}
+
+# {{{ sub NiceHeaders - pulls out only the most relevant headers
+
+=head2 NiceHeaders
+
+Returns the To, From, Cc, Date and Subject headers.
+
+It is a known issue that this breaks if any of these headers are not
+properly unfolded.
+
+=cut
+
+sub NiceHeaders {
+    my $self=shift;
+    my $hdrs="";
+    for (split(/\n/,$self->Headers)) {
+           $hdrs.="$_\n" if /^(To|From|RT-Send-Cc|Cc|Date|Subject): /i
+    }
+    return $hdrs;
+}
+# }}}
+
+# {{{ sub Headers
+
+=head2 Headers
+
+Returns this object's headers as a string.  This method specifically
+removes the RT-Send-Bcc: header, so as to never reveal to whom RT sent a Bcc.
+We need to record the RT-Send-Cc and RT-Send-Bcc values so that we can actually send
+out mail. (The mailing rules are seperated from the ticket update code by
+an abstraction barrier that makes it impossible to pass this data directly
+
+=cut
+
+sub Headers {
+    my $self = shift;
+    my $hdrs="";
+    for (split(/\n/,$self->SUPER::Headers)) {
+           $hdrs.="$_\n" unless /^(RT-Send-Bcc): /i
+    }
+    return $hdrs;
+}
+
+
+# }}}
+
+# {{{ sub GetHeader
+
+=head2 GetHeader ( 'Tag')
+
+Returns the value of the header Tag as a string. This bypasses the weeding out
+done in Headers() above.
+
+=cut
+
+sub GetHeader {
+    my $self = shift;
+    my $tag = shift;
+    foreach my $line (split(/\n/,$self->SUPER::Headers)) {
+        if ($line =~ /^\Q$tag\E:\s+(.*)$/i) { #if we find the header, return its value
+            return ($1);
+        }
+    }
+    
+    # we found no header. return an empty string
+    return undef;
+}
+# }}}
+
+# {{{ sub SetHeader
+
+=head2 SetHeader ( 'Tag', 'Value' )
+
+Replace or add a Header to the attachment's headers.
+
+=cut
+
+sub SetHeader {
+    my $self = shift;
+    my $tag = shift;
+    my $newheader = '';
+
+    foreach my $line (split(/\n/,$self->SUPER::Headers)) {
+        if (defined $tag and $line =~ /^\Q$tag\E:\s+(.*)$/i) {
+           $newheader .= "$tag: $_[0]\n";
+           undef $tag;
+        }
+       else {
+           $newheader .= "$line\n";
+       }
+    }
+
+    $newheader .= "$tag: $_[0]\n" if defined $tag;
+    $self->__Set( Field => 'Headers', Value => $newheader);
+}
+# }}}
+
+# {{{ sub _Value 
+
+=head2 _Value
+
+Takes the name of a table column.
+Returns its value as a string, if the user passes an ACL check
+
+=cut
+
+sub _Value  {
+
+    my $self = shift;
+    my $field = shift;
+    
+    
+    #if the field is public, return it.
+    if ($self->_Accessible($field, 'public')) {
+       #$RT::Logger->debug("Skipping ACL check for $field\n");
+       return($self->__Value($field, @_));
+       
+    }
+    
+    #If it's a comment, we need to be extra special careful
+    elsif ( (($self->TransactionObj->CurrentUserHasRight('ShowTicketComments')) and
+            ($self->TransactionObj->Type eq 'Comment') )  or
+           ($self->TransactionObj->CurrentUserHasRight('ShowTicket'))) {
+               return($self->__Value($field, @_));
+    }
+    #if they ain't got rights to see, don't let em
+    else {
+           return(undef);
+       }
+       
+    
+}
+
+# }}}
+
+sub ContentLength {
+    my $self = shift;
+
+    unless ( (($self->TransactionObj->CurrentUserHasRight('ShowTicketComments')) and
+            ($self->TransactionObj->Type eq 'Comment') )  or
+           ($self->TransactionObj->CurrentUserHasRight('ShowTicket'))) {
+       return undef;
+    }
+
+    if (my $len = $self->GetHeader('Content-Length')) {
+       return $len;
+    }
+
+    {
+       use bytes;
+       my $len = length($self->Content);
+       $self->SetHeader('Content-Length' => $len);
+       return $len;
+    }
+}
+
+# }}}
+
+1;
index 73cd350..177cdd0 100755 (executable)
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Attachments.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-=head1 NAME
 
-  RT::Attachments - a collection of RT::Attachment objects
+=head1 NAME
 
+  RT::Attachments -- Class Description
 =head1 SYNOPSIS
 
-  use RT::Attachments;
+  use RT::Attachments
 
 =head1 DESCRIPTION
 
-This module should never be called directly by client code. it's an internal module which
-should only be accessed through exported APIs in Ticket, Queue and other similar objects.
-
 
 =head1 METHODS
 
+=cut
 
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::Attachments);
+package RT::Attachments;
 
-=end testing
+use RT::SearchBuilder;
+use RT::Attachment;
 
-=cut
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
 
-package RT::Attachments;
 
-use RT::EasySearch;
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'Attachments';
+    $self->{'primary_key'} = 'id';
 
-@ISA= qw(RT::EasySearch);
 
-# {{{ sub _Init  
-sub _Init   {
-  my $self = shift;
-  $self->{'table'} = "Attachments";
-  $self->{'primary_key'} = "id";
-  return ( $self->SUPER::_Init(@_));
+    return ( $self->SUPER::_Init(@_) );
 }
-# }}}
 
 
-# {{{ sub ContentType
+=item NewItem
 
-=head2 ContentType (VALUE => 'text/plain', ENTRYAGGREGATOR => 'OR', OPERATOR => '=' ) 
-
-Limit result set to attachments of ContentType 'TYPE'...
+Returns an empty new RT::Attachment item
 
 =cut
 
+sub NewItem {
+    my $self = shift;
+    return(RT::Attachment->new($self->CurrentUser));
+}
 
-sub ContentType  {
-  my $self = shift;
-  my %args = ( VALUE => 'text/plain',
-              OPERATOR => '=',
-              ENTRYAGGREGATOR => 'OR',
-              @_);
+        eval "require RT::Attachments_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Attachments_Overlay.pm}) {
+            die $@;
+        };
 
-  $self->Limit ( FIELD => 'ContentType',
-                VALUE => $args{'VALUE'},
-                OPERATOR => $args{'OPERATOR'},
-                ENTRYAGGREGATOR => $args{'ENTRYAGGREGATOR'});
-}
-# }}}
+        eval "require RT::Attachments_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Attachments_Vendor.pm}) {
+            die $@;
+        };
 
-# {{{ sub ChildrenOf 
+        eval "require RT::Attachments_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Attachments_Local.pm}) {
+            die $@;
+        };
 
-=head2 ChildrenOf ID
 
-Limit result set to children of Attachment ID
 
-=cut
 
+=head1 SEE ALSO
 
-sub ChildrenOf  {
-  my $self = shift;
-  my $attachment = shift;
-  $self->Limit ( FIELD => 'Parent',
-                VALUE => $attachment);
-}
-# }}}
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
 
-# {{{ sub NewItem 
-sub NewItem  {
-  my $self = shift;
+These overlay files can contain new subs or subs to replace existing subs in this module.
 
-  use RT::Attachment;
-  my $item = new RT::Attachment($self->CurrentUser);
-  return($item);
-}
-# }}}
-  1;
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
 
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
 
+RT::Attachments_Overlay, RT::Attachments_Vendor, RT::Attachments_Local
+
+=cut
 
 
+1;
diff --git a/rt/lib/RT/Attachments_Overlay.pm b/rt/lib/RT/Attachments_Overlay.pm
new file mode 100644 (file)
index 0000000..ce94c9d
--- /dev/null
@@ -0,0 +1,116 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Attachments - a collection of RT::Attachment objects
+
+=head1 SYNOPSIS
+
+  use RT::Attachments;
+
+=head1 DESCRIPTION
+
+This module should never be called directly by client code. it's an internal module which
+should only be accessed through exported APIs in Ticket, Queue and other similar objects.
+
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::Attachments);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+# {{{ sub _Init  
+sub _Init   {
+  my $self = shift;
+  $self->{'table'} = "Attachments";
+  $self->{'primary_key'} = "id";
+  return ( $self->SUPER::_Init(@_));
+}
+# }}}
+
+
+# {{{ sub ContentType
+
+=head2 ContentType (VALUE => 'text/plain', ENTRYAGGREGATOR => 'OR', OPERATOR => '=' ) 
+
+Limit result set to attachments of ContentType 'TYPE'...
+
+=cut
+
+
+sub ContentType  {
+  my $self = shift;
+  my %args = ( VALUE => 'text/plain',
+              OPERATOR => '=',
+              ENTRYAGGREGATOR => 'OR',
+              @_);
+
+  $self->Limit ( FIELD => 'ContentType',
+                VALUE => $args{'VALUE'},
+                OPERATOR => $args{'OPERATOR'},
+                ENTRYAGGREGATOR => $args{'ENTRYAGGREGATOR'});
+}
+# }}}
+
+# {{{ sub ChildrenOf 
+
+=head2 ChildrenOf ID
+
+Limit result set to children of Attachment ID
+
+=cut
+
+
+sub ChildrenOf  {
+  my $self = shift;
+  my $attachment = shift;
+  $self->Limit ( FIELD => 'Parent',
+                VALUE => $attachment);
+}
+# }}}
+
+# {{{ sub NewItem 
+sub NewItem  {
+  my $self = shift;
+
+  use RT::Attachment;
+  my $item = new RT::Attachment($self->CurrentUser);
+  return($item);
+}
+# }}}
+  1;
+
+
+
+
diff --git a/rt/lib/RT/Base.pm b/rt/lib/RT/Base.pm
new file mode 100644 (file)
index 0000000..3b2dcfd
--- /dev/null
@@ -0,0 +1,97 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+package RT::Base;
+use Carp;
+
+use strict;
+use vars qw(@EXPORT);
+
+@EXPORT=qw(loc CurrentUser);
+
+=head1 FUNCTIONS
+
+
+
+# {{{ sub CurrentUser 
+
+=head2 CurrentUser
+
+If called with an argument, sets the current user to that user object.
+This will affect ACL decisions, etc.  
+Returns the current user
+
+=cut
+
+sub CurrentUser {
+    my $self = shift;
+
+    if (@_) {
+        $self->{'user'} = shift;
+    }
+
+    unless ( $self->{'user'} ) {
+        $RT::Logger->err(
+                  "$self was created without a CurrentUser\n" . Carp::cluck() );
+        return (0);
+        die;
+    }
+    return ( $self->{'user'} );
+}
+
+# }}}
+
+
+
+=item loc LOC_STRING
+
+l is a method which takes a loc string
+to this object's CurrentUser->LanguageHandle for localization. 
+
+you call it like this:
+
+    $self->loc("I have [quant,_1,concrete mixer].", 6);
+
+In english, this would return:
+    I have 6 concrete mixers.
+
+
+=cut
+
+sub loc {
+    my $self = shift;
+    unless ($self->CurrentUser) {
+        use Carp;
+        Carp::confess("No currentuser");
+        return ("Critical error:$self has no CurrentUser", $self);
+    }
+    return($self->CurrentUser->loc(@_));
+}
+
+eval "require RT::Base_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Base_Vendor.pm});
+eval "require RT::Base_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Base_Local.pm});
+
+
+1;
diff --git a/rt/lib/RT/CachedGroupMember.pm b/rt/lib/RT/CachedGroupMember.pm
new file mode 100644 (file)
index 0000000..fc3e1bf
--- /dev/null
@@ -0,0 +1,258 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
+
+=head1 NAME
+
+RT::CachedGroupMember
+
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+=cut
+
+package RT::CachedGroupMember;
+use RT::Record; 
+
+
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
+
+sub _Init {
+  my $self = shift; 
+
+  $self->Table('CachedGroupMembers');
+  $self->SUPER::_Init(@_);
+}
+
+
+
+
+
+=item Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+  int(11) 'GroupId'.
+  int(11) 'MemberId'.
+  int(11) 'Via'.
+  int(11) 'ImmediateParentId'.
+  smallint(6) 'Disabled'.
+
+=cut
+
+
+
+
+sub Create {
+    my $self = shift;
+    my %args = ( 
+                GroupId => '',
+                MemberId => '',
+                Via => '',
+                ImmediateParentId => '',
+                Disabled => '0',
+
+                 @_);
+    $self->SUPER::Create(
+                         GroupId => $args{'GroupId'},
+                         MemberId => $args{'MemberId'},
+                         Via => $args{'Via'},
+                         ImmediateParentId => $args{'ImmediateParentId'},
+                         Disabled => $args{'Disabled'},
+);
+
+}
+
+
+
+=item id
+
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
+
+
+=cut
+
+
+=item GroupId
+
+Returns the current value of GroupId. 
+(In the database, GroupId is stored as int(11).)
+
+
+
+=item SetGroupId VALUE
+
+
+Set GroupId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, GroupId will be stored as a int(11).)
+
+
+=cut
+
+
+=item MemberId
+
+Returns the current value of MemberId. 
+(In the database, MemberId is stored as int(11).)
+
+
+
+=item SetMemberId VALUE
+
+
+Set MemberId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, MemberId will be stored as a int(11).)
+
+
+=cut
+
+
+=item Via
+
+Returns the current value of Via. 
+(In the database, Via is stored as int(11).)
+
+
+
+=item SetVia VALUE
+
+
+Set Via to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Via will be stored as a int(11).)
+
+
+=cut
+
+
+=item ImmediateParentId
+
+Returns the current value of ImmediateParentId. 
+(In the database, ImmediateParentId is stored as int(11).)
+
+
+
+=item SetImmediateParentId VALUE
+
+
+Set ImmediateParentId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ImmediateParentId will be stored as a int(11).)
+
+
+=cut
+
+
+=item Disabled
+
+Returns the current value of Disabled. 
+(In the database, Disabled is stored as smallint(6).)
+
+
+
+=item SetDisabled VALUE
+
+
+Set Disabled to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Disabled will be stored as a smallint(6).)
+
+
+=cut
+
+
+
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        GroupId => 
+               {read => 1, write => 1, type => 'int(11)', default => ''},
+        MemberId => 
+               {read => 1, write => 1, type => 'int(11)', default => ''},
+        Via => 
+               {read => 1, write => 1, type => 'int(11)', default => ''},
+        ImmediateParentId => 
+               {read => 1, write => 1, type => 'int(11)', default => ''},
+        Disabled => 
+               {read => 1, write => 1, type => 'smallint(6)', default => '0'},
+
+ }
+};
+
+
+        eval "require RT::CachedGroupMember_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/CachedGroupMember_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::CachedGroupMember_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/CachedGroupMember_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::CachedGroupMember_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/CachedGroupMember_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::CachedGroupMember_Overlay, RT::CachedGroupMember_Vendor, RT::CachedGroupMember_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/CachedGroupMember_Overlay.pm b/rt/lib/RT/CachedGroupMember_Overlay.pm
new file mode 100644 (file)
index 0000000..f2dc86f
--- /dev/null
@@ -0,0 +1,323 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+use strict;
+no warnings qw(redefine);
+
+# {{{ Create
+
+=item Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+  'Group' is the "top level" group we're building the cache for. This is an 
+  RT::Principal object
+
+  'Member' is the RT::Principal  of the user or group we're adding
+  to the cache.
+
+  'ImmediateParent' is the RT::Principal of the group that this principal
+  belongs to to get here
+
+  int(11) 'Via' is an internal reference to CachedGroupMembers->Id of
+  the "parent" record of this cached group member. It should be empty if this
+  member is a "direct" member of this group. (In that case, it will be set to this 
+  cached group member's id after creation)
+
+  This routine should _only_ be called by GroupMember->Create
+
+=cut
+
+sub Create {
+    my $self = shift;
+    my %args = ( Group           => '',
+                 Member          => '',
+                 ImmediateParent => '',
+                 Via             => '0',
+                 Disabled        => '0',
+                 @_ );
+
+    unless (    $args{'Member'}
+             && UNIVERSAL::isa( $args{'Member'}, 'RT::Principal' )
+             && $args{'Member'}->Id ) {
+        $RT::Logger->debug("$self->Create: bogus Member argument");
+    }
+
+    unless (    $args{'Group'}
+             && UNIVERSAL::isa( $args{'Group'}, 'RT::Principal' )
+             && $args{'Group'}->Id ) {
+        $RT::Logger->debug("$self->Create: bogus Group argument");
+    }
+
+    unless (    $args{'ImmediateParent'}
+             && UNIVERSAL::isa( $args{'ImmediateParent'}, 'RT::Principal' )
+             && $args{'ImmediateParent'}->Id ) {
+        $RT::Logger->debug("$self->Create: bogus ImmediateParent argument");
+    }
+
+    # If the parent group for this group member is disabled, it's disabled too, along with all its children
+    if ( $args{'ImmediateParent'}->Disabled ) {
+        $args{'Disabled'} = $args{'ImmediateParent'}->Disabled;
+    }
+
+    my $id = $self->SUPER::Create(
+                              GroupId           => $args{'Group'}->Id,
+                              MemberId          => $args{'Member'}->Id,
+                              ImmediateParentId => $args{'ImmediateParent'}->Id,
+                              Disabled          => $args{'Disabled'},
+                              Via               => $args{'Via'}, );
+
+    unless ($id) {
+        $RT::Logger->warn( "Couldn't create "
+                           . $args{'Member'}
+                           . " as a cached member of "
+                           . $args{'Group'}->Id . " via "
+                           . $args{'Via'} );
+        return (undef);  #this will percolate up and bail out of the transaction
+    }
+    if ( $self->__Value('Via') == 0 ) {
+        my ( $vid, $vmsg ) = $self->__Set( Field => 'Via', Value => $id );
+        unless ($vid) {
+            $RT::Logger->warn( "Due to a via error, couldn't create "
+                               . $args{'Member'}
+                               . " as a cached member of "
+                               . $args{'Group'}->Id . " via "
+                               . $args{'Via'} );
+            return (undef)
+              ;          #this will percolate up and bail out of the transaction
+        }
+    }
+
+    if ( $args{'Member'}->IsGroup() ) {
+        my $GroupMembers = $args{'Member'}->Object->MembersObj();
+        while ( my $member = $GroupMembers->Next() ) {
+            my $cached_member =
+              RT::CachedGroupMember->new( $self->CurrentUser );
+            my $c_id = $cached_member->Create(
+                                             Group  => $args{'Group'},
+                                             Member => $member->MemberObj,
+                                             ImmediateParent => $args{'Member'},
+                                             Disabled => $args{'Disabled'},
+                                             Via      => $id );
+            unless ($c_id) {
+                return (undef);    #percolate the error upwards.
+                     # the caller will log an error and abort the transaction
+            }
+
+        }
+    }
+
+    return ($id);
+
+}
+
+# }}}
+
+# {{{ Delete
+
+=head2 Delete
+
+Deletes the current CachedGroupMember from the group it's in and cascades 
+the delete to all submembers. This routine could be completely excised if
+mysql supported foreign keys with cascading deletes.
+
+=cut 
+
+sub Delete {
+    my $self = shift;
+
+    
+    my $member = $self->MemberObj();
+    if ( $member->IsGroup ) {
+        my $deletable = RT::CachedGroupMembers->new( $self->CurrentUser );
+
+        $deletable->Limit( FIELD    => 'id',
+                           OPERATOR => '!=',
+                           VALUE    => $self->id );
+        $deletable->Limit( FIELD    => 'Via',
+                           OPERATOR => '=',
+                           VALUE    => $self->id );
+
+        while ( my $kid = $deletable->Next ) {
+            my $kid_err = $kid->Delete();
+            unless ($kid_err) {
+                $RT::Logger->error(
+                              "Couldn't delete CachedGroupMember " . $kid->Id );
+                return (undef);
+            }
+        }
+    }
+    my $err = $self->SUPER::Delete();
+    unless ($err) {
+        $RT::Logger->error( "Couldn't delete CachedGroupMember " . $self->Id );
+        return (undef);
+    }
+
+    # Unless $self->GroupObj still has the member recursively $self->MemberObj
+    # (Since we deleted the database row above, $self no longer counts)
+    unless ( $self->GroupObj->Object->HasMemberRecursively( $self->MemberObj ) ) {
+
+
+        #   Find all ACEs granted to $self->GroupId
+        my $acl = RT::ACL->new($RT::SystemUser);
+        $acl->LimitToPrincipal( Id => $self->GroupId );
+
+
+        while ( my $this_ace = $acl->Next() ) {
+            #       Find all ACEs which $self-MemberObj has delegated from $this_ace
+            my $delegations = RT::ACL->new($RT::SystemUser);
+            $delegations->DelegatedFrom( Id => $this_ace->Id );
+            $delegations->DelegatedBy( Id => $self->MemberId );
+
+            # For each delegation 
+            while ( my $delegation = $delegations->Next ) {
+                # WHACK IT
+                my $del_ret = $delegation->_Delete(InsideTransaction => 1);
+                unless ($del_ret) {
+                    $RT::Logger->crit("Couldn't delete an ACL delegation that we know exists ". $delegation->Id);
+                    return(undef);
+                }
+            }
+        }
+    }
+    return ($err);
+}
+
+# }}}
+
+# {{{ SetDisabled
+
+=head2 SetDisabled
+
+SetDisableds the current CachedGroupMember from the group it's in and cascades 
+the SetDisabled to all submembers. This routine could be completely excised if
+mysql supported foreign keys with cascading SetDisableds.
+
+=cut 
+
+sub SetDisabled {
+    my $self = shift;
+    my $val = shift;
+    
+    my $err = $self->SUPER::SetDisabled($val);
+    unless ($err) {
+        $RT::Logger->error( "Couldn't SetDisabled CachedGroupMember " . $self->Id );
+        return (undef);
+    }
+    
+    my $member = $self->MemberObj();
+    if ( $member->IsGroup ) {
+        my $deletable = RT::CachedGroupMembers->new( $self->CurrentUser );
+
+        $deletable->Limit( FIELD    => 'Via', OPERATOR => '=', VALUE    => $self->id );
+        $deletable->Limit( FIELD    => 'id', OPERATOR => '!=', VALUE    => $self->id );
+
+        while ( my $kid = $deletable->Next ) {
+            my $kid_err = $kid->SetDisabled($val );
+            unless ($kid_err) {
+                $RT::Logger->error( "Couldn't SetDisabled CachedGroupMember " . $kid->Id );
+                return (undef);
+            }
+        }
+    }
+
+    # Unless $self->GroupObj still has the member recursively $self->MemberObj
+    # (Since we SetDisabledd the database row above, $self no longer counts)
+    unless ( $self->GroupObj->Object->HasMemberRecursively( $self->MemberObj ) ) {
+        #   Find all ACEs granted to $self->GroupId
+        my $acl = RT::ACL->new($RT::SystemUser);
+        $acl->LimitToPrincipal( Id => $self->GroupId );
+
+        while ( my $this_ace = $acl->Next() ) {
+            #       Find all ACEs which $self-MemberObj has delegated from $this_ace
+            my $delegations = RT::ACL->new($RT::SystemUser);
+            $delegations->DelegatedFrom( Id => $this_ace->Id );
+            $delegations->DelegatedBy( Id => $self->MemberId );
+
+            # For each delegation,  blow away the delegation
+            while ( my $delegation = $delegations->Next ) {
+                # WHACK IT
+                my $del_ret = $delegation->_Delete(InsideTransaction => 1);
+                unless ($del_ret) {
+                    $RT::Logger->crit("Couldn't delete an ACL delegation that we know exists ". $delegation->Id);
+                    return(undef);
+                }
+            }
+        }
+    }
+    return ($err);
+}
+
+# }}}
+
+# {{{ GroupObj
+
+=head2 GroupObj  
+
+Returns the RT::Principal object for this group Group
+
+=cut
+
+sub GroupObj {
+    my $self      = shift;
+    my $principal = RT::Principal->new( $self->CurrentUser );
+    $principal->Load( $self->GroupId );
+    return ($principal);
+}
+
+# }}}
+
+# {{{ ImmediateParentObj
+
+=head2 ImmediateParentObj  
+
+Returns the RT::Principal object for this group ImmediateParent
+
+=cut
+
+sub ImmediateParentObj {
+    my $self      = shift;
+    my $principal = RT::Principal->new( $self->CurrentUser );
+    $principal->Load( $self->ImmediateParentId );
+    return ($principal);
+}
+
+# }}}
+
+# {{{ MemberObj
+
+=head2 MemberObj  
+
+Returns the RT::Principal object for this group member
+
+=cut
+
+sub MemberObj {
+    my $self      = shift;
+    my $principal = RT::Principal->new( $self->CurrentUser );
+    $principal->Load( $self->MemberId );
+    return ($principal);
+}
+
+# }}}
+1;
diff --git a/rt/lib/RT/CachedGroupMembers.pm b/rt/lib/RT/CachedGroupMembers.pm
new file mode 100644 (file)
index 0000000..b520f7b
--- /dev/null
@@ -0,0 +1,115 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
+
+=head1 NAME
+
+  RT::CachedGroupMembers -- Class Description
+=head1 SYNOPSIS
+
+  use RT::CachedGroupMembers
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=cut
+
+package RT::CachedGroupMembers;
+
+use RT::SearchBuilder;
+use RT::CachedGroupMember;
+
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
+
+
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'CachedGroupMembers';
+    $self->{'primary_key'} = 'id';
+
+
+    return ( $self->SUPER::_Init(@_) );
+}
+
+
+=item NewItem
+
+Returns an empty new RT::CachedGroupMember item
+
+=cut
+
+sub NewItem {
+    my $self = shift;
+    return(RT::CachedGroupMember->new($self->CurrentUser));
+}
+
+        eval "require RT::CachedGroupMembers_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/CachedGroupMembers_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::CachedGroupMembers_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/CachedGroupMembers_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::CachedGroupMembers_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/CachedGroupMembers_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::CachedGroupMembers_Overlay, RT::CachedGroupMembers_Vendor, RT::CachedGroupMembers_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/CachedGroupMembers_Overlay.pm b/rt/lib/RT/CachedGroupMembers_Overlay.pm
new file mode 100644 (file)
index 0000000..fd0fd90
--- /dev/null
@@ -0,0 +1,148 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::CachedGroupMembers - a collection of RT::GroupMember objects
+
+=head1 SYNOPSIS
+
+  use RT::CachedGroupMembers;
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::CachedGroupMembers);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+# {{{ LimitToUsers
+
+=head2 LimitToUsers
+
+Limits this search object to users who are members of this group
+This is really useful when you want to haave your UI seperate out
+groups from users for display purposes
+
+=cut
+
+sub LimitToUsers {
+    my $self = shift;
+
+    my $principals = $self->NewAlias('Principals');
+    $self->Join( ALIAS1 => 'main', FIELD1 => 'MemberId',
+                 ALIAS2 => $principals, FIELD2 =>'id');
+
+    $self->Limit(       ALIAS => $principals,
+                         FIELD => 'PrincipalType',
+                         VALUE => 'User',
+                         ENTRYAGGREGATOR => 'OR',
+                         );
+}
+
+# }}}
+
+
+# {{{ LimitToGroups
+
+=head2 LimitToGroups
+
+Limits this search object to Groups who are members of this group
+This is really useful when you want to haave your UI seperate out
+groups from users for display purposes
+
+=cut
+
+sub LimitToGroups {
+    my $self = shift;
+
+    my $principals = $self->NewAlias('Principals');
+    $self->Join( ALIAS1 => 'main', FIELD1 => 'MemberId',
+                 ALIAS2 => $principals, FIELD2 =>'id');
+
+    $self->Limit(       ALIAS => $principals,
+                         FIELD => 'PrincipalType',
+                         VALUE => 'Group',
+                         ENTRYAGGREGATOR => 'OR',
+                         );
+}
+
+# }}}
+
+# {{{ sub LimitToMembersOfGroup
+
+=head2 LimitToMembersOfGroup PRINCIPAL_ID
+
+Takes a Principal Id as its only argument. 
+Limits the current search principals which are _directly_ members
+of the group which has PRINCIPAL_ID as its principal id.
+
+=cut
+
+sub LimitToMembersOfGroup {
+    my $self = shift;
+    my $group = shift;
+
+    return ($self->Limit( 
+                         VALUE => $group,
+                         FIELD => 'GroupId',
+                         ENTRYAGGREGATOR => 'OR',
+                         ));
+
+}
+# }}}
+
+# {{{ sub LimitToGroupsWithMember
+
+=head2 LimitToGroupsWithMember PRINCIPAL_ID
+
+Takes a Principal Id as its only argument. 
+Limits the current search to groups which contain PRINCIPAL_ID as a member  or submember.
+This function gets used by GroupMember->Create to populate subgroups
+
+=cut
+
+sub LimitToGroupsWithMember {
+    my $self = shift;
+    my $member = shift;
+
+    return ($self->Limit( 
+                         VALUE => $member,
+                         FIELD => 'MemberId',
+                         ENTRYAGGREGATOR => 'OR',
+                                   QUOTEVALUE => 0
+                         ));
+
+}
+# }}}
+1;
index 83e5de6..4519fcf 100644 (file)
@@ -1,10 +1,33 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Condition/AnyTransaction.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# Copyright 1996-2001 Jesse Vincent <jesse@fsck.com> 
-# Released under the terms of the GNU General Public License
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 
 package RT::Condition::AnyTransaction;
 require RT::Condition::Generic;
 
+use strict;
+use vars qw/@ISA/;
 @ISA = qw(RT::Condition::Generic);
 
 
@@ -19,5 +42,10 @@ sub IsApplicable {
     return(1);
 }
 
+eval "require RT::Condition::AnyTransaction_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/AnyTransaction_Vendor.pm});
+eval "require RT::Condition::AnyTransaction_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/AnyTransaction_Local.pm});
+
 1;
 
diff --git a/rt/lib/RT/Condition/BeforeDue.pm b/rt/lib/RT/Condition/BeforeDue.pm
new file mode 100644 (file)
index 0000000..7911fd8
--- /dev/null
@@ -0,0 +1,64 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+package RT::Condition::BeforeDue;
+require RT::Condition::Generic;
+
+use RT::Date;
+
+use strict;
+use vars qw/@ISA/;
+@ISA = qw(RT::Condition::Generic);
+
+
+sub IsApplicable {
+    my $self = shift;
+
+    # Parse date string.  Format is "1d2h3m4s" for 1 day and 2 hours
+    # and 3 minutes and 4 seconds.
+    my %e;
+    foreach (qw(d h m s)) {
+       my @vals = $self->Argument =~ m/(\d+)$_/;
+       $e{$_} = pop @vals || 0;
+    }
+    my $elapse = $e{'d'} * 24*60*60 + $e{'h'} * 60*60 + $e{'m'} * 60 + $e{'s'};
+
+    my $cur = new RT::Date( $RT::SystemUser );
+    $cur->SetToNow();
+    my $due = $self->TicketObj->DueObj;
+    return (undef) if $due->Unix <= 0;
+
+    my $diff = $due->Diff($cur);
+    if ( $diff >= 0 and $diff <= $elapse ) {
+        return(1);
+    } else {
+        return(undef);
+    }
+}
+
+eval "require RT::Condition::BeforeDue_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/BeforeDue_Vendor.pm});
+eval "require RT::Condition::BeforeDue_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/BeforeDue_Local.pm});
+
+1;
index 393f4b7..bd26931 100755 (executable)
@@ -1,7 +1,26 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Condition/Generic.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# (c) 1996-2000 Jesse Vincent <jesse@fsck.com>
-# This software is redistributable under the terms of the GNU GPL
-
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 =head1 NAME
 
   RT::Condition::Generic - ;
@@ -29,7 +48,6 @@
 
 =begin testing
 
-ok (require RT::TestHarness);
 ok (require RT::Condition::Generic);
 
 =end testing
@@ -39,6 +57,11 @@ ok (require RT::Condition::Generic);
 
 package RT::Condition::Generic;
 
+use RT::Base;
+use strict;
+use vars qw/@ISA/;
+@ISA = qw(RT::Base);
+
 # {{{ sub new 
 sub new  {
   my $proto = shift;
@@ -61,7 +84,6 @@ sub _Init  {
               ApplicableTransTypes => undef,
               @_ );
   
-  
   $self->{'Argument'} = $args{'Argument'};
   $self->{'ScripObj'} = $args{'ScripObj'};
   $self->{'TicketObj'} = $args{'TicketObj'};
@@ -100,6 +122,19 @@ sub TicketObj  {
 }
 # }}}
 
+# {{{ sub ScripObj
+
+=head2 ScripObj
+
+Return the Scrip object we're talking about
+
+=cut
+
+sub ScripObj  {
+  my $self = shift;
+  return($self->{'ScripObj'});
+}
+# }}}
 # {{{ sub TransactionObj
 
 =head2 TransactionObj
@@ -137,7 +172,7 @@ sub ApplicableTransTypes  {
 # {{{ sub Describe 
 sub Describe  {
   my $self = shift;
-  return ("No description for " . ref $self);
+  return ($self->loc("No description for [_1]", ref $self));
 }
 # }}}
 
@@ -167,4 +202,10 @@ sub DESTROY {
 }
 
 # }}}
+
+eval "require RT::Condition::Generic_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/Generic_Vendor.pm});
+eval "require RT::Condition::Generic_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/Generic_Local.pm});
+
 1;
diff --git a/rt/lib/RT/Condition/NewDependency.pm b/rt/lib/RT/Condition/NewDependency.pm
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/rt/lib/RT/Condition/Overdue.pm b/rt/lib/RT/Condition/Overdue.pm
new file mode 100644 (file)
index 0000000..3a4efe7
--- /dev/null
@@ -0,0 +1,68 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+
+=head1 NAME
+
+RT::Condition::Overdue
+
+=head1 DESCRIPTION
+
+Returns true if the ticket we're operating on is overdue
+
+=cut
+
+package RT::Condition::Overdue;
+require RT::Condition::Generic;
+
+use strict;
+use vars qw/@ISA/;
+@ISA = qw(RT::Condition::Generic);
+
+
+=head2 IsApplicable
+
+If the due date is before "now" return true
+
+=cut
+
+sub IsApplicable {
+    my $self = shift;
+    if ($self->TicketObj->DueObj->Unix > 0 and
+       $self->TicketObj->DueObj->Unix < time())  {
+       return(1);
+    } 
+    else {
+       return(undef);
+    }
+}
+
+eval "require RT::Condition::Overdue_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/Overdue_Vendor.pm});
+eval "require RT::Condition::Overdue_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/Overdue_Local.pm});
+
+1;
+
diff --git a/rt/lib/RT/Condition/OwnerChange.pm b/rt/lib/RT/Condition/OwnerChange.pm
new file mode 100644 (file)
index 0000000..e17f589
--- /dev/null
@@ -0,0 +1,102 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+
+package RT::Condition::OwnerChange;
+require RT::Condition::Generic;
+
+use strict;
+use vars qw/@ISA/;
+@ISA = qw(RT::Condition::Generic);
+
+
+=head2 IsApplicable
+
+If we're changing the owner return true, otherwise return false
+
+=begin testing
+
+my $q = RT::Queue->new($RT::SystemUser);
+$q->Create(Name =>'ownerChangeTest');
+
+ok($q->Id, "Created a scriptest queue");
+
+my $s1 = RT::Scrip->new($RT::SystemUser);
+my ($val, $msg) =$s1->Create( Queue => $q->Id,
+             ScripAction => 'User Defined',
+             ScripCondition => 'On Owner Change',
+             CustomIsApplicableCode => '',
+             CustomPrepareCode => 'return 1',
+             CustomCommitCode => '
+                   $RT::Logger->crit("Before, prio is ".$self->TicketObj->Priority);
+                    $self->TicketObj->SetPriority($self->TicketObj->Priority+1);
+                   $RT::Logger->crit("After, prio is ".$self->TicketObj->Priority);
+                return(1);
+            ',
+             Template => 'Blank'
+    );
+ok($val,$msg);
+
+my $ticket = RT::Ticket->new($RT::SystemUser);
+my ($tv,$ttv,$tm) = $ticket->Create(Queue => $q->Id,
+                                    Subject => "hair on fire",
+                                    InitialPriority => '20'
+                                    );
+ok($tv, $tm);
+ok($ticket->SetOwner('root'));
+is ($ticket->Priority , '21', "Ticket priority is set right");
+ok($ticket->Steal);
+is ($ticket->Priority , '22', "Ticket priority is set right");
+ok($ticket->Untake);
+is ($ticket->Priority , '23', "Ticket priority is set right");
+ok($ticket->Take);
+is ($ticket->Priority , '24', "Ticket priority is set right");
+
+
+
+
+
+=end testing
+
+
+=cut
+
+sub IsApplicable {
+    my $self = shift;
+    if ($self->TransactionObj->Field eq 'Owner') {
+       return(1);
+    } 
+    else {
+       return(undef);
+    }
+}
+
+eval "require RT::Condition::OwnerChange_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/OwnerChange_Vendor.pm});
+eval "require RT::Condition::OwnerChange_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/OwnerChange_Local.pm});
+
+1;
+
diff --git a/rt/lib/RT/Condition/PriorityExceeds.pm b/rt/lib/RT/Condition/PriorityExceeds.pm
new file mode 100644 (file)
index 0000000..7737ca5
--- /dev/null
@@ -0,0 +1,57 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+
+package RT::Condition::PriorityExceeds;
+require RT::Condition::Generic;
+
+use strict;
+use vars qw/@ISA/;
+@ISA = qw(RT::Condition::Generic);
+
+
+=head2 IsApplicable
+
+If the priority exceeds the argument value
+
+=cut
+
+sub IsApplicable {
+    my $self = shift;
+    if ($self->TicketObj->Priority > $self->Argument)  {
+       return(1);
+    } 
+    else {
+       return(undef);
+    }
+}
+
+eval "require RT::Condition::PriorityExceeds_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/PriorityExceeds_Vendor.pm});
+eval "require RT::Condition::PriorityExceeds_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/PriorityExceeds_Local.pm});
+
+1;
+
diff --git a/rt/lib/RT/Condition/QueueChange.pm b/rt/lib/RT/Condition/QueueChange.pm
new file mode 100644 (file)
index 0000000..f3e646a
--- /dev/null
@@ -0,0 +1,57 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+
+package RT::Condition::QueueChange;
+require RT::Condition::Generic;
+
+use strict;
+use vars qw/@ISA/;
+@ISA = qw(RT::Condition::Generic);
+
+
+=head2 IsApplicable
+
+If the queue has changed.
+
+=cut
+
+sub IsApplicable {
+    my $self = shift;
+    if ($self->TransactionObj->Field eq 'Queue') {
+           return(1);
+    } 
+    else {
+           return(undef);
+    }
+}
+
+eval "require RT::Condition::QueueChange_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/QueueChange_Vendor.pm});
+eval "require RT::Condition::QueueChange_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/QueueChange_Local.pm});
+
+1;
+
index 56419b2..8afabcd 100644 (file)
@@ -1,10 +1,34 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Condition/StatusChange.pm,v 1.1 2002-08-12 06:17:08 ivan Exp $
-# Copyright 1996-2001 Jesse Vincent <jesse@fsck.com> 
-# Released under the terms of the GNU General Public License
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
 
 package RT::Condition::StatusChange;
 require RT::Condition::Generic;
 
+use strict;
+use vars qw/@ISA/;
 @ISA = qw(RT::Condition::Generic);
 
 
@@ -26,5 +50,10 @@ sub IsApplicable {
     }
 }
 
+eval "require RT::Condition::StatusChange_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/StatusChange_Vendor.pm});
+eval "require RT::Condition::StatusChange_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/StatusChange_Local.pm});
+
 1;
 
diff --git a/rt/lib/RT/Condition/UserDefined.pm b/rt/lib/RT/Condition/UserDefined.pm
new file mode 100644 (file)
index 0000000..eb829f0
--- /dev/null
@@ -0,0 +1,57 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+package RT::Condition::UserDefined;
+
+use RT::Condition::Generic;
+
+use strict;
+use vars qw/@ISA/;
+@ISA = qw(RT::Condition::Generic);
+
+
+=head2 IsApplicable
+
+This happens on every transaction. it's always applicable
+
+=cut
+
+sub IsApplicable {
+    my $self = shift;
+    my $retval = eval $self->ScripObj->CustomIsApplicableCode;
+    if ($@) {
+        $RT::Logger->error("Scrip ".$self->ScripObj->Id. " IsApplicable failed: ".$@);
+        return (undef);
+    }
+    return ($retval);
+}
+
+eval "require RT::Condition::UserDefined_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/UserDefined_Vendor.pm});
+eval "require RT::Condition::UserDefined_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/UserDefined_Local.pm});
+
+1;
+
index 6997ddb..4ca2f98 100755 (executable)
@@ -1,7 +1,26 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/CurrentUser.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# (c) 1996-1999 Jesse Vincent <jesse@fsck.com>
-# This software is redistributable under the terms of the GNU GPL
-
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 =head1 NAME
 
   RT::CurrentUser - an RT object representing the current user
@@ -19,7 +38,6 @@
 
 =begin testing
 
-ok (require RT::TestHarness);
 ok (require RT::CurrentUser);
 
 =end testing
@@ -28,9 +46,13 @@ ok (require RT::CurrentUser);
 
 
 package RT::CurrentUser;
+
 use RT::Record;
-@ISA= qw(RT::Record);
+use RT::I18N;
 
+use strict;
+use vars qw/@ISA/;
+@ISA= qw(RT::Record);
 
 # {{{ sub _Init 
 
@@ -48,7 +70,7 @@ sub _Init  {
     $self->Load($Name);
   }
   
-  $self->_MyCurrentUser($self);
+  $self->CurrentUser($self);
 
 }
 # }}}
@@ -56,7 +78,8 @@ sub _Init  {
 # {{{ sub Create
 
 sub Create {
-    return (0, 'Permission Denied');
+    my $self = shift;
+    return (0, $self->loc('Permission Denied'));
 }
 
 # }}}
@@ -64,7 +87,8 @@ sub Create {
 # {{{ sub Delete
 
 sub Delete {
-    return (0, 'Permission Denied');
+    my $self = shift;
+    return (0, $self->loc('Permission Denied'));
 }
 
 # }}}
@@ -84,7 +108,7 @@ sub UserObj {
        use RT::User;
        $self->{'UserObj'} = RT::User->new($self);
        unless ($self->{'UserObj'}->Load($self->Id)) {
-           $RT::Logger->err("Couldn't load ".$self->Id. "from the users database.\n");
+           $RT::Logger->err($self->loc("Couldn't load [_1] from the users database.\n", $self->Id));
        }
        
     }
@@ -92,6 +116,42 @@ sub UserObj {
 }
 # }}}
 
+# {{{ sub PrincipalObj 
+
+=head2 PrincipalObj
+
+    Returns this user's principal object.  this is just a helper routine for
+    $self->UserObj->PrincipalObj
+
+=cut
+
+sub PrincipalObj {
+    my $self = shift;
+    return($self->UserObj->PrincipalObj);
+}
+
+
+# }}}
+
+
+# {{{ sub PrincipalId 
+
+=head2 PrincipalId
+
+    Returns this user's principal Id.  this is just a helper routine for
+    $self->UserObj->PrincipalId
+
+=cut
+
+sub PrincipalId {
+    my $self = shift;
+    return($self->UserObj->PrincipalId);
+}
+
+
+# }}}
+
+
 # {{{ sub _Accessible 
 sub _Accessible  {
   my $self = shift;
@@ -120,6 +180,8 @@ Takes the email address of the user to load.
 sub LoadByEmail  {
     my $self = shift;
     my $identifier = shift;
+
+    $identifier = RT::User::CanonicalizeEmailAddress(undef, $identifier);
         
     $self->LoadByCol("EmailAddress",$identifier);
     
@@ -225,46 +287,88 @@ sub Privileged {
 
 # }}}
 
-# {{{ Convenient ACL methods
 
-=head2 HasQueueRight
+# {{{ sub HasRight
 
-calls $self->UserObj->HasQueueRight with the arguments passed in
+=head2 HasRight
+
+calls $self->UserObj->HasRight with the arguments passed in
 
 =cut
 
-sub HasQueueRight {
-       my $self = shift;
-       return ($self->UserObj->HasQueueRight(@_));
+sub HasRight {
+  my $self = shift;
+  return ($self->UserObj->HasRight(@_));
 }
 
-=head2 HasSystemRight
+# }}}
 
-calls $self->UserObj->HasSystemRight with the arguments passed in
+# {{{ Localization
 
-=cut
+=head2 LanguageHandle
 
+Returns this current user's langauge handle. Should take a language
+specification. but currently doesn't
 
-sub HasSystemRight {
-       my $self = shift;
-       return ($self->UserObj->HasSystemRight(@_));
-}
-# }}}
+=begin testing
 
-# {{{ sub HasRight
+ok (my $cu = RT::CurrentUser->new('root'));
+ok (my $lh = $cu->LanguageHandle);
+ok ($lh != undef);
+ok ($lh->isa('Locale::Maketext'));
+ok ($cu->loc('TEST_STRING') eq "Concrete Mixer", "Localized TEST_STRING into English");
+ok ($lh = $cu->LanguageHandle('fr'));
+ok ($cu->loc('Before') eq "Avant", "Localized TEST_STRING into Frenc");
 
-=head2 HasSystemRight
+=end testing
 
-calls $self->UserObj->HasRight with the arguments passed in
+=cut 
 
-=cut
+sub LanguageHandle {
+    my $self = shift;
+    if  ((!defined $self->{'LangHandle'}) || 
+         (!UNIVERSAL::can($self->{'LangHandle'}, 'maketext')) || 
+         (@_))  {
+        $self->{'LangHandle'} = RT::I18N->get_handle(@_);
+    }
+    # Fall back to english.
+    unless ($self->{'LangHandle'}) {
+        die "We couldn't get a dictionary. Nye mogu naidti slovar. No puedo encontrar dictionario.";
+    }
+    return ($self->{'LangHandle'});
+}
 
-sub HasRight {
-  my $self = shift;
-  return ($self->UserObj->HasRight(@_));
+sub loc {
+    my $self = shift;
+    return '' if $_[0] eq '';
+
+    my $handle = $self->LanguageHandle;
+
+    if (@_ == 1) {
+       # pre-scan the lexicon hashes to return _AUTO keys verbatim,
+       # to keep locstrings containing '[' and '~' from tripping over Maketext
+       return $_[0] unless grep { exists $_->{$_[0]} } @{ $handle->_lex_refs };
+    }
+
+    return $handle->maketext(@_);
 }
 
+sub loc_fuzzy {
+    my $self = shift;
+    return '' if $_[0] eq '';
+
+    # XXX: work around perl's deficiency when matching utf8 data
+    return $_[0] if Encode::is_utf8($_[0]);
+    my $result = $self->LanguageHandle->maketext_fuzzy(@_);
+
+    return($result);
+}
 # }}}
 
+eval "require RT::CurrentUser_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/CurrentUser_Vendor.pm});
+eval "require RT::CurrentUser_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/CurrentUser_Local.pm});
+
 1;
  
diff --git a/rt/lib/RT/CustomField.pm b/rt/lib/RT/CustomField.pm
new file mode 100644 (file)
index 0000000..cd40a3a
--- /dev/null
@@ -0,0 +1,340 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
+
+=head1 NAME
+
+RT::CustomField
+
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+=cut
+
+package RT::CustomField;
+use RT::Record; 
+use RT::Queue;
+
+
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
+
+sub _Init {
+  my $self = shift; 
+
+  $self->Table('CustomFields');
+  $self->SUPER::_Init(@_);
+}
+
+
+
+
+
+=item Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+  varchar(200) 'Name'.
+  varchar(200) 'Type'.
+  int(11) 'Queue'.
+  varchar(255) 'Description'.
+  int(11) 'SortOrder'.
+  smallint(6) 'Disabled'.
+
+=cut
+
+
+
+
+sub Create {
+    my $self = shift;
+    my %args = ( 
+                Name => '',
+                Type => '',
+                Queue => '0',
+                Description => '',
+                SortOrder => '0',
+                Disabled => '0',
+
+                 @_);
+    $self->SUPER::Create(
+                         Name => $args{'Name'},
+                         Type => $args{'Type'},
+                         Queue => $args{'Queue'},
+                         Description => $args{'Description'},
+                         SortOrder => $args{'SortOrder'},
+                         Disabled => $args{'Disabled'},
+);
+
+}
+
+
+
+=item id
+
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
+
+
+=cut
+
+
+=item Name
+
+Returns the current value of Name. 
+(In the database, Name is stored as varchar(200).)
+
+
+
+=item SetName VALUE
+
+
+Set Name to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Name will be stored as a varchar(200).)
+
+
+=cut
+
+
+=item Type
+
+Returns the current value of Type. 
+(In the database, Type is stored as varchar(200).)
+
+
+
+=item SetType VALUE
+
+
+Set Type to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Type will be stored as a varchar(200).)
+
+
+=cut
+
+
+=item Queue
+
+Returns the current value of Queue. 
+(In the database, Queue is stored as int(11).)
+
+
+
+=item SetQueue VALUE
+
+
+Set Queue to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Queue will be stored as a int(11).)
+
+
+=cut
+
+
+=item QueueObj
+
+Returns the Queue Object which has the id returned by Queue
+
+
+=cut
+
+sub QueueObj {
+       my $self = shift;
+       my $Queue =  RT::Queue->new($self->CurrentUser);
+       $Queue->Load($self->__Value('Queue'));
+       return($Queue);
+}
+
+=item Description
+
+Returns the current value of Description. 
+(In the database, Description is stored as varchar(255).)
+
+
+
+=item SetDescription VALUE
+
+
+Set Description to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Description will be stored as a varchar(255).)
+
+
+=cut
+
+
+=item SortOrder
+
+Returns the current value of SortOrder. 
+(In the database, SortOrder is stored as int(11).)
+
+
+
+=item SetSortOrder VALUE
+
+
+Set SortOrder to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, SortOrder will be stored as a int(11).)
+
+
+=cut
+
+
+=item Creator
+
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
+
+
+=cut
+
+
+=item Created
+
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
+
+
+=cut
+
+
+=item LastUpdatedBy
+
+Returns the current value of LastUpdatedBy. 
+(In the database, LastUpdatedBy is stored as int(11).)
+
+
+=cut
+
+
+=item LastUpdated
+
+Returns the current value of LastUpdated. 
+(In the database, LastUpdated is stored as datetime.)
+
+
+=cut
+
+
+=item Disabled
+
+Returns the current value of Disabled. 
+(In the database, Disabled is stored as smallint(6).)
+
+
+
+=item SetDisabled VALUE
+
+
+Set Disabled to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Disabled will be stored as a smallint(6).)
+
+
+=cut
+
+
+
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        Name => 
+               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        Type => 
+               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        Queue => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Description => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        SortOrder => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        LastUpdatedBy => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        LastUpdated => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        Disabled => 
+               {read => 1, write => 1, type => 'smallint(6)', default => '0'},
+
+ }
+};
+
+
+        eval "require RT::CustomField_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/CustomField_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::CustomField_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/CustomField_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::CustomField_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/CustomField_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::CustomField_Overlay, RT::CustomField_Vendor, RT::CustomField_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/CustomFieldValue.pm b/rt/lib/RT/CustomFieldValue.pm
new file mode 100644 (file)
index 0000000..f434b44
--- /dev/null
@@ -0,0 +1,294 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
+
+=head1 NAME
+
+RT::CustomFieldValue
+
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+=cut
+
+package RT::CustomFieldValue;
+use RT::Record; 
+use RT::CustomField;
+
+
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
+
+sub _Init {
+  my $self = shift; 
+
+  $self->Table('CustomFieldValues');
+  $self->SUPER::_Init(@_);
+}
+
+
+
+
+
+=item Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+  int(11) 'CustomField'.
+  varchar(200) 'Name'.
+  varchar(255) 'Description'.
+  int(11) 'SortOrder'.
+
+=cut
+
+
+
+
+sub Create {
+    my $self = shift;
+    my %args = ( 
+                CustomField => '0',
+                Name => '',
+                Description => '',
+                SortOrder => '0',
+
+                 @_);
+    $self->SUPER::Create(
+                         CustomField => $args{'CustomField'},
+                         Name => $args{'Name'},
+                         Description => $args{'Description'},
+                         SortOrder => $args{'SortOrder'},
+);
+
+}
+
+
+
+=item id
+
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
+
+
+=cut
+
+
+=item CustomField
+
+Returns the current value of CustomField. 
+(In the database, CustomField is stored as int(11).)
+
+
+
+=item SetCustomField VALUE
+
+
+Set CustomField to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, CustomField will be stored as a int(11).)
+
+
+=cut
+
+
+=item CustomFieldObj
+
+Returns the CustomField Object which has the id returned by CustomField
+
+
+=cut
+
+sub CustomFieldObj {
+       my $self = shift;
+       my $CustomField =  RT::CustomField->new($self->CurrentUser);
+       $CustomField->Load($self->__Value('CustomField'));
+       return($CustomField);
+}
+
+=item Name
+
+Returns the current value of Name. 
+(In the database, Name is stored as varchar(200).)
+
+
+
+=item SetName VALUE
+
+
+Set Name to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Name will be stored as a varchar(200).)
+
+
+=cut
+
+
+=item Description
+
+Returns the current value of Description. 
+(In the database, Description is stored as varchar(255).)
+
+
+
+=item SetDescription VALUE
+
+
+Set Description to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Description will be stored as a varchar(255).)
+
+
+=cut
+
+
+=item SortOrder
+
+Returns the current value of SortOrder. 
+(In the database, SortOrder is stored as int(11).)
+
+
+
+=item SetSortOrder VALUE
+
+
+Set SortOrder to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, SortOrder will be stored as a int(11).)
+
+
+=cut
+
+
+=item Creator
+
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
+
+
+=cut
+
+
+=item Created
+
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
+
+
+=cut
+
+
+=item LastUpdatedBy
+
+Returns the current value of LastUpdatedBy. 
+(In the database, LastUpdatedBy is stored as int(11).)
+
+
+=cut
+
+
+=item LastUpdated
+
+Returns the current value of LastUpdated. 
+(In the database, LastUpdated is stored as datetime.)
+
+
+=cut
+
+
+
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        CustomField => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Name => 
+               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        Description => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        SortOrder => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        LastUpdatedBy => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        LastUpdated => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+
+ }
+};
+
+
+        eval "require RT::CustomFieldValue_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/CustomFieldValue_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::CustomFieldValue_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/CustomFieldValue_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::CustomFieldValue_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/CustomFieldValue_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::CustomFieldValue_Overlay, RT::CustomFieldValue_Vendor, RT::CustomFieldValue_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/CustomFieldValues.pm b/rt/lib/RT/CustomFieldValues.pm
new file mode 100644 (file)
index 0000000..0e792b1
--- /dev/null
@@ -0,0 +1,121 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
+
+=head1 NAME
+
+  RT::CustomFieldValues -- Class Description
+=head1 SYNOPSIS
+
+  use RT::CustomFieldValues
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=cut
+
+package RT::CustomFieldValues;
+
+use RT::SearchBuilder;
+use RT::CustomFieldValue;
+
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
+
+
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'CustomFieldValues';
+    $self->{'primary_key'} = 'id';
+
+
+
+  # By default, order by name
+  $self->OrderBy( ALIAS => 'main',
+                  FIELD => 'SortOrder',
+                  ORDER => 'ASC');
+
+    return ( $self->SUPER::_Init(@_) );
+}
+
+
+=item NewItem
+
+Returns an empty new RT::CustomFieldValue item
+
+=cut
+
+sub NewItem {
+    my $self = shift;
+    return(RT::CustomFieldValue->new($self->CurrentUser));
+}
+
+        eval "require RT::CustomFieldValues_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/CustomFieldValues_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::CustomFieldValues_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/CustomFieldValues_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::CustomFieldValues_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/CustomFieldValues_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::CustomFieldValues_Overlay, RT::CustomFieldValues_Vendor, RT::CustomFieldValues_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/CustomFieldValues_Overlay.pm b/rt/lib/RT/CustomFieldValues_Overlay.pm
new file mode 100644 (file)
index 0000000..0384db9
--- /dev/null
@@ -0,0 +1,47 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+use strict;
+no warnings qw(redefine);
+
+# {{{ sub LimitToCustomField
+
+=head2 LimitToCustomField FIELD
+
+Limits the returned set to values for the custom field with Id FIELD
+
+=cut
+  
+sub LimitToCustomField {
+    my $self = shift;
+    my $cf = shift;
+    return ($self->Limit( FIELD => 'CustomField',
+                         VALUE => $cf,
+                         OPERATOR => '='));
+
+}
+
+# }}}
+
+1;
+
diff --git a/rt/lib/RT/CustomField_Overlay.pm b/rt/lib/RT/CustomField_Overlay.pm
new file mode 100644 (file)
index 0000000..89ef889
--- /dev/null
@@ -0,0 +1,560 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+use strict;
+no warnings qw(redefine);
+
+use vars qw(@TYPES %TYPES);
+
+use RT::CustomFieldValues;
+use RT::TicketCustomFieldValues;
+
+# Enumerate all valid types for this custom field
+@TYPES = (
+    'SelectSingle',    # loc
+    'SelectMultiple',  # loc
+    'FreeformSingle',  # loc
+    'FreeformMultiple', # loc
+);
+
+# Populate a hash of types of easier validation
+for (@TYPES) { $TYPES{$_} = 1};
+
+
+
+
+=head1 NAME
+
+  RT::CustomField_Overlay 
+
+=head1 DESCRIPTION
+
+=head1 'CORE' METHODS
+
+=cut
+
+
+
+=head2 Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+  varchar(200) 'Name'.
+  varchar(200) 'Type'.
+  int(11) 'Queue'.
+  varchar(255) 'Description'.
+  int(11) 'SortOrder'.
+  smallint(6) 'Disabled'.
+
+=cut
+
+
+
+
+sub Create {
+    my $self = shift;
+    my %args = ( 
+                Name => '',
+                Type => '',
+                Queue => '0',
+                Description => '',
+                SortOrder => '0',
+                Disabled => '0',
+
+                 @_);
+
+    
+
+    if (  ! $args{'Queue'} ) {
+        unless ( $self->CurrentUser->HasRight( Object => $RT::System, Right => 'AdminCustomFields') ) {
+            return ( 0, $self->loc('Permission Denied') );
+        }
+    }
+    else {
+        my $queue = RT::Queue->new($self->CurrentUser);
+        $queue->Load($args{'Queue'});
+        unless ($queue->Id) {
+            return (0, $self->loc("Queue not found"));
+        }
+        unless ( $queue->CurrentUserHasRight('AdminCustomFields') ) {
+            return ( 0, $self->loc('Permission Denied') );
+        }
+    }
+    $self->SUPER::Create(
+                         Name => $args{'Name'},
+                         Type => $args{'Type'},
+                         Queue => $args{'Queue'},
+                         Description => $args{'Description'},
+                         SortOrder => $args{'SortOrder'},
+                         Disabled => $args{'Disabled'},
+);
+
+}
+
+
+# {{{ sub LoadByNameAndQueue
+
+=head2  LoadByNameAndQueue (Queue => QUEUEID, Name => NAME)
+
+Loads the Custom field named NAME for Queue QUEUE. If QUEUE is 0,
+loads a global custom field
+
+=cut
+
+# Compatibility for API change after 3.0 beta 1
+*LoadNameAndQueue = \&LoadByNameAndQueue;
+
+sub LoadByNameAndQueue {
+    my $self = shift;
+    my %args = (
+        Queue => undef,
+        Name  => undef,
+        @_,
+    );
+
+    return ( $self->LoadByCols( Name => $args{'Name'}, Queue => $args{'Queue'} ) );
+
+}
+
+# }}}
+
+# {{{ Dealing with custom field values 
+
+=begin testing
+use_ok(RT::CustomField);
+ok(my $cf = RT::CustomField->new($RT::SystemUser));
+ok(my ($id, $msg)=  $cf->Create( Name => 'TestingCF',
+                                 Queue => '0',
+                                 SortOrder => '1',
+                                 Description => 'A Testing custom field',
+                                 Type=> 'SelectSingle'), 'Created a global CustomField');
+ok($id != 0, 'Global custom field correctly created');
+ok ($cf->SingleValue);
+ok($cf->Type eq 'SelectSingle');
+
+ok($cf->SetType('SelectMultiple'));
+ok($cf->Type eq 'SelectMultiple');
+ok(!$cf->SingleValue );
+ok(my ($bogus_val, $bogus_msg) = $cf->SetType('BogusType') , "Trying to set a custom field's type to a bogus type");
+ok($bogus_val == 0, "Unable to set a custom field's type to a bogus type");
+
+ok(my $bad_cf = RT::CustomField->new($RT::SystemUser));
+ok(my ($bad_id, $bad_msg)=  $cf->Create( Name => 'TestingCF-bad',
+                                 Queue => '0',
+                                 SortOrder => '1',
+                                 Description => 'A Testing custom field with a bogus Type',
+                                 Type=> 'SelectSingleton'), 'Created a global CustomField with a bogus type');
+ok($bad_id == 0, 'Global custom field correctly decided to not create a cf with a bogus type ');
+
+=end testing
+
+=cut
+
+# {{{ AddValue
+
+=head2 AddValue HASH
+
+Create a new value for this CustomField.  Takes a paramhash containing the elements Name, Description and SortOrder
+
+=begin testing
+
+ok(my $cf = RT::CustomField->new($RT::SystemUser));
+$cf->Load(1);
+ok($cf->Id == 1);
+ok(my ($val,$msg)  = $cf->AddValue(Name => 'foo' , Description => 'TestCFValue', SortOrder => '6'));
+ok($val != 0);
+ok (my ($delval, $delmsg) = $cf->DeleteValue($val));
+ok ($delval != 0);
+
+=end testing
+
+=cut
+
+sub AddValue {
+       my $self = shift;
+       my %args = ( Name => undef,
+                    Description => undef,
+                    SortOrder => undef,
+                    @_ );
+
+    unless ($self->CurrentUserHasRight('AdminCustomFields')) {
+        return (0, $self->loc('Permission Denied'));
+    }
+
+    unless ($args{'Name'}) {
+        return(0, $self->loc("Can't add a custom field value without a name"));
+    }
+       my $newval = RT::CustomFieldValue->new($self->CurrentUser);
+       return($newval->Create(
+                    CustomField => $self->Id,
+             Name =>$args{'Name'},
+             Description => ($args{'Description'} || ''),
+             SortOrder => ($args{'SortOrder'} || '0')
+        ));    
+}
+
+
+# }}}
+
+# {{{ DeleteValue
+
+=head2 DeleteValue ID
+
+Deletes a value from this custom field by id. 
+
+Does not remove this value for any article which has had it selected   
+
+=cut
+
+sub DeleteValue {
+       my $self = shift;
+    my $id = shift;
+    unless ($self->CurrentUserHasRight('AdminCustomFields')) {
+        return (0, $self->loc('Permission Denied'));
+    }
+
+       my $val_to_del = RT::CustomFieldValue->new($self->CurrentUser);
+       $val_to_del->Load($id);
+       unless ($val_to_del->Id) {
+               return (0, $self->loc("Couldn't find that value"));
+       }
+       unless ($val_to_del->CustomField == $self->Id) {
+               return (0, $self->loc("That is not a value for this custom field"));
+       }
+
+       my $retval = $val_to_del->Delete();
+    if ($retval) {
+        return ($retval, $self->loc("Custom field value deleted"));
+    } else {
+        return(0, $self->loc("Custom field value could not be deleted"));
+    }
+}
+
+# }}}
+
+# {{{ Values
+
+=head2 Values FIELD
+
+Return a CustomFieldeValues object of all acceptable values for this Custom Field.
+
+
+=cut
+
+sub Values {
+    my $self = shift;
+
+    my $cf_values = RT::CustomFieldValues->new($self->CurrentUser);
+    if ( $self->__Value('Queue') == 0 || $self->CurrentUserHasRight( 'SeeQueue') ) {
+        $cf_values->LimitToCustomField($self->Id);
+    }
+    return ($cf_values);
+}
+
+# }}}
+
+# }}}
+
+# {{{ Ticket related routines
+
+# {{{ ValuesForTicket
+
+=head2 ValuesForTicket TICKET
+
+Returns a RT::TicketCustomFieldValues object of this Field's values for TICKET.
+TICKET is a ticket id.
+
+
+=cut
+
+sub ValuesForTicket {
+       my $self = shift;
+    my $ticket_id = shift;
+
+       my $values = new RT::TicketCustomFieldValues($self->CurrentUser);
+       $values->LimitToCustomField($self->Id);
+    $values->LimitToTicket($ticket_id);
+
+       return ($values);
+}
+
+# }}}
+
+# {{{ AddValueForTicket
+
+=head2 AddValueForTicket HASH
+
+Adds a custom field value for a ticket. Takes a param hash of Ticket and Content
+
+=cut
+
+sub AddValueForTicket {
+       my $self = shift;
+       my %args = ( Ticket => undef,
+                 Content => undef,
+                    @_ );
+
+       my $newval = RT::TicketCustomFieldValue->new($self->CurrentUser);
+       my $val = $newval->Create(Ticket => $args{'Ticket'},
+                            Content => $args{'Content'},
+                            CustomField => $self->Id);
+
+    return($val);
+
+}
+
+
+# }}}
+
+# {{{ DeleteValueForTicket
+
+=head2 DeleteValueForTicket HASH
+
+Adds a custom field value for a ticket. Takes a param hash of Ticket and Content
+
+=cut
+
+sub DeleteValueForTicket {
+       my $self = shift;
+       my %args = ( Ticket => undef,
+                 Content => undef,
+                    @_ );
+
+       my $oldval = RT::TicketCustomFieldValue->new($self->CurrentUser);
+    $oldval->LoadByTicketContentAndCustomField (Ticket => $args{'Ticket'}, 
+                                                Content =>  $args{'Content'}, 
+                                                CustomField => $self->Id );
+    # check ot make sure we found it
+    unless ($oldval->Id) {
+        return(0, $self->loc("Custom field value [_1] could not be found for custom field [_2]", $args{'Content'}, $self->Name));
+    }
+    # delete it
+
+    my $ret = $oldval->Delete();
+    unless ($ret) {
+        return(0, $self->loc("Custom field value could not be found"));
+    }
+    return(1, $self->loc("Custom field value deleted"));
+}
+
+
+# }}}
+# }}}
+
+
+=head2 ValidateQueue Queue
+
+Make sure that the queue specified is a valid queue name
+
+=cut
+
+sub ValidateQueue {
+    my $self = shift;
+    my $id = shift;
+
+    if ($id eq '0') { # 0 means "Global" null would _not_ be ok.
+        return (1); 
+    }
+
+    my $q = RT::Queue->new($RT::SystemUser);
+    $q->Load($id);
+    unless ($q->id) {
+        return undef;
+    }
+    return (1);
+
+
+}
+
+
+# {{{ Types
+
+=head2 Types 
+
+Retuns an array of the types of CustomField that are supported
+
+=cut
+
+sub Types {
+       return (@TYPES);
+}
+
+# }}}
+
+
+=head2 FriendlyType [TYPE]
+
+Returns a localized human-readable version of the custom field type.
+If a custom field type is specified as the parameter, the friendly type for that type will be returned
+
+=cut
+
+sub FriendlyType {
+    my $self = shift;
+
+    my $type = shift || $self->Type;
+
+    if ( $type eq 'SelectSingle' ) {
+        return ( $self->loc('Select one value') );
+    }
+    elsif ( $type eq 'SelectMultiple' ) {
+        return ( $self->loc('Select multiple values') );
+    }
+    elsif ( $type eq 'FreeformSingle' ) {
+        return ( $self->loc('Enter one value') );
+    }
+    elsif ( $type eq 'FreeformMultiple' ) {
+        return ( $self->loc('Enter multiple values') );
+    }
+    else {
+        return ( $self->loc( $self->Type ) );
+    }
+}
+
+
+=head2 ValidateType TYPE
+
+Takes a single string. returns true if that string is a value
+type of custom field
+
+=begin testing
+
+ok(my $cf = RT::CustomField->new($RT::SystemUser));
+ok($cf->ValidateType('SelectSingle'));
+ok($cf->ValidateType('SelectMultiple'));
+ok(!$cf->ValidateType('SelectFooMultiple'));
+
+=end testing
+
+=cut
+
+sub ValidateType {
+    my $self = shift;
+    my $type = shift;
+
+    if( $TYPES{$type}) {
+        return(1);
+    }
+    else {
+        return undef;
+    }
+}
+
+# {{{ SingleValue
+
+=head2 SingleValue
+
+Returns true if this CustomField only accepts a single value. 
+Returns false if it accepts multiple values
+
+=cut
+
+sub SingleValue {
+    my $self = shift;
+    if ($self->Type =~  /Single$/) {
+        return 1;
+    } 
+    else {
+        return undef;
+    }
+}
+
+# }}}
+
+# {{{ sub CurrentUserHasRight
+
+=head2 CurrentUserHasRight RIGHT
+
+Helper function to call the custom field's queue's CurrentUserHasRight with the passed in args.
+
+=cut
+
+sub CurrentUserHasRight {
+    my $self = shift;
+    my $right = shift;
+    # if there's no queue, we want to know about a global right
+    if ( ( !defined $self->__Value('Queue') ) || ( $self->__Value('Queue') == 0 ) ) {
+         return $self->CurrentUser->HasRight( Object => $RT::System, Right => $right); 
+    } else {
+        return ( $self->QueueObj->CurrentUserHasRight($right) );
+    }
+}
+
+# }}}
+
+# {{{ sub _Set
+
+sub _Set {
+    my $self = shift;
+
+    unless ( $self->CurrentUserHasRight('AdminCustomFields') ) {
+        return ( 0, $self->loc('Permission Denied') );
+    }
+    return ( $self->SUPER::_Set(@_) );
+
+}
+
+# }}}
+
+# {{{ sub _Value 
+
+=head2 _Value
+
+Takes the name of a table column.
+Returns its value as a string, if the user passes an ACL check
+
+=cut
+
+sub _Value {
+
+    my $self  = shift;
+    my $field = shift;
+
+    # We need to expose the queue so that we can do things like ACL checks
+    if ( $field eq 'Queue') {
+          return ( $self->SUPER::_Value($field) );
+     }
+
+
+    #Anybody can see global custom fields, otherwise we need to do the rights check
+        unless ( $self->__Value('Queue') == 0 || $self->CurrentUserHasRight( 'SeeQueue') ) {
+            return (undef);
+        }
+    return ( $self->__Value($field) );
+
+}
+
+# }}}
+# {{{ sub SetDisabled
+
+=head2 SetDisabled
+
+Takes a boolean.
+1 will cause this custom field to no longer be avaialble for tickets.
+0 will re-enable this queue
+
+=cut
+
+# }}}
+
+1;
diff --git a/rt/lib/RT/CustomFields.pm b/rt/lib/RT/CustomFields.pm
new file mode 100644 (file)
index 0000000..3e47765
--- /dev/null
@@ -0,0 +1,121 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
+
+=head1 NAME
+
+  RT::CustomFields -- Class Description
+=head1 SYNOPSIS
+
+  use RT::CustomFields
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=cut
+
+package RT::CustomFields;
+
+use RT::SearchBuilder;
+use RT::CustomField;
+
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
+
+
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'CustomFields';
+    $self->{'primary_key'} = 'id';
+
+
+
+  # By default, order by name
+  $self->OrderBy( ALIAS => 'main',
+                  FIELD => 'SortOrder',
+                  ORDER => 'ASC');
+
+    return ( $self->SUPER::_Init(@_) );
+}
+
+
+=item NewItem
+
+Returns an empty new RT::CustomField item
+
+=cut
+
+sub NewItem {
+    my $self = shift;
+    return(RT::CustomField->new($self->CurrentUser));
+}
+
+        eval "require RT::CustomFields_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/CustomFields_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::CustomFields_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/CustomFields_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::CustomFields_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/CustomFields_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::CustomFields_Overlay, RT::CustomFields_Vendor, RT::CustomFields_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/CustomFields_Overlay.pm b/rt/lib/RT/CustomFields_Overlay.pm
new file mode 100644 (file)
index 0000000..97c7cb8
--- /dev/null
@@ -0,0 +1,135 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::CustomFields - a collection of RT CustomField objects
+
+=head1 SYNOPSIS
+
+  use RT::CustomFields;
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::CustomFields);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+
+# {{{ sub LimitToGlobalOrQueue 
+
+=item LimitToGlobalOrQueue QUEUEID
+
+Limits the set of custom fields found to global custom fields or those tied to the queue with ID QUEUEID 
+
+=cut
+
+sub LimitToGlobalOrQueue {
+    my $self = shift;
+    my $queue = shift;
+    $self->LimitToQueue($queue);
+    $self->LimitToGlobal();
+}
+
+# }}}
+
+# {{{ sub LimitToQueue 
+
+=head2 LimitToQueue QUEUEID
+
+Takes a queue id (numerical) as its only argument. Makes sure that 
+Scopes it pulls out apply to this queue (or another that you've selected with
+another call to this method
+
+=cut
+
+sub LimitToQueue  {
+   my $self = shift;
+  my $queue = shift;
+  $self->Limit (ENTRYAGGREGATOR => 'OR',
+               FIELD => 'Queue',
+               VALUE => "$queue")
+      if defined $queue;
+  
+}
+# }}}
+
+# {{{ sub LimitToGlobal
+
+=head2 LimitToGlobal
+
+Makes sure that 
+Scopes it pulls out apply to all queues (or another that you've selected with
+another call to this method or LimitToQueue
+
+=cut
+
+
+sub LimitToGlobal  {
+   my $self = shift;
+  $self->Limit (ENTRYAGGREGATOR => 'OR',
+               FIELD => 'Queue',
+               VALUE => 0);
+  
+}
+# }}}
+
+
+# {{{ sub _DoSearch 
+
+=head2 _DoSearch
+
+  A subclass of DBIx::SearchBuilder::_DoSearch that makes sure that _Disabled ro
+ws never get seen unless
+we're explicitly trying to see them.
+
+=cut
+
+sub _DoSearch {
+    my $self = shift;
+    
+    #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
+    unless($self->{'find_disabled_rows'}) {
+        $self->LimitToEnabled();
+    }
+    
+    return($self->SUPER::_DoSearch(@_));
+    
+}
+
+# }}}
+  
+1;
+
index d569971..355370a 100644 (file)
@@ -1,7 +1,26 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Date.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# (c) 1996-2000 Jesse Vincent <jesse@fsck.com>
-# This software is redistributable under the terms of the GNU GPL
-
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 =head1 NAME
 
   RT::Date - a simple Object Oriented date.
@@ -28,7 +47,15 @@ ok (require RT::Date);
 
 
 package RT::Date;
+
 use Time::Local;
+
+use RT::Base;
+
+use strict;
+use vars qw/@ISA/;
+@ISA = qw/RT::Base/;
+
 use vars qw($MINUTE $HOUR $DAY $WEEK $MONTH $YEAR);
 
 $MINUTE = 60;
@@ -45,6 +72,7 @@ sub new  {
   my $class = ref($proto) || $proto;
   my $self  = {};
   bless ($self, $class);
+  $self->CurrentUser(@_);
   $self->Unix(0);
   return $self;
 }
@@ -61,91 +89,114 @@ if $args->{'Format'} is 'unix', takes the number of seconds since the epoch
 
 If $args->{'Format'} is ISO, tries to parse an ISO date.
 
-If $args->{'Format'} is 'unknown', require Date::Parse and make it figure things
-out. This is a heavyweight operation that should never be called from within 
-RT's core. But it's really useful for something like the textbox date entry
-where we let the user do whatever they want.
+If $args->{'Format'} is 'unknown', require Time::ParseDate and make it figure
+things out. This is a heavyweight operation that should never be called from
+within RT's core. But it's really useful for something like the textbox date
+entry where we let the user do whatever they want.
 
 If $args->{'Value'}  is 0, assumes you mean never.
 
+=begin testing
+
+use_ok(RT::Date);
+my $date = RT::Date->new($RT::SystemUser);
+$date->Set(Format => 'unix', Value => '0');
+ok ($date->ISO eq '1970-01-01 00:00:00', "Set a date to midnight 1/1/1970 GMT");
+
+=end testing
 
 =cut
 
 sub Set {
     my $self = shift;
     my %args = ( Format => 'unix',
-                Value => time,
-                @_);
-    if (($args{'Value'} =~ /^\d*$/) and ($args{'Value'} == 0)) {
-       $self->Unix(-1);
-       return($self->Unix());
+                 Value  => time,
+                 @_ );
+    if ( !$args{'Value'}
+         || ( ( $args{'Value'} =~ /^\d*$/ ) and ( $args{'Value'} == 0 ) ) ) {
+        $self->Unix(-1);
+        return ( $self->Unix() );
     }
 
-    if ($args{'Format'} =~ /^unix$/i) {
-       $self->Unix($args{'Value'});
+    if ( $args{'Format'} =~ /^unix$/i ) {
+        $self->Unix( $args{'Value'} );
     }
-    
-    elsif ($args{'Format'} =~ /^(sql|datemanip|iso)$/i) {
-       
-       if (($args{'Value'} =~ /^(\d{4}?)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/) ||
-           ($args{'Value'} =~ /^(\d{4}?)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)$/) ||
-           ($args{'Value'} =~ /^(\d{4}?)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)\+00$/) ||
-           ($args{'Value'} =~ /^(\d{4}?)(\d\d)(\d\d)(\d\d):(\d\d):(\d\d)$/)) {
-           
-        my $year = $1;
-           my $mon = $2;
-           my $mday = $3;
-           my $hours = $4;
-           my $min = $5;
-           my $sec = $6;
-           
-           #timegm expects month as 0->11
-           $mon--;
-           
-           #now that we've parsed it, deal with the case where everything
-           #was 0
-            if ($mon == -1) {
-                   $self->Unix(-1);
-               } else {
-
-                   #Dateamnip strings aren't in GMT.
-                   if ($args{'Format'} =~ /^datemanip$/i) {
-                       $self->Unix(timelocal($sec,$min,$hours,$mday,$mon,$year));
-                   }
-                   #ISO and SQL dates are in GMT
-                   else {
-                       $self->Unix(timegm($sec,$min,$hours,$mday,$mon,$year));
-                   }
-                   
-                   $self->Unix(-1) unless $self->Unix;
-               }
-   }  
-       else {
-           use Carp;
-           Carp::cluck;
-           $RT::Logger->debug( "Couldn't parse date $args{'Value'} as a $args{'Format'}");
-           
-       }
+
+    elsif ( $args{'Format'} =~ /^(sql|datemanip|iso)$/i ) {
+       $args{'Value'} =~ s!/!-!g;
+
+        if (( $args{'Value'} =~ /^(\d{4}?)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/ )
+            || ( $args{'Value'} =~
+                 /^(\d{4}?)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)$/ )
+            || ( $args{'Value'} =~
+                 /^(\d{4}?)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)\+00$/ )
+            || ($args{'Value'} =~ /^(\d{4}?)(\d\d)(\d\d)(\d\d):(\d\d):(\d\d)$/ )
+          ) {
+
+            my $year  = $1;
+            my $mon   = $2;
+            my $mday  = $3;
+            my $hours = $4;
+            my $min   = $5;
+            my $sec   = $6;
+
+            #timegm expects month as 0->11
+            $mon--;
+
+            #now that we've parsed it, deal with the case where everything
+            #was 0
+            if ( $mon == -1 ) {
+                $self->Unix(-1);
+            }
+            else {
+
+                #Dateamnip strings aren't in GMT.
+                if ( $args{'Format'} =~ /^datemanip$/i ) {
+                    $self->Unix(
+                          timelocal( $sec, $min, $hours, $mday, $mon, $year ) );
+                }
+
+                #ISO and SQL dates are in GMT
+                else {
+                    $self->Unix(
+                             timegm( $sec, $min, $hours, $mday, $mon, $year ) );
+                }
+
+                $self->Unix(-1) unless $self->Unix;
+            }
+        }
+        else {
+            use Carp;
+            Carp::cluck;
+            $RT::Logger->debug(
+                     "Couldn't parse date $args{'Value'} as a $args{'Format'}");
+
+        }
+    }
+    elsif ( $args{'Format'} =~ /^unknown$/i ) {
+        require Time::ParseDate;
+
+        #Convert it to an ISO format string
+
+       my $date = Time::ParseDate::parsedate($args{'Value'},
+                       UK => $RT::DateDayBeforeMonth,
+                       PREFER_PAST => $RT::AmbiguousDayInPast,
+                       PREFER_FUTURE => !($RT::AmbiguousDayInPast));
+
+        #This date has now been set to a date in the _local_ timezone.
+        #since ISO dates are known to be in GMT (for RT's purposes);
+
+        $RT::Logger->debug( "RT::Date used date::parse to make "
+                            . $args{'Value'}
+                            . " $date\n" );
+
+        return ( $self->Set( Format => 'unix', Value => "$date" ) );
     }
-    elsif ($args{'Format'} =~ /^unknown$/i) {
-        require Date::Parse;
-        #Convert it to an ISO format string 
-        
-       my $date = Date::Parse::str2time($args{'Value'});
-        
-       #This date has now been set to a date in the _local_ timezone.
-       #since ISO dates are known to be in GMT (for RT's purposes);
-       
-       $RT::Logger->debug("RT::Date used date::parse to make ".$args{'Value'} . " $date\n");
-        
-       
-       return ($self->Set( Format => 'unix', Value => "$date"));
-    }                                                    
     else {
-       die "Unknown Date format: ".$args{'Format'}."\n";
+        die "Unknown Date format: " . $args{'Format'} . "\n";
     }
-    
-    return($self->Unix());
+
+    return ( $self->Unix() );
 }
 
 # }}}
@@ -232,47 +283,59 @@ sub DiffAsString {
 
 # {{{ sub DurationAsString
 
+
 =head2 DurationAsString
 
 Takes a number of seconds. returns a string describing that duration
 
 =cut
 
-sub DurationAsString{
+sub DurationAsString {
 
-    my $self=shift;
+    my $self     = shift;
     my $duration = shift;
-    
-    my ($negative, $s);
-    
-    $negative = 'ago' if ($duration < 0);
+
+    my ( $negative, $s );
+
+    $negative = 1 if ( $duration < 0 );
 
     $duration = abs($duration);
 
-    if($duration < $MINUTE) {
-       $s=$duration;
-       $string="sec";
-    } elsif($duration < (2 * $HOUR)) {
-       $s = int($duration/$MINUTE);
-       $string="min";
-    } elsif($duration < (2 * $DAY)) {
-       $s = int($duration/$HOUR);
-       $string="hours";
-    } elsif($duration < (2 * $WEEK)) {
-       $s = int($duration/$DAY);
-       $string="days";
-    } elsif($duration < (2 * $MONTH)) {
-       $s = int($duration/$WEEK);
-       $string="weeks";
-    } elsif($duration < $YEAR) {
-       $s = int($duration/$MONTH);
-       $string="months";
-    } else {
-       $s = int($duration/$YEAR);
-       $string="years";
+    my $time_unit;
+    if ( $duration < $MINUTE ) {
+        $s         = $duration;
+        $time_unit = $self->loc("sec");
+    }
+    elsif ( $duration < ( 2 * $HOUR ) ) {
+        $s         = int( $duration / $MINUTE );
+        $time_unit = $self->loc("min");
+    }
+    elsif ( $duration < ( 2 * $DAY ) ) {
+        $s         = int( $duration / $HOUR );
+        $time_unit = $self->loc("hours");
+    }
+    elsif ( $duration < ( 2 * $WEEK ) ) {
+        $s         = int( $duration / $DAY );
+        $time_unit = $self->loc("days");
+    }
+    elsif ( $duration < ( 2 * $MONTH ) ) {
+        $s         = int( $duration / $WEEK );
+        $time_unit = $self->loc("weeks");
+    }
+    elsif ( $duration < $YEAR ) {
+        $s         = int( $duration / $MONTH );
+        $time_unit = $self->loc("months");
+    }
+    else {
+        $s         = int( $duration / $YEAR );
+        $time_unit = $self->loc("years");
+    }
+    if (0) { # For now, never display the "AGO" # $negative) {
+        return $self->loc( "[_1] [_2] ago", $s, $time_unit );
+    }
+    else {
+        return $self->loc( "[_1] [_2]", $s, $time_unit );
     }
-    
-    return ("$s $string $negative");
 }
 
 # }}}
@@ -303,12 +366,64 @@ Returns the object\'s time as a string with the current timezone.
 
 sub AsString {
     my $self = shift;
-    return ("Not set") if ($self->Unix <= 0);
+    return ($self->loc("Not set")) if ($self->Unix <= 0);
+
+    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($self->Unix);
 
-    return (scalar(localtime($self->Unix)));
+    return $self->loc("[_1] [_2] [_3] [_4]:[_5]:[_6] [_7]", $self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900));
 }
 # }}}
 
+# {{{ GetWeekday
+=head2 GetWeekday DAY
+
+Takes an integer day of week and returns a localized string for that day of week
+
+=cut
+
+sub GetWeekday {
+    my $self = shift;
+    my $dow = shift;
+    
+    return $self->loc('Mon.') if ($dow == 1);
+    return $self->loc('Tue.') if ($dow == 2);
+    return $self->loc('Wed.') if ($dow == 3);
+    return $self->loc('Thu.') if ($dow == 4);
+    return $self->loc('Fri.') if ($dow == 5);
+    return $self->loc('Sat.') if ($dow == 6);
+    return $self->loc('Sun.') if ($dow == 0);
+}
+
+# }}}
+
+# {{{ GetMonth
+=head2 GetMonth DAY
+
+Takes an integer month and returns a localized string for that month 
+
+=cut
+
+sub GetMonth {
+    my $self = shift;
+   my $mon = shift;
+
+    # We do this rather than an array so that we don't call localize 12x what we need to
+    return $self->loc('Jan.') if ($mon == 0);
+    return $self->loc('Feb.') if ($mon == 1);
+    return $self->loc('Mar.') if ($mon == 2);
+    return $self->loc('Apr.') if ($mon == 3);
+    return $self->loc('May.') if ($mon == 4);
+    return $self->loc('Jun.') if ($mon == 5);
+    return $self->loc('Jul.') if ($mon == 6);
+    return $self->loc('Aug.') if ($mon == 7);
+    return $self->loc('Sep.') if ($mon == 8);
+    return $self->loc('Oct.') if ($mon == 9);
+    return $self->loc('Nov.') if ($mon == 10);
+    return $self->loc('Dec.') if ($mon == 11);
+}
+
+# }}}
+
 # {{{ sub AddSeconds
 
 =head2 sub AddSeconds
@@ -425,12 +540,18 @@ pull from a 'Timezone' attribute of the CurrentUser
 
 sub LocalTimezone {
     my $self = shift;
-    
+
+    return $self->CurrentUser->Timezone
+       if $self->CurrentUser and $self->CurrentUser->can('Timezone');
+
     return ($RT::Timezone);
 }
 
 # }}}
 
-
+eval "require RT::Date_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Date_Vendor.pm});
+eval "require RT::Date_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Date_Local.pm});
 
 1;
diff --git a/rt/lib/RT/EasySearch.pm b/rt/lib/RT/EasySearch.pm
deleted file mode 100755 (executable)
index bcbfa01..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Attic/EasySearch.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-
-=head1 NAME
-
-  RT::EasySearch - a baseclass for RT collection objects
-
-=head1 SYNOPSIS
-
-=head1 DESCRIPTION
-
-
-=head1 METHODS
-
-
-=begin testing
-
-ok (require RT::EasySearch);
-
-=end testing
-
-
-=cut
-
-package RT::EasySearch;
-use DBIx::SearchBuilder;
-@ISA= qw(DBIx::SearchBuilder);
-
-# {{{ sub _Init 
-sub _Init  {
-    my $self = shift;
-    
-    $self->{'user'} = shift;
-    unless(defined($self->CurrentUser)) {
-       use Carp;
-       Carp::confess("$self was created without a CurrentUser");
-       $RT::Logger->err("$self was created without a CurrentUser\n"); 
-       return(0);
-    }
-    $self->SUPER::_Init( 'Handle' => $RT::Handle);
-}
-# }}}
-
-# {{{ sub LimitToEnabled
-
-=head2 LimitToEnabled
-
-Only find items that haven\'t been disabled
-
-=cut
-
-sub LimitToEnabled {
-    my $self = shift;
-    
-    $self->Limit( FIELD => 'Disabled',
-                 VALUE => '0',
-                 OPERATOR => '=' );
-}
-# }}}
-
-# {{{ sub LimitToDisabled
-
-=head2 LimitToDeleted
-
-Only find items that have been deleted.
-
-=cut
-
-sub LimitToDeleted {
-    my $self = shift;
-    
-    $self->{'find_disabled_rows'} = 1;
-    $self->Limit( FIELD => 'Disabled',
-                 OPERATOR => '=',
-                 VALUE => '1'
-               );
-}
-# }}}
-
-
-# {{{ sub Limit 
-
-=head2 Limit PARAMHASH
-
-This Limit sub calls SUPER::Limit, but defaults "CASESENSITIVE" to 1, thus
-making sure that by default lots of things don't do extra work trying to 
-match lower(colname) agaist lc($val);
-
-=cut
-
-sub Limit {
-       my $self = shift;
-       my %args = ( CASESENSITIVE => 1,
-                    @_ );
-
-   return $self->SUPER::Limit(%args);
-}
-
-# {{{ sub CurrentUser 
-
-=head2 CurrentUser
-
-  Returns the current user as an RT::User object.
-
-=cut
-
-sub CurrentUser  {
-  my $self = shift;
-  return ($self->{'user'});
-}
-# }}}
-    
-
-1;
-
-
diff --git a/rt/lib/RT/EmailParser.pm b/rt/lib/RT/EmailParser.pm
new file mode 100644 (file)
index 0000000..49f3d55
--- /dev/null
@@ -0,0 +1,784 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+package RT::EmailParser;
+
+
+use base qw/RT::Base/;
+
+use strict;
+use Mail::Address;
+use MIME::Entity;
+use MIME::Head;
+use MIME::Parser;
+use File::Temp qw/tempdir/;
+
+=head1 NAME
+
+  RT::Interface::CLI - helper functions for creating a commandline RT interface
+
+=head1 SYNOPSIS
+
+
+=head1 DESCRIPTION
+
+
+=begin testing
+
+ok(require RT::EmailParser);
+
+=end testing
+
+
+=head1 METHODS
+
+=head2 new
+
+
+=cut
+
+sub new  {
+  my $proto = shift;
+  my $class = ref($proto) || $proto;
+  my $self  = {};
+  bless ($self, $class);
+  return $self;
+}
+
+
+
+# {{{ sub debug
+
+sub debug {
+    my $val = shift;
+    my ($debug);
+    if ($val) {
+        $RT::Logger->debug( $val . "\n" );
+        if ($debug) {
+            print STDERR "$val\n";
+        }
+    }
+    if ($debug) {
+        return (1);
+    }
+}
+
+# }}}
+
+# {{{ sub CheckForLoops 
+
+sub CheckForLoops {
+    my $self = shift;
+
+    my $head = $self->Head;
+
+    #If this instance of RT sent it our, we don't want to take it in
+    my $RTLoop = $head->get("X-RT-Loop-Prevention") || "";
+    chomp($RTLoop);    #remove that newline
+    if ( $RTLoop =~ /^$RT::rtname/ ) {
+        return (1);
+    }
+
+    # TODO: We might not trap the case where RT instance A sends a mail
+    # to RT instance B which sends a mail to ...
+    return (undef);
+}
+
+# }}}
+
+# {{{ sub CheckForSuspiciousSender
+
+sub CheckForSuspiciousSender {
+    my $self = shift;
+
+    #if it's from a postmaster or mailer daemon, it's likely a bounce.
+
+    #TODO: better algorithms needed here - there is no standards for
+    #bounces, so it's very difficult to separate them from anything
+    #else.  At the other hand, the Return-To address is only ment to be
+    #used as an error channel, we might want to put up a separate
+    #Return-To address which is treated differently.
+
+    #TODO: search through the whole email and find the right Ticket ID.
+
+    my ( $From, $junk ) = $self->ParseSenderAddressFromHead();
+
+    if ( ( $From =~ /^mailer-daemon/i ) or ( $From =~ /^postmaster/i ) ) {
+        return (1);
+
+    }
+
+    return (undef);
+
+}
+
+# }}}
+
+# {{{ sub CheckForAutoGenerated
+sub CheckForAutoGenerated {
+    my $self = shift;
+    my $head = $self->Head;
+
+    my $Precedence = $head->get("Precedence") || "";
+    if ( $Precedence =~ /^(bulk|junk)/i ) {
+        return (1);
+    }
+    else {
+        return (undef);
+    }
+}
+
+# }}}
+
+# {{{ sub ParseMIMEEntityFromSTDIN
+
+sub ParseMIMEEntityFromSTDIN {
+    my $self = shift;
+    return $self->ParseMIMEEntityFromFileHandle(\*STDIN);
+}
+
+# }}}
+
+
+sub ParseMIMEEntityFromScalar {
+    my $self = shift;
+    my $message = shift;
+
+    # Create a new parser object:
+
+    my $parser = MIME::Parser->new();
+    $self->_SetupMIMEParser($parser);
+
+
+    # TODO: XXX 3.0 we really need to wrap this in an eval { }
+    unless ( $self->{'entity'} = $parser->parse_data($message) ) {
+        # Try again, this time without extracting nested messages
+        $parser->extract_nested_messages(0);
+        unless ( $self->{'entity'} = $parser->parse_data($message) ) {
+            $RT::Logger->crit("couldn't parse MIME stream");
+            return ( undef);
+        }
+    }
+    $self->_PostProcessNewEntity();
+    return (1);
+}
+
+# {{{ ParseMIMEEntityFromFilehandle *FH
+
+=head2 ParseMIMEEntityFromFilehandle *FH
+
+Parses a mime entity from a filehandle passed in as an argument
+
+=cut
+
+sub ParseMIMEEntityFromFileHandle {
+    my $self = shift;
+    my $filehandle = shift;
+
+    # Create a new parser object:
+
+    my $parser = MIME::Parser->new();
+    $self->_SetupMIMEParser($parser);
+
+
+    # TODO: XXX 3.0 we really need to wrap this in an eval { }
+
+    unless ( $self->{'entity'} = $parser->parse($filehandle) ) {
+
+        # Try again, this time without extracting nested messages
+        $parser->extract_nested_messages(0);
+        unless ( $self->{'entity'} = $parser->parse($filehandle) ) {
+            $RT::Logger->crit("couldn't parse MIME stream");
+            return ( undef);
+        }
+    }
+    $self->_PostProcessNewEntity();
+    return (1);
+}
+
+# }}}
+
+# {{{ _PostProcessNewEntity 
+
+=head2 _PostProcessNewEntity
+
+cleans up and postprocesses a newly parsed MIME Entity
+
+=cut
+
+sub _PostProcessNewEntity {
+    my $self = shift;
+
+    #Now we've got a parsed mime object. 
+
+    # try to convert text parts into utf-8 charset
+    RT::I18N::SetMIMEEntityToEncoding($self->{'entity'}, 'utf-8');
+
+
+    # Unfold headers that are have embedded newlines
+    $self->Head->unfold;
+
+
+}
+
+# }}}
+
+# {{{ sub ParseTicketId 
+
+sub ParseTicketId {
+    my $self = shift;
+
+    my $Subject = shift;
+
+    if ( $Subject =~ s/\[$RT::rtname \#(\d+)\s*\]//i ) {
+        my $id = $1;
+        $RT::Logger->debug("Found a ticket ID. It's $id");
+        return ($id);
+    }
+    else {
+        return (undef);
+    }
+}
+
+# }}}
+
+# {{{ sub MailError 
+
+=head2 MailError { }
+
+
+# TODO this doesn't belong here.
+# TODO doc this
+
+
+=cut
+
+
+sub MailError {
+    my $self = shift;
+
+    my %args = (
+        To          => $RT::OwnerEmail,
+        Bcc         => undef,
+        From        => $RT::CorrespondAddress,
+        Subject     => 'There has been an error',
+        Explanation => 'Unexplained error',
+        MIMEObj     => undef,
+        LogLevel    => 'crit',
+        @_
+    );
+
+    $RT::Logger->log(
+        level   => $args{'LogLevel'},
+        message => $args{'Explanation'}
+    );
+    my $entity = MIME::Entity->build(
+        Type                   => "multipart/mixed",
+        From                   => $args{'From'},
+        Bcc                    => $args{'Bcc'},
+        To                     => $args{'To'},
+        Subject                => $args{'Subject'},
+        'X-RT-Loop-Prevention' => $RT::rtname,
+    );
+
+    $entity->attach( Data => $args{'Explanation'} . "\n" );
+
+    my $mimeobj = $args{'MIMEObj'};
+    $mimeobj->sync_headers();
+    $entity->add_part($mimeobj);
+
+    if ( $RT::MailCommand eq 'sendmailpipe' ) {
+        open( MAIL, "|$RT::SendmailPath $RT::SendmailArguments" ) || return (0);
+        print MAIL $entity->as_string;
+        close(MAIL);
+    }
+    else {
+        $entity->send( $RT::MailCommand, $RT::MailParams );
+    }
+}
+
+# }}}
+
+
+
+# {{{ sub GetCurrentUser 
+
+sub GetCurrentUser {
+    my $self     = shift;
+    my $ErrorsTo = shift;
+
+    my %UserInfo = ();
+
+    #Suck the address of the sender out of the header
+    my ( $Address, $Name ) = $self->ParseSenderAddressFromHead();
+
+    my $tempuser = RT::User->new($RT::SystemUser);
+
+    #This will apply local address canonicalization rules
+    $Address = $tempuser->CanonicalizeEmailAddress($Address);
+
+    #If desired, synchronize with an external database
+    my $UserFoundInExternalDatabase = 0;
+
+    # Username is the 'Name' attribute of the user that RT uses for things
+    # like authentication
+    my $Username = undef;
+    ( $UserFoundInExternalDatabase, %UserInfo ) =
+      $self->LookupExternalUserInfo( $Address, $Name );
+
+    $Address  = $UserInfo{'EmailAddress'};
+    $Username = $UserInfo{'Name'};
+
+    #Get us a currentuser object to work with. 
+    my $CurrentUser = RT::CurrentUser->new();
+
+    # First try looking up by a username, if we got one from the external
+    # db lookup. Next, try looking up by email address. Failing that,
+    # try looking up by users who have this user's email address as their
+    # username.
+
+    if ($Username) {
+        $CurrentUser->LoadByName($Username);
+    }
+
+    unless ( $CurrentUser->Id ) {
+        $CurrentUser->LoadByEmail($Address);
+    }
+
+    #If we can't get it by email address, try by name.  
+    unless ( $CurrentUser->Id ) {
+        $CurrentUser->LoadByName($Address);
+    }
+
+    unless ( $CurrentUser->Id ) {
+
+        #If we couldn't load a user, determine whether to create a user
+
+        # {{{ If we require an incoming address to be found in the external
+        # user database, reject the incoming message appropriately
+        if ( $RT::SenderMustExistInExternalDatabase
+             && !$UserFoundInExternalDatabase ) {
+
+            my $Message =
+              "Sender's email address was not found in the user database.";
+
+            # {{{  This code useful only if you've defined an AutoRejectRequest template
+
+            require RT::Template;
+            my $template = new RT::Template($RT::Nobody);
+            $template->Load('AutoRejectRequest');
+            $Message = $template->Content || $Message;
+
+            # }}}
+
+            MailError(
+                 To      => $ErrorsTo,
+                 Subject => "Ticket Creation failed: user could not be created",
+                 Explanation => $Message,
+                 MIMEObj     => $self->Entity,
+                 LogLevel    => 'notice' );
+
+            return ($CurrentUser);
+
+        }
+
+        # }}}
+
+        else {
+            my $NewUser = RT::User->new($RT::SystemUser);
+
+            my ( $Val, $Message ) = $NewUser->Create(
+                                  Name => ( $Username || $Address ),
+                                  EmailAddress => $Address,
+                                  RealName     => "$Name",
+                                  Password     => undef,
+                                  Privileged   => 0,
+                                  Comments => 'Autocreated on ticket submission'
+            );
+
+            unless ($Val) {
+
+                # Deal with the race condition of two account creations at once
+                #
+                if ($Username) {
+                    $NewUser->LoadByName($Username);
+                }
+
+                unless ( $NewUser->Id ) {
+                    $NewUser->LoadByEmail($Address);
+                }
+
+                unless ( $NewUser->Id ) {
+                    MailError(To          => $ErrorsTo,
+                              Subject     => "User could not be created",
+                              Explanation =>
+                                "User creation failed in mailgateway: $Message",
+                              MIMEObj  => $self->Entity,
+                              LogLevel => 'crit' );
+                }
+            }
+        }
+
+        #Load the new user object
+        $CurrentUser->LoadByEmail($Address);
+
+        unless ( $CurrentUser->id ) {
+            $RT::Logger->warning(
+                               "Couldn't load user '$Address'." . "giving up" );
+            MailError(
+                   To          => $ErrorsTo,
+                   Subject     => "User could not be loaded",
+                   Explanation =>
+                     "User  '$Address' could not be loaded in the mail gateway",
+                   MIMEObj  => $self->Entity,
+                   LogLevel => 'crit' );
+
+        }
+    }
+
+    return ($CurrentUser);
+
+}
+
+# }}}
+
+
+# {{{ ParseCcAddressesFromHead 
+
+=head2 ParseCcAddressesFromHead HASHREF
+
+Takes a hashref object containing QueueObj, Head and CurrentUser objects.
+Returns a list of all email addresses in the To and Cc 
+headers b<except> the current Queue\'s email addresses, the CurrentUser\'s 
+email address  and anything that the $RTAddressRegexp matches.
+
+=cut
+
+sub ParseCcAddressesFromHead {
+
+    my $self = shift;
+
+    my %args = (
+        QueueObj    => undef,
+        CurrentUser => undef,
+        @_
+    );
+
+    my (@Addresses);
+
+    my @ToObjs = Mail::Address->parse( $self->Head->get('To') );
+    my @CcObjs = Mail::Address->parse( $self->Head->get('Cc') );
+
+    foreach my $AddrObj ( @ToObjs, @CcObjs ) {
+        my $Address = $AddrObj->address;
+        my $user = RT::User->new($RT::SystemUser);
+        $Address = $user->CanonicalizeEmailAddress($Address);
+        next if ( $args{'CurrentUser'}->EmailAddress   =~ /^$Address$/i );
+        next if ( $args{'QueueObj'}->CorrespondAddress =~ /^$Address$/i );
+        next if ( $args{'QueueObj'}->CommentAddress    =~ /^$Address$/i );
+        next if ( IsRTAddress($Address) );
+
+        push ( @Addresses, $Address );
+    }
+    return (@Addresses);
+}
+
+# }}}
+
+# {{{ ParseSenderAdddressFromHead
+
+=head2 ParseSenderAddressFromHead
+
+Takes a MIME::Header object. Returns a tuple: (user@host, friendly name) 
+of the From (evaluated in order of Reply-To:, From:, Sender)
+
+=cut
+
+sub ParseSenderAddressFromHead {
+    my $self = shift;
+
+    #Figure out who's sending this message.
+    my $From = $self->Head->get('Reply-To')
+      || $self->Head->get('From')
+      || $self->Head->get('Sender');
+    return ( $self->ParseAddressFromHeader($From) );
+}
+
+# }}}
+
+# {{{ ParseErrorsToAdddressFromHead
+
+=head2 ParseErrorsToAddressFromHead
+
+Takes a MIME::Header object. Return a single value : user@host
+of the From (evaluated in order of Errors-To:,Reply-To:, From:, Sender)
+
+=cut
+
+sub ParseErrorsToAddressFromHead {
+    my $self = shift;
+
+    #Figure out who's sending this message.
+
+    foreach my $header ( 'Errors-To', 'Reply-To', 'From', 'Sender' ) {
+
+        # If there's a header of that name
+        my $headerobj = $self->Head->get($header);
+        if ($headerobj) {
+            my ( $addr, $name ) = $self->ParseAddressFromHeader($headerobj);
+
+            # If it's got actual useful content...
+            return ($addr) if ($addr);
+        }
+    }
+}
+
+# }}}
+
+# {{{ ParseAddressFromHeader
+
+=head2 ParseAddressFromHeader ADDRESS
+
+Takes an address from $self->Head->get('Line') and returns a tuple: user@host, friendly name
+
+=cut
+
+sub ParseAddressFromHeader {
+    my $self = shift;
+    my $Addr = shift;
+
+    my @Addresses = Mail::Address->parse($Addr);
+
+    my $AddrObj = $Addresses[0];
+
+    unless ( ref($AddrObj) ) {
+        return ( undef, undef );
+    }
+
+    my $Name = ( $AddrObj->phrase || $AddrObj->comment || $AddrObj->address );
+
+    #Lets take the from and load a user object.
+    my $Address = $AddrObj->address;
+
+    return ( $Address, $Name );
+}
+
+# }}}
+
+# {{{ IsRTAddress
+
+=item IsRTaddress ADDRESS
+
+Takes a single parameter, an email address. 
+Returns true if that address matches the $RTAddressRegexp.  
+Returns false, otherwise.
+
+=begin testing
+
+is(RT::EmailParser::IsRTAddress("","rt\@example.com"),1, "Regexp matched rt address" );
+is(RT::EmailParser::IsRTAddress("","frt\@example.com"),undef, "Regexp didn't match non-rt address" );
+
+=end testing
+
+=cut
+
+sub IsRTAddress {
+    my $self = shift;
+    my $address = shift;
+
+    # Example: the following rule would tell RT not to Cc 
+    #   "tickets@noc.example.com"
+    if ( defined($RT::RTAddressRegexp) &&
+                       $address =~ /$RT::RTAddressRegexp/ ) {
+        return(1);
+    } else {
+        return (undef);
+    }
+}
+
+# }}}
+
+
+# {{{ CullRTAddresses
+
+=item CullRTAddresses ARRAY
+
+Takes a single argument, an array of email addresses.
+Returns the same array with any IsRTAddress()es weeded out.
+
+=begin testing
+
+@before = ("rt\@example.com", "frt\@example.com");
+@after = ("frt\@example.com");
+ok(eq_array(RT::EmailParser::CullRTAddresses("",@before),@after), "CullRTAddresses only culls RT addresses");
+
+=end testing
+
+=cut
+
+sub CullRTAddresses {
+    my $self = shift;
+    my @addresses= (@_);
+    my @addrlist;
+
+    foreach my $addr( @addresses ) {
+      push (@addrlist, $addr)    unless IsRTAddress("", $addr);
+    }
+    return (@addrlist);
+}
+
+# }}}
+
+
+# {{{ LookupExternalUserInfo
+
+
+# LookupExternalUserInfo is a site-definable method for synchronizing
+# incoming users with an external data source. 
+#
+# This routine takes a tuple of EmailAddress and FriendlyName
+#   EmailAddress is the user's email address, ususally taken from
+#       an email message's From: header.
+#   FriendlyName is a freeform string, ususally taken from the "comment" 
+#       portion of an email message's From: header.
+#
+# If you define an AutoRejectRequest template, RT will use this   
+# template for the rejection message.
+
+
+=item LookupExternalUserInfo
+
+ LookupExternalUserInfo is a site-definable method for synchronizing
+ incoming users with an external data source. 
+
+ This routine takes a tuple of EmailAddress and FriendlyName
+    EmailAddress is the user's email address, ususally taken from
+        an email message's From: header.
+    FriendlyName is a freeform string, ususally taken from the "comment" 
+        portion of an email message's From: header.
+
+ It returns (FoundInExternalDatabase, ParamHash);
+
+   FoundInExternalDatabase must  be set to 1 before return if the user was
+   found in the external database.
+
+   ParamHash is a Perl parameter hash which can contain at least the following
+   fields. These fields are used to populate RT's users database when the user 
+   is created
+
+    EmailAddress is the email address that RT should use for this user.  
+    Name is the 'Name' attribute RT should use for this user. 
+         'Name' is used for things like access control and user lookups.
+    RealName is what RT should display as the user's name when displaying 
+         'friendly' names
+
+=cut
+
+sub LookupExternalUserInfo {
+  my $self = shift;
+  my $EmailAddress = shift;
+  my $RealName = shift;
+
+  my $FoundInExternalDatabase = 1;
+  my %params;
+
+  #Name is the RT username you want to use for this user.
+  $params{'Name'} = $EmailAddress;
+  $params{'EmailAddress'} = $EmailAddress;
+  $params{'RealName'} = $RealName;
+
+  # See RT's contributed code for examples.
+  # http://www.fsck.com/pub/rt/contrib/
+  return ($FoundInExternalDatabase, %params);
+}
+
+# }}}
+
+# {{{ Accessor methods for parsed email messages
+
+=head2 Head
+
+Return the parsed head from this message
+
+=cut
+
+sub Head {
+    my $self = shift;
+    return $self->Entity->head;
+}
+
+=head2 Entity 
+
+Return the parsed Entity from this message
+
+=cut
+
+sub Entity {
+    my $self = shift;
+    return $self->{'entity'};
+}
+
+# }}}
+# {{{ _SetupMIMEParser 
+
+=head2 _SetupMIMEParser $parser
+
+A private instance method which sets up a mime parser to do its job
+
+=cut
+
+
+    ## TODO: Does it make sense storing to disk at all?  After all, we
+    ## need to put each msg as an in-core scalar before saving it to
+    ## the database, don't we?
+
+    ## At the same time, we should make sure that we nuke attachments 
+    ## Over max size and return them
+
+sub _SetupMIMEParser {
+    my $self = shift;
+    my $parser = shift;
+    my $AttachmentDir = File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 );
+
+    # Set up output directory for files:
+    $parser->output_dir("$AttachmentDir");
+
+    #If someone includes a message, don't extract it
+    $parser->extract_nested_messages(1);
+
+    # Set up the prefix for files with auto-generated names:
+    $parser->output_prefix("part");
+
+    # If content length is <= 50000 bytes, store each msg as in-core scalar;
+    # Else, write to a disk file (the default action):
+
+    $parser->output_to_core(50000);
+}
+# }}}
+
+eval "require RT::EmailParser_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/EmailParser_Vendor.pm});
+eval "require RT::EmailParser_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/EmailParser_Local.pm});
+
+1;
index 005601f..4dcef3f 100755 (executable)
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Group.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# Copyright 2000 Jesse Vincent <jesse@fsck.com>
-# Released under the terms of the GNU Public License
-#
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
 #
 
+use strict;
+
+
 =head1 NAME
 
-  RT::Group - RT\'s group object
+RT::Group
 
-=head1 SYNOPSIS
 
-  use RT::Group;
-my $group = new RT::Group($CurrentUser);
+=head1 SYNOPSIS
 
 =head1 DESCRIPTION
 
-An RT group object.
+=head1 METHODS
 
-=head1 AUTHOR
+=cut
 
-Jesse Vincent, jesse@fsck.com
+package RT::Group;
+use RT::Record; 
 
-=head1 SEE ALSO
 
-RT
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
 
-=head1 METHODS
+sub _Init {
+  my $self = shift; 
 
+  $self->Table('Groups');
+  $self->SUPER::_Init(@_);
+}
 
-=begin testing
 
-ok (require RT::TestHarness);
-ok (require RT::Group);
 
-=end testing
 
-=cut
 
+=item Create PARAMHASH
 
-package RT::Group;
-use RT::Record;
-use RT::GroupMember;
-use RT::ACE;
+Create takes a hash of values and creates a row in the database:
 
-use vars qw|@ISA|;
-@ISA= qw(RT::Record);
+  varchar(200) 'Name'.
+  varchar(255) 'Description'.
+  varchar(64) 'Domain'.
+  varchar(64) 'Type'.
+  varchar(64) 'Instance'.
+
+=cut
 
 
-# {{{ sub _Init
-sub _Init  {
-  my $self = shift; 
-  $self->{'table'} = "Groups";
-  return ($self->SUPER::_Init(@_));
-}
-# }}}
 
-# {{{ sub _Accessible 
-sub _Accessible  {
+
+sub Create {
     my $self = shift;
-    my %Cols = (
-               Name => 'read/write',
-               Description => 'read/write',
-               Pseudo => 'read'
-              );
-    return $self->SUPER::_Accessible(@_, %Cols);
+    my %args = ( 
+                Name => '',
+                Description => '',
+                Domain => '',
+                Type => '',
+                Instance => '',
+
+                 @_);
+    $self->SUPER::Create(
+                         Name => $args{'Name'},
+                         Description => $args{'Description'},
+                         Domain => $args{'Domain'},
+                         Type => $args{'Type'},
+                         Instance => $args{'Instance'},
+);
+
 }
-# }}}
 
-# {{{ sub Load 
 
-=head2 Load
 
-Load a group object from the database. Takes a single argument.
-If the argument is numerical, load by the column 'id'. Otherwise, load by
-the "Name" column which is the group's textual name
+=item id
 
-=cut
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
 
-sub Load  {
-    my $self = shift;
-    my $identifier = shift || return undef;
-    
-    #if it's an int, load by id. otherwise, load by name.
-    if ($identifier !~ /\D/) {
-       $self->SUPER::LoadById($identifier);
-    }
-    else {
-       $self->LoadByCol("Name",$identifier);
-    }
-}
 
-# }}}
+=cut
 
-# {{{ sub Create
 
-=head2 Create
+=item Name
 
-Takes a paramhash with three named arguments: Name, Description and Pseudo.
-Pseudo is used internally by RT for certain special ACL decisions.
+Returns the current value of Name. 
+(In the database, Name is stored as varchar(200).)
 
-=cut
 
-sub Create {
-    my $self = shift;
-    my %args = ( Name => undef,
-                Description => undef,
-                Pseudo => 0,
-                @_);
-    
-    unless ($self->CurrentUser->HasSystemRight('AdminGroups')) {
-       $RT::Logger->warning($self->CurrentUser->Name ." Tried to create a group without permission.");
-       return(0, 'Permission Denied');
-    }
-    
-    my $retval = $self->SUPER::Create(Name => $args{'Name'},
-                                     Description => $args{'Description'},
-                                     Pseudo => $args{'Pseudo'});
-    
-    return ($retval);
-}
 
-# }}}
+=item SetName VALUE
 
-# {{{ sub Delete
 
-=head2 Delete
+Set Name to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Name will be stored as a varchar(200).)
 
-Delete this object
 
 =cut
 
-sub Delete {
-    my $self = shift;
-    
-    unless ($self->CurrentUser->HasSystemRight('AdminGroups')) {
-       return (0, 'Permission Denied');
-    }
-    
-    return($self->SUPER::Delete(@_));    
-}
 
-# }}}
+=item Description
 
-# {{{ MembersObj
+Returns the current value of Description. 
+(In the database, Description is stored as varchar(255).)
 
-=head2 MembersObj
 
-Returns an RT::GroupMembers object of this group's members.
+
+=item SetDescription VALUE
+
+
+Set Description to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Description will be stored as a varchar(255).)
+
 
 =cut
 
-sub MembersObj {
-    my $self = shift;
-    unless (defined $self->{'members_obj'}) {
-       use RT::GroupMembers;
-        $self->{'members_obj'} = new RT::GroupMembers($self->CurrentUser);
-       
-       #If we don't have rights, don't include any results
-       $self->{'members_obj'}->LimitToGroup($self->id);
-       
-    }
-    return ($self->{'members_obj'});
-    
-}
 
-# }}}
+=item Domain
+
+Returns the current value of Domain. 
+(In the database, Domain is stored as varchar(64).)
+
 
-# {{{ AddMember
 
-=head2 AddMember
+=item SetDomain VALUE
+
+
+Set Domain to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Domain will be stored as a varchar(64).)
 
-AddMember adds a user to this group.  It takes a user id.
-Returns a two value array. the first value is true on successful 
-addition or 0 on failure.  The second value is a textual status msg.
 
 =cut
 
-sub AddMember {
-    my $self = shift;
-    my $new_member = shift;
-
-    my $new_member_obj = new RT::User($self->CurrentUser);
-    $new_member_obj->Load($new_member);
-    
-    unless ($self->CurrentUser->HasSystemRight('AdminGroups')) {
-        #User has no permission to be doing this
-        return(0, "Permission Denied");
-    }
-
-    unless ($new_member_obj->Id) {
-       $RT::Logger->debug("Couldn't find user $new_member");
-       return(0, "Couldn't find user");
-    }  
-
-    if ($self->HasMember($new_member_obj->Id)) {
-        #User is already a member of this group. no need to add it
-        return(0, "Group already has member");
-    }
-    
-    my $member_object = new RT::GroupMember($self->CurrentUser);
-    $member_object->Create( UserId => $new_member_obj->Id, 
-                           GroupId => $self->id );
-    return(1, "Member added");
-}
 
-# }}}
+=item Type
+
+Returns the current value of Type. 
+(In the database, Type is stored as varchar(64).)
+
+
+
+=item SetType VALUE
 
-# {{{ HasMember
 
-=head2 HasMember
+Set Type to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Type will be stored as a varchar(64).)
 
-Takes a user Id and returns a GroupMember Id if that user is a member of 
-this group.
-Returns undef if the user isn't a member of the group or if the current
-user doesn't have permission to find out. Arguably, it should differentiate
-between ACL failure and non membership.
 
 =cut
 
-sub HasMember {
-    my $self = shift;
-    my $user_id = shift;
 
-    #Try to cons up a member object using "LoadByCols"
+=item Instance
 
-    my $member_obj = new RT::GroupMember($self->CurrentUser);
-    $member_obj->LoadByCols( UserId => $user_id, GroupId => $self->id);
+Returns the current value of Instance. 
+(In the database, Instance is stored as varchar(64).)
 
-    #If we have a member object
-    if (defined $member_obj->id) {
-        return ($member_obj->id);
-    }
 
-    #If Load returns no objects, we have an undef id. 
-    else {
-        return(undef);
-    } 
-}
 
-# }}}
+=item SetInstance VALUE
 
-# {{{ DeleteMember
 
-=head2 DeleteMember
+Set Instance to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Instance will be stored as a varchar(64).)
 
-Takes the user id of a member.
-If the current user has apropriate rights,
-removes that GroupMember from this group.
-Returns a two value array. the first value is true on successful 
-addition or 0 on failure.  The second value is a textual status msg.
 
 =cut
 
-sub DeleteMember {
-    my $self = shift;
-    my $member = shift;
-
-    unless ($self->CurrentUser->HasSystemRight('AdminGroups')) {
-        #User has no permission to be doing this
-        return(0,"Permission Denied");
-    }
-
-    my $member_user_obj = new RT::User($self->CurrentUser);
-    $member_user_obj->Load($member);
-    
-    unless ($member_user_obj->Id) {
-       $RT::Logger->debug("Couldn't find user $member");
-       return(0, "User not found");
-    }  
-
-    my $member_obj = new RT::GroupMember($self->CurrentUser);
-    unless ($member_obj->LoadByCols ( UserId => $member_user_obj->Id,
-                                     GroupId => $self->Id )) {
-       return(0, "Couldn\'t load member");  #couldn\'t load member object
-    }
-    
-    #If we couldn't load it, return undef.
-    unless ($member_obj->Id()) {
-       return (0, "Group has no such member");
-    }  
-    
-    #Now that we've checked ACLs and sanity, delete the groupmember
-    my $val = $member_obj->Delete();
-    if ($val) {
-       return ($val, "Member deleted");
-    }
-    else {
-       return (0, "Member not deleted");
-    }
-}
 
-# }}}
 
-# {{{ ACL Related routines
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        Name => 
+               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        Description => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        Domain => 
+               {read => 1, write => 1, type => 'varchar(64)', default => ''},
+        Type => 
+               {read => 1, write => 1, type => 'varchar(64)', default => ''},
+        Instance => 
+               {read => 1, write => 1, type => 'varchar(64)', default => ''},
 
-# {{{ GrantQueueRight
+ }
+};
 
-=head2 GrantQueueRight
 
-Grant a queue right to this group.  Takes a paramhash of which the elements
-RightAppliesTo and RightName are important.
+        eval "require RT::Group_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Group_Overlay.pm}) {
+            die $@;
+        };
 
-=cut
+        eval "require RT::Group_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Group_Vendor.pm}) {
+            die $@;
+        };
 
-sub GrantQueueRight {
-    
-    my $self = shift;
-    my %args = ( RightScope => 'Queue',
-                RightName => undef,
-                RightAppliesTo => undef,
-                PrincipalType => 'Group',
-                PrincipalId => $self->Id,
-                @_);
-   
-    #ACLs get checked in ACE.pm
-    
-    my $ace = new RT::ACE($self->CurrentUser);
-    
-    return ($ace->Create(%args));
-}
+        eval "require RT::Group_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Group_Local.pm}) {
+            die $@;
+        };
 
-# }}}
 
-# {{{ GrantSystemRight
 
-=head2 GrantSystemRight
 
-Grant a system right to this group. 
-The only element that's important to set is RightName.
+=head1 SEE ALSO
 
-=cut
-sub GrantSystemRight {
-    
-    my $self = shift;
-    my %args = ( RightScope => 'System',
-                RightName => undef,
-                RightAppliesTo => 0,
-                PrincipalType => 'Group',
-                PrincipalId => $self->Id,
-                @_);
-    
-    # ACLS get checked in ACE.pm
-    
-    my $ace = new RT::ACE($self->CurrentUser);
-    return ($ace->Create(%args));
-}
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
 
+These overlay files can contain new subs or subs to replace existing subs in this module.
 
-# }}}
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
 
+   no warnings qw(redefine);
 
-# {{{ sub _Set
-sub _Set {
-    my $self = shift;
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
 
-    unless ($self->CurrentUser->HasSystemRight('AdminGroups')) {
-       return (0, 'Permission Denied');
-    }  
+RT::Group_Overlay, RT::Group_Vendor, RT::Group_Local
 
-    return ($self->SUPER::_Set(@_));
+=cut
 
-}
-# }}}
+
+1;
index 69de50b..8de1a73 100755 (executable)
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/GroupMember.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# Copyright 2000 Jesse Vincent <jesse@fsck.com>
-# Released under the terms of the GNU Public License
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
 
 =head1 NAME
 
-  RT::GroupMember - a member of an RT Group
+RT::GroupMember
 
-=head1 SYNOPSIS
 
-RT::GroupMember should never be called directly. It should generally
-only be accessed through the helper functions in RT::Group;
+=head1 SYNOPSIS
 
 =head1 DESCRIPTION
 
+=head1 METHODS
 
+=cut
 
+package RT::GroupMember;
+use RT::Record; 
 
-=head1 METHODS
 
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
 
-=begin testing
+sub _Init {
+  my $self = shift; 
 
-ok (require RT::TestHarness);
-ok (require RT::GroupMember);
+  $self->Table('GroupMembers');
+  $self->SUPER::_Init(@_);
+}
 
-=end testing
 
 
-=cut
 
-package RT::GroupMember;
-use RT::Record;
-use vars qw|@ISA|;
-@ISA= qw(RT::Record);
 
-# {{{ sub _Init
-sub _Init {
-  my $self = shift; 
-  $self->{'table'} = "GroupMembers";
-  return($self->SUPER::_Init(@_));
-}
-# }}}
+=item Create PARAMHASH
 
-# {{{ sub _Accessible 
-sub _Accessible  {
-    my $self = shift;
-    my %Cols = (
-               GroupId => 'read',
-               UserId => 'read'
-               );
+Create takes a hash of values and creates a row in the database:
+
+  int(11) 'GroupId'.
+  int(11) 'MemberId'.
+
+=cut
 
-    return $self->SUPER::_Accessible(@_, %Cols);
-}
-# }}}
 
-# {{{ sub Create
 
-# a helper method for Add
 
 sub Create {
     my $self = shift;
-    my %args = ( GroupId => undef,
-                UserId => undef,
-                @_
-              );
-    
-    unless( $self->CurrentUser->HasSystemRight('AdminGroups')) {
-       return (0, 'Permission Denied');
-    }
-
-    return ($self->SUPER::Create(GroupId => $args{'GroupId'},
-                                UserId => $args{'UserId'}))
+    my %args = ( 
+                GroupId => '0',
+                MemberId => '0',
+
+                 @_);
+    $self->SUPER::Create(
+                         GroupId => $args{'GroupId'},
+                         MemberId => $args{'MemberId'},
+);
+
 }
-# }}}
 
-# {{{ sub Add
 
-=head2 Add
 
-Takes a paramhash of UserId and GroupId.  makes that user a memeber
-of that group
+=item id
+
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
+
 
 =cut
 
-sub Add {
-    my $self = shift;
-    return ($self->Create(@_));
-}
-# }}}
 
-# {{{ sub Delete
+=item GroupId
+
+Returns the current value of GroupId. 
+(In the database, GroupId is stored as int(11).)
+
+
+
+=item SetGroupId VALUE
+
 
-=head2 Delete
+Set GroupId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, GroupId will be stored as a int(11).)
 
-Takes no arguments. deletes the currently loaded member from the 
-group in question.
 
 =cut
 
-sub Delete {
-    my $self = shift;
-    unless ($self->CurrentUser->HasSystemRight('AdminGroups')) {
-       return (0, 'Permission Denied');
-    }
-    return($self->SUPER::Delete(@_));
-}
 
-# }}}
+=item MemberId
+
+Returns the current value of MemberId. 
+(In the database, MemberId is stored as int(11).)
+
 
-# {{{ sub UserObj
 
-=head2 UserObj
+=item SetMemberId VALUE
+
+
+Set MemberId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, MemberId will be stored as a int(11).)
 
-Returns an RT::User object for the user specified by $self->UserId
 
 =cut
 
-sub UserObj {
-    my $self = shift;
-    unless (defined ($self->{'user_obj'})) {
-        $self->{'user_obj'} = new RT::User($self->CurrentUser);
-        $self->{'user_obj'}->Load($self->UserId);
-    }
-    return($self->{'user_obj'});
-}
 
-# {{{ sub _Set
-sub _Set {
-    my $self = shift;
-    unless ($self->CurrentUser->HasSystemRight('AdminGroups')) {
-       return (0, 'Permission Denied');
-    }
-    return($self->SUPER::_Set(@_));
-}
-# }}}
+
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        GroupId => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        MemberId => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+
+ }
+};
+
+
+        eval "require RT::GroupMember_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/GroupMember_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::GroupMember_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/GroupMember_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::GroupMember_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/GroupMember_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::GroupMember_Overlay, RT::GroupMember_Vendor, RT::GroupMember_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/GroupMember_Overlay.pm b/rt/lib/RT/GroupMember_Overlay.pm
new file mode 100644 (file)
index 0000000..20949f0
--- /dev/null
@@ -0,0 +1,351 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::GroupMember - a member of an RT Group
+
+=head1 SYNOPSIS
+
+RT::GroupMember should never be called directly. It should ONLY
+only be accessed through the helper functions in RT::Group;
+
+If you're operating on an RT::GroupMember object yourself, you B<ARE>
+doing something wrong.
+
+=head1 DESCRIPTION
+
+
+
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::GroupMember);
+
+=end testing
+
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+use RT::CachedGroupMembers;
+
+# {{{ sub Create
+
+=head2 Create { Group => undef, Member => undef }
+
+Add a Principal to the group Group.
+if the Principal is a group, automatically inserts all
+members of the principal into the cached members table recursively down.
+
+Both Group and Member are expected to be RT::Principal objects
+
+=cut
+
+sub Create {
+    my $self = shift;
+    my %args = (
+        Group  => undef,
+        Member => undef,
+        InsideTransaction => undef,
+        @_
+    );
+
+    unless ($args{'Group'} &&
+            UNIVERSAL::isa($args{'Group'}, 'RT::Principal') &&
+            $args{'Group'}->Id ) {
+
+        $RT::Logger->warning("GroupMember::Create called with a bogus Group arg");
+        return (undef);
+    }
+
+    unless($args{'Group'}->IsGroup) {
+        $RT::Logger->warning("Someone tried to add a member to a user instead of a group");
+        return (undef);
+    }
+
+    unless ($args{'Member'} && 
+            UNIVERSAL::isa($args{'Member'}, 'RT::Principal') &&
+            $args{'Member'}->Id) {
+        $RT::Logger->warning("GroupMember::Create called with a bogus Principal arg");
+        return (undef);
+    }
+
+
+    #Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space. 
+    # TODO what about the groups key cache?
+    RT::Principal->_InvalidateACLCache();
+
+    $RT::Handle->BeginTransaction() unless ($args{'InsideTransaction'});
+
+    # We really need to make sure we don't add any members to this group
+    # that contain the group itself. that would, um, suck. 
+    # (and recurse infinitely)  Later, we can add code to check this in the 
+    # cache and bail so we can support cycling directed graphs
+
+    if ($args{'Member'}->IsGroup) {
+        my $member_object = $args{'Member'}->Object;
+        if ($member_object->HasMemberRecursively($args{'Group'})) {
+            $RT::Logger->debug("Adding that group would create a loop");
+            return(undef);
+        }
+        elsif ( $args{'Member'}->Id == $args{'Group'}->Id) {
+            $RT::Logger->debug("Can't add a group to itself");
+            return(undef);
+        }
+    }
+
+
+    my $id = $self->SUPER::Create(
+        GroupId  => $args{'Group'}->Id,
+        MemberId => $args{'Member'}->Id
+    );
+
+    unless ($id) {
+        $RT::Handle->Rollback() unless ($args{'InsideTransaction'});
+        return (undef);
+    }
+
+    my $cached_member = RT::CachedGroupMember->new( $self->CurrentUser );
+    my $cached_id     = $cached_member->Create(
+        Member          => $args{'Member'},
+        Group           => $args{'Group'},
+        ImmediateParent => $args{'Group'},
+        Via             => '0'
+    );
+
+
+    #When adding a member to a group, we need to go back
+    #and popuplate the CachedGroupMembers of all the groups that group is part of .
+
+    my $cgm = RT::CachedGroupMembers->new( $self->CurrentUser );
+
+    # find things which have the current group as a member. 
+    # $group is an RT::Principal for the group.
+    $cgm->LimitToGroupsWithMember( $args{'Group'}->Id );
+
+    while ( my $parent_member = $cgm->Next ) {
+        my $parent_id = $parent_member->MemberId;
+        my $via       = $parent_member->Id;
+        my $group_id  = $parent_member->GroupId;
+
+          my $other_cached_member =
+          RT::CachedGroupMember->new( $self->CurrentUser );
+        my $other_cached_id = $other_cached_member->Create(
+            Member          => $args{'Member'},
+                      Group => $parent_member->GroupObj,
+            ImmediateParent => $parent_member->MemberObj,
+            Via             => $parent_member->Id
+        );
+        unless ($other_cached_id) {
+            $RT::Logger->err( "Couldn't add " . $args{'Member'}
+                  . " as a submember of a supergroup" );
+            $RT::Handle->Rollback() unless ($args{'InsideTransaction'});
+            return (undef);
+        }
+    } 
+
+    unless ($cached_id) {
+        $RT::Handle->Rollback() unless ($args{'InsideTransaction'});
+        return (undef);
+    }
+
+    $RT::Handle->Commit() unless ($args{'InsideTransaction'});
+
+    return ($id);
+}
+
+# }}}
+
+# {{{ sub _StashUser
+
+=head2 _StashUser PRINCIPAL
+
+Create { Group => undef, Member => undef }
+
+Creates an entry in the groupmembers table, which lists a user
+as a member of himself. This makes ACL checks a whole bunch easier.
+This happens once on user create and never ever gets yanked out.
+
+PRINCIPAL is expected to be an RT::Principal object for a user
+
+This routine expects to be called inside a transaction by RT::User->Create
+
+=cut
+
+sub _StashUser {
+    my $self = shift;
+    my %args = (
+        Group  => undef,
+        Member => undef,
+        @_
+    );
+
+    #Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space. 
+    # TODO what about the groups key cache?
+    RT::Principal->_InvalidateACLCache();
+
+
+    # We really need to make sure we don't add any members to this group
+    # that contain the group itself. that would, um, suck. 
+    # (and recurse infinitely)  Later, we can add code to check this in the 
+    # cache and bail so we can support cycling directed graphs
+
+    my $id = $self->SUPER::Create(
+        GroupId  => $args{'Group'}->Id,
+        MemberId => $args{'Member'}->Id,
+    );
+
+    unless ($id) {
+        return (undef);
+    }
+
+    my $cached_member = RT::CachedGroupMember->new( $self->CurrentUser );
+    my $cached_id     = $cached_member->Create(
+        Member          => $args{'Member'},
+        Group           => $args{'Group'},
+        ImmediateParent => $args{'Group'},
+        Via             => '0'
+    );
+
+    unless ($cached_id) {
+        return (undef);
+    }
+
+    return ($id);
+}
+
+# }}}
+
+# {{{ sub Delete
+
+=head2 Delete
+
+Takes no arguments. deletes the currently loaded member from the 
+group in question.
+
+Expects to be called _outside_ a transaction
+
+=cut
+
+sub Delete {
+    my $self = shift;
+
+
+    $RT::Handle->BeginTransaction();
+
+    # Find all occurrences of this member as a member of this group
+    # in the cache and nuke them, recursively.
+
+    # The following code will delete all Cached Group members
+    # where this member's group is _not_ the primary group 
+    # (Ie if we're deleting C as a member of B, and B happens to be 
+    # a member of A, will delete C as a member of A without touching
+    # C as a member of B
+
+    my $cached_submembers = RT::CachedGroupMembers->new( $self->CurrentUser );
+
+    $cached_submembers->Limit(
+        FIELD    => 'MemberId',
+        OPERATOR => '=',
+        VALUE    => $self->MemberObj->Id
+    );
+
+    $cached_submembers->Limit(
+        FIELD    => 'ImmediateParentId',
+        OPERATOR => '=',
+        VALUE    => $self->GroupObj->Id
+    );
+
+    #Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space. 
+    # TODO what about the groups key cache?
+    RT::Principal->_InvalidateACLCache();
+
+
+
+
+    while ( my $item_to_del = $cached_submembers->Next() ) {
+        my $del_err = $item_to_del->Delete();
+        unless ($del_err) {
+            $RT::Handle->Rollback();
+            $RT::Logger->warning("Couldn't delete cached group submember ".$item_to_del->Id);
+            return (undef);
+        }
+    }
+
+    my $err = $self->SUPER::Delete();
+    unless ($err) {
+            $RT::Logger->warning("Couldn't delete cached group submember ".$self->Id);
+        $RT::Handle->Rollback();
+        return (undef);
+    }
+    $RT::Handle->Commit();
+    return ($err);
+
+}
+
+# }}}
+
+# {{{ sub MemberObj
+
+=head2 MemberObj
+
+Returns an RT::Principal object for the Principal specified by $self->PrincipalId
+
+=cut
+
+sub MemberObj {
+    my $self = shift;
+    unless ( defined( $self->{'Member_obj'} ) ) {
+        $self->{'Member_obj'} = RT::Principal->new( $self->CurrentUser );
+        $self->{'Member_obj'}->Load( $self->MemberId );
+    }
+    return ( $self->{'Member_obj'} );
+}
+
+# }}}
+
+# {{{ sub GroupObj
+
+=head2 GroupObj
+
+Returns an RT::Principal object for the Group specified in $self->GroupId
+
+=cut
+
+sub GroupObj {
+    my $self = shift;
+    unless ( defined( $self->{'Group_obj'} ) ) {
+        $self->{'Group_obj'} = RT::Principal->new( $self->CurrentUser );
+        $self->{'Group_obj'}->Load( $self->GroupId );
+    }
+    return ( $self->{'Group_obj'} );
+}
+
+# }}}
+
+1;
index a90a2a8..31cb953 100755 (executable)
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/GroupMembers.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-=head1 NAME
 
-  RT::GroupMembers - a collection of RT::GroupMember objects
+=head1 NAME
 
+  RT::GroupMembers -- Class Description
 =head1 SYNOPSIS
 
-  use RT::GroupMembers;
+  use RT::GroupMembers
 
 =head1 DESCRIPTION
 
 
 =head1 METHODS
 
-
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::GroupMembers);
-
-=end testing
-
 =cut
 
 package RT::GroupMembers;
-use RT::EasySearch;
+
+use RT::SearchBuilder;
 use RT::GroupMember;
 
-@ISA= qw(RT::EasySearch);
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
 
 
-# {{{ sub _Init  
-sub _Init   {
-  my $self = shift;
-  $self->{'table'} = "GroupMembers";
-  $self->{'primary_key'} = "id";
-  return ( $self->SUPER::_Init(@_) );
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'GroupMembers';
+    $self->{'primary_key'} = 'id';
+
+
+    return ( $self->SUPER::_Init(@_) );
 }
-# }}}
 
-# {{{ sub LimitToGroup
 
-=head2 LimitToGroup
+=item NewItem
 
-Takes a group id as its only argument.  Limits the current search to that
-group object
+Returns an empty new RT::GroupMember item
 
 =cut
 
-sub LimitToGroup {
+sub NewItem {
     my $self = shift;
-    my $group = shift;
+    return(RT::GroupMember->new($self->CurrentUser));
+}
 
-    return ($self->Limit( 
-                         VALUE => "$group",
-                         FIELD => 'GroupId',
-                         ENTRYAGGREGATOR => 'OR',
-                         ));
+        eval "require RT::GroupMembers_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/GroupMembers_Overlay.pm}) {
+            die $@;
+        };
 
-}
-# }}}
+        eval "require RT::GroupMembers_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/GroupMembers_Vendor.pm}) {
+            die $@;
+        };
 
-# {{{ sub NewItem 
+        eval "require RT::GroupMembers_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/GroupMembers_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::GroupMembers_Overlay, RT::GroupMembers_Vendor, RT::GroupMembers_Local
+
+=cut
 
-sub NewItem  {
-    my $self = shift;
-    return(RT::GroupMember->new($self->CurrentUser))
-}
 
-# }}}
 1;
diff --git a/rt/lib/RT/GroupMembers_Overlay.pm b/rt/lib/RT/GroupMembers_Overlay.pm
new file mode 100644 (file)
index 0000000..1259fd6
--- /dev/null
@@ -0,0 +1,126 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::GroupMembers - a collection of RT::GroupMember objects
+
+=head1 SYNOPSIS
+
+  use RT::GroupMembers;
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::GroupMembers);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+# {{{ LimitToUsers
+
+=head2 LimitToUsers
+
+Limits this search object to users who are members of this group.
+This is really useful when you want to haave your UI seperate out
+groups from users for display purposes
+
+=cut
+
+sub LimitToUsers {
+    my $self = shift;
+
+    my $principals = $self->NewAlias('Principals');
+    $self->Join( ALIAS1 => 'main', FIELD1 => 'MemberId',
+                 ALIAS2 => $principals, FIELD2 =>'id');
+
+    $self->Limit(       ALIAS => $principals,
+                         FIELD => 'PrincipalType',
+                         VALUE => 'User',
+                         ENTRYAGGREGATOR => 'OR',
+                         );
+}
+
+# }}}
+
+
+# {{{ LimitToGroups
+
+=head2 LimitToGroups
+
+Limits this search object to Groups who are members of this group.
+This is really useful when you want to haave your UI seperate out
+groups from users for display purposes
+
+=cut
+
+sub LimitToGroups {
+    my $self = shift;
+
+    my $principals = $self->NewAlias('Principals');
+    $self->Join( ALIAS1 => 'main', FIELD1 => 'MemberId',
+                 ALIAS2 => $principals, FIELD2 =>'id');
+
+    $self->Limit(       ALIAS => $principals,
+                         FIELD => 'PrincipalType',
+                         VALUE => 'Group',
+                         ENTRYAGGREGATOR => 'OR',
+                         );
+}
+
+# }}}
+
+# {{{ sub LimitToMembersOfGroup
+
+=head2 LimitToMembersOfGroup PRINCIPAL_ID
+
+Takes a Principal Id as its only argument. 
+Limits the current search principals which are _directly_ members
+of the group which has PRINCIPAL_ID as its principal id.
+
+=cut
+
+sub LimitToMembersOfGroup {
+    my $self = shift;
+    my $group = shift;
+
+    return ($self->Limit( 
+                         VALUE => $group,
+                         FIELD => 'GroupId',
+                         ENTRYAGGREGATOR => 'OR',
+                                    QUOTEVALUE => 0
+                         ));
+
+}
+# }}}
+
+1;
diff --git a/rt/lib/RT/Group_Overlay.pm b/rt/lib/RT/Group_Overlay.pm
new file mode 100644 (file)
index 0000000..9215025
--- /dev/null
@@ -0,0 +1,1260 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Released under the terms of version 2 of the GNU Public License
+
+=head1 NAME
+
+  RT::Group - RT\'s group object
+
+=head1 SYNOPSIS
+
+  use RT::Group;
+my $group = new RT::Group($CurrentUser);
+
+=head1 DESCRIPTION
+
+An RT group object.
+
+=head1 AUTHOR
+
+Jesse Vincent, jesse@bestpractical.com
+
+=head1 SEE ALSO
+
+RT
+
+=head1 METHODS
+
+
+=begin testing
+
+# {{{ Tests
+ok (require RT::Group);
+
+ok (my $group = RT::Group->new($RT::SystemUser), "instantiated a group object");
+ok (my ($id, $msg) = $group->CreateUserDefinedGroup( Name => 'TestGroup', Description => 'A test group',
+                    ), 'Created a new group');
+ok ($id != 0, "Group id is $id");
+ok ($group->Name eq 'TestGroup', "The group's name is 'TestGroup'");
+my $ng = RT::Group->new($RT::SystemUser);
+
+ok($ng->LoadUserDefinedGroup('TestGroup'), "Loaded testgroup");
+ok(($ng->id == $group->id), "Loaded the right group");
+
+
+ok (($id,$msg) = $ng->AddMember('1'), "Added a member to the group");
+ok($id, $msg);
+ok (($id,$msg) = $ng->AddMember('2' ), "Added a member to the group");
+ok($id, $msg);
+ok (($id,$msg) = $ng->AddMember('3' ), "Added a member to the group");
+ok($id, $msg);
+
+# Group 1 now has members 1, 2 ,3
+
+my $group_2 = RT::Group->new($RT::SystemUser);
+ok (my ($id_2, $msg_2) = $group_2->CreateUserDefinedGroup( Name => 'TestGroup2', Description => 'A second test group'), , 'Created a new group');
+ok ($id_2 != 0, "Created group 2 ok- $msg_2 ");
+ok (($id,$msg) = $group_2->AddMember($ng->PrincipalId), "Made TestGroup a member of testgroup2");
+ok($id, $msg);
+ok (($id,$msg) = $group_2->AddMember('1' ), "Added  member RT_System to the group TestGroup2");
+ok($id, $msg);
+
+# Group 2 how has 1, g1->{1, 2,3}
+
+my $group_3 = RT::Group->new($RT::SystemUser);
+ok (($id_3, $msg) = $group_3->CreateUserDefinedGroup( Name => 'TestGroup3', Description => 'A second test group'), 'Created a new group');
+ok ($id_3 != 0, "Created group 3 ok - $msg");
+ok (($id,$msg) =$group_3->AddMember($group_2->PrincipalId), "Made TestGroup a member of testgroup2");
+ok($id, $msg);
+
+# g3 now has g2->{1, g1->{1,2,3}}
+
+my $principal_1 = RT::Principal->new($RT::SystemUser);
+$principal_1->Load('1');
+
+my $principal_2 = RT::Principal->new($RT::SystemUser);
+$principal_2->Load('2');
+
+ok (($id,$msg) = $group_3->AddMember('1' ), "Added  member RT_System to the group TestGroup2");
+ok($id, $msg);
+
+# g3 now has 1, g2->{1, g1->{1,2,3}}
+
+ok($group_3->HasMember($principal_2) == undef, "group 3 doesn't have member 2");
+ok($group_3->HasMemberRecursively($principal_2), "group 3 has member 2 recursively");
+ok($ng->HasMember($principal_2) , "group ".$ng->Id." has member 2");
+my ($delid , $delmsg) =$ng->DeleteMember($principal_2->Id);
+ok ($delid !=0, "Sucessfully deleted it-".$delid."-".$delmsg);
+
+#Gotta reload the group objects, since we've been messing with various internals.
+# we shouldn't need to do this.
+#$ng->LoadUserDefinedGroup('TestGroup');
+#$group_2->LoadUserDefinedGroup('TestGroup2');
+#$group_3->LoadUserDefinedGroup('TestGroup');
+
+# G1 now has 1, 3
+# Group 2 how has 1, g1->{1, 3}
+# g3 now has  1, g2->{1, g1->{1, 3}}
+
+ok(!$ng->HasMember($principal_2)  , "group ".$ng->Id." no longer has member 2");
+ok($group_3->HasMemberRecursively($principal_2) == undef, "group 3 doesn't have member 2");
+ok($group_2->HasMemberRecursively($principal_2) == undef, "group 2 doesn't have member 2");
+ok($ng->HasMember($principal_2) == undef, "group 1 doesn't have member 2");;
+ok($group_3->HasMemberRecursively($principal_2) == undef, "group 3 has member 2 recursively");
+
+# }}}
+
+=end testing
+
+
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+use RT::Users;
+use RT::GroupMembers;
+use RT::Principals;
+use RT::ACL;
+
+use vars qw/$RIGHTS/;
+
+$RIGHTS = {
+    AdminGroup           => 'Modify group metadata or delete group',  # loc_pair
+    AdminGroupMembership =>
+      'Modify membership roster for this group',                      # loc_pair
+    ModifyOwnMembership => 'Join or leave this group'                 # loc_pair
+};
+
+# Tell RT::ACE that this sort of object can get acls granted
+$RT::ACE::OBJECT_TYPES{'RT::Group'} = 1;
+
+
+#
+
+# TODO: This should be refactored out into an RT::ACLedObject or something
+# stuff the rights into a hash of rights that can exist.
+
+foreach my $right ( keys %{$RIGHTS} ) {
+    $RT::ACE::LOWERCASERIGHTNAMES{ lc $right } = $right;
+}
+
+
+=head2 AvailableRights
+
+Returns a hash of available rights for this object. The keys are the right names and the values are a description of what the rights do
+
+=cut
+
+sub AvailableRights {
+    my $self = shift;
+    return($RIGHTS);
+}
+
+
+# {{{ sub SelfDescription
+
+=head2 SelfDescription
+
+Returns a user-readable description of what this group is for and what it's named.
+
+=cut
+
+sub SelfDescription {
+       my $self = shift;
+       if ($self->Domain eq 'ACLEquivalence') {
+               my $user = RT::Principal->new($self->CurrentUser);
+               $user->Load($self->Instance);
+               return $self->loc("user [_1]",$user->Object->Name);
+       }
+       elsif ($self->Domain eq 'UserDefined') {
+               return $self->loc("group '[_1]'",$self->Name);
+       }
+       elsif ($self->Domain eq 'Personal') {
+               my $user = RT::User->new($self->CurrentUser);
+               $user->Load($self->Instance);
+               return $self->loc("personal group '[_1]' for user '[_2]'",$self->Name, $user->Name);
+       }
+       elsif ($self->Domain eq 'RT::System-Role') {
+               return $self->loc("system [_1]",$self->Type);
+       }
+       elsif ($self->Domain eq 'RT::Queue-Role') {
+               my $queue = RT::Queue->new($self->CurrentUser);
+               $queue->Load($self->Instance);
+               return $self->loc("queue [_1] [_2]",$queue->Name, $self->Type);
+       }
+       elsif ($self->Domain eq 'RT::Ticket-Role') {
+               return $self->loc("ticket #[_1] [_2]",$self->Instance, $self->Type);
+       }
+       elsif ($self->Domain eq 'SystemInternal') {
+               return $self->loc("system group '[_1]'",$self->Type);
+       }
+       else {
+               return $self->loc("undescribed group [_1]",$self->Id);
+       }
+}
+
+# }}}
+
+# {{{ sub Load 
+
+=head2 Load ID
+
+Load a group object from the database. Takes a single argument.
+If the argument is numerical, load by the column 'id'. Otherwise, 
+complain and return.
+
+=cut
+
+sub Load {
+    my $self       = shift;
+    my $identifier = shift || return undef;
+
+    #if it's an int, load by id. otherwise, load by name.
+    if ( $identifier !~ /\D/ ) {
+        $self->SUPER::LoadById($identifier);
+    }
+    else {
+        $RT::Logger->crit("Group -> Load called with a bogus argument");
+        return undef;
+    }
+}
+
+# }}}
+
+# {{{ sub LoadUserDefinedGroup 
+
+=head2 LoadUserDefinedGroup NAME
+
+Loads a system group from the database. The only argument is
+the group's name.
+
+
+=cut
+
+sub LoadUserDefinedGroup {
+    my $self       = shift;
+    my $identifier = shift;
+
+        $self->LoadByCols( "Domain" => 'UserDefined',
+                           "Name" => $identifier );
+}
+
+# }}}
+
+# {{{ sub LoadACLEquivalenceGroup 
+
+=head2 LoadACLEquivalenceGroup  PRINCIPAL
+
+Loads a user's acl equivalence group. Takes a principal object.
+ACL equivalnce groups are used to simplify the acl system. Each user
+has one group that only he is a member of. Rights granted to the user
+are actually granted to that group. This greatly simplifies ACL checks.
+While this results in a somewhat more complex setup when creating users
+and granting ACLs, it _greatly_ simplifies acl checks.
+
+
+
+=cut
+
+sub LoadACLEquivalenceGroup {
+    my $self       = shift;
+    my $princ = shift;
+
+        $self->LoadByCols( "Domain" => 'ACLEquivalence',
+                            "Type" => 'UserEquiv',
+                           "Instance" => $princ->Id);
+}
+
+# }}}
+
+# {{{ sub LoadPersonalGroup 
+
+=head2 LoadPersonalGroup {Name => NAME, User => USERID}
+
+Loads a personal group from the database. 
+
+=cut
+
+sub LoadPersonalGroup {
+    my $self       = shift;
+    my %args =  (   Name => undef,
+                    User => undef,
+                    @_);
+
+        $self->LoadByCols( "Domain" => 'Personal',
+                           "Instance" => $args{'User'},
+                           "Type" => '',
+                           "Name" => $args{'Name'} );
+}
+
+# }}}
+
+# {{{ sub LoadSystemInternalGroup 
+
+=head2 LoadSystemInternalGroup NAME
+
+Loads a Pseudo group from the database. The only argument is
+the group's name.
+
+
+=cut
+
+sub LoadSystemInternalGroup {
+    my $self       = shift;
+    my $identifier = shift;
+
+        $self->LoadByCols( "Domain" => 'SystemInternal',
+                           "Instance" => '',
+                           "Name" => '',
+                           "Type" => $identifier );
+}
+
+# }}}
+
+# {{{ sub LoadTicketRoleGroup 
+
+=head2 LoadTicketRoleGroup  { Ticket => TICKET_ID, Type => TYPE }
+
+Loads a ticket group from the database. 
+
+Takes a param hash with 2 parameters:
+
+    Ticket is the TicketId we're curious about
+    Type is the type of Group we're trying to load: 
+        Requestor, Cc, AdminCc, Owner
+
+=cut
+
+sub LoadTicketRoleGroup {
+    my $self       = shift;
+    my %args = (Ticket => undef,
+                Type => undef,
+                @_);
+        $self->LoadByCols( Domain => 'RT::Ticket-Role',
+                           Instance =>$args{'Ticket'}, 
+                           Type => $args{'Type'}
+                           );
+}
+
+# }}}
+
+# {{{ sub LoadQueueRoleGroup 
+
+=head2 LoadQueueRoleGroup  { Queue => Queue_ID, Type => TYPE }
+
+Loads a Queue group from the database. 
+
+Takes a param hash with 2 parameters:
+
+    Queue is the QueueId we're curious about
+    Type is the type of Group we're trying to load: 
+        Requestor, Cc, AdminCc, Owner
+
+=cut
+
+sub LoadQueueRoleGroup {
+    my $self       = shift;
+    my %args = (Queue => undef,
+                Type => undef,
+                @_);
+        $self->LoadByCols( Domain => 'RT::Queue-Role',
+                           Instance =>$args{'Queue'}, 
+                           Type => $args{'Type'}
+                           );
+}
+
+# }}}
+
+# {{{ sub LoadSystemRoleGroup 
+
+=head2 LoadSystemRoleGroup  Type
+
+Loads a System group from the database. 
+
+Takes a single param: Type
+
+    Type is the type of Group we're trying to load: 
+        Requestor, Cc, AdminCc, Owner
+
+=cut
+
+sub LoadSystemRoleGroup {
+    my $self       = shift;
+    my $type = shift;
+        $self->LoadByCols( Domain => 'RT::System-Role',
+                           Type => $type
+                           );
+}
+
+# }}}
+
+# {{{ sub Create
+=head2 Create
+
+You need to specify what sort of group you're creating by calling one of the other
+Create_____ routines.
+
+=cut
+
+sub Create {
+    my $self = shift;
+    $RT::Logger->crit("Someone called RT::Group->Create. this method does not exist. someone's being evil");
+    return(0,$self->loc('Permission Denied'));
+}
+
+# }}}
+
+# {{{ sub _Create
+
+=head2 _Create
+
+Takes a paramhash with named arguments: Name, Description.
+
+Returns a tuple of (Id, Message).  If id is 0, the create failed
+
+=cut
+
+sub _Create {
+    my $self = shift;
+    my %args = (
+        Name        => undef,
+        Description => undef,
+        Domain      => undef,
+        Type        => undef,
+        Instance    => undef,
+        InsideTransaction => undef,
+        @_
+    );
+
+    $RT::Handle->BeginTransaction() unless ($args{'InsideTransaction'});
+    # Groups deal with principal ids, rather than user ids.
+    # When creating this group, set up a principal Id for it.
+    my $principal    = RT::Principal->new( $self->CurrentUser );
+    my $principal_id = $principal->Create(
+        PrincipalType => 'Group',
+        ObjectId      => '0'
+    );
+    $principal->__Set(Field => 'ObjectId', Value => $principal_id);
+
+
+    $self->SUPER::Create(
+        id          => $principal_id,
+        Name        => $args{'Name'},
+        Description => $args{'Description'},
+        Type        => $args{'Type'},
+        Domain      => $args{'Domain'},
+        Instance    => $args{'Instance'}
+    );
+    my $id = $self->Id;
+    unless ($id) {
+        return ( 0, $self->loc('Could not create group') );
+    }
+
+    # If we couldn't create a principal Id, get the fuck out.
+    unless ($principal_id) {
+        $RT::Handle->Rollback() unless ($args{'InsideTransaction'});
+        $self->crit( "Couldn't create a Principal on new user create. Strange things are afoot at the circle K" );
+        return ( 0, $self->loc('Could not create group') );
+    }
+
+    # Now we make the group a member of itself as a cached group member
+    # this needs to exist so that group ACL checks don't fall over.
+    # you're checking CachedGroupMembers to see if the principal in question
+    # is a member of the principal the rights have been granted too
+
+    # in the ordinary case, this would fail badly because it would recurse and add all the members of this group as 
+    # cached members. thankfully, we're creating the group now...so it has no members.
+    my $cgm = RT::CachedGroupMember->new($self->CurrentUser);
+    $cgm->Create(Group =>$self->PrincipalObj, Member => $self->PrincipalObj, ImmediateParent => $self->PrincipalObj);
+
+
+
+    $RT::Handle->Commit() unless ($args{'InsideTransaction'});
+    return ( $id, $self->loc("Group created") );
+}
+
+# }}}
+
+# {{{ CreateUserDefinedGroup
+
+=head2 CreateUserDefinedGroup { Name => "name", Description => "Description"}
+
+A helper subroutine which creates a system group 
+
+Returns a tuple of (Id, Message).  If id is 0, the create failed
+
+=cut
+
+sub CreateUserDefinedGroup {
+    my $self = shift;
+
+    unless ( $self->CurrentUserHasRight('AdminGroup') ) {
+        $RT::Logger->warning( $self->CurrentUser->Name
+              . " Tried to create a group without permission." );
+        return ( 0, $self->loc('Permission Denied') );
+    }
+
+    return($self->_Create( Domain => 'UserDefined', Type => '', Instance => '', @_));
+}
+
+# }}}
+
+# {{{ _CreateACLEquivalenceGroup
+
+=head2 _CreateACLEquivalenceGroup { Principal }
+
+A helper subroutine which creates a group containing only 
+an individual user. This gets used by the ACL system to check rights.
+Yes, it denormalizes the data, but that's ok, as we totally win on performance.
+
+Returns a tuple of (Id, Message).  If id is 0, the create failed
+
+=cut
+
+sub _CreateACLEquivalenceGroup { 
+    my $self = shift;
+    my $princ = shift;
+      my $id = $self->_Create( Domain => 'ACLEquivalence', 
+                           Type => 'UserEquiv',
+                           Name => 'User '. $princ->Object->Id,
+                           Description => 'ACL equiv. for user '.$princ->Object->Id,
+                           Instance => $princ->Id,
+                           InsideTransaction => 1);
+      unless ($id) {
+        $RT::Logger->crit("Couldn't create ACL equivalence group");
+        return undef;
+      }
+    
+       # We use stashuser so we don't get transactions inside transactions
+       # and so we bypass all sorts of cruft we don't need
+       my $aclstash = RT::GroupMember->new($self->CurrentUser);
+       my ($stash_id, $add_msg) = $aclstash->_StashUser(Group => $self->PrincipalObj,
+                                             Member => $princ);
+
+      unless ($stash_id) {
+        $RT::Logger->crit("Couldn't add the user to his own acl equivalence group:".$add_msg);
+        # We call super delete so we don't get acl checked.
+        $self->SUPER::Delete();
+        return(undef);
+      }
+    return ($id);
+}
+
+# }}}
+
+# {{{ CreatePersonalGroup
+
+=head2 CreatePersonalGroup { PrincipalId => PRINCIPAL_ID, Name => "name", Description => "Description"}
+
+A helper subroutine which creates a personal group. Generally,
+personal groups are used for ACL delegation and adding to ticket roles
+PrincipalId defaults to the current user's principal id.
+
+Returns a tuple of (Id, Message).  If id is 0, the create failed
+
+=cut
+
+sub CreatePersonalGroup {
+    my $self = shift;
+    my %args = (
+        Name        => undef,
+        Description => undef,
+        PrincipalId => $self->CurrentUser->PrincipalId,
+        @_
+    );
+
+    if ( $self->CurrentUser->PrincipalId == $args{'PrincipalId'} ) {
+
+        unless ( $self->CurrentUserHasRight('AdminOwnPersonalGroups') ) {
+            $RT::Logger->warning( $self->CurrentUser->Name
+                  . " Tried to create a group without permission." );
+            return ( 0, $self->loc('Permission Denied') );
+        }
+
+    }
+    else {
+        unless ( $self->CurrentUserHasRight('AdminAllPersonalGroups') ) {
+            $RT::Logger->warning( $self->CurrentUser->Name
+                  . " Tried to create a group without permission." );
+            return ( 0, $self->loc('Permission Denied') );
+        }
+
+    }
+
+    return (
+        $self->_Create(
+            Domain      => 'Personal',
+            Type        => '',
+            Instance    => $args{'PrincipalId'},
+            Name        => $args{'Name'},
+            Description => $args{'Description'}
+        )
+    );
+}
+
+# }}}
+
+# {{{ CreateRoleGroup 
+
+=head2 CreateRoleGroup { Domain => DOMAIN, Type =>  TYPE, Instance => ID }
+
+A helper subroutine which creates a  ticket group. (What RT 2.0 called Ticket watchers)
+Type is one of ( "Requestor" || "Cc" || "AdminCc" || "Owner") 
+Domain is one of (RT::Ticket-Role || RT::Queue-Role || RT::System-Role)
+Instance is the id of the ticket or queue in question
+
+This routine expects to be called from {Ticket||Queue}->CreateTicketGroups _inside of a transaction_
+
+Returns a tuple of (Id, Message).  If id is 0, the create failed
+
+=cut
+
+sub CreateRoleGroup {
+    my $self = shift;
+    my %args = ( Instance => undef,
+                 Type     => undef,
+                 Domain   => undef,
+                 @_ );
+    unless ( $args{'Type'} =~ /^(?:Cc|AdminCc|Requestor|Owner)$/ ) {
+        return ( 0, $self->loc("Invalid Group Type") );
+    }
+
+
+    return ( $self->_Create( Domain            => $args{'Domain'},
+                             Instance          => $args{'Instance'},
+                             Type              => $args{'Type'},
+                             InsideTransaction => 1 ) );
+}
+
+# }}}
+
+# {{{ sub Delete
+
+=head2 Delete
+
+Delete this object
+
+=cut
+
+sub Delete {
+    my $self = shift;
+
+    unless ( $self->CurrentUserHasRight('AdminGroup') ) {
+        return ( 0, 'Permission Denied' );
+    }
+
+    $RT::Logger->crit("Deleting groups violates referential integrity until we go through and fix this");
+    # TODO XXX 
+   
+    # Remove the principal object
+    # Remove this group from anything it's a member of.
+    # Remove all cached members of this group
+    # Remove any rights granted to this group
+    # remove any rights delegated by way of this group
+
+    return ( $self->SUPER::Delete(@_) );
+}
+
+# }}}
+
+=head2 SetDisabled BOOL
+
+If passed a positive value, this group will be disabled. No rights it commutes or grants will be honored.
+It will not appear in most group listings.
+
+This routine finds all the cached group members that are members of this group  (recursively) and disables them.
+=cut 
+
+ # }}}
+
+ sub SetDisabled {
+     my $self = shift;
+     my $val = shift;
+    if ($self->Domain eq 'Personal') {
+               if ($self->CurrentUser->PrincipalId == $self->Instance) {
+               unless ( $self->CurrentUserHasRight('AdminOwnPersonalGroups')) {
+                       return ( 0, $self->loc('Permission Denied') );
+               }
+       } else {
+               unless ( $self->CurrentUserHasRight('AdminAllPersonalGroups') ) {
+                        return ( 0, $self->loc('Permission Denied') );
+               }
+       }
+       }
+       else {
+        unless ( $self->CurrentUserHasRight('AdminGroup') ) {
+                 return (0, $self->loc('Permission Denied'));
+    }
+    }
+    $RT::Handle->BeginTransaction();
+    $self->PrincipalObj->SetDisabled($val);
+
+
+
+
+    # Find all occurrences of this member as a member of this group
+    # in the cache and nuke them, recursively.
+
+    # The following code will delete all Cached Group members
+    # where this member's group is _not_ the primary group 
+    # (Ie if we're deleting C as a member of B, and B happens to be 
+    # a member of A, will delete C as a member of A without touching
+    # C as a member of B
+
+    my $cached_submembers = RT::CachedGroupMembers->new( $self->CurrentUser );
+
+    $cached_submembers->Limit( FIELD    => 'ImmediateParentId', OPERATOR => '=', VALUE    => $self->Id);
+
+    #Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space. 
+    # TODO what about the groups key cache?
+    RT::Principal->_InvalidateACLCache();
+
+
+
+    while ( my $item = $cached_submembers->Next() ) {
+        my $del_err = $item->SetDisabled($val);
+        unless ($del_err) {
+            $RT::Handle->Rollback();
+            $RT::Logger->warning("Couldn't disable cached group submember ".$item->Id);
+            return (undef);
+        }
+    }
+
+    $RT::Handle->Commit();
+    return (1, $self->loc("Succeeded"));
+
+}
+
+# }}}
+
+
+
+sub Disabled {
+    my $self = shift;
+    $self->PrincipalObj->Disabled(@_);
+}
+
+
+# {{{ DeepMembersObj
+
+=head2 DeepMembersObj
+
+Returns an RT::CachedGroupMembers object of this group's members.
+
+=cut
+
+sub DeepMembersObj {
+    my $self = shift;
+    my $members_obj = RT::CachedGroupMembers->new( $self->CurrentUser );
+
+    #If we don't have rights, don't include any results
+    # TODO XXX  WHY IS THERE NO ACL CHECK HERE?
+    $members_obj->LimitToMembersOfGroup( $self->PrincipalId );
+
+    return ( $members_obj );
+
+}
+
+# }}}
+
+# {{{ UserMembersObj
+
+=head2 UserMembersObj
+
+Returns an RT::Users object of this group's members, including
+all members of subgroups
+
+=cut
+
+sub UserMembersObj {
+    my $self = shift;
+
+    my $users = RT::Users->new($self->CurrentUser);
+
+    #If we don't have rights, don't include any results
+    # TODO XXX  WHY IS THERE NO ACL CHECK HERE?
+
+    my $principals = $users->NewAlias('Principals');
+
+    $users->Join(ALIAS1 => 'main', FIELD1 => 'id',
+                 ALIAS2 => $principals, FIELD2 => 'ObjectId');
+    $users->Limit(ALIAS =>$principals,
+                  FIELD => 'PrincipalType', OPERATOR => '=', VALUE => 'User');
+
+    my $cached_members = $users->NewAlias('CachedGroupMembers');
+    $users->Join(ALIAS1 => $cached_members, FIELD1 => 'MemberId',
+                 ALIAS2 => $principals, FIELD2 => 'id');
+    $users->Limit(ALIAS => $cached_members, 
+                  FIELD => 'GroupId',
+                  OPERATOR => '=',
+                  VALUE => $self->PrincipalId);
+
+
+    return ( $users);
+
+}
+
+# }}}
+
+# {{{ MembersObj
+
+=head2 MembersObj
+
+Returns an RT::CachedGroupMembers object of this group's members.
+
+=cut
+
+sub MembersObj {
+    my $self = shift;
+    my $members_obj = RT::GroupMembers->new( $self->CurrentUser );
+
+    #If we don't have rights, don't include any results
+    # TODO XXX  WHY IS THERE NO ACL CHECK HERE?
+    $members_obj->LimitToMembersOfGroup( $self->PrincipalId );
+
+    return ( $members_obj );
+
+}
+
+# }}}
+
+# {{{ MemberEmailAddresses
+
+=head2 MemberEmailAddresses
+
+Returns an array of the email addresses of all of this group's members
+
+
+=cut
+
+sub MemberEmailAddresses {
+    my $self = shift;
+
+    my %addresses;
+    my $members = $self->UserMembersObj();
+    while (my $member = $members->Next) {
+        $addresses{$member->EmailAddress} = 1;
+    }
+    return(sort keys %addresses);
+}
+
+# }}}
+
+# {{{ MemberEmailAddressesAsString
+
+=head2 MemberEmailAddressesAsString
+
+Returns a comma delimited string of the email addresses of all users 
+who are members of this group.
+
+=cut
+
+
+sub MemberEmailAddressesAsString {
+    my $self = shift;
+    return (join(', ', $self->MemberEmailAddresses));
+}
+
+# }}}
+
+# {{{ AddMember
+
+=head2 AddMember PRINCIPAL_ID
+
+AddMember adds a principal to this group.  It takes a single principal id.
+Returns a two value array. the first value is true on successful 
+addition or 0 on failure.  The second value is a textual status msg.
+
+=cut
+
+sub AddMember {
+    my $self       = shift;
+    my $new_member = shift;
+
+
+
+    if ($self->Domain eq 'Personal') {
+               if ($self->CurrentUser->PrincipalId == $self->Instance) {
+               unless ( $self->CurrentUserHasRight('AdminOwnPersonalGroups')) {
+                       return ( 0, $self->loc('Permission Denied') );
+               }
+       } else {
+               unless ( $self->CurrentUserHasRight('AdminAllPersonalGroups') ) {
+                        return ( 0, $self->loc('Permission Denied') );
+               }
+       }
+       }
+       
+       else {  
+    # We should only allow membership changes if the user has the right 
+    # to modify group membership or the user is the principal in question
+    # and the user has the right to modify his own membership
+    unless ( ($new_member == $self->CurrentUser->PrincipalId &&
+             $self->CurrentUserHasRight('ModifyOwnMembership') ) ||
+             $self->CurrentUserHasRight('AdminGroupMembership') ) {
+        #User has no permission to be doing this
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+       } 
+    $self->_AddMember(PrincipalId => $new_member);
+}
+
+# A helper subroutine for AddMember that bypasses the ACL checks
+# this should _ONLY_ ever be called from Ticket/Queue AddWatcher
+# when we want to deal with groups according to queue rights
+# In the dim future, this will all get factored out and life
+# will get better      
+
+# takes a paramhash of { PrincipalId => undef, InsideTransaction }
+
+sub _AddMember {
+    my $self = shift;
+    my %args = ( PrincipalId => undef,
+                 InsideTransaction => undef,
+                 @_);
+    my $new_member = $args{'PrincipalId'};
+
+    unless ($self->Id) {
+        $RT::Logger->crit("Attempting to add a member to a group which wasn't loaded. 'oops'");
+        return(0, $self->loc("Group not found"));
+    }
+
+    unless ($new_member =~ /^\d+$/) {
+        $RT::Logger->crit("_AddMember called with a parameter that's not an integer.");
+    }
+
+
+    my $new_member_obj = RT::Principal->new( $self->CurrentUser );
+    $new_member_obj->Load($new_member);
+
+
+    unless ( $new_member_obj->Id ) {
+        $RT::Logger->debug("Couldn't find that principal");
+        return ( 0, $self->loc("Couldn't find that principal") );
+    }
+
+    if ( $self->HasMember( $new_member_obj ) ) {
+
+        #User is already a member of this group. no need to add it
+        return ( 0, $self->loc("Group already has member") );
+    }
+    if ( $new_member_obj->IsGroup &&
+         $new_member_obj->Object->HasMemberRecursively($self->PrincipalObj) ) {
+
+        #This group can't be made to be a member of itself
+        return ( 0, $self->loc("Groups can't be members of their members"));
+    }
+
+
+    my $member_object = RT::GroupMember->new( $self->CurrentUser );
+    my $id = $member_object->Create(
+        Member => $new_member_obj,
+        Group => $self->PrincipalObj,
+        InsideTransaction => $args{'InsideTransaction'}
+    );
+    if ($id) {
+        return ( 1, $self->loc("Member added") );
+    }
+    else {
+        return(0, $self->loc("Couldn't add member to group"));
+    }
+}
+# }}}
+
+# {{{ HasMember
+
+=head2 HasMember RT::Principal
+
+Takes an RT::Principal object returns a GroupMember Id if that user is a 
+member of this group.
+Returns undef if the user isn't a member of the group or if the current
+user doesn't have permission to find out. Arguably, it should differentiate
+between ACL failure and non membership.
+
+=cut
+
+sub HasMember {
+    my $self    = shift;
+    my $principal = shift;
+
+
+    unless (UNIVERSAL::isa($principal,'RT::Principal')) {
+        $RT::Logger->crit("Group::HasMember was called with an argument that".
+                          "isn't an RT::Principal. It's $principal");
+        return(undef);
+    }
+
+    my $member_obj = RT::GroupMember->new( $self->CurrentUser );
+    $member_obj->LoadByCols( MemberId => $principal->id, 
+                             GroupId => $self->PrincipalId );
+
+    #If we have a member object
+    if ( defined $member_obj->id ) {
+        return ( $member_obj->id );
+    }
+
+    #If Load returns no objects, we have an undef id. 
+    else {
+        #$RT::Logger->debug($self." does not contain principal ".$principal->id);
+        return (undef);
+    }
+}
+
+# }}}
+
+# {{{ HasMemberRecursively
+
+=head2 HasMemberRecursively RT::Principal
+
+Takes an RT::Principal object and returns true if that user is a member of 
+this group.
+Returns undef if the user isn't a member of the group or if the current
+user doesn't have permission to find out. Arguably, it should differentiate
+between ACL failure and non membership.
+
+=cut
+
+sub HasMemberRecursively {
+    my $self    = shift;
+    my $principal = shift;
+
+    unless (UNIVERSAL::isa($principal,'RT::Principal')) {
+        $RT::Logger->crit("Group::HasMemberRecursively was called with an argument that".
+                          "isn't an RT::Principal. It's $principal");
+        return(undef);
+    }
+    my $member_obj = RT::CachedGroupMember->new( $self->CurrentUser );
+    $member_obj->LoadByCols( MemberId => $principal->Id,
+                             GroupId => $self->PrincipalId ,
+                             Disabled => 0
+                             );
+
+    #If we have a member object
+    if ( defined $member_obj->id ) {
+        return ( 1);
+    }
+
+    #If Load returns no objects, we have an undef id. 
+    else {
+        return (undef);
+    }
+}
+
+# }}}
+
+# {{{ DeleteMember
+
+=head2 DeleteMember PRINCIPAL_ID
+
+Takes the principal id of a current user or group.
+If the current user has apropriate rights,
+removes that GroupMember from this group.
+Returns a two value array. the first value is true on successful 
+addition or 0 on failure.  The second value is a textual status msg.
+
+=cut
+
+sub DeleteMember {
+    my $self   = shift;
+    my $member_id = shift;
+
+
+    # We should only allow membership changes if the user has the right 
+    # to modify group membership or the user is the principal in question
+    # and the user has the right to modify his own membership
+
+    if ($self->Domain eq 'Personal') {
+               if ($self->CurrentUser->PrincipalId == $self->Instance) {
+               unless ( $self->CurrentUserHasRight('AdminOwnPersonalGroups')) {
+                       return ( 0, $self->loc('Permission Denied') );
+               }
+       } else {
+               unless ( $self->CurrentUserHasRight('AdminAllPersonalGroups') ) {
+                        return ( 0, $self->loc('Permission Denied') );
+               }
+       }
+       }
+       else {
+    unless ( (($member_id == $self->CurrentUser->PrincipalId) &&
+             $self->CurrentUserHasRight('ModifyOwnMembership') ) ||
+             $self->CurrentUserHasRight('AdminGroupMembership') ) {
+        #User has no permission to be doing this
+        return ( 0, $self->loc("Permission Denied") );
+    }
+       }
+    $self->_DeleteMember($member_id);
+}
+
+# A helper subroutine for DeleteMember that bypasses the ACL checks
+# this should _ONLY_ ever be called from Ticket/Queue  DeleteWatcher
+# when we want to deal with groups according to queue rights
+# In the dim future, this will all get factored out and life
+# will get better      
+
+sub _DeleteMember {
+    my $self = shift;
+    my $member_id = shift;
+
+    my $member_obj =  RT::GroupMember->new( $self->CurrentUser );
+    
+    $member_obj->LoadByCols( MemberId  => $member_id,
+                             GroupId => $self->PrincipalId);
+
+
+    #If we couldn't load it, return undef.
+    unless ( $member_obj->Id() ) {
+        $RT::Logger->debug("Group has no member with that id");
+        return ( 0,$self->loc( "Group has no such member" ));
+    }
+
+    #Now that we've checked ACLs and sanity, delete the groupmember
+    my $val = $member_obj->Delete();
+
+    if ($val) {
+        return ( $val, $self->loc("Member deleted") );
+    }
+    else {
+        $RT::Logger->debug("Failed to delete group ".$self->Id." member ". $member_id);
+        return ( 0, $self->loc("Member not deleted" ));
+    }
+}
+
+# }}}
+
+# {{{ ACL Related routines
+
+# {{{ sub _Set
+sub _Set {
+    my $self = shift;
+
+       if ($self->Domain eq 'Personal') {
+               if ($self->CurrentUser->PrincipalId == $self->Instance) {
+               unless ( $self->CurrentUserHasRight('AdminOwnPersonalGroups')) {
+                       return ( 0, $self->loc('Permission Denied') );
+               }
+       } else {
+               unless ( $self->CurrentUserHasRight('AdminAllPersonalGroups') ) {
+                        return ( 0, $self->loc('Permission Denied') );
+               }
+       }
+       }
+       else {
+       unless ( $self->CurrentUserHasRight('AdminGroup') ) {
+               return ( 0, $self->loc('Permission Denied') );
+       }
+       }
+    return ( $self->SUPER::_Set(@_) );
+}
+
+# }}}
+
+
+
+
+=item CurrentUserHasRight RIGHTNAME
+
+Returns true if the current user has the specified right for this group.
+
+
+    TODO: we don't deal with membership visibility yet
+
+=cut
+
+
+sub CurrentUserHasRight {
+    my $self = shift;
+    my $right = shift;
+
+
+
+    if ($self->Id && 
+               $self->CurrentUser->HasRight( Object => $self,
+                                                                                  Right => $right )) {
+        return(1);
+   }
+    elsif ( $self->CurrentUser->HasRight(Object => $RT::System, Right =>  $right )) {
+               return (1);
+    } else {
+        return(undef);
+    }
+
+}
+
+# }}}
+
+
+
+
+# {{{ Principal related routines
+
+=head2 PrincipalObj
+
+Returns the principal object for this user. returns an empty RT::Principal
+if there's no principal object matching this user. 
+The response is cached. PrincipalObj should never ever change.
+
+=begin testing
+
+ok(my $u = RT::Group->new($RT::SystemUser));
+ok($u->Load(4), "Loaded the first user");
+ok($u->PrincipalObj->ObjectId == 4, "user 4 is the fourth principal");
+ok($u->PrincipalObj->PrincipalType eq 'Group' , "Principal 4 is a group");
+
+=end testing
+
+=cut
+
+
+sub PrincipalObj {
+    my $self = shift;
+    unless ($self->{'PrincipalObj'} &&
+            ($self->{'PrincipalObj'}->ObjectId == $self->Id) &&
+            ($self->{'PrincipalObj'}->PrincipalType eq 'Group')) {
+
+            $self->{'PrincipalObj'} = RT::Principal->new($self->CurrentUser);
+            $self->{'PrincipalObj'}->LoadByCols('ObjectId' => $self->Id,
+                                                'PrincipalType' => 'Group') ;
+            }
+    return($self->{'PrincipalObj'});
+}
+
+
+=head2 PrincipalId  
+
+Returns this user's PrincipalId
+
+=cut
+
+sub PrincipalId {
+    my $self = shift;
+    return $self->Id;
+}
+
+# }}}
+1;
+
index f44f1fd..29f12a5 100755 (executable)
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Groups.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-=head1 NAME
 
-  RT::Groups - a collection of RT::Group objects
+=head1 NAME
 
+  RT::Groups -- Class Description
 =head1 SYNOPSIS
 
-  use RT::Groups;
-  my $groups = $RT::Groups->new($CurrentUser);
-  $groups->LimitToReal();
-  while (my $group = $groups->Next()) {
-     print $group->Id ." is a group id\n";
-  }
+  use RT::Groups
 
 =head1 DESCRIPTION
 
 
 =head1 METHODS
 
-
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::Groups);
-
-=end testing
-
 =cut
 
 package RT::Groups;
-use RT::EasySearch;
-use RT::Groups;
 
-@ISA= qw(RT::EasySearch);
+use RT::SearchBuilder;
+use RT::Group;
 
-# {{{ sub _Init
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
 
-sub _Init { 
-  my $self = shift;
-  $self->{'table'} = "Groups";
-  $self->{'primary_key'} = "id";
 
-  $self->OrderBy( ALIAS => 'main',
-                 FIELD => 'Name',
-                 ORDER => 'ASC');
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'Groups';
+    $self->{'primary_key'} = 'id';
 
 
-  return ( $self->SUPER::_Init(@_));
+    return ( $self->SUPER::_Init(@_) );
 }
-# }}}
 
-# {{{ LimitToReal
 
-=head2 LimitToReal
+=item NewItem
 
-Make this groups object return only "real" groups, which can be
-granted rights and have members assigned to them
+Returns an empty new RT::Group item
 
 =cut
 
-sub LimitToReal {
+sub NewItem {
     my $self = shift;
+    return(RT::Group->new($self->CurrentUser));
+}
 
-    return ($self->Limit( FIELD => 'Pseudo',
-                         VALUE => '0',
-                         OPERATOR => '='));
+        eval "require RT::Groups_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Groups_Overlay.pm}) {
+            die $@;
+        };
 
-}
-# }}}
+        eval "require RT::Groups_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Groups_Vendor.pm}) {
+            die $@;
+        };
 
-# {{{ sub LimitToPseudo
+        eval "require RT::Groups_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Groups_Local.pm}) {
+            die $@;
+        };
 
-=head2 LimitToPseudo
 
-Make this groups object return only "pseudo" groups, which can be
-granted rights but whose membership lists are determined dynamically.
 
-=cut
-  
-  sub LimitToPseudo {
-    my $self = shift;
 
-    return ($self->Limit( FIELD => 'Pseudo',
-                         VALUE => '1',
-                         OPERATOR => '='));
+=head1 SEE ALSO
 
-}
-# }}}
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
 
-# {{{ sub NewItem 
-sub NewItem  {
-  my $self = shift;
-  return (RT::Group->new($self->CurrentUser));
-}
-# }}}
+These overlay files can contain new subs or subs to replace existing subs in this module.
 
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
 
-1;
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
 
+RT::Groups_Overlay, RT::Groups_Vendor, RT::Groups_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/Groups_Overlay.pm b/rt/lib/RT/Groups_Overlay.pm
new file mode 100644 (file)
index 0000000..3d2c660
--- /dev/null
@@ -0,0 +1,298 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Groups - a collection of RT::Group objects
+
+=head1 SYNOPSIS
+
+  use RT::Groups;
+  my $groups = $RT::Groups->new($CurrentUser);
+  $groups->LimitToReal();
+  while (my $group = $groups->Next()) {
+     print $group->Id ." is a group id\n";
+  }
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::Groups);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+
+# {{{ sub _Init
+
+sub _Init { 
+  my $self = shift;
+  $self->{'table'} = "Groups";
+  $self->{'primary_key'} = "id";
+
+  $self->OrderBy( ALIAS => 'main',
+                 FIELD => 'Name',
+                 ORDER => 'ASC');
+
+
+  return ( $self->SUPER::_Init(@_));
+}
+# }}}
+
+# {{{ LimiToSystemInternalGroups
+
+=head2 LimitToSystemInternalGroups
+
+Return only SystemInternal Groups, such as "privileged" "unprivileged" and "everyone" 
+
+=cut
+
+
+sub LimitToSystemInternalGroups {
+    my $self = shift;
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'SystemInternal');
+    $self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => '');
+}
+
+
+# }}}
+
+# {{{ LimiToUserDefinedGroups
+
+=head2 LimitToUserDefined Groups
+
+Return only UserDefined Groups
+
+=cut
+
+
+sub LimitToUserDefinedGroups {
+    my $self = shift;
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined');
+    $self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => '');
+}
+
+
+# }}}
+
+# {{{ LimiToPersonalGroups
+
+=head2 LimitToPersonalGroupsFor PRINCIPAL_ID
+
+Return only Personal Groups for the user whose principal id 
+is PRINCIPAL_ID
+
+=cut
+
+
+sub LimitToPersonalGroupsFor {
+    my $self = shift;
+    my $princ = shift;
+
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'Personal');
+    $self->Limit(   FIELD => 'Instance',   
+                    OPERATOR => '=', 
+                    VALUE => $princ,
+                    ENTRY_AGGREGATOR => 'OR');
+}
+
+
+# }}}
+
+# {{{ LimitToRolesForQueue
+
+=item LimitToRolesForQueue QUEUE_ID
+
+Limits the set of groups found to role groups for queue QUEUE_ID
+
+=cut
+
+sub LimitToRolesForQueue {
+    my $self = shift;
+    my $queue = shift;
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'RT::Queue-Role');
+    $self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => $queue);
+}
+
+# }}}
+
+# {{{ LimitToRolesForTicket
+
+=item LimitToRolesForTicket Ticket_ID
+
+Limits the set of groups found to role groups for Ticket Ticket_ID
+
+=cut
+
+sub LimitToRolesForTicket {
+    my $self = shift;
+    my $Ticket = shift;
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'RT::Ticket-Role');
+    $self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => '$Ticket');
+}
+
+# }}}
+
+# {{{ LimitToRolesForSystem
+
+=item LimitToRolesForSystem System_ID
+
+Limits the set of groups found to role groups for System System_ID
+
+=cut
+
+sub LimitToRolesForSystem {
+    my $self = shift;
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'RT::System-Role');
+}
+
+# }}}
+
+=head2 WithMember {PrincipalId => PRINCIPAL_ID, Recursively => undef}
+
+Limits the set of groups returned to groups which have
+Principal PRINCIPAL_ID as a member
+   
+=begin testing
+
+my $u = RT::User->new($RT::SystemUser);
+$u->Create(Name => 'Membertests');
+my $g = RT::Group->new($RT::SystemUser);
+my ($id, $msg) = $g->CreateUserDefinedGroup(Name => 'Membertests');
+ok ($id,$msg);
+
+my ($aid, $amsg) =$g->AddMember($u->id);
+ok ($aid, $amsg);
+ok($g->HasMember($u->PrincipalObj),"G has member u");
+
+my $groups = RT::Groups->new($RT::SystemUser);
+$groups->LimitToUserDefinedGroups();
+$groups->WithMember(PrincipalId => $u->id);
+ok ($groups->Count == 1,"found the 1 group - " . $groups->Count);
+ok ($groups->First->Id == $g->Id, "it's the right one");
+
+
+
+
+=end testing
+
+
+=cut
+
+sub WithMember {
+    my $self = shift;
+    my %args = ( PrincipalId => undef,
+                 Recursively => undef,
+                 @_);
+    my $members;
+
+    if ($args{'Recursively'}) {
+        $members = $self->NewAlias('CachedGroupMembers');
+    } else {
+        $members = $self->NewAlias('GroupMembers');
+    }
+    $self->Join(ALIAS1 => 'main', FIELD1 => 'id',
+                ALIAS2 => $members, FIELD2 => 'GroupId');
+
+    $self->Limit(ALIAS => $members, FIELD => 'MemberId', OPERATOR => '=', VALUE => $args{'PrincipalId'});
+}
+
+
+sub WithRight {
+    my $self = shift;
+    my %args = ( Right                  => undef,
+                 Object =>              => undef,
+                 IncludeSystemRights    => undef,
+                 IncludeSuperusers      => undef,
+                 @_ );
+
+    my $groupprinc = $self->NewAlias('Principals');
+    my $acl        = $self->NewAlias('ACL');
+
+    # {{{ Find only rows where the right granted is the one we're looking up or _possibly_ superuser 
+    $self->Limit( ALIAS           => $acl,
+                  FIELD           => 'RightName',
+                  OPERATOR        => '=',
+                  VALUE           => $args{Right},
+                  ENTRYAGGREGATOR => 'OR' );
+
+    if ( $args{'IncludeSuperusers'} ) {
+        $self->Limit( ALIAS           => $acl,
+                      FIELD           => 'RightName',
+                      OPERATOR        => '=',
+                      VALUE           => 'SuperUser',
+                      ENTRYAGGREGATOR => 'OR' );
+    }
+    # }}}
+
+    my ($or_check_ticket_roles, $or_check_roles, $or_look_at_object);
+
+    if ( defined $args{'Object'} ) {
+        if ( ref($args{'Object'}) eq 'RT::Ticket' ) {
+            $or_check_ticket_roles =
+                " OR ( main.Domain = 'RT::Ticket-Role' AND main.Instance = " . $args{'Object'}->Id . ") ";
+
+            # If we're looking at ticket rights, we also want to look at the associated queue rights.
+            # this is a little bit hacky, but basically, now that we've done the ticket roles magic,
+            # we load the queue object and ask all the rest of our questions about the queue.
+            $args{'Object'}   = $args{'Object'}->QueueObj;
+        }
+        # TODO XXX This really wants some refactoring
+        if ( ref($args{'Object'}) eq 'RT::Queue' ) {
+            $or_check_roles =
+                " OR ( ( (main.Domain = 'RT::Queue-Role' AND main.Instance = " .
+                $args{'Object'}->Id . ") $or_check_ticket_roles ) " .
+                " AND main.Type = $acl.PrincipalType AND main.id = $groupprinc.id) ";
+        }
+
+        $or_look_at_object =
+            " OR ($acl.ObjectType = '" . ref($args{'Object'}) . "'" .
+            " AND $acl.ObjectId = " . $args{'Object'}->Id . ") ";
+    }
+
+    $self->_AddSubClause( "WhichObject", "($acl.ObjectType = 'RT::System' $or_look_at_object)" );
+
+    $self->_AddSubClause( "WhichGroup",
+        qq{
+          ( (    $acl.PrincipalId = $groupprinc.id
+             AND $acl.PrincipalType = 'Group'
+             AND (   main.Domain = 'SystemInternal'
+                  OR main.Domain = 'UserDefined'
+                  OR main.Domain = 'ACLEquivalence')
+             AND main.id = $groupprinc.id)
+           $or_check_roles)
+        }
+    );
+}
+
+1;
+
index 6b74f36..5cdb65e 100644 (file)
@@ -1,5 +1,26 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Handle.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 =head1 NAME
 
   RT::Handle - RT's database handle
@@ -22,14 +43,16 @@ ok(require RT::Handle);
 
 package RT::Handle;
 
-eval "use DBIx::SearchBuilder::Handle::$RT::DatabaseType;
+use strict;
+use vars qw/@ISA/;
 
+eval "use DBIx::SearchBuilder::Handle::$RT::DatabaseType;
 \@ISA= qw(DBIx::SearchBuilder::Handle::$RT::DatabaseType);";
-
 #TODO check for errors here.
 
 =head2 Connect
 
+Connects to RT's database handle.
 Takes nothing. Calls SUPER::Connect with the needed args
 
 =cut
@@ -38,16 +61,41 @@ sub Connect {
 my $self=shift;
 
 # Unless the database port is a positive integer, we really don't want to pass it.
-$RT::DatabasePort = undef unless (defined $RT::DatabasePort && $RT::DatabasePort =~ /^(\d+)$/);
 
-$self->SUPER::Connect(Host => $RT::DatabaseHost, 
-                        Database => $RT::DatabaseName, 
+$self->SUPER::Connect(
                         User => $RT::DatabaseUser,
                         Password => $RT::DatabasePassword,
+                       );
+   
+}
+
+=item BuildDSN
+
+Build the DSN for the RT database. doesn't take any parameters, draws all that
+from the config file.
+
+=cut
+
+
+sub BuildDSN {
+    my $self = shift;
+$RT::DatabasePort = undef unless (defined $RT::DatabasePort && $RT::DatabasePort =~ /^(\d+)$/);
+$RT::DatabaseHost = undef unless (defined $RT::DatabaseHost && $RT::DatabaseHost ne '');
+
+    $self->SUPER::BuildDSN(Host => $RT::DatabaseHost, 
+                        Database => $RT::DatabaseName, 
                         Port => $RT::DatabasePort,
                         Driver => $RT::DatabaseType,
                         RequireSSL => $RT::DatabaseRequireSSL,
+             DisconnectHandleOnDestroy => 1
                        );
    
+
 }
+
+eval "require RT::Handle_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Handle_Vendor.pm});
+eval "require RT::Handle_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Handle_Local.pm});
+
 1;
diff --git a/rt/lib/RT/I18N.pm b/rt/lib/RT/I18N.pm
new file mode 100644 (file)
index 0000000..c013c21
--- /dev/null
@@ -0,0 +1,430 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+RT::I18N - a base class for localization of RT
+
+=cut
+
+package RT::I18N;
+
+use strict;
+use Locale::Maketext 1.04;
+use Locale::Maketext::Lexicon 0.25;
+use base ('Locale::Maketext::Fuzzy');
+use vars qw( %Lexicon );
+
+#If we're running on 5.6, we desperately need Encode::compat. But if we're on 5.8, we don't really need it.
+BEGIN { if ($] < 5.007001) {
+require Encode::compat;
+} }
+use Encode;
+
+use MIME::Entity;
+use MIME::Head;
+
+# I decree that this project's first language is English.
+
+%Lexicon = (
+   'TEST_STRING' => 'Concrete Mixer',
+
+    '__Content-Type' => 'text/plain; charset=utf-8',
+
+  '_AUTO' => 1,
+  # That means that lookup failures can't happen -- if we get as far
+  #  as looking for something in this lexicon, and we don't find it,
+  #  then automagically set $Lexicon{$key} = $key, before possibly
+  #  compiling it.
+  
+  # The exception is keys that start with "_" -- they aren't auto-makeable.
+
+);
+# End of lexicon.
+
+=head2 Init
+
+Initializes the lexicons used for localization.
+
+=begin testing
+
+use_ok (RT::I18N);
+ok(RT::I18N->Init);
+
+=end testing
+
+=cut
+
+sub Init {
+    # Load language-specific functions
+    foreach my $language ( glob(substr(__FILE__, 0, -3) . "/*.pm")) {
+        if ($language =~ /^([-\w.\/\\~:]+)$/) {
+            require $1;
+        }
+        else {
+           warn("$language is tainted. not loading");
+        } 
+    }
+
+    my @lang = @RT::LexiconLanguages;
+    @lang = ('*') unless @lang;
+
+    # Acquire all .po files and iterate them into lexicons
+    Locale::Maketext::Lexicon->import({
+       _decode => 1, map {
+           $_  => [
+               Gettext => (substr(__FILE__, 0, -3) . "/$_.po"),
+               Gettext => "$RT::LocalLexiconPath/*/$_.po",
+           ],
+       } @lang
+    });
+
+    return 1;
+}
+
+=head2 encoding
+
+Returns the encoding of the current lexicon, as yanked out of __ContentType's "charset" field.
+If it can't find anything, it returns 'ISO-8859-1'
+
+=begin testing
+
+ok(my $chinese = RT::I18N->get_handle('zh_tw'));
+ok(UNIVERSAL::can($chinese, 'maketext'));
+ok($chinese->maketext('__Content-Type') =~ /utf-8/i, "Found the utf-8 charset for traditional chinese in the string ".$chinese->maketext('__Content-Type'));
+ok($chinese->encoding eq 'utf-8', "The encoding is 'utf-8' -".$chinese->encoding);
+
+ok(my $en = RT::I18N->get_handle('en'));
+ok(UNIVERSAL::can($en, 'maketext'));
+ok($en->encoding eq 'utf-8', "The encoding ".$en->encoding." is 'utf-8'");
+
+=end testing
+
+
+=cut
+
+
+sub encoding { 'utf-8' }
+
+# {{{ SetMIMEEntityToUTF8
+
+=head2 SetMIMEEntityToUTF8 $entity
+
+An utility method which will try to convert entity body into utf8.
+It's now a wrap-up of SetMIMEEntityToEncoding($entity, 'utf-8').
+
+=cut
+
+sub SetMIMEEntityToUTF8 {
+    RT::I18N::SetMIMEEntityToEncoding(shift, 'utf-8');
+}
+
+# }}}
+
+# {{{ SetMIMEEntityToEncoding
+
+=head2 SetMIMEEntityToEncoding $entity, $encoding
+
+An utility method which will try to convert entity body into specified
+charset encoding (encoded as octets, *not* unicode-strings).  It will
+iterate all the entities in $entity, and try to convert each one into
+specified charset if whose Content-Type is 'text/plain'.
+
+This method doesn't return anything meaningful.
+
+=cut
+
+sub SetMIMEEntityToEncoding {
+    my ( $entity, $enc, $preserve_words ) = ( shift, shift, shift );
+
+    #if ( $entity->is_multipart ) {
+    #$RT::Logger->crit("This entity is a multipart " . $entity->head->as_string);
+       SetMIMEEntityToEncoding( $_, $enc, $preserve_words ) foreach $entity->parts;
+    #}
+
+    my $charset = _FindOrGuessCharset($entity) or return;
+    # one and only normalization
+    $charset = 'utf-8' if $charset eq 'utf8';
+    $enc     = 'utf-8' if $enc     eq 'utf8';
+
+    SetMIMEHeadToEncoding($entity->head, $charset => $enc, $preserve_words);
+
+    my $head = $entity->head;
+
+    # convert at least MIME word encoded attachment filename
+    foreach my $attr (qw(content-type.name content-disposition.filename)) {
+       if ( my $name = $head->mime_attr($attr) and !$preserve_words ) {
+           $head->mime_attr( $attr => DecodeMIMEWordsToUTF8($name) );
+       }
+    }
+
+    # If this is a textual entity, we'd need to preserve its original encoding
+    $head->add( "X-RT-Original-Encoding" => $charset )
+       if $head->mime_attr('content-type.charset') or $head->mime_type =~ /^text/;
+
+
+    return unless ( $head->mime_type =~ qr{^(text/plain|message/rfc822)$}i  );
+    
+
+    my $body = $entity->bodyhandle;
+
+    if ( $enc ne $charset && $body) {
+       my @lines = $body->as_lines or return;
+
+       # {{{ Convert the body
+       eval {
+           $RT::Logger->debug("Converting '$charset' to '$enc' for ". $head->mime_type . " - ". $head->get('subject'));
+
+           # NOTE:: see the comments at the end of the sub.
+           Encode::_utf8_off( $lines[$_] ) foreach ( 0 .. $#lines );
+           Encode::from_to( $lines[$_], $charset => $enc ) for ( 0 .. $#lines );
+       };
+
+       if ($@) {
+           $RT::Logger->error( "Encoding error: " . $@ . " defaulting to ISO-8859-1 -> UTF-8" );
+           eval {
+               Encode::from_to( $lines[$_], 'iso-8859-1' => $enc ) foreach ( 0 .. $#lines );
+           };
+           if ($@) {
+               $RT::Logger->crit( "Totally failed to convert to utf-8: " . $@ . " I give up" );
+           }
+       }
+       # }}}
+
+        my $new_body = MIME::Body::InCore->new( \@lines );
+
+        # set up the new entity
+        $head->mime_attr( "content-type" => 'text/plain' )
+          unless ( $head->mime_attr("content-type") );
+        $head->mime_attr( "content-type.charset" => $enc );
+        $entity->bodyhandle($new_body);
+    }
+}
+
+# NOTES:  Why Encode::_utf8_off before Encode::from_to
+#
+# All the strings in RT are utf-8 now.  Quotes from Encode POD:
+#
+# [$length =] from_to($octets, FROM_ENC, TO_ENC [, CHECK])
+# ... The data in $octets must be encoded as octets and not as
+# characters in Perl's internal format. ...
+#
+# Not turning off the UTF-8 flag in the string will prevent the string
+# from conversion.
+
+# }}}
+
+# {{{ DecodeMIMEWordsToUTF8
+
+=head2 DecodeMIMEWordsToUTF8 $raw
+
+An utility method which mimics MIME::Words::decode_mimewords, but only
+limited functionality.  This function returns an utf-8 string.
+
+It returns the decoded string, or the original string if it's not
+encoded.  Since the subroutine converts specified string into utf-8
+charset, it should not alter a subject written in English.
+
+Why not use MIME::Words directly?  Because it fails in RT when I
+tried.  Maybe it's ok now.
+
+=cut
+
+sub DecodeMIMEWordsToUTF8 {
+    my $str = shift;
+    DecodeMIMEWordsToEncoding($str, 'utf-8');
+}
+
+sub DecodeMIMEWordsToEncoding {
+    my $str = shift;
+    my $enc = shift;
+
+   
+    @_ = $str =~ m/([^=]*)=\?([^?]+)\?([QqBb])\?([^?]+)\?=([^=]*)/g;
+
+    return ($str) unless (@_);
+
+    $str = "";
+    while (@_) {
+       my ($prefix, $charset, $encoding, $enc_str, $trailing) =
+           (shift, shift, shift, shift, shift);
+
+        $trailing =~ s/\s?\t?$//;               # Observed from Outlook Express
+
+       if ($encoding eq 'Q' or $encoding eq 'q') {
+           use MIME::QuotedPrint;
+           $enc_str =~ tr/_/ /;                # Observed from Outlook Express
+           $enc_str = decode_qp($enc_str);
+       } elsif ($encoding eq 'B' or $encoding eq 'b') {
+           use MIME::Base64;
+           $enc_str = decode_base64($enc_str);
+       } else {
+           $RT::Logger->warning("RT::I18N::DecodeMIMEWordsToCharset got a " .
+                             "strange encoding: $encoding.");
+       }
+
+       # now we have got a decoded subject, try to convert into the encoding
+       unless ($charset eq $enc) {
+           eval { Encode::from_to($enc_str, $charset,  $enc) };
+           if ($@) {
+               $charset = _GuessCharset( $enc_str );
+               Encode::from_to($enc_str, $charset, $enc);
+           }
+       }
+
+       $str .= $prefix . $enc_str . $trailing;
+    }
+
+    return ($str)
+}
+
+# }}}
+
+# {{{ _FindOrGuessCharset
+
+=head2 _FindOrGuessCharset MIME::Entity
+
+When handed a MIME::Entity will first attempt to read what charset the message is encoded in. Failing that, 
+will use Encode::Guess to try to figure it out
+
+=cut
+
+sub _FindOrGuessCharset {
+    my $entity = shift;
+    my $head = $entity->head;
+
+    if ($head->mime_attr("content-type.charset")) {
+       return $head->mime_attr("content-type.charset");
+    }
+
+    if ( $head->mime_type =~ m{^text/}) {
+       my $body = $entity->bodyhandle or return;
+       return _GuessCharset( $head->as_string . $body->as_string );
+    }
+    else {
+       # potentially binary data -- don't guess the body
+       return _GuessCharset( $head->as_string );
+    }
+}
+
+# }}}
+
+
+# {{{ _GuessCharset
+
+=head2 _GuessCharset STRING
+
+use Encode::Guess to try to figure it out the string's encoding.
+
+=cut
+
+sub _GuessCharset {
+    my $fallback = 'iso-8859-1';
+    my $charset;
+
+    if ( @RT::EmailInputEncodings and eval { require Encode::Guess; 1 } ) {
+       Encode::Guess->set_suspects(@RT::EmailInputEncodings);
+       my $decoder = Encode::Guess->guess( $_[0] );
+
+       if ( ref $decoder ) {
+           $charset = $decoder->name;
+           $RT::Logger->debug("Guessed encoding: $charset");
+           return $charset;
+       }
+       elsif ($decoder =~ /(\S+ or .+)/) {
+           my %matched = map { $_ => 1 } split(/ or /, $1);
+           return 'utf-8' if $matched{'utf8'}; # one and only normalization
+
+           foreach my $suspect (@RT::EmailInputEncodings) {
+               next unless $matched{$suspect};
+               $RT::Logger->debug("Encode::Guess ambiguous ($decoder); using $suspect");
+               $charset = $suspect;
+               last;
+           }
+       }
+       else {
+           $RT::Logger->warning("Encode::Guess failed: $decoder; fallback to $fallback");
+       }
+    }
+    else {
+       $RT::Logger->warning("Cannot Encode::Guess; fallback to $fallback");
+    }
+
+    return($charset || $fallback);
+}
+
+# }}}
+
+# {{{ SetMIMEHeadToEncoding
+
+=head2 SetMIMEHeadToEncoding HEAD OLD_CHARSET NEW_CHARSET
+
+Converts a MIME Head from one encoding to another. This totally violates the RFC.
+We should never need this. But, Surprise!, MUAs are badly broken and do this kind of stuff
+all the time
+
+
+=cut
+
+sub SetMIMEHeadToEncoding {
+    my ( $head, $charset, $enc, $preserve_words ) = ( shift, shift, shift, shift );
+
+    $charset = 'utf-8' if $charset eq 'utf8';
+    $enc     = 'utf-8' if $enc     eq 'utf8';
+
+    return if $charset eq $enc and $preserve_words;
+
+    foreach my $tag ( $head->tags ) {
+        my @values = $head->get_all($tag);
+        $head->delete($tag);
+        foreach my $value (@values) {
+            if ( $charset ne $enc ) {
+
+                eval {
+                    Encode::_utf8_off($value);
+                    Encode::from_to( $value, $charset => $enc );
+                };
+                if ($@) {
+                    $RT::Logger->error( "Encoding error: " . $@
+                                       . " defaulting to ISO-8859-1 -> UTF-8" );
+                    eval { Encode::from_to( $value, 'iso-8859-1' => $enc ) };
+                    if ($@) {
+                        $RT::Logger->crit( "Totally failed to convert to utf-8: " . $@ . " I give up" );
+                    }
+                }
+            }
+            $value = DecodeMIMEWordsToEncoding( $value, $enc ) unless $preserve_words;
+            $head->add( $tag, $value );
+        }
+    }
+
+}
+# }}}
+
+eval "require RT::I18N_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/I18N_Vendor.pm});
+eval "require RT::I18N_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/I18N_Local.pm});
+
+1;  # End of module.
+
diff --git a/rt/lib/RT/I18N/cs.pm b/rt/lib/RT/I18N/cs.pm
new file mode 100644 (file)
index 0000000..36e2bc6
--- /dev/null
@@ -0,0 +1,68 @@
+package RT::I18N::cs;
+
+# # CZECH TRANSLATORS COMMENTS see Locale::Maketext::TPJ13
+# Obecne parametry musi byt docela slozite (v pripade Slavistickych jazyku)
+# typu pocet, slovo, pad a rod 
+#
+#pad 1., rod muzsky:
+#0 krecku
+#1 krecek
+#2..4 krecci
+#5.. krecku (nehodi se zde resit pravidlo mod 1,2,3,4 krom mod 11,12,13,14)
+#
+#0 kabatu
+#1 kabat
+#2..4 kabaty
+#5 kabatu
+#
+# => Vyplati se udelat quant s parametry typu pocet, slovo1, slovo2..4, slovo5 a slovo0
+#
+
+sub quant {
+  my($handle, $num, @forms) = @_;
+
+  return $num if @forms == 0; # what should this mean?
+  return $forms[3] if @forms > 3 and $num == 0; # special zeroth case
+
+  # Normal case:
+  # Note that the formatting of $num is preserved.
+  #return( $handle->numf($num) . ' ' . $handle->numerate($num, @forms) );
+  return( $handle->numerate($num, @forms) );
+   # Most human languages put the number phrase before the qualified phrase.
+}
+
+
+sub numerate {
+ # return this lexical item in a form appropriate to this number
+  my($handle, $num, @forms) = @_;
+  my $s = ($num == 1);
+
+  return '' unless @forms;
+  return
+   $s ? $forms[0] :
+   ( $num > 1 && $num < 5 ) ? $forms[1] :
+   $forms[2];
+}
+
+#--------------------------------------------------------------------------
+
+sub numf {
+  my($handle, $num) = @_[0,1];
+  if($num < 10_000_000_000 and $num > -10_000_000_000 and $num == int($num)) {
+    $num += 0;  # Just use normal integer stringification.
+         # Specifically, don't let %G turn ten million into 1E+007
+  } else {
+    $num = CORE::sprintf("%G", $num);
+     # "CORE::" is there to avoid confusion with the above sub sprintf.
+  }
+  while( $num =~ s/^([-+]?\d+)(\d{3})/$1,$2/s ) {1}  # right from perlfaq5
+   # The initial \d+ gobbles as many digits as it can, and then we
+   #  backtrack so it un-eats the rightmost three, and then we
+   #  insert the comma there.
+
+  $num =~ tr<.,><,.> if ref($handle) and $handle->{'numf_comma'};
+   # This is just a lame hack instead of using Number::Format
+  return $num;
+}
+
+1;
diff --git a/rt/lib/RT/I18N/cs.po b/rt/lib/RT/I18N/cs.po
new file mode 100644 (file)
index 0000000..75f3495
--- /dev/null
@@ -0,0 +1,4496 @@
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: RT 3.0.0\n"
+"POT-Creation-Date: 2002-05-02 11:36+0800\n"
+"PO-Revision-Date: 2003-03-24 03:00+0800\n"
+"Last-Translator: Jan Okrouhly <okrouhly@civ.zcu.cz>\n"
+"Language-Team: rt-devel <rt-devel@lists.fsck.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28
+msgid "#"
+msgstr "#"
+
+#: html/Admin/Queues/Scrip.html:55
+#. ($QueueObj->id)
+msgid "#%1"
+msgstr "#%1"
+
+#: html/Approvals/Elements/ShowDependency:50 html/Ticket/Display.html:26 html/Ticket/Display.html:30
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr "#%1: %2"
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr "%1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr "%1 %2 %3"
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr "%1 %3.%2.%7 %4:%5:%6"
+
+#: lib/RT/Ticket_Overlay.pm:3438 lib/RT/Transaction_Overlay.pm:559 lib/RT/Transaction_Overlay.pm:601
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 added"
+msgstr "%1 %2 přidáno"
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 %2 ago"
+msgstr "- %1 %2"
+
+#: lib/RT/Ticket_Overlay.pm:3444 lib/RT/Transaction_Overlay.pm:566
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 changed to %3"
+msgstr "%1 %2 změněno na %3"
+
+#: lib/RT/Ticket_Overlay.pm:3441 lib/RT/Transaction_Overlay.pm:562 lib/RT/Transaction_Overlay.pm:607
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 deleted"
+msgstr "%1 %2 smazáno"
+
+#: html/Admin/Elements/EditScrips:44 html/Admin/Elements/ListGlobalScrips:28
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 with template %3"
+msgstr "%1 %2 se vzorem %3"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 this ticket\\n"
+msgstr "%1 (%2) %3 tento požadavek\\n"
+
+#: html/Search/Listing.html:57
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr "%1. až %2. zobrazený"
+
+#: bin/rt-crontool:169 bin/rt-crontool:176 bin/rt-crontool:182
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - An argument to pass to %2"
+msgstr "%1 - argument k předání %2"
+
+#: bin/rt-crontool:185
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr "%1 - Výstupní stav jde do STDOUT"
+
+#: bin/rt-crontool:179
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr "%1 - Jaký akční modul chcete použít"
+
+#: bin/rt-crontool:173
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr "%1 - Jaký podmínkový modul chcete použít"
+
+#: bin/rt-crontool:166
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr "%1 - Jaký vyhledávací modul chcete použít"
+
+#: lib/RT/ScripAction_Overlay.pm:122
+#. ($self->Id)
+msgid "%1 ScripAction loaded"
+msgstr "ScripAction %1 nahrána"
+
+#: lib/RT/Ticket_Overlay.pm:3471
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 added as a value for %2"
+msgstr "%1 přidáno jako hodnota pro %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on"
+msgstr "%1 aliasy vyžadují k činnosti TicketId"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on (from %2) %3"
+msgstr "%1 aliasy vyžadují k činnosti TicketId (odesílatel %2) %3"
+
+#: lib/RT/Link_Overlay.pm:117 lib/RT/Link_Overlay.pm:124
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 appears to be a local object, but can't be found in the database"
+msgstr "%1 vypadá jako lokální objekt, ale není v databázi"
+
+#: html/Ticket/Elements/ShowDates:52 lib/RT/Transaction_Overlay.pm:483
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 by %2"
+msgstr "%1 uživatelem %2"
+
+#: lib/RT/Transaction_Overlay.pm:537 lib/RT/Transaction_Overlay.pm:626 lib/RT/Transaction_Overlay.pm:635 lib/RT/Transaction_Overlay.pm:638
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 changed from %2 to %3"
+msgstr "%1 změněno z %2 na %3"
+
+#: lib/RT/Interface/Web.pm:857
+msgid "%1 could not be set to %2."
+msgstr "%1 nemůže být nastaveno na %2."
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr "%1 nemůže začít transakci (%2)\\n"
+
+#: lib/RT/Ticket_Overlay.pm:2813
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr "%1 nemůže nastavit stav na vyřešen. RT databáze může být nekonzistentní."
+
+#: html/Elements/MyTickets:25
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr "%1 nejdůležitějších požadavků, které vlastním..."
+
+#: html/Elements/MyRequests:25
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr "%1 nejdůležitějších požadavků, které žádám..."
+
+#: bin/rt-crontool:161
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr "%1 je nástroj zpracující požadavky z vnějšího plánovacího nástroje jako je cron"
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr "%1 již není %2 této fronty."
+
+#: lib/RT/Ticket_Overlay.pm:1570
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr "%1 již není %2 tohoto požadavku."
+
+#: lib/RT/Ticket_Overlay.pm:3527
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr "%1 již není hodnotou uživatelské položky %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr "%1 není platným identifikátorem fronty."
+
+#: html/Ticket/Elements/ShowBasics:36
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr "%1 %quant(%1,minuta,minuty,minut,minut)"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr "%1 nezobrazeno"
+
+#: html/User/Elements/DelegateRights:76
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr "práva %1"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr "%1 provedeno\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr "typ %1 neznámý pro $MessageId"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr "typ %1 neznámý pro %2"
+
+#: lib/RT/Action/ResolveMembers.pm:42
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr "%1 vyřeší všechny členy skupiny vyřešeného požadavku."
+
+#: NOT FOUND IN SOURCE
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr "%1 odloží [místní] BÁZI, je-li závislá [či členem] na spjatém požadavku."
+
+#: lib/RT/Transaction_Overlay.pm:435
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr "%1: neudána příloha"
+
+#: html/Ticket/Elements/ShowTransaction:102
+#. ($size)
+msgid "%1b"
+msgstr "%1 B"
+
+#: html/Ticket/Elements/ShowTransaction:99
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr "%1 kB"
+
+#: lib/RT/Ticket_Overlay.pm:1140
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr "%1 je neplatnou hodnotou pro stav"
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr "%1 je neznámá akce."
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr "(Zatrhněte pro smazání scripu)"
+
+#: html/Admin/Elements/EditQueueWatchers:29 html/Admin/Elements/EditScrips:35 html/Admin/Elements/EditTemplates:36 html/Admin/Groups/Members.html:52 html/Ticket/Elements/EditLinks:33 html/Ticket/Elements/EditPeople:46 html/User/Groups/Members.html:55
+msgid "(Check box to delete)"
+msgstr "(Zatrhněte pro smazání)"
+
+#: html/Ticket/Create.html:178
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr "(Zadejte identifikátory či URL požadavku, oddělené mezerami)"
+
+#: html/Admin/Queues/Modify.html:54 html/Admin/Queues/Modify.html:60
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr "(Pro prázdné pole se použije %1)"
+
+#: html/Admin/Elements/EditCustomFields:33 html/Admin/Elements/ListGlobalCustomFields:32
+msgid "(No custom fields)"
+msgstr "(Žádné uživatelské položky)"
+
+#: html/Admin/Groups/Members.html:50 html/User/Groups/Members.html:53
+msgid "(No members)"
+msgstr "(Žádní členové)"
+
+#: html/Admin/Elements/EditScrips:32 html/Admin/Elements/ListGlobalScrips:32
+msgid "(No scrips)"
+msgstr "Žádné scripy"
+
+#: html/Admin/Elements/EditTemplates:31
+msgid "(No templates)"
+msgstr "(Žádné vzory)"
+
+#: html/Ticket/Update.html:85
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(Zašle skrytou kopii této aktualizace mezerami oddělenému seznamu e-mail adres. <b>Neovlivňuje</b> příjemce budoucích aktualizací.)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Zašle skrytou kopii této aktualizace mezerami oddělenému seznamu e-mail adres. <b>Neovlivňuje</b> příjemce budoucích aktualizací.)"
+
+#: html/Ticket/Create.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(Zašle kopii této aktualizace mezerami oddělenému seznamu e-mail adres. Tito lidé <b>budou</b> dostávat budoucí aktualizace.)"
+
+#: html/Ticket/Update.html:81
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(Zašle kopii této aktualizace mezerami oddělenému seznamu e-mail adres. <b>Nemění</b> příjemce budoucích aktualizací"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Zašle kopii této aktualizace mezerami oddělenému seznamu e-mail adres. <b>Neovlivňuje</b> příjemce budoucích aktualizací.)"
+
+#: html/Ticket/Create.html:69
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(Zašle kopii této aktualizace mezerami oddělenému seznamu e-mail adres. Tito lidé <b>budou</b> dostávat budoucí aktualizace.)"
+
+#: html/Admin/Groups/index.html:33 html/User/Groups/index.html:33
+msgid "(empty)"
+msgstr "(prázdná)"
+
+#: html/Admin/Users/index.html:39
+msgid "(no name listed)"
+msgstr "žádné jméno nebylo vypsáno"
+
+#: html/Elements/MyRequests:43 html/Elements/MyTickets:45
+msgid "(no subject)"
+msgstr "(bez předmětu)"
+
+#: html/Admin/Elements/SelectRights:48 html/Elements/SelectCustomFieldValue:30 html/Ticket/Elements/EditCustomField:59 html/Ticket/Elements/ShowCustomFields:36 lib/RT/Transaction_Overlay.pm:536
+msgid "(no value)"
+msgstr "(bez hodnoty)"
+
+#: html/Ticket/Elements/EditLinks:116
+msgid "(only one ticket)"
+msgstr "(jen jeden požadavek)"
+
+#: html/Elements/MyRequests:52 html/Elements/MyTickets:55
+msgid "(pending approval)"
+msgstr "(očekávájící schválení)"
+
+#: html/Elements/MyRequests:54 html/Elements/MyTickets:57
+msgid "(pending other tickets)"
+msgstr "(jiné očekávající požadavky)"
+
+#: html/Admin/Users/Modify.html:50
+msgid "(required)"
+msgstr "(povinné)"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "(untitled)"
+msgstr "(nepojmenováno)"
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I own..."
+msgstr "25 mnou vlastněných nejdůležitějších požadavků..."
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I requested..."
+msgstr "25 mnou žádaných nejdůležitějších požadavků..."
+
+#: html/Ticket/Elements/ShowBasics:32
+msgid "<% $Ticket->Status%>"
+msgstr "<% $Ticket->Status%>"
+
+#: html/Elements/SelectTicketTypes:27
+msgid "<% $_ %>"
+msgstr "<% $_ %>"
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:26
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"Nový požadavek v\">&nbsp;%1"
+
+#: etc/initialdata:203
+msgid "A blank template"
+msgstr "Prázdný vzor"
+
+#: lib/RT/ACE_Overlay.pm:157 lib/RT/Principal_Overlay.pm:181
+msgid "ACE not found"
+msgstr "ACE nenalezeno"
+
+#: lib/RT/ACE_Overlay.pm:831
+msgid "ACEs can only be created and deleted."
+msgstr "ACE mohou být jen vytvářeny nebo rušeny."
+
+#: bin/rt-commit-handler:755
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr "Přerušeno k zamezení nežádoucích změn požadavku.\\n"
+
+#: html/User/Elements/Tabs:32
+msgid "About me"
+msgstr "O mně"
+
+#: html/Admin/Users/Modify.html:80
+msgid "Access control"
+msgstr "Řízení přístupu"
+
+#: html/Admin/Elements/EditScrip:57
+msgid "Action"
+msgstr "Akce"
+
+#: lib/RT/Scrip_Overlay.pm:147
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr "Akce %1 nenalezena"
+
+#: bin/rt-crontool:123
+msgid "Action committed."
+msgstr "Akce provedena."
+
+#: bin/rt-crontool:119
+msgid "Action prepared..."
+msgstr "Akce připravena..."
+
+#: html/Search/Bulk.html:92
+msgid "Add AdminCc"
+msgstr "Přidat AdminCc"
+
+#: html/Search/Bulk.html:90
+msgid "Add Cc"
+msgstr "Přidat Cc"
+
+#: html/Ticket/Create.html:114 html/Ticket/Update.html:100
+msgid "Add More Files"
+msgstr "Přidat další soubory"
+
+#: html/Search/Bulk.html:88
+msgid "Add Requestor"
+msgstr "Přidat Žadatele"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr "Přidat nový globální scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr "Přidat scrip k této frontě"
+
+#: html/Admin/Global/Scrip.html:55
+msgid "Add a scrip which will apply to all queues"
+msgstr "Přidat scrip do všech front"
+
+#: html/Search/Bulk.html:118
+msgid "Add comments or replies to selected tickets"
+msgstr "Přidat komentáře či odpovědi k vybraným požadavkům"
+
+#: html/Admin/Groups/Members.html:42 html/User/Groups/Members.html:39
+msgid "Add members"
+msgstr "Přidat členy"
+
+#: html/Admin/Queues/People.html:66 html/Ticket/Elements/AddWatchers:28
+msgid "Add new watchers"
+msgstr "Přidat nové pozorovatele"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr "PřidatDalšíStav"
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr "Uživatel přidán do této fronty jako %1"
+
+#: lib/RT/Ticket_Overlay.pm:1454
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr "Uživatel přidán k tomuto požadavku jako %1"
+
+#: html/Admin/Elements/ModifyUser:76 html/Admin/Users/Modify.html:122 html/User/Prefs.html:88
+msgid "Address1"
+msgstr "Adresa1"
+
+#: html/Admin/Elements/ModifyUser:78 html/Admin/Users/Modify.html:127 html/User/Prefs.html:90
+msgid "Address2"
+msgstr "Adresa2"
+
+#: html/Ticket/Create.html:74
+msgid "Admin Cc"
+msgstr "Admin Cc"
+
+#: etc/initialdata:274
+msgid "Admin Comment"
+msgstr "Administrativní komentář"
+
+#: etc/initialdata:256
+msgid "Admin Correspondence"
+msgstr "Administrativní korespondence"
+
+#: html/Admin/Queues/index.html:25 html/Admin/Queues/index.html:28
+msgid "Admin queues"
+msgstr "Správa/Front"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr "Správa/Uživatelů"
+
+#: html/Admin/Global/index.html:26 html/Admin/Global/index.html:28
+msgid "Admin/Global configuration"
+msgstr "Správa/Globální konfigurace"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr "Správa/Skupin"
+
+#: html/Admin/Queues/Modify.html:25 html/Admin/Queues/Modify.html:29
+msgid "Admin/Queue/Basics"
+msgstr "Správa/Front/Základních údajů"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr "Spravovat všechny osobní skupiny"
+
+#: etc/initialdata:56 html/Ticket/Elements/ShowPeople:39 html/Ticket/Update.html:50 lib/RT/ACE_Overlay.pm:89
+msgid "AdminCc"
+msgstr "AdminCc"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr "AdminComment"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr "AdminCorrespondence"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "AdminCustomFields"
+msgstr "Spravovat uživatelem definované položky"
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "AdminGroup"
+msgstr "Spravovat skupinu"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "AdminGroupMembership"
+msgstr "Spravovat členství ve skupinách"
+
+#: lib/RT/System.pm:59
+msgid "AdminOwnPersonalGroups"
+msgstr "Spravovat vlastní osobní skupiny"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "AdminQueue"
+msgstr "Spravovat frontu"
+
+#: lib/RT/System.pm:60
+msgid "AdminUsers"
+msgstr "Spravovat uživatele"
+
+#: html/Admin/Queues/People.html:48 html/Ticket/Elements/EditPeople:54
+msgid "Administrative Cc"
+msgstr "Administrativní Cc"
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr "Pokročilé Vyhledávání"
+
+#: html/Elements/SelectDateRelation:36
+msgid "After"
+msgstr "Po"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr "Stáří"
+
+#: html/Admin/Elements/EditCustomFields:96
+msgid "All Custom Fields"
+msgstr "Všechny uživatelské položky"
+
+#: html/Admin/Queues/index.html:53
+msgid "All Queues"
+msgstr "Všechny Fronty"
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr "Vždy posílá zprávu žadatelům nezávisle na odesílateli"
+
+#: html/Elements/Tabs:58
+msgid "Approval"
+msgstr "Schvalování"
+
+#: html/Approvals/Display.html:46 html/Approvals/Elements/Approve:27 html/Approvals/Elements/ShowDependency:42 html/Approvals/index.html:65
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr "Schválení #%1: $2"
+
+#: html/Approvals/index.html:54
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr "Schválení #$1: Poznámky neuloženy kvůli systémové chybě"
+
+#: html/Approvals/index.html:52
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr "Schválení #%1: Poznámky uloženy"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Details"
+msgstr "Detaily schválení"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval diagram"
+msgstr "Schvalovací diagram"
+
+#: html/Approvals/Elements/Approve:45
+msgid "Approve"
+msgstr "Schválit"
+
+#: etc/initialdata:431 etc/upgrade/2.1.71:148
+msgid "Approver's notes: %1"
+msgstr "Poznámky schvalovatele: %1"
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "dub"
+
+#: html/Elements/SelectSortOrder:35
+msgid "Ascending"
+msgstr "Vzestupně"
+
+#: html/Search/Bulk.html:127 html/SelfService/Update.html:36 html/Ticket/ModifyAll.html:83 html/Ticket/Update.html:100
+msgid "Attach"
+msgstr "Přiložit"
+
+#: html/SelfService/Create.html:67 html/Ticket/Create.html:110
+msgid "Attach file"
+msgstr "Připojit soubor"
+
+#: html/Ticket/Create.html:98 html/Ticket/Update.html:89
+msgid "Attached file"
+msgstr "Připojený soubor"
+
+#: html/SelfService/Attachment/dhandler:36
+msgid "Attachment '%1' could not be loaded"
+msgstr "Příloha '%1' nemůže být nahrána"
+
+#: lib/RT/Transaction_Overlay.pm:443
+msgid "Attachment created"
+msgstr "Příloha vytvořena"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "Jméno souboru přílohy"
+
+#: html/Ticket/Elements/ShowAttachments:26
+msgid "Attachments"
+msgstr "Přílohy"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "srp"
+
+#: html/Admin/Elements/ModifyUser:66
+msgid "AuthSystem"
+msgstr "AuthSystem"
+
+#: etc/initialdata:206
+msgid "Autoreply"
+msgstr "Automatická odpověď"
+
+#: etc/initialdata:72
+msgid "Autoreply To Requestors"
+msgstr "Automaticky odpověz žadatelům"
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr "Automatická odpověď žadatelům"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr "Chybná PGP signatura: %1\\n"
+
+#: html/SelfService/Attachment/dhandler:40
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr "Chybný identifikátor přílohy. Nelze nalézt přílohu'%1'\\n"
+
+#: bin/rt-commit-handler:827
+#. ($val)
+msgid "Bad data in %1"
+msgstr "Chybná data v %1"
+
+#: html/SelfService/Attachment/dhandler:43
+#. ($trans, $AttachmentObj->TransactionId())
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr "Chybné číslo transakce u přílohy. %1 má být %2\\n"
+
+#: html/Admin/Elements/GroupTabs:39 html/Admin/Elements/QueueTabs:39 html/Admin/Elements/UserTabs:38 html/Ticket/Elements/Tabs:90 html/User/Elements/GroupTabs:38
+msgid "Basics"
+msgstr "Základní údaje"
+
+#: html/Ticket/Update.html:83
+msgid "Bcc"
+msgstr "Bcc"
+
+#: html/Admin/Elements/EditScrip:88 html/Admin/Global/GroupRights.html:85 html/Admin/Global/Template.html:46 html/Admin/Global/UserRights.html:54 html/Admin/Groups/GroupRights.html:73 html/Admin/Groups/Members.html:81 html/Admin/Groups/Modify.html:56 html/Admin/Groups/UserRights.html:55 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:45 html/Admin/Queues/UserRights.html:54 html/User/Groups/Modify.html:56
+msgid "Be sure to save your changes"
+msgstr "Neopomeňte uložit vaše změny"
+
+#: html/Elements/SelectDateRelation:34 lib/RT/CurrentUser.pm:322
+msgid "Before"
+msgstr "Před"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin Approval"
+msgstr "Začátek schvalování"
+
+#: etc/initialdata:202
+msgid "Blank"
+msgstr "Prázdný"
+
+#: html/Search/Listing.html:79
+msgid "Bookmarkable URL for this search"
+msgstr "Uložitelné URL pro toto hledání"
+
+#: html/Ticket/Elements/ShowHistory:39 html/Ticket/Elements/ShowHistory:45
+msgid "Brief headers"
+msgstr "Zkrácené hlavičky"
+
+#: html/Search/Bulk.html:25 html/Search/Bulk.html:26
+msgid "Bulk ticket update"
+msgstr "Hromadná úprava požadavků"
+
+#: lib/RT/User_Overlay.pm:1331
+msgid "Can not modify system users"
+msgstr "Nelze měnit systémové uživatele"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Can this principal see this queue"
+msgstr "Může tento uživatel vidět tuto frontu"
+
+#: lib/RT/CustomField_Overlay.pm:144
+msgid "Can't add a custom field value without a name"
+msgstr "Uživatelské položce nelze přidat hodnotu beze jména"
+
+#: lib/RT/Link_Overlay.pm:132
+msgid "Can't link a ticket to itself"
+msgstr "Požadavek nelze svázat se sebou samým"
+
+#: lib/RT/Ticket_Overlay.pm:2787
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr "Nelze sloučit do sloučeného požadavku. To by se vám nemělo nikdy stát."
+
+#: lib/RT/Ticket_Overlay.pm:2605 lib/RT/Ticket_Overlay.pm:2674
+msgid "Can't specifiy both base and target"
+msgstr "Nelze zadat zároveň zdroj i cíl"
+
+#: html/autohandler:112
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr "Nelze vytvořit uživatele: %1"
+
+#: etc/initialdata:50 html/Admin/Queues/People.html:44 html/SelfService/Create.html:51 html/SelfService/Display.html:50 html/Ticket/Create.html:64 html/Ticket/Elements/EditPeople:51 html/Ticket/Elements/ShowPeople:35 html/Ticket/Update.html:45 html/Ticket/Update.html:78 lib/RT/ACE_Overlay.pm:88
+msgid "Cc"
+msgstr "Cc"
+
+#: html/SelfService/Prefs.html:31
+msgid "Change password"
+msgstr "Změna hesla"
+
+#: html/Ticket/Create.html:101 html/Ticket/Update.html:92
+msgid "Check box to delete"
+msgstr "Zašrtnutím odstraníte"
+
+#: html/Admin/Elements/SelectRights:31
+msgid "Check box to revoke right"
+msgstr "Zatrhněte k odebrání práva"
+
+#: html/Ticket/Create.html:183 html/Ticket/Elements/EditLinks:131 html/Ticket/Elements/EditLinks:69 html/Ticket/Elements/ShowLinks:51
+msgid "Children"
+msgstr "Potomci"
+
+#: html/Admin/Elements/ModifyUser:80 html/Admin/Users/Modify.html:132 html/User/Prefs.html:92
+msgid "City"
+msgstr "Město"
+
+#: html/Ticket/Elements/ShowDates:47
+msgid "Closed"
+msgstr "Vyřešeno"
+
+#: html/SelfService/Elements/Tabs:60
+msgid "Closed requests"
+msgstr "Uzavřené požadavky"
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr "Neznámý příkaz!\\n"
+
+#: html/Ticket/Elements/ShowTransaction:179 html/Ticket/Elements/Tabs:153
+msgid "Comment"
+msgstr "Komentovat"
+
+#: html/Admin/Elements/ModifyQueue:45 html/Admin/Queues/Modify.html:58
+msgid "Comment Address"
+msgstr "Adresa pro komentáře"
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr "Komentář nezaznamenán"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Comment on tickets"
+msgstr "Komentovat požadavky"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "CommentOnTicket"
+msgstr "Komentovat požadavky"
+
+#: html/Admin/Elements/ModifyUser:35
+msgid "Comments"
+msgstr "Poznámky"
+
+#: html/Ticket/ModifyAll.html:70 html/Ticket/Update.html:70
+msgid "Comments (Not sent to requestors)"
+msgstr "Komentář (Neposílá se žadatelům)"
+
+#: html/Search/Bulk.html:122
+msgid "Comments (not sent to requestors)"
+msgstr "Komentář (nepošle se žadatelům)"
+
+#: html/Elements/ViewUser:27
+#. ($name)
+msgid "Comments about %1"
+msgstr "Poznámky o %1"
+
+#: html/Admin/Users/Modify.html:185 html/Ticket/Elements/ShowRequestor:44
+msgid "Comments about this user"
+msgstr "Poznámky o tomto uživateli"
+
+#: lib/RT/Transaction_Overlay.pm:545
+msgid "Comments added"
+msgstr "Komentáře přidány"
+
+#: lib/RT/Action/Generic.pm:140
+msgid "Commit Stubbed"
+msgstr "Commit v zárodku"
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr "Omezení překladu"
+
+#: html/Admin/Elements/EditScrip:41
+msgid "Condition"
+msgstr "Podmínka"
+
+#: bin/rt-crontool:109
+msgid "Condition matches..."
+msgstr "Podmínky splněny..."
+
+#: lib/RT/Scrip_Overlay.pm:160
+msgid "Condition not found"
+msgstr "Podmínka nenalezena"
+
+#: html/Elements/Tabs:52
+msgid "Configuration"
+msgstr "Správa"
+
+#: html/SelfService/Prefs.html:33
+msgid "Confirm"
+msgstr "Potvrzení"
+
+#: html/Admin/Elements/ModifyUser:60
+msgid "ContactInfoSystem"
+msgstr "Kontaktní informační systém"
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr "Datum kontaktu '%1' nemůže být rozpoznáno"
+
+#: html/Admin/Elements/ModifyTemplate:44 html/Ticket/ModifyAll.html:87
+msgid "Content"
+msgstr "Obsah"
+
+#: etc/initialdata:266
+msgid "Correspondence"
+msgstr "Korespondence"
+
+#: html/Admin/Elements/ModifyQueue:39 html/Admin/Queues/Modify.html:51
+msgid "Correspondence Address"
+msgstr "Adresa pro korespondenci"
+
+#: lib/RT/Transaction_Overlay.pm:541
+msgid "Correspondence added"
+msgstr "Korespondence zaznamenána"
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr "Korespondence nebyla zaznamenána"
+
+#: lib/RT/Ticket_Overlay.pm:3458
+msgid "Could not add new custom field value for ticket. "
+msgstr "Nelze přidat novou hodnotu uživatelské položky požadavku. "
+
+#: lib/RT/Ticket_Overlay.pm:2963 lib/RT/Ticket_Overlay.pm:2971 lib/RT/Ticket_Overlay.pm:2987
+msgid "Could not change owner. "
+msgstr "Nelze změnit vlastníka. "
+
+#: html/Admin/Elements/EditCustomField:68 html/Admin/Elements/EditCustomFields:166
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr "Nelze vytvořit Uživatelskou položku"
+
+#: html/User/Groups/Modify.html:77 lib/RT/Group_Overlay.pm:474 lib/RT/Group_Overlay.pm:481
+msgid "Could not create group"
+msgstr "Nelze vytvořit skupinu"
+
+#: html/Admin/Global/Template.html:75 html/Admin/Queues/Template.html:72
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr "Nelze vytvořit vzor: %1"
+
+#: lib/RT/Ticket_Overlay.pm:1073 lib/RT/Ticket_Overlay.pm:333
+msgid "Could not create ticket. Queue not set"
+msgstr "Nelze vytvořit požadavek. Nenastavena fronta"
+
+#: lib/RT/User_Overlay.pm:208 lib/RT/User_Overlay.pm:220 lib/RT/User_Overlay.pm:238 lib/RT/User_Overlay.pm:414
+msgid "Could not create user"
+msgstr "Nelze vytvořit uživatele"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr "Nelze nalézt požadavek s identifikátorem %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr "Nelze nalézt skupinu %1."
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1422
+msgid "Could not find or create that user"
+msgstr "Tohoto uživatele nelze nalézt nebo vytvořit"
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1501
+msgid "Could not find that principal"
+msgstr "Nelze naléze tohoto uživatele"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr "Nelze nalézt uživatele %1."
+
+#: html/Admin/Groups/Members.html:88 html/User/Groups/Members.html:90 html/User/Groups/Modify.html:82
+msgid "Could not load group"
+msgstr "Nelze načíst skupinu"
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr "Tento uživatel nemůže být %1 této fronty"
+
+#: lib/RT/Ticket_Overlay.pm:1443
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr "Tento uživatel nemůže být %1 tohoto požadavku"
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr "Tento uživatel nemůže být odstraněn jako %1 této fronty"
+
+#: lib/RT/Ticket_Overlay.pm:1559
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr "Tento uživatel nemůže být odstraněn jako %1 tohoto požadavku"
+
+#: lib/RT/Group_Overlay.pm:985
+msgid "Couldn't add member to group"
+msgstr "Do skupiny nelze přidat člena"
+
+#: lib/RT/Ticket_Overlay.pm:3468 lib/RT/Ticket_Overlay.pm:3524
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr "Nelze vytvořit transakci: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr "Nelze zjistit co dělat s gpg odpovědí\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr "Skupinu nelze nalézt\\n"
+
+#: lib/RT/Interface/Web.pm:866
+msgid "Couldn't find row"
+msgstr "Nemohu nalézt sloupec"
+
+#: lib/RT/Group_Overlay.pm:959
+msgid "Couldn't find that principal"
+msgstr "Tohoto uživatele nelze nalézt"
+
+#: lib/RT/CustomField_Overlay.pm:175
+msgid "Couldn't find that value"
+msgstr "Tuto hodnotu nelze nalézt"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr "Uživatele nelze nalézt\\n"
+
+#: lib/RT/CurrentUser.pm:112
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr "Z uživatelské databáze nelze načíst %1.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr "Konfigurační soubor RT '%1'nelze načíst %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr "Scripy nelze načíst."
+
+#: html/Admin/Groups/GroupRights.html:88 html/Admin/Groups/UserRights.html:75
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr "Skupinu %1 nelze načíst"
+
+#: lib/RT/Link_Overlay.pm:175 lib/RT/Link_Overlay.pm:184 lib/RT/Link_Overlay.pm:211
+msgid "Couldn't load link"
+msgstr "Vazbu nelze načíst"
+
+#: html/Admin/Elements/EditCustomFields:147 html/Admin/Queues/People.html:121
+#. ($id)
+msgid "Couldn't load queue"
+msgstr "Frontu nelze načíst"
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:72
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr "Frontu %1 nelze načíst"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr "Scrip nelze načíst"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr "Vzor nelze načíst"
+
+#: html/Admin/Users/Prefs.html:79
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr "Uživatele (%1) nelze načíst"
+
+#: html/SelfService/Display.html:166
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr "Požadavek '%1' nelze načíst"
+
+#: html/Admin/Elements/ModifyUser:86 html/Admin/Users/Modify.html:149 html/User/Prefs.html:98
+msgid "Country"
+msgstr "Země"
+
+#: html/Admin/Elements/CreateUserCalled:26 html/Ticket/Create.html:135 html/Ticket/Create.html:195
+msgid "Create"
+msgstr "Vytvořit"
+
+#: etc/initialdata:128
+msgid "Create Tickets"
+msgstr "Vytvořit požadavky"
+
+#: html/Admin/Elements/EditCustomField:58
+msgid "Create a CustomField"
+msgstr "Vytvořit uživatelskou položku"
+
+#: html/Admin/Queues/CustomField.html:48
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr "Vytvoření uživatelské položky pro frontu %1"
+
+#: html/Admin/Global/CustomField.html:48
+msgid "Create a CustomField which applies to all queues"
+msgstr "Vytvoření uživatelské položky pro všechny front"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr "Vytvořit novou uživatelskou položku"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr "Vytvořit nový globální scrip"
+
+#: html/Admin/Groups/Modify.html:67 html/Admin/Groups/Modify.html:93
+msgid "Create a new group"
+msgstr "Vytvořit novou skupinu"
+
+#: html/User/Groups/Modify.html:67 html/User/Groups/Modify.html:92
+msgid "Create a new personal group"
+msgstr "Vytvořit novou vlastní skupinu"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr "Vytvořit novou frontu"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr "Vytvořit nový scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr "Vytvořit nový vzor"
+
+#: html/SelfService/Create.html:30 html/Ticket/Create.html:25 html/Ticket/Create.html:28 html/Ticket/Create.html:36
+msgid "Create a new ticket"
+msgstr "Vytvoření nového požadavku"
+
+#: html/Admin/Users/Modify.html:214 html/Admin/Users/Modify.html:241
+msgid "Create a new user"
+msgstr "Vytvořit nového uživatele"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "Vytvořit frontu"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr "Vytvořit frontu nazvanou"
+
+#: html/SelfService/Create.html:25 html/SelfService/Create.html:27
+msgid "Create a request"
+msgstr "Vytvořit požadavek"
+
+#: html/Admin/Queues/Scrip.html:59
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr "Vytvořit scrips pro frontu %1"
+
+#: html/Admin/Global/Template.html:69 html/Admin/Queues/Template.html:65
+msgid "Create a template"
+msgstr "Vytvořit vzor"
+
+#: etc/initialdata:130
+msgid "Create new tickets based on this scrip's template"
+msgstr "Vytvářet požadavky podle toho vzoru scripu"
+
+#: html/SelfService/Create.html:81
+msgid "Create ticket"
+msgstr "Vytvořit požadavek"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Create tickets in this queue"
+msgstr "Vytvářet požadavky v této frontě"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Create, delete and modify custom fields"
+msgstr "Vytvářet, mazat a měnit uživatelen definované položky"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Create, delete and modify queues"
+msgstr "Vytvářet, mazat a měnit fronty"
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr "Vytvářet, mazat a měnit členy uživatelských osobních skupin"
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify the members of personal groups"
+msgstr "Vytvářet, mazat a měnit členy osobních skupin"
+
+#: lib/RT/System.pm:60
+msgid "Create, delete and modify users"
+msgstr "Vytvářen, mazat a měnit uživatele"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "CreateTicket"
+msgstr "Vytvořit požadavek"
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1167
+msgid "Created"
+msgstr "Vytvořeno"
+
+#: html/Admin/Elements/EditCustomField:71
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr "Uživatelská položka %1 vytvořena"
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr "Vzor %1 vytvořen"
+
+#: html/Ticket/Elements/EditLinks:28
+msgid "Current Relationships"
+msgstr "Aktuální relace"
+
+#: html/Admin/Elements/EditScrips:30
+msgid "Current Scrips"
+msgstr "Aktuální scripy"
+
+#: html/Admin/Groups/Members.html:39 html/User/Groups/Members.html:42
+msgid "Current members"
+msgstr "Aktuální členové"
+
+#: html/Admin/Elements/SelectRights:29
+msgid "Current rights"
+msgstr "Aktuální práva"
+
+#: html/Search/Listing.html:71
+msgid "Current search criteria"
+msgstr "Aktuální vyhledávací podmínky"
+
+#: html/Admin/Queues/People.html:41 html/Ticket/Elements/EditPeople:45
+msgid "Current watchers"
+msgstr "Aktuální pozorovatelé"
+
+#: html/Admin/Global/CustomField.html:55
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr "Uživatelská položka #%1"
+
+#: html/Admin/Elements/QueueTabs:53 html/Admin/Elements/SystemTabs:40 html/Admin/Global/index.html:50 html/Ticket/Elements/ShowSummary:35
+msgid "Custom Fields"
+msgstr "Uživatelské položky"
+
+#: html/Admin/Elements/EditScrip:73
+msgid "Custom action cleanup code"
+msgstr "Čistící kód uživatelské akce"
+
+#: html/Admin/Elements/EditScrip:65
+msgid "Custom action preparation code"
+msgstr "Přípravný kód uživatelské akce"
+
+#: html/Admin/Elements/EditScrip:49
+msgid "Custom condition"
+msgstr "Uživatelská podmínka"
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr "Užitavelská položka %1 %2 %3"
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr "Uživatelská položka %1 má hodnotu."
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr "Uživatelská položka %1 nemá hodnotu."
+
+#: lib/RT/Ticket_Overlay.pm:3360
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr "Uživatelská položka %1 nenalezena"
+
+#: html/Admin/Elements/EditCustomFields:197
+msgid "Custom field deleted"
+msgstr "Uživatelská položka smazána"
+
+#: lib/RT/Ticket_Overlay.pm:3510
+msgid "Custom field not found"
+msgstr "Uživatelská položka nenalezena"
+
+#: lib/RT/CustomField_Overlay.pm:283
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr "Hodnota %1 nemůže být nalezena v uživatelské položce %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr "Hodnota uživatelské položky změněna z %1 na %2"
+
+#: lib/RT/CustomField_Overlay.pm:185
+msgid "Custom field value could not be deleted"
+msgstr "Hodnota uživatelské položky nemůže být smazána"
+
+#: lib/RT/CustomField_Overlay.pm:289
+msgid "Custom field value could not be found"
+msgstr "Hodnota uživatelské položky nemůže být nalezena"
+
+#: lib/RT/CustomField_Overlay.pm:183 lib/RT/CustomField_Overlay.pm:291
+msgid "Custom field value deleted"
+msgstr "Hodnota uživatelské položky smazána"
+
+#: lib/RT/Transaction_Overlay.pm:550
+msgid "CustomField"
+msgstr "Uživatelská položka"
+
+#: html/Ticket/Create.html:161 html/Ticket/Elements/ShowSummary:53 html/Ticket/Elements/Tabs:93 html/Ticket/ModifyAll.html:44
+msgid "Dates"
+msgstr "Datumy"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "pro"
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr "Implicitní vzor automatické odpovědi"
+
+#: etc/initialdata:207
+msgid "Default Autoresponse template"
+msgstr "Implicitní vzor automatické odpovědi"
+
+#: etc/initialdata:275
+msgid "Default admin comment template"
+msgstr "Implicitní vzor administrativního komentáře"
+
+#: etc/initialdata:257
+msgid "Default admin correspondence template"
+msgstr "Implicitní vzor administrativní korespondence"
+
+#: etc/initialdata:267
+msgid "Default correspondence template"
+msgstr "Implicitní korespondenční vzor"
+
+#: etc/initialdata:238
+msgid "Default transaction template"
+msgstr "Implicitní transakční vzor"
+
+#: lib/RT/Transaction_Overlay.pm:645
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr "Defaulní: %1/%2 změněno z %3 na %4"
+
+#: html/User/Delegation.html:25 html/User/Delegation.html:28
+msgid "Delegate rights"
+msgstr "Delegovat práva"
+
+#: lib/RT/System.pm:63
+msgid "Delegate specific rights which have been granted to you."
+msgstr "Delegovat specifická práva, která vám byla poskytnuta."
+
+#: lib/RT/System.pm:63
+msgid "DelegateRights"
+msgstr "Delegovat práva"
+
+#: html/User/Elements/Tabs:38
+msgid "Delegation"
+msgstr "Pověření"
+
+#: NOT FOUND IN SOURCE
+msgid "Delete"
+msgstr "Smazat"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "Delete tickets"
+msgstr "Mazat požadavky"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "DeleteTicket"
+msgstr "Smazat požadavek"
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr "Smazání tohoto objektu mohlo porušit referenční integritu"
+
+#: lib/RT/Queue_Overlay.pm:292
+msgid "Deleting this object would break referential integrity"
+msgstr "Smazání tohoto objektu by mohlo porušit referenční integritu"
+
+#: lib/RT/User_Overlay.pm:430
+msgid "Deleting this object would violate referential integrity"
+msgstr "Smazání tohoto objektu by mohlo narušit referenční integritu"
+
+#: html/Approvals/Elements/Approve:46
+msgid "Deny"
+msgstr "Zamítnout"
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/EditLinks:123 html/Ticket/Elements/EditLinks:47 html/Ticket/Elements/ShowDependencies:32 html/Ticket/Elements/ShowLinks:35
+msgid "Depended on by"
+msgstr "Je rekvizitou pro"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr "Závistlosti: \\n"
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:180 html/Ticket/Elements/EditLinks:119 html/Ticket/Elements/EditLinks:36 html/Ticket/Elements/ShowDependencies:25 html/Ticket/Elements/ShowLinks:27
+msgid "Depends on"
+msgstr "Závisející na"
+
+#: html/Elements/SelectSortOrder:35
+msgid "Descending"
+msgstr "Sestupně"
+
+#: html/SelfService/Create.html:75 html/Ticket/Create.html:119
+msgid "Describe the issue below"
+msgstr "Popište případ níže"
+
+#: html/Admin/Elements/AddCustomFieldValue:27 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/EditScrip:34 html/Admin/Elements/ModifyQueue:36 html/Admin/Elements/ModifyTemplate:36 html/Admin/Groups/Modify.html:49 html/Admin/Queues/Modify.html:48 html/Elements/SelectGroups:27 html/User/Groups/Modify.html:49
+msgid "Description"
+msgstr "Popis"
+
+#: html/SelfService/Elements/MyRequests:44
+msgid "Details"
+msgstr "Podrobnosti"
+
+#: html/Ticket/Elements/Tabs:85
+msgid "Display"
+msgstr "Zobrazit"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Display Access Control List"
+msgstr "Zobrazit přístupová práva"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Display Scrip templates for this queue"
+msgstr "Zobrazovat scrips vzory pro tuto frontu"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Display Scrips for this queue"
+msgstr "Zobrazovat scripy pro tuto frontu"
+
+#: html/Ticket/Elements/ShowHistory:35
+msgid "Display mode"
+msgstr "Režim zobrazení"
+
+#: html/SelfService/Display.html:25 html/SelfService/Display.html:29
+#. ($Ticket->id)
+msgid "Display ticket #%1"
+msgstr "Zobraz požadavek #%1"
+
+#: lib/RT/System.pm:54
+msgid "Do anything and everything"
+msgstr "Dělat cokoli a všechno"
+
+#: html/Elements/Refresh:30
+msgid "Don't refresh this page."
+msgstr "Neobčerstvovat tuto stránku."
+
+#: html/Search/Elements/PickRestriction:114
+msgid "Don't show search results"
+msgstr "Nezobrazit výsledky hledání"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "Download"
+msgstr "Stáhnout"
+
+#: html/Elements/SelectDateType:32 html/Ticket/Create.html:167 html/Ticket/Elements/EditDates:45 html/Ticket/Elements/ShowDates:43 lib/RT/Ticket_Overlay.pm:1171
+msgid "Due"
+msgstr "Termín dokončení"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr "Datum termínu dokončení '%1' nemůže být rozpoznán"
+
+#: bin/rt-commit-handler:754
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr "CHYBA: Nelze načíst požadavek '%1': %2.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit"
+msgstr "Upravit"
+
+#: html/Admin/Queues/CustomFields.html:45
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr "Upravit uživatelské položky pro %1"
+
+#: html/Ticket/ModifyLinks.html:36
+msgid "Edit Relationships"
+msgstr "Upravit relace"
+
+#: html/Admin/Queues/Templates.html:41
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr "Upravit vzory pro frontu %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr "Upravit scprips"
+
+#: html/Admin/Global/index.html:46
+msgid "Edit system templates"
+msgstr "Úprava systémových vzorů"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr "Upravit vzory pro %1"
+
+#: html/Admin/Elements/ModifyQueue:25 html/Admin/Queues/Modify.html:117
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr "Úprava konfigurace pro frontu %1"
+
+#: html/Admin/Elements/ModifyUser:25
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr "Úprava konfigurace pro uživatele %1"
+
+#: html/Admin/Elements/EditCustomField:74
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr "Úprava uživatelské položky %1"
+
+#: html/Admin/Groups/Members.html:32
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr "Úprava členství ve skupině %1"
+
+#: html/User/Groups/Members.html:129
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr "Úprava členství ve vlastní skupině %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr "Úprava vzoru %1"
+
+#: lib/RT/Ticket_Overlay.pm:2615 lib/RT/Ticket_Overlay.pm:2683
+msgid "Either base or target must be specified"
+msgstr "Zdroj či cíl musí být zadány"
+
+#: html/Admin/Users/Modify.html:53 html/Admin/Users/Prefs.html:46 html/Elements/SelectUsers:27 html/Ticket/Elements/AddWatchers:56 html/User/Prefs.html:42
+msgid "Email"
+msgstr "Email"
+
+#: lib/RT/User_Overlay.pm:188
+msgid "Email address in use"
+msgstr "Email adresa je použita"
+
+#: html/Admin/Elements/ModifyUser:42
+msgid "EmailAddress"
+msgstr "Email adresa"
+
+#: html/Admin/Elements/ModifyUser:54
+msgid "EmailEncoding"
+msgstr "Kódování emailu"
+
+#: html/Admin/Elements/EditCustomField:36
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr "Povolena (zrušením zatrhnutí zablokujete tuto uživatelskou položky)"
+
+#: html/Admin/Groups/Modify.html:53 html/User/Groups/Modify.html:53
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr "Povolena (zrušením zatrhnutí zablokujete tuto skupinu)"
+
+#: html/Admin/Queues/Modify.html:84
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr "Povoleno (zrušení zatrhnutí zablokuje tuto frontu)"
+
+#: html/Admin/Elements/EditCustomFields:99
+msgid "Enabled Custom Fields"
+msgstr "Povolené uživatelské položky"
+
+#: html/Admin/Queues/index.html:56
+msgid "Enabled Queues"
+msgstr "Povolené fronty"
+
+#: html/Admin/Elements/EditCustomField:90 html/Admin/Groups/Modify.html:117 html/Admin/Queues/Modify.html:138 html/Admin/Users/Modify.html:283 html/User/Groups/Modify.html:117
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr "Povolen stav %1"
+
+#: lib/RT/CustomField_Overlay.pm:361
+msgid "Enter multiple values"
+msgstr "Vyplnit více hodnot"
+
+#: lib/RT/CustomField_Overlay.pm:358
+msgid "Enter one value"
+msgstr "Vyplnit jednu hodnotu"
+
+#: html/Ticket/Elements/EditLinks:112
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "Zadejte požadavky či URI se nimiž požadavky svázat. Oddělte více položek mezerami."
+
+#: html/Elements/Login:29 html/SelfService/Error.html:25 html/SelfService/Error.html:26
+msgid "Error"
+msgstr "Chyba"
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr "Chyba v parametrech do Queue->AddWatcher"
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr "Chyba v parametrech do Queue->DelWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1356
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr "Chyba v parametrech do Ticket->AddWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1532
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr "Chyba v parametrech do Ticket->DelWatcher"
+
+#: etc/initialdata:20
+msgid "Everyone"
+msgstr "Kdokoli"
+
+#: bin/rt-crontool:194
+msgid "Example:"
+msgstr "Příklad:"
+
+#: html/Admin/Elements/ModifyUser:64
+msgid "ExternalAuthId"
+msgstr "Identifikátor externí autentizace"
+
+#: html/Admin/Elements/ModifyUser:58
+msgid "ExternalContactInfoId"
+msgstr "Identifikátor externího kontaktu"
+
+#: html/Admin/Users/Modify.html:73
+msgid "Extra info"
+msgstr "Doplňkové údaje"
+
+#: lib/RT/User_Overlay.pm:302
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr "Nepovedlo se nalézt uživatele 'Privilegované' pseudoskupiny."
+
+#: lib/RT/User_Overlay.pm:309
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr "Nepovedlo se nalézt uživatele 'Neprivilegované' pseudoskupiny"
+
+#: bin/rt-crontool:138
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr "Nepovedlo se nahrát modul %1. (%2)"
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "úno"
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr "Kon"
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:59 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "Koncová priorita"
+
+#: lib/RT/Ticket_Overlay.pm:1162
+msgid "FinalPriority"
+msgstr "Koncová priorita"
+
+#: html/Admin/Queues/People.html:61 html/Ticket/Elements/EditPeople:34
+msgid "Find group whose"
+msgstr "Najít skupiny které"
+
+#: html/Elements/Quicksearch:25
+msgid "Find new/open tickets"
+msgstr "Najít nové/otevřené požadavky"
+
+#: html/Admin/Queues/People.html:57 html/Admin/Users/index.html:46 html/Ticket/Elements/EditPeople:30
+msgid "Find people whose"
+msgstr "Najít ty, jejichž"
+
+#: html/Search/Listing.html:108
+msgid "Find tickets"
+msgstr "Nalézt požadavky"
+
+#: NOT FOUND IN SOURCE
+msgid "Finish Approval"
+msgstr "Záverečné schválení"
+
+#: html/Ticket/Elements/Tabs:58
+msgid "First"
+msgstr "První"
+
+#: html/Search/Listing.html:41
+msgid "First page"
+msgstr "První stránka"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr "Foo Bar Baz"
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr "Foo!"
+
+#: html/Search/Bulk.html:87
+msgid "Force change"
+msgstr "Vynutit změnu"
+
+#: html/Search/Listing.html:106
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr "Nalezen%quant(%1,,y,o) %numf(%1) %quant(%1,požadavek,požadavky,požadavků)"
+
+#: lib/RT/Interface/Web.pm:868
+msgid "Found Object"
+msgstr "Nalezen objekt"
+
+#: html/Admin/Elements/ModifyUser:44
+msgid "FreeformContactInfo"
+msgstr "Kontaktní údaje ve volné podobě"
+
+#: lib/RT/CustomField_Overlay.pm:38
+msgid "FreeformMultiple"
+msgstr "Volná forma vícenásobně"
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformSingle"
+msgstr "Volná formu jedinkrát"
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "pá"
+
+#: html/Ticket/Elements/ShowHistory:41 html/Ticket/Elements/ShowHistory:51
+msgid "Full headers"
+msgstr "Celé hlavičky"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr "Aktuální uživatel se získává z PGP podpisu\\n"
+
+#: lib/RT/Transaction_Overlay.pm:595
+#. ($New->Name)
+msgid "Given to %1"
+msgstr "Dán %1"
+
+#: html/Admin/Elements/Tabs:41 html/Admin/index.html:38
+msgid "Global"
+msgstr "Globální"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr "Globální Scrips"
+
+#: html/Admin/Elements/SelectTemplate:38
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr "Globální vzor: %1"
+
+#: html/Admin/Elements/EditCustomFields:75 html/Admin/Queues/People.html:59 html/Admin/Queues/People.html:63 html/Admin/Queues/index.html:44 html/Admin/Users/index.html:49 html/Ticket/Elements/EditPeople:32 html/Ticket/Elements/EditPeople:36 html/index.html:41
+msgid "Go!"
+msgstr "Spusť!"
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr "Správný PGP podpis od %1\\n"
+
+#: html/Search/Listing.html:50
+msgid "Goto page"
+msgstr "Přejít na stránku"
+
+#: html/Elements/GotoTicket:25 html/SelfService/Elements/GotoTicket:25
+msgid "Goto ticket"
+msgstr "Přejít na požadavek"
+
+#: html/Ticket/Elements/AddWatchers:46 html/User/Elements/DelegateRights:78
+msgid "Group"
+msgstr "Skupina"
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr "Skupina %1 %2: %3"
+
+#: html/Admin/Elements/GroupTabs:45 html/Admin/Elements/QueueTabs:57 html/Admin/Elements/SystemTabs:44 html/Admin/Global/index.html:55
+msgid "Group Rights"
+msgstr "Práva skupiny"
+
+#: lib/RT/Group_Overlay.pm:965
+msgid "Group already has member"
+msgstr "Skupina již má člena"
+
+#: html/Admin/Groups/Modify.html:77
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr "Skupina nemůže být založena: %1"
+
+#: lib/RT/Group_Overlay.pm:497
+msgid "Group created"
+msgstr "Skupina vytvořena"
+
+#: lib/RT/Group_Overlay.pm:1133
+msgid "Group has no such member"
+msgstr "Skupina nemá takového člena"
+
+#: lib/RT/Group_Overlay.pm:945 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1429 lib/RT/Ticket_Overlay.pm:1507
+msgid "Group not found"
+msgstr "Skupina nenalezena"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr "Skupina nenalezena.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr "Skupina neudána.\\n"
+
+#: html/Admin/Elements/SelectNewGroupMembers:35 html/Admin/Elements/Tabs:35 html/Admin/Groups/Members.html:64 html/Admin/Queues/People.html:83 html/Admin/index.html:32 html/User/Groups/Members.html:67
+msgid "Groups"
+msgstr "Skupiny"
+
+#: lib/RT/Group_Overlay.pm:971
+msgid "Groups can't be members of their members"
+msgstr "Skupiny nemohou být svými členy"
+
+#: lib/RT/Interface/CLI.pm:73 lib/RT/Interface/CLI.pm:73
+msgid "Hello!"
+msgstr "Ahoj!"
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr "Ahoj, %1"
+
+#: html/Ticket/Elements/ShowHistory:30 html/Ticket/Elements/Tabs:88
+msgid "History"
+msgstr "Historie"
+
+#: html/Admin/Elements/ModifyUser:68
+msgid "HomePhone"
+msgstr "Telefon domů"
+
+#: html/Elements/Tabs:46
+msgid "Homepage"
+msgstr "Domovská stránka"
+
+#: lib/RT/Base.pm:74
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr "Mám %quant(%1,míchačka,míchačky,míchaček)"
+
+#: NOT FOUND IN SOURCE
+msgid "I have [quant,_1,concrete mixer]."
+msgstr "I have [quant,_1,concrete mixer]."
+
+#msgstr "Mám [quant,_1,Míchačku na beton,Míchačky na beton,Míchaček na beton]."
+#: html/Ticket/Elements/ShowBasics:27 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr "Identifikátor"
+
+#: html/Admin/Users/Modify.html:44 html/User/Prefs.html:39
+msgid "Identity"
+msgstr "Identita"
+
+#: etc/upgrade/2.1.71:86
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr "Odmítni původce a zruš stávající schválení, bylo-li zamítnuto schválení"
+
+#: bin/rt-crontool:190
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr "Byl-li tento nástroj setgid, místní uživatel jej mohl použit k získaní administrativního přístupu k RT"
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "If you've updated anything above, be sure to"
+msgstr "Pokud jste změnili cokoli nahoře, nezapomeňte"
+
+#: lib/RT/Interface/Web.pm:860
+msgid "Illegal value for %1"
+msgstr "Neplatná hodnota pro %1"
+
+#: lib/RT/Interface/Web.pm:863
+msgid "Immutable field"
+msgstr "Neměnitelná položka"
+
+#: html/Admin/Elements/EditCustomFields:74
+msgid "Include disabled custom fields in listing."
+msgstr "Zahrnout do výpisu blokované uživatelské položky"
+
+#: html/Admin/Queues/index.html:43
+msgid "Include disabled queues in listing."
+msgstr "Zahrnout blokované fronty do výpisu."
+
+#: html/Admin/Users/index.html:47
+msgid "Include disabled users in search."
+msgstr "Zahrnout blokované uživatele do vyhledávání."
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr "Počáteční priorita"
+
+#: lib/RT/Ticket_Overlay.pm:1161 lib/RT/Ticket_Overlay.pm:1163
+msgid "InitialPriority"
+msgstr "Počáteční priorita"
+
+#: lib/RT/ScripAction_Overlay.pm:105
+msgid "Input error"
+msgstr "Chyba na vstupu"
+
+#: lib/RT/Ticket_Overlay.pm:3729
+msgid "Internal Error"
+msgstr "Vnitřní chyba"
+
+#: lib/RT/Record.pm:143
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr "Vnitřní chyba: %1"
+
+#: lib/RT/Group_Overlay.pm:644
+msgid "Invalid Group Type"
+msgstr "Neplatný typ skupiny"
+
+#: lib/RT/Principal_Overlay.pm:128
+msgid "Invalid Right"
+msgstr "Neplatné právo"
+
+#: lib/RT/Interface/Web.pm:865
+msgid "Invalid data"
+msgstr "Neplatná data"
+
+#: lib/RT/Ticket_Overlay.pm:438
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr "Neplatný vlastník. Použije se 'nobody'."
+
+#: lib/RT/Scrip_Overlay.pm:134 lib/RT/Template_Overlay.pm:251
+msgid "Invalid queue"
+msgstr "Neplatná fronta"
+
+#: lib/RT/ACE_Overlay.pm:244 lib/RT/ACE_Overlay.pm:253 lib/RT/ACE_Overlay.pm:259 lib/RT/ACE_Overlay.pm:270 lib/RT/ACE_Overlay.pm:275
+msgid "Invalid right"
+msgstr "Neplatné právo"
+
+#: lib/RT/Record.pm:118
+#. ($key)
+msgid "Invalid value for %1"
+msgstr "Neplatná hodnota pro %1"
+
+#: lib/RT/Ticket_Overlay.pm:3367
+msgid "Invalid value for custom field"
+msgstr "Neplatná hodnota pro uživatelskou položku"
+
+#: lib/RT/Ticket_Overlay.pm:345
+msgid "Invalid value for status"
+msgstr "Neplatná hodnota pro stav"
+
+#: bin/rt-crontool:191
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr "Je velmi důležité, aby neprivilegovaní uživatelé nemohli spustit tento nástroj."
+
+#: bin/rt-crontool:192
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr "Pro spuštění tohoto nástroje se doporučuje založení neprivilegovaného UNIX uživatele se správným skupinovým členstvím a přístupem do RT."
+
+#: bin/rt-crontool:163
+msgid "It takes several arguments:"
+msgstr "Používá několik parametrů:"
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr "Věci očekávající mé schválení"
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "led"
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "Join or leave this group"
+msgstr "Přidat se či odebrat z této skupiny"
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "čec"
+
+#: html/Ticket/Elements/Tabs:99
+msgid "Jumbo"
+msgstr "Maxi"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "čen"
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr "Klíčové slovo"
+
+#: html/Admin/Elements/ModifyUser:52
+msgid "Lang"
+msgstr "Jazyk"
+
+#: html/Ticket/Elements/Tabs:73
+msgid "Last"
+msgstr "Poslední"
+
+#: html/Ticket/Elements/EditDates:38 html/Ticket/Elements/ShowDates:39
+msgid "Last Contact"
+msgstr "Poslední kontakt"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Contacted"
+msgstr "Naposled kontaktován"
+
+#: html/Search/Elements/TicketHeader:41
+msgid "Last Notified"
+msgstr "Naposled upozorněn"
+
+#: html/Elements/SelectDateType:30
+msgid "Last Updated"
+msgstr "Naposled aktualizován"
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr "Zbývá"
+
+#: html/Admin/Users/Modify.html:83
+msgid "Let this user access RT"
+msgstr "Umožnit tomuto uživateli přístup k RT"
+
+#: html/Admin/Users/Modify.html:87
+msgid "Let this user be granted rights"
+msgstr "Umožnit dávat tomuto uživateli práva"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr "Vlastník omezen na %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr "Fronta omezena na %1 %2"
+
+#: lib/RT/Ticket_Overlay.pm:2697
+msgid "Link already exists"
+msgstr "Vazba již existuje"
+
+#: lib/RT/Ticket_Overlay.pm:2709
+msgid "Link could not be created"
+msgstr "Vazba nemůže být vytvořena"
+
+#: lib/RT/Ticket_Overlay.pm:2717 lib/RT/Ticket_Overlay.pm:2727
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr "Vazba vytvořena (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2638
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr "Vazba zrušena (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2644
+msgid "Link not found"
+msgstr "Vazba nenalezena"
+
+#: html/Ticket/ModifyLinks.html:25 html/Ticket/ModifyLinks.html:29
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr "Svázat požadavek #%1"
+
+#: html/Ticket/Elements/Tabs:97
+msgid "Links"
+msgstr "Vazby"
+
+#: html/Admin/Users/Modify.html:114 html/User/Prefs.html:85
+msgid "Location"
+msgstr "Umístění"
+
+#: lib/RT.pm:158
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr "Záznamový adresář %1 nenalezen nebo doň nemůže být zapisováno.\\ RT nemůže běžet."
+
+#: html/Elements/Header:57
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "Přihlášen jako %1"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:25 html/Elements/Login:34 html/Elements/Login:45
+msgid "Login"
+msgstr "Přihlásit"
+
+#: html/Elements/Header:54
+msgid "Logout"
+msgstr "Odhlásit"
+
+#: html/Search/Bulk.html:86
+msgid "Make Owner"
+msgstr "Nastavit vlastníka"
+
+#: html/Search/Bulk.html:102
+msgid "Make Status"
+msgstr "Nastavit stav"
+
+#: html/Search/Bulk.html:109
+msgid "Make date Due"
+msgstr "Nastavit datum termínu dokončení"
+
+#: html/Search/Bulk.html:110
+msgid "Make date Resolved"
+msgstr "Nastavit datum vyřešení"
+
+#: html/Search/Bulk.html:107
+msgid "Make date Started"
+msgstr "Nastavit datum, kdy začal"
+
+#: html/Search/Bulk.html:106
+msgid "Make date Starts"
+msgstr "Nastavit datum, kdy začne"
+
+#: html/Search/Bulk.html:108
+msgid "Make date Told"
+msgstr "Nastavit datum posledního kontaktu"
+
+#: html/Search/Bulk.html:99
+msgid "Make priority"
+msgstr "Nastavit prioritu"
+
+#: html/Search/Bulk.html:100
+msgid "Make queue"
+msgstr "Nastavit frontu"
+
+#: html/Search/Bulk.html:98
+msgid "Make subject"
+msgstr "Nastavit předmět"
+
+#: html/Admin/index.html:33
+msgid "Manage groups and group membership"
+msgstr "Správa skupin a členství v nich"
+
+#: html/Admin/index.html:39
+msgid "Manage properties and configuration which apply to all queues"
+msgstr "Správa vlastností a konfigurací platných ve všech frontách"
+
+#: html/Admin/index.html:36
+msgid "Manage queues and queue-specific properties"
+msgstr "Správa front a jim příslušných vlastností"
+
+#: html/Admin/index.html:30
+msgid "Manage users and passwords"
+msgstr "Správa uživatelů a hesel"
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "bře"
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "kvě"
+
+#: lib/RT/Group_Overlay.pm:982
+msgid "Member added"
+msgstr "Člen přidán"
+
+#: lib/RT/Group_Overlay.pm:1140
+msgid "Member deleted"
+msgstr "Člen odebrán"
+
+#: lib/RT/Group_Overlay.pm:1144
+msgid "Member not deleted"
+msgstr "Člen neodebrán"
+
+#: html/Elements/SelectLinkType:26
+msgid "Member of"
+msgstr "Člen"
+
+#: html/Admin/Elements/GroupTabs:42 html/User/Elements/GroupTabs:42
+msgid "Members"
+msgstr "Členové"
+
+#: lib/RT/Ticket_Overlay.pm:2843
+msgid "Merge Successful"
+msgstr "Sloučení úspěšné"
+
+#: lib/RT/Ticket_Overlay.pm:2804
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "Sloučení se nepodařilo. Nelze nastavit EffectiveId"
+
+#: html/Ticket/Elements/EditLinks:115
+msgid "Merge into"
+msgstr "Sloučit do"
+
+#: html/Ticket/Update.html:102
+msgid "Message"
+msgstr "Zpráva"
+
+#: lib/RT/Interface/Web.pm:867
+msgid "Missing a primary key?: %1"
+msgstr "Chybí primární klíč?: %1"
+
+#: html/Admin/Users/Modify.html:169 html/User/Prefs.html:54
+msgid "Mobile"
+msgstr "Mobilní telefon"
+
+#: html/Admin/Elements/ModifyUser:72
+msgid "MobilePhone"
+msgstr "Mobilní telefon"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify Access Control List"
+msgstr "Upravovat seznam přístupových práv"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Custom Field %1"
+msgstr "Upravit uživatelskou položku %1"
+
+#: html/Admin/Global/CustomFields.html:44 html/Admin/Global/index.html:51
+msgid "Modify Custom Fields which apply to all queues"
+msgstr "Úprava uživatelských položek pro všechny fronty"
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "Modify Scrip templates for this queue"
+msgstr "Upravovat vzory scripů této fronty"
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "Modify Scrips for this queue"
+msgstr "Upravovat scripů této fronty"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr "Upravovat vzor %1"
+
+#: html/Admin/Queues/CustomField.html:45
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr "Upravovat uživatelskou položku pro frontu %1"
+
+#: html/Admin/Global/CustomField.html:53
+msgid "Modify a CustomField which applies to all queues"
+msgstr "Upravovat uživatelskou položku pro všechny fronty"
+
+#: html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr "Upravovat scrip pro frontu %1"
+
+#: html/Admin/Global/Scrip.html:48
+msgid "Modify a scrip which applies to all queues"
+msgstr "Upravovat scrip platný ve všech frontách"
+
+#: html/Ticket/ModifyDates.html:25 html/Ticket/ModifyDates.html:29
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr "Upravit datumy pro #%1"
+
+#: html/Ticket/ModifyDates.html:35
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr "Úprav datumů pro požadavek # %1"
+
+#: html/Admin/Global/GroupRights.html:25 html/Admin/Global/GroupRights.html:28 html/Admin/Global/index.html:56
+msgid "Modify global group rights"
+msgstr "Úprava globálních skupinových práv"
+
+#: html/Admin/Global/GroupRights.html:33
+msgid "Modify global group rights."
+msgstr "Úprava globálních skupinových práv."
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr "Úprava globálních scrips"
+
+#: html/Admin/Global/UserRights.html:25 html/Admin/Global/UserRights.html:28 html/Admin/Global/index.html:60
+msgid "Modify global user rights"
+msgstr "Úprava globálních uživatelských práv"
+
+#: html/Admin/Global/UserRights.html:33
+msgid "Modify global user rights."
+msgstr "Úprava globálních uživatelských práv."
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "Modify group metadata or delete group"
+msgstr "Upravovat metadata skupiny nebo smazat skupinu"
+
+#: html/Admin/Groups/GroupRights.html:25 html/Admin/Groups/GroupRights.html:29 html/Admin/Groups/GroupRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr "Úprava skupinových práv pro %1"
+
+#: html/Admin/Queues/GroupRights.html:25 html/Admin/Queues/GroupRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr "Úprava skupinových práv pro frontu %1"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Modify membership roster for this group"
+msgstr "Upravovat seznam členů pro tuto skupinu"
+
+#: lib/RT/System.pm:61
+msgid "Modify one's own RT account"
+msgstr "Upravovat vlastní RT účet"
+
+#: html/Admin/Queues/People.html:25 html/Admin/Queues/People.html:29
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr "Úprava uživatelů fronty %1"
+
+#: html/Ticket/ModifyPeople.html:25 html/Ticket/ModifyPeople.html:29 html/Ticket/ModifyPeople.html:35
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr "Úprava uživatelů souvisejících s požadavkem #%1"
+
+#: html/Admin/Queues/Scrips.html:44
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr "Úprava scrips pro frontu %1"
+
+#: html/Admin/Global/Scrips.html:44 html/Admin/Global/index.html:42
+msgid "Modify scrips which apply to all queues"
+msgstr "Upravovat scripy platné ve všech frontách"
+
+#: html/Admin/Global/Template.html:25 html/Admin/Global/Template.html:30 html/Admin/Global/Template.html:81 html/Admin/Queues/Template.html:78
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr "Úprava vzoru %1"
+
+#: html/Admin/Global/Templates.html:44
+msgid "Modify templates which apply to all queues"
+msgstr "Upravit vzory pro všechny fronty"
+
+#: html/Admin/Groups/Modify.html:87 html/User/Groups/Modify.html:86
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr "Úprava skupiny %1"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Modify the queue watchers"
+msgstr "Upravovat pozorovatele fronty"
+
+#: html/Admin/Users/Modify.html:236
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr "Úprava uživatele %1"
+
+#: html/Ticket/ModifyAll.html:37
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "Úprava požadavku # %1"
+
+#: html/Ticket/Modify.html:25 html/Ticket/Modify.html:28 html/Ticket/Modify.html:34
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "Úprava požadavku #%1"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Modify tickets"
+msgstr "Upravovat požadavky"
+
+#: html/Admin/Groups/UserRights.html:25 html/Admin/Groups/UserRights.html:29 html/Admin/Groups/UserRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr "Úprava uživatelských práv pro skupinu %1"
+
+#: html/Admin/Queues/UserRights.html:25 html/Admin/Queues/UserRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr "Úprava skupinových práv pro frontu %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr "Úprava pozorovatelů fronty '%1'"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyACL"
+msgstr "Upravovat seznam přístupových práv"
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "ModifyOwnMembership"
+msgstr "Upravovat členství ve skupině"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "ModifyQueueWatchers"
+msgstr "Upravovat pozorovale fronty"
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "ModifyScrips"
+msgstr "Upravovat scripy"
+
+#: lib/RT/System.pm:61
+msgid "ModifySelf"
+msgstr "Upravovat sebe"
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "ModifyTemplate"
+msgstr "Upravovat vzor"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "ModifyTicket"
+msgstr "Upravovat požadavek"
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "po"
+
+#: html/Ticket/Elements/ShowRequestor:42
+#. ($name)
+msgid "More about %1"
+msgstr "Více o %1"
+
+#: html/Admin/Elements/EditCustomFields:61
+msgid "Move down"
+msgstr "Dát níže"
+
+#: html/Admin/Elements/EditCustomFields:53
+msgid "Move up"
+msgstr "Dát výše"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:27
+msgid "Multiple"
+msgstr "Vícenásobná"
+
+#: lib/RT/User_Overlay.pm:179
+msgid "Must specify 'Name' attribute"
+msgstr "Nutno zadat atribut 'Jméno'"
+
+#: NOT FOUND IN SOURCE
+msgid "My Approvals"
+msgstr "Mnou schválené"
+
+#: html/Approvals/index.html:25 html/Approvals/index.html:26
+msgid "My approvals"
+msgstr "Mnou schválené"
+
+#: html/Admin/Elements/AddCustomFieldValue:26 html/Admin/Elements/EditCustomField:32 html/Admin/Elements/ModifyTemplate:28 html/Admin/Elements/ModifyUser:30 html/Admin/Groups/Modify.html:44 html/Elements/SelectGroups:26 html/Elements/SelectUsers:28 html/User/Groups/Modify.html:44
+msgid "Name"
+msgstr "Jméno"
+
+#: lib/RT/User_Overlay.pm:186
+msgid "Name in use"
+msgstr "Jméno je použito"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr "Je třeba schválení systémového správce"
+
+#: html/Ticket/Elements/ShowDates:52
+msgid "Never"
+msgstr "Nikdy"
+
+#: html/Elements/Quicksearch:30
+msgid "New"
+msgstr "Nové"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:93 html/User/Prefs.html:65
+msgid "New Password"
+msgstr "Nové heslo"
+
+#: etc/initialdata:311 etc/upgrade/2.1.71:16
+msgid "New Pending Approval"
+msgstr "Nová probíhající schválení"
+
+#: html/Ticket/Elements/EditLinks:111
+msgid "New Relationships"
+msgstr "Nové relace"
+
+#: html/Ticket/Elements/Tabs:36
+msgid "New Search"
+msgstr "Nové vyhledávání"
+
+#: html/Admin/Global/CustomField.html:41 html/Admin/Global/CustomFields.html:39 html/Admin/Queues/CustomField.html:52 html/Admin/Queues/CustomFields.html:40
+msgid "New custom field"
+msgstr "Vytvořit uživatelskou položku"
+
+#: html/Admin/Elements/GroupTabs:54 html/User/Elements/GroupTabs:52
+msgid "New group"
+msgstr "Založit skupinu"
+
+#: html/SelfService/Prefs.html:32
+msgid "New password"
+msgstr "Nové heslo"
+
+#: lib/RT/User_Overlay.pm:639
+msgid "New password notification sent"
+msgstr "Oznámení nového hesla zasláno"
+
+#: html/Admin/Elements/QueueTabs:70
+msgid "New queue"
+msgstr "Vytvoření fronty"
+
+#: html/SelfService/Elements/Tabs:63
+msgid "New request"
+msgstr "Nový požadavek"
+
+#: html/Admin/Elements/SelectRights:42
+msgid "New rights"
+msgstr "Nová práva"
+
+#: html/Admin/Global/Scrip.html:40 html/Admin/Global/Scrips.html:39 html/Admin/Queues/Scrip.html:43 html/Admin/Queues/Scrips.html:53
+msgid "New scrip"
+msgstr "Vytovření scripu"
+
+#: NOT FOUND IN SOURCE
+msgid "New search"
+msgstr "Nové vyhledání"
+
+#: html/Admin/Global/Template.html:60 html/Admin/Global/Templates.html:39 html/Admin/Queues/Template.html:58 html/Admin/Queues/Templates.html:46
+msgid "New template"
+msgstr "Vytvořit vzor"
+
+#: lib/RT/Ticket_Overlay.pm:2771
+msgid "New ticket doesn't exist"
+msgstr "Nový požadavek neexistuje"
+
+#: html/Admin/Elements/UserTabs:52
+msgid "New user"
+msgstr "Vytvořit uživatele"
+
+#: html/Admin/Elements/CreateUserCalled:26
+msgid "New user called"
+msgstr "Nový uživatel jména"
+
+#: html/Admin/Queues/People.html:55 html/Ticket/Elements/EditPeople:29
+msgid "New watchers"
+msgstr "Nový pozorovatel"
+
+#: html/Admin/Users/Prefs.html:42
+msgid "New window setting"
+msgstr "Nové nastavení okna"
+
+#: html/Ticket/Elements/Tabs:69
+msgid "Next"
+msgstr "Další"
+
+#: html/Search/Listing.html:48
+msgid "Next page"
+msgstr "Další stránka"
+
+#: html/Admin/Elements/ModifyUser:50
+msgid "NickName"
+msgstr "Přezdívka"
+
+#: html/Admin/Users/Modify.html:63 html/User/Prefs.html:46
+msgid "Nickname"
+msgstr "Přezdívka"
+
+#: html/Admin/Elements/EditCustomField:73 html/Admin/Elements/EditCustomFields:105
+msgid "No CustomField"
+msgstr "Žádná uživatelská položka"
+
+#: html/Admin/Groups/GroupRights.html:84 html/Admin/Groups/UserRights.html:71
+msgid "No Group defined"
+msgstr "Nedefinována žádná skupina"
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:68
+msgid "No Queue defined"
+msgstr "Nedefinována žádná fronta"
+
+#: bin/rt-crontool:56
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr "Žádný uživatel RT nenalezen. Prosím poraďte se se správcem RT.\\n"
+
+#: html/Admin/Global/Template.html:79 html/Admin/Queues/Template.html:76
+msgid "No Template"
+msgstr "Žádný vzor"
+
+#: bin/rt-commit-handler:764
+msgid "No Ticket specified. Aborting ticket "
+msgstr "Neudán požadavek. Přerušuje se požadavek "
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr "Neudán požadavek. Přerušují se úpravy požadavku\\n\\n"
+
+#: html/Approvals/Elements/Approve:47
+msgid "No action"
+msgstr "bez akce"
+
+#: lib/RT/Interface/Web.pm:862
+msgid "No column specified"
+msgstr "Neudán sloupec"
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr "Příkaz nenalezen\\n"
+
+#: html/Elements/ViewUser:36 html/Ticket/Elements/ShowRequestor:45
+msgid "No comment entered about this user"
+msgstr "Poznámky k tomuto uživateli neudány"
+
+#: lib/RT/Ticket_Overlay.pm:2189 lib/RT/Ticket_Overlay.pm:2257
+msgid "No correspondence attached"
+msgstr "Žádná připojená korespondence"
+
+#: lib/RT/Action/Generic.pm:150 lib/RT/Condition/Generic.pm:176 lib/RT/Search/ActiveTicketsInQueue.pm:56 lib/RT/Search/Generic.pm:113
+#. (ref $self)
+msgid "No description for %1"
+msgstr "Pro %1 není popis"
+
+#: lib/RT/Users_Overlay.pm:151
+msgid "No group specified"
+msgstr "Neudána skupina"
+
+#: lib/RT/User_Overlay.pm:857
+msgid "No password set"
+msgstr "Heslo nenastaveno"
+
+#: lib/RT/Queue_Overlay.pm:259
+msgid "No permission to create queues"
+msgstr "Nedostatek práv k vytváření front"
+
+#: lib/RT/Ticket_Overlay.pm:341
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr "Nedostatek práv k vytváření požadavků ve frontě '%1'"
+
+#: lib/RT/User_Overlay.pm:151
+msgid "No permission to create users"
+msgstr "Nedostatek práv k vytváření uživatelů"
+
+#: html/SelfService/Display.html:174
+msgid "No permission to display that ticket"
+msgstr "Nedostatek práv k zobrazení tohoto požadavku"
+
+#: html/SelfService/Update.html:55
+msgid "No permission to view update ticket"
+msgstr "Nedostatek práv k zobrazení aktualizace požadavku"
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1488
+msgid "No principal specified"
+msgstr "Nezadán uživatel"
+
+#: html/Admin/Queues/People.html:154 html/Admin/Queues/People.html:164
+msgid "No principals selected."
+msgstr "Nevybráni uživatelé."
+
+#: html/Admin/Queues/index.html:35
+msgid "No queues matching search criteria found."
+msgstr "Nenalezeny žádné fronty odpovídající vyhledávací podmínce."
+
+#: html/Admin/Elements/SelectRights:81
+msgid "No rights found"
+msgstr "Práva nenalezena"
+
+#: html/Admin/Elements/SelectRights:33
+msgid "No rights granted."
+msgstr "Nepřidělena žádná práva."
+
+#: html/Search/Bulk.html:149
+msgid "No search to operate on."
+msgstr "Bez vyhledání nelze pracovat."
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr "Neudán identifikátor požadavku"
+
+#: lib/RT/Transaction_Overlay.pm:480 lib/RT/Transaction_Overlay.pm:518
+msgid "No transaction type specified"
+msgstr "Neudán typ transakce"
+
+#: html/Admin/Users/index.html:36
+msgid "No users matching search criteria found."
+msgstr "Nenalezeni uživatelé odpovídající vyhledávací podmínce"
+
+#: bin/rt-commit-handler:644
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr "Nenalezen platný uživatel RT. Ovladač RT CVS uvolněn. Prosím poraďte se se svým správcem RT.\\n"
+
+#: lib/RT/Interface/Web.pm:859
+msgid "No value sent to _Set!\\n"
+msgstr "Žádná z hodnot nanastavena na _Set!\\n"
+
+#: html/Search/Elements/TicketRow:37
+msgid "Nobody"
+msgstr "Nikdo"
+
+#: lib/RT/Interface/Web.pm:864
+msgid "Nonexistant field?"
+msgstr "Neexistující položka"
+
+#: html/Elements/Login:99
+msgid "Not logged in"
+msgstr "Nepřihlášen"
+
+#: html/Elements/Header:59 html/SelfService/Elements/Header:58
+msgid "Not logged in."
+msgstr "Nepřihlášen."
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "Nenastaven"
+
+#: html/NoAuth/Reminder.html:27
+msgid "Not yet implemented."
+msgstr "Zatím neimplementováno."
+
+#: html/Admin/Groups/Rights.html:25
+msgid "Not yet implemented...."
+msgstr "Zatím neimplementováno..."
+
+#: html/Approvals/Elements/Approve:50
+msgid "Notes"
+msgstr "Poznámky"
+
+#: lib/RT/User_Overlay.pm:642
+msgid "Notification could not be sent"
+msgstr "Upozornění nemůže být zasláno"
+
+#: etc/initialdata:94
+msgid "Notify AdminCcs"
+msgstr "Zaslat všem AdminCc"
+
+#: etc/initialdata:90
+msgid "Notify AdminCcs as Comment"
+msgstr "Zaslat všem AdminCc jako komentář"
+
+#: etc/initialdata:121
+msgid "Notify Other Recipients"
+msgstr "Zaslat ostatním příjemcům"
+
+#: etc/initialdata:117
+msgid "Notify Other Recipients as Comment"
+msgstr "Zaslat ostatním příjemcům jako komentář"
+
+#: etc/initialdata:86
+msgid "Notify Owner"
+msgstr "Zaslat vlastníkovi"
+
+#: etc/initialdata:82
+msgid "Notify Owner as Comment"
+msgstr "Zaslat vlastníkovi jako komentář"
+
+#: etc/initialdata:313 etc/upgrade/2.1.71:17
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr "Zaslat vlastníkům a všem AdminCc nové případy očekávající jejich schválení"
+
+#: etc/initialdata:78
+msgid "Notify Requestors"
+msgstr "Zaslat žadatelům"
+
+#: etc/initialdata:104
+msgid "Notify Requestors and Ccs"
+msgstr "Zaslat žadatelům a všem Cc"
+
+#: etc/initialdata:99
+msgid "Notify Requestors and Ccs as Comment"
+msgstr "Zaslat žadatelům a všem Cc jako komentář"
+
+#: etc/initialdata:113
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr "Zaslat žadatelům, všem Cc a všem AdminCc"
+
+#: etc/initialdata:109
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr "Zaslat žadatelům, včem Cc a včem AdminCc jako komentář"
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "lis"
+
+#: lib/RT/Record.pm:157
+msgid "Object could not be created"
+msgstr "Objekt nemůže být vytvořen"
+
+#: lib/RT/Record.pm:176
+msgid "Object created"
+msgstr "Objekt vytvořen"
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "říj"
+
+#: html/Elements/SelectDateRelation:35
+msgid "On"
+msgstr "Dne"
+
+#: etc/initialdata:155
+msgid "On Comment"
+msgstr "Při komentáři"
+
+#: etc/initialdata:148
+msgid "On Correspond"
+msgstr "Při korespondenci"
+
+#: etc/initialdata:137
+msgid "On Create"
+msgstr "Při založení"
+
+#: etc/initialdata:169
+msgid "On Owner Change"
+msgstr "Při změně vlastníka"
+
+#: etc/initialdata:177
+msgid "On Queue Change"
+msgstr "Při změně fronty"
+
+#: etc/initialdata:183
+msgid "On Resolve"
+msgstr "Při vyřešení"
+
+#: etc/initialdata:161
+msgid "On Status Change"
+msgstr "Při změně stavu"
+
+#: etc/initialdata:142
+msgid "On Transaction"
+msgstr "Při transakci"
+
+#: html/Approvals/Elements/PendingMyApproval:50
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr "Zobrazit jen schvalování pro požadavky založené po %1"
+
+#: html/Approvals/Elements/PendingMyApproval:48
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr "Zobrazit jen schvalování pro požadavky založení před %quant(%1)"
+
+#: html/Elements/Quicksearch:31
+msgid "Open"
+msgstr "Otevřené"
+
+#: html/Ticket/Elements/Tabs:136
+msgid "Open it"
+msgstr "Otevřít"
+
+#: html/SelfService/Elements/Tabs:57
+msgid "Open requests"
+msgstr "Otevřené požadavky"
+
+#: html/Admin/Users/Prefs.html:41
+msgid "Open tickets (from listing) in a new window"
+msgstr "Otevřít požadavky (ze seznamu) v novém okně"
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in another window"
+msgstr "Otevřít požadavky (ze seznamu) v jiném okně"
+
+#: etc/initialdata:133
+msgid "Open tickets on correspondence"
+msgstr "Otevřít požadavky při korespondenci"
+
+#: html/Search/Elements/PickRestriction:101
+msgid "Ordering and sorting"
+msgstr "Řazení a třídění"
+
+#: html/Admin/Elements/ModifyUser:46 html/Admin/Users/Modify.html:117 html/Elements/SelectUsers:29 html/User/Prefs.html:86
+msgid "Organization"
+msgstr "Organizace"
+
+#: html/Approvals/Elements/Approve:34
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr "Původní požadavek: #%1"
+
+#: html/Admin/Elements/ModifyQueue:55 html/Admin/Queues/Modify.html:69
+msgid "Over time, priority moves toward"
+msgstr "Časem se priorita posouvá k"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Own tickets"
+msgstr "Vlastnit požadavky"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "OwnTicket"
+msgstr "Vlastnit požadavek"
+
+#: etc/initialdata:38 html/Elements/MyRequests:32 html/SelfService/Elements/MyRequests:30 html/Ticket/Create.html:48 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/EditPeople:44 html/Ticket/Elements/ShowPeople:27 html/Ticket/Update.html:63 lib/RT/ACE_Overlay.pm:86 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "Vlastník"
+
+#: lib/RT/Ticket_Overlay.pm:3004
+#. ($OldOwnerObj->Name,  $NewOwnerObj->Name)
+msgid "Owner changed from %1 to %2"
+msgstr "Vlastník změněn z %1 na %2"
+
+#: lib/RT/Transaction_Overlay.pm:584
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr "Vlastník nuceně změněn z %1 na %2"
+
+#: html/Search/Elements/PickRestriction:31
+msgid "Owner is"
+msgstr "Vlastník"
+
+#: html/Admin/Users/Modify.html:174 html/User/Prefs.html:56
+msgid "Pager"
+msgstr "Pager"
+
+#: html/Admin/Elements/ModifyUser:74
+msgid "PagerPhone"
+msgstr "Číslo pageru"
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/EditLinks:127 html/Ticket/Elements/EditLinks:58 html/Ticket/Elements/ShowLinks:43
+msgid "Parents"
+msgstr "Rodiče"
+
+#: html/Elements/Login:43 html/User/Prefs.html:61
+msgid "Password"
+msgstr "Heslo"
+
+#: html/NoAuth/Reminder.html:25
+msgid "Password Reminder"
+msgstr "Připomínač hesel"
+
+#: lib/RT/User_Overlay.pm:168 lib/RT/User_Overlay.pm:860
+msgid "Password too short"
+msgstr "Heslo příliš krátké"
+
+#: html/Admin/Users/Modify.html:291 html/User/Prefs.html:172
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "Heslo: %1"
+
+#: html/Ticket/Elements/ShowSummary:43 html/Ticket/Elements/Tabs:96 html/Ticket/ModifyAll.html:51
+msgid "People"
+msgstr "Uživatelé"
+
+#: etc/initialdata:126
+msgid "Perform a user-defined action"
+msgstr "Provedení uživatelem definované akce"
+
+#: lib/RT/ACE_Overlay.pm:231 lib/RT/ACE_Overlay.pm:237 lib/RT/ACE_Overlay.pm:563 lib/RT/ACE_Overlay.pm:573 lib/RT/ACE_Overlay.pm:583 lib/RT/ACE_Overlay.pm:648 lib/RT/CurrentUser.pm:83 lib/RT/CurrentUser.pm:92 lib/RT/CustomField_Overlay.pm:445 lib/RT/CustomField_Overlay.pm:451 lib/RT/Group_Overlay.pm:1095 lib/RT/Group_Overlay.pm:1099 lib/RT/Group_Overlay.pm:1108 lib/RT/Group_Overlay.pm:1159 lib/RT/Group_Overlay.pm:1163 lib/RT/Group_Overlay.pm:1169 lib/RT/Group_Overlay.pm:426 lib/RT/Group_Overlay.pm:518 lib/RT/Group_Overlay.pm:596 lib/RT/Group_Overlay.pm:604 lib/RT/Group_Overlay.pm:701 lib/RT/Group_Overlay.pm:705 lib/RT/Group_Overlay.pm:711 lib/RT/Group_Overlay.pm:904 lib/RT/Group_Overlay.pm:908 lib/RT/Group_Overlay.pm:921 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:126 lib/RT/Scrip_Overlay.pm:137 lib/RT/Scrip_Overlay.pm:197 lib/RT/Scrip_Overlay.pm:430 lib/RT/Template_Overlay.pm:284 lib/RT/Template_Overlay.pm:88 lib/RT/Template_Overlay.pm:94 lib/RT/Ticket_Overlay.pm:1341 lib/RT/Ticket_Overlay.pm:1351 lib/RT/Ticket_Overlay.pm:1365 lib/RT/Ticket_Overlay.pm:1518 lib/RT/Ticket_Overlay.pm:1527 lib/RT/Ticket_Overlay.pm:1540 lib/RT/Ticket_Overlay.pm:1875 lib/RT/Ticket_Overlay.pm:2013 lib/RT/Ticket_Overlay.pm:2177 lib/RT/Ticket_Overlay.pm:2244 lib/RT/Ticket_Overlay.pm:2596 lib/RT/Ticket_Overlay.pm:2668 lib/RT/Ticket_Overlay.pm:2762 lib/RT/Ticket_Overlay.pm:2777 lib/RT/Ticket_Overlay.pm:2910 lib/RT/Ticket_Overlay.pm:3139 lib/RT/Ticket_Overlay.pm:3337 lib/RT/Ticket_Overlay.pm:3499 lib/RT/Ticket_Overlay.pm:3551 lib/RT/Ticket_Overlay.pm:3716 lib/RT/Transaction_Overlay.pm:468 lib/RT/Transaction_Overlay.pm:475 lib/RT/Transaction_Overlay.pm:504 lib/RT/Transaction_Overlay.pm:511 lib/RT/User_Overlay.pm:1334 lib/RT/User_Overlay.pm:562 lib/RT/User_Overlay.pm:597 lib/RT/User_Overlay.pm:853 lib/RT/User_Overlay.pm:941
+msgid "Permission Denied"
+msgstr "Přístup nepovolen"
+
+#: html/User/Elements/Tabs:35
+msgid "Personal Groups"
+msgstr "Osobní skupiny"
+
+#: html/User/Groups/index.html:30 html/User/Groups/index.html:40
+msgid "Personal groups"
+msgstr "Vlastní skupiny"
+
+#: html/User/Elements/DelegateRights:37
+msgid "Personal groups:"
+msgstr "Vlastní skupiny:"
+
+#: html/Admin/Users/Modify.html:156 html/User/Prefs.html:49
+msgid "Phone numbers"
+msgstr "Čísla telefonů"
+
+#: html/Admin/Users/Rights.html:25
+msgid "Placeholder"
+msgstr "Zábor místa"
+
+#: html/Elements/Header:52 html/Elements/Tabs:55 html/SelfService/Prefs.html:25 html/User/Prefs.html:25 html/User/Prefs.html:28
+msgid "Preferences"
+msgstr "Nastavení"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr "Nastavení"
+
+#: lib/RT/Action/Generic.pm:160
+msgid "Prepare Stubbed"
+msgstr "Prepare v zárodku"
+
+#: html/Ticket/Elements/Tabs:61
+msgid "Prev"
+msgstr "Předchozí"
+
+#: html/Search/Listing.html:44
+msgid "Previous page"
+msgstr "Předchozí stránka"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr "Pri"
+
+#: lib/RT/ACE_Overlay.pm:133 lib/RT/ACE_Overlay.pm:208 lib/RT/ACE_Overlay.pm:552
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr "Uživatel %1 nenalezen."
+
+#: html/Search/Elements/PickRestriction:54 html/SelfService/Display.html:76 html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:54 html/Ticket/Elements/ShowBasics:39 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "Priorita"
+
+#: html/Admin/Elements/ModifyQueue:51 html/Admin/Queues/Modify.html:65
+msgid "Priority starts at"
+msgstr "Priorita začíná na"
+
+#: etc/initialdata:25
+msgid "Privileged"
+msgstr "Privilegovaný"
+
+#: html/Admin/Users/Modify.html:271 html/User/Prefs.html:163
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr "Privilegovaný stav: %1"
+
+#: html/Admin/Users/index.html:62
+msgid "Privileged users"
+msgstr "Privilegovaní uživatelé"
+
+#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59
+msgid "Pseudogroup for internal use"
+msgstr "Pseudo skupina pro vnitřní použití"
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Elements/Quicksearch:29 html/Search/Elements/PickRestriction:46 html/SelfService/Create.html:35 html/SelfService/Display.html:68 html/Ticket/Create.html:38 html/Ticket/Elements/EditBasics:64 html/Ticket/Elements/ShowBasics:43 html/User/Elements/DelegateRights:80 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "Fronta"
+
+#: html/Admin/Queues/CustomField.html:42 html/Admin/Queues/Scrip.html:50 html/Admin/Queues/Scrips.html:46 html/Admin/Queues/Templates.html:43
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr "Fronta %1 nenalezena"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr "Fronta '%1' nenalezena\\n"
+
+#: html/Admin/Elements/ModifyQueue:31 html/Admin/Queues/Modify.html:43
+msgid "Queue Name"
+msgstr "Název fronty"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr "Scripy fronty"
+
+#: lib/RT/Queue_Overlay.pm:263
+msgid "Queue already exists"
+msgstr "Fronta již existuje"
+
+#: lib/RT/Queue_Overlay.pm:272 lib/RT/Queue_Overlay.pm:278
+msgid "Queue could not be created"
+msgstr "Fronta nemůže být vytvořena"
+
+#: html/Ticket/Create.html:209
+msgid "Queue could not be loaded."
+msgstr "Fronta nemůže být načtena."
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:282
+msgid "Queue created"
+msgstr "Fronta vytvořena"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue is not specified."
+msgstr "Není zadána fronta."
+
+#: html/SelfService/Display.html:129
+msgid "Queue not found"
+msgstr "Fronta nenalezena"
+
+#: html/Admin/Elements/Tabs:38 html/Admin/index.html:35
+msgid "Queues"
+msgstr "Fronty"
+
+#: html/Elements/Login:34
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr "RT %1"
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr "RT %1 pro %2"
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr "RT %1 od <a href=\"http://bestpractical.com\">Best Practival Solutions, LLC</a>."
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: html/Admin/index.html:25 html/Admin/index.html:26
+msgid "RT Administration"
+msgstr "Správa RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr "Autentizační chyba RT."
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr "RT Bounce: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr "Konfigurační chyba RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr "Kritická chyba RT. Zpráva nezaznamenána!"
+
+#: html/Elements/Error:41 html/SelfService/Error.html:41
+msgid "RT Error"
+msgstr "Chyba RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr "RT přijal poštu (%1) od sebe samého."
+
+#: html/SelfService/Closed.html:25
+msgid "RT Self Service / Closed Tickets"
+msgstr "RT Samoobsluha / Uzavřené požadavky"
+
+#: html/index.html:25 html/index.html:28
+msgid "RT at a glance"
+msgstr "RT v celé své záři"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr "RT vás nemůže autentizovat"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr "RT nemůže nalézt žadatele přes hledání v externí databázi"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr "RT nemůže nalézt frontu: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr "RT nemůže ověřit tento PGP podpis. \\n"
+
+#: html/Elements/PageLayout:26
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr "RT pro %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr "RT pro %1: %2"
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr "RT zpracoval vaše příkazy"
+
+#: html/Elements/Login:83
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT je &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;. Šířeno pod <a href=\"http://www.gnu.org/copyleft/gpl.html\">verzí 2 GNU General Public License.</a>"
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr "RT bere tuto zprávu jako bounce"
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr "RT zpracuje tuto zprávu tak, jako by byla nepodepsaná.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr "Emailový příkazový režim RT vyžaduje PGP autentizaci. Nepodepsal jste vaši zprávu nebo váš podpis nemůže být ověřen."
+
+#: html/Admin/Users/Modify.html:58 html/Admin/Users/Prefs.html:52 html/User/Prefs.html:44
+msgid "Real Name"
+msgstr "Skutečné jméno"
+
+#: html/Admin/Elements/ModifyUser:48
+msgid "RealName"
+msgstr "Skutečné jméno"
+
+#: html/Ticket/Create.html:185 html/Ticket/Elements/EditLinks:139 html/Ticket/Elements/EditLinks:94 html/Ticket/Elements/ShowLinks:63
+msgid "Referred to by"
+msgstr "Je odkazem z"
+
+#: html/Elements/SelectLinkType:28 html/Ticket/Create.html:184 html/Ticket/Elements/EditLinks:135 html/Ticket/Elements/EditLinks:80 html/Ticket/Elements/ShowLinks:55
+msgid "Refers to"
+msgstr "Odkazuje na"
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr "Zjemnit"
+
+#: html/Search/Elements/PickRestriction:27
+msgid "Refine search"
+msgstr "Zjemnit vyhledání"
+
+#: html/Elements/Refresh:36
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "Obnovit tuto stránku %quant(%1,každou,každé,každých) %numf(%1) %quant(%1,minutu,minuty,minut)."
+
+#??? quant
+#: html/Ticket/Create.html:174 html/Ticket/Elements/ShowSummary:60 html/Ticket/ModifyAll.html:57
+msgid "Relationships"
+msgstr "Vztahy"
+
+#: html/Search/Bulk.html:93
+msgid "Remove AdminCc"
+msgstr "Odstranit AdminCc"
+
+#: html/Search/Bulk.html:91
+msgid "Remove Cc"
+msgstr "Odstranit Cc"
+
+#: html/Search/Bulk.html:89
+msgid "Remove Requestor"
+msgstr "Odstranit žadatele"
+
+#: html/Ticket/Elements/ShowTransaction:173 html/Ticket/Elements/Tabs:122
+msgid "Reply"
+msgstr "Odpovědět"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Reply to tickets"
+msgstr "Odpovědět na požadavky"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "ReplyToTicket"
+msgstr "Odpovídat na požadavky"
+
+#: etc/initialdata:44 html/Ticket/Update.html:40 lib/RT/ACE_Overlay.pm:87
+msgid "Requestor"
+msgstr "Žadatel"
+
+#: html/Search/Elements/PickRestriction:38
+msgid "Requestor email address"
+msgstr "Emailová adresa žadatele"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr "Žadatel(é)"
+
+#: html/SelfService/Create.html:43 html/SelfService/Display.html:42 html/Ticket/Create.html:56 html/Ticket/Elements/EditPeople:48 html/Ticket/Elements/ShowPeople:31
+msgid "Requestors"
+msgstr "Žadatelé"
+
+#: html/Admin/Elements/ModifyQueue:61 html/Admin/Queues/Modify.html:75
+msgid "Requests should be due in"
+msgstr "Požadavky mají být vyřešeny do"
+
+#: html/Elements/Submit:62
+msgid "Reset"
+msgstr "Vynulovat"
+
+#: html/Admin/Users/Modify.html:159 html/User/Prefs.html:50
+msgid "Residence"
+msgstr "Bydliště"
+
+#: html/Ticket/Elements/Tabs:132
+msgid "Resolve"
+msgstr "Vyřešit"
+
+#: html/Ticket/Update.html:133
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr "Vyřešení požadavku #%1 (%2)"
+
+#: etc/initialdata:302 html/Elements/SelectDateType:28 lib/RT/Ticket_Overlay.pm:1170
+msgid "Resolved"
+msgstr "Vyřešen"
+
+#: html/Search/Bulk.html:123 html/Ticket/ModifyAll.html:73 html/Ticket/Update.html:73
+msgid "Response to requestors"
+msgstr "Odpověď žadatelům"
+
+#: html/Elements/ListActions:26
+msgid "Results"
+msgstr "Výsledky"
+
+#: html/Search/Elements/PickRestriction:105
+msgid "Results per page"
+msgstr "Výsledků na stránku"
+
+#: html/Admin/Elements/ModifyUser:33 html/Admin/Users/Modify.html:100 html/User/Prefs.html:72
+msgid "Retype Password"
+msgstr "Zopakujte heslo"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr "Nenalezeno právo %1 pro %2 %3 v mezích %4 (%5)"
+
+#: lib/RT/ACE_Overlay.pm:613
+msgid "Right Delegated"
+msgstr "Právo delegováno"
+
+#: lib/RT/ACE_Overlay.pm:303
+msgid "Right Granted"
+msgstr "Práva přidána"
+
+#: lib/RT/ACE_Overlay.pm:161
+msgid "Right Loaded"
+msgstr "Právo načteno"
+
+#: lib/RT/ACE_Overlay.pm:678 lib/RT/ACE_Overlay.pm:693
+msgid "Right could not be revoked"
+msgstr "Právo nemůže být odebráno"
+
+#: html/User/Delegation.html:64
+msgid "Right not found"
+msgstr "Právo nenalezeno"
+
+#: lib/RT/ACE_Overlay.pm:543 lib/RT/ACE_Overlay.pm:638
+msgid "Right not loaded."
+msgstr "Právo nenačteno."
+
+#: lib/RT/ACE_Overlay.pm:689
+msgid "Right revoked"
+msgstr "Právo odebráno"
+
+#: html/Admin/Elements/UserTabs:41
+msgid "Rights"
+msgstr "Práva"
+
+#: lib/RT/Interface/Web.pm:758
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr "Práva pro %1 nemohou být přidělena"
+
+#: lib/RT/Interface/Web.pm:791
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr "Práva nemohou být %1 odebrána"
+
+#: html/Admin/Global/GroupRights.html:51 html/Admin/Queues/GroupRights.html:52
+msgid "Roles"
+msgstr "Pravidla"
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr "Kořenový schvalovatel"
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "so"
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "Save Changes"
+msgstr "Uložit změny"
+
+#: html/Ticket/ModifyLinks.html:39
+msgid "Save changes"
+msgstr "Nezapomeňte uložit změny - "
+
+#: html/Admin/Global/Scrip.html:49
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr "Scrip #%1"
+
+#: lib/RT/Scrip_Overlay.pm:176
+msgid "Scrip Created"
+msgstr "Scrip vytvořen"
+
+#: html/Admin/Elements/EditScrips:84
+msgid "Scrip deleted"
+msgstr "Scrip smazán"
+
+#: html/Admin/Elements/QueueTabs:46 html/Admin/Elements/SystemTabs:33 html/Admin/Global/index.html:41
+msgid "Scrips"
+msgstr "Scripy"
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr "Scripy fro %1\\n"
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr "Scripy platné ve všech frontách"
+
+#: html/Elements/SimpleSearch:27 html/Search/Elements/PickRestriction:126 html/Ticket/Elements/Tabs:159
+msgid "Search"
+msgstr "Vyhledávání"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr "Podmínky vyhledávání"
+
+#: html/Approvals/Elements/PendingMyApproval:39
+msgid "Search for approvals"
+msgstr "Vyhledávání schvalování"
+
+#: bin/rt-crontool:188
+msgid "Security:"
+msgstr "Zabezpeční:"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "SeeQueue"
+msgstr "Vidět frontu"
+
+#: html/Admin/Groups/index.html:40
+msgid "Select a group"
+msgstr "Výběr skupiny"
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr "Výběr fronty"
+
+#: html/Admin/Users/index.html:25 html/Admin/Users/index.html:28
+msgid "Select a user"
+msgstr "Výběr uživatele"
+
+#: html/Admin/Global/CustomField.html:38 html/Admin/Global/CustomFields.html:36
+msgid "Select custom field"
+msgstr "Vybrat uživatelskou položku"
+
+#: html/Admin/Elements/GroupTabs:52 html/User/Elements/GroupTabs:50
+msgid "Select group"
+msgstr "Vybrat skupinu"
+
+#: lib/RT/CustomField_Overlay.pm:355
+msgid "Select multiple values"
+msgstr "Vybrat více hodnot"
+
+#: lib/RT/CustomField_Overlay.pm:352
+msgid "Select one value"
+msgstr "Vybrat jednu hodnotu"
+
+#: html/Admin/Elements/QueueTabs:67
+msgid "Select queue"
+msgstr "Výběr fronty"
+
+#: html/Admin/Global/Scrip.html:37 html/Admin/Global/Scrips.html:36 html/Admin/Queues/Scrip.html:40 html/Admin/Queues/Scrips.html:50
+msgid "Select scrip"
+msgstr "Výběr scripu"
+
+#: html/Admin/Global/Template.html:57 html/Admin/Global/Templates.html:36 html/Admin/Queues/Template.html:55
+msgid "Select template"
+msgstr "Vybrat vzor"
+
+#: html/Admin/Elements/UserTabs:49
+msgid "Select user"
+msgstr "Výběr uživatele"
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "SelectMultiple"
+msgstr "Výběr vícenásobný"
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectSingle"
+msgstr "Výbět jedinečný"
+
+#: html/SelfService/index.html:25
+msgid "Self Service"
+msgstr "Samoobsluha"
+
+#: etc/initialdata:114
+msgid "Send mail to all watchers"
+msgstr "Zaslat e-mail všem pozorovatelům"
+
+#: etc/initialdata:110
+msgid "Send mail to all watchers as a \"comment\""
+msgstr "Zaslat e-mail všem pozorovatelům jako \"komentář\""
+
+#: etc/initialdata:105
+msgid "Send mail to requestors and Ccs"
+msgstr "Zaslat e-mail žadatelům a všem Cc"
+
+#: etc/initialdata:100
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr "Zaslat e-mail žadatelům a všem Ccs jako komentář"
+
+#: etc/initialdata:79
+msgid "Sends a message to the requestors"
+msgstr "Posílá zprávu všem žadatelům"
+
+#: etc/initialdata:118 etc/initialdata:122
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr "Posílá e-mail všem přesně vyjmenovaným Cc a Bcc"
+
+#: etc/initialdata:95
+msgid "Sends mail to the administrative Ccs"
+msgstr "Posílá e-mail všem administrativním Cc"
+
+#: etc/initialdata:91
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr "Posílá e-mail všem administrativním Cc jako komentář"
+
+#: etc/initialdata:83 etc/initialdata:87
+msgid "Sends mail to the owner"
+msgstr "Posílá e-mail vlastníkovi"
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "zář"
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr "Zobrazit výsledky"
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show approved requests"
+msgstr "Zobrazit schválené požadavky"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show basics"
+msgstr "Zobrazit základní údaje"
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show denied requests"
+msgstr "Zobrazit odepřené požadavky"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show details"
+msgstr "Zobrazit podrobnosti"
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show pending requests"
+msgstr "Zobrazit trvající požadavky"
+
+#: html/Approvals/Elements/PendingMyApproval:46
+msgid "Show requests awaiting other approvals"
+msgstr "Zobrazit požadavky čekající na jejich schválení"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Show ticket private commentary"
+msgstr "Zobrazovat privátní komentáře požadavku"
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "Show ticket summaries"
+msgstr "Zobrazovat výsledky požadavku"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ShowACL"
+msgstr "Zobrazovat seznam přístupových práv"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowScrips"
+msgstr "Zobrazit scripy"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ShowTemplate"
+msgstr "Zobrazit vzor"
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "ShowTicket"
+msgstr "Zobrazit požadavek"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "ShowTicketComments"
+msgstr "Zobrazit komentáře požadavku"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr "Být žadatelem či Cc požadavku či fronty"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr "Být AdminCc požadavku nebo fronty"
+
+#: html/Admin/Elements/ModifyUser:39 html/Admin/Users/Modify.html:191 html/Admin/Users/Prefs.html:32 html/SelfService/Prefs.html:37 html/User/Prefs.html:112
+msgid "Signature"
+msgstr "Podpis"
+
+#: html/SelfService/Elements/Header:52
+#. ($session{'CurrentUser'}->Name)
+msgid "Signed in as %1"
+msgstr "Příhlášen jako %1"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Single"
+msgstr "Jednoduchá"
+
+#: html/Elements/Header:51
+msgid "Skip Menu"
+msgstr "Přeskočit menu"
+
+#: html/Admin/Elements/EditCustomFieldValues:31
+msgid "Sort key"
+msgstr "Třídící klíč"
+
+#: html/Search/Elements/PickRestriction:109
+msgid "Sort results by"
+msgstr "Třídit výsledky dle"
+
+#: html/Admin/Elements/AddCustomFieldValue:25
+msgid "SortOrder"
+msgstr "Třídící pořadí"
+
+#: NOT FOUND IN SOURCE
+msgid "Stalled"
+msgstr "Odložené"
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr "Úvodní stránka"
+
+#: html/Elements/SelectDateType:27 html/Ticket/Elements/EditDates:32 html/Ticket/Elements/ShowDates:35
+msgid "Started"
+msgstr "Započato"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr "Datum započetí '%1' nemůže být rozpoznáno"
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:27 html/Ticket/Elements/ShowDates:31
+msgid "Starts"
+msgstr "Začíná"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr "Začíná"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr "Datum začínání '%1' nemůže být rozpoznáno"
+
+#: html/Admin/Elements/ModifyUser:82 html/Admin/Users/Modify.html:138 html/User/Prefs.html:94
+msgid "State"
+msgstr "Stát"
+
+#: html/Elements/MyRequests:31 html/Elements/MyTickets:31 html/Search/Elements/PickRestriction:74 html/SelfService/Display.html:59 html/SelfService/Elements/MyRequests:29 html/SelfService/Update.html:31 html/Ticket/Create.html:42 html/Ticket/Elements/EditBasics:38 html/Ticket/Elements/ShowBasics:31 html/Ticket/Update.html:60 lib/RT/Ticket_Overlay.pm:1164 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "Stav"
+
+#: etc/initialdata:288
+msgid "Status Change"
+msgstr "Změna Stavu"
+
+#: lib/RT/Transaction_Overlay.pm:530
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr "Stav změněn z %1 na %2"
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr "Změna stavu"
+
+#: html/Ticket/Elements/Tabs:147
+msgid "Steal"
+msgstr "Vzít"
+
+#: lib/RT/Transaction_Overlay.pm:589
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "Vzato %1 "
+
+#: html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Search/Bulk.html:126 html/Search/Elements/PickRestriction:43 html/SelfService/Create.html:59 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:35 html/Ticket/Create.html:84 html/Ticket/Elements/EditBasics:28 html/Ticket/ModifyAll.html:79 html/Ticket/Update.html:77 lib/RT/Ticket_Overlay.pm:1160 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "Předmět"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:611
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr "Předmět změněn na %1"
+
+#: html/Elements/Submit:59
+msgid "Submit"
+msgstr "Odeslat"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr "Potvrdit model zpracování"
+
+#: lib/RT/Group_Overlay.pm:749
+msgid "Succeeded"
+msgstr "Úspěšné"
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "ne"
+
+#: lib/RT/System.pm:54
+msgid "SuperUser"
+msgstr "Super uživatel"
+
+#: html/User/Elements/DelegateRights:77
+msgid "System"
+msgstr "Systém"
+
+#: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:567 lib/RT/Interface/Web.pm:757 lib/RT/Interface/Web.pm:790
+msgid "System Error"
+msgstr "Systémová chyba"
+
+#: lib/RT/ACE_Overlay.pm:616
+msgid "System error. Right not delegated."
+msgstr "Systémová chyba. Právo nedelegováno."
+
+#: lib/RT/ACE_Overlay.pm:146 lib/RT/ACE_Overlay.pm:223 lib/RT/ACE_Overlay.pm:306 lib/RT/ACE_Overlay.pm:898
+msgid "System error. Right not granted."
+msgstr "Systémová chyba. Právo nepřiděleno."
+
+#: html/Admin/Global/GroupRights.html:35 html/Admin/Groups/GroupRights.html:37 html/Admin/Queues/GroupRights.html:36
+msgid "System groups"
+msgstr "Systémové skupiny"
+
+#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53
+msgid "SystemRolegroup for internal use"
+msgstr "Skupina systémovýh pravidel pro vnitřní použití"
+
+#: lib/RT/CurrentUser.pm:320
+msgid "TEST_STRING"
+msgstr "Míchačka na beton"
+
+#: html/Ticket/Elements/Tabs:143
+msgid "Take"
+msgstr "Vzít"
+
+#: lib/RT/Transaction_Overlay.pm:575
+msgid "Taken"
+msgstr "Vzatý"
+
+#: html/Admin/Elements/EditScrip:81
+msgid "Template"
+msgstr "Vzor"
+
+#: html/Admin/Global/Template.html:91 html/Admin/Queues/Template.html:90
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr "Vzor #%!"
+
+#: html/Admin/Elements/EditTemplates:89
+msgid "Template deleted"
+msgstr "Vzor smazán"
+
+#: lib/RT/Scrip_Overlay.pm:153
+msgid "Template not found"
+msgstr "Vzor nenalezen"
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr "Vzor nenalezen\\n"
+
+#: lib/RT/Template_Overlay.pm:347
+msgid "Template parsed"
+msgstr "Vzor rozpoznán"
+
+#: html/Admin/Elements/QueueTabs:49 html/Admin/Elements/SystemTabs:36 html/Admin/Global/index.html:45
+msgid "Templates"
+msgstr "Vzory"
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr "Vzory pro %1\\n"
+
+#: lib/RT/Interface/Web.pm:858
+msgid "That is already the current value"
+msgstr "Toto je již aktuální hodnota"
+
+#: lib/RT/CustomField_Overlay.pm:178
+msgid "That is not a value for this custom field"
+msgstr "Toto není hodnota pro tuto uživatelskou položku"
+
+#: lib/RT/Ticket_Overlay.pm:1886
+msgid "That is the same value"
+msgstr "Toto je shodná hodnota"
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr "Tento uživatel je již v této frontě %1"
+
+#: lib/RT/Ticket_Overlay.pm:1434
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr "Tento uživatel je již u tohoto požadavku %1"
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr "Tento uživatel není v této frontě %1"
+
+#: lib/RT/Ticket_Overlay.pm:1551
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr "Tento uživatel není u tohoto požadavku %1"
+
+#: lib/RT/Ticket_Overlay.pm:1882
+msgid "That queue does not exist"
+msgstr "Tata fronta neexistuje"
+
+#: lib/RT/Ticket_Overlay.pm:3143
+msgid "That ticket has unresolved dependencies"
+msgstr "Tento požadavek má nevyřešené závislosti"
+
+#: lib/RT/ACE_Overlay.pm:288 lib/RT/ACE_Overlay.pm:597
+msgid "That user already has that right"
+msgstr "Tento uživatel již má toto právo"
+
+#: lib/RT/Ticket_Overlay.pm:2952
+msgid "That user already owns that ticket"
+msgstr "Tento uživatel již tento požadavek vlastní"
+
+#: lib/RT/Ticket_Overlay.pm:2918
+msgid "That user does not exist"
+msgstr "Tento uživatel neexistuje"
+
+#: lib/RT/User_Overlay.pm:315
+msgid "That user is already privileged"
+msgstr "Tento uživatel je již privilegován"
+
+#: lib/RT/User_Overlay.pm:332
+msgid "That user is already unprivileged"
+msgstr "Tento uživatel je již neprivilegován"
+
+#: lib/RT/User_Overlay.pm:327
+msgid "That user is now privileged"
+msgstr "Uživatel je nyní privilegován"
+
+#: lib/RT/User_Overlay.pm:344
+msgid "That user is now unprivileged"
+msgstr "Uživatel je nyní neprivilegován"
+
+#: lib/RT/Ticket_Overlay.pm:2944
+msgid "That user may not own tickets in that queue"
+msgstr "V této frontě nemůže tento uživatel vlastnit požadavky"
+
+#: lib/RT/Link_Overlay.pm:206
+msgid "That's not a numerical id"
+msgstr "Toto není číselný identifikátor"
+
+#: html/Ticket/Create.html:150 html/Ticket/Elements/ShowSummary:28
+msgid "The Basics"
+msgstr "Základní údaje"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The CC of a ticket"
+msgstr "Cc požadavku"
+
+#: lib/RT/ACE_Overlay.pm:89
+msgid "The administrative CC of a ticket"
+msgstr "Administrativní Cc požadavku"
+
+#: lib/RT/Ticket_Overlay.pm:2213
+msgid "The comment has been recorded"
+msgstr "Komentář byl zaznamenán"
+
+#: bin/rt-crontool:198
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr "Následující příkaz najde všechny aktivní požadavky ve frontě 'general' a nastaví jejich priority na 99, pokud nebyly tknuty poslední 4 hodiny:"
+
+#: bin/rt-commit-handler:756 bin/rt-commit-handler:766
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr "Následující příkazy nebyly zpracovány\\n\\n"
+
+#: lib/RT/Interface/Web.pm:861
+msgid "The new value has been set."
+msgstr "Nová hodnota nastavena."
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The owner of a ticket"
+msgstr "Vlastník požadavku"
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The requestor of a ticket"
+msgstr "Žadatel požadavku"
+
+#: html/Admin/Elements/EditUserComments:26
+msgid "These comments aren't generally visible to the user"
+msgstr "Tyto komentáře nejsou běžně viditelné uživateli"
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr "Tento požadavek %1 %2 (%3)\\n"
+
+#: bin/rt-crontool:189
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr "Tento nástroj umožňuje uživateli spustit libovolné perl moduly z RT."
+
+#: lib/RT/Transaction_Overlay.pm:253
+msgid "This transaction appears to have no content"
+msgstr "Tato transakce vypadá, že nemá obsah"
+
+#: html/Ticket/Elements/ShowRequestor:47
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr "nejdůležitější%quant(%1, požadavek,požadavky,ch požadavků) tohoto uživatele"
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr "25 nejdůležitějších požadavků tohoto uživatele"
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "čt"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr "Požadavek # %1 %2"
+
+#: html/Ticket/ModifyAll.html:25 html/Ticket/ModifyAll.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "Maxi aktualizace požadavku #%1: %2"
+
+#: html/Approvals/Elements/ShowDependency:46
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr "Požadavek #%1: %2"
+
+#: lib/RT/Ticket_Overlay.pm:608
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr "Požadavek %1 vytvořen ve frontě '%2'"
+
+#: bin/rt-commit-handler:760
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr "Požadavek %1 načten\\n"
+
+#: html/Search/Bulk.html:181
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr "Požadavek %1: %2"
+
+#: html/Ticket/History.html:25 html/Ticket/History.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr "Historie požadavku # %1 %2"
+
+#: html/SelfService/Display.html:34
+msgid "Ticket Id"
+msgstr "Identifikátor požadavku"
+
+#: etc/initialdata:303
+msgid "Ticket Resolved"
+msgstr "Požadavek vyřešen"
+
+#: html/Search/Elements/PickRestriction:63
+msgid "Ticket attachment"
+msgstr "Příloha požadavku"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr "Obsah požadavku"
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr "Typ obsahu požadavku"
+
+#: lib/RT/Ticket_Overlay.pm:495 lib/RT/Ticket_Overlay.pm:597
+msgid "Ticket could not be created due to an internal error"
+msgstr "Požadaven nemůže být vytvořen pro vnitřní chybu"
+
+#: lib/RT/Transaction_Overlay.pm:522
+msgid "Ticket created"
+msgstr "Požadavek vytvořen"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr "Nezdařilo se vytvoření požadavku"
+
+#: lib/RT/Transaction_Overlay.pm:527
+msgid "Ticket deleted"
+msgstr "Požadavek smazán"
+
+#: html/REST/1.0/modify:29 html/REST/1.0/update:34
+msgid "Ticket id not found"
+msgstr "Id požadavku nenalezeno"
+
+#: html/REST/1.0/modify:36 html/REST/1.0/update:41
+msgid "Ticket not found"
+msgstr "Požadavek nenalezen"
+
+#: etc/initialdata:289
+msgid "Ticket status changed"
+msgstr "Stav požadavku změněn"
+
+#: html/Ticket/Update.html:39
+msgid "Ticket watchers"
+msgstr "Pozorovatelé požadavku"
+
+#: html/Elements/Tabs:49
+msgid "Tickets"
+msgstr "Požadavky"
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr "Požadavky %1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr "Požadavky %1 dle %2"
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Tickets from %1"
+msgstr "Požadavky z %1"
+
+#: html/Approvals/Elements/ShowDependency:27
+msgid "Tickets which depend on this approval:"
+msgstr "Požadavky, které záleží na tomto schválení:"
+
+#: html/Ticket/Create.html:157 html/Ticket/Elements/EditBasics:48
+msgid "Time Left"
+msgstr "Zbývající čas"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:43
+msgid "Time Worked"
+msgstr "Čas práce"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "Zbývající čas"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "Čas k zobrazení"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "Čas práce"
+
+#: lib/RT/Ticket_Overlay.pm:1165
+msgid "TimeWorked"
+msgstr "Čas práce"
+
+#: bin/rt-commit-handler:402
+msgid "To generate a diff of this commit:"
+msgstr "Vytvořit diff tohoto commitu:"
+
+#: bin/rt-commit-handler:391
+msgid "To generate a diff of this commit:\\n"
+msgstr "Vytvořit diff tohoto commitu:\\n"
+
+#: lib/RT/Ticket_Overlay.pm:1168
+msgid "Told"
+msgstr "Poslední kontakt"
+
+#: etc/initialdata:237
+msgid "Transaction"
+msgstr "Transakce"
+
+#: lib/RT/Transaction_Overlay.pm:642
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr "Transakce %1 vymazána"
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr "Transakce vytvořena"
+
+#: lib/RT/Transaction_Overlay.pm:89
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr "Bez udání id požadavku nelze volat Transaction->Create"
+
+#: lib/RT/Transaction_Overlay.pm:701
+msgid "Transactions are immutable"
+msgstr "Transakce jsou neměnné"
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr "Pokus o smazání práva: %1"
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "út"
+
+#: html/Admin/Elements/EditCustomField:34 html/Ticket/Elements/AddWatchers:33 html/Ticket/Elements/AddWatchers:44 html/Ticket/Elements/AddWatchers:54 lib/RT/Ticket_Overlay.pm:1166 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "typ"
+
+#: lib/RT/ScripCondition_Overlay.pm:104
+msgid "Unimplemented"
+msgstr "Neimplementováno"
+
+#: html/Admin/Users/Modify.html:68
+msgid "Unix login"
+msgstr "Unixový login"
+
+#: html/Admin/Elements/ModifyUser:62
+msgid "UnixUsername"
+msgstr "Unixové uživatelské jméno"
+
+#: lib/RT/Attachment_Overlay.pm:265
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr "Neznámé kódování obsahu %1"
+
+#: html/Elements/SelectResultsPerPage:37
+msgid "Unlimited"
+msgstr "Neomezeně"
+
+#: etc/initialdata:32
+msgid "Unprivileged"
+msgstr "Neprivilegovaný"
+
+#: lib/RT/Transaction_Overlay.pm:571
+msgid "Untaken"
+msgstr "Vrácen"
+
+#: html/Elements/MyTickets:64 html/Search/Bulk.html:33
+msgid "Update"
+msgstr "Aktualizace"
+
+#: html/Admin/Users/Prefs.html:62
+msgid "Update ID"
+msgstr "Identifikátor aktualizace"
+
+#: html/Search/Bulk.html:120 html/Ticket/ModifyAll.html:66 html/Ticket/Update.html:67
+msgid "Update Type"
+msgstr "Typ aktualizace"
+
+#: html/Search/Listing.html:61
+msgid "Update all these tickets at once"
+msgstr "Aktualizovat společně všechny tyty požadavky"
+
+#: html/Admin/Users/Prefs.html:49
+msgid "Update email"
+msgstr "Aktualizovat email"
+
+#: html/Admin/Users/Prefs.html:55
+msgid "Update name"
+msgstr "Aktualizovat jméno"
+
+#: lib/RT/Interface/Web.pm:375
+msgid "Update not recorded."
+msgstr "Aktualizace nezaznamenána"
+
+#: html/Search/Bulk.html:81
+msgid "Update selected tickets"
+msgstr "Aktualizovat vybrané požadavky"
+
+#: html/Admin/Users/Prefs.html:36
+msgid "Update signature"
+msgstr "Aktualizace podpisu"
+
+#: html/Ticket/ModifyAll.html:63
+msgid "Update ticket"
+msgstr "Aktualizace požadavku"
+
+#: html/SelfService/Update.html:25 html/SelfService/Update.html:27
+#. ($Ticket->id)
+msgid "Update ticket # %1"
+msgstr "Aktualizace požadavku # %1"
+
+#: html/SelfService/Update.html:50
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr "Aktualizace požadavku #%1"
+
+#: html/Ticket/Update.html:135
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr "Aktualizace požadavku #%1 (%2)"
+
+#: lib/RT/Interface/Web.pm:373
+msgid "Update type was neither correspondence nor comment."
+msgstr "Typ aktualizace nebyl ani korespondence ani komentář."
+
+#: html/Elements/SelectDateType:33 html/Ticket/Elements/ShowDates:51 lib/RT/Ticket_Overlay.pm:1169
+msgid "Updated"
+msgstr "Aktualizováno"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr "Uživatel %1 %2: %3\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr "Heslo uživatele %1: %2\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr "Uživatel '%1' nenalezen"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr "Uživatel '%1' nenalezen\\n"
+
+#: etc/initialdata:125 etc/initialdata:191
+msgid "User Defined"
+msgstr "Uživatelem definované"
+
+#: html/Admin/Users/Prefs.html:59
+msgid "User ID"
+msgstr "Identifikátor uživatele"
+
+#: html/Elements/SelectUsers:26
+msgid "User Id"
+msgstr "Identifikátor uživatele"
+
+#: html/Admin/Elements/GroupTabs:47 html/Admin/Elements/QueueTabs:60 html/Admin/Elements/SystemTabs:47 html/Admin/Global/index.html:59
+msgid "User Rights"
+msgstr "Práva uživatele"
+
+#: html/Admin/Users/Modify.html:226
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr "Uživatel nemůže být vytvořen: %1"
+
+#: lib/RT/User_Overlay.pm:262
+msgid "User created"
+msgstr "Uživatel vytvořen"
+
+#: html/Admin/Global/GroupRights.html:67 html/Admin/Groups/GroupRights.html:54 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr "Uživatelem definované skupiny"
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr "Uživatel upozorněn"
+
+#: html/Admin/Users/Prefs.html:25 html/Admin/Users/Prefs.html:29
+msgid "User view"
+msgstr "Uživatelský pohled"
+
+#: html/Admin/Users/Modify.html:48 html/Elements/Login:42 html/Ticket/Elements/AddWatchers:35
+msgid "Username"
+msgstr "Uživatelské jméno"
+
+#: html/Admin/Elements/SelectNewGroupMembers:26 html/Admin/Elements/Tabs:32 html/Admin/Groups/Members.html:55 html/Admin/Queues/People.html:68 html/Admin/index.html:29 html/User/Groups/Members.html:58
+msgid "Users"
+msgstr "Uživatelé"
+
+#: html/Admin/Users/index.html:65
+msgid "Users matching search criteria"
+msgstr "Uživatelé odpovídající podmínce vyhledání"
+
+#: html/Search/Elements/PickRestriction:51
+msgid "ValueOfQueue"
+msgstr "Hodnota fronty"
+
+#: html/Admin/Elements/EditCustomField:40
+msgid "Values"
+msgstr "Hodnoty"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Watch"
+msgstr "Být pozorovatelem"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "WatchAsAdminCc"
+msgstr "Být AdminCc pozorovatelem"
+
+#: html/Admin/Elements/QueueTabs:42
+msgid "Watchers"
+msgstr "Pozorovatelé"
+
+#: html/Admin/Elements/ModifyUser:56
+msgid "WebEncoding"
+msgstr "Kódování WWW"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "st"
+
+#: etc/upgrade/2.1.71:161
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr "Přidat korespondenci k původnímu požadavku, pokud byl požadavek schválen všemi"
+
+#: etc/upgrade/2.1.71:135
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr "Přidat korespondenci k původnímu požadavku, pokud byl požadavek kýmkoli schválen"
+
+#: etc/initialdata:138
+msgid "When a ticket is created"
+msgstr "Když je požadavek vytvořen"
+
+#: etc/upgrade/2.1.71:79
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr "Upozornit vlastníka a všechny AdminCc, jejichž schválení se očekává, při vytvoření schvalovaného požadavku"
+
+#: etc/initialdata:143
+msgid "When anything happens"
+msgstr "Stane-li se cokoli"
+
+#: etc/initialdata:184
+msgid "Whenever a ticket is resolved"
+msgstr "Je-li vyřešen požadavek"
+
+#: etc/initialdata:170
+msgid "Whenever a ticket's owner changes"
+msgstr "Změní-li se vlastník požadavku"
+
+#: etc/initialdata:178
+msgid "Whenever a ticket's queue changes"
+msgstr "Změní-li se fronta požadavku"
+
+#: etc/initialdata:162
+msgid "Whenever a ticket's status changes"
+msgstr "Změní-li se stav požadavku"
+
+#: etc/initialdata:192
+msgid "Whenever a user-defined condition occurs"
+msgstr "Splní-li se uživatelská podmínka"
+
+#: etc/initialdata:156
+msgid "Whenever comments come in"
+msgstr "Přijde-li komentář"
+
+#: etc/initialdata:149
+msgid "Whenever correspondence comes in"
+msgstr "Přijde-li korespondence"
+
+#: html/Admin/Users/Modify.html:164 html/User/Prefs.html:52
+msgid "Work"
+msgstr "Zaměstnání"
+
+#: html/Admin/Elements/ModifyUser:70
+msgid "WorkPhone"
+msgstr "Telefon do zaměstnání"
+
+#: html/SelfService/Display.html:86 html/Ticket/Elements/ShowBasics:35 html/Ticket/Update.html:65
+msgid "Worked"
+msgstr "Odpracováno"
+
+#: lib/RT/Ticket_Overlay.pm:3056
+msgid "You already own this ticket"
+msgstr "Požadavek již vlastníte"
+
+#: html/autohandler:121
+msgid "You are not an authorized user"
+msgstr "Nejste autorizovaný uživatel"
+
+#: lib/RT/Ticket_Overlay.pm:2930
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "Můžete přidělit pouze požadavky, které jsou vaše nebo nejsou vlastněny"
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr "Nemáte právo k zobrazení tohoto požadavku.\\n"
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "Nalezl jste %1 požadavků ve frontě %2"
+
+#??? quant
+#: html/NoAuth/Logout.html:31 html/REST/1.0/logout:25
+msgid "You have been logged out of RT."
+msgstr "Byl jste odhlášen od RT."
+
+#: html/SelfService/Display.html:134
+msgid "You have no permission to create tickets in that queue."
+msgstr "V této frontě nemáte práva vytvářet požadavky."
+
+#: lib/RT/Ticket_Overlay.pm:1895
+msgid "You may not create requests in that queue."
+msgstr "V této frontě nemůžete vytvářet požadavky."
+
+#: html/NoAuth/Logout.html:36
+msgid "You're welcome to login again"
+msgstr "Jste vítáni k dalšímu přihlášení"
+
+#: html/SelfService/Elements/MyRequests:25
+#. ($friendly_status)
+msgid "Your %1 requests"
+msgstr "Vašich %1 požadavků"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr "Váš správce RT chybně nastavil poštovní aliasy, které volají RT"
+
+#: etc/initialdata:429 etc/upgrade/2.1.71:146
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr "Váš požadavek byl schválen uživatelem %1. Další schválení mohou být ještě očekávána."
+
+#: etc/initialdata:463 etc/upgrade/2.1.71:180
+msgid "Your request has been approved."
+msgstr "Váš požadavek byl schválen."
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr "Váš požadavek byl odmítnut"
+
+#: etc/initialdata:384 etc/upgrade/2.1.71:101
+msgid "Your request was rejected."
+msgstr "Váš požadavek byl odmítnut."
+
+#: html/autohandler:136 html/autohandler:142
+msgid "Your username or password is incorrect"
+msgstr "Vaše uživatelské jméno či heslo je nesprávné"
+
+#: html/Admin/Elements/ModifyUser:84 html/Admin/Users/Modify.html:144 html/User/Prefs.html:96
+msgid "Zip"
+msgstr "PSČ"
+
+#: html/User/Elements/DelegateRights:59
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "jak je dovoleno %1"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:34
+msgid "contains"
+msgstr "obsahuje"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content"
+msgstr "obsah"
+
+#: html/Elements/SelectAttachmentField:27
+msgid "content-type"
+msgstr "typ obsahu"
+
+#: lib/RT/Ticket_Overlay.pm:2282
+msgid "correspondence (probably) not sent"
+msgstr "korespondence (zřejmě) neposlána"
+
+#: lib/RT/Ticket_Overlay.pm:2292
+msgid "correspondence sent"
+msgstr "korespondence poslána"
+
+#: html/Admin/Elements/ModifyQueue:63 html/Admin/Queues/Modify.html:77 lib/RT/Date.pm:319
+msgid "days"
+msgstr "dnů"
+
+#: html/Search/Listing.html:75
+msgid "delete"
+msgstr "smazat"
+
+#: lib/RT/Queue_Overlay.pm:63
+msgid "deleted"
+msgstr "smazán"
+
+#: html/Search/Elements/PickRestriction:68
+msgid "does not match"
+msgstr "neodpovídá"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:35
+msgid "doesn't contain"
+msgstr "neobsahuje"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "equal to"
+msgstr "je rovno"
+
+#: html/Elements/SelectAttachmentField:28
+msgid "filename"
+msgstr "název souboru"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "greater than"
+msgstr "větší než"
+
+#: lib/RT/Group_Overlay.pm:194
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "skupina '%1'"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "hodin"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr "Identifikátor"
+
+#: html/Elements/SelectBoolean:32 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88
+msgid "is"
+msgstr "je"
+
+#: html/Elements/SelectBoolean:36 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:37 html/Search/Elements/PickRestriction:48 html/Search/Elements/PickRestriction:77 html/Search/Elements/PickRestriction:89
+msgid "isn't"
+msgstr "není"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "less than"
+msgstr "menší než"
+
+#: html/Search/Elements/PickRestriction:67
+msgid "matches"
+msgstr "odpovídá"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "min"
+
+#: html/Ticket/Update.html:66
+msgid "minutes"
+msgstr "minut"
+
+#: bin/rt-commit-handler:765
+msgid "modifications\\n\\n"
+msgstr "úpravy\\n\\n"
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "měsíců"
+
+#: lib/RT/Queue_Overlay.pm:58
+msgid "new"
+msgstr "nový"
+
+#: html/Admin/Elements/EditScrips:43
+msgid "no value"
+msgstr "znehodnotit"
+
+#: html/Ticket/Elements/EditWatchers:28
+msgid "none"
+msgstr "žádný"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "not equal to"
+msgstr "není rovno"
+
+#: lib/RT/Queue_Overlay.pm:59
+msgid "open"
+msgstr "otevřený"
+
+#: lib/RT/Group_Overlay.pm:199
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr "vlastní skupina '%1' pro uživatele '%2'"
+
+#: lib/RT/Group_Overlay.pm:207
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr "fronta %1 %2"
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "rejected"
+msgstr "zamítnutý"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "resolved"
+msgstr "vyřešený"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr "sek"
+
+#: lib/RT/Queue_Overlay.pm:60
+msgid "stalled"
+msgstr "odložený"
+
+#: lib/RT/Group_Overlay.pm:202
+#. ($self->Type)
+msgid "system %1"
+msgstr "systém %1"
+
+#: lib/RT/Group_Overlay.pm:213
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr "systémová skupina '%1'"
+
+#: html/Elements/Error:42 html/SelfService/Error.html:42
+msgid "the calling component did not specify why"
+msgstr "volající komponenta neudala důvod"
+
+#: lib/RT/Group_Overlay.pm:210
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr "požadavek #%1 %2"
+
+#: lib/RT/Group_Overlay.pm:216
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr "nepopsaná skupina %1"
+
+#: NOT FOUND IN SOURCE
+msgid "undescripbed group %1"
+msgstr "nepopsaná skupina %1"
+
+#: lib/RT/Group_Overlay.pm:191
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr "uživatel %1"
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr "týdnů"
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr "se vzorem %1"
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr "roků"
+
diff --git a/rt/lib/RT/I18N/de.po b/rt/lib/RT/I18N/de.po
new file mode 100644 (file)
index 0000000..3595aad
--- /dev/null
@@ -0,0 +1,4500 @@
+# German localization catalog for Request Tracker (RT)
+# FIRST AUTHOR: Florian Bischof <flo@fxb.de>, May 2002
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: RT 2.1.54\n"
+"POT-Creation-Date: 2002-06-22 06:06+0200\n"
+"PO-Revision-Date: 2003-02-20 04:47+0200\n"
+"Last-Translator: Florian Bischof <flo@fxb.de>\n"
+"Language-Team: RT German <rt@fxb.de>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28
+msgid "#"
+msgstr "#"
+
+#: html/Admin/Queues/Scrip.html:55
+#. ($QueueObj->id)
+msgid "#%1"
+msgstr ""
+
+#: html/Approvals/Elements/ShowDependency:50 html/Ticket/Display.html:26 html/Ticket/Display.html:30
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr "#%1: %2"
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr "%1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr "%1 %2 %3"
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr "%1 %3. %2 %7, %4:%5:%6"
+
+#: lib/RT/Ticket_Overlay.pm:3438 lib/RT/Transaction_Overlay.pm:559 lib/RT/Transaction_Overlay.pm:601
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 added"
+msgstr "%1 %2 hinzugefügt"
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 %2 ago"
+msgstr "vor %1 %2"
+
+#: lib/RT/Ticket_Overlay.pm:3444 lib/RT/Transaction_Overlay.pm:566
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 changed to %3"
+msgstr "%1 %2 geändert in %3"
+
+#: lib/RT/Ticket_Overlay.pm:3441 lib/RT/Transaction_Overlay.pm:562 lib/RT/Transaction_Overlay.pm:607
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 deleted"
+msgstr "%1 %2 gelöscht"
+
+#: html/Admin/Elements/EditScrips:44 html/Admin/Elements/ListGlobalScrips:28
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 with template %3"
+msgstr "%1 %2 mit der Vorlage %3"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 this ticket\\n"
+msgstr "%1 (%2) %3 dieses Ticket\\n"
+
+#: html/Search/Listing.html:57
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr "%1 - %2 angezeigt"
+
+#: bin/rt-crontool:169 bin/rt-crontool:176 bin/rt-crontool:182
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - An argument to pass to %2"
+msgstr "%1 - ein Argument zur Übergabe an %2"
+
+#: bin/rt-crontool:185
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr ""
+
+#msgstr "%1 - Schreibe Statusupdates nach STDOUT"
+#: bin/rt-crontool:179
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr "%1 - Gebe an, welches Action-Modul benutzt werden soll"
+
+#: bin/rt-crontool:173
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr "%1 - Gebe an, welches Condition-Modul benutzt werden soll"
+
+#: bin/rt-crontool:166
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr "%1 - Gebe an, welches Search-Modul benutzt werden soll"
+
+#: lib/RT/ScripAction_Overlay.pm:122
+#. ($self->Id)
+msgid "%1 ScripAction loaded"
+msgstr "ScripAction %1 geladen"
+
+#: lib/RT/Ticket_Overlay.pm:3471
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 added as a value for %2"
+msgstr "%1 als Wert für %2 hinzugefügt"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on (from %2) %3"
+msgstr ""
+
+#: lib/RT/Link_Overlay.pm:117 lib/RT/Link_Overlay.pm:124
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 appears to be a local object, but can't be found in the database"
+msgstr "%1 konnte nicht in der Datenbank gefunden werden obwohl es ein lokales Objekt zu sein scheint"
+
+#: html/Ticket/Elements/ShowDates:52 lib/RT/Transaction_Overlay.pm:483
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 by %2"
+msgstr "am %1 von %2"
+
+#: lib/RT/Transaction_Overlay.pm:537 lib/RT/Transaction_Overlay.pm:626 lib/RT/Transaction_Overlay.pm:635 lib/RT/Transaction_Overlay.pm:638
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 changed from %2 to %3"
+msgstr "%1 von %2 in %3 geändert"
+
+#: lib/RT/Interface/Web.pm:857
+msgid "%1 could not be set to %2."
+msgstr "%1 konnte nicht auf %2 gesetzt werden."
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2813
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr "%1 konnte den Status nicht auf erledigt setzen. Die RT-Datenbank könnte inkonsistent sein."
+
+#: html/Elements/MyTickets:25
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr "%1 mir zugewiesene Anfragen mit höchster Priorität..."
+
+#: html/Elements/MyRequests:25
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr "Die %1 von mir ausgelösten Anfragen mit höchster Priorität"
+
+#: bin/rt-crontool:161
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr "%1 ist ein Werkzeug um Anfragen über externe Terminierungstools wie \"cron\" zu verarbeiten"
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr "%1 ist kein %2 dieses Stapels mehr."
+
+#: lib/RT/Ticket_Overlay.pm:1570
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr "%1 ist nicht mehr  %2 dieser Anfrage."
+
+#: lib/RT/Ticket_Overlay.pm:3527
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr "%1 ist kein Wert des benutzerdefinierten Feldes %2 mehr"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr "%1 ist keine gültige Stapel-Id."
+
+#: html/Ticket/Elements/ShowBasics:36
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr "%1 Min"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr ""
+
+#: html/User/Elements/DelegateRights:76
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr "%1 Rechte"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr ""
+
+#: lib/RT/Action/ResolveMembers.pm:42
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr "%1 wird alle Mitglieder eines erledigten Gruppentickets erledigen."
+
+#: NOT FOUND IN SOURCE
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:435
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr "%1: kein Anhang angegeben"
+
+#: html/Ticket/Elements/ShowTransaction:102
+#. ($size)
+msgid "%1b"
+msgstr "%1b"
+
+#: html/Ticket/Elements/ShowTransaction:99
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr "%1k"
+
+#: lib/RT/Ticket_Overlay.pm:1140
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr "'%1' ist ein ungültiger Wert für Status"
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr "(Markieren um Scrip zu löschen)"
+
+#: html/Admin/Elements/EditQueueWatchers:29 html/Admin/Elements/EditScrips:35 html/Admin/Elements/EditTemplates:36 html/Admin/Groups/Members.html:52 html/Ticket/Elements/EditLinks:33 html/Ticket/Elements/EditPeople:46 html/User/Groups/Members.html:55
+msgid "(Check box to delete)"
+msgstr "(Markieren um zu löschen)"
+
+#: html/Ticket/Create.html:178
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr "(Gib Anfragenummern oder URLs getrennt durch Leerzeichen ein)"
+
+#: html/Admin/Queues/Modify.html:54 html/Admin/Queues/Modify.html:60
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr "(Bei Freilassen %1"
+
+#: html/Admin/Elements/EditCustomFields:33 html/Admin/Elements/ListGlobalCustomFields:32
+msgid "(No custom fields)"
+msgstr "(Keine benutzerdefinierten Felder)"
+
+#: html/Admin/Groups/Members.html:50 html/User/Groups/Members.html:53
+msgid "(No members)"
+msgstr "(Keine Mitglieder)"
+
+#: html/Admin/Elements/EditScrips:32 html/Admin/Elements/ListGlobalScrips:32
+msgid "(No scrips)"
+msgstr "(Keine Scrips)"
+
+#: html/Admin/Elements/EditTemplates:31
+msgid "(No templates)"
+msgstr "(Keine Vorlagen)"
+
+#: html/Ticket/Update.html:85
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(Schickt eine Blindkopie dieser Aktualisierung an eine durch Komma getrennte Liste von E-Mail-Adressen. Ändert <b>nicht</b> wer künftig Aktualisierungen geschickt bekommt.)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr ""
+
+#: html/Ticket/Create.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(Schickt eine Kopie dieser Aktualisierung an eine durch Komma getrennte Liste von administrativen E-Mail-Adressen. Diese <b>werden</b> künftig Aktualisierungen erhalten.)"
+
+#: html/Ticket/Update.html:81
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(Schickt eine Kopie dieser Aktualisierung an eine durch Komma getrennte Liste von E-Mail-Adressen. Ändert <b>nicht</b> wer künftig Aktualisierungen geschickt bekommt.)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr ""
+
+#: html/Ticket/Create.html:69
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(Schickt eine Kopie dieser Aktualisierung an eine durch Komma getrennte Liste von E-Mail-Adressen. Diese <b>werden</b> künftig Aktualisierungen erhalten.)"
+
+#: html/Admin/Groups/index.html:33 html/User/Groups/index.html:33
+msgid "(empty)"
+msgstr "(leer)"
+
+#: html/Admin/Users/index.html:39
+msgid "(no name listed)"
+msgstr ""
+
+#: html/Elements/MyRequests:43 html/Elements/MyTickets:45
+msgid "(no subject)"
+msgstr "(kein Betreff)"
+
+#: html/Admin/Elements/SelectRights:48 html/Elements/SelectCustomFieldValue:30 html/Ticket/Elements/EditCustomField:59 html/Ticket/Elements/ShowCustomFields:36 lib/RT/Transaction_Overlay.pm:536
+msgid "(no value)"
+msgstr "(keine Angabe)"
+
+#: html/Ticket/Elements/EditLinks:116
+msgid "(only one ticket)"
+msgstr "(nur eine Anfrage)"
+
+#: html/Elements/MyRequests:52 html/Elements/MyTickets:55
+msgid "(pending approval)"
+msgstr "(wartet auf Freigabe)"
+
+#: html/Elements/MyRequests:54 html/Elements/MyTickets:57
+msgid "(pending other tickets)"
+msgstr "(wartet auf andere Anfragen)"
+
+#: html/Admin/Users/Modify.html:50
+msgid "(required)"
+msgstr "(notwendig)"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "(untitled)"
+msgstr "(unbenannt)"
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I own..."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I requested..."
+msgstr ""
+
+#: html/Ticket/Elements/ShowBasics:32
+msgid "<% $Ticket->Status%>"
+msgstr ""
+
+#: html/Elements/SelectTicketTypes:27
+msgid "<% $_ %>"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:26
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"Neue Anfrage in\">&nbsp;%1"
+
+#: etc/initialdata:203
+msgid "A blank template"
+msgstr "Eine leere Vorlage"
+
+#: lib/RT/ACE_Overlay.pm:157 lib/RT/Principal_Overlay.pm:181
+msgid "ACE not found"
+msgstr "ACE nicht gefunden"
+
+#: lib/RT/ACE_Overlay.pm:831
+msgid "ACEs can only be created and deleted."
+msgstr "ACEs können nur erstellt und gelöscht werden."
+
+#: bin/rt-commit-handler:755
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr "Breche ab um ungewünschte Veränderungen an der Anfrage zu verhindern.\\n"
+
+#: html/User/Elements/Tabs:32
+msgid "About me"
+msgstr "Über mich"
+
+#: html/Admin/Users/Modify.html:80
+msgid "Access control"
+msgstr "Zugriffskontrolle"
+
+#: html/Admin/Elements/EditScrip:57
+msgid "Action"
+msgstr "Aktion"
+
+#: lib/RT/Scrip_Overlay.pm:147
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr "Aktion %1 nicht gefunden"
+
+#: bin/rt-crontool:123
+msgid "Action committed."
+msgstr "Aktion durchgeführt."
+
+#: bin/rt-crontool:119
+msgid "Action prepared..."
+msgstr "Aktion vorbereitet..."
+
+#: html/Search/Bulk.html:92
+msgid "Add AdminCc"
+msgstr "AdminCC hinzufügen"
+
+#: html/Search/Bulk.html:90
+msgid "Add Cc"
+msgstr "CC hinzufügen"
+
+#: html/Ticket/Create.html:114 html/Ticket/Update.html:100
+msgid "Add More Files"
+msgstr "Mehr Dateien anhängen"
+msgstr "Weitere Dateien anhängen"
+
+#: html/Search/Bulk.html:88
+msgid "Add Requestor"
+msgstr "Klient hinzufügen"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr "Erstelle ein neues globales Scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr "Erstelle ein Scrip für diesen Stapel"
+
+#: html/Admin/Global/Scrip.html:55
+msgid "Add a scrip which will apply to all queues"
+msgstr "Scrip erstellen, das auf alle Stapel angewendet wird"
+
+#: html/Search/Bulk.html:118
+msgid "Add comments or replies to selected tickets"
+msgstr "Füge den ausgewählten Anfragen Kommentare oder Antworten hinzu"
+
+#: html/Admin/Groups/Members.html:42 html/User/Groups/Members.html:39
+msgid "Add members"
+msgstr "Mitglieder hinzufügen"
+
+#: html/Admin/Queues/People.html:66 html/Ticket/Elements/AddWatchers:28
+msgid "Add new watchers"
+msgstr "Neue Beobachter hinzufügen"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr "Habe einen Hauptverantwortlichen als %1 für diesen Stapel hinzugefügt"
+
+#: lib/RT/Ticket_Overlay.pm:1454
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr "Habe einen Hauptverantwortlichen als %1 für diese Anfrage hinzugefügt"
+
+#: html/Admin/Elements/ModifyUser:76 html/Admin/Users/Modify.html:122 html/User/Prefs.html:88
+msgid "Address1"
+msgstr "Adresse 1"
+
+#: html/Admin/Elements/ModifyUser:78 html/Admin/Users/Modify.html:127 html/User/Prefs.html:90
+msgid "Address2"
+msgstr "Adresse 2"
+
+#: html/Ticket/Create.html:74
+msgid "Admin Cc"
+msgstr "Admin CC"
+
+#: etc/initialdata:274
+msgid "Admin Comment"
+msgstr "Admin Kommentar"
+
+#: etc/initialdata:256
+msgid "Admin Correspondence"
+msgstr "Admin Korrespondenz"
+
+#: html/Admin/Queues/index.html:25 html/Admin/Queues/index.html:28
+msgid "Admin queues"
+msgstr "Admin Stapel"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr ""
+
+#: html/Admin/Global/index.html:26 html/Admin/Global/index.html:28
+msgid "Admin/Global configuration"
+msgstr "Admin/Globale Einstellungen"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr ""
+
+#: html/Admin/Queues/Modify.html:25 html/Admin/Queues/Modify.html:29
+msgid "Admin/Queue/Basics"
+msgstr "Admin/Stapel/Basics"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr ""
+
+#: etc/initialdata:56 html/Ticket/Elements/ShowPeople:39 html/Ticket/Update.html:50 lib/RT/ACE_Overlay.pm:89
+msgid "AdminCc"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "AdminCustomFields"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "AdminGroup"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "AdminGroupMembership"
+msgstr ""
+
+#: lib/RT/System.pm:59
+msgid "AdminOwnPersonalGroups"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "AdminQueue"
+msgstr ""
+
+#: lib/RT/System.pm:60
+msgid "AdminUsers"
+msgstr ""
+
+#: html/Admin/Queues/People.html:48 html/Ticket/Elements/EditPeople:54
+msgid "Administrative Cc"
+msgstr "Administrative CC"
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr "Erweiterte Suche"
+
+#: html/Elements/SelectDateRelation:36
+msgid "After"
+msgstr "Nach dem"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr "Alter"
+
+#: html/Admin/Elements/EditCustomFields:96
+msgid "All Custom Fields"
+msgstr "Alle benutzerdefinierten Felder"
+
+#: html/Admin/Queues/index.html:53
+msgid "All Queues"
+msgstr "Alle Stapel"
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr ""
+
+#: html/Elements/Tabs:58
+msgid "Approval"
+msgstr "Freigabe"
+
+#: html/Approvals/Display.html:46 html/Approvals/Elements/Approve:27 html/Approvals/Elements/ShowDependency:42 html/Approvals/index.html:65
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr "Freigabe #%1: %2"
+
+#: html/Approvals/index.html:54
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr "Freigabe #%1: Notiz wurde aufgrund eines Systemfehlers nicht vermerkt"
+
+#: html/Approvals/index.html:52
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr "Freigabe #%1: Notiz vermerkt"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Details"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Approval diagram"
+msgstr ""
+
+#: html/Approvals/Elements/Approve:45
+msgid "Approve"
+msgstr "Freigeben"
+
+#: etc/initialdata:431 etc/upgrade/2.1.71:148
+msgid "Approver's notes: %1"
+msgstr "Notizen des Freigebenden: %1"
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "Apr"
+
+#: html/Elements/SelectSortOrder:35
+msgid "Ascending"
+msgstr "aufsteigend"
+
+#: html/Search/Bulk.html:127 html/SelfService/Update.html:36 html/Ticket/ModifyAll.html:83 html/Ticket/Update.html:100
+msgid "Attach"
+msgstr "Anhängen"
+
+#: html/SelfService/Create.html:67 html/Ticket/Create.html:110
+msgid "Attach file"
+msgstr "Datei anhängen"
+
+#: html/Ticket/Create.html:98 html/Ticket/Update.html:89
+msgid "Attached file"
+msgstr "Dateianhang"
+
+#: html/SelfService/Attachment/dhandler:36
+msgid "Attachment '%1' could not be loaded"
+msgstr "Anhang '%1' konnte nicht geladen werden"
+
+#: lib/RT/Transaction_Overlay.pm:443
+msgid "Attachment created"
+msgstr "Anhang erstellt"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "Dateiname des Anhangs"
+
+#: html/Ticket/Elements/ShowAttachments:26
+msgid "Attachments"
+msgstr "Anhänge"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "Aug"
+
+#: html/Admin/Elements/ModifyUser:66
+msgid "AuthSystem"
+msgstr "AuthSystem"
+
+#: etc/initialdata:206
+msgid "Autoreply"
+msgstr "Autoreply"
+
+#: etc/initialdata:72
+msgid "Autoreply To Requestors"
+msgstr "Autoreply an Klienten"
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr "Fehlerhafte PGP-Signatur: %1\\n"
+
+#: html/SelfService/Attachment/dhandler:40
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr "Fehlerhafte Anhangs-Id. Konnte Anhang '%1' nicht finden\\n"
+
+#: bin/rt-commit-handler:827
+#. ($val)
+msgid "Bad data in %1"
+msgstr "Fehlerhafte Daten in %1"
+
+#: html/SelfService/Attachment/dhandler:43
+#. ($trans, $AttachmentObj->TransactionId())
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr "Fehlerhafte Transaktionsnummer für den Anhang. %1 solle %2 sein\\n"
+
+#: html/Admin/Elements/GroupTabs:39 html/Admin/Elements/QueueTabs:39 html/Admin/Elements/UserTabs:38 html/Ticket/Elements/Tabs:90 html/User/Elements/GroupTabs:38
+msgid "Basics"
+msgstr "Grundlagen"
+
+#: html/Ticket/Update.html:83
+msgid "Bcc"
+msgstr "BCC"
+
+#: html/Admin/Elements/EditScrip:88 html/Admin/Global/GroupRights.html:85 html/Admin/Global/Template.html:46 html/Admin/Global/UserRights.html:54 html/Admin/Groups/GroupRights.html:73 html/Admin/Groups/Members.html:81 html/Admin/Groups/Modify.html:56 html/Admin/Groups/UserRights.html:55 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:45 html/Admin/Queues/UserRights.html:54 html/User/Groups/Modify.html:56
+msgid "Be sure to save your changes"
+msgstr "Denke daran, Deine Änderungen zu speichern"
+
+### wieder - Duzen???
+#: html/Elements/SelectDateRelation:34 lib/RT/CurrentUser.pm:322
+msgid "Before"
+msgstr "vor dem"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin Approval"
+msgstr ""
+
+#: etc/initialdata:202
+msgid "Blank"
+msgstr "Leer"
+
+#: html/Search/Listing.html:79
+msgid "Bookmarkable URL for this search"
+msgstr "Speicherbare URL für diese Suche"
+
+#: html/Ticket/Elements/ShowHistory:39 html/Ticket/Elements/ShowHistory:45
+msgid "Brief headers"
+msgstr "Kurze Kopfzeilen"
+
+#: html/Search/Bulk.html:25 html/Search/Bulk.html:26
+msgid "Bulk ticket update"
+msgstr "Massen Ticketupdate"
+
+#: lib/RT/User_Overlay.pm:1331
+msgid "Can not modify system users"
+msgstr "Kann Systembenutzer nicht ändern"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Can this principal see this queue"
+msgstr "Kann dieser Hauptverantwortliche diesen Stapel sehen"
+
+#: lib/RT/CustomField_Overlay.pm:144
+msgid "Can't add a custom field value without a name"
+msgstr "Kann kein benutzerdefiniertes Feld ohne Namen hinzufügen"
+
+#: lib/RT/Link_Overlay.pm:132
+msgid "Can't link a ticket to itself"
+msgstr "Kann kein Ticket auf sich selbst verweisen lassen!"
+
+#: lib/RT/Ticket_Overlay.pm:2787
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr "Konnte das Ticket nicht in ein vereinigtes Ticket vereinigen. Diesen Fehler solltest du niemals sehen"
+
+#: lib/RT/Ticket_Overlay.pm:2605 lib/RT/Ticket_Overlay.pm:2674
+msgid "Can't specifiy both base and target"
+msgstr "Du kannst nicht Basis und Ziel gleichzeitig angeben"
+
+#: html/autohandler:112
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr "Kann Benutzer nicht anlegen: %1"
+
+#: etc/initialdata:50 html/Admin/Queues/People.html:44 html/SelfService/Create.html:51 html/SelfService/Display.html:50 html/Ticket/Create.html:64 html/Ticket/Elements/EditPeople:51 html/Ticket/Elements/ShowPeople:35 html/Ticket/Update.html:45 html/Ticket/Update.html:78 lib/RT/ACE_Overlay.pm:88
+msgid "Cc"
+msgstr "CC"
+
+#: html/SelfService/Prefs.html:31
+msgid "Change password"
+msgstr "Passwort ändern"
+
+#: html/Ticket/Create.html:101 html/Ticket/Update.html:92
+msgid "Check box to delete"
+msgstr "Zum Löschen ankreuzen"
+
+#: html/Admin/Elements/SelectRights:31
+msgid "Check box to revoke right"
+msgstr "Zum Entziehen einer Berechtigung ankreuzen"
+
+#: html/Ticket/Create.html:183 html/Ticket/Elements/EditLinks:131 html/Ticket/Elements/EditLinks:69 html/Ticket/Elements/ShowLinks:51
+msgid "Children"
+msgstr "Kinder"
+
+#: html/Admin/Elements/ModifyUser:80 html/Admin/Users/Modify.html:132 html/User/Prefs.html:92
+msgid "City"
+msgstr "Stadt"
+
+#: html/Ticket/Elements/ShowDates:47
+msgid "Closed"
+msgstr "Geschlossen"
+
+#: html/SelfService/Elements/Tabs:60
+msgid "Closed requests"
+msgstr "Geschossene Tickets"
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr ""
+
+#: html/Ticket/Elements/ShowTransaction:179 html/Ticket/Elements/Tabs:153
+msgid "Comment"
+msgstr "Kommentar"
+
+#: html/Admin/Elements/ModifyQueue:45 html/Admin/Queues/Modify.html:58
+msgid "Comment Address"
+msgstr "Kommentaradresse"
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Comment on tickets"
+msgstr "Kommentiere Tickets"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "CommentOnTicket"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:35
+msgid "Comments"
+msgstr "Kommantare"
+
+#: html/Ticket/ModifyAll.html:70 html/Ticket/Update.html:70
+msgid "Comments (Not sent to requestors)"
+msgstr "Kommentar (wird nicht an Klienten geschickt)"
+
+#: html/Search/Bulk.html:122
+msgid "Comments (not sent to requestors)"
+msgstr "Kommentar (wird nicht an Klienten geschickt)"
+
+#: html/Elements/ViewUser:27
+#. ($name)
+msgid "Comments about %1"
+msgstr "Kommentar über %1"
+
+#: html/Admin/Users/Modify.html:185 html/Ticket/Elements/ShowRequestor:44
+msgid "Comments about this user"
+msgstr "Kommentar zu diesen Benutzer"
+
+#: lib/RT/Transaction_Overlay.pm:545
+msgid "Comments added"
+msgstr "Kommentar hinzugefügt"
+
+#: lib/RT/Action/Generic.pm:140
+msgid "Commit Stubbed"
+msgstr "Übergabe abgehakt"
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr ""
+
+#: html/Admin/Elements/EditScrip:41
+msgid "Condition"
+msgstr "Bedingung"
+
+#: bin/rt-crontool:109
+msgid "Condition matches..."
+msgstr "Condition trifft zu..."
+
+#: lib/RT/Scrip_Overlay.pm:160
+msgid "Condition not found"
+msgstr "Bedingung nicht gefunden"
+
+#: html/Elements/Tabs:52
+msgid "Configuration"
+msgstr "Konfiguration"
+
+#: html/SelfService/Prefs.html:33
+msgid "Confirm"
+msgstr "Bestätigen"
+
+#: html/Admin/Elements/ModifyUser:60
+msgid "ContactInfoSystem"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr ""
+
+#: html/Admin/Elements/ModifyTemplate:44 html/Ticket/ModifyAll.html:87
+msgid "Content"
+msgstr "Inhalt"
+
+#: etc/initialdata:266
+msgid "Correspondence"
+msgstr "Korrespondenz"
+
+#: html/Admin/Elements/ModifyQueue:39 html/Admin/Queues/Modify.html:51
+msgid "Correspondence Address"
+msgstr "Korrespondenzadresse"
+
+#: lib/RT/Transaction_Overlay.pm:541
+msgid "Correspondence added"
+msgstr "Korrespondenz hinzugefügt"
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3458
+msgid "Could not add new custom field value for ticket. "
+msgstr "Konnte dem Ticket kein neues benutzerdefiniertes Feld hinzufügen. "
+
+#: lib/RT/Ticket_Overlay.pm:2963 lib/RT/Ticket_Overlay.pm:2971 lib/RT/Ticket_Overlay.pm:2987
+msgid "Could not change owner. "
+msgstr "Konnte den Inhaber nicht ändern. "
+
+#: html/Admin/Elements/EditCustomField:68 html/Admin/Elements/EditCustomFields:166
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr "Konnte benutzerdefiniertes Feld nicht anlegen"
+
+#: html/User/Groups/Modify.html:77 lib/RT/Group_Overlay.pm:474 lib/RT/Group_Overlay.pm:481
+msgid "Could not create group"
+msgstr "Konnte Gruppe nicht anlegen"
+
+#: html/Admin/Global/Template.html:75 html/Admin/Queues/Template.html:72
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr "Konnte Vorlage nicht anlegen: %1"
+
+#: lib/RT/Ticket_Overlay.pm:1073 lib/RT/Ticket_Overlay.pm:333
+msgid "Could not create ticket. Queue not set"
+msgstr "Konnte Ticket nicht anlegen. Stapel nicht bestimmt"
+
+#: lib/RT/User_Overlay.pm:208 lib/RT/User_Overlay.pm:220 lib/RT/User_Overlay.pm:238 lib/RT/User_Overlay.pm:414
+msgid "Could not create user"
+msgstr "Konnte Benutzer nicht anlegen"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1422
+msgid "Could not find or create that user"
+msgstr "Konnte diesen Benutzer nicht finden oder anlegen"
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1501
+msgid "Could not find that principal"
+msgstr "Konnte diesen Hauptverantwortlichen nicht finden"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr ""
+
+#: html/Admin/Groups/Members.html:88 html/User/Groups/Members.html:90 html/User/Groups/Modify.html:82
+msgid "Could not load group"
+msgstr "Konnte die Gruppe nicht laden"
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr "Konnte den Hauptverantwortlichen nicht zu einen %1 dieses Stapels machen"
+
+#: lib/RT/Ticket_Overlay.pm:1443
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr "Konnte diesen Hauptverantwortlichen nicht zu einem %1 dieses Tickets machen"
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr "Konnte diesen Hauptverantwortlichen nicht als %1 dieses Stapels entfernen"
+
+#: lib/RT/Ticket_Overlay.pm:1559
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr "Konnte diesen Hauptverantwortlichen nicht als %1 dieses Tickets entfernen"
+
+#: lib/RT/Group_Overlay.pm:985
+msgid "Couldn't add member to group"
+msgstr "Konnte Mitglied nicht der Gruppe hinzufügen"
+
+#: lib/RT/Ticket_Overlay.pm:3468 lib/RT/Ticket_Overlay.pm:3524
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr "Konnte die Transaktion nicht anlegen: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:866
+msgid "Couldn't find row"
+msgstr "Konne Zeile nicht finden"
+
+#: lib/RT/Group_Overlay.pm:959
+msgid "Couldn't find that principal"
+msgstr "Konnte diesen Hauptverantwortlichen nicht finden"
+
+#: lib/RT/CustomField_Overlay.pm:175
+msgid "Couldn't find that value"
+msgstr "Konnte diesen Wert nicht finden"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr ""
+
+#: lib/RT/CurrentUser.pm:112
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr "Konnte %1 nicht aus der Benutzerdatenbank laden.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr ""
+
+#: html/Admin/Groups/GroupRights.html:88 html/Admin/Groups/UserRights.html:75
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr "Konnte Gruppe %1 nicht laden"
+
+#: lib/RT/Link_Overlay.pm:175 lib/RT/Link_Overlay.pm:184 lib/RT/Link_Overlay.pm:211
+msgid "Couldn't load link"
+msgstr "Konnte den Verweis nicht laden"
+
+#: html/Admin/Elements/EditCustomFields:147 html/Admin/Queues/People.html:121
+#. ($id)
+msgid "Couldn't load queue"
+msgstr "Konnte den Stapel nicht laden"
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:72
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr "Konnte den Stapel %1 nicht laden"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr ""
+
+#: html/Admin/Users/Prefs.html:79
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr "Konnte diesen Benutzer nicht laden (%1)"
+
+#: html/SelfService/Display.html:166
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr "Konnte das Ticket '%1' nicht laden"
+
+#: html/Admin/Elements/ModifyUser:86 html/Admin/Users/Modify.html:149 html/User/Prefs.html:98
+msgid "Country"
+msgstr "Land"
+
+#: html/Admin/Elements/CreateUserCalled:26 html/Ticket/Create.html:135 html/Ticket/Create.html:195
+msgid "Create"
+msgstr "Erstellen"
+
+#: etc/initialdata:128
+msgid "Create Tickets"
+msgstr "Erstelle Tickets"
+
+#: html/Admin/Elements/EditCustomField:58
+msgid "Create a CustomField"
+msgstr "Erstelle ein benutzerdefiniertes Feld"
+
+#: html/Admin/Queues/CustomField.html:48
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr "Erstelle ein benutzerdef. Feld für Stapel %1"
+
+#: html/Admin/Global/CustomField.html:48
+msgid "Create a CustomField which applies to all queues"
+msgstr "Erstelle ein benutzerdef. Feld für alle Stapel"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:67 html/Admin/Groups/Modify.html:93
+msgid "Create a new group"
+msgstr "Erstelle eine neue Gruppe"
+
+#: html/User/Groups/Modify.html:67 html/User/Groups/Modify.html:92
+msgid "Create a new personal group"
+msgstr "Erstelle eine neue persönliche Gruppe"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr ""
+
+#: html/SelfService/Create.html:30 html/Ticket/Create.html:25 html/Ticket/Create.html:28 html/Ticket/Create.html:36
+msgid "Create a new ticket"
+msgstr "Erstelle ein neues Ticket"
+
+#: html/Admin/Users/Modify.html:214 html/Admin/Users/Modify.html:241
+msgid "Create a new user"
+msgstr "Erstelle einen neuen Benutzer"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "Erstelle einen Stapel"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr ""
+
+#: html/SelfService/Create.html:25 html/SelfService/Create.html:27
+msgid "Create a request"
+msgstr "Erstelle ein Ticket"
+
+#: html/Admin/Queues/Scrip.html:59
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr "Erstelle ein Scrip für den Stapel %1"
+
+#: html/Admin/Global/Template.html:69 html/Admin/Queues/Template.html:65
+msgid "Create a template"
+msgstr "Erstelle eine Vorlage"
+
+#: etc/initialdata:130
+msgid "Create new tickets based on this scrip's template"
+msgstr "Erstelle neue Tickets basierend auf der Vorlage dieses Scrips"
+
+#: html/SelfService/Create.html:81
+msgid "Create ticket"
+msgstr "Ticket erstellen"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Create tickets in this queue"
+msgstr "Erstelle Tickets in diesem Stapel"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Create, delete and modify custom fields"
+msgstr "Erstellen, löschen und modifizieren von benutzerdef. Felder"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Create, delete and modify queues"
+msgstr "Erstelle, lösche und modifiziere Stapel"
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr ""
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify the members of personal groups"
+msgstr "Erstellen, löschen und modifizieren von Mitgliedern persönlicher Gruppen"
+
+#: lib/RT/System.pm:60
+msgid "Create, delete and modify users"
+msgstr "Erstellen, löschen und modifizieren von Benutzern"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "CreateTicket"
+msgstr ""
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1167
+msgid "Created"
+msgstr "Angelegt"
+
+#: html/Admin/Elements/EditCustomField:71
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr "Erstelle ein benutzerdefiniertes Feld %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr ""
+
+#: html/Ticket/Elements/EditLinks:28
+msgid "Current Relationships"
+msgstr "Momentane Beziehungen"
+
+#: html/Admin/Elements/EditScrips:30
+msgid "Current Scrips"
+msgstr "Aktuelle Scrips"
+
+#: html/Admin/Groups/Members.html:39 html/User/Groups/Members.html:42
+msgid "Current members"
+msgstr "Aktuelle Mitglieder"
+
+#: html/Admin/Elements/SelectRights:29
+msgid "Current rights"
+msgstr "Aktuelle Rechte"
+
+#: html/Search/Listing.html:71
+msgid "Current search criteria"
+msgstr "Aktuelle Suchkriterien"
+
+#: html/Admin/Queues/People.html:41 html/Ticket/Elements/EditPeople:45
+msgid "Current watchers"
+msgstr "Aktuelle Beobachter"
+
+#: html/Admin/Global/CustomField.html:55
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr "Benutzerdef. Feld #%1"
+
+#: html/Admin/Elements/QueueTabs:53 html/Admin/Elements/SystemTabs:40 html/Admin/Global/index.html:50 html/Ticket/Elements/ShowSummary:35
+msgid "Custom Fields"
+msgstr "Benutzerdef. Felder"
+
+#: html/Admin/Elements/EditScrip:73
+msgid "Custom action cleanup code"
+msgstr "Benutzerdefinierter Action-Cleanup-Code"
+
+#: html/Admin/Elements/EditScrip:65
+msgid "Custom action preparation code"
+msgstr "Benutzerdefinierter Aktions-Vorbereitungs-Code"
+
+#: html/Admin/Elements/EditScrip:49
+msgid "Custom condition"
+msgstr "Benutzerdefinierte Bedingung"
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr "Benutzerdefiniertes Feld %1 %2 %3"
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr "Benutzerdefiniertes Feld %1 hat einen Wert."
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr "Benutzerdefiniertes Feld %1 hat keinen Wert."
+
+#: lib/RT/Ticket_Overlay.pm:3360
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr "Benutzerdefiniertes Feld %1 nicht gefunden"
+
+#: html/Admin/Elements/EditCustomFields:197
+msgid "Custom field deleted"
+msgstr "Benutzerdefiniertes Feld wurde gelöscht"
+
+#: lib/RT/Ticket_Overlay.pm:3510
+msgid "Custom field not found"
+msgstr "Benutzerdefiniertes Feld nicht gefunden"
+
+#: lib/RT/CustomField_Overlay.pm:283
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr "Wert %1 des benutzerdefinierten Feldes %2 konnte nicht gefunden werden"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:185
+msgid "Custom field value could not be deleted"
+msgstr "Wert des benutzerdefinierten Felds konnte nicht gelöscht werden"
+
+#: lib/RT/CustomField_Overlay.pm:289
+msgid "Custom field value could not be found"
+msgstr "Wert des benutzerdefinierten Feldes konnte nicht gefunden werden"
+
+#: lib/RT/CustomField_Overlay.pm:183 lib/RT/CustomField_Overlay.pm:291
+msgid "Custom field value deleted"
+msgstr "Wert des benutzerdefinierten Feldes gelöscht"
+
+#: lib/RT/Transaction_Overlay.pm:550
+msgid "CustomField"
+msgstr ""
+
+#: html/Ticket/Create.html:161 html/Ticket/Elements/ShowSummary:53 html/Ticket/Elements/Tabs:93 html/Ticket/ModifyAll.html:44
+msgid "Dates"
+msgstr "Datumsangaben"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "Dez"
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr ""
+
+#: etc/initialdata:207
+msgid "Default Autoresponse template"
+msgstr "Standard Autoresponse-Vorlage"
+
+#: etc/initialdata:275
+msgid "Default admin comment template"
+msgstr "Standard Admin-Kommentar-Vorlage"
+
+#: etc/initialdata:257
+msgid "Default admin correspondence template"
+msgstr "Standard Admin-Korrespondenz-Vorlage"
+
+#: etc/initialdata:267
+msgid "Default correspondence template"
+msgstr "Standard Korrespondenz-Vorlage"
+
+#: etc/initialdata:238
+msgid "Default transaction template"
+msgstr "Standard Transaktions-Vorlage"
+
+#: lib/RT/Transaction_Overlay.pm:645
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr "Standard: %1/%2 von \"%3\" in \"%4\" geändert."
+
+#: html/User/Delegation.html:25 html/User/Delegation.html:28
+msgid "Delegate rights"
+msgstr "Rechte weitergeben"
+
+#: lib/RT/System.pm:63
+msgid "Delegate specific rights which have been granted to you."
+msgstr "Dir gewährte Rechte weitergeben"
+
+#: lib/RT/System.pm:63
+msgid "DelegateRights"
+msgstr ""
+
+#: html/User/Elements/Tabs:38
+msgid "Delegation"
+msgstr "Rechteweitergabe"
+
+#: NOT FOUND IN SOURCE
+msgid "Delete"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "Delete tickets"
+msgstr "Lösche Tickets"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "DeleteTicket"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr "Löschen dieses Objektes kann die referenzielle Integrität gefährden"
+
+#: lib/RT/Queue_Overlay.pm:292
+msgid "Deleting this object would break referential integrity"
+msgstr "Löschen dieses Objektes würde die referenzielle Integrität gefährden"
+
+#: lib/RT/User_Overlay.pm:430
+msgid "Deleting this object would violate referential integrity"
+msgstr "Löschen dieses Objektes würde die referenzielle Integrität verletzen"
+
+#: html/Approvals/Elements/Approve:46
+msgid "Deny"
+msgstr "Ablehnen"
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/EditLinks:123 html/Ticket/Elements/EditLinks:47 html/Ticket/Elements/ShowDependencies:32 html/Ticket/Elements/ShowLinks:35
+msgid "Depended on by"
+msgstr "Abhängig gemacht von"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr ""
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:180 html/Ticket/Elements/EditLinks:119 html/Ticket/Elements/EditLinks:36 html/Ticket/Elements/ShowDependencies:25 html/Ticket/Elements/ShowLinks:27
+msgid "Depends on"
+msgstr "Abhängig von"
+
+#: html/Elements/SelectSortOrder:35
+msgid "Descending"
+msgstr "absteigend"
+
+#: html/SelfService/Create.html:75 html/Ticket/Create.html:119
+msgid "Describe the issue below"
+msgstr "Beschreibe hier das Problem"
+
+#: html/Admin/Elements/AddCustomFieldValue:27 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/EditScrip:34 html/Admin/Elements/ModifyQueue:36 html/Admin/Elements/ModifyTemplate:36 html/Admin/Groups/Modify.html:49 html/Admin/Queues/Modify.html:48 html/Elements/SelectGroups:27 html/User/Groups/Modify.html:49
+msgid "Description"
+msgstr "Beschreibung"
+
+#: html/SelfService/Elements/MyRequests:44
+msgid "Details"
+msgstr "Details"
+
+#: html/Ticket/Elements/Tabs:85
+msgid "Display"
+msgstr "Anzeigen"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Display Access Control List"
+msgstr "Zeige Zugriffskontrollliste an"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Display Scrip templates for this queue"
+msgstr "Zeige Scrip-Vorlagen für diesen Stapel"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Display Scrips for this queue"
+msgstr "Zeige Scrips für diesen Stapel"
+
+#: html/Ticket/Elements/ShowHistory:35
+msgid "Display mode"
+msgstr "Anzeigemodus"
+
+#: html/SelfService/Display.html:25 html/SelfService/Display.html:29
+#. ($Ticket->id)
+msgid "Display ticket #%1"
+msgstr "Zeige Ticket #%1 an"
+
+#: lib/RT/System.pm:54
+msgid "Do anything and everything"
+msgstr "Mache irgend etwas und alles"
+
+#: html/Elements/Refresh:30
+msgid "Don't refresh this page."
+msgstr "Seite nicht aktualisieren."
+
+#: html/Search/Elements/PickRestriction:114
+msgid "Don't show search results"
+msgstr "Suchergebnisse nicht anzeigen"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "Download"
+msgstr "Download"
+
+#: html/Elements/SelectDateType:32 html/Ticket/Create.html:167 html/Ticket/Elements/EditDates:45 html/Ticket/Elements/ShowDates:43 lib/RT/Ticket_Overlay.pm:1171
+msgid "Due"
+msgstr "Fällig"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr ""
+
+#: bin/rt-commit-handler:754
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr "FEHLER: Konnte Ticket '%1' nicht laden: %2.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit"
+msgstr ""
+
+#: html/Admin/Queues/CustomFields.html:45
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr "Bearbeite benutzerdefinierte Felder für %1"
+
+#: html/Ticket/ModifyLinks.html:36
+msgid "Edit Relationships"
+msgstr "Bearbeite Beziehungen"
+
+#: html/Admin/Queues/Templates.html:41
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr "Bearbeite Vorlagen für Stapel %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr ""
+
+#: html/Admin/Global/index.html:46
+msgid "Edit system templates"
+msgstr "Bearbeite Systemvorlagen"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:25 html/Admin/Queues/Modify.html:117
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr "Bearbeite Konfiguration für den Stapel %1"
+
+#: html/Admin/Elements/ModifyUser:25
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr "Bearbeite Konfiguration für Benutzer %1"
+
+#: html/Admin/Elements/EditCustomField:74
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr "Bearbeite benutzerdefiniertes Feld %1"
+
+#: html/Admin/Groups/Members.html:32
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr "Bearbeite Mitgliedschaft für die Gruppe %1"
+
+#: html/User/Groups/Members.html:129
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr "Bearbeite Mitgliedschaft der persönlichen Gruppe %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2615 lib/RT/Ticket_Overlay.pm:2683
+msgid "Either base or target must be specified"
+msgstr "Es muß entweder eine Basis oder ein Ziel angegeben werden"
+
+#: html/Admin/Users/Modify.html:53 html/Admin/Users/Prefs.html:46 html/Elements/SelectUsers:27 html/Ticket/Elements/AddWatchers:56 html/User/Prefs.html:42
+msgid "Email"
+msgstr "E-Mail"
+
+#: lib/RT/User_Overlay.pm:188
+msgid "Email address in use"
+msgstr "E-Mail-Adresse bereits in Gebrauch"
+
+#: html/Admin/Elements/ModifyUser:42
+msgid "EmailAddress"
+msgstr "E-Mail-Adresse"
+
+### muss das überhaupt übersetzt werden???
+#: html/Admin/Elements/ModifyUser:54
+msgid "EmailEncoding"
+msgstr "E-Mail-Kodierung"
+
+### muss das überhaupt übersetzt werden???
+#: html/Admin/Elements/EditCustomField:36
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr "Aktiviert (Abwählen deaktiviert dieses benutzerdef. Feld)"
+
+#: html/Admin/Groups/Modify.html:53 html/User/Groups/Modify.html:53
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr "Aktiviert (Abwählen deaktiviert diese Gruppe)"
+
+#: html/Admin/Queues/Modify.html:84
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr "Aktiviert (Abwählen deaktiviert diesen Stapel)"
+
+#: html/Admin/Elements/EditCustomFields:99
+msgid "Enabled Custom Fields"
+msgstr "Aktivierte benutzerdefinierte Felder"
+
+#: html/Admin/Queues/index.html:56
+msgid "Enabled Queues"
+msgstr "Aktivierte Stapel"
+
+#: html/Admin/Elements/EditCustomField:90 html/Admin/Groups/Modify.html:117 html/Admin/Queues/Modify.html:138 html/Admin/Users/Modify.html:283 html/User/Groups/Modify.html:117
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr "Status %1 aktiviert"
+
+#: lib/RT/CustomField_Overlay.pm:361
+msgid "Enter multiple values"
+msgstr "Mehrere Werte eingeben"
+
+#: lib/RT/CustomField_Overlay.pm:358
+msgid "Enter one value"
+msgstr "Einen Wert eingeben"
+
+#: html/Ticket/Elements/EditLinks:112
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "Ticketnummern oder URIs getrennt durch Leerzeichen eingeben."
+
+#: html/Elements/Login:29 html/SelfService/Error.html:25 html/SelfService/Error.html:26
+msgid "Error"
+msgstr "Fehler"
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr "Fehler in den Parameter für Queue-AddWatcher"
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr "Fehler in den Paramter für Queue->DelWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1356
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr "Fehler in den Parameter für Ticket->AddWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1532
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr "Fehler in den Parameter für Ticket->DelWatcher"
+
+#: etc/initialdata:20
+msgid "Everyone"
+msgstr "Everyone"
+
+#: bin/rt-crontool:194
+msgid "Example:"
+msgstr "Beispiel:"
+
+#: html/Admin/Elements/ModifyUser:64
+msgid "ExternalAuthId"
+msgstr "ExternalAuthId"
+
+#: html/Admin/Elements/ModifyUser:58
+msgid "ExternalContactInfoId"
+msgstr "ExternalContactInfoId"
+
+#: html/Admin/Users/Modify.html:73
+msgid "Extra info"
+msgstr "Zusatzinformationen"
+
+#: lib/RT/User_Overlay.pm:302
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr "Konnte die Pseudogruppe 'Privileged' nicht finden."
+
+#: lib/RT/User_Overlay.pm:309
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr "Failed to find 'Unprivileged' users pseudogroup"
+
+#: bin/rt-crontool:138
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr "Konnte Modul %1 nicht laden. (%2)"
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "Feb"
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr ""
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:59 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "Endpriorität"
+
+#: lib/RT/Ticket_Overlay.pm:1162
+msgid "FinalPriority"
+msgstr ""
+
+#: html/Admin/Queues/People.html:61 html/Ticket/Elements/EditPeople:34
+msgid "Find group whose"
+msgstr "Finde Gruppe wessen"
+
+#: html/Elements/Quicksearch:25
+msgid "Find new/open tickets"
+msgstr "Finde neue/offene Tickets"
+
+#: html/Admin/Queues/People.html:57 html/Admin/Users/index.html:46 html/Ticket/Elements/EditPeople:30
+msgid "Find people whose"
+msgstr "Finde Leute deren"
+
+#: html/Search/Listing.html:108
+msgid "Find tickets"
+msgstr "Anfragen suchen"
+
+#: NOT FOUND IN SOURCE
+msgid "Finish Approval"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:58
+msgid "First"
+msgstr "Erste"
+
+#: html/Search/Listing.html:41
+msgid "First page"
+msgstr "Erste Seite"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr "Foo Bar Baz"
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr "Foo!"
+
+#: html/Search/Bulk.html:87
+msgid "Force change"
+msgstr "erzwinge Änderung"
+
+#: html/Search/Listing.html:106
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr "%quant(%1,ticket) gefunden"
+
+#: lib/RT/Interface/Web.pm:868
+msgid "Found Object"
+msgstr "Objekt gefunden"
+
+#: html/Admin/Elements/ModifyUser:44
+msgid "FreeformContactInfo"
+msgstr "FreeformContactInfo"
+
+#: lib/RT/CustomField_Overlay.pm:38
+msgid "FreeformMultiple"
+msgstr "FreieMehrfachauswahl"
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformSingle"
+msgstr "FreieEinzelauswahl"
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "Fr"
+
+#: html/Ticket/Elements/ShowHistory:41 html/Ticket/Elements/ShowHistory:51
+msgid "Full headers"
+msgstr "Alle Kopfzeilen"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:595
+#. ($New->Name)
+msgid "Given to %1"
+msgstr "An %1 gegeben"
+
+#: html/Admin/Elements/Tabs:41 html/Admin/index.html:38
+msgid "Global"
+msgstr "Global"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr ""
+
+#: html/Admin/Elements/SelectTemplate:38
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr "Globale Vorlage: %1"
+
+#: html/Admin/Elements/EditCustomFields:75 html/Admin/Queues/People.html:59 html/Admin/Queues/People.html:63 html/Admin/Queues/index.html:44 html/Admin/Users/index.html:49 html/Ticket/Elements/EditPeople:32 html/Ticket/Elements/EditPeople:36 html/index.html:41
+msgid "Go!"
+msgstr "Los!"
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr ""
+
+#: html/Search/Listing.html:50
+msgid "Goto page"
+msgstr "Gehe zu Seite"
+
+#: html/Elements/GotoTicket:25 html/SelfService/Elements/GotoTicket:25
+msgid "Goto ticket"
+msgstr "Zeig' Ticket"
+
+#: html/Ticket/Elements/AddWatchers:46 html/User/Elements/DelegateRights:78
+msgid "Group"
+msgstr "Gruppe"
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:45 html/Admin/Elements/QueueTabs:57 html/Admin/Elements/SystemTabs:44 html/Admin/Global/index.html:55
+msgid "Group Rights"
+msgstr "Gruppenrechte"
+
+#: lib/RT/Group_Overlay.pm:965
+msgid "Group already has member"
+msgstr "Gruppe hat bereits Mitglieder"
+
+#: html/Admin/Groups/Modify.html:77
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr "Gruppe konnte nicht erstellt werden: %1"
+
+#: lib/RT/Group_Overlay.pm:497
+msgid "Group created"
+msgstr "Gruppe angelegt"
+
+#: lib/RT/Group_Overlay.pm:1133
+msgid "Group has no such member"
+msgstr "Gruppe hat kein solches Mitglied"
+
+#: lib/RT/Group_Overlay.pm:945 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1429 lib/RT/Ticket_Overlay.pm:1507
+msgid "Group not found"
+msgstr "Gruppe nicht gefunden"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr ""
+
+#: html/Admin/Elements/SelectNewGroupMembers:35 html/Admin/Elements/Tabs:35 html/Admin/Groups/Members.html:64 html/Admin/Queues/People.html:83 html/Admin/index.html:32 html/User/Groups/Members.html:67
+msgid "Groups"
+msgstr "Gruppen"
+
+#: lib/RT/Group_Overlay.pm:971
+msgid "Groups can't be members of their members"
+msgstr "Gruppen können nicht Mitglied eines ihrer Mitglieder sein"
+
+#: lib/RT/Interface/CLI.pm:73 lib/RT/Interface/CLI.pm:73
+msgid "Hello!"
+msgstr "Hallo!"
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr "Hallo %1"
+
+#: html/Ticket/Elements/ShowHistory:30 html/Ticket/Elements/Tabs:88
+msgid "History"
+msgstr "Historie"
+
+#: html/Admin/Elements/ModifyUser:68
+msgid "HomePhone"
+msgstr "TelefonZuhause"
+
+#: html/Elements/Tabs:46
+msgid "Homepage"
+msgstr "Start"
+
+#: lib/RT/Base.pm:74
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "I have [quant,_1,concrete mixer]."
+msgstr ""
+
+#: html/Ticket/Elements/ShowBasics:27 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr "Nr."
+
+#: html/Admin/Users/Modify.html:44 html/User/Prefs.html:39
+msgid "Identity"
+msgstr "Identität"
+
+#: etc/upgrade/2.1.71:86
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr "Wenn eine Freigabe abgewiesen wird, weise das Original ab und lösche wartende Freigaben"
+
+#: bin/rt-crontool:190
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr "Wenn dieses Werkzeug 'setgid' wäre könnte ein feindlicher lokaler Benutzer dadurch administrativen Zugriff auf RT erlangen."
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "If you've updated anything above, be sure to"
+msgstr "Wenn du irgend etwas aktualisiert hast, denke daran hier zu klicken"
+
+#: lib/RT/Interface/Web.pm:860
+msgid "Illegal value for %1"
+msgstr "Unerlaubter Wert für %1"
+
+#: lib/RT/Interface/Web.pm:863
+msgid "Immutable field"
+msgstr "Unveränderbares Feld"
+
+#: html/Admin/Elements/EditCustomFields:74
+msgid "Include disabled custom fields in listing."
+msgstr "Zeige auch deaktivierte benutzerdefinierte Felder an."
+
+#: html/Admin/Queues/index.html:43
+msgid "Include disabled queues in listing."
+msgstr "Zeige auch deaktivierte Stapel an."
+
+#: html/Admin/Users/index.html:47
+msgid "Include disabled users in search."
+msgstr "Zeige deaktivierte Benutzer auch in der Suche an."
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr "Anfängliche Priorität"
+
+#: lib/RT/Ticket_Overlay.pm:1161 lib/RT/Ticket_Overlay.pm:1163
+msgid "InitialPriority"
+msgstr ""
+
+#: lib/RT/ScripAction_Overlay.pm:105
+msgid "Input error"
+msgstr "Eingabefehler"
+
+#: lib/RT/Ticket_Overlay.pm:3729
+msgid "Internal Error"
+msgstr "Interner Fehler"
+
+#: lib/RT/Record.pm:143
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr "Internet Fehler: %1"
+
+#: lib/RT/Group_Overlay.pm:644
+msgid "Invalid Group Type"
+msgstr "Ungültige Gruppenart"
+
+#: lib/RT/Principal_Overlay.pm:128
+msgid "Invalid Right"
+msgstr "Ungültiges Recht"
+
+#: lib/RT/Interface/Web.pm:865
+msgid "Invalid data"
+msgstr "Ungültige Daten"
+
+#: lib/RT/Ticket_Overlay.pm:438
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr "Ungültiger Inhaber. Zurücksetzung auf 'nobody'."
+
+#: lib/RT/Scrip_Overlay.pm:134 lib/RT/Template_Overlay.pm:251
+msgid "Invalid queue"
+msgstr "Ungültiger Stapel"
+
+#: lib/RT/ACE_Overlay.pm:244 lib/RT/ACE_Overlay.pm:253 lib/RT/ACE_Overlay.pm:259 lib/RT/ACE_Overlay.pm:270 lib/RT/ACE_Overlay.pm:275
+msgid "Invalid right"
+msgstr "Ungültiges Recht"
+
+#: lib/RT/Record.pm:118
+#. ($key)
+msgid "Invalid value for %1"
+msgstr "Ungültiger Wert für %1"
+
+#: lib/RT/Ticket_Overlay.pm:3367
+msgid "Invalid value for custom field"
+msgstr "Ungültiger Wert für das benutzerdefinierte Feld"
+
+#: lib/RT/Ticket_Overlay.pm:345
+msgid "Invalid value for status"
+msgstr "Ungültiger Statuswert"
+
+#: bin/rt-crontool:191
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr "Es ist sehr wichtig dass nichtprivilegierte Benutzer dieses Werkzeug nicht aufrufen können."
+
+#: bin/rt-crontool:192
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr "Es wird empfohlen einen nichtprivilegierten Unix-User mit korrekter Gruppenzugehörigkeit zum Zugriff auf RT anzulegen um dieses Werkzeug aufzurufen."
+
+#: bin/rt-crontool:163
+msgid "It takes several arguments:"
+msgstr "Es verarbeitet verschiedene Parameter:"
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr ""
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "Jan"
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "Join or leave this group"
+msgstr "Betrete oder verlasse diese Gruppe"
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "Jul"
+
+#: html/Ticket/Elements/Tabs:99
+msgid "Jumbo"
+msgstr "Alles"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "Jun"
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:52
+msgid "Lang"
+msgstr "Sprache"
+
+#: html/Ticket/Elements/Tabs:73
+msgid "Last"
+msgstr "letzter Kontakt"
+
+#: html/Ticket/Elements/EditDates:38 html/Ticket/Elements/ShowDates:39
+msgid "Last Contact"
+msgstr "Letzter Kontakt"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Contacted"
+msgstr "Zuletzt Kontaktiert"
+
+#: html/Search/Elements/TicketHeader:41
+msgid "Last Notified"
+msgstr "Letzte Änderung"
+
+#: html/Elements/SelectDateType:30
+msgid "Last Updated"
+msgstr "Zuletzt Aktualisiert"
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:83
+msgid "Let this user access RT"
+msgstr "Diesen Benutzer RT-Zugriff gewähren"
+
+#: html/Admin/Users/Modify.html:87
+msgid "Let this user be granted rights"
+msgstr "Diesen Benutzer mehr Rechte gewähren"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2697
+msgid "Link already exists"
+msgstr "Beziehung existiert bereits"
+
+#: lib/RT/Ticket_Overlay.pm:2709
+msgid "Link could not be created"
+msgstr "Beziehung konnte nicht erstellt werden"
+
+#: lib/RT/Ticket_Overlay.pm:2717 lib/RT/Ticket_Overlay.pm:2727
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr "Beziehung erstellt (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2638
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr "Beziehung gelöscht (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2644
+msgid "Link not found"
+msgstr "Beziehung nicht gefunden"
+
+#: html/Ticket/ModifyLinks.html:25 html/Ticket/ModifyLinks.html:29
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr "Verweise auf Ticket #%1"
+
+#: html/Ticket/Elements/Tabs:97
+msgid "Links"
+msgstr "Beziehungen"
+
+#: html/Admin/Users/Modify.html:114 html/User/Prefs.html:85
+msgid "Location"
+msgstr "Adresse"
+
+#: lib/RT.pm:158
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr "Log-Verzeichnis %1 nicht gefunden oder kein Schreibzugriff.\\n RT kann nicht starten."
+
+#: html/Elements/Header:57
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "Angemeldet als %1"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:25 html/Elements/Login:34 html/Elements/Login:45
+msgid "Login"
+msgstr "Anmelden"
+
+#: html/Elements/Header:54
+msgid "Logout"
+msgstr "Abmelden"
+
+#: html/Search/Bulk.html:86
+msgid "Make Owner"
+msgstr "Mach Inhaber"
+
+#: html/Search/Bulk.html:102
+msgid "Make Status"
+msgstr "Mach Status"
+
+#: html/Search/Bulk.html:109
+msgid "Make date Due"
+msgstr "Mach Fälligkeitsdatum"
+
+#: html/Search/Bulk.html:110
+msgid "Make date Resolved"
+msgstr "Mach Erledigungsdatum"
+
+#: html/Search/Bulk.html:107
+msgid "Make date Started"
+msgstr "Mach Datum gestartet"
+
+#: html/Search/Bulk.html:106
+msgid "Make date Starts"
+msgstr "Mach Startdatum"
+
+#: html/Search/Bulk.html:108
+msgid "Make date Told"
+msgstr "Mach Eingangsdatum"
+
+#: html/Search/Bulk.html:99
+msgid "Make priority"
+msgstr "Mach Priorität"
+
+#: html/Search/Bulk.html:100
+msgid "Make queue"
+msgstr "Mach Stapel"
+
+#: html/Search/Bulk.html:98
+msgid "Make subject"
+msgstr "Betreff setzen"
+
+#: html/Admin/index.html:33
+msgid "Manage groups and group membership"
+msgstr "Gruppen und Gruppenmitglieder verwalten"
+
+#: html/Admin/index.html:39
+msgid "Manage properties and configuration which apply to all queues"
+msgstr "Eigenschaften und Einstellungen für alle Stapel verwalten"
+
+#: html/Admin/index.html:36
+msgid "Manage queues and queue-specific properties"
+msgstr "Stapel und stapelspezifische Einstellungen verwalten"
+
+#: html/Admin/index.html:30
+msgid "Manage users and passwords"
+msgstr "Benutzer und Passworte verwalten"
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "Mär"
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "Mai."
+
+#: lib/RT/Group_Overlay.pm:982
+msgid "Member added"
+msgstr "Mitglied hinzugefügt"
+
+#: lib/RT/Group_Overlay.pm:1140
+msgid "Member deleted"
+msgstr "Mitglied gelöscht"
+
+#: lib/RT/Group_Overlay.pm:1144
+msgid "Member not deleted"
+msgstr "Mitglied nicht gelöscht"
+
+#: html/Elements/SelectLinkType:26
+msgid "Member of"
+msgstr "Mitglied von"
+
+#: html/Admin/Elements/GroupTabs:42 html/User/Elements/GroupTabs:42
+msgid "Members"
+msgstr "Mitglieder"
+
+#: lib/RT/Ticket_Overlay.pm:2843
+msgid "Merge Successful"
+msgstr "Zusammenführung erfolgreich"
+
+#: lib/RT/Ticket_Overlay.pm:2804
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "Zusammenführung fehlgeschlagen. Konnte EffectiveId nicht setztn"
+
+#: html/Ticket/Elements/EditLinks:115
+msgid "Merge into"
+msgstr "Zusammenführen in"
+
+#: html/Ticket/Update.html:102
+msgid "Message"
+msgstr "Nachricht"
+
+#: lib/RT/Interface/Web.pm:867
+msgid "Missing a primary key?: %1"
+msgstr "%1: Fehlt ein Primärschlüssel?"
+
+#: html/Admin/Users/Modify.html:169 html/User/Prefs.html:54
+msgid "Mobile"
+msgstr "Mobil"
+
+#: html/Admin/Elements/ModifyUser:72
+msgid "MobilePhone"
+msgstr "Mobiltelefon"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify Access Control List"
+msgstr "Ändere Zugriffskontrollliste"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Custom Field %1"
+msgstr ""
+
+#: html/Admin/Global/CustomFields.html:44 html/Admin/Global/index.html:51
+msgid "Modify Custom Fields which apply to all queues"
+msgstr "Ändere benutzdefinierte Felder für diesen Stapel"
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "Modify Scrip templates for this queue"
+msgstr "Ändere Scrip-Vorlagen für diesen Stapel"
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "Modify Scrips for this queue"
+msgstr "Ändere Scrips für diesen Stapel"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr ""
+
+#: html/Admin/Queues/CustomField.html:45
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr "Ändere ein benutzerdefiniertes Feld für Stapel %1"
+
+#: html/Admin/Global/CustomField.html:53
+msgid "Modify a CustomField which applies to all queues"
+msgstr "Ändere ein globales benutzerdefiniertes Feld"
+
+#: html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr "Ändere ein Scrip für den Stapel %1"
+
+#: html/Admin/Global/Scrip.html:48
+msgid "Modify a scrip which applies to all queues"
+msgstr "Ändere ein globales benutzerdefiniertes Feld"
+
+#: html/Ticket/ModifyDates.html:25 html/Ticket/ModifyDates.html:29
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr "Ändere Datumsangaben für #%1"
+
+#: html/Ticket/ModifyDates.html:35
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr "Ändere Datumsangaben für Ticket #%1"
+
+#: html/Admin/Global/GroupRights.html:25 html/Admin/Global/GroupRights.html:28 html/Admin/Global/index.html:56
+msgid "Modify global group rights"
+msgstr "Ändere globale Gruppenrechte"
+
+#: html/Admin/Global/GroupRights.html:33
+msgid "Modify global group rights."
+msgstr "Ändere globale Gruppenrechte."
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr ""
+
+#: html/Admin/Global/UserRights.html:25 html/Admin/Global/UserRights.html:28 html/Admin/Global/index.html:60
+msgid "Modify global user rights"
+msgstr "Ändere globale Benutzerrechte"
+
+#: html/Admin/Global/UserRights.html:33
+msgid "Modify global user rights."
+msgstr "Ändere globale Benutzerrechte."
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "Modify group metadata or delete group"
+msgstr "Ändere Gruppen-Metadaten oder lösche die Gruppe"
+
+#: html/Admin/Groups/GroupRights.html:25 html/Admin/Groups/GroupRights.html:29 html/Admin/Groups/GroupRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr "Ändere die Gruppenrechte der Gruppe %1"
+
+#: html/Admin/Queues/GroupRights.html:25 html/Admin/Queues/GroupRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr "Ändere Gruppenrechte für Stapel %1"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Modify membership roster for this group"
+msgstr "Ändere Mitgliedsverzeichnis dieser Gruppe"
+
+#: lib/RT/System.pm:61
+msgid "Modify one's own RT account"
+msgstr "Ändere jemandens eigenen RT-Zugang"
+
+#: html/Admin/Queues/People.html:25 html/Admin/Queues/People.html:29
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr "Ändere Leute bezogen auf Stapel %1"
+
+#: html/Ticket/ModifyPeople.html:25 html/Ticket/ModifyPeople.html:29 html/Ticket/ModifyPeople.html:35
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr "Ändere Personen des Tickets #%1"
+
+#: html/Admin/Queues/Scrips.html:44
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr "Ändere Scrips für den Stapel %1"
+
+#: html/Admin/Global/Scrips.html:44 html/Admin/Global/index.html:42
+msgid "Modify scrips which apply to all queues"
+msgstr "Ändere auf alle Stapel angewandte Scrips"
+
+#: html/Admin/Global/Template.html:25 html/Admin/Global/Template.html:30 html/Admin/Global/Template.html:81 html/Admin/Queues/Template.html:78
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr "Ändere Vorlage %1"
+
+#: html/Admin/Global/Templates.html:44
+msgid "Modify templates which apply to all queues"
+msgstr "Ändere globale Templates"
+
+#: html/Admin/Groups/Modify.html:87 html/User/Groups/Modify.html:86
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr "Ändere Gruppe %1"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Modify the queue watchers"
+msgstr "Ändere die Stapelbeobachter"
+
+#: html/Admin/Users/Modify.html:236
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr "Ändere Benutzer %1"
+
+#: html/Ticket/ModifyAll.html:37
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "Ändere Ticket #%1"
+
+#: html/Ticket/Modify.html:25 html/Ticket/Modify.html:28 html/Ticket/Modify.html:34
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "Ändere Ticket #%1"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Modify tickets"
+msgstr "Ändere Tickets"
+
+#: html/Admin/Groups/UserRights.html:25 html/Admin/Groups/UserRights.html:29 html/Admin/Groups/UserRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr "Ändere Benutzerrechte für die Gruppe %1"
+
+#: html/Admin/Queues/UserRights.html:25 html/Admin/Queues/UserRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr "Ändere Benutzerrechte für Stapel %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyACL"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "ModifyOwnMembership"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "ModifyQueueWatchers"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "ModifyScrips"
+msgstr ""
+
+#: lib/RT/System.pm:61
+msgid "ModifySelf"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "ModifyTemplate"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "ModifyTicket"
+msgstr ""
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "Mo"
+
+#: html/Ticket/Elements/ShowRequestor:42
+#. ($name)
+msgid "More about %1"
+msgstr "Mehr über %1"
+
+#: html/Admin/Elements/EditCustomFields:61
+msgid "Move down"
+msgstr "Runter verschieben"
+
+#: html/Admin/Elements/EditCustomFields:53
+msgid "Move up"
+msgstr "Hoch verschieben"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:27
+msgid "Multiple"
+msgstr "Mehrere"
+
+#: lib/RT/User_Overlay.pm:179
+msgid "Must specify 'Name' attribute"
+msgstr "Du musst eine Angabe bei 'Name' machen"
+
+#: NOT FOUND IN SOURCE
+msgid "My Approvals"
+msgstr ""
+
+#: html/Approvals/index.html:25 html/Approvals/index.html:26
+msgid "My approvals"
+msgstr "Meine Freigaben"
+
+#: html/Admin/Elements/AddCustomFieldValue:26 html/Admin/Elements/EditCustomField:32 html/Admin/Elements/ModifyTemplate:28 html/Admin/Elements/ModifyUser:30 html/Admin/Groups/Modify.html:44 html/Elements/SelectGroups:26 html/Elements/SelectUsers:28 html/User/Groups/Modify.html:44
+msgid "Name"
+msgstr "Name"
+
+#: lib/RT/User_Overlay.pm:186
+msgid "Name in use"
+msgstr "Benutzername ist bereits in Gebrauch"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr ""
+
+#: html/Ticket/Elements/ShowDates:52
+msgid "Never"
+msgstr "Niemals"
+
+#: html/Elements/Quicksearch:30
+msgid "New"
+msgstr "Neu"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:93 html/User/Prefs.html:65
+msgid "New Password"
+msgstr "Neues Passwort"
+
+#: etc/initialdata:311 etc/upgrade/2.1.71:16
+msgid "New Pending Approval"
+msgstr "Neue wartende Freigaben"
+
+#: html/Ticket/Elements/EditLinks:111
+msgid "New Relationships"
+msgstr "Neue Beziehungen"
+
+#: html/Ticket/Elements/Tabs:36
+msgid "New Search"
+msgstr "Neue Suche"
+
+#: html/Admin/Global/CustomField.html:41 html/Admin/Global/CustomFields.html:39 html/Admin/Queues/CustomField.html:52 html/Admin/Queues/CustomFields.html:40
+msgid "New custom field"
+msgstr "Neues benutzerdef. Feld"
+
+#: html/Admin/Elements/GroupTabs:54 html/User/Elements/GroupTabs:52
+msgid "New group"
+msgstr "Neue Gruppe"
+
+#: html/SelfService/Prefs.html:32
+msgid "New password"
+msgstr "Neues Passwort"
+
+#: lib/RT/User_Overlay.pm:639
+msgid "New password notification sent"
+msgstr "Neue Passworterinnerung wurde verschickt"
+
+#: html/Admin/Elements/QueueTabs:70
+msgid "New queue"
+msgstr "Neuer Stapel"
+
+#: html/SelfService/Elements/Tabs:63
+msgid "New request"
+msgstr "Neues Ticket"
+
+#: html/Admin/Elements/SelectRights:42
+msgid "New rights"
+msgstr "Neue Rechte"
+
+#: html/Admin/Global/Scrip.html:40 html/Admin/Global/Scrips.html:39 html/Admin/Queues/Scrip.html:43 html/Admin/Queues/Scrips.html:53
+msgid "New scrip"
+msgstr "Neues Scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "New search"
+msgstr ""
+
+#: html/Admin/Global/Template.html:60 html/Admin/Global/Templates.html:39 html/Admin/Queues/Template.html:58 html/Admin/Queues/Templates.html:46
+msgid "New template"
+msgstr "Neue Vorlage"
+
+#: lib/RT/Ticket_Overlay.pm:2771
+msgid "New ticket doesn't exist"
+msgstr "Neues Ticket existiert nicht"
+
+#: html/Admin/Elements/UserTabs:52
+msgid "New user"
+msgstr "Neuer Benutzer"
+
+#: html/Admin/Elements/CreateUserCalled:26
+msgid "New user called"
+msgstr "Neues Benutzer aufgerufen"
+
+#: html/Admin/Queues/People.html:55 html/Ticket/Elements/EditPeople:29
+msgid "New watchers"
+msgstr "Neue Beobachter"
+
+#: html/Admin/Users/Prefs.html:42
+msgid "New window setting"
+msgstr "Speichere Fenstereinstellungen"
+
+#: html/Ticket/Elements/Tabs:69
+msgid "Next"
+msgstr "Nächste"
+
+#: html/Search/Listing.html:48
+msgid "Next page"
+msgstr "Nächste Seite"
+
+#: html/Admin/Elements/ModifyUser:50
+msgid "NickName"
+msgstr "Spitzname"
+
+#: html/Admin/Users/Modify.html:63 html/User/Prefs.html:46
+msgid "Nickname"
+msgstr "Spitzname"
+
+#: html/Admin/Elements/EditCustomField:73 html/Admin/Elements/EditCustomFields:105
+msgid "No CustomField"
+msgstr "Kein benutzerdefiniertes Feld"
+
+#: html/Admin/Groups/GroupRights.html:84 html/Admin/Groups/UserRights.html:71
+msgid "No Group defined"
+msgstr "Keine Gruppe definiert"
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:68
+msgid "No Queue defined"
+msgstr "Kein Stapel vorhanden"
+
+#: bin/rt-crontool:56
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr "Kein RT-Benutzer gefunden. Bitte kontaktiere Deinen RT-Administrator.\\n"
+
+#: html/Admin/Global/Template.html:79 html/Admin/Queues/Template.html:76
+msgid "No Template"
+msgstr "Keine Vorlage"
+
+#: bin/rt-commit-handler:764
+msgid "No Ticket specified. Aborting ticket "
+msgstr "Kein Ticket angegeben. Bereche Ticket ab "
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr ""
+
+#: html/Approvals/Elements/Approve:47
+msgid "No action"
+msgstr "Keine Aktion"
+
+#: lib/RT/Interface/Web.pm:862
+msgid "No column specified"
+msgstr "Keine Spalte angegeben"
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr ""
+
+#: html/Elements/ViewUser:36 html/Ticket/Elements/ShowRequestor:45
+msgid "No comment entered about this user"
+msgstr "Kein Kommentar über diesen Benutzer angegeben"
+
+#: lib/RT/Ticket_Overlay.pm:2189 lib/RT/Ticket_Overlay.pm:2257
+msgid "No correspondence attached"
+msgstr "Keine Korrespondenz aufgezeichnet"
+
+#: lib/RT/Action/Generic.pm:150 lib/RT/Condition/Generic.pm:176 lib/RT/Search/ActiveTicketsInQueue.pm:56 lib/RT/Search/Generic.pm:113
+#. (ref $self)
+msgid "No description for %1"
+msgstr "Keine Beschreibung für %1 vorhanden"
+
+#: lib/RT/Users_Overlay.pm:151
+msgid "No group specified"
+msgstr "Keine Gruppe angegeben"
+
+#: lib/RT/User_Overlay.pm:857
+msgid "No password set"
+msgstr "Kein Passwort gesetzt"
+
+#: lib/RT/Queue_Overlay.pm:259
+msgid "No permission to create queues"
+msgstr "Kein Recht Stapel anzulegen"
+
+#: lib/RT/Ticket_Overlay.pm:341
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr "Kein Recht um Tickets im Stapel '%1' anzulegen"
+
+#: lib/RT/User_Overlay.pm:151
+msgid "No permission to create users"
+msgstr "Kein Recht Benutzer anzulegen"
+
+#: html/SelfService/Display.html:174
+msgid "No permission to display that ticket"
+msgstr "Kein Recht dieses Ticket anzuzeigen"
+
+#: html/SelfService/Update.html:55
+msgid "No permission to view update ticket"
+msgstr "Kein Recht dieses Ticket zu aktualisieren"
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1488
+msgid "No principal specified"
+msgstr "Kein Hauptverantwortlicher angegeben"
+
+#: html/Admin/Queues/People.html:154 html/Admin/Queues/People.html:164
+msgid "No principals selected."
+msgstr "Keine Hauptverantwortliche ausgewählt."
+
+#: html/Admin/Queues/index.html:35
+msgid "No queues matching search criteria found."
+msgstr "Keine den Suchkriterien entsprechenden Stapel gefunden"
+
+#: html/Admin/Elements/SelectRights:81
+msgid "No rights found"
+msgstr "Keine Rechte gefunden"
+
+#: html/Admin/Elements/SelectRights:33
+msgid "No rights granted."
+msgstr "Keine Rechte gewährt."
+
+#: html/Search/Bulk.html:149
+msgid "No search to operate on."
+msgstr "Keine Suchliste zum bearbeiten."
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:480 lib/RT/Transaction_Overlay.pm:518
+msgid "No transaction type specified"
+msgstr "Kein Transaktionstyp angegeben"
+
+#: html/Admin/Users/index.html:36
+msgid "No users matching search criteria found."
+msgstr "Keine auf die Suchkriterien passende Benutzer gefunden"
+
+#: bin/rt-commit-handler:644
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr "Kein gültiger RT-Benutzer gefunden. RT CVS-Handler weggefallen. Bitte kontaktiere Deinen RT-Administrator.\\n"
+
+#: lib/RT/Interface/Web.pm:859
+msgid "No value sent to _Set!\\n"
+msgstr "Kein Wert an _Set geschickt!\\n"
+
+#: html/Search/Elements/TicketRow:37
+msgid "Nobody"
+msgstr "Niemand"
+
+#: lib/RT/Interface/Web.pm:864
+msgid "Nonexistant field?"
+msgstr "Nichtexistierendes Feld?"
+
+#: html/Elements/Login:99
+msgid "Not logged in"
+msgstr "Nicht angemeldet"
+
+#: html/Elements/Header:59 html/SelfService/Elements/Header:58
+msgid "Not logged in."
+msgstr "Nicht angemeldet."
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "Nicht angegeben"
+
+#: html/NoAuth/Reminder.html:27
+msgid "Not yet implemented."
+msgstr "Noch nicht implementiert."
+
+#: html/Admin/Groups/Rights.html:25
+msgid "Not yet implemented...."
+msgstr "Noch nicht implementiert..."
+
+#: html/Approvals/Elements/Approve:50
+msgid "Notes"
+msgstr "Bemerkungen"
+
+#: lib/RT/User_Overlay.pm:642
+msgid "Notification could not be sent"
+msgstr "Benachrichtigung konnte nicht verschickt werden"
+
+#: etc/initialdata:94
+msgid "Notify AdminCcs"
+msgstr "Benachrichtige AdminCCs"
+
+#: etc/initialdata:90
+msgid "Notify AdminCcs as Comment"
+msgstr "Benachrichtige AdminCCs als Kommentar"
+
+#: etc/initialdata:121
+msgid "Notify Other Recipients"
+msgstr "Benachrichtige andere Empfänger"
+
+#: etc/initialdata:117
+msgid "Notify Other Recipients as Comment"
+msgstr "Benachrichtige andere Empfänger als Kommentar"
+
+#: etc/initialdata:86
+msgid "Notify Owner"
+msgstr "Benachrichte Inhaber"
+
+#: etc/initialdata:82
+msgid "Notify Owner as Comment"
+msgstr "Benachrichtige Inhaber als Kommentar"
+
+#: etc/initialdata:313 etc/upgrade/2.1.71:17
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr "Benachrichtige Inhaber und AdminCCs neuer auf Freigabe wartende Anfragen"
+
+#: etc/initialdata:78
+msgid "Notify Requestors"
+msgstr "Benachrichtige die Klienten"
+
+#: etc/initialdata:104
+msgid "Notify Requestors and Ccs"
+msgstr "Benachrichtige die Klienten und CCs"
+
+#: etc/initialdata:99
+msgid "Notify Requestors and Ccs as Comment"
+msgstr "Benachrichtige die Klienten und CCs als Kommentar"
+
+#: etc/initialdata:113
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr "Benachrichtige die Klienten, CCs und AdminCCs"
+
+#: etc/initialdata:109
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr "Benachrichtige die Klienten, CCs und AdminCCs als Kommentar"
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "Nov"
+
+#: lib/RT/Record.pm:157
+msgid "Object could not be created"
+msgstr "Objekt konnte nicht erstellt werden"
+
+#: lib/RT/Record.pm:176
+msgid "Object created"
+msgstr "Objekt erstellt"
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "Okt"
+
+#: html/Elements/SelectDateRelation:35
+msgid "On"
+msgstr "am"
+
+#: etc/initialdata:155
+msgid "On Comment"
+msgstr "Bei Kommentar"
+
+#: etc/initialdata:148
+msgid "On Correspond"
+msgstr "Bei Korrespondenz"
+
+#: etc/initialdata:137
+msgid "On Create"
+msgstr "Bei Erstellen"
+
+#: etc/initialdata:169
+msgid "On Owner Change"
+msgstr "Bei Eigentümerwechsel"
+
+#: etc/initialdata:177
+msgid "On Queue Change"
+msgstr "Bei Stapelwechsel"
+
+#: etc/initialdata:183
+msgid "On Resolve"
+msgstr "Beim Erledigen"
+
+#: etc/initialdata:161
+msgid "On Status Change"
+msgstr "Bei Statuswechsel"
+
+#: etc/initialdata:142
+msgid "On Transaction"
+msgstr "Bei einer Transaktion"
+
+#: html/Approvals/Elements/PendingMyApproval:50
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr "Zeige nur Freigaben für nach dem %1 erstelle Anfragen"
+
+#: html/Approvals/Elements/PendingMyApproval:48
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr "Zeige nur Freigaben für vor dem %1 erstellte Anfragen"
+
+#: html/Elements/Quicksearch:31
+msgid "Open"
+msgstr "Offen"
+
+#: html/Ticket/Elements/Tabs:136
+msgid "Open it"
+msgstr "Öffnen"
+
+#: html/SelfService/Elements/Tabs:57
+msgid "Open requests"
+msgstr "Offene Anfragen"
+
+#: html/Admin/Users/Prefs.html:41
+msgid "Open tickets (from listing) in a new window"
+msgstr "Öffne Anfragen (aus der Liste) in neuem Fenster"
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in another window"
+msgstr "Öffne Anfragen (aus der Liste) in ein anderes Fenster"
+
+#: etc/initialdata:133
+msgid "Open tickets on correspondence"
+msgstr "Öffne Anfragen bei Korrespondenz"
+
+#: html/Search/Elements/PickRestriction:101
+msgid "Ordering and sorting"
+msgstr "Sortierung und Reihenfolge"
+
+#: html/Admin/Elements/ModifyUser:46 html/Admin/Users/Modify.html:117 html/Elements/SelectUsers:29 html/User/Prefs.html:86
+msgid "Organization"
+msgstr "Organisation"
+
+#: html/Approvals/Elements/Approve:34
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr "Ursprüngliche Anfrage: #%1"
+
+#: html/Admin/Elements/ModifyQueue:55 html/Admin/Queues/Modify.html:69
+msgid "Over time, priority moves toward"
+msgstr "Mit der Zeit steigt die Priorität auf"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Own tickets"
+msgstr "Eigene Anfrage"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "OwnTicket"
+msgstr ""
+
+#: etc/initialdata:38 html/Elements/MyRequests:32 html/SelfService/Elements/MyRequests:30 html/Ticket/Create.html:48 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/EditPeople:44 html/Ticket/Elements/ShowPeople:27 html/Ticket/Update.html:63 lib/RT/ACE_Overlay.pm:86 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "Inhaber"
+
+#: lib/RT/Ticket_Overlay.pm:3004
+#. ($OldOwnerObj->Name,  $NewOwnerObj->Name)
+msgid "Owner changed from %1 to %2"
+msgstr "Inhaberwechsel von %1 zu %2"
+
+#: lib/RT/Transaction_Overlay.pm:584
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr "Inhaber mit Gewalt von %1 in %2 geändert"
+
+#: html/Search/Elements/PickRestriction:31
+msgid "Owner is"
+msgstr "Inhaber ist"
+
+#: html/Admin/Users/Modify.html:174 html/User/Prefs.html:56
+msgid "Pager"
+msgstr "Pager"
+
+#: html/Admin/Elements/ModifyUser:74
+msgid "PagerPhone"
+msgstr "PagerTelefon"
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/EditLinks:127 html/Ticket/Elements/EditLinks:58 html/Ticket/Elements/ShowLinks:43
+msgid "Parents"
+msgstr "Eltern"
+
+#: html/Elements/Login:43 html/User/Prefs.html:61
+msgid "Password"
+msgstr "Passwort"
+
+#: html/NoAuth/Reminder.html:25
+msgid "Password Reminder"
+msgstr "Passworterinnerung"
+
+#: lib/RT/User_Overlay.pm:168 lib/RT/User_Overlay.pm:860
+msgid "Password too short"
+msgstr "Passwort ist zu kurz"
+
+#: html/Admin/Users/Modify.html:291 html/User/Prefs.html:172
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "Passwort: %1"
+
+#: html/Ticket/Elements/ShowSummary:43 html/Ticket/Elements/Tabs:96 html/Ticket/ModifyAll.html:51
+msgid "People"
+msgstr "Personen"
+
+#: etc/initialdata:126
+msgid "Perform a user-defined action"
+msgstr "Führe eine benutzerdefinierte Aktion aus"
+
+#: lib/RT/ACE_Overlay.pm:231 lib/RT/ACE_Overlay.pm:237 lib/RT/ACE_Overlay.pm:563 lib/RT/ACE_Overlay.pm:573 lib/RT/ACE_Overlay.pm:583 lib/RT/ACE_Overlay.pm:648 lib/RT/CurrentUser.pm:83 lib/RT/CurrentUser.pm:92 lib/RT/CustomField_Overlay.pm:445 lib/RT/CustomField_Overlay.pm:451 lib/RT/Group_Overlay.pm:1095 lib/RT/Group_Overlay.pm:1099 lib/RT/Group_Overlay.pm:1108 lib/RT/Group_Overlay.pm:1159 lib/RT/Group_Overlay.pm:1163 lib/RT/Group_Overlay.pm:1169 lib/RT/Group_Overlay.pm:426 lib/RT/Group_Overlay.pm:518 lib/RT/Group_Overlay.pm:596 lib/RT/Group_Overlay.pm:604 lib/RT/Group_Overlay.pm:701 lib/RT/Group_Overlay.pm:705 lib/RT/Group_Overlay.pm:711 lib/RT/Group_Overlay.pm:904 lib/RT/Group_Overlay.pm:908 lib/RT/Group_Overlay.pm:921 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:126 lib/RT/Scrip_Overlay.pm:137 lib/RT/Scrip_Overlay.pm:197 lib/RT/Scrip_Overlay.pm:430 lib/RT/Template_Overlay.pm:284 lib/RT/Template_Overlay.pm:88 lib/RT/Template_Overlay.pm:94 lib/RT/Ticket_Overlay.pm:1341 lib/RT/Ticket_Overlay.pm:1351 lib/RT/Ticket_Overlay.pm:1365 lib/RT/Ticket_Overlay.pm:1518 lib/RT/Ticket_Overlay.pm:1527 lib/RT/Ticket_Overlay.pm:1540 lib/RT/Ticket_Overlay.pm:1875 lib/RT/Ticket_Overlay.pm:2013 lib/RT/Ticket_Overlay.pm:2177 lib/RT/Ticket_Overlay.pm:2244 lib/RT/Ticket_Overlay.pm:2596 lib/RT/Ticket_Overlay.pm:2668 lib/RT/Ticket_Overlay.pm:2762 lib/RT/Ticket_Overlay.pm:2777 lib/RT/Ticket_Overlay.pm:2910 lib/RT/Ticket_Overlay.pm:3139 lib/RT/Ticket_Overlay.pm:3337 lib/RT/Ticket_Overlay.pm:3499 lib/RT/Ticket_Overlay.pm:3551 lib/RT/Ticket_Overlay.pm:3716 lib/RT/Transaction_Overlay.pm:468 lib/RT/Transaction_Overlay.pm:475 lib/RT/Transaction_Overlay.pm:504 lib/RT/Transaction_Overlay.pm:511 lib/RT/User_Overlay.pm:1334 lib/RT/User_Overlay.pm:562 lib/RT/User_Overlay.pm:597 lib/RT/User_Overlay.pm:853 lib/RT/User_Overlay.pm:941
+msgid "Permission Denied"
+msgstr "Zugriff verweigert"
+
+#: html/User/Elements/Tabs:35
+msgid "Personal Groups"
+msgstr "Persönliche Gruppen"
+
+#: html/User/Groups/index.html:30 html/User/Groups/index.html:40
+msgid "Personal groups"
+msgstr "Persönliche Gruppen"
+
+#: html/User/Elements/DelegateRights:37
+msgid "Personal groups:"
+msgstr "Persönliche Gruppen:"
+
+#: html/Admin/Users/Modify.html:156 html/User/Prefs.html:49
+msgid "Phone numbers"
+msgstr "Telefonnummern"
+
+#: html/Admin/Users/Rights.html:25
+msgid "Placeholder"
+msgstr "Platzhalter"
+
+#: html/Elements/Header:52 html/Elements/Tabs:55 html/SelfService/Prefs.html:25 html/User/Prefs.html:25 html/User/Prefs.html:28
+msgid "Preferences"
+msgstr "Voreinstellungen"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr ""
+
+#: lib/RT/Action/Generic.pm:160
+msgid "Prepare Stubbed"
+msgstr "Vorbereitung abgehakt"
+
+#: html/Ticket/Elements/Tabs:61
+msgid "Prev"
+msgstr "Vorherige"
+
+#: html/Search/Listing.html:44
+msgid "Previous page"
+msgstr "Vorherige Seite"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:133 lib/RT/ACE_Overlay.pm:208 lib/RT/ACE_Overlay.pm:552
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr "Hauptverantwortlichen %1 nicht gefunden."
+
+#: html/Search/Elements/PickRestriction:54 html/SelfService/Display.html:76 html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:54 html/Ticket/Elements/ShowBasics:39 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "Priorität"
+
+#: html/Admin/Elements/ModifyQueue:51 html/Admin/Queues/Modify.html:65
+msgid "Priority starts at"
+msgstr "Priorität beginnt bei"
+
+#: etc/initialdata:25
+msgid "Privileged"
+msgstr "Privilegiert"
+
+#: html/Admin/Users/Modify.html:271 html/User/Prefs.html:163
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr "Privilegierungsstatus: %1"
+
+#: html/Admin/Users/index.html:62
+msgid "Privileged users"
+msgstr "Privilegierte Benutzer"
+
+#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59
+msgid "Pseudogroup for internal use"
+msgstr "Pseudogruppe für internen Gebrauch"
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Elements/Quicksearch:29 html/Search/Elements/PickRestriction:46 html/SelfService/Create.html:35 html/SelfService/Display.html:68 html/Ticket/Create.html:38 html/Ticket/Elements/EditBasics:64 html/Ticket/Elements/ShowBasics:43 html/User/Elements/DelegateRights:80 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "Stapel"
+
+#: html/Admin/Queues/CustomField.html:42 html/Admin/Queues/Scrip.html:50 html/Admin/Queues/Scrips.html:46 html/Admin/Queues/Templates.html:43
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr "Stapel %2 nicht gefunden"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:31 html/Admin/Queues/Modify.html:43
+msgid "Queue Name"
+msgstr "Name des Stapels"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:263
+msgid "Queue already exists"
+msgstr "Stapel existiert bereits"
+
+#: lib/RT/Queue_Overlay.pm:272 lib/RT/Queue_Overlay.pm:278
+msgid "Queue could not be created"
+msgstr "Stapel konne nicht angelegt werden"
+
+#: html/Ticket/Create.html:209
+msgid "Queue could not be loaded."
+msgstr "Stapel konnte nicht geladen werden"
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:282
+msgid "Queue created"
+msgstr "Stapel angelegt"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue is not specified."
+msgstr ""
+
+#: html/SelfService/Display.html:129
+msgid "Queue not found"
+msgstr "Stapel nicht gefunden"
+
+#: html/Admin/Elements/Tabs:38 html/Admin/index.html:35
+msgid "Queues"
+msgstr "Stapel"
+
+#: html/Elements/Login:34
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr "RT %1"
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr "RT %1 für %2"
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr "RT %1 von <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr ""
+
+#: html/Admin/index.html:25 html/Admin/index.html:26
+msgid "RT Administration"
+msgstr "RT Administration"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr ""
+
+#: html/Elements/Error:41 html/SelfService/Error.html:41
+msgid "RT Error"
+msgstr "RT Fehler"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr ""
+
+#: html/SelfService/Closed.html:25
+msgid "RT Self Service / Closed Tickets"
+msgstr "RT Selbstbedienung / Geschlossene Anfragen"
+
+#: html/index.html:25 html/index.html:28
+msgid "RT at a glance"
+msgstr "RT auf einen Blick"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr ""
+
+#: html/Elements/PageLayout:26
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr "RT für %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr "RT hat Deine Befehle verarbeitet"
+
+#: html/Elements/Login:83
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  Vertrieben unter der <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr ""
+
+#: html/Admin/Users/Modify.html:58 html/Admin/Users/Prefs.html:52 html/User/Prefs.html:44
+msgid "Real Name"
+msgstr "Realer Name"
+
+#: html/Admin/Elements/ModifyUser:48
+msgid "RealName"
+msgstr "RealerName"
+
+#: html/Ticket/Create.html:185 html/Ticket/Elements/EditLinks:139 html/Ticket/Elements/EditLinks:94 html/Ticket/Elements/ShowLinks:63
+msgid "Referred to by"
+msgstr "Bezogen von"
+
+#: html/Elements/SelectLinkType:28 html/Ticket/Create.html:184 html/Ticket/Elements/EditLinks:135 html/Ticket/Elements/EditLinks:80 html/Ticket/Elements/ShowLinks:55
+msgid "Refers to"
+msgstr "Bezieht sich auf"
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:27
+msgid "Refine search"
+msgstr "Suche Verfeinen"
+
+#: html/Elements/Refresh:36
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "Seite alle %1 Minuten aktualisieren."
+
+#: html/Ticket/Create.html:174 html/Ticket/Elements/ShowSummary:60 html/Ticket/ModifyAll.html:57
+msgid "Relationships"
+msgstr "Beziehungen"
+
+#: html/Search/Bulk.html:93
+msgid "Remove AdminCc"
+msgstr "Entferne AdminCC"
+
+#: html/Search/Bulk.html:91
+msgid "Remove Cc"
+msgstr "Entferne CC"
+
+#: html/Search/Bulk.html:89
+msgid "Remove Requestor"
+msgstr "Entferne Klient"
+
+#: html/Ticket/Elements/ShowTransaction:173 html/Ticket/Elements/Tabs:122
+msgid "Reply"
+msgstr "Antworten"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Reply to tickets"
+msgstr "Antworte auf Anfragen"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "ReplyToTicket"
+msgstr ""
+
+#: etc/initialdata:44 html/Ticket/Update.html:40 lib/RT/ACE_Overlay.pm:87
+msgid "Requestor"
+msgstr "Klient"
+
+#: html/Search/Elements/PickRestriction:38
+msgid "Requestor email address"
+msgstr "email-Adresse des Klienten"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr ""
+
+#: html/SelfService/Create.html:43 html/SelfService/Display.html:42 html/Ticket/Create.html:56 html/Ticket/Elements/EditPeople:48 html/Ticket/Elements/ShowPeople:31
+msgid "Requestors"
+msgstr "Klienten"
+
+#: html/Admin/Elements/ModifyQueue:61 html/Admin/Queues/Modify.html:75
+msgid "Requests should be due in"
+msgstr "Anfragen sollten erlegt werden in"
+
+#: html/Elements/Submit:62
+msgid "Reset"
+msgstr "Zurücksetzen"
+
+#: html/Admin/Users/Modify.html:159 html/User/Prefs.html:50
+msgid "Residence"
+msgstr "Zuhause"
+
+#: html/Ticket/Elements/Tabs:132
+msgid "Resolve"
+msgstr "Erledigen"
+
+#: html/Ticket/Update.html:133
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr "Erledige Anfrage Nr. %1 (%2)"
+
+#: etc/initialdata:302 html/Elements/SelectDateType:28 lib/RT/Ticket_Overlay.pm:1170
+msgid "Resolved"
+msgstr "Erledigt"
+
+#: html/Search/Bulk.html:123 html/Ticket/ModifyAll.html:73 html/Ticket/Update.html:73
+msgid "Response to requestors"
+msgstr "Antwort an alle Klienten"
+
+#: html/Elements/ListActions:26
+msgid "Results"
+msgstr "Ergebnisse"
+
+#: html/Search/Elements/PickRestriction:105
+msgid "Results per page"
+msgstr "Ergebnisse pro Seite"
+
+#: html/Admin/Elements/ModifyUser:33 html/Admin/Users/Modify.html:100 html/User/Prefs.html:72
+msgid "Retype Password"
+msgstr "Passwort wiederholen"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:613
+msgid "Right Delegated"
+msgstr "Recht delegiert"
+
+#: lib/RT/ACE_Overlay.pm:303
+msgid "Right Granted"
+msgstr "Recht erteilt"
+
+#: lib/RT/ACE_Overlay.pm:161
+msgid "Right Loaded"
+msgstr "Recht geladen"
+
+#: lib/RT/ACE_Overlay.pm:678 lib/RT/ACE_Overlay.pm:693
+msgid "Right could not be revoked"
+msgstr "Recht konnte nicht zurückgezogen werden"
+
+#: html/User/Delegation.html:64
+msgid "Right not found"
+msgstr "Recht nicht gefunden"
+
+#: lib/RT/ACE_Overlay.pm:543 lib/RT/ACE_Overlay.pm:638
+msgid "Right not loaded."
+msgstr "Recht nicht gefunden."
+
+#: lib/RT/ACE_Overlay.pm:689
+msgid "Right revoked"
+msgstr "Recht zurückgezogen"
+
+#: html/Admin/Elements/UserTabs:41
+msgid "Rights"
+msgstr "Rechte"
+
+#: lib/RT/Interface/Web.pm:758
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr "Rechte konnten für %1 nicht gewährt werden"
+
+#: lib/RT/Interface/Web.pm:791
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr "Rechte konnten nicht für %1 entzogen werden"
+
+#: html/Admin/Global/GroupRights.html:51 html/Admin/Queues/GroupRights.html:52
+msgid "Roles"
+msgstr "Rollen"
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr ""
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "Sa"
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "Save Changes"
+msgstr "Änderungen Sichern"
+
+#: html/Ticket/ModifyLinks.html:39
+msgid "Save changes"
+msgstr "Änderungen Sichern"
+
+#: html/Admin/Global/Scrip.html:49
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:176
+msgid "Scrip Created"
+msgstr "Scrip angelegt"
+
+#: html/Admin/Elements/EditScrips:84
+msgid "Scrip deleted"
+msgstr "Scrip gelöscht"
+
+#: html/Admin/Elements/QueueTabs:46 html/Admin/Elements/SystemTabs:33 html/Admin/Global/index.html:41
+msgid "Scrips"
+msgstr "Scrips"
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr "Scrips für %1\\n"
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr "Auf alle Stapel angewande Scrips"
+
+#: html/Elements/SimpleSearch:27 html/Search/Elements/PickRestriction:126 html/Ticket/Elements/Tabs:159
+msgid "Search"
+msgstr "Suchen"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:39
+msgid "Search for approvals"
+msgstr "Suche nach Freigaben"
+
+#: bin/rt-crontool:188
+msgid "Security:"
+msgstr "Sicherheit:"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "SeeQueue"
+msgstr ""
+
+#: html/Admin/Groups/index.html:40
+msgid "Select a group"
+msgstr "Wähle eine Gruppe aus"
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr ""
+
+#: html/Admin/Users/index.html:25 html/Admin/Users/index.html:28
+msgid "Select a user"
+msgstr "Wähle einen Benutzer aus"
+
+#: html/Admin/Global/CustomField.html:38 html/Admin/Global/CustomFields.html:36
+msgid "Select custom field"
+msgstr "Wähle ein benutzerdef. Feld"
+
+#: html/Admin/Elements/GroupTabs:52 html/User/Elements/GroupTabs:50
+msgid "Select group"
+msgstr "Wähle eine Gruppe"
+
+#: lib/RT/CustomField_Overlay.pm:355
+msgid "Select multiple values"
+msgstr "Wähle mehrere Werte"
+
+#: lib/RT/CustomField_Overlay.pm:352
+msgid "Select one value"
+msgstr "Wähle einen Wert"
+
+#: html/Admin/Elements/QueueTabs:67
+msgid "Select queue"
+msgstr "Wähle einen Stapel"
+
+#: html/Admin/Global/Scrip.html:37 html/Admin/Global/Scrips.html:36 html/Admin/Queues/Scrip.html:40 html/Admin/Queues/Scrips.html:50
+msgid "Select scrip"
+msgstr "Wähle ein Scrip"
+
+#: html/Admin/Global/Template.html:57 html/Admin/Global/Templates.html:36 html/Admin/Queues/Template.html:55
+msgid "Select template"
+msgstr "Wähle ein Template"
+
+#: html/Admin/Elements/UserTabs:49
+msgid "Select user"
+msgstr "Wähle einen Benutzer"
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "SelectMultiple"
+msgstr "Mehrfachauswahlfeld"
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectSingle"
+msgstr "Einzelauswahlfeld"
+
+#: html/SelfService/index.html:25
+msgid "Self Service"
+msgstr "Selbstbedienung"
+
+#: etc/initialdata:114
+msgid "Send mail to all watchers"
+msgstr "Schicke eine Mail an alle Beobachter"
+
+#: etc/initialdata:110
+msgid "Send mail to all watchers as a \"comment\""
+msgstr "Schicke eine Mail an alle Beobachter als \"Kommentar\""
+
+#: etc/initialdata:105
+msgid "Send mail to requestors and Ccs"
+msgstr "Schicke eine Mail an die Klienten und CCs"
+
+#: etc/initialdata:100
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr "Schicke eine Mail an die Klienten und CCs als Kommentar"
+
+#: etc/initialdata:79
+msgid "Sends a message to the requestors"
+msgstr "Schicke eine Mail an die Klienten"
+
+#: etc/initialdata:118 etc/initialdata:122
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr "Schicke eine Mail an die direkt angegebenen CCs und BCCs"
+
+#: etc/initialdata:95
+msgid "Sends mail to the administrative Ccs"
+msgstr "Schicke eine Mail an die administrativen CCs"
+
+#: etc/initialdata:91
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr "Schicke eine Mail an die administrativen CCs als Kommentar"
+
+#: etc/initialdata:83 etc/initialdata:87
+msgid "Sends mail to the owner"
+msgstr "Schicke eine Mail an den Inhaber"
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "Sep"
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show approved requests"
+msgstr "Zeige freigegebene Anfragen"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show basics"
+msgstr "Zeige Grundlagen"
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show denied requests"
+msgstr "Zeige abgelehnte Anfragen"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show details"
+msgstr "Zeige Details"
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show pending requests"
+msgstr "Zeige schwebende Anfragen"
+
+#: html/Approvals/Elements/PendingMyApproval:46
+msgid "Show requests awaiting other approvals"
+msgstr "Zeige auf andere Freigaben wartende Anfragen"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Show ticket private commentary"
+msgstr "Zeige private Kommentare des Anfragen"
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "Show ticket summaries"
+msgstr "Zeige Kurzfassungen der Anfragen"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ShowACL"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowScrips"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ShowTemplate"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "ShowTicket"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "ShowTicketComments"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr "Als Klient einer Anfrage oder Anfrage- bzw. Stapel-CC eintragen"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr "Als Anfrage- oder Stapel-AdminCC eintragen"
+
+#: html/Admin/Elements/ModifyUser:39 html/Admin/Users/Modify.html:191 html/Admin/Users/Prefs.html:32 html/SelfService/Prefs.html:37 html/User/Prefs.html:112
+msgid "Signature"
+msgstr "E-Mail-Signatur"
+
+#: html/SelfService/Elements/Header:52
+#. ($session{'CurrentUser'}->Name)
+msgid "Signed in as %1"
+msgstr "Angemeldet als %1"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Single"
+msgstr "Einzel"
+
+#: html/Elements/Header:51
+msgid "Skip Menu"
+msgstr "Überspringe Menü"
+
+#: html/Admin/Elements/EditCustomFieldValues:31
+msgid "Sort key"
+msgstr "Sortierschlüssel"
+
+#: html/Search/Elements/PickRestriction:109
+msgid "Sort results by"
+msgstr "Sortiere Ergebnisse nach"
+
+#: html/Admin/Elements/AddCustomFieldValue:25
+msgid "SortOrder"
+msgstr "Sortierreihenfolge"
+
+#: NOT FOUND IN SOURCE
+msgid "Stalled"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr ""
+
+#: html/Elements/SelectDateType:27 html/Ticket/Elements/EditDates:32 html/Ticket/Elements/ShowDates:35
+msgid "Started"
+msgstr "Begonnen"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr ""
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:27 html/Ticket/Elements/ShowDates:31
+msgid "Starts"
+msgstr "Beginnt"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:82 html/Admin/Users/Modify.html:138 html/User/Prefs.html:94
+msgid "State"
+msgstr "Staat"
+
+#: html/Elements/MyRequests:31 html/Elements/MyTickets:31 html/Search/Elements/PickRestriction:74 html/SelfService/Display.html:59 html/SelfService/Elements/MyRequests:29 html/SelfService/Update.html:31 html/Ticket/Create.html:42 html/Ticket/Elements/EditBasics:38 html/Ticket/Elements/ShowBasics:31 html/Ticket/Update.html:60 lib/RT/Ticket_Overlay.pm:1164 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "Status"
+
+#: etc/initialdata:288
+msgid "Status Change"
+msgstr "Ändere Status"
+
+#: lib/RT/Transaction_Overlay.pm:530
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr "Status von %1 auf %2 geändert"
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:147
+msgid "Steal"
+msgstr "Stehlen"
+
+#: lib/RT/Transaction_Overlay.pm:589
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "Gestohlen von %1 "
+
+#: html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Search/Bulk.html:126 html/Search/Elements/PickRestriction:43 html/SelfService/Create.html:59 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:35 html/Ticket/Create.html:84 html/Ticket/Elements/EditBasics:28 html/Ticket/ModifyAll.html:79 html/Ticket/Update.html:77 lib/RT/Ticket_Overlay.pm:1160 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "Betreff"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:611
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr "Betreff wurde auf %1 geändert"
+
+#: html/Elements/Submit:59
+msgid "Submit"
+msgstr "Übermitteln"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:749
+msgid "Succeeded"
+msgstr "Geglückt"
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "So"
+
+#: lib/RT/System.pm:54
+msgid "SuperUser"
+msgstr ""
+
+#: html/User/Elements/DelegateRights:77
+msgid "System"
+msgstr "System"
+
+#: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:567 lib/RT/Interface/Web.pm:757 lib/RT/Interface/Web.pm:790
+msgid "System Error"
+msgstr "Systemfehler"
+
+#: lib/RT/ACE_Overlay.pm:616
+msgid "System error. Right not delegated."
+msgstr "Systemfehler. Recht nicht delegiert."
+
+#: lib/RT/ACE_Overlay.pm:146 lib/RT/ACE_Overlay.pm:223 lib/RT/ACE_Overlay.pm:306 lib/RT/ACE_Overlay.pm:898
+msgid "System error. Right not granted."
+msgstr "Systemfehler. Recht nicht gewährt."
+
+#: html/Admin/Global/GroupRights.html:35 html/Admin/Groups/GroupRights.html:37 html/Admin/Queues/GroupRights.html:36
+msgid "System groups"
+msgstr "Systemgruppen"
+
+#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53
+msgid "SystemRolegroup for internal use"
+msgstr "SystemRolegroup für internen Gebrauch"
+
+#: lib/RT/CurrentUser.pm:320
+msgid "TEST_STRING"
+msgstr "TEST_STRING"
+
+#: html/Ticket/Elements/Tabs:143
+msgid "Take"
+msgstr "Übernehmen"
+
+#: lib/RT/Transaction_Overlay.pm:575
+msgid "Taken"
+msgstr "Übernommen"
+
+#: html/Admin/Elements/EditScrip:81
+msgid "Template"
+msgstr "Vorlage"
+
+#: html/Admin/Global/Template.html:91 html/Admin/Queues/Template.html:90
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr "Vorlage #%1"
+
+#: html/Admin/Elements/EditTemplates:89
+msgid "Template deleted"
+msgstr "Vorlage gelöscht"
+
+#: lib/RT/Scrip_Overlay.pm:153
+msgid "Template not found"
+msgstr "Vorlage nicht gefunden"
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr ""
+
+#: lib/RT/Template_Overlay.pm:347
+msgid "Template parsed"
+msgstr "Vorlagen eingelesen"
+
+#: html/Admin/Elements/QueueTabs:49 html/Admin/Elements/SystemTabs:36 html/Admin/Global/index.html:45
+msgid "Templates"
+msgstr "Vorlagen"
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr "Vorlagen für %1\\n"
+
+#: lib/RT/Interface/Web.pm:858
+msgid "That is already the current value"
+msgstr "Das ist bereits der aktuelle Wert"
+
+#: lib/RT/CustomField_Overlay.pm:178
+msgid "That is not a value for this custom field"
+msgstr "Dies ist kein gültiger Wert für dieses benutzerdefinierte Feld"
+
+#: lib/RT/Ticket_Overlay.pm:1886
+msgid "That is the same value"
+msgstr "Das ist der gleiche Wert"
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr "Dieser Hauptverantwortliche ist bereits ein %1 dieses Stapels"
+
+#: lib/RT/Ticket_Overlay.pm:1434
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr "Dieser Hauptverantwortliche ist bereits ein %1 dieser Anfrage"
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr "Dieser Hauptverantwortliche ist nicht ein %1 dieses Stapels"
+
+#: lib/RT/Ticket_Overlay.pm:1551
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr "Dieser Hauptverantwortliche ist nicht ein %1 dieser Anfrage"
+
+#: lib/RT/Ticket_Overlay.pm:1882
+msgid "That queue does not exist"
+msgstr "Dieser Stapel existiert nicht"
+
+#: lib/RT/Ticket_Overlay.pm:3143
+msgid "That ticket has unresolved dependencies"
+msgstr "Diese Anfrage hat ungelöste Abhängigkeiten"
+
+#: lib/RT/ACE_Overlay.pm:288 lib/RT/ACE_Overlay.pm:597
+msgid "That user already has that right"
+msgstr "Dieser Benutzer hat dieses Recht bereits" 
+
+#: lib/RT/Ticket_Overlay.pm:2952
+msgid "That user already owns that ticket"
+msgstr "Diesem Benutzer gehört diese Anfrage bereits"
+
+#: lib/RT/Ticket_Overlay.pm:2918
+msgid "That user does not exist"
+msgstr "Dieser Benutzer existiert nicht"
+
+#: lib/RT/User_Overlay.pm:315
+msgid "That user is already privileged"
+msgstr "Dieser Benutzer ist bereits privilegiert"
+
+#: lib/RT/User_Overlay.pm:332
+msgid "That user is already unprivileged"
+msgstr "Dieser Benutzer ist bereits ungeprivilegiert"
+
+#: lib/RT/User_Overlay.pm:327
+msgid "That user is now privileged"
+msgstr "Dieser Benutzer ist jetzt privilegiert"
+
+#: lib/RT/User_Overlay.pm:344
+msgid "That user is now unprivileged"
+msgstr "Dieser Benutzer ist jetzt unprivelegiert"
+
+#: lib/RT/Ticket_Overlay.pm:2944
+msgid "That user may not own tickets in that queue"
+msgstr "Diesem Benutzer dürfen keine Anfragen aus diesen Stapel gehören"
+
+#: lib/RT/Link_Overlay.pm:206
+msgid "That's not a numerical id"
+msgstr "Dies ist keine numerische Id"
+
+#: html/Ticket/Create.html:150 html/Ticket/Elements/ShowSummary:28
+msgid "The Basics"
+msgstr "Grundlagen"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The CC of a ticket"
+msgstr "Der CC einer Anfrage"
+
+#: lib/RT/ACE_Overlay.pm:89
+msgid "The administrative CC of a ticket"
+msgstr "Der administrative CC einer Anfrage"
+
+#: lib/RT/Ticket_Overlay.pm:2213
+msgid "The comment has been recorded"
+msgstr "Der Kommentar wurde aufgezeichnet"
+
+#: bin/rt-crontool:198
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr "Das folgende Kommando wird alle aktiven Anfragen des Stapels 'general' finden und ihre Priorität auf 99 setzen, wenn sie innerhalb der letzten 4 Stunden nicht angefasst wurden:"
+
+#: bin/rt-commit-handler:756 bin/rt-commit-handler:766
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr "Die folgenden Kommandos wurden nicht verarbeitet:\\n\\n"
+
+#: lib/RT/Interface/Web.pm:861
+msgid "The new value has been set."
+msgstr "Der neue Wert wurde gesetzt."
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The owner of a ticket"
+msgstr "Der Inhaber einer Anfrage"
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The requestor of a ticket"
+msgstr "Der Klient einer Anfrage"
+
+#: html/Admin/Elements/EditUserComments:26
+msgid "These comments aren't generally visible to the user"
+msgstr "Diese Kommentare sind generell nicht für den Benutzer sichtbar"
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr ""
+
+#: bin/rt-crontool:189
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr "Dieses Werkzeug erlaubt es Benutzern beliebige Perl-Module von RT aus aufzurufen."
+
+#: lib/RT/Transaction_Overlay.pm:253
+msgid "This transaction appears to have no content"
+msgstr "Diese Transaktion scheint keinen Inhalt zu haben"
+
+#: html/Ticket/Elements/ShowRequestor:47
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr "Die %1 höchstpriorisiertesten Anfragen dieses Benutzers"
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr ""
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "Do"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr ""
+
+#: html/Ticket/ModifyAll.html:25 html/Ticket/ModifyAll.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "Anfrage Nr. %1 Alles aktualisieren: %2"
+
+#: html/Approvals/Elements/ShowDependency:46
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr "Anfrage Nr. %1: %2"
+
+#: lib/RT/Ticket_Overlay.pm:608
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr "Anfrage %1 wurde in Anfrage '%2' angelegt"
+
+#: bin/rt-commit-handler:760
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr "Anfrage %1 geladen\\n"
+
+#: html/Search/Bulk.html:181
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr "Anfrage %1: %2"
+
+#: html/Ticket/History.html:25 html/Ticket/History.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr "Verlauf von Anfrage Nr. %1 %2"
+
+#: html/SelfService/Display.html:34
+msgid "Ticket Id"
+msgstr "Anfrage Nr." 
+
+#: etc/initialdata:303
+msgid "Ticket Resolved"
+msgstr "Anfrage erledigt"
+
+#: html/Search/Elements/PickRestriction:63
+msgid "Ticket attachment"
+msgstr "Anhang der Anfrage"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr "Inhalt der Anfrage"
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr "Art des Inhalts der Anfrage"
+
+#: lib/RT/Ticket_Overlay.pm:495 lib/RT/Ticket_Overlay.pm:597
+msgid "Ticket could not be created due to an internal error"
+msgstr "Anfrage konnte aufgrund eines internen Fehlers nicht angelegt werden"
+
+#: lib/RT/Transaction_Overlay.pm:522
+msgid "Ticket created"
+msgstr "Anfrage angelegt"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:527
+msgid "Ticket deleted"
+msgstr "Anfrage gelöscht"
+
+#: html/REST/1.0/modify:29 html/REST/1.0/update:34
+msgid "Ticket id not found"
+msgstr "Anfragenummer nicht gefunden"
+
+#: html/REST/1.0/modify:36 html/REST/1.0/update:41
+msgid "Ticket not found"
+msgstr "Anfrage nicht gefunden"
+
+#: etc/initialdata:289
+msgid "Ticket status changed"
+msgstr "Status der Anfrage geändert"
+
+#: html/Ticket/Update.html:39
+msgid "Ticket watchers"
+msgstr "Beobachter der Anfrage"
+
+#: html/Elements/Tabs:49
+msgid "Tickets"
+msgstr "Anfragen"
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr "Anfragen %1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr "Anfragen %2 von %2"
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Tickets from %1"
+msgstr "Anfragen von %1"
+
+#: html/Approvals/Elements/ShowDependency:27
+msgid "Tickets which depend on this approval:"
+msgstr "Anfragen, die von dieser Freigabe abhängen:"
+
+#: html/Ticket/Create.html:157 html/Ticket/Elements/EditBasics:48
+msgid "Time Left"
+msgstr "Übrige Zeit"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:43
+msgid "Time Worked"
+msgstr "Arbeitszeit"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "Übrige Zeit"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "Benötigte Zeit"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "Arbeitszeit"
+
+#: lib/RT/Ticket_Overlay.pm:1165
+msgid "TimeWorked"
+msgstr "Gearbeitete Zeit"
+
+#: bin/rt-commit-handler:402
+msgid "To generate a diff of this commit:"
+msgstr "Um ein 'diff' dieser Übergabe zu erstellen:"
+
+#: bin/rt-commit-handler:391
+msgid "To generate a diff of this commit:\\n"
+msgstr "Um ein 'diff' dieser Übergabe zu erstellen:\\n"
+
+#: lib/RT/Ticket_Overlay.pm:1168
+msgid "Told"
+msgstr "Eingegangen"
+
+#: etc/initialdata:237
+msgid "Transaction"
+msgstr "Transaktion"
+
+#: lib/RT/Transaction_Overlay.pm:642
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr "Transaktion %1 durchgeprügelt"
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr "Transaktion erstellt"
+
+#: lib/RT/Transaction_Overlay.pm:89
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr "Transaction->Create konnte nicht ausgeführt werden da keine Ticketnummer angegeben wurde"
+
+#: lib/RT/Transaction_Overlay.pm:701
+msgid "Transactions are immutable"
+msgstr "Transaktionen sind unveränderbar"
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr ""
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "Di"
+
+#: html/Admin/Elements/EditCustomField:34 html/Ticket/Elements/AddWatchers:33 html/Ticket/Elements/AddWatchers:44 html/Ticket/Elements/AddWatchers:54 lib/RT/Ticket_Overlay.pm:1166 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "Typ"
+
+#: lib/RT/ScripCondition_Overlay.pm:104
+msgid "Unimplemented"
+msgstr "Nicht implementiert"
+
+#: html/Admin/Users/Modify.html:68
+msgid "Unix login"
+msgstr "Unix Login"
+
+#: html/Admin/Elements/ModifyUser:62
+msgid "UnixUsername"
+msgstr "UnixBenutzername"
+
+#: lib/RT/Attachment_Overlay.pm:265
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr "Unbekannte Inhalts-Kodierung %1"
+
+#: html/Elements/SelectResultsPerPage:37
+msgid "Unlimited"
+msgstr "unbegrenzt"
+
+#: etc/initialdata:32
+msgid "Unprivileged"
+msgstr "Unprivilegiert"
+
+#: lib/RT/Transaction_Overlay.pm:571
+msgid "Untaken"
+msgstr "Zurückgegeben"
+
+#: html/Elements/MyTickets:64 html/Search/Bulk.html:33
+msgid "Update"
+msgstr "Aktualisieren"
+
+#: html/Admin/Users/Prefs.html:62
+msgid "Update ID"
+msgstr "Aktualisierungs-ID"
+
+#: html/Search/Bulk.html:120 html/Ticket/ModifyAll.html:66 html/Ticket/Update.html:67
+msgid "Update Type"
+msgstr "Aktualisierungtyp"
+
+#: html/Search/Listing.html:61
+msgid "Update all these tickets at once"
+msgstr "Aktualisiere alle diese Anfragen auf einmal"
+
+#: html/Admin/Users/Prefs.html:49
+msgid "Update email"
+msgstr "Aktualisiere E-Mail"
+
+#: html/Admin/Users/Prefs.html:55
+msgid "Update name"
+msgstr "Aktualisiere Name"
+
+#: lib/RT/Interface/Web.pm:375
+msgid "Update not recorded."
+msgstr "Aktualisierung nicht aufgezeichnet."
+
+#: html/Search/Bulk.html:81
+msgid "Update selected tickets"
+msgstr "Aktualisiere ausgewählte Anfragen"
+
+#: html/Admin/Users/Prefs.html:36
+msgid "Update signature"
+msgstr "Aktualisiere Unterschrift"
+
+#: html/Ticket/ModifyAll.html:63
+msgid "Update ticket"
+msgstr "Aktualisiere Anfrage"
+
+#: html/SelfService/Update.html:25 html/SelfService/Update.html:27
+#. ($Ticket->id)
+msgid "Update ticket # %1"
+msgstr "Aktualisiere Anfrage Nr. %1"
+
+#: html/SelfService/Update.html:50
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr "Aktualisiere Anfrage Nr. %1"
+
+#: html/Ticket/Update.html:135
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr "Aktualisiere Anfrage Nr. %1 (%2)"
+
+#: lib/RT/Interface/Web.pm:373
+msgid "Update type was neither correspondence nor comment."
+msgstr "Aktualisierungstyp war weder Korrespondenz noch Kommentar."
+
+#: html/Elements/SelectDateType:33 html/Ticket/Elements/ShowDates:51 lib/RT/Ticket_Overlay.pm:1169
+msgid "Updated"
+msgstr "Aktualisiert"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr ""
+
+#: etc/initialdata:125 etc/initialdata:191
+msgid "User Defined"
+msgstr "Benutzerdefiniert"
+
+#: html/Admin/Users/Prefs.html:59
+msgid "User ID"
+msgstr "Benutzer-ID"
+
+#: html/Elements/SelectUsers:26
+msgid "User Id"
+msgstr "Benutzername"
+
+#: html/Admin/Elements/GroupTabs:47 html/Admin/Elements/QueueTabs:60 html/Admin/Elements/SystemTabs:47 html/Admin/Global/index.html:59
+msgid "User Rights"
+msgstr "Benutzerrechte"
+
+#: html/Admin/Users/Modify.html:226
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr "Benutzer konnte nicht angelegt werden: %1"
+
+#: lib/RT/User_Overlay.pm:262
+msgid "User created"
+msgstr "Benutzer angelegt"
+
+#: html/Admin/Global/GroupRights.html:67 html/Admin/Groups/GroupRights.html:54 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr "Benutzerdefinierte Gruppe"
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr ""
+
+#: html/Admin/Users/Prefs.html:25 html/Admin/Users/Prefs.html:29
+msgid "User view"
+msgstr "Benutzeransicht"
+
+#: html/Admin/Users/Modify.html:48 html/Elements/Login:42 html/Ticket/Elements/AddWatchers:35
+msgid "Username"
+msgstr "Benutzername"
+
+#: html/Admin/Elements/SelectNewGroupMembers:26 html/Admin/Elements/Tabs:32 html/Admin/Groups/Members.html:55 html/Admin/Queues/People.html:68 html/Admin/index.html:29 html/User/Groups/Members.html:58
+msgid "Users"
+msgstr "Benutzer"
+
+#: html/Admin/Users/index.html:65
+msgid "Users matching search criteria"
+msgstr "Auf diese Kriterien zutreffenede Benutzer"
+
+#: html/Search/Elements/PickRestriction:51
+msgid "ValueOfQueue"
+msgstr "ValueOfQueue"
+
+#: html/Admin/Elements/EditCustomField:40
+msgid "Values"
+msgstr "Werte"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Watch"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "WatchAsAdminCc"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:42
+msgid "Watchers"
+msgstr "Beobachter"
+
+#: html/Admin/Elements/ModifyUser:56
+msgid "WebEncoding"
+msgstr "Webkodierung"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "Mi"
+
+#: etc/upgrade/2.1.71:161
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr "Füge Korrespondenz zum Originalticket, wenn eine Anfrage von allen Freigebenden freigegeben wurde"
+
+#: etc/upgrade/2.1.71:135
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr "Füge Korrespondenz zum Originalticket wenn eine Anfrage  von einem Freigebenden freigegeben wurde"
+
+#: etc/initialdata:138
+msgid "When a ticket is created"
+msgstr "Wenn eine Afrage erstellt wird"
+
+#: etc/upgrade/2.1.71:79
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr "Benachrichtige Inhaber und AdminCCs der auf Freigabe wartende Anfrage wenn ein Freigabeticket erstellt wurde"
+
+#: etc/initialdata:143
+msgid "When anything happens"
+msgstr "Wenn irgendetwas passiert"
+
+#: etc/initialdata:184
+msgid "Whenever a ticket is resolved"
+msgstr "Immer wenn eine Anfrage  erledigt wird"
+
+#: etc/initialdata:170
+msgid "Whenever a ticket's owner changes"
+msgstr "Immer wenn der Eigentümer einer Anfrage wechselt"
+
+#: etc/initialdata:178
+msgid "Whenever a ticket's queue changes"
+msgstr "Immer wenn eine Anfrage den Stapel wechselt"
+
+#: etc/initialdata:162
+msgid "Whenever a ticket's status changes"
+msgstr "Immer wenn sich der Status einer Anfrage ändert"
+
+#: etc/initialdata:192
+msgid "Whenever a user-defined condition occurs"
+msgstr "Immer wenn eine benutzerdefinierte Bedingung auftritt"
+
+#: etc/initialdata:156
+msgid "Whenever comments come in"
+msgstr "Immer wenn ein neuer Kommentar eingeht"
+
+#: etc/initialdata:149
+msgid "Whenever correspondence comes in"
+msgstr "Immer wenn neue Korrespondenz eingeht"
+
+#: html/Admin/Users/Modify.html:164 html/User/Prefs.html:52
+msgid "Work"
+msgstr "Arbeit"
+
+#: html/Admin/Elements/ModifyUser:70
+msgid "WorkPhone"
+msgstr "Arbeitstelefon"
+
+#: html/SelfService/Display.html:86 html/Ticket/Elements/ShowBasics:35 html/Ticket/Update.html:65
+msgid "Worked"
+msgstr "Arbeitszeit"
+
+#: lib/RT/Ticket_Overlay.pm:3056
+msgid "You already own this ticket"
+msgstr "Du besitzt diese Anfrage bereits"
+
+#: html/autohandler:121
+msgid "You are not an authorized user"
+msgstr "Du bist kein authorisierter Benutzer"
+
+#: lib/RT/Ticket_Overlay.pm:2930
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "Du kannst nur Anfragen ohne Inhaber zuweisen"
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "Du hast %1 Anfragen in Stapel %2 gefunden"
+
+#: html/NoAuth/Logout.html:31 html/REST/1.0/logout:25
+msgid "You have been logged out of RT."
+msgstr "Du wurdest von RT abgemeldet."
+
+#: html/SelfService/Display.html:134
+msgid "You have no permission to create tickets in that queue."
+msgstr "Du hast kein Recht, Anfragen in diesen Stapel anzulegen."
+
+#: lib/RT/Ticket_Overlay.pm:1895
+msgid "You may not create requests in that queue."
+msgstr "Du darfst in diesem Stapel keine Anfragen erstellen"
+
+#: html/NoAuth/Logout.html:36
+msgid "You're welcome to login again"
+msgstr "Du kannst dich gerne wieder anmelden"
+
+#: html/SelfService/Elements/MyRequests:25
+#. ($friendly_status)
+msgid "Your %1 requests"
+msgstr "Meine %1 Anfragen"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr ""
+
+#: etc/initialdata:429 etc/upgrade/2.1.71:146
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr "Deine Anfrage wurde von %1 freigegeben. Andere Freigaben können noch ausstehen."
+
+#: etc/initialdata:463 etc/upgrade/2.1.71:180
+msgid "Your request has been approved."
+msgstr "Deine Anfrage wurde freigegeben."
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr ""
+
+#: etc/initialdata:384 etc/upgrade/2.1.71:101
+msgid "Your request was rejected."
+msgstr "Deine Anfrage wurde abgewiesen"
+
+#: html/autohandler:136 html/autohandler:142
+msgid "Your username or password is incorrect"
+msgstr "Dein Benutzername oder Passwort ist falsch"
+
+#: html/Admin/Elements/ModifyUser:84 html/Admin/Users/Modify.html:144 html/User/Prefs.html:96
+msgid "Zip"
+msgstr "PLZ"
+
+#: html/User/Elements/DelegateRights:59
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "wie an %1 gewährt"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:34
+msgid "contains"
+msgstr "enthält"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content"
+msgstr "Inhalt"
+
+#: html/Elements/SelectAttachmentField:27
+msgid "content-type"
+msgstr "content-type"
+
+#: lib/RT/Ticket_Overlay.pm:2282
+msgid "correspondence (probably) not sent"
+msgstr "Korrepsondenz (möglicherweise) nicht verschickt"
+
+#: lib/RT/Ticket_Overlay.pm:2292
+msgid "correspondence sent"
+msgstr "Korrespondenz verschickt"
+
+#: html/Admin/Elements/ModifyQueue:63 html/Admin/Queues/Modify.html:77 lib/RT/Date.pm:319
+msgid "days"
+msgstr "Tage"
+
+#: html/Search/Listing.html:75
+msgid "delete"
+msgstr "löschen"
+
+#: lib/RT/Queue_Overlay.pm:63
+msgid "deleted"
+msgstr "gelöscht"
+
+#: html/Search/Elements/PickRestriction:68
+msgid "does not match"
+msgstr "entspricht nicht"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:35
+msgid "doesn't contain"
+msgstr "enthält nicht"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "equal to"
+msgstr "entspricht"
+
+#: html/Elements/SelectAttachmentField:28
+msgid "filename"
+msgstr "Dateiname"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "greater than"
+msgstr "größer als"
+
+#: lib/RT/Group_Overlay.pm:194
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "Gruppe '%1'"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "Stunden"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr ""
+
+#: html/Elements/SelectBoolean:32 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88
+msgid "is"
+msgstr "ist"
+
+#: html/Elements/SelectBoolean:36 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:37 html/Search/Elements/PickRestriction:48 html/Search/Elements/PickRestriction:77 html/Search/Elements/PickRestriction:89
+msgid "isn't"
+msgstr "ist nicht"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "less than"
+msgstr "kleiner als"
+
+#: html/Search/Elements/PickRestriction:67
+msgid "matches"
+msgstr "entspricht"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "Min"
+
+#: html/Ticket/Update.html:66
+msgid "minutes"
+msgstr "Minuten"
+
+#: bin/rt-commit-handler:765
+msgid "modifications\\n\\n"
+msgstr "Änderungen\\n\\n"
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "Monate"
+
+#: lib/RT/Queue_Overlay.pm:58
+msgid "new"
+msgstr "neu"
+
+#: html/Admin/Elements/EditScrips:43
+msgid "no value"
+msgstr "kein Wert"
+
+#: html/Ticket/Elements/EditWatchers:28
+msgid "none"
+msgstr "keine"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "not equal to"
+msgstr "entspricht nicht"
+
+#: lib/RT/Queue_Overlay.pm:59
+msgid "open"
+msgstr "offen"
+
+#: lib/RT/Group_Overlay.pm:199
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr "persönliche Gruppe '%1' für Benutzer '%2'"
+
+#: lib/RT/Group_Overlay.pm:207
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr "Stapel %1 %2"
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "rejected"
+msgstr "abgewiesen"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "resolved"
+msgstr "erledigt"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr "Sek"
+
+#: lib/RT/Queue_Overlay.pm:60
+msgid "stalled"
+msgstr "zurückgestellt"
+
+#: lib/RT/Group_Overlay.pm:202
+#. ($self->Type)
+msgid "system %1"
+msgstr "System %1"
+
+#: lib/RT/Group_Overlay.pm:213
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr "Systemgruppe '%1'"
+
+#: html/Elements/Error:42 html/SelfService/Error.html:42
+msgid "the calling component did not specify why"
+msgstr "die aufrufende Komponente gab nicht an warum"
+
+#: lib/RT/Group_Overlay.pm:210
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr "Ticket #%1 %2"
+
+#: lib/RT/Group_Overlay.pm:216
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr "unbeschriebene Gruppe %1"
+
+#: NOT FOUND IN SOURCE
+msgid "undescripbed group %1"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:191
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr "Benutzer %1"
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr "Wochen"
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr ""
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr "Jahre"
+
diff --git a/rt/lib/RT/I18N/en.po b/rt/lib/RT/I18N/en.po
new file mode 100644 (file)
index 0000000..ffdc5cc
--- /dev/null
@@ -0,0 +1,88 @@
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "Apr"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "Aug"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "Dec"
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "Feb"
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "Fri"
+
+#: html/Elements/Tabs:46
+msgid "Homepage"
+msgstr "Home"
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "Jan"
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "Jul"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "Jun"
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "Mar"
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "May"
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "Mon"
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "Nov"
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "Oct"
+
+#: html/Ticket/Elements/Tabs:136
+msgid "Open it"
+msgstr "Open"
+
+#: html/Admin/Users/Modify.html:159 html/User/Prefs.html:50
+msgid "Residence"
+msgstr "Home"
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "Sat"
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "Sep"
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "Sun"
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "Thu"
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "Tue"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "Wed"
+
diff --git a/rt/lib/RT/I18N/es.po b/rt/lib/RT/I18N/es.po
new file mode 100644 (file)
index 0000000..05006b1
--- /dev/null
@@ -0,0 +1,4749 @@
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: RT 2.1.x\n"
+"POT-Creation-Date: 2002-05-02 11:36+0800\n"
+"PO-Revision-Date: 2003-03-23 12:38\n"
+"Last-Translator: Tomàs Núñez Lirola <tomasnl@dsl.upc.es>\n"
+"Language-Team: rt-devel <rt-devel@lists.fsck.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28
+msgid "#"
+msgstr "#"
+
+#: html/Admin/Queues/Scrip.html:55
+#. ($QueueObj->id)
+msgid "#%1"
+msgstr "#%1"
+
+#: html/Approvals/Elements/ShowDependency:50 html/Ticket/Display.html:26 html/Ticket/Display.html:30
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr "#%1: %2"
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr "%1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr "%1 %2 %3"
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr "%1 %2 %3 %4:%5:%6 %7"
+
+#: lib/RT/Ticket_Overlay.pm:3438 lib/RT/Transaction_Overlay.pm:559 lib/RT/Transaction_Overlay.pm:601
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 added"
+msgstr "Añadido %1 %2"
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 %2 ago"
+msgstr "Hace %1 %2"
+
+#: lib/RT/Ticket_Overlay.pm:3444 lib/RT/Transaction_Overlay.pm:566
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 changed to %3"
+msgstr "%1 %2 ha cambiado a %3"
+
+#: lib/RT/Ticket_Overlay.pm:3441 lib/RT/Transaction_Overlay.pm:562 lib/RT/Transaction_Overlay.pm:607
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 deleted"
+msgstr "%1 %2 borrado"
+
+#: html/Admin/Elements/EditScrips:44 html/Admin/Elements/ListGlobalScrips:28
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 with template %3"
+msgstr "%1 %2 con la plantilla %3"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 this ticket\\n"
+msgstr "%1 (%2) %3 este caso\\n"
+
+#: html/Search/Listing.html:57
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr "%1 - %2 mostrados"
+
+#: bin/rt-crontool:169 bin/rt-crontool:176 bin/rt-crontool:182
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - An argument to pass to %2"
+msgstr "%1 - Un parametro para pasar a %2"
+
+#: bin/rt-crontool:185
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr "%1 - El estado de la salida actualiza STDOUT"
+
+#: bin/rt-crontool:179
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr "%1 - Especifica el modulo de accion que quieres usar"
+
+#: bin/rt-crontool:173
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr "%1 - Especifica el modulo de condicion que quieres usar"
+
+#: bin/rt-crontool:166
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr "%1 - Especifica el modulo de busqueda que quieres usar"
+
+#: lib/RT/ScripAction_Overlay.pm:122
+#. ($self->Id)
+msgid "%1 ScripAction loaded"
+msgstr "%1 ScripAction cargado"
+
+#: lib/RT/Ticket_Overlay.pm:3471
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 added as a value for %2"
+msgstr "$1 añadido como un valor de %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on"
+msgstr "%1 alias requieren un TicketId en el que trabajar"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on "
+msgstr "%1 alias requieren un TicketId en el que trabajar "
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on (from %2) %3"
+msgstr "%1 alias requieren un TicketId en el que trabajar (de %2) %3"
+
+#: lib/RT/Link_Overlay.pm:117 lib/RT/Link_Overlay.pm:124
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 appears to be a local object, but can't be found in the database"
+msgstr "%1 parece ser un objeto local, pero no se encuentra en la base de datos"
+
+#: html/Ticket/Elements/ShowDates:52 lib/RT/Transaction_Overlay.pm:483
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 by %2"
+msgstr "%1 por %2"
+
+#: lib/RT/Transaction_Overlay.pm:537 lib/RT/Transaction_Overlay.pm:626 lib/RT/Transaction_Overlay.pm:635 lib/RT/Transaction_Overlay.pm:638
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 changed from %2 to %3"
+msgstr "%1 ha cambiado de %2 a %3"
+
+#: lib/RT/Interface/Web.pm:857
+msgid "%1 could not be set to %2."
+msgstr "%1 no se ha podido fijar a %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr "%1 no pudo iniciar una transacción (%2)\\n"
+
+#: lib/RT/Ticket_Overlay.pm:2813
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr "%1 no pudo fijar el estado a resuelto. La base de datos de RT podría ser inconsistente."
+
+#: html/Elements/MyTickets:25
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr "Los %1 tickets de mayor prioridad que poseo... "
+
+#: html/Elements/MyRequests:25
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr "Los %1 tickets de mayor prioridad que he pedido"
+
+#: bin/rt-crontool:161
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr "$1 es una herramienta para actuar sobre los tickets con una herramienta de planificacion externa, como crom"
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr "%1 ha dejado de ser un %2 para esta cola."
+
+#: lib/RT/Ticket_Overlay.pm:1570
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr "%1 ha dejado de ser un %2 para este ticket."
+
+#: lib/RT/Ticket_Overlay.pm:3527
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr "%1 ha dejado de ser un valor para campo personalizable %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr "%1 no es un identificador de Cola válido."
+
+#: html/Ticket/Elements/ShowBasics:36
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr "%1 min"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr "%1 no mostrado"
+
+#: html/User/Elements/DelegateRights:76
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr "%1 privilegios"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr "%1 exitoso\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr "%1 tipo desconocido para $MessageId"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr "%1 tipo desconocido para %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 was created without a CurrentUser\\n"
+msgstr "%1 se creó sin CurrentUser\\n"
+
+#: lib/RT/Action/ResolveMembers.pm:42
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr "%1 resolverá todos los miembros de un grupo de tickets resueltos."
+
+#: NOT FOUND IN SOURCE
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr "%1 pondrá como pendiente una BASE [local] si es dependiente [o miembro] de una solicitud ligada."
+
+#: lib/RT/Transaction_Overlay.pm:435
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr "%1: ningún archivo adjunto especificado"
+
+#: html/Ticket/Elements/ShowTransaction:102
+#. ($size)
+msgid "%1b"
+msgstr "%1b"
+
+#: html/Ticket/Elements/ShowTransaction:99
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr "%1k"
+
+#: lib/RT/Ticket_Overlay.pm:1140
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr "'%1' es un valor inválido para el estado"
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr "'%1' no es una acción reconocida. "
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete group member)"
+msgstr "(Marque la caja para borrar al miembro del grupo)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr "(Marque la caja para borrar el scrip)"
+
+#: html/Admin/Elements/EditQueueWatchers:29 html/Admin/Elements/EditScrips:35 html/Admin/Elements/EditTemplates:36 html/Admin/Groups/Members.html:52 html/Ticket/Elements/EditLinks:33 html/Ticket/Elements/EditPeople:46 html/User/Groups/Members.html:55
+msgid "(Check box to delete)"
+msgstr "(Marque la caja para borrar)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check boxes to delete)"
+msgstr "(Marque las cajas para borrar)"
+
+#: html/Ticket/Create.html:178
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr "(Introduzca los identificadores de ticket o URLs, separados por espacios)"
+
+#: html/Admin/Queues/Modify.html:54 html/Admin/Queues/Modify.html:60
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr "(Si se deja vacio, pasara por defecto a %1"
+
+#: NOT FOUND IN SOURCE
+msgid "(No Value)"
+msgstr "(Sin Valor)"
+
+#: html/Admin/Elements/EditCustomFields:33 html/Admin/Elements/ListGlobalCustomFields:32
+msgid "(No custom fields)"
+msgstr "(No hay campos custom)"
+
+#: html/Admin/Groups/Members.html:50 html/User/Groups/Members.html:53
+msgid "(No members)"
+msgstr "(Sin miembros)"
+
+#: html/Admin/Elements/EditScrips:32 html/Admin/Elements/ListGlobalScrips:32
+msgid "(No scrips)"
+msgstr "(Sin scrips)"
+
+#: html/Admin/Elements/EditTemplates:31
+msgid "(No templates)"
+msgstr "(Sin plantillas)"
+
+#: html/Ticket/Update.html:85
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(Envia una copia oculta de esta actualizacion a una lista delimitada por comas de direcciones de email. <b>NO</b> cambia quien recibirá futuras actualizaciones)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Envía una copia oculta de esta actualización a una lista de direcciones de correo delimitada por comas. <b>No</b> cambia a quien recibirá futuras actualizaciones.)"
+
+#: html/Ticket/Create.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(Envia una copia oculta de esta actualización a una lista delimitada por comas de direcciones de email administrativas. Estas personas <b>recibirán</b> las futuras actualizaciones.)"
+
+#: html/Ticket/Update.html:81
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(Envia una copia oculta de esta actualización a una lista delimitada por comas de direcciones de email.<b>NO</b> cambia quien recibirá futuras actualizaciones."
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Manda una copia de esta actualización a una lista de direcciones de correo delimitada por comas. <b>No</b> cambia a quien recibirá futuras actualizaciones.)"
+
+#: html/Ticket/Create.html:69
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(Envia una copia de esta actualización a una lista de direcciones de correo delimitada por comas. Estas personas <b>recibirán</b> actualizaciones futuras."
+
+#: html/Admin/Groups/index.html:33 html/User/Groups/index.html:33
+msgid "(empty)"
+msgstr "(vacío)"
+
+#: html/Admin/Users/index.html:39
+msgid "(no name listed)"
+msgstr "(no hay nombres listados)"
+
+#: html/Elements/MyRequests:43 html/Elements/MyTickets:45
+msgid "(no subject)"
+msgstr "(sin asunto)"
+
+#: html/Admin/Elements/SelectRights:48 html/Elements/SelectCustomFieldValue:30 html/Ticket/Elements/EditCustomField:59 html/Ticket/Elements/ShowCustomFields:36 lib/RT/Transaction_Overlay.pm:536
+msgid "(no value)"
+msgstr "(sin valor)"
+
+#: html/Ticket/Elements/EditLinks:116
+msgid "(only one ticket)"
+msgstr "(solo un ticket)"
+
+#: html/Elements/MyRequests:52 html/Elements/MyTickets:55
+msgid "(pending approval)"
+msgstr "(pendiente de aprobacion)"
+
+#: html/Elements/MyRequests:54 html/Elements/MyTickets:57
+msgid "(pending other tickets)"
+msgstr "(pendiente de otros tickets)"
+
+#: html/Admin/Users/Modify.html:50
+msgid "(required)"
+msgstr "(requerido)"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "(untitled)"
+msgstr "(sin titulo)"
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I own..."
+msgstr "Los 25 tickets de mayor prioridad que poseo..."
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I requested..."
+msgstr "Los 25 tickets de mayor prioridad que he solicitado..."
+
+#: html/Ticket/Elements/ShowBasics:32
+msgid "<% $Ticket->Status%>"
+msgstr "<% $Ticket->Status%>"
+
+#: html/Elements/SelectTicketTypes:27
+msgid "<% $_ %>"
+msgstr "<% $_ %>"
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:26
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"Nuevo ticket en\">&nbsp;%1"
+
+#: etc/initialdata:203
+msgid "A blank template"
+msgstr "Una plantilla en blanco"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Deleted"
+msgstr "ACE Borrado"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Loaded"
+msgstr "ACE Cargado"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be deleted"
+msgstr "ACE no se pudo borrar"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be found"
+msgstr "ACE no se encontró"
+
+#: lib/RT/ACE_Overlay.pm:157 lib/RT/Principal_Overlay.pm:181
+msgid "ACE not found"
+msgstr "ACE no encontrado"
+
+#: lib/RT/ACE_Overlay.pm:831
+msgid "ACEs can only be created and deleted."
+msgstr "ACEs solo pueden ser creadas o borradas."
+
+#: bin/rt-commit-handler:755
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr "Abortando para prevenir modificaciones no intencionadas al ticket\\n"
+
+#: html/User/Elements/Tabs:32
+msgid "About me"
+msgstr "Sobre mi"
+
+#: html/Admin/Users/Modify.html:80
+msgid "Access control"
+msgstr "Control de acceso"
+
+#: html/Admin/Elements/EditScrip:57
+msgid "Action"
+msgstr "Acción"
+
+#: lib/RT/Scrip_Overlay.pm:147
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr "Acción %1 no encontrada"
+
+#: bin/rt-crontool:123
+msgid "Action committed."
+msgstr "Action committed."
+
+#: bin/rt-crontool:119
+msgid "Action prepared..."
+msgstr "Acción preparada..."
+
+#: html/Search/Bulk.html:92
+msgid "Add AdminCc"
+msgstr "Añadir AdminCc"
+
+#: html/Search/Bulk.html:90
+msgid "Add Cc"
+msgstr "Añadir Cc"
+
+#: html/Ticket/Create.html:114 html/Ticket/Update.html:100
+msgid "Add More Files"
+msgstr "Añadir más archivos"
+
+#: html/Search/Bulk.html:88
+msgid "Add Requestor"
+msgstr "Añadir solicitante"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a keyword selection to this queue"
+msgstr "Añadir una seleccion de palabra clave a esta cola"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr "Añadir un nuevo scrip global"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr "Añadir un scrip a esta cola"
+
+#: html/Admin/Global/Scrip.html:55
+msgid "Add a scrip which will apply to all queues"
+msgstr "Añadir un scrip que se aplicará a todas las colas"
+
+#: html/Search/Bulk.html:118
+msgid "Add comments or replies to selected tickets"
+msgstr "Añadir comentarios o respuestas a los tickets seleccionados"
+
+#: html/Admin/Groups/Members.html:42 html/User/Groups/Members.html:39
+msgid "Add members"
+msgstr "Añadir miembro"
+
+#: html/Admin/Queues/People.html:66 html/Ticket/Elements/AddWatchers:28
+msgid "Add new watchers"
+msgstr "Añadir nuevos observadores"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr "AddNextState"
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr "Principal ha sido añadido como %1 para esta cola"
+
+#: lib/RT/Ticket_Overlay.pm:1454
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr "Principal ha sido añadido como %1 para este ticket"
+
+#: html/Admin/Elements/ModifyUser:76 html/Admin/Users/Modify.html:122 html/User/Prefs.html:88
+msgid "Address1"
+msgstr "Dirección 1"
+
+#: html/Admin/Elements/ModifyUser:78 html/Admin/Users/Modify.html:127 html/User/Prefs.html:90
+msgid "Address2"
+msgstr "Dirección 2"
+
+#: html/Ticket/Create.html:74
+msgid "Admin Cc"
+msgstr "Admin Cc"
+
+#: etc/initialdata:274
+msgid "Admin Comment"
+msgstr "Admin Comment"
+
+#: etc/initialdata:256
+msgid "Admin Correspondence"
+msgstr "Admin Correspondence"
+
+#: html/Admin/Queues/index.html:25 html/Admin/Queues/index.html:28
+msgid "Admin queues"
+msgstr "Administración de colas"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr "Administración de usuarios"
+
+#: html/Admin/Global/index.html:26 html/Admin/Global/index.html:28
+msgid "Admin/Global configuration"
+msgstr "Adminsitración de la configuración global"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr "Administración de Grupos"
+
+#: html/Admin/Queues/Modify.html:25 html/Admin/Queues/Modify.html:29
+msgid "Admin/Queue/Basics"
+msgstr "Administración de una cola"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr "AdminAllPersonalGroups"
+
+#: etc/initialdata:56 html/Ticket/Elements/ShowPeople:39 html/Ticket/Update.html:50 lib/RT/ACE_Overlay.pm:89
+msgid "AdminCc"
+msgstr "AdminCc"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr "AdminComment"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr "AdminCorrespondence"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "AdminCustomFields"
+msgstr "AdminCustomFields"
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "AdminGroup"
+msgstr "AdminGroup"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "AdminGroupMembership"
+msgstr "AdminGroupMembership"
+
+#: lib/RT/System.pm:59
+msgid "AdminOwnPersonalGroups"
+msgstr "AdminOwnPersonalGroups"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "AdminQueue"
+msgstr "AdminQueue"
+
+#: lib/RT/System.pm:60
+msgid "AdminUsers"
+msgstr "AdminUsers"
+
+#: html/Admin/Queues/People.html:48 html/Ticket/Elements/EditPeople:54
+msgid "Administrative Cc"
+msgstr "Cc Administrativa"
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr "Búsqueda avanzada"
+
+#: html/Elements/SelectDateRelation:36
+msgid "After"
+msgstr "Después"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr "Edad"
+
+#: html/Admin/Elements/EditCustomFields:96
+msgid "All Custom Fields"
+msgstr "Todos los campos custom"
+
+#: html/Admin/Queues/index.html:53
+msgid "All Queues"
+msgstr "Todas las colas"
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr "Siempre envia un mensaje a los solicitantes independientemente del remitente del mensaje"
+
+#: html/Elements/Tabs:58
+msgid "Approval"
+msgstr "Aprobacion"
+
+#: html/Approvals/Display.html:46 html/Approvals/Elements/Approve:27 html/Approvals/Elements/ShowDependency:42 html/Approvals/index.html:65
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr "Aprobacion #%1: %2"
+
+#: html/Approvals/index.html:54
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr "Aprobación #%1: No se han guardado las notas debido a un error del sistema"
+
+#: html/Approvals/index.html:52
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr "Aprobacion #%1: Notas guardadas"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Details"
+msgstr "Detalles de la aprobación"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval diagram"
+msgstr "Diagrama de la aprobación"
+
+#: html/Approvals/Elements/Approve:45
+msgid "Approve"
+msgstr "Aprobar"
+
+#: etc/initialdata:431 etc/upgrade/2.1.71:148
+msgid "Approver's notes: %1"
+msgstr "Notas del aprobador: %1"
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "Abr."
+
+#: NOT FOUND IN SOURCE
+msgid "April"
+msgstr "Abril"
+
+#: html/Elements/SelectSortOrder:35
+msgid "Ascending"
+msgstr "Ascendente"
+
+#: html/Search/Bulk.html:127 html/SelfService/Update.html:36 html/Ticket/ModifyAll.html:83 html/Ticket/Update.html:100
+msgid "Attach"
+msgstr "Adjunto"
+
+#: html/SelfService/Create.html:67 html/Ticket/Create.html:110
+msgid "Attach file"
+msgstr "Adjuntar archivo"
+
+#: html/Ticket/Create.html:98 html/Ticket/Update.html:89
+msgid "Attached file"
+msgstr "Archivo adjunto"
+
+#: html/SelfService/Attachment/dhandler:36
+msgid "Attachment '%1' could not be loaded"
+msgstr "Archivo adjunto '%1' no pudo ser cargado"
+
+#: lib/RT/Transaction_Overlay.pm:443
+msgid "Attachment created"
+msgstr "Archivo adjunto creado"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "Nombre del archivo adjunto"
+
+#: html/Ticket/Elements/ShowAttachments:26
+msgid "Attachments"
+msgstr "Archivos adjuntos"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "Ago."
+
+#: NOT FOUND IN SOURCE
+msgid "August"
+msgstr "Agosto"
+
+#: html/Admin/Elements/ModifyUser:66
+msgid "AuthSystem"
+msgstr "Sistema de autenticación"
+
+#: etc/initialdata:206
+msgid "Autoreply"
+msgstr "Autorespuesta"
+
+#: etc/initialdata:72
+msgid "Autoreply To Requestors"
+msgstr "Autorespuesta a los solicitantes"
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr "AutoreplyToRequestors"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr "Firma PGP incorrecta: %1\\n"
+
+#: html/SelfService/Attachment/dhandler:40
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr "Identificador de archivo adjunto erróneo. No se puede encontrar el archivo '%1'\\n"
+
+#: bin/rt-commit-handler:827
+#. ($val)
+msgid "Bad data in %1"
+msgstr "Datos incorrectos en %1"
+
+#: html/SelfService/Attachment/dhandler:43
+#. ($trans, $AttachmentObj->TransactionId())
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr "Número de transacción incorrecta para el archivo adjunto. %1 debe ser %2\\n"
+
+#: html/Admin/Elements/GroupTabs:39 html/Admin/Elements/QueueTabs:39 html/Admin/Elements/UserTabs:38 html/Ticket/Elements/Tabs:90 html/User/Elements/GroupTabs:38
+msgid "Basics"
+msgstr "Basicos"
+
+#: html/Ticket/Update.html:83
+msgid "Bcc"
+msgstr "Bcc"
+
+#: html/Admin/Elements/EditScrip:88 html/Admin/Global/GroupRights.html:85 html/Admin/Global/Template.html:46 html/Admin/Global/UserRights.html:54 html/Admin/Groups/GroupRights.html:73 html/Admin/Groups/Members.html:81 html/Admin/Groups/Modify.html:56 html/Admin/Groups/UserRights.html:55 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:45 html/Admin/Queues/UserRights.html:54 html/User/Groups/Modify.html:56
+msgid "Be sure to save your changes"
+msgstr "Asegúrese de salvar sus cambios"
+
+#: html/Elements/SelectDateRelation:34 lib/RT/CurrentUser.pm:322
+msgid "Before"
+msgstr "Antes"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin Approval"
+msgstr "Begin Approval"
+
+#: etc/initialdata:202
+msgid "Blank"
+msgstr "Vacio"
+
+#: html/Search/Listing.html:79
+msgid "Bookmarkable URL for this search"
+msgstr "URL para guardar esta búsqueda en sus marcadores"
+
+#: html/Ticket/Elements/ShowHistory:39 html/Ticket/Elements/ShowHistory:45
+msgid "Brief headers"
+msgstr "Encabezados breves"
+
+#: html/Search/Bulk.html:25 html/Search/Bulk.html:26
+msgid "Bulk ticket update"
+msgstr "Actualización de varios tickets a la vez"
+
+#: lib/RT/User_Overlay.pm:1331
+msgid "Can not modify system users"
+msgstr "No se pueden modificar los usuarios del sistema"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Can this principal see this queue"
+msgstr "Can this principal see this queue"
+
+#: lib/RT/CustomField_Overlay.pm:144
+msgid "Can't add a custom field value without a name"
+msgstr "No se puede agregar un campo personalizable si no tiene un nombre"
+
+#: lib/RT/Link_Overlay.pm:132
+msgid "Can't link a ticket to itself"
+msgstr "No se puede ligar un ticket a sí mismo"
+
+#: lib/RT/Ticket_Overlay.pm:2787
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr "No se puede fusionar dentro de un caso ya fusionado. Nunca deberia recibir este error"
+
+#: lib/RT/Ticket_Overlay.pm:2605 lib/RT/Ticket_Overlay.pm:2674
+msgid "Can't specifiy both base and target"
+msgstr "No se puede especificar origen y destino al mismo tiempo"
+
+#: html/autohandler:112
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr "No se puede crear el usuario: %1"
+
+#: etc/initialdata:50 html/Admin/Queues/People.html:44 html/SelfService/Create.html:51 html/SelfService/Display.html:50 html/Ticket/Create.html:64 html/Ticket/Elements/EditPeople:51 html/Ticket/Elements/ShowPeople:35 html/Ticket/Update.html:45 html/Ticket/Update.html:78 lib/RT/ACE_Overlay.pm:88
+msgid "Cc"
+msgstr "Cc"
+
+#: html/SelfService/Prefs.html:31
+msgid "Change password"
+msgstr "Cambiar contraseña"
+
+#: html/Ticket/Create.html:101 html/Ticket/Update.html:92
+msgid "Check box to delete"
+msgstr "Check box to delete"
+
+#: html/Admin/Elements/SelectRights:31
+msgid "Check box to revoke right"
+msgstr "Seleccione la caja para quitar el permiso"
+
+#: html/Ticket/Create.html:183 html/Ticket/Elements/EditLinks:131 html/Ticket/Elements/EditLinks:69 html/Ticket/Elements/ShowLinks:51
+msgid "Children"
+msgstr "Hijo"
+
+#: html/Admin/Elements/ModifyUser:80 html/Admin/Users/Modify.html:132 html/User/Prefs.html:92
+msgid "City"
+msgstr "Ciudad"
+
+#: html/Ticket/Elements/ShowDates:47
+msgid "Closed"
+msgstr "Cerrado"
+
+#: html/SelfService/Elements/Tabs:60
+msgid "Closed requests"
+msgstr "Solicitudes cerradas"
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr "No se entendió el comando!\\n"
+
+#: html/Ticket/Elements/ShowTransaction:179 html/Ticket/Elements/Tabs:153
+msgid "Comment"
+msgstr "Comentario"
+
+#: html/Admin/Elements/ModifyQueue:45 html/Admin/Queues/Modify.html:58
+msgid "Comment Address"
+msgstr "Dirección de comentario"
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr "Comentario no grabado"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Comment on tickets"
+msgstr "Comentario sobre los tickets"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "CommentOnTicket"
+msgstr "CommentOnTicket"
+
+#: html/Admin/Elements/ModifyUser:35
+msgid "Comments"
+msgstr "Comentarios"
+
+#: html/Ticket/ModifyAll.html:70 html/Ticket/Update.html:70
+msgid "Comments (Not sent to requestors)"
+msgstr "Comentarios (no se envían a los solicitantes)"
+
+#: html/Search/Bulk.html:122
+msgid "Comments (not sent to requestors)"
+msgstr "Comentarios (no se envían a los solicitantes)"
+
+#: html/Elements/ViewUser:27
+#. ($name)
+msgid "Comments about %1"
+msgstr "Comentarios acerca de %1"
+
+#: html/Admin/Users/Modify.html:185 html/Ticket/Elements/ShowRequestor:44
+msgid "Comments about this user"
+msgstr "Comentarios acerca de este usuario"
+
+#: lib/RT/Transaction_Overlay.pm:545
+msgid "Comments added"
+msgstr "Comentarios añadidos"
+
+#: lib/RT/Action/Generic.pm:140
+msgid "Commit Stubbed"
+msgstr "Acción realizada"
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr "Compilar restricciones"
+
+#: html/Admin/Elements/EditScrip:41
+msgid "Condition"
+msgstr "Condición"
+
+#: bin/rt-crontool:109
+msgid "Condition matches..."
+msgstr "La condicion coincide..."
+
+#: lib/RT/Scrip_Overlay.pm:160
+msgid "Condition not found"
+msgstr "Condición no encontrada"
+
+#: html/Elements/Tabs:52
+msgid "Configuration"
+msgstr "Configuración"
+
+#: html/SelfService/Prefs.html:33
+msgid "Confirm"
+msgstr "Confirmar"
+
+#: html/Admin/Elements/ModifyUser:60
+msgid "ContactInfoSystem"
+msgstr "Información de contacto"
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr "Fecha de contacto '%1' no pudo ser leida"
+
+#: html/Admin/Elements/ModifyTemplate:44 html/Ticket/ModifyAll.html:87
+msgid "Content"
+msgstr "Contenido"
+
+#: NOT FOUND IN SOURCE
+msgid "Coould not create group"
+msgstr "No se pudo crear grupo"
+
+#: etc/initialdata:266
+msgid "Correspondence"
+msgstr "Correspondencia"
+
+#: html/Admin/Elements/ModifyQueue:39 html/Admin/Queues/Modify.html:51
+msgid "Correspondence Address"
+msgstr "Dirección de corresponencia"
+
+#: lib/RT/Transaction_Overlay.pm:541
+msgid "Correspondence added"
+msgstr "Correspondencia agregada"
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr "Correspondencia no guardada"
+
+#: lib/RT/Ticket_Overlay.pm:3458
+msgid "Could not add new custom field value for ticket. "
+msgstr "No se pudo añadir un nuevo valor de campo personalizable para el ticket. "
+
+#: NOT FOUND IN SOURCE
+msgid "Could not add new custom field value for ticket. %1 "
+msgstr "No se pudo añadir un nuevo valor de campo personalizable para el ticket. %1 "
+
+#: lib/RT/Ticket_Overlay.pm:2963 lib/RT/Ticket_Overlay.pm:2971 lib/RT/Ticket_Overlay.pm:2987
+msgid "Could not change owner. "
+msgstr "No se pudo cambiar el propietario. "
+
+#: html/Admin/Elements/EditCustomField:68 html/Admin/Elements/EditCustomFields:166
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr "No se puede crear un CampoPersonalizable"
+
+#: html/User/Groups/Modify.html:77 lib/RT/Group_Overlay.pm:474 lib/RT/Group_Overlay.pm:481
+msgid "Could not create group"
+msgstr "No se pudo crear el grupo"
+
+#: html/Admin/Global/Template.html:75 html/Admin/Queues/Template.html:72
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr "No se pudo crear la plantilla: %1"
+
+#: lib/RT/Ticket_Overlay.pm:1073 lib/RT/Ticket_Overlay.pm:333
+msgid "Could not create ticket. Queue not set"
+msgstr "No se pudo crear el ticket. Cola no seleccionada"
+
+#: lib/RT/User_Overlay.pm:208 lib/RT/User_Overlay.pm:220 lib/RT/User_Overlay.pm:238 lib/RT/User_Overlay.pm:414
+msgid "Could not create user"
+msgstr "No se pudo crear el usuario"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not create watcher for requestor"
+msgstr "No se pudo crear un observador para el solicitante"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr "No se pudo encontrar un ticket con identificador $1"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr "No se pudo encontrar el grupo %1."
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1422
+msgid "Could not find or create that user"
+msgstr "No se pudo encontrar o crear el usuario"
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1501
+msgid "Could not find that principal"
+msgstr "No se pudo encontrar ese principal"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr "No se pudo encontrar el usuario %1."
+
+#: html/Admin/Groups/Members.html:88 html/User/Groups/Members.html:90 html/User/Groups/Modify.html:82
+msgid "Could not load group"
+msgstr "No se puede cargar el grupo"
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr "No se pudo hacer ese principal un %1 para esta cola"
+
+#: lib/RT/Ticket_Overlay.pm:1443
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr "No se pudo hacer ese principal un %1 para este ticket"
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr "No se pudo quitar ese principal como un %1 para esta cola"
+
+#: lib/RT/Ticket_Overlay.pm:1559
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr "No se pudo quitar ese principal como un %1 para este ticket"
+
+#: lib/RT/Group_Overlay.pm:985
+msgid "Couldn't add member to group"
+msgstr "No se pudo agregar el miembro al grupo"
+
+#: lib/RT/Ticket_Overlay.pm:3468 lib/RT/Ticket_Overlay.pm:3524
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr "No se pudo crear la transacción: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr "No se pudo averiguar que hacer a partir de la firma gpg de la respuesta"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr "No se pudo encontrar el grupo\\n"
+
+#: lib/RT/Interface/Web.pm:866
+msgid "Couldn't find row"
+msgstr "No se pudo encontrar la fila"
+
+#: lib/RT/Group_Overlay.pm:959
+msgid "Couldn't find that principal"
+msgstr "No pudo enconcontrar ese principal"
+
+#: lib/RT/CustomField_Overlay.pm:175
+msgid "Couldn't find that value"
+msgstr "No se pudo encontrar ese valor"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find that watcher"
+msgstr "No se pudo encontrar ese observador"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr "No se pudo encontrar el usuario\\n"
+
+#: lib/RT/CurrentUser.pm:112
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr "No se pudo cargar %1 desde la base de datos de usuarios.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load KeywordSelects."
+msgstr "No se pudo cargar KeywordSelects"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr "No se pudo cargar el archivo de configuración de RT '%1' %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr "No se pudieron cargar los Scrips."
+
+#: html/Admin/Groups/GroupRights.html:88 html/Admin/Groups/UserRights.html:75
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr "No se pudo cargar el grupo %1"
+
+#: lib/RT/Link_Overlay.pm:175 lib/RT/Link_Overlay.pm:184 lib/RT/Link_Overlay.pm:211
+msgid "Couldn't load link"
+msgstr "No se puedo cargar el enlace"
+
+#: html/Admin/Elements/EditCustomFields:147 html/Admin/Queues/People.html:121
+#. ($id)
+msgid "Couldn't load queue"
+msgstr "No se pudo cargar la cola"
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:72
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr "No se pudo cargar la cola %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr "No se pudo cargar el scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr "No se pudo cargar la plantilla"
+
+#: html/Admin/Users/Prefs.html:79
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr "No se pudo cargar ese usuario (%1)"
+
+#: html/SelfService/Display.html:166
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr "No se pudo cargar el ticket '%1'"
+
+#: html/Admin/Elements/ModifyUser:86 html/Admin/Users/Modify.html:149 html/User/Prefs.html:98
+msgid "Country"
+msgstr "País"
+
+#: html/Admin/Elements/CreateUserCalled:26 html/Ticket/Create.html:135 html/Ticket/Create.html:195
+msgid "Create"
+msgstr "Crear"
+
+#: etc/initialdata:128
+msgid "Create Tickets"
+msgstr "Crear Tickets"
+
+#: html/Admin/Elements/EditCustomField:58
+msgid "Create a CustomField"
+msgstr "Crear CampoPersonalizable"
+
+#: html/Admin/Queues/CustomField.html:48
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr "Crear un campo personalizables para la cola %1"
+
+#: html/Admin/Global/CustomField.html:48
+msgid "Create a CustomField which applies to all queues"
+msgstr "Crear un campo personalizable que se aplique a todas las colas"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr "Crear un nuevo campo personalizable"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr "Crear un nuevo scrip global"
+
+#: html/Admin/Groups/Modify.html:67 html/Admin/Groups/Modify.html:93
+msgid "Create a new group"
+msgstr "Creat un nuevo grupo"
+
+#: html/User/Groups/Modify.html:67 html/User/Groups/Modify.html:92
+msgid "Create a new personal group"
+msgstr "Crear un nuevo grupo personal"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr "Crear una nueva cola"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr "Crear un nuevo scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr "Crear una nueva plantilla"
+
+#: html/SelfService/Create.html:30 html/Ticket/Create.html:25 html/Ticket/Create.html:28 html/Ticket/Create.html:36
+msgid "Create a new ticket"
+msgstr "Crear un nuevo ticket"
+
+#: html/Admin/Users/Modify.html:214 html/Admin/Users/Modify.html:241
+msgid "Create a new user"
+msgstr "Crear un nuevo usuario"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "Crear una cola"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr "Crear una cola llamada "
+
+#: html/SelfService/Create.html:25 html/SelfService/Create.html:27
+msgid "Create a request"
+msgstr "Crear una solicitud"
+
+#: html/Admin/Queues/Scrip.html:59
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr "Crear un scrip para la cola %1"
+
+#: html/Admin/Global/Template.html:69 html/Admin/Queues/Template.html:65
+msgid "Create a template"
+msgstr "Crear una plantilla"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1 / %2 / %3 "
+msgstr "Creación fallida: %1 / %2 / %3 "
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1/%2/%3"
+msgstr "Creación fallida: %1 / %2 / %3 "
+
+#: etc/initialdata:130
+msgid "Create new tickets based on this scrip's template"
+msgstr "Crear nuevos tickets basados en esta plantilla de scrip"
+
+#: html/SelfService/Create.html:81
+msgid "Create ticket"
+msgstr "Crear ticket"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Create tickets in this queue"
+msgstr "Crear tickets en esta cola"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Create, delete and modify custom fields"
+msgstr "Crear, borrar y modifical campos personalizables"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Create, delete and modify queues"
+msgstr "Crear, borrar y modificar colas"
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr "Crear, borrar y modificar los miembros de cualquier grupo personal de usuario"
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify the members of personal groups"
+msgstr "Crear, borrar y modificar los miembros de los grupos personales"
+
+#: lib/RT/System.pm:60
+msgid "Create, delete and modify users"
+msgstr "Crear, borrar y modificar usuarios"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "CreateTicket"
+msgstr "CreateTicket"
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1167
+msgid "Created"
+msgstr "Creado"
+
+#: html/Admin/Elements/EditCustomField:71
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr "CampoPersonalizable %1 creado"
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr "Plantilla %1 creada"
+
+#: html/Ticket/Elements/EditLinks:28
+msgid "Current Relationships"
+msgstr "Relaciones actuales"
+
+#: html/Admin/Elements/EditScrips:30
+msgid "Current Scrips"
+msgstr "Scrips actuales"
+
+#: html/Admin/Groups/Members.html:39 html/User/Groups/Members.html:42
+msgid "Current members"
+msgstr "Miembros actuales"
+
+#: html/Admin/Elements/SelectRights:29
+msgid "Current rights"
+msgstr "Permisos actuales"
+
+#: html/Search/Listing.html:71
+msgid "Current search criteria"
+msgstr "Criterio de busqueda actual"
+
+#: html/Admin/Queues/People.html:41 html/Ticket/Elements/EditPeople:45
+msgid "Current watchers"
+msgstr "Observadores actuales"
+
+#: html/Admin/Global/CustomField.html:55
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr "Campo personalizable #%1"
+
+#: html/Admin/Elements/QueueTabs:53 html/Admin/Elements/SystemTabs:40 html/Admin/Global/index.html:50 html/Ticket/Elements/ShowSummary:35
+msgid "Custom Fields"
+msgstr "Campos personalizables"
+
+#: html/Admin/Elements/EditScrip:73
+msgid "Custom action cleanup code"
+msgstr "Codigo de limpieza de accion personalizable"
+
+#: html/Admin/Elements/EditScrip:65
+msgid "Custom action preparation code"
+msgstr "Codigo de preparacion de accion personalizable"
+
+#: html/Admin/Elements/EditScrip:49
+msgid "Custom condition"
+msgstr "Condicion personalizable"
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr "Campo personalizado %1 %2 %3"
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr "Campo personalizado %1 tiene un valor."
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr "Campo personalizado %1 no tiene un valor."
+
+#: lib/RT/Ticket_Overlay.pm:3360
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr "Campo personalizado %1 no encontrado"
+
+#: html/Admin/Elements/EditCustomFields:197
+msgid "Custom field deleted"
+msgstr "Campo personalizable borrado"
+
+#: lib/RT/Ticket_Overlay.pm:3510
+msgid "Custom field not found"
+msgstr "Campo personalizado no encontrado"
+
+#: lib/RT/CustomField_Overlay.pm:283
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr "El valor del campo %1 no pudo ser encontrado para el campo %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr "Valor del campo cambiado de %1 a %2"
+
+#: lib/RT/CustomField_Overlay.pm:185
+msgid "Custom field value could not be deleted"
+msgstr "El valor del campo no pudo ser borrado"
+
+#: lib/RT/CustomField_Overlay.pm:289
+msgid "Custom field value could not be found"
+msgstr "El valor del campo no pudo se encontrado"
+
+#: lib/RT/CustomField_Overlay.pm:183 lib/RT/CustomField_Overlay.pm:291
+msgid "Custom field value deleted"
+msgstr "Valor del campo borrado"
+
+#: lib/RT/Transaction_Overlay.pm:550
+msgid "CustomField"
+msgstr "CustomField"
+
+#: NOT FOUND IN SOURCE
+msgid "Data error"
+msgstr "Error de datos"
+
+#: html/Ticket/Create.html:161 html/Ticket/Elements/ShowSummary:53 html/Ticket/Elements/Tabs:93 html/Ticket/ModifyAll.html:44
+msgid "Dates"
+msgstr "Fechas"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "Dic."
+
+#: NOT FOUND IN SOURCE
+msgid "December"
+msgstr "Diciembre"
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr "Plantilla de autorespuesta por defecto"
+
+#: etc/initialdata:207
+msgid "Default Autoresponse template"
+msgstr "Plantilla de autorespuesta por defect"
+
+#: etc/initialdata:275
+msgid "Default admin comment template"
+msgstr "Plantilla de comentario de admin por defecto"
+
+#: etc/initialdata:257
+msgid "Default admin correspondence template"
+msgstr "Plantilla de correspondencia de admin por defecto"
+
+#: etc/initialdata:267
+msgid "Default correspondence template"
+msgstr "Plantilla de correspondencia por defecto"
+
+#: etc/initialdata:238
+msgid "Default transaction template"
+msgstr "Plantilla de trasacciones por defecto"
+
+#: lib/RT/Transaction_Overlay.pm:645
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr "Por defecto: %1/%2 ha cambiado de %3 a %4"
+
+#: html/User/Delegation.html:25 html/User/Delegation.html:28
+msgid "Delegate rights"
+msgstr "Delegar derechos"
+
+#: lib/RT/System.pm:63
+msgid "Delegate specific rights which have been granted to you."
+msgstr "Delegar derechos especificos que te han sido concedidos"
+
+#: lib/RT/System.pm:63
+msgid "DelegateRights"
+msgstr "DelegateRights"
+
+#: html/User/Elements/Tabs:38
+msgid "Delegation"
+msgstr "Delegar"
+
+#: NOT FOUND IN SOURCE
+msgid "Delete"
+msgstr "Borrar"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "Delete tickets"
+msgstr "Borrar tickets"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "DeleteTicket"
+msgstr "DeleteTicket"
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr "Al borrar este objeto, se puede romper la integridad referencial"
+
+#: lib/RT/Queue_Overlay.pm:292
+msgid "Deleting this object would break referential integrity"
+msgstr "Al borrar este objeto, se romperá la integridad referencial"
+
+#: lib/RT/User_Overlay.pm:430
+msgid "Deleting this object would violate referential integrity"
+msgstr "Al borrar este objeto, se violará la integridad referencial"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity."
+msgstr "Al borrar este objeto, se violará la integridad referencial."
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity. That's bad."
+msgstr "Al borrar este objeto, se violará la integridad referencial. Eso es malo."
+
+#: html/Approvals/Elements/Approve:46
+msgid "Deny"
+msgstr "Denegar"
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/EditLinks:123 html/Ticket/Elements/EditLinks:47 html/Ticket/Elements/ShowDependencies:32 html/Ticket/Elements/ShowLinks:35
+msgid "Depended on by"
+msgstr "Dependen de este ticket"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr "Dependencias: \\n"
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:180 html/Ticket/Elements/EditLinks:119 html/Ticket/Elements/EditLinks:36 html/Ticket/Elements/ShowDependencies:25 html/Ticket/Elements/ShowLinks:27
+msgid "Depends on"
+msgstr "Depende de"
+
+#: NOT FOUND IN SOURCE
+msgid "DependsOn"
+msgstr "DependsOn"
+
+#: html/Elements/SelectSortOrder:35
+msgid "Descending"
+msgstr "Descendiente"
+
+#: html/SelfService/Create.html:75 html/Ticket/Create.html:119
+msgid "Describe the issue below"
+msgstr "Describa el problema debajo"
+
+#: html/Admin/Elements/AddCustomFieldValue:27 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/EditScrip:34 html/Admin/Elements/ModifyQueue:36 html/Admin/Elements/ModifyTemplate:36 html/Admin/Groups/Modify.html:49 html/Admin/Queues/Modify.html:48 html/Elements/SelectGroups:27 html/User/Groups/Modify.html:49
+msgid "Description"
+msgstr "Descripción"
+
+#: html/SelfService/Elements/MyRequests:44
+msgid "Details"
+msgstr "Detalles"
+
+#: html/Ticket/Elements/Tabs:85
+msgid "Display"
+msgstr "Despliegue"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Display Access Control List"
+msgstr "Mostrar Lista de Control de Acceso"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Display Scrip templates for this queue"
+msgstr "Mostrar plantillas de scrip para esta cola"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Display Scrips for this queue"
+msgstr "Mostrar scrips para esta cola"
+
+#: html/Ticket/Elements/ShowHistory:35
+msgid "Display mode"
+msgstr "Modo de despliegue"
+
+#: html/SelfService/Display.html:25 html/SelfService/Display.html:29
+#. ($Ticket->id)
+msgid "Display ticket #%1"
+msgstr "Despliega ticket #%1"
+
+#: lib/RT/System.pm:54
+msgid "Do anything and everything"
+msgstr "Hacer cualquier cosa y todo"
+
+#: html/Elements/Refresh:30
+msgid "Don't refresh this page."
+msgstr "No recargar esta página"
+
+#: html/Search/Elements/PickRestriction:114
+msgid "Don't show search results"
+msgstr "No mostrar los resultados de la busqueda"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "Download"
+msgstr "Descargar"
+
+#: html/Elements/SelectDateType:32 html/Ticket/Create.html:167 html/Ticket/Elements/EditDates:45 html/Ticket/Elements/ShowDates:43 lib/RT/Ticket_Overlay.pm:1171
+msgid "Due"
+msgstr "Retraso"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr "La fecha de retraso '%1' no pudo ser leida"
+
+#: bin/rt-commit-handler:754
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr "ERROR: No se pudo cargar el ticket '%1': %2.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit"
+msgstr "Editar"
+
+#: html/Admin/Queues/CustomFields.html:45
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr "Editar campos personalizados para %1"
+
+#: html/Ticket/ModifyLinks.html:36
+msgid "Edit Relationships"
+msgstr "Editar relaciones"
+
+#: html/Admin/Queues/Templates.html:41
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr "Editar plantillas para la cola %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit keywords"
+msgstr "Editar palabras clave"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr "Editar acciones"
+
+#: html/Admin/Global/index.html:46
+msgid "Edit system templates"
+msgstr "Editar plantillas del sistema"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr "Editar plantillas para %1"
+
+#: html/Admin/Elements/ModifyQueue:25 html/Admin/Queues/Modify.html:117
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr "Editando configuración para la cola %1"
+
+#: html/Admin/Elements/ModifyUser:25
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr "Editando configuración para el usuario %1"
+
+#: html/Admin/Elements/EditCustomField:74
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr "Editando campo %1"
+
+#: html/Admin/Groups/Members.html:32
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr "Editando los miembros del grupo %1"
+
+#: html/User/Groups/Members.html:129
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr "Editando los miembros para el grupo personal %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr "Editando plantilla %1"
+
+#: lib/RT/Ticket_Overlay.pm:2615 lib/RT/Ticket_Overlay.pm:2683
+msgid "Either base or target must be specified"
+msgstr "La base o el destinatario deben ser especificados"
+
+#: html/Admin/Users/Modify.html:53 html/Admin/Users/Prefs.html:46 html/Elements/SelectUsers:27 html/Ticket/Elements/AddWatchers:56 html/User/Prefs.html:42
+msgid "Email"
+msgstr "Correo"
+
+#: lib/RT/User_Overlay.pm:188
+msgid "Email address in use"
+msgstr "La dirección de correo ya está en uso"
+
+#: html/Admin/Elements/ModifyUser:42
+msgid "EmailAddress"
+msgstr "Correo Electrónico"
+
+#: html/Admin/Elements/ModifyUser:54
+msgid "EmailEncoding"
+msgstr "Codificación para el correo"
+
+#: html/Admin/Elements/EditCustomField:36
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr "Habilitado (Desmarcar esta caja deshabilita este campo personalizable)"
+
+#: html/Admin/Groups/Modify.html:53 html/User/Groups/Modify.html:53
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr "Habilitado (Desmarcar esta caja deshabilita este campo personalizable)"
+
+#: html/Admin/Queues/Modify.html:84
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr "Habilitado (Desmarcar esta caja, deshabilita esta cola)"
+
+#: html/Admin/Elements/EditCustomFields:99
+msgid "Enabled Custom Fields"
+msgstr "Campos Personalizables Habilitados"
+
+#: html/Admin/Queues/index.html:56
+msgid "Enabled Queues"
+msgstr "Colas habilitadas"
+       
+#: html/Admin/Elements/EditCustomField:90 html/Admin/Groups/Modify.html:117 html/Admin/Queues/Modify.html:138 html/Admin/Users/Modify.html:283 html/User/Groups/Modify.html:117
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr "Estado %1 habilitado"
+
+#: lib/RT/CustomField_Overlay.pm:361
+msgid "Enter multiple values"
+msgstr "Introducir multiples valores"
+
+#: lib/RT/CustomField_Overlay.pm:358
+msgid "Enter one value"
+msgstr "Introducir un valor"
+
+#: html/Ticket/Elements/EditLinks:112
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "Ingrese los números de ticket o las URL que llevan hacia el ticket. Separe multiples entradas con espacios"
+
+#: html/Elements/Login:29 html/SelfService/Error.html:25 html/SelfService/Error.html:26
+msgid "Error"
+msgstr "Error"
+
+#: NOT FOUND IN SOURCE
+msgid "Error adding watcher"
+msgstr "Error añadiendo observador"
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr "Error en los parámetros para Queue->AddWatcher"
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr "Error en los parámetros para Queue->DelWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1356
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr "Error en los parámetros para Queue->AddWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1532
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr "Error en los parámetros para Queue->DelWatcher"
+
+#: etc/initialdata:20
+msgid "Everyone"
+msgstr "Todos"
+
+#: bin/rt-crontool:194
+msgid "Example:"
+msgstr "Ejemplo"
+
+#: html/Admin/Elements/ModifyUser:64
+msgid "ExternalAuthId"
+msgstr "ExternalAuthId"
+
+#: html/Admin/Elements/ModifyUser:58
+msgid "ExternalContactInfoId"
+msgstr "ExternalContactInfoId"
+
+#: html/Admin/Users/Modify.html:73
+msgid "Extra info"
+msgstr "Información extra"
+
+#: lib/RT/User_Overlay.pm:302
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr "Problema para encontrar el pseudogrupo de usuarios 'Privileged'"
+
+#: lib/RT/User_Overlay.pm:309
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr "Problema para encontrar el pseudogrupo de usuarios 'Unprivileged'"
+
+#: bin/rt-crontool:138
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr "Error al cargar el modulo %1. (%2)"
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "Feb."
+
+#: NOT FOUND IN SOURCE
+msgid "February"
+msgstr "Febrero"
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr "Fin"
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:59 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "Prioridad Final"
+
+#: lib/RT/Ticket_Overlay.pm:1162
+msgid "FinalPriority"
+msgstr "FinalPriority"
+
+#: html/Admin/Queues/People.html:61 html/Ticket/Elements/EditPeople:34
+msgid "Find group whose"
+msgstr "Encontrar grupo que"
+
+#: html/Elements/Quicksearch:25
+msgid "Find new/open tickets"
+msgstr "Encontrar tickets nuevos/abiertos"
+
+#: html/Admin/Queues/People.html:57 html/Admin/Users/index.html:46 html/Ticket/Elements/EditPeople:30
+msgid "Find people whose"
+msgstr "Encontrar gente que"
+
+#: html/Search/Listing.html:108
+msgid "Find tickets"
+msgstr "Encontrar tickets"
+
+#: NOT FOUND IN SOURCE
+msgid "Finish Approval"
+msgstr "Aprobacion final"
+
+#: html/Ticket/Elements/Tabs:58
+msgid "First"
+msgstr "Primero"
+
+#: html/Search/Listing.html:41
+msgid "First page"
+msgstr "Primera página"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr "Foo Bar Baz"
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr "Foo!"
+
+#: html/Search/Bulk.html:87
+msgid "Force change"
+msgstr "Forzar cambio"
+
+#: html/Search/Listing.html:106
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr "Encontrado %quant(%1,ticket)"
+
+#: lib/RT/Interface/Web.pm:868
+msgid "Found Object"
+msgstr "Objeto encontrado"
+
+#: html/Admin/Elements/ModifyUser:44
+msgid "FreeformContactInfo"
+msgstr "FreeformContactInfo"
+
+#: lib/RT/CustomField_Overlay.pm:38
+msgid "FreeformMultiple"
+msgstr "FreeformMultiple"
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformSingle"
+msgstr "FreeformSingle"
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "Vie."
+
+#: html/Ticket/Elements/ShowHistory:41 html/Ticket/Elements/ShowHistory:51
+msgid "Full headers"
+msgstr "Encabezados completos"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr "Obteniendo el usuario de la firma pgp"
+
+#: lib/RT/Transaction_Overlay.pm:595
+#. ($New->Name)
+msgid "Given to %1"
+msgstr "Given to %1"
+
+#: html/Admin/Elements/Tabs:41 html/Admin/index.html:38
+msgid "Global"
+msgstr "Global"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Keyword Selections"
+msgstr "Seleccion de palabras clave globales"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr "Acciones Globales"
+
+#: html/Admin/Elements/SelectTemplate:38
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr "Plantilla global"
+
+#: html/Admin/Elements/EditCustomFields:75 html/Admin/Queues/People.html:59 html/Admin/Queues/People.html:63 html/Admin/Queues/index.html:44 html/Admin/Users/index.html:49 html/Ticket/Elements/EditPeople:32 html/Ticket/Elements/EditPeople:36 html/index.html:41
+msgid "Go!"
+msgstr " Ir "
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr "Firma pgp correcta de %1\\n"
+
+#: html/Search/Listing.html:50
+msgid "Goto page"
+msgstr "Ir a página"
+
+#: html/Elements/GotoTicket:25 html/SelfService/Elements/GotoTicket:25
+msgid "Goto ticket"
+msgstr "Ir a ticket"
+
+#: html/Ticket/Elements/AddWatchers:46 html/User/Elements/DelegateRights:78
+msgid "Group"
+msgstr "Grupo"
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr "Grupo %1 %2: %3"
+
+#: html/Admin/Elements/GroupTabs:45 html/Admin/Elements/QueueTabs:57 html/Admin/Elements/SystemTabs:44 html/Admin/Global/index.html:55
+msgid "Group Rights"
+msgstr "Derechos del grupo"
+
+#: lib/RT/Group_Overlay.pm:965
+msgid "Group already has member"
+msgstr "El grupo ya tiene miembros"
+
+#: NOT FOUND IN SOURCE
+msgid "Group could not be created."
+msgstr "El grupo no se pudo crear"
+
+#: html/Admin/Groups/Modify.html:77
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr "El grupo no se pudo crear: %1"
+
+#: lib/RT/Group_Overlay.pm:497
+msgid "Group created"
+msgstr "Grupo creado"
+
+#: lib/RT/Group_Overlay.pm:1133
+msgid "Group has no such member"
+msgstr "El grupo no tiene este miembro"
+
+#: lib/RT/Group_Overlay.pm:945 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1429 lib/RT/Ticket_Overlay.pm:1507
+msgid "Group not found"
+msgstr "Grupo no encontrado"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr "Grupo no entontrado\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr "Grupo no especificado\\n"
+
+#: html/Admin/Elements/SelectNewGroupMembers:35 html/Admin/Elements/Tabs:35 html/Admin/Groups/Members.html:64 html/Admin/Queues/People.html:83 html/Admin/index.html:32 html/User/Groups/Members.html:67
+msgid "Groups"
+msgstr "Grupos"
+
+#: lib/RT/Group_Overlay.pm:971
+msgid "Groups can't be members of their members"
+msgstr "Los grupos no pueden ser miembros de sus propios miembros"
+
+#: lib/RT/Interface/CLI.pm:73 lib/RT/Interface/CLI.pm:73
+msgid "Hello!"
+msgstr "Hola!"
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr "Hola, %1"
+
+#: html/Ticket/Elements/ShowHistory:30 html/Ticket/Elements/Tabs:88
+msgid "History"
+msgstr "Historial"
+
+#: html/Admin/Elements/ModifyUser:68
+msgid "HomePhone"
+msgstr "Tel Casa"
+
+#: html/Elements/Tabs:46
+msgid "Homepage"
+msgstr "Inicio"
+
+#: lib/RT/Base.pm:74
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr "Tengo %quant(%1,concrete mixer)."
+
+#: NOT FOUND IN SOURCE
+msgid "I have [quant,_1,concrete mixer]."
+msgstr "Tengo [quant,_1,concrete mixer]."
+
+#: html/Ticket/Elements/ShowBasics:27 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr "Id"
+
+#: html/Admin/Users/Modify.html:44 html/User/Prefs.html:39
+msgid "Identity"
+msgstr "Identidad"
+
+#: etc/upgrade/2.1.71:86
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr "Si una aprobacion es rechazada, rechazar la original y borrar las aprobaciones pendientes"
+
+#: bin/rt-crontool:190
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr "Si esta herramienta estaba setgid, un usuario hostil local podria usar esta herramienta para conseguir acceso administrativo a RT."
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "If you've updated anything above, be sure to"
+msgstr "Si ha actualizado algo más arriba, no olvide"
+
+#: lib/RT/Interface/Web.pm:860
+msgid "Illegal value for %1"
+msgstr "Valor ilegal para %1"
+
+#: lib/RT/Interface/Web.pm:863
+msgid "Immutable field"
+msgstr "Campo inmutable"
+
+#: html/Admin/Elements/EditCustomFields:74
+msgid "Include disabled custom fields in listing."
+msgstr "Incluir campos personalizables deshabilitados en el listado."
+
+#: html/Admin/Queues/index.html:43
+msgid "Include disabled queues in listing."
+msgstr "Incluir colas deshabilitadas en el listado"
+
+#: html/Admin/Users/index.html:47
+msgid "Include disabled users in search."
+msgstr "Incluir usuarios deshabilitados en la búsqueda"
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr "Prioridad inicial"
+
+#: lib/RT/Ticket_Overlay.pm:1161 lib/RT/Ticket_Overlay.pm:1163
+msgid "InitialPriority"
+msgstr "InitialPriority"
+
+#: lib/RT/ScripAction_Overlay.pm:105
+msgid "Input error"
+msgstr "Error de entrada"
+
+#: NOT FOUND IN SOURCE
+msgid "Interest noted"
+msgstr "Interest noted"
+
+#: lib/RT/Ticket_Overlay.pm:3729
+msgid "Internal Error"
+msgstr "Error interno"
+
+#: lib/RT/Record.pm:143
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr "Error interno: %1"
+
+#: lib/RT/Group_Overlay.pm:644
+msgid "Invalid Group Type"
+msgstr "Tipo de grupo inválido"
+
+#: lib/RT/Principal_Overlay.pm:128
+msgid "Invalid Right"
+msgstr "Derechos inválidos"
+
+#: NOT FOUND IN SOURCE
+msgid "Invalid Type"
+msgstr "Tipo inválido"
+
+#: lib/RT/Interface/Web.pm:865
+msgid "Invalid data"
+msgstr "Datos no válidos"
+
+#: lib/RT/Ticket_Overlay.pm:438
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr "Propietario inválido. Estableciéndolo a 'nobody'."
+
+#: lib/RT/Scrip_Overlay.pm:134 lib/RT/Template_Overlay.pm:251
+msgid "Invalid queue"
+msgstr "Área inválida"
+
+#: lib/RT/ACE_Overlay.pm:244 lib/RT/ACE_Overlay.pm:253 lib/RT/ACE_Overlay.pm:259 lib/RT/ACE_Overlay.pm:270 lib/RT/ACE_Overlay.pm:275
+msgid "Invalid right"
+msgstr "Permiso inválido"
+
+#: lib/RT/Record.pm:118
+#. ($key)
+msgid "Invalid value for %1"
+msgstr "Valor inválido para %1"
+
+#: lib/RT/Ticket_Overlay.pm:3367
+msgid "Invalid value for custom field"
+msgstr "Valor inválido para el campo personalizable"
+
+#: lib/RT/Ticket_Overlay.pm:345
+msgid "Invalid value for status"
+msgstr "Valor inválido para el estado"
+
+#: bin/rt-crontool:191
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr "Es increiblemente importante que los usuarios sin privilegios no puedan ejecutar esta herramienta"
+
+#: bin/rt-crontool:192
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr "Es recomendable crear un usuario unix sin privilegios que pertenezca al grupo correcto y que tenga aceso a ejecutar esta herramienta"
+
+#: bin/rt-crontool:163
+msgid "It takes several arguments:"
+msgstr "Tiene varios parametros:"
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr "Items pendientes de mi aprobación"
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "Ene."
+
+#: NOT FOUND IN SOURCE
+msgid "January"
+msgstr "Enero"
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "Join or leave this group"
+msgstr "Unirse o abandonar este grupo"
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "Jul."
+
+#: NOT FOUND IN SOURCE
+msgid "July"
+msgstr "Julio"
+
+#: html/Ticket/Elements/Tabs:99
+msgid "Jumbo"
+msgstr "Todo"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "Jun."
+
+#: NOT FOUND IN SOURCE
+msgid "June"
+msgstr "Junio"
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr "Palabras clave"
+
+#: html/Admin/Elements/ModifyUser:52
+msgid "Lang"
+msgstr "Leng"
+
+#: html/Ticket/Elements/Tabs:73
+msgid "Last"
+msgstr "Último"
+
+#: html/Ticket/Elements/EditDates:38 html/Ticket/Elements/ShowDates:39
+msgid "Last Contact"
+msgstr "Último contacto"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Contacted"
+msgstr "Último contactado"
+
+#: html/Search/Elements/TicketHeader:41
+msgid "Last Notified"
+msgstr "Se le notifico por ultima vez"
+
+#: html/Elements/SelectDateType:30
+msgid "Last Updated"
+msgstr "Actualizado por ultima vez"
+
+#: NOT FOUND IN SOURCE
+msgid "LastUpdated"
+msgstr "LastUpdated"
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr "Izquierda"
+
+#: html/Admin/Users/Modify.html:83
+msgid "Let this user access RT"
+msgstr "Permitir a este usuario acceder al RT"
+
+#: html/Admin/Users/Modify.html:87
+msgid "Let this user be granted rights"
+msgstr "Permitir que este usuario tenga privilegios adicionales"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr "Limitando propietario a %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr "Limitando cola a %1 %2"
+
+#: lib/RT/Ticket_Overlay.pm:2697
+msgid "Link already exists"
+msgstr "El vínculo ya existe"
+
+#: lib/RT/Ticket_Overlay.pm:2709
+msgid "Link could not be created"
+msgstr "El vínculo no pudo ser creado"
+
+#: lib/RT/Ticket_Overlay.pm:2717 lib/RT/Ticket_Overlay.pm:2727
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr "Vínculo creado (%2)"
+
+#: lib/RT/Ticket_Overlay.pm:2638
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr "Vínculo borrado (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2644
+msgid "Link not found"
+msgstr "Vínculo no encontrado"
+
+#: html/Ticket/ModifyLinks.html:25 html/Ticket/ModifyLinks.html:29
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr "Vincular caso #%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Link ticket %1"
+msgstr "Enlazar ticket %1"
+
+#: html/Ticket/Elements/Tabs:97
+msgid "Links"
+msgstr "Enlaces"
+
+#: html/Admin/Users/Modify.html:114 html/User/Prefs.html:85
+msgid "Location"
+msgstr "Direccion"
+
+#: lib/RT.pm:158
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr "El directorio del log %1 no pudo ser encontrado o no se pudo escribir en él.\\n RT no puede ejecutarse."
+
+#: html/Elements/Header:57
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "Autenticado como %1"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:25 html/Elements/Login:34 html/Elements/Login:45
+msgid "Login"
+msgstr "Entrar"
+
+#: html/Elements/Header:54
+msgid "Logout"
+msgstr "Salir"
+
+#: html/Search/Bulk.html:86
+msgid "Make Owner"
+msgstr "Hacer propietario a"
+
+#: html/Search/Bulk.html:102
+msgid "Make Status"
+msgstr "Establecer estatus"
+
+#: html/Search/Bulk.html:109
+msgid "Make date Due"
+msgstr "Establecer fecha de plazo"
+
+#: html/Search/Bulk.html:110
+msgid "Make date Resolved"
+msgstr "Establecer fecha de resolución"
+
+#: html/Search/Bulk.html:107
+msgid "Make date Started"
+msgstr "Establecer fecha de inicio"
+
+#: html/Search/Bulk.html:106
+msgid "Make date Starts"
+msgstr "Establecer fecha de inicio"
+
+#: html/Search/Bulk.html:108
+msgid "Make date Told"
+msgstr "Establecer fecha de último cambio"
+
+#: html/Search/Bulk.html:99
+msgid "Make priority"
+msgstr "Establecer prioridad"
+
+#: html/Search/Bulk.html:100
+msgid "Make queue"
+msgstr "Establecer cola"
+
+#: html/Search/Bulk.html:98
+msgid "Make subject"
+msgstr "Establecer título"
+
+#: html/Admin/index.html:33
+msgid "Manage groups and group membership"
+msgstr "Administrar grupos y miembros"
+
+#: html/Admin/index.html:39
+msgid "Manage properties and configuration which apply to all queues"
+msgstr "Administrar propiedades y configuracion que se aplique a todas las colas"
+
+#: html/Admin/index.html:36
+msgid "Manage queues and queue-specific properties"
+msgstr "Administrar colas y propiedades especificas"
+
+#: html/Admin/index.html:30
+msgid "Manage users and passwords"
+msgstr "Administrar usuarios y contraseñas"
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "Mar."
+
+#: NOT FOUND IN SOURCE
+msgid "March"
+msgstr "Marzo"
+
+#: NOT FOUND IN SOURCE
+msgid "May"
+msgstr "Mayo"
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "May."
+
+#: lib/RT/Group_Overlay.pm:982
+msgid "Member added"
+msgstr "Miembro añadido"
+
+#: lib/RT/Group_Overlay.pm:1140
+msgid "Member deleted"
+msgstr "Miembro borrado"
+
+#: lib/RT/Group_Overlay.pm:1144
+msgid "Member not deleted"
+msgstr "Miembro no borrado"
+
+#: html/Elements/SelectLinkType:26
+msgid "Member of"
+msgstr "Miembro de"
+
+#: NOT FOUND IN SOURCE
+msgid "MemberOf"
+msgstr "MemberOf"
+
+#: html/Admin/Elements/GroupTabs:42 html/User/Elements/GroupTabs:42
+msgid "Members"
+msgstr "Miembros"
+
+#: lib/RT/Ticket_Overlay.pm:2843
+msgid "Merge Successful"
+msgstr "Fusión exitosa"
+
+#: lib/RT/Ticket_Overlay.pm:2804
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "Fusión fallida. No se pudo establecer el EffectiveId"
+
+#: html/Ticket/Elements/EditLinks:115
+msgid "Merge into"
+msgstr "Fusionar dentro de"
+
+#: html/Ticket/Update.html:102
+msgid "Message"
+msgstr "Mensaje"
+
+#: lib/RT/Interface/Web.pm:867
+msgid "Missing a primary key?: %1"
+msgstr "Falta una clave primaria?: %1"
+
+#: html/Admin/Users/Modify.html:169 html/User/Prefs.html:54
+msgid "Mobile"
+msgstr "Movil"
+
+#: html/Admin/Elements/ModifyUser:72
+msgid "MobilePhone"
+msgstr "Telefono Movil"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify Access Control List"
+msgstr "Modificar lista de control de acceso"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Custom Field %1"
+msgstr "Modificar el campo personalizable %1"
+
+#: html/Admin/Global/CustomFields.html:44 html/Admin/Global/index.html:51
+msgid "Modify Custom Fields which apply to all queues"
+msgstr "Modificar los campos personalizables que se apliquen a todas las colas"
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "Modify Scrip templates for this queue"
+msgstr "Modificar plantillas Sript para esta cola"
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "Modify Scrips for this queue"
+msgstr "Modificar Scrips para esta cola"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify System ACLS"
+msgstr "Modificar ACLs de sistema"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr "Modificar plantilla %1"
+
+#: html/Admin/Queues/CustomField.html:45
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr "Modificar un campo personalizable para la cola %1"
+
+#: html/Admin/Global/CustomField.html:53
+msgid "Modify a CustomField which applies to all queues"
+msgstr "Modificar un campo personalizable que se aplique a todas las colas"
+
+#: html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr "Modificar un scrip para la cola %1"
+
+#: html/Admin/Global/Scrip.html:48
+msgid "Modify a scrip which applies to all queues"
+msgstr "Modificar un scrip que se aplique a todas las colas"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify dates for # %1"
+msgstr "Modificar fechas para # %1"
+
+#: html/Ticket/ModifyDates.html:25 html/Ticket/ModifyDates.html:29
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr "Modificar fechas para #%1"
+
+#: html/Ticket/ModifyDates.html:35
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr "Modificar fechas para ticket # %1"
+
+#: html/Admin/Global/GroupRights.html:25 html/Admin/Global/GroupRights.html:28 html/Admin/Global/index.html:56
+msgid "Modify global group rights"
+msgstr "Modificar privilegios globales de grupo"
+
+#: html/Admin/Global/GroupRights.html:33
+msgid "Modify global group rights."
+msgstr "Modificar privilegios globales de grupo."
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for groups"
+msgstr "Modificar privilegios globales para grupos"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for users"
+msgstr "Modificar privilegios globales para usuarios"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr "Modificar acciones globales"
+
+#: html/Admin/Global/UserRights.html:25 html/Admin/Global/UserRights.html:28 html/Admin/Global/index.html:60
+msgid "Modify global user rights"
+msgstr "Modificar derechos globales de usuario"
+
+#: html/Admin/Global/UserRights.html:33
+msgid "Modify global user rights."
+msgstr "Modificar privilegios globales de usuario"
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "Modify group metadata or delete group"
+msgstr "Modificar metadatos del grupo o borrar grupo"
+
+#: html/Admin/Groups/GroupRights.html:25 html/Admin/Groups/GroupRights.html:29 html/Admin/Groups/GroupRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr "Modificar privilegios de grupo para %1"
+
+#: html/Admin/Queues/GroupRights.html:25 html/Admin/Queues/GroupRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr "Modificar privilegios de grupo para la cola %1"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Modify membership roster for this group"
+msgstr "Modificar miembros de este grupo"
+
+#: lib/RT/System.pm:61
+msgid "Modify one's own RT account"
+msgstr "Modificar la propia cuenta RT"
+
+#: html/Admin/Queues/People.html:25 html/Admin/Queues/People.html:29
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr "Modificar personas relacionadas al cola %1"
+
+#: html/Ticket/ModifyPeople.html:25 html/Ticket/ModifyPeople.html:29 html/Ticket/ModifyPeople.html:35
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr "Modificar personas relacionadas al ticket #%1"
+
+#: html/Admin/Queues/Scrips.html:44
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr "Modificar acciones para la cola %1"
+
+#: html/Admin/Global/Scrips.html:44 html/Admin/Global/index.html:42
+msgid "Modify scrips which apply to all queues"
+msgstr "Modificar scrips que se aplican a todas las colas"
+
+#: html/Admin/Global/Template.html:25 html/Admin/Global/Template.html:30 html/Admin/Global/Template.html:81 html/Admin/Queues/Template.html:78
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr "Modificar plantilla %1"
+
+#: html/Admin/Global/Templates.html:44
+msgid "Modify templates which apply to all queues"
+msgstr "Modificar plantillas que se aplican a todas las colas"
+
+#: html/Admin/Groups/Modify.html:87 html/User/Groups/Modify.html:86
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr "Modificar el grupo %1"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Modify the queue watchers"
+msgstr "Modificar los observadores de la cola"
+
+#: html/Admin/Users/Modify.html:236
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr "Modificar el usuario %1"
+
+#: html/Ticket/ModifyAll.html:37
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "Modificar el ticket # %1"
+
+#: html/Ticket/Modify.html:25 html/Ticket/Modify.html:28 html/Ticket/Modify.html:34
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "Modificar el ticket #%1"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Modify tickets"
+msgstr "Modificar tickets"
+
+#: html/Admin/Groups/UserRights.html:25 html/Admin/Groups/UserRights.html:29 html/Admin/Groups/UserRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr "Modificar privilegios de usuario para el grupo %1"
+
+#: html/Admin/Queues/UserRights.html:25 html/Admin/Queues/UserRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr "Modificar derechos de usuario para la cola %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr "Modificar observadores para la cola '%1'"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyACL"
+msgstr "ModifyACL"
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "ModifyOwnMembership"
+msgstr "ModifyOwnMembership"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "ModifyQueueWatchers"
+msgstr "ModifyQueueWatchers"
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "ModifyScrips"
+msgstr "ModifyScrips"
+
+#: lib/RT/System.pm:61
+msgid "ModifySelf"
+msgstr "ModifySelf"
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "ModifyTemplate"
+msgstr "ModifyTemplate"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "ModifyTicket"
+msgstr "ModifyTicket"
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "Lun."
+
+#: html/Ticket/Elements/ShowRequestor:42
+#. ($name)
+msgid "More about %1"
+msgstr "Más acerca de %1"
+
+#: html/Admin/Elements/EditCustomFields:61
+msgid "Move down"
+msgstr "Mover hacia abajo"
+
+#: html/Admin/Elements/EditCustomFields:53
+msgid "Move up"
+msgstr "Move hacia arriba"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:27
+msgid "Multiple"
+msgstr "Múltiple"
+
+#: lib/RT/User_Overlay.pm:179
+msgid "Must specify 'Name' attribute"
+msgstr "Se debe especificar un nombre"
+
+#: NOT FOUND IN SOURCE
+msgid "My Approvals"
+msgstr "Mis aprobaciones"
+
+#: html/Approvals/index.html:25 html/Approvals/index.html:26
+msgid "My approvals"
+msgstr "Mis aprobaciones"
+
+#: html/Admin/Elements/AddCustomFieldValue:26 html/Admin/Elements/EditCustomField:32 html/Admin/Elements/ModifyTemplate:28 html/Admin/Elements/ModifyUser:30 html/Admin/Groups/Modify.html:44 html/Elements/SelectGroups:26 html/Elements/SelectUsers:28 html/User/Groups/Modify.html:44
+msgid "Name"
+msgstr "Nombre"
+
+#: lib/RT/User_Overlay.pm:186
+msgid "Name in use"
+msgstr "Nombre en uso"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr "Se necesita aprobacion del administrador del sistema"
+
+#: html/Ticket/Elements/ShowDates:52
+msgid "Never"
+msgstr "Nunca"
+
+#: html/Elements/Quicksearch:30
+msgid "New"
+msgstr "Nuevo"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:93 html/User/Prefs.html:65
+msgid "New Password"
+msgstr "Nueva contraseñaa"
+
+#: etc/initialdata:311 etc/upgrade/2.1.71:16
+msgid "New Pending Approval"
+msgstr "Nueva pendiente de aprobación"
+
+#: html/Ticket/Elements/EditLinks:111
+msgid "New Relationships"
+msgstr "Nuevas relaciones"
+
+#: html/Ticket/Elements/Tabs:36
+msgid "New Search"
+msgstr "Nueva búsqueda"
+
+#: html/Admin/Global/CustomField.html:41 html/Admin/Global/CustomFields.html:39 html/Admin/Queues/CustomField.html:52 html/Admin/Queues/CustomFields.html:40
+msgid "New custom field"
+msgstr "Nuevo campo personalizable"
+
+#: html/Admin/Elements/GroupTabs:54 html/User/Elements/GroupTabs:52
+msgid "New group"
+msgstr "Nuevo grupo"
+
+#: html/SelfService/Prefs.html:32
+msgid "New password"
+msgstr "Nueva contraseñaa"
+
+#: lib/RT/User_Overlay.pm:639
+msgid "New password notification sent"
+msgstr "Notificación de nueva contraseña enviada"
+
+#: html/Admin/Elements/QueueTabs:70
+msgid "New queue"
+msgstr "Nueva cola"
+
+#: html/SelfService/Elements/Tabs:63
+msgid "New request"
+msgstr "Nueva solicitud"
+
+#: html/Admin/Elements/SelectRights:42
+msgid "New rights"
+msgstr "Nuevos privilegios"
+
+#: html/Admin/Global/Scrip.html:40 html/Admin/Global/Scrips.html:39 html/Admin/Queues/Scrip.html:43 html/Admin/Queues/Scrips.html:53
+msgid "New scrip"
+msgstr "Nuevo scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "New search"
+msgstr "Nueva búsqueda"
+
+#: html/Admin/Global/Template.html:60 html/Admin/Global/Templates.html:39 html/Admin/Queues/Template.html:58 html/Admin/Queues/Templates.html:46
+msgid "New template"
+msgstr "Nueva plantilla"
+
+#: lib/RT/Ticket_Overlay.pm:2771
+msgid "New ticket doesn't exist"
+msgstr "El ticket nuevo no existe"
+
+#: html/Admin/Elements/UserTabs:52
+msgid "New user"
+msgstr "Nuevo usuario"
+
+#: html/Admin/Elements/CreateUserCalled:26
+msgid "New user called"
+msgstr "Nuevo usuario llamado"
+
+#: html/Admin/Queues/People.html:55 html/Ticket/Elements/EditPeople:29
+msgid "New watchers"
+msgstr "Nuevo observador"
+
+#: html/Admin/Users/Prefs.html:42
+msgid "New window setting"
+msgstr "Establecer nueva ventana "
+
+#: html/Ticket/Elements/Tabs:69
+msgid "Next"
+msgstr "Siguiente"
+
+#: html/Search/Listing.html:48
+msgid "Next page"
+msgstr "Siguiente página"
+
+#: html/Admin/Elements/ModifyUser:50
+msgid "NickName"
+msgstr "Alias"
+
+#: html/Admin/Users/Modify.html:63 html/User/Prefs.html:46
+msgid "Nickname"
+msgstr "Alias"
+
+#: html/Admin/Elements/EditCustomField:73 html/Admin/Elements/EditCustomFields:105
+msgid "No CustomField"
+msgstr "No hay campo personalizable"
+
+#: html/Admin/Groups/GroupRights.html:84 html/Admin/Groups/UserRights.html:71
+msgid "No Group defined"
+msgstr "No hay grupo definido"
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:68
+msgid "No Queue defined"
+msgstr "No hay cola definida"
+
+#: bin/rt-crontool:56
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr "No se encontró el usuario. Por favor consulte al administrador.\\n"
+
+#: html/Admin/Global/Template.html:79 html/Admin/Queues/Template.html:76
+msgid "No Template"
+msgstr "No hay plantilla"
+
+#: bin/rt-commit-handler:764
+msgid "No Ticket specified. Aborting ticket "
+msgstr "No se especificó el ticket. Abortada la transacción"
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr "No se especificó ticket. Abortando las modificaciones al ticket\\n\\n"
+
+#: html/Approvals/Elements/Approve:47
+msgid "No action"
+msgstr "No action"
+
+#: lib/RT/Interface/Web.pm:862
+msgid "No column specified"
+msgstr "No se ha especificado ninguna columna"
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr "Comando no encontrado\\n"
+
+#: html/Elements/ViewUser:36 html/Ticket/Elements/ShowRequestor:45
+msgid "No comment entered about this user"
+msgstr "No hay comentarios sobre este usuario"
+
+#: lib/RT/Ticket_Overlay.pm:2189 lib/RT/Ticket_Overlay.pm:2257
+msgid "No correspondence attached"
+msgstr "No hay ningún archivo adjunto"
+
+#: lib/RT/Action/Generic.pm:150 lib/RT/Condition/Generic.pm:176 lib/RT/Search/ActiveTicketsInQueue.pm:56 lib/RT/Search/Generic.pm:113
+#. (ref $self)
+msgid "No description for %1"
+msgstr "No hay descripción para %1"
+
+#: lib/RT/Users_Overlay.pm:151
+msgid "No group specified"
+msgstr "No hay grupo especificado"
+
+#: lib/RT/User_Overlay.pm:857
+msgid "No password set"
+msgstr "No hay contraseña definida"
+
+#: lib/RT/Queue_Overlay.pm:259
+msgid "No permission to create queues"
+msgstr "No tiene privilegios para crear colas"
+
+#: lib/RT/Ticket_Overlay.pm:341
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr "No tiene privilegios para crear tickets en la cola '%1'"
+
+#: lib/RT/User_Overlay.pm:151
+msgid "No permission to create users"
+msgstr "No tiene privilegios para crear usuarios"
+
+#: html/SelfService/Display.html:174
+msgid "No permission to display that ticket"
+msgstr "No tiene privilegios para mostrar el ticket"
+
+#: html/SelfService/Update.html:55
+msgid "No permission to view update ticket"
+msgstr "Sin permiso para ver la actualización del ticket"
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1488
+msgid "No principal specified"
+msgstr "No hay un principal especificado"
+
+#: html/Admin/Queues/People.html:154 html/Admin/Queues/People.html:164
+msgid "No principals selected."
+msgstr "No hay principales seleccionados"
+
+#: html/Admin/Queues/index.html:35
+msgid "No queues matching search criteria found."
+msgstr "No hay colas que concuerden con los criterios de búsqueda"
+
+#: html/Admin/Elements/SelectRights:81
+msgid "No rights found"
+msgstr "No se encontraron derechos"
+
+#: html/Admin/Elements/SelectRights:33
+msgid "No rights granted."
+msgstr "Sin privilegios concedidos"
+
+#: html/Search/Bulk.html:149
+msgid "No search to operate on."
+msgstr "No hay búsqueda sobre la que operar"
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr "No se especificó el identificador del ticket"
+
+#: lib/RT/Transaction_Overlay.pm:480 lib/RT/Transaction_Overlay.pm:518
+msgid "No transaction type specified"
+msgstr "No se especificó el tipo de transacción"
+
+#: NOT FOUND IN SOURCE
+msgid "No user or email address specified"
+msgstr "No se especificó email o usuario"
+
+#: html/Admin/Users/index.html:36
+msgid "No users matching search criteria found."
+msgstr "No se encontraron usuarios que concuerden con los criterios de búsqueda"
+
+#: bin/rt-commit-handler:644
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr "Usuario no encontrado. El manejador cvs está deshabilitado. Por favor consulte a su administrador.\\n"
+
+#: lib/RT/Interface/Web.pm:859
+msgid "No value sent to _Set!\\n"
+msgstr "No se envió ningun valor a _Set!\\n"
+
+#: html/Search/Elements/TicketRow:37
+msgid "Nobody"
+msgstr "Nadie"
+
+#: lib/RT/Interface/Web.pm:864
+msgid "Nonexistant field?"
+msgstr "Campo no existente?"
+
+#: html/Elements/Login:99
+msgid "Not logged in"
+msgstr "No autenticado"
+
+#: html/Elements/Header:59 html/SelfService/Elements/Header:58
+msgid "Not logged in."
+msgstr "No autenticado."
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "No establecido"
+
+#: html/NoAuth/Reminder.html:27
+msgid "Not yet implemented."
+msgstr "No se ha implementado."
+
+#: html/Admin/Groups/Rights.html:25
+msgid "Not yet implemented...."
+msgstr "No está implementado..."
+
+#: html/Approvals/Elements/Approve:50
+msgid "Notes"
+msgstr "Notas"
+
+#: lib/RT/User_Overlay.pm:642
+msgid "Notification could not be sent"
+msgstr "La notificación no se pudo enviar"
+
+#: etc/initialdata:94
+msgid "Notify AdminCcs"
+msgstr "Notificar AdminCcs"
+
+#: etc/initialdata:90
+msgid "Notify AdminCcs as Comment"
+msgstr "Notificar AdminCcs como comentario"
+
+#: etc/initialdata:121
+msgid "Notify Other Recipients"
+msgstr "Notificar otros destinatarios"
+
+#: etc/initialdata:117
+msgid "Notify Other Recipients as Comment"
+msgstr "Notificar otros destinatarios como comentario"
+
+#: etc/initialdata:86
+msgid "Notify Owner"
+msgstr "Notificar al propietario"
+
+#: etc/initialdata:82
+msgid "Notify Owner as Comment"
+msgstr "Notificar al propietario como comentario"
+
+#: etc/initialdata:313 etc/upgrade/2.1.71:17
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr "Notificar propietarios y AdminCcs de nuevos items pendientes de aprobación"
+
+#: etc/initialdata:78
+msgid "Notify Requestors"
+msgstr "Notificar solicitantes"
+
+#: etc/initialdata:104
+msgid "Notify Requestors and Ccs"
+msgstr "Notificar solicitantes y Ccs"
+
+#: etc/initialdata:99
+msgid "Notify Requestors and Ccs as Comment"
+msgstr "Notificar solicitantes y Ccs como comentario"
+
+#: etc/initialdata:113
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr "Notificar solicitantes, Ccs y AdminCcs"
+
+#: etc/initialdata:109
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr "Notificar solicitantes, Ccs y AdminCcs como comentario"
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "Nov."
+
+#: NOT FOUND IN SOURCE
+msgid "November"
+msgstr "Noviembre"
+
+#: lib/RT/Record.pm:157
+msgid "Object could not be created"
+msgstr "No se pudo crear el objeto"
+
+#: lib/RT/Record.pm:176
+msgid "Object created"
+msgstr "Objeto creado"
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "Oct."
+
+#: NOT FOUND IN SOURCE
+msgid "October"
+msgstr "Octubre"
+
+#: html/Elements/SelectDateRelation:35
+msgid "On"
+msgstr "en "
+
+#: etc/initialdata:155
+msgid "On Comment"
+msgstr "Al comentar"
+
+#: etc/initialdata:148
+msgid "On Correspond"
+msgstr "On Correspond"
+
+#: etc/initialdata:137
+msgid "On Create"
+msgstr "Al crear"
+
+#: etc/initialdata:169
+msgid "On Owner Change"
+msgstr "Al cambiar de propietario"
+
+#: etc/initialdata:177
+msgid "On Queue Change"
+msgstr "Al cambiar de cola"
+
+#: etc/initialdata:183
+msgid "On Resolve"
+msgstr "Al resolver"
+
+#: etc/initialdata:161
+msgid "On Status Change"
+msgstr "Al cambiar de status"
+
+#: etc/initialdata:142
+msgid "On Transaction"
+msgstr "Al hacer transaccion"
+
+#: html/Approvals/Elements/PendingMyApproval:50
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr "Solo muestra aprobaciones para solicitudes creadas despues de %1"
+
+#: html/Approvals/Elements/PendingMyApproval:48
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr "Solo muestra aprobaciones para solicitudes creadas antes de %1"
+
+#: html/Elements/Quicksearch:31
+msgid "Open"
+msgstr "Abierto"
+
+#: html/Ticket/Elements/Tabs:136
+msgid "Open it"
+msgstr "Abrirlo"
+
+#: html/SelfService/Elements/Tabs:57
+msgid "Open requests"
+msgstr "Solicitudes abiertas"
+
+#: html/Admin/Users/Prefs.html:41
+msgid "Open tickets (from listing) in a new window"
+msgstr "Tickets abiertos (del listado) en una nueva ventana"
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in another window"
+msgstr "Tickets abiertos (del listado) en otra ventana"
+
+#: etc/initialdata:133
+msgid "Open tickets on correspondence"
+msgstr "Open tickets on correspondence"
+
+#: html/Search/Elements/PickRestriction:101
+msgid "Ordering and sorting"
+msgstr "Ordenación y clasificación"
+
+#: html/Admin/Elements/ModifyUser:46 html/Admin/Users/Modify.html:117 html/Elements/SelectUsers:29 html/User/Prefs.html:86
+msgid "Organization"
+msgstr "Organización"
+
+#: html/Approvals/Elements/Approve:34
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr "Ticket originario: #%1"
+
+#: html/Admin/Elements/ModifyQueue:55 html/Admin/Queues/Modify.html:69
+msgid "Over time, priority moves toward"
+msgstr "Pasada la fecha de gracia, la prioridad se mueve a"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Own tickets"
+msgstr "Tickets poseidos"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "OwnTicket"
+msgstr "OwnTicket"
+
+#: etc/initialdata:38 html/Elements/MyRequests:32 html/SelfService/Elements/MyRequests:30 html/Ticket/Create.html:48 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/EditPeople:44 html/Ticket/Elements/ShowPeople:27 html/Ticket/Update.html:63 lib/RT/ACE_Overlay.pm:86 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "Propietario"
+
+#: lib/RT/Ticket_Overlay.pm:3004
+#. ($OldOwnerObj->Name,  $NewOwnerObj->Name)
+msgid "Owner changed from %1 to %2"
+msgstr "Propietario cambiado de %1 a %2"
+
+#: lib/RT/Transaction_Overlay.pm:584
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr "Propietario cambiado forzosamente de %1 a %2"
+
+#: html/Search/Elements/PickRestriction:31
+msgid "Owner is"
+msgstr "El propietario es"
+
+#: html/Admin/Users/Modify.html:174 html/User/Prefs.html:56
+msgid "Pager"
+msgstr "Buscapersonas"
+
+#: html/Admin/Elements/ModifyUser:74
+msgid "PagerPhone"
+msgstr "Buscapersonas Tel."
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/EditLinks:127 html/Ticket/Elements/EditLinks:58 html/Ticket/Elements/ShowLinks:43
+msgid "Parents"
+msgstr "Padres"
+
+#: html/Elements/Login:43 html/User/Prefs.html:61
+msgid "Password"
+msgstr "Contraseñaa"
+
+#: html/NoAuth/Reminder.html:25
+msgid "Password Reminder"
+msgstr "Recordatorio de contraseña"
+
+#: lib/RT/User_Overlay.pm:168 lib/RT/User_Overlay.pm:860
+msgid "Password too short"
+msgstr "Contraseña demasiado corta"
+
+#: html/Admin/Users/Modify.html:291 html/User/Prefs.html:172
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "Contraseña: %1"
+
+#: html/Ticket/Elements/ShowSummary:43 html/Ticket/Elements/Tabs:96 html/Ticket/ModifyAll.html:51
+msgid "People"
+msgstr "Personas"
+
+#: etc/initialdata:126
+msgid "Perform a user-defined action"
+msgstr "Realizar una acion definida por el usuario"
+
+#: lib/RT/ACE_Overlay.pm:231 lib/RT/ACE_Overlay.pm:237 lib/RT/ACE_Overlay.pm:563 lib/RT/ACE_Overlay.pm:573 lib/RT/ACE_Overlay.pm:583 lib/RT/ACE_Overlay.pm:648 lib/RT/CurrentUser.pm:83 lib/RT/CurrentUser.pm:92 lib/RT/CustomField_Overlay.pm:445 lib/RT/CustomField_Overlay.pm:451 lib/RT/Group_Overlay.pm:1095 lib/RT/Group_Overlay.pm:1099 lib/RT/Group_Overlay.pm:1108 lib/RT/Group_Overlay.pm:1159 lib/RT/Group_Overlay.pm:1163 lib/RT/Group_Overlay.pm:1169 lib/RT/Group_Overlay.pm:426 lib/RT/Group_Overlay.pm:518 lib/RT/Group_Overlay.pm:596 lib/RT/Group_Overlay.pm:604 lib/RT/Group_Overlay.pm:701 lib/RT/Group_Overlay.pm:705 lib/RT/Group_Overlay.pm:711 lib/RT/Group_Overlay.pm:904 lib/RT/Group_Overlay.pm:908 lib/RT/Group_Overlay.pm:921 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:126 lib/RT/Scrip_Overlay.pm:137 lib/RT/Scrip_Overlay.pm:197 lib/RT/Scrip_Overlay.pm:430 lib/RT/Template_Overlay.pm:284 lib/RT/Template_Overlay.pm:88 lib/RT/Template_Overlay.pm:94 lib/RT/Ticket_Overlay.pm:1341 lib/RT/Ticket_Overlay.pm:1351 lib/RT/Ticket_Overlay.pm:1365 lib/RT/Ticket_Overlay.pm:1518 lib/RT/Ticket_Overlay.pm:1527 lib/RT/Ticket_Overlay.pm:1540 lib/RT/Ticket_Overlay.pm:1875 lib/RT/Ticket_Overlay.pm:2013 lib/RT/Ticket_Overlay.pm:2177 lib/RT/Ticket_Overlay.pm:2244 lib/RT/Ticket_Overlay.pm:2596 lib/RT/Ticket_Overlay.pm:2668 lib/RT/Ticket_Overlay.pm:2762 lib/RT/Ticket_Overlay.pm:2777 lib/RT/Ticket_Overlay.pm:2910 lib/RT/Ticket_Overlay.pm:3139 lib/RT/Ticket_Overlay.pm:3337 lib/RT/Ticket_Overlay.pm:3499 lib/RT/Ticket_Overlay.pm:3551 lib/RT/Ticket_Overlay.pm:3716 lib/RT/Transaction_Overlay.pm:468 lib/RT/Transaction_Overlay.pm:475 lib/RT/Transaction_Overlay.pm:504 lib/RT/Transaction_Overlay.pm:511 lib/RT/User_Overlay.pm:1334 lib/RT/User_Overlay.pm:562 lib/RT/User_Overlay.pm:597 lib/RT/User_Overlay.pm:853 lib/RT/User_Overlay.pm:941
+msgid "Permission Denied"
+msgstr "Permiso denegado"
+
+#: html/User/Elements/Tabs:35
+msgid "Personal Groups"
+msgstr "Grupos personales"
+
+#: html/User/Groups/index.html:30 html/User/Groups/index.html:40
+msgid "Personal groups"
+msgstr "Grupos personales"
+
+#: html/User/Elements/DelegateRights:37
+msgid "Personal groups:"
+msgstr "Grupos personales:"
+
+#: html/Admin/Users/Modify.html:156 html/User/Prefs.html:49
+msgid "Phone numbers"
+msgstr "Números de teléfono"
+
+#: html/Admin/Users/Rights.html:25
+msgid "Placeholder"
+msgstr "Placeholder"
+
+#: html/Elements/Header:52 html/Elements/Tabs:55 html/SelfService/Prefs.html:25 html/User/Prefs.html:25 html/User/Prefs.html:28
+msgid "Preferences"
+msgstr "Preferencias"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr "Prefs"
+
+#: lib/RT/Action/Generic.pm:160
+msgid "Prepare Stubbed"
+msgstr "Preparación cortada"
+
+#: html/Ticket/Elements/Tabs:61
+msgid "Prev"
+msgstr "Prev"
+
+#: html/Search/Listing.html:44
+msgid "Previous page"
+msgstr "Página anterior"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr "Pri"
+
+#: lib/RT/ACE_Overlay.pm:133 lib/RT/ACE_Overlay.pm:208 lib/RT/ACE_Overlay.pm:552
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr "No se encontró el principal %1"
+
+#: html/Search/Elements/PickRestriction:54 html/SelfService/Display.html:76 html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:54 html/Ticket/Elements/ShowBasics:39 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "Prioridad"
+
+#: html/Admin/Elements/ModifyQueue:51 html/Admin/Queues/Modify.html:65
+msgid "Priority starts at"
+msgstr "La prioridad empieza en"
+
+#: etc/initialdata:25
+msgid "Privileged"
+msgstr "Privilegiado"
+
+#: html/Admin/Users/Modify.html:271 html/User/Prefs.html:163
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr "Estado privilegiado: %1"
+
+#: html/Admin/Users/index.html:62
+msgid "Privileged users"
+msgstr "Usuarios privilegiados:"
+
+#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59
+msgid "Pseudogroup for internal use"
+msgstr "Pseudogrupo para uso interno"
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Elements/Quicksearch:29 html/Search/Elements/PickRestriction:46 html/SelfService/Create.html:35 html/SelfService/Display.html:68 html/Ticket/Create.html:38 html/Ticket/Elements/EditBasics:64 html/Ticket/Elements/ShowBasics:43 html/User/Elements/DelegateRights:80 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "Cola"
+
+#: html/Admin/Queues/CustomField.html:42 html/Admin/Queues/Scrip.html:50 html/Admin/Queues/Scrips.html:46 html/Admin/Queues/Templates.html:43
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr "Cola %1 no encontrada"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr "Cola '%1' no encontrada\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Keyword Selections"
+msgstr "Selecciones de palabras clave de la cola"
+
+#: html/Admin/Elements/ModifyQueue:31 html/Admin/Queues/Modify.html:43
+msgid "Queue Name"
+msgstr "Nombre de la cola"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr "Acciones de la cola"
+
+#: lib/RT/Queue_Overlay.pm:263
+msgid "Queue already exists"
+msgstr "La cola ya existe"
+
+#: lib/RT/Queue_Overlay.pm:272 lib/RT/Queue_Overlay.pm:278
+msgid "Queue could not be created"
+msgstr "La cola no se pudo crear"
+
+#: html/Ticket/Create.html:209
+msgid "Queue could not be loaded."
+msgstr "La cola no se pudo cargar"
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:282
+msgid "Queue created"
+msgstr "Cola creada"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue is not specified."
+msgstr "No se especifico ninguna cola"
+
+#: html/SelfService/Display.html:129
+msgid "Queue not found"
+msgstr "Cola no encontrada"
+
+#: html/Admin/Elements/Tabs:38 html/Admin/index.html:35
+msgid "Queues"
+msgstr "Colas"
+
+#: html/Elements/Login:34
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr "RT %1"
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr "RT %1 para %2"
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr "RT %1 de <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1. Derechos reservados 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: html/Admin/index.html:25 html/Admin/index.html:26
+msgid "RT Administration"
+msgstr "Administración del RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr "Error de autenticación en RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr "Rechazo del RT: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr "Error de configuración del RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr "Error crítico en RT. El mensaje no fue grabado!"
+
+#: html/Elements/Error:41 html/SelfService/Error.html:41
+msgid "RT Error"
+msgstr "Error del RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr "RT recibió correo (%1) de sí mismo."
+
+#: NOT FOUND IN SOURCE
+msgid "RT Recieved mail (%1) from itself."
+msgstr "RT recibió correo (%1) de sí mismo."
+
+#: html/SelfService/Closed.html:25
+msgid "RT Self Service / Closed Tickets"
+msgstr "RT AutoServicio / Tickets cerrados"
+
+#: html/index.html:25 html/index.html:28
+msgid "RT at a glance"
+msgstr "RT en un vistazo"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr "RT no te pudo autenticar."
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr "RT no pudo encontrar el solicitante a través de una busqueda a la base de datos externa"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr "RT no pudo encontrar la cola: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr "RT no pudo validar esta firma PGP. \\n"
+
+#: html/Elements/PageLayout:26
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr "RT para %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr "RT para %1: %2"
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr "RT ha procesado tus comandos"
+
+#: html/Elements/Login:83
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT es &copy; Copyright 1996-%1 de Jesse Vincent &lt;jesse@bestpractical.com&gt;.  Es distrbuido bajo <a href=\"http://www.gnu.org/copyleft/gpl.html\">la version 2 de la licencia GNU GPL (General Public License)</a>."
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr "RT cree que este mensaje puede ser un mensaje rebotado"
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr "RT procesará este mensaje como si fuera uno no firmado\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr "El modo de comandos por correo de RT requiere autenticación PGP. Ya sea que no haya firmado su mensaje, o que su firma no pueda ser verificada."
+
+#: html/Admin/Users/Modify.html:58 html/Admin/Users/Prefs.html:52 html/User/Prefs.html:44
+msgid "Real Name"
+msgstr "Nombre real"
+
+#: html/Admin/Elements/ModifyUser:48
+msgid "RealName"
+msgstr "Nombre real"
+
+#: html/Ticket/Create.html:185 html/Ticket/Elements/EditLinks:139 html/Ticket/Elements/EditLinks:94 html/Ticket/Elements/ShowLinks:63
+msgid "Referred to by"
+msgstr "Referenciado por"
+
+#: html/Elements/SelectLinkType:28 html/Ticket/Create.html:184 html/Ticket/Elements/EditLinks:135 html/Ticket/Elements/EditLinks:80 html/Ticket/Elements/ShowLinks:55
+msgid "Refers to"
+msgstr "Hace referencia a"
+
+#: NOT FOUND IN SOURCE
+msgid "RefersTo"
+msgstr "RefersTo"
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr "Refinar"
+
+#: html/Search/Elements/PickRestriction:27
+msgid "Refine search"
+msgstr "Refinar la búsqueda"
+
+#: html/Elements/Refresh:36
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "Refrescar esta página cada %1 minutos"
+
+#: html/Ticket/Create.html:174 html/Ticket/Elements/ShowSummary:60 html/Ticket/ModifyAll.html:57
+msgid "Relationships"
+msgstr "Relaciones"
+
+#: html/Search/Bulk.html:93
+msgid "Remove AdminCc"
+msgstr "Quitar AdminCc"
+
+#: html/Search/Bulk.html:91
+msgid "Remove Cc"
+msgstr "Quitar Cc"
+
+#: html/Search/Bulk.html:89
+msgid "Remove Requestor"
+msgstr "Quitar solicitante"
+
+#: html/Ticket/Elements/ShowTransaction:173 html/Ticket/Elements/Tabs:122
+msgid "Reply"
+msgstr "Responder"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Reply to tickets"
+msgstr "Responder a los tickets"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "ReplyToTicket"
+msgstr "ReplyToTicket"
+
+#: etc/initialdata:44 html/Ticket/Update.html:40 lib/RT/ACE_Overlay.pm:87
+msgid "Requestor"
+msgstr "Solicitante"
+
+#: html/Search/Elements/PickRestriction:38
+msgid "Requestor email address"
+msgstr "Dirección de correo del solicitante"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr "Solicitante(s)"
+
+#: NOT FOUND IN SOURCE
+msgid "RequestorAddresses"
+msgstr "RequestorAddresses"
+
+#: html/SelfService/Create.html:43 html/SelfService/Display.html:42 html/Ticket/Create.html:56 html/Ticket/Elements/EditPeople:48 html/Ticket/Elements/ShowPeople:31
+msgid "Requestors"
+msgstr "Solicitantes"
+
+#: html/Admin/Elements/ModifyQueue:61 html/Admin/Queues/Modify.html:75
+msgid "Requests should be due in"
+msgstr "Las solicitudes entran en vencimiento en"
+
+#: html/Elements/Submit:62
+msgid "Reset"
+msgstr "Borrar"
+
+#: html/Admin/Users/Modify.html:159 html/User/Prefs.html:50
+msgid "Residence"
+msgstr "Residencia"
+
+#: html/Ticket/Elements/Tabs:132
+msgid "Resolve"
+msgstr "Resolver"
+
+#: html/Ticket/Update.html:133
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr "Resolver ticket #%1 (%2)"
+
+#: etc/initialdata:302 html/Elements/SelectDateType:28 lib/RT/Ticket_Overlay.pm:1170
+msgid "Resolved"
+msgstr "Resuelto"
+
+#: html/Search/Bulk.html:123 html/Ticket/ModifyAll.html:73 html/Ticket/Update.html:73
+msgid "Response to requestors"
+msgstr "Responder a los solicitantes"
+
+#: html/Elements/ListActions:26
+msgid "Results"
+msgstr "Resultados"
+
+#: html/Search/Elements/PickRestriction:105
+msgid "Results per page"
+msgstr "Resultados por página"
+
+#: html/Admin/Elements/ModifyUser:33 html/Admin/Users/Modify.html:100 html/User/Prefs.html:72
+msgid "Retype Password"
+msgstr "Confirmar contraseña"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr "Privilegio %1 no encontrado para %2 %3 referente a %4 (%5)\\n"
+
+#: lib/RT/ACE_Overlay.pm:613
+msgid "Right Delegated"
+msgstr "Privilegio delegado"
+
+#: lib/RT/ACE_Overlay.pm:303
+msgid "Right Granted"
+msgstr "Privilegio otorgado"
+
+#: lib/RT/ACE_Overlay.pm:161
+msgid "Right Loaded"
+msgstr "Privilegio cargado"
+
+#: lib/RT/ACE_Overlay.pm:678 lib/RT/ACE_Overlay.pm:693
+msgid "Right could not be revoked"
+msgstr "Privilegio no pudo ser revocado"
+
+#: html/User/Delegation.html:64
+msgid "Right not found"
+msgstr "Privilegio no encontrado"
+
+#: lib/RT/ACE_Overlay.pm:543 lib/RT/ACE_Overlay.pm:638
+msgid "Right not loaded."
+msgstr "Privilegio no cargado"
+
+#: lib/RT/ACE_Overlay.pm:689
+msgid "Right revoked"
+msgstr "Privilegio revocado"
+
+#: html/Admin/Elements/UserTabs:41
+msgid "Rights"
+msgstr "Privilegios"
+
+#: lib/RT/Interface/Web.pm:758
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr "No se pudieron conceder los privilegios a %1"
+
+#: lib/RT/Interface/Web.pm:791
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr "No se pudieron revocar los privilegios de %1"
+
+#: html/Admin/Global/GroupRights.html:51 html/Admin/Queues/GroupRights.html:52
+msgid "Roles"
+msgstr "Roles"
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr "RootApproval"
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "Sab."
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "Save Changes"
+msgstr "Guardar Cambios"
+
+#: html/Ticket/ModifyLinks.html:39
+msgid "Save changes"
+msgstr "Guardar cambios"
+
+#: html/Admin/Global/Scrip.html:49
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr "Scrip #%1"
+
+#: lib/RT/Scrip_Overlay.pm:176
+msgid "Scrip Created"
+msgstr "Acción creada"
+
+#: html/Admin/Elements/EditScrips:84
+msgid "Scrip deleted"
+msgstr "Acción borrada"
+
+#: html/Admin/Elements/QueueTabs:46 html/Admin/Elements/SystemTabs:33 html/Admin/Global/index.html:41
+msgid "Scrips"
+msgstr "Acciones"
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr "Acciones para %1\\n"
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr "Acciones que se aplican a todas las colas"
+
+#: html/Elements/SimpleSearch:27 html/Search/Elements/PickRestriction:126 html/Ticket/Elements/Tabs:159
+msgid "Search"
+msgstr "Búsqueda"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr "Criterios de búsqueda"
+
+#: html/Approvals/Elements/PendingMyApproval:39
+msgid "Search for approvals"
+msgstr "Buscar aprobaciones"
+
+#: bin/rt-crontool:188
+msgid "Security:"
+msgstr "Seguridad:"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "SeeQueue"
+msgstr "Ver cola"
+
+#: html/Admin/Groups/index.html:40
+msgid "Select a group"
+msgstr "Seleccione un grupo"
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr "Seleccione una cola"
+
+#: html/Admin/Users/index.html:25 html/Admin/Users/index.html:28
+msgid "Select a user"
+msgstr "Seleccione un usuario"
+
+#: html/Admin/Global/CustomField.html:38 html/Admin/Global/CustomFields.html:36
+msgid "Select custom field"
+msgstr "Seleccionar un campo personalizable"
+
+#: html/Admin/Elements/GroupTabs:52 html/User/Elements/GroupTabs:50
+msgid "Select group"
+msgstr "Seleccionar grupo"
+
+#: lib/RT/CustomField_Overlay.pm:355
+msgid "Select multiple values"
+msgstr "Seleccionar valores múltiples"
+
+#: lib/RT/CustomField_Overlay.pm:352
+msgid "Select one value"
+msgstr "Seleccionar un valor"
+
+#: html/Admin/Elements/QueueTabs:67
+msgid "Select queue"
+msgstr "Seleccionar cola"
+
+#: html/Admin/Global/Scrip.html:37 html/Admin/Global/Scrips.html:36 html/Admin/Queues/Scrip.html:40 html/Admin/Queues/Scrips.html:50
+msgid "Select scrip"
+msgstr "Seleccionar accion"
+
+#: html/Admin/Global/Template.html:57 html/Admin/Global/Templates.html:36 html/Admin/Queues/Template.html:55
+msgid "Select template"
+msgstr "Selecionar plantilla"
+
+#: html/Admin/Elements/UserTabs:49
+msgid "Select user"
+msgstr "Seleccionar usuario"
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "SelectMultiple"
+msgstr "SelectMultiple"
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectSingle"
+msgstr "SelectSingle"
+
+#: html/SelfService/index.html:25
+msgid "Self Service"
+msgstr "Autoservicio"
+
+#: etc/initialdata:114
+msgid "Send mail to all watchers"
+msgstr "Enviar mail a todos los observadores"
+
+#: etc/initialdata:110
+msgid "Send mail to all watchers as a \"comment\""
+msgstr "Enviar mail a todos los observadores como comentario"
+
+#: etc/initialdata:105
+msgid "Send mail to requestors and Ccs"
+msgstr "Enviar mail a los solicitantes y Ccs"
+
+#: etc/initialdata:100
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr "Enviar mail a los solicitantes y Ccs como comentario"
+
+#: etc/initialdata:79
+msgid "Sends a message to the requestors"
+msgstr "Envia un mesaje a los solicitantes"
+
+#: etc/initialdata:118 etc/initialdata:122
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr "Enviar mail a los Ccs y Bccs listados explicitamente"
+
+#: etc/initialdata:95
+msgid "Sends mail to the administrative Ccs"
+msgstr "Envia mail a los Ccs administrativos"
+
+#: etc/initialdata:91
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr "Envia mail a los Ccs administrativos como comentario"
+
+#: etc/initialdata:83 etc/initialdata:87
+msgid "Sends mail to the owner"
+msgstr "Enviar mail al propietario"
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "Sep."
+
+#: NOT FOUND IN SOURCE
+msgid "September"
+msgstr "Septiembre"
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr "Mostrar resultados"
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show approved requests"
+msgstr "Mostrar peticiones aprobadas"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show basics"
+msgstr "Mostrar lo básico"
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show denied requests"
+msgstr "Mostrar solicitudes denegadas"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show details"
+msgstr "Mostrar detalles"
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show pending requests"
+msgstr "Mostrar solicitudes pendientes"
+
+#: html/Approvals/Elements/PendingMyApproval:46
+msgid "Show requests awaiting other approvals"
+msgstr "Mostrar solicitudes esperando otras aprobaciones"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Show ticket private commentary"
+msgstr "Mostrar ticket en un comentario privado"
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "Show ticket summaries"
+msgstr "Mostrar resumen del ticket"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ShowACL"
+msgstr "ShowACL"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowScrips"
+msgstr "ShowScrips"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ShowTemplate"
+msgstr "ShowTemplate"
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "ShowTicket"
+msgstr "ShowTicket"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "ShowTicketComments"
+msgstr "ShowTicketComments"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr "Validarse como solicitante de ticket o ticket o cola Cc"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr "Validarse como ticket o cola AdminCc"
+
+#: html/Admin/Elements/ModifyUser:39 html/Admin/Users/Modify.html:191 html/Admin/Users/Prefs.html:32 html/SelfService/Prefs.html:37 html/User/Prefs.html:112
+msgid "Signature"
+msgstr "Firma"
+
+#: html/SelfService/Elements/Header:52
+#. ($session{'CurrentUser'}->Name)
+msgid "Signed in as %1"
+msgstr "Validado como %1"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Single"
+msgstr "Sencillo"
+
+#: html/Elements/Header:51
+msgid "Skip Menu"
+msgstr "Saltar Menu"
+
+#: html/Admin/Elements/EditCustomFieldValues:31
+msgid "Sort key"
+msgstr "Clave de ordenación"
+
+#: html/Search/Elements/PickRestriction:109
+msgid "Sort results by"
+msgstr "Ordenar resultados por"
+
+#: html/Admin/Elements/AddCustomFieldValue:25
+msgid "SortOrder"
+msgstr "Ordenamiento"
+
+#: NOT FOUND IN SOURCE
+msgid "Stalled"
+msgstr "Pendiente"
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr "Página de inicio"
+
+#: html/Elements/SelectDateType:27 html/Ticket/Elements/EditDates:32 html/Ticket/Elements/ShowDates:35
+msgid "Started"
+msgstr "Empezado"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr "La fecha de inicio '%1' no se pudo leer"
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:27 html/Ticket/Elements/ShowDates:31
+msgid "Starts"
+msgstr "Empieza"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr "Empezado por"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr "La fecha de inicio '%1' no se pudo ser leer"
+
+#: html/Admin/Elements/ModifyUser:82 html/Admin/Users/Modify.html:138 html/User/Prefs.html:94
+msgid "State"
+msgstr "Estado"
+
+#: html/Elements/MyRequests:31 html/Elements/MyTickets:31 html/Search/Elements/PickRestriction:74 html/SelfService/Display.html:59 html/SelfService/Elements/MyRequests:29 html/SelfService/Update.html:31 html/Ticket/Create.html:42 html/Ticket/Elements/EditBasics:38 html/Ticket/Elements/ShowBasics:31 html/Ticket/Update.html:60 lib/RT/Ticket_Overlay.pm:1164 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "Estado"
+
+#: etc/initialdata:288
+msgid "Status Change"
+msgstr "Cambio de status"
+
+#: lib/RT/Transaction_Overlay.pm:530
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr "Estado cambiado de %1 a %2"
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr "StatusChange"
+
+#: html/Ticket/Elements/Tabs:147
+msgid "Steal"
+msgstr "Robar"
+
+#: lib/RT/Transaction_Overlay.pm:589
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "Robado de %1"
+
+#: html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Search/Bulk.html:126 html/Search/Elements/PickRestriction:43 html/SelfService/Create.html:59 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:35 html/Ticket/Create.html:84 html/Ticket/Elements/EditBasics:28 html/Ticket/ModifyAll.html:79 html/Ticket/Update.html:77 lib/RT/Ticket_Overlay.pm:1160 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "Asunto"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:611
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr "Asunto cambiado a %1"
+
+#: html/Elements/Submit:59
+msgid "Submit"
+msgstr "Enviar"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr "Submit Workflow"
+
+#: lib/RT/Group_Overlay.pm:749
+msgid "Succeeded"
+msgstr "Completado"
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "Dom."
+
+#: lib/RT/System.pm:54
+msgid "SuperUser"
+msgstr "Superusuario"
+
+#: html/User/Elements/DelegateRights:77
+msgid "System"
+msgstr "Sistema"
+
+#: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:567 lib/RT/Interface/Web.pm:757 lib/RT/Interface/Web.pm:790
+msgid "System Error"
+msgstr "Error del sistema"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. Right not granted."
+msgstr "Error de sistema. Derecho no concedido"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. right not granted"
+msgstr "Error de sistema. Derecho no concedido"
+
+#: lib/RT/ACE_Overlay.pm:616
+msgid "System error. Right not delegated."
+msgstr "Error del sistema. Privilegio no delegado."
+
+#: lib/RT/ACE_Overlay.pm:146 lib/RT/ACE_Overlay.pm:223 lib/RT/ACE_Overlay.pm:306 lib/RT/ACE_Overlay.pm:898
+msgid "System error. Right not granted."
+msgstr "Error del sistema. Privilegio no otorgado"
+
+#: NOT FOUND IN SOURCE
+msgid "System error. Unable to grant rights."
+msgstr "Error de sistema. Incapaz de conceder permisos"
+
+#: html/Admin/Global/GroupRights.html:35 html/Admin/Groups/GroupRights.html:37 html/Admin/Queues/GroupRights.html:36
+msgid "System groups"
+msgstr "Grupos del sistema"
+
+#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53
+msgid "SystemRolegroup for internal use"
+msgstr "SystemRolegroup for internal use"
+
+#: lib/RT/CurrentUser.pm:320
+msgid "TEST_STRING"
+msgstr "TEST_STRING"
+
+#: html/Ticket/Elements/Tabs:143
+msgid "Take"
+msgstr "Coger"
+
+#: lib/RT/Transaction_Overlay.pm:575
+msgid "Taken"
+msgstr "Cogido"
+
+#: html/Admin/Elements/EditScrip:81
+msgid "Template"
+msgstr "Plantilla"
+
+#: html/Admin/Global/Template.html:91 html/Admin/Queues/Template.html:90
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr "Plantilla #%1"
+
+#: html/Admin/Elements/EditTemplates:89
+msgid "Template deleted"
+msgstr "Plantilla borrada"
+
+#: lib/RT/Scrip_Overlay.pm:153
+msgid "Template not found"
+msgstr "Plantilla no encontrada"
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr "Plantilla no encontrada\\n"
+
+#: lib/RT/Template_Overlay.pm:347
+msgid "Template parsed"
+msgstr "Plantilla procesada"
+
+#: html/Admin/Elements/QueueTabs:49 html/Admin/Elements/SystemTabs:36 html/Admin/Global/index.html:45
+msgid "Templates"
+msgstr "Plantillas"
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr "Plantillas de %1\\n"
+
+#: lib/RT/Interface/Web.pm:858
+msgid "That is already the current value"
+msgstr "Ese es el valor actual"
+
+#: lib/RT/CustomField_Overlay.pm:178
+msgid "That is not a value for this custom field"
+msgstr "Ese no es un valor para este campo personalizable"
+
+#: lib/RT/Ticket_Overlay.pm:1886
+msgid "That is the same value"
+msgstr "Este es el mismo valor"
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr "Ese principal ya es un %1 para esta cola"
+
+#: lib/RT/Ticket_Overlay.pm:1434
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr "Ese principal ya es un %1 para este ticket"
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr "Ese principal no es un %1 para esta cola"
+
+#: lib/RT/Ticket_Overlay.pm:1551
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr "Ese principal no es un %1 para este ticket"
+
+#: lib/RT/Ticket_Overlay.pm:1882
+msgid "That queue does not exist"
+msgstr "Esa cola no existe"
+
+#: lib/RT/Ticket_Overlay.pm:3143
+msgid "That ticket has unresolved dependencies"
+msgstr "Ese ticket tiene dependencias sin resolver"
+
+#: lib/RT/ACE_Overlay.pm:288 lib/RT/ACE_Overlay.pm:597
+msgid "That user already has that right"
+msgstr "Ese usuario ya tiene ese privilegio"
+
+#: lib/RT/Ticket_Overlay.pm:2952
+msgid "That user already owns that ticket"
+msgstr "Ese usuario ya posee ese ticket"
+
+#: lib/RT/Ticket_Overlay.pm:2918
+msgid "That user does not exist"
+msgstr "Ese usuario no existe"
+
+#: lib/RT/User_Overlay.pm:315
+msgid "That user is already privileged"
+msgstr "Ese usuario ya tiene privilegios"
+
+#: lib/RT/User_Overlay.pm:332
+msgid "That user is already unprivileged"
+msgstr "Ese usuario ya está sin privilegios"
+
+#: lib/RT/User_Overlay.pm:327
+msgid "That user is now privileged"
+msgstr "Ese usuario ahora tiene privilegios"
+
+#: lib/RT/User_Overlay.pm:344
+msgid "That user is now unprivileged"
+msgstr "Ese usuario ya no tiene privilegios"
+
+#: NOT FOUND IN SOURCE
+msgid "That user is now unprivilegedileged"
+msgstr "Este usuario ya no tiene privilegios"
+
+#: lib/RT/Ticket_Overlay.pm:2944
+msgid "That user may not own tickets in that queue"
+msgstr "Ese usuario puede no poseer tickets en esa cola"
+
+#: lib/RT/Link_Overlay.pm:206
+msgid "That's not a numerical id"
+msgstr "Ese no es un identificador numérico"
+
+#: html/Ticket/Create.html:150 html/Ticket/Elements/ShowSummary:28
+msgid "The Basics"
+msgstr "Lo básico"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The CC of a ticket"
+msgstr "El CC de un ticket"
+
+#: lib/RT/ACE_Overlay.pm:89
+msgid "The administrative CC of a ticket"
+msgstr "El CC administrativo de un ticket"
+
+#: lib/RT/Ticket_Overlay.pm:2213
+msgid "The comment has been recorded"
+msgstr "El comentario ha sido grabado"
+
+#: bin/rt-crontool:198
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr "El siguiente comando encontrará todos los tickets activos en la cola 'general' y pondra su prioridad a 99 si no han sido tocados en 4 horas:"
+
+#: bin/rt-commit-handler:756 bin/rt-commit-handler:766
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr "Los siguientes comandos no han sido procesados:\\n\\n"
+
+#: lib/RT/Interface/Web.pm:861
+msgid "The new value has been set."
+msgstr "Ha sido establecido el nuevo valor"
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The owner of a ticket"
+msgstr "El propietario de un ticket"
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The requestor of a ticket"
+msgstr "El solicitante de un ticket"
+
+#: html/Admin/Elements/EditUserComments:26
+msgid "These comments aren't generally visible to the user"
+msgstr "Estos comentarios generalmente no están visibles para el usuario"
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr "Este ticket %1 %2 (%3)"
+
+#: bin/rt-crontool:189
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr "Esta herramiento permite al usuario ejectutar modulos perl arbitrarios desde dentro de RT"
+
+#: lib/RT/Transaction_Overlay.pm:253
+msgid "This transaction appears to have no content"
+msgstr "Parece que esta transacción no tiene contenido"
+
+#: html/Ticket/Elements/ShowRequestor:47
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr "Los %1 tickets de mayor prioridad de este usuario"
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr "Los 25 casos de mayor prioridad de este usuario"
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "Jue."
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr "Ticket # %1  %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1 Jumbo update: %2"
+msgstr "Actualizacion Jumbo para el ticket # %1: %2"
+
+#: html/Ticket/ModifyAll.html:25 html/Ticket/ModifyAll.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "Actualización Jumbo para el ticket #%1: %2"
+
+#: html/Approvals/Elements/ShowDependency:46
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr "Ticket #%1: %2"
+
+#: lib/RT/Ticket_Overlay.pm:608
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr "Ticket %1 creado en la cola '%2'"
+
+#: bin/rt-commit-handler:760
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr "Ticket %1 cargado\\n"
+
+#: html/Search/Bulk.html:181
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr "Ticket %1: %2"
+
+#: html/Ticket/History.html:25 html/Ticket/History.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr "Historial del ticket # %1 %2"
+
+#: html/SelfService/Display.html:34
+msgid "Ticket Id"
+msgstr "Id del ticket:"
+
+#: etc/initialdata:303
+msgid "Ticket Resolved"
+msgstr "Ticket resuelto"
+
+#: html/Search/Elements/PickRestriction:63
+msgid "Ticket attachment"
+msgstr "Archivos adjuntos del ticket"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr "Contenido del ticket"
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr "Tipo de contenido del ticket"
+
+#: lib/RT/Ticket_Overlay.pm:495 lib/RT/Ticket_Overlay.pm:597
+msgid "Ticket could not be created due to an internal error"
+msgstr "No se pudo crear el ticket debido a un error interno"
+
+#: lib/RT/Transaction_Overlay.pm:522
+msgid "Ticket created"
+msgstr "Ticket creado"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr "Creación del ticket fallida"
+
+#: lib/RT/Transaction_Overlay.pm:527
+msgid "Ticket deleted"
+msgstr "Ticket borrado"
+
+#: html/REST/1.0/modify:29 html/REST/1.0/update:34
+msgid "Ticket id not found"
+msgstr "Id de ticket no encontrada"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket killed"
+msgstr "Ticket matado"
+
+#: html/REST/1.0/modify:36 html/REST/1.0/update:41
+msgid "Ticket not found"
+msgstr "Ticket no encontrado"
+
+#: etc/initialdata:289
+msgid "Ticket status changed"
+msgstr "Estado del ticket cambiado"
+
+#: html/Ticket/Update.html:39
+msgid "Ticket watchers"
+msgstr "Observadores del ticket"
+
+#: html/Elements/Tabs:49
+msgid "Tickets"
+msgstr "Tickets"
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr "Tickets %1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr "Tickets %1 por %2"
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Tickets from %1"
+msgstr "Tickets de %1"
+
+#: html/Approvals/Elements/ShowDependency:27
+msgid "Tickets which depend on this approval:"
+msgstr "Tickets que dependen de esta aprobación:"
+
+#: html/Ticket/Create.html:157 html/Ticket/Elements/EditBasics:48
+msgid "Time Left"
+msgstr "Tiempo Restante"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:43
+msgid "Time Worked"
+msgstr "Tiempo Trabajado"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "Tiempo restante"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "Tiempo para mostrar"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "Tiempo trabajado"
+
+#: NOT FOUND IN SOURCE
+msgid "TimeLeft"
+msgstr "TimeLeft"
+
+#: lib/RT/Ticket_Overlay.pm:1165
+msgid "TimeWorked"
+msgstr "TimeWorked"
+
+#: bin/rt-commit-handler:402
+msgid "To generate a diff of this commit:"
+msgstr "Para generar una comparación de este cometido:"
+
+#: bin/rt-commit-handler:391
+msgid "To generate a diff of this commit:\\n"
+msgstr "Para generar una comparación de este cometido:\\n"
+
+#: lib/RT/Ticket_Overlay.pm:1168
+msgid "Told"
+msgstr "Última actualización"
+
+#: etc/initialdata:237
+msgid "Transaction"
+msgstr "Transacción"
+
+#: lib/RT/Transaction_Overlay.pm:642
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr "Transacción %1 limpiada"
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr "Transacción creada"
+
+#: lib/RT/Transaction_Overlay.pm:89
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr "Transaction->Create no pudo, ya no no especificó un ID de ticket"
+
+#: lib/RT/Transaction_Overlay.pm:701
+msgid "Transactions are immutable"
+msgstr "Las transacciones son inmutables"
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr "Intentando borrar el privilegio: %1"
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "Mar."
+
+#: html/Admin/Elements/EditCustomField:34 html/Ticket/Elements/AddWatchers:33 html/Ticket/Elements/AddWatchers:44 html/Ticket/Elements/AddWatchers:54 lib/RT/Ticket_Overlay.pm:1166 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "Tipo"
+
+#: lib/RT/ScripCondition_Overlay.pm:104
+msgid "Unimplemented"
+msgstr "No implementado"
+
+#: html/Admin/Users/Modify.html:68
+msgid "Unix login"
+msgstr "Usuario en Unix"
+
+#: html/Admin/Elements/ModifyUser:62
+msgid "UnixUsername"
+msgstr "Usuario en Unix"
+
+#: lib/RT/Attachment_Overlay.pm:265
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr "Codificación de contenido desconocida: %1"
+
+#: html/Elements/SelectResultsPerPage:37
+msgid "Unlimited"
+msgstr "Ilimitado"
+
+#: etc/initialdata:32
+msgid "Unprivileged"
+msgstr "No privilegiado"
+
+#: lib/RT/Transaction_Overlay.pm:571
+msgid "Untaken"
+msgstr "No cogido"
+
+#: html/Elements/MyTickets:64 html/Search/Bulk.html:33
+msgid "Update"
+msgstr "Actualizar"
+
+#: html/Admin/Users/Prefs.html:62
+msgid "Update ID"
+msgstr "Id de actualización"
+
+#: html/Search/Bulk.html:120 html/Ticket/ModifyAll.html:66 html/Ticket/Update.html:67
+msgid "Update Type"
+msgstr "Tipo de actualización"
+
+#: html/Search/Listing.html:61
+msgid "Update all these tickets at once"
+msgstr "Actualizar todos estos casos al mismo tiempo"
+
+#: html/Admin/Users/Prefs.html:49
+msgid "Update email"
+msgstr "Actualizar correo"
+
+#: html/Admin/Users/Prefs.html:55
+msgid "Update name"
+msgstr "Actualizar nombre"
+
+#: lib/RT/Interface/Web.pm:375
+msgid "Update not recorded."
+msgstr "Actualización no grabada."
+
+#: html/Search/Bulk.html:81
+msgid "Update selected tickets"
+msgstr "Actualizar tickets seleccionados"
+
+#: html/Admin/Users/Prefs.html:36
+msgid "Update signature"
+msgstr "Actualizar firma"
+
+#: html/Ticket/ModifyAll.html:63
+msgid "Update ticket"
+msgstr "Actualizar ticket"
+
+#: html/SelfService/Update.html:25 html/SelfService/Update.html:27
+#. ($Ticket->id)
+msgid "Update ticket # %1"
+msgstr "Actualización de ticket # %1"
+
+#: html/SelfService/Update.html:50
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr "Actualizar ticket #%1"
+
+#: html/Ticket/Update.html:135
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr "Actualizar ticket #%1 (%2)"
+
+#: lib/RT/Interface/Web.pm:373
+msgid "Update type was neither correspondence nor comment."
+msgstr "El tipo de actualización no fue ni respuesta ni comentario"
+
+#: html/Elements/SelectDateType:33 html/Ticket/Elements/ShowDates:51 lib/RT/Ticket_Overlay.pm:1169
+msgid "Updated"
+msgstr "Actualizado"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr "Usuario %1 %2: %3\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr "Usuario %1 Contraseña: %2\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr "Usuario '%1' no encontrado"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr "Usuario '%1' no encontrado\\n"
+
+#: etc/initialdata:125 etc/initialdata:191
+msgid "User Defined"
+msgstr "Definido por el usuario"
+
+#: html/Admin/Users/Prefs.html:59
+msgid "User ID"
+msgstr "ID de usuario"
+
+#: html/Elements/SelectUsers:26
+msgid "User Id"
+msgstr "Id de usuario"
+
+#: html/Admin/Elements/GroupTabs:47 html/Admin/Elements/QueueTabs:60 html/Admin/Elements/SystemTabs:47 html/Admin/Global/index.html:59
+msgid "User Rights"
+msgstr "Privilegios de usuario"
+
+#: html/Admin/Users/Modify.html:226
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr "El usuario no pudo ser creado: %1"
+
+#: lib/RT/User_Overlay.pm:262
+msgid "User created"
+msgstr "Usuario creado"
+
+#: html/Admin/Global/GroupRights.html:67 html/Admin/Groups/GroupRights.html:54 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr "Grupos definidos por el usuario"
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr "Usuario notificado"
+
+#: html/Admin/Users/Prefs.html:25 html/Admin/Users/Prefs.html:29
+msgid "User view"
+msgstr "Vista de usuario"
+
+#: html/Admin/Users/Modify.html:48 html/Elements/Login:42 html/Ticket/Elements/AddWatchers:35
+msgid "Username"
+msgstr "Nombre de usuario"
+
+#: html/Admin/Elements/SelectNewGroupMembers:26 html/Admin/Elements/Tabs:32 html/Admin/Groups/Members.html:55 html/Admin/Queues/People.html:68 html/Admin/index.html:29 html/User/Groups/Members.html:58
+msgid "Users"
+msgstr "Usuarios"
+
+#: html/Admin/Users/index.html:65
+msgid "Users matching search criteria"
+msgstr "Usuarios que concuerdan con los criterios de búsqueda"
+
+#: html/Search/Elements/PickRestriction:51
+msgid "ValueOfQueue"
+msgstr "Valor de la cola"
+
+#: html/Admin/Elements/EditCustomField:40
+msgid "Values"
+msgstr "Valores"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Watch"
+msgstr "Observar"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "WatchAsAdminCc"
+msgstr "WatchAsAdminCc"
+
+#: NOT FOUND IN SOURCE
+msgid "Watcher loaded"
+msgstr "Observador cargado"
+
+#: html/Admin/Elements/QueueTabs:42
+msgid "Watchers"
+msgstr "Observadores"
+
+#: html/Admin/Elements/ModifyUser:56
+msgid "WebEncoding"
+msgstr "Codificación de Web"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "Mie."
+
+#: etc/upgrade/2.1.71:161
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr "Cuando un ticket ha sido aprobado por todos los aprobadores, añadir correspondencia al ticket original"
+
+#: etc/upgrade/2.1.71:135
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr "Cuando un ticket ha sido aprobado por cualquier aprobador, añadir correspondencia al ticket original"
+
+#: etc/initialdata:138
+msgid "When a ticket is created"
+msgstr "Cuando un ticket se crea"
+
+#: etc/upgrade/2.1.71:79
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr "Cuando una aprobacion de ticket se crea, notifica al propietario y AdminCC del item que espera su aprobación"
+
+#: etc/initialdata:143
+msgid "When anything happens"
+msgstr "Cuando pasa cualquier cosa"
+
+#: etc/initialdata:184
+msgid "Whenever a ticket is resolved"
+msgstr "Siempre que un ticket este sin resolver"
+
+#: etc/initialdata:170
+msgid "Whenever a ticket's owner changes"
+msgstr "Siempre que el propietario de un ticket cambie"
+
+#: etc/initialdata:178
+msgid "Whenever a ticket's queue changes"
+msgstr "Siempre que la cola de un ticket cambie"
+
+#: etc/initialdata:162
+msgid "Whenever a ticket's status changes"
+msgstr "Siempre que el estado de un ticket cambie"
+
+#: etc/initialdata:192
+msgid "Whenever a user-defined condition occurs"
+msgstr "Siempre que ocurra una condicion definida por el usuario"
+
+#: etc/initialdata:156
+msgid "Whenever comments come in"
+msgstr "Siempre que venga algun comentario"
+
+#: etc/initialdata:149
+msgid "Whenever correspondence comes in"
+msgstr "Siempre que venga correspondencia"
+
+#: html/Admin/Users/Modify.html:164 html/User/Prefs.html:52
+msgid "Work"
+msgstr "Trabajo"
+
+#: html/Admin/Elements/ModifyUser:70
+msgid "WorkPhone"
+msgstr "Tel Trabajo"
+
+#: html/SelfService/Display.html:86 html/Ticket/Elements/ShowBasics:35 html/Ticket/Update.html:65
+msgid "Worked"
+msgstr "Trabajado"
+
+#: lib/RT/Ticket_Overlay.pm:3056
+msgid "You already own this ticket"
+msgstr "Usted ya es propietario de este caso"
+
+#: html/autohandler:121
+msgid "You are not an authorized user"
+msgstr "Usted no es un usuario autorizado"
+
+#: lib/RT/Ticket_Overlay.pm:2930
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "Usted solo puede reasignar casos que posee o que no posee nadie³"
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr "No tiene permiso para ver ese ticket.\\n"
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "Usted encontró %1 casos en la cola %2"
+
+#: html/NoAuth/Logout.html:31 html/REST/1.0/logout:25
+msgid "You have been logged out of RT."
+msgstr "Se ha desconectado del sistema RT"
+
+#: html/SelfService/Display.html:134
+msgid "You have no permission to create tickets in that queue."
+msgstr "No tiene permiso para crear tickets en esa cola."
+
+#: lib/RT/Ticket_Overlay.pm:1895
+msgid "You may not create requests in that queue."
+msgstr "No puede crear solicitudes en esa cola."
+
+#: html/NoAuth/Logout.html:36
+msgid "You're welcome to login again"
+msgstr "Es bienvenido a regresar en cualquier momento."
+
+#: html/SelfService/Elements/MyRequests:25
+#. ($friendly_status)
+msgid "Your %1 requests"
+msgstr "Sus solicitudes %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr "Su administrador del RT ha desconfigurado el alias de correo que invoca el RT"
+
+#: etc/initialdata:429 etc/upgrade/2.1.71:146
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr "Su petición ha sido aprobada por %1. Otras aprobaciones pueden estar pendientes todavia"
+
+#: etc/initialdata:463 etc/upgrade/2.1.71:180
+msgid "Your request has been approved."
+msgstr "Su peticion ha sido aprobada."
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr "Su petición ha sido rechazada"
+
+#: etc/initialdata:384 etc/upgrade/2.1.71:101
+msgid "Your request was rejected."
+msgstr "Su petición ha sido rechazada"
+
+#: html/autohandler:136 html/autohandler:142
+msgid "Your username or password is incorrect"
+msgstr "Nombre o contraseña de usuario incorrectos"
+
+#: html/Admin/Elements/ModifyUser:84 html/Admin/Users/Modify.html:144 html/User/Prefs.html:96
+msgid "Zip"
+msgstr "Zip"
+
+#: NOT FOUND IN SOURCE
+msgid "[no subject]"
+msgstr "[sin asunto]"
+
+#: html/User/Elements/DelegateRights:59
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "como priviligiado para %1"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:34
+msgid "contains"
+msgstr "contiene"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content"
+msgstr "contenido"
+
+#: html/Elements/SelectAttachmentField:27
+msgid "content-type"
+msgstr "content-type"
+
+#: lib/RT/Ticket_Overlay.pm:2282
+msgid "correspondence (probably) not sent"
+msgstr "Respuesta (probablemente) no enviada"
+
+#: lib/RT/Ticket_Overlay.pm:2292
+msgid "correspondence sent"
+msgstr "Correspondencia enviada"
+
+#: html/Admin/Elements/ModifyQueue:63 html/Admin/Queues/Modify.html:77 lib/RT/Date.pm:319
+msgid "days"
+msgstr "días"
+
+#: NOT FOUND IN SOURCE
+msgid "dead"
+msgstr "muerto"
+
+#: html/Search/Listing.html:75
+msgid "delete"
+msgstr "borrar"
+
+#: lib/RT/Queue_Overlay.pm:63
+msgid "deleted"
+msgstr "borrado"
+
+#: html/Search/Elements/PickRestriction:68
+msgid "does not match"
+msgstr "no coincide"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:35
+msgid "doesn't contain"
+msgstr "no contiene"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "equal to"
+msgstr "igual a"
+
+#: NOT FOUND IN SOURCE
+msgid "false"
+msgstr "falso"
+
+#: html/Elements/SelectAttachmentField:28
+msgid "filename"
+msgstr "nombre de archivo"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "greater than"
+msgstr "mayor que"
+
+#: lib/RT/Group_Overlay.pm:194
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "grupo '%1'"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "horas"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr "id"
+
+#: html/Elements/SelectBoolean:32 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88
+msgid "is"
+msgstr "es"
+
+#: html/Elements/SelectBoolean:36 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:37 html/Search/Elements/PickRestriction:48 html/Search/Elements/PickRestriction:77 html/Search/Elements/PickRestriction:89
+msgid "isn't"
+msgstr "no es"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "less than"
+msgstr "menor que"
+
+#: html/Search/Elements/PickRestriction:67
+msgid "matches"
+msgstr "contiene"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "min"
+
+#: html/Ticket/Update.html:66
+msgid "minutes"
+msgstr "minutos"
+
+#: bin/rt-commit-handler:765
+msgid "modifications\\n\\n"
+msgstr "modificaciones\\n\\n"
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "meses"
+
+#: lib/RT/Queue_Overlay.pm:58
+msgid "new"
+msgstr "nuevo"
+
+#: html/Admin/Elements/EditScrips:43
+msgid "no value"
+msgstr "sin valor"
+
+#: html/Ticket/Elements/EditWatchers:28
+msgid "none"
+msgstr "ninguno"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "not equal to"
+msgstr "no igual a"
+
+#: NOT FOUND IN SOURCE
+msgid "notlike"
+msgstr "notlike"
+
+#: lib/RT/Queue_Overlay.pm:59
+msgid "open"
+msgstr "abierto"
+
+#: lib/RT/Group_Overlay.pm:199
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr "grupo personal '%1' para usuario '%2'"
+
+#: lib/RT/Group_Overlay.pm:207
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr "Cola %1 %2"
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "rejected"
+msgstr "rechazado"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "resolved"
+msgstr "resuelto"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr "sec"
+
+#: lib/RT/Queue_Overlay.pm:60
+msgid "stalled"
+msgstr "pendiente"
+
+#: lib/RT/Group_Overlay.pm:202
+#. ($self->Type)
+msgid "system %1"
+msgstr "sistema %1"
+
+#: lib/RT/Group_Overlay.pm:213
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr "grupo del sistema '%1'"
+
+#: html/Elements/Error:42 html/SelfService/Error.html:42
+msgid "the calling component did not specify why"
+msgstr "el componente que llama no especifica por qué"
+
+#: lib/RT/Group_Overlay.pm:210
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr "ticket #%1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "true"
+msgstr "verdadero"
+
+#: lib/RT/Group_Overlay.pm:216
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr "grupo sin descripción %1"
+
+#: NOT FOUND IN SOURCE
+msgid "undescripbed group %1"
+msgstr "grupo sin descripción %1"
+
+#: lib/RT/Group_Overlay.pm:191
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr "usuario %1"
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr "semanas"
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr "con plantilla %1"
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr "años"
+
diff --git a/rt/lib/RT/I18N/fi.po b/rt/lib/RT/I18N/fi.po
new file mode 100644 (file)
index 0000000..ee1ad71
--- /dev/null
@@ -0,0 +1,4750 @@
+# Finnish localization catalog for Request Tracker (RT)
+# First Author: Janne Pirkkanen <jp@oppipoika.net>, Jul 2002
+msgid ""
+msgstr ""
+"Project-Id-Version: RT 2.1.x\n"
+"POT-Creation-Date: 2002-07-08 17:41+0200\n"
+"PO-Revision-Date: 2002-07-09 18:09+0200\n"
+"Last-Translator: Janne Pirkkanen <jp@oppipoika.net>\n"
+"Language-Team: Finnish\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28
+msgid "#"
+msgstr ""
+
+#: html/Admin/Queues/Scrip.html:55
+#. ($QueueObj->id)
+msgid "#%1"
+msgstr ""
+
+#: html/Approvals/Elements/ShowDependency:50 html/Ticket/Display.html:26 html/Ticket/Display.html:30
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr ""
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr ""
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr "%1 %3.%2 %7 %4:%5:%6"
+
+#: lib/RT/Ticket_Overlay.pm:3438 lib/RT/Transaction_Overlay.pm:559 lib/RT/Transaction_Overlay.pm:601
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 added"
+msgstr ""
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 %2 ago"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3444 lib/RT/Transaction_Overlay.pm:566
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 changed to %3"
+msgstr "%1: %2 muutettu arvoon %3"
+
+#: lib/RT/Ticket_Overlay.pm:3441 lib/RT/Transaction_Overlay.pm:562 lib/RT/Transaction_Overlay.pm:607
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 deleted"
+msgstr ""
+
+#: html/Admin/Elements/EditScrips:44 html/Admin/Elements/ListGlobalScrips:28
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 with template %3"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 this ticket\\n"
+msgstr "%1 (%2) %3 tässä työpyynnössä\\n"
+
+#: html/Search/Listing.html:57
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr ""
+
+#: bin/rt-crontool:169 bin/rt-crontool:176 bin/rt-crontool:182
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - An argument to pass to %2"
+msgstr ""
+
+#: bin/rt-crontool:185
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr ""
+
+#: bin/rt-crontool:179
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr ""
+
+#: bin/rt-crontool:173
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr ""
+
+#: bin/rt-crontool:166
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr ""
+
+#: lib/RT/ScripAction_Overlay.pm:122
+#. ($self->Id)
+msgid "%1 ScripAction loaded"
+msgstr "ScriptAction %1 ladattu"
+
+#: lib/RT/Ticket_Overlay.pm:3471
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 added as a value for %2"
+msgstr "%1 lisätty arvoksi %2lle"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on"
+msgstr "%1 aliakset vaativat työpyynnön id:n"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on "
+msgstr "%1 aliakset vaativat työpyynnön id:n "
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on (from %2) %3"
+msgstr "%1 aliakset vaativat työpyynnön id:n (osoite %2) %3"
+
+#: lib/RT/Link_Overlay.pm:117 lib/RT/Link_Overlay.pm:124
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 appears to be a local object, but can't be found in the database"
+msgstr ""
+
+#: html/Ticket/Elements/ShowDates:52 lib/RT/Transaction_Overlay.pm:483
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 by %2"
+msgstr "%1 - %2"
+
+#: lib/RT/Transaction_Overlay.pm:537 lib/RT/Transaction_Overlay.pm:626 lib/RT/Transaction_Overlay.pm:635 lib/RT/Transaction_Overlay.pm:638
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 changed from %2 to %3"
+msgstr "%1 muutettu arvosta %2 arvoon %3"
+
+#: lib/RT/Interface/Web.pm:857
+msgid "%1 could not be set to %2."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr "%1 ei voinut suorittaa toimintoa (%2)\\n"
+
+#: lib/RT/Ticket_Overlay.pm:2813
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr "%1 ei voinut asettaa tilan arvoa päätetyksi. RT:n tietokanta saattaa olla vioittunut."
+
+#: html/Elements/MyTickets:25
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr ""
+
+#: html/Elements/MyRequests:25
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr ""
+
+#: bin/rt-crontool:161
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr "%1 ei ole enää %2 tälle työjonolle"
+
+#: lib/RT/Ticket_Overlay.pm:1570
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr "%1 ei ole enää %2 tälle työpyynnölle"
+
+#: lib/RT/Ticket_Overlay.pm:3527
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr "%1 ei ole enää kentän %2 arvo"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr "%1 ei ole kelvollinen työjonon id"
+
+#: html/Ticket/Elements/ShowBasics:36
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr "%1 min"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr "%1 ei näy"
+
+#: html/User/Elements/DelegateRights:76
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr "%1 onnistui\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr "%1 tyyppi tuntematon viestille $MessageId"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr "%1 tyyppi tuntematon viestille %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 was created without a CurrentUser\\n"
+msgstr ""
+
+#: lib/RT/Action/ResolveMembers.pm:42
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr "%1 päättää kaikki päätetyt työpyynnöt -ryhmän työpyynnöt."
+
+#: NOT FOUND IN SOURCE
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr "%1 jäädyttää [paikallisen] BASE jos se riippuu linkitetystä työpyynnöstä [tai on sen jäsen]."
+
+#: lib/RT/Transaction_Overlay.pm:435
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr "%1: liitetiedostoa ei ole määritelty"
+
+#: html/Ticket/Elements/ShowTransaction:102
+#. ($size)
+msgid "%1b"
+msgstr ""
+
+#: html/Ticket/Elements/ShowTransaction:99
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1140
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr "'%1' ei kelpaa tilan arvoksi"
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr "'%1' ei ole tunnettu tapahtuma."
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete group member)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr "(Rastita laatikko poistaaksesi skriptin)"
+
+#: html/Admin/Elements/EditQueueWatchers:29 html/Admin/Elements/EditScrips:35 html/Admin/Elements/EditTemplates:36 html/Admin/Groups/Members.html:52 html/Ticket/Elements/EditLinks:33 html/Ticket/Elements/EditPeople:46 html/User/Groups/Members.html:55
+msgid "(Check box to delete)"
+msgstr "(Rastita laatikko poistaaksesi)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check boxes to delete)"
+msgstr ""
+
+#: html/Ticket/Create.html:178
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr "(Syötä työpyynnön numerot tai www-osoitteet, välilyönneillä erotettuina)"
+
+#: html/Admin/Queues/Modify.html:54 html/Admin/Queues/Modify.html:60
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(No Value)"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:33 html/Admin/Elements/ListGlobalCustomFields:32
+msgid "(No custom fields)"
+msgstr ""
+
+#: html/Admin/Groups/Members.html:50 html/User/Groups/Members.html:53
+msgid "(No members)"
+msgstr "(Ei jäseniä)"
+
+#: html/Admin/Elements/EditScrips:32 html/Admin/Elements/ListGlobalScrips:32
+msgid "(No scrips)"
+msgstr "(Ei skriptejä)"
+
+#: html/Admin/Elements/EditTemplates:31
+msgid "(No templates)"
+msgstr ""
+
+#: html/Ticket/Update.html:85
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Lähettää piilokopion tästä päivityksestä pilkulla erotettuihin sähköpostiosoitteisiin. <b>Ei muuta</b> jatkossa tehtävien lähetysten kohteita.)"
+
+#: html/Ticket/Create.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr ""
+
+#: html/Ticket/Update.html:81
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Lähettää kopion tästä päivityksestä pilkulla erotettuihin sähköpostiosoitteisiin. <b>Ei muuta</b> jatkossa tehtävien lähetysten kohteita.)"
+
+#: html/Ticket/Create.html:69
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr ""
+
+#: html/Admin/Groups/index.html:33 html/User/Groups/index.html:33
+msgid "(empty)"
+msgstr "(tyhjä)"
+
+#: html/Admin/Users/index.html:39
+msgid "(no name listed)"
+msgstr ""
+
+#: html/Elements/MyRequests:43 html/Elements/MyTickets:45
+msgid "(no subject)"
+msgstr "(ei otsikkoa)"
+
+#: html/Admin/Elements/SelectRights:48 html/Elements/SelectCustomFieldValue:30 html/Ticket/Elements/EditCustomField:59 html/Ticket/Elements/ShowCustomFields:36 lib/RT/Transaction_Overlay.pm:536
+msgid "(no value)"
+msgstr "(ei arvoa)"
+
+#: html/Ticket/Elements/EditLinks:116
+msgid "(only one ticket)"
+msgstr "(vain yksi työpyyntö)"
+
+#: html/Elements/MyRequests:52 html/Elements/MyTickets:55
+msgid "(pending approval)"
+msgstr ""
+
+#: html/Elements/MyRequests:54 html/Elements/MyTickets:57
+msgid "(pending other tickets)"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:50
+msgid "(required)"
+msgstr "(pakollinen)"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "(untitled)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I own..."
+msgstr "25 omistamaani korkeimpien prioriteettien työpyyntöä..."
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I requested..."
+msgstr "25 tilaamaani korkeimman prioriteetin työpyyntöä..."
+
+#: html/Ticket/Elements/ShowBasics:32
+msgid "<% $Ticket->Status%>"
+msgstr ""
+
+#: html/Elements/SelectTicketTypes:27
+msgid "<% $_ %>"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:26
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"Uusi työpyyntö\">&nbsp;%1"
+
+#: etc/initialdata:203
+msgid "A blank template"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Deleted"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Loaded"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be deleted"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be found"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:157 lib/RT/Principal_Overlay.pm:181
+msgid "ACE not found"
+msgstr "ACE ei löytynyt"
+
+#: lib/RT/ACE_Overlay.pm:831
+msgid "ACEs can only be created and deleted."
+msgstr "ACE:ja voi vain luoda ja poistaa."
+
+#: bin/rt-commit-handler:755
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr "Poistuminen ei-tarkoitettujen työpyyntömuutosten välttämiseksi.\\n"
+
+#: html/User/Elements/Tabs:32
+msgid "About me"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:80
+msgid "Access control"
+msgstr "Pääsynvalvonta"
+
+#: html/Admin/Elements/EditScrip:57
+msgid "Action"
+msgstr "Tapahtuma"
+
+#: lib/RT/Scrip_Overlay.pm:147
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr "Tapahtumaa %1 ei löydetty"
+
+#: bin/rt-crontool:123
+msgid "Action committed."
+msgstr ""
+
+#: bin/rt-crontool:119
+msgid "Action prepared..."
+msgstr ""
+
+#: html/Search/Bulk.html:92
+msgid "Add AdminCc"
+msgstr "Lisää kopio ylläpidolle"
+
+#: html/Search/Bulk.html:90
+msgid "Add Cc"
+msgstr "Lisää kopio"
+
+#: html/Ticket/Create.html:114 html/Ticket/Update.html:100
+msgid "Add More Files"
+msgstr ""
+
+#: html/Search/Bulk.html:88
+msgid "Add Requestor"
+msgstr "Lisää tilaaja"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a keyword selection to this queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr "Lisää uusi globaali lappu"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr "Lisää lappu tälle työjonolle"
+
+#: html/Admin/Global/Scrip.html:55
+msgid "Add a scrip which will apply to all queues"
+msgstr "Lisää kaikille työjonoille yhteinen lappu"
+
+#: html/Search/Bulk.html:118
+msgid "Add comments or replies to selected tickets"
+msgstr "Lisää kommentteja tai vastauksia valituille työpyynnöille"
+
+#: html/Admin/Groups/Members.html:42 html/User/Groups/Members.html:39
+msgid "Add members"
+msgstr "Lisää jäsenä"
+
+#: html/Admin/Queues/People.html:66 html/Ticket/Elements/AddWatchers:28
+msgid "Add new watchers"
+msgstr "Lisää uusia tarkkailijoita"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr "Lisätty toimeksiantaja %1:ksi tähän työjonoon"
+
+#: lib/RT/Ticket_Overlay.pm:1454
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr "Lisätty toimeksiantaja %1:ksi tälle työpyynnölle"
+
+#: html/Admin/Elements/ModifyUser:76 html/Admin/Users/Modify.html:122 html/User/Prefs.html:88
+msgid "Address1"
+msgstr "Osoite1"
+
+#: html/Admin/Elements/ModifyUser:78 html/Admin/Users/Modify.html:127 html/User/Prefs.html:90
+msgid "Address2"
+msgstr "Osoite2"
+
+#: html/Ticket/Create.html:74
+msgid "Admin Cc"
+msgstr "Kopio ylläpidolle"
+
+#: etc/initialdata:274
+msgid "Admin Comment"
+msgstr ""
+
+#: etc/initialdata:256
+msgid "Admin Correspondence"
+msgstr ""
+
+#: html/Admin/Queues/index.html:25 html/Admin/Queues/index.html:28
+msgid "Admin queues"
+msgstr "Työjonojen ylläpito"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr "Käyttäjien ylläpito"
+
+#: html/Admin/Global/index.html:26 html/Admin/Global/index.html:28
+msgid "Admin/Global configuration"
+msgstr "Ylläpito/Globaalit asetukset"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr "Ylläpito/Ryhmät"
+
+#: html/Admin/Queues/Modify.html:25 html/Admin/Queues/Modify.html:29
+msgid "Admin/Queue/Basics"
+msgstr "Ylläpito/Työjono/Perustiedot"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr ""
+
+#: etc/initialdata:56 html/Ticket/Elements/ShowPeople:39 html/Ticket/Update.html:50 lib/RT/ACE_Overlay.pm:89
+msgid "AdminCc"
+msgstr "Kopio ylläpidolle"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "AdminCustomFields"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "AdminGroup"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "AdminGroupMembership"
+msgstr ""
+
+#: lib/RT/System.pm:59
+msgid "AdminOwnPersonalGroups"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "AdminQueue"
+msgstr ""
+
+#: lib/RT/System.pm:60
+msgid "AdminUsers"
+msgstr ""
+
+#: html/Admin/Queues/People.html:48 html/Ticket/Elements/EditPeople:54
+msgid "Administrative Cc"
+msgstr "Kopio ylläpidolle"
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr "Tarkennettu haku"
+
+#: html/Elements/SelectDateRelation:36
+msgid "After"
+msgstr "Jälkeen"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:96
+msgid "All Custom Fields"
+msgstr ""
+
+#: html/Admin/Queues/index.html:53
+msgid "All Queues"
+msgstr "Kaikki työjonot"
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr ""
+
+#: html/Elements/Tabs:58
+msgid "Approval"
+msgstr ""
+
+#: html/Approvals/Display.html:46 html/Approvals/Elements/Approve:27 html/Approvals/Elements/ShowDependency:42 html/Approvals/index.html:65
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr ""
+
+#: html/Approvals/index.html:54
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr ""
+
+#: html/Approvals/index.html:52
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Details"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Approval diagram"
+msgstr ""
+
+#: html/Approvals/Elements/Approve:45
+msgid "Approve"
+msgstr ""
+
+#: etc/initialdata:431 etc/upgrade/2.1.71:148
+msgid "Approver's notes: %1"
+msgstr ""
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "Huhti"
+
+#: NOT FOUND IN SOURCE
+msgid "April"
+msgstr ""
+
+#: html/Elements/SelectSortOrder:35
+msgid "Ascending"
+msgstr "Nouseva"
+
+#: html/Search/Bulk.html:127 html/SelfService/Update.html:36 html/Ticket/ModifyAll.html:83 html/Ticket/Update.html:100
+msgid "Attach"
+msgstr "Liitä"
+
+#: html/SelfService/Create.html:67 html/Ticket/Create.html:110
+msgid "Attach file"
+msgstr "Liitä tiedosto"
+
+#: html/Ticket/Create.html:98 html/Ticket/Update.html:89
+msgid "Attached file"
+msgstr ""
+
+#: html/SelfService/Attachment/dhandler:36
+msgid "Attachment '%1' could not be loaded"
+msgstr "Liitteen '%1' lataaminen ei onnistunut"
+
+#: lib/RT/Transaction_Overlay.pm:443
+msgid "Attachment created"
+msgstr "Liitetiedosto luotu"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "Liitetiedoston nimi"
+
+#: html/Ticket/Elements/ShowAttachments:26
+msgid "Attachments"
+msgstr "Liitetiedostot"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "Elo"
+
+#: NOT FOUND IN SOURCE
+msgid "August"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:66
+msgid "AuthSystem"
+msgstr ""
+
+#: etc/initialdata:206
+msgid "Autoreply"
+msgstr ""
+
+#: etc/initialdata:72
+msgid "Autoreply To Requestors"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr "Virheellinen PGP allekirjoitus: %1\\n"
+
+#: html/SelfService/Attachment/dhandler:40
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr "Virheellinen liitteen numero. Liitetiedostoa '%1' ei löytynyt\\n"
+
+#: bin/rt-commit-handler:827
+#. ($val)
+msgid "Bad data in %1"
+msgstr "Virheellistä dataa kentässä %1"
+
+#: html/SelfService/Attachment/dhandler:43
+#. ($trans, $AttachmentObj->TransactionId())
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr "Virheellinen toiminnon numero liitetiedostolle. %1 pitäisi olla %2\\n"
+
+#: html/Admin/Elements/GroupTabs:39 html/Admin/Elements/QueueTabs:39 html/Admin/Elements/UserTabs:38 html/Ticket/Elements/Tabs:90 html/User/Elements/GroupTabs:38
+msgid "Basics"
+msgstr "Perustiedot"
+
+#: html/Ticket/Update.html:83
+msgid "Bcc"
+msgstr "Piilokopio"
+
+#: html/Admin/Elements/EditScrip:88 html/Admin/Global/GroupRights.html:85 html/Admin/Global/Template.html:46 html/Admin/Global/UserRights.html:54 html/Admin/Groups/GroupRights.html:73 html/Admin/Groups/Members.html:81 html/Admin/Groups/Modify.html:56 html/Admin/Groups/UserRights.html:55 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:45 html/Admin/Queues/UserRights.html:54 html/User/Groups/Modify.html:56
+msgid "Be sure to save your changes"
+msgstr "Muista tallentaa muutokset"
+
+#: html/Elements/SelectDateRelation:34 lib/RT/CurrentUser.pm:322
+msgid "Before"
+msgstr "Ennen"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin Approval"
+msgstr ""
+
+#: etc/initialdata:202
+msgid "Blank"
+msgstr ""
+
+#: html/Search/Listing.html:79
+msgid "Bookmarkable URL for this search"
+msgstr "Osoite tähän kyselyyn (selaimen kirjanmerkkeihin)"
+
+#: html/Ticket/Elements/ShowHistory:39 html/Ticket/Elements/ShowHistory:45
+msgid "Brief headers"
+msgstr "Lyhyet otsikot"
+
+#: html/Search/Bulk.html:25 html/Search/Bulk.html:26
+msgid "Bulk ticket update"
+msgstr "Työpyyntöjen ryhmäpäivitys"
+
+#: lib/RT/User_Overlay.pm:1331
+msgid "Can not modify system users"
+msgstr "Systeemikäyttäjien muokkaus ei ole sallittua"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Can this principal see this queue"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:144
+msgid "Can't add a custom field value without a name"
+msgstr "Kentän lisääminen ilman nimeä ei onnistu"
+
+#: lib/RT/Link_Overlay.pm:132
+msgid "Can't link a ticket to itself"
+msgstr "Työpyyntöä ei voi linkittää itseensä"
+
+#: lib/RT/Ticket_Overlay.pm:2787
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr "Et voi yhdistää jo yhdistettyyn työpyyntöön. Sinun ei pitäisi saada tätä virhettä koskaan."
+
+#: lib/RT/Ticket_Overlay.pm:2605 lib/RT/Ticket_Overlay.pm:2674
+msgid "Can't specifiy both base and target"
+msgstr "Sekä basen ja kohteen määritteleminen samalla ei ole mahdollista"
+
+#: html/autohandler:112
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr "Käyttäjää ei voitu luoda: %1"
+
+#: etc/initialdata:50 html/Admin/Queues/People.html:44 html/SelfService/Create.html:51 html/SelfService/Display.html:50 html/Ticket/Create.html:64 html/Ticket/Elements/EditPeople:51 html/Ticket/Elements/ShowPeople:35 html/Ticket/Update.html:45 html/Ticket/Update.html:78 lib/RT/ACE_Overlay.pm:88
+msgid "Cc"
+msgstr "Kopio"
+
+#: html/SelfService/Prefs.html:31
+msgid "Change password"
+msgstr "Muuta salasana"
+
+#: html/Ticket/Create.html:101 html/Ticket/Update.html:92
+msgid "Check box to delete"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:31
+msgid "Check box to revoke right"
+msgstr "Valitse laatikko poistaaksesi oikeuden"
+
+#: html/Ticket/Create.html:183 html/Ticket/Elements/EditLinks:131 html/Ticket/Elements/EditLinks:69 html/Ticket/Elements/ShowLinks:51
+msgid "Children"
+msgstr "Lapsi"
+
+#: html/Admin/Elements/ModifyUser:80 html/Admin/Users/Modify.html:132 html/User/Prefs.html:92
+msgid "City"
+msgstr "Kaupunki"
+
+#: html/Ticket/Elements/ShowDates:47
+msgid "Closed"
+msgstr ""
+
+#: html/SelfService/Elements/Tabs:60
+msgid "Closed requests"
+msgstr "Suljetut työpyynnöt"
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr "Komentoa ei ymmärretty!\\n"
+
+#: html/Ticket/Elements/ShowTransaction:179 html/Ticket/Elements/Tabs:153
+msgid "Comment"
+msgstr "Kommentoi"
+
+#: html/Admin/Elements/ModifyQueue:45 html/Admin/Queues/Modify.html:58
+msgid "Comment Address"
+msgstr "Kommenttien osoite"
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr "Kommenttia ei tallennettu"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Comment on tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "CommentOnTicket"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:35
+msgid "Comments"
+msgstr "Kommentit"
+
+#: html/Ticket/ModifyAll.html:70 html/Ticket/Update.html:70
+msgid "Comments (Not sent to requestors)"
+msgstr "Kommentit (Ei lähetetä tilaajille)"
+
+#: html/Search/Bulk.html:122
+msgid "Comments (not sent to requestors)"
+msgstr "Kommentit (Ei lähetetä tilaajille)"
+
+#: html/Elements/ViewUser:27
+#. ($name)
+msgid "Comments about %1"
+msgstr "Kommentit kohteesta %1"
+
+#: html/Admin/Users/Modify.html:185 html/Ticket/Elements/ShowRequestor:44
+msgid "Comments about this user"
+msgstr "Kommentit tästä käyttäjästä"
+
+#: lib/RT/Transaction_Overlay.pm:545
+msgid "Comments added"
+msgstr "Kommentit lisätty"
+
+#: lib/RT/Action/Generic.pm:140
+msgid "Commit Stubbed"
+msgstr "Suorita tumppi"
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr "Kokoa rajoitukset"
+
+#: html/Admin/Elements/EditScrip:41
+msgid "Condition"
+msgstr "Ehto"
+
+#: bin/rt-crontool:109
+msgid "Condition matches..."
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:160
+msgid "Condition not found"
+msgstr "Ehtoa ei löydetty"
+
+#: html/Elements/Tabs:52
+msgid "Configuration"
+msgstr "Ylläpito"
+
+#: html/SelfService/Prefs.html:33
+msgid "Confirm"
+msgstr "Varmista"
+
+#: html/Admin/Elements/ModifyUser:60
+msgid "ContactInfoSystem"
+msgstr "Kontaktitietojärjestelmä"
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr "Järjestelmä ei ymmärrä päivää '%1'"
+
+#: html/Admin/Elements/ModifyTemplate:44 html/Ticket/ModifyAll.html:87
+msgid "Content"
+msgstr "Sisältö"
+
+#: NOT FOUND IN SOURCE
+msgid "Coould not create group"
+msgstr ""
+
+#: etc/initialdata:266
+msgid "Correspondence"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:39 html/Admin/Queues/Modify.html:51
+msgid "Correspondence Address"
+msgstr "Kirjeenvaihdon osoite"
+
+#: lib/RT/Transaction_Overlay.pm:541
+msgid "Correspondence added"
+msgstr "Kirjeenvaihto lisätty"
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr "Vastausta ei tallennettu"
+
+#: lib/RT/Ticket_Overlay.pm:3458
+msgid "Could not add new custom field value for ticket. "
+msgstr "Uuden tiedon lisääminen kenttään ei onnistunut"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not add new custom field value for ticket. %1 "
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2963 lib/RT/Ticket_Overlay.pm:2971 lib/RT/Ticket_Overlay.pm:2987
+msgid "Could not change owner. "
+msgstr "Omistajaa ei voitu vaihtaa."
+
+#: html/Admin/Elements/EditCustomField:68 html/Admin/Elements/EditCustomFields:166
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr "Uuden kentän lisääminen ei onnistunut"
+
+#: html/User/Groups/Modify.html:77 lib/RT/Group_Overlay.pm:474 lib/RT/Group_Overlay.pm:481
+msgid "Could not create group"
+msgstr "Ryhmän luominen ei onnistunut"
+
+#: html/Admin/Global/Template.html:75 html/Admin/Queues/Template.html:72
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr "Ei onnistuttu luomaan pohjaa: "
+
+#: lib/RT/Ticket_Overlay.pm:1073 lib/RT/Ticket_Overlay.pm:333
+msgid "Could not create ticket. Queue not set"
+msgstr "Työpyynön luominen ei onnistunut. Työjonoa ei ole asetettu"
+
+#: lib/RT/User_Overlay.pm:208 lib/RT/User_Overlay.pm:220 lib/RT/User_Overlay.pm:238 lib/RT/User_Overlay.pm:414
+msgid "Could not create user"
+msgstr "Käyttäjän luominen ei onnistunut"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not create watcher for requestor"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr "Työpyyntöä numero '%1' ei löytynyt."
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr "Ryhmää '%1' ei löytynyt."
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1422
+msgid "Could not find or create that user"
+msgstr "Käyttäjää ei löydetty eikä pystytty luomaan"
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1501
+msgid "Could not find that principal"
+msgstr "Tätä toimeksiantajaa ei löytynyt"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr "Käyttäjää '%1' ei löytynyt."
+
+#: html/Admin/Groups/Members.html:88 html/User/Groups/Members.html:90 html/User/Groups/Modify.html:82
+msgid "Could not load group"
+msgstr "Ryhmän lataaminen ei onnistunut"
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr "Ei voinut tehdä toimeksiantajaa %1:ksi tälle työjonolle"
+
+#: lib/RT/Ticket_Overlay.pm:1443
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr "Ei voinut tehdä toimeksiantajaa tälle työpyynnölle: %1"
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr "Ei voinut poistaa toimeksiantajaa tältä työjonolta: %1"
+
+#: lib/RT/Ticket_Overlay.pm:1559
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr "Ei voinut poistaa toimeksiantajaa tältä työpyynnöltä: %1"
+
+#: lib/RT/Group_Overlay.pm:985
+msgid "Couldn't add member to group"
+msgstr "Jäsenen lisääminen ryhmään ei onnistunut"
+
+#: lib/RT/Ticket_Overlay.pm:3468 lib/RT/Ticket_Overlay.pm:3524
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr "Toiminnon luominen ei onnistunut: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr "Järjestelmä ei ymmärtänyt mitä tehdä pgp:n vastauksella\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr "Ryhmää ei löytynyt\\n"
+
+#: lib/RT/Interface/Web.pm:866
+msgid "Couldn't find row"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:959
+msgid "Couldn't find that principal"
+msgstr "Tätä toimeksiantajaa ei löytynyt"
+
+#: lib/RT/CustomField_Overlay.pm:175
+msgid "Couldn't find that value"
+msgstr "Tätä arvoa ei löytynyt"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find that watcher"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr "Käyttäjää ei löytynyt\\n"
+
+#: lib/RT/CurrentUser.pm:112
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr "Ei onnistuttu lataamaan käytäjää %1 tietokannasta.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load KeywordSelects."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr "RT asetustiedoston lataaminen ei onnistunut:'%1' %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr "Lappujen lataaminen ei onnistunut."
+
+#: html/Admin/Groups/GroupRights.html:88 html/Admin/Groups/UserRights.html:75
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr "Ryhmän %1 lataaminen ei onnistunut"
+
+#: lib/RT/Link_Overlay.pm:175 lib/RT/Link_Overlay.pm:184 lib/RT/Link_Overlay.pm:211
+msgid "Couldn't load link"
+msgstr "Linkin lataaminen ei onnistunut"
+
+#: html/Admin/Elements/EditCustomFields:147 html/Admin/Queues/People.html:121
+#. ($id)
+msgid "Couldn't load queue"
+msgstr "Työjonon lataaminen ei onnistunut"
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:72
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr "Työjonon %1 lataaminen ei onnistunut"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr "Lapun lataaminen ei onnistunut"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr "Pohjan lataaminen ei onnistunut"
+
+#: html/Admin/Users/Prefs.html:79
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr "Tämän käyttäjän lataaminen ei onnistunut (%1)"
+
+#: html/SelfService/Display.html:166
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr "Työpyynnön '%1' lataaminen ei onnistunut"
+
+#: html/Admin/Elements/ModifyUser:86 html/Admin/Users/Modify.html:149 html/User/Prefs.html:98
+msgid "Country"
+msgstr "Maa"
+
+#: html/Admin/Elements/CreateUserCalled:26 html/Ticket/Create.html:135 html/Ticket/Create.html:195
+msgid "Create"
+msgstr "Luo"
+
+#: etc/initialdata:128
+msgid "Create Tickets"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomField:58
+msgid "Create a CustomField"
+msgstr "Luo kenttä"
+
+#: html/Admin/Queues/CustomField.html:48
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:48
+msgid "Create a CustomField which applies to all queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr "Luo uusi kenttä"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr "Luo uusi globaali lappu"
+
+#: html/Admin/Groups/Modify.html:67 html/Admin/Groups/Modify.html:93
+msgid "Create a new group"
+msgstr "Luo uusi ryhmä"
+
+#: html/User/Groups/Modify.html:67 html/User/Groups/Modify.html:92
+msgid "Create a new personal group"
+msgstr "Luo uusi personaali ryhmä"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr "Luo uusi työjono"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr "Luo uusi pohja"
+
+#: html/SelfService/Create.html:30 html/Ticket/Create.html:25 html/Ticket/Create.html:28 html/Ticket/Create.html:36
+msgid "Create a new ticket"
+msgstr "Luo uusi työpyyntö"
+
+#: html/Admin/Users/Modify.html:214 html/Admin/Users/Modify.html:241
+msgid "Create a new user"
+msgstr "Luo uusi käyttäjä"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "Luo uusi työjono"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr "Luo työjono nimeltään"
+
+#: html/SelfService/Create.html:25 html/SelfService/Create.html:27
+msgid "Create a request"
+msgstr "Luo työpyyntö"
+
+#: html/Admin/Queues/Scrip.html:59
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr ""
+
+#: html/Admin/Global/Template.html:69 html/Admin/Queues/Template.html:65
+msgid "Create a template"
+msgstr "Luo pohja"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1 / %2 / %3 "
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1/%2/%3"
+msgstr ""
+
+#: etc/initialdata:130
+msgid "Create new tickets based on this scrip's template"
+msgstr ""
+
+#: html/SelfService/Create.html:81
+msgid "Create ticket"
+msgstr "Luo työpyyntö"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Create tickets in this queue"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Create, delete and modify custom fields"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Create, delete and modify queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr ""
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify the members of personal groups"
+msgstr ""
+
+#: lib/RT/System.pm:60
+msgid "Create, delete and modify users"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "CreateTicket"
+msgstr ""
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1167
+msgid "Created"
+msgstr "Luotu"
+
+#: html/Admin/Elements/EditCustomField:71
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr "Luotu kenttä %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr "Luotu pohja %1"
+
+#: html/Ticket/Elements/EditLinks:28
+msgid "Current Relationships"
+msgstr "Tämänhetkiset suhteet"
+
+#: html/Admin/Elements/EditScrips:30
+msgid "Current Scrips"
+msgstr ""
+
+#: html/Admin/Groups/Members.html:39 html/User/Groups/Members.html:42
+msgid "Current members"
+msgstr "Tämänhetkiset jäsenet"
+
+#: html/Admin/Elements/SelectRights:29
+msgid "Current rights"
+msgstr "Tämänhetkiset oikeudet"
+
+#: html/Search/Listing.html:71
+msgid "Current search criteria"
+msgstr ""
+
+#: html/Admin/Queues/People.html:41 html/Ticket/Elements/EditPeople:45
+msgid "Current watchers"
+msgstr "Tämänhetkiset tarkkailijat"
+
+#: html/Admin/Global/CustomField.html:55
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:53 html/Admin/Elements/SystemTabs:40 html/Admin/Global/index.html:50 html/Ticket/Elements/ShowSummary:35
+msgid "Custom Fields"
+msgstr "Kentät"
+
+#: html/Admin/Elements/EditScrip:73
+msgid "Custom action cleanup code"
+msgstr ""
+
+#: html/Admin/Elements/EditScrip:65
+msgid "Custom action preparation code"
+msgstr ""
+
+#: html/Admin/Elements/EditScrip:49
+msgid "Custom condition"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr "Kenttä %1 %2 %3"
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr "Kentällä %1 on arvo"
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr "Kentällä %1 ei ole arvoa"
+
+#: lib/RT/Ticket_Overlay.pm:3360
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr "Kenttää %1 ei löytynyt"
+
+#: html/Admin/Elements/EditCustomFields:197
+msgid "Custom field deleted"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3510
+msgid "Custom field not found"
+msgstr "Kenttää ei löytynyt"
+
+#: lib/RT/CustomField_Overlay.pm:283
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr "Kenttän arvoa %1 ei löytynyt kentälle %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr "Kenttän arvo muutettu arvosta %1 arvoon"
+
+#: lib/RT/CustomField_Overlay.pm:185
+msgid "Custom field value could not be deleted"
+msgstr "Kenttän arvoa ei pystytty poistamaan"
+
+#: lib/RT/CustomField_Overlay.pm:289
+msgid "Custom field value could not be found"
+msgstr "Kenttän arvoa ei löydetty"
+
+#: lib/RT/CustomField_Overlay.pm:183 lib/RT/CustomField_Overlay.pm:291
+msgid "Custom field value deleted"
+msgstr "Kenttän arvo poistettu"
+
+#: lib/RT/Transaction_Overlay.pm:550
+msgid "CustomField"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Data error"
+msgstr ""
+
+#: html/Ticket/Create.html:161 html/Ticket/Elements/ShowSummary:53 html/Ticket/Elements/Tabs:93 html/Ticket/ModifyAll.html:44
+msgid "Dates"
+msgstr "Päivät"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "Joulu"
+
+#: NOT FOUND IN SOURCE
+msgid "December"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr ""
+
+#: etc/initialdata:207
+msgid "Default Autoresponse template"
+msgstr ""
+
+#: etc/initialdata:275
+msgid "Default admin comment template"
+msgstr ""
+
+#: etc/initialdata:257
+msgid "Default admin correspondence template"
+msgstr ""
+
+#: etc/initialdata:267
+msgid "Default correspondence template"
+msgstr ""
+
+#: etc/initialdata:238
+msgid "Default transaction template"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:645
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr ""
+
+#: html/User/Delegation.html:25 html/User/Delegation.html:28
+msgid "Delegate rights"
+msgstr "Delegoi oikeuksia"
+
+#: lib/RT/System.pm:63
+msgid "Delegate specific rights which have been granted to you."
+msgstr ""
+
+#: lib/RT/System.pm:63
+msgid "DelegateRights"
+msgstr ""
+
+#: html/User/Elements/Tabs:38
+msgid "Delegation"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Delete"
+msgstr "Poista"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "Delete tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "DeleteTicket"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr "Tämän objektin poistaminen saattaa rikkoa tietokannan viitteet"
+
+#: lib/RT/Queue_Overlay.pm:292
+msgid "Deleting this object would break referential integrity"
+msgstr "Tämän objektin poistaminen rikkoo tietokannan viitteet"
+
+#: lib/RT/User_Overlay.pm:430
+msgid "Deleting this object would violate referential integrity"
+msgstr "Tämän objektin poistaminen rikkoo tietokannan viitteet"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity. That's bad."
+msgstr ""
+
+#: html/Approvals/Elements/Approve:46
+msgid "Deny"
+msgstr ""
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/EditLinks:123 html/Ticket/Elements/EditLinks:47 html/Ticket/Elements/ShowDependencies:32 html/Ticket/Elements/ShowLinks:35
+msgid "Depended on by"
+msgstr "Tästä pyynnöstä riippuu"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr "Riippuvuudet: \\n"
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:180 html/Ticket/Elements/EditLinks:119 html/Ticket/Elements/EditLinks:36 html/Ticket/Elements/ShowDependencies:25 html/Ticket/Elements/ShowLinks:27
+msgid "Depends on"
+msgstr "Riippuu pyynnöstä"
+
+#: NOT FOUND IN SOURCE
+msgid "DependsOn"
+msgstr ""
+
+#: html/Elements/SelectSortOrder:35
+msgid "Descending"
+msgstr "Laskeva"
+
+#: html/SelfService/Create.html:75 html/Ticket/Create.html:119
+msgid "Describe the issue below"
+msgstr "Työtilauksen kuvaus"
+
+#: html/Admin/Elements/AddCustomFieldValue:27 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/EditScrip:34 html/Admin/Elements/ModifyQueue:36 html/Admin/Elements/ModifyTemplate:36 html/Admin/Groups/Modify.html:49 html/Admin/Queues/Modify.html:48 html/Elements/SelectGroups:27 html/User/Groups/Modify.html:49
+msgid "Description"
+msgstr "Kuvaus"
+
+#: html/SelfService/Elements/MyRequests:44
+msgid "Details"
+msgstr "Yksityiskohdat"
+
+#: html/Ticket/Elements/Tabs:85
+msgid "Display"
+msgstr "Näytä"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Display Access Control List"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Display Scrip templates for this queue"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Display Scrips for this queue"
+msgstr ""
+
+#: html/Ticket/Elements/ShowHistory:35
+msgid "Display mode"
+msgstr "Näkymä"
+
+#: html/SelfService/Display.html:25 html/SelfService/Display.html:29
+#. ($Ticket->id)
+msgid "Display ticket #%1"
+msgstr "Näytä työpyyntö #%1"
+
+#: lib/RT/System.pm:54
+msgid "Do anything and everything"
+msgstr ""
+
+#: html/Elements/Refresh:30
+msgid "Don't refresh this page."
+msgstr "Älä päivitä tätä sivua"
+
+#: html/Search/Elements/PickRestriction:114
+msgid "Don't show search results"
+msgstr ""
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "Download"
+msgstr "Lataa"
+
+#: html/Elements/SelectDateType:32 html/Ticket/Create.html:167 html/Ticket/Elements/EditDates:45 html/Ticket/Elements/ShowDates:43 lib/RT/Ticket_Overlay.pm:1171
+msgid "Due"
+msgstr "Mennessä"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr "Mennessä -päivää '%1' ei onnistuttu kääntämään järjestelmälle."
+
+#: bin/rt-commit-handler:754
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr "VIRHE: Työpyynnön '%1' lataaminen ei onnistunut: %2.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit"
+msgstr "Muokkaa"
+
+#: html/Admin/Queues/CustomFields.html:45
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr "Muokkaa kenttiä: työjono %1"
+
+#: html/Ticket/ModifyLinks.html:36
+msgid "Edit Relationships"
+msgstr "Muokkaa suhteita"
+
+#: html/Admin/Queues/Templates.html:41
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit keywords"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr "Muokkaa lappuja"
+
+#: html/Admin/Global/index.html:46
+msgid "Edit system templates"
+msgstr "Muokkaa systeemipohjia"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr "Muokkaa pohjia: työjono %1"
+
+#: html/Admin/Elements/ModifyQueue:25 html/Admin/Queues/Modify.html:117
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr "Asetusten muokkaus: työjono %1"
+
+#: html/Admin/Elements/ModifyUser:25
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr "Asetusten muokkaus: käyttäjä %1"
+
+#: html/Admin/Elements/EditCustomField:74
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr "Kentän %1 muokkaus"
+
+#: html/Admin/Groups/Members.html:32
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr "Ryhmän %1 jäsenten muokkaus"
+
+#: html/User/Groups/Members.html:129
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr "Henkilökohtaisen ryhmän %1 jäsenten muokkaus"
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr "Pohjan %1 muokkaus"
+
+#: lib/RT/Ticket_Overlay.pm:2615 lib/RT/Ticket_Overlay.pm:2683
+msgid "Either base or target must be specified"
+msgstr "Joko juuri tai kohde täytyy olla määritelty"
+
+#: html/Admin/Users/Modify.html:53 html/Admin/Users/Prefs.html:46 html/Elements/SelectUsers:27 html/Ticket/Elements/AddWatchers:56 html/User/Prefs.html:42
+msgid "Email"
+msgstr "Sähköposti"
+
+#: lib/RT/User_Overlay.pm:188
+msgid "Email address in use"
+msgstr "Sähköpostiosoite on jo käytössä"
+
+#: html/Admin/Elements/ModifyUser:42
+msgid "EmailAddress"
+msgstr "Sähköpostiosoite"
+
+#: html/Admin/Elements/ModifyUser:54
+msgid "EmailEncoding"
+msgstr "Sähköpostin koodaus"
+
+#: html/Admin/Elements/EditCustomField:36
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:53 html/User/Groups/Modify.html:53
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr ""
+
+#: html/Admin/Queues/Modify.html:84
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr "Aktiivinen (Rastin poistaminen asettaa työjonon ei-aktiiviseksi)"
+
+#: html/Admin/Elements/EditCustomFields:99
+msgid "Enabled Custom Fields"
+msgstr ""
+
+#: html/Admin/Queues/index.html:56
+msgid "Enabled Queues"
+msgstr "Aktiiviset työjonot"
+
+#: html/Admin/Elements/EditCustomField:90 html/Admin/Groups/Modify.html:117 html/Admin/Queues/Modify.html:138 html/Admin/Users/Modify.html:283 html/User/Groups/Modify.html:117
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr "Aktivoitu tila %1"
+
+#: lib/RT/CustomField_Overlay.pm:361
+msgid "Enter multiple values"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:358
+msgid "Enter one value"
+msgstr ""
+
+#: html/Ticket/Elements/EditLinks:112
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "Lisää työpyyntöjen numerot tai www-linkit. Käytä välilyöntiä erottimena syöttäessäsi useampaa numeroa tai linkkiä."
+
+#: html/Elements/Login:29 html/SelfService/Error.html:25 html/SelfService/Error.html:26
+msgid "Error"
+msgstr "Virhe"
+
+#: NOT FOUND IN SOURCE
+msgid "Error adding watcher"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr "Virhe parametreissa: Queue->AddWatcher"
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr "Virhe parametreissa: Queue->DelWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1356
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr "Virhe parametreissa: Ticket->AddWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1532
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr "Virhe parametreissa: Ticket->DelWatcher"
+
+#: etc/initialdata:20
+msgid "Everyone"
+msgstr ""
+
+#: bin/rt-crontool:194
+msgid "Example:"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:64
+msgid "ExternalAuthId"
+msgstr "Ulkoinen autentikointitunnus"
+
+#: html/Admin/Elements/ModifyUser:58
+msgid "ExternalContactInfoId"
+msgstr "Ulkoinen yhteystietotunnus"
+
+#: html/Admin/Users/Modify.html:73
+msgid "Extra info"
+msgstr "Lisatieto"
+
+#: lib/RT/User_Overlay.pm:302
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr "'Etuoikeutettu' -pseudoryhmää ei löytynyt"
+
+#: lib/RT/User_Overlay.pm:309
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr "Ei-etuoikeutettu' -pseudoryhmää ei löytynyt"
+
+#: bin/rt-crontool:138
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr ""
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "Helmi"
+
+#: NOT FOUND IN SOURCE
+msgid "February"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr "Fin"
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:59 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "Loppuprioriteetti"
+
+#: lib/RT/Ticket_Overlay.pm:1162
+msgid "FinalPriority"
+msgstr ""
+
+#: html/Admin/Queues/People.html:61 html/Ticket/Elements/EditPeople:34
+msgid "Find group whose"
+msgstr ""
+
+#: html/Elements/Quicksearch:25
+msgid "Find new/open tickets"
+msgstr "Etsi uudet/avoimet työpyynnöt"
+
+#: html/Admin/Queues/People.html:57 html/Admin/Users/index.html:46 html/Ticket/Elements/EditPeople:30
+msgid "Find people whose"
+msgstr "Etsi käyttäjät joiden"
+
+#: html/Search/Listing.html:108
+msgid "Find tickets"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Finish Approval"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:58
+msgid "First"
+msgstr "Ensimmäinen"
+
+#: html/Search/Listing.html:41
+msgid "First page"
+msgstr "Viimeinen sivu"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr ""
+
+#: html/Search/Bulk.html:87
+msgid "Force change"
+msgstr "Pakota muutos"
+
+#: html/Search/Listing.html:106
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:868
+msgid "Found Object"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:44
+msgid "FreeformContactInfo"
+msgstr "Vapaamuotoiset yhteystiedot"
+
+#: lib/RT/CustomField_Overlay.pm:38
+msgid "FreeformMultiple"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformSingle"
+msgstr ""
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "Pe"
+
+#: html/Ticket/Elements/ShowHistory:41 html/Ticket/Elements/ShowHistory:51
+msgid "Full headers"
+msgstr "Kokonaiset otsikot"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:595
+#. ($New->Name)
+msgid "Given to %1"
+msgstr ""
+
+#: html/Admin/Elements/Tabs:41 html/Admin/index.html:38
+msgid "Global"
+msgstr "Globaali"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Keyword Selections"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr "Globaalit laput"
+
+#: html/Admin/Elements/SelectTemplate:38
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:75 html/Admin/Queues/People.html:59 html/Admin/Queues/People.html:63 html/Admin/Queues/index.html:44 html/Admin/Users/index.html:49 html/Ticket/Elements/EditPeople:32 html/Ticket/Elements/EditPeople:36 html/index.html:41
+msgid "Go!"
+msgstr "Ok!"
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr "Hyvä PGP allekirjoitus käyttäjältä %1\\n"
+
+#: html/Search/Listing.html:50
+msgid "Goto page"
+msgstr "Siirry sivulle"
+
+#: html/Elements/GotoTicket:25 html/SelfService/Elements/GotoTicket:25
+msgid "Goto ticket"
+msgstr "Siirry työpyyntöön"
+
+#: html/Ticket/Elements/AddWatchers:46 html/User/Elements/DelegateRights:78
+msgid "Group"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr "Ryhmä %1 %2: %3"
+
+#: html/Admin/Elements/GroupTabs:45 html/Admin/Elements/QueueTabs:57 html/Admin/Elements/SystemTabs:44 html/Admin/Global/index.html:55
+msgid "Group Rights"
+msgstr "Ryhmän oikeudet"
+
+#: lib/RT/Group_Overlay.pm:965
+msgid "Group already has member"
+msgstr "Ryhmässä on jo jäsen"
+
+#: NOT FOUND IN SOURCE
+msgid "Group could not be created."
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:77
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:497
+msgid "Group created"
+msgstr "Ryhmä luotu"
+
+#: lib/RT/Group_Overlay.pm:1133
+msgid "Group has no such member"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:945 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1429 lib/RT/Ticket_Overlay.pm:1507
+msgid "Group not found"
+msgstr "Ryhmää ei löydetty"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr "Ryhmää ei löydetty.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr "Ryhmää ei määritelty.\\n"
+
+#: html/Admin/Elements/SelectNewGroupMembers:35 html/Admin/Elements/Tabs:35 html/Admin/Groups/Members.html:64 html/Admin/Queues/People.html:83 html/Admin/index.html:32 html/User/Groups/Members.html:67
+msgid "Groups"
+msgstr "Ryhmät"
+
+#: lib/RT/Group_Overlay.pm:971
+msgid "Groups can't be members of their members"
+msgstr "Ryhmät eivät voi olla jäsentensä jäseniä"
+
+#: lib/RT/Interface/CLI.pm:73 lib/RT/Interface/CLI.pm:73
+msgid "Hello!"
+msgstr "Hei!"
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr "Hei, %1"
+
+#: html/Ticket/Elements/ShowHistory:30 html/Ticket/Elements/Tabs:88
+msgid "History"
+msgstr "Historia"
+
+#: html/Admin/Elements/ModifyUser:68
+msgid "HomePhone"
+msgstr "Kotipuhelin"
+
+#: html/Elements/Tabs:46
+msgid "Homepage"
+msgstr "Kotisivu"
+
+#: lib/RT/Base.pm:74
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "I have [quant,_1,concrete mixer]."
+msgstr ""
+
+#: html/Ticket/Elements/ShowBasics:27 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr "Numero"
+
+#: html/Admin/Users/Modify.html:44 html/User/Prefs.html:39
+msgid "Identity"
+msgstr "Identiteetti"
+
+#: etc/upgrade/2.1.71:86
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr ""
+
+#: bin/rt-crontool:190
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr ""
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "If you've updated anything above, be sure to"
+msgstr "Jos olet muuttanut tietoja, muista tallentaa"
+
+#: lib/RT/Interface/Web.pm:860
+msgid "Illegal value for %1"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:863
+msgid "Immutable field"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:74
+msgid "Include disabled custom fields in listing."
+msgstr ""
+
+#: html/Admin/Queues/index.html:43
+msgid "Include disabled queues in listing."
+msgstr "Sisällytä listaukseen myös ei-aktiiviset työjonot."
+
+#: html/Admin/Users/index.html:47
+msgid "Include disabled users in search."
+msgstr "Sisällytä listaukseen myös ei-aktiiviset käyttäjät."
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr "Alkuprioriteetti"
+
+#: lib/RT/Ticket_Overlay.pm:1161 lib/RT/Ticket_Overlay.pm:1163
+msgid "InitialPriority"
+msgstr ""
+
+#: lib/RT/ScripAction_Overlay.pm:105
+msgid "Input error"
+msgstr "Virhe syötteessä"
+
+#: NOT FOUND IN SOURCE
+msgid "Interest noted"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3729
+msgid "Internal Error"
+msgstr ""
+
+#: lib/RT/Record.pm:143
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:644
+msgid "Invalid Group Type"
+msgstr "Ryhmän tyyppi ei kelpaa"
+
+#: lib/RT/Principal_Overlay.pm:128
+msgid "Invalid Right"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Invalid Type"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:865
+msgid "Invalid data"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:438
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr "Omistaja ei kelpaa. Asetetaan oletusasetusten mukaan 'eikukaan'"
+
+#: lib/RT/Scrip_Overlay.pm:134 lib/RT/Template_Overlay.pm:251
+msgid "Invalid queue"
+msgstr "Kelpaamaton työjono"
+
+#: lib/RT/ACE_Overlay.pm:244 lib/RT/ACE_Overlay.pm:253 lib/RT/ACE_Overlay.pm:259 lib/RT/ACE_Overlay.pm:270 lib/RT/ACE_Overlay.pm:275
+msgid "Invalid right"
+msgstr "Kelpaamaton oikeus"
+
+#: lib/RT/Record.pm:118
+#. ($key)
+msgid "Invalid value for %1"
+msgstr "Kelpaamaton arvo kohteelle %1"
+
+#: lib/RT/Ticket_Overlay.pm:3367
+msgid "Invalid value for custom field"
+msgstr "Kelpaamaton arvo kentälle"
+
+#: lib/RT/Ticket_Overlay.pm:345
+msgid "Invalid value for status"
+msgstr "Kelpaamaton arvo tilalle"
+
+#: bin/rt-crontool:191
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr ""
+
+#: bin/rt-crontool:192
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr ""
+
+#: bin/rt-crontool:163
+msgid "It takes several arguments:"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr ""
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "Tammi"
+
+#: NOT FOUND IN SOURCE
+msgid "January"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "Join or leave this group"
+msgstr ""
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "Heinä"
+
+#: NOT FOUND IN SOURCE
+msgid "July"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:99
+msgid "Jumbo"
+msgstr "Jumbo"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "Kesä"
+
+#: NOT FOUND IN SOURCE
+msgid "June"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr "Avainsana"
+
+#: html/Admin/Elements/ModifyUser:52
+msgid "Lang"
+msgstr "Keili"
+
+#: html/Ticket/Elements/Tabs:73
+msgid "Last"
+msgstr "Viimeinen"
+
+#: html/Ticket/Elements/EditDates:38 html/Ticket/Elements/ShowDates:39
+msgid "Last Contact"
+msgstr "Viimeinen yhteydenotto"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Contacted"
+msgstr "Viimeksi otettu yhteyttä"
+
+#: html/Search/Elements/TicketHeader:41
+msgid "Last Notified"
+msgstr ""
+
+#: html/Elements/SelectDateType:30
+msgid "Last Updated"
+msgstr "Viimeksi päivitetty"
+
+#: NOT FOUND IN SOURCE
+msgid "LastUpdated"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr "Vasen"
+
+#: html/Admin/Users/Modify.html:83
+msgid "Let this user access RT"
+msgstr "Päästä tämä käyttäjä sisään RT:een"
+
+#: html/Admin/Users/Modify.html:87
+msgid "Let this user be granted rights"
+msgstr "Tälle käyttäjälle voidaan antaa oikeuksia"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr "Rajoitetaan omistajaa %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr "Rajoitetaan työjonoa %1 %2"
+
+#: lib/RT/Ticket_Overlay.pm:2697
+msgid "Link already exists"
+msgstr "Linkki on jo olemassa"
+
+#: lib/RT/Ticket_Overlay.pm:2709
+msgid "Link could not be created"
+msgstr "Linkkiä ei voitu luoda"
+
+#: lib/RT/Ticket_Overlay.pm:2717 lib/RT/Ticket_Overlay.pm:2727
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr "Linkki luotu (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2638
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr "Linkki poistettu (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2644
+msgid "Link not found"
+msgstr "Linkkiä ei löydetty"
+
+#: html/Ticket/ModifyLinks.html:25 html/Ticket/ModifyLinks.html:29
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr "Linkitä työpyyntö #%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Link ticket %1"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:97
+msgid "Links"
+msgstr "Linkit"
+
+#: html/Admin/Users/Modify.html:114 html/User/Prefs.html:85
+msgid "Location"
+msgstr "Sijainti"
+
+#: lib/RT.pm:158
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr "Lokihakemistoa %1 ei löytynyt tai kirkoittaminen ei onnistunut.\\n RT ei voi toimia."
+
+#: html/Elements/Header:57
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "Kirjautunut sisään tunnuksella %1"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:25 html/Elements/Login:34 html/Elements/Login:45
+msgid "Login"
+msgstr "Kirjaudu sisään"
+
+#: html/Elements/Header:54
+msgid "Logout"
+msgstr "Kirjaudu ulos"
+
+#: html/Search/Bulk.html:86
+msgid "Make Owner"
+msgstr "Aseta omistaja"
+
+#: html/Search/Bulk.html:102
+msgid "Make Status"
+msgstr "Aseta tila"
+
+#: html/Search/Bulk.html:109
+msgid "Make date Due"
+msgstr "Aseta mennessä -aika"
+
+#: html/Search/Bulk.html:110
+msgid "Make date Resolved"
+msgstr "Aseta päätetty -aika"
+
+#: html/Search/Bulk.html:107
+msgid "Make date Started"
+msgstr "Aseta aloitettu -aika"
+
+#: html/Search/Bulk.html:106
+msgid "Make date Starts"
+msgstr "Aseta alkaa -aika"
+
+#: html/Search/Bulk.html:108
+msgid "Make date Told"
+msgstr "Aseta oltu yhteydessä -aika"
+
+#: html/Search/Bulk.html:99
+msgid "Make priority"
+msgstr "Aseta prioriteetti"
+
+#: html/Search/Bulk.html:100
+msgid "Make queue"
+msgstr "Aseta työjono"
+
+#: html/Search/Bulk.html:98
+msgid "Make subject"
+msgstr "Aseta otsikko"
+
+#: html/Admin/index.html:33
+msgid "Manage groups and group membership"
+msgstr ""
+
+#: html/Admin/index.html:39
+msgid "Manage properties and configuration which apply to all queues"
+msgstr ""
+
+#: html/Admin/index.html:36
+msgid "Manage queues and queue-specific properties"
+msgstr ""
+
+#: html/Admin/index.html:30
+msgid "Manage users and passwords"
+msgstr ""
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "Maasis"
+
+#: NOT FOUND IN SOURCE
+msgid "March"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "May"
+msgstr ""
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "Touko"
+
+#: lib/RT/Group_Overlay.pm:982
+msgid "Member added"
+msgstr "Jäsen lisätty"
+
+#: lib/RT/Group_Overlay.pm:1140
+msgid "Member deleted"
+msgstr "Jäsen poistettu"
+
+#: lib/RT/Group_Overlay.pm:1144
+msgid "Member not deleted"
+msgstr "Jäsentä ei poistettu"
+
+#: html/Elements/SelectLinkType:26
+msgid "Member of"
+msgstr "Jäsen:"
+
+#: NOT FOUND IN SOURCE
+msgid "MemberOf"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:42 html/User/Elements/GroupTabs:42
+msgid "Members"
+msgstr "Jäsenet"
+
+#: lib/RT/Ticket_Overlay.pm:2843
+msgid "Merge Successful"
+msgstr "Yhdistäminen onnistui"
+
+#: lib/RT/Ticket_Overlay.pm:2804
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "Yhdistäminen epäonnistui. EffectiveId:n arvoa ei pystytty asettamaan"
+
+#: html/Ticket/Elements/EditLinks:115
+msgid "Merge into"
+msgstr "Yhdistä"
+
+#: html/Ticket/Update.html:102
+msgid "Message"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:867
+msgid "Missing a primary key?: %1"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:169 html/User/Prefs.html:54
+msgid "Mobile"
+msgstr "Käsipuhelin"
+
+#: html/Admin/Elements/ModifyUser:72
+msgid "MobilePhone"
+msgstr "Käsipuhelin"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify Access Control List"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Custom Field %1"
+msgstr "Muokkaa kenttää %1"
+
+#: html/Admin/Global/CustomFields.html:44 html/Admin/Global/index.html:51
+msgid "Modify Custom Fields which apply to all queues"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "Modify Scrip templates for this queue"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "Modify Scrips for this queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify System ACLS"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr ""
+
+#: html/Admin/Queues/CustomField.html:45
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:53
+msgid "Modify a CustomField which applies to all queues"
+msgstr ""
+
+#: html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr ""
+
+#: html/Admin/Global/Scrip.html:48
+msgid "Modify a scrip which applies to all queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify dates for # %1"
+msgstr ""
+
+#: html/Ticket/ModifyDates.html:25 html/Ticket/ModifyDates.html:29
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr "Muokkaa työpyynnön #%1 päiviä"
+
+#: html/Ticket/ModifyDates.html:35
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr "Muokkaa työpyynnön #%1 päiviä"
+
+#: html/Admin/Global/GroupRights.html:25 html/Admin/Global/GroupRights.html:28 html/Admin/Global/index.html:56
+msgid "Modify global group rights"
+msgstr "Muokkaa ryhmien globaaleja oikeuksia"
+
+#: html/Admin/Global/GroupRights.html:33
+msgid "Modify global group rights."
+msgstr "Muokkaa ryhmien globaaleja oikeuksia."
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for groups"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for users"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr "Muokkaa globaaleja lappuja"
+
+#: html/Admin/Global/UserRights.html:25 html/Admin/Global/UserRights.html:28 html/Admin/Global/index.html:60
+msgid "Modify global user rights"
+msgstr ""
+
+#: html/Admin/Global/UserRights.html:33
+msgid "Modify global user rights."
+msgstr "Muokkaa käyttäjien globaaleja oikeuksia."
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "Modify group metadata or delete group"
+msgstr ""
+
+#: html/Admin/Groups/GroupRights.html:25 html/Admin/Groups/GroupRights.html:29 html/Admin/Groups/GroupRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr "Muokkaa ryhmän %1 oikeuksia."
+
+#: html/Admin/Queues/GroupRights.html:25 html/Admin/Queues/GroupRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr "Muokkaa ryhmän oikeuksia työjonossa %1"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Modify membership roster for this group"
+msgstr ""
+
+#: lib/RT/System.pm:61
+msgid "Modify one's own RT account"
+msgstr ""
+
+#: html/Admin/Queues/People.html:25 html/Admin/Queues/People.html:29
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr "Muokkaa työjonoon %1 liittyviä käyttäjiä"
+
+#: html/Ticket/ModifyPeople.html:25 html/Ticket/ModifyPeople.html:29 html/Ticket/ModifyPeople.html:35
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr "Muokkaa työpyyntöön %1 liittyviä käyttäjiä"
+
+#: html/Admin/Queues/Scrips.html:44
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr "Muokkaa työjonoon %1 liittyviä lappuja"
+
+#: html/Admin/Global/Scrips.html:44 html/Admin/Global/index.html:42
+msgid "Modify scrips which apply to all queues"
+msgstr ""
+
+#: html/Admin/Global/Template.html:25 html/Admin/Global/Template.html:30 html/Admin/Global/Template.html:81 html/Admin/Queues/Template.html:78
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr "Muokkaa pohjaa %1"
+
+#: html/Admin/Global/Templates.html:44
+msgid "Modify templates which apply to all queues"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:87 html/User/Groups/Modify.html:86
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr "Muokkaa työjonoa %1"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Modify the queue watchers"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:236
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr "Muokkaa käyttäjää %1"
+
+#: html/Ticket/ModifyAll.html:37
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "Muokkaa työpyyntöä #%1"
+
+#: html/Ticket/Modify.html:25 html/Ticket/Modify.html:28 html/Ticket/Modify.html:34
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "Muokkaa työpyyntöä #%1"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Modify tickets"
+msgstr ""
+
+#: html/Admin/Groups/UserRights.html:25 html/Admin/Groups/UserRights.html:29 html/Admin/Groups/UserRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr "Muokkaa ryhmän %1 käyttäjien oikeuksia"
+
+#: html/Admin/Queues/UserRights.html:25 html/Admin/Queues/UserRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr "Muokkaa työjonoon %1 liittyviä käyttäjien oikeuksia"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr "Muokkaa työpyynnön %1 katselijoita"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyACL"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "ModifyOwnMembership"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "ModifyQueueWatchers"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "ModifyScrips"
+msgstr ""
+
+#: lib/RT/System.pm:61
+msgid "ModifySelf"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "ModifyTemplate"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "ModifyTicket"
+msgstr ""
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "Ma"
+
+#: html/Ticket/Elements/ShowRequestor:42
+#. ($name)
+msgid "More about %1"
+msgstr "Lisätietoa: %1"
+
+#: html/Admin/Elements/EditCustomFields:61
+msgid "Move down"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:53
+msgid "Move up"
+msgstr ""
+
+#: html/Admin/Elements/SelectSingleOrMultiple:27
+msgid "Multiple"
+msgstr "Monta"
+
+#: lib/RT/User_Overlay.pm:179
+msgid "Must specify 'Name' attribute"
+msgstr "'Nimi' täytyy määritellä"
+
+#: NOT FOUND IN SOURCE
+msgid "My Approvals"
+msgstr ""
+
+#: html/Approvals/index.html:25 html/Approvals/index.html:26
+msgid "My approvals"
+msgstr ""
+
+#: html/Admin/Elements/AddCustomFieldValue:26 html/Admin/Elements/EditCustomField:32 html/Admin/Elements/ModifyTemplate:28 html/Admin/Elements/ModifyUser:30 html/Admin/Groups/Modify.html:44 html/Elements/SelectGroups:26 html/Elements/SelectUsers:28 html/User/Groups/Modify.html:44
+msgid "Name"
+msgstr "Nimi"
+
+#: lib/RT/User_Overlay.pm:186
+msgid "Name in use"
+msgstr "Nimi on käytössä"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr ""
+
+#: html/Ticket/Elements/ShowDates:52
+msgid "Never"
+msgstr ""
+
+#: html/Elements/Quicksearch:30
+msgid "New"
+msgstr "Uusi"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:93 html/User/Prefs.html:65
+msgid "New Password"
+msgstr "Uusi salasana"
+
+#: etc/initialdata:311 etc/upgrade/2.1.71:16
+msgid "New Pending Approval"
+msgstr ""
+
+#: html/Ticket/Elements/EditLinks:111
+msgid "New Relationships"
+msgstr "Uusi linkki"
+
+#: html/Ticket/Elements/Tabs:36
+msgid "New Search"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:41 html/Admin/Global/CustomFields.html:39 html/Admin/Queues/CustomField.html:52 html/Admin/Queues/CustomFields.html:40
+msgid "New custom field"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:54 html/User/Elements/GroupTabs:52
+msgid "New group"
+msgstr ""
+
+#: html/SelfService/Prefs.html:32
+msgid "New password"
+msgstr "Uusi salasana"
+
+#: lib/RT/User_Overlay.pm:639
+msgid "New password notification sent"
+msgstr "Uusi salasana"
+
+#: html/Admin/Elements/QueueTabs:70
+msgid "New queue"
+msgstr ""
+
+#: html/SelfService/Elements/Tabs:63
+msgid "New request"
+msgstr "Uusi työpyyntö"
+
+#: html/Admin/Elements/SelectRights:42
+msgid "New rights"
+msgstr "Uudet oikeudet"
+
+#: html/Admin/Global/Scrip.html:40 html/Admin/Global/Scrips.html:39 html/Admin/Queues/Scrip.html:43 html/Admin/Queues/Scrips.html:53
+msgid "New scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "New search"
+msgstr "Uusi haku"
+
+#: html/Admin/Global/Template.html:60 html/Admin/Global/Templates.html:39 html/Admin/Queues/Template.html:58 html/Admin/Queues/Templates.html:46
+msgid "New template"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2771
+msgid "New ticket doesn't exist"
+msgstr "Uutta työpyyntöä ei löydy"
+
+#: html/Admin/Elements/UserTabs:52
+msgid "New user"
+msgstr ""
+
+#: html/Admin/Elements/CreateUserCalled:26
+msgid "New user called"
+msgstr "Uusi käyttäjä pyydetty"
+
+#: html/Admin/Queues/People.html:55 html/Ticket/Elements/EditPeople:29
+msgid "New watchers"
+msgstr "Uusi tarkkailija"
+
+#: html/Admin/Users/Prefs.html:42
+msgid "New window setting"
+msgstr "Uusi ikkunan asetus"
+
+#: html/Ticket/Elements/Tabs:69
+msgid "Next"
+msgstr "Seuraava"
+
+#: html/Search/Listing.html:48
+msgid "Next page"
+msgstr "Seuraava sivu"
+
+#: html/Admin/Elements/ModifyUser:50
+msgid "NickName"
+msgstr "Lempinimi"
+
+#: html/Admin/Users/Modify.html:63 html/User/Prefs.html:46
+msgid "Nickname"
+msgstr "Lempinimi"
+
+#: html/Admin/Elements/EditCustomField:73 html/Admin/Elements/EditCustomFields:105
+msgid "No CustomField"
+msgstr "Ei kenttiä"
+
+#: html/Admin/Groups/GroupRights.html:84 html/Admin/Groups/UserRights.html:71
+msgid "No Group defined"
+msgstr "Ryhmää ei ole määritelty"
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:68
+msgid "No Queue defined"
+msgstr "Työjonoa ei ole määritelty"
+
+#: bin/rt-crontool:56
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr "Käyttäjää ei löydy. Ole hyvä ja ota yhteyttä RT:n ylläpitäjään.\\n"
+
+#: html/Admin/Global/Template.html:79 html/Admin/Queues/Template.html:76
+msgid "No Template"
+msgstr "Ei pohjaa"
+
+#: bin/rt-commit-handler:764
+msgid "No Ticket specified. Aborting ticket "
+msgstr "Työpyyntöä ei määritelty. Poistutaan työpyynnöstä"
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr "Työpyyntöä ei määritelty. Poistutaan työpyynnön muokkauksesta\\n\\n"
+
+#: html/Approvals/Elements/Approve:47
+msgid "No action"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:862
+msgid "No column specified"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr "Komentoa ei löytynyt\\n"
+
+#: html/Elements/ViewUser:36 html/Ticket/Elements/ShowRequestor:45
+msgid "No comment entered about this user"
+msgstr "Tälle käyttäjälle ei ole annettu kommentteja"
+
+#: lib/RT/Ticket_Overlay.pm:2189 lib/RT/Ticket_Overlay.pm:2257
+msgid "No correspondence attached"
+msgstr "Ei kirjeenvaihtoa liitettynä"
+
+#: lib/RT/Action/Generic.pm:150 lib/RT/Condition/Generic.pm:176 lib/RT/Search/ActiveTicketsInQueue.pm:56 lib/RT/Search/Generic.pm:113
+#. (ref $self)
+msgid "No description for %1"
+msgstr "Ei kuvausta kohteelle %1"
+
+#: lib/RT/Users_Overlay.pm:151
+msgid "No group specified"
+msgstr "Ryhmää ei ole määritelty"
+
+#: lib/RT/User_Overlay.pm:857
+msgid "No password set"
+msgstr "Salasanaa ei ole asetettu"
+
+#: lib/RT/Queue_Overlay.pm:259
+msgid "No permission to create queues"
+msgstr "Ei oikeutta luoda kyselyitä"
+
+#: lib/RT/Ticket_Overlay.pm:341
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:151
+msgid "No permission to create users"
+msgstr "Ei oikeutta luoda käyttäjiä"
+
+#: html/SelfService/Display.html:174
+msgid "No permission to display that ticket"
+msgstr "Ei oikeutta tarkastella tätä työpyyntöä"
+
+#: html/SelfService/Update.html:55
+msgid "No permission to view update ticket"
+msgstr "Ei oikeutta päivittää tätä työpyyntöä"
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1488
+msgid "No principal specified"
+msgstr "Toimeksiantajaa ei ole määritelty"
+
+#: html/Admin/Queues/People.html:154 html/Admin/Queues/People.html:164
+msgid "No principals selected."
+msgstr "Johtajia ei ole valittu."
+
+#: html/Admin/Queues/index.html:35
+msgid "No queues matching search criteria found."
+msgstr "Yhtään hakukriteerit täyttävää työpyyntöä ei löytynyt."
+
+#: html/Admin/Elements/SelectRights:81
+msgid "No rights found"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:33
+msgid "No rights granted."
+msgstr "Ei oikeuksia"
+
+#: html/Search/Bulk.html:149
+msgid "No search to operate on."
+msgstr "Ei hakua jonka kanssa työskennellä"
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr "Työpyynnön numeroa ei ole määritelty"
+
+#: lib/RT/Transaction_Overlay.pm:480 lib/RT/Transaction_Overlay.pm:518
+msgid "No transaction type specified"
+msgstr "Toiminnon tyyppiä ei ole määritelty"
+
+#: NOT FOUND IN SOURCE
+msgid "No user or email address specified"
+msgstr ""
+
+#: html/Admin/Users/index.html:36
+msgid "No users matching search criteria found."
+msgstr "Yhtään hakukriteerit täyttävää käyttäjää ei löytynyt."
+
+#: bin/rt-commit-handler:644
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr "Ei kelpaa RT käyttäjäksi. RT cvs käsittelijä irrottautuu. Ole hyvä ja ota yhteyttä RT:n ylläpitäjään.\\n"
+
+#: lib/RT/Interface/Web.pm:859
+msgid "No value sent to _Set!\\n"
+msgstr ""
+
+#: html/Search/Elements/TicketRow:37
+msgid "Nobody"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:864
+msgid "Nonexistant field?"
+msgstr ""
+
+#: html/Elements/Login:99
+msgid "Not logged in"
+msgstr ""
+
+#: html/Elements/Header:59 html/SelfService/Elements/Header:58
+msgid "Not logged in."
+msgstr "Et ole kirjautunut järjestelmään"
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "Ei asetettu"
+
+#: html/NoAuth/Reminder.html:27
+msgid "Not yet implemented."
+msgstr "Ei vielä implementoitu."
+
+#: html/Admin/Groups/Rights.html:25
+msgid "Not yet implemented...."
+msgstr "Ei vielä implementoitu..."
+
+#: html/Approvals/Elements/Approve:50
+msgid "Notes"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:642
+msgid "Notification could not be sent"
+msgstr "Ilmoitusta ei pystytty lähettämään"
+
+#: etc/initialdata:94
+msgid "Notify AdminCcs"
+msgstr ""
+
+#: etc/initialdata:90
+msgid "Notify AdminCcs as Comment"
+msgstr ""
+
+#: etc/initialdata:121
+msgid "Notify Other Recipients"
+msgstr ""
+
+#: etc/initialdata:117
+msgid "Notify Other Recipients as Comment"
+msgstr ""
+
+#: etc/initialdata:86
+msgid "Notify Owner"
+msgstr ""
+
+#: etc/initialdata:82
+msgid "Notify Owner as Comment"
+msgstr ""
+
+#: etc/initialdata:313 etc/upgrade/2.1.71:17
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr ""
+
+#: etc/initialdata:78
+msgid "Notify Requestors"
+msgstr ""
+
+#: etc/initialdata:104
+msgid "Notify Requestors and Ccs"
+msgstr ""
+
+#: etc/initialdata:99
+msgid "Notify Requestors and Ccs as Comment"
+msgstr ""
+
+#: etc/initialdata:113
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr ""
+
+#: etc/initialdata:109
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr ""
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "Marras"
+
+#: NOT FOUND IN SOURCE
+msgid "November"
+msgstr ""
+
+#: lib/RT/Record.pm:157
+msgid "Object could not be created"
+msgstr ""
+
+#: lib/RT/Record.pm:176
+msgid "Object created"
+msgstr ""
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "Loka"
+
+#: NOT FOUND IN SOURCE
+msgid "October"
+msgstr ""
+
+#: html/Elements/SelectDateRelation:35
+msgid "On"
+msgstr "-"
+
+#: etc/initialdata:155
+msgid "On Comment"
+msgstr ""
+
+#: etc/initialdata:148
+msgid "On Correspond"
+msgstr ""
+
+#: etc/initialdata:137
+msgid "On Create"
+msgstr ""
+
+#: etc/initialdata:169
+msgid "On Owner Change"
+msgstr ""
+
+#: etc/initialdata:177
+msgid "On Queue Change"
+msgstr ""
+
+#: etc/initialdata:183
+msgid "On Resolve"
+msgstr ""
+
+#: etc/initialdata:161
+msgid "On Status Change"
+msgstr ""
+
+#: etc/initialdata:142
+msgid "On Transaction"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:50
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:48
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr ""
+
+#: html/Elements/Quicksearch:31
+msgid "Open"
+msgstr "Avoin"
+
+#: html/Ticket/Elements/Tabs:136
+msgid "Open it"
+msgstr "Avaa"
+
+#: html/SelfService/Elements/Tabs:57
+msgid "Open requests"
+msgstr "Avoimet työpyynnöt"
+
+#: html/Admin/Users/Prefs.html:41
+msgid "Open tickets (from listing) in a new window"
+msgstr "Avoimet työpyynnöt (listasta) uudessa ikkunassa"
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in another window"
+msgstr "Avoimet työpyynnöt (listasta) toisessa ikkunassa"
+
+#: etc/initialdata:133
+msgid "Open tickets on correspondence"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:101
+msgid "Ordering and sorting"
+msgstr "Järjestäminen"
+
+#: html/Admin/Elements/ModifyUser:46 html/Admin/Users/Modify.html:117 html/Elements/SelectUsers:29 html/User/Prefs.html:86
+msgid "Organization"
+msgstr "Organisaatio"
+
+#: html/Approvals/Elements/Approve:34
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:55 html/Admin/Queues/Modify.html:69
+msgid "Over time, priority moves toward"
+msgstr "Ajan kuluessa prioriteetti muuttuu kohti"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Own tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "OwnTicket"
+msgstr ""
+
+#: etc/initialdata:38 html/Elements/MyRequests:32 html/SelfService/Elements/MyRequests:30 html/Ticket/Create.html:48 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/EditPeople:44 html/Ticket/Elements/ShowPeople:27 html/Ticket/Update.html:63 lib/RT/ACE_Overlay.pm:86 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "Omistaja"
+
+#: lib/RT/Ticket_Overlay.pm:3004
+#. ($OldOwnerObj->Name,  $NewOwnerObj->Name)
+msgid "Owner changed from %1 to %2"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:584
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr "Omistaja pakottamalla muutettu arvosta %1 arvoon %2"
+
+#: html/Search/Elements/PickRestriction:31
+msgid "Owner is"
+msgstr "Omistaja on"
+
+#: html/Admin/Users/Modify.html:174 html/User/Prefs.html:56
+msgid "Pager"
+msgstr "Hakulaite"
+
+#: html/Admin/Elements/ModifyUser:74
+msgid "PagerPhone"
+msgstr "Hakulaite puhelin"
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/EditLinks:127 html/Ticket/Elements/EditLinks:58 html/Ticket/Elements/ShowLinks:43
+msgid "Parents"
+msgstr "Isät"
+
+#: html/Elements/Login:43 html/User/Prefs.html:61
+msgid "Password"
+msgstr "Salasana"
+
+#: html/NoAuth/Reminder.html:25
+msgid "Password Reminder"
+msgstr "Salasanan muistuttaja"
+
+#: lib/RT/User_Overlay.pm:168 lib/RT/User_Overlay.pm:860
+msgid "Password too short"
+msgstr "Salasana liian lyhyt"
+
+#: html/Admin/Users/Modify.html:291 html/User/Prefs.html:172
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "Salasana: %1"
+
+#: html/Ticket/Elements/ShowSummary:43 html/Ticket/Elements/Tabs:96 html/Ticket/ModifyAll.html:51
+msgid "People"
+msgstr "Käyttäjät"
+
+#: etc/initialdata:126
+msgid "Perform a user-defined action"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:231 lib/RT/ACE_Overlay.pm:237 lib/RT/ACE_Overlay.pm:563 lib/RT/ACE_Overlay.pm:573 lib/RT/ACE_Overlay.pm:583 lib/RT/ACE_Overlay.pm:648 lib/RT/CurrentUser.pm:83 lib/RT/CurrentUser.pm:92 lib/RT/CustomField_Overlay.pm:445 lib/RT/CustomField_Overlay.pm:451 lib/RT/Group_Overlay.pm:1095 lib/RT/Group_Overlay.pm:1099 lib/RT/Group_Overlay.pm:1108 lib/RT/Group_Overlay.pm:1159 lib/RT/Group_Overlay.pm:1163 lib/RT/Group_Overlay.pm:1169 lib/RT/Group_Overlay.pm:426 lib/RT/Group_Overlay.pm:518 lib/RT/Group_Overlay.pm:596 lib/RT/Group_Overlay.pm:604 lib/RT/Group_Overlay.pm:701 lib/RT/Group_Overlay.pm:705 lib/RT/Group_Overlay.pm:711 lib/RT/Group_Overlay.pm:904 lib/RT/Group_Overlay.pm:908 lib/RT/Group_Overlay.pm:921 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:126 lib/RT/Scrip_Overlay.pm:137 lib/RT/Scrip_Overlay.pm:197 lib/RT/Scrip_Overlay.pm:430 lib/RT/Template_Overlay.pm:284 lib/RT/Template_Overlay.pm:88 lib/RT/Template_Overlay.pm:94 lib/RT/Ticket_Overlay.pm:1341 lib/RT/Ticket_Overlay.pm:1351 lib/RT/Ticket_Overlay.pm:1365 lib/RT/Ticket_Overlay.pm:1518 lib/RT/Ticket_Overlay.pm:1527 lib/RT/Ticket_Overlay.pm:1540 lib/RT/Ticket_Overlay.pm:1875 lib/RT/Ticket_Overlay.pm:2013 lib/RT/Ticket_Overlay.pm:2177 lib/RT/Ticket_Overlay.pm:2244 lib/RT/Ticket_Overlay.pm:2596 lib/RT/Ticket_Overlay.pm:2668 lib/RT/Ticket_Overlay.pm:2762 lib/RT/Ticket_Overlay.pm:2777 lib/RT/Ticket_Overlay.pm:2910 lib/RT/Ticket_Overlay.pm:3139 lib/RT/Ticket_Overlay.pm:3337 lib/RT/Ticket_Overlay.pm:3499 lib/RT/Ticket_Overlay.pm:3551 lib/RT/Ticket_Overlay.pm:3716 lib/RT/Transaction_Overlay.pm:468 lib/RT/Transaction_Overlay.pm:475 lib/RT/Transaction_Overlay.pm:504 lib/RT/Transaction_Overlay.pm:511 lib/RT/User_Overlay.pm:1334 lib/RT/User_Overlay.pm:562 lib/RT/User_Overlay.pm:597 lib/RT/User_Overlay.pm:853 lib/RT/User_Overlay.pm:941
+msgid "Permission Denied"
+msgstr "Pääsy kielletty"
+
+#: html/User/Elements/Tabs:35
+msgid "Personal Groups"
+msgstr ""
+
+#: html/User/Groups/index.html:30 html/User/Groups/index.html:40
+msgid "Personal groups"
+msgstr "Omat ryhmät"
+
+#: html/User/Elements/DelegateRights:37
+msgid "Personal groups:"
+msgstr "Omat ryhmät:"
+
+#: html/Admin/Users/Modify.html:156 html/User/Prefs.html:49
+msgid "Phone numbers"
+msgstr "Puhelinnumerot"
+
+#: html/Admin/Users/Rights.html:25
+msgid "Placeholder"
+msgstr "Paikanpitäjä"
+
+#: html/Elements/Header:52 html/Elements/Tabs:55 html/SelfService/Prefs.html:25 html/User/Prefs.html:25 html/User/Prefs.html:28
+msgid "Preferences"
+msgstr "Asetukset"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr "Asetukset"
+
+#: lib/RT/Action/Generic.pm:160
+msgid "Prepare Stubbed"
+msgstr "Valmistele tumppi"
+
+#: html/Ticket/Elements/Tabs:61
+msgid "Prev"
+msgstr "Edellinen"
+
+#: html/Search/Listing.html:44
+msgid "Previous page"
+msgstr "Edellinen sivu"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr "Pri"
+
+#: lib/RT/ACE_Overlay.pm:133 lib/RT/ACE_Overlay.pm:208 lib/RT/ACE_Overlay.pm:552
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:54 html/SelfService/Display.html:76 html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:54 html/Ticket/Elements/ShowBasics:39 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "Prioriteetti"
+
+#: html/Admin/Elements/ModifyQueue:51 html/Admin/Queues/Modify.html:65
+msgid "Priority starts at"
+msgstr "Prioriteetti alkaa arvosta"
+
+#: etc/initialdata:25
+msgid "Privileged"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:271 html/User/Prefs.html:163
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr "Etuoikeutuksen tila: &1"
+
+#: html/Admin/Users/index.html:62
+msgid "Privileged users"
+msgstr "Etuoikeutetut käyttäjät"
+
+#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59
+msgid "Pseudogroup for internal use"
+msgstr ""
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Elements/Quicksearch:29 html/Search/Elements/PickRestriction:46 html/SelfService/Create.html:35 html/SelfService/Display.html:68 html/Ticket/Create.html:38 html/Ticket/Elements/EditBasics:64 html/Ticket/Elements/ShowBasics:43 html/User/Elements/DelegateRights:80 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "Työjono"
+
+#: html/Admin/Queues/CustomField.html:42 html/Admin/Queues/Scrip.html:50 html/Admin/Queues/Scrips.html:46 html/Admin/Queues/Templates.html:43
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr "Työjonoa '%1' ei löytynyt"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Keyword Selections"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:31 html/Admin/Queues/Modify.html:43
+msgid "Queue Name"
+msgstr "Työjonon nimi"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr "Työjonon laput"
+
+#: lib/RT/Queue_Overlay.pm:263
+msgid "Queue already exists"
+msgstr "Työjono on jo olemassa"
+
+#: lib/RT/Queue_Overlay.pm:272 lib/RT/Queue_Overlay.pm:278
+msgid "Queue could not be created"
+msgstr "Työjonoa ei voitu luoda"
+
+#: html/Ticket/Create.html:209
+msgid "Queue could not be loaded."
+msgstr "Työjonoa ei voitu ladata."
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:282
+msgid "Queue created"
+msgstr "Työjono luotu"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue is not specified."
+msgstr ""
+
+#: html/SelfService/Display.html:129
+msgid "Queue not found"
+msgstr "Työjonoa ei löytynyt"
+
+#: html/Admin/Elements/Tabs:38 html/Admin/index.html:35
+msgid "Queues"
+msgstr "Työjonot"
+
+#: html/Elements/Login:34
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr "RT %1 - %2"
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr "RT %1, tekijä <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: html/Admin/index.html:25 html/Admin/index.html:26
+msgid "RT Administration"
+msgstr "RT Ylläpito"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr "RT Virhe tunnistamisessa"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr "RT palautus: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr "RT Konfiguraatiovirhe"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr "RT Kriittinen virhe. Viestiä ei tallennettu!"
+
+#: html/Elements/Error:41 html/SelfService/Error.html:41
+msgid "RT Error"
+msgstr "RT Virhe"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr "RT Sai sähköpostin (%1) itseltään."
+
+#: NOT FOUND IN SOURCE
+msgid "RT Recieved mail (%1) from itself."
+msgstr ""
+
+#: html/SelfService/Closed.html:25
+msgid "RT Self Service / Closed Tickets"
+msgstr "RT Itsepalvelu / Suljetut työpyynnöt"
+
+#: html/index.html:25 html/index.html:28
+msgid "RT at a glance"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr "RT Ei pystynyt tunnistamaan sinua"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr "RT ei löytänyt tilaajaa ulkopuolisesta tietokannasta"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr "RT ei löytänyt työjonoa: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr "RT ei pystynyt tarkistamaan tätä PGP allekirjoitusta.\\n"
+
+#: html/Elements/PageLayout:26
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr "RT on prosessoinut antamasi komennot"
+
+#: html/Elements/Login:83
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT on tekijänoikeuslain alainen, &copy; 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;. Se on jakelussa seuraavalla lisenssillä: <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr "RT luulee että tämä viesti on palautus"
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr "RT prosessoi tämän viestin kuten se olisi allekirjoittamaton."
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr "RT:n sähköpostiohjaus moodi vaatii PGP tunnistamista. Et allekirjoittanut (PGP) viestiä tai allekirjoitustasi ei pystytty varmistamaan."
+
+#: html/Admin/Users/Modify.html:58 html/Admin/Users/Prefs.html:52 html/User/Prefs.html:44
+msgid "Real Name"
+msgstr "Oikea nimi"
+
+#: html/Admin/Elements/ModifyUser:48
+msgid "RealName"
+msgstr "Oikea nimi"
+
+#: html/Ticket/Create.html:185 html/Ticket/Elements/EditLinks:139 html/Ticket/Elements/EditLinks:94 html/Ticket/Elements/ShowLinks:63
+msgid "Referred to by"
+msgstr "Viitattu jostakin"
+
+#: html/Elements/SelectLinkType:28 html/Ticket/Create.html:184 html/Ticket/Elements/EditLinks:135 html/Ticket/Elements/EditLinks:80 html/Ticket/Elements/ShowLinks:55
+msgid "Refers to"
+msgstr "Viittaus johonkin"
+
+#: NOT FOUND IN SOURCE
+msgid "RefersTo"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr "Päivitä"
+
+#: html/Search/Elements/PickRestriction:27
+msgid "Refine search"
+msgstr "Päivitä haku"
+
+#: html/Elements/Refresh:36
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "Päivitä tämä sivu %1 minuutin välein"
+
+#: html/Ticket/Create.html:174 html/Ticket/Elements/ShowSummary:60 html/Ticket/ModifyAll.html:57
+msgid "Relationships"
+msgstr "Linkit"
+
+#: html/Search/Bulk.html:93
+msgid "Remove AdminCc"
+msgstr "Poista kopio ylläpidolle"
+
+#: html/Search/Bulk.html:91
+msgid "Remove Cc"
+msgstr "Poista kopio"
+
+#: html/Search/Bulk.html:89
+msgid "Remove Requestor"
+msgstr "Poista tilaaja"
+
+#: html/Ticket/Elements/ShowTransaction:173 html/Ticket/Elements/Tabs:122
+msgid "Reply"
+msgstr "Vastaa"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Reply to tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "ReplyToTicket"
+msgstr ""
+
+#: etc/initialdata:44 html/Ticket/Update.html:40 lib/RT/ACE_Overlay.pm:87
+msgid "Requestor"
+msgstr "Tilaaja"
+
+#: html/Search/Elements/PickRestriction:38
+msgid "Requestor email address"
+msgstr "Tilaajan sähköpostiosoite"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RequestorAddresses"
+msgstr ""
+
+#: html/SelfService/Create.html:43 html/SelfService/Display.html:42 html/Ticket/Create.html:56 html/Ticket/Elements/EditPeople:48 html/Ticket/Elements/ShowPeople:31
+msgid "Requestors"
+msgstr "Tilaajat"
+
+#: html/Admin/Elements/ModifyQueue:61 html/Admin/Queues/Modify.html:75
+msgid "Requests should be due in"
+msgstr "Työpyyntö tulisi suorittaa mennessä"
+
+#: html/Elements/Submit:62
+msgid "Reset"
+msgstr "Palauta"
+
+#: html/Admin/Users/Modify.html:159 html/User/Prefs.html:50
+msgid "Residence"
+msgstr "Asuinpaikka"
+
+#: html/Ticket/Elements/Tabs:132
+msgid "Resolve"
+msgstr "Päätä"
+
+#: html/Ticket/Update.html:133
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr ""
+
+#: etc/initialdata:302 html/Elements/SelectDateType:28 lib/RT/Ticket_Overlay.pm:1170
+msgid "Resolved"
+msgstr "Päätetty"
+
+#: html/Search/Bulk.html:123 html/Ticket/ModifyAll.html:73 html/Ticket/Update.html:73
+msgid "Response to requestors"
+msgstr "Vastaus tilaajille"
+
+#: html/Elements/ListActions:26
+msgid "Results"
+msgstr "Tulokset"
+
+#: html/Search/Elements/PickRestriction:105
+msgid "Results per page"
+msgstr "Tulosta sivulle"
+
+#: html/Admin/Elements/ModifyUser:33 html/Admin/Users/Modify.html:100 html/User/Prefs.html:72
+msgid "Retype Password"
+msgstr "Varmista salasana"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr "Oikeutta %1 ei löydetty %2  %3 laajuudessa %4 (%5)\\n"
+
+#: lib/RT/ACE_Overlay.pm:613
+msgid "Right Delegated"
+msgstr "Oikeus delegoitu"
+
+#: lib/RT/ACE_Overlay.pm:303
+msgid "Right Granted"
+msgstr "Oikeus delegoitu"
+
+#: lib/RT/ACE_Overlay.pm:161
+msgid "Right Loaded"
+msgstr "Oikeus ladattu"
+
+#: lib/RT/ACE_Overlay.pm:678 lib/RT/ACE_Overlay.pm:693
+msgid "Right could not be revoked"
+msgstr "Oikeutta ei voitu peruuttaa"
+
+#: html/User/Delegation.html:64
+msgid "Right not found"
+msgstr "Oikeutta ei löydetty"
+
+#: lib/RT/ACE_Overlay.pm:543 lib/RT/ACE_Overlay.pm:638
+msgid "Right not loaded."
+msgstr "Oikeutta ei ladattu"
+
+#: lib/RT/ACE_Overlay.pm:689
+msgid "Right revoked"
+msgstr "Oikeus peruutettu"
+
+#: html/Admin/Elements/UserTabs:41
+msgid "Rights"
+msgstr "Oikeudet"
+
+#: lib/RT/Interface/Web.pm:758
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:791
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr ""
+
+#: html/Admin/Global/GroupRights.html:51 html/Admin/Queues/GroupRights.html:52
+msgid "Roles"
+msgstr "Roolit"
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr ""
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "La"
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "Save Changes"
+msgstr "Tallenna muutokset"
+
+#: html/Ticket/ModifyLinks.html:39
+msgid "Save changes"
+msgstr "Tallenna muutokset"
+
+#: html/Admin/Global/Scrip.html:49
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:176
+msgid "Scrip Created"
+msgstr "Lappu luotu"
+
+#: html/Admin/Elements/EditScrips:84
+msgid "Scrip deleted"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:46 html/Admin/Elements/SystemTabs:33 html/Admin/Global/index.html:41
+msgid "Scrips"
+msgstr "Laput"
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr "Laput työjonolle %1\\n"
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr ""
+
+#: html/Elements/SimpleSearch:27 html/Search/Elements/PickRestriction:126 html/Ticket/Elements/Tabs:159
+msgid "Search"
+msgstr "Hae"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr "Hakukriteerit"
+
+#: html/Approvals/Elements/PendingMyApproval:39
+msgid "Search for approvals"
+msgstr ""
+
+#: bin/rt-crontool:188
+msgid "Security:"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "SeeQueue"
+msgstr ""
+
+#: html/Admin/Groups/index.html:40
+msgid "Select a group"
+msgstr "Valitse ryhmä"
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr "Valitse työjono"
+
+#: html/Admin/Users/index.html:25 html/Admin/Users/index.html:28
+msgid "Select a user"
+msgstr "Valitse käyttäjä"
+
+#: html/Admin/Global/CustomField.html:38 html/Admin/Global/CustomFields.html:36
+msgid "Select custom field"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:52 html/User/Elements/GroupTabs:50
+msgid "Select group"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:355
+msgid "Select multiple values"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:352
+msgid "Select one value"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:67
+msgid "Select queue"
+msgstr ""
+
+#: html/Admin/Global/Scrip.html:37 html/Admin/Global/Scrips.html:36 html/Admin/Queues/Scrip.html:40 html/Admin/Queues/Scrips.html:50
+msgid "Select scrip"
+msgstr ""
+
+#: html/Admin/Global/Template.html:57 html/Admin/Global/Templates.html:36 html/Admin/Queues/Template.html:55
+msgid "Select template"
+msgstr ""
+
+#: html/Admin/Elements/UserTabs:49
+msgid "Select user"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "SelectMultiple"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectSingle"
+msgstr ""
+
+#: html/SelfService/index.html:25
+msgid "Self Service"
+msgstr "Itsepalvelu"
+
+#: etc/initialdata:114
+msgid "Send mail to all watchers"
+msgstr ""
+
+#: etc/initialdata:110
+msgid "Send mail to all watchers as a \"comment\""
+msgstr ""
+
+#: etc/initialdata:105
+msgid "Send mail to requestors and Ccs"
+msgstr ""
+
+#: etc/initialdata:100
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr ""
+
+#: etc/initialdata:79
+msgid "Sends a message to the requestors"
+msgstr ""
+
+#: etc/initialdata:118 etc/initialdata:122
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr ""
+
+#: etc/initialdata:95
+msgid "Sends mail to the administrative Ccs"
+msgstr ""
+
+#: etc/initialdata:91
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr ""
+
+#: etc/initialdata:83 etc/initialdata:87
+msgid "Sends mail to the owner"
+msgstr ""
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "Syys"
+
+#: NOT FOUND IN SOURCE
+msgid "September"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr "Näytä tulokset"
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show approved requests"
+msgstr ""
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show basics"
+msgstr "Näytä perustiedot"
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show denied requests"
+msgstr ""
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show details"
+msgstr "Näytä yksityiskohdat"
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show pending requests"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:46
+msgid "Show requests awaiting other approvals"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Show ticket private commentary"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "Show ticket summaries"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ShowACL"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowScrips"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ShowTemplate"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "ShowTicket"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "ShowTicketComments"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:39 html/Admin/Users/Modify.html:191 html/Admin/Users/Prefs.html:32 html/SelfService/Prefs.html:37 html/User/Prefs.html:112
+msgid "Signature"
+msgstr "Allekirjoitus"
+
+#: html/SelfService/Elements/Header:52
+#. ($session{'CurrentUser'}->Name)
+msgid "Signed in as %1"
+msgstr ""
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Single"
+msgstr "Yksittäinen"
+
+#: html/Elements/Header:51
+msgid "Skip Menu"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFieldValues:31
+msgid "Sort key"
+msgstr "Järjestys"
+
+#: html/Search/Elements/PickRestriction:109
+msgid "Sort results by"
+msgstr "Järjestä tulokset"
+
+#: html/Admin/Elements/AddCustomFieldValue:25
+msgid "SortOrder"
+msgstr "Lajittelujärjestyt"
+
+#: NOT FOUND IN SOURCE
+msgid "Stalled"
+msgstr "Jäädytetty"
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr "Etusivu"
+
+#: html/Elements/SelectDateType:27 html/Ticket/Elements/EditDates:32 html/Ticket/Elements/ShowDates:35
+msgid "Started"
+msgstr "Aloitettu"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr "Aloitettu -aikaa '%1' ei pystytty tulkitsemaan"
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:27 html/Ticket/Elements/ShowDates:31
+msgid "Starts"
+msgstr "Alkaa"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr "Alkaa mennessä"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr "Alkaa -aikaa '%1' ei pystytty tulkitsemaan"
+
+#: html/Admin/Elements/ModifyUser:82 html/Admin/Users/Modify.html:138 html/User/Prefs.html:94
+msgid "State"
+msgstr "Tila"
+
+#: html/Elements/MyRequests:31 html/Elements/MyTickets:31 html/Search/Elements/PickRestriction:74 html/SelfService/Display.html:59 html/SelfService/Elements/MyRequests:29 html/SelfService/Update.html:31 html/Ticket/Create.html:42 html/Ticket/Elements/EditBasics:38 html/Ticket/Elements/ShowBasics:31 html/Ticket/Update.html:60 lib/RT/Ticket_Overlay.pm:1164 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "Tila"
+
+#: etc/initialdata:288
+msgid "Status Change"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:530
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr "Tila muutettu arvosta %1 arvoon %2"
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:147
+msgid "Steal"
+msgstr "Kaappaa"
+
+#: lib/RT/Transaction_Overlay.pm:589
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "Kaapattu käyttäjältä %1"
+
+#: html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Search/Bulk.html:126 html/Search/Elements/PickRestriction:43 html/SelfService/Create.html:59 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:35 html/Ticket/Create.html:84 html/Ticket/Elements/EditBasics:28 html/Ticket/ModifyAll.html:79 html/Ticket/Update.html:77 lib/RT/Ticket_Overlay.pm:1160 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "Otsikko"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:611
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr ""
+
+#: html/Elements/Submit:59
+msgid "Submit"
+msgstr "Lähetä"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:749
+msgid "Succeeded"
+msgstr ""
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "Su"
+
+#: lib/RT/System.pm:54
+msgid "SuperUser"
+msgstr ""
+
+#: html/User/Elements/DelegateRights:77
+msgid "System"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:567 lib/RT/Interface/Web.pm:757 lib/RT/Interface/Web.pm:790
+msgid "System Error"
+msgstr "Systeemivirhe"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. Right not granted."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. right not granted"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:616
+msgid "System error. Right not delegated."
+msgstr "Systeemivirhe. Oikeutta ei delegoitu."
+
+#: lib/RT/ACE_Overlay.pm:146 lib/RT/ACE_Overlay.pm:223 lib/RT/ACE_Overlay.pm:306 lib/RT/ACE_Overlay.pm:898
+msgid "System error. Right not granted."
+msgstr "Systeemivirhe. Oikeutta ei luovutettu."
+
+#: NOT FOUND IN SOURCE
+msgid "System error. Unable to grant rights."
+msgstr ""
+
+#: html/Admin/Global/GroupRights.html:35 html/Admin/Groups/GroupRights.html:37 html/Admin/Queues/GroupRights.html:36
+msgid "System groups"
+msgstr "Systeemiryhmät"
+
+#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53
+msgid "SystemRolegroup for internal use"
+msgstr ""
+
+#: lib/RT/CurrentUser.pm:320
+msgid "TEST_STRING"
+msgstr "TESTI_STRINGI"
+
+#: html/Ticket/Elements/Tabs:143
+msgid "Take"
+msgstr "Ota itselle"
+
+#: lib/RT/Transaction_Overlay.pm:575
+msgid "Taken"
+msgstr "Otettu"
+
+#: html/Admin/Elements/EditScrip:81
+msgid "Template"
+msgstr "Pohja"
+
+#: html/Admin/Global/Template.html:91 html/Admin/Queues/Template.html:90
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr ""
+
+#: html/Admin/Elements/EditTemplates:89
+msgid "Template deleted"
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:153
+msgid "Template not found"
+msgstr "Pohjaa ei löydetty"
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr "Pohjaa ei löydetty\\n"
+
+#: lib/RT/Template_Overlay.pm:347
+msgid "Template parsed"
+msgstr "Pohja tulkittu"
+
+#: html/Admin/Elements/QueueTabs:49 html/Admin/Elements/SystemTabs:36 html/Admin/Global/index.html:45
+msgid "Templates"
+msgstr "Pohjat"
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr "Pohjat työjonolle %1\\n"
+
+#: lib/RT/Interface/Web.pm:858
+msgid "That is already the current value"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:178
+msgid "That is not a value for this custom field"
+msgstr "Ei ole arvo tälle kentälle"
+
+#: lib/RT/Ticket_Overlay.pm:1886
+msgid "That is the same value"
+msgstr "Tämä on sama arvo"
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr "Tämä toimeksiantaja on jo %1 tälle työjonolle"
+
+#: lib/RT/Ticket_Overlay.pm:1434
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr "Tämä toimeksiantaja on jo %1 tälle työpyynnölle"
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr "Tämä toimeksiantaja ei ole %1 tälle työjonolle"
+
+#: lib/RT/Ticket_Overlay.pm:1551
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr "Tämä toimeksiantaja ei ole %1 tälle työpyynnölle"
+
+#: lib/RT/Ticket_Overlay.pm:1882
+msgid "That queue does not exist"
+msgstr "Tätä työjonoa ei ole olemassa"
+
+#: lib/RT/Ticket_Overlay.pm:3143
+msgid "That ticket has unresolved dependencies"
+msgstr "Tämä työpyyntö sisältää ei-päätettyjä riippuvuuksia"
+
+#: lib/RT/ACE_Overlay.pm:288 lib/RT/ACE_Overlay.pm:597
+msgid "That user already has that right"
+msgstr "Käyttäjällä on jo tuo oikeus"
+
+#: lib/RT/Ticket_Overlay.pm:2952
+msgid "That user already owns that ticket"
+msgstr "Käyttäjä omistaa jo tämän työpyynnön"
+
+#: lib/RT/Ticket_Overlay.pm:2918
+msgid "That user does not exist"
+msgstr "Käyttäjää ei ole olemassa"
+
+#: lib/RT/User_Overlay.pm:315
+msgid "That user is already privileged"
+msgstr "Tämä käyttäjä on jo etuoikeutettu"
+
+#: lib/RT/User_Overlay.pm:332
+msgid "That user is already unprivileged"
+msgstr "Tämä käyttäjä on jo ei-etuoikeutettu"
+
+#: lib/RT/User_Overlay.pm:327
+msgid "That user is now privileged"
+msgstr "Tämä käyttäjä on nyt etuoikeutettu"
+
+#: lib/RT/User_Overlay.pm:344
+msgid "That user is now unprivileged"
+msgstr "Tämä käyttäjä on nyt ei-etuoikeutettu"
+
+#: NOT FOUND IN SOURCE
+msgid "That user is now unprivilegedileged"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2944
+msgid "That user may not own tickets in that queue"
+msgstr "Käyttäjä ei voi omistaa työpyyntöjä tuossa työjonossa"
+
+#: lib/RT/Link_Overlay.pm:206
+msgid "That's not a numerical id"
+msgstr "Ei ole numero"
+
+#: html/Ticket/Create.html:150 html/Ticket/Elements/ShowSummary:28
+msgid "The Basics"
+msgstr "Perustiedot"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The CC of a ticket"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:89
+msgid "The administrative CC of a ticket"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2213
+msgid "The comment has been recorded"
+msgstr "Kommentti on tallennettu"
+
+#: bin/rt-crontool:198
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr ""
+
+#: bin/rt-commit-handler:756 bin/rt-commit-handler:766
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr "Seuraavia komentoja ei suoritettu:\\n\\n"
+
+#: lib/RT/Interface/Web.pm:861
+msgid "The new value has been set."
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The owner of a ticket"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The requestor of a ticket"
+msgstr ""
+
+#: html/Admin/Elements/EditUserComments:26
+msgid "These comments aren't generally visible to the user"
+msgstr "Nämä kommentit eivät ole yleisesti näkyvillä käyttäjälle"
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr "Tämä työpyyntö %1 %2 (%3)\\n"
+
+#: bin/rt-crontool:189
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:253
+msgid "This transaction appears to have no content"
+msgstr "Tämä toiminto ei näytä sisältävän mitään"
+
+#: html/Ticket/Elements/ShowRequestor:47
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr "Tämän käyttäjän 25 korkeimman prioriteetin työpyyntöä"
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "To"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr "Työpyyntö # %1  %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1 Jumbo update: %2"
+msgstr ""
+
+#: html/Ticket/ModifyAll.html:25 html/Ticket/ModifyAll.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "Työpyyntö #%1 Jumbo päivitys: %2"
+
+#: html/Approvals/Elements/ShowDependency:46
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:608
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr "Työpyyntö %1 luotu työjonoon '%2'"
+
+#: bin/rt-commit-handler:760
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr "Työpyyntö %1 ladattu\\n"
+
+#: html/Search/Bulk.html:181
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr "Työpyyntö %1: %2"
+
+#: html/Ticket/History.html:25 html/Ticket/History.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr "Työpyynnön historia # %1 %2"
+
+#: html/SelfService/Display.html:34
+msgid "Ticket Id"
+msgstr "Työpyynnön numero"
+
+#: etc/initialdata:303
+msgid "Ticket Resolved"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:63
+msgid "Ticket attachment"
+msgstr "Työpyynnön liite"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr "Työpyynnön sisältö"
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr "Työpyynnön sisällön tyyppi"
+
+#: lib/RT/Ticket_Overlay.pm:495 lib/RT/Ticket_Overlay.pm:597
+msgid "Ticket could not be created due to an internal error"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:522
+msgid "Ticket created"
+msgstr "Työpyyntö luotu"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr "Työpyynnön luonti epäonnistui"
+
+#: lib/RT/Transaction_Overlay.pm:527
+msgid "Ticket deleted"
+msgstr "Työpyyntö poistettu"
+
+#: html/REST/1.0/modify:29 html/REST/1.0/update:34
+msgid "Ticket id not found"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket killed"
+msgstr ""
+
+#: html/REST/1.0/modify:36 html/REST/1.0/update:41
+msgid "Ticket not found"
+msgstr ""
+
+#: etc/initialdata:289
+msgid "Ticket status changed"
+msgstr ""
+
+#: html/Ticket/Update.html:39
+msgid "Ticket watchers"
+msgstr "Työpyynnön tarkkailijat"
+
+#: html/Elements/Tabs:49
+msgid "Tickets"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr ""
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Tickets from %1"
+msgstr "Työpyynnöt %1"
+
+#: html/Approvals/Elements/ShowDependency:27
+msgid "Tickets which depend on this approval:"
+msgstr ""
+
+#: html/Ticket/Create.html:157 html/Ticket/Elements/EditBasics:48
+msgid "Time Left"
+msgstr "Aikaa jäljellä"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:43
+msgid "Time Worked"
+msgstr "Aikaa käytetty"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "Aikaa jäljellä"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "Aika"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "Aikaa käytetty"
+
+#: NOT FOUND IN SOURCE
+msgid "TimeLeft"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1165
+msgid "TimeWorked"
+msgstr ""
+
+#: bin/rt-commit-handler:402
+msgid "To generate a diff of this commit:"
+msgstr "Luodaksesi diffin tästä käskystä:"
+
+#: bin/rt-commit-handler:391
+msgid "To generate a diff of this commit:\\n"
+msgstr "To generate a diff of this commit:\\n"
+
+#: lib/RT/Ticket_Overlay.pm:1168
+msgid "Told"
+msgstr "Oltu yhteydessä"
+
+#: etc/initialdata:237
+msgid "Transaction"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:642
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr "Toiminto %1 puhdistettu"
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr "Toiminto luotu"
+
+#: lib/RT/Transaction_Overlay.pm:89
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:701
+msgid "Transactions are immutable"
+msgstr "Toiminnot ovat muuttumattomia"
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr "Yritetään poistaa oikeus: %1"
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "Ti"
+
+#: html/Admin/Elements/EditCustomField:34 html/Ticket/Elements/AddWatchers:33 html/Ticket/Elements/AddWatchers:44 html/Ticket/Elements/AddWatchers:54 lib/RT/Ticket_Overlay.pm:1166 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "Tyyppi"
+
+#: lib/RT/ScripCondition_Overlay.pm:104
+msgid "Unimplemented"
+msgstr "Toteuttamaton"
+
+#: html/Admin/Users/Modify.html:68
+msgid "Unix login"
+msgstr "Unix login"
+
+#: html/Admin/Elements/ModifyUser:62
+msgid "UnixUsername"
+msgstr "Käyttäjän Unix-tunnus"
+
+#: lib/RT/Attachment_Overlay.pm:265
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr "Tuntematon sisällön enkoodaus %1"
+
+#: html/Elements/SelectResultsPerPage:37
+msgid "Unlimited"
+msgstr "Rajoittamaton"
+
+#: etc/initialdata:32
+msgid "Unprivileged"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:571
+msgid "Untaken"
+msgstr "Ottamaton"
+
+#: html/Elements/MyTickets:64 html/Search/Bulk.html:33
+msgid "Update"
+msgstr "Päivitä"
+
+#: html/Admin/Users/Prefs.html:62
+msgid "Update ID"
+msgstr "Päivitä numero"
+
+#: html/Search/Bulk.html:120 html/Ticket/ModifyAll.html:66 html/Ticket/Update.html:67
+msgid "Update Type"
+msgstr "Päivitä tyyppi"
+
+#: html/Search/Listing.html:61
+msgid "Update all these tickets at once"
+msgstr "Päivitä kaikki nämä työpyynnöt kerralla"
+
+#: html/Admin/Users/Prefs.html:49
+msgid "Update email"
+msgstr "Päivitä sähköposti"
+
+#: html/Admin/Users/Prefs.html:55
+msgid "Update name"
+msgstr "Päivitä nimi"
+
+#: lib/RT/Interface/Web.pm:375
+msgid "Update not recorded."
+msgstr "Päivitystä ei tallennettu"
+
+#: html/Search/Bulk.html:81
+msgid "Update selected tickets"
+msgstr "Päivitä valitut työpyynnöt"
+
+#: html/Admin/Users/Prefs.html:36
+msgid "Update signature"
+msgstr "Päivitä allekirjoitus"
+
+#: html/Ticket/ModifyAll.html:63
+msgid "Update ticket"
+msgstr "Päivitä työpyyntö"
+
+#: html/SelfService/Update.html:25 html/SelfService/Update.html:27
+#. ($Ticket->id)
+msgid "Update ticket # %1"
+msgstr "Päivitä työpyyntö # %1"
+
+#: html/SelfService/Update.html:50
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr "Päivitä työpyyntö #%1"
+
+#: html/Ticket/Update.html:135
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:373
+msgid "Update type was neither correspondence nor comment."
+msgstr "Päivityksen tyyppi ei ollut kirjeenvaihto eikä kommentti."
+
+#: html/Elements/SelectDateType:33 html/Ticket/Elements/ShowDates:51 lib/RT/Ticket_Overlay.pm:1169
+msgid "Updated"
+msgstr "Päivitetty"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr "Käyttäjä %1 %2: %3\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr "Käyttäjä %1 Salasana: %2\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr "Käyttäjää '%1' ei löydetty"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr "Käyttäjää '%1' ei löydetty\\n"
+
+#: etc/initialdata:125 etc/initialdata:191
+msgid "User Defined"
+msgstr ""
+
+#: html/Admin/Users/Prefs.html:59
+msgid "User ID"
+msgstr "Käyttäjän tunnus"
+
+#: html/Elements/SelectUsers:26
+msgid "User Id"
+msgstr "Käyttäjän tunnus"
+
+#: html/Admin/Elements/GroupTabs:47 html/Admin/Elements/QueueTabs:60 html/Admin/Elements/SystemTabs:47 html/Admin/Global/index.html:59
+msgid "User Rights"
+msgstr "Käyttäjän oikeudet"
+
+#: html/Admin/Users/Modify.html:226
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr "Käyttäjää ei voitu luoda: %1"
+
+#: lib/RT/User_Overlay.pm:262
+msgid "User created"
+msgstr "Käyttäjä luotu"
+
+#: html/Admin/Global/GroupRights.html:67 html/Admin/Groups/GroupRights.html:54 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr "Käyttäjän luomat ryhmät"
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr "Käyttäjää informoitu"
+
+#: html/Admin/Users/Prefs.html:25 html/Admin/Users/Prefs.html:29
+msgid "User view"
+msgstr "Käyttäjän näkymä"
+
+#: html/Admin/Users/Modify.html:48 html/Elements/Login:42 html/Ticket/Elements/AddWatchers:35
+msgid "Username"
+msgstr "Käyttäjätunnus"
+
+#: html/Admin/Elements/SelectNewGroupMembers:26 html/Admin/Elements/Tabs:32 html/Admin/Groups/Members.html:55 html/Admin/Queues/People.html:68 html/Admin/index.html:29 html/User/Groups/Members.html:58
+msgid "Users"
+msgstr "Käyttäjät"
+
+#: html/Admin/Users/index.html:65
+msgid "Users matching search criteria"
+msgstr "Hakua vastaavat käyttäjät"
+
+#: html/Search/Elements/PickRestriction:51
+msgid "ValueOfQueue"
+msgstr "Työpyynnon arvo"
+
+#: html/Admin/Elements/EditCustomField:40
+msgid "Values"
+msgstr "Arvot"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Watch"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "WatchAsAdminCc"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Watcher loaded"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:42
+msgid "Watchers"
+msgstr "Tarkkailijat"
+
+#: html/Admin/Elements/ModifyUser:56
+msgid "WebEncoding"
+msgstr "Web Enkoodaus"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "Ke"
+
+#: etc/upgrade/2.1.71:161
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr ""
+
+#: etc/upgrade/2.1.71:135
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr ""
+
+#: etc/initialdata:138
+msgid "When a ticket is created"
+msgstr ""
+
+#: etc/upgrade/2.1.71:79
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr ""
+
+#: etc/initialdata:143
+msgid "When anything happens"
+msgstr ""
+
+#: etc/initialdata:184
+msgid "Whenever a ticket is resolved"
+msgstr ""
+
+#: etc/initialdata:170
+msgid "Whenever a ticket's owner changes"
+msgstr ""
+
+#: etc/initialdata:178
+msgid "Whenever a ticket's queue changes"
+msgstr ""
+
+#: etc/initialdata:162
+msgid "Whenever a ticket's status changes"
+msgstr ""
+
+#: etc/initialdata:192
+msgid "Whenever a user-defined condition occurs"
+msgstr ""
+
+#: etc/initialdata:156
+msgid "Whenever comments come in"
+msgstr ""
+
+#: etc/initialdata:149
+msgid "Whenever correspondence comes in"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:164 html/User/Prefs.html:52
+msgid "Work"
+msgstr "Työ"
+
+#: html/Admin/Elements/ModifyUser:70
+msgid "WorkPhone"
+msgstr "Työpuhelin"
+
+#: html/SelfService/Display.html:86 html/Ticket/Elements/ShowBasics:35 html/Ticket/Update.html:65
+msgid "Worked"
+msgstr "Tehty"
+
+#: lib/RT/Ticket_Overlay.pm:3056
+msgid "You already own this ticket"
+msgstr "Omistat jo tämän työpyynnön"
+
+#: html/autohandler:121
+msgid "You are not an authorized user"
+msgstr "Et ole autorisoitu käyttäjä"
+
+#: lib/RT/Ticket_Overlay.pm:2930
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "Voit palauttaa vain työpyyntöjä jotka omistat itse tai jotka ovat ilman omistajaa"
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr "Sinulla ei ole oikeutta tarkastella tätä työpyyntöä.\\n"
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "Löysit %1 työpyyntöä työjonosta %2"
+
+#: html/NoAuth/Logout.html:31 html/REST/1.0/logout:25
+msgid "You have been logged out of RT."
+msgstr "Olet kirjautunut ulos RT:stä"
+
+#: html/SelfService/Display.html:134
+msgid "You have no permission to create tickets in that queue."
+msgstr "Sinulla ei ole oikeutta luoda työpyyntöjä tähän työjonoon."
+
+#: lib/RT/Ticket_Overlay.pm:1895
+msgid "You may not create requests in that queue."
+msgstr "Et ehkä voi luoda työpyyntöjä tuohon työjonoon."
+
+#: html/NoAuth/Logout.html:36
+msgid "You're welcome to login again"
+msgstr "Tervetuloa kirjautumaan järjestelmään uudelleen"
+
+#: html/SelfService/Elements/MyRequests:25
+#. ($friendly_status)
+msgid "Your %1 requests"
+msgstr "Sinun %1 työpyyntöäsi"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr "RT:n ylläpitäjä on konfiguroinut RT:n käynnisävät sähköpostialiakset väärin."
+
+#: etc/initialdata:429 etc/upgrade/2.1.71:146
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr ""
+
+#: etc/initialdata:463 etc/upgrade/2.1.71:180
+msgid "Your request has been approved."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr ""
+
+#: etc/initialdata:384 etc/upgrade/2.1.71:101
+msgid "Your request was rejected."
+msgstr ""
+
+#: html/autohandler:136 html/autohandler:142
+msgid "Your username or password is incorrect"
+msgstr "Käyttäjätunnuksesi tai salasanasi on väärä"
+
+#: html/Admin/Elements/ModifyUser:84 html/Admin/Users/Modify.html:144 html/User/Prefs.html:96
+msgid "Zip"
+msgstr "Postinumero"
+
+#: NOT FOUND IN SOURCE
+msgid "[no subject]"
+msgstr ""
+
+#: html/User/Elements/DelegateRights:59
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "sallittu käyttäjälle %1"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:34
+msgid "contains"
+msgstr "sisältää"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content"
+msgstr ""
+
+#: html/Elements/SelectAttachmentField:27
+msgid "content-type"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2282
+msgid "correspondence (probably) not sent"
+msgstr "kirjeenvaihtoa (luultavasti) ei ole asetettu"
+
+#: lib/RT/Ticket_Overlay.pm:2292
+msgid "correspondence sent"
+msgstr "kirjeenvaihto lähetetty"
+
+#: html/Admin/Elements/ModifyQueue:63 html/Admin/Queues/Modify.html:77 lib/RT/Date.pm:319
+msgid "days"
+msgstr "päivää"
+
+#: NOT FOUND IN SOURCE
+msgid "dead"
+msgstr ""
+
+#: html/Search/Listing.html:75
+msgid "delete"
+msgstr "poista"
+
+#: lib/RT/Queue_Overlay.pm:63
+msgid "deleted"
+msgstr "poistettu"
+
+#: html/Search/Elements/PickRestriction:68
+msgid "does not match"
+msgstr "ei täsmää"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:35
+msgid "doesn't contain"
+msgstr "ei sisällä"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "equal to"
+msgstr "on yhtäsuuri"
+
+#: NOT FOUND IN SOURCE
+msgid "false"
+msgstr ""
+
+#: html/Elements/SelectAttachmentField:28
+msgid "filename"
+msgstr ""
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "greater than"
+msgstr "suurempi kuin"
+
+#: lib/RT/Group_Overlay.pm:194
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "ryhmä %1"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "tunnit"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr "numero"
+
+#: html/Elements/SelectBoolean:32 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88
+msgid "is"
+msgstr "on"
+
+#: html/Elements/SelectBoolean:36 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:37 html/Search/Elements/PickRestriction:48 html/Search/Elements/PickRestriction:77 html/Search/Elements/PickRestriction:89
+msgid "isn't"
+msgstr "ei ole"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "less than"
+msgstr "vähemmän kuin"
+
+#: html/Search/Elements/PickRestriction:67
+msgid "matches"
+msgstr "sisältää"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "min"
+
+#: html/Ticket/Update.html:66
+msgid "minutes"
+msgstr "minuuttia"
+
+#: bin/rt-commit-handler:765
+msgid "modifications\\n\\n"
+msgstr "muokkaukset\\n\\n"
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "kuukausia"
+
+#: lib/RT/Queue_Overlay.pm:58
+msgid "new"
+msgstr "uusi"
+
+#: html/Admin/Elements/EditScrips:43
+msgid "no value"
+msgstr ""
+
+#: html/Ticket/Elements/EditWatchers:28
+msgid "none"
+msgstr "ei mitään"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "not equal to"
+msgstr "eri suuri kuin"
+
+#: NOT FOUND IN SOURCE
+msgid "notlike"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:59
+msgid "open"
+msgstr "avoin"
+
+#: lib/RT/Group_Overlay.pm:199
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr "oma ryhmä '%1' käyttäjälle '%2'"
+
+#: lib/RT/Group_Overlay.pm:207
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr "työjono %1 %2"
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "rejected"
+msgstr "hylätty"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "resolved"
+msgstr "päätetty"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr "sec"
+
+#: lib/RT/Queue_Overlay.pm:60
+msgid "stalled"
+msgstr "jäädytetty"
+
+#: lib/RT/Group_Overlay.pm:202
+#. ($self->Type)
+msgid "system %1"
+msgstr "systeemi %1"
+
+#: lib/RT/Group_Overlay.pm:213
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr "systeemiryhmä '%1'"
+
+#: html/Elements/Error:42 html/SelfService/Error.html:42
+msgid "the calling component did not specify why"
+msgstr "kutsuva komponentti ei eritellyt syytä"
+
+#: lib/RT/Group_Overlay.pm:210
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr "työpyyntö #%1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "true"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:216
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "undescripbed group %1"
+msgstr "kuvalematon ryhmä %1"
+
+#: lib/RT/Group_Overlay.pm:191
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr "käyttäjä %1"
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr "viikkoa"
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr "pohjalla %1"
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr "vuosia"
+
diff --git a/rt/lib/RT/I18N/fr.po b/rt/lib/RT/I18N/fr.po
new file mode 100644 (file)
index 0000000..4ef68fb
--- /dev/null
@@ -0,0 +1,4959 @@
+# Copyright (c) 2002 Jesse Vincent <jesse@bestpractical.com>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: RT 3.0.4pre1\n"
+"POT-Creation-Date: 2002-05-02 11:36+0800\n"
+"PO-Revision-Date: 2003-07-03 02:00+0800\n"
+"Last-Translator: Blaise Thauvin <blaise@fdn.fr>\n"
+"Language-Team: rt-devel <rt-devel@lists.fsck.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: html/Elements/MyRequests:27 html/Elements/MyTickets:27
+msgid "#"
+msgstr "n°"
+
+#: NOT FOUND IN SOURCE
+msgid "#%1"
+msgstr "n°%1"
+
+#: html/Approvals/Elements/Approve:26 html/Approvals/Elements/ShowDependency:49 html/SelfService/Display.html:24 html/Ticket/Display.html:25 html/Ticket/Display.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($Ticket->id, $Ticket->Subject)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr "n°%1: %2"
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr "%1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr "%1 %2 %3"
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr "%1 %2 %3 %4:%5:%6 %7"
+
+#: lib/RT/Ticket_Overlay.pm:3569 lib/RT/Transaction_Overlay.pm:557 lib/RT/Transaction_Overlay.pm:599
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 added"
+msgstr "%1 %2 ajouté"
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 %2 ago"
+msgstr "il y a %1 %2"
+
+#: lib/RT/Ticket_Overlay.pm:3575 lib/RT/Transaction_Overlay.pm:564
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 changed to %3"
+msgstr "%1 %2 changé en %3"
+
+#: lib/RT/Ticket_Overlay.pm:3572 lib/RT/Transaction_Overlay.pm:560 lib/RT/Transaction_Overlay.pm:605
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 deleted"
+msgstr "%1 %2 supprimé"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 %2 of group %3"
+msgstr "%1 %2 du groupe %3"
+
+#: html/Admin/Elements/EditScrips:43 html/Admin/Elements/ListGlobalScrips:27
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 with template %3"
+msgstr "%1 %2 avec modèle %3"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 this ticket\\n"
+msgstr "%1 (%2) %3 ce ticket\\n"
+
+#: html/Search/Listing.html:56
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr "Tickets %1 à %2"
+
+#: bin/rt-crontool:168 bin/rt-crontool:175 bin/rt-crontool:181
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - An argument to pass to %2"
+msgstr "%1 - Un paramètre à passer à %2"
+
+#: bin/rt-crontool:184
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr "%1 - Ecrit les mises à jour de statuts sur STDOUT"
+
+#: bin/rt-crontool:178
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr "%1 - Précisez l'action que vous voulez utiliser"
+
+#: bin/rt-crontool:172
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr "%1 - Précisez la condition que vous voulez utiliser"
+
+#: bin/rt-crontool:165
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr "%1 - Précisez la recherche que vous voulez utiliser"
+
+#: lib/RT/ScripAction_Overlay.pm:121
+#. ($self->Id)
+msgid "%1 ScripAction loaded"
+msgstr "%1 ScripAction chargée"
+
+#: lib/RT/Ticket_Overlay.pm:3602
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 added as a value for %2"
+msgstr "%1 ajouté(e) comme valeur de %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on"
+msgstr "les alias %1 nécessitent un TicketId sur lequel travailler"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on "
+msgstr "les alias %1 nécessitent un TicketId sur lequel travailler "
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on (from %2) %3"
+msgstr "les alias %1 nécessitent un TicketId pour fonctionner avec (depuis %2) %3"
+
+#: lib/RT/Link_Overlay.pm:116 lib/RT/Link_Overlay.pm:123
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 appears to be a local object, but can't be found in the database"
+msgstr "%1 semble être un objet local, mais est introuvable dans la base de données"
+
+#: html/Ticket/Elements/ShowDates:51 lib/RT/Transaction_Overlay.pm:481
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 by %2"
+msgstr "%1 par %2"
+
+#: lib/RT/Transaction_Overlay.pm:535 lib/RT/Transaction_Overlay.pm:675 lib/RT/Transaction_Overlay.pm:684 lib/RT/Transaction_Overlay.pm:687
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 changed from %2 to %3"
+msgstr "%1 changé(e) de %2 à %3"
+
+#: lib/RT/Interface/Web.pm:893
+msgid "%1 could not be set to %2."
+msgstr "%1 n'a pas pu être positionné à %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr "%1 n'a pas pu initialiser une transaction (%2)\\n"
+
+#: lib/RT/Ticket_Overlay.pm:2867
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr "%1 ne peut pas mettre le statut à résolu. La base de données RT est peut être incohérente."
+
+#: html/Elements/MyTickets:24
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr "Mes %1 tickets à traiter en priorité..."
+
+#: html/Elements/MyRequests:24
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr "Mes %1 demandes les plus prioritaires..."
+
+#: bin/rt-crontool:160
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr "%1 est un outil agissant sur les tickets depuis un planificateur externe tel que cron"
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr "%1 n'est plus un %2 pour cette queue."
+
+#: lib/RT/Ticket_Overlay.pm:1587
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr "%1 n'est plus un %2 pour ce ticket."
+
+#: lib/RT/Ticket_Overlay.pm:3658
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr "%1 n'est plus une valeur pour le champ personnalisé %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr "%1 n'est pas un identifiant de queue valide"
+
+#: html/Ticket/Elements/ShowBasics:35
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr "%1 min"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr "%1 non montré"
+
+#: html/User/Elements/DelegateRights:75
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr "Droits de %1"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr "%1 réussi\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr "Type %1 inconnu pour $MessageId"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr "type %1 inconnu pour %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 was created without a CurrentUser\\n"
+msgstr "%1 a été créé sans utilisateur courant\\n"
+
+#: lib/RT/Action/ResolveMembers.pm:41
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr "%1 résoudra tous les membres d'un ticket groupé résolu."
+
+#: NOT FOUND IN SOURCE
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr "%1 va bloquer une base [locale] s'il dépend ou est membre d'une demande liée."
+
+#: lib/RT/Transaction_Overlay.pm:433
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr "%1: pas d'attachement spécifié"
+
+#: html/Ticket/Elements/ShowTransaction:88
+#. ($size)
+msgid "%1b"
+msgstr "%1b"
+
+#: html/Ticket/Elements/ShowTransaction:85
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr "%1k"
+
+#: lib/RT/Ticket_Overlay.pm:1176
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr "'%1' est un statut invalide"
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr "'%1' n'est pas une action connue. "
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete group member)"
+msgstr "(Cocher la case pour supprimer un membre du groupe)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr "(Cocher la case pour supprimer un scrip)"
+
+#: html/Admin/Elements/EditCustomFieldValues:24 html/Admin/Elements/EditQueueWatchers:28 html/Admin/Elements/EditScrips:34 html/Admin/Elements/EditTemplates:35 html/Admin/Groups/Members.html:51 html/Ticket/Elements/EditLinks:32 html/Ticket/Elements/EditPeople:45 html/User/Groups/Members.html:54
+msgid "(Check box to delete)"
+msgstr "(Cocher la case pour supprimer)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check boxes to delete)"
+msgstr "(Cocher la case pour supprimer)"
+
+#: html/Ticket/Create.html:177
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr "(Entrer les numéros de tickets ou les URLs, séparés par des espaces)"
+
+#: html/Admin/Queues/Modify.html:53 html/Admin/Queues/Modify.html:59
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr "Si laissé à blanc, valeur par défaut : %1"
+
+#: NOT FOUND IN SOURCE
+msgid "(No Value)"
+msgstr "(Non renseigné)"
+
+#: html/Admin/Elements/EditCustomFields:32 html/Admin/Elements/ListGlobalCustomFields:31
+msgid "(No custom fields)"
+msgstr "Pas de champ personnalisé"
+
+#: html/Admin/Groups/Members.html:49 html/User/Groups/Members.html:52
+msgid "(No members)"
+msgstr "(Aucun membre)"
+
+#: html/Admin/Elements/EditScrips:31 html/Admin/Elements/ListGlobalScrips:31
+msgid "(No scrips)"
+msgstr "(Aucun Scrip)"
+
+#: html/Admin/Elements/EditTemplates:30
+msgid "(No templates)"
+msgstr "Aucun modèle"
+
+#: html/Ticket/Update.html:83
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(Envoie une copie cachée de cette mise à jour à une liste d'adresses email séparées par des virgules. Ceci <b>ne changera pas</b> les destinataires des mises à jour suivantes.)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Envoie une copie cachée de cette mise à jour à une liste d'adresses email séparées par des virgules. Ceci <b>ne changera pas</b> les destinataires des mises à jour suivantes.)"
+
+#: html/Ticket/Create.html:78
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(Envoie une copie de cette mise à jour à une liste d'adresses email séparées par des virgules. Ces personnes <b>recevront</b> les mises à jour suivantes.)"
+
+#: html/Ticket/Update.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(Envoie une copie de cette mise à jour à une liste d'adresses email séparées par des virgules. Ceci <b>ne changera pas</b> les destinataires des mises à jour suivantes.)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "Envoie une copie de cette mise à jour à une liste d'adresses email séparées par des virgules. Ceci <b>ne changera pas</b> les destinataires des mises à jour suivantes.)"
+
+#: html/Ticket/Create.html:68
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(Envoie une copie de cette mise à jour à une liste d'adresses email séparées par des virgules. Ces personnes <b>recevront</b> les mises à jour suivantes.)"
+
+#: html/Admin/Groups/index.html:32 html/User/Groups/index.html:32
+msgid "(empty)"
+msgstr "(vide)"
+
+#: html/Admin/Users/index.html:38
+msgid "(no name listed)"
+msgstr "(aucun nom)"
+
+#: html/Elements/MyRequests:42 html/Elements/MyTickets:44
+msgid "(no subject)"
+msgstr "(pas de sujet)"
+
+#: html/Admin/Elements/SelectRights:47 html/Elements/SelectCustomFieldValue:29 html/Ticket/Elements/EditCustomField:60 html/Ticket/Elements/ShowCustomFields:35 lib/RT/Transaction_Overlay.pm:534
+msgid "(no value)"
+msgstr "(non renseigné)"
+
+#: html/Ticket/Elements/BulkLinks:27 html/Ticket/Elements/EditLinks:115
+msgid "(only one ticket)"
+msgstr "(un seul ticket)"
+
+#: html/Elements/MyRequests:51 html/Elements/MyTickets:54
+msgid "(pending approval)"
+msgstr "(en attente d'approbation)"
+
+#: html/Elements/MyRequests:53 html/Elements/MyTickets:56
+msgid "(pending other tickets)"
+msgstr "(en attente d'autres tickets)"
+
+#: NOT FOUND IN SOURCE
+msgid "(requestor's group)"
+msgstr "(groupe du demandeur)"
+
+#: html/Admin/Users/Modify.html:49
+msgid "(required)"
+msgstr "(exigé)"
+
+#: html/Ticket/Elements/ShowTransaction:91
+msgid "(untitled)"
+msgstr "(sans titre)"
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I own..."
+msgstr "Mes 25 tickets à traiter en priorité..."
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I requested..."
+msgstr "Mes 25 demandes les plus prioritaires..."
+
+#: html/Ticket/Elements/ShowBasics:31
+msgid "<% $Ticket->Status%>"
+msgstr "<% $Ticket->Statut%>"
+
+#: html/Elements/SelectTicketTypes:26
+msgid "<% $_ %>"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:25
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"Créer un ticket dans\">&nbsp;%1"
+
+#: etc/initialdata:203
+msgid "A blank template"
+msgstr "Un modèle vide"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Deleted"
+msgstr "ACE Supprimé"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Loaded"
+msgstr "ACE Chargé"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be deleted"
+msgstr "l'ACE n'a pu être supprimé"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be found"
+msgstr "l'ACE n'a pu être trouvé"
+
+#: lib/RT/ACE_Overlay.pm:156 lib/RT/Principal_Overlay.pm:180
+msgid "ACE not found"
+msgstr "ACE non trouvé"
+
+#: lib/RT/ACE_Overlay.pm:830
+msgid "ACEs can only be created and deleted."
+msgstr "Les ACE peuvent seulement être créés et effacés."
+
+#: bin/rt-commit-handler:754
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr "Interruption pour éviter des modifications de ticket involontaires"
+
+#: html/User/Elements/Tabs:31
+msgid "About me"
+msgstr "A propos"
+
+#: html/Admin/Users/Modify.html:79
+msgid "Access control"
+msgstr "contrôle d'accès"
+
+#: html/Admin/Elements/EditScrip:56
+msgid "Action"
+msgstr "Action"
+
+#: lib/RT/Scrip_Overlay.pm:146
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr "Action %1 non trouvée"
+
+#: bin/rt-crontool:122
+msgid "Action committed."
+msgstr "Action validée"
+
+#: bin/rt-crontool:118
+msgid "Action prepared..."
+msgstr "Action préparée..."
+
+#: html/Search/Bulk.html:95
+msgid "Add AdminCc"
+msgstr "Ajouter AdminCC"
+
+#: html/Search/Bulk.html:91
+msgid "Add Cc"
+msgstr "Ajouter CC"
+
+#: html/Ticket/Create.html:113 html/Ticket/Update.html:98
+msgid "Add More Files"
+msgstr "Ajouter d'autres fichiers"
+
+#: NOT FOUND IN SOURCE
+msgid "Add Next State"
+msgstr "Ajouter étape suivant"
+
+#: html/Search/Bulk.html:87
+msgid "Add Requestor"
+msgstr "Ajouter Demandeur"
+
+#: html/Admin/Elements/AddCustomFieldValue:24
+msgid "Add Value"
+msgstr "Ajouter une valeur"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a keyword selection to this queue"
+msgstr "Ajouter une sélection de mots clé à cette queue"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr "Ajouter un nouveau scrip global"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr "Ajouter un scrip à cette queue"
+
+#: html/Admin/Global/Scrip.html:54
+msgid "Add a scrip which will apply to all queues"
+msgstr "Ajouter un scrip qui s'ajoute à toutes les queues"
+
+#: html/Search/Bulk.html:127
+msgid "Add comments or replies to selected tickets"
+msgstr "Ajouter des commentaires ou des réponses aux tickets sélectionnés"
+
+#: html/Admin/Groups/Members.html:41 html/User/Groups/Members.html:38
+msgid "Add members"
+msgstr "Ajouter des membres"
+
+#: html/Admin/Queues/People.html:65 html/Ticket/Elements/AddWatchers:27
+msgid "Add new watchers"
+msgstr "Ajouter de nouveaux observateurs"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr "AjouterEtatSuivant"
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr "Ajout groupe/utilisateur comme %1 pour cette queue"
+
+#: lib/RT/Ticket_Overlay.pm:1471
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr "Ajout groupe/utilisateur comme %1 pour ce ticket"
+
+#: html/Admin/Elements/ModifyUser:75 html/Admin/Users/Modify.html:121 html/User/Prefs.html:87
+msgid "Address1"
+msgstr "Adresse1"
+
+#: html/Admin/Elements/ModifyUser:77 html/Admin/Users/Modify.html:126 html/User/Prefs.html:89
+msgid "Address2"
+msgstr "Adresse2"
+
+#: html/Ticket/Create.html:73
+msgid "Admin Cc"
+msgstr "Admin Cc"
+
+#: etc/initialdata:280
+msgid "Admin Comment"
+msgstr "Commentaire Admin"
+
+#: etc/initialdata:259
+msgid "Admin Correspondence"
+msgstr "Correspondance Admin "
+
+#: html/Admin/Queues/index.html:24 html/Admin/Queues/index.html:27
+msgid "Admin queues"
+msgstr "Administrateurs de queue"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr "Gérer les Utilisateurs"
+
+#: html/Admin/Global/index.html:25 html/Admin/Global/index.html:27
+msgid "Admin/Global configuration"
+msgstr "configuration Gestion/Globale"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr "Gestion/Groupes"
+
+#: html/Admin/Queues/Modify.html:24 html/Admin/Queues/Modify.html:28
+msgid "Admin/Queue/Basics"
+msgstr "Gestion/Queues/Essentiel"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr "GérerTousGroupesPersonnels"
+
+#: etc/initialdata:56 html/Ticket/Elements/ShowPeople:38 html/Ticket/Update.html:49 lib/RT/ACE_Overlay.pm:88
+msgid "AdminCc"
+msgstr "AdminCc"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr "CommentaireAdministrateur"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr "CorrespondanceAdministrateur"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "AdminCustomFields"
+msgstr "GérerChampsPersonnalisés"
+
+#: lib/RT/Group_Overlay.pm:145
+msgid "AdminGroup"
+msgstr "GérerGroupes"
+
+#: lib/RT/Group_Overlay.pm:147
+msgid "AdminGroupMembership"
+msgstr "GérerAppartenanceGroupes"
+
+#: lib/RT/System.pm:58
+msgid "AdminOwnPersonalGroups"
+msgstr "GérerGroupesPersonnelsPropres"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "AdminQueue"
+msgstr "GérerQueues"
+
+#: lib/RT/System.pm:59
+msgid "AdminUsers"
+msgstr "GérerUtilisateurs"
+
+#: html/Admin/Queues/People.html:47 html/Ticket/Elements/EditPeople:53
+msgid "Administrative Cc"
+msgstr "Cc Administratif"
+
+#: NOT FOUND IN SOURCE
+msgid "Admins"
+msgstr "Administrateurs"
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr "Recherche avancée"
+
+#: html/Elements/SelectDateRelation:35
+msgid "After"
+msgstr "Après"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr "Age"
+
+#: NOT FOUND IN SOURCE
+msgid "Alias"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Alias for"
+msgstr "Alias pour"
+
+#: etc/initialdata:348
+msgid "All Approvals Passed"
+msgstr "Toutes les approbations obtenues"
+
+#: html/Admin/Elements/EditCustomFields:95
+msgid "All Custom Fields"
+msgstr "Tous les champs personnalisés"
+
+#: html/Admin/Queues/index.html:52
+msgid "All Queues"
+msgstr "Toutes les queues"
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr "Envoie toujours un message au demandeur indépendamment de l'expéditeur"
+
+#: html/Elements/Tabs:55
+msgid "Approval"
+msgstr "Approbation"
+
+#: html/Approvals/Display.html:45 html/Approvals/Elements/ShowDependency:41 html/Approvals/index.html:64
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr "Approbation n°%1: %2"
+
+#: html/Approvals/index.html:53
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr "Approbation n°%1: Notes non enregistrées en raison d'une erreur système"
+
+#: html/Approvals/index.html:51
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr "Approbation n°%1: Notes non enregistrées"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Details"
+msgstr "Détails de l'approbation"
+
+#: etc/initialdata:336
+msgid "Approval Passed"
+msgstr "Approbations obtenues"
+
+#: etc/initialdata:359
+msgid "Approval Rejected"
+msgstr "Approbations refusées"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval diagram"
+msgstr "Diagramme d'approbation"
+
+#: html/Approvals/Elements/Approve:43
+msgid "Approve"
+msgstr "Approuver"
+
+#: etc/initialdata:486 etc/upgrade/2.1.71:148
+msgid "Approver's notes: %1"
+msgstr "Notes de l'approbateur: %1"
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "Avr."
+
+#: NOT FOUND IN SOURCE
+msgid "April"
+msgstr "Avril"
+
+#: html/Elements/SelectSortOrder:34
+msgid "Ascending"
+msgstr "Croissant"
+
+#: html/Search/Bulk.html:136 html/SelfService/Update.html:32 html/Ticket/ModifyAll.html:82 html/Ticket/Update.html:98
+msgid "Attach"
+msgstr "Attaché"
+
+#: html/SelfService/Create.html:64 html/Ticket/Create.html:109
+msgid "Attach file"
+msgstr "Attacher un ficher"
+
+#: html/Ticket/Create.html:97 html/Ticket/Update.html:87
+msgid "Attached file"
+msgstr "Fichier attaché"
+
+#: NOT FOUND IN SOURCE
+msgid "Attachment '%1' could not be loaded"
+msgstr "Attachement '%1' ne peut pas être chargé"
+
+#: lib/RT/Transaction_Overlay.pm:441
+msgid "Attachment created"
+msgstr "Attachement créé"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "Nom de fichier de l'attachement"
+
+#: html/Ticket/Elements/ShowAttachments:25
+msgid "Attachments"
+msgstr "Attachements"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "Aoû."
+
+#: NOT FOUND IN SOURCE
+msgid "August"
+msgstr "Août"
+
+#: html/Admin/Elements/ModifyUser:65
+msgid "AuthSystem"
+msgstr "AuthSystem"
+
+#: etc/initialdata:206
+msgid "Autoreply"
+msgstr "RéponseAuto"
+
+#: etc/initialdata:72
+msgid "Autoreply To Requestors"
+msgstr "Réponse automatique aux demandeurs"
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr "RéponseAutomtiqueAuxDemandeurs"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr "Signature PGP invalide: %1\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr "Id d'attachement erroné. Impossible de trouver l'attachement '%1'\\n"
+
+#: bin/rt-commit-handler:826
+#. ($val)
+msgid "Bad data in %1"
+msgstr "Données incorrectes dans %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr "Numéro de transaction incorrect pour l'attachement. %1 doit être %2\\n"
+
+#: html/Admin/Elements/GroupTabs:38 html/Admin/Elements/QueueTabs:38 html/Admin/Elements/UserTabs:37 html/Ticket/Elements/Tabs:89 html/User/Elements/GroupTabs:37
+msgid "Basics"
+msgstr "Essentiel"
+
+#: html/Ticket/Update.html:81
+msgid "Bcc"
+msgstr "Bcc"
+
+#: html/Admin/Elements/EditScrip:87 html/Admin/Global/GroupRights.html:84 html/Admin/Global/Template.html:45 html/Admin/Global/UserRights.html:53 html/Admin/Groups/GroupRights.html:72 html/Admin/Groups/Members.html:80 html/Admin/Groups/Modify.html:55 html/Admin/Groups/UserRights.html:54 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:44 html/Admin/Queues/UserRights.html:53 html/User/Groups/Modify.html:55
+msgid "Be sure to save your changes"
+msgstr "Assurez-vous de sauvegarder vos modifications"
+
+#: html/Elements/SelectDateRelation:33 lib/RT/CurrentUser.pm:321
+msgid "Before"
+msgstr "Avant"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin Approval"
+msgstr "Débuter l'approbation"
+
+#: etc/initialdata:202
+msgid "Blank"
+msgstr "Vide"
+
+#: html/Search/Listing.html:78
+msgid "Bookmarkable URL for this search"
+msgstr "URL prédéfinie pour cette recherche"
+
+#: html/Ticket/Elements/ShowHistory:38 html/Ticket/Elements/ShowHistory:44
+msgid "Brief headers"
+msgstr "En-têtes courts"
+
+#: html/Search/Bulk.html:24 html/Search/Bulk.html:25
+msgid "Bulk ticket update"
+msgstr "modification de tickets en masse"
+
+#: lib/RT/User_Overlay.pm:1524
+msgid "Can not modify system users"
+msgstr "Les utilisateurs système ne peuvent être modifiés"
+
+#: lib/RT/Queue_Overlay.pm:66
+msgid "Can this principal see this queue"
+msgstr "Le groupe/utilisateur peut-il voir cette queue"
+
+#: lib/RT/CustomField_Overlay.pm:205
+msgid "Can't add a custom field value without a name"
+msgstr "Impossible d'ajouter une valeur de champ personnalisé sans un nom"
+
+#: lib/RT/Link_Overlay.pm:131
+msgid "Can't link a ticket to itself"
+msgstr "Un ticket ne peut être lié à lui même"
+
+#: lib/RT/Ticket_Overlay.pm:2844
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr "Impossible de fusionner un ticket à un ticket fusionné. Vous ne devriez jamais obtenir cette erreur"
+
+#: lib/RT/Ticket_Overlay.pm:2646 lib/RT/Ticket_Overlay.pm:2725
+msgid "Can't specifiy both base and target"
+msgstr "Impossible de spécifier à la fois la base et la cible"
+
+#: html/autohandler:113
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr "Impossible de créer l'utilisateur: %1"
+
+#: etc/initialdata:50 html/Admin/Queues/People.html:43 html/SelfService/Create.html:48 html/Ticket/Create.html:63 html/Ticket/Elements/EditPeople:50 html/Ticket/Elements/ShowPeople:34 html/Ticket/Update.html:44 html/Ticket/Update.html:76 lib/RT/ACE_Overlay.pm:87
+msgid "Cc"
+msgstr "Cc"
+
+#: html/SelfService/Prefs.html:30
+msgid "Change password"
+msgstr "Changer le mot de passe"
+
+#: html/Ticket/Create.html:100 html/Ticket/Update.html:90
+msgid "Check box to delete"
+msgstr "Cocher la case pour supprimer"
+
+#: html/Admin/Elements/SelectRights:30
+msgid "Check box to revoke right"
+msgstr "Cocher la case pour retirer le droit"
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/BulkLinks:42 html/Ticket/Elements/EditLinks:130 html/Ticket/Elements/EditLinks:68 html/Ticket/Elements/ShowLinks:56
+msgid "Children"
+msgstr "Fils"
+
+#: html/Admin/Elements/ModifyUser:79 html/Admin/Users/Modify.html:131 html/User/Prefs.html:91
+msgid "City"
+msgstr "Ville"
+
+#: html/Ticket/Elements/ShowDates:46
+msgid "Closed"
+msgstr "Fermé"
+
+#: html/SelfService/Closed.html:24
+msgid "Closed Tickets"
+msgstr "Tickets fermés"
+
+#: NOT FOUND IN SOURCE
+msgid "Closed requests"
+msgstr "Demandes closes"
+
+#: html/SelfService/Elements/Tabs:44
+msgid "Closed tickets"
+msgstr "Tickets fermés"
+
+#: NOT FOUND IN SOURCE
+msgid "Code"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr "Commande incomprise! \\n"
+
+#: html/Ticket/Elements/ShowTransaction:165 html/Ticket/Elements/Tabs:152
+msgid "Comment"
+msgstr "Commenter"
+
+#: html/Admin/Elements/ModifyQueue:44 html/Admin/Queues/Modify.html:57
+msgid "Comment Address"
+msgstr "Adresse de commentaire"
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr "Commentaire non enregistré"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Comment on tickets"
+msgstr "Commentaire sur le ticket"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "CommentOnTicket"
+msgstr "CommenterTicket"
+
+#: html/Admin/Elements/ModifyUser:34
+msgid "Comments"
+msgstr "Commentaires"
+
+#: html/Ticket/ModifyAll.html:69 html/Ticket/Update.html:68
+msgid "Comments (Not sent to requestors)"
+msgstr "Commentaires (non envoyés aux demandeurs)"
+
+#: html/Search/Bulk.html:131
+msgid "Comments (not sent to requestors)"
+msgstr "Commentaires (non envoyés aux demandeurs)"
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Comments about %1"
+msgstr "Commentaires sur %1"
+
+#: html/Admin/Users/Modify.html:184 html/Ticket/Elements/ShowRequestor:43
+msgid "Comments about this user"
+msgstr "Commentaires sur cet utilisateur"
+
+#: lib/RT/Transaction_Overlay.pm:543
+msgid "Comments added"
+msgstr "Commentaires ajoutés"
+
+#: lib/RT/Action/Generic.pm:139
+msgid "Commit Stubbed"
+msgstr "tr(Commit Stubbed)"
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr "Restrictions de compilation"
+
+#: html/Admin/Elements/EditScrip:40
+msgid "Condition"
+msgstr "Condition"
+
+#: bin/rt-crontool:108
+msgid "Condition matches..."
+msgstr "La condition satisfait..."
+
+#: lib/RT/Scrip_Overlay.pm:159
+msgid "Condition not found"
+msgstr "Condition non trouvée"
+
+#: html/Elements/Tabs:49
+msgid "Configuration"
+msgstr "Configuration"
+
+#: html/SelfService/Prefs.html:32
+msgid "Confirm"
+msgstr "Confirmer"
+
+#: html/Admin/Elements/ModifyUser:59
+msgid "ContactInfoSystem"
+msgstr "ContactInfoSystem"
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr "Date de contact ne peut pas être analysée"
+
+#: html/Admin/Elements/ModifyTemplate:43 html/Ticket/ModifyAll.html:86
+msgid "Content"
+msgstr "Contenu"
+
+#: NOT FOUND IN SOURCE
+msgid "Coould not create group"
+msgstr "Le groupe n'a pas pu être créé"
+
+#: etc/initialdata:271
+msgid "Correspondence"
+msgstr "Courrier"
+
+#: html/Admin/Elements/ModifyQueue:38 html/Admin/Queues/Modify.html:50
+msgid "Correspondence Address"
+msgstr "Adresse de correspondance"
+
+#: lib/RT/Transaction_Overlay.pm:539
+msgid "Correspondence added"
+msgstr "Courrier ajouté"
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr "Courrier non enregistré"
+
+#: lib/RT/Ticket_Overlay.pm:3589
+msgid "Could not add new custom field value for ticket. "
+msgstr "Impossible d'ajouter une nouvelle valeur de champ personnalisé pour ce ticket. "
+
+#: NOT FOUND IN SOURCE
+msgid "Could not add new custom field value for ticket. %1 "
+msgstr "La valeur de champ personnalisé n'a pas pu être ajoutée. %1"
+
+#: lib/RT/Ticket_Overlay.pm:3095 lib/RT/Ticket_Overlay.pm:3103 lib/RT/Ticket_Overlay.pm:3120
+msgid "Could not change owner. "
+msgstr "Impossible de changer l'intervenant. "
+
+#: html/Admin/Elements/EditCustomField:84 html/Admin/Elements/EditCustomFields:165
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr "Impossible de créer un champ personnalisé CustomField"
+
+#: html/User/Groups/Modify.html:76 lib/RT/Group_Overlay.pm:473 lib/RT/Group_Overlay.pm:480
+msgid "Could not create group"
+msgstr "Impossible de créer un groupe"
+
+#: html/Admin/Global/Template.html:74 html/Admin/Queues/Template.html:71
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr "Impossible de créer un modèle : %1"
+
+#: lib/RT/Ticket_Overlay.pm:1109 lib/RT/Ticket_Overlay.pm:352
+msgid "Could not create ticket. Queue not set"
+msgstr "Impossible de créer un ticket. Queue non indiquée"
+
+#: lib/RT/User_Overlay.pm:267 lib/RT/User_Overlay.pm:279 lib/RT/User_Overlay.pm:297 lib/RT/User_Overlay.pm:483
+msgid "Could not create user"
+msgstr "Impossible de créer un utilisateur"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not create watcher for requestor"
+msgstr "L'observateur n'a pas pu être crée pour le demandeur"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr "Impossible de trouver le ticket numéro %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr "Impossible de trouver le groupe %1."
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1439
+msgid "Could not find or create that user"
+msgstr "Impossible de trouver ou créer cet utilisateur"
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1518
+msgid "Could not find that principal"
+msgstr "Impossible de trouver ce groupe ou utilisateur"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr "Impossible de trouver l'utilisateur %1."
+
+#: html/Admin/Groups/Members.html:87 html/User/Groups/Members.html:89 html/User/Groups/Modify.html:81
+msgid "Could not load group"
+msgstr "Impossible de charger ce groupe"
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr "Impossible de faire de ce groupe/utilisateur un %1 pour cette queue"
+
+#: lib/RT/Ticket_Overlay.pm:1460
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr "Impossible de faire de ce groupe/utilisateur un %1 pour ce ticket"
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr "Impossible de supprimer ce groupe/utilisateur comme un %1 pour cette queue"
+
+#: lib/RT/Ticket_Overlay.pm:1576
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr "Impossible de supprimer ce groupe/utilisateur comme un %1 pour ce ticket"
+
+#: lib/RT/Group_Overlay.pm:984
+msgid "Couldn't add member to group"
+msgstr "Impossible d'ajouter un membre à ce groupe"
+
+#: lib/RT/Ticket_Overlay.pm:3599 lib/RT/Ticket_Overlay.pm:3655
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr "Impossible de créer une transaction : %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr "Impossible de comprendre ce qu'il faut faire avec cette réponse gpg\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr "Groupe introuvable\\n"
+
+#: lib/RT/Interface/Web.pm:902
+msgid "Couldn't find row"
+msgstr "Colonne introuvable"
+
+#: lib/RT/Group_Overlay.pm:958
+msgid "Couldn't find that principal"
+msgstr "groupe/utilisateur introuvable"
+
+#: lib/RT/CustomField_Overlay.pm:239
+msgid "Couldn't find that value"
+msgstr "Valeur introuvable"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find that watcher"
+msgstr "L'observateur n'a pas pu être trouvé"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr "Utilisateur introuvable\\n"
+
+#: lib/RT/CurrentUser.pm:111
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr "Impossible de charger %1 depuis la base de données des utilisateurs.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load KeywordSelects."
+msgstr "KeywordSelects n'a pas pu être chargé"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr "Impossible de charger le fichier de configuration RT '%1' %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr "Les scrips n'ont pas pu être chargés"
+
+#: html/Admin/Groups/GroupRights.html:87 html/Admin/Groups/UserRights.html:74
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr "Impossible de charger le groupe %1"
+
+#: lib/RT/Link_Overlay.pm:174 lib/RT/Link_Overlay.pm:183 lib/RT/Link_Overlay.pm:210
+msgid "Couldn't load link"
+msgstr "Impossible de charger le lien"
+
+#: html/Admin/Elements/EditCustomFields:146 html/Admin/Queues/People.html:120
+#. ($id)
+msgid "Couldn't load queue"
+msgstr "Impossible de charger la queue"
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:71
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr "Impossible de charger la queue %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr "Impossible de charger le Scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr "Impossible de charger le modèle"
+
+#: html/Admin/Users/Prefs.html:78
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr "Impossible de charger cet utilisateur (%1)"
+
+#: html/SelfService/Display.html:108
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr "Impossible de charger le ticket '%1'"
+
+#: html/Admin/Elements/ModifyUser:85 html/Admin/Users/Modify.html:148 html/User/Prefs.html:97
+msgid "Country"
+msgstr "Pays"
+
+#: html/Admin/Elements/CreateUserCalled:25 html/Ticket/Create.html:134 html/Ticket/Create.html:194
+msgid "Create"
+msgstr "Ajouter"
+
+#: etc/initialdata:127
+msgid "Create Tickets"
+msgstr "Ajouter des tickets"
+
+#: html/Admin/Elements/EditCustomField:74
+msgid "Create a CustomField"
+msgstr "Ajouter un Champ Personnalisé"
+
+#: html/Admin/Queues/CustomField.html:47
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr "Ajouter un champ personnalisé à la queue %1"
+
+#: html/Admin/Global/CustomField.html:47
+msgid "Create a CustomField which applies to all queues"
+msgstr "Ajouter un champ personnalisé à toutes les queues"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr "Ajouter un nouveaux champ personnalisé"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr "Ajouter un nouveau scrip global"
+
+#: html/Admin/Groups/Modify.html:66 html/Admin/Groups/Modify.html:92
+msgid "Create a new group"
+msgstr "Ajouter un nouveau groupe"
+
+#: html/User/Groups/Modify.html:66 html/User/Groups/Modify.html:91
+msgid "Create a new personal group"
+msgstr "Ajouter un nouveau groupe personnel"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr "Ajouter une nouvelle queue"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr "Ajouter un nouveau scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr "Ajouter un nouveau modèle"
+
+#: html/Ticket/Create.html:24 html/Ticket/Create.html:27 html/Ticket/Create.html:35
+msgid "Create a new ticket"
+msgstr "Ajouter un nouveau ticket"
+
+#: html/Admin/Users/Modify.html:213 html/Admin/Users/Modify.html:240
+msgid "Create a new user"
+msgstr "Ajouter un nouvel utilisateur"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "Ajouter une queue"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr "Ajouter une nouvelle queue appelée"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a request"
+msgstr "Ajouter une demande"
+
+#: html/Admin/Queues/Scrip.html:58
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr "Ajouter un scrip pour la queue %1"
+
+#: html/Admin/Global/Template.html:68 html/Admin/Queues/Template.html:64
+msgid "Create a template"
+msgstr "Ajouter un modèle"
+
+#: html/SelfService/Create.html:24
+msgid "Create a ticket"
+msgstr "Ajouter un ticket"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1 / %2 / %3 "
+msgstr "Echec à la création de: %1 / %2 / %3"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1/%2/%3"
+msgstr "Echec à la création de: %1/%2/%3"
+
+#: etc/initialdata:129
+msgid "Create new tickets based on this scrip's template"
+msgstr "Ajouter de nouveaux tickets basés sur le modèle de ce scrip"
+
+#: html/SelfService/Create.html:77
+msgid "Create ticket"
+msgstr "Ajouter un ticket"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Create tickets in this queue"
+msgstr "Ajouter des tickets dans cette queue"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Create, delete and modify custom fields"
+msgstr "Ajouter, supprimer et modifier des champs personnalisés"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Create, delete and modify queues"
+msgstr "Ajouter, supprimer et modifier les queues"
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr "Ajouter, supprime et modifie les membres des groupe spersonnels de n'importe quel utilisateur"
+
+#: lib/RT/System.pm:58
+msgid "Create, delete and modify the members of personal groups"
+msgstr "Ajouter, supprimer et modifier les membres d'un groupe personnel"
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify users"
+msgstr "Ajouter, supprimer et modifier les utilisateurs"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "CreateTicket"
+msgstr "CréerTicket"
+
+#: html/Elements/SelectDateType:25 html/Ticket/Elements/ShowDates:26 lib/RT/Ticket_Overlay.pm:1203
+msgid "Created"
+msgstr "Créé"
+
+#: html/Admin/Elements/EditCustomField:87
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr "Champ Personnalisé %1 ajouté"
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr "Modèle %1 créé"
+
+#: html/Ticket/Elements/EditLinks:27
+msgid "Current Relationships"
+msgstr "Relations actuelles"
+
+#: html/Admin/Elements/EditScrips:29
+msgid "Current Scrips"
+msgstr "Scrips actuels"
+
+#: html/Admin/Groups/Members.html:38 html/User/Groups/Members.html:41
+msgid "Current members"
+msgstr "Membres actuels"
+
+#: html/Admin/Elements/SelectRights:28
+msgid "Current rights"
+msgstr "Droits actuels"
+
+#: html/Search/Listing.html:70
+msgid "Current search criteria"
+msgstr "Critères de recherche courants"
+
+#: html/Admin/Queues/People.html:40 html/Ticket/Elements/EditPeople:44
+msgid "Current watchers"
+msgstr "Observateurs actuels"
+
+#: html/Admin/Global/CustomField.html:54
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr "Champ personnalisé n°%1"
+
+#: html/Admin/Elements/QueueTabs:52 html/Admin/Elements/SystemTabs:39 html/Admin/Global/index.html:49 html/Ticket/Elements/ShowSummary:35
+msgid "Custom Fields"
+msgstr "Champs Personnalisés"
+
+#: html/Admin/Elements/EditScrip:72
+msgid "Custom action cleanup code"
+msgstr "Programme de nettoyage d'action personnalisé"
+
+#: html/Admin/Elements/EditScrip:64
+msgid "Custom action preparation code"
+msgstr "Programme de préparation d'action personnalisé "
+
+#: html/Admin/Elements/EditScrip:48
+msgid "Custom condition"
+msgstr "Condition personnalisée"
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr "Champs personnalisés %1 %2 %3"
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr "Le champ personnalisé %1 a une valeur"
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr "Le champ personnalisé %1 n'a pas de valeur"
+
+#: lib/RT/Ticket_Overlay.pm:3491
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr "Le champ personnalisé %1 est introuvable"
+
+#: html/Admin/Elements/EditCustomFields:196
+msgid "Custom field deleted"
+msgstr "Champ personnalisé supprimé"
+
+#: lib/RT/Ticket_Overlay.pm:3641
+msgid "Custom field not found"
+msgstr "Le champ personnalisé est introuvable"
+
+#: lib/RT/CustomField_Overlay.pm:349
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr "La valeur du champ personnalisé %1 ne peut pas être trouvée pour le champ personnalisé %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr "Valeur de champ personnalisé modifié de %1 à %2"
+
+#: lib/RT/CustomField_Overlay.pm:249
+msgid "Custom field value could not be deleted"
+msgstr "La valeur du champ personnalisé ne peut pas être effacée"
+
+#: lib/RT/CustomField_Overlay.pm:355
+msgid "Custom field value could not be found"
+msgstr "La valeur du champ personnalisé ne peut par être trouvée"
+
+#: lib/RT/CustomField_Overlay.pm:247 lib/RT/CustomField_Overlay.pm:357
+msgid "Custom field value deleted"
+msgstr "La valeur du champ personnalisé est effacée"
+
+#: lib/RT/Transaction_Overlay.pm:548
+msgid "CustomField"
+msgstr "ChampPersonnalisé"
+
+#: NOT FOUND IN SOURCE
+msgid "Data error"
+msgstr "Erreur de données"
+
+#: html/SelfService/Display.html:38 html/Ticket/Create.html:160 html/Ticket/Elements/ShowSummary:54 html/Ticket/Elements/Tabs:92 html/Ticket/ModifyAll.html:43
+msgid "Dates"
+msgstr "Dates"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "Déc."
+
+#: NOT FOUND IN SOURCE
+msgid "December"
+msgstr "Décembre"
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr "Modèle de réponse automatique par défaut"
+
+#: etc/initialdata:207
+msgid "Default Autoresponse template"
+msgstr "Modèle de réponse automatique par défaut"
+
+#: etc/initialdata:281
+msgid "Default admin comment template"
+msgstr "Modèle de commentaire administrateur par défaut"
+
+#: etc/initialdata:260
+msgid "Default admin correspondence template"
+msgstr "Modèle de courrier administrateur par défaut"
+
+#: etc/initialdata:272
+msgid "Default correspondence template"
+msgstr "Modèle de courrier par défaut"
+
+#: etc/initialdata:238
+msgid "Default transaction template"
+msgstr "Modèle de transaction par défaut"
+
+#: lib/RT/Transaction_Overlay.pm:694
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr "Par défaut: %1/%2 modifié de %3 à %4"
+
+#: html/User/Delegation.html:24 html/User/Delegation.html:27
+msgid "Delegate rights"
+msgstr "Déléguer les droits"
+
+#: lib/RT/System.pm:62
+msgid "Delegate specific rights which have been granted to you."
+msgstr "Déléguer des droits spécifiques qui vous ont été accordés"
+
+#: lib/RT/System.pm:62
+msgid "DelegateRights"
+msgstr "DéléguerDroits"
+
+#: html/User/Elements/Tabs:37
+msgid "Delegation"
+msgstr "Délégation"
+
+#: NOT FOUND IN SOURCE
+msgid "Delete"
+msgstr "Supprimer"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Delete tickets"
+msgstr "Supprimer des tickets"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "DeleteTicket"
+msgstr "SupprimerTicket"
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr "Effacer cet objet pourrait briser l'intégrité référentielle"
+
+#: lib/RT/Queue_Overlay.pm:293
+msgid "Deleting this object would break referential integrity"
+msgstr "Effacer cet objet briserait l'intégrité référentielle"
+
+#: lib/RT/User_Overlay.pm:499
+msgid "Deleting this object would violate referential integrity"
+msgstr "Effacer cet objet violerait l'intégrité référentielle"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity."
+msgstr "Effacer cet objet violerait l'intégrité référentielle"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity. That's bad."
+msgstr "Effacer cet objet violerait l'intégrité référentielle, c'est serait facheux!"
+
+#: html/Approvals/Elements/Approve:44
+msgid "Deny"
+msgstr "Refuser"
+
+#: html/Ticket/Create.html:180 html/Ticket/Elements/BulkLinks:34 html/Ticket/Elements/EditLinks:122 html/Ticket/Elements/EditLinks:46 html/Ticket/Elements/ShowDependencies:31 html/Ticket/Elements/ShowLinks:36
+msgid "Depended on by"
+msgstr "En dépend"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr "Dépendances : \\n"
+
+#: lib/RT/Transaction_Overlay.pm:626
+#. ($value)
+msgid "Dependency by %1 added"
+msgstr "Ajout de la dépendance par %1"
+
+#: lib/RT/Transaction_Overlay.pm:655
+#. ($value)
+msgid "Dependency by %1 deleted"
+msgstr "Suppression de la dépendance par %1"
+
+#: lib/RT/Transaction_Overlay.pm:624
+#. ($value)
+msgid "Dependency on %1 added"
+msgstr "Ajout de la dépendance de %1"
+
+#: lib/RT/Transaction_Overlay.pm:653
+#. ($value)
+msgid "Dependency on %1 deleted"
+msgstr "Suppression de la dépendance de %1"
+
+#: html/Elements/SelectLinkType:26 html/Ticket/Create.html:179 html/Ticket/Elements/BulkLinks:30 html/Ticket/Elements/EditLinks:118 html/Ticket/Elements/EditLinks:35 html/Ticket/Elements/ShowDependencies:24 html/Ticket/Elements/ShowLinks:26
+msgid "Depends on"
+msgstr "Dépend de"
+
+#: NOT FOUND IN SOURCE
+msgid "DependsOn"
+msgstr "DépendDe"
+
+#: html/Elements/SelectSortOrder:34
+msgid "Descending"
+msgstr "Décroissant"
+
+#: html/SelfService/Create.html:72 html/Ticket/Create.html:118
+msgid "Describe the issue below"
+msgstr "Décrivez la situation ci-dessous"
+
+#: html/Admin/Elements/AddCustomFieldValue:35 html/Admin/Elements/EditCustomField:38 html/Admin/Elements/EditScrip:33 html/Admin/Elements/ModifyQueue:35 html/Admin/Elements/ModifyTemplate:35 html/Admin/Groups/Modify.html:48 html/Admin/Queues/Modify.html:47 html/Elements/SelectGroups:26 html/User/Groups/Modify.html:48
+msgid "Description"
+msgstr "Description"
+
+#: NOT FOUND IN SOURCE
+msgid "Details"
+msgstr "Détails"
+
+#: html/Ticket/Elements/Tabs:84
+msgid "Display"
+msgstr "Afficher"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Display Access Control List"
+msgstr "Afficher la liste des droits"
+
+#: lib/RT/Queue_Overlay.pm:74
+msgid "Display Scrip templates for this queue"
+msgstr "Afficher les modèles de Scrips pour cette queue"
+
+#: lib/RT/Queue_Overlay.pm:77
+msgid "Display Scrips for this queue"
+msgstr "Afficher les Scrips pour cette queue"
+
+#: html/Ticket/Elements/ShowHistory:34
+msgid "Display mode"
+msgstr "Mode d'affichage"
+
+#: NOT FOUND IN SOURCE
+msgid "Display ticket #%1"
+msgstr "Afficher le ticket n°%1"
+
+#: lib/RT/System.pm:53
+msgid "Do anything and everything"
+msgstr "Faire tout et n'importe quoi"
+
+#: html/Elements/Refresh:29
+msgid "Don't refresh this page."
+msgstr "Ne pas rafraîchir cette page."
+
+#: html/Search/Elements/PickRestriction:113
+msgid "Don't show search results"
+msgstr "Ne pas afficher le résultat de la recherche"
+
+#: html/Ticket/Elements/ShowTransaction:91
+msgid "Download"
+msgstr "Télécharger"
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:44 html/Ticket/Elements/ShowDates:42 lib/RT/Ticket_Overlay.pm:1207
+msgid "Due"
+msgstr "Echéance"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr "Date d'échéance '%1' n'est pas comprise"
+
+#: bin/rt-commit-handler:753
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr "ERREUR: impossible de charger le ticket '%1' : %2.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit"
+msgstr "Modifier"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit Conditions"
+msgstr "Modifier les conditions"
+
+#: html/Admin/Queues/CustomFields.html:44
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr "Editer les champs personnalisés pour %1"
+
+#: html/Search/Bulk.html:143 html/Ticket/ModifyLinks.html:35
+msgid "Edit Relationships"
+msgstr "Modifier les relations"
+
+#: html/Admin/Queues/Templates.html:41
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr "Modifier les modèles pour la queue %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit keywords"
+msgstr "Modifier les mots clé"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr "Modifier les scrips"
+
+#: html/Admin/Global/index.html:45
+msgid "Edit system templates"
+msgstr "Modifier les modèles système"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr "Modifier les modèles pour %1"
+
+#: html/Admin/Elements/ModifyQueue:24 html/Admin/Queues/Modify.html:118
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr "Modifier la configuration de la queue %1"
+
+#: html/Admin/Elements/ModifyUser:24
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr "Modifier la configuration de l'utilisateur %1"
+
+#: html/Admin/Elements/EditCustomField:90
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr "Modifier le ChampPersonnalisé %1"
+
+#: html/Admin/Groups/Members.html:31
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr "Modifier les membres du groupe %1"
+
+#: html/User/Groups/Members.html:128
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr "Modifier les membres du groupe personnel %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr "Modifie le modèle %1"
+
+#: lib/RT/Ticket_Overlay.pm:2660 lib/RT/Ticket_Overlay.pm:2738
+msgid "Either base or target must be specified"
+msgstr "La base ou la cible doivent être spécifiées"
+
+#: html/Admin/Users/Modify.html:52 html/Admin/Users/Prefs.html:45 html/Elements/SelectUsers:26 html/Ticket/Elements/AddWatchers:55 html/User/Prefs.html:41
+msgid "Email"
+msgstr "Email"
+
+#: lib/RT/User_Overlay.pm:247
+msgid "Email address in use"
+msgstr "Adresse email utilisée"
+
+#: html/Admin/Elements/ModifyUser:41
+msgid "EmailAddress"
+msgstr "EmailAddress"
+
+#: html/Admin/Elements/ModifyUser:53
+msgid "EmailEncoding"
+msgstr "EmailEncoding"
+
+#: html/Admin/Elements/EditCustomField:50
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr "Activé (Décocher cette case désactive ce champ personnalisé)"
+
+#: html/Admin/Groups/Modify.html:52 html/User/Groups/Modify.html:52
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr "Activé (Décocher cette case désactive ce groupe)"
+
+#: html/Admin/Queues/Modify.html:83
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr "Activé (Décocher cette case désactive cette queue)"
+
+#: html/Admin/Elements/EditCustomFields:98
+msgid "Enabled Custom Fields"
+msgstr "Champs personnalisés actifs"
+
+#: html/Admin/Queues/index.html:55
+msgid "Enabled Queues"
+msgstr "Queues actives"
+
+#: html/Admin/Elements/EditCustomField:106 html/Admin/Groups/Modify.html:116 html/Admin/Queues/Modify.html:140 html/Admin/Users/Modify.html:282 html/User/Groups/Modify.html:116
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr "Statut actif %1"
+
+#: lib/RT/CustomField_Overlay.pm:427
+msgid "Enter multiple values"
+msgstr "Entrer plusieurs valeurs"
+
+#: lib/RT/CustomField_Overlay.pm:424
+msgid "Enter one value"
+msgstr "Entrer une seule valeur"
+
+#: html/Search/Bulk.html:144 html/Ticket/Elements/EditLinks:111
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "Saisir les tickets ou URIs pour y lier les tickets. Séparer les saisies par des espaces."
+
+#: html/Elements/Login:39 html/SelfService/Error.html:24 html/SelfService/Error.html:25
+msgid "Error"
+msgstr "Erreur"
+
+#: NOT FOUND IN SOURCE
+msgid "Error adding watcher"
+msgstr "Erreur à l'ajout de l'observateur"
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr "Erreur de paramètres pour Queue->AddWatcher"
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr "Erreur de paramètres pour Queue->DelWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1392
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr "Erreur de paramètres pour Ticket->AddWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1549
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr "Erreur de paramètres pour Ticket->DelWatcher"
+
+#: etc/initialdata:20
+msgid "Everyone"
+msgstr "Tout le monde"
+
+#: bin/rt-crontool:193
+msgid "Example:"
+msgstr "Exemple:"
+
+#: html/Admin/Elements/ModifyUser:63
+msgid "ExternalAuthId"
+msgstr "ExternalAuthId"
+
+#: html/Admin/Elements/ModifyUser:57
+msgid "ExternalContactInfoId"
+msgstr "ExternalContactInfoId"
+
+#: html/Admin/Users/Modify.html:72
+msgid "Extra info"
+msgstr "Info supplémentaire"
+
+#: lib/RT/User_Overlay.pm:363
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr "Recherche du pseudo groupe d'utilisateurs 'Priviligiés' infructueuse"
+
+#: lib/RT/User_Overlay.pm:370
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr "Recherche du pseudo groupe d'utilisateurs 'non-privilégiés' infructueuse"
+
+#: bin/rt-crontool:137
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr "Echec de chargement du module %1. (%2)"
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "Fév."
+
+#: NOT FOUND IN SOURCE
+msgid "February"
+msgstr "Février"
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr "Fin"
+
+#: html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:58 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "Priorité finale"
+
+#: lib/RT/Ticket_Overlay.pm:1198
+msgid "FinalPriority"
+msgstr "PrioritéFinale"
+
+#: html/Admin/Queues/People.html:60 html/Ticket/Elements/EditPeople:33
+msgid "Find group whose"
+msgstr "Trouver un groupe dont"
+
+#: NOT FOUND IN SOURCE
+msgid "Find new/open tickets"
+msgstr "Accéder aux tickets en cours"
+
+#: html/Admin/Queues/People.html:56 html/Admin/Users/index.html:45 html/Ticket/Elements/EditPeople:29
+msgid "Find people whose"
+msgstr "Trouver les gens dont"
+
+#: html/Search/Listing.html:107
+msgid "Find tickets"
+msgstr "Rechercher des tickets"
+
+#: NOT FOUND IN SOURCE
+msgid "Finish Approval"
+msgstr "Terminer l'approbation"
+
+#: html/Ticket/Elements/Tabs:57
+msgid "First"
+msgstr "Premier"
+
+#: html/Search/Listing.html:40
+msgid "First page"
+msgstr "Première page"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr "Foo Bar Baz"
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr "Foo!"
+
+#: html/Search/Bulk.html:86
+msgid "Force change"
+msgstr "Forcer la modification"
+
+#: html/Search/Listing.html:105
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr "%quant(%1,ticket) trouvés"
+
+#: lib/RT/Interface/Web.pm:904
+msgid "Found Object"
+msgstr "Objet trouvé"
+
+#: html/Admin/Elements/ModifyUser:43
+msgid "FreeformContactInfo"
+msgstr "SaisieLibreInfoContact"
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformMultiple"
+msgstr "SaisieLibreMultiple"
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "FreeformSingle"
+msgstr "SaisieLibreSimple"
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "Ven."
+
+#: html/Ticket/Elements/ShowHistory:40 html/Ticket/Elements/ShowHistory:50
+msgid "Full headers"
+msgstr "En-têtes complets"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr "Obtention de l'utilisateur courant depuis une signature pgp\\n"
+
+#: lib/RT/Transaction_Overlay.pm:593
+#. ($New->Name)
+msgid "Given to %1"
+msgstr "Donné à %1"
+
+#: html/Admin/Elements/Tabs:40 html/Admin/index.html:37
+msgid "Global"
+msgstr "Global"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Keyword Selections"
+msgstr "Mots clé globaux"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr "Scrips globaux"
+
+#: html/Admin/Elements/SelectTemplate:37
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr "Modèle global: %1"
+
+#: html/Admin/Elements/EditCustomFields:74 html/Admin/Queues/People.html:58 html/Admin/Queues/People.html:62 html/Admin/Queues/index.html:43 html/Admin/Users/index.html:48 html/Ticket/Elements/EditPeople:31 html/Ticket/Elements/EditPeople:35 html/index.html:40
+msgid "Go!"
+msgstr "Go!"
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr "Signature pgp valide pour %1\\n"
+
+#: html/Search/Listing.html:49
+msgid "Goto page"
+msgstr "Aller à la page"
+
+#: html/Elements/GotoTicket:24 html/SelfService/Elements/GotoTicket:24
+msgid "Goto ticket"
+msgstr "Aller au ticket"
+
+#: NOT FOUND IN SOURCE
+msgid "Grand"
+msgstr "Accorder"
+
+#: html/Ticket/Elements/AddWatchers:45 html/User/Elements/DelegateRights:77
+msgid "Group"
+msgstr "Groupe"
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr "Groupe %1 %2 : %3"
+
+#: html/Admin/Elements/GroupTabs:44 html/Admin/Elements/QueueTabs:56 html/Admin/Elements/SystemTabs:43 html/Admin/Global/index.html:54
+msgid "Group Rights"
+msgstr "Droits de groupe"
+
+#: lib/RT/Group_Overlay.pm:964
+msgid "Group already has member"
+msgstr "Le groupe a déjà un membre"
+
+#: NOT FOUND IN SOURCE
+msgid "Group could not be created."
+msgstr "Le groupe n'a pas pu être créé"
+
+#: html/Admin/Groups/Modify.html:76
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr "Le groupe %1 n'a pu être créé"
+
+#: lib/RT/Group_Overlay.pm:496
+msgid "Group created"
+msgstr "Groupe ajouté"
+
+#: lib/RT/Group_Overlay.pm:1132
+msgid "Group has no such member"
+msgstr "Un tel membre n'appartient pas au groupe"
+
+#: lib/RT/Group_Overlay.pm:944 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1446 lib/RT/Ticket_Overlay.pm:1524
+msgid "Group not found"
+msgstr "Groupe introuvable"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr "Groupe introuvable.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr "Groupe non spécifié.\\n"
+
+#: html/Admin/Elements/SelectNewGroupMembers:34 html/Admin/Elements/Tabs:34 html/Admin/Groups/Members.html:63 html/Admin/Queues/People.html:82 html/Admin/index.html:31 html/User/Groups/Members.html:66
+msgid "Groups"
+msgstr "Groupes"
+
+#: lib/RT/Group_Overlay.pm:970
+msgid "Groups can't be members of their members"
+msgstr "Les groupes ne peuvent pas être membres de leurs membres"
+
+#: lib/RT/Interface/CLI.pm:72 lib/RT/Interface/CLI.pm:72
+msgid "Hello!"
+msgstr "Bonjour!"
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr "Bonjour, %1"
+
+#: html/Ticket/Elements/ShowHistory:29 html/Ticket/Elements/Tabs:87
+msgid "History"
+msgstr "Historique"
+
+#: html/Admin/Elements/ModifyUser:67
+msgid "HomePhone"
+msgstr "Téléphone domicile"
+
+#: html/Elements/Tabs:43
+msgid "Homepage"
+msgstr "Page d'accueil"
+
+#: lib/RT/Base.pm:73
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr "J'ai %quant (%1, toupie à béton)"
+
+#: NOT FOUND IN SOURCE
+msgid "I have [quant,_1,concrete mixer]."
+msgstr "J'ai %quant (%1, toupie à béton)"
+
+#: html/Ticket/Elements/ShowBasics:26 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr "Identifiant"
+
+#: html/Admin/Users/Modify.html:43 html/User/Prefs.html:38
+msgid "Identity"
+msgstr "Identité"
+
+#: etc/initialdata:411 etc/upgrade/2.1.71:86
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr "Si une approbation est refusée, rejette l'original et supprime les approbations en attente"
+
+#: bin/rt-crontool:189
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr "Si cet outil était setgid, un utilisateur local mal intentionné pourrait l'utiliser pour obtenir un access administrateur à RT"
+
+#: html/Admin/Queues/People.html:104 html/Ticket/Modify.html:38 html/Ticket/ModifyAll.html:93 html/Ticket/ModifyPeople.html:37
+msgid "If you've updated anything above, be sure to"
+msgstr "Si vous avez fait une modification, assurez vous de"
+
+#: lib/RT/Interface/Web.pm:896
+msgid "Illegal value for %1"
+msgstr "Valeur incorrecte pour %1"
+
+#: lib/RT/Interface/Web.pm:899
+msgid "Immutable field"
+msgstr "Champ non modifiable"
+
+#: html/Admin/Elements/EditCustomFields:73
+msgid "Include disabled custom fields in listing."
+msgstr "Inclure les champs personnalisés désactivés dans la liste"
+
+#: html/Admin/Queues/index.html:42
+msgid "Include disabled queues in listing."
+msgstr "Afficher les queues inactives."
+
+#: html/Admin/Users/index.html:46
+msgid "Include disabled users in search."
+msgstr "Inclure les utilisateurs désactivés dans le résultat"
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr "Priorité initiale"
+
+#: lib/RT/Ticket_Overlay.pm:1197 lib/RT/Ticket_Overlay.pm:1199
+msgid "InitialPriority"
+msgstr "PrioritéInitiale"
+
+#: lib/RT/ScripAction_Overlay.pm:104
+msgid "Input error"
+msgstr "Erreur à l'entrée"
+
+#: NOT FOUND IN SOURCE
+msgid "Interest noted"
+msgstr "Votre intéret est noté"
+
+#: lib/RT/Ticket_Overlay.pm:3866
+msgid "Internal Error"
+msgstr "Erreur interne"
+
+#: lib/RT/Record.pm:142
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr "Erreur interne: %1"
+
+#: lib/RT/Group_Overlay.pm:643
+msgid "Invalid Group Type"
+msgstr "Type de groupe invalide"
+
+#: lib/RT/Principal_Overlay.pm:127
+msgid "Invalid Right"
+msgstr "Droit invalide"
+
+#: NOT FOUND IN SOURCE
+msgid "Invalid Type"
+msgstr "Type invalide"
+
+#: lib/RT/Interface/Web.pm:901
+msgid "Invalid data"
+msgstr "Données invalides"
+
+#: lib/RT/Ticket_Overlay.pm:457
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr "Intervenant invalide, affectation à 'personne'"
+
+#: lib/RT/Scrip_Overlay.pm:133 lib/RT/Template_Overlay.pm:250
+msgid "Invalid queue"
+msgstr "Queue invalide"
+
+#: lib/RT/ACE_Overlay.pm:243 lib/RT/ACE_Overlay.pm:252 lib/RT/ACE_Overlay.pm:258 lib/RT/ACE_Overlay.pm:269 lib/RT/ACE_Overlay.pm:274
+msgid "Invalid right"
+msgstr "Droit invalide"
+
+#: lib/RT/Record.pm:117
+#. ($key)
+msgid "Invalid value for %1"
+msgstr "Queue invalide pour %1"
+
+#: lib/RT/Ticket_Overlay.pm:3498
+msgid "Invalid value for custom field"
+msgstr "Valeur incorrecte pour le champ personnalisé"
+
+#: lib/RT/Ticket_Overlay.pm:364
+msgid "Invalid value for status"
+msgstr "Valeur de statut invalide"
+
+#: bin/rt-crontool:190
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr "Il est extrêmement important que les utilisateurs non authorisés n'aient pas accès à cet outil"
+
+#: bin/rt-crontool:191
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr "Il est suggéré de créer un utilisateur unix non privilégié appartenant au bon groupe et ayant accès à RT pour utiliser cet outil"
+
+#: bin/rt-crontool:162
+msgid "It takes several arguments:"
+msgstr "Il faut plusieurs paramètres:"
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr "Eléments attendant mon approbation"
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "Jan."
+
+#: NOT FOUND IN SOURCE
+msgid "January"
+msgstr "Janvier"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Join or leave this group"
+msgstr "Rejoignez ou quittez ce groupe"
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "Jul."
+
+#: NOT FOUND IN SOURCE
+msgid "July"
+msgstr "Juillet"
+
+#: html/Ticket/Elements/Tabs:98
+msgid "Jumbo"
+msgstr "Tout"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "Jun."
+
+#: NOT FOUND IN SOURCE
+msgid "June"
+msgstr "Juin"
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr "Mot Clé"
+
+#: html/Admin/Elements/ModifyUser:51
+msgid "Lang"
+msgstr "Lang"
+
+#: html/Ticket/Elements/Tabs:72
+msgid "Last"
+msgstr "Dernier"
+
+#: html/Ticket/Elements/EditDates:37 html/Ticket/Elements/ShowDates:38
+msgid "Last Contact"
+msgstr "Dernier contact"
+
+#: html/Elements/SelectDateType:28
+msgid "Last Contacted"
+msgstr "Date dernier contact"
+
+#: html/Search/Elements/TicketHeader:40
+msgid "Last Notified"
+msgstr "Dernière notification"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Updated"
+msgstr "Date dernière MAJ"
+
+#: NOT FOUND IN SOURCE
+msgid "LastUpdated"
+msgstr "DernièreMAJ"
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr "Restant"
+
+#: html/Admin/Users/Modify.html:82
+msgid "Let this user access RT"
+msgstr "Donner accès à RT à cet utilisateur"
+
+#: html/Admin/Users/Modify.html:86
+msgid "Let this user be granted rights"
+msgstr "Autoriser cet utilisateur à recevoir des droits"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr "Limitation des intervenants à %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr "Limitation de la queue à %1 %2"
+
+#: lib/RT/Ticket_Overlay.pm:2752
+msgid "Link already exists"
+msgstr "Le lien existe déja"
+
+#: lib/RT/Ticket_Overlay.pm:2764
+msgid "Link could not be created"
+msgstr "Le lien ne peut être ajouté"
+
+#: lib/RT/Ticket_Overlay.pm:2772 lib/RT/Ticket_Overlay.pm:2784
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr "Le lien est ajouté (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2685
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr "Le lien est effacé (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2691
+msgid "Link not found"
+msgstr "Lien introuvable"
+
+#: html/Ticket/ModifyLinks.html:24 html/Ticket/ModifyLinks.html:28
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr "Lier le ticket n°%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Link ticket %1"
+msgstr "Lier au ticket %1"
+
+#: html/Ticket/Elements/Tabs:96
+msgid "Links"
+msgstr "Relations"
+
+#: html/Admin/Users/Modify.html:113 html/User/Prefs.html:84
+msgid "Location"
+msgstr "Localisation"
+
+#: lib/RT.pm:162
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr "Le répertoire de log %1 est introuvable ou en lecture seule. \\n RT ne peut pas démarrer"
+
+#: html/Elements/Header:57
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "Connecté en tant que %1"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:35 html/Elements/Login:44 html/Elements/Login:54
+msgid "Login"
+msgstr "Connexion"
+
+#: html/Elements/Header:54
+msgid "Logout"
+msgstr "Déconnexion"
+
+#: html/Search/Bulk.html:85
+msgid "Make Owner"
+msgstr "Attribuer"
+
+#: html/Search/Bulk.html:109
+msgid "Make Status"
+msgstr "Appliquer Statut"
+
+#: html/Search/Bulk.html:117
+msgid "Make date Due"
+msgstr "Appliquer date d'échéance"
+
+#: html/Search/Bulk.html:119
+msgid "Make date Resolved"
+msgstr "Appliquer date de résolution"
+
+#: html/Search/Bulk.html:113
+msgid "Make date Started"
+msgstr "Appliquer date de début"
+
+#: html/Search/Bulk.html:111
+msgid "Make date Starts"
+msgstr "Appliquer date d'ouverture"
+
+#: html/Search/Bulk.html:115
+msgid "Make date Told"
+msgstr "Appliquer Age"
+
+#: html/Search/Bulk.html:105
+msgid "Make priority"
+msgstr "Appliquer priorité"
+
+#: html/Search/Bulk.html:107
+msgid "Make queue"
+msgstr "Appliquer queue"
+
+#: html/Search/Bulk.html:103
+msgid "Make subject"
+msgstr "Changer le sujet"
+
+#: html/Admin/index.html:32
+msgid "Manage groups and group membership"
+msgstr "Gérer les groupes et leurs membres"
+
+#: html/Admin/index.html:38
+msgid "Manage properties and configuration which apply to all queues"
+msgstr "Gérer les propriétés et configurations générales des queues"
+
+#: html/Admin/index.html:35
+msgid "Manage queues and queue-specific properties"
+msgstr "Gérer les queues et leurs propriétés individuelles"
+
+#: html/Admin/index.html:29
+msgid "Manage users and passwords"
+msgstr "Gérer les utilisateurs et mots de passe"
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "Mar."
+
+#: NOT FOUND IN SOURCE
+msgid "March"
+msgstr "Mars"
+
+#: NOT FOUND IN SOURCE
+msgid "May"
+msgstr "Mai"
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "Mai."
+
+#: lib/RT/Transaction_Overlay.pm:635
+#. ($value)
+msgid "Member %1 added"
+msgstr "Membre %1 ajouté"
+
+#: lib/RT/Transaction_Overlay.pm:664
+#. ($value)
+msgid "Member %1 deleted"
+msgstr "Membre %1 supprimé"
+
+#: lib/RT/Group_Overlay.pm:981
+msgid "Member added"
+msgstr "Membre ajouté"
+
+#: lib/RT/Group_Overlay.pm:1139
+msgid "Member deleted"
+msgstr "Membre supprimé"
+
+#: lib/RT/Group_Overlay.pm:1143
+msgid "Member not deleted"
+msgstr "Membre non supprimé"
+
+#: html/Elements/SelectLinkType:25
+msgid "Member of"
+msgstr "Membre de"
+
+#: NOT FOUND IN SOURCE
+msgid "MemberOf"
+msgstr "MembreDe"
+
+#: html/Admin/Elements/GroupTabs:41 html/User/Elements/GroupTabs:41
+msgid "Members"
+msgstr "Membres"
+
+#: lib/RT/Transaction_Overlay.pm:633
+#. ($value)
+msgid "Membership in %1 added"
+msgstr "Appartenance à %1 ajoutée"
+
+#: lib/RT/Transaction_Overlay.pm:662
+#. ($value)
+msgid "Membership in %1 deleted"
+msgstr "Appartenance à %1 supprimée"
+
+#: lib/RT/Ticket_Overlay.pm:2941
+msgid "Merge Successful"
+msgstr "Fusion réussie"
+
+#: lib/RT/Ticket_Overlay.pm:2861
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "Echec de fusion. Ne peut appliquer EffectiveId"
+
+#: html/Ticket/Elements/BulkLinks:26 html/Ticket/Elements/EditLinks:114
+msgid "Merge into"
+msgstr "Fusionner dans"
+
+#: html/Search/Bulk.html:137 html/Ticket/Update.html:100
+msgid "Message"
+msgstr "Message"
+
+#: lib/RT/Interface/Web.pm:903
+msgid "Missing a primary key?: %1"
+msgstr "Clé primaire manquante? : %1"
+
+#: html/Admin/Users/Modify.html:168 html/User/Prefs.html:53
+msgid "Mobile"
+msgstr "Mobile"
+
+#: html/Admin/Elements/ModifyUser:71
+msgid "MobilePhone"
+msgstr "MobilePhone"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Modify Access Control List"
+msgstr "Modifier la liste de droits"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Custom Field %1"
+msgstr "Modifier champ personnalisé %1"
+
+#: html/Admin/Global/CustomFields.html:43 html/Admin/Global/index.html:50
+msgid "Modify Custom Fields which apply to all queues"
+msgstr "Modifier les champs personnalisés globaux"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Modify Scrip templates for this queue"
+msgstr "Modifier les modèles de Scrips pour cette queue"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Modify Scrips for this queue"
+msgstr "Modifier les Scrips pour cette queue"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify System ACLS"
+msgstr "Modifier ACLs système"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr "Modifier le modèle %1"
+
+#: html/Admin/Queues/CustomField.html:44
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr "Modifier un champ personnalisé pour la queue %1"
+
+#: html/Admin/Global/CustomField.html:52
+msgid "Modify a CustomField which applies to all queues"
+msgstr "Modifier un champ personnalisé global"
+
+#: html/Admin/Queues/Scrip.html:53
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr "Modifier le scrip pour la queue %1"
+
+#: html/Admin/Global/Scrip.html:47
+msgid "Modify a scrip which applies to all queues"
+msgstr "Modiier le scrip qui s'applique à toutes les queues"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify dates for # %1"
+msgstr "Modifier les dates pur n°%1"
+
+#: html/Ticket/ModifyDates.html:24 html/Ticket/ModifyDates.html:28
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr "Modifier les dates pour n°%1"
+
+#: html/Ticket/ModifyDates.html:34
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr "Modifier les dates du ticket n°%1"
+
+#: html/Admin/Global/GroupRights.html:24 html/Admin/Global/GroupRights.html:27 html/Admin/Global/index.html:55
+msgid "Modify global group rights"
+msgstr "Modifier les droits de groupe globaux"
+
+#: html/Admin/Global/GroupRights.html:32
+msgid "Modify global group rights."
+msgstr "Modifier les droits de groupe globaux"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for groups"
+msgstr "Modifier les droits globaux des groupes"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for users"
+msgstr "Modifier les droits globaux des utilisateurs"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr "Modifier les scrips globaux"
+
+#: html/Admin/Global/UserRights.html:24 html/Admin/Global/UserRights.html:27 html/Admin/Global/index.html:59
+msgid "Modify global user rights"
+msgstr "Modifier les droits utilisateurs globaux"
+
+#: html/Admin/Global/UserRights.html:32
+msgid "Modify global user rights."
+msgstr "Modifier les droits utilisateurs globaux"
+
+#: lib/RT/Group_Overlay.pm:145
+msgid "Modify group metadata or delete group"
+msgstr "Modifier les métadonnées ou supprimer le groupe"
+
+#: html/Admin/Groups/GroupRights.html:24 html/Admin/Groups/GroupRights.html:28 html/Admin/Groups/GroupRights.html:34
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr "Modifier les droits du groupe %1"
+
+#: html/Admin/Queues/GroupRights.html:24 html/Admin/Queues/GroupRights.html:28
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr "Modifier les droits de groupe pour la queue %1"
+
+#: lib/RT/Group_Overlay.pm:147
+msgid "Modify membership roster for this group"
+msgstr "Modifier le membership roster pour ce groupe"
+
+#: lib/RT/System.pm:60
+msgid "Modify one's own RT account"
+msgstr "Modifier son propre profile RT"
+
+#: html/Admin/Queues/People.html:24 html/Admin/Queues/People.html:28
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr "Modifier les utilisateurs de la queue %1"
+
+#: html/Ticket/ModifyPeople.html:24 html/Ticket/ModifyPeople.html:28 html/Ticket/ModifyPeople.html:34
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr "Modifier les utilisateurs du ticket n°%1"
+
+#: html/Admin/Queues/Scrips.html:45
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr "Modifier les scrips de la queue %1"
+
+#: html/Admin/Global/Scrips.html:43 html/Admin/Global/index.html:41
+msgid "Modify scrips which apply to all queues"
+msgstr "Modifier les scrips s'appliquant à toutes les queues"
+
+#: html/Admin/Global/Template.html:24 html/Admin/Global/Template.html:29 html/Admin/Global/Template.html:80 html/Admin/Queues/Template.html:77
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr "Modifier le modèle %1"
+
+#: html/Admin/Global/Templates.html:43
+msgid "Modify templates which apply to all queues"
+msgstr "Modifier les modèles globaux"
+
+#: html/Admin/Groups/Modify.html:86 html/User/Groups/Modify.html:85
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr "Modifier le groupe %1"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify the queue watchers"
+msgstr "Modifier les observateurs de la queue"
+
+#: html/Admin/Users/Modify.html:235
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr "Modifier l'utilisateur %1"
+
+#: html/Ticket/ModifyAll.html:36
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "Modifier le ticket # %1"
+
+#: html/Ticket/Modify.html:24 html/Ticket/Modify.html:27 html/Ticket/Modify.html:33
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "Modifier le ticket n°%1"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Modify tickets"
+msgstr "Modifier les tickets"
+
+#: html/Admin/Groups/UserRights.html:24 html/Admin/Groups/UserRights.html:28 html/Admin/Groups/UserRights.html:34
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr "Modifier les droits utilisateurs pour le groupe %1"
+
+#: html/Admin/Queues/UserRights.html:24 html/Admin/Queues/UserRights.html:28
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr "Modifier les droits utilisateurs pour la queue %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr "Modifier les observateurs dela queue '%1'"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ModifyACL"
+msgstr "ModifierACL"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "ModifyOwnMembership"
+msgstr "ModifierPropresAppartenances"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyQueueWatchers"
+msgstr "ModifierObservateurs"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ModifyScrips"
+msgstr "ModifierScrips"
+
+#: lib/RT/System.pm:60
+msgid "ModifySelf"
+msgstr "ModifierDonnéesPerso"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "ModifyTemplate"
+msgstr "ModifierModèle"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "ModifyTicket"
+msgstr "ModifierTicket"
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "Lun."
+
+#: html/Ticket/Elements/ShowRequestor:41
+#. ($name)
+msgid "More about %1"
+msgstr "Plus d'info sur %1"
+
+#: html/Admin/Elements/EditCustomFields:60
+msgid "Move down"
+msgstr "Aller en bas"
+
+#: html/Admin/Elements/EditCustomFields:52
+msgid "Move up"
+msgstr "Aller en haut"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Multiple"
+msgstr "Multiple"
+
+#: lib/RT/User_Overlay.pm:238
+msgid "Must specify 'Name' attribute"
+msgstr "Attribut 'Nom' obligatoire"
+
+#: html/SelfService/Elements/MyRequests:48
+#. ($friendly_status)
+msgid "My %1 tickets"
+msgstr "Mes %1 tickets"
+
+#: NOT FOUND IN SOURCE
+msgid "My Approvals"
+msgstr "Mes approbations"
+
+#: html/Approvals/index.html:24 html/Approvals/index.html:25
+msgid "My approvals"
+msgstr "Mes approbations"
+
+#: html/Admin/Elements/AddCustomFieldValue:31 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/ModifyTemplate:27 html/Admin/Elements/ModifyUser:29 html/Admin/Groups/Modify.html:43 html/Elements/SelectGroups:25 html/Elements/SelectUsers:27 html/User/Groups/Modify.html:43
+msgid "Name"
+msgstr "Nom"
+
+#: lib/RT/User_Overlay.pm:245
+msgid "Name in use"
+msgstr "Nom utilisé"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr "Approbation de l'administrateur système nécessaire"
+
+#: html/Ticket/Elements/ShowDates:51
+msgid "Never"
+msgstr "Jamais"
+
+#: html/Elements/Quicksearch:29
+msgid "New"
+msgstr "Nouveau"
+
+#: html/Admin/Elements/ModifyUser:31 html/Admin/Users/Modify.html:92 html/User/Prefs.html:64
+msgid "New Password"
+msgstr "Nouveau mot de passe"
+
+#: etc/initialdata:317 etc/upgrade/2.1.71:16
+msgid "New Pending Approval"
+msgstr "Nouvelles approbations en attente"
+
+#: html/Ticket/Elements/EditLinks:110
+msgid "New Relationships"
+msgstr "Nouvelles relations"
+
+#: html/Ticket/Elements/Tabs:35
+msgid "New Search"
+msgstr "Nouvelle recherche"
+
+#: html/Admin/Global/CustomField.html:40 html/Admin/Global/CustomFields.html:38 html/Admin/Queues/CustomField.html:51 html/Admin/Queues/CustomFields.html:39
+msgid "New custom field"
+msgstr "Nouveau champ personnalisé"
+
+#: html/Admin/Elements/GroupTabs:53 html/User/Elements/GroupTabs:51
+msgid "New group"
+msgstr "Nouveau groupe"
+
+#: html/SelfService/Prefs.html:31
+msgid "New password"
+msgstr "Nouveau mot de passe"
+
+#: lib/RT/User_Overlay.pm:764
+msgid "New password notification sent"
+msgstr "Notification de nouveau mot de passe envoyée"
+
+#: html/Admin/Elements/QueueTabs:69
+msgid "New queue"
+msgstr "Nouvelle queue"
+
+#: NOT FOUND IN SOURCE
+msgid "New request"
+msgstr "Nouvelle demande"
+
+#: html/Admin/Elements/SelectRights:41
+msgid "New rights"
+msgstr "Nouveaux droits"
+
+#: html/Admin/Global/Scrip.html:39 html/Admin/Global/Scrips.html:38 html/Admin/Queues/Scrip.html:42 html/Admin/Queues/Scrips.html:54
+msgid "New scrip"
+msgstr "Nouveau scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "New search"
+msgstr "Nouvelle recherche"
+
+#: html/Admin/Global/Template.html:59 html/Admin/Global/Templates.html:38 html/Admin/Queues/Template.html:57 html/Admin/Queues/Templates.html:49
+msgid "New template"
+msgstr "Nouveau modèle"
+
+#: html/SelfService/Elements/Tabs:47
+msgid "New ticket"
+msgstr "Nouveau ticket"
+
+#: lib/RT/Ticket_Overlay.pm:2828
+msgid "New ticket doesn't exist"
+msgstr "Nouveau ticket inconnu"
+
+#: html/Admin/Elements/UserTabs:51
+msgid "New user"
+msgstr "Nouvel utilisateur"
+
+#: html/Admin/Elements/CreateUserCalled:25
+msgid "New user called"
+msgstr "Nouvel utilisateur appelé"
+
+#: html/Admin/Queues/People.html:54 html/Ticket/Elements/EditPeople:28
+msgid "New watchers"
+msgstr "Nouveaux observateurs"
+
+#: html/Admin/Users/Prefs.html:41
+msgid "New window setting"
+msgstr "Nouveaux paramètres d'affichage"
+
+#: html/Ticket/Elements/Tabs:68
+msgid "Next"
+msgstr "Suivant"
+
+#: html/Search/Listing.html:47
+msgid "Next page"
+msgstr "Page suivante"
+
+#: html/Admin/Elements/ModifyUser:49
+msgid "NickName"
+msgstr "Surnom"
+
+#: html/Admin/Users/Modify.html:62 html/User/Prefs.html:45
+msgid "Nickname"
+msgstr "Surnom"
+
+#: html/Admin/Elements/EditCustomField:89 html/Admin/Elements/EditCustomFields:104
+msgid "No CustomField"
+msgstr "Pas de CustomField"
+
+#: html/Admin/Groups/GroupRights.html:83 html/Admin/Groups/UserRights.html:70
+msgid "No Group defined"
+msgstr "Aucun groupe défini"
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:67
+msgid "No Queue defined"
+msgstr "Aucune queue définie"
+
+#: bin/rt-crontool:55
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr "Aucun utilisateur RT trouvé. Merci de consulter votre administrateur RT"
+
+#: html/Admin/Global/Template.html:78 html/Admin/Queues/Template.html:75
+msgid "No Template"
+msgstr "Pas de modèle"
+
+#: bin/rt-commit-handler:763
+msgid "No Ticket specified. Aborting ticket "
+msgstr "Aucun ticket spécifié. Annulation de ticket"
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr "Aucun ticket spécifié. Annulation des modifications de tickets\\n\\n"
+
+#: html/Approvals/Elements/Approve:45
+msgid "No action"
+msgstr "Pas d'action"
+
+#: lib/RT/Interface/Web.pm:898
+msgid "No column specified"
+msgstr "Aucune colonne spécifiée"
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr "Commande introuvable\\n"
+
+#: html/Elements/ViewUser:35 html/Ticket/Elements/ShowRequestor:44
+msgid "No comment entered about this user"
+msgstr "Pas de commentaires concernant cet utilisateur"
+
+#: lib/RT/Ticket_Overlay.pm:2220 lib/RT/Ticket_Overlay.pm:2288
+msgid "No correspondence attached"
+msgstr "Pas de texte dans le courrier"
+
+#: lib/RT/Action/Generic.pm:149 lib/RT/Condition/Generic.pm:175 lib/RT/Search/ActiveTicketsInQueue.pm:55 lib/RT/Search/Generic.pm:112
+#. (ref $self)
+msgid "No description for %1"
+msgstr "Aucune description disponible pour %1"
+
+#: lib/RT/Users_Overlay.pm:150
+msgid "No group specified"
+msgstr "Aucun groupe spécifié"
+
+#: lib/RT/User_Overlay.pm:982
+msgid "No password set"
+msgstr "Pas de mot de passe configuré"
+
+#: lib/RT/Queue_Overlay.pm:260
+msgid "No permission to create queues"
+msgstr "Permission refusée pour la création de queue"
+
+#: lib/RT/Ticket_Overlay.pm:360
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr "Vous n'êtes pas autorisé à créer un ticket dans cette queue '%1'"
+
+#: lib/RT/User_Overlay.pm:211
+msgid "No permission to create users"
+msgstr "Permission refusée pour la création d'utilisateurs"
+
+#: html/SelfService/Display.html:117
+msgid "No permission to display that ticket"
+msgstr "Pas de permission pour afficher ce ticket"
+
+#: html/SelfService/Update.html:51
+msgid "No permission to view update ticket"
+msgstr "Pas de permission pour afficher le ticket mis à jour"
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1505
+msgid "No principal specified"
+msgstr "Aucun groupe/utilisateur spécifié"
+
+#: html/Admin/Queues/People.html:153 html/Admin/Queues/People.html:163
+msgid "No principals selected."
+msgstr "Aucun groupe/utilisateur sélectionné"
+
+#: html/Admin/Queues/index.html:34
+msgid "No queues matching search criteria found."
+msgstr "Pas de queue correspondant aux critères de recherche"
+
+#: html/Admin/Elements/SelectRights:80
+msgid "No rights found"
+msgstr "Aucun droit trouvé"
+
+#: html/Admin/Elements/SelectRights:32
+msgid "No rights granted."
+msgstr "Aucun droit accordé"
+
+#: html/Search/Bulk.html:160
+msgid "No search to operate on."
+msgstr "Pas de critère de recherche."
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr "Aucun numéro de ticket spécifié."
+
+#: lib/RT/Transaction_Overlay.pm:478 lib/RT/Transaction_Overlay.pm:516
+msgid "No transaction type specified"
+msgstr "Aucun type de transaction spécifié."
+
+#: NOT FOUND IN SOURCE
+msgid "No user or email address specified"
+msgstr "Aucun utilisateur ou adresse email spécifié"
+
+#: html/Admin/Users/index.html:35
+msgid "No users matching search criteria found."
+msgstr "Aucun utilisateur ne correspond aux critères de recherche."
+
+#: bin/rt-commit-handler:643
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr "Aucun utilisateur RT valide trouvé. Gestionnaire de cvs RT inaccessible. Merci de contacter votre administrateur RT.\\n"
+
+#: lib/RT/Interface/Web.pm:895
+msgid "No value sent to _Set!\\n"
+msgstr "Aucune valeur envoyée à _Set!\\n"
+
+#: html/Search/Elements/TicketRow:36
+msgid "Nobody"
+msgstr "Personne"
+
+#: lib/RT/Interface/Web.pm:900
+msgid "Nonexistant field?"
+msgstr "Champ inexistant?"
+
+#: NOT FOUND IN SOURCE
+msgid "Not logged in"
+msgstr "Non loggé"
+
+#: html/Elements/Header:59
+msgid "Not logged in."
+msgstr "Non connecté"
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "Non renseigné"
+
+#: html/NoAuth/Reminder.html:26
+msgid "Not yet implemented."
+msgstr "Fonction pas encore disponible"
+
+#: NOT FOUND IN SOURCE
+msgid "Not yet implemented...."
+msgstr "Fonction pas encore disponible..."
+
+#: html/Approvals/Elements/Approve:48
+msgid "Notes"
+msgstr "Notes"
+
+#: lib/RT/User_Overlay.pm:767
+msgid "Notification could not be sent"
+msgstr "Impossible d'envoyer la notification"
+
+#: etc/initialdata:93
+msgid "Notify AdminCcs"
+msgstr "Avertir les AdminCCs"
+
+#: etc/initialdata:89
+msgid "Notify AdminCcs as Comment"
+msgstr "Avertir les AdminCCs par un commentaire"
+
+#: etc/initialdata:120
+msgid "Notify Other Recipients"
+msgstr "Avertir les autres destinataires"
+
+#: etc/initialdata:116
+msgid "Notify Other Recipients as Comment"
+msgstr "Avertir les autres destinataires par un commentaire"
+
+#: etc/initialdata:85
+msgid "Notify Owner"
+msgstr "Avertir l'intervenant"
+
+#: etc/initialdata:81
+msgid "Notify Owner as Comment"
+msgstr "Avertir l'intervenant par un commentaire"
+
+#: etc/initialdata:361
+msgid "Notify Owner of their rejected ticket"
+msgstr "Avertir l'Intervenant du rejet de son ticket"
+
+#: etc/initialdata:350
+msgid "Notify Owner of their ticket has been approved by all approvers"
+msgstr "Avertir l'Intervenant de l'approbation de son ticket par tous les approbateurs"
+
+#: etc/initialdata:338
+msgid "Notify Owner of their ticket has been approved by some approver"
+msgstr "Avertir l'Intervenant de l'approbation de son ticket par un des approbateurs"
+
+#: etc/initialdata:319 etc/upgrade/2.1.71:17
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr "Avertir les intervenants et les AdminCCs de nouveaux éléments attendant leur approbation"
+
+#: etc/initialdata:77
+msgid "Notify Requestors"
+msgstr "Avertir les demandeurs"
+
+#: etc/initialdata:103
+msgid "Notify Requestors and Ccs"
+msgstr "Avertir les demandeurs et les Ccs"
+
+#: etc/initialdata:98
+msgid "Notify Requestors and Ccs as Comment"
+msgstr "Avertir les demandeurs et les CC par un commentaire"
+
+#: etc/initialdata:112
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr "Avertir les demandeurs, CCs et AdminCCs"
+
+#: etc/initialdata:108
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr "Avertir les demandeurs, CCs et AdminCCs par un commentaire"
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "Nov."
+
+#: NOT FOUND IN SOURCE
+msgid "November"
+msgstr "Novembre"
+
+#: lib/RT/Record.pm:156
+msgid "Object could not be created"
+msgstr "L'objet n'a pas pu être ajouté"
+
+#: lib/RT/Record.pm:175
+msgid "Object created"
+msgstr "Objet ajouté"
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "Oct."
+
+#: NOT FOUND IN SOURCE
+msgid "October"
+msgstr "Octobre"
+
+#: html/Elements/SelectDateRelation:34
+msgid "On"
+msgstr "Le"
+
+#: etc/initialdata:155
+msgid "On Comment"
+msgstr "Lors d'un commentaire"
+
+#: etc/initialdata:148
+msgid "On Correspond"
+msgstr "Lors d'un courrier"
+
+#: etc/initialdata:137
+msgid "On Create"
+msgstr "Lors d'une création"
+
+#: etc/initialdata:169
+msgid "On Owner Change"
+msgstr "Lors d'un changement d'intervenant"
+
+#: etc/initialdata:177
+msgid "On Queue Change"
+msgstr "Lors d'un changement de queue"
+
+#: etc/initialdata:183
+msgid "On Resolve"
+msgstr "Lors de la résolution/clôture"
+
+#: etc/initialdata:161
+msgid "On Status Change"
+msgstr "Lors d'un changement de statut"
+
+#: etc/initialdata:142
+msgid "On Transaction"
+msgstr "Lors d'une transaction"
+
+#: html/Approvals/Elements/PendingMyApproval:49
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr "Ne montrer que les approbations pour les demandes créées après %1"
+
+#: html/Approvals/Elements/PendingMyApproval:47
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr "Ne montrer que les approbations pour les demandes créées avant %1"
+
+#: html/Elements/Quicksearch:30
+msgid "Open"
+msgstr "Ouvert"
+
+#: html/Ticket/Elements/Tabs:135
+msgid "Open it"
+msgstr "Ouvrir"
+
+#: NOT FOUND IN SOURCE
+msgid "Open requests"
+msgstr "Ouvrir les demandes"
+
+#: html/SelfService/Elements/Tabs:41
+msgid "Open tickets"
+msgstr "Ouvrir les tickets"
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in a new window"
+msgstr "Ouvrir les tickets (depuis une liste) dans une nouvelle fenêtre."
+
+#: html/Admin/Users/Prefs.html:39
+msgid "Open tickets (from listing) in another window"
+msgstr "Ouvrir les tickets (depuis une liste) dans une autre fenêtre."
+
+#: etc/initialdata:132
+msgid "Open tickets on correspondence"
+msgstr "Ouvrir les tickets lors d'une correspondance"
+
+#: html/Search/Elements/PickRestriction:100
+msgid "Ordering and sorting"
+msgstr "Ranger et classer"
+
+#: html/Admin/Elements/ModifyUser:45 html/Admin/Users/Modify.html:116 html/Elements/SelectUsers:28 html/User/Prefs.html:85
+msgid "Organization"
+msgstr "Organisation"
+
+#: html/Approvals/Elements/Approve:32
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr "Ticket source: n°%1"
+
+#: html/Admin/Elements/ModifyQueue:54 html/Admin/Queues/Modify.html:68
+msgid "Over time, priority moves toward"
+msgstr "Temps dépassé, priorité déplacée"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Own tickets"
+msgstr "Tickets propres"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "OwnTicket"
+msgstr "PrendreTicket"
+
+#: etc/initialdata:38 html/Elements/MyRequests:31 html/SelfService/Elements/MyRequests:29 html/Ticket/Create.html:47 html/Ticket/Elements/EditPeople:42 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/ShowPeople:26 html/Ticket/Update.html:62 lib/RT/ACE_Overlay.pm:85 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "Intervenant"
+
+#: NOT FOUND IN SOURCE
+msgid "Owner changed from %1 to %2"
+msgstr "Intervenant changé de %1 en %2"
+
+#: lib/RT/Transaction_Overlay.pm:582
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr "Intervenant forcé de %1 à %2"
+
+#: html/Search/Elements/PickRestriction:30
+msgid "Owner is"
+msgstr "L'intervenant est"
+
+#: html/Admin/Users/Modify.html:173 html/User/Prefs.html:55
+msgid "Pager"
+msgstr "Bipeur"
+
+#: html/Admin/Elements/ModifyUser:73
+msgid "PagerPhone"
+msgstr "PagerPhone"
+
+#: NOT FOUND IN SOURCE
+msgid "Parent"
+msgstr ""
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/BulkLinks:38 html/Ticket/Elements/EditLinks:126 html/Ticket/Elements/EditLinks:57 html/Ticket/Elements/ShowLinks:46
+msgid "Parents"
+msgstr "Parents"
+
+#: html/Elements/Login:52 html/User/Prefs.html:60
+msgid "Password"
+msgstr "Mot de passe"
+
+#: html/NoAuth/Reminder.html:24
+msgid "Password Reminder"
+msgstr "Pense-bête pour votre mot de passe"
+
+#: lib/RT/User_Overlay.pm:228 lib/RT/User_Overlay.pm:985
+msgid "Password too short"
+msgstr "Mot de passe trop court"
+
+#: html/Admin/Users/Modify.html:290 html/User/Prefs.html:171
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "Mot de passe: %1"
+
+#: html/Admin/Users/Modify.html:292
+msgid "Passwords do not match."
+msgstr "Les mots de passes sont différents"
+
+#: html/User/Prefs.html:173
+msgid "Passwords do not match. Your password has not been changed"
+msgstr "Les mots de passe sont différents. Votre mot de passe n'a pas été modifié"
+
+#: html/Ticket/Elements/ShowSummary:44 html/Ticket/Elements/Tabs:95 html/Ticket/ModifyAll.html:50
+msgid "People"
+msgstr "Personnes"
+
+#: etc/initialdata:125
+msgid "Perform a user-defined action"
+msgstr "Réaliser une action définie par l'utilisateur"
+
+#: lib/RT/ACE_Overlay.pm:230 lib/RT/ACE_Overlay.pm:236 lib/RT/ACE_Overlay.pm:562 lib/RT/ACE_Overlay.pm:572 lib/RT/ACE_Overlay.pm:582 lib/RT/ACE_Overlay.pm:647 lib/RT/CurrentUser.pm:82 lib/RT/CurrentUser.pm:91 lib/RT/CustomField_Overlay.pm:100 lib/RT/CustomField_Overlay.pm:201 lib/RT/CustomField_Overlay.pm:233 lib/RT/CustomField_Overlay.pm:511 lib/RT/CustomField_Overlay.pm:90 lib/RT/Group_Overlay.pm:1094 lib/RT/Group_Overlay.pm:1098 lib/RT/Group_Overlay.pm:1107 lib/RT/Group_Overlay.pm:1158 lib/RT/Group_Overlay.pm:1162 lib/RT/Group_Overlay.pm:1168 lib/RT/Group_Overlay.pm:425 lib/RT/Group_Overlay.pm:517 lib/RT/Group_Overlay.pm:595 lib/RT/Group_Overlay.pm:603 lib/RT/Group_Overlay.pm:700 lib/RT/Group_Overlay.pm:704 lib/RT/Group_Overlay.pm:710 lib/RT/Group_Overlay.pm:903 lib/RT/Group_Overlay.pm:907 lib/RT/Group_Overlay.pm:920 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:125 lib/RT/Scrip_Overlay.pm:136 lib/RT/Scrip_Overlay.pm:196 lib/RT/Scrip_Overlay.pm:433 lib/RT/Template_Overlay.pm:283 lib/RT/Template_Overlay.pm:87 lib/RT/Template_Overlay.pm:93 lib/RT/Ticket_Overlay.pm:1377 lib/RT/Ticket_Overlay.pm:1387 lib/RT/Ticket_Overlay.pm:1401 lib/RT/Ticket_Overlay.pm:1535 lib/RT/Ticket_Overlay.pm:1544 lib/RT/Ticket_Overlay.pm:1557 lib/RT/Ticket_Overlay.pm:1906 lib/RT/Ticket_Overlay.pm:2044 lib/RT/Ticket_Overlay.pm:2208 lib/RT/Ticket_Overlay.pm:2275 lib/RT/Ticket_Overlay.pm:2634 lib/RT/Ticket_Overlay.pm:2715 lib/RT/Ticket_Overlay.pm:2819 lib/RT/Ticket_Overlay.pm:2834 lib/RT/Ticket_Overlay.pm:3033 lib/RT/Ticket_Overlay.pm:3043 lib/RT/Ticket_Overlay.pm:3048 lib/RT/Ticket_Overlay.pm:3270 lib/RT/Ticket_Overlay.pm:3468 lib/RT/Ticket_Overlay.pm:3630 lib/RT/Ticket_Overlay.pm:3682 lib/RT/Ticket_Overlay.pm:3860 lib/RT/Transaction_Overlay.pm:466 lib/RT/Transaction_Overlay.pm:473 lib/RT/Transaction_Overlay.pm:502 lib/RT/Transaction_Overlay.pm:509 lib/RT/User_Overlay.pm:1079 lib/RT/User_Overlay.pm:1527 lib/RT/User_Overlay.pm:687 lib/RT/User_Overlay.pm:722 lib/RT/User_Overlay.pm:978
+msgid "Permission Denied"
+msgstr "Accès refusé"
+
+#: html/User/Elements/Tabs:34
+msgid "Personal Groups"
+msgstr "Groupes personnels"
+
+#: html/User/Groups/index.html:29 html/User/Groups/index.html:39
+msgid "Personal groups"
+msgstr "Groupes personnels"
+
+#: html/User/Elements/DelegateRights:36
+msgid "Personal groups:"
+msgstr "Groupes personnels:"
+
+#: html/Admin/Users/Modify.html:155 html/User/Prefs.html:48
+msgid "Phone numbers"
+msgstr "Numéros de téléphone"
+
+#: NOT FOUND IN SOURCE
+msgid "Placeholder"
+msgstr "Paramètre fictif"
+
+#: html/Elements/Header:51 html/Elements/Tabs:52 html/SelfService/Elements/Tabs:50 html/SelfService/Prefs.html:24 html/User/Prefs.html:24 html/User/Prefs.html:27
+msgid "Preferences"
+msgstr "Préférences"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr "Préférences"
+
+#: lib/RT/Action/Generic.pm:159
+msgid "Prepare Stubbed"
+msgstr "Préparation interrompue"
+
+#: html/Ticket/Elements/Tabs:60
+msgid "Prev"
+msgstr "Précédent"
+
+#: html/Search/Listing.html:43
+msgid "Previous page"
+msgstr "Page précédente"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr "Pri."
+
+#: lib/RT/ACE_Overlay.pm:132 lib/RT/ACE_Overlay.pm:207 lib/RT/ACE_Overlay.pm:551
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr "Principal %1 non trouvé"
+
+#: html/Search/Elements/PickRestriction:53 html/Ticket/Create.html:153 html/Ticket/Elements/EditBasics:53 html/Ticket/Elements/ShowBasics:38 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "Priorité"
+
+#: html/Admin/Elements/ModifyQueue:50 html/Admin/Queues/Modify.html:64
+msgid "Priority starts at"
+msgstr "La priorité débute à "
+
+#: etc/initialdata:25
+msgid "Privileged"
+msgstr "Privilégié"
+
+#: html/Admin/Users/Modify.html:270 html/User/Prefs.html:162
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr "Statuts privilégiés : %1"
+
+#: html/Admin/Users/index.html:61
+msgid "Privileged users"
+msgstr "Utilisateurs privilégiés"
+
+#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59
+msgid "Pseudogroup for internal use"
+msgstr "Pseudo groupe pour usage interne"
+
+#: html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Elements/Quicksearch:28 html/Search/Elements/PickRestriction:45 html/SelfService/Create.html:32 html/Ticket/Create.html:37 html/Ticket/Elements/EditBasics:63 html/Ticket/Elements/ShowBasics:42 html/User/Elements/DelegateRights:79 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "Queue"
+
+#: html/Admin/Queues/CustomField.html:41 html/Admin/Queues/Scrip.html:49 html/Admin/Queues/Scrips.html:47 html/Admin/Queues/Templates.html:43
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr "Queue %1 non trouvée"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr "Queue '%1' inconnue\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Keyword Selections"
+msgstr "Sélection des mots clé de queue"
+
+#: html/Admin/Elements/ModifyQueue:30 html/Admin/Queues/Modify.html:42
+msgid "Queue Name"
+msgstr "Nom de la queue"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr "Scrips de queue"
+
+#: lib/RT/Queue_Overlay.pm:264
+msgid "Queue already exists"
+msgstr "Queue déjà créée"
+
+#: lib/RT/Queue_Overlay.pm:273 lib/RT/Queue_Overlay.pm:279
+msgid "Queue could not be created"
+msgstr "Impossible de créer la queue"
+
+#: html/Ticket/Create.html:204
+msgid "Queue could not be loaded."
+msgstr "Queue ne pouvant être chargée"
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:283
+msgid "Queue created"
+msgstr "Queue créée"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue is not specified."
+msgstr "Queue non spécifié"
+
+#: html/SelfService/Display.html:70 lib/RT/CustomField_Overlay.pm:97
+msgid "Queue not found"
+msgstr "Queue inconnue"
+
+#: html/Admin/Elements/Tabs:37 html/Admin/index.html:34
+msgid "Queues"
+msgstr "Queues"
+
+#: html/Elements/Quicksearch:24
+msgid "Quick search"
+msgstr "Recherche rapide"
+
+#: html/Elements/Login:44
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr "RT %1"
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr "RT %1 pour %2"
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: html/Admin/index.html:24 html/Admin/index.html:25
+msgid "RT Administration"
+msgstr "Administration RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr "Erreur d'authentification RT."
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr "Avis de rejet RT: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr "Erreur de configuration RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr "Erreur critique RT. Courrier non enregistré !"
+
+#: html/Elements/Error:41 html/SelfService/Error.html:40
+msgid "RT Error"
+msgstr "Erreur RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr "RT a reçu un e-mail (%1) de lui-même."
+
+#: NOT FOUND IN SOURCE
+msgid "RT Recieved mail (%1) from itself."
+msgstr "RT a reçu du courrier (%1) de lui même"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Self Service / Closed Tickets"
+msgstr "RT Self Service / Tickets résolus"
+
+#: html/index.html:24 html/index.html:27
+msgid "RT at a glance"
+msgstr "RT en un coup d'oeil"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr "RT n'a pas réussi à vous identifier"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr "RT n'a pas pu trouver de demandeur par sa recherche dans une base externe"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr "RT n'a pas trouvé la queue"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr "RT n'a pas réussi à valider cette signature PGP. \\n"
+
+#: html/Elements/PageLayout:85
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr "RT pour %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr "RT pour %1: %2"
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr "RT a exécuté vos commandes"
+
+#: html/Elements/Login:94
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT est &copy; Copyright 1996-2002 Jesse Vincent &lt;jesse@bestpractical.com&gt;. Distribué sous <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 de la licence générale GNU.</a>"
+
+#: NOT FOUND IN SOURCE
+msgid "RT is &copy; Copyright 1996-2002 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT est &copy; Copyright 1996-2002 Jesse Vincent &lt;jesse@bestpractical.com&gt;. Distribué sous <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 de la licence générale GNU.</a>"
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr "RT pense que ce courrier peut être un avis de non-distribution"
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr "RT va traiter ce courrier comme s'il n'était pas signé.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr "L'interface d'utilisation de RT par email utilise une authentification PGP. Soit vous n'avez pas signé votre courrier, soit la signature est n'a pas pu être vérifiée"
+
+#: html/Admin/Users/Modify.html:57 html/Admin/Users/Prefs.html:51 html/User/Prefs.html:43
+msgid "Real Name"
+msgstr "Nom"
+
+#: html/Admin/Elements/ModifyUser:47
+msgid "RealName"
+msgstr "RealName"
+
+#: lib/RT/Transaction_Overlay.pm:631
+#. ($value)
+msgid "Reference by %1 added"
+msgstr "Ajout d'une référence par %1"
+
+#: lib/RT/Transaction_Overlay.pm:660
+#. ($value)
+msgid "Reference by %1 deleted"
+msgstr "Suppression de la référence par %1"
+
+#: lib/RT/Transaction_Overlay.pm:629
+#. ($value)
+msgid "Reference to %1 added"
+msgstr "Ajout d'une reference à %1"
+
+#: lib/RT/Transaction_Overlay.pm:658
+#. ($value)
+msgid "Reference to %1 deleted"
+msgstr "Suppression d'une reference à %1"
+
+#: html/Ticket/Create.html:184 html/Ticket/Elements/BulkLinks:50 html/Ticket/Elements/EditLinks:138 html/Ticket/Elements/EditLinks:93 html/Ticket/Elements/ShowLinks:70
+msgid "Referred to by"
+msgstr "Mentionné par"
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:183 html/Ticket/Elements/BulkLinks:46 html/Ticket/Elements/EditLinks:134 html/Ticket/Elements/EditLinks:79 html/Ticket/Elements/ShowLinks:60
+msgid "Refers to"
+msgstr "Se rapporte à"
+
+#: NOT FOUND IN SOURCE
+msgid "RefersTo"
+msgstr "SeRapporteA"
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr "Affiner"
+
+#: html/Search/Elements/PickRestriction:26
+msgid "Refine search"
+msgstr "Affiner la recherche"
+
+#: html/Elements/Refresh:35
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "Rafraîchir cette page toutes les %1 minutes."
+
+#: html/Ticket/Create.html:173 html/Ticket/Elements/ShowSummary:61 html/Ticket/ModifyAll.html:56
+msgid "Relationships"
+msgstr "Relations"
+
+#: html/Search/Bulk.html:97
+msgid "Remove AdminCc"
+msgstr "Enlever AdminCc "
+
+#: html/Search/Bulk.html:93
+msgid "Remove Cc"
+msgstr "Enlever Cc"
+
+#: html/Search/Bulk.html:89
+msgid "Remove Requestor"
+msgstr "Enlever Demandeur"
+
+#: html/Ticket/Elements/ShowTransaction:159 html/Ticket/Elements/Tabs:121
+msgid "Reply"
+msgstr "Répondre"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Reply to tickets"
+msgstr "Répondre aux tickets"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "ReplyToTicket"
+msgstr "RépondreTicket"
+
+#: etc/initialdata:44 html/Ticket/Update.html:39 lib/RT/ACE_Overlay.pm:86
+msgid "Requestor"
+msgstr "Demandeur"
+
+#: html/Search/Elements/PickRestriction:37
+msgid "Requestor email address"
+msgstr "Adresse email du demandeur"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr "Demandeur(s)"
+
+#: NOT FOUND IN SOURCE
+msgid "RequestorAddresses"
+msgstr "AdresseDuDemandeur"
+
+#: html/SelfService/Create.html:40 html/Ticket/Create.html:55 html/Ticket/Elements/EditPeople:47 html/Ticket/Elements/ShowPeople:30
+msgid "Requestors"
+msgstr "Demandeurs"
+
+#: html/Admin/Elements/ModifyQueue:60 html/Admin/Queues/Modify.html:74
+msgid "Requests should be due in"
+msgstr "Le demande doit être résolue dans"
+
+#: html/Elements/Submit:61
+msgid "Reset"
+msgstr "Remise à zéro"
+
+#: html/Admin/Users/Modify.html:158 html/User/Prefs.html:49
+msgid "Residence"
+msgstr "Domicile"
+
+#: html/Ticket/Elements/Tabs:131
+msgid "Resolve"
+msgstr "Résoudre"
+
+#: html/Ticket/Update.html:137
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr "Résoudre ticket n°%1 (%2)"
+
+#: etc/initialdata:308 html/Elements/SelectDateType:27 lib/RT/Ticket_Overlay.pm:1206
+msgid "Resolved"
+msgstr "Résolu"
+
+#: html/Search/Bulk.html:132 html/Ticket/ModifyAll.html:72 html/Ticket/Update.html:71
+msgid "Response to requestors"
+msgstr "Réponse aux demandeurs"
+
+#: html/Elements/ListActions:25
+msgid "Results"
+msgstr "Résultats"
+
+#: html/Search/Elements/PickRestriction:104
+msgid "Results per page"
+msgstr "Nb tickets par page"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:99 html/User/Prefs.html:71
+msgid "Retype Password"
+msgstr "Saisissez à nouveau votre mot de passe"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr "Le droit %1 introuvable pour %2 %3 dans le périmètre %4 (%5)\\n"
+
+#: lib/RT/ACE_Overlay.pm:612
+msgid "Right Delegated"
+msgstr "Droit délégué"
+
+#: lib/RT/ACE_Overlay.pm:302
+msgid "Right Granted"
+msgstr "Droit accordé"
+
+#: lib/RT/ACE_Overlay.pm:160
+msgid "Right Loaded"
+msgstr "Droit activé"
+
+#: lib/RT/ACE_Overlay.pm:677 lib/RT/ACE_Overlay.pm:692
+msgid "Right could not be revoked"
+msgstr "Droit irrévocable"
+
+#: html/User/Delegation.html:63
+msgid "Right not found"
+msgstr "Droit inconnu"
+
+#: lib/RT/ACE_Overlay.pm:542 lib/RT/ACE_Overlay.pm:637
+msgid "Right not loaded."
+msgstr "Droit non activé"
+
+#: lib/RT/ACE_Overlay.pm:688
+msgid "Right revoked"
+msgstr "Droit révoqué"
+
+#: html/Admin/Elements/UserTabs:40
+msgid "Rights"
+msgstr "Droits"
+
+#: lib/RT/Interface/Web.pm:794
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr "Les droits n'on pas pu être attribués à %1"
+
+#: lib/RT/Interface/Web.pm:827
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr "Les droits n'ont pas pu être révoqués pour %1"
+
+#: html/Admin/Global/GroupRights.html:50 html/Admin/Queues/GroupRights.html:52
+msgid "Roles"
+msgstr "Rôles"
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr "ApprobationDeRoot"
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "Sam."
+
+#: html/Admin/Queues/People.html:104 html/Ticket/Modify.html:38 html/Ticket/ModifyAll.html:93 html/Ticket/ModifyLinks.html:38 html/Ticket/ModifyPeople.html:37
+msgid "Save Changes"
+msgstr "Enregistrer les modifications"
+
+#: NOT FOUND IN SOURCE
+msgid "Save changes"
+msgstr "Enregistrer les modifications"
+
+#: html/Admin/Global/Scrip.html:48 html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->id)
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr "Scrip n°%1"
+
+#: lib/RT/Scrip_Overlay.pm:175
+msgid "Scrip Created"
+msgstr "Scrip ajouté"
+
+#: html/Admin/Elements/EditScrips:83
+msgid "Scrip deleted"
+msgstr "Scrip supprimé"
+
+#: html/Admin/Elements/QueueTabs:45 html/Admin/Elements/SystemTabs:32 html/Admin/Global/index.html:40
+msgid "Scrips"
+msgstr "Scrips"
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr "Scrips pour %1\\n"
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr "Scrips s'appliquant à toutes les queues"
+
+#: html/Elements/SimpleSearch:26 html/Search/Elements/PickRestriction:125 html/Ticket/Elements/Tabs:158
+msgid "Search"
+msgstr "Rechercher"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr "Critère de recherche"
+
+#: html/Approvals/Elements/PendingMyApproval:38
+msgid "Search for approvals"
+msgstr "Chercher des approbations"
+
+#: bin/rt-crontool:187
+msgid "Security:"
+msgstr "Sécurité:"
+
+#: lib/RT/Queue_Overlay.pm:66
+msgid "SeeQueue"
+msgstr "VoirQueue"
+
+#: html/Admin/Groups/index.html:39
+msgid "Select a group"
+msgstr "Sélectionner un groupe"
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr "Choisir une queue"
+
+#: html/Admin/Users/index.html:24 html/Admin/Users/index.html:27
+msgid "Select a user"
+msgstr "Sélectionner un utilisateur"
+
+#: html/Admin/Global/CustomField.html:37 html/Admin/Global/CustomFields.html:35
+msgid "Select custom field"
+msgstr "Selectionner le champ personnalisé"
+
+#: html/Admin/Elements/GroupTabs:51 html/User/Elements/GroupTabs:49
+msgid "Select group"
+msgstr "Sélectionner le groupe"
+
+#: lib/RT/CustomField_Overlay.pm:421
+msgid "Select multiple values"
+msgstr "Choisir plusieurs valeurs"
+
+#: lib/RT/CustomField_Overlay.pm:418
+msgid "Select one value"
+msgstr "Choisir une valeur"
+
+#: html/Admin/Elements/QueueTabs:66
+msgid "Select queue"
+msgstr "Selectionner la queue"
+
+#: html/Admin/Global/Scrip.html:36 html/Admin/Global/Scrips.html:35 html/Admin/Queues/Scrip.html:39 html/Admin/Queues/Scrips.html:51
+msgid "Select scrip"
+msgstr "Selectionner le scrip"
+
+#: html/Admin/Global/Template.html:56 html/Admin/Global/Templates.html:35 html/Admin/Queues/Template.html:54 html/Admin/Queues/Templates.html:46
+msgid "Select template"
+msgstr "Selectionner le modèle"
+
+#: html/Admin/Elements/UserTabs:48
+msgid "Select user"
+msgstr "Selectionner l'utilisateur"
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectMultiple"
+msgstr "ChoixMultiples"
+
+#: lib/RT/CustomField_Overlay.pm:34
+msgid "SelectSingle"
+msgstr "ChoixSimple"
+
+#: NOT FOUND IN SOURCE
+msgid "Self Service"
+msgstr "Self Service"
+
+#: etc/initialdata:113
+msgid "Send mail to all watchers"
+msgstr "Envoyer un courrier à tous les observateurs"
+
+#: etc/initialdata:109
+msgid "Send mail to all watchers as a \"comment\""
+msgstr "Envoyer un courrier à tous les observateurs en tant que \"commentaire\""
+
+#: etc/initialdata:104
+msgid "Send mail to requestors and Ccs"
+msgstr "Envoyer un courrier aux demandeurs et aux CCs"
+
+#: etc/initialdata:99
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr "Envoyer un courrier aux demandeurs et aux CCs en tant que commentaire"
+
+#: etc/initialdata:78
+msgid "Sends a message to the requestors"
+msgstr "Envoyer un courrier aux demandeurs"
+
+#: etc/initialdata:117 etc/initialdata:121
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr "Envoyer un courrier aux CCs et Bccs explicitement indiqués"
+
+#: etc/initialdata:94
+msgid "Sends mail to the administrative Ccs"
+msgstr "Envoyer un mail aux AdminCCs"
+
+#: etc/initialdata:90
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr "Envoyer un mail aux AdminCCs en tant que commentaire"
+
+#: etc/initialdata:82 etc/initialdata:86
+msgid "Sends mail to the owner"
+msgstr "Envoyer un courrier à l'intervenant"
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "Sep."
+
+#: NOT FOUND IN SOURCE
+msgid "September"
+msgstr "Septembre"
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr "Afficher les résultats"
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show approved requests"
+msgstr "Afficher les requêtes approuvées"
+
+#: html/Ticket/Create.html:143 html/Ticket/Create.html:33
+msgid "Show basics"
+msgstr "Affichage court"
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show denied requests"
+msgstr "Afficher les requêtes refusées"
+
+#: html/Ticket/Create.html:143 html/Ticket/Create.html:33
+msgid "Show details"
+msgstr "Affichage long"
+
+#: html/Approvals/Elements/PendingMyApproval:42
+msgid "Show pending requests"
+msgstr "Afficher les requêtes en attente"
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show requests awaiting other approvals"
+msgstr "Afficher les requêtes attendant d'autres approbations"
+
+#: lib/RT/Queue_Overlay.pm:80
+msgid "Show ticket private commentary"
+msgstr "Afficher les commentaires privés du ticket"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Show ticket summaries"
+msgstr "Afficher les résumés de tickets"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "ShowACL"
+msgstr "AfficherACL"
+
+#: lib/RT/Queue_Overlay.pm:77
+msgid "ShowScrips"
+msgstr "AfficherScrips"
+
+#: lib/RT/Queue_Overlay.pm:74
+msgid "ShowTemplate"
+msgstr "AfficherModèle"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowTicket"
+msgstr "AfficherTicket"
+
+#: lib/RT/Queue_Overlay.pm:80
+msgid "ShowTicketComments"
+msgstr "AfficherCommentairesTickets"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr "S'identifier en tant que demandeur ou CC de queue ou de ticket"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr "S'identifier en tant qu'AdminCC de ticket ou de queue"
+
+#: html/Admin/Elements/ModifyUser:38 html/Admin/Users/Modify.html:190 html/Admin/Users/Prefs.html:31 html/User/Prefs.html:111
+msgid "Signature"
+msgstr "Signature"
+
+#: NOT FOUND IN SOURCE
+msgid "Signed in as %1"
+msgstr "Connecté en tant que %1"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:25
+msgid "Single"
+msgstr "Unique"
+
+#: html/Elements/Header:50
+msgid "Skip Menu"
+msgstr "Passer le menu"
+
+#: html/Admin/Elements/AddCustomFieldValue:27
+msgid "Sort"
+msgstr "Trier"
+
+#: NOT FOUND IN SOURCE
+msgid "Sort key"
+msgstr "Ordre de tri"
+
+#: html/Search/Elements/PickRestriction:108
+msgid "Sort results by"
+msgstr "Trier les résultats par"
+
+#: NOT FOUND IN SOURCE
+msgid "SortOrder"
+msgstr "SortOrder"
+
+#: NOT FOUND IN SOURCE
+msgid "Stalled"
+msgstr "Bloqué"
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr "Page de début"
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/EditDates:31 html/Ticket/Elements/ShowDates:34
+msgid "Started"
+msgstr "Ouvert le"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr "La date de démarrage '%1' n'a pas pu être analysée"
+
+#: html/Elements/SelectDateType:30 html/Ticket/Create.html:165 html/Ticket/Elements/EditDates:26 html/Ticket/Elements/ShowDates:30
+msgid "Starts"
+msgstr "Débute"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr "Débute le"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr "La date de début '%1' n'a pas pu être analysée"
+
+#: html/Admin/Elements/ModifyUser:81 html/Admin/Users/Modify.html:137 html/User/Prefs.html:93
+msgid "State"
+msgstr "Etat"
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Search/Elements/PickRestriction:73 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:30 html/Ticket/Create.html:41 html/Ticket/Elements/EditBasics:37 html/Ticket/Elements/ShowBasics:30 html/Ticket/Update.html:59 lib/RT/Ticket_Overlay.pm:1200 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "Statut"
+
+#: etc/initialdata:294
+msgid "Status Change"
+msgstr "Changement de statut"
+
+#: lib/RT/Transaction_Overlay.pm:528
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr "Statut modifié de %1 à %2 "
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr "ChangementDeStatut"
+
+#: html/Ticket/Elements/Tabs:146
+msgid "Steal"
+msgstr "Voler"
+
+#: lib/RT/Queue_Overlay.pm:91
+msgid "Steal tickets"
+msgstr "Voler les tickets "
+
+#: lib/RT/Queue_Overlay.pm:91
+msgid "StealTicket"
+msgstr "VolerTicket"
+
+#: lib/RT/Transaction_Overlay.pm:587
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "Volé à %1"
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28 html/Search/Bulk.html:135 html/Search/Elements/PickRestriction:42 html/SelfService/Create.html:56 html/SelfService/Elements/MyRequests:27 html/SelfService/Update.html:31 html/Ticket/Create.html:83 html/Ticket/Elements/EditBasics:27 html/Ticket/ModifyAll.html:78 html/Ticket/Update.html:75 lib/RT/Ticket_Overlay.pm:1196 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "Sujet"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:609
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr "Sujet modifié en %1"
+
+#: html/Elements/Submit:58
+msgid "Submit"
+msgstr "Valider"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr "Soumettre flux de travail"
+
+#: lib/RT/Group_Overlay.pm:748
+msgid "Succeeded"
+msgstr "Réussi"
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "Dim."
+
+#: lib/RT/System.pm:53
+msgid "SuperUser"
+msgstr "SuperUtilisateur"
+
+#: html/User/Elements/DelegateRights:76
+msgid "System"
+msgstr "Système"
+
+#: html/Admin/Elements/SelectRights:80 lib/RT/ACE_Overlay.pm:566 lib/RT/Interface/Web.pm:793 lib/RT/Interface/Web.pm:826
+msgid "System Error"
+msgstr "Erreur système"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. Right not granted."
+msgstr "Erreur Système. Droit non délégué."
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. right not granted"
+msgstr "Erreur Système. Droit non délégué"
+
+#: lib/RT/ACE_Overlay.pm:615
+msgid "System error. Right not delegated."
+msgstr "Erreur système. Droit non délégué."
+
+#: lib/RT/ACE_Overlay.pm:145 lib/RT/ACE_Overlay.pm:222 lib/RT/ACE_Overlay.pm:305 lib/RT/ACE_Overlay.pm:897
+msgid "System error. Right not granted."
+msgstr "Erreur système. Droit non accordé"
+
+#: NOT FOUND IN SOURCE
+msgid "System error. Unable to grant rights."
+msgstr "Erreur Système. Imposible de déléguer les droits"
+
+#: html/Admin/Global/GroupRights.html:34 html/Admin/Groups/GroupRights.html:36 html/Admin/Queues/GroupRights.html:35
+msgid "System groups"
+msgstr "Groupes système"
+
+#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53
+msgid "SystemRolegroup for internal use"
+msgstr "SystemRolegroup à usage interne"
+
+#: lib/RT/CurrentUser.pm:319
+msgid "TEST_STRING"
+msgstr "Chaîne_de_test"
+
+#: html/Ticket/Elements/Tabs:142
+msgid "Take"
+msgstr "Prendre"
+
+#: lib/RT/Queue_Overlay.pm:89
+msgid "Take tickets"
+msgstr "Prendre les tickets"
+
+#: lib/RT/Queue_Overlay.pm:89
+msgid "TakeTicket"
+msgstr "PrendreTicket"
+
+#: lib/RT/Transaction_Overlay.pm:573
+msgid "Taken"
+msgstr "Pris"
+
+#: html/Admin/Elements/EditScrip:80
+msgid "Template"
+msgstr "Modèle"
+
+#: html/Admin/Global/Template.html:90 html/Admin/Queues/Template.html:89
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr "Modèle n°%1"
+
+#: html/Admin/Elements/EditTemplates:88
+msgid "Template deleted"
+msgstr "Modèle supprimé"
+
+#: lib/RT/Scrip_Overlay.pm:152
+msgid "Template not found"
+msgstr "Modèle inconnu"
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr "Modèle inconnu\\n"
+
+#: lib/RT/Template_Overlay.pm:352
+msgid "Template parsed"
+msgstr "Modèle analysé"
+
+#: html/Admin/Elements/QueueTabs:48 html/Admin/Elements/SystemTabs:35 html/Admin/Global/index.html:44
+msgid "Templates"
+msgstr "Modèles"
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr "Modèles pour %1\\n "
+
+#: lib/RT/Interface/Web.pm:894
+msgid "That is already the current value"
+msgstr "Ceci est déjà la valeur actuelle"
+
+#: lib/RT/CustomField_Overlay.pm:242
+msgid "That is not a value for this custom field"
+msgstr "Valeur incorrecte pour ce champ personnalisé."
+
+#: lib/RT/Ticket_Overlay.pm:1917
+msgid "That is the same value"
+msgstr "Valeur identique"
+
+#: lib/RT/ACE_Overlay.pm:287 lib/RT/ACE_Overlay.pm:596
+msgid "That principal already has that right"
+msgstr "Ce groupe/utilisateur dispose déjà de ce droit"
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr "Ce groupe/utilisateur est déjà un %1 pour cette queue"
+
+#: lib/RT/Ticket_Overlay.pm:1451
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr "Ce groupe/utilisateur est déjà un %1 pour ce ticket"
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr "Ce groupe/utilisateur n'est pas un %1 pour cette queue"
+
+#: lib/RT/Ticket_Overlay.pm:1568
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr "Ce groupe/utilisateur n'est pas un %1 pour ce ticket"
+
+#: lib/RT/Ticket_Overlay.pm:1913
+msgid "That queue does not exist"
+msgstr "Queue inconnue"
+
+#: lib/RT/Ticket_Overlay.pm:3274
+msgid "That ticket has unresolved dependencies"
+msgstr "Ticket ayant des tickets fils ou dépendants non résolus"
+
+#: NOT FOUND IN SOURCE
+msgid "That user already has that right"
+msgstr "Cet utilisateur possède déjà ce droit."
+
+#: lib/RT/Ticket_Overlay.pm:3084
+msgid "That user already owns that ticket"
+msgstr "Cet utilisateur possède déjà ce ticket."
+
+#: lib/RT/Ticket_Overlay.pm:3056
+msgid "That user does not exist"
+msgstr "Utilisateur inconnu"
+
+#: lib/RT/User_Overlay.pm:376
+msgid "That user is already privileged"
+msgstr "Utilisateur possédant déjà un statut privilégié."
+
+#: lib/RT/User_Overlay.pm:397
+msgid "That user is already unprivileged"
+msgstr "Utilisateur déjà sans privilèges."
+
+#: lib/RT/User_Overlay.pm:389
+msgid "That user is now privileged"
+msgstr "Utilisateur bénéficiant à présent du statut privilégié"
+
+#: lib/RT/User_Overlay.pm:410
+msgid "That user is now unprivileged"
+msgstr "Utilisateur à présent sans statut privilégié "
+
+#: NOT FOUND IN SOURCE
+msgid "That user is now unprivilegedileged"
+msgstr "Cet utilisateur a perdu ses droits"
+
+#: lib/RT/Ticket_Overlay.pm:3077
+msgid "That user may not own tickets in that queue"
+msgstr "Cet utilisateur peut ne pas avoir de ticket dans cette queue."
+
+#: lib/RT/Link_Overlay.pm:205
+msgid "That's not a numerical id"
+msgstr "ID non numérique"
+
+#: html/SelfService/Display.html:31 html/Ticket/Create.html:149 html/Ticket/Elements/ShowSummary:27
+msgid "The Basics"
+msgstr "Eléments de base"
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The CC of a ticket"
+msgstr "Le CC d'un ticket"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The administrative CC of a ticket"
+msgstr "L'AdminCC d'un ticket"
+
+#: lib/RT/Ticket_Overlay.pm:2244
+msgid "The comment has been recorded"
+msgstr "Commentaire enregistré"
+
+#: bin/rt-crontool:197
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr "Cette commande trouve tous les tickets actifs de la queue 'general' et positionne leur priorité à 99 s'ils n'ont pas été touchés depuis quatre heures:"
+
+#: bin/rt-commit-handler:755 bin/rt-commit-handler:765
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr "Les commandes suivantes n'ont pas été traitées :\\n\\n"
+
+#: lib/RT/Interface/Web.pm:897
+msgid "The new value has been set."
+msgstr "La nouvelle valeur est enregistrée"
+
+#: lib/RT/ACE_Overlay.pm:85
+msgid "The owner of a ticket"
+msgstr "L'intervenant d'un ticket"
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The requestor of a ticket"
+msgstr "Le demandeur d'un ticket"
+
+#: html/Admin/Elements/EditUserComments:25
+msgid "These comments aren't generally visible to the user"
+msgstr "Ces commentaires ne sont généralement pas accessibles par l'utilisateur"
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr "Ce ticket %1 %2 (%3)\\n "
+
+#: bin/rt-crontool:188
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr "Cet outil permet à l'utilisateur de lancer un module perl quelconque depuis RT"
+
+#: lib/RT/Transaction_Overlay.pm:251
+msgid "This transaction appears to have no content"
+msgstr "Cette opération semble ne pas avoir de contenu"
+
+#: html/Ticket/Elements/ShowRequestor:46
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr "Les %1 tickets de plus haute priorité de cet utilisateur"
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr "Les 25 tickets prioritaires de cet utilisateur"
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "Jeu."
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr "Ticket n°%1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1 Jumbo update: %2"
+msgstr "Ticket n°%1 Jumbo update: %2"
+
+#: html/Ticket/ModifyAll.html:24 html/Ticket/ModifyAll.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "Ticket n°%1 mise à jour globale: %2"
+
+#: html/Approvals/Elements/ShowDependency:45
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr "Ticket n°%1: %2"
+
+#: lib/RT/Ticket_Overlay.pm:623 lib/RT/Ticket_Overlay.pm:644
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr "Ticket %1 créé dans la queue '%2'"
+
+#: bin/rt-commit-handler:759
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr "Ticket %1 chargé\\n "
+
+#: html/Search/Bulk.html:212
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr "Ticket %1: %2"
+
+#: html/Ticket/History.html:24 html/Ticket/History.html:27
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr "Historique ticket # %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket Id"
+msgstr "N° ticket"
+
+#: etc/initialdata:309
+msgid "Ticket Resolved"
+msgstr "Ticket résolu/clos"
+
+#: html/Search/Elements/PickRestriction:62
+msgid "Ticket attachment"
+msgstr "Pièce jointe au ticket"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr "Contenu du ticket."
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr "Type du contenu du ticket"
+
+#: lib/RT/Ticket_Overlay.pm:514 lib/RT/Ticket_Overlay.pm:523 lib/RT/Ticket_Overlay.pm:533 lib/RT/Ticket_Overlay.pm:633
+msgid "Ticket could not be created due to an internal error"
+msgstr "Une erreur interne a empêché l'ajout du ticket"
+
+#: lib/RT/Transaction_Overlay.pm:520
+msgid "Ticket created"
+msgstr "Ticket ajouté"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr "Création de ticket échouée."
+
+#: lib/RT/Transaction_Overlay.pm:525
+msgid "Ticket deleted"
+msgstr "Ticket supprimé."
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket id not found"
+msgstr "Id de ticket non trouvée"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket killed"
+msgstr "Ticket effacé"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket not found"
+msgstr "Ticket non trouvé"
+
+#: etc/initialdata:295
+msgid "Ticket status changed"
+msgstr "Statut de ticket modifié"
+
+#: html/Ticket/Update.html:38
+msgid "Ticket watchers"
+msgstr "Observateurs du ticket"
+
+#: html/Elements/Tabs:46
+msgid "Tickets"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr "Tickets %1 par %2"
+
+#: html/Elements/ViewUser:25
+#. ($name)
+msgid "Tickets from %1"
+msgstr "Tickets depuis %2"
+
+#: html/Approvals/Elements/ShowDependency:26
+msgid "Tickets which depend on this approval:"
+msgstr "Tickets dépendant de cette approbation:"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:47
+msgid "Time Left"
+msgstr "Temps restant"
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:42
+msgid "Time Worked"
+msgstr "Temps passé"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "Temps restant"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "Temps de calcul"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "Temps passé"
+
+#: NOT FOUND IN SOURCE
+msgid "TimeLeft"
+msgstr "TempsRestant"
+
+#: lib/RT/Ticket_Overlay.pm:1201
+msgid "TimeWorked"
+msgstr "TempsPassé"
+
+#: bin/rt-commit-handler:401
+msgid "To generate a diff of this commit:"
+msgstr "Pour conserver les modifications de cette transaction"
+
+#: bin/rt-commit-handler:390
+msgid "To generate a diff of this commit:\\n"
+msgstr "Pour conserver les modifications de cette transaction :\\n"
+
+#: lib/RT/Ticket_Overlay.pm:1204
+msgid "Told"
+msgstr "Annoncé"
+
+#: etc/initialdata:237
+msgid "Transaction"
+msgstr "Transaction"
+
+#: lib/RT/Transaction_Overlay.pm:691
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr "La transaction%1 est supprimée"
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr "Transaction ajoutée"
+
+#: lib/RT/Transaction_Overlay.pm:88
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr "Transaction->Create n'a pas fonctionné car vous n'avez pas spécifié d'identifiant de ticket"
+
+#: lib/RT/Transaction_Overlay.pm:750
+msgid "Transactions are immutable"
+msgstr "Les transactions ne peuvent être transférées"
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr "Tentative de délégation d'un droit : %1"
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "Mar."
+
+#: html/Admin/Elements/EditCustomField:43 html/Ticket/Elements/AddWatchers:32 html/Ticket/Elements/AddWatchers:43 html/Ticket/Elements/AddWatchers:53 lib/RT/Ticket_Overlay.pm:1202 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "Type"
+
+#: lib/RT/ScripCondition_Overlay.pm:103
+msgid "Unimplemented"
+msgstr "Fonction non disponible"
+
+#: html/Admin/Users/Modify.html:67
+msgid "Unix login"
+msgstr "Identifiant Unix"
+
+#: html/Admin/Elements/ModifyUser:61
+msgid "UnixUsername"
+msgstr "UnixUsername"
+
+#: lib/RT/Attachment_Overlay.pm:266 lib/RT/Attachment_Overlay.pm:298
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr "Type d'encodage de courrier inconnu: %1"
+
+#: html/Elements/SelectResultsPerPage:36
+msgid "Unlimited"
+msgstr "Illimité"
+
+#: etc/initialdata:32
+msgid "Unprivileged"
+msgstr "Non privilégié"
+
+#: lib/RT/Transaction_Overlay.pm:569
+msgid "Untaken"
+msgstr "Non pris"
+
+#: html/Elements/MyTickets:63 html/Search/Bulk.html:32
+msgid "Update"
+msgstr "Mettre à jour"
+
+#: html/Admin/Users/Prefs.html:61
+msgid "Update ID"
+msgstr "Mettre à jour l'ID"
+
+#: html/Search/Bulk.html:129 html/Ticket/ModifyAll.html:65 html/Ticket/Update.html:65
+msgid "Update Type"
+msgstr "Mettre à jour le type"
+
+#: html/Search/Listing.html:60
+msgid "Update all these tickets at once"
+msgstr "Mise à jour des tickets en masse"
+
+#: html/Admin/Users/Prefs.html:48
+msgid "Update email"
+msgstr "Mettre à jour l'email"
+
+#: html/Admin/Users/Prefs.html:54
+msgid "Update name"
+msgstr "Mettre à jour le nom"
+
+#: lib/RT/Interface/Web.pm:409
+msgid "Update not recorded."
+msgstr "Mise à jour non enregistrée"
+
+#: html/Search/Bulk.html:80
+msgid "Update selected tickets"
+msgstr "Mettre à jour les tickets sélectionnés"
+
+#: html/Admin/Users/Prefs.html:35
+msgid "Update signature"
+msgstr "Mettre à jour la signature"
+
+#: html/Ticket/ModifyAll.html:62
+msgid "Update ticket"
+msgstr "Mettre à jour le ticket"
+
+#: NOT FOUND IN SOURCE
+msgid "Update ticket # %1"
+msgstr "Mettre à jour le ticket n°%1"
+
+#: html/SelfService/Update.html:24 html/SelfService/Update.html:46
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr "Mettre à jour le ticket n°%1"
+
+#: html/Ticket/Update.html:139
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr "Mettre à jour le ticket n°%1 (%2)"
+
+#: lib/RT/Interface/Web.pm:407
+msgid "Update type was neither correspondence nor comment."
+msgstr "Le type de mise à jour n'était ni un commentaire ni un courrier."
+
+#: html/Elements/SelectDateType:32 html/Ticket/Elements/ShowDates:50 lib/RT/Ticket_Overlay.pm:1205
+msgid "Updated"
+msgstr "Mis(e) à jour"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr "Utilisateur %1 %2: %3\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr "Mot de passe de l'utilisateur %1 : %2\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr "Utilisateur '%1' non trouvé"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr "Utilisateur '%1' non trouvé\\n"
+
+#: etc/initialdata:124 etc/initialdata:191
+msgid "User Defined"
+msgstr "Utilisateur défini"
+
+#: html/Admin/Users/Prefs.html:58
+msgid "User ID"
+msgstr "Id utilisateur"
+
+#: html/Elements/SelectUsers:25
+msgid "User Id"
+msgstr "Id utilisateur"
+
+#: html/Admin/Elements/GroupTabs:46 html/Admin/Elements/QueueTabs:59 html/Admin/Elements/SystemTabs:46 html/Admin/Global/index.html:58
+msgid "User Rights"
+msgstr "Droits utilisateurs"
+
+#: html/Admin/Users/Modify.html:225
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr "Utilisateur ne peut pas être créé : %1"
+
+#: lib/RT/User_Overlay.pm:321
+msgid "User created"
+msgstr "Utilisateur créé"
+
+#: html/Admin/Global/GroupRights.html:66 html/Admin/Groups/GroupRights.html:53 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr "Groupes utilisateur"
+
+#: lib/RT/User_Overlay.pm:575 lib/RT/User_Overlay.pm:592
+msgid "User loaded"
+msgstr "Utilisateur chargé"
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr "Utilisateur informé"
+
+#: html/Admin/Users/Prefs.html:24 html/Admin/Users/Prefs.html:28
+msgid "User view"
+msgstr "Vue utilisateur"
+
+#: html/Admin/Users/Modify.html:47 html/Elements/Login:51 html/Ticket/Elements/AddWatchers:34
+msgid "Username"
+msgstr "Nom d'utilisateur"
+
+#: html/Admin/Elements/SelectNewGroupMembers:25 html/Admin/Elements/Tabs:31 html/Admin/Groups/Members.html:54 html/Admin/Queues/People.html:67 html/Admin/index.html:28 html/User/Groups/Members.html:57
+msgid "Users"
+msgstr "Utilisateurs"
+
+#: html/Admin/Users/index.html:64
+msgid "Users matching search criteria"
+msgstr "Utilisateurs correspondants aux critères de recherche"
+
+#: html/Search/Elements/PickRestriction:50
+msgid "ValueOfQueue"
+msgstr "ValueOfQueue"
+
+#: html/Admin/Elements/EditCustomField:56
+msgid "Values"
+msgstr "Valeurs"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Watch"
+msgstr "Observer"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "WatchAsAdminCc"
+msgstr "ObserverCommeAdminCC"
+
+#: NOT FOUND IN SOURCE
+msgid "Watcher loaded"
+msgstr "Observateur chargé"
+
+#: html/Admin/Elements/QueueTabs:41
+msgid "Watchers"
+msgstr "Observateurs"
+
+#: html/Admin/Elements/ModifyUser:55
+msgid "WebEncoding"
+msgstr "WebEncoding"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "Mer."
+
+#: etc/initialdata:503 etc/upgrade/2.1.71:161
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr "Quand un ticket a été approuvé par tous les approbateurs, ajoute le courrier au ticket source"
+
+#: etc/initialdata:467 etc/upgrade/2.1.71:135
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr "Quand un ticket a été approuvé par au moins un approbateur, ajoute le courrier au ticket source "
+
+#: etc/initialdata:138
+msgid "When a ticket is created"
+msgstr "Quand un ticket est créé"
+
+#: etc/initialdata:400 etc/upgrade/2.1.71:79
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr "Quand un ticket d'approbation est créé, informer l'intervenant et l'AdminCC de l'élément attendant leur approbation"
+
+#: etc/initialdata:143
+msgid "When anything happens"
+msgstr "Quand quelque chose arrive"
+
+#: etc/initialdata:184
+msgid "Whenever a ticket is resolved"
+msgstr "Lorsqu'un ticket quelconque est résolu/clos"
+
+#: etc/initialdata:170
+msgid "Whenever a ticket's owner changes"
+msgstr "Lorsqu'un ticket quelconque change d'intervenant"
+
+#: etc/initialdata:178
+msgid "Whenever a ticket's queue changes"
+msgstr "Lorsqu'un ticket quelconque change de queue"
+
+#: etc/initialdata:162
+msgid "Whenever a ticket's status changes"
+msgstr "Lorsqu'un ticket quelconque change de statut"
+
+#: etc/initialdata:192
+msgid "Whenever a user-defined condition occurs"
+msgstr "Lorsqu'une condition définie par l'utilisateur est satisfaite"
+
+#: etc/initialdata:156
+msgid "Whenever comments come in"
+msgstr "Lorsque un commentaire arrive"
+
+#: etc/initialdata:149
+msgid "Whenever correspondence comes in"
+msgstr "Lorsque un courrier arrive"
+
+#: html/Admin/Users/Modify.html:163 html/User/Prefs.html:51
+msgid "Work"
+msgstr "Travail"
+
+#: html/Admin/Elements/ModifyUser:69
+msgid "WorkPhone"
+msgstr "Tel. bureau"
+
+#: html/Ticket/Elements/ShowBasics:34 html/Ticket/Update.html:64
+msgid "Worked"
+msgstr "Travaillé"
+
+#: lib/RT/Ticket_Overlay.pm:3187
+msgid "You already own this ticket"
+msgstr "Vous êtes déjà intervenant de ce ticket"
+
+#: html/autohandler:122
+msgid "You are not an authorized user"
+msgstr "Vous n'êtes pas un utilisateur autorisé"
+
+#: lib/RT/Ticket_Overlay.pm:3069
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "Vous pouvez seulement réaffecter vos ticket ou ceux qui ne sont pas affectés"
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr "Vous n'êtes pas autorisé à voir ce ticket.\\n"
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "%1 tickets trouvés dans la queue %2"
+
+#: html/NoAuth/Logout.html:30
+msgid "You have been logged out of RT."
+msgstr "Vous avez été déconnecté de RT."
+
+#: html/SelfService/Display.html:77
+msgid "You have no permission to create tickets in that queue."
+msgstr "Vous n'avez pas l'autorisation de créer des tickets dans cette queue."
+
+#: lib/RT/Ticket_Overlay.pm:1926
+msgid "You may not create requests in that queue."
+msgstr "Vous ne pouvez pas créer de demandes dans cette queue."
+
+#: html/NoAuth/Logout.html:34
+msgid "You're welcome to login again"
+msgstr "Vous êtes invité à vous identifier à nouveau"
+
+#: NOT FOUND IN SOURCE
+msgid "Your %1 requests"
+msgstr "Vos %1 requêtes"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr "Votre administrateur RT a mal configuré l'alias de mail qui appelle RT"
+
+#: etc/initialdata:484 etc/upgrade/2.1.71:146
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr "Votre demande a été approuvée par %1. D'autres approbations sont peut être toujours en attente"
+
+#: etc/initialdata:522 etc/upgrade/2.1.71:180
+msgid "Your request has been approved."
+msgstr "Votre demande a été approuvée"
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr "Votre demande a été rejetée"
+
+#: etc/initialdata:427 etc/upgrade/2.1.71:101
+msgid "Your request was rejected."
+msgstr "Votre demande a été rejetée."
+
+#: html/autohandler:144
+msgid "Your username or password is incorrect"
+msgstr "Votre nom d'utilisateur ou votre mot de passe est incorrect"
+
+#: html/Admin/Elements/ModifyUser:83 html/Admin/Users/Modify.html:143 html/User/Prefs.html:95
+msgid "Zip"
+msgstr "Code Postal"
+
+#: NOT FOUND IN SOURCE
+msgid "[no subject]"
+msgstr "[Pas de sujet]"
+
+#: html/User/Elements/DelegateRights:58
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "comme accordé à %1"
+
+#: html/SelfService/Closed.html:27
+msgid "closed"
+msgstr "fermé"
+
+#: html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:33
+msgid "contains"
+msgstr "contient"
+
+#: html/Elements/SelectAttachmentField:25
+msgid "content"
+msgstr "Contenu"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content-type"
+msgstr "Type de contenu"
+
+#: lib/RT/Ticket_Overlay.pm:2313
+msgid "correspondence (probably) not sent"
+msgstr "courrier (probablement) non envoyé"
+
+#: lib/RT/Ticket_Overlay.pm:2323
+msgid "correspondence sent"
+msgstr "courrier envoyé"
+
+#: html/Admin/Elements/ModifyQueue:62 html/Admin/Queues/Modify.html:76 lib/RT/Date.pm:319
+msgid "days"
+msgstr "jours"
+
+#: NOT FOUND IN SOURCE
+msgid "dead"
+msgstr "effacé"
+
+#: html/Search/Listing.html:74
+msgid "delete"
+msgstr "effacer"
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "deleted"
+msgstr "effacé"
+
+#: html/Search/Elements/PickRestriction:67
+msgid "does not match"
+msgstr "ne correspond pas"
+
+#: html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:34
+msgid "doesn't contain"
+msgstr "ne contient pas"
+
+#: html/Elements/SelectEqualityOperator:37
+msgid "equal to"
+msgstr "égal à"
+
+#: NOT FOUND IN SOURCE
+msgid "false"
+msgstr "faux"
+
+#: html/Elements/SelectAttachmentField:27
+msgid "filename"
+msgstr "Nom de fichier"
+
+#: html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectEqualityOperator:37
+msgid "greater than"
+msgstr "supérieur à"
+
+#: lib/RT/Group_Overlay.pm:193
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "groupe '%1'"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "heures"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr "n°"
+
+#: html/Elements/SelectBoolean:31 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:35 html/Search/Elements/PickRestriction:46 html/Search/Elements/PickRestriction:75 html/Search/Elements/PickRestriction:87
+msgid "is"
+msgstr "est"
+
+#: html/Elements/SelectBoolean:35 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88
+msgid "isn't"
+msgstr "n'est pas"
+
+#: html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectEqualityOperator:37
+msgid "less than"
+msgstr "inférieur à"
+
+#: html/Search/Elements/PickRestriction:66
+msgid "matches"
+msgstr "correspond"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "min"
+
+#: html/Ticket/Update.html:64
+msgid "minutes"
+msgstr "minutes"
+
+#: bin/rt-commit-handler:764
+msgid "modifications\\n\\n"
+msgstr "modifications\\n\\n"
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "mois"
+
+#: lib/RT/Queue_Overlay.pm:57
+msgid "new"
+msgstr "nouveau"
+
+#: html/Admin/Elements/EditScrips:42
+msgid "no value"
+msgstr "Non renseigné"
+
+#: html/Admin/Elements/EditQueueWatchers:26 html/Ticket/Elements/EditWatchers:27
+msgid "none"
+msgstr "aucun"
+
+#: html/Elements/SelectEqualityOperator:37
+msgid "not equal to"
+msgstr "différent de"
+
+#: NOT FOUND IN SOURCE
+msgid "notlike"
+msgstr "necontientpas"
+
+#: html/SelfService/Elements/MyRequests:60 lib/RT/Queue_Overlay.pm:58
+msgid "open"
+msgstr "ouvert"
+
+#: lib/RT/Group_Overlay.pm:198
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr "groupe personnel '%1' pour l'utilisateur '%2'"
+
+#: lib/RT/Group_Overlay.pm:206
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr "queue %1 %2"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "rejected"
+msgstr "rejeté"
+
+#: lib/RT/Queue_Overlay.pm:60
+msgid "resolved"
+msgstr "résolu"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr "sec"
+
+#: lib/RT/Queue_Overlay.pm:59
+msgid "stalled"
+msgstr "bloqué"
+
+#: lib/RT/Group_Overlay.pm:201
+#. ($self->Type)
+msgid "system %1"
+msgstr "système %1"
+
+#: lib/RT/Group_Overlay.pm:212
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr "groupe système '%1'"
+
+#: html/Elements/Error:42 html/SelfService/Error.html:41
+msgid "the calling component did not specify why"
+msgstr "le composant appelant n'a pas spécifié pourquoi"
+
+#: lib/RT/URI/fsck_com_rt.pm:234
+#. ($self->Object->Id)
+msgid "ticket #%1"
+msgstr "ticket n°%1"
+
+#: lib/RT/Group_Overlay.pm:209
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr "ticket n°%1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "true"
+msgstr "vrai"
+
+#: lib/RT/Group_Overlay.pm:215
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr "Groupe %1 non décrit"
+
+#: NOT FOUND IN SOURCE
+msgid "undescripbed group %1"
+msgstr "Groupe non décrit %1"
+
+#: lib/RT/Group_Overlay.pm:190
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr "utilisateur %1"
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr "semaines"
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr "Avec modèle %1"
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr "années"
+
diff --git a/rt/lib/RT/I18N/he.po b/rt/lib/RT/I18N/he.po
new file mode 100644 (file)
index 0000000..d3ef20e
--- /dev/null
@@ -0,0 +1,4871 @@
+# Hebrew Translation of the RT interface by Shimi.
+# Comments: shimi@shimi.net
+
+msgid ""
+msgstr ""
+"Language-Team: rt-devel <rt-devel@lists.fsck.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28
+msgid "#"
+msgstr ""
+
+#: html/Admin/Queues/Scrip.html:55
+#. ($QueueObj->id)
+msgid "#%1"
+msgstr ""
+
+#: html/Approvals/Elements/Approve:27 html/Approvals/Elements/ShowDependency:50 html/SelfService/Display.html:25 html/Ticket/Display.html:26 html/Ticket/Display.html:30
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($Ticket->id, $Ticket->Subject)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr ""
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr ""
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3505 lib/RT/Transaction_Overlay.pm:557 lib/RT/Transaction_Overlay.pm:599
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 הוסף"
+msgstr ""
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 לפני %2 ימים"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3511 lib/RT/Transaction_Overlay.pm:564
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 שונה ל %3"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3508 lib/RT/Transaction_Overlay.pm:560 lib/RT/Transaction_Overlay.pm:605
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 נמחק"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 %2 מקבוצה %3"
+msgstr ""
+
+#: html/Admin/Elements/EditScrips:44 html/Admin/Elements/ListGlobalScrips:28
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 עם תבנית %3"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 פנייה זו\\n"
+msgstr ""
+
+#: html/Search/Listing.html:57
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr "%1 - %2 מוצגים"
+
+#: bin/rt-crontool:169 bin/rt-crontool:176 bin/rt-crontool:182
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - ארגומנט להעביר אל %2"
+msgstr ""
+
+#: bin/rt-crontool:185
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr ""
+
+#: bin/rt-crontool:179
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr ""
+
+#: bin/rt-crontool:173
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr ""
+
+#: bin/rt-crontool:166
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr ""
+
+#: lib/RT/ScripAction_Overlay.pm:122
+#. ($self->Id)
+msgid "%1 פעולת-סקריפ נטענה"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3538
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 הוסף כערך עבור %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 כינויים דורשים מזהה פנייה כדי לעבוד עליהם"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 כינויים דורשים מזהה פנייה כדי לעבוד עליהם "
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 כינויים דורשים מזהה פנייה כדי לעבוד עליהם (מ %2) %3"
+msgstr ""
+
+#: lib/RT/Link_Overlay.pm:117 lib/RT/Link_Overlay.pm:124
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 נראה כמו אובייקט מקומי, אבל הוא אינו נמצא במסד הנתונים"
+msgstr ""
+
+#: html/Ticket/Elements/ShowDates:52 lib/RT/Transaction_Overlay.pm:481
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 על ידי %2"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:535 lib/RT/Transaction_Overlay.pm:624 lib/RT/Transaction_Overlay.pm:633 lib/RT/Transaction_Overlay.pm:636
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 שונה מ %2 ל %3"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:891
+msgid "%1 could not be set to %2."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2817
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr ""
+
+#: html/Elements/MyTickets:25
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr "%1 הפניות עם העדיפות הגבוהה ביותר בטיפולי..."
+
+#: html/Elements/MyRequests:25
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr "%1 הפניות עם העדיפות הגבוהה ביותר שאני פתחתי..."
+
+#: bin/rt-crontool:161
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1570
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3594
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr ""
+
+#: html/Ticket/Elements/ShowBasics:36
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr ""
+
+#: html/User/Elements/DelegateRights:76
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr "זכויות"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 was created without a CurrentUser\\n"
+msgstr ""
+
+#: lib/RT/Action/ResolveMembers.pm:42
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:433
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr ""
+
+#: html/Ticket/Elements/ShowTransaction:102
+#. ($size)
+msgid "%1b"
+msgstr ""
+
+#: html/Ticket/Elements/ShowTransaction:99
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1140
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete group member)"
+msgstr "(סמן תיבה כדי למחוק חבר בקבוצה)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr "(סמן תיבה כדי למחוק סקריפ)"
+
+#: html/Admin/Elements/EditCustomFieldValues:25 html/Admin/Elements/EditQueueWatchers:29 html/Admin/Elements/EditScrips:35 html/Admin/Elements/EditTemplates:36 html/Admin/Groups/Members.html:52 html/Ticket/Elements/EditLinks:33 html/Ticket/Elements/EditPeople:46 html/User/Groups/Members.html:55
+msgid "(Check box to delete)"
+msgstr "(סמן תיבה כדי למחוק)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check boxes to delete)"
+msgstr "(סמן תיבות כדי למחוק)"
+
+#: html/Ticket/Create.html:178
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr ""
+
+#: html/Admin/Queues/Modify.html:54 html/Admin/Queues/Modify.html:60
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(No Value)"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:33 html/Admin/Elements/ListGlobalCustomFields:32
+msgid "(No custom fields)"
+msgstr ""
+
+#: html/Admin/Groups/Members.html:50 html/User/Groups/Members.html:53
+msgid "(No members)"
+msgstr ""
+
+#: html/Admin/Elements/EditScrips:32 html/Admin/Elements/ListGlobalScrips:32
+msgid "(No scrips)"
+msgstr ""
+
+#: html/Admin/Elements/EditTemplates:31
+msgid "(No templates)"
+msgstr ""
+
+#: html/Ticket/Update.html:85
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr ""
+
+#: html/Ticket/Create.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr ""
+
+#: html/Ticket/Update.html:81
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr ""
+
+#: html/Ticket/Create.html:69
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr ""
+
+#: html/Admin/Groups/index.html:33 html/User/Groups/index.html:33
+msgid "(empty)"
+msgstr ""
+
+#: html/Admin/Users/index.html:39
+msgid "(no name listed)"
+msgstr ""
+
+#: html/Elements/MyRequests:43 html/Elements/MyTickets:45
+msgid "(no subject)"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:48 html/Elements/SelectCustomFieldValue:30 html/Ticket/Elements/EditCustomField:59 html/Ticket/Elements/ShowCustomFields:36 lib/RT/Transaction_Overlay.pm:534
+msgid "(no value)"
+msgstr ""
+
+#: html/Ticket/Elements/EditLinks:116
+msgid "(only one ticket)"
+msgstr "(רק פנייה אחת)"
+
+#: html/Elements/MyRequests:52 html/Elements/MyTickets:55
+msgid "(pending approval)"
+msgstr ""
+
+#: html/Elements/MyRequests:54 html/Elements/MyTickets:57
+msgid "(pending other tickets)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(requestor's group)"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:50
+msgid "(required)"
+msgstr ""
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "(untitled)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I own..."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I requested..."
+msgstr ""
+
+#: html/Ticket/Elements/ShowBasics:32
+msgid "<% $Ticket->Status%>"
+msgstr ""
+
+#: html/Elements/SelectTicketTypes:27
+msgid "<% $_ %>"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:26
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"פנייה חדשה ב\">&nbsp;%1"
+
+#: NOT FOUND IN SOURCE
+msgid "??????"
+msgstr ""
+
+#: etc/initialdata:203
+msgid "A blank template"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Deleted"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Loaded"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be deleted"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be found"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:157 lib/RT/Principal_Overlay.pm:181
+msgid "ACE not found"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:831
+msgid "ACEs can only be created and deleted."
+msgstr ""
+
+#: bin/rt-commit-handler:755
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr ""
+
+#: html/User/Elements/Tabs:32
+msgid "About me"
+msgstr "מידע אודותי"
+
+#: html/Admin/Users/Modify.html:80
+msgid "Access control"
+msgstr ""
+
+#: html/Admin/Elements/EditScrip:57
+msgid "Action"
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:147
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr ""
+
+#: bin/rt-crontool:123
+msgid "Action committed."
+msgstr ""
+
+#: bin/rt-crontool:119
+msgid "Action prepared..."
+msgstr ""
+
+#: html/Search/Bulk.html:92
+msgid "Add AdminCc"
+msgstr "הוסף העתק ניהולי"
+
+#: html/Search/Bulk.html:90
+msgid "Add Cc"
+msgstr "הוסף העתק"
+
+#: html/Ticket/Create.html:114 html/Ticket/Update.html:100
+msgid "Add More Files"
+msgstr "הוסף עוד קבצים"
+
+#: NOT FOUND IN SOURCE
+msgid "Add Next State"
+msgstr ""
+
+#: html/Search/Bulk.html:88
+msgid "Add Requestor"
+msgstr "הוסף מבקש"
+
+#: html/Admin/Elements/AddCustomFieldValue:26
+msgid "Add Value"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip to this queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip which will apply to all queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a keyword selection to this queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr ""
+
+#: html/Admin/Global/Scrip.html:55
+msgid "Add a scrip which will apply to all queues"
+msgstr ""
+
+#: html/Search/Bulk.html:118
+msgid "Add comments or replies to selected tickets"
+msgstr "הוסף הערות או תגובות לפניות הנבחרות"
+
+#: html/Admin/Groups/Members.html:42 html/User/Groups/Members.html:39
+msgid "Add members"
+msgstr ""
+
+#: html/Admin/Queues/People.html:66 html/Ticket/Elements/AddWatchers:28
+msgid "Add new watchers"
+msgstr "הוסף צופים חדשים"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1454
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:76 html/Admin/Users/Modify.html:122 html/User/Prefs.html:88
+msgid "Address1"
+msgstr "כתובת1"
+
+#: html/Admin/Elements/ModifyUser:78 html/Admin/Users/Modify.html:127 html/User/Prefs.html:90
+msgid "Address2"
+msgstr "כתובת2"
+
+#: html/Ticket/Create.html:74
+msgid "Admin Cc"
+msgstr ""
+
+#: etc/initialdata:280
+msgid "Admin Comment"
+msgstr ""
+
+#: etc/initialdata:259
+msgid "Admin Correspondence"
+msgstr ""
+
+#: html/Admin/Queues/index.html:25 html/Admin/Queues/index.html:28
+msgid "Admin queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr ""
+
+#: html/Admin/Global/index.html:26 html/Admin/Global/index.html:28
+msgid "Admin/Global configuration"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr ""
+
+#: html/Admin/Queues/Modify.html:25 html/Admin/Queues/Modify.html:29
+msgid "Admin/Queue/Basics"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr ""
+
+#: etc/initialdata:56 html/Ticket/Elements/ShowPeople:39 html/Ticket/Update.html:50 lib/RT/ACE_Overlay.pm:89
+msgid "AdminCc"
+msgstr "העתק ניהולי"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "AdminCustomFields"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "AdminGroup"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "AdminGroupMembership"
+msgstr ""
+
+#: lib/RT/System.pm:59
+msgid "AdminOwnPersonalGroups"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "AdminQueue"
+msgstr ""
+
+#: lib/RT/System.pm:60
+msgid "AdminUsers"
+msgstr ""
+
+#: html/Admin/Queues/People.html:48 html/Ticket/Elements/EditPeople:54
+msgid "Administrative Cc"
+msgstr "העתק ניהולי"
+
+#: NOT FOUND IN SOURCE
+msgid "Admins"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr ""
+
+#: html/Elements/SelectDateRelation:36
+msgid "After"
+msgstr "אחרי"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Alias"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Alias for"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:96
+msgid "All Custom Fields"
+msgstr ""
+
+#: html/Admin/Queues/index.html:53
+msgid "All Queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr ""
+
+#: html/Elements/Tabs:56
+msgid "Approval"
+msgstr "אישור"
+
+#: html/Approvals/Display.html:46 html/Approvals/Elements/ShowDependency:42 html/Approvals/index.html:65
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr ""
+
+#: html/Approvals/index.html:54
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr ""
+
+#: html/Approvals/index.html:52
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Details"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Approval diagram"
+msgstr ""
+
+#: html/Approvals/Elements/Approve:44
+msgid "Approve"
+msgstr ""
+
+#: etc/initialdata:437 etc/upgrade/2.1.71:148
+msgid "Approver's notes: %1"
+msgstr ""
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "אפריל"
+
+#: NOT FOUND IN SOURCE
+msgid "April"
+msgstr "אפריל"
+
+#: html/Elements/SelectSortOrder:35
+msgid "Ascending"
+msgstr "עולה"
+
+#: html/Search/Bulk.html:127 html/SelfService/Update.html:33 html/Ticket/ModifyAll.html:83 html/Ticket/Update.html:100
+msgid "Attach"
+msgstr "צרף"
+
+#: html/SelfService/Create.html:65 html/Ticket/Create.html:110
+msgid "Attach file"
+msgstr ""
+
+#: html/Ticket/Create.html:98 html/Ticket/Update.html:89
+msgid "Attached file"
+msgstr "קובץ מצורף"
+
+#: NOT FOUND IN SOURCE
+msgid "Attachment '%1' could not be loaded"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:441
+msgid "Attachment created"
+msgstr "קובץ צורף"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "שם קובץ מצורף"
+
+#: html/Ticket/Elements/ShowAttachments:26
+msgid "Attachments"
+msgstr "קבצים מצורפים"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "אוגוסט"
+
+#: NOT FOUND IN SOURCE
+msgid "August"
+msgstr "אוגוסט"
+
+#: html/Admin/Elements/ModifyUser:66
+msgid "AuthSystem"
+msgstr ""
+
+#: etc/initialdata:206
+msgid "Autoreply"
+msgstr ""
+
+#: etc/initialdata:72
+msgid "Autoreply To Requestors"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr ""
+
+#: bin/rt-commit-handler:827
+#. ($val)
+msgid "Bad data in %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:39 html/Admin/Elements/QueueTabs:39 html/Admin/Elements/UserTabs:38 html/Ticket/Elements/Tabs:90 html/User/Elements/GroupTabs:38
+msgid "Basics"
+msgstr "בסיסי"
+
+#: html/Ticket/Update.html:83
+msgid "Bcc"
+msgstr ""
+
+#: html/Admin/Elements/EditScrip:88 html/Admin/Global/GroupRights.html:85 html/Admin/Global/Template.html:46 html/Admin/Global/UserRights.html:54 html/Admin/Groups/GroupRights.html:73 html/Admin/Groups/Members.html:81 html/Admin/Groups/Modify.html:56 html/Admin/Groups/UserRights.html:55 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:45 html/Admin/Queues/UserRights.html:54 html/User/Groups/Modify.html:56
+msgid "Be sure to save your changes"
+msgstr "אל תשכח לשמור את השינויים"
+
+#: html/Elements/SelectDateRelation:34 lib/RT/CurrentUser.pm:320
+msgid "Before"
+msgstr "לפני"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin Approval"
+msgstr ""
+
+#: etc/initialdata:202
+msgid "Blank"
+msgstr ""
+
+#: html/Search/Listing.html:79
+msgid "Bookmarkable URL for this search"
+msgstr "הוסף כתובת זו לספר הכתובות כדי לחזור על אותו חיפוש"
+
+#: html/Ticket/Elements/ShowHistory:39 html/Ticket/Elements/ShowHistory:45
+msgid "Brief headers"
+msgstr "תקציר כותרים"
+
+#: html/Search/Bulk.html:25 html/Search/Bulk.html:26
+msgid "Bulk ticket update"
+msgstr "עדכון פניות מרוכז"
+
+#: lib/RT/User_Overlay.pm:1352
+msgid "Can not modify system users"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Can this principal see this queue"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:206
+msgid "Can't add a custom field value without a name"
+msgstr ""
+
+#: lib/RT/Link_Overlay.pm:132
+msgid "Can't link a ticket to itself"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2794
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2612 lib/RT/Ticket_Overlay.pm:2681
+msgid "Can't specifiy both base and target"
+msgstr ""
+
+#: html/autohandler:99
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr ""
+
+#: etc/initialdata:50 html/Admin/Queues/People.html:44 html/SelfService/Create.html:49 html/Ticket/Create.html:64 html/Ticket/Elements/EditPeople:51 html/Ticket/Elements/ShowPeople:35 html/Ticket/Update.html:45 html/Ticket/Update.html:78 lib/RT/ACE_Overlay.pm:88
+msgid "Cc"
+msgstr "העתק"
+
+#: html/SelfService/Prefs.html:31
+msgid "Change password"
+msgstr ""
+
+#: html/Ticket/Create.html:101 html/Ticket/Update.html:92
+msgid "Check box to delete"
+msgstr "סמן תיבה כדי למחוק"
+
+#: html/Admin/Elements/SelectRights:31
+msgid "Check box to revoke right"
+msgstr "סמן תיבה כדי לבטל זכות"
+
+#: html/Ticket/Create.html:183 html/Ticket/Elements/EditLinks:131 html/Ticket/Elements/EditLinks:69 html/Ticket/Elements/ShowLinks:57
+msgid "Children"
+msgstr "ילדים"
+
+#: html/Admin/Elements/ModifyUser:80 html/Admin/Users/Modify.html:132 html/User/Prefs.html:92
+msgid "City"
+msgstr "עיר"
+
+#: html/Ticket/Elements/ShowDates:47
+msgid "Closed"
+msgstr "נסגר"
+
+#: html/SelfService/Closed.html:25
+msgid "Closed Tickets"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Closed requests"
+msgstr ""
+
+#: html/SelfService/Elements/Tabs:45
+msgid "Closed tickets"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Code"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr ""
+
+#: html/Ticket/Elements/ShowTransaction:179 html/Ticket/Elements/Tabs:153
+msgid "Comment"
+msgstr "הערה"
+
+#: html/Admin/Elements/ModifyQueue:45 html/Admin/Queues/Modify.html:58
+msgid "Comment Address"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Comment on tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "CommentOnTicket"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:35
+msgid "Comments"
+msgstr ""
+
+#: html/Ticket/ModifyAll.html:70 html/Ticket/Update.html:70
+msgid "Comments (Not sent to requestors)"
+msgstr "הערות (לא נשלחות אל המבקשים)"
+
+#: html/Search/Bulk.html:122
+msgid "Comments (not sent to requestors)"
+msgstr "הערות (לא נשלחות אל המבקשים)"
+
+#: html/Elements/ViewUser:27
+#. ($name)
+msgid "Comments about %1"
+msgstr "הערות לגבי %1"
+
+#: html/Admin/Users/Modify.html:185 html/Ticket/Elements/ShowRequestor:44
+msgid "Comments about this user"
+msgstr "הערות לגבי משתמש זה"
+
+#: lib/RT/Transaction_Overlay.pm:543
+msgid "Comments added"
+msgstr "הערות נוספו"
+
+#: lib/RT/Action/Generic.pm:140
+msgid "Commit Stubbed"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr ""
+
+#: html/Admin/Elements/EditScrip:41
+msgid "Condition"
+msgstr ""
+
+#: bin/rt-crontool:109
+msgid "Condition matches..."
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:160
+msgid "Condition not found"
+msgstr ""
+
+#: html/Elements/Tabs:50
+msgid "Configuration"
+msgstr "הגדרות"
+
+#: html/SelfService/Prefs.html:33
+msgid "Confirm"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:60
+msgid "ContactInfoSystem"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr ""
+
+#: html/Admin/Elements/ModifyTemplate:44 html/Ticket/ModifyAll.html:87
+msgid "Content"
+msgstr "תוכן"
+
+#: NOT FOUND IN SOURCE
+msgid "Coould not create group"
+msgstr ""
+
+#: etc/initialdata:271
+msgid "Correspondence"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:39 html/Admin/Queues/Modify.html:51
+msgid "Correspondence Address"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:539
+msgid "Correspondence added"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3525
+msgid "Could not add new custom field value for ticket. "
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Could not add new custom field value for ticket. %1 "
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3031 lib/RT/Ticket_Overlay.pm:3039 lib/RT/Ticket_Overlay.pm:3055
+msgid "Could not change owner. "
+msgstr ""
+
+#: html/Admin/Elements/EditCustomField:85 html/Admin/Elements/EditCustomFields:166
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr ""
+
+#: html/User/Groups/Modify.html:77 lib/RT/Group_Overlay.pm:474 lib/RT/Group_Overlay.pm:481
+msgid "Could not create group"
+msgstr ""
+
+#: html/Admin/Global/Template.html:75 html/Admin/Queues/Template.html:72
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1073 lib/RT/Ticket_Overlay.pm:334
+msgid "Could not create ticket. Queue not set"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:208 lib/RT/User_Overlay.pm:220 lib/RT/User_Overlay.pm:238 lib/RT/User_Overlay.pm:422
+msgid "Could not create user"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Could not create watcher for requestor"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1422
+msgid "Could not find or create that user"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1501
+msgid "Could not find that principal"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr ""
+
+#: html/Admin/Groups/Members.html:88 html/User/Groups/Members.html:90 html/User/Groups/Modify.html:82
+msgid "Could not load group"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1443
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1559
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:985
+msgid "Couldn't add member to group"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3535 lib/RT/Ticket_Overlay.pm:3591
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:900
+msgid "Couldn't find row"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:959
+msgid "Couldn't find that principal"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:240
+msgid "Couldn't find that value"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find that watcher"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr ""
+
+#: lib/RT/CurrentUser.pm:112
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load KeywordSelects."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr ""
+
+#: html/Admin/Groups/GroupRights.html:88 html/Admin/Groups/UserRights.html:75
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr ""
+
+#: lib/RT/Link_Overlay.pm:175 lib/RT/Link_Overlay.pm:184 lib/RT/Link_Overlay.pm:211
+msgid "Couldn't load link"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:147 html/Admin/Queues/People.html:121
+#. ($id)
+msgid "Couldn't load queue"
+msgstr ""
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:72
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr ""
+
+#: html/Admin/Users/Prefs.html:79
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr ""
+
+#: html/SelfService/Display.html:109
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:86 html/Admin/Users/Modify.html:149 html/User/Prefs.html:98
+msgid "Country"
+msgstr "ארץ"
+
+#: html/Admin/Elements/CreateUserCalled:26 html/Ticket/Create.html:135 html/Ticket/Create.html:195
+msgid "Create"
+msgstr "צור"
+
+#: etc/initialdata:128
+msgid "Create Tickets"
+msgstr "צור פניות"
+
+#: html/Admin/Elements/EditCustomField:75
+msgid "Create a CustomField"
+msgstr ""
+
+#: html/Admin/Queues/CustomField.html:48
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:48
+msgid "Create a CustomField which applies to all queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global Scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:67 html/Admin/Groups/Modify.html:93
+msgid "Create a new group"
+msgstr ""
+
+#: html/User/Groups/Modify.html:67 html/User/Groups/Modify.html:92
+msgid "Create a new personal group"
+msgstr "צור קבוצה פרטית חדשה"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr "צור תור חדש"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr "צור סקריפ חדש"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr "צור תבנית חדשה"
+
+#: html/Ticket/Create.html:25 html/Ticket/Create.html:28 html/Ticket/Create.html:36
+msgid "Create a new ticket"
+msgstr "צור פנייה חדשה"
+
+#: html/Admin/Users/Modify.html:214 html/Admin/Users/Modify.html:241
+msgid "Create a new user"
+msgstr "צור משתמש חדש"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "צור תור חדש"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr "צור תור שנקרא"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a request"
+msgstr "צור בקשה"
+
+#: html/Admin/Queues/Scrip.html:59
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr ""
+
+#: html/Admin/Global/Template.html:69 html/Admin/Queues/Template.html:65
+msgid "Create a template"
+msgstr ""
+
+#: html/SelfService/Create.html:25
+msgid "Create a ticket"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1 / %2 / %3 "
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1/%2/%3"
+msgstr ""
+
+#: etc/initialdata:130
+msgid "Create new tickets based on this scrip's template"
+msgstr ""
+
+#: html/SelfService/Create.html:78
+msgid "Create ticket"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Create tickets in this queue"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Create, delete and modify custom fields"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Create, delete and modify queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr ""
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify the members of personal groups"
+msgstr ""
+
+#: lib/RT/System.pm:60
+msgid "Create, delete and modify users"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "CreateTicket"
+msgstr ""
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1167
+msgid "Created"
+msgstr "נוצר"
+
+#: html/Admin/Elements/EditCustomField:88
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr ""
+
+#: html/Ticket/Elements/EditLinks:28
+msgid "Current Relationships"
+msgstr "יחסים נוכחיים"
+
+#: html/Admin/Elements/EditScrips:30
+msgid "Current Scrips"
+msgstr ""
+
+#: html/Admin/Groups/Members.html:39 html/User/Groups/Members.html:42
+msgid "Current members"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:29
+msgid "Current rights"
+msgstr ""
+
+#: html/Search/Listing.html:71
+msgid "Current search criteria"
+msgstr "קריטריוני החיפוש הנוכחיים"
+
+#: html/Admin/Queues/People.html:41 html/Ticket/Elements/EditPeople:45
+msgid "Current watchers"
+msgstr "צופים נוכחיים"
+
+#: html/Admin/Global/CustomField.html:55
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:53 html/Admin/Elements/SystemTabs:40 html/Admin/Global/index.html:50 html/Ticket/Elements/ShowSummary:36
+msgid "Custom Fields"
+msgstr ""
+
+#: html/Admin/Elements/EditScrip:73
+msgid "Custom action cleanup code"
+msgstr ""
+
+#: html/Admin/Elements/EditScrip:65
+msgid "Custom action preparation code"
+msgstr ""
+
+#: html/Admin/Elements/EditScrip:49
+msgid "Custom condition"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3427
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:197
+msgid "Custom field deleted"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3577
+msgid "Custom field not found"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:350
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:250
+msgid "Custom field value could not be deleted"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:356
+msgid "Custom field value could not be found"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:248 lib/RT/CustomField_Overlay.pm:358
+msgid "Custom field value deleted"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:548
+msgid "CustomField"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Data error"
+msgstr ""
+
+#: html/SelfService/Display.html:39 html/Ticket/Create.html:161 html/Ticket/Elements/ShowSummary:55 html/Ticket/Elements/Tabs:93 html/Ticket/ModifyAll.html:44
+msgid "Dates"
+msgstr "תאריכים"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "דצמבר"
+
+#: NOT FOUND IN SOURCE
+msgid "December"
+msgstr "דצמבר"
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr ""
+
+#: etc/initialdata:207
+msgid "Default Autoresponse template"
+msgstr ""
+
+#: etc/initialdata:281
+msgid "Default admin comment template"
+msgstr ""
+
+#: etc/initialdata:260
+msgid "Default admin correspondence template"
+msgstr ""
+
+#: etc/initialdata:272
+msgid "Default correspondence template"
+msgstr ""
+
+#: etc/initialdata:238
+msgid "Default transaction template"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:643
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr ""
+
+#: html/User/Delegation.html:25 html/User/Delegation.html:28
+msgid "Delegate rights"
+msgstr ""
+
+#: lib/RT/System.pm:63
+msgid "Delegate specific rights which have been granted to you."
+msgstr ""
+
+#: lib/RT/System.pm:63
+msgid "DelegateRights"
+msgstr ""
+
+#: html/User/Elements/Tabs:38
+msgid "Delegation"
+msgstr "דלגציות"
+
+#: NOT FOUND IN SOURCE
+msgid "Delete"
+msgstr "מחק"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "Delete tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "DeleteTicket"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:292
+msgid "Deleting this object would break referential integrity"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:438
+msgid "Deleting this object would violate referential integrity"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity. That's bad."
+msgstr ""
+
+#: html/Approvals/Elements/Approve:45
+msgid "Deny"
+msgstr ""
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/EditLinks:123 html/Ticket/Elements/EditLinks:47 html/Ticket/Elements/ShowDependencies:32 html/Ticket/Elements/ShowLinks:37
+msgid "Depended on by"
+msgstr "תלויים בו"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr ""
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:180 html/Ticket/Elements/EditLinks:119 html/Ticket/Elements/EditLinks:36 html/Ticket/Elements/ShowDependencies:25 html/Ticket/Elements/ShowLinks:27
+msgid "Depends on"
+msgstr "תלוי ב"
+
+#: NOT FOUND IN SOURCE
+msgid "DependsOn"
+msgstr ""
+
+#: html/Elements/SelectSortOrder:35
+msgid "Descending"
+msgstr "יורד"
+
+#: html/SelfService/Create.html:73 html/Ticket/Create.html:119
+msgid "Describe the issue below"
+msgstr ""
+
+#: html/Admin/Elements/AddCustomFieldValue:37 html/Admin/Elements/EditCustomField:39 html/Admin/Elements/EditScrip:34 html/Admin/Elements/ModifyQueue:36 html/Admin/Elements/ModifyTemplate:36 html/Admin/Groups/Modify.html:49 html/Admin/Queues/Modify.html:48 html/Elements/SelectGroups:27 html/User/Groups/Modify.html:49
+msgid "Description"
+msgstr "תיאור"
+
+#: NOT FOUND IN SOURCE
+msgid "Details"
+msgstr "פרטים"
+
+#: html/Ticket/Elements/Tabs:85
+msgid "Display"
+msgstr "הצג"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Display Access Control List"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Display Scrip templates for this queue"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Display Scrips for this queue"
+msgstr ""
+
+#: html/Ticket/Elements/ShowHistory:35
+msgid "Display mode"
+msgstr "מצב תצוגה"
+
+#: NOT FOUND IN SOURCE
+msgid "Display ticket #%1"
+msgstr "הצג פנייה #%1"
+
+#: lib/RT/System.pm:54
+msgid "Do anything and everything"
+msgstr ""
+
+#: html/Elements/Refresh:30
+msgid "Don't refresh this page."
+msgstr "אל תרענן דף זה."
+
+#: html/Search/Elements/PickRestriction:114
+msgid "Don't show search results"
+msgstr "אל תראה את תוצאות החיפוש"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "Download"
+msgstr "הורד"
+
+#: html/Elements/SelectDateType:32 html/Ticket/Create.html:167 html/Ticket/Elements/EditDates:45 html/Ticket/Elements/ShowDates:43 lib/RT/Ticket_Overlay.pm:1171
+msgid "Due"
+msgstr "תאריך יעד"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr ""
+
+#: bin/rt-commit-handler:754
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit Conditions"
+msgstr ""
+
+#: html/Admin/Queues/CustomFields.html:45
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr ""
+
+#: html/Ticket/ModifyLinks.html:36
+msgid "Edit Relationships"
+msgstr ""
+
+#: html/Admin/Queues/Templates.html:42
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit keywords"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr ""
+
+#: html/Admin/Global/index.html:46
+msgid "Edit system templates"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:25 html/Admin/Queues/Modify.html:118
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:25
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomField:91
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr ""
+
+#: html/Admin/Groups/Members.html:32
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr ""
+
+#: html/User/Groups/Members.html:129
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2622 lib/RT/Ticket_Overlay.pm:2690
+msgid "Either base or target must be specified"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:53 html/Admin/Users/Prefs.html:46 html/Elements/SelectUsers:27 html/Ticket/Elements/AddWatchers:56 html/User/Prefs.html:42
+msgid "Email"
+msgstr "אי-מייל"
+
+#: lib/RT/User_Overlay.pm:188
+msgid "Email address in use"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:42
+msgid "EmailAddress"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:54
+msgid "EmailEncoding"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomField:51
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:53 html/User/Groups/Modify.html:53
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr "מופעל (מחיקת סימון תיבה זו מבטלת את קבוצה זו)"
+
+#: html/Admin/Queues/Modify.html:84
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:99
+msgid "Enabled Custom Fields"
+msgstr ""
+
+#: html/Admin/Queues/index.html:56
+msgid "Enabled Queues"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomField:107 html/Admin/Groups/Modify.html:117 html/Admin/Queues/Modify.html:140 html/Admin/Users/Modify.html:283 html/User/Groups/Modify.html:117
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:428
+msgid "Enter multiple values"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:425
+msgid "Enter one value"
+msgstr ""
+
+#: html/Ticket/Elements/EditLinks:112
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "הכנס פניות או כתובות כדי לקשר פניות אליהן. הפרד ערכים רבים באמצעות רווחים."
+
+#: html/Elements/Login:39 html/SelfService/Error.html:25 html/SelfService/Error.html:26
+msgid "Error"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Error adding watcher"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1356
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1532
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr ""
+
+#: etc/initialdata:20
+msgid "Everyone"
+msgstr ""
+
+#: bin/rt-crontool:194
+msgid "Example:"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:64
+msgid "ExternalAuthId"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:58
+msgid "ExternalContactInfoId"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:73
+msgid "Extra info"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:302
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:309
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr ""
+
+#: bin/rt-crontool:138
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr ""
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "פברואר"
+
+#: NOT FOUND IN SOURCE
+msgid "February"
+msgstr "פברואר"
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr ""
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:59 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "עדיפות סופית"
+
+#: lib/RT/Ticket_Overlay.pm:1162
+msgid "FinalPriority"
+msgstr ""
+
+#: html/Admin/Queues/People.html:61 html/Ticket/Elements/EditPeople:34
+msgid "Find group whose"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Find new/open tickets"
+msgstr ""
+
+#: html/Admin/Queues/People.html:57 html/Admin/Users/index.html:46 html/Ticket/Elements/EditPeople:30
+msgid "Find people whose"
+msgstr "מצא אנשים ש"
+
+#: html/Search/Listing.html:108
+msgid "Find tickets"
+msgstr "מצא פניות"
+
+#: NOT FOUND IN SOURCE
+msgid "Finish Approval"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:58
+msgid "First"
+msgstr ""
+
+#: html/Search/Listing.html:41
+msgid "First page"
+msgstr "עמוד ראשון"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr ""
+
+#: html/Search/Bulk.html:87
+msgid "Force change"
+msgstr "הכרח שינוי"
+
+#: html/Search/Listing.html:106
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr "נמצאו %1 פניות"
+
+#: lib/RT/Interface/Web.pm:902
+msgid "Found Object"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:44
+msgid "FreeformContactInfo"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:38
+msgid "FreeformMultiple"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformSingle"
+msgstr ""
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "שישי"
+
+#: html/Ticket/Elements/ShowHistory:41 html/Ticket/Elements/ShowHistory:51
+msgid "Full headers"
+msgstr "כותרים מלאים"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:593
+#. ($New->Name)
+msgid "Given to %1"
+msgstr ""
+
+#: html/Admin/Elements/Tabs:41 html/Admin/index.html:38
+msgid "Global"
+msgstr "גלובאלי"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Keyword Selections"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr ""
+
+#: html/Admin/Elements/SelectTemplate:38
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:75 html/Admin/Queues/People.html:59 html/Admin/Queues/People.html:63 html/Admin/Queues/index.html:44 html/Admin/Users/index.html:49 html/Ticket/Elements/EditPeople:32 html/Ticket/Elements/EditPeople:36 html/index.html:41
+msgid "Go!"
+msgstr "חפש"
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr ""
+
+#: html/Search/Listing.html:50
+msgid "Goto page"
+msgstr ""
+
+#: html/Elements/GotoTicket:25 html/SelfService/Elements/GotoTicket:25
+msgid "Goto ticket"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Grand"
+msgstr ""
+
+#: html/Ticket/Elements/AddWatchers:46 html/User/Elements/DelegateRights:78
+msgid "Group"
+msgstr "קבוצה"
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr "קבוצה %1 %2: %3"
+
+#: html/Admin/Elements/GroupTabs:45 html/Admin/Elements/QueueTabs:57 html/Admin/Elements/SystemTabs:44 html/Admin/Global/index.html:55
+msgid "Group Rights"
+msgstr "זכויות קבוצה"
+
+#: lib/RT/Group_Overlay.pm:965
+msgid "Group already has member"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Group could not be created."
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:77
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:497
+msgid "Group created"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:1133
+msgid "Group has no such member"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:945 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1429 lib/RT/Ticket_Overlay.pm:1507
+msgid "Group not found"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr ""
+
+#: html/Admin/Elements/SelectNewGroupMembers:35 html/Admin/Elements/Tabs:35 html/Admin/Groups/Members.html:64 html/Admin/Queues/People.html:83 html/Admin/index.html:32 html/User/Groups/Members.html:67
+msgid "Groups"
+msgstr "קבוצות"
+
+#: lib/RT/Group_Overlay.pm:971
+msgid "Groups can't be members of their members"
+msgstr ""
+
+#: lib/RT/Interface/CLI.pm:73 lib/RT/Interface/CLI.pm:73
+msgid "Hello!"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr ""
+
+#: html/Ticket/Elements/ShowHistory:30 html/Ticket/Elements/Tabs:88
+msgid "History"
+msgstr "הסטוריה"
+
+#: html/Admin/Elements/ModifyUser:68
+msgid "HomePhone"
+msgstr ""
+
+#: html/Elements/Tabs:44
+msgid "Homepage"
+msgstr "דף הבית"
+
+#: lib/RT/Base.pm:74
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "I have [quant,_1,concrete mixer]."
+msgstr ""
+
+#: html/Ticket/Elements/ShowBasics:27 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:44 html/User/Prefs.html:39
+msgid "Identity"
+msgstr "זהות"
+
+#: etc/upgrade/2.1.71:86
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr ""
+
+#: bin/rt-crontool:190
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr ""
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "If you've updated anything above, be sure to"
+msgstr "אם עדכנת משהו לעיל, אל תשכח ל"
+
+#: lib/RT/Interface/Web.pm:894
+msgid "Illegal value for %1"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:897
+msgid "Immutable field"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:74
+msgid "Include disabled custom fields in listing."
+msgstr ""
+
+#: html/Admin/Queues/index.html:43
+msgid "Include disabled queues in listing."
+msgstr ""
+
+#: html/Admin/Users/index.html:47
+msgid "Include disabled users in search."
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1161 lib/RT/Ticket_Overlay.pm:1163
+msgid "InitialPriority"
+msgstr ""
+
+#: lib/RT/ScripAction_Overlay.pm:105
+msgid "Input error"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Interest noted"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3796
+msgid "Internal Error"
+msgstr ""
+
+#: lib/RT/Record.pm:143
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:644
+msgid "Invalid Group Type"
+msgstr ""
+
+#: lib/RT/Principal_Overlay.pm:128
+msgid "Invalid Right"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Invalid Type"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:899
+msgid "Invalid data"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:439
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:134 lib/RT/Template_Overlay.pm:251
+msgid "Invalid queue"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:244 lib/RT/ACE_Overlay.pm:253 lib/RT/ACE_Overlay.pm:259 lib/RT/ACE_Overlay.pm:270 lib/RT/ACE_Overlay.pm:275
+msgid "Invalid right"
+msgstr ""
+
+#: lib/RT/Record.pm:118
+#. ($key)
+msgid "Invalid value for %1"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3434
+msgid "Invalid value for custom field"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:346
+msgid "Invalid value for status"
+msgstr ""
+
+#: bin/rt-crontool:191
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr ""
+
+#: bin/rt-crontool:192
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr ""
+
+#: bin/rt-crontool:163
+msgid "It takes several arguments:"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr ""
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "ינואר"
+
+#: NOT FOUND IN SOURCE
+msgid "January"
+msgstr "ינואר"
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "Join or leave this group"
+msgstr ""
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "יולי"
+
+#: NOT FOUND IN SOURCE
+msgid "July"
+msgstr "יולי"
+
+#: html/Ticket/Elements/Tabs:99
+msgid "Jumbo"
+msgstr "ג'מבו"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "יוני"
+
+#: NOT FOUND IN SOURCE
+msgid "June"
+msgstr "יוני"
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:52
+msgid "Lang"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:73
+msgid "Last"
+msgstr ""
+
+#: html/Ticket/Elements/EditDates:38 html/Ticket/Elements/ShowDates:39
+msgid "Last Contact"
+msgstr "מגע אחרון"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Contacted"
+msgstr "קשר אחרון"
+
+#: html/Search/Elements/TicketHeader:41
+msgid "Last Notified"
+msgstr "נודע לאחרונה"
+
+#: html/Elements/SelectDateType:30
+msgid "Last Updated"
+msgstr "עדכון אחרון"
+
+#: NOT FOUND IN SOURCE
+msgid "LastUpdated"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr "נותרה"
+
+#: html/Admin/Users/Modify.html:83
+msgid "Let this user access RT"
+msgstr "תן למשתמש זה לגשת ל R"
+
+#: html/Admin/Users/Modify.html:87
+msgid "Let this user be granted rights"
+msgstr "תן אפשרות להעניק זכויות למשתמש זה"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2704
+msgid "Link already exists"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2716
+msgid "Link could not be created"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2724 lib/RT/Ticket_Overlay.pm:2734
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2645
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2651
+msgid "Link not found"
+msgstr ""
+
+#: html/Ticket/ModifyLinks.html:25 html/Ticket/ModifyLinks.html:29
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Link ticket %1"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:97
+msgid "Links"
+msgstr "קישורים"
+
+#: html/Admin/Users/Modify.html:114 html/User/Prefs.html:85
+msgid "Location"
+msgstr "מיקום"
+
+#: lib/RT.pm:159
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr ""
+
+#: html/Elements/Header:57
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "מחובר כ %1"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:35 html/Elements/Login:44 html/Elements/Login:54
+msgid "Login"
+msgstr "כניסה"
+
+#: html/Elements/Header:54
+msgid "Logout"
+msgstr "יציאה"
+
+#: html/Search/Bulk.html:86
+msgid "Make Owner"
+msgstr "שנה בעלות ל"
+
+#: html/Search/Bulk.html:102
+msgid "Make Status"
+msgstr "שנה סטטוס"
+
+#: html/Search/Bulk.html:109
+msgid "Make date Due"
+msgstr "שנה תאריך יעד"
+
+#: html/Search/Bulk.html:110
+msgid "Make date Resolved"
+msgstr "שנה תאריך פתרון"
+
+#: html/Search/Bulk.html:107
+msgid "Make date Started"
+msgstr "שנה תאריך 'הותחל'"
+
+#: html/Search/Bulk.html:106
+msgid "Make date Starts"
+msgstr "שנה תאריך התחלה"
+
+#: html/Search/Bulk.html:108
+msgid "Make date Told"
+msgstr "שנע תאריך מגע אחרון"
+
+#: html/Search/Bulk.html:99
+msgid "Make priority"
+msgstr "שנה עדיפות"
+
+#: html/Search/Bulk.html:100
+msgid "Make queue"
+msgstr "שנה תור"
+
+#: html/Search/Bulk.html:98
+msgid "Make subject"
+msgstr "שנה נושא"
+
+#: html/Admin/index.html:33
+msgid "Manage groups and group membership"
+msgstr "נהל קבוצות וחברות בקבוצות"
+
+#: html/Admin/index.html:39
+msgid "Manage properties and configuration which apply to all queues"
+msgstr "נהל מאפיינים והגדרות שתקפים לכל התורות"
+
+#: html/Admin/index.html:36
+msgid "Manage queues and queue-specific properties"
+msgstr "נהל תורות ומאפיינים ספציפיים לתורות"
+
+#: html/Admin/index.html:30
+msgid "Manage users and passwords"
+msgstr "נהל משתמשים וספריות"
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "מרץ"
+
+#: NOT FOUND IN SOURCE
+msgid "March"
+msgstr "מרץ"
+
+#: NOT FOUND IN SOURCE
+msgid "May"
+msgstr "מאי"
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "מאי"
+
+#: lib/RT/Group_Overlay.pm:982
+msgid "Member added"
+msgstr "חבר הוסף"
+
+#: lib/RT/Group_Overlay.pm:1140
+msgid "Member deleted"
+msgstr "חבר נמחק"
+
+#: lib/RT/Group_Overlay.pm:1144
+msgid "Member not deleted"
+msgstr "חבר לא נמחק"
+
+#: html/Elements/SelectLinkType:26
+msgid "Member of"
+msgstr "חבר ב"
+
+#: NOT FOUND IN SOURCE
+msgid "MemberOf"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:42 html/User/Elements/GroupTabs:42
+msgid "Members"
+msgstr "חברים"
+
+#: lib/RT/Ticket_Overlay.pm:2891
+msgid "Merge Successful"
+msgstr "מיזוג הצליח"
+
+#: lib/RT/Ticket_Overlay.pm:2811
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "מיזוג נכשל. לא יכולתי להגדיר מזהה אפקטיבי"
+
+#: html/Ticket/Elements/EditLinks:115
+msgid "Merge into"
+msgstr "מזג לתוך"
+
+#: html/Ticket/Update.html:102
+msgid "Message"
+msgstr "הודעה"
+
+#: lib/RT/Interface/Web.pm:901
+msgid "Missing a primary key?: %1"
+msgstr "חסר מפתח ראשי?: %1"
+
+#: html/Admin/Users/Modify.html:169 html/User/Prefs.html:54
+msgid "Mobile"
+msgstr "נייד"
+
+#: html/Admin/Elements/ModifyUser:72
+msgid "MobilePhone"
+msgstr "טלפון נייד"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify Access Control List"
+msgstr "שנה רשימת בקרת גישה"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Custom Field %1"
+msgstr ""
+
+#: html/Admin/Global/CustomFields.html:44 html/Admin/Global/index.html:51
+msgid "Modify Custom Fields which apply to all queues"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "Modify Scrip templates for this queue"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "Modify Scrips for this queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify System ACLS"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr ""
+
+#: html/Admin/Queues/CustomField.html:45
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:53
+msgid "Modify a CustomField which applies to all queues"
+msgstr ""
+
+#: html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr ""
+
+#: html/Admin/Global/Scrip.html:48
+msgid "Modify a scrip which applies to all queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify dates for # %1"
+msgstr ""
+
+#: html/Ticket/ModifyDates.html:25 html/Ticket/ModifyDates.html:29
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr ""
+
+#: html/Ticket/ModifyDates.html:35
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr ""
+
+#: html/Admin/Global/GroupRights.html:25 html/Admin/Global/GroupRights.html:28 html/Admin/Global/index.html:56
+msgid "Modify global group rights"
+msgstr ""
+
+#: html/Admin/Global/GroupRights.html:33
+msgid "Modify global group rights."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for groups"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for users"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr ""
+
+#: html/Admin/Global/UserRights.html:25 html/Admin/Global/UserRights.html:28 html/Admin/Global/index.html:60
+msgid "Modify global user rights"
+msgstr ""
+
+#: html/Admin/Global/UserRights.html:33
+msgid "Modify global user rights."
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "Modify group metadata or delete group"
+msgstr ""
+
+#: html/Admin/Groups/GroupRights.html:25 html/Admin/Groups/GroupRights.html:29 html/Admin/Groups/GroupRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr ""
+
+#: html/Admin/Queues/GroupRights.html:25 html/Admin/Queues/GroupRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Modify membership roster for this group"
+msgstr ""
+
+#: lib/RT/System.pm:61
+msgid "Modify one's own RT account"
+msgstr ""
+
+#: html/Admin/Queues/People.html:25 html/Admin/Queues/People.html:29
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr ""
+
+#: html/Ticket/ModifyPeople.html:25 html/Ticket/ModifyPeople.html:29 html/Ticket/ModifyPeople.html:35
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr ""
+
+#: html/Admin/Queues/Scrips.html:44
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr ""
+
+#: html/Admin/Global/Scrips.html:44 html/Admin/Global/index.html:42
+msgid "Modify scrips which apply to all queues"
+msgstr ""
+
+#: html/Admin/Global/Template.html:25 html/Admin/Global/Template.html:30 html/Admin/Global/Template.html:81 html/Admin/Queues/Template.html:78
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr ""
+
+#: html/Admin/Global/Templates.html:44
+msgid "Modify templates which apply to all queues"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:87 html/User/Groups/Modify.html:86
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Modify the queue watchers"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:236
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr ""
+
+#: html/Ticket/ModifyAll.html:37
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "שנה פנייה מספר %1"
+
+#: html/Ticket/Modify.html:25 html/Ticket/Modify.html:28 html/Ticket/Modify.html:34
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "שינוי פנוייה מספר %1"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Modify tickets"
+msgstr "שינוי פניות"
+
+#: html/Admin/Groups/UserRights.html:25 html/Admin/Groups/UserRights.html:29 html/Admin/Groups/UserRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr ""
+
+#: html/Admin/Queues/UserRights.html:25 html/Admin/Queues/UserRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyACL"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "ModifyOwnMembership"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "ModifyQueueWatchers"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "ModifyScrips"
+msgstr ""
+
+#: lib/RT/System.pm:61
+msgid "ModifySelf"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "ModifyTemplate"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "ModifyTicket"
+msgstr ""
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "שני"
+
+#: html/Ticket/Elements/ShowRequestor:42
+#. ($name)
+msgid "More about %1"
+msgstr "עוד לגבי %1"
+
+#: html/Admin/Elements/EditCustomFields:61
+msgid "Move down"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:53
+msgid "Move up"
+msgstr ""
+
+#: html/Admin/Elements/SelectSingleOrMultiple:27
+msgid "Multiple"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:179
+msgid "Must specify 'Name' attribute"
+msgstr ""
+
+#: html/SelfService/Elements/MyRequests:49
+#. ($friendly_status)
+msgid "My %1 tickets"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "My Approvals"
+msgstr "האישורים שלי"
+
+#: html/Approvals/index.html:25 html/Approvals/index.html:26
+msgid "My approvals"
+msgstr "האישורים שלי"
+
+#: html/Admin/Elements/AddCustomFieldValue:33 html/Admin/Elements/EditCustomField:34 html/Admin/Elements/ModifyTemplate:28 html/Admin/Elements/ModifyUser:30 html/Admin/Groups/Modify.html:44 html/Elements/SelectGroups:26 html/Elements/SelectUsers:28 html/User/Groups/Modify.html:44
+msgid "Name"
+msgstr "שם"
+
+#: lib/RT/User_Overlay.pm:186
+msgid "Name in use"
+msgstr "שם בשימוש"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr ""
+
+#: html/Ticket/Elements/ShowDates:52
+msgid "Never"
+msgstr ""
+
+#: html/Elements/Quicksearch:30
+msgid "New"
+msgstr "חדש"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:93 html/User/Prefs.html:65
+msgid "New Password"
+msgstr "סיסמא חדשה"
+
+#: etc/initialdata:317 etc/upgrade/2.1.71:16
+msgid "New Pending Approval"
+msgstr ""
+
+#: html/Ticket/Elements/EditLinks:111
+msgid "New Relationships"
+msgstr "יחסים חדשים"
+
+#: html/Ticket/Elements/Tabs:36
+msgid "New Search"
+msgstr "חיפוש חדש"
+
+#: html/Admin/Global/CustomField.html:41 html/Admin/Global/CustomFields.html:39 html/Admin/Queues/CustomField.html:52 html/Admin/Queues/CustomFields.html:40
+msgid "New custom field"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:54 html/User/Elements/GroupTabs:52
+msgid "New group"
+msgstr "קבוצה חדשה"
+
+#: html/SelfService/Prefs.html:32
+msgid "New password"
+msgstr "סיסמא חדשה"
+
+#: lib/RT/User_Overlay.pm:647
+msgid "New password notification sent"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:70
+msgid "New queue"
+msgstr "תור חדש"
+
+#: NOT FOUND IN SOURCE
+msgid "New request"
+msgstr "בקשה חדשה"
+
+#: html/Admin/Elements/SelectRights:42
+msgid "New rights"
+msgstr "זכויות חדשות"
+
+#: html/Admin/Global/Scrip.html:40 html/Admin/Global/Scrips.html:39 html/Admin/Queues/Scrip.html:43 html/Admin/Queues/Scrips.html:53
+msgid "New scrip"
+msgstr "סקריפ חדש"
+
+#: NOT FOUND IN SOURCE
+msgid "New search"
+msgstr "חיפוש חדש"
+
+#: html/Admin/Global/Template.html:60 html/Admin/Global/Templates.html:39 html/Admin/Queues/Template.html:58 html/Admin/Queues/Templates.html:50
+msgid "New template"
+msgstr "תבנית חדשה"
+
+#: html/SelfService/Elements/Tabs:48
+msgid "New ticket"
+msgstr "פנייה חדשה"
+
+#: lib/RT/Ticket_Overlay.pm:2778
+msgid "New ticket doesn't exist"
+msgstr "פנייה חדשה לא קיימת"
+
+#: html/Admin/Elements/UserTabs:52
+msgid "New user"
+msgstr "משתמש חדש"
+
+#: html/Admin/Elements/CreateUserCalled:26
+msgid "New user called"
+msgstr "משתמש חדש שנקרא"
+
+#: html/Admin/Queues/People.html:55 html/Ticket/Elements/EditPeople:29
+msgid "New watchers"
+msgstr "צופים חדשים"
+
+#: html/Admin/Users/Prefs.html:42
+msgid "New window setting"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:69
+msgid "Next"
+msgstr "הבא"
+
+#: html/Search/Listing.html:48
+msgid "Next page"
+msgstr "דף הבא"
+
+#: html/Admin/Elements/ModifyUser:50
+msgid "NickName"
+msgstr "כינוי"
+
+#: html/Admin/Users/Modify.html:63 html/User/Prefs.html:46
+msgid "Nickname"
+msgstr "כינוי"
+
+#: html/Admin/Elements/EditCustomField:90 html/Admin/Elements/EditCustomFields:105
+msgid "No CustomField"
+msgstr ""
+
+#: html/Admin/Groups/GroupRights.html:84 html/Admin/Groups/UserRights.html:71
+msgid "No Group defined"
+msgstr ""
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:68
+msgid "No Queue defined"
+msgstr ""
+
+#: bin/rt-crontool:56
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr ""
+
+#: html/Admin/Global/Template.html:79 html/Admin/Queues/Template.html:76
+msgid "No Template"
+msgstr ""
+
+#: bin/rt-commit-handler:764
+msgid "No Ticket specified. Aborting ticket "
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr ""
+
+#: html/Approvals/Elements/Approve:46
+msgid "No action"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:896
+msgid "No column specified"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr ""
+
+#: html/Elements/ViewUser:36 html/Ticket/Elements/ShowRequestor:45
+msgid "No comment entered about this user"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2189 lib/RT/Ticket_Overlay.pm:2257
+msgid "No correspondence attached"
+msgstr ""
+
+#: lib/RT/Action/Generic.pm:150 lib/RT/Condition/Generic.pm:176 lib/RT/Search/ActiveTicketsInQueue.pm:56 lib/RT/Search/Generic.pm:113
+#. (ref $self)
+msgid "No description for %1"
+msgstr ""
+
+#: lib/RT/Users_Overlay.pm:145
+msgid "No group specified"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:865
+msgid "No password set"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:259
+msgid "No permission to create queues"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:342
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:152
+msgid "No permission to create users"
+msgstr ""
+
+#: html/SelfService/Display.html:118
+msgid "No permission to display that ticket"
+msgstr ""
+
+#: html/SelfService/Update.html:52
+msgid "No permission to view update ticket"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1488
+msgid "No principal specified"
+msgstr ""
+
+#: html/Admin/Queues/People.html:154 html/Admin/Queues/People.html:164
+msgid "No principals selected."
+msgstr ""
+
+#: html/Admin/Queues/index.html:35
+msgid "No queues matching search criteria found."
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:81
+msgid "No rights found"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:33
+msgid "No rights granted."
+msgstr ""
+
+#: html/Search/Bulk.html:149
+msgid "No search to operate on."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:478 lib/RT/Transaction_Overlay.pm:516
+msgid "No transaction type specified"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "No user or email address specified"
+msgstr ""
+
+#: html/Admin/Users/index.html:36
+msgid "No users matching search criteria found."
+msgstr ""
+
+#: bin/rt-commit-handler:644
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:893
+msgid "No value sent to _Set!\\n"
+msgstr ""
+
+#: html/Search/Elements/TicketRow:37
+msgid "Nobody"
+msgstr "אף אחד"
+
+#: lib/RT/Interface/Web.pm:898
+msgid "Nonexistant field?"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Not logged in"
+msgstr "לא בתוך המערכת"
+
+#: html/Elements/Header:59
+msgid "Not logged in."
+msgstr "לא בתוך המערכת."
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "לא הוזן"
+
+#: html/NoAuth/Reminder.html:27
+msgid "Not yet implemented."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Not yet implemented...."
+msgstr ""
+
+#: html/Approvals/Elements/Approve:49
+msgid "Notes"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:650
+msgid "Notification could not be sent"
+msgstr ""
+
+#: etc/initialdata:94
+msgid "Notify AdminCcs"
+msgstr ""
+
+#: etc/initialdata:90
+msgid "Notify AdminCcs as Comment"
+msgstr ""
+
+#: etc/initialdata:121
+msgid "Notify Other Recipients"
+msgstr ""
+
+#: etc/initialdata:117
+msgid "Notify Other Recipients as Comment"
+msgstr ""
+
+#: etc/initialdata:86
+msgid "Notify Owner"
+msgstr ""
+
+#: etc/initialdata:82
+msgid "Notify Owner as Comment"
+msgstr ""
+
+#: etc/initialdata:319 etc/upgrade/2.1.71:17
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr ""
+
+#: etc/initialdata:78
+msgid "Notify Requestors"
+msgstr ""
+
+#: etc/initialdata:104
+msgid "Notify Requestors and Ccs"
+msgstr ""
+
+#: etc/initialdata:99
+msgid "Notify Requestors and Ccs as Comment"
+msgstr ""
+
+#: etc/initialdata:113
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr ""
+
+#: etc/initialdata:109
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr ""
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "נובמבר"
+
+#: NOT FOUND IN SOURCE
+msgid "November"
+msgstr "נובמבר"
+
+#: lib/RT/Record.pm:157
+msgid "Object could not be created"
+msgstr ""
+
+#: lib/RT/Record.pm:176
+msgid "Object created"
+msgstr ""
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "אוקטובר"
+
+#: NOT FOUND IN SOURCE
+msgid "October"
+msgstr "אוקטובר"
+
+#: html/Elements/SelectDateRelation:35
+msgid "On"
+msgstr "ב"
+
+#: etc/initialdata:155
+msgid "On Comment"
+msgstr ""
+
+#: etc/initialdata:148
+msgid "On Correspond"
+msgstr ""
+
+#: etc/initialdata:137
+msgid "On Create"
+msgstr ""
+
+#: etc/initialdata:169
+msgid "On Owner Change"
+msgstr ""
+
+#: etc/initialdata:177
+msgid "On Queue Change"
+msgstr ""
+
+#: etc/initialdata:183
+msgid "On Resolve"
+msgstr ""
+
+#: etc/initialdata:161
+msgid "On Status Change"
+msgstr ""
+
+#: etc/initialdata:142
+msgid "On Transaction"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:50
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr "הצג רק אישורים עבור בקשות שנוצרו אחרי %1"
+
+#: html/Approvals/Elements/PendingMyApproval:48
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr "הצג רק אישורים עבור בקשות שנוצרו לפני %1"
+
+#: html/Elements/Quicksearch:31
+msgid "Open"
+msgstr "פתוח"
+
+#: html/Ticket/Elements/Tabs:136
+msgid "Open it"
+msgstr "פתח"
+
+#: NOT FOUND IN SOURCE
+msgid "Open requests"
+msgstr ""
+
+#: html/SelfService/Elements/Tabs:42
+msgid "Open tickets"
+msgstr ""
+
+#: html/Admin/Users/Prefs.html:41
+msgid "Open tickets (from listing) in a new window"
+msgstr ""
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in another window"
+msgstr ""
+
+#: etc/initialdata:133
+msgid "Open tickets on correspondence"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:101
+msgid "Ordering and sorting"
+msgstr "סידור ומיון"
+
+#: html/Admin/Elements/ModifyUser:46 html/Admin/Users/Modify.html:117 html/Elements/SelectUsers:29 html/User/Prefs.html:86
+msgid "Organization"
+msgstr "ארגון"
+
+#: html/Approvals/Elements/Approve:33
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:55 html/Admin/Queues/Modify.html:69
+msgid "Over time, priority moves toward"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Own tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "OwnTicket"
+msgstr ""
+
+#: etc/initialdata:38 html/Elements/MyRequests:32 html/SelfService/Elements/MyRequests:30 html/Ticket/Create.html:48 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/EditPeople:44 html/Ticket/Elements/ShowPeople:27 html/Ticket/Update.html:63 lib/RT/ACE_Overlay.pm:86 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "בעלים"
+
+#: lib/RT/Ticket_Overlay.pm:3071
+#. ($OldOwnerObj->Name,  $NewOwnerObj->Name)
+msgid "Owner changed from %1 to %2"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:582
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:31
+msgid "Owner is"
+msgstr "הבעלים"
+
+#: html/Admin/Users/Modify.html:174 html/User/Prefs.html:56
+msgid "Pager"
+msgstr "ביפר"
+
+#: html/Admin/Elements/ModifyUser:74
+msgid "PagerPhone"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Parent"
+msgstr ""
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/EditLinks:127 html/Ticket/Elements/EditLinks:58 html/Ticket/Elements/ShowLinks:47
+msgid "Parents"
+msgstr "הורים"
+
+#: html/Elements/Login:52 html/User/Prefs.html:61
+msgid "Password"
+msgstr "סיסמא"
+
+#: html/NoAuth/Reminder.html:25
+msgid "Password Reminder"
+msgstr "מזכיר סיסמא"
+
+#: lib/RT/User_Overlay.pm:169 lib/RT/User_Overlay.pm:868
+msgid "Password too short"
+msgstr "סיסמא קצרה מדי"
+
+#: html/Admin/Users/Modify.html:291 html/User/Prefs.html:172
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "סיסמא: %1"
+
+#: html/Admin/Users/Modify.html:293
+msgid "Passwords do not match."
+msgstr "הסיסמאות אינן תואמות"
+
+#: html/User/Prefs.html:174
+msgid "Passwords do not match. Your password has not been changed"
+msgstr ""
+
+#: html/Ticket/Elements/ShowSummary:45 html/Ticket/Elements/Tabs:96 html/Ticket/ModifyAll.html:51
+msgid "People"
+msgstr "אנשים"
+
+#: etc/initialdata:126
+msgid "Perform a user-defined action"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:231 lib/RT/ACE_Overlay.pm:237 lib/RT/ACE_Overlay.pm:563 lib/RT/ACE_Overlay.pm:573 lib/RT/ACE_Overlay.pm:583 lib/RT/ACE_Overlay.pm:648 lib/RT/CurrentUser.pm:83 lib/RT/CurrentUser.pm:92 lib/RT/CustomField_Overlay.pm:101 lib/RT/CustomField_Overlay.pm:202 lib/RT/CustomField_Overlay.pm:234 lib/RT/CustomField_Overlay.pm:511 lib/RT/CustomField_Overlay.pm:91 lib/RT/Group_Overlay.pm:1095 lib/RT/Group_Overlay.pm:1099 lib/RT/Group_Overlay.pm:1108 lib/RT/Group_Overlay.pm:1159 lib/RT/Group_Overlay.pm:1163 lib/RT/Group_Overlay.pm:1169 lib/RT/Group_Overlay.pm:426 lib/RT/Group_Overlay.pm:518 lib/RT/Group_Overlay.pm:596 lib/RT/Group_Overlay.pm:604 lib/RT/Group_Overlay.pm:701 lib/RT/Group_Overlay.pm:705 lib/RT/Group_Overlay.pm:711 lib/RT/Group_Overlay.pm:904 lib/RT/Group_Overlay.pm:908 lib/RT/Group_Overlay.pm:921 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:126 lib/RT/Scrip_Overlay.pm:137 lib/RT/Scrip_Overlay.pm:197 lib/RT/Scrip_Overlay.pm:430 lib/RT/Template_Overlay.pm:284 lib/RT/Template_Overlay.pm:88 lib/RT/Template_Overlay.pm:94 lib/RT/Ticket_Overlay.pm:1341 lib/RT/Ticket_Overlay.pm:1351 lib/RT/Ticket_Overlay.pm:1365 lib/RT/Ticket_Overlay.pm:1518 lib/RT/Ticket_Overlay.pm:1527 lib/RT/Ticket_Overlay.pm:1540 lib/RT/Ticket_Overlay.pm:1875 lib/RT/Ticket_Overlay.pm:2013 lib/RT/Ticket_Overlay.pm:2177 lib/RT/Ticket_Overlay.pm:2244 lib/RT/Ticket_Overlay.pm:2603 lib/RT/Ticket_Overlay.pm:2675 lib/RT/Ticket_Overlay.pm:2769 lib/RT/Ticket_Overlay.pm:2784 lib/RT/Ticket_Overlay.pm:2978 lib/RT/Ticket_Overlay.pm:3206 lib/RT/Ticket_Overlay.pm:3404 lib/RT/Ticket_Overlay.pm:3566 lib/RT/Ticket_Overlay.pm:3618 lib/RT/Ticket_Overlay.pm:3783 lib/RT/Transaction_Overlay.pm:466 lib/RT/Transaction_Overlay.pm:473 lib/RT/Transaction_Overlay.pm:502 lib/RT/Transaction_Overlay.pm:509 lib/RT/User_Overlay.pm:1355 lib/RT/User_Overlay.pm:570 lib/RT/User_Overlay.pm:605 lib/RT/User_Overlay.pm:861 lib/RT/User_Overlay.pm:962
+msgid "Permission Denied"
+msgstr ""
+
+#: html/User/Elements/Tabs:35
+msgid "Personal Groups"
+msgstr "קבוצות אישיות"
+
+#: html/User/Groups/index.html:30 html/User/Groups/index.html:40
+msgid "Personal groups"
+msgstr "קבוצות אישיות"
+
+#: html/User/Elements/DelegateRights:37
+msgid "Personal groups:"
+msgstr "קבוצות אישיות"
+
+#: html/Admin/Users/Modify.html:156 html/User/Prefs.html:49
+msgid "Phone numbers"
+msgstr "מספרי טלפון"
+
+#: NOT FOUND IN SOURCE
+msgid "Placeholder"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Pref"
+msgstr ""
+
+#: html/Elements/Header:52 html/Elements/Tabs:53 html/SelfService/Elements/Tabs:51 html/SelfService/Prefs.html:25 html/User/Prefs.html:25 html/User/Prefs.html:28
+msgid "Preferences"
+msgstr "מאפיינים"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr ""
+
+#: lib/RT/Action/Generic.pm:160
+msgid "Prepare Stubbed"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:61
+msgid "Prev"
+msgstr "הקודם"
+
+#: html/Search/Listing.html:44
+msgid "Previous page"
+msgstr "דף קודם"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:133 lib/RT/ACE_Overlay.pm:208 lib/RT/ACE_Overlay.pm:552
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:54 html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:54 html/Ticket/Elements/ShowBasics:39 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "עדיפות"
+
+#: html/Admin/Elements/ModifyQueue:51 html/Admin/Queues/Modify.html:65
+msgid "Priority starts at"
+msgstr ""
+
+#: etc/initialdata:25
+msgid "Privileged"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:271 html/User/Prefs.html:163
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr ""
+
+#: html/Admin/Users/index.html:62
+msgid "Privileged users"
+msgstr ""
+
+#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59
+msgid "Pseudogroup for internal use"
+msgstr ""
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Elements/Quicksearch:29 html/Search/Elements/PickRestriction:46 html/SelfService/Create.html:33 html/Ticket/Create.html:38 html/Ticket/Elements/EditBasics:64 html/Ticket/Elements/ShowBasics:43 html/User/Elements/DelegateRights:80 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "תור"
+
+#: html/Admin/Queues/CustomField.html:42 html/Admin/Queues/Scrip.html:50 html/Admin/Queues/Scrips.html:46 html/Admin/Queues/Templates.html:44
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Keyword Selections"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:31 html/Admin/Queues/Modify.html:43
+msgid "Queue Name"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:263
+msgid "Queue already exists"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:272 lib/RT/Queue_Overlay.pm:278
+msgid "Queue could not be created"
+msgstr ""
+
+#: html/Ticket/Create.html:205
+msgid "Queue could not be loaded."
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:282
+msgid "Queue created"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Queue is not specified."
+msgstr ""
+
+#: html/SelfService/Display.html:71 lib/RT/CustomField_Overlay.pm:98
+msgid "Queue not found"
+msgstr ""
+
+#: html/Admin/Elements/Tabs:38 html/Admin/index.html:35
+msgid "Queues"
+msgstr "תורים"
+
+#: html/Elements/Quicksearch:25
+msgid "Quick search"
+msgstr "חיפוש מהיר"
+
+#: html/Elements/Login:44
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr ""
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr ""
+
+#: html/Admin/index.html:25 html/Admin/index.html:26
+msgid "RT Administration"
+msgstr "ניהול RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr ""
+
+#: html/Elements/Error:41 html/SelfService/Error.html:41
+msgid "RT Error"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT Recieved mail (%1) from itself."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT Self Service / Closed Tickets"
+msgstr ""
+
+#: html/index.html:25 html/index.html:28
+msgid "RT at a glance"
+msgstr "RT ממבט כולל"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr ""
+
+#: html/Elements/PageLayout:26
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr "RT / %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr ""
+
+#: html/Elements/Login:92
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT is &copy; Copyright 1996-2002 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr ""
+
+#: html/Admin/Users/Modify.html:58 html/Admin/Users/Prefs.html:52 html/User/Prefs.html:44
+msgid "Real Name"
+msgstr "שם אמיתי"
+
+#: html/Admin/Elements/ModifyUser:48
+msgid "RealName"
+msgstr "שם אמיתי"
+
+#: html/Ticket/Create.html:185 html/Ticket/Elements/EditLinks:139 html/Ticket/Elements/EditLinks:94 html/Ticket/Elements/ShowLinks:71
+msgid "Referred to by"
+msgstr "מתייחסים אליו"
+
+#: html/Elements/SelectLinkType:28 html/Ticket/Create.html:184 html/Ticket/Elements/EditLinks:135 html/Ticket/Elements/EditLinks:80 html/Ticket/Elements/ShowLinks:61
+msgid "Refers to"
+msgstr "מתייחס ל"
+
+#: NOT FOUND IN SOURCE
+msgid "RefersTo"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:27
+msgid "Refine search"
+msgstr "חדד את החיפוש"
+
+#: html/Elements/Refresh:36
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "רענן דף זה כל %1 דקות."
+
+#: html/Ticket/Create.html:174 html/Ticket/Elements/ShowSummary:62 html/Ticket/ModifyAll.html:57
+msgid "Relationships"
+msgstr "יחסים עם פניות אחרות"
+
+#: html/Search/Bulk.html:93
+msgid "Remove AdminCc"
+msgstr "הסר העתק ניהולי"
+
+#: html/Search/Bulk.html:91
+msgid "Remove Cc"
+msgstr "הסר העתק"
+
+#: html/Search/Bulk.html:89
+msgid "Remove Requestor"
+msgstr "הסר מבקש"
+
+#: html/Ticket/Elements/ShowTransaction:173 html/Ticket/Elements/Tabs:122
+msgid "Reply"
+msgstr "הגב"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Reply to tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "ReplyToTicket"
+msgstr "מענה לפנייה"
+
+#: etc/initialdata:44 html/Ticket/Update.html:40 lib/RT/ACE_Overlay.pm:87
+msgid "Requestor"
+msgstr "מבקש"
+
+#: html/Search/Elements/PickRestriction:38
+msgid "Requestor email address"
+msgstr "כתובת האי-מייל של המבקש"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr "מבקש(ים)"
+
+#: NOT FOUND IN SOURCE
+msgid "RequestorAddresses"
+msgstr "כתובת הפונה"
+
+#: html/SelfService/Create.html:41 html/Ticket/Create.html:56 html/Ticket/Elements/EditPeople:48 html/Ticket/Elements/ShowPeople:31
+msgid "Requestors"
+msgstr "מבקשים"
+
+#: html/Admin/Elements/ModifyQueue:61 html/Admin/Queues/Modify.html:75
+msgid "Requests should be due in"
+msgstr ""
+
+#: html/Elements/Submit:62
+msgid "Reset"
+msgstr "אפס נתונים"
+
+#: html/Admin/Users/Modify.html:159 html/User/Prefs.html:50
+msgid "Residence"
+msgstr "בית"
+
+#: html/Ticket/Elements/Tabs:132
+msgid "Resolve"
+msgstr "פתור"
+
+#: html/Ticket/Update.html:133
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr "פתור פנייה #%1 (%2)"
+
+#: etc/initialdata:308 html/Elements/SelectDateType:28 lib/RT/Ticket_Overlay.pm:1170
+msgid "Resolved"
+msgstr "נפתר"
+
+#: html/Search/Bulk.html:123 html/Ticket/ModifyAll.html:73 html/Ticket/Update.html:73
+msgid "Response to requestors"
+msgstr "תגובה למבקשים"
+
+#: html/Elements/ListActions:26
+msgid "Results"
+msgstr "תוצאות"
+
+#: html/Search/Elements/PickRestriction:105
+msgid "Results per page"
+msgstr "תוצאות לעמוד"
+
+#: html/Admin/Elements/ModifyUser:33 html/Admin/Users/Modify.html:100 html/User/Prefs.html:72
+msgid "Retype Password"
+msgstr "הקלד שנית:"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:613
+msgid "Right Delegated"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:303
+msgid "Right Granted"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:161
+msgid "Right Loaded"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:678 lib/RT/ACE_Overlay.pm:693
+msgid "Right could not be revoked"
+msgstr ""
+
+#: html/User/Delegation.html:64
+msgid "Right not found"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:543 lib/RT/ACE_Overlay.pm:638
+msgid "Right not loaded."
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:689
+msgid "Right revoked"
+msgstr ""
+
+#: html/Admin/Elements/UserTabs:41
+msgid "Rights"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:792
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:825
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr ""
+
+#: html/Admin/Global/GroupRights.html:51 html/Admin/Queues/GroupRights.html:52
+msgid "Roles"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr ""
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "שבת"
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyLinks.html:39 html/Ticket/ModifyPeople.html:38
+msgid "Save Changes"
+msgstr "שמור שינויים"
+
+#: NOT FOUND IN SOURCE
+msgid "Save changes"
+msgstr "שמור שינויים"
+
+#: html/Admin/Global/Scrip.html:49
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:176
+msgid "Scrip Created"
+msgstr ""
+
+#: html/Admin/Elements/EditScrips:84
+msgid "Scrip deleted"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:46 html/Admin/Elements/SystemTabs:33 html/Admin/Global/index.html:41
+msgid "Scrips"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr ""
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr ""
+
+#: html/Elements/SimpleSearch:27 html/Search/Elements/PickRestriction:126 html/Ticket/Elements/Tabs:159
+msgid "Search"
+msgstr "חיפוש"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:39
+msgid "Search for approvals"
+msgstr ""
+
+#: bin/rt-crontool:188
+msgid "Security:"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "SeeQueue"
+msgstr ""
+
+#: html/Admin/Groups/index.html:40
+msgid "Select a group"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr ""
+
+#: html/Admin/Users/index.html:25 html/Admin/Users/index.html:28
+msgid "Select a user"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:38 html/Admin/Global/CustomFields.html:36
+msgid "Select custom field"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:52 html/User/Elements/GroupTabs:50
+msgid "Select group"
+msgstr "בחר קבוצה"
+
+#: lib/RT/CustomField_Overlay.pm:422
+msgid "Select multiple values"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:419
+msgid "Select one value"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:67
+msgid "Select queue"
+msgstr ""
+
+#: html/Admin/Global/Scrip.html:37 html/Admin/Global/Scrips.html:36 html/Admin/Queues/Scrip.html:40 html/Admin/Queues/Scrips.html:50
+msgid "Select scrip"
+msgstr ""
+
+#: html/Admin/Global/Template.html:57 html/Admin/Global/Templates.html:36 html/Admin/Queues/Template.html:55 html/Admin/Queues/Templates.html:47
+msgid "Select template"
+msgstr ""
+
+#: html/Admin/Elements/UserTabs:49
+msgid "Select user"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "SelectMultiple"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectSingle"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Self Service"
+msgstr ""
+
+#: etc/initialdata:114
+msgid "Send mail to all watchers"
+msgstr ""
+
+#: etc/initialdata:110
+msgid "Send mail to all watchers as a \"comment\""
+msgstr ""
+
+#: etc/initialdata:105
+msgid "Send mail to requestors and Ccs"
+msgstr ""
+
+#: etc/initialdata:100
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr ""
+
+#: etc/initialdata:79
+msgid "Sends a message to the requestors"
+msgstr ""
+
+#: etc/initialdata:118 etc/initialdata:122
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr ""
+
+#: etc/initialdata:95
+msgid "Sends mail to the administrative Ccs"
+msgstr ""
+
+#: etc/initialdata:91
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr ""
+
+#: etc/initialdata:83 etc/initialdata:87
+msgid "Sends mail to the owner"
+msgstr ""
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "ספטמבר"
+
+#: NOT FOUND IN SOURCE
+msgid "September"
+msgstr "ספטמבר"
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show approved requests"
+msgstr "הצג בקשות שאושרו"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show basics"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show denied requests"
+msgstr "הצג בקשות שנדחו"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show details"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show pending requests"
+msgstr "הצג בקשות ממתינות"
+
+#: html/Approvals/Elements/PendingMyApproval:46
+msgid "Show requests awaiting other approvals"
+msgstr "הצג בקשות שממתינות לאישורים אחרים"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Show ticket private commentary"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "Show ticket summaries"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ShowACL"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowScrips"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ShowTemplate"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "ShowTicket"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "ShowTicketComments"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:39 html/Admin/Users/Modify.html:191 html/Admin/Users/Prefs.html:32 html/User/Prefs.html:112
+msgid "Signature"
+msgstr "חתימה"
+
+#: NOT FOUND IN SOURCE
+msgid "Signed in as %1"
+msgstr ""
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Single"
+msgstr ""
+
+#: html/Elements/Header:51
+msgid "Skip Menu"
+msgstr ""
+
+#: html/Admin/Elements/AddCustomFieldValue:29
+msgid "Sort"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Sort key"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:109
+msgid "Sort results by"
+msgstr "סדר תוצאות על פי"
+
+#: NOT FOUND IN SOURCE
+msgid "SortOrder"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Stalled"
+msgstr "מושהה"
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr ""
+
+#: html/Elements/SelectDateType:27 html/Ticket/Elements/EditDates:32 html/Ticket/Elements/ShowDates:35
+msgid "Started"
+msgstr "התחיל"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr ""
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:27 html/Ticket/Elements/ShowDates:31
+msgid "Starts"
+msgstr "מתחיל ב"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:82 html/Admin/Users/Modify.html:138 html/User/Prefs.html:94
+msgid "State"
+msgstr "מדינה"
+
+#: html/Elements/MyRequests:31 html/Elements/MyTickets:31 html/Search/Elements/PickRestriction:74 html/SelfService/Elements/MyRequests:29 html/SelfService/Update.html:31 html/Ticket/Create.html:42 html/Ticket/Elements/EditBasics:38 html/Ticket/Elements/ShowBasics:31 html/Ticket/Update.html:60 lib/RT/Ticket_Overlay.pm:1164 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "מצב"
+
+#: etc/initialdata:294
+msgid "Status Change"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:528
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:147
+msgid "Steal"
+msgstr "גנוב"
+
+#: lib/RT/Transaction_Overlay.pm:587
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "נגנב מ %1"
+
+#: html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Search/Bulk.html:126 html/Search/Elements/PickRestriction:43 html/SelfService/Create.html:57 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:32 html/Ticket/Create.html:84 html/Ticket/Elements/EditBasics:28 html/Ticket/ModifyAll.html:79 html/Ticket/Update.html:77 lib/RT/Ticket_Overlay.pm:1160 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "נושא"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:609
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr "נושא שונה ל %1"
+
+#: html/Elements/Submit:59
+msgid "Submit"
+msgstr "שלח"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:749
+msgid "Succeeded"
+msgstr "הצליח"
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "ראשון"
+
+#: lib/RT/System.pm:54
+msgid "SuperUser"
+msgstr "סופר-משתמש"
+
+#: html/User/Elements/DelegateRights:77
+msgid "System"
+msgstr "מערכת"
+
+#: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:567 lib/RT/Interface/Web.pm:791 lib/RT/Interface/Web.pm:824
+msgid "System Error"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. Right not granted."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. right not granted"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:616
+msgid "System error. Right not delegated."
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:146 lib/RT/ACE_Overlay.pm:223 lib/RT/ACE_Overlay.pm:306 lib/RT/ACE_Overlay.pm:898
+msgid "System error. Right not granted."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "System error. Unable to grant rights."
+msgstr ""
+
+#: html/Admin/Global/GroupRights.html:35 html/Admin/Groups/GroupRights.html:37 html/Admin/Queues/GroupRights.html:36
+msgid "System groups"
+msgstr ""
+
+#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53
+msgid "SystemRolegroup for internal use"
+msgstr ""
+
+#: lib/RT/CurrentUser.pm:318
+msgid "TEST_STRING"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:143
+msgid "Take"
+msgstr "קח"
+
+#: lib/RT/Transaction_Overlay.pm:573
+msgid "Taken"
+msgstr "נלקחה"
+
+#: html/Admin/Elements/EditScrip:81
+msgid "Template"
+msgstr ""
+
+#: html/Admin/Global/Template.html:91 html/Admin/Queues/Template.html:90
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr ""
+
+#: html/Admin/Elements/EditTemplates:89
+msgid "Template deleted"
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:153
+msgid "Template not found"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr ""
+
+#: lib/RT/Template_Overlay.pm:347
+msgid "Template parsed"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:49 html/Admin/Elements/SystemTabs:36 html/Admin/Global/index.html:45
+msgid "Templates"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:892
+msgid "That is already the current value"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:243
+msgid "That is not a value for this custom field"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1886
+msgid "That is the same value"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:288 lib/RT/ACE_Overlay.pm:597
+msgid "That principal already has that right"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1434
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1551
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1882
+msgid "That queue does not exist"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3210
+msgid "That ticket has unresolved dependencies"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "That user already has that right"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3020
+msgid "That user already owns that ticket"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2986
+msgid "That user does not exist"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:315
+msgid "That user is already privileged"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:336
+msgid "That user is already unprivileged"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:328
+msgid "That user is now privileged"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:349
+msgid "That user is now unprivileged"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "That user is now unprivilegedileged"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3012
+msgid "That user may not own tickets in that queue"
+msgstr ""
+
+#: lib/RT/Link_Overlay.pm:206
+msgid "That's not a numerical id"
+msgstr ""
+
+#: html/SelfService/Display.html:32 html/Ticket/Create.html:150 html/Ticket/Elements/ShowSummary:28
+msgid "The Basics"
+msgstr "מידע בסיסי"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The CC of a ticket"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:89
+msgid "The administrative CC of a ticket"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2213
+msgid "The comment has been recorded"
+msgstr ""
+
+#: bin/rt-crontool:198
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr ""
+
+#: bin/rt-commit-handler:756 bin/rt-commit-handler:766
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:895
+msgid "The new value has been set."
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The owner of a ticket"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The requestor of a ticket"
+msgstr ""
+
+#: html/Admin/Elements/EditUserComments:26
+msgid "These comments aren't generally visible to the user"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr ""
+
+#: bin/rt-crontool:189
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:251
+msgid "This transaction appears to have no content"
+msgstr ""
+
+#: html/Ticket/Elements/ShowRequestor:47
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr ""
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "חמישי"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket"
+msgstr "פנייה"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1 Jumbo update: %2"
+msgstr "פנייה מספר %1 עדכון ג'מבו: %2"
+
+#: html/Ticket/ModifyAll.html:25 html/Ticket/ModifyAll.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "פנייה מספר %1 עדכון ג'מבו: %2"
+
+#: html/Approvals/Elements/ShowDependency:46
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:587 lib/RT/Ticket_Overlay.pm:608
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr ""
+
+#: bin/rt-commit-handler:760
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr ""
+
+#: html/Search/Bulk.html:181
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr ""
+
+#: html/Ticket/History.html:25 html/Ticket/History.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket Id"
+msgstr ""
+
+#: etc/initialdata:309
+msgid "Ticket Resolved"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:63
+msgid "Ticket attachment"
+msgstr "מצורף לפנייה"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:496 lib/RT/Ticket_Overlay.pm:597
+msgid "Ticket could not be created due to an internal error"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:520
+msgid "Ticket created"
+msgstr "פנייה נוצרה"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:525
+msgid "Ticket deleted"
+msgstr "פנייה נמחקה"
+
+#: html/REST/1.0/modify:29 html/REST/1.0/update:34
+msgid "Ticket id not found"
+msgstr "מזהה פנייה לא נמצא"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket killed"
+msgstr "פנייה נמחקה"
+
+#: html/REST/1.0/modify:36 html/REST/1.0/update:41
+msgid "Ticket not found"
+msgstr "פנייה לא נמצאה"
+
+#: etc/initialdata:295
+msgid "Ticket status changed"
+msgstr "סטטוס פנייה שונה"
+
+#: html/Ticket/Update.html:39
+msgid "Ticket watchers"
+msgstr "צופי הפנייה"
+
+#: html/Elements/Tabs:47
+msgid "Tickets"
+msgstr "פניות"
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr ""
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Tickets from %1"
+msgstr ""
+
+#: html/Approvals/Elements/ShowDependency:27
+msgid "Tickets which depend on this approval:"
+msgstr ""
+
+#: html/Ticket/Create.html:157 html/Ticket/Elements/EditBasics:48
+msgid "Time Left"
+msgstr "זמן נותר"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:43
+msgid "Time Worked"
+msgstr "זמן עבודה"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "זמן נותר"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "זמן להציג"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "זמן עבודה"
+
+#: NOT FOUND IN SOURCE
+msgid "TimeLeft"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1165
+msgid "TimeWorked"
+msgstr ""
+
+#: bin/rt-commit-handler:402
+msgid "To generate a diff of this commit:"
+msgstr ""
+
+#: bin/rt-commit-handler:391
+msgid "To generate a diff of this commit:\\n"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1168
+msgid "Told"
+msgstr ""
+
+#: etc/initialdata:237
+msgid "Transaction"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:640
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:89
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:699
+msgid "Transactions are immutable"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr ""
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "שלישי"
+
+#: html/Admin/Elements/EditCustomField:44 html/Ticket/Elements/AddWatchers:33 html/Ticket/Elements/AddWatchers:44 html/Ticket/Elements/AddWatchers:54 lib/RT/Ticket_Overlay.pm:1166 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "סוג"
+
+#: lib/RT/ScripCondition_Overlay.pm:104
+msgid "Unimplemented"
+msgstr "לא מייושם"
+
+#: html/Admin/Users/Modify.html:68
+msgid "Unix login"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:62
+msgid "UnixUsername"
+msgstr ""
+
+#: lib/RT/Attachment_Overlay.pm:265
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr ""
+
+#: html/Elements/SelectResultsPerPage:37
+msgid "Unlimited"
+msgstr "לא מוגבל"
+
+#: etc/initialdata:32
+msgid "Unprivileged"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:569
+msgid "Untaken"
+msgstr ""
+
+#: html/Elements/MyTickets:64 html/Search/Bulk.html:33
+msgid "Update"
+msgstr "עדכן"
+
+#: html/Admin/Users/Prefs.html:62
+msgid "Update ID"
+msgstr ""
+
+#: html/Search/Bulk.html:120 html/Ticket/ModifyAll.html:66 html/Ticket/Update.html:67
+msgid "Update Type"
+msgstr "סוג עדכון"
+
+#: html/Search/Listing.html:61
+msgid "Update all these tickets at once"
+msgstr "עדכן את כל הפניות לעיל בבת אחת"
+
+#: html/Admin/Users/Prefs.html:49
+msgid "Update email"
+msgstr "עדכן אי-מייל"
+
+#: html/Admin/Users/Prefs.html:55
+msgid "Update name"
+msgstr "עדכן שם"
+
+#: lib/RT/Interface/Web.pm:409
+msgid "Update not recorded."
+msgstr ""
+
+#: html/Search/Bulk.html:81
+msgid "Update selected tickets"
+msgstr "עדכן פניות נבחרות"
+
+#: html/Admin/Users/Prefs.html:36
+msgid "Update signature"
+msgstr "עדכן חתימה"
+
+#: html/Ticket/ModifyAll.html:63
+msgid "Update ticket"
+msgstr "עדכן פנייה"
+
+#: NOT FOUND IN SOURCE
+msgid "Update ticket # %1"
+msgstr ""
+
+#: html/SelfService/Update.html:25 html/SelfService/Update.html:47
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr ""
+
+#: html/Ticket/Update.html:135
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:407
+msgid "Update type was neither correspondence nor comment."
+msgstr ""
+
+#: html/Elements/SelectDateType:33 html/Ticket/Elements/ShowDates:51 lib/RT/Ticket_Overlay.pm:1169
+msgid "Updated"
+msgstr "עודכן"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr ""
+
+#: etc/initialdata:125 etc/initialdata:191
+msgid "User Defined"
+msgstr ""
+
+#: html/Admin/Users/Prefs.html:59
+msgid "User ID"
+msgstr "מזהה המשתמש"
+
+#: html/Elements/SelectUsers:26
+msgid "User Id"
+msgstr "מזהה המשתמש"
+
+#: html/Admin/Elements/GroupTabs:47 html/Admin/Elements/QueueTabs:60 html/Admin/Elements/SystemTabs:47 html/Admin/Global/index.html:59
+msgid "User Rights"
+msgstr "זכויות המשתמש"
+
+#: html/Admin/Users/Modify.html:226
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:262
+msgid "User created"
+msgstr ""
+
+#: html/Admin/Global/GroupRights.html:67 html/Admin/Groups/GroupRights.html:54 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr ""
+
+#: html/Admin/Users/Prefs.html:25 html/Admin/Users/Prefs.html:29
+msgid "User view"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:48 html/Elements/Login:51 html/Ticket/Elements/AddWatchers:35
+msgid "Username"
+msgstr "שם משתמש"
+
+#: html/Admin/Elements/SelectNewGroupMembers:26 html/Admin/Elements/Tabs:32 html/Admin/Groups/Members.html:55 html/Admin/Queues/People.html:68 html/Admin/index.html:29 html/User/Groups/Members.html:58
+msgid "Users"
+msgstr "משתמשים"
+
+#: html/Admin/Users/index.html:65
+msgid "Users matching search criteria"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:51
+msgid "ValueOfQueue"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomField:57
+msgid "Values"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "VrijevormEnkele"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Watch"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "WatchAsAdminCc"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Watcher loaded"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:42
+msgid "Watchers"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:56
+msgid "WebEncoding"
+msgstr ""
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "רביעי"
+
+#: etc/upgrade/2.1.71:161
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr ""
+
+#: etc/upgrade/2.1.71:135
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr ""
+
+#: etc/initialdata:138
+msgid "When a ticket is created"
+msgstr ""
+
+#: etc/upgrade/2.1.71:79
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr ""
+
+#: etc/initialdata:143
+msgid "When anything happens"
+msgstr "בכל פעם שדבר כלשהוא קורה"
+
+#: etc/initialdata:184
+msgid "Whenever a ticket is resolved"
+msgstr "בכל פעם שפנייה נסגרת"
+
+#: etc/initialdata:170
+msgid "Whenever a ticket's owner changes"
+msgstr "בכל פעם שבעלי הפנייה משתנה"
+
+#: etc/initialdata:178
+msgid "Whenever a ticket's queue changes"
+msgstr "בכל מצב שתור הפנייה משתנה"
+
+#: etc/initialdata:162
+msgid "Whenever a ticket's status changes"
+msgstr "בכל פעם שמצב הפנייה משתנה"
+
+#: etc/initialdata:192
+msgid "Whenever a user-defined condition occurs"
+msgstr "בכל פעם שמצב מוגדר על ידי משתמש קורה"
+
+#: etc/initialdata:156
+msgid "Whenever comments come in"
+msgstr "בכל פעם שהערה מגיעה ב"
+
+#: etc/initialdata:149
+msgid "Whenever correspondence comes in"
+msgstr "בכל פעם שתכתובת מגיעה ב"
+
+#: html/Admin/Users/Modify.html:164 html/User/Prefs.html:52
+msgid "Work"
+msgstr "עבודה"
+
+#: html/Admin/Elements/ModifyUser:70
+msgid "WorkPhone"
+msgstr "טלפון בעבודה"
+
+#: html/Ticket/Elements/ShowBasics:35 html/Ticket/Update.html:65
+msgid "Worked"
+msgstr "זמן טיפול"
+
+#: lib/RT/Ticket_Overlay.pm:3123
+msgid "You already own this ticket"
+msgstr "אתה כבר הבעלים של פנייה זו"
+
+#: html/autohandler:108
+msgid "You are not an authorized user"
+msgstr "אינך משתמש מורשה"
+
+#: lib/RT/Ticket_Overlay.pm:2998
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "אתה יכול להציב פניה רק אם אתה הבעלים שלה, או שאין לה בעלים"
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr "אין לך הרשאה כדי לראות את פנייה זו.\\n"
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "מצאת %1 פניות בתור %2"
+
+#: html/NoAuth/Logout.html:31
+msgid "You have been logged out of RT."
+msgstr "התנתקת מהמערכת."
+
+#: html/SelfService/Display.html:78
+msgid "You have no permission to create tickets in that queue."
+msgstr "אין לך הרשאות ליצור פניות בתור זה."
+
+#: lib/RT/Ticket_Overlay.pm:1895
+msgid "You may not create requests in that queue."
+msgstr "אינך מורשה ליצור פניות בתור זה."
+
+#: html/NoAuth/Logout.html:36
+msgid "You're welcome to login again"
+msgstr "הנך מוזמן להיכנס שנית"
+
+#: NOT FOUND IN SOURCE
+msgid "Your %1 requests"
+msgstr "%1 הבקשות שלך"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr "מנהל המערכת לא הגדיר את כתובות הדואר שמפעילות את התוכנה כמו שצריך"
+
+#: etc/initialdata:435 etc/upgrade/2.1.71:146
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr "בקשתך אושרה על ידי %1. ייתכן שאישורים נוספים עדיין ממתינים."
+
+#: etc/initialdata:469 etc/upgrade/2.1.71:180
+msgid "Your request has been approved."
+msgstr "בקשתך אושרה."
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr "בקשתך נדחתה"
+
+#: etc/initialdata:390 etc/upgrade/2.1.71:101
+msgid "Your request was rejected."
+msgstr "בקשתך נדחתה."
+
+#: html/autohandler:127
+msgid "Your username or password is incorrect"
+msgstr "שם המשתמש ו/או הסיסמא אינם נכונים"
+
+#: html/Admin/Elements/ModifyUser:84 html/Admin/Users/Modify.html:144 html/User/Prefs.html:96
+msgid "Zip"
+msgstr "מיקוד"
+
+#: NOT FOUND IN SOURCE
+msgid "[no subject]"
+msgstr "[ללא נושא]"
+
+#: html/User/Elements/DelegateRights:59
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "שהוענק ל%1"
+
+#: html/SelfService/Closed.html:28
+msgid "closed"
+msgstr "סגור"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:34
+msgid "contains"
+msgstr "מכיל"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content"
+msgstr "תוכן"
+
+#: html/Elements/SelectAttachmentField:27
+msgid "content-type"
+msgstr "סוג התוכן"
+
+#: lib/RT/Ticket_Overlay.pm:2282
+msgid "correspondence (probably) not sent"
+msgstr "התכתבות (כנראה) לא נשלחה"
+
+#: lib/RT/Ticket_Overlay.pm:2292
+msgid "correspondence sent"
+msgstr "התכתבות נשלחה"
+
+#: html/Admin/Elements/ModifyQueue:63 html/Admin/Queues/Modify.html:77 lib/RT/Date.pm:319
+msgid "days"
+msgstr "ימים"
+
+#: NOT FOUND IN SOURCE
+msgid "dead"
+msgstr ""
+
+#: html/Search/Listing.html:75
+msgid "delete"
+msgstr "מחק"
+
+#: lib/RT/Queue_Overlay.pm:63
+msgid "deleted"
+msgstr "מחוק"
+
+#: html/Search/Elements/PickRestriction:68
+msgid "does not match"
+msgstr "לא מכיל"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:35
+msgid "doesn't contain"
+msgstr "לא מכיל"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "equal to"
+msgstr "שווה ל"
+
+#: NOT FOUND IN SOURCE
+msgid "false"
+msgstr ""
+
+#: html/Elements/SelectAttachmentField:28
+msgid "filename"
+msgstr "שם קובץ"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "greater than"
+msgstr "גדול מ"
+
+#: lib/RT/Group_Overlay.pm:194
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "קבוצה %1"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "שעות"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr "מזהה"
+
+#: html/Elements/SelectBoolean:32 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88
+msgid "is"
+msgstr "הוא"
+
+#: html/Elements/SelectBoolean:36 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:37 html/Search/Elements/PickRestriction:48 html/Search/Elements/PickRestriction:77 html/Search/Elements/PickRestriction:89
+msgid "isn't"
+msgstr "הוא לא"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "less than"
+msgstr "פחות מ"
+
+#: html/Search/Elements/PickRestriction:67
+msgid "matches"
+msgstr "מכיל"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "דקות"
+
+#: html/Ticket/Update.html:66
+msgid "minutes"
+msgstr "דקות"
+
+#: bin/rt-commit-handler:765
+msgid "modifications\\n\\n"
+msgstr ""
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "חודשים"
+
+#: lib/RT/Queue_Overlay.pm:58
+msgid "new"
+msgstr "חדש"
+
+#: html/Admin/Elements/EditScrips:43
+msgid "no value"
+msgstr "אין ערך"
+
+#: html/Ticket/Elements/EditWatchers:28
+msgid "none"
+msgstr "אין"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "not equal to"
+msgstr "לא שווה ל"
+
+#: NOT FOUND IN SOURCE
+msgid "notlike"
+msgstr ""
+
+#: html/SelfService/Elements/MyRequests:61 lib/RT/Queue_Overlay.pm:59
+msgid "open"
+msgstr "פתוח"
+
+#: lib/RT/Group_Overlay.pm:199
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:207
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "rejected"
+msgstr "נדחה"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "resolved"
+msgstr "פתור"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:60
+msgid "stalled"
+msgstr "מושהה"
+
+#: lib/RT/Group_Overlay.pm:202
+#. ($self->Type)
+msgid "system %1"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:213
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr ""
+
+#: html/Elements/Error:42 html/SelfService/Error.html:42
+msgid "the calling component did not specify why"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:210
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "true"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:216
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "undescripbed group %1"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:191
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr ""
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr ""
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr ""
diff --git a/rt/lib/RT/I18N/i_default.pm b/rt/lib/RT/I18N/i_default.pm
new file mode 100644 (file)
index 0000000..1547026
--- /dev/null
@@ -0,0 +1,86 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+package RT::I18N::i_default;
+
+use strict;
+use vars qw/@ISA/;
+@ISA = qw(RT::I18N);
+
+eval "require RT::I18N::i_default_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/I18N/i_default_Vendor.pm});
+eval "require RT::I18N::i_default_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/I18N/i_default_Local.pm});
+
+1;
+
+__END__
+
+This class just zero-derives from the project base class, which
+is English for this project.  i-default is "English at least".  It
+wouldn't be a bad idea to make our i-default messages be English
+plus, say, French -- i-default is meant to /contain/ English, not
+be /just/ English.  If you have all your English messages in
+Whatever::en and all your French messages in Whatever::fr, it
+would be straightforward to define Whatever::i_default's as a subclass
+of Whatever::en, but for every case where a key gets you a string
+(as opposed to a coderef) from %Whatever::en::Lexicon and
+%Whatever::fr::Lexicon, you could make %Whatever::i_default::Lexicon 
+be the concatenation of them both.  So: "file '[_1]' not found.\n" and
+"fichier '[_1]' non trouve\n" could make for an
+%Whatever::i_default::Lexicon entry of
+"file '[_1]' not found\nfichier '[_1]' non trouve.\n".
+
+There may be entries, however, where that is undesirable.
+And in any case, it's not feasable once you have an _AUTO lexicon
+in the mix, as wo do here.
+
+
+
+RFC 2277 says: 
+
+4.5.  Default Language
+
+   When human-readable text must be presented in a context where the
+   sender has no knowledge of the recipient's language preferences (such
+   as login failures or E-mailed warnings, or prior to language
+   negotiation), text SHOULD be presented in Default Language.
+
+   Default Language is assigned the tag "i-default" according to the
+   procedures of RFC 1766. It is not a specific language, but rather
+   identifies the condition where the language preferences of the user
+   cannot be established.
+
+   Messages in Default Language MUST be understandable by an English-
+   speaking person, since English is the language which, worldwide, the
+   greatest number of people will be able to get adequate help in
+   interpreting when working with computers.
+
+   Note that negotiating English is NOT the same as Default Language;
+   Default Language is an emergency measure in otherwise unmanageable
+   situations.
+
+   In many cases, using only English text is reasonable; in some cases,
+   the English text may be augumented by text in other languages.
+
+
diff --git a/rt/lib/RT/I18N/ja.po b/rt/lib/RT/I18N/ja.po
new file mode 100644 (file)
index 0000000..c0401f8
--- /dev/null
@@ -0,0 +1,4822 @@
+# Japanese translation by Interactive Artists LLC 
+# 0.1 2002 08 15
+msgid ""
+msgstr ""
+"Project-Id-Version: RT 2.1.x\n"
+"POT-Creation-Date: 2002-05-02 11:36+0800\n"
+"PO-Revision-Date: 2002-05-13 02:00+0800\n"
+"Last-Translator: Jesse Vincent <jesse@bestpractical.com>\n"
+"Language-Team: rt-devel <rt-devel@lists.fsck.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28
+msgid "#"
+msgstr "#"
+
+#: html/Admin/Queues/Scrip.html:55
+#. ($QueueObj->id)
+msgid "#%1"
+msgstr ""
+
+#: html/Approvals/Elements/ShowDependency:50 html/Ticket/Display.html:26 html/Ticket/Display.html:30
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr ""
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr ""
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr "%1 %2 %3 %4:%5:%6 %7"
+
+#: lib/RT/Ticket_Overlay.pm:3438 lib/RT/Transaction_Overlay.pm:559 lib/RT/Transaction_Overlay.pm:601
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 added"
+msgstr ""
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 %2 ago"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3444 lib/RT/Transaction_Overlay.pm:566
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 changed to %3"
+msgstr "%3に変更された%1 %2 "
+
+#: lib/RT/Ticket_Overlay.pm:3441 lib/RT/Transaction_Overlay.pm:562 lib/RT/Transaction_Overlay.pm:607
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 deleted"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 %2 of group %3"
+msgstr ""
+
+#: html/Admin/Elements/EditScrips:44 html/Admin/Elements/ListGlobalScrips:28
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 with template %3"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 this ticket\\n"
+msgstr "%1 (%2) %3 このチケット\\n"
+
+#: html/Search/Listing.html:57
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr ""
+
+#: bin/rt-crontool:169 bin/rt-crontool:176 bin/rt-crontool:182
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - An argument to pass to %2"
+msgstr ""
+
+#: bin/rt-crontool:185
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr ""
+
+#: bin/rt-crontool:179
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr ""
+
+#: bin/rt-crontool:173
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr ""
+
+#: bin/rt-crontool:166
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr ""
+
+#: lib/RT/ScripAction_Overlay.pm:122
+#. ($self->Id)
+msgid "%1 ScripAction loaded"
+msgstr "%1スクリプトアクションロードしました"
+
+#: lib/RT/Ticket_Overlay.pm:3471
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 added as a value for %2"
+msgstr "%2と同じバリューの%1が追加されました"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on"
+msgstr "%1aliasesを動かすためにチケットIDが必要です"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on "
+msgstr "%1aliasesを動かすためにチケットIDが必要です "
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on (from %2) %3"
+msgstr "%1aliasesを動かすためにチケットIDが必要です(%2から) %3"
+
+#: lib/RT/Link_Overlay.pm:117 lib/RT/Link_Overlay.pm:124
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 appears to be a local object, but can't be found in the database"
+msgstr ""
+
+#: html/Ticket/Elements/ShowDates:52 lib/RT/Transaction_Overlay.pm:483
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 by %2"
+msgstr "%2による%1"
+
+#: lib/RT/Transaction_Overlay.pm:537 lib/RT/Transaction_Overlay.pm:626 lib/RT/Transaction_Overlay.pm:635 lib/RT/Transaction_Overlay.pm:638
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 changed from %2 to %3"
+msgstr "%1は%2から%3に変更されました"
+
+#: lib/RT/Interface/Web.pm:857
+msgid "%1 could not be set to %2."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr "%1はトランザクションをはじめることができませんでした(%2)\\n"
+
+#: lib/RT/Ticket_Overlay.pm:2813
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr "%1は分解するステータスを設定できませんでした。RTのデータベースに一貫性がない可能性があります。"
+
+#: html/Elements/MyTickets:25
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr ""
+
+#: html/Elements/MyRequests:25
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr ""
+
+#: bin/rt-crontool:161
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr "%1はこのキューでは%2ではありません"
+
+#: lib/RT/Ticket_Overlay.pm:1570
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr "%1はこのチケットでは%2ではありません"
+
+#: lib/RT/Ticket_Overlay.pm:3527
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr "%1はカスタムフィールド%2のバリューはありません"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr "%1は有効なキューIDではありません。"
+
+#: html/Ticket/Elements/ShowBasics:36
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr "%1分"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr "%1表示されません"
+
+#: html/User/Elements/DelegateRights:76
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr "%1 成功しました\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr "%1タイプは$MessageIdIDでは不明です"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr "%1タイプは%2では不明です"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 was created without a CurrentUser\\n"
+msgstr ""
+
+#: lib/RT/Action/ResolveMembers.pm:42
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr "%1は分解されたグループチケットのすべてのメンバーを分解します。"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr "%1がもしリンクされたリクエストの従属者(もしくはメンバー)であると、[ローカル]ベースを行き詰まらせることになります。"
+
+#: lib/RT/Transaction_Overlay.pm:435
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr "%1:アタッチメントが特定できません"
+
+#: html/Ticket/Elements/ShowTransaction:102
+#. ($size)
+msgid "%1b"
+msgstr ""
+
+#: html/Ticket/Elements/ShowTransaction:99
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1140
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr "%1'はステータスに無効名バリューです"
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr "%1' アクションを認識できませんでした。"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete group member)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr "(スクリプトを削除するためのチェックボックス)"
+
+#: html/Admin/Elements/EditQueueWatchers:29 html/Admin/Elements/EditScrips:35 html/Admin/Elements/EditTemplates:36 html/Admin/Groups/Members.html:52 html/Ticket/Elements/EditLinks:33 html/Ticket/Elements/EditPeople:46 html/User/Groups/Members.html:55
+msgid "(Check box to delete)"
+msgstr "(削除のためのチェックボックス)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check boxes to delete)"
+msgstr ""
+
+#: html/Ticket/Create.html:178
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr "(チケットIDまたはURLsを空欄で区切って入力してください)"
+
+#: html/Admin/Queues/Modify.html:54 html/Admin/Queues/Modify.html:60
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(No Value)"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:33 html/Admin/Elements/ListGlobalCustomFields:32
+msgid "(No custom fields)"
+msgstr ""
+
+#: html/Admin/Groups/Members.html:50 html/User/Groups/Members.html:53
+msgid "(No members)"
+msgstr "(メンバーなし)"
+
+#: html/Admin/Elements/EditScrips:32 html/Admin/Elements/ListGlobalScrips:32
+msgid "(No scrips)"
+msgstr "(スクリプトなし)"
+
+#: html/Admin/Elements/EditTemplates:31
+msgid "(No templates)"
+msgstr ""
+
+#: html/Ticket/Update.html:85
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Eメールアドレスにおけるカンマで区切られたリストへの正確なアップデートのブラインドコピーを送る。今後のアップデートを誰が受信するかは<b>変更できません</b>)"
+
+#: html/Ticket/Create.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr ""
+
+#: html/Ticket/Update.html:81
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Eメールアドレスにおけるカンマで区切られたリストへの正確なアップデートのコピーを送る。今後のアップデートを誰が受信するかは<b>変更できません</b>)"
+
+#: html/Ticket/Create.html:69
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr ""
+
+#: html/Admin/Groups/index.html:33 html/User/Groups/index.html:33
+msgid "(empty)"
+msgstr "(空)"
+
+#: html/Admin/Users/index.html:39
+msgid "(no name listed)"
+msgstr ""
+
+#: html/Elements/MyRequests:43 html/Elements/MyTickets:45
+msgid "(no subject)"
+msgstr "(サブジェクトなし)"
+
+#: html/Admin/Elements/SelectRights:48 html/Elements/SelectCustomFieldValue:30 html/Ticket/Elements/EditCustomField:59 html/Ticket/Elements/ShowCustomFields:36 lib/RT/Transaction_Overlay.pm:536
+msgid "(no value)"
+msgstr "(バリューなし)"
+
+#: html/Ticket/Elements/EditLinks:116
+msgid "(only one ticket)"
+msgstr "(ひとつのチケットのみ)"
+
+#: html/Elements/MyRequests:52 html/Elements/MyTickets:55
+msgid "(pending approval)"
+msgstr ""
+
+#: html/Elements/MyRequests:54 html/Elements/MyTickets:57
+msgid "(pending other tickets)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(requestor's group)"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:50
+msgid "(required)"
+msgstr "(必要です)"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "(untitled)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I own..."
+msgstr "私が所有している25の最も重要な優先権"
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I requested..."
+msgstr "私がリクエストした25の最も重要な優先権"
+
+#: html/Ticket/Elements/ShowBasics:32
+msgid "<% $Ticket->Status%>"
+msgstr ""
+
+#: html/Elements/SelectTicketTypes:27
+msgid "<% $_ %>"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:26
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"新しいチケット\">&nbsp;%1"
+
+#: etc/initialdata:203
+msgid "A blank template"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Deleted"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Loaded"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be deleted"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be found"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:157 lib/RT/Principal_Overlay.pm:181
+msgid "ACE not found"
+msgstr "エースはみつかりません"
+
+#: lib/RT/ACE_Overlay.pm:831
+msgid "ACEs can only be created and deleted."
+msgstr "エースは作成、削除のみです。"
+
+#: bin/rt-commit-handler:755
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr "意図的でないチケットの修正を防ぐために強制終了します。\\n"
+
+#: html/User/Elements/Tabs:32
+msgid "About me"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:80
+msgid "Access control"
+msgstr "アクセスコントロール"
+
+#: html/Admin/Elements/EditScrip:57
+msgid "Action"
+msgstr "アクション"
+
+#: lib/RT/Scrip_Overlay.pm:147
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr "アクション%1は見つかりません"
+
+#: bin/rt-crontool:123
+msgid "Action committed."
+msgstr ""
+
+#: bin/rt-crontool:119
+msgid "Action prepared..."
+msgstr ""
+
+#: html/Search/Bulk.html:92
+msgid "Add AdminCc"
+msgstr "管理Ccを追加する"
+
+#: html/Search/Bulk.html:90
+msgid "Add Cc"
+msgstr "Ccを追加する"
+
+#: html/Ticket/Create.html:114 html/Ticket/Update.html:100
+msgid "Add More Files"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add Next State"
+msgstr ""
+
+#: html/Search/Bulk.html:88
+msgid "Add Requestor"
+msgstr "リクエストする人をを追加する"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip to this queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip which will apply to all queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a keyword selection to this queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr "新しいグローバルスクリプトを追加する"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr "このキューにスクリプトを追加する"
+
+#: html/Admin/Global/Scrip.html:55
+msgid "Add a scrip which will apply to all queues"
+msgstr "すべてのキューに適応するスクリプトを追加する"
+
+#: html/Search/Bulk.html:118
+msgid "Add comments or replies to selected tickets"
+msgstr "選択されたチケットへのコメントまたは返事を追加する"
+
+#: html/Admin/Groups/Members.html:42 html/User/Groups/Members.html:39
+msgid "Add members"
+msgstr "メンバーを追加する"
+
+#: html/Admin/Queues/People.html:66 html/Ticket/Elements/AddWatchers:28
+msgid "Add new watchers"
+msgstr "新しいウォッチャーを追加する"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr "このキューに%1の責任者を追加しました"
+
+#: lib/RT/Ticket_Overlay.pm:1454
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr "このチケットに%1の責任者を追加しました"
+
+#: html/Admin/Elements/ModifyUser:76 html/Admin/Users/Modify.html:122 html/User/Prefs.html:88
+msgid "Address1"
+msgstr "住所1"
+
+#: html/Admin/Elements/ModifyUser:78 html/Admin/Users/Modify.html:127 html/User/Prefs.html:90
+msgid "Address2"
+msgstr "住所2"
+
+#: html/Ticket/Create.html:74
+msgid "Admin Cc"
+msgstr "管理Cc"
+
+#: etc/initialdata:274
+msgid "Admin Comment"
+msgstr ""
+
+#: etc/initialdata:256
+msgid "Admin Correspondence"
+msgstr ""
+
+#: html/Admin/Queues/index.html:25 html/Admin/Queues/index.html:28
+msgid "Admin queues"
+msgstr "管理キュー"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr "管理ユーザー"
+
+#: html/Admin/Global/index.html:26 html/Admin/Global/index.html:28
+msgid "Admin/Global configuration"
+msgstr "管理/グローバル設定"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr "管理/グループ"
+
+#: html/Admin/Queues/Modify.html:25 html/Admin/Queues/Modify.html:29
+msgid "Admin/Queue/Basics"
+msgstr "管理/キュー/基本"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr ""
+
+#: etc/initialdata:56 html/Ticket/Elements/ShowPeople:39 html/Ticket/Update.html:50 lib/RT/ACE_Overlay.pm:89
+msgid "AdminCc"
+msgstr "管理Cc"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "AdminCustomFields"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "AdminGroup"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "AdminGroupMembership"
+msgstr ""
+
+#: lib/RT/System.pm:59
+msgid "AdminOwnPersonalGroups"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "AdminQueue"
+msgstr ""
+
+#: lib/RT/System.pm:60
+msgid "AdminUsers"
+msgstr ""
+
+#: html/Admin/Queues/People.html:48 html/Ticket/Elements/EditPeople:54
+msgid "Administrative Cc"
+msgstr "管理者Cc"
+
+#: NOT FOUND IN SOURCE
+msgid "Admins"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr "絞込み検索"
+
+#: html/Elements/SelectDateRelation:36
+msgid "After"
+msgstr "後"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Alias"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Alias for"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:96
+msgid "All Custom Fields"
+msgstr ""
+
+#: html/Admin/Queues/index.html:53
+msgid "All Queues"
+msgstr "すべてのキュー"
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr ""
+
+#: html/Elements/Tabs:58
+msgid "Approval"
+msgstr ""
+
+#: html/Approvals/Display.html:46 html/Approvals/Elements/Approve:27 html/Approvals/Elements/ShowDependency:42 html/Approvals/index.html:65
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr ""
+
+#: html/Approvals/index.html:54
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr ""
+
+#: html/Approvals/index.html:52
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Details"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Approval diagram"
+msgstr ""
+
+#: html/Approvals/Elements/Approve:45
+msgid "Approve"
+msgstr ""
+
+#: etc/initialdata:431 etc/upgrade/2.1.71:148
+msgid "Approver's notes: %1"
+msgstr ""
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "四月"
+
+#: NOT FOUND IN SOURCE
+msgid "April"
+msgstr ""
+
+#: html/Elements/SelectSortOrder:35
+msgid "Ascending"
+msgstr "昇順"
+
+#: html/Search/Bulk.html:127 html/SelfService/Update.html:36 html/Ticket/ModifyAll.html:83 html/Ticket/Update.html:100
+msgid "Attach"
+msgstr "添付"
+
+#: html/SelfService/Create.html:67 html/Ticket/Create.html:110
+msgid "Attach file"
+msgstr "添付ファイル"
+
+#: html/Ticket/Create.html:98 html/Ticket/Update.html:89
+msgid "Attached file"
+msgstr ""
+
+#: html/SelfService/Attachment/dhandler:36
+msgid "Attachment '%1' could not be loaded"
+msgstr "添付ファイル%1は見つかりません"
+
+#: lib/RT/Transaction_Overlay.pm:443
+msgid "Attachment created"
+msgstr "添付ファイルが作成されました"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "添付ファイル名"
+
+#: html/Ticket/Elements/ShowAttachments:26
+msgid "Attachments"
+msgstr "添付ファイル"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "八月"
+
+#: NOT FOUND IN SOURCE
+msgid "August"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:66
+msgid "AuthSystem"
+msgstr "自動システム"
+
+#: etc/initialdata:206
+msgid "Autoreply"
+msgstr ""
+
+#: etc/initialdata:72
+msgid "Autoreply To Requestors"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr "悪いPGP署名: %1\\n"
+
+#: html/SelfService/Attachment/dhandler:40
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr "悪い添付IDです。添付ファイルが見つかりません'%1'\\n"
+
+#: bin/rt-commit-handler:827
+#. ($val)
+msgid "Bad data in %1"
+msgstr "%1の悪いデータです"
+
+#: html/SelfService/Attachment/dhandler:43
+#. ($trans, $AttachmentObj->TransactionId())
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr "添付ファイルにとって悪いトランザクションナンバーです。%1は%2\\nのはずです"
+
+#: html/Admin/Elements/GroupTabs:39 html/Admin/Elements/QueueTabs:39 html/Admin/Elements/UserTabs:38 html/Ticket/Elements/Tabs:90 html/User/Elements/GroupTabs:38
+msgid "Basics"
+msgstr "基本"
+
+#: html/Ticket/Update.html:83
+msgid "Bcc"
+msgstr "Bcc"
+
+#: html/Admin/Elements/EditScrip:88 html/Admin/Global/GroupRights.html:85 html/Admin/Global/Template.html:46 html/Admin/Global/UserRights.html:54 html/Admin/Groups/GroupRights.html:73 html/Admin/Groups/Members.html:81 html/Admin/Groups/Modify.html:56 html/Admin/Groups/UserRights.html:55 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:45 html/Admin/Queues/UserRights.html:54 html/User/Groups/Modify.html:56
+msgid "Be sure to save your changes"
+msgstr "本当に変更を保存してもよろしいですか"
+
+#: html/Elements/SelectDateRelation:34 lib/RT/CurrentUser.pm:322
+msgid "Before"
+msgstr "前"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin Approval"
+msgstr ""
+
+#: etc/initialdata:202
+msgid "Blank"
+msgstr ""
+
+#: html/Search/Listing.html:79
+msgid "Bookmarkable URL for this search"
+msgstr "この検索にブックマークのできるURLです"
+
+#: html/Ticket/Elements/ShowHistory:39 html/Ticket/Elements/ShowHistory:45
+msgid "Brief headers"
+msgstr "短いヘッダー"
+
+#: html/Search/Bulk.html:25 html/Search/Bulk.html:26
+msgid "Bulk ticket update"
+msgstr "チケットの一括アップデート"
+
+#: lib/RT/User_Overlay.pm:1331
+msgid "Can not modify system users"
+msgstr "システムユーザーを修正できません"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Can this principal see this queue"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:144
+msgid "Can't add a custom field value without a name"
+msgstr "氏名なしにカスタムフィールドバリューの追加はできません"
+
+#: lib/RT/Link_Overlay.pm:132
+msgid "Can't link a ticket to itself"
+msgstr "チケット自体にはリンクできません"
+
+#: lib/RT/Ticket_Overlay.pm:2787
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr "すでに結合したチケットには結合できません。このエラーは決して出さないでください"
+
+#: lib/RT/Ticket_Overlay.pm:2605 lib/RT/Ticket_Overlay.pm:2674
+msgid "Can't specifiy both base and target"
+msgstr "ベースとターゲットを特定できません"
+
+#: html/autohandler:112
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr "ユーザー: %1を作成できません"
+
+#: etc/initialdata:50 html/Admin/Queues/People.html:44 html/SelfService/Create.html:51 html/SelfService/Display.html:50 html/Ticket/Create.html:64 html/Ticket/Elements/EditPeople:51 html/Ticket/Elements/ShowPeople:35 html/Ticket/Update.html:45 html/Ticket/Update.html:78 lib/RT/ACE_Overlay.pm:88
+msgid "Cc"
+msgstr "Cc"
+
+#: html/SelfService/Prefs.html:31
+msgid "Change password"
+msgstr "パスワードを変更する"
+
+#: html/Ticket/Create.html:101 html/Ticket/Update.html:92
+msgid "Check box to delete"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:31
+msgid "Check box to revoke right"
+msgstr "権利を無効にするチェックボックス"
+
+#: html/Ticket/Create.html:183 html/Ticket/Elements/EditLinks:131 html/Ticket/Elements/EditLinks:69 html/Ticket/Elements/ShowLinks:51
+msgid "Children"
+msgstr "子供"
+
+#: html/Admin/Elements/ModifyUser:80 html/Admin/Users/Modify.html:132 html/User/Prefs.html:92
+msgid "City"
+msgstr "町"
+
+#: html/Ticket/Elements/ShowDates:47
+msgid "Closed"
+msgstr ""
+
+#: html/SelfService/Elements/Tabs:60
+msgid "Closed requests"
+msgstr "終了したリクエストです"
+
+#: NOT FOUND IN SOURCE
+msgid "Code"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr "理解していないコマンド!\\n"
+
+#: html/Ticket/Elements/ShowTransaction:179 html/Ticket/Elements/Tabs:153
+msgid "Comment"
+msgstr "コメント"
+
+#: html/Admin/Elements/ModifyQueue:45 html/Admin/Queues/Modify.html:58
+msgid "Comment Address"
+msgstr "コメントアドレス"
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr "記録されていないコメント"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Comment on tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "CommentOnTicket"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:35
+msgid "Comments"
+msgstr "コメント"
+
+#: html/Ticket/ModifyAll.html:70 html/Ticket/Update.html:70
+msgid "Comments (Not sent to requestors)"
+msgstr "コメント(リクエスとした人には送信されません)"
+
+#: html/Search/Bulk.html:122
+msgid "Comments (not sent to requestors)"
+msgstr "コメント(リクエスとした人には送信されません)"
+
+#: html/Elements/ViewUser:27
+#. ($name)
+msgid "Comments about %1"
+msgstr "%1についてのコメント"
+
+#: html/Admin/Users/Modify.html:185 html/Ticket/Elements/ShowRequestor:44
+msgid "Comments about this user"
+msgstr "このユーザーについてのコメント"
+
+#: lib/RT/Transaction_Overlay.pm:545
+msgid "Comments added"
+msgstr "コメントが追加されました"
+
+#: lib/RT/Action/Generic.pm:140
+msgid "Commit Stubbed"
+msgstr "コメントが短くされました"
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr "コンパイル規制"
+
+#: html/Admin/Elements/EditScrip:41
+msgid "Condition"
+msgstr "コンディション"
+
+#: bin/rt-crontool:109
+msgid "Condition matches..."
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:160
+msgid "Condition not found"
+msgstr "コンディションが見つかりません"
+
+#: html/Elements/Tabs:52
+msgid "Configuration"
+msgstr "設定"
+
+#: html/SelfService/Prefs.html:33
+msgid "Confirm"
+msgstr "確認"
+
+#: html/Admin/Elements/ModifyUser:60
+msgid "ContactInfoSystem"
+msgstr "コンタクト情報"
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr "コンタクトされた日にち'%1'を解析できませんでした"
+
+#: html/Admin/Elements/ModifyTemplate:44 html/Ticket/ModifyAll.html:87
+msgid "Content"
+msgstr "情報"
+
+#: NOT FOUND IN SOURCE
+msgid "Coould not create group"
+msgstr ""
+
+#: etc/initialdata:266
+msgid "Correspondence"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:39 html/Admin/Queues/Modify.html:51
+msgid "Correspondence Address"
+msgstr "メールアドレス"
+
+#: lib/RT/Transaction_Overlay.pm:541
+msgid "Correspondence added"
+msgstr "通信が追加されました"
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr "記録されていない通信"
+
+#: lib/RT/Ticket_Overlay.pm:3458
+msgid "Could not add new custom field value for ticket. "
+msgstr "チケットの新しいカスタムフィールドバリューを追加できませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not add new custom field value for ticket. %1 "
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2963 lib/RT/Ticket_Overlay.pm:2971 lib/RT/Ticket_Overlay.pm:2987
+msgid "Could not change owner. "
+msgstr "オーナー変更ができませんでした"
+
+#: html/Admin/Elements/EditCustomField:68 html/Admin/Elements/EditCustomFields:166
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr "カスタムフィールドの作成ができませんでした"
+
+#: html/User/Groups/Modify.html:77 lib/RT/Group_Overlay.pm:474 lib/RT/Group_Overlay.pm:481
+msgid "Could not create group"
+msgstr "グループの作成ができませんでした"
+
+#: html/Admin/Global/Template.html:75 html/Admin/Queues/Template.html:72
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr "テンプレート: %1の作成ができませんでした"
+
+#: lib/RT/Ticket_Overlay.pm:1073 lib/RT/Ticket_Overlay.pm:333
+msgid "Could not create ticket. Queue not set"
+msgstr "チケットの作成ができませんでした。キューがセットされていません"
+
+#: lib/RT/User_Overlay.pm:208 lib/RT/User_Overlay.pm:220 lib/RT/User_Overlay.pm:238 lib/RT/User_Overlay.pm:414
+msgid "Could not create user"
+msgstr "ユーザーの作成ができませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not create watcher for requestor"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr "チケットとそのID%1が見つかりませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr "グループ %1が見つかりませんでした"
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1422
+msgid "Could not find or create that user"
+msgstr "そのユーザーを作成または見つけることができませんでした"
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1501
+msgid "Could not find that principal"
+msgstr "その責任者を見つけることができませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr "ユーザー%1を見つけることができませんでした"
+
+#: html/Admin/Groups/Members.html:88 html/User/Groups/Members.html:90 html/User/Groups/Modify.html:82
+msgid "Could not load group"
+msgstr "グループをロードできませんでした"
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr "このキューでその責任者を%1にすることができませんでした"
+
+#: lib/RT/Ticket_Overlay.pm:1443
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr "このチケットでその責任者を%1にすることができませんでした"
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr "このキューでその責任者を%1として削除することができませんでした"
+
+#: lib/RT/Ticket_Overlay.pm:1559
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr "このチケットでその責任者を%1として削除することができませんでした"
+
+#: lib/RT/Group_Overlay.pm:985
+msgid "Couldn't add member to group"
+msgstr "グループにメンバーの追加ができませんでした"
+
+#: lib/RT/Ticket_Overlay.pm:3468 lib/RT/Ticket_Overlay.pm:3524
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr "トランザクション: %1の作成ができませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr "GPGの返事\\nから何を行ったらよいのかわかりませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr "グループ\\nが見つかりませんでした"
+
+#: lib/RT/Interface/Web.pm:866
+msgid "Couldn't find row"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:959
+msgid "Couldn't find that principal"
+msgstr "責任者が見つかりませんでした"
+
+#: lib/RT/CustomField_Overlay.pm:175
+msgid "Couldn't find that value"
+msgstr "そのバリューが見つかりませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find that watcher"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr "ユーザー\\nが見つかりませんでした"
+
+#: lib/RT/CurrentUser.pm:112
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr "ユーザーデータベース\\nから%1をロードできませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load KeywordSelects."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr "RT設定ファイル'%1' %2をロードできませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr "スクリプトをロードできませんでした"
+
+#: html/Admin/Groups/GroupRights.html:88 html/Admin/Groups/UserRights.html:75
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr "グループ%1をロードできませんでした"
+
+#: lib/RT/Link_Overlay.pm:175 lib/RT/Link_Overlay.pm:184 lib/RT/Link_Overlay.pm:211
+msgid "Couldn't load link"
+msgstr "リンクをロードできませんでした"
+
+#: html/Admin/Elements/EditCustomFields:147 html/Admin/Queues/People.html:121
+#. ($id)
+msgid "Couldn't load queue"
+msgstr "キューをロードできませんでした"
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:72
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr "キュー%1をロードできませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr "スクリプトをロードできませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr "テンプレートをロードできませんでした"
+
+#: html/Admin/Users/Prefs.html:79
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr "そのユーザー(%1)をロードできませんでした"
+
+#: html/SelfService/Display.html:166
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr "チケット'%1'をロードできませんでした"
+
+#: html/Admin/Elements/ModifyUser:86 html/Admin/Users/Modify.html:149 html/User/Prefs.html:98
+msgid "Country"
+msgstr "国"
+
+#: html/Admin/Elements/CreateUserCalled:26 html/Ticket/Create.html:135 html/Ticket/Create.html:195
+msgid "Create"
+msgstr "作成"
+
+#: etc/initialdata:128
+msgid "Create Tickets"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomField:58
+msgid "Create a CustomField"
+msgstr "カスタムフィールドの作成"
+
+#: html/Admin/Queues/CustomField.html:48
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:48
+msgid "Create a CustomField which applies to all queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr "新しいカスタムフィールドの作成"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global Scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr "新しいグローバルスクリプトの作成"
+
+#: html/Admin/Groups/Modify.html:67 html/Admin/Groups/Modify.html:93
+msgid "Create a new group"
+msgstr "新しいグループの作成"
+
+#: html/User/Groups/Modify.html:67 html/User/Groups/Modify.html:92
+msgid "Create a new personal group"
+msgstr "新しい個人グループの作成"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr "新しいキューの作成"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr "新しいテンプレートの作成"
+
+#: html/SelfService/Create.html:30 html/Ticket/Create.html:25 html/Ticket/Create.html:28 html/Ticket/Create.html:36
+msgid "Create a new ticket"
+msgstr "新しいチケットの作成"
+
+#: html/Admin/Users/Modify.html:214 html/Admin/Users/Modify.html:241
+msgid "Create a new user"
+msgstr "新しいユーザーの作成"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "キューの作成"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr "呼び出されたキューの作成"
+
+#: html/SelfService/Create.html:25 html/SelfService/Create.html:27
+msgid "Create a request"
+msgstr "リクエストの作成"
+
+#: html/Admin/Queues/Scrip.html:59
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr ""
+
+#: html/Admin/Global/Template.html:69 html/Admin/Queues/Template.html:65
+msgid "Create a template"
+msgstr "テンプレートの作成"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1 / %2 / %3 "
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1/%2/%3"
+msgstr ""
+
+#: etc/initialdata:130
+msgid "Create new tickets based on this scrip's template"
+msgstr ""
+
+#: html/SelfService/Create.html:81
+msgid "Create ticket"
+msgstr "チケットの作成"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Create tickets in this queue"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Create, delete and modify custom fields"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Create, delete and modify queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr ""
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify the members of personal groups"
+msgstr ""
+
+#: lib/RT/System.pm:60
+msgid "Create, delete and modify users"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "CreateTicket"
+msgstr ""
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1167
+msgid "Created"
+msgstr "作成しました"
+
+#: html/Admin/Elements/EditCustomField:71
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr "カスタムフィールド%1を作成しました"
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr "テンプレート%1を作成しました"
+
+#: html/Ticket/Elements/EditLinks:28
+msgid "Current Relationships"
+msgstr "現在の関係"
+
+#: html/Admin/Elements/EditScrips:30
+msgid "Current Scrips"
+msgstr ""
+
+#: html/Admin/Groups/Members.html:39 html/User/Groups/Members.html:42
+msgid "Current members"
+msgstr "現在のメンバー"
+
+#: html/Admin/Elements/SelectRights:29
+msgid "Current rights"
+msgstr "現在の権利"
+
+#: html/Search/Listing.html:71
+msgid "Current search criteria"
+msgstr ""
+
+#: html/Admin/Queues/People.html:41 html/Ticket/Elements/EditPeople:45
+msgid "Current watchers"
+msgstr "現在のウォッチャー"
+
+#: html/Admin/Global/CustomField.html:55
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:53 html/Admin/Elements/SystemTabs:40 html/Admin/Global/index.html:50 html/Ticket/Elements/ShowSummary:35
+msgid "Custom Fields"
+msgstr "カスタムフィールド"
+
+#: html/Admin/Elements/EditScrip:73
+msgid "Custom action cleanup code"
+msgstr ""
+
+#: html/Admin/Elements/EditScrip:65
+msgid "Custom action preparation code"
+msgstr ""
+
+#: html/Admin/Elements/EditScrip:49
+msgid "Custom condition"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr "カスタムフィールド%1 %2 %3"
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr "カスタムフィールド%1はバリューがあります"
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr "カスタムフィールド%1はバリューがありません"
+
+#: lib/RT/Ticket_Overlay.pm:3360
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr "カスタムフィールド%1が見つかりません"
+
+#: html/Admin/Elements/EditCustomFields:197
+msgid "Custom field deleted"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3510
+msgid "Custom field not found"
+msgstr "カスタムフィールドが見つかりません"
+
+#: lib/RT/CustomField_Overlay.pm:283
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr "カスタムフィールド%2のためのカスタムフィールドバリュー%1が見つかりません"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr "カスタムフィールドが%1から%2に変更されました"
+
+#: lib/RT/CustomField_Overlay.pm:185
+msgid "Custom field value could not be deleted"
+msgstr "カスタムフィールドバリューは削除されません"
+
+#: lib/RT/CustomField_Overlay.pm:289
+msgid "Custom field value could not be found"
+msgstr "カスタムフィールドバリューが見つかりません"
+
+#: lib/RT/CustomField_Overlay.pm:183 lib/RT/CustomField_Overlay.pm:291
+msgid "Custom field value deleted"
+msgstr "カスタムフィールドバリューが削除されました"
+
+#: lib/RT/Transaction_Overlay.pm:550
+msgid "CustomField"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Data error"
+msgstr ""
+
+#: html/Ticket/Create.html:161 html/Ticket/Elements/ShowSummary:53 html/Ticket/Elements/Tabs:93 html/Ticket/ModifyAll.html:44
+msgid "Dates"
+msgstr "日付"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "十二月"
+
+#: NOT FOUND IN SOURCE
+msgid "December"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr ""
+
+#: etc/initialdata:207
+msgid "Default Autoresponse template"
+msgstr ""
+
+#: etc/initialdata:275
+msgid "Default admin comment template"
+msgstr ""
+
+#: etc/initialdata:257
+msgid "Default admin correspondence template"
+msgstr ""
+
+#: etc/initialdata:267
+msgid "Default correspondence template"
+msgstr ""
+
+#: etc/initialdata:238
+msgid "Default transaction template"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:645
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr ""
+
+#: html/User/Delegation.html:25 html/User/Delegation.html:28
+msgid "Delegate rights"
+msgstr "代表者の権利"
+
+#: lib/RT/System.pm:63
+msgid "Delegate specific rights which have been granted to you."
+msgstr ""
+
+#: lib/RT/System.pm:63
+msgid "DelegateRights"
+msgstr ""
+
+#: html/User/Elements/Tabs:38
+msgid "Delegation"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Delete"
+msgstr "削除"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "Delete tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "DeleteTicket"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr "このオブジェクトを削除すると指示の完全性がくずされる可能性があります"
+
+#: lib/RT/Queue_Overlay.pm:292
+msgid "Deleting this object would break referential integrity"
+msgstr "このオブジェクトを削除すると指示の完全性がくずされます"
+
+#: lib/RT/User_Overlay.pm:430
+msgid "Deleting this object would violate referential integrity"
+msgstr "このオブジェクトを削除すると指示の完全性が妨害されます"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity. That's bad."
+msgstr ""
+
+#: html/Approvals/Elements/Approve:46
+msgid "Deny"
+msgstr ""
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/EditLinks:123 html/Ticket/Elements/EditLinks:47 html/Ticket/Elements/ShowDependencies:32 html/Ticket/Elements/ShowLinks:35
+msgid "Depended on by"
+msgstr "次のもの次第である"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr "従属チケット: \\n"
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:180 html/Ticket/Elements/EditLinks:119 html/Ticket/Elements/EditLinks:36 html/Ticket/Elements/ShowDependencies:25 html/Ticket/Elements/ShowLinks:27
+msgid "Depends on"
+msgstr "による"
+
+#: NOT FOUND IN SOURCE
+msgid "DependsOn"
+msgstr ""
+
+#: html/Elements/SelectSortOrder:35
+msgid "Descending"
+msgstr "降順する"
+
+#: html/SelfService/Create.html:75 html/Ticket/Create.html:119
+msgid "Describe the issue below"
+msgstr "下の問題点を表す"
+
+#: html/Admin/Elements/AddCustomFieldValue:27 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/EditScrip:34 html/Admin/Elements/ModifyQueue:36 html/Admin/Elements/ModifyTemplate:36 html/Admin/Groups/Modify.html:49 html/Admin/Queues/Modify.html:48 html/Elements/SelectGroups:27 html/User/Groups/Modify.html:49
+msgid "Description"
+msgstr "記述"
+
+#: html/SelfService/Elements/MyRequests:44
+msgid "Details"
+msgstr "詳細"
+
+#: html/Ticket/Elements/Tabs:85
+msgid "Display"
+msgstr "表す"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Display Access Control List"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Display Scrip templates for this queue"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Display Scrips for this queue"
+msgstr ""
+
+#: html/Ticket/Elements/ShowHistory:35
+msgid "Display mode"
+msgstr "モードを表す"
+
+#: html/SelfService/Display.html:25 html/SelfService/Display.html:29
+#. ($Ticket->id)
+msgid "Display ticket #%1"
+msgstr "チケット#%1を表す"
+
+#: lib/RT/System.pm:54
+msgid "Do anything and everything"
+msgstr ""
+
+#: html/Elements/Refresh:30
+msgid "Don't refresh this page."
+msgstr "このページを更新しないでください"
+
+#: html/Search/Elements/PickRestriction:114
+msgid "Don't show search results"
+msgstr ""
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "Download"
+msgstr "ダウンロード"
+
+#: html/Elements/SelectDateType:32 html/Ticket/Create.html:167 html/Ticket/Elements/EditDates:45 html/Ticket/Elements/ShowDates:43 lib/RT/Ticket_Overlay.pm:1171
+msgid "Due"
+msgstr "期限切れ"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr "期限が切れる日'%1'は解析されません"
+
+#: bin/rt-commit-handler:754
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr "ERROR: はチケット '%1': %2.\\nをロードできませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit"
+msgstr "編集"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit Conditions"
+msgstr ""
+
+#: html/Admin/Queues/CustomFields.html:45
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr "%1のカスタムフィールドを編集する"
+
+#: html/Ticket/ModifyLinks.html:36
+msgid "Edit Relationships"
+msgstr "関係を編集する"
+
+#: html/Admin/Queues/Templates.html:41
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit keywords"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr "スクリプトを編集する"
+
+#: html/Admin/Global/index.html:46
+msgid "Edit system templates"
+msgstr "システムテンプレートを編集する"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr "%1のテンプレートを編集する"
+
+#: html/Admin/Elements/ModifyQueue:25 html/Admin/Queues/Modify.html:117
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr "キュー%1の設定を編集する"
+
+#: html/Admin/Elements/ModifyUser:25
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr "ユーザー%1の設定を編集する"
+
+#: html/Admin/Elements/EditCustomField:74
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr "カスタムフィールド%1を編集する"
+
+#: html/Admin/Groups/Members.html:32
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr "グループ%1の会員を編集する"
+
+#: html/User/Groups/Members.html:129
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr "個人グループ%1の会員を編集する"
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr "テンプレート%1を編集する"
+
+#: lib/RT/Ticket_Overlay.pm:2615 lib/RT/Ticket_Overlay.pm:2683
+msgid "Either base or target must be specified"
+msgstr "ベースもしくはターゲットを特定しなければなりません"
+
+#: html/Admin/Users/Modify.html:53 html/Admin/Users/Prefs.html:46 html/Elements/SelectUsers:27 html/Ticket/Elements/AddWatchers:56 html/User/Prefs.html:42
+msgid "Email"
+msgstr "Eメール"
+
+#: lib/RT/User_Overlay.pm:188
+msgid "Email address in use"
+msgstr "お使いのEメールアドレス"
+
+#: html/Admin/Elements/ModifyUser:42
+msgid "EmailAddress"
+msgstr "Eメールアドレス"
+
+#: html/Admin/Elements/ModifyUser:54
+msgid "EmailEncoding"
+msgstr "Eメールエンコーディング"
+
+#: html/Admin/Elements/EditCustomField:36
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:53 html/User/Groups/Modify.html:53
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr ""
+
+#: html/Admin/Queues/Modify.html:84
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr "有効になりました(もう一度このボックスをチェックするとこのキューは有効でなくなります)"
+
+#: html/Admin/Elements/EditCustomFields:99
+msgid "Enabled Custom Fields"
+msgstr ""
+
+#: html/Admin/Queues/index.html:56
+msgid "Enabled Queues"
+msgstr "有効なキュー"
+
+#: html/Admin/Elements/EditCustomField:90 html/Admin/Groups/Modify.html:117 html/Admin/Queues/Modify.html:138 html/Admin/Users/Modify.html:283 html/User/Groups/Modify.html:117
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr "有効なステータス%1"
+
+#: lib/RT/CustomField_Overlay.pm:361
+msgid "Enter multiple values"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:358
+msgid "Enter one value"
+msgstr ""
+
+#: html/Ticket/Elements/EditLinks:112
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "チケットをリンクするチケットまたはURLsを入力してください。入力する項目がいくつかある場合にはスペースで区切ってください。"
+
+#: html/Elements/Login:29 html/SelfService/Error.html:25 html/SelfService/Error.html:26
+msgid "Error"
+msgstr "エラー"
+
+#: NOT FOUND IN SOURCE
+msgid "Error adding watcher"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr "パラメーターのエラーQueue->AddWatcher"
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr "パラメーターのエラーQueue->DelWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1356
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr "パラメーターのエラーTicket->AddWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1532
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr "パラメーターのエラーTicket->DelWatcher"
+
+#: etc/initialdata:20
+msgid "Everyone"
+msgstr ""
+
+#: bin/rt-crontool:194
+msgid "Example:"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:64
+msgid "ExternalAuthId"
+msgstr "外部の認証ID"
+
+#: html/Admin/Elements/ModifyUser:58
+msgid "ExternalContactInfoId"
+msgstr "外部のコンタクト情報ID"
+
+#: html/Admin/Users/Modify.html:73
+msgid "Extra info"
+msgstr "その他の情報"
+
+#: lib/RT/User_Overlay.pm:302
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr "'特権のある'ユーザーの擬似グループの検索が失敗しました"
+
+#: lib/RT/User_Overlay.pm:309
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr "'特権のない'ユーザーの擬似グループの検索が失敗しました"
+
+#: bin/rt-crontool:138
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr ""
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "二月"
+
+#: NOT FOUND IN SOURCE
+msgid "February"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr "終了"
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:59 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "最終優先順位"
+
+#: lib/RT/Ticket_Overlay.pm:1162
+msgid "FinalPriority"
+msgstr ""
+
+#: html/Admin/Queues/People.html:61 html/Ticket/Elements/EditPeople:34
+msgid "Find group whose"
+msgstr ""
+
+#: html/Elements/Quicksearch:25
+msgid "Find new/open tickets"
+msgstr "新しい/開くチケットを見つける"
+
+#: html/Admin/Queues/People.html:57 html/Admin/Users/index.html:46 html/Ticket/Elements/EditPeople:30
+msgid "Find people whose"
+msgstr "人々を見つける"
+
+#: html/Search/Listing.html:108
+msgid "Find tickets"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Finish Approval"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:58
+msgid "First"
+msgstr "最初の"
+
+#: html/Search/Listing.html:41
+msgid "First page"
+msgstr "最初のページ"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr "Foo Bar Baz"
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr "ばか!"
+
+#: html/Search/Bulk.html:87
+msgid "Force change"
+msgstr "変更を強制します"
+
+#: html/Search/Listing.html:106
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:868
+msgid "Found Object"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:44
+msgid "FreeformContactInfo"
+msgstr "フリーフォームコンタクト情報"
+
+#: lib/RT/CustomField_Overlay.pm:38
+msgid "FreeformMultiple"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformSingle"
+msgstr ""
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "金曜日"
+
+#: html/Ticket/Elements/ShowHistory:41 html/Ticket/Elements/ShowHistory:51
+msgid "Full headers"
+msgstr "フルヘッダー"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr "pgp sig\\nから現在のユーザーを得る"
+
+#: lib/RT/Transaction_Overlay.pm:595
+#. ($New->Name)
+msgid "Given to %1"
+msgstr ""
+
+#: html/Admin/Elements/Tabs:41 html/Admin/index.html:38
+msgid "Global"
+msgstr "グローバル"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Keyword Selections"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr "グローバルスクリプト"
+
+#: html/Admin/Elements/SelectTemplate:38
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:75 html/Admin/Queues/People.html:59 html/Admin/Queues/People.html:63 html/Admin/Queues/index.html:44 html/Admin/Users/index.html:49 html/Ticket/Elements/EditPeople:32 html/Ticket/Elements/EditPeople:36 html/index.html:41
+msgid "Go!"
+msgstr "行く!"
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr "%1\\nからの良いpgp sig"
+
+#: html/Search/Listing.html:50
+msgid "Goto page"
+msgstr "ページへ行く"
+
+#: html/Elements/GotoTicket:25 html/SelfService/Elements/GotoTicket:25
+msgid "Goto ticket"
+msgstr "チケットに行く"
+
+#: NOT FOUND IN SOURCE
+msgid "Grand"
+msgstr ""
+
+#: html/Ticket/Elements/AddWatchers:46 html/User/Elements/DelegateRights:78
+msgid "Group"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr "グループ%1 %2: %3"
+
+#: html/Admin/Elements/GroupTabs:45 html/Admin/Elements/QueueTabs:57 html/Admin/Elements/SystemTabs:44 html/Admin/Global/index.html:55
+msgid "Group Rights"
+msgstr "グループ権利"
+
+#: lib/RT/Group_Overlay.pm:965
+msgid "Group already has member"
+msgstr "グループにはすでにメンバーがいます"
+
+#: NOT FOUND IN SOURCE
+msgid "Group could not be created."
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:77
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:497
+msgid "Group created"
+msgstr "グループが作成されました"
+
+#: lib/RT/Group_Overlay.pm:1133
+msgid "Group has no such member"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:945 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1429 lib/RT/Ticket_Overlay.pm:1507
+msgid "Group not found"
+msgstr "グループが見つかりません"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr "グループが見つかりません。\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr "グループが特定できません。\\n"
+
+#: html/Admin/Elements/SelectNewGroupMembers:35 html/Admin/Elements/Tabs:35 html/Admin/Groups/Members.html:64 html/Admin/Queues/People.html:83 html/Admin/index.html:32 html/User/Groups/Members.html:67
+msgid "Groups"
+msgstr "グループ"
+
+#: lib/RT/Group_Overlay.pm:971
+msgid "Groups can't be members of their members"
+msgstr "グループは彼らのメンバーにはなれません"
+
+#: lib/RT/Interface/CLI.pm:73 lib/RT/Interface/CLI.pm:73
+msgid "Hello!"
+msgstr "こんにちは!"
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr "こんにちは、%1"
+
+#: html/Ticket/Elements/ShowHistory:30 html/Ticket/Elements/Tabs:88
+msgid "History"
+msgstr "ヒストリー"
+
+#: html/Admin/Elements/ModifyUser:68
+msgid "HomePhone"
+msgstr "自宅の電話"
+
+#: html/Elements/Tabs:46
+msgid "Homepage"
+msgstr "ホームページ"
+
+#: lib/RT/Base.pm:74
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "I have [quant,_1,concrete mixer]."
+msgstr "私は[quant,_1,concrete mixer]があります。"
+
+#: html/Ticket/Elements/ShowBasics:27 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr "ID"
+
+#: html/Admin/Users/Modify.html:44 html/User/Prefs.html:39
+msgid "Identity"
+msgstr "身分証明書"
+
+#: etc/upgrade/2.1.71:86
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr ""
+
+#: bin/rt-crontool:190
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr ""
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "If you've updated anything above, be sure to"
+msgstr "上の何かをアップデートしたなら、次のことを確認してください"
+
+#: lib/RT/Interface/Web.pm:860
+msgid "Illegal value for %1"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:863
+msgid "Immutable field"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:74
+msgid "Include disabled custom fields in listing."
+msgstr ""
+
+#: html/Admin/Queues/index.html:43
+msgid "Include disabled queues in listing."
+msgstr "リストの無効なキューを含む"
+
+#: html/Admin/Users/index.html:47
+msgid "Include disabled users in search."
+msgstr "検索の無効なユーザーを含む"
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr "最初の優先権"
+
+#: lib/RT/Ticket_Overlay.pm:1161 lib/RT/Ticket_Overlay.pm:1163
+msgid "InitialPriority"
+msgstr ""
+
+#: lib/RT/ScripAction_Overlay.pm:105
+msgid "Input error"
+msgstr "入力エラー"
+
+#: NOT FOUND IN SOURCE
+msgid "Interest noted"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3729
+msgid "Internal Error"
+msgstr ""
+
+#: lib/RT/Record.pm:143
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:644
+msgid "Invalid Group Type"
+msgstr "無効なグループタイプです"
+
+#: lib/RT/Principal_Overlay.pm:128
+msgid "Invalid Right"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Invalid Type"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:865
+msgid "Invalid data"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:438
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr "無効なオーナーです。 '誰でもない'に初期設定します."
+
+#: lib/RT/Scrip_Overlay.pm:134 lib/RT/Template_Overlay.pm:251
+msgid "Invalid queue"
+msgstr "無効なキューです"
+
+#: lib/RT/ACE_Overlay.pm:244 lib/RT/ACE_Overlay.pm:253 lib/RT/ACE_Overlay.pm:259 lib/RT/ACE_Overlay.pm:270 lib/RT/ACE_Overlay.pm:275
+msgid "Invalid right"
+msgstr "無効な権利です"
+
+#: lib/RT/Record.pm:118
+#. ($key)
+msgid "Invalid value for %1"
+msgstr "%1には無効なバリューです"
+
+#: lib/RT/Ticket_Overlay.pm:3367
+msgid "Invalid value for custom field"
+msgstr "カスタムフィールドには無効なバリューです"
+
+#: lib/RT/Ticket_Overlay.pm:345
+msgid "Invalid value for status"
+msgstr "ステータスには無効なバリューです"
+
+#: bin/rt-crontool:191
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr ""
+
+#: bin/rt-crontool:192
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr ""
+
+#: bin/rt-crontool:163
+msgid "It takes several arguments:"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr ""
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "一月"
+
+#: NOT FOUND IN SOURCE
+msgid "January"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "Join or leave this group"
+msgstr ""
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "七月"
+
+#: NOT FOUND IN SOURCE
+msgid "July"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:99
+msgid "Jumbo"
+msgstr "大きい"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "六月"
+
+#: NOT FOUND IN SOURCE
+msgid "June"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr "キーワード"
+
+#: html/Admin/Elements/ModifyUser:52
+msgid "Lang"
+msgstr "長い"
+
+#: html/Ticket/Elements/Tabs:73
+msgid "Last"
+msgstr "最後の"
+
+#: html/Ticket/Elements/EditDates:38 html/Ticket/Elements/ShowDates:39
+msgid "Last Contact"
+msgstr "最後のコンタクト"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Contacted"
+msgstr "最後にコンタクトした"
+
+#: html/Search/Elements/TicketHeader:41
+msgid "Last Notified"
+msgstr ""
+
+#: html/Elements/SelectDateType:30
+msgid "Last Updated"
+msgstr "最後にアップデートした"
+
+#: NOT FOUND IN SOURCE
+msgid "LastUpdated"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr "残った"
+
+#: html/Admin/Users/Modify.html:83
+msgid "Let this user access RT"
+msgstr "このユーザーをRTにアクセスします"
+
+#: html/Admin/Users/Modify.html:87
+msgid "Let this user be granted rights"
+msgstr "このユーザーの権利を認めます"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr "オーナーを%1 %2に制限します"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr "キューを%1 %2に制限します"
+
+#: lib/RT/Ticket_Overlay.pm:2697
+msgid "Link already exists"
+msgstr "リンクはすでに存在しています"
+
+#: lib/RT/Ticket_Overlay.pm:2709
+msgid "Link could not be created"
+msgstr "リンクが作成されませんでした"
+
+#: lib/RT/Ticket_Overlay.pm:2717 lib/RT/Ticket_Overlay.pm:2727
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr "リンクが作成されました(%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2638
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr "リンクが削除されました(%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2644
+msgid "Link not found"
+msgstr "リンクが見つかりません"
+
+#: html/Ticket/ModifyLinks.html:25 html/Ticket/ModifyLinks.html:29
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr "リンクチケット#%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Link ticket %1"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:97
+msgid "Links"
+msgstr "リンク"
+
+#: html/Admin/Users/Modify.html:114 html/User/Prefs.html:85
+msgid "Location"
+msgstr "場所"
+
+#: lib/RT.pm:158
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr "ログディレクトリー%1が見つからない、または書き出せません。\\n RTが動きません"
+
+#: html/Elements/Header:57
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "%1としてサインする"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:25 html/Elements/Login:34 html/Elements/Login:45
+msgid "Login"
+msgstr "ログイン"
+
+#: html/Elements/Header:54
+msgid "Logout"
+msgstr "ログアウト"
+
+#: html/Search/Bulk.html:86
+msgid "Make Owner"
+msgstr "オーナーを決める"
+
+#: html/Search/Bulk.html:102
+msgid "Make Status"
+msgstr "ステータスを決める"
+
+#: html/Search/Bulk.html:109
+msgid "Make date Due"
+msgstr "期限期日を決める"
+
+#: html/Search/Bulk.html:110
+msgid "Make date Resolved"
+msgstr "解析期日を決める"
+
+#: html/Search/Bulk.html:107
+msgid "Make date Started"
+msgstr "開始した日を決める"
+
+#: html/Search/Bulk.html:106
+msgid "Make date Starts"
+msgstr "開始日を決める"
+
+#: html/Search/Bulk.html:108
+msgid "Make date Told"
+msgstr "いわれた日を決める"
+
+#: html/Search/Bulk.html:99
+msgid "Make priority"
+msgstr "優先順位を決める"
+
+#: html/Search/Bulk.html:100
+msgid "Make queue"
+msgstr "キューを決める"
+
+#: html/Search/Bulk.html:98
+msgid "Make subject"
+msgstr "サブジェクトを決める"
+
+#: html/Admin/index.html:33
+msgid "Manage groups and group membership"
+msgstr ""
+
+#: html/Admin/index.html:39
+msgid "Manage properties and configuration which apply to all queues"
+msgstr ""
+
+#: html/Admin/index.html:36
+msgid "Manage queues and queue-specific properties"
+msgstr ""
+
+#: html/Admin/index.html:30
+msgid "Manage users and passwords"
+msgstr ""
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "三月"
+
+#: NOT FOUND IN SOURCE
+msgid "March"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "May"
+msgstr ""
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "五月"
+
+#: lib/RT/Group_Overlay.pm:982
+msgid "Member added"
+msgstr "メンバーが追加されました"
+
+#: lib/RT/Group_Overlay.pm:1140
+msgid "Member deleted"
+msgstr "メンバーが削除されました"
+
+#: lib/RT/Group_Overlay.pm:1144
+msgid "Member not deleted"
+msgstr "メンバーが削除されていません"
+
+#: html/Elements/SelectLinkType:26
+msgid "Member of"
+msgstr "のメンバー"
+
+#: NOT FOUND IN SOURCE
+msgid "MemberOf"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:42 html/User/Elements/GroupTabs:42
+msgid "Members"
+msgstr "メンバー"
+
+#: lib/RT/Ticket_Overlay.pm:2843
+msgid "Merge Successful"
+msgstr "結合が成功しました"
+
+#: lib/RT/Ticket_Overlay.pm:2804
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "結合が失敗しました。有効なIDが設定できませんでした"
+
+#: html/Ticket/Elements/EditLinks:115
+msgid "Merge into"
+msgstr "に結合"
+
+#: html/Ticket/Update.html:102
+msgid "Message"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:867
+msgid "Missing a primary key?: %1"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:169 html/User/Prefs.html:54
+msgid "Mobile"
+msgstr "携帯"
+
+#: html/Admin/Elements/ModifyUser:72
+msgid "MobilePhone"
+msgstr "携帯電話"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify Access Control List"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Custom Field %1"
+msgstr "カスタムフィールド%1を修正する"
+
+#: html/Admin/Global/CustomFields.html:44 html/Admin/Global/index.html:51
+msgid "Modify Custom Fields which apply to all queues"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "Modify Scrip templates for this queue"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "Modify Scrips for this queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify System ACLS"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr ""
+
+#: html/Admin/Queues/CustomField.html:45
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:53
+msgid "Modify a CustomField which applies to all queues"
+msgstr ""
+
+#: html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr ""
+
+#: html/Admin/Global/Scrip.html:48
+msgid "Modify a scrip which applies to all queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify dates for # %1"
+msgstr ""
+
+#: html/Ticket/ModifyDates.html:25 html/Ticket/ModifyDates.html:29
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr "#%1の期日を修正する"
+
+#: html/Ticket/ModifyDates.html:35
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr "チケット#%1の期日を修正する"
+
+#: html/Admin/Global/GroupRights.html:25 html/Admin/Global/GroupRights.html:28 html/Admin/Global/index.html:56
+msgid "Modify global group rights"
+msgstr "グローバルグループの権利を修正する"
+
+#: html/Admin/Global/GroupRights.html:33
+msgid "Modify global group rights."
+msgstr "グローバルグループの権利を修正する"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for groups"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for users"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr "グローバルスクリプトを修正する"
+
+#: html/Admin/Global/UserRights.html:25 html/Admin/Global/UserRights.html:28 html/Admin/Global/index.html:60
+msgid "Modify global user rights"
+msgstr ""
+
+#: html/Admin/Global/UserRights.html:33
+msgid "Modify global user rights."
+msgstr "グローバルユーザーの権利を修正する"
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "Modify group metadata or delete group"
+msgstr ""
+
+#: html/Admin/Groups/GroupRights.html:25 html/Admin/Groups/GroupRights.html:29 html/Admin/Groups/GroupRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr "%1のグループ権利を修正する"
+
+#: html/Admin/Queues/GroupRights.html:25 html/Admin/Queues/GroupRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr "キュー%1のグループ権利を修正する"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Modify membership roster for this group"
+msgstr ""
+
+#: lib/RT/System.pm:61
+msgid "Modify one's own RT account"
+msgstr ""
+
+#: html/Admin/Queues/People.html:25 html/Admin/Queues/People.html:29
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr "キュー%1に関係のある人々を修正する"
+
+#: html/Ticket/ModifyPeople.html:25 html/Ticket/ModifyPeople.html:29 html/Ticket/ModifyPeople.html:35
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr "チケット#%1に関係のある人々を修正する"
+
+#: html/Admin/Queues/Scrips.html:44
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr "キュー%1のスクリプトを修正する"
+
+#: html/Admin/Global/Scrips.html:44 html/Admin/Global/index.html:42
+msgid "Modify scrips which apply to all queues"
+msgstr ""
+
+#: html/Admin/Global/Template.html:25 html/Admin/Global/Template.html:30 html/Admin/Global/Template.html:81 html/Admin/Queues/Template.html:78
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr "テンプレート%1を修正する"
+
+#: html/Admin/Global/Templates.html:44
+msgid "Modify templates which apply to all queues"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:87 html/User/Groups/Modify.html:86
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr "グループ%1を修正する"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Modify the queue watchers"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:236
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr "ユーザー%1を修正する"
+
+#: html/Ticket/ModifyAll.html:37
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "チケット# %1を修正する"
+
+#: html/Ticket/Modify.html:25 html/Ticket/Modify.html:28 html/Ticket/Modify.html:34
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "チケット#%1を修正する"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Modify tickets"
+msgstr ""
+
+#: html/Admin/Groups/UserRights.html:25 html/Admin/Groups/UserRights.html:29 html/Admin/Groups/UserRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr "グループ%1のユーザー権利を修正する"
+
+#: html/Admin/Queues/UserRights.html:25 html/Admin/Queues/UserRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr "キュー%1のユーザー権利を修正する"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr "キュー'%1'のウォッチャーを修正する"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyACL"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "ModifyOwnMembership"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "ModifyQueueWatchers"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "ModifyScrips"
+msgstr ""
+
+#: lib/RT/System.pm:61
+msgid "ModifySelf"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "ModifyTemplate"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "ModifyTicket"
+msgstr ""
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "月曜日"
+
+#: html/Ticket/Elements/ShowRequestor:42
+#. ($name)
+msgid "More about %1"
+msgstr "さらに%1について"
+
+#: html/Admin/Elements/EditCustomFields:61
+msgid "Move down"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:53
+msgid "Move up"
+msgstr ""
+
+#: html/Admin/Elements/SelectSingleOrMultiple:27
+msgid "Multiple"
+msgstr "多くの"
+
+#: lib/RT/User_Overlay.pm:179
+msgid "Must specify 'Name' attribute"
+msgstr "'名前'の属性を特定してください"
+
+#: NOT FOUND IN SOURCE
+msgid "My Approvals"
+msgstr ""
+
+#: html/Approvals/index.html:25 html/Approvals/index.html:26
+msgid "My approvals"
+msgstr ""
+
+#: html/Admin/Elements/AddCustomFieldValue:26 html/Admin/Elements/EditCustomField:32 html/Admin/Elements/ModifyTemplate:28 html/Admin/Elements/ModifyUser:30 html/Admin/Groups/Modify.html:44 html/Elements/SelectGroups:26 html/Elements/SelectUsers:28 html/User/Groups/Modify.html:44
+msgid "Name"
+msgstr "名前"
+
+#: lib/RT/User_Overlay.pm:186
+msgid "Name in use"
+msgstr "現在お使いの名前"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr ""
+
+#: html/Ticket/Elements/ShowDates:52
+msgid "Never"
+msgstr ""
+
+#: html/Elements/Quicksearch:30
+msgid "New"
+msgstr "新しい"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:93 html/User/Prefs.html:65
+msgid "New Password"
+msgstr "新しいパスワード"
+
+#: etc/initialdata:311 etc/upgrade/2.1.71:16
+msgid "New Pending Approval"
+msgstr ""
+
+#: html/Ticket/Elements/EditLinks:111
+msgid "New Relationships"
+msgstr "新しい関係"
+
+#: html/Ticket/Elements/Tabs:36
+msgid "New Search"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:41 html/Admin/Global/CustomFields.html:39 html/Admin/Queues/CustomField.html:52 html/Admin/Queues/CustomFields.html:40
+msgid "New custom field"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:54 html/User/Elements/GroupTabs:52
+msgid "New group"
+msgstr ""
+
+#: html/SelfService/Prefs.html:32
+msgid "New password"
+msgstr "新しいパスワード"
+
+#: lib/RT/User_Overlay.pm:639
+msgid "New password notification sent"
+msgstr "新しいパスワード情報が送られました"
+
+#: html/Admin/Elements/QueueTabs:70
+msgid "New queue"
+msgstr ""
+
+#: html/SelfService/Elements/Tabs:63
+msgid "New request"
+msgstr "新しいリクエスト"
+
+#: html/Admin/Elements/SelectRights:42
+msgid "New rights"
+msgstr "新しい権利"
+
+#: html/Admin/Global/Scrip.html:40 html/Admin/Global/Scrips.html:39 html/Admin/Queues/Scrip.html:43 html/Admin/Queues/Scrips.html:53
+msgid "New scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "New search"
+msgstr "新しい検索"
+
+#: html/Admin/Global/Template.html:60 html/Admin/Global/Templates.html:39 html/Admin/Queues/Template.html:58 html/Admin/Queues/Templates.html:46
+msgid "New template"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2771
+msgid "New ticket doesn't exist"
+msgstr "新しいチケットはありません"
+
+#: html/Admin/Elements/UserTabs:52
+msgid "New user"
+msgstr ""
+
+#: html/Admin/Elements/CreateUserCalled:26
+msgid "New user called"
+msgstr "新しいユーザーが呼ばれました"
+
+#: html/Admin/Queues/People.html:55 html/Ticket/Elements/EditPeople:29
+msgid "New watchers"
+msgstr "新しいウォッチャー"
+
+#: html/Admin/Users/Prefs.html:42
+msgid "New window setting"
+msgstr "新しいウインドウ設定"
+
+#: html/Ticket/Elements/Tabs:69
+msgid "Next"
+msgstr "次へ"
+
+#: html/Search/Listing.html:48
+msgid "Next page"
+msgstr "次のページ"
+
+#: html/Admin/Elements/ModifyUser:50
+msgid "NickName"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:63 html/User/Prefs.html:46
+msgid "Nickname"
+msgstr "ニックネーム"
+
+#: html/Admin/Elements/EditCustomField:73 html/Admin/Elements/EditCustomFields:105
+msgid "No CustomField"
+msgstr "カスタムフィールドがありません"
+
+#: html/Admin/Groups/GroupRights.html:84 html/Admin/Groups/UserRights.html:71
+msgid "No Group defined"
+msgstr "グループが定義されません"
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:68
+msgid "No Queue defined"
+msgstr "キューが定義されません"
+
+#: bin/rt-crontool:56
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr "RTユーザーが見つかりません。RT管理者に相談してください。\\n"
+
+#: html/Admin/Global/Template.html:79 html/Admin/Queues/Template.html:76
+msgid "No Template"
+msgstr "テンプレートがありません"
+
+#: bin/rt-commit-handler:764
+msgid "No Ticket specified. Aborting ticket "
+msgstr "チケットが特定できません。チケットを終了します"
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr "チケットが特定できません。チケットの修正を終了します\\n\\n"
+
+#: html/Approvals/Elements/Approve:47
+msgid "No action"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:862
+msgid "No column specified"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr "コマンドが見つかりません\\n"
+
+#: html/Elements/ViewUser:36 html/Ticket/Elements/ShowRequestor:45
+msgid "No comment entered about this user"
+msgstr "このユーザーに関してのコメントは入力されていません"
+
+#: lib/RT/Ticket_Overlay.pm:2189 lib/RT/Ticket_Overlay.pm:2257
+msgid "No correspondence attached"
+msgstr "通信文書の添付はありません"
+
+#: lib/RT/Action/Generic.pm:150 lib/RT/Condition/Generic.pm:176 lib/RT/Search/ActiveTicketsInQueue.pm:56 lib/RT/Search/Generic.pm:113
+#. (ref $self)
+msgid "No description for %1"
+msgstr "%1記述はありません"
+
+#: lib/RT/Users_Overlay.pm:151
+msgid "No group specified"
+msgstr "グループが特定できません"
+
+#: lib/RT/User_Overlay.pm:857
+msgid "No password set"
+msgstr "パスワードが設定されません"
+
+#: lib/RT/Queue_Overlay.pm:259
+msgid "No permission to create queues"
+msgstr "キューを作成する許可がされていません"
+
+#: lib/RT/Ticket_Overlay.pm:341
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:151
+msgid "No permission to create users"
+msgstr "ユーザーを作成する許可がされていません"
+
+#: html/SelfService/Display.html:174
+msgid "No permission to display that ticket"
+msgstr "そのチケットを表示する許可がありません"
+
+#: html/SelfService/Update.html:55
+msgid "No permission to view update ticket"
+msgstr "アップデートチケットを見る許可がさありません"
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1488
+msgid "No principal specified"
+msgstr "責任者が特定できません"
+
+#: html/Admin/Queues/People.html:154 html/Admin/Queues/People.html:164
+msgid "No principals selected."
+msgstr "責任者が選択されていません"
+
+#: html/Admin/Queues/index.html:35
+msgid "No queues matching search criteria found."
+msgstr "検索基準にあったキューが見つかりません"
+
+#: html/Admin/Elements/SelectRights:81
+msgid "No rights found"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:33
+msgid "No rights granted."
+msgstr "権利が許可されていません"
+
+#: html/Search/Bulk.html:149
+msgid "No search to operate on."
+msgstr "操作のための検索ができません"
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr "チケットIDが特定できません"
+
+#: lib/RT/Transaction_Overlay.pm:480 lib/RT/Transaction_Overlay.pm:518
+msgid "No transaction type specified"
+msgstr "トランザクションタイプが特定できません"
+
+#: NOT FOUND IN SOURCE
+msgid "No user or email address specified"
+msgstr ""
+
+#: html/Admin/Users/index.html:36
+msgid "No users matching search criteria found."
+msgstr "検索基準にあったユーザーが見つかりません"
+
+#: bin/rt-commit-handler:644
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr "有効なRTユーザーが見つかりません。RT cvcハンドラが分離しています。RT管理者に相談してください。\\n"
+
+#: lib/RT/Interface/Web.pm:859
+msgid "No value sent to _Set!\\n"
+msgstr ""
+
+#: html/Search/Elements/TicketRow:37
+msgid "Nobody"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:864
+msgid "Nonexistant field?"
+msgstr ""
+
+#: html/Elements/Login:99
+msgid "Not logged in"
+msgstr ""
+
+#: html/Elements/Header:59 html/SelfService/Elements/Header:58
+msgid "Not logged in."
+msgstr "ログインできません"
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "セットできません"
+
+#: html/NoAuth/Reminder.html:27
+msgid "Not yet implemented."
+msgstr "まだ実行できません"
+
+#: html/Admin/Groups/Rights.html:25
+msgid "Not yet implemented...."
+msgstr "まだ実行できません。。。"
+
+#: html/Approvals/Elements/Approve:50
+msgid "Notes"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:642
+msgid "Notification could not be sent"
+msgstr "お知らせを送ることができませんでした"
+
+#: etc/initialdata:94
+msgid "Notify AdminCcs"
+msgstr ""
+
+#: etc/initialdata:90
+msgid "Notify AdminCcs as Comment"
+msgstr ""
+
+#: etc/initialdata:121
+msgid "Notify Other Recipients"
+msgstr ""
+
+#: etc/initialdata:117
+msgid "Notify Other Recipients as Comment"
+msgstr ""
+
+#: etc/initialdata:86
+msgid "Notify Owner"
+msgstr ""
+
+#: etc/initialdata:82
+msgid "Notify Owner as Comment"
+msgstr ""
+
+#: etc/initialdata:313 etc/upgrade/2.1.71:17
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr ""
+
+#: etc/initialdata:78
+msgid "Notify Requestors"
+msgstr ""
+
+#: etc/initialdata:104
+msgid "Notify Requestors and Ccs"
+msgstr ""
+
+#: etc/initialdata:99
+msgid "Notify Requestors and Ccs as Comment"
+msgstr ""
+
+#: etc/initialdata:113
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr ""
+
+#: etc/initialdata:109
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr ""
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "十一月"
+
+#: NOT FOUND IN SOURCE
+msgid "November"
+msgstr ""
+
+#: lib/RT/Record.pm:157
+msgid "Object could not be created"
+msgstr ""
+
+#: lib/RT/Record.pm:176
+msgid "Object created"
+msgstr ""
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "十月"
+
+#: NOT FOUND IN SOURCE
+msgid "October"
+msgstr ""
+
+#: html/Elements/SelectDateRelation:35
+msgid "On"
+msgstr "に"
+
+#: etc/initialdata:155
+msgid "On Comment"
+msgstr ""
+
+#: etc/initialdata:148
+msgid "On Correspond"
+msgstr ""
+
+#: etc/initialdata:137
+msgid "On Create"
+msgstr ""
+
+#: etc/initialdata:169
+msgid "On Owner Change"
+msgstr ""
+
+#: etc/initialdata:177
+msgid "On Queue Change"
+msgstr ""
+
+#: etc/initialdata:183
+msgid "On Resolve"
+msgstr ""
+
+#: etc/initialdata:161
+msgid "On Status Change"
+msgstr ""
+
+#: etc/initialdata:142
+msgid "On Transaction"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:50
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:48
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr ""
+
+#: html/Elements/Quicksearch:31
+msgid "Open"
+msgstr "開く"
+
+#: html/Ticket/Elements/Tabs:136
+msgid "Open it"
+msgstr "それを開く"
+
+#: html/SelfService/Elements/Tabs:57
+msgid "Open requests"
+msgstr "リクエストを開く"
+
+#: html/Admin/Users/Prefs.html:41
+msgid "Open tickets (from listing) in a new window"
+msgstr "チケットを(リストから)新しいウインドウから開く"
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in another window"
+msgstr "チケットを(リストから)ほかのウインドウから開く"
+
+#: etc/initialdata:133
+msgid "Open tickets on correspondence"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:101
+msgid "Ordering and sorting"
+msgstr "整列と並び替え"
+
+#: html/Admin/Elements/ModifyUser:46 html/Admin/Users/Modify.html:117 html/Elements/SelectUsers:29 html/User/Prefs.html:86
+msgid "Organization"
+msgstr "組織"
+
+#: html/Approvals/Elements/Approve:34
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:55 html/Admin/Queues/Modify.html:69
+msgid "Over time, priority moves toward"
+msgstr "時間切れです、優先順位がうつりました"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Own tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "OwnTicket"
+msgstr ""
+
+#: etc/initialdata:38 html/Elements/MyRequests:32 html/SelfService/Elements/MyRequests:30 html/Ticket/Create.html:48 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/EditPeople:44 html/Ticket/Elements/ShowPeople:27 html/Ticket/Update.html:63 lib/RT/ACE_Overlay.pm:86 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "オーナー"
+
+#: lib/RT/Ticket_Overlay.pm:3004
+#. ($OldOwnerObj->Name,  $NewOwnerObj->Name)
+msgid "Owner changed from %1 to %2"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:584
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr "オーナーは強制的に%1から%2を変更しました"
+
+#: html/Search/Elements/PickRestriction:31
+msgid "Owner is"
+msgstr "オーナーは"
+
+#: html/Admin/Users/Modify.html:174 html/User/Prefs.html:56
+msgid "Pager"
+msgstr "ポケットベル"
+
+#: html/Admin/Elements/ModifyUser:74
+msgid "PagerPhone"
+msgstr "ポケットベル電話"
+
+#: NOT FOUND IN SOURCE
+msgid "Parent"
+msgstr ""
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/EditLinks:127 html/Ticket/Elements/EditLinks:58 html/Ticket/Elements/ShowLinks:43
+msgid "Parents"
+msgstr "両親"
+
+#: html/Elements/Login:43 html/User/Prefs.html:61
+msgid "Password"
+msgstr "パスワード"
+
+#: html/NoAuth/Reminder.html:25
+msgid "Password Reminder"
+msgstr "パスワードのお知らせ"
+
+#: lib/RT/User_Overlay.pm:168 lib/RT/User_Overlay.pm:860
+msgid "Password too short"
+msgstr "パスワードが短すぎます"
+
+#: html/Admin/Users/Modify.html:291 html/User/Prefs.html:172
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "パスワード: %1"
+
+#: html/Ticket/Elements/ShowSummary:43 html/Ticket/Elements/Tabs:96 html/Ticket/ModifyAll.html:51
+msgid "People"
+msgstr "人々"
+
+#: etc/initialdata:126
+msgid "Perform a user-defined action"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:231 lib/RT/ACE_Overlay.pm:237 lib/RT/ACE_Overlay.pm:563 lib/RT/ACE_Overlay.pm:573 lib/RT/ACE_Overlay.pm:583 lib/RT/ACE_Overlay.pm:648 lib/RT/CurrentUser.pm:83 lib/RT/CurrentUser.pm:92 lib/RT/CustomField_Overlay.pm:445 lib/RT/CustomField_Overlay.pm:451 lib/RT/Group_Overlay.pm:1095 lib/RT/Group_Overlay.pm:1099 lib/RT/Group_Overlay.pm:1108 lib/RT/Group_Overlay.pm:1159 lib/RT/Group_Overlay.pm:1163 lib/RT/Group_Overlay.pm:1169 lib/RT/Group_Overlay.pm:426 lib/RT/Group_Overlay.pm:518 lib/RT/Group_Overlay.pm:596 lib/RT/Group_Overlay.pm:604 lib/RT/Group_Overlay.pm:701 lib/RT/Group_Overlay.pm:705 lib/RT/Group_Overlay.pm:711 lib/RT/Group_Overlay.pm:904 lib/RT/Group_Overlay.pm:908 lib/RT/Group_Overlay.pm:921 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:126 lib/RT/Scrip_Overlay.pm:137 lib/RT/Scrip_Overlay.pm:197 lib/RT/Scrip_Overlay.pm:430 lib/RT/Template_Overlay.pm:284 lib/RT/Template_Overlay.pm:88 lib/RT/Template_Overlay.pm:94 lib/RT/Ticket_Overlay.pm:1341 lib/RT/Ticket_Overlay.pm:1351 lib/RT/Ticket_Overlay.pm:1365 lib/RT/Ticket_Overlay.pm:1518 lib/RT/Ticket_Overlay.pm:1527 lib/RT/Ticket_Overlay.pm:1540 lib/RT/Ticket_Overlay.pm:1875 lib/RT/Ticket_Overlay.pm:2013 lib/RT/Ticket_Overlay.pm:2177 lib/RT/Ticket_Overlay.pm:2244 lib/RT/Ticket_Overlay.pm:2596 lib/RT/Ticket_Overlay.pm:2668 lib/RT/Ticket_Overlay.pm:2762 lib/RT/Ticket_Overlay.pm:2777 lib/RT/Ticket_Overlay.pm:2910 lib/RT/Ticket_Overlay.pm:3139 lib/RT/Ticket_Overlay.pm:3337 lib/RT/Ticket_Overlay.pm:3499 lib/RT/Ticket_Overlay.pm:3551 lib/RT/Ticket_Overlay.pm:3716 lib/RT/Transaction_Overlay.pm:468 lib/RT/Transaction_Overlay.pm:475 lib/RT/Transaction_Overlay.pm:504 lib/RT/Transaction_Overlay.pm:511 lib/RT/User_Overlay.pm:1334 lib/RT/User_Overlay.pm:562 lib/RT/User_Overlay.pm:597 lib/RT/User_Overlay.pm:853 lib/RT/User_Overlay.pm:941
+msgid "Permission Denied"
+msgstr "許可が下りませんでした"
+
+#: html/User/Elements/Tabs:35
+msgid "Personal Groups"
+msgstr ""
+
+#: html/User/Groups/index.html:30 html/User/Groups/index.html:40
+msgid "Personal groups"
+msgstr "個人グループ"
+
+#: html/User/Elements/DelegateRights:37
+msgid "Personal groups:"
+msgstr "個人グループ:"
+
+#: html/Admin/Users/Modify.html:156 html/User/Prefs.html:49
+msgid "Phone numbers"
+msgstr "電話番号"
+
+#: html/Admin/Users/Rights.html:25
+msgid "Placeholder"
+msgstr "代替物"
+
+#: NOT FOUND IN SOURCE
+msgid "Pref"
+msgstr "お気に入り"
+
+#: html/Elements/Header:52 html/Elements/Tabs:55 html/SelfService/Prefs.html:25 html/User/Prefs.html:25 html/User/Prefs.html:28
+msgid "Preferences"
+msgstr "お気に入り"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr ""
+
+#: lib/RT/Action/Generic.pm:160
+msgid "Prepare Stubbed"
+msgstr "Prepare Stubbed"
+
+#: html/Ticket/Elements/Tabs:61
+msgid "Prev"
+msgstr "前の"
+
+#: html/Search/Listing.html:44
+msgid "Previous page"
+msgstr "前のページ"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr "優先権"
+
+#: lib/RT/ACE_Overlay.pm:133 lib/RT/ACE_Overlay.pm:208 lib/RT/ACE_Overlay.pm:552
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:54 html/SelfService/Display.html:76 html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:54 html/Ticket/Elements/ShowBasics:39 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "優先権"
+
+#: html/Admin/Elements/ModifyQueue:51 html/Admin/Queues/Modify.html:65
+msgid "Priority starts at"
+msgstr "優先順位は次のように始まります"
+
+#: etc/initialdata:25
+msgid "Privileged"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:271 html/User/Prefs.html:163
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr "特権ステータス: %1"
+
+#: html/Admin/Users/index.html:62
+msgid "Privileged users"
+msgstr "特権のあるユーザー"
+
+#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59
+msgid "Pseudogroup for internal use"
+msgstr ""
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Elements/Quicksearch:29 html/Search/Elements/PickRestriction:46 html/SelfService/Create.html:35 html/SelfService/Display.html:68 html/Ticket/Create.html:38 html/Ticket/Elements/EditBasics:64 html/Ticket/Elements/ShowBasics:43 html/User/Elements/DelegateRights:80 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "キュー"
+
+#: html/Admin/Queues/CustomField.html:42 html/Admin/Queues/Scrip.html:50 html/Admin/Queues/Scrips.html:46 html/Admin/Queues/Templates.html:43
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr "キュー'%1'は見つかりませんでした\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Keyword Selections"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:31 html/Admin/Queues/Modify.html:43
+msgid "Queue Name"
+msgstr "キューの名前"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr "キュースクリプト"
+
+#: lib/RT/Queue_Overlay.pm:263
+msgid "Queue already exists"
+msgstr "キューはすでに存在しています"
+
+#: lib/RT/Queue_Overlay.pm:272 lib/RT/Queue_Overlay.pm:278
+msgid "Queue could not be created"
+msgstr "キューの作成ができませんでした"
+
+#: html/Ticket/Create.html:209
+msgid "Queue could not be loaded."
+msgstr "キューのロードができませんでした"
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:282
+msgid "Queue created"
+msgstr "キューが作成されました"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue is not specified."
+msgstr ""
+
+#: html/SelfService/Display.html:129
+msgid "Queue not found"
+msgstr "キューが見つかりません"
+
+#: html/Admin/Elements/Tabs:38 html/Admin/index.html:35
+msgid "Queues"
+msgstr "キュー"
+
+#: html/Elements/Login:34
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr "%2のRT %1"
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr "<a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>からのRT%1。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr ""
+
+#: html/Admin/index.html:25 html/Admin/index.html:26
+msgid "RT Administration"
+msgstr "RT管理"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr "RT認証エラー"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr "RTバウンス:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr "RT設定エラー"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr "RT重大なエラー。メッセージが記録されません"
+
+#: html/Elements/Error:41 html/SelfService/Error.html:41
+msgid "RT Error"
+msgstr "RTエラー"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr "RT受信メール(%1)自身からのメール "
+
+#: NOT FOUND IN SOURCE
+msgid "RT Recieved mail (%1) from itself."
+msgstr ""
+
+#: html/SelfService/Closed.html:25
+msgid "RT Self Service / Closed Tickets"
+msgstr "RTセルフサービス/クローズされたチケット"
+
+#: html/index.html:25 html/index.html:28
+msgid "RT at a glance"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr "RTでは、ただいまお使いの方の認証ができませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr "RTは外部のデータベースルックアップを使ってリクエストする人を見つけることができませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr "RTはキュー: %1を見つけることができませんでした"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr "RTはこのPGPサインを有効にすることができませんでした。\\n"
+
+#: html/Elements/PageLayout:26
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr "RTはあなたののコマンドを処理しました"
+
+#: html/Elements/Login:83
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RTは&コピー; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;。これは<a href=\"http://www.gnu.org/copyleft/gpl.html\">GNUジェネラルパブリックライセンスのバージョン2で配信されています。</a>"
+
+#: NOT FOUND IN SOURCE
+msgid "RT is &copy; Copyright 1996-2002 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr "RTによるとこのメッセージはバウンスする可能性があります"
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr "RTはこのメッセージがまるでサインされていないように処理します。\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr "RTのEメールコマンドモードではPGP認証が必要になります。貴方のメッセージにサインしなかった、もしくははサインが有効でありません"
+
+#: html/Admin/Users/Modify.html:58 html/Admin/Users/Prefs.html:52 html/User/Prefs.html:44
+msgid "Real Name"
+msgstr "本名"
+
+#: html/Admin/Elements/ModifyUser:48
+msgid "RealName"
+msgstr "本名"
+
+#: html/Ticket/Create.html:185 html/Ticket/Elements/EditLinks:139 html/Ticket/Elements/EditLinks:94 html/Ticket/Elements/ShowLinks:63
+msgid "Referred to by"
+msgstr "次のものによって参照した"
+
+#: html/Elements/SelectLinkType:28 html/Ticket/Create.html:184 html/Ticket/Elements/EditLinks:135 html/Ticket/Elements/EditLinks:80 html/Ticket/Elements/ShowLinks:55
+msgid "Refers to"
+msgstr "参照する"
+
+#: NOT FOUND IN SOURCE
+msgid "RefersTo"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr "絞り込む"
+
+#: html/Search/Elements/PickRestriction:27
+msgid "Refine search"
+msgstr "絞込み検索"
+
+#: html/Elements/Refresh:36
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "このページを%1分おきに更新してください"
+
+#: html/Ticket/Create.html:174 html/Ticket/Elements/ShowSummary:60 html/Ticket/ModifyAll.html:57
+msgid "Relationships"
+msgstr "関係"
+
+#: html/Search/Bulk.html:93
+msgid "Remove AdminCc"
+msgstr "管理Ccを削除する"
+
+#: html/Search/Bulk.html:91
+msgid "Remove Cc"
+msgstr "Ccを削除する"
+
+#: html/Search/Bulk.html:89
+msgid "Remove Requestor"
+msgstr "リクエストする人を削除する"
+
+#: html/Ticket/Elements/ShowTransaction:173 html/Ticket/Elements/Tabs:122
+msgid "Reply"
+msgstr "返信"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Reply to tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "ReplyToTicket"
+msgstr ""
+
+#: etc/initialdata:44 html/Ticket/Update.html:40 lib/RT/ACE_Overlay.pm:87
+msgid "Requestor"
+msgstr "リクエストする人"
+
+#: html/Search/Elements/PickRestriction:38
+msgid "Requestor email address"
+msgstr "リクエストする人のEメールアドレス"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RequestorAddresses"
+msgstr ""
+
+#: html/SelfService/Create.html:43 html/SelfService/Display.html:42 html/Ticket/Create.html:56 html/Ticket/Elements/EditPeople:48 html/Ticket/Elements/ShowPeople:31
+msgid "Requestors"
+msgstr "リクエストする人"
+
+#: html/Admin/Elements/ModifyQueue:61 html/Admin/Queues/Modify.html:75
+msgid "Requests should be due in"
+msgstr "リクエストは次の日までに行われなければなりません"
+
+#: html/Elements/Submit:62
+msgid "Reset"
+msgstr "リセット"
+
+#: html/Admin/Users/Modify.html:159 html/User/Prefs.html:50
+msgid "Residence"
+msgstr "住所"
+
+#: html/Ticket/Elements/Tabs:132
+msgid "Resolve"
+msgstr "分解する"
+
+#: html/Ticket/Update.html:133
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr ""
+
+#: etc/initialdata:302 html/Elements/SelectDateType:28 lib/RT/Ticket_Overlay.pm:1170
+msgid "Resolved"
+msgstr "分解した"
+
+#: html/Search/Bulk.html:123 html/Ticket/ModifyAll.html:73 html/Ticket/Update.html:73
+msgid "Response to requestors"
+msgstr "リクエストする人に返答する"
+
+#: html/Elements/ListActions:26
+msgid "Results"
+msgstr "結果"
+
+#: html/Search/Elements/PickRestriction:105
+msgid "Results per page"
+msgstr "ページごとの結果"
+
+#: html/Admin/Elements/ModifyUser:33 html/Admin/Users/Modify.html:100 html/User/Prefs.html:72
+msgid "Retype Password"
+msgstr "パスワードの再入力"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr "%2 %3の権利%1が領域%4 %5\\nで見つかりませんでした"
+
+#: lib/RT/ACE_Overlay.pm:613
+msgid "Right Delegated"
+msgstr "権利が委託されました"
+
+#: lib/RT/ACE_Overlay.pm:303
+msgid "Right Granted"
+msgstr "権利が許可されました"
+
+#: lib/RT/ACE_Overlay.pm:161
+msgid "Right Loaded"
+msgstr "権利がロードされました"
+
+#: lib/RT/ACE_Overlay.pm:678 lib/RT/ACE_Overlay.pm:693
+msgid "Right could not be revoked"
+msgstr "権利を無効にできませんでした"
+
+#: html/User/Delegation.html:64
+msgid "Right not found"
+msgstr "権利が見つかりませんでした"
+
+#: lib/RT/ACE_Overlay.pm:543 lib/RT/ACE_Overlay.pm:638
+msgid "Right not loaded."
+msgstr "権利がロードできませんでした"
+
+#: lib/RT/ACE_Overlay.pm:689
+msgid "Right revoked"
+msgstr "権利が無効になりました"
+
+#: html/Admin/Elements/UserTabs:41
+msgid "Rights"
+msgstr "権利"
+
+#: lib/RT/Interface/Web.pm:758
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:791
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr ""
+
+#: html/Admin/Global/GroupRights.html:51 html/Admin/Queues/GroupRights.html:52
+msgid "Roles"
+msgstr "役割"
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr ""
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "土曜日"
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "Save Changes"
+msgstr "変更を保存する"
+
+#: html/Ticket/ModifyLinks.html:39
+msgid "Save changes"
+msgstr "変更を保存する"
+
+#: html/Admin/Global/Scrip.html:49
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:176
+msgid "Scrip Created"
+msgstr "スクリプトが作成されました"
+
+#: html/Admin/Elements/EditScrips:84
+msgid "Scrip deleted"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:46 html/Admin/Elements/SystemTabs:33 html/Admin/Global/index.html:41
+msgid "Scrips"
+msgstr "スクリプト"
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr "%1\\nのスクリプト"
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr ""
+
+#: html/Elements/SimpleSearch:27 html/Search/Elements/PickRestriction:126 html/Ticket/Elements/Tabs:159
+msgid "Search"
+msgstr "検索"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr "検索基準"
+
+#: html/Approvals/Elements/PendingMyApproval:39
+msgid "Search for approvals"
+msgstr ""
+
+#: bin/rt-crontool:188
+msgid "Security:"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "SeeQueue"
+msgstr ""
+
+#: html/Admin/Groups/index.html:40
+msgid "Select a group"
+msgstr "グループの選択"
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr "キューの選択"
+
+#: html/Admin/Users/index.html:25 html/Admin/Users/index.html:28
+msgid "Select a user"
+msgstr "ユーザーの選択"
+
+#: html/Admin/Global/CustomField.html:38 html/Admin/Global/CustomFields.html:36
+msgid "Select custom field"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:52 html/User/Elements/GroupTabs:50
+msgid "Select group"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:355
+msgid "Select multiple values"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:352
+msgid "Select one value"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:67
+msgid "Select queue"
+msgstr ""
+
+#: html/Admin/Global/Scrip.html:37 html/Admin/Global/Scrips.html:36 html/Admin/Queues/Scrip.html:40 html/Admin/Queues/Scrips.html:50
+msgid "Select scrip"
+msgstr ""
+
+#: html/Admin/Global/Template.html:57 html/Admin/Global/Templates.html:36 html/Admin/Queues/Template.html:55
+msgid "Select template"
+msgstr ""
+
+#: html/Admin/Elements/UserTabs:49
+msgid "Select user"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "SelectMultiple"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectSingle"
+msgstr ""
+
+#: html/SelfService/index.html:25
+msgid "Self Service"
+msgstr "セルフサービス"
+
+#: etc/initialdata:114
+msgid "Send mail to all watchers"
+msgstr ""
+
+#: etc/initialdata:110
+msgid "Send mail to all watchers as a \"comment\""
+msgstr ""
+
+#: etc/initialdata:105
+msgid "Send mail to requestors and Ccs"
+msgstr ""
+
+#: etc/initialdata:100
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr ""
+
+#: etc/initialdata:79
+msgid "Sends a message to the requestors"
+msgstr ""
+
+#: etc/initialdata:118 etc/initialdata:122
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr ""
+
+#: etc/initialdata:95
+msgid "Sends mail to the administrative Ccs"
+msgstr ""
+
+#: etc/initialdata:91
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr ""
+
+#: etc/initialdata:83 etc/initialdata:87
+msgid "Sends mail to the owner"
+msgstr ""
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "九月"
+
+#: NOT FOUND IN SOURCE
+msgid "September"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr "結果を見る"
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show approved requests"
+msgstr ""
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show basics"
+msgstr "基本を見る"
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show denied requests"
+msgstr ""
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show details"
+msgstr "詳細を見る"
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show pending requests"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:46
+msgid "Show requests awaiting other approvals"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Show ticket private commentary"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "Show ticket summaries"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ShowACL"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowScrips"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ShowTemplate"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "ShowTicket"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "ShowTicketComments"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:39 html/Admin/Users/Modify.html:191 html/Admin/Users/Prefs.html:32 html/SelfService/Prefs.html:37 html/User/Prefs.html:112
+msgid "Signature"
+msgstr "サイン"
+
+#: html/SelfService/Elements/Header:52
+#. ($session{'CurrentUser'}->Name)
+msgid "Signed in as %1"
+msgstr ""
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Single"
+msgstr "ひとつの"
+
+#: html/Elements/Header:51
+msgid "Skip Menu"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFieldValues:31
+msgid "Sort key"
+msgstr "並べ替えのキー"
+
+#: html/Search/Elements/PickRestriction:109
+msgid "Sort results by"
+msgstr "次の項目ごとの並び替え"
+
+#: html/Admin/Elements/AddCustomFieldValue:25
+msgid "SortOrder"
+msgstr "並び順"
+
+#: NOT FOUND IN SOURCE
+msgid "Stalled"
+msgstr "停止しています"
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr "開始ページ"
+
+#: html/Elements/SelectDateType:27 html/Ticket/Elements/EditDates:32 html/Ticket/Elements/ShowDates:35
+msgid "Started"
+msgstr "開始した"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr "開始日'%1'は見つかりませんでした"
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:27 html/Ticket/Elements/ShowDates:31
+msgid "Starts"
+msgstr "開始する"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr "次の日時までに開始する"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr "開始日'%1'を解析できませんでした"
+
+#: html/Admin/Elements/ModifyUser:82 html/Admin/Users/Modify.html:138 html/User/Prefs.html:94
+msgid "State"
+msgstr "状態"
+
+#: html/Elements/MyRequests:31 html/Elements/MyTickets:31 html/Search/Elements/PickRestriction:74 html/SelfService/Display.html:59 html/SelfService/Elements/MyRequests:29 html/SelfService/Update.html:31 html/Ticket/Create.html:42 html/Ticket/Elements/EditBasics:38 html/Ticket/Elements/ShowBasics:31 html/Ticket/Update.html:60 lib/RT/Ticket_Overlay.pm:1164 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "ステータス"
+
+#: etc/initialdata:288
+msgid "Status Change"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:530
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr "ステータスが%1から%2に変更されました"
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:147
+msgid "Steal"
+msgstr "盗用する"
+
+#: lib/RT/Transaction_Overlay.pm:589
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "%1から盗用した"
+
+#: html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Search/Bulk.html:126 html/Search/Elements/PickRestriction:43 html/SelfService/Create.html:59 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:35 html/Ticket/Create.html:84 html/Ticket/Elements/EditBasics:28 html/Ticket/ModifyAll.html:79 html/Ticket/Update.html:77 lib/RT/Ticket_Overlay.pm:1160 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "サブジェクト"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:611
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr ""
+
+#: html/Elements/Submit:59
+msgid "Submit"
+msgstr "提出"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:749
+msgid "Succeeded"
+msgstr ""
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "日曜日"
+
+#: lib/RT/System.pm:54
+msgid "SuperUser"
+msgstr ""
+
+#: html/User/Elements/DelegateRights:77
+msgid "System"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:567 lib/RT/Interface/Web.pm:757 lib/RT/Interface/Web.pm:790
+msgid "System Error"
+msgstr "システムエラー"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. Right not granted."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. right not granted"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:616
+msgid "System error. Right not delegated."
+msgstr "システムエラー。権利が委任されていません"
+
+#: lib/RT/ACE_Overlay.pm:146 lib/RT/ACE_Overlay.pm:223 lib/RT/ACE_Overlay.pm:306 lib/RT/ACE_Overlay.pm:898
+msgid "System error. Right not granted."
+msgstr "システムエラー。権利が認可されていません"
+
+#: NOT FOUND IN SOURCE
+msgid "System error. Unable to grant rights."
+msgstr ""
+
+#: html/Admin/Global/GroupRights.html:35 html/Admin/Groups/GroupRights.html:37 html/Admin/Queues/GroupRights.html:36
+msgid "System groups"
+msgstr "システムグループ"
+
+#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53
+msgid "SystemRolegroup for internal use"
+msgstr ""
+
+#: lib/RT/CurrentUser.pm:320
+msgid "TEST_STRING"
+msgstr "テスト_ストリング"
+
+#: html/Ticket/Elements/Tabs:143
+msgid "Take"
+msgstr "とる"
+
+#: lib/RT/Transaction_Overlay.pm:575
+msgid "Taken"
+msgstr "とられた"
+
+#: html/Admin/Elements/EditScrip:81
+msgid "Template"
+msgstr "テンプレート"
+
+#: html/Admin/Global/Template.html:91 html/Admin/Queues/Template.html:90
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr ""
+
+#: html/Admin/Elements/EditTemplates:89
+msgid "Template deleted"
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:153
+msgid "Template not found"
+msgstr "テンプレートが見つかりません"
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr "テンプレートが見つかりません\\n"
+
+#: lib/RT/Template_Overlay.pm:347
+msgid "Template parsed"
+msgstr "テンプレートが解析されました"
+
+#: html/Admin/Elements/QueueTabs:49 html/Admin/Elements/SystemTabs:36 html/Admin/Global/index.html:45
+msgid "Templates"
+msgstr "テンプレート"
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr "%1\\nのテンプレート"
+
+#: lib/RT/Interface/Web.pm:858
+msgid "That is already the current value"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:178
+msgid "That is not a value for this custom field"
+msgstr "それはこのカスタムフィールドのバリューではありません"
+
+#: lib/RT/Ticket_Overlay.pm:1886
+msgid "That is the same value"
+msgstr "それは同じバリューです"
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr "その責任者はすでにこのキューの%1です"
+
+#: lib/RT/Ticket_Overlay.pm:1434
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr "その責任者はすでにこのチケットの%1です"
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr "その責任者はこのキューの%1ではありません"
+
+#: lib/RT/Ticket_Overlay.pm:1551
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr "その責任者はこのチケットの%1ではありません"
+
+#: lib/RT/Ticket_Overlay.pm:1882
+msgid "That queue does not exist"
+msgstr "そのキューはありません"
+
+#: lib/RT/Ticket_Overlay.pm:3143
+msgid "That ticket has unresolved dependencies"
+msgstr "そのチケットは従属物をすでに分解しました"
+
+#: lib/RT/ACE_Overlay.pm:288 lib/RT/ACE_Overlay.pm:597
+msgid "That user already has that right"
+msgstr "そのユーザーはすでに権利があります"
+
+#: lib/RT/Ticket_Overlay.pm:2952
+msgid "That user already owns that ticket"
+msgstr "そのユーザーはすでにチケットを所有しています"
+
+#: lib/RT/Ticket_Overlay.pm:2918
+msgid "That user does not exist"
+msgstr "そのユーザーは存在しません"
+
+#: lib/RT/User_Overlay.pm:315
+msgid "That user is already privileged"
+msgstr "そのユーザーはすでに特権が与えられています"
+
+#: lib/RT/User_Overlay.pm:332
+msgid "That user is already unprivileged"
+msgstr "そのユーザーにはすでに特権がありません"
+
+#: lib/RT/User_Overlay.pm:327
+msgid "That user is now privileged"
+msgstr "そのユーザーは今特権を与えられました"
+
+#: lib/RT/User_Overlay.pm:344
+msgid "That user is now unprivileged"
+msgstr "そのユーザーは今特権を失いました"
+
+#: NOT FOUND IN SOURCE
+msgid "That user is now unprivilegedileged"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2944
+msgid "That user may not own tickets in that queue"
+msgstr "そのユーザーはこのキューではチケットを所有していない可能性があります"
+
+#: lib/RT/Link_Overlay.pm:206
+msgid "That's not a numerical id"
+msgstr "それは数字のIDではありません"
+
+#: html/Ticket/Create.html:150 html/Ticket/Elements/ShowSummary:28
+msgid "The Basics"
+msgstr "基本"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The CC of a ticket"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:89
+msgid "The administrative CC of a ticket"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2213
+msgid "The comment has been recorded"
+msgstr "コメントは記録されました"
+
+#: bin/rt-crontool:198
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr ""
+
+#: bin/rt-commit-handler:756 bin/rt-commit-handler:766
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr "次のコマンドは処理されませんでした:\\n\\n"
+
+#: lib/RT/Interface/Web.pm:861
+msgid "The new value has been set."
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The owner of a ticket"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The requestor of a ticket"
+msgstr ""
+
+#: html/Admin/Elements/EditUserComments:26
+msgid "These comments aren't generally visible to the user"
+msgstr "それらのコメントは実際ユーザーには見ることができません"
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr "このチケット%1 %2 (%3)\\n"
+
+#: bin/rt-crontool:189
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:253
+msgid "This transaction appears to have no content"
+msgstr "このトランザクションにはコンテンツがありません"
+
+#: html/Ticket/Elements/ShowRequestor:47
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr "このユーザーの25のもっとも高い優先チケット"
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "木曜日"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr "チケット# %1  %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1 Jumbo update: %2"
+msgstr ""
+
+#: html/Ticket/ModifyAll.html:25 html/Ticket/ModifyAll.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "チケット #%1 大きいアップデート: %2"
+
+#: html/Approvals/Elements/ShowDependency:46
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:608
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr "チケット %1がキュー '%2'で作成されました"
+
+#: bin/rt-commit-handler:760
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr "チケット%1がロードされました\\n"
+
+#: html/Search/Bulk.html:181
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr "チケット %1: %2"
+
+#: html/Ticket/History.html:25 html/Ticket/History.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr "チケットヒストリー # %1 %2"
+
+#: html/SelfService/Display.html:34
+msgid "Ticket Id"
+msgstr "チケットID"
+
+#: etc/initialdata:303
+msgid "Ticket Resolved"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:63
+msgid "Ticket attachment"
+msgstr "チケット添付"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr "チケットコンテンツ"
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr "チケットコンテンツタイプ"
+
+#: lib/RT/Ticket_Overlay.pm:495 lib/RT/Ticket_Overlay.pm:597
+msgid "Ticket could not be created due to an internal error"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:522
+msgid "Ticket created"
+msgstr "チケットが作成されました"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr "チケットの作成が失敗しました"
+
+#: lib/RT/Transaction_Overlay.pm:527
+msgid "Ticket deleted"
+msgstr "チケットが削除されました"
+
+#: html/REST/1.0/modify:29 html/REST/1.0/update:34
+msgid "Ticket id not found"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket killed"
+msgstr ""
+
+#: html/REST/1.0/modify:36 html/REST/1.0/update:41
+msgid "Ticket not found"
+msgstr ""
+
+#: etc/initialdata:289
+msgid "Ticket status changed"
+msgstr ""
+
+#: html/Ticket/Update.html:39
+msgid "Ticket watchers"
+msgstr "チケットウォッチャー"
+
+#: html/Elements/Tabs:49
+msgid "Tickets"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr ""
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Tickets from %1"
+msgstr "%1からのチケット"
+
+#: html/Approvals/Elements/ShowDependency:27
+msgid "Tickets which depend on this approval:"
+msgstr ""
+
+#: html/Ticket/Create.html:157 html/Ticket/Elements/EditBasics:48
+msgid "Time Left"
+msgstr "時間が残っています"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:43
+msgid "Time Worked"
+msgstr "使った時間"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "残っている時間"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "表示する時間"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "使った時間"
+
+#: NOT FOUND IN SOURCE
+msgid "TimeLeft"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1165
+msgid "TimeWorked"
+msgstr ""
+
+#: bin/rt-commit-handler:402
+msgid "To generate a diff of this commit:"
+msgstr "このコミットのディフをつくるために:"
+
+#: bin/rt-commit-handler:391
+msgid "To generate a diff of this commit:\\n"
+msgstr "このコミットのディフをつくるために:\\n"
+
+#: lib/RT/Ticket_Overlay.pm:1168
+msgid "Told"
+msgstr "言った"
+
+#: etc/initialdata:237
+msgid "Transaction"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:642
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr "トランザクション%1が消去されました"
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr "トランザクションが作成されました"
+
+#: lib/RT/Transaction_Overlay.pm:89
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:701
+msgid "Transactions are immutable"
+msgstr "トランザクションは変更されることはありません"
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr "権利: %1を削除しています"
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "火曜日"
+
+#: html/Admin/Elements/EditCustomField:34 html/Ticket/Elements/AddWatchers:33 html/Ticket/Elements/AddWatchers:44 html/Ticket/Elements/AddWatchers:54 lib/RT/Ticket_Overlay.pm:1166 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "タイプ"
+
+#: lib/RT/ScripCondition_Overlay.pm:104
+msgid "Unimplemented"
+msgstr "導入されていない"
+
+#: html/Admin/Users/Modify.html:68
+msgid "Unix login"
+msgstr "Unixログイン"
+
+#: html/Admin/Elements/ModifyUser:62
+msgid "UnixUsername"
+msgstr "Unixユーザーネーム"
+
+#: lib/RT/Attachment_Overlay.pm:265
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr "不明なコンテンツエンコーディング%1"
+
+#: html/Elements/SelectResultsPerPage:37
+msgid "Unlimited"
+msgstr "制限されていない"
+
+#: etc/initialdata:32
+msgid "Unprivileged"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:571
+msgid "Untaken"
+msgstr "とられていない"
+
+#: html/Elements/MyTickets:64 html/Search/Bulk.html:33
+msgid "Update"
+msgstr "アップデート"
+
+#: html/Admin/Users/Prefs.html:62
+msgid "Update ID"
+msgstr "アップデートID"
+
+#: html/Search/Bulk.html:120 html/Ticket/ModifyAll.html:66 html/Ticket/Update.html:67
+msgid "Update Type"
+msgstr "アップデートタイプ"
+
+#: html/Search/Listing.html:61
+msgid "Update all these tickets at once"
+msgstr "すべてのチケットを一度にアップデートする"
+
+#: html/Admin/Users/Prefs.html:49
+msgid "Update email"
+msgstr "アップデートEメール"
+
+#: html/Admin/Users/Prefs.html:55
+msgid "Update name"
+msgstr "アップデートネーム"
+
+#: lib/RT/Interface/Web.pm:375
+msgid "Update not recorded."
+msgstr "アップデートは記録されませんでした"
+
+#: html/Search/Bulk.html:81
+msgid "Update selected tickets"
+msgstr "選択されたチケットをアップデートする"
+
+#: html/Admin/Users/Prefs.html:36
+msgid "Update signature"
+msgstr "サインをアップデートする"
+
+#: html/Ticket/ModifyAll.html:63
+msgid "Update ticket"
+msgstr "チケットをアップデートする"
+
+#: html/SelfService/Update.html:25 html/SelfService/Update.html:27
+#. ($Ticket->id)
+msgid "Update ticket # %1"
+msgstr "アップデートチケット # %1"
+
+#: html/SelfService/Update.html:50
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr "アップデートチケット #%1"
+
+#: html/Ticket/Update.html:135
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:373
+msgid "Update type was neither correspondence nor comment."
+msgstr "アップデートタイプは通知でもコメントでもありません"
+
+#: html/Elements/SelectDateType:33 html/Ticket/Elements/ShowDates:51 lib/RT/Ticket_Overlay.pm:1169
+msgid "Updated"
+msgstr "アップデートしました"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr "ユーザー%1 %2: %3\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr "ユーザー%1パスワード: %2\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr "ユーザー'%1'が見つかりません"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr "ユーザー'%1'が見つかりません\\n"
+
+#: etc/initialdata:125 etc/initialdata:191
+msgid "User Defined"
+msgstr ""
+
+#: html/Admin/Users/Prefs.html:59
+msgid "User ID"
+msgstr "ユーザーID"
+
+#: html/Elements/SelectUsers:26
+msgid "User Id"
+msgstr "ユーザーID"
+
+#: html/Admin/Elements/GroupTabs:47 html/Admin/Elements/QueueTabs:60 html/Admin/Elements/SystemTabs:47 html/Admin/Global/index.html:59
+msgid "User Rights"
+msgstr "ユーザー権利"
+
+#: html/Admin/Users/Modify.html:226
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr "ユーザーを作成することができませんでした: %1"
+
+#: lib/RT/User_Overlay.pm:262
+msgid "User created"
+msgstr "ユーザーが作成されました"
+
+#: html/Admin/Global/GroupRights.html:67 html/Admin/Groups/GroupRights.html:54 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr "ユーザーがグループを決定しました"
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr "ユーザーに通告されました"
+
+#: html/Admin/Users/Prefs.html:25 html/Admin/Users/Prefs.html:29
+msgid "User view"
+msgstr "ユーザービュー"
+
+#: html/Admin/Users/Modify.html:48 html/Elements/Login:42 html/Ticket/Elements/AddWatchers:35
+msgid "Username"
+msgstr "ユーザーネーム"
+
+#: html/Admin/Elements/SelectNewGroupMembers:26 html/Admin/Elements/Tabs:32 html/Admin/Groups/Members.html:55 html/Admin/Queues/People.html:68 html/Admin/index.html:29 html/User/Groups/Members.html:58
+msgid "Users"
+msgstr "ユーザー"
+
+#: html/Admin/Users/index.html:65
+msgid "Users matching search criteria"
+msgstr "ユーザーが検索基準にあっています"
+
+#: html/Search/Elements/PickRestriction:51
+msgid "ValueOfQueue"
+msgstr "キューのバリュー"
+
+#: html/Admin/Elements/EditCustomField:40
+msgid "Values"
+msgstr "バリュー"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Watch"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "WatchAsAdminCc"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Watcher loaded"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:42
+msgid "Watchers"
+msgstr "ウォッチャー"
+
+#: html/Admin/Elements/ModifyUser:56
+msgid "WebEncoding"
+msgstr "ウェブエンコーディング"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "水曜日"
+
+#: etc/upgrade/2.1.71:161
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr ""
+
+#: etc/upgrade/2.1.71:135
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr ""
+
+#: etc/initialdata:138
+msgid "When a ticket is created"
+msgstr ""
+
+#: etc/upgrade/2.1.71:79
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr ""
+
+#: etc/initialdata:143
+msgid "When anything happens"
+msgstr ""
+
+#: etc/initialdata:184
+msgid "Whenever a ticket is resolved"
+msgstr ""
+
+#: etc/initialdata:170
+msgid "Whenever a ticket's owner changes"
+msgstr ""
+
+#: etc/initialdata:178
+msgid "Whenever a ticket's queue changes"
+msgstr ""
+
+#: etc/initialdata:162
+msgid "Whenever a ticket's status changes"
+msgstr ""
+
+#: etc/initialdata:192
+msgid "Whenever a user-defined condition occurs"
+msgstr ""
+
+#: etc/initialdata:156
+msgid "Whenever comments come in"
+msgstr ""
+
+#: etc/initialdata:149
+msgid "Whenever correspondence comes in"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:164 html/User/Prefs.html:52
+msgid "Work"
+msgstr "仕事"
+
+#: html/Admin/Elements/ModifyUser:70
+msgid "WorkPhone"
+msgstr "仕事先の電話"
+
+#: html/SelfService/Display.html:86 html/Ticket/Elements/ShowBasics:35 html/Ticket/Update.html:65
+msgid "Worked"
+msgstr "Worked"
+
+#: lib/RT/Ticket_Overlay.pm:3056
+msgid "You already own this ticket"
+msgstr "あなたはすでにこのチケットを所有しています"
+
+#: html/autohandler:121
+msgid "You are not an authorized user"
+msgstr "あなたは認証されたユーザーではありません"
+
+#: lib/RT/Ticket_Overlay.pm:2930
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "あなたは所有、または所有されていないチケットのみを止めることができます"
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr "あなたはそのチケットを見る許可がありません。\\n"
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "あなたは%2でチケット%1を見つけました"
+
+#: html/NoAuth/Logout.html:31 html/REST/1.0/logout:25
+msgid "You have been logged out of RT."
+msgstr "あなたはRTからログアウトしたままです"
+
+#: html/SelfService/Display.html:134
+msgid "You have no permission to create tickets in that queue."
+msgstr "あなたはこのキューでチケット作成の許可がありません"
+
+#: lib/RT/Ticket_Overlay.pm:1895
+msgid "You may not create requests in that queue."
+msgstr "あなたはこのキューでリクエストの作成ができるでしょう"
+
+#: html/NoAuth/Logout.html:36
+msgid "You're welcome to login again"
+msgstr "ぜひまたログインしてください"
+
+#: html/SelfService/Elements/MyRequests:25
+#. ($friendly_status)
+msgid "Your %1 requests"
+msgstr "あなたの%1のリクエスト"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr "あなたのRT管理者はRTを呼び出すメールaliasesを設定できませんでした"
+
+#: etc/initialdata:429 etc/upgrade/2.1.71:146
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr ""
+
+#: etc/initialdata:463 etc/upgrade/2.1.71:180
+msgid "Your request has been approved."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr ""
+
+#: etc/initialdata:384 etc/upgrade/2.1.71:101
+msgid "Your request was rejected."
+msgstr ""
+
+#: html/autohandler:136 html/autohandler:142
+msgid "Your username or password is incorrect"
+msgstr "あなたののユーザーネームとパスワードが間違っています"
+
+#: html/Admin/Elements/ModifyUser:84 html/Admin/Users/Modify.html:144 html/User/Prefs.html:96
+msgid "Zip"
+msgstr "ジップ"
+
+#: NOT FOUND IN SOURCE
+msgid "[no subject]"
+msgstr ""
+
+#: html/User/Elements/DelegateRights:59
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "%1への許可"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:34
+msgid "contains"
+msgstr "含む"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content"
+msgstr ""
+
+#: html/Elements/SelectAttachmentField:27
+msgid "content-type"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2282
+msgid "correspondence (probably) not sent"
+msgstr "通知は(おそらく)送信されていません"
+
+#: lib/RT/Ticket_Overlay.pm:2292
+msgid "correspondence sent"
+msgstr "通知が送信されました"
+
+#: html/Admin/Elements/ModifyQueue:63 html/Admin/Queues/Modify.html:77 lib/RT/Date.pm:319
+msgid "days"
+msgstr "日"
+
+#: NOT FOUND IN SOURCE
+msgid "dead"
+msgstr ""
+
+#: html/Search/Listing.html:75
+msgid "delete"
+msgstr "削除"
+
+#: lib/RT/Queue_Overlay.pm:63
+msgid "deleted"
+msgstr "削除された"
+
+#: html/Search/Elements/PickRestriction:68
+msgid "does not match"
+msgstr "あいません"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:35
+msgid "doesn't contain"
+msgstr "含みません"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "equal to"
+msgstr "等しい"
+
+#: NOT FOUND IN SOURCE
+msgid "false"
+msgstr ""
+
+#: html/Elements/SelectAttachmentField:28
+msgid "filename"
+msgstr ""
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "greater than"
+msgstr "より大きい"
+
+#: lib/RT/Group_Overlay.pm:194
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "グループ'%1'"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "時間"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr "ID"
+
+#: html/Elements/SelectBoolean:32 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88
+msgid "is"
+msgstr "です"
+
+#: html/Elements/SelectBoolean:36 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:37 html/Search/Elements/PickRestriction:48 html/Search/Elements/PickRestriction:77 html/Search/Elements/PickRestriction:89
+msgid "isn't"
+msgstr "でない"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "less than"
+msgstr "より少ない"
+
+#: html/Search/Elements/PickRestriction:67
+msgid "matches"
+msgstr "合う"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "最低"
+
+#: html/Ticket/Update.html:66
+msgid "minutes"
+msgstr "分"
+
+#: bin/rt-commit-handler:765
+msgid "modifications\\n\\n"
+msgstr "修正\\n\\n"
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "月"
+
+#: lib/RT/Queue_Overlay.pm:58
+msgid "new"
+msgstr "新しい"
+
+#: html/Admin/Elements/EditScrips:43
+msgid "no value"
+msgstr ""
+
+#: html/Ticket/Elements/EditWatchers:28
+msgid "none"
+msgstr "なし"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "not equal to"
+msgstr "等しくない"
+
+#: NOT FOUND IN SOURCE
+msgid "notlike"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:59
+msgid "open"
+msgstr "開く"
+
+#: lib/RT/Group_Overlay.pm:199
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr "ユーザー '%2' のパーソナルグループ '%1' "
+
+#: lib/RT/Group_Overlay.pm:207
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr "キュー %1 %2"
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "rejected"
+msgstr "拒否されました"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "resolved"
+msgstr "分解されました"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr "秒"
+
+#: lib/RT/Queue_Overlay.pm:60
+msgid "stalled"
+msgstr "止まりました"
+
+#: lib/RT/Group_Overlay.pm:202
+#. ($self->Type)
+msgid "system %1"
+msgstr "システム %1"
+
+#: lib/RT/Group_Overlay.pm:213
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr "システムグループ '%1'"
+
+#: html/Elements/Error:42 html/SelfService/Error.html:42
+msgid "the calling component did not specify why"
+msgstr "呼び出しているコンポーネントがなぜ次のようなことが起こるのか特定できませんでした"
+
+#: lib/RT/Group_Overlay.pm:210
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr "チケット #%1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "true"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:216
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "undescripbed group %1"
+msgstr "表示されないグループ %1"
+
+#: lib/RT/Group_Overlay.pm:191
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr "ユーザー %1"
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr "週"
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr "テンプレート %1と"
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr "年"
+
+#: NOT FOUND IN SOURCE
+msgid "ニックネーム"
+msgstr ""
+
diff --git a/rt/lib/RT/I18N/nl.po b/rt/lib/RT/I18N/nl.po
new file mode 100644 (file)
index 0000000..0c35499
--- /dev/null
@@ -0,0 +1,4819 @@
+msgid ""
+msgstr ""
+"Language-Team: rt-devel <rt-devel@lists.fsck.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28
+msgid "#"
+msgstr "#"
+
+#: html/Admin/Queues/Scrip.html:55
+#. ($QueueObj->id)
+msgid "#%1"
+msgstr "" 
+#: html/Approvals/Elements/ShowDependency:50 html/Ticket/Display.html:26 html/Ticket/Display.html:30
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr "#%1: %2"
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr "%1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr "%1 %2 %3"
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr "%1 %2 %3 %4:%5:%6 %7"
+
+#: lib/RT/Ticket_Overlay.pm:3438 lib/RT/Transaction_Overlay.pm:559 lib/RT/Transaction_Overlay.pm:601
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 added"
+msgstr "%1 %2 toegevoegd"
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 %2 ago"
+msgstr "%1 %2 geleden"
+
+#: lib/RT/Ticket_Overlay.pm:3444 lib/RT/Transaction_Overlay.pm:566
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 changed to %3"
+msgstr "%1 %2 veranderd naar %3"
+
+#: lib/RT/Ticket_Overlay.pm:3441 lib/RT/Transaction_Overlay.pm:562 lib/RT/Transaction_Overlay.pm:607
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 deleted"
+msgstr "%1 %2 verwijderd"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 %2 of group %3"
+msgstr ""
+
+#: html/Admin/Elements/EditScrips:44 html/Admin/Elements/ListGlobalScrips:28
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 with template %3"
+msgstr "%1 %2 met sjabloon %3"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 this ticket\\n"
+msgstr "%1 (%2) %3 dit ticket\\n"
+
+#: html/Search/Listing.html:57
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr ""
+
+#: bin/rt-crontool:169 bin/rt-crontool:176 bin/rt-crontool:182
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - An argument to pass to %2"
+msgstr "%1 - Een argument om door te geven aan %2"
+
+#: bin/rt-crontool:185
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr "%1 - Uitvoer status herzieningen naar STDOUT"
+
+#: bin/rt-crontool:179
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr "%1 - Specificeer de actie module die u wenst te gebruiken"
+
+#: bin/rt-crontool:173
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr "%1 - Specificeer de conditie module die u wenst te gebruiken"
+
+#: bin/rt-crontool:166
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr "%1 - Specificeer de zoek module die u wenst te gebruiken"
+
+#: lib/RT/ScripAction_Overlay.pm:122
+#. ($self->Id)
+msgid "%1 ScripAction loaded"
+msgstr "%1 ScripAction geladen"
+
+#: lib/RT/Ticket_Overlay.pm:3471
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 added as a value for %2"
+msgstr "%1 toegevoegd als waarde voor %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on"
+msgstr "%1 aliassen hebben een TicketId nodig om mee te werken"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on "
+msgstr "%1 aliassen hebben een TicketId nodig om mee te werken"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on (from %2) %3"
+msgstr "%1 aliassen hebben een TicketId nodig om mee te werken (van %2) %3"
+
+#: lib/RT/Link_Overlay.pm:117 lib/RT/Link_Overlay.pm:124
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 appears to be a local object, but can't be found in the database"
+msgstr ""
+
+#: html/Ticket/Elements/ShowDates:52 lib/RT/Transaction_Overlay.pm:483
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 by %2"
+msgstr "%1 door %2"
+
+#: lib/RT/Transaction_Overlay.pm:537 lib/RT/Transaction_Overlay.pm:626 lib/RT/Transaction_Overlay.pm:635 lib/RT/Transaction_Overlay.pm:638
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 changed from %2 to %3"
+msgstr "%1 veranderd van %2 naar %3"
+
+#: lib/RT/Interface/Web.pm:857
+msgid "%1 could not be set to %2."
+msgstr "%1 kon niet veranderd worden naar %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr "%1 kon geen transactie initiëren (%2)"
+
+#: lib/RT/Ticket_Overlay.pm:2813
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr "%1 kon status niet veranderen naar opgelost. RT's Database zou inconsistent kunnen zijn"
+
+#: html/Elements/MyTickets:25
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr "De %1 hoogste prioriteit tickets die ik bezit..."
+
+#: html/Elements/MyRequests:25
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr "De %1 hoogste prioriteit tickets waarom ik verzocht heb..."
+
+#: bin/rt-crontool:161
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr "%1 is een gereedschap om te reageren op tickets van een extern rooster programma, zoals cron"
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr "%1 is niet langer een %2 voor deze rij"
+
+#: lib/RT/Ticket_Overlay.pm:1570
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr "%1 is niet langer een %2 voor dit ticket"
+
+#: lib/RT/Ticket_Overlay.pm:3527
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr "%1 is niet langer een waarde voor specifiek veld %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr "%1 is niet een geldig Rij id"
+
+#: html/Ticket/Elements/ShowBasics:36
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr "%1 min"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr "%1 niet afgebeeld"
+
+#: html/User/Elements/DelegateRights:76
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr "%1 rechten"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr "%1 gelukt\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr "%1 type onbekend voor $MessageId"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr "%1 type onbekend voor %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 was created without a CurrentUser\\n"
+msgstr ""
+
+#: lib/RT/Action/ResolveMembers.pm:42
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr "%1 zal alle leden van een opgelost groep ticket omzetten."
+
+#: NOT FOUND IN SOURCE
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:435
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr "%1: geen aanhechting gespecificeerd"
+
+#: html/Ticket/Elements/ShowTransaction:102
+#. ($size)
+msgid "%1b"
+msgstr "%1b"
+
+#: html/Ticket/Elements/ShowTransaction:99
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr "%1k"
+
+#: lib/RT/Ticket_Overlay.pm:1140
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr "'%1 is een ongeldige waarde voor status"
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr "'%1' onherkende actie. "
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete group member)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr ""
+
+#: html/Admin/Elements/EditQueueWatchers:29 html/Admin/Elements/EditScrips:35 html/Admin/Elements/EditTemplates:36 html/Admin/Groups/Members.html:52 html/Ticket/Elements/EditLinks:33 html/Ticket/Elements/EditPeople:46 html/User/Groups/Members.html:55
+msgid "(Check box to delete)"
+msgstr "(Vink hokje af om te verwijderen)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check boxes to delete)"
+msgstr ""
+
+#: html/Ticket/Create.html:178
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr "(Vul ticket ids of URLs in, gescheiden door spaties)"
+
+#: html/Admin/Queues/Modify.html:54 html/Admin/Queues/Modify.html:60
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(No Value)"
+msgstr "(Geen Waarde)"
+
+#: html/Admin/Elements/EditCustomFields:33 html/Admin/Elements/ListGlobalCustomFields:32
+msgid "(No custom fields)"
+msgstr ""
+
+#: html/Admin/Groups/Members.html:50 html/User/Groups/Members.html:53
+msgid "(No members)"
+msgstr "(Geen Leden)"
+
+#: html/Admin/Elements/EditScrips:32 html/Admin/Elements/ListGlobalScrips:32
+msgid "(No scrips)"
+msgstr "(Geen scrips)"
+
+#: html/Admin/Elements/EditTemplates:31
+msgid "(No templates)"
+msgstr ""
+
+#: html/Ticket/Update.html:85
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Stuurt een blinde carbon copy van deze herziening naar een comma gescheiden lijst van email adressen. Wie er toekomstige herzieningen zal ontvangen, zal <b>niet</b> veranderen.)"
+
+#: html/Ticket/Create.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr ""
+
+#: html/Ticket/Update.html:81
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Stuurt een carbon copy van deze herziening naar een comma gescheiden lijst van email adressen. Wie er toekomstige herzieningen zal ontvangen, zal <b>niet</b> veranderen.)"
+
+#: html/Ticket/Create.html:69
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr ""
+
+#: html/Admin/Groups/index.html:33 html/User/Groups/index.html:33
+msgid "(empty)"
+msgstr "(leeg)"
+
+#: html/Admin/Users/index.html:39
+msgid "(no name listed)"
+msgstr ""
+
+#: html/Elements/MyRequests:43 html/Elements/MyTickets:45
+msgid "(no subject)"
+msgstr "(geen onderwerp)"
+
+#: html/Admin/Elements/SelectRights:48 html/Elements/SelectCustomFieldValue:30 html/Ticket/Elements/EditCustomField:59 html/Ticket/Elements/ShowCustomFields:36 lib/RT/Transaction_Overlay.pm:536
+msgid "(no value)"
+msgstr "(geen waarde)"
+
+#: html/Ticket/Elements/EditLinks:116
+msgid "(only one ticket)"
+msgstr "(slechts één ticket)"
+
+#: html/Elements/MyRequests:52 html/Elements/MyTickets:55
+msgid "(pending approval)"
+msgstr "(wacht op goedkeuring)"
+
+#: html/Elements/MyRequests:54 html/Elements/MyTickets:57
+msgid "(pending other tickets)"
+msgstr "(wacht op andere tickets)"
+
+#: NOT FOUND IN SOURCE
+msgid "(requestor's group)"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:50
+msgid "(required)"
+msgstr "(verplicht)"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "(untitled)"
+msgstr "(zonder titel)"
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I own..."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I requested..."
+msgstr ""
+
+#: html/Ticket/Elements/ShowBasics:32
+msgid "<% $Ticket->Status%>"
+msgstr "<% $Ticket->Status%>"
+
+#: html/Elements/SelectTicketTypes:27
+msgid "<% $_ %>"
+msgstr "<% $_ %>"
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:26
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"Nieuw ticket in\">&nbsp;%1"
+
+#: NOT FOUND IN SOURCE
+msgid "??????"
+msgstr ""
+
+#: etc/initialdata:203
+msgid "A blank template"
+msgstr "Een leeg sjabloon"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Deleted"
+msgstr "ACE Verwijderd"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Loaded"
+msgstr "ACE Geladen"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be deleted"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be found"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:157 lib/RT/Principal_Overlay.pm:181
+msgid "ACE not found"
+msgstr "ACE niet gevonden"
+
+#: lib/RT/ACE_Overlay.pm:831
+msgid "ACEs can only be created and deleted."
+msgstr "ACEs kunnen allen gecreëerd of verwijderd worden."
+
+#: bin/rt-commit-handler:755
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr "Afbraak om ongewenste ticket aanpassing te voorkomen.\\n"
+
+#: html/User/Elements/Tabs:32
+msgid "About me"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:80
+msgid "Access control"
+msgstr "Toegangscontrole"
+
+#: html/Admin/Elements/EditScrip:57
+msgid "Action"
+msgstr "Actie"
+
+#: lib/RT/Scrip_Overlay.pm:147
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr "Actie %1 niet gevonden"
+
+#: bin/rt-crontool:123
+msgid "Action committed."
+msgstr "Actie uitgevoerd."
+
+#: bin/rt-crontool:119
+msgid "Action prepared..."
+msgstr "Actie voorbereid..."
+
+#: html/Search/Bulk.html:92
+msgid "Add AdminCc"
+msgstr "Voeg AdminCc toe"
+
+#: html/Search/Bulk.html:90
+msgid "Add Cc"
+msgstr "Voeg Cc toe"
+
+#: html/Ticket/Create.html:114 html/Ticket/Update.html:100
+msgid "Add More Files"
+msgstr "Voeg Meer Bestanden Toe"
+
+#: NOT FOUND IN SOURCE
+msgid "Add Next State"
+msgstr ""
+
+#: html/Search/Bulk.html:88
+msgid "Add Requestor"
+msgstr "Voeg Verzoeker Toe"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip to this queue"
+msgstr "Voeg een Scrip toe aan deze rij"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip which will apply to all queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a keyword selection to this queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr ""
+
+#: html/Admin/Global/Scrip.html:55
+msgid "Add a scrip which will apply to all queues"
+msgstr "Voeg een scrip toe welke voor alle rijen zal gelden"
+
+#: html/Search/Bulk.html:118
+msgid "Add comments or replies to selected tickets"
+msgstr "Voeg commentaar of reacties toe aan geselecteerde tickets"
+
+#: html/Admin/Groups/Members.html:42 html/User/Groups/Members.html:39
+msgid "Add members"
+msgstr "Voeg leden toe"
+
+#: html/Admin/Queues/People.html:66 html/Ticket/Elements/AddWatchers:28
+msgid "Add new watchers"
+msgstr "Voeg nieuwe toeschouwers toe"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr "VoegVolgendeStaatToe"
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr "Hoofd toegevoegd als %1 voor deze rij"
+
+#: lib/RT/Ticket_Overlay.pm:1454
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr "Hoofd toegevoegd als %1 voor dit ticket"
+
+#: html/Admin/Elements/ModifyUser:76 html/Admin/Users/Modify.html:122 html/User/Prefs.html:88
+msgid "Address1"
+msgstr "Adres1"
+
+#: html/Admin/Elements/ModifyUser:78 html/Admin/Users/Modify.html:127 html/User/Prefs.html:90
+msgid "Address2"
+msgstr "Adres2"
+
+#: html/Ticket/Create.html:74
+msgid "Admin Cc"
+msgstr "Beheerder Cc"
+
+#: etc/initialdata:274
+msgid "Admin Comment"
+msgstr ""
+
+#: etc/initialdata:256
+msgid "Admin Correspondence"
+msgstr ""
+
+#: html/Admin/Queues/index.html:25 html/Admin/Queues/index.html:28
+msgid "Admin queues"
+msgstr "Beheerder rijen"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr "Beheerder gebruikers"
+
+#: html/Admin/Global/index.html:26 html/Admin/Global/index.html:28
+msgid "Admin/Global configuration"
+msgstr "Beheerder/Globale configuratie"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr "Beheerder/Groepen"
+
+#: html/Admin/Queues/Modify.html:25 html/Admin/Queues/Modify.html:29
+msgid "Admin/Queue/Basics"
+msgstr "Beheerder/Rij/Basis"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr ""
+
+#: etc/initialdata:56 html/Ticket/Elements/ShowPeople:39 html/Ticket/Update.html:50 lib/RT/ACE_Overlay.pm:89
+msgid "AdminCc"
+msgstr "BeheerderCc"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr "BeheerderCommentaar"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr "BeheerderCorrespondentie"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "AdminCustomFields"
+msgstr "BeheerderSpecifiekeVelden"
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "AdminGroup"
+msgstr "BeheerderGroep"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "AdminGroupMembership"
+msgstr "BeheerderGroepLidmaatschap"
+
+#: lib/RT/System.pm:59
+msgid "AdminOwnPersonalGroups"
+msgstr "BeheerderBezitPersoonlijkeGroepen"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "AdminQueue"
+msgstr "BeheerderRij"
+
+#: lib/RT/System.pm:60
+msgid "AdminUsers"
+msgstr "BeheerderGebruikers"
+
+#: html/Admin/Queues/People.html:48 html/Ticket/Elements/EditPeople:54
+msgid "Administrative Cc"
+msgstr "Administratieve Cc"
+
+#: NOT FOUND IN SOURCE
+msgid "Admins"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr "Uitgebreid Zoeken"
+
+#: html/Elements/SelectDateRelation:36
+msgid "After"
+msgstr "Nadat"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr "Leeftijd"
+
+#: NOT FOUND IN SOURCE
+msgid "Alias"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Alias for"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:96
+msgid "All Custom Fields"
+msgstr ""
+
+#: html/Admin/Queues/index.html:53
+msgid "All Queues"
+msgstr "Alle Rijen"
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr "Stuurt altijd een bericht naar de verzoekers ongeacht de verzender van het bericht"
+
+#: html/Elements/Tabs:58
+msgid "Approval"
+msgstr "Goedkeuring"
+
+#: html/Approvals/Display.html:46 html/Approvals/Elements/Approve:27 html/Approvals/Elements/ShowDependency:42 html/Approvals/index.html:65
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr "Goedkeuring #%1: %2"
+
+#: html/Approvals/index.html:54
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr "Goedkeuring #%1: Notities niet bewaard vanwege een systeem fout"
+
+#: html/Approvals/index.html:52
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr "Goedkeuring #%1: Notities bewaard"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Details"
+msgstr "Goedkeuring Details"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval diagram"
+msgstr "Goedkeuring diagram"
+
+#: html/Approvals/Elements/Approve:45
+msgid "Approve"
+msgstr "Goedkeuring"
+
+#: etc/initialdata:431 etc/upgrade/2.1.71:148
+msgid "Approver's notes: %1"
+msgstr "Notities van de goedkeurer: %1"
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "Ggk."
+
+#: NOT FOUND IN SOURCE
+msgid "April"
+msgstr "april"
+
+#: html/Elements/SelectSortOrder:35
+msgid "Ascending"
+msgstr "Oplopend"
+
+#: html/Search/Bulk.html:127 html/SelfService/Update.html:36 html/Ticket/ModifyAll.html:83 html/Ticket/Update.html:100
+msgid "Attach"
+msgstr "Aanhechten"
+
+#: html/SelfService/Create.html:67 html/Ticket/Create.html:110
+msgid "Attach file"
+msgstr "Hecht bestand aan"
+
+#: html/Ticket/Create.html:98 html/Ticket/Update.html:89
+msgid "Attached file"
+msgstr "Aangehecht bestand"
+
+#: html/SelfService/Attachment/dhandler:36
+msgid "Attachment '%1' could not be loaded"
+msgstr "Aanhechting '%1' kon niet geladen worden"
+
+#: lib/RT/Transaction_Overlay.pm:443
+msgid "Attachment created"
+msgstr "Aanhechting gecreëerd"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "Aanhechting bestandsnaam"
+
+#: html/Ticket/Elements/ShowAttachments:26
+msgid "Attachments"
+msgstr "Aanhechtingen"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "aug."
+
+#: NOT FOUND IN SOURCE
+msgid "August"
+msgstr "augustus"
+
+#: html/Admin/Elements/ModifyUser:66
+msgid "AuthSystem"
+msgstr "AuthenticatieSysteem"
+
+#: etc/initialdata:206
+msgid "Autoreply"
+msgstr "Automatisch-antwoord"
+
+#: etc/initialdata:72
+msgid "Autoreply To Requestors"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr "Automatisch-antwoordAanVerzoekers"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr "Ongeldige PGP Signatuur: %1\\n"
+
+#: html/SelfService/Attachment/dhandler:40
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr "Ongeldig aanhechtings id. Kon aanhechting '%1' niet vinden\\n"
+
+#: bin/rt-commit-handler:827
+#. ($val)
+msgid "Bad data in %1"
+msgstr "Ongeldige data in %1"
+
+#: html/SelfService/Attachment/dhandler:43
+#. ($trans, $AttachmentObj->TransactionId())
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr "Ongeldig transactienummer voor aanhechting. %1 zou %2 moeten zijn\\n"
+
+#: html/Admin/Elements/GroupTabs:39 html/Admin/Elements/QueueTabs:39 html/Admin/Elements/UserTabs:38 html/Ticket/Elements/Tabs:90 html/User/Elements/GroupTabs:38
+msgid "Basics"
+msgstr "Basis"
+
+#: html/Ticket/Update.html:83
+msgid "Bcc"
+msgstr "Bcc"
+
+#: html/Admin/Elements/EditScrip:88 html/Admin/Global/GroupRights.html:85 html/Admin/Global/Template.html:46 html/Admin/Global/UserRights.html:54 html/Admin/Groups/GroupRights.html:73 html/Admin/Groups/Members.html:81 html/Admin/Groups/Modify.html:56 html/Admin/Groups/UserRights.html:55 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:45 html/Admin/Queues/UserRights.html:54 html/User/Groups/Modify.html:56
+msgid "Be sure to save your changes"
+msgstr "Zorg ervoor dat u uw veranderingen bewaard"
+
+#: html/Elements/SelectDateRelation:34 lib/RT/CurrentUser.pm:322
+msgid "Before"
+msgstr "Voorheen"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin Approval"
+msgstr "Begin Goedkeuring"
+
+#: etc/initialdata:202
+msgid "Blank"
+msgstr "Blanco"
+
+#: html/Search/Listing.html:79
+msgid "Bookmarkable URL for this search"
+msgstr "XXX URL voor deze zoekopdracht"
+
+#: html/Ticket/Elements/ShowHistory:39 html/Ticket/Elements/ShowHistory:45
+msgid "Brief headers"
+msgstr "Korte koppen"
+
+#: html/Search/Bulk.html:25 html/Search/Bulk.html:26
+msgid "Bulk ticket update"
+msgstr "Bulk ticketherziening"
+
+#: lib/RT/User_Overlay.pm:1331
+msgid "Can not modify system users"
+msgstr "Kan systeemgebruikers niet wijzigen"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Can this principal see this queue"
+msgstr "Kan dit hoofd deze rij zien"
+
+#: lib/RT/CustomFieLd_Overlay.pm:144
+msgid "Can't add a custom field value without a name"
+msgstr "Kan geen specifiek veld toevoegen zonder een naam"
+
+#: lib/RT/Link_Overlay.pm:132
+msgid "Can't link a ticket to itself"
+msgstr "Kan een ticket niet koppelen aan zichzelf"
+
+#: lib/RT/Ticket_Overlay.pm:2787
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr "Kan niet samenvoegen met een reeds samengevoegd ticket. U zou deze boodschap nooit mogen krijgen"
+
+#: lib/RT/Ticket_Overlay.pm:2605 lib/RT/Ticket_Overlay.pm:2674
+msgid "Can't specifiy both base and target"
+msgstr "Kan niet zowel basis als doel specificeren"
+
+#: html/autohandler:112
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr "Kan gebruiker %1 niet aanmaken"
+
+#: etc/initialdata:50 html/Admin/Queues/People.html:44 html/SelfService/Create.html:51 html/SelfService/Display.html:50 html/Ticket/Create.html:64 html/Ticket/Elements/EditPeople:51 html/Ticket/Elements/ShowPeople:35 html/Ticket/Update.html:45 html/Ticket/Update.html:78 lib/RT/ACE_Overlay.pm:88
+msgid "Cc"
+msgstr "Cc"
+
+#: html/SelfService/Prefs.html:31
+msgid "Change password"
+msgstr "Wijzig wachtwoord"
+
+#: html/Ticket/Create.html:101 html/Ticket/Update.html:92
+msgid "Check box to delete"
+msgstr "Vink hokje af om te verwijderen"
+
+#: html/Admin/Elements/SelectRights:31
+msgid "Check box to revoke right"
+msgstr "Vink hokje af om recht te verwijderen"
+
+#: html/Ticket/Create.html:183 html/Ticket/Elements/EditLinks:131 html/Ticket/Elements/EditLinks:69 html/Ticket/Elements/ShowLinks:51
+msgid "Children"
+msgstr "Kinderen"
+
+#: html/Admin/Elements/ModifyUser:80 html/Admin/Users/Modify.html:132 html/User/Prefs.html:92
+msgid "City"
+msgstr "Stad"
+
+#: html/Ticket/Elements/ShowDates:47
+msgid "Closed"
+msgstr ""
+
+#: html/SelfService/Elements/Tabs:60
+msgid "Closed requests"
+msgstr "Gesloten verzoeken"
+
+#: NOT FOUND IN SOURCE
+msgid "Code"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr "Commando niet begrepen!\\n"
+
+#: html/Ticket/Elements/ShowTransaction:179 html/Ticket/Elements/Tabs:153
+msgid "Comment"
+msgstr "Commentaar"
+
+#: html/Admin/Elements/ModifyQueue:45 html/Admin/Queues/Modify.html:58
+msgid "Comment Address"
+msgstr "Commentaar Adres"
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr "Commentaar niet bewaard"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Comment on tickets"
+msgstr "Commentaar op tickets"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "CommentOnTicket"
+msgstr "CommentaarOpTicket"
+
+#: html/Admin/Elements/ModifyUser:35
+msgid "Comments"
+msgstr "Commentaar"
+
+#: html/Ticket/ModifyAll.html:70 html/Ticket/Update.html:70
+msgid "Comments (Not sent to requestors)"
+msgstr "Commentaar (Wordt niet verstuurd aan verzoekers)"
+
+#: html/Search/Bulk.html:122
+msgid "Comments (not sent to requestors)"
+msgstr "Commentaar (Wordt niet verstuurd aan verzoekers)"
+
+#: html/Elements/ViewUser:27
+#. ($name)
+msgid "Comments about %1"
+msgstr "Commentaar over %1"
+
+#: html/Admin/Users/Modify.html:185 html/Ticket/Elements/ShowRequestor:44
+msgid "Comments about this user"
+msgstr "Commentaar over deze gebruiker"
+
+#: lib/RT/Transaction_Overlay.pm:545
+msgid "Comments added"
+msgstr "Commentaar toegevoegd"
+
+#: lib/RT/Action/Generic.pm:140
+msgid "Commit Stubbed"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr "Compilatie Restricties"
+
+#: html/Admin/Elements/EditScrip:41
+msgid "Condition"
+msgstr "Voorwaarde"
+
+#: bin/rt-crontool:109
+msgid "Condition matches..."
+msgstr "Voorwaarde komt overeen..."
+
+#: lib/RT/Scrip_Overlay.pm:160
+msgid "Condition not found"
+msgstr "Voorwaarde niet gevonden"
+
+#: html/Elements/Tabs:52
+msgid "Configuration"
+msgstr "Configuratie"
+
+#: html/SelfService/Prefs.html:33
+msgid "Confirm"
+msgstr "Bevestig"
+
+#: html/Admin/Elements/ModifyUser:60
+msgid "ContactInfoSystem"
+msgstr "ContactInfoSysteem"
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr "Contact datum '%1' kon niet ontleed worden"
+
+#: html/Admin/Elements/ModifyTemplate:44 html/Ticket/ModifyAll.html:87
+msgid "Content"
+msgstr "Inhoud"
+
+#: NOT FOUND IN SOURCE
+msgid "Coould not create group"
+msgstr ""
+
+#: etc/initialdata:266
+msgid "Correspondence"
+msgstr "Correspondentie"
+
+#: html/Admin/Elements/ModifyQueue:39 html/Admin/Queues/Modify.html:51
+msgid "Correspondence Address"
+msgstr "Correspondentieadres"
+
+#: lib/RT/Transaction_Overlay.pm:541
+msgid "Correspondence added"
+msgstr "Correspondentie toegevoegd"
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr "Correspondentie niet bewaard"
+
+#: lib/RT/Ticket_Overlay.pm:3458
+msgid "Could not add new custom field value for ticket. "
+msgstr "Kon nieuw specifiek veld niet toevoegen voor dit ticket. "
+
+#: NOT FOUND IN SOURCE
+msgid "Could not add new custom field value for ticket. %1 "
+msgstr "Kon nieuw specifiek veld niet toevoegen voor dit ticket. %1"
+
+#: lib/RT/Ticket_Overlay.pm:2963 lib/RT/Ticket_Overlay.pm:2971 lib/RT/Ticket_Overlay.pm:2987
+msgid "Could not change owner. "
+msgstr "Kon eigenaar niet wijzigen. "
+
+#: html/Admin/Elements/EditCustomField:68 html/Admin/Elements/EditCustomFields:166
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr "Kon SpecifiekVeld niet creëren"
+
+#: html/User/Groups/Modify.html:77 lib/RT/Group_Overlay.pm:474 lib/RT/Group_Overlay.pm:481
+msgid "Could not create group"
+msgstr "Kon groep niet creëren"
+
+#: html/Admin/Global/Template.html:75 html/Admin/Queues/Template.html:72
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr "Kon sjabloon niet creëren: %1"
+
+#: lib/RT/Ticket_Overlay.pm:1073 lib/RT/Ticket_Overlay.pm:333
+msgid "Could not create ticket. Queue not set"
+msgstr "Kon ticket niet creëren. Rij niet ingesteld"
+
+#: lib/RT/User_Overlay.pm:208 lib/RT/User_Overlay.pm:220 lib/RT/User_Overlay.pm:238 lib/RT/User_Overlay.pm:414
+msgid "Could not create user"
+msgstr "Kon gebruiker niet creëren"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not create watcher for requestor"
+msgstr "Kon toeschouwer niet creëren voor verzoeker"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr "Kon geen ticket vinden met id %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr "Kon groep %1 niet vinden. "
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1422
+msgid "Could not find or create that user"
+msgstr "Kon deze gebruiker niet vinden of creëren"
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1501
+msgid "Could not find that principal"
+msgstr "Kon dat hoofd niet vinden"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr "Kon gebruiker %1 niet vinden."
+
+#: html/Admin/Groups/Members.html:88 html/User/Groups/Members.html:90 html/User/Groups/Modify.html:82
+msgid "Could not load group"
+msgstr "Kon groep niet laden"
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr "Kon dat hoofd geen %1 maken voor deze rij"
+
+#: lib/RT/Ticket_Overlay.pm:1443
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr "Kon dat hoofd geen %1 maken voor dit ticket"
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr "Kon dat hoofd niet verwijderen als %1 voor deze rij"
+
+#: lib/RT/Ticket_Overlay.pm:1559
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr "Kon dat hoofd niet verwijderen als %1 voor dit ticket"
+
+#: lib/RT/Group_Overlay.pm:985
+msgid "Couldn't add member to group"
+msgstr "Kon lid niet toevoegen aan groep"
+
+#: lib/RT/Ticket_Overlay.pm:3468 lib/RT/Ticket_Overlay.pm:3524
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr "Kon geen transactie creëren: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr "Kon niet bepalen welke actie te ondernemen aan de hand van gpg's antwoord\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr "Kon groep niet vinden\\n"
+
+#: lib/RT/Interface/Web.pm:866
+msgid "Couldn't find row"
+msgstr "Kon rij niet vinden"
+
+#: lib/RT/Group_Overlay.pm:959
+msgid "Couldn't find that principal"
+msgstr "Kon dat hoofd niet vinden"
+
+#: lib/RT/CustomField_Overlay.pm:175
+msgid "Couldn't find that value"
+msgstr "Kon die waarde niet vinden"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find that watcher"
+msgstr "Kon die toeschouwer niet vinden"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr "Kon gebruiker niet vinden\\n"
+
+#: lib/RT/CurrentUser.pm:112
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr "Kon %1 niet laden uit de gebruikersdatabase.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load KeywordSelects."
+msgstr "Kon KeywordSelects niet laden."
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr "Kon RT configuratie bestand niet laden '%1' %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr "Kon Scrips niet laden"
+
+#: html/Admin/Groups/GroupRights.html:88 html/Admin/Groups/UserRights.html:75
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr "Kon groep %1 niet laden"
+
+#: lib/RT/Link_Overlay.pm:175 lib/RT/Link_Overlay.pm:184 lib/RT/Link_Overlay.pm:211
+msgid "Couldn't load link"
+msgstr "Kon link niet laden"
+
+#: html/Admin/Elements/EditCustomFields:147 html/Admin/Queues/People.html:121
+#. ($id)
+msgid "Couldn't load queue"
+msgstr "Kon rij niet laden"
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:72
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr "Kon rij %1 niet laden "
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr "Kon scrip niet laden"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr "Kon sjabloon niet laden"
+
+#: html/Admin/Users/Prefs.html:79
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr "Kon die gebruiker (%1) niet laden"
+
+#: html/SelfService/Display.html:166
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr "Kon ticket '%1' niet laden"
+
+#: html/Admin/Elements/ModifyUser:86 html/Admin/Users/Modify.html:149 html/User/Prefs.html:98
+msgid "Country"
+msgstr "Land"
+
+#: html/Admin/Elements/CreateUserCalled:26 html/Ticket/Create.html:135 html/Ticket/Create.html:195
+msgid "Create"
+msgstr "Creëer"
+
+#: etc/initialdata:128
+msgid "Create Tickets"
+msgstr "Creëer Tickets"
+
+#: html/Admin/Elements/EditCustomField:58
+msgid "Create a CustomField"
+msgstr "Creëer een SpecifiekVeld"
+
+#: html/Admin/Queues/CustomField.html:48
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:48
+msgid "Create a CustomField which applies to all queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr "Creëer een niuew Specifiek Veld"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global Scrip"
+msgstr "Creëer een nieuw globaal Scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:67 html/Admin/Groups/Modify.html:93
+msgid "Create a new group"
+msgstr "Creëer een nieuwe groep"
+
+#: html/User/Groups/Modify.html:67 html/User/Groups/Modify.html:92
+msgid "Create a new personal group"
+msgstr "Creëer een nieuwe persoonlijke groep"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr "Creëer een nieuwe rij"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr "Creëer een nieuw scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr "Creëer een nieuw template"
+
+#: html/SelfService/Create.html:30 html/Ticket/Create.html:25 html/Ticket/Create.html:28 html/Ticket/Create.html:36
+msgid "Create a new ticket"
+msgstr "Creëer een nieuw ticket"
+
+#: html/Admin/Users/Modify.html:214 html/Admin/Users/Modify.html:241
+msgid "Create a new user"
+msgstr "Creëer een nieuwe gebruiker"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "Creëer een rij"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr "Creëer een rij genaamd"
+
+#: html/SelfService/Create.html:25 html/SelfService/Create.html:27
+msgid "Create a request"
+msgstr "Creëer een verzoek"
+
+#: html/Admin/Queues/Scrip.html:59
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr "Creëer een scrip voor rij %1"
+
+#: html/Admin/Global/Template.html:69 html/Admin/Queues/Template.html:65
+msgid "Create a template"
+msgstr "Creëer een sjabloon"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1 / %2 / %3 "
+msgstr "Creatie mislukt: %1 / %2 / %3 "
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1/%2/%3"
+msgstr ""
+
+#: etc/initialdata:130
+msgid "Create new tickets based on this scrip's template"
+msgstr "Creëer nieuwe tickets gebaseerd op het sjabloon van dit scrip"
+
+#: html/SelfService/Create.html:81
+msgid "Create ticket"
+msgstr "Creëer ticket"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Create tickets in this queue"
+msgstr "Creëer tickets in deze rij"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Create, delete and modify custom fields"
+msgstr "Creëer, verwijder en wijzig specifieke velden"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Create, delete and modify queues"
+msgstr "Creëer, verwijder en wijzig rijen"
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr ""
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify the members of personal groups"
+msgstr "Creëer, verwijder en wijzig de leden van persoonlijke groepen"
+
+#: lib/RT/System.pm:60
+msgid "Create, delete and modify users"
+msgstr "Creëer, verwijder en wijzig gebruikers"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "CreateTicket"
+msgstr "CreëerTicket"
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1167
+msgid "Created"
+msgstr "Gecreëerd"
+
+#: html/Admin/Elements/EditCustomField:71
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr "SpecifiekVeld %1 gecreëerd"
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr "Sjabloon %1 Gecreëerd"
+
+#: html/Ticket/Elements/EditLinks:28
+msgid "Current Relationships"
+msgstr "Huidige Relaties"
+
+#: html/Admin/Elements/EditScrips:30
+msgid "Current Scrips"
+msgstr "Huidige Scrips"
+
+#: html/Admin/Groups/Members.html:39 html/User/Groups/Members.html:42
+msgid "Current members"
+msgstr "Huidige leden"
+
+#: html/Admin/Elements/SelectRights:29
+msgid "Current rights"
+msgstr "Huidige rechten"
+
+#: html/Search/Listing.html:71
+msgid "Current search criteria"
+msgstr ""
+
+#: html/Admin/Queues/People.html:41 html/Ticket/Elements/EditPeople:45
+msgid "Current watchers"
+msgstr "Huidige toeschouwers"
+
+#: html/Admin/Global/CustomField.html:55
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:53 html/Admin/Elements/SystemTabs:40 html/Admin/Global/index.html:50 html/Ticket/Elements/ShowSummary:35
+msgid "Custom Fields"
+msgstr "Specifieke Velden"
+
+#: html/Admin/Elements/EditScrip:73
+msgid "Custom action cleanup code"
+msgstr "Specifieke actie opruim code"
+
+#: html/Admin/Elements/EditScrip:65
+msgid "Custom action preparation code"
+msgstr "Specifieke actie voorbereidings code"
+
+#: html/Admin/Elements/EditScrip:49
+msgid "Custom condition"
+msgstr "Specifieke voorwaarde"
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr "Specifiek veld %1 %2 %3"
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr "Specifiek veld %1 heeft een waarde."
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr "Specifiek veld %1 heeft geen waarde."
+
+#: lib/RT/Ticket_Overlay.pm:3360
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr "Specifiek veld %1 niet gevonden"
+
+#: html/Admin/Elements/EditCustomFields:197
+msgid "Custom field deleted"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3510
+msgid "Custom field not found"
+msgstr "Specifiek veld niet gevonden"
+
+#: lib/RT/CustomField_Overlay.pm:283
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr "Specifiek veld waarde %1 kon niet gevonden worden voor specifiek veld %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr "Specifiek veld waarde veranderd van %1 naar %2"
+
+#: lib/RT/CustomField_Overlay.pm:185
+msgid "Custom field value could not be deleted"
+msgstr "Specifiek veld waarde kon niet verwijderd worden"
+
+#: lib/RT/CustomField_Overlay.pm:289
+msgid "Custom field value could not be found"
+msgstr "Specifiek veld waarde kon niet gevonden worden"
+
+#: lib/RT/CustomField_Overlay.pm:183 lib/RT/CustomField_Overlay.pm:291
+msgid "Custom field value deleted"
+msgstr "Specifiek veld waarde verwijderd"
+
+#: lib/RT/Transaction_Overlay.pm:550
+msgid "CustomField"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Data error"
+msgstr "Data fout"
+
+#: html/Ticket/Create.html:161 html/Ticket/Elements/ShowSummary:53 html/Ticket/Elements/Tabs:93 html/Ticket/ModifyAll.html:44
+msgid "Dates"
+msgstr "Data"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "dec."
+
+#: NOT FOUND IN SOURCE
+msgid "December"
+msgstr "december"
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr "Standaard Auto-antwoord Sjabloon"
+
+#: etc/initialdata:207
+msgid "Default Autoresponse template"
+msgstr ""
+
+#: etc/initialdata:275
+msgid "Default admin comment template"
+msgstr "Standaard admin commentaar sjabloon"
+
+#: etc/initialdata:257
+msgid "Default admin correspondence template"
+msgstr "Standaard admin correspondentie sjabloon"
+
+#: etc/initialdata:267
+msgid "Default correspondence template"
+msgstr "Standaard correspondentie sjabloon"
+
+#: etc/initialdata:238
+msgid "Default transaction template"
+msgstr "Standaard transactie sjabloon"
+
+#: lib/RT/Transaction_Overlay.pm:645
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr "Standaard: %1/%2 verandered van %3 naar %4"
+
+#: html/User/Delegation.html:25 html/User/Delegation.html:28
+msgid "Delegate rights"
+msgstr "Delegeer rechten"
+
+#: lib/RT/System.pm:63
+msgid "Delegate specific rights which have been granted to you."
+msgstr "Delegeer specifieke rechten die aan u verleend zijn."
+
+#: lib/RT/System.pm:63
+msgid "DelegateRights"
+msgstr "DelegeerRechten"
+
+#: html/User/Elements/Tabs:38
+msgid "Delegation"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Delete"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "Delete tickets"
+msgstr "Verwijder tickets"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "DeleteTicket"
+msgstr "VerwijderTicket"
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr "Het verwijderen van dit object zou de referentiële integriteit kunnen ondermijnen"
+
+#: lib/RT/Queue_Overlay.pm:292
+msgid "Deleting this object would break referential integrity"
+msgstr "Het verwijderen van dit object zou de referentiële integriteit ondermijnen"
+
+#: lib/RT/User_Overlay.pm:430
+msgid "Deleting this object would violate referential integrity"
+msgstr "Het verwijderen van dit object zou de referentiële integriteit ondermijnen"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity."
+msgstr "Het verwijderen van dit object zou de referentiële integriteit ondermijnen"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity. That's bad."
+msgstr ""
+
+#: html/Approvals/Elements/Approve:46
+msgid "Deny"
+msgstr "Wijs af"
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/EditLinks:123 html/Ticket/Elements/EditLinks:47 html/Ticket/Elements/ShowDependencies:32 html/Ticket/Elements/ShowLinks:35
+msgid "Depended on by"
+msgstr "Afhankelijkheid van"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr "Afhankelijkheden: \\n"
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:180 html/Ticket/Elements/EditLinks:119 html/Ticket/Elements/EditLinks:36 html/Ticket/Elements/ShowDependencies:25 html/Ticket/Elements/ShowLinks:27
+msgid "Depends on"
+msgstr "Is afhankelijk van"
+
+#: NOT FOUND IN SOURCE
+msgid "DependsOn"
+msgstr ""
+
+#: html/Elements/SelectSortOrder:35
+msgid "Descending"
+msgstr "Aflopend"
+
+#: html/SelfService/Create.html:75 html/Ticket/Create.html:119
+msgid "Describe the issue below"
+msgstr "Omschrijf onderstaande kwestie"
+
+#: html/Admin/Elements/AddCustomFieldValue:27 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/EditScrip:34 html/Admin/Elements/ModifyQueue:36 html/Admin/Elements/ModifyTemplate:36 html/Admin/Groups/Modify.html:49 html/Admin/Queues/Modify.html:48 html/Elements/SelectGroups:27 html/User/Groups/Modify.html:49
+msgid "Description"
+msgstr "Omschrijving"
+
+#: html/SelfService/Elements/MyRequests:44
+msgid "Details"
+msgstr "Details"
+
+#: html/Ticket/Elements/Tabs:85
+msgid "Display"
+msgstr "Toon"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Display Access Control List"
+msgstr "Toon Toegangs Controle Lijst"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Display Scrip templates for this queue"
+msgstr "Toon Scrip sjablonen voor deze rij"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Display Scrips for this queue"
+msgstr "Toon Scrips voor deze rij"
+
+#: html/Ticket/Elements/ShowHistory:35
+msgid "Display mode"
+msgstr "Toon modus"
+
+#: html/SelfService/Display.html:25 html/SelfService/Display.html:29
+#. ($Ticket->id)
+msgid "Display ticket #%1"
+msgstr "Toon ticket #%1"
+
+#: lib/RT/System.pm:54
+msgid "Do anything and everything"
+msgstr "Doe iets en alles"
+
+#: html/Elements/Refresh:30
+msgid "Don't refresh this page."
+msgstr "Ververs deze pagina niet"
+
+#: html/Search/Elements/PickRestriction:114
+msgid "Don't show search results"
+msgstr ""
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "Download"
+msgstr "Download"
+
+#: html/Elements/SelectDateType:32 html/Ticket/Create.html:167 html/Ticket/Elements/EditDates:45 html/Ticket/Elements/ShowDates:43 lib/RT/Ticket_Overlay.pm:1171
+msgid "Due"
+msgstr "Verwacht"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr "Verwachte datum '%1' kon niet ontleed worden"
+
+#: bin/rt-commit-handler:754
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr "FOUT: Kon ticket '%1' niet laden: %2.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit"
+msgstr "Wijzig"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit Conditions"
+msgstr ""
+
+#: html/Admin/Queues/CustomFields.html:45
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr "Wijzig Specifieke Velden voor %1"
+
+#: html/Ticket/ModifyLinks.html:36
+msgid "Edit Relationships"
+msgstr "Wijzig Relaties"
+
+#: html/Admin/Queues/Templates.html:41
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit keywords"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr ""
+
+#: html/Admin/Global/index.html:46
+msgid "Edit system templates"
+msgstr "Wijzig systeem sjablonen"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr "Wijzig sjablonen voor %1"
+
+#: html/Admin/Elements/ModifyQueue:25 html/Admin/Queues/Modify.html:117
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr "Bezig met wijzigen van de configuratie voor rij %1"
+
+#: html/Admin/Elements/ModifyUser:25
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr "Bezit met het wijzigen van de configuratie voor gebruiker %1"
+
+#: html/Admin/Elements/EditCustomField:74
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr "Bezit met het wijzigen van SpecifiekVeld %1"
+
+#: html/Admin/Groups/Members.html:32
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr "Bezit met het wijzigen van lidmaatschap voor groep %1"
+
+#: html/User/Groups/Members.html:129
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr "Bezit met het wijzigen van lidmaatschap voor persoonlijke groep %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr "Bezit met het wijzigen van sjabloon %1"
+
+#: lib/RT/Ticket_Overlay.pm:2615 lib/RT/Ticket_Overlay.pm:2683
+msgid "Either base or target must be specified"
+msgstr "Of basis of doel moeten gespecificeerd zijn"
+
+#: html/Admin/Users/Modify.html:53 html/Admin/Users/Prefs.html:46 html/Elements/SelectUsers:27 html/Ticket/Elements/AddWatchers:56 html/User/Prefs.html:42
+msgid "Email"
+msgstr "E-mail"
+
+#: lib/RT/User_Overlay.pm:188
+msgid "Email address in use"
+msgstr "E-mailadres in gebruik"
+
+#: html/Admin/Elements/ModifyUser:42
+msgid "EmailAddress"
+msgstr "E-mailAdres"
+
+#: html/Admin/Elements/ModifyUser:54
+msgid "EmailEncoding"
+msgstr "E-mailCodering"
+
+#: html/Admin/Elements/EditCustomField:36
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:53 html/User/Groups/Modify.html:53
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr ""
+
+#: html/Admin/Queues/Modify.html:84
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr "Actief (Het uitvinken van dit hokje zal deze rij deactiveren)"
+
+#: html/Admin/Elements/EditCustomFields:99
+msgid "Enabled Custom Fields"
+msgstr ""
+
+#: html/Admin/Queues/index.html:56
+msgid "Enabled Queues"
+msgstr "Actieve Rijen"
+
+#: html/Admin/Elements/EditCustomField:90 html/Admin/Groups/Modify.html:117 html/Admin/Queues/Modify.html:138 html/Admin/Users/Modify.html:283 html/User/Groups/Modify.html:117
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr "Actieve status %1"
+
+#: lib/RT/CustomField_Overlay.pm:361
+msgid "Enter multiple values"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:358
+msgid "Enter one value"
+msgstr ""
+
+#: html/Ticket/Elements/EditLinks:112
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "Vul tickets of URIs in om deze tickets aan te koppelen. Scheidt meerdere elementen met spaties."
+
+#: html/Elements/Login:29 html/SelfService/Error.html:25 html/SelfService/Error.html:26
+msgid "Error"
+msgstr "Fout"
+
+#: NOT FOUND IN SOURCE
+msgid "Error adding watcher"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr "Fout in paramaters naar Queue->AddWatcher"
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr "Fout in paramaters naar Queue->DelWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1356
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr "Fout in paramaters naar Ticket->AddWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1532
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr "Fout in paramaters naar Ticket->DelWatcher"
+
+#: etc/initialdata:20
+msgid "Everyone"
+msgstr "Iedereen"
+
+#: bin/rt-crontool:194
+msgid "Example:"
+msgstr "Voorbeeld:"
+
+#: html/Admin/Elements/ModifyUser:64
+msgid "ExternalAuthId"
+msgstr "ExternAuteurId"
+
+#: html/Admin/Elements/ModifyUser:58
+msgid "ExternalContactInfoId"
+msgstr "ExternContactInfoId"
+
+#: html/Admin/Users/Modify.html:73
+msgid "Extra info"
+msgstr "Extra informatie"
+
+#: lib/RT/User_Overlay.pm:302
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr "Kon de gebruikers pseudogroep 'Privileged' niet vinden."
+
+#: lib/RT/User_Overlay.pm:309
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr "Kon de gebruikers pseudogroep 'Unprivileged' niet vinden."
+
+#: bin/rt-crontool:138
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr "Kon module %1 niet laden. (%2)"
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "feb."
+
+#: NOT FOUND IN SOURCE
+msgid "February"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr ""
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:59 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "Uiteindelijke Prioriteit"
+
+#: lib/RT/Ticket_Overlay.pm:1162
+msgid "FinalPriority"
+msgstr "UiteindelijkePrioriteit"
+
+#: html/Admin/Queues/People.html:61 html/Ticket/Elements/EditPeople:34
+msgid "Find group whose"
+msgstr ""
+
+#: html/Elements/Quicksearch:25
+msgid "Find new/open tickets"
+msgstr "Zoek nieuwe/open tickets"
+
+#: html/Admin/Queues/People.html:57 html/Admin/Users/index.html:46 html/Ticket/Elements/EditPeople:30
+msgid "Find people whose"
+msgstr "Zoek mensen wier"
+
+#: html/Search/Listing.html:108
+msgid "Find tickets"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Finish Approval"
+msgstr "Beëindig Goedkeuring"
+
+#: html/Ticket/Elements/Tabs:58
+msgid "First"
+msgstr "Eerste"
+
+#: html/Search/Listing.html:41
+msgid "First page"
+msgstr "Eerste pagina"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr "Aap Noot Mies"
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr "Aap!"
+
+#: html/Search/Bulk.html:87
+msgid "Force change"
+msgstr ""
+
+#: html/Search/Listing.html:106
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:868
+msgid "Found Object"
+msgstr "Gevonden Object"
+
+#: html/Admin/Elements/ModifyUser:44
+msgid "FreeformContactInfo"
+msgstr "VrijevormContactInfo"
+
+#: lib/RT/CustomField_Overlay.pm:38
+msgid "FreeformMultiple"
+msgstr "VrijevormMeerdere"
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformSingle"
+msgstr ""
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "Vr."
+
+#: html/Ticket/Elements/ShowHistory:41 html/Ticket/Elements/ShowHistory:51
+msgid "Full headers"
+msgstr "Volledige Kop"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr "Bezig met het ophalen van de huidige gebruiker middels een pgp handtekening"
+
+#: lib/RT/Transaction_Overlay.pm:595
+#. ($New->Name)
+msgid "Given to %1"
+msgstr "Aan %1 gegeven"
+
+#: html/Admin/Elements/Tabs:41 html/Admin/index.html:38
+msgid "Global"
+msgstr "Globaal"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Keyword Selections"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr ""
+
+#: html/Admin/Elements/SelectTemplate:38
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr "Globaal sjabloon: %1"
+
+#: html/Admin/Elements/EditCustomFields:75 html/Admin/Queues/People.html:59 html/Admin/Queues/People.html:63 html/Admin/Queues/index.html:44 html/Admin/Users/index.html:49 html/Ticket/Elements/EditPeople:32 html/Ticket/Elements/EditPeople:36 html/index.html:41
+msgid "Go!"
+msgstr "Ga!"
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr "Goede pgp handtekening van %1\\n"
+
+#: html/Search/Listing.html:50
+msgid "Goto page"
+msgstr "Ga naar pagina"
+
+#: html/Elements/GotoTicket:25 html/SelfService/Elements/GotoTicket:25
+msgid "Goto ticket"
+msgstr "Ga naar ticket"
+
+#: NOT FOUND IN SOURCE
+msgid "Grand"
+msgstr ""
+
+#: html/Ticket/Elements/AddWatchers:46 html/User/Elements/DelegateRights:78
+msgid "Group"
+msgstr "Groep"
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr "Groep %1 %2: %3"
+
+#: html/Admin/Elements/GroupTabs:45 html/Admin/Elements/QueueTabs:57 html/Admin/Elements/SystemTabs:44 html/Admin/Global/index.html:55
+msgid "Group Rights"
+msgstr "Groeps rechten"
+
+#: lib/RT/Group_Overlay.pm:965
+msgid "Group already has member"
+msgstr "Groep heeft al een lid"
+
+#: NOT FOUND IN SOURCE
+msgid "Group could not be created."
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:77
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr "Groep kon niet gecreërd worden: %1"
+
+#: lib/RT/Group_Overlay.pm:497
+msgid "Group created"
+msgstr "Groep gecreërd"
+
+#: lib/RT/Group_Overlay.pm:1133
+msgid "Group has no such member"
+msgstr "Groep heeft geen lid onder die naam"
+
+#: lib/RT/Group_Overlay.pm:945 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1429 lib/RT/Ticket_Overlay.pm:1507
+msgid "Group not found"
+msgstr "Groep niet gevonden"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr "Groep niet gevonden.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr "Groep niet gespecificeerd.\\n"
+
+#: html/Admin/Elements/SelectNewGroupMembers:35 html/Admin/Elements/Tabs:35 html/Admin/Groups/Members.html:64 html/Admin/Queues/People.html:83 html/Admin/index.html:32 html/User/Groups/Members.html:67
+msgid "Groups"
+msgstr "Groepen"
+
+#: lib/RT/Group_Overlay.pm:971
+msgid "Groups can't be members of their members"
+msgstr "Groepen kunnen geen leden zijn van hun leden"
+
+#: lib/RT/Interface/CLI.pm:73 lib/RT/Interface/CLI.pm:73
+msgid "Hello!"
+msgstr "Hallo!"
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr "Hallo, %1"
+
+#: html/Ticket/Elements/ShowHistory:30 html/Ticket/Elements/Tabs:88
+msgid "History"
+msgstr "Geschiedenis"
+
+#: html/Admin/Elements/ModifyUser:68
+msgid "HomePhone"
+msgstr "ThuisNummer"
+
+#: html/Elements/Tabs:46
+msgid "Homepage"
+msgstr "Homepage"
+
+#: lib/RT/Base.pm:74
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "I have [quant,_1,concrete mixer]."
+msgstr ""
+
+#: html/Ticket/Elements/ShowBasics:27 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr "Id"
+
+#: html/Admin/Users/Modify.html:44 html/User/Prefs.html:39
+msgid "Identity"
+msgstr "Identiteit"
+
+#: etc/upgrade/2.1.71:86
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr "Als een goedkeuring afgewezen is, wijs het origineel af en verwijder hangende goedkeuringen"
+
+#: bin/rt-crontool:190
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr "Als dit gereedschap setgid zou zijn, zou een kwaadwillende lokale gebruiker dit gereedschap kunnen gebruiken om administratieve toegang te verkrijgen tot RT"
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "If you've updated anything above, be sure to"
+msgstr "Als u een van de bovenstaande elemented ververst heeft, zorg dan dat u"
+
+#: lib/RT/Interface/Web.pm:860
+msgid "Illegal value for %1"
+msgstr "Illegale waarde voor %1"
+
+#: lib/RT/Interface/Web.pm:863
+msgid "Immutable field"
+msgstr "Niet-wijzigbaar veld"
+
+#: html/Admin/Elements/EditCustomFields:74
+msgid "Include disabled custom fields in listing."
+msgstr ""
+
+#: html/Admin/Queues/index.html:43
+msgid "Include disabled queues in listing."
+msgstr "Neem inactieve rijen op in de weergave"
+
+#: html/Admin/Users/index.html:47
+msgid "Include disabled users in search."
+msgstr "Neem inactieve gebruiker op in de zoek opdracht"
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr "Initiële Prioriteit"
+
+#: lib/RT/Ticket_Overlay.pm:1161 lib/RT/Ticket_Overlay.pm:1163
+msgid "InitialPriority"
+msgstr "InitiëlePrioriteit"
+
+#: lib/RT/ScripAction_Overlay.pm:105
+msgid "Input error"
+msgstr "Invoer fout"
+
+#: NOT FOUND IN SOURCE
+msgid "Interest noted"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3729
+msgid "Internal Error"
+msgstr "Interne Fout"
+
+#: lib/RT/Record.pm:143
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr "Interne Fout: %1"
+
+#: lib/RT/Group_Overlay.pm:644
+msgid "Invalid Group Type"
+msgstr "Ongeldig Groep Type"
+
+#: lib/RT/Principal_Overlay.pm:128
+msgid "Invalid Right"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Invalid Type"
+msgstr "Ongeldig Type"
+
+#: lib/RT/Interface/Web.pm:865
+msgid "Invalid data"
+msgstr "Ongeldige data"
+
+#: lib/RT/Ticket_Overlay.pm:438
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr "Ongeldige eigenaar. Val terug op 'nobody'."
+
+#: lib/RT/Scrip_Overlay.pm:134 lib/RT/Template_Overlay.pm:251
+msgid "Invalid queue"
+msgstr "Ongeldige rij"
+
+#: lib/RT/ACE_Overlay.pm:244 lib/RT/ACE_Overlay.pm:253 lib/RT/ACE_Overlay.pm:259 lib/RT/ACE_Overlay.pm:270 lib/RT/ACE_Overlay.pm:275
+msgid "Invalid right"
+msgstr "Ongeldige recht"
+
+#: lib/RT/Record.pm:118
+#. ($key)
+msgid "Invalid value for %1"
+msgstr "Ongeldige waarde voor %1"
+
+#: lib/RT/Ticket_Overlay.pm:3367
+msgid "Invalid value for custom field"
+msgstr "Ongeldige waarde voor specifiek veld"
+
+#: lib/RT/Ticket_Overlay.pm:345
+msgid "Invalid value for status"
+msgstr "Ongeldige waarde voor status"
+
+#: bin/rt-crontool:191
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr "Het is ontzettend belangrijk dat onbevoorrechtigde gebruikers geen toestemming hebben om dit gereedschap te gebruiken."
+
+#: bin/rt-crontool:192
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr "We stellen voor dat u een onbevoorrechtigde unix gebruiker aanmaakt met het juiste groep lidmaatschap en RT toegang om dit gereedschap te gebruiken."
+
+#: bin/rt-crontool:163
+msgid "It takes several arguments:"
+msgstr "Het accepteerd meerdere argumenten:"
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr "Zaken die wachten op mijn goedkeuring"
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "jan."
+
+#: NOT FOUND IN SOURCE
+msgid "January"
+msgstr "januari"
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "Join or leave this group"
+msgstr "Sluit u aan of verlaat deze groep"
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "jul."
+
+#: NOT FOUND IN SOURCE
+msgid "July"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:99
+msgid "Jumbo"
+msgstr "Jumbo"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "jun."
+
+#: NOT FOUND IN SOURCE
+msgid "June"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr "Sleutelwoord"
+
+#: html/Admin/Elements/ModifyUser:52
+msgid "Lang"
+msgstr "Taal"
+
+#: html/Ticket/Elements/Tabs:73
+msgid "Last"
+msgstr "Laatste"
+
+#: html/Ticket/Elements/EditDates:38 html/Ticket/Elements/ShowDates:39
+msgid "Last Contact"
+msgstr "Laatste Contact"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Contacted"
+msgstr "Laatst Gecontacteerd"
+
+#: html/Search/Elements/TicketHeader:41
+msgid "Last Notified"
+msgstr ""
+
+#: html/Elements/SelectDateType:30
+msgid "Last Updated"
+msgstr "Laatst Ververst"
+
+#: NOT FOUND IN SOURCE
+msgid "LastUpdated"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr "Over"
+
+#: html/Admin/Users/Modify.html:83
+msgid "Let this user access RT"
+msgstr "Geef deze gebruiker toegang tot RT"
+
+#: html/Admin/Users/Modify.html:87
+msgid "Let this user be granted rights"
+msgstr "Geef deze gebruiker rechten"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr "Eigenaar wordt gelimieteerd tot %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr "Rij wordt gelimiteerd tot %1 %2"
+
+#: lib/RT/Ticket_Overlay.pm:2697
+msgid "Link already exists"
+msgstr "Koppeling bestaat al"
+
+#: lib/RT/Ticket_Overlay.pm:2709
+msgid "Link could not be created"
+msgstr "Koppeling kon niet gecreëerd worden"
+
+#: lib/RT/Ticket_Overlay.pm:2717 lib/RT/Ticket_Overlay.pm:2727
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr "Koppeling gecreëerd (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2638
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr "Koppelink verwijderd (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2644
+msgid "Link not found"
+msgstr "Koppeling niet gevonden"
+
+#: html/Ticket/ModifyLinks.html:25 html/Ticket/ModifyLinks.html:29
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr "Koppel ticket #%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Link ticket %1"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:97
+msgid "Links"
+msgstr "Koppelingen"
+
+#: html/Admin/Users/Modify.html:114 html/User/Prefs.html:85
+msgid "Location"
+msgstr "Locatie"
+
+#: lib/RT.pm:158
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr "Log folder %1 niet gevonden of niet toegankelijk.\\n RT kan niet starten."
+
+#: html/Elements/Header:57
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "Aangemeld als %1"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:25 html/Elements/Login:34 html/Elements/Login:45
+msgid "Login"
+msgstr "Aanmelden"
+
+#: html/Elements/Header:54
+msgid "Logout"
+msgstr "Afmelden"
+
+#: html/Search/Bulk.html:86
+msgid "Make Owner"
+msgstr "Maak Eigenaar"
+
+#: html/Search/Bulk.html:102
+msgid "Make Status"
+msgstr "Maak Status"
+
+#: html/Search/Bulk.html:109
+msgid "Make date Due"
+msgstr "Maak verwachtingsdatum"
+
+#: html/Search/Bulk.html:110
+msgid "Make date Resolved"
+msgstr "Make oplossingsdatum"
+
+#: html/Search/Bulk.html:107
+msgid "Make date Started"
+msgstr "Maak startdatum"
+
+#: html/Search/Bulk.html:106
+msgid "Make date Starts"
+msgstr "Maak datum gestart"
+
+#: html/Search/Bulk.html:108
+msgid "Make date Told"
+msgstr "Maak datum gemeld"
+
+#: html/Search/Bulk.html:99
+msgid "Make priority"
+msgstr "Maak prioriteit"
+
+#: html/Search/Bulk.html:100
+msgid "Make queue"
+msgstr "Maak rij"
+
+#: html/Search/Bulk.html:98
+msgid "Make subject"
+msgstr "Maak onderwerp"
+
+#: html/Admin/index.html:33
+msgid "Manage groups and group membership"
+msgstr "Beheer groepen en groeplidmaatschap"
+
+#: html/Admin/index.html:39
+msgid "Manage properties and configuration which apply to all queues"
+msgstr "Beheer eigenschappen en configuraties welke betrekking hebben op alle rijen"
+
+#: html/Admin/index.html:36
+msgid "Manage queues and queue-specific properties"
+msgstr "Beheer rijen en rij-specifieke eigenschappen"
+
+#: html/Admin/index.html:30
+msgid "Manage users and passwords"
+msgstr "Beheer gebruikers en wachtwoorden"
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "maa."
+
+#: NOT FOUND IN SOURCE
+msgid "March"
+msgstr "maart"
+
+#: NOT FOUND IN SOURCE
+msgid "May"
+msgstr "mei"
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "mei."
+
+#: lib/RT/Group_Overlay.pm:982
+msgid "Member added"
+msgstr "Lid toegevoegd"
+
+#: lib/RT/Group_Overlay.pm:1140
+msgid "Member deleted"
+msgstr "Lid verwijderd"
+
+#: lib/RT/Group_Overlay.pm:1144
+msgid "Member not deleted"
+msgstr "Lid niet verwijderd"
+
+#: html/Elements/SelectLinkType:26
+msgid "Member of"
+msgstr "Lid van"
+
+#: NOT FOUND IN SOURCE
+msgid "MemberOf"
+msgstr "LidVan"
+
+#: html/Admin/Elements/GroupTabs:42 html/User/Elements/GroupTabs:42
+msgid "Members"
+msgstr "Leden"
+
+#: lib/RT/Ticket_Overlay.pm:2843
+msgid "Merge Successful"
+msgstr "Samenvoeging Succesvol"
+
+#: lib/RT/Ticket_Overlay.pm:2804
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "Samenvoeging mislukt. Kon EffectiefId niet instellen"
+
+#: html/Ticket/Elements/EditLinks:115
+msgid "Merge into"
+msgstr "Voeg samen in"
+
+#: html/Ticket/Update.html:102
+msgid "Message"
+msgstr "Bericht"
+
+#: lib/RT/Interface/Web.pm:867
+msgid "Missing a primary key?: %1"
+msgstr "Mist primaire sleutel?: %1"
+
+#: html/Admin/Users/Modify.html:169 html/User/Prefs.html:54
+msgid "Mobile"
+msgstr "Mobiel"
+
+#: html/Admin/Elements/ModifyUser:72
+msgid "MobilePhone"
+msgstr "MobieleTelefoon"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify Access Control List"
+msgstr "Wijzig Toegangs Controle Lijst"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Custom Field %1"
+msgstr "Wijzig Specifiek Veld %1"
+
+#: html/Admin/Global/CustomFields.html:44 html/Admin/Global/index.html:51
+msgid "Modify Custom Fields which apply to all queues"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "Modify Scrip templates for this queue"
+msgstr "Wijzit Scrip sjabloon voor deze rij"
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "Modify Scrips for this queue"
+msgstr "Wijzig Scrips voor deze rij"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify System ACLS"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr "Wijzig Sjabloon %1"
+
+#: html/Admin/Queues/CustomField.html:45
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:53
+msgid "Modify a CustomField which applies to all queues"
+msgstr ""
+
+#: html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr "Wijzig een scrip voor deze rij %1"
+
+#: html/Admin/Global/Scrip.html:48
+msgid "Modify a scrip which applies to all queues"
+msgstr "Wijzig een scrip welke betrekking heeft op alle rijen"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify dates for # %1"
+msgstr "Wijzig data voor # %1"
+
+#: html/Ticket/ModifyDates.html:25 html/Ticket/ModifyDates.html:29
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr "Wijzig data voor #%1"
+
+#: html/Ticket/ModifyDates.html:35
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr "Wijzig data voor ticket # %1"
+
+#: html/Admin/Global/GroupRights.html:25 html/Admin/Global/GroupRights.html:28 html/Admin/Global/index.html:56
+msgid "Modify global group rights"
+msgstr "Wijzig globale groepsrechten"
+
+#: html/Admin/Global/GroupRights.html:33
+msgid "Modify global group rights."
+msgstr "Wijzig globale groepsrechten"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for groups"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for users"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr ""
+
+#: html/Admin/Global/UserRights.html:25 html/Admin/Global/UserRights.html:28 html/Admin/Global/index.html:60
+msgid "Modify global user rights"
+msgstr ""
+
+#: html/Admin/Global/UserRights.html:33
+msgid "Modify global user rights."
+msgstr "Wijzig globale gebruikersrechten"
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "Modify group metadata or delete group"
+msgstr "Wijzig groepsmetadata of verwijder groep"
+
+#: html/Admin/Groups/GroupRights.html:25 html/Admin/Groups/GroupRights.html:29 html/Admin/Groups/GroupRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr "Wijzig groepsrechten voor groep %1"
+
+#: html/Admin/Queues/GroupRights.html:25 html/Admin/Queues/GroupRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr "Wijzig groepsrechten voor rij %1"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Modify membership roster for this group"
+msgstr "Wijzig lidmaatschap rooster voor dze groep"
+
+#: lib/RT/System.pm:61
+msgid "Modify one's own RT account"
+msgstr "Wijzig uw eigen RT "
+
+#: html/Admin/Queues/People.html:25 html/Admin/Queues/People.html:29
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr "Wijzig mensen gekoppeld aan rij %1"
+
+#: html/Ticket/ModifyPeople.html:25 html/Ticket/ModifyPeople.html:29 html/Ticket/ModifyPeople.html:35
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr "Wijzig mensen gekoppeld aan ticket #%1"
+
+#: html/Admin/Queues/Scrips.html:44
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr "Wijzig scrips voor rij %1"
+
+#: html/Admin/Global/Scrips.html:44 html/Admin/Global/index.html:42
+msgid "Modify scrips which apply to all queues"
+msgstr "Wijzig scrips welke betrekking hebben op alle rijen"
+
+#: html/Admin/Global/Template.html:25 html/Admin/Global/Template.html:30 html/Admin/Global/Template.html:81 html/Admin/Queues/Template.html:78
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr "Wijzig sjabloon %1"
+
+#: html/Admin/Global/Templates.html:44
+msgid "Modify templates which apply to all queues"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:87 html/User/Groups/Modify.html:86
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr "Wijzig de groep %1"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Modify the queue watchers"
+msgstr "Wijzig de toeschouwers van de rij"
+
+#: html/Admin/Users/Modify.html:236
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr "Wijzig de gebruiker %1"
+
+#: html/Ticket/ModifyAll.html:37
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "Wijzig ticket # %1"
+
+#: html/Ticket/Modify.html:25 html/Ticket/Modify.html:28 html/Ticket/Modify.html:34
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "Wijzig ticket #%1"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Modify tickets"
+msgstr "Wijzig tickets"
+
+#: html/Admin/Groups/UserRights.html:25 html/Admin/Groups/UserRights.html:29 html/Admin/Groups/UserRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr "Wijzig gebruikersrechten voor groep %1"
+
+#: html/Admin/Queues/UserRights.html:25 html/Admin/Queues/UserRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr "Wijzig gebruikersrechten voor rij %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr "Wijzig toeschouwers voor rij '%1'"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyACL"
+msgstr "WijzigACL"
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "ModifyOwnMembership"
+msgstr "WijzigEigenLidmaatschap"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "ModifyQueueWatchers"
+msgstr "WijzigRijToeschouwers"
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "ModifyScrips"
+msgstr "WijzigScrips"
+
+#: lib/RT/System.pm:61
+msgid "ModifySelf"
+msgstr "WijzigZelf"
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "ModifyTemplate"
+msgstr "WijzigSjabloon"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "ModifyTicket"
+msgstr "WijzigTicket"
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "Ma."
+
+#: html/Ticket/Elements/ShowRequestor:42
+#. ($name)
+msgid "More about %1"
+msgstr "Meer over %1"
+
+#: html/Admin/Elements/EditCustomFields:61
+msgid "Move down"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:53
+msgid "Move up"
+msgstr ""
+
+#: html/Admin/Elements/SelectSingleOrMultiple:27
+msgid "Multiple"
+msgstr "Meerdere"
+
+#: lib/RT/User_Overlay.pm:179
+msgid "Must specify 'Name' attribute"
+msgstr "Specificeren van 'Naam' attribuut verplicht"
+
+#: NOT FOUND IN SOURCE
+msgid "My Approvals"
+msgstr "Mijn Goedkeuringen"
+
+#: html/Approvals/index.html:25 html/Approvals/index.html:26
+msgid "My approvals"
+msgstr ""
+
+#: html/Admin/Elements/AddCustomFieldValue:26 html/Admin/Elements/EditCustomField:32 html/Admin/Elements/ModifyTemplate:28 html/Admin/Elements/ModifyUser:30 html/Admin/Groups/Modify.html:44 html/Elements/SelectGroups:26 html/Elements/SelectUsers:28 html/User/Groups/Modify.html:44
+msgid "Name"
+msgstr "Naam"
+
+#: lib/RT/User_Overlay.pm:186
+msgid "Name in use"
+msgstr "Naam in gebruik"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr "Goedkeuring benodigd van de systeem beheerder"
+
+#: html/Ticket/Elements/ShowDates:52
+msgid "Never"
+msgstr "Nooit"
+
+#: html/Elements/Quicksearch:30
+msgid "New"
+msgstr "Nieuw"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:93 html/User/Prefs.html:65
+msgid "New Password"
+msgstr "Nieuw Wachtwoord"
+
+#: etc/initialdata:311 etc/upgrade/2.1.71:16
+msgid "New Pending Approval"
+msgstr "Nieuwe Hangende Goedkeuring"
+
+#: html/Ticket/Elements/EditLinks:111
+msgid "New Relationships"
+msgstr "Nieuwe Relaties"
+
+#: html/Ticket/Elements/Tabs:36
+msgid "New Search"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:41 html/Admin/Global/CustomFields.html:39 html/Admin/Queues/CustomField.html:52 html/Admin/Queues/CustomFields.html:40
+msgid "New custom field"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:54 html/User/Elements/GroupTabs:52
+msgid "New group"
+msgstr ""
+
+#: html/SelfService/Prefs.html:32
+msgid "New password"
+msgstr "Nieuw wachtwoord"
+
+#: lib/RT/User_Overlay.pm:639
+msgid "New password notification sent"
+msgstr "Bericht voor nieuw wachtwoord verzonden"
+
+#: html/Admin/Elements/QueueTabs:70
+msgid "New queue"
+msgstr ""
+
+#: html/SelfService/Elements/Tabs:63
+msgid "New request"
+msgstr "Nieuw verzoek"
+
+#: html/Admin/Elements/SelectRights:42
+msgid "New rights"
+msgstr "Nieuwe rechten"
+
+#: html/Admin/Global/Scrip.html:40 html/Admin/Global/Scrips.html:39 html/Admin/Queues/Scrip.html:43 html/Admin/Queues/Scrips.html:53
+msgid "New scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "New search"
+msgstr "Nieuwe zoekopdracht"
+
+#: html/Admin/Global/Template.html:60 html/Admin/Global/Templates.html:39 html/Admin/Queues/Template.html:58 html/Admin/Queues/Templates.html:46
+msgid "New template"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2771
+msgid "New ticket doesn't exist"
+msgstr "Nieuw ticket bestaat niet"
+
+#: html/Admin/Elements/UserTabs:52
+msgid "New user"
+msgstr ""
+
+#: html/Admin/Elements/CreateUserCalled:26
+msgid "New user called"
+msgstr "Nieuwe gebruiker genaamd"
+
+#: html/Admin/Queues/People.html:55 html/Ticket/Elements/EditPeople:29
+msgid "New watchers"
+msgstr "Nieuwe toeschouwers"
+
+#: html/Admin/Users/Prefs.html:42
+msgid "New window setting"
+msgstr "Nieuwe venster instelling"
+
+#: html/Ticket/Elements/Tabs:69
+msgid "Next"
+msgstr "Volgende"
+
+#: html/Search/Listing.html:48
+msgid "Next page"
+msgstr "Volgende pagina"
+
+#: html/Admin/Elements/ModifyUser:50
+msgid "NickName"
+msgstr "Bijnaam"
+
+#: html/Admin/Users/Modify.html:63 html/User/Prefs.html:46
+msgid "Nickname"
+msgstr "Bijnaam"
+
+#: html/Admin/Elements/EditCustomField:73 html/Admin/Elements/EditCustomFields:105
+msgid "No CustomField"
+msgstr "Geen SpecifiekVeld"
+
+#: html/Admin/Groups/GroupRights.html:84 html/Admin/Groups/UserRights.html:71
+msgid "No Group defined"
+msgstr "Geen Groep gedefinieerd"
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:68
+msgid "No Queue defined"
+msgstr "Geen Rij gedefinieerd"
+
+#: bin/rt-crontool:56
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr "Geen RT gebruiker gevonden. Raadpleeg uw RT beheerder.\\n"
+
+#: html/Admin/Global/Template.html:79 html/Admin/Queues/Template.html:76
+msgid "No Template"
+msgstr "Geen Sjabloon"
+
+#: bin/rt-commit-handler:764
+msgid "No Ticket specified. Aborting ticket "
+msgstr "Geen ticket gespecificeerd. Ticket afgebroken "
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr "Geen ticket gespecificeerd. Ticket wijzigingen afgebroken\\n\\n"
+
+#: html/Approvals/Elements/Approve:47
+msgid "No action"
+msgstr "Geen actie"
+
+#: lib/RT/Interface/Web.pm:862
+msgid "No column specified"
+msgstr "Geen kolom gespecificeerd"
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr "Geen commando gevonden\\n"
+
+#: html/Elements/ViewUser:36 html/Ticket/Elements/ShowRequestor:45
+msgid "No comment entered about this user"
+msgstr "Geen commentaar ingevuld over deze gebruiker"
+
+#: lib/RT/Ticket_Overlay.pm:2189 lib/RT/Ticket_Overlay.pm:2257
+msgid "No correspondence attached"
+msgstr "Geen correspondentie aangehecht"
+
+#: lib/RT/Action/Generic.pm:150 lib/RT/Condition/Generic.pm:176 lib/RT/Search/ActiveTicketsInQueue.pm:56 lib/RT/Search/Generic.pm:113
+#. (ref $self)
+msgid "No description for %1"
+msgstr "Geen omschrijving voor %1"
+
+#: lib/RT/Users_Overlay.pm:151
+msgid "No group specified"
+msgstr "Geen groep gespecificeerd"
+
+#: lib/RT/User_Overlay.pm:857
+msgid "No password set"
+msgstr "Geen wachtwoord ingesteld"
+
+#: lib/RT/Queue_Overlay.pm:259
+msgid "No permission to create queues"
+msgstr "Geen rechten om rijen te creëren"
+
+#: lib/RT/Ticket_Overlay.pm:341
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr "Geen rechten om tickets te creëren in de rij '%1'"
+
+#: lib/RT/User_Overlay.pm:151
+msgid "No permission to create users"
+msgstr "Geen rechten om gebruikers te creëren"
+
+#: html/SelfService/Display.html:174
+msgid "No permission to display that ticket"
+msgstr "Geen rechten om dat ticket te tonen"
+
+#: html/SelfService/Update.html:55
+msgid "No permission to view update ticket"
+msgstr "Geen rechten om verversing ticket te bekijken"
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1488
+msgid "No principal specified"
+msgstr "Geen hoofd gespecificeerd"
+
+#: html/Admin/Queues/People.html:154 html/Admin/Queues/People.html:164
+msgid "No principals selected."
+msgstr "Geen hoofden geselecteerd"
+
+#: html/Admin/Queues/index.html:35
+msgid "No queues matching search criteria found."
+msgstr "Geen rijen gevonden die aan de zoekcriteria voldoen"
+
+#: html/Admin/Elements/SelectRights:81
+msgid "No rights found"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:33
+msgid "No rights granted."
+msgstr "Geen rechten toegekend"
+
+#: html/Search/Bulk.html:149
+msgid "No search to operate on."
+msgstr "Geen zoek opdracht om uit te voeren."
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr "Geen ticket id gespecificeerd"
+
+#: lib/RT/Transaction_Overlay.pm:480 lib/RT/Transaction_Overlay.pm:518
+msgid "No transaction type specified"
+msgstr "Geen transactie type gespecificeerd"
+
+#: NOT FOUND IN SOURCE
+msgid "No user or email address specified"
+msgstr "Geen gebruiker of email-adres gespecificeerd"
+
+#: html/Admin/Users/index.html:36
+msgid "No users matching search criteria found."
+msgstr "Geen gebruikers gevonden die aan de zoekcriteria voldoen"
+
+#: bin/rt-commit-handler:644
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr "Geen geldige RT gebruiker gevonden. RT cvs behandelaar losgemaakt. Neemt u alstublieft contact op met uw RT beheerder.\\n"
+
+#: lib/RT/Interface/Web.pm:859
+msgid "No value sent to _Set!\\n"
+msgstr "Geen waarde gestuurd naar _Set!\\n"
+
+#: html/Search/Elements/TicketRow:37
+msgid "Nobody"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:864
+msgid "Nonexistant field?"
+msgstr "Nietbestaand veld?"
+
+#: html/Elements/Login:99
+msgid "Not logged in"
+msgstr ""
+
+#: html/Elements/Header:59 html/SelfService/Elements/Header:58
+msgid "Not logged in."
+msgstr "Niet aangemeld."
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "Niet gezet"
+
+#: html/NoAuth/Reminder.html:27
+msgid "Not yet implemented."
+msgstr "Nog niet geïmplementeerd."
+
+#: html/Admin/Groups/Rights.html:25
+msgid "Not yet implemented...."
+msgstr "Nog niet geïmplementeerd...."
+
+#: html/Approvals/Elements/Approve:50
+msgid "Notes"
+msgstr "Notities"
+
+#: lib/RT/User_Overlay.pm:642
+msgid "Notification could not be sent"
+msgstr "Bericht kon niet verstuurd worden"
+
+#: etc/initialdata:94
+msgid "Notify AdminCcs"
+msgstr "Bericht AdminCcs"
+
+#: etc/initialdata:90
+msgid "Notify AdminCcs as Comment"
+msgstr "Bericht AdminCcs als Commentaar"
+
+#: etc/initialdata:121
+msgid "Notify Other Recipients"
+msgstr "Bericht Andere Ontvangers"
+
+#: etc/initialdata:117
+msgid "Notify Other Recipients as Comment"
+msgstr "Bericht Andere Ontvangers als Commentaar"
+
+#: etc/initialdata:86
+msgid "Notify Owner"
+msgstr "Bericht Eigenaar"
+
+#: etc/initialdata:82
+msgid "Notify Owner as Comment"
+msgstr "Bericht Eigenaar als Commentaar"
+
+#: etc/initialdata:313 etc/upgrade/2.1.71:17
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr "Bericht Eigenaars en AdminCcs van nieuwe zaken welke hangende hun goedkeuring zijn"
+
+#: etc/initialdata:78
+msgid "Notify Requestors"
+msgstr "Bericht Aanvragers"
+
+#: etc/initialdata:104
+msgid "Notify Requestors and Ccs"
+msgstr "Bericht Aanvragers en Ccs"
+
+#: etc/initialdata:99
+msgid "Notify Requestors and Ccs as Comment"
+msgstr "Bericht Aanvragers en Ccs als Commentaar"
+
+#: etc/initialdata:113
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr "Bericht Aanvragers, Ccs en AdminCcs"
+
+#: etc/initialdata:109
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr "Bericht Aanvragers, Ccs en AdminCcs als Commentaar"
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "nov."
+
+#: NOT FOUND IN SOURCE
+msgid "November"
+msgstr ""
+
+#: lib/RT/Record.pm:157
+msgid "Object could not be created"
+msgstr "Object kon niet gecreëerd worden"
+
+#: lib/RT/Record.pm:176
+msgid "Object created"
+msgstr "Object gecreëerd"
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "oct."
+
+#: NOT FOUND IN SOURCE
+msgid "October"
+msgstr ""
+
+#: html/Elements/SelectDateRelation:35
+msgid "On"
+msgstr "Bij"
+
+#: etc/initialdata:155
+msgid "On Comment"
+msgstr "Bij Commentaar"
+
+#: etc/initialdata:148
+msgid "On Correspond"
+msgstr "Bij Overeenkomst"
+
+#: etc/initialdata:137
+msgid "On Create"
+msgstr "Bij Creatie"
+
+#: etc/initialdata:169
+msgid "On Owner Change"
+msgstr "Bij Eigenaarwijziging"
+
+#: etc/initialdata:177
+msgid "On Queue Change"
+msgstr "Bij Rijwijziging"
+
+#: etc/initialdata:183
+msgid "On Resolve"
+msgstr "Bij Oplossing"
+
+#: etc/initialdata:161
+msgid "On Status Change"
+msgstr "Bij Statuswijziging"
+
+#: etc/initialdata:142
+msgid "On Transaction"
+msgstr "Bij Transactie"
+
+#: html/Approvals/Elements/PendingMyApproval:50
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr "Toon alleen goedkeuringen voor verzoeken gecreëerd na %1"
+
+#: html/Approvals/Elements/PendingMyApproval:48
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr "Toon alleen goedkeuringen voor verzoeken gecreëerd voor %1"
+
+#: html/Elements/Quicksearch:31
+msgid "Open"
+msgstr "Open"
+
+#: html/Ticket/Elements/Tabs:136
+msgid "Open it"
+msgstr "Open"
+
+#: html/SelfService/Elements/Tabs:57
+msgid "Open requests"
+msgstr "Open verzoeken"
+
+#: html/Admin/Users/Prefs.html:41
+msgid "Open tickets (from listing) in a new window"
+msgstr "Open tickets (van lijst) in een nieuw venster"
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in another window"
+msgstr "Open tickets (van lijst) in een ander venster"
+
+#: etc/initialdata:133
+msgid "Open tickets on correspondence"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:101
+msgid "Ordering and sorting"
+msgstr "Ordening en sortering"
+
+#: html/Admin/Elements/ModifyUser:46 html/Admin/Users/Modify.html:117 html/Elements/SelectUsers:29 html/User/Prefs.html:86
+msgid "Organization"
+msgstr "Organisatie"
+
+#: html/Approvals/Elements/Approve:34
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr "Voortgekomen uit ticket: #%1"
+
+#: html/Admin/Elements/ModifyQueue:55 html/Admin/Queues/Modify.html:69
+msgid "Over time, priority moves toward"
+msgstr "Naar mate de tijd vordert, verschuift de prioriteit richting"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Own tickets"
+msgstr "Eigen tickets"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "OwnTicket"
+msgstr "EigenTicket"
+
+#: etc/initialdata:38 html/Elements/MyRequests:32 html/SelfService/Elements/MyRequests:30 html/Ticket/Create.html:48 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/EditPeople:44 html/Ticket/Elements/ShowPeople:27 html/Ticket/Update.html:63 lib/RT/ACE_Overlay.pm:86 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "Eigenaar"
+
+#: lib/RT/Ticket_Overlay.pm:3004
+#. ($OldOwnerObj->Name,  $NewOwnerObj->Name)
+msgid "Owner changed from %1 to %2"
+msgstr "Eigenaar veranderd van %1 naar %2"
+
+#: lib/RT/Transaction_Overlay.pm:584
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr "Eigenaar gedwongen veranderd van %1 naar %2"
+
+#: html/Search/Elements/PickRestriction:31
+msgid "Owner is"
+msgstr "Eigenaar is"
+
+#: html/Admin/Users/Modify.html:174 html/User/Prefs.html:56
+msgid "Pager"
+msgstr "Pieper"
+
+#: html/Admin/Elements/ModifyUser:74
+msgid "PagerPhone"
+msgstr "Pieper"
+
+#: NOT FOUND IN SOURCE
+msgid "Parent"
+msgstr ""
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/EditLinks:127 html/Ticket/Elements/EditLinks:58 html/Ticket/Elements/ShowLinks:43
+msgid "Parents"
+msgstr "Ouders"
+
+#: html/Elements/Login:43 html/User/Prefs.html:61
+msgid "Password"
+msgstr "Wachtwoord"
+
+#: html/NoAuth/Reminder.html:25
+msgid "Password Reminder"
+msgstr "Wachtwoord Herinerring"
+
+#: lib/RT/User_Overlay.pm:168 lib/RT/User_Overlay.pm:860
+msgid "Password too short"
+msgstr "Wachtwoord te kort"
+
+#: html/Admin/Users/Modify.html:291 html/User/Prefs.html:172
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "Wachtwoord: %1"
+
+#: html/Ticket/Elements/ShowSummary:43 html/Ticket/Elements/Tabs:96 html/Ticket/ModifyAll.html:51
+msgid "People"
+msgstr "Mensen"
+
+#: etc/initialdata:126
+msgid "Perform a user-defined action"
+msgstr "Verricht een gebruiker gedefiniëerde actie"
+
+#: lib/RT/ACE_Overlay.pm:231 lib/RT/ACE_Overlay.pm:237 lib/RT/ACE_Overlay.pm:563 lib/RT/ACE_Overlay.pm:573 lib/RT/ACE_Overlay.pm:583 lib/RT/ACE_Overlay.pm:648 lib/RT/CurrentUser.pm:83 lib/RT/CurrentUser.pm:92 lib/RT/CustomField_Overlay.pm:445 lib/RT/CustomField_Overlay.pm:451 lib/RT/Group_Overlay.pm:1095 lib/RT/Group_Overlay.pm:1099 lib/RT/Group_Overlay.pm:1108 lib/RT/Group_Overlay.pm:1159 lib/RT/Group_Overlay.pm:1163 lib/RT/Group_Overlay.pm:1169 lib/RT/Group_Overlay.pm:426 lib/RT/Group_Overlay.pm:518 lib/RT/Group_Overlay.pm:596 lib/RT/Group_Overlay.pm:604 lib/RT/Group_Overlay.pm:701 lib/RT/Group_Overlay.pm:705 lib/RT/Group_Overlay.pm:711 lib/RT/Group_Overlay.pm:904 lib/RT/Group_Overlay.pm:908 lib/RT/Group_Overlay.pm:921 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:126 lib/RT/Scrip_Overlay.pm:137 lib/RT/Scrip_Overlay.pm:197 lib/RT/Scrip_Overlay.pm:430 lib/RT/Template_Overlay.pm:284 lib/RT/Template_Overlay.pm:88 lib/RT/Template_Overlay.pm:94 lib/RT/Ticket_Overlay.pm:1341 lib/RT/Ticket_Overlay.pm:1351 lib/RT/Ticket_Overlay.pm:1365 lib/RT/Ticket_Overlay.pm:1518 lib/RT/Ticket_Overlay.pm:1527 lib/RT/Ticket_Overlay.pm:1540 lib/RT/Ticket_Overlay.pm:1875 lib/RT/Ticket_Overlay.pm:2013 lib/RT/Ticket_Overlay.pm:2177 lib/RT/Ticket_Overlay.pm:2244 lib/RT/Ticket_Overlay.pm:2596 lib/RT/Ticket_Overlay.pm:2668 lib/RT/Ticket_Overlay.pm:2762 lib/RT/Ticket_Overlay.pm:2777 lib/RT/Ticket_Overlay.pm:2910 lib/RT/Ticket_Overlay.pm:3139 lib/RT/Ticket_Overlay.pm:3337 lib/RT/Ticket_Overlay.pm:3499 lib/RT/Ticket_Overlay.pm:3551 lib/RT/Ticket_Overlay.pm:3716 lib/RT/Transaction_Overlay.pm:468 lib/RT/Transaction_Overlay.pm:475 lib/RT/Transaction_Overlay.pm:504 lib/RT/Transaction_Overlay.pm:511 lib/RT/User_Overlay.pm:1334 lib/RT/User_Overlay.pm:562 lib/RT/User_Overlay.pm:597 lib/RT/User_Overlay.pm:853 lib/RT/User_Overlay.pm:941
+msgid "Permission Denied"
+msgstr "Toestemming Geweigerd"
+
+#: html/User/Elements/Tabs:35
+msgid "Personal Groups"
+msgstr ""
+
+#: html/User/Groups/index.html:30 html/User/Groups/index.html:40
+msgid "Personal groups"
+msgstr "Persoonlijke groepen"
+
+#: html/User/Elements/DelegateRights:37
+msgid "Personal groups:"
+msgstr "Persoonlijke groepen:"
+
+#: html/Admin/Users/Modify.html:156 html/User/Prefs.html:49
+msgid "Phone numbers"
+msgstr "Telefoonnummers"
+
+#: html/Admin/Users/Rights.html:25
+msgid "Placeholder"
+msgstr "Plaatshouder"
+
+#: NOT FOUND IN SOURCE
+msgid "Pref"
+msgstr ""
+
+#: html/Elements/Header:52 html/Elements/Tabs:55 html/SelfService/Prefs.html:25 html/User/Prefs.html:25 html/User/Prefs.html:28
+msgid "Preferences"
+msgstr "Voorkeuren"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr "Voorkeuren"
+
+#: lib/RT/Action/Generic.pm:160
+msgid "Prepare Stubbed"
+msgstr "Bereid Plaatshouder Voor"
+
+#: html/Ticket/Elements/Tabs:61
+msgid "Prev"
+msgstr "Vorige"
+
+#: html/Search/Listing.html:44
+msgid "Previous page"
+msgstr "Vorige pagina"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr "Pri"
+
+#: lib/RT/ACE_Overlay.pm:133 lib/RT/ACE_Overlay.pm:208 lib/RT/ACE_Overlay.pm:552
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr "Hoofd %1 niet gevonden."
+
+#: html/Search/Elements/PickRestriction:54 html/SelfService/Display.html:76 html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:54 html/Ticket/Elements/ShowBasics:39 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "Prioriteit"
+
+#: html/Admin/Elements/ModifyQueue:51 html/Admin/Queues/Modify.html:65
+msgid "Priority starts at"
+msgstr "Prioriteit begint bij"
+
+#: etc/initialdata:25
+msgid "Privileged"
+msgstr "Gerechtigd"
+
+#: html/Admin/Users/Modify.html:271 html/User/Prefs.html:163
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr "Gerechtigde status: %1"
+
+#: html/Admin/Users/index.html:62
+msgid "Privileged users"
+msgstr "Gerechtigde gebruikers"
+
+#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59
+msgid "Pseudogroup for internal use"
+msgstr "Pseudogroep voor intern gebruik"
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Elements/Quicksearch:29 html/Search/Elements/PickRestriction:46 html/SelfService/Create.html:35 html/SelfService/Display.html:68 html/Ticket/Create.html:38 html/Ticket/Elements/EditBasics:64 html/Ticket/Elements/ShowBasics:43 html/User/Elements/DelegateRights:80 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "Rij"
+
+#: html/Admin/Queues/CustomField.html:42 html/Admin/Queues/Scrip.html:50 html/Admin/Queues/Scrips.html:46 html/Admin/Queues/Templates.html:43
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr "Rij %1 niet gevonden"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr "Rij '%1' niet gevonden\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Keyword Selections"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:31 html/Admin/Queues/Modify.html:43
+msgid "Queue Name"
+msgstr "Rij Naam"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr "Rij Scrips"
+
+#: lib/RT/Queue_Overlay.pm:263
+msgid "Queue already exists"
+msgstr "Rij bestaat al"
+
+#: lib/RT/Queue_Overlay.pm:272 lib/RT/Queue_Overlay.pm:278
+msgid "Queue could not be created"
+msgstr "Rij kon niet aangemaakt worden"
+
+#: html/Ticket/Create.html:209
+msgid "Queue could not be loaded."
+msgstr "Rij kon niet geladen worden."
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:282
+msgid "Queue created"
+msgstr "Rij aangemaakt"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue is not specified."
+msgstr "Rij is niet gespecificeerd"
+
+#: html/SelfService/Display.html:129
+msgid "Queue not found"
+msgstr "Rij niet gevonden"
+
+#: html/Admin/Elements/Tabs:38 html/Admin/index.html:35
+msgid "Queues"
+msgstr "Rijen"
+
+#: html/Elements/Login:34
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr "RT %1"
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr "RT %1 voor %2"
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr "RT %1 van <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr ""
+
+#: html/Admin/index.html:25 html/Admin/index.html:26
+msgid "RT Administration"
+msgstr "RT Beheer"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr "RT Authenticatie fout"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr "RT Doorgestuurd: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr "RT Configuratie fout"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr "RT Kritieke fout: Bericht niet bewaard!"
+
+#: html/Elements/Error:41 html/SelfService/Error.html:41
+msgid "RT Error"
+msgstr "RT Fout"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr "RT Ontving mail (%1) van zichzelf."
+
+#: NOT FOUND IN SOURCE
+msgid "RT Recieved mail (%1) from itself."
+msgstr ""
+
+#: html/SelfService/Closed.html:25
+msgid "RT Self Service / Closed Tickets"
+msgstr "RT Zelfbediening / Afgesloten Tickets"
+
+#: html/index.html:25 html/index.html:28
+msgid "RT at a glance"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr "RT kon u niet authenticeren"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr "RT kon de verzoeker niet vinden in zijn interne database"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr "RT kon de rij %1 niet vinden"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr "RT kon deze PGP signatuur niet valideren. \\n"
+
+#: html/Elements/PageLayout:26
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr "RT voor %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr "RT voor %1: %2"
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr "RT heeft uw commando's verwerkt"
+
+#: html/Elements/Login:83
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  Het is gedistribueerd onder <a href=\"http://www.gnu.org/copyleft/gpl.html\">Versie 2 van de GNU General Public License.</a>""
+
+#: NOT FOUND IN SOURCE
+msgid "RT is &copy; Copyright 1996-2002 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr "RT denkt dat dit bericht onbestelbaar zou kunnen zijn"
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr "RT zal dit bericht verwerken als of het ongesigneerd is.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr "RT's email commando modus vereist PGP authenticatie.  Of u heeft uw bericht niet gesigneerd, of uw signatuur kon niet geverifieerd worden."
+
+#: html/Admin/Users/Modify.html:58 html/Admin/Users/Prefs.html:52 html/User/Prefs.html:44
+msgid "Real Name"
+msgstr "Echte Naam"
+
+#: html/Admin/Elements/ModifyUser:48
+msgid "RealName"
+msgstr "EchteNaam"
+
+#: html/Ticket/Create.html:185 html/Ticket/Elements/EditLinks:139 html/Ticket/Elements/EditLinks:94 html/Ticket/Elements/ShowLinks:63
+msgid "Referred to by"
+msgstr "Naar gerefeerd door"
+
+#: html/Elements/SelectLinkType:28 html/Ticket/Create.html:184 html/Ticket/Elements/EditLinks:135 html/Ticket/Elements/EditLinks:80 html/Ticket/Elements/ShowLinks:55
+msgid "Refers to"
+msgstr "Refereert aan"
+
+#: NOT FOUND IN SOURCE
+msgid "RefersTo"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr "Verfijn"
+
+#: html/Search/Elements/PickRestriction:27
+msgid "Refine search"
+msgstr "Verfijn Zoekopdracht"
+
+#: html/Elements/Refresh:36
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "Ververs deze pagina elke %1 minuten."
+
+#: html/Ticket/Create.html:174 html/Ticket/Elements/ShowSummary:60 html/Ticket/ModifyAll.html:57
+msgid "Relationships"
+msgstr "Relaties"
+
+#: html/Search/Bulk.html:93
+msgid "Remove AdminCc"
+msgstr "Verwijder AdminCc"
+
+#: html/Search/Bulk.html:91
+msgid "Remove Cc"
+msgstr "Verwijder Cc"
+
+#: html/Search/Bulk.html:89
+msgid "Remove Requestor"
+msgstr "Verwijder Verzoeker"
+
+#: html/Ticket/Elements/ShowTransaction:173 html/Ticket/Elements/Tabs:122
+msgid "Reply"
+msgstr "Antwoord"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Reply to tickets"
+msgstr "Antwoord op tickets"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "ReplyToTicket"
+msgstr "AntwoordOpTicket"
+
+#: etc/initialdata:44 html/Ticket/Update.html:40 lib/RT/ACE_Overlay.pm:87
+msgid "Requestor"
+msgstr "Verzoeker"
+
+#: html/Search/Elements/PickRestriction:38
+msgid "Requestor email address"
+msgstr "Verzoeker email adres"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr "Verzoeker(s)"
+
+#: NOT FOUND IN SOURCE
+msgid "RequestorAddresses"
+msgstr ""
+
+#: html/SelfService/Create.html:43 html/SelfService/Display.html:42 html/Ticket/Create.html:56 html/Ticket/Elements/EditPeople:48 html/Ticket/Elements/ShowPeople:31
+msgid "Requestors"
+msgstr "Verzoekers"
+
+#: html/Admin/Elements/ModifyQueue:61 html/Admin/Queues/Modify.html:75
+msgid "Requests should be due in"
+msgstr "Verzoek is terug verwacht"
+
+#: html/Elements/Submit:62
+msgid "Reset"
+msgstr "Herstel"
+
+#: html/Admin/Users/Modify.html:159 html/User/Prefs.html:50
+msgid "Residence"
+msgstr "Woonplaats"
+
+#: html/Ticket/Elements/Tabs:132
+msgid "Resolve"
+msgstr "Los op"
+
+#: html/Ticket/Update.html:133
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr "Los ticket #%1 (%2) op"
+
+#: etc/initialdata:302 html/Elements/SelectDateType:28 lib/RT/Ticket_Overlay.pm:1170
+msgid "Resolved"
+msgstr "Opgelost"
+
+#: html/Search/Bulk.html:123 html/Ticket/ModifyAll.html:73 html/Ticket/Update.html:73
+msgid "Response to requestors"
+msgstr "Antwoord aan verzoekers"
+
+#: html/Elements/ListActions:26
+msgid "Results"
+msgstr "Resultaten"
+
+#: html/Search/Elements/PickRestriction:105
+msgid "Results per page"
+msgstr "Resultaten per pagina"
+
+#: html/Admin/Elements/ModifyUser:33 html/Admin/Users/Modify.html:100 html/User/Prefs.html:72
+msgid "Retype Password"
+msgstr "Type wachtwoord opnieuw"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr "Recht %1 niet gevonden voor %2  %3 in bereik %4 (%5)\\n"
+
+#: lib/RT/ACE_Overlay.pm:613
+msgid "Right Delegated"
+msgstr "Recht Gedelegeerd"
+
+#: lib/RT/ACE_Overlay.pm:303
+msgid "Right Granted"
+msgstr "Recht Toegekend"
+
+#: lib/RT/ACE_Overlay.pm:161
+msgid "Right Loaded"
+msgstr "Recht Geladen"
+
+#: lib/RT/ACE_Overlay.pm:678 lib/RT/ACE_Overlay.pm:693
+msgid "Right could not be revoked"
+msgstr "Recht kon niet afgenomen worden"
+
+#: html/User/Delegation.html:64
+msgid "Right not found"
+msgstr "Recht niet gevonden"
+
+#: lib/RT/ACE_Overlay.pm:543 lib/RT/ACE_Overlay.pm:638
+msgid "Right not loaded."
+msgstr "Recht niet geladen"
+
+#: lib/RT/ACE_Overlay.pm:689
+msgid "Right revoked"
+msgstr ""
+
+#: html/Admin/Elements/UserTabs:41
+msgid "Rights"
+msgstr "Rechten"
+
+#: lib/RT/Interface/Web.pm:758
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:791
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr ""
+
+#: html/Admin/Global/GroupRights.html:51 html/Admin/Queues/GroupRights.html:52
+msgid "Roles"
+msgstr "Rollen"
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr "RootGoedkeuring"
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "Za."
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "Save Changes"
+msgstr "Bewaarwijzigingen"
+
+#: html/Ticket/ModifyLinks.html:39
+msgid "Save changes"
+msgstr "Bewaarwijzigingen"
+
+#: html/Admin/Global/Scrip.html:49
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:176
+msgid "Scrip Created"
+msgstr "Scrip aangemaakt"
+
+#: html/Admin/Elements/EditScrips:84
+msgid "Scrip deleted"
+msgstr "Script verwijderd"
+
+#: html/Admin/Elements/QueueTabs:46 html/Admin/Elements/SystemTabs:33 html/Admin/Global/index.html:41
+msgid "Scrips"
+msgstr "Scrips"
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr "Scrips voor %1\\n"
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr "Scrips welke betrekking hebben op alle rijen"
+
+#: html/Elements/SimpleSearch:27 html/Search/Elements/PickRestriction:126 html/Ticket/Elements/Tabs:159
+msgid "Search"
+msgstr "Zoek"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr "Zoek Criteria"
+
+#: html/Approvals/Elements/PendingMyApproval:39
+msgid "Search for approvals"
+msgstr ""
+
+#: bin/rt-crontool:188
+msgid "Security:"
+msgstr "Veiligheid"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "SeeQueue"
+msgstr "ZieRij"
+
+#: html/Admin/Groups/index.html:40
+msgid "Select a group"
+msgstr "Selecteer een groep"
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr "Selecteer een rij"
+
+#: html/Admin/Users/index.html:25 html/Admin/Users/index.html:28
+msgid "Select a user"
+msgstr "Selecteer een gebruiker"
+
+#: html/Admin/Global/CustomField.html:38 html/Admin/Global/CustomFields.html:36
+msgid "Select custom field"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:52 html/User/Elements/GroupTabs:50
+msgid "Select group"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:355
+msgid "Select multiple values"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:352
+msgid "Select one value"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:67
+msgid "Select queue"
+msgstr ""
+
+#: html/Admin/Global/Scrip.html:37 html/Admin/Global/Scrips.html:36 html/Admin/Queues/Scrip.html:40 html/Admin/Queues/Scrips.html:50
+msgid "Select scrip"
+msgstr ""
+
+#: html/Admin/Global/Template.html:57 html/Admin/Global/Templates.html:36 html/Admin/Queues/Template.html:55
+msgid "Select template"
+msgstr ""
+
+#: html/Admin/Elements/UserTabs:49
+msgid "Select user"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "SelectMultiple"
+msgstr "SelecteerMeerdere"
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectSingle"
+msgstr "SelecteerEnkele"
+
+#: html/SelfService/index.html:25
+msgid "Self Service"
+msgstr "Zelfbediening"
+
+#: etc/initialdata:114
+msgid "Send mail to all watchers"
+msgstr "Stuurt mail naar alle toeschouwers"
+
+#: etc/initialdata:110
+msgid "Send mail to all watchers as a \"comment\""
+msgstr "Stuurt mail naar alle toeschouwers als een \"commentaar\""
+
+#: etc/initialdata:105
+msgid "Send mail to requestors and Ccs"
+msgstr "Stuurt mail naar alle verzoekers en Ccs"
+
+#: etc/initialdata:100
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr "Stuurt mail naar alle verzoekers en Ccs als een \"commentaar\""
+
+#: etc/initialdata:79
+msgid "Sends a message to the requestors"
+msgstr "Stuurt een bericht aan de verzoekers"
+
+#: etc/initialdata:118 etc/initialdata:122
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr "Stuurt mail aan expliciet genoemde Ccs en Bccs"
+
+#: etc/initialdata:95
+msgid "Sends mail to the administrative Ccs"
+msgstr "Stuurt mail aan de administratieve Ccs"
+
+#: etc/initialdata:91
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr "Stuurt mail aan de administratieve Ccs als een \"commentaar\""
+
+#: etc/initialdata:83 etc/initialdata:87
+msgid "Sends mail to the owner"
+msgstr "Stuurt mail aan de eigenaar"
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "Sep."
+
+#: NOT FOUND IN SOURCE
+msgid "September"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr "Toon Resultaten"
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show approved requests"
+msgstr "Toon goedgekeurde verzoeken"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show basics"
+msgstr "Toon beginselen"
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show denied requests"
+msgstr "Toon afgewezen verzoeken"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show details"
+msgstr "Toon details"
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show pending requests"
+msgstr "Toon hangende verzoeken"
+
+#: html/Approvals/Elements/PendingMyApproval:46
+msgid "Show requests awaiting other approvals"
+msgstr "Toon verzoeken die wachten op andere goedkeuringen"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Show ticket private commentary"
+msgstr "Toon ticket privé commentaar"
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "Show ticket summaries"
+msgstr "Toon ticket samenvattingen"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ShowACL"
+msgstr "ToonACL"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowScrips"
+msgstr "ToonScrips"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ShowTemplate"
+msgstr "ToonSjabloon"
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "ShowTicket"
+msgstr "ToonTicket"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "ShowTicketComments"
+msgstr "ToonTicketCommentaar"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr "Schrijf in als een ticket Verzoeker of ticket of rij Cc"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr "Schrijf in als een ticket of rij AdminCc"
+
+#: html/Admin/Elements/ModifyUser:39 html/Admin/Users/Modify.html:191 html/Admin/Users/Prefs.html:32 html/SelfService/Prefs.html:37 html/User/Prefs.html:112
+msgid "Signature"
+msgstr "Signatuur"
+
+#: html/SelfService/Elements/Header:52
+#. ($session{'CurrentUser'}->Name)
+msgid "Signed in as %1"
+msgstr ""
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Single"
+msgstr "Enkel"
+
+#: html/Elements/Header:51
+msgid "Skip Menu"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFieldValues:31
+msgid "Sort key"
+msgstr "Sorteer sleutel"
+
+#: html/Search/Elements/PickRestriction:109
+msgid "Sort results by"
+msgstr "Sorteer resultaten op"
+
+#: html/Admin/Elements/AddCustomFieldValue:25
+msgid "SortOrder"
+msgstr "SorteerVolgorde"
+
+#: NOT FOUND IN SOURCE
+msgid "Stalled"
+msgstr "Blijft Steken"
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr "Start pagina"
+
+#: html/Elements/SelectDateType:27 html/Ticket/Elements/EditDates:32 html/Ticket/Elements/ShowDates:35
+msgid "Started"
+msgstr "Gestart"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr "Startum '%1' kon niet ontleed worden"
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:27 html/Ticket/Elements/ShowDates:31
+msgid "Starts"
+msgstr "Begint"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr "Begint op"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr "Begindatum '%1' kon niet ontleed worden"
+
+#: html/Admin/Elements/ModifyUser:82 html/Admin/Users/Modify.html:138 html/User/Prefs.html:94
+msgid "State"
+msgstr "Staat"
+
+#: html/Elements/MyRequests:31 html/Elements/MyTickets:31 html/Search/Elements/PickRestriction:74 html/SelfService/Display.html:59 html/SelfService/Elements/MyRequests:29 html/SelfService/Update.html:31 html/Ticket/Create.html:42 html/Ticket/Elements/EditBasics:38 html/Ticket/Elements/ShowBasics:31 html/Ticket/Update.html:60 lib/RT/Ticket_Overlay.pm:1164 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "Status"
+
+#: etc/initialdata:288
+msgid "Status Change"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:530
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr "Status veranderd van %1 naar %2"
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr "StatusVerandering"
+
+#: html/Ticket/Elements/Tabs:147
+msgid "Steal"
+msgstr "Steel"
+
+#: lib/RT/Transaction_Overlay.pm:589
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "Gestolen van %1"
+
+#: html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Search/Bulk.html:126 html/Search/Elements/PickRestriction:43 html/SelfService/Create.html:59 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:35 html/Ticket/Create.html:84 html/Ticket/Elements/EditBasics:28 html/Ticket/ModifyAll.html:79 html/Ticket/Update.html:77 lib/RT/Ticket_Overlay.pm:1160 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "Onderwerp"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:611
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr "Onderwerp veranderd naar %1"
+
+#: html/Elements/Submit:59
+msgid "Submit"
+msgstr "Registreer"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr "Registreer Workflow"
+
+#: lib/RT/Group_Overlay.pm:749
+msgid "Succeeded"
+msgstr "Gelukt"
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "Zo."
+
+#: lib/RT/System.pm:54
+msgid "SuperUser"
+msgstr "SuperGebruiker"
+
+#: html/User/Elements/DelegateRights:77
+msgid "System"
+msgstr "Systeem"
+
+#: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:567 lib/RT/Interface/Web.pm:757 lib/RT/Interface/Web.pm:790
+msgid "System Error"
+msgstr "Systeem Fout"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. Right not granted."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. right not granted"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:616
+msgid "System error. Right not delegated."
+msgstr "Systeem fout. Recht niet gedelegeerd."
+
+#: lib/RT/ACE_Overlay.pm:146 lib/RT/ACE_Overlay.pm:223 lib/RT/ACE_Overlay.pm:306 lib/RT/ACE_Overlay.pm:898
+msgid "System error. Right not granted."
+msgstr "Systeem fout. Recht niet toegekend."
+
+#: NOT FOUND IN SOURCE
+msgid "System error. Unable to grant rights."
+msgstr "Systeem fout. Niet mogelijk om rechten toe te kennen"
+
+#: html/Admin/Global/GroupRights.html:35 html/Admin/Groups/GroupRights.html:37 html/Admin/Queues/GroupRights.html:36
+msgid "System groups"
+msgstr "Systeem groepen"
+
+#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53
+msgid "SystemRolegroup for internal use"
+msgstr "SysteemRolgroep voor intern gebruik"
+
+#: lib/RT/CurrentUser.pm:320
+msgid "TEST_STRING"
+msgstr "TEST_STRING"
+
+#: html/Ticket/Elements/Tabs:143
+msgid "Take"
+msgstr "Neem"
+
+#: lib/RT/Transaction_Overlay.pm:575
+msgid "Taken"
+msgstr "Genomen"
+
+#: html/Admin/Elements/EditScrip:81
+msgid "Template"
+msgstr "Sjabloon"
+
+#: html/Admin/Global/Template.html:91 html/Admin/Queues/Template.html:90
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr ""
+
+#: html/Admin/Elements/EditTemplates:89
+msgid "Template deleted"
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:153
+msgid "Template not found"
+msgstr "Sjabloon niet gevonden"
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr "Sjabloon niet gevonden\\n"
+
+#: lib/RT/Template_Overlay.pm:347
+msgid "Template parsed"
+msgstr "Sjabloon ontleed"
+
+#: html/Admin/Elements/QueueTabs:49 html/Admin/Elements/SystemTabs:36 html/Admin/Global/index.html:45
+msgid "Templates"
+msgstr "Sjablonen"
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr "Sjablonen voor %1\\n"
+
+#: lib/RT/Interface/Web.pm:858
+msgid "That is already the current value"
+msgstr "Dat is al de huidige waarde"
+
+#: lib/RT/CustomField_Overlay.pm:178
+msgid "That is not a value for this custom field"
+msgstr "Dat is geen waarde voor dit specifieke veld"
+
+#: lib/RT/Ticket_Overlay.pm:1886
+msgid "That is the same value"
+msgstr "Dat is de zelfde waarde"
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr "Dat hoofd is reeds een %1 voor deze rij"
+
+#: lib/RT/Ticket_Overlay.pm:1434
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr "Dat hoofd is reeds een %1 voor dit ticket"
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr "Dat hoofd is geen %1 voor deze rij"
+
+#: lib/RT/Ticket_Overlay.pm:1551
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr "Dat hoofd is geen %1 voor dit ticket"
+
+#: lib/RT/Ticket_Overlay.pm:1882
+msgid "That queue does not exist"
+msgstr "Die rij bestaat niet"
+
+#: lib/RT/Ticket_Overlay.pm:3143
+msgid "That ticket has unresolved dependencies"
+msgstr "Dat ticket heeft onopgeloste afhankelijkheden"
+
+#: lib/RT/ACE_Overlay.pm:288 lib/RT/ACE_Overlay.pm:597
+msgid "That user already has that right"
+msgstr "Die gebruiker heeft dat recht reeds"
+
+#: lib/RT/Ticket_Overlay.pm:2952
+msgid "That user already owns that ticket"
+msgstr "Die gebruiker is al eigenaar van dat ticket"
+
+#: lib/RT/Ticket_Overlay.pm:2918
+msgid "That user does not exist"
+msgstr "Die gebruiker bestaat niet"
+
+#: lib/RT/User_Overlay.pm:315
+msgid "That user is already privileged"
+msgstr "Die gebruiker is al gerechtigd"
+
+#: lib/RT/User_Overlay.pm:332
+msgid "That user is already unprivileged"
+msgstr "Die gebruiker is reeds ontrechtigd"
+
+#: lib/RT/User_Overlay.pm:327
+msgid "That user is now privileged"
+msgstr "Die gebruiker is nu gerechtigd"
+
+#: lib/RT/User_Overlay.pm:344
+msgid "That user is now unprivileged"
+msgstr "Die gebruiker is nu ontrechtigd"
+
+#: NOT FOUND IN SOURCE
+msgid "That user is now unprivilegedileged"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2944
+msgid "That user may not own tickets in that queue"
+msgstr "Die gebruiker mag geen eigenaar zijn van tickets in die rij"
+
+#: lib/RT/Link_Overlay.pm:206
+msgid "That's not a numerical id"
+msgstr "Dat is niet een numeriek ID"
+
+#: html/Ticket/Create.html:150 html/Ticket/Elements/ShowSummary:28
+msgid "The Basics"
+msgstr "De Beginselen"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The CC of a ticket"
+msgstr "De CC van een ticket"
+
+#: lib/RT/ACE_Overlay.pm:89
+msgid "The administrative CC of a ticket"
+msgstr "De administratieve CC van een ticket"
+
+#: lib/RT/Ticket_Overlay.pm:2213
+msgid "The comment has been recorded"
+msgstr "Het commentaar is bewaard"
+
+#: bin/rt-crontool:198
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr "Het volgende commando zal alle actieve tickets in de rij 'general' vinden en hun prioriteit op 99 zetten als ze meer dan 4 uur niet aangeraakt zijn:"
+
+#: bin/rt-commit-handler:756 bin/rt-commit-handler:766
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr "De volgende commando's zijn niet verwerkt:\\n\\n"
+
+#: lib/RT/Interface/Web.pm:861
+msgid "The new value has been set."
+msgstr "De waarde is gezet."
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The owner of a ticket"
+msgstr "De eigenaar van een ticket"
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The requestor of a ticket"
+msgstr "De verzoeker van een ticket"
+
+#: html/Admin/Elements/EditUserComments:26
+msgid "These comments aren't generally visible to the user"
+msgstr "Dit commentaar is gewoonlijk niet zichtbaar voor de gebruiker"
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr "Dit ticket %1 %2 (%3)\\n"
+
+#: bin/rt-crontool:189
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr "Dit gereedschap stelt de gebruiker in staat arbitraire perl modules te gebruiken vanuit RT"
+
+#: lib/RT/Transaction_Overlay.pm:253
+msgid "This transaction appears to have no content"
+msgstr "Het lijkt erop alsof deze transactie geen inhoud heeft"
+
+#: html/Ticket/Elements/ShowRequestor:47
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr "De 25 hoogste prioriteit tickets van deze gebruiker"
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "Do."
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1 Jumbo update: %2"
+msgstr ""
+
+#: html/Ticket/ModifyAll.html:25 html/Ticket/ModifyAll.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "Ticket #%1 Jumbo actualisering: %2"
+
+#: html/Approvals/Elements/ShowDependency:46
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr "Ticket #%1: %2"
+
+#: lib/RT/Ticket_Overlay.pm:608
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr "Ticket %1 aangemaakt in rij '%2'"
+
+#: bin/rt-commit-handler:760
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr "Toclet %1 geladen\\n"
+
+#: html/Search/Bulk.html:181
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr "Ticket %1: %2"
+
+#: html/Ticket/History.html:25 html/Ticket/History.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr "Ticket Historie # %1 %2"
+
+#: html/SelfService/Display.html:34
+msgid "Ticket Id"
+msgstr "Ticket Id"
+
+#: etc/initialdata:303
+msgid "Ticket Resolved"
+msgstr "Ticket Opgelost"
+
+#: html/Search/Elements/PickRestriction:63
+msgid "Ticket attachment"
+msgstr "Ticket aanhechting"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr "Ticket inhoud"
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr "Ticket inhoud type"
+
+#: lib/RT/Ticket_Overlay.pm:495 lib/RT/Ticket_Overlay.pm:597
+msgid "Ticket could not be created due to an internal error"
+msgstr "Ticket kong niet aangemaakt worden vanwege een interne fout"
+
+#: lib/RT/Transaction_Overlay.pm:522
+msgid "Ticket created"
+msgstr "Ticket aangemaakt"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr "Ticket aanmaken gefaald"
+
+#: lib/RT/Transaction_Overlay.pm:527
+msgid "Ticket deleted"
+msgstr "Ticket verwijderd"
+
+#: html/REST/1.0/modify:29 html/REST/1.0/update:34
+msgid "Ticket id not found"
+msgstr "Ticket id niet gevonden"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket killed"
+msgstr ""
+
+#: html/REST/1.0/modify:36 html/REST/1.0/update:41
+msgid "Ticket not found"
+msgstr "Ticket niet gevonden"
+
+#: etc/initialdata:289
+msgid "Ticket status changed"
+msgstr "Ticket status gewijzigd"
+
+#: html/Ticket/Update.html:39
+msgid "Ticket watchers"
+msgstr "Ticket toeschouwers"
+
+#: html/Elements/Tabs:49
+msgid "Tickets"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr "Tickets %1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr "Tickets %1 door %2"
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Tickets from %1"
+msgstr "Tickets van %1"
+
+#: html/Approvals/Elements/ShowDependency:27
+msgid "Tickets which depend on this approval:"
+msgstr "Tickets welke afhankelijk zijn van deze goedkeuring"
+
+#: html/Ticket/Create.html:157 html/Ticket/Elements/EditBasics:48
+msgid "Time Left"
+msgstr "Tijd Over"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:43
+msgid "Time Worked"
+msgstr "Tijd Gewerkt"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "Tijd over"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "Tijd om te tonen"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "Tijd gewerkt"
+
+#: NOT FOUND IN SOURCE
+msgid "TimeLeft"
+msgstr "TijdOver"
+
+#: lib/RT/Ticket_Overlay.pm:1165
+msgid "TimeWorked"
+msgstr "TijdGewerkt"
+
+#: bin/rt-commit-handler:402
+msgid "To generate a diff of this commit:"
+msgstr "Om een diff van deze uitvoering te genereren:"
+
+#: bin/rt-commit-handler:391
+msgid "To generate a diff of this commit:\\n"
+msgstr "Om een diff van deze uitvoering te genereren:\\n"
+
+#: lib/RT/Ticket_Overlay.pm:1168
+msgid "Told"
+msgstr "Verteld"
+
+#: etc/initialdata:237
+msgid "Transaction"
+msgstr "Transactie"
+
+#: lib/RT/Transaction_Overlay.pm:642
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr "Transactie %1 gezuiverd"
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr "Transactie Gecreëerd"
+
+#: lib/RT/Transaction_Overlay.pm:89
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr "Transactie->Creëer kon niet, aangezien u geen ticket id gespecificeerd heeft"
+
+#: lib/RT/Transaction_Overlay.pm:701
+msgid "Transactions are immutable"
+msgstr "Transacties zijn onwijzigbaar"
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr "Tracht een recht te verwijderen: %1"
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "Di."
+
+#: html/Admin/Elements/EditCustomField:34 html/Ticket/Elements/AddWatchers:33 html/Ticket/Elements/AddWatchers:44 html/Ticket/Elements/AddWatchers:54 lib/RT/Ticket_Overlay.pm:1166 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "Type"
+
+#: lib/RT/ScripCondition_Overlay.pm:104
+msgid "Unimplemented"
+msgstr "Niet geïmplementeerd"
+
+#: html/Admin/Users/Modify.html:68
+msgid "Unix login"
+msgstr "Unix aanmelden"
+
+#: html/Admin/Elements/ModifyUser:62
+msgid "UnixUsername"
+msgstr "UnixGebruikersnaam"
+
+#: lib/RT/Attachment_Overlay.pm:265
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr "Onbekende InhoudCodering %1"
+
+#: html/Elements/SelectResultsPerPage:37
+msgid "Unlimited"
+msgstr "Ongelimiteerd"
+
+#: etc/initialdata:32
+msgid "Unprivileged"
+msgstr "Ongerechtigd"
+
+#: lib/RT/Transaction_Overlay.pm:571
+msgid "Untaken"
+msgstr "Vrij"
+
+#: html/Elements/MyTickets:64 html/Search/Bulk.html:33
+msgid "Update"
+msgstr "Ververs"
+
+#: html/Admin/Users/Prefs.html:62
+msgid "Update ID"
+msgstr "Ververs ID"
+
+#: html/Search/Bulk.html:120 html/Ticket/ModifyAll.html:66 html/Ticket/Update.html:67
+msgid "Update Type"
+msgstr "Ververs Type"
+
+#: html/Search/Listing.html:61
+msgid "Update all these tickets at once"
+msgstr "Ververs al deze tickets in eens"
+
+#: html/Admin/Users/Prefs.html:49
+msgid "Update email"
+msgstr "Ververs email"
+
+#: html/Admin/Users/Prefs.html:55
+msgid "Update name"
+msgstr "Ververs naam"
+
+#: lib/RT/Interface/Web.pm:375
+msgid "Update not recorded."
+msgstr "Verversing niet opgeslagen."
+
+#: html/Search/Bulk.html:81
+msgid "Update selected tickets"
+msgstr "Ververs geselecteerde tickets"
+
+#: html/Admin/Users/Prefs.html:36
+msgid "Update signature"
+msgstr "Ververs signatuur"
+
+#: html/Ticket/ModifyAll.html:63
+msgid "Update ticket"
+msgstr "Ververs ticket"
+
+#: html/SelfService/Update.html:25 html/SelfService/Update.html:27
+#. ($Ticket->id)
+msgid "Update ticket # %1"
+msgstr "Ververs ticket # %1"
+
+#: html/SelfService/Update.html:50
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr "Ververs ticket #%1"
+
+#: html/Ticket/Update.html:135
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr "Ververs ticket #%1 (%2)"
+
+#: lib/RT/Interface/Web.pm:373
+msgid "Update type was neither correspondence nor comment."
+msgstr "Verversingstype was noch correspondentie, noch commentaar"
+
+#: html/Elements/SelectDateType:33 html/Ticket/Elements/ShowDates:51 lib/RT/Ticket_Overlay.pm:1169
+msgid "Updated"
+msgstr "Ververst"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr "Gebruiker %1 %2: %3\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr "Gebruiker %1 Wachtwoord: %2\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr "Gebruiker '%1' niet gevonden"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr "Gebruiker '%1' niet gevonden\\n"
+
+#: etc/initialdata:125 etc/initialdata:191
+msgid "User Defined"
+msgstr "Gebruiker Gedifiniëerd"
+
+#: html/Admin/Users/Prefs.html:59
+msgid "User ID"
+msgstr "GebruikersID"
+
+#: html/Elements/SelectUsers:26
+msgid "User Id"
+msgstr "Gebruiker Id"
+
+#: html/Admin/Elements/GroupTabs:47 html/Admin/Elements/QueueTabs:60 html/Admin/Elements/SystemTabs:47 html/Admin/Global/index.html:59
+msgid "User Rights"
+msgstr "Gebruikersrechten"
+
+#: html/Admin/Users/Modify.html:226
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr "Gebruiker kon niet aangemaakt worden: %1"
+
+#: lib/RT/User_Overlay.pm:262
+msgid "User created"
+msgstr "Gebruiker aangemaakt"
+
+#: html/Admin/Global/GroupRights.html:67 html/Admin/Groups/GroupRights.html:54 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr "Door gebruiker gedefiniëerde groepen"
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr "Gebruiker verwittigd"
+
+#: html/Admin/Users/Prefs.html:25 html/Admin/Users/Prefs.html:29
+msgid "User view"
+msgstr "Gebruikers aanzicht"
+
+#: html/Admin/Users/Modify.html:48 html/Elements/Login:42 html/Ticket/Elements/AddWatchers:35
+msgid "Username"
+msgstr "Gebruikersnaam"
+
+#: html/Admin/Elements/SelectNewGroupMembers:26 html/Admin/Elements/Tabs:32 html/Admin/Groups/Members.html:55 html/Admin/Queues/People.html:68 html/Admin/index.html:29 html/User/Groups/Members.html:58
+msgid "Users"
+msgstr "Gebruikers"
+
+#: html/Admin/Users/index.html:65
+msgid "Users matching search criteria"
+msgstr "Gebruikers die voldoen aan de zoek criteria"
+
+#: html/Search/Elements/PickRestriction:51
+msgid "ValueOfQueue"
+msgstr "WaardeVanRij"
+
+#: html/Admin/Elements/EditCustomField:40
+msgid "Values"
+msgstr "Waarden"
+
+#: NOT FOUND IN SOURCE
+msgid "VrijevormEnkele"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Watch"
+msgstr "Schouw toe"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "WatchAsAdminCc"
+msgstr "SchouwToeAlsAdminCc"
+
+#: NOT FOUND IN SOURCE
+msgid "Watcher loaded"
+msgstr "Toeschouwer geladen"
+
+#: html/Admin/Elements/QueueTabs:42
+msgid "Watchers"
+msgstr "Toeschouwers"
+
+#: html/Admin/Elements/ModifyUser:56
+msgid "WebEncoding"
+msgstr "WebCodering"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "Wo."
+
+#: etc/upgrade/2.1.71:161
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr "Wanneer een ticket goedgekeurd is door alle goedkeurders, voeg correspondentie toe aan het orginele ticket"
+
+#: etc/upgrade/2.1.71:135
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr "Wanneer een ticket goedgekeurd is door een goedkeurder, voeg correspondentie toe aan het orginele ticket"
+
+#: etc/initialdata:138
+msgid "When a ticket is created"
+msgstr "Wanneer een ticket is aangemaakt"
+
+#: etc/upgrade/2.1.71:79
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr "Wanneer een goedkeuringsticket is aangemaakts, verwittig de Eigenaar en de AdminCc van het onderwerp dat op hun goedkeuring wacht"
+
+#: etc/initialdata:143
+msgid "When anything happens"
+msgstr "Wanneer iets gebeurt"
+
+#: etc/initialdata:184
+msgid "Whenever a ticket is resolved"
+msgstr "Wanneer een ticket is opgelost"
+
+#: etc/initialdata:170
+msgid "Whenever a ticket's owner changes"
+msgstr "Wanneer de eigenaar van een ticket verandert"
+
+#: etc/initialdata:178
+msgid "Whenever a ticket's queue changes"
+msgstr "Wanneer de rij van een ticket verandert"
+
+#: etc/initialdata:162
+msgid "Whenever a ticket's status changes"
+msgstr "Wanneer de status van een ticket verandert"
+
+#: etc/initialdata:192
+msgid "Whenever a user-defined condition occurs"
+msgstr "Wanneer een door de gebruiker gedifiniëerde voorwaarde gebeurt"
+
+#: etc/initialdata:156
+msgid "Whenever comments come in"
+msgstr "Wanneer commentaar binnenkomt"
+
+#: etc/initialdata:149
+msgid "Whenever correspondence comes in"
+msgstr "Wanneer correspondentie binnenkomt"
+
+#: html/Admin/Users/Modify.html:164 html/User/Prefs.html:52
+msgid "Work"
+msgstr "Werk"
+
+#: html/Admin/Elements/ModifyUser:70
+msgid "WorkPhone"
+msgstr "WerkTelefoon"
+
+#: html/SelfService/Display.html:86 html/Ticket/Elements/ShowBasics:35 html/Ticket/Update.html:65
+msgid "Worked"
+msgstr "Gewerkt"
+
+#: lib/RT/Ticket_Overlay.pm:3056
+msgid "You already own this ticket"
+msgstr "U bent al eigenaar van dit ticket"
+
+#: html/autohandler:121
+msgid "You are not an authorized user"
+msgstr "U bent geen geauthorizeerde gebruiker"
+
+#: lib/RT/Ticket_Overlay.pm:2930
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "U kunt alleen tickets opnieuw toe bedelen die van u zijn, of van niemand"
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr "U heeft geen toestemming om dat ticket te bekijken"
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "U vond %1 tickets in rij %2"
+
+#: html/NoAuth/Logout.html:31 html/REST/1.0/logout:25
+msgid "You have been logged out of RT."
+msgstr "U bent afgemeld bij RT"
+
+#: html/SelfService/Display.html:134
+msgid "You have no permission to create tickets in that queue."
+msgstr "U heeft geen toestemming om tickets aan te maken in die rij."
+
+#: lib/RT/Ticket_Overlay.pm:1895
+msgid "You may not create requests in that queue."
+msgstr "U mag geen verzoeken aanmaken in die rij"
+
+#: html/NoAuth/Logout.html:36
+msgid "You're welcome to login again"
+msgstr "U mag zich weer aanmelden"
+
+#: html/SelfService/Elements/MyRequests:25
+#. ($friendly_status)
+msgid "Your %1 requests"
+msgstr "Uw %1 verzoeken"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr "Uw RT beheerder heeft de mail-aliasses welke RT aanroepen verkeerd geconfigureerd"
+
+#: etc/initialdata:429 etc/upgrade/2.1.71:146
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr "Uw verzoek is goedgekeurd door %1. Er zijn wellicht nog andere hangende goedkeuringen."
+
+#: etc/initialdata:463 etc/upgrade/2.1.71:180
+msgid "Your request has been approved."
+msgstr "Uw verzoek is goedgekeurd."
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr ""
+
+#: etc/initialdata:384 etc/upgrade/2.1.71:101
+msgid "Your request was rejected."
+msgstr "Uw verzoek was geweigerd."
+
+#: html/autohandler:136 html/autohandler:142
+msgid "Your username or password is incorrect"
+msgstr "Uw gebruikersnaam of wachtwoord zijn onjuist"
+
+#: html/Admin/Elements/ModifyUser:84 html/Admin/Users/Modify.html:144 html/User/Prefs.html:96
+msgid "Zip"
+msgstr "Postcode"
+
+#: NOT FOUND IN SOURCE
+msgid "[no subject]"
+msgstr ""
+
+#: html/User/Elements/DelegateRights:59
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "zoals gegeven aan %1"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:34
+msgid "contains"
+msgstr "bevat"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content"
+msgstr "inhoud"
+
+#: html/Elements/SelectAttachmentField:27
+msgid "content-type"
+msgstr "inhoud-type"
+
+#: lib/RT/Ticket_Overlay.pm:2282
+msgid "correspondence (probably) not sent"
+msgstr "correspondentie (waarschijnlijk) niet verstuurd"
+
+#: lib/RT/Ticket_Overlay.pm:2292
+msgid "correspondence sent"
+msgstr "correspondentie verstuurd"
+
+#: html/Admin/Elements/ModifyQueue:63 html/Admin/Queues/Modify.html:77 lib/RT/Date.pm:319
+msgid "days"
+msgstr "dagen"
+
+#: NOT FOUND IN SOURCE
+msgid "dead"
+msgstr "dood"
+
+#: html/Search/Listing.html:75
+msgid "delete"
+msgstr "verwijder"
+
+#: lib/RT/Queue_Overlay.pm:63
+msgid "deleted"
+msgstr "verwijderd"
+
+#: html/Search/Elements/PickRestriction:68
+msgid "does not match"
+msgstr "voldoet niet aan"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:35
+msgid "doesn't contain"
+msgstr "bevat niet"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "equal to"
+msgstr "gelijk aan"
+
+#: NOT FOUND IN SOURCE
+msgid "false"
+msgstr ""
+
+#: html/Elements/SelectAttachmentField:28
+msgid "filename"
+msgstr "bestandsnaam"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "greater than"
+msgstr "groter dan"
+
+#: lib/RT/Group_Overlay.pm:194
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "groep '%1'"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "uren"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr "id"
+
+#: html/Elements/SelectBoolean:32 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88
+msgid "is"
+msgstr "is"
+
+#: html/Elements/SelectBoolean:36 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:37 html/Search/Elements/PickRestriction:48 html/Search/Elements/PickRestriction:77 html/Search/Elements/PickRestriction:89
+msgid "isn't"
+msgstr "is niet"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "less than"
+msgstr "minder dan"
+
+#: html/Search/Elements/PickRestriction:67
+msgid "matches"
+msgstr "voldoet aan"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "min"
+
+#: html/Ticket/Update.html:66
+msgid "minutes"
+msgstr "minuten"
+
+#: bin/rt-commit-handler:765
+msgid "modifications\\n\\n"
+msgstr "wijzigingen\\n\\n"
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "maanden"
+
+#: lib/RT/Queue_Overlay.pm:58
+msgid "new"
+msgstr "nieuw"
+
+#: html/Admin/Elements/EditScrips:43
+msgid "no value"
+msgstr ""
+
+#: html/Ticket/Elements/EditWatchers:28
+msgid "none"
+msgstr "geen"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "not equal to"
+msgstr "niet gelijk aan"
+
+#: NOT FOUND IN SOURCE
+msgid "notlike"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:59
+msgid "open"
+msgstr "open"
+
+#: lib/RT/Group_Overlay.pm:199
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr "persoonlijke groep '%1' voor gebruiker '%2'"
+
+#: lib/RT/Group_Overlay.pm:207
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr "rij %1 %2"
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "rejected"
+msgstr "geweigerd"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "resolved"
+msgstr "opgelost"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr "sec"
+
+#: lib/RT/Queue_Overlay.pm:60
+msgid "stalled"
+msgstr "bleef steken"
+
+#: lib/RT/Group_Overlay.pm:202
+#. ($self->Type)
+msgid "system %1"
+msgstr "systeem %1"
+
+#: lib/RT/Group_Overlay.pm:213
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr "systeem groep '%1'"
+
+#: html/Elements/Error:42 html/SelfService/Error.html:42
+msgid "the calling component did not specify why"
+msgstr "het aanroepende component specificeerde niet waarom"
+
+#: lib/RT/Group_Overlay.pm:210
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr "ticket #%1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "true"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:216
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr "onbeschreven groep %1"
+
+#: NOT FOUND IN SOURCE
+msgid "undescripbed group %1"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:191
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr "gebruiker %1"
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr "weken"
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr "met sjabloon %1"
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr "jaren"
+
diff --git a/rt/lib/RT/I18N/no.po b/rt/lib/RT/I18N/no.po
new file mode 100644 (file)
index 0000000..5b1ab05
--- /dev/null
@@ -0,0 +1,4879 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: RT 3.0.1\n"
+"POT-Creation-Date: 2003-04-01 06:06+0200\n"
+"PO-Revision-Date: 2003-05-01 04:47+0200\n"
+"Last-Translator: Marcus Ramberg <marcus@thefeed.no>\n"
+"Language-Team: RT Norwegian <rt@thefeed.no>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28
+msgid "#"
+msgstr "#"
+
+#: html/Admin/Queues/Scrip.html:55
+#. ($QueueObj->id)
+msgid "#%1"
+msgstr "#%1"
+
+#: html/Approvals/Elements/Approve:27 html/Approvals/Elements/ShowDependency:50 html/SelfService/Display.html:25 html/Ticket/Display.html:26 html/Ticket/Display.html:30
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($Ticket->id, $Ticket->Subject)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr "#%1: %2"
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr "%1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr "%1 %2 %3"
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr "%1 %3. %2 %7 %4:%5:%6"
+
+#: lib/RT/Ticket_Overlay.pm:3505 lib/RT/Transaction_Overlay.pm:557 lib/RT/Transaction_Overlay.pm:599
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 added"
+msgstr "%1 %2 lagt til"
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 %2 ago"
+msgstr "%1 %2 siden"
+
+#: lib/RT/Ticket_Overlay.pm:3511 lib/RT/Transaction_Overlay.pm:564
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 changed to %3"
+msgstr "%1 %2 ble endret til %3"
+
+#: lib/RT/Ticket_Overlay.pm:3508 lib/RT/Transaction_Overlay.pm:560 lib/RT/Transaction_Overlay.pm:605
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 deleted"
+msgstr "%1 %2 slettet"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 %2 of group %3"
+msgstr "%1 %2 av gruppen %3"
+
+#: html/Admin/Elements/EditScrips:44 html/Admin/Elements/ListGlobalScrips:28
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 with template %3"
+msgstr "%1 %2 med mal %3"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 this ticket\\n"
+msgstr "%1 (%2) %3 denne biletten\\n""
+
+#: html/Search/Listing.html:57
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr "%1 - %2 vist"
+
+#: bin/rt-crontool:169 bin/rt-crontool:176 bin/rt-crontool:182
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - An argument to pass to %2"
+msgstr "%1 - Et parameter til %2"
+
+#: bin/rt-crontool:185
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr "%1 - Viser statusoppdateringer til STDOUT"
+
+#: bin/rt-crontool:179
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr "%1 - Oppgi kommandomodulen du ønsker Â bruke"
+
+#: bin/rt-crontool:173
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr "%1 - Oppgiv betingelsesmodulen du ønsker Â bruke"
+
+#: bin/rt-crontool:166
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr "%1 - Oppgi søkemodulen du ønsker Â bruke"
+
+#: lib/RT/ScripAction_Overlay.pm:122
+#. ($self->Id)
+msgid "%1 ScripAction loaded"
+msgstr "%1 KommandoScript lastet"
+
+#: lib/RT/Ticket_Overlay.pm:3538
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 added as a value for %2"
+msgstr "%1 ble lagt til som verdi for %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on"
+msgstr "%1 alias trenger en ReferanseId å jobbe mot"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on "
+msgstr "%1 alias trenger en saksnummer å jobbe mot "
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on (from %2) %3"
+msgstr "%1 alias trenger et saksnummer å jobbe mot (fra %2) %3"
+
+#: lib/RT/Link_Overlay.pm:117 lib/RT/Link_Overlay.pm:124
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 appears to be a local object, but can't be found in the database"
+msgstr "%1 ser ut til å være et lokalt objekt, men kan ikke finnes i databasen"
+
+#: html/Ticket/Elements/ShowDates:52 lib/RT/Transaction_Overlay.pm:481
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 by %2"
+msgstr "%1 av %2"
+
+#: lib/RT/Transaction_Overlay.pm:535 lib/RT/Transaction_Overlay.pm:624 lib/RT/Transaction_Overlay.pm:633 lib/RT/Transaction_Overlay.pm:636
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 changed from %2 to %3"
+msgstr "%1 ble endret fra %2 til %3"
+
+#: lib/RT/Interface/Web.pm:891
+msgid "%1 could not be set to %2."
+msgstr "%1 kunne ikke settes til %2."
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr "%1 kunne ikke starte en transaksjon (%2)\\n"
+
+#: lib/RT/Ticket_Overlay.pm:2817
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr "%1 kunne ikke sette status til løst. RT-basen kan være inkonsistent."
+
+#: html/Elements/MyTickets:25
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr "Mine %1 høyst prioriterte saker..."
+
+#: html/Elements/MyRequests:25
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr "Mine %1 høyst prioriterte forespørsler..."
+
+#: bin/rt-crontool:161
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr "%1 er et verktøy for å behandle saker fra eksterne verktøy, slik som cron."
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr "%1 er ikke lenger en %2 for denne køen."
+
+#: lib/RT/Ticket_Overlay.pm:1570
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr "%1 er ikke lenger en %2 for denne saken."
+
+#: lib/RT/Ticket_Overlay.pm:3594
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr "%1 er ikke lenger en verdi for fleksifeltet %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr "%1 er ikke et gyldig saksnummer."
+
+#: html/Ticket/Elements/ShowBasics:36
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr "%1 min"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr "%1 vises ikke"
+
+#: html/User/Elements/DelegateRights:76
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr "%1 rettigheter"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr "%1 var velykket\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr "%1 er ukjent type for $saksnummer"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr "%1 er ukjent type for %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 was created without a CurrentUser\\n"
+msgstr "%1 ble opprettet uten en aktiv bruker\\n"
+
+#: lib/RT/Action/ResolveMembers.pm:42
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr "%1 vil løse alle medlemmer av en løst gruppesak."
+
+#: NOT FOUND IN SOURCE
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr "%1 vil stoppe en [lokal] BASE hvis den er avhengig av/medlem av en tilkoblet sak."
+
+#: lib/RT/Transaction_Overlay.pm:433
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr "%1: ingen vedlegg oppgitt"
+
+#: html/Ticket/Elements/ShowTransaction:102
+#. ($size)
+msgid "%1b"
+msgstr "%1b"
+
+#: html/Ticket/Elements/ShowTransaction:99
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr "%1k"
+
+#: lib/RT/Ticket_Overlay.pm:1140
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr "'%1' er en ugyldig statusverdi"
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr "'%1' er ikke en kjent handling"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete group member)"
+msgstr "(Merk for å slette gruppemedlem)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr "(Merk for å slette Scrip)"
+
+#: html/Admin/Elements/EditCustomFieldValues:25 html/Admin/Elements/EditQueueWatchers:29 html/Admin/Elements/EditScrips:35 html/Admin/Elements/EditTemplates:36 html/Admin/Groups/Members.html:52 html/Ticket/Elements/EditLinks:33 html/Ticket/Elements/EditPeople:46 html/User/Groups/Members.html:55
+msgid "(Check box to delete)"
+msgstr "(Merk for å slette)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check boxes to delete)"
+msgstr "(Merk boksene for å slette)"
+
+#: html/Ticket/Create.html:178
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr "(Skriv inn referansenummer eller URler, separert med mellomrom)"
+
+#: html/Admin/Queues/Modify.html:54 html/Admin/Queues/Modify.html:60
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr "(Standard er %1);H
+
+#: NOT FOUND IN SOURCE
+msgid "(No Value)"
+msgstr "(Ingen Verdi)"
+
+#: html/Admin/Elements/EditCustomFields:33 html/Admin/Elements/ListGlobalCustomFields:32
+msgid "(No custom fields)"
+msgstr "(Ingen fleksifelt)"
+
+#: html/Admin/Groups/Members.html:50 html/User/Groups/Members.html:53
+msgid "(No members)"
+msgstr "(Ingen medlemmer)"
+
+#: html/Admin/Elements/EditScrips:32 html/Admin/Elements/ListGlobalScrips:32
+msgid "(No scrips)"
+msgstr "(Ingen scrips)"
+
+#: html/Admin/Elements/EditTemplates:31
+msgid "(No templates)"
+msgstr "(Ingen maler)"
+
+#: html/Ticket/Update.html:85
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(Sender en kopi av denne oppdateringen til en kommaseparert liste med epostaddresser. Endrer <b>ikke</b> hvem som vil motta fremtidige oppdatreinger.)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Sender en kopi av denne oppdateringen til en kommaseparert liste med epostaddresser. Endrer <b>ikke</b> hvem som vil motta fremtidige oppdateringer.)"
+
+#: html/Ticket/Create.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(Sender en kopi av denne oppdateringen til en kommaseparert liste av administrative epostaddresser. Disse vil <b>vil</b> motta fremtidige oppdateringer.)"
+
+#: html/Ticket/Update.html:81
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(Sender en kopi av denne oppdateringen til en komma-separert liste av epostaddresser. Endrer <b>ikke</b> hvem som vil motta fremtidige oppdateringer.)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Sender en kopi av denne oppdateringen til en kommaseparert liste med epost-addresser. Endrer <b->ikke</b> hvem som vi motta fremtige utfordrer dere nå."
+
+#: html/Ticket/Create.html:69
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(Sender en kopi av dette oppdateringen til en kommaseparert liste med epostaddresser. Disse <b>vill</b> motta fremtidige oppdateringer.)"
+
+#: html/Admin/Groups/index.html:33 html/User/Groups/index.html:33
+msgid "(empty)"
+msgstr "(tom)"
+
+#: html/Admin/Users/index.html:39
+msgid "(no name listed)"
+msgstr "(navn ikke oppgitt)"
+
+#: html/Elements/MyRequests:43 html/Elements/MyTickets:45
+msgid "(no subject)"
+msgstr "(ingen overskrift)"
+
+#: html/Admin/Elements/SelectRights:48 html/Elements/SelectCustomFieldValue:30 html/Ticket/Elements/EditCustomField:59 html/Ticket/Elements/ShowCustomFields:36 lib/RT/Transaction_Overlay.pm:534
+msgid "(no value)"
+msgstr "(ingen verdi)"
+
+#: html/Ticket/Elements/EditLinks:116
+msgid "(only one ticket)"
+msgstr "(bare en sak)"
+
+#: html/Elements/MyRequests:52 html/Elements/MyTickets:55
+msgid "(pending approval)"
+msgstr "(Venter på godkjenning)"
+
+#: html/Elements/MyRequests:54 html/Elements/MyTickets:57
+msgid "(pending other tickets)"
+msgstr "(venter på andre saker)"
+
+#: NOT FOUND IN SOURCE
+msgid "(requestor's group)"
+msgstr "(kundens gruppe)"
+
+#: html/Admin/Users/Modify.html:50
+msgid "(required)"
+msgstr "(nødvendig)"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "(untitled)"
+msgstr "(ingen tittel)"
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I own..."
+msgstr "Mine 25 høyst prioriterte saker..."
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I requested..."
+msgstr "Mine 25 høyst priorterte forespørsler..."
+
+#: html/Ticket/Elements/ShowBasics:32
+msgid "<% $Ticket->Status%>"
+msgstr "<% $Ticket-:Status%>"
+
+#: html/Elements/SelectTicketTypes:27
+msgid "<% $_ %>"
+msgstr "<% $_ %>"
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:26
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"Ny sak i\">&nbsp;%1"
+
+#: NOT FOUND IN SOURCE
+msgid "??????"
+msgstr "??????"
+
+#: etc/initialdata:203
+msgid "A blank template"
+msgstr "En tom mal"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Deleted"
+msgstr "ACE slettet"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Loaded"
+msgstr "ACE lastet"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be deleted"
+msgstr "ACE kunne ikke slettes"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be found"
+msgstr "fant ikke ACE"
+
+#: lib/RT/ACE_Overlay.pm:157 lib/RT/Principal_Overlay.pm:181
+msgid "ACE not found"
+msgstr "ACE ikke funnet"
+
+#: lib/RT/ACE_Overlay.pm:831
+msgid "ACEs can only be created and deleted."
+msgstr "ACEr kan bare opprettes og slettes."
+
+#: bin/rt-commit-handler:755
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr "Avbryter for Â ung uønsket saksendring"
+
+#: html/User/Elements/Tabs:32
+msgid "About me"
+msgstr "Om meg"
+
+#: html/Admin/Users/Modify.html:80
+msgid "Access control"
+msgstr "Aksesskontroll"
+
+#: html/Admin/Elements/EditScrip:57
+msgid "Action"
+msgstr "Handling"
+
+#: lib/RT/Scrip_Overlay.pm:147
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr "Handling %1 finnes ikke"
+
+#: bin/rt-crontool:123
+msgid "Action committed."
+msgstr "Handling skrevet."
+
+#: bin/rt-crontool:119
+msgid "Action prepared..."
+msgstr "Handling forberedt"
+
+#: html/Search/Bulk.html:92
+msgid "Add AdminCc"
+msgstr "Legg til AdminCc"
+
+#: html/Search/Bulk.html:90
+msgid "Add Cc"
+msgstr "Legg til Cc"
+
+#: html/Ticket/Create.html:114 html/Ticket/Update.html:100
+msgid "Add More Files"
+msgstr "Legg til flere filer"
+
+#: NOT FOUND IN SOURCE
+msgid "Add Next State"
+msgstr "Legg til neste status"
+
+#: html/Search/Bulk.html:88
+msgid "Add Requestor"
+msgstr "Legg til kunde"
+
+#: html/Admin/Elements/AddCustomFieldValue:26
+msgid "Add Value"
+msgstr "Legg til verdi"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip to this queue"
+msgstr "Legg til Scrip i denne køen"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip which will apply to all queues"
+msgstr "Legg til et Scrip som gjelder for alle køer"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a keyword selection to this queue"
+msgstr "Legg til et nøkkelordvalg p denne køen"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr "Legg til et globalt Scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr "Legg til et Scrip til denne køen"
+
+#: html/Admin/Global/Scrip.html:55
+msgid "Add a scrip which will apply to all queues"
+msgstr "Legg til et Scrip som vil gjelde for alle køer"
+
+#: html/Search/Bulk.html:118
+msgid "Add comments or replies to selected tickets"
+msgstr "Legg til kommentarer eller svar til denne saken"
+
+#: html/Admin/Groups/Members.html:42 html/User/Groups/Members.html:39
+msgid "Add members"
+msgstr "Legg til medlemmer"
+
+#: html/Admin/Queues/People.html:66 html/Ticket/Elements/AddWatchers:28
+msgid "Add new watchers"
+msgstr "Legg til overvåkere"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr "AddNextState"
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr "La til primær som en %1 for denne køen"
+
+#: lib/RT/Ticket_Overlay.pm:1454
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr "La til primær som en %1 for denne saken"
+
+#: html/Admin/Elements/ModifyUser:76 html/Admin/Users/Modify.html:122 html/User/Prefs.html:88
+msgid "Address1"
+msgstr "Adresse1"
+
+#: html/Admin/Elements/ModifyUser:78 html/Admin/Users/Modify.html:127 html/User/Prefs.html:90
+msgid "Address2"
+msgstr "Adresse2"
+
+#: html/Ticket/Create.html:74
+msgid "Admin Cc"
+msgstr "Admin Cc"
+
+#: etc/initialdata:280
+msgid "Admin Comment"
+msgstr "Admin Kommentar"
+
+#: etc/initialdata:259
+msgid "Admin Correspondence"
+msgstr "Admin-korrespondanse"
+
+#: html/Admin/Queues/index.html:25 html/Admin/Queues/index.html:28
+msgid "Admin queues"
+msgstr "Adminkøer"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr "Adminbrukere"
+
+#: html/Admin/Global/index.html:26 html/Admin/Global/index.html:28
+msgid "Admin/Global configuration"
+msgstr "Admin/Global konfigurasjon"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr "Admin/Grupper"
+
+#: html/Admin/Queues/Modify.html:25 html/Admin/Queues/Modify.html:29
+msgid "Admin/Queue/Basics"
+msgstr "Admin/Køer/Grunnleggende"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr "AdminAllePersonalGrupper"
+
+#: etc/initialdata:56 html/Ticket/Elements/ShowPeople:39 html/Ticket/Update.html:50 lib/RT/ACE_Overlay.pm:89
+msgid "AdminCc"
+msgstr "AdminCc"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr "AdminKommentar"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr "AdminKorrespondanse"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "AdminCustomFields"
+msgstr "AdminFleksifelt"
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "AdminGroup"
+msgstr "AdminGruppe"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "AdminGroupMembership"
+msgstr "AdminGruppeMedlemskap"
+
+#: lib/RT/System.pm:59
+msgid "AdminOwnPersonalGroups"
+msgstr "AdminEgnePersonligeGrupper"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "AdminQueue"
+msgstr "AdminKø"
+
+#: lib/RT/System.pm:60
+msgid "AdminUsers"
+msgstr "AdminBrukere"
+
+#: html/Admin/Queues/People.html:48 html/Ticket/Elements/EditPeople:54
+msgid "Administrative Cc"
+msgstr "Administrativ Cc"
+
+#: NOT FOUND IN SOURCE
+msgid "Admins"
+msgstr "Admin"
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr "Avansert Søk"
+
+#: html/Elements/SelectDateRelation:36
+msgid "After"
+msgstr "Etter"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr "Alder"
+
+#: NOT FOUND IN SOURCE
+msgid "Alias"
+msgstr "Alias"
+
+#: NOT FOUND IN SOURCE
+msgid "Alias for"
+msgstr "Alias for"
+
+#: html/Admin/Elements/EditCustomFields:96
+msgid "All Custom Fields"
+msgstr "Alle Fleksifelt"
+
+#: html/Admin/Queues/index.html:53
+msgid "All Queues"
+msgstr "Alle køer"
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr "Send alltid en melding til kunden uavhengig av meldingssender"
+
+#: html/Elements/Tabs:56
+msgid "Approval"
+msgstr "Godkjennelse"
+
+#: html/Approvals/Display.html:46 html/Approvals/Elements/ShowDependency:42 html/Approvals/index.html:65
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr "Godkjennelse #%1: %2"
+
+#: html/Approvals/index.html:54
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr "Godkjenning # %1: Notater kunne ikke lagres pga. systemfeil"
+
+#: html/Approvals/index.html:52
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr "Godkjenning #%1: Notater lagret"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Details"
+msgstr "Godkjenning - Detaljer"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval diagram"
+msgstr "Godkjenningsdiagram"
+
+#: html/Approvals/Elements/Approve:44
+msgid "Approve"
+msgstr "Godkjenn"
+
+#: etc/initialdata:437 etc/upgrade/2.1.71:148
+msgid "Approver's notes: %1"
+msgstr "Godkjenners notater: %1"
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "Apr."
+
+#: NOT FOUND IN SOURCE
+msgid "April"
+msgstr "April"
+
+#: html/Elements/SelectSortOrder:35
+msgid "Ascending"
+msgstr "Stigende"
+
+#: html/Search/Bulk.html:127 html/SelfService/Update.html:33 html/Ticket/ModifyAll.html:83 html/Ticket/Update.html:100
+msgid "Attach"
+msgstr "Legg Ved"
+
+#: html/SelfService/Create.html:65 html/Ticket/Create.html:110
+msgid "Attach file"
+msgstr "Legg ved fil"
+
+#: html/Ticket/Create.html:98 html/Ticket/Update.html:89
+msgid "Attached file"
+msgstr "Vedlagt fil"
+
+#: NOT FOUND IN SOURCE
+msgid "Attachment '%1' could not be loaded"
+msgstr "Vedlegg '%1' kunne ikke lastes"
+
+#: lib/RT/Transaction_Overlay.pm:441
+msgid "Attachment created"
+msgstr "Vedlegg opprettet"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "Vedleggsnavn"
+
+#: html/Ticket/Elements/ShowAttachments:26
+msgid "Attachments"
+msgstr "Vedlegg"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "Aug."
+
+#: NOT FOUND IN SOURCE
+msgid "August"
+msgstr "August"
+
+#: html/Admin/Elements/ModifyUser:66
+msgid "AuthSystem"
+msgstr "AutSystem"
+
+#: etc/initialdata:206
+msgid "Autoreply"
+msgstr "Autosvar"
+
+#: etc/initialdata:72
+msgid "Autoreply To Requestors"
+msgstr "Autosvar Til Kunde"
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr "AutosvarTilKunde"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr "Ugyldig PGP-signatur: %1\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr "Ugyldig vedleggsid. Kunne ikke finne vedlegg '%1'\\n"
+
+#: bin/rt-commit-handler:827
+#. ($val)
+msgid "Bad data in %1"
+msgstr "Ugyldig data i %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr "Ugyldig transaksjonsnummer for vedlegg. %1 skulle vært %2\\n"
+
+#: html/Admin/Elements/GroupTabs:39 html/Admin/Elements/QueueTabs:39 html/Admin/Elements/UserTabs:38 html/Ticket/Elements/Tabs:90 html/User/Elements/GroupTabs:38
+msgid "Basics"
+msgstr "Detaljer"
+
+#: html/Ticket/Update.html:83
+msgid "Bcc"
+msgstr "Bcc"
+
+#: html/Admin/Elements/EditScrip:88 html/Admin/Global/GroupRights.html:85 html/Admin/Global/Template.html:46 html/Admin/Global/UserRights.html:54 html/Admin/Groups/GroupRights.html:73 html/Admin/Groups/Members.html:81 html/Admin/Groups/Modify.html:56 html/Admin/Groups/UserRights.html:55 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:45 html/Admin/Queues/UserRights.html:54 html/User/Groups/Modify.html:56
+msgid "Be sure to save your changes"
+msgstr "Sørg for Â lagre endringene dine"
+
+#: html/Elements/SelectDateRelation:34 lib/RT/CurrentUser.pm:320
+msgid "Before"
+msgstr "Før"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin Approval"
+msgstr "Begynn Godkjenning"
+
+#: etc/initialdata:202
+msgid "Blank"
+msgstr "Blank"
+
+#: html/Search/Listing.html:79
+msgid "Bookmarkable URL for this search"
+msgstr "URL som kan brukes som bokmerke for dette søket"
+
+#: html/Ticket/Elements/ShowHistory:39 html/Ticket/Elements/ShowHistory:45
+msgid "Brief headers"
+msgstr "Begrens headere"
+
+#: html/Search/Bulk.html:25 html/Search/Bulk.html:26
+msgid "Bulk ticket update"
+msgstr "Masseoppdatering av saker"
+
+#: lib/RT/User_Overlay.pm:1352
+msgid "Can not modify system users"
+msgstr "Kan ikke endre systembrukere"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Can this principal see this queue"
+msgstr "Kan denne primæren se denne køen"
+
+#: lib/RT/CustomField_Overlay.pm:206
+msgid "Can't add a custom field value without a name"
+msgstr "Kan ikke legge til en verdi for et fleksifelt uten navn"
+
+#: lib/RT/Link_Overlay.pm:132
+msgid "Can't link a ticket to itself"
+msgstr "Kan ikke koble en sak til seg selv"
+
+#: lib/RT/Ticket_Overlay.pm:2794
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr "Kan ikke flette inn i en flettet sak. Denne meldingen bør ikke forekomme"
+
+#: lib/RT/Ticket_Overlay.pm:2612 lib/RT/Ticket_Overlay.pm:2681
+msgid "Can't specifiy both base and target"
+msgstr "Kan ikke spesifisere både base og mål."
+
+#: html/autohandler:99
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr "Kunne ikke oprette bruker: %1"
+
+#: etc/initialdata:50 html/Admin/Queues/People.html:44 html/SelfService/Create.html:49 html/Ticket/Create.html:64 html/Ticket/Elements/EditPeople:51 html/Ticket/Elements/ShowPeople:35 html/Ticket/Update.html:45 html/Ticket/Update.html:78 lib/RT/ACE_Overlay.pm:88
+msgid "Cc"
+msgstr "Cc"
+
+#: html/SelfService/Prefs.html:31
+msgid "Change password"
+msgstr "Endre passord"
+
+#: html/Ticket/Create.html:101 html/Ticket/Update.html:92
+msgid "Check box to delete"
+msgstr "Merk for å slette"
+
+#: html/Admin/Elements/SelectRights:31
+msgid "Check box to revoke right"
+msgstr "Merk for å trekke tilbake rettighet"
+
+#: html/Ticket/Create.html:183 html/Ticket/Elements/EditLinks:131 html/Ticket/Elements/EditLinks:69 html/Ticket/Elements/ShowLinks:57
+msgid "Children"
+msgstr "Barn"
+
+#: html/Admin/Elements/ModifyUser:80 html/Admin/Users/Modify.html:132 html/User/Prefs.html:92
+msgid "City"
+msgstr "By"
+
+#: html/Ticket/Elements/ShowDates:47
+msgid "Closed"
+msgstr "Lukket"
+
+#: html/SelfService/Closed.html:25
+msgid "Closed Tickets"
+msgstr "Lukkede Saker"
+
+#: NOT FOUND IN SOURCE
+msgid "Closed requests"
+msgstr "Lukkede forespørsler"
+
+#: html/SelfService/Elements/Tabs:45
+msgid "Closed tickets"
+msgstr "Lukkede saker"
+
+#: NOT FOUND IN SOURCE
+msgid "Code"
+msgstr "Kode"
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr "Kunne ikke tolke kommando!\\n"
+
+#: html/Ticket/Elements/ShowTransaction:179 html/Ticket/Elements/Tabs:153
+msgid "Comment"
+msgstr "Kommenter"
+
+#: html/Admin/Elements/ModifyQueue:45 html/Admin/Queues/Modify.html:58
+msgid "Comment Address"
+msgstr "Kommentaraddresse"
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr "Kommentaren ble ikke lagret"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Comment on tickets"
+msgstr "Kommenter saker"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "CommentOnTicket"
+msgstr "KommenterSak"
+
+#: html/Admin/Elements/ModifyUser:35
+msgid "Comments"
+msgstr "Kommentarer"
+
+#: html/Ticket/ModifyAll.html:70 html/Ticket/Update.html:70
+msgid "Comments (Not sent to requestors)"
+msgstr "Kommentarer (Ikke send til kunder)"
+
+#: html/Search/Bulk.html:122
+msgid "Comments (not sent to requestors)"
+msgstr "Kommentarer (ikke sendt til kunder)"
+
+#: html/Elements/ViewUser:27
+#. ($name)
+msgid "Comments about %1"
+msgstr "Kommentarer til %1"
+
+#: html/Admin/Users/Modify.html:185 html/Ticket/Elements/ShowRequestor:44
+msgid "Comments about this user"
+msgstr "Kommentarer om denne brukeren"
+
+#: lib/RT/Transaction_Overlay.pm:543
+msgid "Comments added"
+msgstr "La til kommentarer "
+
+#: lib/RT/Action/Generic.pm:140
+msgid "Commit Stubbed"
+msgstr "Lagring forkortet"
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr "Kompilatorrestriksjoner"
+
+#: html/Admin/Elements/EditScrip:41
+msgid "Condition"
+msgstr "Forutsetning"
+
+#: bin/rt-crontool:109
+msgid "Condition matches..."
+msgstr "Forutsetning gjelder..."
+
+#: lib/RT/Scrip_Overlay.pm:160
+msgid "Condition not found"
+msgstr "Forutsetning ikke funnet"
+
+#: html/Elements/Tabs:50
+msgid "Configuration"
+msgstr "Konfigurasjon"
+
+#: html/SelfService/Prefs.html:33
+msgid "Confirm"
+msgstr "Bekreft"
+
+#: html/Admin/Elements/ModifyUser:60
+msgid "ContactInfoSystem"
+msgstr "KontaktInfoSystem"
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr "Kontatdato '%1' kunne ikke tolkes"
+
+#: html/Admin/Elements/ModifyTemplate:44 html/Ticket/ModifyAll.html:87
+msgid "Content"
+msgstr "Innhold"
+
+#: NOT FOUND IN SOURCE
+msgid "Coould not create group"
+msgstr "Kunne ikke opprette gruppen"
+
+#: etc/initialdata:271
+msgid "Correspondence"
+msgstr "Korrespondanse"
+
+#: html/Admin/Elements/ModifyQueue:39 html/Admin/Queues/Modify.html:51
+msgid "Correspondence Address"
+msgstr "Korrespondanseaddresse"
+
+#: lib/RT/Transaction_Overlay.pm:539
+msgid "Correspondence added"
+msgstr "Korrespondanse lagt til"
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr "Korrespondansen ble ikke lagret"
+
+#: lib/RT/Ticket_Overlay.pm:3525
+msgid "Could not add new custom field value for ticket. "
+msgstr "Kunne ikke legge til nye fleksifeltverdier for saken. "
+
+#: NOT FOUND IN SOURCE
+msgid "Could not add new custom field value for ticket. %1 "
+msgstr "Kunne ikke legge til nye fleksifeltverdier for saken. %1 "
+
+#: lib/RT/Ticket_Overlay.pm:3031 lib/RT/Ticket_Overlay.pm:3039 lib/RT/Ticket_Overlay.pm:3055
+msgid "Could not change owner. "
+msgstr "Kunne ikke endre eier. "
+
+#: html/Admin/Elements/EditCustomField:85 html/Admin/Elements/EditCustomFields:166
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr "Kunne ikke opprette fleksifelt"
+
+#: html/User/Groups/Modify.html:77 lib/RT/Group_Overlay.pm:474 lib/RT/Group_Overlay.pm:481
+msgid "Could not create group"
+msgstr "Kunne ikke opprette gruppe"
+
+#: html/Admin/Global/Template.html:75 html/Admin/Queues/Template.html:72
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr "Kunne ikke opprette mal: %1"
+
+#: lib/RT/Ticket_Overlay.pm:1073 lib/RT/Ticket_Overlay.pm:334
+msgid "Could not create ticket. Queue not set"
+msgstr "Kunne ikke opprette sak. Kø ikke satt"
+
+#: lib/RT/User_Overlay.pm:208 lib/RT/User_Overlay.pm:220 lib/RT/User_Overlay.pm:238 lib/RT/User_Overlay.pm:422
+msgid "Could not create user"
+msgstr "Kunne ikke opprette bruker"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not create watcher for requestor"
+msgstr "Kunne ikke opprette overvåker for kunde"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr "Kunne ikke finne en sak med id %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr "Kunne ikke finne gruppen %1."
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1422
+msgid "Could not find or create that user"
+msgstr "Kunne ikke finne eller lage den brukeren"
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1501
+msgid "Could not find that principal"
+msgstr "Kunne ikke finne den primæren"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr "Kunne ikke finne brukeren %1."
+
+#: html/Admin/Groups/Members.html:88 html/User/Groups/Members.html:90 html/User/Groups/Modify.html:82
+msgid "Could not load group"
+msgstr "Kunne ikke hente gruppen"
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr "Kunne ikke sette den primæren som %1 for denne køen"
+
+#: lib/RT/Ticket_Overlay.pm:1443
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr "Kunne ikke sette den primæren som %1 for denne saken"
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr "Kunne ikke fjerne den primæren som %1 for denne køen"
+
+#: lib/RT/Ticket_Overlay.pm:1559
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr "Knne ikke fjære den primæren som %1 for denne saken"
+
+#: lib/RT/Group_Overlay.pm:985
+msgid "Couldn't add member to group"
+msgstr "Kunne ikke legge til medlemmmer i gruppen"
+
+#: lib/RT/Ticket_Overlay.pm:3535 lib/RT/Ticket_Overlay.pm:3591
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr "Kunne ikke opprette en transaksjon: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr "Kunne ikke tolke gpgs svar\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr "Kunne ikke finne gruppen\\n"
+
+#: lib/RT/Interface/Web.pm:900
+msgid "Couldn't find row"
+msgstr "Kunne ikke finne raden"
+
+#: lib/RT/Group_Overlay.pm:959
+msgid "Couldn't find that principal"
+msgstr "Kunne ikke finne primæren"
+
+#: lib/RT/CustomField_Overlay.pm:240
+msgid "Couldn't find that value"
+msgstr "Kunne ikke finne verdien"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find that watcher"
+msgstr "Kunne ikke finne den overvåkern"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr "Kunne ikke finne bruker\\n"
+
+#: lib/RT/CurrentUser.pm:112
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr "Kunne ikke laste %1 fra brukerdatabasen.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load KeywordSelects."
+msgstr "Kunne ikke laste NøkkelordValg."
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr "Kunne ikke laste RTs konfigurasjonsfil '%1' %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr "Kunne ikke laste Scripsene."
+
+#: html/Admin/Groups/GroupRights.html:88 html/Admin/Groups/UserRights.html:75
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr "Kunne ikke laste gruppen %1"
+
+#: lib/RT/Link_Overlay.pm:175 lib/RT/Link_Overlay.pm:184 lib/RT/Link_Overlay.pm:211
+msgid "Couldn't load link"
+msgstr "Kunne ikke laste linken"
+
+#: html/Admin/Elements/EditCustomFields:147 html/Admin/Queues/People.html:121
+#. ($id)
+msgid "Couldn't load queue"
+msgstr "Kunne ikke laste køen"
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:72
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr "Kunne ikke laste køen %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr "Kunne ikke laste scripet"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr "Kunne ikke finne mal"
+
+#: html/Admin/Users/Prefs.html:79
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr "Kunne ikke laste den brukeren (%1)"
+
+#: html/SelfService/Display.html:109
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr "Kunne ikke laste saken '%1'"
+
+#: html/Admin/Elements/ModifyUser:86 html/Admin/Users/Modify.html:149 html/User/Prefs.html:98
+msgid "Country"
+msgstr "Land"
+
+#: html/Admin/Elements/CreateUserCalled:26 html/Ticket/Create.html:135 html/Ticket/Create.html:195
+msgid "Create"
+msgstr "Opprett"
+
+#: etc/initialdata:128
+msgid "Create Tickets"
+msgstr "Opprett Saker"
+
+#: html/Admin/Elements/EditCustomField:75
+msgid "Create a CustomField"
+msgstr "Oprett et fleksifelt"
+
+#: html/Admin/Queues/CustomField.html:48
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr "Opprett et fleksifelt for køen %1"
+
+#: html/Admin/Global/CustomField.html:48
+msgid "Create a CustomField which applies to all queues"
+msgstr "Opprett et fleksifelt for alle køer"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr "Opprett et nytt fleksifelt"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global Scrip"
+msgstr "Opprett et globalt Scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr "Opprett et nytt globalt scrip"
+
+#: html/Admin/Groups/Modify.html:67 html/Admin/Groups/Modify.html:93
+msgid "Create a new group"
+msgstr "Opprett en ny gruppe"
+
+#: html/User/Groups/Modify.html:67 html/User/Groups/Modify.html:92
+msgid "Create a new personal group"
+msgstr "Opprett en ny personlig gruppe"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr "Opprett en ny kø"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr "Opprett et nytt scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr "Opprett en ny mal"
+
+#: html/Ticket/Create.html:25 html/Ticket/Create.html:28 html/Ticket/Create.html:36
+msgid "Create a new ticket"
+msgstr "Opprett en ny sak"
+
+#: html/Admin/Users/Modify.html:214 html/Admin/Users/Modify.html:241
+msgid "Create a new user"
+msgstr "Opprett en ny bruker"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "Opprett en ny kø"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr "Opprett en kø kalt"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a request"
+msgstr "Opprett en forespørsel"
+
+#: html/Admin/Queues/Scrip.html:59
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr "Opprett et scrip for køen %1"
+
+#: html/Admin/Global/Template.html:69 html/Admin/Queues/Template.html:65
+msgid "Create a template"
+msgstr "Opprett en mal"
+
+#: html/SelfService/Create.html:25
+msgid "Create a ticket"
+msgstr "Opprett en sak"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1 / %2 / %3 "
+msgstr "Opprettelse feilet: %1 / %2 / %3"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1/%2/%3"
+msgstr "Opprettelse feilet: %1/%2/%3"
+
+#: etc/initialdata:130
+msgid "Create new tickets based on this scrip's template"
+msgstr "Opprett nye saker basert på dette scripets mal"
+
+#: html/SelfService/Create.html:78
+msgid "Create ticket"
+msgstr "Opprett sak"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Create tickets in this queue"
+msgstr "Opprett saker i denne køen"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Create, delete and modify custom fields"
+msgstr "Opprett, slett og modifiser fleksifelt"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Create, delete and modify queues"
+msgstr "Opprett, slett og endre køer"
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr "Opprett, slett og modifiser medlemmene av en brukers personlige grupper"
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify the members of personal groups"
+msgstr "Opprett, slett og modifiser medlemmene av personlige grupper"
+
+#: lib/RT/System.pm:60
+msgid "Create, delete and modify users"
+msgstr "Opprett, slett og modifiser brukere"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "CreateTicket"
+msgstr "OpprettSak"
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1167
+msgid "Created"
+msgstr "Opprettet"
+
+#: html/Admin/Elements/EditCustomField:88
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr "Opprettet Fleksifelt %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr "Opprettet malen %1"
+
+#: html/Ticket/Elements/EditLinks:28
+msgid "Current Relationships"
+msgstr "Eksisterende Forhold"
+
+#: html/Admin/Elements/EditScrips:30
+msgid "Current Scrips"
+msgstr "Eksisterende Scrips"
+
+#: html/Admin/Groups/Members.html:39 html/User/Groups/Members.html:42
+msgid "Current members"
+msgstr "Eksisterende medlemmer"
+
+#: html/Admin/Elements/SelectRights:29
+msgid "Current rights"
+msgstr "Eksisterende rettigheter"
+
+#: html/Search/Listing.html:71
+msgid "Current search criteria"
+msgstr "Eksisterende søkekriterier"
+
+#: html/Admin/Queues/People.html:41 html/Ticket/Elements/EditPeople:45
+msgid "Current watchers"
+msgstr "Eksisterende overvåkere"
+
+#: html/Admin/Global/CustomField.html:55
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr "Fleksifeltet #%1"
+
+#: html/Admin/Elements/QueueTabs:53 html/Admin/Elements/SystemTabs:40 html/Admin/Global/index.html:50 html/Ticket/Elements/ShowSummary:36
+msgid "Custom Fields"
+msgstr "Fleksifelt"
+
+#: html/Admin/Elements/EditScrip:73
+msgid "Custom action cleanup code"
+msgstr "Avsluttningskode"
+
+#: html/Admin/Elements/EditScrip:65
+msgid "Custom action preparation code"
+msgstr "Forberedelseskode"
+
+#: html/Admin/Elements/EditScrip:49
+msgid "Custom condition"
+msgstr "Forutsetning"
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr "Fleksifeltet %1 %2 %3"
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr "Fleksifeltet %1 har en verdi."
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr "Fleksifeltet %1 har ingen verdi."
+
+#: lib/RT/Ticket_Overlay.pm:3427
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr "Fleksifeltet %1 kunne ikke finnes"
+
+#: html/Admin/Elements/EditCustomFields:197
+msgid "Custom field deleted"
+msgstr "Fleksifeltet slettet"
+
+#: lib/RT/Ticket_Overlay.pm:3577
+msgid "Custom field not found"
+msgstr "Fleksifeltet kunne ikke finnes"
+
+#: lib/RT/CustomField_Overlay.pm:350
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr "Verdien %1 for fleksifeltet %2 kunne ikke finnes"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr "Fleksifeltets verdi endret fra %1 til %2"
+
+#: lib/RT/CustomField_Overlay.pm:250
+msgid "Custom field value could not be deleted"
+msgstr "Fleksifeltets verdi kunne ikke slettes"
+
+#: lib/RT/CustomField_Overlay.pm:356
+msgid "Custom field value could not be found"
+msgstr "Fleksifeltets verdi kunne ikke finnes"
+
+#: lib/RT/CustomField_Overlay.pm:248 lib/RT/CustomField_Overlay.pm:358
+msgid "Custom field value deleted"
+msgstr "Fleksifeltverdi slettet"
+
+#: lib/RT/Transaction_Overlay.pm:548
+msgid "CustomField"
+msgstr "FleksiFelt"
+
+#: NOT FOUND IN SOURCE
+msgid "Data error"
+msgstr "Datafeil"
+
+#: html/SelfService/Display.html:39 html/Ticket/Create.html:161 html/Ticket/Elements/ShowSummary:55 html/Ticket/Elements/Tabs:93 html/Ticket/ModifyAll.html:44
+msgid "Dates"
+msgstr "Datoer"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "Des."
+
+#: NOT FOUND IN SOURCE
+msgid "December"
+msgstr "Desember"
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr "Standard Autosvarmal"
+
+#: etc/initialdata:207
+msgid "Default Autoresponse template"
+msgstr "Standard Autosvarmal"
+
+#: etc/initialdata:281
+msgid "Default admin comment template"
+msgstr "Standard Adminkommentarmal"
+
+#: etc/initialdata:260
+msgid "Default admin correspondence template"
+msgstr "Standard Adminkorrespondensemal"
+
+#: etc/initialdata:272
+msgid "Default correspondence template"
+msgstr "Standard korrespondensemal"
+
+#: etc/initialdata:238
+msgid "Default transaction template"
+msgstr "Standard transaksjonsmal"
+
+#: lib/RT/Transaction_Overlay.pm:643
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr "Standard: %1/%2 endret seg fra %3 til %4"
+
+#: html/User/Delegation.html:25 html/User/Delegation.html:28
+msgid "Delegate rights"
+msgstr "Deleger rettigheter"
+
+#: lib/RT/System.pm:63
+msgid "Delegate specific rights which have been granted to you."
+msgstr "Deleger spesifikke rettigheter som har blitt gitt til deg."
+
+#: lib/RT/System.pm:63
+msgid "DelegateRights"
+msgstr "DelegerRettigheter"
+
+#: html/User/Elements/Tabs:38
+msgid "Delegation"
+msgstr "Delegering"
+
+#: NOT FOUND IN SOURCE
+msgid "Delete"
+msgstr "Slett"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "Delete tickets"
+msgstr "Slett saker"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "DeleteTicket"
+msgstr "SlettSak"
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr "Sletting av dette objektet kan føre til inkonsistens"
+
+#: lib/RT/Queue_Overlay.pm:292
+msgid "Deleting this object would break referential integrity"
+msgstr "Sletting av dette objektet vil føre til inkonsistens"
+
+#: lib/RT/User_Overlay.pm:438
+msgid "Deleting this object would violate referential integrity"
+msgstr "Sletting av dette objektet ville føre til inkonsistens"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity."
+msgstr "Sletting av dette objektet ville føre til inkonsisistens."
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity. That's bad."
+msgstr "Sletting av dette objektet ville føre til inkonsistens. Det er uheldig."
+
+#: html/Approvals/Elements/Approve:45
+msgid "Deny"
+msgstr "Nekt"
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/EditLinks:123 html/Ticket/Elements/EditLinks:47 html/Ticket/Elements/ShowDependencies:32 html/Ticket/Elements/ShowLinks:37
+msgid "Depended on by"
+msgstr "Avhengighet fra"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr "Avhengigheter: \\n"
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:180 html/Ticket/Elements/EditLinks:119 html/Ticket/Elements/EditLinks:36 html/Ticket/Elements/ShowDependencies:25 html/Ticket/Elements/ShowLinks:27
+msgid "Depends on"
+msgstr "Avhengig av"
+
+#: NOT FOUND IN SOURCE
+msgid "DependsOn"
+msgstr "AvhengigAv"
+
+#: html/Elements/SelectSortOrder:35
+msgid "Descending"
+msgstr "Synkende"
+
+#: html/SelfService/Create.html:73 html/Ticket/Create.html:119
+msgid "Describe the issue below"
+msgstr "Beskriv problemet under"
+
+#: html/Admin/Elements/AddCustomFieldValue:37 html/Admin/Elements/EditCustomField:39 html/Admin/Elements/EditScrip:34 html/Admin/Elements/ModifyQueue:36 html/Admin/Elements/ModifyTemplate:36 html/Admin/Groups/Modify.html:49 html/Admin/Queues/Modify.html:48 html/Elements/SelectGroups:27 html/User/Groups/Modify.html:49
+msgid "Description"
+msgstr "Beskrivelse"
+
+#: NOT FOUND IN SOURCE
+msgid "Details"
+msgstr "Detaljer"
+
+#: html/Ticket/Elements/Tabs:85
+msgid "Display"
+msgstr "Vis"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Display Access Control List"
+msgstr "Vis Rettigheter"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Display Scrip templates for this queue"
+msgstr "Vis Scrip-maler for denne køen"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Display Scrips for this queue"
+msgstr "Vis Scrip-maler for denne køen"
+
+#: html/Ticket/Elements/ShowHistory:35
+msgid "Display mode"
+msgstr "Visningsmodus"
+
+#: NOT FOUND IN SOURCE
+msgid "Display ticket #%1"
+msgstr "Vis saken #%1"
+
+#: lib/RT/System.pm:54
+msgid "Do anything and everything"
+msgstr "Gjør hva som helst"
+
+#: html/Elements/Refresh:30
+msgid "Don't refresh this page."
+msgstr "Ikke last denne siden p nytt"
+
+#: html/Search/Elements/PickRestriction:114
+msgid "Don't show search results"
+msgstr "Ikke vis søkeresultat"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "Download"
+msgstr "Last ned"
+
+#: html/Elements/SelectDateType:32 html/Ticket/Create.html:167 html/Ticket/Elements/EditDates:45 html/Ticket/Elements/ShowDates:43 lib/RT/Ticket_Overlay.pm:1171
+msgid "Due"
+msgstr "Innen"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr "Innendato '%1' kunne ikke tolkes""
+
+#: bin/rt-commit-handler:754
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr "FEIL: Kunne ikke laste sak '%1': %2.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit"
+msgstr "Rediger"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit Conditions"
+msgstr "Rediger Forhold"
+
+#: html/Admin/Queues/CustomFields.html:45
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr "Rediger fleksifelt for %1"
+
+#: html/Ticket/ModifyLinks.html:36
+msgid "Edit Relationships"
+msgstr "Rediger Forhold"
+
+#: html/Admin/Queues/Templates.html:42
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr "Rediger Maler for køen %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit keywords"
+msgstr "Rediger nøkkelord"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr "Rediger scrips"
+
+#: html/Admin/Global/index.html:46
+msgid "Edit system templates"
+msgstr "Rediger systemmal"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr "Rediger maler for %1"
+
+#: html/Admin/Elements/ModifyQueue:25 html/Admin/Queues/Modify.html:118
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr "Rediger Konfigurasjon for køen %1"
+
+#: html/Admin/Elements/ModifyUser:25
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr "Redigerer Konfigurasjonen av brukern %1"
+
+#: html/Admin/Elements/EditCustomField:91
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr "Redigerer Fleksifeltet %1"
+
+#: html/Admin/Groups/Members.html:32
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr "Redigerer medlemsskap for gruppen %1""
+
+#: html/User/Groups/Members.html:129
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr "Redigerer medlemsskap for den personlige gruppen %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr "Redigerer malen %1"
+
+#: lib/RT/Ticket_Overlay.pm:2622 lib/RT/Ticket_Overlay.pm:2690
+msgid "Either base or target must be specified"
+msgstr "Enten base eller mål må oppgis"
+
+#: html/Admin/Users/Modify.html:53 html/Admin/Users/Prefs.html:46 html/Elements/SelectUsers:27 html/Ticket/Elements/AddWatchers:56 html/User/Prefs.html:42
+msgid "Email"
+msgstr "Epost"
+
+#: lib/RT/User_Overlay.pm:188
+msgid "Email address in use"
+msgstr "Epostaddresse i bruk"
+
+#: html/Admin/Elements/ModifyUser:42
+msgid "EmailAddress"
+msgstr "EpostAddresse"
+
+#: html/Admin/Elements/ModifyUser:54
+msgid "EmailEncoding"
+msgstr "EpostFormat"
+
+#: html/Admin/Elements/EditCustomField:51
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr "Aktivt (Fjern merkingen for Â deaktivere dette fleksifeltet)"
+
+#: html/Admin/Groups/Modify.html:53 html/User/Groups/Modify.html:53
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr "Aktiv (Fjern merkingen for Â deaktivere denne gruppen)"
+
+#: html/Admin/Queues/Modify.html:84
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr "Aktiv (Fjern merkingen for Â deaktivere denne køen)"
+
+#: html/Admin/Elements/EditCustomFields:99
+msgid "Enabled Custom Fields"
+msgstr "Aktive Fleksifelt"
+
+#: html/Admin/Queues/index.html:56
+msgid "Enabled Queues"
+msgstr "Aktive Køer"
+
+#: html/Admin/Elements/EditCustomField:107 html/Admin/Groups/Modify.html:117 html/Admin/Queues/Modify.html:140 html/Admin/Users/Modify.html:283 html/User/Groups/Modify.html:117
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr "Aktiv status %1"
+
+#: lib/RT/CustomField_Overlay.pm:428
+msgid "Enter multiple values"
+msgstr "Skriv multiple verdier"
+
+#: lib/RT/CustomField_Overlay.pm:425
+msgid "Enter one value"
+msgstr "Skriv en verdi"
+
+#: html/Ticket/Elements/EditLinks:112
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "Skriv saker og/eller URIer som det skal linkes til. Separer dem med mellomrom"
+
+#: html/Elements/Login:39 html/SelfService/Error.html:25 html/SelfService/Error.html:26
+msgid "Error"
+msgstr "Feil"
+
+#: NOT FOUND IN SOURCE
+msgid "Error adding watcher"
+msgstr "Feilet ved opprettelse av Overvåker"
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr "Feil i parameterne til Queue->AddWatcher"
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr "Feil i parameterne til Queue->DelWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1356
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr "Feil i parameterne til Ticket->AddWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1532
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr "Feil i parameterne til Ticket->DelWatcher"
+
+#: etc/initialdata:20
+msgid "Everyone"
+msgstr "Alle"
+
+#: bin/rt-crontool:194
+msgid "Example:"
+msgstr "Eksempel:"
+
+#: html/Admin/Elements/ModifyUser:64
+msgid "ExternalAuthId"
+msgstr "EksternAutId"
+
+#: html/Admin/Elements/ModifyUser:58
+msgid "ExternalContactInfoId"
+msgstr "EksternKontaktInfoId"
+
+#: html/Admin/Users/Modify.html:73
+msgid "Extra info"
+msgstr "Ekstra info"
+
+#: lib/RT/User_Overlay.pm:302
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr "Kunne ikke finne pseudogruppen 'Privilgerte' brukere."
+
+#: lib/RT/User_Overlay.pm:309
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr "Kunne ikke finne 'pseudogruppen 'Upriviligerte' brukere"
+
+#: bin/rt-crontool:138
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr "Kunne ikke laste modulen %1. (%2)"
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "Feb."
+
+#: NOT FOUND IN SOURCE
+msgid "February"
+msgstr "Februar"
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr "End"
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:59 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "Endelig Prioritet"
+
+#: lib/RT/Ticket_Overlay.pm:1162
+msgid "FinalPriority"
+msgstr "EndeligPrioritet"
+
+#: html/Admin/Queues/People.html:61 html/Ticket/Elements/EditPeople:34
+msgid "Find group whose"
+msgstr "Finn grupper hvor"
+
+#: NOT FOUND IN SOURCE
+msgid "Find new/open tickets"
+msgstr "Finn nye/Âpne saker"
+
+#: html/Admin/Queues/People.html:57 html/Admin/Users/index.html:46 html/Ticket/Elements/EditPeople:30
+msgid "Find people whose"
+msgstr "Finn folk hvor"
+
+#: html/Search/Listing.html:108
+msgid "Find tickets"
+msgstr "Finn saker"
+
+#: NOT FOUND IN SOURCE
+msgid "Finish Approval"
+msgstr "Fullfør godkjennelse"
+
+#: html/Ticket/Elements/Tabs:58
+msgid "First"
+msgstr "Først"
+
+#: html/Search/Listing.html:41
+msgid "First page"
+msgstr "Første side"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr "Foo Bar Baz"
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr "Foo!"
+
+#: html/Search/Bulk.html:87
+msgid "Force change"
+msgstr "Tving gjennom endring"
+
+#: html/Search/Listing.html:106
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr "Fant %quant(%1,sak)"
+
+#: lib/RT/Interface/Web.pm:902
+msgid "Found Object"
+msgstr "Fant Objektet"
+
+#: html/Admin/Elements/ModifyUser:44
+msgid "FreeformContactInfo"
+msgstr "FriforkKontaktInfo"
+
+#: lib/RT/CustomField_Overlay.pm:38
+msgid "FreeformMultiple"
+msgstr "FriformMultipel"
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformSingle"
+msgstr "FriformSingel"
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "Fre."
+
+#: html/Ticket/Elements/ShowHistory:41 html/Ticket/Elements/ShowHistory:51
+msgid "Full headers"
+msgstr "Fulle headere"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr "Henter brukerinfo fra pgp signatur\\n"
+
+#: lib/RT/Transaction_Overlay.pm:593
+#. ($New->Name)
+msgid "Given to %1"
+msgstr "Gitt til %1"
+
+#: html/Admin/Elements/Tabs:41 html/Admin/index.html:38
+msgid "Global"
+msgstr "Global"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Keyword Selections"
+msgstr "Globale Nøkkelordvalg"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr "Globale Scrip"
+
+#: html/Admin/Elements/SelectTemplate:38
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr "Globale maler: %1"
+
+#: html/Admin/Elements/EditCustomFields:75 html/Admin/Queues/People.html:59 html/Admin/Queues/People.html:63 html/Admin/Queues/index.html:44 html/Admin/Users/index.html:49 html/Ticket/Elements/EditPeople:32 html/Ticket/Elements/EditPeople:36 html/index.html:41
+msgid "Go!"
+msgstr "Start!"
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr "Gyldig pgp sig fra %1\\n"
+
+#: html/Search/Listing.html:50
+msgid "Goto page"
+msgstr "Gå til siden"
+
+#: html/Elements/GotoTicket:25 html/SelfService/Elements/GotoTicket:25
+msgid "Goto ticket"
+msgstr "Gå til saken"
+
+#: NOT FOUND IN SOURCE
+msgid "Grand"
+msgstr "Stor"
+
+#: html/Ticket/Elements/AddWatchers:46 html/User/Elements/DelegateRights:78
+msgid "Group"
+msgstr "Gruppe"
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr "Gruppen %1 %2: %3"
+
+#: html/Admin/Elements/GroupTabs:45 html/Admin/Elements/QueueTabs:57 html/Admin/Elements/SystemTabs:44 html/Admin/Global/index.html:55
+msgid "Group Rights"
+msgstr "Grupperettigheter"
+
+#: lib/RT/Group_Overlay.pm:965
+msgid "Group already has member"
+msgstr "Alt medlem av gruppen"
+
+#: NOT FOUND IN SOURCE
+msgid "Group could not be created."
+msgstr "Gruppen kunne ikke lastes."
+
+#: html/Admin/Groups/Modify.html:77
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr "Gruppen kunne ikke opprettes: %1"
+
+#: lib/RT/Group_Overlay.pm:497
+msgid "Group created"
+msgstr "Gruppen opprettet"
+
+#: lib/RT/Group_Overlay.pm:1133
+msgid "Group has no such member"
+msgstr "Gruppen har ikke det medlemmet"
+
+#: lib/RT/Group_Overlay.pm:945 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1429 lib/RT/Ticket_Overlay.pm:1507
+msgid "Group not found"
+msgstr "Fant ikke gruppen"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr "Fant ikke gruppen.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr "Ikke spesifisert gruppe.\\n"
+
+#: html/Admin/Elements/SelectNewGroupMembers:35 html/Admin/Elements/Tabs:35 html/Admin/Groups/Members.html:64 html/Admin/Queues/People.html:83 html/Admin/index.html:32 html/User/Groups/Members.html:67
+msgid "Groups"
+msgstr "Grupper"
+
+#: lib/RT/Group_Overlay.pm:971
+msgid "Groups can't be members of their members"
+msgstr "Grupper kan ikke være medlemmer av sine medlemmer"
+
+#: lib/RT/Interface/CLI.pm:73 lib/RT/Interface/CLI.pm:73
+msgid "Hello!"
+msgstr "Hallo!"
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr "Hallo, %1"
+
+#: html/Ticket/Elements/ShowHistory:30 html/Ticket/Elements/Tabs:88
+msgid "History"
+msgstr "Historikk"
+
+#: html/Admin/Elements/ModifyUser:68
+msgid "HomePhone"
+msgstr "HjemmeTelefon"
+
+#: html/Elements/Tabs:44
+msgid "Homepage"
+msgstr "Hjemmeside"
+
+#: lib/RT/Base.pm:74
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr "Jeg har %quant(%1, sementblandere)."
+
+#: NOT FOUND IN SOURCE
+msgid "I have [quant,_1,concrete mixer]."
+msgstr "Jeg har [quant,_1,sementblandere]."
+
+#: html/Ticket/Elements/ShowBasics:27 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr "Id"
+
+#: html/Admin/Users/Modify.html:44 html/User/Prefs.html:39
+msgid "Identity"
+msgstr "Identitet"
+
+#: etc/upgrade/2.1.71:86
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr "Hvis en godkjenner blir avvist, avvis orginalen, og slett ventende godkjenninger"
+
+#: bin/rt-crontool:190
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr "Hvis dette verktøyet var setgid kunne en fiendtlig lokal bruker bruke dette verktøyet for å oppnå administrativ tilgang til RT."
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "If you've updated anything above, be sure to"
+msgstr "Hvis du har oppdatert noe over, sørg for at"
+
+#: lib/RT/Interface/Web.pm:894
+msgid "Illegal value for %1"
+msgstr "Ugyldig verdig for %1"
+
+#: lib/RT/Interface/Web.pm:897
+msgid "Immutable field"
+msgstr "Låst felt"
+
+#: html/Admin/Elements/EditCustomFields:74
+msgid "Include disabled custom fields in listing."
+msgstr "Inkluder deaktiverte fleksifelt i listen."
+
+#: html/Admin/Queues/index.html:43
+msgid "Include disabled queues in listing."
+msgstr "Inkluder deaktiverte køer i listen."
+
+#: html/Admin/Users/index.html:47
+msgid "Include disabled users in search."
+msgstr "Inkluder deaktiverte brukere i søket."
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr "Startprioritet"
+
+#: lib/RT/Ticket_Overlay.pm:1161 lib/RT/Ticket_Overlay.pm:1163
+msgid "InitialPriority"
+msgstr "StartPrioritet"
+
+#: lib/RT/ScripAction_Overlay.pm:105
+msgid "Input error"
+msgstr "Feil i inntasting"
+
+#: NOT FOUND IN SOURCE
+msgid "Interest noted"
+msgstr "Interesse registrert"
+
+#: lib/RT/Ticket_Overlay.pm:3796
+msgid "Internal Error"
+msgstr "Intern Feil"
+
+#: lib/RT/Record.pm:143
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr "Intern Feil: %1"
+
+#: lib/RT/Group_Overlay.pm:644
+msgid "Invalid Group Type"
+msgstr "Ugyldig gruppetype"
+
+#: lib/RT/Principal_Overlay.pm:128
+msgid "Invalid Right"
+msgstr "Ugyldige rettigheter"
+
+#: NOT FOUND IN SOURCE
+msgid "Invalid Type"
+msgstr "Ugyldig Type"
+
+#: lib/RT/Interface/Web.pm:899
+msgid "Invalid data"
+msgstr "Ugyldig data"
+
+#: lib/RT/Ticket_Overlay.pm:439
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr "Ugydlig eier. Setter til 'nobody'."
+
+#: lib/RT/Scrip_Overlay.pm:134 lib/RT/Template_Overlay.pm:251
+msgid "Invalid queue"
+msgstr "Ugyldig kø"
+
+#: lib/RT/ACE_Overlay.pm:244 lib/RT/ACE_Overlay.pm:253 lib/RT/ACE_Overlay.pm:259 lib/RT/ACE_Overlay.pm:270 lib/RT/ACE_Overlay.pm:275
+msgid "Invalid right"
+msgstr "Ugyldige rettigheter"
+
+#: lib/RT/Record.pm:118
+#. ($key)
+msgid "Invalid value for %1"
+msgstr "Ugyldig verdi for %1"
+
+#: lib/RT/Ticket_Overlay.pm:3434
+msgid "Invalid value for custom field"
+msgstr "Ugyldig verdi for fleksifeltet."
+
+#: lib/RT/Ticket_Overlay.pm:346
+msgid "Invalid value for status"
+msgstr "Ugyldig verdi for status"
+
+#: bin/rt-crontool:191
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr "Det er ekstremt viktig at ikkepriviligerte brukere ikke har tilgang til dette verktøyet."
+
+#: bin/rt-crontool:192
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr "Det er anbefalt at du oppretter en upriviligert unixbruker med korrekt gruppemedlemsskap og tilgang til RT for Â kjøre dette verktøyet."
+
+#: bin/rt-crontool:163
+msgid "It takes several arguments:"
+msgstr "Det tar flere parametere:"
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr "Ting som venter p min godkjenning"
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "Jan."
+
+#: NOT FOUND IN SOURCE
+msgid "January"
+msgstr "Januar"
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "Join or leave this group"
+msgstr "Bli med i eller forlat denne gruppen"
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "Jul."
+
+#: NOT FOUND IN SOURCE
+msgid "July"
+msgstr "Juli"
+
+#: html/Ticket/Elements/Tabs:99
+msgid "Jumbo"
+msgstr "Total"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "Jun."
+
+#: NOT FOUND IN SOURCE
+msgid "June"
+msgstr "Juni"
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr "Nøkkelord"
+
+#: html/Admin/Elements/ModifyUser:52
+msgid "Lang"
+msgstr "Språk"
+
+#: html/Ticket/Elements/Tabs:73
+msgid "Last"
+msgstr "Siste"
+
+#: html/Ticket/Elements/EditDates:38 html/Ticket/Elements/ShowDates:39
+msgid "Last Contact"
+msgstr "Siste Kontakt"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Contacted"
+msgstr "Sist kontaktet"
+
+#: html/Search/Elements/TicketHeader:41
+msgid "Last Notified"
+msgstr "Sist Informert"
+
+#: html/Elements/SelectDateType:30
+msgid "Last Updated"
+msgstr "Sist Oppdatert"
+
+#: NOT FOUND IN SOURCE
+msgid "LastUpdated"
+msgstr "SistOppdatert"
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr "Igjen"
+
+#: html/Admin/Users/Modify.html:83
+msgid "Let this user access RT"
+msgstr "La denne brukeren få tilgang til RT"
+
+#: html/Admin/Users/Modify.html:87
+msgid "Let this user be granted rights"
+msgstr "La denne brukeren få rettigheter"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr "Begrenser eier til %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr "Begrenser køen til %1 %2"
+
+#: lib/RT/Ticket_Overlay.pm:2704
+msgid "Link already exists"
+msgstr "Lenke finnes alt"
+
+#: lib/RT/Ticket_Overlay.pm:2716
+msgid "Link could not be created"
+msgstr "Lenke kunne ikke opprettes"
+
+#: lib/RT/Ticket_Overlay.pm:2724 lib/RT/Ticket_Overlay.pm:2734
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr "Lenke opprettet (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2645
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr "Lenke slettet (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2651
+msgid "Link not found"
+msgstr "Lenke ble ikke funnet"
+
+#: html/Ticket/ModifyLinks.html:25 html/Ticket/ModifyLinks.html:29
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr "Knytt sak #%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Link ticket %1"
+msgstr "Knytt sak %1"
+
+#: html/Ticket/Elements/Tabs:97
+msgid "Links"
+msgstr "Lenker"
+
+#: html/Admin/Users/Modify.html:114 html/User/Prefs.html:85
+msgid "Location"
+msgstr "Lokasjon"
+
+#: lib/RT.pm:159
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr "Logkatalogen %1 ble ikke funnet eller kunne ikke skrives til.\\nRT kan ikke kjøre."
+
+#: html/Elements/Header:57
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "Logget inn som %1"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:35 html/Elements/Login:44 html/Elements/Login:54
+msgid "Login"
+msgstr "Innlogging"
+
+#: html/Elements/Header:54
+msgid "Logout"
+msgstr "Logg av"
+
+#: html/Search/Bulk.html:86
+msgid "Make Owner"
+msgstr "Sett Eier"
+
+#: html/Search/Bulk.html:102
+msgid "Make Status"
+msgstr "Sett Status"
+
+#: html/Search/Bulk.html:109
+msgid "Make date Due"
+msgstr "Sett tidsfrist" 
+
+#: html/Search/Bulk.html:110
+msgid "Make date Resolved"
+msgstr "Sett løsningsdato"
+
+#: html/Search/Bulk.html:107
+msgid "Make date Started"
+msgstr "Sett startdato"
+
+#: html/Search/Bulk.html:106
+msgid "Make date Starts"
+msgstr "Sett startdato"
+
+#: html/Search/Bulk.html:108
+msgid "Make date Told"
+msgstr "Sett informert dato"
+
+#: html/Search/Bulk.html:99
+msgid "Make priority"
+msgstr "Sett prioritet"
+
+#: html/Search/Bulk.html:100
+msgid "Make queue"
+msgstr "Sett Kø"
+
+#: html/Search/Bulk.html:98
+msgid "Make subject"
+msgstr "Sett Emne"
+
+#: html/Admin/index.html:33
+msgid "Manage groups and group membership"
+msgstr "Sett grupper og gruppemedlemsskap"
+
+#: html/Admin/index.html:39
+msgid "Manage properties and configuration which apply to all queues"
+msgstr "Rediger egenskaper og konfigurasjon som gjelder for alle køer"
+
+#: html/Admin/index.html:36
+msgid "Manage queues and queue-specific properties"
+msgstr "Rediger køer og kø-spesifike egenskaper"
+
+#: html/Admin/index.html:30
+msgid "Manage users and passwords"
+msgstr "Rediger brukere og passord"
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "Mar."
+
+#: NOT FOUND IN SOURCE
+msgid "March"
+msgstr "Mars"
+
+#: NOT FOUND IN SOURCE
+msgid "May"
+msgstr "Mai"
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "Mai."
+
+#: lib/RT/Group_Overlay.pm:982
+msgid "Member added"
+msgstr "Medlem lagt til"
+
+#: lib/RT/Group_Overlay.pm:1140
+msgid "Member deleted"
+msgstr "Medlem slettet"
+
+#: lib/RT/Group_Overlay.pm:1144
+msgid "Member not deleted"
+msgstr "Medlem ikke slettet"
+
+#: html/Elements/SelectLinkType:26
+msgid "Member of"
+msgstr "Medlem av"
+
+#: NOT FOUND IN SOURCE
+msgid "MemberOf"
+msgstr "MedlemAv"
+
+#: html/Admin/Elements/GroupTabs:42 html/User/Elements/GroupTabs:42
+msgid "Members"
+msgstr "Medlemmer"
+
+#: lib/RT/Ticket_Overlay.pm:2891
+msgid "Merge Successful"
+msgstr "Fletting vellykket"
+
+#: lib/RT/Ticket_Overlay.pm:2811
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "Fletting feilet. Kunne ikke sette EffektivId"
+
+#: html/Ticket/Elements/EditLinks:115
+msgid "Merge into"
+msgstr "Flett inn i"
+
+#: html/Ticket/Update.html:102
+msgid "Message"
+msgstr "Melding"
+
+#: lib/RT/Interface/Web.pm:901
+msgid "Missing a primary key?: %1"
+msgstr "Mangler en primærnøkkel?: %1"
+
+#: html/Admin/Users/Modify.html:169 html/User/Prefs.html:54
+msgid "Mobile"
+msgstr "Mobil"
+
+#: html/Admin/Elements/ModifyUser:72
+msgid "MobilePhone"
+msgstr "MobilTelefon"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify Access Control List"
+msgstr "Endre Tilgangslister"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Custom Field %1"
+msgstr "Endre Fleksifeltet %1"
+
+#: html/Admin/Global/CustomFields.html:44 html/Admin/Global/index.html:51
+msgid "Modify Custom Fields which apply to all queues"
+msgstr "Endre Fleksifelt som gjelder for alle køer"
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "Modify Scrip templates for this queue"
+msgstr "Endre Scripmaler for denne køen"
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "Modify Scrips for this queue"
+msgstr "Endre Scrips for denne køen"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify System ACLS"
+msgstr "Endre SystemACLer"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr "Endre Malen %1"
+
+#: html/Admin/Queues/CustomField.html:45
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr "Endre et fleksifelt for køen %1"
+
+#: html/Admin/Global/CustomField.html:53
+msgid "Modify a CustomField which applies to all queues"
+msgstr "Endre et fleksifelt som gjelder for alle køer"
+
+#: html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr "Endre et scrip for køen %1"
+
+#: html/Admin/Global/Scrip.html:48
+msgid "Modify a scrip which applies to all queues"
+msgstr "Endre et scrip som gjelder for alle køer"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify dates for # %1"
+msgstr "Endre datoer for # %1"
+
+#: html/Ticket/ModifyDates.html:25 html/Ticket/ModifyDates.html:29
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr "Endre datoer for #%1"
+
+#: html/Ticket/ModifyDates.html:35
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr "Endre datoer for sak # %1"
+
+#: html/Admin/Global/GroupRights.html:25 html/Admin/Global/GroupRights.html:28 html/Admin/Global/index.html:56
+msgid "Modify global group rights"
+msgstr "Endre globale grupperettigheter"
+
+#: html/Admin/Global/GroupRights.html:33
+msgid "Modify global group rights."
+msgstr "Endre globale grupperettigheter"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for groups"
+msgstr "Endre globale rettigheter for grupper"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for users"
+msgstr "Endre globale rettigheter for brukere"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr "Endre globale scrips"
+
+#: html/Admin/Global/UserRights.html:25 html/Admin/Global/UserRights.html:28 html/Admin/Global/index.html:60
+msgid "Modify global user rights"
+msgstr "Endre globale brukerrettigheter"
+
+#: html/Admin/Global/UserRights.html:33
+msgid "Modify global user rights."
+msgstr "Endre globale brukerrettigheter"
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "Modify group metadata or delete group"
+msgstr "Endre gruppens metadata eller slette gruppen"
+
+#: html/Admin/Groups/GroupRights.html:25 html/Admin/Groups/GroupRights.html:29 html/Admin/Groups/GroupRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr "Endre grupperettigheter for %1 gruppen"
+
+#: html/Admin/Queues/GroupRights.html:25 html/Admin/Queues/GroupRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr "Endre grupperettigheter %1 køen"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Modify membership roster for this group"
+msgstr "Endre medlemsliste for denne gruppen"
+
+#: lib/RT/System.pm:61
+msgid "Modify one's own RT account"
+msgstr "Endre sin egen RT konto"
+
+#: html/Admin/Queues/People.html:25 html/Admin/Queues/People.html:29
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr "Endre hvem som er relatert til %1 køen"
+
+#: html/Ticket/ModifyPeople.html:25 html/Ticket/ModifyPeople.html:29 html/Ticket/ModifyPeople.html:35
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr "Endre hvem som er relater til sak #%1"
+
+#: html/Admin/Queues/Scrips.html:44
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr "Endre scrips for %1 køen"
+
+#: html/Admin/Global/Scrips.html:44 html/Admin/Global/index.html:42
+msgid "Modify scrips which apply to all queues"
+msgstr "Endre scrips som gjelder alle køer"
+
+#: html/Admin/Global/Template.html:25 html/Admin/Global/Template.html:30 html/Admin/Global/Template.html:81 html/Admin/Queues/Template.html:78
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr "Endre mal %1"
+
+#: html/Admin/Global/Templates.html:44
+msgid "Modify templates which apply to all queues"
+msgstr "Endre maler som gjelder for alle køer"
+
+#: html/Admin/Groups/Modify.html:87 html/User/Groups/Modify.html:86
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr "Endre gruppen %1"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Modify the queue watchers"
+msgstr "Endre overvåkere for køen"
+
+#: html/Admin/Users/Modify.html:236
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr "Endre brukeren %1"
+
+#: html/Ticket/ModifyAll.html:37
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "Endre sak # %1"
+
+#: html/Ticket/Modify.html:25 html/Ticket/Modify.html:28 html/Ticket/Modify.html:34
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "Endre sak #%1"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Modify tickets"
+msgstr "Endre saker"
+
+#: html/Admin/Groups/UserRights.html:25 html/Admin/Groups/UserRights.html:29 html/Admin/Groups/UserRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr "Endre brukerrettigheter for %1 gruppen"
+
+#: html/Admin/Queues/UserRights.html:25 html/Admin/Queues/UserRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr "Endre brukerrettigheter for %1 køen"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr "Endre overvåkere for '%1' køen"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyACL"
+msgstr "EndreACL"
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "ModifyOwnMembership"
+msgstr "EndreEgetMedlemskap"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "ModifyQueueWatchers"
+msgstr "EndreKøOvervåkere"
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "ModifyScrips"
+msgstr "EndreScrips"
+
+#: lib/RT/System.pm:61
+msgid "ModifySelf"
+msgstr "EndreSegSelv"
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "ModifyTemplate"
+msgstr "EndreMal"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "ModifyTicket"
+msgstr "EndreSak"
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "Man."
+
+#: html/Ticket/Elements/ShowRequestor:42
+#. ($name)
+msgid "More about %1"
+msgstr "Mer om %1"
+
+#: html/Admin/Elements/EditCustomFields:61
+msgid "Move down"
+msgstr "Flytt ned"
+
+#: html/Admin/Elements/EditCustomFields:53
+msgid "Move up"
+msgstr "Flytt opp"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:27
+msgid "Multiple"
+msgstr "Flere"
+
+#: lib/RT/User_Overlay.pm:179
+msgid "Must specify 'Name' attribute"
+msgstr "Må spesifisere attributten 'Navn'"
+
+#: html/SelfService/Elements/MyRequests:49
+#. ($friendly_status)
+msgid "My %1 tickets"
+msgstr "Mine %1 saker"
+
+#: NOT FOUND IN SOURCE
+msgid "My Approvals"
+msgstr "Mine saker til godkjenning"
+
+#: html/Approvals/index.html:25 html/Approvals/index.html:26
+msgid "My approvals"
+msgstr "Mine saker til godkjenning"
+
+#: html/Admin/Elements/AddCustomFieldValue:33 html/Admin/Elements/EditCustomField:34 html/Admin/Elements/ModifyTemplate:28 html/Admin/Elements/ModifyUser:30 html/Admin/Groups/Modify.html:44 html/Elements/SelectGroups:26 html/Elements/SelectUsers:28 html/User/Groups/Modify.html:44
+msgid "Name"
+msgstr "Navn"
+
+#: lib/RT/User_Overlay.pm:186
+msgid "Name in use"
+msgstr "Navnet er i bruk"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr "Trenger godkjennelse fra systemadministrator"
+
+#: html/Ticket/Elements/ShowDates:52
+msgid "Never"
+msgstr "Aldri"
+
+#: html/Elements/Quicksearch:30
+msgid "New"
+msgstr "Ny"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:93 html/User/Prefs.html:65
+msgid "New Password"
+msgstr "Nytt Passord"
+
+#: etc/initialdata:317 etc/upgrade/2.1.71:16
+msgid "New Pending Approval"
+msgstr "Ny, Venter på Godkjennelse"
+
+#: html/Ticket/Elements/EditLinks:111
+msgid "New Relationships"
+msgstr "Nye forhold"
+
+#: html/Ticket/Elements/Tabs:36
+msgid "New Search"
+msgstr "Nytt Søk"
+
+#: html/Admin/Global/CustomField.html:41 html/Admin/Global/CustomFields.html:39 html/Admin/Queues/CustomField.html:52 html/Admin/Queues/CustomFields.html:40
+msgid "New custom field"
+msgstr "Nytt fleksifelt"
+
+#: html/Admin/Elements/GroupTabs:54 html/User/Elements/GroupTabs:52
+msgid "New group"
+msgstr "Ny gruppe"
+
+#: html/SelfService/Prefs.html:32
+msgid "New password"
+msgstr "Nytt passord"
+
+#: lib/RT/User_Overlay.pm:647
+msgid "New password notification sent"
+msgstr "Melding om nytt passord sendt"
+
+#: html/Admin/Elements/QueueTabs:70
+msgid "New queue"
+msgstr "Ny kø"
+
+#: NOT FOUND IN SOURCE
+msgid "New request"
+msgstr "Ny forespørsel"
+
+#: html/Admin/Elements/SelectRights:42
+msgid "New rights"
+msgstr "Nye rettigheter"
+
+#: html/Admin/Global/Scrip.html:40 html/Admin/Global/Scrips.html:39 html/Admin/Queues/Scrip.html:43 html/Admin/Queues/Scrips.html:53
+msgid "New scrip"
+msgstr "Nytt scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "New search"
+msgstr "Nytt søk"
+
+#: html/Admin/Global/Template.html:60 html/Admin/Global/Templates.html:39 html/Admin/Queues/Template.html:58 html/Admin/Queues/Templates.html:50
+msgid "New template"
+msgstr "Ny mal"
+
+#: html/SelfService/Elements/Tabs:48
+msgid "New ticket"
+msgstr "Ny sak"
+
+#: lib/RT/Ticket_Overlay.pm:2778
+msgid "New ticket doesn't exist"
+msgstr "Ny sak eksistere ikke"
+
+#: html/Admin/Elements/UserTabs:52
+msgid "New user"
+msgstr "Ny bruker"
+
+#: html/Admin/Elements/CreateUserCalled:26
+msgid "New user called"
+msgstr "Ny bruker kalt"
+
+#: html/Admin/Queues/People.html:55 html/Ticket/Elements/EditPeople:29
+msgid "New watchers"
+msgstr "Ny overvåker"
+
+#: html/Admin/Users/Prefs.html:42
+msgid "New window setting"
+msgstr "Instillinger for nytt vindu"
+
+#: html/Ticket/Elements/Tabs:69
+msgid "Next"
+msgstr "Neste"
+
+#: html/Search/Listing.html:48
+msgid "Next page"
+msgstr "Neste side"
+
+#: html/Admin/Elements/ModifyUser:50
+msgid "NickName"
+msgstr "KalleNavn"
+
+#: html/Admin/Users/Modify.html:63 html/User/Prefs.html:46
+msgid "Nickname"
+msgstr "Kallenavn"
+
+#: html/Admin/Elements/EditCustomField:90 html/Admin/Elements/EditCustomFields:105
+msgid "No CustomField"
+msgstr "Ingen FleksiFelt"
+
+#: html/Admin/Groups/GroupRights.html:84 html/Admin/Groups/UserRights.html:71
+msgid "No Group defined"
+msgstr "Ingen grupper definert"
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:68
+msgid "No Queue defined"
+msgstr "Ingen kø definert"
+
+#: bin/rt-crontool:56
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr "Ingen RT bruker funnet. Vennligst referer til manualen.\\n"
+
+#: html/Admin/Global/Template.html:79 html/Admin/Queues/Template.html:76
+msgid "No Template"
+msgstr "Ingen Mal"
+
+#: bin/rt-commit-handler:764
+msgid "No Ticket specified. Aborting ticket "
+msgstr "Ingen sak oppgitt. Avbryter sak "
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr "Ingen Sak oppgitt. Avbryter saksendring\\n\\n"
+
+#: html/Approvals/Elements/Approve:46
+msgid "No action"
+msgstr "Ingen handling"
+
+#: lib/RT/Interface/Web.pm:896
+msgid "No column specified"
+msgstr "Ingen kolonne spesifisert"
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr "Ingen kommando funnet\\n"
+
+#: html/Elements/ViewUser:36 html/Ticket/Elements/ShowRequestor:45
+msgid "No comment entered about this user"
+msgstr "Ingen kommentar skrevet om denne brukeren"
+
+#: lib/RT/Ticket_Overlay.pm:2189 lib/RT/Ticket_Overlay.pm:2257
+msgid "No correspondence attached"
+msgstr "Ingen korrespondanse vedlagt"
+
+#: lib/RT/Action/Generic.pm:150 lib/RT/Condition/Generic.pm:176 lib/RT/Search/ActiveTicketsInQueue.pm:56 lib/RT/Search/Generic.pm:113
+#. (ref $self)
+msgid "No description for %1"
+msgstr "Ingen beskrivelse for %1"
+
+#: lib/RT/Users_Overlay.pm:145
+msgid "No group specified"
+msgstr "Ingen gruppe spesifisert"
+
+#: lib/RT/User_Overlay.pm:865
+msgid "No password set"
+msgstr "Passordet er ikke satt"
+
+#: lib/RT/Queue_Overlay.pm:259
+msgid "No permission to create queues"
+msgstr "Ingen tilgang til å opprette køer"
+
+#: lib/RT/Ticket_Overlay.pm:342
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr "Ikke tilgang til å opprette saker for køen '%1'"
+
+#: lib/RT/User_Overlay.pm:152
+msgid "No permission to create users"
+msgstr "Ikke tilgang til å opprette brukere"
+
+#: html/SelfService/Display.html:118
+msgid "No permission to display that ticket"
+msgstr "Ikke tilgang til å vise den saken"
+
+#: html/SelfService/Update.html:52
+msgid "No permission to view update ticket"
+msgstr "Ingen tilgang til å se oppdatering av saken"
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1488
+msgid "No principal specified"
+msgstr "Ingen primær spesifisert"
+
+#: html/Admin/Queues/People.html:154 html/Admin/Queues/People.html:164
+msgid "No principals selected."
+msgstr "Ingen primære spesifisert"
+
+#: html/Admin/Queues/index.html:35
+msgid "No queues matching search criteria found."
+msgstr "Det er ingen køer som matcher søkekriteriet"
+
+#: html/Admin/Elements/SelectRights:81
+msgid "No rights found"
+msgstr "Ingen rettigheter funnet"
+
+#: html/Admin/Elements/SelectRights:33
+msgid "No rights granted."
+msgstr "Ingen rettigheter tildelt"
+
+#: html/Search/Bulk.html:149
+msgid "No search to operate on."
+msgstr "Ingen søk Â behandle"
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr "Ingen saksid oppgitt"
+
+#: lib/RT/Transaction_Overlay.pm:478 lib/RT/Transaction_Overlay.pm:516
+msgid "No transaction type specified"
+msgstr "Transaksjonstype ikke spesifisert"
+
+#: NOT FOUND IN SOURCE
+msgid "No user or email address specified"
+msgstr "Ingen bruker eller epostaddresse oppgitt"
+
+#: html/Admin/Users/index.html:36
+msgid "No users matching search criteria found."
+msgstr "Fant ingen brukere som treffer søkekriteriene."
+
+#: bin/rt-commit-handler:644
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr "Fant ingen gyldig RT bruker. RT cvs handler avstengt. Kontakt din RT administrator.\\n"
+
+#: lib/RT/Interface/Web.pm:893
+msgid "No value sent to _Set!\\n"
+msgstr "Ingen verdi sendt til _Set!\\n"
+
+#: html/Search/Elements/TicketRow:37
+msgid "Nobody"
+msgstr "Ingen"
+
+#: lib/RT/Interface/Web.pm:898
+msgid "Nonexistant field?"
+msgstr "Ukjent felt?"
+
+#: NOT FOUND IN SOURCE
+msgid "Not logged in"
+msgstr "Ikke logget inn"
+
+#: html/Elements/Header:59
+msgid "Not logged in."
+msgstr "Ikke logget inn."
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "Ikke satt"
+
+#: html/NoAuth/Reminder.html:27
+msgid "Not yet implemented."
+msgstr "Ikke implementert enda."
+
+#: NOT FOUND IN SOURCE
+msgid "Not yet implemented...."
+msgstr "Ikke implementert enda...."
+
+#: html/Approvals/Elements/Approve:49
+msgid "Notes"
+msgstr "Notater"
+
+#: lib/RT/User_Overlay.pm:650
+msgid "Notification could not be sent"
+msgstr "Melding kunne ikke sendes"
+
+#: etc/initialdata:94
+msgid "Notify AdminCcs"
+msgstr "Raporter til AdminCc"
+
+#: etc/initialdata:90
+msgid "Notify AdminCcs as Comment"
+msgstr "Rapporter til AdminCc som kommentar"
+
+#: etc/initialdata:121
+msgid "Notify Other Recipients"
+msgstr "Rapporter til andre mottakere"
+
+#: etc/initialdata:117
+msgid "Notify Other Recipients as Comment"
+msgstr "Rapporter til andre mottakere som kommentar"
+
+#: etc/initialdata:86
+msgid "Notify Owner"
+msgstr "Rapporter til eier"
+
+#: etc/initialdata:82
+msgid "Notify Owner as Comment"
+msgstr "Rapportert til eier som kommentar"
+
+#: etc/initialdata:319 etc/upgrade/2.1.71:17
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr "Rapporter til Eiere og AdminCc om nye ting som venter på godkjenning"
+
+#: etc/initialdata:78
+msgid "Notify Requestors"
+msgstr "Rapporter til kunde"
+
+#: etc/initialdata:104
+msgid "Notify Requestors and Ccs"
+msgstr "Rapporter til Kunder og Cc"
+
+#: etc/initialdata:99
+msgid "Notify Requestors and Ccs as Comment"
+msgstr "Rapporter til Kunder og Cc som kommentar"
+
+#: etc/initialdata:113
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr "Rapporter til Kunder Cc og AdminCc"
+
+#: etc/initialdata:109
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr "Rapporter til Kunder Cc og AdminCc som Kommentar"
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "Nov."
+
+#: NOT FOUND IN SOURCE
+msgid "November"
+msgstr "November"
+
+#: lib/RT/Record.pm:157
+msgid "Object could not be created"
+msgstr "Objekter kunne ikke opprettes"
+
+#: lib/RT/Record.pm:176
+msgid "Object created"
+msgstr "Objektet ble opprettet"
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "Okt."
+
+#: NOT FOUND IN SOURCE
+msgid "October"
+msgstr "Oktober"
+
+#: html/Elements/SelectDateRelation:35
+msgid "On"
+msgstr "Ved"
+
+#: etc/initialdata:155
+msgid "On Comment"
+msgstr "Ved Kommentar"
+
+#: etc/initialdata:148
+msgid "On Correspond"
+msgstr "Ved Korrespondanse"
+
+#: etc/initialdata:137
+msgid "On Create"
+msgstr "Ved Opprettelse"
+
+#: etc/initialdata:169
+msgid "On Owner Change"
+msgstr "Ved Eierskifte"
+
+#: etc/initialdata:177
+msgid "On Queue Change"
+msgstr "Ved Køendring"
+
+#: etc/initialdata:183
+msgid "On Resolve"
+msgstr "Ved Løsning"
+
+#: etc/initialdata:161
+msgid "On Status Change"
+msgstr "Ved statusendring"
+
+#: etc/initialdata:142
+msgid "On Transaction"
+msgstr "Ved Transaksjon"
+
+#: html/Approvals/Elements/PendingMyApproval:50
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr "Vis kun godkjennelse for saker opprettet etter %1"
+
+#: html/Approvals/Elements/PendingMyApproval:48
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr "Bare vis godkjennelse for saker opprettet før %1"
+
+#: html/Elements/Quicksearch:31
+msgid "Open"
+msgstr "Åpne"
+
+#: html/Ticket/Elements/Tabs:136
+msgid "Open it"
+msgstr "Åpne den"
+
+#: NOT FOUND IN SOURCE
+msgid "Open requests"
+msgstr "Åpne forespørsler"
+
+#: html/SelfService/Elements/Tabs:42
+msgid "Open tickets"
+msgstr "Åpne saker"
+
+#: html/Admin/Users/Prefs.html:41
+msgid "Open tickets (from listing) in a new window"
+msgstr "Åpne saker (fra utlisting) i et nytt vindu"
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in another window"
+msgstr "Åpne saker (fra utlisting) it et annet vinud"
+
+#: etc/initialdata:133
+msgid "Open tickets on correspondence"
+msgstr "Åpne saker ved korrespondanse"
+
+#: html/Search/Elements/PickRestriction:101
+msgid "Ordering and sorting"
+msgstr "Rekkefølge og sortering"
+
+#: html/Admin/Elements/ModifyUser:46 html/Admin/Users/Modify.html:117 html/Elements/SelectUsers:29 html/User/Prefs.html:86
+msgid "Organization"
+msgstr "Organisasjon"
+
+#: html/Approvals/Elements/Approve:33
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr "Opprinnelig sak: #%1"
+
+#: html/Admin/Elements/ModifyQueue:55 html/Admin/Queues/Modify.html:69
+msgid "Over time, priority moves toward"
+msgstr "Over tid beveger prioriteten seg mot"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Own tickets"
+msgstr "Eie saker"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "OwnTicket"
+msgstr "EieSak"
+
+#: etc/initialdata:38 html/Elements/MyRequests:32 html/SelfService/Elements/MyRequests:30 html/Ticket/Create.html:48 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/EditPeople:44 html/Ticket/Elements/ShowPeople:27 html/Ticket/Update.html:63 lib/RT/ACE_Overlay.pm:86 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "Eier"
+
+#: lib/RT/Ticket_Overlay.pm:3071
+#. ($OldOwnerObj->Name,  $NewOwnerObj->Name)
+msgid "Owner changed from %1 to %2"
+msgstr "Eier endret fra %1 til %2"
+
+#: lib/RT/Transaction_Overlay.pm:582
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr "Eier ble tvunget til å endres fra %1 til %2"
+
+#: html/Search/Elements/PickRestriction:31
+msgid "Owner is"
+msgstr "Eier er"
+
+#: html/Admin/Users/Modify.html:174 html/User/Prefs.html:56
+msgid "Pager"
+msgstr "Personsøker"
+
+#: html/Admin/Elements/ModifyUser:74
+msgid "PagerPhone"
+msgstr "PersonSøker"
+
+#: NOT FOUND IN SOURCE
+msgid "Parent"
+msgstr "Forelder"
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/EditLinks:127 html/Ticket/Elements/EditLinks:58 html/Ticket/Elements/ShowLinks:47
+msgid "Parents"
+msgstr "Foreldre"
+
+#: html/Elements/Login:52 html/User/Prefs.html:61
+msgid "Password"
+msgstr "Passord"
+
+#: html/NoAuth/Reminder.html:25
+msgid "Password Reminder"
+msgstr "Passordhint"
+
+#: lib/RT/User_Overlay.pm:169 lib/RT/User_Overlay.pm:868
+msgid "Password too short"
+msgstr "For kort passord"
+
+#: html/Admin/Users/Modify.html:291 html/User/Prefs.html:172
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "Passord: %1"
+
+#: html/Admin/Users/Modify.html:293
+msgid "Passwords do not match."
+msgstr "Passordene stemmer ikke overens."
+
+#: html/User/Prefs.html:174
+msgid "Passwords do not match. Your password has not been changed"
+msgstr "Passordene stemmer ikke overrens. Passordet ble ikke endret"
+
+#: html/Ticket/Elements/ShowSummary:45 html/Ticket/Elements/Tabs:96 html/Ticket/ModifyAll.html:51
+msgid "People"
+msgstr "Folk"
+
+#: etc/initialdata:126
+msgid "Perform a user-defined action"
+msgstr "Kjør en brukerdefinert handling"
+
+#: lib/RT/ACE_Overlay.pm:231 lib/RT/ACE_Overlay.pm:237 lib/RT/ACE_Overlay.pm:563 lib/RT/ACE_Overlay.pm:573 lib/RT/ACE_Overlay.pm:583 lib/RT/ACE_Overlay.pm:648 lib/RT/CurrentUser.pm:83 lib/RT/CurrentUser.pm:92 lib/RT/CustomField_Overlay.pm:101 lib/RT/CustomField_Overlay.pm:202 lib/RT/CustomField_Overlay.pm:234 lib/RT/CustomField_Overlay.pm:511 lib/RT/CustomField_Overlay.pm:91 lib/RT/Group_Overlay.pm:1095 lib/RT/Group_Overlay.pm:1099 lib/RT/Group_Overlay.pm:1108 lib/RT/Group_Overlay.pm:1159 lib/RT/Group_Overlay.pm:1163 lib/RT/Group_Overlay.pm:1169 lib/RT/Group_Overlay.pm:426 lib/RT/Group_Overlay.pm:518 lib/RT/Group_Overlay.pm:596 lib/RT/Group_Overlay.pm:604 lib/RT/Group_Overlay.pm:701 lib/RT/Group_Overlay.pm:705 lib/RT/Group_Overlay.pm:711 lib/RT/Group_Overlay.pm:904 lib/RT/Group_Overlay.pm:908 lib/RT/Group_Overlay.pm:921 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:126 lib/RT/Scrip_Overlay.pm:137 lib/RT/Scrip_Overlay.pm:197 lib/RT/Scrip_Overlay.pm:430 lib/RT/Template_Overlay.pm:284 lib/RT/Template_Overlay.pm:88 lib/RT/Template_Overlay.pm:94 lib/RT/Ticket_Overlay.pm:1341 lib/RT/Ticket_Overlay.pm:1351 lib/RT/Ticket_Overlay.pm:1365 lib/RT/Ticket_Overlay.pm:1518 lib/RT/Ticket_Overlay.pm:1527 lib/RT/Ticket_Overlay.pm:1540 lib/RT/Ticket_Overlay.pm:1875 lib/RT/Ticket_Overlay.pm:2013 lib/RT/Ticket_Overlay.pm:2177 lib/RT/Ticket_Overlay.pm:2244 lib/RT/Ticket_Overlay.pm:2603 lib/RT/Ticket_Overlay.pm:2675 lib/RT/Ticket_Overlay.pm:2769 lib/RT/Ticket_Overlay.pm:2784 lib/RT/Ticket_Overlay.pm:2978 lib/RT/Ticket_Overlay.pm:3206 lib/RT/Ticket_Overlay.pm:3404 lib/RT/Ticket_Overlay.pm:3566 lib/RT/Ticket_Overlay.pm:3618 lib/RT/Ticket_Overlay.pm:3783 lib/RT/Transaction_Overlay.pm:466 lib/RT/Transaction_Overlay.pm:473 lib/RT/Transaction_Overlay.pm:502 lib/RT/Transaction_Overlay.pm:509 lib/RT/User_Overlay.pm:1355 lib/RT/User_Overlay.pm:570 lib/RT/User_Overlay.pm:605 lib/RT/User_Overlay.pm:861 lib/RT/User_Overlay.pm:962
+msgid "Permission Denied"
+msgstr "Ingen Tilgang"
+
+#: html/User/Elements/Tabs:35
+msgid "Personal Groups"
+msgstr "Personlige Grupper"
+
+#: html/User/Groups/index.html:30 html/User/Groups/index.html:40
+msgid "Personal groups"
+msgstr "Personlige grupper"
+
+#: html/User/Elements/DelegateRights:37
+msgid "Personal groups:"
+msgstr "Personlige grupper:"
+
+#: html/Admin/Users/Modify.html:156 html/User/Prefs.html:49
+msgid "Phone numbers"
+msgstr "Telefonnummer"
+
+#: NOT FOUND IN SOURCE
+msgid "Placeholder"
+msgstr "Stedholder"
+
+#: NOT FOUND IN SOURCE
+msgid "Pref"
+msgstr "Pref"
+
+#: html/Elements/Header:52 html/Elements/Tabs:53 html/SelfService/Elements/Tabs:51 html/SelfService/Prefs.html:25 html/User/Prefs.html:25 html/User/Prefs.html:28
+msgid "Preferences"
+msgstr "Instillinger"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr "Pref"
+
+#: lib/RT/Action/Generic.pm:160
+msgid "Prepare Stubbed"
+msgstr "Klargjør Forkortet"
+
+#: html/Ticket/Elements/Tabs:61
+msgid "Prev"
+msgstr "Forrige"
+
+#: html/Search/Listing.html:44
+msgid "Previous page"
+msgstr "Forrige side"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr "Pri"
+
+#: lib/RT/ACE_Overlay.pm:133 lib/RT/ACE_Overlay.pm:208 lib/RT/ACE_Overlay.pm:552
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr "Primær %1 ikke funnet."
+
+#: html/Search/Elements/PickRestriction:54 html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:54 html/Ticket/Elements/ShowBasics:39 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "Prioritet"
+
+#: html/Admin/Elements/ModifyQueue:51 html/Admin/Queues/Modify.html:65
+msgid "Priority starts at"
+msgstr "Prioritet starter på"
+
+#: etc/initialdata:25
+msgid "Privileged"
+msgstr "Priviligert"
+
+#: html/Admin/Users/Modify.html:271 html/User/Prefs.html:163
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr "Priviligert status: %1"
+
+#: html/Admin/Users/index.html:62
+msgid "Privileged users"
+msgstr "Priviligerte brukere"
+
+#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59
+msgid "Pseudogroup for internal use"
+msgstr "Pseduogruppe for intern bruk"
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Elements/Quicksearch:29 html/Search/Elements/PickRestriction:46 html/SelfService/Create.html:33 html/Ticket/Create.html:38 html/Ticket/Elements/EditBasics:64 html/Ticket/Elements/ShowBasics:43 html/User/Elements/DelegateRights:80 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "Kø"
+
+#: html/Admin/Queues/CustomField.html:42 html/Admin/Queues/Scrip.html:50 html/Admin/Queues/Scrips.html:46 html/Admin/Queues/Templates.html:44
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr "Køen %1 kunne ikke finnes"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr "Køen '%1' ikke funnet\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Keyword Selections"
+msgstr "Nøkkelordvalg for kø"
+
+#: html/Admin/Elements/ModifyQueue:31 html/Admin/Queues/Modify.html:43
+msgid "Queue Name"
+msgstr "Kønavn"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr "Køscrip"
+
+#: lib/RT/Queue_Overlay.pm:263
+msgid "Queue already exists"
+msgstr "Køen eksisterer allerede"
+
+#: lib/RT/Queue_Overlay.pm:272 lib/RT/Queue_Overlay.pm:278
+msgid "Queue could not be created"
+msgstr "Køen kunne ikke opprettes"
+
+#: html/Ticket/Create.html:205
+msgid "Queue could not be loaded."
+msgstr "Køen kunne ikke lastes."
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:282
+msgid "Queue created"
+msgstr "Køen opprettet"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue is not specified."
+msgstr "Køen er ikke oppgitt."
+
+#: html/SelfService/Display.html:71 lib/RT/CustomField_Overlay.pm:98
+msgid "Queue not found"
+msgstr "Køen ikke funnet"
+
+#: html/Admin/Elements/Tabs:38 html/Admin/index.html:35
+msgid "Queues"
+msgstr "Køer"
+
+#: html/Elements/Quicksearch:25
+msgid "Quick search"
+msgstr "Raskt søk"
+
+#: html/Elements/Login:44
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr "RT %1"
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr "RT %1 for %2"
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr "RT %1 fra <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: html/Admin/index.html:25 html/Admin/index.html:26
+msgid "RT Administration"
+msgstr "RT-administrasjon"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr "RT Autentiseringsfeil."
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr "RT Avvisning: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr "RT Konfigurasjonsfeil"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr "Kritisk RT feil. Meldingen ble ikke lagret!"
+
+#: html/Elements/Error:41 html/SelfService/Error.html:41
+msgid "RT Error"
+msgstr "RT Feil"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr "RT Mottok mail (%1) fra seg selv."
+
+#: NOT FOUND IN SOURCE
+msgid "RT Recieved mail (%1) from itself."
+msgstr "RT Mottok mail (%1) fra seg selv."
+
+#: NOT FOUND IN SOURCE
+msgid "RT Self Service / Closed Tickets"
+msgstr "RT Selvbetjening / Lukkede Saker"
+
+#: html/index.html:25 html/index.html:28
+msgid "RT at a glance"
+msgstr "RT oversikt"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr "RT kunne ikke autentisere deg"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr "RT kunne ikke finne kunde via sitt eksterne databaseoppslag"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr "RT kunne ikke finne køen: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr "RT kunne ikke validere denne PGP signaturen. \\n" 
+
+#: html/Elements/PageLayout:26
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr "RT for %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr "RT for %1: %2"
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr "RT har behandlet dine kommandoer"
+
+#: html/Elements/Login:92
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT er &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;. Den er distribuert under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>""
+
+#: NOT FOUND IN SOURCE
+msgid "RT is &copy; Copyright 1996-2002 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT er &copy; Copyright 1996-2002 Jesse Vincent &lt;jesse@bestpractical.com&gt;. Den er distribuert under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>""
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr "RT tror denne meldingen kan være en returmail"
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr "RT vil behandle denne meldingen som om den var usignert"
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr "RT's epost kommandomodus krever PGP autentisering. Meldingen din var enten ikke signert, eller signaturen din kunne ikke bekreftes."
+
+#: html/Admin/Users/Modify.html:58 html/Admin/Users/Prefs.html:52 html/User/Prefs.html:44
+msgid "Real Name"
+msgstr "Ekte Navn"
+
+#: html/Admin/Elements/ModifyUser:48
+msgid "RealName"
+msgstr "EkteNavn"
+
+#: html/Ticket/Create.html:185 html/Ticket/Elements/EditLinks:139 html/Ticket/Elements/EditLinks:94 html/Ticket/Elements/ShowLinks:71
+msgid "Referred to by"
+msgstr "Referert til av"
+
+#: html/Elements/SelectLinkType:28 html/Ticket/Create.html:184 html/Ticket/Elements/EditLinks:135 html/Ticket/Elements/EditLinks:80 html/Ticket/Elements/ShowLinks:61
+msgid "Refers to"
+msgstr "Refererer til"
+
+#: NOT FOUND IN SOURCE
+msgid "RefersTo"
+msgstr "RefererTil"
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr "Redefiner"
+
+#: html/Search/Elements/PickRestriction:27
+msgid "Refine search"
+msgstr "Redefiner søket"
+
+#: html/Elements/Refresh:36
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "Last siden p nytt hvert %1 minutt."
+
+#: html/Ticket/Create.html:174 html/Ticket/Elements/ShowSummary:62 html/Ticket/ModifyAll.html:57
+msgid "Relationships"
+msgstr "Forhold"
+
+#: html/Search/Bulk.html:93
+msgid "Remove AdminCc"
+msgstr "Fjern AdminCc"
+
+#: html/Search/Bulk.html:91
+msgid "Remove Cc"
+msgstr "Fjern Cc"
+
+#: html/Search/Bulk.html:89
+msgid "Remove Requestor"
+msgstr "Fjern Kunde"
+
+#: html/Ticket/Elements/ShowTransaction:173 html/Ticket/Elements/Tabs:122
+msgid "Reply"
+msgstr "Svar"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Reply to tickets"
+msgstr "Svar p sak"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "ReplyToTicket"
+msgstr "SvarPÂSak"
+
+#: etc/initialdata:44 html/Ticket/Update.html:40 lib/RT/ACE_Overlay.pm:87
+msgid "Requestor"
+msgstr "Kunde"
+
+#: html/Search/Elements/PickRestriction:38
+msgid "Requestor email address"
+msgstr "Kundens epostaddresse"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr "Kunde(r)"
+
+#: NOT FOUND IN SOURCE
+msgid "RequestorAddresses"
+msgstr "KundeAddresser"
+
+#: html/SelfService/Create.html:41 html/Ticket/Create.html:56 html/Ticket/Elements/EditPeople:48 html/Ticket/Elements/ShowPeople:31
+msgid "Requestors"
+msgstr "Kunder"
+
+#: html/Admin/Elements/ModifyQueue:61 html/Admin/Queues/Modify.html:75
+msgid "Requests should be due in"
+msgstr "Forespørsler skal være behandlet innen"
+
+#: html/Elements/Submit:62
+msgid "Reset"
+msgstr "Reset"
+
+#: html/Admin/Users/Modify.html:159 html/User/Prefs.html:50
+msgid "Residence"
+msgstr "Hjemme"
+
+#: html/Ticket/Elements/Tabs:132
+msgid "Resolve"
+msgstr "Løs"
+
+#: html/Ticket/Update.html:133
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr "Løs saknr #%1 (%2)"
+
+#: etc/initialdata:308 html/Elements/SelectDateType:28 lib/RT/Ticket_Overlay.pm:1170
+msgid "Resolved"
+msgstr "Løst"
+
+#: html/Search/Bulk.html:123 html/Ticket/ModifyAll.html:73 html/Ticket/Update.html:73
+msgid "Response to requestors"
+msgstr "Svar til kunder"
+
+#: html/Elements/ListActions:26
+msgid "Results"
+msgstr "Resultater"
+
+#: html/Search/Elements/PickRestriction:105
+msgid "Results per page"
+msgstr "Resultater per side"
+
+#: html/Admin/Elements/ModifyUser:33 html/Admin/Users/Modify.html:100 html/User/Prefs.html:72
+msgid "Retype Password"
+msgstr "Skriv Passord igjen"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr "Rettighet %1 kunne ikke finnes for %2  %3 in scope %4 (%5)\\n"
+
+#: lib/RT/ACE_Overlay.pm:613
+msgid "Right Delegated"
+msgstr "Rettighet Deligert"
+
+#: lib/RT/ACE_Overlay.pm:303
+msgid "Right Granted"
+msgstr "Rettighet Tildelt"
+
+#: lib/RT/ACE_Overlay.pm:161
+msgid "Right Loaded"
+msgstr "Rettighet lastet"
+
+#: lib/RT/ACE_Overlay.pm:678 lib/RT/ACE_Overlay.pm:693
+msgid "Right could not be revoked"
+msgstr "Rettigheten kunne ikke trekkes tilbake"
+
+#: html/User/Delegation.html:64
+msgid "Right not found"
+msgstr "Rettighet ikke funnet"
+
+#: lib/RT/ACE_Overlay.pm:543 lib/RT/ACE_Overlay.pm:638
+msgid "Right not loaded."
+msgstr "Rettighet ikke lastet."
+
+#: lib/RT/ACE_Overlay.pm:689
+msgid "Right revoked"
+msgstr "Rettighet fjernet"
+
+#: html/Admin/Elements/UserTabs:41
+msgid "Rights"
+msgstr "Rettigheter"
+
+#: lib/RT/Interface/Web.pm:792
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr "Rettigheter kunne ikke tildeles for %1"
+
+#: lib/RT/Interface/Web.pm:825
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr "Rettigheter kunne ikke trekkes tilbake for %1"
+
+#: html/Admin/Global/GroupRights.html:51 html/Admin/Queues/GroupRights.html:52
+msgid "Roles"
+msgstr "Roller"
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr "RootGodkjenning"
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "Lør."
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyLinks.html:39 html/Ticket/ModifyPeople.html:38
+msgid "Save Changes"
+msgstr "Lagre Endringer"
+
+#: NOT FOUND IN SOURCE
+msgid "Save changes"
+msgstr "Lage endringer"
+
+#: html/Admin/Global/Scrip.html:49
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr "Scrip #%1"
+
+#: lib/RT/Scrip_Overlay.pm:176
+msgid "Scrip Created"
+msgstr "Scrip Opprettet"
+
+#: html/Admin/Elements/EditScrips:84
+msgid "Scrip deleted"
+msgstr "Scrip slettet"
+
+#: html/Admin/Elements/QueueTabs:46 html/Admin/Elements/SystemTabs:33 html/Admin/Global/index.html:41
+msgid "Scrips"
+msgstr "Scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr "Scrip for %1\\n"
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr "Scrip som gjelder for alle køer"
+
+#: html/Elements/SimpleSearch:27 html/Search/Elements/PickRestriction:126 html/Ticket/Elements/Tabs:159
+msgid "Search"
+msgstr "Søk"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr "Søkekriteria"
+
+#: html/Approvals/Elements/PendingMyApproval:39
+msgid "Search for approvals"
+msgstr "Søk etter godkjenninger"
+
+#: bin/rt-crontool:188
+msgid "Security:"
+msgstr "Sikkerhet:"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "SeeQueue"
+msgstr "SeKø"
+
+#: html/Admin/Groups/index.html:40
+msgid "Select a group"
+msgstr "Velg en gruppe"
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr "Velg en kø"
+
+#: html/Admin/Users/index.html:25 html/Admin/Users/index.html:28
+msgid "Select a user"
+msgstr "Velg en bruker"
+
+#: html/Admin/Global/CustomField.html:38 html/Admin/Global/CustomFields.html:36
+msgid "Select custom field"
+msgstr "Velg fleksifelt"
+
+#: html/Admin/Elements/GroupTabs:52 html/User/Elements/GroupTabs:50
+msgid "Select group"
+msgstr "Velg gruppe"
+
+#: lib/RT/CustomField_Overlay.pm:422
+msgid "Select multiple values"
+msgstr "Velg flere verdier"
+
+#: lib/RT/CustomField_Overlay.pm:419
+msgid "Select one value"
+msgstr "Velg en verdi"
+
+#: html/Admin/Elements/QueueTabs:67
+msgid "Select queue"
+msgstr "Velg kø"
+
+#: html/Admin/Global/Scrip.html:37 html/Admin/Global/Scrips.html:36 html/Admin/Queues/Scrip.html:40 html/Admin/Queues/Scrips.html:50
+msgid "Select scrip"
+msgstr "Velg scrip"
+
+#: html/Admin/Global/Template.html:57 html/Admin/Global/Templates.html:36 html/Admin/Queues/Template.html:55 html/Admin/Queues/Templates.html:47
+msgid "Select template"
+msgstr "Velg mal"
+
+#: html/Admin/Elements/UserTabs:49
+msgid "Select user"
+msgstr "Velg bruker"
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "SelectMultiple"
+msgstr "VelgFlere"
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectSingle"
+msgstr "VelgEnkelt"
+
+#: NOT FOUND IN SOURCE
+msgid "Self Service"
+msgstr "Selvbetjening"
+
+#: etc/initialdata:114
+msgid "Send mail to all watchers"
+msgstr "Send epost til alle overvåkere"
+
+#: etc/initialdata:110
+msgid "Send mail to all watchers as a \"comment\""
+msgstr "Send epost til alle overvåkere som \"kommentar\""
+
+#: etc/initialdata:105
+msgid "Send mail to requestors and Ccs"
+msgstr "Send epost til kunder og Cc"
+
+#: etc/initialdata:100
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr "Send epost til kunder og Cc som kommentar"
+
+#: etc/initialdata:79
+msgid "Sends a message to the requestors"
+msgstr "Sender en melding til kundene"
+
+#: etc/initialdata:118 etc/initialdata:122
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr "Send epost til eksplisit oppgitte Ccer og Bccer"
+
+#: etc/initialdata:95
+msgid "Sends mail to the administrative Ccs"
+msgstr "Send epost til Administrative Ccer"
+
+#: etc/initialdata:91
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr "Sender epost til de administrative Ccene som kommentar"
+
+#: etc/initialdata:83 etc/initialdata:87
+msgid "Sends mail to the owner"
+msgstr "Sender epost til eieren"
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "Sep."
+
+#: NOT FOUND IN SOURCE
+msgid "September"
+msgstr "September"
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr "Vis Resultater"
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show approved requests"
+msgstr "Vis godkjente forespørsler"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show basics"
+msgstr "Vis basisinfo"
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show denied requests"
+msgstr "Vis avviste forespørsler"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show details"
+msgstr "Vis detaljer"
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show pending requests"
+msgstr "Vis ventende forespørsler"
+
+#: html/Approvals/Elements/PendingMyApproval:46
+msgid "Show requests awaiting other approvals"
+msgstr "Vis forespørsler som venter på andre godkjenninger"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Show ticket private commentary"
+msgstr "Vis sakens private kommentarer"
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "Show ticket summaries"
+msgstr "Vis sakssammendrag"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ShowACL"
+msgstr "VisACL"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowScrips"
+msgstr "VisScrip"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ShowTemplate"
+msgstr "VisMal"
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "ShowTicket"
+msgstr "VisSak"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "ShowTicketComments"
+msgstr "VisSaksKommentarer"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr "Meld deg på som saksforespørrer eller sak/kø Cc"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr "Meld deg på som sak/kø AdminCc"
+
+#: html/Admin/Elements/ModifyUser:39 html/Admin/Users/Modify.html:191 html/Admin/Users/Prefs.html:32 html/User/Prefs.html:112
+msgid "Signature"
+msgstr "Signatur"
+
+#: NOT FOUND IN SOURCE
+msgid "Signed in as %1"
+msgstr "Logget inn som %1"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Single"
+msgstr "Enkel"
+
+#: html/Elements/Header:51
+msgid "Skip Menu"
+msgstr "Dropp Meny"
+
+#: html/Admin/Elements/AddCustomFieldValue:29
+msgid "Sort"
+msgstr "Sorter"
+
+#: NOT FOUND IN SOURCE
+msgid "Sort key"
+msgstr "Sorter nøkkel"
+
+#: html/Search/Elements/PickRestriction:109
+msgid "Sort results by"
+msgstr "Sorter resultater etter"
+
+#: NOT FOUND IN SOURCE
+msgid "SortOrder"
+msgstr "SorteringsRekkefølge"
+
+#: NOT FOUND IN SOURCE
+msgid "Stalled"
+msgstr "Pauset"
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr "Startside"
+
+#: html/Elements/SelectDateType:27 html/Ticket/Elements/EditDates:32 html/Ticket/Elements/ShowDates:35
+msgid "Started"
+msgstr "Startet"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr "Startdato '%1' kunne ikke tolkes"
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:27 html/Ticket/Elements/ShowDates:31
+msgid "Starts"
+msgstr "Starter"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr "Starter Etter"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr "Startdato '%1' kunne ikke tolkes"
+
+#: html/Admin/Elements/ModifyUser:82 html/Admin/Users/Modify.html:138 html/User/Prefs.html:94
+msgid "State"
+msgstr "Stat"
+
+#: html/Elements/MyRequests:31 html/Elements/MyTickets:31 html/Search/Elements/PickRestriction:74 html/SelfService/Elements/MyRequests:29 html/SelfService/Update.html:31 html/Ticket/Create.html:42 html/Ticket/Elements/EditBasics:38 html/Ticket/Elements/ShowBasics:31 html/Ticket/Update.html:60 lib/RT/Ticket_Overlay.pm:1164 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "Status"
+
+#: etc/initialdata:294
+msgid "Status Change"
+msgstr "Statusendring"
+
+#: lib/RT/Transaction_Overlay.pm:528
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr "Status endret fra %1 til %2"
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr "EndreStatus"
+
+#: html/Ticket/Elements/Tabs:147
+msgid "Steal"
+msgstr "Stjel"
+
+#: lib/RT/Transaction_Overlay.pm:587
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "Stjålet fra %1 "
+
+#: html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Search/Bulk.html:126 html/Search/Elements/PickRestriction:43 html/SelfService/Create.html:57 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:32 html/Ticket/Create.html:84 html/Ticket/Elements/EditBasics:28 html/Ticket/ModifyAll.html:79 html/Ticket/Update.html:77 lib/RT/Ticket_Overlay.pm:1160 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "Emne"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:609
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr "Endre emne til %1"
+
+#: html/Elements/Submit:59
+msgid "Submit"
+msgstr "Oppdater"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr "Send Arbeidsflyt"
+
+#: lib/RT/Group_Overlay.pm:749
+msgid "Succeeded"
+msgstr "Lykkes"
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "Søn."
+
+#: lib/RT/System.pm:54
+msgid "SuperUser"
+msgstr "SuperBruker"
+
+#: html/User/Elements/DelegateRights:77
+msgid "System"
+msgstr "System"
+
+#: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:567 lib/RT/Interface/Web.pm:791 lib/RT/Interface/Web.pm:824
+msgid "System Error"
+msgstr "Systemfeil"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. Right not granted."
+msgstr "Systemfeil. Rettighet ikke tildelt."
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. right not granted"
+msgstr "Systemfeil. rettigheter ikke tildelt"
+
+#: lib/RT/ACE_Overlay.pm:616
+msgid "System error. Right not delegated."
+msgstr "Systemfeil. Rettighet ikke tildelt."
+
+#: lib/RT/ACE_Overlay.pm:146 lib/RT/ACE_Overlay.pm:223 lib/RT/ACE_Overlay.pm:306 lib/RT/ACE_Overlay.pm:898
+msgid "System error. Right not granted."
+msgstr "Systemfeil. Rettighet ikke tildelt."
+
+#: NOT FOUND IN SOURCE
+msgid "System error. Unable to grant rights."
+msgstr "Systemfeil. Kunne ikke tildele rettigheter."
+
+#: html/Admin/Global/GroupRights.html:35 html/Admin/Groups/GroupRights.html:37 html/Admin/Queues/GroupRights.html:36
+msgid "System groups"
+msgstr "Systemgrupper"
+
+#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53
+msgid "SystemRolegroup for internal use"
+msgstr "SystemRollegruppe for intern bruk"
+
+#: lib/RT/CurrentUser.pm:318
+msgid "TEST_STRING"
+msgstr "TEST_STRENG"
+
+#: html/Ticket/Elements/Tabs:143
+msgid "Take"
+msgstr "Ta"
+
+#: lib/RT/Transaction_Overlay.pm:573
+msgid "Taken"
+msgstr "Tatt"
+
+#: html/Admin/Elements/EditScrip:81
+msgid "Template"
+msgstr "Mal"
+
+#: html/Admin/Global/Template.html:91 html/Admin/Queues/Template.html:90
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr "Mal #%1"
+
+#: html/Admin/Elements/EditTemplates:89
+msgid "Template deleted"
+msgstr "Mal slettet"
+
+#: lib/RT/Scrip_Overlay.pm:153
+msgid "Template not found"
+msgstr "Kunne ikke finne mal"
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr "Kunne ikke finne mal\\n"
+
+#: lib/RT/Template_Overlay.pm:347
+msgid "Template parsed"
+msgstr "Mal tolket"
+
+#: html/Admin/Elements/QueueTabs:49 html/Admin/Elements/SystemTabs:36 html/Admin/Global/index.html:45
+msgid "Templates"
+msgstr "Maler"
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr "Maler for %1\\n"
+
+#: lib/RT/Interface/Web.pm:892
+msgid "That is already the current value"
+msgstr "Verdien er allerede satt"
+
+#: lib/RT/CustomField_Overlay.pm:243
+msgid "That is not a value for this custom field"
+msgstr "Det er ikke en verdi for dette fleksifeltet"
+
+#: lib/RT/Ticket_Overlay.pm:1886
+msgid "That is the same value"
+msgstr "Det er den samme verdien"
+
+#: lib/RT/ACE_Overlay.pm:288 lib/RT/ACE_Overlay.pm:597
+msgid "That principal already has that right"
+msgstr "Den primæren har allerede den rettigheten"
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr "Den primæren er allerede en %1 for denne køen"
+
+#: lib/RT/Ticket_Overlay.pm:1434
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr "Den primæren er allerede en %1 for denne køen"
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr "Den primæren er ikke en %1 for denne køen"
+
+#: lib/RT/Ticket_Overlay.pm:1551
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr "Den primæren er ikke en %1 for denne saken"
+
+#: lib/RT/Ticket_Overlay.pm:1882
+msgid "That queue does not exist"
+msgstr "Den køen eksisterer ikke"
+
+#: lib/RT/Ticket_Overlay.pm:3210
+msgid "That ticket has unresolved dependencies"
+msgstr "Denne saken har uløste avhengigheter"
+
+#: NOT FOUND IN SOURCE
+msgid "That user already has that right"
+msgstr "Den brukeren har allerede den rettigheten"
+
+#: lib/RT/Ticket_Overlay.pm:3020
+msgid "That user already owns that ticket"
+msgstr "Den brukeren eier allerede den saken"
+
+#: lib/RT/Ticket_Overlay.pm:2986
+msgid "That user does not exist"
+msgstr "Den brukeren finnes ikke"
+
+#: lib/RT/User_Overlay.pm:315
+msgid "That user is already privileged"
+msgstr "Den brukeren er allerede priviligert"
+
+#: lib/RT/User_Overlay.pm:336
+msgid "That user is already unprivileged"
+msgstr "Den brukeren er allerede upriviligert"
+
+#: lib/RT/User_Overlay.pm:328
+msgid "That user is now privileged"
+msgstr "Denne brukeren er nå priviligert"
+
+#: lib/RT/User_Overlay.pm:349
+msgid "That user is now unprivileged"
+msgstr "Dette brukeren er nå upriviligert"
+
+#: NOT FOUND IN SOURCE
+msgid "That user is now unprivilegedileged"
+msgstr "Den brukeren er allerede upriviligert"
+
+#: lib/RT/Ticket_Overlay.pm:3012
+msgid "That user may not own tickets in that queue"
+msgstr "Den brukeren kan ikke eie saker i den køen"
+
+#: lib/RT/Link_Overlay.pm:206
+msgid "That's not a numerical id"
+msgstr "Dette er ikke en numerisk id"
+
+#: html/SelfService/Display.html:32 html/Ticket/Create.html:150 html/Ticket/Elements/ShowSummary:28
+msgid "The Basics"
+msgstr "Detaljer"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The CC of a ticket"
+msgstr "CCen til en sak"
+
+#: lib/RT/ACE_Overlay.pm:89
+msgid "The administrative CC of a ticket"
+msgstr "Administrative CCer for en sak"
+
+#: lib/RT/Ticket_Overlay.pm:2213
+msgid "The comment has been recorded"
+msgstr "Kommentarer er lagret"
+
+#: bin/rt-crontool:198
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr "De følgende kommandoene vil finne alle aktive saker i køen 'general' og sette deres prioritet til 99 hvis de ikke har blitt rørt de siste 4 timene:"
+
+#: bin/rt-commit-handler:756 bin/rt-commit-handler:766
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr "De følgende kommandoene ble ikke behandlet:\\n\\n"
+
+#: lib/RT/Interface/Web.pm:895
+msgid "The new value has been set."
+msgstr "Den nye verdien har blitt satt."
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The owner of a ticket"
+msgstr "Eieren av en sak"
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The requestor of a ticket"
+msgstr "Forespørren av en sak"
+
+#: html/Admin/Elements/EditUserComments:26
+msgid "These comments aren't generally visible to the user"
+msgstr "Disse kommentarene er generelt ikke synlig for brukeren"
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr "Denne saken %1 %2 (%3)\\n"
+
+#: bin/rt-crontool:189
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr "Dette verktøyet tillater brukeren  å kjøre perlmoduler fra inni RT."
+
+#: lib/RT/Transaction_Overlay.pm:251
+msgid "This transaction appears to have no content"
+msgstr "Denne transaksjonen ser ikke ut til å ha noe innhold"
+
+#: html/Ticket/Elements/ShowRequestor:47
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr "Denne brukerens %1 høyst prioriterte saker"
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr "Denne brukerens 23 høys prioriterte saker"
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "Tor."
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket"
+msgstr "Sak"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr "Sak # %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1 Jumbo update: %2"
+msgstr "Sak $ %1 Jumbo oppdater: %2"
+
+#: html/Ticket/ModifyAll.html:25 html/Ticket/ModifyAll.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "Sak #%1 Jumbo oppdatering: %2"
+
+#: html/Approvals/Elements/ShowDependency:46
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr "Sak #%1: %2"
+
+#: lib/RT/Ticket_Overlay.pm:587 lib/RT/Ticket_Overlay.pm:608
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr "Sak %1 opprettet i '%2' køen"
+
+#: bin/rt-commit-handler:760
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr "Sak %1 lastet\\n"
+
+#: html/Search/Bulk.html:181
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr "Sak %1: %2"
+
+#: html/Ticket/History.html:25 html/Ticket/History.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr "Sakshistorikk # %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket Id"
+msgstr "SaksId"
+
+#: etc/initialdata:309
+msgid "Ticket Resolved"
+msgstr "Løst Sak"
+
+#: html/Search/Elements/PickRestriction:63
+msgid "Ticket attachment"
+msgstr "Saks-vedlegg"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr "Saks-innhold"
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr "Sakens innholdstype"
+
+#: lib/RT/Ticket_Overlay.pm:496 lib/RT/Ticket_Overlay.pm:597
+msgid "Ticket could not be created due to an internal error"
+msgstr "Saken kunne ikke opprettes på grunn av en intern feil"
+
+#: lib/RT/Transaction_Overlay.pm:520
+msgid "Ticket created"
+msgstr "Sak opprettet"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr "Saksopprettelse feilet"
+
+#: lib/RT/Transaction_Overlay.pm:525
+msgid "Ticket deleted"
+msgstr "Sak slettet"
+
+#: html/REST/1.0/modify:29 html/REST/1.0/update:34
+msgid "Ticket id not found"
+msgstr "Saksid ikke funnet"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket killed"
+msgstr "Sak drept"
+
+#: html/REST/1.0/modify:36 html/REST/1.0/update:41
+msgid "Ticket not found"
+msgstr "Sak ikke funnet"
+
+#: etc/initialdata:295
+msgid "Ticket status changed"
+msgstr "Saksstatus endret"
+
+#: html/Ticket/Update.html:39
+msgid "Ticket watchers"
+msgstr "Saksovervåkere"
+
+#: html/Elements/Tabs:47
+msgid "Tickets"
+msgstr "Saker"
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr "Saker %1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr "Saker %1 av %2"
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Tickets from %1"
+msgstr "Saker fra %1"
+
+#: html/Approvals/Elements/ShowDependency:27
+msgid "Tickets which depend on this approval:"
+msgstr "Saker som er avhengige av denne godkjennelsen:"
+
+#: html/Ticket/Create.html:157 html/Ticket/Elements/EditBasics:48
+msgid "Time Left"
+msgstr "Tid Igjen"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:43
+msgid "Time Worked"
+msgstr "Arbeidstid"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "Tid igjen"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "Tid å vise"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "Arbeidstid"
+
+#: NOT FOUND IN SOURCE
+msgid "TimeLeft"
+msgstr "TidIgjen"
+
+#: lib/RT/Ticket_Overlay.pm:1165
+msgid "TimeWorked"
+msgstr "ArbeidsTid"
+
+#: bin/rt-commit-handler:402
+msgid "To generate a diff of this commit:"
+msgstr "For å generere en diff av denne bekreftelsen:"
+
+#: bin/rt-commit-handler:391
+msgid "To generate a diff of this commit:\\n"
+msgstr "For å genere en diff av denne bekreftelsen"
+
+#: lib/RT/Ticket_Overlay.pm:1168
+msgid "Told"
+msgstr "Fortalt"
+
+#: etc/initialdata:237
+msgid "Transaction"
+msgstr "Transaksjon"
+
+#: lib/RT/Transaction_Overlay.pm:640
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr "Transaksjon %1 slettet"
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr "Transaksjon Opprettet"
+
+#: lib/RT/Transaction_Overlay.pm:89
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr "Transaction->Create kunne ikke, siden du ikke spesifiserte en saksid"
+
+#: lib/RT/Transaction_Overlay.pm:699
+msgid "Transactions are immutable"
+msgstr "Transaksjoner er låst"
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr "Prøver å slette en rettighet: %1"
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "Tir."
+
+#: html/Admin/Elements/EditCustomField:44 html/Ticket/Elements/AddWatchers:33 html/Ticket/Elements/AddWatchers:44 html/Ticket/Elements/AddWatchers:54 lib/RT/Ticket_Overlay.pm:1166 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "Type"
+
+#: lib/RT/ScripCondition_Overlay.pm:104
+msgid "Unimplemented"
+msgstr "Uimplementert"
+
+#: html/Admin/Users/Modify.html:68
+msgid "Unix login"
+msgstr "Unix login"
+
+#: html/Admin/Elements/ModifyUser:62
+msgid "UnixUsername"
+msgstr "UnixBrukerNavn"
+
+#: lib/RT/Attachment_Overlay.pm:265
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr "Ukjent InnholdsFormatering %1"
+
+#: html/Elements/SelectResultsPerPage:37
+msgid "Unlimited"
+msgstr "Ubegrenset"
+
+#: etc/initialdata:32
+msgid "Unprivileged"
+msgstr "Upriviligert"
+
+#: lib/RT/Transaction_Overlay.pm:569
+msgid "Untaken"
+msgstr "Ikke tatt"
+
+#: html/Elements/MyTickets:64 html/Search/Bulk.html:33
+msgid "Update"
+msgstr "Oppdater"
+
+#: html/Admin/Users/Prefs.html:62
+msgid "Update ID"
+msgstr "Oppdater ID"
+
+#: html/Search/Bulk.html:120 html/Ticket/ModifyAll.html:66 html/Ticket/Update.html:67
+msgid "Update Type"
+msgstr "Oppdater Type"
+
+#: html/Search/Listing.html:61
+msgid "Update all these tickets at once"
+msgstr "Oppdater alle disse sakene samtidig"
+
+#: html/Admin/Users/Prefs.html:49
+msgid "Update email"
+msgstr "Oppdater epost"
+
+#: html/Admin/Users/Prefs.html:55
+msgid "Update name"
+msgstr "Oppdater navn"
+
+#: lib/RT/Interface/Web.pm:409
+msgid "Update not recorded."
+msgstr "Oppdatering ikke lagret."
+
+#: html/Search/Bulk.html:81
+msgid "Update selected tickets"
+msgstr "Oppdater valgte saker"
+
+#: html/Admin/Users/Prefs.html:36
+msgid "Update signature"
+msgstr "Oppdater signatur"
+
+#: html/Ticket/ModifyAll.html:63
+msgid "Update ticket"
+msgstr "Oppdater sak"
+
+#: NOT FOUND IN SOURCE
+msgid "Update ticket # %1"
+msgstr "Ooppdater sak # %1"
+
+#: html/SelfService/Update.html:25 html/SelfService/Update.html:47
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr "Oppdater sak #%1"
+
+#: html/Ticket/Update.html:135
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr "Oppdater sak #%1 (%2)"
+
+#: lib/RT/Interface/Web.pm:407
+msgid "Update type was neither correspondence nor comment."
+msgstr "Oppdateringstype var verken korrespondanse eller kommentar."
+
+#: html/Elements/SelectDateType:33 html/Ticket/Elements/ShowDates:51 lib/RT/Ticket_Overlay.pm:1169
+msgid "Updated"
+msgstr "Oppdatert"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr "Bruker %1 %2: %3\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr "Bruker %1 Passord: %2\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr "Brukeren '%1' ble ikke funnet"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr "Brukeren '%1' ble ikke funnet"
+
+#: etc/initialdata:125 etc/initialdata:191
+msgid "User Defined"
+msgstr "Bruker Definert"
+
+#: html/Admin/Users/Prefs.html:59
+msgid "User ID"
+msgstr "BrukerID"
+
+#: html/Elements/SelectUsers:26
+msgid "User Id"
+msgstr "BrukerId"
+
+#: html/Admin/Elements/GroupTabs:47 html/Admin/Elements/QueueTabs:60 html/Admin/Elements/SystemTabs:47 html/Admin/Global/index.html:59
+msgid "User Rights"
+msgstr "Brukerrettigheter"
+
+#: html/Admin/Users/Modify.html:226
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr "Bruker kunne ikke opprettes: %1"
+
+#: lib/RT/User_Overlay.pm:262
+msgid "User created"
+msgstr "Bruker opprettet"
+
+#: html/Admin/Global/GroupRights.html:67 html/Admin/Groups/GroupRights.html:54 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr "Brukerdefinerte grupper"
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr "Bruker informert"
+
+#: html/Admin/Users/Prefs.html:25 html/Admin/Users/Prefs.html:29
+msgid "User view"
+msgstr "Brukervisning"
+
+#: html/Admin/Users/Modify.html:48 html/Elements/Login:51 html/Ticket/Elements/AddWatchers:35
+msgid "Username"
+msgstr "Brukernavn"
+
+#: html/Admin/Elements/SelectNewGroupMembers:26 html/Admin/Elements/Tabs:32 html/Admin/Groups/Members.html:55 html/Admin/Queues/People.html:68 html/Admin/index.html:29 html/User/Groups/Members.html:58
+msgid "Users"
+msgstr "Brukere"
+
+#: html/Admin/Users/index.html:65
+msgid "Users matching search criteria"
+msgstr "Brukere som treffer søkekriteria"
+
+#: html/Search/Elements/PickRestriction:51
+msgid "ValueOfQueue"
+msgstr "KøVerdi"
+
+#: html/Admin/Elements/EditCustomField:57
+msgid "Values"
+msgstr "Verdier"
+
+#: NOT FOUND IN SOURCE
+msgid "VrijevormEnkele"
+msgstr "VrijevormEnkele"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Watch"
+msgstr "Overvåk"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "WatchAsAdminCc"
+msgstr "OvervåkSomAdminCc"
+
+#: NOT FOUND IN SOURCE
+msgid "Watcher loaded"
+msgstr "Overvåker lastet"
+
+#: html/Admin/Elements/QueueTabs:42
+msgid "Watchers"
+msgstr "Overvåkere"
+
+#: html/Admin/Elements/ModifyUser:56
+msgid "WebEncoding"
+msgstr "WebFormatering"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "Ons."
+
+#: etc/upgrade/2.1.71:161
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr "Når en sak har blitt godkjent av alle godkjennere, legg til korrespondanse for den opprinnelige saken"
+
+#: etc/upgrade/2.1.71:135
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr "Når en sak har blitt godkjent av en godkjenner, legg til korrespondanse til den orginale saken"
+
+#: etc/initialdata:138
+msgid "When a ticket is created"
+msgstr "Når er sak er opprettet"
+
+#: etc/upgrade/2.1.71:79
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr "Når er godkjennelsessak blir opprettet, gi melding til Eier og AdminCc om saken som venter på deres godkjenning"
+
+#: etc/initialdata:143
+msgid "When anything happens"
+msgstr "Når noe skjer"
+
+#: etc/initialdata:184
+msgid "Whenever a ticket is resolved"
+msgstr "Når en sak er løst"
+
+#: etc/initialdata:170
+msgid "Whenever a ticket's owner changes"
+msgstr "Når en sak får ny eier"
+
+#: etc/initialdata:178
+msgid "Whenever a ticket's queue changes"
+msgstr "Når en sak flyttes til en ny kø"
+
+#: etc/initialdata:162
+msgid "Whenever a ticket's status changes"
+msgstr "Når en saks status endres"
+
+#: etc/initialdata:192
+msgid "Whenever a user-defined condition occurs"
+msgstr "Når brukerdefinerte forhold intreffer"
+
+#: etc/initialdata:156
+msgid "Whenever comments come in"
+msgstr "Når kommentarer kommer inn"
+
+#: etc/initialdata:149
+msgid "Whenever correspondence comes in"
+msgstr "Når korrespondanse kommer inn"
+
+#: html/Admin/Users/Modify.html:164 html/User/Prefs.html:52
+msgid "Work"
+msgstr "Arbeid"
+
+#: html/Admin/Elements/ModifyUser:70
+msgid "WorkPhone"
+msgstr "ArbeidsTelefon"
+
+#: html/Ticket/Elements/ShowBasics:35 html/Ticket/Update.html:65
+msgid "Worked"
+msgstr "Arbeidet"
+
+#: lib/RT/Ticket_Overlay.pm:3123
+msgid "You already own this ticket"
+msgstr "Du eier allerede denne saken"
+
+#: html/autohandler:108
+msgid "You are not an authorized user"
+msgstr "Du er ikke en autorisert bruker"
+
+#: lib/RT/Ticket_Overlay.pm:2998
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "Du kan bare omfordele saker som du eier eller som ikke har en eier"
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr "Du har ikke tilgang til å se den saken.\\n"
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "Du fant %1 saker i %2 køen"
+
+#: html/NoAuth/Logout.html:31
+msgid "You have been logged out of RT."
+msgstr ""
+
+#: html/SelfService/Display.html:78
+msgid "You have no permission to create tickets in that queue."
+msgstr "Du har ikke tilgang til å opprette saker i den køen."
+
+#: lib/RT/Ticket_Overlay.pm:1895
+msgid "You may not create requests in that queue."
+msgstr "Du kan ikke opprette forespørsler i den køen."
+
+#: html/NoAuth/Logout.html:36
+msgid "You're welcome to login again"
+msgstr "Velkommen tilbake"
+
+#: NOT FOUND IN SOURCE
+msgid "Your %1 requests"
+msgstr "Dine %1 forespørsler"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr "Din RT administrastor har feilkonfigurert mail aliasene som kaller RT"
+
+#: etc/initialdata:435 etc/upgrade/2.1.71:146
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr "Din forespørsel har blitt godkjent av %1. Andre godkjennelser avventer kanskje fortsatt"
+
+#: etc/initialdata:469 etc/upgrade/2.1.71:180
+msgid "Your request has been approved."
+msgstr "Din forespørsel ble godkjent."
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr "Din forespørsel ble avvist"
+
+#: etc/initialdata:390 etc/upgrade/2.1.71:101
+msgid "Your request was rejected."
+msgstr "Din forespørsel ble avvist"
+
+#: html/autohandler:127
+msgid "Your username or password is incorrect"
+msgstr "Ditt brukernavn/passord er ugyldig"
+
+#: html/Admin/Elements/ModifyUser:84 html/Admin/Users/Modify.html:144 html/User/Prefs.html:96
+msgid "Zip"
+msgstr "Zip"
+
+#: NOT FOUND IN SOURCE
+msgid "[no subject]"
+msgstr "[ikke noe emne]"
+
+#: html/User/Elements/DelegateRights:59
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "som tildelt til %1"
+
+#: html/SelfService/Closed.html:28
+msgid "closed"
+msgstr "lukket"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:34
+msgid "contains"
+msgstr "inneholder"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content"
+msgstr "innhold"
+
+#: html/Elements/SelectAttachmentField:27
+msgid "content-type"
+msgstr "innholdstype"
+
+#: lib/RT/Ticket_Overlay.pm:2282
+msgid "correspondence (probably) not sent"
+msgstr "korrespondanse (sansynligvis) ikke sendt"
+
+#: lib/RT/Ticket_Overlay.pm:2292
+msgid "correspondence sent"
+msgstr "korrespondanse sendt"
+
+#: html/Admin/Elements/ModifyQueue:63 html/Admin/Queues/Modify.html:77 lib/RT/Date.pm:319
+msgid "days"
+msgstr "dager"
+
+#: NOT FOUND IN SOURCE
+msgid "dead"
+msgstr "død"
+
+#: html/Search/Listing.html:75
+msgid "delete"
+msgstr "slett"
+
+#: lib/RT/Queue_Overlay.pm:63
+msgid "deleted"
+msgstr "slettet"
+
+#: html/Search/Elements/PickRestriction:68
+msgid "does not match"
+msgstr "treffer ikke"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:35
+msgid "doesn't contain"
+msgstr "inneholder ikke"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "equal to"
+msgstr "lik som"
+
+#: NOT FOUND IN SOURCE
+msgid "false"
+msgstr "usant"
+
+#: html/Elements/SelectAttachmentField:28
+msgid "filename"
+msgstr "filnavn"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "greater than"
+msgstr "større enn"
+
+#: lib/RT/Group_Overlay.pm:194
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "gruppe '%1'"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "timer"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr "id"
+
+#: html/Elements/SelectBoolean:32 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88
+msgid "is"
+msgstr "er"
+
+#: html/Elements/SelectBoolean:36 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:37 html/Search/Elements/PickRestriction:48 html/Search/Elements/PickRestriction:77 html/Search/Elements/PickRestriction:89
+msgid "isn't"
+msgstr "er ikke"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "less than"
+msgstr "mindre enn"
+
+#: html/Search/Elements/PickRestriction:67
+msgid "matches"
+msgstr "treffer"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "min"
+
+#: html/Ticket/Update.html:66
+msgid "minutes"
+msgstr "minutter"
+
+#: bin/rt-commit-handler:765
+msgid "modifications\\n\\n"
+msgstr "endringer\\n\\n"
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "måneder"
+
+#: lib/RT/Queue_Overlay.pm:58
+msgid "new"
+msgstr "ny"
+
+#: html/Admin/Elements/EditScrips:43
+msgid "no value"
+msgstr "ingen verdi"
+
+#: html/Ticket/Elements/EditWatchers:28
+msgid "none"
+msgstr "ingen"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "not equal to"
+msgstr "ikke lik som"
+
+#: NOT FOUND IN SOURCE
+msgid "notlike"
+msgstr "ikkelik"
+
+#: html/SelfService/Elements/MyRequests:61 lib/RT/Queue_Overlay.pm:59
+msgid "open"
+msgstr "åpen"
+
+#: lib/RT/Group_Overlay.pm:199
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr "personlig gruppe '%1' for bruker '%2'"
+
+#: lib/RT/Group_Overlay.pm:207
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr "kø %1 %2"
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "rejected"
+msgstr "avvist"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "resolved"
+msgstr "løst"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr "sek"
+
+#: lib/RT/Queue_Overlay.pm:60
+msgid "stalled"
+msgstr "pauset"
+
+#: lib/RT/Group_Overlay.pm:202
+#. ($self->Type)
+msgid "system %1"
+msgstr "system %1"
+
+#: lib/RT/Group_Overlay.pm:213
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr "systemgruppe '%1'"
+
+#: html/Elements/Error:42 html/SelfService/Error.html:42
+msgid "the calling component did not specify why"
+msgstr "den kallende komponenten oppga ikke hvorfor"
+
+#: lib/RT/Group_Overlay.pm:210
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr "sak #%1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "true"
+msgstr "sant"
+
+#: lib/RT/Group_Overlay.pm:216
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr "ubeskrevet gruppe %1"
+
+#: NOT FOUND IN SOURCE
+msgid "undescripbed group %1"
+msgstr "ubeskrevet gruppe %1"
+
+#: lib/RT/Group_Overlay.pm:191
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr "bruker %1"
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr "uker"
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr "med malen %1"
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr "år"
+
+#: NOT FOUND IN SOURCE
+msgid "„Éã„ÉÉ„ÇØ„Éç„ɺ„Ɇ"
+msgstr "????"
+
diff --git a/rt/lib/RT/I18N/pt_br.po b/rt/lib/RT/I18N/pt_br.po
new file mode 100644 (file)
index 0000000..6962ecb
--- /dev/null
@@ -0,0 +1,4829 @@
+# $Id: pt_br.po,v 1.1 2003-07-15 13:16:28 ivan Exp $
+msgid ""
+msgstr ""
+"Project-Id-Version: RT 2.1.x\n"
+"POT-Creation-Date: 2002-05-02 11:36+0800\n"
+"PO-Revision-Date: 2002-12-07 23:20-02:00\n"
+"Last-Translator: Gustavo Chaves <gustavo@cpqd.com.br>\n"
+"Language-Team: rt-devel <rt-devel@lists.fsck.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28
+msgid "#"
+msgstr "#"
+
+#: html/Admin/Queues/Scrip.html:55
+#. ($QueueObj->id)
+msgid "#%1"
+msgstr ""
+
+#: html/Approvals/Elements/ShowDependency:50 html/Ticket/Display.html:26 html/Ticket/Display.html:30
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr "#%1: %2"
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr "%1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr "%1 %2 %3"
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr "%1 %2 %3 %4:%5:%6 %7"
+
+#: lib/RT/Ticket_Overlay.pm:3438 lib/RT/Transaction_Overlay.pm:559 lib/RT/Transaction_Overlay.pm:601
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 added"
+msgstr "%1 %2 adicionado"
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 %2 ago"
+msgstr "%1 %2 atrás"
+
+#: lib/RT/Ticket_Overlay.pm:3444 lib/RT/Transaction_Overlay.pm:566
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 changed to %3"
+msgstr "%1 %2 alterado para %3"
+
+#: lib/RT/Ticket_Overlay.pm:3441 lib/RT/Transaction_Overlay.pm:562 lib/RT/Transaction_Overlay.pm:607
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 deleted"
+msgstr "%1 %2 removido"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 %2 of group %3"
+msgstr "%1 %2 do grupo %3"
+
+#: html/Admin/Elements/EditScrips:44 html/Admin/Elements/ListGlobalScrips:28
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 with template %3"
+msgstr "%1 %2 com modelo %3"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 this ticket\\n"
+msgstr "%1 (%2) %3 este tíquete\\n"
+
+#: html/Search/Listing.html:57
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr "%1 - %2 apresentados"
+
+#: bin/rt-crontool:169 bin/rt-crontool:176 bin/rt-crontool:182
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - An argument to pass to %2"
+msgstr "%1 - Um argumento para passar para %2"
+
+#: bin/rt-crontool:185
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr "%1 - Mostra atualizações de estado no STDOUT"
+
+#: bin/rt-crontool:179
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr "%1 - Especifica o módulo de ação que você quer usar"
+
+#: bin/rt-crontool:173
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr "%1 - Especifica o módulo de condição que você quer usar"
+
+#: bin/rt-crontool:166
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr "%1 - Especifica o módulo de busca que você quer usar"
+
+#: lib/RT/ScripAction_Overlay.pm:122
+#. ($self->Id)
+msgid "%1 ScripAction loaded"
+msgstr "ScripAction %1 carregado"
+
+#: lib/RT/Ticket_Overlay.pm:3471
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 added as a value for %2"
+msgstr "%1 usado como um valor de %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on"
+msgstr "Aliases %1 requerem um TicketId no qual trabalhar"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on "
+msgstr "Aliases %1 requerem um TicketId no qual trabalhar "
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on (from %2) %3"
+msgstr "Aliases %1 requerem um TicketId no qual trabalhar (de %2) %3"
+
+#: lib/RT/Link_Overlay.pm:117 lib/RT/Link_Overlay.pm:124
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 appears to be a local object, but can't be found in the database"
+msgstr "%1 parece ser um objeto local, mas não pode ser encontrado no banco de dados"
+
+#: html/Ticket/Elements/ShowDates:52 lib/RT/Transaction_Overlay.pm:483
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 by %2"
+msgstr "%1 por %2"
+
+#: lib/RT/Transaction_Overlay.pm:537 lib/RT/Transaction_Overlay.pm:626 lib/RT/Transaction_Overlay.pm:635 lib/RT/Transaction_Overlay.pm:638
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 changed from %2 to %3"
+msgstr "%1 alterado de %2 para %3"
+
+#: lib/RT/Interface/Web.pm:857
+msgid "%1 could not be set to %2."
+msgstr "%1 não pôde ser alterado para %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr "%1 não pôde iniciar uma transação (%2)\\n"
+
+#: lib/RT/Ticket_Overlay.pm:2813
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr "%1 não pôde alterar estado para resolvido.  O banco de dados do RT pode estar inconsistente."
+
+#: html/Elements/MyTickets:25
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr "%1 tíquetes de mais alta prioridade que eu possuo..."
+
+#: html/Elements/MyRequests:25
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr "%1 tíquetes de mais alta prioridade que eu requeri..."
+
+#: bin/rt-crontool:161
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr "%1 é uma ferramenta para modificar tíquetes a partir de uma ferramenta de agenda externa, como o cron."
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr "%1 não é mais um %2 para esta fila."
+
+#: lib/RT/Ticket_Overlay.pm:1570
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr "%1 não é mais um %2 para este tíquete."
+
+#: lib/RT/Ticket_Overlay.pm:3527
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr "%1 não é mais um valor para o campo personalizado %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr "%1 não é um identificador de fila válido."
+
+#: html/Ticket/Elements/ShowBasics:36
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr "%1 min"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr "%1 não mostrado"
+
+#: html/User/Elements/DelegateRights:76
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr "%1 direitos"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr "%1 teve sucesso\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr "Tipo %1 desconhecido para $MessageId"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr "Tipo %1 desconhecido para %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 was created without a CurrentUser\\n"
+msgstr "%1 foi criado sem um CurrentUser\\n"
+
+#: lib/RT/Action/ResolveMembers.pm:42
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr "%1 resolverá todos os membros de um grupo de tíquetes resolvidos."
+
+#: NOT FOUND IN SOURCE
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr "%1 colocará como pendente uma BASE [local] se for dependente [ou membro] de uma requisição ligada."
+
+#: lib/RT/Transaction_Overlay.pm:435
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr "%1: nenhum arquivo anexo especificado"
+
+#: html/Ticket/Elements/ShowTransaction:102
+#. ($size)
+msgid "%1b"
+msgstr "%1b"
+
+#: html/Ticket/Elements/ShowTransaction:99
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr "%1k"
+
+#: lib/RT/Ticket_Overlay.pm:1140
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr "'%1' é um valor inválido para o estado"
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr "'%1' não é uma ação reconhecida."
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete group member)"
+msgstr "(Assinale para remover o membro do grupo)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr "(Assinale para remover o scrip)"
+
+#: html/Admin/Elements/EditQueueWatchers:29 html/Admin/Elements/EditScrips:35 html/Admin/Elements/EditTemplates:36 html/Admin/Groups/Members.html:52 html/Ticket/Elements/EditLinks:33 html/Ticket/Elements/EditPeople:46 html/User/Groups/Members.html:55
+msgid "(Check box to delete)"
+msgstr "(Assinale para remover)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check boxes to delete)"
+msgstr "(Assinale para remover)"
+
+#: html/Ticket/Create.html:178
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr "(Entre com identificadores de tíquetes ou URLs, separados por espaços)"
+
+#: html/Admin/Queues/Modify.html:54 html/Admin/Queues/Modify.html:60
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr "(Se deixado em branco, será entendido como %1"
+
+#: NOT FOUND IN SOURCE
+msgid "(No Value)"
+msgstr "(Sem Valor)"
+
+#: html/Admin/Elements/EditCustomFields:33 html/Admin/Elements/ListGlobalCustomFields:32
+msgid "(No custom fields)"
+msgstr "(Nenhum campo personalizado)"
+
+#: html/Admin/Groups/Members.html:50 html/User/Groups/Members.html:53
+msgid "(No members)"
+msgstr "(Sem membros)"
+
+#: html/Admin/Elements/EditScrips:32 html/Admin/Elements/ListGlobalScrips:32
+msgid "(No scrips)"
+msgstr "(Sem scrips)"
+
+#: html/Admin/Elements/EditTemplates:31
+msgid "(No templates)"
+msgstr "(Nenhum esquema)"
+
+#: html/Ticket/Update.html:85
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(Envia uma cópia-cega (Bcc) desta atualização para uma lista de endereços de email separados por vírgula.  <b>Não</b> altera quem vai receber atualizações futuras.)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Envia uma cópia-cega (Bcc) desta atualização para uma lista de endereços eletrônicos separados por vírgulas. <b>Não</b> altera o destinatário de atualizações futuras.)"
+
+#: html/Ticket/Create.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(Envia uma cópia-cega (Bcc) desta atualização para uma lista de endereços eletrônicos separados por vírgulas. <b>Não</b> altera o destinatário de atualizações futuras.)"
+
+#: html/Ticket/Update.html:81
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(Envia uma cópia-cega (Bcc) desta atualização para uma lista de endereços eletrônicos separados por vírgulas. <b>Não</b> altera o destinatário de atualizações futuras.)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(Envia uma cópia desta atualização para uma lista de endereços eletrônicos separados por vírgulas. <b>Não</b> altera o destinatário de atualizações futuras.)"
+
+#: html/Ticket/Create.html:69
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(Envia uma cópia desta atualização para uma lista de endereços eletrônicos separados por vírgulas. Estas pessoas <b>receberão</b> as atualizações futuras.)"
+
+#: html/Admin/Groups/index.html:33 html/User/Groups/index.html:33
+msgid "(empty)"
+msgstr "(vazio)"
+
+#: html/Admin/Users/index.html:39
+msgid "(no name listed)"
+msgstr "(nenhum nome listado)"
+
+#: html/Elements/MyRequests:43 html/Elements/MyTickets:45
+msgid "(no subject)"
+msgstr "(Sem assunto)"
+
+#: html/Admin/Elements/SelectRights:48 html/Elements/SelectCustomFieldValue:30 html/Ticket/Elements/EditCustomField:59 html/Ticket/Elements/ShowCustomFields:36 lib/RT/Transaction_Overlay.pm:536
+msgid "(no value)"
+msgstr "(sem valor)"
+
+#: html/Ticket/Elements/EditLinks:116
+msgid "(only one ticket)"
+msgstr "(somente um tíquete)"
+
+#: html/Elements/MyRequests:52 html/Elements/MyTickets:55
+msgid "(pending approval)"
+msgstr "(aguardando aprovação)"
+
+#: html/Elements/MyRequests:54 html/Elements/MyTickets:57
+msgid "(pending other tickets)"
+msgstr "(aguardando outros tíquetes)"
+
+#: NOT FOUND IN SOURCE
+msgid "(requestor's group)"
+msgstr "(grupo do requisitante)"
+
+#: html/Admin/Users/Modify.html:50
+msgid "(required)"
+msgstr "(requerido)"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "(untitled)"
+msgstr "(sem título)"
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I own..."
+msgstr "25 tíquetes mais prioritários que possuo..."
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I requested..."
+msgstr "25 tíquetes mais prioritários que requisitei..."
+
+#: html/Ticket/Elements/ShowBasics:32
+msgid "<% $Ticket->Status%>"
+msgstr "<% $Ticket->Status%>"
+
+#: html/Elements/SelectTicketTypes:27
+msgid "<% $_ %>"
+msgstr "<% $_ %>"
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:26
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"Novo tíquete em\">&nbsp;%1"
+
+#: NOT FOUND IN SOURCE
+msgid "??????"
+msgstr ""
+
+#: etc/initialdata:203
+msgid "A blank template"
+msgstr "Um modelo vazio"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Deleted"
+msgstr "ACE Removida"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Loaded"
+msgstr "ACE Carregada"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be deleted"
+msgstr "ACE não pôde ser removida"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be found"
+msgstr "ACE não pode ser encontrada"
+
+#: lib/RT/ACE_Overlay.pm:157 lib/RT/Principal_Overlay.pm:181
+msgid "ACE not found"
+msgstr "ACE não encontrado"
+
+#: lib/RT/ACE_Overlay.pm:831
+msgid "ACEs can only be created and deleted."
+msgstr "ACEs só podem ser criados e removidos."
+
+#: bin/rt-commit-handler:755
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr "Abortando para evitar modificações indesejadas no tíquete.\\n"
+
+#: html/User/Elements/Tabs:32
+msgid "About me"
+msgstr "Sobre mim"
+
+#: html/Admin/Users/Modify.html:80
+msgid "Access control"
+msgstr "Controle de acesso"
+
+#: html/Admin/Elements/EditScrip:57
+msgid "Action"
+msgstr "Ação"
+
+#: lib/RT/Scrip_Overlay.pm:147
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr "Ação %1 não encontrada"
+
+#: bin/rt-crontool:123
+msgid "Action committed."
+msgstr "Ação confirmada."
+
+#: bin/rt-crontool:119
+msgid "Action prepared..."
+msgstr "Ação preparada..."
+
+#: html/Search/Bulk.html:92
+msgid "Add AdminCc"
+msgstr "Adicionar AdminCc"
+
+#: html/Search/Bulk.html:90
+msgid "Add Cc"
+msgstr "Adicionar Cc"
+
+#: html/Ticket/Create.html:114 html/Ticket/Update.html:100
+msgid "Add More Files"
+msgstr "Adicionar Mais Arquivos"
+
+#: NOT FOUND IN SOURCE
+msgid "Add Next State"
+msgstr "Adicionar Próximo Estado"
+
+#: html/Search/Bulk.html:88
+msgid "Add Requestor"
+msgstr "Adicionar Requisitante"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip to this queue"
+msgstr "Adicionar um Scrip nesta fila"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip which will apply to all queues"
+msgstr "Adicionar um Scrip que será aplicado a todas as filas"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a keyword selection to this queue"
+msgstr "Adicionar uma seleção de teclado a esta fila"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr "Adicionar um novo scrip global"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr "Adicionar um scrip a esta fila"
+
+#: html/Admin/Global/Scrip.html:55
+msgid "Add a scrip which will apply to all queues"
+msgstr "Adicionar um scrip que se aplicará a todas as filas"
+
+#: html/Search/Bulk.html:118
+msgid "Add comments or replies to selected tickets"
+msgstr "Adicionar comentários ou respostas aos tíquetes selecionados"
+
+#: html/Admin/Groups/Members.html:42 html/User/Groups/Members.html:39
+msgid "Add members"
+msgstr "Adicionar membros"
+
+#: html/Admin/Queues/People.html:66 html/Ticket/Elements/AddWatchers:28
+msgid "Add new watchers"
+msgstr "Adicionar novos observadores"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr "AddNextState"
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr "Principal adicionado como um %1 para esta fila"
+
+#: lib/RT/Ticket_Overlay.pm:1454
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr "Principal adicionado como um %1 para este tíquete"
+
+#: html/Admin/Elements/ModifyUser:76 html/Admin/Users/Modify.html:122 html/User/Prefs.html:88
+msgid "Address1"
+msgstr "Endereço 1"
+
+#: html/Admin/Elements/ModifyUser:78 html/Admin/Users/Modify.html:127 html/User/Prefs.html:90
+msgid "Address2"
+msgstr "Endereço 2"
+
+#: html/Ticket/Create.html:74
+msgid "Admin Cc"
+msgstr "Admin Cc"
+
+#: etc/initialdata:274
+msgid "Admin Comment"
+msgstr "Comentário do Administrador"
+
+#: etc/initialdata:256
+msgid "Admin Correspondence"
+msgstr "Correspondência do Administrador"
+
+#: html/Admin/Queues/index.html:25 html/Admin/Queues/index.html:28
+msgid "Admin queues"
+msgstr "Administração de filas"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr "Administração de usuários"
+
+#: html/Admin/Global/index.html:26 html/Admin/Global/index.html:28
+msgid "Admin/Global configuration"
+msgstr "Administração da configuração global"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr "Administração de Grupos"
+
+#: html/Admin/Queues/Modify.html:25 html/Admin/Queues/Modify.html:29
+msgid "Admin/Queue/Basics"
+msgstr "Administração de uma fila"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr "AdminAllPersonalGroups"
+
+#: etc/initialdata:56 html/Ticket/Elements/ShowPeople:39 html/Ticket/Update.html:50 lib/RT/ACE_Overlay.pm:89
+msgid "AdminCc"
+msgstr "AdminCc"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr "AdminComment"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr "AdminCorrespondence"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "AdminCustomFields"
+msgstr "AdminCustomFields"
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "AdminGroup"
+msgstr "AdminGroup"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "AdminGroupMembership"
+msgstr "AdminGroupMembership"
+
+#: lib/RT/System.pm:59
+msgid "AdminOwnPersonalGroups"
+msgstr "AdminOwnPersonalGroups"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "AdminQueue"
+msgstr "AdminQueue"
+
+#: lib/RT/System.pm:60
+msgid "AdminUsers"
+msgstr "AdminUsers"
+
+#: html/Admin/Queues/People.html:48 html/Ticket/Elements/EditPeople:54
+msgid "Administrative Cc"
+msgstr "Cc Administrativo"
+
+#: NOT FOUND IN SOURCE
+msgid "Admins"
+msgstr "Administradores"
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr "Busca avançada"
+
+#: html/Elements/SelectDateRelation:36
+msgid "After"
+msgstr "Depois"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr "Idade"
+
+#: NOT FOUND IN SOURCE
+msgid "Alias"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Alias for"
+msgstr "Alias para"
+
+#: html/Admin/Elements/EditCustomFields:96
+msgid "All Custom Fields"
+msgstr "Todos os Campos Personalizados"
+
+#: html/Admin/Queues/index.html:53
+msgid "All Queues"
+msgstr "Todas as filas"
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr "Sempre envia uma mensagem para os requisitantes independentemente do remetente"
+
+#: html/Elements/Tabs:58
+msgid "Approval"
+msgstr "Aprovação"
+
+#: html/Approvals/Display.html:46 html/Approvals/Elements/Approve:27 html/Approvals/Elements/ShowDependency:42 html/Approvals/index.html:65
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr "Aprovação #%1: %2"
+
+#: html/Approvals/index.html:54
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr "Aprovação #%1: Notas não registradas devido a um erro de sistema"
+
+#: html/Approvals/index.html:52
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr "Aprovação #%1: Notas registradas"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Details"
+msgstr "Detalhes da Aprovação"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval diagram"
+msgstr "Diagrama da aprovação"
+
+#: html/Approvals/Elements/Approve:45
+msgid "Approve"
+msgstr "Aprove"
+
+#: etc/initialdata:431 etc/upgrade/2.1.71:148
+msgid "Approver's notes: %1"
+msgstr "Notas do aprovador: %1"
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "Abr."
+
+#: NOT FOUND IN SOURCE
+msgid "April"
+msgstr "Abril"
+
+#: html/Elements/SelectSortOrder:35
+msgid "Ascending"
+msgstr "Ascendente"
+
+#: html/Search/Bulk.html:127 html/SelfService/Update.html:36 html/Ticket/ModifyAll.html:83 html/Ticket/Update.html:100
+msgid "Attach"
+msgstr "Anexar"
+
+#: html/SelfService/Create.html:67 html/Ticket/Create.html:110
+msgid "Attach file"
+msgstr "Anexar arquivo"
+
+#: html/Ticket/Create.html:98 html/Ticket/Update.html:89
+msgid "Attached file"
+msgstr "Arquivo anexado"
+
+#: html/SelfService/Attachment/dhandler:36
+msgid "Attachment '%1' could not be loaded"
+msgstr "Arquivo anexo '%1' não pôde ser carregado"
+
+#: lib/RT/Transaction_Overlay.pm:443
+msgid "Attachment created"
+msgstr "Arquivo anexo criado"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "Nome do arquivo anexo"
+
+#: html/Ticket/Elements/ShowAttachments:26
+msgid "Attachments"
+msgstr "Arquivos anexos"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "Ago."
+
+#: NOT FOUND IN SOURCE
+msgid "August"
+msgstr "Agosto"
+
+#: html/Admin/Elements/ModifyUser:66
+msgid "AuthSystem"
+msgstr "Sistema de autenticação"
+
+#: etc/initialdata:206
+msgid "Autoreply"
+msgstr "Autoreply"
+
+#: etc/initialdata:72
+msgid "Autoreply To Requestors"
+msgstr "Autoreply para Requisitantes"
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr "AutoreplyToRequestors"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr "Assinatura PGP inválida: %1\\n"
+
+#: html/SelfService/Attachment/dhandler:40
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr "Identificador de arquivo anexo inválido.  Não pude encontrar o arquivo '%1'\\n"
+
+#: bin/rt-commit-handler:827
+#. ($val)
+msgid "Bad data in %1"
+msgstr "Dados inválidos em %1"
+
+#: html/SelfService/Attachment/dhandler:43
+#. ($trans, $AttachmentObj->TransactionId())
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr "Número inválido de transação para o arquivo anexo.  %1 deveria ser %2\\n"
+
+#: html/Admin/Elements/GroupTabs:39 html/Admin/Elements/QueueTabs:39 html/Admin/Elements/UserTabs:38 html/Ticket/Elements/Tabs:90 html/User/Elements/GroupTabs:38
+msgid "Basics"
+msgstr "Básicos"
+
+#: html/Ticket/Update.html:83
+msgid "Bcc"
+msgstr "Bcc"
+
+#: html/Admin/Elements/EditScrip:88 html/Admin/Global/GroupRights.html:85 html/Admin/Global/Template.html:46 html/Admin/Global/UserRights.html:54 html/Admin/Groups/GroupRights.html:73 html/Admin/Groups/Members.html:81 html/Admin/Groups/Modify.html:56 html/Admin/Groups/UserRights.html:55 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:45 html/Admin/Queues/UserRights.html:54 html/User/Groups/Modify.html:56
+msgid "Be sure to save your changes"
+msgstr "Não se esqueça de salvar suas alterações"
+
+#: html/Elements/SelectDateRelation:34 lib/RT/CurrentUser.pm:322
+msgid "Before"
+msgstr "Antes"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin Approval"
+msgstr "Incício da Aprovação"
+
+#: etc/initialdata:202
+msgid "Blank"
+msgstr "Vazio"
+
+#: html/Search/Listing.html:79
+msgid "Bookmarkable URL for this search"
+msgstr "URL para guardar esta busca em seus marcadores"
+
+#: html/Ticket/Elements/ShowHistory:39 html/Ticket/Elements/ShowHistory:45
+msgid "Brief headers"
+msgstr "Cabeçalhos resumidos"
+
+#: html/Search/Bulk.html:25 html/Search/Bulk.html:26
+msgid "Bulk ticket update"
+msgstr "Atualização de tíquetes em lote"
+
+#: lib/RT/User_Overlay.pm:1331
+msgid "Can not modify system users"
+msgstr "Não posso modificar os usuários do sistema"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Can this principal see this queue"
+msgstr "Este principal pode ver esta fila"
+
+#: lib/RT/CustomField_Overlay.pm:144
+msgid "Can't add a custom field value without a name"
+msgstr "Não posso adicionar um valor de campo personalizado sem um nome"
+
+#: lib/RT/Link_Overlay.pm:132
+msgid "Can't link a ticket to itself"
+msgstr "Não posso ligar um tíquete a ele mesmo"
+
+#: lib/RT/Ticket_Overlay.pm:2787
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr "Não posso unir a um tíquete já unido.  Você nunca deve obter este erro"
+
+#: lib/RT/Ticket_Overlay.pm:2605 lib/RT/Ticket_Overlay.pm:2674
+msgid "Can't specifiy both base and target"
+msgstr "Não especifique origem e destino simultaneamente"
+
+#: html/autohandler:112
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr "Não posso criar o usuário: %1"
+
+#: etc/initialdata:50 html/Admin/Queues/People.html:44 html/SelfService/Create.html:51 html/SelfService/Display.html:50 html/Ticket/Create.html:64 html/Ticket/Elements/EditPeople:51 html/Ticket/Elements/ShowPeople:35 html/Ticket/Update.html:45 html/Ticket/Update.html:78 lib/RT/ACE_Overlay.pm:88
+msgid "Cc"
+msgstr "Cc"
+
+#: html/SelfService/Prefs.html:31
+msgid "Change password"
+msgstr "Mudar a senha"
+
+#: html/Ticket/Create.html:101 html/Ticket/Update.html:92
+msgid "Check box to delete"
+msgstr "Assinale para remover"
+
+#: html/Admin/Elements/SelectRights:31
+msgid "Check box to revoke right"
+msgstr "Assinalar para revogar o direito de acesso"
+
+#: html/Ticket/Create.html:183 html/Ticket/Elements/EditLinks:131 html/Ticket/Elements/EditLinks:69 html/Ticket/Elements/ShowLinks:51
+msgid "Children"
+msgstr "Filhos"
+
+#: html/Admin/Elements/ModifyUser:80 html/Admin/Users/Modify.html:132 html/User/Prefs.html:92
+msgid "City"
+msgstr "Cidade"
+
+#: html/Ticket/Elements/ShowDates:47
+msgid "Closed"
+msgstr "Fechado"
+
+#: html/SelfService/Elements/Tabs:60
+msgid "Closed requests"
+msgstr "Requisições fechadas"
+
+#: NOT FOUND IN SOURCE
+msgid "Code"
+msgstr "Código"
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr "Comando não entendido!\\n"
+
+#: html/Ticket/Elements/ShowTransaction:179 html/Ticket/Elements/Tabs:153
+msgid "Comment"
+msgstr "Comentário"
+
+#: html/Admin/Elements/ModifyQueue:45 html/Admin/Queues/Modify.html:58
+msgid "Comment Address"
+msgstr "Endereço de Comentário"
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr "Comentário não registrado"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Comment on tickets"
+msgstr "Comente sobre os tíquetes"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "CommentOnTicket"
+msgstr "CommentOnTicket"
+
+#: html/Admin/Elements/ModifyUser:35
+msgid "Comments"
+msgstr "Comentários"
+
+#: html/Ticket/ModifyAll.html:70 html/Ticket/Update.html:70
+msgid "Comments (Not sent to requestors)"
+msgstr "Comentários (não enviados aos requisitantes)"
+
+#: html/Search/Bulk.html:122
+msgid "Comments (not sent to requestors)"
+msgstr "Comentários (não enviados aos requisitantes)"
+
+#: html/Elements/ViewUser:27
+#. ($name)
+msgid "Comments about %1"
+msgstr "Comentários sobre %1"
+
+#: html/Admin/Users/Modify.html:185 html/Ticket/Elements/ShowRequestor:44
+msgid "Comments about this user"
+msgstr "Comentários sobre este usuário"
+
+#: lib/RT/Transaction_Overlay.pm:545
+msgid "Comments added"
+msgstr "Comentários adicionados"
+
+#: lib/RT/Action/Generic.pm:140
+msgid "Commit Stubbed"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr "Compilar restrições"
+
+#: html/Admin/Elements/EditScrip:41
+msgid "Condition"
+msgstr "Condição"
+
+#: bin/rt-crontool:109
+msgid "Condition matches..."
+msgstr "Condição satisfeita..."
+
+#: lib/RT/Scrip_Overlay.pm:160
+msgid "Condition not found"
+msgstr "Condição não encontrada"
+
+#: html/Elements/Tabs:52
+msgid "Configuration"
+msgstr "Configuração"
+
+#: html/SelfService/Prefs.html:33
+msgid "Confirm"
+msgstr "Confirmar"
+
+#: html/Admin/Elements/ModifyUser:60
+msgid "ContactInfoSystem"
+msgstr "Informação de contato"
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr "Data de contato '%1' não pôde ser entendida"
+
+#: html/Admin/Elements/ModifyTemplate:44 html/Ticket/ModifyAll.html:87
+msgid "Content"
+msgstr "Conteúdo"
+
+#: NOT FOUND IN SOURCE
+msgid "Coould not create group"
+msgstr "Não pude criar o grupo"
+
+#: etc/initialdata:266
+msgid "Correspondence"
+msgstr "Correspondência"
+
+#: html/Admin/Elements/ModifyQueue:39 html/Admin/Queues/Modify.html:51
+msgid "Correspondence Address"
+msgstr "Endereço de correspondência"
+
+#: lib/RT/Transaction_Overlay.pm:541
+msgid "Correspondence added"
+msgstr "Correspondência adicionada"
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr "Correspondência não registrada"
+
+#: lib/RT/Ticket_Overlay.pm:3458
+msgid "Could not add new custom field value for ticket. "
+msgstr "Não pude adicionar novo valor de campo personalizado para o tíquete. "
+
+#: NOT FOUND IN SOURCE
+msgid "Could not add new custom field value for ticket. %1 "
+msgstr "Não pude adicionar novo valor de campo personalizado para o tíquete. %1"
+
+#: lib/RT/Ticket_Overlay.pm:2963 lib/RT/Ticket_Overlay.pm:2971 lib/RT/Ticket_Overlay.pm:2987
+msgid "Could not change owner. "
+msgstr "Não pude alterar o proprietário. "
+
+#: html/Admin/Elements/EditCustomField:68 html/Admin/Elements/EditCustomFields:166
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr "Não pude criar CampoPersonalizado"
+
+#: html/User/Groups/Modify.html:77 lib/RT/Group_Overlay.pm:474 lib/RT/Group_Overlay.pm:481
+msgid "Could not create group"
+msgstr "Não pude criar o grupo"
+
+#: html/Admin/Global/Template.html:75 html/Admin/Queues/Template.html:72
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr "Não pude criar o modelo: %1"
+
+#: lib/RT/Ticket_Overlay.pm:1073 lib/RT/Ticket_Overlay.pm:333
+msgid "Could not create ticket. Queue not set"
+msgstr "Não pude criar o tíquete. Fila não selecionada"
+
+#: lib/RT/User_Overlay.pm:208 lib/RT/User_Overlay.pm:220 lib/RT/User_Overlay.pm:238 lib/RT/User_Overlay.pm:414
+msgid "Could not create user"
+msgstr "Não pude criar o usuário"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not create watcher for requestor"
+msgstr "Não pude criar um observador para o requisitante"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr "Não pude encontrar um tíquete com identificador %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr "Não pude encontrar o grupo %1."
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1422
+msgid "Could not find or create that user"
+msgstr "Não pude encontrar ou criar o usuário"
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1501
+msgid "Could not find that principal"
+msgstr "Não pude encontrar este principal"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr "Não pude encontrar o usuário %1."
+
+#: html/Admin/Groups/Members.html:88 html/User/Groups/Members.html:90 html/User/Groups/Modify.html:82
+msgid "Could not load group"
+msgstr "Não pude carregar o grupo"
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr "Não pude fazer este principal um %1 para esta fila"
+
+#: lib/RT/Ticket_Overlay.pm:1443
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr "Não pude fazer este principal um %1 para este tíquete"
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr "Não pude remover este principal como um %1 para esta fila"
+
+#: lib/RT/Ticket_Overlay.pm:1559
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr "Não pude remover este principal como um %1 para este tíquete"
+
+#: lib/RT/Group_Overlay.pm:985
+msgid "Couldn't add member to group"
+msgstr "Não pude adicionar o membro no grupo"
+
+#: lib/RT/Ticket_Overlay.pm:3468 lib/RT/Ticket_Overlay.pm:3524
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr "Não pude criar uma transação: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr "Não sei o que fazer com a resposta do gpg\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr "Não encontrei o grupo\\n"
+
+#: lib/RT/Interface/Web.pm:866
+msgid "Couldn't find row"
+msgstr "Não pude encontrar o registro"
+
+#: lib/RT/Group_Overlay.pm:959
+msgid "Couldn't find that principal"
+msgstr "Não encontrei este principal"
+
+#: lib/RT/CustomField_Overlay.pm:175
+msgid "Couldn't find that value"
+msgstr "Não encontrei este valor"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find that watcher"
+msgstr "Não pude encontrar este observador"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr "Não pude encontrar o usuário\\n"
+
+#: lib/RT/CurrentUser.pm:112
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr "Não pude carregar %1 do banco de dados de usuários.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load KeywordSelects."
+msgstr "Não pude carregar os KeywordSelects."
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr "Não pude carregar o arquivo de configuração do RT '%1' %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr "Não pude carregar os Scrips."
+
+#: html/Admin/Groups/GroupRights.html:88 html/Admin/Groups/UserRights.html:75
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr "Não pude carregar o grupo %1"
+
+#: lib/RT/Link_Overlay.pm:175 lib/RT/Link_Overlay.pm:184 lib/RT/Link_Overlay.pm:211
+msgid "Couldn't load link"
+msgstr "Não pude carregar a ligação"
+
+#: html/Admin/Elements/EditCustomFields:147 html/Admin/Queues/People.html:121
+#. ($id)
+msgid "Couldn't load queue"
+msgstr "Não pude carregar a fila"
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:72
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr "Não pude carregar a fila %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr "Não pude carregar o scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr "Não pude carregar o modelo"
+
+#: html/Admin/Users/Prefs.html:79
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr "Não pude carregar este usuário (%1)"
+
+#: html/SelfService/Display.html:166
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr "Não pude carregar o tíquete '%1'"
+
+#: html/Admin/Elements/ModifyUser:86 html/Admin/Users/Modify.html:149 html/User/Prefs.html:98
+msgid "Country"
+msgstr "País"
+
+#: html/Admin/Elements/CreateUserCalled:26 html/Ticket/Create.html:135 html/Ticket/Create.html:195
+msgid "Create"
+msgstr "Criar"
+
+#: etc/initialdata:128
+msgid "Create Tickets"
+msgstr "Criar Tíquetes"
+
+#: html/Admin/Elements/EditCustomField:58
+msgid "Create a CustomField"
+msgstr "Criar um CampoPersonalizado"
+
+#: html/Admin/Queues/CustomField.html:48
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr "Criar um Campo Personalizado para a fila %1"
+
+#: html/Admin/Global/CustomField.html:48
+msgid "Create a CustomField which applies to all queues"
+msgstr "Criar um Campo Personalizado para todas as filas"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr "Criar um novo Campo Personalizado"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global Scrip"
+msgstr "Criar um novo Scrip global"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr "Criar um novo scrip global"
+
+#: html/Admin/Groups/Modify.html:67 html/Admin/Groups/Modify.html:93
+msgid "Create a new group"
+msgstr "Criar um novo grupo"
+
+#: html/User/Groups/Modify.html:67 html/User/Groups/Modify.html:92
+msgid "Create a new personal group"
+msgstr "Criar um novo grupo pessoal"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr "Criar uma nova fila"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr "Criar um novo scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr "Criar um novo modelo"
+
+#: html/SelfService/Create.html:30 html/Ticket/Create.html:25 html/Ticket/Create.html:28 html/Ticket/Create.html:36
+msgid "Create a new ticket"
+msgstr "Criar um novo tíquete"
+
+#: html/Admin/Users/Modify.html:214 html/Admin/Users/Modify.html:241
+msgid "Create a new user"
+msgstr "Criar um novo usuário"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "Criar uma fila"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr "Criar uma fila chamada"
+
+#: html/SelfService/Create.html:25 html/SelfService/Create.html:27
+msgid "Create a request"
+msgstr "Criar uma requisição"
+
+#: html/Admin/Queues/Scrip.html:59
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr "Criar um scrip para a fila %1"
+
+#: html/Admin/Global/Template.html:69 html/Admin/Queues/Template.html:65
+msgid "Create a template"
+msgstr "Criar um modelo"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1 / %2 / %3 "
+msgstr "Criação falhou: %1 / %2 / %3 "
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1/%2/%3"
+msgstr "Criação falhou: %1/%2/%3"
+
+#: etc/initialdata:130
+msgid "Create new tickets based on this scrip's template"
+msgstr "Criar novos tíquetes baseados no esquema deste scrip"
+
+#: html/SelfService/Create.html:81
+msgid "Create ticket"
+msgstr "Criar um tíquete"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Create tickets in this queue"
+msgstr "Criar tíquetes nesta fila"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Create, delete and modify custom fields"
+msgstr "Criar, remover e modificar campos personalizados"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Create, delete and modify queues"
+msgstr "Criar, remover e modificar filas"
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr "Criar, remover e modificar os membros dos grupos pessoais de qualquer usuário"
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify the members of personal groups"
+msgstr "Criar, remover e modificar os membros de grupos pessoais"
+
+#: lib/RT/System.pm:60
+msgid "Create, delete and modify users"
+msgstr "Criar, remover e modificar usuários"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "CreateTicket"
+msgstr "CreateTicket"
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1167
+msgid "Created"
+msgstr "Criado"
+
+#: html/Admin/Elements/EditCustomField:71
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr "CampoPersonalizado %1 criado"
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr "Modelo %1 criado"
+
+#: html/Ticket/Elements/EditLinks:28
+msgid "Current Relationships"
+msgstr "Relações atuais"
+
+#: html/Admin/Elements/EditScrips:30
+msgid "Current Scrips"
+msgstr "Scrips correntes"
+
+#: html/Admin/Groups/Members.html:39 html/User/Groups/Members.html:42
+msgid "Current members"
+msgstr "Membros atuais"
+
+#: html/Admin/Elements/SelectRights:29
+msgid "Current rights"
+msgstr "Direitos de acesso atuais"
+
+#: html/Search/Listing.html:71
+msgid "Current search criteria"
+msgstr "Critério de busca atual"
+
+#: html/Admin/Queues/People.html:41 html/Ticket/Elements/EditPeople:45
+msgid "Current watchers"
+msgstr "Observadores atuais"
+
+#: html/Admin/Global/CustomField.html:55
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr "Campo Personalizado #%1"
+
+#: html/Admin/Elements/QueueTabs:53 html/Admin/Elements/SystemTabs:40 html/Admin/Global/index.html:50 html/Ticket/Elements/ShowSummary:35
+msgid "Custom Fields"
+msgstr "Campos Personalizados"
+
+#: html/Admin/Elements/EditScrip:73
+msgid "Custom action cleanup code"
+msgstr "Código de finalização da ação customizada"
+
+#: html/Admin/Elements/EditScrip:65
+msgid "Custom action preparation code"
+msgstr "Código de preparação da ação customizada"
+
+#: html/Admin/Elements/EditScrip:49
+msgid "Custom condition"
+msgstr "Condição customizada"
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr "Campo personalizado %1 %2 %3"
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr "O campo personalizado %1 tem um valor."
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr "O campo personalizado %1 não tem valor."
+
+#: lib/RT/Ticket_Overlay.pm:3360
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr "Campo personalizado %1 não encontrado"
+
+#: html/Admin/Elements/EditCustomFields:197
+msgid "Custom field deleted"
+msgstr "Campo personalizado removido"
+
+#: lib/RT/Ticket_Overlay.pm:3510
+msgid "Custom field not found"
+msgstr "Campo personalizado não encontrado"
+
+#: lib/RT/CustomField_Overlay.pm:283
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr "O valor de campo %1 não pôde ser encontrado para o campo personalizado %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr "O valor do campo personalizado foi alterado de %1 para %2"
+
+#: lib/RT/CustomField_Overlay.pm:185
+msgid "Custom field value could not be deleted"
+msgstr "O valor do campo personalizado não pôde ser removido"
+
+#: lib/RT/CustomField_Overlay.pm:289
+msgid "Custom field value could not be found"
+msgstr "O valor de campo personalizado não pôde ser encontrado"
+
+#: lib/RT/CustomField_Overlay.pm:183 lib/RT/CustomField_Overlay.pm:291
+msgid "Custom field value deleted"
+msgstr "Valor do campo personalizado removido"
+
+#: lib/RT/Transaction_Overlay.pm:550
+msgid "CustomField"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Data error"
+msgstr "Erro de dado"
+
+#: html/Ticket/Create.html:161 html/Ticket/Elements/ShowSummary:53 html/Ticket/Elements/Tabs:93 html/Ticket/ModifyAll.html:44
+msgid "Dates"
+msgstr "Datas"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "Dez."
+
+#: NOT FOUND IN SOURCE
+msgid "December"
+msgstr "Dezembro"
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr "Esquema Padrão de Autoresposta"
+
+#: etc/initialdata:207
+msgid "Default Autoresponse template"
+msgstr "Esquema padrão de Autoresposta"
+
+#: etc/initialdata:275
+msgid "Default admin comment template"
+msgstr "Esquema padrão de comentário administrativo"
+
+#: etc/initialdata:257
+msgid "Default admin correspondence template"
+msgstr "Esquema padrão de correspondência administrativa"
+
+#: etc/initialdata:267
+msgid "Default correspondence template"
+msgstr "Esquema padrão de correspondência"
+
+#: etc/initialdata:238
+msgid "Default transaction template"
+msgstr "Esquema padrão de transação"
+
+#: lib/RT/Transaction_Overlay.pm:645
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr "Padrão: %1/%2 mudou de %3 para %4"
+
+#: html/User/Delegation.html:25 html/User/Delegation.html:28
+msgid "Delegate rights"
+msgstr "Delegar direitos de acesso"
+
+#: lib/RT/System.pm:63
+msgid "Delegate specific rights which have been granted to you."
+msgstr "Delegar direitos específicos que foram outorgados a você."
+
+#: lib/RT/System.pm:63
+msgid "DelegateRights"
+msgstr "DelegateRights"
+
+#: html/User/Elements/Tabs:38
+msgid "Delegation"
+msgstr "Delegação"
+
+#: NOT FOUND IN SOURCE
+msgid "Delete"
+msgstr "Remover"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "Delete tickets"
+msgstr "Remover tíquetes"
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "DeleteTicket"
+msgstr "DeleteTicket"
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr "Ao remover este objeto você pode quebrar a integridade referencial"
+
+#: lib/RT/Queue_Overlay.pm:292
+msgid "Deleting this object would break referential integrity"
+msgstr "Ao remover este objeto você quebra a integridade referencial"
+
+#: lib/RT/User_Overlay.pm:430
+msgid "Deleting this object would violate referential integrity"
+msgstr "Ao remover este objeto você viola a integridade referencial"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity."
+msgstr "Remover este objeto violaria a integridade referencial"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity. That's bad."
+msgstr "Remover este objeto violaria a integridade referencial.  Isto é mau."
+
+#: html/Approvals/Elements/Approve:46
+msgid "Deny"
+msgstr "Negue"
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/EditLinks:123 html/Ticket/Elements/EditLinks:47 html/Ticket/Elements/ShowDependencies:32 html/Ticket/Elements/ShowLinks:35
+msgid "Depended on by"
+msgstr "Dependem deste tíquete"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr "Dependências: \\n"
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:180 html/Ticket/Elements/EditLinks:119 html/Ticket/Elements/EditLinks:36 html/Ticket/Elements/ShowDependencies:25 html/Ticket/Elements/ShowLinks:27
+msgid "Depends on"
+msgstr "Depende de"
+
+#: NOT FOUND IN SOURCE
+msgid "DependsOn"
+msgstr "DependsOn"
+
+#: html/Elements/SelectSortOrder:35
+msgid "Descending"
+msgstr "Descendente"
+
+#: html/SelfService/Create.html:75 html/Ticket/Create.html:119
+msgid "Describe the issue below"
+msgstr "Descreva o problema abaixo"
+
+#: html/Admin/Elements/AddCustomFieldValue:27 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/EditScrip:34 html/Admin/Elements/ModifyQueue:36 html/Admin/Elements/ModifyTemplate:36 html/Admin/Groups/Modify.html:49 html/Admin/Queues/Modify.html:48 html/Elements/SelectGroups:27 html/User/Groups/Modify.html:49
+msgid "Description"
+msgstr "Descrição"
+
+#: html/SelfService/Elements/MyRequests:44
+msgid "Details"
+msgstr "Detalhes"
+
+#: html/Ticket/Elements/Tabs:85
+msgid "Display"
+msgstr "Apresentação"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Display Access Control List"
+msgstr "Mostrar Lista de Controle de Acesso"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Display Scrip templates for this queue"
+msgstr "Mostras os esquemas de Scrip para esta fila"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Display Scrips for this queue"
+msgstr "Mostrar os Scrips para esta fila"
+
+#: html/Ticket/Elements/ShowHistory:35
+msgid "Display mode"
+msgstr "Modo de apresentação"
+
+#: html/SelfService/Display.html:25 html/SelfService/Display.html:29
+#. ($Ticket->id)
+msgid "Display ticket #%1"
+msgstr "Apresentar o tíquete #%1"
+
+#: lib/RT/System.pm:54
+msgid "Do anything and everything"
+msgstr "Fazer qualquer coisa"
+
+#: html/Elements/Refresh:30
+msgid "Don't refresh this page."
+msgstr "Não recarregar esta página."
+
+#: html/Search/Elements/PickRestriction:114
+msgid "Don't show search results"
+msgstr "Não mostrar resultados da busca"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "Download"
+msgstr "Baixar"
+
+#: html/Elements/SelectDateType:32 html/Ticket/Create.html:167 html/Ticket/Elements/EditDates:45 html/Ticket/Elements/ShowDates:43 lib/RT/Ticket_Overlay.pm:1171
+msgid "Due"
+msgstr "Vencido"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr "A data de vencimento '%1' não pôde ser entendida"
+
+#: bin/rt-commit-handler:754
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr "ERRO: Não pude carregar o tíquete '%1': %2.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit"
+msgstr "Editar"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit Conditions"
+msgstr "Editar Condições"
+
+#: html/Admin/Queues/CustomFields.html:45
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr "Editar Campos Personalizados para %1"
+
+#: html/Ticket/ModifyLinks.html:36
+msgid "Edit Relationships"
+msgstr "Editar Relacionamentos"
+
+#: html/Admin/Queues/Templates.html:41
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr "Editar Esquemas para a fila %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit keywords"
+msgstr "Editar palavras chave"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr "Editar scrips"
+
+#: html/Admin/Global/index.html:46
+msgid "Edit system templates"
+msgstr "Editar os modelos do sistema"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr "Editar os modelos para %1"
+
+#: html/Admin/Elements/ModifyQueue:25 html/Admin/Queues/Modify.html:117
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr "Editando a configuração para a fila %1"
+
+#: html/Admin/Elements/ModifyUser:25
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr "Editando a configuração para o usuário %1"
+
+#: html/Admin/Elements/EditCustomField:74
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr "Editando o campo %1"
+
+#: html/Admin/Groups/Members.html:32
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr "Editando os membros do grupo %1"
+
+#: html/User/Groups/Members.html:129
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr "Editando os membros do grupo pessoal %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr "Editando o modelo %1"
+
+#: lib/RT/Ticket_Overlay.pm:2615 lib/RT/Ticket_Overlay.pm:2683
+msgid "Either base or target must be specified"
+msgstr "Você deve especificar a origem ou o destinatário"
+
+#: html/Admin/Users/Modify.html:53 html/Admin/Users/Prefs.html:46 html/Elements/SelectUsers:27 html/Ticket/Elements/AddWatchers:56 html/User/Prefs.html:42
+msgid "Email"
+msgstr "Email"
+
+#: lib/RT/User_Overlay.pm:188
+msgid "Email address in use"
+msgstr "O endereço de email já está em uso"
+
+#: html/Admin/Elements/ModifyUser:42
+msgid "EmailAddress"
+msgstr "Correio Eletrônico"
+
+#: html/Admin/Elements/ModifyUser:54
+msgid "EmailEncoding"
+msgstr "Codificação de Email"
+
+#: html/Admin/Elements/EditCustomField:36
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr "Habilitado (Deselecionando este ítem desabilita este campo personalizado)"
+
+#: html/Admin/Groups/Modify.html:53 html/User/Groups/Modify.html:53
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr "Habilitado (Deselecionando este ítem desabilita este grupo)"
+
+#: html/Admin/Queues/Modify.html:84
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr "Habilitado (desassinalando desabilita esta fila)"
+
+#: html/Admin/Elements/EditCustomFields:99
+msgid "Enabled Custom Fields"
+msgstr "Campos Personalizados Habilitados"
+
+#: html/Admin/Queues/index.html:56
+msgid "Enabled Queues"
+msgstr "Filas Habilitadas"
+
+#: html/Admin/Elements/EditCustomField:90 html/Admin/Groups/Modify.html:117 html/Admin/Queues/Modify.html:138 html/Admin/Users/Modify.html:283 html/User/Groups/Modify.html:117
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr "Estado %1 habilitado"
+
+#: lib/RT/CustomField_Overlay.pm:361
+msgid "Enter multiple values"
+msgstr "Entre com múltiplos valores"
+
+#: lib/RT/CustomField_Overlay.pm:358
+msgid "Enter one value"
+msgstr "Entre com um valor"
+
+#: html/Ticket/Elements/EditLinks:112
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "Entre com identificadores de tíquete ou URIs que levam ao tíquete.  Separe entradas múltiplas com espaços."
+
+#: html/Elements/Login:29 html/SelfService/Error.html:25 html/SelfService/Error.html:26
+msgid "Error"
+msgstr "Erro"
+
+#: NOT FOUND IN SOURCE
+msgid "Error adding watcher"
+msgstr "Erro ao adicionar um observador"
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr "Erro nos parâmetros para Queue->AddWatcher"
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr "Erro nos parâmetros para Queue->DelWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1356
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr "Erro nos parâmetros para Ticket->AddWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1532
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr "Erro nos parâmetros para Ticket->DelWatcher"
+
+#: etc/initialdata:20
+msgid "Everyone"
+msgstr "Todos"
+
+#: bin/rt-crontool:194
+msgid "Example:"
+msgstr "Exemplo:"
+
+#: html/Admin/Elements/ModifyUser:64
+msgid "ExternalAuthId"
+msgstr "ExternalAuthId"
+
+#: html/Admin/Elements/ModifyUser:58
+msgid "ExternalContactInfoId"
+msgstr "ExternalContactInfoId"
+
+#: html/Admin/Users/Modify.html:73
+msgid "Extra info"
+msgstr "Informação adicional"
+
+#: lib/RT/User_Overlay.pm:302
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr "Não pude encontrar o pseudogrupo de usuários 'Privileged'."
+
+#: lib/RT/User_Overlay.pm:309
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr "Não pude encontrar o pseudogrupo de usuários 'Unprivileged'"
+
+#: bin/rt-crontool:138
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr "Falhou ao carregar o módulo %1. (%2)"
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "Fev."
+
+#: NOT FOUND IN SOURCE
+msgid "February"
+msgstr "Fevereiro"
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr "Fin"
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:59 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "Prioridade Final"
+
+#: lib/RT/Ticket_Overlay.pm:1162
+msgid "FinalPriority"
+msgstr "FinalPriority"
+
+#: html/Admin/Queues/People.html:61 html/Ticket/Elements/EditPeople:34
+msgid "Find group whose"
+msgstr "Encontrar o grupo cujo"
+
+#: html/Elements/Quicksearch:25
+msgid "Find new/open tickets"
+msgstr "Encontrar tíquetes novos/abertos"
+
+#: html/Admin/Queues/People.html:57 html/Admin/Users/index.html:46 html/Ticket/Elements/EditPeople:30
+msgid "Find people whose"
+msgstr "Encontrar pessoas que"
+
+#: html/Search/Listing.html:108
+msgid "Find tickets"
+msgstr "Encontrar tíquetes"
+
+#: NOT FOUND IN SOURCE
+msgid "Finish Approval"
+msgstr "Terminar Aprovação"
+
+#: html/Ticket/Elements/Tabs:58
+msgid "First"
+msgstr "Primeiro"
+
+#: html/Search/Listing.html:41
+msgid "First page"
+msgstr "Primeira página"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr "Foo Bar Baz"
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr "Foo!"
+
+#: html/Search/Bulk.html:87
+msgid "Force change"
+msgstr "Force alteração"
+
+#: html/Search/Listing.html:106
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr "Encontrado %quant(%1,tíquete)"
+
+#: lib/RT/Interface/Web.pm:868
+msgid "Found Object"
+msgstr "Objeto Encontrado"
+
+#: html/Admin/Elements/ModifyUser:44
+msgid "FreeformContactInfo"
+msgstr "FreeformContactInfo"
+
+#: lib/RT/CustomField_Overlay.pm:38
+msgid "FreeformMultiple"
+msgstr "FreeformMultiple"
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformSingle"
+msgstr "FreeformSingle"
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "Sex."
+
+#: html/Ticket/Elements/ShowHistory:41 html/Ticket/Elements/ShowHistory:51
+msgid "Full headers"
+msgstr "Cabeçalhos completos"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr "Obtendo o usuário corrente a partir de uma assinatura pgp\\n"
+
+#: lib/RT/Transaction_Overlay.pm:595
+#. ($New->Name)
+msgid "Given to %1"
+msgstr "Dado a %1"
+
+#: html/Admin/Elements/Tabs:41 html/Admin/index.html:38
+msgid "Global"
+msgstr "Global"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Keyword Selections"
+msgstr "Seleções de Palavras Chave Globais"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr "Scrips Globais"
+
+#: html/Admin/Elements/SelectTemplate:38
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr "Esquema global: %1"
+
+#: html/Admin/Elements/EditCustomFields:75 html/Admin/Queues/People.html:59 html/Admin/Queues/People.html:63 html/Admin/Queues/index.html:44 html/Admin/Users/index.html:49 html/Ticket/Elements/EditPeople:32 html/Ticket/Elements/EditPeople:36 html/index.html:41
+msgid "Go!"
+msgstr "Ir!"
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr "Assinatura pgp válida de %1\\n"
+
+#: html/Search/Listing.html:50
+msgid "Goto page"
+msgstr "Ir para a página"
+
+#: html/Elements/GotoTicket:25 html/SelfService/Elements/GotoTicket:25
+msgid "Goto ticket"
+msgstr "Ir para o tíquete"
+
+#: NOT FOUND IN SOURCE
+msgid "Grand"
+msgstr ""
+
+#: html/Ticket/Elements/AddWatchers:46 html/User/Elements/DelegateRights:78
+msgid "Group"
+msgstr "Grupo"
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr "Grupo %1 %2: %3"
+
+#: html/Admin/Elements/GroupTabs:45 html/Admin/Elements/QueueTabs:57 html/Admin/Elements/SystemTabs:44 html/Admin/Global/index.html:55
+msgid "Group Rights"
+msgstr "Direitos de Acesso do Grupo"
+
+#: lib/RT/Group_Overlay.pm:965
+msgid "Group already has member"
+msgstr "O grupo já tem um membro"
+
+#: NOT FOUND IN SOURCE
+msgid "Group could not be created."
+msgstr "O grupo não pôde ser criado."
+
+#: html/Admin/Groups/Modify.html:77
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr "O grupo não pôde ser criado: %1"
+
+#: lib/RT/Group_Overlay.pm:497
+msgid "Group created"
+msgstr "Grupo criado"
+
+#: lib/RT/Group_Overlay.pm:1133
+msgid "Group has no such member"
+msgstr "O grupo não contém este membro"
+
+#: lib/RT/Group_Overlay.pm:945 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1429 lib/RT/Ticket_Overlay.pm:1507
+msgid "Group not found"
+msgstr "Grupo não encontrado"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr "Grupo não encontrado.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr "Grupo não especificado.\\n"
+
+#: html/Admin/Elements/SelectNewGroupMembers:35 html/Admin/Elements/Tabs:35 html/Admin/Groups/Members.html:64 html/Admin/Queues/People.html:83 html/Admin/index.html:32 html/User/Groups/Members.html:67
+msgid "Groups"
+msgstr "Grupos"
+
+#: lib/RT/Group_Overlay.pm:971
+msgid "Groups can't be members of their members"
+msgstr "Grupos não podem ser membros de seus próprios membros"
+
+#: lib/RT/Interface/CLI.pm:73 lib/RT/Interface/CLI.pm:73
+msgid "Hello!"
+msgstr "Olá!"
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr "Olá, %1"
+
+#: html/Ticket/Elements/ShowHistory:30 html/Ticket/Elements/Tabs:88
+msgid "History"
+msgstr "Histórico"
+
+#: html/Admin/Elements/ModifyUser:68
+msgid "HomePhone"
+msgstr "Telefone Residencial"
+
+#: html/Elements/Tabs:46
+msgid "Homepage"
+msgstr "Homepage"
+
+#: lib/RT/Base.pm:74
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr "Eu tenho %quant(%1,concrete mixer)."
+
+#: NOT FOUND IN SOURCE
+msgid "I have [quant,_1,concrete mixer]."
+msgstr "Tenho [quant,_1,concrete mixer]."
+
+#: html/Ticket/Elements/ShowBasics:27 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr "Identificador"
+
+#: html/Admin/Users/Modify.html:44 html/User/Prefs.html:39
+msgid "Identity"
+msgstr "Identidade"
+
+#: etc/upgrade/2.1.71:86
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr "Se uma aprovação é rejeitada, rejeite a original e remova as aprovações pendentes"
+
+#: bin/rt-crontool:190
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr "Se esta ferramenta fosse setgid, um usuário local mal-intencionado poderia usá-la para obter acesso administrativo ao RT."
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "If you've updated anything above, be sure to"
+msgstr "Se você alterou qualquer coisa acima, não se esqueça de"
+
+#: lib/RT/Interface/Web.pm:860
+msgid "Illegal value for %1"
+msgstr "Valor ilegal para %1"
+
+#: lib/RT/Interface/Web.pm:863
+msgid "Immutable field"
+msgstr "Campo imutável"
+
+#: html/Admin/Elements/EditCustomFields:74
+msgid "Include disabled custom fields in listing."
+msgstr "Incluir campoas personalizados desabilitados na listagem."
+
+#: html/Admin/Queues/index.html:43
+msgid "Include disabled queues in listing."
+msgstr "Incluir filas desabilitadas na listagem."
+
+#: html/Admin/Users/index.html:47
+msgid "Include disabled users in search."
+msgstr "Incluir usuários desabilitados na busca."
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr "Prioridade Inicial"
+
+#: lib/RT/Ticket_Overlay.pm:1161 lib/RT/Ticket_Overlay.pm:1163
+msgid "InitialPriority"
+msgstr "InitialPriority"
+
+#: lib/RT/ScripAction_Overlay.pm:105
+msgid "Input error"
+msgstr "Erro de entrada"
+
+#: NOT FOUND IN SOURCE
+msgid "Interest noted"
+msgstr "Interesse notado"
+
+#: lib/RT/Ticket_Overlay.pm:3729
+msgid "Internal Error"
+msgstr "Erro Interno"
+
+#: lib/RT/Record.pm:143
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr "Erro Interno: %1"
+
+#: lib/RT/Group_Overlay.pm:644
+msgid "Invalid Group Type"
+msgstr "Tipo Inválido de Grupo"
+
+#: lib/RT/Principal_Overlay.pm:128
+msgid "Invalid Right"
+msgstr "Direito Inválido"
+
+#: NOT FOUND IN SOURCE
+msgid "Invalid Type"
+msgstr "Tipo Inválido"
+
+#: lib/RT/Interface/Web.pm:865
+msgid "Invalid data"
+msgstr "Dado inválido"
+
+#: lib/RT/Ticket_Overlay.pm:438
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr "Proprietário inválido.  Usando 'nobody'."
+
+#: lib/RT/Scrip_Overlay.pm:134 lib/RT/Template_Overlay.pm:251
+msgid "Invalid queue"
+msgstr "Fila inválida"
+
+#: lib/RT/ACE_Overlay.pm:244 lib/RT/ACE_Overlay.pm:253 lib/RT/ACE_Overlay.pm:259 lib/RT/ACE_Overlay.pm:270 lib/RT/ACE_Overlay.pm:275
+msgid "Invalid right"
+msgstr "Direito de acesso inválido"
+
+#: lib/RT/Record.pm:118
+#. ($key)
+msgid "Invalid value for %1"
+msgstr "Valor inválido para %1"
+
+#: lib/RT/Ticket_Overlay.pm:3367
+msgid "Invalid value for custom field"
+msgstr "Valor inválido para o campo personalizado"
+
+#: lib/RT/Ticket_Overlay.pm:345
+msgid "Invalid value for status"
+msgstr "Valor inválido para o estado"
+
+#: bin/rt-crontool:191
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr "É extremamente importante que usuários não privilegiados não possam executar esta ferramenta."
+
+#: bin/rt-crontool:192
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr "Sugere-se que você crie um usuário UNIX não privilegiado com o grupo e acesso RT corretos para executar esta ferramenta."
+
+#: bin/rt-crontool:163
+msgid "It takes several arguments:"
+msgstr "Requer vários argumentos:"
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr "Itens requerendo minha aprovação"
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "Jan."
+
+#: NOT FOUND IN SOURCE
+msgid "January"
+msgstr "Janeiro"
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "Join or leave this group"
+msgstr "Entre ou deixe este grupo"
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "Jul."
+
+#: NOT FOUND IN SOURCE
+msgid "July"
+msgstr "Julho"
+
+#: html/Ticket/Elements/Tabs:99
+msgid "Jumbo"
+msgstr "Jumbo"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "Jun."
+
+#: NOT FOUND IN SOURCE
+msgid "June"
+msgstr "Junho"
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr "Palavra chave"
+
+#: html/Admin/Elements/ModifyUser:52
+msgid "Lang"
+msgstr "Líng"
+
+#: html/Ticket/Elements/Tabs:73
+msgid "Last"
+msgstr "Último"
+
+#: html/Ticket/Elements/EditDates:38 html/Ticket/Elements/ShowDates:39
+msgid "Last Contact"
+msgstr "Último Contato"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Contacted"
+msgstr "Contactado em"
+
+#: html/Search/Elements/TicketHeader:41
+msgid "Last Notified"
+msgstr "Notificado em"
+
+#: html/Elements/SelectDateType:30
+msgid "Last Updated"
+msgstr "Atualizado em"
+
+#: NOT FOUND IN SOURCE
+msgid "LastUpdated"
+msgstr "LastUpdated"
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr "Resta"
+
+#: html/Admin/Users/Modify.html:83
+msgid "Let this user access RT"
+msgstr "Deixar este usuário acessar RT"
+
+#: html/Admin/Users/Modify.html:87
+msgid "Let this user be granted rights"
+msgstr "Deixar este usuário receber direitos de acesso adicionais"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr "Limitando proprietário a %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr "Limitando fila a %1 %2"
+
+#: lib/RT/Ticket_Overlay.pm:2697
+msgid "Link already exists"
+msgstr "A ligação já existe"
+
+#: lib/RT/Ticket_Overlay.pm:2709
+msgid "Link could not be created"
+msgstr "A ligação não pôde ser criada"
+
+#: lib/RT/Ticket_Overlay.pm:2717 lib/RT/Ticket_Overlay.pm:2727
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr "Ligação criada (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2638
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr "Ligação removida (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2644
+msgid "Link not found"
+msgstr "Ligação não encontrada"
+
+#: html/Ticket/ModifyLinks.html:25 html/Ticket/ModifyLinks.html:29
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr "Ligar o tíquete #%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Link ticket %1"
+msgstr "Ligar o tíquete %1"
+
+#: html/Ticket/Elements/Tabs:97
+msgid "Links"
+msgstr "Ligações"
+
+#: html/Admin/Users/Modify.html:114 html/User/Prefs.html:85
+msgid "Location"
+msgstr "Localização"
+
+#: lib/RT.pm:158
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr "O diretório de log %1 não foi encontrado ou não pôde ser alterado.\\n RT não pode funcionar desta maneira."
+
+#: html/Elements/Header:57
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "Assinado como %1"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:25 html/Elements/Login:34 html/Elements/Login:45
+msgid "Login"
+msgstr "Entrar"
+
+#: html/Elements/Header:54
+msgid "Logout"
+msgstr "Sair"
+
+#: html/Search/Bulk.html:86
+msgid "Make Owner"
+msgstr "Definir como proprietário"
+
+#: html/Search/Bulk.html:102
+msgid "Make Status"
+msgstr "Definir o estado"
+
+#: html/Search/Bulk.html:109
+msgid "Make date Due"
+msgstr "Definir o prazo final"
+
+#: html/Search/Bulk.html:110
+msgid "Make date Resolved"
+msgstr "Definir a data de resolução"
+
+#: html/Search/Bulk.html:107
+msgid "Make date Started"
+msgstr "Definir a data de iniciado"
+
+#: html/Search/Bulk.html:106
+msgid "Make date Starts"
+msgstr "Definir a data início"
+
+#: html/Search/Bulk.html:108
+msgid "Make date Told"
+msgstr "Definir a data de última alteração"
+
+#: html/Search/Bulk.html:99
+msgid "Make priority"
+msgstr "Definir a prioridade"
+
+#: html/Search/Bulk.html:100
+msgid "Make queue"
+msgstr "Definir a fila"
+
+#: html/Search/Bulk.html:98
+msgid "Make subject"
+msgstr "Definir o assunto"
+
+#: html/Admin/index.html:33
+msgid "Manage groups and group membership"
+msgstr "Administrar grupos e seus membros"
+
+#: html/Admin/index.html:39
+msgid "Manage properties and configuration which apply to all queues"
+msgstr "Administrar propriedades e configurações aplicáveis a todas as filas"
+
+#: html/Admin/index.html:36
+msgid "Manage queues and queue-specific properties"
+msgstr "Administrar filas e suas propriedades específicas"
+
+#: html/Admin/index.html:30
+msgid "Manage users and passwords"
+msgstr "Administrar usuários e senhas"
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "Mar."
+
+#: NOT FOUND IN SOURCE
+msgid "March"
+msgstr "Março"
+
+#: NOT FOUND IN SOURCE
+msgid "May"
+msgstr "Maio"
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "Mai."
+
+#: lib/RT/Group_Overlay.pm:982
+msgid "Member added"
+msgstr "Membro adicionado"
+
+#: lib/RT/Group_Overlay.pm:1140
+msgid "Member deleted"
+msgstr "Membro removido"
+
+#: lib/RT/Group_Overlay.pm:1144
+msgid "Member not deleted"
+msgstr "Membro não removido"
+
+#: html/Elements/SelectLinkType:26
+msgid "Member of"
+msgstr "Membro de"
+
+#: NOT FOUND IN SOURCE
+msgid "MemberOf"
+msgstr "MemberOf"
+
+#: html/Admin/Elements/GroupTabs:42 html/User/Elements/GroupTabs:42
+msgid "Members"
+msgstr "Membros"
+
+#: lib/RT/Ticket_Overlay.pm:2843
+msgid "Merge Successful"
+msgstr "União bem sucedida"
+
+#: lib/RT/Ticket_Overlay.pm:2804
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "União falhou. Não pude definir o EffectiveId"
+
+#: html/Ticket/Elements/EditLinks:115
+msgid "Merge into"
+msgstr "Unir a"
+
+#: html/Ticket/Update.html:102
+msgid "Message"
+msgstr "Mensagem"
+
+#: lib/RT/Interface/Web.pm:867
+msgid "Missing a primary key?: %1"
+msgstr "Faltando uma chave primária?: %1"
+
+#: html/Admin/Users/Modify.html:169 html/User/Prefs.html:54
+msgid "Mobile"
+msgstr "Móvel"
+
+#: html/Admin/Elements/ModifyUser:72
+msgid "MobilePhone"
+msgstr "Celular"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify Access Control List"
+msgstr "Modificar Lista de Controle de Acesso"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Custom Field %1"
+msgstr "Modificar o campo personalizado %1"
+
+#: html/Admin/Global/CustomFields.html:44 html/Admin/Global/index.html:51
+msgid "Modify Custom Fields which apply to all queues"
+msgstr "Modificar Campos Personalizados que se aplicam a todas as filas"
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "Modify Scrip templates for this queue"
+msgstr "Modificar esquemas de Scrip para esta fila"
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "Modify Scrips for this queue"
+msgstr "Modificar Scrips para esta fila"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify System ACLS"
+msgstr "Modificar ACLs do Sistema"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr "Modificar Esquema %1"
+
+#: html/Admin/Queues/CustomField.html:45
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr "Modificar um Campo Personalizado para a fila %1"
+
+#: html/Admin/Global/CustomField.html:53
+msgid "Modify a CustomField which applies to all queues"
+msgstr "Modificar um Campo Personalizado que se aplica a todas as filas"
+
+#: html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr "Modificar um scrip para a fila %1"
+
+#: html/Admin/Global/Scrip.html:48
+msgid "Modify a scrip which applies to all queues"
+msgstr "Modificar um scrip aplicável a todas as filas"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify dates for # %1"
+msgstr "Modificar datas para # %1"
+
+#: html/Ticket/ModifyDates.html:25 html/Ticket/ModifyDates.html:29
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr "Modificar as datas para #%1"
+
+#: html/Ticket/ModifyDates.html:35
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr "Modificar as datas para o tíquete # %1"
+
+#: html/Admin/Global/GroupRights.html:25 html/Admin/Global/GroupRights.html:28 html/Admin/Global/index.html:56
+msgid "Modify global group rights"
+msgstr "Modificar direitos de acesso globais de grupo"
+
+#: html/Admin/Global/GroupRights.html:33
+msgid "Modify global group rights."
+msgstr "Modificar direitos de acesso globais de grupo."
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for groups"
+msgstr "Modificar direitos globais para grupos"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for users"
+msgstr "Modificar direitos globais para usuários"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr "Modificar scrips globais"
+
+#: html/Admin/Global/UserRights.html:25 html/Admin/Global/UserRights.html:28 html/Admin/Global/index.html:60
+msgid "Modify global user rights"
+msgstr "Modificar direitos de acesso globais de usuário"
+
+#: html/Admin/Global/UserRights.html:33
+msgid "Modify global user rights."
+msgstr "Modificar direitos de acesso globais de usuário."
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "Modify group metadata or delete group"
+msgstr "Modificar metadados do grupo ou removê-lo"
+
+#: html/Admin/Groups/GroupRights.html:25 html/Admin/Groups/GroupRights.html:29 html/Admin/Groups/GroupRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr "Modificar os direitos de acesso do grupo %1"
+
+#: html/Admin/Queues/GroupRights.html:25 html/Admin/Queues/GroupRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr "Modificar os direitos de acesso de grupo para a fila %1"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Modify membership roster for this group"
+msgstr "Modificar lista de membros deste grupo"
+
+#: lib/RT/System.pm:61
+msgid "Modify one's own RT account"
+msgstr "Modificar sua própria conta RT"
+
+#: html/Admin/Queues/People.html:25 html/Admin/Queues/People.html:29
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr "Modificar as pessoas relacionadas à fila %1"
+
+#: html/Ticket/ModifyPeople.html:25 html/Ticket/ModifyPeople.html:29 html/Ticket/ModifyPeople.html:35
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr "Modificar as pessoas relacionadas ao tíquete #%1"
+
+#: html/Admin/Queues/Scrips.html:44
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr "Modificar os scrips da fila %1"
+
+#: html/Admin/Global/Scrips.html:44 html/Admin/Global/index.html:42
+msgid "Modify scrips which apply to all queues"
+msgstr "Modificar scrips aplicáveis a todas as filas"
+
+#: html/Admin/Global/Template.html:25 html/Admin/Global/Template.html:30 html/Admin/Global/Template.html:81 html/Admin/Queues/Template.html:78
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr "Modificar o modelo %1"
+
+#: html/Admin/Global/Templates.html:44
+msgid "Modify templates which apply to all queues"
+msgstr "Modificar esquemas que se aplicam a todas as filas"
+
+#: html/Admin/Groups/Modify.html:87 html/User/Groups/Modify.html:86
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr "Modificar o grupo %1"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Modify the queue watchers"
+msgstr "Modificar os observadores da fila"
+
+#: html/Admin/Users/Modify.html:236
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr "Modificar o usuário %1"
+
+#: html/Ticket/ModifyAll.html:37
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "Modificar o tíquete # %1"
+
+#: html/Ticket/Modify.html:25 html/Ticket/Modify.html:28 html/Ticket/Modify.html:34
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "Modificar o tíquete #%1"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Modify tickets"
+msgstr "Modificar tíquetes"
+
+#: html/Admin/Groups/UserRights.html:25 html/Admin/Groups/UserRights.html:29 html/Admin/Groups/UserRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr "Modificar os direitos de acesso de usuário para o grupo %1"
+
+#: html/Admin/Queues/UserRights.html:25 html/Admin/Queues/UserRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr "Modificar os direitos de acesso de usuário para a fila %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr "Modificar os observadores para a fila '%1'"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyACL"
+msgstr "ModifyACL"
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "ModifyOwnMembership"
+msgstr "ModifyOwnMembership"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "ModifyQueueWatchers"
+msgstr "ModifyQueueWatchers"
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "ModifyScrips"
+msgstr "ModifyScrips"
+
+#: lib/RT/System.pm:61
+msgid "ModifySelf"
+msgstr "ModifySelf"
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "ModifyTemplate"
+msgstr "ModifyTemplate"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "ModifyTicket"
+msgstr "ModifyTicket"
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "Seg."
+
+#: html/Ticket/Elements/ShowRequestor:42
+#. ($name)
+msgid "More about %1"
+msgstr "Mais sobre %1"
+
+#: html/Admin/Elements/EditCustomFields:61
+msgid "Move down"
+msgstr "Descer"
+
+#: html/Admin/Elements/EditCustomFields:53
+msgid "Move up"
+msgstr "Subir"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:27
+msgid "Multiple"
+msgstr "Múltiplo"
+
+#: lib/RT/User_Overlay.pm:179
+msgid "Must specify 'Name' attribute"
+msgstr "O atributo 'Name' deve ser especificado"
+
+#: NOT FOUND IN SOURCE
+msgid "My Approvals"
+msgstr "Minhas Aprovações"
+
+#: html/Approvals/index.html:25 html/Approvals/index.html:26
+msgid "My approvals"
+msgstr "Minhas aprovações"
+
+#: html/Admin/Elements/AddCustomFieldValue:26 html/Admin/Elements/EditCustomField:32 html/Admin/Elements/ModifyTemplate:28 html/Admin/Elements/ModifyUser:30 html/Admin/Groups/Modify.html:44 html/Elements/SelectGroups:26 html/Elements/SelectUsers:28 html/User/Groups/Modify.html:44
+msgid "Name"
+msgstr "Nome"
+
+#: lib/RT/User_Overlay.pm:186
+msgid "Name in use"
+msgstr "Nome em uso"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr "Precisa de aprovação do administrador do sistema"
+
+#: html/Ticket/Elements/ShowDates:52
+msgid "Never"
+msgstr "Nunca"
+
+#: html/Elements/Quicksearch:30
+msgid "New"
+msgstr "Novo"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:93 html/User/Prefs.html:65
+msgid "New Password"
+msgstr "Nova Senha"
+
+#: etc/initialdata:311 etc/upgrade/2.1.71:16
+msgid "New Pending Approval"
+msgstr "Nova Aprovação Pendente"
+
+#: html/Ticket/Elements/EditLinks:111
+msgid "New Relationships"
+msgstr "Novos Relacionamentos"
+
+#: html/Ticket/Elements/Tabs:36
+msgid "New Search"
+msgstr "Nova busca"
+
+#: html/Admin/Global/CustomField.html:41 html/Admin/Global/CustomFields.html:39 html/Admin/Queues/CustomField.html:52 html/Admin/Queues/CustomFields.html:40
+msgid "New custom field"
+msgstr "Novo campo personalizado"
+
+#: html/Admin/Elements/GroupTabs:54 html/User/Elements/GroupTabs:52
+msgid "New group"
+msgstr "Novo grupo"
+
+#: html/SelfService/Prefs.html:32
+msgid "New password"
+msgstr "Nova senha"
+
+#: lib/RT/User_Overlay.pm:639
+msgid "New password notification sent"
+msgstr "Notificação de nova senha enviada"
+
+#: html/Admin/Elements/QueueTabs:70
+msgid "New queue"
+msgstr "Nova fila"
+
+#: html/SelfService/Elements/Tabs:63
+msgid "New request"
+msgstr "Nova requisição"
+
+#: html/Admin/Elements/SelectRights:42
+msgid "New rights"
+msgstr "Novos direitos de acesso"
+
+#: html/Admin/Global/Scrip.html:40 html/Admin/Global/Scrips.html:39 html/Admin/Queues/Scrip.html:43 html/Admin/Queues/Scrips.html:53
+msgid "New scrip"
+msgstr "Novo scrip"
+
+#: NOT FOUND IN SOURCE
+msgid "New search"
+msgstr "Nova busca"
+
+#: html/Admin/Global/Template.html:60 html/Admin/Global/Templates.html:39 html/Admin/Queues/Template.html:58 html/Admin/Queues/Templates.html:46
+msgid "New template"
+msgstr "Novo esquema"
+
+#: lib/RT/Ticket_Overlay.pm:2771
+msgid "New ticket doesn't exist"
+msgstr "O novo tíquete não existe"
+
+#: html/Admin/Elements/UserTabs:52
+msgid "New user"
+msgstr "Novo usuário"
+
+#: html/Admin/Elements/CreateUserCalled:26
+msgid "New user called"
+msgstr "Novo usuário chamado"
+
+#: html/Admin/Queues/People.html:55 html/Ticket/Elements/EditPeople:29
+msgid "New watchers"
+msgstr "Novos observadores"
+
+#: html/Admin/Users/Prefs.html:42
+msgid "New window setting"
+msgstr "Abrir nova janela"
+
+#: html/Ticket/Elements/Tabs:69
+msgid "Next"
+msgstr "Próximo"
+
+#: html/Search/Listing.html:48
+msgid "Next page"
+msgstr "Próxima página"
+
+#: html/Admin/Elements/ModifyUser:50
+msgid "NickName"
+msgstr "Apelido"
+
+#: html/Admin/Users/Modify.html:63 html/User/Prefs.html:46
+msgid "Nickname"
+msgstr "Apelido"
+
+#: html/Admin/Elements/EditCustomField:73 html/Admin/Elements/EditCustomFields:105
+msgid "No CustomField"
+msgstr "Não há Campo Personalizado"
+
+#: html/Admin/Groups/GroupRights.html:84 html/Admin/Groups/UserRights.html:71
+msgid "No Group defined"
+msgstr "Não há Grupo definido"
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:68
+msgid "No Queue defined"
+msgstr "Não há Fila definida"
+
+#: bin/rt-crontool:56
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr "Nenhum usuário RT foi encontrado. Favor consultar o administrador do RT.\\n"
+
+#: html/Admin/Global/Template.html:79 html/Admin/Queues/Template.html:76
+msgid "No Template"
+msgstr "Não há Modelo"
+
+#: bin/rt-commit-handler:764
+msgid "No Ticket specified. Aborting ticket "
+msgstr "Não há Tíquete especificado.  Abortando o tíquete "
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr "Não há Tíquete especificado. Abortando modificações no tíquete\\n\\n"
+
+#: html/Approvals/Elements/Approve:47
+msgid "No action"
+msgstr "Não há ação"
+
+#: lib/RT/Interface/Web.pm:862
+msgid "No column specified"
+msgstr "Não há coluna especificada"
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr "Comando não encontrado\\n"
+
+#: html/Elements/ViewUser:36 html/Ticket/Elements/ShowRequestor:45
+msgid "No comment entered about this user"
+msgstr "Não há comentário sobre este usuário"
+
+#: lib/RT/Ticket_Overlay.pm:2189 lib/RT/Ticket_Overlay.pm:2257
+msgid "No correspondence attached"
+msgstr "Não há nenhum arquivo anexado"
+
+#: lib/RT/Action/Generic.pm:150 lib/RT/Condition/Generic.pm:176 lib/RT/Search/ActiveTicketsInQueue.pm:56 lib/RT/Search/Generic.pm:113
+#. (ref $self)
+msgid "No description for %1"
+msgstr "Não há descrição para %1"
+
+#: lib/RT/Users_Overlay.pm:151
+msgid "No group specified"
+msgstr "Não há grupo especificado"
+
+#: lib/RT/User_Overlay.pm:857
+msgid "No password set"
+msgstr "Não há senha especificada"
+
+#: lib/RT/Queue_Overlay.pm:259
+msgid "No permission to create queues"
+msgstr "Não há permissão para criar filas"
+
+#: lib/RT/Ticket_Overlay.pm:341
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr "Sem permissão para criar tíquetes na fila '%1'"
+
+#: lib/RT/User_Overlay.pm:151
+msgid "No permission to create users"
+msgstr "Sem permissão para criar usuários"
+
+#: html/SelfService/Display.html:174
+msgid "No permission to display that ticket"
+msgstr "Sem permissão para mostrar o tíquete"
+
+#: html/SelfService/Update.html:55
+msgid "No permission to view update ticket"
+msgstr "sem permissão para ver modificar o tíquete"
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1488
+msgid "No principal specified"
+msgstr "Não há principal especificado"
+
+#: html/Admin/Queues/People.html:154 html/Admin/Queues/People.html:164
+msgid "No principals selected."
+msgstr "Não há principal selecionado."
+
+#: html/Admin/Queues/index.html:35
+msgid "No queues matching search criteria found."
+msgstr "Não há fila satisfazendo o critério de busca."
+
+#: html/Admin/Elements/SelectRights:81
+msgid "No rights found"
+msgstr "Nenhum direito encontrado"
+
+#: html/Admin/Elements/SelectRights:33
+msgid "No rights granted."
+msgstr "Nenhum direito outorgado."
+
+#: html/Search/Bulk.html:149
+msgid "No search to operate on."
+msgstr "Não há busca a realizar"
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr "Não há identificador de tíquete especificado"
+
+#: lib/RT/Transaction_Overlay.pm:480 lib/RT/Transaction_Overlay.pm:518
+msgid "No transaction type specified"
+msgstr "Não há tipo de transação especificada"
+
+#: NOT FOUND IN SOURCE
+msgid "No user or email address specified"
+msgstr "Não há usuário ou endereço de email especificado"
+
+#: html/Admin/Users/index.html:36
+msgid "No users matching search criteria found."
+msgstr "Nenhum usuário satisfazendo o critério de busca foi encontrado."
+
+#: bin/rt-commit-handler:644
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr "Nenhum usuário RT válido foi encontrado. O tratador de CVS do RT está desabilitado. Por favor, consulte o administrador do RT.\\n"
+
+#: lib/RT/Interface/Web.pm:859
+msgid "No value sent to _Set!\\n"
+msgstr "Nenhum valor enviado a _Set!\\n"
+
+#: html/Search/Elements/TicketRow:37
+msgid "Nobody"
+msgstr "Ninguém"
+
+#: lib/RT/Interface/Web.pm:864
+msgid "Nonexistant field?"
+msgstr "Campo inexistente?"
+
+#: html/Elements/Login:99
+msgid "Not logged in"
+msgstr "Não logado"
+
+#: html/Elements/Header:59 html/SelfService/Elements/Header:58
+msgid "Not logged in."
+msgstr "Não entrou."
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "Não definido"
+
+#: html/NoAuth/Reminder.html:27
+msgid "Not yet implemented."
+msgstr "Ainda não implementado."
+
+#: html/Admin/Groups/Rights.html:25
+msgid "Not yet implemented...."
+msgstr "Ainda não implementado..."
+
+#: html/Approvals/Elements/Approve:50
+msgid "Notes"
+msgstr "Notas"
+
+#: lib/RT/User_Overlay.pm:642
+msgid "Notification could not be sent"
+msgstr "A notificação não pôde ser enviada"
+
+#: etc/initialdata:94
+msgid "Notify AdminCcs"
+msgstr "Notificar AdminCcs"
+
+#: etc/initialdata:90
+msgid "Notify AdminCcs as Comment"
+msgstr "Notificar AdminCcs como Comentário"
+
+#: etc/initialdata:121
+msgid "Notify Other Recipients"
+msgstr "Notificar Outros Destinatários"
+
+#: etc/initialdata:117
+msgid "Notify Other Recipients as Comment"
+msgstr "Notificar Outros Destinatários como Comentário"
+
+#: etc/initialdata:86
+msgid "Notify Owner"
+msgstr "Notificar Proprietário"
+
+#: etc/initialdata:82
+msgid "Notify Owner as Comment"
+msgstr "Notificar Proprietário como Comentário"
+
+#: etc/initialdata:313 etc/upgrade/2.1.71:17
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr "Notificar Proprietários e AdminCcs sobre novos itens pendendo suas aprovações"
+
+#: etc/initialdata:78
+msgid "Notify Requestors"
+msgstr "Notificar Requisitantes"
+
+#: etc/initialdata:104
+msgid "Notify Requestors and Ccs"
+msgstr "Notificar Requisitantes e Ccs"
+
+#: etc/initialdata:99
+msgid "Notify Requestors and Ccs as Comment"
+msgstr "Notificar Requisitantes e Ccs como Comentário"
+
+#: etc/initialdata:113
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr "Notificar Requisitantes, Ccs e AdminCcs"
+
+#: etc/initialdata:109
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr "Notificar Requisitantes, Ccs e AdminCcs como Comentário"
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "Nov."
+
+#: NOT FOUND IN SOURCE
+msgid "November"
+msgstr "Novembro"
+
+#: lib/RT/Record.pm:157
+msgid "Object could not be created"
+msgstr "Objeto não pôde ser criado"
+
+#: lib/RT/Record.pm:176
+msgid "Object created"
+msgstr "Objeto criado"
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "Out."
+
+#: NOT FOUND IN SOURCE
+msgid "October"
+msgstr "Outubro"
+
+#: html/Elements/SelectDateRelation:35
+msgid "On"
+msgstr "Em"
+
+#: etc/initialdata:155
+msgid "On Comment"
+msgstr "Sobre Comentário"
+
+#: etc/initialdata:148
+msgid "On Correspond"
+msgstr "Sobre Correspondência"
+
+#: etc/initialdata:137
+msgid "On Create"
+msgstr "Sobre Criação"
+
+#: etc/initialdata:169
+msgid "On Owner Change"
+msgstr "Sobre Mudança de Propriedade"
+
+#: etc/initialdata:177
+msgid "On Queue Change"
+msgstr "Sobre Mudança de Fila"
+
+#: etc/initialdata:183
+msgid "On Resolve"
+msgstr "Sobre Resolução"
+
+#: etc/initialdata:161
+msgid "On Status Change"
+msgstr "Sobre Mudança de Estado"
+
+#: etc/initialdata:142
+msgid "On Transaction"
+msgstr "Sobre Transação"
+
+#: html/Approvals/Elements/PendingMyApproval:50
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr "Só mostrar aprovações para requisições criadas depois de %1"
+
+#: html/Approvals/Elements/PendingMyApproval:48
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr "Só mostrar aprovações para requisições criadas antes de %1"
+
+#: html/Elements/Quicksearch:31
+msgid "Open"
+msgstr "Aberto"
+
+#: html/Ticket/Elements/Tabs:136
+msgid "Open it"
+msgstr "Abrir"
+
+#: html/SelfService/Elements/Tabs:57
+msgid "Open requests"
+msgstr "Requisições abertas"
+
+#: html/Admin/Users/Prefs.html:41
+msgid "Open tickets (from listing) in a new window"
+msgstr "Abrir tíquetes (da listagem) em uma nova janela"
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in another window"
+msgstr "Abrir tíquetes (da listagem) em outra janela"
+
+#: etc/initialdata:133
+msgid "Open tickets on correspondence"
+msgstr "Abrir tíquetes na correspondência"
+
+#: html/Search/Elements/PickRestriction:101
+msgid "Ordering and sorting"
+msgstr "Requisitando e ordenando"
+
+#: html/Admin/Elements/ModifyUser:46 html/Admin/Users/Modify.html:117 html/Elements/SelectUsers:29 html/User/Prefs.html:86
+msgid "Organization"
+msgstr "Organização"
+
+#: html/Approvals/Elements/Approve:34
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr "Tíquete originador: #%1"
+
+#: html/Admin/Elements/ModifyQueue:55 html/Admin/Queues/Modify.html:69
+msgid "Over time, priority moves toward"
+msgstr "Após a data, a prioridade tende a"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Own tickets"
+msgstr "Próprios tíquetes"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "OwnTicket"
+msgstr "OwnTicket"
+
+#: etc/initialdata:38 html/Elements/MyRequests:32 html/SelfService/Elements/MyRequests:30 html/Ticket/Create.html:48 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/EditPeople:44 html/Ticket/Elements/ShowPeople:27 html/Ticket/Update.html:63 lib/RT/ACE_Overlay.pm:86 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "Proprietário"
+
+#: lib/RT/Ticket_Overlay.pm:3004
+#. ($OldOwnerObj->Name,  $NewOwnerObj->Name)
+msgid "Owner changed from %1 to %2"
+msgstr "Proprietário mudou de %1 para %2"
+
+#: lib/RT/Transaction_Overlay.pm:584
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr "Proprietário alterado à força de %1 para %2"
+
+#: html/Search/Elements/PickRestriction:31
+msgid "Owner is"
+msgstr "O proprietário é"
+
+#: html/Admin/Users/Modify.html:174 html/User/Prefs.html:56
+msgid "Pager"
+msgstr "Pager"
+
+#: html/Admin/Elements/ModifyUser:74
+msgid "PagerPhone"
+msgstr "Telefone do Pager"
+
+#: NOT FOUND IN SOURCE
+msgid "Parent"
+msgstr "Pai"
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/EditLinks:127 html/Ticket/Elements/EditLinks:58 html/Ticket/Elements/ShowLinks:43
+msgid "Parents"
+msgstr "Pais"
+
+#: html/Elements/Login:43 html/User/Prefs.html:61
+msgid "Password"
+msgstr "Senha"
+
+#: html/NoAuth/Reminder.html:25
+msgid "Password Reminder"
+msgstr "Lembrete de Senha"
+
+#: lib/RT/User_Overlay.pm:168 lib/RT/User_Overlay.pm:860
+msgid "Password too short"
+msgstr "Senha muito curta"
+
+#: html/Admin/Users/Modify.html:291 html/User/Prefs.html:172
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "Senha: %1"
+
+#: html/Ticket/Elements/ShowSummary:43 html/Ticket/Elements/Tabs:96 html/Ticket/ModifyAll.html:51
+msgid "People"
+msgstr "Pessoas"
+
+#: etc/initialdata:126
+msgid "Perform a user-defined action"
+msgstr "Realizar uma ação definida pelo usuário"
+
+#: lib/RT/ACE_Overlay.pm:231 lib/RT/ACE_Overlay.pm:237 lib/RT/ACE_Overlay.pm:563 lib/RT/ACE_Overlay.pm:573 lib/RT/ACE_Overlay.pm:583 lib/RT/ACE_Overlay.pm:648 lib/RT/CurrentUser.pm:83 lib/RT/CurrentUser.pm:92 lib/RT/CustomField_Overlay.pm:445 lib/RT/CustomField_Overlay.pm:451 lib/RT/Group_Overlay.pm:1095 lib/RT/Group_Overlay.pm:1099 lib/RT/Group_Overlay.pm:1108 lib/RT/Group_Overlay.pm:1159 lib/RT/Group_Overlay.pm:1163 lib/RT/Group_Overlay.pm:1169 lib/RT/Group_Overlay.pm:426 lib/RT/Group_Overlay.pm:518 lib/RT/Group_Overlay.pm:596 lib/RT/Group_Overlay.pm:604 lib/RT/Group_Overlay.pm:701 lib/RT/Group_Overlay.pm:705 lib/RT/Group_Overlay.pm:711 lib/RT/Group_Overlay.pm:904 lib/RT/Group_Overlay.pm:908 lib/RT/Group_Overlay.pm:921 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:126 lib/RT/Scrip_Overlay.pm:137 lib/RT/Scrip_Overlay.pm:197 lib/RT/Scrip_Overlay.pm:430 lib/RT/Template_Overlay.pm:284 lib/RT/Template_Overlay.pm:88 lib/RT/Template_Overlay.pm:94 lib/RT/Ticket_Overlay.pm:1341 lib/RT/Ticket_Overlay.pm:1351 lib/RT/Ticket_Overlay.pm:1365 lib/RT/Ticket_Overlay.pm:1518 lib/RT/Ticket_Overlay.pm:1527 lib/RT/Ticket_Overlay.pm:1540 lib/RT/Ticket_Overlay.pm:1875 lib/RT/Ticket_Overlay.pm:2013 lib/RT/Ticket_Overlay.pm:2177 lib/RT/Ticket_Overlay.pm:2244 lib/RT/Ticket_Overlay.pm:2596 lib/RT/Ticket_Overlay.pm:2668 lib/RT/Ticket_Overlay.pm:2762 lib/RT/Ticket_Overlay.pm:2777 lib/RT/Ticket_Overlay.pm:2910 lib/RT/Ticket_Overlay.pm:3139 lib/RT/Ticket_Overlay.pm:3337 lib/RT/Ticket_Overlay.pm:3499 lib/RT/Ticket_Overlay.pm:3551 lib/RT/Ticket_Overlay.pm:3716 lib/RT/Transaction_Overlay.pm:468 lib/RT/Transaction_Overlay.pm:475 lib/RT/Transaction_Overlay.pm:504 lib/RT/Transaction_Overlay.pm:511 lib/RT/User_Overlay.pm:1334 lib/RT/User_Overlay.pm:562 lib/RT/User_Overlay.pm:597 lib/RT/User_Overlay.pm:853 lib/RT/User_Overlay.pm:941
+msgid "Permission Denied"
+msgstr "Permissão Negada"
+
+#: html/User/Elements/Tabs:35
+msgid "Personal Groups"
+msgstr "Grupoas Pessoais"
+
+#: html/User/Groups/index.html:30 html/User/Groups/index.html:40
+msgid "Personal groups"
+msgstr "Grupos pessoais"
+
+#: html/User/Elements/DelegateRights:37
+msgid "Personal groups:"
+msgstr "Grupos pessoais:"
+
+#: html/Admin/Users/Modify.html:156 html/User/Prefs.html:49
+msgid "Phone numbers"
+msgstr "Telefones"
+
+#: html/Admin/Users/Rights.html:25
+msgid "Placeholder"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Pref"
+msgstr ""
+
+#: html/Elements/Header:52 html/Elements/Tabs:55 html/SelfService/Prefs.html:25 html/User/Prefs.html:25 html/User/Prefs.html:28
+msgid "Preferences"
+msgstr "Preferências"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr "Prefs"
+
+#: lib/RT/Action/Generic.pm:160
+msgid "Prepare Stubbed"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:61
+msgid "Prev"
+msgstr "Anterior"
+
+#: html/Search/Listing.html:44
+msgid "Previous page"
+msgstr "Página anterior"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr "Pri"
+
+#: lib/RT/ACE_Overlay.pm:133 lib/RT/ACE_Overlay.pm:208 lib/RT/ACE_Overlay.pm:552
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr "Principal %1 não encontrado."
+
+#: html/Search/Elements/PickRestriction:54 html/SelfService/Display.html:76 html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:54 html/Ticket/Elements/ShowBasics:39 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "Prioridade"
+
+#: html/Admin/Elements/ModifyQueue:51 html/Admin/Queues/Modify.html:65
+msgid "Priority starts at"
+msgstr "A prioridade inicia em"
+
+#: etc/initialdata:25
+msgid "Privileged"
+msgstr "Privilegiado"
+
+#: html/Admin/Users/Modify.html:271 html/User/Prefs.html:163
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr "Estado privilegiado: %1"
+
+#: html/Admin/Users/index.html:62
+msgid "Privileged users"
+msgstr "Usuários privilegiados"
+
+#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59
+msgid "Pseudogroup for internal use"
+msgstr "Falso-grupo para uso interno"
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Elements/Quicksearch:29 html/Search/Elements/PickRestriction:46 html/SelfService/Create.html:35 html/SelfService/Display.html:68 html/Ticket/Create.html:38 html/Ticket/Elements/EditBasics:64 html/Ticket/Elements/ShowBasics:43 html/User/Elements/DelegateRights:80 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "Fila"
+
+#: html/Admin/Queues/CustomField.html:42 html/Admin/Queues/Scrip.html:50 html/Admin/Queues/Scrips.html:46 html/Admin/Queues/Templates.html:43
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr "Fila %1 não encontrada"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr "A fila '%1' não foi encontrada\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Keyword Selections"
+msgstr "Seleções de Palavras-chave da Fila"
+
+#: html/Admin/Elements/ModifyQueue:31 html/Admin/Queues/Modify.html:43
+msgid "Queue Name"
+msgstr "Nome da Fila"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr "Scrips da Fila"
+
+#: lib/RT/Queue_Overlay.pm:263
+msgid "Queue already exists"
+msgstr "A fila já existe"
+
+#: lib/RT/Queue_Overlay.pm:272 lib/RT/Queue_Overlay.pm:278
+msgid "Queue could not be created"
+msgstr "A fila não pôde ser criada"
+
+#: html/Ticket/Create.html:209
+msgid "Queue could not be loaded."
+msgstr "A fila não pôde ser carregada"
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:282
+msgid "Queue created"
+msgstr "Fila criada"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue is not specified."
+msgstr "A fila não foi especificada."
+
+#: html/SelfService/Display.html:129
+msgid "Queue not found"
+msgstr "Fila não encontrada"
+
+#: html/Admin/Elements/Tabs:38 html/Admin/index.html:35
+msgid "Queues"
+msgstr "Filas"
+
+#: html/Elements/Login:34
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr "RT %1"
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr "RT %1 para %2"
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr "RT %1 por <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1. Direitos reservados 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1. Direitos reservados 1996-2002 Jesse Vincent <jesse\\\\@bestpractical.com>\\\\n"
+
+#: html/Admin/index.html:25 html/Admin/index.html:26
+msgid "RT Administration"
+msgstr "Adiministração do RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr "Erro de autenticação no RT."
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr "Ricocheteio do RT: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr "Erro de configuração do RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr "Erro crítico no RT.  A mensagem não foi registrada!"
+
+#: html/Elements/Error:41 html/SelfService/Error.html:41
+msgid "RT Error"
+msgstr "Erro no RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr "O RT recebeu email (%1) dele próprio."
+
+#: NOT FOUND IN SOURCE
+msgid "RT Recieved mail (%1) from itself."
+msgstr "O RT recebeu email (%1) de si próprio."
+
+#: html/SelfService/Closed.html:25
+msgid "RT Self Service / Closed Tickets"
+msgstr "Auto-serviço do RT / Tíquetes Fechados"
+
+#: html/index.html:25 html/index.html:28
+msgid "RT at a glance"
+msgstr "RT por alto"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr "O RT não pôde autenticá-lo"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr "O RT não pôde encontrar o requisitante através de consulta ao banco de dados externo"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr "O RT não pôde encontrar a fila: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr "O RT não pôde validar esta assinatura PGP. \\n"
+
+#: html/Elements/PageLayout:26
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr "RT para %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr "RT para %1: %2"
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr "O RT processou seus comandos"
+
+#: html/Elements/Login:83
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT tem &copy; Direitos Reservados 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  Ele é distribuído sob a <a href=\"http://www.gnu.org/copyleft/gpl.html\">Versão 2 da Licença Pública Geral GNU (GPL).</a>"
+
+#: NOT FOUND IN SOURCE
+msgid "RT is &copy; Copyright 1996-2002 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT tem &copy; Direitos Reservados 1996-%1 por Jesse Vincent &lt;jesse@bestpractical.com&gt;.  Ele é distribuído sob a <a href=\\\"http://www.gnu.org/copyleft/gpl.html\\\">Versão 2 da Licença Pública Geral GNU (GPL).</a>"
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr "O RT crê que esta mensagem seja um ricochete"
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr "O RT vai processar esta mensagem como se não fosse assinada.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr "O modo de comandos por email do RT requer autenticação PGP. Ou você não assinou sua mensagem ou sua assinatura não pôde ser verificada."
+
+#: html/Admin/Users/Modify.html:58 html/Admin/Users/Prefs.html:52 html/User/Prefs.html:44
+msgid "Real Name"
+msgstr "Nome real"
+
+#: html/Admin/Elements/ModifyUser:48
+msgid "RealName"
+msgstr "Nome real"
+
+#: html/Ticket/Create.html:185 html/Ticket/Elements/EditLinks:139 html/Ticket/Elements/EditLinks:94 html/Ticket/Elements/ShowLinks:63
+msgid "Referred to by"
+msgstr "Referenciado por"
+
+#: html/Elements/SelectLinkType:28 html/Ticket/Create.html:184 html/Ticket/Elements/EditLinks:135 html/Ticket/Elements/EditLinks:80 html/Ticket/Elements/ShowLinks:55
+msgid "Refers to"
+msgstr "Faz referência a"
+
+#: NOT FOUND IN SOURCE
+msgid "RefersTo"
+msgstr "RefersTo"
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr "Refinar"
+
+#: html/Search/Elements/PickRestriction:27
+msgid "Refine search"
+msgstr "Refinar a Busca"
+
+#: html/Elements/Refresh:36
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "Recarregar esta página a cada %1 minutos."
+
+#: html/Ticket/Create.html:174 html/Ticket/Elements/ShowSummary:60 html/Ticket/ModifyAll.html:57
+msgid "Relationships"
+msgstr "Relacionamentos"
+
+#: html/Search/Bulk.html:93
+msgid "Remove AdminCc"
+msgstr "Remover AdminCc"
+
+#: html/Search/Bulk.html:91
+msgid "Remove Cc"
+msgstr "Remover Cc"
+
+#: html/Search/Bulk.html:89
+msgid "Remove Requestor"
+msgstr "Remover Requisitante"
+
+#: html/Ticket/Elements/ShowTransaction:173 html/Ticket/Elements/Tabs:122
+msgid "Reply"
+msgstr "Responder"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Reply to tickets"
+msgstr "Responder aos tíquetes"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "ReplyToTicket"
+msgstr "ReplyToTicket"
+
+#: etc/initialdata:44 html/Ticket/Update.html:40 lib/RT/ACE_Overlay.pm:87
+msgid "Requestor"
+msgstr "Requisitante"
+
+#: html/Search/Elements/PickRestriction:38
+msgid "Requestor email address"
+msgstr "Endereço eletrônico do requisitante"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr "Requisitante(s)"
+
+#: NOT FOUND IN SOURCE
+msgid "RequestorAddresses"
+msgstr "RequestorAddresses"
+
+#: html/SelfService/Create.html:43 html/SelfService/Display.html:42 html/Ticket/Create.html:56 html/Ticket/Elements/EditPeople:48 html/Ticket/Elements/ShowPeople:31
+msgid "Requestors"
+msgstr "Requisitantes"
+
+#: html/Admin/Elements/ModifyQueue:61 html/Admin/Queues/Modify.html:75
+msgid "Requests should be due in"
+msgstr "A requisições vencem em"
+
+#: html/Elements/Submit:62
+msgid "Reset"
+msgstr "Restaurar"
+
+#: html/Admin/Users/Modify.html:159 html/User/Prefs.html:50
+msgid "Residence"
+msgstr "Residência"
+
+#: html/Ticket/Elements/Tabs:132
+msgid "Resolve"
+msgstr "Resolver"
+
+#: html/Ticket/Update.html:133
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr "Resolver tíquete #%1 (%2)"
+
+#: etc/initialdata:302 html/Elements/SelectDateType:28 lib/RT/Ticket_Overlay.pm:1170
+msgid "Resolved"
+msgstr "Resolvido"
+
+#: html/Search/Bulk.html:123 html/Ticket/ModifyAll.html:73 html/Ticket/Update.html:73
+msgid "Response to requestors"
+msgstr "Resposta aos requisitantes"
+
+#: html/Elements/ListActions:26
+msgid "Results"
+msgstr "Resultados"
+
+#: html/Search/Elements/PickRestriction:105
+msgid "Results per page"
+msgstr "Resultados por página"
+
+#: html/Admin/Elements/ModifyUser:33 html/Admin/Users/Modify.html:100 html/User/Prefs.html:72
+msgid "Retype Password"
+msgstr "Confirmar a Senha"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr "Direito de acesso %1 não encontrado para %2  %3 referente a %4 (%5)\\n"
+
+#: lib/RT/ACE_Overlay.pm:613
+msgid "Right Delegated"
+msgstr "Direito de Acesso Delegado"
+
+#: lib/RT/ACE_Overlay.pm:303
+msgid "Right Granted"
+msgstr "Direito de Acesso Outorgado"
+
+#: lib/RT/ACE_Overlay.pm:161
+msgid "Right Loaded"
+msgstr "Direito de Acesso Carregado"
+
+#: lib/RT/ACE_Overlay.pm:678 lib/RT/ACE_Overlay.pm:693
+msgid "Right could not be revoked"
+msgstr "Direito de acesso não pôde ser revogado"
+
+#: html/User/Delegation.html:64
+msgid "Right not found"
+msgstr "Direito de acesso não encontrado"
+
+#: lib/RT/ACE_Overlay.pm:543 lib/RT/ACE_Overlay.pm:638
+msgid "Right not loaded."
+msgstr "Direito de acesso não carregado."
+
+#: lib/RT/ACE_Overlay.pm:689
+msgid "Right revoked"
+msgstr "Direito de acesso revogado"
+
+#: html/Admin/Elements/UserTabs:41
+msgid "Rights"
+msgstr "Direitos de Acesso"
+
+#: lib/RT/Interface/Web.pm:758
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr "Direitos de acesso não puderam ser outorgados a %1"
+
+#: lib/RT/Interface/Web.pm:791
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr "Direitos de acesso não puderam ser revogados de %1"
+
+#: html/Admin/Global/GroupRights.html:51 html/Admin/Queues/GroupRights.html:52
+msgid "Roles"
+msgstr "Papéis"
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr "RootApproval"
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "Sáb."
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "Save Changes"
+msgstr "Salvar as Alterações"
+
+#: html/Ticket/ModifyLinks.html:39
+msgid "Save changes"
+msgstr "Salvar as alterações"
+
+#: html/Admin/Global/Scrip.html:49
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr "Scrip #%1"
+
+#: lib/RT/Scrip_Overlay.pm:176
+msgid "Scrip Created"
+msgstr "Scrip Criado"
+
+#: html/Admin/Elements/EditScrips:84
+msgid "Scrip deleted"
+msgstr "Scrip removido"
+
+#: html/Admin/Elements/QueueTabs:46 html/Admin/Elements/SystemTabs:33 html/Admin/Global/index.html:41
+msgid "Scrips"
+msgstr "Scrips"
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr "Scrips para %1\\n"
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr "Scrips aplicáveis a todas as filas"
+
+#: html/Elements/SimpleSearch:27 html/Search/Elements/PickRestriction:126 html/Ticket/Elements/Tabs:159
+msgid "Search"
+msgstr "Buscar"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr "Critérios de Busca"
+
+#: html/Approvals/Elements/PendingMyApproval:39
+msgid "Search for approvals"
+msgstr "Buscar por aprovações"
+
+#: bin/rt-crontool:188
+msgid "Security:"
+msgstr "Segurança:"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "SeeQueue"
+msgstr "SeeQueue"
+
+#: html/Admin/Groups/index.html:40
+msgid "Select a group"
+msgstr "Selecionar um grupo"
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr "Selecionar uma fila"
+
+#: html/Admin/Users/index.html:25 html/Admin/Users/index.html:28
+msgid "Select a user"
+msgstr "Selecionar um usuário"
+
+#: html/Admin/Global/CustomField.html:38 html/Admin/Global/CustomFields.html:36
+msgid "Select custom field"
+msgstr "Selecionar um campo personalizado"
+
+#: html/Admin/Elements/GroupTabs:52 html/User/Elements/GroupTabs:50
+msgid "Select group"
+msgstr "Selecionar um grupo"
+
+#: lib/RT/CustomField_Overlay.pm:355
+msgid "Select multiple values"
+msgstr "Selecionar múltiplos valores"
+
+#: lib/RT/CustomField_Overlay.pm:352
+msgid "Select one value"
+msgstr "Selecionar um valor"
+
+#: html/Admin/Elements/QueueTabs:67
+msgid "Select queue"
+msgstr "Selecionar uma fila"
+
+#: html/Admin/Global/Scrip.html:37 html/Admin/Global/Scrips.html:36 html/Admin/Queues/Scrip.html:40 html/Admin/Queues/Scrips.html:50
+msgid "Select scrip"
+msgstr "Selecionar um scrip"
+
+#: html/Admin/Global/Template.html:57 html/Admin/Global/Templates.html:36 html/Admin/Queues/Template.html:55
+msgid "Select template"
+msgstr "Selecionar um esquema"
+
+#: html/Admin/Elements/UserTabs:49
+msgid "Select user"
+msgstr "Selecionar um usuário"
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "SelectMultiple"
+msgstr "SelectMultiple"
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectSingle"
+msgstr "SelectSingle"
+
+#: html/SelfService/index.html:25
+msgid "Self Service"
+msgstr "Auto-serviço"
+
+#: etc/initialdata:114
+msgid "Send mail to all watchers"
+msgstr "Enviar mensagem a todos os observadores"
+
+#: etc/initialdata:110
+msgid "Send mail to all watchers as a \"comment\""
+msgstr "Enviar mensagem a todos os observadores como um \"comentário\""
+
+#: etc/initialdata:105
+msgid "Send mail to requestors and Ccs"
+msgstr "Enviar mensagem aos requisitantes e Ccs"
+
+#: etc/initialdata:100
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr "Enviar mensagem aos requisitantes e Ccs como um comentário"
+
+#: etc/initialdata:79
+msgid "Sends a message to the requestors"
+msgstr "Envia uma mensagem aos requisitantes"
+
+#: etc/initialdata:118 etc/initialdata:122
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr "Envia uma mensagem aos Ccs e Bccs explicitamente listados"
+
+#: etc/initialdata:95
+msgid "Sends mail to the administrative Ccs"
+msgstr "Envia uma mensagem aos Ccs administrativos"
+
+#: etc/initialdata:91
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr "Envia uma mensagem aos Ccs administrativos como um comentário"
+
+#: etc/initialdata:83 etc/initialdata:87
+msgid "Sends mail to the owner"
+msgstr "Envia uma mensagem ao proprietário"
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "Set."
+
+#: NOT FOUND IN SOURCE
+msgid "September"
+msgstr "Setembro"
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr "Mostrar os Resultados"
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show approved requests"
+msgstr "Mostrar requisições aprovadas"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show basics"
+msgstr "Mostrar o sumário"
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show denied requests"
+msgstr "Mostrar requisições negadas"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show details"
+msgstr "Mostrar os detalhes"
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show pending requests"
+msgstr "Mostrar requisições pendentes"
+
+#: html/Approvals/Elements/PendingMyApproval:46
+msgid "Show requests awaiting other approvals"
+msgstr "Mostrar requisições aguardando outras aprovações"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Show ticket private commentary"
+msgstr "Mostrar comentário privado do tíquete"
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "Show ticket summaries"
+msgstr "Mostrar sumários do tíquete"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ShowACL"
+msgstr "ShowACL"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowScrips"
+msgstr "ShowScrips"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ShowTemplate"
+msgstr "ShowTemplate"
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "ShowTicket"
+msgstr "ShowTicket"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "ShowTicketComments"
+msgstr "ShowTicketComments"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr "Cadastrar como um Requisitante de tíquete ou um Cc de tíquete ou fila"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr "Cadastrar como um AdminCC de tíquete ou fila"
+
+#: html/Admin/Elements/ModifyUser:39 html/Admin/Users/Modify.html:191 html/Admin/Users/Prefs.html:32 html/SelfService/Prefs.html:37 html/User/Prefs.html:112
+msgid "Signature"
+msgstr "Assinatura"
+
+#: html/SelfService/Elements/Header:52
+#. ($session{'CurrentUser'}->Name)
+msgid "Signed in as %1"
+msgstr "Assinado como %1"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Single"
+msgstr "Único"
+
+#: html/Elements/Header:51
+msgid "Skip Menu"
+msgstr "Saltar Menu"
+
+#: html/Admin/Elements/EditCustomFieldValues:31
+msgid "Sort key"
+msgstr "Chave de ordenação"
+
+#: html/Search/Elements/PickRestriction:109
+msgid "Sort results by"
+msgstr "Ordenar os resultados por"
+
+#: html/Admin/Elements/AddCustomFieldValue:25
+msgid "SortOrder"
+msgstr "Ordenação"
+
+#: NOT FOUND IN SOURCE
+msgid "Stalled"
+msgstr "Pendente"
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr "Página inicial"
+
+#: html/Elements/SelectDateType:27 html/Ticket/Elements/EditDates:32 html/Ticket/Elements/ShowDates:35
+msgid "Started"
+msgstr "Iniciado"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr "A data de iníciado '%1' não pôde ser compreendida"
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:27 html/Ticket/Elements/ShowDates:31
+msgid "Starts"
+msgstr "Inicia"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr "Inicia Por"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr "A data de início '%1' não pôde ser compreendida"
+
+#: html/Admin/Elements/ModifyUser:82 html/Admin/Users/Modify.html:138 html/User/Prefs.html:94
+msgid "State"
+msgstr "Estado"
+
+#: html/Elements/MyRequests:31 html/Elements/MyTickets:31 html/Search/Elements/PickRestriction:74 html/SelfService/Display.html:59 html/SelfService/Elements/MyRequests:29 html/SelfService/Update.html:31 html/Ticket/Create.html:42 html/Ticket/Elements/EditBasics:38 html/Ticket/Elements/ShowBasics:31 html/Ticket/Update.html:60 lib/RT/Ticket_Overlay.pm:1164 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "Estado"
+
+#: etc/initialdata:288
+msgid "Status Change"
+msgstr "Mudança de Estado"
+
+#: lib/RT/Transaction_Overlay.pm:530
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr "Estado alterado de %1 para %2"
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr "StatusChange"
+
+#: html/Ticket/Elements/Tabs:147
+msgid "Steal"
+msgstr "Roubar"
+
+#: lib/RT/Transaction_Overlay.pm:589
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "Roubado de %1 "
+
+#: html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Search/Bulk.html:126 html/Search/Elements/PickRestriction:43 html/SelfService/Create.html:59 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:35 html/Ticket/Create.html:84 html/Ticket/Elements/EditBasics:28 html/Ticket/ModifyAll.html:79 html/Ticket/Update.html:77 lib/RT/Ticket_Overlay.pm:1160 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "Assunto"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:611
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr "Assunto modou para %1"
+
+#: html/Elements/Submit:59
+msgid "Submit"
+msgstr "Enviar"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr "Enviar Workflow"
+
+#: lib/RT/Group_Overlay.pm:749
+msgid "Succeeded"
+msgstr "Deu certo"
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "Dom."
+
+#: lib/RT/System.pm:54
+msgid "SuperUser"
+msgstr "SuperUser"
+
+#: html/User/Elements/DelegateRights:77
+msgid "System"
+msgstr "Sistema"
+
+#: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:567 lib/RT/Interface/Web.pm:757 lib/RT/Interface/Web.pm:790
+msgid "System Error"
+msgstr "Erro do Sistema"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. Right not granted."
+msgstr "Erro de sistema.  Direito não outorgado."
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. right not granted"
+msgstr "Erro de sistema.  direito não outorgado"
+
+#: lib/RT/ACE_Overlay.pm:616
+msgid "System error. Right not delegated."
+msgstr "Erro do sistema. Direito de acesso não delegado."
+
+#: lib/RT/ACE_Overlay.pm:146 lib/RT/ACE_Overlay.pm:223 lib/RT/ACE_Overlay.pm:306 lib/RT/ACE_Overlay.pm:898
+msgid "System error. Right not granted."
+msgstr "Erro do sistema. Direito de acesso não outorgado."
+
+#: NOT FOUND IN SOURCE
+msgid "System error. Unable to grant rights."
+msgstr "Erro de sistema.  Não posso outorgar direitos de acesso."
+
+#: html/Admin/Global/GroupRights.html:35 html/Admin/Groups/GroupRights.html:37 html/Admin/Queues/GroupRights.html:36
+msgid "System groups"
+msgstr "Grupos do sistema"
+
+#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53
+msgid "SystemRolegroup for internal use"
+msgstr "SystemRolegroup para uso interno"
+
+#: lib/RT/CurrentUser.pm:320
+msgid "TEST_STRING"
+msgstr "TEST_STRING"
+
+#: html/Ticket/Elements/Tabs:143
+msgid "Take"
+msgstr "Tomar"
+
+#: lib/RT/Transaction_Overlay.pm:575
+msgid "Taken"
+msgstr "Tomado"
+
+#: html/Admin/Elements/EditScrip:81
+msgid "Template"
+msgstr "Modelo"
+
+#: html/Admin/Global/Template.html:91 html/Admin/Queues/Template.html:90
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr "Esquema #%1"
+
+#: html/Admin/Elements/EditTemplates:89
+msgid "Template deleted"
+msgstr "Esquema removido"
+
+#: lib/RT/Scrip_Overlay.pm:153
+msgid "Template not found"
+msgstr "Modelo não encontrado"
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr "Modelo não encontrado\\n"
+
+#: lib/RT/Template_Overlay.pm:347
+msgid "Template parsed"
+msgstr "Modelo processado"
+
+#: html/Admin/Elements/QueueTabs:49 html/Admin/Elements/SystemTabs:36 html/Admin/Global/index.html:45
+msgid "Templates"
+msgstr "Modelos"
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr "Modelos de %1\\n"
+
+#: lib/RT/Interface/Web.pm:858
+msgid "That is already the current value"
+msgstr "Este já é o valor atual"
+
+#: lib/RT/CustomField_Overlay.pm:178
+msgid "That is not a value for this custom field"
+msgstr "Este não é um valor para este campo personalizado"
+
+#: lib/RT/Ticket_Overlay.pm:1886
+msgid "That is the same value"
+msgstr "Este é o mesmo valor"
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr "Este principal já é um %1 para esta fila"
+
+#: lib/RT/Ticket_Overlay.pm:1434
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr "Este principal já é um %1 para este tíquete"
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr "Este principal não é um %1 para esta fila"
+
+#: lib/RT/Ticket_Overlay.pm:1551
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr "Este principal não é um %1 para este tíquete"
+
+#: lib/RT/Ticket_Overlay.pm:1882
+msgid "That queue does not exist"
+msgstr "Esta fila não existe"
+
+#: lib/RT/Ticket_Overlay.pm:3143
+msgid "That ticket has unresolved dependencies"
+msgstr "Este tíquete tem dependências não resolvidas"
+
+#: lib/RT/ACE_Overlay.pm:288 lib/RT/ACE_Overlay.pm:597
+msgid "That user already has that right"
+msgstr "Este usuário já tem este direito de acesso"
+
+#: lib/RT/Ticket_Overlay.pm:2952
+msgid "That user already owns that ticket"
+msgstr "Este usuário já possui este tíquete"
+
+#: lib/RT/Ticket_Overlay.pm:2918
+msgid "That user does not exist"
+msgstr "Este usuário não existe"
+
+#: lib/RT/User_Overlay.pm:315
+msgid "That user is already privileged"
+msgstr "Este usuário já tem privilégios"
+
+#: lib/RT/User_Overlay.pm:332
+msgid "That user is already unprivileged"
+msgstr "Este usuário já não tem privilégios"
+
+#: lib/RT/User_Overlay.pm:327
+msgid "That user is now privileged"
+msgstr "Este usuário agora tem privilégios"
+
+#: lib/RT/User_Overlay.pm:344
+msgid "That user is now unprivileged"
+msgstr "Este usuário agora não tem privilégios"
+
+#: NOT FOUND IN SOURCE
+msgid "That user is now unprivilegedileged"
+msgstr "Este usuário agora é não privilegiado"
+
+#: lib/RT/Ticket_Overlay.pm:2944
+msgid "That user may not own tickets in that queue"
+msgstr "Este usuário não pode possuir tíquetes nesta fila"
+
+#: lib/RT/Link_Overlay.pm:206
+msgid "That's not a numerical id"
+msgstr "Este não é um identificador numérico"
+
+#: html/Ticket/Create.html:150 html/Ticket/Elements/ShowSummary:28
+msgid "The Basics"
+msgstr "Sumário"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The CC of a ticket"
+msgstr "O CC de um tíquete"
+
+#: lib/RT/ACE_Overlay.pm:89
+msgid "The administrative CC of a ticket"
+msgstr "O CC administrativo de um tíquete"
+
+#: lib/RT/Ticket_Overlay.pm:2213
+msgid "The comment has been recorded"
+msgstr "O comentário foi registrado"
+
+#: bin/rt-crontool:198
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr "O seguinte comando procurará por todos os tíquetes ativos na fila 'geral' e alterar sua prioridade para 99 se eles não tiverem sido alterados em 4 horas:"
+
+#: bin/rt-commit-handler:756 bin/rt-commit-handler:766
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr "Os seguintes comandos não foram processados:\\n\\n"
+
+#: lib/RT/Interface/Web.pm:861
+msgid "The new value has been set."
+msgstr "O novo valor foi atribuído."
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The owner of a ticket"
+msgstr "O proprietário de um tíquete"
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The requestor of a ticket"
+msgstr "O requisitante de um tíquete"
+
+#: html/Admin/Elements/EditUserComments:26
+msgid "These comments aren't generally visible to the user"
+msgstr "Estes comandos geralmente não estão visíveis para o usuário"
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr "Este tíquete %1 %2 (%3)\\n"
+
+#: bin/rt-crontool:189
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr "Esta ferramenta permite o usuário invocar módulos Perl arbitrários de dentro do RT."
+
+#: lib/RT/Transaction_Overlay.pm:253
+msgid "This transaction appears to have no content"
+msgstr "Parece que esta transação não tem conteúdo"
+
+#: html/Ticket/Elements/ShowRequestor:47
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr "Os %1 tíquetes mais prioritários deste usuário"
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr "Os 25 tíquetes de mais alta prioridade deste usuário"
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "Qui."
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket"
+msgstr "Tíquete"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr "Tíquete # %1  %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1 Jumbo update: %2"
+msgstr "Tíquete # %1 atualização jumbo: %2"
+
+#: html/Ticket/ModifyAll.html:25 html/Ticket/ModifyAll.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "Tíquete #%1 Atualização jumbo: %2"
+
+#: html/Approvals/Elements/ShowDependency:46
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr "Tíquete #%1: %2"
+
+#: lib/RT/Ticket_Overlay.pm:608
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr "Tíquete %1 criado na fila '%2'"
+
+#: bin/rt-commit-handler:760
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr "Tíquete %1 carregado\\n"
+
+#: html/Search/Bulk.html:181
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr "Tíquete %1: %2"
+
+#: html/Ticket/History.html:25 html/Ticket/History.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr "Histórico do Tíquete # %1 %2"
+
+#: html/SelfService/Display.html:34
+msgid "Ticket Id"
+msgstr "Identificador do tíquete"
+
+#: etc/initialdata:303
+msgid "Ticket Resolved"
+msgstr "Tíquete Resolvido"
+
+#: html/Search/Elements/PickRestriction:63
+msgid "Ticket attachment"
+msgstr "Arquivo anexo do tíquete"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr "Conteúdo do tíquete"
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr "Tipo do conteúdo do tíquete"
+
+#: lib/RT/Ticket_Overlay.pm:495 lib/RT/Ticket_Overlay.pm:597
+msgid "Ticket could not be created due to an internal error"
+msgstr "O tíquete não pôde ser criado devido a um erro interno"
+
+#: lib/RT/Transaction_Overlay.pm:522
+msgid "Ticket created"
+msgstr "Tíquete criado"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr "A criação do tíquete falhou"
+
+#: lib/RT/Transaction_Overlay.pm:527
+msgid "Ticket deleted"
+msgstr "Tíquete removido"
+
+#: html/REST/1.0/modify:29 html/REST/1.0/update:34
+msgid "Ticket id not found"
+msgstr "Id de tíquete não encontrado"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket killed"
+msgstr "Tíquete destruído"
+
+#: html/REST/1.0/modify:36 html/REST/1.0/update:41
+msgid "Ticket not found"
+msgstr "Tíquete não encontrado"
+
+#: etc/initialdata:289
+msgid "Ticket status changed"
+msgstr "O estado do tíquete mudou"
+
+#: html/Ticket/Update.html:39
+msgid "Ticket watchers"
+msgstr "Observadores do tíquete"
+
+#: html/Elements/Tabs:49
+msgid "Tickets"
+msgstr "Tíquetes"
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr "Tíquetes %1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr "Tíquetes %1 por %2"
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Tickets from %1"
+msgstr "Tíquetes de %1"
+
+#: html/Approvals/Elements/ShowDependency:27
+msgid "Tickets which depend on this approval:"
+msgstr "Tíquetes dependentes desta aprovação:"
+
+#: html/Ticket/Create.html:157 html/Ticket/Elements/EditBasics:48
+msgid "Time Left"
+msgstr "Tempo Restante"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:43
+msgid "Time Worked"
+msgstr "Tempo Trabalhado"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "Tempo restante"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "Tempo de apresentação"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "Tempo trabalhado"
+
+#: NOT FOUND IN SOURCE
+msgid "TimeLeft"
+msgstr "TimeLeft"
+
+#: lib/RT/Ticket_Overlay.pm:1165
+msgid "TimeWorked"
+msgstr "TimeWorked"
+
+#: bin/rt-commit-handler:402
+msgid "To generate a diff of this commit:"
+msgstr "Para gerar as diferenças desta transação"
+
+#: bin/rt-commit-handler:391
+msgid "To generate a diff of this commit:\\n"
+msgstr "Para gerar as diferenças desta transação:\\n"
+
+#: lib/RT/Ticket_Overlay.pm:1168
+msgid "Told"
+msgstr "Última atualização"
+
+#: etc/initialdata:237
+msgid "Transaction"
+msgstr "Transação"
+
+#: lib/RT/Transaction_Overlay.pm:642
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr "Transação %1 removida"
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr "Transação Criada"
+
+#: lib/RT/Transaction_Overlay.pm:89
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr "Transaction->Create não pôde, já que você não especificou um id de tíquete"
+
+#: lib/RT/Transaction_Overlay.pm:701
+msgid "Transactions are immutable"
+msgstr "Transações são imutáveis"
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr "Tentando remover um direito de acesso: %1"
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "Ter."
+
+#: html/Admin/Elements/EditCustomField:34 html/Ticket/Elements/AddWatchers:33 html/Ticket/Elements/AddWatchers:44 html/Ticket/Elements/AddWatchers:54 lib/RT/Ticket_Overlay.pm:1166 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "Tipo"
+
+#: lib/RT/ScripCondition_Overlay.pm:104
+msgid "Unimplemented"
+msgstr "Não implementado"
+
+#: html/Admin/Users/Modify.html:68
+msgid "Unix login"
+msgstr "Usuário Unix"
+
+#: html/Admin/Elements/ModifyUser:62
+msgid "UnixUsername"
+msgstr "Usuário Unix"
+
+#: lib/RT/Attachment_Overlay.pm:265
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr "Codificação de conteúdo desconhecida %1"
+
+#: html/Elements/SelectResultsPerPage:37
+msgid "Unlimited"
+msgstr "Ilimitado"
+
+#: etc/initialdata:32
+msgid "Unprivileged"
+msgstr "Não privilegiado"
+
+#: lib/RT/Transaction_Overlay.pm:571
+msgid "Untaken"
+msgstr "Não tomado"
+
+#: html/Elements/MyTickets:64 html/Search/Bulk.html:33
+msgid "Update"
+msgstr "Atualizar"
+
+#: html/Admin/Users/Prefs.html:62
+msgid "Update ID"
+msgstr "Identificador de atualização"
+
+#: html/Search/Bulk.html:120 html/Ticket/ModifyAll.html:66 html/Ticket/Update.html:67
+msgid "Update Type"
+msgstr "Tipo de atualização"
+
+#: html/Search/Listing.html:61
+msgid "Update all these tickets at once"
+msgstr "Atualizar todos estes tíquetes de uma vez"
+
+#: html/Admin/Users/Prefs.html:49
+msgid "Update email"
+msgstr "Atualizar email"
+
+#: html/Admin/Users/Prefs.html:55
+msgid "Update name"
+msgstr "Atualizar nome"
+
+#: lib/RT/Interface/Web.pm:375
+msgid "Update not recorded."
+msgstr "Atualização não registrada."
+
+#: html/Search/Bulk.html:81
+msgid "Update selected tickets"
+msgstr "Atualizar os tíquetes selecionados"
+
+#: html/Admin/Users/Prefs.html:36
+msgid "Update signature"
+msgstr "Atualizar assinatura"
+
+#: html/Ticket/ModifyAll.html:63
+msgid "Update ticket"
+msgstr "Atualizar o tíquete"
+
+#: html/SelfService/Update.html:25 html/SelfService/Update.html:27
+#. ($Ticket->id)
+msgid "Update ticket # %1"
+msgstr "Atualizar o tíquete # %1"
+
+#: html/SelfService/Update.html:50
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr "Atualizar o tíquete #%1"
+
+#: html/Ticket/Update.html:135
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr "Atualizar tíquete #%1 (%2)"
+
+#: lib/RT/Interface/Web.pm:373
+msgid "Update type was neither correspondence nor comment."
+msgstr "O tipo da atualização não foi nem correspondência e nem comentário."
+
+#: html/Elements/SelectDateType:33 html/Ticket/Elements/ShowDates:51 lib/RT/Ticket_Overlay.pm:1169
+msgid "Updated"
+msgstr "Atualizado"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr "Usuário %1 %2: %3\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr "Usuário %1 Senha: %2\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr "Usuário '%1' não encontrado"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr "Usuário '%1' não encontrado\\n"
+
+#: etc/initialdata:125 etc/initialdata:191
+msgid "User Defined"
+msgstr "Definido pelo Usuário"
+
+#: html/Admin/Users/Prefs.html:59
+msgid "User ID"
+msgstr "Identificador de usuário"
+
+#: html/Elements/SelectUsers:26
+msgid "User Id"
+msgstr "Identificador do usuário"
+
+#: html/Admin/Elements/GroupTabs:47 html/Admin/Elements/QueueTabs:60 html/Admin/Elements/SystemTabs:47 html/Admin/Global/index.html:59
+msgid "User Rights"
+msgstr "Direitos de Acesso de Usuário"
+
+#: html/Admin/Users/Modify.html:226
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr "O usuário não pôde ser criado: %1"
+
+#: lib/RT/User_Overlay.pm:262
+msgid "User created"
+msgstr "Usuário criado"
+
+#: html/Admin/Global/GroupRights.html:67 html/Admin/Groups/GroupRights.html:54 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr "Grupos definidos pelo usuário"
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr "Usuário notificado"
+
+#: html/Admin/Users/Prefs.html:25 html/Admin/Users/Prefs.html:29
+msgid "User view"
+msgstr "Visualização de usuário"
+
+#: html/Admin/Users/Modify.html:48 html/Elements/Login:42 html/Ticket/Elements/AddWatchers:35
+msgid "Username"
+msgstr "Nome de usuário"
+
+#: html/Admin/Elements/SelectNewGroupMembers:26 html/Admin/Elements/Tabs:32 html/Admin/Groups/Members.html:55 html/Admin/Queues/People.html:68 html/Admin/index.html:29 html/User/Groups/Members.html:58
+msgid "Users"
+msgstr "Usuários"
+
+#: html/Admin/Users/index.html:65
+msgid "Users matching search criteria"
+msgstr "Usuários que satisfazem o critério de busca"
+
+#: html/Search/Elements/PickRestriction:51
+msgid "ValueOfQueue"
+msgstr "Valor da fila"
+
+#: html/Admin/Elements/EditCustomField:40
+msgid "Values"
+msgstr "Valores"
+
+#: NOT FOUND IN SOURCE
+msgid "VrijevormEnkele"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Watch"
+msgstr "Observar"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "WatchAsAdminCc"
+msgstr "WatchAsAdminCc"
+
+#: NOT FOUND IN SOURCE
+msgid "Watcher loaded"
+msgstr "Observador carregado"
+
+#: html/Admin/Elements/QueueTabs:42
+msgid "Watchers"
+msgstr "Observadores"
+
+#: html/Admin/Elements/ModifyUser:56
+msgid "WebEncoding"
+msgstr "Codificação de Web"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "Qua."
+
+#: etc/upgrade/2.1.71:161
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr "Quando um tíquete for aprovado por todos os aprovadores, adicione uma correspondência ao tíquete original"
+
+#: etc/upgrade/2.1.71:135
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr "Quando um tíquete for aprovado por qualquer aprovador, adicione uma correspondência ao tíquete original"
+
+#: etc/initialdata:138
+msgid "When a ticket is created"
+msgstr "Quando um tíquete é criado"
+
+#: etc/upgrade/2.1.71:79
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr "Quando um tíquete de aprovação é criado, notificar o Proprietário e o AdminCc do item aguardando sua aprovação"
+
+#: etc/initialdata:143
+msgid "When anything happens"
+msgstr "Quando acontecer qualquer coisa"
+
+#: etc/initialdata:184
+msgid "Whenever a ticket is resolved"
+msgstr "Sempre que um tíquete for resolvido"
+
+#: etc/initialdata:170
+msgid "Whenever a ticket's owner changes"
+msgstr "Sempre que mudar o proprietário de um tíquete"
+
+#: etc/initialdata:178
+msgid "Whenever a ticket's queue changes"
+msgstr "Sempre que um tíquete mudar de fila"
+
+#: etc/initialdata:162
+msgid "Whenever a ticket's status changes"
+msgstr "Sempre que o estado de um tíquete mudar"
+
+#: etc/initialdata:192
+msgid "Whenever a user-defined condition occurs"
+msgstr "Sempre que ocorrer uma condição definida por usuário"
+
+#: etc/initialdata:156
+msgid "Whenever comments come in"
+msgstr "Sempre que um novo comentário é adicionado"
+
+#: etc/initialdata:149
+msgid "Whenever correspondence comes in"
+msgstr "Sempre que uma nova correspondência é adicionada"
+
+#: html/Admin/Users/Modify.html:164 html/User/Prefs.html:52
+msgid "Work"
+msgstr "Trabalho"
+
+#: html/Admin/Elements/ModifyUser:70
+msgid "WorkPhone"
+msgstr "Telefone de trabalho"
+
+#: html/SelfService/Display.html:86 html/Ticket/Elements/ShowBasics:35 html/Ticket/Update.html:65
+msgid "Worked"
+msgstr "Trabalhado"
+
+#: lib/RT/Ticket_Overlay.pm:3056
+msgid "You already own this ticket"
+msgstr "Você já é proprietário deste tíquete"
+
+#: html/autohandler:121
+msgid "You are not an authorized user"
+msgstr "Você não é um usuário autorizado"
+
+#: lib/RT/Ticket_Overlay.pm:2930
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "Você só pode reatribuir seus próprios tíquetes ou aqueles que não têm dono"
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr "Você não tem permissão para ver este tíquete.\\n"
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "Você encontrou %1 tíquetes na fila %2"
+
+#: html/NoAuth/Logout.html:31 html/REST/1.0/logout:25
+msgid "You have been logged out of RT."
+msgstr "Você foi desconectado do RT."
+
+#: html/SelfService/Display.html:134
+msgid "You have no permission to create tickets in that queue."
+msgstr "Você não tem permissão para criar tíquetes nesta fila."
+
+#: lib/RT/Ticket_Overlay.pm:1895
+msgid "You may not create requests in that queue."
+msgstr "Você não pode criar requisições nesta fila."
+
+#: html/NoAuth/Logout.html:36
+msgid "You're welcome to login again"
+msgstr "Volte sempre"
+
+#: html/SelfService/Elements/MyRequests:25
+#. ($friendly_status)
+msgid "Your %1 requests"
+msgstr "Suas %1 requisições"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr "Seu administrador do RT configurou erradamente os endereços eletrônicos que invocam o RT"
+
+#: etc/initialdata:429 etc/upgrade/2.1.71:146
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr "Sua requisição foi aprovada por %1.  Outras aprovações ainda podem estar pendentes."
+
+#: etc/initialdata:463 etc/upgrade/2.1.71:180
+msgid "Your request has been approved."
+msgstr "Sua requisição foi aprovada."
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr "Sua requisição foi rejeitada"
+
+#: etc/initialdata:384 etc/upgrade/2.1.71:101
+msgid "Your request was rejected."
+msgstr "Sua requisição foi rejeitada."
+
+#: html/autohandler:136 html/autohandler:142
+msgid "Your username or password is incorrect"
+msgstr "Nome de usuário ou senha incorretos"
+
+#: html/Admin/Elements/ModifyUser:84 html/Admin/Users/Modify.html:144 html/User/Prefs.html:96
+msgid "Zip"
+msgstr "CEP"
+
+#: NOT FOUND IN SOURCE
+msgid "[no subject]"
+msgstr "[sem assunto]"
+
+#: html/User/Elements/DelegateRights:59
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "como outorgado a %1"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:34
+msgid "contains"
+msgstr "contém"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content"
+msgstr "content"
+
+#: html/Elements/SelectAttachmentField:27
+msgid "content-type"
+msgstr "content-type"
+
+#: lib/RT/Ticket_Overlay.pm:2282
+msgid "correspondence (probably) not sent"
+msgstr "correspondência (provavelmente) não enviada"
+
+#: lib/RT/Ticket_Overlay.pm:2292
+msgid "correspondence sent"
+msgstr "correspondência enviada"
+
+#: html/Admin/Elements/ModifyQueue:63 html/Admin/Queues/Modify.html:77 lib/RT/Date.pm:319
+msgid "days"
+msgstr "dias"
+
+#: NOT FOUND IN SOURCE
+msgid "dead"
+msgstr "morto"
+
+#: html/Search/Listing.html:75
+msgid "delete"
+msgstr "remover"
+
+#: lib/RT/Queue_Overlay.pm:63
+msgid "deleted"
+msgstr "removido"
+
+#: html/Search/Elements/PickRestriction:68
+msgid "does not match"
+msgstr "não satisfaz"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:35
+msgid "doesn't contain"
+msgstr "não contém"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "equal to"
+msgstr "igual a"
+
+#: NOT FOUND IN SOURCE
+msgid "false"
+msgstr "falso"
+
+#: html/Elements/SelectAttachmentField:28
+msgid "filename"
+msgstr "filename"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "greater than"
+msgstr "maior que"
+
+#: lib/RT/Group_Overlay.pm:194
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "grupo '%1'"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "horas"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr "identificador"
+
+#: html/Elements/SelectBoolean:32 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88
+msgid "is"
+msgstr "é"
+
+#: html/Elements/SelectBoolean:36 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:37 html/Search/Elements/PickRestriction:48 html/Search/Elements/PickRestriction:77 html/Search/Elements/PickRestriction:89
+msgid "isn't"
+msgstr "não é"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "less than"
+msgstr "menor que"
+
+#: html/Search/Elements/PickRestriction:67
+msgid "matches"
+msgstr "satisfaz"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "min"
+
+#: html/Ticket/Update.html:66
+msgid "minutes"
+msgstr "minutos"
+
+#: bin/rt-commit-handler:765
+msgid "modifications\\n\\n"
+msgstr "modificações\\n\\n"
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "meses"
+
+#: lib/RT/Queue_Overlay.pm:58
+msgid "new"
+msgstr "novo"
+
+#: html/Admin/Elements/EditScrips:43
+msgid "no value"
+msgstr "sem valor"
+
+#: html/Ticket/Elements/EditWatchers:28
+msgid "none"
+msgstr "nenhum"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "not equal to"
+msgstr "diferente de"
+
+#: NOT FOUND IN SOURCE
+msgid "notlike"
+msgstr "diferente"
+
+#: lib/RT/Queue_Overlay.pm:59
+msgid "open"
+msgstr "aberto"
+
+#: lib/RT/Group_Overlay.pm:199
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr "grupo pessoal '%1' para o usuário '%2'"
+
+#: lib/RT/Group_Overlay.pm:207
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr "fila %1 %2"
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "rejected"
+msgstr "rejeitado"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "resolved"
+msgstr "resolvido"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr "seg"
+
+#: lib/RT/Queue_Overlay.pm:60
+msgid "stalled"
+msgstr "pendente"
+
+#: lib/RT/Group_Overlay.pm:202
+#. ($self->Type)
+msgid "system %1"
+msgstr "sistema %1"
+
+#: lib/RT/Group_Overlay.pm:213
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr "grupo do sistema '%1'"
+
+#: html/Elements/Error:42 html/SelfService/Error.html:42
+msgid "the calling component did not specify why"
+msgstr "o componente chamador não especificou por que"
+
+#: lib/RT/Group_Overlay.pm:210
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr "tíquete #%1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "true"
+msgstr "verdadeiro"
+
+#: lib/RT/Group_Overlay.pm:216
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr "grupo %1 não descrito"
+
+#: NOT FOUND IN SOURCE
+msgid "undescripbed group %1"
+msgstr "grupo sem descrição %1"
+
+#: lib/RT/Group_Overlay.pm:191
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr "usuário %1"
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr "semanas"
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr "com modelo %1"
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr "anos"
+
+#: NOT FOUND IN SOURCE
+msgid "ニックネーム"
+msgstr ""
+
diff --git a/rt/lib/RT/I18N/ru.po b/rt/lib/RT/I18N/ru.po
new file mode 100644 (file)
index 0000000..eb14346
--- /dev/null
@@ -0,0 +1,4826 @@
+msgid ""
+msgstr ""
+"Last-Translator: Kirill Pushkin <kirill@mns.ru>\n"
+"PO-Revision-Date: 2002-10-04 19:28+0400\n"
+"Language-Team: Russian <ru@li.org>\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 0.9.6\n"
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28
+msgid "#"
+msgstr "&#8470;"
+
+#: html/Admin/Queues/Scrip.html:55
+#. ($QueueObj->id)
+msgid "#%1"
+msgstr ""
+
+#: html/Approvals/Elements/ShowDependency:50 html/Ticket/Display.html:26 html/Ticket/Display.html:30
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr ""
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr ""
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr "%1 %2 %3 %4:%5:%6 %7"
+
+#: lib/RT/Ticket_Overlay.pm:3438 lib/RT/Transaction_Overlay.pm:559 lib/RT/Transaction_Overlay.pm:601
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 added"
+msgstr ""
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 %2 ago"
+msgstr "%1 %2 назад"
+
+#: lib/RT/Ticket_Overlay.pm:3444 lib/RT/Transaction_Overlay.pm:566
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 changed to %3"
+msgstr "%1 %2 изменено на %3"
+
+#: lib/RT/Ticket_Overlay.pm:3441 lib/RT/Transaction_Overlay.pm:562 lib/RT/Transaction_Overlay.pm:607
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 deleted"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 %2 of group %3"
+msgstr ""
+
+#: html/Admin/Elements/EditScrips:44 html/Admin/Elements/ListGlobalScrips:28
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 with template %3"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 this ticket\\n"
+msgstr "%1 (%2) %3 этот тикет\\n"
+
+#: html/Search/Listing.html:57
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr ""
+
+#: bin/rt-crontool:169 bin/rt-crontool:176 bin/rt-crontool:182
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - An argument to pass to %2"
+msgstr ""
+
+#: bin/rt-crontool:185
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr ""
+
+#: bin/rt-crontool:179
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr ""
+
+#: bin/rt-crontool:173
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr ""
+
+#: bin/rt-crontool:166
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr ""
+
+#: lib/RT/ScripAction_Overlay.pm:122
+#. ($self->Id)
+msgid "%1 ScripAction loaded"
+msgstr "%1 скрипт загружен"
+
+#: lib/RT/Ticket_Overlay.pm:3471
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 added as a value for %2"
+msgstr "%1 добавлено как значение для %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on"
+msgstr "%1 алиасы требуют идентификатор тикета для продолжения работы"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on "
+msgstr "%1 алиасы требуют идентификатор тикета для продолжения работы "
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on (from %2) %3"
+msgstr "%1 алиасы требуют идентификатор тикета для продолжения работы над (от %2) %3"
+
+#: lib/RT/Link_Overlay.pm:117 lib/RT/Link_Overlay.pm:124
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 appears to be a local object, but can't be found in the database"
+msgstr ""
+
+#: html/Ticket/Elements/ShowDates:52 lib/RT/Transaction_Overlay.pm:483
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 by %2"
+msgstr "%1 пользователем %2"
+
+#: lib/RT/Transaction_Overlay.pm:537 lib/RT/Transaction_Overlay.pm:626 lib/RT/Transaction_Overlay.pm:635 lib/RT/Transaction_Overlay.pm:638
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 changed from %2 to %3"
+msgstr "%1 изменилось с %2 на %3"
+
+#: lib/RT/Interface/Web.pm:857
+msgid "%1 could not be set to %2."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2813
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr "%1 не могу закрыть тикет. Возможно, база данных RT испорчена."
+
+#: html/Elements/MyTickets:25
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr ""
+
+#: html/Elements/MyRequests:25
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr ""
+
+#: bin/rt-crontool:161
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr "%1 больше не является %2 для этой очереди."
+
+#: lib/RT/Ticket_Overlay.pm:1570
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr "%1 больше не является %2 для этого тикета."
+
+#: lib/RT/Ticket_Overlay.pm:3527
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr "%1 больше не является значением для нестандартного поля %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr ""
+
+#: html/Ticket/Elements/ShowBasics:36
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr "%1 мин"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr "%1 не отображается"
+
+#: html/User/Elements/DelegateRights:76
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr "%1 успешно произведено\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr "%1 тип не известен для $MessageId"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr "%1 тип не известен для %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 was created without a CurrentUser\\n"
+msgstr ""
+
+#: lib/RT/Action/ResolveMembers.pm:42
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr "%1 закроет все тикеты, входящие в групповой запрос"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr "%1 отложит тикеты, которые зависят запроса или включены в него"
+
+#: lib/RT/Transaction_Overlay.pm:435
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr "%1: без вложений"
+
+#: html/Ticket/Elements/ShowTransaction:102
+#. ($size)
+msgid "%1b"
+msgstr ""
+
+#: html/Ticket/Elements/ShowTransaction:99
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1140
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr "'%1' является неверным значением статуса"
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr "Что делать ? : '%1'"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete group member)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr ""
+
+#: html/Admin/Elements/EditQueueWatchers:29 html/Admin/Elements/EditScrips:35 html/Admin/Elements/EditTemplates:36 html/Admin/Groups/Members.html:52 html/Ticket/Elements/EditLinks:33 html/Ticket/Elements/EditPeople:46 html/User/Groups/Members.html:55
+msgid "(Check box to delete)"
+msgstr "(Пометьте то, что хотите удалить)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check boxes to delete)"
+msgstr ""
+
+#: html/Ticket/Create.html:178
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr "(Введите номера или ссылки на тикеты. Несколько тикетов разделяются пробелами.)"
+
+#: html/Admin/Queues/Modify.html:54 html/Admin/Queues/Modify.html:60
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(No Value)"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:33 html/Admin/Elements/ListGlobalCustomFields:32
+msgid "(No custom fields)"
+msgstr ""
+
+#: html/Admin/Groups/Members.html:50 html/User/Groups/Members.html:53
+msgid "(No members)"
+msgstr "(Нет пользователей)"
+
+#: html/Admin/Elements/EditScrips:32 html/Admin/Elements/ListGlobalScrips:32
+msgid "(No scrips)"
+msgstr "(Нет скриптов)"
+
+#: html/Admin/Elements/EditTemplates:31
+msgid "(No templates)"
+msgstr ""
+
+#: html/Ticket/Update.html:85
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(На эти адреса [разделенные запятой] отправляются копии сообщения. Список этих адресатов в письме не виден. Адреса <b>не</b> сохраняются для последующих уведомлений.)"
+
+#: html/Ticket/Create.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr ""
+
+#: html/Ticket/Update.html:81
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(На эти адреса [разделенные запятой] отправляются копии сообщения. Адреса не сохраняются для последующих уведомлений.)"
+
+#: html/Ticket/Create.html:69
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr ""
+
+#: html/Admin/Groups/index.html:33 html/User/Groups/index.html:33
+msgid "(empty)"
+msgstr "(пусто)"
+
+#: html/Admin/Users/index.html:39
+msgid "(no name listed)"
+msgstr ""
+
+#: html/Elements/MyRequests:43 html/Elements/MyTickets:45
+msgid "(no subject)"
+msgstr "(без темы)"
+
+#: html/Admin/Elements/SelectRights:48 html/Elements/SelectCustomFieldValue:30 html/Ticket/Elements/EditCustomField:59 html/Ticket/Elements/ShowCustomFields:36 lib/RT/Transaction_Overlay.pm:536
+msgid "(no value)"
+msgstr "(нет значения)"
+
+#: html/Ticket/Elements/EditLinks:116
+msgid "(only one ticket)"
+msgstr "(только один тикет)"
+
+#: html/Elements/MyRequests:52 html/Elements/MyTickets:55
+msgid "(pending approval)"
+msgstr ""
+
+#: html/Elements/MyRequests:54 html/Elements/MyTickets:57
+msgid "(pending other tickets)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "(requestor's group)"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:50
+msgid "(required)"
+msgstr "(требуется)"
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "(untitled)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I own..."
+msgstr "25 важнейших моих тикетов..."
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I requested..."
+msgstr "25 самых важных моих запросов..."
+
+#: html/Ticket/Elements/ShowBasics:32
+msgid "<% $Ticket->Status%>"
+msgstr "<% $Ticket->Status%>"
+
+#: html/Elements/SelectTicketTypes:27
+msgid "<% $_ %>"
+msgstr ""
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:26
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"Создать тикет в очереди\">&nbsp;%1"
+
+#: NOT FOUND IN SOURCE
+msgid "??????"
+msgstr ""
+
+#: etc/initialdata:203
+msgid "A blank template"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Deleted"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Loaded"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be deleted"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be found"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:157 lib/RT/Principal_Overlay.pm:181
+msgid "ACE not found"
+msgstr "ACE не найден"
+
+#: lib/RT/ACE_Overlay.pm:831
+msgid "ACEs can only be created and deleted."
+msgstr "ACEы можно только создавать и удалять"
+
+#: bin/rt-commit-handler:755
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr "Прекращаем работу во избежание нежелательного изменения тикета.\\n"
+
+#: html/User/Elements/Tabs:32
+msgid "About me"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:80
+msgid "Access control"
+msgstr "Права доступа"
+
+#: html/Admin/Elements/EditScrip:57
+msgid "Action"
+msgstr "Действие"
+
+#: lib/RT/Scrip_Overlay.pm:147
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr ""
+
+#: bin/rt-crontool:123
+msgid "Action committed."
+msgstr "Действие принято."
+
+#: bin/rt-crontool:119
+msgid "Action prepared..."
+msgstr "Действие подготовлено..."
+
+#: html/Search/Bulk.html:92
+msgid "Add AdminCc"
+msgstr "Добавить административную копию"
+
+#: html/Search/Bulk.html:90
+msgid "Add Cc"
+msgstr "Добавить копию"
+
+#: html/Ticket/Create.html:114 html/Ticket/Update.html:100
+msgid "Add More Files"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add Next State"
+msgstr ""
+
+#: html/Search/Bulk.html:88
+msgid "Add Requestor"
+msgstr "Добавить просителя"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip to this queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip which will apply to all queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a keyword selection to this queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr ""
+
+#: html/Admin/Global/Scrip.html:55
+msgid "Add a scrip which will apply to all queues"
+msgstr "Добавить скрипт, который будет действовать на все очереди"
+
+#: html/Search/Bulk.html:118
+msgid "Add comments or replies to selected tickets"
+msgstr "Добавить комментарии или ответы на выбранные тикеты"
+
+#: html/Admin/Groups/Members.html:42 html/User/Groups/Members.html:39
+msgid "Add members"
+msgstr "Добавить пользователей"
+
+#: html/Admin/Queues/People.html:66 html/Ticket/Elements/AddWatchers:28
+msgid "Add new watchers"
+msgstr "Добавить наблюдателей"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr "Добавить пользователя как %1 для этой очереди"
+
+#: lib/RT/Ticket_Overlay.pm:1454
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr "Добавить пользователя как %1 для этого тикета"
+
+#: html/Admin/Elements/ModifyUser:76 html/Admin/Users/Modify.html:122 html/User/Prefs.html:88
+msgid "Address1"
+msgstr "Адрес1"
+
+#: html/Admin/Elements/ModifyUser:78 html/Admin/Users/Modify.html:127 html/User/Prefs.html:90
+msgid "Address2"
+msgstr "Адрес2"
+
+#: html/Ticket/Create.html:74
+msgid "Admin Cc"
+msgstr "Административная копия"
+
+#: etc/initialdata:274
+msgid "Admin Comment"
+msgstr ""
+
+#: etc/initialdata:256
+msgid "Admin Correspondence"
+msgstr ""
+
+#: html/Admin/Queues/index.html:25 html/Admin/Queues/index.html:28
+msgid "Admin queues"
+msgstr "Управление очередями"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr "Управление пользователями"
+
+#: html/Admin/Global/index.html:26 html/Admin/Global/index.html:28
+msgid "Admin/Global configuration"
+msgstr "Общие настройки"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr "Группы"
+
+#: html/Admin/Queues/Modify.html:25 html/Admin/Queues/Modify.html:29
+msgid "Admin/Queue/Basics"
+msgstr "Параметры очереди"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr ""
+
+#: etc/initialdata:56 html/Ticket/Elements/ShowPeople:39 html/Ticket/Update.html:50 lib/RT/ACE_Overlay.pm:89
+msgid "AdminCc"
+msgstr "Административная копия"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "AdminCustomFields"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "AdminGroup"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "AdminGroupMembership"
+msgstr ""
+
+#: lib/RT/System.pm:59
+msgid "AdminOwnPersonalGroups"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "AdminQueue"
+msgstr ""
+
+#: lib/RT/System.pm:60
+msgid "AdminUsers"
+msgstr ""
+
+#: html/Admin/Queues/People.html:48 html/Ticket/Elements/EditPeople:54
+msgid "Administrative Cc"
+msgstr "Административная копия"
+
+#: NOT FOUND IN SOURCE
+msgid "Admins"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr ""
+
+#: html/Elements/SelectDateRelation:36
+msgid "After"
+msgstr "После"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Alias"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Alias for"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:96
+msgid "All Custom Fields"
+msgstr ""
+
+#: html/Admin/Queues/index.html:53
+msgid "All Queues"
+msgstr "Все очереди"
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr ""
+
+#: html/Elements/Tabs:58
+msgid "Approval"
+msgstr ""
+
+#: html/Approvals/Display.html:46 html/Approvals/Elements/Approve:27 html/Approvals/Elements/ShowDependency:42 html/Approvals/index.html:65
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr "Виза #%1: %2"
+
+#: html/Approvals/index.html:54
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr "Виза #%1: Примечания не сохранены из-за ошибки системы"
+
+#: html/Approvals/index.html:52
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr "Виза #%1: Примечания записаны"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Details"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Approval diagram"
+msgstr ""
+
+#: html/Approvals/Elements/Approve:45
+msgid "Approve"
+msgstr "Завизировать"
+
+#: etc/initialdata:431 etc/upgrade/2.1.71:148
+msgid "Approver's notes: %1"
+msgstr ""
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "Апр."
+
+#: NOT FOUND IN SOURCE
+msgid "April"
+msgstr ""
+
+#: html/Elements/SelectSortOrder:35
+msgid "Ascending"
+msgstr "В порядке возрастания"
+
+#: html/Search/Bulk.html:127 html/SelfService/Update.html:36 html/Ticket/ModifyAll.html:83 html/Ticket/Update.html:100
+msgid "Attach"
+msgstr "Вложение"
+
+#: html/SelfService/Create.html:67 html/Ticket/Create.html:110
+msgid "Attach file"
+msgstr "Вложить файл"
+
+#: html/Ticket/Create.html:98 html/Ticket/Update.html:89
+msgid "Attached file"
+msgstr ""
+
+#: html/SelfService/Attachment/dhandler:36
+msgid "Attachment '%1' could not be loaded"
+msgstr "Вложение '%1' не может быть загружено"
+
+#: lib/RT/Transaction_Overlay.pm:443
+msgid "Attachment created"
+msgstr "Создано вложение"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "Имя файла"
+
+#: html/Ticket/Elements/ShowAttachments:26
+msgid "Attachments"
+msgstr "Вложения"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "Авг."
+
+#: NOT FOUND IN SOURCE
+msgid "August"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:66
+msgid "AuthSystem"
+msgstr "Тип регистрации"
+
+#: etc/initialdata:206
+msgid "Autoreply"
+msgstr ""
+
+#: etc/initialdata:72
+msgid "Autoreply To Requestors"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr "Неправильная подпись PGP: %1\\n"
+
+#: html/SelfService/Attachment/dhandler:40
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr "Неверный идентификатор вложения. Отсутствует вложение '%1'\\n"
+
+#: bin/rt-commit-handler:827
+#. ($val)
+msgid "Bad data in %1"
+msgstr "Неправильная дата в %1"
+
+#: html/SelfService/Attachment/dhandler:43
+#. ($trans, $AttachmentObj->TransactionId())
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr "Неправильный номер транзакции для вложения. %1 должен быть %2\\n"
+
+#: html/Admin/Elements/GroupTabs:39 html/Admin/Elements/QueueTabs:39 html/Admin/Elements/UserTabs:38 html/Ticket/Elements/Tabs:90 html/User/Elements/GroupTabs:38
+msgid "Basics"
+msgstr "Главное"
+
+#: html/Ticket/Update.html:83
+msgid "Bcc"
+msgstr "Скрытая копия"
+
+#: html/Admin/Elements/EditScrip:88 html/Admin/Global/GroupRights.html:85 html/Admin/Global/Template.html:46 html/Admin/Global/UserRights.html:54 html/Admin/Groups/GroupRights.html:73 html/Admin/Groups/Members.html:81 html/Admin/Groups/Modify.html:56 html/Admin/Groups/UserRights.html:55 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:45 html/Admin/Queues/UserRights.html:54 html/User/Groups/Modify.html:56
+msgid "Be sure to save your changes"
+msgstr "Не забудьте сохранить настройки"
+
+#: html/Elements/SelectDateRelation:34 lib/RT/CurrentUser.pm:322
+msgid "Before"
+msgstr "До"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin Approval"
+msgstr ""
+
+#: etc/initialdata:202
+msgid "Blank"
+msgstr ""
+
+#: html/Search/Listing.html:79
+msgid "Bookmarkable URL for this search"
+msgstr "Получить URL для этого поиска"
+
+#: html/Ticket/Elements/ShowHistory:39 html/Ticket/Elements/ShowHistory:45
+msgid "Brief headers"
+msgstr "Сокращенный"
+
+#: html/Search/Bulk.html:25 html/Search/Bulk.html:26
+msgid "Bulk ticket update"
+msgstr "Изменение одним махом"
+
+#: lib/RT/User_Overlay.pm:1331
+msgid "Can not modify system users"
+msgstr "Не могу изменять системных пользователей"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Can this principal see this queue"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:144
+msgid "Can't add a custom field value without a name"
+msgstr "Не могу добавить значение поля без имени"
+
+#: lib/RT/Link_Overlay.pm:132
+msgid "Can't link a ticket to itself"
+msgstr "Тикет не может быть связан с самим собой"
+
+#: lib/RT/Ticket_Overlay.pm:2787
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr "Не могу соединить с объединенным тикетом (эта ошибка никогда не должна происходить)."
+
+#: lib/RT/Ticket_Overlay.pm:2605 lib/RT/Ticket_Overlay.pm:2674
+msgid "Can't specifiy both base and target"
+msgstr "Не могу указать одновременно и источник, и адрес назначения"
+
+#: html/autohandler:112
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr "Не могу создать пользователя: %1"
+
+#: etc/initialdata:50 html/Admin/Queues/People.html:44 html/SelfService/Create.html:51 html/SelfService/Display.html:50 html/Ticket/Create.html:64 html/Ticket/Elements/EditPeople:51 html/Ticket/Elements/ShowPeople:35 html/Ticket/Update.html:45 html/Ticket/Update.html:78 lib/RT/ACE_Overlay.pm:88
+msgid "Cc"
+msgstr "Копия"
+
+#: html/SelfService/Prefs.html:31
+msgid "Change password"
+msgstr "Сменить пароль"
+
+#: html/Ticket/Create.html:101 html/Ticket/Update.html:92
+msgid "Check box to delete"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:31
+msgid "Check box to revoke right"
+msgstr "Выберите права, которые хотите отозвать"
+
+#: html/Ticket/Create.html:183 html/Ticket/Elements/EditLinks:131 html/Ticket/Elements/EditLinks:69 html/Ticket/Elements/ShowLinks:51
+msgid "Children"
+msgstr "Потомки"
+
+#: html/Admin/Elements/ModifyUser:80 html/Admin/Users/Modify.html:132 html/User/Prefs.html:92
+msgid "City"
+msgstr "Город"
+
+#: html/Ticket/Elements/ShowDates:47
+msgid "Closed"
+msgstr ""
+
+#: html/SelfService/Elements/Tabs:60
+msgid "Closed requests"
+msgstr "Закрытые запросы"
+
+#: NOT FOUND IN SOURCE
+msgid "Code"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr "Чего-чего?\\n"
+
+#: html/Ticket/Elements/ShowTransaction:179 html/Ticket/Elements/Tabs:153
+msgid "Comment"
+msgstr "Комментировать"
+
+#: html/Admin/Elements/ModifyQueue:45 html/Admin/Queues/Modify.html:58
+msgid "Comment Address"
+msgstr "Адрес для комментариев"
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr "Комментарий не записан"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Comment on tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "CommentOnTicket"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:35
+msgid "Comments"
+msgstr "Комментарии"
+
+#: html/Ticket/ModifyAll.html:70 html/Ticket/Update.html:70
+msgid "Comments (Not sent to requestors)"
+msgstr "Комментарии (Не отправляются просителям)"
+
+#: html/Search/Bulk.html:122
+msgid "Comments (not sent to requestors)"
+msgstr "Комментарии (не отправляются просителю)"
+
+#: html/Elements/ViewUser:27
+#. ($name)
+msgid "Comments about %1"
+msgstr "Информация о %1"
+
+#: html/Admin/Users/Modify.html:185 html/Ticket/Elements/ShowRequestor:44
+msgid "Comments about this user"
+msgstr "Дополнительная информация об этом пользователе"
+
+#: lib/RT/Transaction_Overlay.pm:545
+msgid "Comments added"
+msgstr "Добавлены комментарии"
+
+#: lib/RT/Action/Generic.pm:140
+msgid "Commit Stubbed"
+msgstr "Действие не реализовано"
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr "Применить ограничения"
+
+#: html/Admin/Elements/EditScrip:41
+msgid "Condition"
+msgstr "Условие"
+
+#: bin/rt-crontool:109
+msgid "Condition matches..."
+msgstr "Подходящее условие..."
+
+#: lib/RT/Scrip_Overlay.pm:160
+msgid "Condition not found"
+msgstr "Условие не найдено"
+
+#: html/Elements/Tabs:52
+msgid "Configuration"
+msgstr "Настройка"
+
+#: html/SelfService/Prefs.html:33
+msgid "Confirm"
+msgstr "Подтвердить"
+
+#: html/Admin/Elements/ModifyUser:60
+msgid "ContactInfoSystem"
+msgstr "Контактная информация"
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr "Не могу разобрать дату последнего контакта '%1'"
+
+#: html/Admin/Elements/ModifyTemplate:44 html/Ticket/ModifyAll.html:87
+msgid "Content"
+msgstr "Текст"
+
+#: NOT FOUND IN SOURCE
+msgid "Coould not create group"
+msgstr ""
+
+#: etc/initialdata:266
+msgid "Correspondence"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:39 html/Admin/Queues/Modify.html:51
+msgid "Correspondence Address"
+msgstr "Адрес для сообщений"
+
+#: lib/RT/Transaction_Overlay.pm:541
+msgid "Correspondence added"
+msgstr "Добавлено сообщение"
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr "Сообщение не записано"
+
+#: lib/RT/Ticket_Overlay.pm:3458
+msgid "Could not add new custom field value for ticket. "
+msgstr "Не могу добавить новое поле с таким значением."
+
+#: NOT FOUND IN SOURCE
+msgid "Could not add new custom field value for ticket. %1 "
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2963 lib/RT/Ticket_Overlay.pm:2971 lib/RT/Ticket_Overlay.pm:2987
+msgid "Could not change owner. "
+msgstr "Не могу сменить владельца. "
+
+#: html/Admin/Elements/EditCustomField:68 html/Admin/Elements/EditCustomFields:166
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr "Не могу добавить поле"
+
+#: html/User/Groups/Modify.html:77 lib/RT/Group_Overlay.pm:474 lib/RT/Group_Overlay.pm:481
+msgid "Could not create group"
+msgstr "Не могу создать группу"
+
+#: html/Admin/Global/Template.html:75 html/Admin/Queues/Template.html:72
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr "Не могу создать шаблон: %1"
+
+#: lib/RT/Ticket_Overlay.pm:1073 lib/RT/Ticket_Overlay.pm:333
+msgid "Could not create ticket. Queue not set"
+msgstr "Не могу создать тикет. Очередь не определена."
+
+#: lib/RT/User_Overlay.pm:208 lib/RT/User_Overlay.pm:220 lib/RT/User_Overlay.pm:238 lib/RT/User_Overlay.pm:414
+msgid "Could not create user"
+msgstr "Не могу создать пользователя"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not create watcher for requestor"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr "Не могу найти тикет по идентификатору %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr "Не найдена группа %1."
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1422
+msgid "Could not find or create that user"
+msgstr "Не могу найти или создать этого пользователя"
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1501
+msgid "Could not find that principal"
+msgstr "Не могу найти этого пользователя"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr "Не найден пользователь %1."
+
+#: html/Admin/Groups/Members.html:88 html/User/Groups/Members.html:90 html/User/Groups/Modify.html:82
+msgid "Could not load group"
+msgstr "Не могу загрузить группу"
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr "Не могу назначить этого пользователя %1 для этой очереди"
+
+#: lib/RT/Ticket_Overlay.pm:1443
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr "Не могу назначить этого пользователя %1 для этого тикета"
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr "Не могу отобрать функции у пользователя как %1 в этой очереди"
+
+#: lib/RT/Ticket_Overlay.pm:1559
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr "Не могу отобрать функции у пользователя как %1 для этого тикета"
+
+#: lib/RT/Group_Overlay.pm:985
+msgid "Couldn't add member to group"
+msgstr "Не могу добавить пользователя в группу"
+
+#: lib/RT/Ticket_Overlay.pm:3468 lib/RT/Ticket_Overlay.pm:3524
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr "Не могу создать транзакцию: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr "Не пойму что делать из ответа gpg\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr "Не найти группу\\n"
+
+#: lib/RT/Interface/Web.pm:866
+msgid "Couldn't find row"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:959
+msgid "Couldn't find that principal"
+msgstr "Не найти этого пользователя"
+
+#: lib/RT/CustomField_Overlay.pm:175
+msgid "Couldn't find that value"
+msgstr "Не найти этого значения"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find that watcher"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr "Пользователь не найден\\n"
+
+#: lib/RT/CurrentUser.pm:112
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr "Не загрузить %1 из базы пользователей.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load KeywordSelects."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr "Не загрузить файл настроек RT '%1' %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr ""
+
+#: html/Admin/Groups/GroupRights.html:88 html/Admin/Groups/UserRights.html:75
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr "Не загрузить группу %1"
+
+#: lib/RT/Link_Overlay.pm:175 lib/RT/Link_Overlay.pm:184 lib/RT/Link_Overlay.pm:211
+msgid "Couldn't load link"
+msgstr "Не загрузить ссылку"
+
+#: html/Admin/Elements/EditCustomFields:147 html/Admin/Queues/People.html:121
+#. ($id)
+msgid "Couldn't load queue"
+msgstr "Не загрузить очередь"
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:72
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr "Не загрузить очередь %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr "Не загрузить скрипт"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr "Не загрузить шаблон"
+
+#: html/Admin/Users/Prefs.html:79
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr "Не загрузить этого пользователя (%1)"
+
+#: html/SelfService/Display.html:166
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr "Не загрузить тикет '%1'"
+
+#: html/Admin/Elements/ModifyUser:86 html/Admin/Users/Modify.html:149 html/User/Prefs.html:98
+msgid "Country"
+msgstr "Страна"
+
+#: html/Admin/Elements/CreateUserCalled:26 html/Ticket/Create.html:135 html/Ticket/Create.html:195
+msgid "Create"
+msgstr "Создать"
+
+#: etc/initialdata:128
+msgid "Create Tickets"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomField:58
+msgid "Create a CustomField"
+msgstr "Добавить поле"
+
+#: html/Admin/Queues/CustomField.html:48
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:48
+msgid "Create a CustomField which applies to all queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr "Добавить новое поле"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global Scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:67 html/Admin/Groups/Modify.html:93
+msgid "Create a new group"
+msgstr "Добавить новую группу"
+
+#: html/User/Groups/Modify.html:67 html/User/Groups/Modify.html:92
+msgid "Create a new personal group"
+msgstr "Добавить новую личную группу"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr "Добавить новую очередь"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr "Добавить новый скрипт"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr "Добавить новый шаблон"
+
+#: html/SelfService/Create.html:30 html/Ticket/Create.html:25 html/Ticket/Create.html:28 html/Ticket/Create.html:36
+msgid "Create a new ticket"
+msgstr "Добавить новый тикет"
+
+#: html/Admin/Users/Modify.html:214 html/Admin/Users/Modify.html:241
+msgid "Create a new user"
+msgstr "Добавить нового пользователя"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "Создать очередь"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr "Создать очередь с именем"
+
+#: html/SelfService/Create.html:25 html/SelfService/Create.html:27
+msgid "Create a request"
+msgstr "Создать запрос"
+
+#: html/Admin/Queues/Scrip.html:59
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr "Создать скрипт для очереди %1"
+
+#: html/Admin/Global/Template.html:69 html/Admin/Queues/Template.html:65
+msgid "Create a template"
+msgstr "Создать запрос"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1 / %2 / %3 "
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1/%2/%3"
+msgstr ""
+
+#: etc/initialdata:130
+msgid "Create new tickets based on this scrip's template"
+msgstr ""
+
+#: html/SelfService/Create.html:81
+msgid "Create ticket"
+msgstr "Создать тикет"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Create tickets in this queue"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Create, delete and modify custom fields"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Create, delete and modify queues"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr ""
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify the members of personal groups"
+msgstr ""
+
+#: lib/RT/System.pm:60
+msgid "Create, delete and modify users"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "CreateTicket"
+msgstr ""
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/ShowDates:27 lib/RT/Ticket_Overlay.pm:1167
+msgid "Created"
+msgstr "Создан"
+
+#: html/Admin/Elements/EditCustomField:71
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr "Добавлено поле %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr "Создан шаблон %1"
+
+#: html/Ticket/Elements/EditLinks:28
+msgid "Current Relationships"
+msgstr "Текущие связи"
+
+#: html/Admin/Elements/EditScrips:30
+msgid "Current Scrips"
+msgstr "Текущие скрипты"
+
+#: html/Admin/Groups/Members.html:39 html/User/Groups/Members.html:42
+msgid "Current members"
+msgstr "Текущие пользователи"
+
+#: html/Admin/Elements/SelectRights:29
+msgid "Current rights"
+msgstr "Текущие права"
+
+#: html/Search/Listing.html:71
+msgid "Current search criteria"
+msgstr ""
+
+#: html/Admin/Queues/People.html:41 html/Ticket/Elements/EditPeople:45
+msgid "Current watchers"
+msgstr "Текущие наблюдатели"
+
+#: html/Admin/Global/CustomField.html:55
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:53 html/Admin/Elements/SystemTabs:40 html/Admin/Global/index.html:50 html/Ticket/Elements/ShowSummary:35
+msgid "Custom Fields"
+msgstr "Дополнительные поля"
+
+#: html/Admin/Elements/EditScrip:73
+msgid "Custom action cleanup code"
+msgstr "Пользовательский код очистки"
+
+#: html/Admin/Elements/EditScrip:65
+msgid "Custom action preparation code"
+msgstr "Пользовательский подготовительный код"
+
+#: html/Admin/Elements/EditScrip:49
+msgid "Custom condition"
+msgstr "Пользовательское условие"
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr "Дополнительное поле %1 %2 %3"
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr "Дополнительное поле %1 имеет значение."
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr "Дополнительное поле %1 не имеет значения."
+
+#: lib/RT/Ticket_Overlay.pm:3360
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr "Дополнительное поле %1 не найдено"
+
+#: html/Admin/Elements/EditCustomFields:197
+msgid "Custom field deleted"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3510
+msgid "Custom field not found"
+msgstr "Дополнительное поле не найдено"
+
+#: lib/RT/CustomField_Overlay.pm:283
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr "Значение %1 не может быть найдено для поля %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr "Значение поля изменено с %1 на %2"
+
+#: lib/RT/CustomField_Overlay.pm:185
+msgid "Custom field value could not be deleted"
+msgstr "Значение дополнительного поля не может быть удалено"
+
+#: lib/RT/CustomField_Overlay.pm:289
+msgid "Custom field value could not be found"
+msgstr "Значение дополнительного поля не найдено"
+
+#: lib/RT/CustomField_Overlay.pm:183 lib/RT/CustomField_Overlay.pm:291
+msgid "Custom field value deleted"
+msgstr "Значение дополнительного поля было удалено"
+
+#: lib/RT/Transaction_Overlay.pm:550
+msgid "CustomField"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Data error"
+msgstr ""
+
+#: html/Ticket/Create.html:161 html/Ticket/Elements/ShowSummary:53 html/Ticket/Elements/Tabs:93 html/Ticket/ModifyAll.html:44
+msgid "Dates"
+msgstr "Даты"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "Дек."
+
+#: NOT FOUND IN SOURCE
+msgid "December"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr ""
+
+#: etc/initialdata:207
+msgid "Default Autoresponse template"
+msgstr ""
+
+#: etc/initialdata:275
+msgid "Default admin comment template"
+msgstr ""
+
+#: etc/initialdata:257
+msgid "Default admin correspondence template"
+msgstr ""
+
+#: etc/initialdata:267
+msgid "Default correspondence template"
+msgstr ""
+
+#: etc/initialdata:238
+msgid "Default transaction template"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:645
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr ""
+
+#: html/User/Delegation.html:25 html/User/Delegation.html:28
+msgid "Delegate rights"
+msgstr "Передача прав"
+
+#: lib/RT/System.pm:63
+msgid "Delegate specific rights which have been granted to you."
+msgstr ""
+
+#: lib/RT/System.pm:63
+msgid "DelegateRights"
+msgstr ""
+
+#: html/User/Elements/Tabs:38
+msgid "Delegation"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Delete"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "Delete tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:90
+msgid "DeleteTicket"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr "Удаление этого объекта может нарушить ссылочную целостность"
+
+#: lib/RT/Queue_Overlay.pm:292
+msgid "Deleting this object would break referential integrity"
+msgstr "Удаление этого объекта нарушит ссылочную целостность"
+
+#: lib/RT/User_Overlay.pm:430
+msgid "Deleting this object would violate referential integrity"
+msgstr "Удаление этого объекта нарушит ссылочную целостность"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity. That's bad."
+msgstr ""
+
+#: html/Approvals/Elements/Approve:46
+msgid "Deny"
+msgstr "Отказать"
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/EditLinks:123 html/Ticket/Elements/EditLinks:47 html/Ticket/Elements/ShowDependencies:32 html/Ticket/Elements/ShowLinks:35
+msgid "Depended on by"
+msgstr "От него зависят"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr "Зависимости: \\n"
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:180 html/Ticket/Elements/EditLinks:119 html/Ticket/Elements/EditLinks:36 html/Ticket/Elements/ShowDependencies:25 html/Ticket/Elements/ShowLinks:27
+msgid "Depends on"
+msgstr "Зависит от"
+
+#: NOT FOUND IN SOURCE
+msgid "DependsOn"
+msgstr ""
+
+#: html/Elements/SelectSortOrder:35
+msgid "Descending"
+msgstr "В порядке убывания"
+
+#: html/SelfService/Create.html:75 html/Ticket/Create.html:119
+msgid "Describe the issue below"
+msgstr "Опишите проблему"
+
+#: html/Admin/Elements/AddCustomFieldValue:27 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/EditScrip:34 html/Admin/Elements/ModifyQueue:36 html/Admin/Elements/ModifyTemplate:36 html/Admin/Groups/Modify.html:49 html/Admin/Queues/Modify.html:48 html/Elements/SelectGroups:27 html/User/Groups/Modify.html:49
+msgid "Description"
+msgstr "Описание"
+
+#: html/SelfService/Elements/MyRequests:44
+msgid "Details"
+msgstr "Подробности"
+
+#: html/Ticket/Elements/Tabs:85
+msgid "Display"
+msgstr "Показать"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Display Access Control List"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Display Scrip templates for this queue"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Display Scrips for this queue"
+msgstr ""
+
+#: html/Ticket/Elements/ShowHistory:35
+msgid "Display mode"
+msgstr "Режим показа"
+
+#: html/SelfService/Display.html:25 html/SelfService/Display.html:29
+#. ($Ticket->id)
+msgid "Display ticket #%1"
+msgstr "Показать тикет #%1"
+
+#: lib/RT/System.pm:54
+msgid "Do anything and everything"
+msgstr ""
+
+#: html/Elements/Refresh:30
+msgid "Don't refresh this page."
+msgstr "Не обновлять эту страницу"
+
+#: html/Search/Elements/PickRestriction:114
+msgid "Don't show search results"
+msgstr ""
+
+#: html/Ticket/Elements/ShowTransaction:105
+msgid "Download"
+msgstr "Скачать"
+
+#: html/Elements/SelectDateType:32 html/Ticket/Create.html:167 html/Ticket/Elements/EditDates:45 html/Ticket/Elements/ShowDates:43 lib/RT/Ticket_Overlay.pm:1171
+msgid "Due"
+msgstr "Дан срок"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr "Не могу прочесть срок решения проблемы '%1'"
+
+#: bin/rt-commit-handler:754
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr "ОШИБКА: Не могу загрузить тикет '%1': %2.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit"
+msgstr "Изменить"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit Conditions"
+msgstr ""
+
+#: html/Admin/Queues/CustomFields.html:45
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr "Изменение дополнительных полей для %1"
+
+#: html/Ticket/ModifyLinks.html:36
+msgid "Edit Relationships"
+msgstr "Изменение связей"
+
+#: html/Admin/Queues/Templates.html:41
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit keywords"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr ""
+
+#: html/Admin/Global/index.html:46
+msgid "Edit system templates"
+msgstr "Изменение системных шаблонов"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr "Изменение шаблонов для %1"
+
+#: html/Admin/Elements/ModifyQueue:25 html/Admin/Queues/Modify.html:117
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr "Изменение настроек очереди %1"
+
+#: html/Admin/Elements/ModifyUser:25
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr "Изменение настроек пользователя %1"
+
+#: html/Admin/Elements/EditCustomField:74
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr "Изменение поля %1"
+
+#: html/Admin/Groups/Members.html:32
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr "Пользователи в группе %1"
+
+#: html/User/Groups/Members.html:129
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr "Пользователи в личной группе %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr "Изменение шаблона %1"
+
+#: lib/RT/Ticket_Overlay.pm:2615 lib/RT/Ticket_Overlay.pm:2683
+msgid "Either base or target must be specified"
+msgstr "Нужно указать либо источник, либо адрес назначения"
+
+#: html/Admin/Users/Modify.html:53 html/Admin/Users/Prefs.html:46 html/Elements/SelectUsers:27 html/Ticket/Elements/AddWatchers:56 html/User/Prefs.html:42
+msgid "Email"
+msgstr "Email"
+
+#: lib/RT/User_Overlay.pm:188
+msgid "Email address in use"
+msgstr "Email уже занят"
+
+#: html/Admin/Elements/ModifyUser:42
+msgid "EmailAddress"
+msgstr "EmailAddress"
+
+#: html/Admin/Elements/ModifyUser:54
+msgid "EmailEncoding"
+msgstr "EmailEncoding"
+
+#: html/Admin/Elements/EditCustomField:36
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:53 html/User/Groups/Modify.html:53
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr ""
+
+#: html/Admin/Queues/Modify.html:84
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr "Включена (Снятая галочка означает отключенную очередь)"
+
+#: html/Admin/Elements/EditCustomFields:99
+msgid "Enabled Custom Fields"
+msgstr ""
+
+#: html/Admin/Queues/index.html:56
+msgid "Enabled Queues"
+msgstr "Включенные очереди"
+
+#: html/Admin/Elements/EditCustomField:90 html/Admin/Groups/Modify.html:117 html/Admin/Queues/Modify.html:138 html/Admin/Users/Modify.html:283 html/User/Groups/Modify.html:117
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr "Включен статус %1"
+
+#: lib/RT/CustomField_Overlay.pm:361
+msgid "Enter multiple values"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:358
+msgid "Enter one value"
+msgstr ""
+
+#: html/Ticket/Elements/EditLinks:112
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "Введите номера или ссылки на тикеты. Несколько тикетов разделяются пробелами."
+
+#: html/Elements/Login:29 html/SelfService/Error.html:25 html/SelfService/Error.html:26
+msgid "Error"
+msgstr "Ошибка"
+
+#: NOT FOUND IN SOURCE
+msgid "Error adding watcher"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr "Ошибка в параметрах Queue->AddWatcher"
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr "Ошибка в параметрах Queue->DelWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1356
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr "Ошибка в параметрах Ticket->AddWatcher"
+
+#: lib/RT/Ticket_Overlay.pm:1532
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr "Ошибка в параметрах Ticket->DelWatcher"
+
+#: etc/initialdata:20
+msgid "Everyone"
+msgstr ""
+
+#: bin/rt-crontool:194
+msgid "Example:"
+msgstr "Пример:"
+
+#: html/Admin/Elements/ModifyUser:64
+msgid "ExternalAuthId"
+msgstr "ExternalAuthId"
+
+#: html/Admin/Elements/ModifyUser:58
+msgid "ExternalContactInfoId"
+msgstr "ExternalContactInfoId"
+
+#: html/Admin/Users/Modify.html:73
+msgid "Extra info"
+msgstr "Доп. информация"
+
+#: lib/RT/User_Overlay.pm:302
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr "Не могу найти псевдо-группу 'Полномочных' пользователей"
+
+#: lib/RT/User_Overlay.pm:309
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr "Не могу найти псевдо-группу 'Неполномочных' пользователей"
+
+#: bin/rt-crontool:138
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr ""
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "Фев."
+
+#: NOT FOUND IN SOURCE
+msgid "February"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr "Конец"
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:59 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "Конечный приоритет"
+
+#: lib/RT/Ticket_Overlay.pm:1162
+msgid "FinalPriority"
+msgstr ""
+
+#: html/Admin/Queues/People.html:61 html/Ticket/Elements/EditPeople:34
+msgid "Find group whose"
+msgstr ""
+
+#: html/Elements/Quicksearch:25
+msgid "Find new/open tickets"
+msgstr "Информация о тикетах"
+
+#: html/Admin/Queues/People.html:57 html/Admin/Users/index.html:46 html/Ticket/Elements/EditPeople:30
+msgid "Find people whose"
+msgstr "Найти людей, у которых"
+
+#: html/Search/Listing.html:108
+msgid "Find tickets"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Finish Approval"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:58
+msgid "First"
+msgstr "Начало"
+
+#: html/Search/Listing.html:41
+msgid "First page"
+msgstr "Первая страница"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr "Foo Bar Baz"
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr "Foo!"
+
+#: html/Search/Bulk.html:87
+msgid "Force change"
+msgstr "Изменить силой"
+
+#: html/Search/Listing.html:106
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:868
+msgid "Found Object"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:44
+msgid "FreeformContactInfo"
+msgstr "FreeformContactInfo"
+
+#: lib/RT/CustomField_Overlay.pm:38
+msgid "FreeformMultiple"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformSingle"
+msgstr ""
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "Птн."
+
+#: html/Ticket/Elements/ShowHistory:41 html/Ticket/Elements/ShowHistory:51
+msgid "Full headers"
+msgstr "Полный"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr "Берем текущего пользователя из pgp подписи\\n"
+
+#: lib/RT/Transaction_Overlay.pm:595
+#. ($New->Name)
+msgid "Given to %1"
+msgstr ""
+
+#: html/Admin/Elements/Tabs:41 html/Admin/index.html:38
+msgid "Global"
+msgstr "Общие"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Keyword Selections"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr ""
+
+#: html/Admin/Elements/SelectTemplate:38
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:75 html/Admin/Queues/People.html:59 html/Admin/Queues/People.html:63 html/Admin/Queues/index.html:44 html/Admin/Users/index.html:49 html/Ticket/Elements/EditPeople:32 html/Ticket/Elements/EditPeople:36 html/index.html:41
+msgid "Go!"
+msgstr "Поехали!"
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr "Хорошая pgp подпись от %1\\n"
+
+#: html/Search/Listing.html:50
+msgid "Goto page"
+msgstr "Перейти на страницу"
+
+#: html/Elements/GotoTicket:25 html/SelfService/Elements/GotoTicket:25
+msgid "Goto ticket"
+msgstr "Показать тикет"
+
+#: NOT FOUND IN SOURCE
+msgid "Grand"
+msgstr ""
+
+#: html/Ticket/Elements/AddWatchers:46 html/User/Elements/DelegateRights:78
+msgid "Group"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr "Группа %1 %2: %3"
+
+#: html/Admin/Elements/GroupTabs:45 html/Admin/Elements/QueueTabs:57 html/Admin/Elements/SystemTabs:44 html/Admin/Global/index.html:55
+msgid "Group Rights"
+msgstr "Права группы"
+
+#: lib/RT/Group_Overlay.pm:965
+msgid "Group already has member"
+msgstr "Пользователь уже входит в группу"
+
+#: NOT FOUND IN SOURCE
+msgid "Group could not be created."
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:77
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr "Не могу создать группу: %1"
+
+#: lib/RT/Group_Overlay.pm:497
+msgid "Group created"
+msgstr "Создана группа"
+
+#: lib/RT/Group_Overlay.pm:1133
+msgid "Group has no such member"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:945 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1429 lib/RT/Ticket_Overlay.pm:1507
+msgid "Group not found"
+msgstr "Группа не найдена"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr "Группа не найдена.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr "Не задана группа.\\n"
+
+#: html/Admin/Elements/SelectNewGroupMembers:35 html/Admin/Elements/Tabs:35 html/Admin/Groups/Members.html:64 html/Admin/Queues/People.html:83 html/Admin/index.html:32 html/User/Groups/Members.html:67
+msgid "Groups"
+msgstr "Группы"
+
+#: lib/RT/Group_Overlay.pm:971
+msgid "Groups can't be members of their members"
+msgstr "Группы не могут быть членами входящих в них пользователей"
+
+#: lib/RT/Interface/CLI.pm:73 lib/RT/Interface/CLI.pm:73
+msgid "Hello!"
+msgstr "Здравствуйте!"
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr "Hello, %1"
+
+#: html/Ticket/Elements/ShowHistory:30 html/Ticket/Elements/Tabs:88
+msgid "History"
+msgstr "История"
+
+#: html/Admin/Elements/ModifyUser:68
+msgid "HomePhone"
+msgstr "HomePhone"
+
+#: html/Elements/Tabs:46
+msgid "Homepage"
+msgstr "Домой"
+
+#: lib/RT/Base.pm:74
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "I have [quant,_1,concrete mixer]."
+msgstr "I have [quant,_1,concrete mixer]."
+
+#: html/Ticket/Elements/ShowBasics:27 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr "Тикет"
+
+#: html/Admin/Users/Modify.html:44 html/User/Prefs.html:39
+msgid "Identity"
+msgstr "Личность"
+
+#: etc/upgrade/2.1.71:86
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr ""
+
+#: bin/rt-crontool:190
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr "Если бы эта программа имела установленный бит setgid, то зловредный пользователь мог бы воспользоваться этим для получения административных полномочий в RT."
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "If you've updated anything above, be sure to"
+msgstr "Если вы что-либо изменили, то удостоверьтесь, что"
+
+#: lib/RT/Interface/Web.pm:860
+msgid "Illegal value for %1"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:863
+msgid "Immutable field"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:74
+msgid "Include disabled custom fields in listing."
+msgstr ""
+
+#: html/Admin/Queues/index.html:43
+msgid "Include disabled queues in listing."
+msgstr "Показывать отключенные очереди."
+
+#: html/Admin/Users/index.html:47
+msgid "Include disabled users in search."
+msgstr "Показать отключенных пользователей."
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr "Начальный приоритет"
+
+#: lib/RT/Ticket_Overlay.pm:1161 lib/RT/Ticket_Overlay.pm:1163
+msgid "InitialPriority"
+msgstr ""
+
+#: lib/RT/ScripAction_Overlay.pm:105
+msgid "Input error"
+msgstr "Ошибка ввода"
+
+#: NOT FOUND IN SOURCE
+msgid "Interest noted"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:3729
+msgid "Internal Error"
+msgstr "Внутренняя ошибка"
+
+#: lib/RT/Record.pm:143
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:644
+msgid "Invalid Group Type"
+msgstr "Неправильный тип группы"
+
+#: lib/RT/Principal_Overlay.pm:128
+msgid "Invalid Right"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Invalid Type"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:865
+msgid "Invalid data"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:438
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr "Владелец отсутствует. Заменяем его на 'nobody'."
+
+#: lib/RT/Scrip_Overlay.pm:134 lib/RT/Template_Overlay.pm:251
+msgid "Invalid queue"
+msgstr "Неверная очередь"
+
+#: lib/RT/ACE_Overlay.pm:244 lib/RT/ACE_Overlay.pm:253 lib/RT/ACE_Overlay.pm:259 lib/RT/ACE_Overlay.pm:270 lib/RT/ACE_Overlay.pm:275
+msgid "Invalid right"
+msgstr "Неверные права"
+
+#: lib/RT/Record.pm:118
+#. ($key)
+msgid "Invalid value for %1"
+msgstr "Неправильное значение для %1"
+
+#: lib/RT/Ticket_Overlay.pm:3367
+msgid "Invalid value for custom field"
+msgstr "Неправильное значение для этого поля"
+
+#: lib/RT/Ticket_Overlay.pm:345
+msgid "Invalid value for status"
+msgstr "Такого статуса не бывает"
+
+#: bin/rt-crontool:191
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr "Обратите внимание, что обычные пользователи не имеют права запускать эту программу."
+
+#: bin/rt-crontool:192
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr "Предполагается, что для запуска этой программы вы должны создать учетную запись пользователя Unix с корректными установками групп и доступом к RT."
+
+#: bin/rt-crontool:163
+msgid "It takes several arguments:"
+msgstr "Она требует несколько параметров:"
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr "Тикеты, ожидающие моей визы"
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "Янв."
+
+#: NOT FOUND IN SOURCE
+msgid "January"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "Join or leave this group"
+msgstr ""
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "Июл."
+
+#: NOT FOUND IN SOURCE
+msgid "July"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:99
+msgid "Jumbo"
+msgstr "Все вместе"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "Июн."
+
+#: NOT FOUND IN SOURCE
+msgid "June"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr "Ключевое слово"
+
+#: html/Admin/Elements/ModifyUser:52
+msgid "Lang"
+msgstr "Язык"
+
+#: html/Ticket/Elements/Tabs:73
+msgid "Last"
+msgstr "Конец"
+
+#: html/Ticket/Elements/EditDates:38 html/Ticket/Elements/ShowDates:39
+msgid "Last Contact"
+msgstr "Контакт"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Contacted"
+msgstr "Контакт"
+
+#: html/Search/Elements/TicketHeader:41
+msgid "Last Notified"
+msgstr ""
+
+#: html/Elements/SelectDateType:30
+msgid "Last Updated"
+msgstr "Обновлен"
+
+#: NOT FOUND IN SOURCE
+msgid "LastUpdated"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr "Осталось"
+
+#: html/Admin/Users/Modify.html:83
+msgid "Let this user access RT"
+msgstr "Разрешить доступ к RT"
+
+#: html/Admin/Users/Modify.html:87
+msgid "Let this user be granted rights"
+msgstr "Пользователь может иметь права"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr "Ограничиваем владельца %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr "Ограничиваем очередь для %1 %2"
+
+#: lib/RT/Ticket_Overlay.pm:2697
+msgid "Link already exists"
+msgstr "Связь уже существует"
+
+#: lib/RT/Ticket_Overlay.pm:2709
+msgid "Link could not be created"
+msgstr "Не могу связать тикеты"
+
+#: lib/RT/Ticket_Overlay.pm:2717 lib/RT/Ticket_Overlay.pm:2727
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2638
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr "Удалена связь (%1)"
+
+#: lib/RT/Ticket_Overlay.pm:2644
+msgid "Link not found"
+msgstr "Связь не найдена"
+
+#: html/Ticket/ModifyLinks.html:25 html/Ticket/ModifyLinks.html:29
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr "Связываем тикет #%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Link ticket %1"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:97
+msgid "Links"
+msgstr "Связи"
+
+#: html/Admin/Users/Modify.html:114 html/User/Prefs.html:85
+msgid "Location"
+msgstr "Местонахождение"
+
+#: lib/RT.pm:158
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr "Не найден каталог для протоколирования %1 или не доступен на запись.\\n RT не может продолжить работу."
+
+#: html/Elements/Header:57
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "Зарегистрирован как %1"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:25 html/Elements/Login:34 html/Elements/Login:45
+msgid "Login"
+msgstr "Логин"
+
+#: html/Elements/Header:54
+msgid "Logout"
+msgstr "Выйти"
+
+#: html/Search/Bulk.html:86
+msgid "Make Owner"
+msgstr "Назначить владельцем"
+
+#: html/Search/Bulk.html:102
+msgid "Make Status"
+msgstr "Назначить статус"
+
+#: html/Search/Bulk.html:109
+msgid "Make date Due"
+msgstr "Назначить срок"
+
+#: html/Search/Bulk.html:110
+msgid "Make date Resolved"
+msgstr "Изменить дату решения"
+
+#: html/Search/Bulk.html:107
+msgid "Make date Started"
+msgstr "Изменить дату 'Начался'"
+
+#: html/Search/Bulk.html:106
+msgid "Make date Starts"
+msgstr "Изменить дату 'Начинается'"
+
+#: html/Search/Bulk.html:108
+msgid "Make date Told"
+msgstr "Изменить дату последнего контакта"
+
+#: html/Search/Bulk.html:99
+msgid "Make priority"
+msgstr "Назначить приоритет"
+
+#: html/Search/Bulk.html:100
+msgid "Make queue"
+msgstr "Назначить очередь"
+
+#: html/Search/Bulk.html:98
+msgid "Make subject"
+msgstr "Изменить тему"
+
+#: html/Admin/index.html:33
+msgid "Manage groups and group membership"
+msgstr "Настройка групп и их пользователей"
+
+#: html/Admin/index.html:39
+msgid "Manage properties and configuration which apply to all queues"
+msgstr "Настройки для всех очередей"
+
+#: html/Admin/index.html:36
+msgid "Manage queues and queue-specific properties"
+msgstr "Настройка очередей и их параметров"
+
+#: html/Admin/index.html:30
+msgid "Manage users and passwords"
+msgstr "Настройка пользователей и их паролей"
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "Мар."
+
+#: NOT FOUND IN SOURCE
+msgid "March"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "May"
+msgstr ""
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "Май"
+
+#: lib/RT/Group_Overlay.pm:982
+msgid "Member added"
+msgstr "Пользователь добавлен в группу"
+
+#: lib/RT/Group_Overlay.pm:1140
+msgid "Member deleted"
+msgstr "Пользователь удален из группы"
+
+#: lib/RT/Group_Overlay.pm:1144
+msgid "Member not deleted"
+msgstr "Пользователь не удален из группы"
+
+#: html/Elements/SelectLinkType:26
+msgid "Member of"
+msgstr "Входит в"
+
+#: NOT FOUND IN SOURCE
+msgid "MemberOf"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:42 html/User/Elements/GroupTabs:42
+msgid "Members"
+msgstr "Пользователи"
+
+#: lib/RT/Ticket_Overlay.pm:2843
+msgid "Merge Successful"
+msgstr "Тикеты успешно склеены"
+
+#: lib/RT/Ticket_Overlay.pm:2804
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "Склейка не удалась. Не смогла установить идентификатор тикета."
+
+#: html/Ticket/Elements/EditLinks:115
+msgid "Merge into"
+msgstr "Приклеить к"
+
+#: html/Ticket/Update.html:102
+msgid "Message"
+msgstr "Текст"
+
+#: lib/RT/Interface/Web.pm:867
+msgid "Missing a primary key?: %1"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:169 html/User/Prefs.html:54
+msgid "Mobile"
+msgstr "Мобильник"
+
+#: html/Admin/Elements/ModifyUser:72
+msgid "MobilePhone"
+msgstr "MobilePhone"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify Access Control List"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Custom Field %1"
+msgstr "Изменение дополнительного поля %1"
+
+#: html/Admin/Global/CustomFields.html:44 html/Admin/Global/index.html:51
+msgid "Modify Custom Fields which apply to all queues"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "Modify Scrip templates for this queue"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "Modify Scrips for this queue"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify System ACLS"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr ""
+
+#: html/Admin/Queues/CustomField.html:45
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:53
+msgid "Modify a CustomField which applies to all queues"
+msgstr ""
+
+#: html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr "Изменить скрипт для очереди %1"
+
+#: html/Admin/Global/Scrip.html:48
+msgid "Modify a scrip which applies to all queues"
+msgstr "Изменение скрипта, который действует для всех очередей"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify dates for # %1"
+msgstr ""
+
+#: html/Ticket/ModifyDates.html:25 html/Ticket/ModifyDates.html:29
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr "Изменение дат в тикете #%1"
+
+#: html/Ticket/ModifyDates.html:35
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr "Изменение дат в тикете #%1"
+
+#: html/Admin/Global/GroupRights.html:25 html/Admin/Global/GroupRights.html:28 html/Admin/Global/index.html:56
+msgid "Modify global group rights"
+msgstr "Изменение глобальных прав группы"
+
+#: html/Admin/Global/GroupRights.html:33
+msgid "Modify global group rights."
+msgstr "Изменение глобальных прав группы"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for groups"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for users"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr ""
+
+#: html/Admin/Global/UserRights.html:25 html/Admin/Global/UserRights.html:28 html/Admin/Global/index.html:60
+msgid "Modify global user rights"
+msgstr ""
+
+#: html/Admin/Global/UserRights.html:33
+msgid "Modify global user rights."
+msgstr "Изменение глобальных прав пользователя"
+
+#: lib/RT/Group_Overlay.pm:146
+msgid "Modify group metadata or delete group"
+msgstr ""
+
+#: html/Admin/Groups/GroupRights.html:25 html/Admin/Groups/GroupRights.html:29 html/Admin/Groups/GroupRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr "Изменение прав групп для группе %1"
+
+#: html/Admin/Queues/GroupRights.html:25 html/Admin/Queues/GroupRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr "Изменение прав групп для очереди %1"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Modify membership roster for this group"
+msgstr ""
+
+#: lib/RT/System.pm:61
+msgid "Modify one's own RT account"
+msgstr ""
+
+#: html/Admin/Queues/People.html:25 html/Admin/Queues/People.html:29
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr "Изменение пользователей относящихся к очереди %1"
+
+#: html/Ticket/ModifyPeople.html:25 html/Ticket/ModifyPeople.html:29 html/Ticket/ModifyPeople.html:35
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr "Изменение пользователей относящихся к тикету #%1"
+
+#: html/Admin/Queues/Scrips.html:44
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr "Изменить скрипты для очереди %1"
+
+#: html/Admin/Global/Scrips.html:44 html/Admin/Global/index.html:42
+msgid "Modify scrips which apply to all queues"
+msgstr "Изменение скриптов, которые действуют на все очереди"
+
+#: html/Admin/Global/Template.html:25 html/Admin/Global/Template.html:30 html/Admin/Global/Template.html:81 html/Admin/Queues/Template.html:78
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr "Изменение шаблона %1"
+
+#: html/Admin/Global/Templates.html:44
+msgid "Modify templates which apply to all queues"
+msgstr ""
+
+#: html/Admin/Groups/Modify.html:87 html/User/Groups/Modify.html:86
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr "Настройки для группы %1"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Modify the queue watchers"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:236
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr "Настройки для пользователя %1"
+
+#: html/Ticket/ModifyAll.html:37
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "Изменение тикета # %1"
+
+#: html/Ticket/Modify.html:25 html/Ticket/Modify.html:28 html/Ticket/Modify.html:34
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "Изменение тикета # %1"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Modify tickets"
+msgstr ""
+
+#: html/Admin/Groups/UserRights.html:25 html/Admin/Groups/UserRights.html:29 html/Admin/Groups/UserRights.html:35
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr "Изменение прав пользователя для группы %1"
+
+#: html/Admin/Queues/UserRights.html:25 html/Admin/Queues/UserRights.html:29
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr "Изменение прав пользователя для очереди %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr "Изменение наблюдателей для очереди '%1'"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyACL"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:149
+msgid "ModifyOwnMembership"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "ModifyQueueWatchers"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:76
+msgid "ModifyScrips"
+msgstr ""
+
+#: lib/RT/System.pm:61
+msgid "ModifySelf"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:73
+msgid "ModifyTemplate"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "ModifyTicket"
+msgstr ""
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "Пнд."
+
+#: html/Ticket/Elements/ShowRequestor:42
+#. ($name)
+msgid "More about %1"
+msgstr "Информация о %1"
+
+#: html/Admin/Elements/EditCustomFields:61
+msgid "Move down"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFields:53
+msgid "Move up"
+msgstr ""
+
+#: html/Admin/Elements/SelectSingleOrMultiple:27
+msgid "Multiple"
+msgstr "Несколько значений"
+
+#: lib/RT/User_Overlay.pm:179
+msgid "Must specify 'Name' attribute"
+msgstr "Вы должны указать Имя"
+
+#: NOT FOUND IN SOURCE
+msgid "My Approvals"
+msgstr "Мои визы"
+
+#: html/Approvals/index.html:25 html/Approvals/index.html:26
+msgid "My approvals"
+msgstr ""
+
+#: html/Admin/Elements/AddCustomFieldValue:26 html/Admin/Elements/EditCustomField:32 html/Admin/Elements/ModifyTemplate:28 html/Admin/Elements/ModifyUser:30 html/Admin/Groups/Modify.html:44 html/Elements/SelectGroups:26 html/Elements/SelectUsers:28 html/User/Groups/Modify.html:44
+msgid "Name"
+msgstr "Имя"
+
+#: lib/RT/User_Overlay.pm:186
+msgid "Name in use"
+msgstr "Имя уже используется"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr ""
+
+#: html/Ticket/Elements/ShowDates:52
+msgid "Never"
+msgstr ""
+
+#: html/Elements/Quicksearch:30
+msgid "New"
+msgstr "Новых"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:93 html/User/Prefs.html:65
+msgid "New Password"
+msgstr "Новый пароль"
+
+#: etc/initialdata:311 etc/upgrade/2.1.71:16
+msgid "New Pending Approval"
+msgstr ""
+
+#: html/Ticket/Elements/EditLinks:111
+msgid "New Relationships"
+msgstr "Новые связи"
+
+#: html/Ticket/Elements/Tabs:36
+msgid "New Search"
+msgstr ""
+
+#: html/Admin/Global/CustomField.html:41 html/Admin/Global/CustomFields.html:39 html/Admin/Queues/CustomField.html:52 html/Admin/Queues/CustomFields.html:40
+msgid "New custom field"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:54 html/User/Elements/GroupTabs:52
+msgid "New group"
+msgstr ""
+
+#: html/SelfService/Prefs.html:32
+msgid "New password"
+msgstr "Новый пароль"
+
+#: lib/RT/User_Overlay.pm:639
+msgid "New password notification sent"
+msgstr "Отправлено сообщение с новым паролем"
+
+#: html/Admin/Elements/QueueTabs:70
+msgid "New queue"
+msgstr ""
+
+#: html/SelfService/Elements/Tabs:63
+msgid "New request"
+msgstr "Новый запрос"
+
+#: html/Admin/Elements/SelectRights:42
+msgid "New rights"
+msgstr "Новые права"
+
+#: html/Admin/Global/Scrip.html:40 html/Admin/Global/Scrips.html:39 html/Admin/Queues/Scrip.html:43 html/Admin/Queues/Scrips.html:53
+msgid "New scrip"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "New search"
+msgstr "Новый поиск"
+
+#: html/Admin/Global/Template.html:60 html/Admin/Global/Templates.html:39 html/Admin/Queues/Template.html:58 html/Admin/Queues/Templates.html:46
+msgid "New template"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2771
+msgid "New ticket doesn't exist"
+msgstr "Новый тикет не существует"
+
+#: html/Admin/Elements/UserTabs:52
+msgid "New user"
+msgstr ""
+
+#: html/Admin/Elements/CreateUserCalled:26
+msgid "New user called"
+msgstr "Добавить пользователя с именем"
+
+#: html/Admin/Queues/People.html:55 html/Ticket/Elements/EditPeople:29
+msgid "New watchers"
+msgstr "Новые наблюдатели"
+
+#: html/Admin/Users/Prefs.html:42
+msgid "New window setting"
+msgstr "Новые настройки окна"
+
+#: html/Ticket/Elements/Tabs:69
+msgid "Next"
+msgstr "Вперед"
+
+#: html/Search/Listing.html:48
+msgid "Next page"
+msgstr "Следующая страница"
+
+#: html/Admin/Elements/ModifyUser:50
+msgid "NickName"
+msgstr "Псевдоним"
+
+#: html/Admin/Users/Modify.html:63 html/User/Prefs.html:46
+msgid "Nickname"
+msgstr "Псевдоним"
+
+#: html/Admin/Elements/EditCustomField:73 html/Admin/Elements/EditCustomFields:105
+msgid "No CustomField"
+msgstr "Нет такого поля"
+
+#: html/Admin/Groups/GroupRights.html:84 html/Admin/Groups/UserRights.html:71
+msgid "No Group defined"
+msgstr "Нет такой группы"
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:68
+msgid "No Queue defined"
+msgstr "Нет такой очереди"
+
+#: bin/rt-crontool:56
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr "Пользователь RT не найден. Пожалуйста, обратитесь к вашему администратору RT.\\n"
+
+#: html/Admin/Global/Template.html:79 html/Admin/Queues/Template.html:76
+msgid "No Template"
+msgstr "Шаблон не определен"
+
+#: bin/rt-commit-handler:764
+msgid "No Ticket specified. Aborting ticket "
+msgstr "Тикет не задан. Ничего не делаем."
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr "Тикет не задан. Отменяем изменения тикета\\n\\n"
+
+#: html/Approvals/Elements/Approve:47
+msgid "No action"
+msgstr "Нет действия"
+
+#: lib/RT/Interface/Web.pm:862
+msgid "No column specified"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr "Команда не найдена\\n"
+
+#: html/Elements/ViewUser:36 html/Ticket/Elements/ShowRequestor:45
+msgid "No comment entered about this user"
+msgstr "Без комментариев"
+
+#: lib/RT/Ticket_Overlay.pm:2189 lib/RT/Ticket_Overlay.pm:2257
+msgid "No correspondence attached"
+msgstr "Пустое сообщение"
+
+#: lib/RT/Action/Generic.pm:150 lib/RT/Condition/Generic.pm:176 lib/RT/Search/ActiveTicketsInQueue.pm:56 lib/RT/Search/Generic.pm:113
+#. (ref $self)
+msgid "No description for %1"
+msgstr "Нет описания для %1"
+
+#: lib/RT/Users_Overlay.pm:151
+msgid "No group specified"
+msgstr "Не указана группа"
+
+#: lib/RT/User_Overlay.pm:857
+msgid "No password set"
+msgstr "Отсутствует пароль"
+
+#: lib/RT/Queue_Overlay.pm:259
+msgid "No permission to create queues"
+msgstr "У вас нет права на создание очереди"
+
+#: lib/RT/Ticket_Overlay.pm:341
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr ""
+
+#: lib/RT/User_Overlay.pm:151
+msgid "No permission to create users"
+msgstr "Вы не имеете права создавать пользователей"
+
+#: html/SelfService/Display.html:174
+msgid "No permission to display that ticket"
+msgstr "Показ этого тикета запрещен"
+
+#: html/SelfService/Update.html:55
+msgid "No permission to view update ticket"
+msgstr "Запрещен показ изменений этого тикета"
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1488
+msgid "No principal specified"
+msgstr "Пользователь не указан"
+
+#: html/Admin/Queues/People.html:154 html/Admin/Queues/People.html:164
+msgid "No principals selected."
+msgstr "Пользователи не выбраны."
+
+#: html/Admin/Queues/index.html:35
+msgid "No queues matching search criteria found."
+msgstr "Ничего подходящего не найдено."
+
+#: html/Admin/Elements/SelectRights:81
+msgid "No rights found"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:33
+msgid "No rights granted."
+msgstr "Нет прав."
+
+#: html/Search/Bulk.html:149
+msgid "No search to operate on."
+msgstr "Нечего делать."
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr "Не указан номер тикета"
+
+#: lib/RT/Transaction_Overlay.pm:480 lib/RT/Transaction_Overlay.pm:518
+msgid "No transaction type specified"
+msgstr "Не указан тип транзакции"
+
+#: NOT FOUND IN SOURCE
+msgid "No user or email address specified"
+msgstr ""
+
+#: html/Admin/Users/index.html:36
+msgid "No users matching search criteria found."
+msgstr "Ни одного подходящего пользователя не найдено."
+
+#: bin/rt-commit-handler:644
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr "Не найден пользователь RT. Обработчик CVS отключен. Обратитесь к администратору RT.\\n"
+
+#: lib/RT/Interface/Web.pm:859
+msgid "No value sent to _Set!\\n"
+msgstr ""
+
+#: html/Search/Elements/TicketRow:37
+msgid "Nobody"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:864
+msgid "Nonexistant field?"
+msgstr ""
+
+#: html/Elements/Login:99
+msgid "Not logged in"
+msgstr ""
+
+#: html/Elements/Header:59 html/SelfService/Elements/Header:58
+msgid "Not logged in."
+msgstr "Не зарегистрирован."
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "Не установлено"
+
+#: html/NoAuth/Reminder.html:27
+msgid "Not yet implemented."
+msgstr "Еще не реализовано."
+
+#: html/Admin/Groups/Rights.html:25
+msgid "Not yet implemented...."
+msgstr "Еще не реализовано..."
+
+#: html/Approvals/Elements/Approve:50
+msgid "Notes"
+msgstr "Примечание"
+
+#: lib/RT/User_Overlay.pm:642
+msgid "Notification could not be sent"
+msgstr "Не могу отослать уведомление"
+
+#: etc/initialdata:94
+msgid "Notify AdminCcs"
+msgstr ""
+
+#: etc/initialdata:90
+msgid "Notify AdminCcs as Comment"
+msgstr ""
+
+#: etc/initialdata:121
+msgid "Notify Other Recipients"
+msgstr ""
+
+#: etc/initialdata:117
+msgid "Notify Other Recipients as Comment"
+msgstr ""
+
+#: etc/initialdata:86
+msgid "Notify Owner"
+msgstr ""
+
+#: etc/initialdata:82
+msgid "Notify Owner as Comment"
+msgstr ""
+
+#: etc/initialdata:313 etc/upgrade/2.1.71:17
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr ""
+
+#: etc/initialdata:78
+msgid "Notify Requestors"
+msgstr ""
+
+#: etc/initialdata:104
+msgid "Notify Requestors and Ccs"
+msgstr ""
+
+#: etc/initialdata:99
+msgid "Notify Requestors and Ccs as Comment"
+msgstr ""
+
+#: etc/initialdata:113
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr ""
+
+#: etc/initialdata:109
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr ""
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "Ноя."
+
+#: NOT FOUND IN SOURCE
+msgid "November"
+msgstr ""
+
+#: lib/RT/Record.pm:157
+msgid "Object could not be created"
+msgstr "Не могу создать объект"
+
+#: lib/RT/Record.pm:176
+msgid "Object created"
+msgstr "Создан объект"
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "Окт."
+
+#: NOT FOUND IN SOURCE
+msgid "October"
+msgstr ""
+
+#: html/Elements/SelectDateRelation:35
+msgid "On"
+msgstr "На"
+
+#: etc/initialdata:155
+msgid "On Comment"
+msgstr ""
+
+#: etc/initialdata:148
+msgid "On Correspond"
+msgstr ""
+
+#: etc/initialdata:137
+msgid "On Create"
+msgstr ""
+
+#: etc/initialdata:169
+msgid "On Owner Change"
+msgstr ""
+
+#: etc/initialdata:177
+msgid "On Queue Change"
+msgstr ""
+
+#: etc/initialdata:183
+msgid "On Resolve"
+msgstr ""
+
+#: etc/initialdata:161
+msgid "On Status Change"
+msgstr ""
+
+#: etc/initialdata:142
+msgid "On Transaction"
+msgstr ""
+
+#: html/Approvals/Elements/PendingMyApproval:50
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr "Показывать визы только для запросов созданных после %1"
+
+#: html/Approvals/Elements/PendingMyApproval:48
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr "Показывать визы только для запросов созданных до %1"
+
+#: html/Elements/Quicksearch:31
+msgid "Open"
+msgstr "Открытых"
+
+#: html/Ticket/Elements/Tabs:136
+msgid "Open it"
+msgstr "Открыть"
+
+#: html/SelfService/Elements/Tabs:57
+msgid "Open requests"
+msgstr "Открыть запросы"
+
+#: html/Admin/Users/Prefs.html:41
+msgid "Open tickets (from listing) in a new window"
+msgstr "Открыть тикеты (из списка) в новом окне"
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in another window"
+msgstr "Открыть тикеты (из списка) в другом окне"
+
+#: etc/initialdata:133
+msgid "Open tickets on correspondence"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:101
+msgid "Ordering and sorting"
+msgstr "Порядок и сортировка"
+
+#: html/Admin/Elements/ModifyUser:46 html/Admin/Users/Modify.html:117 html/Elements/SelectUsers:29 html/User/Prefs.html:86
+msgid "Organization"
+msgstr "Организация"
+
+#: html/Approvals/Elements/Approve:34
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:55 html/Admin/Queues/Modify.html:69
+msgid "Over time, priority moves toward"
+msgstr "Со временем поднять приоритет до"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Own tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "OwnTicket"
+msgstr ""
+
+#: etc/initialdata:38 html/Elements/MyRequests:32 html/SelfService/Elements/MyRequests:30 html/Ticket/Create.html:48 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/EditPeople:44 html/Ticket/Elements/ShowPeople:27 html/Ticket/Update.html:63 lib/RT/ACE_Overlay.pm:86 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "Владелец"
+
+#: lib/RT/Ticket_Overlay.pm:3004
+#. ($OldOwnerObj->Name,  $NewOwnerObj->Name)
+msgid "Owner changed from %1 to %2"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:584
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr "Владелец силой изменен с %1 на %2"
+
+#: html/Search/Elements/PickRestriction:31
+msgid "Owner is"
+msgstr "Владелец"
+
+#: html/Admin/Users/Modify.html:174 html/User/Prefs.html:56
+msgid "Pager"
+msgstr "Пейджер"
+
+#: html/Admin/Elements/ModifyUser:74
+msgid "PagerPhone"
+msgstr "Телефон пейджера"
+
+#: NOT FOUND IN SOURCE
+msgid "Parent"
+msgstr ""
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/EditLinks:127 html/Ticket/Elements/EditLinks:58 html/Ticket/Elements/ShowLinks:43
+msgid "Parents"
+msgstr "Предки"
+
+#: html/Elements/Login:43 html/User/Prefs.html:61
+msgid "Password"
+msgstr "Пароль"
+
+#: html/NoAuth/Reminder.html:25
+msgid "Password Reminder"
+msgstr "Подсказка к паролю"
+
+#: lib/RT/User_Overlay.pm:168 lib/RT/User_Overlay.pm:860
+msgid "Password too short"
+msgstr "Пароль слишком короткий"
+
+#: html/Admin/Users/Modify.html:291 html/User/Prefs.html:172
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "Пароль: %1"
+
+#: html/Ticket/Elements/ShowSummary:43 html/Ticket/Elements/Tabs:96 html/Ticket/ModifyAll.html:51
+msgid "People"
+msgstr "Люди"
+
+#: etc/initialdata:126
+msgid "Perform a user-defined action"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:231 lib/RT/ACE_Overlay.pm:237 lib/RT/ACE_Overlay.pm:563 lib/RT/ACE_Overlay.pm:573 lib/RT/ACE_Overlay.pm:583 lib/RT/ACE_Overlay.pm:648 lib/RT/CurrentUser.pm:83 lib/RT/CurrentUser.pm:92 lib/RT/CustomField_Overlay.pm:445 lib/RT/CustomField_Overlay.pm:451 lib/RT/Group_Overlay.pm:1095 lib/RT/Group_Overlay.pm:1099 lib/RT/Group_Overlay.pm:1108 lib/RT/Group_Overlay.pm:1159 lib/RT/Group_Overlay.pm:1163 lib/RT/Group_Overlay.pm:1169 lib/RT/Group_Overlay.pm:426 lib/RT/Group_Overlay.pm:518 lib/RT/Group_Overlay.pm:596 lib/RT/Group_Overlay.pm:604 lib/RT/Group_Overlay.pm:701 lib/RT/Group_Overlay.pm:705 lib/RT/Group_Overlay.pm:711 lib/RT/Group_Overlay.pm:904 lib/RT/Group_Overlay.pm:908 lib/RT/Group_Overlay.pm:921 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:126 lib/RT/Scrip_Overlay.pm:137 lib/RT/Scrip_Overlay.pm:197 lib/RT/Scrip_Overlay.pm:430 lib/RT/Template_Overlay.pm:284 lib/RT/Template_Overlay.pm:88 lib/RT/Template_Overlay.pm:94 lib/RT/Ticket_Overlay.pm:1341 lib/RT/Ticket_Overlay.pm:1351 lib/RT/Ticket_Overlay.pm:1365 lib/RT/Ticket_Overlay.pm:1518 lib/RT/Ticket_Overlay.pm:1527 lib/RT/Ticket_Overlay.pm:1540 lib/RT/Ticket_Overlay.pm:1875 lib/RT/Ticket_Overlay.pm:2013 lib/RT/Ticket_Overlay.pm:2177 lib/RT/Ticket_Overlay.pm:2244 lib/RT/Ticket_Overlay.pm:2596 lib/RT/Ticket_Overlay.pm:2668 lib/RT/Ticket_Overlay.pm:2762 lib/RT/Ticket_Overlay.pm:2777 lib/RT/Ticket_Overlay.pm:2910 lib/RT/Ticket_Overlay.pm:3139 lib/RT/Ticket_Overlay.pm:3337 lib/RT/Ticket_Overlay.pm:3499 lib/RT/Ticket_Overlay.pm:3551 lib/RT/Ticket_Overlay.pm:3716 lib/RT/Transaction_Overlay.pm:468 lib/RT/Transaction_Overlay.pm:475 lib/RT/Transaction_Overlay.pm:504 lib/RT/Transaction_Overlay.pm:511 lib/RT/User_Overlay.pm:1334 lib/RT/User_Overlay.pm:562 lib/RT/User_Overlay.pm:597 lib/RT/User_Overlay.pm:853 lib/RT/User_Overlay.pm:941
+msgid "Permission Denied"
+msgstr "В доступе отказано"
+
+#: html/User/Elements/Tabs:35
+msgid "Personal Groups"
+msgstr ""
+
+#: html/User/Groups/index.html:30 html/User/Groups/index.html:40
+msgid "Personal groups"
+msgstr "Личные группы"
+
+#: html/User/Elements/DelegateRights:37
+msgid "Personal groups:"
+msgstr "Личные группы:"
+
+#: html/Admin/Users/Modify.html:156 html/User/Prefs.html:49
+msgid "Phone numbers"
+msgstr "Номера телефонов"
+
+#: html/Admin/Users/Rights.html:25
+msgid "Placeholder"
+msgstr "Заполнитель"
+
+#: NOT FOUND IN SOURCE
+msgid "Pref"
+msgstr ""
+
+#: html/Elements/Header:52 html/Elements/Tabs:55 html/SelfService/Prefs.html:25 html/User/Prefs.html:25 html/User/Prefs.html:28
+msgid "Preferences"
+msgstr "Предпочтения"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr "Предпочтения"
+
+#: lib/RT/Action/Generic.pm:160
+msgid "Prepare Stubbed"
+msgstr "Подготовка не реализована"
+
+#: html/Ticket/Elements/Tabs:61
+msgid "Prev"
+msgstr "Назад"
+
+#: html/Search/Listing.html:44
+msgid "Previous page"
+msgstr "Предыдущая страница"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr "Приоритет"
+
+#: lib/RT/ACE_Overlay.pm:133 lib/RT/ACE_Overlay.pm:208 lib/RT/ACE_Overlay.pm:552
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:54 html/SelfService/Display.html:76 html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:54 html/Ticket/Elements/ShowBasics:39 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "Приоритет"
+
+#: html/Admin/Elements/ModifyQueue:51 html/Admin/Queues/Modify.html:65
+msgid "Priority starts at"
+msgstr "Приоритет начинается с"
+
+#: etc/initialdata:25
+msgid "Privileged"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:271 html/User/Prefs.html:163
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr "Состояние полномочий: %1"
+
+#: html/Admin/Users/index.html:62
+msgid "Privileged users"
+msgstr "Полномочные пользователи"
+
+#: etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59
+msgid "Pseudogroup for internal use"
+msgstr ""
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Elements/Quicksearch:29 html/Search/Elements/PickRestriction:46 html/SelfService/Create.html:35 html/SelfService/Display.html:68 html/Ticket/Create.html:38 html/Ticket/Elements/EditBasics:64 html/Ticket/Elements/ShowBasics:43 html/User/Elements/DelegateRights:80 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "Очередь"
+
+#: html/Admin/Queues/CustomField.html:42 html/Admin/Queues/Scrip.html:50 html/Admin/Queues/Scrips.html:46 html/Admin/Queues/Templates.html:43
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr "Не найдена очередь %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr "Не найдена очередь '%1'\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Keyword Selections"
+msgstr ""
+
+#: html/Admin/Elements/ModifyQueue:31 html/Admin/Queues/Modify.html:43
+msgid "Queue Name"
+msgstr "Имя очереди"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:263
+msgid "Queue already exists"
+msgstr "Очередь уже существует"
+
+#: lib/RT/Queue_Overlay.pm:272 lib/RT/Queue_Overlay.pm:278
+msgid "Queue could not be created"
+msgstr "Не могу создать очередь"
+
+#: html/Ticket/Create.html:209
+msgid "Queue could not be loaded."
+msgstr "Не могу загрузить очередь"
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:282
+msgid "Queue created"
+msgstr "Создана очередь"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue is not specified."
+msgstr ""
+
+#: html/SelfService/Display.html:129
+msgid "Queue not found"
+msgstr "Нет такой очереди"
+
+#: html/Admin/Elements/Tabs:38 html/Admin/index.html:35
+msgid "Queues"
+msgstr "Очереди"
+
+#: html/Elements/Login:34
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr "RT %1"
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr "RT %1 для %2"
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr "RT %1 от <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr ""
+
+#: html/Admin/index.html:25 html/Admin/index.html:26
+msgid "RT Administration"
+msgstr "Настройка RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr "Ошибка регистрации в RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr "Письмо возвращено RT: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr "Ошибка конфигурации RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr "Критическая ошибка RT: Сообщение не было сохранено!"
+
+#: html/Elements/Error:41 html/SelfService/Error.html:41
+msgid "RT Error"
+msgstr "Ошибка RT"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr "RT получил свое собственное сообщение (%1)"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Recieved mail (%1) from itself."
+msgstr ""
+
+#: html/SelfService/Closed.html:25
+msgid "RT Self Service / Closed Tickets"
+msgstr "Самообслуживание RT / Закрытые тикеты"
+
+#: html/index.html:25 html/index.html:28
+msgid "RT at a glance"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr "RT не может зарегистрировать вас"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr "RT не смог найти просителя во внешней базе данных"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr "RT не смог найти очередь: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr "RT не смог проверить эту подпись PGP. \\n"
+
+#: html/Elements/PageLayout:26
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr "RT выполнил ваши команды"
+
+#: html/Elements/Login:83
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "Все права на RT защищены и охраняются законом.  &copy; 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  ПО распространяется под <a href=\"http://www.gnu.org/copyleft/gpl.html\">Стандартной Общественной Лицензией GNU Версии 2.</a>"
+
+#: NOT FOUND IN SOURCE
+msgid "RT is &copy; Copyright 1996-2002 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr "RT считает, что это сообщение может быть возвратом"
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr "RT будет обрабатывать это сообщение как неподписанное.\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr "Командный режим RT требует использования подписи .PGP. Вы либо не подписали сообщение, либо ваша подпись не может быть проверена."
+
+#: html/Admin/Users/Modify.html:58 html/Admin/Users/Prefs.html:52 html/User/Prefs.html:44
+msgid "Real Name"
+msgstr "Имя"
+
+#: html/Admin/Elements/ModifyUser:48
+msgid "RealName"
+msgstr "Имя"
+
+#: html/Ticket/Create.html:185 html/Ticket/Elements/EditLinks:139 html/Ticket/Elements/EditLinks:94 html/Ticket/Elements/ShowLinks:63
+msgid "Referred to by"
+msgstr "На него ссылаются"
+
+#: html/Elements/SelectLinkType:28 html/Ticket/Create.html:184 html/Ticket/Elements/EditLinks:135 html/Ticket/Elements/EditLinks:80 html/Ticket/Elements/ShowLinks:55
+msgid "Refers to"
+msgstr "Ссылается на"
+
+#: NOT FOUND IN SOURCE
+msgid "RefersTo"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr "Улучшить"
+
+#: html/Search/Elements/PickRestriction:27
+msgid "Refine search"
+msgstr "Улучшить поиск"
+
+#: html/Elements/Refresh:36
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "Обновлять эту страницу каждые %1 минут."
+
+#: html/Ticket/Create.html:174 html/Ticket/Elements/ShowSummary:60 html/Ticket/ModifyAll.html:57
+msgid "Relationships"
+msgstr "Связи"
+
+#: html/Search/Bulk.html:93
+msgid "Remove AdminCc"
+msgstr "Удалить административную копию"
+
+#: html/Search/Bulk.html:91
+msgid "Remove Cc"
+msgstr "Удалить копию"
+
+#: html/Search/Bulk.html:89
+msgid "Remove Requestor"
+msgstr "Удалить просителя"
+
+#: html/Ticket/Elements/ShowTransaction:173 html/Ticket/Elements/Tabs:122
+msgid "Reply"
+msgstr "Ответить"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Reply to tickets"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "ReplyToTicket"
+msgstr ""
+
+#: etc/initialdata:44 html/Ticket/Update.html:40 lib/RT/ACE_Overlay.pm:87
+msgid "Requestor"
+msgstr "Проситель"
+
+#: html/Search/Elements/PickRestriction:38
+msgid "Requestor email address"
+msgstr "Email просителя"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "RequestorAddresses"
+msgstr ""
+
+#: html/SelfService/Create.html:43 html/SelfService/Display.html:42 html/Ticket/Create.html:56 html/Ticket/Elements/EditPeople:48 html/Ticket/Elements/ShowPeople:31
+msgid "Requestors"
+msgstr "Просители"
+
+#: html/Admin/Elements/ModifyQueue:61 html/Admin/Queues/Modify.html:75
+msgid "Requests should be due in"
+msgstr "Запросы должны быть обработаны за"
+
+#: html/Elements/Submit:62
+msgid "Reset"
+msgstr "Очистить"
+
+#: html/Admin/Users/Modify.html:159 html/User/Prefs.html:50
+msgid "Residence"
+msgstr "Домашний"
+
+#: html/Ticket/Elements/Tabs:132
+msgid "Resolve"
+msgstr "Закрыть"
+
+#: html/Ticket/Update.html:133
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr ""
+
+#: etc/initialdata:302 html/Elements/SelectDateType:28 lib/RT/Ticket_Overlay.pm:1170
+msgid "Resolved"
+msgstr "Закрыт"
+
+#: html/Search/Bulk.html:123 html/Ticket/ModifyAll.html:73 html/Ticket/Update.html:73
+msgid "Response to requestors"
+msgstr "Ответ просителям"
+
+#: html/Elements/ListActions:26
+msgid "Results"
+msgstr "Отчет"
+
+#: html/Search/Elements/PickRestriction:105
+msgid "Results per page"
+msgstr "Тикетов на страницу"
+
+#: html/Admin/Elements/ModifyUser:33 html/Admin/Users/Modify.html:100 html/User/Prefs.html:72
+msgid "Retype Password"
+msgstr "Повторите пароль"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr "Право %1 не найдено для %2  %3 в рамках %4 (%5)\\n"
+
+#: lib/RT/ACE_Overlay.pm:613
+msgid "Right Delegated"
+msgstr "Право делегировано"
+
+#: lib/RT/ACE_Overlay.pm:303
+msgid "Right Granted"
+msgstr "Право выдано"
+
+#: lib/RT/ACE_Overlay.pm:161
+msgid "Right Loaded"
+msgstr "Право загружено"
+
+#: lib/RT/ACE_Overlay.pm:678 lib/RT/ACE_Overlay.pm:693
+msgid "Right could not be revoked"
+msgstr "Право не может быть отобрано"
+
+#: html/User/Delegation.html:64
+msgid "Right not found"
+msgstr "Право не найдено"
+
+#: lib/RT/ACE_Overlay.pm:543 lib/RT/ACE_Overlay.pm:638
+msgid "Right not loaded."
+msgstr "Право не загружено"
+
+#: lib/RT/ACE_Overlay.pm:689
+msgid "Right revoked"
+msgstr "Право отобрано"
+
+#: html/Admin/Elements/UserTabs:41
+msgid "Rights"
+msgstr "Права"
+
+#: lib/RT/Interface/Web.pm:758
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:791
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr ""
+
+#: html/Admin/Global/GroupRights.html:51 html/Admin/Queues/GroupRights.html:52
+msgid "Roles"
+msgstr "Псевдо-группы"
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr ""
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "Суб."
+
+#: html/Admin/Queues/People.html:105 html/Ticket/Modify.html:39 html/Ticket/ModifyAll.html:94 html/Ticket/ModifyPeople.html:38
+msgid "Save Changes"
+msgstr "Сохранить изменения"
+
+#: html/Ticket/ModifyLinks.html:39
+msgid "Save changes"
+msgstr "Сохранить изменения"
+
+#: html/Admin/Global/Scrip.html:49
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:176
+msgid "Scrip Created"
+msgstr "Создан скрипт"
+
+#: html/Admin/Elements/EditScrips:84
+msgid "Scrip deleted"
+msgstr "Удален скрипт"
+
+#: html/Admin/Elements/QueueTabs:46 html/Admin/Elements/SystemTabs:33 html/Admin/Global/index.html:41
+msgid "Scrips"
+msgstr "Скрипты"
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr "Скрипты для %1\\n"
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr "Скрипты, которые действуют для всех очередей"
+
+#: html/Elements/SimpleSearch:27 html/Search/Elements/PickRestriction:126 html/Ticket/Elements/Tabs:159
+msgid "Search"
+msgstr "Поиск"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr "Параметры поиска"
+
+#: html/Approvals/Elements/PendingMyApproval:39
+msgid "Search for approvals"
+msgstr "Искать визы"
+
+#: bin/rt-crontool:188
+msgid "Security:"
+msgstr "Безопасность:"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "SeeQueue"
+msgstr ""
+
+#: html/Admin/Groups/index.html:40
+msgid "Select a group"
+msgstr "Выбор группы"
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr "Выбор очереди"
+
+#: html/Admin/Users/index.html:25 html/Admin/Users/index.html:28
+msgid "Select a user"
+msgstr "Выбор пользователя"
+
+#: html/Admin/Global/CustomField.html:38 html/Admin/Global/CustomFields.html:36
+msgid "Select custom field"
+msgstr ""
+
+#: html/Admin/Elements/GroupTabs:52 html/User/Elements/GroupTabs:50
+msgid "Select group"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:355
+msgid "Select multiple values"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:352
+msgid "Select one value"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:67
+msgid "Select queue"
+msgstr ""
+
+#: html/Admin/Global/Scrip.html:37 html/Admin/Global/Scrips.html:36 html/Admin/Queues/Scrip.html:40 html/Admin/Queues/Scrips.html:50
+msgid "Select scrip"
+msgstr ""
+
+#: html/Admin/Global/Template.html:57 html/Admin/Global/Templates.html:36 html/Admin/Queues/Template.html:55
+msgid "Select template"
+msgstr ""
+
+#: html/Admin/Elements/UserTabs:49
+msgid "Select user"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "SelectMultiple"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectSingle"
+msgstr ""
+
+#: html/SelfService/index.html:25
+msgid "Self Service"
+msgstr "Самообслуживание"
+
+#: etc/initialdata:114
+msgid "Send mail to all watchers"
+msgstr ""
+
+#: etc/initialdata:110
+msgid "Send mail to all watchers as a \"comment\""
+msgstr ""
+
+#: etc/initialdata:105
+msgid "Send mail to requestors and Ccs"
+msgstr ""
+
+#: etc/initialdata:100
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr ""
+
+#: etc/initialdata:79
+msgid "Sends a message to the requestors"
+msgstr ""
+
+#: etc/initialdata:118 etc/initialdata:122
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr ""
+
+#: etc/initialdata:95
+msgid "Sends mail to the administrative Ccs"
+msgstr ""
+
+#: etc/initialdata:91
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr ""
+
+#: etc/initialdata:83 etc/initialdata:87
+msgid "Sends mail to the owner"
+msgstr ""
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "Сен."
+
+#: NOT FOUND IN SOURCE
+msgid "September"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr "Искать"
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show approved requests"
+msgstr "Показать завизированные запросы"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show basics"
+msgstr "Показать главное"
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show denied requests"
+msgstr "Показать отвергнутые запросы"
+
+#: html/Ticket/Create.html:144 html/Ticket/Create.html:34
+msgid "Show details"
+msgstr "Показать все"
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show pending requests"
+msgstr "Показать ожидающие запросы"
+
+#: html/Approvals/Elements/PendingMyApproval:46
+msgid "Show requests awaiting other approvals"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Show ticket private commentary"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "Show ticket summaries"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ShowACL"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowScrips"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ShowTemplate"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:79
+msgid "ShowTicket"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "ShowTicketComments"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr ""
+
+#: html/Admin/Elements/ModifyUser:39 html/Admin/Users/Modify.html:191 html/Admin/Users/Prefs.html:32 html/SelfService/Prefs.html:37 html/User/Prefs.html:112
+msgid "Signature"
+msgstr "Подпись"
+
+#: html/SelfService/Elements/Header:52
+#. ($session{'CurrentUser'}->Name)
+msgid "Signed in as %1"
+msgstr ""
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Single"
+msgstr "Одно значение"
+
+#: html/Elements/Header:51
+msgid "Skip Menu"
+msgstr ""
+
+#: html/Admin/Elements/EditCustomFieldValues:31
+msgid "Sort key"
+msgstr "Ключ для сортировки"
+
+#: html/Search/Elements/PickRestriction:109
+msgid "Sort results by"
+msgstr "Сортировать по полю"
+
+#: html/Admin/Elements/AddCustomFieldValue:25
+msgid "SortOrder"
+msgstr "Порядок сортировки"
+
+#: NOT FOUND IN SOURCE
+msgid "Stalled"
+msgstr "Отложенных"
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr "Начальная страница"
+
+#: html/Elements/SelectDateType:27 html/Ticket/Elements/EditDates:32 html/Ticket/Elements/ShowDates:35
+msgid "Started"
+msgstr "Начался"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr "Не могу разобрать дату 'Начался': '%1'"
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:27 html/Ticket/Elements/ShowDates:31
+msgid "Starts"
+msgstr "Начнется"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr "Запуски"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr "Не могу разобрать дату 'Запуски': '%1'"
+
+#: html/Admin/Elements/ModifyUser:82 html/Admin/Users/Modify.html:138 html/User/Prefs.html:94
+msgid "State"
+msgstr "Состояние"
+
+#: html/Elements/MyRequests:31 html/Elements/MyTickets:31 html/Search/Elements/PickRestriction:74 html/SelfService/Display.html:59 html/SelfService/Elements/MyRequests:29 html/SelfService/Update.html:31 html/Ticket/Create.html:42 html/Ticket/Elements/EditBasics:38 html/Ticket/Elements/ShowBasics:31 html/Ticket/Update.html:60 lib/RT/Ticket_Overlay.pm:1164 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "Статус"
+
+#: etc/initialdata:288
+msgid "Status Change"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:530
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr "Статус изменен с %1 на %2"
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr ""
+
+#: html/Ticket/Elements/Tabs:147
+msgid "Steal"
+msgstr "Отобрать"
+
+#: lib/RT/Transaction_Overlay.pm:589
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "Отобран у %1"
+
+#: html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Search/Bulk.html:126 html/Search/Elements/PickRestriction:43 html/SelfService/Create.html:59 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:35 html/Ticket/Create.html:84 html/Ticket/Elements/EditBasics:28 html/Ticket/ModifyAll.html:79 html/Ticket/Update.html:77 lib/RT/Ticket_Overlay.pm:1160 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "Тема"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:611
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr ""
+
+#: html/Elements/Submit:59
+msgid "Submit"
+msgstr "Готово"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:749
+msgid "Succeeded"
+msgstr ""
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "Вск."
+
+#: lib/RT/System.pm:54
+msgid "SuperUser"
+msgstr ""
+
+#: html/User/Elements/DelegateRights:77
+msgid "System"
+msgstr ""
+
+#: html/Admin/Elements/SelectRights:81 lib/RT/ACE_Overlay.pm:567 lib/RT/Interface/Web.pm:757 lib/RT/Interface/Web.pm:790
+msgid "System Error"
+msgstr "Ошибка системы"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. Right not granted."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. right not granted"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:616
+msgid "System error. Right not delegated."
+msgstr "Ошибка системы. Право не было делегировано."
+
+#: lib/RT/ACE_Overlay.pm:146 lib/RT/ACE_Overlay.pm:223 lib/RT/ACE_Overlay.pm:306 lib/RT/ACE_Overlay.pm:898
+msgid "System error. Right not granted."
+msgstr "Ошибка системы. Право не было выдано."
+
+#: NOT FOUND IN SOURCE
+msgid "System error. Unable to grant rights."
+msgstr ""
+
+#: html/Admin/Global/GroupRights.html:35 html/Admin/Groups/GroupRights.html:37 html/Admin/Queues/GroupRights.html:36
+msgid "System groups"
+msgstr "Системные группы"
+
+#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53
+msgid "SystemRolegroup for internal use"
+msgstr ""
+
+#: lib/RT/CurrentUser.pm:320
+msgid "TEST_STRING"
+msgstr "TEST_STRING"
+
+#: html/Ticket/Elements/Tabs:143
+msgid "Take"
+msgstr "Взять"
+
+#: lib/RT/Transaction_Overlay.pm:575
+msgid "Taken"
+msgstr "Взят"
+
+#: html/Admin/Elements/EditScrip:81
+msgid "Template"
+msgstr "Шаблон"
+
+#: html/Admin/Global/Template.html:91 html/Admin/Queues/Template.html:90
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr ""
+
+#: html/Admin/Elements/EditTemplates:89
+msgid "Template deleted"
+msgstr ""
+
+#: lib/RT/Scrip_Overlay.pm:153
+msgid "Template not found"
+msgstr "Шаблон не найден"
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr "Шаблон не найден\\n"
+
+#: lib/RT/Template_Overlay.pm:347
+msgid "Template parsed"
+msgstr "Шаблон обработан"
+
+#: html/Admin/Elements/QueueTabs:49 html/Admin/Elements/SystemTabs:36 html/Admin/Global/index.html:45
+msgid "Templates"
+msgstr "Шаблоны"
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr "Шаблоны для %1\\n"
+
+#: lib/RT/Interface/Web.pm:858
+msgid "That is already the current value"
+msgstr ""
+
+#: lib/RT/CustomField_Overlay.pm:178
+msgid "That is not a value for this custom field"
+msgstr "Это поле не может иметь такого значения"
+
+#: lib/RT/Ticket_Overlay.pm:1886
+msgid "That is the same value"
+msgstr "Значение не изменилось"
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr "Этот пользователь уже %1 для этой очереди"
+
+#: lib/RT/Ticket_Overlay.pm:1434
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr "Этот пользователь уже %1 для этого тикета"
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr "Этот пользователь не %1 этой очереди"
+
+#: lib/RT/Ticket_Overlay.pm:1551
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr "Этот пользователь не %1 этому тикету"
+
+#: lib/RT/Ticket_Overlay.pm:1882
+msgid "That queue does not exist"
+msgstr "Этой очереди не существует"
+
+#: lib/RT/Ticket_Overlay.pm:3143
+msgid "That ticket has unresolved dependencies"
+msgstr "Этот тикет имеет неразрешенные зависимости"
+
+#: lib/RT/ACE_Overlay.pm:288 lib/RT/ACE_Overlay.pm:597
+msgid "That user already has that right"
+msgstr "Пользователь уже имеет это право"
+
+#: lib/RT/Ticket_Overlay.pm:2952
+msgid "That user already owns that ticket"
+msgstr "Пользователь уже владеет этим тикетом"
+
+#: lib/RT/Ticket_Overlay.pm:2918
+msgid "That user does not exist"
+msgstr "Пользователь не существует"
+
+#: lib/RT/User_Overlay.pm:315
+msgid "That user is already privileged"
+msgstr "Этот пользователь уже имеет все полномочия"
+
+#: lib/RT/User_Overlay.pm:332
+msgid "That user is already unprivileged"
+msgstr "Этот пользователь уже не имеет полномочий"
+
+#: lib/RT/User_Overlay.pm:327
+msgid "That user is now privileged"
+msgstr "Этот пользователь теперь имеет все полномочия"
+
+#: lib/RT/User_Overlay.pm:344
+msgid "That user is now unprivileged"
+msgstr "Этот пользователь теперь не имеет полномочий"
+
+#: NOT FOUND IN SOURCE
+msgid "That user is now unprivilegedileged"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2944
+msgid "That user may not own tickets in that queue"
+msgstr "Этот пользователь не может владеть тикетами из этой очереди"
+
+#: lib/RT/Link_Overlay.pm:206
+msgid "That's not a numerical id"
+msgstr "Это не числовой идентификатор"
+
+#: html/Ticket/Create.html:150 html/Ticket/Elements/ShowSummary:28
+msgid "The Basics"
+msgstr "Главное"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The CC of a ticket"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:89
+msgid "The administrative CC of a ticket"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:2213
+msgid "The comment has been recorded"
+msgstr "Записан комментарий"
+
+#: bin/rt-crontool:198
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr ""
+
+#: bin/rt-commit-handler:756 bin/rt-commit-handler:766
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr "Эти команды не были исполнены:\\n\\n"
+
+#: lib/RT/Interface/Web.pm:861
+msgid "The new value has been set."
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The owner of a ticket"
+msgstr ""
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The requestor of a ticket"
+msgstr ""
+
+#: html/Admin/Elements/EditUserComments:26
+msgid "These comments aren't generally visible to the user"
+msgstr "Эти комментарии не показываются обыкновенному пользователю"
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr "Этот тикет %1 %2 (%3)\\n"
+
+#: bin/rt-crontool:189
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr "Этот инструмент позволяет пользователю запускать некоторые модули Perl из RT."
+
+#: lib/RT/Transaction_Overlay.pm:253
+msgid "This transaction appears to have no content"
+msgstr "Похоже, что эта транзакция не имеет информации"
+
+#: html/Ticket/Elements/ShowRequestor:47
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr "25 важнейших тикетов пользователя..."
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "Чтв."
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr "Тикет # %1  %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1 Jumbo update: %2"
+msgstr ""
+
+#: html/Ticket/ModifyAll.html:25 html/Ticket/ModifyAll.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "Тикет #%1 Обновление всего: %2"
+
+#: html/Approvals/Elements/ShowDependency:46
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:608
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr "Тикет %1 создан в очереди '%2'"
+
+#: bin/rt-commit-handler:760
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr "Загружен тикет %1\\n"
+
+#: html/Search/Bulk.html:181
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr "Тикет %1: %2"
+
+#: html/Ticket/History.html:25 html/Ticket/History.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr "История тикета # %1 %2"
+
+#: html/SelfService/Display.html:34
+msgid "Ticket Id"
+msgstr "Тикет #"
+
+#: etc/initialdata:303
+msgid "Ticket Resolved"
+msgstr ""
+
+#: html/Search/Elements/PickRestriction:63
+msgid "Ticket attachment"
+msgstr "Для вложений"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr "Текст тикета"
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr "Тип данных тикета"
+
+#: lib/RT/Ticket_Overlay.pm:495 lib/RT/Ticket_Overlay.pm:597
+msgid "Ticket could not be created due to an internal error"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:522
+msgid "Ticket created"
+msgstr "Создан тикет"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr "Не удалось создать тикет"
+
+#: lib/RT/Transaction_Overlay.pm:527
+msgid "Ticket deleted"
+msgstr "Тикет удален"
+
+#: html/REST/1.0/modify:29 html/REST/1.0/update:34
+msgid "Ticket id not found"
+msgstr "Идентификатор тикета не найден"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket killed"
+msgstr ""
+
+#: html/REST/1.0/modify:36 html/REST/1.0/update:41
+msgid "Ticket not found"
+msgstr "Тикет не найден"
+
+#: etc/initialdata:289
+msgid "Ticket status changed"
+msgstr ""
+
+#: html/Ticket/Update.html:39
+msgid "Ticket watchers"
+msgstr "Наблюдатели для тикета"
+
+#: html/Elements/Tabs:49
+msgid "Tickets"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr ""
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr ""
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Tickets from %1"
+msgstr "Тикеты от %1"
+
+#: html/Approvals/Elements/ShowDependency:27
+msgid "Tickets which depend on this approval:"
+msgstr "От этой визы зависят следующие тикеты:"
+
+#: html/Ticket/Create.html:157 html/Ticket/Elements/EditBasics:48
+msgid "Time Left"
+msgstr "Осталось"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:43
+msgid "Time Worked"
+msgstr "В работе"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "Осталось"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "Время для показа"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "В работе"
+
+#: NOT FOUND IN SOURCE
+msgid "TimeLeft"
+msgstr ""
+
+#: lib/RT/Ticket_Overlay.pm:1165
+msgid "TimeWorked"
+msgstr ""
+
+#: bin/rt-commit-handler:402
+msgid "To generate a diff of this commit:"
+msgstr "Для генерации дифа этого коммита:"
+
+#: bin/rt-commit-handler:391
+msgid "To generate a diff of this commit:\\n"
+msgstr "Для генерации дифа этого коммита:\\n"
+
+#: lib/RT/Ticket_Overlay.pm:1168
+msgid "Told"
+msgstr "Контакт"
+
+#: etc/initialdata:237
+msgid "Transaction"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:642
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr "Транзакция %1 удалена"
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr "Создана транзакция"
+
+#: lib/RT/Transaction_Overlay.pm:89
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:701
+msgid "Transactions are immutable"
+msgstr "Транзакции не изменены"
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr "Пытаемся удалить право: %1"
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "Втр."
+
+#: html/Admin/Elements/EditCustomField:34 html/Ticket/Elements/AddWatchers:33 html/Ticket/Elements/AddWatchers:44 html/Ticket/Elements/AddWatchers:54 lib/RT/Ticket_Overlay.pm:1166 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "Тип"
+
+#: lib/RT/ScripCondition_Overlay.pm:104
+msgid "Unimplemented"
+msgstr "Не реализовано"
+
+#: html/Admin/Users/Modify.html:68
+msgid "Unix login"
+msgstr "Логин UNIX"
+
+#: html/Admin/Elements/ModifyUser:62
+msgid "UnixUsername"
+msgstr "Имя пользователя UNIX"
+
+#: lib/RT/Attachment_Overlay.pm:265
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr "Неизвестная кодировка %1"
+
+#: html/Elements/SelectResultsPerPage:37
+msgid "Unlimited"
+msgstr "Не ограничено"
+
+#: etc/initialdata:32
+msgid "Unprivileged"
+msgstr ""
+
+#: lib/RT/Transaction_Overlay.pm:571
+msgid "Untaken"
+msgstr "Ничей"
+
+#: html/Elements/MyTickets:64 html/Search/Bulk.html:33
+msgid "Update"
+msgstr "Обновить"
+
+#: html/Admin/Users/Prefs.html:62
+msgid "Update ID"
+msgstr "Обновить идентификатор"
+
+#: html/Search/Bulk.html:120 html/Ticket/ModifyAll.html:66 html/Ticket/Update.html:67
+msgid "Update Type"
+msgstr "Обновить тип"
+
+#: html/Search/Listing.html:61
+msgid "Update all these tickets at once"
+msgstr "Изменить одним махом"
+
+#: html/Admin/Users/Prefs.html:49
+msgid "Update email"
+msgstr "Обновить e-mail"
+
+#: html/Admin/Users/Prefs.html:55
+msgid "Update name"
+msgstr "Обновить имя"
+
+#: lib/RT/Interface/Web.pm:375
+msgid "Update not recorded."
+msgstr "Изменения не сохранены."
+
+#: html/Search/Bulk.html:81
+msgid "Update selected tickets"
+msgstr "Изменить выбранные тикеты"
+
+#: html/Admin/Users/Prefs.html:36
+msgid "Update signature"
+msgstr "Обновить подпись"
+
+#: html/Ticket/ModifyAll.html:63
+msgid "Update ticket"
+msgstr "Обновить тикет"
+
+#: html/SelfService/Update.html:25 html/SelfService/Update.html:27
+#. ($Ticket->id)
+msgid "Update ticket # %1"
+msgstr "Обновить тикет # %1"
+
+#: html/SelfService/Update.html:50
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr "Обновить тикет # %1"
+
+#: html/Ticket/Update.html:135
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr ""
+
+#: lib/RT/Interface/Web.pm:373
+msgid "Update type was neither correspondence nor comment."
+msgstr "Обновление не было ни сообщением, ни комментарием."
+
+#: html/Elements/SelectDateType:33 html/Ticket/Elements/ShowDates:51 lib/RT/Ticket_Overlay.pm:1169
+msgid "Updated"
+msgstr "Обновлен"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr "Пользователь %1 %2: %3\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr "Пользователь %1 Пароль: %2\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr "Пользователь '%1' не найден"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr "Пользователь '%1' не найден\\n"
+
+#: etc/initialdata:125 etc/initialdata:191
+msgid "User Defined"
+msgstr ""
+
+#: html/Admin/Users/Prefs.html:59
+msgid "User ID"
+msgstr "Логин"
+
+#: html/Elements/SelectUsers:26
+msgid "User Id"
+msgstr "Логин"
+
+#: html/Admin/Elements/GroupTabs:47 html/Admin/Elements/QueueTabs:60 html/Admin/Elements/SystemTabs:47 html/Admin/Global/index.html:59
+msgid "User Rights"
+msgstr "Права пользователя"
+
+#: html/Admin/Users/Modify.html:226
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr "Не могу создать пользователя: %1"
+
+#: lib/RT/User_Overlay.pm:262
+msgid "User created"
+msgstr "Создан пользователь"
+
+#: html/Admin/Global/GroupRights.html:67 html/Admin/Groups/GroupRights.html:54 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr "Группы, определенные пользователем"
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr "Пользователю отослано напоминание"
+
+#: html/Admin/Users/Prefs.html:25 html/Admin/Users/Prefs.html:29
+msgid "User view"
+msgstr "Пользовательские настройки"
+
+#: html/Admin/Users/Modify.html:48 html/Elements/Login:42 html/Ticket/Elements/AddWatchers:35
+msgid "Username"
+msgstr "Логин"
+
+#: html/Admin/Elements/SelectNewGroupMembers:26 html/Admin/Elements/Tabs:32 html/Admin/Groups/Members.html:55 html/Admin/Queues/People.html:68 html/Admin/index.html:29 html/User/Groups/Members.html:58
+msgid "Users"
+msgstr "Пользователи"
+
+#: html/Admin/Users/index.html:65
+msgid "Users matching search criteria"
+msgstr "Найдены пользователи"
+
+#: html/Search/Elements/PickRestriction:51
+msgid "ValueOfQueue"
+msgstr "ValueOfQueue"
+
+#: html/Admin/Elements/EditCustomField:40
+msgid "Values"
+msgstr "Значения"
+
+#: NOT FOUND IN SOURCE
+msgid "VrijevormEnkele"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Watch"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "WatchAsAdminCc"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Watcher loaded"
+msgstr ""
+
+#: html/Admin/Elements/QueueTabs:42
+msgid "Watchers"
+msgstr "Наблюдатели"
+
+#: html/Admin/Elements/ModifyUser:56
+msgid "WebEncoding"
+msgstr "WebEncoding"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "Срд."
+
+#: etc/upgrade/2.1.71:161
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr ""
+
+#: etc/upgrade/2.1.71:135
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr ""
+
+#: etc/initialdata:138
+msgid "When a ticket is created"
+msgstr ""
+
+#: etc/upgrade/2.1.71:79
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr ""
+
+#: etc/initialdata:143
+msgid "When anything happens"
+msgstr ""
+
+#: etc/initialdata:184
+msgid "Whenever a ticket is resolved"
+msgstr ""
+
+#: etc/initialdata:170
+msgid "Whenever a ticket's owner changes"
+msgstr ""
+
+#: etc/initialdata:178
+msgid "Whenever a ticket's queue changes"
+msgstr ""
+
+#: etc/initialdata:162
+msgid "Whenever a ticket's status changes"
+msgstr ""
+
+#: etc/initialdata:192
+msgid "Whenever a user-defined condition occurs"
+msgstr ""
+
+#: etc/initialdata:156
+msgid "Whenever comments come in"
+msgstr ""
+
+#: etc/initialdata:149
+msgid "Whenever correspondence comes in"
+msgstr ""
+
+#: html/Admin/Users/Modify.html:164 html/User/Prefs.html:52
+msgid "Work"
+msgstr "Рабочий"
+
+#: html/Admin/Elements/ModifyUser:70
+msgid "WorkPhone"
+msgstr "Рабочий"
+
+#: html/SelfService/Display.html:86 html/Ticket/Elements/ShowBasics:35 html/Ticket/Update.html:65
+msgid "Worked"
+msgstr "В работе"
+
+#: lib/RT/Ticket_Overlay.pm:3056
+msgid "You already own this ticket"
+msgstr "Вы уже владеете этим тикетом"
+
+#: html/autohandler:121
+msgid "You are not an authorized user"
+msgstr "Вам сюда запрещено"
+
+#: lib/RT/Ticket_Overlay.pm:2930
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "Вы можете назначать владельца только для своих или ничьих тикетов."
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr "У вас нет права на просмотр этого тикета.\\n"
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "You found %1 tickets in queue %2"
+
+#: html/NoAuth/Logout.html:31 html/REST/1.0/logout:25
+msgid "You have been logged out of RT."
+msgstr "Вы вышли из RT."
+
+#: html/SelfService/Display.html:134
+msgid "You have no permission to create tickets in that queue."
+msgstr "У вас нет права создавать тикеты в этой очереди."
+
+#: lib/RT/Ticket_Overlay.pm:1895
+msgid "You may not create requests in that queue."
+msgstr "Вы не можете создавать запросы в этой очереди."
+
+#: html/NoAuth/Logout.html:36
+msgid "You're welcome to login again"
+msgstr "Заходите еще"
+
+#: html/SelfService/Elements/MyRequests:25
+#. ($friendly_status)
+msgid "Your %1 requests"
+msgstr "Ваши запросы: %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr "Администратор RT неправильно настроил почтовые алиасы"
+
+#: etc/initialdata:429 etc/upgrade/2.1.71:146
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr ""
+
+#: etc/initialdata:463 etc/upgrade/2.1.71:180
+msgid "Your request has been approved."
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr ""
+
+#: etc/initialdata:384 etc/upgrade/2.1.71:101
+msgid "Your request was rejected."
+msgstr ""
+
+#: html/autohandler:136 html/autohandler:142
+msgid "Your username or password is incorrect"
+msgstr "Вы ввели неверное имя или пароль"
+
+#: html/Admin/Elements/ModifyUser:84 html/Admin/Users/Modify.html:144 html/User/Prefs.html:96
+msgid "Zip"
+msgstr "Индекс"
+
+#: NOT FOUND IN SOURCE
+msgid "[no subject]"
+msgstr ""
+
+#: html/User/Elements/DelegateRights:59
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "с правами %1"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:34
+msgid "contains"
+msgstr "содержит"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content"
+msgstr "данные"
+
+#: html/Elements/SelectAttachmentField:27
+msgid "content-type"
+msgstr "тип данных"
+
+#: lib/RT/Ticket_Overlay.pm:2282
+msgid "correspondence (probably) not sent"
+msgstr "сообщение (возможно) не отправлено"
+
+#: lib/RT/Ticket_Overlay.pm:2292
+msgid "correspondence sent"
+msgstr "отправлено сообщение"
+
+#: html/Admin/Elements/ModifyQueue:63 html/Admin/Queues/Modify.html:77 lib/RT/Date.pm:319
+msgid "days"
+msgstr "дней"
+
+#: NOT FOUND IN SOURCE
+msgid "dead"
+msgstr ""
+
+#: html/Search/Listing.html:75
+msgid "delete"
+msgstr "удалить"
+
+#: lib/RT/Queue_Overlay.pm:63
+msgid "deleted"
+msgstr "удален"
+
+#: html/Search/Elements/PickRestriction:68
+msgid "does not match"
+msgstr "не совпадает"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:35
+msgid "doesn't contain"
+msgstr "не содержит"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "equal to"
+msgstr "равняется"
+
+#: NOT FOUND IN SOURCE
+msgid "false"
+msgstr ""
+
+#: html/Elements/SelectAttachmentField:28
+msgid "filename"
+msgstr "имя файла"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "greater than"
+msgstr "больше чем"
+
+#: lib/RT/Group_Overlay.pm:194
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "группа '%1'"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "часов"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr "идентификатор"
+
+#: html/Elements/SelectBoolean:32 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88
+msgid "is"
+msgstr "является"
+
+#: html/Elements/SelectBoolean:36 html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectMatch:37 html/Search/Elements/PickRestriction:48 html/Search/Elements/PickRestriction:77 html/Search/Elements/PickRestriction:89
+msgid "isn't"
+msgstr "не является"
+
+#: html/Elements/SelectCustomFieldOperator:38 html/Elements/SelectEqualityOperator:38
+msgid "less than"
+msgstr "меньше чем"
+
+#: html/Search/Elements/PickRestriction:67
+msgid "matches"
+msgstr "совпадает"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "мин"
+
+#: html/Ticket/Update.html:66
+msgid "minutes"
+msgstr "минут"
+
+#: bin/rt-commit-handler:765
+msgid "modifications\\n\\n"
+msgstr "изменения\\n\\n"
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "месяцев"
+
+#: lib/RT/Queue_Overlay.pm:58
+msgid "new"
+msgstr "новый"
+
+#: html/Admin/Elements/EditScrips:43
+msgid "no value"
+msgstr ""
+
+#: html/Ticket/Elements/EditWatchers:28
+msgid "none"
+msgstr "нет"
+
+#: html/Elements/SelectEqualityOperator:38
+msgid "not equal to"
+msgstr "не равен"
+
+#: NOT FOUND IN SOURCE
+msgid "notlike"
+msgstr ""
+
+#: lib/RT/Queue_Overlay.pm:59
+msgid "open"
+msgstr "открыт"
+
+#: lib/RT/Group_Overlay.pm:199
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr "личная группа '%1' для пользователя '%2'"
+
+#: lib/RT/Group_Overlay.pm:207
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr "очередь %1 %2"
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "rejected"
+msgstr "отклонен"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "resolved"
+msgstr "решен"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr "сек"
+
+#: lib/RT/Queue_Overlay.pm:60
+msgid "stalled"
+msgstr "отложен"
+
+#: lib/RT/Group_Overlay.pm:202
+#. ($self->Type)
+msgid "system %1"
+msgstr "система %1"
+
+#: lib/RT/Group_Overlay.pm:213
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr "системная группа '%1'"
+
+#: html/Elements/Error:42 html/SelfService/Error.html:42
+msgid "the calling component did not specify why"
+msgstr "вызывающий компонент не указал причину"
+
+#: lib/RT/Group_Overlay.pm:210
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr "тикет #%1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "true"
+msgstr ""
+
+#: lib/RT/Group_Overlay.pm:216
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr ""
+
+#: NOT FOUND IN SOURCE
+msgid "undescripbed group %1"
+msgstr "неописанная группа %1"
+
+#: lib/RT/Group_Overlay.pm:191
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr "пользователь %1"
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr "недель"
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr "с шаблоном %1"
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr "лет"
+
+#: NOT FOUND IN SOURCE
+msgid "ニックネーム"
+msgstr ""
+
diff --git a/rt/lib/RT/I18N/zh_cn.po b/rt/lib/RT/I18N/zh_cn.po
new file mode 100644 (file)
index 0000000..ededc1a
--- /dev/null
@@ -0,0 +1,6384 @@
+# Traditional Chinese localization catalog for Request Tracker (RT)
+msgid ""
+msgstr ""
+"Last-Translator: Autrijus Tang <autrijus@autrijus.org>\n"
+"Language-Team: Chinese <members@ourinet.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: html/Elements/MyRequests:27 html/Elements/MyTickets:27 html/Work/Elements/MyApprovals:8 html/Work/Elements/MyRequests:9 html/Work/Elements/MyTickets:9
+msgid "#"
+msgstr "#"
+
+#: NOT FOUND IN SOURCE
+msgid "#%1"
+msgstr "#%1"
+
+#: html/Approvals/Elements/Approve:26 html/Approvals/Elements/ShowDependency:49 html/SelfService/Display.html:24 html/Ticket/Display.html:25 html/Ticket/Display.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($Ticket->id, $Ticket->Subject)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr "#%1: %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%*(%1,group ticket)"
+msgstr "%*(%1) 件参与的申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "%*(%1,ticket) due"
+msgstr "%*(%1) 件限期完成的申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "%*(%1,unresolved ticket)"
+msgstr "%*(%1) 件尚未解决的申请单"
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr "%1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr "%1 %2 %3"
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr "%7-%2-%3 %4:%5:%6 %1"
+
+#: lib/RT/Ticket_Overlay.pm:3541 lib/RT/Transaction_Overlay.pm:557 lib/RT/Transaction_Overlay.pm:599
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 added"
+msgstr "%2 已新增为 %1"
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 %2 ago"
+msgstr "%1 %2 之前"
+
+#: lib/RT/Ticket_Overlay.pm:3547 lib/RT/Transaction_Overlay.pm:564
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 changed to %3"
+msgstr "%1 已从 %2 改为 %3"
+
+#: lib/RT/Ticket_Overlay.pm:3544 lib/RT/Transaction_Overlay.pm:560 lib/RT/Transaction_Overlay.pm:605
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 deleted"
+msgstr "%2 已自 %1 删除"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:157
+#. ($depth_str, $role_str, $group_str)
+msgid "%1 %2 of group %3"
+msgstr "%3 群组的 %1 %2"
+
+#: html/Admin/Elements/EditScrips:43 html/Admin/Elements/ListGlobalScrips:27
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 with template %3"
+msgstr "条件:%1 | 动作:%2 | 模板:%3"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 this ticket\\n"
+msgstr "%1 (%2) %3 这份申请单\\n"
+
+#: html/Search/Listing.html:56 html/Work/Search/index.html:28
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr "显示第 %1 - %2 笔"
+
+#: bin/rt-crontool:168 bin/rt-crontool:175 bin/rt-crontool:181
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - An argument to pass to %2"
+msgstr "%1 - 传递给 %2 的一个参数"
+
+#: bin/rt-crontool:184
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr "%1 - 将更新状态输出到 STDOUT"
+
+#: bin/rt-crontool:178
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr "%1 - 指定欲使用的动作模块"
+
+#: bin/rt-crontool:172
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr "%1 - 指定欲使用的条件模块"
+
+#: bin/rt-crontool:165
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr "%1 - 指定欲使用的查询模块"
+
+#: lib/RT/ScripAction_Overlay.pm:121
+#. ($self->Id)
+msgid "%1 ScripAction loaded"
+msgstr "加载手续 %1"
+
+#: html/Edit/Elements/Page:48
+#. (scalar $count)
+msgid "%1 Total"
+msgstr "共 %1 笔"
+
+#: lib/RT/Ticket_Overlay.pm:3574
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 added as a value for %2"
+msgstr "新增 %1 作为 %2 的值"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on"
+msgstr "别名 %1 需要可用的申请单编号"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on "
+msgstr "别名 %1 需要可用的申请单编号 "
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on (from %2) %3"
+msgstr "别名 %1 需要可用的申请单编号以处理 %3(出自 %2)"
+
+#: lib/RT/Link_Overlay.pm:116 lib/RT/Link_Overlay.pm:123
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 appears to be a local object, but can't be found in the database"
+msgstr "%1 看来是个本地对象,却不在数据库里"
+
+#: html/Ticket/Elements/ShowDates:51 lib/RT/Transaction_Overlay.pm:481
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 by %2"
+msgstr "%1 (%2)"
+
+#: lib/RT/Transaction_Overlay.pm:535 lib/RT/Transaction_Overlay.pm:624 lib/RT/Transaction_Overlay.pm:633 lib/RT/Transaction_Overlay.pm:636
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 changed from %2 to %3"
+msgstr "%1 的值从 %2 改为 %3"
+
+#: lib/RT/Interface/Web.pm:893
+msgid "%1 could not be set to %2."
+msgstr "无法将 %1 设定为 %2。"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr "%1 无法初始更新 (%2)\\n"
+
+#: lib/RT/Ticket_Overlay.pm:2839
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr "%1 无法将现况设成已解决。RT 数据库内容可能不一致。"
+
+#: html/Elements/MyTickets:24 html/Work/Elements/MyTickets:6
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr "前 %1 份待处理申请单..."
+
+#: html/Elements/MyRequests:24 html/Work/Elements/MyRequests:6
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr "前 %1 份送出的申请单..."
+
+#: html/Work/Elements/MyApprovals:5
+#. ($rows)
+msgid "%1 highest priority tickets pending my approval..."
+msgstr "前 %1 份待签核申请单..."
+
+#: bin/rt-crontool:160
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr "%1 是从外部排程程序(如 cron)来对申请单进行操作的工具。"
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr "%1 已不再是此表单的 %2。"
+
+#: lib/RT/Ticket_Overlay.pm:1578
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr "%1 已不再是此申请单的 %2。"
+
+#: lib/RT/Ticket_Overlay.pm:3630
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr "%1 已不再是自订字段 %2 的值。"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr "%1 不是一个合法的表单编号。"
+
+#: html/Ticket/Elements/ShowBasics:35
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr "%1 分钟"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr "没有显示 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 result(s) found"
+msgstr "找到 %1 项结果"
+
+#: html/User/Elements/DelegateRights:75
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr "%1权限"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr "%1 完成\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr "不知道 $MessageID 的 %1 类别"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr "不知道 %2 的 %1 类别"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 was created without a CurrentUser\\n"
+msgstr "%1 新增时未指定现行使用者"
+
+#: lib/RT/Action/ResolveMembers.pm:41
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr "%1 会解决在已解决群组里成员的申请单。"
+
+#: lib/RT/Action/StallDependent.pm:40
+#. (ref $self)
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr "如果 %1 起始申请单依赖于某个链接,或是某个链接的成员,它将会被延宕。"
+
+#: lib/RT/Transaction_Overlay.pm:433
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr "%1:未指定附件"
+
+#: html/Ticket/Elements/ShowTransaction:89 html/Work/Tickets/Elements/ShowTransaction:152
+#. ($size)
+msgid "%1b"
+msgstr "%1 字节"
+
+#: html/Ticket/Elements/ShowTransaction:86 html/Work/Tickets/Elements/ShowTransaction:149
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr "%1k 字节"
+
+#: NOT FOUND IN SOURCE
+msgid "%quant(%1,result) found"
+msgstr "找到 %1 项结果"
+
+#: lib/RT/Ticket_Overlay.pm:1148
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr "'%1' 不是一个合法的状态值"
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr "'%1'为无法辨识的动作。 "
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete group member)"
+msgstr "(点选欲删除的成员)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr "(点选欲删除的手续)"
+
+#: html/Admin/Elements/EditCustomFieldValues:24 html/Admin/Elements/EditQueueWatchers:28 html/Admin/Elements/EditScrips:34 html/Admin/Elements/EditTemplates:35 html/Admin/Elements/EditWorkflows:36 html/Admin/Groups/Members.html:51 html/Ticket/Elements/EditLinks:32 html/Ticket/Elements/EditPeople:45 html/User/Groups/Members.html:54
+msgid "(Check box to delete)"
+msgstr "(点选欲删除的项目)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check boxes to delete)"
+msgstr "(点选欲删除的项目)"
+
+#: html/Ticket/Create.html:177
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr "(键入申请单编号或网址,以空白分隔)"
+
+#: html/Admin/Queues/Modify.html:53 html/Admin/Queues/Modify.html:59
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr "(如果留白, 则预设为 %1)"
+
+#: NOT FOUND IN SOURCE
+msgid "(No Value)"
+msgstr "(没有值)"
+
+#: html/Admin/Elements/EditCustomFields:32 html/Admin/Elements/ListGlobalCustomFields:31
+msgid "(No custom fields)"
+msgstr "(没有自订字段)"
+
+#: html/Admin/Groups/Members.html:49 html/User/Groups/Members.html:52
+msgid "(No members)"
+msgstr "(没有成员)"
+
+#: html/Admin/Elements/EditScrips:31 html/Admin/Elements/ListGlobalScrips:31
+msgid "(No scrips)"
+msgstr "(没有手续)"
+
+#: html/Admin/Elements/EditTemplates:30
+msgid "(No templates)"
+msgstr "没有模板"
+
+#: html/Admin/Elements/EditWorkflows:31
+msgid "(No workflows)"
+msgstr "没有流程"
+
+#: html/Ticket/Update.html:83 html/Work/Tickets/Update.html:52
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(送出本份更新的密件副本给名单上以逗号隔开的电子邮件地址。这<b>不会</b>更改后续的收件者名单。)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(送出本份更新的密件副本给名单上以逗号隔开的电子邮件地址。这<b>不会</b>更改后续的收件者名单。)"
+
+#: html/Ticket/Create.html:78
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(送出本份更新的副本给名单上以逗号隔开的管理员电子邮件地址。这<b>将会</b>更改后续的收件者名单。)"
+
+#: html/Ticket/Update.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(送出本份更新的副本给名单上以逗号隔开的电子邮件地址。这<b>不会</b>更改后续的收件者名单。)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(送出本份更新的副本给名单上以逗号隔开的电子邮件地址。这<b>不会</b>更改后续的收件者名单。)"
+
+#: html/Ticket/Create.html:68
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(送出本份更新的副本给名单上以逗号隔开的电子邮件地址。这<b>将会</b>更改后续的收件者名单。)"
+
+#: html/Ticket/Elements/EditCustomFieldEntries:35 html/Work/Tickets/Elements/EditCustomFieldEntries:33 html/Work/Tickets/Elements/ShowCustomFieldEntries:13
+msgid "(delete)"
+msgstr "(删除)"
+
+#: html/Admin/Groups/index.html:32 html/User/Groups/index.html:32
+msgid "(empty)"
+msgstr "(空白)"
+
+#: html/Edit/Global/CustomField/index.html:113 html/Edit/Global/Scrip/index.html:111 html/Edit/Global/Template/index.html:106
+msgid "(new)"
+msgstr "(新增)"
+
+#: html/Admin/Users/index.html:38
+msgid "(no name listed)"
+msgstr "(没有列出姓名)"
+
+#: html/Elements/MyRequests:42 html/Elements/MyTickets:44 html/Work/Elements/MyApprovals:37 html/Work/Elements/MyRequests:36 html/Work/Elements/MyTickets:41
+msgid "(no subject)"
+msgstr "(没有主题)"
+
+#: html/Admin/Elements/SelectRights:47 html/Elements/SelectCustomFieldValue:29 html/Ticket/Elements/EditCustomField:60 html/Ticket/Elements/EditCustomFieldValues:52 html/Ticket/Elements/ShowCustomFields:35 html/Work/Elements/EditCustomFieldValues:50 html/Work/Elements/EditCustomFields:32 html/Work/Tickets/Elements/EditCustomFieldValues:33 lib/RT/Transaction_Overlay.pm:534
+msgid "(no value)"
+msgstr "(无)"
+
+#: html/Ticket/Elements/BulkLinks:27 html/Ticket/Elements/EditLinks:115 html/Work/Search/BulkLinks:3
+msgid "(only one ticket)"
+msgstr "(仅能指定一份申请单)"
+
+#: html/Elements/MyRequests:51 html/Elements/MyTickets:54 html/Work/Elements/List:17 html/Work/Elements/MyRequests:46 html/Work/Elements/MyTickets:56 html/Work/Tickets/Elements/ShowBasics:44
+msgid "(pending approval)"
+msgstr "(等待签核)"
+
+#: html/Elements/MyRequests:53 html/Elements/MyTickets:56 html/Work/Elements/MyRequests:48 html/Work/Elements/MyTickets:58
+msgid "(pending other tickets)"
+msgstr "(等待其它申请单)"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:246
+msgid "(requestor's group)"
+msgstr "(申请人所属)"
+
+#: html/Admin/Users/Modify.html:49
+msgid "(required)"
+msgstr "(必填)"
+
+#: html/Ticket/Elements/ShowTransaction:92 html/Work/Tickets/Elements/ShowTransaction:37
+msgid "(untitled)"
+msgstr "(未命名)"
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I own..."
+msgstr "前 25 份待处理申请单..."
+
+#: NOT FOUND IN SOURCE
+msgid "25 highest priority tickets I requested..."
+msgstr "前 25 份送出的申请单..."
+
+#: NOT FOUND IN SOURCE
+msgid ":"
+msgstr ":"
+
+#: html/Ticket/Elements/ShowBasics:31
+msgid "<% $Ticket->Status%>"
+msgstr "<% $Ticket->Status%>"
+
+#: html/Elements/SelectTicketTypes:26
+msgid "<% $_ %>"
+msgstr "<% $_ %>"
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:25 html/Work/Elements/104Header:43
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"提出申请单\">&nbsp;%1"
+
+#: etc/initialdata:221
+msgid "A blank template"
+msgstr "空白模板"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Deleted"
+msgstr "ACE 已删除"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Loaded"
+msgstr "ACE 已加载"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be deleted"
+msgstr "无法删除 ACE"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be found"
+msgstr "找不到 ACE"
+
+#: lib/RT/ACE_Overlay.pm:156 lib/RT/Principal_Overlay.pm:179
+msgid "ACE not found"
+msgstr "找不到 ACE 设定"
+
+#: lib/RT/ACE_Overlay.pm:830
+msgid "ACEs can only be created and deleted."
+msgstr "祇能新增或删除 ACE 设定。"
+
+#: NOT FOUND IN SOURCE
+msgid "ACLEquivalence"
+msgstr "ACLEquivalence"
+
+#: bin/rt-commit-handler:754
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr "离开以免不小心更改到申请单。\\n"
+
+#: html/User/Elements/Tabs:31
+msgid "About me"
+msgstr "个人信息"
+
+#: html/Edit/Users/System:12
+msgid "Access Right"
+msgstr "系统使用登录权限"
+
+#: html/Admin/Users/Modify.html:79
+msgid "Access control"
+msgstr "存取权限"
+
+#: html/Admin/Elements/EditScrip:56 html/Work/Tickets/Elements/ShowTransaction:18
+msgid "Action"
+msgstr "动作"
+
+#: lib/RT/Scrip_Overlay.pm:146
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr "动作 %1 找不到"
+
+#: bin/rt-crontool:122
+msgid "Action committed."
+msgstr "动作执行完毕"
+
+#: bin/rt-crontool:118
+msgid "Action prepared..."
+msgstr "动作准备完毕..."
+
+#: html/Work/Elements/List:13 html/Work/Elements/SelectSearch:24 html/Work/Tickets/Create.html:26 html/Work/Tickets/Elements/ShowBasics:12
+msgid "Activated Date"
+msgstr "申请激活时间"
+
+#: html/Edit/Elements/104Buttons:71 html/Edit/Elements/ListButtons:7
+msgid "Add"
+msgstr "新增"
+
+#: html/Search/Bulk.html:95 html/Work/Search/Bulk.html:74
+msgid "Add AdminCc"
+msgstr "新增管理员副本收件人"
+
+#: html/Search/Bulk.html:91 html/Work/Search/Bulk.html:68
+msgid "Add Cc"
+msgstr "新增副本收件人"
+
+#: html/Ticket/Elements/EditCustomFieldEntries:71 html/Work/Tickets/Elements/ShowCustomFieldEntries:49
+msgid "Add Entry"
+msgstr "新增列"
+
+#: html/Ticket/Create.html:113 html/Ticket/Update.html:98 html/Work/Tickets/Elements/AddAttachments:18
+msgid "Add More Files"
+msgstr "新增更多附件"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:112 html/Admin/Elements/ModifyTemplateAsWorkflow:45
+msgid "Add Next State"
+msgstr "新增下一项关卡"
+
+#: html/Search/Bulk.html:87 html/Work/Search/Bulk.html:62
+msgid "Add Requestor"
+msgstr "新增申请人"
+
+#: html/Admin/Elements/AddCustomFieldValue:24
+msgid "Add Value"
+msgstr "新增字段值"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip to this queue"
+msgstr "新增此表单的手续"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip which will apply to all queues"
+msgstr "新增适用于所有表单的手续"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a keyword selection to this queue"
+msgstr "新增此表单的关键词"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr "新增全域手续"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr "新增一道手续到此表单"
+
+#: html/Admin/Global/Scrip.html:54
+msgid "Add a scrip which will apply to all queues"
+msgstr "新增一道用于所有表单的手续"
+
+#: html/Search/Bulk.html:127 html/Work/Search/Bulk.html:80
+msgid "Add comments or replies to selected tickets"
+msgstr "新增评论或回复到指定的申请单"
+
+#: html/Admin/Groups/Members.html:41 html/User/Groups/Members.html:38
+msgid "Add members"
+msgstr "新增成员"
+
+#: html/Admin/Queues/People.html:65 html/Ticket/Elements/AddWatchers:27
+msgid "Add new watchers"
+msgstr "新增视察员"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr "新增下一项关卡"
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr "单位已新增为此表单的 %1"
+
+#: lib/RT/Ticket_Overlay.pm:1462
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr "单位已新增为此申请单的 %1"
+
+#: html/Admin/Elements/ModifyUser:75 html/Admin/Users/Modify.html:121 html/User/Prefs.html:87 html/Work/Preferences/Info:76
+msgid "Address1"
+msgstr "住址"
+
+#: html/Admin/Elements/ModifyUser:77 html/Admin/Users/Modify.html:126 html/User/Prefs.html:89 html/Work/Preferences/Info:78
+msgid "Address2"
+msgstr "住址(续)"
+
+#: NOT FOUND IN SOURCE
+msgid "Adjust Blinking Rate"
+msgstr "调整闪烁速度快慢"
+
+#: html/Edit/Groups/Admin:9
+msgid "Admin"
+msgstr "管理员"
+
+#: html/Ticket/Create.html:73
+msgid "Admin Cc"
+msgstr "管理员副本"
+
+#: etc/initialdata:303
+msgid "Admin Comment"
+msgstr "管理员评论"
+
+#: etc/initialdata:261
+msgid "Admin Correspondence"
+msgstr "管理员回复"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin Rights"
+msgstr "管理员权限"
+
+#: html/Admin/Queues/index.html:24 html/Admin/Queues/index.html:27
+msgid "Admin queues"
+msgstr "表单管理"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr "使用者管理"
+
+#: html/Admin/Global/index.html:25 html/Admin/Global/index.html:27
+msgid "Admin/Global configuration"
+msgstr "管理/全域设定"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr "管理/群组"
+
+#: html/Admin/Queues/Modify.html:24 html/Admin/Queues/Modify.html:28
+msgid "Admin/Queue/Basics"
+msgstr "管理/表单/基本信息"
+
+#: html/Edit/Global/Basic/Top:60
+msgid "AdminAddress"
+msgstr "管理员 Email"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr "管理所有代理人群组"
+
+#: etc/initialdata:74 html/Admin/Elements/ModifyTemplateAsWorkflow:155 html/Ticket/Elements/ShowPeople:38 html/Ticket/Update.html:49 lib/RT/ACE_Overlay.pm:88
+msgid "AdminCc"
+msgstr "管理员副本"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr "管理员评论"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr "管理员回复"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "AdminCustomFields"
+msgstr "管理自订字段"
+
+#: html/Edit/Groups/Admin:12 lib/RT/Group_Overlay.pm:145
+msgid "AdminGroup"
+msgstr "管理群组"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminGroupDescription"
+msgstr "管理群组描述"
+
+#: lib/RT/Group_Overlay.pm:147
+msgid "AdminGroupMembership"
+msgstr "管理群组成员"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminGroupName"
+msgstr "管理群组名称"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminGroupPermission"
+msgstr "管理群组权限"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminGroupStatus"
+msgstr "管理群组状态"
+
+#: lib/RT/System.pm:58
+msgid "AdminOwnPersonalGroups"
+msgstr "管理代理人群组"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "AdminQueue"
+msgstr "管理表单"
+
+#: lib/RT/System.pm:59
+msgid "AdminUsers"
+msgstr "管理使用者"
+
+#: NOT FOUND IN SOURCE
+msgid "Administrative"
+msgstr "行政类"
+
+#: html/Admin/Queues/People.html:47 html/Ticket/Elements/EditPeople:53
+msgid "Administrative Cc"
+msgstr "管理员副本"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:233
+msgid "Admins"
+msgstr "主管"
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr "进阶查询"
+
+#: html/Elements/SelectDateRelation:35
+msgid "After"
+msgstr "晚于"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr "经历时间"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:172 html/Edit/Global/Workflow/Action:39
+msgid "Alias"
+msgstr "执行其它流程"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:175
+msgid "Alias for"
+msgstr "相当于"
+
+#: html/Edit/Queues/index.html:33 html/Work/Delegates/index.html:13 html/Work/Elements/SelectSearch:11 html/Work/Queues/Select.html:14 html/Work/Queues/index.html:13
+msgid "All"
+msgstr "全部"
+
+#: etc/initialdata:372
+msgid "All Approvals Passed"
+msgstr "完成全部签核"
+
+#: html/Edit/Global/Workflow/Condition:16
+msgid "All Condition"
+msgstr "所有条件"
+
+#: html/Admin/Elements/EditCustomFields:95
+msgid "All Custom Fields"
+msgstr "所有自订字段"
+
+#: html/Admin/Queues/index.html:52
+msgid "All Queues"
+msgstr "所有表单"
+
+#: NOT FOUND IN SOURCE
+msgid "All Users"
+msgstr "全体员工"
+
+#: NOT FOUND IN SOURCE
+msgid "Allowance Request"
+msgstr "福利补助申请"
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr "无论寄件来源为何,一律寄信给申请人"
+
+#: NOT FOUND IN SOURCE
+msgid "Amount"
+msgstr "数额"
+
+#: html/Edit/Global/Workflow/Condition:13
+msgid "Any Condition"
+msgstr "任意条件"
+
+#: html/Edit/Global/Scrip/List:10 html/Edit/Global/Scrip/Top:74
+msgid "Apply Template"
+msgstr "引用模板"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:138 html/Elements/Tabs:55 html/Work/Approvals/Elements/Approve:6
+msgid "Approval"
+msgstr "签核"
+
+#: html/Approvals/Display.html:45 html/Approvals/Elements/ShowDependency:41 html/Approvals/index.html:64
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr "签核单 #%1:%2"
+
+#: html/Approvals/index.html:53
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr "签核单 #%1:系统错误,记录失败"
+
+#: html/Approvals/index.html:51
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr "签核单 #%1:记录完毕"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:123
+msgid "Approval Details"
+msgstr "签核细节"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Due"
+msgstr "签核时限"
+
+#: html/Work/Approvals/Elements/Approve:37
+msgid "Approval Notes"
+msgstr "签核意见"
+
+#: etc/initialdata:357
+msgid "Approval Passed"
+msgstr "完成某项签核"
+
+#: etc/initialdata:383
+msgid "Approval Rejected"
+msgstr "驳回某项签核"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Result"
+msgstr "签核结果"
+
+#: html/Work/Approvals/Elements/Approve:25
+msgid "Approval Status"
+msgstr "核准结果"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Type"
+msgstr "签核种类"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:25
+msgid "Approval diagram"
+msgstr "签核流程"
+
+#: html/Approvals/Elements/Approve:43 html/Work/Approvals/Elements/Approve:29
+msgid "Approve"
+msgstr "核准"
+
+#: html/Work/Approvals/Elements/Approve:21 html/Work/Elements/List:9
+msgid "Approver"
+msgstr "签核人"
+
+#: html/Edit/Global/Workflow/Action:29 html/Edit/Global/Workflow/Owner.html:10
+msgid "Approver Setting"
+msgstr "执行签核人设定"
+
+#: etc/initialdata:516 etc/upgrade/2.1.71:148 html/Edit/Elements/CreateApprovalsQueue:122
+msgid "Approver's notes: %1"
+msgstr "签核备注:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Apr"
+msgstr "四月"
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "04"
+
+#: NOT FOUND IN SOURCE
+msgid "April"
+msgstr "四月"
+
+#: html/Edit/Elements/104Buttons:24
+msgid "Are you sure to delete checked items?"
+msgstr "您确定要删除?"
+
+#: html/Elements/SelectSortOrder:34
+msgid "Ascending"
+msgstr "递增"
+
+#: html/Search/Bulk.html:136 html/SelfService/Update.html:32 html/Ticket/ModifyAll.html:82 html/Ticket/Update.html:98 html/Work/Search/Bulk.html:88
+msgid "Attach"
+msgstr "附件"
+
+#: html/SelfService/Create.html:64 html/Ticket/Create.html:109 html/Work/Tickets/Elements/AddAttachments:15
+msgid "Attach file"
+msgstr "附加档案"
+
+#: html/Ticket/Create.html:97 html/Ticket/Update.html:87 html/Work/Tickets/Elements/AddAttachments:6
+msgid "Attached file"
+msgstr "现有附件"
+
+#: NOT FOUND IN SOURCE
+msgid "Attachment '%1' could not be loaded"
+msgstr "无法加载附件 '%1'"
+
+#: lib/RT/Transaction_Overlay.pm:441
+msgid "Attachment created"
+msgstr "附件新增完毕"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "附件档名"
+
+#: html/Ticket/Elements/ShowAttachments:25 html/Work/Tickets/Elements/ShowTransaction:32
+msgid "Attachments"
+msgstr "附件"
+
+#: NOT FOUND IN SOURCE
+msgid "Aug"
+msgstr "八月"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "08"
+
+#: NOT FOUND IN SOURCE
+msgid "August"
+msgstr "八月"
+
+#: html/Admin/Elements/ModifyUser:65
+msgid "AuthSystem"
+msgstr "认证方式"
+
+#: NOT FOUND IN SOURCE
+msgid "AutoReject"
+msgstr "自动驳回表单"
+
+#: NOT FOUND IN SOURCE
+msgid "AutoResolve"
+msgstr "自动完成表单处理"
+
+#: etc/initialdata:224
+msgid "Autoreply"
+msgstr "自动回复"
+
+#: etc/initialdata:90
+msgid "Autoreply To Requestors"
+msgstr "自动对申请人回复"
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr "自动对申请人回复"
+
+#: html/Edit/Rights/index.html:16
+msgid "Available Rights:"
+msgstr "权限项目列表:"
+
+#: NOT FOUND IN SOURCE
+msgid "Back to Homepage"
+msgstr "回到首页"
+
+#: html/Work/Elements/BackButton:2 html/Work/Search/Bulk.html:101
+msgid "Back to Previous"
+msgstr "回上页"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr "错误的 PGP 签章:%1\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr "错误的附件编号。无法找到附件 '%1'\\n"
+
+#: bin/rt-commit-handler:826
+#. ($val)
+msgid "Bad data in %1"
+msgstr "%1 的数据错误"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr "附件的处理号码错误。%1 应为 %2\\n"
+
+#: html/Admin/Elements/GroupTabs:38 html/Admin/Elements/QueueTabs:38 html/Admin/Elements/UserTabs:37 html/Edit/Global/autohandler:6 html/Edit/Queues/autohandler:17 html/Edit/Users/index.html:121 html/Ticket/Elements/Tabs:89 html/User/Elements/GroupTabs:37
+msgid "Basics"
+msgstr "基本信息"
+
+#: html/Ticket/Update.html:81 html/Work/Tickets/Update.html:49
+msgid "Bcc"
+msgstr "密件副本"
+
+#: html/Admin/Elements/EditScrip:87 html/Admin/Global/GroupRights.html:84 html/Admin/Global/Template.html:45 html/Admin/Global/UserRights.html:53 html/Admin/Global/Workflow.html:46 html/Admin/Groups/GroupRights.html:72 html/Admin/Groups/Members.html:80 html/Admin/Groups/Modify.html:55 html/Admin/Groups/UserRights.html:54 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:44 html/Admin/Queues/UserRights.html:53 html/Admin/Queues/Workflow.html:44 html/User/Groups/Modify.html:55
+msgid "Be sure to save your changes"
+msgstr "请别忘了储存修改。"
+
+#: html/Elements/SelectDateRelation:33 lib/RT/CurrentUser.pm:321
+msgid "Before"
+msgstr "早于"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:44
+msgid "Begin Approval"
+msgstr "开始签核"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin From "
+msgstr "起始日"
+
+#: html/Edit/Users/Info:25
+msgid "Birthday"
+msgstr "生日"
+
+#: etc/initialdata:220
+msgid "Blank"
+msgstr "空白模板"
+
+#: html/Search/Listing.html:78 html/Work/Search/index.html:53
+msgid "Bookmarkable URL for this search"
+msgstr "将查询结果转为可放入书签的网址"
+
+#: html/Ticket/Elements/ShowHistory:38 html/Ticket/Elements/ShowHistory:44
+msgid "Brief headers"
+msgstr "精简标头档"
+
+#: html/Search/Bulk.html:24 html/Search/Bulk.html:25
+msgid "Bulk ticket update"
+msgstr "更新整批申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "Business Unit"
+msgstr "事业部"
+
+#: NOT FOUND IN SOURCE
+msgid "Business Unit:"
+msgstr "事业部:"
+
+#: lib/RT/User_Overlay.pm:1411
+msgid "Can not modify system users"
+msgstr "无法更改系统使用者"
+
+#: lib/RT/Queue_Overlay.pm:66
+msgid "Can this principal see this queue"
+msgstr "该单位是否能查阅此表单"
+
+#: lib/RT/CustomField_Overlay.pm:205
+msgid "Can't add a custom field value without a name"
+msgstr "不能新增没有名称的自订字段值"
+
+#: lib/RT/Link_Overlay.pm:131
+msgid "Can't link a ticket to itself"
+msgstr "申请单不能链接自己。"
+
+#: lib/RT/Ticket_Overlay.pm:2816
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr "不能整合进已整合过的申请单。这个错误不该发生。"
+
+#: lib/RT/Ticket_Overlay.pm:2634 lib/RT/Ticket_Overlay.pm:2703
+msgid "Can't specifiy both base and target"
+msgstr "不能同时指定起始申请单与目的申请单"
+
+#: html/Edit/Elements/PopFooter:8
+msgid "Cancel"
+msgstr "取消"
+
+#: html/autohandler:113
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr "无法新增使用者:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Card No."
+msgstr "卡号"
+
+#: NOT FOUND IN SOURCE
+msgid "Categories"
+msgstr "分类管理"
+
+#: NOT FOUND IN SOURCE
+msgid "Category"
+msgstr "分类"
+
+#: etc/initialdata:68 html/Admin/Queues/People.html:43 html/SelfService/Create.html:48 html/Ticket/Create.html:63 html/Ticket/Elements/EditPeople:50 html/Ticket/Elements/ShowPeople:34 html/Ticket/Update.html:44 html/Ticket/Update.html:76 html/Work/Tickets/Update.html:43 lib/RT/ACE_Overlay.pm:87
+msgid "Cc"
+msgstr "副本"
+
+#: NOT FOUND IN SOURCE
+msgid "Cc Type"
+msgstr "副本类别"
+
+#: NOT FOUND IN SOURCE
+msgid "Chairperson's Office"
+msgstr "董事长室"
+
+#: NOT FOUND IN SOURCE
+msgid "Change Ticket"
+msgstr "修改申请单"
+
+#: html/SelfService/Prefs.html:30
+msgid "Change password"
+msgstr "更改口令"
+
+#: html/Edit/Global/Basic/Top:70
+msgid "ChangeOwnerUI"
+msgstr "可否选择表单承办人"
+
+#: html/Ticket/Create.html:100 html/Ticket/Elements/EditCustomFieldEntries:35 html/Ticket/Update.html:90 html/Work/Tickets/Elements/ShowCustomFieldEntries:13
+msgid "Check box to delete"
+msgstr "选择欲删除的项目"
+
+#: html/Admin/Elements/SelectRights:30
+msgid "Check box to revoke right"
+msgstr "选择欲撤消的权利"
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/BulkLinks:42 html/Ticket/Elements/EditLinks:130 html/Ticket/Elements/EditLinks:68 html/Ticket/Elements/ShowLinks:56 html/Work/Search/BulkLinks:18
+msgid "Children"
+msgstr "子申请单"
+
+#: html/Edit/Elements/PickUsers:21 html/Edit/Global/UserRight/List:8 html/Edit/Global/UserRight/Top:19 html/Edit/Users/List:6 html/Edit/Users/Top:18
+msgid "Chinese Name"
+msgstr "中文姓名"
+
+#: NOT FOUND IN SOURCE
+msgid "Chinese/English"
+msgstr "中英文"
+
+#: html/Admin/Elements/ModifyUser:79 html/Admin/Users/Modify.html:131 html/User/Prefs.html:91 html/Work/Preferences/Info:80
+msgid "City"
+msgstr "所在城市"
+
+#: html/Ticket/Elements/ShowDates:46
+msgid "Closed"
+msgstr "已解决"
+
+#: html/SelfService/Closed.html:24
+msgid "Closed Tickets"
+msgstr "已解决的申请单"
+
+#: html/SelfService/Elements/Tabs:44
+msgid "Closed tickets"
+msgstr "已解决的申请单"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:181 html/Edit/Global/Workflow/Action:58 html/Edit/Global/Workflow/Condition:51
+msgid "Code"
+msgstr "执行程序码"
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr "指令无法辨识!\\n"
+
+#: html/Ticket/Elements/ShowTransaction:166 html/Ticket/Elements/Tabs:152 html/Work/Search/Bulk.html:89 html/Work/Tickets/Display.html:37 html/Work/Tickets/Elements/ShowTransaction:112 html/Work/Tickets/Elements/ShowTransaction:27
+msgid "Comment"
+msgstr "评论"
+
+#: html/Admin/Elements/ModifyQueue:44 html/Admin/Queues/Modify.html:57
+msgid "Comment Address"
+msgstr "评论电子邮件地址"
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr "评论未被纪录"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Comment on tickets"
+msgstr "对申请单提出评论"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "CommentOnTicket"
+msgstr "评论申请单"
+
+#: html/Admin/Elements/ModifyUser:34 html/Work/Tickets/Update.html:59
+msgid "Comments"
+msgstr "评论"
+
+#: html/Ticket/ModifyAll.html:69 html/Ticket/Update.html:68 html/Work/Tickets/Update.html:35
+msgid "Comments (Not sent to requestors)"
+msgstr "评论(不送给申请人)"
+
+#: html/Search/Bulk.html:131 html/Work/Search/Bulk.html:83
+msgid "Comments (not sent to requestors)"
+msgstr "评论(不送给申请人)"
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Comments about %1"
+msgstr "对 %1 的评论"
+
+#: html/Admin/Users/Modify.html:184 html/Ticket/Elements/ShowRequestor:43
+msgid "Comments about this user"
+msgstr "使用者描述"
+
+#: lib/RT/Transaction_Overlay.pm:543
+msgid "Comments added"
+msgstr "新增评论完毕"
+
+#: html/Edit/Elements/PopFooter:4 html/Edit/Elements/PopFooter:6
+msgid "Commit"
+msgstr "确认"
+
+#: lib/RT/Action/Generic.pm:139
+msgid "Commit Stubbed"
+msgstr "消除更动完毕"
+
+#: html/Edit/Users/Info:42
+msgid "Company Name"
+msgstr "公司名称"
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr "设定查询条件"
+
+#: html/Admin/Elements/EditScrip:40 html/Admin/Elements/ModifyTemplateAsWorkflow:127
+msgid "Condition"
+msgstr "条件"
+
+#: bin/rt-crontool:108
+msgid "Condition matches..."
+msgstr "符合条件..."
+
+#: lib/RT/Scrip_Overlay.pm:159
+msgid "Condition not found"
+msgstr "未找到符合的现况"
+
+#: html/Edit/Global/GroupRight/Top:26 html/Edit/Global/UserRight/Top:45 html/Edit/Groups/Member:57 html/Elements/Tabs:49
+msgid "Configuration"
+msgstr "设定"
+
+#: html/SelfService/Prefs.html:32
+msgid "Confirm"
+msgstr "确认口令"
+
+#: NOT FOUND IN SOURCE
+msgid "Confirm Password"
+msgstr "口令确认"
+
+#: html/Work/Approvals/Display.html:25 html/Work/Tickets/Create.html:153 html/Work/Tickets/Create.html:165 html/Work/Tickets/Update.html:81
+msgid "Confirm Submit"
+msgstr "确定送出"
+
+#: NOT FOUND IN SOURCE
+msgid "Contact System Administrator"
+msgstr "连络系统管理员"
+
+#: html/Admin/Elements/ModifyUser:59
+msgid "ContactInfoSystem"
+msgstr "连络信息系统"
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr "无法解读联络日期 '%1'"
+
+#: html/Admin/Elements/ModifyTemplate:43 html/Admin/Elements/ModifyTemplateAsWorkflow:200 html/Ticket/ModifyAll.html:86
+msgid "Content"
+msgstr "内容"
+
+#: NOT FOUND IN SOURCE
+msgid "Coould not create group"
+msgstr "无法新增群组"
+
+#: html/Edit/Elements/104Buttons:74
+msgid "Copy"
+msgstr "复制"
+
+#: NOT FOUND IN SOURCE
+msgid "Copy Field From:"
+msgstr "欲复制字段:"
+
+#: etc/initialdata:282
+msgid "Correspondence"
+msgstr "回复"
+
+#: html/Admin/Elements/ModifyQueue:38 html/Admin/Queues/Modify.html:50
+msgid "Correspondence Address"
+msgstr "申请单回复地址"
+
+#: lib/RT/Transaction_Overlay.pm:539
+msgid "Correspondence added"
+msgstr "新增申请单回复"
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr "未纪录申请单回复"
+
+#: lib/RT/Ticket_Overlay.pm:3561
+msgid "Could not add new custom field value for ticket. "
+msgstr "不能新增自订字段的值 "
+
+#: NOT FOUND IN SOURCE
+msgid "Could not add new custom field value for ticket. %1 "
+msgstr "不能新增自订字段的值。%1 "
+
+#: lib/RT/Ticket_Overlay.pm:3067 lib/RT/Ticket_Overlay.pm:3075 lib/RT/Ticket_Overlay.pm:3092
+msgid "Could not change owner. "
+msgstr "不能更改承办人。 "
+
+#: html/Admin/Elements/EditCustomField:84 html/Admin/Elements/EditCustomFields:165 html/Edit/Global/CustomField/index.html:117
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr "无法新增自订字段"
+
+#: html/Edit/Global/Workflow/index.html:126
+#. ($msg)
+msgid "Could not create Scrip"
+msgstr "无法建立讯息通知"
+
+#: html/Edit/Global/Template/index.html:110
+#. ($msg)
+msgid "Could not create Template"
+msgstr "无法建立通知模板"
+
+#: html/User/Groups/Modify.html:76 lib/RT/Group_Overlay.pm:473 lib/RT/Group_Overlay.pm:480
+msgid "Could not create group"
+msgstr "无法新增群组"
+
+#: html/Admin/Global/Template.html:74 html/Admin/Queues/Template.html:71
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr "无法新增模板:%1"
+
+#: lib/RT/Ticket_Overlay.pm:1081 lib/RT/Ticket_Overlay.pm:334
+msgid "Could not create ticket. Queue not set"
+msgstr "无法新增申请单。尚未指定表单。"
+
+#: lib/RT/User_Overlay.pm:267 lib/RT/User_Overlay.pm:279 lib/RT/User_Overlay.pm:297 lib/RT/User_Overlay.pm:481
+msgid "Could not create user"
+msgstr "无法新增使用者"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not create watcher for requestor"
+msgstr "无法为申请人新增视察员"
+
+#: html/Admin/Elements/ModifyWorkflow:219 html/Admin/Global/Workflow.html:75 html/Admin/Queues/Workflow.html:71
+#. ($msg)
+msgid "Could not create workflow: %1"
+msgstr "无法新增流程:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr "找不到编号 %1 的申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr "找不到群组 %1。"
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1430
+msgid "Could not find or create that user"
+msgstr "找不到或无法新增该名使用者"
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1509
+msgid "Could not find that principal"
+msgstr "找不到该单位"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr "找不到使用者 %1。"
+
+#: html/Admin/Groups/Members.html:87 html/Edit/Users/index.html:83 html/User/Groups/Members.html:89 html/User/Groups/Modify.html:81
+#. ( . $GroupId)
+msgid "Could not load group"
+msgstr "无法加载群组"
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr "无法将该单位设为此表单的 %1。"
+
+#: lib/RT/Ticket_Overlay.pm:1451
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr "无法将该单位设为此申请单的 %1。"
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr "无法将单位 %1 从表单移除。"
+
+#: lib/RT/Ticket_Overlay.pm:1567
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr "无法将单位 %1 从申请单移除。"
+
+#: lib/RT/Group_Overlay.pm:984
+msgid "Couldn't add member to group"
+msgstr "无法新增成员至群组"
+
+#: lib/RT/Ticket_Overlay.pm:3571 lib/RT/Ticket_Overlay.pm:3627
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr "无法新增更动报告"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr "无法从 gpg 回函辨识出该采取的行动\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr "找不到群组\\n"
+
+#: lib/RT/Interface/Web.pm:902
+msgid "Couldn't find row"
+msgstr "找不到此列数据"
+
+#: lib/RT/Group_Overlay.pm:958
+msgid "Couldn't find that principal"
+msgstr "找不到该单位"
+
+#: lib/RT/CustomField_Overlay.pm:239
+msgid "Couldn't find that value"
+msgstr "找不到该值"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find that watcher"
+msgstr "找不到该视察员"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr "找不到使用者\\n"
+
+#: lib/RT/CurrentUser.pm:111
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr "无法从使用者数据库加载 %1。\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load KeywordSelects."
+msgstr "无法加载 KeywordSelects。"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr "无法加载 RT 设定档 '%1' %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr "无法加载手续。"
+
+#: html/Admin/Groups/GroupRights.html:87 html/Admin/Groups/UserRights.html:74 html/Edit/Global/GroupRight/Add.html:54 html/Edit/Global/UserRight/Add.html:23 html/Edit/Groups/Member:121 html/Edit/Groups/Members/Add.html:44 html/Edit/Rights/index.html:57
+#. ($Group)
+#. ($ObjectGroup)
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr "无法加载手续 %1"
+
+#: lib/RT/Link_Overlay.pm:174 lib/RT/Link_Overlay.pm:183 lib/RT/Link_Overlay.pm:210
+msgid "Couldn't load link"
+msgstr "无法加载链接。"
+
+#: html/Admin/Elements/EditCustomFields:146 html/Admin/Queues/People.html:120
+#. ($id)
+msgid "Couldn't load queue"
+msgstr "无法加载表单"
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:71 html/Edit/Global/GroupRight/Add.html:50 html/Edit/Global/GroupRight/index.html:81 html/Edit/Global/UserRight/Add.html:19 html/Edit/Global/UserRight/index.html:83 html/Edit/Rights/index.html:53
+#. ($Queue)
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr "无法加载表单 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr "无法加载手续"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr "无法加载模板"
+
+#: html/Admin/Users/Prefs.html:78
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr "无法加载该名使用者(%1)"
+
+#: html/SelfService/Display.html:108
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr "无法加载申请单 '%1'"
+
+#: html/Admin/Elements/ModifyUser:85 html/Admin/Users/Modify.html:148 html/User/Prefs.html:97 html/Work/Preferences/Info:86
+msgid "Country"
+msgstr "国家"
+
+#: html/Admin/Elements/CreateUserCalled:25 html/Edit/Elements/PopHeader:29 html/Edit/Global/GroupRight/Add.html:18 html/Ticket/Create.html:134 html/Ticket/Create.html:194
+msgid "Create"
+msgstr "新增"
+
+#: html/Edit/Groups/MemberGroups/Add.html:17
+msgid "Create Subgroup:"
+msgstr "新增子群组:"
+
+#: etc/initialdata:145
+msgid "Create Tickets"
+msgstr "新增申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "Create User:"
+msgstr "新增成员:"
+
+#: html/Admin/Elements/EditCustomField:74
+msgid "Create a CustomField"
+msgstr "新增自订字段"
+
+#: html/Admin/Queues/CustomField.html:47
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr "为 %1 表单新增自订字段"
+
+#: html/Admin/Global/CustomField.html:47
+msgid "Create a CustomField which applies to all queues"
+msgstr "为 %1 表单新增自订字段"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr "新增自订字段"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global Scrip"
+msgstr "新增全域手续"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr "新增全域手续"
+
+#: html/Admin/Groups/Modify.html:66 html/Admin/Groups/Modify.html:92
+msgid "Create a new group"
+msgstr "新增群组"
+
+#: html/User/Groups/Modify.html:66 html/User/Groups/Modify.html:91
+msgid "Create a new personal group"
+msgstr "新增代理人群组"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr "新增表单"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr "新增手续"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr "新增模板"
+
+#: html/Ticket/Create.html:24 html/Ticket/Create.html:27 html/Ticket/Create.html:35
+msgid "Create a new ticket"
+msgstr "新增申请单"
+
+#: html/Admin/Users/Modify.html:213 html/Admin/Users/Modify.html:240
+msgid "Create a new user"
+msgstr "新增使用者"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new workflow"
+msgstr "新增流程"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "新增表单"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr "新增表单名称"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a request"
+msgstr "提出申请"
+
+#: html/Admin/Queues/Scrip.html:58
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr "为 %1 表单新增手续"
+
+#: html/Admin/Global/Template.html:68 html/Admin/Queues/Template.html:64
+msgid "Create a template"
+msgstr "新增模板"
+
+#: html/SelfService/Create.html:24
+msgid "Create a ticket"
+msgstr "提出申请单"
+
+#: html/Admin/Elements/ModifyWorkflow:206 html/Admin/Global/Workflow.html:69 html/Admin/Queues/Workflow.html:64
+msgid "Create a workflow"
+msgstr "新增流程"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1 / %2 / %3 "
+msgstr "新增失败:%1 / %2 / %3"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1/%2/%3"
+msgstr "新增失败:%1/%2/%3"
+
+#: NOT FOUND IN SOURCE
+msgid "Create new item"
+msgstr "建立新项目"
+
+#: etc/initialdata:147
+msgid "Create new tickets based on this scrip's template"
+msgstr "依据此项手续内的模版,新增申请单"
+
+#: html/SelfService/Create.html:77
+msgid "Create ticket"
+msgstr "新增申请单"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Create tickets in this queue"
+msgstr "在此表单中新增申请单"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Create, delete and modify custom fields"
+msgstr "新增、删除及更改自订字段"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Create, delete and modify queues"
+msgstr "新增、删除及更改表单"
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr "新增、删除及更改任何使用者的代理人群组"
+
+#: lib/RT/System.pm:58
+msgid "Create, delete and modify the members of personal groups"
+msgstr "新增、删除及更改代理人群组"
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify users"
+msgstr "新增、删除及更改使用者"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "CreateTicket"
+msgstr "新增申请单"
+
+#: html/Elements/SelectDateType:25 html/Ticket/Elements/ShowDates:26 lib/RT/Ticket_Overlay.pm:1175
+msgid "Created"
+msgstr "新增日"
+
+#: html/Admin/Elements/EditCustomField:87
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr "自订字段 %1 新增成功"
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr "模板 %1 新增成功"
+
+#: html/Admin/Elements/ModifyWorkflow:221
+#. (loc( $WorkflowObj->Name() ))
+msgid "Created workflow %1"
+msgstr "流程 %1 新增成功"
+
+#: NOT FOUND IN SOURCE
+msgid "Currency"
+msgstr "币别"
+
+#: NOT FOUND IN SOURCE
+msgid "Current Approval Info"
+msgstr "截至目前签核信息"
+
+#: NOT FOUND IN SOURCE
+msgid "Current Custom Fields"
+msgstr "现有自订字段"
+
+#: html/Edit/Groups/MemberGroups/Add.html:14
+msgid "Current Groups:"
+msgstr "现有群组列表:"
+
+#: html/Ticket/Elements/EditLinks:27
+msgid "Current Relationships"
+msgstr "现有关系"
+
+#: html/Edit/Rights/index.html:19
+msgid "Current Rights:"
+msgstr "现有权限:"
+
+#: html/Admin/Elements/EditScrips:29
+msgid "Current Scrips"
+msgstr "现有手续"
+
+#: html/Work/Tickets/Create.html:48 html/Work/Tickets/Elements/ShowBasics:39
+msgid "Current Status"
+msgstr "目前状态"
+
+#: NOT FOUND IN SOURCE
+msgid "Current Templates"
+msgstr "现有模板"
+
+#: html/Admin/Groups/Members.html:38 html/User/Groups/Members.html:41
+msgid "Current members"
+msgstr "现有成员"
+
+#: html/Admin/Elements/SelectRights:28
+msgid "Current rights"
+msgstr "现有权限"
+
+#: html/Search/Listing.html:70 html/Work/Search/index.html:42
+msgid "Current search criteria"
+msgstr "现有查询条件"
+
+#: html/Admin/Queues/People.html:40 html/Ticket/Elements/EditPeople:44
+msgid "Current watchers"
+msgstr "现有视察员"
+
+#: html/Admin/Global/CustomField.html:54
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr "自订字段 #%1"
+
+#: html/Admin/Elements/QueueTabs:52 html/Admin/Elements/SystemTabs:39 html/Admin/Global/index.html:49 html/Edit/Global/autohandler:7 html/Edit/Queues/autohandler:18 html/Ticket/Elements/ShowSummary:35
+msgid "Custom Fields"
+msgstr "自订字段"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom Fields which apply to all queues"
+msgstr "适用于所有表单的自订字段"
+
+#: html/Admin/Elements/EditScrip:72 html/Edit/Global/Scrip/Top:69
+msgid "Custom action cleanup code"
+msgstr "动作后执行程序"
+
+#: html/Admin/Elements/EditScrip:64 html/Edit/Global/Scrip/Top:62
+msgid "Custom action preparation code"
+msgstr "动作前执行程序"
+
+#: html/Admin/Elements/EditScrip:48 html/Edit/Global/Scrip/Top:35 html/Edit/Global/Scrip/Top:61
+msgid "Custom condition"
+msgstr "自订条件"
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr "自订字段 %1 %2 %3"
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr "自订字段 %1 已有值"
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr "自订字段 %1 没有值"
+
+#: lib/RT/Ticket_Overlay.pm:3463
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr "找不到自订字段 %1"
+
+#: html/Admin/Elements/EditCustomFields:196
+msgid "Custom field deleted"
+msgstr "自订字段已删除"
+
+#: lib/RT/Ticket_Overlay.pm:3613
+msgid "Custom field not found"
+msgstr "找不到自订字段"
+
+#: lib/RT/CustomField_Overlay.pm:349
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr "无法从自订字段 %2 中找到 %1 这个字段值"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr "自订字段值从 %1 改为 %2"
+
+#: lib/RT/CustomField_Overlay.pm:249
+msgid "Custom field value could not be deleted"
+msgstr "无法删除自订字段值"
+
+#: lib/RT/CustomField_Overlay.pm:355
+msgid "Custom field value could not be found"
+msgstr "找不到自订字段值"
+
+#: lib/RT/CustomField_Overlay.pm:247 lib/RT/CustomField_Overlay.pm:357
+msgid "Custom field value deleted"
+msgstr "自订字段值删除成功"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:145 html/Edit/Global/Workflow/Owner.html:90 lib/RT/Transaction_Overlay.pm:548
+msgid "CustomField"
+msgstr "自订字段"
+
+#: NOT FOUND IN SOURCE
+msgid "Data error"
+msgstr "数据错误"
+
+#: NOT FOUND IN SOURCE
+msgid "Date of Departure"
+msgstr "出发日期"
+
+#: html/SelfService/Display.html:38 html/Ticket/Create.html:160 html/Ticket/Elements/ShowSummary:54 html/Ticket/Elements/Tabs:92 html/Ticket/ModifyAll.html:43 html/Work/Tickets/Elements/ShowTransaction:14
+msgid "Dates"
+msgstr "日期"
+
+#: NOT FOUND IN SOURCE
+msgid "Dec"
+msgstr "十二月"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "12"
+
+#: NOT FOUND IN SOURCE
+msgid "December"
+msgstr "十二月"
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr "预设自动响应模板"
+
+#: etc/initialdata:225
+msgid "Default Autoresponse template"
+msgstr "预设自动响应模板"
+
+#: etc/initialdata:304
+msgid "Default admin comment template"
+msgstr "预设管理员评论模板"
+
+#: etc/initialdata:262
+msgid "Default admin correspondence template"
+msgstr "预设管理员回复模板"
+
+#: etc/initialdata:283
+msgid "Default correspondence template"
+msgstr "预设回复模板"
+
+#: etc/initialdata:240
+msgid "Default transaction template"
+msgstr "预设更动模板"
+
+#: lib/RT/Transaction_Overlay.pm:643
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr "预设:%1/%2 已自 %3 改为 %4"
+
+#: html/User/Delegation.html:24 html/User/Delegation.html:27
+msgid "Delegate rights"
+msgstr "代表团权限"
+
+#: lib/RT/System.pm:62
+msgid "Delegate specific rights which have been granted to you."
+msgstr "将拥有的权限委托他人代理"
+
+#: lib/RT/System.pm:62
+msgid "DelegateRights"
+msgstr "设定代理人"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegated Approval"
+msgstr "代理签核"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegated Queue"
+msgstr "代理表单名称"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegated Queue:"
+msgstr "代理表单:"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegated Type"
+msgstr "代理表单种类"
+
+#: html/Edit/Users/index.html:125 html/Work/Delegates/Info:31 html/Work/Delegates/List:8 html/Work/Elements/Tab:39 html/Work/Overview/Info:28
+msgid "Delegates"
+msgstr "代理人"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegates Enabled Status"
+msgstr "代理激活状态"
+
+#: html/Work/Delegates/Info:18 html/Work/Overview/Info:18
+msgid "Delegates Info"
+msgstr "代理人信息"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegates Period"
+msgstr "代理期间"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegates Permission Setting"
+msgstr "代理权限设定"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegates Permission:"
+msgstr "代理权限:"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegates Setting"
+msgstr "代理人设定"
+
+#: html/Work/Delegates/Info:46 html/Work/Delegates/List:11 html/Work/Overview/Info:39
+msgid "Delegates Status"
+msgstr "代理状态"
+
+#: html/User/Elements/Tabs:37
+msgid "Delegation"
+msgstr "代理人权限"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegation Groups"
+msgstr "代理人群组"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegation Rights"
+msgstr "代理人权限"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:113 html/Edit/Elements/104Buttons:73 html/Work/Search/index.html:48 html/Work/Search/index.html:48
+msgid "Delete"
+msgstr "删除"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Delete tickets"
+msgstr "删除申请单"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "DeleteTicket"
+msgstr "删除申请单"
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr "删除此对象可能破坏参考完整性"
+
+#: lib/RT/Queue_Overlay.pm:293
+msgid "Deleting this object would break referential integrity"
+msgstr "删除此对象可能破坏参考完整性"
+
+#: lib/RT/User_Overlay.pm:497
+msgid "Deleting this object would violate referential integrity"
+msgstr "删除此对象会违反参考完整性"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity."
+msgstr "删除此对象会违反参考完整性"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity. That's bad."
+msgstr "删除此对象会违反参考完整性"
+
+#: html/Approvals/Elements/Approve:44 html/Work/Approvals/Elements/Approve:32
+msgid "Deny"
+msgstr "驳回"
+
+#: NOT FOUND IN SOURCE
+msgid "Department"
+msgstr "部门"
+
+#: html/Edit/Global/UserRight/List:12 html/Edit/Global/UserRight/Top:13 html/Edit/Users/List:10 html/Edit/Users/Top:12
+msgid "Department ID"
+msgstr "部门代码"
+
+#: html/Edit/Global/UserRight/List:11 html/Edit/Global/UserRight/Top:49 html/Edit/Users/List:9 html/Edit/Users/Top:48 html/Work/Delegates/Info:78 html/Work/Overview/Info:60
+msgid "Department Name"
+msgstr "部门名称"
+
+#: NOT FOUND IN SOURCE
+msgid "Department's"
+msgstr "部门之"
+
+#: NOT FOUND IN SOURCE
+msgid "Departure Details"
+msgstr "差旅明细"
+
+#: NOT FOUND IN SOURCE
+msgid "Departure From"
+msgstr "差旅起始日"
+
+#: NOT FOUND IN SOURCE
+msgid "Departure Request"
+msgstr "请假单"
+
+#: NOT FOUND IN SOURCE
+msgid "Departure Until"
+msgstr "差旅截止日"
+
+#: html/Ticket/Create.html:180 html/Ticket/Elements/BulkLinks:34 html/Ticket/Elements/EditLinks:122 html/Ticket/Elements/EditLinks:46 html/Ticket/Elements/ShowDependencies:31 html/Ticket/Elements/ShowLinks:36 html/Work/Search/BulkLinks:10
+msgid "Depended on by"
+msgstr "可接续处理的申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr "附属性:\\n"
+
+#: html/Elements/SelectLinkType:26 html/Ticket/Create.html:179 html/Ticket/Elements/BulkLinks:30 html/Ticket/Elements/EditLinks:118 html/Ticket/Elements/EditLinks:35 html/Ticket/Elements/ShowDependencies:24 html/Ticket/Elements/ShowLinks:26 html/Work/Search/BulkLinks:6
+msgid "Depends on"
+msgstr "需先处理"
+
+#: NOT FOUND IN SOURCE
+msgid "DependsOn"
+msgstr "需先处理"
+
+#: html/Elements/SelectSortOrder:34
+msgid "Descending"
+msgstr "递减"
+
+#: html/SelfService/Create.html:72 html/Ticket/Create.html:118
+msgid "Describe the issue below"
+msgstr "在以下字段描述主题"
+
+#: html/Admin/Elements/AddCustomFieldValue:35 html/Admin/Elements/EditCustomField:38 html/Admin/Elements/EditScrip:33 html/Admin/Elements/ModifyQueue:35 html/Admin/Elements/ModifyTemplate:35 html/Admin/Elements/ModifyTemplateAsWorkflow:192 html/Admin/Groups/Modify.html:48 html/Admin/Queues/Modify.html:47 html/Edit/Global/Workflow/Action:14 html/Elements/SelectGroups:26 html/User/Groups/Modify.html:48 html/Work/Preferences/Info:98
+msgid "Description"
+msgstr "描述"
+
+#: NOT FOUND IN SOURCE
+msgid "Description of Responsibility"
+msgstr "经办业务说明"
+
+#: NOT FOUND IN SOURCE
+msgid "Description:"
+msgstr "描述:"
+
+#: html/Work/Tickets/Create.html:108 html/Work/Tickets/Elements/EditCustomFields:39 html/Work/Tickets/Elements/ShowCustomFields:41
+msgid "Details"
+msgstr "细节"
+
+#: NOT FOUND IN SOURCE
+msgid "Direct"
+msgstr "直接"
+
+#: html/Edit/Users/Info:31
+msgid "Disability"
+msgstr "残障身分"
+
+#: html/Edit/Users/Info:29
+msgid "Disability Type"
+msgstr "残障类别"
+
+#: html/Edit/Global/GroupRight/List:9 html/Edit/Global/GroupRight/Top:16 html/Edit/Groups/List:11 html/Edit/Groups/Top:19 html/Edit/Queues/Basic/Top:70 html/Edit/Queues/List:13 html/Work/Delegates/Info:48 html/Work/Delegates/Info:53 html/Work/Delegates/List:12 html/Work/Overview/Info:42
+msgid "Disabled"
+msgstr "停用"
+
+#: html/Ticket/Elements/Tabs:84
+msgid "Display"
+msgstr "显示内容"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Display Access Control List"
+msgstr "显示权限控制清单"
+
+#: lib/RT/Queue_Overlay.pm:74
+msgid "Display Scrip templates for this queue"
+msgstr "显示此表单的模板"
+
+#: lib/RT/Queue_Overlay.pm:77
+msgid "Display Scrips for this queue"
+msgstr "显示此表单的手续"
+
+#: html/Ticket/Elements/ShowHistory:34
+msgid "Display mode"
+msgstr "显示模式"
+
+#: NOT FOUND IN SOURCE
+msgid "Display ticket #%1"
+msgstr "显示第%1号申请单"
+
+#: lib/RT/System.pm:53
+msgid "Do anything and everything"
+msgstr "允许一切操作"
+
+#: html/Elements/Refresh:29
+msgid "Don't refresh this page."
+msgstr "不更新此页面。"
+
+#: html/Search/Elements/PickRestriction:113 html/Work/Search/PickRestriction:95
+msgid "Don't show search results"
+msgstr "不显示查询结果"
+
+#: html/Edit/Elements/Page:19 html/Edit/Elements/Page:21
+msgid "Down"
+msgstr "下一页"
+
+#: html/Ticket/Elements/ShowTransaction:92
+msgid "Download"
+msgstr "下载"
+
+#: NOT FOUND IN SOURCE
+msgid "Dr."
+msgstr "博士"
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:44 html/Ticket/Elements/ShowDates:42 lib/RT/Ticket_Overlay.pm:1179
+msgid "Due"
+msgstr "到期日"
+
+#: NOT FOUND IN SOURCE
+msgid "Due Date"
+msgstr "截止日"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr "无法解读日期 '%1'"
+
+#: bin/rt-commit-handler:753
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr "无法加载申请单 '%1':%2.\\n"
+
+#: html/Work/Tickets/Update.html:46
+msgid "Edit"
+msgstr "编辑"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:132
+msgid "Edit Conditions"
+msgstr "编辑前置条件"
+
+#: html/Admin/Queues/CustomFields.html:44
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr "编辑 %1 的自订字段"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit Custom Fields for queue %1"
+msgstr "编辑表单 %1 的自订字段"
+
+#: html/Search/Bulk.html:143 html/Ticket/ModifyLinks.html:35 html/Work/Search/Bulk.html:93
+msgid "Edit Relationships"
+msgstr "编辑申请单关系"
+
+#: html/Edit/Groups/MemberGroups/Add.html:3 html/Edit/Groups/MemberGroups/index.html:22
+msgid "Edit Subgroups"
+msgstr "新增/维护子群组"
+
+#: html/Admin/Queues/Templates.html:41
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr "编辑表单 %1 的模板"
+
+#: html/Admin/Queues/Workflows.html:42
+#. ($QueueObj->Name)
+msgid "Edit Workflows for queue %1"
+msgstr "编辑表单 %1 的流程"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit keywords"
+msgstr "编辑关键词"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr "编辑手续"
+
+#: html/Admin/Global/index.html:45
+msgid "Edit system templates"
+msgstr "编辑全域模板"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit system workflows"
+msgstr "编辑全域流程"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr "编辑 %1 的模板"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit workflows for %1"
+msgstr "编辑 %1 的流程"
+
+#: html/Admin/Elements/ModifyQueue:24 html/Admin/Queues/Modify.html:118
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr "编辑表单 %1 的设定"
+
+#: html/Admin/Elements/ModifyUser:24
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr "编辑使用者 %1 的设定"
+
+#: html/Admin/Elements/EditCustomField:90
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr "编辑自订字段 %1"
+
+#: html/Admin/Groups/Members.html:31
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr "编辑群组 %1 的成员信息"
+
+#: html/User/Groups/Members.html:128
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr "编辑代理人群组 %1 的成员信息"
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr "编辑模板 %1"
+
+#: html/Admin/Elements/ModifyWorkflow:238
+#. (loc( $WorkflowObj->Name() ))
+msgid "Editing workflow %1"
+msgstr "编辑流程 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Education"
+msgstr "最高学历"
+
+#: NOT FOUND IN SOURCE
+msgid "EffectiveId"
+msgstr "有效编号"
+
+#: lib/RT/Ticket_Overlay.pm:2644 lib/RT/Ticket_Overlay.pm:2712
+msgid "Either base or target must be specified"
+msgstr "需要指定起始申请单或目的申请单"
+
+#: html/Admin/Users/Modify.html:52 html/Admin/Users/Prefs.html:45 html/Elements/SelectUsers:26 html/Ticket/Elements/AddWatchers:55 html/User/Prefs.html:41 html/Work/Delegates/Info:96 html/Work/Overview/Info:78 html/Work/Preferences/Info:16
+msgid "Email"
+msgstr "电子邮件信箱"
+
+#: lib/RT/User_Overlay.pm:247
+msgid "Email address in use"
+msgstr "此电子邮件信箱已被使用"
+
+#: html/Admin/Elements/ModifyUser:41
+msgid "EmailAddress"
+msgstr "电子邮件信箱地址"
+
+#: html/Admin/Elements/ModifyUser:53
+msgid "EmailEncoding"
+msgstr "电子邮件文字编码方式"
+
+#: NOT FOUND IN SOURCE
+msgid "Embark Date"
+msgstr "外籍员工入境日"
+
+#: NOT FOUND IN SOURCE
+msgid "Embarked Date"
+msgstr "抵达日期"
+
+#: NOT FOUND IN SOURCE
+msgid "Embarked Location"
+msgstr "抵达地点"
+
+#: NOT FOUND IN SOURCE
+msgid "Enable Delegates"
+msgstr "代理激活"
+
+#: html/Admin/Elements/EditCustomField:50
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr "启用(取消勾选将停用此自订字段)"
+
+#: html/Admin/Groups/Modify.html:52 html/User/Groups/Modify.html:52
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr "启用(取消勾选将停用此群组)"
+
+#: html/Admin/Queues/Modify.html:83
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr "启用(取消勾选将停用此表单)"
+
+#: html/Admin/Elements/EditCustomFields:98
+msgid "Enabled Custom Fields"
+msgstr "已启用的自订字段"
+
+#: html/Edit/Queues/Basic/Top:75 html/Edit/Queues/List:15
+msgid "Enabled Date"
+msgstr "启用日期"
+
+#: NOT FOUND IN SOURCE
+msgid "Enabled Date:"
+msgstr "激活日期:"
+
+#: html/Admin/Queues/index.html:55
+msgid "Enabled Queues"
+msgstr "已启用的表单"
+
+#: html/Edit/Queues/Basic/Top:66 html/Edit/Queues/List:11
+msgid "Enabled Status"
+msgstr "启用状态"
+
+#: html/Admin/Elements/EditCustomField:106 html/Admin/Groups/Modify.html:116 html/Admin/Queues/Modify.html:140 html/Admin/Users/Modify.html:282 html/User/Groups/Modify.html:116
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr "启用状态 %1"
+
+#: html/Edit/Users/Info:35
+msgid "End of Trial"
+msgstr "试用期满日"
+
+#: NOT FOUND IN SOURCE
+msgid "English Name"
+msgstr "英文姓名"
+
+#: lib/RT/CustomField_Overlay.pm:427
+msgid "Enter multiple values"
+msgstr "键入多重项目"
+
+#: html/Edit/Users/Search.html:15
+msgid "Enter one or more conditions below to search for users"
+msgstr "输入下列单一或复式条件,查询用户数据"
+
+#: lib/RT/CustomField_Overlay.pm:424
+msgid "Enter one value"
+msgstr "键入单一项目"
+
+#: html/Search/Bulk.html:144 html/Ticket/Elements/EditLinks:111 html/Work/Search/Bulk.html:95
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "输入申请单可链接到的申请单编号或网址。以空白隔开。"
+
+#: lib/RT/CustomField_Vendor.pm:20
+msgid "EntryBoolean"
+msgstr "是非填表"
+
+#: lib/RT/CustomField_Vendor.pm:17
+msgid "EntryDate"
+msgstr "日期填表"
+
+#: NOT FOUND IN SOURCE
+msgid "EntryExternal"
+msgstr "系统填表"
+
+#: lib/RT/CustomField_Vendor.pm:16
+msgid "EntryFreeform"
+msgstr "输入填表"
+
+#: NOT FOUND IN SOURCE
+msgid "EntryMultiple"
+msgstr "多选填表"
+
+#: lib/RT/CustomField_Vendor.pm:19
+msgid "EntryNumber"
+msgstr "数值填表"
+
+#: lib/RT/CustomField_Vendor.pm:15
+msgid "EntrySelect"
+msgstr "单选填表"
+
+#: lib/RT/CustomField_Vendor.pm:18
+msgid "EntryTime"
+msgstr "时间填表"
+
+#: html/Elements/Login:39 html/SelfService/Error.html:24 html/SelfService/Error.html:25
+msgid "Error"
+msgstr "错误"
+
+#: NOT FOUND IN SOURCE
+msgid "Error adding watcher"
+msgstr "新增视察员失败"
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr "表单->新增视察员的参数有误"
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr "表单->删除视察员的参数有误"
+
+#: lib/RT/Ticket_Overlay.pm:1364
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr "申请单->新增视察员的参数有误"
+
+#: lib/RT/Ticket_Overlay.pm:1540
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr "申请单->删除视察员的参数有误"
+
+#: etc/initialdata:38
+msgid "Everyone"
+msgstr "所有人"
+
+#: bin/rt-crontool:193
+msgid "Example:"
+msgstr "范例:"
+
+#: html/Edit/Elements/104Buttons:77
+msgid "Export"
+msgstr "汇出"
+
+#: html/Admin/Elements/ModifyUser:63
+msgid "ExternalAuthId"
+msgstr "外部认证帐号"
+
+#: html/Admin/Elements/ModifyUser:57
+msgid "ExternalContactInfoId"
+msgstr "外部联络方式帐号"
+
+#: html/Edit/Global/Basic/Top:64
+msgid "ExternalDatabaseDSN"
+msgstr "外部数据库连结字符串"
+
+#: html/Edit/Global/Basic/Top:68
+msgid "ExternalDatabasePass"
+msgstr "外部数据库口令"
+
+#: html/Edit/Global/Basic/Top:66
+msgid "ExternalDatabaseUser"
+msgstr "外部数据库用户"
+
+#: html/Edit/Global/Basic/Top:62
+msgid "ExternalURL"
+msgstr "外部接口网址"
+
+#: html/Admin/Users/Modify.html:72
+msgid "Extra info"
+msgstr "备注"
+
+#: lib/RT/User_Overlay.pm:361
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr "找不到「内部成员」虚拟群组的使用者。"
+
+#: lib/RT/User_Overlay.pm:368
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr "找不到「非内部成员」虚拟群组的使用者。"
+
+#: bin/rt-crontool:137
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr "无法加载模块 %1. (%2)"
+
+#: NOT FOUND IN SOURCE
+msgid "Feb"
+msgstr "二月"
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "02"
+
+#: NOT FOUND IN SOURCE
+msgid "February"
+msgstr "二月"
+
+#: NOT FOUND IN SOURCE
+msgid "Female"
+msgstr "女"
+
+#: html/Edit/Global/CustomField/List:5 html/Edit/Global/CustomField/Top:9
+msgid "Field Attribute"
+msgstr "字段属性"
+
+#: html/Edit/Global/CustomField/Info:14
+msgid "Field Content:"
+msgstr "字段内容:"
+
+#: html/Edit/Global/CustomField/List:7 html/Edit/Global/CustomField/Top:21
+msgid "Field Description"
+msgstr "字段描述"
+
+#: html/Edit/Global/CustomField/List:6 html/Edit/Global/CustomField/Top:15
+msgid "Field Name"
+msgstr "字段名称"
+
+#: html/Edit/Elements/PickUsers:52 html/Edit/Users/Add.html:47
+msgid "Filter"
+msgstr "筛选"
+
+#: html/Edit/Elements/PickUsers:6 html/Edit/Users/Add.html:7 html/Work/Tickets/Cc:4
+msgid "Filter people"
+msgstr "对象筛选"
+
+#: html/Edit/Elements/PickUsers:68 html/Edit/Users/Add.html:63 html/Work/Tickets/Cc:42
+msgid "Filtered list:"
+msgstr "筛选列表:"
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr "最终"
+
+#: html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:58 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "最低顺位"
+
+#: lib/RT/Ticket_Overlay.pm:1170
+msgid "FinalPriority"
+msgstr "最低顺位"
+
+#: NOT FOUND IN SOURCE
+msgid "Financial Department:"
+msgstr "财务部:"
+
+#: html/Admin/Queues/People.html:60 html/Ticket/Elements/EditPeople:33
+msgid "Find group whose"
+msgstr "寻找群组的"
+
+#: NOT FOUND IN SOURCE
+msgid "Find new/open tickets"
+msgstr "寻找/开启申请单"
+
+#: html/Admin/Queues/People.html:56 html/Admin/Users/index.html:45 html/Ticket/Elements/EditPeople:29
+msgid "Find people whose"
+msgstr "寻找人员的"
+
+#: html/Search/Listing.html:107 html/Work/Search/index.html:88
+msgid "Find tickets"
+msgstr "寻找申请单"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:118
+msgid "Finish Approval"
+msgstr "签核完毕"
+
+#: html/Ticket/Elements/Tabs:57
+msgid "First"
+msgstr "第一项"
+
+#: html/Search/Listing.html:40 html/Work/Search/index.html:17
+msgid "First page"
+msgstr "第一页"
+
+#: html/Edit/Global/Workflow/Owner.html:30
+msgid "First-"
+msgstr "一"
+
+#: NOT FOUND IN SOURCE
+msgid "First-level Admins"
+msgstr "一阶主管"
+
+#: html/Edit/Users/Info:40
+msgid "First-level Users"
+msgstr "一阶主管员工"
+
+#: NOT FOUND IN SOURCE
+msgid "Fixed shift"
+msgstr "固定班"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr "甲 乙 丙"
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr "甲!"
+
+#: html/Search/Bulk.html:86 html/Work/Search/Bulk.html:55
+msgid "Force change"
+msgstr "强制更新"
+
+#: html/Work/Elements/104Header:89
+msgid "Form Processing"
+msgstr "电子表单作业区"
+
+#: html/Search/Listing.html:105 html/Work/Search/index.html:86
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr "找到 %1 张申请单"
+
+#: lib/RT/Interface/Web.pm:904
+msgid "Found Object"
+msgstr "已找到对象"
+
+#: html/Edit/Global/Workflow/Owner.html:33
+msgid "Fourth-"
+msgstr "四"
+
+#: html/Admin/Elements/ModifyUser:43
+msgid "FreeformContactInfo"
+msgstr "联络方式"
+
+#: lib/RT/CustomField_Vendor.pm:11
+msgid "FreeformDate"
+msgstr "日期输入"
+
+#: NOT FOUND IN SOURCE
+msgid "FreeformExternal"
+msgstr "系统字段"
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformMultiple"
+msgstr "多重输入"
+
+#: lib/RT/CustomField_Vendor.pm:13
+msgid "FreeformNumber"
+msgstr "数值输入"
+
+#: lib/RT/CustomField_Vendor.pm:14
+msgid "FreeformPassword"
+msgstr "口令输入"
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "FreeformSingle"
+msgstr "单一输入"
+
+#: lib/RT/CustomField_Vendor.pm:12
+msgid "FreeformTime"
+msgstr "时间输入"
+
+#: NOT FOUND IN SOURCE
+msgid "Fri"
+msgstr "星期五"
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "星期五"
+
+#: html/Ticket/Elements/ShowHistory:40 html/Ticket/Elements/ShowHistory:50
+msgid "Full headers"
+msgstr "完整标头档"
+
+#: NOT FOUND IN SOURCE
+msgid "Gecos"
+msgstr "登入帐号"
+
+#: html/Edit/Users/Info:26
+msgid "Gender"
+msgstr "性别"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr "取得目前使用者的 pgp 签章\\n"
+
+#: lib/RT/Transaction_Overlay.pm:593
+#. ($New->Name)
+msgid "Given to %1"
+msgstr "交予 %1"
+
+#: html/Admin/Elements/Tabs:40 html/Admin/index.html:37
+msgid "Global"
+msgstr "全域设定"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Keyword Selections"
+msgstr "全域关键词选取"
+
+#: html/Edit/Users/System:24
+msgid "Global Rights:"
+msgstr "拥有全域权限列表:"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr "全域手续"
+
+#: html/Edit/Elements/Tab:38
+msgid "Global Setup"
+msgstr "全域设定"
+
+#: html/Admin/Elements/SelectTemplate:37 html/Edit/Elements/SelectTemplate:11
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr "全域模板:%1"
+
+#: html/Admin/Elements/EditCustomFields:74 html/Admin/Queues/People.html:58 html/Admin/Queues/People.html:62 html/Admin/Queues/index.html:43 html/Admin/Users/index.html:48 html/Ticket/Elements/EditPeople:31 html/Ticket/Elements/EditPeople:35 html/index.html:40
+msgid "Go!"
+msgstr "执行"
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr "%1 的 pgp 签章是正确的\\n"
+
+#: html/Search/Listing.html:49
+msgid "Goto page"
+msgstr "到页面"
+
+#: html/Elements/GotoTicket:24 html/SelfService/Elements/GotoTicket:24 html/Work/Elements/104Header:49
+msgid "Goto ticket"
+msgstr "跳到申请单"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:224
+msgid "Grand"
+msgstr "上"
+
+#: html/Ticket/Elements/AddWatchers:45 html/User/Elements/DelegateRights:77
+msgid "Group"
+msgstr "群组"
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr "群组 %1 %2:%3"
+
+#: html/Edit/Global/GroupRight/List:5 html/Edit/Global/GroupRight/Top:20 html/Edit/Groups/List:7
+msgid "Group Description"
+msgstr "群组描述"
+
+#: NOT FOUND IN SOURCE
+msgid "Group Management"
+msgstr "群组管理"
+
+#: NOT FOUND IN SOURCE
+msgid "Group Members"
+msgstr "群组成员"
+
+#: html/Edit/Elements/PickUsers:28 html/Edit/Global/GroupRight/List:4 html/Edit/Global/GroupRight/Top:10 html/Edit/Groups/List:6 html/Edit/Groups/Top:7 html/Edit/Users/Add.html:29 html/Edit/Users/Group:10 html/Edit/Users/Search.html:43 html/Work/Delegates/Add.html:15 html/Work/Tickets/Cc:24
+msgid "Group Name"
+msgstr "群组名称"
+
+#: NOT FOUND IN SOURCE
+msgid "Group Name:"
+msgstr "群组名称:"
+
+#: html/Admin/Elements/GroupTabs:44 html/Admin/Elements/QueueTabs:56 html/Admin/Elements/SystemTabs:43 html/Admin/Global/index.html:54 html/Edit/Global/autohandler:12 html/Edit/Queues/autohandler:23 html/Edit/Users/Group:11 html/Edit/Users/index.html:123
+msgid "Group Rights"
+msgstr "群组权限"
+
+#: NOT FOUND IN SOURCE
+msgid "Group Rights:"
+msgstr "拥有群组权限列表:"
+
+#: html/Edit/Elements/Tab:34
+msgid "Group Setup"
+msgstr "群组设定"
+
+#: html/Edit/Global/GroupRight/List:8 html/Edit/Global/GroupRight/Top:14 html/Edit/Groups/List:10 html/Edit/Groups/Top:15
+msgid "Group Status"
+msgstr "群组状态"
+
+#: lib/RT/Group_Overlay.pm:964
+msgid "Group already has member"
+msgstr "群组内已有此成员"
+
+#: NOT FOUND IN SOURCE
+msgid "Group could not be created."
+msgstr "无法新增群组"
+
+#: html/Admin/Groups/Modify.html:76
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr "无法新增群组:%1"
+
+#: lib/RT/Group_Overlay.pm:496
+msgid "Group created"
+msgstr "群组新增完毕"
+
+#: lib/RT/Group_Overlay.pm:1132
+msgid "Group has no such member"
+msgstr "群组没有这个成员"
+
+#: lib/RT/Group_Overlay.pm:944 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1437 lib/RT/Ticket_Overlay.pm:1515
+msgid "Group not found"
+msgstr "找不到群组"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr "找不到群组。\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr "未指定群组。\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group with Queue Rights"
+msgstr "拥有表单权限群组"
+
+#: html/Edit/Global/Workflow/Owner.html:70
+msgid "Group's"
+msgstr "群组之"
+
+#: NOT FOUND IN SOURCE
+msgid "Group:"
+msgstr "群组:"
+
+#: html/Admin/Elements/SelectNewGroupMembers:34 html/Admin/Elements/Tabs:34 html/Admin/Groups/Members.html:63 html/Admin/Queues/People.html:82 html/Admin/index.html:31 html/Edit/Global/GroupRight/Add.html:15 html/User/Groups/Members.html:66
+msgid "Groups"
+msgstr "群组"
+
+#: lib/RT/Group_Overlay.pm:970
+msgid "Groups can't be members of their members"
+msgstr "不能将群组设为群组内成员"
+
+#: NOT FOUND IN SOURCE
+msgid "Groups with Global Rights"
+msgstr "拥有全域权限群组"
+
+#: html/Edit/Global/GroupRight/List:6 html/Edit/Global/GroupRight/Top:22 html/Edit/Groups/List:8
+msgid "HRMSDefined"
+msgstr "组织架构"
+
+#: html/Edit/Users/Info:32
+msgid "Health Insurance"
+msgstr "健保补助身份"
+
+#: lib/RT/Interface/CLI.pm:72 lib/RT/Interface/CLI.pm:72
+msgid "Hello!"
+msgstr "嗨!"
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr "嗨,%1"
+
+#: html/Edit/Elements/104Top:27
+msgid "Help"
+msgstr "辅助说明"
+
+#: NOT FOUND IN SOURCE
+msgid "Help Desks"
+msgstr "各项业务窗口"
+
+#: html/Ticket/Elements/ShowHistory:29 html/Ticket/Elements/Tabs:87 html/Work/Tickets/Elements/ShowHistory:8
+msgid "History"
+msgstr "纪录"
+
+#: html/Admin/Elements/ModifyUser:67
+msgid "HomePhone"
+msgstr "住处电话"
+
+#: html/Edit/Elements/104Top:15 html/Edit/Elements/104Top:23 html/Edit/Elements/EDOMHeader:9 html/Elements/Tabs:43
+msgid "Homepage"
+msgstr "主页"
+
+#: NOT FOUND IN SOURCE
+msgid "Hotel Expense"
+msgstr "住宿费"
+
+#: lib/RT/Base.pm:73
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr "我有 %quant(%1,份固体搅拌器)。"
+
+#: NOT FOUND IN SOURCE
+msgid "ID Number"
+msgstr "身分证号"
+
+#: NOT FOUND IN SOURCE
+msgid "ID Type"
+msgstr "身分类别"
+
+#: html/Ticket/Elements/ShowBasics:26 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr "编号"
+
+#: html/Admin/Users/Modify.html:43 html/User/Prefs.html:38 html/Work/Preferences/Info:14
+msgid "Identity"
+msgstr "身份"
+
+#: etc/initialdata:439 etc/upgrade/2.1.71:86 html/Edit/Elements/CreateApprovalsQueue:58
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr "若签核单遭到驳回,则连带驳回原申请单,并删除其它相关的待签核事项"
+
+#: bin/rt-crontool:189
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr "如果此工具程序为 setgid,恶意的本地端用户即能由此取得 RT 的管理员权限。"
+
+#: html/Admin/Queues/People.html:104 html/Ticket/Modify.html:38 html/Ticket/ModifyAll.html:93 html/Ticket/ModifyPeople.html:37
+msgid "If you've updated anything above, be sure to"
+msgstr "若您已更新以上数据,请记得按一下"
+
+#: lib/RT/Interface/Web.pm:896
+msgid "Illegal value for %1"
+msgstr "%1 的值错误"
+
+#: lib/RT/Interface/Web.pm:899
+msgid "Immutable field"
+msgstr "此字段值不可更动"
+
+#: html/Edit/Elements/104Buttons:76 html/Edit/Global/Workflow/Import.html:2
+msgid "Import"
+msgstr "汇入"
+
+#: html/Admin/Elements/EditCustomFields:73
+msgid "Include disabled custom fields in listing."
+msgstr "列出停用的自订字段"
+
+#: html/Admin/Queues/index.html:42 html/Edit/Queues/index.html:38
+msgid "Include disabled queues in listing."
+msgstr "列出停用的表单"
+
+#: html/Admin/Users/index.html:46 html/Edit/Users/Search.html:62
+msgid "Include disabled users in search."
+msgstr "列出停用的使用者"
+
+#: html/Edit/Users/Info:37
+msgid "Indirect Employee"
+msgstr "直接/间接员工"
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr "初始优先权"
+
+#: lib/RT/Ticket_Overlay.pm:1169 lib/RT/Ticket_Overlay.pm:1171
+msgid "InitialPriority"
+msgstr "初始优先权"
+
+#: lib/RT/ScripAction_Overlay.pm:104
+msgid "Input error"
+msgstr "输入错误"
+
+#: NOT FOUND IN SOURCE
+msgid "Interest noted"
+msgstr "登记成功"
+
+#: lib/RT/Ticket_Overlay.pm:3835
+msgid "Internal Error"
+msgstr "内部错误"
+
+#: lib/RT/Record.pm:142
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr "内部错误:%1"
+
+#: lib/RT/Group_Overlay.pm:643
+msgid "Invalid Group Type"
+msgstr "错误的群组类别"
+
+#: lib/RT/Principal_Overlay.pm:126
+msgid "Invalid Right"
+msgstr "错误的权限"
+
+#: NOT FOUND IN SOURCE
+msgid "Invalid Type"
+msgstr "错误的类型"
+
+#: lib/RT/Interface/Web.pm:901
+msgid "Invalid data"
+msgstr "错误的数据"
+
+#: lib/RT/Ticket_Overlay.pm:439
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr "错误的承办人。改为预设承办人「nobody」。"
+
+#: lib/RT/Scrip_Overlay.pm:133 lib/RT/Template_Overlay.pm:250
+msgid "Invalid queue"
+msgstr "错误的表单"
+
+#: lib/RT/ACE_Overlay.pm:243 lib/RT/ACE_Overlay.pm:252 lib/RT/ACE_Overlay.pm:258 lib/RT/ACE_Overlay.pm:269 lib/RT/ACE_Overlay.pm:274
+msgid "Invalid right"
+msgstr "错误的权限"
+
+#: lib/RT/Record.pm:117
+#. ($key)
+msgid "Invalid value for %1"
+msgstr "%1 的值错误"
+
+#: lib/RT/Ticket_Overlay.pm:3470
+msgid "Invalid value for custom field"
+msgstr "错误的自订字段值"
+
+#: lib/RT/Ticket_Overlay.pm:346
+msgid "Invalid value for status"
+msgstr "错误的状态值"
+
+#: NOT FOUND IN SOURCE
+msgid "IssueStatement"
+msgstr "送出陈述"
+
+#: bin/rt-crontool:190
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr "请绝对不要让未具权限的使用者执行此工具程序。"
+
+#: bin/rt-crontool:191
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr "建议您新增一个隶属于正确群组的低权限系统使用者,并以该身份执行此工具程序。"
+
+#: bin/rt-crontool:162
+msgid "It takes several arguments:"
+msgstr "它接受下列参数:"
+
+#: NOT FOUND IN SOURCE
+msgid "Item Name"
+msgstr "品名"
+
+#: NOT FOUND IN SOURCE
+msgid "Items"
+msgstr "笔"
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr "待签核项目"
+
+#: NOT FOUND IN SOURCE
+msgid "Jan"
+msgstr "一月"
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "01"
+
+#: NOT FOUND IN SOURCE
+msgid "January"
+msgstr "一月"
+
+#: NOT FOUND IN SOURCE
+msgid "Job"
+msgstr "职称"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Join or leave this group"
+msgstr "加入或离开此群组"
+
+#: NOT FOUND IN SOURCE
+msgid "Jul"
+msgstr "七月"
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "01"
+
+#: NOT FOUND IN SOURCE
+msgid "July"
+msgstr "七月"
+
+#: html/Ticket/Elements/Tabs:98
+msgid "Jumbo"
+msgstr "全部信息"
+
+#: NOT FOUND IN SOURCE
+msgid "Jun"
+msgstr "六月"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "06."
+
+#: NOT FOUND IN SOURCE
+msgid "June"
+msgstr "六月"
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr "关键词"
+
+#: lib/RT/CustomField_Vendor.pm:21
+msgid "LabelURL"
+msgstr "链接卷标"
+
+#: html/Admin/Elements/ModifyUser:51
+msgid "Lang"
+msgstr "使用语言"
+
+#: html/Ticket/Elements/Tabs:72
+msgid "Last"
+msgstr "上次更新"
+
+#: html/Ticket/Elements/EditDates:37 html/Ticket/Elements/ShowDates:38
+msgid "Last Contact"
+msgstr "上次联络"
+
+#: html/Elements/SelectDateType:28
+msgid "Last Contacted"
+msgstr "上次联络日期"
+
+#: html/Search/Elements/TicketHeader:40 html/Work/Search/TicketHeader:19
+msgid "Last Notified"
+msgstr "上次通知"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Updated"
+msgstr "上次更新"
+
+#: NOT FOUND IN SOURCE
+msgid "LastUpdated"
+msgstr "上次更新"
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr "剩馀时间"
+
+#: html/Admin/Users/Modify.html:82
+msgid "Let this user access RT"
+msgstr "允许这名使用者登入"
+
+#: html/Admin/Users/Modify.html:86
+msgid "Let this user be granted rights"
+msgstr "内部成员(具有个人权限)"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr "限制承办人为 %1 到%2"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr "限制表单为 %1 到 %2"
+
+#: html/Work/Queues/Select.html:4
+msgid "Link a Queue"
+msgstr "申请表单连结"
+
+#: lib/RT/Ticket_Overlay.pm:2726
+msgid "Link already exists"
+msgstr "此链接已存在"
+
+#: lib/RT/Ticket_Overlay.pm:2738
+msgid "Link could not be created"
+msgstr "无法新增链接"
+
+#: lib/RT/Ticket_Overlay.pm:2746 lib/RT/Ticket_Overlay.pm:2756
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr "链接(%1)新增完毕"
+
+#: lib/RT/Ticket_Overlay.pm:2667
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr "链接(%1)删除完毕"
+
+#: lib/RT/Ticket_Overlay.pm:2673
+msgid "Link not found"
+msgstr "找不到链接"
+
+#: html/Ticket/ModifyLinks.html:24 html/Ticket/ModifyLinks.html:28
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr "链接申请单 #%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Link ticket %1"
+msgstr "链接申请单 %1"
+
+#: html/Ticket/Elements/Tabs:96
+msgid "Links"
+msgstr "链接"
+
+#: html/Edit/Users/Search.html:11
+msgid "List All Users"
+msgstr "列出所有用户数据"
+
+#: html/Admin/Users/Modify.html:113 html/User/Prefs.html:84 html/Work/Preferences/Info:72
+msgid "Location"
+msgstr "位置"
+
+#: lib/RT.pm:162
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr "登入目录 %1 找不到或无法写入\\n。无法执行 RT。"
+
+#: html/Edit/Global/Basic/Top:52
+msgid "LogToFile"
+msgstr "纪录等级"
+
+#: html/Edit/Global/Basic/Top:54
+msgid "LogToFileNamed"
+msgstr "纪录档名"
+
+#: html/Elements/Header:56
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "使用者:%1"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:35 html/Elements/Login:44 html/Elements/Login:54
+msgid "Login"
+msgstr "登入"
+
+#: html/Edit/Elements/104Top:17 html/Edit/Elements/104Top:17 html/Edit/Elements/104Top:29 html/Elements/Header:53
+msgid "Logout"
+msgstr "注销"
+
+#: NOT FOUND IN SOURCE
+msgid "Long-term contractor"
+msgstr "长期契约员工"
+
+#: html/Search/Bulk.html:85 html/Work/Search/Bulk.html:54
+msgid "Make Owner"
+msgstr "新增承办人"
+
+#: html/Search/Bulk.html:109 html/Work/Search/Bulk.html:63
+msgid "Make Status"
+msgstr "新增现况"
+
+#: html/Search/Bulk.html:117 html/Work/Search/Bulk.html:75
+msgid "Make date Due"
+msgstr "新增到期日"
+
+#: html/Search/Bulk.html:119 html/Work/Search/Bulk.html:78
+msgid "Make date Resolved"
+msgstr "新增解决日期"
+
+#: html/Search/Bulk.html:113 html/Work/Search/Bulk.html:69
+msgid "Make date Started"
+msgstr "新增实际起始日期"
+
+#: html/Search/Bulk.html:111 html/Work/Search/Bulk.html:66
+msgid "Make date Starts"
+msgstr "新增应起始日期"
+
+#: html/Search/Bulk.html:115 html/Work/Search/Bulk.html:72
+msgid "Make date Told"
+msgstr "新增报告日期"
+
+#: html/Search/Bulk.html:105 html/Work/Search/Bulk.html:57
+msgid "Make priority"
+msgstr "新增优先顺位"
+
+#: html/Search/Bulk.html:107 html/Work/Search/Bulk.html:60
+msgid "Make queue"
+msgstr "新增表单"
+
+#: html/Search/Bulk.html:103 html/Work/Search/Bulk.html:59
+msgid "Make subject"
+msgstr "新增主题"
+
+#: NOT FOUND IN SOURCE
+msgid "Male"
+msgstr "男"
+
+#: html/Admin/index.html:32
+msgid "Manage groups and group membership"
+msgstr "管理群组及所属成员"
+
+#: html/Admin/index.html:38
+msgid "Manage properties and configuration which apply to all queues"
+msgstr "管理适用于所有表单的属性与设定"
+
+#: html/Admin/index.html:35
+msgid "Manage queues and queue-specific properties"
+msgstr "管理各表单及相关属性"
+
+#: html/Admin/index.html:29
+msgid "Manage users and passwords"
+msgstr "管理使用者与口令"
+
+#: NOT FOUND IN SOURCE
+msgid "Manager"
+msgstr "经理"
+
+#: NOT FOUND IN SOURCE
+msgid "Mar"
+msgstr "三月"
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "03"
+
+#: NOT FOUND IN SOURCE
+msgid "March"
+msgstr "三月"
+
+#: NOT FOUND IN SOURCE
+msgid "Marketing Department"
+msgstr "行销部"
+
+#: NOT FOUND IN SOURCE
+msgid "May"
+msgstr "五月"
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "05"
+
+#: lib/RT/Group_Overlay.pm:981
+msgid "Member added"
+msgstr "新增成员完毕"
+
+#: lib/RT/Group_Overlay.pm:1139
+msgid "Member deleted"
+msgstr "成员已删除"
+
+#: lib/RT/Group_Overlay.pm:1143
+msgid "Member not deleted"
+msgstr "成员未被删除"
+
+#: html/Elements/SelectLinkType:25
+msgid "Member of"
+msgstr "隶属于"
+
+#: html/Work/Preferences/index.html:20
+msgid "Member since"
+msgstr "注册日期"
+
+#: NOT FOUND IN SOURCE
+msgid "MemberOf"
+msgstr "隶属于"
+
+#: html/Admin/Elements/GroupTabs:41 html/Admin/Elements/ModifyTemplateAsWorkflow:232 html/User/Elements/GroupTabs:41
+msgid "Members"
+msgstr "成员"
+
+#: lib/RT/Ticket_Overlay.pm:2913
+msgid "Merge Successful"
+msgstr "整合完毕"
+
+#: lib/RT/Ticket_Overlay.pm:2833
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "整合失败。无法设定 EffectiveId"
+
+#: html/Ticket/Elements/BulkLinks:26 html/Ticket/Elements/EditLinks:114 html/Work/Search/BulkLinks:2
+msgid "Merge into"
+msgstr "整合进"
+
+#: html/Search/Bulk.html:137 html/Ticket/Update.html:100
+msgid "Message"
+msgstr "讯息"
+
+#: NOT FOUND IN SOURCE
+msgid "Misc. Expense"
+msgstr "杂费"
+
+#: lib/RT/Interface/Web.pm:903
+msgid "Missing a primary key?: %1"
+msgstr "缺少主键值?(%1)"
+
+#: html/Admin/Users/Modify.html:168 html/User/Prefs.html:53 html/Work/Preferences/Info:33
+msgid "Mobile"
+msgstr "行动电话"
+
+#: html/Admin/Elements/ModifyUser:71
+msgid "MobilePhone"
+msgstr "行动电话"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Modify Access Control List"
+msgstr "更改权限控制清单"
+
+#: html/Admin/Global/CustomFields.html:43 html/Admin/Global/index.html:50
+msgid "Modify Custom Fields which apply to all queues"
+msgstr "更改适用于所有表单的自订字段"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Modify Scrip templates for this queue"
+msgstr "更改此表单的模板"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Modify Scrips for this queue"
+msgstr "更改此表单的手续"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify System ACLS"
+msgstr "更改系统权限清单"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr "更改模板 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Workflow"
+msgstr "更改流程"
+
+#: html/Admin/Queues/CustomField.html:44
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr "更改 %1 表单内的自订字段"
+
+#: html/Admin/Global/CustomField.html:52
+msgid "Modify a CustomField which applies to all queues"
+msgstr "更改适用于所有表单的自订字段"
+
+#: html/Admin/Queues/Scrip.html:53
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr "更改 %1 表单内的手续"
+
+#: html/Admin/Global/Scrip.html:47
+msgid "Modify a scrip which applies to all queues"
+msgstr "更改适用于所有表单的手续"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify dates for # %1"
+msgstr "更改 # %1 的日期"
+
+#: html/Ticket/ModifyDates.html:24 html/Ticket/ModifyDates.html:28
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr "更改 #%1 的日期"
+
+#: html/Ticket/ModifyDates.html:34
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr "更改申请单 # %1 的日期"
+
+#: html/Admin/Global/GroupRights.html:24 html/Admin/Global/GroupRights.html:27 html/Admin/Global/index.html:55
+msgid "Modify global group rights"
+msgstr "更改全域设定的群组权限"
+
+#: html/Admin/Global/GroupRights.html:32
+msgid "Modify global group rights."
+msgstr "更改全域设定的群组权限。"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for groups"
+msgstr "更改全域设定的群组权限"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for users"
+msgstr "更改全域设定的使用者权限"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr "更改全域手续"
+
+#: html/Admin/Global/UserRights.html:24 html/Admin/Global/UserRights.html:27 html/Admin/Global/index.html:59
+msgid "Modify global user rights"
+msgstr "更改全域设定的使用者权限"
+
+#: html/Admin/Global/UserRights.html:32
+msgid "Modify global user rights."
+msgstr "更改全域设定的使用者权限。"
+
+#: lib/RT/Group_Overlay.pm:145
+msgid "Modify group metadata or delete group"
+msgstr "更改群组数据及删除群组"
+
+#: html/Admin/Groups/GroupRights.html:24 html/Admin/Groups/GroupRights.html:28 html/Admin/Groups/GroupRights.html:34
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr "更改 %1 的群组权限"
+
+#: html/Admin/Queues/GroupRights.html:24 html/Admin/Queues/GroupRights.html:28
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr "更改表单 %1 的群组权限"
+
+#: lib/RT/Group_Overlay.pm:147
+msgid "Modify membership roster for this group"
+msgstr "更改此群组的成员名单"
+
+#: lib/RT/System.pm:60
+msgid "Modify one's own RT account"
+msgstr "更改个人的帐号信息"
+
+#: html/Admin/Queues/People.html:24 html/Admin/Queues/People.html:28
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr "更改链接到表单 %1 的人员"
+
+#: html/Ticket/ModifyPeople.html:24 html/Ticket/ModifyPeople.html:28 html/Ticket/ModifyPeople.html:34
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr "更改申请单 #%1 链接到的人员"
+
+#: html/Admin/Queues/Scrips.html:45
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr "更改表单 %1 的手续"
+
+#: html/Admin/Global/Scrips.html:43 html/Admin/Global/index.html:41
+msgid "Modify scrips which apply to all queues"
+msgstr "更改适用于所有表单的手续"
+
+#: html/Admin/Global/Template.html:24 html/Admin/Global/Template.html:29 html/Admin/Global/Template.html:80 html/Admin/Queues/Template.html:77
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr "更改模板 %1"
+
+#: html/Admin/Global/Templates.html:43
+msgid "Modify templates which apply to all queues"
+msgstr "更改适用于所有表单的模板"
+
+#: html/Admin/Groups/Modify.html:86 html/User/Groups/Modify.html:85
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr "更改群组 %1"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify the queue watchers"
+msgstr "更改表单视察员"
+
+#: html/Admin/Users/Modify.html:235
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr "更改使用者 %1"
+
+#: html/Ticket/ModifyAll.html:36
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "更改申请单 # %1"
+
+#: html/Ticket/Modify.html:24 html/Ticket/Modify.html:27 html/Ticket/Modify.html:33
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "更改申请单 # %1"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Modify tickets"
+msgstr "更改申请单"
+
+#: html/Admin/Groups/UserRights.html:24 html/Admin/Groups/UserRights.html:28 html/Admin/Groups/UserRights.html:34
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr "更改群组 %1 的使用者权限"
+
+#: html/Admin/Queues/UserRights.html:24 html/Admin/Queues/UserRights.html:28
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr "更改表单 %1 的使用者权限"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr "更改 '%1' 的视察员"
+
+#: html/Admin/Global/Workflow.html:25 html/Admin/Global/Workflow.html:30 html/Admin/Global/Workflow.html:81 html/Admin/Queues/Workflow.html:77
+#. (loc($WorkflowObj->Name()))
+#. ($WorkflowObj->id)
+msgid "Modify workflow %1"
+msgstr "更改流程 %1"
+
+#: html/Admin/Global/Workflows.html:44
+msgid "Modify workflows which apply to all queues"
+msgstr "更改适用于所有表单的流程"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ModifyACL"
+msgstr "更改权限清单"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "ModifyOwnMembership"
+msgstr "更改自己是否属于某群组"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyQueueWatchers"
+msgstr "更改表单视察员"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ModifyScrips"
+msgstr "更改手续"
+
+#: lib/RT/System.pm:60
+msgid "ModifySelf"
+msgstr "更改个人帐号"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "ModifyTemplate"
+msgstr "更改模板"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "ModifyTicket"
+msgstr "更改申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "Mon"
+msgstr "星期一"
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "星期一"
+
+#: html/Ticket/Elements/ShowRequestor:41
+#. ($name)
+msgid "More about %1"
+msgstr "关于 %1 的进一步信息"
+
+#: NOT FOUND IN SOURCE
+msgid "Morning Shift"
+msgstr "早班"
+
+#: html/Edit/Elements/ListButtons:16
+msgid "Move All"
+msgstr "全移"
+
+#: html/Admin/Elements/EditCustomFields:60
+msgid "Move down"
+msgstr "下移"
+
+#: html/Admin/Elements/EditCustomFields:52
+msgid "Move up"
+msgstr "上移"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Multiple"
+msgstr "多重"
+
+#: lib/RT/User_Overlay.pm:238
+msgid "Must specify 'Name' attribute"
+msgstr "必须指定 'Name' 的属性"
+
+#: html/SelfService/Elements/MyRequests:48
+#. ($friendly_status)
+msgid "My %1 tickets"
+msgstr "我的 %1 申请单"
+
+#: html/Work/Elements/Tab:35
+msgid "My Approvals"
+msgstr "表单签核"
+
+#: html/Work/Elements/Tab:33
+msgid "My Requests"
+msgstr "表单申请追踪"
+
+#: html/Work/Elements/Tab:37
+msgid "My Tickets"
+msgstr "表单处理"
+
+#: html/Approvals/index.html:24 html/Approvals/index.html:25
+msgid "My approvals"
+msgstr "表单签核"
+
+#: html/Admin/Elements/AddCustomFieldValue:31 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/ModifyTemplate:27 html/Admin/Elements/ModifyTemplateAsWorkflow:185 html/Admin/Elements/ModifyUser:29 html/Admin/Groups/Modify.html:43 html/Edit/Users/Add.html:22 html/Edit/Users/Search.html:31 html/Elements/SelectGroups:25 html/Elements/SelectUsers:27 html/User/Groups/Modify.html:43 html/Work/Tickets/Cc:18
+msgid "Name"
+msgstr "名称"
+
+#: lib/RT/User_Overlay.pm:245
+msgid "Name in use"
+msgstr "帐号已有人使用"
+
+#: html/Edit/Users/Info:27
+msgid "Nationality"
+msgstr "国籍"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr "需先由系统管理员进行批准"
+
+#: html/Ticket/Elements/ShowDates:51
+msgid "Never"
+msgstr "从未更动"
+
+#: html/Elements/Quicksearch:29 html/Work/Elements/Quicksearch:15 html/Work/Tickets/Create.html:52
+msgid "New"
+msgstr "新建立"
+
+#: html/Admin/Elements/ModifyUser:31 html/Admin/Users/Modify.html:92 html/User/Prefs.html:64 html/Work/Preferences/Info:44
+msgid "New Password"
+msgstr "新的口令"
+
+#: etc/initialdata:341 etc/upgrade/2.1.71:16 html/Edit/Elements/CreateApprovalsQueue:21
+msgid "New Pending Approval"
+msgstr "新的待签核事项"
+
+#: html/Ticket/Elements/EditLinks:110
+msgid "New Relationships"
+msgstr "新增关系"
+
+#: html/Work/Elements/Tab:31
+msgid "New Request"
+msgstr "表单申请"
+
+#: html/Ticket/Elements/Tabs:35
+msgid "New Search"
+msgstr "新增查询"
+
+#: html/Admin/Global/CustomField.html:40 html/Admin/Global/CustomFields.html:38 html/Admin/Queues/CustomField.html:51 html/Admin/Queues/CustomFields.html:39
+msgid "New custom field"
+msgstr "新增自订字段"
+
+#: html/Admin/Elements/GroupTabs:53 html/User/Elements/GroupTabs:51
+msgid "New group"
+msgstr "新增群组"
+
+#: html/SelfService/Prefs.html:31
+msgid "New password"
+msgstr "新的口令"
+
+#: lib/RT/User_Overlay.pm:706
+msgid "New password notification sent"
+msgstr "送出新口令通知"
+
+#: html/Admin/Elements/QueueTabs:69
+msgid "New queue"
+msgstr "新增表单"
+
+#: NOT FOUND IN SOURCE
+msgid "New request"
+msgstr "提出申请单"
+
+#: html/Admin/Elements/SelectRights:41
+msgid "New rights"
+msgstr "新增权限"
+
+#: html/Admin/Global/Scrip.html:39 html/Admin/Global/Scrips.html:38 html/Admin/Queues/Scrip.html:42 html/Admin/Queues/Scrips.html:54
+msgid "New scrip"
+msgstr "新增手续"
+
+#: html/Work/Search/index.html:62
+msgid "New search"
+msgstr "重新查询"
+
+#: html/Admin/Global/Template.html:59 html/Admin/Global/Templates.html:38 html/Admin/Queues/Template.html:57 html/Admin/Queues/Templates.html:49
+msgid "New template"
+msgstr "新增模板"
+
+#: html/SelfService/Elements/Tabs:47
+msgid "New ticket"
+msgstr "提出申请单"
+
+#: lib/RT/Ticket_Overlay.pm:2800
+msgid "New ticket doesn't exist"
+msgstr "没有新申请单"
+
+#: html/Admin/Elements/UserTabs:51
+msgid "New user"
+msgstr "新增使用者"
+
+#: html/Admin/Elements/CreateUserCalled:25
+msgid "New user called"
+msgstr "新使用者名字"
+
+#: html/Admin/Queues/People.html:54 html/Ticket/Elements/EditPeople:28
+msgid "New watchers"
+msgstr "新视察员"
+
+#: html/Admin/Users/Prefs.html:41
+msgid "New window setting"
+msgstr "更新窗口设定"
+
+#: html/Admin/Global/Workflow.html:60 html/Admin/Global/Workflows.html:39 html/Admin/Queues/Workflow.html:57 html/Admin/Queues/Workflows.html:50
+msgid "New workflow"
+msgstr "新增流程"
+
+#: html/Ticket/Elements/Tabs:68
+msgid "Next"
+msgstr "下一项"
+
+#: html/Search/Listing.html:47 html/Work/Search/index.html:24
+msgid "Next page"
+msgstr "下一页"
+
+#: html/Admin/Elements/ModifyUser:49
+msgid "NickName"
+msgstr "昵称"
+
+#: html/Admin/Users/Modify.html:62 html/User/Prefs.html:45 html/Work/Preferences/Info:23
+msgid "Nickname"
+msgstr "昵称"
+
+#: NOT FOUND IN SOURCE
+msgid "Night Shift"
+msgstr "小夜班"
+
+#: html/Edit/Global/Basic/Top:27
+msgid "No"
+msgstr "否"
+
+#: html/Admin/Elements/EditCustomField:89 html/Admin/Elements/EditCustomFields:104
+msgid "No CustomField"
+msgstr "无自订字段"
+
+#: html/Admin/Groups/GroupRights.html:83 html/Admin/Groups/UserRights.html:70
+msgid "No Group defined"
+msgstr "尚未定义群组"
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:67
+msgid "No Queue defined"
+msgstr "没有定义好的表单"
+
+#: bin/rt-crontool:55
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr "找不到 RT 使用者。请向 RT 管理员查询。\\n"
+
+#: html/Admin/Global/Template.html:78 html/Admin/Queues/Template.html:75
+msgid "No Template"
+msgstr "没有模板"
+
+#: bin/rt-commit-handler:763
+msgid "No Ticket specified. Aborting ticket "
+msgstr "未指定申请单。退出申请单 "
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr "未指定申请单。退出申请单更改\\n\\n"
+
+#: html/Admin/Elements/ModifyWorkflow:237 html/Admin/Global/Workflow.html:79 html/Admin/Queues/Workflow.html:75
+msgid "No Workflow"
+msgstr "没有流程"
+
+#: html/Approvals/Elements/Approve:45 html/Work/Approvals/Elements/Approve:35
+msgid "No action"
+msgstr "暂不处理"
+
+#: lib/RT/Interface/Web.pm:898
+msgid "No column specified"
+msgstr "未指定字段"
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr "找不到命令"
+
+#: html/Elements/ViewUser:35 html/Ticket/Elements/ShowRequestor:44
+msgid "No comment entered about this user"
+msgstr "没有对这名使用者的评论"
+
+#: lib/RT/Ticket_Overlay.pm:2211 lib/RT/Ticket_Overlay.pm:2279
+msgid "No correspondence attached"
+msgstr "没有附上申请单回复"
+
+#: lib/RT/Action/Generic.pm:149 lib/RT/Condition/Generic.pm:175 lib/RT/Search/ActiveTicketsInQueue.pm:55 lib/RT/Search/Generic.pm:112
+#. (ref $self)
+msgid "No description for %1"
+msgstr "没有对 %1 的描述"
+
+#: lib/RT/Users_Overlay.pm:150
+msgid "No group specified"
+msgstr "未指定群组"
+
+#: lib/RT/User_Overlay.pm:924
+msgid "No password set"
+msgstr "没有设定口令"
+
+#: lib/RT/Queue_Overlay.pm:260
+msgid "No permission to create queues"
+msgstr "没有新增表单的权限"
+
+#: lib/RT/Ticket_Overlay.pm:342
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr "没有在表单 '%1' 新增申请单的权限"
+
+#: lib/RT/User_Overlay.pm:211
+msgid "No permission to create users"
+msgstr "没有新增使用者的权限"
+
+#: html/SelfService/Display.html:117
+msgid "No permission to display that ticket"
+msgstr "没有显示该申请单的权限"
+
+#: html/SelfService/Update.html:51
+msgid "No permission to view update ticket"
+msgstr "没有检视申请单更新的权限"
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1496
+msgid "No principal specified"
+msgstr "未指定单位"
+
+#: html/Admin/Queues/People.html:153 html/Admin/Queues/People.html:163
+msgid "No principals selected."
+msgstr "未指定单位。"
+
+#: NOT FOUND IN SOURCE
+msgid "No protocol specified in %1"
+msgstr "%1 内未指定协议"
+
+#: html/Admin/Queues/index.html:34
+msgid "No queues matching search criteria found."
+msgstr "找不到符合查询条件的表单。"
+
+#: html/Admin/Elements/SelectRights:80
+msgid "No rights found"
+msgstr "找不到权限"
+
+#: html/Admin/Elements/SelectRights:32
+msgid "No rights granted."
+msgstr "没有选定权限"
+
+#: html/Search/Bulk.html:160 html/Work/Search/Bulk.html:117
+msgid "No search to operate on."
+msgstr "没有要进行的查询"
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr "未指定申请单编号"
+
+#: lib/RT/Transaction_Overlay.pm:478 lib/RT/Transaction_Overlay.pm:516
+msgid "No transaction type specified"
+msgstr "未指定更动报告类别"
+
+#: NOT FOUND IN SOURCE
+msgid "No user or email address specified"
+msgstr "未指定使用者或电子邮件地址"
+
+#: html/Admin/Users/index.html:35
+msgid "No users matching search criteria found."
+msgstr "找不到符合查询条件的使用者。"
+
+#: bin/rt-commit-handler:643
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr "找不到合格的 RT 使用者。RT cvs 处理器已停用。请向 RT 管理者询问。\\n"
+
+#: lib/RT/Interface/Web.pm:895
+msgid "No value sent to _Set!\\n"
+msgstr "_Set 没有收到任何值!\\n"
+
+#: html/Search/Elements/TicketRow:36 html/Work/Search/TicketRow:9
+msgid "Nobody"
+msgstr "没有人"
+
+#: lib/RT/Interface/Web.pm:900
+msgid "Nonexistant field?"
+msgstr "字段不存在?"
+
+#: NOT FOUND IN SOURCE
+msgid "Normal Users"
+msgstr "一般用户群组"
+
+#: NOT FOUND IN SOURCE
+msgid "Not configured to fetch the content from a %1 in %2"
+msgstr "未设定成从 %2 内撷取 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Not logged in"
+msgstr "尚未登入"
+
+#: html/Elements/Header:58
+msgid "Not logged in."
+msgstr "尚未登入"
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "尚未设定"
+
+#: html/NoAuth/Reminder.html:26
+msgid "Not yet implemented."
+msgstr "尚未完工。"
+
+#: NOT FOUND IN SOURCE
+msgid "Not yet implemented...."
+msgstr "尚未完工..."
+
+#: html/Approvals/Elements/Approve:48 html/Work/Tickets/Create.html:134
+msgid "Notes"
+msgstr "备注"
+
+#: NOT FOUND IN SOURCE
+msgid "Notes:"
+msgstr "备注:"
+
+#: lib/RT/User_Overlay.pm:709
+msgid "Notification could not be sent"
+msgstr "无法送出通知"
+
+#: etc/initialdata:111
+msgid "Notify AdminCcs"
+msgstr "通知管理员副本收件人"
+
+#: etc/initialdata:107
+msgid "Notify AdminCcs as Comment"
+msgstr "以评论方式通知管理员副本收件人"
+
+#: etc/initialdata:138
+msgid "Notify Other Recipients"
+msgstr "通知其它收件人"
+
+#: etc/initialdata:134
+msgid "Notify Other Recipients as Comment"
+msgstr "以评论方式通知其它收件人"
+
+#: etc/initialdata:103
+msgid "Notify Owner"
+msgstr "通知承办人"
+
+#: etc/initialdata:99
+msgid "Notify Owner as Comment"
+msgstr "以评论方式通知承办人"
+
+#: etc/initialdata:385
+msgid "Notify Owner of their rejected ticket"
+msgstr "通知承办人申请单已驳回"
+
+#: etc/initialdata:374
+msgid "Notify Owner of their ticket has been approved by all approvers"
+msgstr "通知承办人申请单已完成全部签核"
+
+#: etc/initialdata:359
+msgid "Notify Owner of their ticket has been approved by some approver"
+msgstr "通知承办人申请单已完成某项签核"
+
+#: etc/initialdata:343 etc/upgrade/2.1.71:17 html/Edit/Elements/CreateApprovalsQueue:22
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr "整理待签核事项,通知承办人及管理员副本收件人"
+
+#: etc/initialdata:95
+msgid "Notify Requestors"
+msgstr "通知申请人"
+
+#: etc/initialdata:121
+msgid "Notify Requestors and Ccs"
+msgstr "通知申请人及副本收件人"
+
+#: etc/initialdata:116
+msgid "Notify Requestors and Ccs as Comment"
+msgstr "以评论方式通知申请人及副本收件人"
+
+#: etc/initialdata:130
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr "通知申请人、副本及管理员副本收件人"
+
+#: etc/initialdata:126
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr "以评论方式通知申请人、副本及管理员副本收件人"
+
+#: html/Work/Tickets/Cc:55
+msgid "Notify people:"
+msgstr "通知对象"
+
+#: NOT FOUND IN SOURCE
+msgid "Nov"
+msgstr "十一月"
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "11"
+
+#: NOT FOUND IN SOURCE
+msgid "November"
+msgstr "十一月"
+
+#: html/Edit/Global/Basic/Top:74
+msgid "OIN104"
+msgstr "配合 104eHRMS 接口"
+
+#: html/Edit/Global/Workflow/Export.html:30 html/Work/Copyright.html:23
+msgid "OK"
+msgstr "确定"
+
+#: lib/RT/Record.pm:156
+msgid "Object could not be created"
+msgstr "无法新增对象"
+
+#: lib/RT/Record.pm:175
+msgid "Object created"
+msgstr "对象新增完毕"
+
+#: html/Edit/Users/Info:36
+msgid "Occupation Status"
+msgstr "在职状态"
+
+#: NOT FOUND IN SOURCE
+msgid "Oct"
+msgstr "十月"
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "10"
+
+#: NOT FOUND IN SOURCE
+msgid "October"
+msgstr "十月"
+
+#: html/Edit/Users/Info:33
+msgid "Office Phone"
+msgstr "办公室电话"
+
+#: html/Elements/SelectDateRelation:34
+msgid "On"
+msgstr "等于"
+
+#: etc/initialdata:173
+msgid "On Comment"
+msgstr "评论时"
+
+#: etc/initialdata:166
+msgid "On Correspond"
+msgstr "回复申请单时"
+
+#: etc/initialdata:155
+msgid "On Create"
+msgstr "新增申请单时"
+
+#: etc/initialdata:187
+msgid "On Owner Change"
+msgstr "承办人改变时"
+
+#: etc/initialdata:195
+msgid "On Queue Change"
+msgstr "表单改变时"
+
+#: etc/initialdata:201
+msgid "On Resolve"
+msgstr "解决申请单时"
+
+#: etc/initialdata:179
+msgid "On Status Change"
+msgstr "现况改变时"
+
+#: etc/initialdata:160
+msgid "On Transaction"
+msgstr "发生更动时"
+
+#: html/Approvals/Elements/PendingMyApproval:49
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr "仅显示 %1 之后新增的申请单"
+
+#: html/Approvals/Elements/PendingMyApproval:47
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr "仅显示 %1 之前新增的申请单"
+
+#: html/Edit/Global/GroupRight/List:9 html/Edit/Global/GroupRight/Top:16 html/Edit/Groups/List:11 html/Edit/Groups/Top:18 html/Edit/Queues/Basic/Top:69 html/Edit/Queues/List:13 html/Elements/Quicksearch:30 html/Work/Delegates/Info:48 html/Work/Delegates/Info:51 html/Work/Delegates/List:12 html/Work/Elements/Quicksearch:16 html/Work/Overview/Info:41 html/Work/Tickets/Display.html:28
+msgid "Open"
+msgstr "开启"
+
+#: html/Ticket/Elements/Tabs:135
+msgid "Open it"
+msgstr "开启"
+
+#: html/SelfService/Elements/Tabs:41
+msgid "Open tickets"
+msgstr "开启的申请单"
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in a new window"
+msgstr "在新窗口开启(列表的)申请单"
+
+#: html/Admin/Users/Prefs.html:39
+msgid "Open tickets (from listing) in another window"
+msgstr "在另一个窗口开启(列表的)申请单"
+
+#: etc/initialdata:150
+msgid "Open tickets on correspondence"
+msgstr "收到回复时即开启申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "Opened Tickets"
+msgstr "已申请运行中表单"
+
+#: NOT FOUND IN SOURCE
+msgid "Opinion"
+msgstr "意见"
+
+#: html/Edit/Global/CustomField/Info:35
+msgid "Option Description"
+msgstr "选项描述"
+
+#: html/Edit/Global/CustomField/Info:29
+msgid "Option Name"
+msgstr "选项名称"
+
+#: html/Search/Elements/PickRestriction:100 html/Work/Search/PickRestriction:81
+msgid "Ordering and sorting"
+msgstr "顺序与排序方式"
+
+#: html/Admin/Elements/ModifyUser:45 html/Admin/Users/Modify.html:116 html/Edit/Global/Basic/Top:50 html/Elements/SelectUsers:28 html/User/Prefs.html:85 html/Work/Preferences/Info:74
+msgid "Organization"
+msgstr "组织名称"
+
+#: NOT FOUND IN SOURCE
+msgid "Organization:"
+msgstr "组织:"
+
+#: html/Approvals/Elements/Approve:32
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr "原申请单:#%1"
+
+#: html/Edit/Elements/PickUsers:109 html/Edit/Users/Add.html:106 html/Work/Tickets/Cc:80
+msgid "Other comma-delimited email addresses"
+msgstr "其它e-mail帐号 (仅e-mail通知;多笔帐号请用逗号','区隔)"
+
+#: html/Admin/Elements/ModifyQueue:54 html/Admin/Queues/Modify.html:68 html/Edit/Queues/Basic/Top:41
+msgid "Over time, priority moves toward"
+msgstr "优先顺位随时间增加调整为"
+
+#: NOT FOUND IN SOURCE
+msgid "Override current custom fields with fields from %1"
+msgstr "以 %1 表单的自订字段取代现有字段"
+
+#: html/Admin/Elements/CheckOverrideGlobalACL:25
+msgid "Override global rights"
+msgstr "取代全域权限"
+
+#: html/Admin/Elements/CheckOverrideGlobalACL:34
+#. (loc_fuzzy($msg))
+msgid "OverrideGlobalACL status %1"
+msgstr "取代全域权限 %1"
+
+#: html/Work/Elements/Tab:29
+msgid "Overview"
+msgstr "总览"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Own tickets"
+msgstr "承办申请单"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "OwnTicket"
+msgstr "承办申请单"
+
+#: etc/initialdata:56 html/Admin/Elements/ModifyTemplateAsWorkflow:141 html/Edit/Global/Workflow/Owner.html:19 html/Edit/Queues/Basic/Top:47 html/Edit/Queues/Basic/Top:58 html/Elements/MyRequests:31 html/SelfService/Elements/MyRequests:29 html/Ticket/Create.html:47 html/Ticket/Elements/EditPeople:42 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/ShowPeople:26 html/Ticket/Update.html:62 html/Work/Elements/MyRequests:13 html/Work/Elements/Quicksearch:18 html/Work/Tickets/Elements/ShowBasics:21 html/Work/Tickets/Update.html:27 lib/RT/ACE_Overlay.pm:85 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "承办人"
+
+#: NOT FOUND IN SOURCE
+msgid "Owner changed from %1 to %2"
+msgstr "承办人已从 %1 改为 %2"
+
+#: lib/RT/Transaction_Overlay.pm:582
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr "强制将承办人从 %1 改为 %2"
+
+#: html/Search/Elements/PickRestriction:30 html/Work/Search/PickRestriction:10
+msgid "Owner is"
+msgstr "承办人"
+
+#: html/Work/Elements/List:27 html/Work/Queues/List:8 html/Work/Tickets/Create.html:54 html/Work/Tickets/Elements/ShowBasics:52
+msgid "Owner's Phone"
+msgstr "承办人电话"
+
+#: html/Edit/Elements/Page:39
+msgid "Page"
+msgstr " "
+
+#: html/Admin/Users/Modify.html:173 html/User/Prefs.html:55 html/Work/Preferences/Info:35
+msgid "Pager"
+msgstr "呼叫器"
+
+#: html/Admin/Elements/ModifyUser:73
+msgid "PagerPhone"
+msgstr "呼叫器号码"
+
+#: html/Edit/Global/Workflow/Action:81 html/Edit/Global/Workflow/Condition:66
+msgid "Parameter"
+msgstr "呼叫参数"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:225
+msgid "Parent"
+msgstr "上级"
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/BulkLinks:38 html/Ticket/Elements/EditLinks:126 html/Ticket/Elements/EditLinks:57 html/Ticket/Elements/ShowLinks:46 html/Work/Search/BulkLinks:14
+msgid "Parents"
+msgstr "母申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "Park Space"
+msgstr "停车位申请"
+
+#: html/Elements/Login:52 html/User/Prefs.html:60 html/Work/Preferences/Info:41
+msgid "Password"
+msgstr "口令"
+
+#: html/NoAuth/Reminder.html:24
+msgid "Password Reminder"
+msgstr "口令提示"
+
+#: lib/RT/User_Overlay.pm:228 lib/RT/User_Overlay.pm:927
+msgid "Password too short"
+msgstr "口令太短"
+
+#: html/Admin/Users/Modify.html:290 html/User/Prefs.html:171 html/Work/Preferences/Info:162
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "口令:%1"
+
+#: html/Admin/Users/Modify.html:292
+msgid "Passwords do not match."
+msgstr "口令确认失败。"
+
+#: html/User/Prefs.html:173 html/Work/Preferences/Info:164
+msgid "Passwords do not match. Your password has not been changed"
+msgstr "口令确认失败。您的口令并未改变。"
+
+#: NOT FOUND IN SOURCE
+msgid "Pelase select a queue"
+msgstr "请选择表单名称"
+
+#: NOT FOUND IN SOURCE
+msgid "Pending Approval"
+msgstr "等待签核"
+
+#: html/Ticket/Elements/ShowSummary:44 html/Ticket/Elements/Tabs:95 html/Ticket/ModifyAll.html:50
+msgid "People"
+msgstr "人员"
+
+#: NOT FOUND IN SOURCE
+msgid "People with Queue Rights"
+msgstr "拥有表单权限人员"
+
+#: etc/initialdata:143
+msgid "Perform a user-defined action"
+msgstr "执行使用者自订的动作"
+
+#: lib/RT/ACE_Overlay.pm:230 lib/RT/ACE_Overlay.pm:236 lib/RT/ACE_Overlay.pm:562 lib/RT/ACE_Overlay.pm:572 lib/RT/ACE_Overlay.pm:582 lib/RT/ACE_Overlay.pm:647 lib/RT/CurrentUser.pm:82 lib/RT/CurrentUser.pm:91 lib/RT/CustomField_Overlay.pm:100 lib/RT/CustomField_Overlay.pm:201 lib/RT/CustomField_Overlay.pm:233 lib/RT/CustomField_Overlay.pm:510 lib/RT/CustomField_Overlay.pm:90 lib/RT/Group_Overlay.pm:1094 lib/RT/Group_Overlay.pm:1098 lib/RT/Group_Overlay.pm:1107 lib/RT/Group_Overlay.pm:1158 lib/RT/Group_Overlay.pm:1162 lib/RT/Group_Overlay.pm:1168 lib/RT/Group_Overlay.pm:425 lib/RT/Group_Overlay.pm:517 lib/RT/Group_Overlay.pm:595 lib/RT/Group_Overlay.pm:603 lib/RT/Group_Overlay.pm:700 lib/RT/Group_Overlay.pm:704 lib/RT/Group_Overlay.pm:710 lib/RT/Group_Overlay.pm:903 lib/RT/Group_Overlay.pm:907 lib/RT/Group_Overlay.pm:920 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:125 lib/RT/Scrip_Overlay.pm:136 lib/RT/Scrip_Overlay.pm:196 lib/RT/Scrip_Overlay.pm:429 lib/RT/Template_Overlay.pm:283 lib/RT/Template_Overlay.pm:87 lib/RT/Template_Overlay.pm:93 lib/RT/Ticket_Overlay.pm:1349 lib/RT/Ticket_Overlay.pm:1359 lib/RT/Ticket_Overlay.pm:1373 lib/RT/Ticket_Overlay.pm:1526 lib/RT/Ticket_Overlay.pm:1535 lib/RT/Ticket_Overlay.pm:1548 lib/RT/Ticket_Overlay.pm:1897 lib/RT/Ticket_Overlay.pm:2035 lib/RT/Ticket_Overlay.pm:2199 lib/RT/Ticket_Overlay.pm:2266 lib/RT/Ticket_Overlay.pm:2625 lib/RT/Ticket_Overlay.pm:2697 lib/RT/Ticket_Overlay.pm:2791 lib/RT/Ticket_Overlay.pm:2806 lib/RT/Ticket_Overlay.pm:3005 lib/RT/Ticket_Overlay.pm:3015 lib/RT/Ticket_Overlay.pm:3020 lib/RT/Ticket_Overlay.pm:3242 lib/RT/Ticket_Overlay.pm:3440 lib/RT/Ticket_Overlay.pm:3602 lib/RT/Ticket_Overlay.pm:3654 lib/RT/Ticket_Overlay.pm:3829 lib/RT/Transaction_Overlay.pm:466 lib/RT/Transaction_Overlay.pm:473 lib/RT/Transaction_Overlay.pm:502 lib/RT/Transaction_Overlay.pm:509 lib/RT/User_Overlay.pm:1021 lib/RT/User_Overlay.pm:1414 lib/RT/User_Overlay.pm:629 lib/RT/User_Overlay.pm:664 lib/RT/User_Overlay.pm:920
+msgid "Permission Denied"
+msgstr "权限不足"
+
+#: html/Edit/Rights/index.html:3
+msgid "Permission Settings"
+msgstr "权限设定"
+
+#: NOT FOUND IN SOURCE
+msgid "Permitted Queues:"
+msgstr "拥有权限表单列表:"
+
+#: NOT FOUND IN SOURCE
+msgid "Personal"
+msgstr "代理人群组"
+
+#: html/User/Elements/Tabs:34
+msgid "Personal Groups"
+msgstr "代理人群组"
+
+#: NOT FOUND IN SOURCE
+msgid "Personal Todo"
+msgstr "私人待办事项"
+
+#: html/User/Groups/index.html:29 html/User/Groups/index.html:39
+msgid "Personal groups"
+msgstr "代理人群组"
+
+#: html/User/Elements/DelegateRights:36
+msgid "Personal groups:"
+msgstr "代理人群组:"
+
+#: html/Work/Preferences/Info:21
+msgid "PersonalHomepage"
+msgstr "个人首页"
+
+#: NOT FOUND IN SOURCE
+msgid "Phone"
+msgstr "电话"
+
+#: html/Work/Delegates/Info:90 html/Work/Overview/Info:72
+msgid "Phone number"
+msgstr "电话号码"
+
+#: html/Admin/Users/Modify.html:155 html/User/Prefs.html:48 html/Work/Preferences/Info:27
+msgid "Phone numbers"
+msgstr "电话号码"
+
+#: html/Edit/Users/Add.html:3 html/Work/Delegates/Add.html:3 html/Work/Delegates/Info:34 html/Work/Tickets/ModifyPeople.html:2
+msgid "Pick"
+msgstr "挑选"
+
+#: NOT FOUND IN SOURCE
+msgid "Place of Departure"
+msgstr "出发地点"
+
+#: NOT FOUND IN SOURCE
+msgid "Placeholder"
+msgstr "尚未完工"
+
+#: html/Edit/Elements/PickUsers:31 html/Edit/Elements/PickUsers:44 html/Edit/Elements/SelectCustomFieldType:3 html/Work/Elements/SelectOwner:3 html/Work/Tickets/Elements/EditCustomField:104 html/Work/Tickets/Elements/EditCustomField:185 html/Work/Tickets/Elements/EditCustomField:75 html/Work/Tickets/Elements/EditCustomFieldEntries:66 html/Work/Tickets/Elements/EditCustomFieldEntries:73
+msgid "Please Select"
+msgstr "请选择"
+
+#: html/Edit/Elements/104Buttons:30
+msgid "Please check items to be deleted first."
+msgstr "请先选中要删除的对象"
+
+#: NOT FOUND IN SOURCE
+msgid "Please select a group"
+msgstr "请选择群组"
+
+#: NOT FOUND IN SOURCE
+msgid "Please select a queue's workflow"
+msgstr "请选择表单流程"
+
+#: NOT FOUND IN SOURCE
+msgid "Please select role"
+msgstr "请选择角色"
+
+#: NOT FOUND IN SOURCE
+msgid "Policy"
+msgstr "经营规章"
+
+#: NOT FOUND IN SOURCE
+msgid "Position"
+msgstr "职务"
+
+#: html/Edit/Users/Info:43
+msgid "Position Level"
+msgstr "职等"
+
+#: html/Edit/Elements/PickUsers:41 html/Edit/Global/UserRight/List:13 html/Edit/Global/UserRight/Top:23 html/Edit/Users/Add.html:41 html/Edit/Users/List:11 html/Edit/Users/Top:22 html/Work/Delegates/Add.html:26 html/Work/Delegates/Info:84 html/Work/Overview/Info:66
+msgid "Position Name"
+msgstr "职务名称"
+
+#: html/Edit/Global/UserRight/List:14 html/Edit/Global/UserRight/Top:33 html/Edit/Users/List:12 html/Edit/Users/Top:32
+msgid "Position Number"
+msgstr "职务代码"
+
+#: html/Edit/Users/Info:44
+msgid "Position Rank"
+msgstr "职级"
+
+#: NOT FOUND IN SOURCE
+msgid "Pref"
+msgstr "偏好"
+
+#: html/Edit/Elements/104Top:25 html/Elements/Header:51 html/Elements/Tabs:52 html/SelfService/Elements/Tabs:50 html/SelfService/Prefs.html:24 html/User/Prefs.html:24 html/User/Prefs.html:27 html/Work/Elements/Tab:41
+msgid "Preferences"
+msgstr "偏好"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr "个人信息"
+
+#: lib/RT/Action/Generic.pm:159
+msgid "Prepare Stubbed"
+msgstr "预备动作完毕"
+
+#: html/Ticket/Elements/Tabs:60
+msgid "Prev"
+msgstr "上一项"
+
+#: html/Search/Listing.html:43 html/Work/Search/index.html:20
+msgid "Previous page"
+msgstr "前一页"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr "优先顺位"
+
+#: lib/RT/ACE_Overlay.pm:132 lib/RT/ACE_Overlay.pm:207 lib/RT/ACE_Overlay.pm:551
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr "找不到单位 %1。"
+
+#: html/Search/Elements/PickRestriction:53 html/Ticket/Create.html:153 html/Ticket/Elements/EditBasics:53 html/Ticket/Elements/ShowBasics:38 html/Work/Search/PickRestriction:34 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "优先顺位"
+
+#: html/Admin/Elements/ModifyQueue:50 html/Admin/Queues/Modify.html:64
+msgid "Priority starts at"
+msgstr "优先顺位起始值"
+
+#: etc/initialdata:43
+msgid "Privileged"
+msgstr "内部成员"
+
+#: html/Admin/Users/Modify.html:270 html/User/Prefs.html:162 html/Work/Preferences/Info:153
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr "内部成员状态:%1"
+
+#: html/Admin/Users/index.html:61
+msgid "Privileged users"
+msgstr "内部成员"
+
+#: html/Work/Elements/SelectSearch:16
+msgid "Process Status"
+msgstr "处理状态"
+
+#: etc/initialdata:41 etc/initialdata:47 etc/initialdata:53 etc/initialdata:77
+msgid "Pseudogroup for internal use"
+msgstr "内部用的虚拟群组"
+
+#: html/Work/Preferences/Info:64
+msgid "Public Info"
+msgstr "公开信息"
+
+#: html/Work/Elements/104Header:88
+msgid "Public Service"
+msgstr "公共事务区"
+
+#: html/Edit/Users/Search.html:4
+msgid "Query"
+msgstr "查询"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:166 html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Elements/Quicksearch:28 html/Search/Elements/PickRestriction:45 html/SelfService/Create.html:32 html/Ticket/Create.html:37 html/Ticket/Elements/EditBasics:63 html/Ticket/Elements/ShowBasics:42 html/User/Elements/DelegateRights:79 html/Work/Elements/MyApprovals:10 html/Work/Elements/MyRequests:11 html/Work/Elements/MyTickets:11 html/Work/Elements/Quicksearch:14 html/Work/Search/PickRestriction:26 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "表单"
+
+#: html/Admin/Queues/CustomField.html:41 html/Admin/Queues/Scrip.html:49 html/Admin/Queues/Scrips.html:47 html/Admin/Queues/Templates.html:43 html/Admin/Queues/Workflows.html:44
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr "找不到表单 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr "找不到表单 '%1'\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Keyword Selections"
+msgstr "表单关键词选取"
+
+#: html/Admin/Elements/ModifyQueue:30 html/Admin/Queues/Modify.html:42 html/Edit/Queues/Basic/Top:12 html/Edit/Queues/Basic/index.html:36 html/Edit/Queues/Global:21 html/Edit/Queues/List:6 html/Edit/Users/Queue:10 html/Work/Delegates/List:6 html/Work/Elements/List:11 html/Work/Queues/List:5 html/Work/Tickets/Create.html:20 html/Work/Tickets/Elements/ShowBasics:6
+msgid "Queue Name"
+msgstr "表单名称"
+
+#: html/Edit/Queues/List:8 html/Work/Elements/List:25 html/Work/Queues/List:7 html/Work/Tickets/Create.html:33 html/Work/Tickets/Elements/ShowBasics:19
+msgid "Queue Owner"
+msgstr "业务承办人"
+
+#: html/Edit/Queues/Basic/Top:35
+msgid "Queue Priority"
+msgstr "优先等级"
+
+#: html/Edit/Global/GroupRight/Top:24 html/Edit/Global/UserRight/Top:43 html/Edit/Users/Queue:11 html/Edit/Users/index.html:124
+msgid "Queue Rights"
+msgstr "表单权限"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr "表单手续"
+
+#: html/Edit/Elements/Tab:36
+msgid "Queue Setup"
+msgstr "表单设定"
+
+#: lib/RT/Queue_Overlay.pm:264
+msgid "Queue already exists"
+msgstr "表单已存在"
+
+#: lib/RT/Queue_Overlay.pm:273 lib/RT/Queue_Overlay.pm:279
+msgid "Queue could not be created"
+msgstr "无法新增表单"
+
+#: html/Edit/Queues/autohandler:8 html/Ticket/Create.html:204 html/Work/Tickets/Create.html:176
+msgid "Queue could not be loaded."
+msgstr "无法加载表单"
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:283
+msgid "Queue created"
+msgstr "表单新增完毕"
+
+#: html/Admin/Elements/ModifyWorkflow:32
+msgid "Queue is not specified."
+msgstr "未指定表单。"
+
+#: html/SelfService/Display.html:70 lib/RT/CustomField_Overlay.pm:97
+msgid "Queue not found"
+msgstr "找不到表单"
+
+#: html/Admin/Elements/Tabs:37 html/Admin/index.html:34
+msgid "Queues"
+msgstr "表单"
+
+#: html/Work/Elements/Quicksearch:10
+msgid "Quick Search"
+msgstr "表单现况"
+
+#: html/Elements/Quicksearch:24
+msgid "Quick search"
+msgstr "表单一览"
+
+#: html/Elements/Login:44
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr "RT %1"
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr "%2:RT %1 版"
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr "RT %1 版,<a href=\"http://bestpractical.com\">Best Practical Solutions 公司</a>出品。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1。版权所有 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1。版权所有 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: html/Admin/index.html:24 html/Admin/index.html:25
+msgid "RT Administration"
+msgstr "RT 管理页面"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr "RT 认证错误。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr "RT 退信:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr "RT 设定错误"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr "RT 致命错误。讯息未被纪录。"
+
+#: html/Elements/Error:41 html/SelfService/Error.html:40
+msgid "RT Error"
+msgstr "RT 错误"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr "RT 收到从自己寄出的邮件 (%1)。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Recieved mail (%1) from itself."
+msgstr "RT 收到从自己寄出的邮件 (%1)。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Self Service / Closed Tickets"
+msgstr "RT 自助服务/已解决的申请单"
+
+#: html/index.html:24 html/index.html:27
+msgid "RT at a glance"
+msgstr "RT 一览"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr "RT 无法认证你"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr "RT 无法从外部数据库查询找到申请人信息"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr "RT 找不到表单:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr "RT 无法确认这个 PGP 签章。\\n"
+
+#: html/Edit/Elements/104Header:7 html/Edit/Elements/104Top:20 html/Elements/PageLayout:85 html/Work/Elements/104Header:7
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr "%1 专用流程系统"
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr "%1 专用 RT 系统:%2"
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr "RT 已执行您的命令"
+
+#: html/Elements/Login:94
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT 版权所有 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;。<br>本软体依 <a href=\"http://www.gnu.org/copyleft/gpl.html\">GNU 通用公共授权第二版</a> 散布。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr "RT 认为这可能是退信"
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr "RT 以未签章方式处理这封邮件。\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr "RT 的电子邮件命令模式须要 PGP 认证。您可能没有签章,或是您的签章无法辨识。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT::Queue-Role"
+msgstr "表单运行角色"
+
+#: NOT FOUND IN SOURCE
+msgid "RT::System-Role"
+msgstr "系统运行角色"
+
+#: NOT FOUND IN SOURCE
+msgid "RT::Ticket-Role"
+msgstr "申请单运行角色"
+
+#: html/Work/Tickets/Elements/ShowTransaction:11
+msgid "RT_System"
+msgstr "系统讯息"
+
+#: html/Admin/Users/Modify.html:57 html/Admin/Users/Prefs.html:51 html/User/Prefs.html:43 html/Work/Preferences/Info:18
+msgid "Real Name"
+msgstr "真实姓名"
+
+#: html/Admin/Elements/ModifyUser:47
+msgid "RealName"
+msgstr "真实姓名"
+
+#: html/Work/Approvals/Display.html:27 html/Work/Tickets/Update.html:85
+msgid "Really reject this ticket?"
+msgstr "您确定要驳回这张申请单吗?"
+
+#: html/Ticket/Create.html:184 html/Ticket/Elements/BulkLinks:50 html/Ticket/Elements/EditLinks:138 html/Ticket/Elements/EditLinks:93 html/Ticket/Elements/ShowLinks:70 html/Work/Search/BulkLinks:26
+msgid "Referred to by"
+msgstr "被参考"
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:183 html/Ticket/Elements/BulkLinks:46 html/Ticket/Elements/EditLinks:134 html/Ticket/Elements/EditLinks:79 html/Ticket/Elements/ShowLinks:60 html/Work/Search/BulkLinks:22
+msgid "Refers to"
+msgstr "参考"
+
+#: NOT FOUND IN SOURCE
+msgid "RefersTo"
+msgstr "参考"
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr "在结果范围内查询"
+
+#: html/Search/Elements/PickRestriction:26 html/Work/Search/PickRestriction:7
+msgid "Refine search"
+msgstr "调整查询条件"
+
+#: html/Work/Overview/index.html:12
+msgid "Refresh"
+msgstr "更新"
+
+#: html/Elements/Refresh:35
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "每 %1 分钟更新页面"
+
+#: html/Ticket/Create.html:173 html/Ticket/Elements/ShowSummary:61 html/Ticket/ModifyAll.html:56
+msgid "Relationships"
+msgstr "关系"
+
+#: html/Edit/Elements/ListButtons:13
+msgid "Remove"
+msgstr "移除"
+
+#: html/Search/Bulk.html:97 html/Work/Search/Bulk.html:77
+msgid "Remove AdminCc"
+msgstr "移除管理员副本"
+
+#: html/Search/Bulk.html:93 html/Work/Search/Bulk.html:71
+msgid "Remove Cc"
+msgstr "移除副本"
+
+#: html/Search/Bulk.html:89 html/Work/Search/Bulk.html:65
+msgid "Remove Requestor"
+msgstr "移除申请人"
+
+#: html/Ticket/Elements/ShowTransaction:160 html/Ticket/Elements/Tabs:121 html/Work/Tickets/Display.html:31 html/Work/Tickets/Elements/ShowTransaction:106
+msgid "Reply"
+msgstr "回复"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Reply to tickets"
+msgstr "对申请单进行回复"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "ReplyToTicket"
+msgstr "回复申请单"
+
+#: html/Edit/Users/Info:46
+msgid "Report to Duty"
+msgstr "上下班刷卡"
+
+#: html/Edit/Users/Info:34
+msgid "Reported on"
+msgstr "到职日期"
+
+#: etc/initialdata:62 html/Ticket/Update.html:39 html/Work/Elements/List:21 html/Work/Elements/MyApprovals:12 html/Work/Elements/SelectSearch:30 html/Work/Tickets/Elements/ShowBasics:54 lib/RT/ACE_Overlay.pm:86
+msgid "Requestor"
+msgstr "申请人"
+
+#: html/Edit/Global/Workflow/Owner.html:44
+msgid "Requestor Group's"
+msgstr "申请人所属群组之"
+
+#: html/Search/Elements/PickRestriction:37 html/Work/Search/PickRestriction:17
+msgid "Requestor email address"
+msgstr "申请人电子邮件信箱地址"
+
+#: html/Edit/Global/Workflow/Owner.html:28
+msgid "Requestor's"
+msgstr "申请人所属之第上"
+
+#: html/Work/Elements/List:23
+msgid "Requestor's Phone"
+msgstr "申请人电话"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr "申请人"
+
+#: NOT FOUND IN SOURCE
+msgid "RequestorAddresses"
+msgstr "申请人地址"
+
+#: html/SelfService/Create.html:40 html/Ticket/Create.html:55 html/Ticket/Elements/EditPeople:47 html/Ticket/Elements/ShowPeople:30
+msgid "Requestors"
+msgstr "申请人"
+
+#: html/Admin/Elements/ModifyQueue:60 html/Admin/Queues/Modify.html:74
+msgid "Requests should be due in"
+msgstr "申请单处理期限"
+
+#: html/Elements/Submit:61
+msgid "Reset"
+msgstr "重设"
+
+#: html/Admin/Users/Modify.html:158 html/User/Prefs.html:49 html/Work/Preferences/Info:29
+msgid "Residence"
+msgstr "住处"
+
+#: NOT FOUND IN SOURCE
+msgid "Resolution"
+msgstr "解决状态"
+
+#: html/Ticket/Elements/Tabs:131 html/Work/Tickets/Display.html:34
+msgid "Resolve"
+msgstr "解决"
+
+#: html/Ticket/Update.html:136 html/Work/Tickets/Update.html:120
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr "解决申请单 #%1 (%2)"
+
+#: etc/initialdata:331 html/Elements/SelectDateType:27 lib/RT/Ticket_Overlay.pm:1178
+msgid "Resolved"
+msgstr "已解决"
+
+#: html/Search/Bulk.html:132 html/Ticket/ModifyAll.html:72 html/Ticket/Update.html:71 html/Work/Search/Bulk.html:84 html/Work/Tickets/Update.html:38
+msgid "Response to requestors"
+msgstr "回复申请人"
+
+#: html/Edit/Users/Info:45
+msgid "Responsibility Type"
+msgstr "责任区分"
+
+#: html/Elements/ListActions:25
+msgid "Results"
+msgstr "结果"
+
+#: html/Search/Elements/PickRestriction:104 html/Work/Search/PickRestriction:84
+msgid "Results per page"
+msgstr "每页列出几笔结果"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:99 html/User/Prefs.html:71 html/Work/Preferences/Info:51
+msgid "Retype Password"
+msgstr "再次输入口令"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr "在 %4 (%5) 的范围内找不到 %2 %3 的 %1 权限\\n"
+
+#: lib/RT/ACE_Overlay.pm:612
+msgid "Right Delegated"
+msgstr "权限代理完毕"
+
+#: lib/RT/ACE_Overlay.pm:302
+msgid "Right Granted"
+msgstr "权限设定完毕"
+
+#: lib/RT/ACE_Overlay.pm:160
+msgid "Right Loaded"
+msgstr "权限加载完毕"
+
+#: lib/RT/ACE_Overlay.pm:677 lib/RT/ACE_Overlay.pm:692
+msgid "Right could not be revoked"
+msgstr "无法撤消权限"
+
+#: html/User/Delegation.html:63
+msgid "Right not found"
+msgstr "找不到权限"
+
+#: lib/RT/ACE_Overlay.pm:542 lib/RT/ACE_Overlay.pm:637
+msgid "Right not loaded."
+msgstr "权限并未加载。"
+
+#: lib/RT/ACE_Overlay.pm:688
+msgid "Right revoked"
+msgstr "权限撤消完毕"
+
+#: html/Admin/Elements/UserTabs:40
+msgid "Rights"
+msgstr "权限及代理人"
+
+#: lib/RT/Interface/Web.pm:794
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr "无法将权限赋予 %1"
+
+#: lib/RT/Interface/Web.pm:827
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr "无法撤消 %1 的权限"
+
+#: html/Edit/Groups/Member:55 html/Edit/Groups/Members/List:10
+msgid "Role Members"
+msgstr "角色成员"
+
+#: html/Edit/Groups/Member:37 html/Edit/Groups/Members/Add.html:13 html/Edit/Groups/Members/List:7 html/Edit/Groups/Roles/List:4 html/Edit/Groups/Roles/Top:7
+msgid "Role Name"
+msgstr "角色名称"
+
+#: html/Admin/Global/GroupRights.html:50 html/Admin/Queues/GroupRights.html:52 html/Edit/Global/Workflow/Owner.html:55 html/Edit/Global/Workflow/Owner.html:81 html/Edit/Groups/Member:24
+msgid "Roles"
+msgstr "角色"
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr "交由系统管理员签核"
+
+#: html/Edit/Global/Workflow/Action:27
+msgid "Run Approval"
+msgstr "签核执行"
+
+#: html/Edit/Global/Basic/Top:72
+msgid "SMTPDebug"
+msgstr "SMTP 侦错纪录"
+
+#: html/Edit/Global/Basic/Top:58
+msgid "SMTPFrom"
+msgstr "SMTP 寄件地址"
+
+#: html/Edit/Global/Basic/Top:56
+msgid "SMTPServer"
+msgstr "SMTP 服务器"
+
+#: NOT FOUND IN SOURCE
+msgid "Sat"
+msgstr "星期六"
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "星期六"
+
+#: html/Edit/Elements/104Buttons:72 html/Work/Preferences/index.html:35
+msgid "Save"
+msgstr "储存"
+
+#: html/Admin/Queues/People.html:104 html/Ticket/Modify.html:38 html/Ticket/ModifyAll.html:93 html/Ticket/ModifyLinks.html:38 html/Ticket/ModifyPeople.html:37
+msgid "Save Changes"
+msgstr "储存更改"
+
+#: NOT FOUND IN SOURCE
+msgid "Save changes"
+msgstr "储存更改"
+
+#: html/Admin/Global/Scrip.html:48 html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->id)
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr "手续 #%1"
+
+#: html/Edit/Global/Scrip/List:9 html/Edit/Global/Scrip/Top:41
+msgid "Scrip Action"
+msgstr "讯息通知动作"
+
+#: html/Edit/Global/Scrip/List:8 html/Edit/Global/Scrip/Top:15
+msgid "Scrip Condition"
+msgstr "讯息通知条件"
+
+#: lib/RT/Scrip_Overlay.pm:175
+msgid "Scrip Created"
+msgstr "手续新增完毕"
+
+#: html/Edit/Global/Scrip/List:7 html/Edit/Global/Scrip/Top:9
+msgid "Scrip Name"
+msgstr "讯息名称"
+
+#: html/Admin/Elements/EditScrips:83
+msgid "Scrip deleted"
+msgstr "手续删除完毕"
+
+#: html/Admin/Elements/QueueTabs:45 html/Admin/Elements/SystemTabs:32 html/Admin/Global/index.html:40
+msgid "Scrips"
+msgstr "手续"
+
+#: html/Edit/Global/autohandler:9 html/Edit/Queues/autohandler:20
+msgid "Scrips "
+msgstr "讯息通知"
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr "%1 的手续\\n"
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr "适用于所有表单的手续"
+
+#: html/Edit/Elements/104Buttons:75 html/Elements/SimpleSearch:26 html/Search/Elements/PickRestriction:125 html/Ticket/Elements/Tabs:158 html/Work/Elements/Tab:43 html/Work/Search/PickRestriction:102
+msgid "Search"
+msgstr "查询"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr "查询条件"
+
+#: html/Approvals/Elements/PendingMyApproval:38
+msgid "Search for approvals"
+msgstr "签核单查询"
+
+#: html/Edit/Global/Workflow/Owner.html:31
+msgid "Second-"
+msgstr "二"
+
+#: html/Edit/Users/Info:41
+msgid "Second-level Users"
+msgstr "二阶主管员工"
+
+#: bin/rt-crontool:187
+msgid "Security:"
+msgstr "安全性:"
+
+#: lib/RT/Queue_Overlay.pm:66
+msgid "SeeQueue"
+msgstr "查阅表单"
+
+#: html/Edit/Elements/ListButtons:10
+msgid "Select All"
+msgstr "全选"
+
+#: html/Admin/Groups/index.html:39
+msgid "Select a group"
+msgstr "选择群组"
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr "选择表单"
+
+#: html/Work/Queues/Select.html:8
+msgid "Select a queue to link to"
+msgstr "请选择欲连结表单"
+
+#: html/Admin/Users/index.html:24 html/Admin/Users/index.html:27
+msgid "Select a user"
+msgstr "选择使用者"
+
+#: html/Admin/Global/CustomField.html:37 html/Admin/Global/CustomFields.html:35
+msgid "Select custom field"
+msgstr "选择自订字段"
+
+#: html/Admin/Elements/GroupTabs:51 html/User/Elements/GroupTabs:49
+msgid "Select group"
+msgstr "选择群组"
+
+#: lib/RT/CustomField_Overlay.pm:421
+msgid "Select multiple values"
+msgstr "选择多重项目"
+
+#: lib/RT/CustomField_Overlay.pm:418
+msgid "Select one value"
+msgstr "选择单一项目"
+
+#: html/Admin/Elements/QueueTabs:66
+msgid "Select queue"
+msgstr "选择表单"
+
+#: html/Admin/Global/Scrip.html:36 html/Admin/Global/Scrips.html:35 html/Admin/Queues/Scrip.html:39 html/Admin/Queues/Scrips.html:51
+msgid "Select scrip"
+msgstr "选择手续"
+
+#: html/Admin/Global/Template.html:56 html/Admin/Global/Templates.html:35 html/Admin/Queues/Template.html:54 html/Admin/Queues/Templates.html:46
+msgid "Select template"
+msgstr "选择模板"
+
+#: html/Admin/Elements/UserTabs:48
+msgid "Select user"
+msgstr "选择使用者"
+
+#: html/Admin/Global/Workflow.html:57 html/Admin/Global/Workflows.html:36 html/Admin/Queues/Workflow.html:54 html/Admin/Queues/Workflows.html:47
+msgid "Select workflow"
+msgstr "选择流程"
+
+#: NOT FOUND IN SOURCE
+msgid "SelectExternal"
+msgstr "系统选项"
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectMultiple"
+msgstr "多重选项"
+
+#: lib/RT/CustomField_Overlay.pm:34
+msgid "SelectSingle"
+msgstr "单一选项"
+
+#: html/Edit/Elements/PickUsers:85 html/Edit/Users/Add.html:78
+msgid "Selected users:"
+msgstr "新增对象:"
+
+#: NOT FOUND IN SOURCE
+msgid "Self Service"
+msgstr "自助服务"
+
+#: etc/initialdata:131
+msgid "Send mail to all watchers"
+msgstr "寄信给所有视察员"
+
+#: etc/initialdata:127
+msgid "Send mail to all watchers as a \"comment\""
+msgstr "以评论方式寄信给所有视察员"
+
+#: etc/initialdata:122
+msgid "Send mail to requestors and Ccs"
+msgstr "寄信给申请人及副本收件人"
+
+#: etc/initialdata:117
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr "以评论方式寄信给申请人及副本收件人"
+
+#: etc/initialdata:96
+msgid "Sends a message to the requestors"
+msgstr "寄信给申请人"
+
+#: etc/initialdata:135 etc/initialdata:139
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr "寄信给特定的副本及密件副本收件人"
+
+#: etc/initialdata:112
+msgid "Sends mail to the administrative Ccs"
+msgstr "寄信给管理员副本收件人"
+
+#: etc/initialdata:108
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr "以评论寄信给管理员副本收件人"
+
+#: etc/initialdata:100 etc/initialdata:104
+msgid "Sends mail to the owner"
+msgstr "寄信给申请人"
+
+#: NOT FOUND IN SOURCE
+msgid "Sep"
+msgstr "九月"
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "09"
+
+#: NOT FOUND IN SOURCE
+msgid "September"
+msgstr "九月"
+
+#: html/Edit/Users/Info:39
+msgid "Shift Type"
+msgstr "班别属性"
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr "显示结果"
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show approved requests"
+msgstr "显示已批准的签核单"
+
+#: html/Ticket/Create.html:143 html/Ticket/Create.html:33
+msgid "Show basics"
+msgstr "显示基本信息"
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show denied requests"
+msgstr "显示已驳回的签核单"
+
+#: html/Ticket/Create.html:143 html/Ticket/Create.html:33
+msgid "Show details"
+msgstr "显示细节"
+
+#: html/Approvals/Elements/PendingMyApproval:42
+msgid "Show pending requests"
+msgstr "显示待处理的签核单"
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show requests awaiting other approvals"
+msgstr "显示尚待他人批准的签核单"
+
+#: lib/RT/Queue_Overlay.pm:80
+msgid "Show ticket private commentary"
+msgstr "显示申请单内的私人评论"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Show ticket summaries"
+msgstr "显示申请单摘要"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "ShowACL"
+msgstr "显示权限清单"
+
+#: lib/RT/Queue_Overlay.pm:77
+msgid "ShowScrips"
+msgstr "显示手续"
+
+#: lib/RT/Queue_Overlay.pm:74
+msgid "ShowTemplate"
+msgstr "显示模板"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowTicket"
+msgstr "显示申请单"
+
+#: lib/RT/Queue_Overlay.pm:80
+msgid "ShowTicketComments"
+msgstr "显示申请单的评论"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr "登记成为申请人或副本收件人"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr "登记成为管理员副本收件人"
+
+#: html/Admin/Elements/ModifyUser:38 html/Admin/Users/Modify.html:190 html/Admin/Users/Prefs.html:31 html/User/Prefs.html:111 html/Work/Preferences/Info:106
+msgid "Signature"
+msgstr "签名档"
+
+#: NOT FOUND IN SOURCE
+msgid "Signed in as %1"
+msgstr "使用者:%1"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:25
+msgid "Single"
+msgstr "单一"
+
+#: html/Elements/Header:50
+msgid "Skip Menu"
+msgstr "略过选单"
+
+#: html/Admin/Elements/AddCustomFieldValue:27
+msgid "Sort"
+msgstr "顺序"
+
+#: NOT FOUND IN SOURCE
+msgid "Sort key"
+msgstr "排序方式"
+
+#: html/Search/Elements/PickRestriction:108 html/Work/Search/PickRestriction:89
+msgid "Sort results by"
+msgstr "结果排序方式"
+
+#: NOT FOUND IN SOURCE
+msgid "SortOrder"
+msgstr "排序顺序"
+
+#: html/Work/Elements/List:8 html/Work/Elements/MyApprovals:11
+msgid "Stage"
+msgstr "关卡"
+
+#: html/Edit/Global/Workflow/Top:8
+msgid "Stage Action"
+msgstr "关卡运行动作"
+
+#: html/Edit/Global/Workflow/Top:5
+msgid "Stage Condition"
+msgstr "关卡运行条件"
+
+#: html/Work/Elements/Quicksearch:17
+msgid "Stalled"
+msgstr "延宕"
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr "首页"
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/EditDates:31 html/Ticket/Elements/ShowDates:34
+msgid "Started"
+msgstr "实际起始日"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr "无法解读起始日期 '%1"
+
+#: html/Elements/SelectDateType:30 html/Ticket/Create.html:165 html/Ticket/Elements/EditDates:26 html/Ticket/Elements/ShowDates:30
+msgid "Starts"
+msgstr "应起始日"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr "应起始日"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr "无法解读起始日期 '%1"
+
+#: html/Admin/Elements/ModifyUser:81 html/Admin/Users/Modify.html:137 html/User/Prefs.html:93 html/Work/Preferences/Info:82
+msgid "State"
+msgstr "州"
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Search/Elements/PickRestriction:73 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:30 html/Ticket/Create.html:41 html/Ticket/Elements/EditBasics:37 html/Ticket/Elements/ShowBasics:30 html/Ticket/Update.html:59 html/Work/Elements/List:15 html/Work/Elements/MyRequests:12 html/Work/Elements/MyTickets:12 html/Work/Search/PickRestriction:54 html/Work/Tickets/Update.html:22 lib/RT/Ticket_Overlay.pm:1172 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "现况"
+
+#: etc/initialdata:317
+msgid "Status Change"
+msgstr "现况改变时"
+
+#: lib/RT/Transaction_Overlay.pm:528
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr "现况从 %1 改为 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr "现况改变时"
+
+#: html/Ticket/Elements/Tabs:146
+msgid "Steal"
+msgstr "强制更换承办人"
+
+#: lib/RT/Queue_Overlay.pm:91
+msgid "Steal tickets"
+msgstr "强制承办申请单"
+
+#: lib/RT/Queue_Overlay.pm:91
+msgid "StealTicket"
+msgstr "强制承办申请单"
+
+#: lib/RT/Transaction_Overlay.pm:587
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "被 %1 强制更换 "
+
+#: html/Edit/Groups/Member:69
+msgid "Subgroup"
+msgstr "子群组"
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28 html/Search/Bulk.html:135 html/Search/Elements/PickRestriction:42 html/SelfService/Create.html:56 html/SelfService/Elements/MyRequests:27 html/SelfService/Update.html:31 html/Ticket/Create.html:83 html/Ticket/Elements/EditBasics:27 html/Ticket/ModifyAll.html:78 html/Ticket/Update.html:75 html/Work/Elements/MyApprovals:9 html/Work/Elements/MyRequests:10 html/Work/Elements/MyTickets:10 html/Work/Search/Bulk.html:87 html/Work/Search/PickRestriction:22 html/Work/Tickets/Create.html:122 lib/RT/Ticket_Overlay.pm:1168 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "主题"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:609
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr "标题已改为 %1"
+
+#: html/Elements/Submit:58 html/Work/Search/Bulk.html:103
+msgid "Submit"
+msgstr "送出"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr "送出流程"
+
+#: lib/RT/Group_Overlay.pm:748
+msgid "Succeeded"
+msgstr "设定成功"
+
+#: NOT FOUND IN SOURCE
+msgid "Sun"
+msgstr "星期日"
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "星期日"
+
+#: html/Edit/Users/System:17 lib/RT/System.pm:53
+msgid "SuperUser"
+msgstr "系统管理员"
+
+#: html/User/Elements/DelegateRights:76
+msgid "System"
+msgstr "系统"
+
+#: html/Edit/Global/Scrip/Top:18 html/Edit/Global/Scrip/Top:44
+msgid "System Defined"
+msgstr "系统定义"
+
+#: html/Admin/Elements/SelectRights:80 lib/RT/ACE_Overlay.pm:566 lib/RT/Interface/Web.pm:793 lib/RT/Interface/Web.pm:826
+msgid "System Error"
+msgstr "系统错误"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. Right not granted."
+msgstr "系统错误。设定权限失败。"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. right not granted"
+msgstr "系统错误。设定权限失败。"
+
+#: html/Edit/Users/index.html:122
+msgid "System Rights"
+msgstr "系统权限"
+
+#: lib/RT/ACE_Overlay.pm:615
+msgid "System error. Right not delegated."
+msgstr "系统错误。权限代理失败。"
+
+#: lib/RT/ACE_Overlay.pm:145 lib/RT/ACE_Overlay.pm:222 lib/RT/ACE_Overlay.pm:305 lib/RT/ACE_Overlay.pm:897
+msgid "System error. Right not granted."
+msgstr "系统错误。设定权限失败。"
+
+#: NOT FOUND IN SOURCE
+msgid "System error. Unable to grant rights."
+msgstr "系统错误。无法设定权限。"
+
+#: html/Admin/Global/GroupRights.html:34 html/Admin/Groups/GroupRights.html:36 html/Admin/Queues/GroupRights.html:35
+msgid "System groups"
+msgstr "系统群组"
+
+#: NOT FOUND IN SOURCE
+msgid "SystemInternal"
+msgstr "系统内部用"
+
+#: etc/initialdata:59 etc/initialdata:65 etc/initialdata:71
+msgid "SystemRolegroup for internal use"
+msgstr "内部使用的系统角色群组"
+
+#: lib/RT/CurrentUser.pm:319
+msgid "TEST_STRING"
+msgstr "TEST_STRING"
+
+#: html/Ticket/Elements/Tabs:142
+msgid "Take"
+msgstr "受理"
+
+#: lib/RT/Queue_Overlay.pm:89
+msgid "Take tickets"
+msgstr "自行承办申请单"
+
+#: lib/RT/Queue_Overlay.pm:89
+msgid "TakeTicket"
+msgstr "自行承办申请单"
+
+#: lib/RT/Transaction_Overlay.pm:573
+msgid "Taken"
+msgstr "已受理"
+
+#: html/Admin/Elements/EditScrip:80
+msgid "Template"
+msgstr "模板"
+
+#: html/Admin/Global/Template.html:90 html/Admin/Queues/Template.html:89
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr "模板 #%1"
+
+#: html/Edit/Global/Template/List:9 html/Edit/Global/Template/Top:17
+msgid "Template Content"
+msgstr "通知模板内容"
+
+#: html/Edit/Global/Template/List:8 html/Edit/Global/Template/Top:13
+msgid "Template Description"
+msgstr "通知模板描述"
+
+#: html/Edit/Global/Template/List:7 html/Edit/Global/Template/Top:9
+msgid "Template Name"
+msgstr "通知模板名称"
+
+#: html/Admin/Elements/EditTemplates:88
+msgid "Template deleted"
+msgstr "模板已删除"
+
+#: lib/RT/Scrip_Overlay.pm:152
+msgid "Template not found"
+msgstr "找不到模板"
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr "找不到模板\\n"
+
+#: lib/RT/Template_Overlay.pm:352
+msgid "Template parsed"
+msgstr "模板剖析完毕"
+
+#: html/Admin/Elements/QueueTabs:48 html/Admin/Elements/SystemTabs:35 html/Admin/Global/index.html:44
+msgid "Templates"
+msgstr "模板"
+
+#: html/Edit/Global/autohandler:8 html/Edit/Queues/autohandler:19
+msgid "Templates "
+msgstr "通知模板"
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr "找不到 %1 的模板\\n"
+
+#: lib/RT/Interface/Web.pm:894
+msgid "That is already the current value"
+msgstr "已经是目前字段的值"
+
+#: lib/RT/CustomField_Overlay.pm:242
+msgid "That is not a value for this custom field"
+msgstr "这不是该自订字段的值"
+
+#: lib/RT/Ticket_Overlay.pm:1908
+msgid "That is the same value"
+msgstr "同样的值"
+
+#: lib/RT/ACE_Overlay.pm:287 lib/RT/ACE_Overlay.pm:596
+msgid "That principal already has that right"
+msgstr "这项单位已经拥有该权限"
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr "这项单位已经是这个表单的 %1"
+
+#: lib/RT/Ticket_Overlay.pm:1442
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr "这项单位已经是这份申请单的 %1"
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr "这项单位不是这个表单的 %1"
+
+#: lib/RT/Ticket_Overlay.pm:1559
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr "这项单位不是这份申请单的 %1"
+
+#: lib/RT/Ticket_Overlay.pm:1904
+msgid "That queue does not exist"
+msgstr "此表单不存在"
+
+#: lib/RT/Ticket_Overlay.pm:3246
+msgid "That ticket has unresolved dependencies"
+msgstr "这份申请单有尚未解决的附属申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "That user already has that right"
+msgstr "使用者已具有该项权限"
+
+#: lib/RT/Ticket_Overlay.pm:3056
+msgid "That user already owns that ticket"
+msgstr "该使用者已经承办这份申请单"
+
+#: lib/RT/Ticket_Overlay.pm:3028
+msgid "That user does not exist"
+msgstr "使用者不存在"
+
+#: lib/RT/User_Overlay.pm:374
+msgid "That user is already privileged"
+msgstr "这名使用者已经是内部成员"
+
+#: lib/RT/User_Overlay.pm:395
+msgid "That user is already unprivileged"
+msgstr "这名使用者属于非内部成员群组"
+
+#: lib/RT/User_Overlay.pm:387
+msgid "That user is now privileged"
+msgstr "使用者加入内部成员群组完毕"
+
+#: lib/RT/User_Overlay.pm:408
+msgid "That user is now unprivileged"
+msgstr "这名使用者已加入非内部成员群组"
+
+#: NOT FOUND IN SOURCE
+msgid "That user is now unprivilegedileged"
+msgstr "这名使用者已加入非内部成员群组"
+
+#: lib/RT/Ticket_Overlay.pm:3049
+msgid "That user may not own tickets in that queue"
+msgstr "使用者可能没有承办表单里的申请单"
+
+#: lib/RT/Link_Overlay.pm:205
+msgid "That's not a numerical id"
+msgstr "这不是一个数字编号"
+
+#: html/SelfService/Display.html:31 html/Ticket/Create.html:149 html/Ticket/Elements/ShowSummary:27
+msgid "The Basics"
+msgstr "基本信息"
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The CC of a ticket"
+msgstr "申请单的副本收件人"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The administrative CC of a ticket"
+msgstr "申请单的管理员副本收件人"
+
+#: lib/RT/Ticket_Overlay.pm:2235
+msgid "The comment has been recorded"
+msgstr "评论已被纪录"
+
+#: bin/rt-crontool:197
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr "下列命令会找到 'general' 表单内所有运作中的申请单,并将其中 4 小时内未处理的申请单优先程度设为 99:"
+
+#: bin/rt-commit-handler:755 bin/rt-commit-handler:765
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr "以下命令未被执行:\\n\\n"
+
+#: lib/RT/Interface/Web.pm:897
+msgid "The new value has been set."
+msgstr "新的字段值设定完成。"
+
+#: lib/RT/ACE_Overlay.pm:85
+msgid "The owner of a ticket"
+msgstr "申请单的承办人"
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The requestor of a ticket"
+msgstr "申请单的申请人"
+
+#: html/Admin/Elements/EditUserComments:25
+msgid "These comments aren't generally visible to the user"
+msgstr "该使用者不会看见这些评论"
+
+#: html/Edit/Global/Workflow/Owner.html:32
+msgid "Third-"
+msgstr "三"
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr "申请单 %1 %2 (%3)\\n"
+
+#: bin/rt-crontool:188
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr "此工具程序会让使用者经由 RT 执行任意命令。"
+
+#: lib/RT/Transaction_Overlay.pm:251
+msgid "This transaction appears to have no content"
+msgstr "此项更动报告没有内容"
+
+#: html/Ticket/Elements/ShowRequestor:46
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr "使用者送出的前 %1 份优先处理申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr "使用者送出的前 25 份优先处理申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "Thu"
+msgstr "星期四"
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "星期四"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:163
+msgid "Ticket"
+msgstr "申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr "申请单 # %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1 Jumbo update: %2"
+msgstr "更新申请单 # %1 的全部信息:%2"
+
+#: html/Ticket/ModifyAll.html:24 html/Ticket/ModifyAll.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "更新申请单 #%1 的全部信息:%2"
+
+#: html/Approvals/Elements/ShowDependency:45
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr "申请单 #%1: %2"
+
+#: lib/RT/Ticket_Overlay.pm:595 lib/RT/Ticket_Overlay.pm:616
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr "申请单 #%1 成功新增于 '%2' 表单"
+
+#: bin/rt-commit-handler:759
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr "加载申请单 %1\\n"
+
+#: html/Search/Bulk.html:212 html/Work/Search/Bulk.html:169
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr "申请单 %1:%2"
+
+#: html/Edit/Queues/Basic/Top:28 html/Edit/Queues/List:16 html/Work/Queues/List:9
+msgid "Ticket Due"
+msgstr "表单处理期限"
+
+#: html/Ticket/History.html:24 html/Ticket/History.html:27
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr "申请单处理纪录 # %1 %2"
+
+#: html/Work/Elements/List:6
+msgid "Ticket ID"
+msgstr "单号"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket Id"
+msgstr "申请单编号"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket Processing Due"
+msgstr "表单运行期限"
+
+#: etc/initialdata:332
+msgid "Ticket Resolved"
+msgstr "申请单已解决"
+
+#: html/Edit/Queues/Basic/Top:18 html/Edit/Queues/Category/List:6 html/Edit/Queues/Category/Top:7 html/Edit/Queues/List:7 html/Edit/Queues/index.html:31 html/Work/Delegates/List:7 html/Work/Delegates/index.html:11 html/Work/Elements/List:12 html/Work/Elements/SelectSearch:9 html/Work/Queues/List:6 html/Work/Queues/Select.html:12 html/Work/Queues/index.html:11 html/Work/Tickets/Create.html:42 html/Work/Tickets/Elements/ShowBasics:33
+msgid "Ticket Type"
+msgstr "表单种类"
+
+#: html/Search/Elements/PickRestriction:62 html/Work/Search/PickRestriction:43
+msgid "Ticket attachment"
+msgstr "申请单附件"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr "申请单内容"
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr "申请单内容类别"
+
+#: lib/RT/Ticket_Overlay.pm:485 lib/RT/Ticket_Overlay.pm:494 lib/RT/Ticket_Overlay.pm:504 lib/RT/Ticket_Overlay.pm:605
+msgid "Ticket could not be created due to an internal error"
+msgstr "内部错误,无法新增申请单"
+
+#: lib/RT/Transaction_Overlay.pm:520
+msgid "Ticket created"
+msgstr "申请单新增完毕"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr "申请单新增失败"
+
+#: lib/RT/Transaction_Overlay.pm:525
+msgid "Ticket deleted"
+msgstr "申请单删除完毕"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket id not found"
+msgstr "找不到申请单编号"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket killed"
+msgstr "申请单删除完毕"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket not found"
+msgstr "找不到申请单"
+
+#: etc/initialdata:318
+msgid "Ticket status changed"
+msgstr "申请单现况已改变"
+
+#: html/Ticket/Update.html:38
+msgid "Ticket watchers"
+msgstr "申请单视察员"
+
+#: html/Elements/Tabs:46
+msgid "Tickets"
+msgstr "申请单"
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr "申请单 %1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr "申请单 %1 (%2)"
+
+#: html/Elements/ViewUser:25
+#. ($name)
+msgid "Tickets from %1"
+msgstr "%1 的申请单"
+
+#: html/Approvals/Elements/ShowDependency:26
+msgid "Tickets which depend on this approval:"
+msgstr "批准之后,可接续处理:"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:47
+msgid "Time Left"
+msgstr "剩馀时间"
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:42
+msgid "Time Worked"
+msgstr "处理时间"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "剩馀时间"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "显示时间"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "已处理时间"
+
+#: NOT FOUND IN SOURCE
+msgid "TimeLeft"
+msgstr "剩馀时间"
+
+#: lib/RT/Ticket_Overlay.pm:1173
+msgid "TimeWorked"
+msgstr "已处理时间"
+
+#: bin/rt-commit-handler:401
+msgid "To generate a diff of this commit:"
+msgstr "产生这次更动的差异档:"
+
+#: bin/rt-commit-handler:390
+msgid "To generate a diff of this commit:\\n"
+msgstr "产生这次更动的差异档:\\n"
+
+#: lib/RT/Ticket_Overlay.pm:1176
+msgid "Told"
+msgstr "告知日期"
+
+#: html/Edit/Elements/Page:46
+msgid "Total"
+msgstr "页"
+
+#: etc/initialdata:239
+msgid "Transaction"
+msgstr "更动"
+
+#: lib/RT/Transaction_Overlay.pm:640
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr "清除更动报告 %1"
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr "更动报告已新增"
+
+#: lib/RT/Transaction_Overlay.pm:88
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr "未指定申请单编号,无法新增更动"
+
+#: lib/RT/Transaction_Overlay.pm:699
+msgid "Transactions are immutable"
+msgstr "不可更改更动报告"
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr "试图删除某项权限:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Tue"
+msgstr "星期二"
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "星期二"
+
+#: html/Admin/Elements/EditCustomField:43 html/Admin/Elements/ModifyTemplateAsWorkflow:135 html/Ticket/Elements/AddWatchers:32 html/Ticket/Elements/AddWatchers:43 html/Ticket/Elements/AddWatchers:53 lib/RT/Ticket_Overlay.pm:1174 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "类别"
+
+#: lib/RT/ScripCondition_Overlay.pm:103
+msgid "Unimplemented"
+msgstr "尚无实作"
+
+#: html/Admin/Users/Modify.html:67
+msgid "Unix login"
+msgstr "外部系统登入帐号"
+
+#: html/Admin/Elements/ModifyUser:61
+msgid "UnixUsername"
+msgstr "外部系统登入帐号"
+
+#: lib/RT/Attachment_Overlay.pm:273 lib/RT/Attachment_Overlay.pm:303
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr "不可解的内容文字编码方式 %1"
+
+#: html/Elements/SelectResultsPerPage:36
+msgid "Unlimited"
+msgstr "全数显示"
+
+#: etc/initialdata:50
+msgid "Unprivileged"
+msgstr "非内部成员"
+
+#: lib/RT/Transaction_Overlay.pm:569
+msgid "Untaken"
+msgstr "未被受理"
+
+#: html/Edit/Elements/Page:13 html/Edit/Elements/Page:15
+msgid "Up"
+msgstr "上一页"
+
+#: html/Elements/MyTickets:63 html/Search/Bulk.html:32 html/Work/Elements/MyTickets:72 html/Work/Search/Bulk.html:10 html/Work/Tickets/Elements/EditCustomFieldEntries:82
+msgid "Update"
+msgstr "处理"
+
+#: html/Admin/Users/Prefs.html:61
+msgid "Update ID"
+msgstr "更新编号"
+
+#: html/Search/Bulk.html:129 html/Ticket/ModifyAll.html:65 html/Ticket/Update.html:65 html/Work/Search/Bulk.html:81 html/Work/Tickets/Update.html:32
+msgid "Update Type"
+msgstr "更新类别"
+
+#: html/Search/Listing.html:60 html/Work/Search/index.html:32
+msgid "Update all these tickets at once"
+msgstr "整批更新申请单"
+
+#: html/Admin/Users/Prefs.html:48
+msgid "Update email"
+msgstr "更新电子邮件信箱"
+
+#: html/Admin/Users/Prefs.html:54
+msgid "Update name"
+msgstr "更新帐号"
+
+#: lib/RT/Interface/Web.pm:409
+msgid "Update not recorded."
+msgstr "更新未被记录"
+
+#: html/Search/Bulk.html:80 html/Work/Search/Bulk.html:52
+msgid "Update selected tickets"
+msgstr "更新选择的申请单"
+
+#: html/Admin/Users/Prefs.html:35
+msgid "Update signature"
+msgstr "更新签章"
+
+#: html/Ticket/ModifyAll.html:62
+msgid "Update ticket"
+msgstr "更新申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "Update ticket # %1"
+msgstr "更新申请单 # %1"
+
+#: html/SelfService/Update.html:24 html/SelfService/Update.html:46
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr "更新申请单 #%1"
+
+#: html/Ticket/Update.html:138 html/Work/Tickets/Update.html:122
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr "更新申请单 #%1 (%2)"
+
+#: lib/RT/Interface/Web.pm:407
+msgid "Update type was neither correspondence nor comment."
+msgstr "更新的内容并非申请单回复也不是评论"
+
+#: html/Elements/SelectDateType:32 html/Ticket/Elements/ShowDates:50 lib/RT/Ticket_Overlay.pm:1177
+msgid "Updated"
+msgstr "前次更新"
+
+#: html/Work/Preferences/index.html:15
+msgid "User"
+msgstr "使用者"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr "使用者 %1 %2:%3\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr "使用者 %1 口令:%2\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr "找不到使用者 '%1'"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr "找不到使用者 '%1'\\n"
+
+#: etc/initialdata:142 etc/initialdata:209
+msgid "User Defined"
+msgstr "使用者自订"
+
+#: html/Admin/Users/Prefs.html:58 html/Edit/Users/List:13 html/Edit/Users/Top:42
+msgid "User ID"
+msgstr "使用者 ID"
+
+#: html/Elements/SelectUsers:25
+msgid "User Id"
+msgstr "使用者 ID"
+
+#: html/Edit/Elements/PickUsers:12 html/Edit/Global/UserRight/List:7 html/Edit/Global/UserRight/Top:9 html/Edit/Users/Add.html:13 html/Edit/Users/List:5 html/Edit/Users/Search.html:23 html/Edit/Users/Top:8 html/Work/Delegates/Info:60 html/Work/Tickets/Cc:10
+msgid "User Number"
+msgstr "员工编号"
+
+#: html/Admin/Elements/GroupTabs:46 html/Admin/Elements/QueueTabs:59 html/Admin/Elements/SystemTabs:46 html/Admin/Global/index.html:58 html/Edit/Global/autohandler:11 html/Edit/Queues/autohandler:22
+msgid "User Rights"
+msgstr "使用者权限"
+
+#: html/Edit/Elements/Tab:32
+msgid "User Setup"
+msgstr "使用者设定"
+
+#: html/Edit/Users/Info:38
+msgid "User Shift"
+msgstr "员工班别"
+
+#: html/Admin/Users/Modify.html:225
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr "无法新增使用者:%1"
+
+#: lib/RT/User_Overlay.pm:321
+msgid "User created"
+msgstr "使用者新增完毕"
+
+#: html/Admin/Global/GroupRights.html:66 html/Admin/Groups/GroupRights.html:53 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr "使用者定义的群组"
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr "已通知使用者"
+
+#: html/Admin/Users/Prefs.html:24 html/Admin/Users/Prefs.html:28
+msgid "User view"
+msgstr "使用者私人数据"
+
+#: NOT FOUND IN SOURCE
+msgid "UserDefined"
+msgstr "使用者自定"
+
+#: html/Admin/Users/Modify.html:47 html/Elements/Login:51 html/Ticket/Elements/AddWatchers:34
+msgid "Username"
+msgstr "帐号"
+
+#: html/Admin/Elements/SelectNewGroupMembers:25 html/Admin/Elements/Tabs:31 html/Admin/Groups/Members.html:54 html/Admin/Queues/People.html:67 html/Admin/index.html:28 html/User/Groups/Members.html:57 html/Work/Tickets/Elements/ShowTransaction:8
+msgid "Users"
+msgstr "使用者"
+
+#: html/Admin/Users/index.html:64
+msgid "Users matching search criteria"
+msgstr "符合查询条件的使用者"
+
+#: html/Search/Elements/PickRestriction:50 html/Work/Search/PickRestriction:31
+msgid "ValueOfQueue"
+msgstr "选择表单"
+
+#: html/Admin/Elements/EditCustomField:56
+msgid "Values"
+msgstr "字段值"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Watch"
+msgstr "视察"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "WatchAsAdminCc"
+msgstr "以管理员副本收件人身份视察"
+
+#: NOT FOUND IN SOURCE
+msgid "Watcher loaded"
+msgstr "成功加载视察员信息"
+
+#: html/Admin/Elements/QueueTabs:41
+msgid "Watchers"
+msgstr "视察员"
+
+#: html/Admin/Elements/ModifyUser:55
+msgid "WebEncoding"
+msgstr "网页文字编码方式"
+
+#: NOT FOUND IN SOURCE
+msgid "Wed"
+msgstr "星期三"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "星期三"
+
+#: etc/initialdata:533 etc/upgrade/2.1.71:161 html/Edit/Elements/CreateApprovalsQueue:135
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr "当申请单通过所有签核后,将此讯息回复到原申请单"
+
+#: etc/initialdata:497 etc/upgrade/2.1.71:135 html/Edit/Elements/CreateApprovalsQueue:107
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr "当申请单通过某项签核后,将此讯息回复到原申请单"
+
+#: etc/initialdata:156
+msgid "When a ticket is created"
+msgstr "新增申请单时"
+
+#: etc/initialdata:428 etc/upgrade/2.1.71:79 html/Edit/Elements/CreateApprovalsQueue:51
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr "签核单新增之后,通知应受理的承办人及管理员副本收件人"
+
+#: etc/initialdata:161
+msgid "When anything happens"
+msgstr "当任何事情发生时"
+
+#: etc/initialdata:202
+msgid "Whenever a ticket is resolved"
+msgstr "当申请单解决时"
+
+#: etc/initialdata:188
+msgid "Whenever a ticket's owner changes"
+msgstr "当申请单更换承办人时"
+
+#: etc/initialdata:196
+msgid "Whenever a ticket's queue changes"
+msgstr "当申请单更换表单时"
+
+#: etc/initialdata:180
+msgid "Whenever a ticket's status changes"
+msgstr "当申请单更新现况时"
+
+#: etc/initialdata:210
+msgid "Whenever a user-defined condition occurs"
+msgstr "当使用者自订的情况发生时"
+
+#: etc/initialdata:174
+msgid "Whenever comments come in"
+msgstr "当评论送达时"
+
+#: etc/initialdata:167
+msgid "Whenever correspondence comes in"
+msgstr "当回复送达时"
+
+#: html/Admin/Users/Modify.html:163 html/User/Prefs.html:51 html/Work/Preferences/Info:31
+msgid "Work"
+msgstr "公司"
+
+#: html/Admin/Elements/ModifyUser:69
+msgid "WorkPhone"
+msgstr "公司电话"
+
+#: html/Ticket/Elements/ShowBasics:34 html/Ticket/Update.html:64
+msgid "Worked"
+msgstr "处理时间"
+
+#: html/Admin/Global/Workflow.html:91 html/Admin/Queues/Workflow.html:89
+#. ($WorkflowObj->Id())
+msgid "Workflow #%1"
+msgstr "流程 #%1"
+
+#: html/Edit/Global/Workflow/List:15
+msgid "Workflow Begin"
+msgstr "流程开始"
+
+#: html/Edit/Global/Workflow/List:20
+msgid "Workflow End"
+msgstr "流程结束"
+
+#: html/Admin/Elements/EditWorkflows:90
+msgid "Workflow deleted"
+msgstr "流程已删除"
+
+#: html/Edit/Global/autohandler:10 html/Edit/Queues/autohandler:21
+msgid "Workflows"
+msgstr "流程"
+
+#: html/Edit/Global/Basic/Top:25
+msgid "Yes"
+msgstr "是"
+
+#: lib/RT/Ticket_Overlay.pm:3159
+msgid "You already own this ticket"
+msgstr "您已是这份申请单的承办人"
+
+#: html/autohandler:122
+msgid "You are not an authorized user"
+msgstr "您不是被授权的使用者"
+
+#: lib/RT/Ticket_Overlay.pm:3041
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "祇能重新指派您所承办或是没有承办人的申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr "您没有看那份申请单的权限。\\n"
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "您会在表单 %2 找到 %1 的申请单"
+
+#: html/NoAuth/Logout.html:30
+msgid "You have been logged out of RT."
+msgstr "您已注销 RT。"
+
+#: html/SelfService/Display.html:77
+msgid "You have no permission to create tickets in that queue."
+msgstr "您没有在该表单新增申请单的权限。"
+
+#: lib/RT/Ticket_Overlay.pm:1917
+msgid "You may not create requests in that queue."
+msgstr "您不能在该表单中提出申请。"
+
+#: html/Edit/Global/Basic/Top:38
+msgid "You need to restart the Request Tracker service for saved changes to take effect."
+msgstr "您必须重新激活 Request Tracker 服务,储存的更动才会生效。"
+
+#: html/NoAuth/Logout.html:34
+msgid "You're welcome to login again"
+msgstr "欢迎下次再来"
+
+#: NOT FOUND IN SOURCE
+msgid "Your %1 requests"
+msgstr "您提出的 %1 申请单"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr "RT 管理员可能设错了由 RT 寄出的邮件收件人标头档"
+
+#: etc/initialdata:514 etc/upgrade/2.1.71:146 html/Edit/Elements/CreateApprovalsQueue:119
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr "申请单已由 %1 批准。可能还有其它待签核的步骤。"
+
+#: etc/initialdata:552 etc/upgrade/2.1.71:180 html/Edit/Elements/CreateApprovalsQueue:154
+msgid "Your request has been approved."
+msgstr "您的申请单已完成签核程序。"
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr "您的申请单已被驳回"
+
+#: etc/initialdata:455
+msgid "Your request was rejected by %1."
+msgstr "您的申请单已被 %1 驳回。"
+
+#: etc/upgrade/2.1.71:101 html/Edit/Elements/CreateApprovalsQueue:73
+msgid "Your request was rejected."
+msgstr "您的申请单已被驳回。"
+
+#: html/autohandler:144
+msgid "Your username or password is incorrect"
+msgstr "您的帐号或口令有误"
+
+#: html/Admin/Elements/ModifyUser:83 html/Admin/Users/Modify.html:143 html/User/Prefs.html:95 html/Work/Preferences/Info:84
+msgid "Zip"
+msgstr "邮政编码"
+
+#: NOT FOUND IN SOURCE
+msgid "[no subject]"
+msgstr "[没有标题]"
+
+#: NOT FOUND IN SOURCE
+msgid "ago"
+msgstr "过期"
+
+#: NOT FOUND IN SOURCE
+msgid "alert"
+msgstr "急讯"
+
+#: html/User/Elements/DelegateRights:58
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "权限同 %1"
+
+#: html/SelfService/Closed.html:27
+msgid "closed"
+msgstr "已解决"
+
+#: html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:33
+msgid "contains"
+msgstr "包含"
+
+#: html/Elements/SelectAttachmentField:25
+msgid "content"
+msgstr "内容"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content-type"
+msgstr "类型"
+
+#: lib/RT/Ticket_Overlay.pm:2304
+msgid "correspondence (probably) not sent"
+msgstr "申请单回复(可能)未送出"
+
+#: lib/RT/Ticket_Overlay.pm:2314
+msgid "correspondence sent"
+msgstr "申请单回复已送出"
+
+#: NOT FOUND IN SOURCE
+msgid "critical"
+msgstr "严重"
+
+#: html/Admin/Elements/ModifyQueue:62 html/Admin/Queues/Modify.html:76 html/Edit/Queues/Basic/Top:31 html/Edit/Queues/List:18 html/Work/Queues/List:11 lib/RT/Date.pm:319
+msgid "days"
+msgstr "天"
+
+#: NOT FOUND IN SOURCE
+msgid "dead"
+msgstr "拒绝处理"
+
+#: NOT FOUND IN SOURCE
+msgid "debug"
+msgstr "侦错"
+
+#: html/Search/Listing.html:74
+msgid "delete"
+msgstr "删除"
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "deleted"
+msgstr "已删除"
+
+#: html/Search/Elements/PickRestriction:67 html/Work/Search/PickRestriction:47
+msgid "does not match"
+msgstr "不符合"
+
+#: html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:34
+msgid "doesn't contain"
+msgstr "不包含"
+
+#: NOT FOUND IN SOURCE
+msgid "emergency"
+msgstr "危难"
+
+#: html/Elements/SelectEqualityOperator:37
+msgid "equal to"
+msgstr "等于"
+
+#: NOT FOUND IN SOURCE
+msgid "error"
+msgstr "错误"
+
+#: NOT FOUND IN SOURCE
+msgid "false"
+msgstr "假"
+
+#: html/Elements/SelectAttachmentField:27
+msgid "filename"
+msgstr "档名"
+
+#: html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectEqualityOperator:37
+msgid "greater than"
+msgstr "大于"
+
+#: lib/RT/Group_Overlay.pm:193
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "群组 '%1'"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "小时"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr "编号"
+
+#: NOT FOUND IN SOURCE
+msgid "info"
+msgstr "信息"
+
+#: html/Elements/SelectBoolean:31 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:35 html/Search/Elements/PickRestriction:46 html/Search/Elements/PickRestriction:75 html/Search/Elements/PickRestriction:87 html/Work/Search/PickRestriction:27 html/Work/Search/PickRestriction:56 html/Work/Search/PickRestriction:69
+msgid "is"
+msgstr "是"
+
+#: html/Elements/SelectBoolean:35 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88 html/Work/Search/PickRestriction:28 html/Work/Search/PickRestriction:57 html/Work/Search/PickRestriction:70
+msgid "isn't"
+msgstr "不是"
+
+#: html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectEqualityOperator:37
+msgid "less than"
+msgstr "小于"
+
+#: html/Edit/Global/Workflow/Owner.html:35
+msgid "level Admins"
+msgstr "层主管"
+
+#: html/Search/Elements/PickRestriction:66 html/Work/Search/PickRestriction:46
+msgid "matches"
+msgstr "符合"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "分"
+
+#: html/Ticket/Update.html:64
+msgid "minutes"
+msgstr "分钟"
+
+#: bin/rt-commit-handler:764
+msgid "modifications\\n\\n"
+msgstr "更改\\n\\n"
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "月"
+
+#: lib/RT/Queue_Overlay.pm:57
+msgid "new"
+msgstr "新建立"
+
+#: html/Admin/Elements/EditScrips:42
+msgid "no value"
+msgstr "没有值"
+
+#: html/Admin/Elements/EditQueueWatchers:26 html/Edit/Groups/Member:40 html/Edit/Groups/Members/Add.html:17 html/Edit/Groups/Members/List:8 html/Edit/Queues/Basic/Top:50 html/Edit/Queues/List:18 html/Ticket/Elements/EditWatchers:27 html/Work/Delegates/Info:37 html/Work/Delegates/Info:48 html/Work/Overview/Info:31 html/Work/Queues/List:11 html/Work/Tickets/Elements/ShowBasics:27
+msgid "none"
+msgstr "无"
+
+#: html/Elements/SelectEqualityOperator:37
+msgid "not equal to"
+msgstr "不等于"
+
+#: NOT FOUND IN SOURCE
+msgid "notice"
+msgstr "提示"
+
+#: NOT FOUND IN SOURCE
+msgid "notlike"
+msgstr "不符合"
+
+#: html/Edit/Elements/PickUsers:17 html/Edit/Users/Add.html:18 html/Edit/Users/Search.html:28 html/Work/Tickets/Cc:15
+msgid "number"
+msgstr "号"
+
+#: html/SelfService/Elements/MyRequests:60 lib/RT/Queue_Overlay.pm:58
+msgid "open"
+msgstr "开启"
+
+#: NOT FOUND IN SOURCE
+msgid "opened"
+msgstr "已开启"
+
+#: lib/RT/Group_Overlay.pm:198
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr "使用者「%2」的「%1」代理人群组"
+
+#: lib/RT/Group_Overlay.pm:206
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr "表单 %1 %2"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "rejected"
+msgstr "已驳回"
+
+#: html/Work/Elements/SelectSearch:21 lib/RT/Queue_Overlay.pm:60
+msgid "resolved"
+msgstr "已处理"
+
+#: html/Edit/Global/Basic/Top:48
+msgid "rtname"
+msgstr "服务器名称"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr "秒"
+
+#: lib/RT/Queue_Overlay.pm:59
+msgid "stalled"
+msgstr "延宕"
+
+#: lib/RT/Group_Overlay.pm:201
+#. ($self->Type)
+msgid "system %1"
+msgstr "系统 %1"
+
+#: lib/RT/Group_Overlay.pm:212
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr "系统群组 '%1'"
+
+#: html/Elements/Error:42 html/SelfService/Error.html:41
+msgid "the calling component did not specify why"
+msgstr "呼叫组件未指明原因"
+
+#: lib/RT/Group_Overlay.pm:209
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr "申请单 #%1 %2"
+
+#: html/Work/Elements/SelectSearch:27
+msgid "till"
+msgstr "至"
+
+#: html/Edit/Elements/PickUsers:15 html/Edit/Global/Workflow/Condition:30 html/Edit/Users/Add.html:16 html/Edit/Users/Search.html:26 html/Work/Tickets/Cc:13
+msgid "to"
+msgstr "到"
+
+#: NOT FOUND IN SOURCE
+msgid "true"
+msgstr "真"
+
+#: lib/RT/Group_Overlay.pm:215
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr "没有描述的群组 %1"
+
+#: html/Work/Elements/SelectSearch:19
+msgid "unresolved"
+msgstr "未处理"
+
+#: lib/RT/Group_Overlay.pm:190
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr "使用者 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "warning"
+msgstr "警告"
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr "周"
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr "模板:%1"
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr "年"
+
diff --git a/rt/lib/RT/I18N/zh_tw.po b/rt/lib/RT/I18N/zh_tw.po
new file mode 100644 (file)
index 0000000..8c8c86e
--- /dev/null
@@ -0,0 +1,6416 @@
+# Traditional Chinese localization catalog for Request Tracker (RT)
+msgid ""
+msgstr ""
+"Last-Translator: Autrijus Tang <autrijus@autrijus.org>\n"
+"Language-Team: Chinese <members@ourinet.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: html/Elements/MyRequests:27 html/Elements/MyTickets:27 html/Work/Elements/MyApprovals:8 html/Work/Elements/MyRequests:15 html/Work/Elements/MyTickets:15
+msgid "#"
+msgstr "#"
+
+#: NOT FOUND IN SOURCE
+msgid "#%1"
+msgstr "#%1"
+
+#: html/Approvals/Elements/Approve:26 html/Approvals/Elements/ShowDependency:49 html/SelfService/Display.html:24 html/Ticket/Display.html:25 html/Ticket/Display.html:29
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($Ticket->id, $Ticket->Subject)
+#. ($ticket->Id, $ticket->Subject)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "#%1: %2"
+msgstr "#%1: %2"
+
+#: NOT FOUND IN SOURCE
+msgid "%*(%1,group ticket)"
+msgstr "%*(%1) 件參與的申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "%*(%1,ticket) due"
+msgstr "%*(%1) 件限期完成的申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "%*(%1,unresolved ticket)"
+msgstr "%*(%1) 件尚未解決的申請單"
+
+#: lib/RT/Date.pm:337
+#. ($s, $time_unit)
+msgid "%1 %2"
+msgstr "%1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:771
+#. ($args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'})
+msgid "%1 %2 %3"
+msgstr "%1 %2 %3"
+
+#: lib/RT/Date.pm:373
+#. ($self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900))
+msgid "%1 %2 %3 %4:%5:%6 %7"
+msgstr "%7-%2-%3 %4:%5:%6 %1"
+
+#: lib/RT/Ticket_Overlay.pm:3532 lib/RT/Transaction_Overlay.pm:557 lib/RT/Transaction_Overlay.pm:599
+#. ($cf->Name, $new_value->Content)
+#. ($field, $self->NewValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 added"
+msgstr "%2 已新增為 %1"
+
+#: lib/RT/Date.pm:334
+#. ($s, $time_unit)
+msgid "%1 %2 ago"
+msgstr "%1 %2 之前"
+
+#: lib/RT/Ticket_Overlay.pm:3538 lib/RT/Transaction_Overlay.pm:564
+#. ($cf->Name, $old_value, $new_value->Content)
+#. ($field, $self->OldValue, $self->NewValue)
+msgid "%1 %2 changed to %3"
+msgstr "%1 已從 %2 改為 %3"
+
+#: lib/RT/Ticket_Overlay.pm:3535 lib/RT/Transaction_Overlay.pm:560 lib/RT/Transaction_Overlay.pm:605
+#. ($cf->Name, $old_value)
+#. ($field, $self->OldValue)
+#. ($self->Field, $principal->Object->Name)
+msgid "%1 %2 deleted"
+msgstr "%2 已自 %1 刪除"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:157
+#. ($depth_str, $role_str, $group_str)
+msgid "%1 %2 of group %3"
+msgstr "%3 群組的 %1 %2"
+
+#: html/Admin/Elements/EditScrips:43 html/Admin/Elements/ListGlobalScrips:27
+#. (loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name))
+msgid "%1 %2 with template %3"
+msgstr "條件:%1 | 動作:%2 | 範本:%3"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 (%2) %3 this ticket\\n"
+msgstr "%1 (%2) %3 這份申請單\\n"
+
+#: html/Search/Listing.html:56 html/Work/Search/index.html:28
+#. (($session{'tickets'}->FirstRow+1), ($session{'tickets'}->FirstRow() + $session{'tickets'}->RowsPerPage()  ))
+msgid "%1 - %2 shown"
+msgstr "顯示第 %1 - %2 筆"
+
+#: bin/rt-crontool:168 bin/rt-crontool:175 bin/rt-crontool:181
+#. ("--search-argument", "--search")
+#. ("--condition-argument", "--condition")
+#. ("--action-argument", "--action")
+msgid "%1 - An argument to pass to %2"
+msgstr "%1 - 傳遞給 %2 的一個參數"
+
+#: bin/rt-crontool:184
+#. ("--verbose")
+msgid "%1 - Output status updates to STDOUT"
+msgstr "%1 - 將更新狀態輸出到 STDOUT"
+
+#: bin/rt-crontool:178
+#. ("--action")
+msgid "%1 - Specify the action module you want to use"
+msgstr "%1 - 指定欲使用的動作模組"
+
+#: bin/rt-crontool:172
+#. ("--condition")
+msgid "%1 - Specify the condition module you want to use"
+msgstr "%1 - 指定欲使用的條件模組"
+
+#: bin/rt-crontool:165
+#. ("--search")
+msgid "%1 - Specify the search module you want to use"
+msgstr "%1 - 指定欲使用的查詢模組"
+
+#: lib/RT/ScripAction_Overlay.pm:121
+#. ($self->Id)
+msgid "%1 ScripAction loaded"
+msgstr "載入手續 %1"
+
+#: html/Edit/Elements/Page:48
+#. (scalar $count)
+msgid "%1 Total"
+msgstr "共 %1 筆"
+
+#: lib/RT/Ticket_Overlay.pm:3565
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 added as a value for %2"
+msgstr "新增 %1 作為 %2 的值"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on"
+msgstr "別名 %1 需要可用的申請單編號"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on "
+msgstr "別名 %1 需要可用的申請單編號 "
+
+#: NOT FOUND IN SOURCE
+msgid "%1 aliases require a TicketId to work on (from %2) %3"
+msgstr "別名 %1 需要可用的申請單編號以處理 %3(出自 %2)"
+
+#: lib/RT/Link_Overlay.pm:116 lib/RT/Link_Overlay.pm:123
+#. ($args{'Base'})
+#. ($args{'Target'})
+msgid "%1 appears to be a local object, but can't be found in the database"
+msgstr "%1 看來是個本地物件,卻不在資料庫裡"
+
+#: html/Ticket/Elements/ShowDates:51 lib/RT/Transaction_Overlay.pm:481
+#. ($self->BriefDescription , $self->CreatorObj->Name)
+#. ($Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name)
+msgid "%1 by %2"
+msgstr "%1 (%2)"
+
+#: lib/RT/Transaction_Overlay.pm:535 lib/RT/Transaction_Overlay.pm:624 lib/RT/Transaction_Overlay.pm:633 lib/RT/Transaction_Overlay.pm:636
+#. ($self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue)
+#. ($self->Field , $q1->Name , $q2->Name)
+#. ($self->Field, $t2->AsString, $t1->AsString)
+#. ($self->Field, $self->OldValue, $self->NewValue)
+msgid "%1 changed from %2 to %3"
+msgstr "%1 的值從 %2 改為 %3"
+
+#: lib/RT/Interface/Web.pm:893 x:896
+msgid "%1 could not be set to %2."
+msgstr "無法將 %1 設定為 %2。"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 couldn't init a transaction (%2)\\n"
+msgstr "%1 無法初始更新 (%2)\\n"
+
+#: lib/RT/Ticket_Overlay.pm:2830
+#. ($self)
+msgid "%1 couldn't set status to resolved. RT's Database may be inconsistent."
+msgstr "%1 無法將現況設成已解決。RT 資料庫內容可能不一致。"
+
+#: html/Elements/MyTickets:24 html/Work/Elements/MyTickets:9
+#. ($rows)
+msgid "%1 highest priority tickets I own..."
+msgstr "前 %1 份待處理申請單..."
+
+#: html/Elements/MyRequests:24 html/Work/Elements/MyRequests:9
+#. ($rows)
+msgid "%1 highest priority tickets I requested..."
+msgstr "前 %1 份送出的申請單..."
+
+#: html/Work/Elements/MyApprovals:5
+#. ($rows)
+msgid "%1 highest priority tickets pending my approval..."
+msgstr "前 %1 份待簽核申請單..."
+
+#: bin/rt-crontool:160
+#. ($0)
+msgid "%1 is a tool to act on tickets from an external scheduling tool, such as cron."
+msgstr "%1 是從外部排程程式(如 cron)來對申請單進行操作的工具。"
+
+#: lib/RT/Queue_Overlay.pm:743
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this queue."
+msgstr "%1 已不再是此表單的 %2。"
+
+#: lib/RT/Ticket_Overlay.pm:1569
+#. ($principal->Object->Name, $args{'Type'})
+msgid "%1 is no longer a %2 for this ticket."
+msgstr "%1 已不再是此申請單的 %2。"
+
+#: lib/RT/Ticket_Overlay.pm:3621
+#. ($args{'Value'}, $cf->Name)
+msgid "%1 is no longer a value for custom field %2"
+msgstr "%1 已不再是自訂欄位 %2 的值。"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 isn't a valid Queue id."
+msgstr "%1 不是一個合法的表單編號。"
+
+#: html/Ticket/Elements/ShowBasics:35
+#. ($TimeWorked)
+msgid "%1 min"
+msgstr "%1 分鐘"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 not shown"
+msgstr "沒有顯示 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 result(s) found"
+msgstr "找到 %1 項結果"
+
+#: html/User/Elements/DelegateRights:75
+#. (loc($ObjectType =~ /^RT::(.*)$/))
+msgid "%1 rights"
+msgstr "%1權限"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 succeeded\\n"
+msgstr "%1 完成\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for $MessageId"
+msgstr "不知道 $MessageID 的 %1 類別"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 type unknown for %2"
+msgstr "不知道 %2 的 %1 類別"
+
+#: NOT FOUND IN SOURCE
+msgid "%1 was created without a CurrentUser\\n"
+msgstr "%1 新增時未指定現行使用者"
+
+#: lib/RT/Action/ResolveMembers.pm:41
+#. (ref $self)
+msgid "%1 will resolve all members of a resolved group ticket."
+msgstr "%1 會解決在已解決群組裡成員的申請單。"
+
+#: lib/RT/Action/StallDependent.pm:40
+#. (ref $self)
+msgid "%1 will stall a [local] BASE if it's dependent [or member] of a linked up request."
+msgstr "如果 %1 起始申請單依賴於某個鏈結,或是某個鏈結的成員,它將會被延宕。"
+
+#: lib/RT/Transaction_Overlay.pm:433
+#. ($self)
+msgid "%1: no attachment specified"
+msgstr "%1:未指定附件"
+
+#: html/Ticket/Elements/ShowTransaction:89 html/Work/Tickets/Elements/ShowTransaction:154
+#. ($size)
+msgid "%1b"
+msgstr "%1 位元組"
+
+#: html/Ticket/Elements/ShowTransaction:86 html/Work/Tickets/Elements/ShowTransaction:151
+#. (int($size/102.4)/10)
+msgid "%1k"
+msgstr "%1k 位元組"
+
+#: NOT FOUND IN SOURCE
+msgid "%quant(%1,result) found"
+msgstr "找到 %1 項結果"
+
+#: lib/RT/Ticket_Overlay.pm:1158
+#. ($args{'Status'})
+msgid "'%1' is an invalid value for status"
+msgstr "'%1' 不是一個合法的狀態值"
+
+#: NOT FOUND IN SOURCE
+msgid "'%1' not a recognized action. "
+msgstr "'%1'為無法辨識的動作。 "
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete group member)"
+msgstr "(點選欲刪除的成員)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check box to delete scrip)"
+msgstr "(點選欲刪除的手續)"
+
+#: html/Admin/Elements/EditCustomFieldValues:24 html/Admin/Elements/EditQueueWatchers:28 html/Admin/Elements/EditScrips:34 html/Admin/Elements/EditTemplates:35 html/Admin/Elements/EditWorkflows:36 html/Admin/Groups/Members.html:51 html/Ticket/Elements/EditLinks:32 html/Ticket/Elements/EditPeople:45 html/User/Groups/Members.html:54
+msgid "(Check box to delete)"
+msgstr "(點選欲刪除的項目)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Check boxes to delete)"
+msgstr "(點選欲刪除的項目)"
+
+#: html/Ticket/Create.html:177
+msgid "(Enter ticket ids or URLs, seperated with spaces)"
+msgstr "(鍵入申請單編號或網址,以空白分隔)"
+
+#: html/Admin/Queues/Modify.html:53 html/Admin/Queues/Modify.html:59
+#. ($RT::CorrespondAddress)
+#. ($RT::CommentAddress)
+msgid "(If left blank, will default to %1"
+msgstr "(如果留白, 則預設為 %1)"
+
+#: NOT FOUND IN SOURCE
+msgid "(No Value)"
+msgstr "(沒有值)"
+
+#: html/Admin/Elements/EditCustomFields:32 html/Admin/Elements/ListGlobalCustomFields:31
+msgid "(No custom fields)"
+msgstr "(沒有自訂欄位)"
+
+#: html/Admin/Groups/Members.html:49 html/User/Groups/Members.html:52
+msgid "(No members)"
+msgstr "(沒有成員)"
+
+#: html/Admin/Elements/EditScrips:31 html/Admin/Elements/ListGlobalScrips:31
+msgid "(No scrips)"
+msgstr "(沒有手續)"
+
+#: html/Admin/Elements/EditTemplates:30
+msgid "(No templates)"
+msgstr "沒有範本"
+
+#: html/Admin/Elements/EditWorkflows:31
+msgid "(No workflows)"
+msgstr "沒有流程"
+
+#: html/Ticket/Update.html:83 html/Work/Tickets/Update.html:52
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(送出本份更新的密件副本給名單上以逗號隔開的電子郵件位址。這<b>不會</b>更改後續的收件者名單。)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(送出本份更新的密件副本給名單上以逗號隔開的電子郵件位址。這<b>不會</b>更改後續的收件者名單。)"
+
+#: html/Ticket/Create.html:78
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(送出本份更新的副本給名單上以逗號隔開的管理員電子郵件位址。這<b>將會</b>更改後續的收件者名單。)"
+
+#: html/Ticket/Update.html:79
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will receive future updates.)"
+msgstr "(送出本份更新的副本給名單上以逗號隔開的電子郵件位址。這<b>不會</b>更改後續的收件者名單。)"
+
+#: NOT FOUND IN SOURCE
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <b>not</b> change who will recieve future updates.)"
+msgstr "(送出本份更新的副本給名單上以逗號隔開的電子郵件位址。這<b>不會</b>更改後續的收件者名單。)"
+
+#: html/Ticket/Create.html:68
+msgid "(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <b>will</b> receive future updates.)"
+msgstr "(送出本份更新的副本給名單上以逗號隔開的電子郵件位址。這<b>將會</b>更改後續的收件者名單。)"
+
+#: html/Ticket/Elements/EditCustomFieldEntries:35 html/Work/Tickets/Elements/EditCustomFieldEntries:48 html/Work/Tickets/Elements/ShowCustomFieldEntries:13
+msgid "(delete)"
+msgstr "(刪除)"
+
+#: html/Admin/Groups/index.html:32 html/User/Groups/index.html:32
+msgid "(empty)"
+msgstr "(空白)"
+
+#: html/Edit/Global/CustomField/index.html:113 html/Edit/Global/Scrip/index.html:111 html/Edit/Global/Template/index.html:106
+msgid "(new)"
+msgstr "(新增)"
+
+#: html/Admin/Users/index.html:38
+msgid "(no name listed)"
+msgstr "(沒有列出姓名)"
+
+#: html/Elements/MyRequests:42 html/Elements/MyTickets:44 html/Work/Elements/MyApprovals:37 html/Work/Elements/MyRequests:42 html/Work/Elements/MyTickets:51
+msgid "(no subject)"
+msgstr "(沒有主題)"
+
+#: html/Admin/Elements/SelectRights:47 html/Elements/SelectCustomFieldValue:29 html/Ticket/Elements/EditCustomField:60 html/Ticket/Elements/EditCustomFieldValues:52 html/Ticket/Elements/ShowCustomFields:35 html/Work/Elements/EditCustomFieldValues:50 html/Work/Elements/EditCustomFields:32 html/Work/Tickets/Elements/EditCustomFieldValues:33 lib/RT/Transaction_Overlay.pm:534
+msgid "(no value)"
+msgstr "(無)"
+
+#: html/Ticket/Elements/BulkLinks:27 html/Ticket/Elements/EditLinks:115 html/Work/Search/BulkLinks:3
+msgid "(only one ticket)"
+msgstr "(僅能指定一份申請單)"
+
+#: html/Elements/MyRequests:51 html/Elements/MyTickets:54 html/Work/Elements/List:17 html/Work/Elements/MyRequests:52 html/Work/Elements/MyTickets:66 html/Work/Tickets/Elements/ShowBasics:52
+msgid "(pending approval)"
+msgstr "(等待簽核)"
+
+#: html/Elements/MyRequests:53 html/Elements/MyTickets:56 html/Work/Elements/MyRequests:54 html/Work/Elements/MyTickets:68
+msgid "(pending other tickets)"
+msgstr "(等待其他申請單)"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:246
+msgid "(requestor's group)"
+msgstr "(申請人所屬)"
+
+#: html/Admin/Users/Modify.html:49
+msgid "(required)"
+msgstr "(必填)"
+
+#: html/Ticket/Elements/ShowTransaction:92 html/Work/Tickets/Elements/ShowTransaction:39
+msgid "(untitled)"
+msgstr "(未命名)"
+
+#: NOT FOUND IN SOURCE
+msgid ":"
+msgstr ":"
+
+#: html/Ticket/Elements/ShowBasics:31
+msgid "<% $Ticket->Status%>"
+msgstr "<% $Ticket->Status%>"
+
+#: html/Elements/SelectTicketTypes:26
+msgid "<% $_ %>"
+msgstr "<% $_ %>"
+
+#: docs/design_docs/string-extraction-guide.txt:54 html/Elements/CreateTicket:25 html/Work/Elements/104Header:43
+#. ($m->scomp('/Elements/SelectNewTicketQueue'))
+msgid "<input type=\"submit\" value=\"New ticket in\">&nbsp;%1"
+msgstr "<input type=\"submit\" value=\"提出申請單\">&nbsp;%1"
+
+#: etc/initialdata.zh:221 etc/initialdata:203
+msgid "A blank template"
+msgstr "空白範本"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Deleted"
+msgstr "ACE 已刪除"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE Loaded"
+msgstr "ACE 已載入"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be deleted"
+msgstr "無法刪除 ACE"
+
+#: NOT FOUND IN SOURCE
+msgid "ACE could not be found"
+msgstr "找不到 ACE"
+
+#: lib/RT/ACE_Overlay.pm:156 lib/RT/Principal_Overlay.pm:180
+msgid "ACE not found"
+msgstr "找不到 ACE 設定"
+
+#: lib/RT/ACE_Overlay.pm:830
+msgid "ACEs can only be created and deleted."
+msgstr "祇能新增或刪除 ACE 設定。"
+
+#: NOT FOUND IN SOURCE
+msgid "ACLEquivalence"
+msgstr "ACLEquivalence"
+
+#: bin/rt-commit-handler:754
+msgid "Aborting to avoid unintended ticket modifications.\\n"
+msgstr "離開以免不小心更改到申請單。\\n"
+
+#: html/User/Elements/Tabs:31
+msgid "About me"
+msgstr "個人資訊"
+
+#: html/Edit/Users/System:12
+msgid "Access Right"
+msgstr "系統使用登錄權限"
+
+#: html/Admin/Users/Modify.html:79
+msgid "Access control"
+msgstr "存取權限"
+
+#: html/Admin/Elements/EditScrip:56 html/Work/Tickets/Elements/ShowTransaction:18
+msgid "Action"
+msgstr "動作"
+
+#: lib/RT/Scrip_Overlay.pm:146
+#. ($args{'ScripAction'})
+msgid "Action %1 not found"
+msgstr "動作 %1 找不到"
+
+#: bin/rt-crontool:122
+msgid "Action committed."
+msgstr "動作執行完畢"
+
+#: bin/rt-crontool:118
+msgid "Action prepared..."
+msgstr "動作準備完畢..."
+
+#: html/Work/Elements/List:13 html/Work/Elements/SelectSearch:24 html/Work/Tickets/Create.html:28 html/Work/Tickets/Elements/ShowBasics:12
+msgid "Activated Date"
+msgstr "申請啟動時間"
+
+#: html/Edit/Elements/104Buttons:71 html/Edit/Elements/ListButtons:7
+msgid "Add"
+msgstr "新增"
+
+#: html/Search/Bulk.html:95 html/Work/Search/Bulk.html:74
+msgid "Add AdminCc"
+msgstr "新增管理員副本收件人"
+
+#: html/Search/Bulk.html:91 html/Work/Search/Bulk.html:68
+msgid "Add Cc"
+msgstr "新增副本收件人"
+
+#: html/Ticket/Elements/EditCustomFieldEntries:71 html/Work/Tickets/Elements/ShowCustomFieldEntries:49
+msgid "Add Entry"
+msgstr "新增列"
+
+#: html/Ticket/Create.html:113 html/Ticket/Update.html:98 html/Work/Tickets/Elements/AddAttachments:18
+msgid "Add More Files"
+msgstr "新增更多附件"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:112 html/Admin/Elements/ModifyTemplateAsWorkflow:45
+msgid "Add Next State"
+msgstr "新增下一項關卡"
+
+#: html/Search/Bulk.html:87 html/Work/Search/Bulk.html:62
+msgid "Add Requestor"
+msgstr "新增申請人"
+
+#: html/Admin/Elements/AddCustomFieldValue:24
+msgid "Add Value"
+msgstr "新增欄位值"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip to this queue"
+msgstr "新增此表單的手續"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a Scrip which will apply to all queues"
+msgstr "新增適用於所有表單的手續"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a keyword selection to this queue"
+msgstr "新增此表單的關鍵字"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a new a global scrip"
+msgstr "新增全域手續"
+
+#: NOT FOUND IN SOURCE
+msgid "Add a scrip to this queue"
+msgstr "新增一道手續到此表單"
+
+#: html/Admin/Global/Scrip.html:54
+msgid "Add a scrip which will apply to all queues"
+msgstr "新增一道用於所有表單的手續"
+
+#: html/Search/Bulk.html:127 html/Work/Search/Bulk.html:80
+msgid "Add comments or replies to selected tickets"
+msgstr "新增評論或回覆到指定的申請單"
+
+#: html/Admin/Groups/Members.html:41 html/User/Groups/Members.html:38
+msgid "Add members"
+msgstr "新增成員"
+
+#: html/Admin/Queues/People.html:65 html/Ticket/Elements/AddWatchers:27
+msgid "Add new watchers"
+msgstr "新增視察員"
+
+#: NOT FOUND IN SOURCE
+msgid "AddNextState"
+msgstr "新增下一項關卡"
+
+#: lib/RT/Queue_Overlay.pm:643
+#. ($args{'Type'})
+msgid "Added principal as a %1 for this queue"
+msgstr "單位已新增為此表單的 %1"
+
+#: lib/RT/Ticket_Overlay.pm:1453
+#. ($self->loc($args{'Type'}))
+msgid "Added principal as a %1 for this ticket"
+msgstr "單位已新增為此申請單的 %1"
+
+#: html/Admin/Elements/ModifyUser:75 html/Admin/Users/Modify.html:121 html/User/Prefs.html:87 html/Work/Preferences/Info:77
+msgid "Address1"
+msgstr "住址"
+
+#: html/Admin/Elements/ModifyUser:77 html/Admin/Users/Modify.html:126 html/User/Prefs.html:89 html/Work/Preferences/Info:79
+msgid "Address2"
+msgstr "住址(續)"
+
+#: NOT FOUND IN SOURCE
+msgid "Adjust Blinking Rate"
+msgstr "調整閃爍速度快慢"
+
+#: html/Edit/Groups/Admin:9
+msgid "Admin"
+msgstr "管理員"
+
+#: html/Ticket/Create.html:73
+msgid "Admin Cc"
+msgstr "管理員副本"
+
+#: etc/initialdata.zh:303 etc/initialdata:280
+msgid "Admin Comment"
+msgstr "管理員評論"
+
+#: etc/initialdata.zh:261 etc/initialdata:259
+msgid "Admin Correspondence"
+msgstr "管理員回覆"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin Rights"
+msgstr "管理員權限"
+
+#: html/Admin/Queues/index.html:24 html/Admin/Queues/index.html:27
+msgid "Admin queues"
+msgstr "表單管理"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin users"
+msgstr "使用者管理"
+
+#: html/Admin/Global/index.html:25 html/Admin/Global/index.html:27
+msgid "Admin/Global configuration"
+msgstr "管理/全域設定"
+
+#: NOT FOUND IN SOURCE
+msgid "Admin/Groups"
+msgstr "管理/群組"
+
+#: html/Admin/Queues/Modify.html:24 html/Admin/Queues/Modify.html:28
+msgid "Admin/Queue/Basics"
+msgstr "管理/表單/基本資訊"
+
+#: html/Edit/Global/Basic/Top:60
+msgid "AdminAddress"
+msgstr "管理員 Email"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminAllPersonalGroups"
+msgstr "管理所有代理人群組"
+
+#: etc/initialdata.zh:74 etc/initialdata:56 html/Admin/Elements/ModifyTemplateAsWorkflow:155 html/Ticket/Elements/ShowPeople:38 html/Ticket/Update.html:49 lib/RT/ACE_Overlay.pm:88
+msgid "AdminCc"
+msgstr "管理員副本"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminComment"
+msgstr "管理員評論"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminCorrespondence"
+msgstr "管理員回覆"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "AdminCustomFields"
+msgstr "管理自訂欄位"
+
+#: html/Edit/Groups/Admin:12 lib/RT/Group_Overlay.pm:145
+msgid "AdminGroup"
+msgstr "管理群組"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminGroupDescription"
+msgstr "管理群組描述"
+
+#: lib/RT/Group_Overlay.pm:147
+msgid "AdminGroupMembership"
+msgstr "管理群組成員"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminGroupName"
+msgstr "管理群組名稱"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminGroupPermission"
+msgstr "管理群組權限"
+
+#: NOT FOUND IN SOURCE
+msgid "AdminGroupStatus"
+msgstr "管理群組狀態"
+
+#: lib/RT/System.pm:58
+msgid "AdminOwnPersonalGroups"
+msgstr "管理代理人群組"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "AdminQueue"
+msgstr "管理表單"
+
+#: lib/RT/System.pm:59
+msgid "AdminUsers"
+msgstr "管理使用者"
+
+#: NOT FOUND IN SOURCE
+msgid "Administrative"
+msgstr "行政類"
+
+#: html/Admin/Queues/People.html:47 html/Ticket/Elements/EditPeople:53
+msgid "Administrative Cc"
+msgstr "管理員副本"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:233
+msgid "Admins"
+msgstr "主管"
+
+#: NOT FOUND IN SOURCE
+msgid "Advanced Search"
+msgstr "進階查詢"
+
+#: html/Elements/SelectDateRelation:35
+msgid "After"
+msgstr "晚於"
+
+#: NOT FOUND IN SOURCE
+msgid "Age"
+msgstr "經歷時間"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:172 html/Edit/Global/Workflow/Action:39
+msgid "Alias"
+msgstr "執行其他流程"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:175
+msgid "Alias for"
+msgstr "相當於"
+
+#: html/Edit/Queues/index.html:33 html/Work/Delegates/index.html:13 html/Work/Elements/SelectSearch:11 html/Work/Queues/Select.html:14 html/Work/Queues/index.html:13
+msgid "All"
+msgstr "全部"
+
+#: etc/initialdata.zh:372 etc/initialdata:348
+msgid "All Approvals Passed"
+msgstr "完成全部簽核"
+
+#: html/Edit/Global/Workflow/Condition:16
+msgid "All Condition"
+msgstr "所有條件"
+
+#: html/Admin/Elements/EditCustomFields:95
+msgid "All Custom Fields"
+msgstr "所有自訂欄位"
+
+#: html/Admin/Queues/index.html:52
+msgid "All Queues"
+msgstr "所有表單"
+
+#: NOT FOUND IN SOURCE
+msgid "All Users"
+msgstr "全體員工"
+
+#: NOT FOUND IN SOURCE
+msgid "Allowance Request"
+msgstr "福利補助申請"
+
+#: NOT FOUND IN SOURCE
+msgid "Always sends a message to the requestors independent of message sender"
+msgstr "無論寄件來源為何,一律寄信給申請人"
+
+#: NOT FOUND IN SOURCE
+msgid "Amount"
+msgstr "數額"
+
+#: html/Edit/Global/Workflow/Condition:13
+msgid "Any Condition"
+msgstr "任意條件"
+
+#: html/Edit/Global/Scrip/List:10 html/Edit/Global/Scrip/Top:74
+msgid "Apply Template"
+msgstr "引用範本"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:138 html/Elements/Tabs:55 html/Work/Approvals/Elements/Approve:6
+msgid "Approval"
+msgstr "簽核"
+
+#: html/Approvals/Display.html:45 html/Approvals/Elements/ShowDependency:41 html/Approvals/index.html:64
+#. ($Ticket->Id, $Ticket->Subject)
+#. ($ticket->id, $msg)
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Approval #%1: %2"
+msgstr "簽核單 #%1:%2"
+
+#: html/Approvals/index.html:53
+#. ($ticket->Id)
+msgid "Approval #%1: Notes not recorded due to a system error"
+msgstr "簽核單 #%1:系統錯誤,記錄失敗"
+
+#: html/Approvals/index.html:51
+#. ($ticket->Id)
+msgid "Approval #%1: Notes recorded"
+msgstr "簽核單 #%1:記錄完畢"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:123
+msgid "Approval Details"
+msgstr "簽核細節"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Due"
+msgstr "簽核時限"
+
+#: html/Work/Approvals/Elements/Approve:37
+msgid "Approval Notes"
+msgstr "簽核意見"
+
+#: etc/initialdata.zh:357 etc/initialdata:336
+msgid "Approval Passed"
+msgstr "完成某項簽核"
+
+#: etc/initialdata.zh:383 etc/initialdata:359
+msgid "Approval Rejected"
+msgstr "駁回某項簽核"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Result"
+msgstr "簽核結果"
+
+#: html/Work/Approvals/Elements/Approve:25
+msgid "Approval Status"
+msgstr "核准結果"
+
+#: NOT FOUND IN SOURCE
+msgid "Approval Type"
+msgstr "簽核種類"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:25
+msgid "Approval diagram"
+msgstr "簽核流程"
+
+#: html/Approvals/Elements/Approve:43 html/Work/Approvals/Elements/Approve:29
+msgid "Approve"
+msgstr "核准"
+
+#: html/Work/Approvals/Elements/Approve:21 html/Work/Elements/List:9
+msgid "Approver"
+msgstr "簽核人"
+
+#: html/Edit/Global/Workflow/Action:29 html/Edit/Global/Workflow/Owner.html:10
+msgid "Approver Setting"
+msgstr "執行簽核人設定"
+
+#: etc/initialdata.zh:516 etc/initialdata:486 etc/upgrade/2.1.71:148 html/Edit/Elements/CreateApprovalsQueue:122
+msgid "Approver's notes: %1"
+msgstr "簽核備註:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Apr"
+msgstr "四月"
+
+#: lib/RT/Date.pm:414
+msgid "Apr."
+msgstr "04"
+
+#: NOT FOUND IN SOURCE
+msgid "April"
+msgstr "四月"
+
+#: html/Edit/Elements/104Buttons:24
+msgid "Are you sure to delete checked items?"
+msgstr "您確定要刪除?"
+
+#: html/Elements/SelectSortOrder:34
+msgid "Ascending"
+msgstr "遞增"
+
+#: html/Search/Bulk.html:136 html/SelfService/Update.html:32 html/Ticket/ModifyAll.html:82 html/Ticket/Update.html:98 html/Work/Search/Bulk.html:88
+msgid "Attach"
+msgstr "附件"
+
+#: html/SelfService/Create.html:64 html/Ticket/Create.html:109 html/Work/Tickets/Elements/AddAttachments:15
+msgid "Attach file"
+msgstr "附加檔案"
+
+#: html/Ticket/Create.html:97 html/Ticket/Update.html:87 html/Work/Tickets/Elements/AddAttachments:6
+msgid "Attached file"
+msgstr "現有附件"
+
+#: NOT FOUND IN SOURCE
+msgid "Attachment '%1' could not be loaded"
+msgstr "無法載入附件 '%1'"
+
+#: lib/RT/Transaction_Overlay.pm:441
+msgid "Attachment created"
+msgstr "附件新增完畢"
+
+#: lib/RT/Tickets_Overlay.pm:1189
+msgid "Attachment filename"
+msgstr "附件檔名"
+
+#: html/Ticket/Elements/ShowAttachments:25 html/Work/Tickets/Elements/ShowTransaction:32
+msgid "Attachments"
+msgstr "附件"
+
+#: NOT FOUND IN SOURCE
+msgid "Aug"
+msgstr "八月"
+
+#: lib/RT/Date.pm:418
+msgid "Aug."
+msgstr "08"
+
+#: NOT FOUND IN SOURCE
+msgid "August"
+msgstr "八月"
+
+#: html/Admin/Elements/ModifyUser:65
+msgid "AuthSystem"
+msgstr "認證方式"
+
+#: NOT FOUND IN SOURCE
+msgid "AutoReject"
+msgstr "自動駁回表單"
+
+#: NOT FOUND IN SOURCE
+msgid "AutoResolve"
+msgstr "自動完成表單處理"
+
+#: etc/initialdata.zh:224 etc/initialdata:206
+msgid "Autoreply"
+msgstr "自動回覆"
+
+#: etc/initialdata.zh:90 etc/initialdata:72
+msgid "Autoreply To Requestors"
+msgstr "自動對申請人回覆"
+
+#: NOT FOUND IN SOURCE
+msgid "AutoreplyToRequestors"
+msgstr "自動對申請人回覆"
+
+#: html/Edit/Rights/index.html:16
+msgid "Available Rights:"
+msgstr "權限項目列表:"
+
+#: NOT FOUND IN SOURCE
+msgid "Back to Homepage"
+msgstr "回到首頁"
+
+#: html/Work/Elements/BackButton:2 html/Work/Search/Bulk.html:101
+msgid "Back to Previous"
+msgstr "回上頁"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad PGP Signature: %1\\n"
+msgstr "錯誤的 PGP 簽章:%1\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad attachment id. Couldn't find attachment '%1'\\n"
+msgstr "錯誤的附件編號。無法找到附件 '%1'\\n"
+
+#: bin/rt-commit-handler:826
+#. ($val)
+msgid "Bad data in %1"
+msgstr "%1 的資料錯誤"
+
+#: NOT FOUND IN SOURCE
+msgid "Bad transaction number for attachment. %1 should be %2\\n"
+msgstr "附件的處理號碼錯誤。%1 應為 %2\\n"
+
+#: html/Admin/Elements/GroupTabs:38 html/Admin/Elements/QueueTabs:38 html/Admin/Elements/UserTabs:37 html/Edit/Global/autohandler:6 html/Edit/Queues/autohandler:17 html/Edit/Users/index.html:121 html/Ticket/Elements/Tabs:89 html/User/Elements/GroupTabs:37
+msgid "Basics"
+msgstr "基本資訊"
+
+#: html/Ticket/Update.html:81 html/Work/Tickets/Update.html:49
+msgid "Bcc"
+msgstr "密件副本"
+
+#: html/Admin/Elements/EditScrip:87 html/Admin/Global/GroupRights.html:84 html/Admin/Global/Template.html:45 html/Admin/Global/UserRights.html:53 html/Admin/Global/Workflow.html:46 html/Admin/Groups/GroupRights.html:72 html/Admin/Groups/Members.html:80 html/Admin/Groups/Modify.html:55 html/Admin/Groups/UserRights.html:54 html/Admin/Queues/GroupRights.html:85 html/Admin/Queues/Template.html:44 html/Admin/Queues/UserRights.html:53 html/Admin/Queues/Workflow.html:44 html/User/Groups/Modify.html:55
+msgid "Be sure to save your changes"
+msgstr "請別忘了儲存修改。"
+
+#: html/Elements/SelectDateRelation:33 lib/RT/CurrentUser.pm:321
+msgid "Before"
+msgstr "早於"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:44
+msgid "Begin Approval"
+msgstr "開始簽核"
+
+#: NOT FOUND IN SOURCE
+msgid "Begin From "
+msgstr "起始日"
+
+#: html/Edit/Users/Info:25
+msgid "Birthday"
+msgstr "生日"
+
+#: etc/initialdata.zh:220 etc/initialdata:202
+msgid "Blank"
+msgstr "空白範本"
+
+#: html/Search/Listing.html:78 html/Work/Search/index.html:53
+msgid "Bookmarkable URL for this search"
+msgstr "將查詢結果轉為可放入書籤的網址"
+
+#: html/Ticket/Elements/ShowHistory:38 html/Ticket/Elements/ShowHistory:44
+msgid "Brief headers"
+msgstr "精簡標頭檔"
+
+#: html/Search/Bulk.html:24 html/Search/Bulk.html:25
+msgid "Bulk ticket update"
+msgstr "更新整批申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "Business Unit"
+msgstr "事業部"
+
+#: NOT FOUND IN SOURCE
+msgid "Business Unit:"
+msgstr "事業部:"
+
+#: lib/RT/User_Overlay.pm:1524
+msgid "Can not modify system users"
+msgstr "無法更改系統使用者"
+
+#: lib/RT/Queue_Overlay.pm:66
+msgid "Can this principal see this queue"
+msgstr "該單位是否能查閱此表單"
+
+#: lib/RT/CustomField_Overlay.pm:205
+msgid "Can't add a custom field value without a name"
+msgstr "不能新增沒有名稱的自訂欄位值"
+
+#: lib/RT/Link_Overlay.pm:131
+msgid "Can't link a ticket to itself"
+msgstr "申請單不能鏈結自己。"
+
+#: lib/RT/Ticket_Overlay.pm:2807
+msgid "Can't merge into a merged ticket. You should never get this error"
+msgstr "不能整合進已整合過的申請單。這個錯誤不該發生。"
+
+#: lib/RT/Ticket_Overlay.pm:2625 lib/RT/Ticket_Overlay.pm:2694
+msgid "Can't specifiy both base and target"
+msgstr "不能同時指定起始申請單與目的申請單"
+
+#: html/Edit/Elements/PopFooter:8
+msgid "Cancel"
+msgstr "取消"
+
+#: html/autohandler:113
+#. ($msg)
+msgid "Cannot create user: %1"
+msgstr "無法新增使用者:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Card No."
+msgstr "卡號"
+
+#: NOT FOUND IN SOURCE
+msgid "Categories"
+msgstr "分類管理"
+
+#: NOT FOUND IN SOURCE
+msgid "Category"
+msgstr "分類"
+
+#: etc/initialdata.zh:68 etc/initialdata:50 html/Admin/Queues/People.html:43 html/SelfService/Create.html:48 html/Ticket/Create.html:63 html/Ticket/Elements/EditPeople:50 html/Ticket/Elements/ShowPeople:34 html/Ticket/Update.html:44 html/Ticket/Update.html:76 html/Work/Tickets/Update.html:43 lib/RT/ACE_Overlay.pm:87
+msgid "Cc"
+msgstr "副本"
+
+#: NOT FOUND IN SOURCE
+msgid "Cc Type"
+msgstr "副本類別"
+
+#: NOT FOUND IN SOURCE
+msgid "Chairperson's Office"
+msgstr "董事長室"
+
+#: NOT FOUND IN SOURCE
+msgid "Change Ticket"
+msgstr "修改申請單"
+
+#: html/SelfService/Prefs.html:30
+msgid "Change password"
+msgstr "更改密碼"
+
+#: html/Edit/Global/Basic/Top:70
+msgid "ChangeOwnerUI"
+msgstr "可否選擇表單承辦人"
+
+#: html/Ticket/Create.html:100 html/Ticket/Elements/EditCustomFieldEntries:35 html/Ticket/Update.html:90 html/Work/Tickets/Elements/ShowCustomFieldEntries:13
+msgid "Check box to delete"
+msgstr "選擇欲刪除的項目"
+
+#: html/Admin/Elements/SelectRights:30
+msgid "Check box to revoke right"
+msgstr "選擇欲撤消的權利"
+
+#: html/Ticket/Create.html:182 html/Ticket/Elements/BulkLinks:42 html/Ticket/Elements/EditLinks:130 html/Ticket/Elements/EditLinks:68 html/Ticket/Elements/ShowLinks:56 html/Work/Search/BulkLinks:18
+msgid "Children"
+msgstr "子申請單"
+
+#: html/Edit/Elements/PickUsers:21 html/Edit/Global/UserRight/List:8 html/Edit/Global/UserRight/Top:19 html/Edit/Users/List:6 html/Edit/Users/Top:18
+msgid "Chinese Name"
+msgstr "中文姓名"
+
+#: NOT FOUND IN SOURCE
+msgid "Chinese/English"
+msgstr "中英文"
+
+#: html/Admin/Elements/ModifyUser:79 html/Admin/Users/Modify.html:131 html/User/Prefs.html:91 html/Work/Preferences/Info:81
+msgid "City"
+msgstr "所在城市"
+
+#: html/Edit/Elements/104Top:30
+msgid "ClassicUI"
+msgstr "傳統介面"
+
+#: html/Ticket/Elements/ShowDates:46
+msgid "Closed"
+msgstr "已解決"
+
+#: html/SelfService/Closed.html:24
+msgid "Closed Tickets"
+msgstr "已解決的申請單"
+
+#: html/SelfService/Elements/Tabs:44
+msgid "Closed tickets"
+msgstr "已解決的申請單"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:181 html/Edit/Global/Workflow/Action:58 html/Edit/Global/Workflow/Condition:51
+msgid "Code"
+msgstr "執行程式碼"
+
+#: NOT FOUND IN SOURCE
+msgid "Command not understood!\\n"
+msgstr "指令無法辨識!\\n"
+
+#: html/Ticket/Elements/ShowTransaction:166 html/Ticket/Elements/Tabs:152 html/Work/Search/Bulk.html:89 html/Work/Tickets/Display.html:37 html/Work/Tickets/Elements/ShowTransaction:114 html/Work/Tickets/Elements/ShowTransaction:27
+msgid "Comment"
+msgstr "評論"
+
+#: html/Admin/Elements/ModifyQueue:44 html/Admin/Queues/Modify.html:57
+msgid "Comment Address"
+msgstr "評論電子郵件地址"
+
+#: NOT FOUND IN SOURCE
+msgid "Comment not recorded"
+msgstr "評論未被紀錄"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "Comment on tickets"
+msgstr "對申請單提出評論"
+
+#: lib/RT/Queue_Overlay.pm:85
+msgid "CommentOnTicket"
+msgstr "評論申請單"
+
+#: html/Admin/Elements/ModifyUser:34 html/Work/Tickets/Update.html:59
+msgid "Comments"
+msgstr "評論"
+
+#: html/Ticket/ModifyAll.html:69 html/Ticket/Update.html:68 html/Work/Tickets/Update.html:35
+msgid "Comments (Not sent to requestors)"
+msgstr "評論(不送給申請人)"
+
+#: html/Search/Bulk.html:131 html/Work/Search/Bulk.html:83
+msgid "Comments (not sent to requestors)"
+msgstr "評論(不送給申請人)"
+
+#: html/Elements/ViewUser:26
+#. ($name)
+msgid "Comments about %1"
+msgstr "對 %1 的評論"
+
+#: html/Admin/Users/Modify.html:184 html/Ticket/Elements/ShowRequestor:43
+msgid "Comments about this user"
+msgstr "使用者描述"
+
+#: lib/RT/Transaction_Overlay.pm:543
+msgid "Comments added"
+msgstr "新增評論完畢"
+
+#: html/Edit/Elements/PopFooter:4 html/Edit/Elements/PopFooter:6
+msgid "Commit"
+msgstr "確認"
+
+#: lib/RT/Action/Generic.pm:139
+msgid "Commit Stubbed"
+msgstr "消除更動完畢"
+
+#: html/Edit/Users/Info:41
+msgid "Company Name"
+msgstr "公司名稱"
+
+#: NOT FOUND IN SOURCE
+msgid "Compile Restrictions"
+msgstr "設定查詢條件"
+
+#: html/Admin/Elements/EditScrip:40 html/Admin/Elements/ModifyTemplateAsWorkflow:127
+msgid "Condition"
+msgstr "條件"
+
+#: bin/rt-crontool:108
+msgid "Condition matches..."
+msgstr "符合條件..."
+
+#: lib/RT/Scrip_Overlay.pm:159
+msgid "Condition not found"
+msgstr "未找到符合的現況"
+
+#: html/Edit/Global/GroupRight/Top:26 html/Edit/Global/UserRight/Top:45 html/Edit/Groups/Member:57 html/Elements/Tabs:49
+msgid "Configuration"
+msgstr "設定"
+
+#: html/SelfService/Prefs.html:32
+msgid "Confirm"
+msgstr "確認密碼"
+
+#: NOT FOUND IN SOURCE
+msgid "Confirm Password"
+msgstr "密碼確認"
+
+#: html/Work/Approvals/Display.html:25 html/Work/Tickets/Create.html:161 html/Work/Tickets/Create.html:174 html/Work/Tickets/Update.html:81
+msgid "Confirm Submit"
+msgstr "確定送出"
+
+#: NOT FOUND IN SOURCE
+msgid "Contact System Administrator"
+msgstr "連絡系統管理員"
+
+#: html/Admin/Elements/ModifyUser:59
+msgid "ContactInfoSystem"
+msgstr "連絡資訊系統"
+
+#: NOT FOUND IN SOURCE
+msgid "Contacted date '%1' could not be parsed"
+msgstr "無法解讀聯絡日期 '%1'"
+
+#: html/Admin/Elements/ModifyTemplate:43 html/Admin/Elements/ModifyTemplateAsWorkflow:200 html/Ticket/ModifyAll.html:86
+msgid "Content"
+msgstr "內容"
+
+#: NOT FOUND IN SOURCE
+msgid "Coould not create group"
+msgstr "無法新增群組"
+
+#: html/Edit/Elements/104Buttons:74
+msgid "Copy"
+msgstr "複製"
+
+#: NOT FOUND IN SOURCE
+msgid "Copy Field From:"
+msgstr "欲複製欄位:"
+
+#: etc/initialdata.zh:282 etc/initialdata:271
+msgid "Correspondence"
+msgstr "回覆"
+
+#: html/Admin/Elements/ModifyQueue:38 html/Admin/Queues/Modify.html:50
+msgid "Correspondence Address"
+msgstr "申請單回覆地址"
+
+#: lib/RT/Transaction_Overlay.pm:539
+msgid "Correspondence added"
+msgstr "新增申請單回覆"
+
+#: NOT FOUND IN SOURCE
+msgid "Correspondence not recorded"
+msgstr "未紀錄申請單回覆"
+
+#: lib/RT/Ticket_Overlay.pm:3552
+msgid "Could not add new custom field value for ticket. "
+msgstr "不能新增自訂欄位的值 "
+
+#: NOT FOUND IN SOURCE
+msgid "Could not add new custom field value for ticket. %1 "
+msgstr "不能新增自訂欄位的值。%1 "
+
+#: lib/RT/Ticket_Overlay.pm:3058 lib/RT/Ticket_Overlay.pm:3066 lib/RT/Ticket_Overlay.pm:3083
+msgid "Could not change owner. "
+msgstr "不能更改承辦人。 "
+
+#: html/Admin/Elements/EditCustomField:84 html/Admin/Elements/EditCustomFields:165 html/Edit/Global/CustomField/index.html:117
+#. ($msg)
+msgid "Could not create CustomField"
+msgstr "無法新增自訂欄位"
+
+#: html/Edit/Global/Workflow/index.html:126
+#. ($msg)
+msgid "Could not create Scrip"
+msgstr "無法建立訊息通知"
+
+#: html/Edit/Global/Template/index.html:110
+#. ($msg)
+msgid "Could not create Template"
+msgstr "無法建立通知範本"
+
+#: html/User/Groups/Modify.html:76 lib/RT/Group_Overlay.pm:473 lib/RT/Group_Overlay.pm:480
+msgid "Could not create group"
+msgstr "無法新增群組"
+
+#: html/Admin/Global/Template.html:74 html/Admin/Queues/Template.html:71
+#. ($msg)
+msgid "Could not create template: %1"
+msgstr "無法新增範本:%1"
+
+#: lib/RT/Ticket_Overlay.pm:1091 lib/RT/Ticket_Overlay.pm:334
+msgid "Could not create ticket. Queue not set"
+msgstr "無法新增申請單。尚未指定表單。"
+
+#: lib/RT/User_Overlay.pm:267 lib/RT/User_Overlay.pm:279 lib/RT/User_Overlay.pm:297 lib/RT/User_Overlay.pm:483
+msgid "Could not create user"
+msgstr "無法新增使用者"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not create watcher for requestor"
+msgstr "無法為申請人新增視察員"
+
+#: html/Admin/Elements/ModifyWorkflow:219 html/Admin/Global/Workflow.html:75 html/Admin/Queues/Workflow.html:71
+#. ($msg)
+msgid "Could not create workflow: %1"
+msgstr "無法新增流程:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find a ticket with id %1"
+msgstr "找不到編號 %1 的申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find group %1."
+msgstr "找不到群組 %1。"
+
+#: lib/RT/Queue_Overlay.pm:621 lib/RT/Ticket_Overlay.pm:1421
+msgid "Could not find or create that user"
+msgstr "找不到或無法新增該名使用者"
+
+#: lib/RT/Queue_Overlay.pm:682 lib/RT/Ticket_Overlay.pm:1500
+msgid "Could not find that principal"
+msgstr "找不到該單位"
+
+#: NOT FOUND IN SOURCE
+msgid "Could not find user %1."
+msgstr "找不到使用者 %1。"
+
+#: html/Admin/Groups/Members.html:87 html/Edit/Users/index.html:83 html/User/Groups/Members.html:89 html/User/Groups/Modify.html:81
+#. ( . $GroupId)
+msgid "Could not load group"
+msgstr "無法載入群組"
+
+#: lib/RT/Queue_Overlay.pm:641
+#. ($args{'Type'})
+msgid "Could not make that principal a %1 for this queue"
+msgstr "無法將該單位設為此表單的 %1。"
+
+#: lib/RT/Ticket_Overlay.pm:1442
+#. ($self->loc($args{'Type'}))
+msgid "Could not make that principal a %1 for this ticket"
+msgstr "無法將該單位設為此申請單的 %1。"
+
+#: lib/RT/Queue_Overlay.pm:740
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this queue"
+msgstr "無法將單位 %1 從表單移除。"
+
+#: lib/RT/Ticket_Overlay.pm:1558
+#. ($args{'Type'})
+msgid "Could not remove that principal as a %1 for this ticket"
+msgstr "無法將單位 %1 從申請單移除。"
+
+#: lib/RT/Group_Overlay.pm:984
+msgid "Couldn't add member to group"
+msgstr "無法新增成員至群組"
+
+#: lib/RT/Ticket_Overlay.pm:3562 lib/RT/Ticket_Overlay.pm:3618
+#. ($Msg)
+msgid "Couldn't create a transaction: %1"
+msgstr "無法新增更動報告"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't figure out what to do from gpg's reply\\n"
+msgstr "無法從 gpg 回函辨識出該採取的行動\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find group\\n"
+msgstr "找不到群組\\n"
+
+#: lib/RT/Interface/Web.pm:902 x:905
+msgid "Couldn't find row"
+msgstr "找不到此列資料"
+
+#: lib/RT/Group_Overlay.pm:958
+msgid "Couldn't find that principal"
+msgstr "找不到該單位"
+
+#: lib/RT/CustomField_Overlay.pm:239
+msgid "Couldn't find that value"
+msgstr "找不到該值"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find that watcher"
+msgstr "找不到該視察員"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't find user\\n"
+msgstr "找不到使用者\\n"
+
+#: lib/RT/CurrentUser.pm:111
+#. ($self->Id)
+msgid "Couldn't load %1 from the users database.\\n"
+msgstr "無法從使用者資料庫載入 %1。\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load KeywordSelects."
+msgstr "無法載入 KeywordSelects。"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load RT config file '%1' %2"
+msgstr "無法載入 RT 設定檔 '%1' %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load Scrips."
+msgstr "無法載入手續。"
+
+#: html/Admin/Groups/GroupRights.html:87 html/Admin/Groups/UserRights.html:74 html/Edit/Global/GroupRight/Add.html:54 html/Edit/Global/UserRight/Add.html:23 html/Edit/Groups/Member:121 html/Edit/Groups/Members/Add.html:44 html/Edit/Rights/index.html:57
+#. ($Group)
+#. ($ObjectGroup)
+#. ($id)
+msgid "Couldn't load group %1"
+msgstr "無法載入手續 %1"
+
+#: lib/RT/Link_Overlay.pm:174 lib/RT/Link_Overlay.pm:183 lib/RT/Link_Overlay.pm:210
+msgid "Couldn't load link"
+msgstr "無法載入鏈結。"
+
+#: html/Admin/Elements/EditCustomFields:146 html/Admin/Queues/People.html:120
+#. ($id)
+msgid "Couldn't load queue"
+msgstr "無法載入表單"
+
+#: html/Admin/Queues/GroupRights.html:100 html/Admin/Queues/UserRights.html:71 html/Edit/Global/GroupRight/Add.html:50 html/Edit/Global/GroupRight/index.html:81 html/Edit/Global/UserRight/Add.html:19 html/Edit/Global/UserRight/index.html:83 html/Edit/Rights/index.html:53
+#. ($Queue)
+#. ($id)
+msgid "Couldn't load queue %1"
+msgstr "無法載入表單 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load scrip"
+msgstr "無法載入手續"
+
+#: NOT FOUND IN SOURCE
+msgid "Couldn't load template"
+msgstr "無法載入範本"
+
+#: html/Admin/Users/Prefs.html:78
+#. ($id)
+msgid "Couldn't load that user (%1)"
+msgstr "無法載入該名使用者(%1)"
+
+#: html/SelfService/Display.html:108
+#. ($id)
+msgid "Couldn't load ticket '%1'"
+msgstr "無法載入申請單 '%1'"
+
+#: html/Admin/Elements/ModifyUser:85 html/Admin/Users/Modify.html:148 html/User/Prefs.html:97 html/Work/Preferences/Info:87
+msgid "Country"
+msgstr "國家"
+
+#: html/Admin/Elements/CreateUserCalled:25 html/Edit/Elements/PopHeader:29 html/Edit/Global/GroupRight/Add.html:18 html/Ticket/Create.html:134 html/Ticket/Create.html:194
+msgid "Create"
+msgstr "新增"
+
+#: html/Edit/Groups/MemberGroups/Add.html:17
+msgid "Create Subgroup:"
+msgstr "新增子群組:"
+
+#: etc/initialdata.zh:145 etc/initialdata:127
+msgid "Create Tickets"
+msgstr "新增申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "Create User:"
+msgstr "新增成員:"
+
+#: html/Admin/Elements/EditCustomField:74
+msgid "Create a CustomField"
+msgstr "新增自訂欄位"
+
+#: html/Admin/Queues/CustomField.html:47
+#. ($QueueObj->Name())
+msgid "Create a CustomField for queue %1"
+msgstr "為 %1 表單新增自訂欄位"
+
+#: html/Admin/Global/CustomField.html:47
+msgid "Create a CustomField which applies to all queues"
+msgstr "為 %1 表單新增自訂欄位"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new Custom Field"
+msgstr "新增自訂欄位"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global Scrip"
+msgstr "新增全域手續"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new global scrip"
+msgstr "新增全域手續"
+
+#: html/Admin/Groups/Modify.html:66 html/Admin/Groups/Modify.html:92
+msgid "Create a new group"
+msgstr "新增群組"
+
+#: html/User/Groups/Modify.html:66 html/User/Groups/Modify.html:91
+msgid "Create a new personal group"
+msgstr "新增代理人群組"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new queue"
+msgstr "新增表單"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new scrip"
+msgstr "新增手續"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new template"
+msgstr "新增範本"
+
+#: html/Ticket/Create.html:24 html/Ticket/Create.html:27 html/Ticket/Create.html:35
+msgid "Create a new ticket"
+msgstr "新增申請單"
+
+#: html/Admin/Users/Modify.html:213 html/Admin/Users/Modify.html:240
+msgid "Create a new user"
+msgstr "新增使用者"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a new workflow"
+msgstr "新增流程"
+
+#: html/Admin/Queues/Modify.html:103
+msgid "Create a queue"
+msgstr "新增表單"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a queue called"
+msgstr "新增表單名稱"
+
+#: NOT FOUND IN SOURCE
+msgid "Create a request"
+msgstr "提出申請"
+
+#: html/Admin/Queues/Scrip.html:58
+#. ($QueueObj->Name)
+msgid "Create a scrip for queue %1"
+msgstr "為 %1 表單新增手續"
+
+#: html/Admin/Global/Template.html:68 html/Admin/Queues/Template.html:64
+msgid "Create a template"
+msgstr "新增範本"
+
+#: html/SelfService/Create.html:24
+msgid "Create a ticket"
+msgstr "提出申請單"
+
+#: html/Admin/Elements/ModifyWorkflow:206 html/Admin/Global/Workflow.html:69 html/Admin/Queues/Workflow.html:64
+msgid "Create a workflow"
+msgstr "新增流程"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1 / %2 / %3 "
+msgstr "新增失敗:%1 / %2 / %3"
+
+#: NOT FOUND IN SOURCE
+msgid "Create failed: %1/%2/%3"
+msgstr "新增失敗:%1/%2/%3"
+
+#: NOT FOUND IN SOURCE
+msgid "Create new item"
+msgstr "建立新項目"
+
+#: etc/initialdata.zh:147 etc/initialdata:129
+msgid "Create new tickets based on this scrip's template"
+msgstr "依據此項手續內的模版,新增申請單"
+
+#: html/SelfService/Create.html:77
+msgid "Create ticket"
+msgstr "新增申請單"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "Create tickets in this queue"
+msgstr "在此表單中新增申請單"
+
+#: lib/RT/Queue_Overlay.pm:71
+msgid "Create, delete and modify custom fields"
+msgstr "新增、刪除及更改自訂欄位"
+
+#: lib/RT/Queue_Overlay.pm:67
+msgid "Create, delete and modify queues"
+msgstr "新增、刪除及更改表單"
+
+#: NOT FOUND IN SOURCE
+msgid "Create, delete and modify the members of any user's personal groups"
+msgstr "新增、刪除及更改任何使用者的代理人群組"
+
+#: lib/RT/System.pm:58
+msgid "Create, delete and modify the members of personal groups"
+msgstr "新增、刪除及更改代理人群組"
+
+#: lib/RT/System.pm:59
+msgid "Create, delete and modify users"
+msgstr "新增、刪除及更改使用者"
+
+#: lib/RT/Queue_Overlay.pm:83
+msgid "CreateTicket"
+msgstr "新增申請單"
+
+#: html/Elements/SelectDateType:25 html/Ticket/Elements/ShowDates:26 lib/RT/Ticket_Overlay.pm:1185
+msgid "Created"
+msgstr "新增日"
+
+#: html/Admin/Elements/EditCustomField:87
+#. ($CustomFieldObj->Name())
+msgid "Created CustomField %1"
+msgstr "自訂欄位 %1 新增成功"
+
+#: NOT FOUND IN SOURCE
+msgid "Created template %1"
+msgstr "範本 %1 新增成功"
+
+#: html/Admin/Elements/ModifyWorkflow:221
+#. (loc( $WorkflowObj->Name() ))
+msgid "Created workflow %1"
+msgstr "流程 %1 新增成功"
+
+#: NOT FOUND IN SOURCE
+msgid "Currency"
+msgstr "幣別"
+
+#: NOT FOUND IN SOURCE
+msgid "Current Approval Info"
+msgstr "截至目前簽核資訊"
+
+#: NOT FOUND IN SOURCE
+msgid "Current Custom Fields"
+msgstr "現有自訂欄位"
+
+#: html/Edit/Groups/MemberGroups/Add.html:14
+msgid "Current Groups:"
+msgstr "現有群組列表:"
+
+#: html/Ticket/Elements/EditLinks:27
+msgid "Current Relationships"
+msgstr "現有關係"
+
+#: html/Edit/Rights/index.html:19
+msgid "Current Rights:"
+msgstr "現有權限:"
+
+#: html/Admin/Elements/EditScrips:29
+msgid "Current Scrips"
+msgstr "現有手續"
+
+#: html/Work/Tickets/Create.html:50 html/Work/Tickets/Elements/ShowBasics:47
+msgid "Current Status"
+msgstr "目前狀態"
+
+#: NOT FOUND IN SOURCE
+msgid "Current Templates"
+msgstr "現有範本"
+
+#: html/Admin/Groups/Members.html:38 html/User/Groups/Members.html:41
+msgid "Current members"
+msgstr "現有成員"
+
+#: html/Admin/Elements/SelectRights:28
+msgid "Current rights"
+msgstr "現有權限"
+
+#: html/Search/Listing.html:70 html/Work/Search/index.html:42
+msgid "Current search criteria"
+msgstr "現有查詢條件"
+
+#: html/Admin/Queues/People.html:40 html/Ticket/Elements/EditPeople:44
+msgid "Current watchers"
+msgstr "現有視察員"
+
+#: html/Admin/Global/CustomField.html:54
+#. ($CustomField)
+msgid "Custom Field #%1"
+msgstr "自訂欄位 #%1"
+
+#: html/Admin/Elements/QueueTabs:52 html/Admin/Elements/SystemTabs:39 html/Admin/Global/index.html:49 html/Edit/Global/autohandler:7 html/Edit/Queues/autohandler:18 html/Ticket/Elements/ShowSummary:35
+msgid "Custom Fields"
+msgstr "自訂欄位"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom Fields which apply to all queues"
+msgstr "適用於所有表單的自訂欄位"
+
+#: html/Admin/Elements/EditScrip:72 html/Edit/Global/Scrip/Top:69
+msgid "Custom action cleanup code"
+msgstr "動作後執行程式"
+
+#: html/Admin/Elements/EditScrip:64 html/Edit/Global/Scrip/Top:62
+msgid "Custom action preparation code"
+msgstr "動作前執行程式"
+
+#: html/Admin/Elements/EditScrip:48 html/Edit/Global/Scrip/Top:35 html/Edit/Global/Scrip/Top:61
+msgid "Custom condition"
+msgstr "自訂條件"
+
+#: lib/RT/Tickets_Overlay.pm:1618
+#. ($CF->Name , $args{OPERATOR} , $args{VALUE})
+msgid "Custom field %1 %2 %3"
+msgstr "自訂欄位 %1 %2 %3"
+
+#: lib/RT/Tickets_Overlay.pm:1613
+#. ($CF->Name)
+msgid "Custom field %1 has a value."
+msgstr "自訂欄位 %1 已有值"
+
+#: lib/RT/Tickets_Overlay.pm:1610
+#. ($CF->Name)
+msgid "Custom field %1 has no value."
+msgstr "自訂欄位 %1 沒有值"
+
+#: lib/RT/Ticket_Overlay.pm:3454
+#. ($args{'Field'})
+msgid "Custom field %1 not found"
+msgstr "找不到自訂欄位 %1"
+
+#: html/Admin/Elements/EditCustomFields:196
+msgid "Custom field deleted"
+msgstr "自訂欄位已刪除"
+
+#: lib/RT/Ticket_Overlay.pm:3604
+msgid "Custom field not found"
+msgstr "找不到自訂欄位"
+
+#: lib/RT/CustomField_Overlay.pm:349
+#. ($args{'Content'}, $self->Name)
+msgid "Custom field value %1 could not be found for custom field %2"
+msgstr "無法從自訂欄位 %2 中找到 %1 這個欄位值"
+
+#: NOT FOUND IN SOURCE
+msgid "Custom field value changed from %1 to %2"
+msgstr "自訂欄位值從 %1 改為 %2"
+
+#: lib/RT/CustomField_Overlay.pm:249
+msgid "Custom field value could not be deleted"
+msgstr "無法刪除自訂欄位值"
+
+#: lib/RT/CustomField_Overlay.pm:355
+msgid "Custom field value could not be found"
+msgstr "找不到自訂欄位值"
+
+#: lib/RT/CustomField_Overlay.pm:247 lib/RT/CustomField_Overlay.pm:357
+msgid "Custom field value deleted"
+msgstr "自訂欄位值刪除成功"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:145 html/Edit/Global/Workflow/Owner.html:90 lib/RT/Transaction_Overlay.pm:548
+msgid "CustomField"
+msgstr "自訂欄位"
+
+#: NOT FOUND IN SOURCE
+msgid "Data error"
+msgstr "資料錯誤"
+
+#: NOT FOUND IN SOURCE
+msgid "Date of Departure"
+msgstr "出發日期"
+
+#: html/SelfService/Display.html:38 html/Ticket/Create.html:160 html/Ticket/Elements/ShowSummary:54 html/Ticket/Elements/Tabs:92 html/Ticket/ModifyAll.html:43 html/Work/Tickets/Elements/ShowTransaction:14
+msgid "Dates"
+msgstr "日期"
+
+#: NOT FOUND IN SOURCE
+msgid "Dec"
+msgstr "十二月"
+
+#: lib/RT/Date.pm:422
+msgid "Dec."
+msgstr "12"
+
+#: NOT FOUND IN SOURCE
+msgid "December"
+msgstr "十二月"
+
+#: NOT FOUND IN SOURCE
+msgid "Default Autoresponse Template"
+msgstr "預設自動回應範本"
+
+#: etc/initialdata.zh:225 etc/initialdata:207
+msgid "Default Autoresponse template"
+msgstr "預設自動回應範本"
+
+#: etc/initialdata.zh:304 etc/initialdata:281
+msgid "Default admin comment template"
+msgstr "預設管理員評論範本"
+
+#: etc/initialdata.zh:262 etc/initialdata:260
+msgid "Default admin correspondence template"
+msgstr "預設管理員回覆範本"
+
+#: etc/initialdata.zh:283 etc/initialdata:272
+msgid "Default correspondence template"
+msgstr "預設回覆範本"
+
+#: etc/initialdata.zh:240 etc/initialdata:238
+msgid "Default transaction template"
+msgstr "預設更動範本"
+
+#: lib/RT/Transaction_Overlay.pm:643
+#. ($type, $self->Field, $self->OldValue, $self->NewValue)
+msgid "Default: %1/%2 changed from %3 to %4"
+msgstr "預設:%1/%2 已自 %3 改為 %4"
+
+#: html/User/Delegation.html:24 html/User/Delegation.html:27
+msgid "Delegate rights"
+msgstr "代表團權限"
+
+#: lib/RT/System.pm:62
+msgid "Delegate specific rights which have been granted to you."
+msgstr "將擁有的權限委託他人代理"
+
+#: lib/RT/System.pm:62
+msgid "DelegateRights"
+msgstr "設定代理人"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegated Approval"
+msgstr "代理簽核"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegated Queue"
+msgstr "代理表單名稱"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegated Queue:"
+msgstr "代理表單:"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegated Type"
+msgstr "代理表單種類"
+
+#: html/Edit/Users/index.html:125 html/Work/Delegates/Info:31 html/Work/Delegates/List:8 html/Work/Elements/Tab:41 html/Work/Overview/Info:28
+msgid "Delegates"
+msgstr "代理人"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegates Enabled Status"
+msgstr "代理啟動狀態"
+
+#: html/Work/Delegates/Info:18 html/Work/Overview/Info:18
+msgid "Delegates Info"
+msgstr "代理人資訊"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegates Period"
+msgstr "代理期間"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegates Permission Setting"
+msgstr "代理權限設定"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegates Permission:"
+msgstr "代理權限:"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegates Setting"
+msgstr "代理人設定"
+
+#: html/Work/Delegates/Info:46 html/Work/Delegates/List:11 html/Work/Overview/Info:39
+msgid "Delegates Status"
+msgstr "代理狀態"
+
+#: html/User/Elements/Tabs:37
+msgid "Delegation"
+msgstr "代理人權限"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegation Groups"
+msgstr "代理人群組"
+
+#: NOT FOUND IN SOURCE
+msgid "Delegation Rights"
+msgstr "代理人權限"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:113 html/Edit/Elements/104Buttons:73 html/Work/Search/index.html:48 html/Work/Search/index.html:48
+msgid "Delete"
+msgstr "刪除"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "Delete tickets"
+msgstr "刪除申請單"
+
+#: lib/RT/Queue_Overlay.pm:88
+msgid "DeleteTicket"
+msgstr "刪除申請單"
+
+#: lib/RT/Transaction_Overlay.pm:187
+msgid "Deleting this object could break referential integrity"
+msgstr "刪除此物件可能破壞參考完整性"
+
+#: lib/RT/Queue_Overlay.pm:293
+msgid "Deleting this object would break referential integrity"
+msgstr "刪除此物件可能破壞參考完整性"
+
+#: lib/RT/User_Overlay.pm:499
+msgid "Deleting this object would violate referential integrity"
+msgstr "刪除此物件會違反參考完整性"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity."
+msgstr "刪除此物件會違反參考完整性"
+
+#: NOT FOUND IN SOURCE
+msgid "Deleting this object would violate referential integrity. That's bad."
+msgstr "刪除此物件會違反參考完整性"
+
+#: html/Approvals/Elements/Approve:44 html/Work/Approvals/Elements/Approve:32
+msgid "Deny"
+msgstr "駁回"
+
+#: NOT FOUND IN SOURCE
+msgid "Department"
+msgstr "部門"
+
+#: html/Edit/Global/UserRight/List:12 html/Edit/Global/UserRight/Top:13 html/Edit/Users/List:10 html/Edit/Users/Top:12
+msgid "Department ID"
+msgstr "部門代碼"
+
+#: html/Edit/Global/UserRight/List:11 html/Edit/Global/UserRight/Top:49 html/Edit/Users/List:9 html/Edit/Users/Top:48 html/Work/Delegates/Info:78 html/Work/Overview/Info:60
+msgid "Department Name"
+msgstr "部門名稱"
+
+#: NOT FOUND IN SOURCE
+msgid "Department's"
+msgstr "部門之"
+
+#: NOT FOUND IN SOURCE
+msgid "Departure Details"
+msgstr "差旅明細"
+
+#: NOT FOUND IN SOURCE
+msgid "Departure From"
+msgstr "差旅起始日"
+
+#: NOT FOUND IN SOURCE
+msgid "Departure Request"
+msgstr "請假單"
+
+#: NOT FOUND IN SOURCE
+msgid "Departure Until"
+msgstr "差旅截止日"
+
+#: html/Ticket/Create.html:180 html/Ticket/Elements/BulkLinks:34 html/Ticket/Elements/EditLinks:122 html/Ticket/Elements/EditLinks:46 html/Ticket/Elements/ShowDependencies:31 html/Ticket/Elements/ShowLinks:36 html/Work/Search/BulkLinks:10
+msgid "Depended on by"
+msgstr "可接續處理的申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "Dependencies: \\n"
+msgstr "附屬性:\\n"
+
+#: html/Elements/SelectLinkType:26 html/Ticket/Create.html:179 html/Ticket/Elements/BulkLinks:30 html/Ticket/Elements/EditLinks:118 html/Ticket/Elements/EditLinks:35 html/Ticket/Elements/ShowDependencies:24 html/Ticket/Elements/ShowLinks:26 html/Work/Search/BulkLinks:6
+msgid "Depends on"
+msgstr "需先處理"
+
+#: NOT FOUND IN SOURCE
+msgid "DependsOn"
+msgstr "需先處理"
+
+#: html/Elements/SelectSortOrder:34
+msgid "Descending"
+msgstr "遞減"
+
+#: html/SelfService/Create.html:72 html/Ticket/Create.html:118
+msgid "Describe the issue below"
+msgstr "在以下欄位描述主題"
+
+#: html/Admin/Elements/AddCustomFieldValue:35 html/Admin/Elements/EditCustomField:38 html/Admin/Elements/EditScrip:33 html/Admin/Elements/ModifyQueue:35 html/Admin/Elements/ModifyTemplate:35 html/Admin/Elements/ModifyTemplateAsWorkflow:192 html/Admin/Groups/Modify.html:48 html/Admin/Queues/Modify.html:47 html/Edit/Global/Workflow/Action:14 html/Elements/SelectGroups:26 html/User/Groups/Modify.html:48 html/Work/Preferences/Info:103
+msgid "Description"
+msgstr "描述"
+
+#: NOT FOUND IN SOURCE
+msgid "Description of Responsibility"
+msgstr "經辦業務說明"
+
+#: NOT FOUND IN SOURCE
+msgid "Description:"
+msgstr "描述:"
+
+#: html/Work/Tickets/Create.html:117 html/Work/Tickets/Create.html:85 html/Work/Tickets/Elements/EditCustomFields:13 html/Work/Tickets/Elements/EditCustomFields:47 html/Work/Tickets/Elements/ShowCustomFields:15 html/Work/Tickets/Elements/ShowCustomFields:50
+msgid "Details"
+msgstr "細節"
+
+#: NOT FOUND IN SOURCE
+msgid "Direct"
+msgstr "直接"
+
+#: html/Edit/Users/Info:31
+msgid "Disability"
+msgstr "殘障身分"
+
+#: html/Edit/Users/Info:29
+msgid "Disability Type"
+msgstr "殘障類別"
+
+#: html/Edit/Global/GroupRight/List:9 html/Edit/Global/GroupRight/Top:16 html/Edit/Groups/List:11 html/Edit/Groups/Top:19 html/Edit/Queues/Basic/Top:70 html/Edit/Queues/List:13 html/Work/Delegates/Info:48 html/Work/Delegates/Info:53 html/Work/Delegates/List:12 html/Work/Overview/Info:42
+msgid "Disabled"
+msgstr "停用"
+
+#: html/Ticket/Elements/Tabs:84
+msgid "Display"
+msgstr "顯示內容"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "Display Access Control List"
+msgstr "顯示權限控制清單"
+
+#: lib/RT/Queue_Overlay.pm:74
+msgid "Display Scrip templates for this queue"
+msgstr "顯示此表單的範本"
+
+#: lib/RT/Queue_Overlay.pm:77
+msgid "Display Scrips for this queue"
+msgstr "顯示此表單的手續"
+
+#: html/Ticket/Elements/ShowHistory:34
+msgid "Display mode"
+msgstr "顯示模式"
+
+#: NOT FOUND IN SOURCE
+msgid "Display ticket #%1"
+msgstr "顯示第%1號申請單"
+
+#: lib/RT/System.pm:53
+msgid "Do anything and everything"
+msgstr "允許一切操作"
+
+#: html/Elements/Refresh:29
+msgid "Don't refresh this page."
+msgstr "不更新此頁面。"
+
+#: html/Search/Elements/PickRestriction:113 html/Work/Search/PickRestriction:95
+msgid "Don't show search results"
+msgstr "不顯示查詢結果"
+
+#: html/Edit/Elements/Page:19 html/Edit/Elements/Page:21
+msgid "Down"
+msgstr "下一頁"
+
+#: html/Ticket/Elements/ShowTransaction:92
+msgid "Download"
+msgstr "下載"
+
+#: NOT FOUND IN SOURCE
+msgid "Dr."
+msgstr "博士"
+
+#: html/Elements/SelectDateType:31 html/Ticket/Create.html:166 html/Ticket/Elements/EditDates:44 html/Ticket/Elements/ShowDates:42 lib/RT/Ticket_Overlay.pm:1189
+msgid "Due"
+msgstr "到期日"
+
+#: NOT FOUND IN SOURCE
+msgid "Due Date"
+msgstr "截止日"
+
+#: NOT FOUND IN SOURCE
+msgid "Due date '%1' could not be parsed"
+msgstr "無法解讀日期 '%1'"
+
+#: bin/rt-commit-handler:753
+#. ($1, $msg)
+msgid "ERROR: Couldn't load ticket '%1': %2.\\n"
+msgstr "無法載入申請單 '%1':%2.\\n"
+
+#: html/Work/Tickets/Update.html:46
+msgid "Edit"
+msgstr "編輯"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:132
+msgid "Edit Conditions"
+msgstr "編輯前置條件"
+
+#: html/Admin/Queues/CustomFields.html:44
+#. ($Queue->Name)
+msgid "Edit Custom Fields for %1"
+msgstr "編輯 %1 的自訂欄位"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit Custom Fields for queue %1"
+msgstr "編輯表單 %1 的自訂欄位"
+
+#: html/Search/Bulk.html:143 html/Ticket/ModifyLinks.html:35 html/Work/Search/Bulk.html:93
+msgid "Edit Relationships"
+msgstr "編輯申請單關係"
+
+#: html/Edit/Groups/MemberGroups/Add.html:3 html/Edit/Groups/MemberGroups/index.html:22
+msgid "Edit Subgroups"
+msgstr "新增/維護子群組"
+
+#: html/Admin/Queues/Templates.html:41
+#. ($QueueObj->Name)
+msgid "Edit Templates for queue %1"
+msgstr "編輯表單 %1 的範本"
+
+#: html/Admin/Queues/Workflows.html:42
+#. ($QueueObj->Name)
+msgid "Edit Workflows for queue %1"
+msgstr "編輯表單 %1 的流程"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit keywords"
+msgstr "編輯關鍵字"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit scrips"
+msgstr "編輯手續"
+
+#: html/Admin/Global/index.html:45
+msgid "Edit system templates"
+msgstr "編輯全域範本"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit system workflows"
+msgstr "編輯全域流程"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit templates for %1"
+msgstr "編輯 %1 的範本"
+
+#: NOT FOUND IN SOURCE
+msgid "Edit workflows for %1"
+msgstr "編輯 %1 的流程"
+
+#: html/Admin/Elements/ModifyQueue:24 html/Admin/Queues/Modify.html:118
+#. ($QueueObj->Name)
+#. ($QueueObj->Id)
+msgid "Editing Configuration for queue %1"
+msgstr "編輯表單 %1 的設定"
+
+#: html/Admin/Elements/ModifyUser:24
+#. ($UserObj->Name)
+msgid "Editing Configuration for user %1"
+msgstr "編輯使用者 %1 的設定"
+
+#: html/Admin/Elements/EditCustomField:90
+#. ($CustomFieldObj->Name())
+msgid "Editing CustomField %1"
+msgstr "編輯自訂欄位 %1"
+
+#: html/Admin/Groups/Members.html:31
+#. ($Group->Name)
+msgid "Editing membership for group %1"
+msgstr "編輯群組 %1 的成員資訊"
+
+#: html/User/Groups/Members.html:128
+#. ($Group->Name)
+msgid "Editing membership for personal group %1"
+msgstr "編輯代理人群組 %1 的成員資訊"
+
+#: NOT FOUND IN SOURCE
+msgid "Editing template %1"
+msgstr "編輯範本 %1"
+
+#: html/Admin/Elements/ModifyWorkflow:238
+#. (loc( $WorkflowObj->Name() ))
+msgid "Editing workflow %1"
+msgstr "編輯流程 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Education"
+msgstr "最高學歷"
+
+#: NOT FOUND IN SOURCE
+msgid "EffectiveId"
+msgstr "有效編號"
+
+#: lib/RT/Ticket_Overlay.pm:2635 lib/RT/Ticket_Overlay.pm:2703
+msgid "Either base or target must be specified"
+msgstr "需要指定起始申請單或目的申請單"
+
+#: html/Admin/Users/Modify.html:52 html/Admin/Users/Prefs.html:45 html/Elements/SelectUsers:26 html/Ticket/Elements/AddWatchers:55 html/User/Prefs.html:41 html/Work/Delegates/Info:96 html/Work/Overview/Info:78 html/Work/Preferences/Info:16
+msgid "Email"
+msgstr "電子郵件信箱"
+
+#: lib/RT/User_Overlay.pm:247
+msgid "Email address in use"
+msgstr "此電子郵件信箱已被使用"
+
+#: html/Admin/Elements/ModifyUser:41
+msgid "EmailAddress"
+msgstr "電子郵件信箱位址"
+
+#: html/Admin/Elements/ModifyUser:53
+msgid "EmailEncoding"
+msgstr "電子郵件文字編碼方式"
+
+#: NOT FOUND IN SOURCE
+msgid "Embark Date"
+msgstr "外籍員工入境日"
+
+#: NOT FOUND IN SOURCE
+msgid "Embarked Date"
+msgstr "抵達日期"
+
+#: NOT FOUND IN SOURCE
+msgid "Embarked Location"
+msgstr "抵達地點"
+
+#: NOT FOUND IN SOURCE
+msgid "Enable Delegates"
+msgstr "代理啟動"
+
+#: html/Admin/Elements/EditCustomField:50
+msgid "Enabled (Unchecking this box disables this custom field)"
+msgstr "啟用(取消勾選將停用此自訂欄位)"
+
+#: html/Admin/Groups/Modify.html:52 html/User/Groups/Modify.html:52
+msgid "Enabled (Unchecking this box disables this group)"
+msgstr "啟用(取消勾選將停用此群組)"
+
+#: html/Admin/Queues/Modify.html:83
+msgid "Enabled (Unchecking this box disables this queue)"
+msgstr "啟用(取消勾選將停用此表單)"
+
+#: html/Admin/Elements/EditCustomFields:98
+msgid "Enabled Custom Fields"
+msgstr "已啟用的自訂欄位"
+
+#: html/Edit/Queues/Basic/Top:75 html/Edit/Queues/List:15
+msgid "Enabled Date"
+msgstr "啟用日期"
+
+#: NOT FOUND IN SOURCE
+msgid "Enabled Date:"
+msgstr "啟動日期:"
+
+#: html/Admin/Queues/index.html:55
+msgid "Enabled Queues"
+msgstr "已啟用的表單"
+
+#: html/Edit/Queues/Basic/Top:66 html/Edit/Queues/List:11
+msgid "Enabled Status"
+msgstr "啟用狀態"
+
+#: html/Admin/Elements/EditCustomField:106 html/Admin/Groups/Modify.html:116 html/Admin/Queues/Modify.html:140 html/Admin/Users/Modify.html:282 html/User/Groups/Modify.html:116
+#. (loc_fuzzy($msg))
+msgid "Enabled status %1"
+msgstr "啟用狀態 %1"
+
+#: html/Edit/Users/Info:34
+msgid "End of Trial"
+msgstr "試用期滿日"
+
+#: NOT FOUND IN SOURCE
+msgid "English Name"
+msgstr "英文姓名"
+
+#: lib/RT/CustomField_Overlay.pm:427
+msgid "Enter multiple values"
+msgstr "鍵入多重項目"
+
+#: html/Edit/Users/Search.html:15
+msgid "Enter one or more conditions below to search for users"
+msgstr "輸入下列單一或複式條件,查詢用戶資料"
+
+#: lib/RT/CustomField_Overlay.pm:424
+msgid "Enter one value"
+msgstr "鍵入單一項目"
+
+#: html/Search/Bulk.html:144 html/Ticket/Elements/EditLinks:111 html/Work/Search/Bulk.html:95
+msgid "Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces."
+msgstr "輸入申請單可鏈結到的申請單編號或網址。以空白隔開。"
+
+#: lib/RT/CustomField_Vendor.pm:20
+msgid "EntryBoolean"
+msgstr "是非填表"
+
+#: lib/RT/CustomField_Vendor.pm:17
+msgid "EntryDate"
+msgstr "日期填表"
+
+#: NOT FOUND IN SOURCE
+msgid "EntryExternal"
+msgstr "系統填表"
+
+#: lib/RT/CustomField_Vendor.pm:16
+msgid "EntryFreeform"
+msgstr "輸入填表"
+
+#: NOT FOUND IN SOURCE
+msgid "EntryMultiple"
+msgstr "多選填表"
+
+#: lib/RT/CustomField_Vendor.pm:19
+msgid "EntryNumber"
+msgstr "數值填表"
+
+#: lib/RT/CustomField_Vendor.pm:15
+msgid "EntrySelect"
+msgstr "單選填表"
+
+#: lib/RT/CustomField_Vendor.pm:18
+msgid "EntryTime"
+msgstr "時間填表"
+
+#: html/Elements/Login:39 html/SelfService/Error.html:24 html/SelfService/Error.html:25
+msgid "Error"
+msgstr "錯誤"
+
+#: NOT FOUND IN SOURCE
+msgid "Error adding watcher"
+msgstr "新增視察員失敗"
+
+#: lib/RT/Queue_Overlay.pm:555
+msgid "Error in parameters to Queue->AddWatcher"
+msgstr "表單->新增視察員的參數有誤"
+
+#: lib/RT/Queue_Overlay.pm:713
+msgid "Error in parameters to Queue->DelWatcher"
+msgstr "表單->刪除視察員的參數有誤"
+
+#: lib/RT/Ticket_Overlay.pm:1374
+msgid "Error in parameters to Ticket->AddWatcher"
+msgstr "申請單->新增視察員的參數有誤"
+
+#: lib/RT/Ticket_Overlay.pm:1531
+msgid "Error in parameters to Ticket->DelWatcher"
+msgstr "申請單->刪除視察員的參數有誤"
+
+#: etc/initialdata.zh:38 etc/initialdata:20
+msgid "Everyone"
+msgstr "所有人"
+
+#: bin/rt-crontool:193
+msgid "Example:"
+msgstr "範例:"
+
+#: html/Edit/Elements/104Buttons:77
+msgid "Export"
+msgstr "匯出"
+
+#: html/Admin/Elements/ModifyUser:63
+msgid "ExternalAuthId"
+msgstr "外部認證帳號"
+
+#: html/Admin/Elements/ModifyUser:57
+msgid "ExternalContactInfoId"
+msgstr "外部聯絡方式帳號"
+
+#: html/Edit/Global/Basic/Top:64
+msgid "ExternalDatabaseDSN"
+msgstr "外部資料庫連結字串"
+
+#: html/Edit/Global/Basic/Top:68
+msgid "ExternalDatabasePass"
+msgstr "外部資料庫密碼"
+
+#: html/Edit/Global/Basic/Top:66
+msgid "ExternalDatabaseUser"
+msgstr "外部資料庫用戶"
+
+#: html/Edit/Global/Basic/Top:62
+msgid "ExternalURL"
+msgstr "外部介面網址"
+
+#: html/Admin/Users/Modify.html:72
+msgid "Extra info"
+msgstr "備註"
+
+#: lib/RT/User_Overlay.pm:363
+msgid "Failed to find 'Privileged' users pseudogroup."
+msgstr "找不到「內部成員」虛擬群組的使用者。"
+
+#: lib/RT/User_Overlay.pm:370
+msgid "Failed to find 'Unprivileged' users pseudogroup"
+msgstr "找不到「非內部成員」虛擬群組的使用者。"
+
+#: bin/rt-crontool:137
+#. ($modname, $@)
+msgid "Failed to load module %1. (%2)"
+msgstr "無法載入模組 %1. (%2)"
+
+#: NOT FOUND IN SOURCE
+msgid "Feb"
+msgstr "二月"
+
+#: lib/RT/Date.pm:412
+msgid "Feb."
+msgstr "02"
+
+#: NOT FOUND IN SOURCE
+msgid "February"
+msgstr "二月"
+
+#: NOT FOUND IN SOURCE
+msgid "Female"
+msgstr "女"
+
+#: html/Edit/Global/CustomField/List:5 html/Edit/Global/CustomField/Top:9
+msgid "Field Attribute"
+msgstr "欄位屬性"
+
+#: html/Edit/Global/CustomField/Info:14
+msgid "Field Content:"
+msgstr "欄位內容:"
+
+#: html/Edit/Global/CustomField/List:7 html/Edit/Global/CustomField/Top:21
+msgid "Field Description"
+msgstr "欄位描述"
+
+#: html/Edit/Global/CustomField/List:6 html/Edit/Global/CustomField/Top:15
+msgid "Field Name"
+msgstr "欄位名稱"
+
+#: html/Edit/Elements/PickUsers:52 html/Edit/Users/Add.html:47
+msgid "Filter"
+msgstr "篩選"
+
+#: html/Edit/Elements/PickUsers:6 html/Edit/Users/Add.html:7 html/Work/Tickets/Cc:4
+msgid "Filter people"
+msgstr "對象篩選"
+
+#: html/Edit/Elements/PickUsers:68 html/Edit/Users/Add.html:63 html/Work/Tickets/Cc:42
+msgid "Filtered list:"
+msgstr "篩選列表:"
+
+#: NOT FOUND IN SOURCE
+msgid "Fin"
+msgstr "最終"
+
+#: html/Ticket/Create.html:154 html/Ticket/Elements/EditBasics:58 lib/RT/Tickets_Overlay.pm:1091
+msgid "Final Priority"
+msgstr "最低順位"
+
+#: lib/RT/Ticket_Overlay.pm:1180
+msgid "FinalPriority"
+msgstr "最低順位"
+
+#: NOT FOUND IN SOURCE
+msgid "Financial Department:"
+msgstr "財務部:"
+
+#: html/Admin/Queues/People.html:60 html/Ticket/Elements/EditPeople:33
+msgid "Find group whose"
+msgstr "尋找群組的"
+
+#: NOT FOUND IN SOURCE
+msgid "Find new/open tickets"
+msgstr "尋找/開啟申請單"
+
+#: html/Admin/Queues/People.html:56 html/Admin/Users/index.html:45 html/Ticket/Elements/EditPeople:29
+msgid "Find people whose"
+msgstr "尋找人員的"
+
+#: html/Search/Listing.html:107 html/Work/Search/index.html:88
+msgid "Find tickets"
+msgstr "尋找申請單"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:118
+msgid "Finish Approval"
+msgstr "簽核完畢"
+
+#: html/Ticket/Elements/Tabs:57
+msgid "First"
+msgstr "第一項"
+
+#: html/Search/Listing.html:40 html/Work/Search/index.html:17
+msgid "First page"
+msgstr "第一頁"
+
+#: html/Edit/Global/Workflow/Owner.html:30
+msgid "First-"
+msgstr "一"
+
+#: NOT FOUND IN SOURCE
+msgid "First-level Admins"
+msgstr "一階主管"
+
+#: html/Edit/Users/Info:39
+msgid "First-level Users"
+msgstr "一階主管員工"
+
+#: NOT FOUND IN SOURCE
+msgid "Fixed shift"
+msgstr "固定班"
+
+#: docs/design_docs/string-extraction-guide.txt:33
+msgid "Foo Bar Baz"
+msgstr "甲 乙 丙"
+
+#: docs/design_docs/string-extraction-guide.txt:24
+msgid "Foo!"
+msgstr "甲!"
+
+#: html/Search/Bulk.html:86 html/Work/Search/Bulk.html:55
+msgid "Force change"
+msgstr "強制更新"
+
+#: html/Work/Elements/104Header:89
+msgid "Form Processing"
+msgstr "電子表單作業區"
+
+#: html/Search/Listing.html:105 html/Work/Search/index.html:86
+#. ($ticketcount)
+msgid "Found %quant(%1,ticket)"
+msgstr "找到 %1 張申請單"
+
+#: lib/RT/Interface/Web.pm:904 x:907
+msgid "Found Object"
+msgstr "已找到物件"
+
+#: html/Edit/Global/Workflow/Owner.html:33
+msgid "Fourth-"
+msgstr "四"
+
+#: html/Admin/Elements/ModifyUser:43
+msgid "FreeformContactInfo"
+msgstr "聯絡方式"
+
+#: lib/RT/CustomField_Vendor.pm:11
+msgid "FreeformDate"
+msgstr "日期輸入"
+
+#: NOT FOUND IN SOURCE
+msgid "FreeformExternal"
+msgstr "系統欄位"
+
+#: lib/RT/CustomField_Overlay.pm:37
+msgid "FreeformMultiple"
+msgstr "多重輸入"
+
+#: lib/RT/CustomField_Vendor.pm:13
+msgid "FreeformNumber"
+msgstr "數值輸入"
+
+#: lib/RT/CustomField_Vendor.pm:14
+msgid "FreeformPassword"
+msgstr "密碼輸入"
+
+#: lib/RT/CustomField_Overlay.pm:36
+msgid "FreeformSingle"
+msgstr "單一輸入"
+
+#: lib/RT/CustomField_Vendor.pm:12
+msgid "FreeformTime"
+msgstr "時間輸入"
+
+#: NOT FOUND IN SOURCE
+msgid "Fri"
+msgstr "星期五"
+
+#: lib/RT/Date.pm:392
+msgid "Fri."
+msgstr "星期五"
+
+#: html/Ticket/Elements/ShowHistory:40 html/Ticket/Elements/ShowHistory:50
+msgid "Full headers"
+msgstr "完整標頭檔"
+
+#: NOT FOUND IN SOURCE
+msgid "Gecos"
+msgstr "登入帳號"
+
+#: html/Edit/Users/Info:26
+msgid "Gender"
+msgstr "性別"
+
+#: NOT FOUND IN SOURCE
+msgid "Getting the current user from a pgp sig\\n"
+msgstr "取得目前使用者的 pgp 簽章\\n"
+
+#: lib/RT/Transaction_Overlay.pm:593
+#. ($New->Name)
+msgid "Given to %1"
+msgstr "交予 %1"
+
+#: html/Admin/Elements/Tabs:40 html/Admin/index.html:37
+msgid "Global"
+msgstr "全域設定"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Keyword Selections"
+msgstr "全域關鍵字選取"
+
+#: html/Edit/Users/System:24
+msgid "Global Rights:"
+msgstr "擁有全域權限列表:"
+
+#: NOT FOUND IN SOURCE
+msgid "Global Scrips"
+msgstr "全域手續"
+
+#: html/Edit/Elements/Tab:40
+msgid "Global Setup"
+msgstr "全域設定"
+
+#: html/Admin/Elements/SelectTemplate:37 html/Edit/Elements/SelectTemplate:11
+#. (loc($Template->Name))
+msgid "Global template: %1"
+msgstr "全域範本:%1"
+
+#: html/Admin/Elements/EditCustomFields:74 html/Admin/Queues/People.html:58 html/Admin/Queues/People.html:62 html/Admin/Queues/index.html:43 html/Admin/Users/index.html:48 html/Ticket/Elements/EditPeople:31 html/Ticket/Elements/EditPeople:35 html/index.html:40
+msgid "Go!"
+msgstr "執行"
+
+#: NOT FOUND IN SOURCE
+msgid "Good pgp sig from %1\\n"
+msgstr "%1 的 pgp 簽章是正確的\\n"
+
+#: html/Search/Listing.html:49
+msgid "Goto page"
+msgstr "到頁面"
+
+#: html/Elements/GotoTicket:24 html/SelfService/Elements/GotoTicket:24 html/Work/Elements/104Header:49
+msgid "Goto ticket"
+msgstr "跳到申請單"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:224
+msgid "Grand"
+msgstr "上"
+
+#: html/Ticket/Elements/AddWatchers:45 html/User/Elements/DelegateRights:77
+msgid "Group"
+msgstr "群組"
+
+#: NOT FOUND IN SOURCE
+msgid "Group %1 %2: %3"
+msgstr "群組 %1 %2:%3"
+
+#: html/Edit/Global/GroupRight/List:5 html/Edit/Global/GroupRight/Top:20 html/Edit/Groups/List:7
+msgid "Group Description"
+msgstr "群組描述"
+
+#: NOT FOUND IN SOURCE
+msgid "Group Management"
+msgstr "群組管理"
+
+#: NOT FOUND IN SOURCE
+msgid "Group Members"
+msgstr "群組成員"
+
+#: html/Edit/Elements/PickUsers:28 html/Edit/Global/GroupRight/List:4 html/Edit/Global/GroupRight/Top:10 html/Edit/Groups/List:6 html/Edit/Groups/Top:7 html/Edit/Users/Add.html:29 html/Edit/Users/Group:10 html/Edit/Users/Search.html:43 html/Work/Delegates/Add.html:15 html/Work/Tickets/Cc:24
+msgid "Group Name"
+msgstr "群組名稱"
+
+#: NOT FOUND IN SOURCE
+msgid "Group Name:"
+msgstr "群組名稱:"
+
+#: html/Admin/Elements/GroupTabs:44 html/Admin/Elements/QueueTabs:56 html/Admin/Elements/SystemTabs:43 html/Admin/Global/index.html:54 html/Edit/Global/autohandler:12 html/Edit/Queues/autohandler:23 html/Edit/Users/Group:11 html/Edit/Users/index.html:123
+msgid "Group Rights"
+msgstr "群組權限"
+
+#: NOT FOUND IN SOURCE
+msgid "Group Rights:"
+msgstr "擁有群組權限列表:"
+
+#: html/Edit/Elements/Tab:36
+msgid "Group Setup"
+msgstr "群組設定"
+
+#: html/Edit/Global/GroupRight/List:8 html/Edit/Global/GroupRight/Top:14 html/Edit/Groups/List:10 html/Edit/Groups/Top:15
+msgid "Group Status"
+msgstr "群組狀態"
+
+#: lib/RT/Group_Overlay.pm:964
+msgid "Group already has member"
+msgstr "群組內已有此成員"
+
+#: NOT FOUND IN SOURCE
+msgid "Group could not be created."
+msgstr "無法新增群組"
+
+#: html/Admin/Groups/Modify.html:76
+#. ($create_msg)
+msgid "Group could not be created: %1"
+msgstr "無法新增群組:%1"
+
+#: lib/RT/Group_Overlay.pm:496
+msgid "Group created"
+msgstr "群組新增完畢"
+
+#: lib/RT/Group_Overlay.pm:1132
+msgid "Group has no such member"
+msgstr "群組沒有這個成員"
+
+#: lib/RT/Group_Overlay.pm:944 lib/RT/Queue_Overlay.pm:628 lib/RT/Queue_Overlay.pm:688 lib/RT/Ticket_Overlay.pm:1428 lib/RT/Ticket_Overlay.pm:1506
+msgid "Group not found"
+msgstr "找不到群組"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not found.\\n"
+msgstr "找不到群組。\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group not specified.\\n"
+msgstr "未指定群組。\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Group with Queue Rights"
+msgstr "擁有表單權限群組"
+
+#: html/Edit/Global/Workflow/Owner.html:70
+msgid "Group's"
+msgstr "群組之"
+
+#: NOT FOUND IN SOURCE
+msgid "Group:"
+msgstr "群組:"
+
+#: html/Admin/Elements/SelectNewGroupMembers:34 html/Admin/Elements/Tabs:34 html/Admin/Groups/Members.html:63 html/Admin/Queues/People.html:82 html/Admin/index.html:31 html/Edit/Global/GroupRight/Add.html:15 html/User/Groups/Members.html:66
+msgid "Groups"
+msgstr "群組"
+
+#: lib/RT/Group_Overlay.pm:970
+msgid "Groups can't be members of their members"
+msgstr "不能將群組設為群組內成員"
+
+#: NOT FOUND IN SOURCE
+msgid "Groups with Global Rights"
+msgstr "擁有全域權限群組"
+
+#: html/Edit/Global/GroupRight/List:6 html/Edit/Global/GroupRight/Top:22 html/Edit/Groups/List:8
+msgid "HRMSDefined"
+msgstr "組織架構"
+
+#: NOT FOUND IN SOURCE
+msgid "Health Insurance"
+msgstr "健保補助身份"
+
+#: lib/RT/Interface/CLI.pm:72 lib/RT/Interface/CLI.pm:72
+msgid "Hello!"
+msgstr "嗨!"
+
+#: docs/design_docs/string-extraction-guide.txt:40
+#. ($name)
+msgid "Hello, %1"
+msgstr "嗨,%1"
+
+#: html/Edit/Elements/104Top:28
+msgid "Help"
+msgstr "輔助說明"
+
+#: NOT FOUND IN SOURCE
+msgid "Help Desks"
+msgstr "各項業務窗口"
+
+#: html/Ticket/Elements/ShowHistory:29 html/Ticket/Elements/Tabs:87 html/Work/Tickets/Elements/ShowHistory:8
+msgid "History"
+msgstr "紀錄"
+
+#: html/Admin/Elements/ModifyUser:67
+msgid "HomePhone"
+msgstr "住處電話"
+
+#: html/Edit/Elements/104Top:15 html/Edit/Elements/104Top:24 html/Edit/Elements/EDOMHeader:9 html/Elements/Tabs:43
+msgid "Homepage"
+msgstr "主頁"
+
+#: NOT FOUND IN SOURCE
+msgid "Hotel Expense"
+msgstr "住宿費"
+
+#: lib/RT/Base.pm:73
+#. (6)
+msgid "I have %quant(%1,concrete mixer)."
+msgstr "我有 %quant(%1,份固體攪拌器)。"
+
+#: NOT FOUND IN SOURCE
+msgid "ID Number"
+msgstr "身分證號"
+
+#: NOT FOUND IN SOURCE
+msgid "ID Type"
+msgstr "身分類別"
+
+#: html/Ticket/Elements/ShowBasics:26 lib/RT/Tickets_Overlay.pm:1018
+msgid "Id"
+msgstr "編號"
+
+#: html/Admin/Users/Modify.html:43 html/User/Prefs.html:38 html/Work/Preferences/Info:14
+msgid "Identity"
+msgstr "身份"
+
+#: etc/initialdata.zh:439 etc/initialdata:411 etc/upgrade/2.1.71:86 html/Edit/Elements/CreateApprovalsQueue:58
+msgid "If an approval is rejected, reject the original and delete pending approvals"
+msgstr "若簽核單遭到駁回,則連帶駁回原申請單,並刪除其他相關的待簽核事項"
+
+#: bin/rt-crontool:189
+msgid "If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT."
+msgstr "如果此工具程式為 setgid,惡意的本地端用戶即能由此取得 RT 的管理員權限。"
+
+#: html/Admin/Queues/People.html:104 html/Ticket/Modify.html:38 html/Ticket/ModifyAll.html:93 html/Ticket/ModifyPeople.html:37
+msgid "If you've updated anything above, be sure to"
+msgstr "若您已更新以上資料,請記得按一下"
+
+#: lib/RT/Interface/Web.pm:896 x:899
+msgid "Illegal value for %1"
+msgstr "%1 的值錯誤"
+
+#: lib/RT/Interface/Web.pm:899 x:902
+msgid "Immutable field"
+msgstr "此欄位值不可更動"
+
+#: html/Edit/Elements/104Buttons:76 html/Edit/Global/Workflow/Import.html:2
+msgid "Import"
+msgstr "匯入"
+
+#: html/Admin/Elements/EditCustomFields:73
+msgid "Include disabled custom fields in listing."
+msgstr "列出停用的自訂欄位"
+
+#: html/Admin/Queues/index.html:42 html/Edit/Queues/index.html:38
+msgid "Include disabled queues in listing."
+msgstr "列出停用的表單"
+
+#: html/Admin/Users/index.html:46 html/Edit/Users/Search.html:62
+msgid "Include disabled users in search."
+msgstr "列出停用的使用者"
+
+#: html/Edit/Users/Info:36
+msgid "Indirect Employee"
+msgstr "直接/間接員工"
+
+#: lib/RT/Tickets_Overlay.pm:1067
+msgid "Initial Priority"
+msgstr "初始優先權"
+
+#: lib/RT/Ticket_Overlay.pm:1179 lib/RT/Ticket_Overlay.pm:1181
+msgid "InitialPriority"
+msgstr "初始優先權"
+
+#: lib/RT/ScripAction_Overlay.pm:104
+msgid "Input error"
+msgstr "輸入錯誤"
+
+#: NOT FOUND IN SOURCE
+msgid "Interest noted"
+msgstr "登記成功"
+
+#: lib/RT/Ticket_Overlay.pm:3829
+msgid "Internal Error"
+msgstr "內部錯誤"
+
+#: lib/RT/Record.pm:142
+#. ($id->{error_message})
+msgid "Internal Error: %1"
+msgstr "內部錯誤:%1"
+
+#: lib/RT/Group_Overlay.pm:643
+msgid "Invalid Group Type"
+msgstr "錯誤的群組類別"
+
+#: lib/RT/Principal_Overlay.pm:127
+msgid "Invalid Right"
+msgstr "錯誤的權限"
+
+#: NOT FOUND IN SOURCE
+msgid "Invalid Type"
+msgstr "錯誤的類型"
+
+#: lib/RT/Interface/Web.pm:901 x:904
+msgid "Invalid data"
+msgstr "錯誤的資料"
+
+#: lib/RT/Ticket_Overlay.pm:439
+msgid "Invalid owner. Defaulting to 'nobody'."
+msgstr "錯誤的承辦人。改為預設承辦人「nobody」。"
+
+#: lib/RT/Scrip_Overlay.pm:133 lib/RT/Template_Overlay.pm:250
+msgid "Invalid queue"
+msgstr "錯誤的表單"
+
+#: lib/RT/ACE_Overlay.pm:243 lib/RT/ACE_Overlay.pm:252 lib/RT/ACE_Overlay.pm:258 lib/RT/ACE_Overlay.pm:269 lib/RT/ACE_Overlay.pm:274
+msgid "Invalid right"
+msgstr "錯誤的權限"
+
+#: lib/RT/Record.pm:117
+#. ($key)
+msgid "Invalid value for %1"
+msgstr "%1 的值錯誤"
+
+#: lib/RT/Ticket_Overlay.pm:3461
+msgid "Invalid value for custom field"
+msgstr "錯誤的自訂欄位值"
+
+#: lib/RT/Ticket_Overlay.pm:346
+msgid "Invalid value for status"
+msgstr "錯誤的狀態值"
+
+#: NOT FOUND IN SOURCE
+msgid "IssueStatement"
+msgstr "送出陳述"
+
+#: bin/rt-crontool:190
+msgid "It is incredibly important that nonprivileged users not be allowed to run this tool."
+msgstr "請絕對不要讓未具權限的使用者執行此工具程式。"
+
+#: bin/rt-crontool:191
+msgid "It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool."
+msgstr "建議您新增一個隸屬於正確群組的低權限系統使用者,並以該身份執行此工具程式。"
+
+#: bin/rt-crontool:162
+msgid "It takes several arguments:"
+msgstr "它接受下列參數:"
+
+#: NOT FOUND IN SOURCE
+msgid "Item Name"
+msgstr "品名"
+
+#: NOT FOUND IN SOURCE
+msgid "Items"
+msgstr "筆"
+
+#: NOT FOUND IN SOURCE
+msgid "Items pending my approval"
+msgstr "待簽核項目"
+
+#: NOT FOUND IN SOURCE
+msgid "Jan"
+msgstr "一月"
+
+#: lib/RT/Date.pm:411
+msgid "Jan."
+msgstr "01"
+
+#: NOT FOUND IN SOURCE
+msgid "January"
+msgstr "一月"
+
+#: NOT FOUND IN SOURCE
+msgid "Job"
+msgstr "職稱"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "Join or leave this group"
+msgstr "加入或離開此群組"
+
+#: NOT FOUND IN SOURCE
+msgid "Jul"
+msgstr "七月"
+
+#: lib/RT/Date.pm:417
+msgid "Jul."
+msgstr "01"
+
+#: NOT FOUND IN SOURCE
+msgid "July"
+msgstr "七月"
+
+#: html/Ticket/Elements/Tabs:98
+msgid "Jumbo"
+msgstr "全部資訊"
+
+#: NOT FOUND IN SOURCE
+msgid "Jun"
+msgstr "六月"
+
+#: lib/RT/Date.pm:416
+msgid "Jun."
+msgstr "06."
+
+#: NOT FOUND IN SOURCE
+msgid "June"
+msgstr "六月"
+
+#: NOT FOUND IN SOURCE
+msgid "Keyword"
+msgstr "關鍵字"
+
+#: lib/RT/CustomField_Vendor.pm:23
+msgid "LabelAttachments"
+msgstr "附件標籤"
+
+#: lib/RT/CustomField_Vendor.pm:24
+msgid "LabelContent"
+msgstr "內容標籤"
+
+#: lib/RT/CustomField_Vendor.pm:22
+msgid "LabelSubject"
+msgstr "主題標籤"
+
+#: lib/RT/CustomField_Vendor.pm:21
+msgid "LabelURL"
+msgstr "鏈結標籤"
+
+#: html/Admin/Elements/ModifyUser:51
+msgid "Lang"
+msgstr "使用語言"
+
+#: html/Ticket/Elements/Tabs:72
+msgid "Last"
+msgstr "上次更新"
+
+#: html/Ticket/Elements/EditDates:37 html/Ticket/Elements/ShowDates:38
+msgid "Last Contact"
+msgstr "上次聯絡"
+
+#: html/Elements/SelectDateType:28
+msgid "Last Contacted"
+msgstr "上次聯絡日期"
+
+#: html/Search/Elements/TicketHeader:40 html/Work/Search/TicketHeader:19
+msgid "Last Notified"
+msgstr "上次通知"
+
+#: html/Elements/SelectDateType:29
+msgid "Last Updated"
+msgstr "上次更新"
+
+#: NOT FOUND IN SOURCE
+msgid "LastUpdated"
+msgstr "上次更新"
+
+#: NOT FOUND IN SOURCE
+msgid "Left"
+msgstr "剩餘時間"
+
+#: html/Admin/Users/Modify.html:82
+msgid "Let this user access RT"
+msgstr "允許這名使用者登入"
+
+#: html/Admin/Users/Modify.html:86
+msgid "Let this user be granted rights"
+msgstr "內部成員(具有個人權限)"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting owner to %1 %2"
+msgstr "限制承辦人為 %1 到%2"
+
+#: NOT FOUND IN SOURCE
+msgid "Limiting queue to %1 %2"
+msgstr "限制表單為 %1 到 %2"
+
+#: html/Work/Queues/Select.html:4
+msgid "Link a Queue"
+msgstr "申請表單連結"
+
+#: lib/RT/Ticket_Overlay.pm:2717
+msgid "Link already exists"
+msgstr "此鏈結已存在"
+
+#: lib/RT/Ticket_Overlay.pm:2729
+msgid "Link could not be created"
+msgstr "無法新增鏈結"
+
+#: lib/RT/Ticket_Overlay.pm:2737 lib/RT/Ticket_Overlay.pm:2747
+#. ($TransString)
+msgid "Link created (%1)"
+msgstr "鏈結(%1)新增完畢"
+
+#: lib/RT/Ticket_Overlay.pm:2658
+#. ($TransString)
+msgid "Link deleted (%1)"
+msgstr "鏈結(%1)刪除完畢"
+
+#: lib/RT/Ticket_Overlay.pm:2664
+msgid "Link not found"
+msgstr "找不到鏈結"
+
+#: html/Ticket/ModifyLinks.html:24 html/Ticket/ModifyLinks.html:28
+#. ($Ticket->Id)
+msgid "Link ticket #%1"
+msgstr "鏈結申請單 #%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Link ticket %1"
+msgstr "鏈結申請單 %1"
+
+#: html/Ticket/Elements/Tabs:96
+msgid "Links"
+msgstr "鏈結"
+
+#: html/Edit/Users/Search.html:11
+msgid "List All Users"
+msgstr "列出所有用戶資料"
+
+#: html/Admin/Users/Modify.html:113 html/User/Prefs.html:84 html/Work/Preferences/Info:73
+msgid "Location"
+msgstr "位置"
+
+#: lib/RT.pm:162
+#. ($RT::LogDir)
+msgid "Log directory %1 not found or couldn't be written.\\n RT can't run."
+msgstr "登入目錄 %1 找不到或無法寫入\\n。無法執行 RT。"
+
+#: html/Edit/Global/Basic/Top:52
+msgid "LogToFile"
+msgstr "紀錄等級"
+
+#: html/Edit/Global/Basic/Top:54
+msgid "LogToFileNamed"
+msgstr "紀錄檔名"
+
+#: html/Elements/Header:57
+#. ("<b>".$session{'CurrentUser'}->Name."</b>")
+msgid "Logged in as %1"
+msgstr "使用者:%1"
+
+#: docs/design_docs/string-extraction-guide.txt:71 html/Elements/Login:35 html/Elements/Login:44 html/Elements/Login:54
+msgid "Login"
+msgstr "登入"
+
+#: html/Edit/Elements/104Top:17 html/Edit/Elements/104Top:17 html/Edit/Elements/104Top:32 html/Elements/Header:54
+msgid "Logout"
+msgstr "登出"
+
+#: NOT FOUND IN SOURCE
+msgid "Long-term contractor"
+msgstr "長期契約員工"
+
+#: html/Search/Bulk.html:85 html/Work/Search/Bulk.html:54
+msgid "Make Owner"
+msgstr "新增承辦人"
+
+#: html/Search/Bulk.html:109 html/Work/Search/Bulk.html:63
+msgid "Make Status"
+msgstr "新增現況"
+
+#: html/Search/Bulk.html:117 html/Work/Search/Bulk.html:75
+msgid "Make date Due"
+msgstr "新增到期日"
+
+#: html/Search/Bulk.html:119 html/Work/Search/Bulk.html:78
+msgid "Make date Resolved"
+msgstr "新增解決日期"
+
+#: html/Search/Bulk.html:113 html/Work/Search/Bulk.html:69
+msgid "Make date Started"
+msgstr "新增實際起始日期"
+
+#: html/Search/Bulk.html:111 html/Work/Search/Bulk.html:66
+msgid "Make date Starts"
+msgstr "新增應起始日期"
+
+#: html/Search/Bulk.html:115 html/Work/Search/Bulk.html:72
+msgid "Make date Told"
+msgstr "新增報告日期"
+
+#: html/Search/Bulk.html:105 html/Work/Search/Bulk.html:57
+msgid "Make priority"
+msgstr "新增優先順位"
+
+#: html/Search/Bulk.html:107 html/Work/Search/Bulk.html:60
+msgid "Make queue"
+msgstr "新增表單"
+
+#: html/Search/Bulk.html:103 html/Work/Search/Bulk.html:59
+msgid "Make subject"
+msgstr "新增主題"
+
+#: NOT FOUND IN SOURCE
+msgid "Male"
+msgstr "男"
+
+#: html/Admin/index.html:32
+msgid "Manage groups and group membership"
+msgstr "管理群組及所屬成員"
+
+#: html/Admin/index.html:38
+msgid "Manage properties and configuration which apply to all queues"
+msgstr "管理適用於所有表單的屬性與設定"
+
+#: html/Admin/index.html:35
+msgid "Manage queues and queue-specific properties"
+msgstr "管理各表單及相關屬性"
+
+#: html/Admin/index.html:29
+msgid "Manage users and passwords"
+msgstr "管理使用者與密碼"
+
+#: NOT FOUND IN SOURCE
+msgid "Manager"
+msgstr "經理"
+
+#: NOT FOUND IN SOURCE
+msgid "Mar"
+msgstr "三月"
+
+#: lib/RT/Date.pm:413
+msgid "Mar."
+msgstr "03"
+
+#: NOT FOUND IN SOURCE
+msgid "March"
+msgstr "三月"
+
+#: NOT FOUND IN SOURCE
+msgid "Marketing Department"
+msgstr "行銷部"
+
+#: NOT FOUND IN SOURCE
+msgid "May"
+msgstr "五月"
+
+#: lib/RT/Date.pm:415
+msgid "May."
+msgstr "05"
+
+#: lib/RT/Group_Overlay.pm:981
+msgid "Member added"
+msgstr "新增成員完畢"
+
+#: lib/RT/Group_Overlay.pm:1139
+msgid "Member deleted"
+msgstr "成員已刪除"
+
+#: lib/RT/Group_Overlay.pm:1143
+msgid "Member not deleted"
+msgstr "成員未被刪除"
+
+#: html/Elements/SelectLinkType:25
+msgid "Member of"
+msgstr "隸屬於"
+
+#: html/Work/Preferences/index.html:20
+msgid "Member since"
+msgstr "註冊日期"
+
+#: NOT FOUND IN SOURCE
+msgid "MemberOf"
+msgstr "隸屬於"
+
+#: html/Admin/Elements/GroupTabs:41 html/Admin/Elements/ModifyTemplateAsWorkflow:232 html/User/Elements/GroupTabs:41
+msgid "Members"
+msgstr "成員"
+
+#: lib/RT/Ticket_Overlay.pm:2904
+msgid "Merge Successful"
+msgstr "整合完畢"
+
+#: lib/RT/Ticket_Overlay.pm:2824
+msgid "Merge failed. Couldn't set EffectiveId"
+msgstr "整合失敗。無法設定 EffectiveId"
+
+#: html/Ticket/Elements/BulkLinks:26 html/Ticket/Elements/EditLinks:114 html/Work/Search/BulkLinks:2
+msgid "Merge into"
+msgstr "整合進"
+
+#: html/Search/Bulk.html:137 html/Ticket/Update.html:100
+msgid "Message"
+msgstr "訊息"
+
+#: NOT FOUND IN SOURCE
+msgid "Misc. Expense"
+msgstr "雜費"
+
+#: lib/RT/Interface/Web.pm:903 x:906
+msgid "Missing a primary key?: %1"
+msgstr "缺少主鍵值?(%1)"
+
+#: html/Admin/Users/Modify.html:168 html/User/Prefs.html:53 html/Work/Preferences/Info:36
+msgid "Mobile"
+msgstr "行動電話"
+
+#: html/Admin/Elements/ModifyUser:71
+msgid "MobilePhone"
+msgstr "行動電話"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "Modify Access Control List"
+msgstr "更改權限控制清單"
+
+#: html/Admin/Global/CustomFields.html:43 html/Admin/Global/index.html:50
+msgid "Modify Custom Fields which apply to all queues"
+msgstr "更改適用於所有表單的自訂欄位"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "Modify Scrip templates for this queue"
+msgstr "更改此表單的範本"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "Modify Scrips for this queue"
+msgstr "更改此表單的手續"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify System ACLS"
+msgstr "更改系統權限清單"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Template %1"
+msgstr "更改範本 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify Workflow"
+msgstr "更改流程"
+
+#: html/Admin/Queues/CustomField.html:44
+#. ($QueueObj->Name())
+msgid "Modify a CustomField for queue %1"
+msgstr "更改 %1 表單內的自訂欄位"
+
+#: html/Admin/Global/CustomField.html:52
+msgid "Modify a CustomField which applies to all queues"
+msgstr "更改適用於所有表單的自訂欄位"
+
+#: html/Admin/Queues/Scrip.html:53
+#. ($QueueObj->Name)
+msgid "Modify a scrip for queue %1"
+msgstr "更改 %1 表單內的手續"
+
+#: html/Admin/Global/Scrip.html:47
+msgid "Modify a scrip which applies to all queues"
+msgstr "更改適用於所有表單的手續"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify dates for # %1"
+msgstr "更改 # %1 的日期"
+
+#: html/Ticket/ModifyDates.html:24 html/Ticket/ModifyDates.html:28
+#. ($TicketObj->Id)
+msgid "Modify dates for #%1"
+msgstr "更改 #%1 的日期"
+
+#: html/Ticket/ModifyDates.html:34
+#. ($TicketObj->Id)
+msgid "Modify dates for ticket # %1"
+msgstr "更改申請單 # %1 的日期"
+
+#: html/Admin/Global/GroupRights.html:24 html/Admin/Global/GroupRights.html:27 html/Admin/Global/index.html:55
+msgid "Modify global group rights"
+msgstr "更改全域設定的群組權限"
+
+#: html/Admin/Global/GroupRights.html:32
+msgid "Modify global group rights."
+msgstr "更改全域設定的群組權限。"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for groups"
+msgstr "更改全域設定的群組權限"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global rights for users"
+msgstr "更改全域設定的使用者權限"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify global scrips"
+msgstr "更改全域手續"
+
+#: html/Admin/Global/UserRights.html:24 html/Admin/Global/UserRights.html:27 html/Admin/Global/index.html:59
+msgid "Modify global user rights"
+msgstr "更改全域設定的使用者權限"
+
+#: html/Admin/Global/UserRights.html:32
+msgid "Modify global user rights."
+msgstr "更改全域設定的使用者權限。"
+
+#: lib/RT/Group_Overlay.pm:145
+msgid "Modify group metadata or delete group"
+msgstr "更改群組資料及刪除群組"
+
+#: html/Admin/Groups/GroupRights.html:24 html/Admin/Groups/GroupRights.html:28 html/Admin/Groups/GroupRights.html:34
+#. ($GroupObj->Name)
+msgid "Modify group rights for group %1"
+msgstr "更改 %1 的群組權限"
+
+#: html/Admin/Queues/GroupRights.html:24 html/Admin/Queues/GroupRights.html:28
+#. ($QueueObj->Name)
+msgid "Modify group rights for queue %1"
+msgstr "更改表單 %1 的群組權限"
+
+#: lib/RT/Group_Overlay.pm:147
+msgid "Modify membership roster for this group"
+msgstr "更改此群組的成員名單"
+
+#: lib/RT/System.pm:60
+msgid "Modify one's own RT account"
+msgstr "更改個人的帳號資訊"
+
+#: html/Admin/Queues/People.html:24 html/Admin/Queues/People.html:28
+#. ($QueueObj->Name)
+msgid "Modify people related to queue %1"
+msgstr "更改鏈結到表單 %1 的人員"
+
+#: html/Ticket/ModifyPeople.html:24 html/Ticket/ModifyPeople.html:28 html/Ticket/ModifyPeople.html:34
+#. ($Ticket->id)
+#. ($Ticket->Id)
+msgid "Modify people related to ticket #%1"
+msgstr "更改申請單 #%1 鏈結到的人員"
+
+#: html/Admin/Queues/Scrips.html:45
+#. ($QueueObj->Name)
+msgid "Modify scrips for queue %1"
+msgstr "更改表單 %1 的手續"
+
+#: html/Admin/Global/Scrips.html:43 html/Admin/Global/index.html:41
+msgid "Modify scrips which apply to all queues"
+msgstr "更改適用於所有表單的手續"
+
+#: html/Admin/Global/Template.html:24 html/Admin/Global/Template.html:29 html/Admin/Global/Template.html:80 html/Admin/Queues/Template.html:77
+#. (loc($TemplateObj->Name()))
+#. ($TemplateObj->id)
+msgid "Modify template %1"
+msgstr "更改範本 %1"
+
+#: html/Admin/Global/Templates.html:43
+msgid "Modify templates which apply to all queues"
+msgstr "更改適用於所有表單的範本"
+
+#: html/Admin/Groups/Modify.html:86 html/User/Groups/Modify.html:85
+#. ($Group->Name)
+msgid "Modify the group %1"
+msgstr "更改群組 %1"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "Modify the queue watchers"
+msgstr "更改表單視察員"
+
+#: html/Admin/Users/Modify.html:235
+#. ($UserObj->Name)
+msgid "Modify the user %1"
+msgstr "更改使用者 %1"
+
+#: html/Ticket/ModifyAll.html:36
+#. ($Ticket->Id)
+msgid "Modify ticket # %1"
+msgstr "更改申請單 # %1"
+
+#: html/Ticket/Modify.html:24 html/Ticket/Modify.html:27 html/Ticket/Modify.html:33
+#. ($TicketObj->Id)
+msgid "Modify ticket #%1"
+msgstr "更改申請單 # %1"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "Modify tickets"
+msgstr "更改申請單"
+
+#: html/Admin/Groups/UserRights.html:24 html/Admin/Groups/UserRights.html:28 html/Admin/Groups/UserRights.html:34
+#. ($GroupObj->Name)
+msgid "Modify user rights for group %1"
+msgstr "更改群組 %1 的使用者權限"
+
+#: html/Admin/Queues/UserRights.html:24 html/Admin/Queues/UserRights.html:28
+#. ($QueueObj->Name)
+msgid "Modify user rights for queue %1"
+msgstr "更改表單 %1 的使用者權限"
+
+#: NOT FOUND IN SOURCE
+msgid "Modify watchers for queue '%1'"
+msgstr "更改 '%1' 的視察員"
+
+#: html/Admin/Global/Workflow.html:25 html/Admin/Global/Workflow.html:30 html/Admin/Global/Workflow.html:81 html/Admin/Queues/Workflow.html:77
+#. (loc($WorkflowObj->Name()))
+#. ($WorkflowObj->id)
+msgid "Modify workflow %1"
+msgstr "更改流程 %1"
+
+#: html/Admin/Global/Workflows.html:44
+msgid "Modify workflows which apply to all queues"
+msgstr "更改適用於所有表單的流程"
+
+#: lib/RT/Queue_Overlay.pm:69
+msgid "ModifyACL"
+msgstr "更改權限清單"
+
+#: lib/RT/Group_Overlay.pm:148
+msgid "ModifyOwnMembership"
+msgstr "更改自己是否屬於某群組"
+
+#: lib/RT/Queue_Overlay.pm:70
+msgid "ModifyQueueWatchers"
+msgstr "更改表單視察員"
+
+#: lib/RT/Queue_Overlay.pm:75
+msgid "ModifyScrips"
+msgstr "更改手續"
+
+#: lib/RT/System.pm:60
+msgid "ModifySelf"
+msgstr "更改個人帳號"
+
+#: lib/RT/Queue_Overlay.pm:72
+msgid "ModifyTemplate"
+msgstr "更改範本"
+
+#: lib/RT/Queue_Overlay.pm:87
+msgid "ModifyTicket"
+msgstr "更改申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "Mon"
+msgstr "星期一"
+
+#: lib/RT/Date.pm:388
+msgid "Mon."
+msgstr "星期一"
+
+#: html/Work/Elements/MyRequests:11 html/Work/Elements/MyTickets:11
+msgid "More"
+msgstr "更多"
+
+#: html/Ticket/Elements/ShowRequestor:41
+#. ($name)
+msgid "More about %1"
+msgstr "關於 %1 的進一步資訊"
+
+#: NOT FOUND IN SOURCE
+msgid "Morning Shift"
+msgstr "早班"
+
+#: html/Edit/Elements/ListButtons:16
+msgid "Move All"
+msgstr "全移"
+
+#: html/Admin/Elements/EditCustomFields:60
+msgid "Move down"
+msgstr "下移"
+
+#: html/Admin/Elements/EditCustomFields:52
+msgid "Move up"
+msgstr "上移"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:26
+msgid "Multiple"
+msgstr "多重"
+
+#: lib/RT/User_Overlay.pm:238
+msgid "Must specify 'Name' attribute"
+msgstr "必須指定 'Name' 的屬性"
+
+#: html/SelfService/Elements/MyRequests:48
+#. ($friendly_status)
+msgid "My %1 tickets"
+msgstr "我的 %1 申請單"
+
+#: html/Work/Elements/Tab:37
+msgid "My Approvals"
+msgstr "表單簽核"
+
+#: html/Work/Elements/Tab:35
+msgid "My Requests"
+msgstr "表單申請追蹤"
+
+#: html/Work/Elements/Tab:39
+msgid "My Tickets"
+msgstr "表單處理"
+
+#: html/Approvals/index.html:24 html/Approvals/index.html:25
+msgid "My approvals"
+msgstr "表單簽核"
+
+#: html/Admin/Elements/AddCustomFieldValue:31 html/Admin/Elements/EditCustomField:33 html/Admin/Elements/ModifyTemplate:27 html/Admin/Elements/ModifyTemplateAsWorkflow:185 html/Admin/Elements/ModifyUser:29 html/Admin/Groups/Modify.html:43 html/Edit/Users/Add.html:22 html/Edit/Users/Search.html:31 html/Elements/SelectGroups:25 html/Elements/SelectUsers:27 html/User/Groups/Modify.html:43 html/Work/Tickets/Cc:18
+msgid "Name"
+msgstr "名稱"
+
+#: lib/RT/User_Overlay.pm:245
+msgid "Name in use"
+msgstr "帳號已有人使用"
+
+#: html/Edit/Users/Info:27
+msgid "Nationality"
+msgstr "國籍"
+
+#: NOT FOUND IN SOURCE
+msgid "Need approval from system administrator"
+msgstr "需先由系統管理員進行批准"
+
+#: html/Ticket/Elements/ShowDates:51
+msgid "Never"
+msgstr "從未更動"
+
+#: html/Elements/Quicksearch:29 html/Work/Elements/Quicksearch:15 html/Work/Tickets/Create.html:54
+msgid "New"
+msgstr "新建立"
+
+#: html/Admin/Elements/ModifyUser:31 html/Admin/Users/Modify.html:92 html/User/Prefs.html:64 html/Work/Preferences/Info:47
+msgid "New Password"
+msgstr "新的密碼"
+
+#: etc/initialdata.zh:341 etc/initialdata:317 etc/upgrade/2.1.71:16 html/Edit/Elements/CreateApprovalsQueue:21
+msgid "New Pending Approval"
+msgstr "新的待簽核事項"
+
+#: html/Ticket/Elements/EditLinks:110
+msgid "New Relationships"
+msgstr "新增關係"
+
+#: html/Work/Elements/Tab:33
+msgid "New Request"
+msgstr "表單申請"
+
+#: html/Ticket/Elements/Tabs:35
+msgid "New Search"
+msgstr "新增查詢"
+
+#: html/Admin/Global/CustomField.html:40 html/Admin/Global/CustomFields.html:38 html/Admin/Queues/CustomField.html:51 html/Admin/Queues/CustomFields.html:39
+msgid "New custom field"
+msgstr "新增自訂欄位"
+
+#: html/Admin/Elements/GroupTabs:53 html/User/Elements/GroupTabs:51
+msgid "New group"
+msgstr "新增群組"
+
+#: html/SelfService/Prefs.html:31
+msgid "New password"
+msgstr "新的密碼"
+
+#: lib/RT/User_Overlay.pm:764
+msgid "New password notification sent"
+msgstr "送出新密碼通知"
+
+#: html/Admin/Elements/QueueTabs:69
+msgid "New queue"
+msgstr "新增表單"
+
+#: NOT FOUND IN SOURCE
+msgid "New request"
+msgstr "提出申請單"
+
+#: html/Admin/Elements/SelectRights:41
+msgid "New rights"
+msgstr "新增權限"
+
+#: html/Admin/Global/Scrip.html:39 html/Admin/Global/Scrips.html:38 html/Admin/Queues/Scrip.html:42 html/Admin/Queues/Scrips.html:54
+msgid "New scrip"
+msgstr "新增手續"
+
+#: html/Work/Search/index.html:62
+msgid "New search"
+msgstr "重新查詢"
+
+#: html/Admin/Global/Template.html:59 html/Admin/Global/Templates.html:38 html/Admin/Queues/Template.html:57 html/Admin/Queues/Templates.html:49
+msgid "New template"
+msgstr "新增範本"
+
+#: html/SelfService/Elements/Tabs:47
+msgid "New ticket"
+msgstr "提出申請單"
+
+#: lib/RT/Ticket_Overlay.pm:2791
+msgid "New ticket doesn't exist"
+msgstr "沒有新申請單"
+
+#: html/Admin/Elements/UserTabs:51
+msgid "New user"
+msgstr "新增使用者"
+
+#: html/Admin/Elements/CreateUserCalled:25
+msgid "New user called"
+msgstr "新使用者名字"
+
+#: html/Admin/Queues/People.html:54 html/Ticket/Elements/EditPeople:28
+msgid "New watchers"
+msgstr "新視察員"
+
+#: html/Admin/Users/Prefs.html:41
+msgid "New window setting"
+msgstr "更新視窗設定"
+
+#: html/Admin/Global/Workflow.html:60 html/Admin/Global/Workflows.html:39 html/Admin/Queues/Workflow.html:57 html/Admin/Queues/Workflows.html:50
+msgid "New workflow"
+msgstr "新增流程"
+
+#: html/Ticket/Elements/Tabs:68
+msgid "Next"
+msgstr "下一項"
+
+#: html/Search/Listing.html:47 html/Work/Search/index.html:24
+msgid "Next page"
+msgstr "下一頁"
+
+#: html/Admin/Elements/ModifyUser:49
+msgid "NickName"
+msgstr "暱稱"
+
+#: html/Admin/Users/Modify.html:62 html/User/Prefs.html:45 html/Work/Preferences/Info:26
+msgid "Nickname"
+msgstr "暱稱"
+
+#: NOT FOUND IN SOURCE
+msgid "Night Shift"
+msgstr "小夜班"
+
+#: html/Edit/Global/Basic/Top:27
+msgid "No"
+msgstr "否"
+
+#: html/Admin/Elements/EditCustomField:89 html/Admin/Elements/EditCustomFields:104
+msgid "No CustomField"
+msgstr "無自訂欄位"
+
+#: html/Admin/Groups/GroupRights.html:83 html/Admin/Groups/UserRights.html:70
+msgid "No Group defined"
+msgstr "尚未定義群組"
+
+#: html/Admin/Queues/GroupRights.html:96 html/Admin/Queues/UserRights.html:67
+msgid "No Queue defined"
+msgstr "沒有定義好的表單"
+
+#: bin/rt-crontool:55
+msgid "No RT user found. Please consult your RT administrator.\\n"
+msgstr "找不到 RT 使用者。請向 RT 管理員查詢。\\n"
+
+#: html/Admin/Global/Template.html:78 html/Admin/Queues/Template.html:75
+msgid "No Template"
+msgstr "沒有範本"
+
+#: bin/rt-commit-handler:763
+msgid "No Ticket specified. Aborting ticket "
+msgstr "未指定申請單。退出申請單 "
+
+#: NOT FOUND IN SOURCE
+msgid "No Ticket specified. Aborting ticket modifications\\n\\n"
+msgstr "未指定申請單。退出申請單更改\\n\\n"
+
+#: html/Admin/Elements/ModifyWorkflow:237 html/Admin/Global/Workflow.html:79 html/Admin/Queues/Workflow.html:75
+msgid "No Workflow"
+msgstr "沒有流程"
+
+#: html/Approvals/Elements/Approve:45 html/Work/Approvals/Elements/Approve:35
+msgid "No action"
+msgstr "暫不處理"
+
+#: lib/RT/Interface/Web.pm:898 x:901
+msgid "No column specified"
+msgstr "未指定欄位"
+
+#: NOT FOUND IN SOURCE
+msgid "No command found\\n"
+msgstr "找不到命令"
+
+#: html/Elements/ViewUser:35 html/Ticket/Elements/ShowRequestor:44
+msgid "No comment entered about this user"
+msgstr "沒有對這名使用者的評論"
+
+#: lib/RT/Ticket_Overlay.pm:2202 lib/RT/Ticket_Overlay.pm:2270
+msgid "No correspondence attached"
+msgstr "沒有附上申請單回覆"
+
+#: lib/RT/Action/Generic.pm:149 lib/RT/Condition/Generic.pm:175 lib/RT/Search/ActiveTicketsInQueue.pm:55 lib/RT/Search/Generic.pm:112
+#. (ref $self)
+msgid "No description for %1"
+msgstr "沒有對 %1 的描述"
+
+#: lib/RT/Users_Overlay.pm:150
+msgid "No group specified"
+msgstr "未指定群組"
+
+#: lib/RT/User_Overlay.pm:982
+msgid "No password set"
+msgstr "沒有設定密碼"
+
+#: lib/RT/Queue_Overlay.pm:260
+msgid "No permission to create queues"
+msgstr "沒有新增表單的權限"
+
+#: lib/RT/Ticket_Overlay.pm:342
+#. ($QueueObj->Name)
+msgid "No permission to create tickets in the queue '%1'"
+msgstr "沒有在表單 '%1' 新增申請單的權限"
+
+#: lib/RT/User_Overlay.pm:211
+msgid "No permission to create users"
+msgstr "沒有新增使用者的權限"
+
+#: html/SelfService/Display.html:117
+msgid "No permission to display that ticket"
+msgstr "沒有顯示該申請單的權限"
+
+#: html/SelfService/Update.html:51
+msgid "No permission to view update ticket"
+msgstr "沒有檢視申請單更新的權限"
+
+#: lib/RT/Queue_Overlay.pm:675 lib/RT/Ticket_Overlay.pm:1487
+msgid "No principal specified"
+msgstr "未指定單位"
+
+#: html/Admin/Queues/People.html:153 html/Admin/Queues/People.html:163
+msgid "No principals selected."
+msgstr "未指定單位。"
+
+#: NOT FOUND IN SOURCE
+msgid "No protocol specified in %1"
+msgstr "%1 內未指定協定"
+
+#: html/Admin/Queues/index.html:34
+msgid "No queues matching search criteria found."
+msgstr "找不到符合查詢條件的表單。"
+
+#: html/Admin/Elements/SelectRights:80
+msgid "No rights found"
+msgstr "找不到權限"
+
+#: html/Admin/Elements/SelectRights:32
+msgid "No rights granted."
+msgstr "沒有選定權限"
+
+#: html/Search/Bulk.html:160 html/Work/Search/Bulk.html:117
+msgid "No search to operate on."
+msgstr "沒有要進行的查詢"
+
+#: NOT FOUND IN SOURCE
+msgid "No ticket id specified"
+msgstr "未指定申請單編號"
+
+#: lib/RT/Transaction_Overlay.pm:478 lib/RT/Transaction_Overlay.pm:516
+msgid "No transaction type specified"
+msgstr "未指定更動報告類別"
+
+#: NOT FOUND IN SOURCE
+msgid "No user or email address specified"
+msgstr "未指定使用者或電子郵件地址"
+
+#: html/Admin/Users/index.html:35
+msgid "No users matching search criteria found."
+msgstr "找不到符合查詢條件的使用者。"
+
+#: bin/rt-commit-handler:643
+msgid "No valid RT user found. RT cvs handler disengaged. Please consult your RT administrator.\\n"
+msgstr "找不到合格的 RT 使用者。RT cvs 處理器已停用。請向 RT 管理者詢問。\\n"
+
+#: lib/RT/Interface/Web.pm:895 x:898
+msgid "No value sent to _Set!\\n"
+msgstr "_Set 沒有收到任何值!\\n"
+
+#: html/Search/Elements/TicketRow:36 html/Work/Search/TicketRow:9
+msgid "Nobody"
+msgstr "沒有人"
+
+#: lib/RT/Interface/Web.pm:900 x:903
+msgid "Nonexistant field?"
+msgstr "欄位不存在?"
+
+#: NOT FOUND IN SOURCE
+msgid "Normal Users"
+msgstr "一般用戶群組"
+
+#: NOT FOUND IN SOURCE
+msgid "Not configured to fetch the content from a %1 in %2"
+msgstr "未設定成從 %2 內擷取 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Not logged in"
+msgstr "尚未登入"
+
+#: html/Elements/Header:59
+msgid "Not logged in."
+msgstr "尚未登入"
+
+#: lib/RT/Date.pm:369
+msgid "Not set"
+msgstr "尚未設定"
+
+#: html/NoAuth/Reminder.html:26
+msgid "Not yet implemented."
+msgstr "尚未完工。"
+
+#: NOT FOUND IN SOURCE
+msgid "Not yet implemented...."
+msgstr "尚未完工..."
+
+#: html/Approvals/Elements/Approve:48 html/Work/Tickets/Create.html:143
+msgid "Notes"
+msgstr "備註"
+
+#: NOT FOUND IN SOURCE
+msgid "Notes:"
+msgstr "備註:"
+
+#: lib/RT/User_Overlay.pm:767
+msgid "Notification could not be sent"
+msgstr "無法送出通知"
+
+#: etc/initialdata.zh:111 etc/initialdata:93
+msgid "Notify AdminCcs"
+msgstr "通知管理員副本收件人"
+
+#: etc/initialdata.zh:107 etc/initialdata:89
+msgid "Notify AdminCcs as Comment"
+msgstr "以評論方式通知管理員副本收件人"
+
+#: etc/initialdata.zh:138 etc/initialdata:120
+msgid "Notify Other Recipients"
+msgstr "通知其他收件人"
+
+#: etc/initialdata.zh:134 etc/initialdata:116
+msgid "Notify Other Recipients as Comment"
+msgstr "以評論方式通知其他收件人"
+
+#: etc/initialdata.zh:103 etc/initialdata:85
+msgid "Notify Owner"
+msgstr "通知承辦人"
+
+#: etc/initialdata.zh:99 etc/initialdata:81
+msgid "Notify Owner as Comment"
+msgstr "以評論方式通知承辦人"
+
+#: etc/initialdata.zh:385 etc/initialdata:361
+msgid "Notify Owner of their rejected ticket"
+msgstr "通知承辦人申請單已駁回"
+
+#: etc/initialdata.zh:374 etc/initialdata:350
+msgid "Notify Owner of their ticket has been approved by all approvers"
+msgstr "通知承辦人申請單已完成全部簽核"
+
+#: etc/initialdata.zh:359 etc/initialdata:338
+msgid "Notify Owner of their ticket has been approved by some approver"
+msgstr "通知承辦人申請單已完成某項簽核"
+
+#: etc/initialdata.zh:343 etc/initialdata:319 etc/upgrade/2.1.71:17 html/Edit/Elements/CreateApprovalsQueue:22
+msgid "Notify Owners and AdminCcs of new items pending their approval"
+msgstr "整理待簽核事項,通知承辦人及管理員副本收件人"
+
+#: etc/initialdata.zh:95 etc/initialdata:77
+msgid "Notify Requestors"
+msgstr "通知申請人"
+
+#: etc/initialdata.zh:121 etc/initialdata:103
+msgid "Notify Requestors and Ccs"
+msgstr "通知申請人及副本收件人"
+
+#: etc/initialdata.zh:116 etc/initialdata:98
+msgid "Notify Requestors and Ccs as Comment"
+msgstr "以評論方式通知申請人及副本收件人"
+
+#: etc/initialdata.zh:130 etc/initialdata:112
+msgid "Notify Requestors, Ccs and AdminCcs"
+msgstr "通知申請人、副本及管理員副本收件人"
+
+#: etc/initialdata.zh:126 etc/initialdata:108
+msgid "Notify Requestors, Ccs and AdminCcs as Comment"
+msgstr "以評論方式通知申請人、副本及管理員副本收件人"
+
+#: html/Work/Tickets/Cc:55
+msgid "Notify people:"
+msgstr "通知對象"
+
+#: NOT FOUND IN SOURCE
+msgid "Nov"
+msgstr "十一月"
+
+#: lib/RT/Date.pm:421
+msgid "Nov."
+msgstr "11"
+
+#: NOT FOUND IN SOURCE
+msgid "November"
+msgstr "十一月"
+
+#: html/Edit/Global/Basic/Top:74
+msgid "OIN104"
+msgstr "配合 104eHRMS 介面"
+
+#: html/Edit/Global/Workflow/Export.html:30 html/Work/Copyright.html:23
+msgid "OK"
+msgstr "確定"
+
+#: lib/RT/Record.pm:156
+msgid "Object could not be created"
+msgstr "無法新增物件"
+
+#: lib/RT/Record.pm:175
+msgid "Object created"
+msgstr "物件新增完畢"
+
+#: html/Edit/Users/Info:35
+msgid "Occupation Status"
+msgstr "在職狀態"
+
+#: NOT FOUND IN SOURCE
+msgid "Oct"
+msgstr "十月"
+
+#: lib/RT/Date.pm:420
+msgid "Oct."
+msgstr "10"
+
+#: NOT FOUND IN SOURCE
+msgid "October"
+msgstr "十月"
+
+#: html/Edit/Users/Info:32
+msgid "Office Phone"
+msgstr "辦公室電話"
+
+#: html/Elements/SelectDateRelation:34
+msgid "On"
+msgstr "等於"
+
+#: etc/initialdata.zh:173 etc/initialdata:155
+msgid "On Comment"
+msgstr "評論時"
+
+#: etc/initialdata.zh:166 etc/initialdata:148
+msgid "On Correspond"
+msgstr "回覆申請單時"
+
+#: etc/initialdata.zh:155 etc/initialdata:137
+msgid "On Create"
+msgstr "新增申請單時"
+
+#: etc/initialdata.zh:187 etc/initialdata:169
+msgid "On Owner Change"
+msgstr "承辦人改變時"
+
+#: etc/initialdata.zh:195 etc/initialdata:177
+msgid "On Queue Change"
+msgstr "表單改變時"
+
+#: etc/initialdata.zh:201 etc/initialdata:183
+msgid "On Resolve"
+msgstr "解決申請單時"
+
+#: etc/initialdata.zh:179 etc/initialdata:161
+msgid "On Status Change"
+msgstr "現況改變時"
+
+#: etc/initialdata.zh:160 etc/initialdata:142
+msgid "On Transaction"
+msgstr "發生更動時"
+
+#: html/Approvals/Elements/PendingMyApproval:49
+#. ("<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter'>")
+msgid "Only show approvals for requests created after %1"
+msgstr "僅顯示 %1 之後新增的申請單"
+
+#: html/Approvals/Elements/PendingMyApproval:47
+#. ("<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore'>")
+msgid "Only show approvals for requests created before %1"
+msgstr "僅顯示 %1 之前新增的申請單"
+
+#: html/Edit/Global/GroupRight/List:9 html/Edit/Global/GroupRight/Top:16 html/Edit/Groups/List:11 html/Edit/Groups/Top:18 html/Edit/Queues/Basic/Top:69 html/Edit/Queues/List:13 html/Elements/Quicksearch:30 html/Work/Delegates/Info:48 html/Work/Delegates/Info:51 html/Work/Delegates/List:12 html/Work/Elements/Quicksearch:16 html/Work/Overview/Info:41 html/Work/Tickets/Display.html:28
+msgid "Open"
+msgstr "開啟"
+
+#: html/Ticket/Elements/Tabs:135
+msgid "Open it"
+msgstr "開啟"
+
+#: html/SelfService/Elements/Tabs:41
+msgid "Open tickets"
+msgstr "開啟的申請單"
+
+#: html/Admin/Users/Prefs.html:40
+msgid "Open tickets (from listing) in a new window"
+msgstr "在新視窗開啟(列表的)申請單"
+
+#: html/Admin/Users/Prefs.html:39
+msgid "Open tickets (from listing) in another window"
+msgstr "在另一個視窗開啟(列表的)申請單"
+
+#: etc/initialdata.zh:150 etc/initialdata:132
+msgid "Open tickets on correspondence"
+msgstr "收到回覆時即開啟申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "Opened Tickets"
+msgstr "已申請運行中表單"
+
+#: NOT FOUND IN SOURCE
+msgid "Opinion"
+msgstr "意見"
+
+#: html/Edit/Global/CustomField/Info:35
+msgid "Option Description"
+msgstr "選項描述"
+
+#: html/Edit/Global/CustomField/Info:29
+msgid "Option Name"
+msgstr "選項名稱"
+
+#: html/Search/Elements/PickRestriction:100 html/Work/Search/PickRestriction:81
+msgid "Ordering and sorting"
+msgstr "順序與排序方式"
+
+#: html/Admin/Elements/ModifyUser:45 html/Admin/Users/Modify.html:116 html/Edit/Global/Basic/Top:50 html/Elements/SelectUsers:28 html/User/Prefs.html:85 html/Work/Preferences/Info:75
+msgid "Organization"
+msgstr "組織名稱"
+
+#: NOT FOUND IN SOURCE
+msgid "Organization:"
+msgstr "組織:"
+
+#: html/Approvals/Elements/Approve:32
+#. ($approving->Id, $approving->Subject)
+msgid "Originating ticket: #%1"
+msgstr "原申請單:#%1"
+
+#: html/Edit/Elements/PickUsers:109 html/Edit/Users/Add.html:106 html/Work/Tickets/Cc:80
+msgid "Other comma-delimited email addresses"
+msgstr "其他e-mail帳號 (僅e-mail通知;多筆帳號請用逗號','區隔)"
+
+#: html/Admin/Elements/ModifyQueue:54 html/Admin/Queues/Modify.html:68 html/Edit/Queues/Basic/Top:41
+msgid "Over time, priority moves toward"
+msgstr "優先順位隨時間增加調整為"
+
+#: NOT FOUND IN SOURCE
+msgid "Override current custom fields with fields from %1"
+msgstr "以 %1 表單的自訂欄位取代現有欄位"
+
+#: html/Admin/Elements/CheckOverrideGlobalACL:25
+msgid "Override global rights"
+msgstr "取代全域權限"
+
+#: html/Admin/Elements/CheckOverrideGlobalACL:34
+#. (loc_fuzzy($msg))
+msgid "OverrideGlobalACL status %1"
+msgstr "取代全域權限 %1"
+
+#: html/Work/Elements/Tab:31
+msgid "Overview"
+msgstr "總覽"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "Own tickets"
+msgstr "承辦申請單"
+
+#: lib/RT/Queue_Overlay.pm:86
+msgid "OwnTicket"
+msgstr "承辦申請單"
+
+#: etc/initialdata.zh:56 etc/initialdata:38 html/Admin/Elements/ModifyTemplateAsWorkflow:141 html/Edit/Global/Workflow/Owner.html:19 html/Edit/Queues/Basic/Top:47 html/Edit/Queues/Basic/Top:58 html/Elements/MyRequests:31 html/SelfService/Elements/MyRequests:29 html/Ticket/Create.html:47 html/Ticket/Elements/EditPeople:42 html/Ticket/Elements/EditPeople:43 html/Ticket/Elements/ShowPeople:26 html/Ticket/Update.html:62 html/Work/Elements/MyRequests:19 html/Work/Elements/Quicksearch:18 html/Work/Tickets/Elements/ShowBasics:21 html/Work/Tickets/Update.html:27 lib/RT/ACE_Overlay.pm:85 lib/RT/Tickets_Overlay.pm:1244
+msgid "Owner"
+msgstr "承辦人"
+
+#: NOT FOUND IN SOURCE
+msgid "Owner changed from %1 to %2"
+msgstr "承辦人已從 %1 改為 %2"
+
+#: lib/RT/Transaction_Overlay.pm:582
+#. ($Old->Name , $New->Name)
+msgid "Owner forcibly changed from %1 to %2"
+msgstr "強制將承辦人從 %1 改為 %2"
+
+#: html/Search/Elements/PickRestriction:30 html/Work/Search/PickRestriction:10
+msgid "Owner is"
+msgstr "承辦人"
+
+#: html/Work/Elements/List:27 html/Work/Queues/List:8 html/Work/Tickets/Create.html:56 html/Work/Tickets/Elements/ShowBasics:60
+msgid "Owner's Phone"
+msgstr "承辦人電話"
+
+#: html/Edit/Elements/Page:39
+msgid "Page"
+msgstr " "
+
+#: html/Admin/Users/Modify.html:173 html/User/Prefs.html:55 html/Work/Preferences/Info:38
+msgid "Pager"
+msgstr "呼叫器"
+
+#: html/Admin/Elements/ModifyUser:73
+msgid "PagerPhone"
+msgstr "呼叫器號碼"
+
+#: html/Edit/Global/Workflow/Action:81 html/Edit/Global/Workflow/Condition:66
+msgid "Parameter"
+msgstr "呼叫參數"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:225
+msgid "Parent"
+msgstr "上級"
+
+#: html/Ticket/Create.html:181 html/Ticket/Elements/BulkLinks:38 html/Ticket/Elements/EditLinks:126 html/Ticket/Elements/EditLinks:57 html/Ticket/Elements/ShowLinks:46 html/Work/Search/BulkLinks:14
+msgid "Parents"
+msgstr "母申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "Park Space"
+msgstr "停車位申請"
+
+#: html/Elements/Login:52 html/User/Prefs.html:60 html/Work/Preferences/Info:44
+msgid "Password"
+msgstr "密碼"
+
+#: html/NoAuth/Reminder.html:24
+msgid "Password Reminder"
+msgstr "密碼提示"
+
+#: lib/RT/User_Overlay.pm:228 lib/RT/User_Overlay.pm:985
+msgid "Password too short"
+msgstr "密碼太短"
+
+#: html/Admin/Users/Modify.html:290 html/User/Prefs.html:171 html/Work/Preferences/Info:167
+#. (loc_fuzzy($msg))
+msgid "Password: %1"
+msgstr "密碼:%1"
+
+#: html/Admin/Users/Modify.html:292
+msgid "Passwords do not match."
+msgstr "密碼確認失敗。"
+
+#: html/User/Prefs.html:173 html/Work/Preferences/Info:169
+msgid "Passwords do not match. Your password has not been changed"
+msgstr "密碼確認失敗。您的密碼並未改變。"
+
+#: NOT FOUND IN SOURCE
+msgid "Pelase select a queue"
+msgstr "請選擇表單名稱"
+
+#: NOT FOUND IN SOURCE
+msgid "Pending Approval"
+msgstr "等待簽核"
+
+#: html/Ticket/Elements/ShowSummary:44 html/Ticket/Elements/Tabs:95 html/Ticket/ModifyAll.html:50
+msgid "People"
+msgstr "人員"
+
+#: NOT FOUND IN SOURCE
+msgid "People with Queue Rights"
+msgstr "擁有表單權限人員"
+
+#: etc/initialdata.zh:143 etc/initialdata:125
+msgid "Perform a user-defined action"
+msgstr "執行使用者自訂的動作"
+
+#: lib/RT/ACE_Overlay.pm:230 lib/RT/ACE_Overlay.pm:236 lib/RT/ACE_Overlay.pm:562 lib/RT/ACE_Overlay.pm:572 lib/RT/ACE_Overlay.pm:582 lib/RT/ACE_Overlay.pm:647 lib/RT/CurrentUser.pm:82 lib/RT/CurrentUser.pm:91 lib/RT/CustomField_Overlay.pm:100 lib/RT/CustomField_Overlay.pm:201 lib/RT/CustomField_Overlay.pm:233 lib/RT/CustomField_Overlay.pm:510 lib/RT/CustomField_Overlay.pm:90 lib/RT/Group_Overlay.pm:1094 lib/RT/Group_Overlay.pm:1098 lib/RT/Group_Overlay.pm:1107 lib/RT/Group_Overlay.pm:1158 lib/RT/Group_Overlay.pm:1162 lib/RT/Group_Overlay.pm:1168 lib/RT/Group_Overlay.pm:425 lib/RT/Group_Overlay.pm:517 lib/RT/Group_Overlay.pm:595 lib/RT/Group_Overlay.pm:603 lib/RT/Group_Overlay.pm:700 lib/RT/Group_Overlay.pm:704 lib/RT/Group_Overlay.pm:710 lib/RT/Group_Overlay.pm:903 lib/RT/Group_Overlay.pm:907 lib/RT/Group_Overlay.pm:920 lib/RT/Queue_Overlay.pm:540 lib/RT/Queue_Overlay.pm:550 lib/RT/Queue_Overlay.pm:564 lib/RT/Queue_Overlay.pm:699 lib/RT/Queue_Overlay.pm:708 lib/RT/Queue_Overlay.pm:721 lib/RT/Queue_Overlay.pm:931 lib/RT/Scrip_Overlay.pm:125 lib/RT/Scrip_Overlay.pm:136 lib/RT/Scrip_Overlay.pm:196 lib/RT/Scrip_Overlay.pm:433 lib/RT/Template_Overlay.pm:283 lib/RT/Template_Overlay.pm:87 lib/RT/Template_Overlay.pm:93 lib/RT/Ticket_Overlay.pm:1359 lib/RT/Ticket_Overlay.pm:1369 lib/RT/Ticket_Overlay.pm:1383 lib/RT/Ticket_Overlay.pm:1517 lib/RT/Ticket_Overlay.pm:1526 lib/RT/Ticket_Overlay.pm:1539 lib/RT/Ticket_Overlay.pm:1888 lib/RT/Ticket_Overlay.pm:2026 lib/RT/Ticket_Overlay.pm:2190 lib/RT/Ticket_Overlay.pm:2257 lib/RT/Ticket_Overlay.pm:2616 lib/RT/Ticket_Overlay.pm:2688 lib/RT/Ticket_Overlay.pm:2782 lib/RT/Ticket_Overlay.pm:2797 lib/RT/Ticket_Overlay.pm:2996 lib/RT/Ticket_Overlay.pm:3006 lib/RT/Ticket_Overlay.pm:3011 lib/RT/Ticket_Overlay.pm:3233 lib/RT/Ticket_Overlay.pm:3431 lib/RT/Ticket_Overlay.pm:3593 lib/RT/Ticket_Overlay.pm:3645 lib/RT/Ticket_Overlay.pm:3823 lib/RT/Transaction_Overlay.pm:466 lib/RT/Transaction_Overlay.pm:473 lib/RT/Transaction_Overlay.pm:502 lib/RT/Transaction_Overlay.pm:509 lib/RT/User_Overlay.pm:1079 lib/RT/User_Overlay.pm:1527 lib/RT/User_Overlay.pm:687 lib/RT/User_Overlay.pm:722 lib/RT/User_Overlay.pm:978
+msgid "Permission Denied"
+msgstr "權限不足"
+
+#: html/Edit/Rights/index.html:3
+msgid "Permission Settings"
+msgstr "權限設定"
+
+#: NOT FOUND IN SOURCE
+msgid "Permitted Queues:"
+msgstr "擁有權限表單列表:"
+
+#: NOT FOUND IN SOURCE
+msgid "Personal"
+msgstr "代理人群組"
+
+#: html/User/Elements/Tabs:34
+msgid "Personal Groups"
+msgstr "代理人群組"
+
+#: NOT FOUND IN SOURCE
+msgid "Personal Todo"
+msgstr "私人待辦事項"
+
+#: html/User/Groups/index.html:29 html/User/Groups/index.html:39
+msgid "Personal groups"
+msgstr "代理人群組"
+
+#: html/User/Elements/DelegateRights:36
+msgid "Personal groups:"
+msgstr "代理人群組:"
+
+#: html/Work/Preferences/Info:24
+msgid "PersonalHomepage"
+msgstr "個人首頁"
+
+#: NOT FOUND IN SOURCE
+msgid "Phone"
+msgstr "電話"
+
+#: html/Work/Delegates/Info:90 html/Work/Overview/Info:72
+msgid "Phone number"
+msgstr "電話號碼"
+
+#: html/Admin/Users/Modify.html:155 html/User/Prefs.html:48 html/Work/Preferences/Info:30
+msgid "Phone numbers"
+msgstr "電話號碼"
+
+#: html/Edit/Users/Add.html:3 html/Work/Delegates/Add.html:3 html/Work/Delegates/Info:34 html/Work/Tickets/ModifyPeople.html:2
+msgid "Pick"
+msgstr "挑選"
+
+#: NOT FOUND IN SOURCE
+msgid "Place of Departure"
+msgstr "出發地點"
+
+#: NOT FOUND IN SOURCE
+msgid "Placeholder"
+msgstr "尚未完工"
+
+#: html/Edit/Elements/PickUsers:31 html/Edit/Elements/PickUsers:44 html/Edit/Elements/SelectCustomFieldType:3 html/Work/Elements/SelectOwner:3 html/Work/Tickets/Elements/EditCustomField:183 html/Work/Tickets/Elements/EditCustomField:75 html/Work/Tickets/Elements/EditCustomFieldEntries:81 html/Work/Tickets/Elements/EditCustomFieldEntries:88
+msgid "Please Select"
+msgstr "請選擇"
+
+#: html/Edit/Elements/104Buttons:30
+msgid "Please check items to be deleted first."
+msgstr "請先選中要刪除的對象"
+
+#: NOT FOUND IN SOURCE
+msgid "Please select a group"
+msgstr "請選擇群組"
+
+#: NOT FOUND IN SOURCE
+msgid "Please select a queue's workflow"
+msgstr "請選擇表單流程"
+
+#: NOT FOUND IN SOURCE
+msgid "Please select role"
+msgstr "請選擇角色"
+
+#: NOT FOUND IN SOURCE
+msgid "Policy"
+msgstr "經營規章"
+
+#: NOT FOUND IN SOURCE
+msgid "Position"
+msgstr "職務"
+
+#: html/Edit/Users/Info:42
+msgid "Position Level"
+msgstr "職等"
+
+#: html/Edit/Elements/PickUsers:41 html/Edit/Global/UserRight/List:13 html/Edit/Global/UserRight/Top:23 html/Edit/Users/Add.html:41 html/Edit/Users/List:11 html/Edit/Users/Top:22 html/Work/Delegates/Add.html:26 html/Work/Delegates/Info:84 html/Work/Overview/Info:66
+msgid "Position Name"
+msgstr "職務名稱"
+
+#: html/Edit/Global/UserRight/List:14 html/Edit/Global/UserRight/Top:33 html/Edit/Users/List:12 html/Edit/Users/Top:32
+msgid "Position Number"
+msgstr "職務代碼"
+
+#: html/Edit/Users/Info:43
+msgid "Position Rank"
+msgstr "職級"
+
+#: NOT FOUND IN SOURCE
+msgid "Pref"
+msgstr "偏好"
+
+#: html/Edit/Elements/104Top:26 html/Elements/Header:51 html/Elements/Tabs:52 html/SelfService/Elements/Tabs:50 html/SelfService/Prefs.html:24 html/User/Prefs.html:24 html/User/Prefs.html:27 html/Work/Elements/Tab:43
+msgid "Preferences"
+msgstr "偏好"
+
+#: NOT FOUND IN SOURCE
+msgid "Prefs"
+msgstr "個人資訊"
+
+#: lib/RT/Action/Generic.pm:159
+msgid "Prepare Stubbed"
+msgstr "預備動作完畢"
+
+#: html/Ticket/Elements/Tabs:60
+msgid "Prev"
+msgstr "上一項"
+
+#: html/Search/Listing.html:43 html/Work/Search/index.html:20
+msgid "Previous page"
+msgstr "前一頁"
+
+#: NOT FOUND IN SOURCE
+msgid "Pri"
+msgstr "優先順位"
+
+#: lib/RT/ACE_Overlay.pm:132 lib/RT/ACE_Overlay.pm:207 lib/RT/ACE_Overlay.pm:551
+#. ($args{'PrincipalId'})
+msgid "Principal %1 not found."
+msgstr "找不到單位 %1。"
+
+#: html/Search/Elements/PickRestriction:53 html/Ticket/Create.html:153 html/Ticket/Elements/EditBasics:53 html/Ticket/Elements/ShowBasics:38 html/Work/Search/PickRestriction:34 lib/RT/Tickets_Overlay.pm:1042
+msgid "Priority"
+msgstr "優先順位"
+
+#: html/Admin/Elements/ModifyQueue:50 html/Admin/Queues/Modify.html:64
+msgid "Priority starts at"
+msgstr "優先順位起始值"
+
+#: etc/initialdata.zh:43 etc/initialdata:25
+msgid "Privileged"
+msgstr "內部成員"
+
+#: html/Admin/Users/Modify.html:270 html/User/Prefs.html:162 html/Work/Preferences/Info:158
+#. (loc_fuzzy($msg))
+msgid "Privileged status: %1"
+msgstr "內部成員狀態:%1"
+
+#: html/Admin/Users/index.html:61
+msgid "Privileged users"
+msgstr "內部成員"
+
+#: html/Work/Elements/SelectSearch:16
+msgid "Process Status"
+msgstr "處理狀態"
+
+#: etc/initialdata.zh:41 etc/initialdata.zh:47 etc/initialdata.zh:53 etc/initialdata.zh:77 etc/initialdata:23 etc/initialdata:29 etc/initialdata:35 etc/initialdata:59
+msgid "Pseudogroup for internal use"
+msgstr "內部用的虛擬群組"
+
+#: html/Work/Preferences/Info:68
+msgid "Public Info"
+msgstr "公開資訊"
+
+#: html/Work/Elements/104Header:88
+msgid "Public Service"
+msgstr "公共事務區"
+
+#: html/Edit/Users/Search.html:4
+msgid "Query"
+msgstr "查詢"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:166 html/Elements/MyRequests:29 html/Elements/MyTickets:29 html/Elements/Quicksearch:28 html/Search/Elements/PickRestriction:45 html/SelfService/Create.html:32 html/Ticket/Create.html:37 html/Ticket/Elements/EditBasics:63 html/Ticket/Elements/ShowBasics:42 html/User/Elements/DelegateRights:79 html/Work/Elements/MyApprovals:10 html/Work/Elements/MyRequests:17 html/Work/Elements/MyTickets:17 html/Work/Elements/Quicksearch:14 html/Work/Search/PickRestriction:26 lib/RT/Tickets_Overlay.pm:883
+msgid "Queue"
+msgstr "表單"
+
+#: html/Admin/Queues/CustomField.html:41 html/Admin/Queues/Scrip.html:49 html/Admin/Queues/Scrips.html:47 html/Admin/Queues/Templates.html:43 html/Admin/Queues/Workflows.html:44
+#. ($Queue)
+#. ($id)
+msgid "Queue %1 not found"
+msgstr "找不到表單 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue '%1' not found\\n"
+msgstr "找不到表單 '%1'\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Keyword Selections"
+msgstr "表單關鍵字選取"
+
+#: html/Admin/Elements/ModifyQueue:30 html/Admin/Queues/Modify.html:42 html/Edit/Queues/Basic/Top:12 html/Edit/Queues/Basic/index.html:36 html/Edit/Queues/Global:21 html/Edit/Queues/List:6 html/Edit/Users/Queue:10 html/Work/Delegates/List:6 html/Work/Elements/List:11 html/Work/Queues/List:5 html/Work/Tickets/Create.html:22 html/Work/Tickets/Elements/ShowBasics:6
+msgid "Queue Name"
+msgstr "表單名稱"
+
+#: html/Edit/Queues/List:8 html/Work/Elements/List:25 html/Work/Queues/List:7 html/Work/Tickets/Create.html:35 html/Work/Tickets/Elements/ShowBasics:19
+msgid "Queue Owner"
+msgstr "業務承辦人"
+
+#: html/Edit/Queues/Basic/Top:35
+msgid "Queue Priority"
+msgstr "優先等級"
+
+#: html/Edit/Global/GroupRight/Top:24 html/Edit/Global/UserRight/Top:43 html/Edit/Users/Queue:11 html/Edit/Users/index.html:124
+msgid "Queue Rights"
+msgstr "表單權限"
+
+#: NOT FOUND IN SOURCE
+msgid "Queue Scrips"
+msgstr "表單手續"
+
+#: html/Edit/Elements/Tab:38
+msgid "Queue Setup"
+msgstr "表單設定"
+
+#: lib/RT/Queue_Overlay.pm:264
+msgid "Queue already exists"
+msgstr "表單已存在"
+
+#: lib/RT/Queue_Overlay.pm:273 lib/RT/Queue_Overlay.pm:279
+msgid "Queue could not be created"
+msgstr "無法新增表單"
+
+#: html/Edit/Queues/autohandler:8 html/Ticket/Create.html:204 html/Work/Tickets/Create.html:185
+msgid "Queue could not be loaded."
+msgstr "無法載入表單"
+
+#: docs/design_docs/string-extraction-guide.txt:83 lib/RT/Queue_Overlay.pm:283
+msgid "Queue created"
+msgstr "表單新增完畢"
+
+#: html/Admin/Elements/ModifyWorkflow:32
+msgid "Queue is not specified."
+msgstr "未指定表單。"
+
+#: html/SelfService/Display.html:70 lib/RT/CustomField_Overlay.pm:97
+msgid "Queue not found"
+msgstr "找不到表單"
+
+#: html/Admin/Elements/Tabs:37 html/Admin/index.html:34
+msgid "Queues"
+msgstr "表單"
+
+#: html/Work/Elements/Quicksearch:10
+msgid "Quick Search"
+msgstr "表單現況"
+
+#: html/Elements/Quicksearch:24
+msgid "Quick search"
+msgstr "表單一覽"
+
+#: html/Elements/Login:44
+#. ($RT::VERSION)
+msgid "RT %1"
+msgstr "RT %1"
+
+#: docs/design_docs/string-extraction-guide.txt:70
+#. ($RT::VERSION, $RT::rtname)
+msgid "RT %1 for %2"
+msgstr "%2:RT %1 版"
+
+#: html/Elements/Footer:32
+#. ($RT::VERSION)
+msgid "RT %1 from <a href=\"http://bestpractical.com\">Best Practical Solutions, LLC</a>."
+msgstr "RT %1 版,<a href=\"http://bestpractical.com\">Best Practical Solutions 公司</a>出品。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1。版權所有 1996-%1 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT %1. Copyright 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+msgstr "RT %1。版權所有 1996-2002 Jesse Vincent <jesse\\@bestpractical.com>\\n"
+
+#: html/Admin/index.html:24 html/Admin/index.html:25
+msgid "RT Administration"
+msgstr "RT 管理頁面"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Authentication error."
+msgstr "RT 認證錯誤。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Bounce: %1"
+msgstr "RT 退信:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Configuration error"
+msgstr "RT 設定錯誤"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Critical error. Message not recorded!"
+msgstr "RT 致命錯誤。訊息未被紀錄。"
+
+#: html/Elements/Error:41 html/SelfService/Error.html:40
+msgid "RT Error"
+msgstr "RT 錯誤"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Received mail (%1) from itself."
+msgstr "RT 收到從自己寄出的郵件 (%1)。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Recieved mail (%1) from itself."
+msgstr "RT 收到從自己寄出的郵件 (%1)。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT Self Service / Closed Tickets"
+msgstr "RT 自助服務/已解決的申請單"
+
+#: html/index.html:24 html/index.html:27
+msgid "RT at a glance"
+msgstr "RT 一覽"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't authenticate you"
+msgstr "RT 無法認證你"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find requestor via its external database lookup"
+msgstr "RT 無法從外部資料庫查詢找到申請人資訊"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't find the queue: %1"
+msgstr "RT 找不到表單:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "RT couldn't validate this PGP signature. \\n"
+msgstr "RT 無法確認這個 PGP 簽章。\\n"
+
+#: html/Edit/Elements/104Header:7 html/Edit/Elements/104Top:20 html/Elements/PageLayout:85 html/Work/Elements/104Header:7
+#. ($RT::rtname)
+msgid "RT for %1"
+msgstr "%1 專用流程系統"
+
+#: NOT FOUND IN SOURCE
+msgid "RT for %1: %2"
+msgstr "%1 專用 RT 系統:%2"
+
+#: NOT FOUND IN SOURCE
+msgid "RT has proccessed your commands"
+msgstr "RT 已執行您的命令"
+
+#: html/Elements/Login:94
+#. ('2003')
+msgid "RT is &copy; Copyright 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is distributed under <a href=\"http://www.gnu.org/copyleft/gpl.html\">Version 2 of the GNU General Public License.</a>"
+msgstr "RT 版權所有 1996-%1 Jesse Vincent &lt;jesse@bestpractical.com&gt;。<br>本軟體依 <a href=\"http://www.gnu.org/copyleft/gpl.html\">GNU 通用公共授權第二版</a> 散佈。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT thinks this message may be a bounce"
+msgstr "RT 認為這可能是退信"
+
+#: NOT FOUND IN SOURCE
+msgid "RT will process this message as if it were unsigned.\\n"
+msgstr "RT 以未簽章方式處理這封郵件。\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "RT's email command mode requires PGP authentication.  Either you didn't sign your message, or your signature could not be verified."
+msgstr "RT 的電子郵件命令模式須要 PGP 認證。您可能沒有簽章,或是您的簽章無法辨識。"
+
+#: NOT FOUND IN SOURCE
+msgid "RT::Queue-Role"
+msgstr "表單運行角色"
+
+#: NOT FOUND IN SOURCE
+msgid "RT::System-Role"
+msgstr "系統運行角色"
+
+#: NOT FOUND IN SOURCE
+msgid "RT::Ticket-Role"
+msgstr "申請單運行角色"
+
+#: html/Work/Tickets/Elements/ShowTransaction:11
+msgid "RT_System"
+msgstr "系統訊息"
+
+#: html/Admin/Users/Modify.html:57 html/Admin/Users/Prefs.html:51 html/User/Prefs.html:43 html/Work/Preferences/Info:18
+msgid "Real Name"
+msgstr "真實姓名"
+
+#: html/Admin/Elements/ModifyUser:47
+msgid "RealName"
+msgstr "真實姓名"
+
+#: html/Work/Approvals/Display.html:27 html/Work/Tickets/Update.html:85
+msgid "Really reject this ticket?"
+msgstr "您確定要駁回這張申請單嗎?"
+
+#: html/Ticket/Create.html:184 html/Ticket/Elements/BulkLinks:50 html/Ticket/Elements/EditLinks:138 html/Ticket/Elements/EditLinks:93 html/Ticket/Elements/ShowLinks:70 html/Work/Search/BulkLinks:26
+msgid "Referred to by"
+msgstr "被參考"
+
+#: html/Elements/SelectLinkType:27 html/Ticket/Create.html:183 html/Ticket/Elements/BulkLinks:46 html/Ticket/Elements/EditLinks:134 html/Ticket/Elements/EditLinks:79 html/Ticket/Elements/ShowLinks:60 html/Work/Search/BulkLinks:22
+msgid "Refers to"
+msgstr "參考"
+
+#: NOT FOUND IN SOURCE
+msgid "RefersTo"
+msgstr "參考"
+
+#: NOT FOUND IN SOURCE
+msgid "Refine"
+msgstr "在結果範圍內查詢"
+
+#: html/Search/Elements/PickRestriction:26 html/Work/Search/PickRestriction:7
+msgid "Refine search"
+msgstr "調整查詢條件"
+
+#: html/Work/Overview/index.html:12
+msgid "Refresh"
+msgstr "更新"
+
+#: html/Elements/Refresh:35
+#. ($value/60)
+msgid "Refresh this page every %1 minutes."
+msgstr "每 %1 分鐘更新頁面"
+
+#: html/Ticket/Create.html:173 html/Ticket/Elements/ShowSummary:61 html/Ticket/ModifyAll.html:56
+msgid "Relationships"
+msgstr "關係"
+
+#: html/Edit/Elements/ListButtons:13
+msgid "Remove"
+msgstr "移除"
+
+#: html/Search/Bulk.html:97 html/Work/Search/Bulk.html:77
+msgid "Remove AdminCc"
+msgstr "移除管理員副本"
+
+#: html/Search/Bulk.html:93 html/Work/Search/Bulk.html:71
+msgid "Remove Cc"
+msgstr "移除副本"
+
+#: html/Search/Bulk.html:89 html/Work/Search/Bulk.html:65
+msgid "Remove Requestor"
+msgstr "移除申請人"
+
+#: html/Ticket/Elements/ShowTransaction:160 html/Ticket/Elements/Tabs:121 html/Work/Tickets/Display.html:31 html/Work/Tickets/Elements/ShowTransaction:108
+msgid "Reply"
+msgstr "回覆"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "Reply to tickets"
+msgstr "對申請單進行回覆"
+
+#: lib/RT/Queue_Overlay.pm:84
+msgid "ReplyToTicket"
+msgstr "回覆申請單"
+
+#: html/Edit/Users/Info:45
+msgid "Report to Duty"
+msgstr "上下班刷卡"
+
+#: html/Edit/Users/Info:33
+msgid "Reported on"
+msgstr "到職日期"
+
+#: etc/initialdata.zh:62 etc/initialdata:44 html/Ticket/Update.html:39 html/Work/Elements/List:21 html/Work/Elements/MyApprovals:12 html/Work/Elements/MyTickets:20 html/Work/Elements/SelectSearch:30 html/Work/Tickets/Elements/ShowBasics:62 lib/RT/ACE_Overlay.pm:86
+msgid "Requestor"
+msgstr "申請人"
+
+#: html/Edit/Global/Workflow/Owner.html:44
+msgid "Requestor Group's"
+msgstr "申請人所屬群組之"
+
+#: html/Search/Elements/PickRestriction:37 html/Work/Search/PickRestriction:17
+msgid "Requestor email address"
+msgstr "申請人電子郵件信箱位址"
+
+#: html/Edit/Global/Workflow/Owner.html:28
+msgid "Requestor's"
+msgstr "申請人所屬之第上"
+
+#: html/Work/Elements/List:23
+msgid "Requestor's Phone"
+msgstr "申請人電話"
+
+#: NOT FOUND IN SOURCE
+msgid "Requestor(s)"
+msgstr "申請人"
+
+#: NOT FOUND IN SOURCE
+msgid "RequestorAddresses"
+msgstr "申請人地址"
+
+#: html/SelfService/Create.html:40 html/Ticket/Create.html:55 html/Ticket/Elements/EditPeople:47 html/Ticket/Elements/ShowPeople:30
+msgid "Requestors"
+msgstr "申請人"
+
+#: html/Admin/Elements/ModifyQueue:60 html/Admin/Queues/Modify.html:74
+msgid "Requests should be due in"
+msgstr "申請單處理期限"
+
+#: html/Elements/Submit:61
+msgid "Reset"
+msgstr "重設"
+
+#: html/Admin/Users/Modify.html:158 html/User/Prefs.html:49 html/Work/Preferences/Info:32
+msgid "Residence"
+msgstr "住處"
+
+#: NOT FOUND IN SOURCE
+msgid "Resolution"
+msgstr "解決狀態"
+
+#: html/Ticket/Elements/Tabs:131 html/Work/Tickets/Display.html:34
+msgid "Resolve"
+msgstr "解決"
+
+#: html/Ticket/Update.html:136 html/Work/Tickets/Update.html:120
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Resolve ticket #%1 (%2)"
+msgstr "解決申請單 #%1 (%2)"
+
+#: etc/initialdata.zh:331 etc/initialdata:308 html/Elements/SelectDateType:27 lib/RT/Ticket_Overlay.pm:1188
+msgid "Resolved"
+msgstr "已解決"
+
+#: html/Search/Bulk.html:132 html/Ticket/ModifyAll.html:72 html/Ticket/Update.html:71 html/Work/Search/Bulk.html:84 html/Work/Tickets/Update.html:38
+msgid "Response to requestors"
+msgstr "回覆申請人"
+
+#: html/Edit/Users/Info:44
+msgid "Responsibility Type"
+msgstr "責任區分"
+
+#: html/Elements/ListActions:25
+msgid "Results"
+msgstr "結果"
+
+#: html/Search/Elements/PickRestriction:104 html/Work/Search/PickRestriction:84
+msgid "Results per page"
+msgstr "每頁列出幾筆結果"
+
+#: html/Admin/Elements/ModifyUser:32 html/Admin/Users/Modify.html:99 html/User/Prefs.html:71 html/Work/Preferences/Info:54
+msgid "Retype Password"
+msgstr "再次輸入密碼"
+
+#: NOT FOUND IN SOURCE
+msgid "Right %1 not found for %2  %3 in scope %4 (%5)\\n"
+msgstr "在 %4 (%5) 的範圍內找不到 %2 %3 的 %1 權限\\n"
+
+#: lib/RT/ACE_Overlay.pm:612
+msgid "Right Delegated"
+msgstr "權限代理完畢"
+
+#: lib/RT/ACE_Overlay.pm:302
+msgid "Right Granted"
+msgstr "權限設定完畢"
+
+#: lib/RT/ACE_Overlay.pm:160
+msgid "Right Loaded"
+msgstr "權限載入完畢"
+
+#: lib/RT/ACE_Overlay.pm:677 lib/RT/ACE_Overlay.pm:692
+msgid "Right could not be revoked"
+msgstr "無法撤消權限"
+
+#: html/User/Delegation.html:63
+msgid "Right not found"
+msgstr "找不到權限"
+
+#: lib/RT/ACE_Overlay.pm:542 lib/RT/ACE_Overlay.pm:637
+msgid "Right not loaded."
+msgstr "權限並未載入。"
+
+#: lib/RT/ACE_Overlay.pm:688
+msgid "Right revoked"
+msgstr "權限撤消完畢"
+
+#: html/Admin/Elements/UserTabs:40
+msgid "Rights"
+msgstr "權限及代理人"
+
+#: lib/RT/Interface/Web.pm:794 x:797
+#. ($object_type)
+msgid "Rights could not be granted for %1"
+msgstr "無法將權限賦予 %1"
+
+#: lib/RT/Interface/Web.pm:827 x:830
+#. ($object_type)
+msgid "Rights could not be revoked for %1"
+msgstr "無法撤消 %1 的權限"
+
+#: html/Edit/Groups/Member:55 html/Edit/Groups/Members/List:10
+msgid "Role Members"
+msgstr "角色成員"
+
+#: html/Edit/Groups/Member:37 html/Edit/Groups/Members/Add.html:13 html/Edit/Groups/Members/List:7 html/Edit/Groups/Roles/List:4 html/Edit/Groups/Roles/Top:7
+msgid "Role Name"
+msgstr "角色名稱"
+
+#: html/Admin/Global/GroupRights.html:50 html/Admin/Queues/GroupRights.html:52 html/Edit/Global/Workflow/Owner.html:55 html/Edit/Global/Workflow/Owner.html:81 html/Edit/Groups/Member:24
+msgid "Roles"
+msgstr "角色"
+
+#: NOT FOUND IN SOURCE
+msgid "RootApproval"
+msgstr "交由系統管理員簽核"
+
+#: html/Edit/Global/Workflow/Action:27
+msgid "Run Approval"
+msgstr "簽核執行"
+
+#: html/Edit/Global/Basic/Top:72
+msgid "SMTPDebug"
+msgstr "SMTP 偵錯紀錄"
+
+#: html/Edit/Global/Basic/Top:58
+msgid "SMTPFrom"
+msgstr "SMTP 寄件位址"
+
+#: html/Edit/Global/Basic/Top:56
+msgid "SMTPServer"
+msgstr "SMTP 伺服器"
+
+#: NOT FOUND IN SOURCE
+msgid "Sat"
+msgstr "星期六"
+
+#: lib/RT/Date.pm:393
+msgid "Sat."
+msgstr "星期六"
+
+#: html/Edit/Elements/104Buttons:72 html/Work/Preferences/index.html:35
+msgid "Save"
+msgstr "儲存"
+
+#: html/Admin/Queues/People.html:104 html/Ticket/Modify.html:38 html/Ticket/ModifyAll.html:93 html/Ticket/ModifyLinks.html:38 html/Ticket/ModifyPeople.html:37
+msgid "Save Changes"
+msgstr "儲存更改"
+
+#: NOT FOUND IN SOURCE
+msgid "Save changes"
+msgstr "儲存更改"
+
+#: html/Admin/Global/Scrip.html:48 html/Admin/Queues/Scrip.html:54
+#. ($QueueObj->id)
+#. ($ARGS{'id'})
+msgid "Scrip #%1"
+msgstr "手續 #%1"
+
+#: html/Edit/Global/Scrip/List:9 html/Edit/Global/Scrip/Top:41
+msgid "Scrip Action"
+msgstr "訊息通知動作"
+
+#: html/Edit/Global/Scrip/List:8 html/Edit/Global/Scrip/Top:15
+msgid "Scrip Condition"
+msgstr "訊息通知條件"
+
+#: lib/RT/Scrip_Overlay.pm:175
+msgid "Scrip Created"
+msgstr "手續新增完畢"
+
+#: html/Edit/Global/Scrip/List:7 html/Edit/Global/Scrip/Top:9
+msgid "Scrip Name"
+msgstr "訊息名稱"
+
+#: html/Admin/Elements/EditScrips:83
+msgid "Scrip deleted"
+msgstr "手續刪除完畢"
+
+#: html/Admin/Elements/QueueTabs:45 html/Admin/Elements/SystemTabs:32 html/Admin/Global/index.html:40
+msgid "Scrips"
+msgstr "手續"
+
+#: html/Edit/Global/autohandler:9 html/Edit/Queues/autohandler:20
+msgid "Scrips "
+msgstr "訊息通知"
+
+#: NOT FOUND IN SOURCE
+msgid "Scrips for %1\\n"
+msgstr "%1 的手續\\n"
+
+#: html/Admin/Queues/Scrips.html:33
+msgid "Scrips which apply to all queues"
+msgstr "適用於所有表單的手續"
+
+#: html/Edit/Elements/104Buttons:75 html/Elements/SimpleSearch:26 html/Search/Elements/PickRestriction:125 html/Ticket/Elements/Tabs:158 html/Work/Elements/Tab:45 html/Work/Search/PickRestriction:102
+msgid "Search"
+msgstr "查詢"
+
+#: NOT FOUND IN SOURCE
+msgid "Search Criteria"
+msgstr "查詢條件"
+
+#: html/Approvals/Elements/PendingMyApproval:38
+msgid "Search for approvals"
+msgstr "簽核單查詢"
+
+#: html/Edit/Global/Workflow/Owner.html:31
+msgid "Second-"
+msgstr "二"
+
+#: html/Edit/Users/Info:40
+msgid "Second-level Users"
+msgstr "二階主管員工"
+
+#: bin/rt-crontool:187
+msgid "Security:"
+msgstr "安全性:"
+
+#: lib/RT/Queue_Overlay.pm:66
+msgid "SeeQueue"
+msgstr "查閱表單"
+
+#: html/Edit/Elements/ListButtons:10
+msgid "Select All"
+msgstr "全選"
+
+#: html/Admin/Groups/index.html:39
+msgid "Select a group"
+msgstr "選擇群組"
+
+#: NOT FOUND IN SOURCE
+msgid "Select a queue"
+msgstr "選擇表單"
+
+#: html/Work/Queues/Select.html:8
+msgid "Select a queue to link to"
+msgstr "請選擇欲連結表單"
+
+#: html/Admin/Users/index.html:24 html/Admin/Users/index.html:27
+msgid "Select a user"
+msgstr "選擇使用者"
+
+#: html/Admin/Global/CustomField.html:37 html/Admin/Global/CustomFields.html:35
+msgid "Select custom field"
+msgstr "選擇自訂欄位"
+
+#: html/Admin/Elements/GroupTabs:51 html/User/Elements/GroupTabs:49
+msgid "Select group"
+msgstr "選擇群組"
+
+#: lib/RT/CustomField_Overlay.pm:421
+msgid "Select multiple values"
+msgstr "選擇多重項目"
+
+#: lib/RT/CustomField_Overlay.pm:418
+msgid "Select one value"
+msgstr "選擇單一項目"
+
+#: html/Admin/Elements/QueueTabs:66
+msgid "Select queue"
+msgstr "選擇表單"
+
+#: html/Admin/Global/Scrip.html:36 html/Admin/Global/Scrips.html:35 html/Admin/Queues/Scrip.html:39 html/Admin/Queues/Scrips.html:51
+msgid "Select scrip"
+msgstr "選擇手續"
+
+#: html/Admin/Global/Template.html:56 html/Admin/Global/Templates.html:35 html/Admin/Queues/Template.html:54 html/Admin/Queues/Templates.html:46
+msgid "Select template"
+msgstr "選擇範本"
+
+#: html/Admin/Elements/UserTabs:48
+msgid "Select user"
+msgstr "選擇使用者"
+
+#: html/Admin/Global/Workflow.html:57 html/Admin/Global/Workflows.html:36 html/Admin/Queues/Workflow.html:54 html/Admin/Queues/Workflows.html:47
+msgid "Select workflow"
+msgstr "選擇流程"
+
+#: NOT FOUND IN SOURCE
+msgid "SelectExternal"
+msgstr "系統選項"
+
+#: lib/RT/CustomField_Overlay.pm:35
+msgid "SelectMultiple"
+msgstr "多重選項"
+
+#: lib/RT/CustomField_Overlay.pm:34
+msgid "SelectSingle"
+msgstr "單一選項"
+
+#: html/Edit/Elements/PickUsers:85 html/Edit/Users/Add.html:78
+msgid "Selected users:"
+msgstr "新增對象:"
+
+#: NOT FOUND IN SOURCE
+msgid "Self Service"
+msgstr "自助服務"
+
+#: etc/initialdata.zh:131 etc/initialdata:113
+msgid "Send mail to all watchers"
+msgstr "寄信給所有視察員"
+
+#: etc/initialdata.zh:127 etc/initialdata:109
+msgid "Send mail to all watchers as a \"comment\""
+msgstr "以評論方式寄信給所有視察員"
+
+#: etc/initialdata.zh:122 etc/initialdata:104
+msgid "Send mail to requestors and Ccs"
+msgstr "寄信給申請人及副本收件人"
+
+#: etc/initialdata.zh:117 etc/initialdata:99
+msgid "Send mail to requestors and Ccs as a comment"
+msgstr "以評論方式寄信給申請人及副本收件人"
+
+#: etc/initialdata.zh:96 etc/initialdata:78
+msgid "Sends a message to the requestors"
+msgstr "寄信給申請人"
+
+#: etc/initialdata.zh:135 etc/initialdata.zh:139 etc/initialdata:117 etc/initialdata:121
+msgid "Sends mail to explicitly listed Ccs and Bccs"
+msgstr "寄信給特定的副本及密件副本收件人"
+
+#: etc/initialdata.zh:112 etc/initialdata:94
+msgid "Sends mail to the administrative Ccs"
+msgstr "寄信給管理員副本收件人"
+
+#: etc/initialdata.zh:108 etc/initialdata:90
+msgid "Sends mail to the administrative Ccs as a comment"
+msgstr "以評論寄信給管理員副本收件人"
+
+#: etc/initialdata.zh:100 etc/initialdata.zh:104 etc/initialdata:82 etc/initialdata:86
+msgid "Sends mail to the owner"
+msgstr "寄信給申請人"
+
+#: NOT FOUND IN SOURCE
+msgid "Sep"
+msgstr "九月"
+
+#: lib/RT/Date.pm:419
+msgid "Sep."
+msgstr "09"
+
+#: NOT FOUND IN SOURCE
+msgid "September"
+msgstr "九月"
+
+#: html/Edit/Users/Info:38
+msgid "Shift Type"
+msgstr "班別屬性"
+
+#: NOT FOUND IN SOURCE
+msgid "Show Results"
+msgstr "顯示結果"
+
+#: html/Approvals/Elements/PendingMyApproval:43
+msgid "Show approved requests"
+msgstr "顯示已批准的簽核單"
+
+#: html/Ticket/Create.html:143 html/Ticket/Create.html:33
+msgid "Show basics"
+msgstr "顯示基本資訊"
+
+#: html/Approvals/Elements/PendingMyApproval:44
+msgid "Show denied requests"
+msgstr "顯示已駁回的簽核單"
+
+#: html/Ticket/Create.html:143 html/Ticket/Create.html:33
+msgid "Show details"
+msgstr "顯示細節"
+
+#: html/Approvals/Elements/PendingMyApproval:42
+msgid "Show pending requests"
+msgstr "顯示待處理的簽核單"
+
+#: html/Approvals/Elements/PendingMyApproval:45
+msgid "Show requests awaiting other approvals"
+msgstr "顯示尚待他人批准的簽核單"
+
+#: lib/RT/Queue_Overlay.pm:80
+msgid "Show ticket private commentary"
+msgstr "顯示申請單內的私人評論"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "Show ticket summaries"
+msgstr "顯示申請單摘要"
+
+#: lib/RT/Queue_Overlay.pm:68
+msgid "ShowACL"
+msgstr "顯示權限清單"
+
+#: lib/RT/Queue_Overlay.pm:77
+msgid "ShowScrips"
+msgstr "顯示手續"
+
+#: lib/RT/Queue_Overlay.pm:74
+msgid "ShowTemplate"
+msgstr "顯示範本"
+
+#: lib/RT/Queue_Overlay.pm:78
+msgid "ShowTicket"
+msgstr "顯示申請單"
+
+#: lib/RT/Queue_Overlay.pm:80
+msgid "ShowTicketComments"
+msgstr "顯示申請單的評論"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Sign up as a ticket Requestor or ticket or queue Cc"
+msgstr "登記成為申請人或副本收件人"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "Sign up as a ticket or queue AdminCc"
+msgstr "登記成為管理員副本收件人"
+
+#: html/Admin/Elements/ModifyUser:38 html/Admin/Users/Modify.html:190 html/Admin/Users/Prefs.html:31 html/User/Prefs.html:111 html/Work/Preferences/Info:111
+msgid "Signature"
+msgstr "簽名檔"
+
+#: NOT FOUND IN SOURCE
+msgid "Signed in as %1"
+msgstr "使用者:%1"
+
+#: html/Admin/Elements/SelectSingleOrMultiple:25
+msgid "Single"
+msgstr "單一"
+
+#: html/Edit/Elements/104Top:21 html/Elements/Header:50
+msgid "Skip Menu"
+msgstr "略過選單"
+
+#: html/Admin/Elements/AddCustomFieldValue:27
+msgid "Sort"
+msgstr "順序"
+
+#: NOT FOUND IN SOURCE
+msgid "Sort key"
+msgstr "排序方式"
+
+#: html/Search/Elements/PickRestriction:108 html/Work/Search/PickRestriction:89
+msgid "Sort results by"
+msgstr "結果排序方式"
+
+#: NOT FOUND IN SOURCE
+msgid "SortOrder"
+msgstr "排序順序"
+
+#: html/Work/Elements/List:8 html/Work/Elements/MyApprovals:11
+msgid "Stage"
+msgstr "關卡"
+
+#: html/Edit/Global/Workflow/Top:8
+msgid "Stage Action"
+msgstr "關卡運行動作"
+
+#: html/Edit/Global/Workflow/Top:5
+msgid "Stage Condition"
+msgstr "關卡運行條件"
+
+#: html/Work/Elements/Quicksearch:17
+msgid "Stalled"
+msgstr "延宕"
+
+#: NOT FOUND IN SOURCE
+msgid "Start page"
+msgstr "首頁"
+
+#: html/Elements/SelectDateType:26 html/Ticket/Elements/EditDates:31 html/Ticket/Elements/ShowDates:34
+msgid "Started"
+msgstr "實際起始日"
+
+#: NOT FOUND IN SOURCE
+msgid "Started date '%1' could not be parsed"
+msgstr "無法解讀起始日期 '%1"
+
+#: html/Elements/SelectDateType:30 html/Ticket/Create.html:165 html/Ticket/Elements/EditDates:26 html/Ticket/Elements/ShowDates:30
+msgid "Starts"
+msgstr "應起始日"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts By"
+msgstr "應起始日"
+
+#: NOT FOUND IN SOURCE
+msgid "Starts date '%1' could not be parsed"
+msgstr "無法解讀起始日期 '%1"
+
+#: html/Admin/Elements/ModifyUser:81 html/Admin/Users/Modify.html:137 html/User/Prefs.html:93 html/Work/Preferences/Info:83
+msgid "State"
+msgstr "州"
+
+#: html/Elements/MyRequests:30 html/Elements/MyTickets:30 html/Search/Elements/PickRestriction:73 html/SelfService/Elements/MyRequests:28 html/SelfService/Update.html:30 html/Ticket/Create.html:41 html/Ticket/Elements/EditBasics:37 html/Ticket/Elements/ShowBasics:30 html/Ticket/Update.html:59 html/Work/Elements/List:15 html/Work/Elements/MyRequests:18 html/Work/Elements/MyTickets:18 html/Work/Search/PickRestriction:54 html/Work/Tickets/Update.html:22 lib/RT/Ticket_Overlay.pm:1182 lib/RT/Tickets_Overlay.pm:908
+msgid "Status"
+msgstr "現況"
+
+#: etc/initialdata.zh:317 etc/initialdata:294
+msgid "Status Change"
+msgstr "現況改變時"
+
+#: lib/RT/Transaction_Overlay.pm:528
+#. ($self->loc($self->OldValue), $self->loc($self->NewValue))
+msgid "Status changed from %1 to %2"
+msgstr "現況從 %1 改為 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "StatusChange"
+msgstr "現況改變時"
+
+#: html/Ticket/Elements/Tabs:146
+msgid "Steal"
+msgstr "強制更換承辦人"
+
+#: lib/RT/Queue_Overlay.pm:91
+msgid "Steal tickets"
+msgstr "強制承辦申請單"
+
+#: lib/RT/Queue_Overlay.pm:91
+msgid "StealTicket"
+msgstr "強制承辦申請單"
+
+#: lib/RT/Transaction_Overlay.pm:587
+#. ($Old->Name)
+msgid "Stolen from %1 "
+msgstr "被 %1 強制更換 "
+
+#: html/Edit/Groups/Member:69
+msgid "Subgroup"
+msgstr "子群組"
+
+#: html/Elements/MyRequests:28 html/Elements/MyTickets:28 html/Search/Bulk.html:135 html/Search/Elements/PickRestriction:42 html/SelfService/Create.html:56 html/SelfService/Elements/MyRequests:27 html/SelfService/Update.html:31 html/Ticket/Create.html:83 html/Ticket/Elements/EditBasics:27 html/Ticket/ModifyAll.html:78 html/Ticket/Update.html:75 html/Work/Elements/MyApprovals:9 html/Work/Elements/MyRequests:16 html/Work/Elements/MyTickets:16 html/Work/Search/Bulk.html:87 html/Work/Search/PickRestriction:22 html/Work/Tickets/Create.html:131 html/Work/Tickets/Elements/ShowBasics:36 lib/RT/Ticket_Overlay.pm:1178 lib/RT/Tickets_Overlay.pm:987
+msgid "Subject"
+msgstr "主題"
+
+#: docs/design_docs/string-extraction-guide.txt:89 lib/RT/Transaction_Overlay.pm:609
+#. ($self->Data)
+msgid "Subject changed to %1"
+msgstr "標題已改為 %1"
+
+#: html/Elements/Submit:58 html/Work/Search/Bulk.html:103
+msgid "Submit"
+msgstr "送出"
+
+#: NOT FOUND IN SOURCE
+msgid "Submit Workflow"
+msgstr "送出流程"
+
+#: lib/RT/Group_Overlay.pm:748
+msgid "Succeeded"
+msgstr "設定成功"
+
+#: NOT FOUND IN SOURCE
+msgid "Sun"
+msgstr "星期日"
+
+#: lib/RT/Date.pm:394
+msgid "Sun."
+msgstr "星期日"
+
+#: html/Edit/Users/System:17 lib/RT/System.pm:53
+msgid "SuperUser"
+msgstr "系統管理員"
+
+#: html/User/Elements/DelegateRights:76
+msgid "System"
+msgstr "系統"
+
+#: html/Edit/Global/Scrip/Top:18 html/Edit/Global/Scrip/Top:44
+msgid "System Defined"
+msgstr "系統定義"
+
+#: html/Admin/Elements/SelectRights:80 lib/RT/ACE_Overlay.pm:566 lib/RT/Interface/Web.pm:793 lib/RT/Interface/Web.pm:826 x:796 x:829
+msgid "System Error"
+msgstr "系統錯誤"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. Right not granted."
+msgstr "系統錯誤。設定權限失敗。"
+
+#: NOT FOUND IN SOURCE
+msgid "System Error. right not granted"
+msgstr "系統錯誤。設定權限失敗。"
+
+#: html/Edit/Users/index.html:122
+msgid "System Rights"
+msgstr "系統權限"
+
+#: lib/RT/ACE_Overlay.pm:615
+msgid "System error. Right not delegated."
+msgstr "系統錯誤。權限代理失敗。"
+
+#: lib/RT/ACE_Overlay.pm:145 lib/RT/ACE_Overlay.pm:222 lib/RT/ACE_Overlay.pm:305 lib/RT/ACE_Overlay.pm:897
+msgid "System error. Right not granted."
+msgstr "系統錯誤。設定權限失敗。"
+
+#: NOT FOUND IN SOURCE
+msgid "System error. Unable to grant rights."
+msgstr "系統錯誤。無法設定權限。"
+
+#: html/Admin/Global/GroupRights.html:34 html/Admin/Groups/GroupRights.html:36 html/Admin/Queues/GroupRights.html:35
+msgid "System groups"
+msgstr "系統群組"
+
+#: NOT FOUND IN SOURCE
+msgid "SystemInternal"
+msgstr "系統內部用"
+
+#: etc/initialdata.zh:59 etc/initialdata.zh:65 etc/initialdata.zh:71 etc/initialdata:41 etc/initialdata:47 etc/initialdata:53
+msgid "SystemRolegroup for internal use"
+msgstr "內部使用的系統角色群組"
+
+#: lib/RT/CurrentUser.pm:319
+msgid "TEST_STRING"
+msgstr "TEST_STRING"
+
+#: NOT FOUND IN SOURCE
+msgid "TabbedUI"
+msgstr "頁籤介面"
+
+#: html/Ticket/Elements/Tabs:142
+msgid "Take"
+msgstr "受理"
+
+#: lib/RT/Queue_Overlay.pm:89
+msgid "Take tickets"
+msgstr "自行承辦申請單"
+
+#: lib/RT/Queue_Overlay.pm:89
+msgid "TakeTicket"
+msgstr "自行承辦申請單"
+
+#: lib/RT/Transaction_Overlay.pm:573
+msgid "Taken"
+msgstr "已受理"
+
+#: html/Admin/Elements/EditScrip:80
+msgid "Template"
+msgstr "範本"
+
+#: html/Admin/Global/Template.html:90 html/Admin/Queues/Template.html:89
+#. ($TemplateObj->Id())
+msgid "Template #%1"
+msgstr "範本 #%1"
+
+#: html/Edit/Global/Template/List:9 html/Edit/Global/Template/Top:17
+msgid "Template Content"
+msgstr "通知範本內容"
+
+#: html/Edit/Global/Template/List:8 html/Edit/Global/Template/Top:13
+msgid "Template Description"
+msgstr "通知範本描述"
+
+#: html/Edit/Global/Template/List:7 html/Edit/Global/Template/Top:9
+msgid "Template Name"
+msgstr "通知範本名稱"
+
+#: html/Admin/Elements/EditTemplates:88
+msgid "Template deleted"
+msgstr "範本已刪除"
+
+#: lib/RT/Scrip_Overlay.pm:152
+msgid "Template not found"
+msgstr "找不到範本"
+
+#: NOT FOUND IN SOURCE
+msgid "Template not found\\n"
+msgstr "找不到範本\\n"
+
+#: lib/RT/Template_Overlay.pm:352
+msgid "Template parsed"
+msgstr "範本剖析完畢"
+
+#: html/Admin/Elements/QueueTabs:48 html/Admin/Elements/SystemTabs:35 html/Admin/Global/index.html:44
+msgid "Templates"
+msgstr "範本"
+
+#: html/Edit/Global/autohandler:8 html/Edit/Queues/autohandler:19
+msgid "Templates "
+msgstr "通知範本"
+
+#: NOT FOUND IN SOURCE
+msgid "Templates for %1\\n"
+msgstr "找不到 %1 的範本\\n"
+
+#: lib/RT/Interface/Web.pm:894 x:897
+msgid "That is already the current value"
+msgstr "已經是目前欄位的值"
+
+#: lib/RT/CustomField_Overlay.pm:242
+msgid "That is not a value for this custom field"
+msgstr "這不是該自訂欄位的值"
+
+#: lib/RT/Ticket_Overlay.pm:1899
+msgid "That is the same value"
+msgstr "同樣的值"
+
+#: lib/RT/ACE_Overlay.pm:287 lib/RT/ACE_Overlay.pm:596
+msgid "That principal already has that right"
+msgstr "這項單位已經擁有該權限"
+
+#: lib/RT/Queue_Overlay.pm:633
+#. ($args{'Type'})
+msgid "That principal is already a %1 for this queue"
+msgstr "這項單位已經是這個表單的 %1"
+
+#: lib/RT/Ticket_Overlay.pm:1433
+#. ($self->loc($args{'Type'}))
+msgid "That principal is already a %1 for this ticket"
+msgstr "這項單位已經是這份申請單的 %1"
+
+#: lib/RT/Queue_Overlay.pm:732
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this queue"
+msgstr "這項單位不是這個表單的 %1"
+
+#: lib/RT/Ticket_Overlay.pm:1550
+#. ($args{'Type'})
+msgid "That principal is not a %1 for this ticket"
+msgstr "這項單位不是這份申請單的 %1"
+
+#: lib/RT/Ticket_Overlay.pm:1895
+msgid "That queue does not exist"
+msgstr "此表單不存在"
+
+#: lib/RT/Ticket_Overlay.pm:3237
+msgid "That ticket has unresolved dependencies"
+msgstr "這份申請單有尚未解決的附屬申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "That user already has that right"
+msgstr "使用者已具有該項權限"
+
+#: lib/RT/Ticket_Overlay.pm:3047
+msgid "That user already owns that ticket"
+msgstr "該使用者已經承辦這份申請單"
+
+#: lib/RT/Ticket_Overlay.pm:3019
+msgid "That user does not exist"
+msgstr "使用者不存在"
+
+#: lib/RT/User_Overlay.pm:376
+msgid "That user is already privileged"
+msgstr "這名使用者已經是內部成員"
+
+#: lib/RT/User_Overlay.pm:397
+msgid "That user is already unprivileged"
+msgstr "這名使用者屬於非內部成員群組"
+
+#: lib/RT/User_Overlay.pm:389
+msgid "That user is now privileged"
+msgstr "使用者加入內部成員群組完畢"
+
+#: lib/RT/User_Overlay.pm:410
+msgid "That user is now unprivileged"
+msgstr "這名使用者已加入非內部成員群組"
+
+#: NOT FOUND IN SOURCE
+msgid "That user is now unprivilegedileged"
+msgstr "這名使用者已加入非內部成員群組"
+
+#: lib/RT/Ticket_Overlay.pm:3040
+msgid "That user may not own tickets in that queue"
+msgstr "使用者可能沒有承辦表單裡的申請單"
+
+#: lib/RT/Link_Overlay.pm:205
+msgid "That's not a numerical id"
+msgstr "這不是一個數字編號"
+
+#: html/SelfService/Display.html:31 html/Ticket/Create.html:149 html/Ticket/Elements/ShowSummary:27
+msgid "The Basics"
+msgstr "基本資訊"
+
+#: lib/RT/ACE_Overlay.pm:87
+msgid "The CC of a ticket"
+msgstr "申請單的副本收件人"
+
+#: lib/RT/ACE_Overlay.pm:88
+msgid "The administrative CC of a ticket"
+msgstr "申請單的管理員副本收件人"
+
+#: lib/RT/Ticket_Overlay.pm:2226
+msgid "The comment has been recorded"
+msgstr "評論已被紀錄"
+
+#: bin/rt-crontool:197
+msgid "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+msgstr "下列命令會找到 'general' 表單內所有運作中的申請單,並將其中 4 小時內未處理的申請單優先程度設為 99:"
+
+#: bin/rt-commit-handler:755 bin/rt-commit-handler:765
+msgid "The following commands were not proccessed:\\n\\n"
+msgstr "以下命令未被執行:\\n\\n"
+
+#: lib/RT/Interface/Web.pm:897 x:900
+msgid "The new value has been set."
+msgstr "新的欄位值設定完成。"
+
+#: lib/RT/ACE_Overlay.pm:85
+msgid "The owner of a ticket"
+msgstr "申請單的承辦人"
+
+#: lib/RT/ACE_Overlay.pm:86
+msgid "The requestor of a ticket"
+msgstr "申請單的申請人"
+
+#: html/Admin/Elements/EditUserComments:25
+msgid "These comments aren't generally visible to the user"
+msgstr "該使用者不會看見這些評論"
+
+#: html/Edit/Global/Workflow/Owner.html:32
+msgid "Third-"
+msgstr "三"
+
+#: NOT FOUND IN SOURCE
+msgid "This ticket %1 %2 (%3)\\n"
+msgstr "申請單 %1 %2 (%3)\\n"
+
+#: bin/rt-crontool:188
+msgid "This tool allows the user to run arbitrary perl modules from within RT."
+msgstr "此工具程式會讓使用者經由 RT 執行任意命令。"
+
+#: lib/RT/Transaction_Overlay.pm:251
+msgid "This transaction appears to have no content"
+msgstr "此項更動報告沒有內容"
+
+#: html/Ticket/Elements/ShowRequestor:46
+#. ($rows)
+msgid "This user's %1 highest priority tickets"
+msgstr "使用者送出的前 %1 份優先處理申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "This user's 25 highest priority tickets"
+msgstr "使用者送出的前 25 份優先處理申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "Thu"
+msgstr "星期四"
+
+#: lib/RT/Date.pm:391
+msgid "Thu."
+msgstr "星期四"
+
+#: html/Admin/Elements/ModifyTemplateAsWorkflow:163
+msgid "Ticket"
+msgstr "申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1  %2"
+msgstr "申請單 # %1 %2"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket # %1 Jumbo update: %2"
+msgstr "更新申請單 # %1 的全部資訊:%2"
+
+#: html/Ticket/ModifyAll.html:24 html/Ticket/ModifyAll.html:28
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket #%1 Jumbo update: %2"
+msgstr "更新申請單 #%1 的全部資訊:%2"
+
+#: html/Approvals/Elements/ShowDependency:45
+#. ($link->BaseObj->Id, $link->BaseObj->Subject)
+msgid "Ticket #%1: %2"
+msgstr "申請單 #%1: %2"
+
+#: lib/RT/Ticket_Overlay.pm:605 lib/RT/Ticket_Overlay.pm:626
+#. ($self->Id, $QueueObj->Name)
+msgid "Ticket %1 created in queue '%2'"
+msgstr "申請單 #%1 成功新增於 '%2' 表單"
+
+#: bin/rt-commit-handler:759
+#. ($Ticket->Id)
+msgid "Ticket %1 loaded\\n"
+msgstr "載入申請單 %1\\n"
+
+#: html/Search/Bulk.html:212 html/Work/Search/Bulk.html:169
+#. ($Ticket->Id,$_)
+msgid "Ticket %1: %2"
+msgstr "申請單 %1:%2"
+
+#: html/Edit/Queues/Basic/Top:28 html/Edit/Queues/List:16 html/Work/Queues/List:9
+msgid "Ticket Due"
+msgstr "表單處理期限"
+
+#: html/Ticket/History.html:24 html/Ticket/History.html:27
+#. ($Ticket->Id, $Ticket->Subject)
+msgid "Ticket History # %1 %2"
+msgstr "申請單處理紀錄 # %1 %2"
+
+#: html/Work/Elements/List:6
+msgid "Ticket ID"
+msgstr "單號"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket Id"
+msgstr "申請單編號"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket Processing Due"
+msgstr "表單運行期限"
+
+#: etc/initialdata.zh:332 etc/initialdata:309
+msgid "Ticket Resolved"
+msgstr "申請單已解決"
+
+#: html/Edit/Queues/Basic/Top:18 html/Edit/Queues/Category/List:6 html/Edit/Queues/Category/Top:7 html/Edit/Queues/List:7 html/Edit/Queues/index.html:31 html/Work/Delegates/List:7 html/Work/Delegates/index.html:11 html/Work/Elements/List:12 html/Work/Elements/SelectSearch:9 html/Work/Queues/List:6 html/Work/Queues/Select.html:12 html/Work/Queues/index.html:11 html/Work/Tickets/Create.html:44 html/Work/Tickets/Elements/ShowBasics:34
+msgid "Ticket Type"
+msgstr "表單種類"
+
+#: html/Search/Elements/PickRestriction:62 html/Work/Search/PickRestriction:43
+msgid "Ticket attachment"
+msgstr "申請單附件"
+
+#: lib/RT/Tickets_Overlay.pm:1166
+msgid "Ticket content"
+msgstr "申請單內容"
+
+#: lib/RT/Tickets_Overlay.pm:1212
+msgid "Ticket content type"
+msgstr "申請單內容類別"
+
+#: lib/RT/Ticket_Overlay.pm:496 lib/RT/Ticket_Overlay.pm:505 lib/RT/Ticket_Overlay.pm:515 lib/RT/Ticket_Overlay.pm:615
+msgid "Ticket could not be created due to an internal error"
+msgstr "內部錯誤,無法新增申請單"
+
+#: lib/RT/Transaction_Overlay.pm:520
+msgid "Ticket created"
+msgstr "申請單新增完畢"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket creation failed"
+msgstr "申請單新增失敗"
+
+#: lib/RT/Transaction_Overlay.pm:525
+msgid "Ticket deleted"
+msgstr "申請單刪除完畢"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket id not found"
+msgstr "找不到申請單編號"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket killed"
+msgstr "申請單刪除完畢"
+
+#: NOT FOUND IN SOURCE
+msgid "Ticket not found"
+msgstr "找不到申請單"
+
+#: etc/initialdata.zh:318 etc/initialdata:295
+msgid "Ticket status changed"
+msgstr "申請單現況已改變"
+
+#: html/Ticket/Update.html:38
+msgid "Ticket watchers"
+msgstr "申請單視察員"
+
+#: html/Elements/Tabs:46
+msgid "Tickets"
+msgstr "申請單"
+
+#: lib/RT/Tickets_Overlay.pm:1383
+#. ($self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'}))
+msgid "Tickets %1 %2"
+msgstr "申請單 %1 %2"
+
+#: lib/RT/Tickets_Overlay.pm:1348
+#. ($self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'}))
+msgid "Tickets %1 by %2"
+msgstr "申請單 %1 (%2)"
+
+#: NOT FOUND IN SOURCE
+msgid "Tickets I own"
+msgstr "待處理的申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "Tickets I requested"
+msgstr "送出的申請單"
+
+#: html/Elements/ViewUser:25
+#. ($name)
+msgid "Tickets from %1"
+msgstr "%1 的申請單"
+
+#: html/Approvals/Elements/ShowDependency:26
+msgid "Tickets which depend on this approval:"
+msgstr "批准之後,可接續處理:"
+
+#: html/Ticket/Create.html:156 html/Ticket/Elements/EditBasics:47
+msgid "Time Left"
+msgstr "剩餘時間"
+
+#: html/Ticket/Create.html:155 html/Ticket/Elements/EditBasics:42
+msgid "Time Worked"
+msgstr "處理時間"
+
+#: lib/RT/Tickets_Overlay.pm:1139
+msgid "Time left"
+msgstr "剩餘時間"
+
+#: html/Elements/Footer:36
+msgid "Time to display"
+msgstr "顯示時間"
+
+#: lib/RT/Tickets_Overlay.pm:1115
+msgid "Time worked"
+msgstr "已處理時間"
+
+#: NOT FOUND IN SOURCE
+msgid "TimeLeft"
+msgstr "剩餘時間"
+
+#: lib/RT/Ticket_Overlay.pm:1183
+msgid "TimeWorked"
+msgstr "已處理時間"
+
+#: bin/rt-commit-handler:401
+msgid "To generate a diff of this commit:"
+msgstr "產生這次更動的差異檔:"
+
+#: bin/rt-commit-handler:390
+msgid "To generate a diff of this commit:\\n"
+msgstr "產生這次更動的差異檔:\\n"
+
+#: lib/RT/Ticket_Overlay.pm:1186
+msgid "Told"
+msgstr "告知日期"
+
+#: html/Edit/Elements/Page:46
+msgid "Total"
+msgstr "頁"
+
+#: etc/initialdata.zh:239 etc/initialdata:237
+msgid "Transaction"
+msgstr "更動"
+
+#: lib/RT/Transaction_Overlay.pm:640
+#. ($self->Data)
+msgid "Transaction %1 purged"
+msgstr "清除更動報告 %1"
+
+#: lib/RT/Transaction_Overlay.pm:177
+msgid "Transaction Created"
+msgstr "更動報告已新增"
+
+#: lib/RT/Transaction_Overlay.pm:88
+msgid "Transaction->Create couldn't, as you didn't specify a ticket id"
+msgstr "未指定申請單編號,無法新增更動"
+
+#: lib/RT/Transaction_Overlay.pm:699
+msgid "Transactions are immutable"
+msgstr "不可更改更動報告"
+
+#: NOT FOUND IN SOURCE
+msgid "Trying to delete a right: %1"
+msgstr "試圖刪除某項權限:%1"
+
+#: NOT FOUND IN SOURCE
+msgid "Tue"
+msgstr "星期二"
+
+#: lib/RT/Date.pm:389
+msgid "Tue."
+msgstr "星期二"
+
+#: html/Admin/Elements/EditCustomField:43 html/Admin/Elements/ModifyTemplateAsWorkflow:135 html/Ticket/Elements/AddWatchers:32 html/Ticket/Elements/AddWatchers:43 html/Ticket/Elements/AddWatchers:53 lib/RT/Ticket_Overlay.pm:1184 lib/RT/Tickets_Overlay.pm:959
+msgid "Type"
+msgstr "類別"
+
+#: lib/RT/ScripCondition_Overlay.pm:103
+msgid "Unimplemented"
+msgstr "尚無實作"
+
+#: html/Admin/Users/Modify.html:67
+msgid "Unix login"
+msgstr "外部系統登入帳號"
+
+#: html/Admin/Elements/ModifyUser:61
+msgid "UnixUsername"
+msgstr "外部系統登入帳號"
+
+#: lib/RT/Attachment_Overlay.pm:266 lib/RT/Attachment_Overlay.pm:298
+#. ($self->ContentEncoding)
+msgid "Unknown ContentEncoding %1"
+msgstr "不可解的內容文字編碼方式 %1"
+
+#: html/Elements/SelectResultsPerPage:36
+msgid "Unlimited"
+msgstr "全數顯示"
+
+#: etc/initialdata.zh:50 etc/initialdata:32
+msgid "Unprivileged"
+msgstr "非內部成員"
+
+#: lib/RT/Transaction_Overlay.pm:569
+msgid "Untaken"
+msgstr "未被受理"
+
+#: html/Edit/Elements/Page:13 html/Edit/Elements/Page:15
+msgid "Up"
+msgstr "上一頁"
+
+#: html/Elements/MyTickets:63 html/Search/Bulk.html:32 html/Work/Elements/MyTickets:82 html/Work/Search/Bulk.html:10 html/Work/Tickets/Elements/EditCustomFieldEntries:97
+msgid "Update"
+msgstr "處理"
+
+#: html/Admin/Users/Prefs.html:61
+msgid "Update ID"
+msgstr "更新編號"
+
+#: html/Search/Bulk.html:129 html/Ticket/ModifyAll.html:65 html/Ticket/Update.html:65 html/Work/Search/Bulk.html:81 html/Work/Tickets/Update.html:32
+msgid "Update Type"
+msgstr "更新類別"
+
+#: html/Search/Listing.html:60 html/Work/Search/index.html:32
+msgid "Update all these tickets at once"
+msgstr "整批更新申請單"
+
+#: html/Admin/Users/Prefs.html:48
+msgid "Update email"
+msgstr "更新電子郵件信箱"
+
+#: html/Admin/Users/Prefs.html:54
+msgid "Update name"
+msgstr "更新帳號"
+
+#: lib/RT/Interface/Web.pm:409 x:412
+msgid "Update not recorded."
+msgstr "更新未被記錄"
+
+#: html/Search/Bulk.html:80 html/Work/Search/Bulk.html:52
+msgid "Update selected tickets"
+msgstr "更新選擇的申請單"
+
+#: html/Admin/Users/Prefs.html:35
+msgid "Update signature"
+msgstr "更新簽章"
+
+#: html/Ticket/ModifyAll.html:62
+msgid "Update ticket"
+msgstr "更新申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "Update ticket # %1"
+msgstr "更新申請單 # %1"
+
+#: html/SelfService/Update.html:24 html/SelfService/Update.html:46
+#. ($Ticket->id)
+msgid "Update ticket #%1"
+msgstr "更新申請單 #%1"
+
+#: html/Ticket/Update.html:138 html/Work/Tickets/Update.html:122
+#. ($Ticket->id, $Ticket->Subject)
+msgid "Update ticket #%1 (%2)"
+msgstr "更新申請單 #%1 (%2)"
+
+#: lib/RT/Interface/Web.pm:407 x:410
+msgid "Update type was neither correspondence nor comment."
+msgstr "更新的內容並非申請單回覆也不是評論"
+
+#: html/Elements/SelectDateType:32 html/Ticket/Elements/ShowDates:50 lib/RT/Ticket_Overlay.pm:1187
+msgid "Updated"
+msgstr "前次更新"
+
+#: html/Work/Preferences/index.html:15
+msgid "User"
+msgstr "使用者"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 %2: %3\\n"
+msgstr "使用者 %1 %2:%3\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User %1 Password: %2\\n"
+msgstr "使用者 %1 密碼:%2\\n"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found"
+msgstr "找不到使用者 '%1'"
+
+#: NOT FOUND IN SOURCE
+msgid "User '%1' not found\\n"
+msgstr "找不到使用者 '%1'\\n"
+
+#: etc/initialdata.zh:142 etc/initialdata.zh:209 etc/initialdata:124 etc/initialdata:191
+msgid "User Defined"
+msgstr "使用者自訂"
+
+#: html/Admin/Users/Prefs.html:58 html/Edit/Users/List:13 html/Edit/Users/Top:42
+msgid "User ID"
+msgstr "使用者 ID"
+
+#: html/Elements/SelectUsers:25
+msgid "User Id"
+msgstr "使用者 ID"
+
+#: html/Edit/Elements/PickUsers:12 html/Edit/Global/UserRight/List:7 html/Edit/Global/UserRight/Top:9 html/Edit/Users/Add.html:13 html/Edit/Users/List:5 html/Edit/Users/Search.html:23 html/Edit/Users/Top:8 html/Work/Delegates/Info:60 html/Work/Tickets/Cc:10
+msgid "User Number"
+msgstr "員工編號"
+
+#: html/Admin/Elements/GroupTabs:46 html/Admin/Elements/QueueTabs:59 html/Admin/Elements/SystemTabs:46 html/Admin/Global/index.html:58 html/Edit/Global/autohandler:11 html/Edit/Queues/autohandler:22
+msgid "User Rights"
+msgstr "使用者權限"
+
+#: html/Edit/Elements/Tab:34
+msgid "User Setup"
+msgstr "使用者設定"
+
+#: html/Edit/Users/Info:37
+msgid "User Shift"
+msgstr "員工班別"
+
+#: html/Admin/Users/Modify.html:225
+#. ($msg)
+msgid "User could not be created: %1"
+msgstr "無法新增使用者:%1"
+
+#: lib/RT/User_Overlay.pm:321
+msgid "User created"
+msgstr "使用者新增完畢"
+
+#: html/Admin/Global/GroupRights.html:66 html/Admin/Groups/GroupRights.html:53 html/Admin/Queues/GroupRights.html:68
+msgid "User defined groups"
+msgstr "使用者定義的群組"
+
+#: lib/RT/User_Overlay.pm:575 lib/RT/User_Overlay.pm:592
+msgid "User loaded"
+msgstr "已載入使用者"
+
+#: NOT FOUND IN SOURCE
+msgid "User notified"
+msgstr "已通知使用者"
+
+#: html/Admin/Users/Prefs.html:24 html/Admin/Users/Prefs.html:28
+msgid "User view"
+msgstr "使用者私人資料"
+
+#: NOT FOUND IN SOURCE
+msgid "UserDefined"
+msgstr "使用者自定"
+
+#: html/Admin/Users/Modify.html:47 html/Elements/Login:51 html/Ticket/Elements/AddWatchers:34
+msgid "Username"
+msgstr "帳號"
+
+#: html/Admin/Elements/SelectNewGroupMembers:25 html/Admin/Elements/Tabs:31 html/Admin/Groups/Members.html:54 html/Admin/Queues/People.html:67 html/Admin/index.html:28 html/User/Groups/Members.html:57 html/Work/Tickets/Elements/ShowTransaction:8
+msgid "Users"
+msgstr "使用者"
+
+#: html/Admin/Users/index.html:64
+msgid "Users matching search criteria"
+msgstr "符合查詢條件的使用者"
+
+#: html/Search/Elements/PickRestriction:50 html/Work/Search/PickRestriction:31
+msgid "ValueOfQueue"
+msgstr "選擇表單"
+
+#: html/Admin/Elements/EditCustomField:56
+msgid "Values"
+msgstr "欄位值"
+
+#: lib/RT/Queue_Overlay.pm:81
+msgid "Watch"
+msgstr "視察"
+
+#: lib/RT/Queue_Overlay.pm:82
+msgid "WatchAsAdminCc"
+msgstr "以管理員副本收件人身份視察"
+
+#: NOT FOUND IN SOURCE
+msgid "Watcher loaded"
+msgstr "成功載入視察員資訊"
+
+#: html/Admin/Elements/QueueTabs:41
+msgid "Watchers"
+msgstr "視察員"
+
+#: html/Admin/Elements/ModifyUser:55
+msgid "WebEncoding"
+msgstr "網頁文字編碼方式"
+
+#: NOT FOUND IN SOURCE
+msgid "Wed"
+msgstr "星期三"
+
+#: lib/RT/Date.pm:390
+msgid "Wed."
+msgstr "星期三"
+
+#: etc/initialdata.zh:533 etc/initialdata:503 etc/upgrade/2.1.71:161 html/Edit/Elements/CreateApprovalsQueue:135
+msgid "When a ticket has been approved by all approvers, add correspondence to the original ticket"
+msgstr "當申請單通過所有簽核後,將此訊息回覆到原申請單"
+
+#: etc/initialdata.zh:497 etc/initialdata:467 etc/upgrade/2.1.71:135 html/Edit/Elements/CreateApprovalsQueue:107
+msgid "When a ticket has been approved by any approver, add correspondence to the original ticket"
+msgstr "當申請單通過某項簽核後,將此訊息回覆到原申請單"
+
+#: etc/initialdata.zh:156 etc/initialdata:138
+msgid "When a ticket is created"
+msgstr "新增申請單時"
+
+#: etc/initialdata.zh:428 etc/initialdata:400 etc/upgrade/2.1.71:79 html/Edit/Elements/CreateApprovalsQueue:51
+msgid "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval"
+msgstr "簽核單新增之後,通知應受理的承辦人及管理員副本收件人"
+
+#: etc/initialdata.zh:161 etc/initialdata:143
+msgid "When anything happens"
+msgstr "當任何事情發生時"
+
+#: etc/initialdata.zh:202 etc/initialdata:184
+msgid "Whenever a ticket is resolved"
+msgstr "當申請單解決時"
+
+#: etc/initialdata.zh:188 etc/initialdata:170
+msgid "Whenever a ticket's owner changes"
+msgstr "當申請單更換承辦人時"
+
+#: etc/initialdata.zh:196 etc/initialdata:178
+msgid "Whenever a ticket's queue changes"
+msgstr "當申請單更換表單時"
+
+#: etc/initialdata.zh:180 etc/initialdata:162
+msgid "Whenever a ticket's status changes"
+msgstr "當申請單更新現況時"
+
+#: etc/initialdata.zh:210 etc/initialdata:192
+msgid "Whenever a user-defined condition occurs"
+msgstr "當使用者自訂的情況發生時"
+
+#: etc/initialdata.zh:174 etc/initialdata:156
+msgid "Whenever comments come in"
+msgstr "當評論送達時"
+
+#: etc/initialdata.zh:167 etc/initialdata:149
+msgid "Whenever correspondence comes in"
+msgstr "當回覆送達時"
+
+#: html/Admin/Users/Modify.html:163 html/User/Prefs.html:51 html/Work/Preferences/Info:34
+msgid "Work"
+msgstr "公司"
+
+#: html/Admin/Elements/ModifyUser:69
+msgid "WorkPhone"
+msgstr "公司電話"
+
+#: html/Ticket/Elements/ShowBasics:34 html/Ticket/Update.html:64
+msgid "Worked"
+msgstr "處理時間"
+
+#: html/Admin/Global/Workflow.html:91 html/Admin/Queues/Workflow.html:89
+#. ($WorkflowObj->Id())
+msgid "Workflow #%1"
+msgstr "流程 #%1"
+
+#: html/Edit/Global/Workflow/List:15
+msgid "Workflow Begin"
+msgstr "流程開始"
+
+#: html/Edit/Global/Workflow/List:20
+msgid "Workflow End"
+msgstr "流程結束"
+
+#: html/Admin/Elements/EditWorkflows:90
+msgid "Workflow deleted"
+msgstr "流程已刪除"
+
+#: html/Edit/Global/autohandler:10 html/Edit/Queues/autohandler:21
+msgid "Workflows"
+msgstr "流程"
+
+#: html/Edit/Global/Basic/Top:25
+msgid "Yes"
+msgstr "是"
+
+#: lib/RT/Ticket_Overlay.pm:3150
+msgid "You already own this ticket"
+msgstr "您已是這份申請單的承辦人"
+
+#: html/autohandler:122
+msgid "You are not an authorized user"
+msgstr "您不是被授權的使用者"
+
+#: lib/RT/Ticket_Overlay.pm:3032
+msgid "You can only reassign tickets that you own or that are unowned"
+msgstr "祇能重新指派您所承辦或是沒有承辦人的申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "You don't have permission to view that ticket.\\n"
+msgstr "您沒有看那份申請單的權限。\\n"
+
+#: docs/design_docs/string-extraction-guide.txt:47
+#. ($num, $queue)
+msgid "You found %1 tickets in queue %2"
+msgstr "您會在表單 %2 找到 %1 的申請單"
+
+#: html/NoAuth/Logout.html:30
+msgid "You have been logged out of RT."
+msgstr "您已登出 RT。"
+
+#: html/SelfService/Display.html:77
+msgid "You have no permission to create tickets in that queue."
+msgstr "您沒有在該表單新增申請單的權限。"
+
+#: lib/RT/Ticket_Overlay.pm:1908
+msgid "You may not create requests in that queue."
+msgstr "您不能在該表單中提出申請。"
+
+#: html/Edit/Global/Basic/Top:38
+msgid "You need to restart the Request Tracker service for saved changes to take effect."
+msgstr "您必須重新啟動 Request Tracker 服務,儲存的更動纔會生效。"
+
+#: html/NoAuth/Logout.html:34
+msgid "You're welcome to login again"
+msgstr "歡迎下次再來"
+
+#: NOT FOUND IN SOURCE
+msgid "Your %1 requests"
+msgstr "您提出的 %1 申請單"
+
+#: NOT FOUND IN SOURCE
+msgid "Your RT administrator has misconfigured the mail aliases which invoke RT"
+msgstr "RT 管理員可能設錯了由 RT 寄出的郵件收件人標頭檔"
+
+#: etc/initialdata.zh:514 etc/initialdata:484 etc/upgrade/2.1.71:146 html/Edit/Elements/CreateApprovalsQueue:119
+msgid "Your request has been approved by %1. Other approvals may still be pending."
+msgstr "申請單已由 %1 批准。可能還有其他待簽核的步驟。"
+
+#: etc/initialdata.zh:552 etc/initialdata:522 etc/upgrade/2.1.71:180 html/Edit/Elements/CreateApprovalsQueue:154
+msgid "Your request has been approved."
+msgstr "您的申請單已完成簽核程序。"
+
+#: NOT FOUND IN SOURCE
+msgid "Your request was rejected"
+msgstr "您的申請單已被駁回"
+
+#: etc/initialdata.zh:455
+msgid "Your request was rejected by %1."
+msgstr "您的申請單已被 %1 駁回。"
+
+#: etc/initialdata:427 etc/upgrade/2.1.71:101 html/Edit/Elements/CreateApprovalsQueue:73
+msgid "Your request was rejected."
+msgstr "您的申請單已被駁回。"
+
+#: html/autohandler:144
+msgid "Your username or password is incorrect"
+msgstr "您的帳號或密碼有誤"
+
+#: html/Admin/Elements/ModifyUser:83 html/Admin/Users/Modify.html:143 html/User/Prefs.html:95 html/Work/Preferences/Info:85
+msgid "Zip"
+msgstr "郵遞區號"
+
+#: NOT FOUND IN SOURCE
+msgid "[no subject]"
+msgstr "[沒有標題]"
+
+#: NOT FOUND IN SOURCE
+msgid "ago"
+msgstr "過期"
+
+#: NOT FOUND IN SOURCE
+msgid "alert"
+msgstr "急訊"
+
+#: html/User/Elements/DelegateRights:58
+#. ($right->PrincipalObj->Object->SelfDescription)
+msgid "as granted to %1"
+msgstr "權限同 %1"
+
+#: html/SelfService/Closed.html:27
+msgid "closed"
+msgstr "已解決"
+
+#: html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:33
+msgid "contains"
+msgstr "包含"
+
+#: html/Elements/SelectAttachmentField:25
+msgid "content"
+msgstr "內容"
+
+#: html/Elements/SelectAttachmentField:26
+msgid "content-type"
+msgstr "類型"
+
+#: lib/RT/Ticket_Overlay.pm:2295
+msgid "correspondence (probably) not sent"
+msgstr "申請單回覆(可能)未送出"
+
+#: lib/RT/Ticket_Overlay.pm:2305
+msgid "correspondence sent"
+msgstr "申請單回覆已送出"
+
+#: NOT FOUND IN SOURCE
+msgid "critical"
+msgstr "嚴重"
+
+#: html/Admin/Elements/ModifyQueue:62 html/Admin/Queues/Modify.html:76 html/Edit/Queues/Basic/Top:31 html/Edit/Queues/List:18 html/Work/Queues/List:11 lib/RT/Date.pm:319
+msgid "days"
+msgstr "天"
+
+#: NOT FOUND IN SOURCE
+msgid "dead"
+msgstr "拒絕處理"
+
+#: NOT FOUND IN SOURCE
+msgid "debug"
+msgstr "偵錯"
+
+#: html/Search/Listing.html:74
+msgid "delete"
+msgstr "刪除"
+
+#: lib/RT/Queue_Overlay.pm:62
+msgid "deleted"
+msgstr "已刪除"
+
+#: html/Search/Elements/PickRestriction:67 html/Work/Search/PickRestriction:47
+msgid "does not match"
+msgstr "不符合"
+
+#: html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:34
+msgid "doesn't contain"
+msgstr "不包含"
+
+#: NOT FOUND IN SOURCE
+msgid "emergency"
+msgstr "危難"
+
+#: html/Elements/SelectEqualityOperator:37
+msgid "equal to"
+msgstr "等於"
+
+#: NOT FOUND IN SOURCE
+msgid "error"
+msgstr "錯誤"
+
+#: NOT FOUND IN SOURCE
+msgid "false"
+msgstr "假"
+
+#: html/Elements/SelectAttachmentField:27
+msgid "filename"
+msgstr "檔名"
+
+#: html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectEqualityOperator:37
+msgid "greater than"
+msgstr "大於"
+
+#: lib/RT/Group_Overlay.pm:193
+#. ($self->Name)
+msgid "group '%1'"
+msgstr "群組 '%1'"
+
+#: lib/RT/Date.pm:315
+msgid "hours"
+msgstr "小時"
+
+#: NOT FOUND IN SOURCE
+msgid "id"
+msgstr "編號"
+
+#: NOT FOUND IN SOURCE
+msgid "info"
+msgstr "資訊"
+
+#: html/Elements/SelectBoolean:31 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:35 html/Search/Elements/PickRestriction:46 html/Search/Elements/PickRestriction:75 html/Search/Elements/PickRestriction:87 html/Work/Search/PickRestriction:27 html/Work/Search/PickRestriction:56 html/Work/Search/PickRestriction:69
+msgid "is"
+msgstr "是"
+
+#: html/Elements/SelectBoolean:35 html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectMatch:36 html/Search/Elements/PickRestriction:47 html/Search/Elements/PickRestriction:76 html/Search/Elements/PickRestriction:88 html/Work/Search/PickRestriction:28 html/Work/Search/PickRestriction:57 html/Work/Search/PickRestriction:70
+msgid "isn't"
+msgstr "不是"
+
+#: html/Elements/SelectCustomFieldOperator:37 html/Elements/SelectEqualityOperator:37
+msgid "less than"
+msgstr "小於"
+
+#: html/Edit/Global/Workflow/Owner.html:35
+msgid "level Admins"
+msgstr "層主管"
+
+#: html/Search/Elements/PickRestriction:66 html/Work/Search/PickRestriction:46
+msgid "matches"
+msgstr "符合"
+
+#: lib/RT/Date.pm:311
+msgid "min"
+msgstr "分"
+
+#: html/Ticket/Update.html:64
+msgid "minutes"
+msgstr "分鐘"
+
+#: bin/rt-commit-handler:764
+msgid "modifications\\n\\n"
+msgstr "更改\\n\\n"
+
+#: lib/RT/Date.pm:327
+msgid "months"
+msgstr "月"
+
+#: lib/RT/Queue_Overlay.pm:57
+msgid "new"
+msgstr "新建立"
+
+#: html/Admin/Elements/EditScrips:42
+msgid "no value"
+msgstr "沒有值"
+
+#: html/Admin/Elements/EditQueueWatchers:26 html/Edit/Groups/Member:40 html/Edit/Groups/Members/Add.html:17 html/Edit/Groups/Members/List:8 html/Edit/Queues/Basic/Top:50 html/Edit/Queues/List:18 html/Ticket/Elements/EditWatchers:27 html/Work/Delegates/Info:37 html/Work/Delegates/Info:48 html/Work/Overview/Info:31 html/Work/Queues/List:11 html/Work/Tickets/Elements/ShowBasics:27
+msgid "none"
+msgstr "無"
+
+#: html/Elements/SelectEqualityOperator:37
+msgid "not equal to"
+msgstr "不等於"
+
+#: NOT FOUND IN SOURCE
+msgid "notice"
+msgstr "提示"
+
+#: NOT FOUND IN SOURCE
+msgid "notlike"
+msgstr "不符合"
+
+#: html/Edit/Elements/PickUsers:17 html/Edit/Users/Add.html:18 html/Edit/Users/Search.html:28 html/Work/Tickets/Cc:15
+msgid "number"
+msgstr "號"
+
+#: html/SelfService/Elements/MyRequests:60 lib/RT/Queue_Overlay.pm:58
+msgid "open"
+msgstr "開啟"
+
+#: NOT FOUND IN SOURCE
+msgid "opened"
+msgstr "已開啟"
+
+#: lib/RT/Group_Overlay.pm:198
+#. ($self->Name, $user->Name)
+msgid "personal group '%1' for user '%2'"
+msgstr "使用者「%2」的「%1」代理人群組"
+
+#: lib/RT/Group_Overlay.pm:206
+#. ($queue->Name, $self->Type)
+msgid "queue %1 %2"
+msgstr "表單 %1 %2"
+
+#: lib/RT/Queue_Overlay.pm:61
+msgid "rejected"
+msgstr "已駁回"
+
+#: html/Work/Elements/SelectSearch:21 lib/RT/Queue_Overlay.pm:60
+msgid "resolved"
+msgstr "已處理"
+
+#: html/Edit/Global/Basic/Top:48
+msgid "rtname"
+msgstr "伺服器名稱"
+
+#: lib/RT/Date.pm:307
+msgid "sec"
+msgstr "秒"
+
+#: lib/RT/Queue_Overlay.pm:59
+msgid "stalled"
+msgstr "延宕"
+
+#: lib/RT/Group_Overlay.pm:201
+#. ($self->Type)
+msgid "system %1"
+msgstr "系統 %1"
+
+#: lib/RT/Group_Overlay.pm:212
+#. ($self->Type)
+msgid "system group '%1'"
+msgstr "系統群組 '%1'"
+
+#: html/Elements/Error:42 html/SelfService/Error.html:41
+msgid "the calling component did not specify why"
+msgstr "呼叫元件未指明原因"
+
+#: lib/RT/Group_Overlay.pm:209
+#. ($self->Instance, $self->Type)
+msgid "ticket #%1 %2"
+msgstr "申請單 #%1 %2"
+
+#: html/Work/Elements/SelectSearch:27
+msgid "till"
+msgstr "至"
+
+#: html/Edit/Elements/PickUsers:15 html/Edit/Global/Workflow/Condition:30 html/Edit/Users/Add.html:16 html/Edit/Users/Search.html:26 html/Work/Tickets/Cc:13
+msgid "to"
+msgstr "到"
+
+#: NOT FOUND IN SOURCE
+msgid "true"
+msgstr "真"
+
+#: lib/RT/Group_Overlay.pm:215
+#. ($self->Id)
+msgid "undescribed group %1"
+msgstr "沒有描述的群組 %1"
+
+#: html/Work/Elements/SelectSearch:19
+msgid "unresolved"
+msgstr "未處理"
+
+#: lib/RT/Group_Overlay.pm:190
+#. ($user->Object->Name)
+msgid "user %1"
+msgstr "使用者 %1"
+
+#: NOT FOUND IN SOURCE
+msgid "warning"
+msgstr "警告"
+
+#: lib/RT/Date.pm:323
+msgid "weeks"
+msgstr "週"
+
+#: NOT FOUND IN SOURCE
+msgid "with template %1"
+msgstr "範本:%1"
+
+#: lib/RT/Date.pm:331
+msgid "years"
+msgstr "年"
+
+#: lib/RT/Date.pm:331
+msgid "approving"
+msgstr "待簽核"
+
index a3bf92d..ec0e877 100644 (file)
@@ -1,9 +1,31 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Interface/CLI.pm,v 1.1 2002-08-12 06:17:08 ivan Exp $
-# RT is (c) 1996-2001 Jesse Vincent <jesse@fsck.com>
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+use strict;
 
+use RT;
 package RT::Interface::CLI;
 
-use strict;
 
 
 BEGIN {
@@ -11,14 +33,14 @@ BEGIN {
     use vars qw ($VERSION  @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
     
     # set the version for version checking
-    $VERSION = do { my @r = (q$Revision: 1.1 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker
+    $VERSION = do { my @r = (q$Revision: 1.2 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker
     
     @ISA         = qw(Exporter);
     
     # your exported package globals go here,
     # as well as any optionally exported functions
-    @EXPORT_OK   = qw(&CleanEnv &LoadConfig &DBConnect 
-                     &GetCurrentUser &GetMessageContent &debug);
+    @EXPORT_OK   = qw(&CleanEnv 
+                     &GetCurrentUser &GetMessageContent &debug &loc);
 }
 
 =head1 NAME
@@ -27,25 +49,28 @@ BEGIN {
 
 =head1 SYNOPSIS
 
-  use lib "!!RT_LIB_PATH!!";
-  use lib "!!RT_ETC_PATH!!";
+  use lib "/path/to/rt/libraries/";
 
-  use RT::Interface::CLI  qw(CleanEnv LoadConfig DBConnect 
-                          GetCurrentUser GetMessageContent);
+  use RT::Interface::CLI  qw(CleanEnv 
+                          GetCurrentUser GetMessageContent loc);
 
   #Clean out all the nasties from the environment
   CleanEnv();
 
-  #Load etc/config.pm and drop privs
-  LoadConfig();
+  #let's talk to RT'
+  use RT;
 
-  #Connect to the database and get RT::SystemUser and RT::Nobody loaded
-  DBConnect();
+  #Load RT's config file
+  RT::LoadConfig();
 
+  # Connect to the database. set up loggign
+  RT::Init();
 
   #Get the current user all loaded
   my $CurrentUser = GetCurrentUser();
 
+  print loc('Hello!'); # Synonym of $CuurentUser->loc('Hello!');
+
 =head1 DESCRIPTION
 
 
@@ -53,7 +78,6 @@ BEGIN {
 
 =begin testing
 
-ok(require RT::TestHarness);
 ok(require RT::Interface::CLI);
 
 =end testing
@@ -77,35 +101,10 @@ sub CleanEnv {
 
 
 
-=head2 LoadConfig
-
-Loads RT's config file and then drops setgid privileges.
-
-=cut
-
-sub LoadConfig {
-    
-    #This drags in  RT's config.pm
-    use config;
-    
-}      
-
-
-
-=head2 DBConnect
-
-  Calls RT::Init, which creates a database connection and then creates $RT::Nobody
-  and $RT::SystemUser
-
-=cut
-
-
-sub DBConnect {
-    use RT;
-    RT::Init();
-}
 
+{
 
+    my $CurrentUser; # shared betwen GetCurrentUser and loc
 
 # {{{ sub GetCurrentUser 
 
@@ -115,15 +114,14 @@ sub DBConnect {
 loaded with that user.  if the current user isn't found, returns a copy of RT::Nobody.
 
 =cut
+
 sub GetCurrentUser  {
     
-    my ($Gecos, $CurrentUser);
-    
     require RT::CurrentUser;
     
     #Instantiate a user object
     
-    $Gecos=(getpwuid($<))[0];
+    my $Gecos= ($^O eq 'MSWin32') ? Win32::LoginName() : (getpwuid($<))[0];
 
     #If the current user is 0, then RT will assume that the User object
     #is that of the currentuser.
@@ -134,10 +132,29 @@ sub GetCurrentUser  {
     unless ($CurrentUser->Id) {
        $RT::Logger->debug("No user with a unix login of '$Gecos' was found. ");
     }
+
     return($CurrentUser);
 }
 # }}}
 
+
+# {{{ sub loc 
+
+=head2 loc
+
+  Synonym of $CurrentUser->loc().
+
+=cut
+
+sub loc {
+    die "No current user yet" unless $CurrentUser ||= RT::CurrentUser->new;
+    return $CurrentUser->loc(@_);
+}
+# }}}
+
+}
+
+
 # {{{ sub GetMessageContent
 
 =head2 GetMessageContent
@@ -221,4 +238,9 @@ sub debug {
 # }}}
 
 
+eval "require RT::Interface::CLI_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/CLI_Vendor.pm});
+eval "require RT::Interface::CLI_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/CLI_Local.pm});
+
 1;
index e954360..7eec050 100755 (executable)
@@ -1,41 +1,58 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Interface/Email.pm,v 1.1 2002-08-12 06:17:08 ivan Exp $
-# RT is (c) 1996-2001 Jesse Vincent <jesse@fsck.com>
-
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 package RT::Interface::Email;
 
 use strict;
 use Mail::Address;
 use MIME::Entity;
+use RT::EmailParser;
+
 
 BEGIN {
     use Exporter ();
     use vars qw ($VERSION  @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
     
     # set the version for version checking
-    $VERSION = do { my @r = (q$Revision: 1.1 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker
+    $VERSION = do { my @r = (q$Revision: 1.2 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker
     
     @ISA         = qw(Exporter);
     
     # your exported package globals go here,
     # as well as any optionally exported functions
-    @EXPORT_OK   = qw(&CleanEnv 
-                     &LoadConfig 
-                     &DBConnect 
-                     &GetCurrentUser
+    @EXPORT_OK   = qw(
+              &CreateUser
                      &GetMessageContent
                      &CheckForLoops 
                      &CheckForSuspiciousSender
                      &CheckForAutoGenerated 
-                     &ParseMIMEEntityFromSTDIN
-                     &ParseTicketId 
                      &MailError 
                      &ParseCcAddressesFromHead
                      &ParseSenderAddressFromHead 
-                     &ParseErrorsToAddressFromHead
-              &ParseAddressFromHeader
-
+                     &ParseErrorsToAddressFromHead
+                      &ParseAddressFromHeader
+              &Gateway);
 
-                     &debug);
 }
 
 =head1 NAME
@@ -47,28 +64,13 @@ BEGIN {
   use lib "!!RT_LIB_PATH!!";
   use lib "!!RT_ETC_PATH!!";
 
-  use RT::Interface::Email  qw(CleanEnv LoadConfig DBConnect 
-                             );
-
-  #Clean out all the nasties from the environment
-  CleanEnv();
-
-  #Load etc/config.pm and drop privs
-  LoadConfig();
-
-  #Connect to the database and get RT::SystemUser and RT::Nobody loaded
-  DBConnect();
-
-
-  #Get the current user all loaded
-  my $CurrentUser = GetCurrentUser();
+  use RT::Interface::Email  qw(Gateway CreateUser);
 
 =head1 DESCRIPTION
 
 
 =begin testing
 
-ok(require RT::TestHarness);
 ok(require RT::Interface::Email);
 
 =end testing
@@ -79,71 +81,6 @@ ok(require RT::Interface::Email);
 =cut
 
 
-=head2 CleanEnv
-
-Removes some of the nastiest nasties from the user\'s environment.
-
-=cut
-
-sub CleanEnv {
-    $ENV{'PATH'} = '/bin:/usr/bin';    # or whatever you need
-    $ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
-    $ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'};
-    $ENV{'ENV'} = '' if defined $ENV{'ENV'};
-    $ENV{'IFS'} = '' if defined $ENV{'IFS'};
-}
-
-
-
-=head2 LoadConfig
-
-Loads RT's config file and then drops setgid privileges.
-
-=cut
-
-sub LoadConfig {
-    
-    #This drags in  RT's config.pm
-    use config;
-    
-}      
-
-
-
-=head2 DBConnect
-
-  Calls RT::Init, which creates a database connection and then creates $RT::Nobody
-  and $RT::SystemUser
-
-=cut
-
-
-sub DBConnect {
-    use RT;
-    RT::Init();
-}
-
-
-
-# {{{ sub debug
-
-sub debug {
-    my $val = shift;
-    my ($debug);
-    if ($val) {
-       $RT::Logger->debug($val."\n");
-       if ($debug) {
-           print STDERR "$val\n";
-       }
-    }
-    if ($debug) {
-       return(1);
-    }  
-}
-
-# }}}
-
-
 # {{{ sub CheckForLoops 
 
 sub CheckForLoops  {
@@ -207,82 +144,6 @@ sub CheckForAutoGenerated {
 
 # }}}
 
-# {{{ sub ParseMIMEEntityFromSTDIN
-
-sub ParseMIMEEntityFromSTDIN {
-
-    # Create a new parser object:
-    
-    my $parser = new MIME::Parser;
-    
-    # {{{ Config $parser to store large attacments in temp dir
-
-    ## TODO: Does it make sense storing to disk at all?  After all, we
-    ## need to put each msg as an in-core scalar before saving it to
-    ## the database, don't we?
-
-    ## At the same time, we should make sure that we nuke attachments 
-    ## Over max size and return them
-
-    ## TODO: Remove the temp dir when we don't need it any more.
-
-    my $AttachmentDir = File::Temp::tempdir (TMPDIR => 1, CLEANUP => 1);
-    
-    # Set up output directory for files:
-    $parser->output_dir("$AttachmentDir");
-  
-    #If someone includes a message, don't extract it
-    $parser->extract_nested_messages(0);
-
-   
-    # Set up the prefix for files with auto-generated names:
-    $parser->output_prefix("part");
-
-    # If content length is <= 20000 bytes, store each msg as in-core scalar;
-    # Else, write to a disk file (the default action):
-  
-    $parser->output_to_core(20000);
-
-    # }}} (temporary directory)
-
-    #Ok. now that we're set up, let's get the stdin.
-    my $entity;
-    unless ($entity = $parser->read(\*STDIN)) {
-       die "couldn't parse MIME stream";
-    }
-    #Now we've got a parsed mime object. 
-    
-    # Get the head, a MIME::Head:
-    my $head = $entity->head;
-   
-
-    # Unfold headers that are have embedded newlines
-    $head->unfold; 
-    
-    # TODO - information about the charset is lost here!
-    $head->decode;
-
-    return ($entity, $head);
-
-}
-# }}}
-
-# {{{ sub ParseTicketId 
-
-sub ParseTicketId {
-    my $Subject = shift;
-    my ($Id);
-    
-    if ($Subject =~ s/\[$RT::rtname \#(\d+)\]//i) {
-       $Id = $1;
-       $RT::Logger->debug("Found a ticket ID. It's $Id");
-       return($Id);
-    }
-    else {
-       return(undef);
-    }
-}
-# }}}
 
 # {{{ sub MailError 
 sub MailError {
@@ -313,8 +174,8 @@ sub MailError {
     if ($mimeobj) {
         $mimeobj->sync_headers();
         $entity->add_part($mimeobj);
-    } 
-
+    }
+    
     if ($RT::MailCommand eq 'sendmailpipe') {
         open (MAIL, "|$RT::SendmailPath $RT::SendmailArguments") || return(0);
         print MAIL $entity->as_string;
@@ -327,144 +188,66 @@ sub MailError {
 
 # }}}
 
-# {{{ sub GetCurrentUser 
-
-sub GetCurrentUser  {
-    my $head = shift;
-    my $entity = shift;
-    my $ErrorsTo = shift;
+# {{{ Create User
 
-    my %UserInfo = ();
+sub CreateUser {
+    my ($Username, $Address, $Name, $ErrorsTo, $entity) = @_;
+    my $NewUser = RT::User->new($RT::SystemUser);
 
-    #Suck the address of the sender out of the header
-    my ($Address, $Name) = ParseSenderAddressFromHead($head);
-    
-    #This will apply local address canonicalization rules
-    $Address = RT::CanonicalizeAddress($Address);
-  
-    #If desired, synchronize with an external database
-
-    my $UserFoundInExternalDatabase = 0;
-
-    # Username is the 'Name' attribute of the user that RT uses for things
-    # like authentication
-    my $Username = undef;
-    if ($RT::LookupSenderInExternalDatabase) {
-       ($UserFoundInExternalDatabase, %UserInfo) = 
-         RT::LookupExternalUserInfo($Address, $Name);
-   
-       $Address = $UserInfo{'EmailAddress'};
-       $Username = $UserInfo{'Name'}; 
-    }
-    
-    my $CurrentUser = RT::CurrentUser->new();
+    # This data is tainted by some Very Broken mailers.
+    # (Sometimes they send raw ISO 8859-1 data here. fear that.
+    require Encode;
+    $Username = Encode::encode(utf8 => $Username, Encode::FB_PERLQQ()) if defined $Username;
+    $Name = Encode::encode(utf8 => $Name, Encode::FB_PERLQQ()) if defined $Name;
     
-    # First try looking up by a username, if we got one from the external
-    # db lookup. Next, try looking up by email address. Failing that,
-    # try looking up by users who have this user's email address as their
-    # username.
-
-    if ($Username) {
-       $CurrentUser->LoadByName($Username);
-    }  
+    my ($Val, $Message) = 
+      $NewUser->Create(Name => ($Username || $Address),
+                       EmailAddress => $Address,
+                       RealName => $Name,
+                       Password => undef,
+                       Privileged => 0,
+                       Comments => 'Autocreated on ticket submission'
+                      );
     
-    unless ($CurrentUser->Id) {
-       $CurrentUser->LoadByEmail($Address);
-    }  
-
-    #If we can't get it by email address, try by name.  
-    unless ($CurrentUser->Id) {
-       $CurrentUser->LoadByName($Address);
+    unless ($Val) {
+        
+        # Deal with the race condition of two account creations at once
+        #
+        if ($Username) {
+            $NewUser->LoadByName($Username);
+        }
+        
+        unless ($NewUser->Id) {
+            $NewUser->LoadByEmail($Address);
+        }
+        
+        unless ($NewUser->Id) {  
+            MailError( To => $ErrorsTo,
+                       Subject => "User could not be created",
+                       Explanation => "User creation failed in mailgateway: $Message",
+                       MIMEObj => $entity,
+                       LogLevel => 'crit'
+                     );
+        }
     }
-    
-    
-    unless ($CurrentUser->Id) {
-        #If we couldn't load a user, determine whether to create a user
-
-        # {{{ If we require an incoming address to be found in the external
-       # user database, reject the incoming message appropriately
-        if ( $RT::LookupSenderInExternalDatabase &&
-            $RT::SenderMustExistInExternalDatabase && 
-            !$UserFoundInExternalDatabase) {
-           
-           my $Message = "Sender's email address was not found in the user database.";
-
-           # {{{  This code useful only if you've defined an AutoRejectRequest template
-           
-           require RT::Template;
-           my $template = new RT::Template($RT::Nobody);
-           $template->Load('AutoRejectRequest');
-           $Message = $template->Content || $Message;
-           
-           # }}}
-           
-           MailError( To => $ErrorsTo,
-                      Subject => "Ticket Creation failed: user could not be created",
-                      Explanation => $Message,
-                      MIMEObj => $entity,
-                      LogLevel => 'notice'
-                    );
-
-           return($CurrentUser);
-
-       } 
-       # }}}
-       
-       else {
-           my $NewUser = RT::User->new($RT::SystemUser);
-           
-           my ($Val, $Message) = 
-             $NewUser->Create(Name => ($Username || $Address),
-                              EmailAddress => $Address,
-                              RealName => "$Name",
-                              Password => undef,
-                              Privileged => 0,
-                              Comments => 'Autocreated on ticket submission'
-                             );
-           
-           unless ($Val) {
-               
-               # Deal with the race condition of two account creations at once
-               #
-               if ($Username) {
-                   $NewUser->LoadByName($Username);
-               }
-               
-               unless ($NewUser->Id) {
-                   $NewUser->LoadByEmail($Address);
-               }
-               
-               unless ($NewUser->Id) {  
-                   MailError( To => $ErrorsTo,
-                              Subject => "User could not be created",
-                              Explanation => "User creation failed in mailgateway: $Message",
-                              MIMEObj => $entity,
-                              LogLevel => 'crit'
-                            );
-               }
-           }
-       }
-       
-       #Load the new user object
-       $CurrentUser->LoadByEmail($Address);
-       
-       unless ($CurrentUser->id) {
-           $RT::Logger->warning("Couldn't load user '$Address'.".  "giving up");
-               MailError( To => $ErrorsTo,
-                          Subject => "User could not be loaded",
-                          Explanation => "User  '$Address' could not be loaded in the mail gateway",
-                          MIMEObj => $entity,
-                          LogLevel => 'crit'
-                        );
-           
-       }
+
+    #Load the new user object
+    my $CurrentUser = RT::CurrentUser->new();
+    $CurrentUser->LoadByEmail($Address);
+
+    unless ($CurrentUser->id) {
+            $RT::Logger->warning("Couldn't load user '$Address'.".  "giving up");
+                MailError( To => $ErrorsTo,
+                           Subject => "User could not be loaded",
+                           Explanation => "User  '$Address' could not be loaded in the mail gateway",
+                           MIMEObj => $entity,
+                           LogLevel => 'crit'
+                     );
     }
-    
-    return ($CurrentUser);
-    
-}
-# }}}
 
+    return $CurrentUser;
+}
+# }}}      
 # {{{ ParseCcAddressesFromHead 
 
 =head2 ParseCcAddressesFromHead HASHREF
@@ -489,11 +272,11 @@ sub ParseCcAddressesFromHead {
     
     foreach my $AddrObj (@ToObjs, @CcObjs) {
        my $Address = $AddrObj->address;
-       $Address = RT::CanonicalizeAddress($Address);
+       $Address = $args{'CurrentUser'}->UserObj->CanonicalizeEmailAddress($Address);
        next if ($args{'CurrentUser'}->EmailAddress =~ /^$Address$/i);
        next if ($args{'QueueObj'}->CorrespondAddress =~ /^$Address$/i);
        next if ($args{'QueueObj'}->CommentAddress =~ /^$Address$/i);
-       next if (RT::IsRTAddress($Address));
+       next if (RT::EmailParser::IsRTAddress(undef, $Address));
        
        push (@Addresses, $Address);
     }
@@ -568,8 +351,7 @@ sub ParseAddressFromHeader{
     }
  
     my $Name =  ($AddrObj->phrase || $AddrObj->comment || $AddrObj->address);
-
-
+    
     #Lets take the from and load a user object.
     my $Address = $AddrObj->address;
 
@@ -578,4 +360,289 @@ sub ParseAddressFromHeader{
 # }}}
 
 
+
+=head2 Gateway
+
+This performs all the "guts" of the mail rt-mailgate program, and is
+designed to be called from the web interface with a message, user
+object, and so on.
+
+=cut
+
+sub Gateway {
+    my %args = ( message => undef,
+                 queue   => 1,
+                 action  => 'correspond',
+                 ticket  => undef,
+                 @_ );
+
+    # Validate the action
+    unless ( $args{'action'} =~ /^(comment|correspond|action)$/ ) {
+
+        # Can't safely loc this. What object do we loc around?
+        return ( 0, "Invalid 'action' parameter", undef );
+    }
+
+    my $parser = RT::EmailParser->new();
+    $parser->ParseMIMEEntityFromScalar( $args{'message'} );
+
+    my $Message = $parser->Entity();
+    my $head = $Message->head;
+
+    my ( $CurrentUser, $AuthStat, $status, $error );
+
+    my $ErrorsTo = ParseErrorsToAddressFromHead($head);
+
+    my $MessageId = $head->get('Message-Id')
+      || "<no-message-id-" . time . rand(2000) . "\@.$RT::Organization>";
+
+    #Pull apart the subject line
+    my $Subject = $head->get('Subject') || '';
+    chomp $Subject;
+
+
+    $args{'ticket'} ||= $parser->ParseTicketId($Subject);
+
+    my $SystemTicket;
+    if ($args{'ticket'} ) {
+        $SystemTicket = RT::Ticket->new($RT::SystemUser);
+        $SystemTicket->Load($args{'ticket'});
+    }
+
+    #Set up a queue object
+    my $SystemQueueObj = RT::Queue->new($RT::SystemUser);
+    $SystemQueueObj->Load( $args{'queue'} );
+
+
+    # We can safely have no queue of we have a known-good ticket
+    unless ( $args{'ticket'} || $SystemQueueObj->id ) {
+        MailError(
+                 To          => $RT::OwnerEmail,
+                 Subject     => "RT Bounce: $Subject",
+                 Explanation => "RT couldn't find the queue: " . $args{'queue'},
+                 MIMEObj     => $Message );
+        return ( 0, "RT couldn't find the queue: " . $args{'queue'}, undef );
+    }
+
+    # Authentication Level
+    # -1 - Get out.  this user has been explicitly declined 
+    # 0 - User may not do anything (Not used at the moment)
+    # 1 - Normal user
+    # 2 - User is allowed to specify status updates etc. a la enhanced-mailgate
+
+    push @RT::MailPlugins, "Auth::MailFrom"   unless @RT::MailPlugins;
+    # Since this needs loading, no matter what
+
+    for (@RT::MailPlugins) {
+        my $Code;
+        my $NewAuthStat;
+        if ( ref($_) eq "CODE" ) {
+            $Code = $_;
+        }
+        else {
+            $_ = "RT::Interface::Email::$_" unless /^RT::Interface::Email::/;
+            eval "require $_;";
+            if ($@) {
+                die ("Couldn't load module $_: $@");
+                next;
+            }
+            no strict 'refs';
+            if ( !defined( $Code = *{ $_ . "::GetCurrentUser" }{CODE} ) ) {
+                die ("No GetCurrentUser code found in $_ module");
+                next;
+            }
+        }
+
+        ( $CurrentUser, $NewAuthStat ) = $Code->( Message     => $Message,
+                                                  CurrentUser => $CurrentUser,
+                                                  AuthLevel   => $AuthStat,
+                                                  Action => $args{'action'},
+                                                  Ticket => $SystemTicket,
+                                                  Queue  => $SystemQueueObj );
+
+        # You get the highest level of authentication you were assigned.
+        last if $AuthStat == -1;
+        $AuthStat = $NewAuthStat if $NewAuthStat > $AuthStat;
+    }
+
+    # {{{ If authentication fails and no new user was created, get out.
+    if ( !$CurrentUser or !$CurrentUser->Id or $AuthStat == -1 ) {
+
+        # If the plugins refused to create one, they lose.
+        MailError(
+            Subject     => "Could not load a valid user",
+            Explanation => <<EOT,
+RT could not load a valid user, and RT's configuration does not allow
+for the creation of a new user for your email.
+
+Your RT administrator needs to grant 'Everyone' the right 'CreateTicket'
+for this queue.
+
+EOT
+            MIMEObj  => $Message,
+            LogLevel => 'error' )
+          unless $AuthStat == -1;
+        return ( 0, "Could not load a valid user", undef );
+    }
+
+    # }}}
+
+    # {{{ Lets check for mail loops of various sorts.
+    my $IsAutoGenerated = CheckForAutoGenerated($head);
+
+    my $IsSuspiciousSender = CheckForSuspiciousSender($head);
+
+    my $IsALoop = CheckForLoops($head);
+
+    my $SquelchReplies = 0;
+
+    #If the message is autogenerated, we need to know, so we can not
+    # send mail to the sender
+    if ( $IsSuspiciousSender || $IsAutoGenerated || $IsALoop ) {
+        $SquelchReplies = 1;
+        $ErrorsTo       = $RT::OwnerEmail;
+    }
+
+    # }}}
+
+    # {{{ Drop it if it's disallowed
+    if ( $AuthStat == 0 ) {
+        MailError(
+             To          => $ErrorsTo,
+             Subject     => "Permission Denied",
+             Explanation => "You do not have permission to communicate with RT",
+             MIMEObj     => $Message );
+    }
+
+    # }}}
+    # {{{ Warn someone  if it's a loop
+
+    # Warn someone if it's a loop, before we drop it on the ground
+    if ($IsALoop) {
+        $RT::Logger->crit("RT Recieved mail ($MessageId) from itself.");
+
+        #Should we mail it to RTOwner?
+        if ($RT::LoopsToRTOwner) {
+            MailError( To          => $RT::OwnerEmail,
+                       Subject     => "RT Bounce: $Subject",
+                       Explanation => "RT thinks this message may be a bounce",
+                       MIMEObj     => $Message );
+
+            #Do we actually want to store it?
+            return ( 0, "Message Bounced", undef ) unless ($RT::StoreLoops);
+        }
+    }
+
+    # }}}
+
+    # {{{ Squelch replies if necessary
+    # Don't let the user stuff the RT-Squelch-Replies-To header.
+    if ( $head->get('RT-Squelch-Replies-To') ) {
+        $head->add( 'RT-Relocated-Squelch-Replies-To',
+                    $head->get('RT-Squelch-Replies-To') );
+        $head->delete('RT-Squelch-Replies-To');
+    }
+
+    if ($SquelchReplies) {
+        ## TODO: This is a hack.  It should be some other way to
+        ## indicate that the transaction should be "silent".
+
+        my ( $Sender, $junk ) = ParseSenderAddressFromHead($head);
+        $head->add( 'RT-Squelch-Replies-To', $Sender );
+    }
+
+    # }}}
+
+    my $Ticket = RT::Ticket->new($CurrentUser);
+
+    # {{{ If we don't have a ticket Id, we're creating a new ticket
+    if ( !$args{'ticket'} ) {
+
+        # {{{ Create a new ticket
+
+        my @Cc;
+        my @Requestors = ( $CurrentUser->id );
+
+        if ($RT::ParseNewMessageForTicketCcs) {
+            @Cc = ParseCcAddressesFromHead( Head        => $head,
+                                            CurrentUser => $CurrentUser,
+                                            QueueObj    => $SystemQueueObj );
+        }
+
+        my ( $id, $Transaction, $ErrStr ) = $Ticket->Create(
+                                                      Queue     => $SystemQueueObj->Id,
+                                                      Subject   => $Subject,
+                                                      Requestor => \@Requestors,
+                                                      Cc        => \@Cc,
+                                                      MIMEObj   => $Message );
+        if ( $id == 0 ) {
+            MailError( To          => $ErrorsTo,
+                       Subject     => "Ticket creation failed",
+                       Explanation => $ErrStr,
+                       MIMEObj     => $Message );
+            $RT::Logger->error("Create failed: $id / $Transaction / $ErrStr ");
+            return ( 0, "Ticket creation failed", $Ticket );
+        }
+
+        # }}}
+    }
+
+    # }}}
+
+    #   If the action is comment, add a comment.
+    elsif ( $args{'action'} =~ /^(comment|correspond)$/i ) {
+        $Ticket->Load($args{'ticket'});
+        unless ( $Ticket->Id ) {
+            my $message = "Could not find a ticket with id ".$args{'ticket'};
+            MailError( To          => $ErrorsTo,
+                     Subject     => "Message not recorded",
+                     Explanation => $message,
+                     MIMEObj     => $Message );
+
+            return ( 0, $message);
+        }
+
+        my ( $status, $msg );
+        if ( $args{'action'} =~ /^correspond$/ ) {
+            ( $status, $msg ) = $Ticket->Correspond( MIMEObj => $Message );
+        }
+        else {
+            ( $status, $msg ) = $Ticket->Comment( MIMEObj => $Message );
+        }
+        unless ($status) {
+
+            #Warn the sender that we couldn't actually submit the comment.
+            MailError( To          => $ErrorsTo,
+                       Subject     => "Message not recorded",
+                       Explanation => $msg,
+                       MIMEObj     => $Message );
+            return ( 0, "Message not recorded", $Ticket );
+        }
+    }
+
+    else {
+
+        #Return mail to the sender with an error
+        MailError( To          => $ErrorsTo,
+                   Subject     => "RT Configuration error",
+                   Explanation => "'"
+                     . $args{'action'}
+                     . "' not a recognized action."
+                     . " Your RT administrator has misconfigured "
+                     . "the mail aliases which invoke RT",
+                   MIMEObj => $Message );
+        $RT::Logger->crit( $args{'action'} . " type unknown for $MessageId" );
+        return ( 0, "Configuration error: " . $args{'action'} . " not a recognized action", $Ticket );
+
+    }
+
+
+return ( 1, "Success", $Ticket );
+}
+
+eval "require RT::Interface::Email_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email_Vendor.pm});
+eval "require RT::Interface::Email_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email_Local.pm});
+
 1;
diff --git a/rt/lib/RT/Interface/Email/Auth/MailFrom.pm b/rt/lib/RT/Interface/Email/Auth/MailFrom.pm
new file mode 100644 (file)
index 0000000..eb778ff
--- /dev/null
@@ -0,0 +1,131 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+package RT::Interface::Email::Auth::MailFrom;
+use RT::Interface::Email qw(ParseSenderAddressFromHead CreateUser);
+
+# This is what the ordinary, non-enhanced gateway does at the moment.
+
+sub GetCurrentUser {
+    my %args = ( Message     => undef,
+                 CurrentUser => undef,
+                 AuthLevel   => undef,
+                 Ticket      => undef,
+                 Queue       => undef,
+                 Action      => undef,
+                 @_ );
+
+    # We don't need to do any external lookups
+    my ( $Address, $Name ) = ParseSenderAddressFromHead( $args{'Message'}->head );
+    my $CurrentUser = RT::CurrentUser->new();
+    $CurrentUser->LoadByEmail($Address);
+
+    unless ( $CurrentUser->Id ) {
+        $CurrentUser->LoadByName($Address);
+    }
+
+    if ( $CurrentUser->Id ) {
+        return ( $CurrentUser, 1 );
+    }
+    
+
+
+    # If the user can't be loaded, we may need to create one. Figure out the acl situation.
+    my $unpriv = RT::Group->new($RT::SystemUser);
+    $unpriv->LoadSystemInternalGroup('Unprivileged');
+    unless ( $unpriv->Id ) {
+        $RT::Logger->crit( "Auth::MailFrom couldn't find the 'Unprivileged' internal group" );
+        return ( $args{'CurrentUser'}, -1 );
+    }
+
+    my $everyone = RT::Group->new($RT::SystemUser);
+    $everyone->LoadSystemInternalGroup('Everyone');
+    unless ( $everyone->Id ) {
+        $RT::Logger->crit( "Auth::MailFrom couldn't find the 'Everyone' internal group");
+        return ( $args{'CurrentUser'}, -1 );
+    }
+
+    # but before we do that, we need to make sure that the created user would have the right
+    # to do what we're doing.
+    if ( $args{'Ticket'} && $args{'Ticket'}->Id ) {
+        # We have a ticket. that means we're commenting or corresponding
+        if ( $args{'Action'} =~ /^comment$/i ) {
+
+            # check to see whether "Everybody" or "Unprivileged users" can comment on tickets
+            unless ( $everyone->PrincipalObj->HasRight(
+                                                      Object => $args{'Queue'},
+                                                      Right => 'CommentOnTicket'
+                     )
+                     || $unpriv->PrincipalObj->HasRight(
+                                                      Object => $args{'Queue'},
+                                                      Right => 'CommentOnTicket'
+                     )
+              ) {
+                return ( $args{'CurrentUser'}, 0 );
+            }
+        }
+        elsif ( $args{'Action'} =~ /^correspond$/i ) {
+
+            # check to see whether "Everybody" or "Unprivileged users" can correspond on tickets
+            unless ( $everyone->PrincipalObj->HasRight(Object => $args{'Queue'},
+                                                       Right  => 'ReplyToTicket'
+                     )
+                     || $unpriv->PrincipalObj->HasRight(
+                                                       Object => $args{'Queue'},
+                                                       Right  => 'ReplyToTicket'
+                     )
+              ) {
+                return ( $args{'CurrentUser'}, 0 );
+            }
+
+        }
+        else {
+            return ( $args{'CurrentUser'}, 0 );
+        }
+    }
+
+    # We're creating a ticket
+    elsif ( $args{'Queue'} && $args{'Queue'}->Id ) {
+
+        # check to see whether "Everybody" or "Unprivileged users" can create tickets in this queue
+        unless ( $everyone->PrincipalObj->HasRight( Object => $args{'Queue'},
+                                                    Right  => 'CreateTicket' )
+                 || $unpriv->PrincipalObj->HasRight( Object => $args{'Queue'},
+                                                     Right  => 'CreateTicket' )
+          ) {
+            return ( $args{'CurrentUser'}, 0 );
+        }
+
+    }
+
+    $CurrentUser = CreateUser( undef, $Address, $Name, $args{'Message'} );
+
+    return ( $CurrentUser, 1 );
+}
+
+eval "require RT::Interface::Email::Auth::MailFrom_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email/Auth/MailFrom_Vendor.pm});
+eval "require RT::Interface::Email::Auth::MailFrom_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email/Auth/MailFrom_Local.pm});
+
+1;
diff --git a/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm b/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm
new file mode 100644 (file)
index 0000000..f00e2d8
--- /dev/null
@@ -0,0 +1,63 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+package RT::Interface::Email::Filter::SpamAssassin;
+
+use Mail::SpamAssassin;
+my $spamtest = Mail::SpamAssassin->new();
+
+sub GetCurrentUser {
+    my $item = shift;
+    my $status = $spamtest->check ($item);
+    return (undef, 0) unless $status->is_spam();
+    eval { $status->rewrite_mail() };
+    if ($status->get_hits > $status->get_required_hits()*1.5) { 
+        # Spammy indeed
+        return (undef, -1);
+    }
+    return (undef, 0);
+}
+
+=head1 NAME
+
+RT::Interface::Email::Filter::SpamAssassin - Spam filter for RT
+
+=head1 SYNOPSIS
+
+    @RT::MailPlugins = ("Filter::SpamAssassin", ...);
+
+=head1 DESCRIPTION
+
+This plugin checks to see if an incoming mail is spam (using
+C<spamassassin>) and if so, rewrites its headers. If the mail is very
+definitely spam - 1.5x more hits than required - then it is dropped on
+the floor; otherwise, it is passed on as normal.
+
+=cut
+
+eval "require RT::Interface::Email::Filter::SpamAssassin_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email/Filter/SpamAssassin_Vendor.pm});
+eval "require RT::Interface::Email::Filter::SpamAssassin_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email/Filter/SpamAssassin_Local.pm});
+
+1;
index 6b52728..5097f54 100644 (file)
-## $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Interface/Web.pm,v 1.1 2002-08-12 06:17:08 ivan Exp $
-
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 ## Portions Copyright 2000 Tobias Brox <tobix@fsck.com>
-## Copyright 1996-2002 Jesse Vincent <jesse@bestpractical.com>
 
 ## This is a library of static subs to be used by the Mason web
 ## interface to RT
 
+
+=head1 NAME
+
+RT::Interface::Web
+
+=begin testing
+
+use_ok(RT::Interface::Web);
+
+=end testing
+
+=cut
+
+
 package RT::Interface::Web;
+use strict;
 
-# {{{ sub NewParser
 
-=head2 NewParser
 
-  Returns a new Mason::Parser object. Takes a param hash of things 
-  that get passed to HTML::Mason::Parser. Currently hard coded to only
-  take the parameter 'allow_globals'.
+
+
+# {{{ sub NewApacheHandler 
+
+=head2 NewApacheHandler
+
+  Takes extra options to pass to HTML::Mason::ApacheHandler->new
+  Returns a new Mason::ApacheHandler object
 
 =cut
 
-sub NewParser {
-    my %args = (
-        allow_globals => undef,
+sub NewApacheHandler {
+    require HTML::Mason::ApacheHandler;
+    my $ah = new HTML::Mason::ApacheHandler( 
+    
+        comp_root                    => [
+            [ local    => $RT::MasonLocalComponentRoot ],
+            [ standard => $RT::MasonComponentRoot ]
+        ],
+        args_method => "CGI",
+        default_escape_flags => 'h',
+        allow_globals        => [qw(%session)],
+        data_dir => "$RT::MasonDataDir",
         @_
     );
 
-    my $parser = new HTML::Mason::Parser(
-        default_escape_flags => 'h',
-        allow_globals        => $args{'allow_globals'}
-    );
-    return ($parser);
+    $ah->interp->set_escape( h => \&RT::Interface::Web::EscapeUTF8 );
+    
+    return ($ah);
 }
 
 # }}}
 
-# {{{ sub NewInterp
+# {{{ sub NewCGIHandler 
 
-=head2 NewInterp 
+=head2 NewCGIHandler
 
-  Takes a paremeter hash. Needs a param called 'parser' which is a reference
-  to an HTML::Mason::Parser.
-  returns a new Mason::Interp object
+  Returns a new Mason::CGIHandler object
 
 =cut
 
-sub NewInterp {
-    my %params = (
+sub NewCGIHandler {
+    my %args = (
+        @_
+    );
+
+    my $handler = HTML::Mason::CGIHandler->new(
         comp_root                    => [
             [ local    => $RT::MasonLocalComponentRoot ],
             [ standard => $RT::MasonComponentRoot ]
         ],
         data_dir => "$RT::MasonDataDir",
-        @_
+        default_escape_flags => 'h',
+        allow_globals        => [qw(%session)]
     );
+  
 
-    #We allow recursive autohandlers to allow for RT auth.
+    $handler->interp->set_escape( h => \&RT::Interface::Web::EscapeUTF8 );
 
-    use HTML::Mason::Interp;
-    my $interp = new HTML::Mason::Interp(%params);
 
-}
+    return ($handler);
 
+}
 # }}}
 
-# {{{ sub NewApacheHandler 
 
-=head2 NewApacheHandler
+# {{{ EscapeUTF8
 
-  Takes a Mason::Interp object
-  Returns a new Mason::ApacheHandler object
+=head2 EscapeUTF8 SCALARREF
+
+does a css-busting but minimalist escaping of whatever html you're passing in.
 
 =cut
 
-sub NewApacheHandler {
-    my $interp = shift;
-    my $ah = new HTML::Mason::ApacheHandler( interp => $interp );
-    return ($ah);
+sub EscapeUTF8  {
+        my  $ref = shift;
+        my $val = $$ref;
+        use bytes;
+        $val =~ s/&/&#38;/g;
+        $val =~ s/</&lt;/g; 
+        $val =~ s/>/&gt;/g;
+        $val =~ s/\(/&#40;/g;
+        $val =~ s/\)/&#41;/g;
+        $val =~ s/"/&#34;/g;
+        $val =~ s/'/&#39;/g;
+        $$ref = $val;
+        Encode::_utf8_on($$ref);
+
 }
 
 # }}}
 
 
-# {{{ sub NewMason11ApacheHandler
+package HTML::Mason::Commands;
+use strict;
+use vars qw/$r $m %session/;
 
-=head2 NewMason11ApacheHandler
 
-  Returns a new Mason::ApacheHandler object
+# {{{ loc
+
+=head2 loc ARRAY
+
+loc is a nice clean global routine which calls $session{'CurrentUser'}->loc()
+with whatever it's called with. If there is no $session{'CurrentUser'}, 
+it creates a temporary user, so we have something to get a localisation handle
+through
 
 =cut
 
-sub NewMason11ApacheHandler {
-        my %args = ( default_escape_flags => 'h',
-                    allow_globals        => [%session],
-        comp_root                    => [
-            [ local    => $RT::MasonLocalComponentRoot ],
-            [ standard => $RT::MasonComponentRoot ]
-        ],
-        data_dir => "$RT::MasonDataDir",
-        args_method => 'CGI'
-    );
-    my $ah = new HTML::Mason::ApacheHandler(%args);
-    return ($ah);
+sub loc {
+
+    if ($session{'CurrentUser'} && 
+        UNIVERSAL::can($session{'CurrentUser'}, 'loc')){
+        return($session{'CurrentUser'}->loc(@_));
+    }
+    else  {
+        my $u = RT::CurrentUser->new($RT::SystemUser);
+        return ($u->loc(@_));
+    }
 }
 
 # }}}
 
 
+# {{{ loc_fuzzy
+
+=head2 loc_fuzzy STRING
 
+loc_fuzzy is for handling localizations of messages that may already
+contain interpolated variables, typically returned from libraries
+outside RT's control.  It takes the message string and extracts the
+variable array automatically by matching against the candidate entries
+inside the lexicon file.
+
+=cut
 
+sub loc_fuzzy {
+    my $msg  = shift;
+    
+    if ($session{'CurrentUser'} && 
+        UNIVERSAL::can($session{'CurrentUser'}, 'loc')){
+        return($session{'CurrentUser'}->loc_fuzzy($msg));
+    }
+    else  {
+        my $u = RT::CurrentUser->new($RT::SystemUser);
+        return ($u->loc_fuzzy($msg));
+    }
+}
 
 # }}}
 
-package HTML::Mason::Commands;
 
 # {{{ sub Abort
 # Error - calls Error and aborts
 sub Abort {
 
-    if ( $session{'ErrorDocument'} && $session{'ErrorDocumentType'} ) {
-        SetContentType( $session{'ErrorDocumentType'} );
-        $m->comp( $session{'ErrorDocument'}, Why => shift );
+    if ($session{'ErrorDocument'} && 
+        $session{'ErrorDocumentType'}) {
+        $r->content_type($session{'ErrorDocumentType'});
+        $m->comp($session{'ErrorDocument'} , Why => shift);
         $m->abort;
-    }
-    else {
-        SetContentType('text/html');
-        $m->comp( "/Elements/Error", Why => shift );
+    } 
+    else  {
+        $m->comp("/Elements/Error" , Why => shift);
         $m->abort;
     }
 }
@@ -135,6 +220,7 @@ sub Abort {
 =head2 CreateTicket ARGS
 
 Create a new ticket, using Mason's %ARGS.  returns @results.
+
 =cut
 
 sub CreateTicket {
@@ -158,38 +244,45 @@ sub CreateTicket {
     my $starts = new RT::Date( $session{'CurrentUser'} );
     $starts->Set( Format => 'unknown', Value => $ARGS{'Starts'} );
 
-    my @Requestors = split ( /,/, $ARGS{'Requestors'} );
-    my @Cc         = split ( /,/, $ARGS{'Cc'} );
-    my @AdminCc    = split ( /,/, $ARGS{'AdminCc'} );
+    my @Requestors = split ( /\s*,\s*/, $ARGS{'Requestors'} );
+    my @Cc         = split ( /\s*,\s*/, $ARGS{'Cc'} );
+    my @AdminCc    = split ( /\s*,\s*/, $ARGS{'AdminCc'} );
 
     my $MIMEObj = MakeMIMEEntity(
         Subject             => $ARGS{'Subject'},
         From                => $ARGS{'From'},
         Cc                  => $ARGS{'Cc'},
         Body                => $ARGS{'Content'},
-        AttachmentFieldName => 'Attach'
     );
 
+    if ($ARGS{'Attachments'}) {
+        $MIMEObj->make_multipart;
+        $MIMEObj->add_part($_) foreach values %{$ARGS{'Attachments'}};
+    }
+
     my %create_args = (
-        Queue           => $ARGS{Queue},
-        Owner           => $ARGS{Owner},
-        InitialPriority => $ARGS{InitialPriority},
-        FinalPriority   => $ARGS{FinalPriority},
-        TimeLeft        => $ARGS{TimeLeft},
-        TimeWorked      => $ARGS{TimeWorked},
+        Queue           => $ARGS{'Queue'},
+        Owner           => $ARGS{'Owner'},
+        InitialPriority => $ARGS{'InitialPriority'},
+        FinalPriority   => $ARGS{'FinalPriority'},
+        TimeLeft        => $ARGS{'TimeLeft'},
+        TimeEstimated        => $ARGS{'TimeEstimated'},
+        TimeWorked      => $ARGS{'TimeWorked'},
         Requestor       => \@Requestors,
         Cc              => \@Cc,
         AdminCc         => \@AdminCc,
-        Subject         => $ARGS{Subject},
-        Status          => $ARGS{Status},
+        Subject         => $ARGS{'Subject'},
+        Status          => $ARGS{'Status'},
         Due             => $due->ISO,
         Starts          => $starts->ISO,
         MIMEObj         => $MIMEObj
     );
-
-    # we need to get any KeywordSelect-<integer> fields into %create_args..
-    grep { $_ =~ /^KeywordSelect-/ &&{ $create_args{$_} = $ARGS{$_} } } %ARGS;
-
+  foreach my $arg (%ARGS) {
+        if ($arg =~ /^CustomField-(\d+)(.*?)$/) {
+            next if ($arg =~ /-Magic$/);
+            $create_args{"CustomField-".$1} = $ARGS{"$arg"};
+        }
+    }
     my ( $id, $Trans, $ErrMsg ) = $Ticket->Create(%create_args);
     unless ( $id && $Trans ) {
         Abort($ErrMsg);
@@ -216,7 +309,7 @@ sub CreateTicket {
         }
     }
 
-    push ( @Actions, $ErrMsg );
+    push ( @Actions, split("\n", $ErrMsg) );
     unless ( $Ticket->CurrentUserHasRight('ShowTicket') ) {
         Abort( "No permission to view newly created ticket #"
             . $Ticket->id . "." );
@@ -283,80 +376,38 @@ sub ProcessUpdateMessage {
         my $Message = MakeMIMEEntity(
             Subject             => $args{ARGSRef}->{'UpdateSubject'},
             Body                => $args{ARGSRef}->{'UpdateContent'},
-            AttachmentFieldName => 'UpdateAttachment'
         );
 
-       ## Check whether this was a refresh or not.  
-
-       # Match Correspondence or Comments.
-        my $trans_flag = -2;
-       my $trans_type = undef;
-       my $orig_trans = $args{ARGSRef}->{'UpdateType'};
-        if ( $orig_trans =~ /^(private|public)$/ ) {
-           $trans_type = "Comment";
-        }elsif ( $orig_trans eq 'response' ) {
-           $trans_type = "Correspond";
-       }
-
-       # Do we have a transaction that we need to update on? session
-       if( defined( $trans_type ) ){
-           $trans_flag = 0;
-
-           # Prepare a checksum.
-           # See perldoc -f unpack for example of this.
-           my $this_checksum = unpack("%32C*", $Message->body_as_string ) % 65535;
-
-           # The above *could* generate duplicate checksums.  Crosscheck with
-           # the length.
-           my $this_length = length( $Message->body_as_string );
-
-           # Don't forget the ticket id.
-           my $this_id = $args{TicketObj}->id;
-
-           # Check whether the previous transaction in the
-           # ticket is the same as the current transaction.
-           if( defined( $session{'prev_trans_type'} ) && defined( $session{'prev_trans_chksum'} ) && defined( $session{'prev_trans_length'} ) && defined( $session{'prev_trans_tickid'} ) ){
-               if( $session{'prev_trans_type'} eq $orig_trans && $session{'prev_trans_chksum'} == $this_checksum && $session{'prev_trans_length'} == $this_length && $session{'prev_trans_tickid'} == $this_id ){
-                   # Its the same as the previous transaction for this user.
-                   $trans_flag = -1;
-               }
-           }
-
-           # Store them for next time.
-           $session{'prev_trans_type'} = $orig_trans;
-           $session{'prev_trans_chksum'} = $this_checksum;
-           $session{'prev_trans_length'} = $this_length;
-           $session{'prev_trans_tickid'} = $this_id;
-
-           if( $trans_flag == -1 ){
-                push ( @{ $args{'Actions'} },
-"This appears to be a duplicate of your previous update (please do not refresh this page)" );
-           }
-
-
-            if ( $trans_type eq 'Comment' && $trans_flag >= 0 ) {
-                my ( $Transaction, $Description ) = $args{TicketObj}->Comment(
-                    CcMessageTo  => $args{ARGSRef}->{'UpdateCc'},
-                    BccMessageTo => $args{ARGSRef}->{'UpdateBcc'},
-                    MIMEObj      => $Message,
-                    TimeTaken    => $args{ARGSRef}->{'UpdateTimeWorked'}
-                );
-                push ( @{ $args{Actions} }, $Description );
-            }
-            elsif ( $trans_type eq 'Correspond' && $trans_flag >= 0 ) {
-                my ( $Transaction, $Description ) = $args{TicketObj}->Correspond(
-                    CcMessageTo  => $args{ARGSRef}->{'UpdateCc'},
-                    BccMessageTo => $args{ARGSRef}->{'UpdateBcc'},
-                    MIMEObj      => $Message,
-                    TimeTaken    => $args{ARGSRef}->{'UpdateTimeWorked'}
-                );
-                push ( @{ $args{Actions} }, $Description );
-            }
-       }
+        if ($args{ARGSRef}->{'UpdateAttachments'}) {
+            $Message->make_multipart;
+            $Message->add_part($_) foreach values %{$args{ARGSRef}->{'UpdateAttachments'}};
+        }
+
+        ## TODO: Implement public comments
+        if ( $args{ARGSRef}->{'UpdateType'} =~ /^(private|public)$/ ) {
+            my ( $Transaction, $Description ) = $args{TicketObj}->Comment(
+                CcMessageTo  => $args{ARGSRef}->{'UpdateCc'},
+                BccMessageTo => $args{ARGSRef}->{'UpdateBcc'},
+                MIMEObj      => $Message,
+                TimeTaken    => $args{ARGSRef}->{'UpdateTimeWorked'}
+            );
+            push ( @{ $args{Actions} }, $Description );
+        }
+        elsif ( $args{ARGSRef}->{'UpdateType'} eq 'response' ) {
+            my ( $Transaction, $Description ) = $args{TicketObj}->Correspond(
+                CcMessageTo  => $args{ARGSRef}->{'UpdateCc'},
+                BccMessageTo => $args{ARGSRef}->{'UpdateBcc'},
+                MIMEObj      => $Message,
+                TimeTaken    => $args{ARGSRef}->{'UpdateTimeWorked'}
+            );
+            push ( @{ $args{Actions} }, $Description );
+        }
         else {
             push ( @{ $args{'Actions'} },
-    "Update type was neither correspondence nor comment. Update not recorded"
-                );
+                loc("Update type was neither correspondence nor comment.").
+                " ".
+                loc("Update not recorded.")
+            );
         }
     }
 }
@@ -382,61 +433,66 @@ sub MakeMIMEEntity {
         Cc                  => undef,
         Body                => undef,
         AttachmentFieldName => undef,
-        @_
+        map Encode::encode_utf8($_), @_,
     );
 
     #Make the update content have no 'weird' newlines in it
 
     $args{'Body'} =~ s/\r\n/\n/gs;
-    my $Message = MIME::Entity->build(
-        Subject => $args{'Subject'} || "",
-        From    => $args{'From'},
-        Cc      => $args{'Cc'},
-        Data    => [ $args{'Body'} ]
-    );
+    my $Message;
+    {
+        # MIME::Head is not happy in utf-8 domain.  This only happens
+        # when processing an incoming email (so far observed).
+        no utf8;
+        use bytes;
+        $Message = MIME::Entity->build(
+            Subject => $args{'Subject'} || "",
+            From    => $args{'From'},
+            Cc      => $args{'Cc'},
+            Data    => [ $args{'Body'} ]
+        );
+    }
 
-    my $cgi_object = CGIObject();
-    if ( $cgi_object->param( $args{'AttachmentFieldName'} ) ) {
+    my $cgi_object = $m->cgi_object;
 
-        my $cgi_filehandle =
-          $cgi_object->upload( $args{'AttachmentFieldName'} );
+    if (my $filehandle = $cgi_object->upload( $args{'AttachmentFieldName'} ) ) {
 
-        use File::Temp qw(tempfile tempdir);
 
-        #foreach my $filehandle (@filenames) {
 
-        # my ( $fh, $temp_file ) = tempfile();
+    use File::Temp qw(tempfile tempdir);
 
-        #$binmode $fh;    #thank you, windows
+    #foreach my $filehandle (@filenames) {
 
-        # We're having trouble with tempfiles not getting created. Let's try it with 
-        # a scalar instead
+    my ( $fh, $temp_file ) = tempfile();
 
-        my ( $buffer, @file );
+    binmode $fh;    #thank you, windows
+    my ($buffer);
+    while ( my $bytesread = read( $filehandle, $buffer, 4096 ) ) {
+        print $fh $buffer;
+    }
 
-        while ( my $bytesread = read( $cgi_filehandle, $buffer, 4096 ) ) {
-            push ( @file, $buffer );
-        }
+    my $uploadinfo = $cgi_object->uploadInfo($filehandle);
 
-        $RT::Logger->debug($file);
-        my $filename = "$cgi_filehandle";
-        $filename =~ s#^(.*)/##;
-        $filename =~ s#^(.*)\\##;
-        my $uploadinfo = $cgi_object->uploadInfo($cgi_filehandle);
-        $Message->attach(
-            Data => \@file,
-
-            #Path     => $temp_file,
-            Filename => $filename,
-            Type     => $uploadinfo->{'Content-Type'}
-        );
+    # Prefer the cached name first over CGI.pm stringification.
+    my $filename = $RT::Mason::CGI::Filename;
+    $filename = "$filehandle" unless defined($filename);
+                   
+    $filename =~ s#^.*[\\/]##;
+
+    $Message->attach(
+        Path     => $temp_file,
+        Filename => $filename,
+        Type     => $uploadinfo->{'Content-Type'},
+    );
+    close($fh);
 
-        #close($fh);
-        #unlink($temp_file);
+    #   }
 
-        #      }
     }
+
     $Message->make_singlepart();
+    RT::I18N::SetMIMEEntityToUTF8($Message); # convert text parts into utf-8
+
     return ($Message);
 
 }
@@ -485,6 +541,9 @@ sub ProcessSearchQuery {
     elsif ( $args{ARGS}->{'GotoPage'} eq 'Prev' ) {
         $session{'tickets'}->PrevPage;
     }
+    elsif ( $args{ARGS}->{'GotoPage'} > 0 ) {
+        $session{'tickets'}->GotoPage( $args{ARGS}->{GotoPage} - 1 );
+    }
 
     # }}}
 
@@ -576,8 +635,12 @@ sub ProcessSearchQuery {
     # }}}
     # {{{ Limit Subject
     if ( $args{ARGS}->{'ValueOfSubject'} ne '' ) {
+            my $val = $args{ARGS}->{'ValueOfSubject'};
+        if ($args{ARGS}->{'SubjectOp'} =~ /like/) {
+            $val = "%".$val."%";
+        }
         $session{'tickets'}->LimitSubject(
-            VALUE    => $args{ARGS}->{'ValueOfSubject'},
+            VALUE    => $val,
             OPERATOR => $args{ARGS}->{'SubjectOp'},
         );
     }
@@ -585,40 +648,59 @@ sub ProcessSearchQuery {
     # }}}    
     # {{{ Limit Dates
     if ( $args{ARGS}->{'ValueOfDate'} ne '' ) {
-
         my $date = ParseDateToISO( $args{ARGS}->{'ValueOfDate'} );
         $args{ARGS}->{'DateType'} =~ s/_Date$//;
 
-        $session{'tickets'}->LimitDate(
-            FIELD    => $args{ARGS}->{'DateType'},
-            VALUE    => $date,
-            OPERATOR => $args{ARGS}->{'DateOp'},
-        );
+        if ( $args{ARGS}->{'DateType'} eq 'Updated' ) {
+            $session{'tickets'}->LimitTransactionDate(
+                                            VALUE    => $date,
+                                            OPERATOR => $args{ARGS}->{'DateOp'},
+            );
+        }
+        else {
+            $session{'tickets'}->LimitDate( FIELD => $args{ARGS}->{'DateType'},
+                                            VALUE => $date,
+                                            OPERATOR => $args{ARGS}->{'DateOp'},
+            );
+        }
     }
 
     # }}}    
     # {{{ Limit Content
-    if ( $args{ARGS}->{'ValueOfContent'} ne '' ) {
-        $session{'tickets'}->LimitContent(
-            VALUE    => $args{ARGS}->{'ValueOfContent'},
-            OPERATOR => $args{ARGS}->{'ContentOp'},
+    if ( $args{ARGS}->{'ValueOfAttachmentField'} ne '' ) {
+        my $val = $args{ARGS}->{'ValueOfAttachmentField'};
+        if ($args{ARGS}->{'AttachmentFieldOp'} =~ /like/) {
+            $val = "%".$val."%";
+        }
+        $session{'tickets'}->Limit(
+            FIELD   => $args{ARGS}->{'AttachmentField'},
+            VALUE    => $val,
+            OPERATOR => $args{ARGS}->{'AttachmentFieldOp'},
         );
     }
 
     # }}}   
-    # {{{ Limit KeywordSelects
 
-    foreach my $KeywordSelectId (
-        map { /^KeywordSelect(\d+)$/; $1 }
-        grep { /^KeywordSelect(\d+)$/; } keys %{ $args{ARGS} }
-      )
-    {
-        my $form = $args{ARGS}->{"KeywordSelect$KeywordSelectId"};
-        my $oper = $args{ARGS}->{"KeywordSelectOp$KeywordSelectId"};
-        foreach my $KeywordId ( ref($form) ? @{$form} : ($form) ) {
-            next unless ($KeywordId);
+ # {{{ Limit CustomFields
+
+    foreach my $arg ( keys %{ $args{ARGS} } ) {
+        my $id;
+        if ( $arg =~ /^CustomField(\d+)$/ ) {
+            $id = $1;
+        }
+        else {
+            next;
+        }
+        next unless ( $args{ARGS}->{$arg} );
+
+        my $form = $args{ARGS}->{$arg};
+        my $oper = $args{ARGS}->{ "CustomFieldOp" . $id };
+        foreach my $value ( ref($form) ? @{$form} : ($form) ) {
             my $quote = 1;
-            if ( $KeywordId =~ /^null$/i ) {
+            if ($oper =~ /like/i) {
+                $value = "%".$value."%";
+            }
+            if ( $value =~ /^null$/i ) {
 
                 #Don't quote the string 'null'
                 $quote = 0;
@@ -627,17 +709,16 @@ sub ProcessSearchQuery {
                 $oper = 'IS'     if ( $oper eq '=' );
                 $oper = 'IS NOT' if ( $oper eq '!=' );
             }
-            $session{'tickets'}->LimitKeyword(
-                KEYWORDSELECT => $KeywordSelectId,
-                OPERATOR      => $oper,
-                QUOTEVALUE    => $quote,
-                KEYWORD       => $KeywordId
-            );
+            $session{'tickets'}->LimitCustomField( CUSTOMFIELD => $id,
+                                                   OPERATOR    => $oper,
+                                                   QUOTEVALUE  => $quote,
+                                                   VALUE       => $value );
         }
     }
 
     # }}}
 
+
 }
 
 # }}}
@@ -654,7 +735,7 @@ Returns an ISO date and time in GMT
 sub ParseDateToISO {
     my $date = shift;
 
-    my $date_obj = new RT::Date($CurrentUser);
+    my $date_obj = RT::Date->new($session{'CurrentUser'});
     $date_obj->Set(
         Format => 'unknown',
         Value  => $date
@@ -680,172 +761,82 @@ sub Config {
 # {{{ sub ProcessACLChanges
 
 sub ProcessACLChanges {
-    my $ACLref  = shift;
     my $ARGSref = shift;
 
-    my @CheckACL = @$ACLref;
     my %ARGS     = %$ARGSref;
 
     my ( $ACL, @results );
 
-    # {{{ Add rights
-    foreach $ACL (@CheckACL) {
-        my ($Principal);
 
-        next unless ($ACL);
+    foreach my $arg (keys %ARGS) {
+        if ($arg =~ /GrantRight-(\d+)-(.*?)-(\d+)$/) {
+            my $principal_id = $1;
+            my $object_type = $2;
+            my $object_id = $3;
+            my $rights = $ARGS{$arg};
 
-        # Parse out what we're really talking about. 
-        if ( $ACL =~ /^(.*?)-(\d+)-(.*?)-(\d+)/ ) {
-            my $PrincipalType = $1;
-            my $PrincipalId   = $2;
-            my $Scope         = $3;
-            my $AppliesTo     = $4;
+            my $principal = RT::Principal->new($session{'CurrentUser'});
+            $principal->Load($principal_id);
 
-            # {{{ Create an object called Principal
-            # so we can do rights operations
+            my $obj;
 
-            if ( $PrincipalType eq 'User' ) {
-                $Principal = new RT::User( $session{'CurrentUser'} );
-            }
-            elsif ( $PrincipalType eq 'Group' ) {
-                $Principal = new RT::Group( $session{'CurrentUser'} );
-            }
-            else {
-                Abort("$PrincipalType unknown principal type");
-            }
+            if ($object_type eq 'RT::Queue') {
+                $obj = RT::Queue->new($session{'CurrentUser'});
+                $obj->Load($object_id);      
+            } elsif ($object_type eq 'RT::Group') {
+                $obj = RT::Group->new($session{'CurrentUser'});
+                $obj->Load($object_id);      
 
-            $Principal->Load($PrincipalId)
-              || Abort("$PrincipalType $PrincipalId couldn't be loaded");
-
-            # }}}
-
-            # {{{ load up an RT::ACL object with the same current vals of this ACL
-
-            my $CurrentACL = new RT::ACL( $session{'CurrentUser'} );
-            if ( $Scope eq 'Queue' ) {
-                $CurrentACL->LimitToQueue($AppliesTo);
+            } elsif ($object_type eq 'RT::System') {
+                $obj = $RT::System;
+            } else {
+                push (@results, loc("System Error").
+                                loc("Rights could not be granted for [_1]", $object_type));
+                next;
             }
-            elsif ( $Scope eq 'System' ) {
-                $CurrentACL->LimitToSystem();
-            }
-
-            $CurrentACL->LimitPrincipalToType($PrincipalType);
-            $CurrentACL->LimitPrincipalToId($PrincipalId);
-
-            # }}}
-
-            # {{{ Get the values of the select we're working with 
-            # into an array. it will contain all the new rights that have 
-            # been granted
-            #Hack to turn the ACL returned into an array
-            my @rights =
-              ref( $ARGS{"GrantACE-$ACL"} ) eq 'ARRAY'
-              ? @{ $ARGS{"GrantACE-$ACL"} }
-              : ( $ARGS{"GrantACE-$ACL"} );
-
-            # }}}
-
-            # {{{ Add any rights we need.
 
+            my @rights = ref($ARGS{$arg}) eq 'ARRAY' ? @{$ARGS{$arg}} : ($ARGS{$arg});
             foreach my $right (@rights) {
                 next unless ($right);
-
-                #if the right that's been selected wasn't there before, add it.
-                unless (
-                    $CurrentACL->HasEntry(
-                        RightScope     => "$Scope",
-                        RightName      => "$right",
-                        RightAppliesTo => "$AppliesTo",
-                        PrincipalType  => $PrincipalType,
-                        PrincipalId    => $Principal->Id
-                    )
-                  )
-                {
-
-                    #Add new entry to list of rights.
-                    if ( $Scope eq 'Queue' ) {
-                        my $Queue = new RT::Queue( $session{'CurrentUser'} );
-                        $Queue->Load($AppliesTo);
-                        unless ( $Queue->id ) {
-                            Abort("Couldn't find a queue called $AppliesTo");
-                        }
-
-                        my ( $val, $msg ) = $Principal->GrantQueueRight(
-                            RightAppliesTo => $Queue->id,
-                            RightName      => "$right"
-                        );
-
-                        if ($val) {
-                            push ( @results,
-                                "Granted right $right to "
-                                  . $Principal->Name
-                                  . " for queue "
-                                  . $Queue->Name );
-                        }
-                        else {
-                            push ( @results, $msg );
-                        }
-                    }
-                    elsif ( $Scope eq 'System' ) {
-                        my ( $val, $msg ) = $Principal->GrantSystemRight(
-                            RightAppliesTo => $AppliesTo,
-                            RightName      => "$right"
-                        );
-                        if ($val) {
-                            push ( @results, "Granted system right '$right' to "
-                                  . $Principal->Name );
-                        }
-                        else {
-                            push ( @results, $msg );
-                        }
-                    }
-                }
+                my ($val, $msg) = $principal->GrantRight(Object => $obj, Right => $right);
+                push (@results, $msg);
             }
-
-            # }}}
         }
-    }
-
-    # }}} Add rights
-
-    # {{{ remove any rights that have been deleted
-
-    my @RevokeACE =
-      ref( $ARGS{"RevokeACE"} ) eq 'ARRAY' 
-      ? @{ $ARGS{"RevokeACE"} }
-      : ( $ARGS{"RevokeACE"} );
-
-    foreach my $aceid (@RevokeACE) {
-
-        my $right = new RT::ACE( $session{'CurrentUser'} );
-        $right->Load($aceid);
-        next unless ( $right->id );
+       elsif ($arg =~ /RevokeRight-(\d+)-(.*?)-(\d+)-(.*?)$/) {
+            my $principal_id = $1;
+            my $object_type = $2;
+            my $object_id = $3;
+            my $right = $4;
+
+            my $principal = RT::Principal->new($session{'CurrentUser'});
+            $principal->Load($principal_id);
+            next unless ($right);
+            my $obj;
+
+            if ($object_type eq 'RT::Queue') {
+                $obj = RT::Queue->new($session{'CurrentUser'});
+                $obj->Load($object_id);      
+            } elsif ($object_type eq 'RT::Group') {
+                $obj = RT::Group->new($session{'CurrentUser'});
+                $obj->Load($object_id);      
+
+            } elsif ($object_type eq 'RT::System') {
+                $obj = $RT::System;
+            } else {
+                push (@results, loc("System Error").
+                                loc("Rights could not be revoked for [_1]", $object_type));
+                next;
+            }
+            my ($val, $msg) = $principal->RevokeRight(Object => $obj, Right => $right);
+            push (@results, $msg);
+        }
 
-        my $phrase = "Revoked "
-          . $right->PrincipalType . " "
-          . $right->PrincipalObj->Name
-          . "'s right to "
-          . $right->RightName;
 
-        if ( $right->RightScope eq 'System' ) {
-            $phrase .= ' across all queues.';
-        }
-        else {
-            $phrase .= ' for the queue ' . $right->AppliesToObj->Name . '.';
-        }
-        my ( $val, $msg ) = $right->Delete();
-        if ($val) {
-            push ( @results, $phrase );
-        }
-        else {
-            push ( @results, $msg );
-        }
     }
 
-    # }}}
-
     return (@results);
-}
+
+    }
 
 # }}}
 
@@ -864,6 +855,7 @@ sub UpdateRecordObject {
         ARGSRef       => undef,
         AttributesRef => undef,
         Object        => undef,
+        AttributePrefix => undef,
         @_
     );
 
@@ -872,17 +864,94 @@ sub UpdateRecordObject {
     my $object     = $args{'Object'};
     my $attributes = $args{'AttributesRef'};
     my $ARGSRef    = $args{'ARGSRef'};
+    foreach my $attribute (@$attributes) {
+        my $value;
+        if ( defined $ARGSRef->{$attribute} ) {
+            $value = $ARGSRef->{$attribute};
+        }
+        elsif (
+              defined( $args{'AttributePrefix'} )
+              && defined(
+                  $ARGSRef->{ $args{'AttributePrefix'} . "-" . $attribute }
+              )
+          ) {
+            $value = $ARGSRef->{ $args{'AttributePrefix'} . "-" . $attribute };
+
+        } else {
+                next;
+        }
 
-    foreach $attribute (@$attributes) {
-        if ( ( defined $ARGSRef->{"$attribute"} )
-            and ( $ARGSRef->{"$attribute"} ne $object->$attribute() ) )
-        {
-            $ARGSRef->{"$attribute"} =~ s/\r\n/\n/gs;
+            $value =~ s/\r\n/\n/gs;
+
+        if ($value ne $object->$attribute()){
+
+              my $method = "Set$attribute";
+              my ( $code, $msg ) = $object->$method($value);
+
+              push @results, loc($attribute) . ': ' . loc_fuzzy($msg);
+=for loc
+                                   "[_1] could not be set to [_2].",       # loc
+                                   "That is already the current value",    # loc
+                                   "No value sent to _Set!\n",             # loc
+                                   "Illegal value for [_1]",               # loc
+                                   "The new value has been set.",          # loc
+                                   "No column specified",                  # loc
+                                   "Immutable field",                      # loc
+                                   "Nonexistant field?",                   # loc
+                                   "Invalid data",                         # loc
+                                   "Couldn't find row",                    # loc
+                                   "Missing a primary key?: [_1]",         # loc
+                                   "Found Object",                         # loc
+=cut
+          };
+    }
+    return (@results);
+}
 
-            my $method = "Set$attribute";
-            my ( $code, $msg ) = $object->$method( $ARGSRef->{"$attribute"} );
-            push @results, "$attribute: $msg";
-        }
+# }}}
+
+# {{{ Sub ProcessCustomFieldUpdates
+
+sub ProcessCustomFieldUpdates {
+    my %args = (
+        CustomFieldObj => undef,
+        ARGSRef        => undef,
+        @_
+    );
+
+    my $Object  = $args{'CustomFieldObj'};
+    my $ARGSRef = $args{'ARGSRef'};
+
+    my @attribs = qw( Name Type Description Queue SortOrder);
+    my @results = UpdateRecordObject(
+        AttributesRef => \@attribs,
+        Object        => $Object,
+        ARGSRef       => $ARGSRef
+    );
+
+    if ( $ARGSRef->{ "CustomField-" . $Object->Id . "-AddValue-Name" } ) {
+
+        my ( $addval, $addmsg ) = $Object->AddValue(
+            Name =>
+              $ARGSRef->{ "CustomField-" . $Object->Id . "-AddValue-Name" },
+            Description => $ARGSRef->{ "CustomField-"
+                  . $Object->Id
+                  . "-AddValue-Description" },
+            SortOrder => $ARGSRef->{ "CustomField-"
+                  . $Object->Id
+                  . "-AddValue-SortOrder" },
+        );
+        push ( @results, $addmsg );
+    }
+    my @delete_values = (
+        ref $ARGSRef->{ 'CustomField-' . $Object->Id . '-DeleteValue' } eq
+          'ARRAY' )
+      ? @{ $ARGSRef->{ 'CustomField-' . $Object->Id . '-DeleteValue' } }
+      : ( $ARGSRef->{ 'CustomField-' . $Object->Id . '-DeleteValue' } );
+    foreach my $id (@delete_values) {
+        next unless defined $id;
+        my ( $err, $msg ) = $Object->DeleteValue($id);
+        push ( @results, $msg );
     }
     return (@results);
 }
@@ -913,6 +982,7 @@ sub ProcessTicketBasics {
       Subject
       FinalPriority
       Priority
+      TimeEstimated
       TimeWorked
       TimeLeft
       Status
@@ -934,7 +1004,7 @@ sub ProcessTicketBasics {
     );
 
     # We special case owner changing, so we can use ForceOwnerChange
-    if ( $ARGSRef->{'Owner'} && ( $TicketObj->Owner ne $ARGSRef->{'Owner'} ) ) {
+    if ( $ARGSRef->{'Owner'} && ( $TicketObj->Owner != $ARGSRef->{'Owner'} ) ) {
         my ($ChownType);
         if ( $ARGSRef->{'ForceOwnerChange'} ) {
             $ChownType = "Force";
@@ -945,7 +1015,7 @@ sub ProcessTicketBasics {
 
         my ( $val, $msg ) =
           $TicketObj->SetOwner( $ARGSRef->{'Owner'}, $ChownType );
-        push ( @results, "$msg" );
+        push ( @results, $msg );
     }
 
     # }}}
@@ -955,6 +1025,142 @@ sub ProcessTicketBasics {
 
 # }}}
 
+# {{{ Sub ProcessTicketCustomFieldUpdates
+
+sub ProcessTicketCustomFieldUpdates {
+    my %args = (
+        ARGSRef => undef,
+        @_
+    );
+
+    my @results;
+
+    my $ARGSRef = $args{'ARGSRef'};
+
+    # Build up a list of tickets that we want to work with
+    my %tickets_to_mod;
+    my %custom_fields_to_mod;
+    foreach my $arg ( keys %{$ARGSRef} ) {
+        if ( $arg =~ /^Ticket-(\d+)-CustomField-(\d+)-/ ) {
+
+            # For each of those tickets, find out what custom fields we want to work with.
+            $custom_fields_to_mod{$1}{$2} = 1;
+        }
+    }
+
+    # For each of those tickets
+    foreach my $tick ( keys %custom_fields_to_mod ) {
+        my $Ticket = RT::Ticket->new( $session{'CurrentUser'} );
+        $Ticket->Load($tick);
+
+        # For each custom field  
+        foreach my $cf ( keys %{ $custom_fields_to_mod{$tick} } ) {
+
+           my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
+           $CustomFieldObj->LoadById($cf);
+
+            foreach my $arg ( keys %{$ARGSRef} ) {
+                # since http won't pass in a form element with a null value, we need
+                # to fake it
+                if ($arg =~ /^(.*?)-Values-Magic$/ ) {
+                    # We don't care about the magic, if there's really a values element;
+                    next if (exists $ARGSRef->{$1.'-Values'}) ;
+
+                    $arg = $1."-Values";
+                    $ARGSRef->{$1."-Values"} = undef;
+                
+                }
+                next unless ( $arg =~ /^Ticket-$tick-CustomField-$cf-/ );
+                my @values =
+                  ( ref( $ARGSRef->{$arg} ) eq 'ARRAY' ) 
+                  ? @{ $ARGSRef->{$arg} }
+                  : ( $ARGSRef->{$arg} );
+                if ( ( $arg =~ /-AddValue$/ ) || ( $arg =~ /-Value$/ ) ) {
+                    foreach my $value (@values) {
+                        next unless ($value);
+                        my ( $val, $msg ) = $Ticket->AddCustomFieldValue(
+                            Field => $cf,
+                            Value => $value
+                        );
+                        push ( @results, $msg );
+                    }
+                }
+                elsif ( $arg =~ /-DeleteValues$/ ) {
+                    foreach my $value (@values) {
+                        next unless ($value);
+                        my ( $val, $msg ) = $Ticket->DeleteCustomFieldValue(
+                            Field => $cf,
+                            Value => $value
+                        );
+                        push ( @results, $msg );
+                    }
+                }
+                elsif ( $arg =~ /-Values$/ and $CustomFieldObj->Type !~ /Entry/) {
+                    my $cf_values = $Ticket->CustomFieldValues($cf);
+
+                    my %values_hash;
+                    foreach my $value (@values) {
+                        next unless ($value);
+
+                        # build up a hash of values that the new set has
+                        $values_hash{$value} = 1;
+
+                        unless ( $cf_values->HasEntry($value) ) {
+                            my ( $val, $msg ) = $Ticket->AddCustomFieldValue(
+                                Field => $cf,
+                                Value => $value
+                            );
+                            push ( @results, $msg );
+                        }
+
+                    }
+                    while ( my $cf_value = $cf_values->Next ) {
+                        unless ( $values_hash{ $cf_value->Content } == 1 ) {
+                            my ( $val, $msg ) = $Ticket->DeleteCustomFieldValue(
+                                Field => $cf,
+                                Value => $cf_value->Content
+                            );
+                            push ( @results, $msg);
+
+                        }
+
+                    }
+                }
+                elsif ( $arg =~ /-Values$/ ) {
+                    my $cf_values = $Ticket->CustomFieldValues($cf);
+
+                   # keep everything up to the point of difference, delete the rest
+                   my $delete_flag;
+                   foreach my $old_cf (@{$cf_values->ItemsArrayRef}) {
+                       if (!$delete_flag and @values and $old_cf->Content eq $values[0]) {
+                           shift @values;
+                           next;
+                       }
+
+                       $delete_flag ||= 1;
+                       $old_cf->Delete;
+                   }
+
+                   # now add/replace extra things, if any
+                   foreach my $value (@values) {
+                       my ( $val, $msg ) = $Ticket->AddCustomFieldValue(
+                           Field => $cf,
+                           Value => $value
+                       );
+                       push ( @results, $msg );
+                   }
+               }
+                else {
+                    push ( @results, "User asked for an unknown update type for custom field " . $cf->Name . " for ticket " . $Ticket->id );
+                }
+            }
+        }
+        return (@results);
+    }
+}
+
+# }}}
+
 # {{{ sub ProcessTicketWatchers
 
 =head2 ProcessTicketWatchers ( TicketObj => $Ticket, ARGSRef => \%ARGS );
@@ -978,18 +1184,22 @@ sub ProcessTicketWatchers {
 
     foreach my $key ( keys %$ARGSRef ) {
 
-        # Delete deletable watchers
-        if ( ( $key =~ /^DelWatcher(\d*)$/ ) and ( $ARGSRef->{$key} ) ) {
-            my ( $code, $msg ) = $Ticket->DeleteWatcher($1);
+        # {{{ Delete deletable watchers
+        if ( ( $key =~ /^Ticket-DelWatcher-Type-(.*)-Principal-(\d+)$/ )  ) {
+            my ( $code, $msg ) = 
+                $Ticket->DeleteWatcher(PrincipalId => $2,
+                                       Type => $1);
             push @results, $msg;
         }
 
         # Delete watchers in the simple style demanded by the bulk manipulator
         elsif ( $key =~ /^Delete(Requestor|Cc|AdminCc)$/ ) {
-            my ( $code, $msg ) = $Ticket->DeleteWatcher( $ARGSRef->{$key}, $1 );
+            my ( $code, $msg ) = $Ticket->DeleteWatcher( Type => $ARGSRef->{$key}, PrincipalId => $1 );
             push @results, $msg;
         }
 
+        # }}}
+
         # Add new wathchers by email address      
         elsif ( ( $ARGSRef->{$key} =~ /^(AdminCc|Cc|Requestor)$/ )
             and ( $key =~ /^WatcherTypeEmail(\d*)$/ ) )
@@ -1014,12 +1224,11 @@ sub ProcessTicketWatchers {
 
         # Add new  watchers by owner
         elsif ( ( $ARGSRef->{$key} =~ /^(AdminCc|Cc|Requestor)$/ )
-            and ( $key =~ /^WatcherTypeUser(\d*)$/ ) )
-        {
+            and ( $key =~ /^Ticket-AddWatcher-Principal-(\d*)$/ ) ) {
 
             #They're in this order because otherwise $1 gets clobbered :/
             my ( $code, $msg ) =
-              $Ticket->AddWatcher( Type => $ARGSRef->{$key}, Owner => $1 );
+              $Ticket->AddWatcher( Type => $ARGSRef->{$key}, PrincipalId => $1 );
             push @results, $msg;
         }
     }
@@ -1061,7 +1270,7 @@ sub ProcessTicketDates {
     );
 
     #Run through each field in this list. update the value if apropriate
-    foreach $field (@date_fields) {
+    foreach my $field (@date_fields) {
         my ( $code, $msg );
 
         my $DateObj = RT::Date->new( $session{'CurrentUser'} );
@@ -1098,11 +1307,9 @@ Returns an array of results messages.
 =cut
 
 sub ProcessTicketLinks {
-    my %args = (
-        TicketObj => undef,
-        ARGSRef   => undef,
-        @_
-    );
+    my %args = ( TicketObj => undef,
+                 ARGSRef   => undef,
+                 @_ );
 
     my $Ticket  = $args{'TicketObj'};
     my $ARGSRef = $args{'ARGSRef'};
@@ -1118,11 +1325,9 @@ sub ProcessTicketLinks {
 
             push @results,
               "Trying to delete: Base: $base Target: $target  Type $type";
-            my ( $val, $msg ) = $Ticket->DeleteLink(
-                Base   => $base,
-                Type   => $type,
-                Target => $target
-            );
+            my ( $val, $msg ) = $Ticket->DeleteLink( Base   => $base,
+                                                     Type   => $type,
+                                                     Target => $target );
 
             push @results, $msg;
 
@@ -1133,26 +1338,23 @@ sub ProcessTicketLinks {
     my @linktypes = qw( DependsOn MemberOf RefersTo );
 
     foreach my $linktype (@linktypes) {
-
-        for my $luri ( split ( / /, $ARGSRef->{ $Ticket->Id . "-$linktype" } ) )
-        {
-            $luri =~ s/\s*$//;    # Strip trailing whitespace
-            my ( $val, $msg ) = $Ticket->AddLink(
-                Target => $luri,
-                Type   => $linktype
-            );
-            push @results, $msg;
+        if ( $ARGSRef->{ $Ticket->Id . "-$linktype" } ) {
+            for my $luri ( split ( / /, $ARGSRef->{ $Ticket->Id . "-$linktype" } ) ) {
+                $luri =~ s/\s*$//;    # Strip trailing whitespace
+                my ( $val, $msg ) = $Ticket->AddLink( Target => $luri,
+                                                      Type   => $linktype );
+                push @results, $msg;
+            }
         }
+        if ( $ARGSRef->{ "$linktype-" . $Ticket->Id } ) {
 
-        for my $luri ( split ( / /, $ARGSRef->{ "$linktype-" . $Ticket->Id } ) )
-        {
-            my ( $val, $msg ) = $Ticket->AddLink(
-                Base => $luri,
-                Type => $linktype
-            );
+            for my $luri ( split ( / /, $ARGSRef->{ "$linktype-" . $Ticket->Id } ) ) {
+                my ( $val, $msg ) = $Ticket->AddLink( Base => $luri,
+                                                      Type => $linktype );
 
-            push @results, $msg;
-        }
+                push @results, $msg;
+            }
+        } 
     }
 
     #Merge if we need to
@@ -1167,121 +1369,9 @@ sub ProcessTicketLinks {
 
 # }}}
 
-# {{{ sub ProcessTicketObjectKeywords
-
-=head2 ProcessTicketObjectKeywords ( TicketObj => $Ticket, ARGSRef => \%ARGS );
-
-Returns an array of results messages.
-
-=cut
-
-sub ProcessTicketObjectKeywords {
-    my %args = (
-        TicketObj => undef,
-        ARGSRef   => undef,
-        @_
-    );
-
-    my $TicketObj = $args{'TicketObj'};
-    my $ARGSRef   = $args{'ARGSRef'};
-
-    my (@results);
-
-    # {{{ set ObjectKeywords.
-
-    my $KeywordSelects = $TicketObj->QueueObj->KeywordSelects;
-
-    # iterate through all the keyword selects for this queue
-    while ( my $KeywordSelect = $KeywordSelects->Next ) {
-
-        # {{{ do some setup
-
-        # if we have KeywordSelectMagic for this keywordselect:
-        next
-          unless
-          defined $ARGSRef->{ 'KeywordSelectMagic' . $KeywordSelect->id };
-
-        # Lets get a hash of the possible values to work with
-        my $value = $ARGSRef->{ 'KeywordSelect' . $KeywordSelect->id } || [];
-
-        #lets get all those values in a hash. regardless of # of entries
-        #we'll use this for adding and deleting keywords from this object.
-        my %values = map { $_ => 1 } ref($value) ? @{$value} : ($value);
-
-        # Load up the ObjectKeywords for this KeywordSelect for this ticket
-        my $ObjectKeys = $TicketObj->KeywordsObj( $KeywordSelect->id );
-
-        # }}}
-        # {{{ add new keywords
-
-        foreach my $key ( keys %values ) {
-
-            #unless the ticket has that keyword for that keyword select,
-            unless ( $ObjectKeys->HasEntry($key) ) {
-
-                #Add the keyword
-                my ( $result, $msg ) = $TicketObj->AddKeyword(
-                    Keyword       => $key,
-                    KeywordSelect => $KeywordSelect->id
-                );
-                push ( @results, $msg );
-            }
-        }
-
-        # }}}
-        # {{{ Delete unused keywords
-
-        #redo this search, so we don't ask it to delete things that are already gone
-        # such as when a single keyword select gets its value changed.
-        $ObjectKeys = $TicketObj->KeywordsObj( $KeywordSelect->id );
-
-        while ( my $TicketKey = $ObjectKeys->Next ) {
-
-            # if the hash defined above doesn\'t contain the keyword mentioned,
-            unless ( $values{ $TicketKey->Keyword } ) {
-
-                #I'd really love to just call $keyword->Delete, but then 
-                # we wouldn't get a transaction recorded
-                my ( $result, $msg ) = $TicketObj->DeleteKeyword(
-                    Keyword       => $TicketKey->Keyword,
-                    KeywordSelect => $KeywordSelect->id
-                );
-                push ( @results, $msg );
-            }
-        }
-
-        # }}}
-    }
-
-    #Iterate through the keyword selects for BulkManipulator style access
-    while ( my $KeywordSelect = $KeywordSelects->Next ) {
-        if ( $ARGSRef->{ "AddToKeywordSelect" . $KeywordSelect->Id } ) {
-
-            #Add the keyword
-            my ( $result, $msg ) = $TicketObj->AddKeyword(
-                Keyword =>
-                $ARGSRef->{ "AddToKeywordSelect" . $KeywordSelect->Id },
-                KeywordSelect => $KeywordSelect->id
-            );
-            push ( @results, $msg );
-        }
-        if ( $ARGSRef->{ "DeleteFromKeywordSelect" . $KeywordSelect->Id } ) {
-
-            #Delete the keyword
-            my ( $result, $msg ) = $TicketObj->DeleteKeyword(
-                Keyword =>
-                $ARGSRef->{ "DeleteFromKeywordSelect" . $KeywordSelect->Id },
-                KeywordSelect => $KeywordSelect->id
-            );
-            push ( @results, $msg );
-        }
-    }
-
-    # }}}
-
-    return (@results);
-}
-
-# }}}
+eval "require RT::Interface::Web_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web_Vendor.pm});
+eval "require RT::Interface::Web_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web_Local.pm});
 
 1;
diff --git a/rt/lib/RT/Keyword.pm b/rt/lib/RT/Keyword.pm
deleted file mode 100644 (file)
index a41e0a5..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Attic/Keyword.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-
-=head1 NAME
-
- RT::Keyword - Manipulate an RT::Keyword record
-
-=head1 SYNOPSIS
-
-  use RT::Keyword;
-
-  my $keyword = RT::Keyword->new($CurrentUser);
-  $keyword->Create( Name => 'tofu',
-                   Description => 'fermented soy beans',
-                 );
-  
-
-  my $keyword2 = RT::Keyword->new($CurrentUser);
-  $keyword2->Create( Name   => 'beast',
-                   Description => 'a wild animal',
-                   Parent => $keyword->id(),
-                 );
-
-=head1 DESCRIPTION
-
-An B<RT::Keyword> object is an arbitrary string. 
-
-=head1 METHODS
-
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::Scrip);
-
-=end testing
-
-
-=cut 
-package RT::Keyword;
-
-use strict;
-use vars qw(@ISA);
-use Tie::IxHash;
-use RT::Record;
-use RT::Keywords;
-
-@ISA = qw(RT::Record);
-
-# {{{ Core methods
-
-sub _Init {
-    my $self = shift;
-    $self->{'table'} = "Keywords";
-    $self->SUPER::_Init(@_);
-}
-
-sub _Accessible {
-    my $self = shift;
-    my %cols = (
-               Name        => 'read/write', #the keyword itself
-               Description => 'read/write', #a description of the keyword
-               Parent      => 'read/write', #optional id of another B<RT::Keyword>, allowing keywords to be arranged hierarchically
-               Disabled    => 'read/write'
-              );
-    return ($self->SUPER::_Accessible( @_, %cols));
-    
-}
-
-# }}}
-
-
-=over 4
-
-=item new CURRENT_USER
-
-Takes a single argument, an RT::CurrentUser object.  Instantiates a new
-(uncreated) RT::Keyword object.
-
-=cut
-
-# {{{ sub Create
-
-=item Create KEY => VALUE, ...
-
-Takes a list of key/value pairs and creates a the object.  Returns the id of
-the newly created record, or false if there was an error.
-
-Keys are:
-
-Name - the keyword itself
-Description - (not yet used)
-Parent - optional link to another B<RT::Keyword>, allowing keyword to be arranged in a hierarchical fashion.  Can be specified by id or Name.
-
-=cut
-
-sub Create {
-    my $self = shift;
-    my %args = (Name => undef,
-               Description => undef,
-               Parent => 0,
-               @_);
-    
-    unless ($self->CurrentUserHasRight('AdminKeywords')) {
-       return (0, 'Permission Denied');
-    }    
-  
-    if ( $args{'Parent'} && $args{'Parent'} !~ /^\d+$/ ) {
-       $RT::Logger->err( "can't yet specify parents by name, sorry: ". $args{'Parent'});
-       return(0,'Parent must be specified by id');
-    }
-    
-    my $val = $self->SUPER::Create(Name => $args{'Name'},
-                                  Description => $args{'Description'},
-                                  Parent => $args{'Parent'}
-                                 );
-    if ($val) {
-       return ($val, 'Keyword created');
-    }
-    else {
-       return(0,'Could not create keyword');
-    }  
-}
-
-# }}}
-
-# {{{ sub Delete
-
-sub Delete {
-    my $self = shift;
-    
-    return (0, 'Deleting this object would break referential integrity.');
-}
-
-# }}}
-
-# {{{ sub LoadByPath 
-
-=head2 LoadByPath STRING
-
-LoadByPath takes a string.  Whatever character starts the string is assumed to be a delimter.  The routine parses the keyword path description and tries to load the keyword
-described by that path.  It returns a numerical status and a textual message.
-A non-zero status means 'Success'.
-
-=cut
-
-sub LoadByPath {
-    my $self = shift;
-
-    my $path = shift;
-    
-    my $delimiter = substr($path,0,1);
-    my @path_elements = split($delimiter, $path);
-    
-    #throw awya the first bogus path element
-    shift @path_elements;
-    
-    my $parent = 0;
-    my ($tempkey);
-    #iterate through all the path elements loading up a
-    #keyword object. when we're done, this object becomes 
-    #whatever the last tempkey object was.
-    while (my $name = shift @path_elements) {
-       
-       $tempkey = new RT::Keyword($self->CurrentUser);
-
-       my $loaded = $tempkey->LoadByNameAndParentId($name, $parent);
-       
-       #Set the new parent for loading its child.
-       $parent = $tempkey->Id;
-       
-       #If the parent Id is 0, then we're not recursing through the tree
-       # time to bail
-       return (0, "Couldn't find keyword") unless ($tempkey->id());
-
-    }  
-    #Now that we're through with the loop, the last keyword loaded
-    # is the the one we wanted.
-    # we shouldn't need to explicitly load it like this. but we do. Thanks SQL
-    
-    $self->Load($tempkey->Id);
-    
-    return (1, 'Keyword loaded');
-}
-
-
-# }}}
-
-# {{{ sub LoadByNameAndParentId
-
-=head2 LoadByNameAndParentId NAME PARENT_ID
-  
-Takes two arguments, a keyword name and a parent id. Loads a keyword into 
-  the current object.
-
-=cut
-  
-sub LoadByNameAndParentId {
-    my $self = shift;
-    my $name = shift;
-    my $parentid = shift;
-    
-    my $val = $self->LoadByCols( Name => $name, Parent => $parentid);
-    if ($self->Id) {
-       return ($self->Id, 'Keyword loaded');
-    }  
-    else {
-       return (0, 'Keyword could not be found');
-    }
-  }
-
-# }}}
-
-
-# {{{ sub Load
-
-=head2 Load KEYWORD
-
-Loads KEYWORD, either by id if it's an integer or by Path, otherwise
-
-=cut
-
-sub Load {
-    my $self = shift;
-    my $id = shift;
-
-    if (!$id) {
-       return (0, 'No keyword defined');
-    }  
-    if ($id =~ /^(\d+)$/) {
-        return ($self->SUPER::Load($id));
-    }
-    else {
-        return($self->LoadByPath($id));
-    }
-}
-
-
-# }}}
-
-# {{{ sub Path
-
-=item Path
-
-  Returns this Keyword's full path going back to the root. (eg /OS/Unix/Linux/Redhat if 
-this keyword is "Redhat" )
-
-=cut
-
-sub Path {
-    my $self = shift;
-    
-    if ($self->Parent == 0) {
-       return ("/".$self->Name);
-    }
-    else {
-       return ( $self->ParentObj->Path . "/" . $self->Name);
-    }  
-    
-}
-
-# }}}
-
-# {{{ sub RelativePath 
-
-=head2 RelativePath KEYWORD_OBJ
-
-Takes a keyword object.  Returns this keyword's path relative to that
-keyword.  
-
-=item Bugs
-
-Currently assumes that the "other" keyword is a predecessor of this keyword
-
-=cut
-
-sub RelativePath {
-    my $self = shift;
-    my $OtherKey = shift;
-    
-    my $OtherPath = $OtherKey->Path();
-    my $MyPath = $self->Path;
-    $MyPath =~ s/^$OtherPath\///g;
-    return ($MyPath);
-}
-
-
-# }}}
-
-# {{{ sub ParentObj
-
-=item ParentObj
-
-  Returns an RT::Keyword object of this Keyword's 'parents'
-
-=cut
-
-sub ParentObj {
-    my $self = shift;
-    
-    my $ParentObj = new RT::Keyword($self->CurrentUser);
-    $ParentObj->Load($self->Parent);
-    return ($ParentObj);
-}
-
-# }}}
-
-# {{{ sub Children
-
-=item Children
-
-Return an RT::Keywords object  this Object's children.
-
-=cut
-
-sub Children {
-    my $self = shift;
-    
-    my $Children = new RT::Keywords($self->CurrentUser);
-    $Children->LimitToParent($self->id);
-    return ($Children);
-}
-
-# }}}
-
-# {{{ sub Descendents
-
-=item Descendents [ NUM_GENERATIONS [ EXCLUDE_HASHREF ]  ]
-
-Returns an ordered (see L<Tie::IxHash>) hash reference of the descendents of
-this keyword, possibly limited to a given number of generations.  The keys
-are B<RT::Keyword> I<id>s, and the values are strings containing the I<Name>s
-of those B<RT::Keyword>s.
-
-=cut
-
-sub Descendents {
-    my $self = shift;
-    my $generations = shift || 0;
-    my $exclude = shift || {};
-    my %results;
-    
-
-    tie %results, 'Tie::IxHash';
-    my $Keywords = new RT::Keywords($self->CurrentUser);
-    $Keywords->LimitToParent($self->id || 0 ); #If we have no id, start at the top
-    
-    while ( my $Keyword = $Keywords->Next ) {
-       
-       next if defined $exclude->{ $Keyword->id };
-       $results{ $Keyword->id } = $Keyword->Name;
-               
-       if ( $generations == 0 || $generations > 1 ) {
-           #if we're limiting to some number of generations,
-           # decrement the number of generations
-
-           my $nextgen = $generations;
-           $nextgen-- if ( $nextgen > 1 );
-           
-           my $kids = $Keyword->Descendents($nextgen, \%results);
-           
-           foreach my $kid ( keys %{$kids}) {
-               $results{"$kid"} = $Keyword->Name. "/". $kids->{"$kid"};
-           }
-       }
-    }
-    return(\%results);
-}
-
-# }}}
-
-# {{{ ACL related methods
-
-# {{{ sub _Set
-
-# does an acl check and then passes off the call
-sub _Set {
-    my $self = shift;
-    
-    unless ($self->CurrentUserHasRight('AdminKeywords')) {
-       return (0,'Permission Denied');
-    }
-    return $self->SUPER::_Set(@_);
-}
-
-# }}}
-
-# {{{ sub CurrentUserHasRight
-
-=head2 CurrentUserHasRight
-
-Helper menthod for HasRight. Presets Principal to CurrentUser then 
-calls HasRight.
-
-=cut
-
-sub CurrentUserHasRight {
-    my $self = shift;
-    my $right = shift;
-    return ($self->HasRight( Principal => $self->CurrentUser->UserObj,
-                             Right => $right ));
-    
-}
-
-# }}}
-
-# {{{ sub HasRight
-
-=head2 HasRight
-
-Takes a param-hash consisting of "Right" and "Principal"  Principal is 
-an RT::User object or an RT::CurrentUser object. "Right" is a textual
-Right string that applies to Keywords.
-
-=cut
-
-sub HasRight {
-    my $self = shift;
-    my %args = ( Right => undef,
-                 Principal => undef,
-                 @_ );
-
-    return( $args{'Principal'}->HasSystemRight( $args{'Right'}) );
-
-}
-# }}}
-
-# }}}
-
-=back
-
-=head1 AUTHOR
-
-Ivan Kohler <ivan-rt@420.am>
-
-=head1 BUGS
-
-Yes.
-
-=head1 SEE ALSO
-
-L<RT::Keywords>, L<RT::ObjectKeyword>, L<RT::ObjectKeywords>, L<RT::Ticket>,
-L<RT::Record>
-
-[A=cut
-
-1;
-
diff --git a/rt/lib/RT/KeywordSelect.pm b/rt/lib/RT/KeywordSelect.pm
deleted file mode 100644 (file)
index 6865216..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Attic/KeywordSelect.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-
-package RT::KeywordSelect;
-
-use strict;
-use vars qw(@ISA);
-use RT::Record;
-use RT::Keyword;
-
-@ISA = qw(RT::Record);
-
-# {{{ POD
-
-=head1 NAME
-
- RT::KeywordSelect - Manipulate an RT::KeywordSelect record
-
-=head1 SYNOPSIS
-
-  use RT::KeywordSelect;
-
-  my $keyword_select = RT::KeywordSelect->new($CurrentUser);
-  $keyword_select->Create(
-    Keyword     => 20,
-    ObjectType => 'Ticket',
-    Name       => 'Choices'
-  );
-
-  my $keyword_select = RT::KeywordSelect->new($CurrentUser);
-  $keyword_select->Create(
-    Name        => 'Choices',                    
-    Keyword     => 20,
-    ObjectType  => 'Ticket',
-    ObjectField => 'Queue',
-    ObjectValue => 1,
-    Single      => 1,
-    Depth => 4,
-  );
-
-=head1 DESCRIPTION
-
-An B<RT::KeywordSelect> object is a link between a Keyword and a object
-type (one of: Ticket), titled by the I<Name> field of the B<RT::Keyword> such
-that:
-
-=over 4
-
-=item Object display will contain a field, titled with the I<Name> field and
-  showing any descendent keywords which are related to this object via the
-  B<RT::ObjectKeywords> table.
-
-=item Object creation for this object will contain a field titled with the
-  I<Name> field and containing the descendents of the B<RT::Keyword> as
-  choices.  If the I<Single> field of this B<RT::KeywordSelect> is true, each
-  object must be associated (via an B<RT::ObjectKeywords> record) to a single
-  descendent.  If the I<Single> field is false, each object may be connect to
-  zero, one, or many descendents.
-
-=item Searches for this object type will contain a selection field titled with
-  the I<Name> field and containing the descendents of the B<RT::Keyword> as
-  choices.
-
-=item If I<ObjectField> is defined (one of: Queue), all of the above apply only
-  when the value of I<ObjectField> (Queue) in B<ObjectType> (Ticket) matches
-  I<ObjectValue>.
-
-=back
-
-
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::KeywordSelects);
-
-=end testing
-
-
-=head1 METHODS
-
-
-=cut
-
-
-=over 4
-
-=item new CURRENT_USER
-
-Takes a single argument, an RT::CurrentUser object.  Instantiates a new
-(uncreated) RT::KeywordSelect object.
-
-=cut
-# }}}
-
-# {{{ sub _Init
-sub _Init {
-    my $self = shift;
-    $self->{'table'} = "KeywordSelects";
-    $self->SUPER::_Init(@_);
-}
-# }}}
-
-# {{{ sub _Accessible
-sub _Accessible {
-    my $self = shift;
-    my %Cols = (
-               Name => 'read/write',
-               Keyword => 'read/write', # link to Keywords.  Can be specified by id
-               Single => 'read/write', # bool (described below)
-
-               Depth => 'read/write', #- If non-zero, limits the descendents to this number of levels deep.
-               ObjectType  => 'read/write', # currently only C<Ticket>
-               ObjectField => 'read/write', #optional, currently only C<Queue>
-               ObjectValue => 'read/write', #constrains KeywordSelect function to when B<ObjectType>.I<ObjectField> equals I<ObjectValue>
-               Disabled => 'read/write'
-              );
-    return($self->SUPER::_Accessible(@_, %Cols));  
-}
-# }}}
-
-# {{{ sub LoadByName
-
-=head2 LoadByName( Name => [NAME], Queue => [QUEUE_ID])
-.  Takes a queue id and a keyword select name. 
-    tries to load the keyword select for that queue. if that fails, it tries to load it
-    without a queue specified.
-
-=cut
-
-
-sub LoadByName {
-    my $self = shift;
-    my %args = ( Name => undef,
-                Queue => undef,
-                @_
-              );
-    if ($args{'Queue'}) {
-       #Try to get the keyword select for this queue
-       $self->LoadByCols( Name => $args{'Name'}, 
-                          ObjectType => 'Ticket', 
-                          ObjectField => 'Queue', 
-                          ObjectValue => $args{'Queue'});
-    }  
-    unless ($self->Id) { #if that failed to load an object
-       #Try to get the keyword select of that name that's global
-       $self->LoadByCols( Name => $args{'Name'}, 
-                          ObjectType => 'Ticket', 
-                          ObjectField => 'Queue', 
-                          ObjectValue => '0');
-    }
-    
-    return($self->Id);
-    
-}
-
-# }}}
-
-# {{{ sub Create
-=item Create KEY => VALUE, ...
-
-Takes a list of key/value pairs and creates a the object.  Returns the id of
-the newly created record, or false if there was an error.
-
-Keys are:
-
-Keyword - link to Keywords.  Can be specified by id.
-Name - A name for this KeywordSelect
-Single - bool (described above)
-Depth - If non-zero, limits the descendents to this number of levels deep.
-ObjectType - currently only C<Ticket>
-ObjectField - optional, currently only C<Queue>
-ObjectValue - constrains KeywordSelect function to when B<ObjectType>.I<ObjectField> equals I<ObjectValue>
-
-=cut
-
-sub Create {
-    my $self = shift;
-    my %args = ( Keyword => undef,
-                Single => 1,
-                Depth => 0,
-                Name => undef,
-                ObjectType => undef,
-                ObjectField => undef,
-                ObjectValue => undef,
-                @_);
-
-    #If we're talking about a keyword select based on a ticket's 'Queue' field
-    if  ( ($args{'ObjectField'} eq 'Queue') and
-         ($args{'ObjectType'} eq 'Ticket')) {
-       
-       #If we're talking about a keywordselect for all queues
-       if ($args{'ObjectValue'} == 0) {
-           unless( $self->CurrentUserHasSystemRight('AdminKeywordSelects')) {
-               return (0, 'Permission Denied');
-           }
-       }  
-       #otherwise, we're talking about a keywordselect for a specific queue
-       else {
-           unless ($self->CurrentUserHasQueueRight( Right => 'AdminKeywordSelects',
-                                                    Queue => $args{'ObjectValue'})) {
-               return (0, 'Permission Denied');
-           }
-       }
-    }
-    else {
-       return (0, "Can't create a KeywordSelect for that object/field combo");
-    }
-
-    my $Keyword = new RT::Keyword($self->CurrentUser);
-
-    if ( $args{'Keyword'} && $args{'Keyword'} !~ /^\d+$/ ) {
-       $Keyword->LoadByPath($args{'Keyword'});
-    }  
-    else {
-       $Keyword->Load($args{'Keyword'});
-    }
-
-    unless ($Keyword->Id) {
-       $RT::Logger->debug("Keyword ".$args{'Keyword'} ." not found\n");
-       return(0, 'Keyword not found');
-    }
-    
-    $args{'Name'} = $Keyword->Name if  (!$args{'Name'});
-    
-    my $val = $self->SUPER::Create( Name => $args{'Name'},
-                                   Keyword => $Keyword->Id,
-                                   Single => $args{'Single'},
-                                   Depth => $args{'Depth'},
-                                   ObjectType => $args{'ObjectType'},
-                                   ObjectField => $args{'ObjectField'},
-                                   ObjectValue => $args{'ObjectValue'});
-    if ($val) {
-       return ($val, 'KeywordSelect Created');
-    }
-    else {
-       return (0, 'System error. KeywordSelect not created');
-       
-    }
-}
-# }}}
-
-# {{{ sub Delete
-
-sub Delete {
-    my $self = shift;
-    
-    return (0, 'Deleting this object would break referential integrity.');
-}
-
-# }}}
-
-
-# {{{ sub SetDisabled
-
-=head2 Sub SetDisabled
-
-Toggles the KeywordSelect's disabled flag.
-
-
-=cut 
-
-sub SetDisabled {
-    my $self = shift;
-    my $value = shift;
-
-    unless ($self->CurrentUserHasRight('AdminKeywordSelects')) {
-       return (0, "Permission Denied");
-    }
-    return($self->_Set(Field => 'Disabled', Value => $value));
-}
-
-# }}}
-
-# {{{ sub KeywordObj
-
-=item KeywordObj
-
-Returns the B<RT::Keyword> referenced by the I<Keyword> field.
-
-=cut
-
-sub KeywordObj {
-    my $self = shift;
-
-    my $Keyword = new RT::Keyword($self->CurrentUser);
-    $Keyword->Load( $self->Keyword ); #or ?
-    return($Keyword);
-} 
-# }}}
-
-# {{{ sub Object
-
-=item Object
-
-Returns the object (currently only RT::Queue) specified by ObjectField and ObjectValue.
-
-=cut
-
-sub Object {
-    my $self = shift;
-    if ( $self->ObjectField eq 'Queue' ) {
-       my $Queue = new RT::Queue($self->CurrentUser);
-       $Queue->Load( $self->ObjectValue );
-       return ($Queue);
-    } else {
-       $RT::Logger->error("$self trying to load an object value for a non-queue object");
-       return (undef);
-    }
-}
-
-# }}}
-
-# {{{ sub _Set
-
-# does an acl check, then passes off the call
-sub _Set {
-    my $self = shift;
-
-    unless ($self->CurrentUserHasRight('AdminKeywordSelects')) {
-       return (0, "Permission Denied");
-    }
-    
-    return ($self->SUPER::_Set(@_));
-
-}
-
-# }}}
-
-
-# {{{ sub CurrentUserHasQueueRight 
-
-=head2 CurrentUserHasQueueRight ( Queue => QUEUEID, Right => RIGHTNANAME )
-
-Check to see whether the current user has the specified right for the specified queue.
-
-=cut
-
-sub CurrentUserHasQueueRight {
-    my $self = shift;
-    my %args = (Queue => undef,
-               Right => undef,
-               @_
-               );
-    return ($self->HasRight( Right => $args{'Right'},
-                            Principal => $self->CurrentUser->UserObj,
-                            Queue => $args{'Queue'}));
-}
-
-# }}}
-
-# {{{ sub CurrentUserHasSystemRight 
-
-=head2 CurrentUserHasSystemRight RIGHTNAME
-
-Check to see whether the current user has the specified right for the 'system' scope.
-
-=cut
-
-sub CurrentUserHasSystemRight {
-    my $self = shift;
-    my $right = shift;
-    $RT::Logger->debug("$self in hashsysright for right $right\n");
-    return ($self->HasRight( Right => $right,
-                            System => 1,
-                            Principal => $self->CurrentUser->UserObj));
-}
-
-# }}}
-
-# {{{ sub CurrentUserHasRight
-
-=item CurrentUserHasRight RIGHT  [QUEUEID]
-
-Takes a rightname as a string. Can take a queue id as a second
-optional parameter, which can be useful to a routine like create.
-Helper menthod for HasRight. Presets Principal to CurrentUser then 
-calls HasRight.
-
-=cut
-
-sub CurrentUserHasRight {
-    my $self = shift;
-    my $right = shift;
-    return ($self->HasRight( Principal => $self->CurrentUser->UserObj,
-                             Right => $right,
-                          ));
-}
-
-# }}}
-
-# {{{ sub HasRight
-
-=item HasRight
-
-Takes a param-hash consisting of "Right" and "Principal"  Principal is 
-an RT::User object or an RT::CurrentUser object. "Right" is a textual
-Right string that applies to KeywordSelects
-
-=cut
-
-sub HasRight {
-    my $self = shift;
-    my %args = ( Right => undef,
-                 Principal => undef,
-                Queue => undef,
-                System => undef,
-                 @_ );
-
-    #If we're explicitly specifying a queue, as we need to do on create
-    if ($args{'Queue'}) {
-       return ($args{'Principal'}->HasQueueRight(Right => $args{'Right'},
-                                                 Queue => $args{'Queue'}));
-    }
-    #else if we're specifying to check a system right
-    elsif ($args{'System'}) {
-        return( $args{'Principal'}->HasSystemRight( $args{'Right'} ));
-    }  
-
-    #else if we 're using the object's queue
-    elsif (($self->__Value('ObjectField') eq 'Queue') and
-          ($self->__Value('ObjectValue') > 0 )) {
-        return ($args{'Principal'}->HasQueueRight(Right => $args{'Right'},
-                                                 Queue => $self->__Value('ObjectValue') )); 
-    }
-    
-    #If the object is system scoped.
-    else {
-        return( $args{'Principal'}->HasSystemRight( $args{'Right'} ));
-    }
-}
-
-# }}}
-
-=back
-
-=head1 AUTHORS
-
-Ivan Kohler <ivan-rt@420.am>, Jesse Vincent <jesse@fsck.com>
-
-=head1 BUGS
-
-The ACL system for this object is more byzantine than it should be.  reworking it eventually
-would be a good thing.
-
-=head1 SEE ALSO
-
-L<RT::KeywordSelects>, L<RT::Keyword>, L<RT::Keywords>, L<RT::ObjectKeyword>,
-L<RT::ObjectKeywords>, L<RT::Record>
-
-=cut
-
-1;
-
diff --git a/rt/lib/RT/KeywordSelects.pm b/rt/lib/RT/KeywordSelects.pm
deleted file mode 100644 (file)
index c220b39..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Attic/KeywordSelects.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-
-
-
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::Scrip);
-
-=end testing
-
-=cut
-
-
-package RT::KeywordSelects;
-
-use strict;
-use vars qw( @ISA );
-use RT::EasySearch;
-use RT::KeywordSelect;
-
-@ISA = qw( RT::EasySearch );
-
-# {{{ _Init
-sub _Init {
-  my $self = shift;
-  $self->{'table'} = 'KeywordSelects';
-  $self->{'primary_key'} = 'id';
-  return ($self->SUPER::_Init(@_));
-}
-# }}}
-
-# {{{ sub _DoSearch 
-
-=head2 _DoSearch
-
-  A subclass of DBIx::SearchBuilder::_DoSearch that makes sure that _Disabled rows never get seen unless
-we're explicitly trying to see them.
-
-=cut
-
-sub _DoSearch {
-    my $self = shift;
-    
-    #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
-    unless($self->{'find_disabled_rows'}) {
-       $self->LimitToEnabled();
-    }
-    
-    return($self->SUPER::_DoSearch(@_));
-    
-}
-
-# }}}
-
-# {{{ sub LimitToQueue
-=head2 LimitToQueue 
-
-Takes a queue id. Limits the returned set to KeywordSelects for that queue.
-Repeated calls will be OR'd together.
-
-=cut
-
-sub LimitToQueue {
-    my $self = shift;
-    my $queue = shift;
-
-    $self->Limit( FIELD => 'ObjectValue',
-                 VALUE => $queue,
-                 OPERATOR => '=',
-                 ENTRYAGGREGATOR => 'OR'
-               );
-
-    $self->Limit( FIELD => 'ObjectType',
-                 VALUE => 'Ticket',
-                 OPERATOR => '=');
-
-    $self->Limit( FIELD => 'ObjectField',
-                 VALUE => 'Queue',
-                 OPERATOR => '=');
-
-    
-}
-# }}}
-
-# {{{ sub LimitToGlobals
-
-=head2 LimitToGlobals
-
-Limits the returned set to KeywordSelects for all queues.
-Repeated calls will be OR'd together.
-
-=cut
-
-sub LimitToGlobals {
-    my $self = shift;
-
-    $self->Limit( FIELD => 'ObjectType',
-                 VALUE => 'Ticket',
-                 OPERATOR => '=');
-
-    $self->Limit( FIELD => 'ObjectField',
-                 VALUE => 'Queue',
-                 OPERATOR => '=');
-
-    $self->Limit( FIELD => 'ObjectValue',
-                 VALUE => '0',
-                 OPERATOR => '=',
-                 ENTRYAGGREGATOR => 'OR'
-               );
-    
-}
-# }}}
-
-# {{{ sub IncludeGlobals
-=head2 IncludeGlobals
-
-Include KeywordSelects which apply globally in the set of returned results
-
-=cut
-
-
-sub IncludeGlobals {
-    my $self = shift;
-    $self->Limit( FIELD => 'ObjectValue',
-                 VALUE => '0',
-                 OPERATOR => '=',
-                 ENTRYAGGREGATOR => 'OR'
-               );
-    
-
-}
-# }}}
-
-# {{{ sub NewItem
-sub NewItem {
-    my $self = shift;
-    #my $Handle = shift;
-    return (new RT::KeywordSelect($self->CurrentUser));
-}
-# }}}
-1;
-
diff --git a/rt/lib/RT/Keywords.pm b/rt/lib/RT/Keywords.pm
deleted file mode 100644 (file)
index a9ecda2..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Attic/Keywords.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-
-=head1 NAME
-
-  RT::Keywords - a collection of RT::Keyword objects
-
-=head1 SYNOPSIS
-
-  use RT::Keywords;
-  my $keywords = RT::Keywords->new($user);
-  $keywords->LimitToParent(0);
-  while my ($keyword = $keywords->Next()) {
-     print $keyword->Name ."\n";
-  }
-
-
-=head1 DESCRIPTION
-
-
-=head1 METHODS
-
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::Keywords);
-
-=end testing
-
-=cut
-
-package RT::Keywords;
-
-use strict;
-use vars qw( @ISA );
-use RT::EasySearch;
-use RT::Keyword;
-
-@ISA = qw( RT::EasySearch );
-
-
-# {{{ sub _Init
-
-sub _Init {
-    my $self = shift;
-    $self->{'table'} = 'Keywords';
-    $self->{'primary_key'} = 'id';
-
-    # By default, order by name
-    $self->OrderBy( ALIAS => 'main',
-                   FIELD => 'Name',
-                   ORDER => 'ASC');
-
-    return ($self->SUPER::_Init(@_));
-}
-# }}}
-
-# {{{ sub _DoSearch 
-
-=head2 _DoSearch
-
-  A subclass of DBIx::SearchBuilder::_DoSearch that makes sure that _Disabled rows never get seen unless
-we're explicitly trying to see them.
-
-=cut
-
-sub _DoSearch {
-    my $self = shift;
-    
-    #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
-    unless($self->{'find_disabled_rows'}) {
-       $self->LimitToEnabled();
-    }
-    
-    return($self->SUPER::_DoSearch(@_));
-    
-}
-
-# }}}
-
-# {{{ sub NewItem 
-sub NewItem {
-    my $self = shift;
-    return (RT::Keyword->new($self->CurrentUser));
-}
-# }}}
-
-# {{{ sub LimitToParent
-
-=head2 LimitToParent
-
-Takes a parent id and limits the returned keywords to children of that parent.
-
-=cut
-
-sub LimitToParent {
-    my $self = shift;
-    my $parent = shift;
-    $self->Limit( FIELD => 'Parent',
-                 VALUE => $parent,
-                 OPERATOR => '=',
-                 ENTRYAGGREGATOR => 'OR' );
-}      
-# }}}
-
-1;
-
index 885ffe3..962c378 100644 (file)
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Link.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# (c) 1996-1999 Jesse Vincent <jesse@fsck.com>
-# This software is redistributable under the terms of the GNU GPL
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
 
 =head1 NAME
 
-  RT::Link - an RT Link object
+RT::Link
 
-=head1 SYNOPSIS
 
-  use RT::Link;
+=head1 SYNOPSIS
 
 =head1 DESCRIPTION
 
-This module should never be called directly by client code. it's an internal module which
-should only be accessed through exported APIs in Ticket other similar objects.
-
 =head1 METHODS
 
+=cut
 
-=begin testing
+package RT::Link;
+use RT::Record; 
 
-ok (require RT::TestHarness);
-ok (require RT::Link);
 
-=end testing
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
 
-=cut
+sub _Init {
+  my $self = shift; 
 
-package RT::Link;
-use RT::Record;
-use Carp;
-@ISA= qw(RT::Record);
-
-# {{{ sub _Init
-sub _Init  {
-  my $self  = shift;
-  $self->{'table'} = "Links";
-  return ($self->SUPER::_Init(@_));
+  $self->Table('Links');
+  $self->SUPER::_Init(@_);
 }
 
-# }}}
 
-# {{{ sub Create 
 
-=head2 Create PARAMHASH
 
-Create a new link object. Takes 'Base', 'Target' and 'Type'.
-Returns undef on failure or a Link Id on success.
+
+=item Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+  varchar(240) 'Base'.
+  varchar(240) 'Target'.
+  varchar(20) 'Type'.
+  int(11) 'LocalTarget'.
+  int(11) 'LocalBase'.
 
 =cut
 
-sub Create  {
+
+
+
+sub Create {
     my $self = shift;
-    my %args = ( Base => undef,
-                Target => undef,
-                Type => undef,
-                @_ # get the real argumentlist
-              );
-    
-    my $BaseURI = $self->CanonicalizeURI($args{'Base'});
-    my $TargetURI = $self->CanonicalizeURI($args{'Target'});
-    
-    unless (defined $BaseURI) {
-       $RT::Logger->warning ("$self couldn't resolve base:'".$args{'Base'}.
-                             "' into a URI\n");
-       return (undef);
-    }
-    unless (defined $TargetURI) {
-       $RT::Logger->warning ("$self couldn't resolve target:'".$args{'Target'}.
-                             "' into a URI\n");
-       return(undef);
-    }
-    
-    my $LocalBase = $self->_IsLocal($BaseURI);
-    my $LocalTarget = $self->_IsLocal($TargetURI);
-    my $id = $self->SUPER::Create(Base => "$BaseURI",
-                                 Target => "$TargetURI",
-                                 LocalBase => $LocalBase, 
-                                 LocalTarget => $LocalTarget,
-                                 Type => $args{'Type'});
-    return ($id);
+    my %args = ( 
+                Base => '',
+                Target => '',
+                Type => '',
+                LocalTarget => '0',
+                LocalBase => '0',
+
+                 @_);
+    $self->SUPER::Create(
+                         Base => $args{'Base'},
+                         Target => $args{'Target'},
+                         Type => $args{'Type'},
+                         LocalTarget => $args{'LocalTarget'},
+                         LocalBase => $args{'LocalBase'},
+);
+
 }
 
-# }}}
-# {{{ sub Load 
 
-=head2 Load
 
-  Load an RT::Link object from the database.  Takes one parameter or three.
-  One parameter is the id of an entry in the links table.  Three parameters are a tuple of (base, linktype, target);
+=item id
+
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
 
 
 =cut
 
-sub Load  {
-  my $self = shift;
-  my $identifier = shift;
-  my $linktype = shift if (@_);
-  my $target = shift if (@_);
-  
-  if ($target) {
-      my $BaseURI = $self->CanonicalizeURI($identifier);
-      my $TargetURI = $self->CanonicalizeURI($target);
-      $self->LoadByCols( Base => $BaseURI,
-                        Type => $linktype,
-                        Target => $TargetURI
-                      ) || return (0, "Couldn't load link");
-  }
-  
-  elsif ($identifier =~ /^\d+$/) {
-      $self->LoadById($identifier) ||
-       return (0, "Couldn't load link");
-  }
-  else {
-       return (0, "That's not a numerical id");
-  }
-}
 
-# }}}
+=item Base
 
-# {{{ sub TargetObj 
+Returns the current value of Base. 
+(In the database, Base is stored as varchar(240).)
 
-=head2 TargetObj
 
-=cut
 
-sub TargetObj {
-  my $self = shift;
-   return $self->_TicketObj('base',$self->Target);
-}
-# }}}
+=item SetBase VALUE
+
 
-# {{{ sub BaseObj
+Set Base to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Base will be stored as a varchar(240).)
 
-=head2 BaseObj
 
 =cut
 
-sub BaseObj {
-  my $self = shift;
-  return $self->_TicketObj('target',$self->Base);
-}
-# }}}
-
-# {{{ sub _TicketObj
-sub _TicketObj {
-  my $self = shift;
-  my $name = shift;
-  my $ref = shift;
-  my $tag="$name\_obj";
-  
-  unless (exists $self->{$tag}) {
-
-  $self->{$tag}=RT::Ticket->new($self->CurrentUser);
-
-  #If we can get an actual ticket, load it up.
-  if ($self->_IsLocal($ref)) {
-      $self->{$tag}->Load($ref);
-    }
-  }
-  return $self->{$tag};
-}
-# }}}
-
-# {{{ sub _Accessible 
-sub _Accessible  {
-  my $self = shift;
-  my %Cols = (
-             LocalBase => 'read',
-             LocalTarget => 'read',
-             Base => 'read',
-             Target => 'read',
-             Type => 'read',
-             Creator => 'read/auto',
-             Created => 'read/auto',
-             LastUpdatedBy => 'read/auto',
-             LastUpdated => 'read/auto'
-            );
-  return($self->SUPER::_Accessible(@_, %Cols));
-}
-# }}}
 
+=item Target
 
-# Static methods:
+Returns the current value of Target. 
+(In the database, Target is stored as varchar(240).)
 
-# {{{ sub BaseIsLocal
 
-=head2 BaseIsLocal
 
-Returns true if the base of this link is a local ticket
+=item SetTarget VALUE
+
+
+Set Target to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Target will be stored as a varchar(240).)
+
 
 =cut
 
-sub BaseIsLocal {
-  my $self = shift;
-  return $self->_IsLocal($self->Base);
-}
 
-# }}}
+=item Type
 
-# {{{ sub TargetIsLocal
+Returns the current value of Type. 
+(In the database, Type is stored as varchar(20).)
 
-=head2 TargetIsLocal
 
-Returns true if the target of this link is a local ticket
+
+=item SetType VALUE
+
+
+Set Type to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Type will be stored as a varchar(20).)
+
 
 =cut
 
-sub TargetIsLocal {
-  my $self = shift;
-  return $self->_IsLocal($self->Target);
-}
 
-# }}}
+=item LocalTarget
+
+Returns the current value of LocalTarget. 
+(In the database, LocalTarget is stored as int(11).)
+
+
+
+=item SetLocalTarget VALUE
 
-# {{{ sub _IsLocal
 
-=head2 _IsLocal URI 
+Set LocalTarget to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, LocalTarget will be stored as a int(11).)
 
-When handed a URI returns the local ticket id if it\'s local. otherwise returns undef.
 
 =cut
 
-sub _IsLocal {
-    my $self = shift;
-    my $URI=shift;
-    unless ($URI) {
-       $RT::Logger->warning ("$self _IsLocal called without a URI\n");
-       return (undef);
-    }
-    # TODO: More thorough check
-    if ($URI =~ /^$RT::TicketBaseURI(\d+)$/) {
-       return($1);
-    }
-    else {
-       return (undef);
-    }
-}
-# }}}
+
+=item LocalBase
+
+Returns the current value of LocalBase. 
+(In the database, LocalBase is stored as int(11).)
+
 
 
-# {{{ sub BaseAsHREF 
+=item SetLocalBase VALUE
 
-=head2 BaseAsHREF
 
-Returns an HTTP url to access the base of this link
+Set LocalBase to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, LocalBase will be stored as a int(11).)
+
 
 =cut
 
-sub BaseAsHREF {
-  my $self = shift;
-  return $self->AsHREF($self->Base);
-}
-# }}}
 
-# {{{ sub TargetAsHREF 
+=item LastUpdatedBy
 
-=head2 TargetAsHREF
+Returns the current value of LastUpdatedBy. 
+(In the database, LastUpdatedBy is stored as int(11).)
 
-return an HTTP url to access the target of this link
 
 =cut
 
-sub TargetAsHREF {
-  my $self = shift;
-  return $self->AsHREF($self->Target);
-}
-# }}}
 
-# {{{ sub AsHREF - Converts Link URIs to HTTP URLs
-=head2 URI
+=item LastUpdated
+
+Returns the current value of LastUpdated. 
+(In the database, LastUpdated is stored as datetime.)
 
-Takes a URI and returns an http: url to access that object.
 
 =cut
-sub AsHREF {
-    my $self=shift;
-    my $URI=shift;
-    if ($self->_IsLocal($URI)) {
-       my $url=$RT::WebURL . "Ticket/Display.html?id=$URI";
-       return($url);
-    } 
-    else {
-       my ($protocol) = $URI =~ m|(.*?)://|;
-       unless (exists $RT::URI2HTTP{$protocol}) {
-           $RT::Logger->warning("Linking for protocol $protocol not defined in the config file!");
-           return("");
-       }
-       return $RT::URI2HTTP{$protocol}->($URI);
-    }
-}
 
-# }}}
-
-# {{{ sub GetContent - gets the content from a link
-sub GetContent {
-    my ($self, $URI)= @_;
-    if ($self->_IsLocal($URI)) {
-       die "stub";
-    } else {
-       # Find protocol
-       if ($URI =~ m|^(.*?)://|) {
-           if (exists $RT::ContentFromURI{$1}) {
-               return $RT::ContentFromURI{$1}->($URI);
-           } else {
-               warn "No sub exists for fetching the content from a $1 in $URI";
-           }
-       } else {
-           warn "No protocol specified in $URI";
-       }
-    }
-}
-# }}}
 
-# {{{ sub CanonicalizeURI
+=item Creator
+
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
 
-=head2 CanonicalizeURI
 
-Takes a single argument: some form of ticket identifier. 
-Returns its canonicalized URI.
+=cut
+
+
+=item Created
+
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
 
-Bug: ticket aliases can't have :// in them. URIs must have :// in them.
 
 =cut
 
-sub CanonicalizeURI {
-    my $self = shift;
-    my $id = shift;
-    
-    
-    #If it's a local URI, load the ticket object and return its URI
-    if ($id =~ /^$RT::TicketBaseURI/) {
-       my $ticket = new RT::Ticket($self->CurrentUser);
-       $ticket->Load($id);
-       #If we couldn't find a ticket, return undef.
-       return undef unless (defined $ticket->Id);
-       #$RT::Logger->debug("$self -> CanonicalizeURI was passed $id and returned ".$ticket->URI ." (uri)\n");
-       return ($ticket->URI);
-    }
-    #If it's a remote URI, we're going to punt for now
-    elsif ($id =~ '://' ) {
-       return ($id);
-    }
-  
-    #If the base is an integer, load it as a ticket 
-    elsif ( $id =~ /^\d+$/ ) {
-       
-       #$RT::Logger->debug("$self -> CanonicalizeURI was passed $id. It's a ticket id.\n");
-       my $ticket = new RT::Ticket($self->CurrentUser);
-       $ticket->Load($id);
-       #If we couldn't find a ticket, return undef.
-       return undef unless (defined $ticket->Id);
-       #$RT::Logger->debug("$self returned ".$ticket->URI ." (id #)\n");
-       return ($ticket->URI);
-    }
-
-    #It's not a URI. It's not a numerical ticket ID
-    else { 
+
+
+sub _ClassAccessible {
+    {
      
-       #If we couldn't find a ticket, return undef.
-       return( undef);
-    
-    }
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        Base => 
+               {read => 1, write => 1, type => 'varchar(240)', default => ''},
+        Target => 
+               {read => 1, write => 1, type => 'varchar(240)', default => ''},
+        Type => 
+               {read => 1, write => 1, type => 'varchar(20)', default => ''},
+        LocalTarget => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        LocalBase => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        LastUpdatedBy => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        LastUpdated => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
 
-}
+ }
+};
+
+
+        eval "require RT::Link_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Link_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Link_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Link_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Link_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Link_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::Link_Overlay, RT::Link_Vendor, RT::Link_Local
+
+=cut
 
-# }}}
 
 1;
diff --git a/rt/lib/RT/Link_Overlay.pm b/rt/lib/RT/Link_Overlay.pm
new file mode 100644 (file)
index 0000000..ac1bc37
--- /dev/null
@@ -0,0 +1,360 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Link - an RT Link object
+
+=head1 SYNOPSIS
+
+  use RT::Link;
+
+=head1 DESCRIPTION
+
+This module should never be called directly by client code. it's an internal module which
+should only be accessed through exported APIs in Ticket other similar objects.
+
+=head1 METHODS
+
+
+=begin testing
+
+
+use RT::Link;
+my $link = RT::Link->new($RT::SystemUser);
+
+
+ok (ref $link);
+ok (UNIVERSAL::isa($link, 'RT::Link'));
+ok (UNIVERSAL::isa($link, 'RT::Base'));
+ok (UNIVERSAL::isa($link, 'RT::Record'));
+ok (UNIVERSAL::isa($link, 'DBIx::SearchBuilder::Record'));
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+
+use Carp;
+use RT::URI;
+
+
+# {{{ sub Create 
+
+=head2 Create PARAMHASH
+
+Create a new link object. Takes 'Base', 'Target' and 'Type'.
+Returns undef on failure or a Link Id on success.
+
+=cut
+
+sub Create {
+    my $self = shift;
+    my %args = ( Base   => undef,
+                 Target => undef,
+                 Type   => undef,
+                 @_ );
+
+    my $base = RT::URI->new( $self->CurrentUser );
+    $base->FromURI( $args{'Base'} );
+
+    unless ( $base->Scheme ) {
+        $RT::Logger->warning( "$self couldn't resolve base:'"
+                              . $args{'Base'} . " - "
+                              . $base->Scheme
+                              . "' into a URI\n" );
+
+        #use Data::Dumper;
+        #$RT::Logger->warning(scalar Dumper $base);
+        return (undef);
+    }
+
+    my $target = RT::URI->new( $self->CurrentUser );
+    $target->FromURI( $args{'Target'} );
+
+    unless ( $target->Resolver ) {
+        $RT::Logger->warning( "$self couldn't resolve target:'"
+                              . $args{'Target'} . " - "
+                              . "' into a URI\n" );
+
+        #use Data::Dumper;
+        #$RT::Logger->warning(scalar Dumper $target);
+        return (undef);
+    }
+
+    my $base_id   = 0;
+    my $target_id = 0;
+
+
+
+
+    if ( $base->IsLocal ) {
+        unless (UNIVERSAL::can($base->Object, 'Id')) {
+            return (undef, $self->loc("[_1] appears to be a local object, but can't be found in the database", $args{'Base'}));
+        
+        }
+        $base_id = $base->Object->Id;
+    }
+    if ( $target->IsLocal ) {
+        unless (UNIVERSAL::can($target->Object, 'Id')) {
+            return (undef, $self->loc("[_1] appears to be a local object, but can't be found in the database", $args{'Target'}));
+        
+        }
+        $target_id = $target->Object->Id;
+    }
+
+    # {{{ We don't want references to ourself
+    if ( $base->URI eq $target->URI ) {
+        return ( 0, $self->loc("Can't link a ticket to itself") );
+    }
+
+    # }}}
+
+    my ( $id, $msg ) = $self->SUPER::Create( Base        => $base->URI,
+                                             Target      => $target->URI,
+                                             LocalBase   => $base_id,
+                                             LocalTarget => $target_id,
+                                             Type        => $args{'Type'} );
+    return ( $id, $msg );
+}
+
+# }}}
+ # {{{ sub LoadByParams
+
+=head2 LoadByParams
+
+  Load an RT::Link object from the database.  Takes three parameters
+  
+  Base => undef,
+  Target => undef,
+  Type =>undef
+  Base and Target are expected to be integers which refer to Tickets or URIs
+  Type is the link type
+
+=cut
+
+sub LoadByParams {
+    my $self = shift;
+    my %args = ( Base   => undef,
+                 Target => undef,
+                 Type   => undef,
+                 @_ );
+
+    my $base = RT::URI->new($self->CurrentUser);
+    $base->FromURI( $args{'Base'} );
+
+    my $target = RT::URI->new($self->CurrentUser);
+    $target->FromURI( $args{'Target'} );
+    
+    unless ($base->Resolver && $target->Resolver) {
+        return ( 0, $self->loc("Couldn't load link") );
+    }
+
+
+    my ( $id, $msg ) = $self->LoadByCols( Base   => $base->URI,
+                                          Type   => $args{'Type'},
+                                          Target => $target->URI );
+
+    unless ($id) {
+        return ( 0, $self->loc("Couldn't load link") );
+    }
+}
+
+# }}}
+# {{{ sub Load 
+
+=head2 Load
+
+  Load an RT::Link object from the database.  Takes one parameter, the id of an entry in the links table.
+
+
+=cut
+
+sub Load {
+    my $self       = shift;
+    my $identifier = shift;
+
+
+
+
+    if ( $identifier !~ /^\d+$/ ) {
+        return ( 0, $self->loc("That's not a numerical id") );
+    }
+    else {
+        my ( $id, $msg ) = $self->LoadById($identifier);
+        unless ( $self->Id ) {
+            return ( 0, $self->loc("Couldn't load link") );
+        }
+        return ( $id, $msg );
+    }
+}
+
+# }}}
+
+
+# {{{ TargetURI
+
+=head2 TargetURI
+
+returns an RT::URI object for the "Target" of this link.
+
+=cut
+
+sub TargetURI {
+    my $self = shift;
+    my $URI = RT::URI->new($self->CurrentUser);
+    $URI->FromURI($self->Target);
+    return ($URI);
+}
+
+# }}}
+# {{{ sub TargetObj 
+
+=head2 TargetObj
+
+=cut
+
+sub TargetObj {
+  my $self = shift;
+   return $self->TargetURI->Object;
+}
+# }}}
+
+# {{{ BaseURI
+
+=head2 BaseURI
+
+returns an RT::URI object for the "Base" of this link.
+
+=cut
+
+sub BaseURI {
+    my $self = shift;
+    my $URI = RT::URI->new($self->CurrentUser);
+    $URI->FromURI($self->Base);
+    return ($URI);
+}
+
+# }}}
+# {{{ sub BaseObj
+
+=head2 BaseObj
+
+=cut
+
+sub BaseObj {
+  my $self = shift;
+  return $self->BaseURI->Object;
+}
+# }}}
+
+
+
+# Static methods:
+
+# {{{ sub BaseIsLocal
+
+=head2 BaseIsLocal
+
+Returns true if the base of this link is a local ticket
+
+=cut
+
+sub BaseIsLocal {
+  my $self = shift;
+  $RT::Logger->crit("Link::BaseIsLocal is deprecated in favor of Link->BaseURI->IsLocal");
+  return $self->BaseURI->IsLocal;
+}
+
+# }}}
+
+# {{{ sub TargetIsLocal
+
+=head2 TargetIsLocal
+
+Returns true if the target of this link is a local ticket
+
+=cut
+
+sub TargetIsLocal {
+  my $self = shift;
+  $RT::Logger->crit("Link::BaseIsLocal is deprecated in favor of Link->BaseURI->IsLocal");
+  return $self->TargetURI->IsLocal;
+}
+
+# }}}
+
+
+# {{{ sub BaseAsHREF 
+
+=head2 BaseAsHREF
+
+Returns an HTTP url to access the base of this link
+
+=cut
+
+sub BaseAsHREF {
+  my $self = shift;
+  $RT::Logger->crit("Link::BaseAsHREF deprecated in favor of ->BaseURI->AsHREF");
+  return $self->BaseURI->HREF;
+}
+# }}}
+
+# {{{ sub TargetAsHREF 
+
+=head2 TargetAsHREF
+
+return an HTTP url to access the target of this link
+
+=cut
+
+sub TargetAsHREF {
+  my $self = shift;
+  $RT::Logger->crit("Link::TargetAsHREF deprecated in favor of ->TargetURI->AsHREF");
+  return $self->TargetURI->HREF;
+}
+# }}}
+
+# {{{ sub AsHREF - Converts Link URIs to HTTP URLs
+
+=head2 URI
+
+Takes a URI and returns an http: url to access that object.
+
+=cut
+
+
+sub AsHREF {
+    my $self=shift;
+   
+    $RT::Logger->crit("AsHREF is gone. look at URI::HREF to figure out what to do with \$URI");
+}
+
+# }}}
+
+1;
index a8180ca..7a1773a 100644 (file)
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Links.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-=head1 NAME
 
-  RT::Links - A collection of Link objects
+=head1 NAME
 
+  RT::Links -- Class Description
 =head1 SYNOPSIS
 
-  use RT::Links;
-  my $links = new RT::Links($CurrentUser);
+  use RT::Links
 
 =head1 DESCRIPTION
 
 
 =head1 METHODS
 
-
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::Links);
-
-=end testing
-
 =cut
 
 package RT::Links;
-use RT::EasySearch;
+
+use RT::SearchBuilder;
 use RT::Link;
 
-@ISA= qw(RT::EasySearch);
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
 
-# {{{ sub _Init  
-sub _Init   {
-  my $self = shift;
-  $self->{'table'} = "Links";
-  $self->{'primary_key'} = "id";
 
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'Links';
+    $self->{'primary_key'} = 'id';
 
-  return ( $self->SUPER::_Init(@_));
-}
-# }}}
 
-# {{{ sub Limit 
-sub Limit  {
-    my $self = shift;
-    my %args = ( ENTRYAGGREGATOR => 'AND',
-                OPERATOR => '=',
-                @_);
-    
-    #if someone's trying to search for tickets, try to resolve the uris for searching.
-    
-    if (  ( $args{'OPERATOR'} eq '=') and
-         ( $args{'FIELD'}  eq 'Base') or ($args{'FIELD'} eq 'Target')
-       ) {
-       my $dummy = $self->NewItem();
-         $uri = $dummy->CanonicalizeURI($args{'VALUE'});
-    }
-
-
-    # If we're limiting by target, order by base
-    # (Order by the thing that's changing)
-
-    if ( ($args{'FIELD'} eq 'Target') or 
-        ($args{'FIELD'} eq 'LocalTarget') ) {
-       $self->OrderBy (ALIAS => 'main',
-                       FIELD => 'Base',
-                       ORDER => 'ASC');
-    }
-    elsif ( ($args{'FIELD'} eq 'Base') or 
-           ($args{'FIELD'} eq 'LocalBase') ) {
-       $self->OrderBy (ALIAS => 'main',
-                       FIELD => 'Target',
-                       ORDER => 'ASC');
-    }
-    
-
-    $self->SUPER::Limit(%args);
+    return ( $self->SUPER::_Init(@_) );
 }
-# }}}
 
-# {{{ sub NewItem 
-sub NewItem  {
+
+=item NewItem
+
+Returns an empty new RT::Link item
+
+=cut
+
+sub NewItem {
     my $self = shift;
     return(RT::Link->new($self->CurrentUser));
 }
-# }}}
-  1;
 
+        eval "require RT::Links_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Links_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Links_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Links_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Links_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Links_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::Links_Overlay, RT::Links_Vendor, RT::Links_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/Links_Overlay.pm b/rt/lib/RT/Links_Overlay.pm
new file mode 100644 (file)
index 0000000..d788a42
--- /dev/null
@@ -0,0 +1,125 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Links - A collection of Link objects
+
+=head1 SYNOPSIS
+
+  use RT::Links;
+  my $links = new RT::Links($CurrentUser);
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::Links);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+use RT::URI;
+
+# {{{ sub Limit 
+sub Limit  {
+    my $self = shift;
+    my %args = ( ENTRYAGGREGATOR => 'AND',
+                OPERATOR => '=',
+                @_);
+    
+    #if someone's trying to search for tickets, try to resolve the uris for searching.
+    
+    if (  ( $args{'OPERATOR'} eq '=') and
+         ( $args{'FIELD'}  eq 'Base') or ($args{'FIELD'} eq 'Target')
+       ) {
+         my $dummy = RT::URI->new($self->CurrentUser);
+          $dummy->FromURI($args{'VALUE'});
+          # $uri = $dummy->URI;
+    }
+
+
+    # If we're limiting by target, order by base
+    # (Order by the thing that's changing)
+
+    if ( ($args{'FIELD'} eq 'Target') or 
+        ($args{'FIELD'} eq 'LocalTarget') ) {
+       $self->OrderBy (ALIAS => 'main',
+                       FIELD => 'Base',
+                       ORDER => 'ASC');
+    }
+    elsif ( ($args{'FIELD'} eq 'Base') or 
+           ($args{'FIELD'} eq 'LocalBase') ) {
+       $self->OrderBy (ALIAS => 'main',
+                       FIELD => 'Target',
+                       ORDER => 'ASC');
+    }
+    
+
+    $self->SUPER::Limit(%args);
+}
+# }}}
+
+# {{{ LimitRefersTo 
+
+=head2 LimitRefersTo URI
+
+find all things that refer to URI
+
+=cut
+
+sub LimitRefersTo {
+    my $self = shift;
+    my $URI = shift;
+
+    $self->Limit(FIELD => 'Type', VALUE => 'RefersTo');
+    $self->Limit(FIELD => 'Target', VALUE => $URI);
+}
+
+# }}}
+# {{{ LimitReferredToBy
+
+=head2 LimitReferredToBy URI
+
+find all things that URI refers to
+
+=cut
+
+sub LimitReferredToBy {
+    my $self = shift;
+    my $URI = shift;
+
+    $self->Limit(FIELD => 'Type', VALUE => 'RefersTo');
+    $self->Limit(FIELD => 'Base', VALUE => $URI);
+}
+
+# }}}
+1;
+
diff --git a/rt/lib/RT/ObjectKeyword.pm b/rt/lib/RT/ObjectKeyword.pm
deleted file mode 100644 (file)
index 287d41f..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Attic/ObjectKeyword.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# Released under the terms of the GNU Public License
-
-=head1 NAME
-
-  RT::ObjectKeyword -- a keyword tied to an object in the database
-
-=head1 SYNOPSIS
-
-  use RT::ObjectKeyword;
-
-
-=head1 DESCRIPTION
-
-This module should never be called directly by client code. it's an internal module which
-should only be accessed through exported APIs in Ticket, Queue and other similar objects.
-
-
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::ObjectKeyword);
-
-=end testing
-
-=head1 METHODS
-
-=cut
-
-package RT::ObjectKeyword;
-
-use strict;
-use vars qw(@ISA);
-use RT::Record;
-
-@ISA = qw(RT::Record);
-
-sub _Init {
-    my $self = shift;
-    $self->{'table'} = "ObjectKeywords";
-    $self->SUPER::_Init(@_);
-}
-
-sub _Accessible {
-    my $self = shift;
-    
-    my %cols = (
-               Keyword       => 'read/write', #link to the B<RT::Keyword>
-               KeywordSelect => 'read/write', #link to the B<RT::KeywordSelect>
-               ObjectType    => 'read/write', #currently only C<Ticket>
-               ObjectId      => 'read/write', #link to the object specified in I<ObjectType>
-              );
-    return ($self->SUPER::_Accessible( @_, %cols));
-}
-
-
-
-# TODO - post 2.0. add in _Set and _Value, so we can ACL them.  protected at another API level
-
-
-=head1 NAME
-
- RT::ObjectKeyword - Manipulate an RT::ObjectKeyword record
-
-=head1 SYNOPSIS
-
-  use RT::ObjectKeyword;
-
-  my $keyword = RT::ObjectKeyword->new($CurrentUser);
-  $keyword->Create;
-
-=head1 DESCRIPTION
-
-An B<RT::ObjectKeyword> object associates an B<RT::Keyword> with another
-object (currently only B<RT::Ticket>.
-
-This module should B<NEVER> be called directly by client code. its API is entirely through RT ticket or other objects which can have keywords assigned.
-
-
-=head1 METHODS
-
-=over 4
-
-=item new CURRENT_USER
-
-Takes a single argument, an RT::CurrentUser object.  Instantiates a new
-(uncreated) RT::ObjectKeyword object.
-
-=cut
-
-# {{{ sub Create
-
-=item Create KEY => VALUE, ...
-
-Takes a list of key/value pairs and creates a the object.  Returns the id of
-the newly created record, or false if there was an error.
-
-Keys are:
-
-Keyword - link to the B<RT::Keyword>
-ObjectType - currently only C<Ticket>
-ObjectId - link to the object specified in I<ObjectType>
-
-=cut
-
-
-sub Create {
-    my $self = shift;
-    my %args = (Keyword => undef,
-               KeywordSelect => undef,
-               ObjectType => undef,
-               ObjectId => undef,
-               @_);
-    
-    #TODO post 2.0 ACL check
-    
-    return ($self->SUPER::Create( Keyword => $args{'Keyword'}, 
-                                 KeywordSelect => $args{'KeywordSelect'},
-                                 ObjectType => $args{'ObjectType'}, 
-                                 ObjectId => $args{'ObjectId'}))
-}
-# }}}
-
-# {{{ sub KeywordObj
-
-=item KeywordObj 
-
-Returns an B<RT::Keyword> object of the Keyword associated with this ObjectKeyword.
-
-=cut
-
-sub KeywordObj {
-    my $self = shift;
-    my $keyword = new RT::Keyword($self->CurrentUser);
-    $keyword->Load($self->Keyword);
-    return ($keyword);
-}
-# }}}
-
-# {{{ sub KeywordSelectObj
-
-=item KeywordSelectObj 
-
-Returns an B<RT::KeywordSelect> object of the KeywordSelect associated with this ObjectKeyword.
-
-=cut
-
-sub KeywordSelectObj {
-    my $self = shift;
-    my $keyword_sel = new RT::KeywordSelect($self->CurrentUser);
-    $keyword_sel->Load($self->KeywordSelect);
-    return ($keyword_sel);
-}
-# }}}
-
-# {{{ sub KeywordRelativePath
-
-=item KeywordRelativePath
-
-Returns a string of the Keyword's path relative to this ObjectKeyword's KeywordSelect
-
-
-
-=cut
-
-sub KeywordRelativePath {
-    my $self = shift;
-    return($self->KeywordObj->RelativePath(
-              $self->KeywordSelectObj->KeywordObj->Path));
-    
-}
-# }}}
-
-=back
-
-=head1 AUTHOR
-
-Ivan Kohler <ivan-rt@420.am>
-
-=head1 BUGS
-
-Yes.
-
-=head1 SEE ALSO
-
-L<RT::ObjectKeywords>, L<RT::Keyword>, L<RT::Keywords>, L<RT::Ticket>,
-L<RT::Record>
-
-=cut
-
-1;
-
diff --git a/rt/lib/RT/ObjectKeywords.pm b/rt/lib/RT/ObjectKeywords.pm
deleted file mode 100644 (file)
index 5df996e..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Attic/ObjectKeywords.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-
-package RT::ObjectKeywords;
-
-use strict;
-use vars qw( @ISA );
-
-=head1 NAME
-
-       RT::ObjectKeywords - note warning
-
-=head1 WARNING
-
-This module should B<NEVER> be called directly by client code. its API is entirely through RT ticket or other objects which can have keywords assigned.
-
-=head1 SYNOPSIS
-
-=head1 DESCRIPTION
-
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::ObjectKeywords);
-
-=end testing
-
-=cut
-
-use RT::EasySearch;
-use RT::ObjectKeyword;
-
-@ISA = qw( RT::EasySearch );
-
-# {{{ sub _Init
-sub _Init {
-    my $self = shift;
-    $self->{'table'} = 'ObjectKeywords';
-    $self->{'primary_key'} = 'id';
-    return ($self->SUPER::_Init(@_));
-}
-# }}}
-
-# {{{ sub NewItem
-sub NewItem {
-    my $self = shift;
-    return (new RT::ObjectKeyword($self->CurrentUser));
-}
-# }}}
-
-# {{{ sub LimitToKeywordSelect
-
-=head2 LimitToKeywordSelect
-
-  Takes a B<RT::KeywordSelect> id or Nameas its single argument. limits the returned set of ObjectKeywords
-to ObjectKeywords which apply to that ticket
-
-=cut
-
-
-sub LimitToKeywordSelect {
-    my $self = shift;
-    my $keywordselect = shift;
-    
-    if ($keywordselect =~ /^\d+$/) {
-
-       $self->Limit(FIELD => 'KeywordSelect',
-                    OPERATOR => '=',
-                    ENTRYAGGREGATOR => 'OR',
-                    VALUE => "$keywordselect");
-    }
-
-    #We're limiting by name. time to be klever
-    else {
-       my $ks = $self->NewAlias('KeywordSelects');
-       $self->Join(ALIAS1 => $ks, FIELD1 => 'id',
-                   ALIAS2 => 'main', FIELD2 => 'KeywordSelect');
-       
-       $self->Limit( ALIAS => "$ks",
-                      FIELD => 'Name',
-                      VALUE => "$keywordselect",
-                      OPERATOR => "=",
-                      ENTRYAGGREGATOR => "OR");
-
-       $self->Limit ( ALIAS => "$ks",
-                      FIELD => 'ObjectType',
-                      VALUE => 'Ticket',
-                      OPERATOR => '=',
-                    );
-
-       $self->Limit ( ALIAS => "$ks",
-                      FIELD => 'ObjectField',
-                      VALUE => 'Queue',
-                      OPERATOR => '=',
-                    );
-
-
-       # TODO +++ we need to be able to limit the returned
-       # keywordselects to ones that apply only to this queue
-       #       $self->Limit( ALIAS => "$ks",
-       #                      FIELD => 'ObjectValue',
-       #                      VALUE => $self->QueueObj->Id,
-       #                      OPERATOR => "=",
-       #                      ENTRYAGGREGATOR => "OR");        
-
-    }
-
-
-
-}
-
-# }}}
-
-# {{{ LimitToTicket
-
-=head2 LimitToTicket TICKET_ID
-
-  Takes an B<RT::Ticket> id as its single argument. limits the returned set of ObjectKeywords
-to ObjectKeywords which apply to that ticket
-
-=cut
-
-sub LimitToTicket {
-    my $self = shift;
-    my $ticket = shift;
-    $self->Limit(FIELD => 'ObjectId',
-                OPERATOR => '=',
-                ENTRYAGGREGATOR => 'OR',
-                VALUE => "$ticket");
-
-    $self->Limit(FIELD => 'ObjectType',
-                OPERATOR => '=',
-                ENTRYAGGREGATOR => 'OR',
-                VALUE => "Ticket");
-    
-}
-
-# }}}
-
-# {{{ sub _DoSearch
-#wrap around _DoSearch  so that we can build the hash of returned
-#values 
-
-sub _DoSearch {
-    my $self = shift;
-   # $RT::Logger->debug("Now in ".$self."->_DoSearch");
-    my $return = $self->SUPER::_DoSearch(@_);
-  #  $RT::Logger->debug("In $self ->_DoSearch. return from SUPER::_DoSearch was $return\n");
-    $self->_BuildHash();
-    return ($return);
-}
-# }}}
-
-# {{{ sub _BuildHash
-#Build a hash of this ACL's entries.
-sub _BuildHash {
-    my $self = shift;
-
-    while (my $entry = $self->Next) {
-
-       my $hashkey = $entry->Keyword;
-        $self->{'as_hash'}->{"$hashkey"} =1;
-    }
-
-}
-# }}}
-
-# {{{ HasEntry
-
-=head2 HasEntry KEYWORD_ID
-  
-  Takes a keyword id and returns true if this ObjectKeywords object has an entry for that
-keyword.  Returns undef otherwise.
-
-=cut
-
-sub HasEntry {
-
-    my $self = shift;
-    my $keyword = shift;
-
-
-    #if we haven't done the search yet, do it now.
-    $self->_DoSearch();
-    
-    #    $RT::Logger->debug("Now in ".$self."->HasEntry\n");
-    
-    
-    if ($self->{'as_hash'}->{ $keyword } == 1) {
-       return(1);
-    }
-    else {
-       return(undef);
-    }
-}
-
-# }}}
-
-# {{{ sub RelativePaths
-
-=head2 RelativePaths
-
-# Return a (reference to a) list of KeywordRelativePaths
-
-=cut
-
-sub RelativePaths  {
-    my $self = shift;
-
-    my @list;
-
-    # Here $key is a RT::ObjectKeyword
-    while (my $key=$self->Next()) {
-       push(@list, $key->KeywordRelativePath);
-    }
-    return(\@list);
-}
-# }}}
-
-# {{{ sub RelativePathsAsString
-
-=head2 RelativePathsAsString
-
-# Returns the RT::ObjectKeywords->RelativePaths as a comma seperated string
-
-=cut
-
-sub RelativePathsAsString {
-    my $self = shift;
-    return(join(", ",@{$self->KeywordRelativePaths}));
-}
-# }}}
-
-1;
-
diff --git a/rt/lib/RT/Principal.pm b/rt/lib/RT/Principal.pm
new file mode 100644 (file)
index 0000000..cffee4c
--- /dev/null
@@ -0,0 +1,212 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
+
+=head1 NAME
+
+RT::Principal
+
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+=cut
+
+package RT::Principal;
+use RT::Record; 
+
+
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
+
+sub _Init {
+  my $self = shift; 
+
+  $self->Table('Principals');
+  $self->SUPER::_Init(@_);
+}
+
+
+
+
+
+=item Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+  varchar(16) 'PrincipalType'.
+  int(11) 'ObjectId'.
+  smallint(6) 'Disabled'.
+
+=cut
+
+
+
+
+sub Create {
+    my $self = shift;
+    my %args = ( 
+                PrincipalType => '',
+                ObjectId => '',
+                Disabled => '0',
+
+                 @_);
+    $self->SUPER::Create(
+                         PrincipalType => $args{'PrincipalType'},
+                         ObjectId => $args{'ObjectId'},
+                         Disabled => $args{'Disabled'},
+);
+
+}
+
+
+
+=item id
+
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
+
+
+=cut
+
+
+=item PrincipalType
+
+Returns the current value of PrincipalType. 
+(In the database, PrincipalType is stored as varchar(16).)
+
+
+
+=item SetPrincipalType VALUE
+
+
+Set PrincipalType to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, PrincipalType will be stored as a varchar(16).)
+
+
+=cut
+
+
+=item ObjectId
+
+Returns the current value of ObjectId. 
+(In the database, ObjectId is stored as int(11).)
+
+
+
+=item SetObjectId VALUE
+
+
+Set ObjectId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ObjectId will be stored as a int(11).)
+
+
+=cut
+
+
+=item Disabled
+
+Returns the current value of Disabled. 
+(In the database, Disabled is stored as smallint(6).)
+
+
+
+=item SetDisabled VALUE
+
+
+Set Disabled to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Disabled will be stored as a smallint(6).)
+
+
+=cut
+
+
+
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        PrincipalType => 
+               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+        ObjectId => 
+               {read => 1, write => 1, type => 'int(11)', default => ''},
+        Disabled => 
+               {read => 1, write => 1, type => 'smallint(6)', default => '0'},
+
+ }
+};
+
+
+        eval "require RT::Principal_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Principal_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Principal_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Principal_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Principal_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Principal_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::Principal_Overlay, RT::Principal_Vendor, RT::Principal_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/Principal_Overlay.pm b/rt/lib/RT/Principal_Overlay.pm
new file mode 100644 (file)
index 0000000..d2782b7
--- /dev/null
@@ -0,0 +1,557 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+use strict;
+
+no warnings qw(redefine);
+use vars qw(%_ACL_KEY_CACHE);
+
+use RT::Group;
+use RT::User;
+
+# {{{ IsGroup
+
+=head2 IsGroup
+
+Returns true if this principal is a group. 
+Returns undef, otherwise
+
+=cut
+
+sub IsGroup {
+    my $self = shift;
+    if ($self->PrincipalType eq 'Group') {
+        return(1);
+    }
+    else {
+        return undef;
+    }
+}
+
+# }}}
+
+# {{{ IsUser
+
+=head2 IsUser 
+
+Returns true if this principal is a User. 
+Returns undef, otherwise
+
+=cut
+
+sub IsUser {
+    my $self = shift;
+    if ($self->PrincipalType eq 'User') {
+        return(1);
+    }
+    else {
+        return undef;
+    }
+}
+
+# }}}
+
+# {{{ Object
+
+=head2 Object
+
+Returns the user or group associated with this principal
+
+=cut
+
+sub Object {
+    my $self = shift;
+
+    unless ($self->{'object'}) {
+    if ($self->IsUser) {
+       $self->{'object'} = RT::User->new($self->CurrentUser);
+    }
+    elsif ($self->IsGroup) {
+        $self->{'object'}  = RT::Group->new($self->CurrentUser);
+    }
+    else { 
+        $RT::Logger->crit("Found a principal (".$self->Id.") that was neither a user nor a group");
+        return(undef);
+    }
+    $self->{'object'}->Load($self->ObjectId());
+    }
+    return ($self->{'object'});
+
+
+}
+# }}} 
+
+# {{{ ACL Related routines
+
+# {{{ GrantRight 
+
+=head2 GrantRight  { Right => RIGHTNAME, Object => undef }
+
+A helper function which calls RT::ACE->Create
+
+=cut
+
+sub GrantRight {
+    my $self = shift;
+    my %args = ( Right => undef,
+                Object => undef,
+                @_);
+
+
+    #if we haven't specified any sort of right, we're talking about a global right
+    if (!defined $args{'Object'} && !defined $args{'ObjectId'} && !defined $args{'ObjectType'}) {
+        $args{'Object'} = $RT::System;
+    }
+
+    unless ($args{'Right'}) {
+        return(0, $self->loc("Invalid Right"));
+    }
+
+
+    #ACL check handled in ACE.pm
+    my $ace = RT::ACE->new( $self->CurrentUser );
+
+
+    my $type = $self->_GetPrincipalTypeForACL();
+
+    # If it's a user, we really want to grant the right to their 
+    # user equivalence group
+        return ( $ace->Create(RightName => $args{'Right'},
+                          Object => $args{'Object'},
+                          PrincipalType =>  $type,
+                          PrincipalId => $self->Id
+                          ) );
+}
+# }}}
+
+# {{{ RevokeRight
+
+=head2 RevokeRight { Right => "RightName", Object => "object" }
+
+Delete a right that a user has 
+
+=cut
+
+sub RevokeRight {
+
+    my $self = shift;
+    my %args = (
+        Right      => undef,
+        Object => undef,
+        @_
+    );
+
+    #if we haven't specified any sort of right, we're talking about a global right
+    if (!defined $args{'Object'} && !defined $args{'ObjectId'} && !defined $args{'ObjectType'}) {
+        $args{'Object'} = $RT::System;
+    }
+    #ACL check handled in ACE.pm
+    my $type = $self->_GetPrincipalTypeForACL();
+
+    my $ace = RT::ACE->new( $self->CurrentUser );
+    $ace->LoadByValues(
+        RightName     => $args{'Right'},
+        Object    => $args{'Object'},
+        PrincipalType => $type,
+        PrincipalId   => $self->Id
+    );
+
+    unless ( $ace->Id ) {
+        return ( 0, $self->loc("ACE not found") );
+    }
+    return ( $ace->Delete );
+}
+
+# }}}
+
+
+
+# {{{ sub HasRight
+
+=head2 sub HasRight (Right => 'right' Object => undef)
+
+
+Checks to see whether this principal has the right "Right" for the Object
+specified. If the Object parameter is omitted, checks to see whether the 
+user has the right globally.
+
+This still hard codes to check to see if a user has queue-level rights
+if we ask about a specific ticket.
+
+
+This takes the params:
+
+    Right => name of a right
+
+    And either:
+
+    Object => an RT style object (->id will get its id)
+
+
+
+
+Returns 1 if a matching ACE was found.
+
+Returns undef if no ACE was found.
+
+=cut
+
+sub HasRight {
+
+    my $self = shift;
+    my %args = ( Right      => undef,
+                 Object     => undef,
+                 EquivObjects    => undef,
+                 @_ );
+
+    if ( $self->Disabled ) {
+        $RT::Logger->err( "Disabled User:  " . $self->id . " failed access check for " . $args{'Right'} );
+        return (undef);
+    }
+
+    if ( !defined $args{'Right'} ) {
+        require Carp;
+        $RT::Logger->debug( Carp::cluck("HasRight called without a right") );
+        return (undef);
+    }
+
+    if ( defined( $args{'Object'} )) {
+        return (undef) unless (UNIVERSAL::can( $args{'Object'}, 'id' ) );
+        push(@{$args{'EquivObjects'}}, $args{Object});
+    }
+    elsif ( $args{'ObjectId'} && $args{'ObjectType'} ) {
+        $RT::Logger->crit(Carp::cluck("API not supprted"));
+    }
+    else {
+        $RT::Logger->crit("$self HasRight called with no valid object");
+        return (undef);
+    }
+
+    # If this object is a ticket, we care about ticket roles and queue roles
+    if ( (ref($args{'Object'}) eq 'RT::Ticket') && $args{'Object'}->Id) {
+        # this is a little bit hacky, but basically, now that we've done the ticket roles magic, we load the queue object
+        # and ask all the rest of our questions about the queue.
+        push (@{$args{'EquivObjects'}}, $args{'Object'}->QueueObj);
+
+    }
+
+
+    # {{{ If we've cached a win or loss for this lookup say so
+
+    # {{{ Construct a hashkey to cache decisions in
+    my $hashkey = do {
+       no warnings 'uninitialized';
+        
+       # We don't worry about the hash ordering, as this is only
+       # temporarily used; also if the key changes it would be
+       # invalidated anyway.
+        join (
+            ";:;", $self->Id, map {
+                $_,                              # the key of each arguments
+                ($_ eq 'EquivObjects')           # for object arrayref...
+                   ? map(_ReferenceId($_), @{$args{$_}}) # calculate each
+                    : _ReferenceId( $args{$_} ) # otherwise just the value
+            } keys %args
+        );
+    };
+    # }}}
+
+    #Anything older than 60 seconds needs to be rechecked
+    my $cache_timeout = ( time - 60 );
+
+    # {{{ if we've cached a positive result for this query, return 1
+    if (    ( defined $self->_ACLCache->{"$hashkey"} )
+         && ( $self->_ACLCache->{"$hashkey"}{'val'} == 1 )
+         && ( defined $self->_ACLCache->{"$hashkey"}{'set'} )
+         && ( $self->_ACLCache->{"$hashkey"}{'set'} > $cache_timeout ) ) {
+
+        #$RT::Logger->debug("Cached ACL win for ".  $args{'Right'}.$args{'Scope'}.  $args{'AppliesTo'}."\n");      
+        return ( 1);
+    }
+    # }}}
+
+    #  {{{ if we've cached a negative result for this query return undef
+    elsif (    ( defined $self->_ACLCache->{"$hashkey"} )
+            && ( $self->_ACLCache->{"$hashkey"}{'val'} == -1 )
+            && ( defined $self->_ACLCache->{"$hashkey"}{'set'} )
+            && ( $self->_ACLCache->{"$hashkey"}{'set'} > $cache_timeout ) ) {
+
+        #$RT::Logger->debug("Cached ACL loss decision for ".  $args{'Right'}.$args{'Scope'}.  $args{'AppliesTo'}."\n");            
+
+        return (undef);
+    }
+    # }}}
+
+    # }}}
+
+
+
+    #  {{{ Out of date docs
+    
+    #   We want to grant the right if:
+
+
+    #    # The user has the right as a member of a system-internal or 
+    #    # user-defined group
+    #
+    #    Find all records from the ACL where they're granted to a group 
+    #    of type "UserDefined" or "System"
+    #    for the object "System or the object "Queue N" and the group we're looking
+    #    at has the recursive member $self->Id
+    #
+    #    # The user has the right based on a role
+    #
+    #    Find all the records from ACL where they're granted to the role "foo"
+    #    for the object "System" or the object "Queue N" and the group we're looking
+    #   at is of domain  ("RT::Queue-Role" and applies to the right queue)
+    #                             or ("RT::Ticket-Role" and applies to the right ticket)
+    #    and the type is the same as the type of the ACL and the group has
+    #    the recursive member $self->Id
+    #
+
+    # }}}
+
+    my ( $or_look_at_object_rights, $or_check_roles );
+    my $right = $args{'Right'};
+
+    # {{{ Construct Right Match
+
+    # If an object is defined, we want to look at rights for that object
+   
+    my @look_at_objects;
+    push (@look_at_objects, "ACL.ObjectType = 'RT::System'")
+        unless $self->can('_IsOverrideGlobalACL') and $self->_IsOverrideGlobalACL($args{Object});
+
+
+
+    foreach my $obj (@{$args{'EquivObjects'}}) {
+            next unless (UNIVERSAL::can($obj, 'id'));
+            my $type = ref($obj);
+            my $id = $obj->id;
+            push @look_at_objects, "(ACL.ObjectType = '$type' AND ACL.ObjectId = '$id')"; 
+            }
+
+     
+    # }}}
+
+    # {{{ Build that honkin-big SQL query
+
+    
+
+    my $query_base = "SELECT ACL.id from ACL, Groups, Principals, CachedGroupMembers WHERE  ".
+    # Only find superuser or rights with the name $right
+   "(ACL.RightName = 'SuperUser' OR  ACL.RightName = '$right') ".
+   # Never find disabled groups.
+   "AND Principals.Disabled = 0 " .
+   "AND CachedGroupMembers.Disabled = 0  ".
+    "AND Principals.id = Groups.id " .  # We always grant rights to Groups
+
+    # See if the principal is a member of the group recursively or _is the rightholder_
+    # never find recursively disabled group members
+    # also, check to see if the right is being granted _directly_ to this principal,
+    #  as is the case when we want to look up group rights
+    "AND  Principals.id = CachedGroupMembers.GroupId AND CachedGroupMembers.MemberId = '" . $self->Id . "' ".
+
+    # Make sure the rights apply to the entire system or to the object in question
+    "AND ( ".join(' OR ', @look_at_objects).") ";
+
+
+
+    # The groups query does the query based on group membership and individual user rights
+
+       my $groups_query = $query_base . 
+
+    # limit the result set to groups of types ACLEquivalence (user)  UserDefined, SystemInternal and Personal
+    "AND ( (  ACL.PrincipalId = Principals.id AND ACL.PrincipalType = 'Group' AND ".
+        "(Groups.Domain = 'SystemInternal' OR Groups.Domain = 'UserDefined' OR Groups.Domain = 'ACLEquivalence' OR Groups.Domain = 'Personal'))".
+
+        " ) LIMIT 1";
+        
+    my @roles;
+    foreach my $object (@{$args{'EquivObjects'}}) { 
+          push (@roles, $self->_RolesForObject(ref($object), $object->id));
+    }
+
+    # The roles query does the query based on roles
+    my $roles_query;
+    if (@roles) {
+        $roles_query = $query_base . "AND ".
+            " ( (".join (' OR ', @roles)." ) ".  
+        " AND Groups.Type = ACL.PrincipalType AND Groups.Id = Principals.id AND Principals.PrincipalType = 'Group') LIMIT 1";
+
+   }
+
+
+
+    # }}}
+
+    # {{{ Actually check the ACL by performing an SQL query
+    #   $RT::Logger->debug("Now Trying $groups_query");        
+    my $hitcount = $self->_Handle->FetchResult($groups_query);
+
+    # }}}
+    
+    # {{{ if there's a match, the right is granted 
+    if ($hitcount) {
+
+        # Cache a positive hit.
+        $self->_ACLCache->{"$hashkey"}{'set'} = time;
+        $self->_ACLCache->{"$hashkey"}{'val'} = 1;
+        return (1);
+    }
+    # }}}
+    # {{{ If there's no match on groups, try it on roles
+    else {   
+
+       $hitcount = $self->_Handle->FetchResult($roles_query);
+
+        if ($hitcount) {
+
+            # Cache a positive hit.
+            $self->_ACLCache->{"$hashkey"}{'set'} = time;
+            $self->_ACLCache->{"$hashkey"}{'val'} = 1;
+            return (1);
+           }
+
+        else {
+            # cache a negative hit
+            $self->_ACLCache->{"$hashkey"}{'set'} = time;
+            $self->_ACLCache->{"$hashkey"}{'val'} = -1;
+
+            return (undef);
+           }
+    }
+    # }}}
+}
+
+# }}}
+
+# {{{ _RolesForObject
+
+
+
+=head2 _RolesForObject( $object_type, $object_id)
+
+Returns an SQL clause finding role groups for Objects
+
+=cut
+
+
+sub _RolesForObject {
+    my $self = shift;
+    my $type = shift;
+    my $id = shift;
+    my $clause = "(Groups.Domain = '".$type."-Role' AND Groups.Instance = '" . $id. "') ";
+
+    return($clause);
+}
+
+# }}}
+
+# }}}
+
+# {{{ ACL caching
+
+# {{{ _ACLCache
+
+=head2 _ACLCache
+
+# Function: _ACLCache
+# Type    : private instance
+# Args    : none
+# Lvalue  : hash: ACLCache
+# Desc    : Returns a reference to the Key cache hash
+
+=cut
+
+sub _ACLCache {
+    return(\%_ACL_KEY_CACHE);
+}
+
+# }}}
+
+# {{{ _InvalidateACLCache
+
+=head2 _InvalidateACLCache
+
+Cleans out and reinitializes the user rights key cache
+
+=cut
+
+sub _InvalidateACLCache {
+    %_ACL_KEY_CACHE = ();
+}
+
+# }}}
+
+# }}}
+
+
+# {{{ _GetPrincipalTypeForACL
+
+=head2 _GetPrincipalTypeForACL
+
+Gets the principal type. if it's a user, it's a user. if it's a role group and it has a Type, 
+return that. if it has no type, return group.
+
+=cut
+
+sub _GetPrincipalTypeForACL {
+    my $self = shift;
+    my $type;    
+    if ($self->PrincipalType eq 'Group' && $self->Object->Domain =~ /Role$/) {
+        $type = $self->Object->Type;
+    }
+    else {
+        $type = $self->PrincipalType;
+    }
+
+    return($type);
+}
+
+# }}}
+
+# {{{ _ReferenceId
+
+=head2 _ReferenceId
+
+Returns a list uniquely representing an object or normal scalar.
+
+For scalars, its string value is returned; for objects that has an
+id() method, its class name and Id are returned as a string seperated by a "-".
+
+=cut
+
+sub _ReferenceId {
+    my $scalar = shift;
+
+    # just return the value for non-objects
+    return $scalar unless UNIVERSAL::can($scalar, 'id');
+
+    # an object -- return the class and id
+    return(ref($scalar)."-". $scalar->id);
+}
+
+# }}}
+
+1;
diff --git a/rt/lib/RT/Principals.pm b/rt/lib/RT/Principals.pm
new file mode 100644 (file)
index 0000000..c45a4c7
--- /dev/null
@@ -0,0 +1,115 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
+
+=head1 NAME
+
+  RT::Principals -- Class Description
+=head1 SYNOPSIS
+
+  use RT::Principals
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=cut
+
+package RT::Principals;
+
+use RT::SearchBuilder;
+use RT::Principal;
+
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
+
+
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'Principals';
+    $self->{'primary_key'} = 'id';
+
+
+    return ( $self->SUPER::_Init(@_) );
+}
+
+
+=item NewItem
+
+Returns an empty new RT::Principal item
+
+=cut
+
+sub NewItem {
+    my $self = shift;
+    return(RT::Principal->new($self->CurrentUser));
+}
+
+        eval "require RT::Principals_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Principals_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Principals_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Principals_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Principals_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Principals_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::Principals_Overlay, RT::Principals_Vendor, RT::Principals_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/Principals_Overlay.pm b/rt/lib/RT/Principals_Overlay.pm
new file mode 100644 (file)
index 0000000..0d8c54c
--- /dev/null
@@ -0,0 +1,52 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Principals - a collection of RT::Principal objects
+
+=head1 SYNOPSIS
+
+  use RT::Principals;
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::Principals);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+
+
+
+1;
index 1656903..b362c9f 100755 (executable)
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Queue.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
 
 =head1 NAME
 
-  RT::Queue - an RT Queue object
+RT::Queue
 
-=head1 SYNOPSIS
 
-  use RT::Queue;
+=head1 SYNOPSIS
 
 =head1 DESCRIPTION
 
-
 =head1 METHODS
 
-=begin testing 
-use RT::TestHarness;
-
-use RT::Queue;
-
-=end testing
-
 =cut
 
-
-
 package RT::Queue;
-use RT::Record;
-
-@ISA= qw(RT::Record);
-
-use vars (@STATUS);
-
-@STATUS = qw(new open stalled resolved dead); 
-
-=head2 StatusArray
-
-Returns an array of all statuses for this queue
-
-=cut
-
-sub StatusArray {
-    my $self = shift;
-    return (@STATUS);
-}
-
-
-=head2 IsValidStatus VALUE
-
-Returns true if VALUE is a valid status.  Otherwise, returns 0
-
-=for testing
-my $q = new RT::Queue($RT::SystemUser);
-ok($q->IsValidStatus('new')== 1, 'New is a valid status');
-ok($q->IsValidStatus('f00')== 0, 'f00 is not a valid status');
-
-=cut
-
-sub IsValidStatus {
-       my $self = shift;
-       my $value = shift;
-
-       my $retval = grep (/^$value$/, $self->StatusArray);
-       return ($retval);       
-
-}
-       
-
-
-
-# {{{  sub _Init 
-sub _Init  {
-    my $self = shift;
-    $self->{'table'} = "Queues";
-    return ($self->SUPER::_Init(@_));
-}
-# }}}
-
-# {{{ sub _Accessible 
-
-sub _Accessible  {
-    my $self = shift;
-    my %Cols = ( Name => 'read/write',
-                CorrespondAddress => 'read/write',
-                Description => 'read/write',
-                CommentAddress =>  'read/write',
-                InitialPriority =>  'read/write',
-                FinalPriority =>  'read/write',
-                DefaultDueIn =>  'read/write',
-                Creator => 'read/auto',
-                Created => 'read/auto',
-                LastUpdatedBy => 'read/auto',
-                LastUpdated => 'read/auto',
-                Disabled => 'read/write',
-                
-              );
-    return($self->SUPER::_Accessible(@_, %Cols));
-}
-
-# }}}
+use RT::Record; 
 
-# {{{ sub Create
 
-=head2 Create
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
 
-Create takes the name of the new queue 
-If you pass the ACL check, it creates the queue and returns its queue id.
+sub _Init {
+  my $self = shift; 
 
-=cut
-
-sub Create  {
-    my $self = shift;
-    my %args = ( Name => undef,
-                CorrespondAddress => '',
-                Description => '',
-                CommentAddress => '',
-                InitialPriority => "0",
-                FinalPriority =>  "0",
-                DefaultDueIn =>  "0",
-                @_); 
-    
-    unless ($self->CurrentUser->HasSystemRight('AdminQueue')) {    #Check them ACLs
-       return (0, "No permission to create queues") 
-    }
-
-    unless ($self->ValidateName($args{'Name'})) {
-       return(0, 'Queue already exists');
-    }
-    #TODO better input validation
-    
-    my $id = $self->SUPER::Create(%args);
-    unless ($id) {
-       return (0, 'Queue could not be created');
-    }
-
-    return ($id, "Queue $id created");
+  $self->Table('Queues');
+  $self->SUPER::_Init(@_);
 }
 
-# }}}
 
-# {{{ sub Delete 
 
-sub Delete {
-    my $self = shift;
-    return (0, 'Deleting this object would break referential integrity');
-}
 
-# }}}
 
-# {{{ sub SetDisabled
+=item Create PARAMHASH
 
-=head2 SetDisabled
+Create takes a hash of values and creates a row in the database:
 
-Takes a boolean.
-1 will cause this queue to no longer be avaialble for tickets.
-0 will re-enable this queue
+  varchar(200) 'Name'.
+  varchar(255) 'Description'.
+  varchar(120) 'CorrespondAddress'.
+  varchar(120) 'CommentAddress'.
+  int(11) 'InitialPriority'.
+  int(11) 'FinalPriority'.
+  int(11) 'DefaultDueIn'.
+  smallint(6) 'Disabled'.
 
 =cut
 
-# }}}
 
-# {{{ sub Load 
 
-=head2 Load
 
-Takes either a numerical id or a textual Name and loads the specified queue.
-  
-=cut
-
-sub Load  {
+sub Create {
     my $self = shift;
-    
-    my $identifier = shift;
-    if (!$identifier) {
-       return (undef);
-    }      
-    
-    if ($identifier !~ /\D/) {
-       $self->SUPER::LoadById($identifier);
-    }
-    else {
-       $self->LoadByCol("Name", $identifier);
-    }
-
-    return ($self->Id);
+    my %args = ( 
+                Name => '',
+                Description => '',
+                CorrespondAddress => '',
+                CommentAddress => '',
+                InitialPriority => '0',
+                FinalPriority => '0',
+                DefaultDueIn => '0',
+                Disabled => '0',
 
+                 @_);
+    $self->SUPER::Create(
+                         Name => $args{'Name'},
+                         Description => $args{'Description'},
+                         CorrespondAddress => $args{'CorrespondAddress'},
+                         CommentAddress => $args{'CommentAddress'},
+                         InitialPriority => $args{'InitialPriority'},
+                         FinalPriority => $args{'FinalPriority'},
+                         DefaultDueIn => $args{'DefaultDueIn'},
+                         Disabled => $args{'Disabled'},
+);
 
 }
-# }}}
 
-# {{{ sub ValidateName
 
-=head2 ValidateName NAME
 
-Takes a queue name. Returns true if it's an ok name for
-a new queue. Returns undef if there's already a queue by that name.
+=item id
 
-=cut
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
 
-sub ValidateName {
-    my $self = shift;
-    my $name = shift;
-   
-    my $tempqueue = new RT::Queue($RT::SystemUser);
-    $tempqueue->Load($name);
-
-    #If we couldn't load it :)
-    unless ($tempqueue->id()) {
-       return(1);
-    }
-
-    #If this queue exists, return undef
-    #Avoid the ACL check.
-    if ($tempqueue->Name()){
-        return(undef);
-    }
-
-    #If the queue doesn't exist, return 1
-    else {
-        return(1);
-    }
-
-}
-
-
-# }}}
-
-# {{{ sub Templates
-
-=head2 Templates
-
-Returns an RT::Templates object of all of this queue's templates.
 
 =cut
 
-sub Templates {
-    my $self = shift;
-    
 
-    my $templates = RT::Templates->new($self->CurrentUser);
+=item Name
 
-    if ($self->CurrentUserHasRight('ShowTemplate')) {
-       $templates->LimitToQueue($self->id);
-    }
-    
-    return ($templates); 
-}
-
-# }}}
+Returns the current value of Name. 
+(In the database, Name is stored as varchar(200).)
 
-# {{{ Dealing with watchers
 
-# {{{ sub Watchers
 
-=head2 Watchers
+=item SetName VALUE
 
-Watchers returns a Watchers object preloaded with this queue\'s watchers.
 
-=cut
+Set Name to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Name will be stored as a varchar(200).)
 
-sub Watchers {
-    my $self = shift;
-    
-    require RT::Watchers;
-    my $watchers =RT::Watchers->new($self->CurrentUser);
-    
-    if ($self->CurrentUserHasRight('SeeQueue')) {
-       $watchers->LimitToQueue($self->id);     
-    }  
-    
-    return($watchers);
-}
-
-# }}}
-
-# {{{ sub WatchersAsString
-=head2 WatchersAsString
-
-Returns a string of all queue watchers email addresses concatenated with ','s.
 
 =cut
 
-sub WatchersAsString {
-    my $self=shift;
-    return($self->Watchers->EmailsAsString());
-}
-
-# }}}
-
-# {{{ sub AdminCcAsString 
 
-=head2 AdminCcAsString
+=item Description
 
-Takes nothing. returns a string: All Ticket/Queue AdminCcs.
+Returns the current value of Description. 
+(In the database, Description is stored as varchar(255).)
 
-=cut
 
 
-sub AdminCcAsString {
-    my $self=shift;
-    
-    return($self->AdminCc->EmailsAsString());
-  }
+=item SetDescription VALUE
 
-# }}}
 
-# {{{ sub CcAsString
+Set Description to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Description will be stored as a varchar(255).)
 
-=head2 CcAsString
-
-B<Returns> String: All Queue Ccs as a comma delimited set of email addresses.
 
 =cut
 
-sub CcAsString {
-    my $self=shift;
-    
-    return ($self->Cc->EmailsAsString());
-}
-
-# }}}
-
-# {{{ sub Cc
-
-=head2 Cc
-
-Takes nothing.
-Returns a watchers object which contains this queue\'s Cc watchers
 
-=cut
+=item CorrespondAddress
 
-sub Cc {
-    my $self = shift;
-    my $cc = $self->Watchers();
-    if ($self->CurrentUserHasRight('SeeQueue')) {
-       $cc->LimitToCc();
-    }
-    return ($cc);
-}
+Returns the current value of CorrespondAddress. 
+(In the database, CorrespondAddress is stored as varchar(120).)
 
-# A helper function for Cc, so that we can call it from the ACL checks 
-# without going through acl checks.
 
-sub _Cc {
-    my $self = shift;
-    my $cc = $self->Watchers();
-    $cc->LimitToCc();
-    return($cc);
-    
-}
 
-# }}}
+=item SetCorrespondAddress VALUE
 
-# {{{ sub AdminCc
 
-=head2 AdminCc
+Set CorrespondAddress to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, CorrespondAddress will be stored as a varchar(120).)
 
-Takes nothing.
-Returns this queue's administrative Ccs as an RT::Watchers object
 
 =cut
 
-sub AdminCc {
-    my $self = shift;
-    my $admin_cc = $self->Watchers();
-    if ($self->CurrentUserHasRight('SeeQueue')) {
-       $admin_cc->LimitToAdminCc();
-    }
-    return($admin_cc);
-}
-
-#helper function for AdminCc so we can call it without ACLs
-sub _AdminCc {
-    my $self = shift;
-    my $admin_cc = $self->Watchers();
-    $admin_cc->LimitToAdminCc();
-    return($admin_cc);
-}
 
-# }}}
+=item CommentAddress
 
-# {{{ IsWatcher, IsCc, IsAdminCc
-
-# {{{ sub IsWatcher
-
-# a generic routine to be called by IsRequestor, IsCc and IsAdminCc
-
-=head2 IsWatcher
-
-Takes a param hash with the attributes Type and User. User is either a user object or string containing an email address. Returns true if that user or string
-is a queue watcher. Returns undef otherwise
-
-=cut
-
-sub IsWatcher {
-    my $self = shift;
-    
-    my %args = ( Type => 'Requestor',
-                Id => undef,
-                Email => undef,
-                @_
-              );
-    #ACL check - can't do it. we need this method for ACL checks
-    #    unless ($self->CurrentUserHasRight('SeeQueue')) {
-    #  return(undef);
-    #    }
-
-
-    my %cols = ('Type' => $args{'Type'},
-               'Scope' => 'Queue',
-               'Value' => $self->Id
-              );
-    if (defined ($args{'Id'})) {
-       if (ref($args{'Id'})){ #If it's a ref, assume it's an RT::User object;
-           #Dangerous but ok for now
-           $cols{'Owner'} = $args{'Id'}->Id;
-       }
-       elsif ($args{'Id'} =~ /^\d+$/) { # if it's an integer, it's an RT::User obj
-           $cols{'Owner'} = $args{'Id'};
-       }
-       else {
-           $cols{'Email'} = $args{'Id'};
-       }       
-    }  
-    
-    if (defined $args{'Email'}) {
-       $cols{'Email'} = $args{'Email'};
-    }
-
-    my ($description);
-    $description = join(":",%cols);
-    
-    #If we've cached a positive match...
-    if (defined $self->{'watchers_cache'}->{"$description"}) {
-       if ($self->{'watchers_cache'}->{"$description"} == 1) {
-           return(1);
-       }
-       #If we've cached a negative match...
-       else {
-           return(undef);
-       }
-    }
-
-    require RT::Watcher;
-    my $watcher = new RT::Watcher($self->CurrentUser);
-    $watcher->LoadByCols(%cols);
-    
-    
-    if ($watcher->id) {
-       $self->{'watchers_cache'}->{"$description"} = 1;
-       return(1);
-    }  
-    else {
-       $self->{'watchers_cache'}->{"$description"} = 0;
-       return(undef);
-    }
-    
-}
+Returns the current value of CommentAddress. 
+(In the database, CommentAddress is stored as varchar(120).)
 
-# }}}
 
-# {{{ sub IsCc
 
-=head2 IsCc
+=item SetCommentAddress VALUE
 
-Takes a string. Returns true if the string is a Cc watcher of the current queue
 
-=item Bugs
+Set CommentAddress to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, CommentAddress will be stored as a varchar(120).)
 
-Should also be able to handle an RT::User object
 
 =cut
 
 
-sub IsCc {
-  my $self = shift;
-  my $cc = shift;
-  
-  return ($self->IsWatcher( Type => 'Cc', Id => $cc ));
-  
-}
-
-# }}}
-
-# {{{ sub IsAdminCc
-
-=head2 IsAdminCc
-
-Takes a string. Returns true if the string is an AdminCc watcher of the current queue
+=item InitialPriority
 
-=item Bugs
+Returns the current value of InitialPriority. 
+(In the database, InitialPriority is stored as int(11).)
 
-Should also be able to handle an RT::User object
-
-=cut
-
-sub IsAdminCc {
-  my $self = shift;
-  my $admincc = shift;
-  
-  return ($self->IsWatcher( Type => 'AdminCc', Id => $admincc ));
-  
-}
 
-# }}}
 
-# }}}
+=item SetInitialPriority VALUE
 
-# {{{ sub AddWatcher
 
-=head2 AddWatcher
+Set InitialPriority to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, InitialPriority will be stored as a int(11).)
 
-Takes a paramhash of Email, Owner and Type. Type is one of 'Cc' or 'AdminCc',
-We need either an Email Address in Email or a userid in Owner
 
 =cut
 
-sub AddWatcher {
-    my $self = shift;
-    my %args = ( Email => undef,
-                Type => undef,
-                Owner => 0,
-                @_
-              );
-    
-    # {{{ Check ACLS
-    #If the watcher we're trying to add is for the current user
-    if ( ( ( defined $args{'Email'})  && 
-           ( $args{'Email'} eq $self->CurrentUser->EmailAddress) ) or 
-        ($args{'Owner'} eq $self->CurrentUser->Id)) {
-       
-       #  If it's an AdminCc and they don't have 
-       #   'WatchAsAdminCc' or 'ModifyQueueWatchers', bail
-       if ($args{'Type'} eq 'AdminCc') {
-           unless ($self->CurrentUserHasRight('ModifyQueueWatchers') or 
-                   $self->CurrentUserHasRight('WatchAsAdminCc')) {
-               return(0, 'Permission Denied');
-           }
-       }
-
-       #  If it's a Requestor or Cc and they don't have
-       #   'Watch' or 'ModifyQueueWatchers', bail
-       elsif ($args{'Type'} eq 'Cc') {
-           unless ($self->CurrentUserHasRight('ModifyQueueWatchers') or 
-                   $self->CurrentUserHasRight('Watch')) {
-               return(0, 'Permission Denied');
-           }
-       }
-       else {
-           $RT::Logger->warn("$self -> AddWatcher hit code".
-                             " it never should. We got passed ".
-                             " a type of ". $args{'Type'});
-           return (0,'Error in parameters to $self AddWatcher');
-       }
-    }
-    # If the watcher isn't the current user 
-    # and the current user  doesn't have 'ModifyQueueWatchers'
-    # bail
-    else {
-       unless ($self->CurrentUserHasRight('ModifyQueueWatchers')) {
-           return (0, "Permission Denied");
-       }
-    }
-    # }}}
-        
-    require RT::Watcher;
-    my $Watcher = new RT::Watcher ($self->CurrentUser);
-    return ($Watcher->Create(Scope => 'Queue', 
-                            Value => $self->Id,
-                            Email => $args{'Email'},
-                            Type => $args{'Type'},
-                            Owner => $args{'Owner'}
-                           ));
-}
 
-# }}}
+=item FinalPriority
 
-# {{{ sub AddCc
+Returns the current value of FinalPriority. 
+(In the database, FinalPriority is stored as int(11).)
 
-=head2 AddCc
 
-Add a Cc to this queue.
-Takes a paramhash of Email and Owner. 
-We need either an Email Address in Email or a userid in Owner
 
-=cut
+=item SetFinalPriority VALUE
 
 
-sub AddCc {
-    my $self = shift;
-    return ($self->AddWatcher( Type => 'Cc', @_));
-}
-# }}}
+Set FinalPriority to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, FinalPriority will be stored as a int(11).)
 
-# {{{ sub AddAdminCc
-
-=head2 AddAdminCc
-
-Add an Administrative Cc to this queue.
-Takes a paramhash of Email and Owner. 
-We need either an Email Address in Email or a userid in Owner
 
 =cut
 
-sub AddAdminCc {
-    my $self = shift;
-    return ($self->AddWatcher( Type => 'AdminCc', @_));
-}
-# }}}
-
-# {{{ sub DeleteWatcher
-
-=head2 DeleteWatcher id [type]
 
-DeleteWatcher takes a single argument which is either an email address 
-or a watcher id.  
-If the first argument is an email address, you need to specify the watcher type you're talking
-about as the second argument. Valid values are 'Cc' or 'AdminCc'.
-It removes that watcher from this Queue\'s list of watchers.
+=item DefaultDueIn
 
+Returns the current value of DefaultDueIn. 
+(In the database, DefaultDueIn is stored as int(11).)
 
-=cut
 
 
-sub DeleteWatcher {
-    my $self = shift;
-    my $id = shift;
-    
-    my $type;
-    
-    $type = shift if (@_);
-    
-
-    require RT::Watcher;
-    my $Watcher = new RT::Watcher($self->CurrentUser);
-    
-    #If it\'s a numeric watcherid
-    if ($id =~ /^(\d*)$/) {
-       $Watcher->Load($id);
-    }
-    
-    #Otherwise, we'll assume it's an email address
-    elsif ($type) {
-       my ($result, $msg) = 
-         $Watcher->LoadByValue( Email => $id,
-                                Scope => 'Queue',
-                                Value => $self->id,
-                                Type => $type);
-       return (0,$msg) unless ($result);
-    }
-    
-    else {
-       return(0,"Can\'t delete a watcher by email address without specifying a type");
-    }
-    
-    # {{{ Check ACLS 
-
-    #If the watcher we're trying to delete is for the current user
-    if ($Watcher->Email eq $self->CurrentUser->EmailAddress) {
-               
-       #  If it's an AdminCc and they don't have 
-       #   'WatchAsAdminCc' or 'ModifyQueueWatchers', bail
-       if ($Watcher->Type eq 'AdminCc') {
-           unless ($self->CurrentUserHasRight('ModifyQueueWatchers') or 
-                   $self->CurrentUserHasRight('WatchAsAdminCc')) {
-               return(0, 'Permission Denied');
-           }
-       }
-
-       #  If it's a  Cc and they don't have
-       #   'Watch' or 'ModifyQueueWatchers', bail
-       elsif ($Watcher->Type eq 'Cc') {
-           unless ($self->CurrentUserHasRight('ModifyQueueWatchers') or 
-                   $self->CurrentUserHasRight('Watch')) {
-               return(0, 'Permission Denied');
-           }
-       }
-       else {
-           $RT::Logger->warn("$self -> DeleteWatcher hit code".
-                             " it never should. We got passed ".
-                             " a type of ". $args{'Type'});
-           return (0,'Error in parameters to $self DeleteWatcher');
-       }
-    }
-    # If the watcher isn't the current user 
-    # and the current user  doesn't have 'ModifyQueueWatchers'
-    # bail
-    else {
-       unless ($self->CurrentUserHasRight('ModifyQueueWatchers')) {
-           return (0, "Permission Denied");
-       }
-    }
-
-    # }}}
-    
-    unless (($Watcher->Scope eq 'Queue') and
-           ($Watcher->Value == $self->id) ) {
-       return (0, "Not a watcher for this queue");
-    }
-    
-
-    #Clear out the watchers hash.
-    $self->{'watchers'} = undef;
-    
-    my $retval = $Watcher->Delete();
-    
-    unless ($retval) {
-       return(0,"Watcher could not be deleted.");
-    }
-    
-    return(1, "Watcher deleted");
-}
-
-# {{{ sub DeleteCc
+=item SetDefaultDueIn VALUE
 
-=head2 DeleteCc EMAIL
 
-Takes an email address. It calls DeleteWatcher with a preset 
-type of 'Cc'
+Set DefaultDueIn to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, DefaultDueIn will be stored as a int(11).)
 
 
 =cut
 
-sub DeleteCc {
-   my $self = shift;
-   my $id = shift;
-   return ($self->DeleteWatcher ($id, 'Cc'))
-}
-
-# }}}
 
-# {{{ sub DeleteAdminCc
+=item Creator
 
-=head2 DeleteAdminCc EMAIL
-
-Takes an email address. It calls DeleteWatcher with a preset 
-type of 'AdminCc'
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
 
 
 =cut
 
-sub DeleteAdminCc {
-   my $self = shift;
-   my $id = shift;
-   return ($self->DeleteWatcher ($id, 'AdminCc'))
-}
 
-# }}}
+=item Created
 
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
 
-# }}}
-
-# }}}
-
-# {{{ Dealing with keyword selects
-
-# {{{ sub AddKeywordSelect
-
-=head2 AddKeywordSelect
-
-Takes a paramhash of Name, Keyword, Depth and Single.  Adds a new KeywordSelect for 
-this queue with those attributes.
 
 =cut
 
 
-sub AddKeywordSelect {
-    my $self = shift;
-    my %args = ( Keyword => undef,
-                Depth => undef,
-                Single => undef,
-                Name => undef,
-                @_);
-    
-    #ACLS get handled in KeywordSelect
-    my $NewKeywordSelect = new RT::KeywordSelect($self->CurrentUser);
-    
-    return ($NewKeywordSelect->Create (Keyword => $args{'Keyword'},
-                              Depth => $args{'Depth'},
-                              Name => $args{'Name'},
-                              Single => $args{'Single'},
-                              ObjectType => 'Ticket',
-                              ObjectField => 'Queue',
-                              ObjectValue => $self->Id()
-                             ) );
-}
-
-# }}}
-
-# {{{ sub KeywordSelect
+=item LastUpdatedBy
 
-=head2 KeywordSelect([NAME])
+Returns the current value of LastUpdatedBy. 
+(In the database, LastUpdatedBy is stored as int(11).)
 
-Takes the name of a keyword select for this queue or that's global.
-Returns the relevant KeywordSelect object.  Prefers a keywordselect that's 
-specific to this queue over a global one.  If it can't find the proper
-Keword select or the user doesn't have permission, returns an empty 
-KeywordSelect object
 
 =cut
 
-sub KeywordSelect {
-    my $self = shift;
-    my $name = shift;
-    
-    require RT::KeywordSelect;
-
-    my $select = RT::KeywordSelect->new($self->CurrentUser);
-    if ($self->CurrentUserHasRight('SeeQueue')) {
-       $select->LoadByName( Name => $name, Queue => $self->Id);
-    }
-    return ($select);
-}
-
 
-# }}}
+=item LastUpdated
 
-# {{{ sub KeywordSelects
+Returns the current value of LastUpdated. 
+(In the database, LastUpdated is stored as datetime.)
 
-=head2 KeywordSelects
-
-Returns an B<RT::KeywordSelects> object containing the collection of
-B<RT::KeywordSelect> objects which apply to this queue. (Both queue specific keyword selects
-and global keyword selects.
 
 =cut
 
-sub KeywordSelects {
-  my $self = shift;
 
+=item Disabled
 
-  use RT::KeywordSelects;
-  my $KeywordSelects = new RT::KeywordSelects($self->CurrentUser);
+Returns the current value of Disabled. 
+(In the database, Disabled is stored as smallint(6).)
 
-  if ($self->CurrentUserHasRight('SeeQueue')) {
-      $KeywordSelects->LimitToQueue($self->id);
-      $KeywordSelects->IncludeGlobals();
-  }
-  return ($KeywordSelects);
-}
-# }}}
 
-# }}}
 
-# {{{ ACCESS CONTROL
+=item SetDisabled VALUE
 
-# {{{ sub ACL 
 
-=head2 ACL
+Set Disabled to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Disabled will be stored as a smallint(6).)
 
-#Returns an RT::ACL object of ACEs everyone who has anything to do with this queue.
 
 =cut
 
-sub ACL  {
-    my $self = shift;
-    
-    use RT::ACL;
-    my $acl = new RT::ACL($self->CurrentUser);
-    
-    if ($self->CurrentUserHasRight('ShowACL')) {
-       $acl->LimitToQueue($self->Id);
-    }
-    
-    return ($acl);
-}
-
-# }}}
-
-# {{{ sub _Set
-sub _Set {
-    my $self = shift;
 
-    unless ($self->CurrentUserHasRight('AdminQueue')) {
-       return(0, 'Permission Denied');
-    }  
-    return ($self->SUPER::_Set(@_));
-}
-# }}}
 
-# {{{ sub _Value
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        Name => 
+               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        Description => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        CorrespondAddress => 
+               {read => 1, write => 1, type => 'varchar(120)', default => ''},
+        CommentAddress => 
+               {read => 1, write => 1, type => 'varchar(120)', default => ''},
+        InitialPriority => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        FinalPriority => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        DefaultDueIn => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        LastUpdatedBy => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        LastUpdated => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        Disabled => 
+               {read => 1, write => 1, type => 'smallint(6)', default => '0'},
 
-sub _Value {
-    my $self = shift;
+ }
+};
 
-    unless ($self->CurrentUserHasRight('SeeQueue')) {
-       return (undef);
-    }
 
-    return ($self->__Value(@_));
-}
+        eval "require RT::Queue_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Queue_Overlay.pm}) {
+            die $@;
+        };
 
-# }}}
+        eval "require RT::Queue_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Queue_Vendor.pm}) {
+            die $@;
+        };
 
-# {{{ sub CurrentUserHasRight
+        eval "require RT::Queue_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Queue_Local.pm}) {
+            die $@;
+        };
 
-=head2 CurrentUserHasRight
 
-Takes one argument. A textual string with the name of the right we want to check.
-Returns true if the current user has that right for this queue.
-Returns undef otherwise.
 
-=cut
 
-sub CurrentUserHasRight {
-  my $self = shift;
-  my $right = shift;
+=head1 SEE ALSO
 
-  return ($self->HasRight( Principal=> $self->CurrentUser,
-                            Right => "$right"));
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
 
-}
+These overlay files can contain new subs or subs to replace existing subs in this module.
 
-# }}}
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
 
-# {{{ sub HasRight
+   no warnings qw(redefine);
 
-=head2 HasRight
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
 
-Takes a param hash with the fields 'Right' and 'Principal'.
-Principal defaults to the current user.
-Returns true if the principal has that right for this queue.
-Returns undef otherwise.
+RT::Queue_Overlay, RT::Queue_Vendor, RT::Queue_Local
 
 =cut
 
-# TAKES: Right and optional "Principal" which defaults to the current user
-sub HasRight {
-    my $self = shift;
-        my %args = ( Right => undef,
-                     Principal => $self->CurrentUser,
-                     @_);
-        unless(defined $args{'Principal'}) {
-                $RT::Logger->debug("Principal undefined in Queue::HasRight");
-
-        }
-        return($args{'Principal'}->HasQueueRight(QueueObj => $self,
-          Right => $args{'Right'}));
-}
-# }}}
-
-# }}}
 
 1;
diff --git a/rt/lib/RT/Queue_Overlay.pm b/rt/lib/RT/Queue_Overlay.pm
new file mode 100644 (file)
index 0000000..4eb265f
--- /dev/null
@@ -0,0 +1,1012 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Queue - an RT Queue object
+
+=head1 SYNOPSIS
+
+  use RT::Queue;
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=begin testing 
+
+use RT::Queue;
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+use vars qw(@STATUS @ACTIVE_STATUS @INACTIVE_STATUS $RIGHTS);
+use RT::Groups;
+use RT::ACL;
+
+
+@ACTIVE_STATUS = qw(new open stalled);
+@INACTIVE_STATUS = qw(resolved rejected deleted);
+@STATUS = (@ACTIVE_STATUS, @INACTIVE_STATUS);
+
+# $self->loc('new'); # For the string extractor to get a string to localize
+# $self->loc('open'); # For the string extractor to get a string to localize
+# $self->loc('stalled'); # For the string extractor to get a string to localize
+# $self->loc('resolved'); # For the string extractor to get a string to localize
+# $self->loc('rejected'); # For the string extractor to get a string to localize
+# $self->loc('deleted'); # For the string extractor to get a string to localize
+
+
+$RIGHTS = {
+    SeeQueue            => 'Can this principal see this queue',       # loc_pair
+    AdminQueue          => 'Create, delete and modify queues',        # loc_pair
+    ShowACL             => 'Display Access Control List',             # loc_pair
+    ModifyACL           => 'Modify Access Control List',              # loc_pair
+    ModifyQueueWatchers => 'Modify the queue watchers',               # loc_pair
+    AdminCustomFields   => 'Create, delete and modify custom fields', # loc_pair
+    ModifyTemplate      => 'Modify Scrip templates for this queue',   # loc_pair
+    ShowTemplate        => 'Display Scrip templates for this queue',  # loc_pair
+
+    ModifyScrips => 'Modify Scrips for this queue',                   # loc_pair
+    ShowScrips   => 'Display Scrips for this queue',                  # loc_pair
+
+    ShowTicket         => 'Show ticket summaries',                    # loc_pair
+    ShowTicketComments => 'Show ticket private commentary',           # loc_pair
+
+    Watch => 'Sign up as a ticket Requestor or ticket or queue Cc',   # loc_pair
+    WatchAsAdminCc  => 'Sign up as a ticket or queue AdminCc',        # loc_pair
+    CreateTicket    => 'Create tickets in this queue',                # loc_pair
+    ReplyToTicket   => 'Reply to tickets',                            # loc_pair
+    CommentOnTicket => 'Comment on tickets',                          # loc_pair
+    OwnTicket       => 'Own tickets',                                 # loc_pair
+    ModifyTicket    => 'Modify tickets',                              # loc_pair
+    DeleteTicket    => 'Delete tickets',                              # loc_pair
+    TakeTicket      => 'Take tickets',                                # loc_pair
+    StealTicket     => 'Steal tickets',                               # loc_pair
+
+};
+
+# Tell RT::ACE that this sort of object can get acls granted
+$RT::ACE::OBJECT_TYPES{'RT::Queue'} = 1;
+
+# TODO: This should be refactored out into an RT::ACLedObject or something
+# stuff the rights into a hash of rights that can exist.
+
+foreach my $right ( keys %{$RIGHTS} ) {
+    $RT::ACE::LOWERCASERIGHTNAMES{ lc $right } = $right;
+}
+    
+
+=head2 AvailableRights
+
+Returns a hash of available rights for this object. The keys are the right names and the values are a description of what the rights do
+
+=cut
+
+sub AvailableRights {
+    my $self = shift;
+    return($RIGHTS);
+}
+
+# {{{ ActiveStatusArray
+
+=head2 ActiveStatusArray
+
+Returns an array of all ActiveStatuses for this queue
+
+=cut
+
+sub ActiveStatusArray {
+    my $self = shift;
+    return (@ACTIVE_STATUS);
+}
+
+# }}}
+
+# {{{ InactiveStatusArray
+
+=head2 InactiveStatusArray
+
+Returns an array of all InactiveStatuses for this queue
+
+=cut
+
+sub InactiveStatusArray {
+    my $self = shift;
+    return (@INACTIVE_STATUS);
+}
+
+# }}}
+
+# {{{ StatusArray
+
+=head2 StatusArray
+
+Returns an array of all statuses for this queue
+
+=cut
+
+sub StatusArray {
+    my $self = shift;
+    return (@STATUS);
+}
+
+# }}}
+
+# {{{ IsValidStatus
+
+=head2 IsValidStatus VALUE
+
+Returns true if VALUE is a valid status.  Otherwise, returns 0
+
+=for testing
+my $q = RT::Queue->new($RT::SystemUser);
+ok($q->IsValidStatus('new')== 1, 'New is a valid status');
+ok($q->IsValidStatus('f00')== 0, 'f00 is not a valid status');
+
+=cut
+
+sub IsValidStatus {
+    my $self  = shift;
+    my $value = shift;
+
+    my $retval = grep ( /^$value$/, $self->StatusArray );
+    return ($retval);
+
+}
+
+# }}}
+
+# {{{ IsActiveStatus
+
+=head2 IsActiveStatus VALUE
+
+Returns true if VALUE is a Active status.  Otherwise, returns 0
+
+=for testing
+my $q = RT::Queue->new($RT::SystemUser);
+ok($q->IsActiveStatus('new')== 1, 'New is a Active status');
+ok($q->IsActiveStatus('rejected')== 0, 'Rejected is an inactive status');
+ok($q->IsActiveStatus('f00')== 0, 'f00 is not a Active status');
+
+=cut
+
+sub IsActiveStatus {
+    my $self  = shift;
+    my $value = shift;
+
+    my $retval = grep ( /^$value$/, $self->ActiveStatusArray );
+    return ($retval);
+
+}
+
+# }}}
+
+# {{{ IsInactiveStatus
+
+=head2 IsInactiveStatus VALUE
+
+Returns true if VALUE is a Inactive status.  Otherwise, returns 0
+
+=for testing
+my $q = RT::Queue->new($RT::SystemUser);
+ok($q->IsInactiveStatus('new')== 0, 'New is a Active status');
+ok($q->IsInactiveStatus('rejected')== 1, 'rejeected is an Inactive status');
+ok($q->IsInactiveStatus('f00')== 0, 'f00 is not a Active status');
+
+=cut
+
+sub IsInactiveStatus {
+    my $self  = shift;
+    my $value = shift;
+
+    my $retval = grep ( /^$value$/, $self->InactiveStatusArray );
+    return ($retval);
+
+}
+
+# }}}
+
+
+# {{{ sub Create
+
+=head2 Create
+
+Create takes the name of the new queue 
+If you pass the ACL check, it creates the queue and returns its queue id.
+
+=cut
+
+sub Create {
+    my $self = shift;
+    my %args = (
+        Name              => undef,
+        CorrespondAddress => '',
+        Description       => '',
+        CommentAddress    => '',
+        InitialPriority   => "0",
+        FinalPriority     => "0",
+        DefaultDueIn      => "0",
+        @_
+    );
+
+    unless ( $self->CurrentUser->HasRight(Right => 'AdminQueue', Object => $RT::System) )
+    {    #Check them ACLs
+        return ( 0, $self->loc("No permission to create queues") );
+    }
+
+    unless ( $self->ValidateName( $args{'Name'} ) ) {
+        return ( 0, $self->loc('Queue already exists') );
+    }
+
+    #TODO better input validation
+    $RT::Handle->BeginTransaction();
+
+    my $id = $self->SUPER::Create(%args);
+    unless ($id) {
+        $RT::Handle->Rollback();
+        return ( 0, $self->loc('Queue could not be created') );
+    }
+
+    my $create_ret = $self->_CreateQueueGroups();
+    unless ($create_ret) {
+        $RT::Handle->Rollback();
+        return ( 0, $self->loc('Queue could not be created') );
+    }
+
+    $RT::Handle->Commit();
+    return ( $id, $self->loc("Queue created") );
+}
+
+# }}}
+
+# {{{ sub Delete 
+
+sub Delete {
+    my $self = shift;
+    return ( 0,
+        $self->loc('Deleting this object would break referential integrity') );
+}
+
+# }}}
+
+# {{{ sub SetDisabled
+
+=head2 SetDisabled
+
+Takes a boolean.
+1 will cause this queue to no longer be avaialble for tickets.
+0 will re-enable this queue
+
+=cut
+
+# }}}
+
+# {{{ sub Load 
+
+=head2 Load
+
+Takes either a numerical id or a textual Name and loads the specified queue.
+
+=cut
+
+sub Load {
+    my $self = shift;
+
+    my $identifier = shift;
+    if ( !$identifier ) {
+        return (undef);
+    }
+
+    if ( $identifier =~ /^(\d+)$/ ) {
+        $self->SUPER::LoadById($identifier);
+    }
+    else {
+        $self->LoadByCol( "Name", $identifier );
+    }
+
+    return ( $self->Id );
+
+}
+
+# }}}
+
+# {{{ sub ValidateName
+
+=head2 ValidateName NAME
+
+Takes a queue name. Returns true if it's an ok name for
+a new queue. Returns undef if there's already a queue by that name.
+
+=cut
+
+sub ValidateName {
+    my $self = shift;
+    my $name = shift;
+
+    my $tempqueue = new RT::Queue($RT::SystemUser);
+    $tempqueue->Load($name);
+
+    #If we couldn't load it :)
+    unless ( $tempqueue->id() ) {
+        return (1);
+    }
+
+    #If this queue exists, return undef
+    #Avoid the ACL check.
+    if ( $tempqueue->Name() ) {
+        return (undef);
+    }
+
+    #If the queue doesn't exist, return 1
+    else {
+        return (1);
+    }
+
+}
+
+# }}}
+
+# {{{ sub Templates
+
+=head2 Templates
+
+Returns an RT::Templates object of all of this queue's templates.
+
+=cut
+
+sub Templates {
+    my $self = shift;
+
+    my $templates = RT::Templates->new( $self->CurrentUser );
+
+    if ( $self->CurrentUserHasRight('ShowTemplate') ) {
+        $templates->LimitToQueue( $self->id );
+    }
+
+    return ($templates);
+}
+
+# }}}
+
+# {{{ Dealing with custom fields
+
+# {{{  CustomField
+
+=item CustomField NAME
+
+Load the queue-specific custom field named NAME
+
+=cut
+
+sub CustomField {
+    my $self = shift;
+    my $name = shift;
+    my $cf = RT::CustomField->new($self->CurrentUser);
+    $cf->LoadByNameAndQueue(Name => $name, Queue => $self->Id); 
+    return ($cf);
+}
+
+
+# {{{ CustomFields
+
+=item CustomFields
+
+Returns an RT::CustomFields object containing all global custom fields, as well as those tied to this queue
+
+=cut
+
+sub CustomFields {
+    my $self = shift;
+
+    my $cfs = RT::CustomFields->new( $self->CurrentUser );
+    if ( $self->CurrentUserHasRight('SeeQueue') ) {
+        $cfs->LimitToGlobalOrQueue( $self->Id );
+    }
+    return ($cfs);
+}
+
+# }}}
+
+# }}}
+
+
+# {{{ Routines dealing with watchers.
+
+# {{{ _CreateQueueGroups 
+
+=head2 _CreateQueueGroups
+
+Create the ticket groups and relationships for this ticket. 
+This routine expects to be called from Ticket->Create _inside of a transaction_
+
+It will create four groups for this ticket: Requestor, Cc, AdminCc and Owner.
+
+It will return true on success and undef on failure.
+
+=begin testing
+
+my $Queue = RT::Queue->new($RT::SystemUser); my ($id, $msg) = $Queue->Create(Name => "Foo",
+                );
+ok ($id, "Foo $id was created");
+ok(my $group = RT::Group->new($RT::SystemUser));
+ok($group->LoadQueueRoleGroup(Queue => $id, Type=> 'Cc'));
+ok ($group->Id, "Found the requestors object for this Queue");
+
+
+ok ((my $add_id, $add_msg) = $Queue->AddWatcher(Type => 'Cc', Email => 'bob@fsck.com'), "Added bob at fsck.com as a requestor");
+ok ($add_id, "Add succeeded: ($add_msg)");
+ok(my $bob = RT::User->new($RT::SystemUser), "Creating a bob rt::user");
+$bob->LoadByEmail('bob@fsck.com');
+ok($bob->Id,  "Found the bob rt user");
+ok ($Queue->IsWatcher(Type => 'Cc', PrincipalId => $bob->PrincipalId), "The Queue actually has bob at fsck.com as a requestor");;
+ok ((my $add_id, $add_msg) = $Queue->DeleteWatcher(Type =>'Cc', Email => 'bob@fsck.com'), "Added bob at fsck.com as a requestor");
+ok (!$Queue->IsWatcher(Type => 'Cc', Principal => $bob->PrincipalId), "The Queue no longer has bob at fsck.com as a requestor");;
+
+
+$group = RT::Group->new($RT::SystemUser);
+ok($group->LoadQueueRoleGroup(Queue => $id, Type=> 'Cc'));
+ok ($group->Id, "Found the cc object for this Queue");
+$group = RT::Group->new($RT::SystemUser);
+ok($group->LoadQueueRoleGroup(Queue => $id, Type=> 'AdminCc'));
+ok ($group->Id, "Found the AdminCc object for this Queue");
+
+=end testing
+
+=cut
+
+
+sub _CreateQueueGroups {
+    my $self = shift;
+
+    my @types = qw(Cc AdminCc Requestor Owner);
+
+    foreach my $type (@types) {
+        my $type_obj = RT::Group->new($self->CurrentUser);
+        my ($id, $msg) = $type_obj->CreateRoleGroup(Instance => $self->Id, 
+                                                     Type => $type,
+                                                     Domain => 'RT::Queue-Role');
+        unless ($id) {
+            $RT::Logger->error("Couldn't create a Queue group of type '$type' for ticket ".
+                               $self->Id.": ".$msg);
+            return(undef);
+        }
+     }
+    return(1);
+   
+}
+
+
+# }}}
+
+# {{{ sub AddWatcher
+
+=head2 AddWatcher
+
+AddWatcher takes a parameter hash. The keys are as follows:
+
+Type        One of Requestor, Cc, AdminCc
+
+PrinicpalId The RT::Principal id of the user or group that's being added as a watcher
+Email       The email address of the new watcher. If a user with this 
+            email address can't be found, a new nonprivileged user will be created.
+
+If the watcher you\'re trying to set has an RT account, set the Owner paremeter to their User Id. Otherwise, set the Email parameter to their Email address.
+
+=cut
+
+sub AddWatcher {
+    my $self = shift;
+    my %args = (
+        Type  => undef,
+        PrincipalId => undef,
+        Email => undef,
+        @_
+    );
+
+    # {{{ Check ACLS
+    #If the watcher we're trying to add is for the current user
+    if ( $self->CurrentUser->PrincipalId  eq $args{'PrincipalId'}) {
+        #  If it's an AdminCc and they don't have 
+        #   'WatchAsAdminCc' or 'ModifyTicket', bail
+        if ( $args{'Type'} eq 'AdminCc' ) {
+            unless ( $self->CurrentUserHasRight('ModifyQueueWatchers')
+                or $self->CurrentUserHasRight('WatchAsAdminCc') ) {
+                return ( 0, $self->loc('Permission Denied'))
+            }
+        }
+
+        #  If it's a Requestor or Cc and they don't have
+        #   'Watch' or 'ModifyTicket', bail
+        elsif ( ( $args{'Type'} eq 'Cc' ) or ( $args{'Type'} eq 'Requestor' ) ) {
+
+            unless ( $self->CurrentUserHasRight('ModifyQueueWatchers')
+                or $self->CurrentUserHasRight('Watch') ) {
+                return ( 0, $self->loc('Permission Denied'))
+            }
+        }
+     else {
+            $RT::Logger->warn( "$self -> AddWatcher got passed a bogus type");
+            return ( 0, $self->loc('Error in parameters to Queue->AddWatcher') );
+        }
+    }
+
+    # If the watcher isn't the current user 
+    # and the current user  doesn't have 'ModifyQueueWatcher'
+    # bail
+    else {
+        unless ( $self->CurrentUserHasRight('ModifyQueueWatchers') ) {
+            return ( 0, $self->loc("Permission Denied") );
+        }
+    }
+
+    # }}}
+
+    return ( $self->_AddWatcher(%args) );
+}
+
+#This contains the meat of AddWatcher. but can be called from a routine like
+# Create, which doesn't need the additional acl check
+sub _AddWatcher {
+    my $self = shift;
+    my %args = (
+        Type   => undef,
+        Silent => undef,
+        PrincipalId => undef,
+        Email => undef,
+        @_
+    );
+
+
+    my $principal = RT::Principal->new($self->CurrentUser);
+    if ($args{'PrincipalId'}) {
+        $principal->Load($args{'PrincipalId'});
+    }
+    elsif ($args{'Email'}) {
+
+        my $user = RT::User->new($self->CurrentUser);
+        $user->LoadByEmail($args{'Email'});
+
+        unless ($user->Id) {
+            $user->Load($args{'Email'});
+        }
+        if ($user->Id) { # If the user exists
+            $principal->Load($user->PrincipalId);
+        } else {
+
+        # if the user doesn't exist, we need to create a new user
+             my $new_user = RT::User->new($RT::SystemUser);
+
+            my ( $Val, $Message ) = $new_user->Create(
+                Name => $args{'Email'},
+                EmailAddress => $args{'Email'},
+                RealName     => $args{'Email'},
+                Privileged   => 0,
+                Comments     => 'Autocreated when added as a watcher');
+            unless ($Val) {
+                $RT::Logger->error("Failed to create user ".$args{'Email'} .": " .$Message);
+                # Deal with the race condition of two account creations at once
+                $new_user->LoadByEmail($args{'Email'});
+            }
+            $principal->Load($new_user->PrincipalId);
+        }
+    }
+    # If we can't find this watcher, we need to bail.
+    unless ($principal->Id) {
+        return(0, $self->loc("Could not find or create that user"));
+    }
+
+
+    my $group = RT::Group->new($self->CurrentUser);
+    $group->LoadQueueRoleGroup(Type => $args{'Type'}, Queue => $self->Id);
+    unless ($group->id) {
+        return(0,$self->loc("Group not found"));
+    }
+
+    if ( $group->HasMember( $principal)) {
+
+        return ( 0, $self->loc('That principal is already a [_1] for this queue', $args{'Type'}) );
+    }
+
+
+    my ($m_id, $m_msg) = $group->_AddMember(PrincipalId => $principal->Id);
+    unless ($m_id) {
+        $RT::Logger->error("Failed to add ".$principal->Id." as a member of group ".$group->Id."\n".$m_msg);
+
+        return ( 0, $self->loc('Could not make that principal a [_1] for this queue', $args{'Type'}) );
+    }
+    return ( 1, $self->loc('Added principal as a [_1] for this queue', $args{'Type'}) );
+}
+
+# }}}
+
+# {{{ sub DeleteWatcher
+
+=head2 DeleteWatcher { Type => TYPE, PrincipalId => PRINCIPAL_ID, Email => EMAIL_ADDRESS }
+
+
+Deletes a queue  watcher.  Takes two arguments:
+
+Type  (one of Requestor,Cc,AdminCc)
+
+and one of
+
+PrincipalId (an RT::Principal Id of the watcher you want to remove)
+    OR
+Email (the email address of an existing wathcer)
+
+
+=cut
+
+
+sub DeleteWatcher {
+    my $self = shift;
+
+    my %args = ( Type => undef,
+                 PrincipalId => undef,
+                 @_ );
+
+    unless ($args{'PrincipalId'} ) {
+        return(0, $self->loc("No principal specified"));
+    }
+    my $principal = RT::Principal->new($self->CurrentUser);
+    $principal->Load($args{'PrincipalId'});
+
+    # If we can't find this watcher, we need to bail.
+    unless ($principal->Id) {
+        return(0, $self->loc("Could not find that principal"));
+    }
+
+    my $group = RT::Group->new($self->CurrentUser);
+    $group->LoadQueueRoleGroup(Type => $args{'Type'}, Queue => $self->Id);
+    unless ($group->id) {
+        return(0,$self->loc("Group not found"));
+    }
+
+    # {{{ Check ACLS
+    #If the watcher we're trying to add is for the current user
+    if ( $self->CurrentUser->PrincipalId  eq $args{'PrincipalId'}) {
+        #  If it's an AdminCc and they don't have 
+        #   'WatchAsAdminCc' or 'ModifyQueue', bail
+  if ( $args{'Type'} eq 'AdminCc' ) {
+            unless ( $self->CurrentUserHasRight('ModifyQueueWatchers')
+                or $self->CurrentUserHasRight('WatchAsAdminCc') ) {
+                return ( 0, $self->loc('Permission Denied'))
+            }
+        }
+
+        #  If it's a Requestor or Cc and they don't have
+        #   'Watch' or 'ModifyQueue', bail
+        elsif ( ( $args{'Type'} eq 'Cc' ) or ( $args{'Type'} eq 'Requestor' ) ) {
+            unless ( $self->CurrentUserHasRight('ModifyQueueWatchers')
+                or $self->CurrentUserHasRight('Watch') ) {
+                return ( 0, $self->loc('Permission Denied'))
+            }
+        }
+        else {
+            $RT::Logger->warn( "$self -> DelWatcher got passed a bogus type");
+            return ( 0, $self->loc('Error in parameters to Queue->DelWatcher') );
+        }
+    }
+
+    # If the watcher isn't the current user 
+    # and the current user  doesn't have 'ModifyQueueWathcers' bail
+    else {
+        unless ( $self->CurrentUserHasRight('ModifyQueueWatchers') ) {
+            return ( 0, $self->loc("Permission Denied") );
+        }
+    }
+
+    # }}}
+
+
+    # see if this user is already a watcher.
+
+    unless ( $group->HasMember($principal)) {
+        return ( 0,
+        $self->loc('That principal is not a [_1] for this queue', $args{'Type'}) );
+    }
+
+    my ($m_id, $m_msg) = $group->_DeleteMember($principal->Id);
+    unless ($m_id) {
+        $RT::Logger->error("Failed to delete ".$principal->Id.
+                           " as a member of group ".$group->Id."\n".$m_msg);
+
+        return ( 0,    $self->loc('Could not remove that principal as a [_1] for this queue', $args{'Type'}) );
+    }
+
+    return ( 1, $self->loc("[_1] is no longer a [_2] for this queue.", $principal->Object->Name, $args{'Type'} ));
+}
+
+# }}}
+
+# {{{ AdminCcAddresses
+
+=head2 AdminCcAddresses
+
+returns String: All queue AdminCc email addresses as a string
+
+=cut
+
+sub AdminCcAddresses {
+    my $self = shift;
+    
+    unless ( $self->CurrentUserHasRight('SeeQueue') ) {
+        return undef;
+    }   
+    
+    return ( $self->AdminCc->MemberEmailAddressesAsString )
+    
+}   
+
+# }}}
+
+# {{{ CcAddresses
+
+=head2 CcAddresses
+
+returns String: All queue Ccs as a string of email addresses
+
+=cut
+
+sub CcAddresses {
+    my $self = shift;
+
+    unless ( $self->CurrentUserHasRight('SeeQueue') ) {
+        return undef;
+    }
+
+    return ( $self->Cc->MemberEmailAddressesAsString);
+
+}
+# }}}
+
+
+# {{{ sub Cc
+
+=head2 Cc
+
+Takes nothing.
+Returns an RT::Group object which contains this Queue's Ccs.
+If the user doesn't have "ShowQueue" permission, returns an empty group
+
+=cut
+
+sub Cc {
+    my $self = shift;
+
+    my $group = RT::Group->new($self->CurrentUser);
+    if ( $self->CurrentUserHasRight('SeeQueue') ) {
+        $group->LoadQueueRoleGroup(Type => 'Cc', Queue => $self->Id);
+    }
+    return ($group);
+
+}
+
+# }}}
+
+# {{{ sub AdminCc
+
+=head2 AdminCc
+
+Takes nothing.
+Returns an RT::Group object which contains this Queue's AdminCcs.
+If the user doesn't have "ShowQueue" permission, returns an empty group
+
+=cut
+
+sub AdminCc {
+    my $self = shift;
+
+    my $group = RT::Group->new($self->CurrentUser);
+    if ( $self->CurrentUserHasRight('SeeQueue') ) {
+        $group->LoadQueueRoleGroup(Type => 'AdminCc', Queue => $self->Id);
+    }
+    return ($group);
+
+}
+
+# }}}
+
+# {{{ IsWatcher, IsCc, IsAdminCc
+
+# {{{ sub IsWatcher
+# a generic routine to be called by IsRequestor, IsCc and IsAdminCc
+
+=head2 IsWatcher { Type => TYPE, PrincipalId => PRINCIPAL_ID }
+
+Takes a param hash with the attributes Type and PrincipalId
+
+Type is one of Requestor, Cc, AdminCc and Owner
+
+PrincipalId is an RT::Principal id 
+
+Returns true if that principal is a member of the group Type for this queue
+
+
+=cut
+
+sub IsWatcher {
+    my $self = shift;
+
+    my %args = ( Type  => 'Cc',
+        PrincipalId    => undef,
+        @_
+    );
+
+    # Load the relevant group. 
+    my $group = RT::Group->new($self->CurrentUser);
+    $group->LoadQueueRoleGroup(Type => $args{'Type'}, Queue => $self->id);
+    # Ask if it has the member in question
+
+    my $principal = RT::Principal->new($self->CurrentUser);
+    $principal->Load($args{'PrincipalId'});
+
+    return ($group->HasMember($principal));
+}
+
+# }}}
+
+
+# {{{ sub IsCc
+
+=head2 IsCc PRINCIPAL_ID
+
+  Takes an RT::Principal id.
+  Returns true if the principal is a requestor of the current queue.
+
+
+=cut
+
+sub IsCc {
+    my $self = shift;
+    my $cc   = shift;
+
+    return ( $self->IsWatcher( Type => 'Cc', PrincipalId => $cc ) );
+
+}
+
+# }}}
+
+# {{{ sub IsAdminCc
+
+=head2 IsAdminCc PRINCIPAL_ID
+
+  Takes an RT::Principal id.
+  Returns true if the principal is a requestor of the current queue.
+
+=cut
+
+sub IsAdminCc {
+    my $self   = shift;
+    my $person = shift;
+
+    return ( $self->IsWatcher( Type => 'AdminCc', PrincipalId => $person ) );
+
+}
+
+# }}}
+
+
+# }}}
+
+
+
+
+
+# }}}
+
+# {{{ ACCESS CONTROL
+
+# {{{ sub _Set
+sub _Set {
+    my $self = shift;
+
+    unless ( $self->CurrentUserHasRight('AdminQueue') ) {
+        return ( 0, $self->loc('Permission Denied') );
+    }
+    return ( $self->SUPER::_Set(@_) );
+}
+
+# }}}
+
+# {{{ sub _Value
+
+sub _Value {
+    my $self = shift;
+
+    unless ( $self->CurrentUserHasRight('SeeQueue') ) {
+        return (undef);
+    }
+
+    return ( $self->__Value(@_) );
+}
+
+# }}}
+
+# {{{ sub CurrentUserHasRight
+
+=head2 CurrentUserHasRight
+
+Takes one argument. A textual string with the name of the right we want to check.
+Returns true if the current user has that right for this queue.
+Returns undef otherwise.
+
+=cut
+
+sub CurrentUserHasRight {
+    my $self  = shift;
+    my $right = shift;
+
+    return (
+        $self->HasRight(
+            Principal => $self->CurrentUser,
+            Right     => "$right"
+          )
+    );
+
+}
+
+# }}}
+
+# {{{ sub HasRight
+
+=head2 HasRight
+
+Takes a param hash with the fields 'Right' and 'Principal'.
+Principal defaults to the current user.
+Returns true if the principal has that right for this queue.
+Returns undef otherwise.
+
+=cut
+
+# TAKES: Right and optional "Principal" which defaults to the current user
+sub HasRight {
+    my $self = shift;
+    my %args = (
+        Right     => undef,
+        Principal => $self->CurrentUser,
+        @_
+    );
+    unless ( defined $args{'Principal'} ) {
+        $RT::Logger->debug("Principal undefined in Queue::HasRight");
+
+    }
+    return (
+        $args{'Principal'}->HasRight(
+            Object => $self,
+            Right    => $args{'Right'}
+          )
+    );
+}
+
+# }}}
+
+# }}}
+
+1;
index ab58d8d..60aec90 100755 (executable)
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Queues.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-=head1 NAME
 
-  RT::Queues - a collection of RT::Queue objects
+=head1 NAME
 
+  RT::Queues -- Class Description
 =head1 SYNOPSIS
 
-  use RT::Queues;
+  use RT::Queues
 
 =head1 DESCRIPTION
 
 
 =head1 METHODS
 
-
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::Queues);
-
-=end testing
-
 =cut
 
 package RT::Queues;
-use RT::EasySearch;
-@ISA= qw(RT::EasySearch);
 
+use RT::SearchBuilder;
+use RT::Queue;
 
-# {{{ sub _Init
-sub _Init { 
-  my $self = shift;
-  $self->{'table'} = "Queues";
-  $self->{'primary_key'} = "id";
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
 
-  # By default, order by name
-  $self->OrderBy( ALIAS => 'main',
-                 FIELD => 'Name',
-                 ORDER => 'ASC');
 
-  return ($self->SUPER::_Init(@_));
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'Queues';
+    $self->{'primary_key'} = 'id';
+
+
+    return ( $self->SUPER::_Init(@_) );
 }
-# }}}
 
-# {{{ sub _DoSearch 
 
-=head2 _DoSearch
+=item NewItem
 
-  A subclass of DBIx::SearchBuilder::_DoSearch that makes sure that _Disabled rows never get seen unless
-we're explicitly trying to see them.
+Returns an empty new RT::Queue item
 
 =cut
 
-sub _DoSearch {
+sub NewItem {
     my $self = shift;
-    
-    #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
-    unless($self->{'find_disabled_rows'}) {
-       $self->LimitToEnabled();
-    }
-    
-    return($self->SUPER::_DoSearch(@_));
-    
+    return(RT::Queue->new($self->CurrentUser));
 }
 
-# }}}
-  
+        eval "require RT::Queues_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Queues_Overlay.pm}) {
+            die $@;
+        };
 
-# {{{ sub Limit 
-sub Limit  {
-  my $self = shift;
-  my %args = ( ENTRYAGGREGATOR => 'AND',
-              @_);
-  $self->SUPER::Limit(%args);
-}
-# }}}
+        eval "require RT::Queues_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Queues_Vendor.pm}) {
+            die $@;
+        };
 
-# {{{ sub NewItem 
-sub NewItem  {
-  my $self = shift;
-  my $item;
+        eval "require RT::Queues_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Queues_Local.pm}) {
+            die $@;
+        };
 
-  use RT::Queue;
-  $item = new RT::Queue($self->CurrentUser);
-  return($item);
-}
-# }}}
 
-# {{{ sub Next 
 
-=head2 Next
 
-Returns the next queue that this user can see.
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::Queues_Overlay, RT::Queues_Vendor, RT::Queues_Local
 
 =cut
-  
-sub Next {
-    my $self = shift;
-    
-    
-    my $Queue = $self->SUPER::Next();
-    if ((defined($Queue)) and (ref($Queue))) {
-
-       if ($Queue->CurrentUserHasRight('SeeQueue')) {
-           return($Queue);
-       }
-       
-       #If the user doesn't have the right to show this queue
-       else {  
-           return($self->Next());
-       }
-    }
-    #if there never was any queue
-    else {
-       return(undef);
-    }  
-    
-}
-# }}}
 
-1;
 
+1;
diff --git a/rt/lib/RT/Queues_Overlay.pm b/rt/lib/RT/Queues_Overlay.pm
new file mode 100644 (file)
index 0000000..b85144b
--- /dev/null
@@ -0,0 +1,130 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Queues - a collection of RT::Queue objects
+
+=head1 SYNOPSIS
+
+  use RT::Queues;
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::Queues);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+# {{{ sub _Init
+sub _Init { 
+  my $self = shift;
+  $self->{'table'} = "Queues";
+  $self->{'primary_key'} = "id";
+
+  # By default, order by name
+  $self->OrderBy( ALIAS => 'main',
+                 FIELD => 'Name',
+                 ORDER => 'ASC');
+
+  return ($self->SUPER::_Init(@_));
+}
+# }}}
+
+# {{{ sub _DoSearch 
+
+=head2 _DoSearch
+
+  A subclass of DBIx::SearchBuilder::_DoSearch that makes sure that _Disabled rows never get seen unless
+we're explicitly trying to see them.
+
+=cut
+
+sub _DoSearch {
+    my $self = shift;
+    
+    #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
+    unless($self->{'find_disabled_rows'}) {
+       $self->LimitToEnabled();
+    }
+    
+    return($self->SUPER::_DoSearch(@_));
+    
+}
+
+# }}}
+  
+
+# {{{ sub Limit 
+sub Limit  {
+  my $self = shift;
+  my %args = ( ENTRYAGGREGATOR => 'AND',
+              @_);
+  $self->SUPER::Limit(%args);
+}
+# }}}
+
+# {{{ sub Next 
+
+=head2 Next
+
+Returns the next queue that this user can see.
+
+=cut
+  
+sub Next {
+    my $self = shift;
+    
+    
+    my $Queue = $self->SUPER::Next();
+    if ((defined($Queue)) and (ref($Queue))) {
+
+       if ($Queue->CurrentUserHasRight('SeeQueue')) {
+           return($Queue);
+       }
+       
+       #If the user doesn't have the right to show this queue
+       else {  
+           return($self->Next());
+       }
+    }
+    #if there never was any queue
+    else {
+       return(undef);
+    }  
+    
+}
+# }}}
+
+1;
+
index 5340f7d..6962221 100755 (executable)
@@ -1,5 +1,26 @@
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Record.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
 =head1 NAME
 
   RT::Record - Base class for RT record objects
@@ -20,20 +41,31 @@ ok (require RT::Record);
 
 =cut
 
-
 package RT::Record;
-use DBIx::SearchBuilder::Record::Cachable;
 use RT::Date;
 use RT::User;
 
-@ISA= qw(DBIx::SearchBuilder::Record::Cachable);
+use RT::Base;
+use DBIx::SearchBuilder::Record::Cachable;
+
+use strict;
+use vars qw/@ISA/;
+
+@ISA = qw(RT::Base);
+
+if ($RT::DontCacheSearchBuilderRecords ) {
+    push (@ISA, 'DBIx::SearchBuilder::Record');
+} else {
+    push (@ISA, 'DBIx::SearchBuilder::Record::Cachable');
+
+}
 
 # {{{ sub _Init 
 
-sub _Init  {
-  my $self = shift;
-  $self->_MyCurrentUser(@_);
-  
+sub _Init {
+    my $self = shift;
+    $self->CurrentUser(@_);
+
 }
 
 # }}}
@@ -48,68 +80,108 @@ The primary keys for RT classes is 'id'
 
 sub _PrimaryKeys {
     my $self = shift;
-    return(['id']);
+    return ( ['id'] );
 }
 
 # }}}
 
-# {{{ sub _MyCurrentUser 
-
-sub _MyCurrentUser  {
+# {{{ sub _Handle 
+sub _Handle {
     my $self = shift;
-  
-    $self->CurrentUser(@_);
-    if(!defined($self->CurrentUser)) {
-       use Carp;
-       Carp::cluck();
-       $RT::Logger->err("$self was created without a CurrentUser\n"); 
-      return(0);
-    }
+    return ($RT::Handle);
 }
 
 # }}}
 
-# {{{ sub _Handle 
-sub _Handle  {
-  my $self = shift;
-  return($RT::Handle);
-}
-# }}}
-
 # {{{ sub Create 
 
-sub Create  {
-    my $self = shift;
-    my $now = new RT::Date($self->CurrentUser);
-    $now->Set(Format=> 'unix', Value => time);
-    push @_, 'Created', $now->ISO()
-      if ($self->_Accessible('Created', 'auto'));
-    
-
-    push @_, 'Creator', $self->{'user'}->id
-      if $self->_Accessible('Creator', 'auto');
-    
-    push @_, 'LastUpdated', $now->ISO()
-      if ($self->_Accessible('LastUpdated', 'auto'));
-
-    push @_, 'LastUpdatedBy', $self->{'user'}->id
-      if $self->_Accessible('LastUpdatedBy', 'auto');
-    
-    
-
-   my $id = $self->SUPER::Create(@_);
-    
-    if ($id) {
-       $self->Load($id);
+=item  Create PARAMHASH
+
+Takes a PARAMHASH of Column -> Value pairs.
+If any Column has a Validate$PARAMNAME subroutine defined and the 
+value provided doesn't pass validation, this routine returns
+an error.
+
+If this object's table has any of the following atetributes defined as
+'Auto', this routine will automatically fill in their values.
+
+=cut
+
+sub Create {
+    my $self    = shift;
+    my %attribs = (@_);
+    foreach my $key ( keys %attribs ) {
+        my $method = "Validate$key";
+        unless ( $self->$method( $attribs{$key} ) ) {
+            if (wantarray) {
+                return ( 0, $self->loc('Invalid value for [_1]', $key) );
+            }
+            else {
+                return (0);
+            }
+        }
+    }
+    my $now = RT::Date->new( $self->CurrentUser );
+    $now->Set( Format => 'unix', Value => time );
+    $attribs{'Created'} = $now->ISO() if ( $self->_Accessible( 'Created', 'auto' ) && !$attribs{'Created'});
+
+    if ($self->_Accessible( 'Creator', 'auto' ) && !$attribs{'Creator'}) {
+         $attribs{'Creator'} = $self->CurrentUser->id || '0'; 
+    }
+    $attribs{'LastUpdated'} = $now->ISO()
+      if ( $self->_Accessible( 'LastUpdated', 'auto' ) && !$attribs{'LastUpdated'});
+
+    $attribs{'LastUpdatedBy'} = $self->CurrentUser->id || '0'
+      if ( $self->_Accessible( 'LastUpdatedBy', 'auto' ) && !$attribs{'LastUpdatedBy'});
+
+    my $id = $self->SUPER::Create(%attribs);
+    if ( UNIVERSAL::isa( $id, 'Class::ReturnValue' ) ) {
+        if ( $id->errno ) {
+            if (wantarray) {
+                return ( 0,
+                    $self->loc( "Internal Error: [_1]", $id->{error_message} ) );
+            }
+            else {
+                return (0);
+            }
+        }
+    }
+    # If the object was created in the database, 
+    # load it up now, so we're sure we get what the database 
+    # has.  Arguably, this should not be necessary, but there
+    # isn't much we can do about it.
+
+   unless ($id) { 
+    if (wantarray) {
+        return ( $id, $self->loc('Object could not be created') );
+    }
+    else {
+        return ($id);
+    }
+
+   }
+
+    if  (UNIVERSAL::isa('errno',$id)) {
+        exit(0);
+       warn "It's here!";
+        return(undef);
+    }
+
+    $self->Load($id) if ($id);
+
+
+
+    if (wantarray) {
+        return ( $id, $self->loc('Object created') );
+    }
+    else {
+        return ($id);
     }
-    
-    return($id);
-    
+
 }
 
 # }}}
 
-
 # {{{ sub LoadByCols
 
 =head2 LoadByCols
@@ -125,28 +197,33 @@ sub LoadByCols {
 
     # If this database is case sensitive we need to uncase objects for
     # explicit loading
-    if ($self->_Handle->CaseSensitive) {
-        my %newhash;
-        foreach my $key (keys %hash) {
-        # If we've been passed an empty value, we can't do the lookup. 
-               # We don't need to explicitly downcase integers or an id.
-               if ($key =~ '^id$' || $hash{$key} =~/^\d+$/ || !defined ($hash{$key}) ) {
-                       $newhash{$key} = $hash{$key};
-               }
-               else {
-                       $newhash{"lower(".$key.")"} = lc($hash{$key});  
-               }
-        }
-       $self->SUPER::LoadByCols(%newhash);
-    }
-    else {
-       $self->SUPER::LoadByCols(%hash);
+    if ( $self->_Handle->CaseSensitive ) {
+        my %newhash;
+        foreach my $key ( keys %hash ) {
+
+            # If we've been passed an empty value, we can't do the lookup. 
+            # We don't need to explicitly downcase integers or an id.
+            if ( $key =~ '^id$'
+                || !defined( $hash{$key} )
+                || $hash{$key} =~ /^\d+$/
+                 )
+            {
+                $newhash{$key} = $hash{$key};
+            }
+            else {
+                $newhash{ "lower(" . $key . ")" } = lc( $hash{$key} );
+            }
+        }
+
+        # We've clobbered everything we care about. bash the old hash
+        # and replace it with the new hash
+        %hash = %newhash;
     }
+    $self->SUPER::LoadByCols(%hash);
 }
 
 # }}}
 
-
 # {{{ Datehandling
 
 # There is room for optimizations in most of those subs:
@@ -154,10 +231,10 @@ sub LoadByCols {
 # {{{ LastUpdatedObj
 
 sub LastUpdatedObj {
-    my $self=shift;
-    my $obj = new RT::Date($self->CurrentUser);
-    
-    $obj->Set(Format => 'sql', Value => $self->LastUpdated);
+    my $self = shift;
+    my $obj  = new RT::Date( $self->CurrentUser );
+
+    $obj->Set( Format => 'sql', Value => $self->LastUpdated );
     return $obj;
 }
 
@@ -166,12 +243,11 @@ sub LastUpdatedObj {
 # {{{ CreatedObj
 
 sub CreatedObj {
-    my $self=shift;
-    my $obj = new RT::Date($self->CurrentUser);
-    
-    $obj->Set(Format => 'sql', Value => $self->Created);
+    my $self = shift;
+    my $obj  = new RT::Date( $self->CurrentUser );
+
+    $obj->Set( Format => 'sql', Value => $self->Created );
 
-    
     return $obj;
 }
 
@@ -182,9 +258,10 @@ sub CreatedObj {
 # TODO: This should be deprecated
 #
 sub AgeAsString {
-    my $self=shift;
-    return($self->CreatedObj->AgeAsString());
+    my $self = shift;
+    return ( $self->CreatedObj->AgeAsString() );
 }
+
 # }}}
 
 # {{{ LastUpdatedAsString
@@ -192,12 +269,13 @@ sub AgeAsString {
 # TODO this should be deprecated
 
 sub LastUpdatedAsString {
-    my $self=shift;
-    if ($self->LastUpdated) {
-       return ($self->LastUpdatedObj->AsString());
-         
-    } else {
-       return "never";
+    my $self = shift;
+    if ( $self->LastUpdated ) {
+        return ( $self->LastUpdatedObj->AsString() );
+
+    }
+    else {
+        return "never";
     }
 }
 
@@ -209,8 +287,9 @@ sub LastUpdatedAsString {
 #
 sub CreatedAsString {
     my $self = shift;
-    return ($self->CreatedObj->AsString());
+    return ( $self->CreatedObj->AsString() );
 }
+
 # }}}
 
 # {{{ LongSinceUpdateAsString
@@ -218,42 +297,47 @@ sub CreatedAsString {
 # TODO This should be deprecated
 #
 sub LongSinceUpdateAsString {
-    my $self=shift;
-    if ($self->LastUpdated) {
-      
-        return ($self->LastUpdatedObj->AgeAsString());
-       
-    } else {
-       return "never";
+    my $self = shift;
+    if ( $self->LastUpdated ) {
+
+        return ( $self->LastUpdatedObj->AgeAsString() );
+
+    }
+    else {
+        return "never";
     }
 }
+
 # }}}
 
 # }}} Datehandling
 
-
 # {{{ sub _Set 
-sub _Set  {
-  my $self = shift;
+sub _Set {
+    my $self = shift;
 
-  my %args = ( Field => undef,
-              Value => undef,
-              IsSQL => undef,
-              @_ );
+    my %args = (
+        Field => undef,
+        Value => undef,
+        IsSQL => undef,
+        @_
+    );
 
+    #if the user is trying to modify the record
+    # TODO: document _why_ this code is here
 
-  #if the user is trying to modify the record
-  if ((!defined ($args{'Field'})) || (!defined ($args{'Value'}))) {
-    $args{'Value'} = 0; 
-   }
+    if ( ( !defined( $args{'Field'} ) ) || ( !defined( $args{'Value'} ) ) ) {
+        $args{'Value'} = 0;
+    }
 
-  $self->_SetLastUpdated();
-  $self->SUPER::_Set(Field => $args{'Field'},
-                    Value => $args{'Value'},
-                    IsSQL => $args{'IsSQL'});
-  
-  
+    $self->_SetLastUpdated();
+    my ( $val, $msg ) = $self->SUPER::_Set(
+        Field => $args{'Field'},
+        Value => $args{'Value'},
+        IsSQL => $args{'IsSQL'}
+    );
 }
+
 # }}}
 
 # {{{ sub _SetLastUpdated
@@ -268,16 +352,20 @@ It takes no options. Arguably, this is a bug
 sub _SetLastUpdated {
     my $self = shift;
     use RT::Date;
-    my $now = new RT::Date($self->CurrentUser);
+    my $now = new RT::Date( $self->CurrentUser );
     $now->SetToNow();
 
-    if ($self->_Accessible('LastUpdated','auto')) {
-       my ($msg, $val) = $self->__Set( Field => 'LastUpdated',
-                                        Value => $now->ISO);
+    if ( $self->_Accessible( 'LastUpdated', 'auto' ) ) {
+        my ( $msg, $val ) = $self->__Set(
+            Field => 'LastUpdated',
+            Value => $now->ISO
+        );
     }
-    if ($self->_Accessible('LastUpdatedBy','auto')) {
-        my ($msg, $val) = $self->__Set( Field => 'LastUpdatedBy', 
-                                       Value => $self->CurrentUser->id);
+    if ( $self->_Accessible( 'LastUpdatedBy', 'auto' ) ) {
+        my ( $msg, $val ) = $self->__Set(
+            Field => 'LastUpdatedBy',
+            Value => $self->CurrentUser->id
+        );
     }
 }
 
@@ -291,15 +379,16 @@ Returns an RT::User object with the RT account of the creator of this row
 
 =cut
 
-sub CreatorObj  {
-  my $self = shift;
-  unless (exists $self->{'CreatorObj'}) {
-    
-    $self->{'CreatorObj'} = RT::User->new($self->CurrentUser);
-    $self->{'CreatorObj'}->Load($self->Creator);
-  }
-  return($self->{'CreatorObj'});
+sub CreatorObj {
+    my $self = shift;
+    unless ( exists $self->{'CreatorObj'} ) {
+
+        $self->{'CreatorObj'} = RT::User->new( $self->CurrentUser );
+        $self->{'CreatorObj'}->Load( $self->Creator );
+    }
+    return ( $self->{'CreatorObj'} );
 }
+
 # }}}
 
 # {{{ sub LastUpdatedByObj
@@ -311,35 +400,56 @@ sub CreatorObj  {
 =cut
 
 sub LastUpdatedByObj {
-    my $self=shift;
-    unless (exists $self->{LastUpdatedByObj}) {
-       $self->{'LastUpdatedByObj'}=RT::User->new($self->CurrentUser);
-       $self->{'LastUpdatedByObj'}->Load($self->LastUpdatedBy);
+    my $self = shift;
+    unless ( exists $self->{LastUpdatedByObj} ) {
+        $self->{'LastUpdatedByObj'} = RT::User->new( $self->CurrentUser );
+        $self->{'LastUpdatedByObj'}->Load( $self->LastUpdatedBy );
     }
     return $self->{'LastUpdatedByObj'};
 }
 
 # }}}
 
-# {{{ sub CurrentUser 
 
-=head2 CurrentUser
+require Encode::compat if $] < 5.007001;
+require Encode;
 
-If called with an argument, sets the current user to that user object.
-This will affect ACL decisions, etc.  
-Returns the current user
+sub __Value {
+    my $self  = shift;
+    my $field = shift;
+    my %args = ( decode_utf8 => 1,
+                 @_ );
 
-=cut
+    unless (defined $field && $field) {
+        $RT::Logger->error("$self __Value called with undef field");
+    }
+    my $value = $self->SUPER::__Value($field);
+
+    return('') if ( !defined($value) || $value eq '');
+
+    return Encode::decode_utf8($value) || $value if $args{'decode_utf8'};
+    return $value;
+}
 
-sub CurrentUser  {
-  my $self = shift;
+# Set up defaults for DBIx::SearchBuilder::Record::Cachable
 
-  if (@_) {
-    $self->{'user'} = shift;
+sub _CacheConfig {
+  {
+     'cache_p'        => 1,
+     'fast_update_p'  => 1,
+     'cache_for_sec'  => 30,
   }
-  return ($self->{'user'});
 }
-# }}}
 
+=head2 _DecodeUTF8
+
+ When passed a string will "decode" it int a proper UTF-8 string
+
+=cut
+
+eval "require RT::Record_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Record_Vendor.pm});
+eval "require RT::Record_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Record_Local.pm});
 
 1;
index aef011c..a69dde0 100755 (executable)
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Scrip.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
 
 =head1 NAME
 
-  RT::Scrip - an RT Scrip object
+RT::Scrip
 
-=head1 SYNOPSIS
 
-  use RT::Scrip;
+=head1 SYNOPSIS
 
 =head1 DESCRIPTION
 
-
 =head1 METHODS
 
-=begin testing
+=cut
 
-ok (require RT::TestHarness);
-ok (require RT::Scrip);
+package RT::Scrip;
+use RT::Record; 
+use RT::Queue;
+use RT::Template;
+use RT::ScripCondition;
+use RT::ScripAction;
 
-=end testing
 
-=cut
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
 
-package RT::Scrip;
-use RT::Record;
-@ISA= qw(RT::Record);
+sub _Init {
+  my $self = shift; 
 
-# {{{ sub _Init
-sub _Init  {
-    my $self = shift;
-    $self->{'table'} = "Scrips";
-    return ($self->SUPER::_Init(@_));
+  $self->Table('Scrips');
+  $self->SUPER::_Init(@_);
 }
-# }}}
 
-# {{{ sub _Accessible 
-sub _Accessible  {
-    my $self = shift;
-    my %Cols = ( ScripAction  => 'read/write',
-                ScripCondition => 'read/write',
-                Stage => 'read/write',
-                Queue => 'read/write', 
-                Template => 'read/write',
-              );
-    return($self->SUPER::_Accessible(@_, %Cols));
-}
-# }}}
 
-# {{{ sub Create 
 
-=head2 Create
 
-Creates a new entry in the Scrips table. Takes a paramhash with the attributes:
 
-    Queue           A queue id or 0 for a global scrip
-    Template        A template ID or name.  
-                    Behavior is undefined if you have multiple items with 
-                    the same name
-    ScripAction     A ScripAction id or name
-                    Behavior is undefined if you have multiple items with 
-                    the same name
-    ScripCondition  A ScripCondition id or name
-                    Behavior is undefined if you have multiple items with 
-                    the same name
+=item Create PARAMHASH
 
-Returns (retval, msg);
-retval is 0 for failure or scrip id.  msg is a textual description of what happened.
+Create takes a hash of values and creates a row in the database:
+
+  varchar(255) 'Description'.
+  int(11) 'ScripCondition'.
+  int(11) 'ScripAction'.
+  text 'ConditionRules'.
+  text 'ActionRules'.
+  text 'CustomIsApplicableCode'.
+  text 'CustomPrepareCode'.
+  text 'CustomCommitCode'.
+  varchar(32) 'Stage'.
+  int(11) 'Queue'.
+  int(11) 'Template'.
 
 =cut
 
-sub Create  {
+
+
+
+sub Create {
     my $self = shift;
-    my %args = ( Queue => undef,
-                Template => undef,
-                ScripAction => undef,
-                ScripCondition => undef,
-                Stage => 'TransactionCreate',
-                @_
-              );
-    
-      
-    if ($args{'Queue'} == 0 ) { 
-       unless ($self->CurrentUser->HasSystemRight('ModifyScrips')) {
-           return (0, 'Permission Denied');
-       }       
-    }
-    else {
-       my $QueueObj = new RT::Queue($self->CurrentUser);
-       $QueueObj->Load($args{'Queue'});
-       unless ($QueueObj->id()) {
-           return (0,'Invalid queue');
-       }
-       unless ($QueueObj->CurrentUserHasRight('ModifyScrips')) {
-           return (0, 'Permssion Denied');
-       }       
-    }
-
-    #TODO +++ validate input 
-
-    require RT::ScripAction;
-    my $action = new RT::ScripAction($self->CurrentUser);
-    $action->Load($args{'ScripAction'});
-    return (0, "Action ".$args{'ScripAction'}." not found") unless $action->Id;
-
-    require RT::Template;
-    my $template = new RT::Template($self->CurrentUser);
-    $template->Load($args{'Template'});
-    return (0, 'Template not found') unless $template->Id;
-
-    require RT::ScripCondition;
-    my $condition = new RT::ScripCondition($self->CurrentUser);
-    $condition->Load($args{'ScripCondition'});
-
-    unless ($condition->Id) {
-       return (0, 'Condition not found');
-    }  
-    
-    my $id = $self->SUPER::Create(Queue => $args{'Queue'},
-                                 Template => $template->Id,
-                                 ScripCondition => $condition->id,
-                                 Stage => $args{'Stage'},
-                                 ScripAction => $action->Id
-                                );
-    return ($id, 'Scrip Created'); 
+    my %args = ( 
+                Description => '',
+                ScripCondition => '0',
+                ScripAction => '0',
+                ConditionRules => '',
+                ActionRules => '',
+                CustomIsApplicableCode => '',
+                CustomPrepareCode => '',
+                CustomCommitCode => '',
+                Stage => '',
+                Queue => '0',
+                Template => '0',
+
+                 @_);
+    $self->SUPER::Create(
+                         Description => $args{'Description'},
+                         ScripCondition => $args{'ScripCondition'},
+                         ScripAction => $args{'ScripAction'},
+                         ConditionRules => $args{'ConditionRules'},
+                         ActionRules => $args{'ActionRules'},
+                         CustomIsApplicableCode => $args{'CustomIsApplicableCode'},
+                         CustomPrepareCode => $args{'CustomPrepareCode'},
+                         CustomCommitCode => $args{'CustomCommitCode'},
+                         Stage => $args{'Stage'},
+                         Queue => $args{'Queue'},
+                         Template => $args{'Template'},
+);
+
 }
 
-# }}}
 
-# {{{ sub Delete
 
-=head2 Delete
+=item id
+
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
 
-Delete this object
 
 =cut
 
-sub Delete {
-    my $self = shift;
-    
-    unless ($self->CurrentUserHasRight('ModifyScrips')) {
-       return (0, 'Permission Denied');
-    }
-    
-    return ($self->SUPER::Delete(@_));
-}
-# }}}
 
-# {{{ sub QueueObj
+=item Description
+
+Returns the current value of Description. 
+(In the database, Description is stored as varchar(255).)
+
 
-=head2 QueueObj
 
-Retuns an RT::Queue object with this Scrip\'s queue
+=item SetDescription VALUE
+
+
+Set Description to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Description will be stored as a varchar(255).)
+
 
 =cut
 
-sub QueueObj {
-    my $self = shift;
-    
-    if (!$self->{'QueueObj'})  {
-       require RT::Queue;
-       $self->{'QueueObj'} = RT::Queue->new($self->CurrentUser);
-       $self->{'QueueObj'}->Load($self->Queue);
-    }
-    return ($self->{'QueueObj'});
-}
 
-# }}}
+=item ScripCondition
+
+Returns the current value of ScripCondition. 
+(In the database, ScripCondition is stored as int(11).)
+
 
-# {{{ sub ActionObj
 
+=item SetScripCondition VALUE
 
-=head2 ActionObj
 
-Retuns an RT::Action object with this Scrip\'s Action
+Set ScripCondition to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ScripCondition will be stored as a int(11).)
+
 
 =cut
 
-sub ActionObj {
-    my $self = shift;
-    
-    unless (defined $self->{'ScripActionObj'})  {
-       require RT::ScripAction;
-       
-       $self->{'ScripActionObj'} = RT::ScripAction->new($self->CurrentUser);
-       #TODO: why are we loading Actions with templates like this. 
-       # two seperate methods might make more sense
-       $self->{'ScripActionObj'}->Load($self->ScripAction, $self->Template);
-    }
-    return ($self->{'ScripActionObj'});
+
+=item ScripConditionObj
+
+Returns the ScripCondition Object which has the id returned by ScripCondition
+
+
+=cut
+
+sub ScripConditionObj {
+       my $self = shift;
+       my $ScripCondition =  RT::ScripCondition->new($self->CurrentUser);
+       $ScripCondition->Load($self->__Value('ScripCondition'));
+       return($ScripCondition);
 }
 
-# }}}
+=item ScripAction
+
+Returns the current value of ScripAction. 
+(In the database, ScripAction is stored as int(11).)
+
+
+
+=item SetScripAction VALUE
 
 
-# {{{ sub TemplateObj
-=head2 TemplateObj
+Set ScripAction to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ScripAction will be stored as a int(11).)
 
-Retuns an RT::Template object with this Scrip\'s Template
 
 =cut
 
-sub TemplateObj {
-    my $self = shift;
-    
-    unless (defined $self->{'TemplateObj'})  {
-       require RT::Template;
-       $self->{'TemplateObj'} = RT::Template->new($self->CurrentUser);
-       $self->{'TemplateObj'}->Load($self->Template);
-    }
-    return ($self->{'TemplateObj'});
-}
 
-# }}}
+=item ScripActionObj
 
-# {{{ sub Prepare
-=head2 Prepare
+Returns the ScripAction Object which has the id returned by ScripAction
 
-Calls the action object's prepare method
 
 =cut
 
-sub Prepare {
-    my $self = shift;
-    $self->ActionObj->Prepare(@_);
+sub ScripActionObj {
+       my $self = shift;
+       my $ScripAction =  RT::ScripAction->new($self->CurrentUser);
+       $ScripAction->Load($self->__Value('ScripAction'));
+       return($ScripAction);
 }
 
-# }}}
+=item ConditionRules
+
+Returns the current value of ConditionRules. 
+(In the database, ConditionRules is stored as text.)
+
 
-# {{{ sub Commit
-=head2 Commit
 
-Calls the action object's commit method
+=item SetConditionRules VALUE
+
+
+Set ConditionRules to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ConditionRules will be stored as a text.)
+
 
 =cut
 
-sub Commit {
-    my $self = shift;
-    $self->ActionObj->Commit(@_);
-}
 
-# }}}
+=item ActionRules
 
-# {{{ sub ConditionObj
+Returns the current value of ActionRules. 
+(In the database, ActionRules is stored as text.)
 
-=head2 ConditionObj
 
-Retuns an RT::ScripCondition object with this Scrip's IsApplicable
+
+=item SetActionRules VALUE
+
+
+Set ActionRules to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ActionRules will be stored as a text.)
+
 
 =cut
 
-sub ConditionObj {
-    my $self = shift;
-    
-    unless (defined $self->{'ScripConditionObj'})  {
-       require RT::ScripCondition;
-       $self->{'ScripConditionObj'} = RT::ScripCondition->new($self->CurrentUser);
-       $self->{'ScripConditionObj'}->Load($self->ScripCondition);
-    }
-    return ($self->{'ScripConditionObj'});
-}
 
-# }}}
+=item CustomIsApplicableCode
+
+Returns the current value of CustomIsApplicableCode. 
+(In the database, CustomIsApplicableCode is stored as text.)
+
+
+
+=item SetCustomIsApplicableCode VALUE
 
-# {{{ sub IsApplicable
 
-=head2 IsApplicable
+Set CustomIsApplicableCode to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, CustomIsApplicableCode will be stored as a text.)
 
-Calls the  Condition object\'s IsApplicable method
 
 =cut
 
-sub IsApplicable {
-    my $self = shift;
-    return ($self->ConditionObj->IsApplicable(@_));
-}
 
-# }}}
+=item CustomPrepareCode
 
-# {{{ sub DESTROY
-sub DESTROY {
-    my $self = shift;
-    $self->{'ActionObj'} = undef;
-}
-# }}}
+Returns the current value of CustomPrepareCode. 
+(In the database, CustomPrepareCode is stored as text.)
 
-# {{{ ACL related methods
 
-# {{{ sub _Set
 
-# does an acl check and then passes off the call
-sub _Set {
-    my $self = shift;
-    
-    unless ($self->CurrentUserHasRight('ModifyScrips')) {
-        $RT::Logger->debug("CurrentUser can't modify Scrips for ".$self->Queue."\n");
-       return (0, 'Permission Denied');
-    }
-    return $self->__Set(@_);
-}
+=item SetCustomPrepareCode VALUE
 
-# }}}
 
-# {{{ sub _Value
-# does an acl check and then passes off the call
-sub _Value {
-    my $self = shift;
-    
-    unless ($self->CurrentUserHasRight('ShowScrips')) {
-        $RT::Logger->debug("CurrentUser can't modify Scrips for ".$self->__Value('Queue')."\n");
-       return (undef);
-    }
-    
-    return $self->__Value(@_);
-}
-# }}}
+Set CustomPrepareCode to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, CustomPrepareCode will be stored as a text.)
+
+
+=cut
+
+
+=item CustomCommitCode
+
+Returns the current value of CustomCommitCode. 
+(In the database, CustomCommitCode is stored as text.)
+
 
-# {{{ sub CurrentUserHasRight
 
-=head2 CurrentUserHasRight
+=item SetCustomCommitCode VALUE
+
+
+Set CustomCommitCode to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, CustomCommitCode will be stored as a text.)
 
-Helper menthod for HasRight. Presets Principal to CurrentUser then 
-calls HasRight.
 
 =cut
 
-sub CurrentUserHasRight {
-    my $self = shift;
-    my $right = shift;
-    return ($self->HasRight( Principal => $self->CurrentUser->UserObj,
-                             Right => $right ));
-    
+
+=item Stage
+
+Returns the current value of Stage. 
+(In the database, Stage is stored as varchar(32).)
+
+
+
+=item SetStage VALUE
+
+
+Set Stage to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Stage will be stored as a varchar(32).)
+
+
+=cut
+
+
+=item Queue
+
+Returns the current value of Queue. 
+(In the database, Queue is stored as int(11).)
+
+
+
+=item SetQueue VALUE
+
+
+Set Queue to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Queue will be stored as a int(11).)
+
+
+=cut
+
+
+=item QueueObj
+
+Returns the Queue Object which has the id returned by Queue
+
+
+=cut
+
+sub QueueObj {
+       my $self = shift;
+       my $Queue =  RT::Queue->new($self->CurrentUser);
+       $Queue->Load($self->__Value('Queue'));
+       return($Queue);
 }
 
-# }}}
+=item Template
+
+Returns the current value of Template. 
+(In the database, Template is stored as int(11).)
+
+
+
+=item SetTemplate VALUE
 
-# {{{ sub HasRight
 
-=head2 HasRight
+Set Template to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Template will be stored as a int(11).)
 
-Takes a param-hash consisting of "Right" and "Principal"  Principal is 
-an RT::User object or an RT::CurrentUser object. "Right" is a textual
-Right string that applies to Scrips.
 
 =cut
 
-sub HasRight {
-    my $self = shift;
-    my %args = ( Right => undef,
-                 Principal => undef,
-                 @_ );
-    
-    if ((defined $self->SUPER::_Value('Queue')) and ($self->SUPER::_Value('Queue') != 0)) {
-        return ( $args{'Principal'}->HasQueueRight(
-                                                  Right => $args{'Right'},
-                                                  Queue => $self->SUPER::_Value('Queue'),
-                                                  Principal => $args{'Principal'}
-                                                 ) 
-              );
-       
-    }
-    else {
-        return( $args{'Principal'}->HasSystemRight( $args{'Right'}) );
-    }
+
+=item TemplateObj
+
+Returns the Template Object which has the id returned by Template
+
+
+=cut
+
+sub TemplateObj {
+       my $self = shift;
+       my $Template =  RT::Template->new($self->CurrentUser);
+       $Template->Load($self->__Value('Template'));
+       return($Template);
 }
-# }}}
 
-# }}}
+=item Creator
+
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
+
+
+=cut
+
+
+=item Created
+
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
+
+
+=cut
+
+
+=item LastUpdatedBy
+
+Returns the current value of LastUpdatedBy. 
+(In the database, LastUpdatedBy is stored as int(11).)
+
+
+=cut
+
+
+=item LastUpdated
+
+Returns the current value of LastUpdated. 
+(In the database, LastUpdated is stored as datetime.)
+
+
+=cut
 
-1;
 
 
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        Description => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        ScripCondition => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        ScripAction => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        ConditionRules => 
+               {read => 1, write => 1, type => 'text', default => ''},
+        ActionRules => 
+               {read => 1, write => 1, type => 'text', default => ''},
+        CustomIsApplicableCode => 
+               {read => 1, write => 1, type => 'text', default => ''},
+        CustomPrepareCode => 
+               {read => 1, write => 1, type => 'text', default => ''},
+        CustomCommitCode => 
+               {read => 1, write => 1, type => 'text', default => ''},
+        Stage => 
+               {read => 1, write => 1, type => 'varchar(32)', default => ''},
+        Queue => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Template => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        LastUpdatedBy => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        LastUpdated => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+
+ }
+};
+
+
+        eval "require RT::Scrip_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Scrip_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Scrip_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Scrip_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Scrip_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Scrip_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::Scrip_Overlay, RT::Scrip_Vendor, RT::Scrip_Local
+
+=cut
+
+
+1;
index 471ad91..26824df 100755 (executable)
-# Copyright 1999-2000 Jesse Vincent <jesse@fsck.com>
-# Released under the terms of the GNU Public License
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/ScripAction.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
 
 =head1 NAME
 
-  RT::ScripAction - RT Action object
+RT::ScripAction
+
 
 =head1 SYNOPSIS
 
-  use RT::ScripAction;
+=head1 DESCRIPTION
 
+=head1 METHODS
+
+=cut
+
+package RT::ScripAction;
+use RT::Record; 
 
-=head1 DESCRIPTION
 
-This module should never be called directly by client code. it's an internal module which
-should only be accessed through exported APIs in other modules.
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
 
+sub _Init {
+  my $self = shift; 
 
-=begin testing
+  $self->Table('ScripActions');
+  $self->SUPER::_Init(@_);
+}
 
-ok (require RT::TestHarness);
-ok (require RT::ScripAction);
 
-=end testing
 
-=head1 METHODS
+
+
+=item Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+  varchar(200) 'Name'.
+  varchar(255) 'Description'.
+  varchar(60) 'ExecModule'.
+  varchar(255) 'Argument'.
 
 =cut
 
-package RT::ScripAction;
-use RT::Record;
-@ISA= qw(RT::Record);
-
-# {{{  sub _Init 
-sub _Init  {
-    my $self = shift; 
-    $self->{'table'} = "ScripActions";
-    return ($self->SUPER::_Init(@_));
-}
-# }}}
 
-# {{{ sub _Accessible 
-sub _Accessible  {
+
+
+sub Create {
     my $self = shift;
-    my %Cols = ( Name  => 'read',
-                Description => 'read',
-                ExecModule  => 'read',
-                Argument  => 'read',
-                Creator => 'read/auto',
-                Created => 'read/auto',
-                LastUpdatedBy => 'read/auto',
-                LastUpdated => 'read/auto'
-       );
-    return($self->SUPER::_Accessible(@_, %Cols));
+    my %args = ( 
+                Name => '',
+                Description => '',
+                ExecModule => '',
+                Argument => '',
+
+                 @_);
+    $self->SUPER::Create(
+                         Name => $args{'Name'},
+                         Description => $args{'Description'},
+                         ExecModule => $args{'ExecModule'},
+                         Argument => $args{'Argument'},
+);
+
 }
-# }}}
 
-# {{{ sub Create 
-=head2 Create
-  
- Takes a hash. Creates a new Action entry.
- should be better documented.
+
+
+=item id
+
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
+
+
 =cut
 
-sub Create  {
-    my $self = shift;
-    #TODO check these args and do smart things.
-    return($self->SUPER::Create(@_));
-}
-# }}}
 
-# {{{ sub Delete 
-sub Delete  {
-    my $self = shift;
-    
-    return (0, "ScripAction->Delete not implemented");
-}
-# }}}
+=item Name
+
+Returns the current value of Name. 
+(In the database, Name is stored as varchar(200).)
 
-# {{{ sub Load 
-sub Load  {
-    my $self = shift;
-    my $identifier = shift;
-    
-    if (!$identifier) {
-       return (0, 'Input error');
-    }      
-    
-    if ($identifier !~ /\D/) {
-       $self->SUPER::LoadById($identifier);
-    }
-    else {
-       $self->LoadByCol('Name', $identifier);
-       
-    }
-
-    if (@_) {
-       # Set the template Id to the passed in template    
-       my $template = shift;
-       
-       $self->{'Template'} = $template;
-    }
-    return ($self->Id, 'ScripAction loaded');
-}
-# }}}
 
-# {{{ sub LoadAction 
 
-=head2 LoadAction HASH
+=item SetName VALUE
+
+
+Set Name to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Name will be stored as a varchar(200).)
 
-  Takes a hash consisting of TicketObj and TransactionObj.  Loads an RT::Action:: module.
 
 =cut
 
-sub LoadAction  {
-    my $self = shift;
-    my %args = ( TransactionObj => undef,
-                TicketObj => undef,
-                @_ );
-    
-    #TODO: Put this in an eval  
-    $self->ExecModule =~ /^(\w+)$/;
-    my $module = $1;
-    my $type = "RT::Action::". $module;
-    $RT::Logger->debug("now requiring $type\n"); 
-    eval "require $type" || die "Require of $type failed.\n$@\n";
-    
-    $self->{'Action'}  = $type->new ( 'ScripActionObj' => $self, 
-                                     'TicketObj' => $args{'TicketObj'},
-                                     'TransactionObj' => $args{'TransactionObj'},
-                                     'TemplateObj' => $self->TemplateObj,
-                                     'Argument' => $self->Argument,
-                                   );
-}
-# }}}
 
-# {{{ sub TemplateObj
+=item Description
+
+Returns the current value of Description. 
+(In the database, Description is stored as varchar(255).)
+
+
 
-=head2 TemplateObj
+=item SetDescription VALUE
+
+
+Set Description to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Description will be stored as a varchar(255).)
 
-Return this action\'s template object
 
 =cut
 
-sub TemplateObj {
-    my $self = shift;
-    return undef unless $self->{Template};
-    if (!$self->{'TemplateObj'})  {
-       require RT::Template;
-       $self->{'TemplateObj'} = RT::Template->new($self->CurrentUser);
-       $self->{'TemplateObj'}->LoadById($self->{'Template'});
-       
-    }
-    
-    return ($self->{'TemplateObj'});
-}
-# }}}
 
-# The following methods call the action object
+=item ExecModule
 
-# {{{ sub Prepare 
+Returns the current value of ExecModule. 
+(In the database, ExecModule is stored as varchar(60).)
 
-sub Prepare  {
-    my $self = shift;
-    return ($self->{'Action'}->Prepare());
-  
-}
-# }}}
 
-# {{{ sub Commit 
-sub Commit  {
-    my $self = shift;
-    return($self->{'Action'}->Commit());
-    
-    
-}
-# }}}
 
-# {{{ sub Describe 
-sub Describe  {
-    my $self = shift;
-    return ($self->{'Action'}->Describe());
-    
-}
-# }}}
+=item SetExecModule VALUE
 
-# {{{ sub DESTROY
-sub DESTROY {
-    my $self=shift;
-    $self->{'Action'} = undef;
-    $self->{'TemplateObj'} = undef;
-}
-# }}}
 
+Set ExecModule to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ExecModule will be stored as a varchar(60).)
 
-1;
 
+=cut
+
+
+=item Argument
+
+Returns the current value of Argument. 
+(In the database, Argument is stored as varchar(255).)
 
+
+
+=item SetArgument VALUE
+
+
+Set Argument to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Argument will be stored as a varchar(255).)
+
+
+=cut
+
+
+=item Creator
+
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
+
+
+=cut
+
+
+=item Created
+
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
+
+
+=cut
+
+
+=item LastUpdatedBy
+
+Returns the current value of LastUpdatedBy. 
+(In the database, LastUpdatedBy is stored as int(11).)
+
+
+=cut
+
+
+=item LastUpdated
+
+Returns the current value of LastUpdated. 
+(In the database, LastUpdated is stored as datetime.)
+
+
+=cut
+
+
+
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        Name => 
+               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        Description => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        ExecModule => 
+               {read => 1, write => 1, type => 'varchar(60)', default => ''},
+        Argument => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        LastUpdatedBy => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        LastUpdated => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+
+ }
+};
+
+
+        eval "require RT::ScripAction_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/ScripAction_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::ScripAction_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/ScripAction_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::ScripAction_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/ScripAction_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::ScripAction_Overlay, RT::ScripAction_Vendor, RT::ScripAction_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/ScripAction_Overlay.pm b/rt/lib/RT/ScripAction_Overlay.pm
new file mode 100644 (file)
index 0000000..e2b018a
--- /dev/null
@@ -0,0 +1,217 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::ScripAction - RT Action object
+
+=head1 SYNOPSIS
+
+  use RT::ScripAction;
+
+
+=head1 DESCRIPTION
+
+This module should never be called directly by client code. it's an internal module which
+should only be accessed through exported APIs in other modules.
+
+
+=begin testing
+
+ok (require RT::ScripAction);
+
+=end testing
+
+=head1 METHODS
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+# {{{  sub _Init 
+sub _Init  {
+    my $self = shift; 
+    $self->{'table'} = "ScripActions";
+    return ($self->SUPER::_Init(@_));
+}
+# }}}
+
+# {{{ sub _Accessible 
+sub _Accessible  {
+    my $self = shift;
+    my %Cols = ( Name  => 'read',
+                Description => 'read',
+                ExecModule  => 'read',
+                Argument  => 'read',
+                Creator => 'read/auto',
+                Created => 'read/auto',
+                LastUpdatedBy => 'read/auto',
+                LastUpdated => 'read/auto'
+       );
+    return($self->SUPER::_Accessible(@_, %Cols));
+}
+# }}}
+
+# {{{ sub Create 
+=head2 Create
+  
+ Takes a hash. Creates a new Action entry.
+ should be better documented.
+=cut
+
+sub Create  {
+    my $self = shift;
+    #TODO check these args and do smart things.
+    return($self->SUPER::Create(@_));
+}
+# }}}
+
+# {{{ sub Delete 
+sub Delete  {
+    my $self = shift;
+    
+    return (0, "ScripAction->Delete not implemented");
+}
+# }}}
+
+# {{{ sub Load 
+sub Load  {
+    my $self = shift;
+    my $identifier = shift;
+    
+    if (!$identifier) {
+       return (0, $self->loc('Input error'));
+    }      
+    
+    if ($identifier !~ /\D/) {
+       $self->SUPER::Load($identifier);
+    }
+    else {
+       $self->LoadByCol('Name', $identifier);
+       
+    }
+
+    if (@_) {
+       # Set the template Id to the passed in template    
+       my $template = shift;
+       
+       $self->{'Template'} = $template;
+    }
+    return ($self->loc('[_1] ScripAction loaded', $self->Id));
+}
+# }}}
+
+# {{{ sub LoadAction 
+
+=head2 LoadAction HASH
+
+  Takes a hash consisting of TicketObj and TransactionObj.  Loads an RT::Action:: module.
+
+=cut
+
+sub LoadAction  {
+    my $self = shift;
+    my %args = ( TransactionObj => undef,
+                TicketObj => undef,
+                @_ );
+    
+    #TODO: Put this in an eval  
+    $self->ExecModule =~ /^(\w+)$/;
+    my $module = $1;
+    my $type = "RT::Action::". $module;
+    eval "require $type" || die "Require of $type failed.\n$@\n";
+    
+    $self->{'Action'}  = $type->new ( 'ScripActionObj' => $self, 
+                                     'TicketObj' => $args{'TicketObj'},
+                                     'ScripObj' => $args{'ScripObj'},
+                                     'TransactionObj' => $args{'TransactionObj'},
+                                     'TemplateObj' => $self->TemplateObj,
+                                     'Argument' => $self->Argument,
+                                   );
+}
+# }}}
+
+# {{{ sub TemplateObj
+
+=head2 TemplateObj
+
+Return this action\'s template object
+
+=cut
+
+sub TemplateObj {
+    my $self = shift;
+    return undef unless $self->{Template};
+    if (!$self->{'TemplateObj'})  {
+       require RT::Template;
+       $self->{'TemplateObj'} = RT::Template->new($self->CurrentUser);
+       $self->{'TemplateObj'}->LoadById($self->{'Template'});
+       
+    }
+    
+    return ($self->{'TemplateObj'});
+}
+# }}}
+
+# The following methods call the action object
+
+# {{{ sub Prepare 
+
+sub Prepare  {
+    my $self = shift;
+    return ($self->{'Action'}->Prepare());
+  
+}
+# }}}
+
+# {{{ sub Commit 
+sub Commit  {
+    my $self = shift;
+    return($self->{'Action'}->Commit());
+    
+    
+}
+# }}}
+
+# {{{ sub Describe 
+sub Describe  {
+    my $self = shift;
+    return ($self->{'Action'}->Describe());
+    
+}
+# }}}
+
+# {{{ sub DESTROY
+sub DESTROY {
+    my $self=shift;
+    $self->{'Action'} = undef;
+    $self->{'TemplateObj'} = undef;
+}
+# }}}
+
+
+1;
+
+
index ec61415..614ff37 100755 (executable)
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/ScripActions.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-=head1 NAME
 
-  RT::ScripActions - Collection of Action objects
+=head1 NAME
 
+  RT::ScripActions -- Class Description
 =head1 SYNOPSIS
 
-  use RT::ScripActions;
-
+  use RT::ScripActions
 
 =head1 DESCRIPTION
 
 
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::ScripActions);
-
-=end testing
-
 =head1 METHODS
 
 =cut
 
 package RT::ScripActions;
-use RT::EasySearch;
+
+use RT::SearchBuilder;
 use RT::ScripAction;
 
-@ISA= qw(RT::EasySearch);
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
 
-# {{{ sub _Init
-sub _Init { 
-  my $self = shift;
-  $self->{'table'} = "ScripActions";
-  $self->{'primary_key'} = "id";
-  return ( $self->SUPER::_Init(@_));
-}
-# }}}
-
-# {{{ sub LimitToType 
-sub LimitToType  {
-  my $self = shift;
-  my $type = shift;
-  $self->Limit (ENTRYAGGREGATOR => 'OR',
-               FIELD => 'Type',
-               VALUE => "$type")
-      if defined $type;
-  $self->Limit (ENTRYAGGREGATOR => 'OR',
-               FIELD => 'Type',
-               VALUE => "Correspond")
-      if $type eq "Create";
-  $self->Limit (ENTRYAGGREGATOR => 'OR',
-               FIELD => 'Type',
-               VALUE => 'any');
-  
+
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'ScripActions';
+    $self->{'primary_key'} = 'id';
+
+
+    return ( $self->SUPER::_Init(@_) );
 }
-# }}}
 
-# {{{ sub NewItem 
-sub NewItem  {
-  my $self = shift;
-  return(RT::ScripAction->new($self->CurrentUser));
 
+=item NewItem
+
+Returns an empty new RT::ScripAction item
+
+=cut
+
+sub NewItem {
+    my $self = shift;
+    return(RT::ScripAction->new($self->CurrentUser));
 }
-# }}}
 
+        eval "require RT::ScripActions_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/ScripActions_Overlay.pm}) {
+            die $@;
+        };
 
-1;
+        eval "require RT::ScripActions_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/ScripActions_Vendor.pm}) {
+            die $@;
+        };
 
+        eval "require RT::ScripActions_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/ScripActions_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::ScripActions_Overlay, RT::ScripActions_Vendor, RT::ScripActions_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/ScripActions_Overlay.pm b/rt/lib/RT/ScripActions_Overlay.pm
new file mode 100644 (file)
index 0000000..83cd646
--- /dev/null
@@ -0,0 +1,87 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::ScripActions - Collection of Action objects
+
+=head1 SYNOPSIS
+
+  use RT::ScripActions;
+
+
+=head1 DESCRIPTION
+
+
+=begin testing
+
+ok (require RT::ScripActions);
+
+=end testing
+
+=head1 METHODS
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+# {{{ sub _Init
+sub _Init { 
+  my $self = shift;
+  $self->{'table'} = "ScripActions";
+  $self->{'primary_key'} = "id";
+  return ( $self->SUPER::_Init(@_));
+}
+# }}}
+
+# {{{ sub LimitToType 
+sub LimitToType  {
+  my $self = shift;
+  my $type = shift;
+  $self->Limit (ENTRYAGGREGATOR => 'OR',
+               FIELD => 'Type',
+               VALUE => "$type")
+      if defined $type;
+  $self->Limit (ENTRYAGGREGATOR => 'OR',
+               FIELD => 'Type',
+               VALUE => "Correspond")
+      if $type eq "Create";
+  $self->Limit (ENTRYAGGREGATOR => 'OR',
+               FIELD => 'Type',
+               VALUE => 'any');
+  
+}
+# }}}
+
+# {{{ sub NewItem 
+sub NewItem  {
+  my $self = shift;
+  return(RT::ScripAction->new($self->CurrentUser));
+
+}
+# }}}
+
+
+1;
+
index 253502b..fe0aa2d 100755 (executable)
-# Copyright 1999-2000 Jesse Vincent <jesse@fsck.com>
-# Released under the terms of the GNU Public License
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/ScripCondition.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
 
 =head1 NAME
 
-  RT::ScripCondition - RT scrip conditional
+RT::ScripCondition
+
 
 =head1 SYNOPSIS
 
-  use RT::ScripCondition;
+=head1 DESCRIPTION
 
+=head1 METHODS
 
-=head1 DESCRIPTION
+=cut
 
-This module should never be called directly by client code. it's an internal module which
-should only be accessed through exported APIs in other modules.
+package RT::ScripCondition;
+use RT::Record; 
 
 
-=begin testing
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
 
-ok (require RT::TestHarness);
-ok (require RT::ScripCondition);
+sub _Init {
+  my $self = shift; 
 
-=end testing
+  $self->Table('ScripConditions');
+  $self->SUPER::_Init(@_);
+}
 
-=head1 METHODS
+
+
+
+
+=item Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+  varchar(200) 'Name'.
+  varchar(255) 'Description'.
+  varchar(60) 'ExecModule'.
+  varchar(255) 'Argument'.
+  varchar(60) 'ApplicableTransTypes'.
 
 =cut
 
-package RT::ScripCondition;
-use RT::Record;
-@ISA= qw(RT::Record);
-
-# {{{  sub _Init 
-sub _Init  {
-    my $self = shift; 
-    $self->{'table'} = "ScripConditions";
-    return ($self->SUPER::_Init(@_));
-}
-# }}}
 
-# {{{ sub _Accessible 
-sub _Accessible  {
+
+
+sub Create {
     my $self = shift;
-    my %Cols = ( Name  => 'read',
-                Description => 'read',
-                ApplicableTransTypes    => 'read',
-                ExecModule  => 'read',
-                Argument  => 'read',
-                Creator => 'read/auto',
-                Created => 'read/auto',
-                LastUpdatedBy => 'read/auto',
-                LastUpdated => 'read/auto'
-              );
-    return($self->SUPER::_Accessible(@_, %Cols));
+    my %args = ( 
+                Name => '',
+                Description => '',
+                ExecModule => '',
+                Argument => '',
+                ApplicableTransTypes => '',
+
+                 @_);
+    $self->SUPER::Create(
+                         Name => $args{'Name'},
+                         Description => $args{'Description'},
+                         ExecModule => $args{'ExecModule'},
+                         Argument => $args{'Argument'},
+                         ApplicableTransTypes => $args{'ApplicableTransTypes'},
+);
+
 }
-# }}}
 
-# {{{ sub Create 
 
-=head2 Create
-  
-  Takes a hash. Creates a new Condition entry.
-  should be better documented.
+
+=item id
+
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
+
 
 =cut
 
-sub Create  {
-    my $self = shift;
-    return($self->SUPER::Create(@_));
-}
-# }}}
 
-# {{{ sub Delete 
+=item Name
 
-=head2 Delete
+Returns the current value of Name. 
+(In the database, Name is stored as varchar(200).)
+
+
+
+=item SetName VALUE
+
+
+Set Name to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Name will be stored as a varchar(200).)
 
-No API available for deleting things just yet.
 
 =cut
 
-sub Delete  {
-    my $self = shift;
-    return(0,'Unimplemented');
-}
-# }}}
 
-# {{{ sub Load 
+=item Description
 
-=head2 Load IDENTIFIER
+Returns the current value of Description. 
+(In the database, Description is stored as varchar(255).)
+
+
+
+=item SetDescription VALUE
+
+
+Set Description to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Description will be stored as a varchar(255).)
 
-Loads a condition takes a name or ScripCondition id.
 
 =cut
 
-sub Load  {
-    my $self = shift;
-    my $identifier = shift;
-    
-    unless (defined $identifier) {
-       return (undef);
-    }      
-    
-    if ($identifier !~ /\D/) {
-       return ($self->SUPER::LoadById($identifier));
-    }
-    else {
-       return ($self->LoadByCol('Name', $identifier));
-    }
-}
-# }}}
 
-# {{{ sub LoadCondition 
+=item ExecModule
+
+Returns the current value of ExecModule. 
+(In the database, ExecModule is stored as varchar(60).)
+
+
+
+=item SetExecModule VALUE
+
 
-=head2 LoadCondition  HASH
+Set ExecModule to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ExecModule will be stored as a varchar(60).)
 
-takes a hash which has the following elements:  TransactionObj and TicketObj.
-Loads the Condition module in question.
 
 =cut
 
 
-sub LoadCondition  {
-    my $self = shift;
-    my %args = ( TransactionObj => undef,
-                TicketObj => undef,
-                @_ );
-    
-    #TODO: Put this in an eval  
-    $self->ExecModule =~ /^(\w+)$/;
-    my $module = $1;
-    my $type = "RT::Condition::". $module;
-    
-    $RT::Logger->debug("now requiring $type\n"); 
-    eval "require $type" || die "Require of $type failed.\n$@\n";
-    
-    $self->{'Condition'}  = $type->new ( 'ScripConditionObj' => $self, 
-                                        'TicketObj' => $args{'TicketObj'},
-                                        'TransactionObj' => $args{'TransactionObj'},
-                                        'Argument' => $self->Argument,
-                                        'ApplicableTransTypes' => $self->ApplicableTransTypes,
-                                      );
-}
-# }}}
+=item Argument
+
+Returns the current value of Argument. 
+(In the database, Argument is stored as varchar(255).)
 
-# {{{ The following methods call the Condition object
 
 
-# {{{ sub Describe 
+=item SetArgument VALUE
 
-=head2 Describe 
 
-Helper method to call the condition module\'s Describe method.
+Set Argument to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Argument will be stored as a varchar(255).)
+
 
 =cut
 
-sub Describe  {
-    my $self = shift;
-    return ($self->{'Condition'}->Describe());
-    
-}
-# }}}
 
-# {{{ sub IsApplicable 
+=item ApplicableTransTypes
 
-=head2 IsApplicable
+Returns the current value of ApplicableTransTypes. 
+(In the database, ApplicableTransTypes is stored as varchar(60).)
+
+
+
+=item SetApplicableTransTypes VALUE
+
+
+Set ApplicableTransTypes to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ApplicableTransTypes will be stored as a varchar(60).)
 
-Helper method to call the condition module\'s IsApplicable method.
 
 =cut
 
-sub IsApplicable  {
-    my $self = shift;
-    return ($self->{'Condition'}->IsApplicable());
-    
-}
-# }}}
 
-# }}}
+=item Creator
 
-# {{{ sub DESTROY
-sub DESTROY {
-    my $self=shift;
-    $self->{'Condition'} = undef;
-}
-# }}}
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
 
 
-1;
+=cut
+
+
+=item Created
+
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
+
+
+=cut
+
+
+=item LastUpdatedBy
+
+Returns the current value of LastUpdatedBy. 
+(In the database, LastUpdatedBy is stored as int(11).)
+
+
+=cut
+
+
+=item LastUpdated
+
+Returns the current value of LastUpdated. 
+(In the database, LastUpdated is stored as datetime.)
 
 
+=cut
+
+
+
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        Name => 
+               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        Description => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        ExecModule => 
+               {read => 1, write => 1, type => 'varchar(60)', default => ''},
+        Argument => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        ApplicableTransTypes => 
+               {read => 1, write => 1, type => 'varchar(60)', default => ''},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        LastUpdatedBy => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        LastUpdated => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+
+ }
+};
+
+
+        eval "require RT::ScripCondition_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/ScripCondition_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::ScripCondition_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/ScripCondition_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::ScripCondition_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/ScripCondition_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::ScripCondition_Overlay, RT::ScripCondition_Vendor, RT::ScripCondition_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/ScripCondition_Overlay.pm b/rt/lib/RT/ScripCondition_Overlay.pm
new file mode 100644 (file)
index 0000000..158bc57
--- /dev/null
@@ -0,0 +1,210 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::ScripCondition - RT scrip conditional
+
+=head1 SYNOPSIS
+
+  use RT::ScripCondition;
+
+
+=head1 DESCRIPTION
+
+This module should never be called directly by client code. it's an internal module which
+should only be accessed through exported APIs in other modules.
+
+
+=begin testing
+
+ok (require RT::ScripCondition);
+
+=end testing
+
+=head1 METHODS
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+
+# {{{  sub _Init 
+sub _Init  {
+    my $self = shift; 
+    $self->{'table'} = "ScripConditions";
+    return ($self->SUPER::_Init(@_));
+}
+# }}}
+
+# {{{ sub _Accessible 
+sub _Accessible  {
+    my $self = shift;
+    my %Cols = ( Name  => 'read',
+                Description => 'read',
+                ApplicableTransTypes    => 'read',
+                ExecModule  => 'read',
+                Argument  => 'read',
+                Creator => 'read/auto',
+                Created => 'read/auto',
+                LastUpdatedBy => 'read/auto',
+                LastUpdated => 'read/auto'
+              );
+    return($self->SUPER::_Accessible(@_, %Cols));
+}
+# }}}
+
+# {{{ sub Create 
+
+=head2 Create
+  
+  Takes a hash. Creates a new Condition entry.
+  should be better documented.
+
+=cut
+
+sub Create  {
+    my $self = shift;
+    return($self->SUPER::Create(@_));
+}
+# }}}
+
+# {{{ sub Delete 
+
+=head2 Delete
+
+No API available for deleting things just yet.
+
+=cut
+
+sub Delete  {
+    my $self = shift;
+    return(0, $self->loc('Unimplemented'));
+}
+# }}}
+
+# {{{ sub Load 
+
+=head2 Load IDENTIFIER
+
+Loads a condition takes a name or ScripCondition id.
+
+=cut
+
+sub Load  {
+    my $self = shift;
+    my $identifier = shift;
+    
+    unless (defined $identifier) {
+       return (undef);
+    }      
+    
+    if ($identifier !~ /\D/) {
+       return ($self->SUPER::LoadById($identifier));
+    }
+    else {
+       return ($self->LoadByCol('Name', $identifier));
+    }
+}
+# }}}
+
+# {{{ sub LoadCondition 
+
+=head2 LoadCondition  HASH
+
+takes a hash which has the following elements:  TransactionObj and TicketObj.
+Loads the Condition module in question.
+
+=cut
+
+
+sub LoadCondition  {
+    my $self = shift;
+    my %args = ( TransactionObj => undef,
+                TicketObj => undef,
+                @_ );
+    
+    #TODO: Put this in an eval  
+    $self->ExecModule =~ /^(\w+)$/;
+    my $module = $1;
+    my $type = "RT::Condition::". $module;
+    
+    eval "require $type" || die "Require of $type failed.\n$@\n";
+    
+    $self->{'Condition'}  = $type->new ( 'ScripConditionObj' => $self, 
+                                        'TicketObj' => $args{'TicketObj'},
+                                        'ScripObj' => $args{'ScripObj'},
+                                        'TransactionObj' => $args{'TransactionObj'},
+                                        'Argument' => $self->Argument,
+                                        'ApplicableTransTypes' => $self->ApplicableTransTypes,
+                                      );
+}
+# }}}
+
+# {{{ The following methods call the Condition object
+
+
+# {{{ sub Describe 
+
+=head2 Describe 
+
+Helper method to call the condition module\'s Describe method.
+
+=cut
+
+sub Describe  {
+    my $self = shift;
+    return ($self->{'Condition'}->Describe());
+    
+}
+# }}}
+
+# {{{ sub IsApplicable 
+
+=head2 IsApplicable
+
+Helper method to call the condition module\'s IsApplicable method.
+
+=cut
+
+sub IsApplicable  {
+    my $self = shift;
+    return ($self->{'Condition'}->IsApplicable());
+    
+}
+# }}}
+
+# }}}
+
+# {{{ sub DESTROY
+sub DESTROY {
+    my $self=shift;
+    $self->{'Condition'} = undef;
+}
+# }}}
+
+
+1;
+
+
index 236e671..34f788d 100755 (executable)
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/ScripConditions.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-=head1 NAME
 
-  RT::ScripConditions - Collection of Action objects
+=head1 NAME
 
+  RT::ScripConditions -- Class Description
 =head1 SYNOPSIS
 
-  use RT::ScripConditions;
-
+  use RT::ScripConditions
 
 =head1 DESCRIPTION
 
 
-
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::ScripConditions);
-
-=end testing
-
 =head1 METHODS
 
 =cut
 
 package RT::ScripConditions;
-use RT::EasySearch;
+
+use RT::SearchBuilder;
 use RT::ScripCondition;
-@ISA= qw(RT::EasySearch);
-
-# {{{ sub _Init
-sub _Init { 
-  my $self = shift;
-  $self->{'table'} = "ScripConditions";
-  $self->{'primary_key'} = "id";
-  return ( $self->SUPER::_Init(@_));
-}
-# }}}
-
-# {{{ sub LimitToType 
-sub LimitToType  {
-  my $self = shift;
-  my $type = shift;
-  $self->Limit (ENTRYAGGREGATOR => 'OR',
-               FIELD => 'Type',
-               VALUE => "$type")
-      if defined $type;
-  $self->Limit (ENTRYAGGREGATOR => 'OR',
-               FIELD => 'Type',
-               VALUE => "Correspond")
-      if $type eq "Create";
-  $self->Limit (ENTRYAGGREGATOR => 'OR',
-               FIELD => 'Type',
-               VALUE => 'any');
-  
+
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
+
+
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'ScripConditions';
+    $self->{'primary_key'} = 'id';
+
+
+    return ( $self->SUPER::_Init(@_) );
 }
-# }}}
 
-# {{{ sub NewItem 
-sub NewItem  {
-  my $self = shift;
-  return(RT::ScripCondition->new($self->CurrentUser));
+
+=item NewItem
+
+Returns an empty new RT::ScripCondition item
+
+=cut
+
+sub NewItem {
+    my $self = shift;
+    return(RT::ScripCondition->new($self->CurrentUser));
 }
-# }}}
 
+        eval "require RT::ScripConditions_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/ScripConditions_Overlay.pm}) {
+            die $@;
+        };
 
-1;
+        eval "require RT::ScripConditions_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/ScripConditions_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::ScripConditions_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/ScripConditions_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
 
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::ScripConditions_Overlay, RT::ScripConditions_Vendor, RT::ScripConditions_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/ScripConditions_Overlay.pm b/rt/lib/RT/ScripConditions_Overlay.pm
new file mode 100644 (file)
index 0000000..8bef908
--- /dev/null
@@ -0,0 +1,87 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::ScripConditions - Collection of Action objects
+
+=head1 SYNOPSIS
+
+  use RT::ScripConditions;
+
+
+=head1 DESCRIPTION
+
+
+
+=begin testing
+
+ok (require RT::ScripConditions);
+
+=end testing
+
+=head1 METHODS
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+# {{{ sub _Init
+sub _Init { 
+  my $self = shift;
+  $self->{'table'} = "ScripConditions";
+  $self->{'primary_key'} = "id";
+  return ( $self->SUPER::_Init(@_));
+}
+# }}}
+
+# {{{ sub LimitToType 
+sub LimitToType  {
+  my $self = shift;
+  my $type = shift;
+  $self->Limit (ENTRYAGGREGATOR => 'OR',
+               FIELD => 'Type',
+               VALUE => "$type")
+      if defined $type;
+  $self->Limit (ENTRYAGGREGATOR => 'OR',
+               FIELD => 'Type',
+               VALUE => "Correspond")
+      if $type eq "Create";
+  $self->Limit (ENTRYAGGREGATOR => 'OR',
+               FIELD => 'Type',
+               VALUE => 'any');
+  
+}
+# }}}
+
+# {{{ sub NewItem 
+sub NewItem  {
+  my $self = shift;
+  return(RT::ScripCondition->new($self->CurrentUser));
+}
+# }}}
+
+
+1;
+
diff --git a/rt/lib/RT/Scrip_Overlay.pm b/rt/lib/RT/Scrip_Overlay.pm
new file mode 100644 (file)
index 0000000..06462a9
--- /dev/null
@@ -0,0 +1,507 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Scrip - an RT Scrip object
+
+=head1 SYNOPSIS
+
+  use RT::Scrip;
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=begin testing
+
+ok (require RT::Scrip);
+
+
+my $q = RT::Queue->new($RT::SystemUser);
+$q->Create(Name => 'ScripTest');
+ok($q->Id, "Created a scriptest queue");
+
+my $s1 = RT::Scrip->new($RT::SystemUser);
+my ($val, $msg) =$s1->Create( Queue => $q->Id,
+             ScripAction => 'User Defined',
+             ScripCondition => 'User Defined',
+             CustomIsApplicableCode => 'if ($self->TicketObj->Subject =~ /fire/) { return (1);} else { return(0)}',
+             CustomPrepareCode => 'return 1',
+             CustomCommitCode => '$self->TicketObj->SetPriority("87");',
+             Template => 'Blank'
+    );
+ok($val,$msg);
+
+my $ticket = RT::Ticket->new($RT::SystemUser);
+my ($tv,$ttv,$tm) = $ticket->Create(Queue => $q->Id,
+                                    Subject => "hair on fire",
+                                    );
+ok($tv, $tm);
+
+ok ($ticket->Priority == '87', "Ticket priority is set right");
+
+
+my $ticket2 = RT::Ticket->new($RT::SystemUser);
+my ($t2v,$t2tv,$t2m) = $ticket2->Create(Queue => $q->Id,
+                                    Subject => "hair in water",
+                                    );
+ok($t2v, $t2m);
+
+ok ($ticket2->Priority != '87', "Ticket priority is set right");
+
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+
+# {{{ sub Create 
+
+=head2 Create
+
+Creates a new entry in the Scrips table. Takes a paramhash with:
+
+        Queue                  => 0,
+        Description            => undef,
+        Template               => undef,
+        ScripAction            => undef,
+        ScripCondition         => undef,
+        CustomPrepareCode      => undef,
+        CustomCommitCode       => undef,
+        CustomIsApplicableCode => undef,
+
+
+
+
+Returns (retval, msg);
+retval is 0 for failure or scrip id.  msg is a textual description of what happened.
+
+=cut
+
+sub Create {
+    my $self = shift;
+    my %args = (
+        Queue                  => 0,
+        Template               => 0, # name or id
+        ScripAction            => 0, # name or id
+        ScripCondition         => 0, # name or id
+        Stage                  => 'TransactionCreate',
+        Description            => undef,
+        CustomPrepareCode      => undef,
+        CustomCommitCode       => undef,
+        CustomIsApplicableCode => undef,
+
+        @_
+    );
+
+
+    if (! $args{'Queue'} ) {
+        unless ( $self->CurrentUser->HasRight( Object => $RT::System, Right => 'ModifyScrips') ) {
+            return ( 0, $self->loc('Permission Denied') );
+        }
+        $args{'Queue'} = 0;            # avoid undef sneaking in
+    }
+    else {
+        my $QueueObj = new RT::Queue( $self->CurrentUser );
+        $QueueObj->Load( $args{'Queue'} );
+        unless ( $QueueObj->id() ) {
+            return ( 0, $self->loc('Invalid queue') );
+        }
+        unless ( $QueueObj->CurrentUserHasRight('ModifyScrips') ) {
+            return ( 0, $self->loc('Permission Denied') );
+        }
+        $args{'Queue'} = $QueueObj->id();
+    }
+
+    #TODO +++ validate input 
+
+    require RT::ScripAction;
+    my $action = new RT::ScripAction( $self->CurrentUser );
+    $action->Load( $args{'ScripAction'} || '0' );
+    return ( 0, $self->loc( "Action [_1] not found", $args{'ScripAction'} ) )
+      unless $action->Id;
+
+    require RT::Template;
+    my $template = new RT::Template( $self->CurrentUser );
+    $template->Load( $args{'Template'}||'0' );
+    return ( 0, $self->loc('Template not found') ) unless $template->Id;
+
+    require RT::ScripCondition;
+    my $condition = new RT::ScripCondition( $self->CurrentUser );
+    $condition->Load( $args{'ScripCondition'}||'0' );
+
+    unless ( $condition->Id ) {
+        return ( 0, $self->loc('Condition not found') );
+    }
+
+    my ($id,$msg) = $self->SUPER::Create(
+        Queue                  => $args{'Queue'},
+        Template               => $template->Id,
+        ScripCondition         => $condition->id,
+        Stage                  => $args{'Stage'},
+        ScripAction            => $action->Id,
+        Description            => $args{'Description'},
+        CustomPrepareCode      => $args{'CustomPrepareCode'},
+        CustomCommitCode       => $args{'CustomCommitCode'},
+        CustomIsApplicableCode => $args{'CustomIsApplicableCode'},
+
+    );
+    if ($id) {
+        return ( $id, $self->loc('Scrip Created') );
+    }
+    else {
+        return($id,$msg);
+    }
+}
+
+# }}}
+
+# {{{ sub Delete
+
+=head2 Delete
+
+Delete this object
+
+=cut
+
+sub Delete {
+    my $self = shift;
+    
+    unless ($self->CurrentUserHasRight('ModifyScrips')) {
+       return (0, $self->loc('Permission Denied'));
+    }
+    
+    return ($self->SUPER::Delete(@_));
+}
+# }}}
+
+# {{{ sub QueueObj
+
+=head2 QueueObj
+
+Retuns an RT::Queue object with this Scrip\'s queue
+
+=cut
+
+sub QueueObj {
+    my $self = shift;
+    
+    if (!$self->{'QueueObj'})  {
+       require RT::Queue;
+       $self->{'QueueObj'} = RT::Queue->new($self->CurrentUser);
+       $self->{'QueueObj'}->Load($self->__Value('Queue'));
+    }
+    return ($self->{'QueueObj'});
+}
+
+# }}}
+
+# {{{ sub ActionObj
+
+
+=head2 ActionObj
+
+Retuns an RT::Action object with this Scrip\'s Action
+
+=cut
+
+sub ActionObj {
+    my $self = shift;
+    
+    unless (defined $self->{'ScripActionObj'})  {
+       require RT::ScripAction;
+       
+       $self->{'ScripActionObj'} = RT::ScripAction->new($self->CurrentUser);
+       #TODO: why are we loading Actions with templates like this. 
+       # two seperate methods might make more sense
+       $self->{'ScripActionObj'}->Load($self->ScripAction, $self->Template);
+    }
+    return ($self->{'ScripActionObj'});
+}
+
+# }}}
+
+# {{{ sub ConditionObj
+
+=head2 ConditionObj
+
+Retuns an RT::ScripCondition object with this Scrip's IsApplicable
+
+=cut
+
+sub ConditionObj {
+    my $self = shift;
+    
+    unless (defined $self->{'ScripConditionObj'})  {
+       require RT::ScripCondition;
+       $self->{'ScripConditionObj'} = RT::ScripCondition->new($self->CurrentUser);
+       $self->{'ScripConditionObj'}->Load($self->ScripCondition);
+    }
+    return ($self->{'ScripConditionObj'});
+}
+
+# }}}
+
+# {{{ sub TemplateObj
+=head2 TemplateObj
+
+Retuns an RT::Template object with this Scrip\'s Template
+
+=cut
+
+sub TemplateObj {
+    my $self = shift;
+    
+    unless (defined $self->{'TemplateObj'})  {
+       require RT::Template;
+           $self->{'TemplateObj'} = RT::Template->new($self->CurrentUser);
+           $self->{'TemplateObj'}->Load($self->Template);
+    }
+    return ($self->{'TemplateObj'});
+}
+
+# }}}
+
+
+# {{{ Dealing with this instance of a scrip
+
+=head2 Apply { TicketObj => undef, TransactionObj => undef}
+
+This method instantiates the ScripCondition and ScripAction objects for a
+single execution of this scrip. it then calls the IsApplicable method of the 
+ScripCondition.
+If that succeeds, it calls the Prepare method of the
+ScripAction. If that succeeds, it calls the Commit method of the ScripAction.
+
+Usually, the ticket and transaction objects passed to this method
+should be loaded by the SuperUser role
+
+=cut
+
+
+# {{{ sub Apply
+
+sub Apply {
+    my $self = shift;
+    my %args = ( TicketObj      => undef,
+                 TransactionObj => undef,
+                 @_ );
+
+    # We want to make sure that if a scrip dies, we don't get
+    # hurt
+    eval {
+
+        #Load the scrip's Condition object
+        $self->ConditionObj->LoadCondition(
+                                      ScripObj       => $self,
+                                      TicketObj      => $args{'TicketObj'},
+                                      TransactionObj => $args{'TransactionObj'},
+        );
+
+        unless ( $self->IsApplicable() ) {
+            $self->ConditionObj->DESTROY;
+            return (undef);
+        }
+
+        #If it's applicable, prepare and commit it
+        $self->ActionObj->LoadAction( ScripObj       => $self,
+                                      TicketObj      => $args{'TicketObj'},
+                                      TransactionObj => $args{'TransactionObj'},
+        );
+
+        unless ( $self->Prepare() ) {
+            $RT::Logger->info(
+                          "$self: Couldn't prepare " . $self->ActionObj->Name );
+            $self->ActionObj->DESTROY();
+            $self->ConditionObj->DESTROY();
+            return (undef);
+        }
+        unless ( $self->Commit() ) {
+            $RT::Logger->info(
+                           "$self: Couldn't commit " . $self->ActionObj->Name );
+            $self->ActionObj->DESTROY();
+            $self->ConditionObj->DESTROY();
+            return (undef);
+        }
+
+        #Searchbuilder caching isn't perfectly coherent. got to reload the ticket object, since it
+        # may have changed
+        $args{'TicketObj'}->Load($args{'TicketObj'}->Id);
+
+        #We're done with it. lets clean up.
+        #TODO: something else isn't letting these get garbage collected. check em out.
+        $self->ActionObj->DESTROY();
+        $self->ConditionObj->DESTROY();
+        return (1);
+    };
+    if ($@) {
+        $RT::Logger->error( "Scrip " . $self->Id . " died. - " . $@ );
+    }
+
+}
+# }}}
+
+# {{{ sub IsApplicable
+
+=head2 IsApplicable
+
+Calls the  Condition object\'s IsApplicable method
+
+=cut
+
+sub IsApplicable {
+    my $self = shift;
+    return ($self->ConditionObj->IsApplicable(@_));
+}
+
+# }}}
+
+# {{{ sub Prepare
+
+=head2 Prepare
+
+Calls the action object's prepare method
+
+=cut
+
+sub Prepare {
+    my $self = shift;
+    $self->ActionObj->Prepare(@_);
+}
+
+# }}}
+
+# {{{ sub Commit
+
+=head2 Commit
+
+Calls the action object's commit method
+
+=cut
+
+sub Commit {
+    my $self = shift;
+    $self->ActionObj->Commit(@_);
+}
+
+# }}}
+
+# }}}
+
+# {{{ sub DESTROY
+sub DESTROY {
+    my $self = shift;
+    $self->{'ActionObj'} = undef;
+}
+# }}}
+
+# {{{ ACL related methods
+
+# {{{ sub _Set
+
+# does an acl check and then passes off the call
+sub _Set {
+    my $self = shift;
+    
+    unless ($self->CurrentUserHasRight('ModifyScrips')) {
+        $RT::Logger->debug("CurrentUser can't modify Scrips for ".$self->Queue."\n");
+       return (0, $self->loc('Permission Denied'));
+    }
+    return $self->__Set(@_);
+}
+
+# }}}
+
+# {{{ sub _Value
+# does an acl check and then passes off the call
+sub _Value {
+    my $self = shift;
+    
+    unless ($self->CurrentUserHasRight('ShowScrips')) {
+        $RT::Logger->debug("CurrentUser can't modify Scrips for ".$self->__Value('Queue')."\n");
+       return (undef);
+    }
+    
+    return $self->__Value(@_);
+}
+# }}}
+
+# {{{ sub CurrentUserHasRight
+
+=head2 CurrentUserHasRight
+
+Helper menthod for HasRight. Presets Principal to CurrentUser then 
+calls HasRight.
+
+=cut
+
+sub CurrentUserHasRight {
+    my $self = shift;
+    my $right = shift;
+    return ($self->HasRight( Principal => $self->CurrentUser->UserObj,
+                             Right => $right ));
+    
+}
+
+# }}}
+
+# {{{ sub HasRight
+
+=head2 HasRight
+
+Takes a param-hash consisting of "Right" and "Principal"  Principal is 
+an RT::User object or an RT::CurrentUser object. "Right" is a textual
+Right string that applies to Scrips.
+
+=cut
+
+sub HasRight {
+    my $self = shift;
+    my %args = ( Right => undef,
+                 Principal => undef,
+                 @_ );
+    
+    if ((defined $self->SUPER::_Value('Queue')) and ($self->SUPER::_Value('Queue') != 0)) {
+        return ( $args{'Principal'}->HasRight(
+                                                  Right => $args{'Right'},
+                                                  Object => $self->QueueObj
+                                                 ) 
+              );
+       
+    }
+    else {
+        return( $args{'Principal'}->HasRight( Object => $RT::System, Right =>  $args{'Right'}) );
+    }
+}
+# }}}
+
+# }}}
+
+1;
+
+
index 90be847..a394431 100755 (executable)
-# Copyright 1999-2001 Jesse Vincent <jesse@fsck.com>
-# Released under the terms of the GNU Public License
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Scrips.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-=head1 NAME
 
-  RT::Scrips - a collection of RT Scrip objects
+=head1 NAME
 
+  RT::Scrips -- Class Description
 =head1 SYNOPSIS
 
-  use RT::Scrips;
+  use RT::Scrips
 
 =head1 DESCRIPTION
 
 
 =head1 METHODS
 
+=cut
 
-=begin testing
+package RT::Scrips;
 
-ok (require RT::TestHarness);
-ok (require RT::Scrips);
+use RT::SearchBuilder;
+use RT::Scrip;
 
-=end testing
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
 
-=cut
 
-package RT::Scrips;
-use RT::EasySearch;
-use RT::Scrip;
-@ISA= qw(RT::EasySearch);
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'Scrips';
+    $self->{'primary_key'} = 'id';
 
 
-# {{{ sub _Init
-sub _Init { 
-  my $self = shift;
-  $self->{'table'} = "Scrips";
-  $self->{'primary_key'} = "id";
-  return ( $self->SUPER::_Init(@_));
+    return ( $self->SUPER::_Init(@_) );
 }
-# }}}
 
-# {{{ sub LimitToQueue 
 
-=head2 LimitToQueue
+=item NewItem
 
-Takes a queue id (numerical) as its only argument. Makes sure that 
-Scopes it pulls out apply to this queue (or another that you've selected with
-another call to this method
+Returns an empty new RT::Scrip item
 
 =cut
 
-sub LimitToQueue  {
-   my $self = shift;
-  my $queue = shift;
-  $self->Limit (ENTRYAGGREGATOR => 'OR',
-               FIELD => 'Queue',
-               VALUE => "$queue")
-      if defined $queue;
-  
+sub NewItem {
+    my $self = shift;
+    return(RT::Scrip->new($self->CurrentUser));
 }
-# }}}
 
-# {{{ sub LimitToGlobal
+        eval "require RT::Scrips_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Scrips_Overlay.pm}) {
+            die $@;
+        };
 
-=head2 LimitToGlobal
+        eval "require RT::Scrips_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Scrips_Vendor.pm}) {
+            die $@;
+        };
 
-Makes sure that 
-Scopes it pulls out apply to all queues (or another that you've selected with
-another call to this method or LimitToQueue
+        eval "require RT::Scrips_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Scrips_Local.pm}) {
+            die $@;
+        };
 
-=cut
 
 
-sub LimitToGlobal  {
-   my $self = shift;
-  $self->Limit (ENTRYAGGREGATOR => 'OR',
-               FIELD => 'Queue',
-               VALUE => 0);
-  
-}
-# }}}
 
-# {{{ sub NewItem 
-sub NewItem  {
-  my $self = shift;
-  
-  return(new RT::Scrip($self->CurrentUser));
-}
-# }}}
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
 
-# {{{ sub Next 
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
 
-=head2 Next
+   no warnings qw(redefine);
 
-Returns the next scrip that this user can see.
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::Scrips_Overlay, RT::Scrips_Vendor, RT::Scrips_Local
 
 =cut
-  
-sub Next {
-    my $self = shift;
-    
-    
-    my $Scrip = $self->SUPER::Next();
-    if ((defined($Scrip)) and (ref($Scrip))) {
-
-       if ($Scrip->CurrentUserHasRight('ShowScrips')) {
-           return($Scrip);
-       }
-       
-       #If the user doesn't have the right to show this scrip
-       else {  
-           return($self->Next());
-       }
-    }
-    #if there never was any scrip
-    else {
-       return(undef);
-    }  
-    
-}
-# }}}
 
-1;
 
+1;
diff --git a/rt/lib/RT/Scrips_Overlay.pm b/rt/lib/RT/Scrips_Overlay.pm
new file mode 100644 (file)
index 0000000..46e31c2
--- /dev/null
@@ -0,0 +1,133 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Scrips - a collection of RT Scrip objects
+
+=head1 SYNOPSIS
+
+  use RT::Scrips;
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::Scrips);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+# {{{ sub LimitToQueue 
+
+=head2 LimitToQueue
+
+Takes a queue id (numerical) as its only argument. Makes sure that 
+Scopes it pulls out apply to this queue (or another that you've selected with
+another call to this method
+
+=cut
+
+sub LimitToQueue  {
+   my $self = shift;
+  my $queue = shift;
+  $self->Limit (ENTRYAGGREGATOR => 'OR',
+               FIELD => 'Queue',
+               VALUE => "$queue")
+      if defined $queue;
+  
+}
+# }}}
+
+# {{{ sub LimitToGlobal
+
+=head2 LimitToGlobal
+
+Makes sure that 
+Scopes it pulls out apply to all queues (or another that you've selected with
+another call to this method or LimitToQueue
+
+=cut
+
+
+sub LimitToGlobal  {
+   my $self = shift;
+  $self->Limit (ENTRYAGGREGATOR => 'OR',
+               FIELD => 'Queue',
+               VALUE => 0);
+  
+}
+# }}}
+
+# {{{ sub NewItem 
+sub NewItem  {
+  my $self = shift;
+  
+  return(new RT::Scrip($self->CurrentUser));
+}
+# }}}
+
+# {{{ sub Next 
+
+=head2 Next
+
+Returns the next scrip that this user can see.
+
+=cut
+  
+sub Next {
+    my $self = shift;
+    
+    
+    my $Scrip = $self->SUPER::Next();
+    if ((defined($Scrip)) and (ref($Scrip))) {
+
+       if ($Scrip->CurrentUserHasRight('ShowScrips')) {
+           return($Scrip);
+       }
+       
+       #If the user doesn't have the right to show this scrip
+       else {  
+           return($self->Next());
+       }
+    }
+    #if there never was any scrip
+    else {
+       return(undef);
+    }  
+    
+}
+# }}}
+
+1;
+
diff --git a/rt/lib/RT/Search/ActiveTicketsInQueue.pm b/rt/lib/RT/Search/ActiveTicketsInQueue.pm
new file mode 100644 (file)
index 0000000..766e42e
--- /dev/null
@@ -0,0 +1,78 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Search::ActiveTicketsInQueue
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+Find all active tickets in the queue named in the argument passed in
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::Search::Generic);
+
+=end testing
+
+
+=cut
+
+package RT::Search::ActiveTicketsInQueue;
+
+use strict;
+use base qw(RT::Search::Generic);
+
+
+# {{{ sub Describe 
+sub Describe  {
+  my $self = shift;
+  return ($self->loc("No description for [_1]", ref $self));
+}
+# }}}
+
+# {{{ sub Prepare
+sub Prepare  {
+  my $self = shift;
+
+  $self->TicketsObj->LimitQueue(VALUE => $self->Argument);
+
+  foreach my $status (RT::Queue->ActiveStatusArray()) {
+        $self->TicketsObj->LimitStatus(VALUE => $status);
+  }
+
+  return(1);
+}
+# }}}
+
+eval "require RT::Search::ActiveTicketsInQueue_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Search/ActiveTicketsInQueue_Vendor.pm});
+eval "require RT::Search::ActiveTicketsInQueue_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Search/ActiveTicketsInQueue_Local.pm});
+
+1;
diff --git a/rt/lib/RT/Search/Generic.pm b/rt/lib/RT/Search/Generic.pm
new file mode 100644 (file)
index 0000000..f872c2a
--- /dev/null
@@ -0,0 +1,128 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Search::Generic - ;
+
+=head1 SYNOPSIS
+
+    use RT::Search::Generic;
+    my $tickets = RT::Tickets->new($CurrentUser);
+    my $foo = RT::Search::Generic->new(Argument => $arg,
+                                       TicketsObj => $tickets);
+    $foo->Prepare();
+    while ( my $ticket = $foo->Next ) {
+        # Do something with each ticket we've found
+    }
+
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::Search::Generic);
+
+=end testing
+
+
+=cut
+
+package RT::Search::Generic;
+
+use strict;
+
+# {{{ sub new 
+sub new  {
+  my $proto = shift;
+  my $class = ref($proto) || $proto;
+  my $self  = {};
+  bless ($self, $class);
+  $self->_Init(@_);
+  return $self;
+}
+# }}}
+
+# {{{ sub _Init 
+sub _Init  {
+  my $self = shift;
+  my %args = ( 
+           TicketsObj => undef,
+              Argument => undef,
+              @_ );
+  
+  $self->{'TicketsObj'} = $args{'TicketsObj'}; 
+  $self->{'Argument'} = $args{'Argument'};
+}
+# }}}
+
+# {{{ sub Argument 
+
+=head2 Argument
+
+Return the optional argument associated with this Search
+
+=cut
+
+sub Argument  {
+  my $self = shift;
+  return($self->{'Argument'});
+}
+# }}}
+
+
+=head2 TicketsObj 
+
+Return the Tickets object passed into this search
+
+=cut
+
+sub TicketsObj {
+    my $self = shift;
+    return($self->{'TicketsObj'});
+}
+
+# {{{ sub Describe 
+sub Describe  {
+  my $self = shift;
+  return ($self->loc("No description for [_1]", ref $self));
+}
+# }}}
+
+# {{{ sub Prepare
+sub Prepare  {
+  my $self = shift;
+  return(1);
+}
+# }}}
+
+eval "require RT::Search::Generic_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Search/Generic_Vendor.pm});
+eval "require RT::Search::Generic_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Search/Generic_Local.pm});
+
+1;
diff --git a/rt/lib/RT/SearchBuilder.pm b/rt/lib/RT/SearchBuilder.pm
new file mode 100644 (file)
index 0000000..22c9aff
--- /dev/null
@@ -0,0 +1,200 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::SearchBuilder - a baseclass for RT collection objects
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::SearchBuilder);
+
+=end testing
+
+
+=cut
+
+package RT::SearchBuilder;
+
+use RT::Base;
+use DBIx::SearchBuilder;
+
+use strict;
+use vars qw(@ISA);
+@ISA = qw(DBIx::SearchBuilder RT::Base);
+
+# {{{ sub _Init 
+sub _Init  {
+    my $self = shift;
+    
+    $self->{'user'} = shift;
+    unless(defined($self->CurrentUser)) {
+       use Carp;
+       Carp::confess("$self was created without a CurrentUser");
+       $RT::Logger->err("$self was created without a CurrentUser");
+       return(0);
+    }
+    $self->SUPER::_Init( 'Handle' => $RT::Handle);
+}
+# }}}
+
+# {{{ sub LimitToEnabled
+
+=head2 LimitToEnabled
+
+Only find items that haven\'t been disabled
+
+=cut
+
+sub LimitToEnabled {
+    my $self = shift;
+    
+    $self->Limit( FIELD => 'Disabled',
+                 VALUE => '0',
+                 OPERATOR => '=' );
+}
+# }}}
+
+# {{{ sub LimitToDisabled
+
+=head2 LimitToDeleted
+
+Only find items that have been deleted.
+
+=cut
+
+sub LimitToDeleted {
+    my $self = shift;
+    
+    $self->{'find_disabled_rows'} = 1;
+    $self->Limit( FIELD => 'Disabled',
+                 OPERATOR => '=',
+                 VALUE => '1'
+               );
+}
+# }}}
+
+# {{{ sub FindAllRows
+
+=head2 FindAllRows
+
+Find all matching rows, regardless of whether they are disabled or not
+
+=cut
+
+sub FindAllRows {
+  shift->{'find_disabled_rows'} = 1;
+}
+
+# {{{ sub Limit 
+
+=head2 Limit PARAMHASH
+
+This Limit sub calls SUPER::Limit, but defaults "CASESENSITIVE" to 1, thus
+making sure that by default lots of things don't do extra work trying to 
+match lower(colname) agaist lc($val);
+
+=cut
+
+sub Limit {
+       my $self = shift;
+       my %args = ( CASESENSITIVE => 1,
+                    @_ );
+
+   return $self->SUPER::Limit(%args);
+}
+
+# }}}
+
+# {{{ sub ItemsArrayRef
+
+=item ItemsArrayRef
+
+Return this object's ItemsArray.
+If it has a SortOrder attribute, sort the array by SortOrder.
+Otherwise, if it has a "Name" attribute, sort alphabetically by Name
+Otherwise, just give up and return it in the order it came from the db.
+
+
+=begin testing
+
+use_ok(RT::Queues);
+ok(my $queues = RT::Queues->new($RT::SystemUser), 'Created a queues object');
+ok( $queues->UnLimit(),'Unlimited the result set of the queues object');
+my $items = $queues->ItemsArrayRef();
+my @items = @{$items};
+
+ok($queues->NewItem->_Accessible('Name','read'));
+my @sorted = sort {lc($a->Name) cmp lc($b->Name)} @items;
+ok (@sorted, "We have an array of queues, sorted". join(',',map {$_->Name} @sorted));
+
+ok (@items, "We have an array of queues, raw". join(',',map {$_->Name} @items));
+my @sorted_ids = map {$_->id } @sorted;
+my @items_ids = map {$_->id } @items;
+
+is ($#sorted, $#items);
+is ($sorted[0]->Name, $items[0]->Name);
+is ($sorted[-1]->Name, $items[-1]->Name);
+is_deeply(\@items_ids, \@sorted_ids, "ItemsArrayRef sorts alphabetically by name");;
+
+
+=end testing
+
+=cut
+
+sub ItemsArrayRef {
+    my $self = shift;
+    my @items;
+    
+    if ($self->NewItem()->_Accessible('SortOrder','read')) {
+        @items = sort { $a->SortOrder <=> $b->SortOrder } @{$self->SUPER::ItemsArrayRef()};
+    }
+    elsif ($self->NewItem()->_Accessible('Name','read')) {
+        @items = sort { lc($a->Name) cmp lc($b->Name) } @{$self->SUPER::ItemsArrayRef()};
+    }
+    else {
+        @items = @{$self->SUPER::ItemsArrayRef()};
+    }
+
+    return(\@items);
+
+}
+
+# }}}
+
+eval "require RT::SearchBuilder_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/SearchBuilder_Vendor.pm});
+eval "require RT::SearchBuilder_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/SearchBuilder_Local.pm});
+
+1;
+
+
diff --git a/rt/lib/RT/System.pm b/rt/lib/RT/System.pm
new file mode 100644 (file)
index 0000000..bfa5a4e
--- /dev/null
@@ -0,0 +1,165 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME 
+
+RT::System
+
+=head1 DESCRIPTION
+
+RT::System is a simple global object used as a focal point for things
+that are system-wide.
+
+It works sort of like an RT::Record, except it's really a single object that has
+an id of "1" when instantiated.
+
+This gets used by the ACL system so that you can have rights for the scope "RT::System"
+
+In the future, there will probably be other API goodness encapsulated here.
+
+=cut
+
+
+package RT::System;
+use base qw /RT::Base/;
+use strict;
+
+use RT::ACL;
+use vars qw/ $RIGHTS/;
+
+# System rights are rights granted to the whole system
+# XXX TODO Can't localize these outside of having an object around.
+$RIGHTS = {
+    SuperUser              => 'Do anything and everything',           # loc_pair
+    AdminAllPersonalGroups =>
+      "Create, delete and modify the members of any user's personal groups"
+    ,                                                                 # loc_pair
+    AdminOwnPersonalGroups =>
+      'Create, delete and modify the members of personal groups',     # loc_pair
+    AdminUsers     => 'Create, delete and modify users',              # loc_pair
+    ModifySelf     => "Modify one's own RT account",                  # loc_pair
+    DelegateRights =>
+      "Delegate specific rights which have been granted to you."      # loc_pair
+};
+
+# Tell RT::ACE that this sort of object can get acls granted
+$RT::ACE::OBJECT_TYPES{'RT::System'} = 1;
+
+foreach my $right ( keys %{$RIGHTS} ) {
+    $RT::ACE::LOWERCASERIGHTNAMES{ lc $right } = $right;
+}
+
+
+=head2 AvailableRights
+
+Returns a hash of available rights for this object. The keys are the right names and the values are a description of what the rights do
+
+=begin testing
+
+my $s = RT::System->new($RT::SystemUser);
+my $rights = $s->AvailableRights;
+ok ($rights, "Rights defined");
+ok ($rights->{'AdminUsers'},"AdminUsers right found");
+ok ($rights->{'CreateTicket'},"CreateTicket right found");
+ok ($rights->{'AdminGroupMembership'},"ModifyGroupMembers right found");
+ok (!$rights->{'CasdasdsreateTicket'},"bogus right not found");
+
+
+
+=end testing
+
+
+=cut
+
+sub AvailableRights {
+    my $self = shift;
+
+    my $queue = RT::Queue->new($RT::SystemUser);
+    my $group = RT::Group->new($RT::SystemUser);
+
+    my $qr =$queue->AvailableRights();
+    my $gr = $group->AvailableRights();
+
+    # Build a merged list of all system wide rights, queue rights and group rights.
+    my %rights = (%{$RIGHTS}, %{$gr}, %{$qr});
+    return(\%rights);
+}
+
+
+=head2 new
+
+Create a new RT::System object. Really, you should be using $RT::System
+
+=cut
+
+                         
+sub new {
+    my $proto = shift;
+    my $class = ref($proto) || $proto;
+    my $self  = {};
+    bless( $self, $class );
+
+
+    return ($self);
+}
+
+=head2 id
+
+Returns RT::System's id. It's 1. 
+
+
+=begin testing
+
+use RT::System;
+my $sys = RT::System->new();
+is( $sys->Id, 1);
+is ($sys->id, 1);
+
+=end testing
+
+
+=cut
+
+*Id = \&id;
+
+sub id {
+    return (1);
+}
+
+=head2 Load
+
+Since this object is pretending to be an RT::Record, we need a load method.
+It does nothing
+
+=cut
+
+sub Load {
+       return (1);
+}
+
+eval "require RT::System_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/System_Vendor.pm});
+eval "require RT::System_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/System_Local.pm});
+
+1;
index 3ef96c7..f73ea3e 100755 (executable)
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Template.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# Copyright 1996-2002 Jesse Vincent <jesse@bestpractical.com>
-# Portions Copyright 2000 Tobias Brox <tobix@cpan.org> 
-# Released under the terms of the GNU General Public License
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
 
 =head1 NAME
 
-  RT::Template - RT's template object
+RT::Template
+
 
 =head1 SYNOPSIS
 
-  use RT::Template;
+=head1 DESCRIPTION
 
+=head1 METHODS
 
-=head1 DESCRIPTION
+=cut
 
+package RT::Template;
+use RT::Record; 
+use RT::Queue;
 
-=head1 METHODS
 
-=begin testing
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
+
+sub _Init {
+  my $self = shift; 
+
+  $self->Table('Templates');
+  $self->SUPER::_Init(@_);
+}
+
+
+
+
+
+=item Create PARAMHASH
 
-ok(require RT::TestHarness);
-ok(require RT::Template);
+Create takes a hash of values and creates a row in the database:
 
-=end testing
+  int(11) 'Queue'.
+  varchar(200) 'Name'.
+  varchar(255) 'Description'.
+  varchar(16) 'Type'.
+  varchar(16) 'Language'.
+  int(11) 'TranslationOf'.
+  blob 'Content'.
 
 =cut
 
-package RT::Template;
-use RT::Record;
-use MIME::Entity;
-use MIME::Parser;
 
-@ISA = qw(RT::Record);
 
-# {{{ sub _Init
 
-sub _Init {
+sub Create {
     my $self = shift;
-    $self->{'table'} = "Templates";
-    return ( $self->SUPER::_Init(@_) );
+    my %args = ( 
+                Queue => '0',
+                Name => '',
+                Description => '',
+                Type => '',
+                Language => '',
+                TranslationOf => '0',
+                Content => '',
+
+                 @_);
+    $self->SUPER::Create(
+                         Queue => $args{'Queue'},
+                         Name => $args{'Name'},
+                         Description => $args{'Description'},
+                         Type => $args{'Type'},
+                         Language => $args{'Language'},
+                         TranslationOf => $args{'TranslationOf'},
+                         Content => $args{'Content'},
+);
+
 }
 
-# }}}
 
-# {{{ sub _Accessible 
 
-sub _Accessible {
-    my $self = shift;
-    my %Cols = (
-        id            => 'read',
-        Name          => 'read/write',
-        Description   => 'read/write',
-        Type          => 'read/write',    #Type is one of Action or Message
-        Content       => 'read/write',
-        Queue         => 'read/write',
-        Creator       => 'read/auto',
-        Created       => 'read/auto',
-        LastUpdatedBy => 'read/auto',
-        LastUpdated   => 'read/auto'
-    );
-    return $self->SUPER::_Accessible( @_, %Cols );
-}
+=item id
 
-# }}}
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
 
-# {{{ sub _Set
 
-sub _Set {
-    my $self = shift;
+=cut
 
-    # use super::value or we get acl blocked
-    if ( ( defined $self->SUPER::_Value('Queue') )
-        && ( $self->SUPER::_Value('Queue') == 0 ) )
-    {
-        unless ( $self->CurrentUser->HasSystemRight('ModifyTemplate') ) {
-            return ( 0, 'Permission Denied' );
-        }
-    }
-    else {
-
-        unless ( $self->CurrentUserHasQueueRight('ModifyTemplate') ) {
-            return ( 0, 'Permission Denied' );
-        }
-    }
-    return ( $self->SUPER::_Set(@_) );
 
-}
+=item Queue
+
+Returns the current value of Queue. 
+(In the database, Queue is stored as int(11).)
 
-# }}}
 
-# {{{ sub _Value 
 
-=head2 _Value
+=item SetQueue VALUE
+
+
+Set Queue to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Queue will be stored as a int(11).)
 
-Takes the name of a table column.
-Returns its value as a string, if the user passes an ACL check
 
 =cut
 
-sub _Value {
 
-    my $self  = shift;
-    my $field = shift;
+=item QueueObj
 
-    #If the current user doesn't have ACLs, don't let em at it.  
-    #use super::value or we get acl blocked
-    if ( ( !defined $self->__Value('Queue') )
-        || ( $self->__Value('Queue') == 0 ) )
-    {
-        unless ( $self->CurrentUser->HasSystemRight('ShowTemplate') ) {
-            return (undef);
-        }
-    }
-    else {
-        unless ( $self->CurrentUserHasQueueRight('ShowTemplate') ) {
-            return (undef);
-        }
-    }
-    return ( $self->__Value($field) );
+Returns the Queue Object which has the id returned by Queue
 
+
+=cut
+
+sub QueueObj {
+       my $self = shift;
+       my $Queue =  RT::Queue->new($self->CurrentUser);
+       $Queue->Load($self->__Value('Queue'));
+       return($Queue);
 }
 
-# }}}
+=item Name
+
+Returns the current value of Name. 
+(In the database, Name is stored as varchar(200).)
+
+
 
-# {{{ sub Load
+=item SetName VALUE
 
-=head2 Load <identifer>
 
-Load a template, either by number or by name
+Set Name to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Name will be stored as a varchar(200).)
+
 
 =cut
 
-sub Load {
-    my $self       = shift;
-    my $identifier = shift;
 
-    if ( !$identifier ) {
-        return (undef);
-    }
+=item Description
+
+Returns the current value of Description. 
+(In the database, Description is stored as varchar(255).)
 
-    if ( $identifier !~ /\D/ ) {
-        $self->SUPER::LoadById($identifier);
-    }
-    else {
-        $self->LoadByCol( 'Name', $identifier );
 
-    }
-}
 
-# }}}
+=item SetDescription VALUE
 
-# {{{ sub LoadGlobalTemplate
 
-=head2 LoadGlobalTemplate NAME
+Set Description to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Description will be stored as a varchar(255).)
 
-Load the global tempalte with the name NAME
 
 =cut
 
-sub LoadGlobalTemplate {
-    my $self = shift;
-    my $id   = shift;
 
-    return ( $self->LoadQueueTemplate( Queue => 0, Name => $id ) );
-}
+=item Type
 
-# }}}
+Returns the current value of Type. 
+(In the database, Type is stored as varchar(16).)
 
-# {{{ sub LoadQueueTemplate
 
-=head2  LoadQueueTemplate (Queue => QUEUEID, Name => NAME)
 
-Loads the Queue template named NAME for Queue QUEUE.
+=item SetType VALUE
+
+
+Set Type to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Type will be stored as a varchar(16).)
+
 
 =cut
 
-sub LoadQueueTemplate {
-    my $self = shift;
-    my %args = (
-        Queue => undef,
-        Name  => undef
-    );
 
-    return ( $self->LoadByCols( Name => $args{'Name'}, Queue => {'Queue'} ) );
+=item Language
 
-}
+Returns the current value of Language. 
+(In the database, Language is stored as varchar(16).)
 
-# }}}
 
-# {{{ sub Create
 
-=head2 Create
+=item SetLanguage VALUE
 
-Takes a paramhash of Content, Queue, Name and Description.
-Name should be a unique string identifying this Template.
-Description and Content should be the template's title and content.
-Queue should be 0 for a global template and the queue # for a queue-specific 
-template.
 
-Returns the Template's id # if the create was successful. Returns undef for
-unknown database failure.
+Set Language to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Language will be stored as a varchar(16).)
 
 
 =cut
 
-sub Create {
-    my $self = shift;
-    my %args = (
-        Content     => undef,
-        Queue       => 0,
-        Description => '[no description]',
-        Type => 'Action',    #By default, template are 'Action' templates
-        Name => undef,
-        @_
-    );
-
-    if ( $args{'Queue'} == 0 ) {
-        unless ( $self->CurrentUser->HasSystemRight('ModifyTemplate') ) {
-            return (undef);
-        }
-    }
-    else {
-        my $QueueObj = new RT::Queue( $self->CurrentUser );
-        $QueueObj->Load( $args{'Queue'} ) || return ( 0, 'Invalid queue' );
-
-        unless ( $QueueObj->CurrentUserHasRight('ModifyTemplate') ) {
-            return (undef);
-        }
-    }
-
-    my $result = $self->SUPER::Create(
-        Content => $args{'Content'},
-        Queue   => $args{'Queue'},
-        ,
-        Description => $args{'Description'},
-        Name        => $args{'Name'}
-    );
-
-    return ($result);
 
-}
+=item TranslationOf
+
+Returns the current value of TranslationOf. 
+(In the database, TranslationOf is stored as int(11).)
+
+
 
-# }}}
+=item SetTranslationOf VALUE
 
-# {{{ sub Delete
 
-=head2 Delete
+Set TranslationOf to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, TranslationOf will be stored as a int(11).)
 
-Delete this template.
 
 =cut
 
-sub Delete {
-    my $self = shift;
 
-    unless ( $self->CurrentUserHasRight('ModifyTemplate') ) {
-        return ( 0, 'Permission Denied' );
-    }
+=item Content
 
-    return ( $self->SUPER::Delete(@_) );
-}
+Returns the current value of Content. 
+(In the database, Content is stored as blob.)
 
-# }}}
 
-# {{{ sub MIMEObj
-sub MIMEObj {
-    my $self = shift;
-    return ( $self->{'MIMEObj'} );
-}
 
-# }}}
+=item SetContent VALUE
 
-# {{{ sub Parse 
 
-=item Parse
+Set Content to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Content will be stored as a blob.)
 
- This routine performs Text::Template parsing on thte template and then imports the 
- results into a MIME::Entity so we can really use it
- It returns a tuple of (val, message)
- If val is 0, the message contains an error message
 
 =cut
 
-sub Parse {
-    my $self = shift;
 
-    #We're passing in whatever we were passed. it's destined for _ParseContent
-    my $content = $self->_ParseContent(@_);
+=item LastUpdated
 
-    #Lets build our mime Entity
+Returns the current value of LastUpdated. 
+(In the database, LastUpdated is stored as datetime.)
 
-    my $parser = MIME::Parser->new();
-    
-    # Do work on the parsed template in memory, rather than on disk
-    $parser->output_to_core(1); 
 
-    ### Should we forgive normally-fatal errors?
-    $parser->ignore_errors(1);
-    $self->{'MIMEObj'} = eval { $parser->parse_data($content) };
-    $error = ( $@ || $parser->last_error );
+=cut
 
-    if ($error) {
-        $RT::Logger->error("$error");
-        return ( 0, $error );
-    }
 
-    # Unfold all headers
-    $self->{'MIMEObj'}->head->unfold();
+=item LastUpdatedBy
 
-    return ( 1, "Template parsed" );
-   
+Returns the current value of LastUpdatedBy. 
+(In the database, LastUpdatedBy is stored as int(11).)
 
-}
 
-# }}}
+=cut
 
-# {{{ sub _ParseContent
 
-# Perform Template substitutions on the template
+=item Creator
 
-sub _ParseContent {
-    my $self = shift;
-    my %args = (
-        Argument       => undef,
-        TicketObj      => undef,
-        TransactionObj => undef,
-        @_
-    );
-
-    # Might be subject to change
-    use Text::Template;
-
-    $T::Ticket      = $args{'TicketObj'};
-    $T::Transaction = $args{'TransactionObj'};
-    $T::Argument    = $args{'Argument'};
-    $T::rtname      = $RT::rtname;
-
-    # We need to untaint the content of the template, since we'll be working
-    # with it
-    my $content = $self->Content();
-    $content =~ s/^(.*)$/$1/;
-    $template = Text::Template->new(
-        TYPE   => STRING,
-        SOURCE => $content
-    );
-
-    my $retval = $template->fill_in( PACKAGE => T );
-    return ($retval);
-}
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
 
-# }}}
 
-# {{{ sub QueueObj
+=cut
 
-=head2 QueueObj
 
-Takes nothing. returns this ticket's queue object
+=item Created
+
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
+
 
 =cut
 
-sub QueueObj {
-    my $self = shift;
-    if ( !defined $self->{'queue'} ) {
-        require RT::Queue;
-        $self->{'queue'} = RT::Queue->new( $self->CurrentUser );
-
-        unless ( $self->{'queue'} ) {
-            $RT::Logger->crit(
-                "RT::Queue->new(" . $self->CurrentUser . ") returned false" );
-            return (undef);
-        }
-        my ($result) = $self->{'queue'}->Load( $self->__Value('Queue') );
-
-    }
-    return ( $self->{'queue'} );
-}
 
-# }}}
 
-# {{{ sub CurrentUserHasQueueRight
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        Queue => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Name => 
+               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        Description => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        Type => 
+               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+        Language => 
+               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+        TranslationOf => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Content => 
+               {read => 1, write => 1, type => 'blob', default => ''},
+        LastUpdated => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        LastUpdatedBy => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+
+ }
+};
+
+
+        eval "require RT::Template_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Template_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Template_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Template_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Template_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Template_Local.pm}) {
+            die $@;
+        };
 
-=head2 CurrentUserHasQueueRight
 
-Helper function to call the template's queue's CurrentUserHasQueueRight with the passed in args.
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::Template_Overlay, RT::Template_Vendor, RT::Template_Local
 
 =cut
 
-sub CurrentUserHasQueueRight {
-    my $self = shift;
-    return ( $self->QueueObj->CurrentUserHasRight(@_) );
-}
 
-# }}}
 1;
diff --git a/rt/lib/RT/Template_Overlay.pm b/rt/lib/RT/Template_Overlay.pm
new file mode 100644 (file)
index 0000000..0b5e67d
--- /dev/null
@@ -0,0 +1,411 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Portions Copyright 2000 Tobias Brox <tobix@cpan.org> 
+
+=head1 NAME
+
+  RT::Template - RT's template object
+
+=head1 SYNOPSIS
+
+  use RT::Template;
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=begin testing
+
+ok(require RT::Template);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+use Text::Template;
+use MIME::Entity;
+use MIME::Parser;
+use File::Temp qw /tempdir/;
+
+
+# {{{ sub _Accessible 
+
+sub _Accessible {
+    my $self = shift;
+    my %Cols = (
+        id            => 'read',
+        Name          => 'read/write',
+        Description   => 'read/write',
+        Type          => 'read/write',    #Type is one of Action or Message
+        Content       => 'read/write',
+        Queue         => 'read/write',
+        Creator       => 'read/auto',
+        Created       => 'read/auto',
+        LastUpdatedBy => 'read/auto',
+        LastUpdated   => 'read/auto'
+    );
+    return $self->SUPER::_Accessible( @_, %Cols );
+}
+
+# }}}
+
+# {{{ sub _Set
+
+sub _Set {
+    my $self = shift;
+
+    # use super::value or we get acl blocked
+    if ( ( defined $self->SUPER::_Value('Queue') )
+        && ( $self->SUPER::_Value('Queue') == 0 ) )
+    {
+        unless ( $self->CurrentUser->HasRight( Object => $RT::System, Right => 'ModifyTemplate') ) {
+            return ( 0, $self->loc('Permission Denied') );
+        }
+    }
+    else {
+
+        unless ( $self->CurrentUserHasQueueRight('ModifyTemplate') ) {
+            return ( 0, $self->loc('Permission Denied') );
+        }
+    }
+    return ( $self->SUPER::_Set(@_) );
+
+}
+
+# }}}
+
+# {{{ sub _Value 
+
+=head2 _Value
+
+Takes the name of a table column.
+Returns its value as a string, if the user passes an ACL check
+
+
+=begin testing
+
+my $t = RT::Template->new($RT::SystemUser);
+$t->Create(Name => "Foo", Queue => 1);
+my $t2 = RT::Template->new($RT::Nobody);
+$t2->Load($t->Id);
+ok($t2->QueueObj->id, "Got the template's queue objet");
+
+=end testing
+
+
+
+=cut
+
+sub _Value {
+
+    my $self  = shift;
+    my $field = shift;
+
+   
+    #If the current user doesn't have ACLs, don't let em at it.  
+    #use super::value or we get acl blocked
+    if ( ( !defined $self->__Value('Queue') )
+        || ( $self->__Value('Queue') == 0 ) )
+    {
+        unless ( $self->CurrentUser->HasRight( Object => $RT::System, Right => 'ShowTemplate') ) {
+            return (undef);
+        }
+    }
+    else {
+        unless ( $self->CurrentUserHasQueueRight('ShowTemplate') ) {
+            return (undef);
+        }
+    }
+    return ( $self->__Value($field) );
+
+}
+
+# }}}
+
+# {{{ sub Load
+
+=head2 Load <identifer>
+
+Load a template, either by number or by name
+
+=cut
+
+sub Load {
+    my $self       = shift;
+    my $identifier = shift;
+
+    if ( !$identifier ) {
+        return (undef);
+    }
+
+    if ( $identifier !~ /\D/ ) {
+        $self->SUPER::LoadById($identifier);
+    }
+    else {
+        $self->LoadByCol( 'Name', $identifier );
+
+    }
+}
+
+# }}}
+
+# {{{ sub LoadGlobalTemplate
+
+=head2 LoadGlobalTemplate NAME
+
+Load the global tempalte with the name NAME
+
+=cut
+
+sub LoadGlobalTemplate {
+    my $self = shift;
+    my $id   = shift;
+
+    return ( $self->LoadQueueTemplate( Queue => 0, Name => $id ) );
+}
+
+# }}}
+
+# {{{ sub LoadQueueTemplate
+
+=head2  LoadQueueTemplate (Queue => QUEUEID, Name => NAME)
+
+Loads the Queue template named NAME for Queue QUEUE.
+
+=cut
+
+sub LoadQueueTemplate {
+    my $self = shift;
+    my %args = (
+        Queue => undef,
+        Name  => undef
+    );
+
+    return ( $self->LoadByCols( Name => $args{'Name'}, Queue => {'Queue'} ) );
+
+}
+
+# }}}
+
+# {{{ sub Create
+
+=head2 Create
+
+Takes a paramhash of Content, Queue, Name and Description.
+Name should be a unique string identifying this Template.
+Description and Content should be the template's title and content.
+Queue should be 0 for a global template and the queue # for a queue-specific 
+template.
+
+Returns the Template's id # if the create was successful. Returns undef for
+unknown database failure.
+
+
+=cut
+
+sub Create {
+    my $self = shift;
+    my %args = (
+        Content     => undef,
+        Queue       => 0,
+        Description => '[no description]',
+        Type => 'Action',    #By default, template are 'Action' templates
+        Name => undef,
+        @_
+    );
+
+    if ( !$args{'Queue'}  ) {
+        unless ( $self->CurrentUser->HasRight(Right =>'ModifyTemplate', Object => $RT::System) ) {
+            return (undef);
+        }
+        $args{'Queue'} = 0;
+    }
+    else {
+        my $QueueObj = new RT::Queue( $self->CurrentUser );
+        $QueueObj->Load( $args{'Queue'} ) || return ( 0, $self->loc('Invalid queue') );
+    
+        unless ( $QueueObj->CurrentUserHasRight('ModifyTemplate') ) {
+            return (undef);
+        }
+        $args{'Queue'} = $QueueObj->Id;
+    }
+
+    my $result = $self->SUPER::Create(
+        Content => $args{'Content'},
+        Queue   =>  $args{'Queue'},
+        Description => $args{'Description'},
+        Name        => $args{'Name'}
+    );
+
+    return ($result);
+
+}
+
+# }}}
+
+# {{{ sub Delete
+
+=head2 Delete
+
+Delete this template.
+
+=cut
+
+sub Delete {
+    my $self = shift;
+
+    unless ( $self->CurrentUserHasQueueRight('ModifyTemplate') ) {
+        return ( 0, $self->loc('Permission Denied') );
+    }
+
+    return ( $self->SUPER::Delete(@_) );
+}
+
+# }}}
+
+# {{{ sub MIMEObj
+sub MIMEObj {
+    my $self = shift;
+    return ( $self->{'MIMEObj'} );
+}
+
+# }}}
+
+# {{{ sub Parse 
+
+=item Parse
+
+ This routine performs Text::Template parsing on the template and then
+ imports the results into a MIME::Entity so we can really use it
+ It returns a tuple of (val, message)
+ If val is 0, the message contains an error message
+
+=cut
+
+sub Parse {
+    my $self = shift;
+
+    #We're passing in whatever we were passed. it's destined for _ParseContent
+    my $content = $self->_ParseContent(@_);
+
+    #Lets build our mime Entity
+
+    my $parser = MIME::Parser->new();
+
+    # Setup output directory for files. from RT::EmailParser::_SetupMIMEParser
+    if (my $AttachmentDir = eval { File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 ) }) {
+       # Set up output directory for files:
+       $parser->output_dir("$AttachmentDir");
+    }
+    else {
+       # On some situations TMPDIR is non-writable. sad but true.
+       $parser->output_to_core(1);
+       $parser->tmp_to_core(1);
+    }
+    #If someone includes a message, don't extract it
+    $parser->extract_nested_messages(1);
+    # Set up the prefix for files with auto-generated names:
+    $parser->output_prefix("part");
+    # If content length is <= 50000 bytes, store each msg as in-core scalar;
+    # Else, write to a disk file (the default action):
+    $parser->output_to_core(50000);
+
+
+    ### Should we forgive normally-fatal errors?
+    $parser->ignore_errors(1);
+    $self->{'MIMEObj'} = eval { $parser->parse_data($content) };
+    my $error = ( $@ || $parser->last_error );
+
+    if ($error) {
+        $RT::Logger->error("$error");
+        return ( 0, $error );
+    }
+
+    # Unfold all headers
+    $self->{'MIMEObj'}->head->unfold();
+
+    return ( 1, $self->loc("Template parsed") );
+   
+
+}
+
+# }}}
+
+# {{{ sub _ParseContent
+
+# Perform Template substitutions on the template
+
+sub _ParseContent {
+    my $self = shift;
+    my %args = (
+        Argument       => undef,
+        TicketObj      => undef,
+        TransactionObj => undef,
+        @_
+    );
+
+
+    $T::Ticket      = $args{'TicketObj'};
+    $T::Transaction = $args{'TransactionObj'};
+    $T::Argument    = $args{'Argument'};
+    $T::Requestor   = eval { $T::Ticket->Requestors->UserMembersObj->First->Name };
+    $T::rtname      = $RT::rtname;
+
+    # We need to untaint the content of the template, since we'll be working
+    # with it
+    my $content = $self->Content();
+    $content =~ s/^(.*)$/$1/;
+    my $template = Text::Template->new(
+        TYPE   => 'STRING',
+        SOURCE => $content
+    );
+
+    my $retval = $template->fill_in( PACKAGE => 'T' );
+
+    # MIME::Parser has problems dealing with high-bit utf8 data.
+    Encode::_utf8_off($retval);
+    return ($retval);
+}
+
+# }}}
+
+# {{{ sub CurrentUserHasQueueRight
+
+=head2 CurrentUserHasQueueRight
+
+Helper function to call the template's queue's CurrentUserHasQueueRight with the passed in args.
+
+=cut
+
+sub CurrentUserHasQueueRight {
+    my $self = shift;
+    return ( $self->QueueObj->CurrentUserHasRight(@_) );
+}
+
+# }}}
+1;
index b5b483c..37db840 100755 (executable)
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Templates.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-=head1 NAME
 
-  RT::Templates - a collection of RT Template objects
+=head1 NAME
 
+  RT::Templates -- Class Description
 =head1 SYNOPSIS
 
-  use RT::Templates;
+  use RT::Templates
 
 =head1 DESCRIPTION
 
 
 =head1 METHODS
 
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::Templates);
-
-=end testing
-
 =cut
 
 package RT::Templates;
-use RT::EasySearch;
-@ISA= qw(RT::EasySearch);
 
+use RT::SearchBuilder;
+use RT::Template;
 
-# {{{ sub _Init
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
 
-=head2 _Init
-
-  Returns RT::Templates specific init info like table and primary key names
-
-=cut
 
 sub _Init {
-    
     my $self = shift;
-    $self->{'table'} = "Templates";
-    $self->{'primary_key'} = "id";
-    return ($self->SUPER::_Init(@_));
+    $self->{'table'} = 'Templates';
+    $self->{'primary_key'} = 'id';
+
+
+    return ( $self->SUPER::_Init(@_) );
 }
-# }}}
 
-# {{{ LimitToNotInQueue
 
-=head2 LimitToNotInQueue
+=item NewItem
 
-Takes a queue id # and limits the returned set of templates to those which 
-aren't that queue's templates.
+Returns an empty new RT::Template item
 
 =cut
 
-sub LimitToNotInQueue {
+sub NewItem {
     my $self = shift;
-    my $queue_id = shift;
-    $self->Limit(FIELD => 'Queue',
-                 VALUE => "$queue_id",
-                 OPERATOR => '!='
-                );
+    return(RT::Template->new($self->CurrentUser));
 }
-# }}}
 
-# {{{ LimitToGlobal
+        eval "require RT::Templates_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Templates_Overlay.pm}) {
+            die $@;
+        };
 
-=head2 LimitToGlobal
+        eval "require RT::Templates_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Templates_Vendor.pm}) {
+            die $@;
+        };
 
-Takes no arguments. Limits the returned set to "Global" templates
-which can be used with any queue.
+        eval "require RT::Templates_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Templates_Local.pm}) {
+            die $@;
+        };
 
-=cut
 
-sub LimitToGlobal {
-    my $self = shift;
-    my $queue_id = shift;
-    $self->Limit(FIELD => 'Queue',
-                 VALUE => "0",
-                 OPERATOR => '='
-                );
-}
-# }}}
 
-# {{{ LimitToQueue
 
-=head2 LimitToQueue
+=head1 SEE ALSO
 
-Takes a queue id # and limits the returned set of templates to that queue's
-templates
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
 
-=cut
+These overlay files can contain new subs or subs to replace existing subs in this module.
 
-sub LimitToQueue {
-    my $self = shift;
-    my $queue_id = shift;
-    $self->Limit(FIELD => 'Queue',
-                 VALUE => "$queue_id",
-                 OPERATOR => '='
-                );
-}
-# }}}
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
 
-# {{{ sub NewItem 
+   no warnings qw(redefine);
 
-=head2 NewItem
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
 
-Returns a new empty Template object
+RT::Templates_Overlay, RT::Templates_Vendor, RT::Templates_Local
 
 =cut
 
-sub NewItem  {
-  my $self = shift;
-
-  use RT::Template;
-  my $item = new RT::Template($self->CurrentUser);
-  return($item);
-}
-# }}}
 
 1;
-
diff --git a/rt/lib/RT/Templates_Overlay.pm b/rt/lib/RT/Templates_Overlay.pm
new file mode 100644 (file)
index 0000000..6bc992e
--- /dev/null
@@ -0,0 +1,141 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Templates - a collection of RT Template objects
+
+=head1 SYNOPSIS
+
+  use RT::Templates;
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=begin testing
+
+ok (require RT::Templates);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+
+# {{{ sub _Init
+
+=head2 _Init
+
+  Returns RT::Templates specific init info like table and primary key names
+
+=cut
+
+sub _Init {
+    
+    my $self = shift;
+    $self->{'table'} = "Templates";
+    $self->{'primary_key'} = "id";
+    return ($self->SUPER::_Init(@_));
+}
+# }}}
+
+# {{{ LimitToNotInQueue
+
+=head2 LimitToNotInQueue
+
+Takes a queue id # and limits the returned set of templates to those which 
+aren't that queue's templates.
+
+=cut
+
+sub LimitToNotInQueue {
+    my $self = shift;
+    my $queue_id = shift;
+    $self->Limit(FIELD => 'Queue',
+                 VALUE => "$queue_id",
+                 OPERATOR => '!='
+                );
+}
+# }}}
+
+# {{{ LimitToGlobal
+
+=head2 LimitToGlobal
+
+Takes no arguments. Limits the returned set to "Global" templates
+which can be used with any queue.
+
+=cut
+
+sub LimitToGlobal {
+    my $self = shift;
+    my $queue_id = shift;
+    $self->Limit(FIELD => 'Queue',
+                 VALUE => "0",
+                 OPERATOR => '='
+                );
+}
+# }}}
+
+# {{{ LimitToQueue
+
+=head2 LimitToQueue
+
+Takes a queue id # and limits the returned set of templates to that queue's
+templates
+
+=cut
+
+sub LimitToQueue {
+    my $self = shift;
+    my $queue_id = shift;
+    $self->Limit(FIELD => 'Queue',
+                 VALUE => "$queue_id",
+                 OPERATOR => '='
+                );
+}
+# }}}
+
+# {{{ sub NewItem 
+
+=head2 NewItem
+
+Returns a new empty Template object
+
+=cut
+
+sub NewItem  {
+  my $self = shift;
+
+  use RT::Template;
+  my $item = new RT::Template($self->CurrentUser);
+  return($item);
+}
+# }}}
+
+1;
+
diff --git a/rt/lib/RT/TestHarness.pm b/rt/lib/RT/TestHarness.pm
deleted file mode 100644 (file)
index 160e9e6..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-use lib "/opt/rt2/etc/";
-
-use RT::Interface::CLI  qw(CleanEnv LoadConfig DBConnect 
-                          GetCurrentUser GetMessageContent);
-
-#Clean out all the nasties from the environment
-CleanEnv();
-
-#Load etc/config.pm and drop privs
-LoadConfig();
-
-
-use RT;
-RT::Init;
index f7275e4..2f075a2 100755 (executable)
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Ticket.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# (c) 1996-2001 Jesse Vincent <jesse@fsck.com>
-# This software is redistributable under the terms of the GNU GPL
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
 #
 
-=head1 NAME
+use strict;
 
-  RT::Ticket - RT ticket object
 
-=head1 SYNOPSIS
+=head1 NAME
 
-  use RT::Ticket;
-  my $ticket = new RT::Ticket($CurrentUser);
-  $ticket->Load($ticket_id);
+RT::Ticket
 
-=head1 DESCRIPTION
 
-This module lets you manipulate RT\'s ticket object.
+=head1 SYNOPSIS
 
+=head1 DESCRIPTION
 
 =head1 METHODS
 
 =cut
 
-
-
 package RT::Ticket;
+use RT::Record; 
 use RT::Queue;
-use RT::User;
-use RT::Record;
-use RT::Link;
-use RT::Links;
-use RT::Date;
-use RT::Watcher;
-
-
-@ISA= qw(RT::Record);
-
 
-=begin testing
 
-use RT::TestHarness;
-
-ok(require RT::Ticket, "Loading the RT::Ticket library");
-
-=end testing
-
-=cut
-
-# {{{ sub _Init
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
 
 sub _Init {
-    my $self = shift;
-    $self->{'table'} = "Tickets";
-    return ($self->SUPER::_Init(@_));
-}
-
-# }}}
-
-# {{{ sub Load
-
-=head2 Load
-
-Takes a single argument. This can be a ticket id, ticket alias or 
-local ticket uri.  If the ticket can't be loaded, returns undef.
-Otherwise, returns the ticket id.
-
-=cut
-
-sub Load {
-   my $self = shift;
-   my $id = shift;
-
-   #TODO modify this routine to look at EffectiveId and do the recursive load
-   # thing. be careful to cache all the interim tickets we try so we don't loop forever.
-   
-   #If it's a local URI, turn it into a ticket id
-   if ($id =~ /^$RT::TicketBaseURI(\d+)$/)  {
-       $id = $1;
-   }
-   #If it's a remote URI, we're going to punt for now
-   elsif ($id =~ '://' ) {
-       return (undef);
-   }
-   
-   #If we have an integer URI, load the ticket
-   if ( $id =~ /^\d+$/ ) {
-       my $ticketid = $self->LoadById($id);
-   
-       unless ($ticketid) {
-          $RT::Logger->debug("$self tried to load a bogus ticket: $id\n");
-          return(undef);
-       }
-   }
-   
-   #It's not a URI. It's not a numerical ticket ID. Punt!
-   else {
-       return(undef);
-   }
-   
-   #If we're merged, resolve the merge.
-   if (($self->EffectiveId) and
-       ($self->EffectiveId != $self->Id)) {
-          return ($self->Load($self->EffectiveId));
-       }
-
-   #Ok. we're loaded. lets get outa here.
-   return ($self->Id);
-   
-}
-
-# }}}
+  my $self = shift; 
 
-# {{{ sub LoadByURI
-
-=head2 LoadByURI
-
-Given a local ticket URI, loads the specified ticket.
-
-=cut
-
-sub LoadByURI {
-    my $self = shift;
-    my $uri = shift;
-    
-    if ($uri =~ /^$RT::TicketBaseURI(\d+)$/) {
-        my $id = $1;
-        return ($self->Load($id));
-    }
-    else {
-        return(undef);
-    }
+  $self->Table('Tickets');
+  $self->SUPER::_Init(@_);
 }
 
-# }}}
-
-# {{{ sub Create
-
-=head2 Create (ARGS)
-
-Arguments: ARGS is a hash of named parameters.  Valid parameters are:
-
-  Queue  - Either a Queue object or a Queue Name
-  Requestor -  A reference to a list of RT::User objects, email addresses or RT user Names
-  Cc  - A reference to a list of RT::User objects, email addresses or Names
-  AdminCc  - A reference to a  list of RT::User objects, email addresses or Names
-  Type -- The ticket\'s type. ignore this for now
-  Owner -- This ticket\'s owner. either an RT::User object or this user\'s id
-  Subject -- A string describing the subject of the ticket
-  InitialPriority -- an integer from 0 to 99
-  FinalPriority -- an integer from 0 to 99
-  Status -- any valid status (Defined in RT::Queue)
-  TimeWorked -- an integer
-  TimeLeft -- an integer
-  Starts -- an ISO date describing the ticket\'s start date and time in GMT
-  Due -- an ISO date describing the ticket\'s due date and time in GMT
-  MIMEObj -- a MIME::Entity object with the content of the initial ticket request.
-
-  KeywordSelect-<id> -- an array of keyword ids for that keyword select
-
-
-Returns: TICKETID, Transaction Object, Error Message
-
-
-=begin testing
-
-my $t = RT::Ticket->new($RT::SystemUser);
-
-ok( $t->Create(Queue => 'General', Subject => 'This is a subject'), "Ticket Created");
-
-ok ( my $id = $t->Id, "Got ticket id");
-
-=end testing
-
-=cut
-
-sub Create {
-    my $self = shift;
-    
-    my %args = (
-               Queue => undef,
-               Requestor => undef,
-               Cc => undef,
-               AdminCc => undef,
-               Type => 'ticket',
-               Owner => $RT::Nobody->UserObj,
-               Subject => '[no subject]',
-               InitialPriority => undef,
-               FinalPriority => undef,
-               Status => 'new',
-               TimeWorked => "0",
-               TimeLeft => 0,
-               Due => undef,
-               Starts => undef,
-               MIMEObj => undef,
-               @_);
-
-    my ($ErrStr, $QueueObj, $Owner, $resolved);
-    my (@non_fatal_errors);
-    
-    my $now = RT::Date->new($self->CurrentUser);
-    $now->SetToNow();
-
-    if ( (defined($args{'Queue'})) && (!ref($args{'Queue'})) ) {
-       $QueueObj=RT::Queue->new($RT::SystemUser);
-       $QueueObj->Load($args{'Queue'});
-    }
-    elsif (ref($args{'Queue'}) eq 'RT::Queue') {
-       $QueueObj=RT::Queue->new($RT::SystemUser);
-       $QueueObj->Load($args{'Queue'}->Id);
-    }
-    else {
-       $RT::Logger->debug("$self ". $args{'Queue'} . 
-                        " not a recognised queue object.");
-    }
-  
-    #Can't create a ticket without a queue.
-    unless (defined ($QueueObj)) {
-       $RT::Logger->debug( "$self No queue given for ticket creation.");
-       return (0, 0,'Could not create ticket. Queue not set');
-    }
-    
-    #Now that we have a queue, Check the ACLS
-    unless ($self->CurrentUser->HasQueueRight(Right => 'CreateTicket',
-                                             QueueObj => $QueueObj )) {
-       return (0,0,"No permission to create tickets in the queue '". 
-               $QueueObj->Name."'.");
-    }
-    
-    #Since we have a queue, we can set queue defaults
-    #Initial Priority
-
-    # If there's no queue default initial priority and it's not set, set it to 0
-    $args{'InitialPriority'} = ($QueueObj->InitialPriority || 0)
-      unless (defined $args{'InitialPriority'});
-       
-    #Final priority 
-
-    # If there's no queue default final priority and it's not set, set it to 0
-    $args{'FinalPriority'} = ($QueueObj->FinalPriority  || 0)
-      unless (defined $args{'FinalPriority'});
-    
-    
-    #TODO we should see what sort of due date we're getting, rather +
-    # than assuming it's in ISO format.
-    
-    #Set the due date. if we didn't get fed one, use the queue default due in
-    my $due = new RT::Date($self->CurrentUser);
-    if (defined $args{'Due'}) {
-       $due->Set (Format => 'ISO',
-                  Value => $args{'Due'});
-    }  
-    elsif (defined ($QueueObj->DefaultDueIn)) {
-       $due->SetToNow;
-       $due->AddDays($QueueObj->DefaultDueIn);
-    }  
-    
-    my $starts = new RT::Date($self->CurrentUser);
-    if (defined $args{'Starts'}) {
-       $starts->Set (Format => 'ISO',
-                  Value => $args{'Starts'});
-    }
-
-       
-    # {{{ Deal with setting the owner
-    
-    if (ref($args{'Owner'}) eq 'RT::User') {
-       $Owner = $args{'Owner'};
-    }
-    #If we've been handed something else, try to load the user.
-    elsif ($args{'Owner'}) {
-       $Owner = new RT::User($self->CurrentUser);
-       $Owner->Load($args{'Owner'});
-       
-    }
-    #If we can't handle it, call it nobody
-    else {
-       if (ref($args{'Owner'})) {
-           $RT::Logger->warning("$ticket ->Create called with an Owner of ".
-                "type ".ref($args{'Owner'}) .". Defaulting to nobody.\n");
-
-           push @non_fatal_errors, "Invalid owner. Defaulting to 'nobody'.";
-       }
-       else { 
-           $RT::Logger->warning("$self ->Create called with an ".
-                                "unknown datatype for Owner: ".$args{'Owner'} .
-                                ". Defaulting to Nobody.\n");
-       }
-    }
-    
-    #If we have a proposed owner and they don't have the right 
-    #to own a ticket, scream about it and make them not the owner
-    if ((defined ($Owner)) and
-       ($Owner->Id != $RT::Nobody->Id) and 
-       (!$Owner->HasQueueRight( QueueObj => $QueueObj, 
-                                Right => 'OwnTicket'))) {
-       
-       $RT::Logger->warning("$self user ".$Owner->Name . "(".$Owner->id .
-                            ") was proposed ".
-                            "as a ticket owner but has no rights to own ".
-                            "tickets in this queue\n");
-
-       push @non_fatal_errors, "Invalid owner. Defaulting to 'nobody'.";
-
-       $Owner = undef;
-    }
-    
-    #If we haven't been handed a valid owner, make it nobody.
-    unless (defined ($Owner)) {
-       $Owner = new RT::User($self->CurrentUser);
-       $Owner->Load($RT::Nobody->UserObj->Id);
-    }  
-
-    # }}}
-
-    unless ($self->ValidateStatus($args{'Status'})) {
-       return (0,0,'Invalid value for status');
-    }
-
-    if ($args{'Status'} eq 'resolved') {
-       $resolved = $now->ISO;
-    } else{
-       $resolved = undef;
-    }
-
-    my $id = $self->SUPER::Create(
-                                 Queue => $QueueObj->Id,
-                                 Owner => $Owner->Id,
-                                 Subject => $args{'Subject'},
-                                 InitialPriority => $args{'InitialPriority'},
-                                 FinalPriority => $args{'FinalPriority'},
-                                 Priority => $args{'InitialPriority'},
-                                 Status => $args{'Status'},
-                                 TimeWorked => $args{'TimeWorked'},
-                                 TimeLeft => $args{'TimeLeft'},
-                                 Type => $args{'Type'},        
-                                 Starts => $starts->ISO,
-                                 Resolved => $resolved,
-                                 Due => $due->ISO
-                                );
-    #Set the ticket's effective ID now that we've created it.
-    my ($val, $msg) = $self->__Set(Field => 'EffectiveId', Value => $id);
-    
-    unless ($val) {
-       $RT::Logger->err("$self ->Create couldn't set EffectiveId: $msg\n");
-    }  
-     
-
-    my $watcher;
-    foreach $watcher (@{$args{'Cc'}}) {
-       my ($wval, $wmsg) = 
-         $self->_AddWatcher( Type => 'Cc', Person => $watcher, Silent => 1);
-       push @non_fatal_errors, $wmsg   unless ($wval);
-    }  
-
-    foreach $watcher (@{$args{'Requestor'}}) {
-       my ($wval, $wmsg) = 
-         $self->_AddWatcher( Type => 'Requestor', Person => $watcher, Silent => 1);
-       push @non_fatal_errors, $wmsg   unless ($wval);
-    }
-
-    foreach $watcher (@{$args{'AdminCc'}}) {
-       # Note that we're using AddWatcher, rather than _AddWatcher, as we 
-       # actually _want_ that ACL check. Otherwise, random ticket creators
-       # could make themselves adminccs and maybe get ticket rights. that would
-       # be poor
-       my ($wval, $wmsg) = 
-         $self->AddWatcher( Type => 'AdminCc', Person => $watcher, Silent => 1);
-       push @non_fatal_errors, $wmsg   unless ($wval);
-    }
-
-    # Iterate through all the KeywordSelect-<int> params passed in, calling _AddKeyword
-    # for each of them
-
-
-    foreach my $key (keys %args) {
-
-       next unless ($key =~ /^KeywordSelect-(.*)$/);
-       
-       my $ks = $1;
-
-
-       my @keywords = ref($args{$key}) eq 'ARRAY' ?
-             @{$args{$key}} : ($args{$key});
-       
-       foreach my $keyword (@keywords) {  
-           my ($kval, $kmsg) = $self->_AddKeyword(KeywordSelect => $ks,
-                                                  Keyword => $keyword,
-                                                  Silent => 1);
-       }       
-       push @non_fatal_errors, $kmsg unless ($kval);
-    }
-
-    
-    
-    #Add a transaction for the create
-    my ($Trans, $Msg, $TransObj) = 
-       $self->_NewTransaction( Type => "Create",
-                               TimeTaken => 0, 
-                               MIMEObj=>$args{'MIMEObj'});
-    
-    # Logging
-    if ($self->Id && $Trans) {
-       $ErrStr = "Ticket ".$self->Id . " created in queue '". $QueueObj->Name. 
-         "'.\n" . join("\n", @non_fatal_errors);
-       
-       $RT::Logger->info($ErrStr);
-    }
-    else {
-       # TODO where does this get errstr from?
-       $RT::Logger->warning("Ticket couldn't be created: $ErrStr");
-    }
-    
-    return($self->Id, $TransObj->Id, $ErrStr);
-}
 
-# }}}
 
-# {{{ sub Import
 
-=head2 Import PARAMHASH
 
-Import a ticket. 
-Doesn\'t create a transaction. 
-Doesn\'t supply queue defaults, etc.
+=item Create PARAMHASH
 
-Arguments are identical to Create(), with the addition of
-    Id -    Ticket Id
+Create takes a hash of values and creates a row in the database:
 
-Returns: TICKETID
+  int(11) 'EffectiveId'.
+  int(11) 'Queue'.
+  varchar(16) 'Type'.
+  int(11) 'IssueStatement'.
+  int(11) 'Resolution'.
+  int(11) 'Owner'.
+  varchar(200) 'Subject' defaults to '[no subject]'.
+  int(11) 'InitialPriority'.
+  int(11) 'FinalPriority'.
+  int(11) 'Priority'.
+  int(11) 'TimeEstimated'.
+  int(11) 'TimeWorked'.
+  varchar(10) 'Status'.
+  int(11) 'TimeLeft'.
+  datetime 'Told'.
+  datetime 'Starts'.
+  datetime 'Started'.
+  datetime 'Due'.
+  datetime 'Resolved'.
+  smallint(6) 'Disabled'.
 
 =cut
 
 
-sub Import {
-    my $self = shift;
-    my ( $ErrStr, $QueueObj, $Owner);
-    
-    my %args = (id => undef,
-               EffectiveId => undef,
-               Queue => undef,
-               Requestor => undef,
-               Type => 'ticket',
-               Owner => $RT::Nobody->Id,
-               Subject => '[no subject]',
-               InitialPriority => undef,
-               FinalPriority => undef,
-               Status => 'new',
-               TimeWorked => "0",
-               Due => undef,
-               Created => undef,
-               Updated => undef,
-       Resolved => undef,
-               Told => undef,
-               @_);
-    
-    if ( (defined($args{'Queue'})) && (!ref($args{'Queue'})) ) {
-       $QueueObj=RT::Queue->new($RT::SystemUser);
-       $QueueObj->Load($args{'Queue'});
-       #TODO error check this and return 0 if it\'s not loading properly +++
-    }
-    elsif (ref($args{'Queue'}) eq 'RT::Queue') {
-       $QueueObj=RT::Queue->new($RT::SystemUser);
-       $QueueObj->Load($args{'Queue'}->Id);
-    }
-    else {
-       $RT::Logger->debug("$self ". $args{'Queue'} . 
-                          " not a recognised queue object.");
-    }
-    
-    #Can't create a ticket without a queue.
-    unless (defined ($QueueObj) and $QueueObj->Id) {
-       $RT::Logger->debug( "$self No queue given for ticket creation.");
-       return (0,'Could not create ticket. Queue not set');
-    }
-    
-    #Now that we have a queue, Check the ACLS
-    unless ($self->CurrentUser->HasQueueRight(Right => 'CreateTicket',
-                                             QueueObj => $QueueObj )) {
-       return (0,"No permission to create tickets in the queue '". 
-               $QueueObj->Name."'.");
-    }
-    
-    
-
-
-    # {{{ Deal with setting the owner
-      
-    # Attempt to take user object, user name or user id.
-    # Assign to nobody if lookup fails.
-    if (defined ($args{'Owner'})) { 
-       if ( ref($args{'Owner'}) ) {
-           $Owner = $args{'Owner'};
-       }
-       else {
-           $Owner = new RT::User($self->CurrentUser);
-           $Owner->Load($args{'Owner'});
-           if ( ! defined($Owner->id) ) {
-               $Owner->Load($RT::Nobody->id);
-           }
-       }
-    }
-    
-
-    #If we have a proposed owner and they don't have the right 
-    #to own a ticket, scream about it and make them not the owner
-    if ((defined ($Owner)) and
-       ($Owner->Id != $RT::Nobody->Id) and 
-       (!$Owner->HasQueueRight( QueueObj => $QueueObj, 
-                                Right => 'OwnTicket'))) {
-       
-       $RT::Logger->warning("$self user ".$Owner->Name . "(".$Owner->id .
-                            ") was proposed ".
-                            "as a ticket owner but has no rights to own ".
-                            "tickets in '".$QueueObj->Name."'\n");
-       
-       $Owner = undef;
-    }
-    
-    #If we haven't been handed a valid owner, make it nobody.
-    unless (defined ($Owner)) {
-       $Owner = new RT::User($self->CurrentUser);
-       $Owner->Load($RT::Nobody->UserObj->Id);
-    }  
-
-    # }}}
-
-    unless ($self->ValidateStatus($args{'Status'})) {
-       return (0,"'$args{'Status'}' is an invalid value for status");
-    }
-    
-    $self->{'_AccessibleCache'}{Created} = { 'read'=>1, 'write'=>1 };
-    $self->{'_AccessibleCache'}{Creator} = { 'read'=>1, 'auto'=>1 };
-    $self->{'_AccessibleCache'}{LastUpdated} = { 'read'=>1, 'write'=>1 };
-    $self->{'_AccessibleCache'}{LastUpdatedBy} = { 'read'=>1, 'auto'=>1 };
-
-
-    # If we're coming in with an id, set that now.
-    my $EffectiveId = undef;
-    if ($args{'id'}) {
-       $EffectiveId = $args{'id'};
-
-    }
-
-
-    my $id = $self->SUPER::Create(
-                                 id => $args{'id'},
-                                 EffectiveId => $EffectiveId,
-                                 Queue => $QueueObj->Id,
-                                 Owner => $Owner->Id,
-                                 Subject => $args{'Subject'},
-                                 InitialPriority => $args{'InitialPriority'},
-                                 FinalPriority => $args{'FinalPriority'},
-                                 Priority => $args{'InitialPriority'},
-                                 Status => $args{'Status'},
-                                 TimeWorked => $args{'TimeWorked'},
-                                 Type => $args{'Type'},        
-                                 Created => $args{'Created'},
-                                 Told => $args{'Told'},
-                                 LastUpdated => $args{'Updated'},
-       Resolved => $args{Resolved},
-                                 Due => $args{'Due'},
-                                );
-
-
-
-    # If the ticket didn't have an id
-    # Set the ticket's effective ID now that we've created it.
-    if ($args{'id'} ) { 
-         $self->Load($args{'id'});
-    }
-    else {
-          my ($val, $msg) = $self->__Set(Field => 'EffectiveId', Value => $id);
-    
-          unless ($val) {
-           $RT::Logger->err($self."->Import couldn't set EffectiveId: $msg\n");
-          }    
-    } 
-
-    my $watcher;
-    foreach $watcher (@{$args{'Cc'}}) {
-       $self->_AddWatcher( Type => 'Cc', Person => $watcher, Silent => 1);
-    }  
-    foreach $watcher (@{$args{'AdminCc'}}) {
-       $self->_AddWatcher( Type => 'AdminCc', Person => $watcher, Silent => 1);
-    }  
-    foreach $watcher (@{$args{'Requestor'}}) {
-       $self->_AddWatcher( Type => 'Requestor', Person => $watcher, Silent => 1);
-    }
-    
-    return($self->Id, $ErrStr);
-}
-
-# }}}
-
-# {{{ sub Delete
-
-sub Delete {
-    my $self = shift;
-    return (0, 'Deleting this object would violate referential integrity.'.
-           ' That\'s bad.');
-}
-# }}}
-
-# {{{ Routines dealing with watchers.
-
-# {{{ Routines dealing with adding new watchers
-
-# {{{ sub AddWatcher
-
-=head2 AddWatcher
-
-AddWatcher takes a parameter hash. The keys are as follows:
-
-Email
-Type
-Owner
-
-If the watcher you\'re trying to set has an RT account, set the Owner paremeter to their User Id. Otherwise, set the Email parameter to their Email address.
-
-=cut
-
-sub AddWatcher {
-    my $self = shift;
-    my %args = ( Email => undef,
-                Type => undef,
-                Owner => undef,
-                @_
-              );
-
-    # {{{ Check ACLS
-    #If the watcher we're trying to add is for the current user
-    if ( ( $self->CurrentUser->EmailAddress &&
-           ($args{'Email'} eq $self->CurrentUser->EmailAddress) ) or
-           ($args{'Owner'} eq $self->CurrentUser->Id) 
-        ) {
-
-       
-       #  If it's an AdminCc and they don't have 
-       #   'WatchAsAdminCc' or 'ModifyTicket', bail
-       if ($args{'Type'} eq 'AdminCc') {
-           unless ($self->CurrentUserHasRight('ModifyTicket') or 
-                   $self->CurrentUserHasRight('WatchAsAdminCc')) {
-               return(0, 'Permission Denied');
-           }
-       }
-
-       #  If it's a Requestor or Cc and they don't have
-       #   'Watch' or 'ModifyTicket', bail
-       elsif (($args{'Type'} eq 'Cc') or 
-              ($args{'Type'} eq 'Requestor')) {
-                  
-           unless ($self->CurrentUserHasRight('ModifyTicket') or 
-                   $self->CurrentUserHasRight('Watch')) {
-               return(0, 'Permission Denied');
-           }
-       }
-       else {
-           $RT::Logger->warn("$self -> AddWatcher hit code".
-                             " it never should. We got passed ".
-                             " a type of ". $args{'Type'});
-           return (0,'Error in parameters to TicketAddWatcher');
-       }
-    }
-    # If the watcher isn't the current user 
-    # and the current user  doesn't have 'ModifyTicket'
-    # bail
-    else {
-       unless ($self->CurrentUserHasRight('ModifyTicket')) {
-           return (0, "Permission Denied");
-       }
-    }
-    # }}}
-
-    return ($self->_AddWatcher(%args));
-}
-
-
-#This contains the meat of AddWatcher. but can be called from a routine like
-# Create, which doesn't need the additional acl check
-sub _AddWatcher {
-    my $self = shift;
-    my %args = (
-               Type => undef,
-               Silent => undef,
-               Email => undef,
-               Owner => 0,
-               Person => undef,
-               @_ );
-    
-    
-    
-    #clear the watchers cache
-    $self->{'watchers_cache'} = undef;
-    
-    if (defined $args{'Person'}) {
-       #if it's an RT::User object, pull out the id and shove it in Owner
-       if (ref ($args{'Person'}) =~ /RT::User/) {
-           $args{'Owner'} = $args{'Person'}->id;
-       }       
-       #if it's an int, shove it in Owner
-       elsif ($args{'Person'} =~ /^\d+$/) {
-           $args{'Owner'} = $args{'Person'};
-       }
-       #if it's an email address, shove it in Email
-       else {
-          $args{'Email'} = $args{'Person'};
-       }       
-    }  
-
-    # Turn an email address int a watcher if we possibly can.
-    if ($args{'Email'}) {
-       my $watcher = new RT::User($self->CurrentUser);
-       $watcher->LoadByEmail($args{'Email'});
-       if ($watcher->Id) {
-               $args{'Owner'} = $watcher->Id;
-               delete $args{'Email'};
-       }
-    }
-
-
-    # see if this user is already a watcher. if we have an owner, check it
-    # otherwise, we've got an email-address watcher. use that.
-
-    if ($self->IsWatcher(Type => $args{'Type'},
-                         Id => ($args{'Owner'} || $args{'Email'}) ) ) {
-
-
-        return(0, 'That user is already that sort of watcher for this ticket');
-    }
-
-    
-    require RT::Watcher;
-    my $Watcher = new RT::Watcher ($self->CurrentUser);
-    my ($retval, $msg) = ($Watcher->Create( Value => $self->Id,
-                                           Scope => 'Ticket',
-                                           Email => $args{'Email'},
-                                           Type => $args{'Type'},
-                                           Owner => $args{'Owner'},
-                                         ));
-    
-    unless ($args{'Silent'}) {
-       $self->_NewTransaction( Type => 'AddWatcher',
-                               NewValue => $Watcher->Email,
-                               Field => $Watcher->Type);
-    }
-    
-    return ($retval, $msg);
-}
-
-# }}}
-
-# {{{ sub AddRequestor
-
-=head2 AddRequestor
-
-AddRequestor takes what AddWatcher does, except it presets
-the "Type" parameter to \'Requestor\'
-
-=cut
-
-sub AddRequestor {
-   my $self = shift;
-   return ($self->AddWatcher ( Type => 'Requestor', @_));
-}
-
-# }}}
-
-# {{{ sub AddCc
-
-=head2 AddCc
-
-AddCc takes what AddWatcher does, except it presets
-the "Type" parameter to \'Cc\'
-
-=cut
-
-sub AddCc {
-   my $self = shift;
-   return ($self->AddWatcher ( Type => 'Cc', @_));
-}
-# }}}
-       
-# {{{ sub AddAdminCc
-
-=head2 AddAdminCc
-
-AddAdminCc takes what AddWatcher does, except it presets
-the "Type" parameter to \'AdminCc\'
-
-=cut
-
-sub AddAdminCc {
-   my $self = shift;
-   return ($self->AddWatcher ( Type => 'AdminCc', @_));
-}
-
-# }}}
-
-# }}}
-
-# {{{ sub DeleteWatcher
-
-=head2 DeleteWatcher id [type]
-
-DeleteWatcher takes a single argument which is either an email address 
-or a watcher id.  
-If the first argument is an email address, you need to specify the watcher type you're talking
-about as the second argument. Valid values are 'Requestor', 'Cc' or 'AdminCc'.
-It removes that watcher from this Ticket\'s list of watchers.
-
-
-=cut
 
-#TODO It is lame that you can't call this the same way you can call AddWatcher
 
-sub DeleteWatcher {
+sub Create {
     my $self = shift;
-    my $id = shift;
-
-    my $type;
-    
-    $type = shift if (@_);
-    
-    my $Watcher = new RT::Watcher($self->CurrentUser);
-    
-    #If it\'s a numeric watcherid
-    if ($id =~ /^(\d*)$/) {
-       $Watcher->Load($id);
-    }
-    
-    #Otherwise, we'll assume it's an email address
-    elsif ($type) {
-       my ($result, $msg) = 
-         $Watcher->LoadByValue( Email => $id,
-                                Scope => 'Ticket',
-                                Value => $self->id,
-                                Type => $type);
-       return (0,$msg) unless ($result);
-    }
-    
-    else {
-       return(0,"Can\'t delete a watcher by email address without specifying a type");
-    }
-    
-    # {{{ Check ACLS 
-
-    #If the watcher we're trying to delete is for the current user
-    if ($Watcher->Email eq $self->CurrentUser->EmailAddress) {
-               
-       #  If it's an AdminCc and they don't have 
-       #   'WatchAsAdminCc' or 'ModifyTicket', bail
-       if ($Watcher->Type eq 'AdminCc') {
-           unless ($self->CurrentUserHasRight('ModifyTicket') or 
-                   $self->CurrentUserHasRight('WatchAsAdminCc')) {
-               return(0, 'Permission Denied');
-           }
-       }
-
-       #  If it's a Requestor or Cc and they don't have
-       #   'Watch' or 'ModifyTicket', bail
-       elsif (($Watcher->Type eq 'Cc') or 
-              ($Watcher->Type eq 'Requestor')) {
-                  
-           unless ($self->CurrentUserHasRight('ModifyTicket') or 
-                   $self->CurrentUserHasRight('Watch')) {
-               return(0, 'Permission Denied');
-           }
-       }
-       else {
-           $RT::Logger->warn("$self -> DeleteWatcher hit code".
-                             " it never should. We got passed ".
-                             " a type of ". $args{'Type'});
-           return (0,'Error in parameters to $self DeleteWatcher');
-       }
-    }
-    # If the watcher isn't the current user 
-    # and the current user  doesn't have 'ModifyTicket'
-    # bail
-    else {
-       unless ($self->CurrentUserHasRight('ModifyTicket')) {
-           return (0, "Permission Denied");
-       }
-    }  
-    
-    # }}}
-    
-    unless (($Watcher->Scope eq 'Ticket') and
-           ($Watcher->Value == $self->id) ) {
-       return (0, "Not a watcher for this ticket");
-    }
-
-
-    #Clear out the watchers hash.
-    $self->{'watchers'} = undef;
-    
-    #If we\'ve validated that it is a watcher for this ticket 
-    $self->_NewTransaction ( Type => 'DelWatcher',        
-                            OldValue => $Watcher->Email,
-                            Field => $Watcher->Type,
-                          );
-    
-    my $retval = $Watcher->Delete();
-    
-    unless ($retval) {
-       return(0,"Watcher could not be deleted. Database inconsistency possible.");
-    }
-    
-    return(1, "Watcher deleted");
-}
-
-# {{{ sub DeleteRequestor
-
-=head2 DeleteRequestor EMAIL
+    my %args = ( 
+                EffectiveId => '0',
+                Queue => '0',
+                Type => '',
+                IssueStatement => '0',
+                Resolution => '0',
+                Owner => '0',
+                Subject => '[no subject]',
+                InitialPriority => '0',
+                FinalPriority => '0',
+                Priority => '0',
+                TimeEstimated => '0',
+                TimeWorked => '0',
+                Status => '',
+                TimeLeft => '0',
+                Told => '',
+                Starts => '',
+                Started => '',
+                Due => '',
+                Resolved => '',
+                Disabled => '0',
 
-Takes an email address. It calls DeleteWatcher with a preset 
-type of 'Requestor'
-
-
-=cut
+                 @_);
+    $self->SUPER::Create(
+                         EffectiveId => $args{'EffectiveId'},
+                         Queue => $args{'Queue'},
+                         Type => $args{'Type'},
+                         IssueStatement => $args{'IssueStatement'},
+                         Resolution => $args{'Resolution'},
+                         Owner => $args{'Owner'},
+                         Subject => $args{'Subject'},
+                         InitialPriority => $args{'InitialPriority'},
+                         FinalPriority => $args{'FinalPriority'},
+                         Priority => $args{'Priority'},
+                         TimeEstimated => $args{'TimeEstimated'},
+                         TimeWorked => $args{'TimeWorked'},
+                         Status => $args{'Status'},
+                         TimeLeft => $args{'TimeLeft'},
+                         Told => $args{'Told'},
+                         Starts => $args{'Starts'},
+                         Started => $args{'Started'},
+                         Due => $args{'Due'},
+                         Resolved => $args{'Resolved'},
+                         Disabled => $args{'Disabled'},
+);
 
-sub DeleteRequestor {
-   my $self = shift;
-   my $id = shift;
-   return ($self->DeleteWatcher ($id, 'Requestor'))
 }
 
-# }}}
-
-# {{{ sub DeleteCc
-
-=head2 DeleteCc EMAIL
-
-Takes an email address. It calls DeleteWatcher with a preset 
-type of 'Cc'
-
-
-=cut
-
-sub DeleteCc {
-   my $self = shift;
-   my $id = shift;
-   return ($self->DeleteWatcher ($id, 'Cc'))
-}
-
-# }}}
-
-# {{{ sub DeleteAdminCc
-
-=head2 DeleteAdminCc EMAIL
-
-Takes an email address. It calls DeleteWatcher with a preset 
-type of 'AdminCc'
-
-
-=cut
-
-sub DeleteAdminCc {
-   my $self = shift;
-   my $id = shift;
-   return ($self->DeleteWatcher ($id, 'AdminCc'))
-}
-
-# }}}
-
-
-# }}}
 
-# {{{ sub Watchers
 
-=head2 Watchers
+=item id
 
-Watchers returns a Watchers object preloaded with this ticket\'s watchers.
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
 
-# It should return only the ticket watchers. the actual FooAsString
-# methods capture the queue watchers too. I don't feel thrilled about this,
-# but we don't want the Cc Requestors and AdminCc objects to get filled up
-# with all the queue watchers too. we've got seperate objects for that.
-  # should we rename these as s/(.*)AsString/$1Addresses/ or somesuch?
 
 =cut
 
-sub Watchers {
-  my $self = shift;
-  
-  require RT::Watchers;
-  my $watchers=RT::Watchers->new($self->CurrentUser);
-  if ($self->CurrentUserHasRight('ShowTicket')) {
-      $watchers->LimitToTicket($self->id);
-  }
-  
-  return($watchers);
-  
-}
-
-# }}}
 
-# {{{ a set of  [foo]AsString subs that will return the various sorts of watchers for a ticket/queue as a comma delineated string
+=item EffectiveId
 
-=head2 RequestorsAsString
+Returns the current value of EffectiveId. 
+(In the database, EffectiveId is stored as int(11).)
 
- B<Returns> String: All Ticket Requestor email addresses as a string.
 
-=cut
 
-sub RequestorsAsString {
-    my $self=shift;
+=item SetEffectiveId VALUE
 
-    unless ($self->CurrentUserHasRight('ShowTicket')) {
-        return undef;
-    }
-    
-    return ($self->Requestors->EmailsAsString() );
-}
 
-=head2 WatchersAsString
+Set EffectiveId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, EffectiveId will be stored as a int(11).)
 
-B<Returns> String: All Ticket Watchers email addresses as a string
 
 =cut
 
-sub WatchersAsString {
-    my $self=shift;
-
-    unless ($self->CurrentUserHasRight('ShowTicket')) {
-       return (0, "Permission Denied");
-    }
-    
-    return ($self->Watchers->EmailsAsString());
-
-}
 
-=head2 AdminCcAsString
+=item Queue
 
-returns String: All Ticket AdminCc email addresses as a string
+Returns the current value of Queue. 
+(In the database, Queue is stored as int(11).)
 
-=cut
 
 
-sub AdminCcAsString {
-    my $self=shift;
+=item SetQueue VALUE
 
-    unless ($self->CurrentUserHasRight('ShowTicket')) {
-       return undef;
-    }
-    
-    return ($self->AdminCc->EmailsAsString());
-    
-}
 
-=head2 CcAsString
+Set Queue to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Queue will be stored as a int(11).)
 
-returns String: All Ticket Ccs as a string of email addresses
 
 =cut
 
-sub CcAsString {
-    my $self=shift;
-
-    unless ($self->CurrentUserHasRight('ShowTicket')) {
-        return undef; 
-    }
-    
-    return ($self->Cc->EmailsAsString());
-
-}
-
-# }}}
-
-# {{{ Routines that return RT::Watchers objects of Requestors, Ccs and AdminCcs
 
-# {{{ sub Requestors
+=item QueueObj
 
-=head2 Requestors
+Returns the Queue Object which has the id returned by Queue
 
-Takes nothing.
-Returns this ticket's Requestors as an RT::Watchers object
-
-=cut
-
-sub Requestors {
-    my $self = shift;
-    
-    my $requestors = $self->Watchers();
-    if ($self->CurrentUserHasRight('ShowTicket')) {
-       $requestors->LimitToRequestors();
-    }  
-    
-    return($requestors);
-    
-}
-
-# }}}
-
-# {{{ sub Cc
-
-=head2 Cc
-
-Takes nothing.
-Returns a watchers object which contains this ticket's Cc watchers
-
-=cut
-
-sub Cc {
-    my $self = shift;
-    
-    my $cc = $self->Watchers();
-    
-    if ($self->CurrentUserHasRight('ShowTicket')) {
-       $cc->LimitToCc();
-    }
-    
-    return($cc);
-    
-}
-
-# }}}
-
-# {{{ sub AdminCc
-
-=head2 AdminCc
-
-Takes nothing.
-Returns this ticket\'s administrative Ccs as an RT::Watchers object
-
-=cut
-
-sub AdminCc {
-    my $self = shift;
-    
-    my $admincc = $self->Watchers();
-    if ($self->CurrentUserHasRight('ShowTicket')) {
-       $admincc->LimitToAdminCc();
-    }
-    return($admincc);
-}
-
-# }}}
-
-# }}}
-
-# {{{ IsWatcher,IsRequestor,IsCc, IsAdminCc
-
-# {{{ sub IsWatcher
-# a generic routine to be called by IsRequestor, IsCc and IsAdminCc
-
-=head2 IsWatcher
-
-Takes a param hash with the attributes Type and User. User is either a user object or string containing an email address. Returns true if that user or string
-is a ticket watcher. Returns undef otherwise
-
-=cut
-
-sub IsWatcher {
-    my $self = shift;
-
-    my %args = ( Type => 'Requestor',
-                Email => undef,
-                Id => undef,
-                @_
-              );
-    
-    my %cols = ('Type' => $args{'Type'},
-               'Scope' => 'Ticket',
-               'Value' => $self->Id,
-               'Owner' => undef,
-               'Email' => undef
-              );
-    
-    if (ref($args{'Id'})){ 
-       #If it's a ref, it's an RT::User object;
-       $cols{'Owner'} = $args{'Id'}->Id;
-    }
-    elsif ($args{'Id'} =~ /^\d+$/) { 
-       # if it's an integer, it's a reference to an RT::User obj
-       $cols{'Owner'} = $args{'Id'};
-    }
-    else {
-       $cols{'Email'} = $args{'Id'};
-    }  
-    
-    if ($args{'Email'}) {
-       $cols{'Email'} = $args{'Email'};
-    }
-
-    my $description = join(":",%cols);
-    
-    #If we've cached a positive match...
-    if (defined $self->{'watchers_cache'}->{"$description"}) {
-       if ($self->{'watchers_cache'}->{"$description"} == 1) {
-           return(1);
-       }
-       else { #If we've cached a negative match...
-           return(undef);
-       }
-    }
-    
-    
-    my $watcher = new RT::Watcher($self->CurrentUser);
-    $watcher->LoadByCols(%cols);
-    
-    
-    if ($watcher->id) {
-       $self->{'watchers_cache'}->{"$description"} = 1;
-       return(1);
-    }  
-    else {
-       $self->{'watchers_cache'}->{"$description"} = 0;
-       return(undef);
-    }
-    
-}
-# }}}
-
-# {{{ sub IsRequestor
-
-=head2 IsRequestor
-  
-  Takes an email address, RT::User object or integer (RT user id)
-  Returns true if the string is a requestor of the current ticket.
-
-
-=cut
-
-sub IsRequestor {
-    my $self = shift;
-    my $person = shift;
-
-    return ($self->IsWatcher(Type => 'Requestor', Id => $person));
-           
-};
-
-# }}}
-
-# {{{ sub IsCc
-
-=head2 IsCc
-
-Takes a string. Returns true if the string is a Cc watcher of the current ticket.
-
-=cut
-
-sub IsCc {
-  my $self = shift;
-  my $cc = shift;
-  
-  return ($self->IsWatcher( Type => 'Cc', Id => $cc ));
-  
-}
-
-# }}}
-
-# {{{ sub IsAdminCc
-
-=head2 IsAdminCc
-
-Takes a string. Returns true if the string is an AdminCc watcher of the current ticket.
-
-=cut
-
-sub IsAdminCc {
-  my $self = shift;
-  my $person = shift;
-  
-  return ($self->IsWatcher( Type => 'AdminCc', Id => $person ));
-  
-}
-
-# }}}
-
-# {{{ sub IsOwner
-
-=head2 IsOwner
-
-  Takes an RT::User object. Returns true if that user is this ticket's owner.
-returns undef otherwise
-
-=cut
-
-sub IsOwner {
-    my $self = shift;
-    my $person = shift;
-  
-
-    # no ACL check since this is used in acl decisions
-    # unless ($self->CurrentUserHasRight('ShowTicket')) {
-    #  return(undef);
-    #   }      
-
-    
-    #Tickets won't yet have owners when they're being created.
-    unless ($self->OwnerObj->id) {
-        return(undef);
-    }
-    
-    if ($person->id == $self->OwnerObj->id) {
-       return(1);
-    }
-    else {
-       return(undef);
-    }
-}
-
-
-# }}}
-
-# }}}
-
-# }}}
-
-# {{{ Routines dealing with queues 
-
-# {{{ sub ValidateQueue
-
-sub ValidateQueue {
-  my $self = shift;
-  my $Value = shift;
-  
-  #TODO I don't think this should be here. We shouldn't allow anything to have an undef queue,
-  if (!$Value) {
-    $RT::Logger->warning( " RT:::Queue::ValidateQueue called with a null value. this isn't ok.");
-    return (1);
-  }
-  
-  my $QueueObj = RT::Queue->new($self->CurrentUser);
-  my $id = $QueueObj->Load($Value);
-  
-  if ($id) {
-    return (1);
-  }
-  else {
-    return (undef);
-  }
-}
-
-# }}}
-
-# {{{ sub SetQueue  
-
-sub SetQueue {
-    my $self = shift;
-    my $NewQueue = shift;
-
-    #Redundant. ACL gets checked in _Set;
-    unless ($self->CurrentUserHasRight('ModifyTicket')) {
-       return (0, "Permission Denied");
-    }
-   
-    my $NewQueueObj = RT::Queue->new($self->CurrentUser);
-    $NewQueueObj->Load($NewQueue);
-    
-    unless ($NewQueueObj->Id()) {
-       return (0, "That queue does not exist");
-    }
-    
-    if ($NewQueueObj->Id == $self->QueueObj->Id) {
-       return (0, 'That is the same value');
-    }
-    unless ($self->CurrentUser->HasQueueRight(Right =>'CreateTicket',
-                                             QueueObj => $NewQueueObj )) {
-       return (0, "You may not create requests in that queue.");
-    }
-    
-    unless ($self->OwnerObj->HasQueueRight(Right=> 'OwnTicket',  
-                                          QueueObj => $NewQueueObj)) {
-           $self->Untake();
-    }
-
-    return($self->_Set(Field => 'Queue', Value => $NewQueueObj->Id()));
-    
-}
-
-# }}}
-
-# {{{ sub QueueObj
-
-=head2 QueueObj
-
-Takes nothing. returns this ticket's queue object
 
 =cut
 
 sub QueueObj {
-    my $self = shift;
-    
-    my $queue_obj = RT::Queue->new($self->CurrentUser);
-    #We call __Value so that we can avoid the ACL decision and some deep recursion
-    my ($result) = $queue_obj->Load($self->__Value('Queue'));
-    return ($queue_obj);
+       my $self = shift;
+       my $Queue =  RT::Queue->new($self->CurrentUser);
+       $Queue->Load($self->__Value('Queue'));
+       return($Queue);
 }
 
+=item Type
 
-# }}}
+Returns the current value of Type. 
+(In the database, Type is stored as varchar(16).)
 
-# }}}
 
-# {{{ Date printing routines
 
-# {{{ sub DueObj
-
-=head2 DueObj
-
-  Returns an RT::Date object containing this ticket's due date
-
-=cut
-sub DueObj {
-    my $self = shift;
-    
-    my $time = new RT::Date($self->CurrentUser);
-
-    # -1 is RT::Date slang for never
-    if ($self->Due) {
-       $time->Set(Format => 'sql', Value => $self->Due );
-    }
-    else {
-       $time->Set(Format => 'unix', Value => -1);
-    }
-    
-    return $time;
-}
-# }}}
+=item SetType VALUE
 
-# {{{ sub DueAsString 
 
-=head2 DueAsString
+Set Type to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Type will be stored as a varchar(16).)
 
-Returns this ticket's due date as a human readable string
 
 =cut
 
-sub DueAsString {
-  my $self = shift;
-  return $self->DueObj->AsString();
-}
-
-# }}}
 
-# {{{ sub GraceTimeAsString 
+=item IssueStatement
 
-=head2 GraceTimeAsString
+Returns the current value of IssueStatement. 
+(In the database, IssueStatement is stored as int(11).)
 
-Return the time until this ticket is due as a string
-
-=cut
-
-# TODO This should be deprecated 
-
-sub GraceTimeAsString {
-    my $self=shift;
-    
-    if ($self->Due) {
-       return ($self->DueObj->AgeAsString());
-    } else {
-       return "";
-    }
-}
 
-# }}}
 
+=item SetIssueStatement VALUE
 
-# {{{ sub ResolvedObj
 
-=head2 ResolvedObj
+Set IssueStatement to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, IssueStatement will be stored as a int(11).)
 
-  Returns an RT::Date object of this ticket's 'resolved' time.
 
 =cut
 
-sub ResolvedObj {
-  my $self = shift;
 
-  my $time = new RT::Date($self->CurrentUser);
-  $time->Set(Format => 'sql', Value => $self->Resolved);
-  return $time;
-}
-# }}}
+=item Resolution
 
-# {{{ sub SetStarted
+Returns the current value of Resolution. 
+(In the database, Resolution is stored as int(11).)
 
-=head2 SetStarted
 
-Takes a date in ISO format or undef
-Returns a transaction id and a message
-The client calls "Start" to note that the project was started on the date in $date.
-A null date means "now"
 
-=cut
-  
-sub SetStarted {
-    my $self = shift;
-    my $time = shift || 0;
-    
-
-    unless ($self->CurrentUserHasRight('ModifyTicket')) {
-       return (0, "Permission Denied");
-    }
-
-    #We create a date object to catch date weirdness
-    my $time_obj = new RT::Date($self->CurrentUser());
-    if ($time != 0)  {
-       $time_obj->Set(Format => 'ISO', Value => $time);
-    }
-    else {
-       $time_obj->SetToNow();
-    }
-    
-    #Now that we're starting, open this ticket
-    #TODO do we really want to force this as policy? it should be a scrip
-    
-    #We need $TicketAsSystem, in case the current user doesn't have
-    #ShowTicket
-    #
-    my $TicketAsSystem = new RT::Ticket($RT::SystemUser);
-    $TicketAsSystem->Load($self->Id);  
-    if ($TicketAsSystem->Status eq 'new') {
-       $TicketAsSystem->Open();
-    }  
-    
-    return ($self->_Set(Field => 'Started', Value =>$time_obj->ISO));
-    
-}
+=item SetResolution VALUE
 
-# }}}
 
-# {{{ sub StartedObj
+Set Resolution to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Resolution will be stored as a int(11).)
 
-=head2 StartedObj
-
-  Returns an RT::Date object which contains this ticket's 
-'Started' time.
 
 =cut
 
 
-sub StartedObj {
-    my $self = shift;
-    
-    my $time = new RT::Date($self->CurrentUser);
-    $time->Set(Format => 'sql', Value => $self->Started);
-    return $time;
-}
-# }}}
+=item Owner
 
-# {{{ sub StartsObj
+Returns the current value of Owner. 
+(In the database, Owner is stored as int(11).)
 
-=head2 StartsObj
 
-  Returns an RT::Date object which contains this ticket's 
-'Starts' time.
 
-=cut
-
-sub StartsObj {
-  my $self = shift;
-  
-  my $time = new RT::Date($self->CurrentUser);
-  $time->Set(Format => 'sql', Value => $self->Starts);
-  return $time;
-}
-# }}}
+=item SetOwner VALUE
 
-# {{{ sub ToldObj
 
-=head2 ToldObj
+Set Owner to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Owner will be stored as a int(11).)
 
-  Returns an RT::Date object which contains this ticket's 
-'Told' time.
 
 =cut
 
 
-sub ToldObj {
-  my $self = shift;
-  
-  my $time = new RT::Date($self->CurrentUser);
-  $time->Set(Format => 'sql', Value => $self->Told);
-  return $time;
-}
+=item Subject
 
-# }}}
+Returns the current value of Subject. 
+(In the database, Subject is stored as varchar(200).)
 
-# {{{ sub LongSinceToldAsString
 
-# TODO this should be deprecated
 
+=item SetSubject VALUE
 
-sub LongSinceToldAsString {
-  my $self = shift;
-
-  if ($self->Told) {
-      return $self->ToldObj->AgeAsString();
-  } else {
-      return "Never";
-  }
-}
-# }}}
-
-# {{{ sub ToldAsString
 
-=head2 ToldAsString
+Set Subject to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Subject will be stored as a varchar(200).)
 
-A convenience method that returns ToldObj->AsString
-
-TODO: This should be deprecated
 
 =cut
 
 
-sub ToldAsString {
-    my $self = shift;
-    if ($self->Told) {
-       return $self->ToldObj->AsString();
-    }
-    else {
-       return("Never");
-    }
-}
-# }}}
-
-# {{{ sub TimeWorkedAsString
+=item InitialPriority
 
-=head2 TimeWorkedAsString
+Returns the current value of InitialPriority. 
+(In the database, InitialPriority is stored as int(11).)
 
-Returns the amount of time worked on this ticket as a Text String
 
-=cut
 
-sub TimeWorkedAsString {
-    my $self=shift;
-    return "0" unless $self->TimeWorked;
-    
-    #This is not really a date object, but if we diff a number of seconds 
-    #vs the epoch, we'll get a nice description of time worked.
-    
-    my $worked = new RT::Date($self->CurrentUser);
-    #return the  #of minutes worked turned into seconds and written as
-    # a simple text string
-
-    return($worked->DurationAsString($self->TimeWorked*60));
-}
+=item SetInitialPriority VALUE
 
-# }}}
 
+Set InitialPriority to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, InitialPriority will be stored as a int(11).)
 
-# }}}
-
-# {{{ Routines dealing with correspondence/comments
-
-# {{{ sub Comment
-
-=head2 Comment
-
-Comment on this ticket.
-Takes a hashref with the follwoing attributes:
-
-MIMEObj, TimeTaken, CcMessageTo, BccMessageTo
 
 =cut
 
-sub Comment {
-  my $self = shift;
-  
-  my %args = (
-          CcMessageTo => undef,
-          BccMessageTo => undef,
-             MIMEObj => undef,
-             TimeTaken => 0,
-             @_ );
-
-  unless (($self->CurrentUserHasRight('CommentOnTicket')) or
-         ($self->CurrentUserHasRight('ModifyTicket'))) {
-      return (0, "Permission Denied");
-  }
-   unless ($args{'MIMEObj'}) {
-       return(0,"No correspondence attached");
-   }
-
-  # If we've been passed in CcMessageTo and BccMessageTo fields,
-  # add them to the mime object for passing on to the transaction handler
-  # The "NotifyOtherRecipients" scripAction will look for RT--Send-Cc: and
-  # RT-Send-Bcc: headers
-  $args{'MIMEObj'}->head->add('RT-Send-Cc', $args{'CcMessageTo'});
-  $args{'MIMEObj'}->head->add('RT-Send-Bcc', $args{'BccMessageTo'});
-
-  #Record the correspondence (write the transaction)
-  my ($Trans, $Msg, $TransObj) = $self->_NewTransaction( Type => 'Comment',
-                                     Data =>($args{'MIMEObj'}->head->get('subject') || 'No Subject'),
-                                     TimeTaken => $args{'TimeTaken'},
-                                     MIMEObj => $args{'MIMEObj'}
-                                   );
-  
-  
-  return ($Trans, "The comment has been recorded");
-}
-
-# }}}
 
-# {{{ sub Correspond
+=item FinalPriority
 
-=head2 Correspond
+Returns the current value of FinalPriority. 
+(In the database, FinalPriority is stored as int(11).)
 
-Correspond on this ticket.
-Takes a hashref with the following attributes:
-
-
-MIMEObj, TimeTaken, CcMessageTo, BccMessageTo
-
-=cut
-
-sub Correspond {
-    my $self = shift;
-    my %args = (
-          CcMessageTo => undef,
-          BccMessageTo => undef,
-               MIMEObj => undef,
-               TimeTaken => 0,
-               @_ );
-    
-    unless (($self->CurrentUserHasRight('ReplyToTicket')) or
-           ($self->CurrentUserHasRight('ModifyTicket'))) {
-       return (0, "Permission Denied");
-    }
-    
-    unless ($args{'MIMEObj'}) {
-       return(0,"No correspondence attached");
-    }
-    
-  # If we've been passed in CcMessageTo and BccMessageTo fields,
-  # add them to the mime object for passing on to the transaction handler
-  # The "NotifyOtherRecipients" scripAction will look for RT-Send-Cc: and RT-Send-Bcc:
-  # headers
-  $args{'MIMEObj'}->head->add('RT-Send-Cc', $args{'CcMessageTo'});
-  $args{'MIMEObj'}->head->add('RT-Send-Bcc', $args{'BccMessageTo'});
-
-    #Record the correspondence (write the transaction)
-    my ($Trans,$msg, $TransObj) = $self->_NewTransaction
-      (Type => 'Correspond',
-       Data => ($args{'MIMEObj'}->head->get('subject') || 'No Subject'),
-       TimeTaken => $args{'TimeTaken'},
-       MIMEObj=> $args{'MIMEObj'}     
-      );
-    
-    # TODO this bit of logic should really become a scrip for 2.2
-    my $TicketAsSystem = new RT::Ticket($RT::SystemUser);
-    $TicketAsSystem->Load($self->Id);
-       
-    if (
-       ($TicketAsSystem->Status ne 'open') and
-       ($TicketAsSystem->Status ne 'new')
-       ) {
-       
-       my $oldstatus = $TicketAsSystem->Status();
-       $TicketAsSystem->__Set(Field => 'Status', Value => 'open');
-       $TicketAsSystem->_NewTransaction 
-         ( Type => 'Set',
-           Field => 'Status',
-           OldValue => $oldstatus,
-           NewValue => 'open',
-           Data => 'Ticket auto-opened on incoming correspondence'
-         );
-    }
-    
-    unless ($Trans) {
-       $RT::Logger->err("$self couldn't init a transaction ($msg)\n");
-       return ($Trans, "correspondence (probably) not sent", $args{'MIMEObj'});
-    }
-    
-    #Set the last told date to now if this isn't mail from the requestor.
-    #TODO: Note that this will wrongly ack mail from any non-requestor as a "told"
-    
-    unless ($TransObj->IsInbound) {
-       $self->_SetTold;
-    }
-    
-    return ($Trans, "correspondence sent");
-}
 
-# }}}
 
-# }}}
+=item SetFinalPriority VALUE
 
-# {{{ Routines dealing with Links and Relations between tickets
 
-# {{{ Link Collections
+Set FinalPriority to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, FinalPriority will be stored as a int(11).)
 
-# {{{ sub Members
-
-=head2 Members
-
-  This returns an RT::Links object which references all the tickets 
-which are 'MembersOf' this ticket
 
 =cut
 
-sub Members {
-   my $self = shift;
-   return ($self->_Links('Target', 'MemberOf'));
-}
-
-# }}}
 
-# {{{ sub MemberOf
+=item Priority
 
-=head2 MemberOf
+Returns the current value of Priority. 
+(In the database, Priority is stored as int(11).)
 
-  This returns an RT::Links object which references all the tickets that this
-ticket is a 'MemberOf'
 
-=cut
-
-sub MemberOf {
-   my $self = shift;
-   return ($self->_Links('Base', 'MemberOf'));
-}
 
-# }}}
+=item SetPriority VALUE
 
-# {{{ RefersTo
 
-=head2 RefersTo
+Set Priority to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Priority will be stored as a int(11).)
 
-  This returns an RT::Links object which shows all references for which this ticket is a base
 
 =cut
 
-sub RefersTo {
-    my $self = shift;
-    return ($self->_Links('Base', 'RefersTo'));
-}
-
-# }}}
 
-# {{{ ReferredToBy
+=item TimeEstimated
 
-=head2 ReferredToBy
+Returns the current value of TimeEstimated. 
+(In the database, TimeEstimated is stored as int(11).)
 
-  This returns an RT::Links object which shows all references for which this ticket is a target
 
-=cut
 
-sub ReferredToBy {
-    my $self = shift;
-    return ($self->_Links('Target', 'RefersTo'));
-}
+=item SetTimeEstimated VALUE
 
-# }}}
 
-# {{{ DependedOnBy
+Set TimeEstimated to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, TimeEstimated will be stored as a int(11).)
 
-=head2 DependedOnBy
-
-  This returns an RT::Links object which references all the tickets that depend on this one
 
 =cut
-sub DependedOnBy {
-    my $self = shift;
-    return ($self->_Links('Target','DependsOn'));
-}
-
-# }}}
-
-# {{{ DependsOn
-
-=head2 DependsOn
-
-  This returns an RT::Links object which references all the tickets that this ticket depends on
-
-=cut
-sub DependsOn {
-   my $self = shift;
-    return ($self->_Links('Base','DependsOn'));
-}
-
-# }}}
-
-# {{{ sub _Links 
-
-sub _Links {
-    my $self = shift;
-    
-    #TODO: Field isn't the right thing here. but I ahave no idea what mnemonic ---
-    #tobias meant by $f
-    my $field = shift;
-    my $type =shift || "";
-
-    unless ($self->{"$field$type"}) {
-       $self->{"$field$type"} = new RT::Links($self->CurrentUser);
-       if ($self->CurrentUserHasRight('ShowTicket')) {
-           
-           $self->{"$field$type"}->Limit(FIELD=>$field, VALUE=>$self->URI);
-           $self->{"$field$type"}->Limit(FIELD=>'Type', 
-                                         VALUE=>$type) if ($type);
-       }
-    }
-    return ($self->{"$field$type"});
-}
-
-# }}}
-
-# }}}
 
 
-# {{{ sub DeleteLink 
+=item TimeWorked
 
-=head2 DeleteLink
+Returns the current value of TimeWorked. 
+(In the database, TimeWorked is stored as int(11).)
 
-Delete a link. takes a paramhash of Base, Target and Type.
-Either Base or Target must be null. The null value will 
-be replaced with this ticket\'s id
 
-=cut 
 
-sub DeleteLink {
-    my $self = shift;
-    my %args = ( Base =>  undef,
-                Target => undef,
-                Type => undef,
-                @_ );
-    
-    #check acls
-    unless ($self->CurrentUserHasRight('ModifyTicket')) {
-        $RT::Logger->debug("No permission to delete links\n"); 
-        return (0, 'Permission Denied');
-
-    
-    }
-    
-    #we want one of base and target. we don't care which
-    #but we only want _one_
-
-    if ($args{'Base'} and $args{'Target'}) {
-       $RT::Logger->debug("$self ->_DeleteLink. got both Base and Target\n");
-       return (0, 'Can\'t specifiy both base and target');
-    }
-    elsif ($args{'Base'}) {
-       $args{'Target'} = $self->Id();
-    }
-    elsif ($args{'Target'}) {
-       $args{'Base'} = $self->Id();
-    }
-    else {  
-        $RT::Logger->debug("$self: Base or Target must be specified\n");
-       return (0, 'Either base or target must be specified');
-    }
-     
-    my $link = new RT::Link($self->CurrentUser);
-    $RT::Logger->debug("Trying to load link: ". $args{'Base'}." ". $args{'Type'}. " ". $args{'Target'}. "\n");
-    
-    $link->Load($args{'Base'}, $args{'Type'}, $args{'Target'});
-    
-    
-    
-    #it's a real link. 
-    if ($link->id) {
-        $RT::Logger->debug("We're going to delete link ".$link->id."\n");
-       $link->Delete();
-
-       my $TransString=
-         "Ticket $args{'Base'} no longer $args{Type} ticket $args{'Target'}.";
-       my ($Trans, $Msg, $TransObj) = $self->_NewTransaction
-         (Type => 'DeleteLink',
-          Field => $args{'Type'},
-          Data => $TransString,
-          TimeTaken => 0
-         );
-       
-       return ($linkid, "Link deleted ($TransString)", $transactionid);
-    }
-    #if it's not a link we can find
-    else {
-        $RT::Logger->debug("Couldn't find that link\n");
-       return (0, "Link not found");
-    }
-}
+=item SetTimeWorked VALUE
 
-# }}}
 
-# {{{ sub AddLink
-
-=head2 AddLink
-
-Takes a paramhash of Type and one of Base or Target. Adds that link to this ticket.
+Set TimeWorked to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, TimeWorked will be stored as a int(11).)
 
 
 =cut
 
-sub AddLink {
-    my $self = shift;
-    my %args = ( Target => '',
-                Base => '',
-                Type => '',
-                @_ );
-    
-    unless ($self->CurrentUserHasRight('ModifyTicket')) {
-       return (0, "Permission Denied");
-    }
-    
-    if ($args{'Base'} and $args{'Target'}) {
-       $RT::Logger->debug("$self tried to delete a link. both base and target were specified\n");
-       return (0, 'Can\'t specifiy both base and target');
-    }
-    elsif ($args{'Base'}) {
-        $args{'Target'} = $self->Id();
-    }
-    elsif ($args{'Target'}) {
-       $args{'Base'} = $self->Id();
-    }
-    else {  
-       return (0, 'Either base or target must be specified');
-    }
-    
-    # {{{ We don't want references to ourself
-    if ($args{Base} eq $args{Target}) {
-       return (0, "Can\'t link a ticket to itself");
-    }  
-               
-    # }}}
-    
-    # If the base isn't a URI, make it a URI. 
-    # If the target isn't a URI, make it a URI. 
-        
-    # {{{ Check if the link already exists - we don't want duplicates
-    my $old_link= new RT::Link ($self->CurrentUser);
-    $old_link->Load($args{'Base'}, $args{'Type'}, $args{'Target'});
-    if ($old_link->Id) {
-       $RT::Logger->debug("$self Somebody tried to duplicate a link");
-       return ($old_link->id, "Link already exists",0);
-    }
-    # }}}
-    
-    # Storing the link in the DB.
-    my $link = RT::Link->new($self->CurrentUser);
-    my ($linkid) = $link->Create(Target => $args{Target}, 
-                                Base => $args{Base}, 
-                                Type => $args{Type});
-    
-    unless ($linkid) {
-       return (0,"Link could not be created");
-    }
-       #Write the transaction
-    
-    my $TransString="Ticket $args{'Base'} $args{Type} ticket $args{'Target'}.";
-    
-    my ($Trans, $Msg, $TransObj) = $self->_NewTransaction
-      (Type => 'AddLink',
-       Field => $args{'Type'},
-       Data => $TransString,
-       TimeTaken => 0
-      );
-    
-    return ($Trans, "Link created ($TransString)");
-       
-       
-}
-# }}}
 
-# {{{ sub URI 
+=item Status
 
-=head2 URI
+Returns the current value of Status. 
+(In the database, Status is stored as varchar(10).)
 
-Returns this ticket's URI
 
-=cut
 
-sub URI {
-    my $self = shift;
-    return $RT::TicketBaseURI.$self->id;
-}
+=item SetStatus VALUE
 
-# }}}
 
-# {{{ sub MergeInto
+Set Status to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Status will be stored as a varchar(10).)
 
-=head2 MergeInto
-MergeInto take the id of the ticket to merge this ticket into.
 
 =cut
 
-sub MergeInto {
-    my $self = shift;
-    my $MergeInto = shift;
-    
-    unless ($self->CurrentUserHasRight('ModifyTicket')) {
-       return (0, "Permission Denied");
-    }
-    
-    # Load up the new ticket.
-    my $NewTicket = RT::Ticket->new($RT::SystemUser);
-    $NewTicket->Load($MergeInto);
-
-    # make sure it exists.
-    unless (defined $NewTicket->Id) {
-       return (0, 'New ticket doesn\'t exist');
-    }
-
-    
-    # Make sure the current user can modify the new ticket.
-    unless ($NewTicket->CurrentUserHasRight('ModifyTicket')) {
-       $RT::Logger->debug("failed...");
-       return (0, "Permission Denied");
-    }
-    
-    $RT::Logger->debug("checking if the new ticket has the same id and effective id...");
-    unless ($NewTicket->id == $NewTicket->EffectiveId) {
-       $RT::Logger->err('$self trying to merge into '.$NewTicket->Id .
-                        ' which is itself merged.\n');
-       return (0, "Can't merge into a merged ticket. ".
-               "You should never get this error");
-    }
-
-    
-    # We use EffectiveId here even though it duplicates information from
-    # the links table becasue of the massive performance hit we'd take
-    # by trying to do a seperate database query for merge info everytime 
-    # loaded a ticket. 
-    
-    
-    #update this ticket's effective id to the new ticket's id.
-    my ($id_val, $id_msg) = $self->__Set(Field => 'EffectiveId', 
-                                        Value => $NewTicket->Id());
-    
-    unless ($id_val) {
-       $RT::Logger->error("Couldn't set effective ID for ".$self->Id.
-                          ": $id_msg");
-       return(0,"Merge failed. Couldn't set EffectiveId");
-    }
-    
-    my ($status_val, $status_msg) = $self->__Set(Field => 'Status',
-                                                Value => 'resolved');
-    
-    unless ($status_val) {
-       $RT::Logger->error("$self couldn't set status to resolved.".
-                          "RT's Database may be inconsistent.");
-    }      
-    
-    #make a new link: this ticket is merged into that other ticket.
-    $self->AddLink( Type =>'MergedInto',
-                   Target => $NewTicket->Id() );
-    
-    #add all of this ticket's watchers to that ticket.
-    my $watchers = $self->Watchers();
-    
-    while (my $watcher = $watchers->Next()) {
-       unless (
-               ($watcher->Owner && 
-               $NewTicket->IsWatcher (Type => $watcher->Type,
-                                      Id => $watcher->Owner)) or 
-               ($watcher->Email && 
-                $NewTicket->IsWatcher (Type => $watcher->Type,
-                                       Id => $watcher->Email)) 
-              ) {
-           
-           
-           
-           $NewTicket->_AddWatcher(Silent => 1, 
-                                   Type => $watcher->Type, 
-                                   Email => $watcher->Email,
-                                   Owner => $watcher->Owner);
-       }
-    }
-    
-    
-    #find all of the tickets that were merged into this ticket. 
-    my $old_mergees = new RT::Tickets($self->CurrentUser);
-    $old_mergees->Limit( FIELD => 'EffectiveId',
-                        OPERATOR => '=',
-                        VALUE => $self->Id );
-    
-    #   update their EffectiveId fields to the new ticket's id
-    while (my $ticket = $old_mergees->Next()) {
-       my ($val, $msg) = $ticket->__Set(Field => 'EffectiveId', 
-                                        Value => $NewTicket->Id());
-    }  
-    $NewTicket->_SetLastUpdated;
-
-    return ($TransactionObj, "Merge Successful");
-}  
-
-# }}}
-
-# }}}
-
-# {{{ Routines dealing with keywords
-
-# {{{ sub KeywordsObj
-
-=head2 KeywordsObj [KEYWORD_SELECT_ID]
-
-  Returns an B<RT::ObjectKeywords> object preloaded with this ticket's ObjectKeywords.
-If the optional KEYWORD_SELECT_ID parameter is set, limit the keywords object to that keyword
-select.
-
-=cut
-
-sub KeywordsObj {
-    my $self = shift;
-    my $keyword_select; 
-    
-    $keyword_select = shift if (@_);
-    
-    use RT::ObjectKeywords;
-    my $Keywords = new RT::ObjectKeywords($self->CurrentUser);
-
-    #ACL check
-    if ($self->CurrentUserHasRight('ShowTicket')) {
-       $Keywords->LimitToTicket($self->id);
-       if ($keyword_select) {
-           $Keywords->LimitToKeywordSelect($keyword_select);
-       }       
-    }
-    return ($Keywords);
-}
-# }}}
 
-# {{{ sub AddKeyword
+=item TimeLeft
 
-=head2 AddKeyword
+Returns the current value of TimeLeft. 
+(In the database, TimeLeft is stored as int(11).)
 
-Takes a paramhash of Keyword and KeywordSelect.  If Keyword is a valid choice
-for KeywordSelect, creates a KeywordObject.  If the KeywordSelect says this should
-be a single KeywordObject, automatically removes the old value.
 
- Issues: probably doesn't enforce the depth restrictions or make sure that keywords
-are coming from the right part of the tree. really should.
 
-=cut
+=item SetTimeLeft VALUE
 
-sub AddKeyword {
-    my $self = shift;
-   #ACL check
-    unless ($self->CurrentUserHasRight('ModifyTicket')) {
-       return (0, 'Permission Denied');
-    }
-    
-    return($self->_AddKeyword(@_));
-    
-}
 
+Set TimeLeft to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, TimeLeft will be stored as a int(11).)
 
-# Helper version of AddKeyword without that pesky ACL check
-sub _AddKeyword {
-    my $self = shift;
-    my %args = ( KeywordSelect => undef,  # id of a keyword select record
-                Keyword => undef, #id of the keyword to add
-                Silent => 0,
-                @_
-              );
-    
-    my ($OldValue);
-
-    #TODO make sure that $args{'Keyword'} is valid for $args{'KeywordSelect'}
-
-    #TODO: make sure that $args{'KeywordSelect'} applies to this ticket's queue.
-    
-    my $Keyword = new RT::Keyword($self->CurrentUser);
-    unless ($Keyword->Load($args{'Keyword'}) ) {
-       $RT::Logger->err("$self Couldn't load Keyword ".$args{'Keyword'} ."\n");
-       return(0, "Couldn't load keyword");
-    }
-    
-    my $KeywordSelectObj = new RT::KeywordSelect($self->CurrentUser);
-    unless ($KeywordSelectObj->Load($args{'KeywordSelect'})) {
-       $RT::Logger->err("$self Couldn't load KeywordSelect ".$args{'KeywordSelect'});
-       return(0, "Couldn't load keywordselect");
-    }
-    
-    my $Keywords = $self->KeywordsObj($KeywordSelectObj->id);
-
-    #If the ticket already has this keyword, just get out of here.
-    if ($Keywords->HasEntry($Keyword->id)) {
-       return(0, "That is already the current value");
-    }  
-
-    #If the keywordselect wants this to be a singleton:
-
-    if ($KeywordSelectObj->Single) {
-
-       #Whack any old values...keep track of the last value that we get.
-       #we shouldn't need a loop ehre, but we do it anyway, to try to 
-       # help keep the database clean.
-       while (my $OldKey = $Keywords->Next) {
-           $OldValue = $OldKey->KeywordObj->Name;
-           $OldKey->Delete();
-       }       
-       
-       
-    }
-
-    # create the new objectkeyword 
-    my $ObjectKeyword = new RT::ObjectKeyword($self->CurrentUser);
-    my $result = $ObjectKeyword->Create( Keyword => $Keyword->Id,
-                                        ObjectType => 'Ticket',
-                                        ObjectId => $self->Id,
-                                        KeywordSelect => $KeywordSelectObj->Id );
-    
-
-    # record a single transaction, unless we were told not to
-    unless ($args{'Silent'}) {
-       my ($TransactionId, $Msg, $TransactionObj) = 
-         $self->_NewTransaction( Type => 'Keyword',
-                                 Field => $KeywordSelectObj->Id,
-                                 OldValue => $OldValue,
-                                 NewValue => $Keyword->Name );
-    }
-    return ($TransactionId, "Keyword ".$ObjectKeyword->KeywordObj->Name ." added.");    
-
-}      
-
-# }}}
-
-# {{{ sub DeleteKeyword
-
-=head2 DeleteKeyword
-  
-  Takes a paramhash. Deletes the Keyword denoted by the I<Keyword> parameter from this
-  ticket's object keywords.
 
 =cut
 
-sub DeleteKeyword {
-    my $self = shift;
-    my %args = ( Keyword => undef,
-                KeywordSelect => undef,
-                @_ );
-
-   #ACL check
-    unless ($self->CurrentUserHasRight('ModifyTicket')) {    
-       return (0, 'Permission Denied');
-    }
-
-    
-    #Load up the ObjectKeyword we\'re talking about
-    my $ObjectKeyword = new RT::ObjectKeyword($self->CurrentUser);
-    $ObjectKeyword->LoadByCols(Keyword => $args{'Keyword'},
-                              KeywordSelect => $args{'KeywordSelect'},
-                              ObjectType => 'Ticket',
-                              ObjectId => $self->id()
-                             );
-    
-    #if we can\'t find it, bail
-    unless ($ObjectKeyword->id) {
-       $RT::Logger->err("Couldn't find the keyword ".$args{'Keyword'} .
-                        " for keywordselect ". $args{'KeywordSelect'} . 
-                        "for ticket ".$self->id );
-       return (undef, "Couldn't load keyword while trying to delete it.");
-    };
-    
-    #record transaction here.
-    my ($TransactionId, $Msg, $TransObj) = 
-      $self->_NewTransaction( Type => 'Keyword', 
-                             OldValue => $ObjectKeyword->KeywordObj->Name);
-    
-    $ObjectKeyword->Delete();
-    
-    return ($TransactionId, "Keyword ".$ObjectKeyword->KeywordObj->Name ." deleted.");
-    
-}
 
-# }}}
+=item Told
 
-# }}}
+Returns the current value of Told. 
+(In the database, Told is stored as datetime.)
 
-# {{{ Routines dealing with ownership
 
-# {{{ sub OwnerObj
 
-=head2 OwnerObj
+=item SetTold VALUE
 
-Takes nothing and returns an RT::User object of 
-this ticket's owner
 
-=cut
+Set Told to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Told will be stored as a datetime.)
 
-sub OwnerObj {
-    my $self = shift;
-    
-    #If this gets ACLed, we lose on a rights check in User.pm and
-    #get deep recursion. if we need ACLs here, we need
-    #an equiv without ACLs
-    
-    $owner = new RT::User ($self->CurrentUser);
-    $owner->Load($self->__Value('Owner'));
-    
-    #Return the owner object
-    return ($owner);
-}
-
-# }}}
-
-# {{{ sub OwnerAsString 
-
-=head2 OwnerAsString
-
-Returns the owner's email address
 
 =cut
 
-sub OwnerAsString {
-  my $self = shift;
-  return($self->OwnerObj->EmailAddress);
 
-}
+=item Starts
 
-# }}}
+Returns the current value of Starts. 
+(In the database, Starts is stored as datetime.)
 
-# {{{ sub SetOwner
 
-=head2 SetOwner
-
-Takes two arguments:
-     the Id or Name of the owner 
-and  (optionally) the type of the SetOwner Transaction. It defaults
-to 'Give'.  'Steal' is also a valid option.
-
-=cut
-
-sub SetOwner {
-    my $self = shift;
-    my $NewOwner = shift;
-    my $Type = shift || "Give";
-    
-    unless ($self->CurrentUserHasRight('ModifyTicket')) {
-       return (0, "Permission Denied");
-    }  
-    
-    my $NewOwnerObj = RT::User->new($self->CurrentUser);
-    my $OldOwnerObj = $self->OwnerObj;
-  
-    $NewOwnerObj->Load($NewOwner);
-    if (!$NewOwnerObj->Id) {
-           return (0, "That user does not exist");
-    }
-    
-    #If thie ticket has an owner and it's not the current user
-    
-    if (($Type ne 'Steal' ) and ($Type ne 'Force') and #If we're not stealing
-       ($self->OwnerObj->Id != $RT::Nobody->Id ) and #and the owner is set
-       ($self->CurrentUser->Id ne $self->OwnerObj->Id())) { #and it's not us
-       return(0, "You can only reassign tickets that you own or that are unowned");
-    }
-    
-    #If we've specified a new owner and that user can't modify the ticket
-    elsif (($NewOwnerObj->Id) and 
-          (!$NewOwnerObj->HasQueueRight(Right => 'OwnTicket',
-                                        QueueObj => $self->QueueObj,
-                                        TicketObj => $self))
-         ) {
-       return (0, "That user may not own requests in that queue");
-    }
-  
-  
-    #If the ticket has an owner and it's the new owner, we don't need
-    #To do anything
-    elsif (($self->OwnerObj) and ($NewOwnerObj->Id eq $self->OwnerObj->Id)) {
-       return(0, "That user already owns that request");
-    }
-  
-  
-    my ($trans,$msg)=$self->_Set(Field => 'Owner',
-                                Value => $NewOwnerObj->Id, 
-                                TimeTaken => 0,
-                                TransactionType => $Type);
-  
-    if ($trans) {
-       $msg = "Owner changed from ".$OldOwnerObj->Name." to ".$NewOwnerObj->Name;
-    }
-    return ($trans, $msg);
-         
-}
 
-# }}}
+=item SetStarts VALUE
 
-# {{{ sub Take
 
-=head2 Take
+Set Starts to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Starts will be stored as a datetime.)
 
-A convenince method to set the ticket's owner to the current user
 
 =cut
 
-sub Take {
-    my $self = shift;
-    return ($self->SetOwner($self->CurrentUser->Id, 'Take'));
-}
 
-# }}}
+=item Started
 
-# {{{ sub Untake
+Returns the current value of Started. 
+(In the database, Started is stored as datetime.)
 
-=head2 Untake
 
-Convenience method to set the owner to 'nobody' if the current user is the owner.
 
-=cut
+=item SetStarted VALUE
 
-sub Untake {
-    my $self = shift;
-    return($self->SetOwner($RT::Nobody->UserObj->Id, 'Untake'));
-}
-# }}}
-
-# {{{ sub Steal 
 
-=head2 Steal
+Set Started to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Started will be stored as a datetime.)
 
-A convenience method to change the owner of the current ticket to the
-current user. Even if it's owned by another user.
 
 =cut
 
-sub Steal {
-    my $self = shift;
-  
-    if ($self->IsOwner($self->CurrentUser)) {
-       return (0,"You already own this ticket"); 
-    } else {
-       return($self->SetOwner($self->CurrentUser->Id, 'Steal'));
-      
-    }
-  
-}
-
-# }}}
-
-# }}}
 
-# {{{ Routines dealing with status
+=item Due
 
-# {{{ sub ValidateStatus 
+Returns the current value of Due. 
+(In the database, Due is stored as datetime.)
 
-=head2 ValidateStatus STATUS
 
-Takes a string. Returns true if that status is a valid status for this ticket.
-Returns false otherwise.
 
-=cut
-
-sub ValidateStatus {
-    my $self = shift;
-    my $status = shift;
+=item SetDue VALUE
 
-    #Make sure the status passed in is valid
-    unless ($self->QueueObj->IsValidStatus($status)) {
-       return (undef);
-    }
-    
-    return (1);
 
-}
+Set Due to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Due will be stored as a datetime.)
 
 
-# }}}
+=cut
 
-# {{{ sub SetStatus
 
-=head2 SetStatus STATUS
+=item Resolved
 
-Set this ticket\'s status. STATUS can be one of: new, open, stalled, resolved or dead.
+Returns the current value of Resolved. 
+(In the database, Resolved is stored as datetime.)
 
-=cut
 
-sub SetStatus { 
-    my $self = shift;
-    my $status = shift;
-
-    #Check ACL
-    unless ($self->CurrentUserHasRight('ModifyTicket')) {
-       return (0, 'Permission Denied');
-    }
-
-    my $now = new RT::Date($self->CurrentUser);
-    $now->SetToNow();
-    
-    #If we're changing the status from new, record that we've started
-    if (($self->Status =~ /new/) && ($status ne 'new')) {
-       #Set the Started time to "now"
-       $self->_Set(Field => 'Started',
-                   Value => $now->ISO,
-                   RecordTransaction => 0);
-    }
-    
-
-    if ($status eq 'resolved') {
-       #When we resolve a ticket, set the 'Resolved' attribute to now.
-       $self->_Set(Field => 'Resolved',
-                   Value => $now->ISO, 
-                   RecordTransaction => 0);
-    }
-    
-    
-    #Actually update the status
-    return($self->_Set(Field => 'Status', 
-                      Value => $status,
-                      TimeTaken => 0,
-                      TransactionType => 'Status'));
-}
 
-# }}}
+=item SetResolved VALUE
 
-# {{{ sub Kill
 
-=head2 Kill
+Set Resolved to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Resolved will be stored as a datetime.)
 
-Takes no arguments. Marks this ticket for garbage collection
 
 =cut
 
-sub Kill {
-  my $self = shift;
-  return ($self->SetStatus('dead'));
-  # TODO: garbage collection
-}
-
-# }}}
 
-# {{{ sub Stall
+=item LastUpdatedBy
 
-=head2 Stall
+Returns the current value of LastUpdatedBy. 
+(In the database, LastUpdatedBy is stored as int(11).)
 
-Sets this ticket's status to stalled
 
 =cut
 
-sub Stall {
-  my $self = shift;
-  return ($self->SetStatus('stalled'));
-}
-
-# }}}
 
-# {{{ sub Open
+=item LastUpdated
 
-=head2 Open
+Returns the current value of LastUpdated. 
+(In the database, LastUpdated is stored as datetime.)
 
-Sets this ticket\'s status to Open
 
 =cut
 
-sub Open {
-    my $self = shift;
-    return ($self->SetStatus('open'));
-}
-
-# }}}
 
-# {{{ sub Resolve
+=item Creator
 
-=head2 Resolve
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
 
-Sets this ticket\'s status to Resolved
 
 =cut
 
-sub Resolve {
-    my $self = shift;
-    return ($self->SetStatus('resolved'));
-}
-
-# }}}
-
-# }}}
-
-# {{{ Actions + Routines dealing with transactions
 
-# {{{ sub SetTold and _SetTold
+=item Created
 
-=head2 SetTold ISO  [TIMETAKEN]
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
 
-Updates the told and records a transaction
 
 =cut
 
-sub SetTold {
-    my $self=shift;
-    my $told;
-    $told = shift if (@_);
-    my $timetaken=shift || 0;
-   
-    unless ($self->CurrentUserHasRight('ModifyTicket')) {
-       return (0, "Permission Denied");
-    }
-
-    my $datetold = new RT::Date($self->CurrentUser);
-    if ($told) {
-       $datetold->Set( Format => 'iso',
-                       Value => $told);
-    }
-    else {
-        $datetold->SetToNow(); 
-    }
-    
-    return($self->_Set(Field => 'Told', 
-                      Value => $datetold->ISO,
-                      TimeTaken => $timetaken,
-                      TransactionType => 'Told'));
-}
 
-=head2 _SetTold
+=item Disabled
 
-Updates the told without a transaction or acl check. Useful when we're sending replies.
+Returns the current value of Disabled. 
+(In the database, Disabled is stored as smallint(6).)
 
-=cut
 
-sub _SetTold {
-    my $self=shift;
-    
-    my $now = new RT::Date($self->CurrentUser);
-    $now->SetToNow();
-    #use __Set to get no ACLs ;)
-    return($self->__Set(Field => 'Told',
-                       Value => $now->ISO));
-}
 
-# }}}
+=item SetDisabled VALUE
 
-# {{{ sub Transactions 
 
-=head2 Transactions
+Set Disabled to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Disabled will be stored as a smallint(6).)
 
-  Returns an RT::Transactions object of all transactions on this ticket
 
 =cut
-  
-sub Transactions {
-    my $self = shift;
-    
-    use RT::Transactions;
-    my $transactions = RT::Transactions->new($self->CurrentUser);
-
-    #If the user has no rights, return an empty object
-    if ($self->CurrentUserHasRight('ShowTicket')) {
-       my $tickets = $transactions->NewAlias('Tickets');
-       $transactions->Join( ALIAS1 => 'main',
-                             FIELD1 => 'Ticket',
-                             ALIAS2 => $tickets,
-                             FIELD2 => 'id');
-       $transactions->Limit( ALIAS => $tickets,
-                             FIELD => 'EffectiveId',
-                             VALUE => $self->id());
-        # if the user may not see comments do not return them
-        unless ($self->CurrentUserHasRight('ShowTicketComments')) {
-            $transactions->Limit( FIELD => 'Type',
-                                  OPERATOR => '!=',
-                                  VALUE => "Comment");
-        }
-    }
-    
-    return($transactions);
-}
-
-# }}}
-
-# {{{ sub _NewTransaction
-
-sub _NewTransaction {
-    my $self = shift;
-    my %args = ( TimeTaken => 0,
-                Type => undef,
-                OldValue => undef,
-                NewValue => undef,
-                Data => undef,
-                Field => undef,
-                MIMEObj => undef,
-                @_ );
-    
-    
-    require RT::Transaction;
-    my $trans = new RT::Transaction($self->CurrentUser);
-    my ($transaction, $msg) = 
-      $trans->Create( Ticket => $self->Id,
-                     TimeTaken => $args{'TimeTaken'},
-                     Type => $args{'Type'},
-                     Data => $args{'Data'},
-                     Field => $args{'Field'},
-                     NewValue => $args{'NewValue'},
-                     OldValue => $args{'OldValue'},
-                     MIMEObj => $args{'MIMEObj'}
-                   );
-    
-    $RT::Logger->warning($msg) unless $transaction;
-    
-    $self->_SetLastUpdated;
-    
-    if (defined $args{'TimeTaken'} ) {
-       $self->_UpdateTimeTaken($args{'TimeTaken'}); 
-    }
-    return($transaction, $msg, $trans);
-}
 
-# }}}
 
-# }}}
-
-# {{{ PRIVATE UTILITY METHODS. Mostly needed so Ticket can be a DBIx::Record
-
-# {{{ sub _ClassAccessible
 
 sub _ClassAccessible {
     {
-       EffectiveId => { 'read' => 1, 'write' => 1, 'public' => 1 },
-       Queue => { 'read' => 1, 'write' => 1 },
-       Requestors => { 'read' => 1, 'write' => 1 },
-       Owner => { 'read' => 1, 'write' => 1 },
-       Subject => { 'read' => 1, 'write' => 1 },
-       InitialPriority => { 'read' => 1, 'write' => 1 },
-       FinalPriority => { 'read' => 1, 'write' => 1 },
-       Priority => { 'read' => 1, 'write' => 1 },
-       Status => { 'read' => 1, 'write' => 1 },
-       TimeWorked => { 'read' => 1, 'write' => 1 },
-       TimeLeft => { 'read' => 1, 'write' => 1 },
-       Created => { 'read' => 1, 'auto' => 1 },
-       Creator => { 'read' => 1,  'auto' => 1 },
-       Told => { 'read' => 1, 'write' => 1 },
-       Resolved => {'read' => 1},
-       Starts => { 'read' => 1, 'write' => 1 },
-       Started => { 'read' => 1, 'write' => 1 },
-       Due => { 'read' => 1, 'write' => 1 },
-       Creator => { 'read' => 1, 'auto' => 1 },
-       Created => { 'read' => 1, 'auto' => 1 },
-       LastUpdatedBy => { 'read' => 1, 'auto' => 1 },
-       LastUpdated => { 'read' => 1, 'auto' => 1 }
-    };
-
-}    
-
-# }}}
-
-# {{{ sub _Set
-
-sub _Set {
-    my $self = shift;
-    
-    unless ($self->CurrentUserHasRight('ModifyTicket')) {
-       return (0, "Permission Denied");
-    }
-    
-    my %args = (Field => undef,
-               Value => undef,
-               TimeTaken => 0,
-               RecordTransaction => 1,
-               TransactionType => 'Set',
-               @_
-              );
-    #if the user is trying to modify the record
-    
-    #Take care of the old value we really don't want to get in an ACL loop.
-    # so ask the super::_Value
-    my $Old=$self->SUPER::_Value("$args{'Field'}");
-    
-    #Set the new value
-    my ($ret, $msg)=$self->SUPER::_Set(Field => $args{'Field'}, 
-                                      Value=> $args{'Value'});
-    
-    #If we can't actually set the field to the value, don't record
-    # a transaction. instead, get out of here.
-    if ($ret==0) {return (0,$msg);}
-    
-    if ($args{'RecordTransaction'} == 1) {
-       
-       my ($Trans, $Msg, $TransObj) =  
-         $self->_NewTransaction(Type => $args{'TransactionType'},
-                                Field => $args{'Field'},
-                                NewValue => $args{'Value'},
-                                OldValue =>  $Old,
-                                TimeTaken => $args{'TimeTaken'},
-                               );
-      return ($Trans,$TransObj->Description);
-    }
-    else {
-       return ($ret, $msg);
-  }
-}
-
-# }}}
-
-# {{{ sub _Value 
-
-=head2 _Value
-
-Takes the name of a table column.
-Returns its value as a string, if the user passes an ACL check
-
-=cut
-
-sub _Value  {
-
-  my $self = shift;
-  my $field = shift;
-
-  
-  #if the field is public, return it.
-  if ($self->_Accessible($field, 'public')) {
-      #$RT::Logger->debug("Skipping ACL check for $field\n");
-      return($self->SUPER::_Value($field));
-      
-  }
-  
-  #If the current user doesn't have ACLs, don't let em at it.  
-  
-  unless ($self->CurrentUserHasRight('ShowTicket')) {
-      return (undef);
-  }
-  return($self->SUPER::_Value($field));
-  
-}
-
-# }}}
-
-# {{{ sub _UpdateTimeTaken
-
-=head2 _UpdateTimeTaken
-
-This routine will increment the timeworked counter. it should
-only be called from _NewTransaction 
-
-=cut
-
-sub _UpdateTimeTaken {
-  my $self = shift;
-  my $Minutes = shift;
-  my ($Total);
-   
-  $Total = $self->SUPER::_Value("TimeWorked");
-  $Total = ($Total || 0) + ($Minutes || 0);
-  $self->SUPER::_Set(Field => "TimeWorked", 
-                    Value => $Total);
-
-  return ($Total);
-}
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        EffectiveId => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Queue => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Type => 
+               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+        IssueStatement => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Resolution => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Owner => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Subject => 
+               {read => 1, write => 1, type => 'varchar(200)', default => '[no subject]'},
+        InitialPriority => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        FinalPriority => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Priority => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        TimeEstimated => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        TimeWorked => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Status => 
+               {read => 1, write => 1, type => 'varchar(10)', default => ''},
+        TimeLeft => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Told => 
+               {read => 1, write => 1, type => 'datetime', default => ''},
+        Starts => 
+               {read => 1, write => 1, type => 'datetime', default => ''},
+        Started => 
+               {read => 1, write => 1, type => 'datetime', default => ''},
+        Due => 
+               {read => 1, write => 1, type => 'datetime', default => ''},
+        Resolved => 
+               {read => 1, write => 1, type => 'datetime', default => ''},
+        LastUpdatedBy => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        LastUpdated => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        Disabled => 
+               {read => 1, write => 1, type => 'smallint(6)', default => '0'},
+
+ }
+};
 
-# }}}
 
-# }}}
+        eval "require RT::Ticket_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Ticket_Overlay.pm}) {
+            die $@;
+        };
 
-# {{{ Routines dealing with ACCESS CONTROL
+        eval "require RT::Ticket_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Ticket_Vendor.pm}) {
+            die $@;
+        };
 
-# {{{ sub CurrentUserHasRight 
+        eval "require RT::Ticket_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Ticket_Local.pm}) {
+            die $@;
+        };
 
-=head2 CurrentUserHasRight
 
-  Takes the textual name of a Ticket scoped right (from RT::ACE) and returns
-1 if the user has that right. It returns 0 if the user doesn't have that right.
 
-=cut
 
-sub CurrentUserHasRight {
-  my $self = shift;
-  my $right = shift;
-  
-  return ($self->HasRight( Principal=> $self->CurrentUser->UserObj(),
-                           Right => "$right"));
+=head1 SEE ALSO
 
-}
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
 
-# }}}
+These overlay files can contain new subs or subs to replace existing subs in this module.
 
-# {{{ sub HasRight 
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
 
-=head2 HasRight
+   no warnings qw(redefine);
 
- Takes a paramhash with the attributes 'Right' and 'Principal'
-  'Right' is a ticket-scoped textual right from RT::ACE 
-  'Principal' is an RT::User object
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
 
-  Returns 1 if the principal has the right. Returns undef if not.
+RT::Ticket_Overlay, RT::Ticket_Vendor, RT::Ticket_Local
 
 =cut
 
-sub HasRight {
-    my $self = shift;
-    my %args = ( Right => undef,
-                Principal => undef,
-                @_);
-    
-    unless ((defined $args{'Principal'}) and (ref($args{'Principal'}))) {
-       $RT::Logger->warning("Principal attrib undefined for Ticket::HasRight");
-    }
-    
-    return($args{'Principal'}->HasQueueRight(TicketObj => $self,
-                                            Right => $args{'Right'}));
-}
-
-# }}}
-
-# }}}
-
 
 1;
-
-=head1 AUTHOR
-
-Jesse Vincent, jesse@fsck.com
-
-=head1 SEE ALSO
-
-RT
-
-=cut
-
-
diff --git a/rt/lib/RT/TicketCustomFieldValue.pm b/rt/lib/RT/TicketCustomFieldValue.pm
new file mode 100644 (file)
index 0000000..862a5dc
--- /dev/null
@@ -0,0 +1,286 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
+
+=head1 NAME
+
+RT::TicketCustomFieldValue
+
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+=cut
+
+package RT::TicketCustomFieldValue;
+use RT::Record; 
+use RT::CustomField;
+use RT::Ticket;
+
+
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
+
+sub _Init {
+  my $self = shift; 
+
+  $self->Table('TicketCustomFieldValues');
+  $self->SUPER::_Init(@_);
+}
+
+
+
+
+
+=item Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+  int(11) 'Ticket'.
+  int(11) 'CustomField'.
+  varchar(255) 'Content'.
+
+=cut
+
+
+
+
+sub Create {
+    my $self = shift;
+    my %args = ( 
+                Ticket => '0',
+                CustomField => '0',
+                Content => '',
+
+                 @_);
+    $self->SUPER::Create(
+                         Ticket => $args{'Ticket'},
+                         CustomField => $args{'CustomField'},
+                         Content => $args{'Content'},
+);
+
+}
+
+
+
+=item id
+
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
+
+
+=cut
+
+
+=item Ticket
+
+Returns the current value of Ticket. 
+(In the database, Ticket is stored as int(11).)
+
+
+
+=item SetTicket VALUE
+
+
+Set Ticket to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Ticket will be stored as a int(11).)
+
+
+=cut
+
+
+=item TicketObj
+
+Returns the Ticket Object which has the id returned by Ticket
+
+
+=cut
+
+sub TicketObj {
+       my $self = shift;
+       my $Ticket =  RT::Ticket->new($self->CurrentUser);
+       $Ticket->Load($self->__Value('Ticket'));
+       return($Ticket);
+}
+
+=item CustomField
+
+Returns the current value of CustomField. 
+(In the database, CustomField is stored as int(11).)
+
+
+
+=item SetCustomField VALUE
+
+
+Set CustomField to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, CustomField will be stored as a int(11).)
+
+
+=cut
+
+
+=item CustomFieldObj
+
+Returns the CustomField Object which has the id returned by CustomField
+
+
+=cut
+
+sub CustomFieldObj {
+       my $self = shift;
+       my $CustomField =  RT::CustomField->new($self->CurrentUser);
+       $CustomField->Load($self->__Value('CustomField'));
+       return($CustomField);
+}
+
+=item Content
+
+Returns the current value of Content. 
+(In the database, Content is stored as varchar(255).)
+
+
+
+=item SetContent VALUE
+
+
+Set Content to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Content will be stored as a varchar(255).)
+
+
+=cut
+
+
+=item Creator
+
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
+
+
+=cut
+
+
+=item Created
+
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
+
+
+=cut
+
+
+=item LastUpdatedBy
+
+Returns the current value of LastUpdatedBy. 
+(In the database, LastUpdatedBy is stored as int(11).)
+
+
+=cut
+
+
+=item LastUpdated
+
+Returns the current value of LastUpdated. 
+(In the database, LastUpdated is stored as datetime.)
+
+
+=cut
+
+
+
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        Ticket => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        CustomField => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Content => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        LastUpdatedBy => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        LastUpdated => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+
+ }
+};
+
+
+        eval "require RT::TicketCustomFieldValue_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/TicketCustomFieldValue_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::TicketCustomFieldValue_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/TicketCustomFieldValue_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::TicketCustomFieldValue_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/TicketCustomFieldValue_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::TicketCustomFieldValue_Overlay, RT::TicketCustomFieldValue_Vendor, RT::TicketCustomFieldValue_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/TicketCustomFieldValue_Overlay.pm b/rt/lib/RT/TicketCustomFieldValue_Overlay.pm
new file mode 100644 (file)
index 0000000..c395eca
--- /dev/null
@@ -0,0 +1,52 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+use strict;
+no warnings qw(redefine);
+
+
+
+=head2 LoadByTicketContentAndCustomField { Ticket => TICKET, CustomField => CUSTOMFIELD, Content => CONTENT }
+
+Loads a custom field value by Ticket, Content and which CustomField it's tied to
+
+=cut
+
+
+sub LoadByTicketContentAndCustomField {
+    my $self = shift;
+    my %args = ( Ticket => undef,
+                CustomField => undef,
+                Content => undef,
+                @_
+                );
+
+
+    $self->LoadByCols( Content => $args{'Content'},
+                         CustomField => $args{'CustomField'},
+                         Ticket => $args{'Ticket'});
+
+    
+}
+
+1;
diff --git a/rt/lib/RT/TicketCustomFieldValues.pm b/rt/lib/RT/TicketCustomFieldValues.pm
new file mode 100644 (file)
index 0000000..f137f53
--- /dev/null
@@ -0,0 +1,115 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
+
+=head1 NAME
+
+  RT::TicketCustomFieldValues -- Class Description
+=head1 SYNOPSIS
+
+  use RT::TicketCustomFieldValues
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=cut
+
+package RT::TicketCustomFieldValues;
+
+use RT::SearchBuilder;
+use RT::TicketCustomFieldValue;
+
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
+
+
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'TicketCustomFieldValues';
+    $self->{'primary_key'} = 'id';
+
+
+    return ( $self->SUPER::_Init(@_) );
+}
+
+
+=item NewItem
+
+Returns an empty new RT::TicketCustomFieldValue item
+
+=cut
+
+sub NewItem {
+    my $self = shift;
+    return(RT::TicketCustomFieldValue->new($self->CurrentUser));
+}
+
+        eval "require RT::TicketCustomFieldValues_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/TicketCustomFieldValues_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::TicketCustomFieldValues_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/TicketCustomFieldValues_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::TicketCustomFieldValues_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/TicketCustomFieldValues_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::TicketCustomFieldValues_Overlay, RT::TicketCustomFieldValues_Vendor, RT::TicketCustomFieldValues_Local
+
+=cut
+
+
+1;
diff --git a/rt/lib/RT/TicketCustomFieldValues_Overlay.pm b/rt/lib/RT/TicketCustomFieldValues_Overlay.pm
new file mode 100644 (file)
index 0000000..5777c37
--- /dev/null
@@ -0,0 +1,86 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+use strict;
+no warnings qw(redefine);
+
+# {{{ sub LimitToCustomField
+
+=head2 LimitToCustomField FIELD
+
+Limits the returned set to values for the custom field with Id FIELD
+
+=cut
+  
+sub LimitToCustomField {
+    my $self = shift;
+    my $cf = shift;
+    return ($self->Limit( FIELD => 'CustomField',
+                         VALUE => $cf,
+                         OPERATOR => '='));
+
+}
+
+# }}}
+
+# {{{ sub LimitToTicket
+
+=head2 LimitToTicket TICKETID
+
+Limits the returned set to values for the ticket with Id TICKETID
+
+=cut
+  
+sub LimitToTicket {
+    my $self = shift;
+    my $ticket = shift;
+    return ($self->Limit( FIELD => 'Ticket',
+                         VALUE => $ticket,
+                         OPERATOR => '='));
+
+}
+
+# }}}
+
+
+=sub HasEntry VALUE
+
+Returns true if this CustomFieldValues collection has an entry with content that eq VALUE
+
+=cut
+
+
+sub HasEntry {
+    my $self = shift;
+    my $value = shift;
+
+    #TODO: this could cache and optimize a fair bit.
+    foreach my $item (@{$self->ItemsArrayRef}) {
+        return(1) if ($item->Content eq $value);  
+    }
+    return undef;
+
+}
+
+1;
+
diff --git a/rt/lib/RT/Ticket_Overlay.pm b/rt/lib/RT/Ticket_Overlay.pm
new file mode 100644 (file)
index 0000000..c88bbc9
--- /dev/null
@@ -0,0 +1,4040 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# {{{ Front Material 
+
+=head1 SYNOPSIS
+
+  use RT::Ticket;
+  my $ticket = new RT::Ticket($CurrentUser);
+  $ticket->Load($ticket_id);
+
+=head1 DESCRIPTION
+
+This module lets you manipulate RT\'s ticket object.
+
+
+=head1 METHODS
+
+=begin testing
+
+use_ok ( RT::Queue);
+ok(my $testqueue = RT::Queue->new($RT::SystemUser));
+ok($testqueue->Create( Name => 'ticket tests'));
+ok($testqueue->Id != 0);
+use_ok(RT::CustomField);
+ok(my $testcf = RT::CustomField->new($RT::SystemUser));
+ok($testcf->Create( Name => 'selectmulti',
+                    Queue => $testqueue->id,
+                               Type => 'SelectMultiple'));
+ok($testcf->AddValue ( Name => 'Value1',
+                        SortOrder => '1',
+                        Description => 'A testing value'));
+ok($testcf->AddValue ( Name => 'Value2',
+                        SortOrder => '2',
+                        Description => 'Another testing value'));
+ok($testcf->AddValue ( Name => 'Value3',
+                        SortOrder => '3',
+                        Description => 'Yet Another testing value'));
+                       
+ok($testcf->Values->Count == 3);
+
+use_ok(RT::Ticket);
+
+my $u = RT::User->new($RT::SystemUser);
+$u->Load("root");
+ok ($u->Id, "Found the root user");
+ok(my $t = RT::Ticket->new($RT::SystemUser));
+ok(my ($id, $msg) = $t->Create( Queue => $testqueue->Id,
+               Subject => 'Testing',
+               Owner => $u->Id
+              ));
+ok($id != 0);
+ok ($t->OwnerObj->Id == $u->Id, "Root is the ticket owner");
+ok(my ($cfv, $cfm) =$t->AddCustomFieldValue(Field => $testcf->Id,
+                           Value => 'Value1'));
+ok($cfv != 0, "Custom field creation didn't return an error: $cfm");
+ok($t->CustomFieldValues($testcf->Id)->Count == 1);
+ok($t->CustomFieldValues($testcf->Id)->First &&
+    $t->CustomFieldValues($testcf->Id)->First->Content eq 'Value1');;
+
+ok(my ($cfdv, $cfdm) = $t->DeleteCustomFieldValue(Field => $testcf->Id,
+                        Value => 'Value1'));
+ok ($cfdv != 0, "Deleted a custom field value: $cfdm");
+ok($t->CustomFieldValues($testcf->Id)->Count == 0);
+
+ok(my $t2 = RT::Ticket->new($RT::SystemUser));
+ok($t2->Load($id));
+ok($t2->Subject eq 'Testing');
+ok($t2->QueueObj->Id eq $testqueue->id);
+ok($t2->OwnerObj->Id == $u->Id);
+
+my $t3 = RT::Ticket->new($RT::SystemUser);
+my ($id3, $msg3) = $t3->Create( Queue => $testqueue->Id,
+                                Subject => 'Testing',
+                                Owner => $u->Id);
+my ($cfv1, $cfm1) = $t->AddCustomFieldValue(Field => $testcf->Id,
+ Value => 'Value1');
+ok($cfv1 != 0, "Adding a custom field to ticket 1 is successful: $cfm");
+my ($cfv2, $cfm2) = $t3->AddCustomFieldValue(Field => $testcf->Id,
+ Value => 'Value2');
+ok($cfv2 != 0, "Adding a custom field to ticket 2 is successful: $cfm");
+my ($cfv3, $cfm3) = $t->AddCustomFieldValue(Field => $testcf->Id,
+ Value => 'Value3');
+ok($cfv3 != 0, "Adding a custom field to ticket 1 is successful: $cfm");
+ok($t->CustomFieldValues($testcf->Id)->Count == 2,
+   "This ticket has 2 custom field values");
+ok($t3->CustomFieldValues($testcf->Id)->Count == 1,
+   "This ticket has 1 custom field value");
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+use RT::Queue;
+use RT::User;
+use RT::Record;
+use RT::Links;
+use RT::Date;
+use RT::CustomFields;
+use RT::TicketCustomFieldValues;
+use RT::Tickets;
+use RT::URI::fsck_com_rt;
+use RT::URI;
+
+=begin testing
+
+
+ok(require RT::Ticket, "Loading the RT::Ticket library");
+
+=end testing
+
+=cut
+
+# }}}
+
+# {{{ LINKTYPEMAP
+# A helper table for relationships mapping to make it easier
+# to build and parse links between tickets
+
+use vars '%LINKTYPEMAP';
+
+%LINKTYPEMAP = (
+    MemberOf => { Type => 'MemberOf',
+                  Mode => 'Target', },
+    Members => { Type => 'MemberOf',
+                 Mode => 'Base', },
+    HasMember => { Type => 'MemberOf',
+                   Mode => 'Base', },
+    RefersTo => { Type => 'RefersTo',
+                  Mode => 'Target', },
+    ReferredToBy => { Type => 'RefersTo',
+                      Mode => 'Base', },
+    DependsOn => { Type => 'DependsOn',
+                   Mode => 'Target', },
+    DependedOnBy => { Type => 'DependsOn',
+                      Mode => 'Base', },
+
+);
+
+# }}}
+
+# {{{ LINKDIRMAP
+# A helper table for relationships mapping to make it easier
+# to build and parse links between tickets
+
+use vars '%LINKDIRMAP';
+
+%LINKDIRMAP = (
+    MemberOf => { Base => 'MemberOf',
+                  Target => 'HasMember', },
+    RefersTo => { Base => 'RefersTo',
+                Target => 'ReferredToBy', },
+    DependsOn => { Base => 'DependsOn',
+                   Target => 'DependedOnBy', },
+
+);
+
+# }}}
+
+# {{{ sub Load
+
+=head2 Load
+
+Takes a single argument. This can be a ticket id, ticket alias or 
+local ticket uri.  If the ticket can't be loaded, returns undef.
+Otherwise, returns the ticket id.
+
+=cut
+
+sub Load {
+    my $self = shift;
+    my $id   = shift;
+
+    #TODO modify this routine to look at EffectiveId and do the recursive load
+    # thing. be careful to cache all the interim tickets we try so we don't loop forever.
+
+    #If it's a local URI, turn it into a ticket id
+    if ( $id =~ /^$RT::TicketBaseURI(\d+)$/ ) {
+        $id = $1;
+    }
+
+    #If it's a remote URI, we're going to punt for now
+    elsif ( $id =~ '://' ) {
+        return (undef);
+    }
+
+    #If we have an integer URI, load the ticket
+    if ( $id =~ /^\d+$/ ) {
+        my $ticketid = $self->LoadById($id);
+
+        unless ($ticketid) {
+            $RT::Logger->debug("$self tried to load a bogus ticket: $id\n");
+            return (undef);
+        }
+    }
+
+    #It's not a URI. It's not a numerical ticket ID. Punt!
+    else {
+        return (undef);
+    }
+
+    #If we're merged, resolve the merge.
+    if ( ( $self->EffectiveId ) and ( $self->EffectiveId != $self->Id ) ) {
+        return ( $self->Load( $self->EffectiveId ) );
+    }
+
+    #Ok. we're loaded. lets get outa here.
+    return ( $self->Id );
+
+}
+
+# }}}
+
+# {{{ sub LoadByURI
+
+=head2 LoadByURI
+
+Given a local ticket URI, loads the specified ticket.
+
+=cut
+
+sub LoadByURI {
+    my $self = shift;
+    my $uri  = shift;
+
+    if ( $uri =~ /^$RT::TicketBaseURI(\d+)$/ ) {
+        my $id = $1;
+        return ( $self->Load($id) );
+    }
+    else {
+        return (undef);
+    }
+}
+
+# }}}
+
+# {{{ sub Create
+
+=head2 Create (ARGS)
+
+Arguments: ARGS is a hash of named parameters.  Valid parameters are:
+
+  id 
+  Queue  - Either a Queue object or a Queue Name
+  Requestor -  A reference to a list of RT::User objects, email addresses or RT user Names
+  Cc  - A reference to a list of RT::User objects, email addresses or Names
+  AdminCc  - A reference to a  list of RT::User objects, email addresses or Names
+  Type -- The ticket\'s type. ignore this for now
+  Owner -- This ticket\'s owner. either an RT::User object or this user\'s id
+  Subject -- A string describing the subject of the ticket
+  InitialPriority -- an integer from 0 to 99
+  FinalPriority -- an integer from 0 to 99
+  Status -- any valid status (Defined in RT::Queue)
+  TimeEstimated -- an integer. estimated time for this task in minutes
+  TimeWorked -- an integer. time worked so far in minutes
+  TimeLeft -- an integer. time remaining in minutes
+  Starts -- an ISO date describing the ticket\'s start date and time in GMT
+  Due -- an ISO date describing the ticket\'s due date and time in GMT
+  MIMEObj -- a MIME::Entity object with the content of the initial ticket request.
+  CustomField-<n> -- a scalar or array of values for the customfield with the id <n>
+
+
+Returns: TICKETID, Transaction Object, Error Message
+
+
+=begin testing
+
+my $t = RT::Ticket->new($RT::SystemUser);
+
+ok( $t->Create(Queue => 'General', Due => '2002-05-21 00:00:00', ReferredToBy => 'http://www.cpan.org', RefersTo => 'http://fsck.com', Subject => 'This is a subject'), "Ticket Created");
+
+ok ( my $id = $t->Id, "Got ticket id");
+ok ($t->RefersTo->First->Target =~ /fsck.com/, "Got refers to");
+ok ($t->ReferredToBy->First->Base =~ /cpan.org/, "Got referredtoby");
+ok ($t->ResolvedObj->Unix == -1, "It hasn't been resolved - ". $t->ResolvedObj->Unix);
+
+=end testing
+
+=cut
+
+sub Create {
+    my $self = shift;
+
+    my %args = ( id              => undef,
+                 Queue           => undef,
+                 Requestor       => undef,
+                 Cc              => undef,
+                 AdminCc         => undef,
+                 Type            => 'ticket',
+                 Owner           => undef,
+                 Subject         => '',
+                 InitialPriority => undef,
+                 FinalPriority   => undef,
+                 Status          => 'new',
+                 TimeWorked      => "0",
+                 TimeLeft        => 0,
+                 TimeEstimated        => 0,
+                 Due             => undef,
+                 Starts          => undef,
+                 Started         => undef,
+                 Resolved        => undef,
+                 MIMEObj         => undef,
+                 _RecordTransaction => 1,
+                 
+
+
+                 @_ );
+
+    my ( $ErrStr, $Owner, $resolved );
+    my (@non_fatal_errors);
+
+    my $QueueObj = RT::Queue->new($RT::SystemUser);
+
+    
+    if ( ( defined( $args{'Queue'} ) ) && ( !ref( $args{'Queue'} ) ) ) {
+        $QueueObj->Load( $args{'Queue'} );
+    }
+    elsif ( ref( $args{'Queue'} ) eq 'RT::Queue' ) {
+        $QueueObj->Load( $args{'Queue'}->Id );
+    }
+    else {
+        $RT::Logger->debug( $args{'Queue'} . " not a recognised queue object.");
+    }
+;
+
+    #Can't create a ticket without a queue.
+    unless ( defined($QueueObj) && $QueueObj->Id ) {
+        $RT::Logger->debug("$self No queue given for ticket creation.");
+        return ( 0, 0, $self->loc('Could not create ticket. Queue not set') );
+    }
+
+    #Now that we have a queue, Check the ACLS
+    unless ( $self->CurrentUser->HasRight( Right    => 'CreateTicket',
+                                                Object => $QueueObj )
+      ) {
+        return ( 0, 0,
+                 $self->loc( "No permission to create tickets in the queue '[_1]'", $QueueObj->Name ) );
+    }
+
+    unless ( $QueueObj->IsValidStatus( $args{'Status'} ) ) {
+        return ( 0, 0, $self->loc('Invalid value for status') );
+    }
+
+
+    #Since we have a queue, we can set queue defaults
+    #Initial Priority
+
+    # If there's no queue default initial priority and it's not set, set it to 0
+    $args{'InitialPriority'} = ( $QueueObj->InitialPriority || 0 )
+      unless ( defined $args{'InitialPriority'} );
+
+    #Final priority 
+
+    # If there's no queue default final priority and it's not set, set it to 0
+    $args{'FinalPriority'} = ( $QueueObj->FinalPriority || 0 )
+      unless ( defined $args{'FinalPriority'} );
+
+    # {{{ Dates
+    #TODO we should see what sort of due date we're getting, rather +
+    # than assuming it's in ISO format.
+
+    #Set the due date. if we didn't get fed one, use the queue default due in
+    my $Due = new RT::Date( $self->CurrentUser );
+
+    if ( $args{'Due'} ) {
+        $Due->Set( Format => 'ISO', Value  => $args{'Due'} );
+    }
+    elsif (  $QueueObj->DefaultDueIn  ) {
+        $Due->SetToNow;
+        $Due->AddDays( $QueueObj->DefaultDueIn );
+    }
+
+    my $Starts = new RT::Date( $self->CurrentUser );
+    if ( defined $args{'Starts'} ) {
+        $Starts->Set( Format => 'ISO', Value  => $args{'Starts'} );
+    }
+
+    my $Started = new RT::Date( $self->CurrentUser );
+    if ( defined $args{'Started'} ) {
+        $Started->Set( Format => 'ISO', Value  => $args{'Started'} );
+    }
+
+    my $Resolved = new RT::Date( $self->CurrentUser );
+    if ( defined $args{'Resolved'} ) {
+        $Resolved->Set( Format => 'ISO', Value  => $args{'Resolved'} );
+    }
+
+
+    #If the status is an inactive status, set the resolved date
+    if ($QueueObj->IsInactiveStatus($args{'Status'}) && !$args{'Resolved'}) {
+        $RT::Logger->debug("Got a ".$args{'Status'} . "ticket with a resolved of ".$args{'Resolved'});
+        $Resolved->SetToNow;
+    }
+
+    # }}}
+
+    # {{{ Dealing with time fields
+
+    $args{'TimeEstimated'} = 0 unless defined $args{'TimeEstimated'};
+    $args{'TimeWorked'}    = 0 unless defined $args{'TimeWorked'};
+    $args{'TimeLeft'}      = 0 unless defined $args{'TimeLeft'};
+
+    # }}}
+
+    # {{{ Deal with setting the owner
+
+    if ( ref( $args{'Owner'} ) eq 'RT::User' ) {
+        $Owner = $args{'Owner'};
+    }
+
+    #If we've been handed something else, try to load the user.
+    elsif ( defined $args{'Owner'} ) {
+        $Owner = RT::User->new( $self->CurrentUser );
+        $Owner->Load( $args{'Owner'} );
+
+    }
+
+    #If we have a proposed owner and they don't have the right 
+    #to own a ticket, scream about it and make them not the owner
+    if (     ( defined($Owner) )
+         and ( $Owner->Id )
+         and ( $Owner->Id != $RT::Nobody->Id )
+         and ( !$Owner->HasRight( Object => $QueueObj,
+                                       Right    => 'OwnTicket' ) )
+      ) {
+
+        $RT::Logger->warning( "User "
+                              . $Owner->Name . "("
+                              . $Owner->id
+                              . ") was proposed "
+                              . "as a ticket owner but has no rights to own "
+                              . "tickets in ".$QueueObj->Name );
+
+        push @non_fatal_errors, $self->loc("Invalid owner. Defaulting to 'nobody'.");
+
+        $Owner = undef;
+    }
+
+    #If we haven't been handed a valid owner, make it nobody.
+    unless ( defined($Owner) && $Owner->Id ) {
+        $Owner = new RT::User( $self->CurrentUser );
+        $Owner->Load( $RT::Nobody->Id );
+    }
+
+    # }}}
+
+    # We attempt to load or create each of the people who might have a role for this ticket
+    # _outside_ the transaction, so we don't get into ticket creation races
+    foreach my $type ( "Cc", "AdminCc", "Requestor" ) {
+     next unless (defined $args{$type});
+        foreach my $watcher ( ref( $args{$type} ) ? @{ $args{$type} } : ( $args{$type} ) ) {
+        my $user = RT::User->new($RT::SystemUser);
+        $user->LoadOrCreateByEmail($watcher) if ($watcher !~ /^\d+$/);
+        }
+    }
+
+
+    $RT::Handle->BeginTransaction();
+
+    my %params =( Queue           => $QueueObj->Id,
+                                   Owner           => $Owner->Id,
+                                   Subject         => $args{'Subject'},
+                                   InitialPriority => $args{'InitialPriority'},
+                                   FinalPriority   => $args{'FinalPriority'},
+                                   Priority        => $args{'InitialPriority'},
+                                   Status          => $args{'Status'},
+                                   TimeWorked      => $args{'TimeWorked'},
+                                   TimeEstimated   => $args{'TimeEstimated'},
+                                   TimeLeft        => $args{'TimeLeft'},
+                                   Type            => $args{'Type'},
+                                   Starts          => $Starts->ISO,
+                                   Started         => $Started->ISO,
+                                   Resolved        => $Resolved->ISO,
+                                   Due             => $Due->ISO );
+
+    # Parameters passed in during an import that we probably don't want to touch, otherwise
+    foreach my $attr qw(id Creator Created LastUpdated LastUpdatedBy) {
+        $params{$attr} = $args{$attr} if ($args{$attr});
+    }
+
+    # Delete null integer parameters
+    foreach my $attr qw(TimeWorked TimeLeft TimeEstimated InitialPriority FinalPriority) {
+        delete $params{$attr}  unless (exists $params{$attr} && $params{$attr});
+    }
+
+
+    my $id = $self->SUPER::Create( %params);
+    unless ($id) {
+        $RT::Logger->crit( "Couldn't create a ticket");
+        $RT::Handle->Rollback();
+        return ( 0, 0, $self->loc( "Ticket could not be created due to an internal error") );
+    }
+
+    #Set the ticket's effective ID now that we've created it.
+    my ( $val, $msg ) = $self->__Set( Field => 'EffectiveId', Value => $id );
+
+    unless ($val) {
+        $RT::Logger->crit("$self ->Create couldn't set EffectiveId: $msg\n");
+        $RT::Handle->Rollback();
+        return ( 0, 0, $self->loc( "Ticket could not be created due to an internal error") );
+    }
+
+    my $create_groups_ret = $self->_CreateTicketGroups();
+    unless ($create_groups_ret) {
+        $RT::Logger->crit( "Couldn't create ticket groups for ticket "
+                           . $self->Id
+                           . ". aborting Ticket creation." );
+        $RT::Handle->Rollback();
+        return ( 0, 0,
+                 $self->loc( "Ticket could not be created due to an internal error") );
+    }
+
+    # Set the owner in the Groups table
+    # We denormalize it into the Ticket table too because doing otherwise would 
+    # kill performance, bigtime. It gets kept in lockstep thanks to the magic of transactionalization
+
+    $self->OwnerGroup->_AddMember( PrincipalId => $Owner->PrincipalId , InsideTransaction => 1);
+
+    # {{{ Deal with setting up watchers
+
+
+    foreach my $type ( "Cc", "AdminCc", "Requestor" ) {
+        next unless (defined $args{$type});
+        foreach my $watcher ( ref( $args{$type} ) ? @{ $args{$type} } : ( $args{$type} ) ) {
+
+           # we reason that all-digits number must be a principal id, not email
+           # this is the only way to can add
+           my $field = 'Email';
+           $field = 'PrincipalId' if $watcher =~ /^\d+$/;
+
+           my ( $wval, $wmsg );
+
+            if ( $type eq 'AdminCc' ) {
+
+                # Note that we're using AddWatcher, rather than _AddWatcher, as we 
+                # actually _want_ that ACL check. Otherwise, random ticket creators
+                # could make themselves adminccs and maybe get ticket rights. that would
+                # be poor
+                ( $wval, $wmsg ) = $self->AddWatcher( Type   => $type,
+                                                         $field => $watcher,
+                                                         Silent => 1 );
+            }
+            else {
+                ( $wval, $wmsg ) = $self->_AddWatcher( Type   => $type,
+                                                          $field => $watcher,
+                                                          Silent => 1 );
+            }
+
+            push @non_fatal_errors, $wmsg unless ($wval);
+        }
+    }
+
+    # }}}
+    # {{{ Deal with setting up links
+
+
+    foreach my $type ( keys %LINKTYPEMAP ) {
+        next unless (defined $args{$type});
+        foreach my $link (
+            ref( $args{$type} ) ? @{ $args{$type} } : ( $args{$type} ) )
+        {
+            my ( $wval, $wmsg ) = $self->AddLink(
+                Type                          => $LINKTYPEMAP{$type}->{'Type'},
+                $LINKTYPEMAP{$type}->{'Mode'} => $link,
+                Silent                        => 1
+            );
+
+            push @non_fatal_errors, $wmsg unless ($wval);
+        }
+    }
+
+    # }}}
+
+   # {{{ Add all the custom fields 
+
+    foreach my $arg ( keys %args ) {
+    next unless ( $arg =~ /^CustomField-(\d+)$/i );
+    my $cfid = $1;
+    foreach
+      my $value ( ref( $args{$arg} ) ? @{ $args{$arg} } : ( $args{$arg} ) ) {
+        next unless ($value);
+        $self->_AddCustomFieldValue( Field => $cfid,
+                                     Value => $value,
+                                     RecordTransaction => 0
+                                 );
+    }
+    }
+    # }}}
+
+    if ( $args{'_RecordTransaction'} ) {
+        # {{{ Add a transaction for the create
+        my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
+                                                     Type      => "Create",
+                                                     TimeTaken => 0,
+                                                     MIMEObj => $args{'MIMEObj'}
+        );
+
+
+        if ( $self->Id && $Trans ) {
+            $ErrStr = $self->loc( "Ticket [_1] created in queue '[_2]'", $self->Id, $QueueObj->Name );
+            $ErrStr = join ( "\n", $ErrStr, @non_fatal_errors );
+
+            $RT::Logger->info("Ticket ".$self->Id. " created in queue '".$QueueObj->Name."' by ".$self->CurrentUser->Name);
+        }
+        else {
+            $RT::Handle->Rollback();
+
+            # TODO where does this get errstr from?
+            $RT::Logger->error("Ticket couldn't be created: $ErrStr");
+            return ( 0, 0, $self->loc( "Ticket could not be created due to an internal error"));
+        }
+
+        $RT::Handle->Commit();
+        return ( $self->Id, $TransObj->Id, $ErrStr );
+        # }}}
+    }
+    else {
+
+        # Not going to record a transaction
+        $RT::Handle->Commit();
+        $ErrStr = $self->loc( "Ticket [_1] created in queue '[_2]'", $self->Id, $QueueObj->Name );
+        $ErrStr = join ( "\n", $ErrStr, @non_fatal_errors );
+        return ( $self->Id, $0, $ErrStr );
+
+    }
+}
+
+
+# }}}
+
+# {{{ sub CreateFromEmailMessage
+
+
+=head2 CreateFromEmailMessage { Message, Queue, ExtractActorFromHeaders } 
+
+This code replaces what was once a large part of the email gateway.
+It takes an email message as a parameter, parses out the sender, subject
+and a MIME object. It then creates a ticket based on those attributes
+
+=cut
+
+sub CreateFromEmailMessage {
+    my $self = shift;
+    my %args = ( Message => undef,
+                 Queue => undef,
+                 ExtractActorFromSender => undef,
+                 @_ );
+
+    
+    # Pull out requestor
+
+    # Pull out Cc?
+
+    # 
+
+
+}
+
+# }}}
+
+
+# {{{ CreateFrom822
+
+=head2 FORMAT
+
+CreateTickets uses the template as a template for an ordered set of tickets 
+to create. The basic format is as follows:
+
+
+ ===Create-Ticket: identifier
+ Param: Value
+ Param2: Value
+ Param3: Value
+ Content: Blah
+ blah
+ blah
+ ENDOFCONTENT
+=head2 Acceptable fields
+
+A complete list of acceptable fields for this beastie:
+
+
+    *  Queue           => Name or id# of a queue
+       Subject         => A text string
+       Status          => A valid status. defaults to 'new'
+
+       Due             => Dates can be specified in seconds since the epoch
+                          to be handled literally or in a semi-free textual
+                          format which RT will attempt to parse.
+       Starts          => 
+       Started         => 
+       Resolved        => 
+       Owner           => Username or id of an RT user who can and should own 
+                          this ticket
+   +   Requestor       => Email address
+   +   Cc              => Email address 
+   +   AdminCc         => Email address 
+       TimeWorked      => 
+       TimeEstimated   => 
+       TimeLeft        => 
+       InitialPriority => 
+       FinalPriority   => 
+       Type            => 
+    +  DependsOn       => 
+    +  DependedOnBy    =>
+    +  RefersTo        =>
+    +  ReferredToBy    => 
+    +  Members         =>
+    +  MemberOf        => 
+       Content         => content. Can extend to multiple lines. Everything
+                          within a template after a Content: header is treated
+                          as content until we hit a line containing only 
+                          ENDOFCONTENT
+       ContentType     => the content-type of the Content field
+       CustomField-<id#> => custom field value
+
+Fields marked with an * are required.
+
+Fields marked with a + man have multiple values, simply
+by repeating the fieldname on a new line with an additional value.
+
+
+When parsed, field names are converted to lowercase and have -s stripped.
+Refers-To, RefersTo, refersto, refers-to and r-e-f-er-s-tO will all 
+be treated as the same thing.
+
+
+=begin testing
+
+use_ok(RT::Ticket);
+
+=end testing
+
+
+=cut
+
+sub CreateFrom822 {
+    my $self    = shift;
+    my $content = shift;
+
+
+
+    my %args = $self->_Parse822HeadersForAttributes($content);
+
+    # Now we have a %args to work with.
+    # Make sure we have at least the minimum set of
+    # reasonable data and do our thang
+    my $ticket = RT::Ticket->new($RT::SystemUser);
+
+    my %ticketargs = (
+        Queue           => $args{'queue'},
+        Subject         => $args{'subject'},
+        Status          => $args{'status'},
+        Due             => $args{'due'},
+        Starts          => $args{'starts'},
+        Started         => $args{'started'},
+        Resolved        => $args{'resolved'},
+        Owner           => $args{'owner'},
+        Requestor       => $args{'requestor'},
+        Cc              => $args{'cc'},
+        AdminCc         => $args{'admincc'},
+        TimeWorked      => $args{'timeworked'},
+        TimeEstimated   => $args{'timeestimated'},
+        TimeLeft        => $args{'timeleft'},
+        InitialPriority => $args{'initialpriority'},
+        FinalPriority   => $args{'finalpriority'},
+        Type            => $args{'type'},
+        DependsOn       => $args{'dependson'},
+        DependedOnBy    => $args{'dependedonby'},
+        RefersTo        => $args{'refersto'},
+        ReferredToBy    => $args{'referredtoby'},
+        Members         => $args{'members'},
+        MemberOf        => $args{'memberof'},
+        MIMEObj         => $args{'mimeobj'}
+    );
+
+    # Add custom field entries to %ticketargs.
+    # TODO: allow named custom fields
+    map {
+        /^customfield-(\d+)$/
+          && ( $ticketargs{ "CustomField-" . $1 } = $args{$_} );
+    } keys(%args);
+
+    my ( $id, $transid, $msg ) = $ticket->Create(%ticketargs);
+    unless ($id) {
+        $RT::Logger->error( "Couldn't create a related ticket for "
+              . $self->TicketObj->Id . " "
+              . $msg );
+    }
+
+    return (1);
+}
+
+# }}}
+
+# {{{ UpdateFrom822 
+
+=head2 UpdateFrom822 $MESSAGE
+
+Takes an RFC822 format message as a string and uses it to make a bunch of changes to a ticket.
+Returns an um. ask me again when the code exists
+
+
+=begin testing
+
+my $simple_update = <<EOF;
+Subject: target
+AddRequestor: jesse\@example.com
+EOF
+
+my $ticket = RT::Ticket->new($RT::SystemUser);
+$ticket->Create(Subject => 'first', Queue => 'general');
+ok($ticket->Id, "Created the test ticket");
+$ticket->UpdateFrom822($simple_update);
+is($ticket->Subject, 'target', "changed the subject");
+my $jesse = RT::User->new($RT::SystemUser);
+$jesse->LoadByEmail('jesse@example.com');
+ok ($jesse->Id, "There's a user for jesse");
+ok($ticket->Requestors->HasMember( $jesse->PrincipalObj), "It has the jesse principal object as a requestor ");
+
+=end testing
+
+
+=cut
+
+sub UpdateFrom822 {
+        my $self = shift;
+        my $content = shift;
+        my %args = $self->_Parse822HeadersForAttributes($content);
+
+        
+    my %ticketargs = (
+        Queue           => $args{'queue'},
+        Subject         => $args{'subject'},
+        Status          => $args{'status'},
+        Due             => $args{'due'},
+        Starts          => $args{'starts'},
+        Started         => $args{'started'},
+        Resolved        => $args{'resolved'},
+        Owner           => $args{'owner'},
+        Requestor       => $args{'requestor'},
+        Cc              => $args{'cc'},
+        AdminCc         => $args{'admincc'},
+        TimeWorked      => $args{'timeworked'},
+        TimeEstimated   => $args{'timeestimated'},
+        TimeLeft        => $args{'timeleft'},
+        InitialPriority => $args{'initialpriority'},
+        Priority => $args{'priority'},
+        FinalPriority   => $args{'finalpriority'},
+        Type            => $args{'type'},
+        DependsOn       => $args{'dependson'},
+        DependedOnBy    => $args{'dependedonby'},
+        RefersTo        => $args{'refersto'},
+        ReferredToBy    => $args{'referredtoby'},
+        Members         => $args{'members'},
+        MemberOf        => $args{'memberof'},
+        MIMEObj         => $args{'mimeobj'}
+    );
+
+    foreach my $type qw(Requestor Cc Admincc) {
+
+        foreach my $action ( 'Add', 'Del', '' ) {
+
+            my $lctag = lc($action) . lc($type);
+            foreach my $list ( $args{$lctag}, $args{ $lctag . 's' } ) {
+
+                foreach my $entry ( ref($list) ? @{$list} : ($list) ) {
+                    push @{$ticketargs{ $action . $type }} , split ( /\s*,\s*/, $entry );
+                }
+
+            }
+
+            # Todo: if we're given an explicit list, transmute it into a list of adds/deletes
+
+        }
+    }
+
+    # Add custom field entries to %ticketargs.
+    # TODO: allow named custom fields
+    map {
+        /^customfield-(\d+)$/
+          && ( $ticketargs{ "CustomField-" . $1 } = $args{$_} );
+    } keys(%args);
+
+# for each ticket we've been told to update, iterate through the set of
+# rfc822 headers and perform that update to the ticket.
+
+
+    # {{{ Set basic fields 
+    my @attribs = qw(
+      Subject
+      FinalPriority
+      Priority
+      TimeEstimated
+      TimeWorked
+      TimeLeft
+      Status
+      Queue
+      Type
+    );
+
+
+    # Resolve the queue from a name to a numeric id.
+    if ( $ticketargs{'Queue'} and ( $ticketargs{'Queue'} !~ /^(\d+)$/ ) ) {
+        my $tempqueue = RT::Queue->new($RT::SystemUser);
+        $tempqueue->Load( $ticketargs{'Queue'} );
+        $ticketargs{'Queue'} = $tempqueue->Id() if ( $tempqueue->id );
+    }
+
+    # die "updaterecordobject is a webui thingy";
+    my @results;
+
+    foreach my $attribute (@attribs) {
+        my $value = $ticketargs{$attribute};
+
+        if ( $value ne $self->$attribute() ) {
+
+            my $method = "Set$attribute";
+            my ( $code, $msg ) = $self->$method($value);
+
+            push @results, $self->loc($attribute) . ': ' . $msg;
+
+        }
+    }
+
+    # We special case owner changing, so we can use ForceOwnerChange
+    if ( $ticketargs{'Owner'} && ( $self->Owner != $ticketargs{'Owner'} ) ) {
+        my $ChownType = "Give";
+        $ChownType = "Force" if ( $ticketargs{'ForceOwnerChange'} );
+
+        my ( $val, $msg ) = $self->SetOwner( $ticketargs{'Owner'}, $ChownType );
+        push ( @results, $msg );
+    }
+
+    # }}}
+# Deal with setting watchers
+
+
+# Acceptable arguments:
+#  Requestor
+#  Requestors
+#  AddRequestor
+#  AddRequestors
+#  DelRequestor
+ foreach my $type qw(Requestor Cc AdminCc) {
+
+        # If we've been given a number of delresses to del, do it.
+                foreach my $address (@{$ticketargs{'Del'.$type}}) {
+                my ($id, $msg) = $self->DelWatcher( Type => $type, Email => $address);
+                push (@results, $msg) ;
+                }
+
+        # If we've been given a number of addresses to add, do it.
+                foreach my $address (@{$ticketargs{'Add'.$type}}) {
+                $RT::Logger->debug("Adding $address as a $type");
+                my ($id, $msg) = $self->AddWatcher( Type => $type, Email => $address);
+                push (@results, $msg) ;
+
+        }
+
+
+}
+
+
+}
+# }}}
+
+# {{{ _Parse822HeadersForAttributes Content
+
+=head2 _Parse822HeadersForAttributes Content
+
+Takes an RFC822 style message and parses its attributes into a hash.
+
+=cut
+
+sub _Parse822HeadersForAttributes {
+    my $self    = shift;
+    my $content = shift;
+    my %args;
+
+    my @lines = ( split ( /\n/, $content ) );
+    while ( defined( my $line = shift @lines ) ) {
+        if ( $line =~ /^(.*?):(?:\s+(.*))?$/ ) {
+            my $value = $2;
+            my $tag   = lc($1);
+
+            $tag =~ s/-//g;
+            if ( defined( $args{$tag} ) )
+            {    #if we're about to get a second value, make it an array
+                $args{$tag} = [ $args{$tag} ];
+            }
+            if ( ref( $args{$tag} ) )
+            {    #If it's an array, we want to push the value
+                push @{ $args{$tag} }, $value;
+            }
+            else {    #if there's nothing there, just set the value
+                $args{$tag} = $value;
+            }
+        } elsif ($line =~ /^$/) {
+
+            #TODO: this won't work, since "" isn't of the form "foo:value"
+
+                while ( defined( my $l = shift @lines ) ) {
+                    push @{ $args{'content'} }, $l;
+                }
+            }
+        
+    }
+
+    foreach my $date qw(due starts started resolved) {
+        my $dateobj = RT::Date->new($RT::SystemUser);
+        if ( $args{$date} =~ /^\d+$/ ) {
+            $dateobj->Set( Format => 'unix', Value => $args{$date} );
+        }
+        else {
+            $dateobj->Set( Format => 'unknown', Value => $args{$date} );
+        }
+        $args{$date} = $dateobj->ISO;
+    }
+    $args{'mimeobj'} = MIME::Entity->new();
+    $args{'mimeobj'}->build(
+        Type => ( $args{'contenttype'} || 'text/plain' ),
+        Data => ($args{'content'} || '')
+    );
+
+    return (%args);
+}
+
+# }}}
+
+# {{{ sub Import
+
+=head2 Import PARAMHASH
+
+Import a ticket. 
+Doesn\'t create a transaction. 
+Doesn\'t supply queue defaults, etc.
+
+Returns: TICKETID
+
+=cut
+
+sub Import {
+    my $self = shift;
+    my ( $ErrStr, $QueueObj, $Owner );
+
+    my %args = (
+        id              => undef,
+        EffectiveId     => undef,
+        Queue           => undef,
+        Requestor       => undef,
+        Type            => 'ticket',
+        Owner           => $RT::Nobody->Id,
+        Subject         => '[no subject]',
+        InitialPriority => undef,
+        FinalPriority   => undef,
+        Status          => 'new',
+        TimeWorked      => "0",
+        Due             => undef,
+        Created         => undef,
+        Updated         => undef,
+        Resolved        => undef,
+        Told            => undef,
+        @_
+    );
+
+    if ( ( defined( $args{'Queue'} ) ) && ( !ref( $args{'Queue'} ) ) ) {
+        $QueueObj = RT::Queue->new($RT::SystemUser);
+        $QueueObj->Load( $args{'Queue'} );
+
+        #TODO error check this and return 0 if it\'s not loading properly +++
+    }
+    elsif ( ref( $args{'Queue'} ) eq 'RT::Queue' ) {
+        $QueueObj = RT::Queue->new($RT::SystemUser);
+        $QueueObj->Load( $args{'Queue'}->Id );
+    }
+    else {
+        $RT::Logger->debug(
+            "$self " . $args{'Queue'} . " not a recognised queue object." );
+    }
+
+    #Can't create a ticket without a queue.
+    unless ( defined($QueueObj) and $QueueObj->Id ) {
+        $RT::Logger->debug("$self No queue given for ticket creation.");
+        return ( 0, $self->loc('Could not create ticket. Queue not set') );
+    }
+
+    #Now that we have a queue, Check the ACLS
+    unless (
+        $self->CurrentUser->HasRight(
+            Right    => 'CreateTicket',
+            Object => $QueueObj
+        )
+      )
+    {
+        return ( 0,
+            $self->loc("No permission to create tickets in the queue '[_1]'"
+              , $QueueObj->Name));
+    }
+
+    # {{{ Deal with setting the owner
+
+    # Attempt to take user object, user name or user id.
+    # Assign to nobody if lookup fails.
+    if ( defined( $args{'Owner'} ) ) {
+        if ( ref( $args{'Owner'} ) ) {
+            $Owner = $args{'Owner'};
+        }
+        else {
+            $Owner = new RT::User( $self->CurrentUser );
+            $Owner->Load( $args{'Owner'} );
+            if ( !defined( $Owner->id ) ) {
+                $Owner->Load( $RT::Nobody->id );
+            }
+        }
+    }
+
+    #If we have a proposed owner and they don't have the right 
+    #to own a ticket, scream about it and make them not the owner
+    if (
+        ( defined($Owner) )
+        and ( $Owner->Id != $RT::Nobody->Id )
+        and (
+            !$Owner->HasRight(
+                Object => $QueueObj,
+                Right    => 'OwnTicket'
+            )
+        )
+      )
+    {
+
+        $RT::Logger->warning( "$self user "
+              . $Owner->Name . "("
+              . $Owner->id
+              . ") was proposed "
+              . "as a ticket owner but has no rights to own "
+              . "tickets in '"
+              . $QueueObj->Name . "'\n" );
+
+        $Owner = undef;
+    }
+
+    #If we haven't been handed a valid owner, make it nobody.
+    unless ( defined($Owner) ) {
+        $Owner = new RT::User( $self->CurrentUser );
+        $Owner->Load( $RT::Nobody->UserObj->Id );
+    }
+
+    # }}}
+
+    unless ( $self->ValidateStatus( $args{'Status'} ) ) {
+        return ( 0, $self->loc("'[_1]' is an invalid value for status", $args{'Status'}) );
+    }
+
+    $self->{'_AccessibleCache'}{Created}       = { 'read' => 1, 'write' => 1 };
+    $self->{'_AccessibleCache'}{Creator}       = { 'read' => 1, 'auto'  => 1 };
+    $self->{'_AccessibleCache'}{LastUpdated}   = { 'read' => 1, 'write' => 1 };
+    $self->{'_AccessibleCache'}{LastUpdatedBy} = { 'read' => 1, 'auto'  => 1 };
+
+    # If we're coming in with an id, set that now.
+    my $EffectiveId = undef;
+    if ( $args{'id'} ) {
+        $EffectiveId = $args{'id'};
+
+    }
+
+    my $id = $self->SUPER::Create(
+        id              => $args{'id'},
+        EffectiveId     => $EffectiveId,
+        Queue           => $QueueObj->Id,
+        Owner           => $Owner->Id,
+        Subject         => $args{'Subject'},           # loc
+        InitialPriority => $args{'InitialPriority'},   # loc
+        FinalPriority   => $args{'FinalPriority'},     # loc
+        Priority        => $args{'InitialPriority'},   # loc
+        Status          => $args{'Status'},            # loc
+        TimeWorked      => $args{'TimeWorked'},                # loc
+        Type            => $args{'Type'},              # loc
+        Created         => $args{'Created'},           # loc
+        Told            => $args{'Told'},              # loc
+        LastUpdated     => $args{'Updated'},           # loc
+        Resolved        => $args{'Resolved'},          # loc
+        Due             => $args{'Due'},               # loc
+    );
+
+    # If the ticket didn't have an id
+    # Set the ticket's effective ID now that we've created it.
+    if ( $args{'id'} ) {
+        $self->Load( $args{'id'} );
+    }
+    else {
+        my ( $val, $msg ) =
+          $self->__Set( Field => 'EffectiveId', Value => $id );
+
+        unless ($val) {
+            $RT::Logger->err(
+                $self . "->Import couldn't set EffectiveId: $msg\n" );
+        }
+    }
+
+    my $watcher;
+    foreach $watcher ( @{ $args{'Cc'} } ) {
+        $self->_AddWatcher( Type => 'Cc', Person => $watcher, Silent => 1 );
+    }
+    foreach $watcher ( @{ $args{'AdminCc'} } ) {
+        $self->_AddWatcher( Type => 'AdminCc', Person => $watcher,
+            Silent => 1 );
+    }
+    foreach $watcher ( @{ $args{'Requestor'} } ) {
+        $self->_AddWatcher( Type => 'Requestor', Person => $watcher,
+            Silent => 1 );
+    }
+
+    return ( $self->Id, $ErrStr );
+}
+
+# }}}
+
+
+# {{{ Routines dealing with watchers.
+
+# {{{ _CreateTicketGroups 
+
+=head2 _CreateTicketGroups
+
+Create the ticket groups and relationships for this ticket. 
+This routine expects to be called from Ticket->Create _inside of a transaction_
+
+It will create four groups for this ticket: Requestor, Cc, AdminCc and Owner.
+
+It will return true on success and undef on failure.
+
+=begin testing
+
+my $ticket = RT::Ticket->new($RT::SystemUser);
+my ($id, $msg) = $ticket->Create(Subject => "Foo",
+                Owner => $RT::SystemUser->Id,
+                Status => 'open',
+                Requestor => ['jesse@example.com'],
+                Queue => '1'
+                );
+ok ($id, "Ticket $id was created");
+ok(my $group = RT::Group->new($RT::SystemUser));
+ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'Requestor'));
+ok ($group->Id, "Found the requestors object for this ticket");
+
+ok(my $jesse = RT::User->new($RT::SystemUser), "Creating a jesse rt::user");
+$jesse->LoadByEmail('jesse@example.com');
+ok($jesse->Id,  "Found the jesse rt user");
+
+
+ok ($ticket->IsWatcher(Type => 'Requestor', PrincipalId => $jesse->PrincipalId), "The ticket actually has jesse at fsck.com as a requestor");
+ok ((my $add_id, $add_msg) = $ticket->AddWatcher(Type => 'Requestor', Email => 'bob@fsck.com'), "Added bob at fsck.com as a requestor");
+ok ($add_id, "Add succeeded: ($add_msg)");
+ok(my $bob = RT::User->new($RT::SystemUser), "Creating a bob rt::user");
+$bob->LoadByEmail('bob@fsck.com');
+ok($bob->Id,  "Found the bob rt user");
+ok ($ticket->IsWatcher(Type => 'Requestor', PrincipalId => $bob->PrincipalId), "The ticket actually has bob at fsck.com as a requestor");;
+ok ((my $add_id, $add_msg) = $ticket->DeleteWatcher(Type =>'Requestor', Email => 'bob@fsck.com'), "Added bob at fsck.com as a requestor");
+ok (!$ticket->IsWatcher(Type => 'Requestor', Principal => $bob->PrincipalId), "The ticket no longer has bob at fsck.com as a requestor");;
+
+
+$group = RT::Group->new($RT::SystemUser);
+ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'Cc'));
+ok ($group->Id, "Found the cc object for this ticket");
+$group = RT::Group->new($RT::SystemUser);
+ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'AdminCc'));
+ok ($group->Id, "Found the AdminCc object for this ticket");
+$group = RT::Group->new($RT::SystemUser);
+ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'Owner'));
+ok ($group->Id, "Found the Owner object for this ticket");
+ok($group->HasMember($RT::SystemUser->UserObj->PrincipalObj), "the owner group has the member 'RT_System'");
+
+=end testing
+
+=cut
+
+
+sub _CreateTicketGroups {
+    my $self = shift;
+    
+    my @types = qw(Requestor Owner Cc AdminCc);
+
+    foreach my $type (@types) {
+        my $type_obj = RT::Group->new($self->CurrentUser);
+        my ($id, $msg) = $type_obj->CreateRoleGroup(Domain => 'RT::Ticket-Role',
+                                                       Instance => $self->Id, 
+                                                       Type => $type);
+        unless ($id) {
+            $RT::Logger->error("Couldn't create a ticket group of type '$type' for ticket ".
+                               $self->Id.": ".$msg);     
+            return(undef);
+        }
+     }
+    return(1);
+    
+}
+
+# }}}
+
+# {{{ sub OwnerGroup
+
+=head2 OwnerGroup
+
+A constructor which returns an RT::Group object containing the owner of this ticket.
+
+=cut
+
+sub OwnerGroup {
+    my $self = shift;
+    my $owner_obj = RT::Group->new($self->CurrentUser);
+    $owner_obj->LoadTicketRoleGroup( Ticket => $self->Id,  Type => 'Owner');
+    return ($owner_obj);
+}
+
+# }}}
+
+
+# {{{ sub AddWatcher
+
+=head2 AddWatcher
+
+AddWatcher takes a parameter hash. The keys are as follows:
+
+Type        One of Requestor, Cc, AdminCc
+
+PrinicpalId The RT::Principal id of the user or group that's being added as a watcher
+
+Email       The email address of the new watcher. If a user with this 
+            email address can't be found, a new nonprivileged user will be created.
+
+If the watcher you\'re trying to set has an RT account, set the Owner paremeter to their User Id. Otherwise, set the Email parameter to their Email address.
+
+=cut
+
+sub AddWatcher {
+    my $self = shift;
+    my %args = (
+        Type  => undef,
+        PrincipalId => undef,
+        Email => undef,
+        @_
+    );
+
+    # {{{ Check ACLS
+    #If the watcher we're trying to add is for the current user
+    if ( $self->CurrentUser->PrincipalId  eq $args{'PrincipalId'}) {
+        #  If it's an AdminCc and they don't have 
+        #   'WatchAsAdminCc' or 'ModifyTicket', bail
+        if ( $args{'Type'} eq 'AdminCc' ) {
+            unless ( $self->CurrentUserHasRight('ModifyTicket')
+                or $self->CurrentUserHasRight('WatchAsAdminCc') ) {
+                return ( 0, $self->loc('Permission Denied'))
+            }
+        }
+
+        #  If it's a Requestor or Cc and they don't have
+        #   'Watch' or 'ModifyTicket', bail
+        elsif ( ( $args{'Type'} eq 'Cc' ) or ( $args{'Type'} eq 'Requestor' ) ) {
+
+            unless ( $self->CurrentUserHasRight('ModifyTicket')
+                or $self->CurrentUserHasRight('Watch') ) {
+                return ( 0, $self->loc('Permission Denied'))
+            }
+        }
+        else {
+            $RT::Logger->warn( "$self -> AddWatcher got passed a bogus type");
+            return ( 0, $self->loc('Error in parameters to Ticket->AddWatcher') );
+        }
+    }
+
+    # If the watcher isn't the current user 
+    # and the current user  doesn't have 'ModifyTicket'
+    # bail
+    else {
+        unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+            return ( 0, $self->loc("Permission Denied") );
+        }
+    }
+
+    # }}}
+
+    return ( $self->_AddWatcher(%args) );
+}
+
+#This contains the meat of AddWatcher. but can be called from a routine like
+# Create, which doesn't need the additional acl check
+sub _AddWatcher {
+    my $self = shift;
+    my %args = (
+        Type   => undef,
+        Silent => undef,
+        PrincipalId => undef,
+        Email => undef,
+        @_
+    );
+
+
+    my $principal = RT::Principal->new($self->CurrentUser);
+    if ($args{'Email'}) {
+        my $user = RT::User->new($RT::SystemUser);
+        my ($pid, $msg) = $user->LoadOrCreateByEmail($args{'Email'});
+        if ($pid) {
+            $args{'PrincipalId'} = $pid; 
+        }
+    }
+    if ($args{'PrincipalId'}) {
+        $principal->Load($args{'PrincipalId'});
+    } 
+
+    # If we can't find this watcher, we need to bail.
+    unless ($principal->Id) {
+            $RT::Logger->error("Could not load create a user with the email address '".$args{'Email'}. "' to add as a watcher for ticket ".$self->Id);
+        return(0, $self->loc("Could not find or create that user"));
+    }
+
+
+    my $group = RT::Group->new($self->CurrentUser);
+    $group->LoadTicketRoleGroup(Type => $args{'Type'}, Ticket => $self->Id);
+    unless ($group->id) {
+        return(0,$self->loc("Group not found"));
+    }
+
+    if ( $group->HasMember( $principal)) {
+
+        return ( 0, $self->loc('That principal is already a [_1] for this ticket', $self->loc($args{'Type'})) );
+    }
+
+
+    my ( $m_id, $m_msg ) = $group->_AddMember( PrincipalId => $principal->Id,
+                                               InsideTransaction => 1 );
+    unless ($m_id) {
+        $RT::Logger->error("Failed to add ".$principal->Id." as a member of group ".$group->Id."\n".$m_msg);
+
+        return ( 0, $self->loc('Could not make that principal a [_1] for this ticket', $self->loc($args{'Type'})) );
+    }
+
+    unless ( $args{'Silent'} ) {
+        $self->_NewTransaction(
+            Type     => 'AddWatcher',
+            NewValue => $principal->Id,
+            Field    => $args{'Type'}
+        );
+    }
+
+        return ( 1, $self->loc('Added principal as a [_1] for this ticket', $self->loc($args{'Type'})) );
+}
+
+# }}}
+
+
+# {{{ sub DeleteWatcher
+
+=head2 DeleteWatcher { Type => TYPE, PrincipalId => PRINCIPAL_ID, Email => EMAIL_ADDRESS }
+
+
+Deletes a Ticket watcher.  Takes two arguments:
+
+Type  (one of Requestor,Cc,AdminCc)
+
+and one of
+
+PrincipalId (an RT::Principal Id of the watcher you want to remove)
+    OR
+Email (the email address of an existing wathcer)
+
+
+=cut
+
+
+sub DeleteWatcher {
+    my $self = shift;
+
+    my %args = ( Type => undef,
+                 PrincipalId => undef,
+                 Email => undef,
+                 @_ );
+
+    unless ($args{'PrincipalId'} || $args{'Email'} ) {
+        return(0, $self->loc("No principal specified"));
+    }
+    my $principal = RT::Principal->new($self->CurrentUser);
+    if ($args{'PrincipalId'} ) {
+
+        $principal->Load($args{'PrincipalId'});
+    } else {
+        my $user = RT::User->new($self->CurrentUser);
+        $user->LoadByEmail($args{'Email'});
+        $principal->Load($user->Id);
+    }
+    # If we can't find this watcher, we need to bail.
+    unless ($principal->Id) {
+        return(0, $self->loc("Could not find that principal"));
+    }
+
+    my $group = RT::Group->new($self->CurrentUser);
+    $group->LoadTicketRoleGroup(Type => $args{'Type'}, Ticket => $self->Id);
+    unless ($group->id) {
+        return(0,$self->loc("Group not found"));
+    }
+
+    # {{{ Check ACLS
+    #If the watcher we're trying to add is for the current user
+    if ( $self->CurrentUser->PrincipalId  eq $args{'PrincipalId'}) {
+        #  If it's an AdminCc and they don't have 
+        #   'WatchAsAdminCc' or 'ModifyTicket', bail
+        if ( $args{'Type'} eq 'AdminCc' ) {
+            unless ( $self->CurrentUserHasRight('ModifyTicket')
+                or $self->CurrentUserHasRight('WatchAsAdminCc') ) {
+                return ( 0, $self->loc('Permission Denied'))
+            }
+        }
+
+        #  If it's a Requestor or Cc and they don't have
+        #   'Watch' or 'ModifyTicket', bail
+        elsif ( ( $args{'Type'} eq 'Cc' ) or ( $args{'Type'} eq 'Requestor' ) ) {
+            unless ( $self->CurrentUserHasRight('ModifyTicket')
+                or $self->CurrentUserHasRight('Watch') ) {
+                return ( 0, $self->loc('Permission Denied'))
+            }
+        }
+        else {
+            $RT::Logger->warn( "$self -> DeleteWatcher got passed a bogus type");
+            return ( 0, $self->loc('Error in parameters to Ticket->DelWatcher') );
+        }
+    }
+
+    # If the watcher isn't the current user 
+    # and the current user  doesn't have 'ModifyTicket' bail
+    else {
+        unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+            return ( 0, $self->loc("Permission Denied") );
+        }
+    }
+
+    # }}}
+
+
+    # see if this user is already a watcher.
+
+    unless ( $group->HasMember($principal)) {
+        return ( 0, 
+        $self->loc('That principal is not a [_1] for this ticket', $args{'Type'}) );
+    }
+
+    my ($m_id, $m_msg) = $group->_DeleteMember($principal->Id);
+    unless ($m_id) {
+        $RT::Logger->error("Failed to delete ".$principal->Id.
+                           " as a member of group ".$group->Id."\n".$m_msg);
+
+        return ( 0,    $self->loc('Could not remove that principal as a [_1] for this ticket', $args{'Type'}) );
+    }
+
+    unless ( $args{'Silent'} ) {
+        $self->_NewTransaction(
+            Type     => 'DelWatcher',
+            OldValue => $principal->Id,
+            Field    => $args{'Type'}
+        );
+    }
+
+    return ( 1, $self->loc("[_1] is no longer a [_2] for this ticket.", $principal->Object->Name, $args{'Type'} ));
+}
+
+
+
+
+# }}}
+
+
+# {{{ a set of  [foo]AsString subs that will return the various sorts of watchers for a ticket/queue as a comma delineated string
+
+=head2 RequestorAddresses
+
+ B<Returns> String: All Ticket Requestor email addresses as a string.
+
+=cut
+
+sub RequestorAddresses {
+    my $self = shift;
+
+    unless ( $self->CurrentUserHasRight('ShowTicket') ) {
+        return undef;
+    }
+
+    return ( $self->Requestors->MemberEmailAddressesAsString );
+}
+
+
+=head2 AdminCcAddresses
+
+returns String: All Ticket AdminCc email addresses as a string
+
+=cut
+
+sub AdminCcAddresses {
+    my $self = shift;
+
+    unless ( $self->CurrentUserHasRight('ShowTicket') ) {
+        return undef;
+    }
+
+    return ( $self->AdminCc->MemberEmailAddressesAsString )
+
+}
+
+=head2 CcAddresses
+
+returns String: All Ticket Ccs as a string of email addresses
+
+=cut
+
+sub CcAddresses {
+    my $self = shift;
+
+    unless ( $self->CurrentUserHasRight('ShowTicket') ) {
+        return undef;
+    }
+
+    return ( $self->Cc->MemberEmailAddressesAsString);
+
+}
+
+# }}}
+
+# {{{ Routines that return RT::Watchers objects of Requestors, Ccs and AdminCcs
+
+# {{{ sub Requestors
+
+=head2 Requestors
+
+Takes nothing.
+Returns this ticket's Requestors as an RT::Group object
+
+=cut
+
+sub Requestors {
+    my $self = shift;
+
+    my $group = RT::Group->new($self->CurrentUser);
+    if ( $self->CurrentUserHasRight('ShowTicket') ) {
+        $group->LoadTicketRoleGroup(Type => 'Requestor', Ticket => $self->Id);
+    }
+    return ($group);
+
+}
+
+# }}}
+
+# {{{ sub Cc
+
+=head2 Cc
+
+Takes nothing.
+Returns an RT::Group object which contains this ticket's Ccs.
+If the user doesn't have "ShowTicket" permission, returns an empty group
+
+=cut
+
+sub Cc {
+    my $self = shift;
+
+    my $group = RT::Group->new($self->CurrentUser);
+    if ( $self->CurrentUserHasRight('ShowTicket') ) {
+        $group->LoadTicketRoleGroup(Type => 'Cc', Ticket => $self->Id);
+    }
+    return ($group);
+
+}
+
+# }}}
+
+# {{{ sub AdminCc
+
+=head2 AdminCc
+
+Takes nothing.
+Returns an RT::Group object which contains this ticket's AdminCcs.
+If the user doesn't have "ShowTicket" permission, returns an empty group
+
+=cut
+
+sub AdminCc {
+    my $self = shift;
+
+    my $group = RT::Group->new($self->CurrentUser);
+    if ( $self->CurrentUserHasRight('ShowTicket') ) {
+        $group->LoadTicketRoleGroup(Type => 'AdminCc', Ticket => $self->Id);
+    }
+    return ($group);
+
+}
+
+# }}}
+
+# }}}
+
+# {{{ IsWatcher,IsRequestor,IsCc, IsAdminCc
+
+# {{{ sub IsWatcher
+# a generic routine to be called by IsRequestor, IsCc and IsAdminCc
+
+=head2 IsWatcher { Type => TYPE, PrincipalId => PRINCIPAL_ID, Email => EMAIL }
+
+Takes a param hash with the attributes Type and either PrincipalId or Email
+
+Type is one of Requestor, Cc, AdminCc and Owner
+
+PrincipalId is an RT::Principal id, and Email is an email address.
+
+Returns true if the specified principal (or the one corresponding to the
+specified address) is a member of the group Type for this ticket.
+
+=cut
+
+sub IsWatcher {
+    my $self = shift;
+
+    my %args = ( Type  => 'Requestor',
+        PrincipalId    => undef,
+        Email          => undef,
+        @_
+    );
+
+    # Load the relevant group. 
+    my $group = RT::Group->new($self->CurrentUser);
+    $group->LoadTicketRoleGroup(Type => $args{'Type'}, Ticket => $self->id);
+
+    # Find the relevant principal.
+    my $principal = RT::Principal->new($self->CurrentUser);
+    if (!$args{PrincipalId} && $args{Email}) {
+        # Look up the specified user.
+        my $user = RT::User->new($self->CurrentUser);
+        $user->LoadByEmail($args{Email});
+        if ($user->Id) {
+            $args{PrincipalId} = $user->PrincipalId;
+        }
+        else {
+            # A non-existent user can't be a group member.
+            return 0;
+        }
+    }
+    $principal->Load($args{'PrincipalId'});
+
+    # Ask if it has the member in question
+    return ($group->HasMember($principal));
+}
+
+# }}}
+
+# {{{ sub IsRequestor
+
+=head2 IsRequestor PRINCIPAL_ID
+  
+  Takes an RT::Principal id
+  Returns true if the principal is a requestor of the current ticket.
+
+
+=cut
+
+sub IsRequestor {
+    my $self   = shift;
+    my $person = shift;
+
+    return ( $self->IsWatcher( Type => 'Requestor', PrincipalId => $person ) );
+
+};
+
+# }}}
+
+# {{{ sub IsCc
+
+=head2 IsCc PRINCIPAL_ID
+
+  Takes an RT::Principal id.
+  Returns true if the principal is a requestor of the current ticket.
+
+
+=cut
+
+sub IsCc {
+    my $self = shift;
+    my $cc   = shift;
+
+    return ( $self->IsWatcher( Type => 'Cc', PrincipalId => $cc ) );
+
+}
+
+# }}}
+
+# {{{ sub IsAdminCc
+
+=head2 IsAdminCc PRINCIPAL_ID
+
+  Takes an RT::Principal id.
+  Returns true if the principal is a requestor of the current ticket.
+
+=cut
+
+sub IsAdminCc {
+    my $self   = shift;
+    my $person = shift;
+
+    return ( $self->IsWatcher( Type => 'AdminCc', PrincipalId => $person ) );
+
+}
+
+# }}}
+
+# {{{ sub IsOwner
+
+=head2 IsOwner
+
+  Takes an RT::User object. Returns true if that user is this ticket's owner.
+returns undef otherwise
+
+=cut
+
+sub IsOwner {
+    my $self   = shift;
+    my $person = shift;
+
+    # no ACL check since this is used in acl decisions
+    # unless ($self->CurrentUserHasRight('ShowTicket')) {
+    #  return(undef);
+    #   }      
+
+    #Tickets won't yet have owners when they're being created.
+    unless ( $self->OwnerObj->id ) {
+        return (undef);
+    }
+
+    if ( $person->id == $self->OwnerObj->id ) {
+        return (1);
+    }
+    else {
+        return (undef);
+    }
+}
+
+# }}}
+
+# }}}
+
+# }}}
+
+# {{{ Routines dealing with queues 
+
+# {{{ sub ValidateQueue
+
+sub ValidateQueue {
+    my $self  = shift;
+    my $Value = shift;
+
+    if ( !$Value ) {
+        $RT::Logger->warning( " RT:::Queue::ValidateQueue called with a null value. this isn't ok.");
+        return (1);
+    }
+
+    my $QueueObj = RT::Queue->new( $self->CurrentUser );
+    my $id       = $QueueObj->Load($Value);
+
+    if ($id) {
+        return (1);
+    }
+    else {
+        return (undef);
+    }
+}
+
+# }}}
+
+# {{{ sub SetQueue  
+
+sub SetQueue {
+    my $self     = shift;
+    my $NewQueue = shift;
+
+    #Redundant. ACL gets checked in _Set;
+    unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+    my $NewQueueObj = RT::Queue->new( $self->CurrentUser );
+    $NewQueueObj->Load($NewQueue);
+
+    unless ( $NewQueueObj->Id() ) {
+        return ( 0, $self->loc("That queue does not exist") );
+    }
+
+    if ( $NewQueueObj->Id == $self->QueueObj->Id ) {
+        return ( 0, $self->loc('That is the same value') );
+    }
+    unless (
+        $self->CurrentUser->HasRight(
+            Right    => 'CreateTicket',
+            Object => $NewQueueObj
+        )
+      )
+    {
+        return ( 0, $self->loc("You may not create requests in that queue.") );
+    }
+
+    unless (
+        $self->OwnerObj->HasRight(
+            Right    => 'OwnTicket',
+            Object => $NewQueueObj
+        )
+      )
+    {
+        $self->Untake();
+    }
+
+    return ( $self->_Set( Field => 'Queue', Value => $NewQueueObj->Id() ) );
+
+}
+
+# }}}
+
+# {{{ sub QueueObj
+
+=head2 QueueObj
+
+Takes nothing. returns this ticket's queue object
+
+=cut
+
+sub QueueObj {
+    my $self = shift;
+
+    my $queue_obj = RT::Queue->new( $self->CurrentUser );
+
+    #We call __Value so that we can avoid the ACL decision and some deep recursion
+    my ($result) = $queue_obj->Load( $self->__Value('Queue') );
+    return ($queue_obj);
+}
+
+# }}}
+
+# }}}
+
+# {{{ Date printing routines
+
+# {{{ sub DueObj
+
+=head2 DueObj
+
+  Returns an RT::Date object containing this ticket's due date
+
+=cut
+
+sub DueObj {
+    my $self = shift;
+
+    my $time = new RT::Date( $self->CurrentUser );
+
+    # -1 is RT::Date slang for never
+    if ( $self->Due ) {
+        $time->Set( Format => 'sql', Value => $self->Due );
+    }
+    else {
+        $time->Set( Format => 'unix', Value => -1 );
+    }
+
+    return $time;
+}
+
+# }}}
+
+# {{{ sub DueAsString 
+
+=head2 DueAsString
+
+Returns this ticket's due date as a human readable string
+
+=cut
+
+sub DueAsString {
+    my $self = shift;
+    return $self->DueObj->AsString();
+}
+
+# }}}
+
+# {{{ sub ResolvedObj
+
+=head2 ResolvedObj
+
+  Returns an RT::Date object of this ticket's 'resolved' time.
+
+=cut
+
+sub ResolvedObj {
+    my $self = shift;
+
+    my $time = new RT::Date( $self->CurrentUser );
+    $time->Set( Format => 'sql', Value => $self->Resolved );
+    return $time;
+}
+
+# }}}
+
+# {{{ sub SetStarted
+
+=head2 SetStarted
+
+Takes a date in ISO format or undef
+Returns a transaction id and a message
+The client calls "Start" to note that the project was started on the date in $date.
+A null date means "now"
+
+=cut
+
+sub SetStarted {
+    my $self = shift;
+    my $time = shift || 0;
+
+    unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+        return ( 0, self->loc("Permission Denied") );
+    }
+
+    #We create a date object to catch date weirdness
+    my $time_obj = new RT::Date( $self->CurrentUser() );
+    if ( $time != 0 ) {
+        $time_obj->Set( Format => 'ISO', Value => $time );
+    }
+    else {
+        $time_obj->SetToNow();
+    }
+
+    #Now that we're starting, open this ticket
+    #TODO do we really want to force this as policy? it should be a scrip
+
+    #We need $TicketAsSystem, in case the current user doesn't have
+    #ShowTicket
+    #
+    my $TicketAsSystem = new RT::Ticket($RT::SystemUser);
+    $TicketAsSystem->Load( $self->Id );
+    if ( $TicketAsSystem->Status eq 'new' ) {
+        $TicketAsSystem->Open();
+    }
+
+    return ( $self->_Set( Field => 'Started', Value => $time_obj->ISO ) );
+
+}
+
+# }}}
+
+# {{{ sub StartedObj
+
+=head2 StartedObj
+
+  Returns an RT::Date object which contains this ticket's 
+'Started' time.
+
+=cut
+
+sub StartedObj {
+    my $self = shift;
+
+    my $time = new RT::Date( $self->CurrentUser );
+    $time->Set( Format => 'sql', Value => $self->Started );
+    return $time;
+}
+
+# }}}
+
+# {{{ sub StartsObj
+
+=head2 StartsObj
+
+  Returns an RT::Date object which contains this ticket's 
+'Starts' time.
+
+=cut
+
+sub StartsObj {
+    my $self = shift;
+
+    my $time = new RT::Date( $self->CurrentUser );
+    $time->Set( Format => 'sql', Value => $self->Starts );
+    return $time;
+}
+
+# }}}
+
+# {{{ sub ToldObj
+
+=head2 ToldObj
+
+  Returns an RT::Date object which contains this ticket's 
+'Told' time.
+
+=cut
+
+sub ToldObj {
+    my $self = shift;
+
+    my $time = new RT::Date( $self->CurrentUser );
+    $time->Set( Format => 'sql', Value => $self->Told );
+    return $time;
+}
+
+# }}}
+
+# {{{ sub ToldAsString
+
+=head2 ToldAsString
+
+A convenience method that returns ToldObj->AsString
+
+TODO: This should be deprecated
+
+=cut
+
+sub ToldAsString {
+    my $self = shift;
+    if ( $self->Told ) {
+        return $self->ToldObj->AsString();
+    }
+    else {
+        return ("Never");
+    }
+}
+
+# }}}
+
+# {{{ sub TimeWorkedAsString
+
+=head2 TimeWorkedAsString
+
+Returns the amount of time worked on this ticket as a Text String
+
+=cut
+
+sub TimeWorkedAsString {
+    my $self = shift;
+    return "0" unless $self->TimeWorked;
+
+    #This is not really a date object, but if we diff a number of seconds 
+    #vs the epoch, we'll get a nice description of time worked.
+
+    my $worked = new RT::Date( $self->CurrentUser );
+
+    #return the  #of minutes worked turned into seconds and written as
+    # a simple text string
+
+    return ( $worked->DurationAsString( $self->TimeWorked * 60 ) );
+}
+
+# }}}
+
+# }}}
+
+# {{{ Routines dealing with correspondence/comments
+
+# {{{ sub Comment
+
+=head2 Comment
+
+Comment on this ticket.
+Takes a hashref with the following attributes:
+If MIMEObj is undefined, Content will be used to build a MIME::Entity for this
+commentl
+
+MIMEObj, TimeTaken, CcMessageTo, BccMessageTo, Content.
+
+=cut
+
+## Please see file perltidy.ERR
+sub Comment {
+    my $self = shift;
+
+    my %args = ( CcMessageTo  => undef,
+                 BccMessageTo => undef,
+                 MIMEObj      => undef,
+                 Content      => undef,
+                 TimeTaken => 0,
+                 @_ );
+
+    unless (    ( $self->CurrentUserHasRight('CommentOnTicket') )
+             or ( $self->CurrentUserHasRight('ModifyTicket') ) ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+    unless ( $args{'MIMEObj'} ) {
+        if ( $args{'Content'} ) {
+            use MIME::Entity;
+            $args{'MIMEObj'} = MIME::Entity->build(
+               Data => ( ref $args{'Content'} ? $args{'Content'} : [ $args{'Content'} ] )
+           );
+        }
+        else {
+
+            return ( 0, $self->loc("No correspondence attached") );
+        }
+    }
+
+    RT::I18N::SetMIMEEntityToUTF8($args{'MIMEObj'}); # convert text parts into utf-8
+
+    # If we've been passed in CcMessageTo and BccMessageTo fields,
+    # add them to the mime object for passing on to the transaction handler
+    # The "NotifyOtherRecipients" scripAction will look for RT--Send-Cc: and
+    # RT-Send-Bcc: headers
+
+    $args{'MIMEObj'}->head->add( 'RT-Send-Cc',  $args{'CcMessageTo'} )
+       if defined $args{'CcMessageTo'};
+    $args{'MIMEObj'}->head->add( 'RT-Send-Bcc', $args{'BccMessageTo'} )
+       if defined $args{'BccMessageTo'};
+
+    #Record the correspondence (write the transaction)
+    my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
+        Type      => 'Comment',
+        Data      => ( $args{'MIMEObj'}->head->get('subject') || 'No Subject' ),
+        TimeTaken => $args{'TimeTaken'},
+        MIMEObj   => $args{'MIMEObj'}
+    );
+
+    return ( $Trans, $self->loc("The comment has been recorded") );
+}
+
+# }}}
+
+# {{{ sub Correspond
+
+=head2 Correspond
+
+Correspond on this ticket.
+Takes a hashref with the following attributes:
+
+
+MIMEObj, TimeTaken, CcMessageTo, BccMessageTo, Content
+
+if there's no MIMEObj, Content is used to build a MIME::Entity object
+
+
+=cut
+
+sub Correspond {
+    my $self = shift;
+    my %args = ( CcMessageTo  => undef,
+                 BccMessageTo => undef,
+                 MIMEObj      => undef,
+                 Content      => undef,
+                 TimeTaken    => 0,
+                 @_ );
+
+    unless (    ( $self->CurrentUserHasRight('ReplyToTicket') )
+             or ( $self->CurrentUserHasRight('ModifyTicket') ) ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+    unless ( $args{'MIMEObj'} ) {
+        if ( $args{'Content'} ) {
+            use MIME::Entity;
+            $args{'MIMEObj'} = MIME::Entity->build(
+               Data => ( ref $args{'Content'} ?  $args{'Content'} : [ $args{'Content'} ] )
+           );
+
+        }
+        else {
+
+            return ( 0, $self->loc("No correspondence attached") );
+        }
+    }
+
+    RT::I18N::SetMIMEEntityToUTF8($args{'MIMEObj'}); # convert text parts into utf-8
+
+    # If we've been passed in CcMessageTo and BccMessageTo fields,
+    # add them to the mime object for passing on to the transaction handler
+    # The "NotifyOtherRecipients" scripAction will look for RT-Send-Cc: and RT-Send-Bcc:
+    # headers
+
+    $args{'MIMEObj'}->head->add( 'RT-Send-Cc',  $args{'CcMessageTo'} )
+       if defined $args{'CcMessageTo'};
+    $args{'MIMEObj'}->head->add( 'RT-Send-Bcc', $args{'BccMessageTo'} )
+       if defined $args{'BccMessageTo'};
+
+    #Record the correspondence (write the transaction)
+    my ( $Trans, $msg, $TransObj ) = $self->_NewTransaction(
+             Type => 'Correspond',
+             Data => ( $args{'MIMEObj'}->head->get('subject') || 'No Subject' ),
+             TimeTaken => $args{'TimeTaken'},
+             MIMEObj   => $args{'MIMEObj'} );
+
+    unless ($Trans) {
+        $RT::Logger->err( "$self couldn't init a transaction $msg");
+        return ( $Trans, $self->loc("correspondence (probably) not sent"), $args{'MIMEObj'} );
+    }
+
+    #Set the last told date to now if this isn't mail from the requestor.
+    #TODO: Note that this will wrongly ack mail from any non-requestor as a "told"
+
+    unless ( $TransObj->IsInbound ) {
+        $self->_SetTold;
+    }
+
+    return ( $Trans, $self->loc("correspondence sent") );
+}
+
+# }}}
+
+# }}}
+
+# {{{ Routines dealing with Links and Relations between tickets
+
+# {{{ Link Collections
+
+# {{{ sub Members
+
+=head2 Members
+
+  This returns an RT::Links object which references all the tickets 
+which are 'MembersOf' this ticket
+
+=cut
+
+sub Members {
+    my $self = shift;
+    return ( $self->_Links( 'Target', 'MemberOf' ) );
+}
+
+# }}}
+
+# {{{ sub MemberOf
+
+=head2 MemberOf
+
+  This returns an RT::Links object which references all the tickets that this
+ticket is a 'MemberOf'
+
+=cut
+
+sub MemberOf {
+    my $self = shift;
+    return ( $self->_Links( 'Base', 'MemberOf' ) );
+}
+
+# }}}
+
+# {{{ RefersTo
+
+=head2 RefersTo
+
+  This returns an RT::Links object which shows all references for which this ticket is a base
+
+=cut
+
+sub RefersTo {
+    my $self = shift;
+    return ( $self->_Links( 'Base', 'RefersTo' ) );
+}
+
+# }}}
+
+# {{{ ReferredToBy
+
+=head2 ReferredToBy
+
+  This returns an RT::Links object which shows all references for which this ticket is a target
+
+=cut
+
+sub ReferredToBy {
+    my $self = shift;
+    return ( $self->_Links( 'Target', 'RefersTo' ) );
+}
+
+# }}}
+
+# {{{ DependedOnBy
+
+=head2 DependedOnBy
+
+  This returns an RT::Links object which references all the tickets that depend on this one
+
+=cut
+
+sub DependedOnBy {
+    my $self = shift;
+    return ( $self->_Links( 'Target', 'DependsOn' ) );
+}
+
+# }}}
+
+
+
+=head2 HasUnresolvedDependencies
+
+  Takes a paramhash of Type (default to '__any').  Returns true if
+$self->UnresolvedDependencies returns an object with one or more members
+of that type.  Returns false otherwise
+
+
+=begin testing
+
+my $t1 = RT::Ticket->new($RT::SystemUser);
+my ($id, $trans, $msg) = $t1->Create(Subject => 'DepTest1', Queue => 'general');
+ok($id, "Created dep test 1 - $msg");
+
+my $t2 = RT::Ticket->new($RT::SystemUser);
+my ($id2, $trans, $msg2) = $t2->Create(Subject => 'DepTest2', Queue => 'general');
+ok($id2, "Created dep test 2 - $msg2");
+my $t3 = RT::Ticket->new($RT::SystemUser);
+my ($id3, $trans, $msg3) = $t3->Create(Subject => 'DepTest3', Queue => 'general', Type => 'approval');
+ok($id3, "Created dep test 3 - $msg3");
+
+ok ($t1->AddLink( Type => 'DependsOn', Target => $t2->id));
+ok ($t1->AddLink( Type => 'DependsOn', Target => $t3->id));
+
+ok ($t1->HasUnresolvedDependencies, "Ticket ".$t1->Id." has unresolved deps");
+ok (!$t1->HasUnresolvedDependencies( Type => 'blah' ), "Ticket ".$t1->Id." has no unresolved blahs");
+ok ($t1->HasUnresolvedDependencies( Type => 'approval' ), "Ticket ".$t1->Id." has unresolved approvals");
+ok (!$t2->HasUnresolvedDependencies, "Ticket ".$t2->Id." has no unresolved deps");
+my ($rid, $rmsg)= $t1->Resolve();
+ok(!$rid, $rmsg);
+ok($t2->Resolve);
+($rid, $rmsg)= $t1->Resolve();
+ok(!$rid, $rmsg);
+ok($t3->Resolve);
+($rid, $rmsg)= $t1->Resolve();
+ok($rid, $rmsg);
+
+
+=end testing
+
+=cut
+
+sub HasUnresolvedDependencies {
+    my $self = shift;
+    my %args = (
+        Type   => undef,
+        @_
+    );
+
+    my $deps = $self->UnresolvedDependencies;
+
+    if ($args{Type}) {
+        $deps->Limit( FIELD => 'Type', 
+              OPERATOR => '=',
+              VALUE => $args{Type}); 
+    }
+    else {
+           $deps->IgnoreType;
+    }
+
+    if ($deps->Count > 0) {
+        return 1;
+    }
+    else {
+        return (undef);
+    }
+}
+
+
+# {{{ UnresolvedDependencies 
+
+=head2 UnresolvedDependencies
+
+Returns an RT::Tickets object of tickets which this ticket depends on
+and which have a status of new, open or stalled. (That list comes from
+RT::Queue->ActiveStatusArray
+
+=cut
+
+
+sub UnresolvedDependencies {
+    my $self = shift;
+    my $deps = RT::Tickets->new($self->CurrentUser);
+
+    my @live_statuses = RT::Queue->ActiveStatusArray();
+    foreach my $status (@live_statuses) {
+        $deps->LimitStatus(VALUE => $status);
+    }
+    $deps->LimitDependedOnBy($self->Id);
+
+    return($deps);
+
+}
+
+# }}}
+
+# {{{ AllDependedOnBy
+
+=head2 AllDependedOnBy
+
+Returns an array of RT::Ticket objects which (directly or indirectly)
+depends on this ticket; takes an optional 'Type' argument in the param
+hash, which will limit returned tickets to that type, as well as cause
+tickets with that type to serve as 'leaf' nodes that stops the recursive
+dependency search.
+
+=cut
+
+sub AllDependedOnBy {
+    my $self = shift;
+    my $dep = $self->DependedOnBy;
+    my %args = (
+        Type   => undef,
+       _found => {},
+       _top   => 1,
+        @_
+    );
+
+    while (my $link = $dep->Next()) {
+       next unless ($link->BaseURI->IsLocal());
+       next if $args{_found}{$link->BaseObj->Id};
+
+       if (!$args{Type}) {
+           $args{_found}{$link->BaseObj->Id} = $link->BaseObj;
+           $link->BaseObj->AllDependedOnBy( %args, _top => 0 );
+       }
+       elsif ($link->BaseObj->Type eq $args{Type}) {
+           $args{_found}{$link->BaseObj->Id} = $link->BaseObj;
+       }
+       else {
+           $link->BaseObj->AllDependedOnBy( %args, _top => 0 );
+       }
+    }
+
+    if ($args{_top}) {
+       return map { $args{_found}{$_} } sort keys %{$args{_found}};
+    }
+    else {
+       return 1;
+    }
+}
+
+# }}}
+
+# {{{ DependsOn
+
+=head2 DependsOn
+
+  This returns an RT::Links object which references all the tickets that this ticket depends on
+
+=cut
+
+sub DependsOn {
+    my $self = shift;
+    return ( $self->_Links( 'Base', 'DependsOn' ) );
+}
+
+# }}}
+
+
+
+
+# {{{ sub _Links 
+
+sub _Links {
+    my $self = shift;
+
+    #TODO: Field isn't the right thing here. but I ahave no idea what mnemonic ---
+    #tobias meant by $f
+    my $field = shift;
+    my $type  = shift || "";
+
+    unless ( $self->{"$field$type"} ) {
+        $self->{"$field$type"} = new RT::Links( $self->CurrentUser );
+        if ( $self->CurrentUserHasRight('ShowTicket') ) {
+            # Maybe this ticket is a merged ticket
+            my $Tickets = new RT::Tickets( $self->CurrentUser );
+            # at least to myself
+            $self->{"$field$type"}->Limit( FIELD => $field,
+                                           VALUE => $self->URI,
+                                           ENTRYAGGREGATOR => 'OR' );
+            $Tickets->Limit( FIELD => 'EffectiveId',
+                             VALUE => $self->EffectiveId );
+            while (my $Ticket = $Tickets->Next) {
+                $self->{"$field$type"}->Limit( FIELD => $field,
+                                               VALUE => $Ticket->URI,
+                                               ENTRYAGGREGATOR => 'OR' );
+            }
+            $self->{"$field$type"}->Limit( FIELD => 'Type',
+                                           VALUE => $type )
+              if ($type);
+        }
+    }
+    return ( $self->{"$field$type"} );
+}
+
+# }}}
+
+# }}}
+
+# {{{ sub DeleteLink 
+
+=head2 DeleteLink
+
+Delete a link. takes a paramhash of Base, Target and Type.
+Either Base or Target must be null. The null value will 
+be replaced with this ticket\'s id
+
+=cut 
+
+sub DeleteLink {
+    my $self = shift;
+    my %args = (
+        Base   => undef,
+        Target => undef,
+        Type   => undef,
+        @_
+    );
+
+    #check acls
+    unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+        $RT::Logger->debug("No permission to delete links\n");
+        return ( 0, $self->loc('Permission Denied'))
+
+    }
+
+    #we want one of base and target. we don't care which
+    #but we only want _one_
+
+    my $direction;
+    my $remote_link;
+
+    if ( $args{'Base'} and $args{'Target'} ) {
+        $RT::Logger->debug("$self ->_DeleteLink. got both Base and Target\n");
+        return ( 0, $self->loc("Can't specifiy both base and target") );
+    }
+    elsif ( $args{'Base'} ) {
+        $args{'Target'} = $self->URI();
+       $remote_link = $args{'Base'};
+       $direction = 'Target';
+    }
+    elsif ( $args{'Target'} ) {
+        $args{'Base'} = $self->URI();
+       $remote_link = $args{'Target'};
+        $direction='Base';
+    }
+    else {
+        $RT::Logger->debug("$self: Base or Target must be specified\n");
+        return ( 0, $self->loc('Either base or target must be specified') );
+    }
+
+    my $link = new RT::Link( $self->CurrentUser );
+    $RT::Logger->debug( "Trying to load link: " . $args{'Base'} . " " . $args{'Type'} . " " . $args{'Target'} . "\n" );
+
+
+    $link->LoadByParams( Base=> $args{'Base'}, Type=> $args{'Type'}, Target=>  $args{'Target'} );
+    #it's a real link. 
+    if ( $link->id ) {
+
+        my $linkid = $link->id;
+        $link->Delete();
+
+        my $TransString = "Ticket $args{'Base'} no longer $args{Type} ticket $args{'Target'}.";
+       my $remote_uri = RT::URI->new( $RT::SystemUser );
+       $remote_uri->FromURI( $remote_link );
+
+        my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
+            Type      => 'DeleteLink',
+            Field => $LINKDIRMAP{$args{'Type'}}->{$direction},
+           OldValue =>  $remote_uri->URI || $remote_link,
+            TimeTaken => 0
+        );
+
+        return ( $Trans, $self->loc("Link deleted ([_1])", $TransString));
+    }
+
+    #if it's not a link we can find
+    else {
+        $RT::Logger->debug("Couldn't find that link\n");
+        return ( 0, $self->loc("Link not found") );
+    }
+}
+
+# }}}
+
+# {{{ sub AddLink
+
+=head2 AddLink
+
+Takes a paramhash of Type and one of Base or Target. Adds that link to this ticket.
+
+
+=cut
+
+sub AddLink {
+    my $self = shift;
+    my %args = ( Target => '',
+                 Base   => '',
+                 Type   => '',
+                 Silent => undef,
+                 @_ );
+
+    unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+    # Remote_link is the URI of the object that is not this ticket
+    my $remote_link;
+    my $direction;
+
+    if ( $args{'Base'} and $args{'Target'} ) {
+        $RT::Logger->debug(
+"$self tried to delete a link. both base and target were specified\n" );
+        return ( 0, $self->loc("Can't specifiy both base and target") );
+    }
+    elsif ( $args{'Base'} ) {
+        $args{'Target'} = $self->URI();
+       $remote_link = $args{'Base'};
+       $direction = 'Target';
+    }
+    elsif ( $args{'Target'} ) {
+        $args{'Base'} = $self->URI();
+       $remote_link = $args{'Target'};
+        $direction='Base';
+    }
+    else {
+        return ( 0, $self->loc('Either base or target must be specified') );
+    }
+
+    # If the base isn't a URI, make it a URI. 
+    # If the target isn't a URI, make it a URI. 
+
+    # {{{ Check if the link already exists - we don't want duplicates
+    use RT::Link;
+    my $old_link = RT::Link->new( $self->CurrentUser );
+    $old_link->LoadByParams( Base   => $args{'Base'},
+                             Type   => $args{'Type'},
+                             Target => $args{'Target'} );
+    if ( $old_link->Id ) {
+        $RT::Logger->debug("$self Somebody tried to duplicate a link");
+        return ( $old_link->id, $self->loc("Link already exists"), 0 );
+    }
+
+    # }}}
+
+    # Storing the link in the DB.
+    my $link = RT::Link->new( $self->CurrentUser );
+    my ($linkid) = $link->Create( Target => $args{Target},
+                                  Base   => $args{Base},
+                                  Type   => $args{Type} );
+
+    unless ($linkid) {
+        return ( 0, $self->loc("Link could not be created") );
+    }
+
+    my $TransString =
+      "Ticket $args{'Base'} $args{Type} ticket $args{'Target'}.";
+
+    # Don't write the transaction if we're doing this on create
+    if ( $args{'Silent'} ) {
+        return ( 1, $self->loc( "Link created ([_1])", $TransString ) );
+    }
+    else {
+       my $remote_uri = RT::URI->new( $RT::SystemUser );
+       $remote_uri->FromURI( $remote_link );
+
+        #Write the transaction
+        my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
+                                                         Type  => 'AddLink',
+                                                         Field => $LINKDIRMAP{$args{'Type'}}->{$direction},
+                                                                                    NewValue =>  $remote_uri->URI || $remote_link,
+                                                         TimeTaken => 0 );
+        return ( $Trans, $self->loc( "Link created ([_1])", $TransString ) );
+    }
+
+}
+
+# }}}
+
+# {{{ sub URI 
+
+=head2 URI
+
+Returns this ticket's URI
+
+=cut
+
+sub URI {
+    my $self = shift;
+    my $uri = RT::URI::fsck_com_rt->new($self->CurrentUser);
+    return($uri->URIForObject($self));
+}
+
+# }}}
+
+# {{{ sub MergeInto
+
+=head2 MergeInto
+MergeInto take the id of the ticket to merge this ticket into.
+
+=cut
+
+sub MergeInto {
+    my $self      = shift;
+    my $MergeInto = shift;
+
+    unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+    # Load up the new ticket.
+    my $NewTicket = RT::Ticket->new($RT::SystemUser);
+    $NewTicket->Load($MergeInto);
+
+    # make sure it exists.
+    unless ( defined $NewTicket->Id ) {
+        return ( 0, $self->loc("New ticket doesn't exist") );
+    }
+
+    # Make sure the current user can modify the new ticket.
+    unless ( $NewTicket->CurrentUserHasRight('ModifyTicket') ) {
+        $RT::Logger->debug("failed...");
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+    $RT::Logger->debug(
+        "checking if the new ticket has the same id and effective id...");
+    unless ( $NewTicket->id == $NewTicket->EffectiveId ) {
+        $RT::Logger->err( "$self trying to merge into "
+              . $NewTicket->Id
+              . " which is itself merged.\n" );
+        return ( 0,
+            $self->loc("Can't merge into a merged ticket. You should never get this error") );
+    }
+
+    # We use EffectiveId here even though it duplicates information from
+    # the links table becasue of the massive performance hit we'd take
+    # by trying to do a seperate database query for merge info everytime 
+    # loaded a ticket. 
+
+    #update this ticket's effective id to the new ticket's id.
+    my ( $id_val, $id_msg ) = $self->__Set(
+        Field => 'EffectiveId',
+        Value => $NewTicket->Id()
+    );
+
+    unless ($id_val) {
+        $RT::Logger->error(
+            "Couldn't set effective ID for " . $self->Id . ": $id_msg" );
+        return ( 0, $self->loc("Merge failed. Couldn't set EffectiveId") );
+    }
+
+    my ( $status_val, $status_msg ) = $self->__Set( Field => 'Status', Value => 'resolved');
+
+    unless ($status_val) {
+        $RT::Logger->error( $self->loc("[_1] couldn't set status to resolved. RT's Database may be inconsistent.", $self) );
+    }
+
+
+    # update all the links that point to that old ticket
+    my $old_links_to = RT::Links->new($self->CurrentUser);
+    $old_links_to->Limit(FIELD => 'Target', VALUE => $self->URI);
+
+    while (my $link = $old_links_to->Next) {
+        if ($link->Base eq $NewTicket->URI) {
+            $link->Delete;
+        } else {
+            $link->SetTarget($NewTicket->URI);
+        }
+
+    }
+
+    my $old_links_from = RT::Links->new($self->CurrentUser);
+    $old_links_from->Limit(FIELD => 'Base', VALUE => $self->URI);
+
+    while (my $link = $old_links_from->Next) {
+        if ($link->Target eq $NewTicket->URI) {
+            $link->Delete;
+        } else {
+            $link->SetBase($NewTicket->URI);
+        }
+
+    }
+
+
+    #make a new link: this ticket is merged into that other ticket.
+    $self->AddLink( Type   => 'MergedInto', Target => $NewTicket->Id());
+
+    #add all of this ticket's watchers to that ticket.
+    my $requestors = $self->Requestors->MembersObj;
+    while (my $watcher = $requestors->Next) { 
+        $NewTicket->_AddWatcher( Type => 'Requestor',
+                                  Silent => 1,
+                                  PrincipalId => $watcher->MemberId);
+    }
+
+    my $Ccs = $self->Cc->MembersObj;
+    while (my $watcher = $Ccs->Next) { 
+        $NewTicket->_AddWatcher( Type => 'Cc',
+                                  Silent => 1,
+                                  PrincipalId => $watcher->MemberId);
+    }
+
+    my $AdminCcs = $self->AdminCc->MembersObj;
+    while (my $watcher = $AdminCcs->Next) { 
+        $NewTicket->_AddWatcher( Type => 'AdminCc',
+                                  Silent => 1,
+                                  PrincipalId => $watcher->MemberId);
+    }
+
+
+    #find all of the tickets that were merged into this ticket. 
+    my $old_mergees = new RT::Tickets( $self->CurrentUser );
+    $old_mergees->Limit(
+        FIELD    => 'EffectiveId',
+        OPERATOR => '=',
+        VALUE    => $self->Id
+    );
+
+    #   update their EffectiveId fields to the new ticket's id
+    while ( my $ticket = $old_mergees->Next() ) {
+        my ( $val, $msg ) = $ticket->__Set(
+            Field => 'EffectiveId',
+            Value => $NewTicket->Id()
+        );
+    }
+
+    $NewTicket->_SetLastUpdated;
+
+    return ( 1, $self->loc("Merge Successful") );
+}
+
+# }}}
+
+# }}}
+
+# {{{ Routines dealing with ownership
+
+# {{{ sub OwnerObj
+
+=head2 OwnerObj
+
+Takes nothing and returns an RT::User object of 
+this ticket's owner
+
+=cut
+
+sub OwnerObj {
+    my $self = shift;
+
+    #If this gets ACLed, we lose on a rights check in User.pm and
+    #get deep recursion. if we need ACLs here, we need
+    #an equiv without ACLs
+
+    my $owner = new RT::User( $self->CurrentUser );
+    $owner->Load( $self->__Value('Owner') );
+
+    #Return the owner object
+    return ($owner);
+}
+
+# }}}
+
+# {{{ sub OwnerAsString 
+
+=head2 OwnerAsString
+
+Returns the owner's email address
+
+=cut
+
+sub OwnerAsString {
+    my $self = shift;
+    return ( $self->OwnerObj->EmailAddress );
+
+}
+
+# }}}
+
+# {{{ sub SetOwner
+
+=head2 SetOwner
+
+Takes two arguments:
+     the Id or Name of the owner 
+and  (optionally) the type of the SetOwner Transaction. It defaults
+to 'Give'.  'Steal' is also a valid option.
+
+=begin testing
+
+my $root = RT::User->new($RT::SystemUser);
+$root->Load('root');
+ok ($root->Id, "Loaded the root user");
+my $t = RT::Ticket->new($RT::SystemUser);
+$t->Load(1);
+$t->SetOwner('root');
+ok ($t->OwnerObj->Name eq 'root' , "Root owns the ticket");
+$t->Steal();
+ok ($t->OwnerObj->id eq $RT::SystemUser->id , "SystemUser owns the ticket");
+my $txns = RT::Transactions->new($RT::SystemUser);
+$txns->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$txns->Limit(FIELD => 'Ticket', VALUE => '1');
+my $steal  = $txns->First;
+ok($steal->OldValue == $root->Id , "Stolen from root");
+ok($steal->NewValue == $RT::SystemUser->Id , "Stolen by the systemuser");
+
+=end testing
+
+=cut
+
+sub SetOwner {
+    my $self     = shift;
+    my $NewOwner = shift;
+    my $Type     = shift || "Give";
+
+    # must have ModifyTicket rights
+    # or TakeTicket/StealTicket and $NewOwner is self
+    # see if it's a take
+    if ( $self->OwnerObj->Id == $RT::Nobody->Id ) {
+        unless (    $self->CurrentUserHasRight('ModifyTicket')
+                 || $self->CurrentUserHasRight('TakeTicket') ) {
+            return ( 0, $self->loc("Permission Denied") );
+        }
+    }
+
+    # see if it's a steal
+    elsif (    $self->OwnerObj->Id != $RT::Nobody->Id
+            && $self->OwnerObj->Id != $self->CurrentUser->id ) {
+
+        unless (    $self->CurrentUserHasRight('ModifyTicket')
+                 || $self->CurrentUserHasRight('StealTicket') ) {
+            return ( 0, $self->loc("Permission Denied") );
+        }
+    }
+    else {
+        unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+            return ( 0, $self->loc("Permission Denied") );
+        }
+    }
+    my $NewOwnerObj = RT::User->new( $self->CurrentUser );
+    my $OldOwnerObj = $self->OwnerObj;
+
+    $NewOwnerObj->Load($NewOwner);
+    if ( !$NewOwnerObj->Id ) {
+        return ( 0, $self->loc("That user does not exist") );
+    }
+
+    #If thie ticket has an owner and it's not the current user
+
+    if (    ( $Type ne 'Steal' )
+        and ( $Type ne 'Force' )
+        and    #If we're not stealing
+        ( $self->OwnerObj->Id != $RT::Nobody->Id ) and    #and the owner is set
+        ( $self->CurrentUser->Id ne $self->OwnerObj->Id() )
+      ) {                                                 #and it's not us
+        return ( 0,
+                 $self->loc(
+"You can only reassign tickets that you own or that are unowned" ) );
+    }
+
+    #If we've specified a new owner and that user can't modify the ticket
+    elsif ( ( $NewOwnerObj->Id )
+            and ( !$NewOwnerObj->HasRight( Right  => 'OwnTicket',
+                                           Object => $self ) )
+      ) {
+        return ( 0, $self->loc("That user may not own tickets in that queue") );
+    }
+
+    #If the ticket has an owner and it's the new owner, we don't need
+    #To do anything
+    elsif (     ( $self->OwnerObj )
+            and ( $NewOwnerObj->Id eq $self->OwnerObj->Id ) ) {
+        return ( 0, $self->loc("That user already owns that ticket") );
+    }
+
+    $RT::Handle->BeginTransaction();
+
+    # Delete the owner in the owner group, then add a new one
+    # TODO: is this safe? it's not how we really want the API to work
+    # for most things, but it's fast.
+    my ( $del_id, $del_msg ) = $self->OwnerGroup->MembersObj->First->Delete();
+    unless ($del_id) {
+        $RT::Handle->Rollback();
+        return ( 0, $self->loc("Could not change owner. ") . $del_msg );
+    }
+
+    my ( $add_id, $add_msg ) = $self->OwnerGroup->_AddMember(
+                                       PrincipalId => $NewOwnerObj->PrincipalId,
+                                       InsideTransaction => 1 );
+    unless ($add_id) {
+        $RT::Handle->Rollback();
+        return ( 0, $self->loc("Could not change owner. ") . $add_msg );
+    }
+
+    # We call set twice with slightly different arguments, so
+    # as to not have an SQL transaction span two RT transactions
+
+    my ( $val, $msg ) = $self->_Set(
+                      Field             => 'Owner',
+                      RecordTransaction => 0,
+                      Value             => $NewOwnerObj->Id,
+                      TimeTaken         => 0,
+                      TransactionType   => $Type,
+                      CheckACL          => 0,                  # don't check acl
+    );
+
+    unless ($val) {
+        $RT::Handle->Rollback;
+        return ( 0, $self->loc("Could not change owner. ") . $msg );
+    }
+
+    $RT::Handle->Commit();
+
+    my ( $trans, $msg, undef ) = $self->_NewTransaction(
+                                                   Type     => $Type,
+                                                   Field    => 'Owner',
+                                                   NewValue => $NewOwnerObj->Id,
+                                                   OldValue => $OldOwnerObj->Id,
+                                                   TimeTaken => 0 );
+
+    if ($trans) {
+        $msg = $self->loc( "Owner changed from [_1] to [_2]",
+                           $OldOwnerObj->Name, $NewOwnerObj->Name );
+
+        # TODO: make sure the trans committed properly
+    }
+    return ( $trans, $msg );
+
+}
+
+# }}}
+
+# {{{ sub Take
+
+=head2 Take
+
+A convenince method to set the ticket's owner to the current user
+
+=cut
+
+sub Take {
+    my $self = shift;
+    return ( $self->SetOwner( $self->CurrentUser->Id, 'Take' ) );
+}
+
+# }}}
+
+# {{{ sub Untake
+
+=head2 Untake
+
+Convenience method to set the owner to 'nobody' if the current user is the owner.
+
+=cut
+
+sub Untake {
+    my $self = shift;
+    return ( $self->SetOwner( $RT::Nobody->UserObj->Id, 'Untake' ) );
+}
+
+# }}}
+
+# {{{ sub Steal 
+
+=head2 Steal
+
+A convenience method to change the owner of the current ticket to the
+current user. Even if it's owned by another user.
+
+=cut
+
+sub Steal {
+    my $self = shift;
+
+    if ( $self->IsOwner( $self->CurrentUser ) ) {
+        return ( 0, $self->loc("You already own this ticket") );
+    }
+    else {
+        return ( $self->SetOwner( $self->CurrentUser->Id, 'Steal' ) );
+
+    }
+
+}
+
+# }}}
+
+# }}}
+
+# {{{ Routines dealing with status
+
+# {{{ sub ValidateStatus 
+
+=head2 ValidateStatus STATUS
+
+Takes a string. Returns true if that status is a valid status for this ticket.
+Returns false otherwise.
+
+=cut
+
+sub ValidateStatus {
+    my $self   = shift;
+    my $status = shift;
+
+    #Make sure the status passed in is valid
+    unless ( $self->QueueObj->IsValidStatus($status) ) {
+        return (undef);
+    }
+
+    return (1);
+
+}
+
+# }}}
+
+# {{{ sub SetStatus
+
+=head2 SetStatus STATUS
+
+Set this ticket\'s status. STATUS can be one of: new, open, stalled, resolved, rejected or deleted.
+
+Alternatively, you can pass in a list of named parameters (Status => STATUS, Force => FORCE).  If FORCE is true, ignore unresolved dependencies and force a status change.
+
+=begin testing
+
+my $tt = RT::Ticket->new($RT::SystemUser);
+my ($id, $tid, $msg)= $tt->Create(Queue => 'general',
+            Subject => 'test');
+ok($id, $msg);
+ok($tt->Status eq 'new', "New ticket is created as new");
+
+($id, $msg) = $tt->SetStatus('open');
+ok($id, $msg);
+ok ($msg =~ /open/i, "Status message is correct");
+($id, $msg) = $tt->SetStatus('resolved');
+ok($id, $msg);
+ok ($msg =~ /resolved/i, "Status message is correct");
+($id, $msg) = $tt->SetStatus('resolved');
+ok(!$id,$msg);
+
+
+=end testing
+
+
+=cut
+
+sub SetStatus {
+    my $self   = shift;
+    my %args;
+
+    if (@_ == 1) {
+       $args{Status} = shift;
+    }
+    else {
+       %args = (@_);
+    }
+
+    #Check ACL
+    unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+        return ( 0, $self->loc('Permission Denied') );
+    }
+
+    if (!$args{Force} && ($args{'Status'} eq 'resolved') && $self->HasUnresolvedDependencies) {
+        return (0, $self->loc('That ticket has unresolved dependencies'));
+    }
+
+    my $now = RT::Date->new( $self->CurrentUser );
+    $now->SetToNow();
+
+    #If we're changing the status from new, record that we've started
+    if ( ( $self->Status =~ /new/ ) && ( $args{Status} ne 'new' ) ) {
+
+        #Set the Started time to "now"
+        $self->_Set( Field             => 'Started',
+                     Value             => $now->ISO,
+                     RecordTransaction => 0 );
+    }
+
+    if ( $args{Status} =~ /^(resolved|rejected|dead)$/ ) {
+
+        #When we resolve a ticket, set the 'Resolved' attribute to now.
+        $self->_Set( Field             => 'Resolved',
+                     Value             => $now->ISO,
+                     RecordTransaction => 0 );
+    }
+
+    #Actually update the status
+   my ($val, $msg)= $self->_Set( Field           => 'Status',
+                          Value           => $args{Status},
+                          TimeTaken       => 0,
+                          TransactionType => 'Status'  );
+
+    return($val,$msg);
+}
+
+# }}}
+
+# {{{ sub Kill
+
+=head2 Kill
+
+Takes no arguments. Marks this ticket for garbage collection
+
+=cut
+
+sub Kill {
+    my $self = shift;
+    $RT::Logger->crit("'Kill' is deprecated. use 'Delete' instead.");
+    return $self->Delete;
+}
+
+sub Delete {
+    my $self = shift;
+    return ( $self->SetStatus('deleted') );
+
+    # TODO: garbage collection
+}
+
+# }}}
+
+# {{{ sub Stall
+
+=head2 Stall
+
+Sets this ticket's status to stalled
+
+=cut
+
+sub Stall {
+    my $self = shift;
+    return ( $self->SetStatus('stalled') );
+}
+
+# }}}
+
+# {{{ sub Reject
+
+=head2 Reject
+
+Sets this ticket's status to rejected
+
+=cut
+
+sub Reject {
+    my $self = shift;
+    return ( $self->SetStatus('rejected') );
+}
+
+# }}}
+
+# {{{ sub Open
+
+=head2 Open
+
+Sets this ticket\'s status to Open
+
+=cut
+
+sub Open {
+    my $self = shift;
+    return ( $self->SetStatus('open') );
+}
+
+# }}}
+
+# {{{ sub Resolve
+
+=head2 Resolve
+
+Sets this ticket\'s status to Resolved
+
+=cut
+
+sub Resolve {
+    my $self = shift;
+    return ( $self->SetStatus('resolved') );
+}
+
+# }}}
+
+# }}}
+
+# {{{ Routines dealing with custom fields
+
+
+# {{{ FirstCustomFieldValue
+
+=item FirstCustomFieldValue FIELD
+
+Return the content of the first value of CustomField FIELD for this ticket
+Takes a field id or name
+
+=cut
+
+sub FirstCustomFieldValue {
+    my $self = shift;
+    my $field = shift;
+    my $values = $self->CustomFieldValues($field);
+    if ($values->First) {
+        return $values->First->Content;
+    } else {
+        return undef;
+    }
+
+}
+
+
+
+# {{{ CustomFieldValues
+
+=item CustomFieldValues FIELD
+
+Return a TicketCustomFieldValues object of all values of CustomField FIELD for this ticket.  
+Takes a field id or name.
+
+
+=cut
+
+sub CustomFieldValues {
+    my $self  = shift;
+    my $field = shift;
+
+    my $cf = RT::CustomField->new($self->CurrentUser);
+
+    if ($field =~ /^\d+$/) {
+        $cf->LoadById($field);
+    } else {
+        $cf->LoadByNameAndQueue(Name => $field, Queue => $self->QueueObj->Id);
+    }
+    my $cf_values = RT::TicketCustomFieldValues->new( $self->CurrentUser );
+    $cf_values->LimitToCustomField($cf->id);
+    $cf_values->LimitToTicket($self->Id());
+
+    # @values is a CustomFieldValues object;
+    return ($cf_values);
+}
+
+# }}}
+
+# {{{ AddCustomFieldValue
+
+=item AddCustomFieldValue { Field => FIELD, Value => VALUE }
+
+VALUE can either be a CustomFieldValue object or a string.
+FIELD can be a CustomField object OR a CustomField ID.
+
+
+Adds VALUE as a value of CustomField FIELD.  If this is a single-value custom field,
+deletes the old value. 
+If VALUE isn't a valid value for the custom field, returns 
+(0, 'Error message' ) otherwise, returns (1, 'Success Message')
+
+=cut
+
+sub AddCustomFieldValue {
+    my $self = shift;
+    unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+    $self->_AddCustomFieldValue(@_);
+}
+
+sub _AddCustomFieldValue {
+    my $self = shift;
+    my %args = (
+        Field => undef,
+        Value => undef,
+       RecordTransaction => 1,
+        @_
+    );
+
+    my $cf = RT::CustomField->new( $self->CurrentUser );
+    if ( UNIVERSAL::isa( $args{'Field'}, "RT::CustomField" ) ) {
+        $cf->Load( $args{'Field'}->id );
+    }
+    else {
+        $cf->Load( $args{'Field'} );
+    }
+
+    unless ( $cf->Id ) {
+        return ( 0, $self->loc("Custom field [_1] not found", $args{'Field'}) );
+    }
+
+    # Load up a TicketCustomFieldValues object for this custom field and this ticket
+    my $values = $cf->ValuesForTicket( $self->id );
+
+    unless ( $cf->ValidateValue( $args{'Value'} ) ) {
+        return ( 0, $self->loc("Invalid value for custom field") );
+    }
+
+    # If the custom field only accepts a single value, delete the existing
+    # value and record a "changed from foo to bar" transaction
+    if ( $cf->SingleValue ) {
+
+        # We need to whack any old values here.  In most cases, the custom field should
+        # only have one value to delete.  In the pathalogical case, this custom field
+        # used to be a multiple and we have many values to whack....
+        my $cf_values = $values->Count;
+
+        if ( $cf_values > 1 ) {
+            my $i = 0;   #We want to delete all but the last one, so we can then
+                 # execute the same code to "change" the value from old to new
+            while ( my $value = $values->Next ) {
+                $i++;
+                if ( $i < $cf_values ) {
+                    my $old_value = $value->Content;
+                    my ($val, $msg) = $cf->DeleteValueForTicket(Ticket => $self->Id, Content => $value->Content);
+                    unless ($val) {
+                        return (0,$msg);
+                    }
+                    my ( $TransactionId, $Msg, $TransactionObj ) =
+                      $self->_NewTransaction(
+                        Type     => 'CustomField',
+                        Field    => $cf->Id,
+                        OldValue => $old_value
+                      );
+                }
+            }
+        }
+
+        my $old_value;
+        if (my $value = $cf->ValuesForTicket( $self->Id )->First) {
+           $old_value = $value->Content();
+           return (1) if $old_value eq $args{'Value'};
+       }
+
+        my ( $new_value_id, $value_msg ) = $cf->AddValueForTicket(
+            Ticket  => $self->Id,
+            Content => $args{'Value'}
+        );
+
+        unless ($new_value_id) {
+            return ( 0,
+                $self->loc("Could not add new custom field value for ticket. [_1] ",
+                  ,$value_msg) );
+        }
+
+        my $new_value = RT::TicketCustomFieldValue->new( $self->CurrentUser );
+        $new_value->Load($new_value_id);
+
+        # now that adding the new value was successful, delete the old one
+       if ($old_value) {
+           my ($val, $msg) = $cf->DeleteValueForTicket(Ticket => $self->Id, Content => $old_value);
+           unless ($val) { 
+                       return (0,$msg);
+           }
+       }
+
+       if ($args{'RecordTransaction'}) {
+        my ( $TransactionId, $Msg, $TransactionObj ) = $self->_NewTransaction(
+            Type     => 'CustomField',
+            Field    => $cf->Id,
+            OldValue => $old_value,
+            NewValue => $new_value->Content
+        );
+       }
+
+        if ( $old_value eq '' ) {
+            return ( 1, $self->loc("[_1] [_2] added", $cf->Name, $new_value->Content) );
+        }
+        elsif ( $new_value->Content eq '' ) {
+            return ( 1, $self->loc("[_1] [_2] deleted", $cf->Name, $old_value) );
+        }
+        else {
+            return ( 1, $self->loc("[_1] [_2] changed to [_3]", $cf->Name, $old_value, $new_value->Content ) );
+        }
+
+    }
+
+    # otherwise, just add a new value and record "new value added"
+    else {
+        my ( $new_value_id ) = $cf->AddValueForTicket(
+            Ticket  => $self->Id,
+            Content => $args{'Value'}
+        );
+
+        unless ($new_value_id) {
+            return ( 0,
+                $self->loc("Could not add new custom field value for ticket. "));
+        }
+    if ( $args{'RecordTransaction'} ) {
+        my ( $TransactionId, $Msg, $TransactionObj ) = $self->_NewTransaction(
+            Type     => 'CustomField',
+            Field    => $cf->Id,
+            NewValue => $args{'Value'}
+        );
+        unless ($TransactionId) {
+            return ( 0,
+                $self->loc( "Couldn't create a transaction: [_1]", $Msg ) );
+        }
+    }
+        return ( 1, $self->loc("[_1] added as a value for [_2]",$args{'Value'}, $cf->Name));
+    }
+
+}
+
+# }}}
+
+# {{{ DeleteCustomFieldValue
+
+=item DeleteCustomFieldValue { Field => FIELD, Value => VALUE }
+
+Deletes VALUE as a value of CustomField FIELD. 
+
+VALUE can be a string, a CustomFieldValue or a TicketCustomFieldValue.
+
+If VALUE isn't a valid value for the custom field, returns 
+(0, 'Error message' ) otherwise, returns (1, 'Success Message')
+
+=cut
+
+sub DeleteCustomFieldValue {
+    my $self = shift;
+    my %args = (
+        Field => undef,
+        Value => undef,
+        @_);
+
+    unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+    my $cf = RT::CustomField->new( $self->CurrentUser );
+    if ( UNIVERSAL::isa( $args{'Field'}, "RT::CustomField" ) ) {
+        $cf->LoadById( $args{'Field'}->id );
+    }
+    else {
+        $cf->LoadById( $args{'Field'} );
+    }
+
+    unless ( $cf->Id ) {
+        return ( 0, $self->loc("Custom field not found") );
+    }
+
+
+     my ($val, $msg) = $cf->DeleteValueForTicket(Ticket => $self->Id, Content => $args{'Value'});
+     unless ($val) { 
+            return (0,$msg);
+     }
+        my ( $TransactionId, $Msg, $TransactionObj ) = $self->_NewTransaction(
+            Type     => 'CustomField',
+            Field    => $cf->Id,
+            OldValue => $args{'Value'}
+        );
+        unless($TransactionId) {
+            return(0, $self->loc("Couldn't create a transaction: [_1]", $Msg));
+        } 
+
+        return($TransactionId, $self->loc("[_1] is no longer a value for custom field [_2]", $args{'Value'}, $cf->Name));
+}
+
+# }}}
+
+# }}}
+
+# {{{ Actions + Routines dealing with transactions
+
+# {{{ sub SetTold and _SetTold
+
+=head2 SetTold ISO  [TIMETAKEN]
+
+Updates the told and records a transaction
+
+=cut
+
+sub SetTold {
+    my $self = shift;
+    my $told;
+    $told = shift if (@_);
+    my $timetaken = shift || 0;
+
+    unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+    my $datetold = new RT::Date( $self->CurrentUser );
+    if ($told) {
+        $datetold->Set( Format => 'iso',
+                        Value  => $told );
+    }
+    else {
+        $datetold->SetToNow();
+    }
+
+    return ( $self->_Set( Field           => 'Told',
+                          Value           => $datetold->ISO,
+                          TimeTaken       => $timetaken,
+                          TransactionType => 'Told' ) );
+}
+
+=head2 _SetTold
+
+Updates the told without a transaction or acl check. Useful when we're sending replies.
+
+=cut
+
+sub _SetTold {
+    my $self = shift;
+
+    my $now = new RT::Date( $self->CurrentUser );
+    $now->SetToNow();
+
+    #use __Set to get no ACLs ;)
+    return ( $self->__Set( Field => 'Told',
+                           Value => $now->ISO ) );
+}
+
+# }}}
+
+# {{{ sub Transactions 
+
+=head2 Transactions
+
+  Returns an RT::Transactions object of all transactions on this ticket
+
+=cut
+
+sub Transactions {
+    my $self = shift;
+
+    use RT::Transactions;
+    my $transactions = RT::Transactions->new( $self->CurrentUser );
+
+    #If the user has no rights, return an empty object
+    if ( $self->CurrentUserHasRight('ShowTicket') ) {
+        my $tickets = $transactions->NewAlias('Tickets');
+        $transactions->Join(
+            ALIAS1 => 'main',
+            FIELD1 => 'Ticket',
+            ALIAS2 => $tickets,
+            FIELD2 => 'id'
+        );
+        $transactions->Limit(
+            ALIAS => $tickets,
+            FIELD => 'EffectiveId',
+            VALUE => $self->id()
+        );
+
+        # if the user may not see comments do not return them
+        unless ( $self->CurrentUserHasRight('ShowTicketComments') ) {
+            $transactions->Limit(
+                FIELD    => 'Type',
+                OPERATOR => '!=',
+                VALUE    => "Comment"
+            );
+        }
+    }
+
+    return ($transactions);
+}
+
+# }}}
+
+# {{{ sub _NewTransaction
+
+sub _NewTransaction {
+    my $self = shift;
+    my %args = (
+        TimeTaken => 0,
+        Type      => undef,
+        OldValue  => undef,
+        NewValue  => undef,
+        Data      => undef,
+        Field     => undef,
+        MIMEObj   => undef,
+        @_
+    );
+
+    require RT::Transaction;
+    my $trans = new RT::Transaction( $self->CurrentUser );
+    my ( $transaction, $msg ) = $trans->Create(
+        Ticket    => $self->Id,
+        TimeTaken => $args{'TimeTaken'},
+        Type      => $args{'Type'},
+        Data      => $args{'Data'},
+        Field     => $args{'Field'},
+        NewValue  => $args{'NewValue'},
+        OldValue  => $args{'OldValue'},
+        MIMEObj   => $args{'MIMEObj'}
+    );
+
+
+    $self->Load($self->Id);
+
+    $RT::Logger->warning($msg) unless $transaction;
+
+    $self->_SetLastUpdated;
+
+    if ( defined $args{'TimeTaken'} ) {
+        $self->_UpdateTimeTaken( $args{'TimeTaken'} );
+    }
+    return ( $transaction, $msg, $trans );
+}
+
+# }}}
+
+# }}}
+
+# {{{ PRIVATE UTILITY METHODS. Mostly needed so Ticket can be a DBIx::Record
+
+# {{{ sub _ClassAccessible
+
+sub _ClassAccessible {
+    {
+        EffectiveId       => { 'read' => 1,  'write' => 1,  'public' => 1 },
+          Queue           => { 'read' => 1,  'write' => 1 },
+          Requestors      => { 'read' => 1,  'write' => 1 },
+          Owner           => { 'read' => 1,  'write' => 1 },
+          Subject         => { 'read' => 1,  'write' => 1 },
+          InitialPriority => { 'read' => 1,  'write' => 1 },
+          FinalPriority   => { 'read' => 1,  'write' => 1 },
+          Priority        => { 'read' => 1,  'write' => 1 },
+          Status          => { 'read' => 1,  'write' => 1 },
+          TimeEstimated      => { 'read' => 1,  'write' => 1 },
+          TimeWorked      => { 'read' => 1,  'write' => 1 },
+          TimeLeft        => { 'read' => 1,  'write' => 1 },
+          Created         => { 'read' => 1,  'auto'  => 1 },
+          Creator         => { 'read' => 1,  'auto'  => 1 },
+          Told            => { 'read' => 1,  'write' => 1 },
+          Resolved        => { 'read' => 1 },
+          Type            => { 'read' => 1 },
+          Starts        => { 'read' => 1, 'write' => 1 },
+          Started       => { 'read' => 1, 'write' => 1 },
+          Due           => { 'read' => 1, 'write' => 1 },
+          Creator       => { 'read' => 1, 'auto'  => 1 },
+          Created       => { 'read' => 1, 'auto'  => 1 },
+          LastUpdatedBy => { 'read' => 1, 'auto'  => 1 },
+          LastUpdated   => { 'read' => 1, 'auto'  => 1 }
+    };
+
+}
+
+# }}}
+
+# {{{ sub _Set
+
+sub _Set {
+    my $self = shift;
+
+    my %args = ( Field             => undef,
+                 Value             => undef,
+                 TimeTaken         => 0,
+                 RecordTransaction => 1,
+                 UpdateTicket      => 1,
+                 CheckACL          => 1,
+                 TransactionType   => 'Set',
+                 @_ );
+
+    if ($args{'CheckACL'}) {
+      unless ( $self->CurrentUserHasRight('ModifyTicket')) {
+          return ( 0, $self->loc("Permission Denied"));
+      }
+   }
+
+    unless ($args{'UpdateTicket'} || $args{'RecordTransaction'}) {
+        $RT::Logger->error("Ticket->_Set called without a mandate to record an update or update the ticket");
+        return(0, $self->loc("Internal Error"));
+    }
+
+    #if the user is trying to modify the record
+
+    #Take care of the old value we really don't want to get in an ACL loop.
+    # so ask the super::_Value
+    my $Old = $self->SUPER::_Value("$args{'Field'}");
+    
+    my ($ret, $msg);
+    if ( $args{'UpdateTicket'}  ) {
+
+        #Set the new value
+        ( $ret, $msg ) = $self->SUPER::_Set( Field => $args{'Field'},
+                                                Value => $args{'Value'} );
+    
+        #If we can't actually set the field to the value, don't record
+        # a transaction. instead, get out of here.
+        if ( $ret == 0 ) { return ( 0, $msg ); }
+    }
+
+    if ( $args{'RecordTransaction'} == 1 ) {
+
+        my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
+                                               Type => $args{'TransactionType'},
+                                               Field     => $args{'Field'},
+                                               NewValue  => $args{'Value'},
+                                               OldValue  => $Old,
+                                               TimeTaken => $args{'TimeTaken'},
+        );
+        return ( $Trans, scalar $TransObj->Description );
+    }
+    else {
+        return ( $ret, $msg );
+    }
+}
+
+# }}}
+
+# {{{ sub _Value 
+
+=head2 _Value
+
+Takes the name of a table column.
+Returns its value as a string, if the user passes an ACL check
+
+=cut
+
+sub _Value {
+
+    my $self  = shift;
+    my $field = shift;
+
+    #if the field is public, return it.
+    if ( $self->_Accessible( $field, 'public' ) ) {
+
+        #$RT::Logger->debug("Skipping ACL check for $field\n");
+        return ( $self->SUPER::_Value($field) );
+
+    }
+
+    #If the current user doesn't have ACLs, don't let em at it.  
+
+    unless ( $self->CurrentUserHasRight('ShowTicket') ) {
+        return (undef);
+    }
+    return ( $self->SUPER::_Value($field) );
+
+}
+
+# }}}
+
+# {{{ sub _UpdateTimeTaken
+
+=head2 _UpdateTimeTaken
+
+This routine will increment the timeworked counter. it should
+only be called from _NewTransaction 
+
+=cut
+
+sub _UpdateTimeTaken {
+    my $self    = shift;
+    my $Minutes = shift;
+    my ($Total);
+
+    $Total = $self->SUPER::_Value("TimeWorked");
+    $Total = ( $Total || 0 ) + ( $Minutes || 0 );
+    $self->SUPER::_Set(
+        Field => "TimeWorked",
+        Value => $Total
+    );
+
+    return ($Total);
+}
+
+# }}}
+
+# }}}
+
+# {{{ Routines dealing with ACCESS CONTROL
+
+# {{{ sub CurrentUserHasRight 
+
+=head2 CurrentUserHasRight
+
+  Takes the textual name of a Ticket scoped right (from RT::ACE) and returns
+1 if the user has that right. It returns 0 if the user doesn't have that right.
+
+=cut
+
+sub CurrentUserHasRight {
+    my $self  = shift;
+    my $right = shift;
+
+    return (
+        $self->HasRight(
+            Principal => $self->CurrentUser->UserObj(),
+            Right     => "$right"
+          )
+    );
+
+}
+
+# }}}
+
+# {{{ sub HasRight 
+
+=head2 HasRight
+
+ Takes a paramhash with the attributes 'Right' and 'Principal'
+  'Right' is a ticket-scoped textual right from RT::ACE 
+  'Principal' is an RT::User object
+
+  Returns 1 if the principal has the right. Returns undef if not.
+
+=cut
+
+sub HasRight {
+    my $self = shift;
+    my %args = (
+        Right     => undef,
+        Principal => undef,
+        @_
+    );
+
+    unless ( ( defined $args{'Principal'} ) and ( ref( $args{'Principal'} ) ) )
+    {
+        $RT::Logger->warning("Principal attrib undefined for Ticket::HasRight");
+    }
+
+    return (
+        $args{'Principal'}->HasRight(
+            Object => $self,
+            Right     => $args{'Right'}
+          )
+    );
+}
+
+# }}}
+
+# }}}
+
+1;
+
+=head1 AUTHOR
+
+Jesse Vincent, jesse@bestpractical.com
+
+=head1 SEE ALSO
+
+RT
+
+=cut
+
index dd91126..b6b3491 100755 (executable)
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Tickets.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
 
-=head1 NAME
+use strict;
 
-  RT::Tickets - A collection of Ticket objects
 
+=head1 NAME
 
+  RT::Tickets -- Class Description
 =head1 SYNOPSIS
 
-  use RT::Tickets;
-  my $tickets = new RT::Tickets($CurrentUser);
+  use RT::Tickets
 
 =head1 DESCRIPTION
 
-   A collection of RT::Tickets.
 
 =head1 METHODS
 
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::Tickets);
-
-=end testing
-
 =cut
 
 package RT::Tickets;
-use RT::EasySearch;
-use RT::Ticket;
-@ISA= qw(RT::EasySearch);
-
-use vars qw(%TYPES @SORTFIELDS);
-
-# {{{ TYPES
-
-%TYPES =    ( Status => 'ENUM',
-             Queue  => 'ENUM',
-             Type => 'ENUM',
-             Creator => 'ENUM',
-             LastUpdatedBy => 'ENUM',
-             Owner => 'ENUM',
-             EffectiveId => 'INT',
-             id => 'INT',
-             InitialPriority => 'INT',
-             FinalPriority => 'INT',
-             Priority => 'INT',
-             TimeLeft => 'INT',
-             TimeWorked => 'INT',
-             MemberOf => 'LINK',
-             DependsOn => 'LINK',
-             HasMember => 'LINK',
-             HasDepender => 'LINK',
-             RelatedTo => 'LINK',
-              Told => 'DATE',
-              StartsBy => 'DATE',
-              Started => 'DATE',
-              Due  => 'DATE',
-              Resolved => 'DATE',
-              LastUpdated => 'DATE',
-              Created => 'DATE',
-              Subject => 'STRING',
-             Type => 'STRING',
-              Content => 'TRANSFIELD',
-             ContentType => 'TRANSFIELD',
-             TransactionDate => 'TRANSDATE',
-             Watcher => 'WATCHERFIELD',
-             LinkedTo => 'LINKFIELD',
-              Keyword => 'KEYWORDFIELD'
-
-           );
-
-
-# }}}
-
-# {{{ sub SortFields
-
-@SORTFIELDS = qw(id Status Owner Created Due Starts Started
-                Queue Subject Told Started 
-                   Resolved LastUpdated Priority TimeWorked TimeLeft);
-
-=head2 SortFields
-
-Returns the list of fields that lists of tickets can easily be sorted by
-
-=cut
-
-
-sub SortFields {
-       my $self = shift;
-       return(@SORTFIELDS);
-}
-
-
-# }}}
-
-# {{{ Limit the result set based on content
-
-# {{{ sub Limit 
-
-=head2 Limit
-
-Takes a paramhash with the fields FIELD, OPERATOR, VALUE and DESCRIPTION
-Generally best called from LimitFoo methods
-
-=cut
-sub Limit {
-    my $self = shift;
-    my %args = ( FIELD => undef,
-                OPERATOR => '=',
-                VALUE => undef,
-                DESCRIPTION => undef,
-                @_
-              );
-   $args{'DESCRIPTION'} = "Autodescribed: ".$args{'FIELD'} . $args{'OPERATOR'} . $args{'VALUE'},
-    if (!defined $args{'DESCRIPTION'}) ;
-
-    my $index = $self->_NextIndex;
-    
-    #make the TicketRestrictions hash the equivalent of whatever we just passed in;
-    
-    %{$self->{'TicketRestrictions'}{$index}} = %args;
-
-    $self->{'RecalcTicketLimits'} = 1;
-
-    # If we're looking at the effective id, we don't want to append the other clause
-    # which limits us to tickets where id = effective id 
-    if ($args{'FIELD'} eq 'EffectiveId') {
-        $self->{'looking_at_effective_id'} = 1;
-    }
-
-    return ($index);
-}
-
-# }}}
-
-
-
-
-=head2 FreezeLimits
-
-Returns a frozen string suitable for handing back to ThawLimits.
-
-=cut
-# {{{ sub FreezeLimits
-
-sub FreezeLimits {
-       my $self = shift;
-       require FreezeThaw;
-       return (FreezeThaw::freeze($self->{'TicketRestrictions'},
-                                  $self->{'restriction_index'}
-                                 ));
-}
-
-# }}}
-
-=head2 ThawLimits
-
-Take a frozen Limits string generated by FreezeLimits and make this tickets
-object have that set of limits.
-
-=cut
-# {{{ sub ThawLimits
-
-sub ThawLimits {
-       my $self = shift;
-       my $in = shift;
-       
-       #if we don't have $in, get outta here.
-       return undef unless ($in);
-
-       $self->{'RecalcTicketLimits'} = 1;
-
-       require FreezeThaw;
-       
-       #We don't need to die if the thaw fails.
-       
-       eval {
-               ($self->{'TicketRestrictions'},
-               $self->{'restriction_index'}
-               ) = FreezeThaw::thaw($in);
-       }
-
-}
-
-# }}}
-
-# {{{ Limit by enum or foreign key
-
-# {{{ sub LimitQueue
-
-=head2 LimitQueue
-
-LimitQueue takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of = or !=. (It defaults to =).
-VALUE is a queue id. 
-
-=cut
-
-sub LimitQueue {
-    my $self = shift;
-    my %args = (VALUE => undef,
-               OPERATOR => '=',
-               @_);
-
-    #TODO  VALUE should also take queue names and queue objects
-    my $queue = new RT::Queue($self->CurrentUser);
-    $queue->Load($args{'VALUE'});
-    
-    #TODO check for a valid queue here
-
-    $self->Limit (FIELD => 'Queue',
-                 VALUE => $queue->id(),
-                 OPERATOR => $args{'OPERATOR'},
-                 DESCRIPTION => 'Queue ' .  $args{'OPERATOR'}. " ". $queue->Name
-                );
-    
-}
-# }}}
-
-# {{{ sub LimitStatus
-
-=head2 LimitStatus
-
-Takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of = or !=.
-VALUE is a status.
-
-=cut
-
-sub LimitStatus {
-    my $self = shift;
-    my %args = ( OPERATOR => '=',
-                  @_);
-    $self->Limit (FIELD => 'Status',
-                 VALUE => $args{'VALUE'},
-                 OPERATOR => $args{'OPERATOR'},
-                 DESCRIPTION => 'Status ' .  $args{'OPERATOR'}. " ". $args{'VALUE'},
-                );
-}
-
-# }}}
-
-# {{{ sub LimitType
-
-=head2 LimitType
-
-Takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of = or !=, it defaults to "=".
-VALUE is a string to search for in the type of the ticket.
-
-=cut
-
-sub LimitType {
-    my $self = shift;
-    my %args = (OPERATOR => '=',
-               VALUE => undef,
-               @_);
-    $self->Limit (FIELD => 'Type',
-                  VALUE => $args{'VALUE'},
-                  OPERATOR => $args{'OPERATOR'},
-                  DESCRIPTION => 'Type ' .  $args{'OPERATOR'}. " ". $args{'Limit'},
-                 );
-}
-
-# }}}
-
-# }}}
-
-# {{{ Limit by string field
-
-# {{{ sub LimitSubject
-
-=head2 LimitSubject
-
-Takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of = or !=.
-VALUE is a string to search for in the subject of the ticket.
-
-=cut
-
-sub LimitSubject {
-    my $self = shift;
-    my %args = (@_);
-    $self->Limit (FIELD => 'Subject',
-                 VALUE => $args{'VALUE'},
-                 OPERATOR => $args{'OPERATOR'},
-                 DESCRIPTION => 'Subject ' .  $args{'OPERATOR'}. " ". $args{'VALUE'},
-                );
-}
-
-# }}}
-
-# }}}
-
-# {{{ Limit based on ticket numerical attributes
-# Things that can be > < = !=
-
-# {{{ sub LimitId
-
-=head2 LimitId
-
-Takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of =, >, < or !=.
-VALUE is a ticket Id to search for
-
-=cut
-
-sub LimitId {
-    my $self = shift;
-    my %args = (OPERATOR => '=',
-                @_);
-    
-    $self->Limit (FIELD => 'id',
-                  VALUE => $args{'VALUE'},
-                  OPERATOR => $args{'OPERATOR'},
-                  DESCRIPTION => 'Id ' .  $args{'OPERATOR'}. " ". $args{'VALUE'},
-                 );
-}
-
-# }}}
-
-# {{{ sub LimitPriority
-
-=head2 LimitPriority
-
-Takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of =, >, < or !=.
-VALUE is a value to match the ticket\'s priority against
-
-=cut
-
-sub LimitPriority {
-    my $self = shift;
-    my %args = (@_);
-    $self->Limit (FIELD => 'Priority',
-                 VALUE => $args{'VALUE'},
-                 OPERATOR => $args{'OPERATOR'},
-                 DESCRIPTION => 'Priority ' .  $args{'OPERATOR'}. " ". $args{'VALUE'},
-                );
-}
-
-# }}}
-
-# {{{ sub LimitInitialPriority
-
-=head2 LimitInitialPriority
-
-Takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of =, >, < or !=.
-VALUE is a value to match the ticket\'s initial priority against
-
-
-=cut
-
-sub LimitInitialPriority {
-    my $self = shift;
-    my %args = (@_);
-    $self->Limit (FIELD => 'InitialPriority',
-                 VALUE => $args{'VALUE'},
-                 OPERATOR => $args{'OPERATOR'},
-                 DESCRIPTION => 'Initial Priority ' .  $args{'OPERATOR'}. " ". $args{'VALUE'},
-                );
-}
-
-# }}}
 
-# {{{ sub LimitFinalPriority
-
-=head2 LimitFinalPriority
-
-Takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of =, >, < or !=.
-VALUE is a value to match the ticket\'s final priority against
-
-=cut
-
-sub LimitFinalPriority {
-    my $self = shift;
-    my %args = (@_);
-    $self->Limit (FIELD => 'FinalPriority',
-                 VALUE => $args{'VALUE'},
-                 OPERATOR => $args{'OPERATOR'},
-                 DESCRIPTION => 'Final Priority ' .  $args{'OPERATOR'}. " ". $args{'VALUE'},
-                );
-}
-
-# }}}
-
-# {{{ sub LimitTimeWorked
-
-=head2 LimitTimeWorked
-
-Takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of =, >, < or !=.
-VALUE is a value to match the ticket's TimeWorked attribute
-
-=cut
-
-sub LimitTimeWorked {
-    my $self = shift;
-    my %args = (@_);
-    $self->Limit (FIELD => 'TimeWorked',
-                 VALUE => $args{'VALUE'},
-                 OPERATOR => $args{'OPERATOR'},
-                 DESCRIPTION => 'Time worked ' .  $args{'OPERATOR'}. " ". $args{'VALUE'},
-                );
-}
-
-# }}}
-
-# {{{ sub LimitTimeLeft
-
-=head2 LimitTimeLeft
-
-Takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of =, >, < or !=.
-VALUE is a value to match the ticket's TimeLeft attribute
-
-=cut
-
-sub LimitTimeLeft {
-    my $self = shift;
-    my %args = (@_);
-    $self->Limit (FIELD => 'TimeLeft',
-                 VALUE => $args{'VALUE'},
-                 OPERATOR => $args{'OPERATOR'},
-                 DESCRIPTION => 'Time left ' .  $args{'OPERATOR'}. " ". $args{'VALUE'},
-                );
-}
-
-# }}}
-
-# }}}
-
-# {{{ Limiting based on attachment attributes
-
-# {{{ sub LimitContent
-
-=head2 LimitContent
-
-Takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of =, LIKE, NOT LIKE or !=.
-VALUE is a string to search for in the body of the ticket
-
-=cut
-sub LimitContent {
-    my $self = shift;
-    my %args = (@_);
-    $self->Limit (FIELD => 'Content',
-                 VALUE => $args{'VALUE'},
-                 OPERATOR => $args{'OPERATOR'},
-                 DESCRIPTION => 'Ticket content ' .  $args{'OPERATOR'}. " ". $args{'VALUE'},
-                );
-}
-
-# }}}
-# {{{ sub LimitContentType
-
-=head2 LimitContentType
-
-Takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of =, LIKE, NOT LIKE or !=.
-VALUE is a content type to search ticket attachments for
-
-=cut
-  
-sub LimitContentType {
-    my $self = shift;
-    my %args = (@_);
-    $self->Limit (FIELD => 'ContentType',
-                 VALUE => $args{'VALUE'},
-                 OPERATOR => $args{'OPERATOR'},
-                 DESCRIPTION => 'Ticket content type ' .  $args{'OPERATOR'}. " ". $args{'VALUE'},
-                );
-}
-# }}}
-
-# }}}
-
-# {{{ Limiting based on people
-
-# {{{ sub LimitOwner
-
-=head2 LimitOwner
-
-Takes a paramhash with the fields OPERATOR and VALUE.
-OPERATOR is one of = or !=.
-VALUE is a user id.
-
-=cut
-
-sub LimitOwner {
-    my $self = shift;
-    my %args = ( OPERATOR => '=',
-                 @_);
-    
-    my $owner = new RT::User($self->CurrentUser);
-    $owner->Load($args{'VALUE'});
-    $self->Limit (FIELD => 'Owner',
-                 VALUE => $owner->Id,
-                 OPERATOR => $args{'OPERATOR'},
-                 DESCRIPTION => 'Owner ' .  $args{'OPERATOR'}. " ". $owner->Name()
-                );
-    
-}
-
-# }}}
-
-# {{{ Limiting watchers
-
-# {{{ sub LimitWatcher
+use RT::SearchBuilder;
+use RT::Ticket;
 
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
 
-=head2 LimitWatcher
-  
-  Takes a paramhash with the fields OPERATOR, TYPE and VALUE.
-  OPERATOR is one of =, LIKE, NOT LIKE or !=.
-  VALUE is a value to match the ticket\'s watcher email addresses against
-  TYPE is the sort of watchers you want to match against. Leave it undef if you want to search all of them
 
-=cut
-   
-sub LimitWatcher {
+sub _Init {
     my $self = shift;
-    my %args = ( OPERATOR => '=',
-                VALUE => undef,
-                TYPE => undef,
-               @_);
-
-
-    #build us up a description
-    my ($watcher_type, $desc);
-    if ($args{'TYPE'}) {
-       $watcher_type = $args{'TYPE'};
-    }
-    else {
-       $watcher_type = "Watcher";
-    }
-    $desc = "$watcher_type ".$args{'OPERATOR'}." ".$args{'VALUE'};
-
-
-    $self->Limit (FIELD => 'Watcher',
-                 VALUE => $args{'VALUE'},
-                 OPERATOR => $args{'OPERATOR'},
-                 TYPE => $args{'TYPE'},
-                 DESCRIPTION => "$desc"
-                );
-}
-
-# }}}
-
-# {{{ sub LimitRequestor
+    $self->{'table'} = 'Tickets';
+    $self->{'primary_key'} = 'id';
 
-=head2 LimitRequestor
 
-It\'s like LimitWatcher, but it presets TYPE to Requestor
-
-=cut
-
-
-sub LimitRequestor {
-    my $self = shift;
-    $self->LimitWatcher(TYPE=> 'Requestor', @_);
+    return ( $self->SUPER::_Init(@_) );
 }
 
-# }}}
-
-# {{{ sub LimitCc
 
-=head2 LimitCC
+=item NewItem
 
-It\'s like LimitWatcher, but it presets TYPE to Cc
+Returns an empty new RT::Ticket item
 
 =cut
 
-sub LimitCc {
-    my $self = shift;
-    $self->LimitWatcher(TYPE=> 'Cc', @_);
-}
-
-# }}}
-
-# {{{ sub LimitAdminCc
-
-=head2 LimitAdminCc
-
-It\'s like LimitWatcher, but it presets TYPE to AdminCc
-
-=cut
-  
-sub LimitAdminCc {
+sub NewItem {
     my $self = shift;
-    $self->LimitWatcher(TYPE=> 'AdminCc', @_);
+    return(RT::Ticket->new($self->CurrentUser));
 }
 
-# }}}
-
-# }}}
-
-# }}}
+        eval "require RT::Tickets_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Tickets_Overlay.pm}) {
+            die $@;
+        };
 
-# {{{ Limiting based on links
+        eval "require RT::Tickets_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Tickets_Vendor.pm}) {
+            die $@;
+        };
 
-# {{{ LimitLinkedTo
+        eval "require RT::Tickets_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Tickets_Local.pm}) {
+            die $@;
+        };
 
-=head2 LimitLinkedTo
 
-LimitLinkedTo takes a paramhash with two fields: TYPE and TARGET
-TYPE limits the sort of relationship we want to search on
 
-TARGET is the id or URI of the TARGET of the link
-(TARGET used to be 'TICKET'.  'TICKET' is deprecated, but will be treated as TARGET
 
-=cut
-
-sub LimitLinkedTo {
-    my $self = shift;
-    my %args = ( 
-               TICKET => undef,
-               TARGET => undef,
-               TYPE => undef,
-                @_);
-
-
-    $self->Limit( FIELD => 'LinkedTo',
-                 BASE => undef,
-                 TARGET => ($args{'TARGET'} || $args{'TICKET'}),
-                 TYPE => $args{'TYPE'},
-                 DESCRIPTION => "Tickets ".$args{'TYPE'}." by ".($args{'TARGET'} || $args{'TICKET'})
-               );
-}
-
-
-# }}}
+=head1 SEE ALSO
 
-# {{{ LimitLinkedFrom
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
 
-=head2 LimitLinkedFrom
+These overlay files can contain new subs or subs to replace existing subs in this module.
 
-LimitLinkedFrom takes a paramhash with two fields: TYPE and BASE
-TYPE limits the sort of relationship we want to search on
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
 
+   no warnings qw(redefine);
 
-BASE is the id or URI of the BASE of the link
-(BASE used to be 'TICKET'.  'TICKET' is deprecated, but will be treated as BASE
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
 
+RT::Tickets_Overlay, RT::Tickets_Vendor, RT::Tickets_Local
 
 =cut
 
-sub LimitLinkedFrom {
-    my $self = shift;
-    my %args = ( BASE => undef,
-                TICKET => undef,
-                TYPE => undef,
-                @_);
-
-    
-    $self->Limit( FIELD => 'LinkedTo',
-                 TARGET => undef,
-                 BASE => ($args{'BASE'} || $args{'TICKET'}),
-                 TYPE => $args{'TYPE'},
-                 DESCRIPTION => "Tickets " .($args{'BASE'} || $args{'TICKET'}) ." ".$args{'TYPE'}
-               );
-}
-
-
-# }}}
-
-# {{{ LimitMemberOf 
-sub LimitMemberOf {
-    my $self = shift;
-    my $ticket_id = shift;
-    $self->LimitLinkedTo ( TARGET=> "$ticket_id",
-                          TYPE => 'MemberOf',
-                         );
-    
-}
-# }}}
-
-# {{{ LimitHasMember
-sub LimitHasMember {
-    my $self = shift;
-    my $ticket_id =shift;
-    $self->LimitLinkedFrom ( BASE => "$ticket_id",
-                            TYPE => 'MemberOf',
-                            );
-    
-}
-# }}}
-
-# {{{ LimitDependsOn
-
-sub LimitDependsOn {
-    my $self = shift;
-    my $ticket_id = shift;
-    $self->LimitLinkedTo ( TARGET => "$ticket_id",
-                           TYPE => 'DependsOn',
-                          );
-    
-}
-
-# }}}
-
-# {{{ LimitDependedOnBy
-
-sub LimitDependedOnBy {
-    my $self = shift;
-    my $ticket_id = shift;
-    $self->LimitLinkedFrom (  BASE => "$ticket_id",
-                               TYPE => 'DependsOn',
-                            );
-    
-}
-
-# }}}
-
-
-# {{{ LimitRefersTo
-
-sub LimitRefersTo {
-    my $self = shift;
-    my $ticket_id = shift;
-    $self->LimitLinkedTo ( TARGET => "$ticket_id",
-                           TYPE => 'RefersTo',
-                          );
-    
-}
-
-# }}}
-
-# {{{ LimitReferredToBy
-
-sub LimitReferredToBy {
-    my $self = shift;
-    my $ticket_id = shift;
-    $self->LimitLinkedFrom (  BASE=> "$ticket_id",
-                               TYPE => 'RefersTo',
-                            );
-    
-}
-
-# }}}
-
-# }}}
-
-# {{{ limit based on ticket date attribtes
-
-# {{{ sub LimitDate
-
-=head2 LimitDate (FIELD => 'DateField', OPERATOR => $oper, VALUE => $ISODate)
-
-Takes a paramhash with the fields FIELD OPERATOR and VALUE.
-
-OPERATOR is one of > or < 
-VALUE is a date and time in ISO format in GMT
-FIELD is one of Starts, Started, Told, Created, Resolved, LastUpdated
-
-There are also helper functions of the form LimitFIELD that eliminate
-the need to pass in a FIELD argument.
-
-=cut
-
-sub LimitDate {
-    my $self = shift;
-    my %args = (
-                  FIELD => undef,
-                 VALUE => $args{'VALUE'},
-                 OPERATOR => $args{'OPERATOR'},
-
-                  @_);
-
-    #Set the description if we didn't get handed it above
-    unless ($args{'DESCRIPTION'} ) {
-       $args{'DESCRIPTION'} = $args{'FIELD'} . " " .$args{'OPERATOR'}. " ". $args{'VALUE'} . " GMT"
-    }
-
-    $self->Limit (%args);
-
-}
-
-# }}}
-
-
-
-
-sub LimitCreated {
-    my $self = shift;
-    $self->LimitDate( FIELD => 'Created', @_);
-}
-sub LimitDue {
-    my $self = shift;
-    $self->LimitDate( FIELD => 'Due', @_);
-
-}
-sub LimitStarts {
-    my $self = shift;
-    $self->LimitDate( FIELD => 'Starts', @_);
-
-}
-sub LimitStarted {
-    my $self = shift;
-    $self->LimitDate( FIELD => 'Started', @_);
-}
-sub LimitResolved { 
-    my $self = shift;
-    $self->LimitDate( FIELD => 'Resolved', @_);
-}
-sub LimitTold {
-    my $self = shift;
-    $self->LimitDate( FIELD => 'Told', @_);
-}
-sub LimitLastUpdated {
-    my $self = shift;
-    $self->LimitDate( FIELD => 'LastUpdated', @_);
-}
-#
-# {{{ sub LimitTransactionDate
-
-=head2 LimitTransactionDate (OPERATOR => $oper, VALUE => $ISODate)
-
-Takes a paramhash with the fields FIELD OPERATOR and VALUE.
-
-OPERATOR is one of > or < 
-VALUE is a date and time in ISO format in GMT
-
-
-=cut
-
-sub LimitTransactionDate {
-    my $self = shift;
-    my %args = (
-                  FIELD => 'TransactionDate',
-                 VALUE => $args{'VALUE'},
-                 OPERATOR => $args{'OPERATOR'},
-
-                  @_);
-
-    #Set the description if we didn't get handed it above
-    unless ($args{'DESCRIPTION'} ) {
-       $args{'DESCRIPTION'} = $args{'FIELD'} . " " .$args{'OPERATOR'}. " ". $args{'VALUE'} . " GMT"
-    }
-
-    $self->Limit (%args);
-
-}
-
-# }}}
-
-# }}}
-
-# {{{ sub LimitKeyword
-
-=head2 LimitKeyword 
-
-Takes a paramhash of key/value pairs with the following keys:
-
-=over 4
-
-=item KEYWORDSELECT - KeywordSelect id
-
-=item OPERATOR - (for KEYWORD only - KEYWORDSELECT operator is always `=')
-
-=item KEYWORD - Keyword id
-
-=back
-
-=cut
-
-sub LimitKeyword {
-    my $self = shift;
-    my %args = ( KEYWORD => undef,
-                 KEYWORDSELECT => undef,
-                OPERATOR => '=',
-                DESCRIPTION => undef,
-                FIELD => 'Keyword',
-                QUOTEVALUE => 1,
-                @_
-              );
-
-    use RT::KeywordSelect;
-    my $KeywordSelect = RT::KeywordSelect->new($self->CurrentUser);
-    $KeywordSelect->Load($args{KEYWORDSELECT});
-    
-
-    # Below, We're checking to see whether the keyword we're searching for
-    # is null or not.
-    # This could probably be rewritten to be easier to read and  understand
-
-    
-    #If we are looking to compare with a null value.
-    if ($args{'OPERATOR'} =~ /is/i)  {
-       if ($args{'OPERATOR'} =~ /^is$/i) {
-           $args{'DESCRIPTION'} ||= "Keyword Selection ". $KeywordSelect->Name . " has no value";
-       }
-       elsif ($args{'OPERATOR'} =~ /^is not$/i) {
-           $args{'DESCRIPTION'} ||= "Keyword Selection ". $KeywordSelect->Name . " has a value";
-       }
-    }
-       # if we're not looking to compare with a null value
-    else {     
-        use RT::Keyword;
-       my $Keyword = RT::Keyword->new($self->CurrentUser);
-       $Keyword->Load($args{KEYWORD});
-       $args{'DESCRIPTION'} ||= "Keyword Selection " . $KeywordSelect->Name.  " $args{OPERATOR} ". $Keyword->Name;
-    }
-    
-    $args{SingleValued} = $KeywordSelect->Single();
-    
-    my $index = $self->_NextIndex;
-    %{$self->{'TicketRestrictions'}{$index}} = %args;
-    
-    $self->{'RecalcTicketLimits'} = 1;
-    return ($index);
-}
-
-# }}}
-
-# {{{ sub _NextIndex
-
-=head2 _NextIndex
-
-Keep track of the counter for the array of restrictions
-
-=cut
-
-sub _NextIndex {
-    my $self = shift;
-    return ($self->{'restriction_index'}++);
-}
-# }}}
-
-# }}} 
-
-# {{{ Core bits to make this a DBIx::SearchBuilder object
-
-# {{{ sub _Init 
-sub _Init  {
-    my $self = shift;
-    $self->{'table'} = "Tickets";
-    $self->{'RecalcTicketLimits'} = 1;
-    $self->{'looking_at_effective_id'} = 0;
-    $self->{'restriction_index'} =1;
-    $self->{'primary_key'} = "id";
-    $self->SUPER::_Init(@_);
-
-}
-# }}}
-
-# {{{ sub NewItem 
-sub NewItem  {
-  my $self = shift;
-  return(RT::Ticket->new($self->CurrentUser));
-
-}
-# }}}
-
-# {{{ sub Count
-sub Count {
-  my $self = shift;
-  $self->_ProcessRestrictions if ($self->{'RecalcTicketLimits'} == 1 );
-  return($self->SUPER::Count());
-}
-# }}}
-
-# {{{ sub ItemsArrayRef
-
-=head2 ItemsArrayRef
-
-Returns a reference to the set of all items found in this search
-
-=cut
-
-sub ItemsArrayRef {
-    my $self = shift;
-    my @items;
-    
-    my $placeholder = $self->_ItemsCounter;
-    $self->GotoFirstItem();
-    while (my $item = $self->Next) { 
-       push (@items, $item);
-    }
-    
-    $self->GotoItem($placeholder);
-    return(\@items);
-}
-# }}}
-
-# {{{ sub Next 
-sub Next {
-       my $self = shift;
-       
-       $self->_ProcessRestrictions if ($self->{'RecalcTicketLimits'} == 1 );
-
-       my $Ticket = $self->SUPER::Next();
-       if ((defined($Ticket)) and (ref($Ticket))) {
-
-           #Make sure we _never_ show dead tickets
-           #TODO we should be doing this in the where clause.
-           #but you can't do multiple clauses on the same field just yet :/
-
-           if ($Ticket->Status eq 'dead') {
-               return($self->Next());
-           }
-           elsif ($Ticket->CurrentUserHasRight('ShowTicket')) {
-               return($Ticket);
-           }
-
-           #If the user doesn't have the right to show this ticket
-           else {      
-               return($self->Next());
-           }
-       }
-       #if there never was any ticket
-       else {
-               return(undef);
-       }       
-
-}
-# }}}
-
-# }}}
-
-# {{{ Deal with storing and restoring restrictions
-
-# {{{ sub LoadRestrictions
-
-=head2 LoadRestrictions
-
-LoadRestrictions takes a string which can fully populate the TicketRestrictons hash.
-TODO It is not yet implemented
-
-=cut
-
-# }}}
-
-# {{{ sub DescribeRestrictions
-
-=head2 DescribeRestrictions
-
-takes nothing.
-Returns a hash keyed by restriction id. 
-Each element of the hash is currently a one element hash that contains DESCRIPTION which
-is a description of the purpose of that TicketRestriction
-
-=cut
-
-sub DescribeRestrictions  {
-    my $self = shift;
-    
-    my ($row, %listing);
-    
-    foreach $row (keys %{$self->{'TicketRestrictions'}}) {
-       $listing{$row} = $self->{'TicketRestrictions'}{$row}{'DESCRIPTION'};
-    }
-    return (%listing);
-}
-# }}}
-
-# {{{ sub RestrictionValues
-
-=head2 RestrictionValues FIELD
-
-Takes a restriction field and returns a list of values this field is restricted
-to.
-
-=cut
-
-sub RestrictionValues {
-    my $self = shift;
-    my $field = shift;
-    map $self->{'TicketRestrictions'}{$_}{'VALUE'},
-      grep {
-             $self->{'TicketRestrictions'}{$_}{'FIELD'} eq $field
-             && $self->{'TicketRestrictions'}{$_}{'OPERATOR'} eq "="
-           }
-        keys %{$self->{'TicketRestrictions'}};
-}
-
-# }}}
-
-# {{{ sub ClearRestrictions
-
-=head2 ClearRestrictions
-
-Removes all restrictions irretrievably
-
-=cut
-  
-sub ClearRestrictions {
-    my $self = shift;
-    delete $self->{'TicketRestrictions'};
-    $self->{'looking_at_effective_id'} = 0;
-    $self->{'RecalcTicketLimits'} =1;
-}
-
-# }}}
-
-# {{{ sub DeleteRestriction
-
-=head2 DeleteRestriction
-
-Takes the row Id of a restriction (From DescribeRestrictions' output, for example.
-Removes that restriction from the session's limits.
-
-=cut
-
-
-sub DeleteRestriction {
-    my $self = shift;
-    my $row = shift;
-    delete $self->{'TicketRestrictions'}{$row};
-    
-    $self->{'RecalcTicketLimits'} = 1;
-    #make the underlying easysearch object forget all its preconceptions
-}
-
-# }}}
-
-# {{{ sub _ProcessRestrictions 
-
-sub _ProcessRestrictions {
-    my $self = shift;
-
-    #Need to clean the EasySearch slate because it makes things too sticky
-    $self->CleanSlate();
-
-    #Blow away ticket aliases since we'll need to regenerate them for a new search
-    delete $self->{'TicketAliases'};
-    delete $self->{KeywordsAliases};
-
-    my $row;
-    
-    foreach $row (keys %{$self->{'TicketRestrictions'}}) {
-        my $restriction = $self->{'TicketRestrictions'}{$row};
-       # {{{ if it's an int
-       
-       if ($TYPES{$restriction->{'FIELD'}} eq 'INT' ) {
-           if ($restriction->{'OPERATOR'} =~ /^(=|!=|>|<|>=|<=)$/) {
-               $self->SUPER::Limit( FIELD => $restriction->{'FIELD'},
-                             ENTRYAGGREGATOR => 'AND',
-                             OPERATOR => $restriction->{'OPERATOR'},
-                             VALUE => $restriction->{'VALUE'},
-                             );
-           }
-       }
-       # }}}
-       # {{{ if it's an enum
-       elsif ($TYPES{$restriction->{'FIELD'}} eq 'ENUM') {
-           
-           if ($restriction->{'OPERATOR'} eq '=') {
-               $self->SUPER::Limit( FIELD => $restriction->{'FIELD'},
-                             ENTRYAGGREGATOR => 'OR',
-                             OPERATOR => '=',
-                             VALUE => $restriction->{'VALUE'},
-                           );
-           }
-           elsif ($restriction->{'OPERATOR'} eq '!=') {
-               $self->SUPER::Limit( FIELD => $restriction->{'FIELD'},
-                             ENTRYAGGREGATOR => 'AND',
-                             OPERATOR => '!=',
-                             VALUE => $restriction->{'VALUE'},
-                           );
-           }
-           
-       }
-       # }}}
-       # {{{ if it's a date
-
-       elsif ($TYPES{$restriction->{'FIELD'}} eq 'DATE') {
-           $self->SUPER::Limit( FIELD => $restriction->{'FIELD'},
-                                ENTRYAGGREGATOR => 'AND',
-                                OPERATOR => $restriction->{'OPERATOR'},
-                                VALUE => $restriction->{'VALUE'},
-                              );
-       }
-       # }}}
-       # {{{ if it's a string
-
-       elsif ($TYPES{$restriction->{'FIELD'}} eq 'STRING') {
-           
-           if ($restriction->{'OPERATOR'} eq '=') {
-               $self->SUPER::Limit( FIELD => $restriction->{'FIELD'},
-                             ENTRYAGGREGATOR => 'OR',
-                             OPERATOR => '=',
-                             VALUE => $restriction->{'VALUE'},
-                             CASESENSITIVE => 0
-                           );
-           }
-           elsif ($restriction->{'OPERATOR'} eq '!=') {
-               $self->SUPER::Limit( FIELD => $restriction->{'FIELD'},
-                             ENTRYAGGREGATOR => 'AND',
-                             OPERATOR => '!=',
-                             VALUE => $restriction->{'VALUE'},
-                             CASESENSITIVE => 0
-                           );
-           }
-           elsif ($restriction->{'OPERATOR'} eq 'LIKE') {
-               $self->SUPER::Limit( FIELD => $restriction->{'FIELD'},
-                             ENTRYAGGREGATOR => 'AND',
-                             OPERATOR => 'LIKE',
-                             VALUE => $restriction->{'VALUE'},
-                             CASESENSITIVE => 0
-                           );
-           }
-           elsif ($restriction->{'OPERATOR'} eq 'NOT LIKE') {
-               $self->SUPER::Limit( FIELD => $restriction->{'FIELD'},
-                             ENTRYAGGREGATOR => 'AND',
-                             OPERATOR => 'NOT LIKE',
-                             VALUE => $restriction->{'VALUE'},
-                             CASESENSITIVE => 0
-                           );
-           }
-       }
-
-       # }}}
-       # {{{ if it's Transaction content that we're hunting for
-       elsif ($TYPES{$restriction->{'FIELD'}} eq 'TRANSFIELD') {
-
-           #Basically, we want to make sure that the limits apply to the same attachment,
-           #rather than just another attachment for the same ticket, no matter how many 
-           #clauses we lump on. 
-           #We put them in TicketAliases so that they get nuked when we redo the join.
-           
-           unless (defined $self->{'TicketAliases'}{'TransFieldAlias'}) {
-               $self->{'TicketAliases'}{'TransFieldAlias'} = $self->NewAlias ('Transactions');
-           }
-           unless (defined $self->{'TicketAliases'}{'TransFieldAttachAlias'}){
-               $self->{'TicketAliases'}{'TransFieldAttachAlias'} = $self->NewAlias('Attachments');
-               
-           }
-           #Join transactions to attachments
-           $self->Join( ALIAS1 => $self->{'TicketAliases'}{'TransFieldAttachAlias'},  
-                        FIELD1 => 'TransactionId',
-                        ALIAS2 => $self->{'TicketAliases'}{'TransFieldAlias'}, FIELD2=> 'id');
-           
-           #Join transactions to tickets
-           $self->Join( ALIAS1 => 'main', FIELD1 => $self->{'primary_key'},
-                        ALIAS2 =>$self->{'TicketAliases'}{'TransFieldAlias'}, FIELD2 => 'Ticket');
-           
-           #Search for the right field
-           $self->SUPER::Limit(ALIAS => $self->{'TicketAliases'}{'TransFieldAttachAlias'},
-                                 ENTRYAGGREGATOR => 'AND',
-                                 FIELD =>    $restriction->{'FIELD'},
-                                 OPERATOR => $restriction->{'OPERATOR'} ,
-                                 VALUE =>    $restriction->{'VALUE'},
-                                 CASESENSITIVE => 0
-                               );
-           
-
-       }
-
-       # }}}
-       # {{{ if it's a Transaction date that we're hunting for
-       elsif ($TYPES{$restriction->{'FIELD'}} eq 'TRANSDATE') {
-
-           #Basically, we want to make sure that the limits apply to the same attachment,
-           #rather than just another attachment for the same ticket, no matter how many 
-           #clauses we lump on. 
-           #We put them in TicketAliases so that they get nuked when we redo the join.
-           
-           unless (defined $self->{'TicketAliases'}{'TransFieldAlias'}) {
-               $self->{'TicketAliases'}{'TransFieldAlias'} = $self->NewAlias ('Transactions');
-           }
-
-           #Join transactions to tickets
-           $self->Join( ALIAS1 => 'main', FIELD1 => $self->{'primary_key'},
-                        ALIAS2 =>$self->{'TicketAliases'}{'TransFieldAlias'}, FIELD2 => 'Ticket');
-           
-           #Search for the right field
-           $self->SUPER::Limit(ALIAS => $self->{'TicketAliases'}{'TransFieldAlias'},
-                               ENTRYAGGREGATOR => 'AND',
-                               FIELD =>    'Created',
-                               OPERATOR => $restriction->{'OPERATOR'} ,
-                               VALUE =>    $restriction->{'VALUE'} );
-       }
-
-       # }}}
-       # {{{ if it's a relationship that we're hunting for
-       
-       # Takes FIELD: which is something like "LinkedTo"
-       # takes TARGET or BASE which is the TARGET or BASE id that we're searching for
-       # takes TYPE which is the type of link we're looking for.
-
-       elsif ($TYPES{$restriction->{'FIELD'}} eq 'LINKFIELD') {
-
-           
-           my $LinkAlias = $self->NewAlias ('Links');
-
-           
-           #Make sure we get the right type of link, if we're restricting it
-           if ($restriction->{'TYPE'}) {
-               $self->SUPER::Limit(ALIAS => $LinkAlias,
-                                   ENTRYAGGREGATOR => 'AND',
-                                   FIELD =>   'Type',
-                                   OPERATOR => '=',
-                                   VALUE =>    $restriction->{'TYPE'} );
-           }
-           
-           #If we're trying to limit it to things that are target of
-           if ($restriction->{'TARGET'}) {
-               
-
-               # If the TARGET is an integer that means that we want to look at the LocalTarget
-               # field. otherwise, we want to look at the "Target" field
-
-               my ($matchfield);
-               if ($restriction->{'TARGET'} =~/^(\d+)$/) {
-                   $matchfield = "LocalTarget";
-               }       
-               else {
-                   $matchfield = "Target";
-               }       
-
-               $self->SUPER::Limit(ALIAS => $LinkAlias,
-                                   ENTRYAGGREGATOR => 'AND',
-                                   FIELD =>   $matchfield,
-                                   OPERATOR => '=',
-                                   VALUE =>    $restriction->{'TARGET'} );
-
-               
-               #If we're searching on target, join the base to ticket.id
-               $self->Join( ALIAS1 => 'main', FIELD1 => $self->{'primary_key'},
-                            ALIAS2 => $LinkAlias,
-                            FIELD2 => 'LocalBase');
-
-           
-
-
-           }
-           #If we're trying to limit it to things that are base of
-           elsif ($restriction->{'BASE'}) {
-
-
-               # If we're trying to match a numeric link, we want to look at LocalBase,
-               # otherwise we want to look at "Base"
-
-               my ($matchfield);
-               if ($restriction->{'BASE'} =~/^(\d+)$/) {
-                   $matchfield = "LocalBase";
-               }       
-               else {
-                   $matchfield = "Base";
-               }       
-
-
-               $self->SUPER::Limit(ALIAS => $LinkAlias,
-                                   ENTRYAGGREGATOR => 'AND',
-                                   FIELD => $matchfield,
-                                   OPERATOR => '=',
-                                   VALUE =>    $restriction->{'BASE'} );
-               
-               #If we're searching on base, join the target to ticket.id
-               $self->Join( ALIAS1 => 'main', FIELD1 => $self->{'primary_key'},
-                            ALIAS2 => $LinkAlias,
-                            FIELD2 => 'LocalTarget');
-               
-           }
-
-       }
-               
-       # }}}
-       # {{{ if it's a watcher that we're hunting for
-       elsif ($TYPES{$restriction->{'FIELD'}} eq 'WATCHERFIELD') {
-
-           my $Watch = $self->NewAlias('Watchers');
-
-           #Join watchers to users
-           my $User = $self->Join( TYPE => 'left',
-                                    ALIAS1 => $Watch, 
-                                    FIELD1 => 'Owner',
-                                    TABLE2 => 'Users', 
-                                    FIELD2 => 'id',
-                                  );
-
-           #Join Ticket to watchers
-           $self->Join( ALIAS1 => 'main', FIELD1 => 'id',
-                        ALIAS2 => $Watch, FIELD2 => 'Value');
-
-
-           #Make sure we're only talking about ticket watchers
-           $self->SUPER::Limit( ALIAS => $Watch,
-                                FIELD => 'Scope',
-                                VALUE => 'Ticket',
-                                OPERATOR => '=');
-
-
-           # Find email address watchers
-           $self->SUPER::Limit( SUBCLAUSE => 'WatcherEmailAddress',
-                                ALIAS => $Watch,
-                                FIELD => 'Email',
-                                ENTRYAGGREGATOR => 'OR',
-                                VALUE => $restriction->{'VALUE'},
-                                OPERATOR => $restriction->{'OPERATOR'},
-                                CASESENSITIVE => 0
-                       );
-
-
-
-           #Find user watchers
-           $self->SUPER::Limit(
-                               SUBCLAUSE => 'WatcherEmailAddress',
-                               ALIAS => $User,
-                               FIELD => 'EmailAddress',
-                               ENTRYAGGREGATOR => 'OR',
-                               VALUE => $restriction->{'VALUE'},
-                               OPERATOR => $restriction->{'OPERATOR'},
-                               CASESENSITIVE => 0
-                              );
-
-           
-           #If we only want a specific type of watchers, then limit it to that
-           if ($restriction->{'TYPE'}) {
-               $self->SUPER::Limit( ALIAS => $Watch,
-                                    FIELD => 'Type',
-                                    ENTRYAGGREGATOR => 'OR',
-                                    VALUE => $restriction->{'TYPE'},
-                                    OPERATOR => '=');
-           }
-       }
-
-       # }}}
-       # {{{ if it's a keyword
-       elsif ($TYPES{$restriction->{'FIELD'}} eq 'KEYWORDFIELD') {
-           my $null_columns_ok;
-
-            my $ObjKeywordsAlias;
-           $ObjKeywordsAlias = $self->{KeywordsAliases}{$restriction->{'KEYWORDSELECT'}}
-             if $restriction->{SingleValued};
-           unless (defined $ObjKeywordsAlias) {
-             $ObjKeywordsAlias = $self->Join(
-                                              TYPE => 'left',
-                                              ALIAS1 => 'main',
-                                              FIELD1 => 'id',
-                                              TABLE2 => 'ObjectKeywords',
-                                              FIELD2 => 'ObjectId'
-                                             );
-             if ($restriction->{'SingleValued'}) {
-               $self->{KeywordsAliases}{$restriction->{'KEYWORDSELECT'}} 
-                 = $ObjKeywordsAlias;
-             }
-           }
-
-         
-            $self->SUPER::Limit(
-                               ALIAS => $ObjKeywordsAlias,
-                               FIELD => 'Keyword',
-                               OPERATOR => $restriction->{'OPERATOR'},
-                               VALUE => $restriction->{'KEYWORD'},
-                               QUOTEVALUE => $restriction->{'QUOTEVALUE'},
-                               ENTRYAGGREGATOR => 'OR',
-                               );
-           
-            if  ( ($restriction->{'OPERATOR'} =~ /^IS$/i) or 
-                 ($restriction->{'OPERATOR'} eq '!=') ) {
-               
-               $null_columns_ok=1;
-
-           } 
-
-           #If we're trying to find tickets where the keyword isn't somethng, also check ones where it _IS_ null
-           if ( $restriction->{'OPERATOR'} eq '!=') {
-               $self->SUPER::Limit(
-                                   ALIAS => $ObjKeywordsAlias,
-                                   FIELD => 'Keyword',
-                                   OPERATOR => 'IS',
-                                   VALUE => 'NULL',
-                                   QUOTEVALUE => 0,
-                                   ENTRYAGGREGATOR => 'OR',
-                                  );
-             }
-
-
-            $self->SUPER::Limit(LEFTJOIN => $ObjKeywordsAlias,
-                               FIELD => 'KeywordSelect',
-                               VALUE => $restriction->{'KEYWORDSELECT'},
-                               ENTRYAGGREGATOR => 'OR');
-
-
-            $self->SUPER::Limit( ALIAS => $ObjKeywordsAlias,
-                                 FIELD => 'ObjectType',
-                                 VALUE => 'Ticket',
-                                 ENTRYAGGREGATOR => 'AND');
-           
-           if ($null_columns_ok) {
-                $self->SUPER::Limit(ALIAS => $ObjKeywordsAlias,
-                                    FIELD => 'ObjectType',
-                                   OPERATOR => 'IS',
-                                    VALUE => 'NULL',
-                                   QUOTEVALUE => 0,
-                                    ENTRYAGGREGATOR => 'OR');
-           }
-          
-        }
-        # }}}
-
-    
-     }
-
-     
-     # here, we make sure we don't get any tickets that have been merged  into other tickets
-     # (Ticket Id == Ticket EffectiveId
-     # note that we _really_ don't want to do this if we're already looking at the effectiveid
-     if ($self->_isLimited && (! $self->{'looking_at_effective_id'})) {
-        $self->SUPER::Limit( FIELD => 'EffectiveId', 
-              OPERATOR => '=',
-              QUOTEVALUE => 0,
-              VALUE => 'main.id');   #TODO, we shouldn't be hard coding the tablename to main.
-      } 
-    $self->{'RecalcTicketLimits'} = 0;
-}
-
-# }}}
-
-# }}}
-
-# {{{ Deal with displaying rows of the listing 
-
-#
-#  Everything in this section is stub code for 2.2
-# It's not part of the API. It's not for your use
-# It's not for our use.
-#
-
-
-# {{{ sub SetListingFormat
-
-=head2 SetListingFormat
-
-Takes a single Format string as specified below. parses that format string and makes the various listing output
-things DTRT.
-
-=item Format strings
-
-Format strings are made up of a chain of Elements delimited with vertical pipes (|).
-Elements of a Format string 
-
-
-FormatString:    Element[::FormatString]
-
-Element:         AttributeName[;HREF=<URL>][;TITLE=<TITLE>]
-
-AttributeName    Id | Subject | Status | Owner | Priority | InitialPriority | TimeWorked | TimeLeft |
-  
-                 Keywords[;SELECT=<KeywordSelect>] | 
-       
-                <Created|Starts|Started|Contacted|Due|Resolved>Date<AsString|AsISO|AsAge>
-
-
-=cut
-
-
-
-
-#accept a format string
-
-
-
-sub SetListingFormat {
-    my $self = shift;
-    my $listing_format = shift;
-    
-    my ($element, $attribs);
-    my $i = 0;
-    foreach $element (split (/::/,$listing_format)) {
-       if ($element =~ /^(.*?);(.*)$/) {
-           $element = $1;
-           $attribs = $2;
-       }       
-       $self->{'format_string'}->[$i]->{'Element'} = $element;
-       foreach $attrib (split (/;/, $attribs)) {
-           my $value = "";
-           if ($attrib =~ /^(.*?)=(.*)$/) {
-               $attrib = $1;
-               $value = $2;
-           }   
-           $self->{'format_string'}->[$i]->{"$attrib"} = $val;
-           
-       }
-    
-    }
-    return(1);
-}
-
-# }}}
-
-# {{{ sub HeaderAsHTML
-sub HeaderAsHTML {
-    my $self = shift;
-    my $header = "";
-    my $col;
-    foreach $col ( @{[ $self->{'format_string'} ]}) {
-       $header .= "<TH>" . $self->_ColumnTitle($self->{'format_string'}->[$col]) . "</TH>";
-       
-    }
-    return ($header);
-}
-# }}}
-
-# {{{ sub HeaderAsText
-#Print text header
-sub HeaderAsText {
-    my $self = shift;
-    my ($header);
-    
-    return ($header);
-}
-# }}}
-
-# {{{ sub TicketAsHTMLRow
-#Print HTML row
-sub TicketAsHTMLRow {
-    my $self = shift;
-    my $Ticket = shift;
-    my ($row, $col);
-    foreach $col (@{[$self->{'format_string'}]}) {
-       $row .= "<TD>" . $self->_TicketColumnValue($ticket,$self->{'format_string'}->[$col]) . "</TD>";
-       
-    }
-    return ($row);
-}
-# }}}
-
-# {{{ sub TicketAsTextRow
-#Print text row
-sub TicketAsTextRow {
-    my $self = shift;
-    my ($row);
-
-    #TODO implement
-    
-    return ($row);
-}
-# }}}
-
-# {{{ _ColumnTitle {
-
-sub _ColumnTitle {
-    my $self = shift;
-    
-    # Attrib is a hash 
-    my $attrib = shift;
-    
-    # return either attrib->{'TITLE'} or..
-    if ($attrib->{'TITLE'}) {
-       return($attrib->{'TITLE'});
-    }  
-    # failing that, Look up the title in a hash
-    else {
-       #TODO create $self->{'ColumnTitles'};
-       return ($self->{'ColumnTitles'}->{$attrib->{'Element'}});
-    }  
-    
-}
-
-# }}}
-
-# {{{ _TicketColumnValue
-sub _TicketColumnValue {
-    my $self = shift;
-    my $Ticket = shift;
-    my $attrib = shift;
-
-    
-    my $out;
-
-  SWITCH: {
-       /^id/i && do {
-           $out = $Ticket->id;
-           last SWITCH; 
-       };
-       /^subj/i && do {
-           last SWITCH; 
-           $Ticket->Subject;
-                  };   
-       /^status/i && do {
-           last SWITCH; 
-           $Ticket->Status;
-       };
-       /^prio/i && do {
-           last SWITCH; 
-           $Ticket->Priority;
-       };
-       /^finalprio/i && do {
-           
-           last SWITCH; 
-           $Ticket->FinalPriority
-       };
-       /^initialprio/i && do {
-           
-           last SWITCH; 
-           $Ticket->InitialPriority;
-       };      
-       /^timel/i && do {
-           
-           last SWITCH; 
-           $Ticket->TimeWorked;
-       };
-       /^timew/i && do {
-           
-           last SWITCH; 
-           $Ticket->TimeLeft;
-       };
-       
-       /^(.*?)date(.*)$/i && do {
-           my $o = $1;
-           my $m = $2;
-           my ($obj);
-           #TODO: optimize
-           $obj = $Ticket->DueObj         if $o =~ /due/i;
-           $obj = $Ticket->CreatedObj     if $o =~ /created/i;
-           $obj = $Ticket->StartsObj      if $o =~ /starts/i;
-           $obj = $Ticket->StartedObj     if $o =~ /started/i;
-           $obj = $Ticket->ToldObj        if $o =~ /told/i;
-           $obj = $Ticket->LastUpdatedObj if $o =~ /lastu/i;
-           
-           $method = 'ISO' if $m =~ /iso/i;
-           
-           $method = 'AsString' if $m =~ /asstring/i;
-           $method = 'AgeAsString' if $m =~ /age/i;
-           last SWITCH;
-           $obj->$method();
-             
-       };
-         
-         /^watcher/i && do {
-             last SWITCH; 
-             $Ticket->WatchersAsString();
-         };    
-       
-       /^requestor/i && do {
-           last SWITCH; 
-           $Ticket->RequestorsAsString();
-       };      
-       /^cc/i && do {
-           last SWITCH; 
-           $Ticket->CCAsString();
-       };      
-       
-       
-       /^admincc/i && do {
-           last SWITCH; 
-           $Ticket->AdminCcAsString();
-       };
-       
-       /^keywords/i && do {
-           last SWITCH; 
-           #Limit it to the keyword select we're talking about, if we've got one.
-           my $objkeys =$Ticket->KeywordsObj($attrib->{'SELECT'});
-           $objkeys->KeywordRelativePathsAsString();
-       };
-       
-    }
-      
-}
-
-# }}}
-
-# }}}
-
-# {{{ POD
-=head2 notes
-"Enum" Things that get Is, IsNot
-
-
-"Int" Things that get Is LessThan and GreaterThan
-id
-InitialPriority
-FinalPriority
-Priority
-TimeLeft
-TimeWorked
-
-"Text" Things that get Is, Like
-Subject
-TransactionContent
-
-
-"Link" OPERATORs
-
-
-"Date" OPERATORs Is, Before, After
 
-  =cut
-# }}}
 1;
diff --git a/rt/lib/RT/Tickets_Overlay.pm b/rt/lib/RT/Tickets_Overlay.pm
new file mode 100644 (file)
index 0000000..d8a1ac8
--- /dev/null
@@ -0,0 +1,2055 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Major Changes:
+
+# - Decimated ProcessRestrictions and broke it into multiple
+# functions joined by a LUT
+# - Semi-Generic SQL stuff moved to another file
+
+# Known Issues: FIXME!
+
+# - ClearRestrictions and Reinitialization is messy and unclear.  The
+# only good way to do it is to create a new RT::Tickets object.
+
+=head1 NAME
+
+  RT::Tickets - A collection of Ticket objects
+
+
+=head1 SYNOPSIS
+
+  use RT::Tickets;
+  my $tickets = new RT::Tickets($CurrentUser);
+
+=head1 DESCRIPTION
+
+   A collection of RT::Tickets.
+
+=head1 METHODS
+
+=begin testing
+
+ok (require RT::Tickets);
+
+=end testing
+
+=cut
+use strict;
+no warnings qw(redefine);
+use vars qw(@SORTFIELDS);
+
+
+# Configuration Tables:
+
+# FIELDS is a mapping of searchable Field name, to Type, and other
+# metadata.
+
+my %FIELDS =
+  ( Status         => ['ENUM'],
+    Queue          => ['ENUM' => 'Queue',],
+    Type           => ['ENUM',],
+    Creator        => ['ENUM' => 'User',],
+    LastUpdatedBy   => ['ENUM' => 'User',],
+    Owner          => ['ENUM' => 'User',],
+    EffectiveId            => ['INT',],
+    id             => ['INT',],
+    InitialPriority => ['INT',],
+    FinalPriority   => ['INT',],
+    Priority       => ['INT',],
+    TimeLeft       => ['INT',],
+    TimeWorked     => ['INT',],
+    MemberOf       => ['LINK' => To => 'MemberOf', ],
+    DependsOn      => ['LINK' => To => 'DependsOn',],
+    RefersTo        => ['LINK' => To => 'RefersTo',],
+    HasMember      => ['LINK' => From => 'MemberOf',],
+    DependentOn     => ['LINK' => From => 'DependsOn',],
+    ReferredTo      => ['LINK' => From => 'RefersTo',],
+#   HasDepender            => ['LINK',],
+#   RelatedTo      => ['LINK',],
+    Told           => ['DATE' => 'Told',],
+    Starts         => ['DATE' => 'Starts',],
+    Started        => ['DATE' => 'Started',],
+    Due                    => ['DATE' => 'Due',],
+    Resolved       => ['DATE' => 'Resolved',],
+    LastUpdated            => ['DATE' => 'LastUpdated',],
+    Created        => ['DATE' => 'Created',],
+    Subject        => ['STRING',],
+    Type           => ['STRING',],
+    Content        => ['TRANSFIELD',],
+    ContentType            => ['TRANSFIELD',],
+    Filename        => ['TRANSFIELD',],
+    TransactionDate => ['TRANSDATE',],
+    Requestor       => ['WATCHERFIELD' => 'Requestor',],
+    CC              => ['WATCHERFIELD' => 'Cc',],
+    AdminCC         => ['WATCHERFIELD' => 'AdminCC',],
+    Watcher        => ['WATCHERFIELD'],
+    LinkedTo       => ['LINKFIELD',],
+    CustomFieldValue =>['CUSTOMFIELD',],
+    CF              => ['CUSTOMFIELD',],
+  );
+
+# Mapping of Field Type to Function
+my %dispatch =
+  ( ENUM           => \&_EnumLimit,
+    INT                    => \&_IntLimit,
+    LINK           => \&_LinkLimit,
+    DATE           => \&_DateLimit,
+    STRING         => \&_StringLimit,
+    TRANSFIELD     => \&_TransLimit,
+    TRANSDATE      => \&_TransDateLimit,
+    WATCHERFIELD    => \&_WatcherLimit,
+    LINKFIELD      => \&_LinkFieldLimit,
+    CUSTOMFIELD    => \&_CustomFieldLimit,
+  );
+
+# Default EntryAggregator per type
+my %DefaultEA = (
+                 INT           => 'AND',
+                 ENUM          => { '=' => 'OR',
+                                    '!='=> 'AND'
+                                  },
+                 DATE          => 'AND',
+                 STRING                => { '=' => 'OR',
+                                    '!='=> 'AND',
+                                    'LIKE'=> 'AND',
+                                    'NOT LIKE' => 'AND'
+                                  },
+                 TRANSFIELD    => 'AND',
+                 TRANSDATE     => 'AND',
+                 LINKFIELD     => 'AND',
+                 TARGET                => 'AND',
+                 BASE          => 'AND',
+                 WATCHERFIELD  => { '=' => 'OR',
+                                    '!='=> 'AND',
+                                    'LIKE'=> 'OR',
+                                    'NOT LIKE' => 'AND'
+                                  },
+
+                 CUSTOMFIELD   => 'OR',
+                );
+
+
+# Helper functions for passing the above lexically scoped tables above
+# into Tickets_Overlay_SQL.
+sub FIELDS   { return \%FIELDS   }
+sub dispatch { return \%dispatch }
+
+# Bring in the clowns.
+require RT::Tickets_Overlay_SQL;
+
+# {{{ sub SortFields
+
+@SORTFIELDS = qw(id Status
+                Queue Subject
+         Owner Created Due Starts Started
+         Told
+                Resolved LastUpdated Priority TimeWorked TimeLeft);
+
+=head2 SortFields
+
+Returns the list of fields that lists of tickets can easily be sorted by
+
+=cut
+
+sub SortFields {
+       my $self = shift;
+       return(@SORTFIELDS);
+}
+
+
+# }}}
+
+
+# BEGIN SQL STUFF *********************************
+
+=head1 Limit Helper Routines
+
+These routines are the targets of a dispatch table depending on the
+type of field.  They all share the same signature:
+
+  my ($self,$field,$op,$value,@rest) = @_;
+
+The values in @rest should be suitable for passing directly to
+DBIx::SearchBuilder::Limit.
+
+Essentially they are an expanded/broken out (and much simplified)
+version of what ProcessRestrictions used to do.  They're also much
+more clearly delineated by the TYPE of field being processed.
+
+=head2 _EnumLimit
+
+Handle Fields which are limited to certain values, and potentially
+need to be looked up from another class.
+
+This subroutine actually handles two different kinds of fields.  For
+some the user is responsible for limiting the values.  (i.e. Status,
+Type).
+
+For others, the value specified by the user will be looked by via
+specified class.
+
+Meta Data:
+  name of class to lookup in (Optional)
+
+=cut
+
+sub _EnumLimit {
+  my ($sb,$field,$op,$value,@rest) = @_;
+
+  # SQL::Statement changes != to <>.  (Can we remove this now?)
+  $op = "!=" if $op eq "<>";
+
+  die "Invalid Operation: $op for $field"
+    unless $op eq "=" or $op eq "!=";
+
+  my $meta = $FIELDS{$field};
+  if (defined $meta->[1]) {
+    my $class = "RT::" . $meta->[1];
+    my $o = $class->new($sb->CurrentUser);
+    $o->Load( $value );
+    $value = $o->Id;
+  }
+  $sb->_SQLLimit( FIELD => $field,,
+             VALUE => $value,
+             OPERATOR => $op,
+             @rest,
+           );
+}
+
+=head2 _IntLimit
+
+Handle fields where the values are limited to integers.  (For example,
+Priority, TimeWorked.)
+
+Meta Data:
+  None
+
+=cut
+
+sub _IntLimit {
+  my ($sb,$field,$op,$value,@rest) = @_;
+
+  die "Invalid Operator $op for $field"
+    unless $op =~ /^(=|!=|>|<|>=|<=)$/;
+
+  $sb->_SQLLimit(
+            FIELD => $field,
+            VALUE => $value,
+            OPERATOR => $op,
+            @rest,
+           );
+}
+
+
+=head2 _LinkLimit
+
+Handle fields which deal with links between tickets.  (MemberOf, DependsOn)
+
+Meta Data:
+  1: Direction (From,To)
+  2: Relationship Type (MemberOf, DependsOn,RefersTo)
+
+=cut
+
+sub _LinkLimit {
+  my ($sb,$field,$op,$value,@rest) = @_;
+
+  die "Op must be ="
+    unless $op eq "=";
+
+  my $meta = $FIELDS{$field};
+  die "Incorrect Meta Data for $field"
+    unless (defined $meta->[1] and defined $meta->[2]);
+
+  my $LinkAlias = $sb->NewAlias ('Links');
+
+  $sb->_OpenParen();
+
+  $sb->_SQLLimit(
+            ALIAS => $LinkAlias,
+            FIELD =>   'Type',
+            OPERATOR => '=',
+            VALUE => $meta->[2],
+            @rest,
+           );
+
+  if ($meta->[1] eq "To") {
+    my $matchfield = ( $value  =~ /^(\d+)$/ ? "LocalTarget" : "Target" );
+
+    $sb->_SQLLimit(
+              ALIAS => $LinkAlias,
+              ENTRYAGGREGATOR => 'AND',
+              FIELD =>   $matchfield,
+              OPERATOR => '=',
+              VALUE => $value ,
+             );
+
+    #If we're searching on target, join the base to ticket.id
+    $sb->Join( ALIAS1 => 'main', FIELD1 => $sb->{'primary_key'},
+              ALIAS2 => $LinkAlias,     FIELD2 => 'LocalBase');
+
+  } elsif ( $meta->[1] eq "From" ) {
+    my $matchfield = ( $value  =~ /^(\d+)$/ ? "LocalBase" : "Base" );
+
+    $sb->_SQLLimit(
+              ALIAS => $LinkAlias,
+              ENTRYAGGREGATOR => 'AND',
+              FIELD =>   $matchfield,
+              OPERATOR => '=',
+              VALUE => $value ,
+             );
+
+    #If we're searching on base, join the target to ticket.id
+    $sb->Join( ALIAS1 => 'main',     FIELD1 => $sb->{'primary_key'},
+              ALIAS2 => $LinkAlias, FIELD2 => 'LocalTarget');
+
+  } else {
+    die "Invalid link direction '$meta->[1]' for $field\n";
+  }
+
+  $sb->_CloseParen();
+
+}
+
+=head2 _DateLimit
+
+Handle date fields.  (Created, LastTold..)
+
+Meta Data:
+  1: type of relationship.  (Probably not necessary.)
+
+=cut
+
+sub _DateLimit {
+  my ($sb,$field,$op,$value,@rest) = @_;
+
+  die "Invalid Date Op: $op"
+     unless $op =~ /^(=|!=|>|<|>=|<=)$/;
+
+  my $meta = $FIELDS{$field};
+  die "Incorrect Meta Data for $field"
+    unless (defined $meta->[1]);
+
+  require Time::ParseDate;
+  use POSIX 'strftime';
+
+  my $time = Time::ParseDate::parsedate( $value,
+                       UK => $RT::DateDayBeforeMonth,
+                       PREFER_PAST => $RT::AmbiguousDayInPast,
+                       PREFER_FUTURE => !($RT::AmbiguousDayInPast));
+  $value = strftime("%Y-%m-%d %H:%M",localtime($time));
+
+  $sb->_SQLLimit(
+            FIELD => $meta->[1],
+            OPERATOR => $op,
+            VALUE => $value,
+            @rest,
+           );
+}
+
+=head2 _StringLimit
+
+Handle simple fields which are just strings.  (Subject,Type)
+
+Meta Data:
+  None
+
+=cut
+
+sub _StringLimit {
+  my ($sb,$field,$op,$value,@rest) = @_;
+
+  # FIXME:
+  # Valid Operators:
+  #  =, !=, LIKE, NOT LIKE
+
+  $sb->_SQLLimit(
+            FIELD => $field,
+            OPERATOR => $op,
+            VALUE => $value,
+            CASESENSITIVE => 0,
+            @rest,
+           );
+}
+
+=head2 _TransDateLimit
+
+Handle fields limiting based on Transaction Date.
+
+The inpupt value must be in a format parseable by Time::ParseDate
+
+Meta Data:
+  None
+
+=cut
+
+sub _TransDateLimit {
+  my ($sb,$field,$op,$value,@rest) = @_;
+
+  # See the comments for TransLimit, they apply here too
+
+  $sb->{_sql_transalias} = $sb->NewAlias ('Transactions')
+    unless defined $sb->{_sql_transalias};
+  $sb->{_sql_trattachalias} = $sb->NewAlias ('Attachments')
+    unless defined $sb->{_sql_trattachalias};
+
+  $sb->_OpenParen;
+
+  # Join Transactions To Attachments
+  $sb->Join( ALIAS1 => $sb->{_sql_trattachalias}, FIELD1 => 'TransactionId',
+            ALIAS2 => $sb->{_sql_transalias}, FIELD2 => 'id');
+
+  # Join Transactions to Tickets
+  $sb->Join( ALIAS1 => 'main', FIELD1 => $sb->{'primary_key'}, # UGH!
+            ALIAS2 => $sb->{_sql_transalias}, FIELD2 => 'Ticket');
+
+  my $d = new RT::Date( $sb->CurrentUser );
+  $d->Set($value);
+  $value = $d->ISO;
+
+  #Search for the right field
+  $sb->_SQLLimit(ALIAS => $sb->{_sql_trattachalias},
+                FIELD =>    'Created',
+                OPERATOR => $op,
+                VALUE =>    $value,
+                CASESENSITIVE => 0,
+                @rest
+               );
+
+  $sb->_CloseParen;
+}
+
+=head2 _TransLimit
+
+Limit based on the Content of a transaction or the ContentType.
+
+Meta Data:
+  none
+
+=cut
+
+sub _TransLimit {
+  # Content, ContentType, Filename
+
+  # If only this was this simple.  We've got to do something
+  # complicated here:
+
+            #Basically, we want to make sure that the limits apply to
+            #the same attachment, rather than just another attachment
+            #for the same ticket, no matter how many clauses we lump
+            #on. We put them in TicketAliases so that they get nuked
+            #when we redo the join.
+
+  # In the SQL, we might have
+  #       (( Content = foo ) or ( Content = bar AND Content = baz ))
+  # The AND group should share the same Alias.
+
+  # Actually, maybe it doesn't matter.  We use the same alias and it
+  # works itself out? (er.. different.)
+
+  # Steal more from _ProcessRestrictions
+
+  # FIXME: Maybe look at the previous FooLimit call, and if it was a
+  # TransLimit and EntryAggregator == AND, reuse the Aliases?
+
+  # Or better - store the aliases on a per subclause basis - since
+  # those are going to be the things we want to relate to each other,
+  # anyway.
+
+  # maybe we should not allow certain kinds of aggregation of these
+  # clauses and do a psuedo regex instead? - the problem is getting
+  # them all into the same subclause when you have (A op B op C) - the
+  # way they get parsed in the tree they're in different subclauses.
+
+  my ($sb,$field,$op,$value,@rest) = @_;
+
+  $sb->{_sql_transalias} = $sb->NewAlias ('Transactions')
+    unless defined $sb->{_sql_transalias};
+  $sb->{_sql_trattachalias} = $sb->NewAlias ('Attachments')
+    unless defined $sb->{_sql_trattachalias};
+
+  $sb->_OpenParen;
+
+  # Join Transactions To Attachments
+  $sb->Join( ALIAS1 => $sb->{_sql_trattachalias}, FIELD1 => 'TransactionId',
+            ALIAS2 => $sb->{_sql_transalias}, FIELD2 => 'id');
+
+  # Join Transactions to Tickets
+  $sb->Join( ALIAS1 => 'main', FIELD1 => $sb->{'primary_key'}, # UGH!
+            ALIAS2 => $sb->{_sql_transalias}, FIELD2 => 'Ticket');
+
+  #Search for the right field
+  $sb->_SQLLimit(ALIAS => $sb->{_sql_trattachalias},
+                FIELD =>    $field,
+                OPERATOR => $op,
+                VALUE =>    $value,
+                CASESENSITIVE => 0,
+                @rest
+               );
+
+  $sb->_CloseParen;
+
+}
+
+=head2 _WatcherLimit
+
+Handle watcher limits.  (Requestor, CC, etc..)
+
+Meta Data:
+  1: Field to query on
+
+=cut
+
+sub _WatcherLimit {
+  my ($self,$field,$op,$value,@rest) = @_;
+  my %rest = @rest;
+
+  $self->_OpenParen;
+
+  my $groups       = $self->NewAlias('Groups');
+  my $group_princs  = $self->NewAlias('Principals');
+  my $groupmembers  = $self->NewAlias('CachedGroupMembers');
+  my $member_princs = $self->NewAlias('Principals');
+  my $users        = $self->NewAlias('Users');
+
+
+  #Find user watchers
+#  my $subclause = undef;
+#  my $aggregator = 'OR';
+#  if ($restriction->{'OPERATOR'} =~ /!|NOT/i ){
+#    $subclause = 'AndEmailIsNot';
+#    $aggregator = 'AND';
+#  }
+
+
+  $self->_SQLLimit(ALIAS => $users,
+                  FIELD => $rest{SUBKEY} || 'EmailAddress',
+                  VALUE           => $value,
+                  OPERATOR        => $op,
+                  CASESENSITIVE   => 0,
+                  @rest,
+                 );
+
+  # {{{ Tie to groups for tickets we care about
+  $self->_SQLLimit(ALIAS => $groups,
+                  FIELD => 'Domain',
+                  VALUE => 'RT::Ticket-Role',
+                  ENTRYAGGREGATOR => 'AND');
+
+  $self->Join(ALIAS1 => $groups, FIELD1 => 'Instance',
+             ALIAS2 => 'main',   FIELD2 => 'id');
+  # }}}
+
+  # If we care about which sort of watcher
+  my $meta = $FIELDS{$field};
+  my $type = ( defined $meta->[1] ? $meta->[1] : undef );
+
+  if ( $type ) {
+    $self->_SQLLimit(ALIAS => $groups,
+                    FIELD => 'Type',
+                    VALUE => $type,
+                    ENTRYAGGREGATOR => 'AND');
+  }
+
+  $self->Join (ALIAS1 => $groups,  FIELD1 => 'id',
+              ALIAS2 => $group_princs, FIELD2 => 'ObjectId');
+  $self->_SQLLimit(ALIAS => $group_princs,
+                  FIELD => 'PrincipalType',
+                  VALUE => 'Group',
+                  ENTRYAGGREGATOR => 'AND');
+  $self->Join( ALIAS1 => $group_princs, FIELD1 => 'id',
+              ALIAS2 => $groupmembers, FIELD2 => 'GroupId');
+
+  $self->Join( ALIAS1 => $groupmembers, FIELD1 => 'MemberId',
+              ALIAS2 => $member_princs, FIELD2 => 'id');
+  $self->Join (ALIAS1 => $member_princs, FIELD1 => 'ObjectId',
+              ALIAS2 => $users, FIELD2 => 'id');
+
+ $self->_CloseParen;
+
+}
+
+sub _LinkFieldLimit {
+  my $restriction;
+  my $self;
+  my $LinkAlias;
+  my %args;
+  if ($restriction->{'TYPE'}) {
+    $self->SUPER::Limit(ALIAS => $LinkAlias,
+                       ENTRYAGGREGATOR => 'AND',
+                       FIELD =>   'Type',
+                       OPERATOR => '=',
+                       VALUE =>    $restriction->{'TYPE'} );
+  }
+
+   #If we're trying to limit it to things that are target of
+  if ($restriction->{'TARGET'}) {
+    # If the TARGET is an integer that means that we want to look at
+    # the LocalTarget field. otherwise, we want to look at the
+    # "Target" field
+    my ($matchfield);
+    if ($restriction->{'TARGET'} =~/^(\d+)$/) {
+      $matchfield = "LocalTarget";
+    } else {
+      $matchfield = "Target";
+    }
+    $self->SUPER::Limit(ALIAS => $LinkAlias,
+                       ENTRYAGGREGATOR => 'AND',
+                       FIELD =>   $matchfield,
+                       OPERATOR => '=',
+                       VALUE =>    $restriction->{'TARGET'} );
+    #If we're searching on target, join the base to ticket.id
+    $self->Join( ALIAS1 => 'main', FIELD1 => $self->{'primary_key'},
+                ALIAS2 => $LinkAlias,
+                FIELD2 => 'LocalBase');
+  }
+  #If we're trying to limit it to things that are base of
+  elsif ($restriction->{'BASE'}) {
+    # If we're trying to match a numeric link, we want to look at
+    # LocalBase, otherwise we want to look at "Base"
+    my ($matchfield);
+    if ($restriction->{'BASE'} =~/^(\d+)$/) {
+      $matchfield = "LocalBase";
+    } else {
+      $matchfield = "Base";
+    }
+
+    $self->SUPER::Limit(ALIAS => $LinkAlias,
+                       ENTRYAGGREGATOR => 'AND',
+                       FIELD => $matchfield,
+                       OPERATOR => '=',
+                       VALUE =>    $restriction->{'BASE'} );
+    #If we're searching on base, join the target to ticket.id
+    $self->Join( ALIAS1 => 'main', FIELD1 => $self->{'primary_key'},
+                ALIAS2 => $LinkAlias,
+                FIELD2 => 'LocalTarget')
+  }
+}
+
+
+=head2 KeywordLimit
+
+Limit based on Keywords
+
+Meta Data:
+  none
+
+=cut
+
+sub _CustomFieldLimit {
+  my ($self,$_field,$op,$value,@rest) = @_;
+
+  my %rest = @rest;
+  my $field = $rest{SUBKEY} || die "No field specified";
+
+  # For our sanity, we can only limit on one queue at a time
+  my $queue = undef;
+  # Ugh.    This will not do well for things with underscores in them
+
+  use RT::CustomFields;
+  my $CF = RT::CustomFields->new( $self->CurrentUser );
+  #$CF->Load( $cfid} );
+
+  my $q;
+  if ($field =~ /^(.+?)\.{(.+)}$/) {
+    my $q = RT::Queue->new($self->CurrentUser);
+    $q->Load($1);
+    $field = $2;
+    $CF->LimitToQueue( $q->Id );
+    $queue = $q->Id;
+  } else {
+    $CF->LimitToGlobal;
+  }
+  $CF->FindAllRows;
+
+  my $cfid = 0;
+
+  while ( my $CustomField = $CF->Next ) {
+    if ($CustomField->Name eq $field) {
+      $cfid = $CustomField->Id;
+      last;
+    }
+  }
+  die "No custom field named $field found\n"
+    unless $cfid;
+
+#   use RT::CustomFields;
+#   my $CF = RT::CustomField->new( $self->CurrentUser );
+#   $CF->Load( $cfid );
+
+
+  my $null_columns_ok;
+  my $TicketCFs = $self->Join( TYPE   => 'left',
+                              ALIAS1 => 'main',
+                              FIELD1 => 'id',
+                              TABLE2 => 'TicketCustomFieldValues',
+                              FIELD2 => 'Ticket' );
+
+  $self->_OpenParen;
+
+  $self->_SQLLimit( ALIAS      => $TicketCFs,
+                   FIELD      => 'Content',
+                   OPERATOR   => $op,
+                   VALUE      => $value,
+                   QUOTEVALUE => 1,
+                   @rest );
+
+  if (   $op =~ /^IS$/i
+        or ( $op eq '!=' ) ) {
+    $null_columns_ok = 1;
+  }
+
+  #If we're trying to find tickets where the keyword isn't somethng,
+  #also check ones where it _IS_ null
+
+  if ( $op eq '!=' ) {
+    $self->_SQLLimit( ALIAS           => $TicketCFs,
+                     FIELD           => 'Content',
+                     OPERATOR        => 'IS',
+                     VALUE           => 'NULL',
+                     QUOTEVALUE      => 0,
+                     ENTRYAGGREGATOR => 'OR', );
+  }
+
+  $self->_SQLLimit( LEFTJOIN => $TicketCFs,
+                   FIELD    => 'CustomField',
+                   VALUE    => $cfid,
+                   ENTRYAGGREGATOR => 'OR' );
+
+
+
+  $self->_CloseParen;
+
+}
+
+
+# End Helper Functions
+
+# End of SQL Stuff -------------------------------------------------
+
+# {{{ Limit the result set based on content
+
+# {{{ sub Limit
+
+=head2 Limit
+
+Takes a paramhash with the fields FIELD, OPERATOR, VALUE and DESCRIPTION
+Generally best called from LimitFoo methods
+
+=cut
+sub Limit {
+    my $self = shift;
+    my %args = ( FIELD => undef,
+                OPERATOR => '=',
+                VALUE => undef,
+                DESCRIPTION => undef,
+                @_
+              );
+    $args{'DESCRIPTION'} = $self->loc(
+       "[_1] [_2] [_3]", $args{'FIELD'}, $args{'OPERATOR'}, $args{'VALUE'}
+    ) if (!defined $args{'DESCRIPTION'}) ;
+
+    my $index = $self->_NextIndex;
+
+    #make the TicketRestrictions hash the equivalent of whatever we just passed in;
+
+    %{$self->{'TicketRestrictions'}{$index}} = %args;
+
+    $self->{'RecalcTicketLimits'} = 1;
+
+    # If we're looking at the effective id, we don't want to append the other clause
+    # which limits us to tickets where id = effective id
+    if ($args{'FIELD'} eq 'EffectiveId') {
+        $self->{'looking_at_effective_id'} = 1;
+    }
+
+    if ($args{'FIELD'} eq 'Type') {
+        $self->{'looking_at_type'} = 1;
+    }
+
+    return ($index);
+}
+
+# }}}
+
+
+
+
+=head2 FreezeLimits
+
+Returns a frozen string suitable for handing back to ThawLimits.
+
+=cut
+# {{{ sub FreezeLimits
+
+sub FreezeLimits {
+       my $self = shift;
+       require FreezeThaw;
+       return (FreezeThaw::freeze($self->{'TicketRestrictions'},
+                                  $self->{'restriction_index'}
+                                 ));
+}
+
+# }}}
+
+=head2 ThawLimits
+
+Take a frozen Limits string generated by FreezeLimits and make this tickets
+object have that set of limits.
+
+=cut
+# {{{ sub ThawLimits
+
+sub ThawLimits {
+       my $self = shift;
+       my $in = shift;
+       
+       #if we don't have $in, get outta here.
+       return undef unless ($in);
+
+       $self->{'RecalcTicketLimits'} = 1;
+
+       require FreezeThaw;
+       
+       #We don't need to die if the thaw fails.
+       
+       eval {
+               ($self->{'TicketRestrictions'},
+               $self->{'restriction_index'}
+               ) = FreezeThaw::thaw($in);
+       }
+
+}
+
+# }}}
+
+# {{{ Limit by enum or foreign key
+
+# {{{ sub LimitQueue
+
+=head2 LimitQueue
+
+LimitQueue takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of = or !=. (It defaults to =).
+VALUE is a queue id or Name.
+
+
+=cut
+
+sub LimitQueue {
+    my $self = shift;
+    my %args = (VALUE => undef,
+               OPERATOR => '=',
+               @_);
+
+    #TODO  VALUE should also take queue names and queue objects
+    #TODO FIXME why are we canonicalizing to name, not id, robrt?
+    if ($args{VALUE} =~ /^\d+$/) {
+      my $queue = new RT::Queue($self->CurrentUser);
+      $queue->Load($args{'VALUE'});
+      $args{VALUE} = $queue->Name;
+    }
+
+    # What if they pass in an Id?  Check for isNum() and convert to
+    # string.
+
+    #TODO check for a valid queue here
+
+    $self->Limit (FIELD => 'Queue',
+                 VALUE => $args{VALUE},
+                 OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Queue'), $args{'OPERATOR'}, $args{VALUE},
+                 ),
+                );
+
+}
+# }}}
+
+# {{{ sub LimitStatus
+
+=head2 LimitStatus
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of = or !=.
+VALUE is a status.
+
+=cut
+
+sub LimitStatus {
+    my $self = shift;
+    my %args = ( OPERATOR => '=',
+                  @_);
+    $self->Limit (FIELD => 'Status',
+                 VALUE => $args{'VALUE'},
+                 OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Status'), $args{'OPERATOR'}, $self->loc($args{'VALUE'})
+                 ),
+                );
+}
+
+# }}}
+
+# {{{ sub IgnoreType
+
+=head2 IgnoreType
+
+If called, this search will not automatically limit the set of results found
+to tickets of type "Ticket". Tickets of other types, such as "project" and
+"approval" will be found.
+
+=cut
+
+sub IgnoreType {
+    my $self = shift;
+
+    # Instead of faking a Limit that later gets ignored, fake up the
+    # fact that we're already looking at type, so that the check in
+    # Tickets_Overlay_SQL/FromSQL goes down the right branch
+
+    #  $self->LimitType(VALUE => '__any');
+    $self->{looking_at_type} = 1;
+}
+
+# }}}
+
+# {{{ sub LimitType
+
+=head2 LimitType
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of = or !=, it defaults to "=".
+VALUE is a string to search for in the type of the ticket.
+
+
+
+=cut
+
+sub LimitType {
+    my $self = shift;
+    my %args = (OPERATOR => '=',
+               VALUE => undef,
+               @_);
+    $self->Limit (FIELD => 'Type',
+                  VALUE => $args{'VALUE'},
+                  OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Type'), $args{'OPERATOR'}, $args{'Limit'},
+                 ),
+                 );
+}
+
+# }}}
+
+# }}}
+
+# {{{ Limit by string field
+
+# {{{ sub LimitSubject
+
+=head2 LimitSubject
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of = or !=.
+VALUE is a string to search for in the subject of the ticket.
+
+=cut
+
+sub LimitSubject {
+    my $self = shift;
+    my %args = (@_);
+    $self->Limit (FIELD => 'Subject',
+                 VALUE => $args{'VALUE'},
+                 OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Subject'), $args{'OPERATOR'}, $args{'VALUE'},
+                 ),
+                );
+}
+
+# }}}
+
+# }}}
+
+# {{{ Limit based on ticket numerical attributes
+# Things that can be > < = !=
+
+# {{{ sub LimitId
+
+=head2 LimitId
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of =, >, < or !=.
+VALUE is a ticket Id to search for
+
+=cut
+
+sub LimitId {
+    my $self = shift;
+    my %args = (OPERATOR => '=',
+                @_);
+
+    $self->Limit (FIELD => 'id',
+                  VALUE => $args{'VALUE'},
+                  OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Id'), $args{'OPERATOR'}, $args{'VALUE'},
+                 ),
+                 );
+}
+
+# }}}
+
+# {{{ sub LimitPriority
+
+=head2 LimitPriority
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of =, >, < or !=.
+VALUE is a value to match the ticket\'s priority against
+
+=cut
+
+sub LimitPriority {
+    my $self = shift;
+    my %args = (@_);
+    $self->Limit (FIELD => 'Priority',
+                 VALUE => $args{'VALUE'},
+                 OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Priority'), $args{'OPERATOR'}, $args{'VALUE'},
+                 ),
+                );
+}
+
+# }}}
+
+# {{{ sub LimitInitialPriority
+
+=head2 LimitInitialPriority
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of =, >, < or !=.
+VALUE is a value to match the ticket\'s initial priority against
+
+
+=cut
+
+sub LimitInitialPriority {
+    my $self = shift;
+    my %args = (@_);
+    $self->Limit (FIELD => 'InitialPriority',
+                 VALUE => $args{'VALUE'},
+                 OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Initial Priority'), $args{'OPERATOR'}, $args{'VALUE'},
+                 ),
+                );
+}
+
+# }}}
+
+# {{{ sub LimitFinalPriority
+
+=head2 LimitFinalPriority
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of =, >, < or !=.
+VALUE is a value to match the ticket\'s final priority against
+
+=cut
+
+sub LimitFinalPriority {
+    my $self = shift;
+    my %args = (@_);
+    $self->Limit (FIELD => 'FinalPriority',
+                 VALUE => $args{'VALUE'},
+                 OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Final Priority'), $args{'OPERATOR'}, $args{'VALUE'},
+                 ),
+                );
+}
+
+# }}}
+
+# {{{ sub LimitTimeWorked
+
+=head2 LimitTimeWorked
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of =, >, < or !=.
+VALUE is a value to match the ticket's TimeWorked attribute
+
+=cut
+
+sub LimitTimeWorked {
+    my $self = shift;
+    my %args = (@_);
+    $self->Limit (FIELD => 'TimeWorked',
+                 VALUE => $args{'VALUE'},
+                 OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Time worked'), $args{'OPERATOR'}, $args{'VALUE'},
+                 ),
+                );
+}
+
+# }}}
+
+# {{{ sub LimitTimeLeft
+
+=head2 LimitTimeLeft
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of =, >, < or !=.
+VALUE is a value to match the ticket's TimeLeft attribute
+
+=cut
+
+sub LimitTimeLeft {
+    my $self = shift;
+    my %args = (@_);
+    $self->Limit (FIELD => 'TimeLeft',
+                 VALUE => $args{'VALUE'},
+                 OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Time left'), $args{'OPERATOR'}, $args{'VALUE'},
+                 ),
+                );
+}
+
+# }}}
+
+# }}}
+
+# {{{ Limiting based on attachment attributes
+
+# {{{ sub LimitContent
+
+=head2 LimitContent
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of =, LIKE, NOT LIKE or !=.
+VALUE is a string to search for in the body of the ticket
+
+=cut
+sub LimitContent {
+    my $self = shift;
+    my %args = (@_);
+    $self->Limit (FIELD => 'Content',
+                 VALUE => $args{'VALUE'},
+                 OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Ticket content'), $args{'OPERATOR'}, $args{'VALUE'},
+                 ),
+                );
+}
+
+# }}}
+
+# {{{ sub LimitFilename
+
+=head2 LimitFilename
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of =, LIKE, NOT LIKE or !=.
+VALUE is a string to search for in the body of the ticket
+
+=cut
+sub LimitFilename {
+    my $self = shift;
+    my %args = (@_);
+    $self->Limit (FIELD => 'Filename',
+                 VALUE => $args{'VALUE'},
+                 OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Attachment filename'), $args{'OPERATOR'}, $args{'VALUE'},
+                 ),
+                );
+}
+
+# }}}
+# {{{ sub LimitContentType
+
+=head2 LimitContentType
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of =, LIKE, NOT LIKE or !=.
+VALUE is a content type to search ticket attachments for
+
+=cut
+
+sub LimitContentType {
+    my $self = shift;
+    my %args = (@_);
+    $self->Limit (FIELD => 'ContentType',
+                 VALUE => $args{'VALUE'},
+                 OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Ticket content type'), $args{'OPERATOR'}, $args{'VALUE'},
+                 ),
+                );
+}
+# }}}
+
+# }}}
+
+# {{{ Limiting based on people
+
+# {{{ sub LimitOwner
+
+=head2 LimitOwner
+
+Takes a paramhash with the fields OPERATOR and VALUE.
+OPERATOR is one of = or !=.
+VALUE is a user id.
+
+=cut
+
+sub LimitOwner {
+    my $self = shift;
+    my %args = ( OPERATOR => '=',
+                 @_);
+
+    my $owner = new RT::User($self->CurrentUser);
+    $owner->Load($args{'VALUE'});
+    # FIXME: check for a valid $owner
+    $self->Limit (FIELD => 'Owner',
+                 VALUE => $args{'VALUE'},
+                 OPERATOR => $args{'OPERATOR'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc('Owner'), $args{'OPERATOR'}, $owner->Name(),
+                 ),
+                );
+
+}
+
+# }}}
+
+# {{{ Limiting watchers
+
+# {{{ sub LimitWatcher
+
+
+=head2 LimitWatcher
+
+  Takes a paramhash with the fields OPERATOR, TYPE and VALUE.
+  OPERATOR is one of =, LIKE, NOT LIKE or !=.
+  VALUE is a value to match the ticket\'s watcher email addresses against
+  TYPE is the sort of watchers you want to match against. Leave it undef if you want to search all of them
+
+=begin testing
+
+my $t1 = RT::Ticket->new($RT::SystemUser);
+$t1->Create(Queue => 'general', Subject => "LimitWatchers test", Requestors => \['requestor1@example.com']);
+
+=end testing
+
+=cut
+
+sub LimitWatcher {
+    my $self = shift;
+    my %args = ( OPERATOR => '=',
+                VALUE => undef,
+                TYPE => undef,
+               @_);
+
+
+    #build us up a description
+    my ($watcher_type, $desc);
+    if ($args{'TYPE'}) {
+       $watcher_type = $args{'TYPE'};
+    }
+    else {
+       $watcher_type = "Watcher";
+    }
+
+    $self->Limit (FIELD => $watcher_type,
+                 VALUE => $args{'VALUE'},
+                 OPERATOR => $args{'OPERATOR'},
+                 TYPE => $args{'TYPE'},
+                 DESCRIPTION => join(
+                  ' ', $self->loc($watcher_type), $args{'OPERATOR'}, $args{'VALUE'},
+                 ),
+                );
+}
+
+
+sub LimitRequestor {
+    my $self = shift;
+    my %args = (@_);
+  my ($package, $filename, $line) = caller;
+    $RT::Logger->error("Tickets->LimitRequestor is deprecated. please rewrite call at  $package - $filename: $line");
+    $self->LimitWatcher(TYPE => 'Requestor', @_);
+
+}
+
+# }}}
+
+
+# }}}
+
+# }}}
+
+# {{{ Limiting based on links
+
+# {{{ LimitLinkedTo
+
+=head2 LimitLinkedTo
+
+LimitLinkedTo takes a paramhash with two fields: TYPE and TARGET
+TYPE limits the sort of relationship we want to search on
+
+TYPE = { RefersTo, MemberOf, DependsOn }
+
+TARGET is the id or URI of the TARGET of the link
+(TARGET used to be 'TICKET'.  'TICKET' is deprecated, but will be treated as TARGET
+
+=cut
+
+sub LimitLinkedTo {
+    my $self = shift;
+    my %args = (
+               TICKET => undef,
+               TARGET => undef,
+               TYPE => undef,
+                @_);
+
+    $self->Limit(
+                FIELD => 'LinkedTo',
+                BASE => undef,
+                TARGET => ($args{'TARGET'} || $args{'TICKET'}),
+                TYPE => $args{'TYPE'},
+                DESCRIPTION => $self->loc(
+                  "Tickets [_1] by [_2]", $self->loc($args{'TYPE'}), ($args{'TARGET'} || $args{'TICKET'})
+                 ),
+               );
+}
+
+
+# }}}
+
+# {{{ LimitLinkedFrom
+
+=head2 LimitLinkedFrom
+
+LimitLinkedFrom takes a paramhash with two fields: TYPE and BASE
+TYPE limits the sort of relationship we want to search on
+
+
+BASE is the id or URI of the BASE of the link
+(BASE used to be 'TICKET'.  'TICKET' is deprecated, but will be treated as BASE
+
+
+=cut
+
+sub LimitLinkedFrom {
+    my $self = shift;
+    my %args = ( BASE => undef,
+                TICKET => undef,
+                TYPE => undef,
+                @_);
+
+
+    $self->Limit( FIELD => 'LinkedTo',
+                 TARGET => undef,
+                 BASE => ($args{'BASE'} || $args{'TICKET'}),
+                 TYPE => $args{'TYPE'},
+                 DESCRIPTION => $self->loc(
+                  "Tickets [_1] [_2]", $self->loc($args{'TYPE'}), ($args{'BASE'} || $args{'TICKET'})
+                 ),
+               );
+}
+
+
+# }}}
+
+# {{{ LimitMemberOf
+sub LimitMemberOf {
+    my $self = shift;
+    my $ticket_id = shift;
+    $self->LimitLinkedTo ( TARGET=> "$ticket_id",
+                          TYPE => 'MemberOf',
+                         );
+
+}
+# }}}
+
+# {{{ LimitHasMember
+sub LimitHasMember {
+    my $self = shift;
+    my $ticket_id =shift;
+    $self->LimitLinkedFrom ( BASE => "$ticket_id",
+                            TYPE => 'HasMember',
+                            );
+
+}
+# }}}
+
+# {{{ LimitDependsOn
+
+sub LimitDependsOn {
+    my $self = shift;
+    my $ticket_id = shift;
+    $self->LimitLinkedTo ( TARGET => "$ticket_id",
+                           TYPE => 'DependsOn',
+                          );
+
+}
+
+# }}}
+
+# {{{ LimitDependedOnBy
+
+sub LimitDependedOnBy {
+    my $self = shift;
+    my $ticket_id = shift;
+    $self->LimitLinkedFrom (  BASE => "$ticket_id",
+                               TYPE => 'DependentOn',
+                            );
+
+}
+
+# }}}
+
+
+# {{{ LimitRefersTo
+
+sub LimitRefersTo {
+    my $self = shift;
+    my $ticket_id = shift;
+    $self->LimitLinkedTo ( TARGET => "$ticket_id",
+                           TYPE => 'RefersTo',
+                          );
+
+}
+
+# }}}
+
+# {{{ LimitReferredToBy
+
+sub LimitReferredToBy {
+    my $self = shift;
+    my $ticket_id = shift;
+    $self->LimitLinkedFrom (  BASE=> "$ticket_id",
+                               TYPE => 'ReferredTo',
+                            );
+
+}
+
+# }}}
+
+# }}}
+
+# {{{ limit based on ticket date attribtes
+
+# {{{ sub LimitDate
+
+=head2 LimitDate (FIELD => 'DateField', OPERATOR => $oper, VALUE => $ISODate)
+
+Takes a paramhash with the fields FIELD OPERATOR and VALUE.
+
+OPERATOR is one of > or <
+VALUE is a date and time in ISO format in GMT
+FIELD is one of Starts, Started, Told, Created, Resolved, LastUpdated
+
+There are also helper functions of the form LimitFIELD that eliminate
+the need to pass in a FIELD argument.
+
+=cut
+
+sub LimitDate {
+    my $self = shift;
+    my %args = (
+                  FIELD => undef,
+                 VALUE => undef,
+                 OPERATOR => undef,
+
+                  @_);
+
+    #Set the description if we didn't get handed it above
+    unless ($args{'DESCRIPTION'} ) {
+       $args{'DESCRIPTION'} = $args{'FIELD'} . " " .$args{'OPERATOR'}. " ". $args{'VALUE'} . " GMT"
+    }
+
+    $self->Limit (%args);
+
+}
+
+# }}}
+
+
+
+
+sub LimitCreated {
+    my $self = shift;
+    $self->LimitDate( FIELD => 'Created', @_);
+}
+sub LimitDue {
+    my $self = shift;
+    $self->LimitDate( FIELD => 'Due', @_);
+
+}
+sub LimitStarts {
+    my $self = shift;
+    $self->LimitDate( FIELD => 'Starts', @_);
+
+}
+sub LimitStarted {
+    my $self = shift;
+    $self->LimitDate( FIELD => 'Started', @_);
+}
+sub LimitResolved {
+    my $self = shift;
+    $self->LimitDate( FIELD => 'Resolved', @_);
+}
+sub LimitTold {
+    my $self = shift;
+    $self->LimitDate( FIELD => 'Told', @_);
+}
+sub LimitLastUpdated {
+    my $self = shift;
+    $self->LimitDate( FIELD => 'LastUpdated', @_);
+}
+#
+# {{{ sub LimitTransactionDate
+
+=head2 LimitTransactionDate (OPERATOR => $oper, VALUE => $ISODate)
+
+Takes a paramhash with the fields FIELD OPERATOR and VALUE.
+
+OPERATOR is one of > or <
+VALUE is a date and time in ISO format in GMT
+
+
+=cut
+
+sub LimitTransactionDate {
+    my $self = shift;
+    my %args = (
+                  FIELD => 'TransactionDate',
+                 VALUE => undef,
+                 OPERATOR => undef,
+
+                  @_);
+
+    #  <20021217042756.GK28744@pallas.fsck.com>
+    #    "Kill It" - Jesse.
+
+    #Set the description if we didn't get handed it above
+    unless ($args{'DESCRIPTION'} ) {
+       $args{'DESCRIPTION'} = $args{'FIELD'} . " " .$args{'OPERATOR'}. " ". $args{'VALUE'} . " GMT"
+    }
+
+    $self->Limit (%args);
+
+}
+
+# }}}
+
+# }}}
+
+# {{{ Limit based on custom fields
+# {{{ sub LimitCustomField
+
+=head2 LimitCustomField
+
+Takes a paramhash of key/value pairs with the following keys:
+
+=over 4
+
+=item KEYWORDSELECT - KeywordSelect id
+
+=item OPERATOR - (for KEYWORD only - KEYWORDSELECT operator is always `=')
+
+=item KEYWORD - Keyword id
+
+=back
+
+=cut
+
+sub LimitCustomField {
+    my $self = shift;
+    my %args = ( VALUE        => undef,
+                 CUSTOMFIELD   => undef,
+                 OPERATOR      => '=',
+                 DESCRIPTION   => undef,
+                 FIELD         => 'CustomFieldValue',
+                 QUOTEVALUE    => 1,
+                 @_ );
+
+    use RT::CustomFields;
+    my $CF = RT::CustomField->new( $self->CurrentUser );
+    $CF->Load( $args{CUSTOMFIELD} );
+
+    #If we are looking to compare with a null value.
+    if ( $args{'OPERATOR'} =~ /^is$/i ) {
+      $args{'DESCRIPTION'} ||= $self->loc("Custom field [_1] has no value.", $CF->Name);
+    }
+    elsif ( $args{'OPERATOR'} =~ /^is not$/i ) {
+      $args{'DESCRIPTION'} ||= $self->loc("Custom field [_1] has a value.", $CF->Name);
+    }
+
+    # if we're not looking to compare with a null value
+    else {
+        $args{'DESCRIPTION'} ||= $self->loc("Custom field [_1] [_2] [_3]",  $CF->Name , $args{OPERATOR} , $args{VALUE});
+    }
+
+#    my $index = $self->_NextIndex;
+#    %{ $self->{'TicketRestrictions'}{$index} } = %args;
+
+
+    my $q = "";
+    if ($CF->Queue) {
+      my $qo = new RT::Queue( $self->CurrentUser );
+      $qo->load( $CF->Queue );
+      $q = $qo->Name;
+    }
+
+    $self->Limit( VALUE => $args{VALUE},
+                 FIELD => "CF.".( $q
+                            ? $q . ".{" . $CF->Name . "}"
+                            : $CF->Name
+                          ),
+                 OPERATOR => $args{OPERATOR},
+                 CUSTOMFIELD => 1,
+               );
+
+
+    $self->{'RecalcTicketLimits'} = 1;
+  #  return ($index);
+}
+
+# }}}
+# }}}
+
+
+# {{{ sub _NextIndex
+
+=head2 _NextIndex
+
+Keep track of the counter for the array of restrictions
+
+=cut
+
+sub _NextIndex {
+    my $self = shift;
+    return ($self->{'restriction_index'}++);
+}
+# }}}
+
+# }}}
+
+# {{{ Core bits to make this a DBIx::SearchBuilder object
+
+# {{{ sub _Init
+sub _Init  {
+    my $self = shift;
+    $self->{'table'} = "Tickets";
+    $self->{'RecalcTicketLimits'} = 1;
+    $self->{'looking_at_effective_id'} = 0;
+    $self->{'looking_at_type'} = 0;
+    $self->{'restriction_index'} =1;
+    $self->{'primary_key'} = "id";
+    delete $self->{'items_array'};
+    delete $self->{'item_map'};
+    $self->SUPER::_Init(@_);
+
+    $self->_InitSQL;
+
+}
+# }}}
+
+# {{{ sub Count
+sub Count {
+  my $self = shift;
+  $self->_ProcessRestrictions() if ($self->{'RecalcTicketLimits'} == 1 );
+  return($self->SUPER::Count());
+}
+# }}}
+
+# {{{ sub CountAll
+sub CountAll {
+  my $self = shift;
+  $self->_ProcessRestrictions() if ($self->{'RecalcTicketLimits'} == 1 );
+  return($self->SUPER::CountAll());
+}
+# }}}
+
+
+# {{{ sub ItemsArrayRef
+
+=head2 ItemsArrayRef
+
+Returns a reference to the set of all items found in this search
+
+=cut
+
+sub ItemsArrayRef {
+    my $self = shift;
+    my @items;
+
+    unless ( $self->{'items_array'} ) {
+
+        my $placeholder = $self->_ItemsCounter;
+        $self->GotoFirstItem();
+        while ( my $item = $self->Next ) {
+            push ( @{ $self->{'items_array'} }, $item );
+        }
+        $self->GotoItem($placeholder);
+    }
+    return ( $self->{'items_array'} );
+}
+# }}}
+
+# {{{ sub Next
+sub Next {
+       my $self = shift;
+       
+       $self->_ProcessRestrictions() if ($self->{'RecalcTicketLimits'} == 1 );
+
+       my $Ticket = $self->SUPER::Next();
+       if ((defined($Ticket)) and (ref($Ticket))) {
+
+           #Make sure we _never_ show deleted tickets
+           #TODO we should be doing this in the where clause.
+           #but you can't do multiple clauses on the same field just yet :/
+
+           if ($Ticket->__Value('Status') eq 'deleted') {
+               return($self->Next());
+           }
+            # Since Ticket could be granted with more rights instead
+            # of being revoked, it's ok if queue rights allow
+            # ShowTicket.  It seems need another query, but we have
+            # rights cache in Principal::HasRight.
+           elsif ($Ticket->QueueObj->CurrentUserHasRight('ShowTicket') ||
+                   $Ticket->CurrentUserHasRight('ShowTicket')) {
+               return($Ticket);
+           }
+
+           #If the user doesn't have the right to show this ticket
+           else {      
+               return($self->Next());
+           }
+       }
+       #if there never was any ticket
+       else {
+               return(undef);
+       }       
+
+}
+# }}}
+
+# }}}
+
+# {{{ Deal with storing and restoring restrictions
+
+# {{{ sub LoadRestrictions
+
+=head2 LoadRestrictions
+
+LoadRestrictions takes a string which can fully populate the TicketRestrictons hash.
+TODO It is not yet implemented
+
+=cut
+
+# }}}
+
+# {{{ sub DescribeRestrictions
+
+=head2 DescribeRestrictions
+
+takes nothing.
+Returns a hash keyed by restriction id.
+Each element of the hash is currently a one element hash that contains DESCRIPTION which
+is a description of the purpose of that TicketRestriction
+
+=cut
+
+sub DescribeRestrictions  {
+    my $self = shift;
+
+    my ($row, %listing);
+
+    foreach $row (keys %{$self->{'TicketRestrictions'}}) {
+       $listing{$row} = $self->{'TicketRestrictions'}{$row}{'DESCRIPTION'};
+    }
+    return (%listing);
+}
+# }}}
+
+# {{{ sub RestrictionValues
+
+=head2 RestrictionValues FIELD
+
+Takes a restriction field and returns a list of values this field is restricted
+to.
+
+=cut
+
+sub RestrictionValues {
+    my $self = shift;
+    my $field = shift;
+    map $self->{'TicketRestrictions'}{$_}{'VALUE'},
+      grep {
+             $self->{'TicketRestrictions'}{$_}{'FIELD'} eq $field
+             && $self->{'TicketRestrictions'}{$_}{'OPERATOR'} eq "="
+           }
+        keys %{$self->{'TicketRestrictions'}};
+}
+
+# }}}
+
+# {{{ sub ClearRestrictions
+
+=head2 ClearRestrictions
+
+Removes all restrictions irretrievably
+
+=cut
+
+sub ClearRestrictions {
+    my $self = shift;
+    delete $self->{'TicketRestrictions'};
+    $self->{'looking_at_effective_id'} = 0;
+    $self->{'looking_at_type'} = 0;
+    $self->{'RecalcTicketLimits'} =1;
+}
+
+# }}}
+
+# {{{ sub DeleteRestriction
+
+=head2 DeleteRestriction
+
+Takes the row Id of a restriction (From DescribeRestrictions' output, for example.
+Removes that restriction from the session's limits.
+
+=cut
+
+
+sub DeleteRestriction {
+    my $self = shift;
+    my $row = shift;
+    delete $self->{'TicketRestrictions'}{$row};
+
+    $self->{'RecalcTicketLimits'} = 1;
+    #make the underlying easysearch object forget all its preconceptions
+}
+
+# }}}
+
+# {{{ sub _RestrictionsToClauses
+
+# Convert a set of oldstyle SB Restrictions to Clauses for RQL
+
+sub _RestrictionsToClauses {
+  my $self = shift;
+
+  my $row;
+  my %clause;
+  foreach $row (keys %{$self->{'TicketRestrictions'}}) {
+    my $restriction = $self->{'TicketRestrictions'}{$row};
+    #use Data::Dumper;
+    #print Dumper($restriction),"\n";
+
+      # We need to reimplement the subclause aggregation that SearchBuilder does.
+      # Default Subclause is ALIAS.FIELD, and default ALIAS is 'main',
+      # Then SB AND's the different Subclauses together.
+
+      # So, we want to group things into Subclauses, convert them to
+      # SQL, and then join them with the appropriate DefaultEA.
+      # Then join each subclause group with AND.
+
+    my $field = $restriction->{'FIELD'};
+    my $realfield = $field;    # CustomFields fake up a fieldname, so
+                                # we need to figure that out
+
+    # One special case
+    # Rewrite LinkedTo meta field to the real field
+    if ($field =~ /LinkedTo/) {
+      $realfield = $field = $restriction->{'TYPE'};
+    }
+
+    # Two special case
+    # CustomFields have a different real field
+    if ($field =~ /^CF\./) {
+      $realfield = "CF"
+    }
+
+    die "I don't know about $field yet"
+      unless (exists $FIELDS{$realfield} or $restriction->{CUSTOMFIELD});
+
+    my $type = $FIELDS{$realfield}->[0];
+    my $op   = $restriction->{'OPERATOR'};
+
+    my $value = ( grep { defined }
+                 map { $restriction->{$_} } qw(VALUE TICKET BASE TARGET))[0];
+
+    # this performs the moral equivalent of defined or/dor/C<//>,
+    # without the short circuiting.You need to use a 'defined or'
+    # type thing instead of just checking for truth values, because
+    # VALUE could be 0.(i.e. "false")
+
+    # You could also use this, but I find it less aesthetic:
+    # (although it does short circuit)
+    #( defined $restriction->{'VALUE'}? $restriction->{VALUE} :
+    # defined $restriction->{'TICKET'} ?
+    # $restriction->{TICKET} :
+    # defined $restriction->{'BASE'} ?
+    # $restriction->{BASE} :
+    # defined $restriction->{'TARGET'} ?
+    # $restriction->{TARGET} )
+
+    my $ea = $DefaultEA{$type};
+    if ( ref $ea ) {
+      die "Invalid operator $op for $field ($type)"
+       unless exists $ea->{$op};
+      $ea = $ea->{$op};
+    }
+    exists $clause{$realfield} or $clause{$realfield} = [];
+    # Escape Quotes
+    $field =~ s!(['"])!\\$1!g;
+    $value =~ s!(['"])!\\$1!g;
+    my $data = [ $ea, $type, $field, $op, $value ];
+
+    # here is where we store extra data, say if it's a keyword or
+    # something.  (I.e. "TYPE SPECIFIC STUFF")
+
+    #print Dumper($data);
+    push @{$clause{$realfield}}, $data;
+  }
+  return \%clause;
+}
+
+# }}}
+
+# {{{ sub _ProcessRestrictions
+
+=head2 _ProcessRestrictions PARAMHASH
+
+# The new _ProcessRestrictions is somewhat dependent on the SQL stuff,
+# but isn't quite generic enough to move into Tickets_Overlay_SQL.
+
+=cut
+
+sub _ProcessRestrictions {
+    my $self = shift;
+    
+    #Blow away ticket aliases since we'll need to regenerate them for
+    #a new search
+    delete $self->{'TicketAliases'};
+    delete $self->{'items_array'};                                                                                                                   
+    my $sql = $self->{_sql_query}; # Violating the _SQL namespace
+    if (!$sql||$self->{'RecalcTicketLimits'}) {
+      #  "Restrictions to Clauses Branch\n";
+      my $clauseRef = eval { $self->_RestrictionsToClauses; };
+      if ($@) {
+       $RT::Logger->error( "RestrictionsToClauses: " . $@ );
+       $self->FromSQL("");
+      } else {
+       $sql = $self->ClausesToSQL($clauseRef);
+       $self->FromSQL($sql);
+      }
+    }
+
+
+    $self->{'RecalcTicketLimits'} = 0;
+
+}
+
+=head2 _BuildItemMap
+
+    # Build up a map of first/last/next/prev items, so that we can display search nav quickly
+
+=cut
+
+sub _BuildItemMap {
+    my $self = shift;
+
+    my $items = $self->ItemsArrayRef;
+    my $prev = 0 ;
+
+    delete $self->{'item_map'};
+    if ($items->[0]) {
+    $self->{'item_map'}->{'first'} = $items->[0]->Id;
+    while (my $item = shift @$items ) {
+        my $id = $item->Id;
+        $self->{'item_map'}->{$id}->{'defined'} = 1;
+        $self->{'item_map'}->{$id}->{prev}  = $prev;
+        $self->{'item_map'}->{$id}->{next}  = $items->[0]->Id if ($items->[0]);
+        $prev = $id;
+    }
+    $self->{'item_map'}->{'last'} = $prev;
+    }
+} 
+
+
+=head2 ItemMap
+
+Returns an a map of all items found by this search. The map is of the form
+
+$ItemMap->{'first'} = first ticketid found
+$ItemMap->{'last'} = last ticketid found
+$ItemMap->{$id}->{prev} = the tikcet id found before $id
+$ItemMap->{$id}->{next} = the tikcet id found after $id
+
+=cut
+
+sub ItemMap {
+    my $self = shift;
+    $self->_BuildItemMap() unless ($self->{'item_map'});
+    return ($self->{'item_map'});
+}
+
+
+
+
+=cut
+
+}
+
+
+
+# }}}
+
+# }}}
+
+=head2 PrepForSerialization
+
+You don't want to serialize a big tickets object, as the {items} hash will be instantly invalid _and_ eat lots of space
+
+=cut
+
+
+sub PrepForSerialization {
+    my $self = shift;
+    delete $self->{'items'};
+    $self->RedoSearch();
+}
+
+1;
+
diff --git a/rt/lib/RT/Tickets_Overlay_SQL.pm b/rt/lib/RT/Tickets_Overlay_SQL.pm
new file mode 100644 (file)
index 0000000..d78a56d
--- /dev/null
@@ -0,0 +1,382 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+use strict;
+use warnings;
+
+# Import configuration data from the lexcial scope of __PACKAGE__ (or
+# at least where those two Subroutines are defined.)
+
+my %FIELDS = %{FIELDS()};
+my %dispatch = %{dispatch()};
+
+sub _InitSQL {
+  my $self = shift;
+
+  # How many of these do we actually still use?
+
+  # Private Member Variales (which should get cleaned)
+  $self->{'_sql_linksc'}        = 0;
+  $self->{'_sql_watchersc'}     = 0;
+  $self->{'_sql_keywordsc'}     = 0;
+  $self->{'_sql_subclause'}     = "a";
+  $self->{'_sql_first'}         = 0;
+  $self->{'_sql_opstack'}       = [''];
+  $self->{'_sql_transalias'}    = undef;
+  $self->{'_sql_trattachalias'} = undef;
+  $self->{'_sql_keywordalias'}  = undef;
+  $self->{'_sql_depth'}         = 0;
+  $self->{'_sql_localdepth'}    = 0;
+  $self->{'_sql_query'}         = '';
+  $self->{'_sql_looking_at'}    = {};
+
+}
+
+sub _SQLLimit {
+  # All SQL stuff goes into one SB subclause so we can deal with all
+  # the aggregation
+  my $this = shift;
+  $this->SUPER::Limit(@_,
+                      SUBCLAUSE => 'ticketsql');
+}
+
+# Helpers
+sub _OpenParen {
+  $_[0]->SUPER::_OpenParen( 'ticketsql' );
+}
+sub _CloseParen {
+  $_[0]->SUPER::_CloseParen( 'ticketsql' );
+}
+
+=head1 SQL Functions
+
+=cut
+
+sub _match {
+  # Case insensitive equality
+  my ($y,$x) = @_;
+  return 1 if $x =~ /^$y$/i;
+  #  return 1 if ((lc $x) eq (lc $y)); # Why isnt this equiv?
+  return 0;
+}
+
+=head2 Robert's Simple SQL Parser
+
+Documentation In Progress
+
+The Parser/Tokenizer is a relatively simple state machine that scans through a SQL WHERE clause type string extracting a token at a time (where a token is:
+
+  VALUE -> quoted string or number
+  AGGREGator -> AND or OR
+  KEYWORD -> quoted string or single word
+  OPerator -> =,!=,LIKE,etc..
+  PARENthesis -> open or close.
+
+And that stream of tokens is passed through the "machine" in order to build up a structure that looks like:
+
+       KEY OP VALUE
+  AND  KEY OP VALUE
+  OR   KEY OP VALUE
+
+That also deals with parenthesis for nesting.  (The parentheses are
+just handed off the SearchBuilder)
+
+=cut
+
+use Regexp::Common qw /delimited/;
+
+# States
+use constant VALUE => 1;
+use constant AGGREG => 2;
+use constant OP => 4;
+use constant PAREN => 8;
+use constant KEYWORD => 16;
+my @tokens = qw[VALUE AGGREG OP PAREN KEYWORD];
+
+my $re_aggreg = qr[(?i:AND|OR)];
+my $re_value  = qr[$RE{delimited}{-delim=>qq{\'\"}}|\d+];
+my $re_keyword = qr[$RE{delimited}{-delim=>qq{\'\"}}|(?:\{|\}|\w|\.)+];
+my $re_op     = qr[=|!=|>=|<=|>|<|(?i:IS NOT)|(?i:IS)|(?i:NOT LIKE)|(?i:LIKE)]; # long to short
+my $re_paren  = qr'\(|\)';
+
+sub _parser {
+  my ($self,$string) = @_;
+  my $want = KEYWORD | PAREN;
+  my $last = undef;
+
+  my $depth = 0;
+
+  my ($ea,$key,$op,$value) = ("","","","");
+
+  while ($string =~ /(
+                      $re_aggreg
+                      |$re_keyword
+                      |$re_value
+                      |$re_op
+                      |$re_paren
+                     )/igx ) {
+    my $val = $1;
+    my $current = 0;
+
+    # Highest priority is last
+    $current = OP      if _match($re_op,$val);
+    $current = VALUE   if _match($re_value,$val);
+    $current = KEYWORD if _match($re_keyword,$val) && ($want & KEYWORD);
+    $current = AGGREG  if _match($re_aggreg,$val);
+    $current = PAREN   if _match($re_paren,$val);
+
+    unless ($current && $want & $current) {
+      # Error
+      # FIXME: I will only print out the highest $want value
+      die "Error near ->$val<- expecting a ", $tokens[((log $want)/(log 2))], " in $string\n";
+    }
+
+    # State Machine:
+
+    # Parens are highest priority
+    if ($current & PAREN) {
+      if ($val eq "(") {
+        $depth++;
+        $self->_OpenParen;
+
+      } else {
+        $depth--;
+        $self->_CloseParen;
+      }
+
+      $want = KEYWORD | PAREN | AGGREG;
+    }
+    elsif ( $current & AGGREG ) {
+      $ea = $val;
+      $want = KEYWORD | PAREN;
+    }
+    elsif ( $current & KEYWORD ) {
+      $key = $val;
+      $want = OP;
+    }
+    elsif ( $current & OP ) {
+      $op = $val;
+      $want = VALUE;
+    }
+    elsif ( $current & VALUE ) {
+      $value = $val;
+
+      # Remove surrounding quotes from $key, $val
+      # (in future, simplify as for($key,$val) { action on $_ })
+      if ($key =~ /$RE{delimited}{-delim=>qq{\'\"}}/) {
+        substr($key,0,1) = "";
+        substr($key,-1,1) = "";
+      }
+      if ($val =~ /$RE{delimited}{-delim=>qq{\'\"}}/) {
+        substr($val,0,1) = "";
+        substr($val,-1,1) = "";
+      }
+      # Unescape escaped characters                                            
+      $key =~ s!\\(.)!$1!g;                                                    
+      $val =~ s!\\(.)!$1!g;     
+      #    print "$ea Key=[$key] op=[$op]  val=[$val]\n";
+
+
+   my $subkey;
+   if ($key =~ /^(.+?)\.(.+)$/) {
+     $key = $1;
+     $subkey = $2;
+   }
+
+      my $class;
+      my ($stdkey) = grep { /^$key$/i } (keys %FIELDS);
+      if ($stdkey && exists $FIELDS{$stdkey}) {
+        $class = $FIELDS{$key}->[0];
+        $key = $stdkey;
+      }
+   # no longer have a default, since CF's are now a real class, not fallthrough
+   # fixme: "default class" is not Generic.
+
+   die "Unknown field: $key" unless $class;
+
+      $self->{_sql_localdepth} = 0;
+      die "No such dispatch method: $class"
+        unless exists $dispatch{$class};
+      my $sub = $dispatch{$class} || die;;
+      $sub->(
+             $self,
+             $key,
+             $op,
+             $val,
+             SUBCLAUSE =>  "",  # don't need anymore
+             ENTRYAGGREGATOR => $ea || "",
+             SUBKEY => $subkey,
+            );
+
+      $self->{_sql_looking_at}{lc $key} = 1;
+
+      ($ea,$key,$op,$value) = ("","","","");
+
+      $want = PAREN | AGGREG;
+    } else {
+      die "I'm lost";
+    }
+
+    $last = $current;
+  } # while
+
+  die "Incomplete query"
+    unless (($want | PAREN) || ($want | KEYWORD));
+
+  die "Incomplete Query"
+    unless ($last && ($last | PAREN) || ($last || VALUE));
+
+  # This will never happen, because the parser will complain
+  die "Mismatched parentheses"
+    unless $depth == 0;
+
+}
+
+
+=head2 ClausesToSQL
+
+=cut
+
+sub ClausesToSQL {
+  my $self = shift;
+  my $clauses = shift;
+  my @sql;
+
+  for my $f (keys %{$clauses}) {
+    my $sql;
+    my $first = 1;
+
+    # Build SQL from the data hash
+     for my $data ( @{ $clauses->{$f} } ) {
+      $sql .= $data->[0] unless $first; $first=0;
+      $sql .= " '". $data->[2] . "' ";
+      $sql .= $data->[3] . " ";
+      $sql .= "'". $data->[4] . "' ";
+    }
+
+    push @sql, " ( " . $sql . " ) ";
+  }
+
+  return join("AND",@sql);
+}
+
+=head2 FromSQL
+
+Convert a RT-SQL string into a set of SearchBuilder restrictions.
+
+Returns (1, 'Status message') on success and (0, 'Error Message') on
+failure.
+
+=cut
+
+sub FromSQL {
+  my ($self,$query) = @_;
+
+  $self->CleanSlate;
+  $self->_InitSQL();
+  return (1,"No Query") unless $query;
+
+  $self->{_sql_query} = $query;
+  eval { $self->_parser( $query ); };
+  $RT::Logger->error( $@ ) if $@;
+  return(0,$@) if $@;
+
+  # We only want to look at EffectiveId's (mostly) for these searches.
+  unless (exists $self->{_sql_looking_at}{'effectiveid'}) {
+  $self->SUPER::Limit( FIELD           => 'EffectiveId',
+                     ENTRYAGGREGATOR => 'AND',
+                     OPERATOR        => '=',
+                     QUOTEVALUE      => 0,
+                     VALUE           => 'main.id'
+    );    #TODO, we shouldn't be hard #coding the tablename to main.
+    }
+  # FIXME: Need to bring this logic back in
+
+  #      if ($self->_isLimited && (! $self->{'looking_at_effective_id'})) {
+  #         $self->SUPER::Limit( FIELD => 'EffectiveId',
+  #               OPERATOR => '=',
+  #               QUOTEVALUE => 0,
+  #               VALUE => 'main.id');   #TODO, we shouldn't be hard coding the tablename to main.
+  #       }
+  # --- This is hardcoded above.  This comment block can probably go.
+  # Or, we need to reimplement the looking_at_effective_id toggle.
+
+  # Unless we've explicitly asked to look at a specific Type, we need
+  # to limit to it.
+  unless ($self->{looking_at_type}) {
+    $self->SUPER::Limit( FIELD => 'Type',
+                         OPERATOR => '=',
+                         VALUE => 'ticket');
+  }
+
+  # set SB's dirty flag
+  $self->{'must_redo_search'} = 1;
+  $self->{'RecalcTicketLimits'} = 0;                                           
+
+  return (1,"Good Query");
+
+}
+
+
+1;
+
+=pod
+
+=head2 Exceptions
+
+Most of the RT code does not use Exceptions (die/eval) but it is used
+in the TicketSQL code for simplicity and historical reasons.  Lest you
+be worried that the dies will trigger user visible errors, all are
+trapped via evals.
+
+99% of the dies fall in subroutines called via FromSQL and then parse.
+(This includes all of the _FooLimit routines in Tickets_Overlay.pm.)
+The other 1% or so are via _ProcessRestrictions.
+
+All dies are trapped by eval {}s, and will be logged at the 'error'
+log level.  The general failure mode is to not display any tickets.
+
+=head2 General Flow
+
+Legacy Layer:
+
+   Legacy LimitFoo routines build up a RestrictionsHash
+
+   _ProcessRestrictions converts the Restrictions to Clauses
+   ([key,op,val,rest]).
+
+   Clauses are converted to RT-SQL (TicketSQL)
+
+New RT-SQL Layer:
+
+   FromSQL calls the parser
+
+   The parser calls the _FooLimit routines to do DBIx::SearchBuilder
+   limits.
+
+And then the normal SearchBuilder/Ticket routines are used for
+display/navigation.
+
+=cut
+
index ee1f069..ca491a6 100755 (executable)
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Transaction.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# Copyright 1999-2001 Jesse Vincent <jesse@fsck.com>
-# Released under the terms of the GNU Public License
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
 
 =head1 NAME
 
-  RT::Transaction - RT\'s transaction object
+RT::Transaction
+
 
 =head1 SYNOPSIS
 
-  use RT::Transaction;
+=head1 DESCRIPTION
 
+=head1 METHODS
 
-=head1 DESCRIPTION
+=cut
 
+package RT::Transaction;
+use RT::Record; 
+use RT::Ticket;
 
-Each RT::Transaction describes an atomic change to a ticket object 
-or an update to an RT::Ticket object.
-It can have arbitrary MIME attachments.
 
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
+
+sub _Init {
+  my $self = shift; 
+
+  $self->Table('Transactions');
+  $self->SUPER::_Init(@_);
+}
 
-=head1 METHODS
 
-=begin testing
 
-ok(require RT::TestHarness);
-ok(require RT::Transaction);
 
-=end testing
+
+=item Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+  int(11) 'EffectiveTicket'.
+  int(11) 'Ticket'.
+  int(11) 'TimeTaken'.
+  varchar(20) 'Type'.
+  varchar(40) 'Field'.
+  varchar(255) 'OldValue'.
+  varchar(255) 'NewValue'.
+  varchar(100) 'Data'.
 
 =cut
 
-package RT::Transaction;
 
-use RT::Record;
-@ISA= qw(RT::Record);
-    
-use RT::Attachments;
 
-# {{{ sub _Init 
-sub _Init  {
+
+sub Create {
     my $self = shift;
-  $self->{'table'} = "Transactions";
-  return ($self->SUPER::_Init(@_));
+    my %args = ( 
+                EffectiveTicket => '0',
+                Ticket => '0',
+                TimeTaken => '0',
+                Type => '',
+                Field => '',
+                OldValue => '',
+                NewValue => '',
+                Data => '',
+
+                 @_);
+    $self->SUPER::Create(
+                         EffectiveTicket => $args{'EffectiveTicket'},
+                         Ticket => $args{'Ticket'},
+                         TimeTaken => $args{'TimeTaken'},
+                         Type => $args{'Type'},
+                         Field => $args{'Field'},
+                         OldValue => $args{'OldValue'},
+                         NewValue => $args{'NewValue'},
+                         Data => $args{'Data'},
+);
 
 }
-# }}}
 
-# {{{ sub Create 
 
-=head2 Create
 
-Create a new transaction.
+=item id
 
-This routine should _never_ be called anything other Than RT::Ticket. It should not be called 
-from client code. Ever. Not ever.  If you do this, we will hunt you down. and break your kneecaps.
-Then the unpleasant stuff will start.
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
 
-TODO: Document what gets passed to this
 
 =cut
 
-sub Create  {
-    my $self = shift;
-    my %args = ( id => undef,
-                TimeTaken => 0,
-                Ticket => 0 ,
-                Type => 'undefined',
-                Data => '',
-                Field => undef,
-                OldValue => undef,
-                NewValue => undef,
-                MIMEObj => undef,
-                ActivateScrips => 1,
-                @_
-              );
-    
-    #if we didn't specify a ticket, we need to bail
-    unless ( $args{'Ticket'} ) {
-       return(0, "RT::Transaction->Create couldn't, as you didn't specify a ticket id");
-    }
-        
-    #lets create our transaction
-    my $id = $self->SUPER::Create(Ticket => $args{'Ticket'},
-                                 TimeTaken => $args{'TimeTaken'},
-                                 Type => $args{'Type'},
-                                 Data => $args{'Data'},
-                                 Field => $args{'Field'},
-                                 OldValue => $args{'OldValue'},
-                                 NewValue => $args{'NewValue'},
-                                 Created => $args{'Created'}
-                                );
-    $self->Load($id);
-    $self->_Attach($args{'MIMEObj'})
-      if defined $args{'MIMEObj'};
-    
-    #Provide a way to turn off scrips if we need to
-    if ($args{'ActivateScrips'}) {
-
-       #We're really going to need a non-acled ticket for the scrips to work
-       my $TicketAsSystem = RT::Ticket->new($RT::SystemUser);
-       $TicketAsSystem->Load($args{'Ticket'}) || 
-         $RT::Logger->err("$self couldn't load ticket $args{'Ticket'}\n");
-       
-       my $TransAsSystem = RT::Transaction->new($RT::SystemUser);
-       $TransAsSystem->Load($self->id) ||
-         $RT::Logger->err("$self couldn't load a copy of itself as superuser\n");
-       
-       # {{{ Deal with Scrips
-    
-    #Load a scripscopes object
-    use RT::Scrips;
-    my $PossibleScrips = RT::Scrips->new($RT::SystemUser);
-    
-    $PossibleScrips->LimitToQueue($TicketAsSystem->QueueObj->Id); #Limit it to  $Ticket->QueueObj->Id
-    $PossibleScrips->LimitToGlobal(); # or to "global"
-    my $ConditionsAlias = $PossibleScrips->NewAlias('ScripConditions');
-    
-    $PossibleScrips->Join(ALIAS1 => 'main',  FIELD1 => 'ScripCondition',
-                         ALIAS2 => $ConditionsAlias, FIELD2=> 'id');
-    
-    
-    #We only want things where the scrip applies to this sort of transaction
-    $PossibleScrips->Limit(ALIAS=> $ConditionsAlias,
-                          FIELD=>'ApplicableTransTypes',
-                          OPERATOR => 'LIKE',
-                          VALUE => $args{'Type'},
-                          ENTRYAGGREGATOR => 'OR',
-                         );
-    
-    # Or where the scrip applies to any transaction
-    $PossibleScrips->Limit(ALIAS=> $ConditionsAlias,
-                          FIELD=>'ApplicableTransTypes',
-                          OPERATOR => 'LIKE',
-                          VALUE => "Any",
-                          ENTRYAGGREGATOR => 'OR',
-                         );                        
-    
-    #Iterate through each script and check it's applicability.
-    
-    while (my $Scrip = $PossibleScrips->Next()) {
-      
-      #TODO: properly deal with errors raised in this scrip loop
-       
-      #$RT::Logger->debug("$self now dealing with ".$Scrip->Id. "\n");      
-       eval {
-         local $SIG{__DIE__} = sub { $RT::Logger->error($_[0])};
-         
-         
-         #Load the scrip's Condition object
-         $Scrip->ConditionObj->LoadCondition(TicketObj => $TicketAsSystem, 
-                                             TransactionObj => $TransAsSystem);          
-         
-         
-         #If it's applicable, prepare and commit it
-         
-       $RT::Logger->debug ("$self: Checking condition ".$Scrip->ConditionObj->Name. "...\n");
-         
-         if ( $Scrip->IsApplicable() ) {
-             
-               $RT::Logger->debug ("$self: Matches condition ".$Scrip->ConditionObj->Name. "...\n");
-             #TODO: handle some errors here
-             
-             $Scrip->ActionObj->LoadAction(TicketObj => $TicketAsSystem, 
-                                          TransactionObj => $TransAsSystem);
-         
-             
-             if ($Scrip->Prepare()) {
-                 $RT::Logger->debug("$self: Prepared " .
-                                  $Scrip->ActionObj->Name . "\n");
-                 if ($Scrip->Commit()) {
-                       $RT::Logger->debug("$self: Committed " .
-                                          $Scrip->ActionObj->Name . "\n");
-                 }
-                 else {
-                       $RT::Logger->info("$self: Failed to commit ".
-                                          $Scrip->ActionObj->Name . "\n");
-                 } 
-             }
-             else {
-                 $RT::Logger->info("$self: Failed to prepare " .
-                                    $Scrip->ActionObj->Name . "\n");
-             }
-
-             #We're done with it. lets clean up.
-             #TODO: something else isn't letting these get garbage collected. check em out.
-             $Scrip->ActionObj->DESTROY();
-             $Scrip->ConditionObj->DESTROY;
-         }
-         
-         
-       else {
-           $RT::Logger->debug ("$self: Doesn't match condition ".$Scrip->ConditionObj->Name. "...\n");
-
-           # TODO: why doesn't this catch all the ScripObjs we create. 
-           # and why do we explictly need to destroy them?
-           $Scrip->ConditionObj->DESTROY;
-       }
-      }        
-    }
-
-    # }}}
-       
-    }
-
-    return ($id, "Transaction Created");
-}
 
-# }}}
+=item EffectiveTicket
 
-# {{{ sub Delete
+Returns the current value of EffectiveTicket. 
+(In the database, EffectiveTicket is stored as int(11).)
 
-sub Delete {
-    my $self = shift;
-    return (0, 'Deleting this object could break referential integrity');
-}
 
-# }}}
 
-# {{{ Routines dealing with Attachments
+=item SetEffectiveTicket VALUE
 
-# {{{ sub Message 
 
-=head2 Message
+Set EffectiveTicket to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, EffectiveTicket will be stored as a int(11).)
 
-  Returns the RT::Attachments Object which contains the "top-level" object
-  attachment for this transaction
 
 =cut
 
-sub Message  {
 
-    my $self = shift;
-    
-    if (!defined ($self->{'message'}) ){
-       
-       $self->{'message'} = new RT::Attachments($self->CurrentUser);
-       $self->{'message'}->Limit(FIELD => 'TransactionId',
-                                 VALUE => $self->Id);
-       
-       $self->{'message'}->ChildrenOf(0);
-    } 
-    return($self->{'message'});
-}
-# }}}
+=item Ticket
+
+Returns the current value of Ticket. 
+(In the database, Ticket is stored as int(11).)
+
 
-# {{{ sub Content
 
-=head2 Content PARAMHASH
+=item SetTicket VALUE
 
-If this transaction has attached mime objects, returns the first text/ part.
-Otherwise, returns undef.
 
-Takes a paramhash.  If the $args{'Quote'} parameter is set, wraps this message 
-at $args{'Wrap'}.  $args{'Wrap'} defaults to 70.
+Set Ticket to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Ticket will be stored as a int(11).)
 
 
 =cut
 
-sub Content {
-    my $self = shift;
-    my %args = ( Quote => 0,
-                Wrap => 70,
-                @_ );
-
-    my $content = undef;
-
-    # If we don\'t have any content, return undef now.
-    unless ($self->Message->First) {
-       return (undef);
-    }  
-    
-    # Get the set of toplevel attachments to this transaction.
-    my $MIMEObj = $self->Message->First();
-    
-    # If it's a message or a plain part, just return the
-    # body. 
-    if ($MIMEObj->ContentType() =~ '^(text|message)(/|$)') {
-       $content = $MIMEObj->Content();
-    }
-    
-    # If it's a multipart object, first try returning the first 
-    # text/plain part. 
-    
-    elsif ($MIMEObj->ContentType() =~ '^multipart/') {
-       my $plain_parts = $MIMEObj->Children();
-       $plain_parts->ContentType(VALUE => 'text/plain');
-       
-       # If we actully found a part, return its content
-       if ($plain_parts->First && 
-        $plain_parts->First->Content ne '') {
-           $content = $plain_parts->First->Content;            
-       }       
-       
-       # If that fails, return the  first text/ or message/ part 
-       # which has some content.
-    
-       else {
-           my $all_parts = $MIMEObj->Children();
-           while (($content == undef) && 
-                  (my $part = $all_parts->Next)) {
-               if (($part->ContentType() =~ '^(text|message)(/|$)') and
-                   ($part->Content())) {
-                   $content = $part->Content;
-               }       
-           }
-       }       
-
-    }
-    # If all else fails, return a message that we couldn't find
-    # any content
-    else { 
-        $content = 'This transaction appears to have no content';
-    }  
-
-    if ($args{'Quote'}) {
-       # Remove quoted signature.
-       $content =~ s/\n-- \n(.*)$//s;
-
-       # What's the longest line like?
-       foreach (split (/\n/,$content)) {
-           $max=length if ( length > $max);
-       }
-
-       if ($max>76) {
-           require Text::Wrapper;
-           my $wrapper=new Text::Wrapper
-               (
-                columns => $args{'Wrap'}, 
-                body_start => ($max > 70*3 ? '   ' : ''),
-                par_start => ''
-                );
-           $content=$wrapper->wrap($content);
-       }
-
-       $content =~ s/^/> /gm;
-       $content = '[' . $self->CreatorObj->Name() . ' - ' . $self->CreatedAsString()
-                   . "]:\n\n"
-               . $content . "\n\n";
-
-    }
-
-    return ($content); 
-}
-# }}}
 
-# {{{ sub Subject
+=item TicketObj
+
+Returns the Ticket Object which has the id returned by Ticket
 
-=head2 Subject
 
-If this transaction has attached mime objects, returns the first one's subject
-Otherwise, returns null
-  
 =cut
 
-sub Subject {
-    my $self = shift;
-    if ($self->Message->First) {
-       return ($self->Message->First->Subject);
-    }
-    else {
-       return (undef);
-    }
+sub TicketObj {
+       my $self = shift;
+       my $Ticket =  RT::Ticket->new($self->CurrentUser);
+       $Ticket->Load($self->__Value('Ticket'));
+       return($Ticket);
 }
-# }}}
 
-# {{{ sub Attachments 
+=item TimeTaken
+
+Returns the current value of TimeTaken. 
+(In the database, TimeTaken is stored as int(11).)
+
 
-=head2 Attachments
 
-  Returns all the RT::Attachment objects which are attached
-to this transaction. Takes an optional parameter, which is
-a ContentType that Attachments should be restricted to.
+=item SetTimeTaken VALUE
+
+
+Set TimeTaken to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, TimeTaken will be stored as a int(11).)
+
 
 =cut
 
 
-sub Attachments  {
-    my $self = shift;
-    my $Types = '';
-    $Types = shift if (@_);
-
-    my $Attachments = new RT::Attachments($self->CurrentUser);
-    
-    #If it's a comment, return an empty object if they don't have the right to see it
-    if ($self->Type eq 'Comment') {
-       unless ($self->CurrentUserHasRight('ShowTicketComments')) {
-           return ($Attachments);
-       }
-    }  
-    #if they ain't got rights to see, return an empty object
-    else {
-       unless ($self->CurrentUserHasRight('ShowTicket')) {
-           return ($Attachments);
-       }
-    }
-    
-    $Attachments->Limit(FIELD => 'TransactionId',
-                       VALUE => $self->Id);
-
-    # Get the attachments in the order they're put into
-    # the database.  Arguably, we should be returning a tree
-    # of attachments, not a set...but no current app seems to need
-    # it. 
-
-    $Attachments->OrderBy(ALIAS => 'main', 
-                         FIELD => 'Id',
-                         ORDER => 'asc');
-
-    if ($Types) {
-       $Attachments->ContentType( VALUE => "$Types",
-                                  OPERATOR => "LIKE");
-    }
-    
-    
-    return($Attachments);
-    
-}
+=item Type
 
-# }}}
+Returns the current value of Type. 
+(In the database, Type is stored as varchar(20).)
 
-# {{{ sub _Attach 
 
-=head2 _Attach
 
-A private method used to attach a mime object to this transaction.
+=item SetType VALUE
+
+
+Set Type to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Type will be stored as a varchar(20).)
+
 
 =cut
 
-sub _Attach  {
-    my $self = shift;
-    my $MIMEObject = shift;
-    
-    if (!defined($MIMEObject)) {
-       $RT::Logger->error("$self _Attach: We can't attach a mime object if you don't give us one.\n");
-       return(0, "$self: no attachment specified");
-    }
-    
-  
-    use RT::Attachment;
-    my $Attachment = new RT::Attachment ($self->CurrentUser);
-    $Attachment->Create(TransactionId => $self->Id,
-                       Attachment => $MIMEObject);
-    return ($Attachment, "Attachment created");
-    
-}
 
-# }}}
+=item Field
 
-# }}}
+Returns the current value of Field. 
+(In the database, Field is stored as varchar(40).)
 
-# {{{ Routines dealing with Transaction Attributes
 
-# {{{ sub TicketObj
 
-=head2 TicketObj
+=item SetField VALUE
+
+
+Set Field to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Field will be stored as a varchar(40).)
 
-Returns this transaction's ticket object.
 
 =cut
 
-sub TicketObj {
-    my $self = shift;
-    if (! exists $self->{'TicketObj'}) {
-       $self->{'TicketObj'} = new RT::Ticket($self->CurrentUser);
-       $self->{'TicketObj'}->Load($self->Ticket);
-    }
-    
-    return $self->{'TicketObj'};
-}
-# }}}
 
-# {{{ sub Description 
+=item OldValue
+
+Returns the current value of OldValue. 
+(In the database, OldValue is stored as varchar(255).)
+
+
+
+=item SetOldValue VALUE
+
 
-=head2 Description
+Set OldValue to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, OldValue will be stored as a varchar(255).)
 
-Returns a text string which describes this transaction
 
 =cut
 
 
-sub Description  {
-    my $self = shift;
+=item NewValue
+
+Returns the current value of NewValue. 
+(In the database, NewValue is stored as varchar(255).)
 
-    #Check those ACLs
-    #If it's a comment, we need to be extra special careful
-    if ($self->__Value('Type') eq 'Comment') {
-       unless ($self->CurrentUserHasRight('ShowTicketComments')) {
-           return (0, "Permission Denied");
-       }
-    }  
-
-    #if they ain't got rights to see, don't let em
-    else {
-       unless ($self->CurrentUserHasRight('ShowTicket')) {
-           return (0, "Permission Denied");
-       }
-    }
-
-    if (!defined($self->Type)) {
-       return("No transaction type specified");
-    }
-    
-    return ($self->BriefDescription . " by " . $self->CreatorObj->Name);
-}
 
-# }}}
 
-# {{{ sub BriefDescription 
+=item SetNewValue VALUE
 
-=head2 BriefDescription
 
-Returns a text string which briefly describes this transaction
+Set NewValue to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, NewValue will be stored as a varchar(255).)
+
 
 =cut
 
 
-sub BriefDescription  {
-    my $self = shift;
+=item Data
 
-    #Check those ACLs
-    #If it's a comment, we need to be extra special careful
-    if ($self->__Value('Type') eq 'Comment') {
-       unless ($self->CurrentUserHasRight('ShowTicketComments')) {
-           return (0, "Permission Denied");
-       }
-    }  
-
-    #if they ain't got rights to see, don't let em
-    else {
-       unless ($self->CurrentUserHasRight('ShowTicket')) {
-           return (0, "Permission Denied");
-       }
-    }
-
-    if (!defined($self->Type)) {
-       return("No transaction type specified");
-    }
-    
-    if ($self->Type eq 'Create'){
-       return("Ticket created");
-    }
-    elsif ($self->Type =~ /Status/) {
-       if ($self->Field eq 'Status') {
-           if ($self->NewValue eq 'dead') {
-               return ("Ticket killed");
-      }
-           else {
-               return( "Status changed from ".  $self->OldValue . 
-                       " to ". $self->NewValue);
-
-           }
-       }
-       # Generic:
-       return ($self->Field." changed from ".($self->OldValue||"(empty value)").
-         " to ".$self->NewValue );
-      }
-    
-    if ($self->Type eq 'Correspond')    {
-       return("Correspondence added");
-    }
-    
-    elsif ($self->Type eq 'Comment')  {
-       return( "Comments added");
-    }
-    
-    elsif ($self->Type eq 'Keyword') {
-
-       my $field = 'Keyword';
-
-       if ($self->Field) {
-           my $keywordsel = new RT::KeywordSelect ($self->CurrentUser);
-           $keywordsel->Load($self->Field);
-           $field = $keywordsel->Name();
-       }
-
-       if ($self->OldValue eq '') {
-           return ($field." ".$self->NewValue." added");
-       }
-       elsif ($self->NewValue eq '') {
-           return ($field." ".$self->OldValue." deleted"); 
-           
-       }
-       else {
-           return ($field." ".$self->OldValue . " changed to ". 
-                    $self->NewValue);
-       }       
-    }
-    
-    elsif ($self->Type eq 'Untake'){
-           return( "Untaken");
-       }
-    
-    elsif ($self->Type eq "Take") {
-       return( "Taken");
-    }
-    
-    elsif ($self->Type eq "Force") {
-        my $Old = RT::User->new($self->CurrentUser);
-        $Old->Load($self->OldValue);
-        my $New = RT::User->new($self->CurrentUser);
-        $New->Load($self->NewValue);
-       return "Owner forcibly changed from ".$Old->Name . " to ". $New->Name;
-    }
-    elsif ($self->Type eq "Steal") {
-       my $Old = RT::User->new($self->CurrentUser);
-       $Old->Load($self->OldValue);
-       return "Stolen from ".$Old->Name;
-    }
-    
-    elsif ($self->Type eq "Give") {
-       my $New = RT::User->new($self->CurrentUser);
-       $New->Load($self->NewValue);
-       return( "Given to ".$New->Name);
-    }
-    
-    elsif ($self->Type eq 'AddWatcher'){
-       return( $self->Field." ". $self->NewValue ." added");
-    }
-    
-    elsif ($self->Type eq 'DelWatcher'){
-       return( $self->Field." ".$self->OldValue ." deleted");
-    }
-    
-    elsif ($self->Type eq 'Subject') {
-       return( "Subject changed to ".$self->Data);
-    }
-    elsif ($self->Type eq 'Told') {
-       return( "User notified");
-    }
-    
-    elsif ($self->Type eq 'AddLink') {
-       return ($self->Data);
-    }
-    elsif ($self->Type eq 'DeleteLink') {
-       return ($self->Data);
-    }
-    elsif ($self->Type eq 'Set') {
-       if ($self->Field eq 'Queue') {
-           my $q1 = new RT::Queue($self->CurrentUser);
-           $q1->Load($self->OldValue);
-           my $q2 = new RT::Queue($self->CurrentUser);
-           $q2->Load($self->NewValue);
-           return ($self->Field . " changed from " . $q1->Name . " to ".
-                   $q2->Name);
-       }
-
-        # Write the date/time change at local time:                    
-    elsif ($self->Field =~  /Due|Starts|Started|Told/) {           
-        my $t1 = new RT::Date($self->CurrentUser);                 
-        $t1->Set(Format => 'ISO', Value => $self->NewValue);       
-        my $t2 = new RT::Date($self->CurrentUser);                 
-        $t2->Set(Format => 'ISO', Value => $self->OldValue);       
-        return ($self->Field . " changed from " . $t2->AsString .  
-                    " to ".$t1->AsString);      
-    }                
-       else {
-           return ($self->Field . " changed from " . $self->OldValue . 
-                   " to ".$self->NewValue);
-       }       
-    }
-    elsif ($self->Type eq 'PurgeTransaction') {
-       return ("Transaction ".$self->Data. " purged");
-    }
-    else {
-       return ("Default: ". $self->Type ."/". $self->Field . 
-               " changed from " . $self->OldValue . 
-               " to ".$self->NewValue);
-       
-    }
-}
+Returns the current value of Data. 
+(In the database, Data is stored as varchar(100).)
 
-# }}}
 
-# {{{ Utility methods
 
-# {{{ sub IsInbound
+=item SetData VALUE
 
-=head2 IsInbound
 
-Returns true if the creator of the transaction is a requestor of the ticket.
-Returns false otherwise
+Set Data to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Data will be stored as a varchar(100).)
 
-=cut
 
-sub IsInbound {
-    my $self=shift;
-    return ($self->TicketObj->IsRequestor($self->CreatorObj));
-}
+=cut
 
-# }}}
-
-# }}}
-
-# {{{ sub _Accessible 
-
-sub _Accessible  {
-  my $self = shift;
-  my %Cols = (
-             TimeTaken => 'read',
-             Ticket => 'read/public',
-             Type=> 'read',
-             Field => 'read',
-             Data => 'read',
-             NewValue => 'read',
-             OldValue => 'read',
-             Creator => 'read/auto',
-             Created => 'read/auto',
-            );
-  return $self->SUPER::_Accessible(@_, %Cols);
-}
 
-# }}}
+=item Creator
 
-# }}}
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
 
-# {{{ sub _Set
 
-sub _Set {
-    my $self = shift;
-    return(0, 'Transactions are immutable');
-}
+=cut
 
-# }}}
 
-# {{{ sub _Value 
+=item Created
 
-=head2 _Value
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
 
-Takes the name of a table column.
-Returns its value as a string, if the user passes an ACL check
 
 =cut
 
-sub _Value  {
 
-    my $self = shift;
-    my $field = shift;
-    
-    
-    #if the field is public, return it.
-    if ($self->_Accessible($field, 'public')) {
-       return($self->__Value($field));
-       
-    }
-    #If it's a comment, we need to be extra special careful
-    if ($self->__Value('Type') eq 'Comment') {
-       unless ($self->CurrentUserHasRight('ShowTicketComments')) {
-           return (undef);
-       }
-    }  
-    #if they ain't got rights to see, don't let em
-    else {
-       unless ($self->CurrentUserHasRight('ShowTicket')) {
-           return (undef);
-       }
-    }  
-    
-    return($self->__Value($field));
-    
-}
 
-# }}}
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        EffectiveTicket => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Ticket => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        TimeTaken => 
+               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        Type => 
+               {read => 1, write => 1, type => 'varchar(20)', default => ''},
+        Field => 
+               {read => 1, write => 1, type => 'varchar(40)', default => ''},
+        OldValue => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        NewValue => 
+               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+        Data => 
+               {read => 1, write => 1, type => 'varchar(100)', default => ''},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
 
-# {{{ sub CurrentUserHasRight
+ }
+};
 
-=head2 CurrentUserHasRight RIGHT
 
-Calls $self->CurrentUser->HasQueueRight for the right passed in here.
-passed in here.
+        eval "require RT::Transaction_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Transaction_Overlay.pm}) {
+            die $@;
+        };
 
-=cut
+        eval "require RT::Transaction_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Transaction_Vendor.pm}) {
+            die $@;
+        };
 
-sub CurrentUserHasRight {
-    my $self = shift;
-    my $right = shift;
-    return ($self->CurrentUser->HasQueueRight(Right => "$right", 
-                                              TicketObj => $self->TicketObj));            
-}
+        eval "require RT::Transaction_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Transaction_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::Transaction_Overlay, RT::Transaction_Vendor, RT::Transaction_Local
+
+=cut
 
-# }}}
 
 1;
diff --git a/rt/lib/RT/Transaction_Overlay.pm b/rt/lib/RT/Transaction_Overlay.pm
new file mode 100644 (file)
index 0000000..54bb326
--- /dev/null
@@ -0,0 +1,817 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Transaction - RT\'s transaction object
+
+=head1 SYNOPSIS
+
+  use RT::Transaction;
+
+
+=head1 DESCRIPTION
+
+
+Each RT::Transaction describes an atomic change to a ticket object 
+or an update to an RT::Ticket object.
+It can have arbitrary MIME attachments.
+
+
+=head1 METHODS
+
+=begin testing
+
+ok(require RT::Transaction);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+use RT::Attachments;
+
+# {{{ sub Create 
+
+=head2 Create
+
+Create a new transaction.
+
+This routine should _never_ be called anything other Than RT::Ticket. It should not be called 
+from client code. Ever. Not ever.  If you do this, we will hunt you down. and break your kneecaps.
+Then the unpleasant stuff will start.
+
+TODO: Document what gets passed to this
+
+=cut
+
+sub Create {
+    my $self = shift;
+    my %args = (
+        id             => undef,
+        TimeTaken      => 0,
+        Ticket         => 0,
+        Type           => 'undefined',
+        Data           => '',
+        Field          => undef,
+        OldValue       => undef,
+        NewValue       => undef,
+        MIMEObj        => undef,
+        ActivateScrips => 1,
+        @_
+    );
+
+    #if we didn't specify a ticket, we need to bail
+    unless ( $args{'Ticket'} ) {
+        return ( 0, $self->loc( "Transaction->Create couldn't, as you didn't specify a ticket id"));
+    }
+
+
+
+    #lets create our transaction
+    my %params = (Ticket    => $args{'Ticket'},
+        Type      => $args{'Type'},
+        Data      => $args{'Data'},
+        Field     => $args{'Field'},
+        OldValue  => $args{'OldValue'},
+        NewValue  => $args{'NewValue'},
+        Created   => $args{'Created'}
+    );
+
+    # Parameters passed in during an import that we probably don't want to touch, otherwise
+    foreach my $attr qw(id Creator Created LastUpdated TimeTaken LastUpdatedBy) {
+        $params{$attr} = $args{$attr} if ($args{$attr});
+    }
+    my $id = $self->SUPER::Create(%params);
+    $self->Load($id);
+    $self->_Attach( $args{'MIMEObj'} )
+      if defined $args{'MIMEObj'};
+
+    #Provide a way to turn off scrips if we need to
+    if ( $args{'ActivateScrips'} ) {
+
+        #We're really going to need a non-acled ticket for the scrips to work
+        my $TicketAsSystem = RT::Ticket->new($RT::SystemUser);
+        $TicketAsSystem->Load( $args{'Ticket'} )
+          || $RT::Logger->err("$self couldn't load ticket $args{'Ticket'}\n");
+
+        my $TransAsSystem = RT::Transaction->new($RT::SystemUser);
+        $TransAsSystem->Load( $self->id )
+          || $RT::Logger->err(
+            "$self couldn't load a copy of itself as superuser\n"); 
+        # {{{ Deal with Scrips
+
+        use RT::Scrips;
+        my $PossibleScrips = RT::Scrips->new($RT::SystemUser);
+
+        $PossibleScrips->LimitToQueue( $TicketAsSystem->QueueObj->Id )
+          ;                                  #Limit it to  $Ticket->QueueObj->Id
+        $PossibleScrips->LimitToGlobal()
+           unless $TicketAsSystem->QueueObj->Disabled;    # or to "global"
+
+
+        $PossibleScrips->Limit(FIELD => "Stage", VALUE => "TransactionCreate");
+
+
+        my $ConditionsAlias = $PossibleScrips->NewAlias('ScripConditions');
+
+        $PossibleScrips->Join(
+            ALIAS1 => 'main',
+            FIELD1 => 'ScripCondition',
+            ALIAS2 => $ConditionsAlias,
+            FIELD2 => 'id'
+        );
+
+        #We only want things where the scrip applies to this sort of transaction
+        $PossibleScrips->Limit(
+            ALIAS           => $ConditionsAlias,
+            FIELD           => 'ApplicableTransTypes',
+            OPERATOR        => 'LIKE',
+            VALUE           => $args{'Type'},
+            ENTRYAGGREGATOR => 'OR',
+        );
+
+        # Or where the scrip applies to any transaction
+        $PossibleScrips->Limit(
+            ALIAS           => $ConditionsAlias,
+            FIELD           => 'ApplicableTransTypes',
+            OPERATOR        => 'LIKE',
+            VALUE           => "Any",
+            ENTRYAGGREGATOR => 'OR',
+        );
+
+        #Iterate through each script and check it's applicability.
+
+        while ( my $Scrip = $PossibleScrips->Next() ) {
+            $Scrip->Apply (TicketObj => $TicketAsSystem,
+                           TransactionObj => $TransAsSystem);
+        }
+
+        # }}}
+
+    }
+
+    return ( $id, $self->loc("Transaction Created") );
+}
+
+# }}}
+
+# {{{ sub Delete
+
+sub Delete {
+    my $self = shift;
+    return ( 0,
+        $self->loc('Deleting this object could break referential integrity') );
+}
+
+# }}}
+
+# {{{ Routines dealing with Attachments
+
+# {{{ sub Message 
+
+=head2 Message
+
+  Returns the RT::Attachments Object which contains the "top-level"object
+  attachment for this transaction
+
+=cut
+
+sub Message {
+
+    my $self = shift;
+    
+    if ( !defined( $self->{'message'} ) ) {
+
+        $self->{'message'} = new RT::Attachments( $self->CurrentUser );
+        $self->{'message'}->Limit(
+            FIELD => 'TransactionId',
+            VALUE => $self->Id
+        );
+
+        $self->{'message'}->ChildrenOf(0);
+    }
+    return ( $self->{'message'} );
+}
+
+# }}}
+
+# {{{ sub Content
+
+=head2 Content PARAMHASH
+
+If this transaction has attached mime objects, returns the first text/plain part.
+Otherwise, returns undef.
+
+Takes a paramhash.  If the $args{'Quote'} parameter is set, wraps this message 
+at $args{'Wrap'}.  $args{'Wrap'} defaults to 70.
+
+
+=cut
+
+sub Content {
+    my $self = shift;
+    my %args = (
+        Quote => 0,
+        Wrap  => 70,
+        @_
+    );
+
+    my $content;
+    my $content_obj = $self->ContentObj;
+    if ($content_obj) {
+        $content = $content_obj->Content;
+    }
+
+    # If all else fails, return a message that we couldn't find any content
+    else {
+        $content = $self->loc('This transaction appears to have no content');
+    }
+
+    if ( $args{'Quote'} ) {
+
+        # Remove quoted signature.
+        $content =~ s/\n-- \n(.*)$//s;
+
+        # What's the longest line like?
+        my $max = 0;
+        foreach ( split ( /\n/, $content ) ) {
+            $max = length if ( length > $max );
+        }
+
+        if ( $max > 76 ) {
+            require Text::Wrapper;
+            my $wrapper = new Text::Wrapper(
+                columns    => $args{'Wrap'},
+                body_start => ( $max > 70 * 3 ? '   ' : '' ),
+                par_start  => ''
+            );
+            $content = $wrapper->wrap($content);
+        }
+
+        $content = '['
+          . $self->CreatorObj->Name() . ' - '
+          . $self->CreatedAsString() . "]:\n\n" . $content . "\n\n";
+        $content =~ s/^/> /gm;
+
+    }
+
+    return ($content);
+}
+
+# }}}
+
+# {{{ ContentObj
+
+=head2 ContentObj 
+
+Returns the RT::Attachment object which contains the content for this Transaction
+
+=cut
+
+
+
+sub ContentObj {
+
+    my $self = shift;
+
+    # If we don\'t have any content, return undef now.
+    unless ( $self->Attachments->First ) {
+        return (undef);
+    }
+
+    # Get the set of toplevel attachments to this transaction.
+    my $Attachment = $self->Attachments->First();
+
+    # If it's a message or a plain part, just return the
+    # body.
+    if ( $Attachment->ContentType() =~ '^(text/plain$|message/)' ) {
+        return ($Attachment);
+    }
+
+    # If it's a multipart object, first try returning the first
+    # text/plain part.
+
+    elsif ( $Attachment->ContentType() =~ '^multipart/' ) {
+        my $plain_parts = $Attachment->Children();
+        $plain_parts->ContentType( VALUE => 'text/plain' );
+
+        # If we actully found a part, return its content
+        if ( $plain_parts->First && $plain_parts->First->Content ne '' ) {
+            return ( $plain_parts->First );
+        }
+
+        # If that fails, return the  first text/plain or message/ part
+        # which has some content.
+
+        else {
+            my $all_parts = $Attachment->Children();
+            while ( my $part = $all_parts->Next ) {
+                if (( $part->ContentType() =~ '^(text/plain$|message/)' ) &&  $part->Content()  ) {
+                    return ($part);
+                }
+            }
+        }
+
+    }
+
+    # We found no content. suck
+    return (undef);
+}
+
+# }}}
+
+# {{{ sub Subject
+
+=head2 Subject
+
+If this transaction has attached mime objects, returns the first one's subject
+Otherwise, returns null
+  
+=cut
+
+sub Subject {
+    my $self = shift;
+    if ( $self->Attachments->First ) {
+        return ( $self->Attachments->First->Subject );
+    }
+    else {
+        return (undef);
+    }
+}
+
+# }}}
+
+# {{{ sub Attachments 
+
+=head2 Attachments
+
+  Returns all the RT::Attachment objects which are attached
+to this transaction. Takes an optional parameter, which is
+a ContentType that Attachments should be restricted to.
+
+=cut
+
+sub Attachments {
+    my $self = shift;
+
+    unless ( $self->{'attachments'} ) {
+        $self->{'attachments'} = RT::Attachments->new( $self->CurrentUser );
+
+        #If it's a comment, return an empty object if they don't have the right to see it
+        if ( $self->Type eq 'Comment' ) {
+            unless ( $self->CurrentUserHasRight('ShowTicketComments') ) {
+                return ( $self->{'attachments'} );
+            }
+        }
+
+        #if they ain't got rights to see, return an empty object
+        else {
+            unless ( $self->CurrentUserHasRight('ShowTicket') ) {
+                return ( $self->{'attachments'} );
+            }
+        }
+
+        $self->{'attachments'}->Limit( FIELD => 'TransactionId',
+                                       VALUE => $self->Id );
+
+        # Get the self->{'attachments'} in the order they're put into
+        # the database.  Arguably, we should be returning a tree
+        # of self->{'attachments'}, not a set...but no current app seems to need
+        # it.
+
+        $self->{'attachments'}->OrderBy( ALIAS => 'main',
+                                         FIELD => 'id',
+                                         ORDER => 'asc' );
+
+    }
+    return ( $self->{'attachments'} );
+
+}
+
+# }}}
+
+# {{{ sub _Attach 
+
+=head2 _Attach
+
+A private method used to attach a mime object to this transaction.
+
+=cut
+
+sub _Attach {
+    my $self       = shift;
+    my $MIMEObject = shift;
+
+    if ( !defined($MIMEObject) ) {
+        $RT::Logger->error(
+"$self _Attach: We can't attach a mime object if you don't give us one.\n"
+        );
+        return ( 0, $self->loc("[_1]: no attachment specified", $self) );
+    }
+
+    my $Attachment = new RT::Attachment( $self->CurrentUser );
+    $Attachment->Create(
+        TransactionId => $self->Id,
+        Attachment    => $MIMEObject
+    );
+    return ( $Attachment, $self->loc("Attachment created") );
+
+}
+
+# }}}
+
+# }}}
+
+# {{{ Routines dealing with Transaction Attributes
+
+# {{{ sub Description 
+
+=head2 Description
+
+Returns a text string which describes this transaction
+
+=cut
+
+sub Description {
+    my $self = shift;
+
+    #Check those ACLs
+    #If it's a comment, we need to be extra special careful
+    if ( $self->__Value('Type') eq 'Comment' ) {
+        unless ( $self->CurrentUserHasRight('ShowTicketComments') ) {
+            return ( $self->loc("Permission Denied") );
+        }
+    }
+
+    #if they ain't got rights to see, don't let em
+    else {
+        unless ( $self->CurrentUserHasRight('ShowTicket') ) {
+            return ($self->loc("Permission Denied") );
+        }
+    }
+
+    if ( !defined( $self->Type ) ) {
+        return ( $self->loc("No transaction type specified"));
+    }
+
+    return ( $self->loc("[_1] by [_2]",$self->BriefDescription , $self->CreatorObj->Name ));
+}
+
+# }}}
+
+# {{{ sub BriefDescription 
+
+=head2 BriefDescription
+
+Returns a text string which briefly describes this transaction
+
+=cut
+
+sub BriefDescription {
+    my $self = shift;
+
+
+    #Check those ACLs
+    #If it's a comment, we need to be extra special careful
+    if ( $self->__Value('Type') eq 'Comment' ) {
+        unless ( $self->CurrentUserHasRight('ShowTicketComments') ) {
+            return ( $self->loc("Permission Denied") );
+        }
+    }
+
+    #if they ain't got rights to see, don't let em
+    else {
+        unless ( $self->CurrentUserHasRight('ShowTicket') ) {
+            return ( $self->loc("Permission Denied") );
+        }
+    }
+
+    my $type = $self->Type; #cache this, rather than calling it 30 times
+
+    if ( !defined( $type ) ) {
+        return $self->loc("No transaction type specified");
+    }
+
+    if ( $type eq 'Create' ) {
+        return ($self->loc("Ticket created"));
+    }
+    elsif ( $type =~ /Status/ ) {
+        if ( $self->Field eq 'Status' ) {
+            if ( $self->NewValue eq 'deleted' ) {
+                return ($self->loc("Ticket deleted"));
+            }
+            else {
+                return ( $self->loc("Status changed from [_1] to [_2]", $self->loc($self->OldValue), $self->loc($self->NewValue) ));
+
+            }
+        }
+
+        # Generic:
+       my $no_value = $self->loc("(no value)"); 
+        return ( $self->loc( "[_1] changed from [_2] to [_3]", $self->Field , ( $self->OldValue || $no_value ) ,  $self->NewValue ));
+    }
+
+    if ( $type eq 'Correspond' ) {
+        return $self->loc("Correspondence added");
+    }
+
+    elsif ( $type eq 'Comment' ) {
+        return $self->loc("Comments added");
+    }
+
+    elsif ( $type eq 'CustomField' ) {
+
+        my $field = $self->loc('CustomField');
+
+        if ( $self->Field ) {
+            my $cf = RT::CustomField->new( $self->CurrentUser );
+            $cf->Load( $self->Field );
+            $field = $cf->Name();
+        }
+
+        if ( $self->OldValue eq '' ) {
+            return ( $self->loc("[_1] [_2] added", $field, $self->NewValue) );
+        }
+        elsif ( $self->NewValue eq '' ) {
+            return ( $self->loc("[_1] [_2] deleted", $field, $self->OldValue) );
+
+        }
+        else {
+            return $self->loc("[_1] [_2] changed to [_3]", $field, $self->OldValue, $self->NewValue );
+        }
+    }
+
+    elsif ( $type eq 'Untake' ) {
+        return $self->loc("Untaken");
+    }
+
+    elsif ( $type eq "Take" ) {
+        return $self->loc("Taken");
+    }
+
+    elsif ( $type eq "Force" ) {
+        my $Old = RT::User->new( $self->CurrentUser );
+        $Old->Load( $self->OldValue );
+        my $New = RT::User->new( $self->CurrentUser );
+        $New->Load( $self->NewValue );
+
+        return $self->loc("Owner forcibly changed from [_1] to [_2]" , $Old->Name , $New->Name);
+    }
+    elsif ( $type eq "Steal" ) {
+        my $Old = RT::User->new( $self->CurrentUser );
+        $Old->Load( $self->OldValue );
+        return $self->loc("Stolen from [_1] ",  $Old->Name);
+    }
+
+    elsif ( $type eq "Give" ) {
+        my $New = RT::User->new( $self->CurrentUser );
+        $New->Load( $self->NewValue );
+        return $self->loc( "Given to [_1]",  $New->Name );
+    }
+
+    elsif ( $type eq 'AddWatcher' ) {
+        my $principal = RT::Principal->new($self->CurrentUser);
+        $principal->Load($self->NewValue);
+        return $self->loc( "[_1] [_2] added", $self->Field, $principal->Object->Name);
+    }
+
+    elsif ( $type eq 'DelWatcher' ) {
+        my $principal = RT::Principal->new($self->CurrentUser);
+        $principal->Load($self->OldValue);
+        return $self->loc( "[_1] [_2] deleted", $self->Field, $principal->Object->Name);
+    }
+
+    elsif ( $type eq 'Subject' ) {
+        return $self->loc( "Subject changed to [_1]", $self->Data );
+    }
+
+    elsif ( $type eq 'AddLink' ) {
+        my $value;
+       if ($self->NewValue) {
+               my $URI = RT::URI->new($self->CurrentUser);
+               $URI->FromURI($self->NewValue);
+               if ($URI->Resolver) {
+                       $value = $URI->Resolver->AsString;
+               } else {
+                       $value = $self->NewValue;
+               }
+       }
+       if ($self->Field eq 'DependsOn') {
+               return $self->loc("Dependency on [_1] added",$value);
+       } elsif ($self->Field eq 'DependedOnBy') {
+               return $self->loc("Dependency by [_1] added",$value);
+               
+       } elsif ($self->Field eq 'RefersTo') {
+               return $self->loc("Reference to [_1] added",$value);
+       } elsif ($self->Field eq 'ReferredToBy') {
+               return $self->loc("Reference by [_1] added",$value);
+       } elsif ($self->Field eq 'MemberOf') {
+               return $self->loc("Membership in [_1] added",$value);
+       } elsif ($self->Field eq 'HasMember') {
+               return $self->loc("Member [_1] added",$value);
+       } else {
+        return ( $self->Data );
+       }
+    }
+    elsif ( $type eq 'DeleteLink' ) {
+    my $value;
+       if ($self->OldValue) {
+               my $URI = RT::URI->new($self->CurrentUser);
+               $URI->FromURI($self->OldValue);
+               if ($URI->Resolver) {
+                       $value = $URI->Resolver->AsString;
+               } else {
+                       $value = $self->OldValue;
+               }
+       }
+
+       if ($self->Field eq 'DependsOn') {
+               return $self->loc("Dependency on [_1] deleted",$value);
+       } elsif ($self->Field eq 'DependedOnBy') {
+               return $self->loc("Dependency by [_1] deleted",$value);
+               
+       } elsif ($self->Field eq 'RefersTo') {
+               return $self->loc("Reference to [_1] deleted",$value);
+       } elsif ($self->Field eq 'ReferredToBy') {
+               return $self->loc("Reference by [_1] deleted",$value);
+       } elsif ($self->Field eq 'MemberOf') {
+               return $self->loc("Membership in [_1] deleted",$value);
+       } elsif ($self->Field eq 'HasMember') {
+               return $self->loc("Member [_1] deleted",$value);
+       } else {
+        return ( $self->Data );
+       }
+    }
+    elsif ( $type eq 'Set' ) {
+        if ( $self->Field eq 'Queue' ) {
+            my $q1 = new RT::Queue( $self->CurrentUser );
+            $q1->Load( $self->OldValue );
+            my $q2 = new RT::Queue( $self->CurrentUser );
+            $q2->Load( $self->NewValue );
+            return $self->loc("[_1] changed from [_2] to [_3]", $self->Field , $q1->Name , $q2->Name);
+        }
+
+        # Write the date/time change at local time:
+    elsif ($self->Field =~  /Due|Starts|Started|Told/) {
+        my $t1 = new RT::Date($self->CurrentUser);
+        $t1->Set(Format => 'ISO', Value => $self->NewValue);
+        my $t2 = new RT::Date($self->CurrentUser);
+        $t2->Set(Format => 'ISO', Value => $self->OldValue);
+        return $self->loc( "[_1] changed from [_2] to [_3]", $self->Field, $t2->AsString, $t1->AsString );
+    }
+        else {
+            return $self->loc( "[_1] changed from [_2] to [_3]", $self->Field, $self->OldValue, $self->NewValue );
+        }
+    }
+    elsif ( $type eq 'PurgeTransaction' ) {
+        return $self->loc("Transaction [_1] purged", $self->Data);
+    }
+    else {
+        return $self->loc( "Default: [_1]/[_2] changed from [_3] to [_4]", $type, $self->Field, $self->OldValue, $self->NewValue );
+
+    }
+}
+
+# }}}
+
+# {{{ Utility methods
+
+# {{{ sub IsInbound
+
+=head2 IsInbound
+
+Returns true if the creator of the transaction is a requestor of the ticket.
+Returns false otherwise
+
+=cut
+
+sub IsInbound {
+    my $self = shift;
+    return ( $self->TicketObj->IsRequestor( $self->CreatorObj->PrincipalId ) );
+}
+
+# }}}
+
+# }}}
+
+sub _ClassAccessible {
+    {
+
+        id => { read => 1, type => 'int(11)', default => '' },
+          EffectiveTicket =>
+          { read => 1, write => 1, type => 'int(11)', default => '' },
+          Ticket =>
+          { read => 1, public => 1, type => 'int(11)', default => '' },
+          TimeTaken => { read => 1, type => 'int(11)',      default => '' },
+          Type      => { read => 1, type => 'varchar(20)',  default => '' },
+          Field     => { read => 1, type => 'varchar(40)',  default => '' },
+          OldValue  => { read => 1, type => 'varchar(255)', default => '' },
+          NewValue  => { read => 1, type => 'varchar(255)', default => '' },
+          Data      => { read => 1, type => 'varchar(100)', default => '' },
+          Creator => { read => 1, auto => 1, type => 'int(11)', default => '' },
+          Created =>
+          { read => 1, auto => 1, type => 'datetime', default => '' },
+
+    }
+};
+
+# }}}
+
+# }}}
+
+# {{{ sub _Set
+
+sub _Set {
+    my $self = shift;
+    return ( 0, $self->loc('Transactions are immutable') );
+}
+
+# }}}
+
+# {{{ sub _Value 
+
+=head2 _Value
+
+Takes the name of a table column.
+Returns its value as a string, if the user passes an ACL check
+
+=cut
+
+sub _Value {
+
+    my $self  = shift;
+    my $field = shift;
+
+    #if the field is public, return it.
+    if ( $self->_Accessible( $field, 'public' ) ) {
+        return ( $self->__Value($field) );
+
+    }
+
+    #If it's a comment, we need to be extra special careful
+    if ( $self->__Value('Type') eq 'Comment' ) {
+        unless ( $self->CurrentUserHasRight('ShowTicketComments') ) {
+            return (undef);
+        }
+    }
+
+    #if they ain't got rights to see, don't let em
+    else {
+        unless ( $self->CurrentUserHasRight('ShowTicket') ) {
+            return (undef);
+        }
+    }
+
+    return ( $self->__Value($field) );
+
+}
+
+# }}}
+
+# {{{ sub CurrentUserHasRight
+
+=head2 CurrentUserHasRight RIGHT
+
+Calls $self->CurrentUser->HasQueueRight for the right passed in here.
+passed in here.
+
+=cut
+
+sub CurrentUserHasRight {
+    my $self  = shift;
+    my $right = shift;
+    return (
+        $self->CurrentUser->HasRight(
+            Right     => "$right",
+            Object => $self->TicketObj
+          )
+    );
+}
+
+# }}}
+
+1;
index 2ae98f2..23a475a 100755 (executable)
-#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Transactions.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-=head1 NAME
 
-  RT::Transactions - a collection of RT Transaction objects
+=head1 NAME
 
+  RT::Transactions -- Class Description
 =head1 SYNOPSIS
 
-  use RT::Transactions;
-
+  use RT::Transactions
 
 =head1 DESCRIPTION
 
 
 =head1 METHODS
 
-=begin testing
-
-ok (require RT::TestHarness);
-ok (require RT::Transactions);
-
-=end testing
-
 =cut
 
 package RT::Transactions;
-use RT::EasySearch;
 
-@ISA= qw(RT::EasySearch);
+use RT::SearchBuilder;
 use RT::Transaction;
 
-# {{{ sub _Init  
-sub _Init   {
-  my $self = shift;
-  
-  $self->{'table'} = "Transactions";
-  $self->{'primary_key'} = "id";
-  
-  # By default, order by the date of the transaction, rather than ID.
-  $self->OrderBy( ALIAS => 'main',
-                 FIELD => 'Created',
-                 ORDER => 'ASC');
-
-  return ( $self->SUPER::_Init(@_));
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
+
+
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'Transactions';
+    $self->{'primary_key'} = 'id';
+
+
+    return ( $self->SUPER::_Init(@_) );
 }
-# }}}
 
-# {{{ sub NewItem 
-sub NewItem  {
+
+=item NewItem
+
+Returns an empty new RT::Transaction item
+
+=cut
+
+sub NewItem {
     my $self = shift;
-    
     return(RT::Transaction->new($self->CurrentUser));
 }
-# }}}
+
+        eval "require RT::Transactions_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Transactions_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Transactions_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Transactions_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::Transactions_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Transactions_Local.pm}) {
+            die $@;
+        };
 
 
-=head2 example methods
 
-  Queue RT::Queue or Queue Id
-  Ticket RT::Ticket or Ticket Id
 
+=head1 SEE ALSO
 
-LimitDate 
-  
-Type TRANSTYPE
-Field STRING
-OldValue OLDVAL
-NewValue NEWVAL
-Data DATA
-TimeTaken
-Actor USEROBJ/USERID
-ContentMatches STRING
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::Transactions_Overlay, RT::Transactions_Vendor, RT::Transactions_Local
 
 =cut
 
 
 1;
-
diff --git a/rt/lib/RT/Transactions_Overlay.pm b/rt/lib/RT/Transactions_Overlay.pm
new file mode 100644 (file)
index 0000000..3a7d4c1
--- /dev/null
@@ -0,0 +1,86 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Transactions - a collection of RT Transaction objects
+
+=head1 SYNOPSIS
+
+  use RT::Transactions;
+
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=begin testing
+
+ok (require RT::Transactions);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+# {{{ sub _Init  
+sub _Init   {
+  my $self = shift;
+  
+  $self->{'table'} = "Transactions";
+  $self->{'primary_key'} = "id";
+  
+  # By default, order by the date of the transaction, rather than ID.
+  $self->OrderBy( ALIAS => 'main',
+                 FIELD => 'Created',
+                 ORDER => 'ASC');
+
+  return ( $self->SUPER::_Init(@_));
+}
+# }}}
+
+=head2 example methods
+
+  Queue RT::Queue or Queue Id
+  Ticket RT::Ticket or Ticket Id
+
+
+LimitDate 
+  
+Type TRANSTYPE
+Field STRING
+OldValue OLDVAL
+NewValue NEWVAL
+Data DATA
+TimeTaken
+Actor USEROBJ/USERID
+ContentMatches STRING
+
+=cut
+
+
+1;
+
diff --git a/rt/lib/RT/URI.pm b/rt/lib/RT/URI.pm
new file mode 100644 (file)
index 0000000..7acc1dc
--- /dev/null
@@ -0,0 +1,244 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+package RT::URI;;
+
+use strict;
+use vars qw/@ISA/;
+@ISA = qw(RT::Base);
+
+use RT::URI::base;
+use Carp;
+
+=head1 NAME
+
+RT::URI
+
+=head1 DESCRIPTION
+
+This class provides a base class for URIs, such as those handled
+by RT::Link objects.  
+
+=head1 API
+
+
+
+=cut
+
+
+
+
+=head2 new
+
+Create a new RT::URI object.
+
+=cut
+
+                         
+sub new {
+    my $proto = shift;
+    my $class = ref($proto) || $proto;
+    my $self  = {};
+    bless( $self, $class );
+
+    $self->CurrentUser(@_);
+
+    return ($self);
+}
+
+
+
+# {{{ FromObject
+
+=head2 FromObject <Object>
+
+Given a local object, such as an RT::Ticket or an RT::FM::Article, this routine will return a URI for
+the local object
+
+=cut
+
+sub FromObject {
+    my $self = shift;
+    my $obj = shift;
+
+    return undef unless  $obj->can('URI');
+    return $self->FromURI($obj->URI);
+}
+
+# }}}
+
+# {{{ FromURI
+
+=head2 FromURI <URI>
+
+Returns a local object id for this content.  You are expected to know what sort of object this is the Id 
+of 
+
+=cut
+
+sub FromURI {
+    my $self = shift;
+    my $uri = shift;    
+
+    return undef unless ($uri);
+
+       my $scheme;
+       # Special case: integers passed in as URIs must be ticket ids
+       if ($uri =~ /^(\d+)$/) {
+               $scheme = "fsck.com-rt";
+       } elsif ($uri =~ /^((?:\w|\.|-)+?):/) {
+         $scheme = $1;
+    }
+    else {
+        $RT::Logger->warning("$self Could not determine a URI scheme for $uri");
+               return (undef);
+    }
+     
+    # load up a resolver object for this scheme  
+    $self->_GetResolver($scheme);
+    
+    unless ($self->Resolver->ParseURI($uri)) {
+        $RT::Logger->warning("Resolver ".ref($self->Resolver)." could not parse $uri");
+       return (undef);
+    }
+
+}
+
+# }}}
+
+# {{{ _GetResolver
+
+=private _GetResolver <scheme>
+
+Gets an RT URI resolver for the scheme <scheme>. 
+Falls back to a null resolver. RT::URI::base.
+
+=cut
+
+sub _GetResolver {
+    my $self = shift;
+    my $scheme = shift;
+
+    $scheme =~ s/(\.|-)/_/g;
+    my $resolver;
+
+    
+       eval " 
+            require RT::URI::$scheme;
+            \$resolver = RT::URI::$scheme->new(\$self->CurrentUser);
+       ";
+     
+        if ($resolver) {
+        $self->{'resolver'} = $resolver;
+        } else {
+        $self->{'resolver'} = RT::URI::base->new($self->CurrentUser); 
+        }
+
+}
+
+# }}}
+
+# {{{ Scheme
+
+=head2 Scheme
+
+Returns a local object id for this content.  You are expected to know what sort of object this is the Id 
+of 
+
+=cut
+
+sub Scheme {
+    my $self = shift;
+    return ($self->Resolver->Scheme);
+
+}
+# }}}
+# {{{ URI
+
+=head2 URI
+
+Returns a local object id for this content.  You are expected to know what sort of object this is the Id 
+of 
+
+=cut
+
+sub URI {
+    my $self = shift;
+    return ($self->Resolver->URI);
+
+}
+# }}}
+
+# {{{ Object
+
+=head2 Object
+
+Returns a local object for this content. This will usually be an RT::Ticket or somesuch
+
+=cut
+
+
+sub Object {   
+    my $self = shift;
+    return($self->Resolver->Object);
+
+}
+
+
+# }}}
+
+# {{{ IsLocal
+
+=head2 IsLocal
+
+Returns a local object for this content. This will usually be an RT::Ticket or somesuch
+
+=cut
+
+sub IsLocal {
+    my $self = shift;
+    return $self->Resolver->IsLocal;     
+}
+
+
+# }}}
+
+
+=head Resolver
+
+Returns this URI's URI resolver object
+
+=cut
+
+
+sub Resolver {
+    my $self =shift;
+    return ($self->{'resolver'});
+}
+
+eval "require RT::URI_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/URI_Vendor.pm});
+eval "require RT::URI_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/URI_Local.pm});
+
+1;
diff --git a/rt/lib/RT/URI/base.pm b/rt/lib/RT/URI/base.pm
new file mode 100644 (file)
index 0000000..a599f3a
--- /dev/null
@@ -0,0 +1,129 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+package RT::URI::base;
+
+use strict;
+use base qw(RT::Base);
+
+=head1 NAME
+
+RT::URI::base
+
+=head1 DESCRIPTION
+
+A baseclass (and fallback) RT::URI handler. Every URI handler needs to 
+handle the API presented here
+
+=cut
+
+
+=head1 API
+
+=head2 new
+
+Create a new URI handler
+
+=cut
+
+sub new {
+    my $proto = shift;
+    my $class = ref($proto) || $proto;
+    my $self  = {};
+    bless( $self, $class );
+    $self->CurrentUser(@_);
+    return ($self);
+}
+
+sub ParseObject  {
+    my $self = shift;
+    my $obj = shift;
+    $self->{'uri'} = "unknown-object:".ref($obj);
+
+
+}
+
+
+
+sub ParseURI { 
+    my $self = shift;
+    my $uri = shift;
+
+    if ($uri =~  /^(.*?):/) { 
+        $self->{'scheme'} = $1;
+    }
+    $self->{'uri'} = $uri;
+   
+    
+}
+
+
+sub Object {
+    my $self = shift;
+    return undef;
+
+}
+
+sub URI {
+    my $self = shift;
+    return($self->{'uri'});
+}
+
+sub Scheme { 
+    my $self = shift;
+    return($self->{'scheme'});
+
+}
+
+sub HREF {
+    my $self = shift;
+    return($self->{'href'} || $self->{'uri'});
+}
+
+sub IsLocal {
+    my $self = shift;
+    return undef;
+}
+
+=head2 AsString
+
+Return a "pretty" string representing the URI object.
+
+This is meant to be used like this:
+
+ % $re = $uri->Resolver;
+ <A HREF="<% $re->HREF %>"><% $re->AsString %></A>
+
+=cut
+
+sub AsString {
+    my $self = shift;
+    return $self->URI;
+}
+
+eval "require RT::URI::base_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/URI/base_Vendor.pm});
+eval "require RT::URI::base_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/URI/base_Local.pm});
+
+1;
diff --git a/rt/lib/RT/URI/fsck_com_rt.pm b/rt/lib/RT/URI/fsck_com_rt.pm
new file mode 100644 (file)
index 0000000..36e8f82
--- /dev/null
@@ -0,0 +1,247 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+package RT::URI::fsck_com_rt;
+
+use RT::Ticket;
+
+use RT::URI::base;
+
+use strict;
+use vars qw(@ISA);
+@ISA = qw/RT::URI::base/;
+
+
+
+
+=head2 LocalURIPrefix 
+
+Returns the prefix for a local ticket URI
+
+=begin testing
+
+use_ok("RT::URI::fsck_com_rt");
+my $uri = RT::URI::fsck_com_rt->new($RT::SystemUser);
+
+ok(ref($uri));
+
+use Data::Dumper;
+
+
+ok (UNIVERSAL::isa($uri,RT::URI::fsck_com_rt), "It's an RT::URI::fsck_com_rt");
+
+ok ($uri->isa('RT::URI::base'), "It's an RT::URI::base");
+ok ($uri->isa('RT::Base'), "It's an RT::Base");
+
+is ($uri->LocalURIPrefix , 'fsck.com-rt://example.com/ticket/');
+
+=end testing
+
+
+
+=cut
+
+sub LocalURIPrefix {
+    my $self = shift;
+    my $prefix = $self->Scheme. "://$RT::Organization/ticket/";
+    return ($prefix);
+}
+
+
+
+
+
+=head2 URIForObject RT::Ticket
+
+Returns the RT URI for a local RT::Ticket object
+
+=begin testing
+
+my $ticket = RT::Ticket->new($RT::SystemUser);
+$ticket->Load(1);
+my $uri = RT::URI::fsck_com_rt->new($ticket->CurrentUser);
+is($uri->LocalURIPrefix . "1" , $uri->URIForObject($ticket));
+
+=end testing
+
+=cut
+
+sub URIForObject {
+
+    my $self = shift;
+
+    my $obj = shift;
+    return ($self->LocalURIPrefix. $obj->Id);
+}
+
+
+=head2 ParseObject $TicketObj
+
+When handed an RT::Ticekt object, figure out its URI
+
+
+=cut
+
+
+
+=head2 ParseURI URI
+
+When handed an fsck.com-rt: URI, figures out things like whether its a local ticket
+and what its ID is
+
+=cut
+
+
+sub ParseURI { 
+    my $self = shift;
+    my $uri = shift;
+
+       my $ticket;
+       if ($uri =~ /^(\d+)$/) {
+               $ticket = RT::Ticket->new($self->CurrentUser);
+               $ticket->Load($uri);    
+               $self->{'uri'} = $ticket->URI;
+       }
+       else {
+           $self->{'uri'} = $uri;
+       }
+       #If it's a local URI, load the ticket object and return its URI
+    if ( $self->IsLocal) {
+   
+        my $local_uri_prefix = $self->LocalURIPrefix;
+       if ($self->{'uri'} =~ /^$local_uri_prefix(\d+)$/) {
+               my $id = $1;
+       
+    
+               $ticket = RT::Ticket->new( $self->CurrentUser );
+           $ticket->Load($id);
+
+           #If we couldn't find a ticket, return undef.
+           unless ( defined $ticket->Id ) {
+               return undef;
+           }
+           } else {
+           return undef;
+           }   
+    }
+       $self->{'object'} = $ticket;
+    if ( UNIVERSAL::can( $ticket, 'Id' ) ) {
+        return ( $ticket->Id );
+    }
+    else {
+        return undef;
+    }
+}
+
+=head2 IsLocal 
+
+Returns true if this URI is for a local ticket.
+Returns undef otherwise.
+
+
+
+=cut
+
+sub IsLocal {
+       my $self = shift;
+        my $local_uri_prefix = $self->LocalURIPrefix;
+       if ($self->{'uri'} =~ /^$local_uri_prefix/) {
+               return 1;
+    }
+       else {
+               return undef;
+       }
+}
+
+
+
+=head2 Object
+
+Returns the object for this URI, if it's local. Otherwise returns undef.
+
+=cut
+
+sub Object {
+    my $self = shift;
+    return ($self->{'object'});
+
+}
+
+=head2 Scheme
+
+Return the URI scheme for RT tickets
+
+=cut
+
+
+sub Scheme {
+    my $self = shift;
+       return "fsck.com-rt";
+}
+
+=head2 HREF
+
+If this is a local ticket, return an HTTP url to it.
+Otherwise, return its URI
+
+=cut
+
+
+sub HREF {
+    my $self = shift;
+    if ($self->IsLocal) {
+        return ( $RT::WebURL . "Ticket/Display.html?id=".$self->Object->Id);
+    }   
+    else {
+        return ($self->URI);
+    }
+}
+
+=head2 AsString
+
+Returns either a localized string 'ticket #23' or the full URI if the object is not local
+
+=cut
+
+sub AsString {
+    my $self = shift;
+    if ($self->IsLocal) {
+       return $self->loc("ticket #[_1]", $self->Object->Id);
+
+    }
+    else {
+       return $self->Object->URI;
+    }
+}
+
+eval "require RT::URI::fsck_com_rt_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/URI/fsck_com_rt_Vendor.pm});
+eval "require RT::URI::fsck_com_rt_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/URI/fsck_com_rt_Local.pm});
+
+1;
index 4e85540..cbc10f5 100755 (executable)
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/User.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# (c) 1996-2000 Jesse Vincent <jesse@fsck.com>
-# This software is redistributable under the terms of the GNU GPL
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+
 
 =head1 NAME
 
-  RT::User - RT User object
+RT::User
 
-=head1 SYNOPSIS
 
-  use RT::User;
+=head1 SYNOPSIS
 
 =head1 DESCRIPTION
 
-
 =head1 METHODS
 
-=begin testing
+=cut
+
+package RT::User;
+use RT::Record; 
+
+
+use vars qw( @ISA );
+@ISA= qw( RT::Record );
+
+sub _Init {
+  my $self = shift; 
+
+  $self->Table('Users');
+  $self->SUPER::_Init(@_);
+}
 
-ok(require RT::TestHarness);
-ok(require RT::User);
 
-=end testing
 
 
+
+=item Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+  varchar(200) 'Name'.
+  varchar(40) 'Password'.
+  blob 'Comments'.
+  blob 'Signature'.
+  varchar(120) 'EmailAddress'.
+  blob 'FreeformContactInfo'.
+  varchar(200) 'Organization'.
+  varchar(120) 'RealName'.
+  varchar(16) 'NickName'.
+  varchar(16) 'Lang'.
+  varchar(16) 'EmailEncoding'.
+  varchar(16) 'WebEncoding'.
+  varchar(100) 'ExternalContactInfoId'.
+  varchar(30) 'ContactInfoSystem'.
+  varchar(100) 'ExternalAuthId'.
+  varchar(30) 'AuthSystem'.
+  varchar(16) 'Gecos'.
+  varchar(30) 'HomePhone'.
+  varchar(30) 'WorkPhone'.
+  varchar(30) 'MobilePhone'.
+  varchar(30) 'PagerPhone'.
+  varchar(200) 'Address1'.
+  varchar(200) 'Address2'.
+  varchar(100) 'City'.
+  varchar(100) 'State'.
+  varchar(16) 'Zip'.
+  varchar(50) 'Country'.
+  varchar(50) 'Timezone'.
+  text 'PGPKey'.
+
 =cut
 
 
-package RT::User;
-use RT::Record;
-@ISA= qw(RT::Record);
 
-# {{{ sub _Init
-sub _Init  {
+
+sub Create {
     my $self = shift;
-    $self->{'table'} = "Users";
-    return($self->SUPER::_Init(@_));
-}
-# }}}
-
-# {{{ sub _Accessible 
-
-sub _Accessible  {
-  my $self = shift;
-  my %Cols = (
-             # {{{ Core RT info
-             Name => 'public/read/write/admin',
-             Password => 'write',
-             Comments => 'read/write/admin',
-             Signature => 'read/write',
-             EmailAddress => 'public/read/write',
-             PagerEmailAddress => 'read/write',
-             FreeformContactInfo => 'read/write',
-             Organization => 'public/read/write/admin',
-             Disabled => 'public/read/write/admin', #To modify this attribute, we have helper
-             #methods
-             Privileged => 'read/write/admin', # 0=no 1=user 2=system
-
-             # }}}
-             
-             # {{{ Names
-             
-             RealName => 'public/read/write',
-             NickName => 'public/read/write',
-             # }}}
-                     
-             # {{{ Localization and Internationalization
-             Lang => 'public/read/write',
-             EmailEncoding => 'public/read/write',
-             WebEncoding => 'public/read/write',
-             # }}}
-             
-             # {{{ External ContactInfo Linkage
-             ExternalContactInfoId => 'public/read/write/admin',
-             ContactInfoSystem => 'public/read/write/admin',
-             # }}}
-             
-             # {{{ User Authentication identifier
-             ExternalAuthId => 'public/read/write/admin',
-             #Authentication system used for user 
-             AuthSystem => 'public/read/write/admin',
-             Gecos => 'public/read/write/admin', #Gecos is the name of the fields in a 
-             # unix passwd file. In this case, it refers to "Unix Username"
-             # }}}
-             
-             # {{{ Telephone numbers
-             HomePhone =>  'read/write',
-             WorkPhone => 'read/write',
-             MobilePhone => 'read/write',
-             PagerPhone => 'read/write',
-
-             # }}}
-             
-             # {{{ Paper Address
-             Address1 => 'read/write',
-             Address2 => 'read/write',
-             City => 'read/write',
-             State => 'read/write',
-             Zip => 'read/write',
-             Country => 'read/write',
-             # }}}
-             
-             # {{{ Core DBIx::Record Attributes
-             Creator => 'read/auto',
-             Created => 'read/auto',
-             LastUpdatedBy => 'read/auto',
-             LastUpdated => 'read/auto'
-
-             # }}}
-            );
-  return($self->SUPER::_Accessible(@_, %Cols));
+    my %args = ( 
+                Name => '',
+                Password => '',
+                Comments => '',
+                Signature => '',
+                EmailAddress => '',
+                FreeformContactInfo => '',
+                Organization => '',
+                RealName => '',
+                NickName => '',
+                Lang => '',
+                EmailEncoding => '',
+                WebEncoding => '',
+                ExternalContactInfoId => '',
+                ContactInfoSystem => '',
+                ExternalAuthId => '',
+                AuthSystem => '',
+                Gecos => '',
+                HomePhone => '',
+                WorkPhone => '',
+                MobilePhone => '',
+                PagerPhone => '',
+                Address1 => '',
+                Address2 => '',
+                City => '',
+                State => '',
+                Zip => '',
+                Country => '',
+                Timezone => '',
+                PGPKey => '',
+
+                 @_);
+    $self->SUPER::Create(
+                         Name => $args{'Name'},
+                         Password => $args{'Password'},
+                         Comments => $args{'Comments'},
+                         Signature => $args{'Signature'},
+                         EmailAddress => $args{'EmailAddress'},
+                         FreeformContactInfo => $args{'FreeformContactInfo'},
+                         Organization => $args{'Organization'},
+                         RealName => $args{'RealName'},
+                         NickName => $args{'NickName'},
+                         Lang => $args{'Lang'},
+                         EmailEncoding => $args{'EmailEncoding'},
+                         WebEncoding => $args{'WebEncoding'},
+                         ExternalContactInfoId => $args{'ExternalContactInfoId'},
+                         ContactInfoSystem => $args{'ContactInfoSystem'},
+                         ExternalAuthId => $args{'ExternalAuthId'},
+                         AuthSystem => $args{'AuthSystem'},
+                         Gecos => $args{'Gecos'},
+                         HomePhone => $args{'HomePhone'},
+                         WorkPhone => $args{'WorkPhone'},
+                         MobilePhone => $args{'MobilePhone'},
+                         PagerPhone => $args{'PagerPhone'},
+                         Address1 => $args{'Address1'},
+                         Address2 => $args{'Address2'},
+                         City => $args{'City'},
+                         State => $args{'State'},
+                         Zip => $args{'Zip'},
+                         Country => $args{'Country'},
+                         Timezone => $args{'Timezone'},
+                         PGPKey => $args{'PGPKey'},
+);
+
 }
 
-# }}}
 
-# {{{ sub Create 
 
-sub Create  {
-    my $self = shift;
-    my %args = (Privileged => 0,
-               @_ # get the real argumentlist
-              );
-    
-    #Check the ACL
-    unless ($self->CurrentUserHasRight('AdminUsers')) {
-       return (0, 'No permission to create users');
-    }
-    
-    if (! $args{'Password'})  {
-       $args{'Password'} = '*NO-PASSWORD*';
-    }
-    elsif (length($args{'Password'}) < $RT::MinimumPasswordLength) {
-        return(0,"Password too short");
-    }
-    else {
-        my $salt = join '', ('.','/',0..9,'A'..'Z','a'..'z')[rand 64, rand 64];
-        $args{'Password'} = crypt($args{'Password'}, $salt);     
-    }   
-        
-    
-    #TODO Specify some sensible defaults.
-    
-    unless (defined ($args{'Name'})) {
-       return(0, "Must specify 'Name' attribute");
-    }  
-    
-    
-    #SANITY CHECK THE NAME AND ABORT IF IT'S TAKEN
-    if ($RT::SystemUser) { #This only works if RT::SystemUser has been defined
-               my $TempUser = RT::User->new($RT::SystemUser);
-               $TempUser->Load($args{'Name'});
-               return (0, 'Name in use') if ($TempUser->Id);
-       
-               return(0, 'Email address in use') 
-                       unless ($self->ValidateEmailAddress($args{'EmailAddress'}));
-    }
-    else {
-               $RT::Logger->warning("$self couldn't check for pre-existing ".
-                            " users on create. This will happen".
-                            " on installation\n");
-    }
-    
-    my $id = $self->SUPER::Create(%args);
-    
-    #If the create failed.
-    unless ($id) {
-               return (0, 'Could not create user');
-    }
-      
-    
-    #TODO post 2.0
-    #if ($args{'SendWelcomeMessage'}) {
-    #  #TODO: Check if the email exists and looks valid
-    #  #TODO: Send the user a "welcome message" 
-    #}
-    
-    return ($id, 'User created');
-}
+=item id
 
-# }}}
+Returns the current value of id. 
+(In the database, id is stored as int(11).)
 
-# {{{ sub _BootstrapCreate 
 
-#create a user without validating _any_ data.
+=cut
 
-#To be used only on database init.
 
-sub _BootstrapCreate {
-    my $self = shift;
-    my %args = (@_);
+=item Name
 
-    $args{'Password'} = "*NO-PASSWORD*";
-    my $id = $self->SUPER::Create(%args);
-    
-    #If the create failed.
-    return (0, 'Could not create user') 
-      unless ($id);
+Returns the current value of Name. 
+(In the database, Name is stored as varchar(200).)
 
-    return ($id, 'User created');
-}
 
-# }}}
 
-# {{{ sub Delete 
+=item SetName VALUE
 
-sub Delete  {
-    my $self = shift;
-    
-    return(0, 'Deleting this object would violate referential integrity');
-    
-}
 
-# }}}
+Set Name to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Name will be stored as a varchar(200).)
+
+
+=cut
+
+
+=item Password
+
+Returns the current value of Password. 
+(In the database, Password is stored as varchar(40).)
 
-# {{{ sub Load 
 
-=head2 Load
 
-Load a user object from the database. Takes a single argument.
-If the argument is numerical, load by the column 'id'. Otherwise, load by
-the "Name" column which is the user's textual username.
+=item SetPassword VALUE
+
+
+Set Password to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Password will be stored as a varchar(40).)
+
 
 =cut
 
-sub Load  {
-    my $self = shift;
-    my $identifier = shift || return undef;
-    
-    #if it's an int, load by id. otherwise, load by name.
-    if ($identifier !~ /\D/) {
-       $self->SUPER::LoadById($identifier);
-    }
-    else {
-       $self->LoadByCol("Name",$identifier);
-    }
-}
 
-# }}}
+=item Comments
+
+Returns the current value of Comments. 
+(In the database, Comments is stored as blob.)
 
 
-# {{{ sub LoadByEmail
 
-=head2 LoadByEmail
+=item SetComments VALUE
 
-Tries to load this user object from the database by the user's email address.
+
+Set Comments to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Comments will be stored as a blob.)
 
 
 =cut
 
-sub LoadByEmail {
-    my $self=shift;
-    my $address = shift;
 
-    # Never load an empty address as an email address.
-    unless ($address) {
-       return(undef);
-    }
+=item Signature
 
-    $address = RT::CanonicalizeAddress($address);
-    #$RT::Logger->debug("Trying to load an email address: $address\n");
-    return $self->LoadByCol("EmailAddress", $address);
-}
-# }}}
+Returns the current value of Signature. 
+(In the database, Signature is stored as blob.)
 
 
-# {{{ sub ValidateEmailAddress
 
-=head2 ValidateEmailAddress ADDRESS
+=item SetSignature VALUE
+
+
+Set Signature to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Signature will be stored as a blob.)
 
-Returns true if the email address entered is not in use by another user or is 
-undef or ''. Returns false if it's in use. 
 
 =cut
 
-sub ValidateEmailAddress {
-       my $self = shift;
-       my $Value = shift;
 
-       # if the email address is null, it's always valid
-       return (1) if(!$Value || $Value eq "");
+=item EmailAddress
 
-       my $TempUser = RT::User->new($RT::SystemUser);
-       $TempUser->LoadByEmail($Value);
+Returns the current value of EmailAddress. 
+(In the database, EmailAddress is stored as varchar(120).)
 
-       if( $TempUser->id && 
-          ($TempUser->id != $self->id)) { # if we found a user with that address 
-                                       # it's invalid to set this user's address to it
-               return(undef);
-       }
-       else { #it's a valid email address
-               return(1);
-       }
-}
 
-# }}}
 
+=item SetEmailAddress VALUE
+
+
+Set EmailAddress to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, EmailAddress will be stored as a varchar(120).)
+
+
+=cut
+
+
+=item FreeformContactInfo
+
+Returns the current value of FreeformContactInfo. 
+(In the database, FreeformContactInfo is stored as blob.)
 
 
 
-# {{{ sub SetRandomPassword
+=item SetFreeformContactInfo VALUE
 
-=head2 SetRandomPassword
 
-Takes no arguments. Returns a status code and a new password or an error message.
-If the status is 1, the second value returned is the new password.
-If the status is anything else, the new value returned is the error code.
+Set FreeformContactInfo to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, FreeformContactInfo will be stored as a blob.)
+
 
 =cut
 
-sub SetRandomPassword  {
-    my $self = shift;
 
+=item Organization
 
-    unless ($self->CurrentUserCanModify('Password')) {
-       return (0, "Permission Denied");
-    }
-    
-    my $pass = $self->GenerateRandomPassword(6,8);
+Returns the current value of Organization. 
+(In the database, Organization is stored as varchar(200).)
 
-    # If we have "notify user on 
 
-    my ($val, $msg) = $self->SetPassword($pass);
-    
-    #If we got an error return the error.
-    return (0, $msg) unless ($val);
-    
-    #Otherwise, we changed the password, lets return it.
-    return (1, $pass);
-    
-}
 
-# }}}
+=item SetOrganization VALUE
+
+
+Set Organization to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Organization will be stored as a varchar(200).)
+
+
+=cut
+
+
+=item RealName
+
+Returns the current value of RealName. 
+(In the database, RealName is stored as varchar(120).)
 
 
-# {{{ sub ResetPassword
 
-=head2 ResetPassword
+=item SetRealName VALUE
+
+
+Set RealName to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, RealName will be stored as a varchar(120).)
 
-Returns status, [ERROR or new password].  Resets this user\'s password to
-a randomly generated pronouncable password and emails them, using a 
-global template called "RT_PasswordChange", which can be overridden
-with global templates "RT_PasswordChange_Privileged" or "RT_PasswordChange_NonPrivileged" 
-for privileged and Non-privileged users respectively.
 
 =cut
 
-sub ResetPassword {
-    my $self = shift;
-    
-    unless ($self->CurrentUserCanModify('Password')) {
-       return (0, "Permission Denied");
-    }
-    my ($status, $pass) = $self->SetRandomPassword();
-
-    unless ($status) {
-       return (0, "$pass");
-    }
-    
-    my $template = RT::Template->new($self->CurrentUser);
-
-
-    if ($self->IsPrivileged) {
-       $template->LoadGlobalTemplate('RT_PasswordChange_Privileged');
-    } 
-    else {
-       $template->LoadGlobalTemplate('RT_PasswordChange_Privileged');
-    }  
-    
-    unless ($template->Id) {
-       $template->LoadGlobalTemplate('RT_PasswordChange');
-    }  
-    
-    unless ($template->Id) {
-       $RT::Logger->crit("$self tried to send ".$self->Name." a password reminder ".
-                         "but couldn't find a password change template");
-    }  
-
-    my $notification =  RT::Action::SendPasswordEmail->new(TemplateObj => $template,
-                                                          Argument => $pass);
-    
-    $notification->SetTo($self->EmailAddress);
-
-    my ($ret);
-    $ret = $notification->Prepare();
-    if ($ret) {
-       $ret = $notification->Commit();
-    }
-    
-    if ($ret) {
-       return(1, 'New password notification sent');
-    }  else {
-       return (0, 'Notification could not be sent');
-    }  
-    
-}
 
+=item NickName
 
-# }}}
+Returns the current value of NickName. 
+(In the database, NickName is stored as varchar(16).)
 
-# {{{ sub GenerateRandomPassword
 
-=head2 GenerateRandomPassword MIN_LEN and MAX_LEN
 
-Returns a random password between MIN_LEN and MAX_LEN characters long.
+=item SetNickName VALUE
+
+
+Set NickName to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, NickName will be stored as a varchar(16).)
+
 
 =cut
 
-sub GenerateRandomPassword {
-    my $self = shift;
-    my $min_length = shift;
-    my $max_length = shift;
-    
-    #This code derived from mpw.pl, a bit of code with a sordid history
-    # Its notes: 
-    
-    # Perl cleaned up a bit by Jesse Vincent 1/14/2001.
-    # Converted to perl from C by Marc Horowitz, 1/20/2000.
-    # Converted to C from Multics PL/I by Bill Sommerfeld, 4/21/86.
-    # Original PL/I version provided by Jerry Saltzer.
-
-    
-    my ($frequency, $start_freq, $total_sum, $row_sums);
-
-    #When munging characters, we need to know where to start counting letters from
-    my $a = ord('a');
-
-    # frequency of English digraphs (from D Edwards 1/27/66) 
-    $frequency =
-      [ [ 4, 20, 28, 52, 2, 11, 28, 4, 32, 4, 6, 62, 23,
-         167, 2, 14, 0, 83, 76, 127, 7, 25, 8, 1, 9, 1 ], # aa - az
-       [ 13, 0, 0, 0, 55, 0, 0, 0, 8, 2, 0, 22, 0,
-         0, 11, 0, 0, 15, 4, 2, 13, 0, 0, 0, 15, 0 ], # ba - bz
-       [ 32, 0, 7, 1, 69, 0, 0, 33, 17, 0, 10, 9, 1,
-         0, 50, 3, 0, 10, 0, 28, 11, 0, 0, 0, 3, 0 ], # ca - cz
-       [ 40, 16, 9, 5, 65, 18, 3, 9, 56, 0, 1, 4, 15,
-         6, 16, 4, 0, 21, 18, 53, 19, 5, 15, 0, 3, 0 ], # da - dz
-       [ 84, 20, 55, 125, 51, 40, 19, 16, 50, 1, 4, 55, 54,
-         146, 35, 37, 6, 191, 149, 65, 9, 26, 21, 12, 5, 0 ], # ea - ez
-       [ 19, 3, 5, 1, 19, 21, 1, 3, 30, 2, 0, 11, 1,
-         0, 51, 0, 0, 26, 8, 47, 6, 3, 3, 0, 2, 0 ], # fa - fz
-       [ 20, 4, 3, 2, 35, 1, 3, 15, 18, 0, 0, 5, 1,
-         4, 21, 1, 1, 20, 9, 21, 9, 0, 5, 0, 1, 0 ], # ga - gz
-       [ 101, 1, 3, 0, 270, 5, 1, 6, 57, 0, 0, 0, 3,
-         2, 44, 1, 0, 3, 10, 18, 6, 0, 5, 0, 3, 0 ], # ha - hz
-       [ 40, 7, 51, 23, 25, 9, 11, 3, 0, 0, 2, 38, 25,
-         202, 56, 12, 1, 46, 79, 117, 1, 22, 0, 4, 0, 3 ], # ia - iz
-       [ 3, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0,
-         0, 4, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0 ], # ja - jz
-       [ 1, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 0,
-         2, 0, 0, 0, 0, 6, 2, 1, 0, 2, 0, 1, 0 ], # ka - kz
-       [ 44, 2, 5, 12, 62, 7, 5, 2, 42, 1, 1, 53, 2,
-         2, 25, 1, 1, 2, 16, 23, 9, 0, 1, 0, 33, 0 ], # la - lz
-       [ 52, 14, 1, 0, 64, 0, 0, 3, 37, 0, 0, 0, 7,
-         1, 17, 18, 1, 2, 12, 3, 8, 0, 1, 0, 2, 0 ], # ma - mz
-       [ 42, 10, 47, 122, 63, 19, 106, 12, 30, 1, 6, 6, 9,
-         7, 54, 7, 1, 7, 44, 124, 6, 1, 15, 0, 12, 0 ], # na - nz
-       [ 7, 12, 14, 17, 5, 95, 3, 5, 14, 0, 0, 19, 41,
-         134, 13, 23, 0, 91, 23, 42, 55, 16, 28, 0, 4, 1 ], # oa - oz
-       [ 19, 1, 0, 0, 37, 0, 0, 4, 8, 0, 0, 15, 1,
-         0, 27, 9, 0, 33, 14, 7, 6, 0, 0, 0, 0, 0 ], # pa - pz
-       [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-         0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0 ], # qa - qz
-       [ 83, 8, 16, 23, 169, 4, 8, 8, 77, 1, 10, 5, 26,
-         16, 60, 4, 0, 24, 37, 55, 6, 11, 4, 0, 28, 0 ], # ra - rz
-       [ 65, 9, 17, 9, 73, 13, 1, 47, 75, 3, 0, 7, 11,
-         12, 56, 17, 6, 9, 48, 116, 35, 1, 28, 0, 4, 0 ], # sa - sz
-       [ 57, 22, 3, 1, 76, 5, 2, 330, 126, 1, 0, 14, 10,
-         6, 79, 7, 0, 49, 50, 56, 21, 2, 27, 0, 24, 0 ], # ta - tz
-       [ 11, 5, 9, 6, 9, 1, 6, 0, 9, 0, 1, 19, 5,
-         31, 1, 15, 0, 47, 39, 31, 0, 3, 0, 0, 0, 0 ], # ua - uz
-       [ 7, 0, 0, 0, 72, 0, 0, 0, 28, 0, 0, 0, 0,
-         0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0 ], # va - vz
-       [ 36, 1, 1, 0, 38, 0, 0, 33, 36, 0, 0, 4, 1,
-         8, 15, 0, 0, 0, 4, 2, 0, 0, 1, 0, 0, 0 ], # wa - wz
-       [ 1, 0, 2, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0,
-         0, 1, 5, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0 ], # xa - xz
-       [ 14, 5, 4, 2, 7, 12, 12, 6, 10, 0, 0, 3, 7,
-         5, 17, 3, 0, 4, 16, 30, 0, 0, 5, 0, 0, 0 ], # ya - yz
-       [ 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
-         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ]; # za - zz
-
-    #We need to know the totals for each row 
-    $row_sums =
-      [ map { my $sum = 0; map { $sum += $_ } @$_; $sum } @$frequency ];
-    
-
-    #Frequency with which a given letter starts a word.
-    $start_freq =
-      [ 1299, 425, 725, 271, 375, 470, 93, 223, 1009, 24, 20, 355, 379,
-       319, 823, 618, 21, 317, 962, 1991, 271, 104, 516, 6, 16, 14 ];
-    
-    $total_sum = 0; map { $total_sum += $_ } @$start_freq;
-    
-    
-    my $length = $min_length + int(rand($max_length-$min_length));
-    
-    my $char = $self->GenerateRandomNextChar($total_sum, $start_freq);
-    my @word = ($char+$a);
-    for (2..$length) {
-       $char = $self->_GenerateRandomNextChar($row_sums->[$char], $frequency->[$char]);
-       push(@word, $char+$a);
-    }
-    
-    #Return the password
-    return pack("C*",@word);
-    
-}
 
+=item Lang
+
+Returns the current value of Lang. 
+(In the database, Lang is stored as varchar(16).)
 
-#A private helper function for RandomPassword
-# Takes a row summary and a frequency chart for the next character to be searched
-sub _GenerateRandomNextChar {
-    my $self = shift;
-    my($all, $freq) = @_;
-    my($pos, $i);
-    
-    for ($pos = int(rand($all)), $i=0;
-        $pos >= $freq->[$i];
-        $pos -= $freq->[$i], $i++) {};
-    
-    return($i);
-}
 
-# }}}
 
-# {{{ sub SetPassword
+=item SetLang VALUE
 
-=head2 SetPassword
 
-Takes a string. Checks the string's length and sets this user's password 
-to that string.
+Set Lang to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Lang will be stored as a varchar(16).)
+
 
 =cut
 
-sub SetPassword {
-    my $self = shift;
-    my $password = shift;
-    
-    unless ($self->CurrentUserCanModify('Password')) {
-       return(0, 'Permission Denied');
-    }
-    
-    if (! $password)  {
-        return(0, "No password set");
-    }
-    elsif (length($password) < $RT::MinimumPasswordLength) {
-        return(0,"Password too short");
-    }
-    else {
-        my $salt = join '', ('.','/',0..9,'A'..'Z','a'..'z')[rand 64, rand 64];
-        return ( $self->SUPER::SetPassword(crypt($password, $salt)) );
-    }   
-    
-}
 
-# }}}
+=item EmailEncoding
+
+Returns the current value of EmailEncoding. 
+(In the database, EmailEncoding is stored as varchar(16).)
 
-# {{{ sub IsPassword 
 
-=head2 IsPassword
 
-Returns true if the passed in value is this user's password.
-Returns undef otherwise.
+=item SetEmailEncoding VALUE
+
+
+Set EmailEncoding to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, EmailEncoding will be stored as a varchar(16).)
+
 
 =cut
 
-sub IsPassword { 
-    my $self = shift;
-    my $value = shift;
-
-    #TODO there isn't any apparent way to legitimately ACL this
-
-    # RT does not allow null passwords 
-    if ((!defined ($value)) or ($value eq '')) {
-       return(undef);
-    } 
-    if ($self->Disabled) {
-       $RT::Logger->info("Disabled user ".$self->Name." tried to log in");
-       return(undef);
-    }
-
-    if ( ($self->__Value('Password') eq '') || 
-         ($self->__Value('Password') eq undef) )  {
-        return(undef);
-     }
-    if ($self->__Value('Password') eq crypt($value, $self->__Value('Password'))) {
-       return (1);
-    }
-    else {
-       return (undef);
-    }
-}
 
-# }}}
+=item WebEncoding
+
+Returns the current value of WebEncoding. 
+(In the database, WebEncoding is stored as varchar(16).)
 
-# {{{ sub SetDisabled
 
-=head2 Sub SetDisabled
 
-Toggles the user's disabled flag.
-If this flag is
-set, all password checks for this user will fail. All ACL checks for this
-user will fail. The user will appear in no user listings.
+=item SetWebEncoding VALUE
 
-=cut 
 
-# }}}
+Set WebEncoding to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, WebEncoding will be stored as a varchar(16).)
 
-# {{{ ACL Related routines
 
-# {{{ GrantQueueRight
+=cut
+
 
-=head2 GrantQueueRight
+=item ExternalContactInfoId
+
+Returns the current value of ExternalContactInfoId. 
+(In the database, ExternalContactInfoId is stored as varchar(100).)
+
+
+
+=item SetExternalContactInfoId VALUE
+
+
+Set ExternalContactInfoId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ExternalContactInfoId will be stored as a varchar(100).)
 
-Grant a queue right to this user.  Takes a paramhash of which the elements
-RightAppliesTo and RightName are important.
 
 =cut
 
-sub GrantQueueRight {
-    
-    my $self = shift;
-    my %args = ( RightScope => 'Queue',
-                RightName => undef,
-                RightAppliesTo => undef,
-                PrincipalType => 'User',
-                PrincipalId => $self->Id,
-                @_);
-   
-    #ACL check handled in ACE.pm
-
-    require RT::ACE;
-
-#    $RT::Logger->debug("$self ->GrantQueueRight right:". $args{'RightName'} .
-#                     " applies to queue ".$args{'RightAppliesTo'}."\n");
-    
-    my $ace = new RT::ACE($self->CurrentUser);
-    
-    return ($ace->Create(%args));
-}
 
-# }}}
+=item ContactInfoSystem
+
+Returns the current value of ContactInfoSystem. 
+(In the database, ContactInfoSystem is stored as varchar(30).)
+
+
 
-# {{{ GrantSystemRight
+=item SetContactInfoSystem VALUE
 
-=head2 GrantSystemRight
 
-Grant a system right to this user. 
-The only element that's important to set is RightName.
+Set ContactInfoSystem to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ContactInfoSystem will be stored as a varchar(30).)
+
 
 =cut
-sub GrantSystemRight {
-    
-    my $self = shift;
-    my %args = ( RightScope => 'System',
-                RightName => undef,
-                RightAppliesTo => 0,
-                PrincipalType => 'User',
-                PrincipalId => $self->Id,
-                @_);
-   
-
-    #ACL check handled in ACE.pm
-
-    require RT::ACE;    
-    my $ace = new RT::ACE($self->CurrentUser);
-    
-    return ($ace->Create(%args));
-}
 
 
-# }}}
+=item ExternalAuthId
+
+Returns the current value of ExternalAuthId. 
+(In the database, ExternalAuthId is stored as varchar(100).)
 
-# {{{ sub HasQueueRight
 
-=head2 HasQueueRight
 
-Takes a paramhash which can contain
-these items:
-    TicketObj => RT::Ticket or QueueObj => RT::Queue or Queue => integer
-    IsRequestor => undef, (for bootstrapping create)
-    Right => 'Right' 
+=item SetExternalAuthId VALUE
 
 
-Returns 1 if this user has the right specified in the paramhash. for the queue
-passed in.
+Set ExternalAuthId to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ExternalAuthId will be stored as a varchar(100).)
 
-Returns undef if they don't
 
 =cut
 
-sub HasQueueRight {
-    my $self = shift;
-    my %args = ( TicketObj => undef,
-                 QueueObj => undef,
-                Queue => undef,
-                IsRequestor => undef,
-                Right => undef,
-                @_);
-    
-    my ($IsRequestor, $IsCc, $IsAdminCc, $IsOwner);
-    
-    if (defined $args{'Queue'}) {
-       $args{'QueueObj'} = new RT::Queue($self->CurrentUser);
-       $args{'QueueObj'}->Load($args{'Queue'});
-    }
-    
-    if (defined $args{'TicketObj'}) {
-       $args{'QueueObj'} = $args{'TicketObj'}->QueueObj();
-    }
-
-    # {{{ Validate and load up the QueueId
-    unless ((defined $args{'QueueObj'}) and ($args{'QueueObj'}->Id)) {
-       require Carp;
-       $RT::Logger->debug(Carp::cluck ("$self->HasQueueRight Couldn't find a queue id"));
-       return undef;
-    }
-
-    # }}}
-
-        
-    # Figure out whether a user has the right we're asking about.
-    # first see if they have the right personally for the queue in question. 
-    my $retval = $self->_HasRight(Scope => 'Queue',
-                                 AppliesTo => $args{'QueueObj'}->Id,
-                                 Right => $args{'Right'},
-                                 IsOwner => $IsOwner);
-
-    return ($retval) if (defined $retval);
-    
-    # then we see whether they have the right personally globally. 
-    $retval = $self->HasSystemRight( $args{'Right'});
-
-    return ($retval) if (defined $retval);
-    
-    # now that we know they don't have the right personally,
-    
-    # {{{ Find out about whether the current user is a Requestor, Cc, AdminCc or Owner
-
-    if (defined $args{'TicketObj'}) {
-       if ($args{'TicketObj'}->IsRequestor($self)) {#user is requestor
-           $IsRequestor = 1;
-       }       
-
-       if ($args{'TicketObj'}->IsCc($self)) { #If user is a cc
-           $IsCc = 1;
-       }
-
-       if ($args{'TicketObj'}->IsAdminCc($self)) { #If user is an admin cc
-           $IsAdminCc = 1;
-       }       
-       
-       if ($args{'TicketObj'}->IsOwner($self)) { #If user is an owner
-           $IsOwner = 1;
-       }
-    }
-    
-    if (defined $args{'QueueObj'}) {
-       if ($args{'QueueObj'}->IsCc($self)) { #If user is a cc
-           $IsCc = 1;
-       }
-       if ($args{'QueueObj'}->IsAdminCc($self)) { #If user is an admin cc
-           $IsAdminCc = 1;
-       }
-       
-    } 
-    # }}}
-    
-    # then see whether they have the right for the queue as a member of a metagroup 
-
-    $retval = $self->_HasRight(Scope => 'Queue',
-                                 AppliesTo => $args{'QueueObj'}->Id,
-                                 Right => $args{'Right'},
-                                 IsOwner => $IsOwner,
-                                 IsCc => $IsCc,
-                                 IsAdminCc => $IsAdminCc,
-                                 IsRequestor => $IsRequestor
-                                );
-
-    return ($retval) if (defined $retval);
-
-    #   then we see whether they have the right globally as a member of a metagroup
-    $retval = $self->HasSystemRight( $args{'Right'},
-                                    (IsOwner => $IsOwner,
-                                     IsCc => $IsCc,
-                                     IsAdminCc => $IsAdminCc,
-                                     IsRequestor => $IsRequestor
-                                    ) );
-
-    #If they haven't gotten it by now, they just lose.
-    return ($retval);
-    
-}
 
-# }}}
-  
-# {{{ sub HasSystemRight
+=item AuthSystem
+
+Returns the current value of AuthSystem. 
+(In the database, AuthSystem is stored as varchar(30).)
+
 
-=head2 HasSystemRight
 
-takes an array of a single value and a paramhash.
-The single argument is the right being passed in.
-the param hash is some additional data. (IsCc, IsOwner, IsAdminCc and IsRequestor)
+=item SetAuthSystem VALUE
+
+
+Set AuthSystem to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, AuthSystem will be stored as a varchar(30).)
 
-Returns 1 if this user has the listed 'right'. Returns undef if this user doesn't.
 
 =cut
 
-sub HasSystemRight {
-    my $self = shift;
-    my $right = shift;
-
-    my %args = ( IsOwner => undef,
-                IsCc => undef,
-                IsAdminCc => undef,
-                IsRequestor => undef,
-                @_);
-    
-    unless (defined $right) {
-
-       $RT::Logger->debug("$self RT::User::HasSystemRight was passed in no right.");
-       return(undef);
-    }  
-    return ( $self->_HasRight ( Scope => 'System',
-                               AppliesTo => '0',
-                               Right => $right,
-                               IsOwner => $args{'IsOwner'},
-                               IsCc => $args{'IsCc'},
-                               IsAdminCc => $args{'IsAdminCc'},
-                               IsRequestor => $args{'IsRequestor'},
-                               
-                             )
-          );
-    
-}
 
-# }}}
+=item Gecos
+
+Returns the current value of Gecos. 
+(In the database, Gecos is stored as varchar(16).)
+
+
 
-# {{{ sub _HasRight
+=item SetGecos VALUE
 
-=head2 sub _HasRight (Right => 'right', Scope => 'scope',  AppliesTo => int, ExtendedPrincipals => SQL)
 
-_HasRight is a private helper method for checking a user's rights. It takes
-several options:
+Set Gecos to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Gecos will be stored as a varchar(16).)
+
+
+=cut
+
 
-=item Right is a textual right name
+=item HomePhone
 
-=item Scope is a textual scope name. (As of July these were Queue, Ticket and System
+Returns the current value of HomePhone. 
+(In the database, HomePhone is stored as varchar(30).)
 
-=item AppliesTo is the numerical Id of the object identified in the scope. For tickets, this is the queue #. for queues, this is the queue #
 
-=item ExtendedPrincipals is an  SQL select clause which assumes that the only
-table in play is ACL.  It's used by HasQueueRight to pass in which 
-metaprincipals apply. Actually, it's probably obsolete. TODO: remove it.
 
-Returns 1 if a matching ACE was found.
+=item SetHomePhone VALUE
+
+
+Set HomePhone to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, HomePhone will be stored as a varchar(30).)
 
-Returns undef if no ACE was found.
 
 =cut
 
 
-sub _HasRight {
-    
-    my $self = shift;
-    my %args = ( Right => undef,
-                Scope => undef,
-                AppliesTo => undef,
-                IsRequestor => undef,
-                IsCc => undef,
-                IsAdminCc => undef,
-                IsOwner => undef,
-                ExtendedPrincipals => undef,
-                @_);
-    
-    if ($self->Disabled) {
-       $RT::Logger->debug ("Disabled User:  ".$self->Name.
-                           " failed access check for ".$args{'Right'}.
-                           " to object ".$args{'Scope'}."/".
-                           $args{'AppliesTo'}."\n");
-       return (undef);
-    }
-    
-    if (!defined $args{'Right'}) {
-       $RT::Logger->debug("_HasRight called without a right\n");
-       return(undef);
-    }
-    elsif (!defined $args{'Scope'}) {
-       $RT::Logger->debug("_HasRight called without a scope\n");
-       return(undef);
-    }
-    elsif (!defined $args{'AppliesTo'}) {
-       $RT::Logger->debug("_HasRight called without an AppliesTo object\n");
-       return(undef);
-    }
-    
-    #If we've cached a win or loss for this lookup say so
-    
-    #TODO Security +++ check to make sure this is complete and right
-    
-    #Construct a hashkey to cache decisions in
-    my ($hashkey);
-    { #it's ugly, but we need to turn off warning, cuz we're joining nulls.
-       local $^W=0;
-       $hashkey =$self->Id .":". join(':',%args);
-    }  
-    
-  # $RT::Logger->debug($hashkey."\n");
-    
-    #Anything older than 10 seconds needs to be rechecked
-    my $cache_timeout = (time - 10);
-    
-    
-    if ((defined $self->{'rights'}{"$hashkey"}) &&
-           ($self->{'rights'}{"$hashkey"} == 1 ) &&
-        (defined $self->{'rights'}{"$hashkey"}{'set'} ) &&
-           ($self->{'rights'}{"$hashkey"}{'set'} > $cache_timeout)) {
-#        $RT::Logger->debug("Cached ACL win for ". 
-#                           $args{'Right'}.$args{'Scope'}.
-#                           $args{'AppliesTo'}."\n");      
-       return ($self->{'rights'}{"$hashkey"});
-    }
-    elsif ((defined $self->{'rights'}{"$hashkey"}) &&
-              ($self->{'rights'}{"$hashkey"} == -1)  &&
-           (defined $self->{'rights'}{"$hashkey"}{'set'}) &&
-              ($self->{'rights'}{"$hashkey"}{'set'} > $cache_timeout)) {
-       
-#      $RT::Logger->debug("Cached ACL loss decision for ". 
-#                         $args{'Right'}.$args{'Scope'}.
-#                         $args{'AppliesTo'}."\n");        
-       
-       return(undef);
-    }
-    
-    
-    my $RightClause = "(RightName = '$args{'Right'}')";
-    my $ScopeClause = "(RightScope = '$args{'Scope'}')";
-    
-    #If an AppliesTo was passed in, we should pay attention to it.
-    #otherwise, none is needed
-    
-    $ScopeClause = "($ScopeClause AND (RightAppliesTo = $args{'AppliesTo'}))"
-      if ($args{'AppliesTo'});
-    
-    
-    # The generic principals clause looks for users with my id
-    # and Rights that apply to _everyone_
-    my $PrincipalsClause = "((PrincipalType = 'User') AND (PrincipalId = ".$self->Id."))";
-    
-    
-    # If the user is the superuser, grant them the damn right ;)
-    my $SuperUserClause = 
-      "(RightName = 'SuperUser') AND (RightScope = 'System') AND (RightAppliesTo = 0)";
-    
-    # If we've been passed in an extended principals clause, we should lump it
-    # on to the existing principals clause. it'll make life easier
-    if ($args{'ExtendedPrincipals'}) {
-       $PrincipalsClause = "(($PrincipalsClause) OR ".
-         "($args{'ExtendedPrincipalsClause'}))";
-    }
-    
-    my $GroupPrincipalsClause = "((ACL.PrincipalType = 'Group') ".
-      "AND (ACL.PrincipalId = Groups.Id) AND (GroupMembers.GroupId = Groups.Id) ".
-     " AND (GroupMembers.UserId = ".$self->Id."))";
-    
-    
-
-
-    # {{{ A bunch of magic statements that make the metagroups listed
-    # work. basically, we if the user falls into the right group,
-    # we add the type of ACL check needed
-    my (@MetaPrincipalsSubClauses, $MetaPrincipalsClause);
-    
-    #The user is always part of the 'Everyone' Group
-    push (@MetaPrincipalsSubClauses,  "((Groups.Name = 'Everyone') AND 
-                                       (PrincipalType = 'Group') AND 
-                                       (Groups.Id = PrincipalId))");
-
-    if ($args{'IsAdminCc'}) {
-       push (@MetaPrincipalsSubClauses,  "((Groups.Name = 'AdminCc') AND 
-                                       (PrincipalType = 'Group') AND 
-                                       (Groups.Id = PrincipalId))");
-    }
-    if ($args{'IsCc'}) {
-       push (@MetaPrincipalsSubClauses, " ((Groups.Name = 'Cc') AND 
-                                       (PrincipalType = 'Group') AND 
-                                       (Groups.Id = PrincipalId))");
-    }
-    if ($args{'IsRequestor'}) {
-       push (@MetaPrincipalsSubClauses,  " ((Groups.Name = 'Requestor') AND 
-                                       (PrincipalType = 'Group') AND 
-                                       (Groups.Id = PrincipalId))");
-    }
-    if ($args{'IsOwner'}) {
-       
-       push (@MetaPrincipalsSubClauses, " ((Groups.Name = 'Owner') AND 
-                                       (PrincipalType = 'Group') AND 
-                                       (Groups.Id = PrincipalId))");
-    }
-
-    # }}}
-    
-    my ($GroupRightsQuery, $MetaGroupRightsQuery, $IndividualRightsQuery, $hitcount);
-    
-    # {{{ If there are any metaprincipals to be checked
-    if (@MetaPrincipalsSubClauses) {
-       #chop off the leading or
-       #TODO redo this with an array and a join
-       $MetaPrincipalsClause = join (" OR ", @MetaPrincipalsSubClauses);
-       
-       $MetaGroupRightsQuery =  "SELECT COUNT(ACL.id) FROM ACL, Groups".
-         " WHERE " .
-           " ($ScopeClause) AND ($RightClause) AND ($MetaPrincipalsClause)";
-       
-       # {{{ deal with checking if the user has a right as a member of a metagroup
-
-#      $RT::Logger->debug("Now Trying $MetaGroupRightsQuery\n");       
-       $hitcount = $self->_Handle->FetchResult($MetaGroupRightsQuery);
-       
-       #if there's a match, the right is granted
-       if ($hitcount) {
-           $self->{'rights'}{"$hashkey"}{'set'} = time;
-           $self->{'rights'}{"$hashkey"} = 1;
-           return (1);
-       }
-       
-#      $RT::Logger->debug("No ACL matched MetaGroups query: $MetaGroupRightsQuery\n"); 
-
-       # }}}    
-       
-    }
-    # }}}
-
-    # {{{ deal with checking if the user has a right as a member of a group
-    # This query checks to se whether the user has the right as a member of a
-    # group
-    $GroupRightsQuery = "SELECT COUNT(ACL.id) FROM ACL, GroupMembers, Groups".
-      " WHERE " .
-       " (((($ScopeClause) AND ($RightClause)) OR ($SuperUserClause)) ".
-         " AND ($GroupPrincipalsClause))";    
-    
-    #  $RT::Logger->debug("Now Trying $GroupRightsQuery\n");   
-    $hitcount = $self->_Handle->FetchResult($GroupRightsQuery);
-    
-    #if there's a match, the right is granted
-    if ($hitcount) {
-       $self->{'rights'}{"$hashkey"}{'set'} = time;
-       $self->{'rights'}{"$hashkey"} = 1;
-       return (1);
-    }
-    
-#    $RT::Logger->debug("No ACL matched $GroupRightsQuery\n"); 
-    
-    # }}}
-
-    # {{{ Check to see whether the user has a right as an individual
-    
-    # This query checks to see whether the current user has the right directly
-    $IndividualRightsQuery = "SELECT COUNT(ACL.id) FROM ACL WHERE ".
-      " ((($ScopeClause) AND ($RightClause)) OR ($SuperUserClause)) " .
-       " AND ($PrincipalsClause)";
-
-    
-    $hitcount = $self->_Handle->FetchResult($IndividualRightsQuery);
-    
-    if ($hitcount) {
-       $self->{'rights'}{"$hashkey"}{'set'} = time;
-       $self->{'rights'}{"$hashkey"} = 1;
-       return (1);
-    }
-    # }}}
-
-    else { #If the user just doesn't have the right
-       
-#      $RT::Logger->debug("No ACL matched $IndividualRightsQuery\n");
-       
-       #If nothing matched, return 0.
-       $self->{'rights'}{"$hashkey"}{'set'} = time;
-       $self->{'rights'}{"$hashkey"} = -1;
-
-       
-       return (undef);
-    }
-}
+=item WorkPhone
+
+Returns the current value of WorkPhone. 
+(In the database, WorkPhone is stored as varchar(30).)
+
+
 
-# }}}
+=item SetWorkPhone VALUE
 
-# {{{ sub CurrentUserCanModify
 
-=head2 CurrentUserCanModify RIGHT
+Set WorkPhone to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, WorkPhone will be stored as a varchar(30).)
 
-If the user has rights for this object, either because
-he has 'AdminUsers' or (if he\'s trying to edit himself and the right isn\'t an 
-admin right) 'ModifySelf', return 1. otherwise, return undef.
 
 =cut
 
-sub CurrentUserCanModify {
-    my $self = shift;
-    my $right = shift;
-
-    if ($self->CurrentUserHasRight('AdminUsers')) {
-       return (1);
-    }
-    #If the field is marked as an "administrators only" field, 
-    # don\'t let the user touch it.
-    elsif ($self->_Accessible($right, 'admin')) {
-       return(undef);
-    }
-    
-    #If the current user is trying to modify themselves
-    elsif ( ($self->id == $self->CurrentUser->id)  and
-           ($self->CurrentUserHasRight('ModifySelf'))) {
-       return(1);
-    }
-    #If we don\'t have a good reason to grant them rights to modify
-    # by now, they lose
-    else {
-       return(undef);
-    }
-    
-}
 
-# }}}
+=item MobilePhone
+
+Returns the current value of MobilePhone. 
+(In the database, MobilePhone is stored as varchar(30).)
+
 
-# {{{ sub CurrentUserHasRight
 
-=head2 CurrentUserHasRight
-  
-  Takes a single argument. returns 1 if $Self->CurrentUser
-  has the requested right. returns undef otherwise
+=item SetMobilePhone VALUE
+
+
+Set MobilePhone to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, MobilePhone will be stored as a varchar(30).)
+
 
 =cut
 
-sub CurrentUserHasRight {
-    my $self = shift;
-    my $right = shift;
-    
-    return ($self->CurrentUser->HasSystemRight($right));
-}
 
-# }}}
+=item PagerPhone
 
+Returns the current value of PagerPhone. 
+(In the database, PagerPhone is stored as varchar(30).)
 
-# {{{ sub _Set
 
-sub _Set {
-  my $self = shift;
-  
-  my %args = (Field => undef,
-             Value => undef,
-             @_
-            );
 
-  # Nobody is allowed to futz with RT_System or Nobody unless they
-  # want to change an email address. For 2.2, neither should have an email address
+=item SetPagerPhone VALUE
 
-  if ($self->Privileged == 2) {
-    return (0, "Can not modify system users"); 
-  }
-  unless ($self->CurrentUserCanModify($args{'Field'})) {
-      return (0, "Permission Denied");
-  }
 
+Set PagerPhone to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, PagerPhone will be stored as a varchar(30).)
+
+
+=cut
+
+
+=item Address1
+
+Returns the current value of Address1. 
+(In the database, Address1 is stored as varchar(200).)
 
-  
-  #Set the new value
-  my ($ret, $msg)=$self->SUPER::_Set(Field => $args{'Field'}, 
-                                    Value=> $args{'Value'});
-  
-    return ($ret, $msg);
-}
 
-# }}}
 
-# {{{ sub _Value 
+=item SetAddress1 VALUE
 
-=head2 _Value
 
-Takes the name of a table column.
-Returns its value as a string, if the user passes an ACL check
+Set Address1 to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Address1 will be stored as a varchar(200).)
+
 
 =cut
 
-sub _Value  {
-
-  my $self = shift;
-  my $field = shift;
-  
-  #If the current user doesn't have ACLs, don't let em at it.  
-  
-  my @PublicFields = qw( Name EmailAddress Organization Disabled
-                        RealName NickName Gecos ExternalAuthId 
-                        AuthSystem ExternalContactInfoId 
-                        ContactInfoSystem );
-
-  #if the field is public, return it.
-  if ($self->_Accessible($field, 'public')) {
-      return($self->SUPER::_Value($field));
-      
-  }
-  #If the user wants to see their own values, let them
-  elsif ($self->CurrentUser->Id == $self->Id) {        
-      return($self->SUPER::_Value($field));
-  } 
-  #If the user has the admin users right, return the field
-  elsif ($self->CurrentUserHasRight('AdminUsers')) {
-      return($self->SUPER::_Value($field));
-  }
-  else {
-      return(undef);
-  }    
 
-}
+=item Address2
+
+Returns the current value of Address2. 
+(In the database, Address2 is stored as varchar(200).)
+
+
+
+=item SetAddress2 VALUE
+
+
+Set Address2 to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Address2 will be stored as a varchar(200).)
+
+
+=cut
+
+
+=item City
+
+Returns the current value of City. 
+(In the database, City is stored as varchar(100).)
+
+
+
+=item SetCity VALUE
+
+
+Set City to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, City will be stored as a varchar(100).)
+
+
+=cut
+
+
+=item State
+
+Returns the current value of State. 
+(In the database, State is stored as varchar(100).)
+
+
+
+=item SetState VALUE
+
+
+Set State to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, State will be stored as a varchar(100).)
+
+
+=cut
+
+
+=item Zip
+
+Returns the current value of Zip. 
+(In the database, Zip is stored as varchar(16).)
+
+
+
+=item SetZip VALUE
+
+
+Set Zip to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Zip will be stored as a varchar(16).)
+
+
+=cut
+
+
+=item Country
+
+Returns the current value of Country. 
+(In the database, Country is stored as varchar(50).)
+
+
+
+=item SetCountry VALUE
+
+
+Set Country to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Country will be stored as a varchar(50).)
+
+
+=cut
+
+
+=item Timezone
+
+Returns the current value of Timezone. 
+(In the database, Timezone is stored as varchar(50).)
+
+
+
+=item SetTimezone VALUE
+
+
+Set Timezone to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Timezone will be stored as a varchar(50).)
+
+
+=cut
+
+
+=item PGPKey
+
+Returns the current value of PGPKey. 
+(In the database, PGPKey is stored as text.)
+
+
+
+=item SetPGPKey VALUE
+
+
+Set PGPKey to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, PGPKey will be stored as a text.)
+
+
+=cut
+
+
+=item Creator
+
+Returns the current value of Creator. 
+(In the database, Creator is stored as int(11).)
+
+
+=cut
+
+
+=item Created
+
+Returns the current value of Created. 
+(In the database, Created is stored as datetime.)
+
+
+=cut
+
+
+=item LastUpdatedBy
+
+Returns the current value of LastUpdatedBy. 
+(In the database, LastUpdatedBy is stored as int(11).)
+
+
+=cut
+
+
+=item LastUpdated
+
+Returns the current value of LastUpdated. 
+(In the database, LastUpdated is stored as datetime.)
+
+
+=cut
+
+
+
+sub _ClassAccessible {
+    {
+     
+        id =>
+               {read => 1, type => 'int(11)', default => ''},
+        Name => 
+               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        Password => 
+               {read => 1, write => 1, type => 'varchar(40)', default => ''},
+        Comments => 
+               {read => 1, write => 1, type => 'blob', default => ''},
+        Signature => 
+               {read => 1, write => 1, type => 'blob', default => ''},
+        EmailAddress => 
+               {read => 1, write => 1, type => 'varchar(120)', default => ''},
+        FreeformContactInfo => 
+               {read => 1, write => 1, type => 'blob', default => ''},
+        Organization => 
+               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        RealName => 
+               {read => 1, write => 1, type => 'varchar(120)', default => ''},
+        NickName => 
+               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+        Lang => 
+               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+        EmailEncoding => 
+               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+        WebEncoding => 
+               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+        ExternalContactInfoId => 
+               {read => 1, write => 1, type => 'varchar(100)', default => ''},
+        ContactInfoSystem => 
+               {read => 1, write => 1, type => 'varchar(30)', default => ''},
+        ExternalAuthId => 
+               {read => 1, write => 1, type => 'varchar(100)', default => ''},
+        AuthSystem => 
+               {read => 1, write => 1, type => 'varchar(30)', default => ''},
+        Gecos => 
+               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+        HomePhone => 
+               {read => 1, write => 1, type => 'varchar(30)', default => ''},
+        WorkPhone => 
+               {read => 1, write => 1, type => 'varchar(30)', default => ''},
+        MobilePhone => 
+               {read => 1, write => 1, type => 'varchar(30)', default => ''},
+        PagerPhone => 
+               {read => 1, write => 1, type => 'varchar(30)', default => ''},
+        Address1 => 
+               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        Address2 => 
+               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        City => 
+               {read => 1, write => 1, type => 'varchar(100)', default => ''},
+        State => 
+               {read => 1, write => 1, type => 'varchar(100)', default => ''},
+        Zip => 
+               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+        Country => 
+               {read => 1, write => 1, type => 'varchar(50)', default => ''},
+        Timezone => 
+               {read => 1, write => 1, type => 'varchar(50)', default => ''},
+        PGPKey => 
+               {read => 1, write => 1, type => 'text', default => ''},
+        Creator => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        Created => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+        LastUpdatedBy => 
+               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        LastUpdated => 
+               {read => 1, auto => 1, type => 'datetime', default => ''},
+
+ }
+};
+
+
+        eval "require RT::User_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/User_Overlay.pm}) {
+            die $@;
+        };
+
+        eval "require RT::User_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/User_Vendor.pm}) {
+            die $@;
+        };
+
+        eval "require RT::User_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/User_Local.pm}) {
+            die $@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+RT::User_Overlay, RT::User_Vendor, RT::User_Local
+
+=cut
 
-# }}}
 
-# }}}
 1;
diff --git a/rt/lib/RT/User_Overlay.pm b/rt/lib/RT/User_Overlay.pm
new file mode 100644 (file)
index 0000000..e828ebd
--- /dev/null
@@ -0,0 +1,1589 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::User - RT User object
+
+=head1 SYNOPSIS
+
+  use RT::User;
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=begin testing
+
+ok(require RT::User);
+
+=end testing
+
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+use vars qw(%_USERS_KEY_CACHE);
+
+%_USERS_KEY_CACHE = ();
+
+use Digest::MD5;
+use RT::Principals;
+use RT::ACE;
+
+
+# {{{ sub _Accessible 
+
+
+sub _ClassAccessible {
+    {
+     
+        id =>
+                {read => 1, type => 'int(11)', default => ''},
+        Name => 
+                {read => 1, write => 1, public => 1, admin => 1, type => 'varchar(120)', default => ''},
+        Password => 
+                { write => 1, type => 'varchar(40)', default => ''},
+        Comments => 
+                {read => 1, write => 1, admin => 1, type => 'blob', default => ''},
+        Signature => 
+                {read => 1, write => 1, type => 'blob', default => ''},
+        EmailAddress => 
+                {read => 1, write => 1, public => 1,  type => 'varchar(120)', default => ''},
+        FreeformContactInfo => 
+                {read => 1, write => 1, type => 'blob', default => ''},
+        Organization => 
+                {read => 1, write => 1, public => 1, admin => 1, type => 'varchar(200)', default => ''},
+        RealName => 
+                {read => 1, write => 1, public => 1, type => 'varchar(120)', default => ''},
+        NickName => 
+                {read => 1, write => 1, public => 1, type => 'varchar(16)', default => ''},
+        Lang => 
+                {read => 1, write => 1, public => 1, type => 'varchar(16)', default => ''},
+        EmailEncoding => 
+                {read => 1, write => 1, public => 1, type => 'varchar(16)', default => ''},
+        WebEncoding => 
+                {read => 1, write => 1, public => 1, type => 'varchar(16)', default => ''},
+        ExternalContactInfoId => 
+                {read => 1, write => 1, public => 1, admin => 1, type => 'varchar(100)', default => ''},
+        ContactInfoSystem => 
+                {read => 1, write => 1, public => 1, admin => 1, type => 'varchar(30)', default => ''},
+        ExternalAuthId => 
+                {read => 1, write => 1, public => 1, admin => 1, type => 'varchar(100)', default => ''},
+        AuthSystem => 
+                {read => 1, write => 1, public => 1, admin => 1,type => 'varchar(30)', default => ''},
+        Gecos => 
+                {read => 1, write => 1, public => 1, admin => 1, type => 'varchar(16)', default => ''},
+
+        PGPKey => {
+                {read => 1, write => 1, public => 1, admin => 1, type => 'text', default => ''},
+        },
+        HomePhone => 
+                {read => 1, write => 1, type => 'varchar(30)', default => ''},
+        WorkPhone => 
+                {read => 1, write => 1, type => 'varchar(30)', default => ''},
+        MobilePhone => 
+                {read => 1, write => 1, type => 'varchar(30)', default => ''},
+        PagerPhone => 
+                {read => 1, write => 1, type => 'varchar(30)', default => ''},
+        Address1 => 
+                {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        Address2 => 
+                {read => 1, write => 1, type => 'varchar(200)', default => ''},
+        City => 
+                {read => 1, write => 1, type => 'varchar(100)', default => ''},
+        State => 
+                {read => 1, write => 1, type => 'varchar(100)', default => ''},
+        Zip => 
+                {read => 1, write => 1, type => 'varchar(16)', default => ''},
+        Country => 
+                {read => 1, write => 1, type => 'varchar(50)', default => ''},
+        Creator => 
+                {read => 1, auto => 1, type => 'int(11)', default => ''},
+        Created => 
+                {read => 1, auto => 1, type => 'datetime', default => ''},
+        LastUpdatedBy => 
+                {read => 1, auto => 1, type => 'int(11)', default => ''},
+        LastUpdated => 
+                {read => 1, auto => 1, type => 'datetime', default => ''},
+
+ }
+};
+
+
+# }}}
+
+# {{{ sub Create 
+
+=head2 Create { PARAMHASH }
+
+
+=begin testing
+
+# Make sure we can create a user
+
+my $u1 = RT::User->new($RT::SystemUser);
+is(ref($u1), 'RT::User');
+my ($id, $msg) = $u1->Create(Name => 'CreateTest1', EmailAddress => 'create-test-1@example.com');
+ok ($id, "Creating user CreateTest1 - " . $msg );
+
+# Make sure we can't create a second user with the same name
+my $u2 = RT::User->new($RT::SystemUser);
+($id, $msg) = $u2->Create(Name => 'CreateTest1', EmailAddress => 'create-test-2@example.com');
+ok (!$id, $msg);
+
+
+# Make sure we can't create a second user with the same EmailAddress address
+my $u3 = RT::User->new($RT::SystemUser);
+($id, $msg) = $u3->Create(Name => 'CreateTest2', EmailAddress => 'create-test-1@example.com');
+ok (!$id, $msg);
+
+# Make sure we can create a user with no EmailAddress address
+my $u4 = RT::User->new($RT::SystemUser);
+($id, $msg) = $u4->Create(Name => 'CreateTest3');
+ok ($id, $msg);
+
+# make sure we can create a second user with no EmailAddress address
+my $u5 = RT::User->new($RT::SystemUser);
+($id, $msg) = $u5->Create(Name => 'CreateTest4');
+ok ($id, $msg);
+
+# make sure we can create a user with a blank EmailAddress address
+my $u6 = RT::User->new($RT::SystemUser);
+($id, $msg) = $u6->Create(Name => 'CreateTest6', EmailAddress => '');
+ok ($id, $msg);
+# make sure we can create a second user with a blankEmailAddress address
+my $u7 = RT::User->new($RT::SystemUser);
+($id, $msg) = $u7->Create(Name => 'CreateTest7', EmailAddress => '');
+ok ($id, $msg);
+
+# Can we change the email address away from from "";
+($id,$msg) = $u7->SetEmailAddress('foo@bar');
+ok ($id, $msg);
+# can we change the address back to "";  
+($id,$msg) = $u7->SetEmailAddress('');
+ok ($id, $msg);
+is ($u7->EmailAddress, '');
+
+
+=end testing
+
+=cut
+
+
+sub Create {
+    my $self = shift;
+    my %args = (
+        Privileged => 0,
+        Disabled => 0,
+        EmailAddress => '',
+        @_    # get the real argumentlist
+    );
+
+
+    $args{'EmailAddress'} = $self->CanonicalizeEmailAddress($args{'EmailAddress'});
+
+    #Check the ACL
+    unless ( $self->CurrentUser->HasRight(Right => 'AdminUsers', Object => $RT::System) ) {
+        return ( 0, $self->loc('No permission to create users') );
+    }
+
+
+    # Privileged is no longer a column in users
+    my $privileged = $args{'Privileged'};
+    delete $args{'Privileged'};
+
+
+    if ($args{'CryptedPassword'} ) {
+        $args{'Password'} = $args{'CryptedPassword'};
+        delete $args{'CryptedPassword'};
+    }
+    elsif ( !$args{'Password'} ) {
+        $args{'Password'} = '*NO-PASSWORD*';
+    }
+    elsif ( length( $args{'Password'} ) < $RT::MinimumPasswordLength ) {
+        return ( 0, $self->loc("Password too short") );
+    }
+
+    else {
+        $args{'Password'} = $self->_GeneratePassword($args{'Password'});
+    }
+
+    #TODO Specify some sensible defaults.
+
+    unless ( defined( $args{'Name'} ) ) {
+        return ( 0, $self->loc("Must specify 'Name' attribute") );
+    }
+
+    #SANITY CHECK THE NAME AND ABORT IF IT'S TAKEN
+    if ($RT::SystemUser) {   #This only works if RT::SystemUser has been defined
+        my $TempUser = RT::User->new($RT::SystemUser);
+        $TempUser->Load( $args{'Name'} );
+        return ( 0, $self->loc('Name in use') ) if ( $TempUser->Id );
+
+        return ( 0, $self->loc('Email address in use') )
+          unless ( $self->ValidateEmailAddress( $args{'EmailAddress'} ) );
+    }
+    else {
+        $RT::Logger->warning( "$self couldn't check for pre-existing users");
+    }
+
+
+    $RT::Handle->BeginTransaction();
+    # Groups deal with principal ids, rather than user ids.
+    # When creating this user, set up a principal Id for it.
+    my $principal = RT::Principal->new($self->CurrentUser);
+    my $principal_id = $principal->Create(PrincipalType => 'User',
+                                Disabled => $args{'Disabled'},
+                                ObjectId => '0');
+    $principal->__Set(Field => 'ObjectId', Value => $principal_id);
+    # If we couldn't create a principal Id, get the fuck out.
+    unless ($principal_id) {
+        $RT::Handle->Rollback();
+        $RT::Logger->crit("Couldn't create a Principal on new user create. Strange things are afoot at the circle K");
+        return ( 0, $self->loc('Could not create user') );
+    }
+
+    delete $args{'Disabled'};
+
+    $self->SUPER::Create(id => $principal_id , %args);
+    my $id = $self->Id;
+
+    #If the create failed.
+    unless ($id) {
+        $RT::Logger->error("Could not create a new user - " .join('-'. %args));
+
+        return ( 0, $self->loc('Could not create user') );
+    }
+
+
+    #TODO post 2.0
+    #if ($args{'SendWelcomeMessage'}) {
+    #  #TODO: Check if the email exists and looks valid
+    #  #TODO: Send the user a "welcome message" 
+    #}
+
+
+
+    my $aclstash = RT::Group->new($self->CurrentUser);
+    my $stash_id = $aclstash->_CreateACLEquivalenceGroup($principal);
+
+    unless ($stash_id) {
+        $RT::Handle->Rollback();
+        $RT::Logger->crit("Couldn't stash the user in groumembers");
+        return ( 0, $self->loc('Could not create user') );
+    }
+
+    $RT::Handle->Commit;
+
+    #$RT::Logger->debug("Adding the user as a member of everyone"); 
+    my $everyone = RT::Group->new($self->CurrentUser);
+    $everyone->LoadSystemInternalGroup('Everyone');
+    $everyone->AddMember($self->PrincipalId);
+
+    if ($privileged)  {
+        my $priv = RT::Group->new($self->CurrentUser);
+        #$RT::Logger->debug("Making ".$self->Id." a privileged user");
+        $priv->LoadSystemInternalGroup('Privileged');
+        $priv->AddMember($self->PrincipalId);  
+    } else {
+        my $unpriv = RT::Group->new($self->CurrentUser);
+        #$RT::Logger->debug("Making ".$self->Id." an unprivileged user");
+        $unpriv->LoadSystemInternalGroup('Unprivileged');
+        $unpriv->AddMember($self->PrincipalId);  
+    }
+
+
+   #  $RT::Logger->debug("Finished creating the user");
+    return ( $id, $self->loc('User created') );
+}
+
+# }}}
+
+
+
+# {{{ SetPrivileged
+
+=head2 SetPrivileged BOOL
+
+If passed a true value, makes this user a member of the "Privileged"  PseudoGroup.
+Otherwise, makes this user a member of the "Unprivileged" pseudogroup. 
+
+Returns a standard RT tuple of (val, msg);
+
+=begin testing
+
+
+ok(my $user = RT::User->new($RT::SystemUser));
+ok($user->Load('root'), "Loaded user 'root'");
+ok($user->Privileged, "User 'root' is privileged");
+ok(my ($v,$m) = $user->SetPrivileged(0));
+ok ($v ==1, "Set unprivileged suceeded ($m)");
+ok(!$user->Privileged, "User 'root' is no longer privileged");
+ok(my ($v2,$m2) = $user->SetPrivileged(1));
+ok ($v2 ==1, "Set privileged suceeded ($m2");
+ok($user->Privileged, "User 'root' is privileged again");
+
+=end testing
+
+=cut
+
+sub SetPrivileged {
+    my $self = shift;
+    my $val = shift;
+
+    my $priv = RT::Group->new($self->CurrentUser);
+    $priv->LoadSystemInternalGroup('Privileged');
+   
+    unless ($priv->Id) {
+        $RT::Logger->crit("Could not find Privileged pseudogroup");
+        return(0,$self->loc("Failed to find 'Privileged' users pseudogroup."));
+    }
+
+    my $unpriv = RT::Group->new($self->CurrentUser);
+    $unpriv->LoadSystemInternalGroup('Unprivileged');
+    unless ($unpriv->Id) {
+        $RT::Logger->crit("Could not find unprivileged pseudogroup");
+        return(0,$self->loc("Failed to find 'Unprivileged' users pseudogroup"));
+    }
+
+    if ($val) {
+        if ($priv->HasMember($self->PrincipalObj)) {
+            #$RT::Logger->debug("That user is already privileged");
+            return (0,$self->loc("That user is already privileged"));
+        }
+        if ($unpriv->HasMember($self->PrincipalObj)) {
+            $unpriv->DeleteMember($self->PrincipalId);
+        } else {
+        # if we had layered transactions, life would be good
+        # sadly, we have to just go ahead, even if something
+        # bogus happened
+            $RT::Logger->crit("User ".$self->Id." is neither privileged nor ".
+                "unprivileged. something is drastically wrong.");
+        }
+        my ($status, $msg) = $priv->AddMember($self->PrincipalId);  
+        if ($status) {
+            return (1, $self->loc("That user is now privileged"));
+        } else {
+            return (0, $msg);
+        }
+    }
+    else {
+        if ($unpriv->HasMember($self->PrincipalObj)) {
+            #$RT::Logger->debug("That user is already unprivileged");
+            return (0,$self->loc("That user is already unprivileged"));
+        }
+        if ($priv->HasMember($self->PrincipalObj)) {
+            $priv->DeleteMember($self->PrincipalId);
+        } else {
+        # if we had layered transactions, life would be good
+        # sadly, we have to just go ahead, even if something
+        # bogus happened
+            $RT::Logger->crit("User ".$self->Id." is neither privileged nor ".
+                "unprivileged. something is drastically wrong.");
+        }
+        my ($status, $msg) = $unpriv->AddMember($self->PrincipalId);  
+        if ($status) {
+            return (1, $self->loc("That user is now unprivileged"));
+        } else {
+            return (0, $msg);
+        }
+    }
+}
+
+# }}}
+
+# {{{ Privileged
+
+=head2 Privileged
+
+Returns true if this user is privileged. Returns undef otherwise.
+
+=cut
+
+sub Privileged {
+    my $self = shift;
+    my $priv = RT::Group->new($self->CurrentUser);
+    $priv->LoadSystemInternalGroup('Privileged');
+    if ($priv->HasMember($self->PrincipalObj)) {
+        return(1);
+    }
+    else {
+        return(undef);
+    }
+}
+
+# }}}
+
+# {{{ sub _BootstrapCreate 
+
+#create a user without validating _any_ data.
+
+#To be used only on database init.
+# We can't localize here because it's before we _have_ a loc framework
+
+sub _BootstrapCreate {
+    my $self = shift;
+    my %args = (@_);
+
+    $args{'Password'} = '*NO-PASSWORD*';
+
+
+    $RT::Handle->BeginTransaction(); 
+
+    # Groups deal with principal ids, rather than user ids.
+    # When creating this user, set up a principal Id for it.
+    my $principal = RT::Principal->new($self->CurrentUser);
+    my $principal_id = $principal->Create(PrincipalType => 'User', ObjectId => '0');
+    $principal->__Set(Field => 'ObjectId', Value => $principal_id);
+   
+    # If we couldn't create a principal Id, get the fuck out.
+    unless ($principal_id) {
+        $RT::Handle->Rollback();
+        $RT::Logger->crit("Couldn't create a Principal on new user create. Strange things are afoot at the circle K");
+        return ( 0, 'Could not create user' );
+    }
+    $self->SUPER::Create(id => $principal_id, %args);
+    my $id = $self->Id;
+    #If the create failed.
+      unless ($id) {
+      $RT::Handle->Rollback();
+      return ( 0, 'Could not create user' ) ; #never loc this
+    }
+
+    my $aclstash = RT::Group->new($self->CurrentUser);
+    my $stash_id  = $aclstash->_CreateACLEquivalenceGroup($principal);
+
+    unless ($stash_id) {
+        $RT::Handle->Rollback();
+        $RT::Logger->crit("Couldn't stash the user in groupmembers");
+        return ( 0, $self->loc('Could not create user') );
+    }
+
+                                    
+    $RT::Handle->Commit();
+
+    return ( $id, 'User created' );
+}
+
+# }}}
+
+# {{{ sub Delete 
+
+sub Delete {
+    my $self = shift;
+
+    return ( 0, $self->loc('Deleting this object would violate referential integrity') );
+
+}
+
+# }}}
+
+# {{{ sub Load 
+
+=head2 Load
+
+Load a user object from the database. Takes a single argument.
+If the argument is numerical, load by the column 'id'. Otherwise, load by
+the "Name" column which is the user's textual username.
+
+=cut
+
+sub Load {
+    my $self       = shift;
+    my $identifier = shift || return undef;
+
+    #if it's an int, load by id. otherwise, load by name.
+    if ( $identifier !~ /\D/ ) {
+        $self->SUPER::LoadById($identifier);
+    }
+    else {
+        $self->LoadByCol( "Name", $identifier );
+    }
+}
+
+# }}}
+
+# {{{ sub LoadByEmail
+
+=head2 LoadByEmail
+
+Tries to load this user object from the database by the user's email address.
+
+
+=cut
+
+sub LoadByEmail {
+    my $self    = shift;
+    my $address = shift;
+
+    # Never load an empty address as an email address.
+    unless ($address) {
+        return (undef);
+    }
+
+    $address = $self->CanonicalizeEmailAddress($address);
+
+    #$RT::Logger->debug("Trying to load an email address: $address\n");
+    return $self->LoadByCol( "EmailAddress", $address );
+}
+
+# }}}
+
+# {{{ LoadOrCreateByEmail 
+
+=head2 LoadOrCreateByEmail ADDRESS
+
+Attempts to find a user who has the provided email address. If that fails, creates an unprivileged user with
+the provided email address. and loads them.
+
+Returns a tuple of the user's id and a status message.
+0 will be returned in place of the user's id in case of failure.
+
+=cut
+
+sub LoadOrCreateByEmail {
+    my $self = shift;
+    my $email = shift;
+
+        my ($val, $message);
+
+        $self->LoadByEmail($email);
+        $message = $self->loc('User loaded');
+        unless ($self->Id) {
+            ( $val, $message ) = $self->Create(
+                Name => $email,
+                EmailAddress => $email,
+                RealName     => $email,
+                Privileged   => 0,
+                Comments     => 'Autocreated when added as a watcher');
+            unless ($val) {
+                # Deal with the race condition of two account creations at once
+                $self->LoadByEmail($email);
+                unless ($self->Id) {
+                    sleep 5;
+                    $self->LoadByEmail($email);
+                }
+                if ($self->Id) {
+                    $RT::Logger->error("Recovered from creation failure due to race condition");
+                    $message = $self->loc("User loaded");
+                }
+                else {
+                    $RT::Logger->crit("Failed to create user ".$email .": " .$message);
+                }
+            }
+        }
+
+        if ($self->Id) {
+            return($self->Id, $message);
+        }
+        else {
+            return(0, $message);
+        }
+
+
+    }
+
+# }}}
+
+# {{{ sub ValidateEmailAddress
+
+=head2 ValidateEmailAddress ADDRESS
+
+Returns true if the email address entered is not in use by another user or is 
+undef or ''. Returns false if it's in use. 
+
+=cut
+
+sub ValidateEmailAddress {
+    my $self  = shift;
+    my $Value = shift;
+
+    # if the email address is null, it's always valid
+    return (1) if ( !$Value || $Value eq "" );
+
+    my $TempUser = RT::User->new($RT::SystemUser);
+    $TempUser->LoadByEmail($Value);
+
+    if ( $TempUser->id && ( $TempUser->id != $self->id ) )
+    {    # if we found a user with that address
+            # it's invalid to set this user's address to it
+        return (undef);
+    }
+    else {    #it's a valid email address
+        return (1);
+    }
+}
+
+# }}}
+
+# {{{ sub CanonicalizeEmailAddress
+
+
+
+=item CanonicalizeEmailAddress ADDRESS
+
+# CanonicalizeEmailAddress converts email addresses into canonical form.
+# it takes one email address in and returns the proper canonical
+# form. You can dump whatever your proper local config is in here
+
+=cut
+
+sub CanonicalizeEmailAddress {
+    my $self = shift;
+    my $email = shift;
+    # Example: the following rule would treat all email
+    # coming from a subdomain as coming from second level domain
+    # foo.com
+    if ($RT::CanonicalizeEmailAddressMatch && $RT::CanonicalizeEmailAddressReplace ) {
+        $email =~ s/$RT::CanonicalizeEmailAddressMatch/$RT::CanonicalizeEmailAddressReplace/gi;
+    }
+    return ($email);
+}
+
+
+# }}}
+
+
+# {{{ Password related functions
+
+# {{{ sub SetRandomPassword
+
+=head2 SetRandomPassword
+
+Takes no arguments. Returns a status code and a new password or an error message.
+If the status is 1, the second value returned is the new password.
+If the status is anything else, the new value returned is the error code.
+
+=cut
+
+sub SetRandomPassword {
+    my $self = shift;
+
+    unless ( $self->CurrentUserCanModify('Password') ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+    my $pass = $self->GenerateRandomPassword( 6, 8 );
+
+    # If we have "notify user on 
+
+    my ( $val, $msg ) = $self->SetPassword($pass);
+
+    #If we got an error return the error.
+    return ( 0, $msg ) unless ($val);
+
+    #Otherwise, we changed the password, lets return it.
+    return ( 1, $pass );
+
+}
+
+# }}}
+
+# {{{ sub ResetPassword
+
+=head2 ResetPassword
+
+Returns status, [ERROR or new password].  Resets this user\'s password to
+a randomly generated pronouncable password and emails them, using a 
+global template called "RT_PasswordChange", which can be overridden
+with global templates "RT_PasswordChange_Privileged" or "RT_PasswordChange_NonPrivileged" 
+for privileged and Non-privileged users respectively.
+
+=cut
+
+sub ResetPassword {
+    my $self = shift;
+
+    unless ( $self->CurrentUserCanModify('Password') ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+    my ( $status, $pass ) = $self->SetRandomPassword();
+
+    unless ($status) {
+        return ( 0, "$pass" );
+    }
+
+    my $template = RT::Template->new( $self->CurrentUser );
+
+    if ( $self->IsPrivileged ) {
+        $template->LoadGlobalTemplate('RT_PasswordChange_Privileged');
+    }
+    else {
+        $template->LoadGlobalTemplate('RT_PasswordChange_Privileged');
+    }
+
+    unless ( $template->Id ) {
+        $template->LoadGlobalTemplate('RT_PasswordChange');
+    }
+
+    unless ( $template->Id ) {
+        $RT::Logger->crit( "$self tried to send "
+              . $self->Name
+              . " a password reminder "
+              . "but couldn't find a password change template" );
+    }
+
+    my $notification = RT::Action::SendPasswordEmail->new(
+        TemplateObj => $template,
+        Argument    => $pass
+    );
+
+    $notification->SetTo( $self->EmailAddress );
+
+    my ($ret);
+    $ret = $notification->Prepare();
+    if ($ret) {
+        $ret = $notification->Commit();
+    }
+
+    if ($ret) {
+        return ( 1, $self->loc('New password notification sent') );
+    }
+    else {
+        return ( 0, $self->loc('Notification could not be sent') );
+    }
+
+}
+
+# }}}
+
+# {{{ sub GenerateRandomPassword
+
+=head2 GenerateRandomPassword MIN_LEN and MAX_LEN
+
+Returns a random password between MIN_LEN and MAX_LEN characters long.
+
+=cut
+
+sub GenerateRandomPassword {
+    my $self       = shift;
+    my $min_length = shift;
+    my $max_length = shift;
+
+    #This code derived from mpw.pl, a bit of code with a sordid history
+    # Its notes: 
+
+    # Perl cleaned up a bit by Jesse Vincent 1/14/2001.
+    # Converted to perl from C by Marc Horowitz, 1/20/2000.
+    # Converted to C from Multics PL/I by Bill Sommerfeld, 4/21/86.
+    # Original PL/I version provided by Jerry Saltzer.
+
+    my ( $frequency, $start_freq, $total_sum, $row_sums );
+
+    #When munging characters, we need to know where to start counting letters from
+    my $a = ord('a');
+
+    # frequency of English digraphs (from D Edwards 1/27/66) 
+    $frequency = [
+        [
+            4, 20, 28, 52, 2,  11,  28, 4,  32, 4, 6, 62, 23, 167,
+            2, 14, 0,  83, 76, 127, 7,  25, 8,  1, 9, 1
+        ],    # aa - az
+        [
+            13, 0, 0, 0,  55, 0, 0,  0, 8, 2, 0,  22, 0, 0,
+            11, 0, 0, 15, 4,  2, 13, 0, 0, 0, 15, 0
+        ],    # ba - bz
+        [
+            32, 0, 7, 1,  69, 0,  0,  33, 17, 0, 10, 9, 1, 0,
+            50, 3, 0, 10, 0,  28, 11, 0,  0,  0, 3,  0
+        ],    # ca - cz
+        [
+            40, 16, 9, 5,  65, 18, 3,  9, 56, 0, 1, 4, 15, 6,
+            16, 4,  0, 21, 18, 53, 19, 5, 15, 0, 3, 0
+        ],    # da - dz
+        [
+            84, 20, 55, 125, 51, 40, 19, 16,  50,  1,
+            4,  55, 54, 146, 35, 37, 6,  191, 149, 65,
+            9,  26, 21, 12,  5,  0
+        ],    # ea - ez
+        [
+            19, 3, 5, 1,  19, 21, 1, 3, 30, 2, 0, 11, 1, 0,
+            51, 0, 0, 26, 8,  47, 6, 3, 3,  0, 2, 0
+        ],    # fa - fz
+        [
+            20, 4, 3, 2,  35, 1,  3, 15, 18, 0, 0, 5, 1, 4,
+            21, 1, 1, 20, 9,  21, 9, 0,  5,  0, 1, 0
+        ],    # ga - gz
+        [
+            101, 1, 3, 0, 270, 5,  1, 6, 57, 0, 0, 0, 3, 2,
+            44,  1, 0, 3, 10,  18, 6, 0, 5,  0, 3, 0
+        ],    # ha - hz
+        [
+            40, 7,  51, 23, 25, 9,   11, 3,  0, 0, 2, 38, 25, 202,
+            56, 12, 1,  46, 79, 117, 1,  22, 0, 4, 0, 3
+        ],    # ia - iz
+        [
+            3, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+            4, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0
+        ],    # ja - jz
+        [
+            1, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 0, 2,
+            0, 0, 0, 0, 6,  2, 1, 0, 2,  0, 1, 0
+        ],    # ka - kz
+        [
+            44, 2, 5, 12, 62, 7,  5, 2, 42, 1, 1,  53, 2, 2,
+            25, 1, 1, 2,  16, 23, 9, 0, 1,  0, 33, 0
+        ],    # la - lz
+        [
+            52, 14, 1, 0, 64, 0, 0, 3, 37, 0, 0, 0, 7, 1,
+            17, 18, 1, 2, 12, 3, 8, 0, 1,  0, 2, 0
+        ],    # ma - mz
+        [
+            42, 10, 47, 122, 63, 19, 106, 12, 30, 1,
+            6,  6,  9,  7,   54, 7,  1,   7,  44, 124,
+            6,  1,  15, 0,   12, 0
+        ],    # na - nz
+        [
+            7,  12, 14, 17, 5,  95, 3,  5,  14, 0, 0, 19, 41, 134,
+            13, 23, 0,  91, 23, 42, 55, 16, 28, 0, 4, 1
+        ],    # oa - oz
+        [
+            19, 1, 0, 0,  37, 0, 0, 4, 8, 0, 0, 15, 1, 0,
+            27, 9, 0, 33, 14, 7, 6, 0, 0, 0, 0, 0
+        ],    # pa - pz
+        [
+            0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0
+        ],    # qa - qz
+        [
+            83, 8, 16, 23, 169, 4,  8, 8,  77, 1, 10, 5, 26, 16,
+            60, 4, 0,  24, 37,  55, 6, 11, 4,  0, 28, 0
+        ],    # ra - rz
+        [
+            65, 9,  17, 9, 73, 13,  1,  47, 75, 3, 0, 7, 11, 12,
+            56, 17, 6,  9, 48, 116, 35, 1,  28, 0, 4, 0
+        ],    # sa - sz
+        [
+            57, 22, 3,  1, 76, 5, 2, 330, 126, 1,
+            0,  14, 10, 6, 79, 7, 0, 49,  50,  56,
+            21, 2,  27, 0, 24, 0
+        ],    # ta - tz
+        [
+            11, 5,  9, 6,  9,  1,  6, 0, 9, 0, 1, 19, 5, 31,
+            1,  15, 0, 47, 39, 31, 0, 3, 0, 0, 0, 0
+        ],    # ua - uz
+        [
+            7, 0, 0, 0, 72, 0, 0, 0, 28, 0, 0, 0, 0, 0,
+            5, 0, 0, 0, 0,  0, 0, 0, 0,  0, 3, 0
+        ],    # va - vz
+        [
+            36, 1, 1, 0, 38, 0, 0, 33, 36, 0, 0, 4, 1, 8,
+            15, 0, 0, 0, 4,  2, 0, 0,  1,  0, 0, 0
+        ],    # wa - wz
+        [
+            1, 0, 2, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0,
+            1, 5, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0
+        ],    # xa - xz
+        [
+            14, 5, 4, 2, 7,  12, 12, 6, 10, 0, 0, 3, 7, 5,
+            17, 3, 0, 4, 16, 30, 0,  0, 5,  0, 0, 0
+        ],    # ya - yz
+        [
+            1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+        ]
+    ];    # za - zz
+
+    #We need to know the totals for each row 
+    $row_sums = [
+        map {
+            my $sum = 0;
+            map { $sum += $_ } @$_;
+            $sum;
+          } @$frequency
+    ];
+
+    #Frequency with which a given letter starts a word.
+    $start_freq = [
+        1299, 425, 725, 271, 375, 470, 93, 223, 1009, 24,
+        20,   355, 379, 319, 823, 618, 21, 317, 962,  1991,
+        271,  104, 516, 6,   16,  14
+    ];
+
+    $total_sum = 0;
+    map { $total_sum += $_ } @$start_freq;
+
+    my $length = $min_length + int( rand( $max_length - $min_length ) );
+
+    my $char = $self->GenerateRandomNextChar( $total_sum, $start_freq );
+    my @word = ( $char + $a );
+    for ( 2 .. $length ) {
+        $char =
+          $self->_GenerateRandomNextChar( $row_sums->[$char],
+            $frequency->[$char] );
+        push ( @word, $char + $a );
+    }
+
+    #Return the password
+    return pack( "C*", @word );
+
+}
+
+#A private helper function for RandomPassword
+# Takes a row summary and a frequency chart for the next character to be searched
+sub _GenerateRandomNextChar {
+    my $self = shift;
+    my ( $all, $freq ) = @_;
+    my ( $pos, $i );
+
+    for ( $pos = int( rand($all) ), $i = 0 ;
+        $pos >= $freq->[$i] ;
+        $pos -= $freq->[$i], $i++ )
+    {
+    }
+
+    return ($i);
+}
+
+# }}}
+
+# {{{ sub SetPassword
+
+=head2 SetPassword
+
+Takes a string. Checks the string's length and sets this user's password 
+to that string.
+
+=cut
+
+sub SetPassword {
+    my $self     = shift;
+    my $password = shift;
+
+    unless ( $self->CurrentUserCanModify('Password') ) {
+        return ( 0, $self->loc('Permission Denied') );
+    }
+
+    if ( !$password ) {
+        return ( 0, $self->loc("No password set") );
+    }
+    elsif ( length($password) < $RT::MinimumPasswordLength ) {
+        return ( 0, $self->loc("Password too short") );
+    }
+    else {
+        $password = $self->_GeneratePassword($password);
+        return ( $self->SUPER::SetPassword( $password));
+    }
+
+}
+
+=head2 _GeneratePassword PASSWORD
+
+returns an MD5 hash of the password passed in, in base64 encoding.
+
+=cut
+
+sub _GeneratePassword {
+    my $self = shift;
+    my $password = shift;
+
+    my $md5 = Digest::MD5->new();
+    $md5->add($password);
+    return ($md5->b64digest);
+
+}
+
+# }}}
+
+# {{{ sub IsPassword 
+
+=head2 IsPassword
+
+Returns true if the passed in value is this user's password.
+Returns undef otherwise.
+
+=cut
+
+sub IsPassword {
+    my $self  = shift;
+    my $value = shift;
+
+    #TODO there isn't any apparent way to legitimately ACL this
+
+    # RT does not allow null passwords 
+    if ( ( !defined($value) ) or ( $value eq '' ) ) {
+        return (undef);
+    }
+
+   if ( $self->PrincipalObj->Disabled ) {
+        $RT::Logger->info(
+            "Disabled user " . $self->Name . " tried to log in" );
+        return (undef);
+    }
+
+    if ( ($self->__Value('Password') eq '') || 
+         ($self->__Value('Password') eq undef) )  {
+        return(undef);
+     }
+
+    # generate an md5 password 
+    if ($self->_GeneratePassword($value) eq $self->__Value('Password')) {
+        return(1);
+    }
+
+    #  if it's a historical password we say ok.
+
+    if ( $self->__Value('Password') eq crypt( $value, $self->__Value('Password') ) ) {
+        return (1);
+    }
+
+    # no password check has succeeded. get out
+
+    return (undef);
+}
+
+# }}}
+
+# }}}
+
+# {{{ sub SetDisabled
+
+=head2 Sub SetDisabled
+
+Toggles the user's disabled flag.
+If this flag is
+set, all password checks for this user will fail. All ACL checks for this
+user will fail. The user will appear in no user listings.
+
+=cut 
+
+# }}}
+
+sub SetDisabled {
+    my $self = shift;
+    unless ( $self->CurrentUser->HasRight(Right => 'AdminUsers', Object => $RT::System) ) {
+        return (0, $self->loc('Permission Denied'));
+    }
+    return $self->PrincipalObj->SetDisabled(@_);
+}
+
+sub Disabled {
+    my $self = shift;
+    return $self->PrincipalObj->Disabled(@_);
+}
+
+
+# {{{ Principal related routines
+
+=head2 PrincipalObj 
+
+Returns the principal object for this user. returns an empty RT::Principal
+if there's no principal object matching this user. 
+The response is cached. PrincipalObj should never ever change.
+
+=begin testing
+
+ok(my $u = RT::User->new($RT::SystemUser));
+ok($u->Load(1), "Loaded the first user");
+ok($u->PrincipalObj->ObjectId == 1, "user 1 is the first principal");
+ok($u->PrincipalObj->PrincipalType eq 'User' , "Principal 1 is a user, not a group");
+
+=end testing
+
+=cut
+
+
+sub PrincipalObj {
+    my $self = shift;
+    unless ($self->{'PrincipalObj'} && 
+            ($self->{'PrincipalObj'}->ObjectId == $self->Id) &&
+            ($self->{'PrincipalObj'}->PrincipalType eq 'User')) {
+
+            $self->{'PrincipalObj'} = RT::Principal->new($self->CurrentUser);
+            $self->{'PrincipalObj'}->LoadByCols('ObjectId' => $self->Id,
+                                                'PrincipalType' => 'User') ;
+            }
+    return($self->{'PrincipalObj'});
+}
+
+
+=head2 PrincipalId  
+
+Returns this user's PrincipalId
+
+=cut
+
+sub PrincipalId {
+    my $self = shift;
+    return $self->Id;
+}
+
+# }}}
+
+
+
+# {{{ sub HasGroupRight
+
+=head2 HasGroupRight
+
+Takes a paramhash which can contain
+these items:
+    GroupObj => RT::Group or Group => integer
+    Right => 'Right' 
+
+
+Returns 1 if this user has the right specified in the paramhash for the Group
+passed in.
+
+Returns undef if they don't.
+
+=cut
+
+sub HasGroupRight {
+    my $self = shift;
+    my %args = (
+        GroupObj    => undef,
+        Group       => undef,
+        Right       => undef,
+        @_
+    );
+
+
+    if ( defined $args{'Group'} ) {
+        $args{'GroupObj'} = RT::Group->new( $self->CurrentUser );
+        $args{'GroupObj'}->Load( $args{'Group'} );
+    }
+
+    # {{{ Validate and load up the GroupId
+    unless ( ( defined $args{'GroupObj'} ) and ( $args{'GroupObj'}->Id ) ) {
+        return undef;
+    }
+
+    # }}}
+
+
+    # Figure out whether a user has the right we're asking about.
+    my $retval = $self->HasRight(
+        Object => $args{'GroupObj'},
+        Right     => $args{'Right'},
+    );
+
+    return ($retval);
+
+
+}
+
+# }}}
+
+# {{{ sub Rights testing
+
+=head2 Rights testing
+
+
+=begin testing
+
+my $root = RT::User->new($RT::SystemUser);
+$root->Load('root');
+ok($root->Id, "Found the root user");
+my $rootq = RT::Queue->new($root);
+$rootq->Load(1);
+ok($rootq->Id, "Loaded the first queue");
+
+ok ($rootq->CurrentUser->HasRight(Right=> 'CreateTicket', Object => $rootq), "Root can create tickets");
+
+my $new_user = RT::User->new($RT::SystemUser);
+my ($id, $msg) = $new_user->Create(Name => 'ACLTest');
+
+ok ($id, "Created a new user for acl test $msg");
+
+my $q = RT::Queue->new($new_user);
+$q->Load(1);
+ok($q->Id, "Loaded the first queue");
+
+
+ok (!$q->CurrentUser->HasRight(Right => 'CreateTicket', Object => $q), "Some random user doesn't have the right to create tickets");
+ok (my ($gval, $gmsg) = $new_user->PrincipalObj->GrantRight( Right => 'CreateTicket', Object => $q), "Granted the random user the right to create tickets");
+ok ($gval, "Grant succeeded - $gmsg");
+
+
+ok ($q->CurrentUser->HasRight(Right => 'CreateTicket', Object => $q), "The user can create tickets after we grant him the right");
+ok (my ($gval, $gmsg) = $new_user->PrincipalObj->RevokeRight( Right => 'CreateTicket', Object => $q), "revoked the random user the right to create tickets");
+ok ($gval, "Revocation succeeded - $gmsg");
+ok (!$q->CurrentUser->HasRight(Right => 'CreateTicket', Object => $q), "The user can't create tickets anymore");
+
+
+
+
+
+# Create a ticket in the queue
+my $new_tick = RT::Ticket->new($RT::SystemUser);
+my ($tickid, $tickmsg) = $new_tick->Create(Subject=> 'ACL Test', Queue => 'General');
+ok($tickid, "Created ticket: $tickid");
+# Make sure the user doesn't have the right to modify tickets in the queue
+ok (!$new_user->HasRight( Object => $new_tick, Right => 'ModifyTicket'), "User can't modify the ticket without group membership");
+# Create a new group
+my $group = RT::Group->new($RT::SystemUser);
+$group->CreateUserDefinedGroup(Name => 'ACLTest');
+ok($group->Id, "Created a new group Ok");
+# Grant a group the right to modify tickets in a queue
+ok(my ($gv,$gm) = $group->PrincipalObj->GrantRight( Object => $q, Right => 'ModifyTicket'),"Granted the group the right to modify tickets");
+ok($gv,"Grant succeeed - $gm");
+# Add the user to the group
+ok( my ($aid, $amsg) = $group->AddMember($new_user->PrincipalId), "Added the member to the group");
+ok ($aid, "Member added to group: $amsg");
+# Make sure the user does have the right to modify tickets in the queue
+ok ($new_user->HasRight( Object => $new_tick, Right => 'ModifyTicket'), "User can modify the ticket with group membership");
+
+
+# Remove the user from the group
+ok( my ($did, $dmsg) = $group->DeleteMember($new_user->PrincipalId), "Deleted the member from the group");
+ok ($did,"Deleted the group member: $dmsg");
+# Make sure the user doesn't have the right to modify tickets in the queue
+ok (!$new_user->HasRight( Object => $new_tick, Right => 'ModifyTicket'), "User can't modify the ticket without group membership");
+
+
+my $q_as_system = RT::Queue->new($RT::SystemUser);
+$q_as_system->Load(1);
+ok($q_as_system->Id, "Loaded the first queue");
+
+# Create a ticket in the queue
+my $new_tick2 = RT::Ticket->new($RT::SystemUser);
+my ($tick2id, $tickmsg) = $new_tick2->Create(Subject=> 'ACL Test 2', Queue =>$q_as_system->Id);
+ok($tick2id, "Created ticket: $tick2id");
+ok($new_tick2->QueueObj->id eq $q_as_system->Id, "Created a new ticket in queue 1");
+
+
+# make sure that the user can't do this without subgroup membership
+ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket without group membership");
+
+# Create a subgroup
+my $subgroup = RT::Group->new($RT::SystemUser);
+$subgroup->CreateUserDefinedGroup(Name => 'Subgrouptest');
+ok($subgroup->Id, "Created a new group ".$subgroup->Id."Ok");
+#Add the subgroup as a subgroup of the group
+my ($said, $samsg) =  $group->AddMember($subgroup->PrincipalId);
+ok ($said, "Added the subgroup as a member of the group");
+# Add the user to a subgroup of the group
+
+my ($usaid, $usamsg) =  $subgroup->AddMember($new_user->PrincipalId);
+ok($usaid,"Added the user ".$new_user->Id."to the subgroup");
+# Make sure the user does have the right to modify tickets in the queue
+ok ($new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can modify the ticket with subgroup membership");
+
+#  {{{ Deal with making sure that members of subgroups of a disabled group don't have rights
+
+my ($id, $msg);
+ ($id, $msg) =  $group->SetDisabled(1);
+ ok ($id,$msg);
+ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket when the group ".$group->Id. " is disabled");
+ ($id, $msg) =  $group->SetDisabled(0);
+ok($id,$msg);
+# Test what happens when we disable the group the user is a member of directly
+
+($id, $msg) =  $subgroup->SetDisabled(1);
+ ok ($id,$msg);
+ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket when the group ".$subgroup->Id. " is disabled");
+ ($id, $msg) =  $subgroup->SetDisabled(0);
+ ok ($id,$msg);
+ok ($new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can modify the ticket without group membership");
+
+# }}}
+
+
+my ($usrid, $usrmsg) =  $subgroup->DeleteMember($new_user->PrincipalId);
+ok($usrid,"removed the user from the group - $usrmsg");
+# Make sure the user doesn't have the right to modify tickets in the queue
+ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket without group membership");
+
+#revoke the right to modify tickets in a queue
+ok(($gv,$gm) = $group->PrincipalObj->RevokeRight( Object => $q, Right => 'ModifyTicket'),"Granted the group the right to modify tickets");
+ok($gv,"revoke succeeed - $gm");
+
+# {{{ Test the user's right to modify a ticket as a _queue_ admincc for a right granted at the _queue_ level
+
+# Grant queue admin cc the right to modify ticket in the queue 
+ok(my ($qv,$qm) = $q_as_system->AdminCc->PrincipalObj->GrantRight( Object => $q_as_system, Right => 'ModifyTicket'),"Granted the queue adminccs the right to modify tickets");
+ok($qv, "Granted the right successfully - $qm");
+
+# Add the user as a queue admincc
+ok ((my $add_id, $add_msg) = $q_as_system->AddWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId)  , "Added the new user as a queue admincc");
+ok ($add_id, "the user is now a queue admincc - $add_msg");
+
+# Make sure the user does have the right to modify tickets in the queue
+ok ($new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can modify the ticket as an admincc");
+# Remove the user from the role  group
+ok ((my $del_id, $del_msg) = $q_as_system->DeleteWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId)  , "Deleted the new user as a queue admincc");
+
+# Make sure the user doesn't have the right to modify tickets in the queue
+ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket without group membership");
+
+# }}}
+
+# {{{ Test the user's right to modify a ticket as a _ticket_ admincc with the right granted at the _queue_ level
+
+# Add the user as a ticket admincc
+ok ((my $uadd_id, $uadd_msg) = $new_tick2->AddWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId)  , "Added the new user as a queue admincc");
+ok ($add_id, "the user is now a queue admincc - $add_msg");
+
+# Make sure the user does have the right to modify tickets in the queue
+ok ($new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can modify the ticket as an admincc");
+
+# Remove the user from the role  group
+ok ((my $del_id, $del_msg) = $new_tick2->DeleteWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId)  , "Deleted the new user as a queue admincc");
+
+# Make sure the user doesn't have the right to modify tickets in the queue
+ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket without group membership");
+
+
+# Revoke the right to modify ticket in the queue 
+ok(my ($rqv,$rqm) = $q_as_system->AdminCc->PrincipalObj->RevokeRight( Object => $q_as_system, Right => 'ModifyTicket'),"Revokeed the queue adminccs the right to modify tickets");
+ok($rqv, "Revoked the right successfully - $rqm");
+
+# }}}
+
+
+
+# {{{ Test the user's right to modify a ticket as a _queue_ admincc for a right granted at the _system_ level
+
+# Before we start Make sure the user does not have the right to modify tickets in the queue
+ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can not modify the ticket without it being granted");
+ok (!$new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket'), "User can not modify tickets in the queue without it being granted");
+
+# Grant queue admin cc the right to modify ticket in the queue 
+ok(my ($qv,$qm) = $q_as_system->AdminCc->PrincipalObj->GrantRight( Object => $RT::System, Right => 'ModifyTicket'),"Granted the queue adminccs the right to modify tickets");
+ok($qv, "Granted the right successfully - $qm");
+
+# Make sure the user can't modify the ticket before they're added as a watcher
+ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can not modify the ticket without being an admincc");
+ok (!$new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket'), "User can not modify tickets in the queue without being an admincc");
+
+# Add the user as a queue admincc
+ok ((my $add_id, $add_msg) = $q_as_system->AddWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId)  , "Added the new user as a queue admincc");
+ok ($add_id, "the user is now a queue admincc - $add_msg");
+
+# Make sure the user does have the right to modify tickets in the queue
+ok ($new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can modify the ticket as an admincc");
+ok ($new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket'), "User can modify tickets in the queue as an admincc");
+# Remove the user from the role  group
+ok ((my $del_id, $del_msg) = $q_as_system->DeleteWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId)  , "Deleted the new user as a queue admincc");
+
+# Make sure the user doesn't have the right to modify tickets in the queue
+ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket without group membership");
+ok (!$new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket'), "User can't modify tickets in the queue without group membership");
+
+# }}}
+
+# {{{ Test the user's right to modify a ticket as a _ticket_ admincc with the right granted at the _queue_ level
+
+ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can not modify the ticket without being an admincc");
+ok (!$new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket'), "User can not modify tickets in the queue obj without being an admincc");
+
+
+# Add the user as a ticket admincc
+ok ((my $uadd_id, $uadd_msg) = $new_tick2->AddWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId)  , "Added the new user as a queue admincc");
+ok ($add_id, "the user is now a queue admincc - $add_msg");
+
+# Make sure the user does have the right to modify tickets in the queue
+ok ($new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can modify the ticket as an admincc");
+ok (!$new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket'), "User can not modify tickets in the queue obj being only a ticket admincc");
+
+# Remove the user from the role  group
+ok ((my $del_id, $del_msg) = $new_tick2->DeleteWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId)  , "Deleted the new user as a queue admincc");
+
+# Make sure the user doesn't have the right to modify tickets in the queue
+ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket without being an admincc");
+ok (!$new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket'), "User can not modify tickets in the queue obj without being an admincc");
+
+
+# Revoke the right to modify ticket in the queue 
+ok(my ($rqv,$rqm) = $q_as_system->AdminCc->PrincipalObj->RevokeRight( Object => $RT::System, Right => 'ModifyTicket'),"Revokeed the queue adminccs the right to modify tickets");
+ok($rqv, "Revoked the right successfully - $rqm");
+
+# }}}
+
+
+
+
+# Grant "privileged users" the system right to create users
+# Create a privileged user.
+# have that user create another user
+# Revoke the right for privileged users to create users
+# have the privileged user try to create another user and fail the ACL check
+
+=end testing
+
+=cut
+
+# }}}
+
+
+# {{{ sub HasRight
+
+=head2 sub HasRight
+
+Shim around PrincipalObj->HasRight. See RT::Principal
+
+=cut
+
+sub HasRight {
+
+    my $self = shift;
+    return $self->PrincipalObj->HasRight(@_);
+}
+
+# }}}
+
+# {{{ sub CurrentUserCanModify
+
+=head2 CurrentUserCanModify RIGHT
+
+If the user has rights for this object, either because
+he has 'AdminUsers' or (if he\'s trying to edit himself and the right isn\'t an 
+admin right) 'ModifySelf', return 1. otherwise, return undef.
+
+=cut
+
+sub CurrentUserCanModify {
+    my $self  = shift;
+    my $right = shift;
+
+    if ( $self->CurrentUser->HasRight(Right => 'AdminUsers', Object => $RT::System) ) {
+        return (1);
+    }
+
+    #If the field is marked as an "administrators only" field, 
+    # don\'t let the user touch it.
+    elsif ( $self->_Accessible( $right, 'admin' ) ) {
+        return (undef);
+    }
+
+    #If the current user is trying to modify themselves
+    elsif ( ( $self->id == $self->CurrentUser->id )
+        and ( $self->CurrentUser->HasRight(Right => 'ModifySelf', Object => $RT::System) ) )
+    {
+        return (1);
+    }
+
+    #If we don\'t have a good reason to grant them rights to modify
+    # by now, they lose
+    else {
+        return (undef);
+    }
+
+}
+
+# }}}
+
+# {{{ sub CurrentUserHasRight
+
+=head2 CurrentUserHasRight
+  
+  Takes a single argument. returns 1 if $Self->CurrentUser
+  has the requested right. returns undef otherwise
+
+=cut
+
+sub CurrentUserHasRight {
+    my $self  = shift;
+    my $right = shift;
+
+    return ( $self->CurrentUser->HasRight(Right => $right, Object => $RT::System) );
+}
+
+# }}}
+
+# {{{ sub _Set
+
+sub _Set {
+    my $self = shift;
+
+    my %args = (
+        Field => undef,
+        Value => undef,
+        @_
+    );
+
+    # Nobody is allowed to futz with RT_System or Nobody 
+
+    if ( ($self->Id == $RT::SystemUser->Id )  || 
+         ($self->Id == $RT::Nobody->Id)) {
+        return ( 0, $self->loc("Can not modify system users") );
+    }
+    unless ( $self->CurrentUserCanModify( $args{'Field'} ) ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+    #Set the new value
+    my ( $ret, $msg ) = $self->SUPER::_Set(
+        Field => $args{'Field'},
+        Value => $args{'Value'}
+    );
+
+    return ( $ret, $msg );
+}
+
+# }}}
+
+# {{{ sub _Value 
+
+=head2 _Value
+
+Takes the name of a table column.
+Returns its value as a string, if the user passes an ACL check
+
+=cut
+
+sub _Value {
+
+    my $self  = shift;
+    my $field = shift;
+
+    #If the current user doesn't have ACLs, don't let em at it.  
+
+    my @PublicFields = qw( Name EmailAddress Organization Disabled
+      RealName NickName Gecos ExternalAuthId
+      AuthSystem ExternalContactInfoId
+      ContactInfoSystem );
+
+    #if the field is public, return it.
+    if ( $self->_Accessible( $field, 'public' ) ) {
+        return ( $self->SUPER::_Value($field) );
+
+    }
+
+    #If the user wants to see their own values, let them
+    # TODO figure ouyt a better way to deal with this
+   elsif ( $self->CurrentUser->Id == $self->Id ) {
+        return ( $self->SUPER::_Value($field) );
+    }
+
+    #If the user has the admin users right, return the field
+    elsif ( $self->CurrentUser->HasRight(Right =>'AdminUsers', Object => $RT::System) ) {
+        return ( $self->SUPER::_Value($field) );
+    }
+    else {
+        return (undef);
+    }
+
+}
+
+# }}}
+
+
+1;
+
+
index f4a9726..d58f696 100755 (executable)
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
 
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Users.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# (c) 1996-1999 Jesse Vincent <jesse@fsck.com>
-# This software is redistributable under the terms of the GNU GPL
 
 =head1 NAME
 
-  RT::Users - Collection of RT::User objects
-
+  RT::Users -- Class Description
 =head1 SYNOPSIS
 
-  use RT::Users;
-
+  use RT::Users
 
 =head1 DESCRIPTION
 
 
 =head1 METHODS
 
-=begin testing
-
-ok(require RT::TestHarness);
-ok(require RT::Users);
-
-=end testing
-
 =cut
 
 package RT::Users;
-use RT::EasySearch;
-@ISA = qw(RT::EasySearch);
-
-# {{{ sub _Init 
-sub _Init  {
-  my $self = shift;
-  $self->{'table'} = "Users";
-  $self->{'primary_key'} = "id";
-
-  # By default, order by name
-  $self->OrderBy( ALIAS => 'main',
-                 FIELD => 'Name',
-                 ORDER => 'ASC');
-
-  return ($self->SUPER::_Init(@_));
-  
-}
-# }}}
-
-# {{{ sub _DoSearch 
-
-=head2 _DoSearch
-
-  A subclass of DBIx::SearchBuilder::_DoSearch that makes sure that _Disabled rows never get seen unless
-we're explicitly trying to see them.
-
-=cut
-
-sub _DoSearch {
-    my $self = shift;
-    
-    #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
-    unless($self->{'find_disabled_rows'}) {
-       $self->LimitToEnabled();
-    }
-    
-    return($self->SUPER::_DoSearch(@_));
-    
-}
-
-# }}}
-
-# {{{ sub NewItem 
-
-sub NewItem  {
-  my $self = shift;
 
-  use RT::User;
-  my $item = new RT::User($self->CurrentUser);
-  return($item);
-}
-# }}}
-
-# {{{ LimitToEmail
-=head2 LimitToEmail
+use RT::SearchBuilder;
+use RT::User;
 
-Takes one argument. an email address. limits the returned set to
-that email address
+use vars qw( @ISA );
+@ISA= qw(RT::SearchBuilder);
 
-=cut
 
-sub LimitToEmail {
+sub _Init {
     my $self = shift;
-    my $addr = shift;
-    $self->Limit(FIELD => 'EmailAddress', VALUE => "$addr");
-}
-
-# }}}
-
-# {{{ MemberOfGroup
-
-=head2 MemberOfGroup
-
-takes one argument, a group id number. Limits the returned set
-to members of a given group
-
-=cut
-
-sub MemberOfGroup {
-    my $self = shift;
-    my $group = shift;
-    
-    return ("No group specified") if (!defined $group);
-
-    my $groupalias = $self->NewAlias('GroupMembers');
-
-    $self->Join( ALIAS1 => 'main', FIELD1 => 'id', 
-                ALIAS2 => "$groupalias", FIELD2 => 'Name');
-    
-    $self->Limit (ALIAS => "$groupalias",
-                 FIELD => 'GroupId',
-                 VALUE => "$group",
-                 OPERATOR => "="
-                );
-}
-
-# }}}
-
-# {{{ LimitToPrivileged
-
-=head2 LimitToPrivileged
-
-Limits to users who can be made members of ACLs and groups
+    $self->{'table'} = 'Users';
+    $self->{'primary_key'} = 'id';
 
-=cut
 
-sub LimitToPrivileged {
-    my $self = shift;
-    $self->Limit( FIELD => 'Privileged',
-                  OPERATOR => '=',
-                  VALUE => '1');
+    return ( $self->SUPER::_Init(@_) );
 }
 
-# }}}
-
-
-
-# {{{ LimitToSystem
 
-=head2 LimitToSystem
+=item NewItem
 
-Limits to users who can be granted rights, but who should
-never have their rights modified by a user or be made members of groups.
+Returns an empty new RT::User item
 
 =cut
 
-sub LimitToSystem {
+sub NewItem {
     my $self = shift;
-    $self->Limit( FIELD => 'Privileged',
-                  OPERATOR => '=',
-                  VALUE => '2');
+    return(RT::User->new($self->CurrentUser));
 }
 
-# }}}
-
-# {{{ HasQueueRight
-
-=head2 HasQueueRight
-
-Takes a queue id as its first argument.  Queue Id "0" is treated by RT as "applies to all queues"
-Takes a specific right as an optional second argument
-
-Limits the returned set to users who have rights in the queue specified, personally.  If the optional second argument is supplied, limits to users who have been explicitly granted that right.
-
-
-
-This should not be used as an ACL check, but only for obtaining lists of
-users with explicit rights in a given queue.
-
-=cut
-
-sub HasQueueRight {
-    my $self = shift;
-    my $queue = shift;
-    my $right;
-    
-    $right = shift if (@_);
-
+        eval "require RT::Users_Overlay";
+        if ($@ && $@ !~ qr{^Can't locate RT/Users_Overlay.pm}) {
+            die $@;
+        };
 
-    my $acl_alias  = $self->NewAlias('ACL');
-    $self->Join( ALIAS1 => 'main',  FIELD1 => 'id',
-                ALIAS2 => $acl_alias, FIELD2 => 'PrincipalId');
-    $self->Limit (ALIAS => $acl_alias,
-                FIELD => 'PrincipalType',
-                OPERATOR => '=',
-                VALUE => 'User');
+        eval "require RT::Users_Vendor";
+        if ($@ && $@ !~ qr{^Can't locate RT/Users_Vendor.pm}) {
+            die $@;
+        };
 
+        eval "require RT::Users_Local";
+        if ($@ && $@ !~ qr{^Can't locate RT/Users_Local.pm}) {
+            die $@;
+        };
 
-    $self->Limit(ALIAS => $acl_alias,
-                FIELD => 'RightAppliesTo',
-                OPERATOR => '=',
-                VALUE => "$queue");
 
 
-    $self->Limit(ALIAS => $acl_alias,
-                FIELD => 'RightScope',
-                OPERATOR => '=',
-                ENTRYAGGREGATOR => 'OR',
-                VALUE => 'Queue');
 
+=head1 SEE ALSO
 
-    $self->Limit(ALIAS => $acl_alias,
-                FIELD => 'RightScope',
-                OPERATOR => '=',
-                ENTRYAGGREGATOR => 'OR',
-                VALUE => 'Ticket');
+This class allows "overlay" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
 
+These overlay files can contain new subs or subs to replace existing subs in this module.
 
-    #TODO: is this being initialized properly if the right isn't there?
-    if (defined ($right)) {
-       
-       $self->Limit(ALIAS => $acl_alias,
-                    FIELD => 'RightName',
-                    OPERATOR => '=',
-                    VALUE => "$right");
-       
-       
-       };
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
 
+   no warnings qw(redefine);
 
-}
-
-
-
-# }}}
-
-# {{{ HasSystemRight
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
 
-=head2 HasSystemRight
-
-Takes one optional argument:
-   The name of a System level right.
-
-Limits the returned set to users who have been granted system rights, personally.  If the optional argument is passed in, limits to users who have been granted the explicit right listed.   Please see the note attached to LimitToQueueRights
+RT::Users_Overlay, RT::Users_Vendor, RT::Users_Local
 
 =cut
 
-sub HasSystemRight {
-    my $self = shift;
-    my $right = shift if (@_);
-       my $acl_alias  = $self->NewAlias('ACL');
-
-
-    $self->Join( ALIAS1 => 'main',  FIELD1 => 'id',
-                ALIAS2 => $acl_alias, FIELD2 => 'PrincipalId');
-    $self->Limit (ALIAS => $acl_alias,
-                FIELD => 'PrincipalType',
-                OPERATOR => '=',
-                VALUE => 'User');
-
-    $self->Limit(ALIAS => $acl_alias,
-                FIELD => 'RightScope',
-                OPERATOR => '=',
-                VALUE => 'System');
-
-
-    #TODO: is this being initialized properly if the right isn't there?
-    if (defined ($right)) {
-       $self->Limit(ALIAS => $acl_alias,
-                    FIELD => 'RightName',
-                    OPERATOR => '=',
-                    VALUE => "$right");
-       
-       }
-
-    
-}
-
-# }}}
 
 1;
-
diff --git a/rt/lib/RT/Users_Overlay.pm b/rt/lib/RT/Users_Overlay.pm
new file mode 100644 (file)
index 0000000..b397c3b
--- /dev/null
@@ -0,0 +1,290 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+=head1 NAME
+
+  RT::Users - Collection of RT::User objects
+
+=head1 SYNOPSIS
+
+  use RT::Users;
+
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=begin testing
+
+ok(require RT::Users);
+
+=end testing
+
+=cut
+
+use strict;
+no warnings qw(redefine);
+
+# {{{ sub _Init 
+sub _Init {
+    my $self = shift;
+    $self->{'table'} = 'Users';
+        $self->{'primary_key'} = 'id';
+
+
+
+    my @result =          $self->SUPER::_Init(@_);
+    # By default, order by name
+    $self->OrderBy( ALIAS => 'main',
+                    FIELD => 'Name',
+                    ORDER => 'ASC' );
+
+    $self->{'princalias'} = $self->NewAlias('Principals');
+
+    $self->Join( ALIAS1 => 'main',
+                 FIELD1 => 'id',
+                 ALIAS2 => $self->{'princalias'},
+                 FIELD2 => 'id' );
+
+    $self->Limit( ALIAS    => $self->{'princalias'},
+                  FIELD    => 'PrincipalType',
+                  OPERATOR => '=',
+                  VALUE    => 'User' );
+    return (@result);
+}
+
+# }}}
+
+# {{{ sub _DoSearch 
+
+=head2 _DoSearch
+
+  A subclass of DBIx::SearchBuilder::_DoSearch that makes sure that _Disabled rows never get seen unless
+we're explicitly trying to see them.
+
+=cut
+
+sub _DoSearch {
+    my $self = shift;
+
+    #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
+    unless ( $self->{'find_disabled_rows'} ) {
+        $self->LimitToEnabled();
+    }
+    return ( $self->SUPER::_DoSearch(@_) );
+
+}
+
+# }}}
+# {{{ sub LimitToEnabled
+
+=head2 LimitToEnabled
+
+Only find items that haven\'t been disabled
+
+=cut
+
+sub LimitToEnabled {
+    my $self = shift;
+
+    $self->Limit( ALIAS    => $self->{'princalias'},
+                  FIELD    => 'Disabled',
+                  VALUE    => '0',
+                  OPERATOR => '=' );
+}
+
+# }}}
+
+# {{{ LimitToEmail
+
+=head2 LimitToEmail
+
+Takes one argument. an email address. limits the returned set to
+that email address
+
+=cut
+
+sub LimitToEmail {
+    my $self = shift;
+    my $addr = shift;
+    $self->Limit( FIELD => 'EmailAddress', VALUE => "$addr" );
+}
+
+# }}}
+
+# {{{ MemberOfGroup
+
+=head2 MemberOfGroup PRINCIPAL_ID
+
+takes one argument, a group's principal id. Limits the returned set
+to members of a given group
+
+=cut
+
+sub MemberOfGroup {
+    my $self  = shift;
+    my $group = shift;
+
+    return $self->loc("No group specified") if ( !defined $group );
+
+    my $groupalias = $self->NewAlias('CachedGroupMembers');
+
+    # Join the principal to the groups table
+    $self->Join( ALIAS1 => $self->{'princalias'},
+                 FIELD1 => 'id',
+                 ALIAS2 => $groupalias,
+                 FIELD2 => 'MemberId' );
+
+    $self->Limit( ALIAS    => "$groupalias",
+                  FIELD    => 'GroupId',
+                  VALUE    => "$group",
+                  OPERATOR => "=" );
+}
+
+# }}}
+
+# {{{ LimitToPrivileged
+
+=head2 LimitToPrivileged
+
+Limits to users who can be made members of ACLs and groups
+
+=cut
+
+sub LimitToPrivileged {
+    my $self = shift;
+
+    my $priv = RT::Group->new( $self->CurrentUser );
+    $priv->LoadSystemInternalGroup('Privileged');
+    unless ( $priv->Id ) {
+        $RT::Logger->crit("Couldn't find a privileged users group");
+    }
+    $self->MemberOfGroup( $priv->PrincipalId );
+}
+
+# }}}
+
+# {{{ WhoHaveRight
+
+=head2 WhoHaveRight { Right => 'name', Object => $rt_object , IncludeSuperusers => undef, IncludeSubgroupMembers => undef, IncludeSystemRights => undef }
+
+=begin testing
+
+ok(my $users = RT::Users->new($RT::SystemUser));
+$users->WhoHaveRight(Object =>$RT::System, Right =>'SuperUser');
+ok($users->Count == 1, "There is one privileged superuser - Found ". $users->Count );
+# TODO: this wants more testing
+
+
+=end testing
+
+
+find all users who the right Right for this group, either individually
+or as members of groups
+
+
+
+
+
+=cut
+
+sub WhoHaveRight {
+    my $self = shift;
+    my %args = ( Right                  => undef,
+                 Object =>              => undef,
+                 IncludeSystemRights    => undef,
+                 IncludeSuperusers      => undef,
+                 IncludeSubgroupMembers => 1,
+                 @_ );
+
+    if (defined $args{'ObjectType'} || defined $args{'ObjectId'}) {
+        $RT::Logger->crit("$self WhoHaveRight called with the Obsolete ObjectId/ObjectType API");
+        return(undef);
+    }
+        my @privgroups;
+        my $Groups = RT::Groups->new($RT::SystemUser);
+        $Groups->WithRight(Right=> $args{'Right'},
+                     Object => $args{'Object'},
+                     IncludeSystemRights => $args{'IncludeSystemRights'},
+                     IncludeSuperusers => $args{'IncludeSuperusers'});
+        while (my $Group = $Groups->Next()) {
+                push @privgroups, $Group->Id();
+        }
+
+        $self->WhoBelongToGroups(Groups => \@privgroups,
+                                 IncludeSubgroupMembers => $args{'IncludeSubgroupMembers'});
+}
+
+# }}}
+
+# {{{ WhoBelongToGroups 
+
+=head2 WhoBelongToGroups { Groups => ARRAYREF, IncludeSubgroupMembers => 1 }
+
+=cut
+
+sub WhoBelongToGroups {
+    my $self = shift;
+    my %args = ( Groups                 => undef,
+                 IncludeSubgroupMembers => 1,
+                 @_ );
+
+    # Unprivileged users can't be granted real system rights. 
+    # is this really the right thing to be saying?
+    $self->LimitToPrivileged();
+
+    my $userprinc  = $self->{'princalias'};
+    my $cgm;
+
+    # The cachedgroupmembers table is used for unrolling group memberships to allow fast lookups 
+    # if we bind to CachedGroupMembers, we'll find all members of groups recursively.
+    # if we don't we'll find only 'direct' members of the group in question
+
+    if ( $args{'IncludeSubgroupMembers'} ) {
+        $cgm = $self->NewAlias('CachedGroupMembers');
+    }
+    else {
+        $cgm = $self->NewAlias('GroupMembers');
+    }
+
+    # {{{ Tie the users we're returning ($userprinc) to the groups that have rights granted to them ($groupprinc)
+    $self->Join( ALIAS1 => $cgm, FIELD1 => 'MemberId',
+                 ALIAS2 => $userprinc, FIELD2 => 'id' );
+    # }}} 
+
+ #   my $and_check_groups = "($cgm.GroupId = NULL";
+    foreach my $groupid (@{$args{'Groups'}}) {
+        $self->Limit(ALIAS => $cgm, FIELD => 'GroupId', VALUE => $groupid, QUOTEVALUE => 0, ENTRYAGGREGATOR=> 'OR')
+
+        #$and_check_groups .= " OR $cgm.GroupId = $groupid";
+    }
+    #$and_check_groups .= ")";
+
+    #$self->_AddSubClause("WhichGroup", $and_check_groups);
+}
+# }}}
+
+
+1;
diff --git a/rt/lib/RT/Watcher.pm b/rt/lib/RT/Watcher.pm
deleted file mode 100755 (executable)
index c7c6100..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Attic/Watcher.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# (c) 1996-2001 Jesse Vincent <jesse@fsck.com>
-# This software is redistributable under the terms of the GNU GPL
-
-=head1 NAME
-
-  RT::Watcher - RT Watcher object
-
-=head1 SYNOPSIS
-
-  use RT::Watcher;
-
-
-=head1 DESCRIPTION
-
-This module should never be called directly by client code. it\'s an internal module which
-should only be accessed through exported APIs in Ticket, Queue and other similar objects.
-
-=head1 METHODS
-
-=begin testing
-
-ok(require RT::TestHarness);
-ok(require RT::Watcher);
-
-=end testing
-
-=cut
-
-package RT::Watcher;
-use RT::Record;
-@ISA= qw(RT::Record);
-
-
-# {{{ sub _Init 
-
-sub _Init {
-  my $self = shift;
-  
-  $self->{'table'} = "Watchers";
-  return ($self->SUPER::_Init(@_));
-
-}
-# }}}
-
-# {{{ sub Create 
-
-=head2 Create PARAMHASH
-
-Create a new watcher object with the following Attributes:
-
-Scope:  Ticket or Queue
-Value: Ticket or queue id
-Type: Requestor, Cc or AdminCc.  Requestor is not supported for a scope of \'Queue\'
-Email: The email address of the watcher.  If the email address maps to an RT User, this is resolved
-to an Owner object instead.
-Owner: The RT user id of the \'owner\' of this watcher object. 
-
-=cut
-
-sub Create  {
-    my $self = shift;
-    my %args = (
-               Owner => undef,
-               Email => undef,
-               Value => undef,
-               Scope => undef,
-               Type => undef,
-               Quiet => 0,
-               @_ # get the real argumentlist
-              );
-    
-    #Do we have someone this applies to?
-    unless (($args{'Owner'} =~ /^(\d+)$/) || ($args{'Email'} =~ /\@/)) {
-       return (0, "No user or email address specified");
-    }
-    
-    #if we only have an email address, try to resolve it to an owner
-    if ($args{'Owner'} == 0) {
-        my $User = new RT::User($RT::SystemUser);
-        $User->LoadByEmail($args{'Email'});
-        if ($User->id) {
-            $args{'Owner'} = $User->id;
-           delete $args{'Email'};
-       }
-    }
-    
-    
-    if ($args{'Type'} eq "Requestor" and $args{'Owner'} == 0) {
-       # Requestors *MUST* have an account
-       
-       my $Address = RT::CanonicalizeAddress($args{'Email'});
-       
-       my $NewUser = RT::User->new($RT::SystemUser);
-       my ($Val, $Message) =
-         $NewUser->Create(Name => $Address,
-                          EmailAddress => $Address,
-                          RealName => $Address,
-                          Password => undef,
-                          Privileged => 0,
-                          Comments => 'Autocreated on ticket submission'
-                         );
-       return (0, "Could not create watcher for requestor")
-         unless $Val;
-       if ($NewUser->id) {
-           $args{'Owner'} = $NewUser->id;
-           delete $args{'Email'};
-       }
-    }
-    
-    
-    
-    
-    #Make sure we\'ve got a valid type
-    #TODO --- move this to ValidateType 
-    return (0, "Invalid Type")
-      unless ($args{'Type'} =~ /^(Requestor|Cc|AdminCc)$/i);
-
-    my $id = $self->SUPER::Create(%args);
-    if ($id) {
-       return (1,"Interest noted");
-    }
-    else {
-       return (0, "Error adding watcher");
-    }
-}
-# }}}
-
-# {{{ sub Load 
-
-=head2 Load ID
-  
-  Loads a watcher by the primary key of the watchers table ($Watcher->id)
-  
-=cut
-
-sub Load  {
-    my $self = shift;
-    my $identifier = shift;
-    
-    if ($identifier !~ /\D/) {
-       $self->SUPER::LoadById($identifier);
-    }
-    else {
-       return (0, "That's not a numerical id");
-    }
-}
-
-# }}}
-
-# {{{ sub LoadByValue
-
-=head2 LoadByValue PARAMHASH
-  
-LoadByValue takes a parameter hash with the following attributes:
-
-  Email, Owner, Scope, Type, Value
-
-The same rules enforced at create are enforced by Load.
-
-Returns a tuple of (retval, msg). Retval is 1 on success and 0 on failure.
-msg describes what happened in a human readable form.
-
-=cut
-
-sub LoadByValue {
-    my $self = shift;
-    my %args = ( Email => undef, 
-                Owner => undef,
-                Scope => undef,
-                Type => undef,
-                Value => undef,
-                @_);
-    
-    #TODO: all this code is being copied from Create. that\'s silly
-    
-    #Do we have someone this applies to?
-    unless (($args{'Owner'} =~ /^(\d*)$/) || ($args{'Email'} =~ /\@/)) {
-       return (0, "No user or email address specified");
-    }
-    
-    #if we only have an email address, try to resolve it to an owner
-    unless ($args{'Owner'}) {
-        my $User = new RT::User($RT::SystemUser);
-        $User->LoadByEmail($args{'Email'});
-        if ($User->id > 0) {
-            $args{'Owner'} = $User->id;
-           delete $args{'Email'};
-       }
-    }
-    
-    if ((defined ($args{'Type'})) and 
-       ($args{'Type'} !~ /^(Requestor|Cc|AdminCc)$/i)) {
-       return (0, "Invalid Type");
-    }
-    if ($args{'Owner'}) {
-       $self->LoadByCols( Type => $args{'Type'},
-                          Value => $args{'Value'},
-                          Owner => $args{'Owner'},
-                          Scope => $args{'Scope'},
-                        );
-    }
-    else {
-       $self->LoadByCols( Type => $args{'Type'},
-                          Email => $args{'Email'},
-                          Value => $args{'Value'},
-                          Scope => $args{'Scope'},
-                        );
-    }  
-    unless ($self->Id) {
-       return(0, "Couldn\'t find that watcher");
-    }
-    return (1, "Watcher loaded");
-}
-
-# }}}
-
-# {{{ sub OwnerObj 
-
-=head2 OwnerObj
-
-Return an RT Owner Object for this Watcher, if we have one
-
-=cut
-
-sub OwnerObj  {
-    my $self = shift;
-    if (!defined $self->{'OwnerObj'}) {
-       require RT::User;
-       $self->{'OwnerObj'} = RT::User->new($self->CurrentUser);
-       if ($self->Owner) {
-           $self->{'OwnerObj'}->Load($self->Owner);
-       } else {
-           return $RT::Nobody->UserObj;
-       }
-    }
-    return ($self->{'OwnerObj'});
-}
-# }}}
-
-# {{{ sub Email
-
-=head2 Email
-
-This custom data accessor does the right thing and returns
-the 'Email' attribute of this Watcher object. If that's undefined,
-it returns the 'EmailAddress' attribute of its 'Owner' object, which is
-an RT::User object.
-
-=cut
-
-sub Email {
-    my $self = shift;
-    
-    # IF Email is defined, return that. Otherwise, return the Owner's email address
-    if (defined($self->__Value('Email'))) {
-       return ($self->__Value('Email'));
-    }
-    elsif ($self->Owner) {
-       return ($self->OwnerObj->EmailAddress);
-    }
-    else {
-       return ("Data error");
-    }
-}
-# }}}
-  
-# {{{ sub IsUser
-
-=head2 IsUser
-
-Returns true if this watcher object is tied to a user object. (IE it
-isn't sending to some other email address).
-Otherwise, returns undef
-
-=cut
-
-sub IsUser {
-    my $self = shift;
-    # if this watcher has an email address glued onto it,
-    # return undef
-
-    if (defined($self->__Value('Email'))) {
-        return undef;
-    }
-    else {
-        return 1;
-    }
-}
-
-# }}}
-
-# {{{ sub _Accessible 
-sub _Accessible  {
-  my $self = shift;
-  my %Cols = (
-             Email => 'read/write',
-             Scope => 'read/write',
-             Value => 'read/write',
-             Type => 'read/write',
-             Quiet => 'read/write',
-             Owner => 'read/write',          
-             Creator => 'read/auto',
-             Created => 'read/auto',
-             LastUpdatedBy => 'read/auto',
-             LastUpdated => 'read/auto'
-            );
-  return($self->SUPER::_Accessible(@_, %Cols));
-}
-# }}}
-
-1;
diff --git a/rt/lib/RT/Watchers.pm b/rt/lib/RT/Watchers.pm
deleted file mode 100755 (executable)
index c55adda..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Attic/Watchers.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# (c) 1996-2000 Jesse Vincent <jesse@fsck.com>
-# This software is redistributable under the terms of the GNU GPL
-
-=head1 NAME
-
-  RT::Watchers - Collection of RT Watcher objects
-
-=head1 SYNOPSIS
-
-  use RT::Watchers;
-  my $watchers = new RT::Watchers($CurrentUser);
-  while (my $watcher = $watchers->Next()) {
-    print $watcher->Id . "is a watcher";
-  }  
-
-=head1 DESCRIPTION
-
-This module should never be called directly by client code. it's an internal module which
-should only be accessed through exported APIs in Ticket, Queue and other similar objects.
-
-
-=head1 METHODS
-
-=begin testing
-
-ok(require RT::TestHarness);
-ok(require RT::Watchers);
-
-=end testing
-
-=cut
-
-package RT::Watchers;
-
-use strict;
-use vars qw( @ISA );
-
-
-require RT::EasySearch;
-require RT::Watcher;
-@ISA= qw(RT::EasySearch);
-
-
-# {{{ sub _Init
-sub _Init  {
-  my $self = shift;
-  
-  $self->{'table'} = "Watchers";
-  $self->{'primary_key'} = "id";
-  return($self->SUPER::_Init(@_));
-}
-# }}}
-
-# {{{ sub Limit 
-
-=head2 Limit
-
-  A wrapper around RT::EasySearch::Limit which sets
-the default entry aggregator to 'AND'
-
-=cut
-
-sub Limit  {
-  my $self = shift;
-  my %args = ( ENTRYAGGREGATOR => 'AND',
-              @_);
-
-  $self->SUPER::Limit(%args);
-}
-# }}}
-
-# {{{ sub LimitToTicket
-
-=head2 LimitToTicket
-
-Takes a single arg which is a ticket id
-Limits to watchers of that ticket
-
-=cut
-
-sub LimitToTicket { 
-  my $self = shift;
-  my $ticket = shift;
-  $self->Limit( ENTRYAGGREGATOR => 'OR',
-               FIELD => 'Value',
-               VALUE => $ticket);
-  $self->Limit (ENTRYAGGREGATOR => 'AND',
-               FIELD => 'Scope',
-               VALUE => 'Ticket');
-}
-# }}}
-
-# {{{ sub LimitToQueue 
-
-=head2 LimitToQueue
-
-Takes a single arg, which is a queue id
-Limits to watchers of that queue.
-
-=cut
-
-sub LimitToQueue  {
-  my $self = shift;
-  my $queue = shift;
-  $self->Limit (ENTRYAGGREGATOR => 'OR',
-               FIELD => 'Value',
-               VALUE => $queue);
-  $self->Limit (ENTRYAGGREGATOR => 'AND',
-               FIELD => 'Scope',
-               VALUE => 'Queue');
-}
-# }}}
-
-# {{{ sub LimitToType 
-
-=head2 LimitToType
-
-Takes a single string as its argument. That string is a watcher type
-which is one of 'Requestor', 'Cc' or 'AdminCc'
-Limits to watchers of that type
-
-=cut
-
-
-sub LimitToType  {
-  my $self = shift;
-  my $type = shift;
-  $self->Limit(FIELD => 'Type',
-              VALUE => "$type");
-}
-# }}}
-
-# {{{ sub LimitToRequestors 
-
-=head2 LimitToRequestors
-
-Limits to watchers of type 'Requestor'
-
-=cut
-
-sub LimitToRequestors  {
-  my $self = shift;
-  $self->LimitToType("Requestor");
-}
-# }}}
-
-# {{{ sub LimitToCc 
-
-=head2 LimitToCc
-
-Limits to watchers of type 'Cc'
-
-=cut
-
-sub LimitToCc  {
-    my $self = shift;
-    $self->LimitToType("Cc");
-}
-# }}}
-
-# {{{ sub LimitToAdminCc 
-
-=head2 LimitToAdminCc
-
-Limits to watchers of type AdminCc
-
-=cut
-
-sub LimitToAdminCc  {
-    my $self = shift;
-    $self->LimitToType("AdminCc");
-}
-# }}}
-
-# {{{ sub Emails 
-
-=head2 Emails
-
-# Return a (reference to a) list of emails
-
-=cut
-
-sub Emails  {
-    my $self = shift;
-    my @list;    # List is a list of watcher email addresses
-
-    # $watcher is an RT::Watcher object
-    while (my $watcher=$self->Next()) {
-       push(@list, $watcher->Email);
-    }
-    return \@list;
-}
-# }}}
-
-# {{{ sub EmailsAsString
-
-=head2 EmailsAsString
-
-# Returns the RT::Watchers->Emails as a comma seperated string
-
-=cut
-
-sub EmailsAsString {
-    my $self = shift;
-    return(join(", ",@{$self->Emails}));
-}
-# }}}
-
-# {{{ sub NewItem 
-
-
-
-sub NewItem  {
-    my $self = shift;
-    
-    use RT::Watcher;
-    my  $item = new RT::Watcher($self->CurrentUser);
-    return($item);
-}
-# }}}
-1;
-
-
-
-
diff --git a/rt/lib/t/00smoke.t b/rt/lib/t/00smoke.t
new file mode 100644 (file)
index 0000000..4f36bb3
--- /dev/null
@@ -0,0 +1,14 @@
+#!/usr/bin/perl
+
+use Test::More qw(no_plan);
+
+use lib "/opt/rt3/lib";
+use RT;
+ok(RT::LoadConfig);
+ok(RT::Init, "Basic initialization and DB connectivity");
+
+use File::Find;
+File::Find::find({wanted => \&wanted}, '.');
+sub wanted { /^*\.pm\z/s && ok(require $_, "Requiring '$_'"); }
+
+
diff --git a/rt/lib/t/00smoke.t.in b/rt/lib/t/00smoke.t.in
new file mode 100644 (file)
index 0000000..11f0a9c
--- /dev/null
@@ -0,0 +1,14 @@
+#!@PERL@
+
+use Test::More qw(no_plan);
+
+use lib "@RT_LIB_PATH@";
+use RT;
+ok(RT::LoadConfig);
+ok(RT::Init, "Basic initialization and DB connectivity");
+
+use File::Find;
+File::Find::find({wanted => \&wanted}, '.');
+sub wanted { /^*\.pm\z/s && ok(require $_, "Requiring '$_'"); }
+
+
diff --git a/rt/lib/t/01harness.t b/rt/lib/t/01harness.t
new file mode 100644 (file)
index 0000000..98c28d2
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/perl
+
+use Test::More qw(no_plan);
+
+use lib "/opt/rt3/lib";
+use RT;
+ok(RT::LoadConfig);
+ok(RT::Init, "Basic initialization and DB connectivity");
+
+my $test = shift @ARGV;
+require $test;
+
diff --git a/rt/lib/t/01harness.t.in b/rt/lib/t/01harness.t.in
new file mode 100644 (file)
index 0000000..d132330
--- /dev/null
@@ -0,0 +1,12 @@
+#!@PERL@
+
+use Test::More qw(no_plan);
+
+use lib "@RT_LIB_PATH@";
+use RT;
+ok(RT::LoadConfig);
+ok(RT::Init, "Basic initialization and DB connectivity");
+
+my $test = shift @ARGV;
+require $test;
+
diff --git a/rt/lib/t/02regression.t b/rt/lib/t/02regression.t
new file mode 100644 (file)
index 0000000..62b4e9a
--- /dev/null
@@ -0,0 +1,44 @@
+#!/usr/bin/perl
+
+use Test::More qw(no_plan);
+
+use lib "/opt/rt3/lib";
+use RT;
+ok(RT::LoadConfig);
+ok(RT::Init, "Basic initialization and DB connectivity");
+
+# Create a new queue
+use_ok(RT::Queue);
+my $q = RT::Queue->new($RT::SystemUser);
+
+$q->Load('regression');
+if ($q->id != 0) {
+        die "Regression tests not starting with a clean DB. Bailing";
+}
+
+my ($id, $msg) = $q->Create( Name => 'Regression',
+            Description => 'A regression test queue',
+            CorrespondAddress => 'correspond@a',
+            CommentAddress => 'comment@a');
+
+isnt($id, 0, "Queue was created sucessfully - $msg");
+
+my $q2 = RT::Queue->new($RT::SystemUser);
+
+ok($q2->Load($id));
+is($q2->id, $id, "Sucessfully loaded the queue again");
+is($q2->Name, 'Regression');
+is($q2->Description, 'A regression test queue');
+is($q2->CorrespondAddress, 'correspond@a');
+is($q2->CommentAddress, 'comment@a');
+
+
+use File::Find;
+File::Find::find({wanted => \&wanted_autogen}, 'lib/t/autogen');
+sub wanted_autogen { /^autogen.*\.t\z/s && require $_; }
+
+File::Find::find({wanted => \&wanted_regression}, 'lib/t/regression');
+sub wanted_regression { /^*\.t\z/s && require $_; }
+
+require "lib/t/03web.pl";
+require "lib/t/04_send_email.pl";
diff --git a/rt/lib/t/02regression.t.in b/rt/lib/t/02regression.t.in
new file mode 100644 (file)
index 0000000..51cd7e3
--- /dev/null
@@ -0,0 +1,44 @@
+#!@PERL@
+
+use Test::More qw(no_plan);
+
+use lib "@RT_LIB_PATH@";
+use RT;
+ok(RT::LoadConfig);
+ok(RT::Init, "Basic initialization and DB connectivity");
+
+# Create a new queue
+use_ok(RT::Queue);
+my $q = RT::Queue->new($RT::SystemUser);
+
+$q->Load('regression');
+if ($q->id != 0) {
+        die "Regression tests not starting with a clean DB. Bailing";
+}
+
+my ($id, $msg) = $q->Create( Name => 'Regression',
+            Description => 'A regression test queue',
+            CorrespondAddress => 'correspond@a',
+            CommentAddress => 'comment@a');
+
+isnt($id, 0, "Queue was created sucessfully - $msg");
+
+my $q2 = RT::Queue->new($RT::SystemUser);
+
+ok($q2->Load($id));
+is($q2->id, $id, "Sucessfully loaded the queue again");
+is($q2->Name, 'Regression');
+is($q2->Description, 'A regression test queue');
+is($q2->CorrespondAddress, 'correspond@a');
+is($q2->CommentAddress, 'comment@a');
+
+
+use File::Find;
+File::Find::find({wanted => \&wanted_autogen}, 'lib/t/autogen');
+sub wanted_autogen { /^autogen.*\.t\z/s && require $_; }
+
+File::Find::find({wanted => \&wanted_regression}, 'lib/t/regression');
+sub wanted_regression { /^*\.t\z/s && require $_; }
+
+require "lib/t/03web.pl";
+require "lib/t/04_send_email.pl";
diff --git a/rt/lib/t/03web.pl b/rt/lib/t/03web.pl
new file mode 100644 (file)
index 0000000..4500ff2
--- /dev/null
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+
+use strict;
+use WWW::Mechanize;
+use HTTP::Request::Common;
+use HTTP::Cookies;
+use LWP;
+
+my $cookie_jar = HTTP::Cookies->new;
+my $agent = WWW::Mechanize->new();
+
+# give the agent a place to stash the cookies
+
+$agent->cookie_jar($cookie_jar);
+
+
+# get the top page
+my $url = "http://localhost/";
+$agent->get($url);
+
+is ($agent->{'status'}, 200, "Loaded a page");
+
+
+# {{{ test a login
+
+# follow the link marked "Login"
+
+ok($agent->{form}->find_input('user'));
+
+ok($agent->{form}->find_input('pass'));
+ok ($agent->{'content'} =~ /username:/i);
+$agent->field( 'user' => 'root' );
+$agent->field( 'pass' => 'password' );
+# the field isn't named, so we have to click link 0
+$agent->click(0);
+is($agent->{'status'}, 200, "Fetched the page ok");
+ok( $agent->{'content'} =~ /Logout/i, "Found a logout link");
+
+
+use File::Find;
+find ( \&wanted , 'html/');
+
+sub wanted {
+        -f  && /\.html$/ && $_ !~ /Logout.html$/  && test_get($File::Find::name);
+}       
+
+sub test_get {
+        my $file = shift;
+
+
+        $file =~ s#^html/##; 
+        ok ($agent->get("$url/$file", "GET $url/$file"));
+        is ($agent->{'status'}, 200, "Loaded $file");
+        ok( $agent->{'content'} =~ /Logout/i, "Found a logout link on $file ");
+        ok( $agent->{'content'} !~ /Not logged in/i, "Still logged in for  $file");
+        ok( $agent->{'content'} !~ /System error/i, "Didn't get a Mason compilation error on $file");
+        
+}
+
+# }}}
+
+1;
diff --git a/rt/lib/t/03web.pl.in b/rt/lib/t/03web.pl.in
new file mode 100644 (file)
index 0000000..abe446e
--- /dev/null
@@ -0,0 +1,62 @@
+#!@PERL@
+
+use strict;
+use WWW::Mechanize;
+use HTTP::Request::Common;
+use HTTP::Cookies;
+use LWP;
+
+my $cookie_jar = HTTP::Cookies->new;
+my $agent = WWW::Mechanize->new();
+
+# give the agent a place to stash the cookies
+
+$agent->cookie_jar($cookie_jar);
+
+
+# get the top page
+my $url = "http://localhost/";
+$agent->get($url);
+
+is ($agent->{'status'}, 200, "Loaded a page");
+
+
+# {{{ test a login
+
+# follow the link marked "Login"
+
+ok($agent->{form}->find_input('user'));
+
+ok($agent->{form}->find_input('pass'));
+ok ($agent->{'content'} =~ /username:/i);
+$agent->field( 'user' => 'root' );
+$agent->field( 'pass' => 'password' );
+# the field isn't named, so we have to click link 0
+$agent->click(0);
+is($agent->{'status'}, 200, "Fetched the page ok");
+ok( $agent->{'content'} =~ /Logout/i, "Found a logout link");
+
+
+use File::Find;
+find ( \&wanted , 'html/');
+
+sub wanted {
+        -f  && /\.html$/ && $_ !~ /Logout.html$/  && test_get($File::Find::name);
+}       
+
+sub test_get {
+        my $file = shift;
+
+
+        $file =~ s#^html/##; 
+        ok ($agent->get("$url/$file", "GET $url/$file"));
+        is ($agent->{'status'}, 200, "Loaded $file");
+        ok( $agent->{'content'} =~ /Logout/i, "Found a logout link on $file ");
+        ok( $agent->{'content'} !~ /Not logged in/i, "Still logged in for  $file");
+        ok( $agent->{'content'} !~ /System error/i, "Didn't get a Mason compilation error on $file");
+        
+}
+
+# }}}
+
+1;
diff --git a/rt/lib/t/04_send_email.pl b/rt/lib/t/04_send_email.pl
new file mode 100644 (file)
index 0000000..46e3d74
--- /dev/null
@@ -0,0 +1,389 @@
+#!/usr/bin/perl -w
+
+use strict;
+use RT::EmailParser;
+use RT::Tickets;
+use RT::Action::SendEmail;
+
+my @_outgoing_messages;
+my @scrips_fired;
+
+#We're not testing acls here.
+my $everyone = RT::Group->new($RT::SystemUser);
+$everyone->LoadSystemInternalGroup('Everyone');
+$everyone->PrincipalObj->GrantRight(Right =>'SuperUser');
+
+
+is (__PACKAGE__, 'main', "We're operating in the main package");
+
+
+{
+no warnings qw/redefine/;
+sub RT::Action::SendEmail::SendMessage {
+        my $self = shift;
+        my $MIME = shift;
+
+        main::_fired_scrip($self->ScripObj);
+        main::ok(ref($MIME) eq 'MIME::Entity', "hey, look. it's a mime entity");
+}
+
+}
+
+# instrument SendEmail to pass us what it's about to send.
+# create a regular ticket
+
+my $parser = RT::EmailParser->new();
+$parser->ParseMIMEEntityFromScalar('From: root@localhost
+To: rt@example.com
+Subject: This is a test of new ticket creation as an unknown user
+
+Blah!
+Foob!');
+
+                                  
+use Data::Dumper;
+
+my $ticket = RT::Ticket->new($RT::SystemUser);
+my ($id,  $tid, $msg ) = $ticket->Create(Requestor => ['root@localhost'], Queue => 'general', Subject => 'I18NTest', MIMEObj => $parser->Entity);
+ok ($id,$msg);
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject eq 'I18NTest', "failed to create the new ticket from an unprivileged account");
+
+# make sure it fires scrips.
+is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation");
+# make sure it sends an autoreply
+# make sure it sends a notification to adminccs
+
+
+# we need to swap out SendMessage to test the new things we care about;
+&utf8_redef_sendmessage;
+
+# create an iso 8859-1 ticket
+@scrips_fired = ();
+
+my $content =  `cat ./lib/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content";
+
+
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+use RT::Interface::Email;
+                                  
+ RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Content =~ /H\x{e5}vard/, "It's signed by havard. yay");
+
+
+# make sure it fires scrips.
+is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation");
+# make sure it sends an autoreply
+
+
+# make sure it sends a notification to adminccs
+
+# If we correspond, does it do the right thing to the outbound messages?
+
+$parser->ParseMIMEEntityFromScalar($content);
+my ($id, $msg) = $tick->Comment(MIMEObj => $parser->Entity);
+ok ($id, $msg);
+
+$parser->ParseMIMEEntityFromScalar($content);
+($id, $msg) = $tick->Correspond(MIMEObj => $parser->Entity);
+ok ($id, $msg);
+
+
+# we need to swap out SendMessage to test the new things we care about;
+&iso8859_redef_sendmessage;
+$RT::EmailOutputEncoding = 'iso-8859-1';
+# create an iso 8859-1 ticket
+@scrips_fired = ();
+
+my $content =  `cat ./lib/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content";
+# be as much like the mail gateway as possible.
+use RT::Interface::Email;
+                                  
+ RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Content =~ /H\x{e5}vard/, "It's signed by havard. yay");
+
+
+# make sure it fires scrips.
+is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation");
+# make sure it sends an autoreply
+
+
+# make sure it sends a notification to adminccs
+
+
+# If we correspond, does it do the right thing to the outbound messages?
+
+$parser->ParseMIMEEntityFromScalar($content);
+my ($id, $msg) = $tick->Comment(MIMEObj => $parser->Entity);
+ok ($id, $msg);
+
+$parser->ParseMIMEEntityFromScalar($content);
+($id, $msg) = $tick->Correspond(MIMEObj => $parser->Entity);
+ok ($id, $msg);
+
+
+sub _fired_scrip {
+        my $scrip = shift;
+        push @scrips_fired, $scrip;
+}       
+
+sub utf8_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval ' 
+    sub RT::Action::SendEmail::SendMessage {
+        my $self = shift;
+        my $MIME = shift;
+
+        my $scrip = $self->ScripObj->id;
+        ok(1, $self->ScripObj->ConditionObj->Name . " ".$self->ScripObj->ActionObj->Name);
+        main::_fired_scrip($self->ScripObj);
+        $MIME->make_singlepart;
+        main::ok( ref($MIME) eq \'MIME::Entity\',
+                  "hey, look. it\'s a mime entity" );
+        main::ok( ref( $MIME->head ) eq \'MIME::Head\',
+                  "its mime header is a mime header. yay" );
+        main::ok( $MIME->head->get(\'Content-Type\') =~ /utf-8/,
+                  "Its content type is utf-8" );
+        my $message_as_string = $MIME->bodyhandle->as_string();
+        use Encode;
+        $message_as_string = Encode::decode_utf8($message_as_string);
+        main::ok(
+            $message_as_string =~ /H\x{e5}vard/,
+"The message\'s content contains havard\'s name. this will fail if it\'s not utf8 out");
+
+    }';
+}
+
+sub iso8859_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval ' 
+    sub RT::Action::SendEmail::SendMessage {
+        my $self = shift;
+        my $MIME = shift;
+
+        my $scrip = $self->ScripObj->id;
+        ok(1, $self->ScripObj->ConditionObj->Name . " ".$self->ScripObj->ActionObj->Name);
+        main::_fired_scrip($self->ScripObj);
+        $MIME->make_singlepart;
+        main::ok( ref($MIME) eq \'MIME::Entity\',
+                  "hey, look. it\'s a mime entity" );
+        main::ok( ref( $MIME->head ) eq \'MIME::Head\',
+                  "its mime header is a mime header. yay" );
+        main::ok( $MIME->head->get(\'Content-Type\') =~ /iso-8859-1/,
+                  "Its content type is iso-8859-1 - " . $MIME->head->get("Content-Type") );
+        my $message_as_string = $MIME->bodyhandle->as_string();
+        use Encode;
+        $message_as_string = Encode::decode("iso-8859-1",$message_as_string);
+        main::ok(
+            $message_as_string =~ /H\x{e5}vard/, "The message\'s content contains havard\'s name. this will fail if it\'s not utf8 out");
+
+    }';
+}
+
+# {{{ test a multipart alternative containing a text-html part with an umlaut
+
+my $content =  `cat ./lib/t/data/multipart-alternative-with-umlaut` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&umlauts_redef_sendmessage;
+
+RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Content =~ /causes Error/, "We recorded the content right as text-plain");
+is ($tick->Transactions->First->Attachments->Count , 3 , "Has three attachments, presumably a text-plain, a text-html and a multipart alternative");
+
+sub umlauts_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { }';
+}
+
+# }}}
+
+# {{{ test a text-html message with an umlaut
+
+my $content =  `cat ./lib/t/data/text-html-with-umlaut` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&text_html_umlauts_redef_sendmessage;
+
+RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Attachments->First->Content =~ /causes Error/, "We recorded the content as containing 'causes error'");
+ok ($tick->Transactions->First->Attachments->First->ContentType =~ /text\/html/, "We recorded the content as text/html");
+ok ($tick->Transactions->First->Attachments->Count ==1 , "Has one attachment, presumably a text-html and a multipart alternative");
+
+sub text_html_umlauts_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { 
+                my $self = shift; 
+                my $MIME = shift; 
+                use Data::Dumper;
+                return (1) unless ($self->ScripObj->ScripActionObj->Name eq "Notify AdminCcs" );
+                ok (is $MIME->parts, 2, "generated correspondence mime entityis composed of three parts");
+                is ($MIME->head->mime_type , "multipart/mixed", "The first part is a multipart mixed". $MIME->head->mime_type);
+                is ($MIME->parts(0)->head->mime_type , "text/plain", "The second part is a plain");
+                is ($MIME->parts(1)->head->mime_type , "text/html", "The third part is an html ");
+                 }';
+}
+
+# }}}
+
+# {{{ test a text-html message with russian characters
+
+my $content =  `cat ./lib/t/data/text-html-in-russian` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&text_html_russian_redef_sendmessage;
+
+RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Attachments->First->ContentType =~ /text\/html/, "We recorded the content right as text-html");
+ok ($tick->Transactions->First->Attachments->Count ==1 , "Has one attachment, presumably a text-html and a multipart alternative");
+
+sub text_html_russian_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { 
+                my $self = shift; 
+                my $MIME = shift; 
+                use Data::Dumper;
+                return (1) unless ($self->ScripObj->ScripActionObj->Name eq "Notify AdminCcs" );
+                ok (is $MIME->parts, 2, "generated correspondence mime entityis composed of three parts");
+                is ($MIME->head->mime_type , "multipart/mixed", "The first part is a multipart mixed". $MIME->head->mime_type);
+                is ($MIME->parts(0)->head->mime_type , "text/plain", "The second part is a plain");
+                is ($MIME->parts(1)->head->mime_type , "text/html", "The third part is an html ");
+                my $content_1251;
+                $content_1251 = $MIME->parts(1)->bodyhandle->as_string();
+                ok ($content_1251 =~ qr{Ó÷eáíûé Öeíòp "ÊÀÄÐÛ ÄÅËÎÂÎÃΠÌÈÐÀ" ïpèãëaøaeò ía òpeíèíã:},
+"Content matches drugim in codepage 1251" );
+                 }';
+}
+
+# }}}
+
+# {{{ test a message containing a russian subject and NO content type
+
+unshift (@RT::EmailInputEncodings, 'koi8-r');
+$RT::EmailOutputEncoding = 'koi8-r';
+my $content =  `cat ./lib/t/data/russian-subject-no-content-type` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&text_plain_russian_redef_sendmessage;
+RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Attachments->First->ContentType =~ /text\/plain/, "We recorded the content type right");
+ok ($tick->Transactions->First->Attachments->Count ==1 , "Has one attachment, presumably a text-plain");
+is ($tick->Subject, "\x{442}\x{435}\x{441}\x{442} \x{442}\x{435}\x{441}\x{442}", "Recorded the subject right");
+sub text_plain_russian_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { 
+                my $self = shift; 
+                my $MIME = shift; 
+                return (1) unless ($self->ScripObj->ScripActionObj->Name eq "Notify AdminCcs" );
+                is ($MIME->head->mime_type , "text/plain", "The only part is text/plain ");
+                 my $subject  = $MIME->head->get("subject");
+                chomp($subject);
+                #is( $subject ,      /^=\?KOI8-R\?B\?W2V4YW1wbGUuY39tICM3XSDUxdPUINTF09Q=\?=/ , "The $subject is encoded correctly");
+               };
+                 ';
+}
+
+shift @RT::EmailInputEncodings;
+$RT::EmailOutputEncoding = 'utf-8';
+# }}}
+
+
+# {{{ test a message containing a nested RFC 822 message
+
+my $content =  `cat ./lib/t/data/nested-rfc-822` || die "couldn't find new content";
+ok ($content, "Loaded nested-rfc-822 to test");
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&text_plain_nested_redef_sendmessage;
+RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+is ($tick->Subject, "[Jonas Liljegren] Re: [Para] Niv\x{e5}er?");
+ok ($tick->Transactions->First->Attachments->First->ContentType =~ /multipart\/mixed/, "We recorded the content type right");
+is ($tick->Transactions->First->Attachments->Count , 5 , "Has one attachment, presumably a text-plain and a message RFC 822 and another plain");
+sub text_plain_nested_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { 
+                my $self = shift; 
+                my $MIME = shift; 
+                return (1) unless ($self->ScripObj->ScripActionObj->Name eq "Notify AdminCcs" );
+                is ($MIME->head->mime_type , "multipart/mixed", "It is a mixed multipart");
+                 my $subject  =  $MIME->head->get("subject");
+                 $subject  = MIME::Base64::decode_base64( $subject);
+                chomp($subject);
+               # TODO, why does this test fail
+                #ok($subject =~ qr{Niv\x{e5}er}, "The subject matches the word - $subject");
+               1;
+                 }';
+}
+
+# }}}
+
+
+
+
+# Don't taint the environment
+$everyone->PrincipalObj->RevokeRight(Right =>'SuperUser');
+1;
diff --git a/rt/lib/t/04_send_email.pl.in b/rt/lib/t/04_send_email.pl.in
new file mode 100644 (file)
index 0000000..e171cdc
--- /dev/null
@@ -0,0 +1,389 @@
+#!@PERL@ -w
+
+use strict;
+use RT::EmailParser;
+use RT::Tickets;
+use RT::Action::SendEmail;
+
+my @_outgoing_messages;
+my @scrips_fired;
+
+#We're not testing acls here.
+my $everyone = RT::Group->new($RT::SystemUser);
+$everyone->LoadSystemInternalGroup('Everyone');
+$everyone->PrincipalObj->GrantRight(Right =>'SuperUser');
+
+
+is (__PACKAGE__, 'main', "We're operating in the main package");
+
+
+{
+no warnings qw/redefine/;
+sub RT::Action::SendEmail::SendMessage {
+        my $self = shift;
+        my $MIME = shift;
+
+        main::_fired_scrip($self->ScripObj);
+        main::ok(ref($MIME) eq 'MIME::Entity', "hey, look. it's a mime entity");
+}
+
+}
+
+# instrument SendEmail to pass us what it's about to send.
+# create a regular ticket
+
+my $parser = RT::EmailParser->new();
+$parser->ParseMIMEEntityFromScalar('From: root@localhost
+To: rt@example.com
+Subject: This is a test of new ticket creation as an unknown user
+
+Blah!
+Foob!');
+
+                                  
+use Data::Dumper;
+
+my $ticket = RT::Ticket->new($RT::SystemUser);
+my ($id,  $tid, $msg ) = $ticket->Create(Requestor => ['root@localhost'], Queue => 'general', Subject => 'I18NTest', MIMEObj => $parser->Entity);
+ok ($id,$msg);
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject eq 'I18NTest', "failed to create the new ticket from an unprivileged account");
+
+# make sure it fires scrips.
+is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation");
+# make sure it sends an autoreply
+# make sure it sends a notification to adminccs
+
+
+# we need to swap out SendMessage to test the new things we care about;
+&utf8_redef_sendmessage;
+
+# create an iso 8859-1 ticket
+@scrips_fired = ();
+
+my $content =  `cat ./lib/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content";
+
+
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+use RT::Interface::Email;
+                                  
+ RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Content =~ /H\x{e5}vard/, "It's signed by havard. yay");
+
+
+# make sure it fires scrips.
+is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation");
+# make sure it sends an autoreply
+
+
+# make sure it sends a notification to adminccs
+
+# If we correspond, does it do the right thing to the outbound messages?
+
+$parser->ParseMIMEEntityFromScalar($content);
+my ($id, $msg) = $tick->Comment(MIMEObj => $parser->Entity);
+ok ($id, $msg);
+
+$parser->ParseMIMEEntityFromScalar($content);
+($id, $msg) = $tick->Correspond(MIMEObj => $parser->Entity);
+ok ($id, $msg);
+
+
+# we need to swap out SendMessage to test the new things we care about;
+&iso8859_redef_sendmessage;
+$RT::EmailOutputEncoding = 'iso-8859-1';
+# create an iso 8859-1 ticket
+@scrips_fired = ();
+
+my $content =  `cat ./lib/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content";
+# be as much like the mail gateway as possible.
+use RT::Interface::Email;
+                                  
+ RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Content =~ /H\x{e5}vard/, "It's signed by havard. yay");
+
+
+# make sure it fires scrips.
+is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation");
+# make sure it sends an autoreply
+
+
+# make sure it sends a notification to adminccs
+
+
+# If we correspond, does it do the right thing to the outbound messages?
+
+$parser->ParseMIMEEntityFromScalar($content);
+my ($id, $msg) = $tick->Comment(MIMEObj => $parser->Entity);
+ok ($id, $msg);
+
+$parser->ParseMIMEEntityFromScalar($content);
+($id, $msg) = $tick->Correspond(MIMEObj => $parser->Entity);
+ok ($id, $msg);
+
+
+sub _fired_scrip {
+        my $scrip = shift;
+        push @scrips_fired, $scrip;
+}       
+
+sub utf8_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval ' 
+    sub RT::Action::SendEmail::SendMessage {
+        my $self = shift;
+        my $MIME = shift;
+
+        my $scrip = $self->ScripObj->id;
+        ok(1, $self->ScripObj->ConditionObj->Name . " ".$self->ScripObj->ActionObj->Name);
+        main::_fired_scrip($self->ScripObj);
+        $MIME->make_singlepart;
+        main::ok( ref($MIME) eq \'MIME::Entity\',
+                  "hey, look. it\'s a mime entity" );
+        main::ok( ref( $MIME->head ) eq \'MIME::Head\',
+                  "its mime header is a mime header. yay" );
+        main::ok( $MIME->head->get(\'Content-Type\') =~ /utf-8/,
+                  "Its content type is utf-8" );
+        my $message_as_string = $MIME->bodyhandle->as_string();
+        use Encode;
+        $message_as_string = Encode::decode_utf8($message_as_string);
+        main::ok(
+            $message_as_string =~ /H\x{e5}vard/,
+"The message\'s content contains havard\'s name. this will fail if it\'s not utf8 out");
+
+    }';
+}
+
+sub iso8859_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval ' 
+    sub RT::Action::SendEmail::SendMessage {
+        my $self = shift;
+        my $MIME = shift;
+
+        my $scrip = $self->ScripObj->id;
+        ok(1, $self->ScripObj->ConditionObj->Name . " ".$self->ScripObj->ActionObj->Name);
+        main::_fired_scrip($self->ScripObj);
+        $MIME->make_singlepart;
+        main::ok( ref($MIME) eq \'MIME::Entity\',
+                  "hey, look. it\'s a mime entity" );
+        main::ok( ref( $MIME->head ) eq \'MIME::Head\',
+                  "its mime header is a mime header. yay" );
+        main::ok( $MIME->head->get(\'Content-Type\') =~ /iso-8859-1/,
+                  "Its content type is iso-8859-1 - " . $MIME->head->get("Content-Type") );
+        my $message_as_string = $MIME->bodyhandle->as_string();
+        use Encode;
+        $message_as_string = Encode::decode("iso-8859-1",$message_as_string);
+        main::ok(
+            $message_as_string =~ /H\x{e5}vard/, "The message\'s content contains havard\'s name. this will fail if it\'s not utf8 out");
+
+    }';
+}
+
+# {{{ test a multipart alternative containing a text-html part with an umlaut
+
+my $content =  `cat ./lib/t/data/multipart-alternative-with-umlaut` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&umlauts_redef_sendmessage;
+
+RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Content =~ /causes Error/, "We recorded the content right as text-plain");
+is ($tick->Transactions->First->Attachments->Count , 3 , "Has three attachments, presumably a text-plain, a text-html and a multipart alternative");
+
+sub umlauts_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { }';
+}
+
+# }}}
+
+# {{{ test a text-html message with an umlaut
+
+my $content =  `cat ./lib/t/data/text-html-with-umlaut` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&text_html_umlauts_redef_sendmessage;
+
+RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Attachments->First->Content =~ /causes Error/, "We recorded the content as containing 'causes error'");
+ok ($tick->Transactions->First->Attachments->First->ContentType =~ /text\/html/, "We recorded the content as text/html");
+ok ($tick->Transactions->First->Attachments->Count ==1 , "Has one attachment, presumably a text-html and a multipart alternative");
+
+sub text_html_umlauts_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { 
+                my $self = shift; 
+                my $MIME = shift; 
+                use Data::Dumper;
+                return (1) unless ($self->ScripObj->ScripActionObj->Name eq "Notify AdminCcs" );
+                ok (is $MIME->parts, 2, "generated correspondence mime entityis composed of three parts");
+                is ($MIME->head->mime_type , "multipart/mixed", "The first part is a multipart mixed". $MIME->head->mime_type);
+                is ($MIME->parts(0)->head->mime_type , "text/plain", "The second part is a plain");
+                is ($MIME->parts(1)->head->mime_type , "text/html", "The third part is an html ");
+                 }';
+}
+
+# }}}
+
+# {{{ test a text-html message with russian characters
+
+my $content =  `cat ./lib/t/data/text-html-in-russian` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&text_html_russian_redef_sendmessage;
+
+RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Attachments->First->ContentType =~ /text\/html/, "We recorded the content right as text-html");
+ok ($tick->Transactions->First->Attachments->Count ==1 , "Has one attachment, presumably a text-html and a multipart alternative");
+
+sub text_html_russian_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { 
+                my $self = shift; 
+                my $MIME = shift; 
+                use Data::Dumper;
+                return (1) unless ($self->ScripObj->ScripActionObj->Name eq "Notify AdminCcs" );
+                ok (is $MIME->parts, 2, "generated correspondence mime entityis composed of three parts");
+                is ($MIME->head->mime_type , "multipart/mixed", "The first part is a multipart mixed". $MIME->head->mime_type);
+                is ($MIME->parts(0)->head->mime_type , "text/plain", "The second part is a plain");
+                is ($MIME->parts(1)->head->mime_type , "text/html", "The third part is an html ");
+                my $content_1251;
+                $content_1251 = $MIME->parts(1)->bodyhandle->as_string();
+                ok ($content_1251 =~ qr{Ó÷eáíûé Öeíòp "ÊÀÄÐÛ ÄÅËÎÂÎÃΠÌÈÐÀ" ïpèãëaøaeò ía òpeíèíã:},
+"Content matches drugim in codepage 1251" );
+                 }';
+}
+
+# }}}
+
+# {{{ test a message containing a russian subject and NO content type
+
+unshift (@RT::EmailInputEncodings, 'koi8-r');
+$RT::EmailOutputEncoding = 'koi8-r';
+my $content =  `cat ./lib/t/data/russian-subject-no-content-type` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&text_plain_russian_redef_sendmessage;
+RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Attachments->First->ContentType =~ /text\/plain/, "We recorded the content type right");
+ok ($tick->Transactions->First->Attachments->Count ==1 , "Has one attachment, presumably a text-plain");
+is ($tick->Subject, "\x{442}\x{435}\x{441}\x{442} \x{442}\x{435}\x{441}\x{442}", "Recorded the subject right");
+sub text_plain_russian_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { 
+                my $self = shift; 
+                my $MIME = shift; 
+                return (1) unless ($self->ScripObj->ScripActionObj->Name eq "Notify AdminCcs" );
+                is ($MIME->head->mime_type , "text/plain", "The only part is text/plain ");
+                 my $subject  = $MIME->head->get("subject");
+                chomp($subject);
+                #is( $subject ,      /^=\?KOI8-R\?B\?W2V4YW1wbGUuY39tICM3XSDUxdPUINTF09Q=\?=/ , "The $subject is encoded correctly");
+               };
+                 ';
+}
+
+shift @RT::EmailInputEncodings;
+$RT::EmailOutputEncoding = 'utf-8';
+# }}}
+
+
+# {{{ test a message containing a nested RFC 822 message
+
+my $content =  `cat ./lib/t/data/nested-rfc-822` || die "couldn't find new content";
+ok ($content, "Loaded nested-rfc-822 to test");
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&text_plain_nested_redef_sendmessage;
+RT::Interface::Email::Gateway(message => $content, queue => 1, action => 'correspond');
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+is ($tick->Subject, "[Jonas Liljegren] Re: [Para] Niv\x{e5}er?");
+ok ($tick->Transactions->First->Attachments->First->ContentType =~ /multipart\/mixed/, "We recorded the content type right");
+is ($tick->Transactions->First->Attachments->Count , 5 , "Has one attachment, presumably a text-plain and a message RFC 822 and another plain");
+sub text_plain_nested_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { 
+                my $self = shift; 
+                my $MIME = shift; 
+                return (1) unless ($self->ScripObj->ScripActionObj->Name eq "Notify AdminCcs" );
+                is ($MIME->head->mime_type , "multipart/mixed", "It is a mixed multipart");
+                 my $subject  =  $MIME->head->get("subject");
+                 $subject  = MIME::Base64::decode_base64( $subject);
+                chomp($subject);
+               # TODO, why does this test fail
+                #ok($subject =~ qr{Niv\x{e5}er}, "The subject matches the word - $subject");
+               1;
+                 }';
+}
+
+# }}}
+
+
+
+
+# Don't taint the environment
+$everyone->PrincipalObj->RevokeRight(Right =>'SuperUser');
+1;
diff --git a/rt/lib/t/data/8859-15-message-series/dir b/rt/lib/t/data/8859-15-message-series/dir
new file mode 100644 (file)
index 0000000..b9f8ec3
--- /dev/null
@@ -0,0 +1,356 @@
+Return-Path: <rt-users-admin@lists.fsck.com>
+Delivered-To: j@pallas.eruditorum.org
+Received: from pallas.eruditorum.org (localhost [127.0.0.1])
+       by pallas.eruditorum.org (Postfix) with ESMTP
+       id 72E3A111B3; Mon, 26 May 2003 14:50:14 -0400 (EDT)
+Delivered-To: rt-users@pallas.eruditorum.org
+Received: from mail-in-02.arcor-online.net (mail-in-02.arcor-online.net [151.189.21.42])
+       by pallas.eruditorum.org (Postfix) with ESMTP id 15E761118D
+       for <rt-users@lists.fsck.com>; Mon, 26 May 2003 14:49:56 -0400 (EDT)
+Received: from otdial-212-144-012-186.arcor-ip.net (otdial-212-144-011-024.arcor-ip.net [212.144.11.24])
+       by mail-in-02.arcor-online.net (Postfix) with ESMTP
+       id 745EE15E87; Mon, 26 May 2003 20:53:15 +0200 (CEST)
+From: Dirk Pape <pape-rt@inf.fu-berlin.de>
+To: Jesse Vincent <jesse@bestpractical.com>,
+       rt-users <rt-users@lists.fsck.com>
+Subject: Re: [rt-users] [rt-announce] Development Snapshot 3.0.2++
+Message-ID: <2147483647.1053982235@otdial-212-144-011-024.arcor-ip.net>
+In-Reply-To: <2147483647.1053974498@[10.0.255.35]>
+References: <20030523202405.GF23719@fsck.com>
+ <2147483647.1053974498@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="==========2147500486=========="
+Sender: rt-users-admin@lists.fsck.com
+Errors-To: rt-users-admin@lists.fsck.com
+X-BeenThere: rt-users@lists.fsck.com
+X-Mailman-Version: 2.0.12
+Precedence: bulk
+List-Help: <mailto:rt-users-request@lists.fsck.com?subject=help>
+List-Post: <mailto:rt-users@lists.fsck.com>
+List-Subscribe: <http://lists.fsck.com/mailman/listinfo/rt-users>,
+       <mailto:rt-users-request@lists.fsck.com?subject=subscribe>
+List-Id: For users of RT: Request Tracker <rt-users.lists.fsck.com>
+List-Unsubscribe: <http://lists.fsck.com/mailman/listinfo/rt-users>,
+       <mailto:rt-users-request@lists.fsck.com?subject=unsubscribe>
+List-Archive: <http://lists.fsck.com/pipermail/rt-users/>
+Date: Mon, 26 May 2003 20:50:36 +0200
+X-Spam-Status: No, hits=-2.5 required=5.0
+       tests=AWL,IN_REP_TO,KNOWN_MAILING_LIST,QUOTED_EMAIL_TEXT,
+             REFERENCES,REPLY_WITH_QUOTES
+       autolearn=ham version=2.55
+X-Spam-Level: 
+X-Spam-Checker-Version: SpamAssassin 2.55 (1.174.2.19-2003-05-19-exp)
+
+--==========2147500486==========
+Content-Type: text/plain; charset=us-ascii; format=flowed
+Content-Transfer-Encoding: 7bit
+Content-Disposition: inline
+
+Hello,
+
+here is the digest I forgot to attach. And I also forgot to say, that these 
+were the only messages after a restart of apache.
+
+The messages in the digest are the copies which I - for testing purpose - 
+allways queue into a mailbox just befor it is queued via rt-mailgate into 
+the rt-system.
+
+--Am Montag, 26. Mai 2003 18:41 Uhr +0200 schrieb Dirk Pape 
+<pape-rt@inf.fu-berlin.de>:
+
+> I attach a digest with mails I send one after another to the rt-system
+> and they get queued into one queue, each as a new ticket.
+
+
+
+
+--==========2147500486==========
+Content-Type: multipart/digest; boundary="==========2147489407=========="
+
+--==========2147489407==========
+Content-Type: message/rfc822; name="test _________"
+
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 27591 invoked by uid 9804); 26 May 2003 18:10:50 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:10:46 +0200
+Received: (Qmail 27575 invoked from network); 26 May 2003 18:10:46 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:10:46 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKYe-0000Yi-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:10:44 +0200
+Received: (qmail 27557 invoked by uid 9804); 26 May 2003 18:10:44 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:10:40 +0200
+Received: (Qmail 27540 invoked from network); 26 May 2003 18:10:40 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:10:40 +0200
+Date: Mon, 26 May 2003 18:11:00 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972660@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [27578] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
+
+--==========2147489407==========
+Content-Type: message/rfc822; name="test _________"
+
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 27754 invoked by uid 9804); 26 May 2003 18:11:24 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:11:20 +0200
+Received: (Qmail 27704 invoked from network); 26 May 2003 18:11:19 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:11:19 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKZA-0000Yy-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:11:16 +0200
+Received: (qmail 27690 invoked by uid 9804); 26 May 2003 18:11:16 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:11:13 +0200
+Received: (Qmail 27677 invoked from network); 26 May 2003 18:11:13 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:11:13 +0200
+Date: Mon, 26 May 2003 18:11:32 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972692@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [27711] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
+
+--==========2147489407==========
+Content-Type: message/rfc822; name="test _________"
+
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 27971 invoked by uid 9804); 26 May 2003 18:12:02 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:11:52 +0200
+Received: (Qmail 27908 invoked from network); 26 May 2003 18:11:52 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:11:52 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKZj-0000ZC-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:11:51 +0200
+Received: (qmail 27848 invoked by uid 9804); 26 May 2003 18:11:50 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:11:46 +0200
+Received: (Qmail 27809 invoked from network); 26 May 2003 18:11:45 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:11:45 +0200
+Date: Mon, 26 May 2003 18:12:05 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972725@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [27911] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
+
+--==========2147489407==========
+Content-Type: message/rfc822; name="test _________"
+
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 28283 invoked by uid 9804); 26 May 2003 18:12:39 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:12:36 +0200
+Received: (Qmail 28256 invoked from network); 26 May 2003 18:12:35 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:12:35 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKaQ-0000ZQ-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:12:34 +0200
+Received: (qmail 28236 invoked by uid 9804); 26 May 2003 18:12:34 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:12:30 +0200
+Received: (Qmail 28224 invoked from network); 26 May 2003 18:12:30 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:12:30 +0200
+Date: Mon, 26 May 2003 18:12:50 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972770@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [28259] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
+
+--==========2147489407==========
+Content-Type: message/rfc822; name="test _________"
+
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 28578 invoked by uid 9804); 26 May 2003 18:13:20 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:13:15 +0200
+Received: (Qmail 28534 invoked from network); 26 May 2003 18:13:14 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:13:14 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKb1-0000Ze-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:13:11 +0200
+Received: (qmail 28516 invoked by uid 9804); 26 May 2003 18:13:11 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:13:08 +0200
+Received: (Qmail 28479 invoked from network); 26 May 2003 18:13:07 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:13:07 +0200
+Date: Mon, 26 May 2003 18:13:27 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972807@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [28540] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
+
+
+--==========2147489407==========
+Content-Type: message/rfc822; name="test _________"
+
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 29108 invoked by uid 9804); 26 May 2003 18:14:15 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:14:10 +0200
+Received: (Qmail 29066 invoked from network); 26 May 2003 18:14:10 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:14:10 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKbw-0000Zr-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:14:08 +0200
+Received: (qmail 29054 invoked by uid 9804); 26 May 2003 18:14:08 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:14:04 +0200
+Received: (Qmail 29036 invoked from network); 26 May 2003 18:14:04 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:14:04 +0200
+Date: Mon, 26 May 2003 18:14:24 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972864@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [29069] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
+
+--==========2147489407==========
+Content-Type: message/rfc822; name="test _________"
+
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 29551 invoked by uid 9804); 26 May 2003 18:15:16 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:15:12 +0200
+Received: (Qmail 29521 invoked from network); 26 May 2003 18:15:12 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:15:12 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKcx-0000a4-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:15:11 +0200
+Received: (qmail 29511 invoked by uid 9804); 26 May 2003 18:15:10 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:15:07 +0200
+Received: (Qmail 29465 invoked from network); 26 May 2003 18:15:06 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:15:06 +0200
+Date: Mon, 26 May 2003 18:15:26 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972926@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [29524] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
+
+
+--==========2147489407==========--
+
+--==========2147500486==========--
+
+_______________________________________________
+rt-users mailing list
+rt-users@lists.fsck.com
+http://lists.fsck.com/mailman/listinfo/rt-users
+
+Have you read the FAQ? The RT FAQ Manager lives at http://fsck.com/rtfm
+
diff --git a/rt/lib/t/data/8859-15-message-series/msg1 b/rt/lib/t/data/8859-15-message-series/msg1
new file mode 100644 (file)
index 0000000..cc99c40
--- /dev/null
@@ -0,0 +1,36 @@
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 27591 invoked by uid 9804); 26 May 2003 18:10:50 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:10:46 +0200
+Received: (Qmail 27575 invoked from network); 26 May 2003 18:10:46 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:10:46 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKYe-0000Yi-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:10:44 +0200
+Received: (qmail 27557 invoked by uid 9804); 26 May 2003 18:10:44 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:10:40 +0200
+Received: (Qmail 27540 invoked from network); 26 May 2003 18:10:40 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:10:40 +0200
+Date: Mon, 26 May 2003 18:11:00 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972660@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [27578] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
+
diff --git a/rt/lib/t/data/8859-15-message-series/msg2 b/rt/lib/t/data/8859-15-message-series/msg2
new file mode 100644 (file)
index 0000000..dc442cf
--- /dev/null
@@ -0,0 +1,36 @@
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 27754 invoked by uid 9804); 26 May 2003 18:11:24 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:11:20 +0200
+Received: (Qmail 27704 invoked from network); 26 May 2003 18:11:19 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:11:19 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKZA-0000Yy-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:11:16 +0200
+Received: (qmail 27690 invoked by uid 9804); 26 May 2003 18:11:16 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:11:13 +0200
+Received: (Qmail 27677 invoked from network); 26 May 2003 18:11:13 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:11:13 +0200
+Date: Mon, 26 May 2003 18:11:32 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972692@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [27711] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
+
diff --git a/rt/lib/t/data/8859-15-message-series/msg3 b/rt/lib/t/data/8859-15-message-series/msg3
new file mode 100644 (file)
index 0000000..e23866d
--- /dev/null
@@ -0,0 +1,35 @@
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 27971 invoked by uid 9804); 26 May 2003 18:12:02 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:11:52 +0200
+Received: (Qmail 27908 invoked from network); 26 May 2003 18:11:52 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:11:52 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKZj-0000ZC-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:11:51 +0200
+Received: (qmail 27848 invoked by uid 9804); 26 May 2003 18:11:50 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:11:46 +0200
+Received: (Qmail 27809 invoked from network); 26 May 2003 18:11:45 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:11:45 +0200
+Date: Mon, 26 May 2003 18:12:05 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972725@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [27911] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
diff --git a/rt/lib/t/data/8859-15-message-series/msg4 b/rt/lib/t/data/8859-15-message-series/msg4
new file mode 100644 (file)
index 0000000..831695c
--- /dev/null
@@ -0,0 +1,35 @@
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 28283 invoked by uid 9804); 26 May 2003 18:12:39 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:12:36 +0200
+Received: (Qmail 28256 invoked from network); 26 May 2003 18:12:35 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:12:35 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKaQ-0000ZQ-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:12:34 +0200
+Received: (qmail 28236 invoked by uid 9804); 26 May 2003 18:12:34 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:12:30 +0200
+Received: (Qmail 28224 invoked from network); 26 May 2003 18:12:30 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:12:30 +0200
+Date: Mon, 26 May 2003 18:12:50 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972770@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [28259] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
diff --git a/rt/lib/t/data/8859-15-message-series/msg5 b/rt/lib/t/data/8859-15-message-series/msg5
new file mode 100644 (file)
index 0000000..272c93c
--- /dev/null
@@ -0,0 +1,35 @@
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 28578 invoked by uid 9804); 26 May 2003 18:13:20 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:13:15 +0200
+Received: (Qmail 28534 invoked from network); 26 May 2003 18:13:14 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:13:14 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKb1-0000Ze-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:13:11 +0200
+Received: (qmail 28516 invoked by uid 9804); 26 May 2003 18:13:11 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:13:08 +0200
+Received: (Qmail 28479 invoked from network); 26 May 2003 18:13:07 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:13:07 +0200
+Date: Mon, 26 May 2003 18:13:27 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972807@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [28540] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
diff --git a/rt/lib/t/data/8859-15-message-series/msg6 b/rt/lib/t/data/8859-15-message-series/msg6
new file mode 100644 (file)
index 0000000..3ae9d3b
--- /dev/null
@@ -0,0 +1,35 @@
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 29108 invoked by uid 9804); 26 May 2003 18:14:15 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:14:10 +0200
+Received: (Qmail 29066 invoked from network); 26 May 2003 18:14:10 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:14:10 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKbw-0000Zr-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:14:08 +0200
+Received: (qmail 29054 invoked by uid 9804); 26 May 2003 18:14:08 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:14:04 +0200
+Received: (Qmail 29036 invoked from network); 26 May 2003 18:14:04 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:14:04 +0200
+Date: Mon, 26 May 2003 18:14:24 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972864@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [29069] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
diff --git a/rt/lib/t/data/8859-15-message-series/msg7 b/rt/lib/t/data/8859-15-message-series/msg7
new file mode 100644 (file)
index 0000000..6149dd6
--- /dev/null
@@ -0,0 +1,36 @@
+Return-Path: <pape@inf.fu-berlin.de>
+Delivered-To: pape-rtdoublecheck@mi.fu-berlin.de
+Received: (qmail 29551 invoked by uid 9804); 26 May 2003 18:15:16 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:15:12 +0200
+Received: (Qmail 29521 invoked from network); 26 May 2003 18:15:12 +0200
+Received: From es.inf.fu-berlin.de (160.45.110.22)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:15:12 +0200
+Received: from leibniz ([160.45.40.10] helo=math.fu-berlin.de)
+       by es.inf.fu-berlin.de with smtp (Exim 3.35 #1 (Debian))
+       id 19KKcx-0000a4-00
+       for <staff@tec.mi.fu-berlin.de>; Mon, 26 May 2003 18:15:11 +0200
+Received: (qmail 29511 invoked by uid 9804); 26 May 2003 18:15:10 +0200
+Received: from localhost (HELO math.fu-berlin.de) (127.0.0.1)
+  by localhost with SMTP; 26 May 2003 18:15:07 +0200
+Received: (Qmail 29465 invoked from network); 26 May 2003 18:15:06 +0200
+Received: From eremix.inf.fu-berlin.de (HELO eremix) (160.45.113.36)
+  by leibniz.math.fu-berlin.de with SMTP; 26 May 2003 18:15:06 +0200
+Date: Mon, 26 May 2003 18:15:26 +0200
+From: Dirk Pape <pape@inf.fu-berlin.de>
+To: staff@tec.mi.fu-berlin.de
+Subject: =?ISO-8859-15?Q?test_=E4=F6=FC=DF=C4=D6=DC=DF=A4?=
+Message-ID: <2147483647.1053972926@[10.0.255.35]>
+X-Mailer: Mulberry/3.0.3 (Mac OS X)
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Envelope-Sender: pape@inf.fu-berlin.de
+X-Virus-Scanned: by AMaViS 0.3.12pre7-U23 [29524] (NAI-uvscan@math.fu-berlin.de)
+X-Remote-IP: 160.45.110.22
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-15; FORMAT=flowed
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+test nochmal in anderer Queue
+test =E4=F6=FC=DF=C4=D6=DC=DF=A4
+
diff --git a/rt/lib/t/data/multipart-alternative-with-umlaut b/rt/lib/t/data/multipart-alternative-with-umlaut
new file mode 100644 (file)
index 0000000..1ad4fe3
--- /dev/null
@@ -0,0 +1,62 @@
+Return-Path: <gst@example.com>
+Delivered-To: j@pallas.eruditorum.org
+Received: from vis.example.com (vis.example.com [212.68.68.251])
+       by pallas.eruditorum.org (Postfix) with SMTP id 59236111C3
+       for <jesse@example.com>; Thu, 12 Jun 2003 02:14:44 -0400 (EDT)
+Received: (qmail 29541 invoked by uid 502); 12 Jun 2003 06:14:42 -0000
+Received: from sivd.example.com (HELO example.com) (192.168.42.1)
+  by 192.168.42.42 with SMTP; 12 Jun 2003 06:14:42 -0000
+Received: received from 172.20.72.174 by odie.example.com; Thu, 12 Jun 2003 08:14:27 +0200
+Received: by mailserver.example.com with Internet Mail Service (5.5.2653.19) id <LJSB7T54>; Thu, 12 Jun 2003 08:14:39 +0200
+Message-ID: <50362EC956CBD411A339009027F6257E013DD495@mailserver.example.com>
+Date: Thu, 12 Jun 2003 08:14:39 +0200
+From: "Stever, Gregor" <gst@example.com>
+MIME-Version: 1.0
+X-Mailer: Internet Mail Service (5.5.2653.19)
+To: "'jesse@example.com'" <jesse@example.com>
+Subject: RE: [rt-users] HTML-encoded mails with umlaute
+Date: Thu, 12 Jun 2003 08:14:39 +0200
+Content-Type: multipart/alternative;
+       boundary="----_=_NextPart_001_01C330A9.E7BDD590"
+X-Spam-Status: No, hits=0.0 required=5.0
+       tests=AWL,HTML_50_60,HTML_MESSAGE,INVALID_DATE
+       version=2.55
+X-Spam-Level: 
+X-Spam-Checker-Version: SpamAssassin 2.55 (1.174.2.19-2003-05-19-exp)
+
+------_=_NextPart_001_01C330A9.E7BDD590
+Content-Type: text/plain;
+       charset="iso-8859-1"
+Content-Transfer-Encoding: quoted-printable
+
+Hello,
+
+ist this kind of Messages, that causes rt to crash.=20
+
+Mit freundlichen Gr=FC=DFen
+Gregor Stever      ^^causes Error!!
+
+
+------_=_NextPart_001_01C330A9.E7BDD590
+Content-Type: text/html;
+       charset="iso-8859-1"
+Content-Transfer-Encoding: quoted-printable
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML><HEAD>
+<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; charset=3Diso-8859-=
+1">
+
+
+<META content=3D"MSHTML 6.00.2800.1170" name=3DGENERATOR></HEAD>
+<BODY>
+<DIV><FONT face=3DArial><FONT size=3D2>Hello,<BR><BR>ist this kind of Messa=
+ges, that=20
+causes rt to crash.<BR><BR>Mit freundlichen Gr=FC=DFen<BR>Gregor=20
+Stever&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ^^causes Error<SPAN=20
+class=3D975501206-12062003>!!</SPAN></FONT></FONT></DIV></BODY></HTML>
+
+
+------_=_NextPart_001_01C330A9.E7BDD590--
+
+
diff --git a/rt/lib/t/data/nested-mime-sample b/rt/lib/t/data/nested-mime-sample
new file mode 100644 (file)
index 0000000..8b85d94
--- /dev/null
@@ -0,0 +1,396 @@
+Return-Path: <Xxxxxx_Yyyyyyy@some.net>
+Delivered-To: jesse@pallas.eruditorum.org
+Received: by pallas.eruditorum.org (Postfix)
+       id B5D3E1123A; Fri, 12 Jul 2002 11:35:27 -0400 (EDT)
+Delivered-To: rt-2.0-bugs@pallas.eruditorum.org
+Received: from postman.some.net (postman.some.net [193.0.0.199])
+       by pallas.eruditorum.org (Postfix) with SMTP id 2736011234
+       for <rt-2.0-bugs@fsck.com>; Fri, 12 Jul 2002 11:35:27 -0400 (EDT)
+Received: (qmail 11615 invoked by uid 0); 12 Jul 2002 15:35:26 -0000
+Received: from x22.some.net (HELO x22.some.net.some.net) (193.0.1.22)
+  by postman.some.net with SMTP; 12 Jul 2002 15:35:26 -0000
+Date: Fri, 12 Jul 2002 17:35:26 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+To: rt-0.0-bugs@fsck.com
+Subject: Example MIME within MIME within MIME message
+Message-ID: <Pine.LNX.4.44.0207121734250.25020-120000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: MULTIPART/MIXED; BOUNDARY="12654081-192303556-1026488126=:25020"
+X-Spam-Status: No, hits=4.0 required=7.0
+       tests=DOUBLE_CAPSWORD,MIME_NULL_BLOCK,MIME_MISSING_BOUNDARY
+       version=2.31
+Content-Length: 11478
+
+  This message is in MIME format.  The first part should be readable text,
+  while the remaining parts are likely unreadable without MIME-aware tools.
+  Send mail to mime@docserver.cac.washington.edu for more info.
+
+--12654081-192303556-1026488126=:25020
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+MIME is fun at times.
+
+
+-- 
+                             Xxxxxx Yyyyyyy                            SOME
+                   Systems/Network Engineer                             NCC
+                 www.some.net - PGP000C8B1B             Operations/Security
+
+--12654081-192303556-1026488126=:25020
+Content-Type: MULTIPART/Digest; BOUNDARY="12654081-2102091261-1026488126=:25020"
+Content-ID: <Pine.LNX.4.44.0207121734322.25020@x22.some.net>
+Content-Description: Digest of 2 messages
+
+  This message is in MIME format.  The first part should be readable text,
+  while the remaining parts are likely unreadable without MIME-aware tools.
+  Send mail to mime@docserver.cac.washington.edu for more info.
+
+--12654081-2102091261-1026488126=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121734320.25020@x22.some.net>
+Content-Description: first outer message (fwd)
+
+Date: Fri, 12 Jul 2002 17:32:37 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: first outer message
+Message-ID: <Pine.LNX.4.44.0207121732180.25020-120000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: MULTIPART/MIXED; BOUNDARY="12654081-113777422-1026487957=:25020"
+
+
+--12654081-113777422-1026487957=:25020
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+first outer message
+
+--12654081-113777422-1026487957=:25020
+Content-Type: MULTIPART/Digest; BOUNDARY="12654081-387266385-1026487957=:25020"
+Content-ID: <Pine.LNX.4.44.0207121732222.25020@x22.some.net>
+Content-Description: Digest of 2 messages
+
+--12654081-387266385-1026487957=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121732220.25020@x22.some.net>
+Content-Description: middle message (fwd)
+
+Date: Fri, 12 Jul 2002 17:31:45 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: middle message
+Message-ID: <Pine.LNX.4.44.0207121731190.25020-120000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: MULTIPART/MIXED; BOUNDARY="12654081-1711788944-1026487905=:25020"
+
+
+--12654081-1711788944-1026487905=:25020
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+This is the first middle message
+
+
+--12654081-1711788944-1026487905=:25020
+Content-Type: MULTIPART/Digest; BOUNDARY="12654081-1221085552-1026487905=:25020"
+Content-ID: <Pine.LNX.4.44.0207121731262.25020@x22.some.net>
+Content-Description: Digest of 2 messages
+
+--12654081-1221085552-1026487905=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121731260.25020@x22.some.net>
+Content-Description: This is the inner-most message (fwd)
+
+Date: Fri, 12 Jul 2002 17:30:31 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: This is the inner-most message
+Message-ID: <Pine.LNX.4.44.0207121730070.25020-100000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+
+inner-msg
+
+
+
+--12654081-1221085552-1026487905=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121731261.25020@x22.some.net>
+Content-Description: another inner message (need two before pine will do the mime-digest thing) (fwd)
+
+Date: Fri, 12 Jul 2002 17:31:12 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: another inner message (need two before pine will do the mime-digest
+ thing)
+Message-ID: <Pine.LNX.4.44.0207121730480.25020-100000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+
+again
+
+
+
+--12654081-1221085552-1026487905=:25020--
+--12654081-1711788944-1026487905=:25020--
+
+--12654081-387266385-1026487957=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121732221.25020@x22.some.net>
+Content-Description: middle message (fwd)
+
+Date: Fri, 12 Jul 2002 17:32:05 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: middle message
+Message-ID: <Pine.LNX.4.44.0207121731470.25020-120000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: MULTIPART/MIXED; BOUNDARY="12654081-1731270459-1026487925=:25020"
+
+
+--12654081-1731270459-1026487925=:25020
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+
+This is the second middle message
+
+
+--12654081-1731270459-1026487925=:25020
+Content-Type: MULTIPART/Digest; BOUNDARY="12654081-128832654-1026487925=:25020"
+Content-ID: <Pine.LNX.4.44.0207121731502.25020@x22.some.net>
+Content-Description: Digest of 2 messages
+
+--12654081-128832654-1026487925=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121731500.25020@x22.some.net>
+Content-Description: This is the inner-most message (fwd)
+
+Date: Fri, 12 Jul 2002 17:30:31 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: This is the inner-most message
+Message-ID: <Pine.LNX.4.44.0207121730070.25020-100000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+
+inner-msg
+
+
+
+--12654081-128832654-1026487925=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121731501.25020@x22.some.net>
+Content-Description: another inner message (need two before pine will do the mime-digest thing) (fwd)
+
+Date: Fri, 12 Jul 2002 17:31:12 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: another inner message (need two before pine will do the mime-digest
+ thing)
+Message-ID: <Pine.LNX.4.44.0207121730480.25020-100000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+
+again
+
+
+
+--12654081-128832654-1026487925=:25020--
+--12654081-1731270459-1026487925=:25020--
+
+--12654081-387266385-1026487957=:25020--
+--12654081-113777422-1026487957=:25020--
+
+--12654081-2102091261-1026488126=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121734321.25020@x22.some.net>
+Content-Description: 2nd outer message (fwd)
+
+Date: Fri, 12 Jul 2002 17:32:54 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: 2nd outer message
+Message-ID: <Pine.LNX.4.44.0207121732380.25020-120000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: MULTIPART/MIXED; BOUNDARY="12654081-1955637437-1026487974=:25020"
+
+
+--12654081-1955637437-1026487974=:25020
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+2nd outer message
+
+
+--12654081-1955637437-1026487974=:25020
+Content-Type: MULTIPART/Digest; BOUNDARY="12654081-362457126-1026487974=:25020"
+Content-ID: <Pine.LNX.4.44.0207121732412.25020@x22.some.net>
+Content-Description: Digest of 2 messages
+
+--12654081-362457126-1026487974=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121732410.25020@x22.some.net>
+Content-Description: middle message (fwd)
+
+Date: Fri, 12 Jul 2002 17:31:45 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: middle message
+Message-ID: <Pine.LNX.4.44.0207121731190.25020-120000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: MULTIPART/MIXED; BOUNDARY="12654081-1711788944-1026487905=:25020"
+
+
+--12654081-1711788944-1026487905=:25020
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+This is the first middle message
+
+
+--12654081-1711788944-1026487905=:25020
+Content-Type: MULTIPART/Digest; BOUNDARY="12654081-1221085552-1026487905=:25020"
+Content-ID: <Pine.LNX.4.44.0207121731262.25020@x22.some.net>
+Content-Description: Digest of 2 messages
+
+--12654081-1221085552-1026487905=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121731260.25020@x22.some.net>
+Content-Description: This is the inner-most message (fwd)
+
+Date: Fri, 12 Jul 2002 17:30:31 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: This is the inner-most message
+Message-ID: <Pine.LNX.4.44.0207121730070.25020-100000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+
+inner-msg
+
+
+
+--12654081-1221085552-1026487905=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121731261.25020@x22.some.net>
+Content-Description: another inner message (need two before pine will do the mime-digest thing) (fwd)
+
+Date: Fri, 12 Jul 2002 17:31:12 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: another inner message (need two before pine will do the mime-digest
+ thing)
+Message-ID: <Pine.LNX.4.44.0207121730480.25020-100000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+
+again
+
+
+
+--12654081-1221085552-1026487905=:25020--
+--12654081-1711788944-1026487905=:25020--
+
+--12654081-362457126-1026487974=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121732411.25020@x22.some.net>
+Content-Description: middle message (fwd)
+
+Date: Fri, 12 Jul 2002 17:32:05 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: middle message
+Message-ID: <Pine.LNX.4.44.0207121731470.25020-120000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: MULTIPART/MIXED; BOUNDARY="12654081-1731270459-1026487925=:25020"
+
+
+--12654081-1731270459-1026487925=:25020
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+
+This is the second middle message
+
+
+--12654081-1731270459-1026487925=:25020
+Content-Type: MULTIPART/Digest; BOUNDARY="12654081-128832654-1026487925=:25020"
+Content-ID: <Pine.LNX.4.44.0207121731502.25020@x22.some.net>
+Content-Description: Digest of 2 messages
+
+--12654081-128832654-1026487925=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121731500.25020@x22.some.net>
+Content-Description: This is the inner-most message (fwd)
+
+Date: Fri, 12 Jul 2002 17:30:31 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: This is the inner-most message
+Message-ID: <Pine.LNX.4.44.0207121730070.25020-100000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+
+inner-msg
+
+
+
+--12654081-128832654-1026487925=:25020
+Content-Type: MESSAGE/RFC822; CHARSET=US-ASCII
+Content-ID: <Pine.LNX.4.44.0207121731501.25020@x22.some.net>
+Content-Description: another inner message (need two before pine will do the mime-digest thing) (fwd)
+
+Date: Fri, 12 Jul 2002 17:31:12 +0200 (CEST)
+From: Xxxxxx Yyyyyyy <Xxxxxx_Yyyyyyy@some.net>
+X-X-Sender: bc@x22.some.net
+To: Xxxxxx_Yyyyyyy@some.net
+Subject: another inner message (need two before pine will do the mime-digest
+ thing)
+Message-ID: <Pine.LNX.4.44.0207121730480.25020-100000@x22.some.net>
+MIME-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+
+
+
+again
+
+
+
+--12654081-128832654-1026487925=:25020--
+--12654081-1731270459-1026487925=:25020--
+
+--12654081-362457126-1026487974=:25020--
+--12654081-1955637437-1026487974=:25020--
+
+--12654081-2102091261-1026488126=:25020--
+--12654081-192303556-1026488126=:25020--
+
diff --git a/rt/lib/t/data/nested-rfc-822 b/rt/lib/t/data/nested-rfc-822
new file mode 100644 (file)
index 0000000..d4f118d
--- /dev/null
@@ -0,0 +1,253 @@
+Return-Path: <jonas@astral.example.com>
+Delivered-To: j@pallas.eruditorum.org
+Received: from example.com (example.com [213.88.137.35])
+       by pallas.eruditorum.org (Postfix) with ESMTP id 869591115E
+       for <jesse@bestpractical.com>; Sun, 29 Jun 2003 18:04:04 -0400 (EDT)
+Received: from jonas by example.com with local (Exim 4.20)
+       id 19WkLK-0004Vr-0I
+       for jesse@bestpractical.com; Mon, 30 Jun 2003 00:08:18 +0200
+Resent-To: jesse@bestpractical.com
+Resent-From: Jonas Liljegren <jonas@example.com>
+Resent-Date: Mon, 30 Jun 2003 00:08:17 +0200
+Received: from mail by example.com with spam-scanned (Exim 4.20)
+       id 19Wayz-00068j-KO
+       for jonas@astral.example.com; Sun, 29 Jun 2003 14:08:42 +0200
+Received: from jonas by example.com with local (Exim 4.20)
+       id 19Wayz-00068g-FY
+       for red@example.com; Sun, 29 Jun 2003 14:08:37 +0200
+To: Redaktionen <red@example.com>
+Subject: [Jonas Liljegren] Re: [Para] =?iso-8859-1?q?Niv=E5er=3F?=
+From: Jonas Liljegren <jonas@example.com>
+Date: Sun, 29 Jun 2003 14:08:37 +0200
+Message-ID: <87d6gxt7ay.fsf@example.com>
+User-Agent: Gnus/5.1002 (Gnus v5.10.2) Emacs/21.2 (gnu/linux)
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="=-=-="
+Sender: Jonas Liljegren <jonas@astral.example.com>
+Resent-Message-Id: <E19WkLK-0004Vr-0I@example.com>
+Resent-Sender: Jonas Liljegren <jonas@astral.example.com>
+Resent-Date: Mon, 30 Jun 2003 00:08:18 +0200
+X-Spam-Status: No, hits=-5.7 required=5.0
+       tests=AWL,BAYES_10,EMAIL_ATTRIBUTION,MAILTO_WITH_SUBJ,
+             QUOTED_EMAIL_TEXT,USER_AGENT_GNUS_UA
+       version=2.55
+X-Spam-Level: 
+X-Spam-Checker-Version: SpamAssassin 2.55 (1.174.2.19-2003-05-19-exp)
+
+--=-=-=
+Content-Type: text/plain; charset=iso-8859-1
+Content-Transfer-Encoding: quoted-printable
+
+Material f=F6r att uppdatera texten om niv=E5er.
+
+Denna text b=F6r dessutom ligga som ett uppslagsord och inte d=E4r den ligg=
+er nu.
+
+
+--=-=-=
+Content-Type: message/rfc822
+Content-Disposition: inline
+
+Return-path: <list-bounces@example.com>
+Received: from mail by example.com with spam-scanned (Exim 4.20)
+       id 19WFzq-0005i1-WE
+       for jonas@example.com; Sat, 28 Jun 2003 15:44:13 +0200
+Received: from localhost
+       ([127.0.0.1] helo=example.com ident=list)
+       by example.com with esmtp (Exim 4.20)
+       id 19WFzp-0005hf-Tz; Sat, 28 Jun 2003 15:44:05 +0200
+Received: from mail by example.com with spam-scanned (Exim 4.20)
+       id 19WFzh-0005hR-Bu
+       for list@example.com; Sat, 28 Jun 2003 15:44:03 +0200
+Received: from jonas by example.com with local (Exim 4.20)
+       id 19WFzh-0005hO-AO
+       for list@example.com; Sat, 28 Jun 2003 15:43:57 +0200
+To: list@example.com
+Subject: Re: [Para] =?iso-8859-1?q?Niv=E5er=3F?=
+References: <002701c33d62$170fb2e0$a33740d5@TELIA.COM>
+       <002301c33d66$bf6483e0$d97864d5@remotel2tu76c8>
+       <64753.217.210.4.156.1056801224.squirrel@example.com>
+From: Jonas Liljegren <jonas@example.com>
+Date: Sat, 28 Jun 2003 15:43:57 +0200
+In-Reply-To: <64753.217.210.4.156.1056801224.squirrel@example.com> (Jakob
+       Carlsson's message of "Sat, 28 Jun 2003 13:53:44 +0200 (CEST)")
+Message-ID: <877k76uxk2.fsf@example.com>
+User-Agent: Gnus/5.1002 (Gnus v5.10.2) Emacs/21.2 (gnu/linux)
+X-BeenThere: list@example.com
+X-Mailman-Version: 2.1.2
+Precedence: list
+List-Id: &#214;ppen lista f&#246;r alla medlemmar  <list.example.com>
+List-Unsubscribe: <http://example.com/cgi-bin/mailman/listinfo/list>,
+       <mailto:list-request@example.com?subject=unsubscribe>
+List-Archive: <http://example.com/pipermail/list>
+List-Post: <mailto:list@example.com>
+List-Help: <mailto:list-request@example.com?subject=help>
+List-Subscribe: <http://example.com/cgi-bin/mailman/listinfo/list>,
+       <mailto:list-request@example.com?subject=subscribe>
+Sender: list-bounces@example.com
+Errors-To: list-bounces@example.com
+X-Spam-Status: No, hits=-7.0 required=5.0
+       tests=BAYES_00,EMAIL_ATTRIBUTION,IN_REP_TO,QUOTED_EMAIL_TEXT,
+             REFERENCES,REPLY_WITH_QUOTES,USER_AGENT_GNUS_UA
+       version=2.55
+X-Spam-Level: 
+X-Spam-Checker-Version: SpamAssassin 2.55 (1.174.2.19-2003-05-19-exp)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-1
+Content-Transfer-Encoding: quoted-printable
+
+"Jakob Carlsson" <esrange@example.com> writes:
+
+>> Om du g=E5r in p=E5 Hemsidan och sen p=E5 Torget.
+>> D=E4r ser du att det st=E5r ditt anv=E4ndarnamn och
+>> bredvid det Niv=E5 5.
+>> Klicka p=E5 niv=E5 5 s=E5 kommer du in p=E5 en sida som
+>>  f=F6rklarar allt om niv=E5systemet.
+>
+> Bra svar. Men jag k=E4nner f=F6r att ge en kort f=F6rklaring av niv=E5-sy=
+stemet.
+
+Jag skulle kunna l=E4gga en massa tid p=E5 at skriva samma sak om och om
+igen.  Fliker in h=E4r f=F6r att s=E4ga detta =E4nnu en g=E5ng...:
+
+ * Det =E4r jag som hittat p=E5 det h=E4r med niv=E5system
+
+ * Det =E4r en stor skillnad p=E5 hur det =E4r t=E4nkt att vara och hur det=
+ =E4r
+   nu.  Jag har stora planer och en massa id=E9er jag vill genomf=F6ra.
+
+ * Niv=E5systemet =E4r en =E5terkoppling f=F6r vad man gjort f=F6r webbplat=
+sen.
+   Som ett tack g=F6r hj=E4lpen.
+
+ * Systemet finns som en inspiration f=F6r de som d=E5 k=E4nner f=F6r att g=
+=F6ra
+   mer.  Men jag vill inte att det ska ge en negativ influens f=F6r de
+   som inte gillar niv=E5er.  Var och en ska kunna v=E4lja att ignorera
+   niv=E5n.  Speciellt b=F6r de f=F6rst=E5 att det inte har att g=F6ra med
+   graden av andlig utveckling, esoteriska kunskaper eller n=E5got
+   s=E5dant.
+
+ * Inspirationen till niv=E5erna kommer fr=E5n spel, hemliga ordenssystem,
+   kosmska hiearkier, skr=E5v=E4sen, akademier, politisk administration,
+   osv.  Det =E4r ett element av rollspel. En lek.
+
+ * Olika niv=E5er motsvarar olika roller p=E5 webbplatsen.  Webbplatsen
+   webbmaster och ansvbariga har en viss niv=E5, bes=F6kare och g=E4ster har
+   en annan niv=E5.
+
+ * Alla datorsystem har administrat=F6rssystem f=F6r dem som sk=F6ter
+   systemet.  Jag har valt att arrangera dessa funktioner i en skala.
+   Niv=E5n anger hur mycket av systemet du har r=E4tt att administrera.
+
+ * Att ha ett niv=E5system f=F6r access g=F6r att man kan g=F6ra som p=E5 f=
+ilm;
+   att l=E5ta de med h=F6gre access komma =E5t mer information.  De med
+   riktigt h=F6g niv=E5 kan n=E5 topphemlig information.  P=E5 denna webbpl=
+ats
+   kan varje anv=E4ndae v=E4lja att h=E5lla vissa personliga uppgifter.  Har
+   du h=F6g niv=E5 har du rollen som anv=E4ndaradministrat=F6r och har
+   tillg=E5ng till dessa uppgifter.  Just nu =E4r vi tre personer med
+   denna niv=E5n.
+
+ * Niv=E5systemet =E4r ett m=E5tt p=E5 p=E5litlighet.  Vi ger dig h=F6gre n=
+iv=E5 n=E4r
+   vi litar p=E5 att du inte kommer att f=F6rst=F6ra f=F6r oss.  F=F6r ju h=
+=F6gre
+   niv=E5, desto l=E4ttare kan du sabbotera inneh=E5llet.
+
+ * P=E5 en h=F6gre niv=E5 beh=F6vs det inte bara att vi litar p=E5 att du v=
+ill
+   v=E4l.  Du m=E5ste =E4ven ha ett gott omd=F6me, teknisk f=F6rst=E5else,
+   intresse och logiskt t=E4nkande.  Utan detta =E4r det l=E4tt h=E4nt att =
+du
+   f=F6rst=F6r saker av misstag.
+
+ * Vi vill uppmuntra medlemmarna att g=F6ra det som =E4r bra f=F6r
+   webbplatsen.  Tilldelandet av h=F6gre niv=E5 ska uppmuntra till att
+   g=F6ra det som =E4r bra.
+
+ * F=F6r att minska missbruk av e-postadresser visar vi e-postadresser
+   bara f=F6r de med lite h=F6gre niv=E5.  P=E5 s=E5 vis vill vi undvika att
+   n=E5gon g=E5r med som medlem bara f=F6r att samla e-postadresser f=F6r a=
+tt
+   sedan g=F6ra reklamutskick.
+
+ * Idag n=E5r du olika niv=E5er p=E5 detta vis:
+
+   0. Kom in p=E5 webbplatsen som g=E4st
+
+   1. V=E4lj anv=E4ndarnamn och ange e-postadress
+
+   2. Logga in med det l=F6senord som skickats till dig
+
+   3. Skrivit en presentation
+
+   5. Presentationen har godk=E4nts
+
+   6. Du har svarat p=E5 ett f=E5tal fr=E5gor om dina intressen
+
+   7. Du har svarat p=E5 en massa fr=E5gor om intressen och beskrivit dem
+      detaljerat
+
+  10. N=E5gon v=E4ktare tycker du f=F6rtj=E4nar h=F6gre niv=E5 f=F6r att du=
+ =E4r s=E5
+      trevlig och engagerad i webbplatsen.
+
+  11. Du har gjort ett antal kopplingar mellan =E4mnen och =F6verv=E4gande
+      delan av dem har godk=E4nts av en v=E4ktare, och du accepterar att
+      b=F6rja som l=E4rling i v=E4ktarakademin (jobbet som
+      systemadministrat=F6r)
+
+  12-39. D=E5 och d=E5 tittar jag p=E5 vad du gjort i form av skrivande av
+      texter och arbetande med uppslagsverkets =E4mnen, och justerar din
+      niv=E5 i f=F6rh=E5llande till m=E4ngd och kvalit=E9 p=E5 arbetet
+
+  40. Du har full=E4ndat ett helt =E4mnesomr=E5de.  En m=E4ngd sammanl=E4nk=
+ade
+      =E4mnen med bra textinneh=E5ll.
+
+  41. F=F6rtroende att arbeta med adminstration av medlemsregistret.
+
+  42. Delaktig i utvecklandet av webbplatsens prgrammering.
+
+
+ * Allts=E5.  Automatik tar dig till niv=E5 7.
+
+ * Men som sagt.  Jag har en massa andra planer d=E4r mycket mer kopplas
+   till niv=E5er och d=E4r det finns systemautomatik f=F6r hela v=E4gen till
+   niv=E5 40.
+
+ * 41 och 42 ligger utanf=F6r niv=E5systemet i =F6vrigt.  Den som har de
+   niv=E5erna har inte n=F6dv=E4ndigtvis tagit sig till niv=E5 40 innan. De
+   motsvaras av anv=E4ndaradministrat=F6r och systemadministrat=F6r och
+   niv=E5n speglar maktbefogenheterna snarare =E4n vad man i =F6vrigt gjort
+   f=F6r webbplatsen.
+
+ * Alla texter. Allt inneh=E5ll =E4r =F6ppet f=F6r alla. =C4ven f=F6r bes=
+=F6kare som
+   inte loggar in.  Du kan till och med g=E5 in p=E5
+   administrationssidorna utan att logga in.  Vi g=F6mmer inte inneh=E5ll.
+   Det vi g=F6r =E4r att hindra dig fr=E5n att =E4ndra inneh=E5llet.  Vi d=
+=F6ljer
+   dock en del information om andra medlemmar i syfte att f=E5 s=E5 m=E5nga
+   som m=F6jligt att sj=E4lv skriva in sig och skriva en presentation.
+
+--=20
+/ Jonas  -  http://jonas.example.com/myself/en/index.html
+
+_______________________________________________
+List mailing list
+List@example.com
+http://example.com/cgi-bin/mailman/listinfo/list
+
+
+--=-=-=
+
+
+
+-- 
+/ Jonas  -  http://jonas.example.com/myself/en/index.html
+
+--=-=-=--
+
diff --git a/rt/lib/t/data/new-ticket-from-iso-8859-1 b/rt/lib/t/data/new-ticket-from-iso-8859-1
new file mode 100644 (file)
index 0000000..299392d
--- /dev/null
@@ -0,0 +1,31 @@
+Return-Path: <hw@nordkapp.net>
+Delivered-To: j@pallas.eruditorum.org
+Received: from sm1.nordkapp.net (sm1.nordkapp.net [62.70.54.150])
+       by pallas.eruditorum.org (Postfix) with ESMTP id 48F4E11112
+       for <jesse@bestpractical.com>; Mon,  2 Jun 2003 14:58:37 -0400 (EDT)
+Received: (qmail 3612 invoked by uid 1009); 2 Jun 2003 18:58:36 -0000
+Received: from unknown (HELO office.nordkapp.net) (213.161.186.83)
+  by 0 with SMTP; 2 Jun 2003 18:58:36 -0000
+Message-Id: <5.2.1.1.0.20030602205708.0314c5f8@mail.nordkapp.net>
+X-Sender: hw@nordkapp.net@mail.nordkapp.net
+X-Mailer: QUALCOMM Windows Eudora Version 5.2.1
+Date: Mon, 02 Jun 2003 20:58:30 +0200
+To: Jesse Vincent <jesse@bestpractical.com>
+From: Wilhelmsen Håvard <hw@nordkapp.net>
+Subject: Re: rt-3.0.3pre1
+In-Reply-To: <20030602185607.GN10811@fsck.com>
+References: <5.2.1.1.0.20030602204834.031406d8@mail.nordkapp.net>
+ <5.2.1.1.0.20030530194214.0371c988@mail.nordkapp.net>
+ <5.2.1.1.0.20030530194214.0371c988@mail.nordkapp.net>
+ <5.2.1.1.0.20030602204834.031406d8@mail.nordkapp.net>
+Mime-Version: 1.0
+Content-Type: text/plain; charset="iso-8859-1"; format=flowed
+Content-Transfer-Encoding: 8bit
+X-Spam-Status: No, hits=-1.9 required=5.0
+       tests=AWL,EMAIL_ATTRIBUTION,IN_REP_TO,QUOTED_EMAIL_TEXT,
+             REFERENCES,REPLY_WITH_QUOTES
+       autolearn=ham version=2.55
+X-Spam-Level: 
+X-Spam-Checker-Version: SpamAssassin 2.55 (1.174.2.19-2003-05-19-exp)
+
+Håvard
diff --git a/rt/lib/t/data/new-ticket-from-iso-8859-1-full b/rt/lib/t/data/new-ticket-from-iso-8859-1-full
new file mode 100644 (file)
index 0000000..493ca15
--- /dev/null
@@ -0,0 +1,38 @@
+X-Mailer: QUALCOMM Windows Eudora Version 5.2.1
+To: Jesse Vincent <jesse@bestpractical.com>
+From: Wilhelmsen Håvard <hw@nordkapp.net>
+Subject: Re: rt-3.0.3pre1
+X-Spam-Status: No, hits=-1.9 required=5.0
+       tests=AWL,EMAIL_ATTRIBUTION,IN_REP_TO,QUOTED_EMAIL_TEXT,
+             REFERENCES,REPLY_WITH_QUOTES
+       autolearn=ham version=2.55
+X-Spam-Level: 
+X-Spam-Checker-Version: SpamAssassin 2.55 (1.174.2.19-2003-05-19-exp)
+
+At 14:56 02.06.2003 -0400, you wrote:
+>> This patch didn't help us out.
+>> We still got problems with auto responding e-mails sent from the system
+>> when a new ticket is created.
+>> The same problem appears when one of the staff replays to an new ticket.
+>> All Norwegian letters is converted to strange letters like Ã¸
+>>
+>> We would love if this bug could be fixed. On our mail server we are 
+>running
+>> perl 5.6.1 since we are using debian stabel packet lists.
+>
+>I'd love it too. I just can't find it. Can you send me
+>(jesse@bestpractical.com) a couple of email messages containing
+>characters that break your RT?
+
+Hello again,
+
+Thanks for your fast replay!
+
+I don't know how this looks at your end but it is letters like: ø æ å
+If your want to make this in html it will be &oslash; &aring; and &aerlig;
+
+
+-- 
+Håvard 
+
+
diff --git a/rt/lib/t/data/russian-subject-no-content-type b/rt/lib/t/data/russian-subject-no-content-type
new file mode 100644 (file)
index 0000000..03d95b8
--- /dev/null
@@ -0,0 +1,42 @@
+Return-Path: <mitya@fling-wing.example.com>
+X-Real-To: <mitya@second.example.com>
+Received: from [194.87.5.31] (HELO sinbin.example.com)
+  by cgp.second.example.com (CommuniGate Pro SMTP 4.0.5/D)
+  with ESMTP-TLS id 69661026 for mitya@second.example.com; Wed, 18 Jun 2003 11:14:49 +0400
+Received: (from daemon@localhost)
+       by sinbin.example.com (8.12.8/8.11.6) id h5I7EfOj096595
+       for mitya@second.example.com; Wed, 18 Jun 2003 11:14:41 +0400 (MSD)
+       (envelope-from mitya@fling-wing.example.com)
+Received: from example.com by sinbin.example.com with ESMTP id h5I7Ee8K096580;
+       (8.12.9/D) Wed, 18 Jun 2003 11:14:40 +0400 (MSD)
+X-Real-To: <mitya@second.example.com>
+Received: from [194.87.0.31] (HELO mail.example.com)
+  by example.com (CommuniGate Pro SMTP 4.1b7/D)
+  with ESMTP id 76217696 for mitya@example.com; Wed, 18 Jun 2003 11:14:40 +0400
+Received: by mail.example.com (CommuniGate Pro PIPE 4.1b7/D)
+  with PIPE id 63920083; Wed, 18 Jun 2003 11:14:40 +0400
+Received: from [194.87.5.69] (HELO fling-wing.example.com)
+  by mail.example.com (CommuniGate Pro SMTP 4.1b7/D)
+  with ESMTP-TLS id 63920055 for mitya@example.com; Wed, 18 Jun 2003 11:14:38 +0400
+Received: from fling-wing.example.com (localhost [127.0.0.1])
+       by fling-wing.example.com (8.12.9/8.12.6) with ESMTP id h5I7Ec5R000153
+       for <mitya@example.com>; Wed, 18 Jun 2003 11:14:38 +0400 (MSD)
+       (envelope-from mitya@fling-wing.example.com)
+Received: (from mitya@localhost)
+       by fling-wing.example.com (8.12.9/8.12.6/Submit) id h5I7Ec0J000152
+       for mitya@example.com; Wed, 18 Jun 2003 11:14:38 +0400 (MSD)
+Date: Wed, 18 Jun 2003 11:14:38 +0400 (MSD)
+From: "Dmitry S. Sivachenko" <mitya@fling-wing.example.com>
+Message-Id: <200306180714.h5I7Ec0J000152@fling-wing.example.com>
+To: mitya@example.com
+Subject: ÔÅÓÔ ÔÅÓÔ
+X-Spam-Checker-Version: SpamAssassin 2.60-cvs-mail.demos (1.193-2003-06-13-exp)
+X-Spam-Level: +
+X-Spam-Status: No, hits=1.0 required=5.0 tests=SUBJ_ILLEGAL_CHARS autolearn=no
+       version=2.60-cvs-mail.demos
+X-Spam-Report: * SUBJ_ILLEGAL_CHARS  1.0 (Subject contains too many raw illegal characters)
+       
+Content-Length: 6
+
+ôåóô
+
diff --git a/rt/lib/t/data/text-html-in-russian b/rt/lib/t/data/text-html-in-russian
new file mode 100644 (file)
index 0000000..b965b1b
--- /dev/null
@@ -0,0 +1,87 @@
+From rickt@other-example.com  Tue Jun 17 20:39:13 2003
+Return-Path: <rickt@other-example.com>
+X-Original-To: info
+Delivered-To: mitya@vh.example.com
+Received: from example.com (mx.example.com [194.87.0.32])
+       by vh.example.com (Postfix) with ESMTP id 8D77B16E6BD
+       for <info>; Tue, 17 Jun 2003 20:39:05 +0400 (MSD)
+Received: from hotline@example.com
+  by example.com (CommuniGate Pro GROUP 4.1b7/D)
+  with GROUP id 76033026; Tue, 17 Jun 2003 20:38:00 +0400
+Received: by example.com (CommuniGate Pro PIPE 4.1b7/D)
+  with PIPE id 76033052; Tue, 17 Jun 2003 20:38:00 +0400
+Received: from [217.132.49.75] (HELO compuserve.com)
+  by example.com (CommuniGate Pro SMTP 4.1b7/D)
+  with SMTP id 76032971 for info@example.com; Tue, 17 Jun 2003 20:37:41 +0400
+Date: Wed, 18 Jun 2003 01:41:01 +0000
+From: Ó÷åáíûé Öåíòð <rickt@other-example.com>
+Subject: Ïðèãëàøàåì ðóêîâîäèòåëÿ, íà÷àëüíèêîâ ïîäðàçäåëåíèé íà òðåíèíã                                                         YXLWLJ3LPT9UHuLyGTzyuKQc06eIZ96Y6RVTCZFt
+To: Info <info@example.com>
+References: <0ID97EGL951H1907@example.com>
+In-Reply-To: <0ID97EGL951H1907@example.com>
+Message-ID: <HDE46LIK8GGJJ72I@other-example.com>
+MIME-Version: 1.0
+Content-Type: text/html; charset=Windows-1251
+Content-Transfer-Encoding: 8bit
+X-Spam-Flag: YES
+X-Spam-Checker-Version: SpamAssassin 2.60-cvs-jumbo.demos (1.190-2003-06-01-exp)
+X-Spam-Level: ++++++++++++++
+X-Spam-Status: Yes, hits=14.9 required=5.0 tests=BAYES_99,DATE_IN_FUTURE_06_12
+       FROM_ILLEGAL_CHARS,HTML_10_20,HTML_FONTCOLOR_UNKNOWN,HTML_FONT_BIG
+       MIME_HTML_ONLY,RCVD_IN_NJABL,SUBJ_HAS_SPACES,SUBJ_HAS_UNIQ_ID
+       SUBJ_ILLEGAL_CHARS autolearn=no version=2.60-cvs-jumbo.demos
+X-Spam-Report: 14.9 points, 5.0 required;
+       *  2.3 -- Subject contains lots of white space
+       *  1.0 -- BODY: HTML font color is unknown to us
+       *  0.3 -- BODY: FONT Size +2 and up or 3 and up
+                 [score: 1.0000]
+       *  2.8 -- BODY: Bayesian classifier spam probability is 99 to 100%
+       *  1.0 -- BODY: Message is 10% to 20% HTML
+       *  1.0 -- From contains too many raw illegal characters
+       *  1.0 -- Subject contains a unique ID
+       *  1.0 -- Subject contains too many raw illegal characters
+       *  1.2 -- Date: is 6 to 12 hours after Received: date
+                 [217.132.49.75 listed in dnsbl.njabl.org]
+       *  1.2 -- RBL: Received via a relay in dnsbl.njabl.org
+       *  2.0 -- Message only has text/html MIME parts
+Status: RO
+Content-Length: 2743
+Lines: 36
+
+<html><body><basefont face="times new roman, times, serif" size="2">
+<center>Ó÷eáíûé Öeíòp "ÊÀÄÐÛ ÄÅËÎÂÎÃΠÌÈÐÀ" ïpèãëaøaeò ía òpeíèíã:<br>
+<font size="5"><b>ÌÎÒÈÂÀÖÈß ÊÀÊ ÈÍÑÒÐÓÌÅÍÒ ÓÏÐÀÂËÅÍÈß ÏÅÐÑÎÍÀËÎÌ</b></font><br>
+<font color="red"><b>19 èþíÿ 2003 ã.</b></font><br>
+<b><i>Òpeíèíã ïpeäíaçía÷eí äëÿ âûcøeão è cpeäíeão óïpaâëeí÷ecêoão ïepcoíaëa.</i></b><br></center><br>
+<p align="justify"><b>Òpeíep: Áopìoòoâ Ïaâeë.</b> Ïpaêòè÷ecêèé ïcèõoëoã, oïûò paáoòû áoëee 10 ëeò â oáëacòè ïcèõoëoãèè è áèçíec-òpeíèíãoâ. Àâòop pÿäa ïóáëèêaöèé è ìeòoäè÷ecêèõ ïocoáèé paçëè÷íûõ íaïpaâëeíèé ïcèõoëoãèè, â òoì ÷ècëe: \93Òeõíoëoãèÿ äeëoâoão oáùeíèÿ\94\93Òeõíèêè è ïpèeìû ýôôeêòèâíûõ ïepeãoâopoâ\94\93Ñòpaòeãèè ôopìèpoâaíèÿ êopïopaòèâíoão èìèäæa\94 è äp. Çaêoí÷èë ËÃÓ ôaêóëüòeò coöèaëüíoé ïcèõoëoãèè, Ðoccèécêóþ Àêaäeìèþ ãocóäapcòâeííoé cëóæáû ïpè Ïpeçèäeíòe ÐÔ, êópcû MBA.<br><br>
+<b><u>Öeëè òpeíèíãa:</u></b><br>
+1. Îcâoèòü ïpèeìû óïpaâëeíèÿ ìoòèâaöèeé;<br>
+2. Ïoëó÷èòü ïpaêòè÷ecêèe íaâûêè ìoòèâaöèè ïepcoíaëa ê paáoòe;<br>
+3. Îcâoèòü ocíoâíûe íaâûêè êoìaíäooápaçoâaíèÿ;<br>
+4. Îâëaäeòü ïpaêòè÷ecêèìè ìeòoäaìè coçäaíèÿ è ócèëeíèÿ paáo÷eé ìoòèâaöèè, êoìaíäooápaçoâaíèÿ.<br><br>
+<b><u>Çaäa÷è òpeíèíãa:</u></b><br>
+&nbsp;- Îcâoèòü ìeòoäû ïoáóæäeíèÿ äpóãèõ ëþäeé ê âûïoëíeíèþ oïpeäeëeííoé äeÿòeëüíocòè;<br>
+&nbsp;- Íaó÷èòücÿ íaïpaâëÿòü ïoáóæäeíèÿ coòpóäíèêoâ â cooòâeòcòâèe c çaäa÷aìè opãaíèçaöèè.<br><br>
+<b><u>Ñoäepæaíèe ïpoãpaììû:</u></b><br>
+<b>I. Ìaòepèaëüíûe è íeìaòepèaëüíûe ôopìû ìoòèâaöèè:</b><br>
+1. Ìecòo è poëü ìoòèâaöèè â óïpaâëeíèè ïepcoíaëoì;<br>
+2. Ïpaêòèêa óïpaâëeíèÿ opãaíèçaöèÿìè.<br>
+<b>II. Ïpaêòè÷ecêoe ïpèìeíeíèe ìoòèâaöèè â óïpaâëeíèè ïepcoíaëoì:</b><br>
+1. Àíòèìoòèâèpóþùèe pacïopÿæeíèÿ;<br>
+2. Ìoòèâaöèÿ è oöeíêa äeÿòeëüíocòè (poëü aòòecòaöèè coòpóäíèêoâ);<br>
+3. Ìoòèâaöèÿ è ïpaêòèêa íaêaçaíèé.<br><br>
+<b><u> çaâepøeíèè ïpoãpaììû ó÷acòíèêè cìoãóò:</u></b><br>
+1. Îpèeíòèpoâaòü coòpóäíèêoâ ía äocòèæeíèe oïpeäeëeííoão peçóëüòaòa;<br>
+2. Îâëaäeòü íeoáõoäèìûìè íaâûêaìè óïpaâëeíèÿ ìoòèâaöèeé ïepcoíaëa;<br>
+3. Ïpèìeíÿòü ïoëó÷eííûe çíaíèÿ â ïpaêòèêe óïpaâëeíèÿ ïepcoíaëoì;<br>
+4. Îïpeäeëÿòü èíäèâèäóaëüíûe ocoáeííocòè (ïpeäïo÷òeíèÿ) ìoòèâaöèè coòpóäíèêoâ â opãaíèçaöèè.<br>
+<i> õoäe òpeíèíãa ècïoëüçóeòcÿ paáo÷èé è cïpaâo÷íûé ìaòepèaë ïo ìoòèâaöèè è còèìóëèpoâaíèþ ïepcoíaëa poccèécêèõ êoìïaíèé. Ïo oêoí÷aíèè âûäaeòcÿ cepòèôèêaò.</i><br><br>
+<center>Ïpoäoëæèòeëüíocòü: 1 äeíü, 8 ÷acoâ (äâa ïepepûâa, oáeä)<br>
+<b>Ñòoèìocòü ó÷acòèÿ: 4 700 póáëeé áeç ÍÄÑ.</b><br>
+921-5862, 928-4156, 928-4200, 928-5321</center><br>
+<font size=1>  Åcëè èíôopìaöèÿ ïoäoáíoão poäa Âac íe èíòepecóeò è ïo äpóãèì âoïpocaì - ïèøèòe:  <a href="mailto:motiv@mailje.nl">seminar</a></font>
+<br><font size="1" color="#ffffff">3ZkRPb60QBbiHef1IRVl</font>
+</body></html>
+
+
+
diff --git a/rt/lib/t/data/text-html-with-umlaut b/rt/lib/t/data/text-html-with-umlaut
new file mode 100644 (file)
index 0000000..90e5d3f
--- /dev/null
@@ -0,0 +1,35 @@
+Return-Path: <gst@example.com>
+Delivered-To: j@pallas.eruditorum.org
+Received: from vis.example.com (vis.example.com [212.68.68.251])
+       by pallas.eruditorum.org (Postfix) with SMTP id 59236111C3
+       for <jesse@example.com>; Thu, 12 Jun 2003 02:14:44 -0400 (EDT)
+Received: (qmail 29541 invoked by uid 502); 12 Jun 2003 06:14:42 -0000
+Received: from sivd.example.com (HELO example.com) (192.168.42.1)
+  by 192.168.42.42 with SMTP; 12 Jun 2003 06:14:42 -0000
+Received: received from 172.20.72.174 by odie.example.com; Thu, 12 Jun 2003 08:14:27 +0200
+Received: by mailserver.example.com with Internet Mail Service (5.5.2653.19) id <LJSB7T54>; Thu, 12 Jun 2003 08:14:39 +0200
+Message-ID: <50362EC956CBD411A339009027F6257E013DD495@mailserver.example.com>
+Date: Thu, 12 Jun 2003 08:14:39 +0200
+From: "Stever, Gregor" <gst@example.com>
+MIME-Version: 1.0
+X-Mailer: Internet Mail Service (5.5.2653.19)
+To: "'jesse@example.com'" <jesse@example.com>
+Subject: An example of mail containing text-html with an umlaut in the content
+Date: Thu, 12 Jun 2003 08:14:39 +0200
+Content-Type: text/html;
+       charset="iso-8859-1"
+Content-Transfer-Encoding: quoted-printable
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML><HEAD>
+<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; charset=3Diso-8859-=
+1">
+
+
+<META content=3D"MSHTML 6.00.2800.1170" name=3DGENERATOR></HEAD>
+<BODY>
+<DIV><FONT face=3DArial><FONT size=3D2>Hello,<BR><BR>ist this kind of Messa=
+ges, that=20
+causes rt to crash.<BR><BR>Mit freundlichen Gr=FC=DFen<BR>Gregor=20
+Stever&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ^^causes Error<SPAN=20
+class=3D975501206-12062003>!!</SPAN></FONT></FONT></DIV></BODY></HTML>
diff --git a/rt/lib/t/regression/00placeholder b/rt/lib/t/regression/00placeholder
new file mode 100644 (file)
index 0000000..0afc604
--- /dev/null
@@ -0,0 +1 @@
+1;
diff --git a/rt/lib/t/regression/mime_tests b/rt/lib/t/regression/mime_tests
new file mode 100644 (file)
index 0000000..26e4dbf
--- /dev/null
@@ -0,0 +1,19 @@
+use RT::Ticket;
+use RT::Queue;
+
+use MIME::Parser;
+use File::Temp;
+use RT::EmailParser;
+
+open (HANDLE, "data/nested-mime-sample");
+my $parser = RT::EmailParser->new()
+ $parser->ParseMIMEEntityFromFileHandle(\*HANDLE);
+my $entity = $parser->Entity;
+
+my $q = RT::Queue->new($RT::SystemUser);
+$q->Load('general');
+ok ($q->Id, "Queue is loaded");
+my $Ticket = RT::Ticket->new($RT::SystemUser);
+my ($tid, $ttid, $msg) =$Ticket->Create( Queue => $q->Id, Subject => "Nested mime test", MIMEObj => $entity);
+ok ($tid, $msg);
+ok($Ticket->Id);
diff --git a/rt/lib/test.pl b/rt/lib/test.pl
deleted file mode 100644 (file)
index f0da5df..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-# Before `make install' is performed this script should be runnable with
-# `make test'. After `make install' it should work as `perl test.pl'
-
-######################### We start with some black magic to print on failure.
-
-# Change 1..1 below to 1..last_test_to_print .
-# (It may become useful if the test is moved to ./t subdirectory.)
-
-BEGIN { $| = 1; print "1..1\n"; }
-END {print "not ok 1\n" unless $loaded;}
-use RT;
-$loaded = 1;
-print "ok 1\n";
-
-######################### End of black magic.
-
-# Insert your test code below (better if it prints "ok 13"
-# (correspondingly "not ok 13") depending on the success of chunk 13
-# of the test code):
-
-use RT::Record;
-use RT::EasySearch;
-use RT::Handle;
-use RT::Ticket;
-use RT::Tickets;
-use RT::ACE;
-use RT::ACL;
-use RT::Watcher;
-use RT::Watchers;
-use RT::Scrip;
-use RT::Scrips;
-use RT::ScripAction;
-use RT::ScripCondition;
-use RT::ScripActions;
-use RT::ScripConditions;
-use RT::Transaction;
-use RT::Transactions;
-use RT::Group;
-use RT::GroupMembers;
-use RT::User;
-use RT::Users;
-use RT::CurrentUser;
-use RT::Attachment;
-use RT::Attachments;
-use RT::Keyword;
-use RT::Keywords;
-use RT::KeywordSelect;
-use RT::KeywordSelects;
-use RT::ObjectKeyword;
-use RT::ObjectKeywords;
-use RT::Date;
-
diff --git a/rt/m4/rt_enable_layout.m4 b/rt/m4/rt_enable_layout.m4
new file mode 100644 (file)
index 0000000..cadec1c
--- /dev/null
@@ -0,0 +1,36 @@
+dnl
+dnl @synopsis RT_ENABLE_LAYOUT()
+dnl
+dnl Enable a specific directory layout for the installation to use.
+dnl This configures a command-line parameter that can be specified
+dnl at ./configure invocation.
+dnl
+dnl The use of this feature in this way is a little hackish, but
+dnl better than a heap of options for every directory.
+dnl
+dnl This code is heavily borrowed *cough* from the Apache 2 code.
+dnl
+
+AC_DEFUN([RT_ENABLE_LAYOUT],[
+AC_ARG_ENABLE(layout,
+             AC_HELP_STRING([--enable-layout=LAYOUT],
+                            [Use a specific directory layout (Default: RT3)]),
+             LAYOUT=$enableval)
+
+if test "x$LAYOUT" = "x"; then
+       LAYOUT="RT3"
+fi
+RT_LAYOUT($srcdir/config.layout, $LAYOUT)
+AC_MSG_CHECKING(for chosen layout)
+if test "x$rt_layout_name" = "xno"; then
+       if test "x$LAYOUT" = "xno"; then
+               AC_MSG_RESULT(none)
+       else
+               AC_MSG_RESULT($LAYOUT)
+       fi
+       AC_MSG_ERROR([a valid layout must be specified (or the default used)])
+else
+       AC_SUBST(rt_layout_name)
+       AC_MSG_RESULT($rt_layout_name)
+fi
+])
diff --git a/rt/m4/rt_expand_var.m4 b/rt/m4/rt_expand_var.m4
new file mode 100644 (file)
index 0000000..cec884a
--- /dev/null
@@ -0,0 +1,18 @@
+dnl
+dnl @synopsis  RT_EXPAND_VAR(baz, $fraz)
+dnl
+dnl Iteratively expands the second parameter, until successive iterations
+dnl yield no change. The result is then assigned to the first parameter.
+dnl
+dnl This code is heavily borrowed from the Apache 2 codebase.
+dnl
+
+AC_DEFUN([RT_EXPAND_VAR],[
+       ap_last=''
+       ap_cur='$2'
+       while test "x${ap_cur}" != "x${ap_last}"; do
+               ap_last="${ap_cur}"
+               ap_cur=`eval "echo ${ap_cur}"`
+       done
+       $1="${ap_cur}"
+])
diff --git a/rt/m4/rt_layout.m4 b/rt/m4/rt_layout.m4
new file mode 100644 (file)
index 0000000..393b321
--- /dev/null
@@ -0,0 +1,74 @@
+dnl
+dnl @synopsis RT_LAYOUT(configlayout, layoutname)
+dnl
+dnl This macro reads an Apache-style layout file (specified as the
+dnl configlayout parameter), and searches for a specific layout
+dnl (named using the layoutname parameter).
+dnl
+dnl The entries for a given layout are then inserted into the
+dnl environment such that they become available as substitution
+dnl variables. In addition, the rt_layout_name variable is set
+dnl (but not exported) if the layout is valid.
+dnl
+dnl This code is heavily borrowed *cough* from the Apache 2 codebase.
+dnl
+
+AC_DEFUN([RT_LAYOUT],[
+       if test ! -f $srcdir/config.layout; then
+               AC_MSG_WARN([Layout file $srcdir/config.layout not found])
+               rt_layout_name=no
+       else
+               pldconf=./config.pld
+               $PERL  -0777 -p -e "\$layout = '$2';"  -e '
+               s/.*<Layout\s+$layout>//gims; 
+               s/\<\/Layout\>.*//s; 
+               s/^#.*$//m;
+               s/^\s+//gim;
+               s/\s+$/\n/gim;
+               s/\+$/\/rt3/gim;
+               # m4 will not let us just use $1, we need @S|@1
+               s/^\s*((?:bin|sbin|libexec|data|sysconf|sharedstate|localstate|lib|include|oldinclude|info|man)dir)\s*:\s*(.*)$/@S|@1=@S|@2/gim;
+               s/^\s*(.*?)\s*:\s*(.*)$/\(test "x\@S|@@S|@1" = "xNONE" || test "x\@S|@@S|@1" = "x") && @S|@1=@S|@2/gim;
+                ' < $1 > $pldconf
+
+               if test -s $pldconf; then
+                       rt_layout_name=$2
+                       . $pldconf
+                       changequote({,})
+                       for var in prefix exec_prefix bindir sbindir \
+                                sysconfdir mandir libdir datadir htmldir \
+                                localstatedir logfiledir masonstatedir \
+                                sessionstatedir customdir custometcdir customhtmldir \
+                                customlexdir customlibdir manualdir; do
+                               eval "val=\"\$$var\""
+                               val=`echo $val | sed -e 's:\(.\)/*$:\1:'`
+                               val=`echo $val | 
+                                       sed -e 's:[\$]\([a-z_]*\):${\1}:g'`
+                               eval "$var='$val'"
+                       done
+                       changequote([,])
+               else
+                       rt_layout_name=no
+               fi
+               #rm $pldconf
+       fi
+       RT_SUBST_EXPANDED_ARG(prefix)
+       RT_SUBST_EXPANDED_ARG(exec_prefix)
+       RT_SUBST_EXPANDED_ARG(bindir)
+       RT_SUBST_EXPANDED_ARG(sbindir)
+       RT_SUBST_EXPANDED_ARG(sysconfdir)
+       RT_SUBST_EXPANDED_ARG(mandir)
+       RT_SUBST_EXPANDED_ARG(libdir)
+       RT_SUBST_EXPANDED_ARG(datadir)
+       RT_SUBST_EXPANDED_ARG(htmldir)
+       RT_SUBST_EXPANDED_ARG(manualdir)
+       RT_SUBST_EXPANDED_ARG(localstatedir)
+       RT_SUBST_EXPANDED_ARG(logfiledir)
+       RT_SUBST_EXPANDED_ARG(masonstatedir)
+       RT_SUBST_EXPANDED_ARG(sessionstatedir)
+       RT_SUBST_EXPANDED_ARG(customdir)
+       RT_SUBST_EXPANDED_ARG(custometcdir)
+       RT_SUBST_EXPANDED_ARG(customhtmldir)
+       RT_SUBST_EXPANDED_ARG(customlexdir)
+       RT_SUBST_EXPANDED_ARG(customlibdir)
+])dnl
diff --git a/rt/m4/rt_subst_expanded_arg.m4 b/rt/m4/rt_subst_expanded_arg.m4
new file mode 100644 (file)
index 0000000..02002b0
--- /dev/null
@@ -0,0 +1,14 @@
+dnl
+dnl @synopsis  RT_SUBST_EXPANDED_ARG(var)
+dnl
+dnl Export (via AC_SUBST) a given variable, along with an expanded
+dnl version of the variable (same name, but with exp_ prefix).
+dnl
+dnl This code is heavily borrowed *cough* from the Apache 2 source.
+dnl
+
+AC_DEFUN([RT_SUBST_EXPANDED_ARG],[
+       RT_EXPAND_VAR(exp_$1, [$]$1)
+       AC_SUBST($1)
+       AC_SUBST(exp_$1)
+])
diff --git a/rt/sbin/extract-message-catalog b/rt/sbin/extract-message-catalog
new file mode 100644 (file)
index 0000000..af7b2c7
--- /dev/null
@@ -0,0 +1,246 @@
+#!/usr/bin/perl -w 
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+# Portions Copyright 2002 Autrijus Tang <autrijus@autrijus.org>
+
+use strict;
+
+use File::Find;
+use File::Copy;
+use Regexp::Common;
+use Carp;
+
+use vars qw($DEBUG $FILECAT);
+
+$DEBUG = 1;
+
+@ARGV = <lib/RT/I18N/*.po> unless @ARGV;
+
+$FILECAT = {};
+
+# extract all strings and stuff them into $FILECAT
+File::Find::find( { wanted => \&extract_strings_from_code, follow => 0 }, '.' );
+
+# ensure proper escaping and [_1] => %1 transformation
+foreach my $str ( sort keys %{$FILECAT} ) {
+    my $entry = $FILECAT->{$str};
+    my $oldstr = $str;
+
+    $str =~ s/\\/\\\\/g;
+    $str =~ s/\"/\\"/g;
+    $str =~ s/((?<!~)(?:~~)*)\[_(\d+)\]/$1%$2/g;
+    $str =~ s/((?<!~)(?:~~)*)\[([A-Za-z#*]\w*),([^\]]+)\]/"$1%$2(".escape($3).")"/eg;
+    $str =~ s/~([\[\]])/$1/g;
+
+    delete $FILECAT->{$oldstr};
+    $FILECAT->{$str} = $entry;
+}
+
+# update all language dictionaries
+foreach my $dict (@ARGV) {
+    $dict = "lib/RT/I18N/$dict.po" unless -f $dict or $dict =~ m!/!;
+
+    my $lang = $dict;
+    $lang =~ s|.*/||;
+    $lang =~ s|\.po$||;
+
+    update($lang, $dict);
+}
+
+
+# {{{ pull strings out of the code.
+
+sub extract_strings_from_code {
+    my $file = $_;
+
+    local $/;
+    return if ( -d $_ );
+    return if ( $File::Find::dir =~ 'lib/blib|lib/t/autogen|var|m4|local' );
+    return if ( /\.po$|\.bak$|~|,D|,B$|extract-message-catalog$/ );
+    return if ( /^[\.#]/ );
+    return if ( -f "$_.in" );
+
+    print "Looking at $File::Find::name\n";
+    my $filename = $File::Find::name;
+    $filename =~ s'^\./'';
+    $filename =~ s'\.in$'';
+
+    unless (open _, $file) {
+        print "Cannot open $file for reading ($!), skipping.\n";
+        return;
+    }
+
+    $_ = <_>;
+
+    # Mason filter: <&|/l>...</&>
+    my $line = 1;
+    while (m!\G.*?<&\|/l(.*?)&>(.*?)</&>!sg) {
+        my ( $vars, $str ) = ( $1, $2 );
+        $line += ( () = ( $& =~ /\n/g ) );    # cryptocontext!
+        $str =~ s/\\'/\'/g;
+        #print "STR IS $str\n";
+        push @{ $FILECAT->{$str} }, [ $filename, $line, $vars ];
+    }
+
+    # Localization function: loc(...)
+    $line = 1;
+    pos($_) = 0;
+    while (m/\G.*?\bloc$RE{balanced}{-parens=>'()'}{-keep}/sg) {
+        my $match = $1;
+        $line += ( () = ( $& =~ /\n/g ) );    # cryptocontext!
+
+        my ( $vars, $str );
+        if ( $match =~
+                /\(\s*($RE{delimited}{-delim=>q{'"}}{-keep})(.*?)\s*\)$/ ) {
+
+            $str = substr( $1, 1, -1 );       # $str comes before $vars now
+            $vars = $9;
+        }
+        else {
+            next;
+        }
+
+        $vars =~ s/[\n\r]//g;
+        $str  =~ s/\\'/\'/g;
+
+        push @{ $FILECAT->{$str} }, [ $filename, $line, $vars ];
+    }
+
+    # Comment-based mark: "..." # loc
+    $line = 1;
+    pos($_) = 0;
+    while (m/\G.*?($RE{delimited}{-delim=>q{'"}}{-keep})[\}\)\],]*\s*\#\s*loc\s*$/smg) {
+       my $str = substr($1, 1, -1);
+       $line += ( () = ( $& =~ /\n/g ) );    # cryptocontext!
+       $str  =~ s/\\'/\'/g;
+       push @{ $FILECAT->{$str} }, [ $filename, $line, '' ];
+    }
+
+    # Comment-based pair mark: "..." => "..." # loc_pair
+    $line = 1;
+    pos($_) = 0;
+    while (m/\G.*?(\w+)\s*=>\s*($RE{delimited}{-delim=>q{'"}}{-keep})[\}\)\],]*\s*\#\s*loc_pair\s*$/smg) {
+       my $key = $1;
+       my $val = substr($2, 1, -1);
+       $line += ( () = ( $& =~ /\n/g ) );    # cryptocontext!
+       $key  =~ s/\\'/\'/g;
+       $val  =~ s/\\'/\'/g;
+       push @{ $FILECAT->{$key} }, [ $filename, $line, '' ];
+       push @{ $FILECAT->{$val} }, [ $filename, $line, '' ];
+    }
+
+    close (_);
+}
+# }}} extract from strings
+
+sub update {
+    my $lang = shift;
+    my $file = shift;
+    my ( %Lexicon, %Header);
+    my $out = '';
+
+    unless (!-e $file or -w $file) {
+       warn "Can't write to $lang, skipping...\n";
+       return;
+    }
+
+    print "Updating $lang...\n";
+
+    my @lines;
+    @lines = (<LEXICON>) if open (LEXICON, $file);
+    @lines = grep { !/^(#(:|\.)\s*|$)/ } @lines;
+    while (@lines) {
+        my $msghdr = "";
+        $msghdr .= shift @lines while ( $lines[0] && $lines[0] !~ /^msgid/ );
+        my $msgid  = shift @lines;
+        my $msgstr = "";
+        $msgstr .= shift @lines while ( $lines[0] && $lines[0] =~ /^(msgstr|")/ );
+
+        last unless $msgid;
+
+        chomp $msgid;
+        chomp $msgstr;
+        $msgid  =~ s/^msgid "(.*)"$/$1/    or warn $msgid;
+        $msgstr =~ s/^msgstr "(.*)"$/$1/ms or warn $msgstr;
+
+        $Lexicon{$msgid} = $msgstr;
+        $Header{$msgid}  = $msghdr;
+    }
+
+    my $is_english = ( $lang =~ /^en(?:[^A-Za-z]|$)/ );
+
+    foreach my $str ( sort keys %{$FILECAT} ) {
+        $Lexicon{$str} ||= '';;
+    }
+    foreach ( sort keys %Lexicon ) {
+        my $f = join ( ' ', sort map $_->[0].":".$_->[1], @{ $FILECAT->{$_} } );
+        my $nospace = $_;
+        $nospace =~ s/ +$//;
+
+        if ( !$Lexicon{$_} and $Lexicon{$nospace} ) {
+            $Lexicon{$_} =
+              $Lexicon{$nospace} . ( ' ' x ( length($_) - length($nospace) ) );
+        }
+
+        next if !length( $Lexicon{$_} ) and $is_english;
+
+        my %seen;
+        $out .= $Header{$_} if exists $Header{$_};
+        if ( $f && $f !~ /^\s+$/ ) {
+
+            $out .= "#: $f\n";
+        }
+        elsif ($_) {
+            $out .= "#: NOT FOUND IN SOURCE\n";
+        }
+        foreach my $entry ( grep { $_->[2] } @{ $FILECAT->{$_} } ) {
+            my ( $file, $line, $var ) = @{$entry};
+            $var =~ s/^\s*,\s*//;
+            $var =~ s/\s*$//;
+            $out .= "#. ($var)\n" unless $seen{$var}++;
+        }
+        $out .= "msgid \"$_\"\nmsgstr \"$Lexicon{$_}\"\n\n";
+    }
+
+    open PO, ">$file" or die $!;
+    print PO $out;
+    close PO;
+
+    return 1;
+}
+
+sub escape {
+    my $text = shift;
+    $text =~ s/\b_(\d+)/%$1/;
+    return $text;
+}
+
+__END__
+# Local variables:
+# c-indentation-style: bsd
+# c-basic-offset: 4
+# indent-tabs-mode: nil
+# End:
+# vim: expandtab shiftwidth=4:
diff --git a/rt/sbin/extract_pod_tests b/rt/sbin/extract_pod_tests
new file mode 100644 (file)
index 0000000..ed01c7d
--- /dev/null
@@ -0,0 +1,129 @@
+#!/usr/bin/perl
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+use strict;
+use vars qw($VERSION);
+$VERSION = '0.06';
+
+use Pod::Tests;
+use Symbol;
+
+=pod
+
+=head1 NAME
+
+extract_pod_tests -  RT-specific variant of pod2tests
+
+=head1 SYNOPSIS
+
+  pod2test [-Mmodule] [input [output]]
+
+=head1 DESCRIPTION
+
+B<pod2test> is a front-end for Test::Inline.  It generates the 
+"Bodies" of MakeMaker style .t testing files from embedded tests and 
+code examples.
+
+If output is not specified, the resulting .t file will go to STDOUT.
+Otherwise, it will go to the given output file.  If input is not
+given, it will draw from STDIN.
+
+If the given file contains no tests or code examples, no output will
+be given and no output file will be created.
+
+=cut
+
+my($infile, $outfile) = @ARGV;
+my($infh,$outfh);
+
+
+if( defined $infile ) {
+    $infh = gensym;
+    open($infh, $infile) or 
+      die "Can't open the POD file $infile: $!";
+}
+else {
+    $infh = \*STDIN;
+}
+
+unless ($outfile) {
+     ( my $test = $infile ) =~ s/\.(pm|pod)$//;
+            $test =~ s/^lib\W//;
+            $test =~ s/\W/-/;
+            $test =~ s/\//__/g;
+
+        $outfile = "lib/t/autogen/autogen-$test.t";
+}
+
+
+my $p = Pod::Tests->new;
+$p->parse_fh($infh);
+
+# XXX Hack to put the filename into the #line directive
+$p->{file} = $infile || '';
+
+my @tests    = $p->build_tests($p->tests);
+my @examples = $p->build_examples($p->examples);
+
+exit unless @tests or @examples;
+
+
+if( defined $outfile) {
+    $outfh = gensym;
+    open($outfh, ">$outfile") or
+      die "Can't open the test file $outfile: $!";
+}
+else {
+    $outfh = \*STDOUT;
+}
+
+
+
+foreach my $test (@tests, @examples) {
+    print $outfh "$test\n";
+}
+
+print $outfh "1;\n";
+
+=pod
+
+=head1 BUGS and CAVEATS
+
+This is a very simple rough cut.  It only does very rudimentary tests
+on the examples.
+
+=head1 AUTHOR
+
+
+
+Based on pod2tests by Michael G Schwern <schwern@pobox.com>
+
+=head1 SEE ALSO
+
+L<Test::Inline>
+
+=cut
+
+1;
diff --git a/rt/sbin/factory b/rt/sbin/factory
new file mode 100644 (file)
index 0000000..8abb192
--- /dev/null
@@ -0,0 +1,427 @@
+#!/usr/bin/perl
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+use DBI;
+
+my $database  = shift;
+my $namespace = shift;
+
+my $CollectionBaseclass = 'RT::SearchBuilder';
+my $RecordBaseclass     = 'RT::Record';
+
+my $driver   = 'mysql';
+my $hostname = 'localhost';
+my $user     = 'root';
+my $password = '';
+
+
+my $LicenseBlock = << '.';
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+.
+
+my $Attribution = << '.';
+# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
+# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
+# 
+# !! DO NOT EDIT THIS FILE !!
+#
+
+use strict;
+.
+
+my $dsn = "DBI:$driver:database=$database;host=$hostname";
+
+my $dbh = DBI->connect( $dsn, $user, $password );
+
+#get all tables out of database
+my @tables = $dbh->tables();
+
+my ( %tablemap, $typemap, %modulemap );
+
+foreach my $table (@tables) {
+    next if ($table eq 'sessions');
+    $tablemap{$table}  = $table;
+    $modulemap{$table} = $table;
+    if ( $table =~ /^(.*)s$/ ) {
+        $tablemap{$1}  = $table;
+        $modulemap{$1} = $1;
+    }
+}
+$tablemap{'CreatedBy'} = 'User';
+$tablemap{'UpdatedBy'} = 'User';
+
+$typemap{'id'}            = 'ro';
+$typemap{'Creator'}       = 'auto';
+$typemap{'Created'}       = 'auto';
+$typemap{'Updated'}       = 'auto';
+$typemap{'UpdatedBy'}     = 'auto';
+$typemap{'LastUpdated'}   = 'auto';
+$typemap{'LastUpdatedBy'} = 'auto';
+
+foreach my $table (@tables) {
+    next if ($table eq 'sessions');
+    my $tablesingle = $table;
+    $tablesingle =~ s/s$//;
+    my $tableplural = $tablesingle . "s";
+
+    if ( $tablesingle eq 'ACL' ) {
+        $tablesingle = "ACE";
+        $tableplural = "ACL";
+    }
+
+    my %requirements;
+
+    my $CollectionClassName = $namespace . "::" . $tableplural;
+    my $RecordClassName     = $namespace . "::" . $tablesingle;
+
+    my $path = $namespace;
+    $path =~ s/::/\//g;
+
+    my $RecordClassPath     = $path . "/" . $tablesingle . ".pm";
+    my $CollectionClassPath = $path . "/" . $tableplural . ".pm";
+
+    #create a collection class
+    my $CreateInParams;
+    my $CreateOutParams;
+    my $ClassAccessible = "";
+    my $FieldsPod       = "";
+    my $CreatePod       = "";
+    my %fields;
+    my $sth = $dbh->prepare("DESCRIBE $table");
+    $sth->execute;
+
+    while ( my $row = $sth->fetchrow_hashref() ) {
+        my $field   = $row->{'Field'};
+        my $type    = $row->{'Type'};
+        my $default = $row->{'Default'};
+        $fields{$field} = 1;
+
+        #generate the 'accessible' datastructure
+
+        if ( $typemap{$field} eq 'auto' ) {
+            $ClassAccessible .= "        $field => 
+               {read => 1, auto => 1,";
+        }
+        elsif ( $typemap{$field} eq 'ro' ) {
+            $ClassAccessible .= "        $field =>
+               {read => 1,";
+        }
+        else {
+            $ClassAccessible .= "        $field => 
+               {read => 1, write => 1,";
+
+        }
+
+        $ClassAccessible .= " type => '$type', default => '$default'},\n";
+
+        #generate pod for the accessible fields
+        $FieldsPod .= "
+=head2 $field
+
+Returns the current value of $field. 
+(In the database, $field is stored as $type.)
+
+";
+
+        unless ( $typemap{$field} eq 'auto' || $typemap{$field} eq 'ro' ) {
+            $FieldsPod .= "
+
+=head2 Set$field VALUE
+
+
+Set $field to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, $field will be stored as a $type.)
+
+";
+        }
+
+        $FieldsPod .= "
+=cut
+
+";
+
+        if ( $modulemap{$field} ) {
+            $FieldsPod .= "
+=head2 ${field}Obj
+
+Returns the $modulemap{$field} Object which has the id returned by $field
+
+
+=cut
+
+sub ${field}Obj {
+       my \$self = shift;
+       my \$$field =  ${namespace}::$modulemap{$field}->new(\$self->CurrentUser);
+       \$$field->Load(\$self->__Value('$field'));
+       return(\$$field);
+}
+";
+            $requirements{ $tablemap{$field} } =
+              "use ${namespace}::$modulemap{$field};";
+
+        }
+
+        unless ( $typemap{$field} eq 'auto' || $field eq 'id' ) {
+
+            #generate create statement
+            $CreateInParams .= "                $field => '$default',\n";
+            $CreateOutParams .=
+              "                         $field => \$args{'$field'},\n";
+
+            #gerenate pod for the create statement     
+            $CreatePod .= "  $type '$field'";
+            $CreatePod .= " defaults to '$default'" if ($default);
+            $CreatePod .= ".\n";
+
+        }
+
+    }
+
+    $Create = "
+sub Create {
+    my \$self = shift;
+    my \%args = ( 
+$CreateInParams
+                 \@_);
+    \$self->SUPER::Create(
+$CreateOutParams);
+
+}
+";
+    $CreatePod .= "\n=cut\n\n";
+
+    my $CollectionClass = $LicenseBlock . $Attribution .
+
+      "
+
+=head1 NAME
+
+  $CollectionClassName -- Class Description
+=head1 SYNOPSIS
+
+  use $CollectionClassName
+
+=head1 DESCRIPTION
+
+
+=head1 METHODS
+
+=cut
+
+package $CollectionClassName;
+
+use $CollectionBaseclass;
+use $RecordClassName;
+
+use vars qw( \@ISA );
+\@ISA= qw($CollectionBaseclass);
+
+
+sub _Init {
+    my \$self = shift;
+    \$self->{'table'} = '$table';
+    \$self->{'primary_key'} = 'id';
+
+";
+
+    if ( $fields{'SortOrder'} ) {
+
+        $CollectionClass .= "
+
+  # By default, order by name
+  \$self->OrderBy( ALIAS => 'main',
+                  FIELD => 'SortOrder',
+                  ORDER => 'ASC');
+";
+    }
+    $CollectionClass .= "
+    return ( \$self->SUPER::_Init(\@_) );
+}
+
+
+=head2 NewItem
+
+Returns an empty new $RecordClassName item
+
+=cut
+
+sub NewItem {
+    my \$self = shift;
+    return($RecordClassName->new(\$self->CurrentUser));
+}
+" . MagicImport($CollectionClassName);
+
+    my $RecordClassHeader = $Attribution . "
+
+=head1 NAME
+
+$RecordClassName
+
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+=cut
+
+package $RecordClassName;
+use $RecordBaseclass; 
+";
+
+    foreach my $key ( keys %requirements ) {
+        $RecordClassHeader .= $requirements{$key} . "\n";
+    }
+    $RecordClassHeader .= "
+
+use vars qw( \@ISA );
+\@ISA= qw( $RecordBaseclass );
+
+sub _Init {
+  my \$self = shift; 
+
+  \$self->Table('$table');
+  \$self->SUPER::_Init(\@_);
+}
+
+";
+
+    my $RecordClass = $LicenseBlock .  $RecordClassHeader . "
+
+$RecordInit
+
+=head2 Create PARAMHASH
+
+Create takes a hash of values and creates a row in the database:
+
+$CreatePod
+
+$Create
+
+$FieldsPod
+
+sub _ClassAccessible {
+    {
+     
+$ClassAccessible
+ }
+};
+
+" . MagicImport($RecordClassName);
+
+    print "About to make $RecordClassPath, $CollectionClassPath\n";
+    `mkdir -p $path`;
+
+    open( RECORD, ">$RecordClassPath" );
+    print RECORD $RecordClass;
+    close(RECORD);
+
+    open( COL, ">$CollectionClassPath" );
+    print COL $CollectionClass;
+    close($COL);
+
+}
+
+sub MagicImport {
+    my $class = shift;
+
+    #if (exists \$warnings::{unimport})  {
+    #        no warnings qw(redefine);
+
+    my $path = $class;
+    $path =~ s#::#/#gi;
+
+
+    my $content = "
+        eval \"require @{[$class]}_Overlay\";
+        if (\$@ && \$@ !~ qr{^Can't locate ".$path."_Overlay.pm}) {
+            die \$@;
+        };
+
+        eval \"require @{[$class]}_Vendor\";
+        if (\$@ && \$@ !~ qr{^Can't locate ".$path."_Vendor.pm}) {
+            die \$@;
+        };
+
+        eval \"require @{[$class]}_Local\";
+        if (\$@ && \$@ !~ qr{^Can't locate ".$path."_Local.pm}) {
+            die \$@;
+        };
+
+
+
+
+=head1 SEE ALSO
+
+This class allows \"overlay\" methods to be placed
+into the following files _Overlay is for a System overlay by the original author,
+_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.  
+
+These overlay files can contain new subs or subs to replace existing subs in this module.
+
+If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+
+   no warnings qw(redefine);
+
+so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+
+@{[$class]}_Overlay, @{[$class]}_Vendor, @{[$class]}_Local
+
+=cut
+
+
+1;
+";
+
+    return $content;
+}
+
+# }}}
+
diff --git a/rt/sbin/license_tag b/rt/sbin/license_tag
new file mode 100644 (file)
index 0000000..33da2e0
--- /dev/null
@@ -0,0 +1,196 @@
+#!/usr/bin/perl
+
+
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+my $LICENSE  = <<EOL;
+
+Copyright (c) 1996-2003 Jesse Vincent <jesse\@bestpractical.com>
+
+(Except where explictly superceded by other copyright notices)
+
+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.
+
+Unless otherwise specified, all modifications, corrections or
+extensions to this work which alter its source code become the
+property of Best Practical Solutions, LLC when submitted for
+inclusion in the work.
+
+
+EOL
+
+use File::Find;
+
+my @MAKE = qw(Makefile);
+
+File::Find::find({ no_chdir => 1, wanted => \&tag_pm}, 'lib');
+File::Find::find({ no_chdir => 1, wanted => \&tag_mason}, 'html');
+File::Find::find({ no_chdir => 1, wanted => \&tag_script}, 'sbin');
+File::Find::find({ no_chdir => 1, wanted => \&tag_script}, 'bin');
+tag_makefile ('Makefile');
+tag_makefile ('README');
+
+
+sub tag_mason {
+        my $pm = $_;
+        next unless (-f $pm);
+        next if ($pm =~ /images/);
+        open(FILE,"<$pm") || die "Failed to open $pm";
+        my $file = (join "", <FILE>); 
+        close (FILE);
+        my $pmlic = $LICENSE;
+        $pmlic =~ s/^/%# /mg;
+
+
+        print "$pm - ";
+        if ($file =~ /^%# BEGIN LICENSE BLOCK/ms) {
+                print "has license section";
+             $file =~ s/^%# BEGIN LICENSE BLOCK(.*?)%# END LICENSE BLOCK/%# BEGIN LICENSE BLOCK\n$pmlic%# END LICENSE BLOCK/ms;
+             
+
+        } else {
+                print "no license section";
+             $file ="%# BEGIN LICENSE BLOCK\n$pmlic%# END LICENSE BLOCK\n". $file;
+        }
+        $file =~ s/%# END LICENSE BLOCK(\n+)/%# END LICENSE BLOCK\n/mg;
+        print "\n";
+        
+        
+
+
+        open (FILE, ">$pm") || die "couldn't write new file";
+        print FILE $file;
+        close FILE;
+
+}
+
+
+sub tag_makefile {
+        my $pm = shift;
+        open(FILE,"<$pm") || die "Failed to open $pm";
+        my $file = (join "", <FILE>); 
+        close (FILE);
+        my $pmlic = $LICENSE;
+        $pmlic =~ s/^/# /mg;
+
+
+        print "$pm - ";
+        if ($file =~ /^# BEGIN LICENSE BLOCK/ms) {
+                print "has license section";
+             $file =~ s/^# BEGIN LICENSE BLOCK(.*?)# END LICENSE BLOCK/# BEGIN LICENSE BLOCK\n$pmlic# END LICENSE BLOCK/ms;
+             
+
+        } else {
+                print "no license section";
+             $file ="# BEGIN LICENSE BLOCK\n$pmlic# END LICENSE BLOCK\n". $file;
+        }
+        $file =~ s/# END LICENSE BLOCK(\n+)/# END LICENSE BLOCK\n/mg;
+        print "\n";
+        
+        
+
+
+        open (FILE, ">$pm") || die "couldn't write new file";
+        print FILE $file;
+        close FILE;
+
+}
+
+
+sub tag_pm {
+        my $pm = $_;
+        next unless $pm =~ /\.pm\z/s;
+        open(FILE,"<$pm") || die "Failed to open $pm";
+        my $file = (join "", <FILE>); 
+        close (FILE);
+        my $pmlic = $LICENSE;
+        $pmlic =~ s/^/# /mg;
+
+
+        print "$pm - ";
+        if ($file =~ /^# BEGIN LICENSE BLOCK/ms) {
+                print "has license section";
+             $file =~ s/^# BEGIN LICENSE BLOCK(.*?)# END LICENSE BLOCK/# BEGIN LICENSE BLOCK\n$pmlic# END LICENSE BLOCK/ms;
+             
+
+        } else {
+                print "no license section";
+             $file ="# BEGIN LICENSE BLOCK\n$pmlic# END LICENSE BLOCK\n". $file;
+        }
+        $file =~ s/# END LICENSE BLOCK(\n+)/# END LICENSE BLOCK\n/mg;
+        print "\n";
+        
+        
+
+
+        open (FILE, ">$pm") || die "couldn't write new file $pm";
+        print FILE $file;
+        close FILE;
+
+}
+
+
+sub tag_script {
+        my $pm = $_;
+        return unless (-f $pm);
+        open(FILE,"<$pm") || die "Failed to open $pm";
+        my $file = (join "", <FILE>); 
+        close (FILE);
+        my $pmlic = $LICENSE;
+        $pmlic =~ s/^/# /msg;
+
+        print "$pm - ";
+        if ($file =~ /^# BEGIN LICENSE BLOCK/ms) {
+                print "has license section";
+             $file =~ s/^# BEGIN LICENSE BLOCK(.*?)# END LICENSE BLOCK/# BEGIN LICENSE BLOCK\n$pmlic# END LICENSE BLOCK/ms;
+             
+
+        } else {
+                print "no license section";
+                if ($file =~ /^(#!.*?)\n/) {
+
+            my  $lic ="# BEGIN LICENSE BLOCK\n$pmlic# END LICENSE BLOCK\n";
+                $file =~ s/^(#!.*?)\n/$1\n$lic/; 
+
+                } 
+        }
+        $file =~ s/# END LICENSE BLOCK(\n+)/# END LICENSE BLOCK\n\n/mg;
+        print "\n";
+        
+
+        open (FILE, ">$pm") || die "couldn't write new file";
+        print FILE $file;
+        close FILE;
+
+}
+
diff --git a/rt/sbin/regression_harness b/rt/sbin/regression_harness
new file mode 100644 (file)
index 0000000..fc1e293
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/perl
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+open (FH,"make regression|");
+
+my $skip_frontmatter = 1;
+while (<FH>) {
+        next if /^ok/;
+       $skip_frontmatter = 0 if (/autogen/);
+        print $_ unless ($skip_frontmatter);
+}
diff --git a/rt/sbin/rt-setup-database b/rt/sbin/rt-setup-database
new file mode 100644 (file)
index 0000000..f84f290
--- /dev/null
@@ -0,0 +1,585 @@
+#!/usr/bin/perl -w
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+use strict;
+use vars qw($PROMPT $VERSION $Handle $Nobody $SystemUser $item);
+use vars
+  qw(@Groups @Users @ACL @Queues @ScripActions @ScripConditions @Templates @CustomFields @Scrips);
+
+use lib "/opt/rt3/lib";
+
+#This drags in  RT's config.pm
+# We do it in a begin block because RT::Handle needs to know the type to do its
+# inheritance
+use RT;
+use Carp;
+use RT::User;
+use RT::CurrentUser;
+use RT::Template;
+use RT::ScripAction;
+use RT::ACE;
+use RT::Group;
+use RT::User;
+use RT::Queue;
+use RT::ScripCondition;
+use RT::CustomField;
+use RT::Scrip;
+
+RT::LoadConfig();
+use Term::ReadKey;
+use Getopt::Long;
+
+my %args;
+
+GetOptions(
+    \%args,
+    'prompt-for-dba-password', 'force', 'debug',
+    'action=s',                'dba=s', 'dba-password=s', 'datafile=s',
+    'datadir=s'
+);
+
+$| = 1;    #unbuffer that output.
+
+require RT::Handle;
+my $Handle = RT::Handle->new($RT::DatabaseType);
+$Handle->BuildDSN;
+my $dbh;
+
+if ( $args{'prompt-for-dba-password'} ) {
+    $args{'dba-password'} = get_dba_password();
+    chomp( $args{'dba-password'} );
+}
+
+unless ( $args{'action'} ) {
+    help();
+    die;
+}
+if ( $args{'action'} eq 'init' ) {
+    $dbh = DBI->connect( get_system_dsn(), $args{'dba'}, $args{'dba-password'} )
+      || die "Failed to connect to " . get_system_dsn() . " as $args{'dba'}: $DBI::errstr";
+    print "Now creating a database for RT.\n";
+    create_db();
+
+    $dbh->disconnect;
+    $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} )
+      || die $DBI::errstr;
+
+    print "Now populating database schema.\n";
+    insert_schema();
+    print "Now inserting database ACLs\n";
+    insert_acl();
+    print "Now inserting RT core system objects\n";
+    insert_initial_data();
+    print "Now inserting RT data\n";
+    insert_data( $RT::EtcPath . "/initialdata" );
+}
+elsif ( $args{'action'} eq 'drop' ) {
+    unless ( $dbh =
+         DBI->connect( get_system_dsn(), $args{'dba'}, $args{'dba-password'} ) )
+    {
+        warn $DBI::errstr;
+        warn "Database doesn't appear to exist. Aborting database drop.";
+        exit(0);
+    }
+    drop_db();
+}
+elsif ( $args{'action'} eq 'insert' ) {
+    insert_data( $args{'datafile'} );
+}
+elsif ($args{'action'} eq 'acl') {
+    $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} )
+      || die "Failed to connect to " . get_system_dsn() . " as $args{'dba'}: $DBI::errstr";
+     insert_acl($args{'datadir'});
+}
+elsif ($args{'action'} eq 'schema') {
+    $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} )
+      || die "Failed to connect to " . get_system_dsn() . " as $args{'dba'}: $DBI::errstr";
+        insert_schema($args{'datadir'});
+}
+
+else {
+    print STDERR '$0 called with an invalid --action parameter';
+    exit(-1);
+}
+
+# {{{ sub insert_schema
+sub insert_schema {
+        my $base_path = (shift || $RT::EtcPath);
+    my (@schema);
+    print "Creating database schema.\n";
+
+    if ( -f $base_path . "/schema." . $RT::DatabaseType ) {
+       no warnings 'unopened';
+
+        open( SCHEMA, "<" . $base_path . "/schema." . $RT::DatabaseType );
+        open( SCHEMA_LOCAL, "<" . $RT::LocalEtcPath . "/schema." . $RT::DatabaseType );
+
+        my $statement = "";
+        foreach my $line (<SCHEMA>, <SCHEMA_LOCAL>) {
+            $line =~ s/\#.*//g;
+            $statement .= $line;
+            if ( $line =~ /;(\s*)$/ ) {
+                $statement =~ s/;(\s*)$//g;
+                push @schema, $statement;
+                $statement = "";
+            }
+        }
+
+        foreach my $statement (@schema) {
+            print STDERR $statement if $args{'debug'};
+            my $sth = $dbh->prepare($statement) or die $dbh->errstr;
+            unless ( $sth->execute ) {
+                die "Problem with statement:\n $statement\n" . $sth->errstr;
+            }
+        }
+
+    }
+    else {
+        die "Couldn't find schema file for " . $RT::DatabaseType . "\n";
+    }
+    print "schema sucessfully inserted\n";
+
+}
+
+# }}}
+
+# {{{ sub drop_db
+sub drop_db {
+    return if ( $RT::DatabaseType eq 'SQLite' );
+    unless ( $args{'force'} ) {
+        print <<END;
+
+About to drop $RT::DatabaseType database $RT::DatabaseName on $RT::DatabaseHost.
+WARNING: This will erase all data in $RT::DatabaseName.
+
+END
+        exit unless _yesno();
+
+    }
+
+    print "Dropping $RT::DatabaseType database $RT::DatabaseName.\n";
+
+    $dbh->do("Drop DATABASE $RT::DatabaseName") or warn $DBI::errstr;
+}
+
+# }}}
+
+# {{{ sub create_db
+sub create_db {
+    print "Creating $RT::DatabaseType database $RT::DatabaseName.\n";
+    if ( $RT::DatabaseType eq 'SQLite' ) {
+        return;
+    }
+    elsif ( $RT::DatabaseType eq 'Pg' ) {
+        $dbh->do("CREATE DATABASE $RT::DatabaseName WITH ENCODING='UNICODE'");
+        if ($DBI::errstr) {
+            $dbh->do("CREATE DATABASE $RT::DatabaseName") || die $DBI::errstr;
+        }
+    }
+    else {
+        $dbh->do("CREATE DATABASE $RT::DatabaseName") or die $DBI::errstr;
+    }
+}
+
+# }}}
+
+sub get_dba_password {
+    print
+"In order to create a new database and grant RT access to that database,\n";
+    print "this script needs to connect to your "
+      . $RT::DatabaseType
+      . " instance on "
+      . $RT::DatabaseHost . " as "
+      . $args{'dba'} . ".\n";
+    print
+"Please specify that user's database password below. If the user has no database\n";
+    print "password, just press return.\n\n";
+    print "Password: ";
+    ReadMode('noecho');
+    my $password = ReadLine(0);
+    ReadMode('normal');
+    return ($password);
+}
+
+# {{{ sub _yesno
+sub _yesno {
+    print "Proceed [y/N]:";
+    my $x = scalar(<STDIN>);
+    $x =~ /^y/i;
+}
+
+# }}}
+
+# {{{ insert_acls
+sub insert_acl {
+
+        my $base_path = (shift || $RT::EtcPath);
+
+    if ( $RT::DatabaseType =~ /^oracle$/i ) {
+        do $base_path . "/acl.Oracle"
+          || die "Couldn't find ACLS for Oracle\n" . $@;
+    }
+    elsif ( $RT::DatabaseType =~ /^pg$/i ) {
+        do $base_path . "/acl.Pg" || die "Couldn't find ACLS for Pg\n" . $@;
+    }
+    elsif ( $RT::DatabaseType =~ /^mysql$/i ) {
+        do $base_path . "/acl.mysql"
+          || die "Couldn't find ACLS for mysql in " . $RT::EtcPath . "\n" . $@;
+    }
+    elsif ( $RT::DatabaseType =~ /^SQLite$/i ) {
+        return;
+    }
+    else {
+        die "Unknown RT database type";
+    }
+
+    my @acl = acl($dbh);
+    foreach my $statement (@acl) {
+        print STDERR $statement if $args{'debug'};
+        my $sth = $dbh->prepare($statement) or die $dbh->errstr;
+        unless ( $sth->execute ) {
+            die "Problem with statement:\n $statement\n" . $sth->errstr;
+        }
+    }
+}
+
+# }}}
+
+=head2 get_system_dsn
+
+Returns a dsn suitable for database creates and drops
+and user creates and drops
+
+=cut
+
+sub get_system_dsn {
+
+    my $dsn = $Handle->DSN;
+
+    #with mysql, you want to connect sans database to funge things
+    if ( $RT::DatabaseType eq 'mysql' ) {
+        $dsn =~ s/dbname=$RT::DatabaseName//;
+
+        # with postgres, you want to connect to database1
+    }
+    elsif ( $RT::DatabaseType eq 'Pg' ) {
+        $dsn =~ s/dbname=$RT::DatabaseName/dbname=template1/;
+    }
+    return $dsn;
+}
+
+sub insert_initial_data {
+
+    RT::InitLogging();
+
+    #connect to the db, for actual RT work
+    require RT::Handle;
+    $RT::Handle = RT::Handle->new();
+    $RT::Handle->Connect();
+
+    #Put together a current user object so we can create a User object
+    my $CurrentUser = new RT::CurrentUser();
+
+    print "Checking for existing system user...";
+    my $test_user = RT::User->new($CurrentUser);
+    $test_user->Load('RT_System');
+    if ( $test_user->id ) {
+        print "found!\n\nYou appear to have a functional RT database.\n"
+          . "Exiting, so as not to clobber your existing data.\n";
+        exit(-1);
+
+    }
+    else {
+        print "not found.  This appears to be a new installation.\n";
+    }
+
+    print "Creating system user...";
+    my $RT_System = new RT::User($CurrentUser);
+
+    my ( $val, $msg ) = $RT_System->_BootstrapCreate(
+        Name     => 'RT_System',
+        RealName => 'The RT System itself',
+        Comments =>
+'Do not delete or modify this user. It is integral to RT\'s internal database structures',
+        Creator => '1' );
+
+    unless ($val) {
+        print "$msg\n";
+        exit(1);
+    }
+    print "done.\n";
+    $RT::Handle->dbh->disconnect();
+
+}
+
+# load some sort of data into the database
+
+sub insert_data {
+    my $datafile = shift;
+
+    #Connect to the database and get RT::SystemUser and RT::Nobody loaded
+    RT::Init;
+
+    my $CurrentUser = RT::CurrentUser->new();
+    $CurrentUser->LoadByName('RT_System');
+
+    if ( $datafile eq $RT::EtcPath . "/initialdata" ) {
+
+        print "Creating Superuser  ACL...";
+
+        my $superuser_ace = RT::ACE->new($CurrentUser);
+        $superuser_ace->_BootstrapCreate(
+                             PrincipalId => ACLEquivGroupId( $CurrentUser->Id ),
+                             PrincipalType => 'Group',
+                             RightName     => 'SuperUser',
+                             ObjectType    => 'RT::System',
+                             ObjectId      => '1' );
+
+    }
+
+    # Slurp in stuff to insert from the datafile. Possible things to go in here:-
+    # @groups, @users, @acl, @queues, @ScripActions, @ScripConditions, @templates
+
+    require $datafile
+      || die "Couldn't find initial data for import\n" . $@;
+
+    if (@Groups) {
+        print "Creating groups...";
+        foreach $item (@Groups) {
+            my $new_entry = RT::Group->new($CurrentUser);
+            my ( $return, $msg ) = $new_entry->_Create(%$item);
+            print "(Error: $msg)" unless ($return);
+            print $return. ".";
+        }
+        print "done.\n";
+    }
+    if (@Users) {
+        print "Creating users...";
+        foreach $item (@Users) {
+            my $new_entry = new RT::User($CurrentUser);
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+            print "(Error: $msg)" unless ($return);
+            print $return. ".";
+        }
+        print "done.\n";
+    }
+    if (@Queues) {
+        print "Creating queues...";
+        for $item (@Queues) {
+            my $new_entry = new RT::Queue($CurrentUser);
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+            print "(Error: $msg)" unless ($return);
+            print $return. ".";
+        }
+        print "done.\n";
+    }
+    if (@ACL) {
+        print "Creating ACL...";
+        for my $item (@ACL) {
+
+           my ($princ, $object);
+
+           # Global rights or Queue rights?
+           if ($item->{'Queue'}) {
+                $object = RT::Queue->new($CurrentUser);
+                $object->Load( $item->{'Queue'} );
+           } else {
+               $object = $RT::System;
+           }
+
+           # Group rights or user rights?
+           if ($item->{'GroupDomain'}) {
+                $princ = RT::Group->new($CurrentUser);
+               if ($item->{'GroupDomain'} eq 'UserDefined') {
+                  $princ->LoadUserDefinedGroup( $item->{'GroupId'} );
+               } elsif ($item->{'GroupDomain'} eq 'SystemInternal') {
+                  $princ->LoadSystemInternalGroup( $item->{'GroupType'} );
+               } elsif ($item->{'GroupDomain'} eq 'RT::Queue-Role' &&
+                        $item->{'Queue'}) {
+                  $princ->LoadQueueRoleGroup( Type => $item->{'GroupType'},
+                                             Queue => $object->id);
+               } else {
+                  $princ->Load( $item->{'GroupId'} );
+               }
+           } else {
+               $princ = RT::User->new($CurrentUser);
+               $princ->Load( $item->{'UserId'} );
+           }
+
+           # Grant it
+           my ( $return, $msg ) = $princ->PrincipalObj->GrantRight(
+                                                     Right => $item->{'Right'},
+                                                     Object => $object );
+
+            if ($return) {
+                print $return. ".";
+            }
+            else {
+                print $msg . ".";
+
+            }
+
+        }
+        print "done.\n";
+    }
+    if (@CustomFields) {
+        print "Creating custom fields...";
+        for $item (@CustomFields) {
+            my $new_entry = new RT::CustomField($CurrentUser);
+            my $values    = $item->{'Values'};
+            delete $item->{'Values'};
+            my $q     = $item->{'Queue'};
+            my $q_obj = RT::Queue->new($CurrentUser);
+            $q_obj->Load($q);
+            if ( $q_obj->Id ) {
+                $item->{'Queue'} = $q_obj->Id;
+            }
+            elsif ( $q == 0 ) {
+                $item->{'Queue'} = 0;
+            }
+            else {
+                print "(Error: Could not find queue " . $q . ")\n"
+                  unless ( $q_obj->Id );
+                next;
+            }
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+
+            foreach my $value ( @{$values} ) {
+                my ( $eval, $emsg ) = $new_entry->AddValue(%$value);
+                print "(Error: $emsg)\n" unless ($eval);
+            }
+
+            print "(Error: $msg)\n" unless ($return);
+            print $return. ".";
+        }
+
+        print "done.\n";
+    }
+
+    if (@ScripActions) {
+        print "Creating ScripActions...";
+
+        for $item (@ScripActions) {
+            my $new_entry = RT::ScripAction->new($CurrentUser);
+            my $return    = $new_entry->Create(%$item);
+            print $return. ".";
+        }
+
+        print "done.\n";
+    }
+
+    if (@ScripConditions) {
+        print "Creating ScripConditions...";
+
+        for $item (@ScripConditions) {
+            my $new_entry = RT::ScripCondition->new($CurrentUser);
+            my $return    = $new_entry->Create(%$item);
+            print $return. ".";
+        }
+
+        print "done.\n";
+    }
+
+    if (@Templates) {
+        print "Creating templates...";
+
+        for $item (@Templates) {
+            my $new_entry = new RT::Template($CurrentUser);
+            my $return    = $new_entry->Create(%$item);
+            print $return. ".";
+        }
+        print "done.\n";
+    }
+    if (@Scrips) {
+        print "Creating scrips...";
+
+        for $item (@Scrips) {
+            my $new_entry = new RT::Scrip($CurrentUser);
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+            if ($return) {
+                print $return. ".";
+            }
+            else {
+                print "(Error: $msg)\n";
+            }
+        }
+        print "done.\n";
+    }
+    $RT::Handle->Disconnect();
+
+}
+
+=head2 ACLEquivGroupId
+
+Given a userid, return that user's acl equivalence group
+
+=cut
+
+sub ACLEquivGroupId {
+    my $username = shift;
+    my $user     = RT::User->new($RT::SystemUser);
+    $user->Load($username);
+    my $equiv_group = RT::Group->new($RT::SystemUser);
+    $equiv_group->LoadACLEquivalenceGroup($user);
+    return ( $equiv_group->Id );
+}
+
+sub help {
+
+    print <<EOF;
+
+$0: Set up RT's database
+
+--action        init    Initialize the database
+                drop    Drop the database. 
+                        This will ERASE ALL YOUR DATA
+                insert  Insert data into RT's database. 
+                        By default, will use RT's installation data.
+                        To use a local or supplementary datafile, specify it
+                        using the '--datafile' option below.
+                        
+                acl     Initialize only the database ACLs
+                        To use a local or supplementary datafile, specify it
+                        using the '--datadir' option below.
+                        
+                schema  Initialize only the database schema
+                        To use a local or supplementary datafile, specify it
+                        using the '--datadir' option below.
+
+--datafile /path/to/datafile
+--datadir /path/to/              Used to specify a path to find the local
+                                database schema and acls to be installed.
+
+
+--dba                           dba's username
+--dba-password                  dba's password
+--prompt-for-dba-password       Ask for the database administrator's password interactively
+
+
+EOF
+
+}
+
+1;
diff --git a/rt/sbin/rt-setup-database.in b/rt/sbin/rt-setup-database.in
new file mode 100644 (file)
index 0000000..e49a32e
--- /dev/null
@@ -0,0 +1,585 @@
+#!@PERL@ -w
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+use strict;
+use vars qw($PROMPT $VERSION $Handle $Nobody $SystemUser $item);
+use vars
+  qw(@Groups @Users @ACL @Queues @ScripActions @ScripConditions @Templates @CustomFields @Scrips);
+
+use lib "@RT_LIB_PATH@";
+
+#This drags in  RT's config.pm
+# We do it in a begin block because RT::Handle needs to know the type to do its
+# inheritance
+use RT;
+use Carp;
+use RT::User;
+use RT::CurrentUser;
+use RT::Template;
+use RT::ScripAction;
+use RT::ACE;
+use RT::Group;
+use RT::User;
+use RT::Queue;
+use RT::ScripCondition;
+use RT::CustomField;
+use RT::Scrip;
+
+RT::LoadConfig();
+use Term::ReadKey;
+use Getopt::Long;
+
+my %args;
+
+GetOptions(
+    \%args,
+    'prompt-for-dba-password', 'force', 'debug',
+    'action=s',                'dba=s', 'dba-password=s', 'datafile=s',
+    'datadir=s'
+);
+
+$| = 1;    #unbuffer that output.
+
+require RT::Handle;
+my $Handle = RT::Handle->new($RT::DatabaseType);
+$Handle->BuildDSN;
+my $dbh;
+
+if ( $args{'prompt-for-dba-password'} ) {
+    $args{'dba-password'} = get_dba_password();
+    chomp( $args{'dba-password'} );
+}
+
+unless ( $args{'action'} ) {
+    help();
+    die;
+}
+if ( $args{'action'} eq 'init' ) {
+    $dbh = DBI->connect( get_system_dsn(), $args{'dba'}, $args{'dba-password'} )
+      || die "Failed to connect to " . get_system_dsn() . " as $args{'dba'}: $DBI::errstr";
+    print "Now creating a database for RT.\n";
+    create_db();
+
+    $dbh->disconnect;
+    $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} )
+      || die $DBI::errstr;
+
+    print "Now populating database schema.\n";
+    insert_schema();
+    print "Now inserting database ACLs\n";
+    insert_acl();
+    print "Now inserting RT core system objects\n";
+    insert_initial_data();
+    print "Now inserting RT data\n";
+    insert_data( $RT::EtcPath . "/initialdata" );
+}
+elsif ( $args{'action'} eq 'drop' ) {
+    unless ( $dbh =
+         DBI->connect( get_system_dsn(), $args{'dba'}, $args{'dba-password'} ) )
+    {
+        warn $DBI::errstr;
+        warn "Database doesn't appear to exist. Aborting database drop.";
+        exit(0);
+    }
+    drop_db();
+}
+elsif ( $args{'action'} eq 'insert' ) {
+    insert_data( $args{'datafile'} );
+}
+elsif ($args{'action'} eq 'acl') {
+    $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} )
+      || die "Failed to connect to " . get_system_dsn() . " as $args{'dba'}: $DBI::errstr";
+     insert_acl($args{'datadir'});
+}
+elsif ($args{'action'} eq 'schema') {
+    $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} )
+      || die "Failed to connect to " . get_system_dsn() . " as $args{'dba'}: $DBI::errstr";
+        insert_schema($args{'datadir'});
+}
+
+else {
+    print STDERR '$0 called with an invalid --action parameter';
+    exit(-1);
+}
+
+# {{{ sub insert_schema
+sub insert_schema {
+        my $base_path = (shift || $RT::EtcPath);
+    my (@schema);
+    print "Creating database schema.\n";
+
+    if ( -f $base_path . "/schema." . $RT::DatabaseType ) {
+       no warnings 'unopened';
+
+        open( SCHEMA, "<" . $base_path . "/schema." . $RT::DatabaseType );
+        open( SCHEMA_LOCAL, "<" . $RT::LocalEtcPath . "/schema." . $RT::DatabaseType );
+
+        my $statement = "";
+        foreach my $line (<SCHEMA>, <SCHEMA_LOCAL>) {
+            $line =~ s/\#.*//g;
+            $statement .= $line;
+            if ( $line =~ /;(\s*)$/ ) {
+                $statement =~ s/;(\s*)$//g;
+                push @schema, $statement;
+                $statement = "";
+            }
+        }
+
+        foreach my $statement (@schema) {
+            print STDERR $statement if $args{'debug'};
+            my $sth = $dbh->prepare($statement) or die $dbh->errstr;
+            unless ( $sth->execute ) {
+                die "Problem with statement:\n $statement\n" . $sth->errstr;
+            }
+        }
+
+    }
+    else {
+        die "Couldn't find schema file for " . $RT::DatabaseType . "\n";
+    }
+    print "schema sucessfully inserted\n";
+
+}
+
+# }}}
+
+# {{{ sub drop_db
+sub drop_db {
+    return if ( $RT::DatabaseType eq 'SQLite' );
+    unless ( $args{'force'} ) {
+        print <<END;
+
+About to drop $RT::DatabaseType database $RT::DatabaseName on $RT::DatabaseHost.
+WARNING: This will erase all data in $RT::DatabaseName.
+
+END
+        exit unless _yesno();
+
+    }
+
+    print "Dropping $RT::DatabaseType database $RT::DatabaseName.\n";
+
+    $dbh->do("Drop DATABASE $RT::DatabaseName") or warn $DBI::errstr;
+}
+
+# }}}
+
+# {{{ sub create_db
+sub create_db {
+    print "Creating $RT::DatabaseType database $RT::DatabaseName.\n";
+    if ( $RT::DatabaseType eq 'SQLite' ) {
+        return;
+    }
+    elsif ( $RT::DatabaseType eq 'Pg' ) {
+        $dbh->do("CREATE DATABASE $RT::DatabaseName WITH ENCODING='UNICODE'");
+        if ($DBI::errstr) {
+            $dbh->do("CREATE DATABASE $RT::DatabaseName") || die $DBI::errstr;
+        }
+    }
+    else {
+        $dbh->do("CREATE DATABASE $RT::DatabaseName") or die $DBI::errstr;
+    }
+}
+
+# }}}
+
+sub get_dba_password {
+    print
+"In order to create a new database and grant RT access to that database,\n";
+    print "this script needs to connect to your "
+      . $RT::DatabaseType
+      . " instance on "
+      . $RT::DatabaseHost . " as "
+      . $args{'dba'} . ".\n";
+    print
+"Please specify that user's database password below. If the user has no database\n";
+    print "password, just press return.\n\n";
+    print "Password: ";
+    ReadMode('noecho');
+    my $password = ReadLine(0);
+    ReadMode('normal');
+    return ($password);
+}
+
+# {{{ sub _yesno
+sub _yesno {
+    print "Proceed [y/N]:";
+    my $x = scalar(<STDIN>);
+    $x =~ /^y/i;
+}
+
+# }}}
+
+# {{{ insert_acls
+sub insert_acl {
+
+        my $base_path = (shift || $RT::EtcPath);
+
+    if ( $RT::DatabaseType =~ /^oracle$/i ) {
+        do $base_path . "/acl.Oracle"
+          || die "Couldn't find ACLS for Oracle\n" . $@;
+    }
+    elsif ( $RT::DatabaseType =~ /^pg$/i ) {
+        do $base_path . "/acl.Pg" || die "Couldn't find ACLS for Pg\n" . $@;
+    }
+    elsif ( $RT::DatabaseType =~ /^mysql$/i ) {
+        do $base_path . "/acl.mysql"
+          || die "Couldn't find ACLS for mysql in " . $RT::EtcPath . "\n" . $@;
+    }
+    elsif ( $RT::DatabaseType =~ /^SQLite$/i ) {
+        return;
+    }
+    else {
+        die "Unknown RT database type";
+    }
+
+    my @acl = acl($dbh);
+    foreach my $statement (@acl) {
+        print STDERR $statement if $args{'debug'};
+        my $sth = $dbh->prepare($statement) or die $dbh->errstr;
+        unless ( $sth->execute ) {
+            die "Problem with statement:\n $statement\n" . $sth->errstr;
+        }
+    }
+}
+
+# }}}
+
+=head2 get_system_dsn
+
+Returns a dsn suitable for database creates and drops
+and user creates and drops
+
+=cut
+
+sub get_system_dsn {
+
+    my $dsn = $Handle->DSN;
+
+    #with mysql, you want to connect sans database to funge things
+    if ( $RT::DatabaseType eq 'mysql' ) {
+        $dsn =~ s/dbname=$RT::DatabaseName//;
+
+        # with postgres, you want to connect to database1
+    }
+    elsif ( $RT::DatabaseType eq 'Pg' ) {
+        $dsn =~ s/dbname=$RT::DatabaseName/dbname=template1/;
+    }
+    return $dsn;
+}
+
+sub insert_initial_data {
+
+    RT::InitLogging();
+
+    #connect to the db, for actual RT work
+    require RT::Handle;
+    $RT::Handle = RT::Handle->new();
+    $RT::Handle->Connect();
+
+    #Put together a current user object so we can create a User object
+    my $CurrentUser = new RT::CurrentUser();
+
+    print "Checking for existing system user...";
+    my $test_user = RT::User->new($CurrentUser);
+    $test_user->Load('RT_System');
+    if ( $test_user->id ) {
+        print "found!\n\nYou appear to have a functional RT database.\n"
+          . "Exiting, so as not to clobber your existing data.\n";
+        exit(-1);
+
+    }
+    else {
+        print "not found.  This appears to be a new installation.\n";
+    }
+
+    print "Creating system user...";
+    my $RT_System = new RT::User($CurrentUser);
+
+    my ( $val, $msg ) = $RT_System->_BootstrapCreate(
+        Name     => 'RT_System',
+        RealName => 'The RT System itself',
+        Comments =>
+'Do not delete or modify this user. It is integral to RT\'s internal database structures',
+        Creator => '1' );
+
+    unless ($val) {
+        print "$msg\n";
+        exit(1);
+    }
+    print "done.\n";
+    $RT::Handle->dbh->disconnect();
+
+}
+
+# load some sort of data into the database
+
+sub insert_data {
+    my $datafile = shift;
+
+    #Connect to the database and get RT::SystemUser and RT::Nobody loaded
+    RT::Init;
+
+    my $CurrentUser = RT::CurrentUser->new();
+    $CurrentUser->LoadByName('RT_System');
+
+    if ( $datafile eq $RT::EtcPath . "/initialdata" ) {
+
+        print "Creating Superuser  ACL...";
+
+        my $superuser_ace = RT::ACE->new($CurrentUser);
+        $superuser_ace->_BootstrapCreate(
+                             PrincipalId => ACLEquivGroupId( $CurrentUser->Id ),
+                             PrincipalType => 'Group',
+                             RightName     => 'SuperUser',
+                             ObjectType    => 'RT::System',
+                             ObjectId      => '1' );
+
+    }
+
+    # Slurp in stuff to insert from the datafile. Possible things to go in here:-
+    # @groups, @users, @acl, @queues, @ScripActions, @ScripConditions, @templates
+
+    require $datafile
+      || die "Couldn't find initial data for import\n" . $@;
+
+    if (@Groups) {
+        print "Creating groups...";
+        foreach $item (@Groups) {
+            my $new_entry = RT::Group->new($CurrentUser);
+            my ( $return, $msg ) = $new_entry->_Create(%$item);
+            print "(Error: $msg)" unless ($return);
+            print $return. ".";
+        }
+        print "done.\n";
+    }
+    if (@Users) {
+        print "Creating users...";
+        foreach $item (@Users) {
+            my $new_entry = new RT::User($CurrentUser);
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+            print "(Error: $msg)" unless ($return);
+            print $return. ".";
+        }
+        print "done.\n";
+    }
+    if (@Queues) {
+        print "Creating queues...";
+        for $item (@Queues) {
+            my $new_entry = new RT::Queue($CurrentUser);
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+            print "(Error: $msg)" unless ($return);
+            print $return. ".";
+        }
+        print "done.\n";
+    }
+    if (@ACL) {
+        print "Creating ACL...";
+        for my $item (@ACL) {
+
+           my ($princ, $object);
+
+           # Global rights or Queue rights?
+           if ($item->{'Queue'}) {
+                $object = RT::Queue->new($CurrentUser);
+                $object->Load( $item->{'Queue'} );
+           } else {
+               $object = $RT::System;
+           }
+
+           # Group rights or user rights?
+           if ($item->{'GroupDomain'}) {
+                $princ = RT::Group->new($CurrentUser);
+               if ($item->{'GroupDomain'} eq 'UserDefined') {
+                  $princ->LoadUserDefinedGroup( $item->{'GroupId'} );
+               } elsif ($item->{'GroupDomain'} eq 'SystemInternal') {
+                  $princ->LoadSystemInternalGroup( $item->{'GroupType'} );
+               } elsif ($item->{'GroupDomain'} eq 'RT::Queue-Role' &&
+                        $item->{'Queue'}) {
+                  $princ->LoadQueueRoleGroup( Type => $item->{'GroupType'},
+                                             Queue => $object->id);
+               } else {
+                  $princ->Load( $item->{'GroupId'} );
+               }
+           } else {
+               $princ = RT::User->new($CurrentUser);
+               $princ->Load( $item->{'UserId'} );
+           }
+
+           # Grant it
+           my ( $return, $msg ) = $princ->PrincipalObj->GrantRight(
+                                                     Right => $item->{'Right'},
+                                                     Object => $object );
+
+            if ($return) {
+                print $return. ".";
+            }
+            else {
+                print $msg . ".";
+
+            }
+
+        }
+        print "done.\n";
+    }
+    if (@CustomFields) {
+        print "Creating custom fields...";
+        for $item (@CustomFields) {
+            my $new_entry = new RT::CustomField($CurrentUser);
+            my $values    = $item->{'Values'};
+            delete $item->{'Values'};
+            my $q     = $item->{'Queue'};
+            my $q_obj = RT::Queue->new($CurrentUser);
+            $q_obj->Load($q);
+            if ( $q_obj->Id ) {
+                $item->{'Queue'} = $q_obj->Id;
+            }
+            elsif ( $q == 0 ) {
+                $item->{'Queue'} = 0;
+            }
+            else {
+                print "(Error: Could not find queue " . $q . ")\n"
+                  unless ( $q_obj->Id );
+                next;
+            }
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+
+            foreach my $value ( @{$values} ) {
+                my ( $eval, $emsg ) = $new_entry->AddValue(%$value);
+                print "(Error: $emsg)\n" unless ($eval);
+            }
+
+            print "(Error: $msg)\n" unless ($return);
+            print $return. ".";
+        }
+
+        print "done.\n";
+    }
+
+    if (@ScripActions) {
+        print "Creating ScripActions...";
+
+        for $item (@ScripActions) {
+            my $new_entry = RT::ScripAction->new($CurrentUser);
+            my $return    = $new_entry->Create(%$item);
+            print $return. ".";
+        }
+
+        print "done.\n";
+    }
+
+    if (@ScripConditions) {
+        print "Creating ScripConditions...";
+
+        for $item (@ScripConditions) {
+            my $new_entry = RT::ScripCondition->new($CurrentUser);
+            my $return    = $new_entry->Create(%$item);
+            print $return. ".";
+        }
+
+        print "done.\n";
+    }
+
+    if (@Templates) {
+        print "Creating templates...";
+
+        for $item (@Templates) {
+            my $new_entry = new RT::Template($CurrentUser);
+            my $return    = $new_entry->Create(%$item);
+            print $return. ".";
+        }
+        print "done.\n";
+    }
+    if (@Scrips) {
+        print "Creating scrips...";
+
+        for $item (@Scrips) {
+            my $new_entry = new RT::Scrip($CurrentUser);
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+            if ($return) {
+                print $return. ".";
+            }
+            else {
+                print "(Error: $msg)\n";
+            }
+        }
+        print "done.\n";
+    }
+    $RT::Handle->Disconnect();
+
+}
+
+=head2 ACLEquivGroupId
+
+Given a userid, return that user's acl equivalence group
+
+=cut
+
+sub ACLEquivGroupId {
+    my $username = shift;
+    my $user     = RT::User->new($RT::SystemUser);
+    $user->Load($username);
+    my $equiv_group = RT::Group->new($RT::SystemUser);
+    $equiv_group->LoadACLEquivalenceGroup($user);
+    return ( $equiv_group->Id );
+}
+
+sub help {
+
+    print <<EOF;
+
+$0: Set up RT's database
+
+--action        init    Initialize the database
+                drop    Drop the database. 
+                        This will ERASE ALL YOUR DATA
+                insert  Insert data into RT's database. 
+                        By default, will use RT's installation data.
+                        To use a local or supplementary datafile, specify it
+                        using the '--datafile' option below.
+                        
+                acl     Initialize only the database ACLs
+                        To use a local or supplementary datafile, specify it
+                        using the '--datadir' option below.
+                        
+                schema  Initialize only the database schema
+                        To use a local or supplementary datafile, specify it
+                        using the '--datadir' option below.
+
+--datafile /path/to/datafile
+--datadir /path/to/              Used to specify a path to find the local
+                                database schema and acls to be installed.
+
+
+--dba                           dba's username
+--dba-password                  dba's password
+--prompt-for-dba-password       Ask for the database administrator's password interactively
+
+
+EOF
+
+}
+
+1;
diff --git a/rt/sbin/rt-test-dependencies b/rt/sbin/rt-test-dependencies
new file mode 100644 (file)
index 0000000..637d33a
--- /dev/null
@@ -0,0 +1,246 @@
+#!/usr/bin/perl
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+#
+# This is just a basic script that checks to make sure that all
+# the modules needed by RT before you can install it.
+#
+
+use strict;
+no warnings qw(numeric redefine);
+use Getopt::Long;
+use CPAN;
+my %args;
+my %deps;
+GetOptions(\%args,'install', 'with-MYSQL', 'with-POSTGRESQL|with-pg|with-pgsql', 'with-SQLITE', 'with-ORACLE', 'with-FASTCGI', 'with-SPEEDYCGI', 'with-MODPERL1', 'with-MODPERL2' ,'with-DEV');
+
+if  (!keys %args) {
+help();
+exit(0);
+}
+$args{'with-MASON'} = 1;
+$args{'with-CORE'} = 1;
+$args{'with-DEV'} =1; 
+$args{'with-CLI'} =1; 
+$args{'with-MAILGATE'} =1; 
+if ($] < 5.007) {
+$args{'with-I18N-COMPAT'} = 1;
+}
+
+
+sub help {
+
+print <<'.'
+
+By default, testdeps determine whether you have 
+installed all the perl modules RT needs to run.
+
+       --install               Install missing modules
+
+The following switches will tell the tool to check for specific dependencies
+
+       --with-mysql            Database interface for MySQL
+       --with-postgresql       Database interface for PostgreSQL 
+       --with-sqlite           Database interface and driver for SQLite (unsupported)
+       --with-oracle           Database interface for oracle (unsupported)
+
+       --with-fastcgi          Libraries needed to support the fastcgi handler
+       --with-speedycgi        Libraries needed to support the speedycgi handler
+       --with-modperl1         Libraries needed to support the modperl 1 handler
+       --with-modperl2         Libraries needed to support the modperl 2 handler
+
+       --with-dev              Tools needed for RT development
+.
+}
+
+
+sub _ {
+    map { /(\S+)\s*(\S*)/; $1 => ($2 ? $2 :'') } split ( /\n/, $_[0] );
+}
+
+$deps{'CORE'} = [ _( << '.') ];
+Digest::MD5
+DBI 1.18
+Test::Inline
+Class::ReturnValue 0.40
+DBIx::SearchBuilder 0.86
+Text::Template
+File::Spec 0.8
+HTML::Entities 
+Net::Domain
+Log::Dispatch 2.0
+Locale::Maketext 1.04
+Locale::Maketext::Lexicon 0.25
+Locale::Maketext::Fuzzy
+MIME::Entity 5.108
+Mail::Mailer 1.57
+Net::SMTP
+Text::Wrapper 
+Time::ParseDate
+File::Temp
+Term::ReadKey
+Text::Autoformat
+Text::Quoted
+.
+
+$deps{'MASON'} = [ _( << '.') ];
+Params::Validate 0.02
+Cache::Cache
+Exception::Class
+HTML::Mason 1.16
+MLDBM
+Errno
+FreezeThaw
+Digest::MD5
+CGI::Cookie 1.20
+Storable
+Apache::Session 1.53
+.
+
+$deps{'MAILGATE'} = [ _( << '.') ];
+HTML::TreeBuilder
+HTML::FormatText
+Getopt::Long
+LWP::UserAgent
+.
+
+$deps{'CLI'} = [ _( << '.') ];
+Getopt::Long 2.24
+.
+
+$deps{'DEV'} = [ _( << '.') ];
+Regexp::Common
+Time::HiRes 
+Test::Inline 
+WWW::Mechanize
+.
+
+$deps{'FASTCGI'} = [ _( << '.') ];
+CGI
+FCGI
+CGI::Fast 
+.
+
+$deps{'SPEEDYCGI'} = [ _( << '.') ];
+CGI
+CGI::SpeedyCGI
+.
+
+
+$deps{'MODPERL1'} = [ _( << '.') ];
+CGI
+Apache::Request
+Apache::DBI
+.
+
+$deps{'MODPERL2'} = [ _( << '.') ];
+CGI 2.89
+Apache::DBI
+.
+
+$deps{'I18N-COMPAT'} = [ _( << '.') ];
+Text::Iconv
+Encode::compat 0.04
+.
+
+$deps{'MYSQL'} = [ _( << '.') ];
+DBD::mysql 2.1018
+.
+$deps{'ORACLE'} = [ _( << '.') ];
+DBD::Oracle
+.
+$deps{'POSTGRESQL'} = [ _( << '.') ];
+DBD::Pg
+.
+
+
+foreach my $type (keys %args)  {
+next unless ($type =~ /^with-(.*?)$/);
+my $type = $1;
+print "$type dependencies:\n";
+       my @deps = (@{$deps{$type}});
+       while (@deps) {
+               my $module = shift @deps;
+               my $version = shift @deps;
+my $ret;
+       $ret =test_dep($module, $version);      
+
+if ($args{'install'} && !$ret) {
+       resolve_dep($module);           
+}
+}
+}
+sub test_dep {
+       my $module = shift;
+       my $version = shift;
+
+         print "\t$module $version";
+        eval "use $module $version" ;
+        if ($@) {
+       my $error = $@;
+       $error =~ s/\n(.*)$//s;
+       print "...MISSING\n";
+               print "\t\t$error\n" if $error =~ /this is only/;
+
+       return undef;
+       } else {
+       print "...found\n";
+return 1;
+       }
+}
+
+sub resolve_dep {
+       my $module = shift;
+       use CPAN;
+       CPAN::Shell->install($module);          
+       
+}
+
+
+sub print_help {
+    print << "EOF";
+
+$0 FLAG DBTYPE
+
+
+$0 is a tool for RT that will tell you if you've got all
+the modules RT depends on properly installed.
+
+Flags: (only one flag is valid for a given run)
+
+-quiet will check to see if we've got everything we need
+       and will exit with a return code of (1) if we don't.
+
+-warn will tell you what isn't properly installed
+
+-fix will use CPANPLUS.pm or CPAN.pm to magically make everything better
+
+DBTYPE is one of:
+       oracle, pg, mysql
+
+EOF
+
+    exit(0);
+}
diff --git a/rt/sbin/rt-test-dependencies.in b/rt/sbin/rt-test-dependencies.in
new file mode 100644 (file)
index 0000000..6951290
--- /dev/null
@@ -0,0 +1,246 @@
+#!@PERL@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+#
+# This is just a basic script that checks to make sure that all
+# the modules needed by RT before you can install it.
+#
+
+use strict;
+no warnings qw(numeric redefine);
+use Getopt::Long;
+use CPAN;
+my %args;
+my %deps;
+GetOptions(\%args,'install', 'with-MYSQL', 'with-POSTGRESQL|with-pg|with-pgsql', 'with-SQLITE', 'with-ORACLE', 'with-FASTCGI', 'with-SPEEDYCGI', 'with-MODPERL1', 'with-MODPERL2' ,'with-DEV');
+
+if  (!keys %args) {
+help();
+exit(0);
+}
+$args{'with-MASON'} = 1;
+$args{'with-CORE'} = 1;
+$args{'with-DEV'} =1; 
+$args{'with-CLI'} =1; 
+$args{'with-MAILGATE'} =1; 
+if ($] < 5.007) {
+$args{'with-I18N-COMPAT'} = 1;
+}
+
+
+sub help {
+
+print <<'.'
+
+By default, testdeps determine whether you have 
+installed all the perl modules RT needs to run.
+
+       --install               Install missing modules
+
+The following switches will tell the tool to check for specific dependencies
+
+       --with-mysql            Database interface for MySQL
+       --with-postgresql       Database interface for PostgreSQL 
+       --with-sqlite           Database interface and driver for SQLite (unsupported)
+       --with-oracle           Database interface for oracle (unsupported)
+
+       --with-fastcgi          Libraries needed to support the fastcgi handler
+       --with-speedycgi        Libraries needed to support the speedycgi handler
+       --with-modperl1         Libraries needed to support the modperl 1 handler
+       --with-modperl2         Libraries needed to support the modperl 2 handler
+
+       --with-dev              Tools needed for RT development
+.
+}
+
+
+sub _ {
+    map { /(\S+)\s*(\S*)/; $1 => ($2 ? $2 :'') } split ( /\n/, $_[0] );
+}
+
+$deps{'CORE'} = [ _( << '.') ];
+Digest::MD5
+DBI 1.18
+Test::Inline
+Class::ReturnValue 0.40
+DBIx::SearchBuilder 0.86
+Text::Template
+File::Spec 0.8
+HTML::Entities 
+Net::Domain
+Log::Dispatch 2.0
+Locale::Maketext 1.04
+Locale::Maketext::Lexicon 0.25
+Locale::Maketext::Fuzzy
+MIME::Entity 5.108
+Mail::Mailer 1.57
+Net::SMTP
+Text::Wrapper 
+Time::ParseDate
+File::Temp
+Term::ReadKey
+Text::Autoformat
+Text::Quoted
+.
+
+$deps{'MASON'} = [ _( << '.') ];
+Params::Validate 0.02
+Cache::Cache
+Exception::Class
+HTML::Mason 1.16
+MLDBM
+Errno
+FreezeThaw
+Digest::MD5
+CGI::Cookie 1.20
+Storable
+Apache::Session 1.53
+.
+
+$deps{'MAILGATE'} = [ _( << '.') ];
+HTML::TreeBuilder
+HTML::FormatText
+Getopt::Long
+LWP::UserAgent
+.
+
+$deps{'CLI'} = [ _( << '.') ];
+Getopt::Long 2.24
+.
+
+$deps{'DEV'} = [ _( << '.') ];
+Regexp::Common
+Time::HiRes 
+Test::Inline 
+WWW::Mechanize
+.
+
+$deps{'FASTCGI'} = [ _( << '.') ];
+CGI
+FCGI
+CGI::Fast 
+.
+
+$deps{'SPEEDYCGI'} = [ _( << '.') ];
+CGI
+CGI::SpeedyCGI
+.
+
+
+$deps{'MODPERL1'} = [ _( << '.') ];
+CGI
+Apache::Request
+Apache::DBI
+.
+
+$deps{'MODPERL2'} = [ _( << '.') ];
+CGI 2.89
+Apache::DBI
+.
+
+$deps{'I18N-COMPAT'} = [ _( << '.') ];
+Text::Iconv
+Encode::compat 0.04
+.
+
+$deps{'MYSQL'} = [ _( << '.') ];
+DBD::mysql 2.1018
+.
+$deps{'ORACLE'} = [ _( << '.') ];
+DBD::Oracle
+.
+$deps{'POSTGRESQL'} = [ _( << '.') ];
+DBD::Pg
+.
+
+
+foreach my $type (keys %args)  {
+next unless ($type =~ /^with-(.*?)$/);
+my $type = $1;
+print "$type dependencies:\n";
+       my @deps = (@{$deps{$type}});
+       while (@deps) {
+               my $module = shift @deps;
+               my $version = shift @deps;
+my $ret;
+       $ret =test_dep($module, $version);      
+
+if ($args{'install'} && !$ret) {
+       resolve_dep($module);           
+}
+}
+}
+sub test_dep {
+       my $module = shift;
+       my $version = shift;
+
+         print "\t$module $version";
+        eval "use $module $version" ;
+        if ($@) {
+       my $error = $@;
+       $error =~ s/\n(.*)$//s;
+       print "...MISSING\n";
+               print "\t\t$error\n" if $error =~ /this is only/;
+
+       return undef;
+       } else {
+       print "...found\n";
+return 1;
+       }
+}
+
+sub resolve_dep {
+       my $module = shift;
+       use CPAN;
+       CPAN::Shell->install($module);          
+       
+}
+
+
+sub print_help {
+    print << "EOF";
+
+$0 FLAG DBTYPE
+
+
+$0 is a tool for RT that will tell you if you've got all
+the modules RT depends on properly installed.
+
+Flags: (only one flag is valid for a given run)
+
+-quiet will check to see if we've got everything we need
+       and will exit with a return code of (1) if we don't.
+
+-warn will tell you what isn't properly installed
+
+-fix will use CPANPLUS.pm or CPAN.pm to magically make everything better
+
+DBTYPE is one of:
+       oracle, pg, mysql
+
+EOF
+
+    exit(0);
+}
diff --git a/rt/tools/cpan2rpm b/rt/tools/cpan2rpm
deleted file mode 100644 (file)
index 9b54cb9..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-#!/usr/bin/perl -w
-
-
-# Take a perl tarball and make a specfile for it. Now with bundles.
-#
-# Copyright 2000,2001 Simon Wilkinson. All rights reserved.
-#
-# 10/18/2001 - <jesse@bestpractical.com>
-#              Added resolution of prereq_pm modules
-#
-# This program is free software; you can redistribute it 
-# and/or modify it under the same terms as Perl itself.
-#
-
-use strict;
-
-use CPAN;
-use POSIX;
-use Sys::Hostname;
-use File::Basename;
-use Getopt::Long;
-
-use vars qw ($DEBUG $ARCH $builddir $seen @report);
-
-$ARCH = 'i386';
-
-$DEBUG = 0;
-# Icky globals
-
-my $release;
-my $package;
-
-$seen = {};
-
-
-sub usage 
-{
-  print STDERR <<EOM;
-
-Usage: cpan2rpm [--release <release>] [--builddir <rpm build dir>]  <Perl::Module>
-
-Where:
-<release> is the release number of the RPM you wish to produce
-<Perl::Module> is the name of the module to build
-EOM
-  exit(1);
-}
-
-
-my $ret=GetOptions("release" => \$release,
-                  "builddir=s" => \$builddir);
-
-$package=$ARGV[0];
-usage() if !$package;
-$release=1 if !$release;
-
-
-$builddir=ExtractRpmMacro($ENV{HOME}."/.rpmmacros","_topdir") if !$builddir;
-$builddir=ExtractRpmMacro("/etc/rpm/macros","_topdir") if !$builddir;
-$builddir=getcwd() if !$builddir;
-  
-die "Build directory $builddir doesn't look like an RPM build root\n"
-    if ((! -d "$builddir/SPECS") || (! -d "$builddir/SOURCES"));
-
-process($package,$release);
-
-print join("\n",@report)."\n";
-
-sub process {
-  my ($infile,$release)=@_;
-
-  
-
-# Convert our installation list into an unbundled one
-  unbundle($infile);
-
-  print "Building $infile\n";
-
-    cpan2rpm($infile,$builddir,$release);
-
-}
-
-# Given a Module, try to split it into its required components - this
-# currently only handles Bundles, but could also be extended to deal with
-# prereqs as well.
-
-sub unbundle {
-  my ($item) = @_;
-
-  if ($item=~/Bundle::/) {
-    my $obj=CPAN::Shell->expand('Bundle',$item);
-
-    foreach my $kid ($obj->contains) {
-       process($kid,$release);
-    }
-  }
-}
-
-
-sub cpan2rpm($$$) {
-  my ($infile,$builddir,$release) = @_;
-
-  my $ret;
-
-  my $obj=CPAN::Shell->expand('Module',$infile);
-
-  print "CPAN tells us the following about $infile:\n",$obj->as_string if ($DEBUG);
-
-  $ret=fetch_source($obj,$builddir);
-  $ret=build_specfile($obj,$builddir,$release) if !$ret;
-  
-  return $ret;
-}
-
-# FIXME: Some error handling in the function below wouldn't go amiss ...
-sub fetch_source {
-  my ($obj,$builddir)=@_;
-
-  # Minor Sanity checks
-  my $id=$obj->{ID};
-
-  return "Error: No file for $id\n" 
-     if $obj->cpan_file eq "N/A";
-  return "Error: $id says 'Contact Author'\n" 
-     if $obj->cpan_file =~ /^Contact Author/;
-  return "Error: $id is contained within Perl itself!\n"
-     if ($obj->cpan_file =~/perl-5\.\d?\.\d?\.tar\.gz/xo);
-
-  # We do this so we can take advantage of CPAN's object caching. This is
-  # pinched from the CPAN::Distribution::get method, which we can't use
-  # directly, as it untars the package as well - which we let RPM do.
-  my $dist = $CPAN::META->instance('CPAN::Distribution',$obj->cpan_file);
-
-
-  my($local_wanted) =
-       MM->catfile($CPAN::Config->{keep_source_where},
-                   "authors",
-                   "id",
-                   split("/",$dist->{ID})
-                   );
-
-  my $local_file = CPAN::FTP->localize("authors/id/$dist->{ID}", $local_wanted);
-  
-  $dist->{localfile} = $local_file;
-
-  $dist->verifyMD5 if ($CPAN::META->has_inst('MD5'));
-
-
-  # Find all the prereqs for this distribution, then build em.
-  # TODO this should be somewhere else
-
-  $dist->make;
-  build_prereqs( $dist->prereq_pm());
-
-
-
-  my $infile=basename($obj->cpan_file);
-
-  File::Copy::copy($local_file,"$builddir/SOURCES/$infile");
-
-  return undef;
-}
-
-
-sub build_prereqs($) {
-  my ($prereqs) = @_;
-  
-  foreach my $prereq (keys %{$prereqs}) {
-       process ($prereq, $release);
-  }
-}
-sub build_specfile($$$) {
-  my ($obj,$builddir,$release) = @_;
-
-  my $source=basename($obj->cpan_file);
-
-  # don't go through dependencies on something we've already dealt with
-  return() if ($seen->{$source});
-  $seen->{$source} = 1; 
-
-my ($name,$version)=($source=~/(.*)-(.*)\.tar\.gz/);
-  return "Couldn't get a name for $source\n" if !$name;
-  return "Couldn't get a version for $source\n" if !$version; 
-  
-  my $summary="$name module for perl";
-  my $description=$obj->{description};
-  $description= $summary if !$description;
-
-  open(SPEC, ">$builddir/SPECS/perl-$name.spec")
-    or die "Couldn't open perl-$name.spec for writing.";
-  print SPEC <<EOF;
-
-Summary: $summary
-Name: perl-$name
-Version: $version
-Release: $release
-Copyright: distributable
-Group: Applications/CPAN
-Source0: $source
-Url: http://www.cpan.org
-BuildRoot: /var/tmp/perl-${name}-buildroot/
-Requires: perl 
-
-%description
-This is a perl module, autogenerated by cpan2rpm. The original package's
-description was:
-
-$description
-
-%prep
-%setup -q -n $name-%{version}
-
-%build
-CFLAGS="\$RPM_OPT_FLAGS" perl Makefile.PL
-make
-
-%clean
-rm -rf \$RPM_BUILD_ROOT
-
-%install
-rm -rf \$RPM_BUILD_ROOT
-eval `perl '-V:installarchlib'`
-mkdir -p \$RPM_BUILD_ROOT/\$installarchlib
-make PREFIX=\$RPM_BUILD_ROOT/usr install
-/usr/lib/rpm/brp-compress
-find \$RPM_BUILD_ROOT/usr -type f -print | sed "s\@^\$RPM_BUILD_ROOT\@\@g" | grep -v perllocal.pod > $name-$version-filelist
-
-%files -f ${name}-${version}-filelist
-%defattr(-,root,root)
-
-%changelog
-EOF
-  print SPEC "* ",POSIX::strftime("%a %b %d %Y",localtime()), " ",$ENV{USER}," <",$ENV{USER},"\@",hostname(),">\n";
-  print SPEC "- Spec file automatically generated by cpan2rpm\n";
-
-  close(SPEC);
-
-  system("rpm -ba $builddir/SPECS/perl-$name.spec >/dev/null") == 0
-    or push (@report,  "RPM of $source failed with : $!\n"); 
-  system("rpm -Uvh $builddir/RPMS/$ARCH/perl-$name-$version-$release.$ARCH.rpm") == 0
-    or warn "RPM of $source could not be installed: $!\n";
-
-  push (@report,  "Built perl-$name-$version-$release.$ARCH.rpm");
-}
-
-sub ExtractRpmMacro {
-  my ($file,$macro) = @_;
-
-  my $handle=new IO::File;
-
-  if (!$handle->open($file)) {
-    return undef;
-  }
-
-  while(<$handle>) {
-    if (/\%$macro (.*)/) {
-       return $1;
-    }
-  }
-
-  return undef;
-}
-
-=head1 NAME
-
-cpan2rpm - fetch and convert CPAN packages to RPMs
-
-=head1 SYNOPSIS
-
-cpan2rpm --release <release> <package>
-
-=head1 DESCRIPTION
-
-cpan2rpm provides a quick way of creating RPM packages from perl modules
-published on CPAN. It interfaces with the perl CPAN module to fetch the
-file from the selected mirror, and then creates a spec file from the 
-information in CPAN, and invokes RPM on that spec file.
-
-Files are created in the users RPM build root.
-
-=head1 OPTIONS
-
-=over 4
-
-=item release
-
-Sets the release number of the created RPMs.
-
-=back
-
-=head1 SEE ALSO
-
-rpm(1)
-
-=head1 AUTHOR
-
-Simon Wilkinson <sxw@sxw.org.uk>
diff --git a/rt/tools/initdb b/rt/tools/initdb
deleted file mode 100644 (file)
index ffb1ae3..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-#!/usr/bin/perl -w
-# $Header: /home/cvs/cvsroot/freeside/rt/tools/Attic/initdb,v 1.1 2002-08-12 06:17:08 ivan Exp $
-
-use strict;
-use vars qw($PROMPT $SCHEMA_FILE $SCHEMA_DIR
-           $ACTION $DEBUG $DB_TYPE $DB_HOME 
-           $DB_HOST $DB_PORT $DB_DBA $DB_DATABASE $DB_DBA_PASSWORD);
-
-use DBI;
-use DBIx::DataSource qw( create_database drop_database );
-
-
-$|=1; #unbuffer that output.
-
-$DEBUG=0;
-$PROMPT = 1; #by default, should at least *ask* before nuking databases
-$SCHEMA_DIR ="etc";
-$SCHEMA_FILE = "$SCHEMA_DIR/schema.pm"; #hmm
-
-($DB_TYPE, $DB_HOME, $DB_HOST, $DB_PORT, $DB_DBA, $DB_DATABASE, $ACTION) = @ARGV;
-
-
-if ($DEBUG) {
-  print_config_params();
-}
-my $dsn = "dbi:$DB_TYPE:";
-
-if (($DB_TYPE eq 'Pg') or ($DB_TYPE eq 'mysql')) {
-   $dsn .= "dbname=$DB_DATABASE";
-   if ($DB_HOST) {
-       $dsn .= ";host=$DB_HOST";
-    }
-   if ($DB_PORT) {
-       $dsn .= ";port=$DB_PORT";
-   }
-}
-elsif ($DB_TYPE eq 'Oracle') {
-   $dsn .= "$DB_DATABASE";
-}
-
-
-if ($ACTION eq 'create') {
-    unless ($DB_TYPE eq 'Oracle') {
-        print "Now creating a database for RT.\n";
-       prompt_for_dba_password();
-       create_db();
-    }
-}
-elsif ($ACTION eq 'drop' ) {
-    unless ($DB_TYPE eq 'Oracle') {
-       print "Now dropping the RT2 database.\n";
-        prompt_for_dba_password();
-        drop_db();
-    }
-}
-elsif ($ACTION eq 'insert' ) {
-    print "Now populating database schema.\n";
-    prompt_for_dba_password();
-    insert_schema();
-}
-elsif ($ACTION eq 'generate') {
-    prompt_for_dba_password();
-    generate_schema();
-}
-else {
-    print STDERR '$ACTION unspecified. Makefile error. It was '.$ACTION ;
-    exit(-1);
-}
-
-
-# {{{ sub prompt_for_dba_password
-
-sub prompt_for_dba_password {
-    print "Enter the $DB_TYPE password for $DB_DBA: ";
-
-    system "stty -echo";
-    $DB_DBA_PASSWORD = scalar(<STDIN>); #keep off commandline
-    system "stty echo";
-    chomp $DB_DBA_PASSWORD;
-
-}
-# }}}
-
-# {{{ sub print_config_params
-sub print_config_params {
-    print <<END;
-Database creation parameters:
-
-DB_TYPE         = $DB_TYPE
-DB_HOME         = $DB_HOME
-DB_HOST         = $DB_HOST
-DB_DBA          = $DB_DBA
-DB_DBA_PASSWORD = <hidden>
-DB_DATABASE     = $DB_DATABASE
-END
-}
-# }}}
-
-# {{{ sub drop_db
-sub drop_db {
-    
-    if ( $PROMPT ) {
-       print <<END;
-
-About to drop $DB_TYPE database $DB_DATABASE.
-WARNING: This will erase all data in $DB_DATABASE.
-If you have an existing RT 2.x installation, this will destroy all your data.
-i
-END
-       exit unless _yesno();
-       
-    }
-    
-
-  print "\nDropping $DB_TYPE database $DB_DATABASE.\n";
-  drop_database( $dsn, $DB_DBA, $DB_DBA_PASSWORD )
-    or warn $DBIx::DataSource::errstr;
-
-
-}
-# }}}
-
-# {{{ sub generate_schema
-sub generate_schema {
-    my @schema = generate_schema_from_hash();
-    print "Generating schema for $DB_TYPE...";
-    
-    system('mv', "$SCHEMA_DIR/schema.$DB_TYPE", "$SCHEMA_DIR/schema.$DB_TYPE.bak")
-      if (-f "$SCHEMA_DIR/schema.$DB_TYPE");
-    open(SCHEMA, ">$SCHEMA_DIR/schema.$DB_TYPE");
-    foreach my $line (@schema) {
-       print SCHEMA "$line;\n";
-    }
-    close(SCHEMA);
-    print "done.\n";
-}
-# }}}
-
-# {{{ sub insert_schema
-sub insert_schema {
-    my (@schema);
-    print "\nCreating database schema.\n";
-   
-    my $dbh = DBI->connect( $dsn, $DB_DBA, $DB_DBA_PASSWORD ) or die $DBI::errstr;    
-    
-    if ( -f "$SCHEMA_DIR/schema.$DB_TYPE") {
-       open (SCHEMA, "<$SCHEMA_DIR/schema.$DB_TYPE");
-       my $statement = "";
-       foreach my $line (<SCHEMA>) {
-           $statement .= $line;
-           if ($line =~ /;$/) {
-               $statement =~ s/;$//g;
-               push @schema, $statement;
-               $statement = "";
-           }
-       }       
-    }  
-    
-    else {
-        @schema = generate_schema_from_hash();
-     }
-    
-    foreach my $statement (@schema) {
-       print STDERR $statement if $DEBUG;
-       my $sth = $dbh->prepare($statement) or die $dbh->errstr;
-       unless ($sth->execute) {
-           print STDERR "Problem with statement:\n $statement\n";
-           die $sth->errstr;
-       }
-    }
-    
-    
-    $dbh->disconnect;
-    print "schema sucessfully inserted\n";
-    
-}
-# }}}
-
-# {{{ sub generate_schema_from_hash
-sub generate_schema_from_hash {
-    my (@schema);
-    
-    require DBIx::DBSchema;    
-    my $schema_href = do "$SCHEMA_FILE" or die $@ || $!;
-    my $schema = DBIx::DBSchema->pretty_read($schema_href);
-    
-    
-    foreach my $statement ( $schema->sql($dsn, $DB_DBA, $DB_DBA_PASSWORD ) ) {
-       print STDERR $statement if $DEBUG;
-       chomp $statement;
-       push @schema, $statement;
-       
-    }
-    return (@schema);
-    
-}
-# }}}
-
-# {{{ sub create_db
-sub create_db {
-    
-    print "\nCreating $DB_TYPE database $DB_DATABASE.\n";
-    create_database( $dsn, $DB_DBA, $DB_DBA_PASSWORD )
-      or die $DBIx::DataSource::errstr;
-
-}
-# }}}
-
-# {{{ sub _yesno
-sub _yesno {
-    print "Proceed [y/N]:";
-    my $x = scalar(<STDIN>);
-    $x =~ /^y/i;
-}
-
-# }}}
diff --git a/rt/tools/insertdata b/rt/tools/insertdata
deleted file mode 100755 (executable)
index b3e76e6..0000000
+++ /dev/null
@@ -1,618 +0,0 @@
-#!/usr/bin/perl -w
-#
-# $Header: /home/cvs/cvsroot/freeside/rt/tools/Attic/insertdata,v 1.1 2002-08-12 06:17:08 ivan Exp $
-# RT is (c) 1996-2002 Jesse Vincent (jesse@bestpractical.com);
-
-package RT;
-use strict;
-use vars qw($VERSION $Handle $Nobody $SystemUser $item);
-
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
-
-#This drags in  RT's config.pm
-use config;
-use Carp;
-
-use RT::Handle;
-use RT::User;
-use RT::CurrentUser;
-
-# 
-my $LastVersion = shift || undef;
-my $LastMinorVersion = undef;
-
-#connect to the db
-$RT::Handle = new RT::Handle($RT::DatabaseType);
-$RT::Handle->Connect();
-
-#Put together a current user object so we can create a User object
-my $CurrentUser = new RT::CurrentUser();
-
-if ($LastVersion) {
-    if ( $LastVersion =~ /^2.0.(\d+)$/ ) {
-        $LastMinorVersion = $1;
-        print "Looking for new objects to add to the database"
-          . " since $LastVersion\n\n";
-    }
-    else {
-        print "This tool does not support upgrades from development releases "
-          . "or non 2.0.x versions";
-    }
-}
-else {    # this is a virgin install
-    print "Checking for existing system user...";
-    my $test_user = RT::User->new($CurrentUser);
-    $test_user->Load('RT_System');
-    if ( $test_user->id ) {
-        print "Found!\n\nYou appear to have already run insertdata.\n"
-          . "Exiting, so as not to clobber your existing data. To ERASE your\n"
-          . "RT database and start over, type 'make dropdb; make install' in\n"
-          . "the RT installation directory. If you just meant to upgrade the\n"
-          . "content of your database, rerun this program as: \n",
-          "       $0 <version>\n"
-          . "where <version> is the last RELEASED version of RT you installed\n"
-          . "for example, if you're upgrading from 2.0.4, you'd type:\n"
-          . "       $0 2.0.4\n";
-        exit(-1);
-
-    }
-    else {
-        print "not found.  This appears to be a new installation";
-    }
-
-    print "Creating system user...";
-    my $RT_System = new RT::User($CurrentUser);
-
-    my ( $val, $msg ) = $RT_System->_BootstrapCreate(
-        Name     => 'RT_System',
-        RealName => 'The RT System itself',
-        Comments =>
-'Do not delete or modify this user. It is integral to RT\'s internal database structures',
-        Privileged => '2',
-        Creator    => '1'
-    );
-
-    if ($val) {
-        print "done.\n";
-    }
-    else {
-        print "$msg\n";
-        exit(1);
-    }
-
-}
-
-#now that we bootstrapped that little bit, we can use the standard RT cli
-# helpers  to do what we need
-
-use RT::Interface::CLI qw(CleanEnv LoadConfig DBConnect
-  GetCurrentUser GetMessageContent);
-
-#Clean out all the nasties from the environment
-CleanEnv();
-
-#Load etc/config.pm and drop privs
-LoadConfig();
-
-#Connect to the database and get RT::SystemUser and RT::Nobody loaded
-DBConnect();
-
-$CurrentUser->LoadByName('RT_System');
-
-# {{{ Users
-
-my @users;
-
-unless ($LastVersion) {
-    @users = (
-        {
-            Name     => 'Nobody',
-            RealName => 'Nobody in particular',
-            Comments => 'Do not delete or modify this user. It is integral '
-              . 'to RT\'s internal data structures',
-            Privileged => '2',
-        },
-
-        {
-            Name         => 'root',
-            Gecos        => 'root',
-            RealName     => 'Enoch Root',
-            Password     => 'password',
-            EmailAddress => "root\@localhost",
-            Comments     => 'SuperUser',
-            Privileged   => '1',
-        }
-    );
-}
-
-# }}}
-
-# {{{ Groups 
-
-my @groups;
-unless ($LastVersion) {
-    @groups = (
-        {
-            Name        => 'Everyone',
-            Description => 'Pseudogroup for internal use',
-            Pseudo      => '1',
-        },
-        {
-            Name        => 'Owner',
-            Description => 'Pseudogroup for internal use',
-            Pseudo      => '1',
-        },
-        {
-            Name        => 'Requestor',
-            Description => 'Pseudogroup for internal use',
-            Pseudo      => '1',
-        },
-        {
-            Name        => 'Cc',
-            Description => 'Pseudogroup for internal use',
-            Pseudo      => '1',
-        },
-        {
-            Name        => 'AdminCc',
-            Description => 'Pseudogroup for internal use',
-            Pseudo      => '1',
-        },
-    );
-}
-
-# }}}
-
-# {{{ ACL
-my @acl;
-
-unless ($LastVersion) {
-    @acl = (    #TODO: make this actually take the serial # granted to root.
-        {
-            PrincipalId    => '1',
-            PrincipalType  => 'User',
-            RightName      => 'SuperUser',
-            RightScope     => 'System',
-            RightAppliesTo => '0'
-        },
-        {
-            PrincipalId    => '2',
-            PrincipalType  => 'User',
-            RightName      => 'SuperUser',
-            RightScope     => 'System',
-            RightAppliesTo => '0'
-        },
-
-        {
-            PrincipalId    => '3',
-            PrincipalType  => 'User',
-            RightName      => 'SuperUser',
-            RightScope     => 'System',
-            RightAppliesTo => '0'
-        }
-
-    );
-}
-
-# }}}
-
-# {{{ Queues
-
-my @queues;
-unless ($LastVersion) {
-    @queues = (
-        {
-            Name              => 'general',
-            Description       => 'The default queue',
-            CorrespondAddress => "rt\@localhost",
-            CommentAddress    => "rt-comment\@localhost"
-        }
-    );
-}
-
-# }}}
-
-# {{{ ScripActions
-
-my @ScripActions;
-
-unless ($LastVersion) {
-    @ScripActions = (
-
-        {
-            Name        => 'AutoreplyToRequestors',
-            Description =>
-'Always sends a message to the requestors independent of message sender',
-            ExecModule => 'Autoreply',
-            Argument   => 'Requestor'
-        },
-        {
-            Name        => 'NotifyRequestors',
-            Description => 'Sends a message to the requestors',
-            ExecModule  => 'Notify',
-            Argument    => 'Requestor'
-        },
-        {
-            Name        => 'NotifyOwnerAsComment',
-            Description => 'Sends mail to the owner',
-            ExecModule  => 'NotifyAsComment',
-            Argument    => 'Owner'
-        },
-        {
-            Name        => 'NotifyOwner',
-            Description => 'Sends mail to the owner',
-            ExecModule  => 'Notify',
-            Argument    => 'Owner'
-        },
-        {
-            Name        => 'NotifyAdminCcsAsComment',
-            Description => 'Sends mail to the administrative Ccs as a comment',
-            ExecModule  => 'NotifyAsComment',
-            Argument    => 'AdminCc'
-        },
-        {
-            Name        => 'NotifyAdminCcs',
-            Description => 'Sends mail to the administrative Ccs',
-            ExecModule  => 'Notify',
-            Argument    => 'AdminCc'
-        },
-
-        {
-            Name        => 'NotifyRequestorsAndCcsAsComment',
-            Description => 'Send mail to requestors and Ccs as a comment',
-            ExecModule  => 'NotifyAsComment',
-            Argument    => 'Requestor,Cc'
-        },
-
-        {
-            Name        => 'NotifyRequestorsAndCcs',
-            Description => 'Send mail to requestors and Ccs',
-            ExecModule  => 'Notify',
-            Argument    => 'Requestor,Cc'
-        },
-
-        {
-            Name        => 'NotifyAllWatchersAsComment',
-            Description => 'Send mail to all watchers',
-            ExecModule  => 'NotifyAsComment',
-            Argument    => 'All'
-        },
-        {
-            Name        => 'NotifyAllWatchers',
-            Description => 'Send mail to all watchers',
-            ExecModule  => 'Notify',
-            Argument    => 'All'
-        },
-    );
-}
-
-if ( $LastMinorVersion < 12 ) {
-    push (
-        @ScripActions,
-        {
-            Name        => 'NotifyOtherRecipientsAsComment',
-            Description => 'Sends mail to explicitly listed Ccs and Bccs',
-            ExecModule  => 'NotifyAsComment',
-            Argument    => 'OtherRecipients'
-        },
-        {
-            Name        => 'NotifyOtherRecipients',
-            Description => 'Sends mail to explicitly listed Ccs and Bccs',
-            ExecModule  => 'Notify',
-            Argument    => 'OtherRecipients'
-        },
-    );
-}
-
-# }}}
-
-# {{{ ScripConditions
-
-my @ScripConditions;
-unless ($LastVersion) {
-    @ScripConditions = (
-        {
-            Name                 => 'OnCreate',
-            Description          => 'When a ticket is created',
-            ApplicableTransTypes => 'Create',
-            ExecModule           => 'AnyTransaction',
-        },
-
-        {
-            Name                 => 'OnTransaction',
-            Description          => 'When anything happens',
-            ApplicableTransTypes => 'Any',
-            ExecModule           => 'AnyTransaction',
-        },
-        {
-
-            Name                 => 'OnCorrespond',
-            Description          => 'Whenever correspondence comes in',
-            ApplicableTransTypes => 'Correspond',
-            ExecModule           => 'AnyTransaction',
-        },
-
-        {
-
-            Name                 => 'OnComment',
-            Description          => 'Whenever comments come in',
-            ApplicableTransTypes => 'Comment',
-            ExecModule           => 'AnyTransaction'
-        },
-        {
-
-            Name                 => 'OnStatus',
-            Description          => 'Whenever a ticket\'s status changes',
-            ApplicableTransTypes => 'Status',
-            ExecModule           => 'AnyTransaction',
-
-        },
-        {
-            Name                 => 'OnResolve',
-            Description          => 'Whenever a ticket is resolved.',
-            ApplicableTransTypes => 'Status',
-            ExecModule           => 'StatusChange',
-            Argument             => 'resolved'
-
-        },
-
-    );
-}
-
-# }}}
-
-# {{{ Templates
-my @templates;
-
-unless ($LastVersion) {
-    @templates = (
-        {
-            Queue       => '0',
-            Name        => 'Autoreply',
-            Description => 'Default Autoresponse Template',
-            Content     => 'Subject: AutoReply: {$Ticket->Subject}
-
-
-Greetings,
-
-This message has been automatically generated in response to the
-creation of a trouble ticket regarding:
-       "{$Ticket->Subject()}", 
-a summary of which appears below.
-
-There is no need to reply to this message right now.  Your ticket has been
-assigned an ID of [{$rtname} #{$Ticket->id()}].
-
-Please include the string:
-
-         [{$rtname} #{$Ticket->id}]
-
-in the subject line of all future correspondence about this issue. To do so, 
-you may reply to this message.
-
-                        Thank you,
-                        {$Ticket->QueueObj->CorrespondAddress()}
-
--------------------------------------------------------------------------
-{$Transaction->Content()}
-'
-        },
-
-        {
-
-            #                  id => 2,
-            Queue       => '0',
-            Name        => 'Transaction',
-            Description => 'Default transaction template',
-            Content     => '
-
-
-{$Transaction->CreatedAsString}: Request {$Ticket->id} was acted upon.
-Transaction: {$Transaction->Description}
-       Queue: {$Ticket->QueueObj->Name}
-     Subject: {$Transaction->Subject || $Ticket->Subject || "(No subject given)"}
-       Owner: {$Ticket->OwnerObj->Name}
-  Requestors: {$Ticket->Requestors->EmailsAsString()}
-      Status: {$Ticket->Status}
- Ticket <URL: {$RT::WebURL}Ticket/Display.html?id={$Ticket->id} >
--------------------------------------------------------------------------
-{$Transaction->Content()}'
-        },
-
-        {
-
-            Queue       => '0',
-            Name        => 'AdminCorrespondence',
-            Description => 'Default admin correspondence template',
-            Content     => '
-
-
-<URL: {$RT::WebURL}Ticket/Display.html?id={$Ticket->id} >
-
-{$Transaction->Content()}'
-        },
-
-        {
-            Queue       => '0',
-            Name        => 'Correspondence',
-            Description => 'Default correspondence template',
-            Content     => '
-
-{$Transaction->Content()}'
-        },
-
-        {
-            Queue       => '0',
-            Name        => 'AdminComment',
-            Description => 'Default admin comment template',
-            Content     =>
-'Subject: [Comment] {my $s=($Transaction->Subject||$Ticket->Subject); $s =~ s/\\[Comment\\]//g; $comment =~ s/^Re//i; $s;}
-
-
-{$RT::WebURL}Ticket/Display.html?id={$Ticket->id}
-This is a comment.  It is not sent to the Requestor(s):
-
-{$Transaction->Content()}
-'
-        },
-
-        {
-            Queue       => '0',
-            Name        => 'StatusChange',
-            Description => 'Ticket status changed',
-            Content     => 'Subject: Status Changed to: {$Transaction->NewValue}
-
-
-{$RT::WebURL}Ticket/Display.html?id={$Ticket->id}
-
-{$Transaction->Content()}
-'
-        },
-
-        {
-
-            Queue       => '0',
-            Name        => 'Resolved',
-            Description => 'Ticket Resolved',
-            Content     => 'Subject: Ticket Resolved
-
-According to our records, your request has been resolved. If you have any
-further questions or concerns, please respond to this message.
-'
-        }
-    );
-}
-
-# }}}
-
-# {{{ Scrips;
-
-my @scrips;
-unless ($LastVersion) {
-     @scrips = (
-                { Queue => 0,
-                  ScripCondition => 'OnCreate',
-                  ScripAction => 'AutoreplyToRequestors',
-                  Template => 'Autoreply'
-                },
-                { Queue => 0,
-                  ScripCondition => 'OnCreate',
-                  ScripAction => 'NotifyAdminCcs',
-                  Template => 'Transaction',
-                },
-                { Queue => 0,
-                  ScripCondition => 'OnCorrespond',
-                  ScripAction => 'NotifyAllWatchers',
-                  Template => 'Correspondence',
-                },
-                { Queue => 0,
-                  ScripCondition => 'OnComment',
-                  ScripAction => 'NotifyAdminCcsAsComment',
-                  Template => 'AdminComment',
-                },
-     ) 
-}
-if ( $LastMinorVersion < 12 ) {
-    push (
-        @scrips,
-                { Queue => 0,
-                  ScripCondition => 'OnComment',
-                  ScripAction => 'NotifyOtherRecipientsAsComment',
-                  Template => 'Correspondence',
-                },
-                { Queue => 0,
-                  ScripCondition => 'OnCorrespond',
-                  ScripAction => 'NotifyOtherRecipients',
-                  Template => 'Correspondence',
-                },
-        );
-}
-# }}}
-
-print "Creating ACL...";
-use RT::ACE;
-for $item (@acl) {
-    my $new_entry = new RT::ACE($CurrentUser);
-
-    #Using an internal function. this should never be used outside of the bootstrap script
-    my $return = $new_entry->_BootstrapRight(%$item);
-    print $return. ".";
-}
-print "done.\n";
-
-print "Creating users...";
-use RT::User;
-foreach $item (@users) {
-    my $new_entry = new RT::User($CurrentUser);
-    my ( $return, $msg ) = $new_entry->Create(%$item);
-    print "(Error: $msg)" unless ($return);
-    print $return. ".";
-}
-print "done.\n";
-
-print "Creating groups...";
-use RT::Group;
-foreach $item (@groups) {
-    my $new_entry = new RT::Group($CurrentUser);
-    my $return    = $new_entry->Create(%$item);
-    print $return. ".";
-}
-print "done.\n";
-
-print "Creating queues...";
-use RT::Queue;
-for $item (@queues) {
-    my $new_entry = new RT::Queue($CurrentUser);
-    my ( $return, $msg ) = $new_entry->Create(%$item);
-    print "(Error: $msg)" unless ($return);
-    print $return. ".";
-}
-
-print "done.\n";
-print "Creating ScripActions...";
-
-use RT::ScripAction;
-for $item (@ScripActions) {
-    my $new_entry = new RT::ScripAction($CurrentUser);
-    my $return    = $new_entry->Create(%$item);
-    print $return. ".";
-}
-
-print "done.\n";
-print "Creating ScripConditions...";
-
-use RT::ScripCondition;
-for $item (@ScripConditions) {
-    my $new_entry = new RT::ScripCondition($CurrentUser);
-    my $return    = $new_entry->Create(%$item);
-    print $return. ".";
-}
-
-print "done.\n";
-
-print "Creating templates...";
-
-use RT::Template;
-for $item (@templates) {
-    my $new_entry = new RT::Template($CurrentUser);
-    my $return    = $new_entry->Create(%$item);
-    print $return. ".";
-}
-print "done.\n";
-
-print "Creating Scrips...";
-
-use RT::Scrip;
-for $item (@scrips) {
-        my $new_entry = RT::Scrip->new($CurrentUser);
-        my ($return,$msg) = $new_entry->Create(%$item);
-        print "(Error: $msg)" unless ($return);
-        print $return.".";
-
-}
-print "done.\n";
-
-$RT::Handle->Disconnect();
-
-1;
-
diff --git a/rt/tools/testdeps b/rt/tools/testdeps
deleted file mode 100644 (file)
index ddc3381..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/perl -w
-
-# $Header: /home/cvs/cvsroot/freeside/rt/tools/Attic/testdeps,v 1.1 2002-08-12 06:17:08 ivan Exp $
-
-# Copyright 2000 Jesse Vincent <jesse@fsck.com>
-# Distributed under the GNU General Public License
-# 
-
-#
-# This is just a basic script that checks to make sure that all
-# the modules needed by RT before you can install it.
-#
-
-use strict;
-
-use vars qw($mode $dbd $module @modules);
-
-$mode = shift || print_help();
-$dbd = shift || print_help();
-
-@modules = qw(
-Digest::MD5
-Storable
-DBI 1.18
-DBIx::DataSource 0.02
-DBIx::SearchBuilder 0.48
-HTML::Entities 
-MLDBM
-Net::Domain
-Net::SMTP
-Params::Validate 0.02
-HTML::Mason 1.02
-CGI::Cookie 1.20
-Apache::Cookie
-Apache::Session 1.53
-Date::Parse
-Date::Format 
-MIME::Entity 5.108
-Mail::Mailer 1.20
-Getopt::Long 2.24
-Tie::IxHash 
-Text::Wrapper 
-Text::Template
-File::Spec 0.8
-Errno
-FreezeThaw
-File::Temp 
-Log::Dispatch 1.6
-);
-
-
-if ($dbd =~ /mysql/i) {
-       push @modules, ('DBD::mysql','2.0416'); 
-}
-elsif ($dbd =~ /oracle/i) {
-       push @modules, ('DBD::Oracle','');
-}
-elsif ($dbd =~ /pg/i) {
-       push @modules, ('DBD::Pg','');
-}
-use CPAN;
-
-while ($module= shift @modules) {
-       my $version = "";
-       $version = " ". shift (@modules) . " " if ($modules[0] =~ /^([\d\.]*)$/);
-       print "Checking for $module$version";
-       eval "use $module$version" ;
-       if ($@) {
-       &resolve_dependency($module, $version) 
-       }
-       else {
-       print "...found\n";
-       }
-}
-
-sub print_help {
-print <<EOF;
-
-$0 FLAG DBTYPE
-
-
-$0 is a tool for RT that will tell you if you've got all
-the modules RT depends on properly installed.
-
-Flags: (only one flag is valid for a given run)
-
--quiet will check to see if we've got everything we need
-       and will exit with a return code of (1) if we don't.
-
--warn will tell you what isn't properly installed
-
--fix will use CPAN to magically make everything better
-
-DBTYPE is one of:
-       oracle, pg, mysql
-
-EOF
-
-exit(0);
-}
-
-sub resolve_dependency {
-       my $module = shift;
-       my $version = shift;
-        print "....$module$version not installed.";
-    if ($mode =~ /-f/) {
-       $module = "DBD::mysql::Install" if ($module =~ /DBD::mysql/);
-       
-        print "Installing with CPAN...";
-        CPAN::install($module);
-     }
-     print "\n";
-       exit(1) if ($mode =~ /-q/);
-}      
-       
diff --git a/rt/webrt/Admin/Elements/CreateQueueCalled b/rt/webrt/Admin/Elements/CreateQueueCalled
deleted file mode 100755 (executable)
index aeed6e7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<FORM METHOD=get ACTION="<% $RT::WebPath %>/Admin/Queues/Create.html">
-Create a queue called <INPUT NAME="Name" size=10><input type=submit>
-</form>
diff --git a/rt/webrt/Admin/Elements/CreateUserCalled b/rt/webrt/Admin/Elements/CreateUserCalled
deleted file mode 100755 (executable)
index 7e4bb75..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<FORM METHOD=get ACTION="<%$RT::WebPath%>/Admin/Users/Create.html">
-New user called <INPUT NAME="Name" size=10><input type=submit value="Create">
-</form>
diff --git a/rt/webrt/Admin/Elements/EditUserComments b/rt/webrt/Admin/Elements/EditUserComments
deleted file mode 100755 (executable)
index 1ac7e18..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<& /Elements/Header, Title => "Comments about $name" &>
-These comments aren't generally visible to the user:<br>
-<input type="hidden" name="id" value="<%$id%>">
-<TEXTAREA COLS=60 ROWS=15 WRAP=SOFT NAME="Comments"><% $UserObj->Comments %></TEXTAREA>
-</FORM>
-
-<%ARGS>
-$UserObj => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/GrantQueueRightsTo b/rt/webrt/Admin/Elements/GrantQueueRightsTo
deleted file mode 100755 (executable)
index 3850a18..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-<BR>
-
-% if ($msg) {
-<%$msg%>
-% } elsif ($Users) {
-<ul>
-% while (my $u = $Users->Next ) {
-<li> <%$u->Name%> (<%$u->RealName%>) <& SelectQueueRights, Name => "GrantTo".$u->id &>
-% }
-</ul>
-% }
-
-<%INIT>
-my ($msg, $Users);
-if (!$ARGS{'UserString'}) {
-$msg = "No users selected.";
- }
-else {
-    $Users = new RT::Users($session{'CurrentUser'});
-    $Users->Limit(FIELD => $ARGS{'UserField'},
-                 VALUE => $ARGS{'UserString'},
-                 OPERATOR => $ARGS{'UserOp'});
-     }
-</%INIT>
-
-<%ARGS>
-$UserField => 'Name'
-$UserOp => '='
-$UserString => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/GroupTabs b/rt/webrt/Admin/Elements/GroupTabs
deleted file mode 100755 (executable)
index 261bef1..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<& /Admin/Elements/Tabs, subtabs => $subtabs, current_tab => 'Admin/Groups/' &>
-<hr>
-<%INIT>
-my $subtabs = { 
-             Basics => { title => 'Basics',
-                         path => "Admin/Groups/Modify.html?id=". $GroupObj->id
-                       }
-       };
-
-unless ($GroupObj->Pseudo) {
-$subtabs->{'Members'} = { title => 'Members',
-                         path => "Admin/Groups/Members.html?id=".$GroupObj->id };
-}
-</%INIT>
-
-<%ARGS>
-$GroupObj => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/Header b/rt/webrt/Admin/Elements/Header
deleted file mode 100755 (executable)
index 95acdac..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<& /Elements/Header, Title => $Title &>
-
-<%ARGS>
-$Title => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/ListGlobalKeywordSelects b/rt/webrt/Admin/Elements/ListGlobalKeywordSelects
deleted file mode 100644 (file)
index b24d689..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-% while (my $KeywordSelect = $KeywordSelects->Next()) {
-
-<%$KeywordSelect->Name %>:
-<% $KeywordSelect->Single ? 'Single' : 'Multiple' %>
-children of
-<% $KeywordSelect->KeywordObj->Path %>
-% if ($KeywordSelect->Depth) {
-         up to <%$KeywordSelect->Depth%> levels deep
-% }
-<BR>
-%} 
-<%INIT>
-my $KeywordSelects = RT::KeywordSelects->new($session{'CurrentUser'});
-$KeywordSelects->LimitToGlobals();
-</%INIT>
diff --git a/rt/webrt/Admin/Elements/ListGlobalScrips b/rt/webrt/Admin/Elements/ListGlobalScrips
deleted file mode 100755 (executable)
index 2f044bf..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-%  while (my $scrip = $Scrips->Next ) {
-<% $scrip->ConditionObj->Name %> 
-<% $scrip->ActionObj->Name %> 
-with template <% $scrip->TemplateObj->Name %>
-<BR>
-%   }
-<%init>
-my $Scrips = new RT::Scrips ($session{'CurrentUser'});
-$Scrips->LimitToGlobal();
-</%INIT>
diff --git a/rt/webrt/Admin/Elements/ModifyKeyword b/rt/webrt/Admin/Elements/ModifyKeyword
deleted file mode 100644 (file)
index 4b01c36..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-<FORM METHOD="get" ACTION="<%$RT::WebPath%>/Admin/Keywords/Modify.html">
-[<%$title |n %>]<BR>
-
-<INPUT TYPE="hidden" NAME="id" VALUE="<% $id %>">
-Keyword <INPUT NAME="Name" VALUE="<% $Keyword->Name %>"><BR>
-
-Parent <SELECT NAME="Parent">
-             <OPTION VALUE=""<% defined($Keyword->Parent) ? '' : ' SELECTED' %>>-</OPTION>
-%while ( $parent = $parents->Next ) {
-             <OPTION VALUE="<% $parent->id %>"<% defined($Keyword->Parent) && $parent->id == $Keyword->Parent ? ' SELECTED' : '' %>><% $parent->Name %></OPTION>
-%}
-</SELECT>
-
-
-Kids <FONT SIZE="-2">(separate by
-<INPUT TYPE="radio" NAME="delim" VALUE="n"<% $delim eq 'n' ? ' CHECKED' : '' %>>
-line or
-<INPUT TYPE="radio" NAME="delim" VALUE="s"<% $delim eq 's' ? ' CHECKED' : '' %>>
-whitespace)</FONT><BR>
-
-<TEXTAREA NAME="Kids" ROWS=4><% $kidstring %></TEXTAREA>
-<BR>
-
-<& /Elements/Submit, Label => $submit &>
-</FORM>
-
-<%INIT>
-
-my $Keyword = new RT::Keyword($session{CurrentUser});
-my ($title, $submit, %kids, $kid);
-
-if ( $Create ) {
-    $title = "Create a new Keyword";
-    $submit = "Create";
-    $id = "new";
-    %kids = ();
-    $Parent = ''; #silence 
-} elsif ( $id eq 'new' ) {
-    $id = $Keyword->Create( Name => $Name, Parent => $Parent )
-      or Abort("can't create keyword Name=>$Name, Parent=>$Parent");
-} else {
-    $Keyword->Load($id) || Abort("Can't load keyword id $id");
-    #foreach my $field ( grep eval "defined(\$$_)", qw( Name Parent )) {
-    #  eval "\$Keyword->Set(\$field=>\$$field); #sigh
-    #}
-    $Keyword->SetName($Name) if defined($Name);
-    $Keyword->SetParent($Parent) if defined($Parent);
-}
-
-$title = "Modify the Keyword <B>". $Keyword->Name. "</B>";
-$submit = "Modify";
-
-my $kids = new RT::Keywords($session{CurrentUser});
-$kids->Limit( FIELD => 'Parent', VALUE => $id, OPERATOR => '=' );
-$kids{$kid->Name} = $kid while $kid = $kids->Next;
-
-if ( defined($Kids) ) {
-    my %newkids;
-    if ( $delim eq 'n' ) {
-       %newkids = map { $_=>1 } split(/\n/, $Kids);
-    } elsif ( $delim eq 's' ) {
-       %newkids = map { $_=>1 } split(' ', $Kids);
-    } else {
-       Abort("'$delim' isn't a valid keyword delimiter.");
-    }
-    foreach ( grep { ! defined($newkids{$_}) } keys %kids ) {
-       $kids{$_}->Delete;
-       delete $kids{$_};
-    }
-    foreach ( grep { ! defined($kids{$_}) } keys %newkids ) {
-       $kids{$_} = new RT::Keyword($session{CurrentUser});
-       $kids{$_}->Create( Name => $_, Parent => $id )
-         or Abort("can't create keyword Name=>$_, Parent=>$id");
-    }
-
-}
-
-
-my $parent;
-my $parents = new RT::Keywords($session{CurrentUser});
-$parents->UnLimit;
-
-$delim = ( grep /\s/, keys %kids ) ? 'n' : 's';
-my $kidstring = join("\n", keys %kids);
-
-</%INIT>
-
-<%ARGS>
-$id => undef
-$Create => undef
-$Name => undef
-$Parent => undef
-$Kids => undef
-$delim => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/ModifyKeywordSelect b/rt/webrt/Admin/Elements/ModifyKeywordSelect
deleted file mode 100644 (file)
index 470e629..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-  <FORM NAME="ModifyKeywordSelect" METHOD=POST ACTION="<%$RT::WebPath%>/Admin/KeywordSelects/Modify.html">
-
-    [<%$title |n %>]
-    <BR>
-      
-      <INPUT TYPE="hidden" NAME="id" VALUE="<% $id %>">
-       Keyword 
-       <SELECT NAME="Parent">
-         
-%while ( $parent = $parents->Next ) {
-         
-         <OPTION VALUE="<% $parent->id %>" <% defined($KeywordSelect->Parent) && $parent->id == $KeywordSelect->Parent ? ' SELECTED' : '' %>><% $parent->Name %></OPTION>
-         
-% }
-         
-       </SELECT>
-       <BR>
-         Object 
-         <SELECT NAME="ObjectType">
-           <OPTION SELECTED>Ticket</OPTION>
-         </SELECT>
-         <BR>
-           
-<SCRIPT>
-function addOption(text, value, defaultselected, selected) {
-  var option = new Option(text, value, defaultselected, selected )
-  var length = document.ModifyKeywordSelect.ObjectValue.length;
-  document.ModifyKeywordSelect.ObjectValue.options[length] = option
-}
-function ChangeObjectValue(what) {
-  Value = what.options[what.selectedIndex].value
-  if ( Value == "(none)" ) {
-    document.ModifyKeywordSelect.ObjectValue.options.length = 0
-    addOption("(n/a)", "", false, false)
-  }
-  if ( Value == "Queue" ) {
-    document.ModifyKeywordSelect.ObjectValue.options.length = 0
-%foreach $queue ( keys %queues ) {
-    addOption("<% $queues{$queue} %>", "<% $queue %>", false, <% $queue == $KeywordSelect->ObjectValue ? 'true' : 'false' %> )
-%}
-  }
-}
-</SCRIPT>
-           
-           Limit to <SELECT NAME="ObjectField" onChange="ChangeObjectValue(this)">
-             <OPTION VALUE="" <% $KeywordSelect->ObjectField ? '' : ' SELECTED' %>>(none)</OPTION>
-             <OPTION VALUE="Queue" <% $KeywordSelect->ObjectField eq 'Queue' ? ' SELECTED' : '' %>>Queue</OPTION>
-           </SELECT> 
-           <SELECT NAME="ObjectValue">
-             <OPTION VALUE="<% $KeywordSelect->ObjectValue %>">
-               <% $KeywordSelect->ObjectField ? $queues{$KeywordSelect->ObjectValue} : "(n/a)" %></OPTION>
-           </SELECT><BR>
-             <INPUT TYPE="hidden" NAME="SingleMagic" VALUE="1">
-               <INPUT TYPE="checkbox" NAME="Single" VALUE="1" <% $KeywordSelect->Single ? ' CHECKED' : '' %>>Allow single selection only<BR>
-                   Limit to <INPUT TYPE="text" NAME="Generations" SIZE="2" VALUE="<% $KeywordSelect->Generations %>"> generations (0 = no limit)<BR>
-                       <& /Elements/Submit, Label => $submit &>
-
-</FORM>
-
-<%INIT>
-
-
-my $KeywordSelect = new RT::KeywordSelect($session{CurrentUser});
-  
-my($title, $submit);
-  
-if ( $Create ) {
-      $title = "Create a new KeywordSelect";
-      $submit = "Create";
-      $id = "new";
-} else {
-    if  ( $id eq 'new' ) {
-       $id = $KeywordSelect->Create (
-                                     Parent      => $Parent,
-                                     ObjectType  => $ObjectType,
-                                     ObjectField => $ObjectField,
-                                     ObjectValue => $ObjectValue,
-                                     Single      => $Single,
-                                     Generations => $Generations,
-                                    ) or Abort "can't create KeywordSelect";
-    } else {
-       $KeywordSelect->Load($id) || Abort("Can't load keyword id $id");
-       #false laziness
-       $KeywordSelect->SetParent($Parent) if defined($Parent);
-       $KeywordSelect->SetObjectType($ObjectType) if defined($ObjectType);
-       $KeywordSelect->SetObjectField($ObjectField) if defined($ObjectField);
-       $KeywordSelect->SetObjectValue($ObjectValue) if defined($ObjectValue);
-       $KeywordSelect->SetSingle($Single) if defined($SingleMagic);
-       $KeywordSelect->SetGenerations($Generations) if defined($Generations);
-    }
-    $title = "Modify the KeywordSelect <B>". $KeywordSelect->KeywordObj->Name. "</B>";
-    $submit = "Modify";
-    
-}
-  
-  my $parents = new RT::Keywords($session{CurrentUser});
-  $parents->UnLimit;
-  my $parent;
-
-my $queues = new RT::Queues($session{CurrentUser});
-$queues->UnLimit;
-
-my %queues;
-my $queue;
-$queues{$queue->id} = $queue->Name while $queue = $queues->Next;
-
-</%INIT>
-
-<%ARGS>
-$id => undef
-$Create => undef
-$Parent => undef
-$ObjectType => undef
-$ObjectField => undef
-$ObjectValue => undef
-$Single => undef
-$SingleMagic => undef
-$Generations => undef
-</%ARGS>
-
diff --git a/rt/webrt/Admin/Elements/ModifyQueue b/rt/webrt/Admin/Elements/ModifyQueue
deleted file mode 100755 (executable)
index a641c81..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-
-<& /Elements/TitleBoxStart, title => 'Editing Configuration for queue '.$QueueObj->Id &>
-
-<FORM ACTION="<%$RT::WebPath%>/Admin/Queues/Modify.html" METHOD=POST>
-<INPUT TYPE=HIDDEN NAME=id VALUE="<%$QueueObj->Id%>">
-<TABLE>
-<TR><TD ALIGN=RIGHT>
-Queue Name: 
-</TD>
-<TD><INPUT name="Name" value="<%$QueueObj->Name%>"></TD>
-</TR><TR>
-<TD ALIGN=RIGHT>
-Description:</TD><TD COLSPAN=3><INPUT name="Description" value="<%$QueueObj->Description%>" size=60></TD></TR>
-<TR>
-<TD ALIGN=RIGHT>
-Correspondence Address:
-</TD><TD>
-<INPUT name="CorrespondAddress" value="<%$QueueObj->CorrespondAddress%>">
-</TD>
-<TD ALIGN=RIGHT>
-
-Comment Address: </TD><TD>
-<INPUT NAME="CommentAddress" value="<%$QueueObj->CommentAddress%>">
-</TD>
-</TR><TR>
-
-<TD ALIGN=RIGHT>
-Priority starts at: 
-</TD><TD><INPUT NAME="InitialPriority" value="<%$QueueObj->InitialPriority %>">
-</TD>
-<TD ALIGN=RIGHT>
-Over time, priority moves toward:
-</TD><TD><INPUT NAME="FinalPriority" value="<%$QueueObj->FinalPriority %>">
-</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT>
-Requests should be due in:
-</TD><TD>
-<INPUT NAME="DefaultDueIn" VALUE="<%$QueueObj->DefaultDueIn%>"> days.
-</TD>
-</TR>
-</TABLE>
-<& /Elements/Submit &>
-</form>
-<& /Elements/TitleBoxEnd &>
-
-<%INIT>
-
-</%INIT>
-
-<%ARGS>
-
-
-$QueueObj => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/ModifyTemplate b/rt/webrt/Admin/Elements/ModifyTemplate
deleted file mode 100755 (executable)
index 6e4f8a3..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-
-<& /Elements/TitleBoxStart, title => 'Editing Configuration for user '.$UserObj->Name &>
-
-<FORM ACTION="<%$RT::WebPath%>/Admin/ModifyUser.html" METHOD=POST>
-<INPUT TYPE=HIDDEN NAME=id VALUE="<%$UserObj->Id%>">
-
-Name: <input name="Name" value="<%$UserObj->Name%>">
-<BR>
-New Password: <input type=password name="Pass1"><BR>
-Retype Password: <input type=password name="Pass2"><BR>
-
-Comments: <TEXTAREA name="Comments" COLS=20 ROWS=5>
-<%$UserObj->Comments%></TEXTAREA>
-
-<BR>
-Signature: <TEXTAREA COLS=80 ROWS=5 name="Signature">
-<%$UserObj->Signature%>"></TEXTAREA>
-<BR>
-EmailAddress: <input name="EmailAddress" value="<%$UserObj->EmailAddress%>">
-<BR>
-FreeformContactInfo: <input name="FreeformContactInfo" value="<%$UserObj->FreeformContactInfo%>">
-<BR>
-Organization: <input name="Organization" value="<%$UserObj->Organization%>">
-<BR>
-RealName: <input name="RealName" value="<%$UserObj->RealName%>">
-<BR>
-NickName: <input name="NickName" value="<%$UserObj->NickName%>">
-<BR>
-Lang: <input name="Lang" value="<%$UserObj->Lang%>">
-<BR>
-EmailEncoding: <input name="EmailEncoding" value="<%$UserObj->EmailEncoding%>">
-<BR>
-WebEncoding: <input name="WebEncoding" value="<%$UserObj->WebEncoding%>">
-<BR>
-ExternalContactInfoId: <input name="ExternalContactInfoId" value="<%$UserObj->ExternalContactInfoId%>">
-<BR>
-ContactInfoSystem: <input name="ContactInfoSystem" value="<%$UserObj->ContactInfoSystem%>">
-<BR>
-Gecos: <input name="Gecos" value="<%$UserObj->Gecos%>">
-<BR>
-ExternalAuthId: <input name="ExternalAuthId" value="<%$UserObj->ExternalAuthId%>">
-<BR>
-AuthSystem: <input name="AuthSystem" value="<%$UserObj->AuthSystem%>">
-<BR>
-HomePhone: <input name="HomePhone" value="<%$UserObj->HomePhone%>">
-<BR>
-WorkPhone: <input name="WorkPhone" value="<%$UserObj->WorkPhone%>">
-<BR>
-MobilePhone: <input name="MobilePhone" value="<%$UserObj->MobilePhone%>">
-<BR>
-PagerPhone: <input name="PagerPhone" value="<%$UserObj->PagerPhone%>">
-<BR>
-Address1: <input name="Address1" value="<%$UserObj->Address1%>">
-<BR>
-Address2: <input name="Address2" value="<%$UserObj->Address2%>">
-<BR>
-City: <input name="City" value="<%$UserObj->City%>">
-<BR>
-State: <input name="State" value="<%$UserObj->State%>">
-<BR>
-Zip: <input name="Zip" value="<%$UserObj->Zip%>">
-<BR>
-Country: <input name="Country" value="<%$UserObj->Country%>">
-<BR>
-
-<input type=submit>
-</form>
-<& /Elements/TitleBoxEnd &>
-
-<%INIT>
-
-</%INIT>
-
-<%ARGS>
-
-
-$UserObj => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/ModifyUser b/rt/webrt/Admin/Elements/ModifyUser
deleted file mode 100755 (executable)
index 53aa027..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-
-<& /Elements/TitleBoxStart, title => 'Editing Configuration for user '.$UserObj->Name &>
-
-<FORM ACTION="<%$RT::WebPath%>/Admin/Users/Modify.html" METHOD=POST>
-<INPUT TYPE=HIDDEN NAME=id VALUE="<%$UserObj->Id%>">
-
-Name: <input name="Name" value="<%$UserObj->Name%>">
-<BR>
-New Password: <input type=password name="Pass1"><BR>
-Retype Password: <input type=password name="Pass2"><BR>
-
-Comments: <TEXTAREA name="Comments" COLS=80 ROWS=5 WRAP=VIRTUAL>
-<%$UserObj->Comments%></TEXTAREA>
-
-<BR>
-Signature: <TEXTAREA COLS=80 ROWS=5 name="Signature" WRAP=HARD>
-<%$UserObj->Signature%></TEXTAREA>
-<BR>
-EmailAddress: <input name="EmailAddress" value="<%$UserObj->EmailAddress%>">
-<BR>
-FreeformContactInfo: <input name="FreeformContactInfo" value="<%$UserObj->FreeformContactInfo%>">
-<BR>
-Organization: <input name="Organization" value="<%$UserObj->Organization%>">
-<BR>
-RealName: <input name="RealName" value="<%$UserObj->RealName%>">
-<BR>
-NickName: <input name="NickName" value="<%$UserObj->NickName%>">
-<BR>
-Lang: <input name="Lang" value="<%$UserObj->Lang%>">
-<BR>
-EmailEncoding: <input name="EmailEncoding" value="<%$UserObj->EmailEncoding%>">
-<BR>
-WebEncoding: <input name="WebEncoding" value="<%$UserObj->WebEncoding%>">
-<BR>
-ExternalContactInfoId: <input name="ExternalContactInfoId" value="<%$UserObj->ExternalContactInfoId%>">
-<BR>
-ContactInfoSystem: <input name="ContactInfoSystem" value="<%$UserObj->ContactInfoSystem%>">
-<BR>
-Gecos: <input name="Gecos" value="<%$UserObj->Gecos%>">
-<BR>
-ExternalAuthId: <input name="ExternalAuthId" value="<%$UserObj->ExternalAuthId%>">
-<BR>
-AuthSystem: <input name="AuthSystem" value="<%$UserObj->AuthSystem%>">
-<BR>
-HomePhone: <input name="HomePhone" value="<%$UserObj->HomePhone%>">
-<BR>
-WorkPhone: <input name="WorkPhone" value="<%$UserObj->WorkPhone%>">
-<BR>
-MobilePhone: <input name="MobilePhone" value="<%$UserObj->MobilePhone%>">
-<BR>
-PagerPhone: <input name="PagerPhone" value="<%$UserObj->PagerPhone%>">
-<BR>
-Address1: <input name="Address1" value="<%$UserObj->Address1%>">
-<BR>
-Address2: <input name="Address2" value="<%$UserObj->Address2%>">
-<BR>
-City: <input name="City" value="<%$UserObj->City%>">
-<BR>
-State: <input name="State" value="<%$UserObj->State%>">
-<BR>
-Zip: <input name="Zip" value="<%$UserObj->Zip%>">
-<BR>
-Country: <input name="Country" value="<%$UserObj->Country%>">
-<BR>
-<& /Elements/Submit &>
-</form>
-<& /Elements/TitleBoxEnd &>
-
-<%INIT>
-
-</%INIT>
-
-<%ARGS>
-
-
-$UserObj => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/QueueRightsForUser b/rt/webrt/Admin/Elements/QueueRightsForUser
deleted file mode 100644 (file)
index e62a124..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<UL>
-%while(my $ACE = $ACL->Next) {
-
-<LI><checkbox name="delete_ace_<%$ACE->id%>"> <%$ACE->RightName%> (<%$ACE->UserObj->RealName%>)
-
-%}
-</UL>
-
-<%INIT>
-my $ACL = new RT::ACL($session{'CurrentUser'});
-$ACL->LimitToQueue($QueueObj->id);
-$ACL->LimitPrincipalToUser($PrincipalId);
-</%INIT>
-<%ARGS>
-$PrincipalId => undef
-$QueueObj => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/QueueTabs b/rt/webrt/Admin/Elements/QueueTabs
deleted file mode 100755 (executable)
index b7da7e0..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<& /Admin/Elements/Tabs, subtabs => $subtabs, current_tab => 'Admin/Queues/' &>
-<hr>
-<%INIT>
-  my $subtabs = {
-                A => { title => 'Basics',
-                       path => "Admin/Queues/Modify.html?id=".$id,
-                          },
-                B => { title => 'Watchers',
-                       path => "Admin/Queues/People.html?id=".$id,
-                     },
-
-                C => { title => 'Scrips',
-                            path => "Admin/Queues/Scrips.html?id=".$id,
-                          },
-                D => { title => 'Templates',
-                               path => "Admin/Queues/Templates.html?id=".$id,
-                             },
-                E => { title => 'Keyword Selections',
-                               path => "Admin/Queues/Keywords.html?id=".$id,
-                       },
-                F => { title => 'Group Rights',
-                         path => "Admin/Queues/GroupRights.html?id=".$id,
-                       },      
-                G => { title => 'User Rights',
-                         path => "Admin/Queues/UserRights.html?id=".$id,
-                       },
-
-
-                
-};
-</%INIT>
-
-  
-<%ARGS>
-$id => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/SelectKeywordSelect b/rt/webrt/Admin/Elements/SelectKeywordSelect
deleted file mode 100644 (file)
index f5a8d77..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<input size=10 name="<%$NamePrefix%>-Name" value="<% $KeywordSelect->Name %>">:
-<& /Admin/Elements/SelectSingleOrMultiple, 
-         Name => $NamePrefix.'-Single',
-         Default => $KeywordSelect->Single &>
-         
-children of
-<& /Elements/SelectKeyword, Root => '0', 
-                           Name => $NamePrefix.'-Keyword',
-                            Default => $KeywordSelect->KeywordObj->Id &>
-         up to <input name="<%$NamePrefix%>-Depth" size=2 value="<%$KeywordSelect->Depth%>"> levels deep.
-<%INIT>
-unless ($NamePrefix) {
-       $NamePrefix = $KeywordSelect->Id;
-}
-$NamePrefix = "KeywordSelect-$NamePrefix";
-
-</%INIT>
-
-<%ARGS>
-$KeywordSelect => undef
-$NamePrefix => undef
-</%ARGS>
\ No newline at end of file
diff --git a/rt/webrt/Admin/Elements/SelectModifyGroup b/rt/webrt/Admin/Elements/SelectModifyGroup
deleted file mode 100644 (file)
index 45d437f..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-%while ( $Group = $Groups->Next) {
-<A HREF="Modify.html?id=<%$Group->id%>"><%$Group->id%>: <%$Group->Name%></a><BR>
-%}
-<%INIT>
-my ($Group);
-my $Groups = new RT::Groups($session{'CurrentUser'});
-$Groups->UnLimit;
-</%INIT>
-<%ARGS>
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/SelectModifyKeyword b/rt/webrt/Admin/Elements/SelectModifyKeyword
deleted file mode 100644 (file)
index 6af2232..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-%while ( $keyword = $keywords->Next ) {
-<A HREF="/Admin/Keywords/Modify.html?id=<%$keyword->id%>"><%$keyword->id%>: <%$keyword->Name%></a><BR>
-%}
-
-<%INIT>
-
-use RT::Keywords;
-
-my $keyword;
-my $keywords = new RT::Keywords $session{CurrentUser};
-$keywords->UnLimit;
-</%INIT>
-
diff --git a/rt/webrt/Admin/Elements/SelectModifyKeywordSelect b/rt/webrt/Admin/Elements/SelectModifyKeywordSelect
deleted file mode 100644 (file)
index c91eb6c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-%while ( $keywordselect = $keywordselects->Next ) {
-<A HREF="/Admin/KeywordSelects/Modify.html?id=<%$keywordselect->id%>"><%$keywordselect->id%>: ( <%$keywordselect->Parent%>: <%$keywordselect->KeywordObj->Name%> )</a><BR>
-%}
-
-<%INIT>
-
-use RT::KeywordSelects;
-
-my $keywordselect;
-my $keywordselects = new RT::KeywordSelects $session{CurrentUser};
-$keywordselects->UnLimit;
-</%INIT>
-
diff --git a/rt/webrt/Admin/Elements/SelectModifyQueue b/rt/webrt/Admin/Elements/SelectModifyQueue
deleted file mode 100755 (executable)
index 1c6cd7d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-%while ( $queue = $queues->Next) {
-<A HREF="Modify.html?id=<%$queue->id%>"><%$queue->id%>: <%$queue->Name%></a><BR>
-%}
-<%INIT>
-my ($queue);
-my $queues = new RT::Queues($session{'CurrentUser'});
-$queues->UnLimit;
-</%INIT>
-<%ARGS>
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/SelectModifyUser b/rt/webrt/Admin/Elements/SelectModifyUser
deleted file mode 100755 (executable)
index da49212..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-%while ( $user = $users->Next) {
-<A HREF="Modify.html?id=<%$user->id%>"><%$user->id%>: <%$user->Name%></a><BR>
-%}
-<%INIT>
-my ($user);
-my $users = new RT::Users($session{'CurrentUser'});
-$users->Limit(FIELD => 'id',
-              VALUE => $RT::SystemUser->id,
-              OPERATOR => '!=' );
-
-if (defined $IdLike) {
-$users->Limit(FIELD => 'Name',
-              VALUE => $IdLike,
-              OPERATOR => 'LIKE' );
-}
-if (defined $EmailLike) {
-$users->Limit(FIELD => 'EmailAddress',
-              VALUE => $EmailLike,
-              OPERATOR => 'LIKE');
-
-}
-</%INIT>
-<%ARGS>
-$IdLike => undef
-$EmailLike => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/SelectQueueRights b/rt/webrt/Admin/Elements/SelectQueueRights
deleted file mode 100755 (executable)
index 6861d40..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Admin/Elements/Attic/SelectQueueRights,v 1.1 2002-08-12 06:17:08 ivan Exp $
-
-<SELECT NAME ="<%$Name%>">
-<OPTION VALUE="">-</OPTION>
-%foreach $right (@rights) {
-<OPTION VALUE="<%$right%>" <%($Default eq $right) && 'SELECTED'%>><%$right%></OPTION>
-% }
-</SELECT>
-<%ONCE>
-
-use RT::ACE;
-my $ACE = new RT::ACE($session{'CurrentUser'});
-my %QueueRights = $ACE->QueueRights;
-my %TicketRights = $ACE->TicketRights;
-
-my ($key, $right, @rights);
-
-foreach $key (sort keys %QueueRights) {
-push (@rights, $QueueRights{$key} . " ($key)");
-}
-foreach $key (sort keys %TicketRights) {
-push (@rights, $TicketRights{$key} . " ($key)");
-}
-</%ONCE>
-<%ARGS>
-$Name => undef
-$Default => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/SelectRights b/rt/webrt/Admin/Elements/SelectRights
deleted file mode 100644 (file)
index 0ac7749..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<INPUT TYPE=HIDDEN NAME="CheckACL"  VALUE="<%$ACLDesc%>">
-     <TABLE BORDER=0>
-<TR>
-<TD valign=top>
-<h3>New rights</h3> 
-<SELECT SIZE=5  MULTIPLE  NAME="GrantACE-<%$ACLDesc%>">
-% foreach $right (sort keys %Rights) {
-      <OPTION VALUE="<%$right%>"  
-       ><%$right%></OPTION>
-% }
-<OPTION VALUE="" SELECTED>(no value)</OPTION>
-</SELECT>
-</TD>
-<TD valign=top> 
-<h3>Current rights</h3>
-<i>(Check box to revoke right)</i> <BR>
-% while (my $right = $ACLObj->Next()) {
-% if ($right->RightName) {
-<input type=checkbox value="<%$right->Id%>" name="RevokeACE"> <%$right->RightName%><br>
-% }
-%  }
-</TD>
-</TR>
-</TABLE>
-<%INIT>
-    my ($right, $ACLDesc, $AppliesTo, %Rights);
-   
-       
-    my $ACLObj = new RT::ACL($session{'CurrentUser'});
-    my $ACE = new RT::ACE($session{'CurrentUser'});
-
-    if ($Scope eq 'Queue') { 
-        $AppliesTo = $QueueObj->Id;
-        $ACLObj->LimitToQueue($AppliesTo);
-        %Rights = $ACE->QueueRights();
-    } 
-    elsif ($Scope eq 'System') {
-        $AppliesTo = 0;
-        $ACLObj->LimitToSystem();
-        %Rights =  ( $ACE->SystemRights , $ACE->QueueRights());
-    }
-
-    if ($PrincipalType eq 'Group') {
-        $ACLObj->LimitPrincipalToGroup($PrincipalObj->Id);
-    } 
-    elsif ($PrincipalType eq 'User') {
-        $ACLObj->LimitPrincipalToUser($PrincipalObj->Id);
-    } 
-    
-    $ACLDesc = "$PrincipalType-".$PrincipalObj->Id."-$Scope-$AppliesTo";
-</%INIT>
-    
-<%ARGS>
-$PrincipalType => undef
-$PrincipalObj => undef
-$Scope => undef
-$QueueObj => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/SelectScrip b/rt/webrt/Admin/Elements/SelectScrip
deleted file mode 100755 (executable)
index 4ae15d8..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-<SELECT NAME=<%$Name%>>
-<OPTION VALUE="" 
-<% $Default eq undef && 'SELECTED' %>
->-</OPTION>
-%while  (my $Scrip = $Scrips->Next) {
-<OPTION VALUE=<%$Scrip->Id%>
-<% $Scrip->Id == $Default && 'SELECTED' %>
-><%$Scrip->Name%>
-</OPTION>
-%}
-</SELECT>
-
-<%INIT>
-my $Scrips = RT::Scrips->new($session{'CurrentUser'});
-$Scrips->UnLimit;
-
-
-
-</%INIT>
-<%ARGS>
-
-$Default => undef
-$Name => 'Scrip'
-
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/SelectScripAction b/rt/webrt/Admin/Elements/SelectScripAction
deleted file mode 100644 (file)
index 08a1734..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-<SELECT NAME=<%$Name%>>
-<OPTION VALUE="" 
-<% $Default eq undef && 'SELECTED' %>
->-</OPTION>
-%while  (my $ScripAction = $ScripActions->Next) {
-<OPTION VALUE=<%$ScripAction->Id%>
-<% $ScripAction->Id == $Default && 'SELECTED' %>
-><%$ScripAction->Name%>
-</OPTION>
-%}
-</SELECT>
-
-<%INIT>
-my $ScripActions = RT::ScripActions->new($session{'CurrentUser'});
-$ScripActions->UnLimit;
-
-
-
-</%INIT>
-<%ARGS>
-
-$Default => undef
-$Name => 'ScripAction'
-
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/SelectScripCondition b/rt/webrt/Admin/Elements/SelectScripCondition
deleted file mode 100644 (file)
index 434f0c4..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-<SELECT NAME=<%$Name%>>
-<OPTION VALUE="" 
-<% $Default eq undef && 'SELECTED' %>
->-</OPTION>
-%while  (my $ScripCondition = $ScripConditions->Next) {
-<OPTION VALUE=<%$ScripCondition->Id%>
-<% $ScripCondition->Id == $Default && 'SELECTED' %>
-><%$ScripCondition->Name%>
-</OPTION>
-%}
-</SELECT>
-
-<%INIT>
-my $ScripConditions = RT::ScripConditions->new($session{'CurrentUser'});
-$ScripConditions->UnLimit;
-
-
-
-</%INIT>
-<%ARGS>
-
-$Default => undef
-$Name => 'ScripCondition'
-
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/SelectSingleOrMultiple b/rt/webrt/Admin/Elements/SelectSingleOrMultiple
deleted file mode 100644 (file)
index 307b021..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-  <select name="<%$Name%>">
-    <option value="1" <%$SingleDefault%>>Single</option>
-    <option value="0" <%$MultipleDefault%>>Multiple</option>
-  </select>    
-
-
-<%INIT>
-my ($SingleDefault, $MultipleDefault);
-if ($Default == 1) {
-    $SingleDefault = "SELECTED";
-}
-elsif ($Default == 0 ) {
-    $MultipleDefault = "SELECTED";
-}
-
-</%INIT>
-<%ARGS>
-$Name => 'Single'
-$Default => 1
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/SelectTemplate b/rt/webrt/Admin/Elements/SelectTemplate
deleted file mode 100755 (executable)
index 76550dc..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<SELECT NAME=<%$Name%>>
-<OPTION VALUE="" 
-<% $Default eq 'none' && 'SELECTED' %>
->-</OPTION>
-%while  (my $Template = $PrimaryTemplates->Next) {
-<OPTION VALUE=<%$Template->Id%>
-<% ($Template->Id == $Default) && 'SELECTED' %>
-><%$Template->Name%>
-</OPTION>
-%}
-%while  (my $Template = $OtherTemplates->Next) {
-<OPTION VALUE=<%$Template->Id%>
-<% ($Template->Id == $Default)  && 'SELECTED'%>
->Global template: <%$Template->Name%>
-</OPTION>
-%}
-</SELECT>
-
-<%INIT>
-
-
-my $PrimaryTemplates = RT::Templates->new($session{'CurrentUser'});
-if ($DefaultQueue != 0) {
-$PrimaryTemplates->LimitToQueue($DefaultQueue);
-}
-
-my $OtherTemplates = RT::Templates->new($session{'CurrentUser'});
-$OtherTemplates->LimitToGlobal($DefaultQueue);
-
-</%INIT>
-<%ARGS>
-
-$Default => 'none'
-$DefaultQueue => undef
-$Name => 'Template'
-
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/SelectUsers b/rt/webrt/Admin/Elements/SelectUsers
deleted file mode 100644 (file)
index af51c60..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<SELECT MULTIPLE NAME="<%$Name%>"  SIZE=10>
-%while (my $user = $users->Next) {
-<OPTION VALUE="<%$user->id%>"><%$user->Name%>
-%}
-</SELECT>
-
-<%INIT>
-my $users = new RT::Users($session{'CurrentUser'});
-
-$users->Limit(FIELD => 'id', VALUE => $RT::SystemUser->id, OPERATOR => '!=' );
-$users->Limit(FIELD => 'id', VALUE => $RT::Nobody->id, OPERATOR => '!=' );
-$users->LimitToPrivileged();
-
-</%INIT>
-<%ARGS>
-$Name => 'Users'
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/SystemTabs b/rt/webrt/Admin/Elements/SystemTabs
deleted file mode 100755 (executable)
index f8b2312..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<& /Admin/Elements/Tabs, subtabs => $subtabs, current_tab => 'Admin/Global/', current_subtab => $current_subtab &>
-<hr>
-<%INIT>
-  my $subtabs = {
-               
-              A => { title => 'Scrips',
-                          path => 'Admin/Global/Scrips.html',
-                        },
-              Ba => { title => 'Keyword Selections',           
-                               path => 'Admin/Global/Keywords.html',
-                     },
-
-              B => { title => 'Templates',
-                       path => 'Admin/Global/Templates.html',
-                     },
-               C => { title => 'Group Rights',
-                               path => 'Admin/Global/GroupRights.html',
-                     },
-               D => { title => 'User Rights',
-                               path => 'Admin/Global/UserRights.html',
-                     }
-
-
-};
-</%INIT>
-
-  
-<%ARGS>
-$id => undef
-$current_subtab => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/Tabs b/rt/webrt/Admin/Elements/Tabs
deleted file mode 100755 (executable)
index ee6d82b..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<& /Elements/Tabs, tabs => $tabs, subtabs => $subtabs, current_toptab => 'Admin/', current_tab => $current_tab, current_subtab => $current_subtab&>
-
-<hr>
-  
-<%INIT>
-  my $tabs = { Users => { title => 'Users',
-                         path => 'Admin/Users/',
-                       },
-              Groups => { title => 'Groups',
-                          path => 'Admin/Groups/',
-                        },
-              Queues => { title => 'Queues',
-                          path => 'Admin/Queues/',
-                        },
-              System => { 'title' => 'Global',
-                          path => 'Admin/Global/',
-                        },
-               Keywords => { title => 'Keywords',
-                                   path => 'Admin/Keywords/',
-                                 },
-
-              
-            };
-</%INIT>
-
-
-<%ARGS>
-$subtabs => undef
-$current_tab => undef
-$current_subtab => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Elements/UserTabs b/rt/webrt/Admin/Elements/UserTabs
deleted file mode 100755 (executable)
index bbf1731..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<& /Admin/Elements/Tabs, subtabs => $subtabs,
-                        current_tab => 'Admin/Users/', 
-                         current_subtab => $current_subtab &>
-<hr>
-<%INIT>
-my $subtabs = {
-              Queues => { title => 'Basics',
-                          path => "Admin/Users/Modify.html?id=".$id
-                        },
-#             Scrips => { title => 'Rights',
-#                         path => "Admin/Users/Rights.html?id=".$id
-#                       }
-              
-             };
-</%INIT>
-  
-  
-<%ARGS>
-$id => undef
-$current_subtab => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Global/GroupRights.html b/rt/webrt/Admin/Global/GroupRights.html
deleted file mode 100755 (executable)
index 26b7e1f..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Modify System ACLS' &>
-<& /Admin/Elements/SystemTabs &>
-  
-<& /Elements/ListActions, actions => \@results &>
-  <FORM METHOD=POST action="GroupRights.html">
-      
-
-
-<h2>Modify global rights for groups</h2>
-
-<TABLE>
-<TR><TD>Pseudogroups</TD></TR>
-% while (my $GroupObj = $PseudoGroups->Next()) {
-             
-             <TR ALIGN=RIGHT> 
-               <TD VALIGN=TOP>
-                 <% $GroupObj->Name %>
-               </TD>
-               <TD>
-           <& /Admin/Elements/SelectRights, PrincipalObj => $GroupObj, 
-                                   PrincipalType => 'Group',
-                                   Scope => 'System' &>
-               </TD>
-             </TR>
-       
-% }
-
-<TR><TD>Groups</TD></TR>
-
-% while (my $GroupObj = $Groups->Next()) {
-             
-             <TR ALIGN=RIGHT> 
-               <TD VALIGN=TOP>
-                 <% $GroupObj->Name %>
-               </TD>
-               <TD>
-           <& /Admin/Elements/SelectRights, PrincipalObj => $GroupObj, 
-                                   PrincipalType => 'Group',
-                                   Scope => 'System' &>
-               </TD>
-             </TR>
-       
-% }
-       
-      </TABLE>
-    <& /Elements/Submit, Caption => "Be sure to save your changes", Reset => 1 &>
-  </FORM>
-  
-  <%INIT>
-   #Update the acls.
- my @results =  ProcessACLChanges(\@CheckACL, \%ARGS);
-
-        
-    # {{{ do basic initialization.
-    
-  
-  
-  # Find out which groups we want to display ACL selects for.
-  my $Groups = new RT::Groups($session{'CurrentUser'});
-  #TODO: limit this to non-pseudogroups
-  $Groups->LimitToReal();
-
-
-  my $PseudoGroups = new RT::Groups($session{'CurrentUser'});
-  #TODO: limit this to non-pseudogroups
-  $PseudoGroups->LimitToPseudo;
-
-  # }}}
-    
-  
-
-  
-  </%INIT>
-
-<%ARGS>
-@CheckACL => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Global/Keywords.html b/rt/webrt/Admin/Global/Keywords.html
deleted file mode 100644 (file)
index bf7bbd2..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Edit keywords' &>
-<& /Admin/Elements/SystemTabs &>
-<& /Elements/ListActions, actions => \@actions &>
-
-<& /Elements/TitleBoxStart, title => $description &>
-  
-  <FORM METHOD=POST ACTION="Keywords.html">
-
-% if ($KeywordSelects->Count > 0 ) {
-<TABLE>
-<TR><TD>Delete</TD></TR>
-%  while (my $keywordselect = $KeywordSelects->Next ) {
-<TR>
-  <TD><INPUT TYPE="CHECKBOX" NAME="KeywordSelect-<%$keywordselect->Id%>-Delete"></TD>
-  <TD><& /Admin/Elements/SelectKeywordSelect, KeywordSelect => $keywordselect &></TD>
-</TR>
-%  }
-</TABLE>
-% }
-
-Add a global keyword selection:
-%my $ks = new RT::KeywordSelect($session{'CurrentUser'});
-<ul>
-<li><& /Admin/Elements/SelectKeywordSelect, KeywordSelect => $ks, NamePrefix => 'new' &></li>
-</ul>
-
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit &>
-</FORM>
-
-
-
-<%init>
-my (@actions);
-
-my $description = "Modify global Keyword selections";
-
-my $KeywordSelects = new RT::KeywordSelects ($session{'CurrentUser'});
-
-unless ($KeywordSelects->LimitToGlobals()) {
-    Abort("Couldn't load KeywordSelects.");
-}
-
-
-# {{{ if we're trying to create a new keyword select
-
-if ($ARGS{'KeywordSelect-new-Name'}) {
-    my $NewKeywordSelect = new RT::KeywordSelect($session{'CurrentUser'});
-    
-    my ($retval, $msg) = $NewKeywordSelect->Create ( Keyword => $ARGS{'KeywordSelect-new-Keyword'},
-                                            ObjectField => 'Queue',
-                                            ObjectType => 'Ticket',
-                                            ObjectValue => 0,
-                                            Name => $ARGS{'KeywordSelect-new-Name'},
-                                            Single => $ARGS{'KeywordSelect-new-Single'},
-                                            Depth => $ARGS{'KeywordSelect-new-Depth'}
-                                          );
-       push (@actions, $msg);
-}
-# }}}
-
-# {{{ if we're trying to delete the keywordselect
-foreach my $key (keys %ARGS) {
-    if ($key =~ /^KeywordSelect-(\d+)-Delete$/) {
-       my $id = $1;
-       my $keywordselect = new RT::KeywordSelect($session{'CurrentUser'});
-       $keywordselect->Load($id) || push @actions, "Couldn't load keywordSelect";
-       my ($val, $msg) = $keywordselect->SetDisabled(1);
-       if ($val) {
-           push @actions, 'KeywordSelect disabled.';
-       }       
-       else {
-           push @actions, $msg;
-       }       
-    }
-}
-# }}}
-# {{{ if we're modifying keyword selects
-my @fields = qw(Name Keyword Single Depth);
-
-while (my $ks = $KeywordSelects->Next) {
-    foreach my $field (@fields) {
-       if (defined ($ARGS{"KeywordSelect-".$ks->Id."-".$field}) &&
-           ($ARGS{"KeywordSelect-".$ks->Id."-".$field} ne $ks->$field())) {
-           
-           my $method = "Set$field";
-           my ($val, $msg) = $ks->$method($ARGS{"KeywordSelect-".$ks->Id."-".$field});
-           push @actions, "Keyword Select ". $ks->Name."/$field:".$msg;
-       }       
-    }
-}
-# }}}
-
-</%init>
-
-<%ARGS>
-</%ARGS>
diff --git a/rt/webrt/Admin/Global/Scrips.html b/rt/webrt/Admin/Global/Scrips.html
deleted file mode 100755 (executable)
index e55f8b3..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Edit scrips' &>
-<& /Admin/Elements/SystemTabs &>
-
-<& /Elements/ListActions, actions => \@actions &>
-
-<& /Elements/TitleBoxStart, title => "Modify global scrips" &>
-  
-  <FORM METHOD=POST ACTION="Scrips.html">
-
-% if ($Scrips->Count > 0 ) {
-<TABLE>
-<TR>
-<TD>Delete
-</TD>
-<TD>
-</TR>
-
-%   while (my $scrip = $Scrips->Next ) {
-<TR>
-<TD>
-<INPUT TYPE="CHECKBOX" NAME="DeleteScrip-<%$scrip->Id%>">
-</TD>
-<TD>
-<% $scrip->ConditionObj->Name %> 
-<% $scrip->ActionObj->Name %> 
-with template <% $scrip->TemplateObj->Name %>
-</TD>
-</TR>
-%   }
-
-</TABLE>
-
-% }
-Add a scrip which will apply to all queues:
-<ul>
-<li>Condition: <& /Admin/Elements/SelectScripCondition, Name => 'NewScripCondition' &>
-         Action: <& /Admin/Elements/SelectScripAction, Name => 'NewScripAction' &>
-         Template: <& /Admin/Elements/SelectTemplate, Name => 'NewScripTemplate' &>
-
-</ul>
-
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit &>
-</FORM>
-<%init>
-my (@actions, $description);
-
-my $Scrips = new RT::Scrips ($session{'CurrentUser'});
-$Scrips->LimitToGlobal();
-
-
-
-
-if ($NewScripAction and $NewScripCondition) {
-    my $NewScrip = new RT::Scrip($session{'CurrentUser'});
-    
-    my ($retval, $msg) = $NewScrip->Create ( ScripAction => $NewScripAction,
-                                    ScripCondition => $NewScripCondition,
-                                    Stage => 'TransactionCreate',
-                                    Queue => 0,
-                                    Template => $NewScripTemplate);
-    if (defined $retval) {
-        push @actions, $msg;
-    }
-    else {
-        push @actions, $msg;
-    }
-}
-
-# {{{ deal with modifying and deleting existing scrips
-my ($key );
-foreach $key (keys %ARGS) {
-  # {{{ if we're trying to delete the scrip
-  if ($key =~ /^DeleteScrip-(\d+)/) {
-    my $id = $1;
-    my $scrip = new RT::Scrip($session{'CurrentUser'});
-    $scrip->Load($id);
-    my ($retval, $msg) = $scrip->Delete;
-    if ($retval) {
-      push @actions, "Scrip deleted";
-    }
-    else {
-      push @actions, $msg;
-    }
-  }
-  # }}}
-}
-# }}}
-</%init>
-
-<%ARGS>
-$NewScripCondition => undef
-$NewScripAction => undef
-$NewScripTemplate => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Global/Template.html b/rt/webrt/Admin/Global/Template.html
deleted file mode 100755 (executable)
index 856d2ee..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<& /Admin/Elements/Header, title => "Modify template ".$TemplateObj->id&>
-<& /Admin/Elements/SystemTabs &>
-<& /Elements/ListActions, actions => \@results &>
-
-<& /Elements/TitleBoxStart, title => $title &>
-
-<FORM METHOD=POST ACTION="Template.html">
-%if ($create ) {
-<INPUT TYPE=HIDDEN NAME=template VALUE="new">
-% } else {
-<INPUT TYPE=HIDDEN NAME=template VALUE="<%$TemplateObj->Id%>">
-% }
-
-%# hang onto the queue id
-<INPUT TYPE=HIDDEN name="Queue" value="<%$Queue%>">
-
-
-Name: <input name="Name" VALUE="<%$TemplateObj->Name%>" SIZE=20><BR>
-Description: <input name="Description" VALUE="<%$TemplateObj->Description%>" SIZE=80><BR>
-
-<TEXTAREA NAME=Content ROWS=25 COLS=80 WRAP=SOFT>
-<%$TemplateObj->Content%></TEXTAREA>
-
-<& /Elements/TitleBoxEnd&>
-<&/Elements/Submit&>
-</FORM>
-
-
-
-<%INIT>
-
-my $TemplateObj = new RT::Template($session{'CurrentUser'});
-my  ($title, @results);
-
-if ($create) {
-  $title = "Create a template";
-}
-
-else {
-  if ($template eq 'new') {
-      my ($val, $msg) =  $TemplateObj->Create(Queue => $Queue, Name => $Name);
-      Abort("Could not create template: $msg") unless ($val);
-     push @results, $msg;
-     $title = 'Created template ' . $TemplateObj->Name(); 
-    }
-    else {
-       $TemplateObj->Load($template) || Abort('No Template');
-      $title = 'Editing template ' . $TemplateObj->Name(); 
-    }
-  
-    
-}
-if ($TemplateObj->Id()) {
-  my @attribs = qw( Description Content Queue Name);
-  my @aresults = UpdateRecordObject( AttributesRef => \@attribs, 
-                                    Object => $TemplateObj, 
-                                    ARGSRef => \%ARGS);
-  push @results, @aresults;
-}
-</%INIT>
-<%ARGS>
-$Queue => undef
-$template => undef
-$create => undef
-$Name => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Global/Templates.html b/rt/webrt/Admin/Global/Templates.html
deleted file mode 100755 (executable)
index cf388e5..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Edit system templates' &>
-<& /Admin/Elements/SystemTabs &>
-
-<& /Elements/TitleBoxStart, title => 'Edit system templates' &>
-<UL>
-<LI><A href="Template.html?create=1&Queue=0">Create a new template</A><BR><BR>
-
-
-%while  (my $TemplateObj = $Templates->Next) { 
-
-<LI><A HREF="Template.html?template=<%$TemplateObj->id()%>"><%$TemplateObj->id()%>/<%$TemplateObj->Name%>: <%$TemplateObj->Description%></a><BR>
-
-%}
-
-<& /Elements/TitleBoxEnd &>
-<%INIT>
-
-my $Templates = RT::Templates->new($session{'CurrentUser'});
-$Templates->LimitToGlobal();
-
-</%INIT>
-<%ARGS>
-$id => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Global/UserRights.html b/rt/webrt/Admin/Global/UserRights.html
deleted file mode 100755 (executable)
index 351f4b8..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Modify System ACLS' &>
-<& /Admin/Elements/SystemTabs &>
-  
-<& /Elements/ListActions, actions => \@results &>
-  <FORM METHOD=POST action="UserRights.html">
-      
-
-<h2>Modify global rights for users</h2>
-<TABLE>
-%      while (my $UserObj = $Users->Next()) {
-  <TR ALIGN=RIGHT> 
-       <TD VALIGN=TOP>
-         <A HREF="<%$RT::WebPath%>/Admin/Users/Modify.html?id=<%$UserObj->id%>"><% $UserObj->Name %></A>
-       </TD>
-       <TD>
-         <& /Admin/Elements/SelectRights, PrincipalObj => $UserObj, 
-             PrincipalType => 'User',
-             Scope => 'System' &>
-         
-       </TD>
-      </TR>
-       
-% }
-    </TABLE>
-    
-    <& /Elements/Submit, Caption => "Be sure to save your changes", Reset => 1 &>
-  </FORM>
-  
-<%INIT>
- my @results =  ProcessACLChanges(\@CheckACL, \%ARGS);
-
- # Find out which users we want to display ACL selects for
- my $Users = new RT::Users($session{'CurrentUser'});
-
- $Users->LimitToPrivileged();
-  
-</%INIT>
-
-<%ARGS>
-@CheckACL => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Global/index.html b/rt/webrt/Admin/Global/index.html
deleted file mode 100755 (executable)
index 5907ed1..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Admin/Global configuration' &>
-<& /Admin/Elements/SystemTabs &>
diff --git a/rt/webrt/Admin/Groups/Members.html b/rt/webrt/Admin/Groups/Members.html
deleted file mode 100644 (file)
index 4b0e0d0..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-<& /Admin/Elements/Header, Title => "RT/Admin/Edit the group ". $Group->Name &>
-<& /Admin/Elements/GroupTabs, GroupObj => $Group &>
-<& /Elements/ListActions, actions => \@results &>
-
-
-<& /Elements/TitleBoxStart, title => 'Editing membership for group '.$Group->Name &>
-
-<FORM ACTION="<%$RT::WebPath%>/Admin/Groups/Members.html" METHOD=POST>
-<INPUT TYPE=HIDDEN NAME=id VALUE="<%$Group->Id%>">
-<TABLE WIDTH="100%">
-<TR>
-<TD>
-Add members
-</TD>
-<TD>
-Current members
-</TD>
-</TR>
-
-<TR>
-<TD VALIGN=TOP>
-<& /Admin/Elements/SelectUsers, Name => "AddMembers" &>
-</TD>
-<TD VALIGN=TOP>
-% if ($Group->MembersObj->Count == 0 ) {
-<i>(No members)</i>
-% } else {
-(Check box to delete group member)
-<UL>
-% while (my $member = $Group->MembersObj->Next()) {
-<LI><INPUT TYPE=CHECKBOX Name="DeleteMember-<%$member->UserObj->id%>">
-<%$member->UserObj->Name%> (<%$member->UserObj->RealName%>)
-% }
-% }
-</UL>
-</TD>
-</TR>
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit &>
-</form>
-
-
-<%INIT>
-
-my $Group = new RT::Group($session{'CurrentUser'});
-$Group->Load($id) || Abort('Could not load group');
-
-my (@results);
-
-my $key;
-foreach $key (keys %ARGS) {
-
-if ($key =~ /^DeleteMember-(\d+)$/) {
-    my $id = $1; 
-    my ($val,$msg) = $Group->DeleteMember($id);
-    push (@results, $msg);
-}
-}
-
-# Make sure AddMembers is always an array
-my @AddMembers = (ref $AddMembers eq 'ARRAY') ? @{$AddMembers} : ($AddMembers);
-
-foreach my $member (@AddMembers) {
-    next unless ($member);
-    my ($val, $msg) = $Group->AddMember($member);
-    push (@results, $msg);
-}
-
-
-</%INIT>
-
-<%ARGS>
-$AddMembers => undef
-$id => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Groups/Modify.html b/rt/webrt/Admin/Groups/Modify.html
deleted file mode 100644 (file)
index 7104a69..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-<& /Admin/Elements/Header, Title => $title &>
-
-<& /Admin/Elements/GroupTabs, GroupObj => $Group &>
-<& /Elements/ListActions, actions => \@results &>
-
-
-<& /Elements/TitleBoxStart, title => $title &>
-
-<FORM ACTION="<%$RT::WebPath%>/Admin/Groups/Modify.html" METHOD=POST>
-
-%unless ($Group->Id) {
-<INPUT TYPE=HIDDEN NAME=id VALUE="new">
-% } else {
-<INPUT TYPE=HIDDEN NAME=id VALUE="<%$Group->Id%>">
-% }
-<TABLE>
-<TR><TD ALIGN=RIGHT>
-Name: 
-</TD>
-<TD><INPUT name="Name" value="<%$Group->Name%>"></TD>
-</TR><TR>
-<TD ALIGN=RIGHT>
-Description:</TD><TD COLSPAN=3><INPUT name="Description" value="<%$Group->Description%>" size=60></TD></TR>
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-
-<& /Elements/Submit &>
-</form>
-<%INIT>
-
-my ($title);
-my (@results);
-
-my $Group = new RT::Group($session{'CurrentUser'});
-
-if ($Create) {
-    $title = "Create a new group";
-} 
-
-else {
-    
-    if ($id eq 'new' ) {
-       
-       $Group->Create(Name => "$Name") || Abort ("Group could not be created.");
-       $id = $Group->Id;
-    }
-    else {
-       $Group->Load($id) || Abort('Could not load group');
-    }
-
-
-    if ($id) {
-       $title = "Modify the group ". $Group->Name;
-
-    }  
-
-    # If the create failed
-    else {
-       $title = "Create a new group";
-       $Create = 1;
-    }    
-    
-}
-
-if ($id) {
-    
-    my @fields = qw(Description Name );
-    my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields,
-                                           Object => $Group,
-                                           ARGSRef => \%ARGS );
-    push (@results,@fieldresults);
-}
-
-
-</%INIT>
-
-
-<%ARGS>
-$Create => undef
-$Name => undef
-$Description => undef
-$id => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Groups/Rights.html b/rt/webrt/Admin/Groups/Rights.html
deleted file mode 100644 (file)
index 5c842a3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Not yet implemented....
diff --git a/rt/webrt/Admin/Groups/index.html b/rt/webrt/Admin/Groups/index.html
deleted file mode 100644 (file)
index d419e7f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-
-<& /Admin/Elements/Header, Title => 'Admin/Groups' &>
-<& /Admin/Elements/Tabs, current_tab => 'Admin/Groups/' &>
-
-<& /Elements/TitleBoxStart, title => 'Select a group' &>
-
-Pseudogroups:<BR>
-<UL>
-%while ( $Group = $PseudoGroups->Next) {
-<LI><A HREF="Modify.html?id=<%$Group->id%>"><%$Group->Name%></a><BR>
-%}
-
-</UL>
-
-Groups:<BR>
-<UL>
-<LI><A HREF="Modify.html?Create=1">Create a new group</A><BR><BR></LI>
-%while ( $Group = $Groups->Next) {
-<LI><A HREF="Modify.html?id=<%$Group->id%>"><%$Group->Name%></a><BR>
-%}
-</UL>
-
-<& /Elements/TitleBoxEnd &>
-<%INIT>
-my ($Group);
-my $PseudoGroups = new RT::Groups($session{'CurrentUser'});
-$PseudoGroups->LimitToPseudo;
-my $Groups = new RT::Groups($session{'CurrentUser'});
-$Groups->LimitToReal;
-
-</%INIT>
-<%ARGS>
-</%ARGS>
diff --git a/rt/webrt/Admin/KeywordSelects/Modify.html b/rt/webrt/Admin/KeywordSelects/Modify.html
deleted file mode 100644 (file)
index e753c66..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Admin KeywordSelects' &>
-<& /Admin/Elements/Tabs &>
-
-<& /Admin/Elements/ModifyKeywordSelect, Create=>$Create, id=>$id, Parent=>$Parent, ObjectType=>$ObjectType, ObjectField=>$ObjectField, ObjectValue=>$ObjectValue, Single=>$Single, SingleMagic=>$SingleMagic, Generations=>$Generations &>
-
-<%ARGS>
-$Create => undef
-$id => undef
-$Parent => undef
-$ObjectType => undef
-$ObjectField => undef
-$ObjectValue => undef
-$Single => undef
-$SingleMagic => undef
-$Generations => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/KeywordSelects/index.html b/rt/webrt/Admin/KeywordSelects/index.html
deleted file mode 100644 (file)
index ba3da9f..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Admin KeywordSelects' &>
-<& /Admin/Elements/Tabs, current_tab => 'Admin/KeywordSelects/' &>
-
-A <B>KeywordSelect</B> is a link between a <B>Keyword</B> and a object
-(currently just <B>Tickets</B>), titled by the <I>Name</I> field of the Keyword such that:
-<ul>
-<li>Object display will contain a field, titled with the <I>Name</I> field of
-the <B>Keyword</B> and showing any descendent keywords.
-<li>Object creation for this field will contain a field, titled with the
-<I>Name</I> field of the <B>Keyword</B> and containing the descendents of
-the <B>Keyword</B> as choices.
-<li>Searches for this object type will contain a selection field titled with
-the <I>Name</I> field of the <B>Keyword</B> and containing the descendents
-of the <B>Keyword</B> as choices.
-<TABLE WIDTH=100%>
-
-
-
-  <TD VALIGN=TOP>
-    <h2>Create KeywordSelect</h2>
-  <FORM NAME="ModifyKeywordSelect" METHOD="POST" ACTION="<%$RT::WebPath%>/Admin/KeywordSelects/Modify.html">
-    [<%$title |n %>]
-    <BR>
-      
-      <INPUT TYPE="hidden" NAME="id" VALUE="<% $id %>">
-       Keyword 
-       <SELECT NAME="Parent">
-         
-%while ( $parent = $parents->Next ) {
-         
-         <OPTION VALUE="<% $parent->id %>" <% defined($KeywordSelect->Parent) && $parent->id == $KeywordSelect->Parent ? ' SELECTED' : '' %>><% $parent->Name %></OPTION>
-         
-% }
-         
-       </SELECT>
-       <BR>
-         Object 
-         <SELECT NAME="ObjectType">
-           <OPTION SELECTED>Ticket</OPTION>
-         </SELECT>
-         <BR>
-           
-%foreach $queue ( keys %queues ) {
-    addOption("<% $queues{$queue} %>", "<% $queue %>", false, <% $queue == $KeywordSelect->ObjectValue ? 'true' : 'false' %> )
-%}
-  }
-}
-</SCRIPT>
-           
-           Limit to <SELECT NAME="ObjectField" onChange="ChangeObjectValue(this)">
-             <OPTION VALUE="" <% $KeywordSelect->ObjectField ? '' : ' SELECTED' %>>(none)</OPTION>
-             <OPTION VALUE="Queue" <% $KeywordSelect->ObjectField eq 'Queue' ? ' SELECTED' : '' %>>Queue</OPTION>
-           </SELECT> 
-           <SELECT NAME="ObjectValue">
-             <OPTION VALUE="<% $KeywordSelect->ObjectValue %>">
-               <% $KeywordSelect->ObjectField ? $queues{$KeywordSelect->ObjectValue} : "(n/a)" %></OPTION>
-           </SELECT><BR>
-             <INPUT TYPE="hidden" NAME="SingleMagic" VALUE="1">
-               <INPUT TYPE="checkbox" NAME="Single" VALUE="1" <% $KeywordSelect->Single ? ' CHECKED' : '' %>>Allow single selection only<BR>
-                   Limit to <INPUT TYPE="text" NAME="Generations" SIZE="2" VALUE="<% $KeywordSelect->Generations %>"> generations (0 = no limit)<BR>
-                       <& /Elements/Submit, Label => $submit &>
-
-</FORM>
-
-<%INIT>
-
-
-my $KeywordSelect = new RT::KeywordSelect($session{CurrentUser});
-  
-my($title, $submit);
-  
-if ( $Create ) {
-      $title = "Create a new KeywordSelect";
-      $submit = "Create";
-      $id = "new";
-} else {
-    if  ( $id eq 'new' ) {
-       $id = $KeywordSelect->Create (
-                                     Parent      => $Parent,
-                                     ObjectType  => $ObjectType,
-                                     ObjectField => $ObjectField,
-                                     ObjectValue => $ObjectValue,
-                                     Single      => $Single,
-                                     Generations => $Generations,
-                                    ) or Abort "can't create KeywordSelect";
-    } else {
-       $KeywordSelect->Load($id) || Abort("Can't load keyword id $id");
-       #false laziness
-       $KeywordSelect->SetParent($Parent) if defined($Parent);
-       $KeywordSelect->SetObjectType($ObjectType) if defined($ObjectType);
-       $KeywordSelect->SetObjectField($ObjectField) if defined($ObjectField);
-       $KeywordSelect->SetObjectValue($ObjectValue) if defined($ObjectValue);
-       $KeywordSelect->SetSingle($Single) if defined($SingleMagic);
-       $KeywordSelect->SetGenerations($Generations) if defined($Generations);
-    }
-    $title = "Modify the KeywordSelect <B>". $KeywordSelect->KeywordObj->Name. "</B>";
-    $submit = "Modify";
-    
-}
-  
-  my $parents = new RT::Keywords($session{CurrentUser});
-  $parents->UnLimit;
-  my $parent;
-
-my $queues = new RT::Queues($session{CurrentUser});
-$queues->UnLimit;
-
-my %queues;
-my $queue;
-$queues{$queue->id} = $queue->Name while $queue = $queues->Next;
-
-</%INIT>
-
-<%ARGS>
-$id => undef
-$Create => undef
-$Parent => undef
-$ObjectType => undef
-$ObjectField => undef
-$ObjectValue => undef
-$Single => undef
-$SingleMagic => undef
-$Generations => undef
-</%ARGS>
-
-
-    <& /Admin/Elements/ModifyKeywordSelect, 'Create'=>'1' &>
-  </TD>
-
-  <TD VALIGN=TOP>
-    <H2>Modify KeywordSelect</H2>
-
-    <& /Admin/Elements/SelectModifyKeywordSelect &>
-  </TD>
-</TR>
-
-</TABLE>
diff --git a/rt/webrt/Admin/Keywords/Modify.html b/rt/webrt/Admin/Keywords/Modify.html
deleted file mode 100644 (file)
index bb7e2db..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-<& /Admin/Elements/Header, Title => $title &>
-<& /Admin/Elements/Tabs &>
-
-
-<& /Elements/TitleBoxStart, title => %$title  &>
-<FORM METHOD="POST" ACTION="<%$RT::WebPath%>/Admin/Keywords/Modify.html">
-<INPUT TYPE="hidden" NAME="id" VALUE="<% $id %>">
-Keyword <INPUT NAME="Name" VALUE="<% $Keyword->Name %>"><BR>
-
-Parent <SELECT NAME="Parent">
-             <OPTION VALUE=""<% defined($Keyword->Parent) ? '' : ' SELECTED' %>>-</OPTION>
-%while ( $parent = $parents->Next ) {
-             <OPTION VALUE="<% $parent->id %>"<% defined($Keyword->Parent) && $parent->id == $Keyword->Parent ? ' SELECTED' : '' %>><% $parent->Name %></OPTION>
-%}
-</SELECT>
-
-
-New children of this keyword. one per line.
-<TEXTAREA NAME="Kids" ROWS=4><% $kidstring %></TEXTAREA>
-<BR>
-
-<& /Elements/Submit, Label => $submit &>
-</FORM>
-<& /Elements/TitleBoxEnd &>
-
-<%INIT>
-
-my $Keyword = new RT::Keyword($session{CurrentUser});
-my ($title, $submit, %kids, $kid);
-
-if ( $Create ) {
-    $title = "Create a new Keyword";
-    $submit = "Create";
-    $id = "new";
-    %kids = ();
-    $Parent = ''; #silence 
-} 
-else {
-    if ( $id eq 'new' ) {
-       $id = $Keyword->Create( Name => $Name, Parent => $Parent )
-         or Abort("can't create keyword Name=>$Name, Parent=>$Parent");
-    } else {
-       $Keyword->Load($id) || Abort("Can't load keyword id $id");
-       
-       #foreach my $field ( grep eval "defined(\$$_)", qw( Name Parent )) {
-       #  eval "\$Keyword->Set(\$field=>\$$field); #sigh
-       #}
-       
-       $Keyword->SetName($Name) if defined($Name);
-       $Keyword->SetParent($Parent) if defined($Parent);
-    }
-
-    $title = "Modify the Keyword <B>". $Keyword->Name. "</B>";
-    $submit = "Modify";
-}
-
-
-my $kids = $Keyword->Children(new RT::Keywords($session{CurrentUser}));
-
-$kids{$kid->Name} = $kid while $kid = $kids->Next;
-
-if ( defined($Kids) ) {
-    my %newkids;
-
-       %newkids = map { $_=>1 } split(/\r/, $Kids);
-
-    }
-    foreach ( grep { ! defined($newkids{$_}) } keys %kids ) {
-       $kids{$_}->Delete;
-       delete $kids{$_};
-    }
-    foreach ( grep { ! defined($kids{$_}) } keys %newkids ) {
-       $kids{$_} = new RT::Keyword($session{CurrentUser});
-       $kids{$_}->Create( Name => $_, Parent => $id )
-         or Abort("can't create keyword Name=>$_, Parent=>$id");
-    }
-
-}
-
-
-my $parent;
-my $parents = new RT::Keywords($session{CurrentUser});
-$parents->UnLimit;
-
-my $kidstring = join("\r", keys %kids);
-
-</%INIT>
-
-<%ARGS>
-$id => undef
-$Create => undef
-$Name => undef
-$Parent => undef
-$Kids => undef
-
-</%ARGS>
diff --git a/rt/webrt/Admin/Keywords/index.html b/rt/webrt/Admin/Keywords/index.html
deleted file mode 100644 (file)
index 12814ec..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-<& /Elements/Header, Title => 'Admin/Keywords' &>
-<& /Admin/Elements/Tabs, current_tab => 'Admin/Keywords/' &>
-
-<& /Elements/ListActions, actions => \@Actions &>
-
-<& /Elements/TitleBoxStart, title => 'Keywords' &>
-<a href="<%$RT::WebPath%>/Admin/Keywords/?RootId=<%$Root->Parent%>"><%$Root->Path%></a>
-<UL>
-<FORM METHOD=POST ACTION="index.html">
-<input type=hidden name=RootId value="<%$RootId%>">
-
-
-% while (my $key = $Keywords->Next) {
-    <LI>
-% if ($Edit == $key->id) {
-      <input name="KeyName-<%$key->id%>" value="<%$key->Name%>">
-         <input type=submit value="Update">
-           <input type=submit name="Disable-<%$key->id%>" value="Disable">
-% } else {
-             <A HREF="?RootId=<%$key->id%>"><%$key->Name%></A>
-% if ($key->Disabled) {
-       <input type=submit name="Enable-<%$key->id%>" value="Enable">
-% } else {
-      [<a href="?Edit=<%$key->id%>&RootId=<%$Root->Id%>">edit</a>]
-% }
-% }
-
-
-         </LI>
-% }
-         <LI>
-           <input name="KeyName-New"> <input type=submit value="Add">
-</UL>
-<BR>
-         <input type="checkbox" name="ShowDisabled"> Include disabled items in listing.
-       <input type=submit value="Go!">
-
-</FORM>
-
-<& /Elements/TitleBoxEnd &>
-<%INIT>
-my (@Actions);
-  
-if ($ARGS{'KeyName-New'}) {
-    my $NewKey = new RT::Keyword($session{'CurrentUser'});
-    my ($val, $msg) = $NewKey->Create( Parent => $RootId, Name => $ARGS{'KeyName-New'});
-    push (@Actions, $msg);
-}
-
-my $arg;
-foreach $arg (keys %ARGS) {
-    if ($arg =~ /^Disable-(\d*)$/) {
-       my $id = $1;
-       my $keyword = new RT::Keyword($session{'CurrentUser'});
-       $keyword->Load($id);
-       my ($val, $msg) = $keyword->SetDisabled(1);
-       push (@Actions, $msg);
-
-
-    }  
-    elsif ($arg =~ /^Enable-(\d*)$/) {
-       my $id = $1;
-       my $keyword = new RT::Keyword($session{'CurrentUser'});
-       $keyword->Load($id);
-       my ($val, $msg) = $keyword->SetDisabled(0);
-       push (@Actions, $msg);
-    }
-    elsif ($arg =~ /^KeyName-(\d*)$/) {
-       my $id = $1;
-       my $keyword = new RT::Keyword ($session{'CurrentUser'});
-       $keyword->Load($id);
-       if ($keyword->Name() ne $ARGS{"$arg"}) {
-           my ($val, $msg) = $keyword->SetName($ARGS{"$arg"});
-           push (@Actions, $msg);
-       }       
-       if (($ARGS{"KeyParent-$id"}) && 
-           ($keyword->Parent ne $ARGS{"KeyParent-$id"})) {
-           my ($val, $msg) = $keyword->SetParent($ARGS{"KeyParent-$id"});
-           push (@Actions, $msg);
-       }       
-    }  
-}
-
-
-my $Root = new RT::Keyword($session{'CurrentUser'});
-my $Keywords;
-#If we have a root load it.
-if ($RootId != 0) {
-    $Root->Load($RootId);
-    $Keywords = $Root->Children();
-    
-}
-else {
-    $Keywords = new RT::Keywords($session{'CurrentUser'});
-    $Keywords->LimitToParent(0);
-}
-
-if ($ShowDisabled) {
-    $Keywords->{'find_disabled_rows'} = 1;
-}
-
-
-
-
-</%INIT>
-<%ARGS>
-$RootId => 0
-$Edit => undef
-$ShowDisabled => 0
-</%ARGS>
diff --git a/rt/webrt/Admin/Queues/Create.html b/rt/webrt/Admin/Queues/Create.html
deleted file mode 100755 (executable)
index b39d659..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Create a queue' &>
-    <h1>Create a queue</h1>
-
-<& /Admin/Elements/ModifyQueue, QueueObj => $QueueObj &>
-
-<%INIT>
-my $QueueObj = new RT::Queue($session{'CurrentUser'});
-$QueueObj->Create(Name => "$Name");
-</%INIT>
-
-<%ARGS>
-$Name => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Queues/GroupRights.html b/rt/webrt/Admin/Queues/GroupRights.html
deleted file mode 100755 (executable)
index a2c6690..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Modify group rights for queue '. $QueueObj->Name &>
-<& /Admin/Elements/QueueTabs, id => $id &>  
-<& /Elements/ListActions, actions => \@results &>
-
-  <FORM METHOD=POST ACTION="GroupRights.html">
-    <INPUT TYPE=HIDDEN NAME=id VALUE="<% $QueueObj->id %>">
-      
-
-
-<& /Elements/TitleBoxStart, title => 'Modify group rights for queue '.$QueueObj->Name &>
-
-<TABLE>
-<TR><TD>Pseudogroups</TD></TR>
-% while (my $GroupObj = $PseudoGroups->Next()) {
-             
-             <TR ALIGN=RIGHT> 
-               <TD VALIGN=TOP>
-                 <% $GroupObj->Name %>
-               </TD>
-               <TD>
-           <& /Admin/Elements/SelectRights, PrincipalObj => $GroupObj, 
-                                   PrincipalType => 'Group',
-                                  QueueObj => $QueueObj,
-                                   Scope => 'Queue' &>
-
-               </TD>
-             </TR>
-       
-% }
-
-<TR><TD>Groups</TD></TR>
-
-% while (my $GroupObj = $Groups->Next()) {
-             
-             <TR ALIGN=RIGHT> 
-               <TD VALIGN=TOP>
-                 <% $GroupObj->Name %>
-               </TD>
-               <TD>
-           <& /Admin/Elements/SelectRights, PrincipalObj => $GroupObj, 
-                                   PrincipalType => 'Group',
-                                  QueueObj => $QueueObj,
-                                   Scope => 'Queue' &>
-
-               </TD>
-             </TR>
-       
-% }
-       
-      </TABLE>
-
-      <& /Elements/TitleBoxEnd &>
-      <& /Elements/Submit, Caption => "Be sure to save your changes", Reset => 1 &>
-  </FORM>
-  
-<%INIT>
-#Update the acls.
-my @results =  ProcessACLChanges(\@CheckACL, \%ARGS);
-
-# {{{ Deal with setting up the display of current rights.
-
-# {{{ do basic initialization.
-
-#Define vars used in html above
-my ($GroupObj);
-
-my ($right);
-
-
-if (!defined $id) {
-    Abort("No Queue defined");
-}
-
-my $QueueObj = new RT::Queue($session{'CurrentUser'});
-$QueueObj->Load($id) ||
-  Abort("Couldn't load queue $id");
-  
-  # Find out which groups we want to display ACL selects for.
-  my $Groups = new RT::Groups($session{'CurrentUser'});
-  #TODO: limit this to non-pseudogroups
-  $Groups->LimitToReal();
-
-
-  my $PseudoGroups = new RT::Groups($session{'CurrentUser'});
-  #TODO: limit this to non-pseudogroups
-  $PseudoGroups->LimitToPseudo;
-
-
-# }}}
-    
-  
-  # }}}
-
-</%INIT>
-
-<%ARGS>
-$id => undef
-$UserString => undef
-$UserOp => undef
-$UserField => undef
-@CheckACL => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Queues/Keywords.html b/rt/webrt/Admin/Queues/Keywords.html
deleted file mode 100644 (file)
index 7809805..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Edit keywords' &>
-<& /Admin/Elements/QueueTabs, id => $QueueObj->Id &>
-
-<& /Elements/ListActions, actions => \@actions &>
-
-<& /Elements/TitleBoxStart, title => $description &>
-
-<h2>Global Keyword Selections</h2>
-<& /Admin/Elements/ListGlobalKeywordSelects &>
-<BR>
-  
-  <FORM METHOD=POST ACTION="Keywords.html">
-    <INPUT TYPE=HIDDEN NAME=id VALUE="<%$id%>">
-
-% if ($KeywordSelects->Count > 0 ) {
-
-
-<h2>Queue Keyword Selections</h2>
-<TABLE>
-<TR><TD>Delete</TD></TR>
-%  while (my $keywordselect = $KeywordSelects->Next ) {
-<TR>
-  <TD><INPUT TYPE="CHECKBOX" NAME="KeywordSelect-<%$keywordselect->Id%>-Delete"></TD>
-  <TD><& /Admin/Elements/SelectKeywordSelect, KeywordSelect => $keywordselect &></TD>
-</TR>
-%  }
-</TABLE>
-% }
-
-Add a keyword selection to this queue:
-%my $ks = new RT::KeywordSelect($session{'CurrentUser'});
-<ul>
-<li><& /Admin/Elements/SelectKeywordSelect, KeywordSelect => $ks, NamePrefix => 'new' &></li>
-</ul>
-
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit &>
-
-</FORM>
-<%init>
-my (@actions);
-
-
-
-my $KeywordSelects = new RT::KeywordSelects ($session{'CurrentUser'});
-unless ($id =~ /^\d+$/) {
-    Abort("$id isn't a valid Queue id.");
-}
-
-unless ($KeywordSelects->LimitToQueue($id)) {
-    Abort("Couldn't load KeywordSelects.");
-}
-
-my $QueueObj = new RT::Queue($session{'CurrentUser'});
-$QueueObj->Load($id);
-
-my $description = "Modify Keyword selections for queue '". $QueueObj->Name ."'";
-
-
-
-# {{{ if we're trying to create a new keyword select
-
-if ($ARGS{'KeywordSelect-new-Name'}) {
-    my $NewKeywordSelect = new RT::KeywordSelect($session{'CurrentUser'});
-    
-    my ($retval, $msg) = $NewKeywordSelect->Create ( Keyword => $ARGS{'KeywordSelect-new-Keyword'},
-                                            ObjectField => 'Queue',
-                                            ObjectType => 'Ticket',
-                                            ObjectValue => $QueueObj->Id,
-                                            Name => $ARGS{'KeywordSelect-new-Name'},
-                                            Single => $ARGS{'KeywordSelect-new-Single'},
-                                            Depth => $ARGS{'KeywordSelect-new-Depth'}
-                                          );
-       push (@actions, $msg);
-}
-# }}}
-# {{{ if we're trying to delete the keywordselect
-foreach my $key (keys %ARGS) {
-    if ($key =~ /^KeywordSelect-(\d+)-Delete$/) {
-       my $id = $1;
-       my $keywordselect = new RT::KeywordSelect($session{'CurrentUser'});
-       $keywordselect->Load($id) || push @actions, "Couldn't load keywordSelect";
-       my ($val, $msg) = $keywordselect->SetDisabled(1);
-       if ($val) {
-           push @actions, 'KeywordSelect disabled.';
-       }       
-       else {
-           push @actions, $msg;
-       }       
-    }
-}
-# }}}
-# {{{ if we're modifying keyword selects
-my @fields = qw(Name Keyword Single Depth);
-
-while (my $ks = $KeywordSelects->Next) {
-    foreach my $field (@fields) {
-       if (defined ($ARGS{"KeywordSelect-".$ks->Id."-".$field}) &&
-           ($ARGS{"KeywordSelect-".$ks->Id."-".$field} ne $ks->$field())) {
-           
-           my $method = "Set$field";
-           my ($val, $msg) = $ks->$method($ARGS{"KeywordSelect-".$ks->Id."-".$field});
-           push @actions, "Keyword Select ". $ks->Name."/$field:".$msg;
-       }       
-    }
-}
-# }}}
-
-</%init>
-
-<%ARGS>
-$id => undef         #some identifier that a Queue could 
-
-</%ARGS>
diff --git a/rt/webrt/Admin/Queues/Modify.html b/rt/webrt/Admin/Queues/Modify.html
deleted file mode 100755 (executable)
index 7a200df..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Admin/Queue/Basics' &>
-<& /Admin/Elements/QueueTabs, id => $QueueObj->id &>
-<& /Elements/ListActions, actions => \@results &>
-
-
-
-<& /Elements/TitleBoxStart, title => $title &>
-
-
-<FORM ACTION="<%$RT::WebPath%>/Admin/Queues/Modify.html" METHOD=POST>
-%if ($Create ) {
-<INPUT TYPE=HIDDEN NAME=id VALUE="new">
-% } else {
-<INPUT TYPE=HIDDEN NAME=id VALUE="<%$QueueObj->Id%>">
-% }
-
-<TABLE>
-<TR><TD ALIGN=RIGHT>
-Queue Name: 
-</TD>
-<TD><INPUT name="Name" value="<%$QueueObj->Name%>"></TD>
-</TR><TR>
-<TD ALIGN=RIGHT>
-Description:</TD><TD COLSPAN=3><INPUT name="Description" value="<%$QueueObj->Description%>" size=60></TD></TR>
-<TR>
-<TD ALIGN=RIGHT>
-Correspondence Address:
-</TD><TD>
-<INPUT name="CorrespondAddress" value="<%$QueueObj->CorrespondAddress%>">
-<BR><font size="-1"><i>(If left blank, will default to <%$RT::CorrespondAddress%></i></font>
-</TD>
-<TD ALIGN=RIGHT>
-
-Comment Address: </TD><TD>
-<INPUT NAME="CommentAddress" value="<%$QueueObj->CommentAddress%>">
-<BR><font size="-1"><i>(If left blank, will default to <%$RT::CommentAddress%></i></font>
-</TD>
-</TR><TR>
-
-<TD ALIGN=RIGHT>
-Priority starts at: 
-</TD><TD><INPUT NAME="InitialPriority" value="<%$QueueObj->InitialPriority %>">
-</TD>
-<TD ALIGN=RIGHT>
-Over time, priority moves toward:
-</TD><TD><INPUT NAME="FinalPriority" value="<%$QueueObj->FinalPriority %>">
-</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT>
-Requests should be due in:
-</TD><TD>
-<INPUT NAME="DefaultDueIn" VALUE="<%$QueueObj->DefaultDueIn%>"> days.
-</TD>
-</TR>
-<TR>
-<TD>
-</TD>
-<TD COLSPAN=4><INPUT TYPE=HIDDEN NAME="SetEnabled" VALUE="1">
-<INPUT TYPE=CHECKBOX NAME="Enabled" VALUE="1" <%$EnabledChecked%>> Enabled (Unchecking this box disables this queue)<BR>
-</TD>
-</TR>
-
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit &>
-</form>
-
-
-
-<%INIT>
-
-my $QueueObj = new RT::Queue($session{'CurrentUser'});
-my  ($title, @results, $Disabled, $EnabledChecked);
-
-if ($Create) {
-    $title = "Create a queue";
-}
-
-else {
-    if ($id eq 'new') {
-       my ($val, $msg) =  $QueueObj->Create(Name => $Name);
-       if ($val == 0 ) {
-           Abort("Could not create queue: $msg");
-       }
-       else {
-               push @results, $msg;
-       }    
-     }
-     else {
-        $QueueObj->Load($id) || $QueueObj->Load($Name) || Abort("Couldn't load queue '$Name'");
-    }
-        $title = 'Editing Configuration for queue '.$QueueObj->Name;
-    
-}
-if ($QueueObj->Id()) {
-my @attribs= qw(Description CorrespondAddress CommentAddress Name 
-                InitialPriority FinalPriority DefaultDueIn);
-
-  @results = UpdateRecordObject( AttributesRef => \@attribs, 
-                                   Object => $QueueObj, 
-                                   ARGSRef => \%ARGS);
-
-}
-
-#we're asking about enabled on the web page but really care about disabled.
-if ($Enabled == 1) {
-    $Disabled = 0;
-}      
-else {
-    $Disabled = 1;
-}
-if  ( ($SetEnabled) and ( $Disabled != $QueueObj->Disabled) ) { 
-    my  ($code, $msg) = $QueueObj->SetDisabled($Disabled);
-    push @results, 'Enabled status '. $msg;
-}
-
-unless ($QueueObj->Disabled()) {
-    $EnabledChecked ="CHECKED";
-}
-</%INIT>
-
-
-<%ARGS>
-$id => undef
-$result => undef
-$Name => undef
-$Create => undef
-$Description => undef
-$CorrespondAddress => undef
-$CommentAddress => undef
-$InitialPriority => undef
-$FinalPriority => undef
-$DefaultDueIn => undef
-$SetEnabled => undef
-$Enabled => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Queues/People.html b/rt/webrt/Admin/Queues/People.html
deleted file mode 100755 (executable)
index b495400..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-<& /Elements/Header, Title => 'Modify people related to queue ' . $QueueObj->Name &>
-<& /Admin/Elements/QueueTabs, id => $id  &>
-
-<& /Elements/ListActions, actions => \@results &>
-
-<FORM METHOD=POST ACTION="People.html">
-<INPUT TYPE=HIDDEN NAME=id VALUE="<%$QueueObj->Id%>">
-<& /Elements/TitleBoxStart, title => 'Modify watchers for queue \''.$QueueObj->Name ."'",   width => "100%" &>
-
-<TABLE WIDTH=100%>
-<TR>
-<TD VALIGN=TOP >
-
-<h3>Current watchers</h3>
-<i>(Check box to delete)</i><br><BR>
-
-
-Cc:
-
-<ul>
-
-%# Print out a placeholder if there are none.
-%if ($cc->Count == 0 ) {
-<li><i>none</i>
-% }
-
-%while (my $watcher=$cc->Next) {
-<li>
-<INPUT TYPE=CHECKBOX NAME="DelWatcher<%$watcher->id%>" UNCHECKED>
-%# account
-%if ($watcher->IsUser) { 
-<a href="<%$RT::WebPath%>/Admin/Users/Modify.html?id=<%$watcher->OwnerObj->id%>">
-<%$watcher->OwnerObj->RealName%></a>:
-%} else {
-Email address:
-%}
-<i><%$watcher->Email%></i>
-%}
-</ul>
-
-
-Administrative Cc:
-<UL>
-%# Print out a placeholder if there are none.
-%if ($admincc->Count == 0 ) {
-<li><i>none</i>
-% }
-
-%while (my $watcher=$admincc->Next) {
-<li><INPUT TYPE=CHECKBOX NAME="DelWatcher<%$watcher->id%>" UNCHECKED>
-%# account
-%if ($watcher->IsUser) { 
-<a href="<%$RT::WebPath%>/Admin/Users/Modify.html?id=<%$watcher->OwnerObj->id%>">
-<%$watcher->OwnerObj->RealName%></a>:
-%} else {
-Email address:
-%}
-<i><%$watcher->Email%></i>
-%}
-</UL>
-</TD>
-
-<TD VALIGN=TOP>
-<h3>New watchers</h3>
-Find people whose<BR>
-<& /Elements/SelectUsers &>
-
-<BR>
-Add new watchers:<br>
-
-% if ($msg) {
-<i><%$msg%></i>
-% } elsif ($Users) {
-<ul>
-% while (my $u = $Users->Next ) {
-<li><&/Elements/SelectWatcherType, Scope=>'queue', Name => "WatcherTypeUser".$u->Id &> <%$u->Name%>
-(<%$u->RealName%>)
-% }
-</ul>
-% }
-
-</TD>
-</TR>
-</TABLE>
-
-
-
-
-
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit, Label => 'Save Changes', Caption => "If you've updated anything above, be sure to" &>
-</form>
-
-<%INIT>
-
-my ($field, @results, $User, $Users, $watcher, $key, $msg);
-# {{{ Load the queue
-#If we get handed two ids, mason will make them an array. bleck.
-# We want teh first one. Just because there's no other sensible way
-# to deal
-
-
-
-my $QueueObj = new RT::Queue($session{'CurrentUser'});
-$QueueObj->Load($id) || Abort("Couldn't load queue '$id'");
-# }}}
-
-# {{{ Delete deletable watchers
-
-foreach $key (keys %ARGS) {
-    if (($key =~ /^DelWatcher(\d*)$/) and
-       ($ARGS{$key})) {
-       $RT::Logger->debug("Deleting watcher $1\n");
-       my ($code, $msg) = $QueueObj->DeleteWatcher($1);
-       
-       push @results, $msg;
-    }
-}
-# }}}
-
-# {{{ Add new watchers
-foreach $key (keys %ARGS) {
-    #They're in this order because otherwise $1 gets clobbered :/
-    if ( ($ARGS{$key} =~ /^(AdminCc|Cc)$/) and
-        ($key =~ /^WatcherTypeUser(\d*)$/) ) {
-       $RT::Logger->debug("Adding a watcher $1 to ".$ARGS{$key}."\n");
-       my ($code, $msg) = 
-         $QueueObj->AddWatcher(Type => $ARGS{$key},
-                                Owner => $1);
-       push @results, $msg;
-    }
-}
-
-# }}}
-
-
-
-my $admincc = $QueueObj->AdminCc;
-my $cc = $QueueObj->Cc;
-
-if (!$ARGS{'UserString'}) {
-$msg = "No users selected.";
- }
-else {
-    $Users = new RT::Users($session{'CurrentUser'});
-    $Users->Limit(FIELD => $ARGS{'UserField'},
-                 VALUE => $ARGS{'UserString'},
-                 OPERATOR => $ARGS{'UserOp'});
-     }
-</%INIT>
-
-<%ARGS>
-$UserField => 'Name'
-$UserOp => '='
-$UserString => undef
-$Type => undef
-$id => undef
-</%ARGS>
-
diff --git a/rt/webrt/Admin/Queues/Scrips.html b/rt/webrt/Admin/Queues/Scrips.html
deleted file mode 100755 (executable)
index 95b8c43..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Edit scrips' &>
-<& /Admin/Elements/QueueTabs, id => $QueueObj->Id &>
-
-<& /Elements/ListActions, actions => \@actions &>
-
-<& /Elements/TitleBoxStart, title => $description &>
-<h2>Global Scrips</h2>
-<& /Admin/Elements/ListGlobalScrips &>
-<BR> 
-  <FORM METHOD=POST ACTION="Scrips.html">
-    <INPUT TYPE=HIDDEN NAME=id VALUE=<%$id%>>
-<h2>Queue Scrips</h2>
-% if ($Scrips->Count > 0 ) {
-<TABLE>
-<TR>
-<TD>Delete
-</TD>
-<TD>
-</TR>
-% while (my $scrip = $Scrips->Next ) {
-<TR>
-<TD>
-<INPUT TYPE="CHECKBOX" NAME="DeleteScrip-<%$scrip->Id%>">
-</TD>
-<TD>
-<% $scrip->ConditionObj->Name %> 
-<% $scrip->ActionObj->Name %> with template
-<% $scrip->TemplateObj->Name %>
-</TD>
-</TR>
-% }
-</TABLE>
-% }
-<BR>
-<h2>Add a scrip to this queue</h2>
-Condition: <& /Admin/Elements/SelectScripCondition, Name => 'NewScripCondition' &>
-         Action: <& /Admin/Elements/SelectScripAction, Name => 'NewScripAction' &>
-         Template: <& /Admin/Elements/SelectTemplate, Name => 'NewScripTemplate', DefaultQueue => $id &>
-
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit &>
-</FORM>
-<%init>
-my (@actions, $description);
-
-my $Scrips = new RT::Scrips ($session{'CurrentUser'});
-unless ($id =~ /^\d+$/) {
-    Abort("$id isn't a valid Queue id.");
-}
-
-unless ($Scrips->LimitToQueue($id)) {
-    Abort("Couldn't load Scrips.");
-        }
-
-my $QueueObj = new RT::Queue($session{'CurrentUser'});
-$QueueObj->Load($id);
-
-if ($QueueObj->id) {
-    $description = "Modify scrips for queue '". $QueueObj->Name ."'";
-}
-else {
-    $description = "Modify global scrips";
-}
-
-
-if ($NewScripAction and $NewScripCondition) {
-    my $NewScrip = new RT::Scrip($session{'CurrentUser'});
-    
-    my ($retval, $msg) = $NewScrip->Create ( ScripAction => $NewScripAction,
-                                    ScripCondition => $NewScripCondition,
-                                    Stage => 'TransactionCreate',
-                                    Queue => $id,
-                                    Template => $NewScripTemplate);
-    if (defined $retval) {
-        push @actions, $msg;
-    }
-    else {
-        push @actions, $msg;
-    }
-}
-
-# {{{ deal with modifying and deleting existing scrips
-my ($key );
-foreach $key (keys %ARGS) {
-       # {{{ if we're trying to delete the scrip
-    if ($key =~ /^DeleteScrip-(\d+)/) {
-            my $id = $1;
-               my $scrip = new RT::Scrip($session{'CurrentUser'});
-               $scrip->Load($id);
-           my ($retval, $msg) = $scrip->Delete;
-           if ($retval) {
-               push @actions, 'Scrip deleted';
-           }
-           else {
-               push @actions, $msg;
-           }
-       }
-       # }}}
-
-    
-}
-# }}}
-</%init>
-
-<%ARGS>
-$NewScripCondition => undef
-$NewScripAction => undef
-$NewScripTemplate => undef
-$id => undef         #some identifier that a Queue could 
-</%ARGS>
diff --git a/rt/webrt/Admin/Queues/Template.html b/rt/webrt/Admin/Queues/Template.html
deleted file mode 100755 (executable)
index 61ee418..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-<& /Admin/Elements/Header, title => "Modify template ".$TemplateObj->id&>
-<& /Admin/Elements/QueueTabs, id => $Queue &>
-<& /Elements/ListActions, actions => \@results &>
-
-<& /Elements/TitleBoxStart, title => $title &>
-
-<FORM METHOD=POST ACTION="Template.html">
-%if ($create ) {
-<INPUT TYPE=HIDDEN NAME=template VALUE="new">
-% } else {
-<INPUT TYPE=HIDDEN NAME=template VALUE="<%$TemplateObj->Id%>">
-% }
-
-%# hang onto the queue id
-<INPUT TYPE=HIDDEN name="Queue" value="<%$Queue%>">
-
-
-Name: <input name="Name" VALUE="<%$TemplateObj->Name%>" SIZE=20><BR>
-Description: <input name="Description" VALUE="<%$TemplateObj->Description%>" SIZE=80><BR>
-
-<TEXTAREA NAME=Content ROWS=25 COLS=80 WRAP=SOFT>
-<%$TemplateObj->Content%></TEXTAREA>
-
-<& /Elements/TitleBoxEnd&>
-<&/Elements/Submit&>
-</FORM>
-
-
-
-<%INIT>
-
-my $TemplateObj = new RT::Template($session{'CurrentUser'});
-my  ($title, @results);
-
-if ($create) {
-  $title = "Create a template";
-}
-
-else {
-  if ($template eq 'new') {
-      my ($val, $msg) =  $TemplateObj->Create(Queue => $Queue, Name => $Name);
-      Abort("Could not create template: $msg") unless ($val);
-     push @results, $msg;
-     $title = 'Created template ' . $TemplateObj->Name(); 
-    }
-    else {
-       $TemplateObj->Load($template) || Abort('No Template');
-      $title = 'Editing template ' . $TemplateObj->Name(); 
-    }
-  
-    
-}
-if ($TemplateObj->Id()) {
-  $Queue = $TemplateObj->Queue;
-
-  my @attribs = qw( Description Content Queue Name);
-  my @aresults = UpdateRecordObject( AttributesRef => \@attribs, 
-                                    Object => $TemplateObj, 
-                                    ARGSRef => \%ARGS);
-  push @results, @aresults;
-}
-</%INIT>
-<%ARGS>
-$Queue => undef
-$template => undef
-$create => undef
-$Name => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Queues/Templates.html b/rt/webrt/Admin/Queues/Templates.html
deleted file mode 100755 (executable)
index 218d41d..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Edit templates for '.$Queue->Name &>
-<& /Admin/Elements/QueueTabs, id => $Queue->id &>
-
-<& /Elements/TitleBoxStart, title => 'Edit templates for '.$Queue->Name &>
-<UL>
-<LI><A href="Template.html?create=1&Queue=<%$Queue->id%>">Create a new template</A><BR><BR>
-
-%while  (my $TemplateObj = $Templates->Next) { 
-
-<LI><A HREF="Template.html?Queue=<%$id%>&template=<%$TemplateObj->id()%>"><%$TemplateObj->id()%>/<%$TemplateObj->Name%>: <%$TemplateObj->Description%></a><BR>
-
-%}
-
-<& /Elements/TitleBoxEnd &>
-<%INIT>
-
-my $Queue = new RT::Queue($session{'CurrentUser'});
-$Queue->Load($id);
-my $Templates = $Queue->Templates;
-
-</%INIT>
-<%ARGS>
-$id => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Queues/UserRights.html b/rt/webrt/Admin/Queues/UserRights.html
deleted file mode 100755 (executable)
index 75d9cb2..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Modify user rights for queue '. $QueueObj->Name &>
-<& /Admin/Elements/QueueTabs, id => $id &>  
-<& /Elements/ListActions, actions => \@results &>
-
-  <FORM METHOD=POST ACTION="UserRights.html">
-    <INPUT TYPE=HIDDEN NAME=id VALUE="<% $QueueObj->id %>">
-      
-<& /Elements/TitleBoxStart, title => 'Modify user rights for queue '.$QueueObj->Name &>
-      
-<TABLE>
-        
-%      while (my $UserObj = $Users->Next()) {
-  <TR ALIGN=RIGHT> 
-       <TD VALIGN=TOP>
-           <% $UserObj->Name %>
-                 </TD>
-         <TD>
-           <& /Admin/Elements/SelectRights, PrincipalObj => $UserObj,
-                   PrincipalType => 'User',
-                     Scope => 'Queue',
-                       QueueObj => $QueueObj &>
-         </TD>
-       </TR>
-% }
-      </TABLE>
-            
-      <& /Elements/TitleBoxEnd &>
-      <& /Elements/Submit, Caption => "Be sure to save your changes", Reset => 1 &>
-      
-  </FORM>
-  
-<%INIT>
-  #Update the acls.
-  my @results =  ProcessACLChanges(\@CheckACL, \%ARGS);
-
-# {{{ Deal with setting up the display of current rights.
-
-# {{{ do basic initialization.
-
-#Define vars used in html above
-my ($GroupObj);
-
-my ($right);
-
-
-if (!defined $id) {
-    Abort("No Queue defined");
-}
-
-my $QueueObj = new RT::Queue($session{'CurrentUser'});
-$QueueObj->Load($id) ||
-  Abort("Couldn't load queue $id");
-
-# Find out which users we want to display ACL selects for
-my $Users = new RT::Users($session{'CurrentUser'});
-$Users->LimitToPrivileged();
-
-# }}}
-    
-  
-# }}}
-    
-</%INIT>
-
-<%ARGS>
-$id => undef
-$UserString => undef
-$UserOp => undef
-$UserField => undef
-@CheckACL => undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Queues/index.html b/rt/webrt/Admin/Queues/index.html
deleted file mode 100755 (executable)
index 52dfb73..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Admin queues' &>
-<& /Admin/Elements/Tabs, current_tab => 'Admin/Queues/' &>
-
-
-<& /Elements/TitleBoxStart, title => 'Select a queue' &>
-
-<TABLE>
-<TR>
-<TD VALIGN=TOP>
-
-<FORM METHOD=POST ACTION="<% $RT::WebPath %>/Admin/Queues/">
-
-<input type="checkbox" name="FindDisabledQueues"> Include disabled queues in listing.
-<BR>
-<div align=right><input type=submit value="Go!"></div> 
-</FORM>
-</TD>
-<TD VALIGN=TOP>
-<UL>
-% if ($session{'CurrentUser'}->HasSystemRight('AdminQueue')) {
-<LI><A HREF="<%$RT::WebPath%>/Admin/Queues/Modify.html?Create=1">Create a new queue</A><BR><BR></LI>
-</UL>
-% }
-
-<%$caption%><BR>
-<UL>
-%if ($queues->Count == 0) {
-<LI> <i>No queues matching search criteria found.</i>
-% }
-%while ( $queue = $queues->Next) {
-<LI><A HREF="Modify.html?id=<%$queue->id%>"><%$queue->Name%></a></LI>
-%}
-
-</UL>
-</TD>
-</TR>
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-
-<%INIT>
-my ($queue, $caption);
-my $queues = new RT::Queues($session{'CurrentUser'});
-$queues->UnLimit();
-
-if ($FindDisabledQueues) {
-       $queues->{'find_disabled_rows'} = 1;
-}
-
-</%INIT>
-<%ARGS>
-$FindDisabledQueues => 0
-</%ARGS>
diff --git a/rt/webrt/Admin/Users/Modify.html b/rt/webrt/Admin/Users/Modify.html
deleted file mode 100755 (executable)
index b6daed4..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-<& /Admin/Elements/Header, Title => $title &>
-<& /Admin/Elements/UserTabs, id => $id, current_subtab => '/Admin/Elements/Modify.html?id='.$id &>
-
-<& /Elements/ListActions, actions => \@results &>
-
-<FORM ACTION="<%$RT::WebPath%>/Admin/Users/Modify.html" METHOD=POST>
-%if ($Create) {
-<INPUT TYPE=HIDDEN NAME=id VALUE="new">
-% } else {
-<INPUT TYPE=HIDDEN NAME=id VALUE="<%$UserObj->Id%>">
-% }
-
-<TABLE WIDTH=100% BORDER=0>
-<TR>
-
-<TD VALIGN=TOP ROWSPAN=2>
-<& /Elements/TitleBoxStart, title => 'Identity' &>
-
-Username: <input name="Name" value="<%$UserObj->Name%>"> <b>(required)</b> <BR>
-Email: <input name="EmailAddress" value="<%$UserObj->EmailAddress%>"><BR>
-Real Name: <input name="RealName" value="<%$UserObj->RealName%>"> <BR>
-Nickname: <input name="NickName" value="<%$UserObj->NickName%>">
-<BR>
-Unix login: <input name="Gecos" value="<%$UserObj->Gecos%>">
-<BR>
-Extra info: <textarea name="FreeformContactInfo" cols=20 rows=5><%$UserObj->FreeformContactInfo%></TEXTAREA>
-<& /Elements/TitleBoxEnd &>
-</TD>
-<TD VALIGN=TOP>
-<& /Elements/TitleBoxStart, title => 'Access control' &>
-<INPUT TYPE=HIDDEN NAME="SetEnabled" VALUE="1">
-<INPUT TYPE=CHECKBOX NAME="Enabled" VALUE="1" <%$EnabledChecked%>>
-Let this user access RT<BR>
-
-
-<INPUT TYPE=HIDDEN NAME="SetPrivileged" VALUE="1">
-<INPUT TYPE=CHECKBOX NAME="Privileged" VALUE="1" <%$PrivilegedChecked%>> Let this user be granted rights<BR>
-                   
-% unless ($RT::WebExternalAuth) {
-<TABLE>
-<TR>
-<TD ALIGN=RIGHT>
-New Password:
-</TD>
-<TD ALIGN=LEFT>
-<input type=password name="Pass1">
-</TD>
-</TR>
-<TR><TD ALIGN=RIGHT>
-Retype Password:
-</TD>
-<TD>
-<input type=password name="Pass2">
-</TD>
-</TR>
-</TABLE>
-% }
-<& /Elements/TitleBoxEnd &>
-</TD>
-<TR>
-
-<TD VALIGN=TOP>
-<& /Elements/TitleBoxStart, title => 'Location' &>
-Organization: <input name="Organization" value="<%$UserObj->Organization%>">
-<BR>
-Address1: <input name="Address1" value="<%$UserObj->Address1%>">
-<BR>
-Address2: <input name="Address2" value="<%$UserObj->Address2%>">
-<BR>
-City: <input name="City" value="<%$UserObj->City%>" size=14>
-
-State: <input name="State" value="<%$UserObj->State%>" size=3>
-
-Zip: <input name="Zip" value="<%$UserObj->Zip%>" size=9>
-<BR>
-Country: <input name="Country" value="<%$UserObj->Country%>">
-<BR>
-
-
-<& /Elements/TitleBoxEnd &>
-</TD>
-</TR>
-<TR>
-<TD COLSPAN=2 VALIGN=TOP>
-
-
-<& /Elements/TitleBoxStart, title => 'Phone numbers' &>
-Home: <input name="HomePhone" value="<%$UserObj->HomePhone%>" size=13>
-
-Work: <input name="WorkPhone" value="<%$UserObj->WorkPhone%>" size=13>
-
-Mobile: <input name="MobilePhone" value="<%$UserObj->MobilePhone%>" size=13>
-
-Pager: <input name="PagerPhone" value="<%$UserObj->PagerPhone%>" size=13>
-<& /Elements/TitleBoxEnd &>
-<BR>
-<& /Elements/TitleBoxStart, title => 'Comments about this user' &>
-<TEXTAREA name="Comments" COLS=80 ROWS=5 WRAP=VIRTUAL><%$UserObj->Comments%></TEXTAREA>
-<& /Elements/TitleBoxEnd &>
-
-
-%if ($UserObj->Privileged) {
-<BR>
-<& /Elements/TitleBoxStart, title => 'Signature' &>
-<TEXTAREA COLS=80 ROWS=5 name="Signature" WRAP=HARD>
-<%$UserObj->Signature%></TEXTAREA>
-<& /Elements/TitleBoxEnd &>
-% }
-
-</TD>
-
-</TR>
-</TABLE>
-
-
-<& /Elements/Submit &>
-</form>
-
-
-<%INIT>
-
-my $UserObj = new RT::User($session{'CurrentUser'});
-my ($title, $PrivilegedChecked, $EnabledChecked, $Disabled, $result, @results);
-
-my ($val, $msg);
-
-if ($Create) {
-    $title = "Create a new user";
-} 
-else {
-
-    if ($id eq 'new') {
-       ($val, $msg) = $UserObj->Create( Name => $Name,
-                                        EmailAddress => $ARGS{'EmailAddress'}
-                                      );
-       if ($val) {
-               push @results, $msg;
-       } else {
-               push @results, 'User could not be created: '. $msg;
-       }       
-       
-    }
-    else {
-       $UserObj->Load($id) || $UserObj->Load($Name) || Abort("Couldn't load user '$Name'");
-       $val = $UserObj->Id();
-    }
-
-    if ($val) {
-       $title = "Modify the user ". $UserObj->Name;
-    }  
-
-    # If the create failed
-    else {
-       $title = "Create a new user";
-       $Create = 1;
-    }    
-
-    
-
-}
-
-
-
-
-# If we have a user to modify, lets try. 
-if ($UserObj->Id) {
-    
-    my @fields = qw(Name Comments Signature EmailAddress FreeformContactInfo 
-                   Organization RealName NickName Lang EmailEncoding WebEncoding 
-                   ExternalContactInfoId ContactInfoSystem Gecos ExternalAuthId 
-                   AuthSystem HomePhone WorkPhone MobilePhone PagerPhone Address1
-               Address2 City State Zip Country 
-                  );
-    
-    my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields,
-                                           Object => $UserObj,
-                                           ARGSRef => \%ARGS );
-    push (@results,@fieldresults);
-
-
-# {{{ Deal with special fields: Privileged, Enabled and Password
-if  ( ($SetPrivileged) and ( $Privileged != $UserObj->Privileged) ) {
-my  ($code, $msg) = $UserObj->SetPrivileged($Privileged);
-     push @results, 'Privileged status: '. $msg;
-}
-
-#we're asking about enabled on the web page but really care about disabled.
-if ($Enabled == 1) {
-    $Disabled = 0;
-}      
-else {
-    $Disabled = 1;
-}
-if  ( ($SetEnabled) and ( $Disabled != $UserObj->Disabled) ) { 
-    my  ($code, $msg) = $UserObj->SetDisabled($Disabled);
-    push @results, 'Enabled status '. $msg;
-}
-
-
-#TODO: make this report errors properly
-if ((defined $Pass1) and ($Pass1 ne '') and ($Pass1 eq $Pass2) and (!$UserObj->IsPassword($Pass1))) {
-    my ($code, $msg);
-    ($code, $msg) = $UserObj->SetPassword($Pass1);
-    push @results, 'Password: '. $msg;
-}
-
-# }}}
-}
-
-
-# {{{ Do some setup for the ui
-unless ($UserObj->Disabled()) {
-    $EnabledChecked ="CHECKED";
-}
-
-if ($UserObj->Privileged()) {  
-    $PrivilegedChecked = "CHECKED";
-}
-
-# }}}
-</%INIT>
-
-
-<%ARGS>
-$id => undef
-$Name  => undef
-$Comments  => undef
-$Signature  => undef
-$EmailAddress  => undef
-$FreeformContactInfo => undef
-$Organization  => undef
-$RealName  => undef
-$NickName  => undef
-$Privileged => undef
-$SetPrivileged => undef
-$Enabled => undef
-$SetEnabled => undef
-$Lang  => undef
-$EmailEncoding  => undef
-$WebEncoding => undef
-$ExternalContactInfoId  => undef
-$ContactInfoSystem  => undef
-$Gecos => undef
-$ExternalAuthId  => undef
-$AuthSystem  => undef
-$HomePhone => undef
-$WorkPhone  => undef
-$MobilePhone  => undef
-$PagerPhone  => undef
-$Address1 => undef
-$Address2  => undef
-$City  => undef
-$State  => undef
-$Zip  => undef
-$Country => undef
-$Pass1 => undef
-$Pass2=> undef
-$Create=> undef
-</%ARGS>
diff --git a/rt/webrt/Admin/Users/Prefs.html b/rt/webrt/Admin/Users/Prefs.html
deleted file mode 100755 (executable)
index 4a9fc5c..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-<& /Elements/Header, Title=>"User view" &>
-
-<& /Elements/ViewUser, User=>$u &>
-
-%if ($session{CurrentUser} && ($session{CurrentUser}->Id == $id)) {
-       <& /Elements/TitleBoxStart, title => 'Signature'  &>
-<form method=post>
-<input type="hidden" name="id" value=<%$id%>>
-<TEXTAREA COLS=72 ROWS=4 WRAP=HARD NAME="Signature"><% $u->Signature %></TEXTAREA><br><br>
-<input type="submit" value="Update signature">
-</form>
-         <& /Elements/TitleBoxEnd &>
-         <form method=post>
-         Open tickets (from listing) in another window: <input type="checkbox" name="NewWindowOption" <%exists $session{NewWindowOption} && "CHECKED"%>><br>
-         Open tickets (from listing) in a new window: <input type="checkbox" name="AlwaysNewWindowOption" <%exists $session{AlwaysNewWindowOption} && "CHECKED"%>><br>
-         <input type="submit" name="NewWindowSetting" value="New window setting">
-         </form>
-%}
-
-       <& /Elements/TitleBoxStart, title => 'Email'  &>
-<form method=post>
-<input type="hidden" name="id" value="<%$id%>">
-<input name="Email" value="<% $u->EmailAddress %>"><input type="submit" value="Update email">
-</form>
-         <& /Elements/TitleBoxEnd &>
-       <& /Elements/TitleBoxStart, title => 'Real Name'  &>
-<form method=post>
-<input type="hidden" name="id" value="<%$id%>">
-<input name="RealName" value="<% $u->RealName %>"><input type="submit" value="Update name">
-</form>
-         <& /Elements/TitleBoxEnd &>
-
-       <& /Elements/TitleBoxStart, title => 'User ID'  &>
-<form method=post>
-<input type="hidden" name="id" value="<%$id%>">
-<input name="Name" value="<% $u->Name %>"><input type="submit" value="Update ID">
-</form>
-         <& /Elements/TitleBoxEnd &>
-
-%# TODO: alternative email addresses + merging users
-
-<%ARGS>
-$id => $session{CurrentUser} ? $session{CurrentUser}->Id : 0
-$Signature => undef
-$Email => undef
-$RealName => undef
-$Name => undef
-</%ARGS>
-
-<%INIT>
-require RT::User;
-my $u=RT::User->new($session{CurrentUser});
-$u->Load($id) || die "Couldn't load that user ($id)";
-if ($Signature) {
-my ($val, $msg)=$u->SetSignature($Signature);
-$RT::Logger->log(level=>($val ? 'info' : 'error'), message=>$msg);
-}
-
-if ($Email) {
-my ($val, $msg)=$u->SetEmailAddress($Email);
-$RT::Logger->log(level=>($val ? 'info' : 'error'), message=>$msg);
-}
-
-if ($RealName) {
-my ($val, $msg)=$u->SetRealName($RealName);
-$RT::Logger->log(level=>($val ? 'info' : 'error'), message=>$msg);
-}
-
-if ($Name) {
-my ($val, $msg)=$u->SetName($Name);
-$RT::Logger->log(level=>($val ? 'info' : 'error'), message=>$msg);
-}
-
-if ($ARGS{NewWindowSetting}) {
-if ($ARGS{NewWindowOption}) {
-$session{NewWindowOption}=1;
-} else {
-delete $session{NewWindowOption};
-}
-if ($ARGS{AlwaysNewWindowOption}) {
-$session{NewWindowOption}=1;
-$session{AlwaysNewWindowOption}=1;
-} else {
-delete $session{AlwaysNewWindowOption};
-}
-}
-
-</%INIT>
-
-
-
-
-
-
-
-
-
diff --git a/rt/webrt/Admin/Users/Rights.html b/rt/webrt/Admin/Users/Rights.html
deleted file mode 100644 (file)
index 3b94f91..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Placeholder
diff --git a/rt/webrt/Admin/Users/index.html b/rt/webrt/Admin/Users/index.html
deleted file mode 100755 (executable)
index 3835137..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-<& /Admin/Elements/Header, Title => 'Admin users' &>
-<& /Admin/Elements/Tabs, current_tab => 'Admin/Users/' &>
-
-
-<& /Elements/TitleBoxStart, title => 'Select a user' &>
-
-<TABLE>
-<TR>
-<TD VALIGN=TOP>
-
-<FORM METHOD=POST ACTION="<% $RT::WebPath %>/Admin/Users/">
-
-Find people whose <& /Elements/SelectUsers &><BR>
-<input type="checkbox" name="FindDisabledUsers"> Include disabled users in search.
-<BR>
-<div align=right><input type=submit value="Go!"></div> 
-</FORM>
-</TD>
-<TD VALIGN=TOP>
-<UL>
-% if ($session{'CurrentUser'}->HasSystemRight('AdminUsers')) {
-<LI><A HREF="<%$RT::WebPath%>/Admin/Users/Modify.html?Create=1">Create a new user</A><BR><BR></LI>
-</UL>
-% }
-
-<%$caption%><BR>
-<UL>
-%if ($users->Count == 0) {
-<LI> <i>No users matching search criteria found.</i>
-% }
-%while ( $user = $users->Next) {
-<LI><A HREF="Modify.html?id=<%$user->id%>"><%$user->Name || '(no name listed)'%></a></LI>
-%}
-
-</UL>
-</TD>
-</TR>
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-
-<%INIT>
-my ($user, $caption);
-my $users = new RT::Users($session{'CurrentUser'});
-
-if ($FindDisabledUsers) {
-       $users->{'find_disabled_rows'} = 1;
-}
-
-unless (defined $UserString) {
-    $users->LimitToPrivileged();
-    $caption = "Privileged users";
-}
-else {
-    $caption = "Users matching search criteria";
-
-  if ($UserString) {
-       $users->Limit( FIELD => $UserField,
-                       OPERATOR => $UserOp,
-                      VALUE => $UserString); 
-
-}
-}
-</%INIT>
-<%ARGS>
-$UserString => undef
-$UserOp => '='
-$UserField => 'Name'
-$IdLike => undef
-$EmailLike => undef
-$FindDisabledUsers => 0
-</%ARGS>
diff --git a/rt/webrt/Admin/index.html b/rt/webrt/Admin/index.html
deleted file mode 100755 (executable)
index 1ed973f..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-  <& /Admin/Elements/Header, Title => 'RT Administration' &>
-<& /Admin/Elements/Tabs &>
-
-
diff --git a/rt/webrt/Elements/Checkbox b/rt/webrt/Elements/Checkbox
deleted file mode 100755 (executable)
index 964c482..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Elements/Attic/Checkbox,v 1.1 2002-08-12 06:17:08 ivan Exp $
-<INPUT TYPE="Checkbox" NAME ="<%$Name%>" <%$IsChecked%>>
-
-<%ARGS>
-$Name => undef
-$Default => undef
-$True => undef
-$False => undef
-$IsChecked => undef
-</%ARGS>
-
-<%INIT>
-$IsChecked = 
-  ($Default && $Default =~ /checked/i)
-    ? " CHECKED " : "";
-1;
-</%INIT>
diff --git a/rt/webrt/Elements/CreateTicket b/rt/webrt/Elements/CreateTicket
deleted file mode 100644 (file)
index 1270f6e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<FORM ACTION="<% $RT::WebPath%>/Ticket/Create.html"><input type=submit value="New ticket in">&nbsp;<& /Elements/SelectNewTicketQueue &></FORM>
diff --git a/rt/webrt/Elements/CustomHomepageHeader b/rt/webrt/Elements/CustomHomepageHeader
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/rt/webrt/Elements/Error b/rt/webrt/Elements/Error
deleted file mode 100755 (executable)
index ec2cf51..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<& /Elements/Header, Code => $Code, Why => $Why &>
-<& /Elements/Tabs &>
-<& /Elements/TitleBoxStart, title => $Title &>
-<%$Why%>
-<br>
-<font size=-1>
-<%$Details%>
-</font>
-<& /Elements/TitleBoxEnd &>
-</body>
-</HTML>
-
-
-<%args>
-$Code => undef
-$Details => undef
-$Title => "RT Error"
-$Why => "the calling component did not specify why"
-</%args>
-
-<%INIT>
-$RT::Logger->error("WebRT: $Why ($Details)");
-</%INIT>
diff --git a/rt/webrt/Elements/Footer b/rt/webrt/Elements/Footer
deleted file mode 100755 (executable)
index 776c219..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-% if ($Debug) {
-<HR>
-<b>Time to display: <%time - $m->{'rt_base_time'} %></b>
-% }
-</BODY>
-</HTML>
-
-<%ARGS>
-$Debug => 0
-</%ARGS>
diff --git a/rt/webrt/Elements/GotoTicket b/rt/webrt/Elements/GotoTicket
deleted file mode 100644 (file)
index 21d2bcd..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<FORM ACTION="<%$RT::WebPath%>/Ticket/Display.html"><input type=submit value="Goto ticket">&nbsp;<input size=5 name=id></FORM>
diff --git a/rt/webrt/Elements/Header b/rt/webrt/Elements/Header
deleted file mode 100755 (executable)
index 471331b..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<HTML>
-<HEAD>
-<TITLE><%$Title%></TITLE>
-<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
-
-%# TODO this gets called from error. but I have no idea what it might
-%# be used for. can we whack it?  -jesse
-% if ($Code) {
-<META HTTP-EQUIV VALUE="<%$Code%> <%$Why%>">
-% }
-% if ($Refresh > 0) {
-<META HTTP-EQUIV="REFRESH" CONTENT="<%$Refresh%>">
-% }
-
-<link rel="stylesheet" href="<%$RT::WebPath%>/NoAuth/webrt.css" type="text/css">
-</HEAD>
-<BODY BGCOLOR="<%$BgColor%>">
-% if ($ShowBar) {
-<TABLE BORDER=0 WIDTH=100% CELLSPACING=0 BGCOLOR="#993333">
-<TR VALIGN=TOP>
-<TD><IMG SRC="<%$RT::LogoURL%>" alt="RT"></TD>
-<TD VALIGN=CENTER ALIGN=LEFT>
-<font size=+2 color="#ffffff">
-<B>
-<%$Title%>
-</B>
-</font>
-</TD>
-<TD ALIGN=RIGHT>
-<font color="#ffffff">
-% if ($session{'CurrentUser'}) {
-Signed in as <b><%$session{'CurrentUser'}->Name%></b>.<BR>
-% if ($session{'CurrentUser'}->HasSystemRight('ModifySelf')) {
-[<A class='inverse' HREF="<%$RT::WebPath%>/User/Prefs.html" >Preferences</A>] 
-% }
-% unless ($RT::WebExternalAuth) { 
-[<A class='inverse' HREF="<%$RT::WebPath%>/NoAuth/Logout.html">Logout</a>]
-% }
-% } else {
-Not logged in.
-% }
-</font>
-</TD>
-</TR>
-</TABLE>
-
-<BR>
-% }
-<%ARGS>
-$Title => 'WebRT'
-$Code => undef
-$Refresh => undef
-$Why => undef
-$BgColor => '#ffffff'
-$ShowBar => 1
-</%ARGS>
-<%INIT>
-$Title = "RT/$RT::rtname: ".$Title;
-</%INIT>
-
diff --git a/rt/webrt/Elements/ListActions b/rt/webrt/Elements/ListActions
deleted file mode 100755 (executable)
index 3fc9b0b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-% if (@actions ) {
-<& /Elements/TitleBoxStart, title => 'Results' &>
-<UL>
-% foreach my $action (@actions) {
-% next unless ($action);
-<LI><%$action%></LI>
-% }
-</UL>
-<& /Elements/TitleBoxEnd &>
-<BR>
-% }
-<%ARGS>
-@actions => undef
-</%ARGS>
diff --git a/rt/webrt/Elements/Login b/rt/webrt/Elements/Login
deleted file mode 100755 (executable)
index 27ec982..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<& /Elements/Header, Title=>"Login" , &>
-
-<DIV ALIGN=CENTER>
-% if ($Error) {
-<& /Elements/TitleBoxStart, title => 'Error' &>
-<% $Error %>
-<& /Elements/TitleBoxEnd &>
-% }
-<BR>
-<& /Elements/TitleBoxStart, width=> "40%", titleright => "RT $RT::VERSION for $RT::rtname", title => 'Login' ,
-contentbg=>"#cccccc" &>
-
-
-% unless ($RT::WebExternalAuth) {
-<FORM METHOD=POST >
-<TABLE BORDER=0 WIDTH=100%>
-<TR ALIGN=RIGHT>
-<TD ALIGN=RIGHT>Username:</TD><TD ALIGN=LEFT><input name=user value="<%$user%>"></TD></TR>
-<TR><TD ALIGN=RIGHT>Password:</TD><TD ALIGN=LEFT><input type=password name=pass></TD></TR>
-<TR><TD colspan=2 align=right>
-<input type=submit Value="Login">
-</TD></TR>
-</TABLE>
-<&/Elements/TitleBoxEnd&>
-% # From mason 1.0.1 forward, this doesn't work. in fact, it breaks things.
-% if (0) {
-% # The code below iterates through everything in the passed in arguments
-% # Preserving all the old parameters
-% # This would be easier, except mason is 'smart' and calls multiple values
-% # arrays rather than multiple hash keys
-% my $key; my $val;
-% foreach $key (keys %ARGS) {
-%  if (($key ne 'user') and ($key ne 'pass')) {
-%      if (ref($ARGS{$key}) =~ /ARRAY/) {
-%              foreach $val (@{$ARGS{$key}}) {
-<input type=hidden name="<%$key %>" value="<% $val %>">
-%              }
-%      }
-%      else {
-<input type="hidden" name="<% $key %>" value="<% $ARGS{$key} %>">
-%      }
-% }
-%}
-% }
-</FORM>
-% }
-</DIV>
-
-<BR>
-<!-- TODO: not yet implemented
-If you've forgotten your username or password, RT can <A
-href="/NoAuth/Reminder.html">send you a reminder</a>.
--->
-<BR>
-<HR>
-RT is &copy; Copyright 1996-2002 Jesse Vincent &lt;jesse@bestpractical.com&gt;.  It is
-distributed under <a href="http://www.gnu.org/copyleft/gpl.html">Version 2 of the GNU General Public License.</a>
-
-
-<%ARGS>
-$user => ""
-$pass => undef
-$goto => undef
-$Error => undef
-</%ARGS>
-
-<%INIT>
-SetContentType('text/html');
-</%INIT>
diff --git a/rt/webrt/Elements/MessageBox b/rt/webrt/Elements/MessageBox
deleted file mode 100644 (file)
index aa081a3..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-<TEXTAREA COLS=<%$Width%> ROWS=15 WRAP=HARD NAME="<%$Name%>"><% $Default %><%$message%><%$signature%></TEXTAREA>
-<%INIT>
-
-my ($message);
-
-if ($MessageURI) {
-       my $code;
-       ($code, $Default)=RT::Link->GetContent($MessageURI);
-}
-if ($QuoteTransaction) {
-    my $transaction=RT::Transaction->new($session{'CurrentUser'});
-    $transaction->Load($QuoteTransaction);
-    $message=$transaction->Content(Quote => 1);
-}
-
-my $signature = '';
-if ($session{'CurrentUser'}->UserObj->Signature) {
-       $signature = "-- \n".$session{'CurrentUser'}->UserObj->Signature;
-}
-
-</%INIT>
-<%ARGS>
-$QuoteTransaction => undef
-$Name => 'Content'
-$Default => ''
-$DefaultURI => undef
-$Width => 72
-$MessageURI => undef
-</%ARGS>
-
diff --git a/rt/webrt/Elements/MyRequests b/rt/webrt/Elements/MyRequests
deleted file mode 100644 (file)
index 6781729..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-<& /Elements/TitleBoxStart, title => "25 highest priority tickets I requested..." &>
-<TABLE BORDER=0 cellspacing=0 cellpadding=1 WIDTH=100%>
-<TR>
-<TH align=right>#</TH>
-<TH align=left>Subject</TH>
-<TH align=left>Queue</TH>
-<TH align=left>Status</TH>
-<TH align=left>Owner</TH>
-<TH>&nbsp;</TH>
-</TR>
-% while (my $Ticket = $MyTickets->Next) {
-<TR>
-<TD ALIGN=RIGHT>
-<%$Ticket->Id%>
-</TD>
-<TD>
-<A HREF="<% $RT::WebPath %>/Ticket/Display.html?id=<%$Ticket->Id%>">
-<%$Ticket->Subject || '[no subject]'%>
-</A>
-</TD>
-<TD>
-<%$Ticket->QueueObj->Name%>
-</TD><TD>
-<%$Ticket->Status%>
-</TD><TD>
-<%$Ticket->OwnerObj->Name%>
-</TD><TD ALIGN=RIGHT>
-[<A HREF="<% $RT::WebPath %>/Ticket/Display.html?id=<%$Ticket->Id%>">Display</A>]
-</TD>
-</TR>
-% }
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-
-
-<%INIT>
-my $MyTickets;
-$MyTickets = new RT::Tickets ($session{'CurrentUser'});
-$MyTickets->LimitRequestor(VALUE => $session{'CurrentUser'}->EmailAddress);
-$MyTickets->LimitStatus(VALUE => "open");
-$MyTickets->LimitStatus(VALUE => "new");
-$MyTickets->OrderBy(FIELD => 'Priority', ORDER => 'DESC');
-$MyTickets->RowsPerPage(25);
-
-</%INIT>
diff --git a/rt/webrt/Elements/MyTickets b/rt/webrt/Elements/MyTickets
deleted file mode 100644 (file)
index 64a2ba7..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-<& /Elements/TitleBoxStart, title => "25 highest priority tickets I own..." &>
-<TABLE BORDER=0 cellspacing=0 cellpadding=1 WIDTH=100%>
-<TR>
-<TH ALIGN=RIGHT>#</TH>
-<TH ALIGN=LEFT>Subject</TH>
-<TH ALIGN=LEFT>Queue</TH>
-<TH ALIGN=LEFT>Status</TH>
-<TH ALIGN=LEFT>&nbsp;</TH>
-</TR>
-% while (my $Ticket = $MyTickets->Next) {
-<TR>
-<TD ALIGN=RIGHT>
-<%$Ticket->Id%>
-</TD>
-<TD>
-<A HREF="<% $RT::WebPath %>/Ticket/Display.html?id=<%$Ticket->Id%>">
-<%$Ticket->Subject || '[no subject]'%>
-</A>
-</TD>
-<TD>
-<%$Ticket->QueueObj->Name%>
-</TD><TD>
-<%$Ticket->Status%>
-</TD>
-<TD ALIGN=RIGHT>
-[<A HREF="<% $RT::WebPath %>/Ticket/Update.html?id=<%$Ticket->Id%>">Update</A>]
-</TD>
-</TR>
-% }
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-
-
-<%INIT>
-my $MyTickets;
-$MyTickets = new RT::Tickets ($session{'CurrentUser'});
-$MyTickets->LimitOwner(VALUE => $session{'CurrentUser'}->Id);
-$MyTickets->LimitStatus(VALUE => "open");
-$MyTickets->LimitStatus(VALUE => "new");
-$MyTickets->OrderBy(FIELD => 'Priority', ORDER => 'DESC');
-$MyTickets->RowsPerPage(25);
-
-</%INIT>
diff --git a/rt/webrt/Elements/Quicksearch b/rt/webrt/Elements/Quicksearch
deleted file mode 100644 (file)
index d44c996..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-<& /Elements/TitleBoxStart, title => "Find new/open tickets", titleright => "<A class='inverse' href=\"$RT::WebPath/Search/Listing.html?NewSearch=1\">Advanced Search</A>" &>
-
-<TABLE BORDER=0 cellspacing=0 cellpadding=1 WIDTH=100%>                       
-<tr>                                                                          
-       <th align=left>Queue</th>                                         
-       <th align=left><font size=-1>New</font></th>
-       <th align=left><font size=-1>Open</font></th>          
-       <th align=left><font size=-1>Stalled</font></th>          
-</tr>
-
-<%PERL>
-while (my $queue = $Queues->Next) {
-     $Tickets->ClearRestrictions;                                           
-     $Tickets->LimitStatus(VALUE => "open");                                
-     $Tickets->LimitQueue(VALUE => $queue->id, OPERATOR => '=');            
-     my $open = $Tickets->Count();
-
-     $Tickets->ClearRestrictions;                                           
-     $Tickets->LimitStatus(VALUE => "new");
-     $Tickets->LimitQueue(VALUE => $queue->id, OPERATOR => '=');            
-     my $new = $Tickets->Count();
-
-     $Tickets->ClearRestrictions; 
-     $Tickets->LimitStatus(VALUE => "stalled");
-     $Tickets->LimitQueue(VALUE => $queue->id, OPERATOR => '=');            
-     my $stalled = $Tickets->Count();
-</%PERL>
-<TR><TD><A HREF="<% $RT::WebPath%>/Search/Listing.html?ValueOfStatus=open&ValueOfStatus=new&StatusOp=%3D&QueueOp=%3D&ValueOfQueue=<%$queue->Id%>&RowsPerPage=50&NewSearch=1"><%$queue->Name%></a></TD>
-<TD><%$new%></TD>
-<TD><%$open%></TD>
-<TD><%$stalled%></TD>
-</TR>
-% }
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-
-<%INIT>
-my $Queues = new RT::Queues($session{'CurrentUser'}); 
-$Queues->UnLimit();
-my $Tickets = new RT::Tickets ($session{'CurrentUser'});
-</%INIT>
diff --git a/rt/webrt/Elements/Refresh b/rt/webrt/Elements/Refresh
deleted file mode 100644 (file)
index 6949d8c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<SELECT NAME="<%$Name%>">
-<OPTION VALUE="-1"
-%unless ($Default) {
- SELECTED
-%}
->Don't refresh this page.</OPTION>
-%foreach my $value (@refreshevery) {
-<OPTION VALUE="<%$value%>"
-% if ($value == $Default) {
-SELECTED 
-% }
->Refresh this page every <%$value/60%> minutes.
-%}
-</SELECT>
-
-<%INIT>
-my @refreshevery = qw(120 300 600 1200 3600 7200);
-</%INIT>
-<%ARGS>
-$Name => undef
-$Default => undef
-</%ARGS>
diff --git a/rt/webrt/Elements/Section b/rt/webrt/Elements/Section
deleted file mode 100755 (executable)
index 067311d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<TABLE WIDTH=100%>
-<TR>
-<TD>
-<font size=+4><%$title%></font>
-</TD>
-</TR>
-</TABLE>
-
-<%ARGS>
-$title => undef
-</%ARGS>
\ No newline at end of file
diff --git a/rt/webrt/Elements/SelectBoolean b/rt/webrt/Elements/SelectBoolean
deleted file mode 100755 (executable)
index 93b78ce..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Elements/Attic/SelectBoolean,v 1.1 2002-08-12 06:17:08 ivan Exp $
-<SELECT NAME ="<%$Name%>">
-<OPTION VALUE="<%$TrueVal%>" <%$TrueDefault%>><%$True%></OPTION>
-<OPTION VALUE="<%$FalseVal%>" <%$FalseDefault%>><%$False%></OPTION>
-</SELECT>
-
-<%ARGS>
-$Name => undef
-$True => "is"
-$Default => 'true'
-$TrueVal => 1
-$FalseVal => 0
-$False => "isn't"
-</%ARGS>
-
-<%INIT>
-my ($TrueDefault, $FalseDefault);
-if ($Default && $Default !~ /true/i) {
-       $FalseDefault = "SELECTED";
-}
-else {
-       $TrueDefault = "SELECTED";
-}
-</%INIT>
diff --git a/rt/webrt/Elements/SelectDate b/rt/webrt/Elements/SelectDate
deleted file mode 100755 (executable)
index 6fafbf1..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-<INPUT NAME="<%$Name%>" VALUE="<%$Default%>" size=16> 
-
-<%init>
-unless ((defined $Default) or 
-       ($current <= 0)) {
-       my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
-                                            localtime($current);
-        $Default = sprintf("%04d-%02d-%02d %02d:%02d",                         
-                           $year+1900,$mon+1,$mday,                            
-                           $hour,$min);   
-}
-
-unless ($Name) {
-       $Name = $menu_prefix. "_Date";
-}
-</%init>
-
-<%args>
-
-$ShowTime => undef
-$menu_prefix=>''
-$current=>time
-$Default => undef
-$Name => undef
-</%args>
diff --git a/rt/webrt/Elements/SelectDateRelation b/rt/webrt/Elements/SelectDateRelation
deleted file mode 100755 (executable)
index c5849c8..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Elements/Attic/SelectDateRelation,v 1.1 2002-08-12 06:17:08 ivan Exp $
-<SELECT NAME ="<%$Name%>">
-<OPTION VALUE="&lt;"><%$Before%></OPTION>
-<OPTION VALUE="="><%$On%></OPTION>
-<OPTION VALUE="&gt;"><%$After%></OPTION>
-</SELECT>
-
-<%ARGS>
-$Name => undef
-$Default => undef
-$Before => 'Before'
-$On =>         'On'
-$After => 'After'
-</%ARGS>
diff --git a/rt/webrt/Elements/SelectDateType b/rt/webrt/Elements/SelectDateType
deleted file mode 100755 (executable)
index 65c0e9b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<SELECT NAME="<%$Name%>">
-<OPTION VALUE="Created">Created</OPTION>
-<OPTION VALUE="Started">Started</OPTION>
-<OPTION VALUE="Resolved">Resolved</OPTION>
-<OPTION VALUE="Told">Last Contacted</OPTION>
-<OPTION VALUE="LastUpdated">Last Updated</OPTION>
-<OPTION VALUE="StartsBy">Starts By</OPTION>
-<OPTION VALUE="Due">Due</OPTION>
-</SELECT>
-<%ARGS>
-$Name => 'DateType'
-</%ARGS>
diff --git a/rt/webrt/Elements/SelectEqualityOperator b/rt/webrt/Elements/SelectEqualityOperator
deleted file mode 100755 (executable)
index f93dc1a..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Elements/Attic/SelectEqualityOperator,v 1.1 2002-08-12 06:17:08 ivan Exp $
-<SELECT NAME ="<%$Name%>">
-% while (my $option = shift @Options) {
-% my $value = shift @Values;
-<OPTION VALUE="<%$value%>"
-% if ($Default eq '$value') {
-SELECTED
-% }
-><%$option%></OPTION>
-% }
-</SELECT>
-
-<%ARGS>
-$Name => undef
-@Options => ('less than', 'equal to', 'greater than', 'not equal to')
-@Values => qw(< = > !=)
-$Default => undef
-</%ARGS>
diff --git a/rt/webrt/Elements/SelectKeyword b/rt/webrt/Elements/SelectKeyword
deleted file mode 100644 (file)
index c4bd9e1..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-<SELECT NAME=<%$Name%> <%$Size%> <%$Multiple%>>
-<OPTION VALUE="">-</OPTION>
-<OPTION VALUE="NULL">(empty)</OPTION>
-%   foreach my $kid ( keys %{$Descendents} ) {
-<OPTION VALUE="<% $kid %>" 
-%if ($kid == $Default) {
-SELECTED
-%}
-><% $Descendents->{$kid} %></OPTION>
-% }
-</SELECT>
-
-
-<%INIT>
-
-unless (defined $KeywordObj) {
-    $KeywordObj = new RT::Keyword($session{'CurrentUser'});
-    $KeywordObj->Load($Root);
-}
-my $Descendents = $KeywordObj->Descendents();
-
-if ($Multiple) {
-       $Multiple = "MULTIPLE";
-}
-if ($Size) {
-       $Size="SIZE=$Size";
-}      
-
-
-</%INIT>
-<%ARGS>
-$Multiple => undef
-$Size => undef
-$Name => 'Keyword'
-$KeywordObj => undef
-$Root => 0
-$Default => undef
-</%ARGS>
diff --git a/rt/webrt/Elements/SelectKeywordOptions b/rt/webrt/Elements/SelectKeywordOptions
deleted file mode 100644 (file)
index f56dfe5..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<PERL>
-while (my $keyword = $keywords->Next()) {
-    my ($selected);
-    if $keyword->Id == $default
-</PERL>
-<OPTION VALUE="<%$keyword->id%>"><% '-' x $depth %><%$keyword->Name%></OPTION>
-<& SelectKeywordOptions, depth => ($depth+1), root => $keyword->id &>
-%}
-<%INIT>
-
-my $keywords = new RT::Keywords($session{'CurrentUser'});
-$keywords->LimitToParent($root);
-
-</%INIT>
-<%ARGS>
-$root => undef
-$depth => 0
-</%ARGS>
\ No newline at end of file
diff --git a/rt/webrt/Elements/SelectLinkType b/rt/webrt/Elements/SelectLinkType
deleted file mode 100644 (file)
index 22cde3d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Elements/Attic/SelectLinkType,v 1.1 2002-08-12 06:17:08 ivan Exp $
-
-<SELECT NAME ="<%$Name%>">
-% foreach ('MemberOf', 'DependsOn', 'RefersTo') { # TODO: Merging!
-<OPTION VALUE="<%$_%>"><%$_%></OPTION>
-% }
-</SELECT>
-
-<%ARGS>
-$Name => "LinkType"
-$Default => undef
-</%ARGS>
-
-<%INIT>
-# TODO handle Default
-</%INIT>
diff --git a/rt/webrt/Elements/SelectMatch b/rt/webrt/Elements/SelectMatch
deleted file mode 100644 (file)
index 7f3a94f..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Elements/Attic/SelectMatch,v 1.1 2002-08-12 06:17:08 ivan Exp $
-<SELECT NAME ="<%$Name%>">
-<OPTION VALUE="LIKE" <%$LikeDefault%>><%$Like%></OPTION>
-<OPTION VALUE="NOT LIKE" <%$NotLikeDefault%>><%$NotLike%></OPTION>
-<OPTION VALUE="=" <%$TrueDefault%>><%$True%></OPTION>
-<OPTION VALUE="!=" <%$FalseDefault%>><%$False%></OPTION>
-</SELECT>
-
-<%ARGS>
-$Name => undef
-$Like => 'contains'
-$NotLike => "doesn't contain"
-$True => 'is'
-$False => "isn't"
-$Default => undef
-</%ARGS>
-<%INIT>
-my ($TrueDefault, $FalseDefault, $LikeDefault, $NotLikeDefault);
-if ($Default && $Default !~ /true/i) {
-       $FalseDefault = "SELECTED";
-}
-elsif ($Default && $Default !~ /false/i) {
-       $TrueDefault = "SELECTED";
-} 
-elsif ($Default && $Default !~ /notlike/i) {
-       $NotLikeDefault = "SELECTED";
-}
-else {
-       $LikeDefault = "SELECTED";
-}
-</%INIT>
diff --git a/rt/webrt/Elements/SelectNewTicketQueue b/rt/webrt/Elements/SelectNewTicketQueue
deleted file mode 100755 (executable)
index 9f5cd28..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Elements/Attic/SelectNewTicketQueue,v 1.1 2002-08-12 06:17:08 ivan Exp $
-<& SelectQueue, Name => $Name, Verbose => $Verbose, Default => $Default,
-       ShowAllQueues => 0, ShowNullOption => 0 &>
-
-<%ARGS>
-$Name => 'Queue'
-$Verbose => undef
-$Default => undef
-</%ARGS>
diff --git a/rt/webrt/Elements/SelectOwner b/rt/webrt/Elements/SelectOwner
deleted file mode 100755 (executable)
index 59ebf36..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<SELECT NAME="<%$Name%>">
-<OPTION VALUE="">-</OPTION>
-<OPTION <% ($RT::Nobody->Id() == $Default) && "SELECTED" %> VALUE="<%$RT::Nobody->Id%>"><%$RT::Nobody->Name%></OPTION>
-%while ( my $User = $Users->Next())  {
-% if ((!defined $QueueObj) || ($User->HasQueueRight(Right => 'OwnTicket', QueueObj => $QueueObj, TicketObj => $TicketObj))){
-<OPTION VALUE="<%$User->Id()%>" <% ($User->Id() == $Default) && "SELECTED" %>><%$User->Name()%></OPTION>
-% }
-%}
-</SELECT>
-
-<%INIT>
-my $Users = RT::Users->new($session{CurrentUser});
-$Users->LimitToPrivileged;
-</%INIT>
-
-<%ARGS>
-$QueueObj => undef
-$Name => undef
-$Default => undef
-$User => undef
-$TicketObj => undef
-</%ARGS>
diff --git a/rt/webrt/Elements/SelectQueue b/rt/webrt/Elements/SelectQueue
deleted file mode 100755 (executable)
index d63b17b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Elements/Attic/SelectQueue,v 1.1 2002-08-12 06:17:08 ivan Exp $
-
-% if ($Lite) {
-<INPUT NAME="<%$Name%>" size=25 DEFAULT="<%$d->Name%>">
-% } else {
-<SELECT NAME ="<%$Name%>">
-% if ($ShowNullOption) {
-<OPTION VALUE="">-</OPTION>
-% }
-% while (my $queue=$q->Next) {
-% if ($ShowAllQueues || $queue->CurrentUserHasRight('CreateTicket')) {
-<OPTION VALUE="<%$queue->Id%>" <%($queue->Id == $Default) && 'SELECTED'%>><%$queue->Name%>
-%   if (($Verbose) and ($queue->Description) ){
-(<%$queue->Description%>)
-%  }
-</OPTION>
-% }
-% }
-</SELECT>
-% }
-<%ARGS>
-$ShowNullOption => 1
-$ShowAllQueues => 1
-$Name => undef
-$Verbose => undef
-$Default => undef
-$Lite => 0
-</%ARGS>
-
-<%INIT>
-
-my $q=new RT::Queues($session{'CurrentUser'});
-$q->UnLimit;
-
-my $d = new RT::Queue($session{'CurrentUser'});
-$d->Load($Default);
-
-</%INIT>
diff --git a/rt/webrt/Elements/SelectResultsPerPage b/rt/webrt/Elements/SelectResultsPerPage
deleted file mode 100644 (file)
index 0699c68..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Elements/Attic/SelectResultsPerPage,v 1.1 2002-08-12 06:17:08 ivan Exp $
-
-%# TODO: Better default handling
-
-<SELECT NAME ="<%$Name%>">
-% foreach my $value (@values) {
-<OPTION VALUE="<%$value%>" <% $value == $Default && 'SELECTED' %>>
-<% shift @labels %>
-</OPTION>
-% }
-</SELECT>
-
-<%INIT>
-my @values = qw(0 10 25 50 100);
-my @labels = qw(Unlimited 10 25 50 100);
-</%INIT>
-<%ARGS>
-
-$Name => undef
-$Default => 50
-
-</%ARGS>
diff --git a/rt/webrt/Elements/SelectSortOrder b/rt/webrt/Elements/SelectSortOrder
deleted file mode 100644 (file)
index 6dc9006..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<SELECT NAME="<%$Name%>">
-%foreach my $order (@orders) {
-<OPTION VALUE="<%$order%>" <%$order eq $Default && 'SELECTED' %>>
-<% shift @order_names %>
-</OPTION>
-% }
-</SELECT>
-
-<%INIT>
-my @orders = qw (ASC DESC);
-my @order_names = qw (Ascending Descending);
-
-</%INIT>
-
-<%ARGS>
-$Name => 'SortOrder'
-$Default => 'ASC'
-</%ARGS>
diff --git a/rt/webrt/Elements/SelectStatus b/rt/webrt/Elements/SelectStatus
deleted file mode 100755 (executable)
index 92df7c6..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Elements/Attic/SelectStatus,v 1.1 2002-08-12 06:17:08 ivan Exp $
-
-<SELECT NAME ="<%$Name%>">
-<OPTION VALUE="">-</OPTION>
-%foreach my $status (@status) {
-<OPTION VALUE="<%$status%>" <%($Default eq $status) && 'SELECTED'%>><%$status%></OPTION>
-% }
-</SELECT>
-<%ONCE>
-my $queue = new RT::Queue($session{'CurrentUser'});
-my @status = $queue->StatusArray();
-</%ONCE>
-<%ARGS>
-$Name => undef
-$Default => undef
-</%ARGS>
diff --git a/rt/webrt/Elements/SelectTicketSortBy b/rt/webrt/Elements/SelectTicketSortBy
deleted file mode 100644 (file)
index 02021de..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-<SELECT NAME="<%$Name%>">
-% foreach my $field (@sortfields) {
-<OPTION VALUE="<%$field%>" <%$field eq $Default && 'SELECTED'%>><%$field%></OPTION>
-% }
-</SELECT>
-
-<%INIT>
-my $tickets = new RT::Tickets($session{'CurrentUser'});
-my @sortfields = $tickets->SortFields();
-
-</%INIT>
-<%ARGS>
-$Name => 'SortTicketsBy'
-$Default => 'id'
-</%ARGS>
diff --git a/rt/webrt/Elements/SelectUsers b/rt/webrt/Elements/SelectUsers
deleted file mode 100755 (executable)
index f517d35..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<select name="UserField">
-<option value="Name">User Id
-<option value="EmailAddress">Email
-<option value="RealName">Name
-<option value="Organization">Organization
-</select>
-<& /Elements/SelectMatch, Name=> 'UserOp' &>
-<input size=8 name="UserString">
diff --git a/rt/webrt/Elements/SelectWatcherType b/rt/webrt/Elements/SelectWatcherType
deleted file mode 100644 (file)
index 5a85519..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Elements/Attic/SelectWatcherType,v 1.1 2002-08-12 06:17:08 ivan Exp $
-%# portions Copyright 2000 Tobias Brox <tobix@fsck.com>
-%# Request Tracker is Copyright 1996-2000 Jesse Vincent <jesse@fsck.com>
-
-<SELECT NAME ="<%$Name%>">
-<OPTION VALUE="none">-</OPTION>
-%# Make nice options:
-%for my $option (@types) {
-<OPTION VALUE="<%$option%>" <%$option eq $Default && "SELECTED"%>><%$option%></OPTION>
-%}
-</SELECT>
-
-<%INIT>
-my @types;
-if ($Scope =~ 'queue') {
-   @types = qw(Cc AdminCc);
-}
-else { 
-   @types = qw(Requestor Cc AdminCc);
-}
-</%INIT>
-<%ARGS>
-$Default=>undef
-$Scope => 'ticket'
-$Name => 'WatcherType'
-</%ARGS>
diff --git a/rt/webrt/Elements/ShadedBox b/rt/webrt/Elements/ShadedBox
deleted file mode 100755 (executable)
index 334b579..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<div align="left"><span class=label><%$title |n %></span><br><b><%$content |n %></b></div>
-<%ARGS>
-$title => undef
-$content => "&nbsp;"
-</%ARGS>
diff --git a/rt/webrt/Elements/Submit b/rt/webrt/Elements/Submit
deleted file mode 100755 (executable)
index 7b75e9e..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-<TABLE WIDTH=100% BGCOLOR="<%$color%>" CELLSPACING=0 BORDER=0 CELLPADDING=0 >
-<TR>
-% if ($Reset) {
-<TD>
-<FONT COLOR=#ffd800 >
-<INPUT TYPE=RESET VALUE="<%$ResetLabel%>">
-</FONT>
-</TD>
-%}
-<TD>
-&nbsp;
-</TD>
-<TD ALIGN=RIGHT VALIGN=CENTER>
-
-<FONT COLOR=#ffd800>
-
-% if ($AlternateLabel) {
-<B><%$AlternateCaption%>
-<INPUT TYPE=SUBMIT
-%if ($Name) {
-NAME="<%$Name%>"
-%}
-VALUE='<%$AlternateLabel%>'></B>
-% }
-
-<B><%$Caption%>
-<INPUT TYPE=SUBMIT
-%if ($Name) {
-NAME="<%$Name%>"
-% }
- VALUE='<%$Label%>'></B></FONT>
-</TD>
-</TR>
-</TABLE>
-<%ARGS>
-$color => "#336699"
-$Caption => undef
-$AlternateCaption => undef
-$AlternateLabel => undef
-$Label => 'Submit'
-$Name => undef
-$Reset => undef
-$ResetLabel => 'Reset'
-</%ARGS>
diff --git a/rt/webrt/Elements/Tabs b/rt/webrt/Elements/Tabs
deleted file mode 100755 (executable)
index 6eacf39..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-<TABLE WIDTH=100%>
-    <TR>
-      <TD VALIGN=TOP>
-       <TABLE cellspacing=1>
-         <TR>
-% foreach $tab (sort keys %{$toptabs}) {
-           <TD ALIGN=CENTER>
-             <font size=+1>
-               [<A 
-% if ($current_toptab eq $toptabs->{$tab}->{'path'}) {
-class='currenttab'
-% } 
-       HREF="<%$RT::WebPath%>/<% $toptabs->{$tab}->{'path'}%>"><% $toptabs->{$tab}->{'title'}%></A>]
-
-
-             </font>
-           </TD>
-% }
-         </TR>
-       </TABLE>
-<BR>
-% if ($tabs_scalar) {
-<% $tabs_scalar |n%>
-% }
-% if ($tabs) {
-       
-       <TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0>    
-         <TR>
-% foreach $tab (sort keys %{$tabs}) {
-           <TD ALIGN=CENTER VALIGN=TOP>
-[<A 
-% if ($current_tab eq $tabs->{$tab}->{'path'}) {
-class='currenttab' 
-% } 
-HREF="<%$RT::WebPath%>/<% $tabs->{$tab}->{'path'}%>"><% $tabs->{$tab}->{'title'}%></A>]</TD>
-%}
-         </TR>
-       </TABLE>
-%}
-
-<BR>
-% if ($subtabs_scalar) {
-<% $subtabs_scalar |n%>
-% }
-% if ($subtabs) {
-       <TABLE> 
-         <TR>
-% foreach $tab (sort keys %{$subtabs}) {
-           <TD ALIGN=CENTER>
-             [<A HREF="<%$RT::WebPath%>/<% $subtabs->{$tab}->{'path'}%>"><% $subtabs->{$tab}->{'title'}%></A>]
-           </TD>
-%}
-         </TR>
-       </TABLE>
-%}
-      </TD>
-      <TD VALIGN=TOP ALIGN=RIGHT>
-<TABLE>
-<TR>
-
-% foreach $action (sort keys %{$topactions}) {
-<TD><font size=-1><%$topactions->{"$action"}->{'html'} |n %></font></TD>
-% }
-</TR>
-</TABLE>
-       
-
-       
-% if ($actions) {
-<TABLE><TR>
-%  foreach $action (sort keys %{$actions}) {
-<TD>
-<FONT SIZE=-1>
-% if ($actions->{"$action"}->{'html'}) {
-<%$actions->{"$action"}->{'html'} |n%>
-% } else {
-<A HREF="<%$RT::WebPath%>/<% $actions->{$action}->{'path'}%>"><% $actions->{$action}->{'title'}%></A>
-% }
-</FONT>
-</TD>
-%  }
-</TR></TABLE>
-% }
-       
-% if ($subactions_scalar) {
-<% $subactions_scalar |n%>
-% }
-% if ($subactions) {
-<BR>|&nbsp;
-%  foreach $action (sort keys %{$subactions}) {
-<%$subactions->{"$action"}->{'html'} |n%>&nbsp;|
-%  }
-% }
-      </TD>
-    </TR>
-  </TABLE>
-
-
-<%INIT>
-my ($tab, $action);
-my $toptabs = {    A => { title => 'Home',
-                           path => '',
-                         },
-                    B => { title => 'Search',
-                        path => 'Search/Listing.html'
-                      },
-
-                    D => { title => 'Configuration',
-                           path => 'Admin/'
-                         }
-                 };
-                    
-
-my $topactions = {
-       A => { html => $m->scomp('/Elements/CreateTicket')      
-               },
-       B => { html => $m->scomp('/Elements/GotoTicket') 
-               }
-       };
-</%INIT>
-<%ARGS>
-$current_toptab =>  "none"
-$current_tab => "none"
-$current_subtab => "none"
-$tabs => undef
-$tabs_scalar => undef
-$subtabs => undef
-$actions => undef
-$subactions => undef
-$subtabs_scalar => undef
-$subactions_scalar => undef
-</%ARGS>
-
diff --git a/rt/webrt/Elements/TitleBoxEnd b/rt/webrt/Elements/TitleBoxEnd
deleted file mode 100755 (executable)
index bdd4106..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-</TD></TR></TABLE>
-</TD>
-</TR>
-<TR><TD COLSPAN=4><IMG SRC="<%$RT::WebImagesURL%>spacer.gif" height=1 ALT="&nbsp;"width=1></TD>
-</TABLE>
-<%ARGS>
-$title => undef
-$content => undef
-</%ARGS>
-
diff --git a/rt/webrt/Elements/TitleBoxStart b/rt/webrt/Elements/TitleBoxStart
deleted file mode 100755 (executable)
index 6d0f1f9..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<TABLE CLASS="<%$class%>" BGCOLOR="<%$color%>" CELLSPACING=0 BORDER=0 CELLPADDING=0 WIDTH="<%$width%>">
-<TR><TD ROWSPAN=2><IMG SRC="<%$RT::WebImagesURL%>spacer.gif" width=1 height=1 ALT=""></TD>
-<TD valign=middle align=left bgcolor="<%$color%>">&nbsp;<font size=-1 color="#ffffff"><b><% $title_href && "<A CLASS=\"$title_class\" HREF=\"$title_href\">"|n%><%$title |n %><%  $title_href && "</A>" |n%></b></font></TD>
-<TD  ALIGN="right" valign=middle bgcolor="<%$color%>"><FONT color="#ffffff" SIZE=-1><%$titleright |n %></FONT>&nbsp;</TD>
-<TD ROWSPAN=2><IMG SRC="<%$RT::WebImagesURL%>spacer.gif" width=1 height=1 ALT=""></TD></TR>
-<TR><TD COLSPAN=2 bgcolor="<%$contentbg%>" valign=top align=left WIDTH=100%>
-<TABLE CELLPADDING=2 WIDTH=100%><TR><TD>
-<%ARGS>
-$width => "100%"
-$class => undef
-
-$title_href => undef
-$title => undef
-$title_class => undef
-
-$titleright_href => undef
-$titleright => undef
-$contentbg => "#dddddd"
-$color => "#336699"
-</%ARGS>
diff --git a/rt/webrt/Elements/ViewUser b/rt/webrt/Elements/ViewUser
deleted file mode 100644 (file)
index 92446e6..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-
-<& /Elements/TitleBoxStart, 
-       title => "<a class='inverse' href=\"$RT::WebPath/Search/Listing.html?LimitRequestorById=1&IdOfRequestor=".$User->id."\">Tickets from $name</a>",
-       titleright=> "<a class='inverse' href=\"$RT::WebPath/EditUserComments.html?id=".$User->id."\">Comments about $name</a>" &>
-<TABLE WIDTH="100%">
-<tr>
-<td halign=left valign=top>
-%while (my $w=$tickets->Next) {
-<%$w->Id%>: <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$w->id%>"><%$w->Subject%></a> (<%$w->Status%>)<BR>
-%}
-</td>
-<td align=right valign=top>
-       <% ($User->Comments || "No comment entered about this user") %>
-</tr>
-</table>
-<& /Elements/TitleBoxEnd &>
-
-<%ARGS>
-$User=>undef
-</%ARGS>
-
-<%INIT>
-my $name=$User->RealName || $User->EmailAddress;       
-
-my $tickets = new RT::Tickets($session{'CurrentUser'});
-$tickets->LimitRequestor(VALUE => $User->EmailAddress);
-
-
-</%INIT>
diff --git a/rt/webrt/Elements/dayMenu b/rt/webrt/Elements/dayMenu
deleted file mode 100755 (executable)
index 6591b05..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<%doc>-------------------------------------------------------------------
-dayMenu: Display a pulldown menu of days of the month (1 to 31)
-
-Optional arguments:
-$menu_name - Name of menu, defaults to 'day'
-$current - Selected day value (1 to 31)
--------------------------------------------------------------------</%doc>
-
-<select name="<% $menu_name %>">
-<option value="-1">-
-% foreach my $day (1..31) {
-<option value="<% $day %>" <% $day==$current ? "selected" : "" %>><% sprintf("%02d",$day) %>
-% }
-</select>
-
-<%args>
-$menu_name=>'day'
-$current=>undef
-</%args>
diff --git a/rt/webrt/Elements/monthMenu b/rt/webrt/Elements/monthMenu
deleted file mode 100755 (executable)
index b9a71d3..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<%doc>-------------------------------------------------------------------
-monthMenu: Display a pulldown menu of months
-
-Optional arguments:
-$menu_name - Name of menu, defaults to 'month'
-$current - Selected month value (1 to 12)
-$format - Choice of month labels:
-   'full'    (January, February, ...)
-   'short'   (Jan, Feb, ...)
-   'numeric' (1, 2, ...)
-  Defaults to 'full'. The format only affects appearance; the menu
-  values are always numeric.
--------------------------------------------------------------------</%doc>
-
-<select name="<% $menu_name %>">
-<option value="-1">-
-% foreach my $month (1..12) {
-<option value="<% $month %>" <% $month==$current ? "selected" : "" %>>
-%   if ($format eq 'full') {
-<% $month_names[$month-1] %>
-%   } elsif ($format eq 'short') {
-<% substr($month_names[$month-1],0,3) %>
-%   } elsif ($format eq 'numeric') {
-<% sprintf("%02d",$month) %>
-%   }
-% }
-</select>
-
-<%init>
-my @month_names = qw(January February March April May June July August September October November December);
-</%init>
-
-<%args>
-$menu_name=>'month'
-$current=>undef
-$format=>'full'
-</%args>
diff --git a/rt/webrt/Elements/yearMenu b/rt/webrt/Elements/yearMenu
deleted file mode 100755 (executable)
index 4a0e7a7..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-<%doc>-------------------------------------------------------------------
-yearMenu: Display a pulldown menu of years.
-
-Optional arguments:
-$menu_name - Name of menu, defaults to 'year'
-$current - Selected year value
-$min - Minimum year appearing in menu; defaults to current year
-$max - Maximum year appearing in menus; defaults to $min plus 10.
--------------------------------------------------------------------</%doc>
-
-<select name="<% $menu_name %>">
-<option value="-1">-
-% foreach my $year ($min..$max) {
-<option value="<% $year %>" <% $year==$current ? "selected" : "" %>>
-<% $year %>
-% }
-</select>
-
-<%args>
-$menu_name=>'year'
-$current=>(localtime)[5]+1900
-$min=>(localtime)[5]+1900-1
-$max=>$min+10
-</%args>
diff --git a/rt/webrt/NoAuth/Logout.html b/rt/webrt/NoAuth/Logout.html
deleted file mode 100755 (executable)
index a00ae96..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<HTML>
-<HEAD>
-<TITLE>RT: Logout</TITLE>
- <META HTTP-EQUIV="Refresh" CONTENT="0;URL=<%$RT::WebPath%>/">
-</HEAD>
-<BODY>
-<p>You have been logged out of RT.
-
-
-<br>
-<br>
-<A HREF="<%$RT::WebPath%>/">You're welcome to login again</a>
-
-
-<%PERL>
-if (defined %session) {
-       %session = undef;
-}
-$m->abort();
-</%PERL>
-
-
diff --git a/rt/webrt/NoAuth/Reminder.html b/rt/webrt/NoAuth/Reminder.html
deleted file mode 100755 (executable)
index a814a91..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<& /Elements/Header, title => 'Password Reminder' &>
-
-Not yet implemented.
diff --git a/rt/webrt/NoAuth/images/rt.jpg b/rt/webrt/NoAuth/images/rt.jpg
deleted file mode 100644 (file)
index a137a93..0000000
Binary files a/rt/webrt/NoAuth/images/rt.jpg and /dev/null differ
diff --git a/rt/webrt/NoAuth/images/spacer.gif b/rt/webrt/NoAuth/images/spacer.gif
deleted file mode 100644 (file)
index 5bfd67a..0000000
Binary files a/rt/webrt/NoAuth/images/spacer.gif and /dev/null differ
diff --git a/rt/webrt/NoAuth/webrt.css b/rt/webrt/NoAuth/webrt.css
deleted file mode 100755 (executable)
index a71d057..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-BODY, TD {font-family: Helvetica, Arial, sans-serif}
-TD {border-color: #cccccc }
-
-BLOCKQUOTE.message {
-       font-size: 80%;
-       font-family: "Helvetica", sans-serif;
-}
-
-
-BODY {
-  color: #000;
-  background: #FFFFFF;
-  font-family: "Helvetica", sans-serif;
-
-
-}
-
-TD, TH { /* ns workaround */
-  font-family: "Helvetica", sans-serif;
-}
-
-TR.oddline { 
-    background-color : #eeeeee;
-}
-
-H1, H2, H3 { 
-  margin-top: 0.2em;
-  color: #336699;
-  font-family: "Helvetica", sans-serif;
-
-  clear: both;
-}
-
-
-DIV.endmatter { margin-left: -7% }
-
-
-
-A { font-weight: bold; 
-               color: #000000;
-           /* border: none -- breaks NS 4.x */ }
-
-.currenttab { background-color: #cccccc; }
-
-.inverse { color: #ffffff; }
-
-
-
-A:link IMG, A:visited IMG { border-style: none }
-
-A IMG { color: white } /* The only way to hide the border in NS 4.x */
-
-.hide {
-  display: none;
-  color: white;
-}
-
-SPAN.date { font-size: 0.8em }
-
-SPAN.attribution {
-  font-weight: bold
-}
-
-SPAN.label { font-size: 0.8em; 
-}
-
-BLOCKQUOTE {
-  font-style: italic;
-  /* color: #990; */
-}
-
-ADDRESS { 
-  text-align: right;
-  font-weight: bold;
-  font-style: italic 
-}
-
-BLOCKQUOTE P {                 /* Try to avoid space above the attribution */
-  margin-bottom: 0;
-}
-BLOCKQUOTE ADDRESS {
-  margin: 0;
-}
-
-.motto, .motto A {font: italic 120%/1.3 Georgia, serif; color: #990}
-
-.emphasized {
-  font-weight: bold
-}
-
-/* Why o why does this break Netscape 4.x?
-IMG { 
-  border: none
-}
-*/
-
-P.map-also { font-style: italic; margin-left: 15%; text-align: right }
-
-.oddline { 
-background-color : #eeeeee;
-
-}
diff --git a/rt/webrt/Search/Bulk.html b/rt/webrt/Search/Bulk.html
deleted file mode 100755 (executable)
index ac688d7..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Search/Attic/Bulk.html,v 1.1 2002-08-12 06:17:09 ivan Exp $
-%# Copyright 1996-2001 Jesse Vincent <jesse@fsck.com>
-<& /Elements/Header, Title => "Bulk ticket update" &>
-<& /Elements/Tabs &>
-
-<& /Elements/ListActions, actions => \@results &>
-
-<FORM METHOD=POST>
-<TABLE WIDTH=100% border=0 cellpadding=3 CELLSPACING=0>
-<TR>
-<TH>Update</TH>
-%foreach my $col (@cols) {
-% my $colalias = $col;
-% $colalias =~ s/(Obj\-\>|)(Name|AsString)//;
-
-<TH ><% $colalias %>&nbsp;</TH>
-%}
-</TR>
-
-<%PERL>
-
-my $i;
-
-
-      
-$session{'tickets'}->RedoSearch();
-while (my $Ticket = $session{'tickets'}->Next) {
- $i++;
- if ($i % 2) {
-     $bgcolor = "#dddddd";
- }
- else {
-     $bgcolor = "#ffffff";
- }
-      </%PERL>
-<TR bgcolor="<%$bgcolor%>">
-<TD><input type=checkbox name="UpdateTicket<%$Ticket->Id%>" CHECKED></TD>
-%# The ticket view is controlled by config.pm, WebOptions
-%foreach my $col (@cols) {
-<TD>
-% if ($col eq 'id') {
-<A HREF="<% $RT::WebPath%>/Ticket/Display.html?id=<%$Ticket->Id%>"><%$Ticket->Id()%></A>
-% }
-%else {
-<% eval "\$Ticket->$col()" %>&nbsp;
-%}
-</TD>
-%}
-</TR>
-%}
-
-
-
-</TABLE>
-
-<HR>
-
-
-<& /Elements/TitleBoxStart, title => 'Update selected tickets' &>
-<TABLE>
-<TR>
-<TD VALIGN=TOP>
-<UL>
-<li> Make Owner <& /Elements/SelectOwner, Name => "Owner" &>
-(<input type=checkbox name="ForceOwnerChange"> Force change)
-<li> Add Requestor <INPUT Name="AddRequestor" SIZE=20>
-<li> Remove Requestor <INPUT Name="DeleteRequestor" SIZE=20>
-<li> Add Cc <INPUT Name="AddCc" SIZE=20>
-<li> Remove Cc <INPUT Name="DeleteCc" SIZE=20>
-<li> Add AdminCc <INPUT Name="AddAdminCc" SIZE=20>
-<li> Remove AdminCc <INPUT Name="DeleteAdminCc" SIZE=20>
-</UL>
-</TD>
-<TD VALIGN=TOP>
-<UL>
-<li> Make subject <INPUT Name="Subject" SIZE=20>
-<li> Make priority <INPUT Name="Priority" SIZE=4>
-<li> Make queue <& /Elements/SelectQueue, Name => "Queue" &>
-
-<li>Make Status <& /Elements/SelectStatus, Name => "Status" &>
-
-
-
-<li> Make date Starts <& /Elements/SelectDate, Name => "Starts_Date", ShowTime => 0, Default => '' &>
-<li> Make date Started <& /Elements/SelectDate, Name => "Started_Date", ShowTime => 0, Default => '' &>
-<li> Make date Told <& /Elements/SelectDate, Name => "Told_Date", ShowTime => 0, Default => '' &>
-<li> Make date Due <& /Elements/SelectDate, Name => "Due_Date", ShowTime => 0, Default => '' &>
-<li> Make date Resolved <& /Elements/SelectDate, Name => "Resolved_Date", ShowTime => 0, Default => '' &>
-
-
-% while ( my $KeywordSelect = $KeywordSelects->Next ) {
-
-<li> Add <% $KeywordSelect->Name %> <& /Elements/SelectKeyword, Name => "AddToKeywordSelect".$KeywordSelect->id, KeywordObj => $KeywordSelect->KeywordObj &>
-<li> Remove <% $KeywordSelect->Name %> <& /Elements/SelectKeyword, Name => "DeleteFromKeywordSelect".$KeywordSelect->id, KeywordObj => $KeywordSelect->KeywordObj &>
-% }
-
-</UL>
-
-
-</TD>
-</TR>
-</table>
-<& /Elements/TitleBoxEnd&>
-<& /Elements/TitleBoxStart, title => 'Add comments or replies to selected tickets' &>
-<table>
-<tr><td align=right>Update Type:</td>
-<td><select name="UpdateType">
-  <option value="private" >Comments (not sent to requestors)</option>
-<option value="response" >Response to requestors</option>
-</select> 
-</td></tr>
-<tr><td align=right>Subject:</td><td> <input name="UpdateSubject" size=60 value=""></td></tr>
- <tr><td align=right>Attach:</td><td><input name="UpdateAttachment" type="file"></td></tr>
- <tr><td colspan="2">
- <& /Elements/MessageBox, Name=>"UpdateContent"&>
- </td></tr>
- </table>
-<& /Elements/TitleBoxEnd &>
-
-
-
-
-<& /Elements/Submit &>
-
-
-</FORM>
-<%INIT>
-
-# Iterate through the ARGS hash and remove anything with a null value.
-map ($ARGS{$_} =~ /^$/ && (delete $ARGS{$_}), keys %ARGS);
-
-my ($bgcolor, @results);
-my @cols = qw(id Status Priority Subject QueueObj->Name OwnerObj->Name RequestorsAsString DueAsString );
-
-Abort("No search to operate on.") unless ($session{'tickets'});
-
-
-my $do_comment_reply=0;
-# Prepare for ticket updates
-$ARGS{'UpdateContent'} =~ s/\r\n/\n/g;
-chomp ($ARGS{'UpdateContent'}) ;
-
-if ($ARGS{'UpdateContent'} &&
-    $ARGS{'UpdateContent'} ne '' &&
-    $ARGS{'UpdateContent'} ne  "-- \n" .
-    $session{'CurrentUser'}->UserObj->Signature) {
-            $do_comment_reply=1;
-}
-
-my $KeywordSelects = new RT::KeywordSelects $session{'CurrentUser'};
-foreach ( $session{'tickets'}->RestrictionValues('Queue') ) {
-    $KeywordSelects->LimitToQueue($_);
-}
-
-$KeywordSelects->IncludeGlobals;
-
-
-#Iterate through each ticket we've been handed
-
-while (my $Ticket = $session{'tickets'}->Next) {
-    $RT::Logger->debug( "Checking Ticket ".$Ticket->Id ."\n");
-    next unless ($ARGS{"UpdateTicket".$Ticket->Id});
-    $RT::Logger->debug ("Matched\n");
-    #Update the basics.
-    my @basicresults = ProcessTicketBasics(TicketObj => $Ticket, ARGSRef => \%ARGS);
-    my @dateresults = ProcessTicketDates(TicketObj => $Ticket, ARGSRef => \%ARGS);
-    my @watchresults = ProcessTicketWatchers(TicketObj => $Ticket, ARGSRef => \%ARGS);    
-    my @selectresults = ProcessTicketObjectKeywords(TicketObj => $Ticket, ARGSRef => \%ARGS);
-    
-   
-     my @updateresults; 
-     if ($do_comment_reply) {
-     ProcessUpdateMessage(TicketObj => $Ticket, ARGSRef => \%ARGS, Actions => \
-@updateresults); 
-    } 
-    my @tempresults = (@watchresults, @basicresults, @dateresults, @updateresults);
-    @tempresults = map { "Ticket ".$Ticket->Id. ": ".$_ } @tempresults;
-
-    
-    #Update the keyword selects
-    #Update the watchers
-    $RT::Logger->debug(join("\n",@tempresults));
-    @results = (@results, @tempresults);
-}
-
-</%INIT>
diff --git a/rt/webrt/Search/Listing.html b/rt/webrt/Search/Listing.html
deleted file mode 100755 (executable)
index da927fe..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Search/Attic/Listing.html,v 1.1 2002-08-12 06:17:09 ivan Exp $
-%# Copyright 1996-2001 Jesse Vincent <jesse@fsck.com>
-<& /Elements/Header, Title => "Search", Refresh => $session{'tickets_refresh_interval'} &>
-<& /Elements/Tabs, current_toptab => 'Search/Listing.html' &>
-
-
-% unless ($ARGS{'Action'} eq 'Refine') {
-<TABLE WIDTH=100% border=0 cellpadding=3 CELLSPACING=1>
-<TR>
-%foreach my $col (@{Config(\%ARGS, 'QueueListingCols')}) {
-<TH>
-
-<%PERL>        
-my ($order);
- my $attr = $col->{'TicketAttribute'};
- $attr =~ s/Obj->(Name|AsString|AgeAsString)//g;
-  if ($session{'tickets_sort_order'} =~ /^asc$/i) {
-   $order = 'DESC';
- } else {
-   $order = 'ASC';
- }
-</%PERL>
-
-% if (grep (/^$attr$/i, $session{'tickets'}->SortFields)) {
-<A 
-% if ($attr eq $session{'tickets_sort_by'}) {
-class="currenttab"
-% }
-HREF="<% $RT::WebPath%>/Search/Listing.html?Bookmark=<%$session{'tickets'}->FreezeLimits()|u%>&TicketsSortBy=<%$attr%>&TicketsSortOrder=<%$order%>&RowsPerPage=<%$session{'tickets_rows_per_page'}%>">
-<%$col->{Header}%>
-</A>
-% } else {
-<% $col->{Header} %>
-% }
-</TH>
-%}
-</TR>
-
-<%PERL>
-
-my $i;
-      
-$session{'tickets'}->RedoSearch();
-while (my $Ticket = $session{'tickets'}->Next) {
- $i++;
- if ($i % 2) {
-     $bgcolor = "#dddddd";
- }
- else {
-     $bgcolor = "#ffffff";
- }
-      </%PERL>
-<TR bgcolor="<%$bgcolor%>" >
-%# The ticket view is controlled by config.pm, WebOptions
-%foreach my $col (@{Config(\%ARGS,'QueueListingCols')}) {
-<TD><& TicketCell , Ticket=>$Ticket,  Column=>$col &></TD>
-%}
-</TR>
-%}
-
-
-
-</TABLE>
-
-<div align=center>
-<font size=2>
-<a href="Listing.html?GotoPage=1">First page</a>
-&nbsp;&nbsp;
-<a href="Listing.html?GotoPage=Prev">&lt;Previous page</a>
-&nbsp;&nbsp;
-<a href="Listing.html?GotoPage=Next">Next page&gt;</a>
-%#&nbsp;&nbsp;<form method=get action="Listing.html">Goto page <input name=GotoPage size=2></form>
-</font>
-</div>
-% if ($session{'tickets'}->Count()) { 
-<div align=right>
-<a href="Bulk.html">Update all these tickets at once</a>
-</div>
-% }
-<HR>
-
-% } #endif {$ARGS{'Action'} eq 'Refine')
-<TABLE WIDTH="100%">
-<TR>
-<TD VALIGN="TOP">
-<& /Elements/TitleBoxStart, title => 'Search Criteria'&>
-
-<A HREF="<% $RT::WebPath%>/Search/Listing.html?ClearRestrictions=1">New search</a><br>
-<A HREF="<% $RT::WebPath%>/Search/Listing.html?Bookmark=<%$session{'tickets'}->FreezeLimits()|u%>&TicketsSortBy=<%$session{'tickets_sort_by'}%>&TicketsSortOrder=<%$session{'tickets_sort_order'}%>&RowsPerPage=<%$session{'tickets_rows_per_page'}%>">Bookmarkable URL for this search</a>
-<BR>
-<BR>
-% my %restrictions=$session{'tickets'}->DescribeRestrictions();
-% my %seen_restrictions=();
-% foreach $row (keys %restrictions){
-%  my $tmp=$restrictions{"$row"};
-%  if( ! defined( $seen_restrictions{"$tmp"} ) ){
-<%$restrictions{"$row"}%> <A HREF="<% $RT::WebPath%>/Search/Listing.html?DeleteRestriction=<%$row%>">[delete]</a><br>
-%   } else {
-%     $session{'tickets'}->DeleteRestriction($row);
-<b>Deleted Duplicate Restriction <i><%$tmp%></i></b><br>
-% }
-% $seen_restrictions{"$tmp"}++;
-%}
-<& /Elements/TitleBoxEnd&>
-</TD>
-<TD>
-
-<& PickRestriction &>
-
-</TD>
-</TR>
-</TABLE>
-
-<%INIT>
-
-my $bgcolor;
-require RT::Interface::Web;
-
-$session{'i'}++;
-if ($session{'tickets'}) {
-    if ( ($ARGS{'ClearRestrictions'}) ||
-        ($ARGS{'NewSearch'}) ) {
-       $session{'tickets'}->ClearRestrictions;
-    }
-    
-    if ($ARGS{'DeleteRestriction'}) {
-       $session{'tickets'}->DeleteRestriction($ARGS{'DeleteRestriction'});
-    }
-}
-&ProcessSearchQuery(ARGS=>\%ARGS);
-
-my $row;
-
-</%INIT>
diff --git a/rt/webrt/Search/PickRestriction b/rt/webrt/Search/PickRestriction
deleted file mode 100755 (executable)
index 82f576c..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Search/Attic/PickRestriction,v 1.1 2002-08-12 06:17:09 ivan Exp $
-<FORM ACTION="Listing.html" METHOD="GET">
-<INPUT TYPE=HIDDEN NAME="Bookmark" VALUE="<% $session{'tickets'}->FreezeLimits()|u %>">
-<& /Elements/TitleBoxStart, title => 'Refine Search'&>
-<INPUT TYPE=HIDDEN NAME="CompileRestriction" VALUE=1>
-
-<ul>
-<li>Owner is  <& /Elements/SelectBoolean, Name => "OwnerOp", 
-                                         TrueVal=> '=', 
-                                         FalseVal => '!=' 
-&> 
-<& /Elements/SelectOwner, Name => "ValueOfOwner" &>
-
-<li>
-Requestor email address 
-<& /Elements/SelectMatch, Name => "RequestorOp" &>
-<INPUT Name="ValueOfRequestor" SIZE=20>
-
-<li>
-Subject <& /Elements/SelectMatch, Name => "SubjectOp" &> 
-<INPUT Name="ValueOfSubject" SIZE=20>
-
-<li>Queue  <& /Elements/SelectBoolean,  Name => "QueueOp" , 
-                                       True => "is", 
-                                       False => "isn't", 
-                                       TrueVal=> '=', 
-                                       FalseVal => '!=' &>
-<& /Elements/SelectQueue, Name => "ValueOfQueue" &>
-
-
-<li>Priority  <& /Elements/SelectEqualityOperator,  Name => "PriorityOp" &>
-
-<INPUT Name="ValueOfPriority" SIZE=5>
-
-
-<li>
-<& /Elements/SelectDateType, Name => 'DateType' &>
-<& /Elements/SelectDateRelation, Name=>"DateOp" &>
-<& /Elements/SelectDate, Name => "ValueOfDate", ShowTime => 0, Default => '' &>
-
-<li>Ticket content 
-<& /Elements/SelectBoolean, Name => "ContentOp", 
-                           True => "matches", 
-                           False => "does not match", 
-                           TrueVal => 'LIKE', 
-                           FalseVal => 'NOT LIKE' 
-&> 
-<Input Name="ValueOfContent" Size=20>
-
-<li>Status 
-<& /Elements/SelectBoolean, Name => "StatusOp", 
-                           True => "is", 
-                           False => "isn't", 
-                           TrueVal=> '=', 
-                           FalseVal => '!=' 
-&>  
-<& /Elements/SelectStatus, Name => "ValueOfStatus" &>
-
-% while ( my $KeywordSelect = $KeywordSelects->Next ) {
-
-<li><% $KeywordSelect->Name %> 
-       <& /Elements/SelectBoolean, Name => "KeywordSelectOp". $KeywordSelect->id, 
-                                   True => "is", False => "isn't", 
-                                   TrueVal=> '=', FalseVal => '!=' &>
-
-<& /Elements/SelectKeyword, Name => "KeywordSelect".$KeywordSelect->id,
-                           KeywordObj => $KeywordSelect->KeywordObj
-                           &>
-% }
-
-</UL>
-
-<& /Elements/TitleBoxEnd &>
-
-<& /Elements/TitleBoxStart, title => 'Ordering and sorting'&>
-
-<UL>
-
-<li>Results per page <& /Elements/SelectResultsPerPage, Name => "RowsPerPage", 
-                                                       Default => $session{'tickets_rows_per_page'} || '50'
-&>
-
-<li>Sort results by <& /Elements/SelectTicketSortBy, Name => "TicketsSortBy", 
-                                                    Default => $session{'tickets_sort_by'} 
-&> 
-<& /Elements/SelectSortOrder, Name => 'TicketsSortOrder', Default => $session{'tickets_sort_order'} &>
-
-<li> <& /Elements/Refresh, Name => 'RefreshSearchInterval' , Default => $session{'tickets_refresh_interval'} &>
-
-
-</UL>
-
-
-</DIV>
-
-
-
-<& /Elements/TitleBoxEnd &>
-
-<& /Elements/Submit, Label => 'Show Results', AlternateLabel => 'Refine', Name => 'Action'&>
-
-</FORM>
-
-
- <%INIT>
- my $KeywordSelects = new RT::KeywordSelects $session{'CurrentUser'};
- foreach ( $session{'tickets'}->RestrictionValues('Queue') ) {
-        $KeywordSelects->LimitToQueue($_);
- }
-
- $KeywordSelects->IncludeGlobals;
-</%INIT>
diff --git a/rt/webrt/Search/RestrictSearch.html b/rt/webrt/Search/RestrictSearch.html
deleted file mode 100755 (executable)
index 977308e..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<& /Elements/Header, Title=>"Compile Restrictions" &>
-<& /Elements/Tabs &>
-<& PickRestriction &>
diff --git a/rt/webrt/Search/TicketCell b/rt/webrt/Search/TicketCell
deleted file mode 100644 (file)
index aaded88..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-%#$Header: /home/cvs/cvsroot/freeside/rt/webrt/Search/Attic/TicketCell,v 1.1 2002-08-12 06:17:09 ivan Exp $
-<% $link |n%><%$Column->{Constant} || eval("\$Ticket->$Column->{TicketAttribute}") || "-" %><% $endlink|n %>
-<%INIT>
-
-my $link = "";
-my $endlink = "";
-if ($Column->{TicketLink}) {
-       $link = "<A HREF=\"";
-       if ($Column->{TicketLink} == 1 ) {
-               $link .= "../Ticket/Display.html?";
-       }
-       else {
-               $link .= $Column->{TicketLink};
-       }
-
-       $link .= "id=".$Ticket->Id . $Column->{ExtraLinks};
-
-       if ($session{NewWindowOption}) {
-               $link .= "TARGET=\"TicketDisplay".$session{AlwaysNewWindowOption} && (time() . rand(1024))."\" ";
-       }
-       $link .= "\">";
-       $endlink = "</a>";
-}
-</%INIT>
-<%ARGS>
-$Ticket => undef
-$Column => undef
-</%ARGS>
diff --git a/rt/webrt/SelfService/Attachment/dhandler b/rt/webrt/SelfService/Attachment/dhandler
deleted file mode 100644 (file)
index 0d646cc..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<%perl>
-     my ($ticket, $trans,$attach, $filename);
-     my $arg = $m->dhandler_arg;                # get rest of path
-     if ($arg =~ '^(\d+)/(\d+)') {
-        $trans = $1;
-        $attach = $2;
-     }
-    else {
-        Abort("Corrupted attachment URL.");
-        }
-     my $AttachmentObj = new RT::Attachment($session{'CurrentUser'});
-     $AttachmentObj->Load($attach) || Abort("Attachment '$attach' could not be loaded");
-
-
-     unless ($AttachmentObj->id) {
-        Abort("Bad attachment id. Couldn't find attachment '$attach'\n");
-    }
-     unless ($AttachmentObj->TransactionId() == $trans ) {
-        Abort("Bad transaction number for attachment. $trans should be".$AttachmentObj->TransactionId() ."\n");
-
-     }
-     my $content_type = $AttachmentObj->ContentType || 'text/plain';
-     SetContentType($content_type);
-     $m->out($AttachmentObj->Content); 
-     $m->abort; 
-</%perl>
-
diff --git a/rt/webrt/SelfService/Closed.html b/rt/webrt/SelfService/Closed.html
deleted file mode 100644 (file)
index a359360..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<& /SelfService/Elements/Header, title => 'RT Self Service / Closed Tickets' &>
-
-<& /SelfService/Elements/MyRequests, status => ['resolved'], friendly_status =>
-'closed' &>
diff --git a/rt/webrt/SelfService/Create.html b/rt/webrt/SelfService/Create.html
deleted file mode 100755 (executable)
index 60110cb..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/SelfService/Attic/Create.html,v 1.1 2002-08-12 06:17:09 ivan Exp $
-%# Copyright 1996-2001 Jesse Vincent <jesse@fsck.com>
-
-<& Elements/Header, Title => "Create a request" &>
-
-
-<FORM ACTION="Display.html" METHOD="POST" ENCTYPE="multipart/form-data">
-<INPUT TYPE=HIDDEN Name="id" VALUE="new">
-<& /Elements/TitleBoxStart, contentbg => "#cccccc", title => "Create a new ticket" &>
-
-<TABLE>
-<TR>
-<TD>
-Queue:
-</TD>
-<TD>
-<& /Elements/SelectNewTicketQueue, Verbose => 'True' &>
-</TD>
-</TR>
-<TR>
-<TD>
-Requestors: 
-</TD>
-<TD>
-<INPUT Name="Requestors" Value="<%$session{CurrentUser}->EmailAddress%>" SIZE=20>
-</TD>
-</TR>
-<TR>
-<TD>
-Cc:
-</TD>
-<TD>
- <INPUT NAME="Cc" SIZE=20>
-</TD>
-</TR>
-<TR>
-<TD>
-Subject:
-</TD>
-<TD>
-<INPUT Name="Subject" SIZE=60 MAXSIZE=100 value="">
-</TD>
-</TR>
-<TR>
-<TD>
-Attach file:
-</TD>
-<TD>
-<INPUT Name="Attach" type=file>
-</TD>
-</TR>
-<TR>
-<TD COLSPAN=2>
-Describe the issue below:<br>
-<& /Elements/MessageBox &>
-</TD>
-</TR>
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit, Label => "Create ticket"&>
-
-
-</FORM>
diff --git a/rt/webrt/SelfService/Display.html b/rt/webrt/SelfService/Display.html
deleted file mode 100755 (executable)
index 2d44f14..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/SelfService/Attic/Display.html,v 1.1 2002-08-12 06:17:09 ivan Exp $
-%# Copyright 1996-2001 Jesse Vincent <jesse@fsck.com>
-
-<& /SelfService/Elements/Header, Title => 'Display ticket #'.$Ticket->id &>
-
-
-<& /Elements/ListActions, actions => \@results &>
-
-<TABLE>
-    <TR>
-       <TD VALIGN=TOP WIDTH="20%" ALIGN=RIGHT>
-       Ticket Id
-       </TD>
-      <TD>
-       <%$Ticket->Id%>
-       </TD>
-      </TR>
-    <TR>       
-      <TD VALIGN=TOP WIDTH="20%" ALIGN=RIGHT>
-       Requestors
-       </TD>
-      <TD>
-       <%$Ticket->RequestorsAsString%>
-      </TD>
-      </TR>
-    <TR>       
-      <TD VALIGN=TOP WIDTH="20%" ALIGN=RIGHT>
-       Cc
-       </TD>
-      <TD>
-       <%$Ticket->CcAsString%>
-      </TD>
-    </TR>
-
-  <TR> 
-      <TD VALIGN=TOP WIDTH="20%" ALIGN=RIGHT>
-       Status
-       </TD>
-      <TD>
-       <%$Ticket->Status%>
-      </TD>
-    </TR>
-
-    <TR>       
-      <TD VALIGN=TOP WIDTH="20%" ALIGN=RIGHT>
-       Queue
-       </TD>
-      <TD>
-       <%$Ticket->QueueObj->Name%> (<%$Ticket->QueueObj->Description%>)
-      </TD>
-    </TR>
-    <TR>       
-      <TD VALIGN=TOP WIDTH="20%" ALIGN=RIGHT>
-       Priority
-      </TD>
-      <TD>
-       <%$Ticket->Priority %>
-      </TD>
-    </TR>
-%  if ($Ticket->TimeWorked) {
-   <TR>        
-      <TD VALIGN=TOP WIDTH="20%" ALIGN=RIGHT>
-       Worked
-      </TD>
-      <TD>
-       <%$Ticket->TimeWorked %> minutes
-      </TD>
-    </TR>
-% }
-    
-% my $selects = $Ticket->QueueObj->KeywordSelects;
-% while (my $select = $selects->Next) {
-    <TR>
-      <TD VALIGN=TOP WIDTH="20%" ALIGN=RIGHT>
-       <%$select->Name%>
-      </TD>
-      <TD>
-% my $object_keywords = $Ticket->KeywordsObj($select->id);     
-% while (my $keyword = $object_keywords->Next) {
-       <%$keyword->KeywordObj->RelativePath($select->KeywordObj)%>
-% }
-%}
-       </TD>
-      </TR>
-
-
-
-
-       </TABLE>
-<TABLE BORDER=0 CELLSPACING=0>
-% my ($i);
-%while (my $Transaction = $Transactions->Next) {
-% $i++;
-%      if ($Transactions->IsLast) {
-       <a name="lasttrans"></a>
-%      }
-       <& /Ticket/Elements/ShowTransaction, Transaction => $Transaction, 
-                                            RowNum => $i,
-                                            Ticket => $Ticket &>
-
-%}
-</TABLE>
-
-
-<%INIT>
-
-my ($field, @results);
-
-# {{{ Load the ticket
-#If we get handed two ids, mason will make them an array. bleck.
-# We want teh first one. Just because there's no other sensible way
-# to deal
-my @id = (ref $id eq 'ARRAY') ? @{$id} : ($id);                
-
-
-my $Ticket = new RT::Ticket($session{'CurrentUser'});
-if ($id[0] eq 'new') {
-    # {{{ Create a new ticket
-    
-    my $Queue = new RT::Queue($session{'CurrentUser'});        
-    unless ($Queue->Load($ARGS{'Queue'})) {
-       $m->comp('Error.html', Why => 'Queue not found');
-       $m->abort;
-    }
-    
-    unless ($Queue->CurrentUserHasRight('CreateTicket')) {
-       $m->comp('Error.html', Why => 'You have no permission to create tickets in that queue.');
-       $m->abort; 
-    }
-    
-    my @Requestors = split(/,/,$ARGS{'Requestors'});
-    my @Cc = split(/,/,$ARGS{'Cc'});
-    
-
-    my $MIMEObj = MakeMIMEEntity ( Subject => $ARGS{'Subject'},
-                                  From => $ARGS{'From'},
-                                  Cc => $ARGS{'Cc'},
-                                  Body => $ARGS{'Content'},
-                                  AttachmentFieldName => 'Attach');
-
-    #TODO in Create_Details.html: priorities and due-date      
-    my ($id, $Trans, $ErrMsg)= $Ticket->Create(Queue=>$ARGS{Queue},
-                                              Requestor=> \@Requestors,
-                                              Cc => \@Cc,
-                                              Subject=>$ARGS{Subject},
-                                              MIMEObj => $MIMEObj        
-                                             );         
-    unless ($id && $Trans) {
-       $m->comp('Error.html', Why => $ErrMsg);
-       $m->abort(); 
-    }
-
-    push(@results, $ErrMsg);
-
-    # }}}
-}
-else {
-    unless ($Ticket->Load($id[0])) {
-       $m->comp('Error.html', Why =>"Couldn't load ticket '$id'");
-       $m->abort();
-    }
-}
-# }}}
-
-unless ($session{'CurrentUser'}->HasQueueRight ( TicketObj => $Ticket,
-                                                Right => 'ShowTicket')) {
-    $m->comp('Error.html', Why => "No permission to display that ticket");
-    $m->abort();
-}
-
-my ($code, $msg);
-
-#Update the status
-if ((defined $ARGS{'Status'}) and 
-    ($ARGS{'Status'} ne $Ticket->Status)) {
-    ($code, $msg) = $Ticket->SetStatus($ARGS{'Status'});
-    push @results, "$msg";
-}
-
-ProcessUpdateMessage(ARGSRef=>\%ARGS, Actions=>\@results, TicketObj=>$Ticket);
-
-my $Transactions = $Ticket->Transactions;
-
-</%INIT>
-
-
-<%ARGS>
-$id => undef
-</%ARGS>
diff --git a/rt/webrt/SelfService/Elements/GotoTicket b/rt/webrt/SelfService/Elements/GotoTicket
deleted file mode 100755 (executable)
index 0c0c8b6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<FORM ACTION="<%$RT::WebPath%>/SelfService/Display.html"><input type=submit value="Goto ticket">&nbsp;<input size=4 name=id></FORM>
diff --git a/rt/webrt/SelfService/Elements/Header b/rt/webrt/SelfService/Elements/Header
deleted file mode 100755 (executable)
index ecf58f4..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
-     "http://www.w3.org/TR/REC-html40/loose.dtd"> 
-<HTML>
-<HEAD>
-<TITLE><%$Title%></TITLE>
-% if ($Code) {
-<META NAME="HTTP-EQUIV" VALUE="<%$Code%> <%$Why%>">
-% }
-
-<link rel="stylesheet" href="<%$RT::WebPath%>/NoAuth/webrt.css" type="text/css">
-</HEAD>
-<BODY BGCOLOR="<%$BgColor%>">
-<TABLE BORDER=0 WIDTH=100% CELLSPACING=0 BGCOLOR="#993333">
-<TR VALIGN=TOP>
-<TD WIDTH=32>
-        <IMG SRC="<%$RT::LogoURL%>" alt="RT">
-</TD>
-<TD VALIGN=CENTER ALIGN=LEFT>
-<font size=+2 color=#ffffff>
-<B>
-<%$Title%>
-</B>
-</font>
-</TD>
-<TD ALIGN=RIGHT>
-<font color="#ffffff">
-% if ($session{'CurrentUser'} ) {
-Signed in as <b><%$session{'CurrentUser'}->Name%></b>.<BR>
-% if ($session{'CurrentUser'}->HasSystemRight('ModifySelf')) {
-[<A class='inverse' HREF="<%$RT::WebPath%>/SelfService/Prefs.html" >Preferences</A>]
-% }
-% unless ($RT::WebExternalAuth) { 
- [<A class='inverse' HREF="<%$RT::WebPath%>/NoAuth/Logout.html">Logout</a>]
-% }
-% } else {
-Not logged in.
-% }
-</font>
-</TD>
-</TR>
-</TABLE>
-
-<BR>
-<& /SelfService/Elements/Tabs &>
-
-<%ARGS>
-$Title => ''
-$Code => undef
-$Why => undef
-$BgColor => '#ffffff'
-</%ARGS>
-<%INIT>
-$Title = "RT/$RT::rtname: ".$Title;
-</%INIT>
-
diff --git a/rt/webrt/SelfService/Elements/MyRequests b/rt/webrt/SelfService/Elements/MyRequests
deleted file mode 100644 (file)
index ce268d5..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-<& /Elements/TitleBoxStart, title => "Your $friendly_status requests" &>
-<TABLE BORDER=0 cellspacing=1 cellpadding=1 BGCOLOR="#eeeeee" WIDTH=100%>
-<TR>
-<TH>Subject</TH>
-<TH>Status</TH>
-<TH>Owner</TH>
-<TH>&nbsp;</TH>
-</TR>
-<TR>
-% while (my $Ticket = $MyTickets->Next) {
-<TR>
-<TD>
-<%$Ticket->Id%>: <%$Ticket->Subject%>
-</TD>
-<TD>
-<%$Ticket->Status%>
-</TD><TD>
-<%$Ticket->OwnerObj->Name%>
-</TD><TD ALIGN=RIGHT>
-[<A HREF="<% $RT::WebPath %>/SelfService/Display.html?id=<%$Ticket->Id%>">Details</A>]
-</TD>
-</TR>
-% }
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-
-
-<%INIT>
-my $MyTickets;
-$MyTickets = new RT::Tickets ($session{'CurrentUser'});
-$MyTickets->LimitRequestor(VALUE => $session{'CurrentUser'}->EmailAddress);
-
-foreach my $status (@status) {
-
-        $MyTickets->LimitStatus(VALUE => $status);
-}
-</%INIT>
-<%ARGS>
-$friendly_status => 'open'
-@status => ('open', 'new', 'stalled')
-</%ARGS>
diff --git a/rt/webrt/SelfService/Elements/Tabs b/rt/webrt/SelfService/Elements/Tabs
deleted file mode 100644 (file)
index d689d8a..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-<TABLE WIDTH=100%>
-<TR>
-% foreach $tab (sort keys %{$tabs}) {
-<TD ALIGN=CENTER>
-[<A HREF="<%$RT::WebPath%>/<% $tabs->{"$tab"}->{'path'}%>"><% $tabs->{"$tab"}->{'title'}%></A>]
-</TD>
-%}
-
-% if ($actions) {
-
-<TD ALIGN=RIGHT>
-<TABLE><TR>
-%  foreach my $action (sort keys %{$actions}) {
-<TD>
-<FONT SIZE=-1>
-% if ($actions->{"$action"}->{'html'}) {
-<%$actions->{"$action"}->{'html'} |n%>
-% } else {
-<A HREF="<%$RT::WebPath%>/<% $actions->{$action}->{'path'}%>"><% $actions->{$action}->{'title'}%></A>
-% }
-</FONT>
-</TD>
-%  }
-</TR>
-</TABLE>
-</TD>
-%}
-</TR>
-</TABLE>
-<hr>
-<%INIT>
-my ($tab);
-my $tabs = { A  => { title => 'Open requests',
-                        path => 'SelfService/',
-                      },
-             B => { title => 'Closed requests',
-                         path => 'SelfService/Closed.html',
-                       },
-             C => { title => 'New request',
-                    path => 'SelfService/Create.html'
-                    }
-           };
-my $actions = {
-       B => { html => $m->scomp('GotoTicket') 
-               }
-       };
-</%INIT>
-
-
diff --git a/rt/webrt/SelfService/Error.html b/rt/webrt/SelfService/Error.html
deleted file mode 100755 (executable)
index 19b79e6..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<& /SelfService/Elements/Header, Title => 'Error' &>
-<& /Elements/TitleBoxStart, title => $Title &>
-<%$Why%>
-<br>
-<font size=-1>
-<%$Details%>
-</font>
-<& /Elements/TitleBoxEnd &>
-</body>
-</HTML>
-
-
-<%args>
-$Code => undef
-$Details => undef
-$Title => "RT Error"
-$Why => "the calling component did not specify why"
-</%args>
-
-<%INIT>
-$RT::Logger->error("WebRT: $Why ($Details)");
-</%INIT>
diff --git a/rt/webrt/SelfService/Prefs.html b/rt/webrt/SelfService/Prefs.html
deleted file mode 100755 (executable)
index 9c614e9..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-<& /SelfService/Elements/Header, title => 'Preferences' &>
-
-<& /Elements/ListActions, actions => \@results &>
-<form method=post>
-
-% unless ($RT::WebExternalAuth) {
-<& /Elements/TitleBoxStart, title => 'Change password'  &>
-New password: <input type=password name="NewPass1" size=16>
-Confirm: <input type=password name="NewPass2" size=16>
-<& /Elements/TitleBoxEnd &>
-<BR>
-% }
-<& /Elements/TitleBoxStart, title => 'Signature'  &>
-
-<TEXTAREA COLS=72 ROWS=4 WRAP=HARD NAME="Signature"><% $session{'CurrentUser'}->UserObj->Signature %></TEXTAREA>
-<br>
-<BR>
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit &>
-         </form>
-
-
-<%INIT>
-my @results;
-
-if ($NewPass1) {
-    if ($NewPass1 ne $NewPass2) {
-       push (@results, "Passwords did not match.");
-    }  
-    else {
-       my ($val, $msg)=$session{'CurrentUser'}->UserObj->SetPassword($NewPass1);
-       push (@results, "Password: ".$msg);
-    }  
-}
-if ($Signature) {
-    $Signature =~ s/(\r\n|\r)/\n/g;
-    if ($Signature ne $session{'CurrentUser'}->UserObj->Signature) {
-       my ($val, $msg)=$session{'CurrentUser'}->UserObj->SetSignature($Signature);
-       push (@results, "Signature: ".$msg);
-    }
-}
-#A hack to make sure that session gets rewritten.
-
-$session{'i'}++;
-</%INIT>
-
-<%ARGS>
-$Signature => undef
-$NewPass1 => undef
-$NewPass2 => undef
-</%ARGS>
diff --git a/rt/webrt/SelfService/Update.html b/rt/webrt/SelfService/Update.html
deleted file mode 100755 (executable)
index 17f1618..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<& /SelfService/Elements/Header, Title => 'Update ticket #'.$Ticket->id &>
-
-
-<FORM ACTION="Display.html" METHOD=POST ENCTYPE="multipart/form-data">
-
-Status:
-<& /Elements/SelectStatus, Name=>"Status", Default => $DefaultStatus &> 
-<input type=hidden name="UpdateType" value="response">
-
-Subject: <input name="UpdateSubject" size=60 value="Re: <% $Ticket->Subject %>"> <br>
-Attach: <input name="UpdateAttachment" type=file><br>
-<& /Elements/MessageBox, Name=>"UpdateContent", QuoteTransaction=>$ARGS{QuoteTransaction} &>
-               <INPUT TYPE=HIDDEN NAME=id VALUE="<%$Ticket->Id%>"><br>
-
-
-<& /Elements/Submit &>
-  </FORM>
-
-
-
-<%INIT>
-
-my $Ticket = LoadTicket($id);
-
-my $title = "Update ticket #" . $Ticket->id;
-
-$DefaultStatus = $Ticket->Status() unless ($DefaultStatus);
-
-
-Abort("No permission to view update ticket") 
-       unless ( $Ticket->CurrentUserHasRight('ReplyToTicket') or
-                     $Ticket->CurrentUserHasRight('ModifyTicket') ); 
-
-</%INIT>
-
-<%ARGS>
-$id => undef
-$Action => undef
-$DefaultStatus => undef
-</%ARGS>
diff --git a/rt/webrt/SelfService/index.html b/rt/webrt/SelfService/index.html
deleted file mode 100644 (file)
index a377d8c..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<& /SelfService/Elements/Header, title => 'Self Service' &>
-
-<& /SelfService/Elements/MyRequests &>
diff --git a/rt/webrt/Ticket/Attachment/dhandler b/rt/webrt/Ticket/Attachment/dhandler
deleted file mode 100644 (file)
index 0d646cc..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<%perl>
-     my ($ticket, $trans,$attach, $filename);
-     my $arg = $m->dhandler_arg;                # get rest of path
-     if ($arg =~ '^(\d+)/(\d+)') {
-        $trans = $1;
-        $attach = $2;
-     }
-    else {
-        Abort("Corrupted attachment URL.");
-        }
-     my $AttachmentObj = new RT::Attachment($session{'CurrentUser'});
-     $AttachmentObj->Load($attach) || Abort("Attachment '$attach' could not be loaded");
-
-
-     unless ($AttachmentObj->id) {
-        Abort("Bad attachment id. Couldn't find attachment '$attach'\n");
-    }
-     unless ($AttachmentObj->TransactionId() == $trans ) {
-        Abort("Bad transaction number for attachment. $trans should be".$AttachmentObj->TransactionId() ."\n");
-
-     }
-     my $content_type = $AttachmentObj->ContentType || 'text/plain';
-     SetContentType($content_type);
-     $m->out($AttachmentObj->Content); 
-     $m->abort; 
-</%perl>
-
diff --git a/rt/webrt/Ticket/Create.html b/rt/webrt/Ticket/Create.html
deleted file mode 100755 (executable)
index 2c61de0..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Ticket/Attic/Create.html,v 1.1 2002-08-12 06:17:09 ivan Exp $
-%# Copyright 1996-2000 Jesse Vincent <jesse@fsck.com> 
-
-<& /Elements/Header, Title => "Create a new ticket" &>
-<& /Elements/Tabs, current_toptab => "Ticket/Create.html" &>
-<FORM ACTION="Display.html" METHOD="POST" ENCTYPE="multipart/form-data">
-<INPUT TYPE=HIDDEN Name="id" VALUE="new">
-<A NAME="top">
-       
-       
-[<a class="currenttab">Show basics</a>] [<A HREF="#detail">Show details</a>]
-<BR>
-<& /Elements/TitleBoxStart, contentbg => "#cccccc", title => "Create a new ticket"&>
-<div align=right><input type=submit value="Create"></div>
-<TABLE border=0 cellpadding=0 cellspacing=0>
-<TR><TD>Queue</TD>
-<TD><% $QueueObj->Name %>
-<INPUT TYPE=HIDDEN NAME=Queue Value="<%$QueueObj->Name%>">
-</TD>
-<TD>Status:
-</TD>
-<TD>
-<& /Elements/SelectStatus, Name => "Status", Default=> 'new' &>
-</TD>
-<TD>
-Owner: 
-</TD>
-<TD>
-<& /Elements/SelectOwner, Name => "ValueOfOwner", QueueObj => $QueueObj &>
-</TD>
-</TR>
-<TR>
-<TD>
-Requestors: 
-</TD>
-<TD COLSPAN=5>
-<INPUT Name="Requestors" Value="<%$session{CurrentUser}->EmailAddress%>" SIZE=40>
-</TD>
-</TR>
-<TR>
-<TD>
-Cc:
-</TD>
-<TD COLSPAN=5>
- <INPUT NAME="Cc" SIZE=40>
-</TD>
-</TR>
-<TR>
-<TD>
-Admin Cc:
-</TD>
-<TD COLSPAN=5>
- <INPUT NAME="AdminCc" SIZE=40>
-</TD>
-</TR>
-<TR>
-<TD>
-Subject:
-</TD>
-<TD COLSPAN=5>
-<INPUT Name="Subject" SIZE=60 MAXSIZE=100 value="">
-</TD>
-</TR>
-<TR>
-<TD>
-Attach file:
-</TD>
-<TD COLSPAN=5>
-<INPUT TYPE=FILE NAME="Attach">
-</TD>
-</TR>
-<TR>
-<TD COLSPAN=6>
-Describe the issue below:<br>
-<& /Elements/MessageBox, QuoteTransaction => $QuoteTransaction &>
-
-<BR>
-</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT COLSPAN=2>
-</TD>
-</TR>
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit, Label => "Create"&>
-
-<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
-<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
-<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
-<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
-<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
-
-<A NAME="detail">
-       [<A HREF="#top">Show basics</a>] [<a class="currenttab">Show details</a>]
-<BR>
-<TABLE WIDTH="100%" BORDER=0>
-<TR>
-<TD WIDTH="50%" VALIGN=TOP>
-
-         <& /Elements/TitleBoxStart, title => 'The Basics', 
-               title_class=> 'inverse',  
-               color => "#993333" &>
-<TABLE BORDER=0>
-<TR><TD ALIGN=RIGHT>Priority:</TD><TD><input size=3 name="InitialPriority" value="<%$QueueObj->InitialPriority%>"></TD></TR>
-<TR><TD ALIGN=RIGHT>Final Priority:</TD><TD><input size=3 name="FinalPriority" value="<%$QueueObj->FinalPriority%>"></TD></TR>
-<TR><TD ALIGN=RIGHT>Time Worked:</TD><TD><input size=3 name="TimeWorked"></TD></TR>
-<TR><TD ALIGN=RIGHT>Time Left:</TD><TD><input size=3 name="TimeLeft"></TD></TR>
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-<BR>
-<BR>
-
-
- <& /Elements/TitleBoxStart, 
-               title_class=> 'inverse',  
-               title => "Keyword Selections", color => "#993300"
-  &>
-<TABLE BORDER=0>
-% while ( my $KeywordSelect = $KeywordSelects->Next ) {
-%   my $Descendents = $KeywordSelect->KeywordObj->Descendents;
-     <TR><TD ALIGN=RIGHT>
-       <% $KeywordSelect->Name %></TD><TD>
-         <INPUT TYPE="hidden" NAME="KeywordSelectMagic<% $KeywordSelect->id %>" VALUE="1">
-           <SELECT NAME="KeywordSelect-<% $KeywordSelect->id %>"
-             <% $KeywordSelect->Single ? "" : " MULTIPLE " %> SIZE=5>
-%#
-%#  All of this cruft is so we have a 'no keyword' selector for single
-%#  keywords that's only selected when there's no value.
-%
-% foreach my $kid ( keys %{$Descendents} ) {
-             <OPTION VALUE="<% $kid %>"><% $Descendents->{$kid} %></OPTION>
-%   }
-%   if ( $KeywordSelect->Single) {
-<OPTION VALUE="" SELECTED>(empty)</OPTION>
-% }
-           </SELECT>
-      </TD></TR>
-% }
-  
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-
-</TD>
-
-<TD VALIGN="TOP">
-<& /Elements/TitleBoxStart, title => "Dates",
-               title_class=> 'inverse',  
-                color => "#663366" &>
-
-<TABLE BORDER=0>
-<TR><TD ALIGN=RIGHT>Starts:</TD><TD><input size=10 name="Starts"></TD></TR>
-<TR><TD ALIGN=RIGHT>Due:</TD><TD><input size=10 name="Due"></TD></TR>
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-<BR>
-<& /Elements/TitleBoxStart, title => 'Relationships', 
-       title_class=> 'inverse',  
-       titleright => '', color=> "#336633" &>
-
-<i>(Enter ticket ids or URLs, seperated with spaces)</i>
-<TABLE BORDER=0>
-<TR><TD ALIGN=RIGHT>Depends on</TD><TD><input size=10 name="new-DependsOn"></TD></TR>
-<TR><TD ALIGN=RIGHT>Depended on by</TD><TD><input size=10 name="DependsOn-new"></TD></TR>
-<TR><TD ALIGN=RIGHT>Parents</TD><TD><input size=10 name="new-MemberOf"></TD></TR>
-<TR><TD ALIGN=RIGHT>Children</TD><TD><input size=10 name="MemberOf-new"></TD></TR>
-<TR><TD ALIGN=RIGHT>Refers to</TD><TD><input size=10 name="new-RefersTo"></TD></TR>
-<TR><TD ALIGN=RIGHT>Referred to by</TD><TD><input size=10 name="RefersTo-new"></TD></TR>
-
-
-</TABLE>
-<& /Elements/TitleBoxEnd &>
-<BR>
-
-</TD>
-</TR>
-</TABLE>
-<& /Elements/Submit, Label => "Create"&>
-</FORM>
-<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
-<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
-<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
-<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
-<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
-
-<%INIT>
-my $QueueObj = new RT::Queue($session{'CurrentUser'});
-$QueueObj->Load($Queue) || Abort("Queue could not be loaded.");
-my $KeywordSelects = $QueueObj->KeywordSelects;
-
-</%INIT>
-
-<%ARGS>
-$DependsOn => undef
-$DependedOnBy => undef
-$MemberOf => undef
-$QuoteTransaction => undef
-$Queue => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Display.html b/rt/webrt/Ticket/Display.html
deleted file mode 100755 (executable)
index cb0dc25..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Ticket/Attic/Display.html,v 1.1 2002-08-12 06:17:09 ivan Exp $
-%# Copyright 1996-2000 Jesse Vincent <jesse@fsck.com>
-
-<& /Elements/Header, Title => "Ticket #".$Ticket->Id ." ".$Ticket->Subject &>
-<& /Ticket/Elements/Tabs, Ticket => $Ticket, current_tab => 'Ticket/Display.html?id='.$Ticket->id &>
-
-<& /Elements/ListActions, actions => \@Actions &>
-
-<& /Ticket/Elements/ShowSummary,  Ticket => $Ticket &>
-
-
-<BR>
-<& /Ticket/Elements/ShowHistory , 
-      Ticket => $Ticket, 
-      Collapsed => $ARGS{'Collapsed'}, 
-      ShowHeaders => $ARGS{'ShowHeaders'} &> 
-
-  
-<%ARGS>
-$id => undef
-$Create => undef
-$ShowHeaders => undef
-$Collapsed => undef
-</%ARGS>
-
-<%INIT>
-
-  
-  my ($linkid, $message, $tid, $Ticket, @Actions);  
-
-$Ticket = new RT::Ticket($session{'CurrentUser'});
-
-unless ($id) {
-    Abort('No ticket specified');
-}
-
-if ($ARGS{'id'} eq 'new') {
-    # {{{ Create a new ticket
-    
-    my $Queue = new RT::Queue($session{'CurrentUser'});        
-    unless ($Queue->Load($ARGS{'Queue'})) {
-       Abort('Queue not found');
-    }
-    
-    unless ($Queue->CurrentUserHasRight('CreateTicket')) {
-       Abort('You have no permission to create tickets in that queue.');
-    }
-   
-    my $due = new RT::Date($session{'CurrentUser'});
-    $due->Set(Format => 'unknown', Value => $ARGS{'Due'});
-    my $starts = new RT::Date($session{'CurrentUser'});
-    $starts->Set(Format => 'unknown', Value => $ARGS{'Starts'});
-    
-    my @Requestors = split(/,/,$ARGS{'Requestors'});
-    my @Cc = split(/,/,$ARGS{'Cc'});
-    my @AdminCc = split(/,/,$ARGS{'AdminCc'});
-    
-    my $MIMEObj = MakeMIMEEntity( Subject => $ARGS{'Subject'},
-                                 From => $ARGS{'From'},
-                                 Cc => $ARGS{'Cc'},
-                                 Body => $ARGS{'Content'},
-                                 AttachmentFieldName => 'Attach');
-                                 
-    my %create_args = ( 
-                      Queue=>$ARGS{Queue},
-                      Owner=>$ARGS{ValueOfOwner},
-                      InitialPriority=> $ARGS{InitialPriority},
-                      FinalPriority=> $ARGS{FinalPriority},
-                      TimeLeft => $ARGS{TimeLeft},
-                      TimeWorked => $ARGS{TimeWorked},
-                      Requestor=> \@Requestors,
-                      Cc => \@Cc,
-                      AdminCc => \@AdminCc,
-                      Subject=>$ARGS{Subject},
-                      Status=>$ARGS{Status},
-                      Due => $due->ISO,
-                      Starts => $starts->ISO,
-                      MIMEObj => $MIMEObj        
-                     );         
-
-    
-    # we need to get any KeywordSelect-<integer> fields into %create_args..
-    grep { $_ =~ /^KeywordSelect-/ && {$create_args{$_} = $ARGS{$_}}} %ARGS;
-
-    my ($id, $Trans, $ErrMsg)= $Ticket->Create(%create_args);
-    unless ($id && $Trans) {
-       Abort($ErrMsg);
-    }
-    my @linktypes = qw( DependsOn MemberOf RefersTo );
-    
-    foreach my $linktype (@linktypes) {
-      foreach my $luri (split (/ /,$ARGS{"new-$linktype"})) {
-       $luri =~ s/\s*$//; # Strip trailing whitespace
-       my ($val, $msg) = $Ticket->AddLink( Target => $luri,
-                                           Type => $linktype);
-       push @Actions, $msg;
-      }
-      
-      foreach my $luri (split (/ /,$ARGS{"$linktype-new"})) {
-       my ($val, $msg) = $Ticket->AddLink( Base => $luri,
-                                           Type => $linktype);
-       
-       push @Actions, $msg;
-      }
-    }
-    # don't try to change queue to the current queue
-    delete $ARGS{'Queue'};
-
-    push(@Actions, $ErrMsg);
-    unless ($Ticket->CurrentUserHasRight('ShowTicket')) {
-      Abort("No permission to view newly created ticket #".$Ticket->id.".");
-    }
-    # }}}
-}
-
-else { 
-    $Ticket = LoadTicket($ARGS{'id'});
-    unless ($Ticket->CurrentUserHasRight('ShowTicket')) {
-       Abort("No permission to view ticket");
-    }
-
-
-if (defined $ARGS{'Action'}) {
-  if ($ARGS{'Action'} =~ /^(Steal|Kill|Take|SetTold)$/) {
-    my $action = $1;
-    my ($res, $msg)=$Ticket->$action();
-    push(@Actions, $msg);
-  }
-}
-    $ARGS{'UpdateContent'} =~ s/\r\n/\n/g;
-
-    if ($ARGS{'UpdateContent'} &&
-        $ARGS{'UpdateContent'} ne '' &&
-        $ARGS{'UpdateContent'} ne  "-- \n" .
-                                $session{'CurrentUser'}->UserObj->Signature
-       ) {
-           ProcessUpdateMessage(ARGSRef=>\%ARGS, 
-                                Actions=>\@Actions, 
-                                TicketObj=>$Ticket);
-       }
-#Process status updates
-my @BasicActions = ProcessTicketBasics(ARGSRef => \%ARGS, TicketObj=>$Ticket);
-
-push (@Actions, @BasicActions);
-}
-</%INIT>
-
-
-
-
diff --git a/rt/webrt/Ticket/Elements/AddWatchers b/rt/webrt/Ticket/Elements/AddWatchers
deleted file mode 100755 (executable)
index 053cff1..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-<BR>
-<%$msg%><br>
-
-Add new watchers:<br>
-
-<table>
-% if ($Users) {
-<tr><td>
-Type
-</td><td>
-Username
-</td></tr>
-% while (my $u = $Users->Next ) {
-<tr><td><&/Elements/SelectWatcherType, Name => "WatcherTypeUser".$u->Id &></td><td><%$u->Name%> (<%$u->RealName%>)</td></tr>
-% }
-% }
-
-<tr><td>
-Type
-</td><td>
-Email
-</td></tr>
-<tr><td>
-<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail1" &>
-</td><td>
-<input name="WatcherAddressEmail1" size=15>
-</td></tr>
-<tr><td>
-<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail2" &> 
-</td><td>
-<input name="WatcherAddressEmail2" size=15>
-</td></tr>
-<tr><td>
-<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail3" &>
-</td><td>
-<input name="WatcherAddressEmail3" size=15>
-</td></tr>
-</table>
-
-<%INIT>
-my ($msg, $Users);
-if ($UserString) {
-    $Users = new RT::Users($session{'CurrentUser'});
-    $Users->Limit(FIELD => $UserField,
-                 VALUE => $UserString,
-                 OPERATOR => $UserOp);
-     }
-</%INIT>
-
-<%ARGS>
-$UserField => 'Name'
-$UserOp => '='
-$UserString => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/EditBasics b/rt/webrt/Ticket/Elements/EditBasics
deleted file mode 100755 (executable)
index 1214287..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-<TABLE>
-<TR>
-<TD COLSPAN=6>
-        Subject<BR>
-        <input name=Subject value="<%$TicketObj->Subject|h%>"  SIZE=50>
-</TD>
-</TR>
-<TR>
-<TD>
-<& /Elements/ShadedBox, 
-        title => 'Status',
-        content => $SelectStatus
-&>
-</TD>
-<TD>
-
-<& /Elements/ShadedBox,
-       title => 'Time Worked',
-       content => "<input name=TimeWorked value=\"".$TicketObj->TimeWorked."\" SIZE=5>" 
-&>
-
-</TD>
-<TD>
-<& /Elements/ShadedBox,
-       title => 'Time Left',
-       content => "<input name=TimeLeft value=\"".$TicketObj->TimeLeft."\" SIZE=5>" 
-&>
-</TD>
-<TD>
-<& /Elements/ShadedBox,
-       title => 'Priority',
-       content => "<input name=Priority value=\"".$TicketObj->Priority."\" SIZE=3>"
-&>
-
-</TD>
-<TD>
-<& /Elements/ShadedBox,
-       title => 'Final Priority',
-       content => "<input name=FinalPriority value=\"".$TicketObj->FinalPriority."\" SIZE=3>"
-&>
-
-
-</TD>
-<TD>
-<& /Elements/ShadedBox,
-        title => 'Queue',
-        content => "$SelectQueue"
- &>
-</TD>
-</TR>
-</TABLE>
-
-<%INIT>
-#It's hard to do this inline, so we'll preload the html of the selectstatus in here.
-my $SelectStatus = $m->scomp("/Elements/SelectStatus", Name => 'Status', Default=> $TicketObj->Status);
-my $SelectQueue = $m->scomp("/Elements/SelectQueue", Name => 'Queue', Default =>$TicketObj->QueueObj->Id);
-
-</%INIT>
-<%ARGS>
-
-$TicketObj => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/EditDates b/rt/webrt/Ticket/Elements/EditDates
deleted file mode 100755 (executable)
index f04130b..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-<TABLE>
-<TR>
-<TD>
-Starts: 
-</TD>
-<TD>
-<& /Elements/SelectDate, menu_prefix => 'Starts', current => 0 &> 
-        (<% $TicketObj->StartsObj->AsString %>)
-</TD>
-</TR>
-<TR>
-<TD>
-Started:
-</TD>
-<TD>
-<& /Elements/SelectDate, menu_prefix => 'Started', current => 0 &> (<%$TicketObj->StartedObj->AsString %>)
-
-
-
-</TD>
-</TR>
-
-<TR>
-<TD>
-Last Contact:
-</TD>
-<TD>
-<& /Elements/SelectDate, menu_prefix => 'Told', current => 0 &> (<% $TicketObj->ToldObj->AsString %>)
-
-</TD>
-</TR>
-<TR>
-<TD>
-Due:
-</TD>
-<TD>
-
-<& /Elements/SelectDate, menu_prefix => 'Due', current => 0 &> (<% $TicketObj->DueObj->AsString %>)
-</TD>
-</TR>
-
-</TABLE>
-<%ARGS>
-$TicketObj => undef
-</%ARGS>
-
diff --git a/rt/webrt/Ticket/Elements/EditKeywordSelects b/rt/webrt/Ticket/Elements/EditKeywordSelects
deleted file mode 100644 (file)
index 34ade9f..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-
-<TABLE>
-    <TR>
-% while ( my $KeywordSelect = $KeywordSelects->Next ) {
-% my $CurrentKeywords = $TicketObj->KeywordsObj($KeywordSelect->id);   
-%   my $Descendents = $KeywordSelect->KeywordObj->Descendents;
-      <TD VALIGN=TOP>
-       <% $KeywordSelect->Name %>
-       <BR>
-         <INPUT TYPE="hidden" NAME="KeywordSelectMagic<% $KeywordSelect->id %>" VALUE="1">
-           <SELECT NAME="KeywordSelect<% $KeywordSelect->id %>"
-             <% $KeywordSelect->Single ? "" : " MULTIPLE " %> SIZE=5>
-%#
-%#
-%#  All of this cruft is so we have a 'no keyword' selector for single
-%#  keywords that's only selected when there's no value.
-%
-% my $selected_keywords = 0;
-% foreach my $kid ( keys %{$Descendents} ) {
-% my $selected = 0;
-% if ($CurrentKeywords->HasEntry($kid)) { $selected_keywords++; $selected=1;}
-             <OPTION VALUE="<% $kid %>" 
-               <% $selected && 'SELECTED'%>>
-               <% $Descendents->{$kid} %>
-             </OPTION>
-%   }
-%   if ( $KeywordSelect->Single) {
-<OPTION VALUE="" <% ($selected_keywords == 0) && 'SELECTED' %> >(empty)</OPTION>
-% }
-           </SELECT>
-      </TD>
-% }
-    </TR>
-  
-</TABLE>
-
-
-<%INIT>
-my $KeywordSelects = $TicketObj->QueueObj->KeywordSelects;
-</%INIT>
-
-<%ARGS>
-$TicketObj => undef
-</%ARGS>
-
diff --git a/rt/webrt/Ticket/Elements/EditLinks b/rt/webrt/Ticket/Elements/EditLinks
deleted file mode 100755 (executable)
index b0296fc..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Ticket/Elements/Attic/EditLinks,v 1.1 2002-08-12 06:17:09 ivan Exp $
-%# Copyright 1996-2000 Jesse Vincent <jesse@fsck.com>
-
-
-<TABLE>
-<TR>
-<TD VALIGN=TOP>
-<h3>New Relationships</h3>
-<i>Enter tickets or URIs to link tickets to. Seperate multiple entries with spaces.</i><br>
-<TABLE>
-<TR><TD>Merge into:</TD><TD><input name="<%$Ticket->Id%>-MergeInto"> <i>(only one ticket)</i></TD></TR>
-<TR><TD>Depends on:</TD><TD><input name="<%$Ticket->Id%>-DependsOn"></TD></TR>
-<TR><TD>Depended on by:</TD><TD><input name="DependsOn-<%$Ticket->Id%>"></TD></TR>
-<TR><TD>Parents:</TD><TD><input name="<%$Ticket->Id%>-MemberOf"></TD></TR>
-<TR><TD>Children:</TD><TD> <input name="MemberOf-<%$Ticket->Id%>"></TD></TR>
-<TR><TD>Refers to:</TD><TD><input name="<%$Ticket->Id%>-RefersTo"></TD></TR>
-<TR><TD>Referred to by:</TD><TD> <input name="RefersTo-<%$Ticket->Id%>"></TD></TR>
-</TABLE>
-</TD>
-<TD VALIGN=TOP WIDTH=50%>
-<h3>Current Relationships</h3>
-<i>(Check boxes to delete)</i><br>
-
-Depends on:<BR>
-<UL>
-% while (my $link = $Ticket->DependsOn->Next) {
-% my $member = $link->TargetObj;
-<LI>
-<INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>">
-<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%>
-[<%$member->Status%>]
-
-% }
-</UL>
-
-Depended on by:<BR>
-<UL>
-% while (my $link = $Ticket->DependedOnBy->Next) {
-% my $member = $link->BaseObj;
-<LI>
-<INPUT TYPE=CHECKBOX NAME="DeleteLink-<%$link->Base%>-<%$link->Type%>-">
-<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> 
-[<%$member->Status%>]
-% }
-</UL>
-
-Parents:<BR>
-<UL>
-% while (my $link = $Ticket->MemberOf->Next) {
-% my $member = $link->TargetObj;
-<LI>
-<INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>">
-<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%>
-[<%$member->Status%>]
-
-% }
-</UL>
-
-Children:<BR>
-<UL>
-% while (my $link = $Ticket->Members->Next) {
-<LI>
-<INPUT TYPE=CHECKBOX NAME="DeleteLink-<%$link->Base%>-<%$link->Type%>-">
-% my $member = $link->BaseObj;
-<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> 
-[<%$member->Status%>]
-% }
-</UL>
-
-
-Refers to:<BR>
-<UL>
-% while (my $link = $Ticket->RefersTo->Next) {
-<LI>
-<INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>">
-% if ($link->TargetIsLocal) {
-% my $member = $link->TargetObj;
-
-<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<%$member->Status%>]<br>
-% } else {
-<A HREF="<%$link->TargetAsHREF%>"><%$link->Target%></A>
-% }
-%}
-</UL>
-
-Referred to by:<BR>
-<UL>
-% while (my $link = $Ticket->ReferredToBy->Next) {
-<LI>
-<INPUT TYPE=CHECKBOX NAME="DeleteLink-<%$link->Base%>-<%$link->Type%>-">
-% if ($link->BaseIsLocal) {
-% my $member = $link->BaseObj;
-<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<%$member->Status%>]<br>
-% } else {
-<A HREF="<%$link->BaseAsHREF%>"><%$link->Base%></A>
-%}
-% }
-</UL>
-
-                           
-</TD>
-</TR>
-</TABLE>
-
-
-      
-<%ARGS>
-$Ticket => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/EditPeople b/rt/webrt/Ticket/Elements/EditPeople
deleted file mode 100755 (executable)
index 4f69af9..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-
-<TABLE>
-<TR>
-<TD VALIGN=TOP>
-
-<h3>New watchers</h3>
-Find people whose<BR>
-<& /Elements/SelectUsers &>
-<input type=submit name="OnlySearchForPeople" value="Go!">
-
-<& AddWatchers, Ticket => $Ticket, UserString => $UserString,
-        UserOp => $UserOp, UserField => $UserField &> 
-</TD><TD VALIGN=TOP>
-<h3>Owner</h3>
-Owner: <& /Elements/SelectOwner, Name => 'Owner', QueueObj => $Ticket->QueueObj, TicketObj => $Ticket, Default => $Ticket->OwnerObj->Id &>
-<h3>Current watchers</h3>
-(Check box to delete)<br>
-
-Requestors:
-<& EditWatchers, TicketObj => $Ticket, Type => 'requestors' &>
-
-Cc:
-<& EditWatchers, TicketObj => $Ticket, Type => 'cc' &>
-
-Administrative Cc:
-<& EditWatchers, TicketObj => $Ticket, Type => 'admincc' &>
-
-</TD>
-</TR>
-</TABLE>
-
-<%ARGS>
-$UserField => undef
-$UserOp => undef
-$UserString => undef
-$Ticket => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/EditWatchers b/rt/webrt/Ticket/Elements/EditWatchers
deleted file mode 100755 (executable)
index 00185e8..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Ticket/Elements/Attic/EditWatchers,v 1.1 2002-08-12 06:17:09 ivan Exp $
-%# Copyright 1996-2000 Jesse Vincent <jesse@fsck.com>
-
-<ul>
-
-%# Print out a placeholder if there are none.
-%if ($watchers->Count == 0 ) {
-<li><i>none</i>
-% }
-
-
-%while (my $watcher=$watchers->Next) {
-<li>
-<INPUT TYPE=CHECKBOX NAME="DelWatcher<%$watcher->id%>" UNCHECKED>
-%#If there's a principal backing this user, lets give a link to their
-%# account
-%if ($watcher->IsUser) { 
-<a href="<%$RT::WebPath%>/Admin/Users/Modify.html?id=<%$watcher->OwnerObj->id%>">
-<%$watcher->OwnerObj->RealName%></a>:
-%} else {
-Email address:
-%}
-<i><%$watcher->Email%></i>
-%}
-</ul>
-<%INIT>
-my ($watchers, $watcher, $set);
-if ($Type  =~ /^request/i) {
-       $watchers = $TicketObj->Requestors;
-       }
-elsif ($Type =~ /^admin/i) {
-        $watchers = $TicketObj->AdminCc;
-        }
-elsif ($Type =~ /^cc/i) {
-        $watchers = $TicketObj->Cc;
-      }
-else { $watchers = $TicketObj->Watchers;
-       }
-</%INIT>
-<%ARGS>
-$TicketObj => undef
-$Type => undef
-</%ARGS>
-
-
-
diff --git a/rt/webrt/Ticket/Elements/ShowBasics b/rt/webrt/Ticket/Elements/ShowBasics
deleted file mode 100755 (executable)
index 97c84c9..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
- <TABLE WIDTH="100%">
-      <TR>
-       <TD VALIGN=TOP WIDTH="20%">
-         <& /Elements/ShadedBox, title => 'Id' , content => $Ticket->Id &>
-       </TD>
-       <TD VALIGN=TOP WIDTH="20%"> <& /Elements/ShadedBox, title => 'Status' , content => $Ticket->Status &>
-       </TD>
-       <TD VALIGN=TOP WIDTH="20%">
-        <& /Elements/ShadedBox, title => 'Worked' , content => $TimeWorked ." min" &>
-       </TD>
-       <TD VALIGN=TOP WIDTH="20%">
-         <& /Elements/ShadedBox, title => 'Priority', content=> $Ticket->Priority."/".$Ticket->FinalPriority &>
-       </TD>
-       <TD VALIGN=TOP WIDTH="20%">
-         <& /Elements/ShadedBox, title => 'Queue', content=> $Ticket->QueueObj->Name &>
-       </TD>   
-
-
-      </TR>
-    </TABLE>
-<%INIT>
-my $TimeWorked = $Ticket->TimeWorked;
-if ($Ticket->TimeLeft > 0 ) {
-        $TimeWorked = $Ticket->TimeWorked."/".$Ticket->TimeLeft;
-}
-</%INIT>
-<%ARGS>
-$Ticket => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/ShowDates b/rt/webrt/Ticket/Elements/ShowDates
deleted file mode 100755 (executable)
index e17e313..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-<TABLE>
-<TR>
-<TD>
-Created:
-</TD>
-<TD>
-<% $Ticket->CreatedObj->AsString %>
-</TD>
-</TR>
-<TR>
-<TD>
-Starts: 
-</TD>
-<TD>
-<% $Ticket->StartsObj->AsString %> <BR>
-</TD>
-</TR>
-<TR>
-<TD>
-Started:
-</TD>
-<TD>
-<% $Ticket->StartedObj->AsString %>
-</TD>
-</TR>
-
-<TR>
-<TD>
-<a href="Display.html?id=<%$Ticket->id%>&Action=SetTold">Last Contact</a>:
-</TD>
-<TD>
-<% $Ticket->ToldObj->AsString %>
-</TD>
-</TR>
-<TR>
-<TD>
-Due:
-</TD>
-<TD><% $Ticket->DueObj->AsString  %>
-</TD>
-</TR>
-<TR>
-<TD>
-Updated:
-</TD>
-<TD>
-<A HREF="#lasttrans">
-<% $Ticket->LastUpdated ? ($Ticket->LastUpdatedAsString ." by ".$Ticket->LastUpdatedByObj->Name) : "Never" | h %></a>
-</TD>
-</TR>
-</TABLE>
-<%ARGS>
-$Ticket => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/ShowDependencies b/rt/webrt/Ticket/Elements/ShowDependencies
deleted file mode 100755 (executable)
index 488652f..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-Depends on:<BR>
-% while (my $Link = $Ticket->DependsOn->Next) {
-% my $member = $Link->TargetObj;
-<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%>
-[<%$member->Status%>]
- <br>
-% }
-Depended on by:<BR>
-% while (my $Link = $Ticket->DependedOnBy->Next) {
-% my $member = $Link->TargetObj;
-<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> 
-[<%$member->Status%>]
- <br>
-% }
-
-<%ARGS>
-$Ticket => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/ShowHistory b/rt/webrt/Ticket/Elements/ShowHistory
deleted file mode 100755 (executable)
index 155eaaa..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-<TABLE BORDER=0 width="100%">
-<TR>
-<TD ALIGN=LEFT>
-% if ($ShowTitle) {
-<font size=+3>History</font>
-% }
-&nbsp;</TD>
-<TD align=right><font size=-1>Display mode: 
-%  if ($ShowHeaders == $Ticket->Id) {
-[<A HREF="<%$URIFile%>?id=<%$Ticket->id%>">Brief headers</a>]
-<b>[Full headers]</b>
-% } else {
-<b>[Brief headers]</b>
-[<A HREF="<%$URIFile%>?ShowHeaders=<%$Ticket->Id%>&id=<%$Ticket->id%>">Full headers</a>]
-%  }
-</font>
-</TD>
-</TR>
-</TABLE>
-
-<TABLE WIDTH=100% CELLSPACING=0 CELLPADDING=2 BORDER=0>
-% while (my $Transaction = $Transactions->Next) {
-% $i++;
-%      if ($Transactions->IsLast) {
-       <a name="lasttrans"></a>
-%      }
-           <& ShowTransaction, Ticket => $Ticket, Transaction => $Transaction, ShowHeaders => $ShowHeaders, Collapsed => $Collapsed, RowNum => $i  &>
-% }
-</TABLE>
-<%INIT>
-
-my $Transactions = $Ticket->Transactions;
-my $i;
-
-
-</%INIT>
-<%ARGS>
-$URIFile => 'Display.html'
-$Ticket => undef
-$ShowHeaders => undef
-$Collapsed => undef
-$ShowTitle => 1
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/ShowKeywordSelects b/rt/webrt/Ticket/Elements/ShowKeywordSelects
deleted file mode 100644 (file)
index 4f8a178..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<TABLE>
-% while ( my $KeywordSelect = $KeywordSelects->Next ) {
-    <TR>
-      <TD VALIGN=TOP>
-       <% $KeywordSelect->Name %><BR>
-      </TD>
-      <TD VALIGN=TOP>
-       <UL>
-% my $Keywords = $Ticket->KeywordsObj($KeywordSelect->Id);
-% while (my $Keyword = $Keywords->Next) { 
-       <li><% $Keyword->KeywordObj->RelativePath($KeywordSelect->KeywordObj) |n %></li>
-
-%   }
-       </ul>
-      </TD>
-    </TR>
-% }
-</TABLE>
-
-<%INIT>
-my $KeywordSelects = $Ticket->QueueObj->KeywordSelects;
-</%INIT>
-
-<%ARGS>
-$Ticket => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/ShowLinks b/rt/webrt/Ticket/Elements/ShowLinks
deleted file mode 100755 (executable)
index 4979595..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-Depends on:<BR>
-<UL>
-% while (my $Link = $Ticket->DependsOn->Next) {
-% my $member = $Link->TargetObj;
-<LI><a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%>
-[<%$member->Status%>]
-
-% }
-</UL>
-
-Depended on by:<BR>
-<UL>
-% while (my $Link = $Ticket->DependedOnBy->Next) {
-% my $member = $Link->BaseObj;
-<LI><a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> 
-[<%$member->Status%>]
-% }
-</UL>
-Parents:<BR>   
-<UL>
-% while (my $Link = $Ticket->MemberOf->Next) {
-% my $member = $Link->TargetObj;
-<LI><a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%>
-[<%$member->Status%>]
-
-% }
-</UL>
-
-Children:<BR>
-<& /Ticket/Elements/ShowMembers, Ticket => $Ticket &>
-<BR>
-Refers to:<BR>
-<UL>
-% while (my $Link = $Ticket->RefersTo->Next) {
-<LI>
-% if ($Link->TargetIsLocal) {
-% my $member = $Link->TargetObj;
-
-<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<%$member->Status%>]<br>
-% } else {
-<A HREF="<%$Link->TargetAsHREF%>"><%$Link->Target%></A>
-% }
-%}
-</UL>
-
-Referred to by:<BR>
-<UL>
-% while (my $Link = $Ticket->ReferredToBy->Next) {
-<LI>
-% if ($Link->BaseIsLocal) {
-% my $member = $Link->BaseObj;
-<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<%$member->Status%>]<br>
-% } else {
-<A HREF="<%$Link->BaseAsHREF%>"><%$Link->Base%></A>
-%}
-% }
-</UL>
-
-<%ARGS>
-$Ticket => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/ShowMemberOf b/rt/webrt/Ticket/Elements/ShowMemberOf
deleted file mode 100755 (executable)
index df5dc92..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<UL>
-% my $memberof = $Ticket->MemberOf;
-% while (my $member_of = $memberof->Next) {
-<LI><a href="/Ticket/Display.html?id=<%$member_of->Id%>"><%$member_of->Id%></a>: <%$member_of->Subject%> [<%$member_of->Status%>]
-% }
-</UL>
-
-<%INIT>
-</%INIT>
-<%ARGS>
-$Ticket => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/ShowMembers b/rt/webrt/Ticket/Elements/ShowMembers
deleted file mode 100755 (executable)
index 0a6f123..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-% if ($members->Count) {
-<UL>
-% while (my $link = $members->Next) {
-% my $member= $link->BaseObj;
-<LI><a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: <%$member->Subject%> [<%$member->Status%>]<br>
-% if ($depth < 8) {
-<&/Ticket/Elements/ShowMembers, Ticket => $member, depth => ($depth+1) &> 
-% }
-% }
-</UL>
-% }
-
-<%INIT>
-
-my $members = $Ticket->Members;
-
-</%INIT>
-
-<%ARGS>
-$Ticket => undef
-$depth => 1
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/ShowPeople b/rt/webrt/Ticket/Elements/ShowPeople
deleted file mode 100755 (executable)
index ff35f48..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-Owner<BR>
-&nbsp;<B><%$Ticket->OwnerObj->Name%></B><BR>
-Requestors<BR>
-&nbsp;<B><%$Ticket->RequestorsAsString%></B><BR>
-Cc<BR>
-&nbsp;<B><%$Ticket->CcAsString%></B><BR>
-AdminCc<BR>
-&nbsp;<B><%$Ticket->AdminCcAsString%></B>
-<%ARGS>
-$Ticket => undef
-</%ARGS>
-
diff --git a/rt/webrt/Ticket/Elements/ShowReferences b/rt/webrt/Ticket/Elements/ShowReferences
deleted file mode 100755 (executable)
index 37e2fde..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<UL>
-% while (my $Link = $Ticket->RefersTo->Next) {
-<LI>
-% if ($Link->TargetIsLocal) {
-% my $member = $Link->TargetObj;
-
-<a href="/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<%$member->Status%>]<br>
-% } else {
-<A HREF="<%$Link->TargetAsHREF%>"><%$Link->Target%></A>
-% }
-%}
-
-
-
-% while (my $Link = $Ticket->ReferredToBy->Next) {
-<LI>
-% if ($Link->BaseIsLocal) {
-% my $member = $Link->BaseObj;
-<a href="/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<%$member->Status%>]<br>
-% } else {
-<A HREF="<%$Link->BaseAsHREF%>"><%$Link->Base%></A>
-%}
-% }
-</UL>
-<%ARGS>
-$Ticket => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/ShowRequestor b/rt/webrt/Ticket/Elements/ShowRequestor
deleted file mode 100644 (file)
index fcbe71d..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<%PERL>
-my $people = $Ticket->Requestors;
-while (my $requestor=$people->Next) {
-if (($requestor->Owner ) && (my $user=$requestor->OwnerObj)) {
-my $name=$user->RealName || $user->EmailAddress;       
-my $tickets = new RT::Tickets($session{'CurrentUser'});
-$tickets->LimitRequestor(VALUE => $user->EmailAddress);
-$tickets->LimitStatus( VALUE => 'open');
-$tickets->LimitStatus( VALUE => 'new');
-$tickets->RowsPerPage(25);
-$tickets->OrderBy(FIELD => 'Priority',
-                 ORDER => 'DESC');
-</%PERL>
-
-% unless ($user->Privileged) {
-<& /Elements/TitleBoxStart, 
-       title => "<a class='inverse' href=\"$RT::WebPath/Admin/Users/Modify.html?id=".$user->id."\">More about $name</a>" &>
-
-Comments about this user:<BR>
-<B><% ($user->Comments || "No comment entered about this user") %></B><BR>
-
-This user's 25 highest priority tickets:<BR>
-<UL>
-%while (my $w=$tickets->Next) {
-<LI><%$w->Id%>: <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$w->id%>"><%$w->Subject%></a> (<%$w->Status%>)
-%}
-</UL>
-<& /Elements/TitleBoxEnd &>
-
-% }
-% }
-%}
-<%ARGS>
-$Ticket=>undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/ShowSummary b/rt/webrt/Ticket/Elements/ShowSummary
deleted file mode 100755 (executable)
index b80ceb4..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-      <TABLE WIDTH="100%" >
-      <TR>
-       <TD VALIGN=TOP >
-         <& /Elements/TitleBoxStart, title => 'The Basics', 
-               title_href =>"$RT::WebPath/Ticket/Modify.html?id=".$Ticket->Id, 
-               title_class=> 'inverse',  
-               color => "#993333" &>
-         <& /Ticket/Elements/ShowBasics, Ticket => $Ticket &>
-         <& /Elements/TitleBoxEnd &>
-
-       <BR>
-
-         <& /Elements/TitleBoxStart, 
-               title_href =>"$RT::WebPath/Ticket/Modify.html?id=".$Ticket->Id, 
-               title_class=> 'inverse',  
-               title => "Keyword Selections", color => "#993300"
-         &>
-         <& /Ticket/Elements/ShowKeywordSelects, Ticket => $Ticket &>
-         <& /Elements/TitleBoxEnd &>
-
-       
-
-       <BR>
-         <& /Elements/TitleBoxStart, title => 'Relationships', 
-               title_href => "$RT::WebPath/Ticket/ModifyLinks.html?id=".$Ticket->Id, 
-               title_class=> 'inverse',  
-               titleright => '', color=> "#336633" &>
-         <& /Ticket/Elements/ShowLinks, Ticket => $Ticket &>
-       <& /Elements/TitleBoxEnd &>
-       </TD>
-       <BR>
-       <TD VALIGN=TOP >
-
-         <& /Elements/TitleBoxStart, title => "Dates",
-               title_href =>"$RT::WebPath/Ticket/ModifyDates.html?id=".$Ticket->Id, 
-               title_class=> 'inverse',  
-                color => "#663366" &>
-         <& /Ticket/Elements/ShowDates, Ticket => $Ticket &>
-         <& /Elements/TitleBoxEnd &>
-       <BR>  
-         <& /Elements/TitleBoxStart, title => 'People', 
-               title_href =>"$RT::WebPath/Ticket/ModifyPeople.html?id=".$Ticket->Id, 
-               title_class=> 'inverse',  
-               color => "#333399" &>
-         <& /Ticket/Elements/ShowPeople, Ticket => $Ticket &>
-         <& /Elements/TitleBoxEnd &>
-       <BR>
-
-         <& /Ticket/Elements/ShowRequestor, Ticket => $Ticket &>
-
-
-       </TD>
-      </TR>
-    </TABLE>
-<%ARGS>
-$Ticket => undef
-</%ARGS>
-
-
-
-
diff --git a/rt/webrt/Ticket/Elements/ShowTransaction b/rt/webrt/Ticket/Elements/ShowTransaction
deleted file mode 100755 (executable)
index a0da008..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-<TR bgcolor="<%$rowbgcolor%>">
-<TD bgcolor="<%$bgcolor%>"><A NAME="#<%$Transaction->Id%>"></A>&nbsp&nbsp;</TD>
-<TD>&nbsp&nbsp;</TD>
-<TD><font size=-2><% $transdate|n %></font>&nbsp;</TD>
-<TD ALIGN="LEFT"><b><%$Transaction->CreatorObj->Name%> - <%$TicketString%> <%$Transaction->BriefDescription%>
-
-</b></TD>
-<TD><%$TimeTaken%>&nbsp;</TD>
-<TD ALIGN="RIGHT"><font size=-1><%$titlebar_commands|n%></font></TD>
-</TR>
-<%PERL>
-
-unless ($Collapsed) {
- $attachments->GotoFirstItem;
- while (my $message=$attachments->Next) {
-     #we don't want to show any empty transactions, unless they have kids
-     next unless (length $message->Content || $message->Children->Count);
-     my ($headers, $content);
-     
-    </%PERL>
-
-
-<%PERL>
-  if ($message->Parent == 0) {
-      if ($ShowHeaders == $Ticket->Id) {
-         $headers = $message->Headers;
-      } else {
-         $headers = $message->NiceHeaders;
-      }
-      chomp $headers;
-      $headers .= "\n\n" if ($headers);
-  }
-     # 13456 is a random # of about the biggest size we want to see inline text
-     my $MAX_INLINE_BODY = 13456;
-     if ($message->ContentType =~ m{^(text/plain|message|text$)}i && 
-                                   length($message->Content)< $MAX_INLINE_BODY ) {
-
-        $content = $message->Content;
-
-        my $wrapper = new Text::Wrapper (columns=>85);
-        $content = $wrapper->wrap($content);
-         $content =~ s/&/&amp;/g;
-        $content =~ s/</&lt;/g;
-        $content =~ s/>/&gt;/g;
-         $content =~ s!((?:http|https|ftp|mailto):\S*?)([\s"']|&gt;|\.[\n])!<A HREF=\"$1\" TARGET=new>$1</A>$2!g;
-
-
-     }
-     else {
-        $content = "&nbsp;";
-     }
-        
-</%PERL>
-<TR BGCOLOR="<%$rowbgcolor%>">
-      <TD BGCOLOR="<%$bgcolor%>">&nbsp;&nbsp;</TD>
-      <TD>&nbsp&nbsp;</TD>
-      <TD COLSPAN=3 VALIGN=TOP>
-       <PRE>
-<%$headers%><%$content|n%>
-</PRE>
-      </TD>
-      <TD VALIGN=TOP ALIGN=RIGHT>
-       
-% if ($message->Parent == 0  ) {
-<BR>
-% }
-<%PERL>
-my $size = length($message->Content());
-
-if ($size) {
-    if ($size > 1024) {
-       $size = int($size/102.4)/10 . "k";
-    }
-    else {
-       $size = $size ."b";
-    }
-</%PERL>
-<font size=-1><A HREF="Attachment/<%$Transaction->Id%>/<%$message->Id%>/<%$message->Filename%>">Download <%$message->Filename|| '(untitled)'%></a> <% $size %></font>
-% }
-</TD>
-</TR>
-% }
-% }
-
-
-
-<%ARGS>
-$Ticket => undef
-$Transaction => undef
-$ShowHeaders => undef
-$Collapsed => undef
-$ShowTitleBarCommands => 1
-$RowNum => 1
-</%ARGS>
-
-<%INIT>
-
-
-my ($TimeTaken, $TicketString, $bgcolor, $rowbgcolor);
-
-my $transdate = $Transaction->CreatedAsString();
-$transdate =~ s/\s/&nbsp;/g;
-
-if ($RowNum % 2) {
-       $rowbgcolor="#cccccc";
-} else {
-       $rowbgcolor="#ffffff";
-}
-
-if ($Transaction->Type =~ /^(Create|Correspond|Comment$)/) {
-       if ($Transaction->IsInbound) {
-               $bgcolor="#336699";
-       }
-       else {
-               $bgcolor="#339999";
-       }
-} elsif (($Transaction->Field =~ /^Owner$/) or 
-        ($Transaction->Type =~ /^(AddWatcher|DelWatcher)$/)) {
-       $bgcolor="#333399";
-
-} elsif ($Transaction->Type =~ /^(AddLink|DeleteLink)$/) {
-       $bgcolor="#336633";
-} elsif ($Transaction->Type =~ /^(Status|Set|Keyword|Told)$/) {
-       if ($Transaction->Field =~ /^(Told|Starts|Started|Due)$/) {
-               $bgcolor="#663366";     
-       }
-       else {
-               $bgcolor="#993333";
-       }
-}
-else {
-       $bgcolor="#cccccc";
-}
-
-if ($Ticket->Id != $Transaction->Ticket) {
-       $TicketString = "Ticket ".$Transaction->Ticket .": ";
-}
-
-if ($Transaction->TimeTaken > 0) {
-       $TimeTaken = $Transaction->TimeTaken." min"
-}
-my $attachments = $Transaction->Attachments;
-
-my $titlebar_commands='&nbsp;';
-
-# If the transaction has anything attached to it at all
-if ($Transaction->Message->First && $ShowTitleBarCommands) {
-       if ($Transaction->TicketObj->CurrentUserHasRight('ReplyToTicket')) {
-               $titlebar_commands .= 
-                 "[<a href=\"Update.html?id=".
-                 $Transaction->Ticket . "&QuoteTransaction=".$Transaction->Id.
-                 "&Action=Respond\">Reply</a>]&nbsp;";
-       }
-       if ($Transaction->TicketObj->CurrentUserHasRight('CommentOnTicket')) {
-            $titlebar_commands .= 
-            "[<a href=\"Update.html?id=".$Transaction->Ticket. 
-            "&QuoteTransaction=".$Transaction->Id.
-            "&Action=Comment\">Comment</a>]";
-       }
-}
-
-</%INIT>
diff --git a/rt/webrt/Ticket/Elements/Tabs b/rt/webrt/Ticket/Elements/Tabs
deleted file mode 100755 (executable)
index 8cce197..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-<& /Elements/Tabs, tabs => $tabs, actions => $actions, current_tab => $current_tab, tabs_scalar => $tabs_scalar &>
-<%INIT>
-       
-  my $id = $Ticket->id();
-  my $tabs_scalar = '';
-  my $tabs = {
-                A => { title => 'Display',
-                       path => "Ticket/Display.html?id=".$id,
-                     },
-             
-             Ab => { title => 'History',
-                     path => "Ticket/History.html?id=".$id,
-                      },
-             B => { title => 'Basics',
-                    path => "Ticket/Modify.html?id=".$id,
-                  },
-             
-             C => { title => 'Dates',
-                    path => "Ticket/ModifyDates.html?id=".$id,
-                  },
-             
-             D => { title => 'People',
-                    path => "Ticket/ModifyPeople.html?id=".$id,
-                  },
-             E => { title => 'Links',
-                    path => "Ticket/ModifyLinks.html?id=".$id,
-                  },
-             F => { title => 'Jumbo',
-                    path => "Ticket/ModifyAll.html?id=".$id,
-                  },
-             
-            };
-
-my $actions;
-if ($Ticket->CurrentUserHasRight('ModifyTicket') or 
-    $Ticket->CurrentUserHasRight('CommentOnTicket')) {
-    $actions->{'Comment'} = 
-      { 
-       title => 'Comment',
-       path => "Ticket/Update.html?Action=Comment&id=".$id,
-      }
-  };
-
-if ($Ticket->CurrentUserHasRight('ModifyTicket') or 
-    $Ticket->CurrentUserHasRight('ReplyToTicket')) {
-    $actions->{'Reply'} = 
-      { 
-       title => 'Reply',
-       path => "Ticket/Update.html?Action=Respond&id=".$id,
-      }
-  };
-
-if ($Ticket->CurrentUserHasRight('OwnTicket')) {
-    if ($Ticket->OwnerObj->id == $RT::Nobody->id)  {
-       $actions->{'Take'} =    
-         { 
-          path => "Ticket/Display.html?Action=Take&id=".$id,
-          title => 'Take'
-         };
-    }
-    elsif ( $Ticket->OwnerObj->id != $session{CurrentUser}->id) {
-       $actions->{'Steal'} =   
-         { 
-          path => "Ticket/Display.html?Action=Steal&id=".$id,
-          title => 'Steal' 
-         };
-    }
-}
-
-if ($Ticket->CurrentUserHasRight('ModifyTicket')) {
-    if ($Ticket->Status ne 'resolved') {
-       $actions->{'Resolve'} = 
-         { 
-
-           path => "Ticket/Update.html?Action=Comment&DefaultStatus=resolved&id=".$id,
-          title => 'Resolve'
-         };
-    }  
-    if ($Ticket->Status ne 'open') {   
-       $actions->{'Open'} = 
-         { 
-          path => "Ticket/Display.html?Status=open&id=". $id,
-          title => 'Open'
-         };
-    }
-}
-
-
-
-
-if (defined $session{'tickets'}) {
-    my $items = $session{'tickets'}->ItemsArrayRef();
-    my @indexs = grep(($items->[$_]->id == $Ticket->Id), 0 .. $#{$items});
-
-    if ($items->[0]) {
-
-    if ($items->[$indexs[0]]->id == $Ticket->Id) {
-       # Don't display prev links if we're on the first ticket
-       if ( $items->[0]->id != $Ticket->id ) {
-           $tabs_scalar .= '[<A HREF="Display.html?id='.
-             $items->[0]->id.
-               '">&lt;&lt; First</a>] ';
-           $tabs_scalar .= '[<A HREF="Display.html?id='.
-             $items->[$indexs[0]-1]->id.
-               '">&lt; Prev</a>] ';
-       }
-       # Don't display next links if we're on the last ticket
-       if ( $Ticket->id != $items->[-1]->id ) {
-           $tabs_scalar .= '[<A HREF="Display.html?id='.
-             $items->[$indexs[0]+1]->id.
-               '">Next &gt;</a>] ';
-           $tabs_scalar .= '[<A HREF="Display.html?id='.
-             $items->[-1]->id.
-               '">Last &gt;&gt</a>]';
-       }
-       $tabs_scalar .= "<BR><BR>";
-    }
-    }
-}
-</%INIT>
-
-  
-<%ARGS>
-$Ticket => undef
-$current_tab => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/Elements/ToolBar b/rt/webrt/Ticket/Elements/ToolBar
deleted file mode 100755 (executable)
index 108e2f7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<%ARGS>
-$Ticket => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/History.html b/rt/webrt/Ticket/History.html
deleted file mode 100755 (executable)
index e0a5fe1..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Ticket/Attic/History.html,v 1.1 2002-08-12 06:17:09 ivan Exp $
-%# Copyright 1996-2000 Jesse Vincent <jesse@fsck.com>
-
-<& /Elements/Header, Title => "Ticket History #".$Ticket->Id ." ".$Ticket->Subject &>
-<& /Ticket/Elements/Tabs, Ticket => $Ticket, current_tab => 'Ticket/History.html?id='.$Ticket->id  &>
-
-<BR>
-      
-<& /Ticket/Elements/ShowHistory , Ticket => $Ticket, ShowHeaders => $ARGS{'ShowHeaders'}, URIFile => 'History.html' &> 
-
-
-<%ARGS>
-$id => undef
-</%ARGS>
-
-<%INIT>
-
-  
-
-my $Ticket = LoadTicket ($id);
-
-unless ($Ticket->CurrentUserHasRight('ShowTicket')) {
-       Abort("No permission to view ticket");
-}
-
-</%INIT>
-
-
-
-
diff --git a/rt/webrt/Ticket/Modify.html b/rt/webrt/Ticket/Modify.html
deleted file mode 100755 (executable)
index 7a8a792..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<& /Elements/Header, Title => 'Modify ticket #'.$TicketObj->Id &>
-<& /Ticket/Elements/Tabs, Ticket => $TicketObj, current_tab => "Ticket/Modify.html?id=".$TicketObj->Id  &>
-
-<& /Elements/ListActions, actions => \@results &>
-<FORM METHOD=POST ACTION="Modify.html">
-<INPUT TYPE=HIDDEN NAME=id VALUE="<%$TicketObj->Id%>">
-
-<& /Elements/TitleBoxStart, title => 'Modify ticket #'.$TicketObj->Id, 
-  color=> "#993333", width => "100%" &>
-<& Elements/EditBasics, TicketObj => $TicketObj &>
-<& /Elements/TitleBoxEnd &>
-
-<& /Elements/TitleBoxStart, title => 'Keywords', color =>"#993333"&>
-<& Elements/EditKeywordSelects, TicketObj=>$TicketObj &>
-<& /Elements/TitleBoxEnd &>
-
-<& /Elements/Submit, Label => 'Save Changes', Caption => "If you've updated anything above, be sure to", color => "#993333" &>
-</form>
-<%INIT>
-  
-my $TicketObj = LoadTicket($id);
-
-my @results = ProcessTicketBasics(TicketObj => $TicketObj, ARGSRef => \%ARGS);
-my @okresults = ProcessTicketObjectKeywords(TicketObj => $TicketObj, ARGSRef => \%ARGS);
-
-push (@results, @okresults);
-
-# TODO: display the results, even if we can't display the ticket
-
-unless ($TicketObj->CurrentUserHasRight('ShowTicket')) {
-     Abort("No permission to view ticket");
-} 
-
-</%INIT>
-
-
-<%ARGS>
-$id => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/ModifyAll.html b/rt/webrt/Ticket/ModifyAll.html
deleted file mode 100755 (executable)
index ad91373..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-<& /Elements/Header, Title => "Ticket #".$Ticket->Id ." Jumbo update: ".$Ticket->Subject &>
-<& /Ticket/Elements/Tabs, Ticket => $Ticket , current_tab => "Ticket/ModifyAll.html?id=".$Ticket->Id &>
-
-<& /Elements/ListActions, actions => \@results &>
-
-<FORM METHOD=POST ACTION="ModifyAll.html" ENCTYPE="multipart/form-data">
-<INPUT TYPE=HIDDEN NAME=id VALUE="<%$Ticket->Id%>">
-
-
-<& /Elements/TitleBoxStart, title => 'Modify ticket #'.$Ticket->Id,   color=> "#993333", width => "100%" &>
-<& Elements/EditBasics, TicketObj => $Ticket &>
-<& /Elements/TitleBoxEnd &>
-
-<BR>
-
-<& /Elements/TitleBoxStart, title => 'Dates',  width => "100%", color => "#663366"  &>
-<& Elements/EditDates, TicketObj => $Ticket &>
-<& /Elements/TitleBoxEnd &>
-
-<BR>
-
-<& /Elements/TitleBoxStart, title => 'Keywords', color =>"#993333"&>
-<& Elements/EditKeywordSelects, TicketObj=>$Ticket &>
-<& /Elements/TitleBoxEnd &>
-
-<BR>
-
-<& /Elements/TitleBoxStart, title => 'People',width => "100%", color=> "#333399" &>
-<& Elements/EditPeople, Ticket => $Ticket, UserField => $UserField, UserString => $UserString, UserOp => $UserOp &>
-<& /Elements/TitleBoxEnd &>
-
-<BR>
-
-<& /Elements/TitleBoxStart, title => 'Relationships', color => "#336633"&>
-<& Elements/EditLinks, Ticket => $Ticket &>
-<& /Elements/TitleBoxEnd &>
-
-<BR>
-
-<& /Elements/TitleBoxStart, title => 'Update ticket' &>
-<hr>
-Update Type: <select name="UpdateType">
-% if ($CanComment) {
-  <option value="private" >Comments (Not sent to requestors)</option>
-% }
-% if ($CanRespond) {
-   <option value="response">Response to requestors</option>
-% }
-</select> 
-<br>
-
-Subject: <input name="UpdateSubject" size=60 value=""> <br>
-Attach: <input name="UpdateAttachment" type=file> <br>
-<& /Elements/MessageBox, Name=>"UpdateContent", QuoteTransaction=>$ARGS{QuoteTransaction} &>
-<& /Elements/TitleBoxEnd &>
-
-
-<& /Elements/Submit, Label => 'Save Changes', Caption => "If you've updated anything above, be sure to", color => "#333399" &>
-</form>
-
-<%INIT>
-
-
-
-my $Ticket = LoadTicket($id);
-
-my $CanRespond = 0;
-my $CanComment = 0;
-
-
-$CanRespond = 1 if ( $Ticket->CurrentUserHasRight('ReplyToTicket') or
-                     $Ticket->CurrentUserHasRight('ModifyTicket') ); 
-
-$CanComment = 1 if ( $Ticket->CurrentUserHasRight('CommentOnTicket') or
-                     $Ticket->CurrentUserHasRight('ModifyTicket') );
-
-
-my (@wresults, @results, @okresults, @dresults, @lresults);
-
-unless ($OnlySearchForPeople) {
-    @wresults = ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS);
-    @results = ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS);
-    @okresults = ProcessTicketObjectKeywords(TicketObj => $Ticket, ARGSRef => \%ARGS);
-
-    @dresults = ProcessTicketDates( TicketObj => $Ticket, ARGSRef => \%ARGS);
-    @lresults = ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS);
-
-    $ARGS{'UpdateContent'} =~ s/\r\n/\n/g;
-
-    if ($ARGS{'UpdateContent'} && 
-       $ARGS{'UpdateContent'} ne '' && 
-       $ARGS{'UpdateContent'} ne  "-- \n" . 
-                               $session{'CurrentUser'}->UserObj->Signature
-       ) {
-        ProcessUpdateMessage(TicketObj => $Ticket, 
-                             ARGSRef=>\%ARGS, 
-                              Actions=>\@results);
-       }
-}
-push @results, @wresults;
-push @results, @dresults;
-push @results, @lresults;
-push @results, @okresults;
-
-# If they've gone and moved the ticket to somewhere they can't see, etc...
-# TODO: display the results, even if we can't display the ticket.
-
-unless ($Ticket->CurrentUserHasRight('ShowTicket')) {
-   Abort("No permission to view ticket");
-}
-
-
-</%INIT>
-
-
-
-<%ARGS>
-$OnlySearchForPeople => undef
-$UserField => undef
-$UserOp => undef
-$UserString => undef
-$id => undef
-</%ARGS>
-
diff --git a/rt/webrt/Ticket/ModifyDates.html b/rt/webrt/Ticket/ModifyDates.html
deleted file mode 100755 (executable)
index b2ecb68..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<& /Elements/Header, Title => 'Modify dates for #'. $TicketObj->Id &>
-<& /Ticket/Elements/Tabs, Ticket => $TicketObj, current_tab => "Ticket/ModifyDates.html?id=".$TicketObj->Id  &> 
-
-<& /Elements/ListActions, actions => \@results &>
-
-<FORM METHOD=POST ACTION="ModifyDates.html">
-<INPUT TYPE=HIDDEN NAME=id VALUE="<%$TicketObj->Id%>">
-<& /Elements/TitleBoxStart, title => 'Modify dates for ticket #'.$TicketObj->Id,  width => "100%", color => "#663366"  &>
-
-<& Elements/EditDates, TicketObj => $TicketObj &>
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit, color => "#663366" &>
-</form>
-
-
-<%INIT>
-
-my $TicketObj = LoadTicket($id);
-my @results = ProcessTicketDates( TicketObj => $TicketObj, ARGSRef => \%ARGS);
-
-</%INIT>
-
-
-<%ARGS>
-$id => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/ModifyLinks.html b/rt/webrt/Ticket/ModifyLinks.html
deleted file mode 100755 (executable)
index 14c939d..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Ticket/Attic/ModifyLinks.html,v 1.1 2002-08-12 06:17:09 ivan Exp $
-%# Copyright 1996-2000 Jesse Vincent <jesse@fsck.com>
-
-<& /Elements/Header, Title => "Link ticket ".$Ticket->Id &>
-<& /Ticket/Elements/Tabs, Ticket => $Ticket, current_tab => "Ticket/ModifyLinks.html?id=".$Ticket->Id &>
-
-<& /Elements/ListActions, actions => \@results &>
-
-<form action="ModifyLinks.html" method="post">
-<input type="hidden" name="id" value="<%$Ticket->id%>">
-
-<& /Elements/TitleBoxStart, title => 'Edit Relationships', color => "#336633"&>
-<& Elements/EditLinks, Ticket => $Ticket &>
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit, color => "#336633", Caption=> 'Save changes' &>
-</form>
-
-
-
-
-<%INIT>
-  
-my $Ticket = LoadTicket($id);
-my @results = ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS);
-    
-</%INIT>
-      
-      
-<%ARGS>
-$id => undef
-</%ARGS>
diff --git a/rt/webrt/Ticket/ModifyPeople.html b/rt/webrt/Ticket/ModifyPeople.html
deleted file mode 100755 (executable)
index fecf091..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-<& /Elements/Header, Title => 'Modify people related to ticket # ' . $Ticket->id &>
-<& /Ticket/Elements/Tabs, Ticket => $Ticket , current_tab => "Ticket/ModifyPeople.html?id=".$Ticket->Id &>
-
-<& /Elements/ListActions, actions => \@results &>
-
-<FORM METHOD=POST ACTION="ModifyPeople.html">
-<INPUT TYPE=HIDDEN NAME=id VALUE="<%$Ticket->Id%>">
-<& /Elements/TitleBoxStart, title => 'Modify people related to ticket #'.$Ticket->Id,   width => "100%", color=> "#333399" &>
-<& Elements/EditPeople, Ticket => $Ticket, UserField => $UserField, UserString => $UserString, UserOp => $UserOp &>
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit, Label => 'Save Changes', Caption => "If you've updated anything above, be sure to", color => "#333399" &>
-</form>
-
-<%INIT>
-
-my (@results, @wresults);
-
-my $Ticket = LoadTicket($id);
-
-# if we're trying to search for watchers and nothing else
-unless ($OnlySearchForPeople) {
-    @results = ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS);
-    @wresults = ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS);
-}
-
-push @results, @wresults;
-</%INIT>
-
-
-
-<%ARGS>
-$OnlySearchForPeople => undef
-$UserField => undef
-$UserOp => undef
-$UserString => undef
-$id => undef
-</%ARGS>
-
diff --git a/rt/webrt/Ticket/Update.html b/rt/webrt/Ticket/Update.html
deleted file mode 100755 (executable)
index be22666..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-<& /Elements/Header, Title=> $title  &>
-<& /Ticket/Elements/Tabs, Ticket => $Ticket &>
-<& /Elements/TitleBoxStart, title => "Update ticket" &>
-
-<FORM ACTION="Display.html" NAME="TicketUpdate" 
-       METHOD=POST enctype="multipart/form-data">
-
-<TABLE>
-<TR><TD>
-<a href="ModifyPeople.html?id=<%$Ticket->Id%>">Ticket watchers</A></TD><TD align=right>
-Requestor:
-</TD><TD>
-<b><% $Ticket->RequestorsAsString %></b>
-</TD></TR>
-<TR><TD>&nbsp;</TD><TD align=right>
-Cc:
-</TD><TD>
-<b><% $Ticket->CcAsString %></b>
-</TD></TR>
-<TR><TD>&nbsp;</TD><TD align=right>
-AdminCc:
-</TD><TD>
-<b><% $Ticket->AdminCcAsString %></b>
-</TD></TR>
-</TR>
-</TABLE>
-<hr>
-
-<TABLE BORDER=0>
-
-<tr><td align=right>Status:</td>
-<td>
-<& /Elements/SelectStatus, Name=>"Status", Default => $DefaultStatus &>
-Owner:  
-<& /Elements/SelectOwner, Name=>"Owner", Default => $Ticket->OwnerObj->Id(), QueueObj => $Ticket->QueueObj, TicketObj => $Ticket &>
-Worked: <input size=4 name="UpdateTimeWorked"> minutes</td></tr>
-<tr><td align=right>Update Type:</td>
-<td><select name="UpdateType">
-% if ($CanComment) {
-  <option value="private" <%$CommentDefault%>>Comments (Not sent to requestors)</option>
-% }
-% if ($CanRespond) {
-   <option value="response" <%$ResponseDefault%>>Response to requestors</option>
-% }
-</select> 
-</td></tr>
-<tr><td align=right>Subject:</td><td> <input name="UpdateSubject" size=60 value="<%$Ticket->Subject()%>"></td></tr>
-<tr><td align=right>Cc:</td><td> <input name="UpdateCc" size=60><BR>
-<i><font size=-2>(Sends a carbon-copy of this update to a comma-delimited list
-of email addresses. Does <b>not</b> change who will receive future updates.)</font></i>
-</td></tr>
-<tr><td align=right>Bcc:</td><td> <input name="UpdateBcc" size=60><BR>
-<i><font size=-2>(Sends a blind carbon-copy of this update to a comma-delimited list
-of email addresses. Does <b>not</b> change who will receive future updates.)</font></i>
-</td></tr>
-<tr><td align=right>Attach:</td><td><input name="UpdateAttachment" type="file"></td></tr>
-</table>
-<& /Elements/MessageBox, Name=>"UpdateContent", QuoteTransaction=>$ARGS{QuoteTransaction} &>
-               <INPUT TYPE=HIDDEN NAME=id VALUE="<%$Ticket->Id%>"><br>
-
-
-
-
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit &>
-  </FORM>
-
-
-
-<%INIT>
-
-my $CanRespond = 0;
-my $CanComment = 0;
-my $title;
-
-my $Ticket = LoadTicket($id);
-
-
-if ($DefaultStatus eq 'resolved') {
-       $title = "Resolve";
-} else {
-       $title = "Update";
-}
-
-$title .= " ticket #" . $Ticket->id . " (" .$Ticket->Subject.")";
-
-# Things needed in the template - we'll do the processing here, just
-# for the convinience:
-my $CommentDefault=$Action eq "Comment" ? "SELECTED" : "";
-my $ResponseDefault=$Action eq "Respond" ? "SELECTED" : "";
-
-$DefaultStatus = $Ticket->Status() unless ($DefaultStatus);
-
-$CanRespond = 1 if ( $Ticket->CurrentUserHasRight('ReplyToTicket') or
-                     $Ticket->CurrentUserHasRight('ModifyTicket') ); 
-
-$CanComment = 1 if ( $Ticket->CurrentUserHasRight('CommentOnTicket') or
-                     $Ticket->CurrentUserHasRight('ModifyTicket') ); 
-       
-
-     
-     
-
-</%INIT>
-
-<%ARGS>
-$id => undef
-$Action => undef
-$DefaultStatus => undef
-</%ARGS>
diff --git a/rt/webrt/User/Prefs.html b/rt/webrt/User/Prefs.html
deleted file mode 100755 (executable)
index d769977..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<& /Elements/Header, Title=>"Preferences" &>
-<& /Elements/Tabs &>
-
-<& /Elements/ListActions, actions => \@results &>
-<form method=post>
-
-% unless ($RT::WebExternalAuth) {
-<& /Elements/TitleBoxStart, title => 'Change password'  &>
-New password: <input type=password name="NewPass1" size=16>
-Confirm: <input type=password name="NewPass2" size=16>
-<& /Elements/TitleBoxEnd &>
-<BR>
-% }
-<& /Elements/TitleBoxStart, title => 'Signature'  &>
-<INPUT TYPE=HIDDEN NAME="SignatureMagic" VALUE=1>
-<TEXTAREA COLS=72 ROWS=4 WRAP=HARD NAME="Signature"><% $session{'CurrentUser'}->UserObj->Signature %></TEXTAREA>
-<br>
-<BR>
-<& /Elements/TitleBoxEnd &>
-<& /Elements/Submit &>
-         </form>
-
-
-<%INIT>
-my @results;
-
-if ($NewPass1) {
-    if ($NewPass1 ne $NewPass2) {
-       push (@results, "Passwords did not match.");
-    }  
-    else {
-       my ($val, $msg)=$session{'CurrentUser'}->UserObj->SetPassword($NewPass1);
-       push (@results, "Password: ".$msg);
-    }  
-}
-if ($Signature || $SignatureMagic) {
-    $Signature =~ s/(\r\n|\r)/\n/g;
-    if ($Signature ne $session{'CurrentUser'}->UserObj->Signature) {
-       my ($val, $msg)=$session{'CurrentUser'}->UserObj->SetSignature($Signature);
-       push (@results, "Signature: ".$msg);
-    }
-}
-#A hack to make sure that session gets rewritten.
-
-$session{'i'}++;
-</%INIT>
-
-<%ARGS>
-$Signature => undef
-$SignatureMagic => undef
-$NewPass1 => undef
-$NewPass2 => undef
-</%ARGS>
diff --git a/rt/webrt/autohandler b/rt/webrt/autohandler
deleted file mode 100755 (executable)
index 16cdbc7..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-%# $Header: /home/cvs/cvsroot/freeside/rt/webrt/Attic/autohandler,v 1.1 2002-08-12 06:17:08 ivan Exp $
-<& /Elements/Footer, %ARGS &>
-
-<%INIT>
-
-$m->{'rt_base_time'} = time;
-
-#if it's a noauth file, don't ask for auth.
-if ($m->base_comp->path =~ '^/+NoAuth/') {
-        $m->call_next();
-       $m->abort();
-}
-
-# If RT is configured for external auth, let's get REMOTE_USER
-# We intentionally don't test for REMOTE_USER to meet our policy
-elsif ($RT::WebExternalAuth){
-
-    $user = $ENV{'REMOTE_USER'};
-    $session{'CurrentUser'} = RT::CurrentUser->new();
-    $session{'CurrentUser'}->Load($user);
-    unless ($session{'CurrentUser'}->id() ) {
-        delete $session{'CurrentUser'};
-        $m->comp('/Elements/Login', %ARGS, Error=> 'You are not an authorized user');
-        $m->abort();
-    }
-}
-# If the user is loging in, let's authenticate
-elsif (defined ($user) && defined ($pass)){
-    
-    $session{'CurrentUser'} = RT::CurrentUser->new();
-    $session{'CurrentUser'}->Load($user);
-    unless ($session{'CurrentUser'}->id() ) {
-       delete $session{'CurrentUser'};
-       $m->comp('/Elements/Login', %ARGS, Error=> 'Your username or password is incorrect');
-        $m->abort();
-    };
-    unless ($session{'CurrentUser'}->IsPassword($pass)) {
-       delete $session{'CurrentUser'};
-       
-       $m->comp('/Elements/Login', Error => 'Your username or password is incorrect', %ARGS);
-       $m->abort();
-    }
-}
-  
-
-#If we've got credentials, lets serve the file up.
-if ( (defined $session{'CurrentUser'}) and 
-     ( $session{'CurrentUser'}->Id) ) {
-    
-    # If the user isn\'t privileged, they can only see SelfService
-    if ((! $session{'CurrentUser'}->Privileged) and
-       ($m->base_comp->path !~ '^/+SelfService/') ) {
-       $m->comp('/SelfService/index.html');
-       $m->abort();
-    }
-    else {
-       $m->call_next;
-    }
-}
-
-#If we have no credentials
-else {
-    $m->comp('/Elements/Login', %ARGS);
-    $m->abort();
-}
-
-</%INIT>
-
-<%ARGS>
-$user => undef
-$pass => undef
-</%ARGS>
diff --git a/rt/webrt/index.html b/rt/webrt/index.html
deleted file mode 100644 (file)
index 0c1091a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-<& /Elements/Header, Title=>"Start page", Refresh => $session{'home_refresh_interval'} &>
-<& /Elements/Tabs, current_toptab => '' &>
-<TABLE BORDER=0 WIDTH=100%>
-<TR VALIGN=TOP>
-<TD WIDTH=70%>
-<& /Elements/CustomHomepageHeader, %ARGS &>
-<& /Elements/MyTickets &>
-<BR>
-<& /Elements/MyRequests &>
-</TD>
-<TD>
-<& /Elements/Quicksearch &>
-<BR>
-<form method=get action="index.html">
-<& /Elements/Refresh, Name => 'HomeRefreshInterval', Default => $session {'home_refresh_interval'} &>
-<div align=right><input type=submit value="Go!"></div>
-</form>
-</TD>
-</TR>
-</TABLE>
-<%init>
-if ($ARGS{'HomeRefreshInterval'}) {
-       $session{'home_refresh_interval'} = $ARGS{'HomeRefreshInterval'};
-}
-</%init>
diff --git a/sql-ledger/SL/AM.pm b/sql-ledger/SL/AM.pm
new file mode 100644 (file)
index 0000000..d691b3c
--- /dev/null
@@ -0,0 +1,694 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Administration module
+#    Chart of Accounts
+#    template routines
+#    preferences
+#
+#======================================================================
+
+package AM;
+
+
+sub get_account {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT accno, description, charttype, gifi_accno,
+                 category, link
+                 FROM chart
+                WHERE id = $form->{id}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $ref = $sth->fetchrow_hashref(NAME_lc);
+  
+  foreach my $key (keys %$ref) {
+    $form->{"$key"} = $ref->{"$key"};
+  }
+
+  $sth->finish;
+
+
+  # get default accounts
+  $query = qq|SELECT inventory_accno_id, income_accno_id, expense_accno_id
+              FROM defaults|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  $ref = $sth->fetchrow_hashref(NAME_lc);
+
+  map { $form->{$_} = $ref->{$_} } keys %ref;
+
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+
+sub save_account {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database, turn off AutoCommit
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  # sanity check, can't have AR with AR_...
+  if ($form->{AR} || $form->{AP} || $form->{IC}) {
+    map { delete $form->{$_} } qw(AR_amount AR_tax AR_paid AP_amount AP_tax AP_paid IC_sale IC_cogs IC_taxpart IC_income IC_expense IC_taxservice);
+  }
+  
+  $form->{link} = "";
+  foreach my $item ($form->{AR},
+                   $form->{AR_amount},
+                    $form->{AR_tax},
+                    $form->{AR_paid},
+                    $form->{AP},
+                   $form->{AP_amount},
+                   $form->{AP_tax},
+                   $form->{AP_paid},
+                   $form->{IC},
+                   $form->{IC_sale},
+                   $form->{IC_cogs},
+                   $form->{IC_taxpart},
+                   $form->{IC_income},
+                   $form->{IC_expense},
+                   $form->{IC_taxservice},
+                   $form->{CT_tax}
+                   ) {
+     $form->{link} .= "${item}:" if ($item);
+  }
+  chop $form->{link};
+
+  # if we have an id then replace the old record
+  $form->{description} =~ s/'/''/g;
+
+  # strip blanks from accno
+  map { $form->{$_} =~ s/ //g; } qw(accno gifi_accno);
+  
+  my ($query, $sth);
+  
+  if ($form->{id}) {
+    $query = qq|UPDATE chart SET
+                accno = '$form->{accno}',
+               description = '$form->{description}',
+               charttype = '$form->{charttype}',
+               gifi_accno = '$form->{gifi_accno}',
+               category = '$form->{category}',
+               link = '$form->{link}'
+               WHERE id = $form->{id}|;
+  } else {
+    $query = qq|INSERT INTO chart 
+                (accno, description, charttype, gifi_accno, category, link)
+                VALUES ('$form->{accno}', '$form->{description}',
+               '$form->{charttype}', '$form->{gifi_accno}',
+               '$form->{category}', '$form->{link}')|;
+  }
+  $dbh->do($query) || $form->dberror($query);
+  
+
+  if ($form->{IC_taxpart} || $form->{IC_taxservice} || $form->{CT_tax}) {
+
+    my $chart_id = $form->{id};
+    
+    unless ($form->{id}) {
+      # get id from chart
+      $query = qq|SELECT id
+                  FROM chart
+                 WHERE accno = '$form->{accno}'|;
+      $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+
+      ($chart_id) = $sth->fetchrow_array;
+      $sth->finish;
+    }
+    
+    # add account if it doesn't exist in tax
+    $query = qq|SELECT chart_id
+                FROM tax
+               WHERE chart_id = $chart_id|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    my ($tax_id) = $sth->fetchrow_array;
+    $sth->finish;
+    
+    # add tax if it doesn't exist
+    unless ($tax_id) {
+      $query = qq|INSERT INTO tax (chart_id, rate)
+                  VALUES ($chart_id, 0)|;
+      $dbh->do($query) || $form->dberror($query);
+    }
+  } else {
+    # remove tax
+    if ($form->{id}) {
+      $query = qq|DELETE FROM tax
+                 WHERE chart_id = $form->{id}|;
+      $dbh->do($query) || $form->dberror($query);
+    }
+  }
+
+
+  # commit
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+  
+}
+
+
+
+sub delete_account {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database, turn off AutoCommit
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  # delete chart of account record
+  $query = qq|DELETE FROM chart
+              WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  # set inventory_accno_id, income_accno_id, expense_accno_id to defaults
+  $query = qq|UPDATE parts
+              SET inventory_accno_id = 
+                        (SELECT inventory_accno_id FROM defaults)
+             WHERE inventory_accno_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+  
+  $query = qq|UPDATE parts
+              SET income_accno_id =
+                        (SELECT income_accno_id FROM defaults)
+             WHERE income_accno_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+  
+  $query = qq|UPDATE parts
+              SET expense_accno_id =
+                        (SELECT expense_accno_id FROM defaults)
+             WHERE expense_accno_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+  
+  foreach my $table (qw(partstax customertax vendortax tax)) {
+    $query = qq|DELETE FROM $table
+               WHERE chart_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+  }
+
+  # commit and redirect
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+  
+  $rc;
+
+}
+
+
+sub gifi_accounts {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT accno, description
+                 FROM gifi
+                ORDER BY accno|;
+
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{ALL} }, $ref;
+  }
+
+  $sth->finish;
+  $dbh->disconnect;
+  
+}
+
+
+
+sub get_gifi {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  
+  my $query = qq|SELECT accno, description
+                 FROM gifi
+                WHERE accno = '$form->{accno}'|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $ref = $sth->fetchrow_hashref(NAME_lc);
+  
+  map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+
+sub save_gifi {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  
+  $form->{description} =~ s/'/''/g;
+  $form->{accno} =~ s/ //g;
+
+  # id is the old account number!
+  if ($form->{id}) {
+    $query = qq|UPDATE gifi SET
+                accno = '$form->{accno}',
+               description = '$form->{description}'
+               WHERE accno = '$form->{id}'|;
+  } else {
+    $query = qq|INSERT INTO gifi 
+                (accno, description)
+                VALUES ('$form->{accno}', '$form->{description}')|;
+  }
+  $dbh->do($query) || $form->dberror($query);
+  
+  $dbh->disconnect;
+
+}
+
+
+sub delete_gifi {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  
+  # id is the old account number!
+  $query = qq|DELETE FROM gifi
+             WHERE accno = '$form->{id}'|;
+  $dbh->do($query) || $form->dberror($query);
+  
+  $dbh->disconnect;
+
+}
+
+
+sub load_template {
+  my ($self, $form) = @_;
+  
+  open(TEMPLATE, "$form->{file}") or $form->error("$form->{file} : $!");
+
+  while (<TEMPLATE>) {
+    $form->{body} .= $_;
+  }
+
+  close(TEMPLATE);
+
+}
+
+
+sub save_template {
+  my ($self, $form) = @_;
+  
+  open(TEMPLATE, ">$form->{file}") or $form->error("$form->{file} : $!");
+  
+  # strip \r
+  $form->{body} =~ s/\r\n/\n/g;
+  print TEMPLATE $form->{body};
+
+  close(TEMPLATE);
+
+}
+
+
+
+sub save_preferences {
+  my ($self, $myconfig, $form, $memberfile, $userspath) = @_;
+
+  map { ($form->{$_}) = split /--/, $form->{$_} } qw(inventory_accno income_accno expense_accno fxgain_accno fxloss_accno);
+  
+  my @a;
+  $form->{curr} =~ s/ //g;
+  map { push(@a, uc pack "A3", $_) if $_ } split /:/, $form->{curr};
+  $form->{curr} = join ':', @a;
+    
+  # connect to database
+  my $dbh = $form->dbconnect_noauto($myconfig);
+  
+  # these defaults are database wide
+  # user specific variables are in myconfig
+  # save defaults
+  my $query = qq|UPDATE defaults SET
+                 inventory_accno_id = 
+                    (SELECT id FROM chart
+                               WHERE accno = '$form->{inventory_accno}'),
+                 income_accno_id =
+                    (SELECT id FROM chart
+                               WHERE accno = '$form->{income_accno}'),
+                expense_accno_id =
+                    (SELECT id FROM chart
+                               WHERE accno = '$form->{expense_accno}'),
+                fxgain_accno_id =
+                    (SELECT id FROM chart
+                               WHERE accno = '$form->{fxgain_accno}'),
+                fxloss_accno_id =
+                    (SELECT id FROM chart
+                               WHERE accno = '$form->{fxloss_accno}'),
+                invnumber = '$form->{invnumber}',
+                sonumber = '$form->{sonumber}',
+                ponumber = '$form->{ponumber}',
+                yearend = '$form->{yearend}',
+                curr = '$form->{curr}',
+                weightunit = '$form->{weightunit}',
+                businessnumber = '$form->{businessnumber}'
+               |;
+  $dbh->do($query) || $form->dberror($query);
+
+  # update name
+  my $name = $form->{name};
+  $name =~ s/'/''/g;
+  $query = qq|UPDATE employee
+              SET name = '$name'
+             WHERE login = '$form->{login}'|;
+  $dbh->do($query) || $form->dberror($query);
+  
+  foreach my $item (split / /, $form->{taxaccounts}) {
+    $query = qq|UPDATE tax
+               SET rate = |.($form->{$item} / 100).qq|,
+               taxnumber = '$form->{"taxnumber_$item"}'
+               WHERE chart_id = $item|;
+    $dbh->do($query) || $form->dberror($query);
+  }
+
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  # save first currency in myconfig
+  $form->{currency} = substr($form->{curr},0,3);
+  
+  my $myconfig = new User "$memberfile", "$form->{login}";
+  
+  foreach my $item (keys %$form) {
+    $myconfig->{$item} = $form->{$item};
+  }
+
+  $myconfig->save_member($memberfile, $userspath);
+
+  $rc;
+  
+}
+
+
+sub defaultaccounts {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  
+  # get defaults from defaults table
+  my $query = qq|SELECT * FROM defaults|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+  
+  $form->{defaults} = $sth->fetchrow_hashref(NAME_lc);
+  $form->{defaults}{IC} = $form->{defaults}{inventory_accno_id};
+  $form->{defaults}{IC_income} = $form->{defaults}{income_accno_id};
+  $form->{defaults}{IC_expense} = $form->{defaults}{expense_accno_id};
+  $form->{defaults}{FX_gain} = $form->{defaults}{fxgain_accno_id};
+  $form->{defaults}{FX_loss} = $form->{defaults}{fxloss_accno_id};
+  
+  
+  $sth->finish;
+
+
+  $query = qq|SELECT id, accno, description, link
+              FROM chart
+              WHERE link LIKE '%IC%'
+              ORDER BY accno|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    foreach my $key (split(/:/, $ref->{link})) {
+      if ($key =~ /IC/) {
+       $nkey = $key;
+       if ($key =~ /cogs/) {
+         $nkey = "IC_expense";
+       }
+       if ($key =~ /sale/) {
+         $nkey = "IC_income";
+       }
+        %{ $form->{IC}{$nkey}{$ref->{accno}} } = ( id => $ref->{id},
+                                        description => $ref->{description} );
+      }
+    }
+  }
+  $sth->finish;
+
+
+  $query = qq|SELECT id, accno, description
+              FROM chart
+             WHERE category = 'I'
+             AND charttype = 'A'
+              ORDER BY accno|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    %{ $form->{IC}{FX_gain}{$ref->{accno}} } = ( id => $ref->{id},
+                                      description => $ref->{description} );
+  }
+  $sth->finish;
+
+  $query = qq|SELECT id, accno, description
+              FROM chart
+             WHERE category = 'E'
+             AND charttype = 'A'
+              ORDER BY accno|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    %{ $form->{IC}{FX_loss}{$ref->{accno}} } = ( id => $ref->{id},
+                                      description => $ref->{description} );
+  }
+  $sth->finish;
+
+
+  # now get the tax rates and numbers
+  $query = qq|SELECT chart.id, chart.accno, chart.description,
+              tax.rate * 100 AS rate, tax.taxnumber
+              FROM chart, tax
+             WHERE chart.id = tax.chart_id|;
+
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    $form->{taxrates}{$ref->{accno}}{id} = $ref->{id};
+    $form->{taxrates}{$ref->{accno}}{description} = $ref->{description};
+    $form->{taxrates}{$ref->{accno}}{taxnumber} = $ref->{taxnumber} if $ref->{taxnumber};
+    $form->{taxrates}{$ref->{accno}}{rate} = $ref->{rate} if $ref->{rate};
+  }
+
+  $sth->finish;
+  $dbh->disconnect;
+  
+}
+
+
+sub backup {
+  my ($self, $myconfig, $form, $userspath) = @_;
+  
+  my ($tmpfile, $out, $mail);
+  
+  if ($form->{media} eq 'email') {
+
+    my $boundary = time;
+    $tmpfile = "$userspath/$boundary.$myconfig->{dbname}-$form->{dbversion}.sql";
+    $out = $form->{OUT};
+    $form->{OUT} = ">$tmpfile";
+    
+    use SL::Mailer;
+    $mail = new Mailer;
+
+    $mail->{to} = qq|"$myconfig->{name}" <$myconfig->{email}>|;
+    $mail->{from} = qq|"$myconfig->{name}" <$myconfig->{email}>|;
+    $mail->{subject} = "SQL-Ledger Backup / $myconfig->{dbname}-$form->{dbversion}.sql";
+    @{ $mail->{attachments} } = ($tmpfile);
+    $mail->{version} = $form->{version};
+    $mail->{fileid} = "$boundary.";
+
+    $myconfig->{signature} =~ s/\\n/\r\n/g;
+    $mail->{message} = "--\n$myconfig->{signature}";
+    
+  }
+    
+  if ($form->{OUT}) {
+    open(OUT, "$form->{OUT}") or $form->error("$form->{OUT} : $!");
+  } else {
+    open(OUT, ">-") or $form->error("STDOUT : $!");
+  }
+
+  if ($form->{media} eq 'file') {
+    print OUT qq|Content-Type: Application/File;
+Content-Disposition: filename="$myconfig->{dbname}-$form->{dbversion}.sql"\n\n|;
+  }
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  # get all the tables
+  my @tables = $dbh->tables;
+  
+  my $today = scalar localtime;
+  
+
+  $myconfig->{dbhost} = 'localhost' unless $myconfig->{dbhost};
+  
+  print OUT qq|-- SQL-Ledger Backup
+-- Dataset: $myconfig->{dbname}
+-- Version: $form->{dbversion}
+-- Host: $myconfig->{dbhost}
+-- Login: $form->{login}
+-- User: $myconfig->{name}
+-- Date: $today
+--
+-- set options
+$myconfig->{dboptions};
+--
+|;
+
+  foreach $table (@tables) {
+    my $query = qq|SELECT * FROM $table|;
+    
+    my $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    $query = qq|INSERT INTO $table (|;
+    map { $query .= qq|$sth->{NAME}->[$_],| } (0 .. $sth->{NUM_OF_FIELDS} - 1);
+    chop $query;
+
+    $query .= qq|) VALUES|;
+    
+    print OUT qq|--
+DELETE FROM $table;
+|;
+    while (my @arr = $sth->fetchrow_array) {
+
+      $fields = "(";
+      foreach my $item (@arr) {
+       if (defined $item) {
+         $item =~ s/'/''/g;
+         $fields .= qq|'$item',|;
+       } else {
+         $fields .= 'NULL,';
+       }
+      }
+       
+      chop $fields;
+      $fields .= ")";
+       
+      print OUT qq|$query $fields;\n|;
+    }
+    
+    $sth->finish;
+  }
+
+  $query = qq|SELECT last_value FROM id|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my ($id) = $sth->fetchrow_array;
+  $sth->finish;
+  
+  print OUT qq|--
+DROP SEQUENCE id;
+CREATE SEQUENCE id START $id;
+|;
+  
+  close(OUT);
+  
+  $dbh->disconnect;
+
+  if ($form->{media} eq 'email') {
+    my $err = $mail->send($out);
+    $_ = $tmpfile;
+    unlink;
+  }
+    
+}
+
+
+sub closedto {
+  my ($self, $myconfig, $form) = @_;
+
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT closedto, revtrans FROM defaults|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  ($form->{closedto}, $form->{revtrans}) = $sth->fetchrow_array;
+  
+  $sth->finish;
+  
+  $dbh->disconnect;
+
+}
+
+sub closebooks {
+  my ($self, $myconfig, $form) = @_;
+
+  my $dbh = $form->dbconnect($myconfig);
+
+  if ($form->{revtrans}) {
+   
+    $query = qq|UPDATE defaults SET closedto = NULL,
+                                   revtrans = '1'|;
+  } else {
+    if ($form->{closedto}) {
+    
+      $query = qq|UPDATE defaults SET closedto = '$form->{closedto}',
+                                     revtrans = '0'|;
+    } else {
+      
+      $query = qq|UPDATE defaults SET closedto = NULL,
+                                     revtrans = '0'|;
+    }
+  }
+
+  # set close in defaults
+  $dbh->do($query) || $form->dberror($query);
+  
+  $dbh->disconnect;
+  
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/AP.pm b/sql-ledger/SL/AP.pm
new file mode 100644 (file)
index 0000000..e1870f8
--- /dev/null
@@ -0,0 +1,381 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Accounts Payables database backend routines
+#
+#======================================================================
+
+
+package AP;
+
+
+sub post_transaction {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect_noauto($myconfig);
+  
+  my ($null, $taxrate, $amount);
+  my $exchangerate = 0;
+  
+  # split and store id numbers in link accounts
+  ($form->{AP}{payables}) = split(/--/, $form->{AP});
+  map { ($form->{AP}{"amount_$_"}) = split(/--/, $form->{"AP_amount_$_"}) } (1 .. $form->{rowcount});
+
+  if ($form->{currency} eq $form->{defaultcurrency}) {
+    $form->{exchangerate} = 1;
+  } else {
+    $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, 'sell');
+
+    $form->{exchangerate} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{exchangerate});
+  }
+  
+  # reverse and parse amounts
+  for my $i (1 .. $form->{rowcount}) {
+    $form->{"amount_$i"} = $form->round_amount($form->parse_amount($myconfig, $form->{"amount_$i"}) * $form->{exchangerate} * -1, 2);
+    $amount += ($form->{"amount_$i"} * -1);
+  }
+
+  # this is for ap
+  $form->{amount} = $amount;
+  
+  # taxincluded doesn't make sense if there is no amount
+  $form->{taxincluded} = 0 if ($form->{amount} == 0);
+
+  for my $item (split / /, $form->{taxaccounts}) {
+    $form->{AP}{"tax_$item"} = $item;
+
+    $amount = $form->round_amount($form->parse_amount($myconfig, $form->{"tax_$item"}), 2);
+    
+    $form->{"tax_$item"} = $form->round_amount($amount * $form->{exchangerate}, 2) * -1;
+    $form->{total_tax} += ($form->{"tax_$item"} * -1);
+  }
+
+  # adjust paidaccounts if there is no date in the last row
+  $form->{paidaccounts}-- unless ($form->{"datepaid_$form->{paidaccounts}"});
+  
+  $form->{invpaid} = 0;
+  # add payments
+  for my $i (1 .. $form->{paidaccounts}) {
+    $form->{"paid_$i"} = $form->round_amount($form->parse_amount($myconfig, $form->{"paid_$i"}), 2);
+    
+    $form->{invpaid} += $form->{"paid_$i"};
+    $form->{datepaid} = $form->{"datepaid_$i"};
+
+  }
+  
+  $form->{invpaid} = $form->round_amount($form->{invpaid} * $form->{exchangerate}, 2);
+  
+  if ($form->{taxincluded} *= 1) {
+    for $i (1 .. $form->{rowcount}) {
+      $tax = $form->{total_tax} * $form->{"amount_$i"} / $form->{amount};
+      $amount = $form->{"amount_$i"} - $tax;
+      $form->{"amount_$i"} = $form->round_amount($amount, 2);
+      $diff += $amount - $form->{"amount_$i"};
+    }
+
+    # deduct taxes from amount
+    $form->{amount} -= $form->{total_tax};
+    # deduct difference from amount_1
+    $form->{amount_1} += $form->round_amount($diff, 2);
+  }
+
+  $form->{netamount} = $form->{amount};
+  
+  # store invoice total, this goes into ap table
+  $form->{invtotal} = $form->{amount} + $form->{total_tax};
+  
+  # amount for total AP
+  $form->{payables} = $form->{invtotal};
+
+  my ($query, $sth);
+
+  # if we have an id delete old records
+  if ($form->{id}) {
+
+    # delete detail records
+    $query = qq|DELETE FROM acc_trans WHERE trans_id = $form->{id}|;
+
+    $dbh->do($query) || $form->dberror($query);
+    
+  } else {
+    my $uid = time;
+    $uid .= $form->{login};
+
+    $query = qq|INSERT INTO ap (invnumber, employee_id)
+                VALUES ('$uid', (SELECT id FROM employee
+                                WHERE login = '$form->{login}') )|;
+    $dbh->do($query) || $form->dberror($query);
+    
+    $query = qq|SELECT id FROM ap
+                WHERE invnumber = '$uid'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{id}) = $sth->fetchrow_array;
+    $sth->finish;
+   
+  }
+
+  # escape '
+  $form->{notes} =~ s/'/''/g;
+    
+  $form->{datepaid} = $form->{transdate} unless ($form->{datepaid});
+  my $datepaid = ($form->{invpaid} != 0) ? qq|'$form->{datepaid}'| : 'NULL';
+
+  $query = qq|UPDATE ap SET
+             invnumber = '$form->{invnumber}',
+             transdate = '$form->{transdate}',
+             ordnumber = '$form->{ordnumber}',
+             vendor_id = $form->{vendor_id},
+             taxincluded = '$form->{taxincluded}',
+             amount = $form->{invtotal},
+             duedate = '$form->{duedate}',
+             paid = $form->{invpaid},
+             datepaid = $datepaid,
+             netamount = $form->{netamount},
+             curr = '$form->{currency}',
+             notes = '$form->{notes}'
+             WHERE id = $form->{id}
+            |;
+  $dbh->do($query) || $form->dberror($query);
+
+
+  # update exchangerate
+  if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
+    $form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, 0, $form->{exchangerate});
+  }
+
+  # add individual transactions
+  foreach my $item (keys %{ $form->{AP} }) {
+    if ($form->{$item} != 0) {
+      $project_id = 'NULL';
+      if ($item =~ /amount_/) {
+       if ($form->{"project_id_$'"} && $form->{"projectnumber_$'"}) { 
+         $project_id = $form->{"project_id_$'"};
+       }
+      }
+
+      # insert detail records in acc_trans
+      $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
+                                         project_id)
+                  VALUES ($form->{id}, (SELECT id FROM chart
+                                       WHERE accno = '$form->{AP}{$item}'),
+                 $form->{$item}, '$form->{transdate}', $project_id)|;
+      $dbh->do($query) || $form->dberror($query);
+    }
+  }
+
+  # if there is no amount but a payment record a payable
+  if ($form->{amount} == 0 && $form->{invtotal} == 0) {
+    $form->{payables} = $form->{invpaid};
+  }
+  # add paid transactions
+  for my $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"} != 0) {
+
+      $exchangerate = 0;
+      if ($form->{currency} eq $form->{defaultcurrency}) {
+       $form->{"exchangerate_$i"} = 1;
+      } else {
+       $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'sell');
+
+       $form->{"exchangerate_$i"} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{"exchangerate_$i"});
+      }
+      
+      
+      # get paid account
+      ($form->{AP}{"paid_$i"}) = split(/--/, $form->{"AP_paid_$i"});
+      $form->{"datepaid_$i"} = $form->{transdate} unless ($form->{"datepaid_$i"});
+
+      # if there is no amount and invtotal is zero there is no exchangerate
+      if ($form->{amount} == 0 && $form->{invtotal} == 0) {
+       $form->{exchangerate} = $form->{"exchangerate_$i"};
+      }
+      
+      $amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate} * -1, 2);
+      if ($form->{payables}) {
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                   transdate)
+                   VALUES ($form->{id},
+                          (SELECT id FROM chart
+                           WHERE accno = '$form->{AP}{payables}'),
+                   $amount, '$form->{"datepaid_$i"}')|;
+       $dbh->do($query) || $form->dberror($query);
+      }
+      $form->{payables} = $amount;
+
+      # add payment
+      $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                  transdate, source)
+                  VALUES ($form->{id},
+                        (SELECT id FROM chart
+                         WHERE accno = '$form->{AP}{"paid_$i"}'),
+                 $form->{"paid_$i"}, '$form->{"datepaid_$i"}',
+                 '$form->{"source_$i"}')|;
+      $dbh->do($query) || $form->dberror($query);
+      
+      # add exchange rate difference
+      $amount = $form->round_amount($form->{"paid_$i"} * ($form->{"exchangerate_$i"} - 1), 2);
+      if ($amount != 0) {
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                   transdate, fx_transaction, cleared)
+                   VALUES ($form->{id},
+                          (SELECT id FROM chart
+                           WHERE accno = '$form->{AP}{"paid_$i"}'),
+                   $amount, '$form->{"datepaid_$i"}', '1', '0')|;
+
+       $dbh->do($query) || $form->dberror($query);
+      }
+
+      # exchangerate gain/loss
+      $amount = $form->round_amount($form->{"paid_$i"} * ($form->{exchangerate} - $form->{"exchangerate_$i"}), 2);
+
+      if ($amount != 0) {
+       $accno = ($amount > 0) ? $form->{fxgain_accno} : $form->{fxloss_accno};
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                   transdate, fx_transaction, cleared)
+                   VALUES ($form->{id}, (SELECT id FROM chart
+                                         WHERE accno = '$accno'),
+                   $amount, '$form->{"datepaid_$i"}', '1', '0')|;
+       $dbh->do($query) || $form->dberror($query);
+      }
+
+      # update exchange rate record
+      if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
+       $form->update_exchangerate($dbh, $form->{currency}, $form->{"datepaid_$i"}, 0, $form->{"exchangerate_$i"});
+      }
+    }
+  }
+  
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+  
+}
+
+
+
+
+sub delete_transaction {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  # check for other foreign currency transactions
+  $form->delete_exchangerate($dbh) if ($form->{currency} ne $form->{defaultcurrency});
+  
+  my $query = qq|DELETE FROM ap WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  $query = qq|DELETE FROM acc_trans WHERE trans_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+  
+  # commit and redirect
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+
+}
+
+
+
+
+sub ap_transactions {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $incemp = qq|, (SELECT e.name FROM employee e
+                   WHERE a.employee_id = e.id) AS employee
+                | if ($form->{l_employee});
+                   
+  my $query = qq|SELECT a.id, a.invnumber, a.transdate, a.duedate,
+                 a.amount, a.paid, a.ordnumber, v.name, a.invoice,
+                a.netamount, a.datepaid, a.notes
+                
+                $incemp
+                
+                FROM ap a, vendor v
+                WHERE a.vendor_id = v.id|;
+
+  if ($form->{vendor_id}) {
+    $query .= " AND a.vendor_id = $form->{vendor_id}";
+  } else {
+    if ($form->{vendor}) {
+      my $vendor = $form->like(lc $form->{vendor});
+      $query .= " AND lower(v.name) LIKE '$vendor'";
+    }
+  }
+  if ($form->{invnumber}) {
+    my $invnumber = $form->like(lc $form->{invnumber});
+    $query .= " AND lower(a.invnumber) LIKE '$invnumber'";
+  }
+  if ($form->{ordnumber}) {
+    my $ordnumber = $form->like(lc $form->{ordnumber});
+    $query .= " AND lower(a.ordnumber) LIKE '$ordnumber'";
+  }
+  if ($form->{notes}) {
+    my $notes = $form->like(lc $form->{notes});
+    $query .= " AND lower(a.notes) LIKE '$notes'";
+  }
+
+  $query .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+  $query .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+  if ($form->{open} || $form->{closed}) {
+    unless ($form->{open} && $form->{closed}) {
+      $query .= " AND a.amount <> a.paid" if ($form->{open});
+      $query .= " AND a.amount = a.paid" if ($form->{closed});
+    }
+  }
+
+  my @a = (transdate, invnumber, name);
+  push @a, "employee" if $self->{l_employee};
+  my $sortorder = join ', ', $form->sort_columns(@a);
+  $sortorder = $form->{sort} unless $sortorder;
+
+  $query .= " ORDER by $sortorder";
+
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ap = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{AP} }, $ap;
+  }
+  
+  $sth->finish;
+  $dbh->disconnect;
+  
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/AR.pm b/sql-ledger/SL/AR.pm
new file mode 100644 (file)
index 0000000..4ea3d82
--- /dev/null
@@ -0,0 +1,381 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Accounts Receivable module backend routines
+#
+#======================================================================
+
+package AR;
+
+
+sub post_transaction {
+  my ($self, $myconfig, $form) = @_;
+
+  my ($null, $taxrate, $amount, $tax, $diff);
+  my $exchangerate = 0;
+  my $i;
+
+  # split and store id numbers in link accounts
+  map { ($form->{AR}{"amount_$_"}) = split(/--/, $form->{"AR_amount_$_"}) } (1 .. $form->{rowcount});
+  ($form->{AR}{receivables}) = split(/--/, $form->{AR});
+
+  if ($form->{currency} eq $form->{defaultcurrency}) {
+    $form->{exchangerate} = 1;
+  } else {
+    $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, 'buy');
+  }
+  
+  $form->{exchangerate} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{exchangerate}); 
+
+  for $i (1 .. $form->{rowcount}) {
+    $form->{"amount_$i"} = $form->round_amount($form->parse_amount($myconfig, $form->{"amount_$i"}) * $form->{exchangerate}, 2);
+    $amount += $form->{"amount_$i"};
+  }
+  
+  # this is for ar
+  $form->{amount} = $amount;
+
+  # taxincluded doesn't make sense if there is no amount
+  $form->{taxincluded} = 0 if ($form->{amount} == 0);
+
+  foreach my $item (split / /, $form->{taxaccounts}) {
+    $form->{AR}{"tax_$item"} = $item;
+
+    $amount = $form->round_amount($form->parse_amount($myconfig, $form->{"tax_$item"}), 2);
+    
+    $form->{"tax_$item"} = $form->round_amount($amount * $form->{exchangerate}, 2);
+    $form->{total_tax} += $form->{"tax_$item"};
+
+  }
+
+  # adjust paidaccounts if there is no date in the last row
+  $form->{paidaccounts}-- unless ($form->{"datepaid_$form->{paidaccounts}"});
+
+  $form->{invpaid} = 0;
+  # add payments
+  for $i (1 .. $form->{paidaccounts}) {
+    $form->{"paid_$i"} = $form->round_amount($form->parse_amount($myconfig, $form->{"paid_$i"}), 2);
+    
+    $form->{invpaid} += $form->{"paid_$i"};
+    $form->{datepaid} = $form->{"datepaid_$i"};
+
+    # reverse payment
+    $form->{"paid_$i"} *= -1;
+
+  }
+  
+  $form->{invpaid} = $form->round_amount($form->{invpaid} * $form->{exchangerate}, 2);
+  if ($form->{taxincluded} *= 1) {
+    for $i (1 .. $form->{rowcount}) {
+      $tax = $form->{total_tax} * $form->{"amount_$i"} / $form->{amount};
+      $amount = $form->{"amount_$i"} - $tax;
+      $form->{"amount_$i"} = $form->round_amount($amount, 2);
+      $diff += $amount - $form->{"amount_$i"};
+    }
+    
+    $form->{amount} -= $form->{total_tax};
+    # deduct difference from amount_1
+    $form->{amount_1} += $form->round_amount($diff, 2);
+  }
+
+  # store invoice total, this goes into ar table
+  $form->{invtotal} = $form->{amount} + $form->{total_tax};
+  
+  # connect to database
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my ($query, $sth);
+  
+  # if we have an id delete old records
+  if ($form->{id}) {
+
+    # delete detail records
+    $query = qq|DELETE FROM acc_trans WHERE trans_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+    
+  } else {
+    my $uid = time;
+    $uid .= $form->{login};
+
+    $query = qq|INSERT INTO ar (invnumber, employee_id)
+                VALUES ('$uid', (SELECT id FROM employee
+                                WHERE login = '$form->{login}') )|;
+    $dbh->do($query) || $form->dberror($query);
+    
+    $query = qq|SELECT id FROM ar
+                WHERE invnumber = '$uid'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{id}) = $sth->fetchrow_array;
+    $sth->finish;
+
+  }
+
+  # escape '
+  $form->{notes} =~ s/'/''/g;
+
+  # record last payment date in ar table
+  $form->{datepaid} = $form->{transdate} unless $form->{datepaid};
+  my $datepaid = ($form->{invpaid} != 0) ? qq|'$form->{datepaid}'| : 'NULL';
+  
+  $query = qq|UPDATE ar set
+             invnumber = '$form->{invnumber}',
+             ordnumber = '$form->{ordnumber}',
+             transdate = '$form->{transdate}',
+             customer_id = $form->{customer_id},
+             taxincluded = '$form->{taxincluded}',
+             amount = $form->{invtotal},
+             duedate = '$form->{duedate}',
+             paid = $form->{invpaid},
+             datepaid = $datepaid,
+             netamount = $form->{amount},
+             curr = '$form->{currency}',
+             notes = '$form->{notes}'
+             WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  
+  # amount for AR account
+  $form->{receivables} = $form->round_amount($form->{invtotal} * -1, 2);
+  
+
+  # update exchangerate
+  if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
+    $form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, $form->{exchangerate}, 0);
+  }
+  
+  # add individual transactions for AR, amount and taxes
+  foreach my $item (keys %{ $form->{AR} }) {
+    if ($form->{$item} != 0) {
+      $project_id = 'NULL';
+      if ($item =~ /amount_/) {
+       if ($form->{"project_id_$'"} && $form->{"projectnumber_$'"}) {
+         $project_id = $form->{"project_id_$'"};
+       }
+      }
+      
+      # insert detail records in acc_trans
+      $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
+                                         project_id)
+                 VALUES ($form->{id}, (SELECT id FROM chart
+                                       WHERE accno = '$form->{AR}{$item}'),
+                 $form->{$item}, '$form->{transdate}', $project_id)|;
+      $dbh->do($query) || $form->dberror($query);
+    }
+  }
+
+  # if there is no amount but a payment record a receivables
+  if ($form->{amount} == 0 && $form->{invtotal} == 0) {
+    $form->{receivables} = $form->{invpaid} * -1;
+  }
+  
+  # add paid transactions
+  for my $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"} != 0) {
+      
+       ($form->{AR}{"paid_$i"}) = split(/--/, $form->{"AR_paid_$i"});
+      $form->{"datepaid_$i"} = $form->{transdate} unless ($form->{"datepaid_$i"});
+     
+      $exchangerate = 0;
+      if ($form->{currency} eq $form->{defaultcurrency}) {
+       $form->{"exchangerate_$i"} = 1;
+      } else {
+       $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'buy');
+       
+       $form->{"exchangerate_$i"} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{"exchangerate_$i"}); 
+      }
+      
+
+      # if there is no amount and invtotal is zero there is no exchangerate
+      if ($form->{amount} == 0 && $form->{invtotal} == 0) {
+       $form->{exchangerate} = $form->{"exchangerate_$i"};
+      }
+      
+      # receivables amount
+      $amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate} * -1, 2);
+      
+      if ($form->{receivables} != 0) {
+       # add receivable
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                   transdate)
+                   VALUES ($form->{id},
+                          (SELECT id FROM chart
+                           WHERE accno = '$form->{AR}{receivables}'),
+                   $amount, '$form->{"datepaid_$i"}')|;
+       $dbh->do($query) || $form->dberror($query);
+      }
+      $form->{receivables} = $amount;
+      
+      # add payment
+      $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                 transdate, source)
+                 VALUES ($form->{id},
+                        (SELECT id FROM chart
+                         WHERE accno = '$form->{AR}{"paid_$i"}'),
+                 $form->{"paid_$i"}, '$form->{"datepaid_$i"}',
+                 '$form->{"source_$i"}')|;
+      $dbh->do($query) || $form->dberror($query);
+      
+      
+      # exchangerate difference for payment
+      $amount = $form->round_amount($form->{"paid_$i"} * ($form->{"exchangerate_$i"} - 1), 2);
+       
+      if ($amount != 0) {
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                   transdate, fx_transaction, cleared)
+                   VALUES ($form->{id},
+                          (SELECT id FROM chart
+                           WHERE accno = '$form->{AR}{"paid_$i"}'),
+                   $amount, '$form->{"datepaid_$i"}', '1', '0')|;
+       $dbh->do($query) || $form->dberror($query);
+      }
+       
+      # exchangerate gain/loss
+      $amount = $form->round_amount($form->{"paid_$i"} * ($form->{exchangerate} - $form->{"exchangerate_$i"}), 2);
+      
+      if ($amount != 0) {
+       $accno = ($amount > 0) ? $form->{fxgain_accno} : $form->{fxloss_accno};
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                   transdate, fx_transaction, cleared)
+                   VALUES ($form->{id}, (SELECT id FROM chart
+                                         WHERE accno = '$accno'),
+                   $amount, '$form->{"datepaid_$i"}', '1', '0')|;
+       $dbh->do($query) || $form->dberror($query);
+      }
+      
+      # update exchangerate record
+      if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
+       $form->update_exchangerate($dbh, $form->{currency}, $form->{"datepaid_$i"}, $form->{"exchangerate_$i"}, 0);
+      }
+    }
+  }
+
+
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+  
+}
+
+
+
+sub delete_transaction {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database, turn AutoCommit off
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  # check for other foreign currency transactions
+  $form->delete_exchangerate($dbh) if ($form->{currency} ne $form->{defaultcurrency});
+
+  my $query = qq|DELETE FROM ar WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  $query = qq|DELETE FROM acc_trans WHERE trans_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+  
+  # commit
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+  
+  $rc;
+
+}
+
+
+
+sub ar_transactions {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $incemp = qq|, (SELECT e.name FROM employee e
+                   WHERE a.employee_id = e.id) AS employee
+                  | if ($form->{l_employee});
+                  
+  my $query = qq|SELECT a.id, a.invnumber, a.ordnumber, a.transdate,
+                 a.duedate, a.netamount, a.amount, a.paid, c.name,
+                a.invoice, a.datepaid, a.terms, a.notes, a.shippingpoint
+                
+                $incemp
+                
+                FROM ar a, customer c
+                WHERE a.customer_id = c.id|;
+  
+  if ($form->{customer_id}) {
+    $query .= " AND a.customer_id = $form->{customer_id}";
+  } else {
+    if ($form->{customer}) {
+      my $customer = $form->like(lc $form->{customer});
+      $query .= " AND lower(c.name) LIKE '$customer'";
+    }
+  }
+  if ($form->{invnumber}) {
+    my $invnumber = $form->like(lc $form->{invnumber});
+    $query .= " AND lower(a.invnumber) LIKE '$invnumber'";
+  }
+  if ($form->{ordnumber}) {
+    my $ordnumber = $form->like(lc $form->{ordnumber});
+    $query .= " AND lower(a.ordnumber) LIKE '$ordnumber'";
+  }
+  if ($form->{notes}) {
+    my $notes = $form->like(lc $form->{notes});
+    $query .= " AND lower(a.notes) LIKE '$notes'";
+  }
+  
+  $query .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+  $query .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+  if ($form->{open} || $form->{closed}) {
+    unless ($form->{open} && $form->{closed}) {
+    $query .= " AND a.amount <> a.paid" if ($form->{open});
+    $query .= " AND a.amount = a.paid" if ($form->{closed});
+    }
+  }
+
+  my @a = (transdate, invnumber, name);
+  push @a, "employee" if $form->{l_employee};
+  my $sortorder = join ', ', $form->sort_columns(@a);
+  $sortorder = $form->{sort} unless $sortorder;
+  
+  $query .= " ORDER by $sortorder";
+  
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ar = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{AR} }, $ar;
+  }
+  
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/CA.pm b/sql-ledger/SL/CA.pm
new file mode 100644 (file)
index 0000000..b71749d
--- /dev/null
@@ -0,0 +1,262 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+# chart of accounts
+#
+# CHANGE LOG:
+#   DS. 2000-07-04  Created
+#
+#======================================================================
+
+
+package CA;
+
+
+sub all_accounts {
+  my ($self, $myconfig, $form) = @_;
+
+  my $amount = ();
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT accno,
+                 SUM(acc_trans.amount) AS amount
+                 FROM chart, acc_trans
+                WHERE chart.id = acc_trans.chart_id
+                GROUP BY accno|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    $amount{$ref->{accno}} = $ref->{amount}
+  }
+  $sth->finish;
+  $query = qq|SELECT accno, description
+              FROM gifi|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $gifi = ();
+  while (my ($accno, $description) = $sth->fetchrow_array) {
+    $gifi{$accno} = $description;
+  }
+  $sth->finish;
+
+  $query = qq|SELECT c.id, c.accno, c.description, c.charttype, c.gifi_accno,
+              c.category, c.link
+              FROM chart c
+             ORDER BY accno|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+  while (my $ca = $sth->fetchrow_hashref(NAME_lc)) {
+    $ca->{amount} = $amount{$ca->{accno}};
+    $ca->{gifi_description} = $gifi{$ca->{gifi_accno}};
+    if ($ca->{amount} < 0) {
+      $ca->{debit} = $ca->{amount} * -1;
+    } else {
+      $ca->{credit} = $ca->{amount};
+    }
+    push @{ $form->{CA} }, $ca;
+  }
+
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+
+sub all_transactions {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  # get chart_id
+  my $query = qq|SELECT id FROM chart
+                 WHERE accno = '$form->{accno}'|;
+  if ($form->{accounttype} eq 'gifi') {
+    $query = qq|SELECT id FROM chart
+                WHERE gifi_accno = '$form->{gifi_accno}'|;
+  }
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my @id = ();
+  while (my ($id) = $sth->fetchrow_array) {
+    push @id, $id;
+  }
+
+  $sth->finish;
+
+  my $where = '1 = 1';
+  # build WHERE clause from dates if any
+  if ($form->{fromdate}) {
+    $where .= " AND ac.transdate >= '$form->{fromdate}'";
+  }
+  if ($form->{todate}) {
+    $where .= " AND ac.transdate <= '$form->{todate}'";
+  }
+
+  my $sortorder = join ', ', $form->sort_columns(qw(transdate reference description));
+  my $false = ($myconfig->{dbdriver} eq 'Pg') ? FALSE : q|'0'|;
+  
+  # Oracle workaround, use ordinal positions
+  my %ordinal = ( transdate => 4,
+                 reference => 2,
+                 description => 3 );
+  map { $sortorder =~ s/$_/$ordinal{$_}/ } keys %ordinal;
+
+   
+  if ($form->{accno}) {
+    # get category for account
+    $query = qq|SELECT category
+                FROM chart
+               WHERE accno = '$form->{accno}'|;
+    $sth = $dbh->prepare($query);
+
+    $sth->execute || $form->dberror($query);
+    ($form->{category}) = $sth->fetchrow_array;
+    $sth->finish;
+    
+    if ($form->{fromdate}) {
+      # get beginning balance
+      $query = qq|SELECT SUM(ac.amount)
+                 FROM acc_trans ac, chart c
+                 WHERE ac.chart_id = c.id
+                 AND c.accno = '$form->{accno}'
+                 AND ac.transdate < date '$form->{fromdate}'
+                 |;
+      $sth = $dbh->prepare($query);
+
+      $sth->execute || $form->dberror($query);
+      ($form->{balance}) = $sth->fetchrow_array;
+      $sth->finish;
+    }
+  }
+  
+  if ($form->{accounttype} eq 'gifi' && $form->{gifi_accno}) {
+    # get category for account
+    $query = qq|SELECT category
+                FROM chart
+               WHERE gifi_accno = '$form->{gifi_accno}'|;
+    $sth = $dbh->prepare($query);
+
+    $sth->execute || $form->dberror($query);
+    ($form->{category}) = $sth->fetchrow_array;
+    $sth->finish;
+    if ($form->{fromdate}) {
+      # get beginning balance
+      $query = qq|SELECT SUM(ac.amount)
+                 FROM acc_trans ac, chart c
+                 WHERE ac.chart_id = c.id
+                 AND c.gifi_accno = '$form->{gifi_accno}'
+                 AND ac.transdate < date '$form->{fromdate}'
+                 |;
+      $sth = $dbh->prepare($query);
+
+      $sth->execute || $form->dberror($query);
+      ($form->{balance}) = $sth->fetchrow_array;
+      $sth->finish;
+    }
+  }
+  $query = "";
+  
+  foreach my $id (@id) {
+    
+    # get all transactions
+    $query .= qq|
+      SELECT g.id, g.reference, g.description, ac.transdate,
+               $false AS invoice,
+               ac.amount, 'gl' as charttype
+               FROM gl g, acc_trans ac
+               WHERE $where
+               AND ac.chart_id = $id
+               AND ac.trans_id = g.id
+      UNION ALL
+      SELECT a.id, a.invnumber, c.name, ac.transdate,
+               a.invoice,
+               ac.amount, 'ar' as charttype
+               FROM ar a, acc_trans ac, customer c
+               WHERE $where
+               AND ac.chart_id = $id
+               AND ac.trans_id = a.id
+               AND a.customer_id = c.id
+      UNION ALL
+      SELECT a.id, a.invnumber, v.name, ac.transdate,
+               a.invoice,
+               ac.amount, 'ap' as charttype
+               FROM ap a, acc_trans ac, vendor v
+               WHERE $where
+               AND ac.chart_id = $id
+               AND ac.trans_id = a.id
+               AND a.vendor_id = v.id
+      UNION ALL|;
+  }
+
+  $query =~ s/UNION ALL$//;
+  $query .= qq|
+      ORDER BY $sortorder|;
+
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ca = $sth->fetchrow_hashref(NAME_lc)) {
+
+    # gl
+    if ($ca->{charttype} eq "gl") {
+      $ca->{module} = "gl";
+    }
+
+    # ap
+    if ($ca->{charttype} eq "ap") {
+      $ca->{module} = ($ca->{invoice}) ? 'ir' : 'ap';
+    }
+
+    # ar
+    if ($ca->{charttype} eq "ar") {
+      $ca->{module} = ($ca->{invoice}) ? 'is' : 'ar';
+    }
+
+    if ($ca->{amount} < 0) {
+      $ca->{debit} = $ca->{amount} * -1;
+      $ca->{credit} = 0;
+    } else {
+      $ca->{credit} = $ca->{amount};
+      $ca->{debit} = 0;
+    }
+
+    push @{ $form->{CA} }, $ca;
+
+  }
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+1;
+
diff --git a/sql-ledger/SL/CP.pm b/sql-ledger/SL/CP.pm
new file mode 100644 (file)
index 0000000..f84bd15
--- /dev/null
@@ -0,0 +1,308 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Check and receipt printing payment module backend routines
+# Number to text conversion routines are in
+# locale/{countrycode}/Num2text
+#
+#======================================================================
+
+package CP;
+
+
+sub new {
+  my ($type, $countrycode) = @_;
+
+  $self = {};
+
+  if ($countrycode) {
+    if (-f "locale/$countrycode/Num2text") {
+      require "locale/$countrycode/Num2text";
+    } else {
+      use SL::Num2text;
+    }
+  } else {
+    use SL::Num2text;
+  }
+
+  bless $self, $type;
+
+}
+
+
+sub paymentaccounts {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  
+  my $query = qq|SELECT accno, description
+                 FROM chart
+                WHERE link LIKE '%$form->{arap}_paid%'
+                ORDER BY accno|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{PR} }, $ref;
+  }
+  $sth->finish;
+  
+  # get currencies and closedto
+  $query = qq|SELECT curr, closedto
+              FROM defaults|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+  
+  ($form->{currencies}, $form->{closedto}) = $sth->fetchrow_array;
+  $sth->finish;
+
+  $dbh->disconnect;
+
+}
+
+
+sub get_openvc {
+  my ($self, $myconfig, $form) = @_;
+
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $arap = ($form->{vc} eq 'customer') ? 'ar' : 'ap';
+  
+  my $query = qq|SELECT count(*)
+                 FROM $form->{vc} ct, $arap a
+                WHERE a.$form->{vc}_id = ct.id
+                 AND a.amount != a.paid|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+  my ($count) = $sth->fetchrow_array;
+  $sth->finish;
+
+  # build selection list
+  if ($count < $myconfig->{vclimit}) {
+    $query = qq|SELECT DISTINCT ct.id, ct.name
+                FROM $form->{vc} ct, $arap a
+               WHERE a.$form->{vc}_id = ct.id
+               AND a.amount != a.paid
+               ORDER BY name|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+      push @{ $form->{"all_$form->{vc}"} }, $ref;
+    }
+
+    $sth->finish;
+
+  }
+
+  $dbh->disconnect;
+
+}
+
+
+sub get_openinvoices {
+  my ($self, $myconfig, $form) = @_;
+
+  return unless $form->{"$form->{vc}_id"};
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $where = qq|WHERE $form->{vc}_id = $form->{"$form->{vc}_id"}
+                 AND curr = '$form->{currency}'
+                AND NOT amount = paid|;
+  
+  if ($form->{transdatefrom}) {
+    $where .= " AND transdate >= '$form->{transdatefrom}'";
+  }
+  if ($form->{transdateto}) {
+    $where .= " AND transdate <= '$form->{transdateto}'";
+  }
+  
+  my ($arap, $buysell);
+  if ($form->{vc} eq 'customer') {
+    $arap = "ar";
+    $buysell = "buy";
+  } else {
+    $arap = "ap";
+    $buysell = "sell";
+  }
+  
+  my $query = qq|SELECT id, invnumber, transdate, amount, paid, curr
+                FROM $arap
+                $where
+                ORDER BY id|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+    # if this is a foreign currency transaction get exchangerate
+    $ref->{exchangerate} = $form->get_exchangerate($dbh, $ref->{curr}, $ref->{transdate}, $buysell) if ($form->{currency} ne $form->{defaultcurrency});
+    push @{ $form->{PR} }, $ref;
+  }
+  
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+
+
+sub process_payment {
+  my ($self, $myconfig, $form) = @_;
+    
+  # connect to database, turn AutoCommit off
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my ($paymentaccno) = split /--/, $form->{account};
+  
+  # if currency ne defaultcurrency update exchangerate
+  if ($form->{currency} ne $form->{defaultcurrency}) {
+    $form->{exchangerate} = $form->parse_amount($myconfig, $form->{exchangerate});
+
+    if ($form->{vc} eq 'customer') {
+      $form->update_exchangerate($dbh, $form->{currency}, $form->{datepaid}, $form->{exchangerate}, 0);
+    } else {
+      $form->update_exchangerate($dbh, $form->{currency}, $form->{datepaid}, 0, $form->{exchangerate});
+    }
+  } else {
+    $form->{exchangerate} = 1;
+  }
+
+  my $query = qq|SELECT fxgain_accno_id, fxloss_accno_id
+                 FROM defaults|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my ($fxgain_accno_id, $fxloss_accno_id) = $sth->fetchrow_array;
+  $sth->finish;
+
+  my ($ARAP, $arap, $buysell);
+  
+  if ($form->{vc} eq 'customer') {
+    $ARAP = "AR";
+    $arap = "ar";
+    $buysell = "buy";
+  } else {
+    $ARAP = "AP";
+    $arap = "ap";
+    $buysell = "sell";
+  }
+  
+  # go through line by line
+  for my $i (1 .. $form->{rowcount}) {
+
+    if ($form->{"paid_$i"}) {
+
+      $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"});
+      
+      # get exchangerate for original 
+      $query = qq|SELECT $buysell FROM exchangerate e, $arap a
+                 WHERE e.curr = '$form->{currency}'
+                 AND a.transdate = e.transdate
+                 AND a.id = $form->{"id_$i"}|;
+      $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+
+      my ($exchangerate) = $sth->fetchrow_array;
+      $sth->finish;
+
+      $exchangerate = 1 unless $exchangerate;
+
+      $query = qq|SELECT c.id FROM chart c, acc_trans a
+                  WHERE a.chart_id = c.id
+                 AND c.link = '$ARAP'
+                 AND a.trans_id = $form->{"id_$i"}|;
+      $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+
+      my ($id) = $sth->fetchrow_array;
+      $sth->finish;
+
+      my $amount = $form->round_amount($form->{"paid_$i"} * $exchangerate * -1, 2);
+      $ml = ($ARAP eq 'AR') ? -1 : 1;
+      # add AR/AP
+      $query = qq|INSERT INTO acc_trans (trans_id, chart_id, transdate, amount)
+                  VALUES ($form->{"id_$i"}, $id,
+                 '$form->{datepaid}', $amount * $ml)|;
+      $dbh->do($query) || $form->dberror($query);
+      
+      # add payment
+      $query = qq|INSERT INTO acc_trans (trans_id, chart_id, transdate, amount,
+                  source)
+                  VALUES ($form->{"id_$i"},
+                        (SELECT id FROM chart
+                         WHERE accno = '$paymentaccno'),
+                 '$form->{datepaid}', $form->{"paid_$i"} * $ml,
+                 '$form->{source}')|;
+      $dbh->do($query) || $form->dberror($query);
+
+      # add exchangerate difference if currency ne defaultcurrency
+      $amount = $form->round_amount($form->{"paid_$i"} * ($form->{exchangerate} - 1), 2);
+
+      if ($amount != 0) {
+        # exchangerate difference
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, transdate,
+                   amount, cleared, fx_transaction)
+                   VALUES ($form->{"id_$i"},
+                          (SELECT id FROM chart
+                           WHERE accno = '$paymentaccno'),
+                 '$form->{datepaid}', $amount * $ml, '0', '1')|;
+       $dbh->do($query) || $form->dberror($query);
+
+        # gain/loss
+        
+       $amount = $form->round_amount($form->{"paid_$i"} * ($exchangerate - $form->{exchangerate}) * $ml, 2);
+       if ($amount != 0) {
+         my $accno_id = ($amount > 0) ? $fxgain_accno_id : $fxloss_accno_id;
+         $query = qq|INSERT INTO acc_trans (trans_id, chart_id, transdate,
+                     amount, cleared, fx_transaction)
+                     VALUES ($form->{"id_$i"}, $accno_id,
+                     '$form->{datepaid}', $amount, '0', '1')|;
+         $dbh->do($query) || $form->dberror($query);
+       }
+      }
+
+      $form->{"paid_$i"} = $form->round_amount($form->{"paid_$i"} * $exchangerate, 2);
+
+      # update AR/AP transaction
+      $query = qq|UPDATE $arap set
+                 paid = paid + $form->{"paid_$i"},
+                 datepaid = '$form->{datepaid}'
+                 WHERE id = $form->{"id_$i"}|;
+      $dbh->do($query) || $form->dberror($query);
+    }
+  }
+  
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/CT.pm b/sql-ledger/SL/CT.pm
new file mode 100644 (file)
index 0000000..7c42cb8
--- /dev/null
@@ -0,0 +1,447 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# backend code for customers and vendors
+#
+# CHANGE LOG:
+#   DS. 2000-07-04  Created
+#
+#======================================================================
+
+package CT;
+
+
+sub get_tuple {
+  my ($self, $myconfig, $form) = @_;
+
+  my $dbh = $form->dbconnect($myconfig);
+  my $query = qq|SELECT *
+                 FROM $form->{db}
+                 WHERE id = $form->{id}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+  
+  my $ref = $sth->fetchrow_hashref(NAME_lc);
+  
+  map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+  $sth->finish;
+
+
+  # get ship to
+  $query = qq|SELECT *
+              FROM shipto
+             WHERE trans_id = $form->{id}|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  $ref = $sth->fetchrow_hashref(NAME_lc);
+
+  map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+  $sth->finish;
+
+
+  # get tax labels
+  $query = qq|SELECT accno, description
+              FROM chart, tax
+             WHERE link LIKE '%CT_tax%'
+             AND chart.id = tax.chart_id
+             ORDER BY accno|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+    $form->{taxaccounts} .= "$ref->{accno} ";
+    $form->{tax}{$ref->{accno}}{description} = $ref->{description};
+  }
+  $sth->finish;
+  chop $form->{taxaccounts};
+
+  # get taxes for customer/vendor
+  $query = qq|SELECT chart_id, accno
+              FROM $form->{db}tax, chart
+              WHERE chart_id = chart.id
+              AND $form->{db}_id = $form->{id}|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+    $form->{tax}{$ref->{accno}}{taxable} = 1;
+  }
+  $sth->finish;
+
+  
+  $dbh->disconnect;
+
+}
+
+
+sub taxaccounts {
+  my ($self, $myconfig, $form) = @_;
+
+  my $dbh = $form->dbconnect($myconfig);
+
+  # get tax labels
+  my $query = qq|SELECT accno, description
+                 FROM chart, tax
+                WHERE link LIKE '%CT_tax%'
+                AND chart.id = tax.chart_id
+                ORDER BY accno|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $taxref = $sth->fetchrow_hashref(NAME_lc)) {
+    $form->{taxaccounts} .= "$taxref->{accno} ";
+    $form->{tax}{$taxref->{accno}}{description} = $taxref->{description};
+  }
+  $sth->finish;
+  chop $form->{taxaccounts};
+
+  $dbh->disconnect;
+
+}
+
+
+sub delete_customer {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database, turn AutoCommit off
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my $query = qq|SELECT id FROM ar
+                 WHERE customer_id = $form->{id}
+                UNION
+                SELECT id FROM oe
+                WHERE customer_id = $form->{id}|;
+  my $sth = $dbh->prepare($query) || $form->dberror($query);
+  $sth->execute;
+
+  my ($rc) = $sth->fetchrow_array;
+  $sth->finish;
+
+  if ($rc) {
+    $dbh->disconnect;
+    $rc = -1;
+  } else {
+    
+    # delete customer
+    $query = qq|DELETE FROM customer
+                WHERE id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+
+    $query = qq|DELETE FROM shipto
+                WHERE trans_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+    
+    $query = qq|DELETE FROM customertax
+                WHERE customer_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+
+    # commit and redirect
+    $rc = $dbh->commit;
+    $dbh->disconnect;
+    
+  }
+
+  $rc;
+  
+}
+
+
+sub save_customer {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  # escape '
+  map { $form->{$_} =~ s/'/''/g } qw(customernumber name addr1 addr2 addr3 addr4 contact notes);
+
+  # assign value discount, terms, creditlimit
+  $form->{discount} /= 100;
+  $form->{terms} *= 1;
+  $form->{taxincluded} *= 1;
+  $form->{creditlimit} = $form->parse_amount($myconfig, $form->{creditlimit});
+  
+  my ($query, $sth);
+
+  if ($form->{id}) {
+    $query = qq|DELETE FROM customertax
+                WHERE customer_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+
+    $query = qq|DELETE FROM shipto
+                WHERE trans_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+  } else {
+    my $uid = time;
+    $uid .= $form->{login};
+
+    $query = qq|INSERT INTO customer (name)
+                VALUES ('$uid')|;
+    $dbh->do($query) || $form->dberror($query);
+    
+    $query = qq|SELECT id FROM customer
+                WHERE name = '$uid'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{id}) = $sth->fetchrow_array;
+    $sth->finish;
+
+  }
+               
+  $query = qq|UPDATE customer SET
+              customernumber = '$form->{customernumber}',
+             name = '$form->{name}',
+             addr1 = '$form->{addr1}',
+             addr2 = '$form->{addr2}',
+             addr3 = '$form->{addr3}',
+             addr4 = '$form->{addr4}',
+             contact = '$form->{contact}',
+             phone = '$form->{phone}',
+             fax = '$form->{fax}',
+             email = '$form->{email}',
+             cc = '$form->{cc}',
+             bcc = '$form->{bcc}',
+             notes = '$form->{notes}',
+             discount = $form->{discount},
+             creditlimit = $form->{creditlimit},
+             terms = $form->{terms},
+             taxincluded = '$form->{taxincluded}'
+             WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  # save taxes
+  foreach $item (split / /, $form->{taxaccounts}) {
+    if ($form->{"tax_$item"}) {
+      $query = qq|INSERT INTO customertax (customer_id, chart_id)
+                 VALUES ($form->{id}, (SELECT id
+                                       FROM chart
+                                       WHERE accno = '$item'))|;
+      $dbh->do($query) || $form->dberror($query);
+    }
+  }
+  
+  # add shipto
+  $form->add_shipto($dbh, $form->{id});
+
+  $dbh->disconnect;
+
+}
+
+
+sub save_vendor {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  # escape '
+  map { $form->{$_} =~ s/'/''/g } qw(vendornumber name addr1 addr2 addr3 addr4 contact notes);
+
+  $form->{terms} *= 1;
+  $form->{taxincluded} *= 1;
+  
+  my $query;
+  
+  if ($form->{id}) {
+    $query = qq|DELETE FROM vendortax
+                WHERE vendor_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+
+    $query = qq|DELETE FROM shipto
+                WHERE trans_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+  } else {
+    my $uid = time;
+    $uid .= $form->{login};
+    
+    $query = qq|INSERT INTO vendor (name)
+                VALUES ('$uid')|;
+    $dbh->do($query) || $form->dberror($query);
+   
+    $query = qq|SELECT id FROM vendor
+                WHERE name = '$uid'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{id}) = $sth->fetchrow_array;
+    $sth->finish;
+
+  }
+   
+
+  $query = qq|UPDATE vendor SET
+              vendornumber = '$form->{vendornumber}',
+             name = '$form->{name}',
+             addr1 = '$form->{addr1}',
+             addr2 = '$form->{addr2}',
+             addr3 = '$form->{addr3}',
+             addr4 = '$form->{addr4}',
+             contact = '$form->{contact}',
+             phone = '$form->{phone}',
+             fax = '$form->{fax}',
+             email = '$form->{email}',
+             cc = '$form->{cc}',
+             bcc = '$form->{bcc}',
+             notes = '$form->{notes}',
+             terms = $form->{terms},
+             taxincluded = '$form->{taxincluded}'
+             WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  # save taxes
+  foreach $item (split / /, $form->{taxaccounts}) {
+    if ($form->{"tax_$item"}) {
+      $query = qq|INSERT INTO vendortax (vendor_id, chart_id)
+                 VALUES ($form->{id}, (SELECT id
+                                       FROM chart
+                                       WHERE accno = '$item'))|;
+      $dbh->do($query) || $form->dberror($query);
+    }
+  }
+
+  # add shipto
+  $form->add_shipto($dbh, $form->{id});
+
+  $dbh->disconnect;
+
+}
+
+
+
+sub delete_vendor {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database, turn AutoCommit off
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  # check if there are any transactions on file
+  my $query = qq|SELECT id FROM ap
+                 WHERE vendor_id = $form->{id}
+                UNION
+                SELECT id FROM oe
+                WHERE vendor_id = $form->{id}|;
+  my $sth = $dbh->prepare($query) || $form->dberror($query);
+  $sth->execute;
+  
+  my ($rc) = $sth->fetchrow_array;
+  $sth->finish;
+  
+  if ($rc) {
+    $dbh->disconnect;
+    $rc = -1;
+  } else {
+    
+    # delete vendor
+    $query = qq|DELETE FROM vendor
+                WHERE id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+
+    $query = qq|DELETE FROM shipto
+                WHERE trans_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+
+    $query = qq|DELETE FROM vendortax
+                WHERE vendor_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+
+    # commit and redirect
+    $rc = $dbh->commit;
+    $dbh->disconnect;
+
+  }
+
+  $rc;
+
+}
+
+
+sub search {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $where = "1 = 1";
+  $form->{sort} = "name" unless ($form->{sort});
+  
+  if ($form->{"$form->{db}number"}) {
+    my $companynumber = $form->like(lc $form->{"$form->{db}number"});
+    $where .= " AND lower($form->{db}number) LIKE '$companynumber'";
+  }
+  if ($form->{name}) {
+    my $name = $form->like(lc $form->{name});
+    $where .= " AND lower(name) LIKE '$name'";
+  }
+  if ($form->{contact}) {
+    my $contact = $form->like(lc $form->{contact});
+    $where .= " AND lower(contact) LIKE '$contact'";
+  }
+  if ($form->{email}) {
+    my $email = $form->like(lc $form->{email});
+    $where .= " AND lower(email) LIKE '$email'";
+  }
+
+  if ($form->{status} eq 'orphaned') {
+    $where .= qq| AND id NOT IN (SELECT o.$form->{db}_id
+                                 FROM oe o, $form->{db} ct
+                                WHERE ct.id = o.$form->{db}_id)|;
+    if ($form->{db} eq 'customer') {
+      $where .= qq| AND id NOT IN (SELECT a.customer_id
+                                   FROM ar a, customer ct
+                                  WHERE ct.id = a.customer_id)|;
+    }
+    if ($form->{db} eq 'vendor') {
+      $where .= qq| AND id NOT IN (SELECT a.vendor_id
+                                   FROM ap a, vendor ct
+                                  WHERE ct.id = a.vendor_id)|;
+    }
+  }
+  
+  my $query = qq~SELECT id, name, $form->{db}number, 
+                 addr1 || ' ' || addr2 || ' ' || addr3 || ' ' || addr4 AS address,
+                 contact, phone, fax, email, cc, terms
+                 FROM $form->{db}
+                 WHERE $where
+                ORDER BY $form->{sort}~;
+
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{CT} }, $ref;
+  }
+
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/Form.pm b/sql-ledger/SL/Form.pm
new file mode 100644 (file)
index 0000000..ef5f2ca
--- /dev/null
@@ -0,0 +1,1397 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 1998-2003
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+# Contributors: Thomas Bayen <bayen@gmx.de>
+#               Antti Kaihola <akaihola@siba.fi>
+#               Moritz Bunkus (tex code)
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+# Utilities for parsing forms
+# and supporting routines for linking account numbers
+# used in AR, AP and IS, IR modules
+#
+#======================================================================
+
+package Form;
+
+
+sub new {
+  my $type = shift;
+  
+  my $self = {};
+
+  read(STDIN, $_, $ENV{CONTENT_LENGTH});
+  
+  if ($ENV{QUERY_STRING}) {
+    $_ = $ENV{QUERY_STRING};
+  }
+
+  if ($ARGV[0]) {
+    $_ = $ARGV[0];
+  }
+
+  foreach $item (split(/&/)) {
+    ($key, $value) = split(/=/, $item);
+    $self->{$key} = &unescape("",$value);
+  }
+
+  $self->{action} = lc $self->{action};
+  $self->{action} =~ s/( |-|,)/_/g;
+
+  $self->{version} = "2.0.8";
+  $self->{dbversion} = "2.0.8";
+
+  bless $self, $type;
+  
+}
+
+
+sub debug {
+  my ($self) = @_;
+  
+  print "\n";
+  
+  map { print "$_ = $self->{$_}\n" } (sort keys %{$self});
+  
+} 
+
+  
+sub escape {
+  my ($self, $str, $beenthere) = @_;
+
+  # for Apache 2 we escape strings twice
+  if (($ENV{SERVER_SOFTWARE} =~ /Apache\/2/) && !$beenthere) {
+    $str = $self->escape($str, 1);
+  }
+           
+  $str =~ s/([^a-zA-Z0-9_.-])/sprintf("%%%02x", ord($1))/ge;
+  $str;
+
+}
+
+
+sub unescape {
+  my ($self, $str) = @_;
+  
+  $str =~ tr/+/ /;
+  $str =~ s/\\$//;
+
+  $str =~ s/%([0-9a-fA-Z]{2})/pack("c",hex($1))/eg;
+
+  $str;
+
+}
+
+
+sub error {
+  my ($self, $msg) = @_;
+
+  if ($ENV{HTTP_USER_AGENT}) {
+    $msg =~ s/\n/<br>/g;
+
+    print qq|Content-Type: text/html
+
+    <body bgcolor=ffffff>
+
+    <h2><font color=red>Error!</font></h2>
+
+    <p><b>$msg</b>
+    
+    </body>
+    </html>
+    |;
+
+    die "Error: $msg\n";
+
+  } else {
+  
+    if ($self->{error_function}) {
+      &{ $self->{error_function} }($msg);
+    } else {
+      die "Error: $msg\n";
+    }
+  }
+  
+}
+
+
+
+sub info {
+  my ($self, $msg) = @_;
+
+  if ($ENV{HTTP_USER_AGENT}) {
+    $msg =~ s/\n/<br>/g;
+
+    if (!$self->{header}) {
+      $self->header;
+      print qq|
+      <body>|;
+    }
+
+    print qq|
+
+    <p><b>$msg</b>
+    |;
+    
+  } else {
+  
+    if ($self->{info_function}) {
+      &{ $self->{info_function} }($msg);
+    } else {
+      print "$msg\n";
+    }
+  }
+  
+}
+
+
+sub numtextrows {
+  my ($self, $str, $cols, $maxrows) = @_;
+
+  my $rows;
+
+  map { $rows += int ((length $_)/$cols) + 1 } (split /\r/, $str);
+
+  $rows = $maxrows if (defined $maxrows && ($rows > $maxrows));
+  
+  $rows;
+
+}
+
+
+sub dberror {
+  my ($self, $msg) = @_;
+
+  $self->error("$msg\n".$DBI::errstr);
+  
+}
+
+
+sub isblank {
+  my ($self, $name, $msg) = @_;
+
+  if ($self->{$name} =~ /^\s*$/) {
+    $self->error($msg);
+  }
+}
+  
+
+sub header {
+  my ($self) = @_;
+
+  my ($nocache, $stylesheet, $charset);
+  
+  # use expire tag to prevent caching
+#  $nocache = qq|<META HTTP-EQUIV="Expires" CONTENT="Tue, 01 Jan 1980 1:00:00 GMT">
+#  <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
+#|;
+
+  if ($self->{stylesheet} && (-f "css/$self->{stylesheet}")) {
+    $stylesheet = qq|<LINK REL="stylesheet" HREF="css/$self->{stylesheet}" TYPE="text/css" TITLE="SQL-Ledger style sheet">
+|;
+  }
+
+  if ($self->{charset}) {
+    $charset = qq|<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=$self->{charset}">
+|;
+  }
+
+  $self->{titlebar} = ($self->{title}) ? "$self->{title} - $self->{titlebar}" : $self->{titlebar};
+  
+  print qq|Content-Type: text/html
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<head>
+  <title>$self->{titlebar}</title>
+  $nocache
+  $stylesheet
+  $charset
+</head>
+
+|;
+
+}
+
+
+sub redirect {
+  my ($self, $msg) = @_;
+
+  if ($self->{callback}) {
+
+    ($script, $argv) = split(/\?/, $self->{callback});
+
+    exec ("perl", "$script", $argv);
+   
+  } else {
+    
+    if ($ENV{HTTP_USER_AGENT}) {
+      $msg =~ s/\n/<br>/g;
+
+      print qq|Content-Type: text/html
+
+<body bgcolor=ffffff>
+
+<h2>$msg</h2>
+
+</body>
+</html>
+|;
+
+    } else {
+      print "$msg\n";
+    }
+
+    exit;
+    
+  }
+
+}
+
+
+sub sort_columns {
+  my ($self, @columns) = @_;
+
+  @columns = grep !/^$self->{sort}$/, @columns;
+  splice @columns, 0, 0, $self->{sort};
+
+  @columns;
+  
+}
+
+
+sub format_amount {
+  my ($self, $myconfig, $amount, $places, $dash) = @_;
+
+  if ($places =~ /\d/) {
+    $amount = $self->round_amount($amount, $places);
+  }
+
+  # is the amount negative
+  my $negative = ($amount < 0);
+  
+  if ($amount != 0) {
+    if ($myconfig->{numberformat} && ($myconfig->{numberformat} ne '1000.00')) {
+      my ($whole, $dec) = split /\./, "$amount";
+      $whole =~ s/-//;
+      $amount = join '', reverse split //, $whole;
+      
+      if ($myconfig->{numberformat} eq '1,000.00') {
+       $amount =~ s/\d{3,}?/$&,/g;
+       $amount =~ s/,$//;
+       $amount = join '', reverse split //, $amount;
+       $amount .= "\.$dec" if ($dec ne "");
+      }
+      
+      if ($myconfig->{numberformat} eq '1.000,00') {
+       $amount =~ s/\d{3,}?/$&./g;
+       $amount =~ s/\.$//;
+       $amount = join '', reverse split //, $amount;
+       $amount .= ",$dec" if ($dec ne "");
+      }
+      
+      if ($myconfig->{numberformat} eq '1000,00') {
+       $amount = "$whole";
+       $amount .= ",$dec" if ($dec ne "");
+      }
+
+      if ($dash =~ /-/) {
+       $amount = ($negative) ? "($amount)" : "$amount";
+      } elsif ($dash =~ /DRCR/) {
+       $amount = ($negative) ? "$amount DR" : "$amount CR";
+      } else {
+       $amount = ($negative) ? "-$amount" : "$amount";
+      }
+    }
+  } else {
+    if ($dash eq "0" && $places) {
+      if ($myconfig->{numberformat} eq '1.000,00') {
+       $amount = "0".","."0" x $places;
+      } else {
+       $amount = "0"."."."0" x $places;
+      }
+    } else {
+      $amount = ($dash ne "") ? "$dash" : "";
+    }
+  }
+
+  $amount;
+
+}
+
+
+sub parse_amount {
+  my ($self, $myconfig, $amount) = @_;
+
+  if (($myconfig->{numberformat} eq '1.000,00') ||
+      ($myconfig->{numberformat} eq '1000,00')) {
+    $amount =~ s/\.//g;
+    $amount =~ s/,/\./;
+  }
+
+  $amount =~ s/,//g;
+  
+  return ($amount * 1);
+
+}
+
+
+sub round_amount {
+  my ($self, $amount, $places) = @_;
+
+#  $places = 3 if $places == 2;
+  
+  if (($places * 1) >= 0) {
+    # compensate for perl behaviour, add 1/10^$places+3
+    sprintf("%.${places}f", $amount + (1 / (10 ** ($places + 3))) * (($amount > 0) ? 1 : -1));
+  } else {
+    $places *= -1;
+    sprintf("%.f", $amount / (10 ** $places) + (($amount > 0) ? 0.1 : -0.1)) * (10 ** $places);
+  }
+
+}
+
+
+sub parse_template {
+  my ($self, $myconfig, $userspath) = @_;
+
+  # { Moritz Bunkus
+  # Some variables used for page breaks
+  my ($chars_per_line, $lines_on_first_page, $lines_on_second_page) = (0, 0, 0);
+  my ($current_page, $current_line) = (1, 1);
+  my $pagebreak = "";
+  my $sum = 0;
+  # } Moritz Bunkus
+
+  open(IN, "$self->{templates}/$self->{IN}") or $self->error("$self->{IN} : $!");
+
+  @_ = <IN>;
+  close(IN);
+  
+  $self->{copies} = 1 if (($self->{copies} *= 1) <= 0);
+  
+  # OUT is used for the media, screen, printer, email
+  # for postscript we store a copy in a temporary file
+  my $fileid = time;
+  $self->{tmpfile} = "$userspath/${fileid}.$self->{IN}";
+  if ($self->{format} =~ /(postscript|pdf)/ || $self->{media} eq 'email') {
+    $out = $self->{OUT};
+    $self->{OUT} = ">$self->{tmpfile}";
+  }
+  
+  
+  if ($self->{OUT}) {
+    open(OUT, "$self->{OUT}") or $self->error("$self->{OUT} : $!");
+  } else {
+    open(OUT, ">-") or $self->error("STDOUT : $!");
+    $self->header;
+  }
+
+
+  # first we generate a tmpfile
+  # read file and replace <%variable%>
+  while ($_ = shift) {
+      
+    $par = "";
+    $var = $_;
+
+
+    # { Moritz Bunkus
+    # detect pagebreak block and its parameters
+    if (/<%pagebreak ([0-9]+) ([0-9]+) ([0-9]+)%>/) {
+      $chars_per_line = $1;
+      $lines_on_first_page = $2;
+      $lines_on_second_page = $3;
+      
+      while ($_ = shift) {
+        last if (/<\%end pagebreak%>/);
+        $pagebreak .= $_;
+      }
+    }
+    # } Moritz Bunkus
+
+    
+    if (/<%foreach /) {
+      
+      # this one we need for the count
+      chomp $var;
+      $var =~ s/<%foreach (.+?)%>/$1/;
+      while ($_ = shift) {
+       last if (/<%end /);
+
+       # store line in $par
+       $par .= $_;
+      }
+      
+      # display contents of $self->{number}[] array
+      for $i (0 .. $#{ $self->{$var} }) {
+
+        # { Moritz Bunkus
+        # Try to detect whether a manual page break is necessary
+        # but only if there was a <%pagebreak ...%> block before
+       
+        if ($chars_per_line) {
+          my $lines = int(length($self->{"description"}[$i]) / $chars_per_line + 0.95);
+          my $lpp;
+         
+          if ($current_page == 1) {
+            $lpp = $lines_on_first_page;
+          } else {
+            $lpp = $lines_on_second_page;
+          }
+
+          # Yes we need a manual page break
+          if (($current_line + $lines) > $lpp) {
+            my $pb = $pagebreak;
+           
+            # replace the special variables <%sumcarriedforward%>
+            # and <%lastpage%>
+           
+            my $psum = $self->format_amount($myconfig, $sum, 2);
+            $pb =~ s/<%sumcarriedforward%>/$psum/g;
+            $pb =~ s/<%lastpage%>/$current_page/g;
+            
+           # only "normal" variables are supported here
+            # (no <%if, no <%foreach, no <%include)
+            
+           $pb =~ s/<%(.+?)%>/$self->{$1}/g;
+            
+           # page break block is ready to rock
+            print(OUT $pb);
+            $current_page++;
+            $current_line = 1;
+          }
+          $current_line += $lines;
+        }
+        $sum += $self->parse_amount($myconfig, $self->{"linetotal"}[$i]);
+        # } Moritz Bunkus
+
+
+       # don't parse par, we need it for each line
+       $_ = $par;
+       s/<%(.+?)%>/$self->{$1}[$i]/mg;
+       print OUT;
+      }
+      next;
+    }
+
+    # if not comes before if!
+    if (/<%if not /) {
+      # check if it is not set and display
+      chop;
+      s/<%if not (.+?)%>/$1/;
+
+      unless ($self->{$_}) {
+       while ($_ = shift) {
+         last if (/<%end /);
+
+         # store line in $par
+         $par .= $_;
+       }
+       
+       $_ = $par;
+       
+      } else {
+       while ($_ = shift) {
+         last if (/<%end /);
+       }
+       next;
+      }
+    }
+    if (/<%if /) {
+      # check if it is set and display
+      chop;
+      s/<%if (.+?)%>/$1/;
+
+      if ($self->{$_}) {
+       while ($_ = shift) {
+         last if (/<%end /);
+
+         # store line in $par
+         $par .= $_;
+       }
+       
+       $_ = $par;
+       
+      } else {
+       while ($_ = shift) {
+         last if (/<%end /);
+       }
+       next;
+      }
+    }
+   
+    # check for <%include filename%>
+    if (/<%include /) {
+      
+      # get the filename
+      chomp $var;
+      $var =~ s/<%include (.+?)%>/$1/;
+
+      # mangle filename if someone tries to be cute
+      $var =~ s/\///g;
+
+      # prevent the infinite loop!
+      next if ($self->{"$var"});
+
+      open(INC, "$self->{templates}/$var") or $self->error($self->cleanup."$self->{templates}/$var : $!");
+      unshift(@_, <INC>);
+      close(INC);
+
+      $self->{"$var"} = 1;
+
+      next;
+    }
+    
+    s/<%(.+?)%>/$self->{$1}/g;
+    print OUT;
+  }
+
+  close(OUT);
+
+
+  # { Moritz Bunkus
+  # Convert the tex file to postscript
+  if ($self->{format} =~ /(postscript|pdf)/) {
+
+    use Cwd;
+    $self->{cwd} = cwd();
+    chdir("$userspath") or $self->error($self->cleanup."chdir : $!");
+
+    $self->{tmpfile} =~ s/$userspath\///g;
+
+    # DS. added screen and email option in addition to printer
+    # screen
+    if ($self->{format} eq 'postscript') {
+      system("latex --interaction=nonstopmode $self->{tmpfile} > $self->{tmpfile}.err");
+      $self->error($self->cleanup) if ($?);
+      
+      $self->{tmpfile} =~ s/tex$/dvi/;
+
+      system("dvips $self->{tmpfile} -o -q > /dev/null");
+      $self->error($self->cleanup."dvips : $!") if ($?);
+      $self->{tmpfile} =~ s/dvi$/ps/;
+    }
+    if ($self->{format} eq 'pdf') {
+      system("pdflatex --interaction=nonstopmode $self->{tmpfile} > $self->{tmpfile}.err");
+      $self->error($self->cleanup) if ($?);
+      $self->{tmpfile} =~ s/tex$/pdf/;
+    }
+
+  }
+
+  if ($self->{format} =~ /(postscript|pdf)/ || $self->{media} eq 'email') {
+
+    if ($self->{media} eq 'email') {
+      
+      use SL::Mailer;
+
+      my $mail = new Mailer;
+      
+      $self->{email} =~ s/,/>,</g;
+      
+      map { $mail->{$_} = $self->{$_} } qw(cc bcc subject message version format charset);
+      $mail->{to} = qq|"$self->{name}" <$self->{email}>|;
+      $mail->{from} = qq|"$myconfig->{name}" <$myconfig->{email}>|;
+      $mail->{fileid} = "$fileid.";
+
+      # if we send html or plain text inline
+      if (($self->{format} eq 'html') && ($self->{sendmode} eq 'inline')) {
+       $mail->{contenttype} = "text/html";
+
+        $mail->{message} =~ s/\r\n/<br>\n/g;
+       $myconfig->{signature} =~ s/\\n/<br>\n/g;
+       $mail->{message} .= "<br>\n--<br>\n$myconfig->{signature}\n<br>";
+       
+       open(IN, $self->{tmpfile}) or $self->error($self->cleanup."$self->{tmpfile} : $!");
+       while (<IN>) {
+         $mail->{message} .= $_;
+       }
+
+       close(IN);
+
+      } else {
+       
+       @{ $mail->{attachments} } = ($self->{tmpfile});
+
+       $myconfig->{signature} =~ s/\\n/\r\n/g;
+       $mail->{message} .= "\r\n--\r\n$myconfig->{signature}";
+
+      }
+      my $err = $mail->send($out);
+      $self->error($self->cleanup."$err") if ($err);
+      
+    } else {
+      
+      $self->{OUT} = $out;
+      open(IN, $self->{tmpfile}) or $self->error($self->cleanup."$self->{tmpfile} : $!");
+
+      $self->{copies} = 1 unless $self->{media} eq 'printer';
+      
+      for my $i (1 .. $self->{copies}) {
+         
+       if ($self->{OUT}) {
+         open(OUT, $self->{OUT}) or $self->error($self->cleanup."$self->{OUT} : $!");
+       } else {
+         open(OUT, ">-") or $self->error($self->cleanup."$!: STDOUT");
+         
+         # launch application
+         print qq|Content-Type: application/$self->{format}; name="$self->{tmpfile}"
+  Content-Disposition: filename="$self->{tmpfile}"
+
+  |;
+       }
+       
+       while (<IN>) {
+         print OUT $_;
+       }
+       close(OUT);
+       seek IN, 0, 0;
+      }
+
+      close(IN);
+    }
+
+    $self->cleanup;
+
+  }
+  # } Moritz Bunkus
+
+}
+
+
+sub cleanup {
+  my $self = shift;
+
+  my @err = ();
+  if (-f "$self->{tmpfile}.err") {
+    open(FH, "$self->{tmpfile}.err");
+    @err = <FH>;
+    close(FH);
+  }
+  
+  if ($self->{tmpfile}) {
+    # strip extension
+    $self->{tmpfile} =~ s/\.\w+$//g;
+    my $tmpfile = $self->{tmpfile};
+    unlink(<$tmpfile.*>);
+  }
+
+
+  chdir("$self->{cwd}");
+  
+  "@err";
+  
+}
+
+
+sub format_string {
+  my ($self, @fields) = @_;
+
+  my $format = $self->{format};
+  if ($self->{format} =~ /(postscript|pdf)/) {
+    $format = 'tex';
+  }
+
+  my %replace = ( 'order' => { 'html' => [ quotemeta('\n'), '\r' ],
+                               'tex'  => [ '&', quotemeta('\n'), '\r',
+                                          '\$', '%', '_', '#', quotemeta('^'),
+                                          '{', '}', '<', '>', '£' ] },
+                  'html' => {
+                quotemeta('\n') => '<br>', '\r' => '<br>'
+                           },
+                  'tex' => {
+               '&' => '\&', '\$' => '\$', '%' => '\%', '_' => '\_',
+               '#' => '\#', quotemeta('^') => '\^\\', '{' => '\{', '}' => '\}',
+               '<' => '$<$', '>' => '$>$',
+               quotemeta('\n') => '\newline ', '\r' => '\newline ',
+               '£' => '\pounds ',
+                            }
+               );
+
+  foreach my $key (@{ $replace{order}{$format} }) {
+    map { $self->{$_} =~ s/$key/$replace{$format}{$key}/g; } @fields;
+  }
+
+}
+
+
+sub datetonum {
+  my ($self, $date, $myconfig) = @_;
+
+  if ($date) {
+    # get separator
+    my $spc = $myconfig->{dateformat};
+    $spc =~ s/\w//g;
+    $spc = substr($spc, 1, 1);
+
+    if ($spc eq '.') {
+      $spc = '\.';
+    }
+    if ($spc eq '/') {
+      $spc = '\/';
+    }
+
+    if ($myconfig->{dateformat} =~ /^yy/) {
+      ($yy, $mm, $dd) = split /$spc/, $date;
+    }
+    if ($myconfig->{dateformat} =~ /^mm/) {
+      ($mm, $dd, $yy) = split /$spc/, $date;
+    }
+    if ($myconfig->{dateformat} =~ /^dd/) {
+      ($dd, $mm, $yy) = split /$spc/, $date;
+    }
+    
+    $dd *= 1;
+    $mm *= 1;
+    $yy = ($yy < 70) ? $yy + 2000 : $yy;
+    $yy = ($yy >= 70 && $yy <= 99) ? $yy + 1900 : $yy;
+
+    $dd = "0$dd" if ($dd < 10);
+    $mm = "0$mm" if ($mm < 10);
+    
+    $date = "$yy$mm$dd";
+  }
+
+  $date;
+  
+}
+
+
+
+# Database routines used throughout
+
+sub dbconnect {
+  my ($self, $myconfig) = @_;
+
+  # connect to database
+  my $dbh = DBI->connect($myconfig->{dbconnect}, $myconfig->{dbuser}, $myconfig->{dbpasswd}) or $self->dberror;
+
+  # set db options
+  if ($myconfig->{dboptions}) {
+    $dbh->do($myconfig->{dboptions}) || $self->dberror($myconfig->{dboptions});
+  }
+
+  $dbh;
+
+}
+
+
+sub dbconnect_noauto {
+  my ($self, $myconfig) = @_;
+
+  # connect to database
+  $dbh = DBI->connect($myconfig->{dbconnect}, $myconfig->{dbuser}, $myconfig->{dbpasswd}, {AutoCommit => 0}) or $self->dberror;
+
+  # set db options
+  if ($myconfig->{dboptions}) {
+    $dbh->do($myconfig->{dboptions}) || $self->dberror($myconfig->{dboptions});
+  }
+
+  $dbh;
+
+}
+
+
+sub update_balance {
+  my ($self, $dbh, $table, $field, $where, $value) = @_;
+
+  # if we have a value, go do it
+  if ($value != 0) {
+    # retrieve balance from table
+    my $query = "SELECT $field FROM $table WHERE $where";
+    my $sth = $dbh->prepare($query);
+
+    $sth->execute || $self->dberror($query);
+    my ($balance) = $sth->fetchrow_array;
+    $sth->finish;
+
+    $balance += $value;
+    # update balance
+    $query = "UPDATE $table SET $field = $balance WHERE $where";
+    $dbh->do($query) || $self->dberror($query);
+  }
+}
+
+
+
+sub update_exchangerate {
+  my ($self, $dbh, $curr, $transdate, $buy, $sell) = @_;
+
+  # some sanity check for currency
+  return if ($curr eq '');
+
+  my $query = qq|SELECT curr FROM exchangerate
+                 WHERE curr = '$curr'
+                AND transdate = '$transdate'|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+  
+  my $set;
+  if ($buy != 0 && $sell != 0) {
+    $set = "buy = $buy, sell = $sell";
+  } elsif ($buy != 0) {
+    $set = "buy = $buy";
+  } elsif ($sell != 0) {
+    $set = "sell = $sell";
+  }
+  
+  if ($sth->fetchrow_array) {
+    $query = qq|UPDATE exchangerate
+                SET $set
+               WHERE curr = '$curr'
+               AND transdate = '$transdate'|;
+  } else {
+    $query = qq|INSERT INTO exchangerate (curr, buy, sell, transdate)
+                VALUES ('$curr', $buy, $sell, '$transdate')|;
+  }
+  $sth->finish;
+  $dbh->do($query) || $self->dberror($query);
+  
+}
+
+
+sub get_exchangerate {
+  my ($self, $dbh, $curr, $transdate, $fld) = @_;
+  
+  my $query = qq|SELECT $fld FROM exchangerate
+                 WHERE curr = '$curr'
+                AND transdate = '$transdate'|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+
+  my ($exchangerate) = $sth->fetchrow_array;
+  $sth->finish;
+
+  $exchangerate;
+
+}
+
+
+sub delete_exchangerate {
+  my ($self, $dbh) = @_;
+
+  my @transdate = ();
+  my $transdate;
+
+  my $query = qq|SELECT DISTINCT transdate
+                 FROM acc_trans
+                WHERE trans_id = $self->{id}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+
+  while ($transdate = $sth->fetchrow_array) {
+    push @transdate, $transdate;
+  }
+  $sth->finish;
+
+  $query = qq|SELECT transdate FROM acc_trans
+              WHERE ar.id = trans_id
+             AND ar.curr = '$self->{currency}'
+             AND transdate IN
+                 (SELECT transdate FROM acc_trans
+                 WHERE trans_id = $self->{id})
+              AND trans_id != $self->{id}
+        UNION SELECT transdate FROM acc_trans
+             WHERE ap.id = trans_id
+             AND ap.curr = '$self->{currency}'
+             AND transdate IN
+                 (SELECT transdate FROM acc_trans
+                 WHERE trans_id = $self->{id})
+              AND trans_id != $self->{id}
+        UNION SELECT transdate FROM oe
+               WHERE oe.curr = '$self->{currency}'
+               AND transdate IN
+                   (SELECT transdate FROM acc_trans
+                   WHERE trans_id = $self->{id})|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+
+  while ($transdate = $sth->fetchrow_array) {
+    @transdate = grep !/^$transdate$/, @transdate;
+  }
+  $sth->finish;
+
+  foreach $transdate (@transdate) {
+    $query = qq|DELETE FROM exchangerate
+                WHERE curr = '$self->{currency}'
+               AND transdate = '$transdate'|;
+    $dbh->do($query) || $self->dberror($query);
+  }
+  
+}
+
+
+sub check_exchangerate {
+  my ($self, $myconfig, $currency, $transdate, $fld) = @_;
+
+  return "" unless $transdate;
+  
+  my $dbh = $self->dbconnect($myconfig);
+
+  my $query = qq|SELECT $fld FROM exchangerate
+                 WHERE curr = '$currency'
+                AND transdate = '$transdate'|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+
+  my ($exchangerate) = $sth->fetchrow_array;
+  $sth->finish;
+  $dbh->disconnect;
+  
+  $exchangerate;
+  
+}
+
+
+sub add_shipto {
+  my ($self, $dbh, $id) = @_;
+
+  my $shipto;
+  foreach my $item (qw(name addr1 addr2 addr3 addr4 contact phone fax email)) {
+    if ($self->{"shipto$item"}) {
+      $shipto = 1 if ($self->{$item} ne $self->{"shipto$item"});
+    }
+    $self->{"shipto$item"} =~ s/'/''/g;
+  }
+
+  if ($shipto) {
+    my $query = qq|INSERT INTO shipto (trans_id, shiptoname, shiptoaddr1,
+                   shiptoaddr2, shiptoaddr3, shiptoaddr4, shiptocontact,
+                  shiptophone, shiptofax, shiptoemail) VALUES ($id,
+                  '$self->{shiptoname}', '$self->{shiptoaddr1}',
+                  '$self->{shiptoaddr2}', '$self->{shiptoaddr3}',
+                  '$self->{shiptoaddr4}', '$self->{shiptocontact}',
+                  '$self->{shiptophone}', '$self->{shiptofax}',
+                  '$self->{shiptoemail}')|;
+    $dbh->do($query) || $self->dberror($query);
+  }
+
+}
+
+
+sub get_employee {
+  my ($self, $dbh) = @_;
+
+  my $query = qq|SELECT name FROM employee 
+                 WHERE login = '$self->{login}'|; 
+  my $sth = $dbh->prepare($query); 
+  $sth->execute || $self->dberror($query); 
+
+  ($self->{employee}) = $sth->fetchrow_array;
+  $sth->finish; 
+
+}
+
+
+# this sub gets the id and name from $table
+sub get_name {
+  my ($self, $myconfig, $table) = @_;
+
+  # connect to database
+  my $dbh = $self->dbconnect($myconfig);
+  
+  my $name = $self->like(lc $self->{$table});
+  my $query = qq~SELECT id, name,
+                 addr1 || ' ' || addr2 || ' ' || addr3 || ' ' || addr4 AS address
+                 FROM $table
+                WHERE lower(name) LIKE '$name'
+                ORDER BY name~;
+  my $sth = $dbh->prepare($query);
+
+  $sth->execute || $self->dberror($query);
+
+  my $i = 0;
+  while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push(@{ $self->{name_list} }, $ref);
+    $i++;
+  }
+  $sth->finish;
+  $dbh->disconnect;
+
+  $i;
+  
+}
+
+
+# the selection sub is used in the AR, AP, IS, IR and OE module
+#
+sub all_vc {
+  my ($self, $myconfig, $table) = @_;
+  
+  my $dbh = $self->dbconnect($myconfig);
+  
+  my $query = qq|SELECT count(*) FROM $table|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+  my ($count) = $sth->fetchrow_array;
+  $sth->finish;
+  
+  # build selection list
+  if ($count < $myconfig->{vclimit}) {
+    $query = qq|SELECT id, name
+               FROM $table
+               ORDER BY name|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $self->dberror($query);
+
+    while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+      push @{ $self->{"all_$table"} }, $ref;
+    }
+    
+    $sth->finish;
+    
+  }
+
+  $dbh->disconnect;
+
+}
+
+
+sub create_links {
+  my ($self, $module, $myconfig, $table) = @_;
+
+  $self->all_vc($myconfig, $table);
+  
+  # get last customers or vendors
+  my ($query, $sth);
+  
+  my $dbh = $self->dbconnect($myconfig);
+  
+  my %xkeyref = ();
+
+
+  # now get the account numbers
+  $query = qq|SELECT accno, description, link
+              FROM chart
+             WHERE link LIKE '%$module%'
+             ORDER BY accno|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+
+  $self->{accounts} = "";
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    
+    foreach my $key (split(/:/, $ref->{link})) {
+      if ($key =~ /$module/) {
+       # cross reference for keys
+       $xkeyref{$ref->{accno}} = $key;
+       
+       push @{ $self->{"${module}_links"}{$key} }, { accno => $ref->{accno},
+                                       description => $ref->{description} };
+
+        $self->{accounts} .= "$ref->{accno} " unless $key =~ /tax/;
+      }
+    }
+  }
+  $sth->finish;
+  
+  if ($self->{id}) {
+    my $arap = ($table eq 'customer') ? 'ar' : 'ap';
+    
+    $query = qq|SELECT a.invnumber, a.transdate,
+                a.${table}_id, a.datepaid, a.duedate, a.ordnumber,
+               a.taxincluded, a.curr AS currency, a.notes, c.name AS $table,
+               a.amount AS oldinvtotal, a.paid AS oldtotalpaid
+               FROM $arap a, $table c
+               WHERE a.${table}_id = c.id
+               AND a.id = $self->{id}|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $self->dberror($query);
+    
+    $ref = $sth->fetchrow_hashref(NAME_lc);
+    foreach $key (keys %$ref) {
+      $self->{$key} = $ref->{$key};
+    }
+    $sth->finish;
+
+    # get amounts from individual entries
+    $query = qq|SELECT c.accno, c.description, a.source, a.amount,
+                a.transdate, a.cleared, a.project_id, p.projectnumber
+               FROM acc_trans a
+               JOIN chart c ON (c.id = a.chart_id)
+               LEFT JOIN project p ON (a.project_id = p.id)
+               WHERE a.trans_id = $self->{id}
+               AND a.fx_transaction = '0'
+               ORDER BY transdate|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $self->dberror($query);
+
+    my $fld = ($table eq 'customer') ? 'buy' : 'sell';
+    # get exchangerate for currency
+    $self->{exchangerate} = $self->get_exchangerate($dbh, $self->{currency}, $self->{transdate}, $fld);
+    
+    # store amounts in {acc_trans}{$key} for multiple accounts
+    while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+      $ref->{exchangerate} = $self->get_exchangerate($dbh, $self->{currency}, $ref->{transdate}, $fld);
+
+      push @{ $self->{acc_trans}{$xkeyref{$ref->{accno}}} }, $ref;
+    }
+
+    $sth->finish;
+
+    $query = qq|SELECT d.curr AS currencies, d.closedto, d.revtrans,
+                  (SELECT c.accno FROM chart c
+                  WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
+                  (SELECT c.accno FROM chart c
+                  WHERE d.fxloss_accno_id = c.id) AS fxloss_accno
+               FROM defaults d|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $self->dberror($query);
+
+    $ref = $sth->fetchrow_hashref(NAME_lc);
+    map { $self->{$_} = $ref->{$_} } keys %$ref;
+    $sth->finish;
+
+  } else {
+   
+    # get date
+    $query = qq|SELECT current_date AS transdate,
+                d.curr AS currencies, d.closedto, d.revtrans,
+                  (SELECT c.accno FROM chart c
+                  WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
+                  (SELECT c.accno FROM chart c
+                  WHERE d.fxloss_accno_id = c.id) AS fxloss_accno
+               FROM defaults d|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $self->dberror($query);
+
+    $ref = $sth->fetchrow_hashref(NAME_lc);
+    map { $self->{$_} = $ref->{$_} } keys %$ref;
+    $sth->finish;
+
+    if ($self->{"$self->{vc}_id"}) {
+      # only setup currency
+      ($self->{currency}) = split /:/, $self->{currencies};
+      
+    } else {
+      
+      $self->lastname_used($dbh, $myconfig, $table, $module);
+    
+      my $fld = ($table eq 'customer') ? 'buy' : 'sell';
+      # get exchangerate for currency
+      $self->{exchangerate} = $self->get_exchangerate($dbh, $self->{currency}, $self->{transdate}, $fld);
+   
+    }
+
+  }
+
+  $dbh->disconnect;
+
+}
+
+
+sub lastname_used {
+  my ($self, $dbh, $myconfig, $table, $module) = @_;
+
+  my $arap = ($table eq 'customer') ? "ar" : "ap";
+  $arap = 'oe' if ($self->{type} =~ /_order/);
+
+  my $query = qq|SELECT id FROM $arap
+                 WHERE id IN (SELECT MAX(id) FROM $arap
+                             WHERE ${table}_id > 0)|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+  
+  my ($trans_id) = $sth->fetchrow_array;
+  $sth->finish;
+  
+  $trans_id *= 1;
+  $query = qq|SELECT ct.name, a.curr, a.${table}_id,
+              current_date + ct.terms AS duedate
+             FROM $arap a
+             JOIN $table ct ON (a.${table}_id = ct.id)
+             WHERE a.id = $trans_id|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $self->dberror($query);
+
+  ($self->{$table}, $self->{currency}, $self->{"${table}_id"}, $self->{duedate}) = $sth->fetchrow_array;
+  $sth->finish;
+
+}
+
+
+
+sub current_date {
+  my ($self, $myconfig, $thisdate, $days) = @_;
+  
+  my $dbh = $self->dbconnect($myconfig);
+  my ($sth, $query);
+
+  $days *= 1;
+  if ($thisdate) {
+    my $dateformat = $myconfig->{dateformat};
+    $dateformat .= "yy" if $myconfig->{dateformat} !~ /^y/;
+    
+    $query = qq|SELECT to_date('$thisdate', '$dateformat') + $days AS thisdate
+                FROM defaults|;
+     $sth = $dbh->prepare($query);
+     $sth->execute || $self->dberror($query);
+  } else {
+    $query = qq|SELECT current_date AS thisdate
+                FROM defaults|;
+     $sth = $dbh->prepare($query);
+     $sth->execute || $self->dberror($query);
+  }
+
+  ($thisdate) = $sth->fetchrow_array;
+  $sth->finish;
+
+  $dbh->disconnect;
+
+  $thisdate;
+
+}
+
+
+sub like {
+  my ($self, $string) = @_;
+  
+  unless ($string =~ /%/) {
+    $string = "%$string%";
+  }
+
+  $string =~ s/'/''/g;
+  $string;
+  
+}
+
+
+sub redo_rows {
+  my ($self, $flds, $new, $count, $numrows) = @_;
+
+  my @ndx = ();
+
+  map { push @ndx, { num => $new->[$_-1]->{runningnumber}, ndx => $_ } } (1 .. $count);
+
+  my $i = 0;
+  # fill rows
+  foreach my $item (sort { $a->{num} <=> $b->{num} } @ndx) {
+    $i++;
+    $j = $item->{ndx} - 1;
+    map { $self->{"${_}_$i"} = $new->[$j]->{$_} } @{$flds};
+  }
+
+  # delete empty rows
+  for $i ($count + 1 .. $numrows) {
+    map { delete $self->{"${_}_$i"} } @{$flds}; 
+  }
+
+}
+
+  
+package Locale;
+
+
+sub new {
+  my ($type, $country, $NLS_file) = @_;
+  my $self = {};
+
+  %self = ();
+  if ($country && -d "locale/$country") {
+    $self->{countrycode} = $country;
+    eval { require "locale/$country/$NLS_file"; };
+  }
+
+  $self->{NLS_file} = $NLS_file;
+  
+  push @{ $self->{LONG_MONTH} }, ("January", "February", "March", "April", "May ", "June", "July", "August", "September", "October", "November", "December");
+  push @{ $self->{SHORT_MONTH} }, (qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec));
+  
+  bless $self, $type;
+
+}
+
+
+sub text {
+  my ($self, $text) = @_;
+  
+  return (exists $self{texts}{$text}) ? $self{texts}{$text} : $text;
+  
+}
+
+
+sub findsub {
+  my ($self, $text) = @_;
+
+  if (exists $self{subs}{$text}) {
+    $text = $self{subs}{$text};
+  } else {
+    if ($self->{countrycode} && $self->{NLS_file}) {
+      Form->error("$text not defined in locale/$self->{countrycode}/$self->{NLS_file}");
+    }
+  }
+
+  $text;
+
+}
+
+
+sub date {
+  my ($self, $myconfig, $date, $longformat) = @_;
+
+  my $longdate = "";
+  my $longmonth = ($longformat) ? 'LONG_MONTH' : 'SHORT_MONTH';
+
+  if ($date) {
+    # get separator
+    $spc = $myconfig->{dateformat};
+    $spc =~ s/\w//g;
+    $spc = substr($spc, 1, 1);
+
+    if ($spc eq '.') {
+      $spc = '\.';
+    }
+    if ($spc eq '/') {
+      $spc = '\/';
+    }
+
+    if ($myconfig->{dateformat} =~ /^yy/) {
+      ($yy, $mm, $dd) = split /$spc/, $date;
+    }
+    if ($myconfig->{dateformat} =~ /^mm/) {
+      ($mm, $dd, $yy) = split /$spc/, $date;
+    }
+    if ($myconfig->{dateformat} =~ /^dd/) {
+      ($dd, $mm, $yy) = split /$spc/, $date;
+    }
+    
+    $dd *= 1;
+    $mm--;
+    $yy = ($yy < 70) ? $yy + 2000 : $yy;
+    $yy = ($yy >= 70 && $yy <= 99) ? $yy + 1900 : $yy;
+
+    if ($myconfig->{dateformat} =~ /^dd/) {
+      $longdate = "$dd. ".&text($self, $self->{$longmonth}[$mm])." $yy";
+    } else {
+      $longdate = &text($self, $self->{$longmonth}[$mm])." $dd, $yy";
+    }
+
+  }
+
+  $longdate;
+
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/GL.pm b/sql-ledger/SL/GL.pm
new file mode 100644 (file)
index 0000000..5bceb07
--- /dev/null
@@ -0,0 +1,462 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# General ledger backend code
+#
+# CHANGE LOG:
+#   DS. 2000-07-04  Created
+#   DS. 2001-06-12  Changed relations from accno to chart_id
+#
+#======================================================================
+
+package GL;
+
+
+sub delete_transaction {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my $query = qq|DELETE FROM gl WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  $query = qq|DELETE FROM acc_trans WHERE trans_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  # commit and redirect
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+  
+  $rc;
+  
+}
+
+
+sub post_transaction {
+  my ($self, $myconfig, $form) = @_;
+  
+  my ($debit, $credit) = (0, 0);
+  my $project_id;
+
+  my $i;
+  # check if debit and credit balances
+  for $i (1 .. $form->{rowcount}) {
+    if ($form->{"debit_$i"} && $form->{"credit_$i"}) {
+      return -1;
+    }
+
+    $form->{"debit_$i"} = $form->parse_amount($myconfig, $form->{"debit_$i"});
+    $form->{"credit_$i"} = $form->parse_amount($myconfig, $form->{"credit_$i"});
+
+    $debit += $form->{"debit_$i"};
+    $credit += $form->{"credit_$i"};
+  }
+
+  $debit = $form->round_amount($debit, 2);
+  $credit = $form->round_amount($credit, 2);
+  
+  if ($debit != $credit) {
+    return -2;
+  }
+
+  if (($debit + $credit) == 0) {
+    return -3;
+  }
+  
+  # connect to database, turn off AutoCommit
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  # post the transaction
+  # make up a unique handle and store in reference field
+  # then retrieve the record based on the unique handle to get the id
+  # replace the reference field with the actual variable
+  # add records to acc_trans
+
+  # if there is a $form->{id} replace the old transaction
+  # delete all acc_trans entries and add the new ones
+
+  # escape '
+  map { $form->{$_} =~ s/'/''/g } qw(reference description);
+
+
+  my ($query, $sth);
+  
+  if ($form->{id}) {
+    # delete individual transactions
+    $query = qq|DELETE FROM acc_trans 
+                WHERE trans_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+    
+  } else {
+    my $uid = time;
+    $uid .= $form->{login};
+
+    $query = qq|INSERT INTO gl (reference, employee_id)
+                VALUES ('$uid', (SELECT id FROM employee
+                                WHERE login = '$form->{login}'))|;
+    $dbh->do($query) || $form->dberror($query);
+    
+    $query = qq|SELECT id FROM gl
+                WHERE reference = '$uid'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{id}) = $sth->fetchrow_array;
+    $sth->finish;
+
+  }
+  
+  $query = qq|UPDATE gl SET 
+             reference = '$form->{reference}',
+             description = '$form->{description}',
+             notes = '$form->{notes}',
+             transdate = '$form->{transdate}'
+             WHERE id = $form->{id}|;
+          
+  $dbh->do($query) || $form->dberror($query);
+
+  # insert acc_trans transactions
+  for $i (1 .. $form->{rowcount}) {
+    # extract accno
+    ($accno) = split(/--/, $form->{"accno_$i"});
+    my $amount = 0;
+    
+    if ($form->{"credit_$i"} != 0) {
+      $amount = $form->{"credit_$i"};
+    }
+    if ($form->{"debit_$i"} != 0) {
+      $amount = $form->{"debit_$i"} * -1;
+    }
+
+
+    # if there is an amount, add the record
+    if ($amount != 0) {
+      $project_id = ($form->{"project_id_$i"}) ? $form->{"project_id_$i"} : 'NULL'; 
+      $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
+                  source, project_id)
+                 VALUES
+                 ($form->{id}, (SELECT id
+                                FROM chart
+                                WHERE accno = '$accno'),
+                  $amount, '$form->{transdate}', '$form->{reference}',
+                 $project_id)|;
+    
+      $dbh->do($query) || $form->dberror($query);
+    }
+  }
+
+  # commit and redirect
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+
+}
+
+
+
+sub all_transactions {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  my $query;
+  my $sth;
+
+  my ($glwhere, $arwhere, $apwhere) = ("1 = 1", "1 = 1", "1 = 1");
+  
+  if ($form->{reference}) {
+    my $source = $form->like(lc $form->{reference});
+    $glwhere .= " AND lower(g.reference) LIKE '$source'";
+    $arwhere .= " AND lower(a.invnumber) LIKE '$source'";
+    $apwhere .= " AND lower(a.invnumber) LIKE '$source'";
+  }
+  if ($form->{source}) {
+    my $source = $form->like(lc $form->{source});
+    $glwhere .= " AND lower(ac.source) LIKE '$source'";
+    $arwhere .= " AND lower(ac.source) LIKE '$source'";
+    $apwhere .= " AND lower(ac.source) LIKE '$source'";
+  }
+  if ($form->{datefrom}) {
+    $glwhere .= " AND ac.transdate >= '$form->{datefrom}'";
+    $arwhere .= " AND ac.transdate >= '$form->{datefrom}'";
+    $apwhere .= " AND ac.transdate >= '$form->{datefrom}'";
+  }
+  if ($form->{dateto}) {
+    $glwhere .= " AND ac.transdate <= '$form->{dateto}'";
+    $arwhere .= " AND ac.transdate <= '$form->{dateto}'";
+    $apwhere .= " AND ac.transdate <= '$form->{dateto}'";
+  }
+  if ($form->{description}) {
+    my $description = $form->like(lc $form->{description});
+    $glwhere .= " AND lower(g.description) LIKE '$description'";
+    $arwhere .= " AND lower(ct.name) LIKE '$description'";
+    $apwhere .= " AND lower(ct.name) LIKE '$description'";
+  }
+  if ($form->{notes}) {
+    my $notes = $form->like(lc $form->{notes});
+    $glwhere .= " AND lower(g.notes) LIKE '$notes'";
+    $arwhere .= " AND lower(a.notes) LIKE '$notes'";
+    $apwhere .= " AND lower(a.notes) LIKE '$notes'";
+  }
+  if ($form->{accno}) {
+    $glwhere .= " AND c.accno = '$form->{accno}'";
+    $arwhere .= " AND c.accno = '$form->{accno}'";
+    $apwhere .= " AND c.accno = '$form->{accno}'";
+  }
+  if ($form->{gifi_accno}) {
+    $glwhere .= " AND c.gifi_accno = '$form->{gifi_accno}'";
+    $arwhere .= " AND c.gifi_accno = '$form->{gifi_accno}'";
+    $apwhere .= " AND c.gifi_accno = '$form->{gifi_accno}'";
+  }
+  if ($form->{category} ne 'X') {
+    $glwhere .= " AND c.category = '$form->{category}'";
+    $arwhere .= " AND c.category = '$form->{category}'";
+    $apwhere .= " AND c.category = '$form->{category}'";
+  }
+
+  if ($form->{accno}) {
+    # get category for account
+    $query = qq|SELECT category
+                FROM chart
+               WHERE accno = '$form->{accno}'|;
+    $sth = $dbh->prepare($query); 
+
+    $sth->execute || $form->dberror($query); 
+    ($form->{ml}) = $sth->fetchrow_array; 
+    $sth->finish; 
+    
+    if ($form->{datefrom}) {
+      $query = qq|SELECT SUM(ac.amount)
+                 FROM acc_trans ac, chart c
+                 WHERE ac.chart_id = c.id
+                 AND c.accno = '$form->{accno}'
+                 AND ac.transdate < date '$form->{datefrom}'
+                 |;
+      $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+
+      ($form->{balance}) = $sth->fetchrow_array;
+      $sth->finish;
+    }
+  }
+  
+  if ($form->{gifi_accno}) {
+    # get category for account
+    $query = qq|SELECT category
+                FROM chart
+               WHERE gifi_accno = '$form->{gifi_accno}'|;
+    $sth = $dbh->prepare($query); 
+
+    $sth->execute || $form->dberror($query); 
+    ($form->{ml}) = $sth->fetchrow_array; 
+    $sth->finish; 
+   
+    if ($form->{datefrom}) {
+      $query = qq|SELECT SUM(ac.amount)
+                 FROM acc_trans ac, chart c
+                 WHERE ac.chart_id = c.id
+                 AND c.gifi_accno = '$form->{gifi_accno}'
+                 AND ac.transdate < date '$form->{datefrom}'
+                 |;
+      $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+
+      ($form->{balance}) = $sth->fetchrow_array;
+      $sth->finish;
+    }
+  }
+
+  my $false = ($myconfig->{dbdriver} eq 'Pg') ? FALSE : q|'0'|;
+
+  my $sortorder = join ', ', $form->sort_columns(qw(transdate reference source description accno));
+  my %ordinal = ( transdate => 6,
+                  reference => 4,
+                  source => 7,
+                 description => 5 );
+  map { $sortorder =~ s/$_/$ordinal{$_}/ } keys %ordinal;
+  
+  my $query = qq|SELECT g.id, 'gl' AS type, $false AS invoice, g.reference,
+                 g.description, ac.transdate, ac.source,
+                ac.amount, c.accno, c.gifi_accno, g.notes
+                 FROM gl g, acc_trans ac, chart c
+                 WHERE $glwhere
+                AND ac.chart_id = c.id
+                AND g.id = ac.trans_id
+       UNION ALL
+                SELECT a.id, 'ar' AS type, a.invoice, a.invnumber,
+                ct.name, ac.transdate, ac.source,
+                ac.amount, c.accno, c.gifi_accno, a.notes
+                FROM ar a, acc_trans ac, chart c, customer ct
+                WHERE $arwhere
+                AND ac.chart_id = c.id
+                AND a.customer_id = ct.id
+                AND a.id = ac.trans_id
+       UNION ALL
+                SELECT a.id, 'ap' AS type, a.invoice, a.invnumber,
+                ct.name, ac.transdate, ac.source,
+                ac.amount, c.accno, c.gifi_accno, a.notes
+                FROM ap a, acc_trans ac, chart c, vendor ct
+                WHERE $apwhere
+                AND ac.chart_id = c.id
+                AND a.vendor_id = ct.id
+                AND a.id = ac.trans_id
+                ORDER BY $sortorder|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+    # gl
+    if ($ref->{type} eq "gl") {
+      $ref->{module} = "gl";
+    }
+
+    # ap
+    if ($ref->{type} eq "ap") {
+      if ($ref->{invoice}) {
+        $ref->{module} = "ir";
+      } else {
+        $ref->{module} = "ap";
+      }
+    }
+
+    # ar
+    if ($ref->{type} eq "ar") {
+      if ($ref->{invoice}) {
+        $ref->{module} = "is";
+      } else {
+        $ref->{module} = "ar";
+      }
+    }
+
+    if ($ref->{amount} < 0) {
+      $ref->{debit} = $ref->{amount} * -1;
+      $ref->{credit} = 0;
+    } else {
+      $ref->{credit} = $ref->{amount};
+      $ref->{debit} = 0;
+    }
+
+    push @{ $form->{GL} }, $ref;
+    
+  }
+
+  $sth->finish;
+
+  if ($form->{accno}) {
+    $query = qq|SELECT description FROM chart WHERE accno = '$form->{accno}'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{account_description}) = $sth->fetchrow_array;
+    $sth->finish;
+  }
+  if ($form->{gifi_accno}) {
+    $query = qq|SELECT description FROM gifi WHERE accno = '$form->{gifi_accno}'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{gifi_account_description}) = $sth->fetchrow_array;
+    $sth->finish;
+  }
+  $dbh->disconnect;
+
+}
+
+
+sub transaction {
+  my ($self, $myconfig, $form) = @_;
+  
+  my ($query, $sth);
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  if ($form->{id}) {
+    $query = "SELECT closedto, revtrans
+              FROM defaults";
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{closedto}, $form->{revtrans}) = $sth->fetchrow_array;
+    $sth->finish;
+
+    $query = "SELECT reference, description, notes, transdate
+              FROM gl
+             WHERE id = $form->{id}";
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{reference}, $form->{description}, $form->{notes}, $form->{transdate}) = $sth->fetchrow_array;
+    $sth->finish;
+  
+    # retrieve individual rows
+    $query = "SELECT c.accno, a.amount, project_id,
+                (SELECT p.projectnumber FROM project p
+                WHERE a.project_id = p.id) AS projectnumber
+             FROM acc_trans a, chart c
+             WHERE a.chart_id = c.id
+             AND a.trans_id = $form->{id}
+             ORDER BY accno";
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+    
+    while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+      push @{ $form->{GL} }, $ref;
+    }
+  } else {
+    $query = "SELECT current_date AS transdate, closedto, revtrans
+              FROM defaults";
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{transdate}, $form->{closedto}, $form->{revtrans}) = $sth->fetchrow_array;
+  }
+
+  $sth->finish;
+
+  # get chart of accounts
+  $query = qq|SELECT accno,description
+              FROM chart
+             WHERE charttype = 'A'
+              ORDER by accno|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+  $form->{chart} = "";
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{chart} }, $ref;
+  }
+  $sth->finish;
+  
+  $dbh->disconnect;
+
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/IC.pm b/sql-ledger/SL/IC.pm
new file mode 100644 (file)
index 0000000..f4a2f75
--- /dev/null
@@ -0,0 +1,936 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Inventory Control backend
+#
+#======================================================================
+
+package IC;
+
+
+sub get_part {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to db
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT p.*,
+                 c1.accno AS inventory_accno,
+                 c2.accno AS income_accno,
+                 c3.accno AS expense_accno,
+                pg.partsgroup
+                FROM parts p
+                LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
+                LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
+                LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
+                LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+                 WHERE p.id = $form->{id}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+  my $ref = $sth->fetchrow_hashref(NAME_lc);
+
+  # copy to $form variables
+  map { $form->{$_} = $ref->{$_} } ( keys %{ $ref } );
+  
+  $sth->finish;
+  
+  my %oid = ('Pg'      => 'a.oid',
+             'Oracle'  => 'a.rowid'
+           );
+  
+  
+  # part or service item
+  $form->{item} = ($form->{inventory_accno}) ? 'part' : 'service';
+  if ($form->{assembly}) {
+    $form->{item} = 'assembly';
+
+    # retrieve assembly items
+    $query = qq|SELECT p.id, p.partnumber, p.description,
+                p.sellprice, p.weight, a.qty, a.bom, p.unit,
+               pg.partsgroup
+                FROM parts p
+               JOIN assembly a ON (a.parts_id = p.id)
+               LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+               WHERE a.id = $form->{id}
+               ORDER BY $oid{$myconfig->{dbdriver}}|;
+
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+    
+    $form->{assembly_rows} = 0;
+    while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+      $form->{assembly_rows}++;
+      foreach my $key ( keys %{ $ref } ) {
+       $form->{"${key}_$form->{assembly_rows}"} = $ref->{$key};
+      }
+    }
+    $sth->finish;
+
+  }
+
+  # setup accno hash for <option checked> {amount} is used in create_links
+  $form->{amount}{IC} = $form->{inventory_accno};
+  $form->{amount}{IC_income} = $form->{income_accno};
+  $form->{amount}{IC_sale} = $form->{income_accno};
+  $form->{amount}{IC_expense} = $form->{expense_accno};
+  $form->{amount}{IC_cogs} = $form->{expense_accno};
+  
+
+  if ($form->{item} ne 'service') {
+    # get makes
+    if ($form->{makemodel}) {
+      $query = qq|SELECT name FROM makemodel
+                  WHERE parts_id = $form->{id}|;
+
+      $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+      
+      my $i = 1;
+      while (($form->{"make_$i"}, $form->{"model_$i"}) = split(/:/, $sth->fetchrow_array)) {
+       $i++;
+      }
+      $sth->finish;
+      $form->{makemodel_rows} = $i - 1;
+
+    }
+  }
+
+  # now get accno for taxes
+  $query = qq|SELECT c.accno
+              FROM chart c, partstax pt
+             WHERE pt.chart_id = c.id
+             AND pt.parts_id = $form->{id}|;
+  
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (($key) = $sth->fetchrow_array) {
+    $form->{amount}{$key} = $key;
+  }
+
+  $sth->finish;
+
+  # is it an orphan
+  $query = qq|SELECT parts_id
+              FROM invoice
+             WHERE parts_id = $form->{id}
+             UNION
+             SELECT parts_id
+             FROM orderitems
+             WHERE parts_id = $form->{id}
+             UNION
+             SELECT parts_id
+             FROM assembly
+             WHERE parts_id = $form->{id}|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  ($form->{orphaned}) = $sth->fetchrow_array;
+  $form->{orphaned} = !$form->{orphaned};
+  $sth->finish;
+  
+  $dbh->disconnect;
+  
+}
+
+
+
+sub save {
+  my ($self, $myconfig, $form) = @_;
+
+  ($form->{inventory_accno}) = split(/--/, $form->{IC});
+  ($form->{expense_accno}) = split(/--/, $form->{IC_expense});
+  ($form->{income_accno}) = split(/--/, $form->{IC_income});
+
+  # connect to database, turn off AutoCommit
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  # save the part
+  # make up a unique handle and store in partnumber field
+  # then retrieve the record based on the unique handle to get the id
+  # replace the partnumber field with the actual variable
+  # add records for makemodel
+
+  # if there is a $form->{id} then replace the old entry
+  # delete all makemodel entries and add the new ones
+
+  # escape '
+  map { $form->{$_} =~ s/'/''/g } qw(partnumber description notes unit bin);
+
+  # undo amount formatting
+  map { $form->{$_} = $form->parse_amount($myconfig, $form->{$_}) } qw(rop weight listprice sellprice lastcost stock);
+  
+  # set date to NULL if nothing entered
+  $form->{priceupdate} = ($form->{priceupdate}) ? qq|'$form->{priceupdate}'| : "NULL";
+  
+  $form->{makemodel} = (($form->{make_1}) || ($form->{model_1})) ? 1 : 0;
+
+  $form->{alternate} = 0;
+  $form->{assembly} = ($form->{item} eq 'assembly') ? 1 : 0;
+  $form->{obsolete} *= 1;
+  $form->{onhand} *= 1;
+
+  my ($query, $sth);
+  
+  if ($form->{id}) {
+
+    # get old price
+    $query = qq|SELECT sellprice, weight
+                FROM parts
+               WHERE id = $form->{id}|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    my ($sellprice, $weight) = $sth->fetchrow_array;
+    $sth->finish;
+
+    # if item is part of an assembly adjust all assemblies
+    $query = qq|SELECT id, qty
+                FROM assembly
+               WHERE parts_id = $form->{id}|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    while (my ($id, $qty) = $sth->fetchrow_array) {
+      &update_assembly($dbh, $form, $id, $qty * 1, $sellprice * 1, $weight * 1);
+    }
+    $sth->finish;
+
+
+    if ($form->{item} ne 'service') {
+      # delete makemodel records
+      $query = qq|DELETE FROM makemodel
+                 WHERE parts_id = $form->{id}|;
+      $dbh->do($query) || $form->dberror($query);
+    }
+
+    if ($form->{item} eq 'assembly') {
+      if ($form->{onhand} != 0) {
+       &adjust_inventory($dbh, $form, $form->{id}, $form->{onhand} * -1);
+      }
+      
+      if ($form->{orphaned}) {
+       # delete assembly records
+       $query = qq|DELETE FROM assembly
+                   WHERE id = $form->{id}|;
+       $dbh->do($query) || $form->dberror($query);
+      } else {
+        # update BOM only
+       $query = qq|UPDATE assembly
+                   SET bom = ?
+                   WHERE id = ?
+                   AND parts_id = ?|;
+       $sth = $dbh->prepare($query);
+       
+       for $i (1 .. $form->{assembly_rows} - 1) {
+          $sth->execute(($form->{"bom_$i"}) ? '1' : '0', $form->{id}, $form->{"id_$i"}) || $form->dberror($query);
+       }
+       $sth->finish;
+      }
+      
+      $form->{onhand} += $form->{stock};
+    }
+    
+    # delete tax records
+    $query = qq|DELETE FROM partstax
+               WHERE parts_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+
+  } else {
+    my $uid = time;
+    $uid .= $form->{login};
+
+    $query = qq|INSERT INTO parts (partnumber)
+                VALUES ('$uid')|;
+    $dbh->do($query) || $form->dberror($query);
+
+    $query = qq|SELECT id FROM parts
+                WHERE partnumber = '$uid'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{id}) = $sth->fetchrow_array;
+    $sth->finish;
+
+    $form->{orphaned} = 1;
+    $form->{onhand} = ($form->{stock} * 1) if $form->{item} eq 'assembly';
+    
+  }
+  
+  my $partsgroup_id = 0;
+  if ($form->{partsgroup}) {
+    my $partsgroup = lc $form->{partsgroup};
+    $query = qq|SELECT DISTINCT id FROM partsgroup
+               WHERE lower(partsgroup) = '$partsgroup'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($partsgroup_id) = $sth->fetchrow_array;
+    $sth->finish;
+
+    if (!$partsgroup_id) {
+      $query = qq|INSERT INTO partsgroup (partsgroup)
+                  VALUES ('$form->{partsgroup}')|;
+      $dbh->do($query) || $form->dberror($query);
+
+      $query = qq|SELECT id FROM partsgroup
+                  WHERE partsgroup = '$form->{partsgroup}'|;
+      $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+
+      ($partsgroup_id) = $sth->fetchrow_array;
+      $sth->finish;
+    }
+  }
+  
+  
+  $query = qq|UPDATE parts SET 
+             partnumber = '$form->{partnumber}',
+             description = '$form->{description}',
+             makemodel = '$form->{makemodel}',
+             alternate = '$form->{alternate}',
+             assembly = '$form->{assembly}',
+             listprice = $form->{listprice},
+             sellprice = $form->{sellprice},
+             lastcost = $form->{lastcost},
+             weight = $form->{weight},
+             priceupdate = $form->{priceupdate},
+             unit = '$form->{unit}',
+             notes = '$form->{notes}',
+             rop = $form->{rop},
+             bin = '$form->{bin}',
+             inventory_accno_id = (SELECT id FROM chart
+                                   WHERE accno = '$form->{inventory_accno}'),
+             income_accno_id = (SELECT id FROM chart
+                                WHERE accno = '$form->{income_accno}'),
+             expense_accno_id = (SELECT id FROM chart
+                                 WHERE accno = '$form->{expense_accno}'),
+              obsolete = '$form->{obsolete}',
+             image = '$form->{image}',
+             drawing = '$form->{drawing}',
+             microfiche = '$form->{microfiche}',
+             partsgroup_id = $partsgroup_id
+             WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  # insert makemodel records
+  unless ($form->{item} eq 'service') {
+    for my $i (1 .. $form->{makemodel_rows}) {
+      # put make and model together
+      if (($form->{"make_$i"}) || ($form->{"model_$i"})) {
+       map { $form->{"${_}_$i"} =~ s/'/''/g } qw(make model);
+       
+       $query = qq|INSERT INTO makemodel (parts_id, name)
+                   VALUES ($form->{id},
+                   '$form->{"make_$i"}:$form->{"model_$i"}')|;
+       $dbh->do($query) || $form->dberror($query);
+      }
+    }
+  }
+
+
+  # insert taxes
+  foreach $item (split / /, $form->{taxaccounts}) {
+    if ($form->{"IC_tax_$item"}) {
+      $query = qq|INSERT INTO partstax (parts_id, chart_id)
+                  VALUES ($form->{id}, 
+                         (SELECT id
+                          FROM chart
+                          WHERE accno = '$item'))|;
+      $dbh->do($query) || $form->dberror($query);
+    }
+  }
+
+  # add assembly records
+  if ($form->{item} eq 'assembly') {
+    
+    if ($form->{orphaned}) {
+      for my $i (1 .. $form->{assembly_rows}) {
+       $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
+       
+       if ($form->{"qty_$i"} != 0) {
+         $form->{"bom_$i"} *= 1;
+         $query = qq|INSERT INTO assembly (id, parts_id, qty, bom)
+                     VALUES ($form->{id}, $form->{"id_$i"},
+                     $form->{"qty_$i"}, '$form->{"bom_$i"}')|;
+         $dbh->do($query) || $form->dberror($query);
+       }
+      }
+    }
+    
+    # adjust onhand for the assembly
+    if ($form->{onhand} != 0) {
+      &adjust_inventory($dbh, $form, $form->{id}, $form->{onhand});
+    }
+    
+  }
+
+  # commit
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+  
+}
+
+
+
+sub update_assembly {
+  my ($dbh, $form, $id, $qty, $sellprice, $weight) = @_;
+
+  my $query = qq|SELECT id, qty
+                 FROM assembly
+                WHERE parts_id = $id|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my ($pid, $aqty) = $sth->fetchrow_array) {
+    &update_assembly($dbh, $form, $pid, $aqty * $qty, $sellprice, $weight);
+  }
+  $sth->finish;
+
+  $query = qq|UPDATE parts
+              SET sellprice = sellprice +
+                 $qty * ($form->{sellprice} - $sellprice),
+                  weight = weight +
+                 $qty * ($form->{weight} - $weight)
+             WHERE id = $id|;
+  $dbh->do($query) || $form->dberror($query);
+
+}
+
+
+
+sub retrieve_assemblies {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $where = '1 = 1';
+  
+  if ($form->{partnumber}) {
+    my $partnumber = $form->like(lc $form->{partnumber});
+    $where .= " AND lower(p.partnumber) LIKE '$partnumber'";
+  }
+  
+  if ($form->{description}) {
+    my $description = $form->like(lc $form->{description});
+    $where .= " AND lower(p.description) LIKE '$description'";
+  }
+  $where .= " AND NOT p.obsolete = '1'";
+
+  # retrieve assembly items
+  my $query = qq|SELECT p.id, p.partnumber, p.description,
+                 p.bin, p.onhand, p.rop,
+                  (SELECT sum(p2.inventory_accno_id)
+                   FROM parts p2, assembly a
+                   WHERE p2.id = a.parts_id
+                   AND a.id = p.id) AS inventory
+                 FROM parts p
+                WHERE $where
+                AND assembly = '1'|;
+
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+  
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{assembly_items} }, $ref if $ref->{inventory};
+  }
+  $sth->finish;
+
+  $dbh->disconnect;
+  
+}
+
+
+sub restock_assemblies {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect_noauto($myconfig);
+  
+  for my $i (1 .. $form->{rowcount}) {
+
+    $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
+
+    if ($form->{"qty_$i"} != 0) {
+      &adjust_inventory($dbh, $form, $form->{"id_$i"}, $form->{"qty_$i"});
+    }
+
+  }
+  
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+
+}
+
+
+sub adjust_inventory {
+  my ($dbh, $form, $id, $qty) = @_;
+
+  my $query = qq|SELECT p.id, p.inventory_accno_id, p.assembly, a.qty
+                FROM parts p
+                JOIN assembly a ON (a.parts_id = p.id)
+                WHERE a.id = $id|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+    my $allocate = $qty * $ref->{qty};
+    
+    # is it a service item, then loop
+    $ref->{inventory_accno_id} *= 1;
+    next if (($ref->{inventory_accno_id} == 0) && !$ref->{assembly});
+    
+    # adjust parts onhand
+    $form->update_balance($dbh,
+                         "parts",
+                         "onhand",
+                         qq|id = $ref->{id}|,
+                         $allocate * -1);
+  }
+
+  $sth->finish;
+
+  # update assembly
+  $form->update_balance($dbh,
+                       "parts",
+                       "onhand",
+                       qq|id = $id|,
+                       $qty);
+}
+
+
+sub delete {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database, turn off AutoCommit
+  my $dbh = $form->dbconnect_noauto($myconfig);
+  
+  if ($form->{item} eq 'assembly' && $form->{onhand} != 0) {
+    # adjust onhand for the assembly
+    &adjust_inventory($dbh, $form, $form->{id}, $form->{onhand} * -1);
+  }
+
+  my $query = qq|DELETE FROM parts
+                WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  $query = qq|DELETE FROM partstax
+             WHERE parts_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  # check if it is a part, assembly or service
+  if ($form->{item} eq 'part') {
+    $query = qq|DELETE FROM makemodel
+               WHERE parts_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+  }
+
+  if ($form->{item} eq 'assembly') {
+    $query = qq|DELETE FROM assembly
+               WHERE id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+  }
+  
+  if ($form->{item} eq 'alternate') {
+    $query = qq|DELETE FROM alternate
+               WHERE id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+  }
+
+  # commit
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+  
+}
+
+
+sub assembly_item {
+  my ($self, $myconfig, $form) = @_;
+
+  my $i = $form->{assembly_rows};
+  my $var;
+  my $where = "1 = 1";
+
+  if ($form->{"partnumber_$i"}) {
+    $var = $form->like(lc $form->{"partnumber_$i"});
+    $where .= " AND lower(p.partnumber) LIKE '$var'";
+  }
+  if ($form->{"description_$i"}) {
+    $var = $form->like(lc $form->{"description_$i"});
+    $where .= " AND lower(p.description) LIKE '$var'";
+  }
+  if ($form->{"partsgroup_$i"}) {
+    $var = $form->like(lc $form->{"partsgroup_$i"});
+    $where .= " AND lower(pg.partsgroup) LIKE '$var'";
+  }
+  
+  if ($form->{id}) {
+    $where .= " AND NOT p.id = $form->{id}";
+  }
+
+  if ($partnumber) {
+    $where .= " ORDER BY p.partnumber";
+  } else {
+    $where .= " ORDER BY p.description";
+  }
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT p.id, p.partnumber, p.description, p.sellprice,
+                 p.weight, p.onhand, p.unit,
+                pg.partsgroup
+                FROM parts p
+                LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+                WHERE $where|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{item_list} }, $ref;
+  }
+  
+  $sth->finish;
+  $dbh->disconnect;
+  
+}
+
+
+sub all_parts {
+  my ($self, $myconfig, $form) = @_;
+
+  my $where = '1 = 1';
+  my $var;
+  
+  foreach my $item (qw(partnumber drawing microfiche)) {
+    if ($form->{$item}) {
+      $var = $form->like(lc $form->{$item});
+      $where .= " AND lower(p.$item) LIKE '$var'";
+    }
+  }
+  # special case for description
+  if ($form->{description}) {
+    unless ($form->{bought} || $form->{sold} || $form->{onorder} || $form->{ordered}) {
+      $var = $form->like(lc $form->{description});
+      $where .= " AND lower(p.description) LIKE '$var'";
+    }
+  }
+
+  if ($form->{searchitems} eq 'part') {
+    $where .= " AND p.inventory_accno_id > 0";
+  }
+  if ($form->{searchitems} eq 'assembly') {
+    $form->{bought} = "";
+    $where .= " AND p.assembly = '1'";
+  }
+  if ($form->{searchitems} eq 'service') {
+    $where .= " AND p.inventory_accno_id IS NULL AND NOT p.assembly = '1'";
+    # irrelevant for services
+    $form->{make} = $form->{model} = "";
+  }
+
+  # items which were never bought, sold or on an order
+  if ($form->{itemstatus} eq 'orphaned') {
+    $form->{onhand} = $form->{short} = 0;
+    $form->{bought} = $form->{sold} = 0;
+    $form->{onorder} = $form->{ordered} = 0;
+    $form->{transdatefrom} = $form->{transdateto} = "";
+    
+    $where .= " AND p.onhand = 0
+                AND p.id NOT IN (SELECT p.id FROM parts p, invoice i
+                                WHERE p.id = i.parts_id)
+               AND p.id NOT IN (SELECT p.id FROM parts p, assembly a
+                                WHERE p.id = a.parts_id)
+                AND p.id NOT IN (SELECT p.id FROM parts p, orderitems o
+                                WHERE p.id = o.parts_id)";
+  }
+  
+  if ($form->{itemstatus} eq 'active') {
+    $where .= " AND p.obsolete = '0'";
+  }
+  if ($form->{itemstatus} eq 'obsolete') {
+    $where .= " AND p.obsolete = '1'";
+    $form->{onhand} = $form->{short} = 0;
+  }
+  if ($form->{itemstatus} eq 'onhand') {
+    $where .= " AND p.onhand > 0";
+  }
+  if ($form->{itemstatus} eq 'short') {
+    $where .= " AND p.onhand < 0";
+  }
+
+  if ($form->{make}) {
+    $var = $form->like(lc $form->{make}).":%";
+    $where .= " AND p.id IN (SELECT DISTINCT ON (m.parts_id) m.parts_id
+                           FROM makemodel m WHERE lower(m.name) LIKE '$var')";
+  }
+  if ($form->{model}) {
+    $var = "%:".$form->like($form->{model});
+    $where .= " AND p.id IN (SELECT DISTINCT ON (m.parts_id) m.parts_id
+                           FROM makemodel m WHERE lower(m.name) LIKE '$var')";
+  }
+  if ($form->{partsgroup}) {
+    $var = $form->like(lc $form->{partsgroup});
+    $where .= " AND lower(pg.partsgroup) LIKE '$var'";
+    
+  }
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  
+  my $sortorder = join ', ', $form->sort_columns(qw(partnumber description bin priceupdate partsgroup));
+  $sortorder = $form->{sort} unless $sortorder;
+
+  my $query = qq|SELECT p.id, p.partnumber, p.description, p.onhand, p.unit,
+                 p.bin, p.sellprice, p.listprice, p.lastcost, p.rop, p.weight,
+                p.priceupdate, p.image, p.drawing, p.microfiche,
+                pg.partsgroup
+                 FROM parts p
+                 LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+                WHERE $where
+                ORDER BY $sortorder|;
+
+  # rebuild query for bought and sold items
+  if ($form->{bought} || $form->{sold} || $form->{onorder} || $form->{ordered}) {
+    
+    my $union = "";
+    $query = "";
+  
+    if ($form->{bought} || $form->{sold}) {
+      
+      my $invwhere = "$where";
+      $invwhere .= " AND i.assemblyitem = '0'";
+      $invwhere .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+      $invwhere .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+
+      if ($form->{description}) {
+       $var = $form->like(lc $form->{description});
+       $invwhere .= " AND lower(i.description) LIKE '$var'";
+      }
+
+      my $flds = qq|p.id, p.partnumber, i.description,
+                    i.qty AS onhand, i.unit, p.bin, i.sellprice,
+                   p.listprice, p.lastcost, p.rop, p.weight,
+                   p.priceupdate, p.image, p.drawing, p.microfiche,
+                   pg.partsgroup,
+                   a.invnumber, a.ordnumber, i.trans_id|;
+
+      if ($form->{bought}) {
+       $query = qq|
+                   SELECT $flds, 'ir' AS module, '' AS type,
+                   1 AS exchangerate
+                   FROM parts p
+                   JOIN invoice i ON (i.parts_id = p.id)
+                   JOIN ap a ON (i.trans_id = a.id)
+                    LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+                   WHERE $invwhere|;
+       $union = "
+                 UNION";
+      }
+
+      if ($form->{sold}) {
+       $query .= qq|$union
+                     SELECT $flds, 'is' AS module, '' AS type,
+                    1 As exchangerate
+                    FROM parts p
+                    JOIN invoice i ON (i.parts_id = p.id)
+                    JOIN ar a ON (i.trans_id = a.id)
+                     LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+                    WHERE $invwhere|;
+       $union = "
+                 UNION";
+      }
+    }
+
+    if ($form->{onorder} || $form->{ordered}) {
+      my $ordwhere = "$where";
+      $ordwhere .= " AND o.closed = '0'" unless $form->{closed};
+      
+      $ordwhere .= " AND o.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+      $ordwhere .= " AND o.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+
+      if ($form->{description}) {
+       $var = $form->like(lc $form->{description});
+       $ordwhere .= " AND lower(oi.description) LIKE '$var'";
+      }
+
+      $flds = qq|p.id, p.partnumber, oi.description,
+                 oi.qty AS onhand, oi.unit, p.bin, oi.sellprice,
+                p.listprice, p.lastcost, p.rop, p.weight,
+                p.priceupdate, p.image, p.drawing, p.microfiche,
+                pg.partsgroup,
+                '' AS invnumber, o.ordnumber, oi.trans_id|;
+
+      if ($form->{ordered}) {
+       $query .= qq|$union
+                     SELECT $flds, 'oe' AS module, 'sales_order' AS type,
+                   (SELECT buy FROM exchangerate ex
+                    WHERE ex.curr = o.curr
+                    AND ex.transdate = o.transdate) AS exchangerate
+                    FROM parts p
+                    JOIN orderitems oi ON (oi.parts_id = p.id)
+                    JOIN oe o ON (oi.trans_id = o.id)
+                     LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+                    WHERE $ordwhere
+                    AND o.customer_id > 0|;
+       $union = "
+                 UNION";
+      }
+      
+      if ($form->{onorder}) {
+        $flds = qq|p.id, p.partnumber, oi.description,
+                   oi.qty * -1 AS onhand, oi.unit, p.bin, oi.sellprice,
+                  p.listprice, p.lastcost, p.rop, p.weight,
+                  p.priceupdate, p.image, p.drawing, p.microfiche,
+                  pg.partsgroup,
+                  '' AS invnumber, o.ordnumber, oi.trans_id|;
+
+       $query .= qq|$union
+                   SELECT $flds, 'oe' AS module, 'purchase_order' AS type,
+                   (SELECT sell FROM exchangerate ex
+                    WHERE ex.curr = o.curr
+                    AND ex.transdate = o.transdate) AS exchangerate
+                   FROM parts p
+                   JOIN orderitems oi ON (oi.parts_id = p.id)
+                   JOIN oe o ON (oi.trans_id = o.id)
+                    LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+                   WHERE $ordwhere
+                   AND o.vendor_id > 0|;
+      }
+
+    }
+
+    $query .= qq|
+                ORDER BY $sortorder|;
+
+  }
+
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{parts} }, $ref;
+  }
+
+  $sth->finish;
+
+
+  # include individual items for assemblies
+  if ($form->{searchitems} eq 'assembly' && $form->{bom}) {
+    foreach $item (@{ $form->{parts} }) {
+      push @assemblies, $item;
+      $query = qq|SELECT p.id, p.partnumber, p.description, a.qty AS onhand,
+                  p.unit, p.bin,
+                  p.sellprice, p.listprice, p.lastcost,
+                 p.rop, p.weight, p.priceupdate,
+                 p.image, p.drawing, p.microfiche
+                 FROM parts p
+                 JOIN assembly a ON (p.id = a.parts_id)
+                 WHERE a.id = $item->{id}|;
+      
+      $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+
+      while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+       $ref->{assemblyitem} = 1;
+       push @assemblies, $ref;
+      }
+      $sth->finish;
+
+      push @assemblies, {id => $item->{id}};
+
+    }
+
+    # copy assemblies to $form->{parts}
+    @{ $form->{parts} } = @assemblies;
+    
+  }
+
+  $dbh->disconnect;
+
+}
+
+
+sub create_links {
+  my ($self, $module, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT accno, description, link
+                 FROM chart
+                WHERE link LIKE '%$module%'
+                ORDER BY accno|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    foreach my $key (split(/:/, $ref->{link})) {
+      if ($key =~ /$module/) {
+       push @{ $form->{"${module}_links"}{$key} }, { accno => $ref->{accno},
+                                     description => $ref->{description} };
+      }
+    }
+  }
+
+  $sth->finish;
+
+  if ($form->{id}) {
+    $query = qq|SELECT weightunit
+                FROM defaults|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{weightunit}) = $sth->fetchrow_array;
+    $sth->finish;
+
+  } else {
+    $query = qq|SELECT weightunit, current_date
+                FROM defaults|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{weightunit}, $form->{priceupdate}) = $sth->fetchrow_array;
+    $sth->finish;
+  }
+  
+  $dbh->disconnect;
+
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/IR.pm b/sql-ledger/SL/IR.pm
new file mode 100644 (file)
index 0000000..357533e
--- /dev/null
@@ -0,0 +1,995 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Inventory received module
+#
+#======================================================================
+
+package IR;
+
+
+sub post_invoice {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database, turn off autocommit
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my ($query, $sth, $null, $project_id);
+  my $exchangerate = 0;
+
+  if ($form->{id}) {
+
+    &reverse_invoice($dbh, $form);
+
+  } else {
+    my $uid = time;
+    $uid .= $form->{login};
+
+    $query = qq|INSERT INTO ap (invnumber, employee_id)
+                VALUES ('$uid', (SELECT id FROM employee
+                                WHERE login = '$form->{login}'))|;
+    $dbh->do($query) || $form->dberror($query);
+    
+    $query = qq|SELECT id FROM ap
+                WHERE invnumber = '$uid'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{id}) = $sth->fetchrow_array;
+    $sth->finish;
+  }
+
+  map { $form->{$_} =~ s/'/''/g } qw(invnumber ordnumber);
+  
+  my ($amount, $linetotal, $lastinventoryaccno, $lastexpenseaccno);
+  my ($netamount, $invoicediff, $expensediff) = (0, 0, 0);
+
+  if ($form->{currency} eq $form->{defaultcurrency}) {
+    $form->{exchangerate} = 1;
+  } else {
+    $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, 'sell');
+  }
+  
+  $form->{exchangerate} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{exchangerate});
+
+  
+  for my $i (1 .. $form->{rowcount}) {
+    $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
+    
+    if ($form->{"qty_$i"} != 0) {
+      
+      map { $form->{"${_}_$i"} =~ s/'/''/g } qw(partnumber description unit);
+      
+      my ($allocated, $taxrate) = (0, 0);
+      my $taxamount;
+      
+      $form->{"sellprice_$i"} = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
+      my $fxsellprice = $form->{"sellprice_$i"};
+
+      my ($dec) = ($fxsellprice =~ /\.(\d+)/);
+      $dec = length $dec;
+      my $decimalplaces = ($dec > 2) ? $dec : 2;
+      
+      
+      map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{"taxaccounts_$i"};
+
+      if ($form->{"inventory_accno_$i"}) {
+
+       $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
+       
+       if ($form->{taxincluded}) {
+         $taxamount = $linetotal * ($taxrate / (1 + $taxrate));
+         $form->{"sellprice_$i"} = $form->{"sellprice_$i"} * (1 / (1 + $taxrate));
+       } else {
+         $taxamount = $linetotal * $taxrate;
+       }
+
+       $netamount += $linetotal;
+       
+       if ($taxamount != 0) {
+         map { $form->{amount}{$form->{id}}{$_} -= $taxamount * $form->{"${_}_rate"} / $taxrate } split / /, $form->{"taxaccounts_$i"};
+       }
+
+       # add purchase to inventory, this one is without the tax!
+       $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * $form->{exchangerate};
+       $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2) * $form->{exchangerate};
+       $linetotal = $form->round_amount($linetotal, 2);
+
+        # this is the difference for the inventory
+       $invoicediff += ($amount - $linetotal);
+       
+       $form->{amount}{$form->{id}}{$form->{"inventory_accno_$i"}} -= $linetotal;
+
+        # adjust and round sellprice
+       $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} * $form->{exchangerate}, $decimalplaces);
+
+       
+       # update parts table
+       $query = qq|UPDATE parts SET
+                   lastcost = $form->{"sellprice_$i"},
+                   onhand = onhand + $form->{"qty_$i"}
+                   WHERE id = $form->{"id_$i"}|;
+       $dbh->do($query) || $form->dberror($query);
+
+
+        # check if we sold the item already and
+        # make an entry for the expense and inventory
+       $query = qq|SELECT i.id, i.qty, i.allocated, i.trans_id,
+                   p.inventory_accno_id, p.expense_accno_id, a.transdate
+                   FROM invoice i, ar a, parts p
+                   WHERE i.parts_id = p.id
+                   AND i.parts_id = $form->{"id_$i"}
+                   AND (i.qty + i.allocated) > 0
+                   AND i.trans_id = a.id
+                   ORDER BY transdate|;
+       $sth = $dbh->prepare($query);
+       $sth->execute || $form->dberror($query);
+
+
+        my $totalqty = $form->{"qty_$i"};
+       
+       while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+         
+         my $qty = $ref->{qty} + $ref->{allocated};
+         
+         if (($qty - $totalqty) > 0) {
+           $qty = $totalqty;
+         }
+
+
+          $linetotal = $form->round_amount($form->{"sellprice_$i"} * $qty, 2);
+         
+         if ($ref->{allocated} < 0) {
+           # we have an entry for it already, adjust amount
+           $form->update_balance($dbh,
+                                 "acc_trans",
+                                 "amount",
+                                 qq|trans_id = $ref->{trans_id} AND chart_id = $ref->{inventory_accno_id} AND transdate = '$ref->{transdate}'|,
+                                 $linetotal);
+
+           $form->update_balance($dbh,
+                                 "acc_trans",
+                                 "amount",
+                                 qq|trans_id = $ref->{trans_id} AND chart_id = $ref->{expense_accno_id} AND transdate = '$ref->{transdate}'|,
+                                 $linetotal * -1);
+
+         } else {
+           # add entry for inventory, this one is for the sold item
+           if ($linetotal != 0) {
+             $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, 
+                         transdate)
+                         VALUES ($ref->{trans_id}, $ref->{inventory_accno_id},
+                         $linetotal, '$ref->{transdate}')|;
+             $dbh->do($query) || $form->dberror($query);
+
+             # add expense
+             $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, 
+                         transdate)
+                         VALUES ($ref->{trans_id}, $ref->{expense_accno_id},
+                         |. ($linetotal * -1) .qq|, '$ref->{transdate}')|;
+             $dbh->do($query) || $form->dberror($query);
+           }
+         }
+       
+         # update allocated for sold item
+         $form->update_balance($dbh,
+                               "invoice",
+                               "allocated",
+                               qq|id = $ref->{id}|,
+                               $qty * -1);
+       
+         $allocated += $qty;
+
+         last if (($totalqty -= $qty) <= 0);
+       }
+
+       $sth->finish;
+
+        $lastinventoryaccno = $form->{"inventory_accno_$i"};
+       
+      } else {
+       
+       $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
+       
+        if ($form->{taxincluded}) {
+         $taxamount = $linetotal * ($taxrate / (1 + $taxrate));
+         
+         $form->{"sellprice_$i"} = $form->{"sellprice_$i"} * (1 / (1 + $taxrate));
+       } else {
+         $taxamount = $linetotal * $taxrate;
+       }
+       
+       $netamount += $linetotal;
+       
+        if ($taxamount != 0) {
+         map { $form->{amount}{$form->{id}}{$_} -= $taxamount * $form->{"${_}_rate"} / $taxrate } split / /, $form->{"taxaccounts_$i"};
+       }
+
+        $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * $form->{exchangerate};
+       $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2) * $form->{exchangerate};
+       $linetotal = $form->round_amount($linetotal, 2);
+
+        # this is the difference for expense
+       $expensediff += ($amount - $linetotal);
+       
+       # add amount to expense
+       $form->{amount}{$form->{id}}{$form->{"expense_accno_$i"}} -= $linetotal;
+
+       $lastexpenseaccno = $form->{"expense_accno_$i"};
+
+        # adjust and round sellprice
+        $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} * $form->{exchangerate}, $decimalplaces);
+       
+       # update lastcost
+       $query = qq|UPDATE parts SET
+                   lastcost = $form->{"sellprice_$i"}
+                   WHERE id = $form->{"id_$i"}|;
+       $dbh->do($query) || $form->dberror($query);
+
+      }
+
+      $project_id = 'NULL';
+      if ($form->{"project_id_$i"}) {
+       $project_id = $form->{"project_id_$i"};
+      }
+      $deliverydate = ($form->{"deliverydate_$i"}) ? qq|'$form->{"deliverydate_$i"}'| : "NULL";
+      
+      # save detail record in invoice table
+      $query = qq|INSERT INTO invoice (trans_id, parts_id, description, qty,
+                  sellprice, fxsellprice, allocated, unit, deliverydate)
+                 VALUES ($form->{id}, $form->{"id_$i"},
+                 '$form->{"description_$i"}', |. ($form->{"qty_$i"} * -1) .qq|,
+                 $form->{"sellprice_$i"}, $fxsellprice, $allocated,
+                 '$form->{"unit_$i"}', $deliverydate)|;
+      $dbh->do($query) || $form->dberror($query);
+
+    }
+  }
+
+
+  $form->{datepaid} = $form->{invdate};
+
+  # all amounts are in natural state, netamount includes the taxes
+  # if tax is included, netamount is rounded to 2 decimal places,
+  # taxes are not
+  
+  # total payments
+  for my $i (1 .. $form->{paidaccounts}) {
+    $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"});
+    $form->{paid} += $form->{"paid_$i"};
+    $form->{datepaid} = $form->{"datepaid_$i"} if ($form->{"datepaid_$i"}); 
+  }
+
+  my ($tax, $paiddiff) = (0, 0);
+
+  $netamount = $form->round_amount($netamount, 2);
+  
+  # figure out rounding errors for amount paid and total amount
+  if ($form->{taxincluded}) {
+
+    $amount = $form->round_amount($netamount * $form->{exchangerate}, 2);
+    $paiddiff = $amount - $netamount * $form->{exchangerate};
+    $netamount = $amount;
+
+    foreach my $item (split / /, $form->{taxaccounts}) {
+      $amount = $form->{amount}{$form->{id}}{$item} * $form->{exchangerate};
+      $form->{amount}{$form->{id}}{$item} = $form->round_amount($amount, 2);
+      $amount = $form->{amount}{$form->{id}}{$item} * -1;
+      $tax += $amount;
+      $netamount -= $amount;
+    }
+
+    $invoicediff += $paiddiff;
+    $expensediff += $paiddiff;
+    
+    ######## this only applies to tax included
+    if ($lastinventoryaccno) {
+      $form->{amount}{$form->{id}}{$lastinventoryaccno} -= $invoicediff;
+    }
+    if ($lastexpenseaccno) {
+      $form->{amount}{$form->{id}}{$lastexpenseaccno} -= $expensediff;
+    }
+
+  } else {
+    $amount = $form->round_amount($netamount * $form->{exchangerate}, 2);
+    $paiddiff = $amount - $netamount * $form->{exchangerate};
+    $netamount = $amount;
+    foreach my $item (split / /, $form->{taxaccounts}) {
+      $form->{amount}{$form->{id}}{$item} = $form->round_amount($form->{amount}{$form->{id}}{$item}, 2);
+      $amount = $form->round_amount($form->{amount}{$form->{id}}{$item} * $form->{exchangerate} * -1, 2);
+      $paiddiff += $amount - $form->{amount}{$form->{id}}{$item} * $form->{exchangerate} * -1;
+      $form->{amount}{$form->{id}}{$item} = $form->round_amount($amount * -1, 2);
+      $amount = $form->{amount}{$form->{id}}{$item} * -1;
+      $tax += $amount;
+    }
+  }
+
+
+  $form->{amount}{$form->{id}}{$form->{AP}} = $netamount + $tax;
+
+  if ($form->{paid} != 0) {
+    $form->{paid} = $form->round_amount($form->{paid} * $form->{exchangerate} + $paiddiff, 2);
+  }
+
+
+  # update exchangerate
+  if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
+    $form->update_exchangerate($dbh, $form->{currency}, $form->{invdate}, 0, $form->{exchangerate});
+  }
+  
+  # record acc_trans transactions
+  foreach my $trans_id (keys %{$form->{amount}}) {
+    foreach my $accno (keys %{ $form->{amount}{$trans_id} }) {
+      if (($form->{amount}{$trans_id}{$accno} = $form->round_amount($form->{amount}{$trans_id}{$accno}, 2)) != 0) {
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, 
+                   transdate)
+                   VALUES ($trans_id, (SELECT id FROM chart
+                                        WHERE accno = '$accno'),
+                   $form->{amount}{$trans_id}{$accno}, '$form->{invdate}')|;
+       $dbh->do($query) || $form->dberror($query);
+      }
+    }
+  }
+
+  # deduct payment differences from paiddiff
+  for my $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"} != 0) {
+      $amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate}, 2);
+      $paiddiff -= $amount - $form->{"paid_$i"} * $form->{exchangerate};
+    }
+  }
+
+  # force AP entry if 0
+  $form->{amount}{$form->{id}}{$form->{AP}} = $form->{paid} if ($form->{amount}{$form->{id}}{$form->{AP}} == 0);
+  
+  # record payments and offsetting AP
+  for my $i (1 .. $form->{paidaccounts}) {
+
+    if ($form->{"paid_$i"} != 0) {
+      my ($accno) = split /--/, $form->{"AP_paid_$i"};
+      $form->{"datepaid_$i"} = $form->{invdate} unless ($form->{"datepaid_$i"});
+      $form->{datepaid} = $form->{"datepaid_$i"};
+      
+      $amount = ($form->round_amount($form->{"paid_$i"} * $form->{exchangerate} + $paiddiff, 2)) * -1;
+      
+      # record AP
+      
+      if ($form->{amount}{$form->{id}}{$form->{AP}} != 0) {
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                   transdate)
+                   VALUES ($form->{id}, (SELECT id FROM chart
+                                       WHERE accno = '$form->{AP}'),
+                   $amount, '$form->{"datepaid_$i"}')|;
+       $dbh->do($query) || $form->dberror($query);
+      }
+
+      # record payment
+      
+      $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
+                  source)
+                  VALUES ($form->{id}, (SELECT id FROM chart
+                                     WHERE accno = '$accno'),
+                  $form->{"paid_$i"}, '$form->{"datepaid_$i"}',
+                 '$form->{"source_$i"}')|;
+      $dbh->do($query) || $form->dberror($query);
+
+
+      $exchangerate = 0;
+
+      if ($form->{currency} eq $form->{defaultcurrency}) {
+       $form->{"exchangerate_$i"} = 1;
+      } else {
+       $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'sell');
+
+       $form->{"exchangerate_$i"} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{"exchangerate_$i"});
+      }
+      
+
+      # exchangerate difference
+      $form->{fx}{$accno}{$form->{"datepaid_$i"}} += $form->{"paid_$i"} * ($form->{"exchangerate_$i"} - 1) + $paiddiff;
+      
+
+      # gain/loss
+      $amount = ($form->{"paid_$i"} * $form->{exchangerate}) - ($form->{"paid_$i"} * $form->{"exchangerate_$i"});
+      if ($amount > 0) {
+       $form->{fx}{$form->{fxgain_accno}}{$form->{"datepaid_$i"}} += $amount;
+      } else {
+       $form->{fx}{$form->{fxloss_accno}}{$form->{"datepaid_$i"}} += $amount;
+      }
+      
+      $paiddiff = 0;
+
+      # update exchange rate
+      if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
+       $form->update_exchangerate($dbh, $form->{currency}, $form->{"datepaid_$i"}, 0, $form->{"exchangerate_$i"});
+      }
+    }
+  }
+
+  # record exchange rate differences and gains/losses
+  foreach my $accno (keys %{$form->{fx}}) {
+    foreach my $transdate (keys %{ $form->{fx}{$accno} }) {
+      if (($form->{fx}{$accno}{$transdate} = $form->round_amount($form->{fx}{$accno}{$transdate}, 2)) != 0) {
+
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                   transdate, cleared, fx_transaction)
+                   VALUES ($form->{id}, (SELECT id FROM chart
+                                       WHERE accno = '$accno'),
+                    $form->{fx}{$accno}{$transdate}, '$transdate', '0', '1')|;
+        $dbh->do($query) || $form->dberror($query);
+      }
+    }
+  }
+
+
+  $amount = $netamount + $tax;
+
+  # set values which could be empty
+  $form->{taxincluded} *= 1;
+  my $datepaid = ($form->{paid}) ? qq|'$form->{datepaid}'| : "NULL";
+  my $duedate = ($form->{duedate}) ? qq|'$form->{duedate}'| : "NULL";
+  
+  # save AP record
+  $query = qq|UPDATE ap set
+              invnumber = '$form->{invnumber}',
+             ordnumber = '$form->{ordnumber}',
+              transdate = '$form->{invdate}',
+              vendor_id = $form->{vendor_id},
+              amount = $amount,
+              netamount = $netamount,
+              paid = $form->{paid},
+             datepaid = $datepaid,
+             duedate = $duedate,
+             invoice = '1',
+             taxincluded = '$form->{taxincluded}',
+             notes = '$form->{notes}',
+             curr = '$form->{currency}'
+              WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  # add shipto
+  $form->{name} = $form->{vendor};
+  $form->{name} =~ s/--$form->{vendor_id}//;
+  $form->add_shipto($dbh, $form->{id});
+  
+  # delete zero entries
+  $query = qq|DELETE FROM acc_trans
+              WHERE amount = 0|;
+  $dbh->do($query) || $form->dberror($query);
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+  $rc;
+  
+}
+
+
+
+sub reverse_invoice {
+  my ($dbh, $form) = @_;
+  
+  # reverse inventory items
+  my $query = qq|SELECT i.parts_id, p.inventory_accno_id, p.expense_accno_id,
+                 i.qty, i.allocated, i.sellprice
+                 FROM invoice i, parts p
+                WHERE i.parts_id = p.id
+                 AND i.trans_id = $form->{id}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $netamount = 0;
+  
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    $netamount += $form->round_amount($ref->{sellprice} * $ref->{qty} * -1, 2);
+
+    if ($ref->{inventory_accno_id}) {
+      # update onhand
+      $form->update_balance($dbh,
+                           "parts",
+                           "onhand",
+                           qq|id = $ref->{parts_id}|,
+                           $ref->{qty});
+      # if $ref->{allocated} > 0 than we sold that many items
+      if ($ref->{allocated} > 0) {
+
+       # get references for sold items
+       $query = qq|SELECT i.id, i.trans_id, i.allocated, a.transdate
+                   FROM invoice i, ar a
+                   WHERE i.parts_id = $ref->{parts_id}
+                   AND i.allocated < 0
+                   AND i.trans_id = a.id
+                   ORDER BY transdate DESC|;
+       my $sth = $dbh->prepare($query);
+       $sth->execute || $form->dberror($query);
+
+       while (my $pthref = $sth->fetchrow_hashref(NAME_lc)) {
+         my $qty = $ref->{allocated};
+         if (($ref->{allocated} + $pthref->{allocated}) > 0) {
+           $qty = $pthref->{allocated} * -1;
+         }
+
+         my $amount = $form->round_amount($ref->{sellprice} * $qty, 2);
+         
+         #adjust allocated
+         $form->update_balance($dbh,
+                               "invoice",
+                               "allocated",
+                               qq|id = $pthref->{id}|,
+                               $qty);
+         
+         $form->update_balance($dbh,
+                               "acc_trans",
+                               "amount",
+                               qq|trans_id = $pthref->{trans_id} AND chart_id = $ref->{expense_accno_id} AND transdate = '$pthref->{transdate}'|,
+                               $amount);
+                     
+         $form->update_balance($dbh,
+                               "acc_trans",
+                               "amount",
+                               qq|trans_id = $pthref->{trans_id} AND chart_id = $ref->{inventory_accno_id} AND transdate = '$pthref->{transdate}'|,
+                               $amount * -1);
+
+         last if (($ref->{allocated} -= $qty) <= 0);
+       }
+       $sth->finish;
+      }
+    }
+  }
+  $sth->finish;
+  
+  # delete acc_trans
+  $query = qq|DELETE FROM acc_trans
+              WHERE trans_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  # delete invoice entries
+  $query = qq|DELETE FROM invoice
+              WHERE trans_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  $query = qq|DELETE FROM shipto
+              WHERE trans_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+  
+} 
+
+
+
+sub delete_invoice {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  # check for other foreign currency transactions
+  $form->delete_exchangerate($dbh) if ($form->{currency} ne $form->{defaultcurrency});
+
+  &reverse_invoice($dbh, $form);
+  
+  # delete zero entries
+  my $query = qq|DELETE FROM acc_trans
+                 WHERE amount = 0|;
+  $dbh->do($query) || $form->dberror($query);
+
+  # delete AP record
+  my $query = qq|DELETE FROM ap
+                 WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+  
+}
+
+
+
+sub retrieve_invoice {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my $query;
+
+  if ($form->{id}) {
+    # get default accounts and last invoice number
+    $query = qq|SELECT (SELECT c.accno FROM chart c
+                        WHERE d.inventory_accno_id = c.id) AS inventory_accno,
+                       (SELECT c.accno FROM chart c
+                       WHERE d.income_accno_id = c.id) AS income_accno,
+                       (SELECT c.accno FROM chart c
+                       WHERE d.expense_accno_id = c.id) AS expense_accno,
+                      (SELECT c.accno FROM chart c
+                       WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
+                      (SELECT c.accno FROM chart c
+                       WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
+                d.curr AS currencies
+               FROM defaults d|;
+  } else {
+    $query = qq|SELECT (SELECT c.accno FROM chart c
+                        WHERE d.inventory_accno_id = c.id) AS inventory_accno,
+                       (SELECT c.accno FROM chart c
+                       WHERE d.income_accno_id = c.id) AS income_accno,
+                       (SELECT c.accno FROM chart c
+                       WHERE d.expense_accno_id = c.id) AS expense_accno,
+                      (SELECT c.accno FROM chart c
+                       WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
+                      (SELECT c.accno FROM chart c
+                       WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
+                d.ponumber AS invnumber, d.curr AS currencies,
+               current_date AS invdate
+               FROM defaults d|;
+  }
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $ref = $sth->fetchrow_hashref(NAME_lc);
+  map { $form->{$_} = $ref->{$_} } keys %$ref;
+  $sth->finish;
+
+
+  if ($form->{id}) {
+    
+    # retrieve invoice
+    $query = qq|SELECT a.invnumber, a.transdate AS invdate, a.duedate,
+                a.ordnumber, a.paid, a.taxincluded, a.notes, a.curr AS currency
+               FROM ap a
+               WHERE id = $form->{id}|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    $ref = $sth->fetchrow_hashref(NAME_lc);
+    map { $form->{$_} = $ref->{$_} } keys %$ref;
+    $sth->finish;
+
+    $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{invdate}, "sell");
+    
+    # get shipto
+    $query = qq|SELECT * FROM shipto
+                WHERE trans_id = $form->{id}|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    $ref = $sth->fetchrow_hashref(NAME_lc);
+    map { $form->{$_} = $ref->{$_} } keys %$ref;
+    $sth->finish;
+    
+    # retrieve individual items
+    $query = qq|SELECT c1.accno AS inventory_accno,
+                       c2.accno AS income_accno,
+                      c3.accno AS expense_accno,
+               p.partnumber, i.description, i.qty, i.fxsellprice AS sellprice,
+               i.parts_id AS id, i.unit, p.bin, i.deliverydate,
+               pr.projectnumber,
+                i.project_id,
+               pg.partsgroup
+               FROM invoice i
+               JOIN parts p ON (i.parts_id = p.id)
+               LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
+               LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
+               LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
+               LEFT JOIN project pr ON (i.project_id = pr.id)
+               LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
+               WHERE trans_id = $form->{id}
+               ORDER BY i.id|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+      # get tax rates for part
+      $query = qq|SELECT c.accno
+                  FROM chart c, partstax pt
+                 WHERE pt.chart_id = c.id
+                 AND pt.parts_id = $ref->{id}|;
+      my $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+
+      $ref->{taxaccounts} = "";
+      my $taxrate = 0;
+      
+      while (my $ptref = $sth->fetchrow_hashref(NAME_lc)) {
+        $ref->{taxaccounts} .= "$ptref->{accno} ";
+        $taxrate += $form->{"$ptref->{accno}_rate"};
+      }
+      
+      $sth->finish;
+      chop $ref->{taxaccounts};
+
+      $ref->{qty} *= -1;
+      
+      push @{ $form->{invoice_details} }, $ref;
+      
+    }
+    
+    $sth->finish;
+    
+  } else {
+
+    # up invoice number by 1
+    $form->{invnumber}++;
+
+    # save the new number
+    $query = qq|UPDATE defaults
+                SET ponumber = '$form->{invnumber}'|;
+    $dbh->do($query) || $form->dberror($query);
+
+  }
+  
+  
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+  
+  $rc;
+  
+}
+
+
+
+sub get_vendor {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  
+  my $dateformat = $myconfig->{dateformat};
+  $dateformat .= "yy" if $myconfig->{dateformat} !~ /^y/;
+
+  my $duedate = ($form->{invdate}) ? "to_date('$form->{invdate}', '$dateformat')" : "current_date";
+
+  $form->{vendor_id} *= 1;
+  # get vendor
+  my $query = qq|SELECT taxincluded, terms, email, cc, bcc,
+                 addr1, addr2, addr3, addr4,
+                 $duedate + terms AS duedate
+                 FROM vendor
+                WHERE id = $form->{vendor_id}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  $ref = $sth->fetchrow_hashref(NAME_lc);
+  map { $form->{$_} = $ref->{$_} } keys %$ref;
+  $sth->finish;
+  
+  # get shipto if we do not convert an order or invoice
+  if (!$form->{shipto}) {
+    map { delete $form->{$_} } qw(shiptoname shiptoaddr1 shiptoaddr2 shiptoaddr3 shiptoaddr4 shiptocontact shiptophone shiptofax shiptoemail);
+
+    $query = qq|SELECT * FROM shipto
+                WHERE trans_id = $form->{vendor_id}|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    $ref = $sth->fetchrow_hashref(NAME_lc);
+    map { $form->{$_} = $ref->{$_} } keys %$ref;
+    $sth->finish;
+  }
+  
+  # get taxes for vendor
+  $query = qq|SELECT c.accno
+              FROM chart c, vendortax v
+             WHERE v.chart_id = c.id
+             AND v.vendor_id = $form->{vendor_id}|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $vendortax = ();
+  while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+    $vendortax{$ref->{accno}} = 1;
+  }
+  $sth->finish;
+
+
+  # get tax rates and description
+  $query = qq|SELECT c.accno, c.description, c.link, t.rate
+              FROM chart c, tax t
+              WHERE c.id = t.chart_id
+             AND c.link LIKE '%CT_tax%'
+             ORDER BY accno|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  $form->{taxaccounts} = "";
+  $form->{taxpart} = "";
+  $form->{taxservice} = "";
+  while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+    if ($vendortax{$ref->{accno}}) {
+      $form->{"$ref->{accno}_rate"} = $ref->{rate};
+      $form->{"$ref->{accno}_description"} = $ref->{description};
+      $form->{taxaccounts} .= "$ref->{accno} ";
+    }
+    
+    foreach my $item (split /:/, $ref->{link}) {
+      if ($item =~ /IC_taxpart/) {
+       $form->{taxpart} .= "$ref->{accno} ";
+      }
+      
+      if ($item =~ /IC_taxservice/) {
+       $form->{taxservice} .= "$ref->{accno} ";
+      }
+    }
+  }
+  $sth->finish;
+  chop $form->{taxaccounts};
+  chop $form->{taxpart};
+  chop $form->{taxservice};
+
+  if (!$form->{id} && $form->{type} !~ /_order/) {
+    # setup last accounts used
+    $query = qq|SELECT c.accno, c.description, c.link, c.category
+                FROM chart c
+               JOIN acc_trans ac ON (ac.chart_id = c.id)
+               JOIN ap a ON (a.id = ac.trans_id)
+               WHERE a.vendor_id = $form->{vendor_id}
+               AND NOT (c.link LIKE '%_tax%' OR c.link LIKE '%_paid%')
+               AND a.id IN (SELECT max(id) FROM ap
+                            WHERE vendor_id = $form->{vendor_id})|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    my $i = 0;
+    while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+      if ($ref->{category} eq 'E') {
+       $i++;
+       $form->{"AP_amount_$i"} = "$ref->{accno}--$ref->{description}";
+      }
+      if ($ref->{category} eq 'L') {
+       $form->{AP} = $form->{AP_1} = "$ref->{accno}--$ref->{description}";
+      }
+    }
+    $sth->finish;
+    $form->{rowcount} = $i if ($i && !$form->{type});
+  }
+
+  $dbh->disconnect;
+  
+}
+
+
+sub retrieve_item {
+  my ($self, $myconfig, $form) = @_;
+
+  my $i = $form->{rowcount};
+  my $var;
+  
+  # don't include assemblies or obsolete parts
+  my $where = "NOT p.assembly = '1' AND NOT p.obsolete = '1'";
+  
+  if ($form->{"partnumber_$i"}) {
+    $var = $form->like(lc $form->{"partnumber_$i"});
+    $where .= " AND lower(p.partnumber) LIKE '$var'";
+  }
+  
+  if ($form->{"description_$i"}) {
+    $var = $form->like(lc $form->{"description_$i"});
+    $where .= " AND lower(p.description) LIKE '$var'";
+  }
+
+  if ($form->{"partsgroup_$i"}) {
+    $var = $form->like(lc $form->{"partsgroup_$i"});
+    $where .= " AND lower(pg.partsgroup) LIKE '$var'";
+  }
+
+  if ($form->{"description_$i"}) {
+    $where .= " ORDER BY description";
+  } else {
+    $where .= " ORDER BY partnumber";
+  }
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT p.id, p.partnumber, p.description,
+                 c1.accno AS inventory_accno,
+                c2.accno AS income_accno,
+                c3.accno AS expense_accno,
+                pg.partsgroup
+                 FROM parts p
+                LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
+                LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
+                LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
+                LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
+                WHERE $where|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    # get tax rates for part
+    $query = qq|SELECT c.accno
+                FROM chart c
+               JOIN partstax pt ON (pt.chart_id = c.id)
+               WHERE pt.parts_id = $ref->{id}|;
+    my $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    $ref->{taxaccounts} = "";
+    while (my $ptref = $sth->fetchrow_hashref(NAME_lc)) {
+      $ref->{taxaccounts} .= "$ptref->{accno} ";
+    }
+    $sth->finish;
+    chop $ref->{taxaccounts};
+    
+    push @{ $form->{item_list} }, $ref;
+  }
+  
+  $sth->finish;
+  $dbh->disconnect;
+  
+}
+
+
+
+sub vendor_details {
+  my ($self, $myconfig, $form) = @_;
+      
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  # get rest for the vendor
+  my $query = qq|SELECT vendornumber, name, addr1, addr2, addr3, addr4,
+                 contact, phone as vendorphone, fax as vendorfax, vendornumber
+                 FROM vendor
+                 WHERE id = $form->{vendor_id}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  $ref = $sth->fetchrow_hashref(NAME_lc);
+  map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+
+sub item_links {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT accno, description, link
+                FROM chart
+                WHERE link LIKE '%IC%'
+                ORDER BY accno|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    foreach my $key (split(/:/, $ref->{link})) {
+      if ($key =~ /IC/) {
+        push @{ $form->{IC_links}{$key} }, { accno => $ref->{accno},
+                                       description => $ref->{description} };
+      }
+    }
+  }
+
+  $sth->finish;
+}
+
+1;
+
diff --git a/sql-ledger/SL/IS.pm b/sql-ledger/SL/IS.pm
new file mode 100644 (file)
index 0000000..dc11e36
--- /dev/null
@@ -0,0 +1,1231 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Inventory invoicing module
+#
+#======================================================================
+
+package IS;
+
+
+sub invoice_details {
+  my ($self, $myconfig, $form) = @_;
+
+  $form->{duedate} = $form->{invdate} unless ($form->{duedate});
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT date '$form->{duedate}' - date '$form->{invdate}'
+                 AS terms
+                FROM defaults|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  ($form->{terms}) = $sth->fetchrow_array;
+  $sth->finish;
+
+  my $tax = 0;
+  my $item;
+  my $i;
+  my @partsgroup = ();
+  my $partsgroup;
+  my %oid = ( 'Pg' => 'oid',
+              'Oracle' => 'rowid' );
+  
+  # sort items by partsgroup
+  for $i (1 .. $form->{rowcount}) {
+    $partsgroup = "";
+    if ($form->{"partsgroup_$i"} && $form->{groupitems}) {
+      $form->format_string("partsgroup_$i");
+      $partsgroup = $form->{"partsgroup_$i"};
+    }
+    push @partsgroup, [ $i, $partsgroup ];
+  }
+  
+  my $sameitem = "";
+  foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) {
+    $i = $item->[0];
+
+    if ($item->[1] ne $sameitem) {
+      push(@{ $form->{description} }, qq|$item->[1]|);
+      $sameitem = $item->[1];
+
+      map { push(@{ $form->{$_} }, "") } qw(runningnumber number bin qty unit deliverydate sellprice listprice netprice discount linetotal);
+    }
+    
+    $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
+    
+    if ($form->{"qty_$i"} != 0) {
+
+      # add number, description and qty to $form->{number}, ....
+      push(@{ $form->{runningnumber} }, $i);
+      push(@{ $form->{number} }, qq|$form->{"partnumber_$i"}|);
+      push(@{ $form->{bin} }, qq|$form->{"bin_$i"}|);
+      push(@{ $form->{description} }, qq|$form->{"description_$i"}|);
+      push(@{ $form->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"}));
+      push(@{ $form->{unit} }, qq|$form->{"unit_$i"}|);
+      push(@{ $form->{deliverydate} }, qq|$form->{"deliverydate_$i"}|);
+      
+      push(@{ $form->{sellprice} }, $form->{"sellprice_$i"});
+      
+      # listprice
+      push(@{ $form->{listprice} }, $form->{"listprice_$i"});
+
+      my $sellprice = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
+      my ($dec) = ($sellprice =~ /\.(\d+)/);
+      $dec = length $dec;
+      my $decimalplaces = ($dec > 2) ? $dec : 2;
+      
+      my $discount = $form->round_amount($sellprice * $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100, $decimalplaces);
+      
+      # keep a netprice as well, (sellprice - discount)
+      $form->{"netprice_$i"} = $sellprice - $discount;
+      push(@{ $form->{netprice} }, ($form->{"netprice_$i"} != 0) ? $form->format_amount($myconfig, $form->{"netprice_$i"}, $decimalplaces) : " ");
+
+      
+      my $linetotal = $form->round_amount($form->{"qty_$i"} * $form->{"netprice_$i"}, 2);
+
+      $discount = ($discount != 0) ? $form->format_amount($myconfig, $discount * -1, $decimalplaces) : " ";
+      $linetotal = ($linetotal != 0) ? $linetotal : " ";
+      
+      push(@{ $form->{discount} }, $discount);
+
+      $form->{total} += $linetotal;
+
+      push(@{ $form->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2));
+      
+      my $taxrate = 0;
+      my ($taxamount, $taxbase);
+      
+      map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{"taxaccounts_$i"};
+
+      if ($form->{taxincluded}) {
+       # calculate tax
+       $taxamount = $linetotal * ($taxrate / (1 + $taxrate));
+       $taxbase = $linetotal - $taxamount;
+      } else {
+        $taxamount = $linetotal * $taxrate;
+       $taxbase = $linetotal;
+      }
+      
+      if ($taxamount != 0) {
+       foreach my $item (split / /, $form->{"taxaccounts_$i"}) {
+         $taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
+         $taxbase{$item} += $taxbase;
+       }
+      }
+
+      if ($form->{"assembly_$i"}) {
+       $sameitem = "";
+       
+        # get parts and push them onto the stack
+       my $sortorder = "";
+       if ($form->{groupitems}) { 
+         $sortorder = qq|ORDER BY pg.partsgroup, a.$oid{$myconfig->{dbdriver}}|;
+       } else {
+         $sortorder = qq|ORDER BY a.$oid{$myconfig->{dbdriver}}|;
+       }
+       
+       $query = qq|SELECT p.partnumber, p.description, p.unit, a.qty,
+                   pg.partsgroup
+                   FROM assembly a
+                   JOIN parts p ON (a.parts_id = p.id)
+                   LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+                   WHERE a.bom = '1'
+                   AND a.id = '$form->{"id_$i"}'
+                   $sortorder|;
+        $sth = $dbh->prepare($query);
+        $sth->execute || $form->dberror($query);
+
+       while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+         if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
+           map { push(@{ $form->{$_} }, "") } qw(runningnumber number unit qty bin sellprice listprice netprice discount linetotal);
+           $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
+           push(@{ $form->{description} }, $sameitem);
+         }
+           
+         push(@{ $form->{number} }, qq|$ref->{partnumber}|);
+         push(@{ $form->{description} }, qq|$ref->{description}|);
+         push(@{ $form->{unit} }, qq|$ref->{unit}|);
+         push(@{ $form->{qty} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}));
+
+          map { push(@{ $form->{$_} }, "") } qw(runningnumber bin sellprice listprice netprice discount linetotal);
+         
+       }
+       $sth->finish;
+      }
+      
+    }
+  }
+
+
+  foreach my $item (sort keys %taxaccounts) {
+    if ($form->round_amount($taxaccounts{$item}, 2) != 0) {
+      push(@{ $form->{taxbase} }, $form->format_amount($myconfig, $taxbase{$item}, 2));
+      
+      $tax += $taxamount = $form->round_amount($taxaccounts{$item}, 2);
+      
+      push(@{ $form->{tax} }, $form->format_amount($myconfig, $taxamount));
+      push(@{ $form->{taxdescription} }, $form->{"${item}_description"});
+      push(@{ $form->{taxrate} }, $form->format_amount($myconfig, $form->{"${item}_rate"} * 100));
+      push(@{ $form->{taxnumber} }, $form->{"${item}_taxnumber"});
+    }
+  }
+    
+
+  for my $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"}) {
+      push(@{ $form->{payment} }, $form->{"paid_$i"});
+      my ($accno, $description) = split /--/, $form->{"AR_paid_$i"};
+      push(@{ $form->{paymentaccount} }, $description); 
+      push(@{ $form->{paymentdate} }, $form->{"datepaid_$i"});
+      push(@{ $form->{paymentsource} }, $form->{"source_$i"});
+
+      $form->{paid} += $form->parse_amount($myconfig, $form->{"paid_$i"});
+    }
+  }
+  
+  $form->{subtotal} = $form->format_amount($myconfig, $form->{total}, 2);
+  $form->{invtotal} = ($form->{taxincluded}) ? $form->{total} : $form->{total} + $tax;
+  $form->{total} = $form->format_amount($myconfig, $form->{invtotal} - $form->{paid}, 2);
+  $form->{invtotal} = $form->format_amount($myconfig, $form->{invtotal}, 2);
+
+  $form->{paid} = $form->format_amount($myconfig, $form->{paid}, 2);
+
+  # myconfig variables
+  map { $form->{$_} = $myconfig->{$_} } (qw(company address tel fax signature businessnumber));
+  $form->{username} = $myconfig->{name};
+
+  $dbh->disconnect;
+  
+}
+
+
+sub project_description {
+  my ($self, $dbh, $id) = @_;
+
+  my $query = qq|SELECT description
+                 FROM project
+                WHERE id = $id|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  ($_) = $sth->fetchrow_array;
+
+  $sth->finish;
+
+  $_;
+
+}
+
+
+sub customer_details {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  
+  # get rest for the customer
+  my $query = qq|SELECT customernumber, name, addr1, addr2, addr3, addr4,
+                phone as customerphone, fax as customerfax, contact
+                FROM customer
+                WHERE id = $form->{customer_id}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  $ref = $sth->fetchrow_hashref(NAME_lc);
+  map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+
+sub post_invoice {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database, turn off autocommit
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my ($query, $sth, $null, $project_id, $deliverydate);
+  my $exchangerate = 0;
+  if ($form->{id}) {
+
+    &reverse_invoice($dbh, $form);
+
+  } else {
+    my $uid = time;
+    $uid .= $form->{login};
+    
+    $query = qq|INSERT INTO ar (invnumber, employee_id)
+                VALUES ('$uid', (SELECT id FROM employee
+                                WHERE login = '$form->{login}') )|;
+    $dbh->do($query) || $form->dberror($query);
+
+    $query = qq|SELECT id FROM ar
+                WHERE invnumber = '$uid'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{id}) = $sth->fetchrow_array;
+    $sth->finish;
+  }
+
+
+  map { $form->{$_} =~ s/'/''/g } (qw(invnumber shippingpoint notes message));
+
+  my ($netamount, $invoicediff) = (0, 0);
+  my ($amount, $linetotal, $lastincomeaccno);
+
+  if ($form->{currency} eq $form->{defaultcurrency}) {
+    $form->{exchangerate} = 1;
+  } else {
+    $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, 'buy');
+  }
+
+  $form->{exchangerate} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{exchangerate});
+  
+
+  foreach my $i (1 .. $form->{rowcount}) {
+    $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
+    
+    if ($form->{"qty_$i"} != 0) {
+
+      map { $form->{"${_}_$i"} =~ s/'/''/g } (qw(partnumber description unit));
+      
+      # undo discount formatting
+      $form->{"discount_$i"} = $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100;
+
+      my ($allocated, $taxrate) = (0, 0);
+      my $taxamount;
+      
+      # keep entered selling price
+      my $fxsellprice = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
+      
+      my ($dec) = ($fxsellprice =~ /\.(\d+)/);
+      $dec = length $dec;
+      my $decimalplaces = ($dec > 2) ? $dec : 2;
+      
+      # deduct discount
+      my $discount = $form->round_amount($fxsellprice * $form->{"discount_$i"}, $decimalplaces);
+      $form->{"sellprice_$i"} = $fxsellprice - $discount;
+      
+      # add tax rates
+      map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{"taxaccounts_$i"};
+
+      # round linetotal to 2 decimal places
+      $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
+      
+      if ($form->{taxincluded}) {
+       $taxamount = $linetotal * ($taxrate / (1 + $taxrate));
+       $form->{"sellprice_$i"} = $form->{"sellprice_$i"} * (1 / (1 + $taxrate));
+      } else {
+       $taxamount = $linetotal * $taxrate;
+      }
+
+      $netamount += $linetotal;
+      
+      if ($taxamount != 0) {
+       map { $form->{amount}{$form->{id}}{$_} += $taxamount * $form->{"${_}_rate"} / $taxrate } split / /, $form->{"taxaccounts_$i"};
+      }
+    
+    
+      # add amount to income, $form->{amount}{trans_id}{accno}
+      $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * $form->{exchangerate};
+      
+      $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2) * $form->{exchangerate};
+      $linetotal = $form->round_amount($linetotal, 2);
+      
+      # this is the difference from the inventory
+      $invoicediff += ($amount - $linetotal);
+                     
+      $form->{amount}{$form->{id}}{$form->{"income_accno_$i"}} += $linetotal;
+      
+      $lastincomeaccno = $form->{"income_accno_$i"};
+      
+
+      # adjust and round sellprice
+      $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} * $form->{exchangerate}, $decimalplaces);
+      
+      if ($form->{"inventory_accno_$i"} || $form->{"assembly_$i"}) {
+        # adjust parts onhand quantity
+
+        if ($form->{"assembly_$i"}) {
+         # do not update if assembly consists of all services
+         $query = qq|SELECT sum(p.inventory_accno_id)
+                     FROM parts p, assembly a
+                     WHERE a.parts_id = p.id
+                     AND a.id = $form->{"id_$i"}|;
+         $sth = $dbh->prepare($query);
+         $sth->execute || $form->dberror($query);
+
+         if ($sth->fetchrow_array) {
+           $form->update_balance($dbh,
+                                 "parts",
+                                 "onhand",
+                                 qq|id = $form->{"id_$i"}|,
+                                 $form->{"qty_$i"} * -1);
+         }
+         $sth->finish;
+          
+         # record assembly item as allocated
+         &process_assembly($dbh, $form, $form->{"id_$i"}, $form->{"qty_$i"});
+       } else {
+         $form->update_balance($dbh,
+                               "parts",
+                               "onhand",
+                               qq|id = $form->{"id_$i"}|,
+                               $form->{"qty_$i"} * -1);
+         
+         $allocated = &cogs($dbh, $form, $form->{"id_$i"}, $form->{"qty_$i"});
+       }
+      }
+
+      $project_id = 'NULL';
+      if ($form->{"project_id_$i"}) {
+       $project_id = $form->{"project_id_$i"};
+      }
+      $deliverydate = ($form->{"deliverydate_$i"}) ? qq|'$form->{"deliverydate_$i"}'| : "NULL";
+
+      # save detail record in invoice table
+      $query = qq|INSERT INTO invoice (trans_id, parts_id, description, qty,
+                  sellprice, fxsellprice, discount, allocated, assemblyitem,
+                 unit, deliverydate, project_id)
+                 VALUES ($form->{id}, $form->{"id_$i"},
+                 '$form->{"description_$i"}', $form->{"qty_$i"},
+                 $form->{"sellprice_$i"}, $fxsellprice,
+                 $form->{"discount_$i"}, $allocated, 'f',
+                 '$form->{"unit_$i"}', $deliverydate, $project_id)|;
+      $dbh->do($query) || $form->dberror($query);
+
+    }
+  }
+
+
+  $form->{datepaid} = $form->{invdate};
+  
+  # total payments, don't move we need it here
+  for my $i (1 .. $form->{paidaccounts}) {
+    $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"});
+    $form->{paid} += $form->{"paid_$i"};
+    $form->{datepaid} = $form->{"datepaid_$i"} if ($form->{"datepaid_$i"});
+  }
+  
+  my ($tax, $diff) = (0, 0);
+  
+  $netamount = $form->round_amount($netamount, 2);
+  
+  # figure out rounding errors for total amount vs netamount + taxes
+  if ($form->{taxincluded}) {
+    
+    $amount = $form->round_amount($netamount * $form->{exchangerate}, 2);
+    $diff += $amount - $netamount * $form->{exchangerate};
+    $netamount = $amount;
+    
+    foreach my $item (split / /, $form->{taxaccounts}) {
+      $amount = $form->{amount}{$form->{id}}{$item} * $form->{exchangerate};
+      $form->{amount}{$form->{id}}{$item} = $form->round_amount($amount, 2);
+      $tax += $form->{amount}{$form->{id}}{$item};
+      $netamount -= $form->{amount}{$form->{id}}{$item};
+    }
+
+    $invoicediff += $diff;
+    ######## this only applies to tax included
+    if ($lastincomeaccno) {
+      $form->{amount}{$form->{id}}{$lastincomeaccno} += $invoicediff;
+    }
+
+  } else {
+    $amount = $form->round_amount($netamount * $form->{exchangerate}, 2);
+    $diff = $amount - $netamount * $form->{exchangerate};
+    $netamount = $amount;
+    foreach my $item (split / /, $form->{taxaccounts}) {
+      $form->{amount}{$form->{id}}{$item} = $form->round_amount($form->{amount}{$form->{id}}{$item}, 2);
+      $amount = $form->round_amount($form->{amount}{$form->{id}}{$item} * $form->{exchangerate}, 2);
+      $diff += $amount - $form->{amount}{$form->{id}}{$item} * $form->{exchangerate};
+      $form->{amount}{$form->{id}}{$item} = $form->round_amount($amount, 2);
+      $tax += $form->{amount}{$form->{id}}{$item};
+    }
+  }
+
+  
+  $form->{amount}{$form->{id}}{$form->{AR}} = $netamount + $tax;
+
+  if ($form->{paid} != 0) {
+    $form->{paid} = $form->round_amount($form->{paid} * $form->{exchangerate} + $diff, 2);
+  }
+  
+  # reverse AR
+  $form->{amount}{$form->{id}}{$form->{AR}} *= -1;
+
+
+  # update exchangerate
+  if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
+    $form->update_exchangerate($dbh, $form->{currency}, $form->{invdate}, $form->{exchangerate}, 0);
+  }
+    
+  foreach my $trans_id (keys %{$form->{amount}}) {
+    foreach my $accno (keys %{ $form->{amount}{$trans_id} }) {
+      if (($form->{amount}{$trans_id}{$accno} = $form->round_amount($form->{amount}{$trans_id}{$accno}, 2)) != 0) {
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                   transdate)
+                   VALUES ($trans_id, (SELECT id FROM chart
+                                       WHERE accno = '$accno'),
+                   $form->{amount}{$trans_id}{$accno}, '$form->{invdate}')|;
+       $dbh->do($query) || $form->dberror($query);
+      }
+    }
+  }
+
+  # deduct payment differences from diff
+  for my $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"} != 0) {
+      $amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate}, 2);
+      $diff -= $amount - $form->{"paid_$i"} * $form->{exchangerate};
+    }
+  }
+
+  # force AR entry if 0
+  $form->{amount}{$form->{id}}{$form->{AR}} = 1 if ($form->{amount}{$form->{id}}{$form->{AR}} == 0);
+  
+  # record payments and offsetting AR
+  for my $i (1 .. $form->{paidaccounts}) {
+    
+    if ($form->{"paid_$i"} != 0) {
+      my ($accno) = split /--/, $form->{"AR_paid_$i"};
+      $form->{"datepaid_$i"} = $form->{invdate} unless ($form->{"datepaid_$i"});
+      $form->{datepaid} = $form->{"datepaid_$i"};
+      
+      # record AR
+      $amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate} + $diff, 2);
+
+      if ($form->{amount}{$form->{id}}{$form->{AR}} != 0) {
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                   transdate)
+                   VALUES ($form->{id}, (SELECT id FROM chart
+                                       WHERE accno = '$form->{AR}'),
+                   $amount, '$form->{"datepaid_$i"}')|;
+       $dbh->do($query) || $form->dberror($query);
+      }
+
+      # record payment
+      $form->{"paid_$i"} *= -1;
+
+      $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
+                  source)
+                  VALUES ($form->{id}, (SELECT id FROM chart
+                                     WHERE accno = '$accno'),
+                 $form->{"paid_$i"}, '$form->{"datepaid_$i"}',
+                 '$form->{"source_$i"}')|;
+      $dbh->do($query) || $form->dberror($query);
+
+      
+      $exchangerate = 0;
+      
+      if ($form->{currency} eq $form->{defaultcurrency}) {
+       $form->{"exchangerate_$i"} = 1;
+      } else {
+       $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'buy');
+       
+       $form->{"exchangerate_$i"} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{"exchangerate_$i"});
+      }
+      
+      
+      # exchangerate difference
+      $form->{fx}{$accno}{$form->{"datepaid_$i"}} += $form->{"paid_$i"} * ($form->{"exchangerate_$i"} - 1) + $diff;
+
+      
+      # gain/loss
+      $amount = $form->{"paid_$i"} * $form->{exchangerate} - $form->{"paid_$i"} * $form->{"exchangerate_$i"};
+      if ($amount > 0) {
+       $form->{fx}{$form->{fxgain_accno}}{$form->{"datepaid_$i"}} += $amount;
+      } else {
+       $form->{fx}{$form->{fxloss_accno}}{$form->{"datepaid_$i"}} += $amount;
+      }
+
+      $diff = 0;
+
+      # update exchange rate
+      if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
+       $form->update_exchangerate($dbh, $form->{currency}, $form->{"datepaid_$i"}, $form->{"exchangerate_$i"}, 0);
+      }
+    }
+  }
+
+  
+  # record exchange rate differences and gains/losses
+  foreach my $accno (keys %{$form->{fx}}) {
+    foreach my $transdate (keys %{ $form->{fx}{$accno} }) {
+      if (($form->{fx}{$accno}{$transdate} = $form->round_amount($form->{fx}{$accno}{$transdate}, 2)) != 0) {
+
+       $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+                   transdate, cleared, fx_transaction)
+                   VALUES ($form->{id},
+                          (SELECT id FROM chart
+                           WHERE accno = '$accno'),
+                   $form->{fx}{$accno}{$transdate}, '$transdate', '0', '1')|;
+       $dbh->do($query) || $form->dberror($query);
+      }
+    }
+  }
+
+  $amount = $netamount + $tax;
+  
+  # set values which could be empty to 0
+  $form->{terms} *= 1;
+  $form->{taxincluded} *= 1;
+  my $datepaid = ($form->{paid}) ? qq|'$form->{datepaid}'| : "NULL";
+  my $duedate = ($form->{duedate}) ? qq|'$form->{duedate}'| : "NULL";
+
+  # fill in subject if there is none
+  $form->{subject} = qq|$form->{label} $form->{invnumber}| unless $form->{subject};
+  # if there is a message stuff it into the notes
+  my $cc = "Cc: $form->{cc}\\r\n" if $form->{cc};
+  my $bcc = "Bcc: $form->{bcc}\\r\n" if $form->{bcc};
+  $form->{notes} .= qq|\r
+\r
+[email]\r
+To: $form->{email}\r
+$cc${bcc}Subject: $form->{subject}\r
+\r
+Message: $form->{message}\r| if $form->{message};
+
+  # save AR record
+  $query = qq|UPDATE ar set
+              invnumber = '$form->{invnumber}',
+             ordnumber = '$form->{ordnumber}',
+              transdate = '$form->{invdate}',
+              customer_id = $form->{customer_id},
+              amount = $amount,
+              netamount = $netamount,
+              paid = $form->{paid},
+             datepaid = $datepaid,
+             duedate = $duedate,
+             invoice = '1',
+             shippingpoint = '$form->{shippingpoint}',
+             terms = $form->{terms},
+             notes = '$form->{notes}',
+             taxincluded = '$form->{taxincluded}',
+             curr = '$form->{currency}'
+              WHERE id = $form->{id}
+             |;
+  $dbh->do($query) || $form->dberror($query);
+
+  # add shipto
+  $form->{name} = $form->{customer};
+  $form->{name} =~ s/--$form->{customer_id}//;
+  $form->add_shipto($dbh, $form->{id});
+
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+  
+}
+
+
+sub process_assembly {
+  my ($dbh, $form, $id, $totalqty) = @_;
+
+  my $query = qq|SELECT a.parts_id, a.qty, p.assembly,
+                 p.partnumber, p.description, p.unit,
+                 p.inventory_accno_id, p.income_accno_id,
+                p.expense_accno_id
+                 FROM assembly a, parts p
+                WHERE a.parts_id = p.id
+                AND a.id = $id|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+    my $allocated = 0;
+    
+    $ref->{inventory_accno_id} *= 1;
+    $ref->{expense_accno_id} *= 1;
+
+    map { $ref->{$_} =~ s/'/''/g } (qw(partnumber description unit));
+    
+    # multiply by number of assemblies
+    $ref->{qty} *= $totalqty;
+    
+    if ($ref->{assembly}) {
+      &process_assembly($dbh, $form, $ref->{parts_id}, $ref->{qty});
+      next;
+    } else {
+      if ($ref->{inventory_accno_id}) {
+       $allocated = &cogs($dbh, $form, $ref->{parts_id}, $ref->{qty});
+      }
+    }
+
+    # save detail record for individual assembly item in invoice table
+    $query = qq|INSERT INTO invoice (trans_id, description, parts_id, qty,
+                sellprice, fxsellprice, allocated, assemblyitem, unit)
+               VALUES
+               ($form->{id}, '$ref->{description}',
+               $ref->{parts_id}, $ref->{qty}, 0, 0, $allocated, 't',
+               '$ref->{unit}')|;
+    $dbh->do($query) || $form->dberror($query);
+        
+  }
+
+  $sth->finish;
+
+}
+
+
+sub cogs {
+  my ($dbh, $form, $id, $totalqty) = @_;
+    
+  my $query = qq|SELECT i.id, i.trans_id, i.qty, i.allocated, i.sellprice,
+                        (SELECT c.accno FROM chart c
+                        WHERE p.inventory_accno_id = c.id)
+                        AS inventory_accno,
+                       (SELECT c.accno FROM chart c
+                        WHERE p.expense_accno_id = c.id)
+                        AS expense_accno
+                 FROM invoice i, parts p
+                 WHERE i.parts_id = p.id
+                 AND i.parts_id = $id
+                 AND (i.qty + i.allocated) < 0
+                 ORDER BY trans_id|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $allocated = 0;
+  my $qty;
+  
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    if (($qty = (($ref->{qty} * -1) - $ref->{allocated})) > $totalqty) {
+      $qty = $totalqty;
+    }
+    
+    $form->update_balance($dbh,
+                         "invoice",
+                         "allocated",
+                         qq|id = $ref->{id}|,
+                         $qty);
+
+    # total expenses and inventory
+    # sellprice is the cost of the item
+    $linetotal = $form->round_amount($ref->{sellprice} * $qty, 2);
+    
+    # add to expense
+    $form->{amount}{$form->{id}}{$ref->{expense_accno}} += -$linetotal;
+
+    # deduct inventory
+    $form->{amount}{$form->{id}}{$ref->{inventory_accno}} -= -$linetotal;
+
+    # add allocated
+    $allocated += -$qty;
+    
+    last if (($totalqty -= $qty) <= 0);
+  }
+
+  $sth->finish;
+
+  $allocated;
+  
+}
+
+
+
+sub reverse_invoice {
+  my ($dbh, $form) = @_;
+  
+  # reverse inventory items
+  my $query = qq|SELECT i.id, i.parts_id, i.qty, i.assemblyitem, p.assembly,
+                p.inventory_accno_id
+                 FROM invoice i, parts p
+                WHERE i.parts_id = p.id
+                AND i.trans_id = $form->{id}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+    if ($ref->{inventory_accno_id} || $ref->{assembly}) {
+
+      # if the invoice item is not an assemblyitem adjust parts onhand
+      unless ($ref->{assemblyitem}) {
+       # adjust onhand in parts table
+       $form->update_balance($dbh,
+                             "parts",
+                             "onhand",
+                             qq|id = $ref->{parts_id}|,
+                             $ref->{qty});
+      }
+
+      # loop if it is an assembly
+      next if ($ref->{assembly});
+      
+      # de-allocated purchases
+      $query = qq|SELECT id, trans_id, allocated
+                  FROM invoice
+                 WHERE parts_id = $ref->{parts_id}
+                 AND allocated > 0
+                 ORDER BY trans_id DESC|;
+      my $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+
+      while (my $inhref = $sth->fetchrow_hashref(NAME_lc)) {
+       $qty = $ref->{qty};
+       if (($ref->{qty} - $inhref->{allocated}) > 0) {
+         $qty = $inhref->{allocated};
+       }
+       
+       # update invoice
+       $form->update_balance($dbh,
+                             "invoice",
+                             "allocated",
+                             qq|id = $inhref->{id}|,
+                             $qty * -1);
+
+        last if (($ref->{qty} -= $qty) <= 0);
+      }
+      $sth->finish;
+    }
+  }
+  
+  $sth->finish;
+  
+  # delete acc_trans
+  $query = qq|DELETE FROM acc_trans
+              WHERE trans_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+  # delete invoice entries
+  $query = qq|DELETE FROM invoice
+              WHERE trans_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  $query = qq|DELETE FROM shipto
+              WHERE trans_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+}
+
+
+
+sub delete_invoice {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  # check for other foreign currency transactions
+  $form->delete_exchangerate($dbh) if ($form->{currency} ne $form->{defaultcurrency});
+  &reverse_invoice($dbh, $form);
+  
+  # delete AR record
+  my $query = qq|DELETE FROM ar
+                 WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+  
+  $rc;
+  
+}
+
+
+
+sub retrieve_invoice {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my $query;
+  
+  if ($form->{id}) {
+    # get default accounts and last invoice number
+    $query = qq|SELECT (SELECT c.accno FROM chart c
+                        WHERE d.inventory_accno_id = c.id) AS inventory_accno,
+                      (SELECT c.accno FROM chart c
+                       WHERE d.income_accno_id = c.id) AS income_accno,
+                      (SELECT c.accno FROM chart c
+                       WHERE d.expense_accno_id = c.id) AS expense_accno,
+                      (SELECT c.accno FROM chart c
+                       WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
+                      (SELECT c.accno FROM chart c
+                       WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
+                d.curr AS currencies
+               FROM defaults d|;
+  } else {
+    $query = qq|SELECT (SELECT c.accno FROM chart c
+                        WHERE d.inventory_accno_id = c.id) AS inventory_accno,
+                      (SELECT c.accno FROM chart c
+                       WHERE d.income_accno_id = c.id) AS income_accno,
+                      (SELECT c.accno FROM chart c
+                       WHERE d.expense_accno_id = c.id) AS expense_accno,
+                      (SELECT c.accno FROM chart c
+                       WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
+                      (SELECT c.accno FROM chart c
+                       WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
+                d.invnumber, d.curr AS currencies, current_date AS invdate
+                FROM defaults d|;
+  }
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $ref = $sth->fetchrow_hashref(NAME_lc);
+  map { $form->{$_} = $ref->{$_} } keys %$ref;
+  $sth->finish;
+
+  
+  if ($form->{id}) {
+    
+    # retrieve invoice
+    $query = qq|SELECT a.invnumber, a.ordnumber, a.transdate AS invdate, a.paid,
+                a.shippingpoint, a.terms, a.notes, a.duedate, a.taxincluded,
+               a.curr AS currency, (SELECT e.name FROM employee e
+                                    WHERE e.id = a.employee_id) AS employee
+               FROM ar a
+               WHERE a.id = $form->{id}|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    $ref = $sth->fetchrow_hashref(NAME_lc);
+    map { $form->{$_} = $ref->{$_} } keys %$ref;
+    $sth->finish;
+
+    $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{invdate}, "buy");
+
+    # get shipto
+    $query = qq|SELECT * FROM shipto
+                WHERE trans_id = $form->{id}|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    $ref = $sth->fetchrow_hashref(NAME_lc);
+    map { $form->{$_} = $ref->{$_} } keys %$ref;
+    $sth->finish;
+    
+    # retrieve individual items
+    $query = qq|SELECT c1.accno AS inventory_accno,
+                       c2.accno AS income_accno,
+                      c3.accno AS expense_accno,
+                i.description, i.qty, i.fxsellprice AS sellprice,
+               i.discount, i.parts_id AS id, i.unit, i.deliverydate,
+               pr.projectnumber,
+                i.project_id,
+               p.partnumber, p.assembly, p.bin,
+               pg.partsgroup
+               FROM invoice i
+               JOIN parts p ON (i.parts_id = p.id)
+               LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
+               LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
+               LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
+               LEFT JOIN project pr ON (i.project_id = pr.id)
+               LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+               WHERE i.trans_id = $form->{id}
+               AND NOT i.assemblyitem = '1'
+               ORDER BY i.id|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+      # get taxes
+      $query = qq|SELECT c.accno
+                  FROM chart c, partstax pt
+                 WHERE pt.chart_id = c.id
+                 AND pt.parts_id = $ref->{id}|;
+      my $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+
+      $ref->{taxaccounts} = "";
+      my $taxrate = 0;
+      
+      while (my $ptref = $sth->fetchrow_hashref(NAME_lc)) {
+       $ref->{taxaccounts} .= "$ptref->{accno} ";
+       $taxrate += $form->{"$ptref->{accno}_rate"};
+      }
+      $sth->finish;
+      chop $ref->{taxaccounts};
+
+      push @{ $form->{invoice_details} }, $ref;
+    }
+    $sth->finish;
+
+  } else {
+
+    $form->{shippingpoint} = $myconfig->{shippingpoint} unless $form->{shippingpoint};
+
+    # up invoice number by 1
+    $form->{invnumber}++;
+
+    # save the new number
+    $query = qq|UPDATE defaults
+                SET invnumber = '$form->{invnumber}'|;
+    $dbh->do($query) || $form->dberror($query);
+
+    $form->get_employee($dbh);
+
+  }
+
+
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+  
+  $rc;
+
+}
+
+
+sub get_customer {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $dateformat = $myconfig->{dateformat};
+  $dateformat .= "yy" if $myconfig->{dateformat} !~ /^y/;
+
+  my $duedate = ($form->{invdate}) ? "to_date('$form->{invdate}', '$dateformat')" : "current_date";
+
+  $form->{customer_id} *= 1;
+  # get customer
+  my $query = qq|SELECT c.name AS customer, c.discount, c.creditlimit, c.terms,
+                 c.email, c.cc, c.bcc, c.taxincluded,
+                c.addr1, c.addr2, c.addr3, c.addr4,
+                $duedate + c.terms AS duedate
+                 FROM customer c
+                WHERE c.id = $form->{customer_id}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  $ref = $sth->fetchrow_hashref(NAME_lc);
+
+  map { $form->{$_} = $ref->{$_} } keys %$ref;
+  $sth->finish;
+  
+  $form->{creditremaining} = $form->{creditlimit};
+  $query = qq|SELECT SUM(amount - paid)
+             FROM ar
+             WHERE customer_id = $form->{customer_id}|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  ($form->{creditremaining}) -= $sth->fetchrow_array;
+
+  $sth->finish;
+  
+  $query = qq|SELECT o.amount,
+                (SELECT e.buy FROM exchangerate e
+                WHERE e.curr = o.curr
+                AND e.transdate = o.transdate)
+             FROM oe o
+             WHERE o.customer_id = $form->{customer_id}
+             AND o.closed = '0'|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my ($amount, $exch) = $sth->fetchrow_array) {
+    $exch = 1 unless $exch;
+    $form->{creditremaining} -= $amount * $exch;
+  }
+  $sth->finish;
+
+
+  # get shipto if we did not converted an order or invoice
+  if (!$form->{shipto}) {
+    map { delete $form->{$_} } qw(shiptoname shiptoaddr1 shiptoaddr2 shiptoaddr3 shiptoaddr4 shiptocontact shiptophone shiptofax shiptoemail);
+
+    $query = qq|SELECT * FROM shipto
+                WHERE trans_id = $form->{customer_id}|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    $ref = $sth->fetchrow_hashref(NAME_lc);
+    map { $form->{$_} = $ref->{$_} } keys %$ref;
+    $sth->finish;
+  }
+      
+  # get taxes we charge for this customer
+  $query = qq|SELECT c.accno
+              FROM chart c, customertax ct
+             WHERE ct.chart_id = c.id
+             AND ct.customer_id = $form->{customer_id}|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+  
+  my $customertax = ();
+  while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+    $customertax{$ref->{accno}} = 1;
+  }
+  $sth->finish;
+    
+  # get tax rates and description
+  $query = qq|SELECT c.accno, c.description, t.rate, t.taxnumber
+             FROM chart c, tax t
+             WHERE c.id = t.chart_id
+             AND c.link LIKE '%CT_tax%'
+             ORDER BY accno|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  $form->{taxaccounts} = "";
+  while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+    if ($customertax{$ref->{accno}}) {
+      $form->{"$ref->{accno}_rate"} = $ref->{rate};
+      $form->{"$ref->{accno}_description"} = $ref->{description};
+      $form->{"$ref->{accno}_taxnumber"} = $ref->{taxnumber};
+      $form->{taxaccounts} .= "$ref->{accno} ";
+    }
+  }
+  $sth->finish;
+  chop $form->{taxaccounts};
+
+  # setup last accounts used for this customer
+  if (!$form->{id} && $form->{type} !~ /_order/) {
+    $query = qq|SELECT c.accno, c.description, c.link, c.category
+                FROM chart c
+               JOIN acc_trans ac ON (ac.chart_id = c.id)
+               JOIN ar a ON (a.id = ac.trans_id)
+               WHERE a.customer_id = $form->{customer_id}
+               AND NOT (c.link LIKE '%_tax%' OR c.link LIKE '%_paid%')
+               AND a.id IN (SELECT max(id) FROM ar
+                            WHERE customer_id = $form->{customer_id})|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    my $i = 0;
+    while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+      if ($ref->{category} eq 'I') {
+       $i++;
+       $form->{"AR_amount_$i"} = "$ref->{accno}--$ref->{description}";
+      }
+      if ($ref->{category} eq 'A') {
+       $form->{AR} = $form->{AR_1} = "$ref->{accno}--$ref->{description}";
+      }
+    }
+    $sth->finish;
+    $form->{rowcount} = $i if ($i && !$form->{type});
+  }
+  
+  $dbh->disconnect;
+
+}
+
+
+
+sub retrieve_item {
+  my ($self, $myconfig, $form) = @_;
+
+  my $i = $form->{rowcount};
+  my $var;
+  my $where = "NOT obsolete = '1'";
+
+  if ($form->{"partnumber_$i"}) {
+    $var = $form->like(lc $form->{"partnumber_$i"});
+    $where .= " AND lower(p.partnumber) LIKE '$var'";
+  }
+  if ($form->{"description_$i"}) {
+    $var = $form->like(lc $form->{"description_$i"});
+    $where .= " AND lower(p.description) LIKE '$var'";
+  }
+
+  if ($form->{"partsgroup_$i"}) {
+    $var = $form->like(lc $form->{"partsgroup_$i"});
+    $where .= " AND lower(pg.partsgroup) LIKE '$var'";
+  }
+
+  if ($form->{"description_$i"}) {
+    $where .= " ORDER BY description";
+  } else {
+    $where .= " ORDER BY partnumber";
+  }
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT p.id, p.partnumber, p.description, p.sellprice,
+                        p.listprice,
+                       c1.accno AS inventory_accno,
+                       c2.accno AS income_accno,
+                       c3.accno AS expense_accno,
+                p.unit, p.assembly, p.bin, p.onhand, p.makemodel,
+                pg.partsgroup
+                 FROM parts p
+                LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
+                LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
+                LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
+                LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
+                WHERE $where|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+    # get taxes for part
+    $query = qq|SELECT c.accno
+                FROM chart c
+               JOIN partstax pt ON (c.id = pt.chart_id)
+               WHERE pt.parts_id = $ref->{id}|;
+    my $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    $ref->{taxaccounts} = "";
+    while (my $ptref = $sth->fetchrow_hashref(NAME_lc)) {
+      $ref->{taxaccounts} .= "$ptref->{accno} ";
+    }
+    $sth->finish;
+    chop $ref->{taxaccounts};
+
+    # get makemodel
+    if ($ref->{makemodel}) {
+      $query = qq|SELECT name
+                 FROM makemodel
+                 WHERE parts_id = $ref->{id}|;
+      $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+      
+      $ref->{makemodel} = "";
+      while (my $ptref = $sth->fetchrow_hashref(NAME_lc)) {
+       $ref->{makemodel} .= "$ptref->{name}:";
+      }
+      $sth->finish;
+      chop $ref->{makemodel};
+    }
+
+    push @{ $form->{item_list} }, $ref;
+
+  }
+  
+  $sth->finish;
+  $dbh->disconnect;
+  
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/Inifile.pm b/sql-ledger/SL/Inifile.pm
new file mode 100644 (file)
index 0000000..e9de47a
--- /dev/null
@@ -0,0 +1,87 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#=====================================================================
+#
+# routines to retrieve / manipulate win ini style files
+# ORDER is used to keep the elements in the order they appear in .ini
+#
+#=====================================================================
+
+package Inifile;
+
+
+sub new {
+  my ($type, $file, $level) = @_;
+  
+  my $id = "";
+  my $skip;
+  
+  $type = ref($self) || $self;
+  
+  open FH, "$file" or Form->error("$file : $!");
+
+  while (<FH>) {
+    next if /^(#|;|\s)/;
+    last if /^\./;
+
+    chop;
+
+    # strip comments
+    s/\s*(#|;).*//g;
+    
+    # remove any trailing whitespace
+    s/^\s*(.*?)\s*$/$1/;
+
+    if (/^\[/) {
+      s/(\[|\])//g;
+
+      $id = $_;
+
+      # if there is a level skip
+      if ($skip = ($id !~ /^$level/)) {
+       next;
+      }
+
+      push @{$self->{ORDER}}, $_;
+      
+      next;
+      
+    }
+
+    if (!$skip) {
+      # add key=value to $id
+      my ($key, $value) = split /=/, $_, 2;
+      
+      $self->{$id}{$key} = $value;
+    }
+
+  }
+  close FH;
+  
+  bless $self, $type;
+  
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/Mailer.pm b/sql-ledger/SL/Mailer.pm
new file mode 100644 (file)
index 0000000..934ad36
--- /dev/null
@@ -0,0 +1,147 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+# Contributors: 
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+
+package Mailer;
+
+sub new {
+  my ($type) = @_;
+  my $self = {};
+
+  bless $self, $type;
+}
+
+
+sub send {
+  my ($self, $out) = @_;
+
+  my $boundary = time;
+  $boundary = "SL-$self->{version}-$boundary";
+  my $domain = $self->{from};
+  $domain =~ s/(.*?\@|>)//g;
+  my $msgid = "$boundary\@$domain";
+  
+  $self->{charset} = "ISO-8859-1" unless $self->{charset};
+  
+  if ($out) {
+    open(OUT, $out) or return "$out : $!";
+  } else {
+    open(OUT, ">-") or return "STDOUT : $!";
+  }
+
+  $self->{contenttype} = "text/plain" unless $self->{contenttype};
+  
+  my ($cc, $bcc);
+  $cc = "Cc: $self->{cc}\n" if $self->{cc};
+  $bcc = "Bcc: $self->{bcc}\n" if $self->{bcc};
+  
+  print OUT qq|From: $self->{from}
+To: $self->{to}
+${cc}${bcc}Subject: $self->{subject}
+Message-ID: <$msgid>
+X-Mailer: SQL-Ledger $self->{version}
+MIME-Version: 1.0
+|;
+
+
+  if ($self->{attachments}) {
+    print OUT qq|Content-Type: multipart/mixed; boundary="$boundary"
+
+--${boundary}
+Content-Type: $self->{contenttype}; charset="$self->{charset}"
+
+$self->{message}
+
+|;
+
+    foreach my $attachment (@{ $self->{attachments} }) {
+      
+      my $application = ($attachment =~ /(^\w+$)|\.(html|text|txt|sql)$/) ? "text" : "application";
+      
+      open(IN, $attachment);
+      if ($?) {
+       close(OUT);
+       return "$attachment : $!";
+      }
+      
+      my $filename = $attachment;
+      # strip path
+      $filename =~ s/(.*\/|$self->{fileid})//g;
+      
+      print OUT qq|--${boundary}
+Content-Type: $application/$self->{format}; name="$filename"; charset="$self->{charset}"
+Content-Transfer-Encoding: BASE64
+Content-Disposition: attachment; filename="$filename"\n\n|;
+
+      my $msg = "";
+      while (<IN>) {;
+        $msg .= $_;
+      }
+      print OUT &encode_base64($msg);
+
+      close(IN);
+      
+    }
+    print OUT qq|--${boundary}--\n|;
+
+  } else {
+    print OUT qq|Content-Type: $self->{contenttype}; charset="$self->{charset}"
+
+$self->{message}
+|;
+  }
+
+  close(OUT);
+
+  return "";
+  
+}
+
+
+sub encode_base64 ($;$) {
+
+  # this code is from the MIME-Base64-2.12 package
+  # Copyright 1995-1999,2001 Gisle Aas <gisle@ActiveState.com>
+
+  my $res = "";
+  my $eol = $_[1];
+  $eol = "\n" unless defined $eol;
+  pos($_[0]) = 0;                          # ensure start at the beginning
+
+  $res = join '', map( pack('u',$_)=~ /^.(\S*)/, ($_[0]=~/(.{1,45})/gs));
+
+  $res =~ tr|` -_|AA-Za-z0-9+/|;               # `# help emacs
+  # fix padding at the end
+  my $padding = (3 - length($_[0]) % 3) % 3;
+  $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
+  # break encoded string into lines of no more than 60 characters each
+  if (length $eol) {
+    $res =~ s/(.{1,60})/$1$eol/g;
+  }
+  return $res;
+  
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/Menu.pm b/sql-ledger/SL/Menu.pm
new file mode 100644 (file)
index 0000000..661d354
--- /dev/null
@@ -0,0 +1,117 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#=====================================================================
+#
+# routines for menu items
+#
+#=====================================================================
+
+package Menu;
+
+
+sub new {
+  my ($type, $menufile, $level) = @_;
+
+  use SL::Inifile;
+  my $self = Inifile->new($menufile, $level);
+  
+  bless $self, $type;
+
+}
+
+
+sub menuitem {
+  my ($self, $myconfig, $form, $item) = @_;
+
+  my $module = $form->{script};
+  my $action = "section_menu";
+  my $target = "";
+
+  if ($self->{$item}{module}) {
+    $module = $self->{$item}{module};
+  }
+  if ($self->{$item}{action}) {
+    $action = $self->{$item}{action};
+  }
+  if ($self->{$item}{target}) {
+    $target = $self->{$item}{target};
+  }
+
+  my $level = $form->escape($item);
+  my $str = qq|<a href=$module?path=$form->{path}&action=$action&level=$level&login=$form->{login}&password=$form->{password}|;
+  my @vars = qw(module action target href);
+  
+  if ($self->{$item}{href}) {
+    $str = qq|<a href=$self->{$item}{href}|;
+    @vars = qw(module target href);
+  }
+
+  map { delete $self->{$item}{$_} } @vars;
+  
+  
+  # add other params
+  foreach my $key (keys %{ $self->{$item} }) {
+    $str .= "&".$form->escape($key,1)."=";
+    ($value, $conf) = split /=/, $self->{$item}{$key}, 2;
+    $value = $myconfig->{$value}."/$conf" if ($conf);
+    $str .= $form->escape($value, 1);
+  }
+
+  if ($target) {
+    $str .= qq| target=$target|;
+  }
+
+  $str .= ">";
+  
+}
+
+
+sub access_control {
+  my ($self, $myconfig, $menulevel) = @_;
+  
+  my @menu = ();
+
+  if ($menulevel eq "") {
+    @menu = grep { !/--/ } @{ $self->{ORDER} };
+  } else {
+    @menu = grep { /^${menulevel}--/ } @{ $self->{ORDER} };
+  }
+
+  my @a = split /;/, $myconfig->{acs};
+  my $excl = ();
+
+  # remove --AR, --AP from array
+  grep { ($a, $b) = split /--/; s/--$a$//; } @a;
+
+  map { $excl{$_} = 1 } @a;
+
+  @a = ();
+  map { push @a, $_ unless $excl{$_} } (@menu);
+
+  @a;
+
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/Num2text.pm b/sql-ledger/SL/Num2text.pm
new file mode 100644 (file)
index 0000000..f09121c
--- /dev/null
@@ -0,0 +1,162 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#=====================================================================
+#
+# this is the default code for the Check package
+#
+#=====================================================================
+
+
+sub init {
+  my $self = shift;
+
+  %{ $self->{numbername} } =
+                   (0 => 'Zero',
+                    1 => 'One',
+                    2 => 'Two',
+                   3 => 'Three',
+                   4 => 'Four',
+                   5 => 'Five',
+                   6 => 'Six',
+                   7 => 'Seven',
+                   8 => 'Eight',
+                   9 => 'Nine',
+                  10 => 'Ten',
+                  11 => 'Eleven',
+                  12 => 'Twelve',
+                  13 => 'Thirteen',
+                  14 => 'Fourteen',
+                  15 => 'Fifteen',
+                  16 => 'Sixteen',
+                  17 => 'Seventeen',
+                  18 => 'Eighteen',
+                  19 => 'Nineteen',
+                  20 => 'Twenty',
+                  30 => 'Thirty',
+                  40 => 'Forty',
+                  50 => 'Fifty',
+                  60 => 'Sixty',
+                  70 => 'Seventy',
+                  80 => 'Eighty',
+                  90 => 'Ninety',
+                10**2 => 'Hundred',
+                10**3 => 'Thousand',
+               10**6 => 'Million',
+               10**9 => 'Billion',
+              10**12 => 'Trillion',
+               );
+
+}
+
+
+sub num2text {
+  my ($self, $amount) = @_;
+
+  return $self->{numbername}{0} unless $amount;
+
+  my @textnumber = ();
+
+  # split amount into chunks of 3
+  my @num = reverse split //, $amount;
+  my @numblock = ();
+  my @a;
+  my $i;
+
+  while (@num) {
+    @a = ();
+    for (1 .. 3) {
+      push @a, shift @num;
+    }
+    push @numblock, join / /, reverse @a;
+  }
+    
+  while (@numblock) {
+
+    $i = $#numblock;
+    @num = split //, $numblock[$i];
+    
+    if ($numblock[$i] == 0) {
+      pop @numblock;
+      next;
+    }
+   
+    if ($numblock[$i] > 99) {
+      # the one from hundreds
+      push @textnumber, $self->{numbername}{$num[0]};
+     
+      # add hundred designation
+      push @textnumber, $self->{numbername}{10**2};
+
+      # reduce numblock
+      $numblock[$i] -= $num[0] * 100;
+      
+    }
+    
+    $numblock[$i] *= 1;
+    
+    if ($numblock[$i] > 9) {
+      # tens
+      push @textnumber, $self->format_ten($numblock[$i]);
+    } elsif ($numblock[$i] > 0) {
+      # ones
+      push @textnumber, $self->{numbername}{$numblock[$i]};
+    }
+    
+    # add thousand, million
+    if ($i) {
+      $num = 10**($i * 3);
+      push @textnumber, $self->{numbername}{$num};
+    }
+      
+    pop @numblock;
+    
+  }
+
+  join ' ', @textnumber;
+
+}
+
+
+sub format_ten {
+  my ($self, $amount) = @_;
+  
+  my $textnumber = "";
+  my @num = split //, $amount;
+
+  if ($amount > 20) {
+    $textnumber = $self->{numbername}{$num[0]*10};
+    $amount = $num[1];
+  } else {
+    $textnumber = $self->{numbername}{$amount};
+    $amount = 0;
+  }
+
+  $textnumber .= " ".$self->{numbername}{$amount} if $amount;
+
+  $textnumber;
+  
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/OE.pm b/sql-ledger/SL/OE.pm
new file mode 100644 (file)
index 0000000..a742ca7
--- /dev/null
@@ -0,0 +1,674 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Order entry module
+#
+#======================================================================
+
+package OE;
+
+
+sub transactions {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  my $query;
+
+  my $rate = ($form->{vc} eq 'customer') ? 'buy' : 'sell';
+  
+  my $query = qq|SELECT o.id, o.ordnumber, o.transdate, o.reqdate,
+                 o.amount, ct.name, o.netamount, o.$form->{vc}_id,
+                (SELECT $rate FROM exchangerate ex
+                 WHERE ex.curr = o.curr
+                 AND ex.transdate = o.transdate) AS exchangerate,
+                o.closed
+                FROM oe o, $form->{vc} ct
+                WHERE o.$form->{vc}_id = ct.id|;
+             
+  my $ordnumber = $form->like(lc $form->{ordnumber});
+  
+  if ($form->{"$form->{vc}_id"}) {
+    $query .= qq| AND o.$form->{vc}_id = $form->{"$form->{vc}_id"}|;
+  } else {
+    if ($form->{$form->{vc}}) {
+      my $name = $form->like(lc $form->{$form->{vc}});
+      $query .= " AND lower(name) LIKE '$name'";
+    }
+  }
+  unless ($form->{open} && $form->{closed}) {
+    $query .= ($form->{open}) ? " AND o.closed = '0'" : " AND o.closed = '1'";
+  }
+
+  my $sortorder = join ', ', $form->sort_columns(qw(transdate ordnumber name));
+  $sortorder = $form->{sort} unless $sortorder;
+  
+  $query .= " AND lower(ordnumber) LIKE '$ordnumber'" if $form->{ordnumber};
+  $query .= " AND transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+  $query .= " AND transdate <= '$form->{transdateto}'" if $form->{transdateto};
+  $query .= " ORDER by $sortorder";
+
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $oe = $sth->fetchrow_hashref(NAME_lc)) {
+    $oe->{exchangerate} = 1 unless $oe->{exchangerate};
+    push @{ $form->{OE} }, $oe;
+  }
+
+  $sth->finish;
+  $dbh->disconnect;
+  
+}
+
+
+sub save_order {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database, turn off autocommit
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my ($query, $sth);
+  my $exchangerate = 0;
+
+  if ($form->{id}) {
+
+    $query = qq|DELETE FROM orderitems
+                WHERE trans_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+
+    $query = qq|DELETE FROM shipto
+                WHERE trans_id = $form->{id}|;
+    $dbh->do($query) || $form->dberror($query);
+
+  } else {
+    my $uid = time;
+    $uid .= $form->{login};
+    
+    $query = qq|INSERT INTO oe (ordnumber, employee_id)
+                VALUES ('$uid', (SELECT id FROM employee
+                                WHERE login = '$form->{login}') )|;
+    $dbh->do($query) || $form->dberror($query);
+   
+    $query = qq|SELECT id FROM oe
+                WHERE ordnumber = '$uid'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    ($form->{id}) = $sth->fetchrow_array;
+    $sth->finish;
+  }
+
+  map { $form->{$_} =~ s/'/''/g } qw(ordnumber shippingpoint notes message);
+  
+  my ($amount, $linetotal, $discount, $project_id, $reqdate);
+  my ($taxrate, $taxamount, $fxsellprice);
+  my %taxbase = ();
+  my %taxaccounts = ();
+  my ($netamount, $tax) = (0, 0);
+
+  for my $i (1 .. $form->{rowcount}) {
+    
+    $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
+    
+    if ($form->{"qty_$i"} != 0) {
+      
+      map { $form->{"${_}_$i"} =~ s/'/''/g } qw(partnumber description unit);
+      
+      # set values to 0 if nothing entered
+      $form->{"discount_$i"} = $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100;
+
+      $form->{"sellprice_$i"} = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
+      $fxsellprice = $form->{"sellprice_$i"};
+
+      my ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
+      $dec = length $dec;
+      my $decimalplaces = ($dec > 2) ? $dec : 2;
+      
+      $discount = $form->round_amount($form->{"sellprice_$i"} * $form->{"discount_$i"}, $decimalplaces);
+      $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} - $discount, $decimalplaces);
+      
+      $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
+      $taxrate = 0;
+      map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{"taxaccounts_$i"};
+
+      if ($form->{taxincluded}) {
+       $taxamount = $linetotal * $taxrate / (1 + $taxrate);
+       $taxbase = $linetotal - $taxamount;
+       # we are not keeping a natural price, do not round
+       $form->{"sellprice_$i"} = $form->{"sellprice_$i"} * (1 / (1 + $taxrate));
+      } else {
+       $taxamount = $linetotal * $taxrate;
+       $taxbase = $linetotal;
+      }
+
+      if ($taxamount != 0) {
+       foreach my $item (split / /, $form->{"taxaccounts_$i"}) {
+         $taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
+         $taxbase{$item} += $taxbase;
+       }
+      }
+      
+      $netamount += $form->{"sellprice_$i"} * $form->{"qty_$i"};
+      
+      $project_id = 'NULL';
+      if ($form->{"project_id_$i"}) {
+       $project_id = $form->{"project_id_$i"};
+      }
+      $reqdate = ($form->{"reqdate_$i"}) ? qq|'$form->{"reqdate_$i"}'| : "NULL";
+      
+      # save detail record in orderitems table
+      $query = qq|INSERT INTO orderitems
+                (trans_id, parts_id, description, qty, sellprice, discount,
+                 unit, reqdate, project_id) VALUES (
+                 $form->{id}, $form->{"id_$i"}, '$form->{"description_$i"}',
+                 $form->{"qty_$i"}, $fxsellprice, $form->{"discount_$i"},
+                 '$form->{"unit_$i"}', $reqdate, $project_id)|;
+      $dbh->do($query) || $form->dberror($query);
+
+      $form->{"sellprice_$i"} = $fxsellprice;
+      $form->{"discount_$i"} *= 100;
+    }
+  }
+
+
+  # set values which could be empty
+  map { $form->{$_} *= 1 } qw(vendor_id customer_id taxincluded closed);
+
+  $reqdate = ($form->{reqdate}) ? qq|'$form->{reqdate}'| : "NULL";
+  
+  # add up the tax
+  foreach my $item (sort keys %taxaccounts) {
+    $taxamount = $form->round_amount($taxaccounts{$item}, 2);
+    $tax += $taxamount;
+  }
+  
+  $amount = $form->round_amount($netamount + $tax, 2);
+  $netamount = $form->round_amount($netamount, 2);
+
+  if ($form->{currency} eq $form->{defaultcurrency}) {
+    $form->{exchangerate} = 1;
+  } else {
+    $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, ($form->{vc} eq 'customer') ? 'buy' : 'sell');
+  }
+  
+  $form->{exchangerate} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{exchangerate});
+  
+  # fill in subject if there is none
+  $form->{subject} = qq|$form->{label} $form->{ordnumber}| unless $form->{subject};
+  # if there is a message stuff it into the notes
+  my $cc = "Cc: $form->{cc}\\r\n" if $form->{cc};
+  my $bcc = "Bcc: $form->{bcc}\\r\n" if $form->{bcc};
+  $form->{notes} .= qq|\r
+\r
+[email]\r
+To: $form->{email}\r
+$cc${bcc}Subject: $form->{subject}\r
+\r
+Message: $form->{message}\r| if $form->{message};
+  
+  # save OE record
+  $query = qq|UPDATE oe set
+             ordnumber = '$form->{ordnumber}',
+              transdate = '$form->{orddate}',
+              vendor_id = $form->{vendor_id},
+             customer_id = $form->{customer_id},
+              amount = $amount,
+              netamount = $netamount,
+             reqdate = $reqdate,
+             taxincluded = '$form->{taxincluded}',
+             shippingpoint = '$form->{shippingpoint}',
+             notes = '$form->{notes}',
+             curr = '$form->{currency}',
+             closed = '$form->{closed}'
+              WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  $form->{ordtotal} = $amount;
+
+  # add shipto
+  $form->{name} = $form->{$form->{vc}};
+  $form->{name} =~ s/--$form->{"$form->{vc}_id"}//;
+  $form->add_shipto($dbh, $form->{id});
+  
+  if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
+    if ($form->{vc} eq 'customer') {
+      $form->update_exchangerate($dbh, $form->{currency}, $form->{orddate}, $form->{exchangerate}, 0);
+    }
+    if ($form->{vc} eq 'vendor') {
+      $form->update_exchangerate($dbh, $form->{currency}, $form->{orddate}, 0, $form->{exchangerate});
+    }
+  }
+  
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+  
+}
+
+
+
+sub delete_order {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my $query;
+
+  # can't use $form->delete_exchangerate
+  if ($form->{currency} ne $form->{defaultcurrency}) {
+       $query = qq|SELECT transdate FROM acc_trans
+                  WHERE ar.id = trans_id
+                  AND ar.curr = '$form->{currency}'
+                  AND transdate = '$form->{orddate}'
+          UNION SELECT transdate FROM acc_trans
+                  WHERE ap.id = trans_id
+                  AND ap.curr = '$form->{currency}'
+                  AND transdate = '$form->{orddate}'|;
+    my $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+    
+    my ($transdate) = $sth->fetchrow_array;
+    $sth->finish;
+
+    if (!$transdate) {
+      $query = qq|DELETE FROM exchangerate
+                 WHERE curr = '$form->{currency}'
+                 AND transdate = '$form->{orddate}'|;
+      $dbh->do($query) || $self->dberror($query);
+    }
+  }
+             
+  
+  # delete OE record
+  $query = qq|DELETE FROM oe
+              WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  # delete individual entries
+  $query = qq|DELETE FROM orderitems
+              WHERE trans_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  $query = qq|DELETE FROM shipto
+              WHERE trans_id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+  
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+  
+}
+
+
+
+sub retrieve_order {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my $query;
+
+  if ($form->{id}) {
+    # get default accounts and last order number
+    $query = qq|SELECT (SELECT c.accno FROM chart c
+                        WHERE d.inventory_accno_id = c.id) AS inventory_accno,
+                       (SELECT c.accno FROM chart c
+                       WHERE d.income_accno_id = c.id) AS income_accno,
+                       (SELECT c.accno FROM chart c
+                       WHERE d.expense_accno_id = c.id) AS expense_accno,
+                       (SELECT c.accno FROM chart c
+                       WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
+                       (SELECT c.accno FROM chart c
+                       WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
+                d.curr AS currencies
+               FROM defaults d|;
+  } else {
+    my $ordnumber = ($form->{vc} eq 'customer') ? 'sonumber' : 'ponumber';
+    $query = qq|SELECT (SELECT c.accno FROM chart c
+                        WHERE d.inventory_accno_id = c.id) AS inventory_accno,
+                       (SELECT c.accno FROM chart c
+                       WHERE d.income_accno_id = c.id) AS income_accno,
+                       (SELECT c.accno FROM chart c
+                       WHERE d.expense_accno_id = c.id) AS expense_accno,
+                       (SELECT c.accno FROM chart c
+                       WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
+                       (SELECT c.accno FROM chart c
+                       WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
+                $ordnumber AS ordnumber, d.curr AS currencies,
+               current_date AS orddate, current_date AS reqdate
+               FROM defaults d|;
+  }
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $ref = $sth->fetchrow_hashref(NAME_lc);
+  map { $form->{$_} = $ref->{$_} } keys %$ref;
+  $sth->finish;
+
+  ($form->{currency}) = split /:/, $form->{currencies};
+  
+  if ($form->{id}) {
+    
+    # retrieve order
+    $query = qq|SELECT o.ordnumber, o.transdate AS orddate, o.reqdate,
+                o.taxincluded, o.shippingpoint, o.notes, o.curr AS currency,
+               (SELECT name FROM employee e
+                WHERE e.id = o.employee_id) AS employee,
+               o.$form->{vc}_id, cv.name AS $form->{vc}, o.amount AS invtotal,
+               o.closed, o.reqdate
+               FROM oe o, $form->{vc} cv
+               WHERE o.$form->{vc}_id = cv.id
+               AND o.id = $form->{id}|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    $ref = $sth->fetchrow_hashref(NAME_lc);
+    map { $form->{$_} = $ref->{$_} } keys %$ref;
+    $sth->finish;
+    
+   
+    $query = qq|SELECT * FROM shipto
+                WHERE trans_id = $form->{id}|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    $ref = $sth->fetchrow_hashref(NAME_lc);
+    map { $form->{$_} = $ref->{$_} } keys %$ref;
+    $sth->finish;
+    
+    my %oid = ( 'Pg'           => 'oid',
+                'Oracle'       => 'rowid',
+                'DB2'          => '' );
+
+    # retrieve individual items
+    $query = qq|SELECT c1.accno AS inventory_accno,
+                       c2.accno AS income_accno,
+                      c3.accno AS expense_accno,
+                p.partnumber, p.assembly, o.description, o.qty,
+               o.sellprice, o.parts_id AS id, o.unit, o.discount, p.bin,
+                o.reqdate, o.project_id,
+               pr.projectnumber,
+               pg.partsgroup
+               FROM orderitems o
+               JOIN parts p ON (o.parts_id = p.id)
+               LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
+               LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
+               LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
+               LEFT JOIN project pr ON (o.project_id = pr.id)
+               LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+               WHERE trans_id = $form->{id}
+                ORDER BY o.$oid{$myconfig->{dbdriver}}|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+      # get tax rates for part
+      $query = qq|SELECT c.accno
+                  FROM chart c, partstax pt
+                 WHERE pt.chart_id = c.id
+                 AND pt.parts_id = $ref->{id}|;
+      my $pth = $dbh->prepare($query);
+      $pth->execute || $form->dberror($query);
+
+      $ref->{taxaccounts} = "";
+      my $taxrate = 0;
+      
+      while (my $ptref = $pth->fetchrow_hashref(NAME_lc)) {
+        $ref->{taxaccounts} .= "$ptref->{accno} ";
+        $taxrate += $form->{"$ptref->{accno}_rate"};
+      }
+      $pth->finish;
+      chop $ref->{taxaccounts};
+
+      push @{ $form->{order_details} }, $ref;
+      
+    }
+    $sth->finish;
+
+  } else {
+
+    my $ordnumber = ($form->{vc} eq 'customer') ? 'sonumber' : 'ponumber';
+    # up order number by 1
+    $form->{ordnumber}++;
+
+    # save the new number
+    $query = qq|UPDATE defaults
+                SET $ordnumber = '$form->{ordnumber}'|;
+    $dbh->do($query) || $form->dberror($query);
+
+    $form->get_employee($dbh);
+    
+    # get last name used
+    $form->lastname_used($dbh, $myconfig, $form->{vc}) unless $form->{"$form->{vc}_id"};
+
+  }
+  
+  $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{orddate}, ($form->{vc} eq 'customer') ? "buy" : "sell");
+  
+  my $rc = $dbh->commit;
+  $dbh->disconnect;
+
+  $rc;
+  
+}
+
+
+
+sub order_details {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+    
+  my $tax = 0;
+  my $item;
+  my $i;
+  my @partsgroup = ();
+  my $partsgroup;
+  my %oid = ( 'Pg' => 'oid',
+             'Oracle' => 'rowid' );
+
+  # sort items by partsgroup
+  for $i (1 .. $form->{rowcount}) {
+    $partsgroup = "";
+    if ($form->{"partsgroup_$i"} && $form->{groupitems}) {
+      $form->format_string("partsgroup_$i");
+      $partsgroup = $form->{"partsgroup_$i"};
+    }
+    push @partsgroup, [ $i, $partsgroup ];
+  }
+  
+  my $sameitem = "";
+  foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) {
+    $i = $item->[0];
+
+    if ($item->[1] ne $sameitem) {
+      push(@{ $form->{description} }, qq|$item->[1]|);
+      $sameitem = $item->[1];
+
+      map { push(@{ $form->{$_} }, "") } qw(runningnumber number bin qty unit reqdate sellprice listprice netprice discount linetotal);
+    }
+
+    $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
+    
+    if ($form->{"qty_$i"} != 0) {
+
+      # add number, description and qty to $form->{number}, ....
+      push(@{ $form->{runningnumber} }, $i);
+      push(@{ $form->{number} }, qq|$form->{"partnumber_$i"}|);
+      push(@{ $form->{description} }, qq|$form->{"description_$i"}|);
+      push(@{ $form->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"}));
+      push(@{ $form->{unit} }, qq|$form->{"unit_$i"}|);
+      push(@{ $form->{reqdate} }, qq|$form->{"reqdate_$i"}|);
+      
+      push(@{ $form->{sellprice} }, $form->{"sellprice_$i"});
+      
+      push(@{ $form->{listprice} }, $form->{"listprice_$i"});
+      
+      my $sellprice = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
+      my ($dec) = ($sellprice =~ /\.(\d+)/);
+      $dec = length $dec;
+      my $decimalplaces = ($dec > 2) ? $dec : 2;
+
+      my $discount = $form->round_amount($sellprice * $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100, $decimalplaces);
+
+      # keep a netprice as well, (sellprice - discount)
+      $form->{"netprice_$i"} = $sellprice - $discount;
+
+      my $linetotal = $form->round_amount($form->{"qty_$i"} * $form->{"netprice_$i"}, 2);
+
+      push(@{ $form->{netprice} }, ($form->{"netprice_$i"} != 0) ? $form->format_amount($myconfig, $form->{"netprice_$i"}, $decimalplaces) : " ");
+      
+      $discount = ($discount != 0) ? $form->format_amount($myconfig, $discount * -1, $decimalplaces) : " ";
+      $linetotal = ($linetotal != 0) ? $linetotal : " ";
+
+      push(@{ $form->{discount} }, $discount);
+      
+      $form->{ordtotal} += $linetotal;
+
+      push(@{ $form->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2));
+      
+      my ($taxamount, $taxbase);
+      my $taxrate = 0;
+      
+      map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{"taxaccounts_$i"};
+
+      if ($form->{taxincluded}) {
+       # calculate tax
+       $taxamount = $linetotal * $taxrate / (1 + $taxrate);
+       $taxbase = $linetotal / (1 + $taxrate);
+      } else {
+        $taxamount = $linetotal * $taxrate;
+       $taxbase = $linetotal;
+      }
+
+
+      if ($taxamount != 0) {
+       foreach my $item (split / /, $form->{"taxaccounts_$i"}) {
+         $taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
+         $taxbase{$item} += $taxbase;
+       }
+      }
+
+      if ($form->{"assembly_$i"}) {
+        $sameitem = "";
+       
+        # get parts and push them onto the stack
+       my $sortorder = "";
+       if ($form->{groupitems}) {
+         $sortorder = qq|ORDER BY pg.partsgroup, a.$oid{$myconfig->{dbdriver}}|;
+       } else {
+         $sortorder = qq|ORDER BY a.$oid{$myconfig->{dbdriver}}|;
+       }
+       
+       $query = qq|SELECT p.partnumber, p.description, p.unit, a.qty,
+                   pg.partsgroup
+                   FROM assembly a
+                   JOIN parts p ON (a.parts_id = p.id)
+                   LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+                   WHERE a.bom = '1'
+                   AND a.id = '$form->{"id_$i"}'
+                   $sortorder|;
+        $sth = $dbh->prepare($query);
+        $sth->execute || $form->dberror($query);
+
+       while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+         if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
+           map { push(@{ $form->{$_} }, "") } qw(runningnumber number unit bin qty sellprice listprice netprice discount linetotal);
+           $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
+           push(@{ $form->{description} }, $sameitem);
+         }
+           
+         push(@{ $form->{number} }, qq|$ref->{partnumber}|);
+         push(@{ $form->{description} }, qq|$ref->{description}|);
+         push(@{ $form->{unit} }, qq|$ref->{unit}|);
+         push(@{ $form->{qty} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}));
+
+          map { push(@{ $form->{$_} }, "") } qw(runningnumber bin sellprice listprice netprice discount linetotal);
+         
+       }
+       $sth->finish;
+      }
+
+    }
+  }
+
+
+  foreach $item (sort keys %taxaccounts) {
+    if ($form->round_amount($taxaccounts{$item}, 2) != 0) {
+      push(@{ $form->{taxbase} }, $form->format_amount($myconfig, $taxbase{$item}, 2));
+      
+      $taxamount = $form->round_amount($taxaccounts{$item}, 2);
+      $tax += $taxamount;
+      
+      push(@{ $form->{tax} }, $form->format_amount($myconfig, $taxamount, 2));
+      push(@{ $form->{taxdescription} }, $form->{"${item}_description"});
+      push(@{ $form->{taxrate} }, $form->format_amount($myconfig, $form->{"${item}_rate"} * 100));
+      push(@{ $form->{taxnumber} }, $form->{"${item}_taxnumber"});
+    }
+  }
+
+
+  $form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
+  $form->{ordtotal} = ($form->{taxincluded}) ? $form->{ordtotal} : $form->{ordtotal} + $tax;
+  
+  # format amounts
+  $form->{ordtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
+
+  # myconfig variables
+  map { $form->{$_} = $myconfig->{$_} } (qw(company address tel fax signature businessnumber));
+  $form->{username} = $myconfig->{name};
+
+  $dbh->disconnect;
+
+}
+
+
+sub project_description {
+  my ($self, $dbh, $id) = @_;
+
+  my $query = qq|SELECT description
+                 FROM project
+                WHERE id = $id|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  ($_) = $sth->fetchrow_array;
+  
+  $sth->finish;
+
+  $_;
+
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/PE.pm b/sql-ledger/SL/PE.pm
new file mode 100644 (file)
index 0000000..dec04bb
--- /dev/null
@@ -0,0 +1,276 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Project module
+# also used for partsgroups
+#
+#======================================================================
+
+package PE;
+
+
+sub projects {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $sortorder = ($form->{sort}) ? $form->{sort} : "projectnumber";
+
+  my $query = qq|SELECT id, projectnumber, description
+                 FROM project
+                WHERE 1 = 1|;
+
+  if ($form->{projectnumber}) {
+    my $projectnumber = $form->like(lc $form->{projectnumber});
+    $query .= " AND lower(projectnumber) LIKE '$projectnumber'";
+  }
+  if ($form->{projectdescription}) {
+    my $description = $form->like(lc $form->{projectdescription});
+    $query .= " AND lower(description) LIKE '$description'";
+  }
+  if ($form->{status} eq 'orphaned') {
+    $query .= " AND id NOT IN (SELECT p.id
+                               FROM project p, acc_trans a
+                              WHERE p.id = a.project_id)
+                AND id NOT IN (SELECT p.id
+                              FROM project p, invoice i
+                              WHERE p.id = i.project_id)
+               AND id NOT IN (SELECT p.id
+                              FROM project p, orderitems o
+                              WHERE p.id = o.project_id)";
+  }
+
+  $query .= qq|
+                ORDER BY $sortorder|;
+
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $i = 0;
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{project_list} }, $ref;
+    $i++;
+  }
+
+  $sth->finish;
+  $dbh->disconnect;
+  
+  $i;
+
+}
+
+
+sub get_project {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  
+  my $query = qq|SELECT *
+                 FROM project
+                WHERE id = $form->{id}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $ref = $sth->fetchrow_hashref(NAME_lc);
+  
+  map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+  $sth->finish;
+
+  # check if it is orphaned
+  $query = qq|SELECT count(*)
+              FROM acc_trans
+             WHERE project_id = $form->{id}|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  ($form->{orphaned}) = $sth->fetchrow_array;
+  $form->{orphaned} = !$form->{orphaned};
+       
+  $sth->finish;
+  
+  $dbh->disconnect;
+
+}
+
+
+sub save_project {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  
+  map { $form->{$_} =~ s/'/''/g } (projectnumber, description);
+
+  if ($form->{id}) {
+    $query = qq|UPDATE project SET
+                projectnumber = '$form->{projectnumber}',
+               description = '$form->{description}'
+               WHERE id = $form->{id}|;
+  } else {
+    $query = qq|INSERT INTO project
+                (projectnumber, description)
+                VALUES ('$form->{projectnumber}', '$form->{description}')|;
+  }
+  $dbh->do($query) || $form->dberror($query);
+  
+  $dbh->disconnect;
+
+}
+
+
+sub partsgroups {
+  my ($self, $myconfig, $form) = @_;
+  
+  my $var;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $sortorder = ($form->{sort}) ? $form->{sort} : "partsgroup";
+
+  my $query = qq|SELECT g.*
+                 FROM partsgroup g|;
+
+  my $where = "1 = 1";
+  
+  if ($form->{partsgroup}) {
+    $var = $form->like(lc $form->{partsgroup});
+    $where .= " AND lower(partsgroup) LIKE '$var'";
+  }
+  $query .= qq|
+               WHERE $where
+              ORDER BY $sortorder|;
+  
+  if ($form->{status} eq 'orphaned') {
+    $query = qq|SELECT g.*
+                FROM partsgroup g
+                LEFT JOIN parts p ON (p.partsgroup_id = g.id)
+               WHERE $where
+                EXCEPT
+                SELECT g.*
+               FROM partsgroup g
+               JOIN parts p ON (p.partsgroup_id = g.id)
+               WHERE $where
+               ORDER BY $sortorder|;
+  }
+
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $i = 0;
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{item_list} }, $ref;
+    $i++;
+  }
+
+  $sth->finish;
+  $dbh->disconnect;
+  
+  $i;
+
+}
+
+
+sub save_partsgroup {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  
+  map { $form->{$_} =~ s/'/''/g } (partsgroup);
+
+
+  if ($form->{id}) {
+    $query = qq|UPDATE partsgroup SET
+                partsgroup = '$form->{partsgroup}'
+               WHERE id = $form->{id}|;
+  } else {
+    $query = qq|INSERT INTO partsgroup
+                (partsgroup)
+                VALUES ('$form->{partsgroup}')|;
+  }
+  $dbh->do($query) || $form->dberror($query);
+  
+  $dbh->disconnect;
+
+}
+
+
+sub get_partsgroup {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  
+  my $query = qq|SELECT *
+                 FROM partsgroup
+                WHERE id = $form->{id}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  my $ref = $sth->fetchrow_hashref(NAME_lc);
+  map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+  $sth->finish;
+
+  # check if it is orphaned
+  $query = qq|SELECT count(*)
+              FROM parts
+             WHERE partsgroup_id = $form->{id}|;
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  ($form->{orphaned}) = $sth->fetchrow_array;
+  $form->{orphaned} = !$form->{orphaned};
+       
+  $sth->finish;
+  
+  $dbh->disconnect;
+
+}
+
+
+
+sub delete_tuple {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  
+  $query = qq|DELETE FROM $form->{type}
+             WHERE id = $form->{id}|;
+  $dbh->do($query) || $form->dberror($query);
+  
+  $dbh->disconnect;
+
+}
+
+
+
+1;
+
diff --git a/sql-ledger/SL/RC.pm b/sql-ledger/SL/RC.pm
new file mode 100644 (file)
index 0000000..9957d73
--- /dev/null
@@ -0,0 +1,186 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Account reconciliation routines
+#
+#======================================================================
+
+package RC;
+
+
+sub paymentaccounts {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT accno, description
+                 FROM chart
+                WHERE link LIKE '%_paid%'
+                AND category = 'A'
+                ORDER BY accno|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{PR} }, $ref;
+  }
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+
+sub payment_transactions {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database, turn AutoCommit off
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my ($query, $sth);
+  
+  # get cleared balance
+  if ($form->{fromdate}) {
+    $query = qq|SELECT sum(a.amount)
+               FROM acc_trans a, chart c
+               WHERE a.transdate < date '$form->{fromdate}'
+               AND a.cleared = '1'
+               AND c.id = a.chart_id
+               AND c.accno = '$form->{accno}'
+               |;
+  } else {
+    $query = qq|SELECT sum(a.amount)
+               FROM acc_trans a, chart c
+               WHERE a.cleared = '1'
+               AND c.id = a.chart_id
+               AND c.accno = '$form->{accno}'
+               |;
+  }
+  
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  ($form->{beginningbalance}) = $sth->fetchrow_array;
+
+  $sth->finish;
+
+  my %oid = ( 'Pg'      => 'ac.oid',
+              'Oracle'  => 'ac.rowid');
+
+  $query = qq|SELECT c.name, ac.source, ac.transdate, ac.cleared,
+             ac.fx_transaction, ac.amount, a.id,
+             $oid{$myconfig->{dbdriver}} AS oid
+             FROM customer c, acc_trans ac, ar a, chart ch
+             WHERE c.id = a.customer_id
+             AND ac.cleared = '0'
+             AND ac.trans_id = a.id
+             AND ac.chart_id = ch.id
+             AND ch.accno = '$form->{accno}'
+             |;
+             
+  $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
+  $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
+
+
+  $query .= qq|
+  
+      UNION
+              SELECT v.name, ac.source, ac.transdate, ac.cleared,
+             ac.fx_transaction, ac.amount, a.id,
+             $oid{$myconfig->{dbdriver}} AS oid
+             FROM vendor v, acc_trans ac, ap a, chart ch
+             WHERE v.id = a.vendor_id
+             AND ac.cleared = '0'
+             AND ac.trans_id = a.id
+             AND ac.chart_id = ch.id
+             AND ch.accno = '$form->{accno}'
+            |;
+             
+  $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
+  $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
+
+  $query .= qq|
+  
+      UNION
+             SELECT g.description, ac.source, ac.transdate, ac.cleared,
+             ac.fx_transaction, ac.amount, g.id,
+             $oid{$myconfig->{dbdriver}} AS oid
+             FROM gl g, acc_trans ac, chart ch
+             WHERE g.id = ac.trans_id
+             AND ac.cleared = '0'
+             AND ac.trans_id = g.id
+             AND ac.chart_id = ch.id
+             AND ch.accno = '$form->{accno}'
+             |;
+
+  $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
+  $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
+
+  $query .= " ORDER BY 3,7,8";
+
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while (my $pr = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{PR} }, $pr;
+  }
+  $sth->finish;
+
+  $dbh->disconnect;
+  
+}
+
+
+sub reconcile {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my ($query, $i);
+  my %oid = ( 'Pg'      => 'oid',
+              'Oracle'  => 'rowid');
+  
+  # clear flags
+  for $i (1 .. $form->{rowcount}) {
+    if ($form->{"cleared_$i"}) {
+      $query = qq|UPDATE acc_trans SET cleared = '1'
+                  WHERE $oid{$myconfig->{dbdriver}} = $form->{"oid_$i"}|;
+      $dbh->do($query) || $form->dberror($query);
+
+      # clear fx_transaction
+      if ($form->{"fxoid_$i"}) {
+       $query = qq|UPDATE acc_trans SET cleared = '1'
+                   WHERE $oid{$myconfig->{dbdriver}} = $form->{"fxoid_$i"}|;
+       $dbh->do($query) || $form->dberror($query);
+      }
+    }
+  }
+
+  $dbh->disconnect;
+
+}
+
+1;
+
diff --git a/sql-ledger/SL/RP.pm b/sql-ledger/SL/RP.pm
new file mode 100644 (file)
index 0000000..3f07bb5
--- /dev/null
@@ -0,0 +1,1310 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors: Benjamin Lee <benjaminlee@consultant.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# backend code for reports
+#
+#======================================================================
+
+package RP;
+
+
+sub income_statement {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $last_period = 0;
+  my @categories = qw(I E);
+  my $category;
+
+  $form->{decimalplaces} *= 1;
+
+  &get_accounts($dbh, $last_period, $form->{fromdate}, $form->{todate}, $form, \@categories);
+  
+  # if there are any compare dates
+  if ($form->{comparefromdate} || $form->{comparetodate}) {
+    $last_period = 1;
+
+    &get_accounts($dbh, $last_period, $form->{comparefromdate}, $form->{comparetodate}, $form, \@categories);
+  }  
+
+  
+  # disconnect
+  $dbh->disconnect;
+
+
+  # now we got $form->{I}{accno}{ }
+  # and $form->{E}{accno}{  }
+  
+  my %account = ( 'I' => { 'label' => 'income',
+                           'labels' => 'income',
+                          'ml' => 1 },
+                 'E' => { 'label' => 'expense',
+                          'labels' => 'expenses',
+                          'ml' => -1 }
+               );
+  
+  my $str;
+  
+  foreach $category (@categories) {
+    
+    foreach $key (sort keys %{ $form->{$category} }) {
+      # push description onto array
+      
+      $str = ($form->{l_heading}) ? $form->{padding} : "";
+      
+      if ($form->{$category}{$key}{charttype} eq "A") {
+       $str .= ($form->{l_accno}) ? "$form->{$category}{$key}{accno} - $form->{$category}{$key}{description}" : "$form->{$category}{$key}{description}";
+      }
+      if ($form->{$category}{$key}{charttype} eq "H") {
+       if ($account{$category}{subtotal} && $form->{l_subtotal}) {
+         $dash = "- ";
+         push(@{$form->{"$account{$category}{label}_account"}}, "$str$form->{bold}$account{$category}{subdescription}$form->{endbold}");
+         push(@{$form->{"$account{$category}{labels}_this_period"}}, $form->format_amount($myconfig, $account{$category}{subthis} * $account{$category}{ml}, $form->{decimalplaces}, $dash));
+         
+         if ($last_period) {
+           push(@{$form->{"$account{$category}{labels}_last_period"}}, $form->format_amount($myconfig, $account{$category}{sublast} * $account{$category}{ml}, $form->{decimalplaces}, $dash));
+         }
+         
+       }
+       
+       $str = "$form->{br}$form->{bold}$form->{$category}{$key}{description}$form->{endbold}";
+
+       $account{$category}{subthis} = $form->{$category}{$key}{this};
+       $account{$category}{sublast} = $form->{$category}{$key}{last};
+       $account{$category}{subdescription} = $form->{$category}{$key}{description};
+       $account{$category}{subtotal} = 1;
+
+       $form->{$category}{$key}{this} = 0;
+       $form->{$category}{$key}{last} = 0;
+
+       next unless $form->{l_heading};
+
+       $dash = " ";
+      }
+      
+      push(@{$form->{"$account{$category}{label}_account"}}, $str);
+      
+      if ($form->{$category}{$key}{charttype} eq 'A') {
+       $form->{"total_$account{$category}{labels}_this_period"} += $form->{$category}{$key}{this} * $account{$category}{ml};
+       $dash = "- ";
+      }
+      
+      push(@{$form->{"$account{$category}{labels}_this_period"}}, $form->format_amount($myconfig, $form->{$category}{$key}{this} * $account{$category}{ml}, $form->{decimalplaces}, $dash));
+      
+      # add amount or - for last period
+      if ($last_period) {
+       $form->{"total_$account{$category}{labels}_last_period"} += $form->{$category}{$key}{last} * $account{$category}{ml};
+
+       push(@{$form->{"$account{$category}{labels}_last_period"}}, $form->format_amount($myconfig,$form->{$category}{$key}{last} * $account{$category}{ml}, $form->{decimalplaces}, $dash));
+      }
+    }
+
+    $str = ($form->{l_heading}) ? $form->{padding} : "";
+    if ($account{$category}{subtotal} && $form->{l_subtotal}) {
+      push(@{$form->{"$account{$category}{label}_account"}}, "$str$form->{bold}$account{$category}{subdescription}$form->{endbold}");
+      push(@{$form->{"$account{$category}{labels}_this_period"}}, $form->format_amount($myconfig, $account{$category}{subthis} * $account{$category}{ml}, $form->{decimalplaces}, $dash));
+
+      if ($last_period) {
+       push(@{$form->{"$account{$category}{labels}_last_period"}}, $form->format_amount($myconfig, $account{$category}{sublast} * $account{$category}{ml}, $form->{decimalplaces}, $dash));
+      }
+    }
+      
+  }
+
+  
+  # totals for income and expenses
+  $form->{total_income_this_period} = $form->round_amount($form->{total_income_this_period}, $form->{decimalplaces});
+  $form->{total_expenses_this_period} = $form->round_amount($form->{total_expenses_this_period}, $form->{decimalplaces});
+
+  # total for income/loss
+  $form->{total_this_period} = $form->{total_income_this_period} - $form->{total_expenses_this_period};
+  
+  if ($last_period) {
+    # total for income/loss
+    $form->{total_last_period} = $form->format_amount($myconfig, $form->{total_income_last_period} - $form->{total_expenses_last_period}, $form->{decimalplaces}, "- ");
+    
+    # totals for income and expenses for last_period
+    $form->{total_income_last_period} = $form->format_amount($myconfig, $form->{total_income_last_period}, $form->{decimalplaces}, "- ");
+    $form->{total_expenses_last_period} = $form->format_amount($myconfig, $form->{total_expenses_last_period}, $form->{decimalplaces}, "- ");
+
+  }
+
+
+  $form->{total_income_this_period} = $form->format_amount($myconfig,$form->{total_income_this_period}, $form->{decimalplaces}, "- ");
+  $form->{total_expenses_this_period} = $form->format_amount($myconfig,$form->{total_expenses_this_period}, $form->{decimalplaces}, "- ");
+  $form->{total_this_period} = $form->format_amount($myconfig,$form->{total_this_period}, $form->{decimalplaces}, "- ");
+
+}
+
+
+
+sub balance_sheet {
+  my ($self, $myconfig, $form) = @_;
+  
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $last_period = 0;
+  my @categories = qw(A L Q);
+
+  # if there are any dates construct a where
+  if ($form->{asofdate}) {
+    
+    $form->{this_period} = "$form->{asofdate}";
+    $form->{period} = "$form->{asofdate}";
+    
+  }
+
+  $form->{decimalplaces} *= 1;
+
+  &get_accounts($dbh, $last_period, "", $form->{asofdate}, $form, \@categories);
+  
+  # if there are any compare dates
+  if ($form->{compareasofdate}) {
+
+    $last_period = 1;
+    &get_accounts($dbh, $last_period, "", $form->{compareasofdate}, $form, \@categories);
+  
+    $form->{last_period} = "$form->{compareasofdate}";
+
+  }  
+
+  
+  # disconnect
+  $dbh->disconnect;
+
+
+  # now we got $form->{A}{accno}{ }    assets
+  # and $form->{L}{accno}{ }           liabilities
+  # and $form->{Q}{accno}{ }           equity
+  # build asset accounts
+  
+  my $str;
+  my $key;
+  
+  my %account  = ( 'A' => { 'label' => 'asset',
+                            'labels' => 'assets',
+                           'ml' => -1 },
+                  'L' => { 'label' => 'liability',
+                           'labels' => 'liabilities',
+                           'ml' => 1 },
+                  'Q' => { 'label' => 'equity',
+                           'labels' => 'equities',
+                           'ml' => 1 }
+               );          
+                           
+  foreach $category (@categories) {
+
+    foreach $key (sort keys %{ $form->{$category} }) {
+
+      $str = ($form->{l_heading}) ? $form->{padding} : "";
+
+      if ($form->{$category}{$key}{charttype} eq "A") {
+       $str .= ($form->{l_accno}) ? "$form->{$category}{$key}{accno} - $form->{$category}{$key}{description}" : "$form->{$category}{$key}{description}";
+      }
+      if ($form->{$category}{$key}{charttype} eq "H") {
+       if ($account{$category}{subtotal} && $form->{l_subtotal}) {
+         $dash = "- ";
+         push(@{$form->{"$account{$category}{label}_account"}}, "$str$form->{bold}$account{$category}{subdescription}$form->{endbold}");
+         push(@{$form->{"$account{$category}{label}_this_period"}}, $form->format_amount($myconfig, $account{$category}{subthis} * $account{$category}{ml}, $form->{decimalplaces}, $dash));
+         
+         if ($last_period) {
+           push(@{$form->{"$account{$category}{label}_last_period"}}, $form->format_amount($myconfig, $account{$category}{sublast} * $account{$category}{ml}, $form->{decimalplaces}, $dash));
+         }
+       }
+
+       $str = "$form->{bold}$form->{$category}{$key}{description}$form->{endbold}";
+       
+       $account{$category}{subthis} = $form->{$category}{$key}{this};
+       $account{$category}{sublast} = $form->{$category}{$key}{last};
+       $account{$category}{subdescription} = $form->{$category}{$key}{description};
+       $account{$category}{subtotal} = 1;
+       
+       $form->{$category}{$key}{this} = 0;
+       $form->{$category}{$key}{last} = 0;
+
+       next unless $form->{l_heading};
+
+       $dash = " ";
+      }
+      
+      # push description onto array
+      push(@{$form->{"$account{$category}{label}_account"}}, $str);
+      
+      if ($form->{$category}{$key}{charttype} eq 'A') {
+       $form->{"total_$account{$category}{labels}_this_period"} += $form->{$category}{$key}{this} * $account{$category}{ml};
+       $dash = "- ";
+      }
+
+      push(@{$form->{"$account{$category}{label}_this_period"}}, $form->format_amount($myconfig, $form->{$category}{$key}{this} * $account{$category}{ml}, $form->{decimalplaces}, $dash));
+      
+      if ($last_period) {
+       $form->{"total_$account{$category}{labels}_last_period"} += $form->{$category}{$key}{last} * $account{$category}{ml};
+
+       push(@{$form->{"$account{$category}{label}_last_period"}}, $form->format_amount($myconfig, $form->{$category}{$key}{last} * $account{$category}{ml}, $form->{decimalplaces}, $dash));
+      }
+    }
+
+    $str = ($form->{l_heading}) ? $form->{padding} : "";
+    if ($account{$category}{subtotal} && $form->{l_subtotal}) {
+      push(@{$form->{"$account{$category}{label}_account"}}, "$str$form->{bold}$account{$category}{subdescription}$form->{endbold}");
+      push(@{$form->{"$account{$category}{label}_this_period"}}, $form->format_amount($myconfig, $account{$category}{subthis} * $account{$category}{ml}, $form->{decimalplaces}, $dash));
+      
+      if ($last_period) {
+       push(@{$form->{"$account{$category}{label}_last_period"}}, $form->format_amount($myconfig, $account{$category}{sublast} * $account{$category}{ml}, $form->{decimalplaces}, $dash));
+      }
+    }
+
+  }
+
+  
+  # totals for assets, liabilities
+  $form->{total_assets_this_period} = $form->round_amount($form->{total_assets_this_period}, $form->{decimalplaces});
+  $form->{total_liabilities_this_period} = $form->round_amount($form->{total_liabilities_this_period}, $form->{decimalplaces});
+  
+
+  # calculate retained earnings
+  $form->{earnings_this_period} = $form->{total_assets_this_period} - $form->{total_liabilities_this_period} - $form->{total_equity_this_period};
+
+  push(@{$form->{equity_this_period}}, $form->format_amount($myconfig, $form->{earnings_this_period}, $form->{decimalplaces}, "- "));
+  
+  $form->{total_equity_this_period} = $form->round_amount($form->{total_equity_this_period} + $form->{earnings_this_period}, $form->{decimalplaces});
+  
+  # add liability + equity
+  $form->{total_this_period} = $form->format_amount($myconfig, $form->{total_liabilities_this_period} + $form->{total_equity_this_period}, $form->{decimalplaces}, "- ");
+
+
+  if ($last_period) {
+    # totals for assets, liabilities
+    $form->{total_assets_last_period} = $form->round_amount($form->{total_assets_last_period}, $form->{decimalplaces});
+    $form->{total_liabilities_last_period} = $form->round_amount($form->{total_liabilities_last_period}, $form->{decimalplaces});
+    
+
+    # calculate retained earnings
+    $form->{earnings_last_period} = $form->{total_assets_last_period} - $form->{total_liabilities_last_period} - $form->{total_equity_last_period};
+
+    push(@{$form->{equity_last_period}}, $form->format_amount($myconfig,$form->{earnings_last_period}, $form->{decimalplaces}, "- "));
+    
+    $form->{total_equity_last_period} = $form->round_amount($form->{total_equity_last_period} + $form->{earnings_last_period}, $form->{decimalplaces});
+
+    # add liability + equity
+    $form->{total_last_period} = $form->format_amount($myconfig, $form->{total_liabilities_last_period} + $form->{total_equity_last_period}, $form->{decimalplaces}, "- ");
+
+  }
+
+  
+  $form->{total_liabilities_last_period} = $form->format_amount($myconfig, $form->{total_liabilities_last_period}, $form->{decimalplaces}, "- ") if ($form->{total_liabilities_last_period} != 0);
+  
+  $form->{total_equity_last_period} = $form->format_amount($myconfig, $form->{total_equity_last_period}, $form->{decimalplaces}, "- ") if ($form->{total_equity_last_period} != 0);
+  
+  $form->{total_assets_last_period} = $form->format_amount($myconfig, $form->{total_assets_last_period}, $form->{decimalplaces}, "- ") if ($form->{total_assets_last_period} != 0);
+  
+  $form->{total_assets_this_period} = $form->format_amount($myconfig, $form->{total_assets_this_period}, $form->{decimalplaces}, "- ");
+  
+  $form->{total_liabilities_this_period} = $form->format_amount($myconfig, $form->{total_liabilities_this_period}, $form->{decimalplaces}, "- ");
+  
+  $form->{total_equity_this_period} = $form->format_amount($myconfig, $form->{total_equity_this_period}, $form->{decimalplaces}, "- ");
+  
+}
+
+
+
+sub get_accounts {
+  my ($dbh, $last_period, $fromdate, $todate, $form, $categories) = @_;
+
+  my $query;
+  my $where = "WHERE 1 = 1";
+  my $subwhere;
+  my $item;
+  my $category = "AND (";
+  foreach $item (@{ $categories }) {
+    $category .= qq|c.category = '$item' OR |;
+  }
+  $category =~ s/OR $/\)/;
+
+
+  # get headings
+  $query = qq|SELECT accno, description, category
+             FROM chart c
+             WHERE c.charttype = 'H'
+             $category
+             ORDER by c.accno|;
+
+  if ($form->{accounttype} eq 'gifi')
+  {
+    $query = qq|SELECT g.accno, g.description, c.category
+               FROM gifi g
+               JOIN chart c ON (c.gifi_accno = g.accno)
+               WHERE c.charttype = 'H'
+               $category
+               ORDER BY g.accno|;
+  }
+
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+  
+  my @headingaccounts = ();
+  while ($ref = $sth->fetchrow_hashref(NAME_lc))
+  {
+    $form->{$ref->{category}}{$ref->{accno}}{description} = "$ref->{description}";
+    $form->{$ref->{category}}{$ref->{accno}}{charttype} = "H";
+    $form->{$ref->{category}}{$ref->{accno}}{accno} = $ref->{accno};
+    
+    push @headingaccounts, $ref->{accno};
+  }
+
+  $sth->finish;
+
+
+  $where .= " AND ac.transdate >= '$fromdate'" if $fromdate;
+
+  if ($todate) {
+    $where .= " AND ac.transdate <= '$todate'";
+    $subwhere = " AND transdate <= '$todate'";
+  }
+    
+
+  if ($form->{project_id})
+  {
+    $project = qq|
+                 AND ac.project_id = $form->{project_id}
+                |;
+  }
+
+
+  if ($form->{accounttype} eq 'gifi')
+  {
+    
+    if ($form->{method} eq 'cash')
+    {
+
+       $query = qq|
+       
+                SELECT g.accno, sum(ac.amount) AS amount,
+                g.description, c.category
+                FROM acc_trans ac
+                JOIN chart c ON (c.id = ac.chart_id)
+                JOIN ar a ON (a.id = ac.trans_id)
+                JOIN gifi g ON (g.accno = c.gifi_accno)
+                $where
+                $category
+                AND ac.trans_id IN
+                  (
+                    SELECT trans_id
+                    FROM acc_trans
+                    JOIN chart ON (chart_id = id)
+                    WHERE link LIKE '%AR_paid%'
+                    $subwhere
+                  )
+                $project
+                GROUP BY g.accno, g.description, c.category
+                
+       UNION
+       
+                SELECT '' AS accno, SUM(ac.amount) AS amount,
+                '' AS description, c.category
+                FROM acc_trans ac
+                JOIN chart c ON (c.id = ac.chart_id)
+                JOIN ar a ON (a.id = ac.trans_id)
+                $where
+                $category
+                AND c.gifi_accno = ''
+                AND ac.trans_id IN
+                  (
+                    SELECT trans_id
+                    FROM acc_trans
+                    JOIN chart ON (chart_id = id)
+                    WHERE link LIKE '%AR_paid%'
+                    $subwhere
+                  )
+                $project
+                GROUP BY c.category
+
+       UNION
+
+                        SELECT g.accno, sum(ac.amount) AS amount,
+                g.description, c.category
+                FROM acc_trans ac
+                JOIN chart c ON (c.id = ac.chart_id)
+                JOIN ap a ON (a.id = ac.trans_id)
+                JOIN gifi g ON (g.accno = c.gifi_accno)
+                $where
+                $category
+                AND ac.trans_id IN
+                  (
+                    SELECT trans_id
+                    FROM acc_trans
+                    JOIN chart ON (chart_id = id)
+                    WHERE link LIKE '%AP_paid%'
+                    $subwhere
+                  )
+                $project
+                GROUP BY g.accno, g.description, c.category
+                
+       UNION
+       
+                SELECT '' AS accno, SUM(ac.amount) AS amount,
+                '' AS description, c.category
+                FROM acc_trans ac
+                JOIN chart c ON (c.id = ac.chart_id)
+                JOIN ap a ON (a.id = ac.trans_id)
+                $where
+                $category
+                AND c.gifi_accno = ''
+                AND ac.trans_id IN
+                  (
+                    SELECT trans_id
+                    FROM acc_trans
+                    JOIN chart ON (chart_id = id)
+                    WHERE link LIKE '%AP_paid%'
+                    $subwhere
+                  )
+                $project
+                GROUP BY c.category
+
+       UNION
+
+-- add gl
+       
+                SELECT g.accno, sum(ac.amount) AS amount,
+                g.description, c.category
+                FROM acc_trans ac
+                JOIN chart c ON (c.id = ac.chart_id)
+                JOIN gifi g ON (g.accno = c.gifi_accno)
+                JOIN gl a ON (a.id = ac.trans_id)
+                $where
+                $category
+                AND NOT (c.link = 'AR' OR c.link = 'AP')
+                $project
+                GROUP BY g.accno, g.description, c.category
+                
+       UNION
+       
+                SELECT '' AS accno, SUM(ac.amount) AS amount,
+                '' AS description, c.category
+                FROM acc_trans ac
+                JOIN chart c ON (c.id = ac.chart_id)
+                JOIN gl a ON (a.id = ac.trans_id)
+                $where
+                $category
+                AND c.gifi_accno = ''
+                AND NOT (c.link = 'AR' OR c.link = 'AP')
+                $project
+                GROUP BY c.category
+                |;
+
+    } else {
+
+      $query = qq|
+      
+             SELECT g.accno, SUM(ac.amount) AS amount,
+             g.description, c.category
+             FROM acc_trans ac
+             JOIN chart c ON (c.id = ac.chart_id)
+             JOIN gifi g ON (c.gifi_accno = g.accno)
+             $where
+             $category
+             $project
+             GROUP BY g.accno, g.description, c.category
+             
+          UNION
+          
+             SELECT '' AS accno, SUM(ac.amount) AS amount,
+             '' AS description, c.category
+             FROM acc_trans ac
+             JOIN chart c ON (c.id = ac.chart_id)
+             $where
+             $category
+             AND c.gifi_accno = ''
+             $project
+             GROUP by c.category
+             |;
+             
+    }
+    
+  } else {
+
+    if ($form->{method} eq 'cash')
+    {
+
+
+      $query = qq|
+       
+                SELECT c.accno, sum(ac.amount) AS amount,
+                c.description, c.category
+                FROM acc_trans ac
+                JOIN chart c ON (c.id = ac.chart_id)
+                JOIN ar a ON (a.id = ac.trans_id)
+                $where
+                $category
+                AND ac.trans_id IN
+                  (
+                    SELECT trans_id
+                    FROM acc_trans
+                    JOIN chart ON (chart_id = id)
+                    WHERE link LIKE '%AR_paid%'
+                    $subwhere
+                  )
+                    
+                $project
+                GROUP BY c.accno, c.description, c.category
+                
+       UNION
+       
+                SELECT c.accno, sum(ac.amount) AS amount,
+                c.description, c.category
+                FROM acc_trans ac
+                JOIN chart c ON (c.id = ac.chart_id)
+                JOIN ap a ON (a.id = ac.trans_id)
+                $where
+                $category
+                AND ac.trans_id IN
+                  (
+                    SELECT trans_id
+                    FROM acc_trans
+                    JOIN chart ON (chart_id = id)
+                    WHERE link LIKE '%AP_paid%'
+                    $subwhere
+                  )
+                    
+                $project
+                GROUP BY c.accno, c.description, c.category
+                
+        UNION
+
+                SELECT c.accno, sum(ac.amount) AS amount,
+                c.description, c.category
+                FROM acc_trans ac
+                JOIN chart c ON (c.id = ac.chart_id)
+                JOIN gl a ON (a.id = ac.trans_id)
+                $where
+                $category
+                AND NOT (c.link = 'AR' OR c.link = 'AP')
+                $project
+                GROUP BY c.accno, c.description, c.category
+                |;
+                
+    } else {
+     
+      $query = qq|
+      
+                SELECT c.accno, sum(ac.amount) AS amount,
+                c.description, c.category
+                FROM acc_trans ac
+                JOIN chart c ON (c.id = ac.chart_id)
+                $where
+                $category
+                $project
+                GROUP BY c.accno, c.description, c.category
+                |;
+
+    }
+    
+  }
+
+
+  my @accno;
+  my $accno;
+  my $ref;
+  
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while ($ref = $sth->fetchrow_hashref(NAME_lc))
+  {
+
+    if ($ref->{category} eq 'C') {
+      $ref->{category} = 'A';
+    }
+      
+    # get last heading account
+    @accno = grep { $_ le "$ref->{accno}" } @headingaccounts;
+    $accno = pop @accno;
+    if ($accno) {
+      if ($last_period)
+      {
+       $form->{$ref->{category}}{$accno}{last} += $ref->{amount};
+      } else {
+       $form->{$ref->{category}}{$accno}{this} += $ref->{amount};
+      }
+    }
+    
+    $form->{$ref->{category}}{$ref->{accno}}{accno} = $ref->{accno};
+    $form->{$ref->{category}}{$ref->{accno}}{description} = $ref->{description};
+    $form->{$ref->{category}}{$ref->{accno}}{charttype} = "A";
+    
+    if ($last_period)
+    {
+      $form->{$ref->{category}}{$ref->{accno}}{last} += $ref->{amount};
+    } else {
+      $form->{$ref->{category}}{$ref->{accno}}{this} += $ref->{amount};
+    }
+  }
+  $sth->finish;
+
+  
+  # remove accounts with zero balance
+  foreach $category (@{ $categories }) {
+    foreach $accno (keys %{ $form->{$category} }) {
+      $form->{$category}{$accno}{last} = $form->round_amount($form->{$category}{$accno}{last}, $form->{decimalplaces});
+      $form->{$category}{$accno}{this} = $form->round_amount($form->{$category}{$accno}{this}, $form->{decimalplaces});
+
+      delete $form->{$category}{$accno} if ($form->{$category}{$accno}{this} == 0 && $form->{$category}{$accno}{last} == 0);
+    }
+  }
+
+}
+
+
+
+sub trial_balance_details {
+  my ($self, $myconfig, $form) = @_;
+
+  my $dbh = $form->dbconnect($myconfig);
+
+  my ($query, $sth, $ref);
+  my %balance = ();
+  my %trb = ();
+
+  my $where = "WHERE 1 = 1";
+
+  if ($form->{project_id}) {
+    $where .= qq|
+                AND a.project_id = $form->{project_id}
+               |;
+  }
+  
+  # get beginning balances
+  if ($form->{fromdate}) {
+
+    if ($form->{accounttype} eq 'gifi') {
+      
+      $query = qq|SELECT g.accno, c.category, SUM(a.amount) AS amount,
+                  g.description
+                 FROM acc_trans a
+                 JOIN chart c ON (a.chart_id = c.id)
+                 JOIN gifi g ON (c.gifi_accno = g.accno)
+                 $where
+                 AND a.transdate < '$form->{fromdate}'
+                 GROUP BY g.accno, c.category, g.description
+                 |;
+   
+    } else {
+      
+      $query = qq|SELECT c.accno, c.category, SUM(a.amount) AS amount,
+                  c.description
+                 FROM acc_trans a
+                 JOIN chart c ON (a.chart_id = c.id)
+                 $where
+                 AND a.transdate < '$form->{fromdate}'
+                 GROUP BY c.accno, c.category, c.description
+                 |;
+    }
+
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+      $balance{$ref->{accno}} = $ref->{amount};
+
+      if ($ref->{amount} != 0 && $form->{all_accounts}) {
+       $trb{$ref->{accno}}{description} = $ref->{description};
+       $trb{$ref->{accno}}{charttype} = 'A';
+       $trb{$ref->{accno}}{category} = $ref->{category};
+      }
+
+    }
+    $sth->finish;
+
+  }
+
+
+  # get headings
+  $query = qq|SELECT c.accno, c.description, c.category
+             FROM chart c
+             WHERE c.charttype = 'H'
+             ORDER by c.accno|;
+
+  if ($form->{accounttype} eq 'gifi')
+  {
+    $query = qq|SELECT g.accno, g.description, c.category
+               FROM gifi g
+               JOIN chart c ON (c.gifi_accno = g.accno)
+               WHERE c.charttype = 'H'
+               ORDER BY g.accno|;
+  }
+
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+  
+  my @headingaccounts = ();
+  while ($ref = $sth->fetchrow_hashref(NAME_lc))
+  {
+    $trb{$ref->{accno}}{description} = $ref->{description};
+    $trb{$ref->{accno}}{charttype} = 'H';
+    $trb{$ref->{accno}}{category} = $ref->{category};
+   
+    push @headingaccounts, $ref->{accno};
+  }
+
+  $sth->finish;
+
+
+  if ($form->{fromdate} || $form->{todate}) {
+    if ($form->{fromdate}) {
+      $where .= " AND a.transdate >= '$form->{fromdate}'";
+    }
+    if ($form->{todate}) {
+      $where .= " AND a.transdate <= '$form->{todate}'";
+    }
+  }
+
+
+  if ($form->{accounttype} eq 'gifi') {
+
+    $query = qq|SELECT g.accno, g.description, c.category,
+                SUM(a.amount) AS amount
+               FROM acc_trans a
+               JOIN chart c ON (c.id = a.chart_id)
+               JOIN gifi g ON (c.gifi_accno = g.accno)
+               $where
+               GROUP BY g.accno, g.description, c.category
+               
+             UNION
+
+               SELECT '' AS accno, '' AS description, c.category,
+               SUM(a.amount) AS amount
+               FROM acc_trans a
+               JOIN chart c ON (c.id = a.chart_id)
+               $where
+               AND c.gifi_accno = ''
+               GROUP BY c.category
+               ORDER BY accno|;
+    
+  } else {
+
+    $query = qq|SELECT c.accno, c.description, c.category,
+                SUM(a.amount) AS amount
+               FROM acc_trans a
+               JOIN chart c ON (c.id = a.chart_id)
+               $where
+               GROUP BY c.accno, c.description, c.category
+                ORDER BY accno|;
+
+  }
+  
+  $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+
+  # prepare query for each account
+    
+  $query = qq|SELECT (SELECT SUM(a.amount) * -1
+             FROM acc_trans a
+             JOIN chart c ON (c.id = a.chart_id)
+             $where
+             AND a.amount < 0
+             AND c.accno = ?) AS debit,
+            (SELECT SUM(a.amount)
+             FROM acc_trans a
+             JOIN chart c ON (c.id = a.chart_id)
+             $where
+             AND a.amount > 0
+             AND c.accno = ?) AS credit
+             |;
+
+  if ($form->{accounttype} eq 'gifi') {
+
+    $query = qq|SELECT (SELECT SUM(a.amount) * -1
+               FROM acc_trans a
+               JOIN chart c ON (c.id = a.chart_id)
+               $where
+               AND a.amount < 0
+               AND c.gifi_accno = ?) AS debit,
+              (SELECT SUM(a.amount)
+               FROM acc_trans a
+               JOIN chart c ON (c.id = a.chart_id)
+               $where
+               AND a.amount > 0
+               AND c.gifi_accno = ?) AS credit|;
+  
+  }
+   
+  $drcr = $dbh->prepare($query);
+  
+  # calculate the debit and credit in the period
+  while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+    $trb{$ref->{accno}}{description} = $ref->{description};
+    $trb{$ref->{accno}}{charttype} = 'A';
+    $trb{$ref->{accno}}{category} = $ref->{category};
+    $trb{$ref->{accno}}{amount} += $ref->{amount};
+
+  }
+  $sth->finish;
+
+  my ($debit, $credit);
+  
+  foreach my $accno (sort keys %trb) {
+    $ref = ();
+
+    $ref->{accno} = $accno;
+    map { $ref->{$_} = $trb{$accno}{$_} } qw(description category charttype amount);
+    
+    $ref->{balance} = $form->round_amount($balance{$ref->{accno}}, 2);
+
+    if ($trb{$accno}{charttype} eq 'A') {
+      # get DR/CR
+      $drcr->execute($ref->{accno}, $ref->{accno}) || $form->dberror($query);
+      
+      ($debit, $credit) = (0,0);
+      while (($debit, $credit) = $drcr->fetchrow_array) {
+       $ref->{debit} += $debit;
+       $ref->{credit} += $credit;
+      }
+      $drcr->finish;
+
+      $ref->{debit} = $form->round_amount($ref->{debit}, 2);
+      $ref->{credit} = $form->round_amount($ref->{credit}, 2);
+    
+    }
+
+
+    # add subtotal
+    @accno = grep { $_ le "$ref->{accno}" } @headingaccounts;
+    $accno = pop @accno;
+    if ($accno) {
+      $trb{$accno}{debit} += $ref->{debit};
+      $trb{$accno}{credit} += $ref->{credit};
+    }
+   
+    push @{ $form->{TB} }, $ref;
+    
+  }
+
+  $dbh->disconnect;
+
+  # debits and credits for headings
+  foreach $accno (@headingaccounts) {
+    foreach $ref (@{ $form->{TB} }) {
+      if ($accno eq $ref->{accno}) {
+        $ref->{debit} = $trb{$accno}{debit};
+        $ref->{credit} = $trb{$accno}{credit};
+      }
+    }
+  }
+
+}
+
+
+
+sub aging {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+  my $invoice = ($form->{arap} eq 'ar') ? 'is' : 'ir';
+  
+  $form->{todate} = $form->current_date($myconfig) unless ($form->{todate});
+
+  my $where = "1 = 1";
+  my $name;
+
+  if ($form->{"$form->{ct}_id"}) {
+    $where .= qq| AND ct.id = $form->{"$form->{ct}_id"}|;
+  } else {
+    if ($form->{$form->{ct}}) {
+      $name = $form->like(lc $form->{$form->{ct}});
+      $where .= qq| AND lower(ct.name) LIKE '$name'| if $form->{$form->{ct}};
+    }
+  }
+
+  # select outstanding vendors or customers, depends on $ct
+  my $query = qq|SELECT DISTINCT ct.id, ct.name
+                 FROM $form->{ct} ct, $form->{arap} a
+                WHERE $where
+                 AND a.$form->{ct}_id = ct.id
+                 AND a.paid != a.amount
+                 AND (a.transdate <= '$form->{todate}')
+                 ORDER BY ct.name|;
+
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror;
+
+  my $buysell = ($form->{arap} eq 'ar') ? 'buy' : 'sell';
+  
+  # for each company that has some stuff outstanding
+  while ( my ($id) = $sth->fetchrow_array ) {
+  
+    $query = qq|
+
+-- between 0-30 days
+
+       SELECT $form->{ct}.id AS ctid, $form->{ct}.name,
+       addr1, addr2, addr3, addr4, contact,
+       phone as customerphone, fax as customerfax, $form->{ct}number,
+       "invnumber", "transdate",
+       (amount - paid) as "c0", 0.00 as "c30", 0.00 as "c60", 0.00 as "c90",
+       "duedate", invoice, $form->{arap}.id,
+         (SELECT $buysell FROM exchangerate
+          WHERE $form->{arap}.curr = exchangerate.curr
+          AND exchangerate.transdate = $form->{arap}.transdate) AS exchangerate
+  FROM $form->{arap}, $form->{ct} 
+       WHERE paid != amount
+       AND $form->{arap}.$form->{ct}_id = $form->{ct}.id
+       AND $form->{ct}.id = $id
+       AND (
+               transdate <= (date '$form->{todate}' - interval '0 days') 
+               AND transdate >= (date '$form->{todate}' - interval '30 days')
+           )
+       
+       UNION
+
+-- between 31-60 days
+
+       SELECT $form->{ct}.id AS ctid, $form->{ct}.name,
+       addr1, addr2, addr3, addr4, contact,
+       phone as customerphone, fax as customerfax, $form->{ct}number,
+       "invnumber", "transdate", 
+       0.00 as "c0", (amount - paid) as "c30", 0.00 as "c60", 0.00 as "c90",
+       "duedate", invoice, $form->{arap}.id,
+         (SELECT $buysell FROM exchangerate
+          WHERE $form->{arap}.curr = exchangerate.curr
+          AND exchangerate.transdate = $form->{arap}.transdate) AS exchangerate
+  FROM $form->{arap}, $form->{ct}
+       WHERE paid != amount 
+       AND $form->{arap}.$form->{ct}_id = $form->{ct}.id 
+       AND $form->{ct}.id = $id
+       AND (
+               transdate < (date '$form->{todate}' - interval '30 days') 
+               AND transdate >= (date '$form->{todate}' - interval '60 days')
+               )
+
+       UNION
+  
+-- between 61-90 days
+
+       SELECT $form->{ct}.id AS ctid, $form->{ct}.name,
+       addr1, addr2, addr3, addr4, contact,
+       phone as customerphone, fax as customerfax, $form->{ct}number,
+       "invnumber", "transdate", 
+       0.00 as "c0", 0.00 as "c30", (amount - paid) as "c60", 0.00 as "c90",
+       "duedate", invoice, $form->{arap}.id,
+         (SELECT $buysell FROM exchangerate
+          WHERE $form->{arap}.curr = exchangerate.curr
+          AND exchangerate.transdate = $form->{arap}.transdate) AS exchangerate
+       FROM $form->{arap}, $form->{ct} 
+       WHERE paid != amount
+       AND $form->{arap}.$form->{ct}_id = $form->{ct}.id 
+       AND $form->{ct}.id = $id
+       AND (
+               transdate < (date '$form->{todate}' - interval '60 days') 
+               AND transdate >= (date '$form->{todate}' - interval '90 days')
+               )
+
+       UNION
+  
+-- over 90 days
+
+       SELECT $form->{ct}.id AS ctid, $form->{ct}.name,
+       addr1, addr2, addr3, addr4, contact,
+       phone as customerphone, fax as customerfax, $form->{ct}number,
+       "invnumber", "transdate", 
+       0.00 as "c0", 0.00 as "c30", 0.00 as "c60", (amount - paid) as "c90",
+       "duedate", invoice, $form->{arap}.id,
+         (SELECT $buysell FROM exchangerate
+          WHERE $form->{arap}.curr = exchangerate.curr
+          AND exchangerate.transdate = $form->{arap}.transdate) AS exchangerate
+       FROM $form->{arap}, $form->{ct} 
+       WHERE paid != amount
+       AND $form->{arap}.$form->{ct}_id = $form->{ct}.id 
+       AND $form->{ct}.id = $id
+       AND transdate < (date '$form->{todate}' - interval '90 days') 
+
+       ORDER BY
+  
+  ctid, invnumber, transdate
+  
+               |;
+
+    my $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror;
+
+    while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+      $ref->{module} = ($ref->{invoice}) ? $invoice : $form->{arap};
+      $ref->{exchangerate} = 1 unless $ref->{exchangerate};
+      push @{ $form->{AG} }, $ref;
+    }
+    
+    $sth->finish;
+
+  }
+
+  $sth->finish;
+  # disconnect
+  $dbh->disconnect;
+
+}
+
+
+sub get_customer {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  my $query = qq|SELECT name, email, cc, bcc
+                 FROM $form->{ct} ct
+                WHERE ct.id = $form->{"$form->{ct}_id"}|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror;
+
+  ($form->{$form->{ct}}, $form->{email}, $form->{cc}, $form->{bcc}) = $sth->fetchrow_array;
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+
+sub get_taxaccounts {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  # get tax accounts
+  my $query = qq|SELECT accno, description
+                 FROM chart
+                WHERE link LIKE '%CT_tax%'
+                 ORDER BY accno|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror;
+
+  while ( my ($accno, $description) = $sth->fetchrow_array ) {
+    push @{ $form->{taxaccounts} }, "$accno--$description";
+  }
+  $sth->finish;
+
+  # get gifi tax accounts
+  my $query = qq|SELECT DISTINCT ON (g.accno) g.accno, g.description
+                 FROM gifi g, chart c
+                WHERE g.accno = c.gifi_accno
+                AND c.link LIKE '%CT_tax%'
+                 ORDER BY accno|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror;
+
+  while ( my ($accno, $description) = $sth->fetchrow_array ) {
+    push @{ $form->{gifi_taxaccounts} }, "$accno--$description";
+  }
+  $sth->finish;
+
+  $dbh->disconnect;
+
+}
+
+
+
+sub tax_report {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->dbconnect($myconfig);
+
+  # build WHERE
+  my $where = qq|WHERE ac.trans_id = a.id
+                AND ac.chart_id = ch.id|;
+                
+
+  if ($form->{accno} =~ /^gifi_/) {
+    my ($null, $accno) = split /_/, $form->{accno};
+    $where .= qq| AND ch.gifi_accno = '$accno'|;
+  } else {
+    $where .= qq| AND ch.accno = '$form->{accno}'|;
+  }
+
+  my $table;
+  
+  if ($form->{db} eq 'ar') {
+    $where .= " AND n.id = a.customer_id";
+    $table = "customer";
+  }
+  if ($form->{db} eq 'ap') {
+    $where .= " AND n.id = a.vendor_id";
+    $table = "vendor";
+  }
+
+  my $transdate = ($form->{cashbased}) ? "a.datepaid" : "ac.transdate";
+  if ($form->{cashbased}) {
+    $where .= " AND a.amount = a.paid";
+  }
+
+  # if there are any dates construct a where
+  if ($form->{fromdate} || $form->{todate}) {
+    if ($form->{fromdate}) {
+      $where .= " AND $transdate >= '$form->{fromdate}'";
+    }
+    if ($form->{todate}) {
+      $where .= " AND $transdate <= '$form->{todate}'";
+    }
+  }
+  
+  my $query = qq|SELECT a.id, a.invoice, $transdate AS transdate, a.invnumber,
+                        n.name, a.netamount,|;
+  my $sortorder = join ', ', $form->sort_columns(qw(transdate invnumber name));
+  $sortorder = $form->{sort} unless $sortorder;
+  
+  if ($form->{db} eq 'ar') {
+    $query .= " ac.amount AS tax";
+  }
+  if ($form->{db} eq 'ap') {
+    $query .= " ac.amount * -1 AS tax";
+  }
+
+  $query .= qq|
+               FROM acc_trans ac, "$form->{db}" a, "$table" n, chart ch
+              $where
+              ORDER by $sortorder|;
+
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+
+  while ( my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{TR} }, $ref;
+  }
+
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+
+sub paymentaccounts {
+  my ($self, $myconfig, $form) = @_;
+  # connect to database, turn AutoCommit off
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my $arap = uc $form->{db};
+  $arap .= "_paid";
+  
+  # get A(R|P)_paid accounts
+  my $query = qq|SELECT accno, description
+                 FROM chart
+                 WHERE link LIKE '%$arap%'|;
+  my $sth = $dbh->prepare($query);
+  $sth->execute || $form->dberror($query);
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    push @{ $form->{PR} }, $ref;
+  }
+
+  $sth->finish;
+  $dbh->disconnect;
+
+}
+
+sub payments {
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database, turn AutoCommit off
+  my $dbh = $form->dbconnect_noauto($myconfig);
+
+  my $ml = 1;
+  if ($form->{db} eq 'ar') {
+    $table = 'customer';
+    $ml = -1;
+  }
+  if ($form->{db} eq 'ap') {
+    $table = 'vendor';
+  }
+  
+  my ($query, $sth);
+  
+  # cycle through each id
+  foreach my $accno (split(/ /, $form->{paymentaccounts})) {
+
+    $query = qq|SELECT id, accno, description
+                FROM chart
+               WHERE accno = '$accno'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    my $ref = $sth->fetchrow_hashref(NAME_lc);
+    push @{ $form->{PR} }, $ref;
+    $sth->finish;
+
+    $query = qq|SELECT c.name, a.invnumber, a.ordnumber,
+               ac.transdate,
+               ac.amount * $ml AS paid, ac.source, a.invoice, a.id,
+               '$form->{db}' AS module
+               FROM $table c, acc_trans ac, $form->{db} a
+               WHERE c.id = a.${table}_id
+               AND ac.trans_id = a.id
+               AND ac.chart_id = $ref->{id}|;
+               
+    $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
+    $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
+
+    $query .= qq|
+       UNION
+               SELECT g.description, g.reference, NULL AS ordnumber,
+                ac.transdate,
+                ac.amount * $ml AS paid, ac.source, '0' as invoice, g.id,
+                'gl' AS module
+                FROM gl g, acc_trans ac
+                WHERE g.id = ac.trans_id
+                AND ac.chart_id = $ref->{id}
+                AND (ac.amount * $ml) > 0
+               |;
+
+    $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
+    $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
+
+
+    my $sortorder = join ', ', $form->sort_columns(qw(name invnumber ordnumber transdate source));
+    
+    $query .= " ORDER BY $sortorder";
+
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    while (my $pr = $sth->fetchrow_hashref(NAME_lc)) {
+      push @{ $form->{$ref->{id}} }, $pr;
+    }
+    $sth->finish;
+
+  }
+  
+  $dbh->disconnect;
+  
+}
+
+
+1;
+
+
diff --git a/sql-ledger/SL/User.pm b/sql-ledger/SL/User.pm
new file mode 100644 (file)
index 0000000..d9b463d
--- /dev/null
@@ -0,0 +1,692 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#=====================================================================
+#
+# user related functions
+#
+#=====================================================================
+
+package User;
+
+
+sub new {
+  my ($type, $memfile, $login) = @_;
+  my $self = {};
+
+  if ($login ne "") {
+    # check if the file is locked
+    &error("", "$memfile locked!") if (-f "${memfile}.LCK");
+    
+    open(MEMBER, "$memfile") or &error("", "$memfile : $!");
+    
+    while (<MEMBER>) {
+      if (/^\[$login\]/) {
+       while (<MEMBER>) {
+         last if /^\[/;
+         next if /^(#|\s)/;
+         
+         # remove comments
+         s/\s#.*//g;
+
+         # remove any trailing whitespace
+         s/^\s*(.*?)\s*$/$1/;
+
+         ($key, $value) = split /=/, $_, 2;
+         
+         $self->{$key} = $value;
+       }
+       
+       $self->{login} = $login;
+
+       last;
+      }
+    }
+    close MEMBER;
+  }
+  
+  bless $self, $type;
+}
+
+
+sub country_codes {
+
+  my %cc = ();
+  my @language = ();
+  
+  # scan the locale directory and read in the LANGUAGE files
+  opendir DIR, "locale";
+
+  my @dir = grep !/(^\.\.?$|\..*)/, readdir DIR;
+  
+  foreach my $dir (@dir) {
+    next unless open(FH, "locale/$dir/LANGUAGE");
+    @language = <FH>;
+    close FH;
+
+    $cc{$dir} = "@language";
+  }
+
+  closedir(DIR);
+  
+  %cc;
+
+}
+
+
+sub login {
+  my ($self, $form, $userspath) = @_;
+
+
+  if ($self->{login}) {
+    
+    if ($self->{password}) {
+      $form->{password} = crypt $form->{password}, substr($self->{login}, 0, 2);
+      if ($self->{password} ne $form->{password}) {
+       return -1;
+      }
+    }
+    
+    unless (-e "$userspath/$self->{login}.conf") {
+      $self->create_config("$userspath/$self->{login}.conf");
+    }
+    
+    do "$userspath/$self->{login}.conf";
+    $myconfig{dbpasswd} = unpack 'u', $myconfig{dbpasswd};
+  
+    # check if database is down
+    my $dbh = DBI->connect($myconfig{dbconnect}, $myconfig{dbuser}, $myconfig{dbpasswd}) or $self->error(DBI::errstr);
+
+    # we got a connection, check the version
+    my $query = qq|SELECT version FROM defaults|;
+    my $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    my ($dbversion) = $sth->fetchrow_array;
+    $sth->finish;
+
+    # add login to employee table if it does not exist
+    # no error check for employee table, ignore if it does not exist
+    $query = qq|SELECT id FROM employee WHERE login = '$self->{login}'|;
+    $sth = $dbh->prepare($query);
+    $sth->execute;
+
+    my ($login) = $sth->fetchrow_array;
+    $sth->finish;
+
+    if (!$login) {
+      $query = qq|INSERT INTO employee (login, name, workphone)
+                  VALUES ('$self->{login}', '$myconfig{name}', '$myconfig{tel}')|;
+      $dbh->do($query);
+    }
+    $dbh->disconnect;
+
+    if ($form->{dbversion} ne $dbversion) {
+      return -2;
+    }
+
+  } else {
+    return -3;
+  }
+
+}
+
+
+
+sub dbconnect_vars {
+  my ($form, $db) = @_;
+  
+  my %dboptions = (
+     'Pg' => {
+        'yy-mm-dd' => 'set DateStyle to \'ISO\'',
+       'mm/dd/yy' => 'set DateStyle to \'SQL, US\'',
+       'mm-dd-yy' => 'set DateStyle to \'POSTGRES, US\'',
+       'dd/mm/yy' => 'set DateStyle to \'SQL, EUROPEAN\'',
+       'dd-mm-yy' => 'set DateStyle to \'POSTGRES, EUROPEAN\'',
+       'dd.mm.yy' => 'set DateStyle to \'GERMAN\''
+            },
+     'Oracle' => {
+       'yy-mm-dd' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'YY-MM-DD\'',
+       'mm/dd/yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'MM/DD/YY\'',
+       'mm-dd-yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'MM-DD-YY\'',
+       'dd/mm/yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD/MM/YY\'',
+       'dd-mm-yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD-MM-YY\'',
+       'dd.mm.yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD.MM.YY\'',
+                }
+     );
+                            
+  $form->{dboptions} = $dboptions{$form->{dbdriver}}{$form->{dateformat}};
+
+  if ($form->{dbdriver} eq 'Pg') {
+    $form->{dbconnect} = "dbi:Pg:dbname=$db";
+  }
+
+  if ($form->{dbdriver} eq 'Oracle') {
+    $form->{dbconnect} = "dbi:Oracle:sid=$form->{sid}";
+  }
+
+  if ($form->{dbhost}) {
+    $form->{dbconnect} .= ";host=$form->{dbhost}";
+  }
+  if ($form->{dbport}) {
+    $form->{dbconnect} .= ";port=$form->{dbport}";
+  }
+  
+}
+
+
+sub dbdrivers {
+
+  my @drivers = DBI->available_drivers();
+
+  return (grep { /(Pg|Oracle)$/ } @drivers);
+
+}
+
+
+sub dbsources {
+  my ($self, $form) = @_;
+
+  my @dbsources = ();
+  my ($sth, $query);
+  
+  $form->{dbdefault} = $form->{dbuser} unless $form->{dbdefault};
+  $form->{sid} = $form->{dbdefault};
+  &dbconnect_vars($form, $form->{dbdefault});
+
+  my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
+
+
+  if ($form->{dbdriver} eq 'Pg') {
+
+    $query = qq|SELECT datname FROM pg_database|;
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+    
+    while (my ($db) = $sth->fetchrow_array) {
+
+      if ($form->{only_acc_db}) {
+       
+       next if ($db =~ /^template/);
+
+       &dbconnect_vars($form, $db);
+       my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
+
+       $query = qq|SELECT tablename FROM pg_tables
+                   WHERE tablename = 'defaults'
+                   AND tableowner = '$form->{dbuser}'|;
+       my $sth = $dbh->prepare($query);
+       $sth->execute || $form->dberror($query);
+
+       if ($sth->fetchrow_array) {
+         push @dbsources, $db;
+       }
+       $sth->finish;
+       $dbh->disconnect;
+       next;
+      }
+      push @dbsources, $db;
+    }
+  }
+
+  if ($form->{dbdriver} eq 'Oracle') {
+    if ($form->{only_acc_db}) {
+      $query = qq|SELECT owner FROM dba_objects
+                 WHERE object_name = 'DEFAULTS'
+                 AND object_type = 'TABLE'|;
+    } else {
+      $query = qq|SELECT username FROM dba_users|;
+    }
+
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    while (my ($db) = $sth->fetchrow_array) {
+      push @dbsources, $db;
+    }
+  }
+
+  $sth->finish;
+  $dbh->disconnect;
+  
+  return @dbsources;
+
+}
+
+
+sub dbcreate {
+  my ($self, $form) = @_;
+
+  my %dbcreate = ( 'Pg' => qq|CREATE DATABASE "$form->{db}"|,
+               'Oracle' => qq|CREATE USER "$form->{db}" DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP IDENTIFIED BY "$form->{db}"|);
+
+  $dbcreate{Pg} .= " WITH ENCODING = '$form->{encoding}'" if $form->{encoding};
+  
+  $form->{sid} = $form->{dbdefault};
+  &dbconnect_vars($form, $form->{dbdefault});
+  my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
+  my $query = qq|$dbcreate{$form->{dbdriver}}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  if ($form->{dbdriver} eq 'Oracle') {
+    $query = qq|GRANT CONNECT,RESOURCE TO "$form->{db}"|;
+    $dbh->do($query) || $form->dberror($query);
+  }
+  $dbh->disconnect;
+
+
+  # setup variables for the new database
+  if ($form->{dbdriver} eq 'Oracle') {
+    $form->{dbuser} = $form->{db};
+    $form->{dbpasswd} = $form->{db};
+  }
+  
+  
+  &dbconnect_vars($form, $form->{db});
+  
+  $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
+  
+  # create the tables
+  my $filename = qq|sql/$form->{dbdriver}-tables.sql|;
+  $self->processquery($form, $dbh, $filename);
+
+  # load gifi
+  ($filename) = split /_/, $form->{chart};
+  $filename =~ s/_//;
+  $self->processquery($form, $dbh, "sql/${filename}-gifi.sql");
+
+  # load chart of accounts
+  $filename = qq|sql/$form->{chart}-chart.sql|;
+  $self->processquery($form, $dbh, $filename);
+
+  # create indices
+  $filename = qq|sql/$form->{dbdriver}-indices.sql|;
+  $self->processquery($form, $dbh, $filename);
+  
+  $dbh->disconnect;
+
+}
+
+
+
+sub processquery {
+  my ($self, $form, $dbh, $filename) = @_;
+  
+  return unless (-f $filename);
+  
+  open(FH, "$filename") or $form->error("$filename : $!\n");
+  my $query = "";
+  
+  while (<FH>) {
+    $query .= $_;
+
+    if (/;\s*$/) {
+      # strip ;... Oracle doesn't like it
+      $query =~ s/;\s*$//;
+      $dbh->do($query) || $form->dberror($query);
+      $query = "";
+    }
+  }
+  close FH;
+
+}
+  
+
+
+sub dbdelete {
+  my ($self, $form) = @_;
+
+  my %dbdelete = ( 'Pg' => qq|DROP DATABASE "$form->{db}"|,
+               'Oracle' => qq|DROP USER $form->{db} CASCADE|
+                );
+  
+  $form->{sid} = $form->{dbdefault};
+  &dbconnect_vars($form, $form->{dbdefault});
+  my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
+  my $query = qq|$dbdelete{$form->{dbdriver}}|;
+  $dbh->do($query) || $form->dberror($query);
+
+  $dbh->disconnect;
+
+}
+  
+
+
+sub dbsources_unused {
+  my ($self, $form, $memfile) = @_;
+
+  my @dbexcl = ();
+  my @dbsources = ();
+  
+  $form->error('File locked!') if (-f "${memfile}.LCK");
+  
+  # open members file
+  open(FH, "$memfile") or $form->error("$memfile : $!");
+
+  while (<FH>) {
+    if (/^dbname=/) {
+      my ($null,$item) = split /=/;
+      push @dbexcl, $item;
+    }
+  }
+
+  close FH;
+
+  $form->{only_acc_db} = 1;
+  my @db = &dbsources("", $form);
+
+  push @dbexcl, $form->{dbdefault};
+
+  foreach $item (@db) {
+    unless (grep /$item$/, @dbexcl) {
+      push @dbsources, $item;
+    }
+  }
+
+  return @dbsources;
+
+}
+
+
+sub dbneedsupdate {
+  my ($self, $form) = @_;
+
+  my %dbsources = ();
+  my $query;
+  
+  $form->{sid} = $form->{dbdefault};
+  &dbconnect_vars($form, $form->{dbdefault});
+
+  my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
+
+  if ($form->{dbdriver} eq 'Pg') {
+
+    $query = qq|SELECT d.datname FROM pg_database d, pg_user u
+                WHERE d.datdba = u.usesysid
+               AND u.usename = '$form->{dbuser}'|;
+    my $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+    
+    while (my ($db) = $sth->fetchrow_array) {
+
+      next if ($db =~ /^template/);
+
+      &dbconnect_vars($form, $db);
+      
+      my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
+
+      $query = qq|SELECT tablename FROM pg_tables
+                 WHERE tablename = 'defaults'|;
+      my $sth = $dbh->prepare($query);
+      $sth->execute || $form->dberror($query);
+
+      if ($sth->fetchrow_array) {
+       $query = qq|SELECT version FROM defaults|;
+       my $sth = $dbh->prepare($query);
+       $sth->execute;
+       
+       if (my ($version) = $sth->fetchrow_array) {
+         $dbsources{$db} = $version;
+       }
+       $sth->finish;
+      }
+      $sth->finish;
+      $dbh->disconnect;
+    }
+    $sth->finish;
+  }
+
+
+  if ($form->{dbdriver} eq 'Oracle') {
+    $query = qq|SELECT owner FROM dba_objects
+               WHERE object_name = 'DEFAULTS'
+               AND object_type = 'TABLE'|;
+
+    $sth = $dbh->prepare($query);
+    $sth->execute || $form->dberror($query);
+
+    while (my ($db) = $sth->fetchrow_array) {
+      
+      $form->{dbuser} = $db;
+      &dbconnect_vars($form, $db);
+      
+      my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
+
+      $query = qq|SELECT version FROM defaults|;
+      my $sth = $dbh->prepare($query);
+      $sth->execute;
+      
+      if (my ($version) = $sth->fetchrow_array) {
+       $dbsources{$db} = $version;
+      }
+      $sth->finish;
+      $dbh->disconnect;
+    }
+    $sth->finish;
+  }
+  
+  $dbh->disconnect;
+  
+  %dbsources;
+
+}
+
+
+sub dbupdate {
+  my ($self, $form) = @_;
+
+  $form->{sid} = $form->{dbdefault};
+  
+  my @upgradescripts = ();
+  my $query;
+  
+  if ($form->{dbupdate}) {
+    # read update scripts into memory
+    opendir SQLDIR, "sql/." or $form-error($!);
+    @upgradescripts = sort grep /$form->{dbdriver}-upgrade-.*?\.sql/, readdir SQLDIR;
+    closedir SQLDIR;
+  }
+
+  
+  foreach my $db (split / /, $form->{dbupdate}) {
+
+    next unless $form->{$db};
+
+    # strip db from dataset
+    $db =~ s/^db//;
+    &dbconnect_vars($form, $db);
+
+    my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
+
+    # check version
+    $query = qq|SELECT version FROM defaults|;
+    my $sth = $dbh->prepare($query);
+    # no error check, let it fall through
+    $sth->execute;
+
+    my $version = $sth->fetchrow_array;
+    $sth->finish;
+    
+    next unless $version;
+
+    foreach my $upgradescript (@upgradescripts) {
+      my $a = $upgradescript;
+      $a =~ s/(^$form->{dbdriver}-upgrade-|\.sql$)//g;
+      
+      my ($mindb, $maxdb) = split /-/, $a;
+
+      next if ($version ge $maxdb);
+
+      # if there is no upgrade script exit
+      last if ($version lt $mindb);
+
+      # apply upgrade
+      $self->processquery($form, $dbh, "sql/$upgradescript");
+
+      $version = $maxdb;
+    }
+    
+    $dbh->disconnect;
+    
+  }
+}
+  
+
+
+sub create_config {
+  my ($self, $filename) = @_;
+
+
+  @config = &config_vars;
+  
+  open(CONF, ">$filename") or $self->error("$filename : $!");
+  
+  # create the config file
+  print CONF qq|# configuration file for $self->{login}
+
+\%myconfig = (
+|;
+
+  foreach $key (sort @config) {
+    $self->{$key} =~ s/'/\\'/g;
+    print CONF qq|  $key => '$self->{$key}',\n|;
+  }
+
+   
+  print CONF qq|);\n\n|;
+
+  close CONF;
+
+}
+
+
+sub save_member {
+  my ($self, $memberfile, $userspath) = @_;
+
+  my $newmember = 1;
+  
+  # format dbconnect and dboptions string
+  map { $self->{$_} = lc $self->{$_} } qw(dbname host);
+  &dbconnect_vars($self, $self->{dbname});
+  
+  $self->error('File locked!') if (-f "${memberfile}.LCK");
+  open(FH, ">${memberfile}.LCK") or $self->error("${memberfile}.LCK : $!");
+  close(FH);
+  
+  open(CONF, "+<$memberfile") or $self->error("$memberfile : $!");
+  
+  @config = <CONF>;
+  
+  seek(CONF, 0, 0);
+  truncate(CONF, 0);
+  
+  while ($line = shift @config) {
+    if ($line =~ /^\[$self->{login}\]/) {
+      $newmember = 0;
+      last;
+    }
+    print CONF $line;
+  }
+
+  # remove everything up to next login or EOF
+  while ($line = shift @config) {
+    last if ($line =~ /^\[/);
+  }
+
+  # this one is either the next login or EOF
+  print CONF $line;
+
+  while ($line = shift @config) {
+    print CONF $line;
+  }
+
+  print CONF qq|[$self->{login}]\n|;
+  
+  if ((($self->{dbpasswd} ne $self->{old_dbpasswd}) || $newmember) && $self->{root}) {
+    $self->{dbpasswd} = pack 'u', $self->{dbpasswd};
+    chop $self->{dbpasswd};
+  }
+  
+  if ($self->{password} ne $self->{old_password}) {
+    $self->{password} = crypt $self->{password}, substr($self->{login}, 0, 2) if $self->{password};
+  }
+  
+  if ($self->{'root login'}) {
+    @config = ("password");
+  } else {
+    @config = &config_vars;
+  }
+  
+  # replace \r\n with \n
+  $self->{address} =~ s/\r\n/\\n/g if $self->{address};
+  $self->{signature} =~ s/\r\n/\\n/g if $self->{signature};
+
+  foreach $key (sort @config) {
+    print CONF qq|$key=$self->{$key}\n|;
+  }
+
+  print CONF "\n";
+  close CONF;
+  unlink "${memberfile}.LCK";
+  
+  # create conf file
+  $self->create_config("$userspath/$self->{login}.conf") unless $self->{'root login'};
+}
+
+
+sub config_vars {
+  
+  my @conf = qw(acs address admin businessnumber charset company countrycode
+             currency dateformat dbconnect dbdriver dbhost dbport dboptions
+            dbname dbuser dbpasswd email fax name numberformat password
+            printer sid shippingpoint signature stylesheet tel templates
+            vclimit);
+
+  @conf;
+
+}
+
+
+sub error {
+  my ($self, $msg) = @_;
+
+  if ($ENV{HTTP_USER_AGENT}) {
+    print qq|Content-Type: text/html
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+
+<body bgcolor=ffffff>
+
+<h2><font color=red>Error!</font></h2>
+<p><b>$msg</b>|;
+
+  }
+  
+  die "Error: $msg\n";
+  
+}
+
+
+1;
+
diff --git a/sql-ledger/VERSION b/sql-ledger/VERSION
new file mode 100644 (file)
index 0000000..815e68d
--- /dev/null
@@ -0,0 +1 @@
+2.0.8
diff --git a/sql-ledger/am.pl b/sql-ledger/am.pl
new file mode 100755 (executable)
index 0000000..f69a15a
--- /dev/null
@@ -0,0 +1,126 @@
+#!/usr/bin/perl
+#
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#######################################################################
+#
+# this script is the frontend called from bin/$terminal/$script
+# all the accounting modules are linked to this script which in
+# turn execute the same script in bin/$terminal/
+#
+#######################################################################
+
+# setup defaults, these are overidden by sql-ledger.conf
+# DO NOT CHANGE
+$userspath = "users";
+$templates = "templates";
+$memberfile = "users/members";
+$sendmail = "| /usr/sbin/sendmail -t";
+########## end ###########################################
+
+
+$| = 1;
+
+use SL::Form;
+
+eval { require "sql-ledger.conf"; };
+
+
+$form = new Form;
+
+
+# name of this script
+$0 =~ tr/\\/\//;
+$pos = rindex $0, '/';
+$script = substr($0, $pos + 1);
+
+# we use $script for the language module
+$form->{script} = $script;
+# strip .pl for translation files
+$script =~ s/\.pl//;
+
+# pull in DBI
+use DBI;
+
+# check for user config file, could be missing or ???
+eval { require("$userspath/$form->{login}.conf"); };
+if ($@) {
+  $locale = new Locale "$language", "$script";
+  
+  $form->{callback} = "";
+  $msg1 = $locale->text('You are logged out!');
+  $msg2 = $locale->text('Login');
+  $form->redirect("$msg1 <p><a href=login.pl target=_top>$msg2</a>");
+}
+
+
+$myconfig{dbpasswd} = unpack 'u', $myconfig{dbpasswd};
+map { $form->{$_} = $myconfig{$_} } qw(stylesheet charset) unless (($form->{action} eq "save") && ($form->{type} eq 'preferences'));
+
+
+# locale messages
+$locale = new Locale "$myconfig{countrycode}", "$script";
+
+
+# check password
+$form->error($locale->text('Incorrect Password!')) if ($form->{password} ne $myconfig{password});
+
+$form->{path} =~ s/\.\.\///g;
+if ($form->{path} !~ /^bin\//) {
+  $form->error($locale->text('Invalid path!')."\n");
+}
+
+# did sysadmin lock us out
+if (-e "$userspath/nologin") {
+  $form->error($locale->text('System currently down for maintenance!'));
+}
+
+
+# pull in the main code
+require "$form->{path}/$form->{script}";
+
+# customized scripts
+if (-f "$form->{path}/custom_$form->{script}") {
+  eval { require "$form->{path}/custom_$form->{script}"; };
+  $form->error($@) if ($@);
+}
+
+# customized scripts for login
+if (-f "$form->{path}/$form->{login}_$form->{script}") {
+  eval { require "$form->{path}/$form->{login}_$form->{script}"; };
+  $form->error($@) if ($@);
+}
+
+if ($form->{action}) {
+  # window title bar, user info
+  $form->{titlebar} = "SQL-Ledger ".$locale->text('Version'). " $form->{version} - $myconfig{name} - $myconfig{dbname}";
+
+  &{ $locale->findsub($form->{action}) };
+} else {
+  $form->error($locale->text('action= not defined!'));
+}
+
+
+# end
+
diff --git a/sql-ledger/bin/lynx/menu.pl b/sql-ledger/bin/lynx/menu.pl
new file mode 100644 (file)
index 0000000..5599716
--- /dev/null
@@ -0,0 +1,128 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors: Christopher Browne
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#######################################################################
+#
+# menu for text based browsers (lynx)
+#
+# CHANGE LOG:
+#   DS. 2000-07-04  Created
+#   DS. 2001-08-07  access control
+#   CBB 2002-02-09  Refactored HTML out to subroutines
+#######################################################################
+
+$menufile = "menu.ini";
+use SL::Menu;
+
+
+1;
+# end of main
+
+
+
+sub display {
+
+  $menu = new Menu "$menufile";
+  
+  @menuorder = $menu->access_control(\%myconfig);
+
+  $form->{title} = "SQL-Ledger $form->{version}";
+  
+  $form->header;
+
+  $offset = int (21 - $#menuorder)/2;
+
+  print "<pre>";
+  print "\n" x $offset;
+  print "</pre>";
+
+  print qq|<center><table>|;
+
+  map { print "<tr><td>".$menu->menuitem(\%myconfig, \%$form, $_).$locale->text($_).qq|</a></td></tr>|; } @menuorder;
+
+  print qq'
+</table>
+
+</body>
+</html>
+';
+
+  # display the company logo
+#  $argv = "login=$form->{login}&password=$form->{password}&path=$form->{path}&action=company_logo&noheader=1";
+#  exec "./login.pl", $argv;
+  
+}
+
+
+sub section_menu {
+
+  $menu = new Menu "$menufile", $form->{level};
+  
+  # build tiered menus
+  @menuorder = $menu->access_control(\%myconfig, $form->{level});
+
+  foreach $item (@menuorder) {
+    $a = $item;
+    $item =~ s/^$form->{level}--//;
+    push @neworder, $a unless ($item =~ /--/);
+  }
+  @menuorder = @neworder;
+  $level = $form->{level};
+  $level =~ s/--/ /g;
+
+  $form->{title} = $locale->text($level);
+  
+  $form->header;
+
+  $offset = int (21 - $#menuorder)/2;
+  print "<pre>";
+  print "\n" x $offset;
+  print "</pre>";
+  
+  print qq|<center><table>|;
+
+  foreach $item (@menuorder) {
+    $label = $item;
+    $label =~ s/$form->{level}--//g;
+
+    # remove target
+    $menu->{$item}{target} = "";
+
+    print "<tr><td>".$menu->menuitem(\%myconfig, \%$form, $item, $form->{level}).$locale->text($label)."</a></td></tr>";
+  }
+  
+  print qq'</table>
+
+</body>
+</html>
+';
+
+}
+
+
+sub acc_menu {
+  
+  &section_menu;
+  
+}
+
diff --git a/sql-ledger/bin/mozilla/admin.pl b/sql-ledger/bin/mozilla/admin.pl
new file mode 100644 (file)
index 0000000..39247b5
--- /dev/null
@@ -0,0 +1,1504 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# setup module
+# add/edit/delete users
+#
+#======================================================================
+
+$menufile = "menu.ini";
+
+use SL::Form;
+use SL::User;
+
+
+$form = new Form;
+
+$locale = new Locale $language, "admin";
+  
+eval { require DBI; };
+$form->error($locale->text('DBI not installed!')) if ($@);
+
+
+# customization
+if (-f "$form->{path}/custom_$form->{script}") {
+  eval { require "$form->{path}/custom_$form->{script}"; };
+  $form->error($@) if ($@);
+}
+
+
+if (-f "css/sql-ledger.css") {
+  $form->{stylesheet} = "sql-ledger.css";
+}
+
+
+if ($form->{action}) {
+
+  $subroutine = $locale->findsub($form->{action});
+  
+  if ($subroutine eq 'login') {
+    if ($form->{rpw}) {
+      $form->{rpw} = crypt $form->{rpw}, "ro";
+    }
+  }
+  
+  &check_password;
+  
+  &$subroutine;
+    
+} else {
+
+  # if there are no drivers bail out
+  $form->error($locale->text('No Database Drivers available!')) unless (User->dbdrivers);
+
+  # create memberfile
+  if (! -f $memberfile) {
+    open(FH, ">$memberfile") or $form->error("$memberfile : $!");
+    print FH qq|# SQL-Ledger Accounting members
+
+[root login]
+password=
+
+|;
+    close(FH);
+  }
+
+  &adminlogin;
+
+}
+
+1;
+# end
+
+
+sub adminlogin {
+
+  $form->{title} = qq|SQL-Ledger $form->{version} |.$locale->text('Administration');
+
+  $form->header;
+  
+  print qq|
+<body class=admin>
+
+
+<div align=center>
+
+<a href="http://www.sql-ledger.org"><img src=sql-ledger.png border=0></a>
+<h1 class=login>|.$locale->text('Version').qq| $form->{version}<p>|.$locale->text('Administration').qq|</h1>
+
+<form method=post action="$form->{script}">
+
+<table>
+  <tr>
+    <th>|.$locale->text('Password').qq|</th>
+    <td><input type=password name=rpw></td>
+    <td><input type=submit class=submit name=action value="|.$locale->text('Login').qq|"></td>
+  </tr>
+<input type=hidden name=action value=login>
+<input type=hidden name=root value="root login">
+<input type=hidden name=path value=$form->{path}>
+</table>
+
+
+</form>
+
+<a href=http://www.sql-ledger.org>SQL-Ledger |.$locale->text('website').qq|</a>
+
+</div>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+
+sub login {
+
+  &list_users;
+
+}
+
+
+
+sub add_user {
+  
+  $form->{title} = "SQL-Ledger ".$locale->text('Accounting')." ".$locale->text('Administration')." / ".$locale->text('Add User');
+
+  $form->{Oracle_sid} = $sid;
+  $form->{Oracle_dbport} = '1521';
+  $form->{Oracle_dbhost} = `hostname`;
+
+  if (-f "css/sql-ledger.css") {
+    $myconfig->{stylesheet} = "sql-ledger.css";
+  }
+  $myconfig->{vclimit} = 200;
+  
+  &form_header;
+  &form_footer;
+  
+}
+
+
+
+sub edit {
+
+  $form->{title} = "SQL-Ledger ".$locale->text('Accounting')." ".$locale->text('Administration')." / ".$locale->text('Edit User');
+  $form->{edit} = 1;
+
+  &form_header;
+  &form_footer;
+
+}
+
+
+sub form_footer {
+
+  if ($form->{edit}) {
+    $delete = qq|<input type=submit class=submit name=action value="|.$locale->text('Delete').qq|">
+<input type=hidden name=edit value=1>|;
+  }
+
+  print qq|
+
+<input name=callback type=hidden value="$form->{script}?action=list_users&path=$form->{path}&root=$form->{root}&rpw=$form->{rpw}">
+<input type=hidden name=root value="$form->{root}">
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=rpw value=$form->{rpw}>
+
+<input type=submit class=submit name=action value="|.$locale->text('Save').qq|">
+$delete
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub list_users {
+
+  $form->error("$memberfile : ".$locale->text('locked!')) if (-f "${memberfile}.LCK");
+
+  open(FH, "$memberfile") or $form->error("$memberfile : $!");
+  
+  while (<FH>) {
+    chop;
+    
+    if (/^\[.*\]/) {
+      $login = $_;
+      $login =~ s/(\[|\])//g;
+    }
+
+    if (/^(name=|company=|templates=|dbuser=|dbdriver=|dbname=|dbhost=)/) {
+      chop ($var = $&);
+      ($null, $member{$login}{$var}) = split /=/, $_, 2;
+    }
+  }
+  
+  close(FH);
+
+# type=submit $locale->text('Pg Database Administration')
+# type=submit $locale->text('Oracle Database Administration')
+
+  foreach $item (User->dbdrivers) {
+    $dbdrivers .= qq|<input name=action type=submit class=submit value="|.$locale->text("$item Database Administration").qq|">|;
+  }
+
+
+  $column_header{login} = qq|<th>|.$locale->text('Login').qq|</th>|;
+  $column_header{name} = qq|<th>|.$locale->text('Name').qq|</th>|;
+  $column_header{company} = qq|<th>|.$locale->text('Company').qq|</th>|;
+  $column_header{dbdriver} = qq|<th>|.$locale->text('Driver').qq|</th>|;
+  $column_header{dbhost} = qq|<th>|.$locale->text('Host').qq|</th>|;
+  $column_header{dataset} = qq|<th>|.$locale->text('Dataset').qq|</th>|;
+  $column_header{templates} = qq|<th>|.$locale->text('Templates').qq|</th>|;
+
+  @column_index = qw(login name company dbdriver dbhost dataset templates);
+
+  $form->{title} = "SQL-Ledger ".$locale->text('Accounting')." ".$locale->text('Administration');
+
+  $form->header;
+
+  print qq|
+<body class=admin>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr>
+  <tr class=listheading>
+    <th>$form->{title}</th>
+  </tr>
+  <tr size=5></tr>
+  <tr>
+    <td>
+      <table width=100%>
+        <tr class=listheading>|;
+
+  map { print "$column_header{$_}\n" } @column_index;
+  
+  print qq|
+        </tr>
+|;
+
+foreach $key (sort keys %member) {
+  $href = "$script?action=edit&login=$key&path=$form->{path}&root=$form->{root}&rpw=$form->{rpw}";
+  $href =~ s/ /%20/g;
+  
+  $member{$key}{templates} =~ s/^$templates\///;
+  $member{$key}{dbhost} = $locale->text('localhost') unless $member{$key}{dbhost};
+  $member{$key}{dbname} = $member{$key}{dbuser} if ($member{$key}{dbdriver} eq 'Oracle');
+
+  $column_data{login} = qq|<td><a href=$href>$key</a></td>|;
+  $column_data{name} = qq|<td>$member{$key}{name}</td>|;
+  $column_data{company} = qq|<td>$member{$key}{company}</td>|;
+  $column_data{dbdriver} = qq|<td>$member{$key}{dbdriver}</td>|;
+  $column_data{dbhost} = qq|<td>$member{$key}{dbhost}</td>|;
+  $column_data{dataset} = qq|<td>$member{$key}{dbname}</td>|;
+  $column_data{templates} = qq|<td>$member{$key}{templates}</td>|;
+  
+  $i++; $i %= 2;
+  print qq|
+        <tr class=listrow$i>|;
+
+  map { print "$column_data{$_}\n" } @column_index;
+
+  print qq|
+        </tr>|;
+}
+
+
+print qq|
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=rpw value=$form->{rpw}>
+<input type=hidden name=root value="$form->{root}">
+
+<br><input type=submit class=submit name=action value="|.$locale->text('Add User').qq|">
+<input type=submit class=submit name=action value="|.$locale->text('Change Admin Password').qq|">
+
+$dbdrivers
+
+</form>
+
+|.$locale->text('Click on login name to edit!').qq|
+<br>
+|.$locale->text('To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.').qq|
+
+<p>
+
+<form method=post action=login.pl>
+
+<table border=0 width=100%>
+  <tr class=listheading>
+    <th>SQL-Ledger |.$locale->text('Accounting')." ".$locale->text('Login').qq|</th>
+  </tr>
+  <tr>
+    <td>
+      <table>
+        <tr>
+         <th align=right>|.$locale->text('Name').qq|</th>
+         <td><input class=login name=login></td>
+         <td>&nbsp;</td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Password').qq|</th>
+         <td><input class=login type=password name=password></td>
+         <td><input type=submit name=action value="|.$locale->text('Login').qq|"></td>
+       </tr>
+<input type=hidden name=path value=$form->{path}>
+      </table>
+    </td>
+  </tr>
+</table>
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+
+sub form_header {
+
+  # if there is a login, get user
+  if ($form->{login}) {
+    # get user
+    $myconfig = new User "$memberfile", "$form->{login}";
+
+    $myconfig->{signature} =~ s/\\n/\r\n/g;
+    $myconfig->{address} =~ s/\\n/\r\n/g;
+
+    # strip basedir from templates directory
+    $myconfig->{templates} =~ s/^$templates\///;
+
+    $myconfig->{dbpasswd} = unpack 'u', $myconfig->{dbpasswd};
+  }
+
+
+  foreach $item (qw(mm-dd-yy mm/dd/yy dd-mm-yy dd/mm/yy dd.mm.yy yyyy-mm-dd)) {
+    $dateformat .= ($item eq $myconfig->{dateformat}) ? "<option selected>$item\n" : "<option>$item\n";
+  }
+
+  foreach $item (qw(1,000.00 1000.00 1.000,00 1000,00)) {
+    $numberformat .= ($item eq $myconfig->{numberformat}) ? "<option selected>$item\n" : "<option>$item\n";
+  }
+
+
+  %countrycodes = User->country_codes;
+  $countrycodes = "";
+  foreach $key (sort { $countrycodes{$a} cmp $countrycodes{$b} } keys %countrycodes) {
+    $countrycodes .= ($myconfig->{countrycode} eq $key) ? "<option selected value=$key>$countrycodes{$key}" : "<option value=$key>$countrycodes{$key}";
+  }
+  $countrycodes = qq|<option value="">American English\n$countrycodes|;
+
+  # is there a templates basedir
+  if (! -d "$templates") {
+    $form->error($locale->text('Directory').": $templates ".$locale->text('does not exist'));
+  }
+
+  opendir TEMPLATEDIR, "$templates/." or $form->error("$templates : $!");
+  @all = grep !/^\.\.?$/, readdir TEMPLATEDIR;
+  closedir TEMPLATEDIR;
+
+  @allhtml = sort grep /\.html/, @all;
+  @alldir = grep !/\.(html|tex)$/, @all;
+  
+  @allhtml = reverse grep !/Default/, @allhtml;
+  push @allhtml, 'Default';
+  @allhtml = reverse @allhtml;
+  
+  foreach $item (@alldir) {
+    if ($item eq $myconfig->{templates}) {
+      $usetemplates .= qq|<option selected>$item\n|;
+    } else {
+      $usetemplates .= qq|<option>$item\n|;
+    }
+  }
+  
+  $lastitem = $allhtml[0];
+  $lastitem =~ s/-.*//g;
+  $mastertemplates = qq|<option>$lastitem\n|;
+  foreach $item (@allhtml) {
+    $item =~ s/-.*//g;
+    
+    if ($item ne $lastitem) {
+      $mastertemplates .= qq|<option>$item\n|;
+      $lastitem = $item;
+    }
+  }
+
+  
+  $form->header;
+  print qq|
+<body class=admin>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr class=listheading><th colspan=2>$form->{title}</th></tr>
+  <tr size=5></tr>
+  <tr valign=top>
+    <td>
+      <table>
+       <tr>
+         <th align=right>|.$locale->text('Login').qq|</th>
+         <td><input name=login value="$myconfig->{login}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Password').qq|</th>
+         <td><input type=password name=password size=8 value=$myconfig->{password}></td>
+         <input type=hidden name=old_password value=$myconfig->{password}>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Name').qq|</th>
+         <td><input name=name size=15 value="$myconfig->{name}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('E-mail').qq|</th>
+         <td><input name=email size=30 value="$myconfig->{email}"></td>
+       </tr>
+       <tr valign=top>
+         <th align=right>|.$locale->text('Signature').qq|</th>
+         <td><textarea name=signature rows=3 cols=35>$myconfig->{signature}</textarea></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Phone').qq|</th>
+         <td><input name=tel size=14 value="$myconfig->{tel}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Fax').qq|</th>
+         <td><input name=fax size=14 value="$myconfig->{fax}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Company').qq|</th>
+         <td><input name=company size=35 value="$myconfig->{company}"></td>
+       </tr>
+       <tr valign=top>
+         <th align=right>|.$locale->text('Address').qq|</th>
+         <td><textarea name=address rows=4 cols=35>$myconfig->{address}</textarea></td>
+       </tr>
+      </table>
+    </td>
+    <td>
+      <table>
+       <tr>
+         <th align=right>|.$locale->text('Date Format').qq|</th>
+         <td><select name=dateformat>$dateformat</select></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Number Format').qq|</th>
+         <td><select name=numberformat>$numberformat</select></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Dropdown Limit').qq|</th>
+         <td><input name=vclimit value="$myconfig->{vclimit}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Language').qq|</th>
+         <td><select name=countrycode>$countrycodes</select></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Character Set').qq|</th>
+         <td><input name=charset value="$myconfig->{charset}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Stylesheet').qq|</th>
+         <td><input name=userstylesheet value="$myconfig->{stylesheet}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Printer').qq|</th>
+         <td><input name=printer size=20 value="$myconfig->{printer}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Ship via').qq|</th>
+         <td><input name=shippingpoint size=15 value="$myconfig->{shippingpoint}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Use Templates').qq|</th>
+         <td><select name=usetemplates>$usetemplates</select></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('New Templates').qq|</th>
+         <td><input name=newtemplates></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Setup Templates').qq|</th>
+         <td><select name=mastertemplates>$mastertemplates</select></td>
+       </tr>
+       <input type=hidden name=templates value=$myconfig->{templates}>
+      </table>
+    </td>
+  </tr>
+  <tr class=listheading>
+    <th colspan=2>|.$locale->text('Database').qq|</th>
+  </tr>|;
+
+    # list section for database drivers
+    foreach $item (User->dbdrivers) {
+      
+    print qq|
+  <tr>
+    <td colspan=2>
+      <table>
+       <tr>|;
+
+    $checked = "";
+    if ($myconfig->{dbdriver} eq $item) {
+      map { $form->{"${item}_$_"} = $myconfig->{$_} } qw(dbhost dbport dbuser dbpasswd dbname sid);
+      $checked = "checked";
+    }
+
+    print qq|
+         <th align=right>|.$locale->text('Driver').qq|</th>
+         <td><input name=dbdriver type=radio class=radio value=$item $checked>&nbsp;$item</td>
+         <th align=right>|.$locale->text('Host').qq|</th>
+         <td><input name="${item}_dbhost" value=$form->{"${item}_dbhost"}></td>
+       </tr>
+       <tr>|;
+
+    if ($item eq 'Pg') {
+      print qq|
+         <th align=right>|.$locale->text('Dataset').qq|</th>
+         <td><input name=Pg_dbname size=10 value=$form->{Pg_dbname}></td>
+         <th align=right>|.$locale->text('Port').qq|</th>
+         <td><input name=Pg_dbport size=4 value=$form->{Pg_dbport}></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('User').qq|</th>
+         <td><input name="${item}_dbuser" size=10 value=$form->{"${item}_dbuser"}></td>
+         <th align=right>|.$locale->text('Password').qq|</th>
+         <td><input name="${item}_dbpasswd" type=password size=10 value=$form->{"${item}_dbpasswd"}></td>
+       </tr>|;
+
+    }
+
+    if ($item eq 'Oracle') {
+      print qq|
+         <th align=right>SID</th>
+         <td><input name=Oracle_sid value=$form->{Oracle_sid}></td>
+         <th align=right>|.$locale->text('Port').qq|</th>
+         <td><input name=Oracle_dbport size=4 value=$form->{Oracle_dbport}></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Dataset').qq|</th>
+         <td><input name="${item}_dbuser" size=10 value=$form->{"${item}_dbuser"}></td>
+         <th align=right>|.$locale->text('Password').qq|</th>
+         <td><input name="${item}_dbpasswd" type=password size=10 value=$form->{"${item}_dbpasswd"}></td>
+         
+       </tr>|;
+    }
+    
+      
+    print qq|
+       <input type=hidden name=old_dbpasswd value=$myconfig->{dbpasswd}>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td colspan=2><hr size=2 noshade></td>
+  </tr>
+|;
+
+  }
+
+
+  # access control
+  open(FH, $menufile) or $form->error("$menufile : $!");
+  # scan for first menu level
+  @a = <FH>;
+  close(FH);
+  
+  if (open(FH, "custom_$menufile")) {
+    push @a, <FH>;
+  }
+  close(FH);
+
+  foreach $item (@a) {
+    next unless $item =~ /\[/;
+    next if $item =~ /\#/;
+
+    $item =~ s/(\[|\])//g;
+    chop $item;
+
+    if ($item =~ /--/) {
+      ($level, $menuitem) = split /--/, $item, 2;
+    } else {
+      $level = $item;
+      $menuitem = $item;
+      push @acsorder, $item;
+    }
+
+    push @{ $acs{$level} }, $menuitem;
+
+  }
+  
+  $admincheck = "checked" if $myconfig->{admin};
+  
+  print qq|
+  <tr class=listheading>
+    <th colspan=2>|.$locale->text('Access Control').qq|</th>
+  </tr>
+  <tr>
+    <td><input name=admin type=checkbox class=checkbox value=1 $admincheck>&nbsp;<b>|.$locale->text('Administrator').qq|</b></td>
+  </tr>
+|;
+  
+  foreach $item (split /;/, $myconfig->{acs}) {
+    ($key, $value) = split /--/, $item, 2;
+    $excl{$key}{$value} = 1;
+  }
+  
+  foreach $key (@acsorder) {
+
+    $checked = "checked";
+    if ($form->{login}) {
+      $checked = ($excl{$key}{$key}) ? "" : "checked";
+    }
+    
+    # can't have variable names with spaces
+    # the 1 is for apache 2
+    $item = $form->escape("${key}--$key", 1);
+    
+    $acsheading = $key;
+    $acsheading =~ s/ /&nbsp;/g;
+    
+    $acsheading = qq|
+    <th align=left><input name="$item" class=checkbox type=checkbox value=1 $checked>&nbsp;$acsheading</th>\n|;
+    $menuitems .= "$item;";
+    $acsdata = "
+    <td>";
+
+    foreach $item (@{ $acs{$key} }) {
+      next if ($key eq $item);
+
+      $checked = "checked";
+      if ($form->{login}) {
+       $checked = ($excl{$key}{$item}) ? "" : "checked";
+      }
+
+      $acsitem = $form->escape("${key}--$item", 1);
+      
+      $acsdata .= qq|
+    <br><input name="$acsitem" class=checkbox type=checkbox value=1 $checked>&nbsp;$item|;
+      $menuitems .= "$acsitem;";
+    }
+
+    $acsdata .= "
+    </td>";
+
+    print qq|
+  <tr valign=top>$acsheading $acsdata
+  </tr>
+|;
+  }
+  
+  print qq|<input type=hidden name=acs value="$menuitems">
+  
+   <tr>
+    <td colspan=2><hr size=3 noshade></td>
+  </tr>
+  <tr>
+    <td>
+    </td>
+  </tr>
+</table>
+|;
+
+}
+
+
+sub save {
+
+  # no driver checked
+  $form->error($locale->text('Database Driver not checked!')) unless $form->{dbdriver};
+
+  # no spaces allowed in login name
+  ($form->{login}) = split / /, $form->{login};
+  
+  # check for duplicates
+  if (!$form->{edit}) {
+    $temp = new User "$memberfile", "$form->{login}";
+   
+    if ($temp->{login}) {
+      $form->error("$form->{login} ".$locale->text('is already a member!'));
+    }
+  }
+  
+  # does stylesheet exist
+  if ($form->{userstylesheet}) {
+    $form->error($locale->text('Stylesheet').": css/$form->{userstylesheet} ".$locale->text('does not exist')) unless (-f "css/$form->{userstylesheet}");
+  }
+  
+  # no spaces allowed in directories
+  ($form->{newtemplates}) = split / /, $form->{newtemplates};
+  
+  if ($form->{newtemplates}) {
+    $form->{templates} = $form->{newtemplates};
+  } else {
+    $form->{templates} = ($form->{usetemplates}) ? $form->{usetemplates} : $form->{login};
+  }
+  
+  
+  # is there a basedir
+  if (! -d "$templates") {
+    $form->error($locale->text('Directory').": $templates ".$locale->text('does not exist'));
+  }
+
+  # add base directory to $form->{templates}
+  $form->{templates} = "$templates/$form->{templates}";
+
+
+  $myconfig = new User "$memberfile", "$form->{login}";
+
+  # redo acs variable and delete all the acs codes
+  @acs = split /;/, $form->{acs};
+
+  $form->{acs} = "";
+  foreach $item (@acs) {
+    $item = $form->escape($item, 1);
+
+    if (!$form->{$item}) {
+      $form->{acs} .= $form->unescape($form->unescape($item)).";";
+    }
+    delete $form->{$item};
+  }
+
+  # check which database was filled in
+  if ($form->{dbdriver} eq 'Oracle') {
+    $form->{sid} = $form->{Oracle_sid}, ;
+    $form->{dbhost} = $form->{Oracle_dbhost}, ;
+    $form->{dbport} = $form->{Oracle_dbport};
+    $form->{dbpasswd} = $form->{Oracle_dbpasswd};
+    $form->{dbuser} = $form->{Oracle_dbuser};
+    $form->{dbname} = $form->{Oracle_dbuser};
+
+    $form->isblank("dbhost", $locale->text('Hostname missing!'));
+    $form->isblank("dbport", $locale->text('Port missing!'));
+    $form->isblank("dbuser", $locale->text('Dataset missing!'));
+  }
+  if ($form->{dbdriver} eq 'Pg') {
+    $form->{dbhost} = $form->{Pg_dbhost};
+    $form->{dbport} = $form->{Pg_dbport};
+    $form->{dbpasswd} = $form->{Pg_dbpasswd};
+    $form->{dbuser} = $form->{Pg_dbuser};
+    $form->{dbname} = $form->{Pg_dbname};
+    
+    $form->isblank("dbname", $locale->text('Dataset missing!'));
+    $form->isblank("dbuser", $locale->text('Database User missing!'));
+  }
+    
+  # set admin
+  $form->{admin} = "" unless $form->{admin};
+  
+  foreach $item (keys %{$form}) {
+    $myconfig->{$item} = $form->{$item};
+  }
+
+  delete $myconfig->{stylesheet};
+  if ($form->{userstylesheet}) {
+    $myconfig->{stylesheet} = $form->{userstylesheet};
+  }
+  
+  $myconfig->save_member($memberfile, $userspath);
+
+  # create user template directory and copy master files
+  if (! -d "$form->{templates}") {
+    umask(002);
+    
+    if (mkdir "$form->{templates}", oct("771")) {
+      
+      umask(007);
+      
+      # copy templates to the directory
+      opendir TEMPLATEDIR, "$templates/." or $form-error("$templates : $!");
+      @templates = grep /$form->{mastertemplates}.*?\.(html|tex)$/, readdir TEMPLATEDIR;
+      closedir TEMPLATEDIR;
+
+      foreach $file (@templates) {
+       open(TEMP, "$templates/$file") or $form->error("$templates/$file : $!");
+       
+       $file =~ s/$form->{mastertemplates}-//;
+       open(NEW, ">$form->{templates}/$file") or $form->error("$form->{templates}/$file : $!");
+         
+       while ($line = <TEMP>) {
+         print NEW $line;
+       }
+       close(TEMP);
+       close(NEW);
+      }
+    } else {
+      $form->error("$!: $form->{templates}");
+    }
+  }
+
+  $form->redirect($locale->text('User saved!'));
+  
+}
+
+
+sub delete {
+
+  $form->{templates} = ($form->{templates}) ? "$templates/$form->{templates}" : "$templates/$form->{login}";
+  
+  $form->error("$memberfile : ".$locale->text('locked!')) if (-f ${memberfile}.LCK);
+  open(FH, ">${memberfile}.LCK") or $form->error("${memberfile}.LCK : $!");
+  close(FH);
+  
+  open(CONF, "+<$memberfile") or $form->error("$memberfile : $!");
+
+  @config = <CONF>;
+
+  seek(CONF, 0, 0);
+  truncate(CONF, 0);
+  
+  while ($line = shift @config) {
+
+    if ($line =~ /^\[/) {
+      last if ($line =~ /\[$form->{login}\]/);
+      $login = &login_name($line);
+    }
+    
+    if ($line =~ /^templates=/) {
+      $user{$login} = &get_value($line);
+    }
+
+    print CONF $line;
+  }
+
+  # remove everything up to next login or EOF
+  # and save template variable
+  while ($line = shift @config) {
+    if ($line =~ /^templates=/) {
+      $templatedir = &get_value($line);
+    }
+    last if ($line =~ /^\[/);
+  }
+
+  # this one is either the next login or EOF
+  print CONF $line;
+
+  $login = &login_name($line);
+  
+
+  while ($line = shift @config) {
+    if ($line =~ /^\[/) {
+      $login = &login_name($line);
+    }
+    
+    if ($line =~ /^templates=/) {
+      $user{$login} = &get_value($line);
+    }
+    
+    print CONF $line;
+  }
+
+  close(CONF);
+  unlink "${memberfile}.LCK";
+
+  # scan %user for $templatedir
+  foreach $login (keys %user) {
+    last if ($found = ($templatedir eq $user{$login}));
+  }
+
+  # if found keep directory otherwise delete
+  if (!$found) {
+    # delete it if there is a template directory
+    $dir = "$form->{templates}";
+    if (-d "$dir") {
+      unlink <$dir/*.html>;
+      unlink <$dir/*.tex>;
+      rmdir "$dir";
+    }
+  }
+  
+  # delete config file for user
+  unlink "$userspath/$form->{login}.conf";
+    
+  $form->redirect($locale->text('User deleted!'));
+  
+}
+
+
+sub login_name {
+  my $login = shift;
+  
+  $login =~ s/\[\]//g;
+  return ($login) ? $login : undef;
+  
+}
+
+
+
+sub get_value {
+  my $line = shift;
+  
+  my ($null, $value) = split(/=/, $line, 2);
+
+  # remove comments
+  $value =~ s/\s#.*//g;
+      
+  # remove any trailing whitespace
+  $value =~ s/^\s*(.*?)\s*$/$1/;
+
+  $value;
+}
+
+
+
+sub change_admin_password {
+
+  $form->{title} = qq|SQL-Ledger |.$locale->text('Accounting')." ".$locale->text('Administration')." / ".$locale->text('Change Admin Password');
+  
+  $form->header;
+
+  print qq|
+<body class=admin>
+
+
+<h2>|.$locale->text('Change Admin Password').qq|</h2>
+
+<form method=post action=$form->{script}>
+
+<b>|.$locale->text('Password').qq|</b> <input type=password name=password size=8>
+
+<input type=hidden name=root value="$form->{root}">
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=rpw value=$form->{rpw}>
+
+<p>
+<input type=submit class=submit name=action value="|.$locale->text('Change Password').qq|">
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub change_password {
+
+  $root->{password} = $form->{password};
+  
+  $root->{'root login'} = 1;
+  $root->save_member($memberfile);
+
+  $form->{callback} = "$form->{script}?action=list_users&path=$form->{path}&root=$form->{root}&rpw=$root->{password}";
+
+  $form->redirect($locale->text('Password changed!'));
+
+}
+
+
+sub check_password {
+
+  $root = new User "$memberfile", $form->{root};
+
+  if ($root->{password}) {
+    if ($root->{password} ne $form->{rpw}) {
+      $form->error($locale->text('Incorrect Password!'));
+    }
+  }
+
+}
+
+
+sub pg_database_administration {
+
+  $form->{dbdriver} = 'Pg';
+  &dbselect_source;
+
+}
+
+
+sub oracle_database_administration {
+  
+  $form->{dbdriver} = 'Oracle';
+  &dbselect_source;
+
+}
+
+
+sub dbdriver_defaults {
+
+  # load some defaults for the selected driver
+  %driverdefaults = ( 'Pg' => { dbport => '',
+                                dbuser => 'sql-ledger',
+                            dbdefault => 'template1',
+                               dbhost => '',
+                        connectstring => $locale->text('Connect to')
+                             },
+                  'Oracle' => { dbport => '1521',
+                               dbuser => 'oralin',
+                            dbdefault => $sid,
+                               dbhost => `hostname`,
+                        connectstring => 'SID'
+                             }
+                    );
+
+  map { $form->{$_} = $driverdefaults{$form->{dbdriver}}{$_} } keys %{ $driverdefaults{Pg} };
+  
+}
+  
+
+sub dbselect_source {
+
+  &dbdriver_defaults;
+
+  $msg{Pg} = $locale->text('Leave host and port field empty unless you want to make a remote connection.');
+  $msg{Oracle} = $locale->text('You must enter a host and port for local and remote connections!');
+  
+
+ $form->{title} = "SQL-Ledger ".$locale->text('Accounting')." / ".$locale->text('Database Administration');
+  
+
+  $form->header;
+
+  print qq|
+<body class=admin>
+
+
+<center>
+<h2>$form->{title}</h2>
+
+<form method=post action=$form->{script}>
+
+<table>
+<tr><td>
+
+<table>
+
+  <tr class=listheading>
+    <th colspan=4>|.$locale->text('Database').qq|</th>
+  </tr>
+
+<input type=hidden name=dbdriver value=$form->{dbdriver}>
+
+  <tr><td>
+   <table>
+
+  <tr>
+
+    <th align=right>|.$locale->text('Host').qq|</th>
+    <td><input name=dbhost size=25 value=$form->{dbhost}></td>
+    <th align=right>|.$locale->text('Port').qq|</th>
+    <td><input name=dbport size=5 value=$form->{dbport}></td>
+
+  </tr>
+
+  <tr>
+
+    <th align=right>|.$locale->text('User').qq|</th>
+    <td><input name=dbuser size=10 value=$form->{dbuser}></td>
+    <th align=right>|.$locale->text('Password').qq|</th>
+    <td><input type=password name=dbpasswd size=10></td>
+
+  </tr>
+  
+  <tr>
+
+    <th align=right>$form->{connectstring}</th>
+    <td colspan=3><input name=dbdefault size=10 value=$form->{dbdefault}></td>
+
+  </tr>
+
+</table>
+
+</td></tr>
+</table>
+
+<input name=callback type=hidden value="$form->{script}?action=list_users&path=$form->{path}&root=$form->{root}&rpw=$form->{rpw}">
+<input type=hidden name=root value="$form->{root}">
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=rpw value=$form->{rpw}>
+
+<hr size=3 noshade>
+<br>
+
+<input type=submit class=submit name=action value="|.$locale->text('Create Dataset').qq|">
+<input type=submit class=submit name=action value="|.$locale->text('Update Dataset').qq|">
+<input type=submit class=submit name=action value="|.$locale->text('Delete Dataset').qq|">
+
+</form>
+
+</td></tr>
+</table>
+
+<p>|.$locale->text('This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!')
+
+.qq|
+<br>$msg{$form->{dbdriver}}
+
+
+</body>
+</html>
+|;
+
+}
+
+
+sub continue {
+
+  &{ $form->{nextsub} };
+
+}
+
+
+sub update_dataset {
+
+  %needsupdate = User->dbneedsupdate(\%$form);
+
+  $form->{title} = "SQL-Ledger ".$locale->text('Accounting')." ".$locale->text('Database Administration')." / ".$locale->text('Update Dataset');
+  
+  $form->header;
+
+  print qq|
+<body class=admin>
+
+
+<center>
+<h2>$form->{title}</h2>
+|;
+
+
+  foreach $key (sort keys %needsupdate) {
+    if ($needsupdate{$key} lt $form->{dbversion}) {
+      $upd .= qq|<br><input name="db$key" type=checkbox value=1 checked> $key\n|;
+      $form->{dbupdate} .= "db$key ";
+    }
+  }
+
+  chop $form->{dbupdate};
+
+
+  if ($form->{dbupdate}) {
+
+    print qq|
+<table>
+<form method=post action=$form->{script}>
+
+<input type=hidden name=dbdriver value=$form->{dbdriver}>
+<input type=hidden name=dbhost value=$form->{dbhost}>
+<input type=hidden name=dbport value=$form->{dbport}>
+<input type=hidden name=dbuser value=$form->{dbuser}>
+<input type=hidden name=dbpasswd value=$form->{dbpasswd}>
+<input type=hidden name=dbdefault value=$form->{dbdefault}>
+
+<tr class=listheading>
+  <th>|.$locale->text('The following Datasets need to be updated').qq|</th>
+</tr>
+<tr>
+<td>
+
+$upd
+
+</td></tr>
+<tr><td>
+
+<input name=dbupdate type=hidden value="$form->{dbupdate}">
+
+<input name=callback type=hidden value="$form->{script}?action=list_users&path=$form->{path}&root=$form->{root}&rpw=$form->{rpw}">
+
+<input type=hidden name=root value="$form->{root}">
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=rpw value=$form->{rpw}>
+
+<input type=hidden name=nextsub value=dbupdate>
+
+<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|">
+
+</td></tr>
+</table>
+</form>
+|;
+
+  } else {
+
+    print $locale->text('All Datasets up to date!');
+
+  }
+  
+  print qq|
+
+</body>
+</html>
+|;
+
+}
+
+
+sub dbupdate {
+
+  User->dbupdate(\%$form);
+
+  $form->redirect($locale->text('Dataset updated!'));
+  
+}
+
+
+sub create_dataset {
+
+  foreach $item (sort User->dbsources(\%$form)) {
+    $dbsources .= "[$item] ";
+  }
+
+  opendir SQLDIR, "sql/." or $form-error($!);
+  foreach $item (sort grep /-chart\.sql/, readdir SQLDIR) {
+    next if ($item eq 'Default-chart.sql');
+    $item =~ s/-chart\.sql//;
+    push @charts, qq| <input name=chart class=radio type=radio value="$item">&nbsp;$item|;
+  }
+  closedir SQLDIR;
+
+  # add Default at beginning
+  @charts = (qq|<input name=chart class=radio type=radio value="Default" checked>&nbsp;Default|, @charts);
+
+  $selectencoding = qq|<option> 
+  <option value=SQL_ASCII>ASCII
+  <option value=EUC_JP>Japanese Extended UNIX Code
+  <option value=EUC_CN>Chinese Extended UNIX Code 
+  <option value=EUC_KR>Korean Extended UNIX Code
+  <option value=EUC_TW>Taiwan Extended UNIX Code
+  <option value=UNICODE>UTF-8 Unicode 
+  <option value=MULE_INTERNAL>Mule internal type
+  <option value=LATIN1>ISO 8859-1
+  <option value=LATIN2>ISO 8859-2 
+  <option value=LATIN3>ISO 8859-3
+  <option value=LATIN4>ISO 8859-4
+  <option value=LATIN5>ISO 8859-5
+  <option value=KOI8>KOI8-R
+  <option value=WIN>Windows CP1251
+  <option value=ALT>Windows CP866
+  |;
+  
+  $form->{title} = "SQL-Ledger ".$locale->text('Accounting')." ".$locale->text('Database Administration')." / ".$locale->text('Create Dataset');
+  
+  $form->header;
+
+  print qq|
+<body class=admin>
+
+
+<center>
+<h2>$form->{title}</h2>
+
+<form method=post action=$form->{script}>
+
+<table>
+  <tr class=listheading>
+    <th colspan=2>&nbsp;</th>
+  </tr>
+
+  <tr>
+
+    <th align=right nowrap>|.$locale->text('Existing Datasets').qq|</th>
+    <td>$dbsources</td>
+
+  </tr>
+  
+  <tr>
+
+    <th align=right nowrap>|.$locale->text('Create Dataset').qq|</th>
+    <td><input name=db></td>
+
+  </tr>
+  
+  <tr>
+
+    <th align=right nowrap>|.$locale->text('Multibyte Encoding').qq|</th>
+    <td><select name=encoding>$selectencoding</select></td>
+
+  </tr>
+  <tr>
+
+    <th align=right>|.$locale->text('Create Chart of Accounts').qq|</th>
+    <td>@charts</td>
+
+  </tr>
+  <tr><td colspan=2>
+<hr size=3 noshade>
+<br>
+<input type=hidden name=dbdriver value=$form->{dbdriver}>
+<input type=hidden name=dbuser value=$form->{dbuser}>
+<input type=hidden name=dbhost value=$form->{dbhost}>
+<input type=hidden name=dbport value=$form->{dbport}>
+<input type=hidden name=dbpasswd value=$form->{dbpasswd}>
+<input type=hidden name=dbdefault value=$form->{dbdefault}>
+
+<input name=callback type=hidden value="$form->{script}?action=list_users&path=$form->{path}&root=$form->{root}&rpw=$form->{rpw}">
+
+<input type=hidden name=root value="$form->{root}">
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=rpw value=$form->{rpw}>
+
+<input type=hidden name=nextsub value=dbcreate>
+
+<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|">
+
+  </td></tr>
+</table>
+
+</form>
+
+
+</body>
+</html>
+|;
+
+}
+
+
+sub dbcreate {
+
+  $form->isblank("db", $locale->text('Dataset missing!'));
+
+  User->dbcreate(\%$form);
+  
+  $form->{title} = "SQL-Ledger ".$locale->text('Accounting')." ".$locale->text('Database Administration')." / ".$locale->text('Create Dataset');
+
+  $form->header;
+
+  print qq|
+<body class=admin>
+
+
+<center>
+<h2>$form->{title}</h2>
+
+<form method=post action=$form->{script}>|
+
+.$locale->text('Dataset')." $form->{db} ".$locale->text('successfully created!')
+
+.qq|
+
+<input type=hidden name=root value="$form->{root}">
+<input type=hidden name=path value="$form->{path}">
+<input type=hidden name=rpw value="$form->{rpw}">
+
+<input type=hidden name=nextsub value=list_users>
+
+<p><input type=submit class=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+
+</body>
+</html>
+|;
+
+}
+
+
+sub delete_dataset {
+
+  if (@dbsources = User->dbsources_unused(\%$form, $memberfile)) {
+    foreach $item (sort @dbsources) {
+      $dbsources .= qq|<input name=db class=radio type=radio value=$item>&nbsp;$item\n<br>|;
+    }
+  } else {
+    $form->error($locale->text('Nothing to delete!'));
+  }
+
+  $form->{title} = "SQL-Ledger ".$locale->text('Accounting')." ".$locale->text('Database Administration')." / ".$locale->text('Delete Dataset');
+
+  $form->header;
+
+  print qq|
+<body class=admin>
+
+
+<center>
+<h2>$form->{title}</h2>
+
+<form method=post action=$form->{script}>
+
+<table>
+  <tr class=listheading>
+    <th>|.$locale->text('The following Datasets are not in use and can be deleted').qq|</th>
+  </tr>
+
+  <tr>
+    <td>
+    $dbsources
+    </td>
+  </tr>
+  
+  <tr><td>
+
+<hr size=3 noshade>
+<br>
+<input type=hidden name=dbdriver value=$form->{dbdriver}>
+<input type=hidden name=dbuser value=$form->{dbuser}>
+<input type=hidden name=dbhost value=$form->{dbhost}>
+<input type=hidden name=dbport value=$form->{dbport}>
+<input type=hidden name=dbpasswd value=$form->{dbpasswd}>
+<input type=hidden name=dbdefault value=$form->{dbdefault}>
+
+<input name=callback type=hidden value="$form->{script}?action=list_users&path=$form->{path}&root=$form->{root}&rpw=$form->{rpw}">
+
+<input type=hidden name=root value="$form->{root}">
+<input type=hidden name=path value="$form->{path}">
+<input type=hidden name=rpw value="$form->{rpw}">
+
+<input type=hidden name=nextsub value=dbdelete>
+
+<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|">
+
+  </td></tr>
+</table>
+
+</form>
+
+<p>|.$locale->text('Select a Dataset to delete and press "Continue"')
+
+.qq|
+
+
+</body>
+</html>
+|;
+
+}
+
+
+sub dbdelete {
+
+  if (!$form->{db}) {
+    $form->error($locale->text('No Dataset selected!'));
+  }
+
+  User->dbdelete(\%$form);
+
+  $form->{title} = "SQL-Ledger ".$locale->text('Accounting')." ".$locale->text('Database Administration')." / ".$locale->text('Delete Dataset');
+
+  $form->header;
+
+  print qq|
+<body class=admin>
+
+
+<center>
+<h2>$form->{title}</h2>
+
+<form method=post action=$form->{script}>
+
+$form->{db} |.$locale->text('successfully deleted!')
+
+.qq|
+
+<input type=hidden name=root value="$form->{root}">
+<input type=hidden name=path value="$form->{path}">
+<input type=hidden name=rpw value="$form->{rpw}">
+
+<input type=hidden name=nextsub value=list_users>
+
+<p><input type=submit class=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+
+</body>
+</html>
+|;
+
+}
+
diff --git a/sql-ledger/bin/mozilla/am.pl b/sql-ledger/bin/mozilla/am.pl
new file mode 100644 (file)
index 0000000..7e36cfd
--- /dev/null
@@ -0,0 +1,1051 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# administration
+#
+#======================================================================
+
+
+use SL::AM;
+use SL::CA;
+use SL::Form;
+use SL::User;
+
+
+1;
+# end of main
+
+
+
+sub add {
+
+  $form->{title} = "Add";
+  $form->{charttype} = "A";
+  
+  $form->{callback} = "$form->{script}?action=list&path=$form->{path}&login=$form->{login}&password=$form->{password}" unless $form->{callback};
+
+  &form_header;
+  &form_footer;
+  
+}
+
+
+sub edit {
+  $form->{title} = "Edit";
+
+  # if it is a template
+  if ($form->{file}) {
+    $form->{type} = "template";
+    &edit_template;
+    exit;
+  }
+
+  AM->get_account(\%myconfig, \%$form);
+  
+  foreach my $item (split(/:/, $form->{link})) {
+    $form->{$item} = "checked";
+  }
+
+  &form_header;
+  &form_footer;
+
+}
+
+
+sub form_header {
+
+  $form->{title} = $locale->text("$form->{title} Account");
+  
+  $checked{$form->{charttype}} = "checked";
+  $checked{"$form->{category}_"} = "checked";
+  $checked{CT_tax} = ($form->{CT_tax}) ? "" : "checked";
+  
+  $form->{description} =~ s/"/&quot;/g;
+
+# this is for our parser only!
+# type=submit $locale->text('Add Account')
+# type=submit $locale->text('Edit Account')
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=id value=$form->{id}>
+<input type=hidden name=type value=account>
+
+<input type=hidden name=inventory_accno_id value=$form->{inventory_accno_id}>
+<input type=hidden name=income_accno_id value=$form->{income_accno_id}>
+<input type=hidden name=expense_accno_id value=$form->{expense_accno_id}>
+<input type=hidden name=fxgain_accno_id values=$form->{fxgain_accno_id}>
+<input type=hidden name=fxloss_accno_id values=$form->{fxloss_accno_id}>
+
+<input type=hidden name=amount value=$form->{amount}>
+
+<table border=0 width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr valign=top>
+    <td>
+      <table>
+       <tr>
+         <th align=right>|.$locale->text('Account Number').qq|</th>
+         <td><input name=accno size=20 value=$form->{accno}></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Description').qq|</th>
+         <td><input name=description size=40 value="$form->{description}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Account Type').qq|</th>
+         <td>
+           <table>
+             <tr valign=top>
+               <td><input name=category type=radio class=radio value=A $checked{A_}>&nbsp;|.$locale->text('Asset').qq|\n<br>
+               <input name=category type=radio class=radio value=L $checked{L_}>&nbsp;|.$locale->text('Liability').qq|\n<br>
+               <input name=category type=radio class=radio value=Q $checked{Q_}>&nbsp;|.$locale->text('Equity').qq|\n<br>
+               <input name=category type=radio class=radio value=I $checked{I_}>&nbsp;|.$locale->text('Income').qq|\n<br>
+               <input name=category type=radio class=radio value=E $checked{E_}>&nbsp;|.$locale->text('Expense')
+               .qq|</td>
+               <td>
+               <input name=charttype type=radio class=radio value="H" $checked{H}>&nbsp;|.$locale->text('Heading').qq|<br>
+               <input name=charttype type=radio class=radio value="A" $checked{A}>&nbsp;|.$locale->text('Account')
+               .qq|</td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+|;
+
+
+if ($form->{charttype} eq "A") {
+  print qq|
+       <tr>
+         <td colspan=2>
+           <table>
+             <tr>
+               <th align=left>|.$locale->text('Is this a summary account to record').qq|</th>
+               <td>
+               <input name=AR type=checkbox class=checkbox value=AR $form->{AR}>&nbsp;|.$locale->text('AR')
+               .qq|&nbsp;<input name=AP type=checkbox class=checkbox value=AP $form->{AP}>&nbsp;|.$locale->text('AP')
+               .qq|&nbsp;<input name=IC type=checkbox class=checkbox value=IC $form->{IC}>&nbsp;|.$locale->text('Inventory')
+               .qq|</td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+       <tr>
+         <th colspan=2>|.$locale->text('Include in drop-down menus').qq|</th>
+       </tr>
+       <tr valign=top>
+         <td colspan=2>
+           <table width=100%>
+             <tr>
+               <th align=left>|.$locale->text('Receivables').qq|</th>
+               <th align=left>|.$locale->text('Payables').qq|</th>
+               <th align=left>|.$locale->text('Parts Inventory').qq|</th>
+               <th align=left>|.$locale->text('Service Items').qq|</th>
+             </tr>
+             <tr>
+               <td>
+               <input name=AR_amount type=checkbox class=checkbox value=AR_amount $form->{AR_amount}>&nbsp;|.$locale->text('Income').qq|\n<br>
+               <input name=AR_paid type=checkbox class=checkbox value=AR_paid $form->{AR_paid}>&nbsp;|.$locale->text('Payment').qq|\n<br>
+               <input name=AR_tax type=checkbox class=checkbox value=AR_tax $form->{AR_tax}>&nbsp;|.$locale->text('Tax')
+               .qq|
+               </td>
+               <td>
+               <input name=AP_amount type=checkbox class=checkbox value=AP_amount $form->{AP_amount}>&nbsp;|.$locale->text('Expense/Asset').qq|\n<br>
+               <input name=AP_paid type=checkbox class=checkbox value=AP_paid $form->{AP_paid}>&nbsp;|.$locale->text('Payment').qq|\n<br>
+               <input name=AP_tax type=checkbox class=checkbox value=AP_tax $form->{AP_tax}>&nbsp;|.$locale->text('Tax')
+               .qq|
+               </td>
+               <td>
+               <input name=IC_sale type=checkbox class=checkbox value=IC_sale $form->{IC_sale}>&nbsp;|.$locale->text('Sales').qq|\n<br>
+               <input name=IC_cogs type=checkbox class=checkbox value=IC_cogs $form->{IC_cogs}>&nbsp;|.$locale->text('COGS').qq|\n<br>
+               <input name=IC_taxpart type=checkbox class=checkbox value=IC_taxpart $form->{IC_taxpart}>&nbsp;|.$locale->text('Tax')
+               .qq|
+               </td>
+               <td>
+               <input name=IC_income type=checkbox class=checkbox value=IC_income $form->{IC_income}>&nbsp;|.$locale->text('Income').qq|\n<br>
+               <input name=IC_expense type=checkbox class=checkbox value=IC_expense $form->{IC_expense}>&nbsp;|.$locale->text('Expense').qq|\n<br>
+               <input name=IC_taxservice type=checkbox class=checkbox value=IC_taxservice $form->{IC_taxservice}>&nbsp;|.$locale->text('Tax')
+               .qq|
+               </td>
+             </tr>
+           </table>
+         </td>  
+       </tr>  
+       <tr>
+         <td colspan=2>
+           <table>
+             <tr>
+               <th align=left>|.$locale->text('Include this account on the customer/vendor forms to flag customer/vendor as taxable?').qq|</th>
+               <td>
+                 <input name=CT_tax type=radio class=radio value=CT_tax $form->{CT_tax}>&nbsp;|.$locale->text('Yes').qq|&nbsp;
+                 <input name=CT_tax type=radio class=radio value="" $checked{CT_tax}>&nbsp;|.$locale->text('No')
+               .qq|
+               </td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+|;
+}
+
+print qq|
+        <tr>
+         <th align=right>|.$locale->text('GIFI').qq|</th>
+         <td><input name=gifi_accno size=9 value=$form->{gifi_accno}></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+|;
+
+}
+
+
+sub form_footer {
+
+  print qq|
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br>
+<input type=submit class=submit name=action value="|.$locale->text('Save').qq|">
+|;
+
+  if ($form->{id}) {
+    print qq|<input type=submit class=submit name=action value="|.$locale->text('Delete').qq|">|;
+  }
+
+  print qq|
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub save { &{ "save_$form->{type}" } };
+  
+sub save_account {
+
+  $form->isblank("accno", $locale->text('Account Number missing!'));
+  $form->isblank("category", $locale->text('Account Type missing!'));
+  
+  $form->redirect($locale->text('Account saved!')) if (AM->save_account(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot save account!'));
+
+}
+
+
+sub list {
+
+  CA->all_accounts(\%myconfig, \%$form);
+
+  $form->{title} = $locale->text('Chart of Accounts');
+  
+  # construct callback
+  $callback = "$form->{script}?action=list&path=$form->{path}&login=$form->{login}&password=$form->{password}";
+
+  @column_index = qw(accno gifi_accno description debit credit link);
+
+  $column_header{accno} = qq|<th class=listheading>|.$locale->text('Account').qq|</a></th>|;
+  $column_header{gifi_accno} = qq|<th class=listheading>|.$locale->text('GIFI').qq|</a></th>|;
+  $column_header{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</a></th>|;
+  $column_header{debit} = qq|<th class=listheading>|.$locale->text('Debit').qq|</a></th>|;
+  $column_header{credit} = qq|<th class=listheading>|.$locale->text('Credit').qq|</a></th>|;
+  $column_header{link} = qq|<th class=listheading>|.$locale->text('Link').qq|</a></th>|;
+
+
+  $form->header;
+  $colspan = $#column_index + 1;
+
+  print qq|
+<body>
+
+<table border=0 width=100%>
+  <tr><th class=listtop colspan=$colspan>$form->{title}</th></tr>
+  <tr height=5></tr>
+  <tr class=listheading>
+|;
+
+  map { print "$column_header{$_}\n" } @column_index;
+  
+  print qq|
+</tr>
+|;
+
+  # escape callback
+  $callback = $form->escape($callback);
+  
+  foreach $ca (@{ $form->{CA} }) {
+    
+    $ca->{debit} = "&nbsp;";
+    $ca->{credit} = "&nbsp;";
+
+    # needed if we can delete an account
+    $amount = 0;
+
+    if ($ca->{amount} > 0) {
+      $amount = $ca->{amount};
+      $ca->{credit} = $form->format_amount(\%myconfig, $ca->{amount}, 2, "&nbsp;");
+    }
+    if ($ca->{amount} < 0) {
+      $amount = -$ca->{amount};
+      $ca->{debit} = $form->format_amount(\%myconfig, -$ca->{amount}, 2, "&nbsp;");
+    }
+
+    $ca->{link} =~ s/:/<br>/og;
+
+    if ($ca->{charttype} eq "H") {
+      print qq|<tr class=listheading>|;
+
+      $column_data{accno} = qq|<th><a class=listheading href=$form->{script}?action=edit&id=$ca->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ca->{accno}</a></th>|;
+      $column_data{gifi_accno} = qq|<th><a class=listheading href=$form->{script}?action=edit_gifi&accno=$ca->{gifi_accno}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ca->{gifi_accno}</a>&nbsp;</th>|;
+      $column_data{description} = qq|<th class=listheading>$ca->{description}&nbsp;</th>|;
+      $column_data{debit} = qq|<th>&nbsp;</th>|;
+      $column_data{credit} = qq| <th>&nbsp;</th>|;
+      $column_data{link} = qq|<th>&nbsp;</th>|;
+
+    } else {
+      $i++; $i %= 2;
+      print qq|
+<tr valign=top class=listrow$i>|;
+      $column_data{accno} = qq|<td><a href=$form->{script}?action=edit&id=$ca->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback&amount=$amount>$ca->{accno}</a></td>|;
+      $column_data{gifi_accno} = qq|<td><a href=$form->{script}?action=edit_gifi&accno=$ca->{gifi_accno}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback&amount=$amount>$ca->{gifi_accno}</a>&nbsp;</td>|;
+      $column_data{description} = qq|<td>$ca->{description}&nbsp;</td>|;
+      $column_data{debit} = qq|<td align=right>$ca->{debit}</td>|;
+      $column_data{credit} = qq|<td align=right>$ca->{credit}</td>|;
+      $column_data{link} = qq|<td>$ca->{link}&nbsp;</td>|;
+      
+    }
+
+    map { print "$column_data{$_}\n" } @column_index;
+    
+    print "</tr>\n";
+  }
+  
+  print qq|
+  <tr><td colspan=$colspan><hr size=3 noshade></td></tr>
+</table>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub delete { &{ "delete_$form->{type}" } };
+
+sub delete_account {
+
+  $form->{title} = $locale->text('Delete Account');
+
+  if ($form->{amount} != 0) {  
+    $form->error($locale->text('Transactions exist; cannot delete account!'));
+  }
+
+  foreach $id (qw(inventory_accno_id income_accno_id expense_accno_id fxgain_accno_id fxloss_accno_id)) {
+    if ($form->{id} == $form->{$id}) {
+      $form->error($locale->text('Cannot delete default account!'));
+    }
+  }
+
+  $form->redirect($locale->text('Account deleted!')) if (AM->delete_account(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot delete account!'));
+
+}
+
+
+sub list_gifi {
+
+  @{ $form->{fields} } = (accno, description);
+  $form->{table} = "gifi";
+  $form->{sortorder} = "accno";
+  
+  AM->gifi_accounts(\%myconfig, \%$form);
+
+  $form->{title} = $locale->text('GIFI');
+  
+  # construct callback
+  $callback = "$form->{script}?action=list_gifi&path=$form->{path}&login=$form->{login}&password=$form->{password}";
+
+  @column_index = qw(accno description);
+
+  $column_header{accno} = qq|<th class=listheading>|.$locale->text('GIFI').qq|</a></th>|;
+  $column_header{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</a></th>|;
+
+
+  $form->header;
+  $colspan = $#column_index + 1;
+
+  print qq|
+<body>
+
+<table border=0 width=100%>
+  <tr><th class=listtop colspan=$colspan>$form->{title}</th></tr>
+  <tr height="5"></tr>
+  <tr class=listheading>
+|;
+
+  map { print "$column_header{$_}\n" } @column_index;
+  
+  print qq|
+</tr>
+|;
+
+  # escape callback
+  $callback = $form->escape($callback);
+  
+  foreach $ca (@{ $form->{ALL} }) {
+    
+    $i++; $i %= 2;
+    
+    print qq|
+<tr valign=top class=listrow$i>|;
+    
+    $column_data{accno} = qq|<td><a href=$form->{script}?action=edit_gifi&coa=1&accno=$ca->{accno}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ca->{accno}</td>|;
+    $column_data{description} = qq|<td>$ca->{description}&nbsp;</td>|;
+    
+    map { print "$column_data{$_}\n" } @column_index;
+    
+    print "</tr>\n";
+  }
+  
+  print qq|
+  <tr>
+    <td colspan=$colspan><hr size=3 noshade></td>
+  </tr>
+</table>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub add_gifi {
+  $form->{title} = "Add";
+  
+  # construct callback
+  $form->{callback} = "$form->{script}?action=list_gifi&path=$form->{path}&login=$form->{login}&password=$form->{password}";
+
+  $form->{coa} = 1;
+  
+  &gifi_header;
+  &gifi_footer;
+  
+}
+
+
+sub edit_gifi {
+  
+  $form->{title} = "Edit";
+
+  AM->get_gifi(\%myconfig, \%$form);
+  
+  &gifi_header;
+  &gifi_footer;
+  
+}
+
+
+sub gifi_header {
+
+  $form->{title} = $locale->text("$form->{title} GIFI");
+  
+# $locale->text('Add GIFI')
+# $locale->text('Edit GIFI')
+
+  $form->{description} =~ s/"/&quot;/g;
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=id value=$form->{accno}>
+<input type=hidden name=type value=gifi>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table>
+       <tr>
+         <th align=right>|.$locale->text('GIFI').qq|</th>
+         <td><input name=accno size=20 value=$form->{accno}></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Description').qq|</th>
+         <td><input name=description size=60 value="$form->{description}"></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td colspan=2><hr size=3 noshade></td>
+  </tr>
+</table>
+|;
+
+}
+
+
+sub gifi_footer {
+
+  print qq|
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br><input type=submit class=submit name=action value="|.$locale->text('Save').qq|">
+|;
+
+  if ($form->{coa}) {
+    print qq|
+<input type=submit class=submit name=action value="|.$locale->text('Copy to COA').qq|">
+|;
+
+    if ($form->{accno}) {
+      print qq|<input type=submit class=submit name=action value="|.$locale->text('Delete').qq|">|;
+    }
+  }
+
+  print qq|
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub save_gifi {
+
+  $form->isblank("accno", $locale->text('GIFI missing!'));
+  AM->save_gifi(\%myconfig, \%$form);
+  $form->redirect($locale->text('GIFI saved!'));
+
+}
+
+
+sub copy_to_coa {
+
+  $form->isblank("accno", $locale->text('GIFI missing!'));
+
+  AM->save_gifi(\%myconfig, \%$form);
+
+  delete $form->{id};
+  $form->{gifi_accno} = $form->{accno};
+  $form->{title} = "Add";
+  $form->{charttype} = "A";
+  
+  &form_header;
+  &form_footer;
+  
+}
+
+
+sub delete_gifi {
+
+  AM->delete_gifi(\%myconfig, \%$form);
+  $form->redirect($locale->text('GIFI deleted!'));
+
+}
+
+
+sub display_stylesheet {
+  
+  $form->{file} = "css/$myconfig{stylesheet}";
+  &display_form;
+  
+}
+
+
+sub display_form {
+
+  $form->{file} =~ s/^(.:)*?\/|\.\.\///g;
+  $form->{file} =~ s/^\/*//g;
+  $form->{file} =~ s/$userspath//;
+
+  $form->error("$!: $form->{file}") unless -f $form->{file};
+
+  AM->load_template(\%$form);
+
+  $form->{title} = $form->{file};
+
+  # if it is anything but html
+  if ($form->{file} !~ /\.html$/) {
+    $form->{body} = "<pre>\n$form->{body}\n</pre>";
+  }
+    
+  $form->header;
+
+  print qq|
+<body>
+
+$form->{body}
+
+<form method=post action=$form->{script}>
+
+<input name=file type=hidden value=$form->{file}>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input name=action type=submit class=submit value="|.$locale->text('Edit').qq|">
+</form>
+
+
+</body>
+</html>
+|;
+
+}
+
+
+sub edit_template {
+
+  AM->load_template(\%$form);
+
+  $form->{title} = $locale->text('Edit Template');
+  # convert &nbsp to &amp;nbsp;
+  $form->{body} =~ s/&nbsp;/&amp;nbsp;/gi;
+  
+
+  $form->header;
+  
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input name=file type=hidden value=$form->{file}>
+<input name=type type=hidden value=template>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input name=callback type=hidden value="$form->{script}?action=display_form&file=$form->{file}&path=$form->{path}&login=$form->{login}&password=$form->{password}">
+
+<textarea name=body rows=25 cols=70>
+$form->{body}
+</textarea>
+
+<br>
+<input type=submit class=submit name=action value="|.$locale->text('Save').qq|">
+
+</form>
+
+
+</body>
+</html>
+|;
+
+}
+
+
+sub save_template {
+
+  AM->save_template(\%$form);
+  $form->redirect($locale->text('Template saved!'));
+  
+}
+
+
+sub config {
+
+  # get defaults for account numbers and last numbers
+  AM->defaultaccounts(\%myconfig, \%$form);
+
+  foreach $item (qw(mm-dd-yy mm/dd/yy dd-mm-yy dd/mm/yy dd.mm.yy yyyy-mm-dd)) {
+    $dateformat .= ($item eq $myconfig{dateformat}) ? "<option selected>$item\n" : "<option>$item\n";
+  }
+
+  foreach $item (qw(1,000.00 1000.00 1.000,00 1000,00)) {
+    $numberformat .= ($item eq $myconfig{numberformat}) ? "<option selected>$item\n" : "<option>$item\n";
+  }
+
+  foreach $item (qw(name company address signature shippingpoint)) {
+    $myconfig{$item} =~ s/"/&quot;/g;
+  }
+
+  foreach $item (qw(address signature)) {
+    $myconfig{$item} =~ s/\\n/\r\n/g;
+  }
+
+  %countrycodes = User->country_codes;
+  $countrycodes = '';
+  foreach $key (sort { $countrycodes{$a} cmp $countrycodes{$b} } keys %countrycodes) {
+    $countrycodes .= ($myconfig{countrycode} eq $key) ? "<option selected value=$key>$countrycodes{$key}\n" : "<option value=$key>$countrycodes{$key}\n";
+  }
+  $countrycodes = "<option>American English\n$countrycodes";
+
+  foreach $key (keys %{ $form->{IC} }) {
+    foreach $accno (sort keys %{ $form->{IC}{$key} }) {
+      $myconfig{$key} .= ($form->{IC}{$key}{$accno}{id} == $form->{defaults}{$key}) ? "<option selected>$accno--$form->{IC}{$key}{$accno}{description}\n" : "<option>$accno--$form->{IC}{$key}{$accno}{description}\n";
+    }
+  }
+  
+  $form->{title} = $locale->text('Edit Preferences for').qq| $form->{login}|;
+  
+  $form->header;
+  
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=old_password value=$myconfig{password}>
+<input type=hidden name=type value=preferences>
+
+<table width=100%>
+  <tr><th class=listtop>$form->{title}</th></tr>
+  <tr>
+    <td>
+      <table>
+        <tr>
+         <th align=right>|.$locale->text('Name').qq|</th>
+         <td><input name=name size=15 value="$myconfig{name}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Password').qq|</th>
+         <td><input type=password name=password size=10 value=$myconfig{password}></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('E-mail').qq|</th>
+         <td><input name=email size=30 value="$myconfig{email}"></td>
+       </tr>
+       <tr valign=top>
+         <th align=right>|.$locale->text('Signature').qq|</th>
+         <td><textarea name=signature rows=3 cols=50>$myconfig{signature}</textarea></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Phone').qq|</th>
+         <td><input name=tel size=14 value="$myconfig{tel}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Fax').qq|</th>
+         <td><input name=fax size=14 value="$myconfig{fax}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Company').qq|</th>
+         <td><input name=company size=30 value="$myconfig{company}"></td>
+       </tr>
+       <tr valign=top>
+         <th align=right>|.$locale->text('Address').qq|</th>
+         <td><textarea name=address rows=4 cols=50>$myconfig{address}</textarea></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Date Format').qq|</th>
+         <td><select name=dateformat>$dateformat</select></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Number Format').qq|</th>
+         <td><select name=numberformat>$numberformat</select></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Dropdown Limit').qq|</th>
+         <td><input name=vclimit size=10 value="$myconfig{vclimit}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Language').qq|</th>
+         <td><select name=countrycode>$countrycodes</select></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Character Set').qq|</th>
+         <td><input name=charset size=20 value="$myconfig{charset}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Stylesheet').qq|</th>
+         <td><input name=stylesheet size=20 value="$myconfig{stylesheet}"></td>
+       </tr>
+       <input name=printer type=hidden value="$myconfig{printer}">
+       <tr>
+         <th align=right>|.$locale->text('Ship via').qq|</th>
+         <td><input name=shippingpoint size=25 value="$myconfig{shippingpoint}"></td>
+       </tr>
+       <tr class=listheading>
+         <th colspan=2>&nbsp;</th>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Business Number').qq|</th>
+         <td><input name=businessnumber size=25 value="$myconfig{businessnumber}"></td>
+       </tr>
+       <tr>
+         <td colspan=2>
+           <table width=100%>
+             <tr>
+               <th align=right>|.$locale->text('Year End').qq| (mm/dd)</th>
+               <td><input name=yearend size=5 maxsize=5 value=$form->{defaults}{yearend}></td>
+               <th align=right>|.$locale->text('Weight Unit').qq|</th>
+               <td><input name=weightunit size=5 value="$form->{defaults}{weightunit}"></td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+       <tr class=listheading>
+         <th class=listheading colspan=2>|.$locale->text('Last Numbers & Default Accounts').qq|</th>
+       </tr>
+       <tr>
+         <td colspan=2>
+           <table width=100%>
+             <tr>
+               <th width=1% align=right nowrap>|.$locale->text('Inventory Account').qq|</th>
+               <td><select name=inventory_accno>$myconfig{IC}</select></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Income Account').qq|</th>
+               <td><select name=income_accno>$myconfig{IC_income}</select></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Expense Account').qq|</th>
+               <td><select name=expense_accno>$myconfig{IC_expense}</select></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Foreign Exchange Gain').qq|</th>
+               <td><select name=fxgain_accno>$myconfig{FX_gain}</select></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Foreign Exchange Loss').qq|</th>
+               <td><select name=fxloss_accno>$myconfig{FX_loss}</select></td>
+             </tr>
+             <tr>
+               <td colspan=2>|.$locale->text('Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies').qq|<br><input name=curr size=40 value="$form->{defaults}{curr}"></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Last Invoice Number').qq|</th>
+               <td><input name=invnumber size=10 value=$form->{defaults}{invnumber}></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Last Sales Order Number').qq|</th>
+               <td><input name=sonumber size=10 value=$form->{defaults}{sonumber}></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Last Purchase Order Number').qq|</th>
+               <td><input name=ponumber size=10 value=$form->{defaults}{ponumber}></td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+       <tr class=listheading>
+         <th class=listheading colspan=2>|.$locale->text('Tax Accounts').qq|</th>
+       </tr>
+       <tr>
+         <td colspan=2>
+           <table>
+             <tr>
+               <th>&nbsp;</th>
+               <th>|.$locale->text('Rate').qq| (%)</th>
+               <th>|.$locale->text('Number').qq|</th>
+             </tr>
+|;
+
+  foreach $accno (sort keys %{ $form->{taxrates} }) {
+    print qq|
+              <tr>
+               <th align=right>$form->{taxrates}{$accno}{description}</th>
+               <td><input name=$form->{taxrates}{$accno}{id} size=6 value=$form->{taxrates}{$accno}{rate}></td>
+               <td><input name="taxnumber_$form->{taxrates}{$accno}{id}" value="$form->{taxrates}{$accno}{taxnumber}"></td>
+             </tr>
+|;
+    $form->{taxaccounts} .= "$form->{taxrates}{$accno}{id} ";
+  }
+
+  chop $form->{taxaccounts};
+
+  print qq|
+<input name=taxaccounts type=hidden value="$form->{taxaccounts}">
+
+            </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br>
+<input type=submit class=submit name=action value="|.$locale->text('Save').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub save_preferences {
+
+  # does stylesheet exist
+  if ($form->{stylesheet}) {
+    $form->error($locale->text('Stylesheet').": css/$form->{stylesheet} ".$locale->text('does not exist')) unless (-f "css/$form->{stylesheet}");
+  } 
+
+  $form->redirect($locale->text('Preferences saved!')) if (AM->save_preferences(\%myconfig, \%$form, $memberfile, $userspath));
+  $form->error($locale->text('Cannot save preferences!'));
+
+}
+
+
+sub backup {
+
+  if ($form->{media} eq 'email') {
+    $form->error($locale->text('No email address for')." $myconfig{name}") unless ($myconfig{email});
+    
+    $form->{OUT} = "$sendmail";
+
+  }
+  
+  AM->backup(\%myconfig, \%$form, $userspath);
+
+  if ($form->{media} eq 'email') {
+    $form->redirect($locale->text('Backup sent to').qq| $myconfig{email}|);
+  }
+
+}
+
+
+
+sub audit_control {
+
+  $form->{title} = $locale->text('Audit Control');
+
+  AM->closedto(\%myconfig, \%$form);
+  
+  if ($form->{revtrans}) {
+    $checked{Y} = "checked";
+  } else {
+    $checked{N} = "checked";
+  }
+  
+  $form->header;
+  
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<table width=100%>
+  <tr><th class=listtop>$form->{title}</th></tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table>
+       <tr>
+         <td>|.$locale->text('Enforce transaction reversal for all dates').qq|</th>
+         <td><input name=revtrans class=radio type=radio value="1" $checked{Y}> |.$locale->text('Yes').qq| <input name=revtrans class=radio type=radio value="0" $checked{N}> |.$locale->text('No').qq|</td>
+       </tr>
+       <tr>
+         <td>|.$locale->text('Close Books up to').qq|</th>
+         <td><input name=closedto size=11 title="$myconfig{dateformat}" value=$form->{closedto}></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+
+<hr size=3 noshade>
+
+<br>
+<input type=hidden name=nextsub value=doclose>
+
+<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|">
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub doclose {
+
+  AM->closebooks(\%myconfig, \%$form);
+  
+  if ($form->{revtrans}) {
+    $form->redirect($locale->text('Transaction reversal enforced for all dates'));
+  } else {
+    if ($form->{closedto}) {
+      $form->redirect($locale->text('Transaction reversal enforced up to')
+      ." ".$locale->date(\%myconfig, $form->{closedto}, 1));
+    } else {
+      $form->redirect($locale->text('Books are open'));
+    }
+  }
+
+}
+
+
+
+sub continue {
+    
+  &{ $form->{nextsub} };
+
+}
+
+
diff --git a/sql-ledger/bin/mozilla/ap.pl b/sql-ledger/bin/mozilla/ap.pl
new file mode 100644 (file)
index 0000000..269f7cf
--- /dev/null
@@ -0,0 +1,1103 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Accounts Payables
+#
+#======================================================================
+
+
+use SL::AP;
+use SL::IR;
+use SL::PE;
+
+require "$form->{path}/arap.pl";
+
+1;
+# end of main
+
+
+# this is for our long dates
+# $locale->text('January')
+# $locale->text('February')
+# $locale->text('March')
+# $locale->text('April')
+# $locale->text('May ')
+# $locale->text('June')
+# $locale->text('July')
+# $locale->text('August')
+# $locale->text('September')
+# $locale->text('October')
+# $locale->text('November')
+# $locale->text('December')
+
+# this is for our short month
+# $locale->text('Jan')
+# $locale->text('Feb')
+# $locale->text('Mar')
+# $locale->text('Apr')
+# $locale->text('May')
+# $locale->text('Jun')
+# $locale->text('Jul')
+# $locale->text('Aug')
+# $locale->text('Sep')
+# $locale->text('Oct')
+# $locale->text('Nov')
+# $locale->text('Dec')
+
+
+sub add {
+
+  $form->{title} = "Add";
+  
+  $form->{callback} = "$form->{script}?action=add&path=$form->{path}&login=$form->{login}&password=$form->{password}" unless $form->{callback};
+
+  &create_links;
+  &display_form;
+  
+}
+
+
+sub edit {
+  
+  $form->{title} = "Edit";
+
+  &create_links;
+  &display_form;
+
+}
+
+
+sub display_form {
+  
+  &form_header;
+  &form_footer;
+
+}
+
+
+sub create_links {
+
+  $form->create_links("AP", \%myconfig, "vendor");
+
+  $taxincluded = $form->{taxincluded};
+  $duedate = $form->{duedate};
+  
+  IR->get_vendor(\%myconfig, \%$form);
+  
+  $form->{duedate} = $duedate;
+  $form->{oldvendor} = "$form->{vendor}--$form->{vendor_id}";
+  
+  # build the popup menus
+
+  # currencies
+  @curr = split /:/, $form->{currencies};
+  chomp $curr[0];
+  $form->{defaultcurrency} = $curr[0];
+
+  map { $form->{selectcurrency} .= "<option>$_\n" } @curr;
+
+  # vendors
+  if (@{ $form->{all_vendor} }) {
+    $form->{vendor} = qq|$form->{vendor}--$form->{vendor_id}|;
+    map { $form->{selectvendor} .= "<option>$_->{name}--$_->{id}\n" } (@{ $form->{all_vendor} });
+  }
+  
+
+  # forex
+  $form->{forex} = $form->{exchangerate};
+  $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1;
+  
+  foreach $key (keys %{ $form->{AP_links} }) {
+    
+    foreach $ref (@{ $form->{AP_links}{$key} }) {
+      if ($key eq "AP_tax") {
+       $form->{"selectAP_tax_$ref->{accno}"} = "<option>$ref->{accno}--$ref->{description}\n";
+       next;
+      }
+      $form->{"select$key"} .= "<option>$ref->{accno}--$ref->{description}\n";
+    }
+       
+    # if there is a value we have an old entry
+    for $i (1 .. scalar @{ $form->{acc_trans}{$key} }) {
+
+      if ($key eq "AP_paid") {
+       $form->{"AP_paid_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
+       $form->{"paid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{amount};
+       $form->{"datepaid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{transdate};
+       $form->{"source_$i"} = $form->{acc_trans}{$key}->[$i-1]->{source};
+       
+       $form->{"forex_$i"} = $form->{"exchangerate_$i"} = $form->{acc_trans}{$key}->[$i-1]->{exchangerate};
+       
+       $form->{paidaccounts}++;
+      } else {
+
+        $akey = $key;
+        $akey =~ s/AP_//;
+
+       if ($key eq "AP_tax") {
+         $form->{"${key}_$form->{acc_trans}{$key}->[$i-1]->{accno}"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
+         $form->{"${akey}_$form->{acc_trans}{$key}->[$i-1]->{accno}"} = $form->round_amount($form->{acc_trans}{$key}->[$i-1]->{amount} / $exchangerate * -1, 2);
+         $totaltax += $form->{"${akey}_$form->{acc_trans}{$key}->[$i-1]->{accno}"};
+       } else {
+         $form->{"${akey}_$i"} = $form->round_amount($form->{acc_trans}{$key}->[$i-1]->{amount} / $exchangerate, 2);
+         if ($akey eq 'amount') {
+           $form->{"${akey}_$i"} *= -1;
+           $totalamount += $form->{"${akey}_$i"};
+           $form->{rowcount}++;
+
+           $form->{"oldprojectnumber_$i"} = $form->{"projectnumber_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{projectnumber}";
+           $form->{"project_id_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{project_id}";
+         }
+         $form->{"${key}_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
+       }
+      }
+    }
+  }
+
+  $form->{taxincluded} = $taxincluded if ($form->{id});
+  $form->{paidaccounts} = 1 if not defined $form->{paidaccounts};
+
+  if ($form->{taxincluded} && $totalamount) {
+  # add tax to amounts and invtotal
+    for $i (1 .. $form->{rowcount}) {
+      $taxamount = $totaltax * $form->{"amount_$i"} / $totalamount;
+      $tax = $form->round_amount($taxamount, 2);
+      $diff += ($taxamount - $tax);
+      $form->{"amount_$i"} += $tax;
+    }
+    $form->{amount_1} += $form->round_amount($diff, 2);
+  }
+  
+  $form->{invtotal} = $totalamount + $totaltax;
+  $form->{rowcount}++ if $form->{id};
+  
+  $form->{AP} = $form->{AP_1};
+
+  $form->{locked} = ($form->datetonum($form->{transdate}, \%myconfig) <= $form->datetonum($form->{closedto}, \%myconfig));
+
+}
+
+
+sub form_header {
+
+  $title = $form->{title};
+  $form->{title} = $locale->text("$title Accounts Payables Transaction");
+
+  $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : "";
+  
+# type=submit $locale->text('Add Accounts Payables Transaction')
+# type=submit $locale->text('Edit Accounts Payables Transaction')
+
+  # set option selected
+  foreach $item (qw(AP vendor currency)) {
+    $form->{"select$item"} =~ s/ selected//;
+    $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
+  }
+
+  
+  # format amounts
+  $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate});
+  
+  $exchangerate = qq|
+<input type=hidden name=forex value=$form->{forex}>
+|;
+  if ($form->{currency} ne $form->{defaultcurrency}) {
+    if ($form->{forex}) {
+      $exchangerate .= qq|
+             <th align=right>|.$locale->text('Exchangerate').qq|</th>
+              <td><input type=hidden name=exchangerate value=$form->{exchangerate}>$form->{exchangerate}</td>
+|;
+    } else {
+      $exchangerate .= qq|
+            <th align=right>|.$locale->text('Exchangerate').qq|</th>
+             <td><input name=exchangerate size=10 value=$form->{exchangerate}></td>
+|;
+    }
+  }
+  
+  $taxincluded = "";
+  if ($form->{taxaccounts}) {
+    $taxincluded = qq|
+            <tr>
+              <td align=right><input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}></td>
+              <th align=left nowrap>|.$locale->text('Tax Included').qq|</th>
+            </tr>
+|;
+  }
+
+
+  if (($rows = $form->numtextrows($form->{notes}, 50)) < 2) {
+    $rows = 2;
+  }
+  $notes = qq|<textarea name=notes rows=$rows cols=50 wrap=soft>$form->{notes}</textarea>|;
+  
+  
+  $form->header;
+
+  $vendor = ($form->{selectvendor}) ? qq|<select name=vendor>$form->{selectvendor}</select>| : qq|<input name=vendor value="$form->{vendor}" size=35>|; 
+  
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=id value=$form->{id}>
+<input type=hidden name=sort value=$form->{sort}>
+<input type=hidden name=closedto value=$form->{closedto}>
+<input type=hidden name=locked value=$form->{locked}>
+<input type=hidden name=title value="$title">
+
+<table width=100%>
+  <tr class=listtop>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr valign=top>
+    <td>
+      <table width=100%>
+        <tr valign=top>
+         <td>
+           <table>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Vendor').qq|</th>
+               <td colspan=3>$vendor</td>
+               <input type=hidden name=selectvendor value="$form->{selectvendor}">
+               <input type=hidden name=oldvendor value="$form->{oldvendor}">
+               <input type=hidden name=vendor_id value="$form->{vendor_id}">
+               <input type=hidden name=terms value=$form->{terms}>
+             </tr>
+             $taxincluded
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Currency').qq|</th>
+               <td><select name=currency>$form->{selectcurrency}</select></td>
+               <input type=hidden name=selectcurrency value="$form->{selectcurrency}">
+               <input type=hidden name=defaultcurrency value=$form->{defaultcurrency}>
+               <input type=hidden name=fxgain_accno value=$form->{fxgain_accno}>
+               <input type=hidden name=fxloss_accno value=$form->{fxloss_accno}>
+               $exchangerate
+             </tr>
+           </table>
+         </td>
+         <td align=right>
+           <table>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th>
+               <td><input name=invnumber size=11 value="$form->{invnumber}"></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Order Number').qq|</th>
+               <td><input name=ordnumber size=11 value="$form->{ordnumber}"></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Invoice Date').qq|</th>
+               <td><input name=transdate size=11 title="$myconfig{'dateformat'}" value=$form->{transdate}></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Due Date').qq|</th>
+               <td><input name=duedate size=11 title="$myconfig{'dateformat'}" value=$form->{duedate}></td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <input type=hidden name=selectAP_amount value="$form->{selectAP_amount}">
+  <input type=hidden name=rowcount value=$form->{rowcount}>
+  <tr>
+    <td>
+      <table width=100%>
+|;
+
+  $amount = $locale->text('Amount');
+  $project = $locale->text('Project');
+  
+  for $i (1 .. $form->{rowcount}) {
+
+    $form->{"selectAP_amount"} =~ s/ selected//;
+    $form->{"selectAP_amount"} =~ s/option>\Q$form->{"AP_amount_$i"}\E/option selected>$form->{"AP_amount_$i"}/;
+
+    # format amounts
+    $form->{"amount_$i"} = $form->format_amount(\%myconfig, $form->{"amount_$i"}, 2);
+
+    print qq|
+       <tr>
+         <th align=right nowrap>$amount</th>
+         <td><input name="amount_$i" size=10 value=$form->{"amount_$i"}></td>
+         <th>$project</th>
+         <td><input name="projectnumber_$i" size=20 value="$form->{"projectnumber_$i"}">
+             <input type=hidden name="project_id_$i" value=$form->{"project_id_$i"}>
+             <input type=hidden name="oldprojectnumber_$i" value="$form->{"oldprojectnumber_$i"}"></td>
+         <td width=50%><select name="AP_amount_$i">$form->{selectAP_amount}</select></td>
+       </tr>
+|;
+    $amount = "";
+    $project = "";
+  }
+
+  $taxlabel = ($form->{taxincluded}) ? $locale->text('Tax Included') : $locale->text('Tax');
+  
+  foreach $item (split / /, $form->{taxaccounts}) {
+
+    # format and reverse tax
+    $form->{"tax_$item"} = $form->format_amount(\%myconfig, $form->{"tax_$item"}, 2); 
+
+    print qq|
+        <tr>
+         <th align=right nowrap>${taxlabel}</th>
+         <td><input name="tax_$item" size=10 value=$form->{"tax_$item"}></td>
+         <td colspan=2></td>
+         <td><select name=AP_tax_$item>$form->{"selectAP_tax_$item"}</select></td>
+        </tr>
+       <input type=hidden name="${item}_rate" value="$form->{"${item}_rate"}">
+       <input type=hidden name="${item}_description" value="$form->{"${item}_description"}">
+       <input type=hidden name="selectAP_tax_$item" value="$form->{"selectAP_tax_$item"}">
+|;
+  }
+   
+  $form->{invtotal} = $form->format_amount(\%myconfig, $form->{invtotal}, 2);
+
+  print qq|
+        <tr>
+         <th align=right nowrap>|.$locale->text('Total').qq|</th>
+         <td>$form->{invtotal}</td>
+         <td colspan=2></td>
+          <td><select name=AP>$form->{selectAP}</select></td>
+         <input type=hidden name=selectAP value="$form->{selectAP}">
+         <input type=hidden name=taxaccounts value="$form->{taxaccounts}">
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Notes').qq|</th>
+         <td colspan=5>$notes</td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+         <th class=listheading colspan=5>|.$locale->text('Payments').qq|</th>
+       </tr>
+|;
+
+
+  if ($form->{currency} eq $form->{defaultcurrency}) {
+    @column_index = qw(datepaid source paid AP_paid);
+  } else {
+    @column_index = qw(datepaid source paid exchangerate AP_paid);
+  }
+
+  $column_data{datepaid} = "<th>".$locale->text('Date')."</th>";
+  $column_data{paid} = "<th>".$locale->text('Amount')."</th>";
+  $column_data{exchangerate} = "<th>".$locale->text('Exch')."</th>";
+  $column_data{AP_paid} = "<th>".$locale->text('Account')."</th>";
+  $column_data{source} = "<th>".$locale->text('Source')."</th>";
+
+  print "
+        <tr>
+";
+  map { print "$column_data{$_}\n" } @column_index;
+  print "
+        </tr>
+";
+
+  $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"});
+  for $i (1 .. $form->{paidaccounts}) {
+    print "
+        <tr>
+";
+
+    $form->{"selectAP_paid_$i"} = $form->{selectAP_paid};
+    $form->{"selectAP_paid_$i"} =~ s/option>\Q$form->{"AP_paid_$i"}\E/option selected>$form->{"AP_paid_$i"}/;
+
+    # format amounts
+    $form->{"paid_$i"} = $form->format_amount(\%myconfig, $form->{"paid_$i"}, 2);
+    $form->{"exchangerate_$i"} = $form->format_amount(\%myconfig, $form->{"exchangerate_$i"});
+    
+    $exchangerate = qq|&nbsp;|;
+    if ($form->{currency} ne $form->{defaultcurrency}) {
+      if ($form->{"forex_$i"}) {
+       $exchangerate = qq|<input type=hidden name="exchangerate_$i" value=$form->{"exchangerate_$i"}>$form->{"exchangerate_$i"}|;
+      } else {
+       $exchangerate = qq|<input name="exchangerate_$i" size=10 value=$form->{"exchangerate_$i"}>|;
+      }
+    }
+
+    $exchangerate .= qq|
+<input type=hidden name="forex_$i" value=$form->{"forex_$i"}>
+|;
+
+    $column_data{"paid_$i"} = qq|<td align=center><input name="paid_$i" size=10 value=$form->{"paid_$i"}></td>|;
+    $column_data{"AP_paid_$i"} = qq|<td align=center><select name="AP_paid_$i">$form->{"selectAP_paid_$i"}</select></td>|;
+    $column_data{"exchangerate_$i"} = qq|<td align=center>$exchangerate</td>|;
+    $column_data{"datepaid_$i"} = qq|<td align=center><input name="datepaid_$i" size=11 title="($myconfig{'dateformat'})" value=$form->{"datepaid_$i"}></td>|;
+    $column_data{"source_$i"} = qq|<td align=center><input name="source_$i" size=10 value="$form->{"source_$i"}"></td>|;
+
+    map { print qq|$column_data{"${_}_$i"}\n| } @column_index;
+
+    print "
+        </tr>
+";
+  }
+
+  print qq|
+    <input type=hidden name=paidaccounts value=$form->{paidaccounts}>
+    <input type=hidden name=selectAP_paid value="$form->{selectAP_paid}">
+    
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+|;
+
+}
+
+
+sub form_footer {
+
+  print qq|
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br>
+|;
+
+  $transdate = $form->datetonum($form->{transdate}, \%myconfig);
+  $closedto = $form->datetonum($form->{closedto}, \%myconfig);
+  
+  if ($form->{id}) {
+    print qq|<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+|;
+
+    if (!$form->{revtrans}) {
+      if (!$form->{locked}) {
+       print qq|
+       <input class=submit type=submit name=action value="|.$locale->text('Post').qq|">
+       <input class=submit type=submit name=action value="|.$locale->text('Delete').qq|">
+|;
+      }
+    }
+
+    if ($transdate > $closedto) {
+      print qq|
+<input class=submit type=submit name=action value="|.$locale->text('Post as new').qq|">
+|;
+    }
+
+  } else {
+    if ($transdate > $closedto) {
+      print qq|<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+      <input class=submit type=submit name=action value="|.$locale->text('Post').qq|">|;
+    }
+  }
+
+  print "
+</form>
+
+</body>
+</html>
+";
+
+}
+
+
+sub update {
+  my $display = shift;
+
+  if ($display) {
+    goto TAXCALC;
+  }
+
+  $form->{invtotal} = 0;
+  
+  $form->{exchangerate} = $form->parse_amount(\%myconfig, $form->{exchangerate});
+
+  @flds = qw(amount AP_amount projectnumber oldprojectnumber project_id);
+  $count = 0;
+  for $i (1 .. $form->{rowcount}) {
+    $form->{"amount_$i"} = $form->parse_amount(\%myconfig, $form->{"amount_$i"});
+    if ($form->{"amount_$i"}) {
+      push @a, {};
+      my $j = $#a;
+      map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
+      $count++;
+    }
+  }
+  $form->redo_rows(\@flds, \@a, $count, $form->{rowcount});
+  $form->{rowcount} = $count + 1;
+  
+  map { $form->{invtotal} += $form->{"amount_$_"} } (1 .. $form->{rowcount});
+  
+  $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, 'sell')));
+
+  $form->{invdate} = $form->{transdate};
+  &check_name(vendor);
+
+  &check_project;
+
+
+TAXCALC:
+  # recalculate taxes
+  if ($form->{taxincluded}) {
+    $taxrate = 0;
+
+    map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{taxaccounts};
+
+    foreach $item (split / /, $form->{taxaccounts}) {
+      $amount = ($form->{invtotal} * (1 - 1 / (1 + $taxrate)) * $form->{"${item}_rate"} / $taxrate) if $taxrate;
+      $form->{"tax_$item"} = $form->round_amount($amount, 2);
+      $taxdiff += ($amount - $form->{"tax_$item"});
+      if (abs $taxdiff >= 0.005) {
+       $form->{"tax_$item"} += $form->round_amount($taxdiff, 2);
+       $taxdiff = 0;
+      }
+      $form->{"selectAP_tax_$item"} = qq|<option>$item--$form->{"${item}_description"}|;
+      $totaltax += $form->{"tax_$item"};
+    }
+  } else {
+    foreach $item (split / /, $form->{taxaccounts}) {
+      $form->{"tax_$item"} = $form->round_amount($form->{invtotal} * $form->{"${item}_rate"}, 2);
+      $form->{"selectAP_tax_$item"} = qq|<option>$item--$form->{"${item}_description"}|;
+      $totaltax += $form->{"tax_$item"};
+    }
+  }
+
+  $form->{invtotal} = ($form->{taxincluded}) ? $form->{invtotal} : $form->{invtotal} + $totaltax;
+  
+  for $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"}) {
+      map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(paid exchangerate);
+      
+      $form->{"exchangerate_$i"} = $exchangerate if ($form->{"forex_$i"} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'sell')));
+    }
+  }
+
+  &display_form;
+
+}
+
+sub post {
+
+  # check if there is an invoice number, invoice and due date
+  $form->isblank("invnumber", $locale->text("Invoice Number missing!"));
+  $form->isblank("transdate", $locale->text("Invoice Date missing!"));
+  $form->isblank("duedate", $locale->text("Due Date missing!"));
+  $form->isblank("vendor", $locale->text('Vendor missing!'));
+  
+  
+  $closedto = $form->datetonum($form->{closedto}, \%myconfig);
+  $transdate = $form->datetonum($form->{transdate}, \%myconfig);
+
+  $form->error($locale->text('Cannot post transaction for a closed period!')) if ($transdate <= $closedto);
+
+  $form->isblank("exchangerate", $locale->text('Exchangerate missing!')) if ($form->{currency} ne $form->{defaultcurrency});
+
+  for $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"}) {
+      $datepaid = $form->datetonum($form->{"datepaid_$i"}, \%myconfig);
+
+      $form->isblank("datepaid_$i", $locale->text('Payment date missing!'));
+
+      $form->error($locale->text('Cannot post payment for a closed period!')) if ($datepaid <= $closedto);
+
+      if ($form->{currency} ne $form->{defaultcurrency}) {
+       $form->{"exchangerate_$i"} = $form->{exchangerate} if ($transdate == $datepaid);
+       $form->isblank("exchangerate_$i", $locale->text('Exchangerate for payment missing!'));
+      }
+      
+    }
+  }
+      
+
+  # if old vendor ne vendor redo form
+  ($vendor) = split /--/, $form->{vendor};
+  if ($form->{oldvendor} ne "$vendor--$form->{vendor_id}") {
+    &update;
+    exit;
+  }
+
+  $form->{id} = 0 if $form->{postasnew};
+
+  $form->redirect($locale->text('Transaction posted!')) if (AP->post_transaction(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot post transaction!'));
+  
+}
+
+
+sub post_as_new {
+
+  $form->{postasnew} = 1;
+  &post;
+
+}
+
+
+sub delete {
+
+  $form->{title} = $locale->text('Confirm!');
+  
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+|;
+
+  foreach $key (keys %$form) {
+    print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
+  }
+
+  print qq|
+<h2 class=confirm>$form->{title}</h2>
+
+<h4>|.$locale->text('Are you sure you want to delete Transaction').qq| $form->{invnumber}</h4>
+
+<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+sub yes {
+
+  $form->redirect($locale->text('Transaction deleted!')) if (AP->delete_transaction(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot delete transaction!'));
+
+}
+
+
+sub search {
+  
+  # setup vendor selection
+  $form->all_vc(\%myconfig, "vendor");
+
+  if (@{ $form->{all_vendor} }) {
+    map { $vendor .= "<option>$_->{name}--$_->{id}\n" } @{ $form->{all_vendor} };
+    $vendor = qq|<select name=vendor><option>\n$vendor\n</select>|;
+  } else {
+    $vendor = qq|<input name=vendor size=35>|;
+  }
+    
+    $form->{title} = $locale->text('AP Transactions');
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table>
+       <tr>
+         <th align=right>|.$locale->text('Vendor').qq|</th>
+         <td colspan=3>$vendor</td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th>
+         <td colspan=3><input name=invnumber size=20></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Order Number').qq|</th>
+         <td colspan=3><input name=ordnumber size=20></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Notes').qq|</th>
+         <td colspan=3><input name=notes size=40></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('From').qq|</th>
+         <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td>
+         <th align=right>|.$locale->text('to').qq|</th>
+         <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td>
+       </tr>
+        <input type=hidden name=sort value=transdate>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Include in Report').qq|</th>
+         <td>
+           <table width=100%>
+             <tr>
+               <td align=right><input name=open class=checkbox type=checkbox value=Y checked></td>
+               <td nowrap>|.$locale->text('Open').qq|</td>
+               <td align=right><input name=closed class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Closed').qq|</td>
+             </tr>
+             <tr>
+               <td align=right><input name="l_id" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('ID').qq|</td>
+               <td align=right><input name="l_invnumber" class=checkbox type=checkbox value=Y checked></td>
+               <td nowrap>|.$locale->text('Invoice Number').qq|</td>
+               <td align=right><input name="l_ordnumber" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Order Number').qq|</td>
+             </tr>
+             <tr>
+               <td align=right><input name="l_name" class=checkbox type=checkbox value=Y checked></td>
+               <td nowrap>|.$locale->text('Vendor').qq|</td>
+               <td align=right><input name="l_transdate" class=checkbox type=checkbox value=Y checked></td>
+               <td nowrap>|.$locale->text('Invoice Date').qq|</td>
+               <td align=right><input name="l_netamount" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Amount').qq|</td>
+             </tr>
+             <tr>
+               <td align=right><input name="l_tax" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Tax').qq|</td>
+               <td align=right><input name="l_amount" class=checkbox type=checkbox value=Y checked></td>
+               <td nowrap>|.$locale->text('Total').qq|</td>
+               <td align=right><input name="l_datepaid" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Date Paid').qq|</td>
+             </tr>
+             <tr>
+               <td align=right><input name="l_paid" class=checkbox type=checkbox value=Y checked></td>
+               <td nowrap>|.$locale->text('Paid').qq|</td>
+               <td align=right><input name="l_duedate" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Due Date').qq|</td>
+               <td align=right><input name="l_due" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Amount Due').qq|</td>
+             </tr>
+             <tr>
+               <td align=right><input name="l_notes" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Notes').qq|</td>
+               <td align=right><input name="l_employee" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Employee').qq|</td>
+             </tr>
+             <tr>
+               <td align=right><input name="l_subtotal" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Subtotal').qq|</td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<br>
+<input type=hidden name=nextsub value=$form->{nextsub}>
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub ap_transactions {
+
+  $form->{vendor} = $form->unescape($form->{vendor});
+  ($form->{vendor}, $form->{vendor_id}) = split(/--/, $form->{vendor});
+
+  AP->ap_transactions(\%myconfig, \%$form);
+
+  $callback = "$form->{script}?action=ap_transactions&path=$form->{path}&login=$form->{login}&password=$form->{password}";
+  $href = $callback;
+    
+
+  if ($form->{vendor}) {
+    $callback .= "&vendor=".$form->escape($form->{vendor});
+    $href .= "&vendor=".$form->escape($form->{vendor});
+    $option .= $locale->text('Vendor')." : $form->{vendor}";
+  }
+  if ($form->{invnumber}) {
+    $callback .= "&invnumber=$form->{invnumber}";
+    $href .= "&invnumber=".$form->escape($form->{invnumber});
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('Invoice Number')." : $form->{invnumber}";
+  }
+  if ($form->{ordnumber}) {
+    $callback .= "&ordnumber=$form->{ordnumber}";
+    $href .= "&ordnumber=".$form->escape($form->{ordnumber});
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('Order Number')." : $form->{ordnumber}";
+  }
+  if ($form->{notes}) {
+    $callback .= "&notes=$form->{notes}";
+    $href .= "&notes=".$form->escape($form->{notes});
+    $option .= "\n<br>" if $option;
+    $option .= $locale->text('Notes')." : $form->{notes}";
+  }
+  
+  if ($form->{transdatefrom}) {
+    $callback .= "&transdatefrom=$form->{transdatefrom}";
+    $href .= "&transdatefrom=$form->{transdatefrom}";
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{transdatefrom}, 1);
+  }
+  if ($form->{transdateto}) {
+    $callback .= "&transdateto=$form->{transdateto}";
+    $href .= "&transdateto=$form->{transdateto}";
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('to')." ".$locale->date(\%myconfig, $form->{transdateto}, 1);
+  }
+  if ($form->{open}) {
+    $callback .= "&open=$form->{open}";
+    $href .= "&open=$form->{open}";
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('Open');
+  }
+  if ($form->{closed}) {
+    $callback .= "&closed=$form->{closed}";
+    $href .= "&closed=$form->{closed}";
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('Closed');
+  }
+
+  @columns = $form->sort_columns(qw(transdate id invnumber ordnumber name netamount tax amount paid datepaid due duedate notes employee));
+
+  foreach $item (@columns) {
+    if ($form->{"l_$item"} eq "Y") {
+      push @column_index, $item;
+      
+      # add column to href and callback
+      $callback .= "&l_$item=Y";
+      $href .= "&l_$item=Y";
+    }
+  }
+  
+  if ($form->{l_subtotal} eq 'Y') {
+    $callback .= "&l_subtotal=Y";
+    $href .= "&l_subtotal=Y";
+  }
+  
+    
+  $column_header{id} = qq|<th><a class=listheading href=$href&sort=id>|.$locale->text('ID').qq|</a></th>|;
+  $column_header{transdate} = qq|<th><a class=listheading href=$href&sort=transdate>|.$locale->text('Date').qq|</a></th>|;
+  $column_header{duedate} = qq|<th><a class=listheading href=$href&sort=duedate>|.$locale->text('Due Date').qq|</a></th>|;
+  $column_header{due} = qq|<th class=listheading>|.$locale->text('Amount Due').qq|</th>|;
+  $column_header{invnumber} = qq|<th><a class=listheading href=$href&sort=invnumber>|.$locale->text('Invoice').qq|</a></th>|;
+  $column_header{ordnumber} = qq|<th><a class=listheading href=$href&sort=ordnumber>|.$locale->text('Order').qq|</a></th>|;
+  $column_header{name} = qq|<th><a class=listheading href=$href&sort=name>|.$locale->text('Vendor').qq|</a></th>|;
+  $column_header{netamount} = qq|<th class=listheading>|.$locale->text('Amount').qq|</th>|;
+  $column_header{tax} = qq|<th class=listheading>|.$locale->text('Tax').qq|</th>|;
+  $column_header{amount} = qq|<th class=listheading>|.$locale->text('Total').qq|</th>|;
+  $column_header{paid} = qq|<th class=listheading>|.$locale->text('Paid').qq|</th>|;
+  $column_header{datepaid} = qq|<th><a class=listheading href=$href&sort=datepaid>|.$locale->text('Date Paid').qq|</a></th>|;
+  $column_header{notes} = qq|<th><a class=listheading>|.$locale->text('Notes').qq|</th>|;
+  $column_header{employee} = "<th><a class=listheading href=$href&sort=employee>".$locale->text('Employee')."</th>";
+
+  
+  $form->{title} = $locale->text('AP Transactions');
+
+  $form->header;
+  
+  print qq|
+<body>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>$option</td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+|;
+
+  map { print "\n$column_header{$_}" } @column_index;
+
+  print qq|
+       </tr>
+|;
+
+  # add sort and escape callback
+  $form->{callback} = "$callback&sort=$form->{sort}";
+  $callback = $form->escape($form->{callback});
+
+  if (@{ $form->{AP} }) {
+    $sameitem = $form->{AP}->[0]->{$form->{sort}};
+  }
+  
+  # sums and tax on reports by Antonio Gallardo
+  #
+  foreach $ap (@{ $form->{AP} }) {
+
+    if ($form->{l_subtotal} eq 'Y') {
+      if ($sameitem ne $ap->{$form->{sort}}) {
+       &ap_subtotal;
+       $sameitem = $ap->{$form->{sort}};
+      }
+    }
+    
+    $column_data{netamount} = "<td align=right>".$form->format_amount(\%myconfig, $ap->{netamount}, 2, "&nbsp;")."</td>";
+    $column_data{tax} = "<td align=right>".$form->format_amount(\%myconfig, $ap->{amount} - $ap->{netamount}, 2, "&nbsp;") . "</td>";
+    $column_data{amount} = "<td align=right>".$form->format_amount(\%myconfig, $ap->{amount}, 2, "&nbsp;") . "</td>";
+    $column_data{paid} = "<td align=right>".$form->format_amount(\%myconfig, $ap->{paid}, 2, "&nbsp;")."</td>";
+    $column_data{due} = "<td align=right>".$form->format_amount(\%myconfig, $ap->{amount} - $ap->{paid}, 2, "&nbsp;")."</td>";
+
+    $totalnetamount += $ap->{netamount};
+    $totalamount += $ap->{amount};
+    $totalpaid += $ap->{paid};
+    $totaldue += ($ap->{amount} - $ap->{paid});
+
+    $subtotalnetamount += $ap->{netamount};
+    $subtotalamount += $ap->{amount};
+    $subtotalpaid += $ap->{paid};
+    $subtotaldue += ($ap->{amount} - $ap->{paid});
+
+    $column_data{transdate} = "<td>$ap->{transdate}&nbsp;</td>";
+    $column_data{duedate} = "<td>$ap->{duedate}&nbsp;</td>";
+    $column_data{datepaid} = "<td>$ap->{datepaid}&nbsp;</td>";
+
+    $module = ($ap->{invoice}) ? "ir.pl" : $form->{script};
+
+    $column_data{invnumber} = qq|<td><a href="$module?action=edit&path=$form->{path}&id=$ap->{id}&login=$form->{login}&password=$form->{password}&callback=$callback">$ap->{invnumber}</a></td>|;
+    $column_data{id} = "<td>$ap->{id}</td>";
+    $column_data{ordnumber} = "<td>$ap->{ordnumber}&nbsp;</td>";
+    $column_data{name} = "<td>$ap->{name}</td>";
+    $ap->{notes} =~ s/\r\n/<br>/g;
+    $column_data{notes} = "<td>$ap->{notes}&nbsp;</td>";
+    $column_data{employee} = "<td>$ap->{employee}&nbsp;</td>";
+    
+    $i++;
+    $i %= 2;
+    print "
+        <tr class=listrow$i >
+";
+    
+    map { print "\n$column_data{$_}" } @column_index;
+
+    print qq|
+       </tr>
+|;
+
+  }
+  
+  if ($form->{l_subtotal} eq 'Y') {
+    &ap_subtotal;
+  }
+  
+  # print totals
+  print qq|
+        <tr class=listtotal>
+|;
+  
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+  
+  $column_data{netamount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalnetamount, 2, "&nbsp;")."</th>";
+  $column_data{tax} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount - $totalnetamount, 2, "&nbsp;")."</th>";
+  $column_data{amount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount, 2, "&nbsp;")."</th>";
+  $column_data{paid} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalpaid, 2, "&nbsp;")."</th>";
+  $column_data{due} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totaldue, 2, "&nbsp;")."</th>";
+
+  map { print "$column_data{$_}\n" } @column_index;
+
+  print qq|
+        </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>  
+</table>
+
+<br>
+<form method=post action=$form->{script}>
+<input name=callback type=hidden value="$form->{callback}">
+  
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+   
+<input class=submit type=submit name=action value="|.$locale->text('AP Transaction').qq|">
+
+<input class=submit type=submit name=action value="|.$locale->text('Vendor Invoice').qq|">
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub ap_subtotal {
+
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+  
+  $column_data{netamount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalnetamount, 2, "&nbsp;")."</th>";
+  $column_data{tax} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount - $subtotalnetamount, 2, "&nbsp;")."</th>";
+  $column_data{amount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount, 2, "&nbsp;")."</th>";
+  $column_data{paid} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalpaid, 2, "&nbsp;")."</th>";
+  $column_data{due} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotaldue, 2, "&nbsp;")."</th>";
+
+  $subtotalnetamount = 0;
+  $subtotalamount = 0;
+  $subtotalpaid = 0;
+  $subtotaldue = 0;
+
+  print "<tr class=listsubtotal>";
+  
+  map { print "\n$column_data{$_}" } @column_index;
+
+  print qq|
+  </tr>
+|;
+
+}
+
+
+
diff --git a/sql-ledger/bin/mozilla/ar.pl b/sql-ledger/bin/mozilla/ar.pl
new file mode 100644 (file)
index 0000000..341c038
--- /dev/null
@@ -0,0 +1,1135 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Accounts Receivables
+#
+#======================================================================
+
+
+use SL::AR;
+use SL::IS;
+use SL::PE;
+
+require "$form->{path}/arap.pl";
+
+1;
+# end of main
+
+# this is for our long dates
+# $locale->text('January')
+# $locale->text('February')
+# $locale->text('March')
+# $locale->text('April')
+# $locale->text('May ')
+# $locale->text('June')
+# $locale->text('July')
+# $locale->text('August')
+# $locale->text('September')
+# $locale->text('October')
+# $locale->text('November')
+# $locale->text('December')
+
+# this is for our short month
+# $locale->text('Jan')
+# $locale->text('Feb')
+# $locale->text('Mar')
+# $locale->text('Apr')
+# $locale->text('May')
+# $locale->text('Jun')
+# $locale->text('Jul')
+# $locale->text('Aug')
+# $locale->text('Sep')
+# $locale->text('Oct')
+# $locale->text('Nov')
+# $locale->text('Dec')
+
+
+sub add {
+
+  $form->{title} = "Add";
+  $form->{callback} = "$form->{script}?action=add&path=$form->{path}&login=$form->{login}&password=$form->{password}" unless $form->{callback};
+
+  &create_links;
+  &display_form;
+  
+}
+
+
+sub edit {
+
+  $form->{title} = "Edit";
+
+  &create_links;
+  &display_form;
+
+}
+
+
+sub display_form {
+
+  &form_header;
+  &form_footer;
+
+}
+
+
+sub create_links {
+
+  $form->create_links("AR", \%myconfig, "customer");
+  $duedate = $form->{duedate};
+  
+  $taxincluded = $form->{taxincluded};
+  
+  IS->get_customer(\%myconfig, \%$form);
+
+  $form->{duedate} = $duedate;
+  $form->{oldcustomer} = "$form->{customer}--$form->{customer_id}";
+
+  # currencies
+  @curr = split /:/, $form->{currencies};
+  chomp $curr[0];
+  $form->{defaultcurrency} = $curr[0];
+
+  map { $form->{selectcurrency} .= "<option>$_\n" } @curr;
+
+  # customers
+  if (@{ $form->{all_customer} }) {
+    $form->{customer} = "$form->{customer}--$form->{customer_id}";
+    map { $form->{selectcustomer} .= "<option>$_->{name}--$_->{id}\n" } (@{ $form->{all_customer} });
+  }
+  
+  # forex
+  $form->{forex} = $form->{exchangerate};
+  $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1;
+  
+  foreach $key (keys %{ $form->{AR_links} }) {
+       
+    foreach $ref (@{ $form->{AR_links}{$key} }) {
+      if ($key eq 'AR_tax') {
+       $form->{"selectAR_tax_$ref->{accno}"} = "<option>$ref->{accno}--$ref->{description}\n";
+       next;
+      }
+      $form->{"select$key"} .= "<option>$ref->{accno}--$ref->{description}\n";
+    }
+    
+    # if there is a value we have an old entry
+    for $i (1 .. scalar @{ $form->{acc_trans}{$key} }) {
+      if ($key eq "AR_paid") {
+       $form->{"AR_paid_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
+       # reverse paid
+       $form->{"paid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{amount} * -1;
+       $form->{"datepaid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{transdate};
+       $form->{"source_$i"} = $form->{acc_trans}{$key}->[$i-1]->{source};
+       
+       $form->{"forex_$i"} = $form->{"exchangerate_$i"} = $form->{acc_trans}{$key}->[$i-1]->{exchangerate};
+       
+       $form->{paidaccounts}++;
+      } else {
+     
+       $akey = $key;
+       $akey =~ s/AR_//;
+       
+        if ($key eq "AR_tax") {
+
+         $form->{"${key}_$form->{acc_trans}{$key}->[$i-1]->{accno}"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
+         $form->{"${akey}_$form->{acc_trans}{$key}->[$i-1]->{accno}"} = $form->round_amount($form->{acc_trans}{$key}->[$i-1]->{amount} / $exchangerate, 2);
+         $totaltax += $form->{"${akey}_$form->{acc_trans}{$key}->[$i-1]->{accno}"};
+       } else {
+         $form->{"${akey}_$i"} = $form->round_amount($form->{acc_trans}{$key}->[$i-1]->{amount} / $exchangerate, 2);
+         if ($akey eq 'amount') {
+           $form->{rowcount}++;
+           $totalamount += $form->{"${akey}_$i"};
+
+           $form->{"oldprojectnumber_$i"} = $form->{"projectnumber_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{projectnumber}";
+           $form->{"project_id_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{project_id}";
+         }
+         $form->{"${key}_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
+       }
+      }
+    }
+  }
+
+  $form->{taxincluded} = $taxincluded if ($form->{id});
+  $form->{paidaccounts} = 1 if not defined $form->{paidaccounts};
+
+  if ($form->{taxincluded} && $totalamount) {
+    # add tax to amounts and invtotal
+    for $i (1 .. $form->{rowcount}) {
+      $taxamount = $totaltax * $form->{"amount_$i"} / $totalamount;
+      $tax = $form->round_amount($taxamount, 2);
+      $diff += ($taxamount - $tax);
+      $form->{"amount_$i"} += $tax;
+    }
+    $form->{amount_1} += $form->round_amount($diff, 2);
+  }
+
+  $form->{invtotal} = $totalamount + $totaltax;
+  $form->{rowcount}++ if $form->{id};
+  
+  $form->{AR} = $form->{AR_1};
+  
+  $form->{locked} = ($form->datetonum($form->{transdate}, \%myconfig) <= $form->datetonum($form->{closedto}, \%myconfig));
+
+}
+
+
+sub form_header {
+
+  $title = $form->{title};
+  $form->{title} = $locale->text("$title Accounts Receivables Transaction");
+
+  $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : "";
+  
+# $locale->text('Add Accounts Receivables Transaction')
+# $locale->text('Edit Accounts Receivables Transaction')
+
+  # set option selected
+  foreach $item (qw(AR customer currency)) {
+    $form->{"select$item"} =~ s/ selected//;
+    $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
+  }
+  
+  # format amounts
+  $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate});
+  
+  $form->{creditlimit} = $form->format_amount(\%myconfig, $form->{creditlimit}, 0, "0");
+  $form->{creditremaining} = $form->format_amount(\%myconfig, $form->{creditremaining}, 0, "0");
+
+  $exchangerate = qq|
+<input type=hidden name=forex value=$form->{forex}>
+|;
+  if ($form->{currency} ne $form->{defaultcurrency}) {
+    if ($form->{forex}) {
+      $exchangerate .= qq|
+       <th align=right>|.$locale->text('Exchangerate').qq|</th>
+       <td><input type=hidden name=exchangerate value=$form->{exchangerate}>$form->{exchangerate}</td>
+|;
+    } else {
+      $exchangerate .= qq|
+        <th align=right>|.$locale->text('Exchangerate').qq|</th>
+        <td><input name=exchangerate size=10 value=$form->{exchangerate}></td>
+|;
+    }
+  }
+  
+  $taxincluded = "";
+  if ($form->{taxaccounts}) {
+    $taxincluded = qq|
+             <tr>
+               <td align=right><input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}></td>
+               <th align=left nowrap>|.$locale->text('Tax Included').qq|</th>
+             </tr>
+|;
+  }
+
+  if (($rows = $form->numtextrows($form->{notes}, 50)) < 2) {
+    $rows = 2;
+  }
+  $notes = qq|<textarea name=notes rows=$rows cols=50 wrap=soft>$form->{notes}</textarea>|;
+  
+
+  $form->header;
+  
+  $n = ($form->{creditremaining} =~ /-/) ? "0" : "1";
+
+  $customer = ($form->{selectcustomer}) ? qq|<select name=customer>$form->{selectcustomer}</select>| : qq|<input name=customer value="$form->{customer}" size=35>|;
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=id value=$form->{id}>
+<input type=hidden name=sort value=$form->{sort}>
+<input type=hidden name=closedto value=$form->{closedto}>
+<input type=hidden name=locked value=$form->{locked}>
+<input type=hidden name=title value="$title">
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr valign=top>
+    <td>
+      <table width=100%>
+        <tr valign=top>
+         <td>
+           <table>
+             <tr>
+               <th align="right" nowrap>|.$locale->text('Customer').qq|</th>
+               <td colspan=3>$customer</td>
+               <input type=hidden name=selectcustomer value="$form->{selectcustomer}">
+               <input type=hidden name=oldcustomer value="$form->{oldcustomer}">
+               <input type=hidden name=customer_id value="$form->{customer_id}">
+               <input type=hidden name=terms value=$form->{terms}>
+             </tr>
+             <tr>
+               <td></td>
+               <td colspan=3>
+                 <table width=100%>
+                   <tr>
+                     <th align=left nowrap>|.$locale->text('Credit Limit').qq|</th>
+                     <td>$form->{creditlimit}</td>
+                     <th align=left nowrap>|.$locale->text('Remaining').qq|</th>
+                     <td class="plus$n">$form->{creditremaining}</td>
+                     <input type=hidden name=creditlimit value=$form->{creditlimit}>
+                     <input type=hidden name=creditremaining value=$form->{creditremaining}>
+                   </tr>
+                 </table>
+               </td>
+             </tr>
+             $taxincluded
+             <tr>
+               <th align=right>|.$locale->text('Currency').qq|</th>
+               <td><select name=currency>$form->{selectcurrency}</select></td>
+               <input type=hidden name=selectcurrency value="$form->{selectcurrency}">
+               <input type=hidden name=defaultcurrency value=$form->{defaultcurrency}>
+               <input type=hidden name=fxgain_accno value=$form->{fxgain_accno}>
+               <input type=hidden name=fxloss_accno value=$form->{fxloss_accno}>
+               $exchangerate
+             </tr>
+           </table>
+         </td>
+         <td align=right>
+           <table>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th>
+               <td><input name=invnumber size=11 value="$form->{invnumber}"></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Order Number').qq|</th>
+               <td><input name=ordnumber size=11 value="$form->{ordnumber}"></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Invoice Date').qq|</th>
+               <td><input name=transdate size=11 title="($myconfig{'dateformat'})" value=$form->{transdate}></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Due Date').qq|</th>
+               <td><input name=duedate size=11 title="$myconfig{'dateformat'}" value=$form->{duedate}></td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+    
+<input type=hidden name=selectAR_amount value="$form->{selectAR_amount}">
+<input type=hidden name=rowcount value=$form->{rowcount}>
+|;
+
+  $amount = $locale->text('Amount');
+  $project = $locale->text('Project');
+  
+  for $i (1 .. $form->{rowcount}) {
+    
+    $form->{"selectAR_amount"} =~ s/ selected//;
+    $form->{"selectAR_amount"} =~ s/option>\Q$form->{"AR_amount_$i"}\E/option selected>$form->{"AR_amount_$i"}/;
+    
+    # format amounts
+    $form->{"amount_$i"} = $form->format_amount(\%myconfig, $form->{"amount_$i"}, 2);
+
+    print qq|
+       <tr>
+         <th align=right>$amount</th>
+         <td><input name="amount_$i" size=10 value=$form->{"amount_$i"}></td>
+         <th>$project</th>
+         <td><input name="projectnumber_$i" size=20 value="$form->{"projectnumber_$i"}">
+             <input type=hidden name="project_id_$i" value=$form->{"project_id_$i"}>
+             <input type=hidden name="oldprojectnumber_$i" value="$form->{"oldprojectnumber_$i"}"></td>
+         <td width=50%><select name="AR_amount_$i">$form->{"selectAR_amount"}</select></td>
+       </tr>
+|;
+    $amount = "";
+    $project = "";
+  }
+
+  $taxlabel = ($form->{taxincluded}) ? $locale->text('Tax Included') : $locale->text('Tax');
+  
+  foreach $item (split / /, $form->{taxaccounts}) {
+
+    $form->{"tax_$item"} = $form->format_amount(\%myconfig, $form->{"tax_$item"}, 2);
+    print qq|
+        <tr>
+         <th align=right nowrap>$taxlabel</th>
+         <td><input name="tax_$item" size=10 value=$form->{"tax_$item"}></td>
+         <td colspan=2></td>
+         <td><select name="AR_tax_$item">$form->{"selectAR_tax_$item"}</select></td>
+       </tr>
+       <input type=hidden name="${item}_rate" value="$form->{"${item}_rate"}">
+       <input type=hidden name="${item}_description" value="$form->{"${item}_description"}">
+       <input type=hidden name="selectAR_tax_$item" value="$form->{"selectAR_tax_$item"}">
+|;
+  
+  }
+
+  $form->{invtotal} = $form->format_amount(\%myconfig, $form->{invtotal}, 2);
+
+  print qq|
+        <tr>
+
+         <th align=right>|.$locale->text('Total').qq|</th>
+         <th align=left>$form->{invtotal}</th>
+
+         <input type=hidden name=oldinvtotal value=$form->{oldinvtotal}>
+         <input type=hidden name=oldtotalpaid value=$form->{oldtotalpaid}>
+
+         <input type=hidden name=taxaccounts value="$form->{taxaccounts}">
+
+         <td colspan=2></td>
+         <td><select name=AR>$form->{selectAR}</select></td>
+          <input type=hidden name=selectAR value="$form->{selectAR}">
+  
+        </tr>
+        <tr>
+         <th align=right>|.$locale->text('Notes').qq|</th>
+         <td colspan=4>$notes</td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr>
+         <th class=listheading colspan=5>|.$locale->text('Payments').qq|</th>
+       </tr>
+|;
+
+
+  if ($form->{currency} eq $form->{defaultcurrency}) {
+    @column_index = qw(datepaid source paid AR_paid);
+  } else {
+    @column_index = qw(datepaid source paid exchangerate AR_paid);
+  }
+
+  $column_data{datepaid} = "<th>".$locale->text('Date')."</th>";
+  $column_data{paid} = "<th>".$locale->text('Amount')."</th>";
+  $column_data{exchangerate} = "<th>".$locale->text('Exch')."</th>";
+  $column_data{AR_paid} = "<th>".$locale->text('Account')."</th>";
+  $column_data{source} = "<th>".$locale->text('Source')."</th>";
+  
+  print "
+        <tr>
+";
+  map { print "$column_data{$_}\n" } @column_index;
+  print "
+        </tr>
+";
+
+  $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"});
+  for $i (1 .. $form->{paidaccounts}) {
+    print "
+        <tr>
+";
+
+    $form->{"selectAR_paid_$i"} = $form->{selectAR_paid};
+    $form->{"selectAR_paid_$i"} =~ s/option>\Q$form->{"AR_paid_$i"}\E/option selected>$form->{"AR_paid_$i"}/;
+  
+    # format amounts
+    $form->{"paid_$i"} = $form->format_amount(\%myconfig, $form->{"paid_$i"}, 2);
+    $form->{"exchangerate_$i"} = $form->format_amount(\%myconfig, $form->{"exchangerate_$i"});
+
+    $exchangerate = qq|&nbsp;|;
+    if ($form->{currency} ne $form->{defaultcurrency}) {
+      if ($form->{"forex_$i"}) {
+       $exchangerate = qq|<input type=hidden name="exchangerate_$i" value=$form->{"exchangerate_$i"}>$form->{"exchangerate_$i"}|;
+      } else {
+       $exchangerate = qq|<input name="exchangerate_$i" size=10 value=$form->{"exchangerate_$i"}>|;
+      }
+    }
+    
+    $exchangerate .= qq|
+<input type=hidden name="forex_$i" value=$form->{"forex_$i"}>
+|;
+
+    $column_data{"paid_$i"} = qq|<td align=center><input name="paid_$i" size=10 value=$form->{"paid_$i"}></td>|;
+    $column_data{"AR_paid_$i"} = qq|<td align=center><select name="AR_paid_$i">$form->{"selectAR_paid_$i"}</select></td>|;
+    $column_data{"exchangerate_$i"} = qq|<td align=center>$exchangerate</td>|;
+    $column_data{"datepaid_$i"} = qq|<td align=center><input name="datepaid_$i" size=11 value=$form->{"datepaid_$i"}></td>|;
+    $column_data{"source_$i"} = qq|<td align=center><input name="source_$i" size=10 value="$form->{"source_$i"}"></td>|;
+
+    map { print qq|$column_data{"${_}_$i"}\n| } @column_index;
+    
+    print "
+        </tr>
+";
+  }
+  
+  print qq|
+<input type=hidden name=paidaccounts value=$form->{paidaccounts}>
+<input type=hidden name=selectAR_paid value="$form->{selectAR_paid}">
+
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+|;
+
+}
+
+
+sub form_footer {
+
+  print qq|
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br>
+|;
+
+  $transdate = $form->datetonum($form->{transdate}, \%myconfig);
+  $closedto = $form->datetonum($form->{closedto}, \%myconfig);
+  
+  if ($form->{id}) {
+    
+      print qq|<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+|;
+
+    if (!$form->{revtrans}) {
+      if (!$form->{locked}) {
+       print qq|
+       <input class=submit type=submit name=action value="|.$locale->text('Post').qq|">
+       <input class=submit type=submit name=action value="|.$locale->text('Delete').qq|">
+|;
+      }
+    }
+
+    if ($transdate > $closedto) {
+      print qq|
+<input class=submit type=submit name=action value="|.$locale->text('Post as new').qq|">
+|;
+    }
+
+  } else {
+    if ($transdate > $closedto) {
+      print qq|<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+      <input class=submit type=submit name=action value="|.$locale->text('Post').qq|">|;
+    }
+  }
+
+  print "
+</form>
+
+</body>
+</html>
+";
+
+}
+
+
+sub update {
+  my $display = shift;
+
+  if ($display) {
+    goto TAXCALC;
+  }
+
+  $form->{invtotal} = 0;
+  
+  map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate creditlimit creditremaining);
+
+  @flds = qw(amount AR_amount projectnumber oldprojectnumber project_id);
+  $count = 0;
+  @a = ();
+  for $i (1 .. $form->{rowcount}) {
+    $form->{"amount_$i"} = $form->parse_amount(\%myconfig, $form->{"amount_$i"});
+    if ($form->{"amount_$i"}) {
+      push @a, {};
+      $j = $#a;
+
+      map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
+      $count++;
+    }
+  }
+
+  $form->redo_rows(\@flds, \@a, $count, $form->{rowcount});
+  $form->{rowcount} = $count + 1;
+
+  map { $form->{invtotal} += $form->{"amount_$_"} } (1 .. $form->{rowcount});
+
+  $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, 'buy')));
+
+
+  $form->{invdate} = $form->{transdate};
+  &check_name(customer);
+
+  &check_project;
+
+
+TAXCALC:
+  # recalculate taxes
+  if ($form->{taxincluded}) {
+    $taxrate = 0;
+
+    map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{taxaccounts};
+
+    foreach $item (split / /, $form->{taxaccounts}) {
+      $amount = ($form->{invtotal} * (1 - 1 / (1 + $taxrate)) * $form->{"${item}_rate"} / $taxrate) if $taxrate;
+      $form->{"tax_$item"} = $form->round_amount($amount, 2);
+      $taxdiff += ($amount - $form->{"tax_$item"});
+      if (abs $taxdiff >= 0.005) {
+       $form->{"tax_$item"} += $form->round_amount($taxdiff, 2);
+       $taxdiff = 0;
+      }
+      $form->{"selectAR_tax_$item"} = qq|<option>$item--$form->{"${item}_description"}|;
+      $totaltax += $form->{"tax_$item"};
+    }
+  } else {
+    foreach $item (split / /, $form->{taxaccounts}) {
+      $form->{"tax_$item"} = $form->round_amount($form->{invtotal} * $form->{"${item}_rate"}, 2);
+      $form->{"selectAR_tax_$item"} = qq|<option>$item--$form->{"${item}_description"}|;
+      $totaltax += $form->{"tax_$item"};
+    }
+  }
+
+  $form->{invtotal} = ($form->{taxincluded}) ? $form->{invtotal} : $form->{invtotal} + $totaltax;
+
+  for $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"}) {
+      map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(paid exchangerate);
+
+      $totalpaid += $form->{"paid_$i"};
+
+      $form->{"exchangerate_$i"} = $exchangerate if ($form->{"forex_$i"} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'buy')));
+    }
+  }
+
+  $form->{creditremaining} -= ($form->{invtotal} - $totalpaid + $form->{oldtotalpaid} - $form->{oldinvtotal});
+  $form->{oldinvtotal} = $form->{invtotal};
+  $form->{oldtotalpaid} = $totalpaid;
+  
+  &display_form;
+  
+}
+
+
+sub post {
+
+  # check if there is an invoice number, invoice and due date
+  $form->isblank("invnumber", $locale->text('Invoice Number missing!'));
+  $form->isblank("transdate", $locale->text('Invoice Date missing!'));
+  $form->isblank("duedate", $locale->text('Due Date missing!'));
+  $form->isblank("customer", $locale->text('Customer missing!'));
+
+  $closedto = $form->datetonum($form->{closedto}, \%myconfig);
+  $transdate = $form->datetonum($form->{transdate}, \%myconfig);
+  
+  $form->error($locale->text('Cannot post transaction for a closed period!')) if ($transdate <= $closedto);
+
+  $form->isblank("exchangerate", $locale->text('Exchangerate missing!')) if ($form->{currency} ne $form->{defaultcurrency});
+  
+  for $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"}) {
+      $datepaid = $form->datetonum($form->{"datepaid_$i"}, \%myconfig);
+      
+      $form->isblank("datepaid_$i", $locale->text('Payment date missing!'));
+
+      $form->error($locale->text('Cannot post payment for a closed period!')) if ($datepaid <= $closedto);
+
+      if ($form->{currency} ne $form->{defaultcurrency}) {
+       $form->{"exchangerate_$i"} = $form->{exchangerate} if ($transdate == $datepaid);
+       $form->isblank("exchangerate_$i", $locale->text('Exchangerate for payment missing!'));
+      }
+    }
+  }
+
+  # if oldcustomer ne customer redo form
+  ($customer) = split /--/, $form->{customer};
+  if ($form->{oldcustomer} ne "$customer--$form->{customer_id}") {
+    &update;
+    exit;
+  }
+
+  $form->{id} = 0 if $form->{postasnew};
+
+  $form->redirect($locale->text('Transaction posted!')) if (AR->post_transaction(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot post transaction!'));
+
+}
+
+
+sub post_as_new {
+
+  $form->{postasnew} = 1;
+  &post;
+
+}
+
+
+sub delete {
+
+  $form->{title} = $locale->text('Confirm!');
+  
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+|;
+
+  foreach $key (keys %$form) {
+    print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
+  }
+
+  print qq|
+<h2 class=confirm>$form->{title}</h2>
+
+<h4>|.$locale->text('Are you sure you want to delete Transaction').qq| $form->{invnumber}</h4>
+
+<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+sub yes {
+
+  $form->redirect($locale->text('Transaction deleted!')) if (AR->delete_transaction(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot delete transaction!'));
+
+}
+
+
+sub search {
+
+  # setup customer selection
+  $form->all_vc(\%myconfig, "customer");
+
+  if (@{ $form->{all_customer} }) { 
+    map { $customer .= "<option>$_->{name}--$_->{id}\n" } @{ $form->{all_customer} };
+    $customer = qq|<select name=customer><option>\n$customer</select>|;
+  } else {
+    $customer = qq|<input name=customer size=35>|;
+  }
+    
+  $form->{title} = $locale->text('AR Transactions');
+    
+  $form->header;
+  
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr><th class=listtop>$form->{title}</th></tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table>
+       <tr>
+         <th align=right>|.$locale->text('Customer').qq|</th>
+         <td colspan=3>$customer</td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th>
+         <td colspan=3><input name=invnumber size=20></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Order Number').qq|</th>
+         <td colspan=3><input name=ordnumber size=20></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Notes').qq|</th>
+         <td colspan=3><input name=notes size=40></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('From').qq|</th>
+         <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td>
+         <th align=right>|.$locale->text('to').qq|</th>
+         <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td>
+       </tr>
+       <input type=hidden name=sort value=transdate>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Include in Report').qq|</th>
+         <td>
+           <table width=100%>
+             <tr>
+               <td align=right><input name=open class=checkbox type=checkbox value=Y checked></td>
+               <td nowrap>|.$locale->text('Open').qq|</td>
+               <td align=right><input name=closed class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Closed').qq|</td>
+             </tr>
+             <tr>
+               <td align=right><input name="l_id" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('ID').qq|</td>
+               <td align=right><input name="l_invnumber" class=checkbox type=checkbox value=Y checked></td>
+               <td nowrap>|.$locale->text('Invoice Number').qq|</td>
+               <td align=right><input name="l_ordnumber" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Order Number').qq|</td>
+               <td align=right><input name="l_transdate" class=checkbox type=checkbox value=Y checked></td>
+               <td nowrap>|.$locale->text('Invoice Date').qq|</td>
+             </tr>
+             <tr>
+               <td align=right><input name="l_name" class=checkbox type=checkbox value=Y checked></td>
+               <td nowrap>|.$locale->text('Customer').qq|</td>
+               <td align=right><input name="l_netamount" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Amount').qq|</td>
+               <td align=right><input name="l_tax" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Tax').qq|</td>
+               <td align=right><input name="l_amount" class=checkbox type=checkbox value=Y checked></td>
+               <td nowrap>|.$locale->text('Total').qq|</td>
+             </tr>
+             <tr>
+               <td align=right><input name="l_datepaid" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Date Paid').qq|</td>
+               <td align=right><input name="l_paid" class=checkbox type=checkbox value=Y checked></td>
+               <td nowrap>|.$locale->text('Paid').qq|</td>
+               <td align=right><input name="l_duedate" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Due Date').qq|</td>
+               <td align=right><input name="l_due" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Amount Due').qq|</td>
+             </tr>
+             <tr>
+               <td align=right><input name="l_notes" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Notes').qq|</td>
+               <td align=right><input name="l_employee" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Salesperson').qq|</td>
+               <td align=right><input name="l_shippingpoint" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Ship via').qq|</td>
+             </tr>
+             <tr>
+               <td align=right><input name="l_subtotal" class=checkbox type=checkbox value=Y></td>
+               <td nowrap>|.$locale->text('Subtotal').qq|</td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<input type=hidden name=nextsub value=$form->{nextsub}>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub ar_transactions {
+
+  $form->{customer} = $form->unescape($form->{customer});
+  ($form->{customer}, $form->{customer_id}) = split(/--/, $form->{customer});
+
+  AR->ar_transactions(\%myconfig, \%$form);
+
+  $callback = "$form->{script}?action=ar_transactions&path=$form->{path}&login=$form->{login}&password=$form->{password}";
+  $href = $callback;
+
+  if ($form->{customer}) {
+    $callback .= "&customer=".$form->escape($form->{customer});
+    $href .= "&customer=".$form->escape($form->{customer});
+    $option = $locale->text('Customer')." : $form->{customer}";
+  }
+  if ($form->{invnumber}) {
+    $callback .= "&invnumber=$form->{invnumber}";
+    $href .= "&invnumber=".$form->escape($form->{invnumber});
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('Invoice Number')." : $form->{invnumber}";
+  }
+  if ($form->{ordnumber}) {
+    $callback .= "&ordnumber=$form->{ordnumber}";
+    $href .= "&ordnumber=".$form->escape($form->{ordnumber});
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('Order Number')." : $form->{ordnumber}";
+  }
+  if ($form->{notes}) {
+    $callback .= "&notes=$form->{notes}";
+    $href .= "&notes=".$form->escape($form->{notes});
+    $option .= "\n<br>" if $option;
+    $option .= $locale->text('Notes')." : $form->{notes}";
+  }
+  
+  if ($form->{transdatefrom}) {
+    $callback .= "&transdatefrom=$form->{transdatefrom}";
+    $href .= "&transdatefrom=$form->{transdatefrom}";
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('From')."&nbsp;".$locale->date(\%myconfig, $form->{transdatefrom}, 1);
+  }
+  if ($form->{transdateto}) {
+    $callback .= "&transdateto=$form->{transdateto}";
+    $href .= "&transdateto=$form->{transdateto}";
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('to')."&nbsp;".$locale->date(\%myconfig, $form->{transdateto}, 1);
+  }
+  if ($form->{open}) {
+    $callback .= "&open=$form->{open}";
+    $href .= "&open=$form->{open}";
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('Open');
+  }
+  if ($form->{closed}) {
+    $callback .= "&closed=$form->{closed}";
+    $href .= "&closed=$form->{closed}";
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('Closed');
+  }
+
+  @columns = $form->sort_columns(qw(transdate id invnumber ordnumber name netamount tax amount paid datepaid due duedate notes employee shippingpoint));
+  
+  foreach $item (@columns) {
+    if ($form->{"l_$item"} eq "Y") {
+      push @column_index, $item;
+
+      # add column to href and callback
+      $callback .= "&l_$item=Y";
+      $href .= "&l_$item=Y";
+    }
+  }
+
+  if ($form->{l_subtotal} eq 'Y') {
+    $callback .= "&l_subtotal=Y";
+    $href .= "&l_subtotal=Y";
+  }
+  
+
+  $column_header{id} = "<th><a class=listheading href=$href&sort=id>".$locale->text('ID')."</a></th>";
+  $column_header{transdate} = "<th><a class=listheading href=$href&sort=transdate>".$locale->text('Date')."</a></th>";
+  $column_header{duedate} = "<th><a class=listheading href=$href&sort=duedate>".$locale->text('Due Date')."</a></th>";
+  $column_header{invnumber} = "<th><a class=listheading href=$href&sort=invnumber>".$locale->text('Invoice')."</a></th>";
+  $column_header{ordnumber} = "<th><a class=listheading href=$href&sort=ordnumber>".$locale->text('Order')."</a></th>";
+  $column_header{name} = "<th><a class=listheading href=$href&sort=name>".$locale->text('Customer')."</a></th>";
+  $column_header{netamount} = "<th class=listheading>" . $locale->text('Amount') . "</th>";
+  $column_header{tax} = "<th class=listheading>" . $locale->text('Tax') . "</th>";
+  $column_header{amount} = "<th class=listheading>" . $locale->text('Total') . "</th>";
+  $column_header{paid} = "<th class=listheading>" . $locale->text('Paid') . "</th>";
+  $column_header{datepaid} = "<th><a class=listheading href=$href&sort=datepaid>" . $locale->text('Date Paid') . "</a></th>";
+  $column_header{due} = "<th class=listheading>" . $locale->text('Amount Due') . "</th>";
+  $column_header{notes} = "<th class=listheading>".$locale->text('Notes')."</th>";
+  $column_header{employee} = "<th class=listheading><a class=listheading href=$href&sort=employee>".$locale->text('Salesperson')."</th>";
+
+  $column_header{shippingpoint} = "<th class=listheading><a class=listheading href=$href&sort=shippingpoint>" . $locale->text('Ship via') . "</a></th>";
+  
+
+  $form->{title} = $locale->text('AR Transactions');
+
+  $form->header;
+
+  print qq|
+<body>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>$option</td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+|;
+
+  map { print "\n$column_header{$_}" } @column_index;
+
+  print qq|
+       </tr>
+|;
+
+
+  # add sort and escape callback, this one we use for the add sub
+  $form->{callback} = $callback .= "&sort=$form->{sort}";
+
+  # escape callback for href
+  $callback = $form->escape($callback);
+  
+  if (@{ $form->{AR} }) {
+    $sameitem = $form->{AR}->[0]->{$form->{sort}};
+  }
+  
+  # sums and tax on reports by Antonio Gallardo
+  #
+  foreach $ar (@{ $form->{AR} }) {
+
+    if ($form->{l_subtotal} eq 'Y') {
+      if ($sameitem ne $ar->{$form->{sort}}) {
+       &ar_subtotal;
+      }
+    }
+    
+    $column_data{netamount} = "<td align=right>".$form->format_amount(\%myconfig, $ar->{netamount}, 2, "&nbsp;")."</td>";
+    $column_data{tax} = "<td align=right>".$form->format_amount(\%myconfig, $ar->{amount} - $ar->{netamount}, 2, "&nbsp;")."</td>";
+    $column_data{amount} = "<td align=right>".$form->format_amount(\%myconfig, $ar->{amount}, 2, "&nbsp;")."</td>";
+    $column_data{paid} = "<td align=right>".$form->format_amount(\%myconfig, $ar->{paid}, 2, "&nbsp;")."</td>";
+    $column_data{due} = "<td align=right>".$form->format_amount(\%myconfig, $ar->{amount} - $ar->{paid}, 2, "&nbsp;")."</td>";
+    
+    $subtotalnetamount += $ar->{netamount};
+    $subtotalamount += $ar->{amount};
+    $subtotalpaid += $ar->{paid};
+    $subtotaldue += $ar->{amount} - $ar->{paid};
+    
+    $totalnetamount += $ar->{netamount};
+    $totalamount += $ar->{amount};
+    $totalpaid += $ar->{paid};
+    $totaldue += ($ar->{amount} - $ar->{paid});
+    
+    $column_data{transdate} = "<td>$ar->{transdate}&nbsp;</td>";
+    $column_data{id} = "<td>$ar->{id}</td>";
+    $column_data{datepaid} = "<td>$ar->{datepaid}&nbsp;</td>";
+    $column_data{duedate} = "<td>$ar->{duedate}&nbsp;</td>";
+
+    $module = ($ar->{invoice}) ? "is.pl" : $form->{script};
+
+    $column_data{invnumber} = "<td><a href=$module?action=edit&id=$ar->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ar->{invnumber}</a></td>";
+    $column_data{ordnumber} = "<td>$ar->{ordnumber}&nbsp;</td>";
+    $column_data{name} = "<td>$ar->{name}</td>";
+    $ar->{notes} =~ s/\r\n/<br>/g;
+    $column_data{notes} = "<td>$ar->{notes}&nbsp;</td>";
+    $column_data{shippingpoint} = "<td>$ar->{shippingpoint}&nbsp;</td>";
+    $column_data{employee} = "<td>$ar->{employee}&nbsp;</td>";
+
+    $i++; $i %= 2;
+    print "
+        <tr class=listrow$i>
+";
+
+    map { print "\n$column_data{$_}" } @column_index;
+
+    print qq|
+        </tr>
+|;
+
+  
+  }
+
+  if ($form->{l_subtotal} eq 'Y') {
+    &ar_subtotal;
+  }
+
+  # print totals
+  print qq|
+        <tr class=listtotal>
+|;
+
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+  
+  $column_data{netamount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalnetamount, 2, "&nbsp;")."</th>";
+  $column_data{tax} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount - $totalnetamount, 2, "&nbsp;")."</th>";
+  $column_data{amount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount, 2, "&nbsp;")."</th>";
+  $column_data{paid} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalpaid, 2, "&nbsp;")."</th>";
+  $column_data{due} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totaldue, 2, "&nbsp;")."</th>";
+
+  map { print "\n$column_data{$_}" } @column_index;
+
+  print qq|
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<br>
+<form method=post action=$form->{script}>
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input class=submit type=submit name=action value="|.$locale->text('AR Transaction').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('Sales Invoice').qq|">
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub ar_subtotal {
+
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+  
+  $column_data{tax} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount - $subtotalnetamount, 2, "&nbsp;")."</th>";
+  $column_data{amount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount, 2, "&nbsp;")."</th>";
+  $column_data{paid} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalpaid, 2, "&nbsp;")."</th>";
+  $column_data{due} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotaldue, 2, "&nbsp;")."</th>";
+  
+  $subtotalnetamount = 0;
+  $subtotalamount = 0;
+  $subtotalpaid = 0;
+  $subtotaldue = 0;
+
+  $sameitem = $ar->{$form->{sort}};
+  
+  print "<tr class=listsubtotal>";
+
+  map { print "\n$column_data{$_}" } @column_index;
+
+print "
+</tr>
+";
+}
+
+
+
diff --git a/sql-ledger/bin/mozilla/arap.pl b/sql-ledger/bin/mozilla/arap.pl
new file mode 100644 (file)
index 0000000..fecd926
--- /dev/null
@@ -0,0 +1,406 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# common routines for gl, ar, ap, is, ir, oe
+#
+
+# any custom scripts for this one
+if (-f "$form->{path}/custom_arap.pl") {
+  eval { require "$form->{path}/custom_arap.pl"; };
+}
+if (-f "$form->{path}/$form->{login}_arap.pl") {
+  eval { require "$form->{path}/$form->{login}_arap.pl"; };
+}
+
+
+1;
+# end of main
+
+
+sub check_name {
+  my ($name) = @_;
+
+  my ($new_name, $new_id) = split /--/, $form->{$name};
+  my $i = 0;
+  
+  # if we use a selection
+  if ($form->{"select$name"}) {
+    if ($form->{"old$name"} ne $form->{$name}) {
+      # this is needed for is, ir and oe
+      map { delete $form->{"${_}_rate"} } (split / /, $form->{taxaccounts});
+      
+      # for credit calculations
+      $form->{oldinvtotal} = 0;
+      $form->{oldtotalpaid} = 0;
+      
+      $form->{"${name}_id"} = $new_id;
+      $form->{"old$name"} = "$new_name--$new_id";
+
+      IS->get_customer(\%myconfig, \%$form) if ($name eq 'customer');
+      IR->get_vendor(\%myconfig, \%$form) if ($name eq 'vendor');
+
+      $i = 1;
+    }
+  } else {
+
+    # check name, combine name and id
+    if ($form->{"old$name"} ne qq|$form->{$name}--$form->{"${name}_id"}|) {
+      # this is needed for is, ir and oe
+      map { delete $form->{"${_}_rate"} } (split / /, $form->{taxaccounts});
+
+      # for credit calculations
+      $form->{oldinvtotal} = 0;
+      $form->{oldtotalpaid} = 0;
+
+      # return one name or a list of names in $form->{name_list}
+      if (($i = $form->get_name(\%myconfig, $name)) > 1) {
+       &select_name($name);
+       exit;
+      }
+
+      if ($i == 1) {
+       # we got one name
+       $form->{"${name}_id"} = $form->{name_list}[0]->{id};
+       $form->{$name} = $form->{name_list}[0]->{name};
+       $form->{"old$name"} = qq|$form->{$name}--$form->{"${name}_id"}|;
+       
+       IS->get_customer(\%myconfig, \%$form) if ($name eq 'customer');
+       IR->get_vendor(\%myconfig, \%$form) if ($name eq 'vendor');
+       
+      } else {
+       # name is not on file
+       $msg = ucfirst $name . " not on file!";
+       $form->error($locale->text($msg));
+      }
+    }
+  }
+
+  $i;
+
+}
+
+# $locale->text('Customer not on file!')
+# $locale->text('Vendor not on file!')
+
+
+
+sub select_name {
+  my ($table) = @_;
+  
+  @column_index = qw(ndx name address);
+
+  $label = ucfirst $table;
+  $column_data{ndx} = qq|<th>&nbsp;</th>|;
+  $column_data{name} = qq|<th>|.$locale->text($label).qq|</th>|;
+  $column_data{address} = qq|<th>|.$locale->text('Address').qq|</th>|;
+  
+  # list items with radio button on a form
+  $form->header;
+
+  $title = $locale->text('Select from one of the names below');
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$title</th>
+  </tr>
+  <tr space=5></tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>|;
+
+  map { print "\n$column_data{$_}" } @column_index;
+  
+  print qq|
+       </tr>
+|;
+
+  my $i = 0;
+  foreach $ref (@{ $form->{name_list} }) {
+    $checked = ($i++) ? "" : "checked";
+
+    $ref->{name} =~ s/"/&quot;/g;
+    
+   $column_data{ndx} = qq|<td><input name=ndx class=radio type=radio value=$i $checked></td>|;
+   $column_data{name} = qq|<td><input name="new_name_$i" type=hidden value="$ref->{name}">$ref->{name}</td>|;
+   $column_data{address} = qq|<td>$ref->{address}</td>|;
+    
+    $j++; $j %= 2;
+    print qq|
+       <tr class=listrow$j>|;
+
+    map { print "\n$column_data{$_}" } @column_index;
+
+    print qq|
+       </tr>
+
+<input name="new_id_$i" type=hidden value=$ref->{id}>
+
+|;
+
+  }
+  
+  print qq|
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<input name=lastndx type=hidden value=$i>
+
+|;
+
+  # delete action variable
+  delete $form->{action};
+  delete $form->{name_list};
+    
+  # save all other form variables
+  foreach $key (keys %${form}) {
+    $form->{$key} =~ s/"/&quot;/g;
+    print qq|<input name=$key type=hidden value="$form->{$key}">\n|;
+  }
+
+  print qq|
+<input type=hidden name=nextsub value=name_selected>
+
+<input type=hidden name=vc value=$table>
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+sub name_selected {
+
+  # replace the variable with the one checked
+
+  # index for new item
+  $i = $form->{ndx};
+  
+  $form->{$form->{vc}} = $form->{"new_name_$i"};
+  $form->{"$form->{vc}_id"} = $form->{"new_id_$i"};
+  $form->{"old$form->{vc}"} = qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|;
+
+  # delete all the new_ variables
+  for $i (1 .. $form->{lastndx}) {
+    map { delete $form->{"new_${_}_$i"} } (id, name);
+  }
+  
+  map { delete $form->{$_} } qw(ndx lastndx nextsub);
+
+  IS->get_customer(\%myconfig, \%$form) if ($form->{vc} eq 'customer');
+  IR->get_vendor(\%myconfig, \%$form) if ($form->{vc} eq 'vendor');
+
+  &update(1);
+
+}
+
+
+sub add_transaction {
+  my ($module) = @_;
+
+  delete $form->{script};
+  $form->{action} = "add";
+  $form->{type} = "invoice" if $module =~ /(is|ir)/;
+
+  $form->{callback} = $form->escape($form->{callback},1);
+  map { $argv .= "$_=$form->{$_}&" } keys %$form;
+
+  exec ("perl", "$module.pl", $argv);
+
+}
+
+
+
+sub check_project {
+
+  for $i (1 .. $form->{rowcount}) {
+    $form->{"project_id_$i"} = "" unless $form->{"projectnumber_$i"};
+    if ($form->{"projectnumber_$i"} ne $form->{"oldprojectnumber_$i"}) {
+      if ($form->{"projectnumber_$i"}) {
+       # get new project
+       $form->{projectnumber} = $form->{"projectnumber_$i"};
+       if (($rows = PE->projects(\%myconfig, $form)) > 1) {
+         # check form->{project_list} how many there are
+         $form->{rownumber} = $i;
+         &select_project;
+         exit;
+       }
+
+       if ($rows == 1) {
+         $form->{"project_id_$i"} = $form->{project_list}->[0]->{id};
+         $form->{"projectnumber_$i"} = $form->{project_list}->[0]->{projectnumber};
+         $form->{"oldprojectnumber_$i"} = $form->{project_list}->[0]->{projectnumber};
+       } else {
+         # not on file
+         $form->error($locale->text('Project not on file!'));
+       }
+      }
+    }
+  }
+
+}
+
+
+sub select_project {
+  
+  @column_index = qw(ndx projectnumber description);
+
+  $column_data{ndx} = qq|<th>&nbsp;</th>|;
+  $column_data{projectnumber} = qq|<th>|.$locale->text('Number').qq|</th>|;
+  $column_data{description} = qq|<th>|.$locale->text('Description').qq|</th>|;
+  
+  # list items with radio button on a form
+  $form->header;
+
+  $title = $locale->text('Select from one of the projects below');
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=rownumber value=$form->{rownumber}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$title</th>
+  </tr>
+  <tr space=5></tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>|;
+
+  map { print "\n$column_data{$_}" } @column_index;
+  
+  print qq|
+        </tr>
+|;
+
+  my $i = 0;
+  foreach $ref (@{ $form->{project_list} }) {
+    $checked = ($i++) ? "" : "checked";
+
+    $ref->{name} =~ s/"/&quot;/g;
+    
+   $column_data{ndx} = qq|<td><input name=ndx class=radio type=radio value=$i $checked></td>|;
+   $column_data{projectnumber} = qq|<td><input name="new_projectnumber_$i" type=hidden value="$ref->{projectnumber}">$ref->{projectnumber}</td>|;
+   $column_data{description} = qq|<td>$ref->{description}</td>|;
+    
+    $j++; $j %= 2;
+    print qq|
+        <tr class=listrow$j>|;
+
+    map { print "\n$column_data{$_}" } @column_index;
+
+    print qq|
+        </tr>
+
+<input name="new_id_$i" type=hidden value=$ref->{id}>
+
+|;
+
+  }
+  
+  print qq|
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<input name=lastndx type=hidden value=$i>
+
+|;
+
+  # delete action variable
+  delete $form->{action};
+  delete $form->{project_list};
+    
+  # save all other form variables
+  foreach $key (keys %${form}) {
+    $form->{$key} =~ s/"/&quot;/g;
+    print qq|<input name=$key type=hidden value="$form->{$key}">\n|;
+  }
+
+  print qq|
+<input type=hidden name=nextsub value=project_selected>
+
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub project_selected {
+  
+  # replace the variable with the one checked
+
+  # index for new item
+  $i = $form->{ndx};
+  
+  $form->{"projectnumber_$form->{rownumber}"} = $form->{"new_projectnumber_$i"};
+  $form->{"oldprojectnumber_$form->{rownumber}"} = $form->{"new_projectnumber_$i"};
+  $form->{"project_id_$form->{rownumber}"} = $form->{"new_id_$i"};
+
+  # delete all the new_ variables
+  for $i (1 .. $form->{lastndx}) {
+    map { delete $form->{"new_${_}_$i"} } qw(id projectnumber description);
+  }
+  
+  map { delete $form->{$_} } qw(ndx lastndx nextsub);
+
+  &update;
+
+}
+
+
+sub continue { &{ $form->{nextsub} } };
+sub gl_transaction { &add };
+sub ar_transaction { &add_transaction(ar) };
+sub ap_transaction { &add_transaction(ap) };
+sub sales_invoice { &add_transaction(is) };
+sub vendor_invoice { &add_transaction(ir) };
+
diff --git a/sql-ledger/bin/mozilla/ca.pl b/sql-ledger/bin/mozilla/ca.pl
new file mode 100644 (file)
index 0000000..ed31005
--- /dev/null
@@ -0,0 +1,413 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# module for Chart of Accounts, Income Statement and Balance Sheet
+# search and edit transactions posted by the GL, AR and AP
+# 
+#======================================================================
+
+
+use SL::CA;
+
+1;
+# end of main
+
+# this is for our long dates
+# $locale->text('January')
+# $locale->text('February')
+# $locale->text('March')
+# $locale->text('April')
+# $locale->text('May ')
+# $locale->text('June')
+# $locale->text('July')
+# $locale->text('August')
+# $locale->text('September')
+# $locale->text('October')
+# $locale->text('November')
+# $locale->text('December')
+
+# this is for our short month
+# $locale->text('Jan')
+# $locale->text('Feb')
+# $locale->text('Mar')
+# $locale->text('Apr')
+# $locale->text('May')
+# $locale->text('Jun')
+# $locale->text('Jul')
+# $locale->text('Aug')
+# $locale->text('Sep')
+# $locale->text('Oct')
+# $locale->text('Nov')
+# $locale->text('Dec')
+
+
+sub chart_of_accounts {
+
+  CA->all_accounts(\%myconfig, \%$form);
+
+  @column_index = qw(accno gifi_accno description debit credit);
+
+  $column_header{accno} = qq|<th class=listheading>|.$locale->text('Account').qq|</th>\n|;
+  $column_header{gifi_accno} = qq|<th class=listheading>|.$locale->text('GIFI').qq|</th>\n|;
+  $column_header{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</th>\n|;
+  $column_header{debit} = qq|<th class=listheading>|.$locale->text('Debit').qq|</th>\n|;
+  $column_header{credit} = qq|<th class=listheading>|.$locale->text('Credit').qq|</th>\n|;
+  
+
+  $form->{title} = $locale->text('Chart of Accounts');
+
+  $colspan = $#column_index + 1;
+  
+  $form->header;
+
+  print qq|
+<body>
+  
+<table width=100%>
+  <tr><th class=listtop colspan=$colspan>$form->{title}</font></th></tr>
+  <tr height="5"></tr>
+  <tr class=listheading>|;
+
+  map { print $column_header{$_} } @column_index;
+
+  print qq|
+  </tr>
+|;
+
+  
+  foreach $ca (@{ $form->{CA} }) {
+
+    $description = $form->escape($ca->{description});
+    $gifi_description = $form->escape($ca->{gifi_description});
+    
+    $href = qq|$form->{script}?path=$form->{path}&action=list&accno=$ca->{accno}&login=$form->{login}&password=$form->{password}&description=$description&gifi_accno=$ca->{gifi_accno}&gifi_description=$gifi_description|;
+    
+    if ($ca->{charttype} eq "H") {
+      print qq|<tr class=listheading>|;
+      map { $column_data{$_} = "<th class=listheading>$ca->{$_}</th>"; } qw(accno description);
+      $column_data{gifi_accno} = "<th class=listheading>$ca->{gifi_accno}&nbsp;</font></th>";
+    } else {
+      $i++; $i %= 2;
+      print qq|<tr class=listrow$i>|;
+      $column_data{accno} = "<td><a href=$href>$ca->{accno}</a></td>";
+      $column_data{gifi_accno} = "<td><a href=$href&accounttype=gifi>$ca->{gifi_accno}</a>&nbsp;</td>";
+      $column_data{description} = "<td>$ca->{description}</td>";
+    }
+      
+    $column_data{debit} = "<td align=right>".$form->format_amount(\%myconfig, $ca->{debit}, 2, "&nbsp;")."</td>\n";
+    $column_data{credit} = "<td align=right>".$form->format_amount(\%myconfig, $ca->{credit}, 2, "&nbsp;")."</td>\n";
+    
+    $totaldebit += $ca->{debit};
+    $totalcredit += $ca->{credit};
+
+    map { print $column_data{$_} } @column_index;
+
+    print qq|
+</tr>
+|;
+  }
+
+  map { $column_data{$_} = "<td>&nbsp;</td>"; } qw(accno gifi_accno description);
+
+  $column_data{debit} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totaldebit, 2, 0)."</font></th>";
+  $column_data{credit} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalcredit, 2, 0)."</font></th>";
+  
+  print "<tr class=listtotal>";
+
+  map { print $column_data{$_} } @column_index;
+
+  print qq|
+</tr>
+<tr>
+  <td colspan=$colspan><hr size=3 noshade></td>
+</tr>
+</table>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub list {
+
+  $form->{title} = $locale->text('List Transactions');
+  if ($form->{accounttype} eq 'gifi') {
+    $form->{title} .= " - ".$locale->text('GIFI')." $form->{gifi_accno}";
+  } else {
+    $form->{title} .= " - ".$locale->text('Account')." $form->{accno}";
+  }
+  
+  $form->header;
+  
+  map { $form->{$_} =~ s/"/&quot;/g; } qw(description gifi_description);
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=accno value=$form->{accno}>
+<input type=hidden name=description value="$form->{description}">
+<input type=hidden name=sort value=transdate>
+
+<input type=hidden name=accounttype value=$form->{accounttype}>
+<input type=hidden name=gifi_accno value=$form->{gifi_accno}>
+<input type=hidden name=gifi_description value="$form->{gifi_description}">
+
+<table border=0 width=100%>
+  <tr><th class=listtop>$form->{title}</font></th></tr>
+  <tr height="5"></tr
+  <tr valign=top>
+    <td>
+      <table>
+       <tr>
+         <th align=right>|.$locale->text('From').qq|</th>
+         <td><input name=fromdate size=11 title="$myconfig{dateformat}"></td>
+         <th align=right>|.$locale->text('to').qq|</th>
+         <td><input name=todate size=11 title="$myconfig{dateformat}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Include in Report').qq|</th>
+         <td colspan=3>
+         <input name=l_subtotal class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Subtotal').qq|</td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr><td><hr size=3 noshade></td></tr>
+</table>
+
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=password value=$form->{password}>
+
+<br><input class=submit type=submit name=action value="|.$locale->text('List Transactions').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub list_transactions {
+
+  CA->all_transactions(\%myconfig, \%$form);
+
+  $description = $form->escape($form->{description});
+  $gifi_description = $form->escape($form->{gifi_description});
+
+  # construct href
+  $href = "$form->{script}?path=$form->{path}&action=list_transactions&accno=$form->{accno}&login=$form->{login}&password=$form->{password}&fromdate=$form->{fromdate}&todate=$form->{todate}&description=$description&accounttype=$form->{accounttype}&gifi_accno=$form->{gifi_accno}&gifi_description=$gifi_description&l_heading=$form->{l_heading}&l_subtotal=$form->{l_subtotal}";
+
+  # construct callback
+  $callback = "rp.pl?path=$form->{path}&action=generate_trial_balance&login=$form->{login}&password=$form->{password}&fromdate=$form->{fromdate}&todate=$form->{todate}&l_heading=$form->{l_heading}&l_subtotal=$form->{l_subtotal}&accounttype=$form->{accounttype}";
+
+  # figure out which column comes first
+  $column_header{transdate} = qq|<th><a class=listheading href=$href&sort=transdate>|.$locale->text('Date').qq|</a></th>|;
+  $column_header{reference} = qq|<th><a class=listheading href=$href&sort=reference>|.$locale->text('Reference').qq|</a></th>|;
+  $column_header{description} = qq|<th><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|;
+  $column_header{debit} = qq|<th class=listheading>|.$locale->text('Debit').qq|</th>|;
+  $column_header{credit} = qq|<th class=listheading>|.$locale->text('Credit').qq|</th>|;
+  $column_header{balance} = qq|<th class=listheading>|.$locale->text('Balance').qq|</th>|;
+
+  @column_index = $form->sort_columns(qw(transdate reference description debit credit));
+  
+  if ($form->{accounttype} eq 'gifi') {
+    map { $form->{$_} = $form->{"gifi_$_"} } qw(accno description);
+  }
+  if ($form->{accno}) {
+    push @column_index, "balance";
+  }
+    
+  $form->{title} = ($form->{accounttype} eq 'gifi') ? $locale->text('GIFI') : $locale->text('Account');
+  
+  $form->{title} .= " $form->{accno} - $form->{description}";
+  if ($form->{fromdate} || $form->{todate}) {
+    if ($form->{fromdate}) {
+      $fromdate = $locale->date(\%myconfig, $form->{fromdate}, 1);
+    }
+    if ($form->{todate}) {
+      $todate = $locale->date(\%myconfig, $form->{todate}, 1);
+    }
+    
+    $form->{period} = "$fromdate - $todate";
+  } else {
+    $form->{period} = $locale->date(\%myconfig, $form->current_date(\%myconfig),1);
+  }
+
+  
+  $form->header;
+
+  print qq|
+<body>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</font></th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>$form->{period}</td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+|;
+
+map { print "$column_header{$_}\n" } @column_index;
+
+print qq|
+       </tr>
+|;
+
+  # add sort to callback
+  $callback = $form->escape($callback . "&sort=$form->{sort}");
+
+  if (@{ $form->{CA} }) {
+    $sameitem = $form->{CA}->[0]->{$form->{sort}};
+  }
+
+  $ml = ($form->{category} =~ /(A|E)/) ? -1 : 1;
+  if ($form->{accno} && $form->{balance}) {
+    
+    map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+
+    $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $form->{balance} * $ml, 2, 0)."</td>";
+    
+    $i++; $i %= 2;
+    print qq|
+        <tr class=listrow$i>
+|;
+    map { print $column_data{$_} } @column_index;
+    print qq|
+       </tr>
+|;
+  }
+    
+  foreach $ca (@{ $form->{CA} }) {
+
+    if ($form->{l_subtotal} eq 'Y') {
+      if ($sameitem ne $ca->{$form->{sort}}) {
+       &ca_subtotal;
+      }
+    }
+    
+    # construct link to source
+    $href = "<a href=$ca->{module}.pl?path=$form->{path}&action=edit&id=$ca->{id}&login=$form->{login}&password=$form->{password}&callback=$callback>$ca->{reference}</a>";
+
+    
+    $column_data{debit} = "<td align=right>".$form->format_amount(\%myconfig, $ca->{debit}, 2, "&nbsp;")."</td>";
+    $column_data{credit} = "<td align=right>".$form->format_amount(\%myconfig, $ca->{credit}, 2, "&nbsp;")."</td>";
+    
+    $form->{balance} += $ca->{amount};
+    $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $form->{balance} * $ml, 2, 0)."</td>";
+
+    $subtotaldebit += $ca->{debit};
+    $subtotalcredit += $ca->{credit};
+    
+    $totaldebit += $ca->{debit};
+    $totalcredit += $ca->{credit};
+    
+    $column_data{transdate} = qq|<td>$ca->{transdate}</td>|;
+    $column_data{reference} = qq|<td>$href</td>|;
+    $column_data{description} = qq|<td>$ca->{description}</td>|;
+  
+    $i++; $i %= 2;
+    print qq|
+        <tr class=listrow$i>
+|;
+
+    map { print $column_data{$_} } @column_index;
+
+    print qq|
+        </tr>
+|;
+
+  }
+
+  if ($form->{l_subtotal} eq 'Y') {
+    &ca_subtotal;
+  }
+
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+  
+  $column_data{debit} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totaldebit, 2, "&nbsp;")."</font></th>";
+  $column_data{credit} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalcredit, 2, "&nbsp;")."</font></th>";
+  $column_data{balance} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $form->{balance} * $ml, 2, 0)."</font></th>";
+
+  print qq|
+       <tr class=listtotal>
+|;
+
+  map { print $column_data{$_} } @column_index;
+  
+  print qq|
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+</body>
+</html>
+|;
+  
+}
+
+
+sub ca_subtotal {
+
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+  
+  $column_data{debit} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotaldebit, 2, "&nbsp;") . "</font></th>";
+  $column_data{credit} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalcredit, 2, "&nbsp;") . "</font></th>";
+       
+  $subtotaldebit = 0;
+  $subtotalcredit = 0;
+
+  $sameitem = $ca->{$form->{sort}};
+
+  print qq|
+      <tr class=listsubtotal>
+|;
+
+  map { print "$column_data{$_}\n" } @column_index;
+
+  print qq|
+      </tr>
+|;
+
+}
+
diff --git a/sql-ledger/bin/mozilla/cp.pl b/sql-ledger/bin/mozilla/cp.pl
new file mode 100644 (file)
index 0000000..911b701
--- /dev/null
@@ -0,0 +1,528 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Payment module
+#
+#======================================================================
+
+
+use SL::CP;
+use SL::IS;
+use SL::IR;
+
+require "$form->{path}/arap.pl";
+
+1;
+# end of main
+
+
+sub payment {
+  
+  # setup customer/vendor selection for open invoices
+  CP->get_openvc(\%myconfig, \%$form);
+
+  if ($form->{"all_$form->{vc}"}) {
+    map { $form->{"select$form->{vc}"} .= "<option>$_->{name}--$_->{id}\n" } @{ $form->{"all_$form->{vc}"} };
+  }
+
+  $form->{arap} = ($form->{vc} eq 'customer') ? "AR" : "AP";
+
+  CP->paymentaccounts(\%myconfig, \%$form);
+
+  map { $form->{selectaccount} .= "<option>$_->{accno}--$_->{description}\n" } @{ $form->{PR} };
+
+  # currencies
+  @curr = split /:/, $form->{currencies};
+  chomp $curr[0];
+  $form->{defaultcurrency} = $form->{currency} = $form->{oldcurrency} = $curr[0];
+
+  map { $form->{selectcurrency} .= "<option>$_\n" } @curr;
+
+  $form->{media} = "screen";
+
+  &form_header;
+  &list_invoices;
+  &form_footer;
+
+}
+
+
+
+sub form_header {
+
+  $vclabel = ucfirst $form->{vc};
+  $vclabel = $locale->text($vclabel);
+
+  if ($form->{vc} eq 'customer') {
+    $form->{title} = $locale->text('Receipt');
+    $rclabel = $locale->text('Reference');
+    $form->{type} = 'receipt';
+  } else {
+    $form->{title} = $locale->text('Payment');
+    $rclabel = $locale->text('Check');
+    $form->{type} = 'check';
+  }
+
+# $locale->text('Customer')
+# $locale->text('Vendor')
+
+  if ($form->{$form->{vc}} eq "") {
+    map { $form->{"addr$_"} = "" } (1 .. 4);
+  }
+
+  if ($form->{currency} ne $form->{defaultcurrency}) {
+    $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate});
+    if ($form->{forex}) {
+      $exchangerate = qq|
+             <tr>
+               <th align=right nowrap>|.$locale->text('Exchangerate').qq|</th>
+               <td colspan=3><input type=hidden name=exchangerate size=10 value=$form->{exchangerate}>$form->{exchangerate}</td>
+             </tr>
+|;
+    } else {
+      $exchangerate = qq|
+             <tr>
+               <th align=right nowrap>|.$locale->text('Exchangerate').qq|</th>
+               <td colspan=3><input name=exchangerate size=10 value=$form->{exchangerate}></td>
+             </tr>
+|;
+    }
+  }
+  
+  foreach $item ($form->{vc}, account, currency) {
+    $form->{"select$item"} =~ s/ selected//;
+    $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
+  }
+
+  $vc = ($form->{"select$form->{vc}"}) ? qq|<select name=$form->{vc}>$form->{"select$form->{vc}"}\n</select>| : qq|<input name=$form->{vc} size=35 value="$form->{$form->{vc}}">|;
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=defaultcurrency value=$form->{defaultcurrency}>
+<input type=hidden name=closedto value=$form->{closedto}>
+<input type=hidden name=vc value=$form->{vc}>
+<input type=hidden name=type value=$form->{type}>
+
+<table border=0 width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table width=100%>
+        <tr valign=top>
+         <td>
+           <table>
+             <tr>
+               <th align=right>$vclabel</th>
+               <td>$vc</td>
+                <input type=hidden name="select$form->{vc}" value="$form->{"select$form->{vc}"}">
+                <input type=hidden name="$form->{vc}_id" value=$form->{"$form->{vc}_id"}>
+               <input type=hidden name="old$form->{vc}" value="$form->{"old$form->{vc}"}">
+             </tr>
+             <tr valign=top>
+               <th align=right nowrap>|.$locale->text('Address').qq|</th>
+               <td>
+                 <table>
+                   <tr>
+                     <td>$form->{addr1}</td>
+                   </tr>
+                   <tr>
+                     <td>$form->{addr2}</td>
+                   </tr>
+                   <tr>
+                     <td>$form->{addr3}</td>
+                   </tr>
+                   <tr>
+                     <td>$form->{addr4}</td>
+                   </tr>
+                 </table>
+               </td>
+               <input type=hidden name=addr1 value="$form->{addr1}">
+               <input type=hidden name=addr2 value="$form->{addr2}">
+               <input type=hidden name=addr3 value="$form->{addr3}">
+               <input type=hidden name=addr4 value="$form->{addr4}">
+             </tr>
+           </table>
+         </td>
+         <td align=right>
+           <table>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Account').qq|</th>
+               <td colspan=3><select name=account>$form->{selectaccount}</select>
+               <input type=hidden name=selectaccount value="$form->{selectaccount}">
+               </td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Date').qq|</th>
+               <td><input name=datepaid value="$form->{datepaid}" title="$myconfig{dateformat}" size=11></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Currency').qq|</th>
+               <td><select name=currency>$form->{selectcurrency}</select></td>
+               <input type=hidden name=selectcurrency value="$form->{selectcurrency}">
+               <input type=hidden name=oldcurrency value=$form->{oldcurrency}>
+             </tr>
+             $exchangerate
+             <tr>
+               <th align=right nowrap>$rclabel</th>
+               <td colspan=3><input name=source value="$form->{source}" size=10></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Amount').qq|</th>
+               <td colspan=3><input name=amount size=10 value=|.$form->format_amount(\%myconfig, $form->{amount}, 2).qq|></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('From').qq|</th>
+               <td><input name=transdatefrom size=11 title="$myconfig{dateformat}" value=$form->{transdatefrom}></td>
+               <th align=right nowrap>|.$locale->text('to').qq|</th>
+               <td><input name=transdateto size=11 title="$myconfig{dateformat}" value=$form->{transdateto}></td>
+               <input type=hidden name=oldtransdatefrom value=$form->{oldtransdatefrom}>
+               <input type=hidden name=oldtransdateto value=$form->{oldtransdateto}>
+             </tr>
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+|;
+
+}
+
+
+sub list_invoices {
+
+  @column_index = qw(invnumber transdate amount due paid selectpaid);
+  
+  $colspan = $#column_index + 1;
+  
+  print qq|
+  <input type=hidden name=column_index value="id @column_index">
+  <tr>
+    <td>
+      <table width=100%>
+       <tr>
+         <th class=listheading colspan=$colspan>|.$locale->text('Invoices').qq|</th>
+       </tr>
+|;
+
+  $column_data{invnumber} = qq|<th nowrap>|.$locale->text('Invoice')."</th>";
+  $column_data{transdate} = qq|<th nowrap>|.$locale->text('Date')."</th>";
+  $column_data{amount} = qq|<th nowrap>|.$locale->text('Amount')."</th>";
+  $column_data{due} = qq|<th nowrap>|.$locale->text('Due')."</th>";
+  $column_data{paid} = qq|<th nowrap>|.$locale->text('Applied')."</th>";
+  $column_data{selectpaid} = qq|<th nowrap>|.$locale->text('Paid in full')."</th>";
+  
+  print qq|
+        <tr>
+|;
+  map { print "$column_data{$_}\n" } @column_index;
+  print qq|
+        </tr>
+|;
+
+  for $i (1 .. $form->{rowcount}) {
+
+    $form->{"selectpaid_$i"} = "checked" if $form->{"selectpaid_$i"};
+    map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(amount due paid);
+    
+    $totalamount += $form->{"amount_$i"};
+    $totaldue += $form->{"due_$i"};
+    $totalpaid += $form->{"paid_$i"};
+
+    map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) } qw(amount due paid);
+
+    $column_data{invnumber} = qq|<td>$form->{"invnumber_$i"}</td>
+      <input type=hidden name="invnumber_$i" value="$form->{"invnumber_$i"}">
+      <input type=hidden name="id_$i" value=$form->{"id_$i"}>|;
+    $column_data{transdate} = qq|<td width=15%>$form->{"transdate_$i"}</td>
+      <input type=hidden name="transdate_$i" value=$form->{"transdate_$i"}>|;
+    $column_data{amount} = qq|<td align=right width=15%>$form->{"amount_$i"}</td>
+      <input type=hidden name="amount_$i" value=$form->{"amount_$i"}>|;
+    $column_data{due} = qq|<td align=right width=15%>$form->{"due_$i"}</td>
+      <input type=hidden name="due_$i" value=$form->{"due_$i"}>|;
+
+    $column_data{paid} = qq|<td align=right width=15%>|;
+    if ($form->{"selectpaid_$i"}) {
+      $column_data{paid} .= qq|<input type=hidden name="paid_$i" value=$form->{"paid_$i"}>$form->{"paid_$i"}</td>|;
+    } else {
+      $column_data{paid} .= qq|<input name="paid_$i" size=10 value=$form->{"paid_$i"}></td>|;
+    }
+    $column_data{selectpaid} = qq|<td align=center width=10%><input name="selectpaid_$i" type=checkbox class=checkbox $form->{"selectpaid_$i"}></td>|;
+
+    $j++; $j %= 2;
+    print qq|
+       <tr class=listrow$j>
+|;
+    map { print "$column_data{$_}\n" } @column_index;
+    print qq|
+        </tr>
+|;
+  }
+
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+
+  $column_data{amount} = qq|<th align=right>|.$form->format_amount(\%myconfig, $totalamount, 2, "&nbsp;").qq|</th>|;
+  $column_data{due} = qq|<th align=right>|.$form->format_amount(\%myconfig, $totaldue, 2, "&nbsp;").qq|</th>|;
+  $column_data{paid} = qq|<th align=right>|.$form->format_amount(\%myconfig, $totalpaid, 2, "&nbsp;").qq|</th>|;
+
+  print qq|
+        <tr class=listtotal>
+|;
+  map { print "$column_data{$_}\n" } @column_index;
+  print qq|
+        </tr>
+      </table>
+    </td>
+  </tr>
+|;
+
+}
+
+
+sub form_footer {
+
+  $form->{OP}{$form->{media}} = "checked";
+  
+  print qq|
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+<input type=hidden name=rowcount value=$form->{rowcount}>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('Post').qq|">|;
+
+  if ($latex) {
+    print qq|
+<input class=submit type=submit name=action value="|.$locale->text('Print').qq|">
+<input class=radio type=radio name=media value=screen $form->{OP}{screen}> |.$locale->text('Screen');
+
+    if ($myconfig{printer}) {
+      print qq|
+<input class=radio type=radio name=media value=printer $form->{OP}{printer}> |.$locale->text('Printer');
+    }
+  }
+
+  print qq|
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub update {
+  my ($new_name_selected) = @_;
+
+  # get customer and invoices
+  $updated = &check_name($form->{vc});
+
+  $updated = 1 if (($form->{oldtransdatefrom} ne $form->{transdatefrom}) || ($form->{oldtransdateto} ne $form->{transdateto}));
+  $form->{oldtransdatefrom} = $form->{transdatefrom};
+  $form->{oldtransdateto} = $form->{transdateto};
+  
+  if ($new_name_selected || $updated) {
+    CP->get_openinvoices(\%myconfig, \%$form);
+    $updated = 1;
+  }
+
+  if ($form->{currency} ne $form->{oldcurrency}) {
+    $form->{oldcurrency} = $form->{currency};
+    if (!$updated) {
+      CP->get_openinvoices(\%myconfig, \%$form);
+      $updated = 1;
+    }
+  }
+  
+  # check currency
+  $buysell = ($form->{vc} eq 'customer') ? "buy" : "sell";
+  
+  $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{datepaid}, $buysell)));
+
+  $amount = $form->{amount} = $form->parse_amount(\%myconfig, $form->{amount});
+  
+  if ($updated) {
+    $form->{rowcount} = 0;
+    
+    $i = 0;
+    foreach $ref (@{ $form->{PR} }) {
+      $i++;
+      $form->{"id_$i"} = $ref->{id};
+      $form->{"invnumber_$i"} = $ref->{invnumber};
+      $form->{"transdate_$i"} = $ref->{transdate};
+      $ref->{exchangerate} = 1 unless $ref->{exchangerate};
+      $form->{"amount_$i"} = $ref->{amount} / $ref->{exchangerate};
+      $form->{"due_$i"} = $form->round_amount(($ref->{amount} - $ref->{paid}) / $ref->{exchangerate}, 2);
+      $amount = $form->round_amount($amount - $form->{"due_$i"}, 2);
+      $form->{"selectpaid_$i"} = 1 if $amount > 0;
+
+      map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) } qw(amount due paid);
+
+    }
+    $form->{rowcount} = $i;
+  }
+
+  # recalculate
+  $amount = $form->{amount};
+  for $i (1 .. $form->{rowcount}) {
+
+    map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(amount due paid);
+
+    if ($form->{"selectpaid_$i"}) {
+      $amount -= $form->{"due_$i"};
+      
+      if ($amount < 0) {
+       $form->{"selectpaid_$i"} = 0;
+      } else {
+       $form->{"paid_$i"} = $form->{"due_$i"};
+      }
+    }
+
+    map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) } qw(amount due paid);
+
+  }
+
+  &form_header;
+  &list_invoices;
+  &form_footer;
+  
+}
+
+
+sub post {
+  
+  &check_form;
+
+  $form->redirect($locale->text('Payment posted!')) if (CP->process_payment(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot post payment!'));
+
+}
+
+
+sub print {
+  &check_form;
+
+  ($whole, $form->{decimal}) = split /\./, $form->{amount};
+  
+  $form->{amount} = $form->format_amount(\%myconfig, $form->{amount}, 2);
+  $m = "*" x (24 - length $form->{amount});
+  $form->{amount} = $locale->text($form->{currency})."$m$form->{amount}";
+  
+  $form->{decimal} .= "00";
+  $form->{decimal} = substr($form->{decimal}, 0, 2);
+
+  $check = new CP $myconfig{countrycode};
+  $check->init;
+  $form->{text_amount} = $check->num2text($whole);
+
+  &{ "$form->{vc}_details" };
+
+  $form->{format} = ($form->{media} eq 'screen') ? "pdf" : "postscript";
+  $form->{templates} = "$myconfig{templates}";
+  $form->{IN} = "$form->{type}.tex";
+  $form->{OUT} = "| $myconfig{printer}" if ($form->{media} eq 'printer');
+
+  $form->{company} = $myconfig{company};
+  $form->{address} = $myconfig{address};
+  @a = qw(name invnumber company address text_amount addr1 addr2 addr3 addr4);
+  $form->format_string(@a);
+
+  $form->parse_template(\%myconfig, $userspath);
+
+  $form->{callback} = "";
+
+  $label = uc $form->{type};
+
+# $locale->text('Check printed!')
+# $locale->text('Check printing failed!')
+# $locale->text('Receipt printed!')
+# $locale->text('Receipt printing failed!')
+
+  $form->redirect($locale->text("$label printed!"));
+  $form->error($locale->text("$label printing failed!"));
+  
+}
+
+
+sub customer_details { IS->customer_details(\%myconfig, \%$form) };
+sub vendor_details { IR->vendor_details(\%myconfig, \%$form) };
+  
+
+sub check_form {
+  
+  # construct callback
+  $form->{callback} = "$form->{script}?action=payment&vc=$form->{vc}&path=$form->{path}&login=$form->{login}&password=$form->{password}";
+
+  $form->redirect unless $form->{rowcount};
+
+  if ($form->{currency} ne $form->{oldcurrency}) {
+    &update;
+    exit;
+  }
+  
+  $form->error($locale->text('Date missing!')) unless $form->{datepaid};
+  $form->error($locale->text('Amount missing!')) unless $form->{amount};
+
+  $closedto = $form->datetonum($form->{closedto}, \%myconfig);
+  $datepaid = $form->datetonum($form->{datepaid}, \%myconfig);
+  
+  $form->error($locale->text('Cannot process payment for a closed period!')) if ($datepaid <= $closedto);
+
+  $form->{amount} = $form->parse_amount(\%myconfig, $form->{amount});
+  for $i (1 .. $form->{rowcount}) {
+    $totalpaid += $form->parse_amount(\%myconfig, $form->{"paid_$i"});
+    if ($form->{"paid_$i"}) {
+      push(@{ $form->{paid} }, $form->{"paid_$i"});
+      push(@{ $form->{due} }, $form->{"due_$i"});
+      push(@{ $form->{invnumber} }, $form->{"invnumber_$i"});
+      push(@{ $form->{invdate} }, $form->{"transdate_$i"});
+    }
+  }
+
+  $totalpaid = $form->round_amount($totalpaid, 2);
+
+  $form->error($locale->text('Nothing applied!')) unless $totalpaid;
+  $form->error($locale->text('Amount does not equal applied!')) if ($form->{amount} != $totalpaid);
+
+}
+
+
diff --git a/sql-ledger/bin/mozilla/ct.pl b/sql-ledger/bin/mozilla/ct.pl
new file mode 100644 (file)
index 0000000..3dbb565
--- /dev/null
@@ -0,0 +1,631 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors: Reed White <alta@alta-research.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# customer/vendor module
+#
+#======================================================================
+
+# $locale->text('Customers')
+# $locale->text('Vendors')
+
+use SL::CT;
+
+1;
+# end of main
+
+
+
+sub add {
+
+  $form->{title} = "Add";
+
+  $form->{callback} = "$form->{script}?action=add&db=$form->{db}&path=$form->{path}&login=$form->{login}&password=$form->{password}" unless $form->{callback};
+
+  CT->taxaccounts(\%myconfig, \%$form);
+  
+  &form_header;
+  &form_footer;
+  
+}
+
+
+sub search {
+
+  $label = ucfirst $form->{db};
+  $form->{title} = $locale->text($label."s");
+  $form->header;
+  
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=db value=$form->{db}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr valign=top>
+    <td>
+      <table>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Number').qq|</th>
+         <td><input name=$form->{db}number size=35></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Name').qq|</th>
+         <td><input name=name size=35></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Contact').qq|</th>
+         <td><input name=contact size=35></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('E-mail').qq|</th>
+         <td><input name=email size=35></td>
+       </tr>
+       <tr>
+         <td></td>
+         <td><input name=status class=radio type=radio value=all checked>&nbsp;|.$locale->text('All').qq|
+         <input name=status class=radio type=radio value=orphaned>&nbsp;|.$locale->text('Orphaned').qq|</td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Include in Report').qq|</th>
+         <td>
+         <input name="l_$form->{db}number" type=checkbox class=checkbox value=Y>&nbsp;|.$locale->text('Number').qq|
+         <input name="l_name" type=checkbox class=checkbox value=Y checked>&nbsp;|.$locale->text('Name').qq|
+         <input name="l_address" type=checkbox class=checkbox value=Y>&nbsp;|.$locale->text('Address').qq|<br>
+         <input name="l_contact" type=checkbox class=checkbox value=Y checked>&nbsp;|.$locale->text('Contact').qq|
+         <input name="l_phone" type=checkbox class=checkbox value=Y checked>&nbsp;|.$locale->text('Phone').qq|
+         <input name="l_fax" type=checkbox class=checkbox value=Y>&nbsp;|.$locale->text('Fax').qq|
+         <input name="l_email" type=checkbox class=checkbox value=Y checked>&nbsp;|.$locale->text('E-mail').qq|
+         <input name="l_cc" type=checkbox class=checkbox value=Y>&nbsp;|.$locale->text('Cc').qq|
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<input type=hidden name=nextsub value=list_names>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br>
+<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+}
+
+
+sub list_names {
+  
+  CT->search(\%myconfig, \%$form);
+  
+  $callback = "$form->{script}?action=list_names&db=$form->{db}&path=$form->{path}&login=$form->{login}&password=$form->{password}&status=$form->{status}";
+  $href = $callback;
+  
+  @columns = $form->sort_columns(name, "$form->{db}number", address, contact, phone, fax, email, cc);
+
+  foreach $item (@columns) {
+    if ($form->{"l_$item"} eq "Y") {
+      push @column_index, $item;
+
+      # add column to href and callback
+      $callback .= "&l_$item=Y";
+      $href .= "&l_$item=Y";
+    }
+  }
+  
+  if ($form->{status} eq 'all') {
+    $option = $locale->text('All');
+  }
+  if ($form->{status} eq 'orphaned') {
+    $option .= $locale->text('Orphaned');
+  }
+  if ($form->{name}) {
+    $callback .= "&name=$form->{name}";
+    $href .= "&name=".$form->escape($form->{name});
+    $option .= "\n<br>".$locale->text('Name')." : $form->{name}";
+  }
+  if ($form->{contact}) {
+    $callback .= "&contact=$form->{contact}";
+    $href .= "&contact=".$form->escape($form->{contact});
+    $option .= "\n<br>".$locale->text('Contact')." : $form->{contact}";
+  }
+  if ($form->{"$form->{db}number"}) {
+    $callback .= qq|&$form->{db}number=$form->{"$form->{db}number"}|;
+    $href .= "&$form->{db}number=".$form->escape($form->{"$form->{db}number"});
+    $option .= "\n<br>".$locale->text('Number').qq| : $form->{"$form->{db}number"}|;
+  }
+  if ($form->{email}) {
+    $callback .= "&email=$form->{email}";
+    $href .= "&email=".$form->escape($form->{email});
+    $option .= "\n<br>".$locale->text('E-mail')." : $form->{email}";
+  }
+
+  $form->{callback} = "$callback&sort=$form->{sort}";
+  $callback = $form->escape($form->{callback});
+  
+  $column_header{"$form->{db}number"} = qq|<th><a class=listheading href=$href&sort=$form->{db}number>|.$locale->text('Number').qq|</a></th>|;
+  $column_header{name} = qq|<th><a class=listheading href=$href&sort=name>|.$locale->text('Name').qq|</a></th>|;
+  $column_header{address} = qq|<th><a class=listheading href=$href&sort=address>|.$locale->text('Address').qq|</a></th>|;
+  $column_header{contact} = qq|<th><a class=listheading href=$href&sort=contact>|.$locale->text('Contact').qq|</a></th>|;
+  $column_header{phone} = qq|<th><a class=listheading href=$href&sort=phone>|.$locale->text('Phone').qq|</a></th>|;
+  $column_header{fax} = qq|<th><a class=listheading href=$href&sort=fax>|.$locale->text('Fax').qq|</a></th>|;
+  $column_header{email} = qq|<th><a class=listheading href=$href&sort=email>|.$locale->text('E-mail').qq|</a></th>|;
+  $column_header{cc} = qq|<th><a class=listheading href=$href&sort=cc>|.$locale->text('Cc').qq|</a></th>|;
+  
+  $label = ucfirst $form->{db}."s";
+  $form->{title} = $locale->text($label);
+
+  $form->header;
+
+  print qq|
+<body>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>$option</td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+|;
+
+  map { print "$column_header{$_}\n" } @column_index;
+  
+  print qq|
+        </tr>
+|;
+
+  foreach $ref (@{ $form->{CT} }) {
+
+    map { $column_data{$_} = "<td>$ref->{$_}&nbsp;</td>" } ("$form->{db}number", address, contact, phone, fax);
+    
+    $column_data{name} = "<td><a href=$form->{script}?action=edit&id=$ref->{id}&db=$form->{db}&path=$form->{path}&login=$form->{login}&password=$form->{password}&status=$form->{status}&callback=$callback>$ref->{name}&nbsp;</td>";
+    
+    $column_data{email} = ($ref->{email}) ? qq|<td><a href="mailto:$ref->{email}">$ref->{email}</a></td>| : "<td>&nbsp;</td>";
+    $column_data{cc} = ($ref->{cc}) ? qq|<td><a href="mailto:$ref->{cc}">$ref->{cc}</a></td>| : "<td>&nbsp;</td>";
+    
+    $i++; $i %= 2;
+    print "
+        <tr class=listrow$i>
+";
+
+    map { print "$column_data{$_}\n" } @column_index;
+
+    print qq|
+        </tr>
+|;
+    
+  }
+
+  print qq|
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<br>
+<form method=post action=$form->{script}>
+
+<input name=callback type=hidden value="$form->{callback}">
+<input name=db type=hidden value=$form->{db}>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input class=submit type=submit name=action value="|.$locale->text('Add').qq|">
+
+</form>
+
+</body>
+</html>
+|;
+}
+
+
+sub edit {
+
+# $locale->text('Edit Customer')
+# $locale->text('Edit Vendor')
+
+  CT->get_tuple(\%myconfig, \%$form);
+
+  # format " into &quot;
+  map { $form->{$_} =~ s/"/&quot;/g } keys %$form;
+
+  $form->{title} = "Edit";
+
+  # format discount
+  $form->{discount} *= 100;
+  
+  &form_header;
+  &form_footer;
+
+}
+
+
+sub form_header {
+
+  foreach $item (split / /, $form->{taxaccounts}) {
+    if (($form->{tax}{$item}{taxable}) || !($form->{id})) {
+      $taxable .= qq| <input name="tax_$item" value=1 class=checkbox type=checkbox checked>&nbsp;<b>$form->{tax}{$item}{description}</b>|;
+    } else {
+      $taxable .= qq| <input name="tax_$item" value=1 class=checkbox type=checkbox>&nbsp;<b>$form->{tax}{$item}{description}</b>|;
+    }
+  }
+
+  $tax = qq|
+  <tr>
+    <td>
+      <table>
+        <tr>
+         <th align=right>|.$locale->text('Taxable').qq|</th>
+         <td>$taxable</td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+|;
+
+  $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : "";
+  $form->{creditlimit} = $form->format_amount(\%myconfig, $form->{creditlimit}, 0);
+  
+  if ($myconfig{admin}) {
+    $bcc = qq|
+        <tr>
+         <th align=right nowrap>|.$locale->text('Bcc').qq|</th>
+         <td><input name=bcc size=35 value="$form->{bcc}"></td>
+       </tr>
+|;
+  }
+  
+  
+  $label = ucfirst $form->{db};
+  $form->{title} = $locale->text("$form->{title} $label");
+
+  if ($form->{db} eq 'customer') {
+    $creditlimit = qq|
+         <th align=right>|.$locale->text('Credit Limit').qq|</th>
+         <td><input name=creditlimit size=9 value="$form->{creditlimit}"></td>
+         <th align=right>|.$locale->text('Discount').qq|</th>
+         <td><input name=discount size=4 value="$form->{discount}"></td>
+         <th>%</th>
+|;
+  }
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+         <th class=listheading colspan=2 width=50%">&nbsp;</th>
+         <th class=listheading width=50%">|.$locale->text('Ship to').qq|</th>
+       </tr>
+       <tr height="5"></tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Number').qq|</th>
+         <td><input name="$form->{db}number" size=35 maxsize=35 value="$form->{"$form->{db}number"}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Name').qq|</th>
+         <td><input name=name size=35 maxsize=35 value="$form->{name}"></td>
+         <td><input name=shiptoname size=35 maxsize=35 value="$form->{shiptoname}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Address').qq|</th>
+         <td><input name=addr1 size=35 maxsize=35 value="$form->{addr1}"></td>
+         <td><input name=shiptoaddr1 size=35 maxsize=35 value="$form->{shiptoaddr1}"></td>
+       </tr>
+       <tr>
+         <th></th>
+         <td><input name=addr2 size=35 maxsize=35 value="$form->{addr2}"></td>
+         <td><input name=shiptoaddr2 size=35 maxsize=35 value="$form->{shiptoaddr2}"></td>
+       </tr>
+       <tr>
+         <th></th>
+         <td><input name=addr3 size=35 maxsize=35 value="$form->{addr3}"></td>
+         <td><input name=shiptoaddr3 size=35 maxsize=35 value="$form->{shiptoaddr3}"></td>
+       </tr>
+       <tr>
+         <th></th>
+         <td><input name=addr4 size=35 maxsize=35 value="$form->{addr4}"></td>
+         <td><input name=shiptoaddr4 size=35 maxsize=35 value="$form->{shiptoaddr4}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Contact').qq|</th>
+         <td><input name=contact size=35 maxsize=35 value="$form->{contact}"></td>
+         <td><input name=shiptocontact size=35 maxsize=35 value="$form->{shiptocontact}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Phone').qq|</th>
+         <td><input name=phone size=20 maxsize=20 value="$form->{phone}"></td>
+         <td><input name=shiptophone size=20 maxsize=20 value="$form->{shiptophone}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Fax').qq|</th>
+         <td><input name=fax size=20 maxsize=20 value="$form->{fax}"></td>
+         <td><input name=shiptofax size=20 maxsize=20 value="$form->{shiptofax}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('E-mail').qq|</th>
+         <td><input name=email size=35 value="$form->{email}"></td>
+         <td><input name=shiptoemail size=35 value="$form->{shiptoemail}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Cc').qq|</th>
+         <td><input name=cc size=35 value="$form->{cc}"></td>
+       </tr>
+        $bcc
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr>
+         <th align=right>|.$locale->text('Terms: Net').qq|</th>
+         <td><input name=terms size=2 value="$form->{terms}"></td>
+         <th>|.$locale->text('days').qq|</th>
+         $creditlimit
+         <td><input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}></td>
+         <th align=left>|.$locale->text('Tax Included').qq|</th>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  $tax
+  <tr>
+    <th align=left nowrap>|.$locale->text('Notes').qq|</th>
+  </tr>
+  <tr>
+    <td><textarea name=notes rows=3 cols=60 wrap=soft>$form->{notes}</textarea></td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+|;
+
+}
+
+
+
+sub form_footer {
+
+  $label = ucfirst $form->{db};
+
+  print qq|
+<input name=id type=hidden value=$form->{id}>
+<input name=taxaccounts type=hidden value="$form->{taxaccounts}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input type=hidden name=callback value="$form->{callback}">
+<input type=hidden name=db value=$form->{db}>
+
+<br>
+
+<input class=submit type=submit name=action value="|.$locale->text("Save").qq|">
+<input class=submit type=submit name=action value="|.$locale->text("Invoice").qq|">
+<input class=submit type=submit name=action value="|.$locale->text('Order').qq|">
+|;
+
+  if ($form->{id} && $form->{status} eq 'orphaned') {
+    print qq|<input class=submit type=submit name=action value="|.$locale->text('Delete').qq|">\n|;
+  }
+
+  print qq|
+  </form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub invoice { &{ "$form->{db}_invoice" } };
+
+sub customer_invoice {
+
+  $form->isblank("name", $locale->text("Name missing!"));
+  CT->save_customer(\%myconfig, \%$form);
+  
+  delete $form->{script};
+  
+  $form->{action} = "add";
+  $form->{callback} = $form->escape($form->{callback},1);
+
+  $form->{customer} = $form->{name};
+  $form->{customer_id} = $form->{id};
+  $form->{vc} = 'customer';
+
+  delete $form->{id};
+
+  map { $argv .= "$_=$form->{$_}&" } keys %$form;
+  
+  exec ("perl", "is.pl", $argv);
+
+}
+
+
+sub vendor_invoice {
+
+  $form->isblank("name", $locale->text("Name missing!"));
+  CT->save_vendor(\%myconfig, \%$form);
+  
+  delete $form->{script};
+  
+  $form->{action} = "add";
+  $form->{callback} = $form->escape($form->{callback},1);
+
+  $form->{vendor} = $form->{name};
+  $form->{vendor_id} = $form->{id};
+  $form->{vc} = 'vendor';
+  
+  delete $form->{id};
+
+  map { $argv .= "$_=$form->{$_}&" } keys %$form;
+  
+  exec ("perl", "ir.pl", $argv);
+
+}
+
+
+sub order { &{ "$form->{db}_order" } };
+
+sub customer_order {
+
+  $form->isblank("name", $locale->text("Name missing!"));
+  CT->save_customer(\%myconfig, \%$form);
+  
+  delete $form->{script};
+  
+  $form->{action} = "add";
+  $form->{callback} = $form->escape($form->{callback},1);
+  
+  $form->{customer} = $form->{name};
+  $form->{customer_id} = $form->{id};
+  $form->{vc} = 'customer';
+
+  $form->{type} = 'sales_order';
+  
+  delete $form->{id};
+
+  map { $argv .= "$_=$form->{$_}&" } keys %$form;
+  
+  exec ("perl", "oe.pl", $argv);
+
+}
+
+
+sub vendor_order {
+
+  $form->isblank("name", $locale->text("Name missing!"));
+  CT->save_vendor(\%myconfig, \%$form);
+  
+  delete $form->{script};
+  
+  $form->{action} = "add";
+  $form->{callback} = $form->escape($form->{callback},1);
+  
+  $form->{vendor} = $form->{name};
+  $form->{vendor_id} = $form->{id};
+  $form->{vc} = 'vendor';
+
+  $form->{type} = 'purchase_order';
+
+  delete $form->{id};
+
+  map { $argv .= "$_=$form->{$_}&" } keys %$form;
+  
+  exec ("perl", "oe.pl", $argv);
+
+}
+
+
+sub save { &{ "save_$form->{db}" } };
+
+sub save_customer {
+
+  $form->isblank("name", $locale->text("Name missing!"));
+  CT->save_customer(\%myconfig, \%$form);
+  $form->redirect($locale->text('Customer saved!'));
+  
+}
+
+
+sub save_vendor {
+
+  $form->isblank("name", $locale->text("Name missing!"));
+  CT->save_vendor(\%myconfig, \%$form);
+  $form->redirect($locale->text('Vendor saved!'));
+  
+}
+
+
+sub delete { &{ "delete_$form->{db}" } };
+
+sub delete_customer {
+
+  $rc = CT->delete_customer(\%myconfig, \%$form);
+  
+  $form->error($locale->text('Transactions exist, cannot delete customer!')) if ($rc == -1);
+  $form->redirect($locale->text('Customer deleted!')) if $rc;
+  $form->error($locale->text('Cannot delete customer!'));
+
+}
+
+
+sub delete_vendor {
+
+  $rc = CT->delete_vendor(\%myconfig, \%$form);
+  
+  $form->error($locale->text('Transactions exist, cannot delete vendor!')) if ($rc == -1);
+  $form->redirect($locale->text('Vendor deleted!')) if $rc;
+  $form->error($locale->text('Cannot delete vendor!'));
+
+}
+
+
+sub continue { &{ $form->{nextsub} } };
+
+
diff --git a/sql-ledger/bin/mozilla/gl.pl b/sql-ledger/bin/mozilla/gl.pl
new file mode 100644 (file)
index 0000000..0d2dd46
--- /dev/null
@@ -0,0 +1,806 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Genereal Ledger
+#
+#======================================================================
+
+
+use SL::GL;
+use SL::PE;
+
+require "$form->{path}/arap.pl";
+
+1;
+# end of main
+
+
+# this is for our long dates
+# $locale->text('January')
+# $locale->text('February')
+# $locale->text('March')
+# $locale->text('April')
+# $locale->text('May ')
+# $locale->text('June')
+# $locale->text('July')
+# $locale->text('August')
+# $locale->text('September')
+# $locale->text('October')
+# $locale->text('November')
+# $locale->text('December')
+
+# this is for our short month
+# $locale->text('Jan')
+# $locale->text('Feb')
+# $locale->text('Mar')
+# $locale->text('Apr')
+# $locale->text('May')
+# $locale->text('Jun')
+# $locale->text('Jul')
+# $locale->text('Aug')
+# $locale->text('Sep')
+# $locale->text('Oct')
+# $locale->text('Nov')
+# $locale->text('Dec')
+
+
+sub add {
+
+  $form->{title} = "Add";
+  
+  $form->{callback} = "$form->{script}?action=add&path=$form->{path}&login=$form->{login}&password=$form->{password}" unless $form->{callback};
+
+  # we use this only to set a default date
+  GL->transaction(\%myconfig, \%$form);
+  
+  map { $chart .= "<option>$_->{accno}--$_->{description}" } @{ $form->{chart} };
+  $form->{chart} = $chart;
+  
+  $form->{rowcount} = 4;
+  &display_form;
+  
+}
+
+
+sub edit {
+
+  GL->transaction(\%myconfig, \%$form);
+
+  map { $chart .= "<option>$_->{accno}--$_->{description}" } @{ $form->{chart} };
+  $form->{chart} = $chart;
+
+  $form->{locked} = ($form->datetonum($form->{transdate}, \%myconfig) <= $form->datetonum($form->{closedto}, \%myconfig));
+
+  $form->{title} = "Edit";
+  
+  &form_header;
+
+  $i = 1;
+  foreach $ref (@{ $form->{GL} }) {
+    $form->{"accno_$i"} = $ref->{accno};
+    $form->{"oldprojectnumber_$i"} = $form->{"projectnumber_$i"} = $ref->{projectnumber};
+    $form->{"project_id_$i"} = $ref->{project_id};
+    
+    if ($ref->{amount} < 0) {
+      $form->{totaldebit} -= $ref->{amount};
+      $form->{"debit_$i"} = $form->format_amount(\%myconfig, $ref->{amount} * -1, 2);
+    } else {
+      $form->{totalcredit} += $ref->{amount};
+      $form->{"credit_$i"} = ($ref->{amount} > 0) ? $form->format_amount(\%myconfig, $ref->{amount}, 2) : "";
+    }
+
+    &form_row($i++);
+  }
+
+  &form_row($i);
+
+  &form_footer;
+  
+}
+
+
+
+sub search {
+
+  $form->{title} = $locale->text('General Ledger')." ".$locale->text('Reports');
+  
+  $form->header;
+  
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=sort value=transdate>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table>
+       <tr>
+         <th align=right>|.$locale->text('Reference').qq|</th>
+         <td><input name=reference size=20></td>
+         <th align=right>|.$locale->text('Source').qq|</th>
+         <td><input name=source size=20></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Description').qq|</th>
+         <td colspan=3><input name=description size=40></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Notes').qq|</th>
+         <td colspan=3><input name=notes size=40></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('From').qq|</th>
+         <td><input name=datefrom size=11 title="$myconfig{dateformat}"></td>
+         <th align=right>|.$locale->text('to').qq|</th>
+         <td><input name=dateto size=11 title="$myconfig{dateformat}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Include in Report').qq|</th>
+         <td colspan=3>
+           <table>
+             <tr>
+               <td>
+                 <input name="category" class=radio type=radio value=X checked>&nbsp;|.$locale->text('All').qq|
+                 <input name="category" class=radio type=radio value=A>&nbsp;|.$locale->text('Asset').qq|
+                 <input name="category" class=radio type=radio value=L>&nbsp;|.$locale->text('Liability').qq|
+                 <input name="category" class=radio type=radio value=Q>&nbsp;|.$locale->text('Equity').qq|
+                 <input name="category" class=radio type=radio value=I>&nbsp;|.$locale->text('Income').qq|
+                 <input name="category" class=radio type=radio value=E>&nbsp;|.$locale->text('Expense').qq|
+               </td>
+             </tr>
+             <tr>
+               <table>
+                 <tr>
+                   <td align=right><input name="l_id" class=checkbox type=checkbox value=Y></td>
+                   <td>|.$locale->text('ID').qq|</td>
+                   <td align=right><input name="l_transdate" class=checkbox type=checkbox value=Y checked></td>
+                   <td>|.$locale->text('Date').qq|</td>
+                   <td align=right><input name="l_reference" class=checkbox type=checkbox value=Y checked></td>
+                   <td>|.$locale->text('Reference').qq|</td>
+                   <td align=right><input name="l_description" class=checkbox type=checkbox value=Y checked></td>
+                   <td>|.$locale->text('Description').qq|</td>
+                   <td align=right><input name="l_notes" class=checkbox type=checkbox value=Y></td>
+                   <td>|.$locale->text('Notes').qq|</td>
+                 </tr>
+                 <tr>
+                   <td align=right><input name="l_debit" class=checkbox type=checkbox value=Y checked></td>
+                   <td>|.$locale->text('Debit').qq|</td>
+                   <td align=right><input name="l_credit" class=checkbox type=checkbox value=Y checked></td>
+                   <td>|.$locale->text('Credit').qq|</td>
+                   <td align=right><input name="l_source" class=checkbox type=checkbox value=Y checked></td>
+                   <td>|.$locale->text('Source').qq|</td>
+                   <td align=right><input name="l_accno" class=checkbox type=checkbox value=Y checked></td>
+                   <td>|.$locale->text('Account').qq|</td>
+                   <td align=right><input name="l_gifi_accno" class=checkbox type=checkbox value=Y></td>
+                   <td>|.$locale->text('GIFI').qq|</td>
+                 </tr>
+                 <tr>
+                   <td align=right><input name="l_subtotal" class=checkbox type=checkbox value=Y></td>
+                   <td>|.$locale->text('Subtotal').qq|</td>
+                 </tr>
+               </table>
+             </tr>
+           </table>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<input type=hidden name=nextsub value=generate_report>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+}
+
+
+sub generate_report {
+
+  GL->all_transactions(\%myconfig, \%$form);
+  
+  $callback = "$form->{script}?action=generate_report&path=$form->{path}&login=$form->{login}&password=$form->{password}";
+  %acctype = ( 'A' => $locale->text('Asset'),
+               'L' => $locale->text('Liability'),
+              'Q' => $locale->text('Equity'),
+              'I' => $locale->text('Income'),
+              'E' => $locale->text('Expense'),
+            );
+  
+  $form->{title} = $locale->text('General Ledger');
+  
+  $ml = ($form->{ml} =~ /(A|E)/) ? -1 : 1;
+
+  unless ($form->{category} eq 'X') {
+    $form->{title} .= " : ".$locale->text($acctype{$form->{category}});
+  }
+  if ($form->{accno}) {
+    $callback .= "&accno=$form->{accno}";
+    $option = $locale->text('Account')." : $form->{accno} $form->{account_description}";
+  }
+  if ($form->{gifi_accno}) {
+    $callback .= "&gifi_accno=$form->{gifi_accno}";
+    $option .= "\n<br>" if $option;
+    $option .= $locale->text('GIFI')." : $form->{gifi_accno} $form->{gifi_account_description}";
+  }
+  if ($form->{source}) {
+    $callback .= "&source=".$form->escape($form->{source});
+    $option .= "\n<br>" if $option;
+    $option .= $locale->text('Source')." : $form->{source}";
+  }
+  if ($form->{reference}) {
+    $callback .= "&reference=".$form->escape($form->{reference});
+    $option .= "\n<br>" if $option;
+    $option .= $locale->text('Reference')." : $form->{reference}";
+  }
+  if ($form->{description}) {
+    $callback .= "&description=".$form->escape($form->{description});
+    $option .= "\n<br>" if $option;
+    $option .= $locale->text('Description')." : $form->{description}";
+  }
+  if ($form->{notes}) {
+    $callback .= "&notes=".$form->escape($form->{notes});
+    $option .= "\n<br>" if $option;
+    $option .= $locale->text('Notes')." : $form->{notes}";
+  }
+   
+  if ($form->{datefrom}) {
+    $callback .= "&datefrom=$form->{datefrom}";
+    $option .= "\n<br>" if $option;
+    $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{datefrom}, 1);
+  }
+  if ($form->{dateto}) {
+    $callback .= "&dateto=$form->{dateto}";
+    if ($form->{datefrom}) {
+      $option .= " ";
+    } else {
+      $option .= "\n<br>" if $option;
+    }
+    $option .= $locale->text('to')." ".$locale->date(\%myconfig, $form->{dateto}, 1);
+  }
+
+
+  @columns = $form->sort_columns(qw(transdate id reference description notes source debit credit accno gifi_accno));
+
+  if ($form->{accno} || $form->{gifi_accno}) {
+    @columns = grep !/(accno|gifi_accno)/, @columns;
+    push @columns, "balance";
+    $form->{l_balance} = "Y";
+  }
+  
+  $href = "$callback&sort=$form->{sort}";        # needed for accno
+  
+  foreach $item (@columns) {
+    if ($form->{"l_$item"} eq "Y") {
+      push @column_index, $item;
+
+      # add column to href and callback
+      $callback .= "&l_$item=Y";
+      $href .= "&l_$item=Y";
+    }
+  }
+  
+  if ($form->{l_subtotal} eq 'Y') {
+    $callback .= "&l_subtotal=Y";
+    $href .= "&l_subtotal=Y";
+  }
+
+  $callback .= "&category=$form->{category}";
+  $href .= "&category=$form->{category}";
+
+  $column_header{id} = "<th><a class=listheading href=$callback&sort=id>".$locale->text('ID')."</a></th>";
+  $column_header{transdate} = "<th><a class=listheading href=$callback&sort=transdate>".$locale->text('Date')."</a></th>";
+  $column_header{reference} = "<th><a class=listheading href=$callback&sort=reference>".$locale->text('Reference')."</a></th>";
+  $column_header{source} = "<th><a class=listheading href=$callback&sort=source>".$locale->text('Source')."</a></th>";
+  $column_header{description} = "<th><a class=listheading href=$callback&sort=description>".$locale->text('Description')."</a></th>";
+  $column_header{notes} = "<th class=listheading>".$locale->text('Notes')."</th>";
+  $column_header{debit} = "<th class=listheading>".$locale->text('Debit')."</th>";
+  $column_header{credit} = "<th class=listheading>".$locale->text('Credit')."</th>";
+  $column_header{accno} = "<th><a class=listheading href=$callback&sort=accno>".$locale->text('Account')."</a></th>";
+  $column_header{gifi_accno} = "<th><a class=listheading href=$callback&sort=gifi_accno>".$locale->text('GIFI')."</a></th>";
+  $column_header{balance} = "<th class=listheading>".$locale->text('Balance')."</th>";
+  $form->header;
+
+  print qq|
+<body>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>$option</td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+|;
+
+map { print "$column_header{$_}\n" } @column_index;
+
+print "
+        </tr>
+";
+  
+  # add sort to callback
+  $form->{callback} = "$callback&sort=$form->{sort}";
+  $callback = $form->escape($form->{callback});
+  
+  # initial item for subtotals
+  if (@{ $form->{GL} }) {
+    $sameitem = $form->{GL}->[0]->{$form->{sort}};
+  }
+  
+  if (($form->{accno} || $form->{gifi_accno}) && $form->{balance}) {
+
+    map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+    $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $form->{balance} * $ml, 2, 0)."</td>";
+    
+    $i++; $i %= 2;
+    print qq|
+        <tr class=listrow$i>
+|;
+    map { print "$column_data{$_}\n" } @column_index;
+    
+    print qq|
+        </tr>
+|;
+  }
+    
+  foreach $ref (@{ $form->{GL} }) {
+
+    # if item ne sort print subtotal
+    if ($form->{l_subtotal} eq 'Y') {
+      if ($sameitem ne $ref->{$form->{sort}}) {
+       &gl_subtotal;
+      }
+    }
+    
+    $form->{balance} += $ref->{amount};
+    
+    $subtotaldebit += $ref->{debit};
+    $subtotalcredit += $ref->{credit};
+    
+    $totaldebit += $ref->{debit};
+    $totalcredit += $ref->{credit};
+
+    $ref->{debit} = $form->format_amount(\%myconfig, $ref->{debit}, 2, "&nbsp;");
+    $ref->{credit} = $form->format_amount(\%myconfig, $ref->{credit}, 2, "&nbsp;");
+    
+    $column_data{id} = "<td>$ref->{id}</td>";
+    $column_data{transdate} = "<td>$ref->{transdate}</td>";
+    $column_data{reference} = "<td><a href=$ref->{module}.pl?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{reference}</td>";
+    $column_data{description} = "<td>$ref->{description}&nbsp;</td>";
+    $column_data{source} = "<td>$ref->{source}&nbsp;</td>";
+    $column_data{notes} = "<td>$ref->{notes}&nbsp;</td>";
+    $column_data{debit} = "<td align=right>$ref->{debit}</td>";
+    $column_data{credit} = "<td align=right>$ref->{credit}</td>";
+    $column_data{accno} = "<td><a href=$href&accno=$ref->{accno}&callback=$callback>$ref->{accno}</a></td>";
+    $column_data{gifi_accno} = "<td><a href=$href&gifi_accno=$ref->{gifi_accno}&callback=$callback>$ref->{gifi_accno}</a>&nbsp;</td>";
+    $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $form->{balance} * $ml, 2, 0)."</td>";
+
+    $i++; $i %= 2;
+    print "
+        <tr class=listrow$i>";
+    map { print "$column_data{$_}\n" } @column_index;
+    print "</tr>";
+    
+  }
+
+
+  &gl_subtotal if ($form->{l_subtotal} eq 'Y');
+
+
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+  
+  $column_data{debit} = "<th align=right>".$form->format_amount(\%myconfig, $totaldebit, 2, "&nbsp;")."</th>";
+  $column_data{credit} = "<th align=right>".$form->format_amount(\%myconfig, $totalcredit, 2, "&nbsp;")."</th>";
+  $column_data{balance} = "<th align=right>".$form->format_amount(\%myconfig, $form->{balance} * $ml, 2, 0)."</th>";
+  
+  print qq|
+       <tr class=listtotal>
+|;
+
+  map { print "$column_data{$_}\n" } @column_index;
+
+  print qq|
+        </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<br>
+
+<form method=post action=$form->{script}>
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input class=submit type=submit name=action value="|.$locale->text('GL Transaction').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('AR Transaction').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('AP Transaction').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('Sales Invoice').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('Vendor Invoice').qq|">
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub gl_subtotal {
+      
+  $subtotaldebit = $form->format_amount(\%myconfig, $subtotaldebit, 2, "&nbsp;");
+  $subtotalcredit = $form->format_amount(\%myconfig, $subtotalcredit, 2, "&nbsp;");
+  
+  map { $column_data{$_} = "<td>&nbsp;</td>" } qw(transdate id reference source description accno);
+  $column_data{debit} = "<th class=listsubtotal align=right>$subtotaldebit</td>";
+  $column_data{credit} = "<th class=listsubtotal align=right>$subtotalcredit</td>";
+
+  
+  print "<tr class=listsubtotal>";
+  map { print "$column_data{$_}\n" } @column_index;
+  print "</tr>";
+
+  $subtotaldebit = 0;
+  $subtotalcredit = 0;
+
+  $sameitem = $ref->{$form->{sort}};
+
+}
+
+
+sub update {
+
+  @a = ();
+  $count = 0;
+  @flds = (qw(accno debit credit projectnumber project_id));
+
+  for $i (1 .. $form->{rowcount}) {
+    unless (($form->{"debit_$i"} eq "") && ($form->{"credit_$i"} eq "")) {
+      # take accno apart
+      ($form->{"accno_$i"}) = split(/--/, $form->{"accno_$i"});
+      
+      push @a, {};
+      $j = $#a;
+      
+      map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
+      $count++;
+    }
+  }
+
+  for $i (1 .. $count) {
+    $j = $i - 1;
+    map { $form->{"${_}_$i"} = $a[$j]->{$_} } @flds;
+  }
+
+  for $i ($count + 1 .. $form->{rowcount}) {
+    map { delete $form->{"${_}_$i"} } @flds;
+  }
+
+  $form->{rowcount} = $count;
+
+  &check_project;
+
+  &display_form;
+  
+}
+
+
+sub display_form {
+
+  &form_header;
+
+  $form->{rowcount}++;
+  $form->{totaldebit} = 0;
+  $form->{totalcredit} = 0;
+  
+  for $i (1 .. $form->{rowcount}) {
+    $form->{totaldebit} += $form->parse_amount(\%myconfig, $form->{"debit_$i"});
+    $form->{totalcredit} += $form->parse_amount(\%myconfig, $form->{"credit_$i"});
+    &form_row($i);
+  }
+
+  &form_footer;
+
+}
+
+
+sub form_row {
+  my $i = shift;
+  
+  my $chart = $form->{chart};
+  $chart =~ s/<option>$form->{"accno_$i"}/<option selected>$form->{"accno_$i"}/;
+  
+  print qq|<tr>
+  <td><select name="accno_$i">$chart</select></td>
+  <td><input name="debit_$i" size=12 value=$form->{"debit_$i"}></td>
+  <td><input name="credit_$i" size=12 value=$form->{"credit_$i"}></td>
+  <td><input name="projectnumber_$i" size=12 value="$form->{"projectnumber_$i"}">
+      <input type=hidden name="project_id_$i" value=$form->{"project_id_$i"}>
+      <input type=hidden name="oldprojectnumber_$i" value="$form->{"oldprojectnumber_$i"}"></td>
+</tr>
+<input type=hidden name=rowcount value=$i>
+
+|;
+
+}
+
+
+sub form_header {
+
+  $title = $form->{title};
+  $form->{title} = $locale->text("$title General Ledger Transaction");
+  
+# $locale->text('Add General Ledger Transaction')
+# $locale->text('Edit General Ledger Transaction')
+
+  map { $form->{$_} =~ s/"/&quot;/g } qw(reference description chart);
+
+  if (($rows = $form->numtextrows($form->{description}, 50)) > 1) {
+    $description = qq|<textarea name=description rows=$rows cols=50 wrap=soft>$form->{description}</textarea>|;
+  } else {
+    $description = qq|<input name=description size=50 value="$form->{description}">|;
+  }
+  
+  if (($rows = $form->numtextrows($form->{notes}, 50)) > 1) {
+    $notes = qq|<textarea name=notes rows=$rows cols=50 wrap=soft>$form->{notes}</textarea>|;
+  } else {
+    $notes = qq|<input name=notes size=50 value="$form->{notes}">|;
+  }
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input name=id type=hidden value=$form->{id}>
+
+<input name=chart type=hidden value="$form->{chart}">
+<input type=hidden name=closedto value=$form->{closedto}>
+<input type=hidden name=locked value=$form->{locked}>
+<input type=hidden name=title value="$title">
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr>
+         <th align=right>|.$locale->text('Reference').qq|</th>
+         <td><input name=reference size=20 value="$form->{reference}"></td>
+         <td align=right>
+           <table>
+             <tr>
+               <th align=right>|.$locale->text('Date').qq|</th>
+               <td><input name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Description').qq|</th>
+         <td colspan=2>$description</td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Notes').qq|</th>
+         <td colspan=2>$notes</td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+         <th class=listheading>|.$locale->text('Account').qq|</th>
+         <th class=listheading>|.$locale->text('Debit').qq|</th>
+         <th class=listheading>|.$locale->text('Credit').qq|</th>
+         <th class=listheading>|.$locale->text('Project').qq|</th>
+       </tr>
+|;
+
+}
+
+
+sub form_footer {
+
+  ($dec) = ($form->{totaldebit} =~ /\.(\d+)/);
+  $dec = length $dec;
+  $decimalplaces = ($dec > 2) ? $dec : 2;
+  
+  map { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, $decimalplaces, "&nbsp;") } qw(totaldebit totalcredit);
+  
+  print qq|
+        <tr class=listtotal>
+         <th>&nbsp;</th>
+         <th class=listtotal align=right>$form->{totaldebit}</th>
+         <th class=listtotal align=right>$form->{totalcredit}</th>
+         <th>&nbsp;</th>
+        </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<br>
+|;
+
+  $transdate = $form->datetonum($form->{transdate}, \%myconfig);
+  $closedto = $form->datetonum($form->{closedto}, \%myconfig);
+  
+  if ($form->{id}) {
+    print qq|<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+|;
+
+    if (!$form->{revtrans}) {
+      if (!$form->{locked}) {
+       print qq|
+       <input class=submit type=submit name=action value="|.$locale->text('Post').qq|">
+       <input class=submit type=submit name=action value="|.$locale->text('Delete').qq|">
+|;
+      }
+    }
+
+    if ($transdate > $closedto) {
+      print qq|
+      <input class=submit type=submit name=action value="|.$locale->text('Post as new').qq|">
+|;
+    }
+    
+  } else {
+    if ($transdate > $closedto) {
+      print qq|<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+      <input class=submit type=submit name=action value="|.$locale->text('Post').qq|">|;
+    }
+  }
+
+  print "</form>
+
+</body>
+</html>
+";
+  
+}
+
+
+sub delete {
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+|;
+
+  map { $form->{$_} =~ s/"/&quot;/g } qw(reference description chart);
+
+  foreach $key (keys %$form) {
+    print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
+  }
+
+  print qq|
+<h2 class=confirm>|.$locale->text('Confirm!').qq|</h2>
+
+<h4>|.$locale->text('Are you sure you want to delete Transaction').qq| $form->{reference}</h4>
+
+<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|">
+</form>
+|;
+
+}
+
+
+sub yes {
+
+  $form->redirect($locale->text('Transaction deleted!')) if (GL->delete_transaction(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot delete transaction!'));
+  
+}
+
+
+sub post {
+
+  # check if there is something in reference and date
+  $form->isblank("reference", $locale->text('Reference missing!'));
+  $form->isblank("transdate", $locale->text('Transaction Date missing!'));
+
+  $transdate = $form->datetonum($form->{transdate}, \%myconfig);
+  $closedto = $form->datetonum($form->{closedto}, \%myconfig);
+
+  # check project
+  &check_project;
+  
+  # this is just for the wise guys
+  $form->error($locale->text('Cannot post transaction for a closed period!')) if ($transdate <= $closedto);
+  
+  if (($errno = GL->post_transaction(\%myconfig, \%$form)) <= -1) {
+    $errno *= -1;
+    $err[1] = $locale->text('Cannot have a value in both Debit and Credit!');
+    $err[2] = $locale->text('Debit and credit out of balance!');
+    $err[3] = $locale->text('Cannot post a transaction without a value!');
+    
+    $form->error($err[$errno]);
+  }
+    
+  $form->redirect($locale->text('Transaction posted!'));
+  
+}
+
+
+sub post_as_new {
+
+  $form->{id} = 0;
+  &post;
+
+}
+
+
diff --git a/sql-ledger/bin/mozilla/ic.pl b/sql-ledger/bin/mozilla/ic.pl
new file mode 100644 (file)
index 0000000..797daee
--- /dev/null
@@ -0,0 +1,1638 @@
+#=====================================================================
+# SQL-Ledger, Accounting
+# Copyright (c) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Inventory Control module
+#
+#======================================================================
+
+
+use SL::IC;
+
+require "$form->{path}/io.pl";
+
+1;
+# end of main
+
+
+
+sub add {
+
+  $form->{title} = $locale->text('Add ' . ucfirst $form->{item});
+
+  $form->{callback} = "$form->{script}?action=add&item=$form->{item}&path=$form->{path}&login=$form->{login}&password=$form->{password}" unless $form->{callback};
+
+  $form->{unit} = ($form->{item} eq 'service') ? $locale->text('hr') : $locale->text('ea');
+
+  &link_part;
+  
+  &display_form;
+  
+}
+
+
+sub search {
+
+  $form->{title} = (ucfirst $form->{searchitems})."s";
+  $form->{title} = $locale->text($form->{title});
+  
+# $locale->text('Parts')
+# $locale->text('Services')
+
+  unless ($form->{searchitems} eq 'service') {
+    
+    $onhand = qq|
+            <input name=itemstatus class=radio type=radio value=onhand>&nbsp;|.$locale->text('On Hand').qq|
+            <input name=itemstatus class=radio type=radio value=short>&nbsp;|.$locale->text('Short').qq|
+|;
+
+    $makemodel = qq|
+        <tr>
+          <th width="1%" align=right nowrap>|.$locale->text('Make').qq|</th>
+          <td><input name=make size=20></td>
+          <th width="1%" align=right nowrap>|.$locale->text('Model').qq|</th>
+          <td><input name=model size=20></td>
+        </tr>
+|;
+  }
+
+  if ($form->{searchitems} eq 'assembly') {
+
+    $form->{title} = $locale->text('Assemblies');
+    
+    $toplevel = qq|
+        <tr>
+         <td></td>
+          <td colspan=3>
+         <input name=none class=radio type=radio value=1 checked>&nbsp;|.$locale->text('Top Level').qq|
+         <input name=bom class=checkbox type=checkbox value=1>&nbsp;|.$locale->text('Individual Items').qq|
+          </td>
+        </tr>
+|;
+    
+    $bought = qq|
+       <tr>
+         <td></td>
+         <td colspan=3>
+           <table>
+             <tr>
+               <td>
+                 <table>
+                   <tr>
+                     <td><input name=sold class=checkbox type=checkbox value=1></td>
+                     <td nowrap>|.$locale->text('Sold').qq|</td>
+                   </tr>
+                   <tr>
+                     <td colspan=2><hr size=1 noshade></td>
+                   </tr>
+                   <tr>
+                     <td><input name=ordered class=checkbox type=checkbox value=1></td>
+                     <td nowrap>|.$locale->text('Ordered').qq|</td>
+                   </tr>
+                 </table>
+               </td>
+               <td width=5%>&nbsp;</td>
+               <th>|.$locale->text('From').qq|</th>
+               <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td>
+               <th>|.$locale->text('to').qq|</th>
+               <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td>
+
+               <td><input name=closed class=checkbox type=checkbox value=1>&nbsp;|.$locale->text('Closed').qq|</td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+|;
+
+  } else {
+       
+     $bought = qq|
+        <tr>
+          <td></td>
+          <td colspan=3>
+           <table>
+             <tr>
+               <td>
+                 <table>
+                   <tr>
+                     <td><input name=bought class=checkbox type=checkbox value=1></td>
+                     <td nowrap>|.$locale->text('Bought').qq|</td>
+                     <td><input name=sold class=checkbox type=checkbox value=1></td>
+                     <td nowrap>|.$locale->text('Sold').qq|</td>
+                   </tr>
+                   <tr>
+                     <td colspan=4><hr size=1 noshade></td>
+                   </tr>
+                   <tr>
+                     <td><input name=onorder class=checkbox type=checkbox value=1></td>
+                     <td nowrap>|.$locale->text('On Order').qq|</td>
+                     <td><input name=ordered class=checkbox type=checkbox value=1></td>
+                     <td nowrap>|.$locale->text('Ordered').qq|</td>
+                   </tr>
+                 </table>
+               </td>
+               <td width=5%>&nbsp;</td>
+               <td>
+                 <table>
+                   <tr>
+                     <th>|.$locale->text('From').qq|</th>
+                     <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td>
+                     <th>|.$locale->text('to').qq|</th>
+                     <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td>
+
+                     <td><input name=closed class=checkbox type=checkbox value=1>&nbsp;|.$locale->text('Closed').qq|</td>
+                   </tr>
+                 </table>
+               </td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+|;
+  }
+
+
+  $form->header;
+  
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=searchitems value=$form->{searchitems}>
+<input type=hidden name=title value="$form->{title}">
+
+<table width="100%">
+  <tr><th class=listtop>$form->{title}</th></tr>
+  <tr height="5"></tr>
+  <tr valign=top>
+    <td>
+      <table>
+        <tr>
+          <th width=1% align=right nowrap>|.$locale->text('Number').qq|</th>
+          <td><input name=partnumber size=20></td>
+          <th align=right nowrap>|.$locale->text('Description').qq|</th>
+          <td><input name=description size=40></td>
+        </tr>
+        <tr>
+          <th align=right nowrap>|.$locale->text('Group').qq|</th>
+          <td><input name=partsgroup size=20></td>
+        </tr>
+       $makemodel
+        <tr>
+          <th align=right nowrap>|.$locale->text('Drawing').qq|</th>
+          <td><input name=drawing size=20></td>
+          <th align=right nowrap>|.$locale->text('Microfiche').qq|</th>
+          <td><input name=microfiche size=20></td>
+        </tr>
+       $toplevel
+        <tr>
+          <td></td>
+          <td colspan=3>
+            <input name=itemstatus class=radio type=radio value=active checked>&nbsp;|.$locale->text('Active').qq|
+           $onhand
+            <input name=itemstatus class=radio type=radio value=obsolete>&nbsp;|.$locale->text('Obsolete').qq|
+            <input name=itemstatus class=radio type=radio value=orphaned>&nbsp;|.$locale->text('Orphaned').qq|
+         </td>
+       </tr>
+       $bought
+        <tr>
+         <td></td>
+          <td colspan=3>
+           <hr size=1 noshade>
+         </td>
+       </tr>
+       <tr>
+          <th align=right nowrap>|.$locale->text('Include in Report').qq|</th>
+          <td colspan=3>
+            <table>
+              <tr>
+                <td><input name=l_partnumber class=checkbox type=checkbox value=Y checked>&nbsp;|.$locale->text('Number').qq|</td>
+               <td><input name=l_description class=checkbox type=checkbox value=Y checked>&nbsp;|.$locale->text('Description').qq|</td>
+               <td><input name=l_unit class=checkbox type=checkbox value=Y checked>&nbsp;|.$locale->text('Unit of measure').qq|</td>
+             </tr>
+             <tr>
+                <td><input name=l_listprice class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('List Price').qq|</td>
+               <td><input name=l_sellprice class=checkbox type=checkbox value=Y checked>&nbsp;|.$locale->text('Sell Price').qq|</td>
+               <td><input name=l_lastcost class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Last Cost').qq|</td>
+               <td><input name=l_linetotal class=checkbox type=checkbox value=Y checked>&nbsp;|.$locale->text('Line Total').qq|</td>
+             </tr>
+             <tr>
+                <td><input name=l_priceupdate class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Updated').qq|</td>
+               <td><input name=l_bin class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Bin').qq|</td>
+               <td><input name=l_rop class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('ROP').qq|</td>
+               <td><input name=l_weight class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Weight').qq|</td>
+              </tr>
+             <tr>
+                <td><input name=l_image class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Image').qq|</td>
+               <td><input name=l_drawing class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Drawing').qq|</td>
+               <td><input name=l_microfiche class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Microfiche').qq|</td>
+               <td><input name=l_partsgroup class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Group').qq|</td>
+              </tr>
+             <tr>
+                <td><input name=l_subtotal class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Subtotal').qq|</td>
+             </tr>
+            </table>
+          </td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+  <tr><td colspan=4><hr size=3 noshade></td></tr>
+</table>
+
+<input type=hidden name=nextsub value=generate_report>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+sub generate_report {
+
+  # setup $form->{sort}
+  unless ($form->{sort}) {
+    if ($form->{description} && !($form->{partnumber})) {
+      $form->{sort} = "description";
+    } else {
+      $form->{sort} = "partnumber";
+    }
+  }
+
+  $callback = "$form->{script}?action=generate_report&path=$form->{path}&login=$form->{login}&password=$form->{password}&searchitems=$form->{searchitems}&itemstatus=$form->{itemstatus}&bom=$form->{bom}&l_linetotal=$form->{l_linetotal}&title=".$form->escape($form->{title},1);
+
+  IC->all_parts(\%myconfig, \%$form);
+
+
+  if ($form->{itemstatus} eq 'active') {
+    $option .= $locale->text('Active')." : ";
+  }
+  if ($form->{itemstatus} eq 'obsolete') {
+    $option .= $locale->text('Obsolete')." : ";
+  }
+  if ($form->{itemstatus} eq 'orphaned') {
+    $option .= $locale->text('Orphaned')." : ";
+  }
+  if ($form->{itemstatus} eq 'onhand') {
+    $option .= $locale->text('On Hand')." : ";
+    $form->{l_onhand} = "Y";
+  }
+  if ($form->{itemstatus} eq 'short') {
+    $option .= $locale->text('Short')." : ";
+    $form->{l_onhand} = "Y";
+  }
+  if ($form->{onorder}) {
+    $form->{l_ordnumber} = "Y";
+    $callback .= "&onorder=$form->{onorder}";
+    $option .= $locale->text('On Order')." : ";
+  }
+  if ($form->{ordered}) {
+    $form->{l_ordnumber} = "Y";
+    $callback .= "&ordered=$form->{ordered}";
+    $option .= $locale->text('Ordered')." : ";
+  }
+  if ($form->{closed}) {
+    $callback .= "&closed=$form->{closed}";
+    $option .= $locale->text('Closed')." : ";
+  }
+  if ($form->{bought}) {
+    $form->{l_invnumber} = "Y";
+    $callback .= "&bought=$form->{bought}";
+    $option .= $locale->text('Bought')." : ";
+  }
+  if ($form->{sold}) {
+    $form->{l_invnumber} = "Y";
+    $callback .= "&sold=$form->{sold}";
+    $option .= $locale->text('Sold')." : ";
+  }
+  if ($form->{bought} || $form->{sold} || $form->{onorder} || $form->{ordered}) {
+    
+    $form->{l_lastcost} = "";
+    if ($form->{transdatefrom}) {
+      $callback .= "&transdatefrom=$form->{transdatefrom}";
+      $option .= "\n<br>".$locale->text('From')."&nbsp;".$locale->date(\%myconfig, $form->{transdatefrom}, 1);
+    }
+    if ($form->{transdateto}) {
+      $callback .= "&transdateto=$form->{transdateto}";
+      $option .= "\n<br>".$locale->text('to')."&nbsp;".$locale->date(\%myconfig, $form->{transdateto}, 1);
+    }
+  }
+  
+  $option .= "<br>";
+  
+  if ($form->{partnumber}) {
+    $callback .= "&partnumber=$form->{partnumber}";
+    $option .= $locale->text('Number').qq| : $form->{partnumber}<br>|;
+  }
+  if ($form->{description}) {
+    $callback .= "&description=$form->{description}";
+    $option .= $locale->text('Description').qq| : $form->{description}<br>|;
+  }
+  if ($form->{make}) {
+    $callback .= "&make=$form->{make}";
+    $option .= $locale->text('Make').qq| : $form->{make}<br>|;
+  }
+  if ($form->{model}) {
+    $callback .= "&model=$form->{model}";
+    $option .= $locale->text('Model').qq| : $form->{model}<br>|;
+  }
+  if ($form->{drawing}) {
+    $callback .= "&drawing=$form->{drawing}";
+    $option .= $locale->text('Drawing').qq| : $form->{drawing}<br>|;
+  }
+  if ($form->{microfiche}) {
+    $callback .= "&microfiche=$form->{microfiche}";
+    $option .= $locale->text('Microfiche').qq| : $form->{microfiche}<br>|;
+  }
+  if ($form->{partsgroup}) {
+    $callback .= "&partsgroup=$form->{partsgroup}";
+    $option .= $locale->text('Group').qq| : $form->{partsgroup}<br>|;
+  }
+
+
+  @columns = $form->sort_columns(qw(partnumber description partsgroup bin onhand rop unit listprice linetotallistprice sellprice linetotalsellprice lastcost linetotallastcost priceupdate weight image drawing microfiche invnumber ordnumber));
+
+  if ($form->{l_linetotal}) {
+    $form->{l_onhand} = "Y";
+    $form->{l_linetotalsellprice} = "Y" if $form->{l_sellprice};
+    if ($form->{l_lastcost}) {
+      $form->{l_linetotallastcost} = "Y";
+      if (($form->{searchitems} eq 'assembly') && !$form->{bom}) {
+       $form->{l_linetotallastcost} = "";
+      }
+    }
+    $form->{l_linetotallistprice} = "Y" if $form->{l_listprice};
+  }
+
+  if ($form->{searchitems} eq 'service') {
+    # remove bin, weight and rop from list
+    map { $form->{"l_$_"} = "" } qw(bin weight rop);
+
+    $form->{l_onhand} = "";
+    # qty is irrelevant unless bought or sold
+    if ($form->{bought} || $form->{sold} || $form->{onorder} || $form->{ordered}) {
+      $form->{l_onhand} = "Y";
+    } else {
+      $form->{l_linetotalsellprice} = "";
+      $form->{l_linetotallastcost} = "";
+    }
+  }
+
+  $form->{l_lastcost} = "" if ($form->{searchitems} eq 'assembly' && !$form->{bom});
+  
+  foreach $item (@columns) {
+    if ($form->{"l_$item"} eq "Y") {
+      push @column_index, $item;
+
+      # add column to callback
+      $callback .= "&l_$item=Y";
+    }
+  }
+
+  if ($form->{l_subtotal} eq 'Y') {
+    $callback .= "&l_subtotal=Y";
+  }
+  
+  $column_header{partnumber} = qq|<th nowrap><a class=listheading href=$callback&sort=partnumber>|.$locale->text('Number').qq|</a></th>|;
+  $column_header{description} = qq|<th nowrap><a class=listheading href=$callback&sort=description>|.$locale->text('Description').qq|</a></th>|;
+  $column_header{partsgroup} = qq|<th nowrap><a class=listheading href=$callback&sort=partsgroup>|.$locale->text('Group').qq|</a></th>|;
+  $column_header{bin} = qq|<th><a class=listheading href=$callback&sort=bin>|.$locale->text('Bin').qq|</a></th>|;
+  $column_header{priceupdate} = qq|<th nowrap><a class=listheading href=$callback&sort=priceupdate>|.$locale->text('Updated').qq|</a></th>|;
+  $column_header{onhand} = qq|<th class=listheading nowrap>|.$locale->text('Qty').qq|</th>|;
+  $column_header{unit} = qq|<th class=listheading nowrap>|.$locale->text('Unit').qq|</th>|;
+  $column_header{listprice} = qq|<th class=listheading nowrap>|.$locale->text('List Price').qq|</th>|;
+  $column_header{lastcost} = qq|<th class=listheading nowrap>|.$locale->text('Last Cost').qq|</th>|;
+  $column_header{rop} = qq|<th class=listheading nowrap>|.$locale->text('ROP').qq|</th>|;
+  $column_header{weight} = qq|<th class=listheading nowrap>|.$locale->text('Weight').qq|</th>|;
+  
+  $column_header{invnumber} = qq|<th nowrap><a class=listheading href=$callback&sort=invnumber>|.$locale->text('Invoice Number').qq|</a></th>|;
+  $column_header{ordnumber} = qq|<th nowrap><a class=listheading href=$callback&sort=ordnumber>|.$locale->text('Order Number').qq|</a></th>|;
+  
+  $column_header{sellprice} = qq|<th class=listheading nowrap>|.$locale->text('Sell Price').qq|</th>|;
+  $column_header{linetotalsellprice} = qq|<th class=listheading nowrap>|.$locale->text('Extended').qq|</th>|;
+  $column_header{linetotallastcost} = qq|<th class=listheading nowrap>|.$locale->text('Extended').qq|</th>|;
+  $column_header{linetotallistprice} = qq|<th class=listheading nowrap>|.$locale->text('Extended').qq|</th>|;
+  
+  $column_header{image} = qq|<th class=listheading nowrap>|.$locale->text('Image').qq|</a></th>|;
+  $column_header{drawing} = qq|<th nowrap><a class=listheading href=$callback&sort=drawing>|.$locale->text('Drawing').qq|</a></th>|;
+  $column_header{microfiche} = qq|<th nowrap><a class=listheading href=$callback&sort=microfiche>|.$locale->text('Microfiche').qq|</a></th>|;
+  
+  $form->header;
+  $colspan = $#column_index + 1;
+
+  print qq|
+<body>
+
+<table width=100%>
+<tr><th class=listtop colspan=$colspan>$form->{title}</th></tr>
+<tr height="5"></tr>
+
+<tr><td colspan=$colspan>$option</td></tr>
+
+  <tr class=listheading>
+|;
+
+  map { print "\n$column_header{$_}" } @column_index;
+  
+  print qq|
+  </tr>
+  |;
+
+
+  # add order to callback
+  $form->{callback} = $callback .= "&sort=$form->{sort}";
+
+  # escape callback for href
+  $callback = $form->escape($callback);
+
+  if (@{ $form->{parts} }) {
+    $sameitem = $form->{parts}->[0]->{$form->{sort}};
+  }
+
+  foreach $ref (@{ $form->{parts} }) {
+  
+    if ($form->{l_subtotal} eq 'Y' && !$ref->{assemblyitem}) {
+      if ($sameitem ne $ref->{$form->{sort}}) {
+       &parts_subtotal;
+       $sameitem = $ref->{$form->{sort}};
+      }
+    }
+
+    $ref->{exchangerate} = 1 unless $ref->{exchangerate};
+    $ref->{sellprice} *= $ref->{exchangerate};
+    $ref->{listprice} *= $ref->{exchangerate};
+    $ref->{lastcost} *= $ref->{exchangerate};
+    
+    $align = "left";
+    $onhand = $ref->{onhand};
+    
+    if ($ref->{assemblyitem}) {
+      $align = "right";
+      $onhand = 0 if ($form->{sold});
+    }
+
+    $column_data{partnumber} = "<td align=$align><a href=$form->{script}?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{partnumber}&nbsp;</a></td>";
+    $column_data{description} = "<td>$ref->{description}&nbsp;</td>";
+    $column_data{partsgroup} = "<td>$ref->{partsgroup}&nbsp;</td>";
+   
+    $column_data{onhand} = "<td align=right>".$form->format_amount(\%myconfig, $onhand, '', "&nbsp;")."</td>";
+    $column_data{sellprice} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{sellprice}, 2, "&nbsp;") . "</td>";
+    $column_data{listprice} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{listprice}, 2, "&nbsp;") . "</td>";
+    $column_data{lastcost} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{lastcost}, 2, "&nbsp;") . "</td>";
+    
+    $column_data{linetotalsellprice} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{onhand} * $ref->{sellprice}, 2, "&nbsp;")."</td>";
+    $column_data{linetotallastcost} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{onhand} * $ref->{lastcost}, 2, "&nbsp;")."</td>";
+    $column_data{linetotallistprice} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{onhand} * $ref->{listprice}, 2, "&nbsp;")."</td>";
+    
+    if (!$ref->{assemblyitem}) {
+      $totalsellprice += $onhand * $ref->{sellprice};
+      $totallastcost += $onhand * $ref->{lastcost};
+      $totallistprice += $onhand * $ref->{listprice};
+
+      $subtotalonhand += $onhand;
+      $subtotalsellprice += $onhand * $ref->{sellprice};
+      $subtotallastcost += $onhand * $ref->{lastcost};
+      $subtotallistprice += $onhand * $ref->{listprice};
+    }
+
+    $column_data{rop} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{rop}, '', "&nbsp;")."</td>";
+    $column_data{weight} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{weight}, '', "&nbsp;")."</td>";
+    $column_data{unit} = "<td>$ref->{unit}&nbsp;</td>";
+    $column_data{bin} = "<td>$ref->{bin}&nbsp;</td>";
+    $column_data{priceupdate} = "<td>$ref->{priceupdate}&nbsp;</td>";
+    
+    $column_data{invnumber} = ($ref->{module} ne 'oe') ? "<td><a href=$ref->{module}.pl?action=edit&type=invoice&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{invnumber}&nbsp;</a></td>" : "<td>$ref->{invnumber}&nbsp;</td>";
+    $column_data{ordnumber} = ($ref->{module} eq 'oe') ? "<td><a href=$ref->{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{ordnumber}&nbsp;</a></td>" : "<td>$ref->{ordnumber}&nbsp;</td>";
+   
+    $column_data{image} = ($ref->{image}) ? "<td><a href=$ref->{image}><img src=$ref->{image} height=32 border=0></a></td>" : "<td>&nbsp;</td>";
+    $column_data{drawing} = ($ref->{drawing}) ? "<td><a href=$ref->{drawing}>$ref->{drawing}</a></td>" : "<td>&nbsp;</td>";
+    $column_data{microfiche} = ($ref->{microfiche}) ? "<td><a href=$ref->{microfiche}>$ref->{microfiche}</a></td>" : "<td>&nbsp;</td>";
+    
+    $i++; $i %= 2;
+    print "<tr class=listrow$i>";
+
+    map { print "\n$column_data{$_}" } @column_index;
+
+    print qq|
+    </tr>
+|;
+
+  }
+  
+  
+  if ($form->{l_subtotal} eq 'Y') {
+    &parts_subtotal;
+  }
+
+  if ($form->{"l_linetotal"}) {
+    map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+    $column_data{linetotalsellprice} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalsellprice, 2, "&nbsp;")."</th>";
+    $column_data{linetotallastcost} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totallastcost, 2, "&nbsp;")."</th>";
+    $column_data{linetotallistprice} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totallistprice, 2, "&nbsp;")."</th>";
+
+    print "<tr class=listtotal>";
+
+    map { print "\n$column_data{$_}" } @column_index;
+
+    print qq|</tr>
+    |;
+  }
+
+  print qq|
+  <tr><td colspan=$colspan><hr size=3 noshade></td></tr>
+</table>
+
+|;
+
+
+  print qq|
+
+<br>
+
+<form method=post action=$form->{script}>
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=item value=$form->{searchitems}>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input class=submit type=submit name=action value="|.$locale->text('Add').qq|">
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+sub parts_subtotal {
+
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+  $subtotalonhand = 0 if ($form->{searchitems} eq 'assembly' && $form->{bom});
+
+  $column_data{onhand} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalonhand, '', "&nbsp;")."</th>";
+  $column_data{sellprice} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalsellprice, 2, "&nbsp;")."</th>";
+  $column_data{listprice} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotallistprice, 2, "&nbsp;")."</th>";
+  $column_data{lastcost} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotallastcost, 2, "&nbsp;")."</th>";
+  
+  $subtotalonhand = 0;
+  $subtotalsellprice = 0;
+  $subtotallistprice = 0;
+  $subtotallastcost = 0;
+
+  print "<tr class=listsubtotal>";
+
+  map { print "\n$column_data{$_}" } @column_index;
+
+  print qq|
+  </tr>
+|;
+
+}
+
+
+
+sub edit {
+
+  IC->get_part(\%myconfig, \%$form);
+
+  $form->{title} = $locale->text('Edit '.ucfirst $form->{item});
+
+  &link_part;
+  &display_form;
+  
+}
+
+
+
+sub link_part {
+
+  IC->create_links("IC", \%myconfig, \%$form);
+  
+  # parts and assemblies have the same links
+  $item = $form->{item};
+  if ($form->{item} eq 'assembly') {
+    $item = 'part';
+  }
+
+  # build the popup menus
+  $form->{taxaccounts} = "";
+  foreach $key (keys %{ $form->{IC_links} }) {
+    foreach $ref (@{ $form->{IC_links}{$key} }) {
+      # if this is a tax field
+      if ($key =~ /IC_tax/) {
+       if ($key =~ /$item/) {
+         $form->{taxaccounts} .= "$ref->{accno} ";
+         $form->{"IC_tax_$ref->{accno}_description"} = "$ref->{accno}--$ref->{description}";
+         
+         if ($form->{id}) {
+           if ($form->{amount}{$ref->{accno}}) {
+             $form->{"IC_tax_$ref->{accno}"} = "checked";
+           }
+         } else {
+           $form->{"IC_tax_$ref->{accno}"} = "checked";
+         }
+       }
+      } else {
+
+       $form->{"select$key"} .= "<option>$ref->{accno}--$ref->{description}\n";
+       if ($form->{amount}{$key} eq $ref->{accno}) {
+         $form->{$key} = "$ref->{accno}--$ref->{description}";
+       }
+       
+      }
+    }
+  }
+  chop $form->{taxaccounts};
+
+  if (($form->{item} eq "part") || ($form->{item} eq "assembly")) {
+    $form->{selectIC_income} = $form->{selectIC_sale};
+    $form->{selectIC_expense} = $form->{selectIC_cogs};
+    $form->{IC_income} = $form->{IC_sale};
+    $form->{IC_expense} = $form->{IC_cogs};
+  }
+  
+  delete $form->{IC_links};
+  delete $form->{amount};
+
+}
+
+
+
+sub form_header {
+
+  ($dec) = ($form->{sellprice} =~ /\.(\d+)/);
+  $dec = length $dec;
+  my $decimalplaces = ($dec > 2) ? $dec : 2;
+
+  map { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, $decimalplaces)} qw(listprice sellprice);
+
+  ($dec) = ($form->{lastcost} =~ /\.(\d+)/);
+  $dec = length $dec;
+  my $decimalplaces = ($dec > 2) ? $dec : 2;
+
+  $form->{lastcost} = $form->format_amount(\%myconfig, $form->{lastcost}, $decimalplaces);
+
+  map { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}) } qw(weight rop stock);
+
+  foreach $item (qw(partnumber description unit notes)) {
+    $form->{$item} =~ s/"/&quot;/g;
+  }
+
+  
+  if (($rows = $form->numtextrows($form->{notes}, 40)) < 2) {
+    $rows = 2;
+  }
+  
+  $notes = qq|<textarea name=notes rows=$rows cols=40 wrap=soft>$form->{notes}</textarea>|;
+
+  if (($rows = $form->numtextrows($form->{description}, 40)) > 1) {
+    $description = qq|<textarea name="description" rows=$rows cols=40 wrap=soft>$form->{description}</textarea>|;
+  } else {
+    $description = qq|<input name=description size=40 value="$form->{description}">|;
+  }
+  
+  foreach $item (split / /, $form->{taxaccounts}) {
+    $form->{"IC_tax_$item"} = ($form->{"IC_tax_$item"}) ? "checked" : "";
+  }
+
+
+  # set option
+  foreach $item (qw(IC IC_income IC_expense)) {
+    if ($form->{$item}) {
+      if ($form->{id} && $form->{orphaned}) {
+       $form->{"select$item"} =~ s/ selected//;
+       $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
+
+      } else {
+       $form->{"select$item"} = qq|<option selected>$form->{$item}|;
+      }
+    }
+  }
+
+  # tax fields
+  foreach $item (split / /, $form->{taxaccounts}) {
+    $tax .= qq|
+      <input class=checkbox type=checkbox name="IC_tax_$item" value=1 $form->{"IC_tax_$item"}>&nbsp;<b>$form->{"IC_tax_${item}_description"}</b>
+      <br><input type=hidden name=IC_tax_${item}_description value="$form->{"IC_tax_${item}_description"}">
+|;
+  }
+
+  $form->{obsolete} = "checked" if $form->{obsolete};
+
+  $lastcost = qq|
+             <tr>
+                <th align="right" nowrap="true">|.$locale->text('Last Cost').qq|</th>
+                <td><input name=lastcost size=11 value=$form->{lastcost}></td>
+              </tr>
+|;
+  if ($form->{item} eq "part") {
+
+    $linkaccounts = qq|
+             <tr>
+               <th width="1%" align=right>|.$locale->text('Inventory').qq|</th>
+               <td><select name=IC>$form->{selectIC}</select></td>
+               <input name=selectIC type=hidden value="$form->{selectIC}">
+             </tr>
+             <tr>
+               <th align=right>|.$locale->text('Sales').qq|</th>
+               <td><select name=IC_income>$form->{selectIC_income}</select></td>
+               <input name=selectIC_income type=hidden value="$form->{selectIC_income}">
+             </tr>
+             <tr>
+               <th align=right>|.$locale->text('COGS').qq|</th>
+               <td><select name=IC_expense>$form->{selectIC_expense}</select></td>
+               <input name=selectIC_expense type=hidden value="$form->{selectIC_expense}">
+             </tr>
+|;
+  
+    if ($tax) {
+      $linkaccounts .= qq|
+             <tr>
+               <th align=right>|.$locale->text('Tax').qq|</th>
+               <td>$tax</td>
+             </tr>
+|;
+    }
+  
+    $weight = qq|
+             <tr>
+               <th align="right" nowrap="true">|.$locale->text('Weight').qq|</th>
+               <td>
+                 <table>
+                   <tr>
+                     <td>
+                       <input name=weight size=10 value=$form->{weight}>
+                     </td>
+                     <th>
+                       &nbsp;
+                       $form->{weightunit}
+                       <input type=hidden name=weightunit value=$form->{weightunit}>
+                     </th>
+                   </tr>
+                 </table>
+               </td>
+             </tr>
+|;
+    
+  }
+
+
+  if ($form->{item} eq "assembly") {
+    
+    $lastcost = "";
+    
+    $linkaccounts = qq|
+             <tr>
+               <th width="1%" align=right>|.$locale->text('Sales').qq|</th>
+               <td><select name=IC_income>$form->{selectIC_income}</select></td>
+               <input name=selectIC_income type=hidden value="$form->{selectIC_income}">
+             </tr>
+|;
+  
+    if ($tax) {
+      $linkaccounts .= qq|
+             <tr>
+               <th align=right>|.$locale->text('Tax').qq|</th>
+               <td>$tax</td>
+             </tr>
+|;
+    }
+  
+    $weight = qq|
+             <tr>
+               <th align="right" nowrap="true">|.$locale->text('Weight').qq|</th>
+               <td>
+                 <table>
+                   <tr>
+                     <td>
+                       &nbsp;$form->{weight}
+                       <input type=hidden name=weight value=$form->{weight}>
+                     </td>
+                     <th>
+                       &nbsp;
+                       $form->{weightunit}
+                       <input type=hidden name=weightunit value=$form->{weightunit}>
+                     </th>
+                   </tr>
+                 </table>
+               </td>
+             </tr>
+|;
+
+   
+  }
+
+  if ($form->{item} eq "service") {
+    
+    $linkaccounts = qq|
+             <tr>
+               <th width="1%" align=right>|.$locale->text('Income').qq|</th>
+               <td><select name=IC_income>$form->{selectIC_income}</select></td>
+               <input name=selectIC_income type=hidden value="$form->{selectIC_income}">
+             </tr>
+             <tr>
+               <th align=right>|.$locale->text('Expense').qq|</th>
+               <td><select name=IC_expense>$form->{selectIC_expense}</select></td>
+               <input name=selectIC_expense type=hidden value="$form->{selectIC_expense}">
+             </tr>
+|;
+  
+    if ($tax) {
+      $linkaccounts .= qq|
+             <tr>
+               <th align=right>|.$locale->text('Tax').qq|</th>
+               <td>$tax</td>
+             </tr>
+|;
+    }
+
+  }
+
+
+  if ($form->{item} ne 'service') {
+    $color = ($form->{onhand} > 0) ? "green" : "red";
+    $rop = qq|
+             <tr>
+               <th align="right" nowrap>|.$locale->text('On Hand').qq|</th>
+               <th align=left nowrap>&nbsp;|.$form->format_amount(\%myconfig, $form->{onhand}).qq|</th>
+             </tr>
+|;
+
+    if ($form->{item} eq 'assembly') {
+      $rop .= qq|
+             <tr>
+               <th align="right" nowrap>|.$locale->text('Stock').qq|</th>
+               <td><input name=stock size=10 value=$form->{stock}></td>
+             </tr>
+|;
+    }
+  
+    $rop .= qq|
+             <tr>
+               <th align="right" nowrap="true">|.$locale->text('ROP').qq|</th>
+               <td><input name=rop size=10 value=$form->{rop}></td>
+             </tr>
+|;
+    
+    $bin = qq|
+             <tr>
+               <th align="right" nowrap="true">|.$locale->text('Bin').qq|</th>
+               <td><input name=bin size=10 value=$form->{bin}></td>
+             </tr>
+|;
+    
+    $imagelinks = qq|
+  <tr>
+    <td>
+      <table>
+        <tr>
+         <th width=1% align=right nowrap>|.$locale->text('Image').qq|</th>
+         <td width=70%><input name=image size=40 value="$form->{image}"></td>
+
+       </tr>
+       <tr>
+         <th width=1% align=right nowrap>|.$locale->text('Drawing').qq|</th>
+         <td width=70%><input name=drawing size=40 value="$form->{drawing}"></td>
+         <th width=1% align=right nowrap>|.$locale->text('Microfiche').qq|</th>
+         <td width=30%><input name=microfiche size=20 value="$form->{microfiche}"></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+|;
+
+  }
+
+  if ($form->{id}) {
+    $obsolete = qq|
+             <tr>
+               <th align="right" nowrap="true">|.$locale->text('Obsolete').qq|</th>
+               <td><input name=obsolete type=checkbox class=checkbox value=1 $form->{obsolete}></td>
+             </tr>
+|;
+  }
+
+
+
+# type=submit $locale->text('Add Part')
+# type=submit $locale->text('Add Service')
+# type=submit $locale->text('Add Assembly')
+
+# type=submit $locale->text('Edit Part')
+# type=submit $locale->text('Edit Service')
+# type=submit $locale->text('Edit Assembly')
+
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input name=id type=hidden value=$form->{id}>
+<input name=item type=hidden value=$form->{item}>
+<input name=title type=hidden value="$form->{title}">
+<input name=makemodel type=hidden value="$form->{makemodel}">
+<input name=alternate type=hidden value="$form->{alternate}">
+<input name=onhand type=hidden value=$form->{onhand}>
+<input name=orphaned type=hidden value=$form->{orphaned}>
+<input name=taxaccounts type=hidden value="$form->{taxaccounts}">
+<input name=rowcount type=hidden value=$form->{rowcount}>
+
+<table width="100%">
+  <tr><th class=listtop>$form->{title}</th></tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table width="100%">
+        <tr valign=top>
+          <th align=left>|.$locale->text('Number').qq|</th>
+          <th align=left>|.$locale->text('Description').qq|</th>
+         <th align=left>|.$locale->text('Group').qq|</th>
+       </tr>
+       <tr valign=top>
+          <td><input name=partnumber value="$form->{partnumber}" size=20></td>
+          <td>$description</td>
+         <td><input name=partsgroup size=20 value="$form->{partsgroup}"></td>
+         <input type=hidden name=oldpartsgroup value="$form->{oldpartsgroup}">
+        </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table width="100%" height="100%">
+        <tr valign=top>
+          <td width=70%>
+            <table width="100%" height="100%">
+              <tr class="listheading">
+                <th class="listheading" align="center" colspan=2>|.$locale->text('Link Accounts').qq|</th>
+              </tr>
+              $linkaccounts
+              <tr>
+                <th align="left">|.$locale->text('Notes').qq|</th>
+              </tr>
+              <tr>
+                <td colspan=2>
+                  $notes
+                </td>
+              </tr>
+            </table>
+          </td>
+         <td width="30%">
+           <table width="100%">
+             <tr>
+               <th align="right" nowrap="true">|.$locale->text('Updated').qq|</th>
+               <td><input name=priceupdate size=11 title="$myconfig{dateformat}" value=$form->{priceupdate}></td>    
+             </tr>
+             <tr>
+               <th align="right" nowrap="true">|.$locale->text('List Price').qq|</th>
+               <td><input name=listprice size=11 value=$form->{listprice}></td>
+             </tr>
+             <tr>
+               <th align="right" nowrap="true">|.$locale->text('Sell Price').qq|</th>
+               <td><input name=sellprice size=11 value=$form->{sellprice}></td>
+             </tr>
+             $lastcost
+             <tr>
+               <th align="right" nowrap="true">|.$locale->text('Unit').qq|</th>
+               <td><input name=unit size=5 maxsize=5 value="$form->{unit}"></td>
+             </tr>
+             $weight
+             $rop
+             $bin
+             $obsolete
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  $imagelinks
+|;
+}
+
+
+sub form_footer {
+
+  if ($form->{item} eq "assembly") {
+
+    print qq|
+       <tr>
+         <td>
+            <table width="100%">
+              <tr>
+                <th colspan=2 align=right>|.$locale->text('Total').qq|&nbsp;</th>
+                <th width="1%" align=right>|.$form->format_amount(\%myconfig, $form->{assemblytotal}, 2).qq|</th>
+              </tr>
+            </table>
+          </td>
+        </tr>
+        <input type=hidden name=assembly_rows value=$form->{assembly_rows}>
+|;
+  }
+
+  print qq|
+      <input type=hidden name=path value=$form->{path}>
+      <input type=hidden name=login value=$form->{login}>
+      <input type=hidden name=password value=$form->{password}>
+      <input type=hidden name=callback value="$form->{callback}">
+      <input type=hidden name=previous_form value="$form->{previous_form}">
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+|;
+
+  if ($form->{item} ne "service") {
+    print qq|
+      <input type=hidden name=makemodel_rows value=$form->{makemodel_rows}>
+    |;
+  }
+
+  print qq|
+      <input class=submit type=submit name=action value="|.$locale->text('Save').qq|">|;
+
+  if ($form->{id}) {
+
+    if (! $form->{previous_form}) {
+      print qq|
+      <input class=submit type=submit name=action value="|.$locale->text('Save as new').qq|">|;
+    }
+    
+    if ($form->{orphaned}) {
+      if (! $form->{previous_form}) {
+       print qq|
+      <input class=submit type=submit name=action value="|.$locale->text('Delete').qq|">|;
+      }
+    }
+
+  }
+
+  print qq|
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+sub makemodel_row {
+  my ($numrows) = @_;
+
+  $form->{"make_$i"} =~ s/"/&quot;/g;
+  $form->{"model_$i"} =~ s/"/&quot;/g;
+
+  print qq|
+  <tr>
+    <td>
+      <table width=100%>
+       <tr>
+         <th class="listheading">|.$locale->text('Make').qq|</th>
+         <th class="listheading">|.$locale->text('Model').qq|</th>
+       </tr>
+|;
+
+  for $i (1 .. $numrows) {
+    print qq|
+       <tr>
+         <td width=50%><input name="make_$i" size=30 value="$form->{"make_$i"}"></td>
+         <td width=50%><input name="model_$i" size=30 value="$form->{"model_$i"}"></td>
+       </tr>
+|;
+  }
+
+  print qq|
+      </table>
+    </td>
+  </tr>
+|;
+
+}
+
+
+sub assembly_row {
+  my ($numrows) = @_;
+
+  @column_index = qw(runningnumber qty unit bom partnumber description partsgroup total);
+  
+  if ($form->{previous_form}) {
+    $nochange = 1;
+    @column_index = qw(qty unit bom partnumber description partsgroup total);
+  } else {
+    # change callback
+    $form->{old_callback} = $form->{callback};
+    $callback = $form->{callback};
+    $form->{callback} = "$form->{script}?action=display_form";
+
+    # delete action
+    delete $form->{action};
+
+    $previous_form = "";
+    # save form variables in a previous_form variable
+    foreach $key (sort keys %$form) {
+      # escape ampersands
+      $form->{$key} =~ s/&/%26/g;
+      $previous_form .= qq|$key=$form->{$key}&|;
+    }
+    chop $previous_form;
+    $previous_form = $form->escape($form->escape($previous_form, 1));
+    $form->{callback} = $callback;
+    
+    $form->{assemblytotal} = 0;
+    $form->{weight} = 0;
+
+  }
+
+  $column_header{runningnumber} = qq|<th nowrap width=5%>|.$locale->text('No.').qq|</th>|;
+  $column_header{qty} = qq|<th align=left nowrap width=10%>|.$locale->text('Qty').qq|</th>|;
+  $column_header{unit} = qq|<th align=left nowrap width=5%>|.$locale->text('Unit').qq|</th>|;
+  $column_header{partnumber} = qq|<th align=left nowrap width=20%>|.$locale->text('Number').qq|</th>|;
+  $column_header{description} = qq|<th nowrap width=50%>|.$locale->text('Description').qq|</th>|;
+  $column_header{total} = qq|<th align=right nowrap>|.$locale->text('Extended').qq|</th>|;
+  $column_header{bom} = qq|<th>|.$locale->text('BOM').qq|</th>|;
+  $column_header{partsgroup} = qq|<th>|.$locale->text('Group').qq|</th>|;
+  
+  print qq|
+  <tr class=listheading>
+    <th class=listheading>|.$locale->text('Individual Items').qq|</th>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+        <tr>
+|;
+
+  map { print "\n$column_header{$_}" } @column_index;
+  
+  print qq|
+        </tr>
+|;
+
+  for $i (1 .. $numrows) {
+    $form->{"partnumber_$i"} =~ s/"/&quot;/g;
+
+    $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
+    $form->{assemblytotal} += $linetotal;
+    
+    $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"});
+
+    $linetotal = $form->format_amount(\%myconfig, $linetotal, 2);
+
+    if (($i >= 1) && ($i == $numrows)) {
+
+      if ($nochange) {
+       map { $column_data{$_} = qq|<td></td>| } qw(qty unit partnumber description bom partsgroup);
+      } else {
+       
+       map { $column_data{$_} = qq|<td></td>| } qw(runningnumber unit bom);
+       
+       $column_data{qty} = qq|<td><input name="qty_$i" size=5 value="$form->{"qty_$i"}"></td>|;
+       $column_data{partnumber} = qq|<td><input name="partnumber_$i" size=15 value="$form->{"partnumber_$i"}"></td>|;
+       $column_data{description} = qq|<td><input name="description_$i" size=40 value="$form->{"description_$i"}"></td>|;
+       $column_data{partsgroup} = qq|<td><input name="partsgroup_$i" size=10 value="$form->{"partsgroup_$i"}"></td>|;
+       
+      }
+
+    } else {
+      
+      if ($form->{previous_form}) {
+       $column_data{partnumber} = qq|<td><input type=hidden name="partnumber_$i" value="$form->{"partnumber_$i"}">$form->{"partnumber_$i"}</td>|;
+       $column_data{qty} = qq|<td align=right><input type=hidden name="qty_$i" value="$form->{"qty_$i"}">$form->{"qty_$i"}</td>|;
+
+        $column_data{bom} = qq|<td align=center><input type=hidden name="bom_$i" value=$form->{"bom_$i"}>|;
+       $column_data{bom} .= ($form->{"bom_$i"}) ? "x" : "&nbsp;";
+       $column_data{bom} .= qq|</td>|;
+
+       $column_data{partsgroup} = qq|<td><input type=hidden name="partsgroup_$i" value="$form->{"partsgroup_$i"}">$form->{"partsgroup_$i"}</td>|;
+       
+      } else {
+       $href = qq|$form->{script}?action=edit&id=$form->{"id_$i"}&path=$form->{path}&login=$form->{login}&password=$form->{password}&rowcount=$i&previous_form=$previous_form|;
+       $column_data{partnumber} = qq|<td><input type=hidden name="partnumber_$i" value="$form->{"partnumber_$i"}"><a href=$href>$form->{"partnumber_$i"}</a></td>|;
+       $column_data{runningnumber} = qq|<td><input name="runningnumber_$i" size=3 value="$i"}"></td>|;
+       $column_data{qty} = qq|<td><input name="qty_$i" size=5 value="$form->{"qty_$i"}"></td>|;
+
+       $form->{"bom_$i"} = ($form->{"bom_$i"}) ? "checked" : "";
+       $column_data{bom} = qq|<td align=center><input name="bom_$i" type=checkbox class=checkbox value=1 $form->{"bom_$i"}></td>|;
+
+       $column_data{partsgroup} = qq|<td><input type=hidden name="partsgroup_$i" value="$form->{"partsgroup_$i"}">$form->{"partsgroup_$i"}</td>|;
+
+      }
+
+      $column_data{unit} = qq|<td><input type=hidden name="unit_$i" value="$form->{"unit_$i"}">$form->{"unit_$i"}</td>|;
+      $column_data{description} = qq|<td><input type=hidden name="description_$i" value="$form->{"description_$i"}">$form->{"description_$i"}</td>|;
+    }
+    
+    $column_data{total} = qq|<td align=right>$linetotal</td>|;
+    
+    print qq|
+        <tr>|;
+
+    map { print "\n$column_data{$_}" } @column_index;
+    
+    print qq|
+        </tr>
+  <input type=hidden name="id_$i" value=$form->{"id_$i"}>
+  <input type=hidden name="sellprice_$i" value=$form->{"sellprice_$i"}>
+  <input type=hidden name="weight_$i" value=$form->{"weight_$i"}>
+|;
+  }
+
+  print qq|
+      </table>
+    </td>
+  </tr>
+|;
+}
+
+
+sub update {
+
+  if ($form->{item} eq "assembly") {
+
+    $i = $form->{assembly_rows};
+    
+    # if last row is empty check the form otherwise retrieve item
+    if (($form->{"partnumber_$i"} eq "") && ($form->{"description_$i"} eq "") && ($form->{"partsgroup_$i"} eq "")) {
+      
+      &check_form;
+      
+    } else {
+
+      IC->assembly_item(\%myconfig, \%$form);
+
+      $rows = scalar @{ $form->{item_list} };
+      
+      if ($rows) {
+       $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
+       
+       if ($rows > 1) {
+         $form->{makemodel_rows}--;
+         &select_item;
+         exit;
+       } else {
+         map { $form->{item_list}[$i]{$_} =~ s/"/&quot;/g } qw(partnumber description unit partsgroup);
+         map { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } keys %{ $form->{item_list}[0] };
+         $form->{"runningnumber_$i"} = $form->{assembly_rows};
+         $form->{assembly_rows}++;
+
+         &check_form;
+
+       }
+
+      } else {
+
+        $form->{rowcount} = $i;
+       $form->{assembly_rows}++;
+       
+       &new_item;
+
+      }
+    }
+  }
+  
+  if ($form->{item} eq "part") {
+    &check_form;
+  }
+
+  if ($form->{item} eq 'service') {
+    map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(sellprice listprice);
+    
+    &form_header;
+    &form_footer;
+  }
+
+}
+
+
+sub save {
+
+  # check if there is a part number
+  $form->isblank("partnumber", $locale->text(ucfirst $form->{item}." Number missing!"));
+
+  if ($form->{obsolete}) {
+    $form->error($locale->text("Inventory quantity must be zero before you can set this $form->{item} obsolete!")) if ($form->{onhand});
+  }
+
+# expand dynamic strings
+# $locale->text('Inventory quantity must be zero before you can set this part obsolete!')
+# $locale->text('Inventory quantity must be zero before you can set this assembly obsolete!')
+# $locale->text('Part Number missing!')
+# $locale->text('Service Number missing!')
+# $locale->text('Assembly Number missing!')
+
+  # save part
+  $rc = IC->save(\%myconfig, \%$form);
+
+  $parts_id = $form->{id};
+  
+  # load previous variables
+  if ($form->{previous_form}) {
+    # save the new form variables before splitting previous_form
+    map { $newform{$_} = $form->{$_} } keys %$form;
+
+    $previous_form = $form->unescape($form->{previous_form});
+
+    # don't trample on previous variables
+    map { delete $form->{$_} } keys %newform;
+
+    # now take it apart and restore original values
+    foreach $item (split /&/, $previous_form) {
+      ($key, $value) = split /=/, $item, 2;
+      $value =~ s/%26/&/g;
+      $form->{$key} = $value;
+    }
+
+    if ($form->{item} eq 'assembly') {
+      # undo formatting
+      map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(listprice sellprice weight);
+
+      $form->{assembly_rows}--;
+      $i = $newform{rowcount};
+      $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
+
+      $form->{sellprice} -= $form->{"sellprice_$i"} * $form->{"qty_$i"};
+      $form->{weight} -= $form->{"weight_$i"} * $form->{"qty_$i"};
+      
+      # change/add values for assembly item
+      map { $form->{"${_}_$i"} = $newform{$_} } qw(partnumber description bin unit weight listprice sellprice inventory_accno income_accno expense_accno partsgroup);
+
+      # undo string formatting
+      map { $form->{"${_}_$i"} =~ s/''/'/g } qw(partnumber description unit bin);
+      
+      $form->{sellprice} += $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
+      $form->{weight} += $form->{"weight_$i"} * $form->{"qty_$i"};
+
+    } else {
+      # set values for last invoice/order item
+      $i = $form->{rowcount};
+      $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
+
+      map { $form->{"${_}_$i"} = $newform{$_} } qw(partnumber description bin unit listprice inventory_accno income_accno expense_accno sellprice);
+      $form->{"sellprice_$i"} = $newform{lastcost} if ($form->{vendor_id});
+
+      if ($form->{exchangerate} != 0) {
+       $form->{"sellprice_$i"} /= $form->{exchangerate};
+      }
+      
+      map { $form->{"taxaccounts_$i"} .= "$_ " if ($newform{"IC_tax_$_"}) } split / /, $newform{taxaccounts};
+      chop $form->{"taxaccounts_$i"};
+
+      # credit remaining calculation
+      $amount = $form->{"sellprice_$i"} * (1 - $form->{"discount_$i"} / 100) * $form->{"qty_$i"};
+      map { $form->{"${_}_base"} += $amount } (split / /, $form->{"taxaccounts_$i"});
+      map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{"taxaccounts_$i"} if !$form->{taxincluded};
+      
+      $form->{creditremaining} -= $amount;
+      
+    }
+    
+    $form->{"id_$i"} = $parts_id;
+    delete $form->{action};
+
+    # restore original callback
+    $callback = $form->unescape($form->{callback});
+    $form->{callback} = $form->unescape($form->{old_callback});
+    delete $form->{old_callback};
+
+    $form->{makemodel_rows}--;
+
+    # put callback together
+    foreach $key (keys %$form) {
+      # do single escape for Apache 2.0
+      $value = $form->escape($form->{$key}, 1);
+      $callback .= qq|&$key=$value|;
+    }
+    $form->{callback} = $callback;
+  }
+
+  # redirect
+  $form->redirect;
+
+}
+
+
+sub save_as_new {
+
+  $form->{id} = 0;
+  &save;
+
+}
+
+
+sub delete {
+
+  $rc = IC->delete(\%myconfig, \%$form);
+  
+  # redirect
+  $form->redirect($locale->text('Item deleted!')) if ($rc > 0);
+  $form->error($locale->text('Cannot delete item!'));
+
+}
+
+
+
+sub stock_assembly {
+
+  $form->{title} = $locale->text('Stock Assembly');
+  
+  $form->header;
+  
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width="100%">
+  <tr><th class=listtop>$form->{title}</th></tr>
+  <tr height="5"></tr>
+  <tr valign=top>
+    <td>
+      <table width="100%">
+        <tr>
+          <th width="1%" align="right" nowrap="true">|.$locale->text('Number').qq|</th>
+          <td width="40%"><input name=partnumber size=20></td>
+          <td>&nbsp;</td>
+        </tr>
+        <tr>
+          <th align="right" nowrap="true">|.$locale->text('Description').qq|</th>
+          <td colspan="2"><input name=description size=40></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+  <tr><td><hr size=3 noshade></td></tr>
+</table>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input type=hidden name=nextsub value=list_assemblies>
+
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+
+sub list_assemblies {
+
+  IC->retrieve_assemblies(\%myconfig, \%$form);
+
+  $column_header{partnumber} = qq|<th class=listheading>|.$locale->text('Number').qq|</th>|;
+  $column_header{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</th>|;
+  $column_header{bin} = qq|<th class=listheading>|.$locale->text('Bin').qq|</th>|;
+  $column_header{onhand} = qq|<th class=listheading>|.$locale->text('Qty').qq|</th>|;
+  $column_header{rop} = qq|<th class=listheading>|.$locale->text('ROP').qq|</th>|;
+  $column_header{stock} = qq|<th class=listheading>|.$locale->text('Add').qq|</th>|;
+
+  @column_index = (qw(partnumber description bin onhand rop stock));
+  
+  $form->{title} = $locale->text('Stock Assembly');
+
+  $form->{callback} = "$form->{script}?action=stock_assembly&path=$form->{path}&login=$form->{login}&password=$form->{password}";
+  
+  $form->header;
+  
+  $colspan = $#column_index + 1;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr><th class=listtop colspan=$colspan>$form->{title}</th></tr>
+  <tr size=5></tr>
+  <tr class=listheading>|;
+
+  map { print "\n$column_header{$_}" } @column_index;
+
+  print qq|
+  </tr>
+|;
+
+  $i = 1;
+  foreach $ref (@{ $form->{assembly_items} }) {
+
+    map { $ref->{$_} =~ s/"/&quot;/g } qw(partnumber description);
+   
+    # figure out how many to stock
+    $form->{"qty_$i"} = $form->format_amount(\%myconfig, $ref->{rop} - $ref->{onhand});
+
+    $column_data{partnumber} = qq|<td width=20%>$ref->{partnumber}</td>|;
+    $column_data{description} = qq|<td width=50%>$ref->{description}&nbsp;</td>|;
+    $column_data{bin} = qq|<td>$ref->{bin}&nbsp;</td>|;
+    $column_data{onhand} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{onhand}, '', "&nbsp;").qq|</td>|;
+    $column_data{rop} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{rop}, '', "&nbsp;").qq|</td>|;
+    $column_data{stock} = qq|<td width=10%><input name="qty_$i" size=10 value=$form->{"qty_$i"}></td>|;
+
+    $j++; $j %= 2;
+    print qq|<tr class=listrow$j><input name="id_$i" type=hidden value=$ref->{id}>\n|;
+    
+    map { print "\n$column_data{$_}" } @column_index;
+    
+    print qq|
+    </tr>
+|;
+
+    $i++;
+
+  }
+  
+  $i--;
+  print qq|
+  <tr>
+    <td colspan=6><hr size=3 noshade>
+  </tr>
+</table>
+<input name=rowcount type=hidden value="$i">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=nextsub value=restock_assemblies>
+
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+
+</form>
+
+</body>
+</html>
+|;
+}
+
+
+sub restock_assemblies {
+
+  $form->redirect($locale->text('Assemblies restocked!')) if (IC->restock_assemblies(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot stock assemblies!'));
+  
+}
+
+
+sub continue { &{ $form->{nextsub} } };
+
+
diff --git a/sql-ledger/bin/mozilla/io.pl b/sql-ledger/bin/mozilla/io.pl
new file mode 100644 (file)
index 0000000..751d9a2
--- /dev/null
@@ -0,0 +1,1149 @@
+######################################################################
+# SQL-Ledger, Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+#
+# common routines used in is, ir, oe
+#
+#######################################################################
+
+# any custom scripts for this one
+if (-f "$form->{path}/custom_io.pl") {
+  eval { require "$form->{path}/custom_io.pl"; };
+}
+if (-f "$form->{path}/$form->{login}_io.pl") {
+  eval { require "$form->{path}/$form->{login}_io.pl"; };
+}
+
+
+1;
+# end of main
+
+
+# this is for our long dates
+# $locale->text('January')
+# $locale->text('February')
+# $locale->text('March')
+# $locale->text('April')
+# $locale->text('May ')
+# $locale->text('June')
+# $locale->text('July')
+# $locale->text('August')
+# $locale->text('September')
+# $locale->text('October')
+# $locale->text('November')
+# $locale->text('December')
+
+# this is for our short month
+# $locale->text('Jan')
+# $locale->text('Feb')
+# $locale->text('Mar')
+# $locale->text('Apr')
+# $locale->text('May')
+# $locale->text('Jun')
+# $locale->text('Jul')
+# $locale->text('Aug')
+# $locale->text('Sep')
+# $locale->text('Oct')
+# $locale->text('Nov')
+# $locale->text('Dec')
+
+
+sub display_row {
+  my $numrows = shift;
+
+  @column_index = (partnumber, description, qty);
+  
+  if ($form->{type} eq "sales_order") {
+    if ($form->{id}) {
+      push @column_index, "ship";
+      $column_data{ship} = qq|<th class=listheading align=left width="auto">|.$locale->text('Ship').qq|</th>|;
+    }
+  }
+  if ($form->{type} eq "purchase_order") {
+    if ($form->{id}) {
+      push @column_index, "ship";
+      $column_data{ship} = qq|<th class=listheading align=left width="auto">|.$locale->text('Recd').qq|</th>|;
+    }
+  }
+  
+  push @column_index, qw(unit sellprice);
+  
+  if ($form->{script} eq 'is.pl' || $form->{type} eq 'sales_order') {
+    push @column_index, qw(discount);
+  }
+  
+  push @column_index, "linetotal";
+
+  my $colspan = $#column_index + 1;
+
+     
+  $form->{invsubtotal} = 0;
+  map { $form->{"${_}_base"} = 0 } (split / /, $form->{taxaccounts});
+  
+  $column_data{partnumber} = qq|<th class=listheading nowrap>|.$locale->text('Number').qq|</th>|;
+  $column_data{description} = qq|<th class=listheading nowrap>|.$locale->text('Description').qq|</th>|;
+  $column_data{qty} = qq|<th class=listheading nowrap>|.$locale->text('Qty').qq|</th>|;
+  $column_data{unit} = qq|<th class=listheading nowrap>|.$locale->text('Unit').qq|</th>|;
+  $column_data{sellprice} = qq|<th class=listheading nowrap>|.$locale->text('Price').qq|</th>|;
+  $column_data{discount} = qq|<th class=listheading>%</th>|;
+  $column_data{linetotal} = qq|<th class=listheading nowrap>|.$locale->text('Extended').qq|</th>|;
+  $column_data{bin} = qq|<th class=listheading nowrap>|.$locale->text('Bin').qq|</th>|;
+  
+  print qq|
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>|;
+
+  map { print "\n$column_data{$_}" } @column_index;
+
+  print qq|
+        </tr>
+|;
+
+
+  $projectnumber = $locale->text('Project');
+  $runningnumber = $locale->text('No.');
+  $partsgroup = $locale->text('Group');
+  
+  if ($form->{type} =~ /_order/) {
+    $reqdate = $locale->text('Required by');
+    $delvar = "reqdate";
+  } else {
+    $deliverydate = $locale->text('Delivery Date');
+    $delvar = "deliverydate";
+  }
+  
+  
+  for $i (1 .. $numrows) {
+    # undo formatting
+    map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(qty ship discount sellprice);
+
+    ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
+    $dec = length $dec;
+    $decimalplaces = ($dec > 2) ? $dec : 2;
+    
+    $discount = $form->round_amount($form->{"sellprice_$i"} * $form->{"discount_$i"}/100, $decimalplaces);
+    $linetotal = $form->round_amount($form->{"sellprice_$i"} - $discount, $decimalplaces);
+    $linetotal = $form->round_amount($linetotal * $form->{"qty_$i"}, 2);
+
+    # convert " to &quot;
+    map { $form->{"${_}_$i"} =~ s/"/&quot;/g } qw(partnumber description unit);
+    
+    $column_data{partnumber} = qq|<td><input name="partnumber_$i" size=20 value="$form->{"partnumber_$i"}"></td>|;
+
+    if (($rows = $form->numtextrows($form->{"description_$i"}, 30, 6)) > 1) {
+      $column_data{description} = qq|<td><textarea name="description_$i" rows=$rows cols=30 wrap=soft>$form->{"description_$i"}</textarea></td>|;
+    } else {
+      $column_data{description} = qq|<td><input name="description_$i" size=30 value="$form->{"description_$i"}"></td>|;
+    }
+
+    $column_data{qty} = qq|<td align=right><input name="qty_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"qty_$i"}).qq|></td>|;
+    $column_data{ship} = qq|<td align=right><input name="ship_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"ship_$i"}).qq|></td>|;
+    $column_data{unit} = qq|<td><input name="unit_$i" size=5 maxsize=5 value="$form->{"unit_$i"}"></td>|;
+    $column_data{sellprice} = qq|<td align=right><input name="sellprice_$i" size=9 value=|.$form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces).qq|></td>|;
+    $column_data{discount} = qq|<td align=right><input name="discount_$i" size=3 value=|.$form->format_amount(\%myconfig, $form->{"discount_$i"}).qq|></td>|;
+    $column_data{linetotal} = qq|<td align=right>|.$form->format_amount(\%myconfig, $linetotal, 2).qq|</td>|;
+    $column_data{bin} = qq|<td>$form->{"bin_$i"}</td>|;
+    
+    print qq|
+        <tr valign=top>|;
+
+    map { print "\n$column_data{$_}" } @column_index;
+  
+    print qq|
+        </tr>
+
+<input type=hidden name="id_$i" value=$form->{"id_$i"}>
+<input type=hidden name="inventory_accno_$i" value=$form->{"inventory_accno_$i"}>
+<input type=hidden name="bin_$i" value="$form->{"bin_$i"}">
+<input type=hidden name="income_accno_$i" value=$form->{"income_accno_$i"}>
+<input type=hidden name="expense_accno_$i" value=$form->{"expense_accno_$i"}>
+<input type=hidden name="listprice_$i" value="$form->{"listprice_$i"}">
+<input type=hidden name="assembly_$i" value="$form->{"assembly_$i"}">
+<input type=hidden name="taxaccounts_$i" value="$form->{"taxaccounts_$i"}">
+
+|;
+
+    # print second row
+    print qq|
+        <tr>
+         <td colspan=$colspan>
+           <table>
+             <tr>
+                <th>$runningnumber</th>
+               <td><input name="runningnumber_$i" size=3 value=$i></td>
+               <td width=20></td>
+               <th>$partsgroup</th>
+               <td><input name="partsgroup_$i" size=10 value="$form->{"partsgroup_$i"}">
+               <th>${$delvar}</th>
+               <td><input name="${delvar}_$i" size=11 title="$myconfig{dateformat}" value="$form->{"${delvar}_$i"}"></td>
+               <th>$projectnumber</th>
+               <td><input name="projectnumber_$i" size=10 value="$form->{"projectnumber_$i"}">
+                   <input type=hidden name="oldprojectnumber_$i" value="$form->{"oldprojectnumber_$i"}">
+                   <input type=hidden name="project_id_$i" value="$form->{"project_id_$i"}"></td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+       <tr>
+         <td colspan=$colspan><hr size=1 noshade></td>
+       </tr>
+|;
+  
+
+    map { $form->{"${_}_base"} += $linetotal } (split / /, $form->{"taxaccounts_$i"});
+  
+    $form->{invsubtotal} += $linetotal;
+  }
+
+  print qq|
+      </table>
+    </td>
+  </tr>
+|;
+
+}
+
+
+sub select_item {
+  
+  @column_index = qw(ndx partnumber description onhand sellprice);
+
+  $column_data{ndx} = qq|<th>&nbsp;</th>|;
+  $column_data{partnumber} = qq|<th class=listheading>|.$locale->text('Number').qq|</th>|;
+  $column_data{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</th>|;
+  $column_data{sellprice} = qq|<th class=listheading>|.$locale->text('Price').qq|</th>|;
+  $column_data{onhand} = qq|<th class=listheading>|.$locale->text('Qty').qq|</th>|;
+  
+  
+  # list items with radio button on a form
+  $form->header;
+
+  $title = $locale->text('Select from one of the items below');
+  $colspan = $#column_index + 1;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop colspan=$colspan>$title</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr class=listheading>|;
+
+  map { print "\n$column_data{$_}" } @column_index;
+  
+  print qq|</tr>|;
+
+  my $i = 0;
+  foreach $ref (@{ $form->{item_list} }) {
+    $checked = ($i++) ? "" : "checked";
+
+    map { $ref->{$_} =~ s/"/&quot;/g } qw(partnumber description unit);
+
+    $column_data{ndx} = qq|<td><input name=ndx class=radio type=radio value=$i $checked></td>|;
+    $column_data{partnumber} = qq|<td><input name="new_partnumber_$i" type=hidden value="$ref->{partnumber}">$ref->{partnumber}</td>|;
+    $column_data{description} = qq|<td><input name="new_description_$i" type=hidden value="$ref->{description}">$ref->{description}</td>|;
+    $column_data{sellprice} = qq|<td align=right><input name="new_sellprice_$i" type=hidden value=$ref->{sellprice}>|.$form->format_amount(\%myconfig, $ref->{sellprice}, 2, "&nbsp;").qq|</td>|;
+    $column_data{onhand} = qq|<td align=right><input name="new_onhand_$i" type=hidden value=$ref->{onhand}>|.$form->format_amount(\%myconfig, $ref->{onhand}, '', "&nbsp;").qq|</td>|;
+    
+    $j++; $j %= 2;
+    print qq|
+<tr class=listrow$j>|;
+
+    map { print "\n$column_data{$_}" } @column_index;
+
+    print qq|
+</tr>
+
+<input name="new_bin_$i" type=hidden value="$ref->{bin}">
+<input name="new_listprice_$i" type=hidden value=$ref->{listprice}>
+<input name="new_inventory_accno_$i" type=hidden value=$ref->{inventory_accno}>
+<input name="new_income_accno_$i" type=hidden value=$ref->{income_accno}>
+<input name="new_expense_accno_$i" type=hidden value=$ref->{expense_accno}>
+<input name="new_unit_$i" type=hidden value="$ref->{unit}">
+<input name="new_weight_$i" type=hidden value="$ref->{weight}">
+<input name="new_assembly_$i" type=hidden value="$ref->{assembly}">
+<input name="new_taxaccounts_$i" type=hidden value="$ref->{taxaccounts}">
+<input name="new_partsgroup_$i" type=hidden value="$ref->{partsgroup}">
+
+<input name="new_id_$i" type=hidden value=$ref->{id}>
+
+|;
+
+  }
+  
+  print qq|
+<tr><td colspan=8><hr size=3 noshade></td></tr>
+</table>
+
+<input name=lastndx type=hidden value=$i>
+
+|;
+
+  # delete action variable
+  delete $form->{action};
+  delete $form->{item_list};
+    
+  # save all other form variables
+  foreach $key (keys %${form}) {
+    $form->{$key} =~ s/"/&quot;/g;
+    print qq|<input name=$key type=hidden value="$form->{$key}">\n|;
+  }
+
+  print qq|
+<input type=hidden name=nextsub value=item_selected>
+
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+sub item_selected {
+
+  # replace the last row with the checked row
+  $i = $form->{rowcount};
+  $i = $form->{assembly_rows} if ($form->{item} eq 'assembly');
+
+  # index for new item
+  $j = $form->{ndx};
+
+  # if there was a price entered, override it
+  $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
+  
+  map { $form->{"${_}_$i"} = $form->{"new_${_}_$j"} } qw(id partnumber description sellprice listprice inventory_accno income_accno expense_accno bin unit weight assembly taxaccounts partsgroup);
+
+  ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
+  $dec = length $dec;
+  $decimalplaces = ($dec > 2) ? $dec : 2;
+
+  if ($sellprice) {
+    $form->{"sellprice_$i"} = $sellprice;
+  } else {
+    # if there is an exchange rate adjust sellprice
+    if (($form->{exchangerate} * 1) != 0) {
+      $form->{"sellprice_$i"} /= $form->{exchangerate};
+      $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"}, $decimalplaces);
+    }
+  }
+
+  map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(sellprice weight);
+
+  $form->{sellprice} += ($form->{"sellprice_$i"} * $form->{"qty_$i"});
+  $form->{weight} += ($form->{"weight_$i"} * $form->{"qty_$i"});
+
+  $amount = $form->{"sellprice_$i"} * (1 - $form->{"discount_$i"} / 100) * $form->{"qty_$i"};
+  map { $form->{"${_}_base"} += $amount } (split / /, $form->{"taxaccounts_$i"});
+  map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{"taxaccounts_$i"} if !$form->{taxincluded};
+
+  $form->{creditremaining} -= $amount;
+
+  $form->{"runningnumber_$i"} = $i;
+  
+  # delete all the new_ variables
+  for $i (1 .. $form->{lastndx}) {
+    map { delete $form->{"new_${_}_$i"} } qw(partnumber description sellprice bin listprice inventory_accno income_accno expense_accno unit assembly taxaccounts id);
+  }
+  
+  map { delete $form->{$_} } qw(ndx lastndx nextsub);
+
+  if ($form->{item} eq 'assembly') {
+    map { $form->{"qty_$_"} = $form->parse_amount(\%myconfig, $form->{"qty_$_"}) } (1 .. $i);
+  } else {
+    # format amounts for invoice / order
+    map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces) } qw(sellprice listprice);
+  }
+
+  &display_form;
+  
+}
+
+
+sub new_item {
+
+  # change callback
+  $form->{old_callback} = $form->escape($form->{callback},1);
+  $form->{callback} = $form->escape("$form->{script}?action=display_form",1);
+
+  # delete action
+  delete $form->{action};
+
+  # save all other form variables in a previous_form variable
+  foreach $key (keys %$form) {
+    # escape ampersands
+    $form->{$key} =~ s/&/%26/g;
+    $previous_form .= qq|$key=$form->{$key}&|;
+  }
+  chop $previous_form;
+  $previous_form = $form->escape($previous_form, 1);
+
+  $i = $form->{rowcount};
+  map { $form->{"${_}_$i"} =~ s/"/&quot;/g } qw(partnumber description);
+
+  $form->header;
+
+  print qq|
+<body>
+
+<h4 class=error>|.$locale->text('Item not on file!').qq|
+
+<p>
+|.$locale->text('What type of item is this?').qq|</h4>
+
+<form method=post action=ic.pl>
+
+<p>
+
+  <input class=radio type=radio name=item value=part checked>&nbsp;|.$locale->text('Part')
+.qq|<br>
+  <input class=radio type=radio name=item value=service>&nbsp;|.$locale->text('Service')
+
+.qq|
+<input type=hidden name=previous_form value="$previous_form">
+<input type=hidden name=partnumber value="$form->{"partnumber_$i"}">
+<input type=hidden name=description value="$form->{"description_$i"}">
+<input type=hidden name=rowcount value=$form->{rowcount}>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input type=hidden name=nextsub value=add>
+
+<p>
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+sub display_form {
+
+  &form_header;
+
+  $numrows = ++$form->{rowcount};
+  $subroutine = "display_row";
+
+  if ($form->{item} eq 'part') {
+    $numrows = ++$form->{makemodel_rows};
+    $subroutine = "makemodel_row";
+  }
+  if ($form->{item} eq 'assembly') {
+    $numrows = ++$form->{makemodel_rows};
+    $subroutine = "makemodel_row";
+  
+    # create makemodel rows
+    &{ $subroutine }($numrows);
+
+    $numrows = ++$form->{assembly_rows};
+    $subroutine = "assembly_row";
+  }
+  if ($form->{item} eq 'service') {
+    $numrows = 0;
+  }
+
+  # create rows
+  &{ $subroutine }($numrows) if $numrows;
+
+  &form_footer;
+
+}
+
+
+
+sub check_form {
+  
+  my @a = ();
+  my $count = 0;
+  my @flds = (qw(id partnumber description qty sellprice unit discount inventory_accno income_accno expense_accno listprice taxaccounts bin assembly weight projectnumber project_id oldprojectnumber runningnumber partsgroup));
+
+  # remove any makes or model rows
+  if ($form->{item} eq 'part') {
+    map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(listprice sellprice lastcost weight rop);
+    
+    @flds = (make, model);
+    for my $i (1 .. ($form->{makemodel_rows})) {
+      if (($form->{"make_$i"} ne "") || ($form->{"model_$i"} ne "")) {
+       push @a, {};
+       my $j = $#a;
+
+       map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
+       $count++;
+      }
+    }
+
+    $form->redo_rows(\@flds, \@a, $count, $form->{makemodel_rows});
+    $form->{makemodel_rows} = $count;
+
+  } elsif ($form->{item} eq 'assembly') {
+    
+    $form->{sellprice} = 0;
+    $form->{weight} = 0;
+    map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(listprice rop);
+
+    @flds = qw(id qty unit bom partnumber description sellprice weight runningnumber partsgroup);
+    
+    for my $i (1 .. ($form->{assembly_rows} - 1)) {
+      if ($form->{"qty_$i"}) {
+       push @a, {};
+       my $j = $#a;
+
+        $form->{"qty_$i"} = $form->parse_amount(\%myconfig, $form->{"qty_$i"});
+
+       map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
+
+       $form->{sellprice} += ($form->{"qty_$i"} * $form->{"sellprice_$i"});
+       $form->{weight} += ($form->{"qty_$i"} * $form->{"weight_$i"});
+       $count++;
+      }
+    }
+
+    $form->{sellprice} = $form->round_amount($form->{sellprice}, 2);
+    
+    $form->redo_rows(\@flds, \@a, $count, $form->{assembly_rows});
+    $form->{assembly_rows} = $count;
+    
+    $count = 0;
+    @flds = qw(make model);
+    @a = ();
+    
+    for my $i (1 .. ($form->{makemodel_rows})) {
+      if (($form->{"make_$i"} ne "") || ($form->{"model_$i"} ne "")) {
+       push @a, {};
+       my $j = $#a;
+
+       map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
+       $count++;
+      }
+    }
+
+    $form->redo_rows(\@flds, \@a, $count, $form->{makemodel_rows});
+    $form->{makemodel_rows} = $count;
+
+  } else {
+
+    # this section applies to invoices and orders
+    # remove any empty numbers
+    
+    if ($form->{rowcount}) {
+      for my $i (1 .. $form->{rowcount} - 1) {
+       if ($form->{"partnumber_$i"}) {
+         push @a, {};
+         my $j = $#a;
+
+         map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
+         $count++;
+       }
+      }
+      
+      $form->redo_rows(\@flds, \@a, $count, $form->{rowcount});
+      $form->{rowcount} = $count;
+
+      $form->{creditremaining} -= &invoicetotal;
+      
+    }
+  }
+
+  &display_form;
+
+}
+
+
+sub invoicetotal {
+
+  $form->{oldinvtotal} = 0;
+  # add all parts and deduct paid
+  map { $form->{"${_}_base"} = 0 } split / /, $form->{taxaccounts};
+
+  my ($amount, $sellprice, $discount, $qty);
+  
+  for my $i (1 .. $form->{rowcount}) {
+    $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
+    $discount = $form->parse_amount(\%myconfig, $form->{"discount_$i"});
+    $qty = $form->parse_amount(\%myconfig, $form->{"qty_$i"});
+
+    $amount = $sellprice * (1 - $discount / 100) * $qty;
+    map { $form->{"${_}_base"} += $amount } (split / /, $form->{"taxaccounts_$i"});
+    $form->{oldinvtotal} += $amount;
+  }
+
+  map { $form->{oldinvtotal} += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{taxaccounts} if !$form->{taxincluded};
+  
+  $form->{oldtotalpaid} = 0;
+  for $i (1 .. $form->{paidaccounts}) {
+    $form->{oldtotalpaid} += $form->{"paid_$i"};
+  }
+  
+  # return total
+  ($form->{oldinvtotal} - $form->{oldtotalpaid});
+
+}
+
+
+sub validate_items {
+  
+  # check if items are valid
+  if ($form->{rowcount} == 1) {
+    &update;
+    exit;
+  }
+    
+  for $i (1 .. $form->{rowcount} - 1) {
+    $form->isblank("partnumber_$i", $locale->text('Number missing in Row') . " $i");
+  }
+
+}
+
+
+sub order {
+
+  $form->{ordnumber} = $form->{invnumber};
+
+  $form->{id} = '';
+
+  if ($form->{script} eq 'ir.pl') {
+    $form->{title} = $locale->text('Add Purchase Order');
+    $form->{vc} = 'vendor';
+    $form->{type} = 'purchase_order';
+    $buysell = 'sell';
+  }
+  if ($form->{script} eq 'is.pl') {
+    $form->{title} = $locale->text('Add Sales Order');
+    $form->{vc} = 'customer';
+    $form->{type} = 'sales_order';
+    $buysell = 'buy';
+  }
+  $form->{script} = 'oe.pl';
+
+  $form->{shipto} = 1;
+  
+  $form->{rowcount}--;
+
+  require "$form->{path}/$form->{script}";
+
+  map { $form->{"select$_"} = "" } ($form->{vc}, currency);
+  
+  $currency = $form->{currency};
+  
+  &order_links;
+
+  $form->{currency} = $currency;
+  $form->{exchangerate} = "";
+  $form->{forex} = "";
+  $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{orddate}, $buysell))); 
+  
+  &prepare_order;
+  &display_form;
+
+}
+
+
+sub e_mail {
+
+
+  if ($myconfig{admin}) {
+    $bcc = qq|
+         <th align=right nowrap=true>|.$locale->text('Bcc').qq|</th>
+         <td><input name=bcc size=30 value="$form->{bcc}"></td>
+|;
+  }
+
+  if ($form->{type} eq 'packing_list') {
+    $form->{email} = $form->{shiptoemail} if $form->{shiptoemail};
+  }
+
+  $name = $form->{$form->{vc}};
+  $name =~ s/--.*//g;
+  $title = $locale->text('E-mail')." $name";
+  
+  $form->{oldmedia} = $form->{media};
+  $form->{media} = "email";
+  
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr class=listtop>
+    <th class=listtop>$title</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr>
+         <th align=right nowrap>|.$locale->text('To').qq|</th>
+         <td><input name=email size=30 value="$form->{email}"></td>
+         <th align=right nowrap>|.$locale->text('Cc').qq|</th>
+         <td><input name=cc size=30 value="$form->{cc}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Subject').qq|</th>
+         <td><input name=subject size=30 value="$form->{subject}"></td>
+         $bcc
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr>
+         <th align=left nowrap>|.$locale->text('Message').qq|</th>
+       </tr>
+       <tr>
+         <td><textarea name=message rows=15 cols=60 wrap=soft>$form->{message}</textarea></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+|;
+
+  &print_options;
+  
+  map { delete $form->{$_} } qw(action email cc bcc subject message type sendmode format);
+  
+  # save all other variables
+  foreach $key (keys %$form) {
+    $form->{$key} =~ s/"/&quot;/g;
+    print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
+  }
+
+  print qq|
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<input type=hidden name=nextsub value=send_email>
+
+<br>
+<input name=action class=submit type=submit value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub send_email {
+
+  $old_form = new Form;
+  map { $old_form->{$_} = $form->{$_} } keys %$form;
+  $old_form->{media} = $form->{oldmedia};
+  &print_form($old_form);
+  
+}
+  
+
+sub print_options {
+
+  $form->{sendmode} = "attachment";
+  $form->{copies} = 3 unless $form->{copies};
+  
+  $form->{PD}{$form->{type}} = "checked";
+  $form->{DF}{$form->{format}} = "checked";
+  $form->{OP}{$form->{media}} = "checked";
+  $form->{SM}{$form->{sendmode}} = "checked";
+  
+  if ($form->{type} =~ /_order/) {
+    $order = qq|
+         <td align=right><input class=radio type=radio name=type value="$`_order" $form->{PD}{"$`_order"}></td><td>|.$locale->text('Order').qq|</td>
+|;
+  } else {
+    $invoice = qq|
+         <td align=right><input class=radio type=radio name=type value=invoice $form->{PD}{invoice}></td><td>|.$locale->text('Invoice').qq|</td>
+         <td align=right><input class=radio type=radio name=type value=packing_list $form->{PD}{packing_list}></td><td>|.$locale->text('Packing List').qq|</td>
+|;
+  }
+
+  if ($form->{media} eq 'email') {
+    $email = qq|
+       <td align=center><input class=radio type=radio name=sendmode value=attachment $form->{SM}{attachment}> |.$locale->text('Attachment')
+       .qq| <input class=radio type=radio name=sendmode value=inline $form->{SM}{inline}> |.$locale->text('In-line').qq|</td>
+|;
+  } else {
+    $screen = qq|
+       <td align=right><input class=radio type=radio name=media value=screen $form->{OP}{screen}></td>
+       <td>|.$locale->text('Screen').qq|</td>
+|;
+  }
+
+  print qq|
+<table width=100%>
+  <tr valign=top>
+    $invoice
+    $order
+    <td align=right><input class=radio type=radio name=format value=html $form->{DF}{html}></td>
+    <td>html</td>
+|;
+
+  if ($latex) {
+      print qq|
+    <td align=right><input class=radio type=radio name=format value=postscript $form->{DF}{postscript}></td>
+    <td>|.$locale->text('Postscript').qq|</td>
+    <td align=right><input class=radio type=radio name=format value=pdf $form->{DF}{pdf}></td>
+    <td>|.$locale->text('PDF').qq|</td>
+|;
+  }
+
+  print qq|
+    $screen
+|;
+
+  if ($screen) {
+    if ($myconfig{printer} && $latex) {
+      print qq|
+    <td align=right><input class=radio type=radio name=media value=printer $form->{OP}{printer}></td>
+    <td>|.$locale->text('Printer')
+    .qq| (|.$locale->text('Copies')
+    .qq| <input name=copies size=2 value=$form->{copies}>)</td>
+|;
+    }
+  }
+
+  
+  $form->{groupitems} = "checked" if $form->{groupitems};
+  
+  print qq|
+    $email
+    <td align=right><input name=groupitems type=checkbox class=checkbox $form->{groupitems}></td>
+    <td>|.$locale->text('Group Items').qq|</td>
+  </tr>
+</table>
+|;
+
+}
+
+
+sub print {
+  
+  # if this goes to the printer pass through
+  if ($form->{media} eq 'printer') {
+    $form->error($locale->text('Select postscript or PDF!')) if ($form->{format} !~ /(postscript|pdf)/);
+
+    $old_form = new Form;
+    map { $old_form->{$_} = $form->{$_} } keys %$form;
+  }
+
+  &print_form($old_form);
+
+}
+
+
+sub print_form {
+  my $old_form = shift;
+  
+  $inv = "inv";
+  $due = "due";
+
+  if ($form->{type} eq "invoice") {
+    $form->{label} = $locale->text('Invoice');
+  }
+  if ($form->{type} eq "packing_list") {
+    $form->{label} = $locale->text('Packing List');
+  }
+  if ($form->{type} eq 'sales_order') {
+    $inv = "ord";
+    $due = "req";
+    $form->{label} = $locale->text('Sales Order');
+  }
+  if ($form->{type} eq 'purchase_order') {
+    $inv = "ord";
+    $due = "req";
+    $form->{label} = $locale->text('Purchase Order');
+  }
+
+  $form->isblank("email", $locale->text('E-mail address missing!')) if ($form->{media} eq 'email');
+  $form->isblank("${inv}number", $locale->text($form->{label} .' Number missing!'));
+  $form->isblank("${inv}date", $locale->text($form->{label} .' Date missing!'));
+
+# $locale->text('Invoice Number missing!')
+# $locale->text('Invoice Date missing!')
+# $locale->text('Packing List Number missing!')
+# $locale->text('Packing List Date missing!')
+# $locale->text('Order Number missing!')
+# $locale->text('Order Date missing!')
+
+  &validate_items;
+
+  &{ "$form->{vc}_details" };
+
+  @a = ();
+  map { push @a, ("partnumber_$_", "description_$_") } (1 .. $form->{rowcount});
+  map { push @a, "${_}_description" } split / /, $form->{taxaccounts};
+  $form->format_string(@a);
+
+  # format payment dates
+  map { $form->{"datepaid_$_"} = $locale->date(\%myconfig, $form->{"datepaid_$_"}) } (1 .. $form->{paidaccounts});
+  
+  # create the form variables for the invoice, packing list or order
+  if ($form->{type} =~ /order$/) {
+    OE->order_details(\%myconfig, \%$form);
+  } else {
+    IS->invoice_details(\%myconfig, \%$form);
+  }
+
+  $form->{"${inv}date"} = $locale->date(\%myconfig, $form->{"${inv}date"}, 1);
+  $form->{"${due}date"} = $locale->date(\%myconfig, $form->{"${due}date"}, 1);
+  
+  
+  @a = qw(name addr1 addr2 addr3 addr4);
+  $fillshipto = 1;
+  # if there is no shipto fill it in from billto
+  foreach $item (@a) {
+    if ($form->{"shipto$item"}) {
+      $fillshipto = 0;
+      last;
+    }
+  }
+
+  if ($fillshipto) {
+    if ($form->{type} eq 'purchase_order') {
+       $form->{shiptoname} = $myconfig{company};
+       $form->{shiptoaddr1} = $myconfig{address};
+    } else {
+      map { $form->{"shipto$_"} = $form->{$_} } @a;
+    }
+  }
+
+  $form->{notes} =~ s/^\s+//g;
+
+  # some of the stuff could have umlauts so we translate them
+  push @a, qw(shiptoname shiptoaddr1 shiptoaddr2 shiptoaddr3 shiptoaddr4 shippingpoint company address signature notes);
+
+  push @a, ("${inv}date", "${due}date");
+  
+  $form->format_string(@a);
+
+
+  $form->{templates} = "$myconfig{templates}";
+  $form->{IN} = "$form->{type}.html";
+
+  if ($form->{format} eq 'postscript') {
+    $form->{postscript} = 1;
+    $form->{IN} =~ s/html$/tex/;
+  }
+  if ($form->{format} eq 'pdf') {
+    $form->{pdf} = 1;
+    $form->{IN} =~ s/html$/tex/;
+  }
+
+  $form->format_string(email, shiptoemail, cc, bcc) if $form->{format} =~ /(pdf|postscript)/;
+  
+  if ($form->{media} eq 'printer') {
+    $form->{OUT} = "| $myconfig{printer}";
+  }
+
+  if ($form->{media} eq 'email') {
+    $form->{subject} = qq|$form->{label} $form->{"${inv}number"}| unless $form->{subject};
+    
+    $form->{OUT} = "$sendmail";
+  }
+  
+
+  $form->parse_template(\%myconfig, $userspath);
+
+  $form->{callback} = "";
+  
+  # if we got back here restore the previous form
+  if ($form->{media} =~ /(printer|email)/) {
+    if ($old_form) {
+      # restore and display form
+      map { $form->{$_} = $old_form->{$_} } keys %$old_form;
+      $form->{rowcount}--;
+      map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate creditlimit creditremaining);
+
+      for $i (1 .. $form->{paidaccounts}) {
+       map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(paid exchangerate);
+      }
+      
+      &display_form;
+      exit;
+    }
+
+    $msg = ($form->{media} eq 'printer') ? $locale->text('sent to printer') : $locale->text('emailed to')." $form->{email}";
+    $form->redirect(qq|$form->{label} $form->{"${inv}number"} $msg|);
+  }
+
+}
+
+
+sub customer_details {
+
+  IS->customer_details(\%myconfig, \%$form);
+
+}
+
+
+sub vendor_details {
+
+  IR->vendor_details(\%myconfig, \%$form);
+
+}
+
+
+sub post_as_new {
+
+  $form->{postasnew} = 1;
+  &post;
+
+}
+
+
+sub ship_to {
+
+  $title = $form->{title};
+  $form->{title} = $locale->text('Ship to');
+  
+  $form->{rowcount}--;
+
+  map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate creditlimit creditremaining);
+
+  # get details for name
+  &{ "$form->{vc}_details" };
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr>
+    <td>
+      <table>
+       <tr class=listheading>
+         <th class=listheading colspan=2 width=50%>|.$locale->text('To').qq|</th>
+         <th class=listheading width=50%>|.$locale->text('Ship to').qq|</th>
+       </tr>
+       <tr height="5"></tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Number').qq|</th>
+         <td>$form->{"$form->{vc}number"}</td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Name').qq|</th>
+         <td>$form->{name}</td>
+         <td><input name=shiptoname size=35 maxsize=35 value="$form->{shiptoname}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Address').qq|</th>
+         <td>$form->{addr1}</td>
+         <td><input name=shiptoaddr1 size=35 maxsize=35 value="$form->{shiptoaddr1}"></td>
+       </tr>
+       <tr>
+         <th></th>
+         <td>$form->{addr2}</td>
+         <td><input name=shiptoaddr2 size=35 maxsize=35 value="$form->{shiptoaddr2}"></td>
+       </tr>
+       <tr>
+         <th></th>
+         <td>$form->{addr3}</td>
+         <td><input name=shiptoaddr3 size=35 maxsize=35 value="$form->{shiptoaddr3}"></td>
+       </tr>
+       <tr>
+         <th></th>
+         <td>$form->{addr4}</td>
+         <td><input name=shiptoaddr4 size=35 maxsize=35 value="$form->{shiptoaddr4}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Contact').qq|</th>
+         <td>$form->{contact}</td>
+         <td><input name=shiptocontact size=35 maxsize=35 value="$form->{shiptocontact}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Phone').qq|</th>
+         <td>$form->{"$form->{vc}phone"}</td>
+         <td><input name=shiptophone size=20 maxsize=20 value="$form->{shiptophone}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Fax').qq|</th>
+         <td>$form->{"$form->{vc}fax"}</td>
+         <td><input name=shiptofax size=20 maxsize=20 value="$form->{shiptofax}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('E-mail').qq|</th>
+         <td>$form->{email}</td>
+         <td><input name=shiptoemail size=35 value="$form->{shiptoemail}"></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+|;
+
+  # delete shipto
+  map { delete $form->{$_} } qw(shiptoname shiptoaddr1 shiptoaddr2 shiptoaddr3 shiptoaddr4 shiptocontact shiptophone shiptofax shiptoemail);
+  $form->{title} = $title;
+  
+  foreach $key (keys %$form) {
+    $form->{$key} =~ s/"/&quot;/g;
+    print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
+  }
+
+  print qq|
+
+<input type=hidden name=nextsub value=display_form>
+
+<hr size=3 noshade>
+
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
diff --git a/sql-ledger/bin/mozilla/ir.pl b/sql-ledger/bin/mozilla/ir.pl
new file mode 100644 (file)
index 0000000..ec7d18c
--- /dev/null
@@ -0,0 +1,653 @@
+#=====================================================================
+# SQL-Ledger, Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Inventory received module
+#
+#======================================================================
+
+
+use SL::IR;
+use SL::PE;
+
+require "$form->{path}/io.pl";
+require "$form->{path}/arap.pl";
+
+1;
+# end of main
+
+
+
+sub add {
+
+  $form->{title} = $locale->text('Add Vendor Invoice');
+
+  &invoice_links;
+  &prepare_invoice;
+  &display_form;
+  
+}
+
+
+sub edit {
+
+  $form->{title} = $locale->text('Edit Vendor Invoice');
+
+  &invoice_links;
+  &prepare_invoice;
+  &display_form;
+  
+}
+
+
+sub invoice_links {
+
+  # create links
+  $form->create_links("AP", \%myconfig, "vendor");
+
+  IR->get_vendor(\%myconfig, \%$form);
+  IR->retrieve_invoice(\%myconfig, \%$form);
+
+  # currencies
+  @curr = split /:/, $form->{currencies};
+  chomp $curr[0];
+  $form->{defaultcurrency} = $curr[0];
+
+  map { $form->{selectcurrency} .= "<option>$_\n" } @curr;
+
+  $form->{oldvendor} = "$form->{vendor}--$form->{vendor_id}";
+
+  # vendors
+  if (@{ $form->{all_vendor} }) {
+    $form->{vendor} = "$form->{vendor}--$form->{vendor_id}";
+    map { $form->{selectvendor} .= "<option>$_->{name}--$_->{id}\n" } (@{ $form->{all_vendor} });
+  }
+
+  
+  # forex
+  $form->{forex} = $form->{exchangerate};
+  $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1;
+  
+  foreach $key (keys %{ $form->{AP_links} }) {
+
+    foreach $ref (@{ $form->{AP_links}{$key} }) {
+      $form->{"select$key"} .= "<option>$ref->{accno}--$ref->{description}\n";
+    }
+
+    if ($key eq "AP_paid") {
+      for $i (1 .. scalar @{ $form->{acc_trans}{$key} }) {
+       $form->{"AP_paid_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
+       # reverse paid
+       $form->{"paid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{amount};
+       $form->{"datepaid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{transdate};
+       $form->{"forex_$i"} = $form->{"exchangerate_$i"} = $form->{acc_trans}{$key}->[$i-1]->{exchangerate};
+       $form->{"source_$i"} = $form->{acc_trans}{$key}->[$i-1]->{source};
+       $form->{paidaccounts} = $i;
+      }
+    } else {
+      $form->{$key} = "$form->{acc_trans}{$key}->[0]->{accno}--$form->{acc_trans}{$key}->[0]->{description}";
+    }
+  }
+
+  $form->{paidaccounts} = 1 unless (exists $form->{paidaccounts});
+
+  $form->{AP} = $form->{AP_1} unless $form->{id};
+
+  $form->{locked} = ($form->datetonum($form->{invdate}, \%myconfig) <= $form->datetonum($form->{closedto}, \%myconfig));
+  
+}
+
+
+
+sub prepare_invoice {
+
+  if ($form->{id}) {
+        
+    map { $form->{$_} =~ s/"/&quot;/g } qw(invnumber ordnumber);
+
+    foreach $ref (@{ $form->{invoice_details} }) {
+      $i++;
+      map { $form->{"${_}_$i"} = $ref->{$_} } keys %{ $ref };
+      
+      ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
+      $dec = length $dec;
+      $decimalplaces = ($dec > 2) ? $dec : 2;
+      
+      $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
+      $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"});
+
+      $form->{rowcount} = $i;
+    }
+  }
+  
+}
+
+
+
+sub form_header {
+
+  # set option selected
+  foreach $item (qw(AP vendor currency)) {
+    $form->{"select$item"} =~ s/ selected//;
+    $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
+  }
+  
+  $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate});
+
+  $exchangerate = "";
+  if ($form->{currency} ne $form->{defaultcurrency}) {
+    if ($form->{forex}) {
+      $exchangerate .= qq|
+      <th align=right nowrap>|.$locale->text('Exchangerate').qq|</th>
+      <td>$form->{exchangerate}<input type=hidden name=exchangerate value=$form->{exchangerate}></td>
+|;
+    } else {
+      $exchangerate .= qq|
+      <th align=right nowrap>|.$locale->text('Exchangerate').qq|</th>
+      <td><input name=exchangerate size=10 value=$form->{exchangerate}></td>
+|;
+    }
+  }
+  $exchangerate .= qq|
+<input type=hidden name=forex value=$form->{forex}>
+|;
+  
+  $vendor = ($form->{selectvendor}) ? qq|<select name=vendor>$form->{selectvendor}</select>\n<input type=hidden name="selectvendor" value="$form->{selectvendor}">| : qq|<input name=vendor value="$form->{vendor}" size=35>|;
+  
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=id value=$form->{id}>
+<input type=hidden name=title value="$form->{title}">
+<input type=hidden name=vc value="vendor">
+
+<input type=hidden name=closedto value=$form->{closedto}>
+<input type=hidden name=locked value=$form->{locked}>
+
+
+<table width=100%>
+  <tr class=listtop>
+    <th>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table width=100%>
+        <tr valign=top>
+         <td>
+           <table>
+             <tr>
+               <th align=right>|.$locale->text('Record in').qq|</th>
+               <td colspan=3><select name=AP>$form->{selectAP}</select></td>
+               <input type=hidden name=selectAP value="$form->{selectAP}">
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Vendor').qq|</th>
+               <td colspan=3>$vendor</td>
+               
+               <input type=hidden name=vendor_id value=$form->{vendor_id}>
+               <input type=hidden name=oldvendor value="$form->{oldvendor}">
+
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Currency').qq|</th>
+               <td><select name=currency>$form->{selectcurrency}</select></td>
+               $exchangerate
+             </tr>
+           </table>
+         </td>
+         <td align=right>
+           <table>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th>
+               <td><input name=invnumber size=11 value="$form->{invnumber}"></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Invoice Date').qq|</th>
+               <td><input name=invdate size=11 title="$myconfig{dateformat}" value=$form->{invdate}></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Due Date').qq|</th>
+               <td><input name=duedate size=11 title="$myconfig{dateformat}" value=$form->{duedate}></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Order Number').qq|</th>
+               <td><input name=ordnumber size=11 value="$form->{ordnumber}"></td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+<input type=hidden name=selectcurrency value="$form->{selectcurrency}">
+<input type=hidden name=defaultcurrency value=$form->{defaultcurrency}>
+<input type=hidden name=fxgain_accno value=$form->{fxgain_accno}>
+<input type=hidden name=fxloss_accno value=$form->{fxloss_accno}>
+
+<input type=hidden name=taxpart value="$form->{taxpart}">
+<input type=hidden name=taxservice value="$form->{taxservice}">
+
+<input type=hidden name=taxaccounts value="$form->{taxaccounts}">
+|;
+
+  foreach $item (split / /, $form->{taxaccounts}) {
+    print qq|
+<input type=hidden name="${item}_rate" value=$form->{"${item}_rate"}>
+<input type=hidden name="${item}_description" value="$form->{"${item}_description"}">
+|;
+  }
+
+}
+
+
+
+sub form_footer {
+
+  $form->{invtotal} = $form->{invsubtotal};
+  
+  if (($rows = $form->numtextrows($form->{notes}, 50, 8)) < 2) {
+    $rows = 2;
+  }
+  $notes = qq|<textarea name=notes rows=$rows cols=50 wrap=soft>$form->{notes}</textarea>|;
+
+
+  $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : "";
+  if ($form->{taxaccounts}) {
+    $taxincluded = qq|
+               <input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}> <b>|.$locale->text('Tax Included').qq|</b><br><br>
+|;
+  }
+  
+  if (!$form->{taxincluded}) {
+    
+    foreach $item (split / /, $form->{taxaccounts}) {
+      if ($form->{"${item}_base"}) {
+       $form->{invtotal} += $form->{"${item}_total"} = $form->round_amount($form->{"${item}_base"} * $form->{"${item}_rate"}, 2);
+       $form->{"${item}_total"} = $form->format_amount(\%myconfig, $form->{"${item}_total"}, 2);
+       
+       $tax .= qq|
+               <tr>
+                 <th align=right>$form->{"${item}_description"}</th>
+                 <td align=right>$form->{"${item}_total"}</td>
+               </tr>
+|;
+      }
+    }
+
+    $form->{invsubtotal} = $form->format_amount(\%myconfig, $form->{invsubtotal}, 2, 0);
+    
+    $subtotal = qq|
+             <tr>
+               <th align=right>|.$locale->text('Subtotal').qq|</th>
+               <td align=right>$form->{invsubtotal}</td>
+             </tr>
+|;
+
+  }
+
+
+  $form->{invtotal} = $form->format_amount(\%myconfig, $form->{invtotal}, 2, 0);
+
+  print qq|
+  <tr>
+    <td colspan=$colspan>
+      <table cellspacing="0">
+       <tr valign=bottom>
+         <td>
+           <table>
+             <tr>
+               <th align=left>|.$locale->text('Notes').qq|</th>
+             </tr>
+             <tr>
+               <td>$notes</td>
+             </tr>
+           </table>
+         </td>
+         <td colspan=2 align=right width=100%>
+           $taxincluded
+           <table width=100%>
+             $subtotal
+             $tax
+             <tr>
+               <th align=right>|.$locale->text('Total').qq|</th>
+               <td align=right>$form->{invtotal}</td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td colspan=$colspan>
+      <table width=100%>
+        <tr>
+         <th colspan=5 class=listheading>|.$locale->text('Payments').qq|</th>
+       </tr>
+|;
+
+    if ($form->{currency} eq $form->{defaultcurrency}) {
+      @column_index = qw(datepaid source paid AP_paid);
+    } else {
+      @column_index = qw(datepaid source paid exchangerate AP_paid);
+    }
+
+    $column_data{datepaid} = "<th>".$locale->text('Date')."</th>";
+    $column_data{paid} = "<th>".$locale->text('Amount')."</th>";
+    $column_data{exchangerate} = "<th>".$locale->text('Exch')."</th>";
+    $column_data{AP_paid} = "<th>".$locale->text('Account')."</th>";
+    $column_data{source} = "<th>".$locale->text('Source')."</th>";
+
+    print qq|
+       <tr>
+|;
+    map { print "$column_data{$_}\n" } @column_index;
+    print qq|
+       </tr>
+|;
+
+    $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"});
+    for $i (1 .. $form->{paidaccounts}) {
+
+      print qq|
+       <tr>
+|;
+
+      $form->{"selectAP_paid_$i"} = $form->{selectAP_paid};
+      $form->{"selectAP_paid_$i"} =~ s/option>\Q$form->{"AP_paid_$i"}\E/option selected>$form->{"AP_paid_$i"}/;
+
+      # format amounts
+      $form->{"paid_$i"} = $form->format_amount(\%myconfig, $form->{"paid_$i"}, 2);
+      $form->{"exchangerate_$i"} = $form->format_amount(\%myconfig, $form->{"exchangerate_$i"});
+
+      $exchangerate = qq|&nbsp;|;
+      if ($form->{currency} ne $form->{defaultcurrency}) {
+       if ($form->{"forex_$i"}) {
+         $exchangerate = qq|<input type=hidden name="exchangerate_$i" value=$form->{"exchangerate_$i"}>$form->{"exchangerate_$i"}|;
+       } else {
+         $exchangerate = qq|<input name="exchangerate_$i" size=10 value=$form->{"exchangerate_$i"}>|;
+       }
+      }
+      $exchangerate .= qq|
+<input type=hidden name="forex_$i" value=$form->{"forex_$i"}>
+|;
+
+      $column_data{"paid_$i"} = qq|<td align=center><input name="paid_$i" size=11 value=$form->{"paid_$i"}></td>|;
+      $column_data{"exchangerate_$i"} = qq|<td align=center>$exchangerate</td>|;
+      $column_data{"AP_paid_$i"} = qq|<td align=center><select name="AP_paid_$i">$form->{"selectAP_paid_$i"}</select></td>|;
+      $column_data{"datepaid_$i"} = qq|<td align=center><input name="datepaid_$i" size=11 title="$myconfig{dateformat}" value=$form->{"datepaid_$i"}></td>|;
+      $column_data{"source_$i"} = qq|<td align=center><input name="source_$i" size=11 value=$form->{"source_$i"}></td>|;
+
+      map { print qq|$column_data{"${_}_$i"}\n| } @column_index;
+
+      print qq|
+       </tr>
+|;
+    }
+    
+    print qq|
+           <input type=hidden name=paidaccounts value=$form->{paidaccounts}>
+           <input type=hidden name=selectAP_paid value="$form->{selectAP_paid}">
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+<br>
+|;
+
+  $invdate = $form->datetonum($form->{invdate}, \%myconfig);
+  $closedto = $form->datetonum($form->{closedto}, \%myconfig);
+  
+  if ($form->{id}) {
+    print qq|<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+|;
+
+    if (!$form->{revtrans}) {
+      if (!$form->{locked}) {
+       print qq|
+       <input class=submit type=submit name=action value="|.$locale->text('Post').qq|">
+       <input class=submit type=submit name=action value="|.$locale->text('Delete').qq|">
+|;
+      }
+    }
+
+    if ($invdate > $closedto) {
+      print qq|
+      <input class=submit type=submit name=action value="|.$locale->text('Post as new').qq|">
+      <input class=submit type=submit name=action value="|.$locale->text('Order').qq|">
+|;
+    }
+
+  } else {
+    if ($invdate > $closedto) {
+      print qq|<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+      <input class=submit type=submit name=action value="|.$locale->text('Post').qq|">|;
+    }
+  }
+
+print qq|
+
+<input type=hidden name=rowcount value=$form->{rowcount}>
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+sub update {
+
+  $form->{exchangerate} = $form->parse_amount(\%myconfig, $form->{exchangerate});
+  
+  &check_name(vendor);
+
+  &check_project;
+
+  $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{invdate}, 'sell')));
+  
+  
+  for $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"}) {
+      map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(paid exchangerate);
+
+      $form->{"exchangerate_$i"} = $exchangerate if ($form->{"forex_$i"} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'sell')));
+    }
+  }
+  
+  $i = $form->{rowcount};
+  $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1;
+
+  if (($form->{"partnumber_$i"} eq "") && ($form->{"description_$i"} eq "") && ($form->{"partsgroup_$i"} eq "")) {
+
+    &check_form;
+    
+  } else {
+   
+    IR->retrieve_item(\%myconfig, \%$form);
+
+    my $rows = scalar @{ $form->{item_list} };
+
+    if ($rows) {
+      $form->{"qty_$i"}                     = 1 unless ($form->{"qty_$i"});
+      
+      if ($rows > 1) {
+       
+       &select_item;
+       exit;
+       
+      } else {
+        # override sellprice if there is one entered
+       $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
+
+       map { $form->{item_list}[$i]{$_} =~ s/"/&quot;/g } qw(partnumber description unit);
+       
+       map { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } keys %{ $form->{item_list}[0] };
+
+       $s = ($sellprice) ? $sellprice : $form->{"sellprice_$i"};
+       
+       ($dec) = ($s =~ /\.(\d+)/);
+       $dec = length $dec;
+       $decimalplaces = ($dec > 2) ? $dec : 2;
+        if ($sellprice) {
+         $form->{"sellprice_$i"} = $sellprice;
+       } else {
+         # if there is an exchange rate adjust sellprice
+         $form->{"sellprice_$i"} /= $exchangerate;
+       }
+     
+       $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
+       $form->{"qty_$i"} =  $form->format_amount(\%myconfig, $form->{"qty_$i"});
+      }
+
+      &display_form;
+
+    } else {
+      # ok, so this is a new part
+      # ask if it is a part or service item
+
+      if ($form->{"partsgroup_$i"} && ($form->{"partsnumber_$i"} eq "") && ($form->{"description_$i"} eq "")) {
+       $form->{rowcount}--;
+       $form->{"discount_$i"} = "";
+       &display_form;
+      } else {
+       
+       $form->{"id_$i"}                = 0;
+       $form->{"unit_$i"}      = $locale->text('ea');
+
+       &new_item;
+
+      }
+    }
+  }
+}
+
+
+
+sub post {
+
+  $form->isblank("invnumber", $locale->text('Invoice Number missing!'));
+  $form->isblank("invdate", $locale->text('Invoice Date missing!'));
+  $form->isblank("vendor", $locale->text('Vendor missing!'));
+  
+  # if the vendor changed get new values
+  if (&check_name(vendor)) {
+    &update;
+    exit;
+  }
+
+  &validate_items;
+
+  $closedto = $form->datetonum($form->{closedto}, \%myconfig);
+  $invdate = $form->datetonum($form->{invdate}, \%myconfig);
+
+  $form->error($locale->text('Cannot post invoice for a closed period!')) if ($invdate <= $closedto);
+
+  $form->isblank("exchangerate", $locale->text('Exchangerate missing!')) if ($form->{currency} ne $form->{defaultcurrency});
+  
+  for $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"}) {
+      $datepaid = $form->datetonum($form->{"datepaid_$i"}, \%myconfig);
+
+      $form->isblank("datepaid_$i", $locale->text('Payment date missing!'));
+      
+      $form->error($locale->text('Cannot post payment for a closed period!')) if ($datepaid <= $closedto);
+      
+      if ($form->{currency} ne $form->{defaultcurrency}) {
+       $form->{"exchangerate_$i"} = $form->{exchangerate} if ($invdate == $datepaid);
+       $form->isblank("exchangerate_$i", $locale->text('Exchangerate for payment missing!'));
+      }
+    }
+  }
+  
+  
+  ($form->{AP}) = split /--/, $form->{AP};
+  ($form->{AP_paid}) = split /--/, $form->{AP_paid};
+  
+  $form->{id} = 0 if $form->{postasnew};
+
+  $form->redirect($locale->text('Invoice posted!')) if (IR->post_invoice(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot post invoice!'));
+  
+}
+
+
+
+sub delete {
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+|;
+
+  # delete action variable
+  delete $form->{action};
+
+  foreach $key (keys %$form) {
+    $form->{$key} =~ s/"/&quot;/g;
+    print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
+  }
+
+  print qq|
+<h2 class=confirm>|.$locale->text('Confirm!').qq|</h2>
+
+<h4>|.$locale->text('Are you sure you want to delete Invoice Number').qq| $form->{invnumber}</h4>
+<p>
+<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|">
+</form>
+|;
+
+
+}
+
+
+
+sub yes {
+
+  $form->redirect($locale->text('Invoice deleted!')) if (IR->delete_invoice(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot delete invoice!'));
+
+}
+
+
diff --git a/sql-ledger/bin/mozilla/is.pl b/sql-ledger/bin/mozilla/is.pl
new file mode 100644 (file)
index 0000000..cca5813
--- /dev/null
@@ -0,0 +1,739 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Inventory invoicing module
+#
+#======================================================================
+
+
+use SL::IS;
+use SL::PE;
+
+require "$form->{path}/io.pl";
+require "$form->{path}/arap.pl";
+
+
+1;
+# end of main
+
+
+
+sub add {
+
+  $form->{title} = $locale->text('Add Sales Invoice');
+
+  &invoice_links;
+  &prepare_invoice;
+  &display_form;
+  
+}
+
+
+sub edit {
+
+  $form->{title} = $locale->text('Edit Sales Invoice');
+
+  &invoice_links;
+  &prepare_invoice;
+  &display_form;
+  
+}
+
+
+sub invoice_links {
+
+  # create links
+  $form->create_links("AR", \%myconfig, "customer");
+  
+  IS->get_customer(\%myconfig, \%$form);
+  IS->retrieve_invoice(\%myconfig, \%$form);
+
+  # currencies
+  @curr = split /:/, $form->{currencies};
+  chomp $curr[0];
+  $form->{defaultcurrency} = $curr[0];
+
+  map { $form->{selectcurrency} .= "<option>$_\n" } @curr;
+
+  $form->{oldcustomer} = "$form->{customer}--$form->{customer_id}";
+  
+  if (@{ $form->{all_customer} }) {
+    $form->{customer} = qq|$form->{customer}--$form->{customer_id}|;
+    map { $form->{selectcustomer} .= "<option>$_->{name}--$_->{id}\n" } (@{ $form->{all_customer} });
+  }
+
+  # forex
+  $form->{forex} = $form->{exchangerate};
+  $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1;
+
+  foreach $key (keys %{ $form->{AR_links} }) {
+    
+    foreach $ref (@{ $form->{AR_links}{$key} }) {
+      $form->{"select$key"} .= "<option>$ref->{accno}--$ref->{description}\n";
+    }
+
+    if ($key eq "AR_paid") {
+      for $i (1 .. scalar @{ $form->{acc_trans}{$key} }) {
+       $form->{"AR_paid_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
+       # reverse paid
+       $form->{"paid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{amount} * -1;
+       $form->{"datepaid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{transdate};
+       $form->{"forex_$i"} = $form->{"exchangerate_$i"} = $form->{acc_trans}{$key}->[$i-1]->{exchangerate};
+       $form->{"source_$i"} = $form->{acc_trans}{$key}->[$i-1]->{source};
+       $form->{paidaccounts} = $i;
+      }
+    } else {
+      $form->{$key} = "$form->{acc_trans}{$key}->[0]->{accno}--$form->{acc_trans}{$key}->[0]->{description}";
+    }
+  }
+
+  $form->{paidaccounts} = 1 unless (exists $form->{paidaccounts});
+
+  $form->{AR} = $form->{AR_1} unless $form->{id};
+
+  $form->{locked} = ($form->datetonum($form->{invdate}, \%myconfig) <= $form->datetonum($form->{closedto}, \%myconfig));
+
+}
+
+
+sub prepare_invoice {
+
+  $form->{type} = "invoice";
+  $form->{format} = "html";
+  $form->{media} = "screen";
+  
+  if ($form->{id}) {
+    
+    map { $form->{$_} =~ s/"/&quot;/g } qw(invnumber ordnumber shippingpoint notes);
+
+    foreach $ref (@{ $form->{invoice_details} } ) {
+      $i++;
+      map { $form->{"${_}_$i"} = $ref->{$_} } keys %{ $ref };
+      $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"} * 100);
+
+      ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
+      $dec = length $dec;
+      $decimalplaces = ($dec > 2) ? $dec : 2;
+      
+      $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
+      $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"});
+      
+      map { $form->{"${_}_$i"} =~ s/"/&quot;/g } qw(partnumber description unit);
+      $form->{rowcount} = $i;
+    }
+  }
+  
+}
+
+
+
+sub form_header {
+
+
+  # set option selected
+  foreach $item (qw(AR customer currency)) {
+    $form->{"select$item"} =~ s/ selected//;
+    $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
+  }
+    
+  $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate});
+
+  $form->{creditlimit} = $form->format_amount(\%myconfig, $form->{creditlimit}, 0, "0");
+  $form->{creditremaining} = $form->format_amount(\%myconfig, $form->{creditremaining}, 0, "0");
+
+  
+  $exchangerate = "";
+  if ($form->{currency} ne $form->{defaultcurrency}) {
+    if ($form->{forex}) {
+      $exchangerate .= qq|<th align=right>|.$locale->text('Exchangerate').qq|</th><td>$form->{exchangerate}<input type=hidden name=exchangerate value=$form->{exchangerate}></td>|;
+    } else {
+      $exchangerate .= qq|<th align=right>|.$locale->text('Exchangerate').qq|</th><td><input name=exchangerate size=10 value=$form->{exchangerate}></td>|;
+    }
+  }
+  $exchangerate .= qq|
+<input type=hidden name=forex value=$form->{forex}>
+|;
+
+  $customer = ($form->{selectcustomer}) ? qq|<select name=customer>$form->{selectcustomer}</select>\n<input type=hidden name="selectcustomer" value="$form->{selectcustomer}">| : qq|<input name=customer value="$form->{customer}" size=35>|;
+  
+  $n = ($form->{creditremaining} =~ /-/) ? "0" : "1";
+
+  
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=id value=$form->{id}>
+
+<input type=hidden name=type value=$form->{type}>
+<input type=hidden name=media value=$form->{media}>
+<input type=hidden name=format value=$form->{format}>
+
+<input type=hidden name=title value="$form->{title}">
+<input type=hidden name=vc value="customer">
+<input type=hidden name=employee value="$form->{employee}">
+
+<input type=hidden name=discount value=$form->{discount}>
+<input type=hidden name=creditlimit value=$form->{creditlimit}>
+<input type=hidden name=creditremaining value=$form->{creditremaining}>
+
+<input type=hidden name=closedto value=$form->{closedto}>
+<input type=hidden name=locked value=$form->{locked}>
+
+<table width=100%>
+  <tr class=listtop>
+    <th class=listtop>$form->{title}</font></th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr valign=top>
+         <td>
+           <table>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Record in').qq|</th>
+               <td colspan=3><select name=AR>$form->{selectAR}</select></td>
+               <input type=hidden name=selectAR value="$form->{selectAR}">
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Customer').qq|</th>
+               <td colspan=3>$customer</td>
+               <input type=hidden name=customer_id value=$form->{customer_id}>
+               <input type=hidden name=oldcustomer value="$form->{oldcustomer}"> 
+             </tr>
+             <tr>
+               <td></td>
+               <td colspan=3>
+                 <table width=100%>
+                   <tr>
+                     <th align=left nowrap>|.$locale->text('Credit Limit').qq|</th>
+                     <td>$form->{creditlimit}</td>
+                     <th align=left nowrap>|.$locale->text('Remaining').qq|</th>
+                     <td class="plus$n">$form->{creditremaining}</font></td>
+                   </tr>
+                 </table>
+               </td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Currency').qq|</th>
+               <td><select name=currency>$form->{selectcurrency}</select></td>
+               <input type=hidden name=selectcurrency value="$form->{selectcurrency}">
+               <input type=hidden name=defaultcurrency value=$form->{defaultcurrency}>
+               <input type=hidden name=fxgain_accno value=$form->{fxgain_accno}>
+               <input type=hidden name=fxloss_accno value=$form->{fxloss_accno}>
+               $exchangerate
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Ship via').qq|</th>
+               <td colspan=3><input name=shippingpoint size=35 value="$form->{shippingpoint}"></td>
+             </tr>
+           </table>
+         </td>
+         <td align=right>
+           <table>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th>
+               <td><input name=invnumber size=11 value="$form->{invnumber}"></td>
+             </tr>
+             <tr>
+               <th align=right>|.$locale->text('Invoice Date').qq|</th>
+               <td><input name=invdate size=11 title="$myconfig{dateformat}" value=$form->{invdate}></td>
+             </tr>
+             <tr>
+               <th align=right>|.$locale->text('Due Date').qq|</th>
+               <td><input name=duedate size=11 title="$myconfig{dateformat}" value=$form->{duedate}></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Order Number').qq|</th>
+               <td><input name=ordnumber size=11 value="$form->{ordnumber}"></td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+    </td>
+  </tr>
+<!-- shipto are in hidden variables -->
+
+<input type=hidden name=shiptoname value="$form->{shiptoname}">
+<input type=hidden name=shiptoaddr1 value="$form->{shiptoaddr1}">
+<input type=hidden name=shiptoaddr2 value="$form->{shiptoaddr2}">
+<input type=hidden name=shiptoaddr3 value="$form->{shiptoaddr3}">
+<input type=hidden name=shiptoaddr4 value="$form->{shiptoaddr4}">
+<input type=hidden name=shiptocontact value="$form->{shiptocontact}">
+<input type=hidden name=shiptophone value="$form->{shiptophone}">
+<input type=hidden name=shiptofax value="$form->{shiptofax}">
+<input type=hidden name=shiptoemail value="$form->{shiptoemail}">
+
+<!-- email variables -->
+<input type=hidden name=message value="$form->{message}">
+<input type=hidden name=email value="$form->{email}">
+<input type=hidden name=subject value="$form->{subject}">
+<input type=hidden name=cc value="$form->{cc}">
+<input type=hidden name=bcc value="$form->{bcc}">
+
+<input type=hidden name=taxaccounts value="$form->{taxaccounts}">
+|;
+
+  foreach $item (split / /, $form->{taxaccounts}) {
+    print qq|
+<input type=hidden name="${item}_rate" value="$form->{"${item}_rate"}">
+<input type=hidden name="${item}_description" value="$form->{"${item}_description"}">
+<input type=hidden name="${item}_taxnumber" value="$form->{"${item}_taxnumber"}">
+|;
+  }
+
+}
+
+
+
+sub form_footer {
+
+  $form->{invtotal} = $form->{invsubtotal};
+
+  if (($rows = $form->numtextrows($form->{notes}, 50, 8)) < 2) {
+    $rows = 2;
+  }
+  $notes = qq|<textarea name=notes rows=$rows cols=50 wrap=soft>$form->{notes}</textarea>|;
+
+
+  $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : "";
+
+  if ($form->{taxaccounts}) {
+    $taxincluded = qq|
+               <input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}> <b>|.$locale->text('Tax Included').qq|</b><br><br>
+|;
+  }
+  
+  if (!$form->{taxincluded}) {
+    
+    foreach $item (split / /, $form->{taxaccounts}) {
+      if ($form->{"${item}_base"}) {
+       $form->{"${item}_total"} = $form->round_amount($form->{"${item}_base"} * $form->{"${item}_rate"}, 2);
+       $form->{invtotal} += $form->{"${item}_total"};
+       $form->{"${item}_total"} = $form->format_amount(\%myconfig, $form->{"${item}_total"}, 2);
+       
+       $tax .= qq|
+             <tr>
+               <th align=right>$form->{"${item}_description"}</th>
+               <td align=right>$form->{"${item}_total"}</td>
+             </tr>
+|;
+      }
+    }
+
+    $form->{invsubtotal} = $form->format_amount(\%myconfig, $form->{invsubtotal}, 2, 0);
+    
+    $subtotal = qq|
+             <tr>
+               <th align=right>|.$locale->text('Subtotal').qq|</th>
+               <td align=right>$form->{invsubtotal}</td>
+             </tr>
+|;
+
+  }
+
+  $form->{oldinvtotal} = $form->{invtotal};
+  $form->{invtotal} = $form->format_amount(\%myconfig, $form->{invtotal}, 2, 0);
+  
+  print qq|
+  <tr>
+    <td>
+      <table width=100%>
+       <tr valign=bottom>
+         <td>
+           <table>
+             <tr>
+               <th align=left>|.$locale->text('Notes').qq|</th>
+             </tr>
+             <tr>
+               <td>$notes</td>
+             </tr>
+           </table>
+         </td>
+         <td align=right width=100%>
+           $taxincluded
+           <table width=100%>
+             $subtotal
+             $tax
+             <tr>
+               <th align=right>|.$locale->text('Total').qq|</th>
+               <td align=right>$form->{invtotal}</td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+         <th class=listheading colspan=5>|.$locale->text('Payments')
+         .qq|</font></th>
+       </tr>
+|;
+
+  if ($form->{currency} eq $form->{defaultcurrency}) {
+    @column_index = qw(datepaid source paid AR_paid);
+  } else {
+    @column_index = qw(datepaid source paid exchangerate AR_paid);
+  }
+
+  $column_data{datepaid} = "<th>".$locale->text('Date')."</th>";
+  $column_data{paid} = "<th>".$locale->text('Amount')."</th>";
+  $column_data{exchangerate} = "<th>".$locale->text('Exch')."</th>";
+  $column_data{AR_paid} = "<th>".$locale->text('Account')."</th>";
+  $column_data{source} = "<th>".$locale->text('Source')."</th>";
+  
+  print "
+       <tr>
+";
+  map { print "$column_data{$_}\n" } @column_index;
+  print "
+        </tr>
+";
+  
+  $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"});
+  for $i (1 .. $form->{paidaccounts}) {
+
+    print "
+        <tr>\n";
+
+    $form->{"selectAR_paid_$i"} = $form->{selectAR_paid};
+    $form->{"selectAR_paid_$i"} =~ s/option>\Q$form->{"AR_paid_$i"}\E/option selected>$form->{"AR_paid_$i"}/;
+    
+    # format amounts
+    $totalpaid += $form->{"paid_$i"};
+    $form->{"paid_$i"} = $form->format_amount(\%myconfig, $form->{"paid_$i"}, 2);
+    $form->{"exchangerate_$i"} = $form->format_amount(\%myconfig, $form->{"exchangerate_$i"});
+
+    $exchangerate = qq|&nbsp;|;
+    if ($form->{currency} ne $form->{defaultcurrency}) {
+      if ($form->{"forex_$i"}) {
+       $exchangerate = qq|<input type=hidden name="exchangerate_$i" value=$form->{"exchangerate_$i"}>$form->{"exchangerate_$i"}|;
+      } else {
+       $exchangerate = qq|<input name="exchangerate_$i" size=10 value=$form->{"exchangerate_$i"}>|;
+      }
+    }
+
+    $exchangerate .= qq|
+<input type=hidden name="forex_$i" value=$form->{"forex_$i"}>
+|;
+
+    $column_data{"paid_$i"} = qq|<td align=center><input name="paid_$i" size=11 value=$form->{"paid_$i"}></td>|;
+    $column_data{"exchangerate_$i"} = qq|<td align=center>$exchangerate</td>|;
+    $column_data{"AR_paid_$i"} = qq|<td align=center><select name="AR_paid_$i">$form->{"selectAR_paid_$i"}</select></td>|;
+    $column_data{"datepaid_$i"} = qq|<td align=center><input name="datepaid_$i" size=11 title="$myconfig{dateformat}" value=$form->{"datepaid_$i"}></td>|;
+    $column_data{"source_$i"} = qq|<td align=center><input name="source_$i" size=11 value="$form->{"source_$i"}"></td>|;
+
+    map { print qq|$column_data{"${_}_$i"}\n| } @column_index;
+    print "
+        </tr>\n";
+  }
+
+  print qq|
+<input type=hidden name=paidaccounts value=$form->{paidaccounts}>
+<input type=hidden name=selectAR_paid value="$form->{selectAR_paid}">
+<input type=hidden name=oldinvtotal value=$form->{oldinvtotal}>
+<input type=hidden name=oldtotalpaid value=$totalpaid>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+|;
+
+  &print_options;
+
+  print qq|
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+|;
+
+
+  $invdate = $form->datetonum($form->{invdate}, \%myconfig);
+  $closedto = $form->datetonum($form->{closedto}, \%myconfig);
+  if ($form->{id}) {
+    print qq|
+    <input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+    <input class=submit type=submit name=action value="|.$locale->text('Ship to').qq|">
+    <input class=submit type=submit name=action value="|.$locale->text('Print').qq|">
+    <input class=submit type=submit name=action value="|.$locale->text('E-mail').qq|">
+|;
+
+    if (!$form->{revtrans}) {
+      if (!$form->{locked}) {
+       print qq|
+       <input class=submit type=submit name=action value="|.$locale->text('Post').qq|">
+       <input class=submit type=submit name=action value="|.$locale->text('Delete').qq|">
+|;
+      }
+    }
+
+    if ($invdate > $closedto) {
+      print qq|
+      <input class=submit type=submit name=action value="|.$locale->text('Post as new').qq|">
+      <input class=submit type=submit name=action value="|.$locale->text('Order').qq|">
+|;
+    }
+
+  } else {
+    if ($invdate > $closedto) {
+      print qq|<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+      <input class=submit type=submit name=action value="|.$locale->text('Ship to').qq|">
+      <input class=submit type=submit name=action value="|.$locale->text('Print').qq|">
+      <input class=submit type=submit name=action value="|.$locale->text('E-mail').qq|">
+      <input class=submit type=submit name=action value="|.$locale->text('Post').qq|">|;
+    }
+  }
+
+  print qq|
+
+<input type=hidden name=rowcount value=$form->{rowcount}>
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub update {
+
+  map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate creditlimit creditremaining);
+  
+  &check_name(customer);
+
+  &check_project;
+
+  $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{invdate}, 'buy')));
+
+  for $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"}) {
+      map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(paid exchangerate);
+
+      $form->{"exchangerate_$i"} = $exchangerate if ($form->{"forex_$i"} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'buy')));
+    }
+  }
+
+  $i = $form->{rowcount};
+  $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1;
+
+  # if last row empty, check the form otherwise retrieve new item
+  if (($form->{"partnumber_$i"} eq "") && ($form->{"description_$i"} eq "") && ($form->{"partsgroup_$i"} eq "")) {
+
+    $form->{creditremaining} += ($form->{oldinvtotal} - $form->{oldtotalpaid});
+    &check_form;
+
+  } else {
+
+    IS->retrieve_item(\%myconfig, \%$form);
+    
+    $rows = scalar @{ $form->{item_list} };
+
+    $form->{"discount_$i"}     = $form->format_amount(\%myconfig, $form->{discount} * 100);
+
+    if ($rows) {
+      $form->{"qty_$i"}                = ($form->{"qty_$i"} * 1) ? $form->{"qty_$i"} : 1;
+      
+      if ($rows > 1) {
+       
+       &select_item;
+       exit;
+       
+      } else {
+
+        $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
+       
+       map { $form->{item_list}[$i]{$_} =~ s/"/&quot;/g } qw(partnumber description unit);
+       map { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } keys %{ $form->{item_list}[0] };
+       
+       $s = ($sellprice) ? $sellprice : $form->{"sellprice_$i"};
+       ($dec) = ($s =~ /\.(\d+)/);
+       $dec = length $dec;
+       $decimalplaces = ($dec > 2) ? $dec : 2;
+
+       if ($sellprice) {
+         $form->{"sellprice_$i"} = $sellprice;
+       } else {
+         # if there is an exchange rate adjust sellprice
+         $form->{"sellprice_$i"} /= $exchangerate;
+       }
+       
+       $form->{"listprice_$i"} /= $exchangerate;
+
+        $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * (1 - $form->{"discount_$i"} / 100);
+       map { $form->{"${_}_base"} = 0 } (split / /, $form->{taxaccounts});
+        map { $form->{"${_}_base"} += $amount } (split / /, $form->{"taxaccounts_$i"});
+       map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{"taxaccounts_$i"} if !$form->{taxincluded};
+       
+        $form->{creditremaining} -= $amount;
+       
+
+       map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces) } qw(sellprice listprice);
+       
+       $form->{"qty_$i"} =  $form->format_amount(\%myconfig, $form->{"qty_$i"});
+
+      }
+
+      &display_form;
+
+    } else {
+      # ok, so this is a new part
+      # ask if it is a part or service item
+
+      if ($form->{"partsgroup_$i"} && ($form->{"partsnumber_$i"} eq "") && ($form->{"description_$i"} eq "")) {
+       $form->{rowcount}--;
+       $form->{"discount_$i"} = "";
+       &display_form;
+      } else {
+
+       $form->{"id_$i"}          = 0;
+       $form->{"unit_$i"}        = $locale->text('ea');
+
+       &new_item;
+
+      }
+    }
+  }
+}
+
+
+
+sub post {
+
+  $form->isblank("invnumber", $locale->text('Invoice Number missing!'));
+  $form->isblank("invdate", $locale->text('Invoice Date missing!'));
+  $form->isblank("customer", $locale->text('Customer missing!'));
+
+  # if oldcustomer ne customer redo form
+  if (&check_name(customer)) {
+    &update;
+    exit;
+  }
+  
+  &validate_items;
+
+  $closedto = $form->datetonum($form->{closedto}, \%myconfig);
+  $invdate = $form->datetonum($form->{invdate}, \%myconfig);
+  
+  $form->error($locale->text('Cannot post invoice for a closed period!')) if ($invdate <= $closedto);
+
+  $form->isblank("exchangerate", $locale->text('Exchangerate missing!')) if ($form->{currency} ne $form->{defaultcurrency});
+  
+  for $i (1 .. $form->{paidaccounts}) {
+    if ($form->{"paid_$i"}) {
+      $datepaid = $form->datetonum($form->{"datepaid_$i"}, \%myconfig);
+
+      $form->isblank("datepaid_$i", $locale->text('Payment date missing!'));
+      
+      $form->error($locale->text('Cannot post payment for a closed period!')) if ($datepaid <= $closedto);
+
+      if ($form->{currency} ne $form->{defaultcurrency}) {
+       $form->{"exchangerate_$i"} = $form->{exchangerate} if ($invdate == $datepaid);
+       $form->isblank("exchangerate_$i", $locale->text('Exchangerate for payment missing!'));
+      }
+    }
+  }
+
+      
+  ($form->{AR}) = split /--/, $form->{AR};
+  ($form->{AR_paid}) = split /--/, $form->{AR_paid};
+  
+  $form->{label} = $locale->text('Invoice');
+
+  $form->{id} = 0 if $form->{postasnew};
+  
+  $form->redirect($locale->text('Invoice posted!')) if (IS->post_invoice(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot post invoice!'));
+    
+}
+
+
+
+
+sub delete {
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+|;
+
+  # delete action variable
+  delete $form->{action};
+
+  foreach $key (keys %$form) {
+    $form->{$key} =~ s/"/&quot;/g;
+    print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
+  }
+
+  print qq|
+<h2 class=confirm>|.$locale->text('Confirm!').qq|</font></h2>
+
+<h4>|.$locale->text('Are you sure you want to delete Invoice Number').qq| $form->{invnumber}
+</h4>
+
+<p>
+<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|">
+</form>
+|;
+
+
+}
+
+
+
+sub yes {
+
+  $form->redirect($locale->text('Invoice deleted!')) if (IS->delete_invoice(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot delete invoice!'));
+
+}
+
+
diff --git a/sql-ledger/bin/mozilla/login.pl b/sql-ledger/bin/mozilla/login.pl
new file mode 100644 (file)
index 0000000..3c36564
--- /dev/null
@@ -0,0 +1,217 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#######################################################################
+
+
+use DBI;
+use SL::User;
+use SL::Form;
+
+
+$form = new Form;
+
+$locale = new Locale $language, "login";
+
+# customization
+if (-f "$form->{path}/custom_$form->{script}") {
+  eval { require "$form->{path}/custom_$form->{script}"; };
+  $form->error($@) if ($@);
+}
+
+# per login customization
+if (-f "$form->{path}/$form->{login}_$form->{script}") {
+  eval { require "$form->{path}/$form->{login}_$form->{script}"; };
+  $form->error($@) if ($@);
+}
+
+# window title bar, user info
+$form->{titlebar} = "SQL-Ledger ".$locale->text('Version'). " $form->{version}";
+
+if ($form->{action}) {
+  $form->{titlebar} .= " - $myconfig{name} - $myconfig{dbname}";
+  &{ $locale->findsub($form->{action}) };
+} else {
+  &login_screen;
+}
+
+
+1;
+
+
+sub login_screen {
+  
+  if (-f "css/sql-ledger.css") {
+    $form->{stylesheet} = "sql-ledger.css";
+  }
+
+  $form->header;
+
+  print qq|
+<body class=login>
+
+<pre>
+
+</pre>
+
+<center>
+<table class=login border=3 cellpadding=20>
+  <tr>
+    <td class=login align=center><a href="http://www.sql-ledger.org" target=_top><img src=sql-ledger.png border=0></a>
+<h1 class=login align=center>|.$locale->text('Version').qq| $form->{version}
+</h1>
+
+<p>
+
+<form method=post action=$form->{script}>
+
+      <table width=100%>
+       <tr>
+         <td align=center>
+           <table>
+             <tr>
+               <th align=right>|.$locale->text('Name').qq|</th>
+               <td><input class=login name=login size=30></td>
+             </tr> 
+             <tr>
+               <th align=right>|.$locale->text('Password').qq|</th>
+               <td><input class=login type=password name=password size=30></td>
+             </tr>
+             <input type=hidden name=path value=$form->{path}>
+           </table>
+
+           <br>
+           <input type=submit name=action value="|.$locale->text('Login').qq|">
+
+         </td>
+       </tr>
+      </table>
+
+</form>
+
+    </td>
+  </tr>
+</table>
+  
+</body>
+</html>
+|;
+
+}
+
+
+sub login {
+
+  $form->error($locale->text('You did not enter a name!')) unless ($form->{login});
+
+  $user = new User $memberfile, $form->{login};
+
+  # if we get an error back, bale out
+  if (($errno = $user->login(\%$form, $userspath)) <= -1) {
+    $errno *= -1;
+    $err[1] = $locale->text('Incorrect Password!');
+    $err[2] = $locale->text('Incorrect Dataset version!');
+    $err[3] = qq|$form->{login} |.$locale->text('is not a member!');
+    
+    $form->error($err[$errno]);
+  }
+  
+  # made it this far, execute the menu
+  $argv = "login=$form->{login}&password=$form->{password}&path=$form->{path}&action=display";
+
+  exec ("perl", "menu.pl", $argv);
+
+}
+
+
+
+sub logout {
+
+  unlink "$userspath/$form->{login}.conf";
+  
+  # remove the callback to display the message
+  $form->{callback} = "login.pl?path=$form->{path}&action=&login=";
+  $form->redirect($locale->text('You are logged out!'));
+
+}
+
+
+    
+sub company_logo {
+  
+  require "$userspath/$form->{login}.conf";
+  $locale = new Locale $myconfig{countrycode}, "login" unless ($language eq $myconfig{countrycode});
+
+  $myconfig{address} =~ s/\\n/<br>/g;
+  $myconfig{dbhost} = $locale->text('localhost') unless $myconfig{dbhost};
+
+  map { $form->{$_} = $myconfig{$_} } qw(charset stylesheet);
+  
+  $form->{title} = $locale->text('About');
+  
+  # create the logo screen
+  $form->header unless $form->{noheader};
+
+  print qq|
+<body>
+
+<pre>
+
+</pre>
+<center>
+<a href="http://www.sql-ledger.org" target=_top><img src=sql-ledger.png border=0></a>
+<h1 class=login>|.$locale->text('Version').qq| $form->{version}</h1>
+
+<p>
+|.$locale->text('Licensed to').qq|
+<p>
+<b>
+$myconfig{company}
+<br>$myconfig{address}
+</b>
+
+<p>
+<table>
+  <tr>
+    <th align=right>|.$locale->text('User').qq|</th>
+    <td>$myconfig{name}</td>
+  </tr>
+  <tr>
+    <th align=right>|.$locale->text('Dataset').qq|</th>
+    <td>$myconfig{dbname}</td>
+  </tr>
+  <tr>
+    <th align=right>|.$locale->text('Database Host').qq|</th>
+    <td>$myconfig{dbhost}</td>
+  </tr>
+</table>
+
+</center>
+
+</body>
+</html>
+|;
+
+}
+
+
+
diff --git a/sql-ledger/bin/mozilla/menu.pl b/sql-ledger/bin/mozilla/menu.pl
new file mode 100644 (file)
index 0000000..67c18bd
--- /dev/null
@@ -0,0 +1,160 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors: Christopher Browne
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#######################################################################
+#
+# two frame layout with refractured menu
+#
+# CHANGE LOG:
+#   DS. 2002-03-25  Created
+#######################################################################
+
+$menufile = "menu.ini";
+use SL::Menu;
+
+
+1;
+# end of main
+
+
+sub display {
+
+  $framesize = ($ENV{HTTP_USER_AGENT} =~ /links/i) ? "240" : "135";
+
+  $form->header;
+
+  print qq|
+
+<FRAMESET COLS="$framesize,*" BORDER="1">
+
+  <FRAME NAME="acc_menu" SRC="$form->{script}?login=$form->{login}&password=$form->{password}&action=acc_menu&path=$form->{path}">
+  <FRAME NAME="main_window" SRC="login.pl?login=$form->{login}&password=$form->{password}&action=company_logo&path=$form->{path}">
+
+</FRAMESET>
+
+</BODY>
+</HTML>
+|;
+
+}
+
+
+
+sub acc_menu {
+
+  my $menu = new Menu "$menufile";
+  $menu = new Menu "custom_$menufile" if (-f "custom_$menufile");
+  $menu = new Menu "$form->{login}_$menufile" if (-f "$form->{login}_$menufile");
+  
+  $form->{title} = $locale->text('Accounting Menu');
+  
+  $form->header;
+
+  print qq|
+<body class=menu>
+
+|;
+
+  &section_menu($menu);
+
+  print qq|
+</body>
+</html>
+|;
+
+}
+
+
+sub section_menu {
+  my ($menu, $level) = @_;
+
+  # build tiered menus
+  my @menuorder = $menu->access_control(\%myconfig, $level);
+
+  while (@menuorder) {
+    $item = shift @menuorder;
+    $label = $item;
+    $label =~ s/$level--//g;
+
+    my $spacer = "&nbsp;" x (($item =~ s/--/--/g) * 2);
+
+    $label =~ s/.*--//g;
+    $label = $locale->text($label);
+    $label =~ s/ /&nbsp;/g;
+
+    $menu->{$item}{target} = "main_window" unless $menu->{$item}{target};
+    
+    if ($menu->{$item}{submenu}) {
+      $menu->{$item}{$item} = !$form->{$item};
+
+      if ($form->{level} && $item =~ /^$form->{level}/) {
+
+        # expand menu
+       print qq|<br>\n$spacer|.$menu->menuitem(\%myconfig, \%$form, $item, $level).qq|$label</a>|;
+
+       # remove same level items
+       map { shift @menuorder } grep /^$item/, @menuorder;
+       
+       &section_menu($menu, $item);
+
+       print qq|<br>\n|;
+
+      } else {
+       
+       print qq|<br>\n$spacer|.$menu->menuitem(\%myconfig, \%$form, $item, $level).qq|$label&nbsp;...</a>|;
+
+        # remove same level items
+       map { shift @menuorder } grep /^$item/, @menuorder;
+
+      }
+
+      
+    } else {
+    
+      if ($menu->{$item}{module}) {
+       if ($form->{$item} && $form->{level} eq $item) {
+         $menu->{$item}{$item} = !$form->{$item};
+         print qq|<br>\n$spacer|.$menu->menuitem(\%myconfig, \%$form, $item, $level).qq|$label</a>|;
+         
+         # remove same level items
+         map { shift @menuorder } grep /^$item/, @menuorder;
+         
+         &section_menu($menu, $item);
+
+       } else {
+         print qq|<br>\n$spacer|.$menu->menuitem(\%myconfig, \%$form, $item, $level).qq|$label</a>|;
+       }
+       
+      } else {
+       
+       print qq|<br><b>$label</b>|;
+       
+       &section_menu($menu, $item);
+
+       print qq|<br>\n|;
+       
+      }
+    }
+  }
+}
+
+
diff --git a/sql-ledger/bin/mozilla/oe.pl b/sql-ledger/bin/mozilla/oe.pl
new file mode 100644 (file)
index 0000000..6a8326f
--- /dev/null
@@ -0,0 +1,1111 @@
+#=====================================================================
+# SQL-Ledger, Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Order entry module
+#
+#======================================================================
+
+
+use SL::OE;
+use SL::IR;
+use SL::IS;
+use SL::PE;
+
+require "$form->{path}/io.pl";
+require "$form->{path}/arap.pl";
+
+1;
+# end of main
+
+
+sub add {
+
+  if ($form->{type} eq 'purchase_order') {
+    $form->{title} = $locale->text('Add Purchase Order');
+    $form->{vc} = 'vendor';
+  }
+  if ($form->{type} eq 'sales_order') {
+    $form->{title} = $locale->text('Add Sales Order');
+    $form->{vc} = 'customer';
+  }
+  
+  &order_links;
+  &prepare_order;
+  &display_form;
+
+}
+
+
+sub edit {
+
+  if ($form->{type} eq 'purchase_order') {
+    $form->{title} = $locale->text('Edit Purchase Order');
+    $form->{vc} = 'vendor';
+  }
+  if ($form->{type} eq 'sales_order') {
+    $form->{title} = $locale->text('Edit Sales Order');
+    $form->{vc} = 'customer';
+  }
+  
+  &order_links;
+  &prepare_order;
+
+  &display_form;
+
+}
+
+
+sub order_links {
+
+  # get vendors / customers
+  $form->all_vc(\%myconfig, $form->{vc});
+
+  # retrieve order
+  OE->retrieve_order(\%myconfig, \%$form);
+  
+  $taxincluded = $form->{taxincluded};
+  $form->{shipto} = 1 if $form->{id};
+
+  # get customer / vendor
+  if ($form->{type} eq 'purchase_order') {
+    IR->get_vendor(\%myconfig, \%$form);
+  }
+  if ($form->{type} eq 'sales_order') {
+    IS->get_customer(\%myconfig, \%$form);
+  }
+
+  ($form->{$form->{vc}}) = split /--/, $form->{$form->{vc}};
+  $form->{"old$form->{vc}"} = qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|;
+
+  # build the popup menus
+  if (@{ $form->{"all_$form->{vc}"} }) {
+    $form->{$form->{vc}} = qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|;
+    map { $form->{"select$form->{vc}"} .= "<option>$_->{name}--$_->{id}\n" } (@{ $form->{"all_$form->{vc}"} });
+  }
+  
+  # currencies
+  @curr = split /:/, $form->{currencies};
+  chomp $curr[0];
+  $form->{defaultcurrency} = $curr[0];
+  
+  map { $form->{selectcurrency} .= "<option>$_\n" } @curr;
+
+  $form->{taxincluded} = $taxincluded if ($form->{id});
+
+  # forex
+  $form->{forex} = $form->{exchangerate};
+  
+}
+
+
+sub prepare_order {
+
+  $form->{format} = "html";
+  $form->{media} = "screen";
+  
+  if ($form->{id}) {
+    
+    map { $form->{$_} =~ s/"/&quot;/g } qw(invnumber shippingpoint notes shiptoname shiptoaddr1 shiptoaddr2 shiptoaddr3 shiptoaddr4 shiptocontact);
+    
+    foreach $ref (@{ $form->{order_details} } ) {
+      $i++;
+      map { $form->{"${_}_$i"} = $ref->{$_} } keys %{ $ref };
+      $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"} * 100);
+
+      ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
+      $dec = length $dec;
+      $decimalplaces = ($dec > 2) ? $dec : 2;
+      
+      $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
+      $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"});
+      
+      map { $form->{"${_}_$i"} =~ s/"/&quot;/g } qw(partnumber description unit);
+      $form->{rowcount} = $i;
+    }
+  }
+
+}
+
+
+sub form_header {
+
+  $checkedopen = ($form->{closed}) ? "" : "checked";
+  $checkedclosed = ($form->{closed}) ? "checked" : "";
+
+  if ($form->{id}) {
+    $openclosed = qq|
+      <tr>
+        <td colspan=2 align=center>
+         <table>
+           <tr>
+             <th nowrap><input name=closed type=radio class=radio value=0 $checkedopen> |.$locale->text('Open').qq|</th>
+             <th nowrap><input name=closed type=radio class=radio value=1 $checkedclosed> |.$locale->text('Closed').qq|</th>
+           </tr>
+         </table>
+       </td>
+      </tr>
+|;
+  }
+
+  # set option selected
+  foreach $item ($form->{vc}, currency) {
+    $form->{"select$item"} =~ s/ selected//;
+    $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
+  }
+    
+  $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate});
+
+  $form->{creditlimit} = $form->format_amount(\%myconfig, $form->{creditlimit}, 0, "0");
+  $form->{creditremaining} = $form->format_amount(\%myconfig, $form->{creditremaining}, 0, "0");
+  
+  $exchangerate = qq|
+<input type=hidden name=forex value=$form->{forex}>
+|;
+
+  if ($form->{currency} ne $form->{defaultcurrency}) {
+    if ($form->{forex}) {
+      $exchangerate .= qq|<th align=right>|.$locale->text('Exchangerate').qq|</th><td>$form->{exchangerate}</td>
+      <input type=hidden name=exchangerate value=$form->{exchangerate}>
+|;
+    } else {
+      $exchangerate .= qq|<th align=right>|.$locale->text('Exchangerate').qq|</th><td><input name=exchangerate size=10 value=$form->{exchangerate}></td>|;
+    }
+  }
+
+
+  $vclabel = ucfirst $form->{vc};
+  $vclabel = $locale->text($vclabel);
+
+  if ($form->{type} eq 'sales_order') {
+    
+    $n = ($form->{creditremaining} =~ /-/) ? "0" : "1";
+    
+    $creditremaining = qq|
+             <tr>
+               <td></td>
+               <td colspan=3>
+                 <table width=100%>
+                   <tr>
+                     <th align=left nowrap>|.$locale->text('Credit Limit').qq|</th>
+                     <td>$form->{creditlimit}</td>
+                     <th align=left nowrap>|.$locale->text('Remaining').qq|</th>
+                     <td class="plus$n">$form->{creditremaining}</td>
+                   </tr>
+                 </table>
+               </td>
+             </tr>
+|;
+  }
+
+  $vc = ($form->{"select$form->{vc}"}) ? qq|<select name=$form->{vc}>$form->{"select$form->{vc}"}</select>\n<input type=hidden name="select$form->{vc}" value="$form->{"select$form->{vc}"}">| : qq|<input name=$form->{vc} value="$form->{$form->{vc}}" size=35>|;
+
+
+  $form->header;
+  
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=id value=$form->{id}>
+
+<input type=hidden name=type value=$form->{type}>
+<input type=hidden name=media value=$form->{media}>
+<input type=hidden name=format value=$form->{format}>
+
+<input type=hidden name=vc value=$form->{vc}>
+<input type=hidden name=employee value="$form->{employee}">
+
+<input type=hidden name=title value="$form->{title}">
+
+<input type=hidden name=discount value=$form->{discount}>
+<input type=hidden name=creditlimit value=$form->{creditlimit}>
+<input type=hidden name=creditremaining value=$form->{creditremaining}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table width="100%">
+        <tr valign=top>
+         <td>
+           <table>
+             <tr>
+               <th align=right>$vclabel</th>
+               <td colspan=3>$vc</td>
+               <input type=hidden name=$form->{vc}_id value=$form->{"$form->{vc}_id"}>
+               <input type=hidden name="old$form->{vc}" value="$form->{"old$form->{vc}"}">
+             </tr>
+             $creditremaining
+             <tr>
+               <th align=right>|.$locale->text('Currency').qq|</th>
+               <td><select name=currency>$form->{selectcurrency}</select></td>
+               <input type=hidden name=selectcurrency value="$form->{selectcurrency}">
+               <input type=hidden name=defaultcurrency value=$form->{defaultcurrency}>
+               $exchangerate
+             </tr>
+             <tr>
+               <th align=right>|.$locale->text('Ship via').qq|</th>
+               <td colspan=3><input name=shippingpoint size=35 value="$form->{shippingpoint}"></td>
+             </tr>
+           </table>
+         </td>
+         <td align=right>
+           <table width=100%>
+             $openclosed
+             <tr>
+               <th align=right nowrap>|.$locale->text('Order Number').qq|</th>
+               <td><input name=ordnumber size=11 value="$form->{ordnumber}"></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Order Date').qq|</th>
+               <td><input name=orddate size=11 title="$myconfig{dateformat}" value=$form->{orddate}></td>
+             </tr>
+             <tr>
+               <th align=right nowrap=true>|.$locale->text('Required by').qq|</th>
+               <td><input name=reqdate size=11 title="$myconfig{dateformat}" value=$form->{reqdate}></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Terms: Net').qq|</th>
+               <td nowrap=true><input name=terms size="3" maxlength="3" value=$form->{terms}> |.$locale->text('days').qq|</td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+
+<!-- shipto are in hidden variables -->
+
+<input type=hidden name=shiptoname value="$form->{shiptoname}">
+<input type=hidden name=shiptoaddr1 value="$form->{shiptoaddr1}">
+<input type=hidden name=shiptoaddr2 value="$form->{shiptoaddr2}">
+<input type=hidden name=shiptoaddr3 value="$form->{shiptoaddr3}">
+<input type=hidden name=shiptoaddr4 value="$form->{shiptoaddr4}">
+<input type=hidden name=shiptocontact value="$form->{shiptocontact}">
+<input type=hidden name=shiptophone value="$form->{shiptophone}">
+<input type=hidden name=shiptofax value="$form->{shiptofax}">
+<input type=hidden name=shiptoemail value="$form->{shiptoemail}">
+
+<!-- email variables -->
+<input type=hidden name=message value="$form->{message}"> 
+<input type=hidden name=email value="$form->{email}">
+<input type=hidden name=subject value="$form->{subject}">
+<input type=hidden name=cc value="$form->{cc}">
+<input type=hidden name=bcc value="$form->{bcc}">
+
+<input type=hidden name=taxpart value="$form->{taxpart}">
+<input type=hidden name=taxservice value="$form->{taxservice}">
+
+<input type=hidden name=taxaccounts value="$form->{taxaccounts}">
+|;
+
+  foreach $item (split / /, $form->{taxaccounts}) {
+    print qq|
+<input type=hidden name="${item}_rate" value=$form->{"${item}_rate"}>
+<input type=hidden name="${item}_description" value="$form->{"${item}_description"}">
+|;
+  }
+
+}
+
+
+sub form_footer {
+
+  $form->{invtotal} = $form->{invsubtotal};
+
+  if (($rows = $form->numtextrows($form->{notes}, 50, 8)) < 2) {
+    $rows = 2;
+  }
+  $notes = qq|<textarea name=notes rows=$rows cols=50 wrap=soft>$form->{notes}</textarea>|;
+
+  $taxincluded = "";
+  $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : "";
+  if ($form->{taxaccounts}) {
+    $taxincluded = qq|
+               <input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}> <b>|.$locale->text('Tax Included').qq|</b><br><br>
+|;
+  }
+
+  if (!$form->{taxincluded}) {
+    
+    foreach $item (split / /, $form->{taxaccounts}) {
+      if ($form->{"${item}_base"}) {
+       $form->{invtotal} += $form->{"${item}_total"} = $form->round_amount($form->{"${item}_base"} * $form->{"${item}_rate"}, 2);
+       $form->{"${item}_total"} = $form->format_amount(\%myconfig, $form->{"${item}_total"}, 2);
+       
+       $tax .= qq|
+             <tr>
+               <th align=right>$form->{"${item}_description"}</th>
+               <td align=right>$form->{"${item}_total"}</td>
+             </tr>
+|;
+      }
+    }
+
+    $form->{invsubtotal} = $form->format_amount(\%myconfig, $form->{invsubtotal}, 2, 0);
+    
+    $subtotal = qq|
+             <tr>
+               <th align=right>|.$locale->text('Subtotal').qq|</th>
+               <td align=right>$form->{invsubtotal}</td>
+             </tr>
+|;
+
+  }
+
+  $form->{oldinvtotal} = $form->{invtotal};
+  $form->{invtotal} = $form->format_amount(\%myconfig, $form->{invtotal}, 2, 0);
+
+  print qq|
+  <tr>
+    <td>
+      <table width=100%>
+       <tr valign=bottom>
+         <td>
+           <table>
+             <tr>
+               <th align=left>|.$locale->text('Notes').qq|</th>
+             </tr>
+             <tr>
+               <td>$notes</td>
+             </tr>
+           </table>
+         </td>
+         <td align=right width=100%>
+           $taxincluded
+           <table width=100%>
+             $subtotal
+             $tax
+             <tr>
+               <th align=right>|.$locale->text('Total').qq|</th>
+               <td align=right>$form->{invtotal}</td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+<input type=hidden name=oldinvtotal value=$form->{oldinvtotal}>
+<input type=hidden name=oldtotalpaid value=$totalpaid>
+  <tr>
+    <td>
+|;
+
+  &print_options;
+
+  print qq|
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('Ship to').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('Print').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('E-mail').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('Save').qq|">
+|;
+
+    if ($form->{id}) {
+      print qq|
+<input class=submit type=submit name=action value="|.$locale->text('Save as new').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('Delete').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('Invoice').qq|">
+|;
+    }
+
+  print qq| 
+
+<input type=hidden name=rowcount value=$form->{rowcount}>
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub update {
+
+  map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate creditlimit creditremaining);
+
+  &check_name($form->{vc});
+
+  &check_project;
+
+  $buysell = 'buy';
+  $buysell = 'sell' if ($form->{vc} eq 'vendor');
+  $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{orddate}, $buysell)));
+  
+
+  my $i = $form->{rowcount};
+  $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1;
+
+  if (($form->{"partnumber_$i"} eq "") && ($form->{"description_$i"} eq "") && ($form->{"partsgroup_$i"} eq "")) {
+
+    $form->{creditremaining} += ($form->{oldinvtotal} - $form->{oldtotalpaid});
+    &check_form;
+
+  } else {
+   
+    if ($form->{type} eq 'purchase_order') {
+      IR->retrieve_item(\%myconfig, \%$form);
+    }
+    if ($form->{type} eq 'sales_order') {
+      IS->retrieve_item(\%myconfig, \%$form);
+    }
+
+    my $rows = scalar @{ $form->{item_list} };
+    
+    $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{discount} * 100);
+
+    if ($rows) {
+      $form->{"qty_$i"}                     = 1 unless ($form->{"qty_$i"});
+      
+      if ($rows > 1) {
+       
+       &select_item;
+       exit;
+       
+      } else {
+       
+       $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
+       
+       map { $form->{item_list}[$i]{$_} =~ s/"/&quot;/g } qw(partnumber description unit);
+       map { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } keys %{ $form->{item_list}[0] };
+
+       $s = ($sellprice) ? $sellprice : $form->{"sellprice_$i"};
+       
+       ($dec) = ($s =~ /\.(\d+)/);
+       $dec = length $dec;
+       $decimalplaces = ($dec > 2) ? $dec : 2;
+
+        if ($sellprice) {
+         $form->{"sellprice_$i"} = $sellprice;
+       } else {
+         # if there is an exchange rate adjust sellprice
+         $form->{"sellprice_$i"} /= $exchangerate;
+       }
+       
+       $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * (1 - $form->{"discount_$i"} / 100);
+       map { $form->{"${_}_base"} = 0 } (split / /, $form->{taxaccounts});
+       map { $form->{"${_}_base"} += $amount } (split / /, $form->{"taxaccounts_$i"});
+       map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{taxaccounts} if !$form->{taxincluded};
+       
+       $form->{creditremaining} -= $amount;
+       
+       $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
+       $form->{"qty_$i"} =  $form->format_amount(\%myconfig, $form->{"qty_$i"});
+      }
+
+      &display_form;
+
+    } else {
+      # ok, so this is a new part
+      # ask if it is a part or service item
+      
+      if ($form->{"partsgroup_$i"} && ($form->{"partsnumber_$i"} eq "") && ($form->{"description_$i"} eq "")) {
+       $form->{rowcount}--;
+       $form->{"discount_$i"} = "";
+       &display_form;
+      } else {
+       
+       $form->{"id_$i"}                = 0;
+       $form->{"unit_$i"}      = $locale->text('ea');
+
+       &new_item;
+
+      }
+    }
+  }
+}
+
+
+
+sub search {
+  
+  if ($form->{type} eq 'purchase_order') {
+    $form->{title} = $locale->text('Purchase Orders');
+    $form->{vc} = 'vendor';
+  }
+  if ($form->{type} eq 'sales_order') {
+    $form->{title} = $locale->text('Sales Orders');
+    $form->{vc} = 'customer';
+  }
+
+  # setup vendor / customer selection
+  $form->all_vc(\%myconfig, "$form->{vc}");
+
+  map { $vc .= "<option>$_->{name}--$_->{id}\n" } @{ $form->{"all_$form->{vc}"} };
+
+  $vclabel = ucfirst $form->{vc};
+  $vclabel = $locale->text($vclabel);
+  
+# $locale->text('Vendor')
+# $locale->text('Customer')
+  
+  $vc = ($vc) ? qq|<select name=$form->{vc}><option>\n$vc</select>| : qq|<input name=$form->{vc} size=35>|;
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table>
+        <tr>
+          <th align=right>$vclabel</th>
+          <td colspan=3>$vc</td>
+        </tr>
+        <tr>
+          <th align=right>|.$locale->text('Order Number').qq|</th>
+          <td colspan=3><input name=ordnumber size=20></td>
+        </tr>
+        <tr>
+          <th align=right>|.$locale->text('From').qq|</th>
+          <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td>
+          <th align=right>|.$locale->text('to').qq|</th>
+          <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td>
+        </tr>
+        <input type=hidden name=sort value=transdate>
+        <tr>
+          <th align=right>|.$locale->text('Include in Report').qq|</th>
+          <td colspan=3>
+           <table>
+             <tr>
+               <td><input name="open" class=checkbox type=checkbox value=1 checked> |.$locale->text('Open').qq|</td>
+               <td><input name="closed" class=checkbox type=checkbox value=1 $form->{closed}> |.$locale->text('Closed').qq|</td>
+             </tr>
+             <tr>
+               <td><input name="l_id" class=checkbox type=checkbox value=Y> |.$locale->text('ID').qq|</td>
+               <td><input name="l_ordnumber" class=checkbox type=checkbox value=Y checked> |.$locale->text('Order Number').qq|</td>
+               <td><input name="l_transdate" class=checkbox type=checkbox value=Y checked> |.$locale->text('Order Date').qq|</td>
+               <td><input name="l_reqdate" class=checkbox type=checkbox value=Y checked> |.$locale->text('Required by').qq|</td>
+             </tr>
+             <tr>
+               <td><input name="l_name" class=checkbox type=checkbox value=Y checked> $vclabel</td>
+               <td><input name="l_netamount" class=checkbox type=checkbox value=Y> |.$locale->text('Amount').qq|</td>
+               <td><input name="l_tax" class=checkbox type=checkbox value=Y> |.$locale->text('Tax').qq|</td>
+               <td><input name="l_amount" class=checkbox type=checkbox value=Y checked> |.$locale->text('Total').qq|</td>
+             </tr>
+             <tr>
+               <td><input name="l_subtotal" class=checkbox type=checkbox value=Y> |.$locale->text('Subtotal').qq|</td>
+             </tr>
+           </table>
+          </td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+  <tr><td colspan=4><hr size=3 noshade></td></tr>
+</table>
+
+<br>
+<input type=hidden name=nextsub value=orders>
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+<input type=hidden name=vc value=$form->{vc}>
+<input type=hidden name=type value=$form->{type}>
+
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub orders {
+
+  $name = $form->{$form->{vc}};
+  
+  # split vendor / customer
+  ($form->{$form->{vc}}, $form->{"$form->{vc}_id"}) = split(/--/, $form->{$form->{vc}});
+
+  OE->transactions(\%myconfig, \%$form);
+
+  # construct href
+  $href = "$form->{script}?path=$form->{path}&action=orders&type=$form->{type}&vc=$form->{vc}&login=$form->{login}&password=$form->{password}&transdatefrom=$form->{transdatefrom}&transdateto=$form->{transdateto}&open=$form->{open}&closed=$form->{closed}&ordnumber=" . $form->escape($form->{ordnumber}) . "&$form->{vc}=" . $form->escape($form->{$form->{vc}});
+
+  # construct callback
+  $name =~ s/&/_/g;
+  $callback = "$form->{script}?path=$form->{path}&action=orders&type=$form->{type}&vc=$form->{vc}&login=$form->{login}&password=$form->{password}&transdatefrom=$form->{transdatefrom}&transdateto=$form->{transdateto}&open=$form->{open}&closed=$form->{closed}&ordnumber=$form->{ordnumber}&$form->{vc}=$name";
+
+  @columns = $form->sort_columns(qw(transdate reqdate id ordnumber name netamount tax amount curr open closed));
+
+  $form->{l_open} = $form->{l_closed} = "Y" if ($form->{open} && $form->{closed}) ;
+
+  foreach $item (@columns) {
+    if ($form->{"l_$item"} eq "Y") {
+      push @column_index, $item;
+      
+      # add column to href and callback
+      $callback .= "&l_$item=Y";
+      $href .= "&l_$item=Y";
+    }
+  }
+  
+  if ($form->{l_subtotal} eq 'Y') {
+    $callback .= "&l_subtotal=Y";
+    $href .= "&l_subtotal=Y";
+  }
+  if ($form->{vc} eq 'vendor') {
+    $form->{title} = $locale->text('Purchase Orders');
+    $name = $locale->text('Vendor');
+  }
+  if ($form->{vc} eq 'customer') {
+    $form->{title} = $locale->text('Sales Orders');
+    $name = $locale->text('Customer');
+  }
+  $column_header{id} = qq|<th><a class=listheading href=$href&sort=id>|.$locale->text('ID').qq|</a></th>|;
+  $column_header{transdate} = qq|<th><a class=listheading href=$href&sort=transdate>|.$locale->text('Date').qq|</a></th>|;
+  $column_header{reqdate} = qq|<th><a class=listheading href=$href&sort=reqdate>|.$locale->text('Required by').qq|</a></th>|;
+  $column_header{ordnumber} = qq|<th><a class=listheading href=$href&sort=ordnumber>|.$locale->text('Order').qq|</a></th>|;
+  $column_header{name} = qq|<th><a class=listheading href=$href&sort=name>$name</a></th>|;
+  $column_header{netamount} = qq|<th class=listheading>|.$locale->text('Amount').qq|</th>|;
+  $column_header{tax} = qq|<th class=listheading>|.$locale->text('Tax').qq|</th>|;
+  $column_header{amount} = qq|<th class=listheading>|.$locale->text('Total').qq|</th>|;
+  $column_header{curr} = qq|<th class=listheading>|.$locale->text('Curr').qq|</th>|;
+  $column_header{open} = qq|<th class=listheading>|.$locale->text('O').qq|</th>|;
+  $column_header{closed} = qq|<th class=listheading>|.$locale->text('C').qq|</th>|;
+
+  if ($form->{open}) {
+    $option = $locale->text('Open');
+  }
+  if ($form->{closed}) {
+    $option .= " : " if $form->{open};
+    $option .= $locale->text('Closed');
+  }
+  if ($form->{$form->{vc}}) {
+    $option .= "\n<br>";
+    $option .= ucfirst $form->{vc};
+    $option .= " : $form->{$form->{vc}}";
+  }
+  if ($form->{transdatefrom}) {
+    $option .= "\n<br>".$locale->text('From')." ".$locale->date(\%myconfig, $form->{transdatefrom}, 1);
+  }
+  if ($form->{transdateto}) {
+    $option .= "\n<br>".$locale->text('to')." ".$locale->date(\%myconfig, $form->{transdateto}, 1);
+  }
+  
+  $form->header;
+
+  $colspan = $#column_index + 1;
+
+  print qq|
+<body>
+
+<table width=100%>
+  <tr><th class=listtop colspan=$colspan>$form->{title}</th></tr>
+  <tr height="5"></tr>
+  <tr>
+    <td colspan=$colspan>$option</td>
+  </tr>
+  <tr class=listheading>|;
+
+map { print "\n$column_header{$_}" } @column_index;
+
+print qq|
+  </tr>
+|;
+
+  # add sort and escape callback
+  $callback = $form->escape($callback . "&sort=$form->{sort}");
+
+  if (@{ $form->{OE} }) {
+    $sameitem = $form->{OE}->[0]->{$form->{sort}};
+  }
+
+  foreach $oe (@{ $form->{OE} }) {
+
+    if ($form->{l_subtotal} eq 'Y') {
+      if ($sameitem ne $oe->{$form->{sort}}) {
+       &subtotal;
+       $sameitem = $oe->{$form->{sort}};
+      }
+    }
+    
+    map { $oe->{$_} *= $oe->{exchangerate} } (qw(netamount amount));
+    
+    $column_data{netamount} = "<td align=right>".$form->format_amount(\%myconfig, $oe->{netamount}, 2, "&nbsp;")."</td>";
+    $column_data{tax} = "<td align=right>".$form->format_amount(\%myconfig, $oe->{amount} - $oe->{netamount}, 2, "&nbsp;")."</td>";
+    $column_data{amount} = "<td align=right>".$form->format_amount(\%myconfig, $oe->{amount}, 2, "&nbsp;")."</td>";
+
+    $totalnetamount += $oe->{netamount};
+    $totalamount += $oe->{amount};
+
+    $subtotalnetamount += $oe->{netamount};
+    $subtotalamount += $oe->{amount};
+
+    $column_data{id} = "<td>$oe->{id}</td>";
+    $column_data{transdate} = "<td>$oe->{transdate}&nbsp;</td>";
+    $column_data{reqdate} = "<td>$oe->{reqdate}&nbsp;</td>";
+
+    $column_data{ordnumber} = "<td><a href=oe.pl?path=$form->{path}&action=edit&type=$form->{type}&id=$oe->{id}&login=$form->{login}&password=$form->{password}&callback=$callback>$oe->{ordnumber}</a></td>";
+    $column_data{name} = "<td>$oe->{name}</td>";
+
+    if ($oe->{closed}) {
+      $column_data{closed} = "<td align=center>X</td>";
+      $column_data{open} = "<td>&nbsp;</td>";
+    } else {
+      $column_data{closed} = "<td>&nbsp;</td>";
+      $column_data{open} = "<td align=center>X</td>";
+    }
+
+    $i++; $i %= 2;
+    print "<tr class=listrow$i>";
+    
+    map { print "\n$column_data{$_}" } @column_index;
+
+    print qq|
+    </tr>
+|;
+
+  }
+  
+  if ($form->{l_subtotal} eq 'Y') {
+    &subtotal;
+  }
+  
+  # print totals
+  print qq|<tr class=listtotal>|;
+  
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+  
+  $column_data{netamount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalnetamount, 2, "&nbsp;")."</th>";
+  $column_data{tax} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount - $totalnetamount, 2, "&nbsp;")."</th>";
+  $column_data{amount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount, 2, "&nbsp;")."</th>";
+
+  map { print "\n$column_data{$_}" } @column_index;
+
+  print qq|
+  </tr>
+  <tr><td colspan=8><hr size=3 noshade></td></tr>
+</table>
+
+<br>
+<form method=post action=$form->{script}>
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=type value=$form->{type}>
+<input type=hidden name=vc value=$form->{vc}>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input class=submit type=submit name=action value=|.$locale->text('Add').qq|
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+sub subtotal {
+
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+  
+  $column_data{netamount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalnetamount, 2, "&nbsp;")."</th>";
+  $column_data{tax} = "<td class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount - $subtotalnetamount, 2, "&nbsp;")."</th>";
+  $column_data{amount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount, 2, "&nbsp;")."</th>";
+
+  $subtotalnetamount = 0;
+  $subtotalamount = 0;
+
+  print "<tr class=listsubtotal>";
+  
+  map { print "\n$column_data{$_}" } @column_index;
+
+  print qq|
+  </tr>
+|;
+
+}
+
+
+sub save {
+
+  $form->isblank("ordnumber", $locale->text('Order Number missing!'));
+  $form->isblank("orddate", $locale->text('Order Date missing!'));
+  
+  $msg = ucfirst $form->{vc};
+  $form->isblank($form->{vc}, $locale->text($msg . " missing!"));
+
+# $locale->text('Customer missing!');
+# $locale->text('Vendor missing!');
+  
+  $form->isblank("exchangerate", $locale->text('Exchangerate missing!')) if ($form->{currency} ne $form->{defaultcurrency});
+  
+  &validate_items;
+
+  # if the name changed get new values
+  if (&check_name($form->{vc})) {
+    &update;
+    exit;
+  }
+
+
+  # this is for the notes section for the [email] Subject
+  $form->{label} = ($form->{type} eq 'sales_order') ? $locale->text('Sales Order') : $locale->text('Purchase Order');
+
+  $form->{id} = 0 if $form->{saveasnew};
+  
+  $form->redirect($locale->text('Order saved!')) if (OE->save_order(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot save order!'));
+  
+}
+
+
+
+sub delete {
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+|;
+
+  # delete action variable
+  delete $form->{action};
+
+  foreach $key (keys %$form) {
+    $form->{$key} =~ s/"/&quot;/g;
+    print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
+  }
+
+  print qq|
+<h2 class=confirm>|.$locale->text('Confirm!').qq|</h2>
+
+<h4>|
+  .$locale->text('Are you sure you want to delete Order Number').qq| $form->{ordnumber}
+</h4>
+<p>
+<input name=action class=submit type=submit value="|.$locale->text('Yes').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+
+}
+
+
+
+sub yes {
+
+  $form->redirect($locale->text('Order deleted!')) if (OE->delete_order(\%myconfig, \%$form));
+  $form->error($locale->text('Cannot delete order!'));
+
+}
+
+
+sub invoice {
+  
+  $form->isblank("ordnumber", $locale->text('Order Number missing!'));
+  $form->isblank("orddate", $locale->text('Order Date missing!'));
+
+
+  # if the name changed get new values
+  if (&check_name($form->{vc})) {
+    &update;
+    exit;
+  }
+
+  $form->{closed} = 1;
+  OE->save_order(\%myconfig, \%$form);
+  
+  $form->{orddate} = $form->{transdate} = $form->{invdate} = $form->current_date(\%myconfig);
+  $form->{duedate} = $form->current_date(\%myconfig, $form->{invdate}, $form->{terms} * 1);
+  $form->{id} = '';
+  $form->{closed} = 0;
+  $form->{rowcount}--;
+  $form->{shipto} = 1;
+
+  &create_backorder;
+
+  if ($form->{type} eq 'purchase_order') {
+    $form->{title} = $locale->text('Add Vendor Invoice');
+    $form->{script} = 'ir.pl';
+    $script = "ir";
+    $buysell = 'sell';
+  }
+  if ($form->{type} eq 'sales_order') {
+    $form->{title} = $locale->text('Add Sales Invoice');
+    $form->{script} = 'is.pl';
+    $script = "is";
+    $buysell = 'buy';
+  }
+  
+  # bo creates the id, reset it
+  map { $form->{$_} = "" } qw(id subject message cc bcc);
+  $form->{$form->{vc}} =~ s/--.*//g;
+  $form->{type} = "invoice";
+  # locale messages
+  $locale = new Locale "$myconfig{countrycode}", "$script";
+
+  require "$form->{path}/$form->{script}";
+
+  map { $form->{"select$_"} = "" } ($form->{vc}, currency);
+
+  map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(creditlimit creditremaining);
+
+  $currency = $form->{currency};
+  &invoice_links;
+
+  $form->{currency} = $currency;
+  $form->{exchangerate} = "";
+  $form->{forex} = "";
+  $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{invdate}, $buysell)));
+  $form->{creditremaining} -= ($form->{oldinvtotal} - $form->{ordtotal});
+
+  &prepare_invoice;
+
+  # format amounts
+  for $i (1 .. $form->{rowcount}) {
+    $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"});
+
+    ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
+    $dec = length $dec;
+    $decimalplaces = ($dec > 2) ? $dec : 2;
+
+    $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
+    $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"});
+
+    map { $form->{"${_}_$i"} =~ s/"/&quot;/g } qw(partnumber description unit);
+  }
+
+  &display_form;
+
+}
+
+
+sub create_backorder {
+
+  # figure out if we need to create a backorder
+  # items aren't saved if qty != 0
+
+  for $i (1 .. $form->{rowcount}) {
+    $totalqty += $qty = $form->parse_amount($myconfig, $form->{"qty_$i"});
+    $totalship += $ship = $form->parse_amount($myconfig, $form->{"ship_$i"});
+    
+    $form->{"qty_$i"} = $qty - $ship;
+  }
+
+  if ($totalship == 0) {
+    map { $form->{"ship_$_"} = $form->{"qty_$_"} } (1 .. $form->{rowcount});
+    $form->{ordtotal} = 0;
+    return;
+  }
+
+  if ($totalqty == $totalship) {
+    map { $form->{"qty_$_"} = $form->{"ship_$_"} } (1 .. $form->{rowcount});
+    $form->{ordtotal} = 0;
+    return;
+  }
+
+  @flds = (qw(partnumber description qty ship unit sellprice discount id inventory_accno bin income_accno expense_accno listprice assembly taxaccounts));
+
+  OE->save_order(\%myconfig, \%$form);
+  
+  # rebuild rows for invoice
+  @a = ();
+  $count = 0;
+
+  for $i (1 .. $form->{rowcount}) {
+    
+    # reformat values if there was a backorder quantity
+    if ($form->{"qty_$i"}) {
+      $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"});
+      $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"});
+    }
+
+    $form->{"qty_$i"} = $form->{"ship_$i"};
+
+    if ($form->{"qty_$i"}) {
+      push @a, {};
+      $j = $#a;
+      map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
+      $count++;
+    }
+  }
+  $form->redo_rows(\@flds, \@a, $count, $form->{rowcount});
+  $form->{rowcount} = $count;
+  
+}
+
+
+
+sub save_as_new {
+
+  $form->{saveasnew} = 1;
+  $form->{closed} = 0;
+  &save;
+
+}
+
+
diff --git a/sql-ledger/bin/mozilla/pe.pl b/sql-ledger/bin/mozilla/pe.pl
new file mode 100644 (file)
index 0000000..d8706d4
--- /dev/null
@@ -0,0 +1,549 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# project administration
+# partsgroup administration
+#
+#======================================================================
+
+
+use SL::PE;
+
+1;
+# end of main
+
+
+
+sub add {
+  
+  $form->{title} = "Add";
+
+  # construct callback
+  $form->{callback} = "$form->{script}?action=add&type=$form->{type}&path=$form->{path}&login=$form->{login}&password=$form->{password}" unless $form->{callback};
+
+  &{ "form_$form->{type}_header" };
+  &{ "form_$form->{type}_footer" };
+  
+}
+
+
+sub edit {
+  
+  $form->{title} = "Edit";
+
+  if ($form->{type} eq 'project') {
+    PE->get_project(\%myconfig, \%$form);
+  }
+  if ($form->{type} eq 'partsgroup') {
+    PE->get_partsgroup(\%myconfig, \%$form);
+  }
+
+  &{ "form_$form->{type}_header" };
+  &{ "form_$form->{type}_footer" };
+  
+}
+
+
+sub search {
+
+  if ($form->{type} eq 'project') {
+    $report = "project_report";
+    $sort = 'projectnumber';
+    $form->{title} = $locale->text('Projects');
+
+    $number = qq|
+       <tr>
+         <th align=right width=1%>|.$locale->text('Number').qq|</th>
+         <td><input name=projectnumber size=20></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Description').qq|</th>
+         <td><input name=description size=60></td>
+       </tr>
+|;
+
+  }
+  if ($form->{type} eq 'partsgroup') {
+    $report = "partsgroup_report";
+    $sort = 'partsgroup';
+    $form->{title} = $locale->text('Groups');
+    
+    $number = qq|
+       <tr>
+         <th align=right width=1%>|.$locale->text('Group').qq|</th>
+         <td><input name=partsgroup size=20></td>
+       </tr>
+|;
+
+  }
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=sort value=$sort>
+<input type=hidden name=type value=$form->{type}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table width=100%>
+        $number
+       <tr>
+         <td></td>
+         <td><input name=status class=radio type=radio value=all checked>&nbsp;|.$locale->text('All').qq|
+         <input name=status class=radio type=radio value=orphaned>&nbsp;|.$locale->text('Orphaned').qq|</td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<input type=hidden name=nextsub value=$report>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+sub project_report {
+
+  map { $form->{$_} = $form->unescape($form->{$_}) } (projectnumber, description);
+  PE->projects(\%myconfig, \%$form);
+
+  $callback = "$form->{script}?action=project_report&type=$form->{type}&path=$form->{path}&login=$form->{login}&password=$form->{password}&status=$form->{status}";
+  $href = $callback;
+  
+  if ($form->{status} eq 'all') {
+    $option = $locale->text('All');
+  }
+  if ($form->{status} eq 'orphaned') {
+    $option .= $locale->text('Orphaned');
+  }
+  if ($form->{projectnumber}) {
+    $href .= "&projectnumber=".$form->escape($form->{projectnumber});
+    $callback .= "&projectnumber=$form->{projectnumber}";
+    $option .= "\n<br>".$locale->text('Project')." : $form->{projectnumber}";
+  }
+  if ($form->{description}) {
+    $href .= "&description=".$form->escape($form->{description});
+    $callback .= "&description=$form->{description}";
+    $option .= "\n<br>".$locale->text('Description')." : $form->{description}";
+  }
+    
+
+  @column_index = $form->sort_columns(qw(projectnumber description));
+
+  $column_header{projectnumber} = qq|<th><a class=listheading href=$href&sort=projectnumber>|.$locale->text('Number').qq|</a></th>|;
+  $column_header{description} = qq|<th><a class=listheading href=$href&sort=description>|.$locale->text('Description').qq|</a></th>|;
+
+  $form->{title} = $locale->text('Projects');
+
+  $form->header;
+  print qq|
+<body>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>$option</td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+|;
+
+  map { print "$column_header{$_}\n" } @column_index;
+  
+  print qq|
+        </tr>
+|;
+
+  # escape callback
+  $form->{callback} = $callback .= "&sort=$form->{sort}";
+
+  # escape callback for href
+  $callback = $form->escape($callback);
+  
+  foreach $ref (@{ $form->{project_list} }) {
+    
+    $i++; $i %= 2;
+    
+    print qq|
+        <tr valign=top class=listrow$i>
+|;
+    
+    $column_data{projectnumber} = qq|<td><a href=$form->{script}?action=edit&type=$form->{type}&status=$form->{status}&id=$ref->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{projectnumber}</td>|;
+    $column_data{description} = qq|<td>$ref->{description}&nbsp;</td>|;
+    
+    map { print "$column_data{$_}\n" } @column_index;
+    
+    print "
+        </tr>
+";
+  }
+  
+  print qq|
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<br>
+<form method=post action=$form->{script}>
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=type value=$form->{type}>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input class=submit type=submit name=action value="|.$locale->text('Add').qq|">
+
+</body>
+</html>
+|;
+
+}
+
+
+sub form_project_header {
+
+  $form->{title} = $locale->text("$form->{title} Project");
+  
+# $locale->text('Add Project')
+# $locale->text('Edit Project')
+
+  $form->{description} =~ s/"/&quot;/g;
+
+  if (($rows = $form->numtextrows($form->{description}, 60)) > 1) {
+    $description = qq|<textarea name="description" rows=$rows cols=60 style="width: 100%" wrap=soft>$form->{description}</textarea>|;
+  } else {
+    $description = qq|<input name=description size=60 value="$form->{description}">|;
+  }
+  
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=id value=$form->{id}>
+<input type=hidden name=type value=project>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table>
+       <tr>
+         <th align=right>|.$locale->text('Number').qq|</th>
+         <td><input name=projectnumber size=20 value="$form->{projectnumber}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Description').qq|</th>
+         <td>$description</td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td colspan=2><hr size=3 noshade></td>
+  </tr>
+</table>
+|;
+
+}
+
+
+sub form_project_footer {
+
+  print qq|
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br><input type=submit class=submit name=action value="|.$locale->text('Save').qq|">
+|;
+
+  if ($form->{id} && $form->{orphaned}) {
+    print qq|
+<input type=submit class=submit name=action value="|.$locale->text('Delete').qq|">|;
+  }
+
+  print qq|
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub save {
+
+  if ($form->{type} eq 'project') {
+    $form->isblank("projectnumber", $locale->text('Project Number missing!'));
+    PE->save_project(\%myconfig, \%$form);
+    $form->redirect($locale->text('Project saved!'));
+  }
+  if ($form->{type} eq 'partsgroup') {
+    $form->isblank("partsgroup", $locale->text('Group missing!'));
+    PE->save_partsgroup(\%myconfig, \%$form);
+    $form->redirect($locale->text('Group saved!'));
+  }
+
+}
+
+
+sub delete {
+
+  PE->delete_tuple(\%myconfig, \%$form);
+  
+  if ($form->{type} eq 'project') { 
+    $form->redirect($locale->text('Project deleted!'));
+  }
+  if ($form->{type} eq 'partsgroup') {
+    $form->redirect($locale->text('Group deleted!'));
+  }
+
+}
+
+
+sub continue { &{ $form->{nextsub} } };
+
+
+sub partsgroup_report {
+
+  map { $form->{$_} = $form->unescape($form->{$_}) } (partsgroup);
+  PE->partsgroups(\%myconfig, \%$form);
+
+  $callback = "$form->{script}?action=partsgroup_report&type=$form->{type}&path=$form->{path}&login=$form->{login}&password=$form->{password}&status=$form->{status}";
+  
+  if ($form->{status} eq 'all') {
+    $option = $locale->text('All');
+  }
+  if ($form->{status} eq 'orphaned') {
+    $option .= $locale->text('Orphaned');
+  }
+  if ($form->{partsgroup}) {
+    $callback .= "&partsgroup=$form->{partsgroup}";
+    $option .= "\n<br>".$locale->text('Group')." : $form->{partsgroup}";
+  }
+   
+
+  @column_index = (partsgroup);
+
+  $column_header{partsgroup} = qq|<th class=listheading width=90%>|.$locale->text('Group').qq|</th>|;
+
+  $form->{title} = $locale->text('Groups');
+
+  $form->header;
+  print qq|
+<body>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>$option</td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+|;
+
+  map { print "$column_header{$_}\n" } @column_index;
+  
+  print qq|
+        </tr>
+|;
+
+  # escape callback
+  $form->{callback} = $callback;
+
+  # escape callback for href
+  $callback = $form->escape($callback);
+  
+  foreach $ref (@{ $form->{item_list} }) {
+    
+    $i++; $i %= 2;
+    
+    print qq|
+        <tr valign=top class=listrow$i>
+|;
+    
+
+    $column_data{partsgroup} = qq|<td><a href=$form->{script}?action=edit&type=$form->{type}&status=$form->{status}&id=$ref->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{partsgroup}</td>|;
+    
+    map { print "$column_data{$_}\n" } @column_index;
+    
+    print "
+        </tr>
+";
+  }
+  
+  print qq|
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<br>
+<form method=post action=$form->{script}>
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=type value=$form->{type}>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input class=submit type=submit name=action value="|.$locale->text('Add').qq|">
+
+</body>
+</html>
+|;
+
+}
+
+
+sub form_partsgroup_header {
+
+  $form->{title} = $locale->text("$form->{title} Group");
+  
+# $locale->text('Add Group')
+# $locale->text('Edit Group')
+
+  $form->{partsgroup} =~ s/"/&quot;/g;
+
+  
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=id value=$form->{id}>
+<input type=hidden name=type value=$form->{type}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr>
+         <th align=right>|.$locale->text('Group').qq|</th>
+          <td><input name=partsgroup size=30 value="$form->{partsgroup}"></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td colspan=2><hr size=3 noshade></td>
+  </tr>
+</table>
+|;
+
+}
+
+
+sub form_partsgroup_footer {
+
+  print qq|
+
+<input name=callback type=hidden value="$form->{callback}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br><input type=submit class=submit name=action value="|.$locale->text('Save').qq|">
+|;
+
+  if ($form->{id} && $form->{orphaned}) {
+    print qq|
+<input type=submit class=submit name=action value="|.$locale->text('Delete').qq|">|;
+  }
+
+  print qq|
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
diff --git a/sql-ledger/bin/mozilla/rc.pl b/sql-ledger/bin/mozilla/rc.pl
new file mode 100644 (file)
index 0000000..cf2bc23
--- /dev/null
@@ -0,0 +1,371 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Account reconciliation module
+#
+#======================================================================
+
+
+use SL::RC;
+
+
+1;
+# end of main
+
+
+sub reconciliation {
+  
+  RC->paymentaccounts(\%myconfig, \%$form);
+
+  $selection = "";
+  map { $selection .= "<option>$_->{accno}--$_->{description}\n" } @{ $form->{PR} };
+
+  $form->{title} = $locale->text('Reconciliation');
+
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Account').qq|</th>
+         <td colspan=3><select name=accno>$selection</select>
+         </td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('From').qq|</th>
+         <td><input name=fromdate size=11 title="$myconfig{dateformat}"></td>
+         <th align=right>|.$locale->text('to').qq|</th>
+         <td><input name=todate size=11 title="$myconfig{dateformat}"></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<br>
+<input type=hidden name=nextsub value=get_payments>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|">
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub continue { &{ $form->{nextsub} } };
+
+
+sub get_payments {
+
+  ($form->{accno}, $form->{account}) = split /--/, $form->{accno};
+
+  RC->payment_transactions(\%myconfig, \%$form);
+  &display_form;
+
+}
+
+
+sub display_form {
+  
+  @column_index = qw(cleared transdate source name credit debit balance);
+  
+  $column_header{cleared} = "<th class=listheading>&nbsp;</th>";
+  $column_header{source} = "<th class=listheading>".$locale->text('Source')."</a></th>";
+  $column_header{name} = "<th class=listheading>".$locale->text('Description')."</a></th>";
+  $column_header{transdate} = "<th class=listheading>".$locale->text('Date')."</a></th>";
+
+  $column_header{debit} = "<th class=listheading>".$locale->text('Deposit')."</a></th>";
+  $column_header{credit} = "<th class=listheading>".$locale->text('Payment')."</a></th>";
+
+  $column_header{balance} = "<th class=listheading>".$locale->text('Balance')."</a></th>";
+
+  if ($form->{fromdate}) {
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('From')."&nbsp;".$locale->date(\%myconfig, $form->{fromdate}, 1);
+  }
+  if ($form->{todate}) {
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('to')."&nbsp;".$locale->date(\%myconfig, $form->{todate}, 1);
+  }
+
+  $form->{title} = "$form->{accno}--$form->{account}";
+  
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>$option</td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr>
+|;
+
+  map { print "\n$column_header{$_}" } @column_index;
+
+  print qq|
+        </tr>
+|;
+
+  $form->{beginningbalance} *= -1;
+  $clearedbalance = $balance = $form->{beginningbalance};
+  $i = 0;
+  $id = 0;
+
+  map { $column_data{$_} = "<td>&nbsp;</td>" } qw(cleared transdate source name debit credit);
+  $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $balance, 2, 0)."</td>";
+  $j = 0;
+  print qq|
+        <tr class=listrow$j>
+|;
+
+  map { print "\n$column_data{$_}" } @column_index;
+
+  print qq|
+        </tr>
+|;
+  
+
+  foreach $ref (@{ $form->{PR} }) {
+
+    $balance += $ref->{amount} * -1;
+    $cleared += $ref->{amount} * -1 if $ref->{cleared};
+
+    $column_data{name} = "<td>$ref->{name}&nbsp;</td>";
+    $column_data{source} = qq|<td>$ref->{source}&nbsp;</a>
+    </td>|;
+    $column_data{transdate} = "<td>$ref->{transdate}&nbsp;</td>";
+    
+    $column_data{debit} = "<td>&nbsp;</td>";
+    $column_data{credit} = "<td>&nbsp;</td>";
+    
+    if ($ref->{amount} < 0) {
+      $totaldebits += $ref->{amount} * -1;
+      $column_data{debit} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{amount} * -1, 2, "&nbsp;")."</td>";
+    } else {
+      $totalcredits += $ref->{amount};
+      $column_data{credit} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{amount}, 2, "&nbsp;")."</td>";
+    }
+    
+    $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $balance, 2, 0)."</td>";
+
+    if ($ref->{fx_transaction}) {
+      $i++ unless $id == $ref->{id};
+      $fx_transaction = 1;
+      $fx += $ref->{amount} * -1;
+      $column_data{cleared} = qq|<td align=center>&nbsp;
+      <input type=hidden name="fxoid_$i" value=$ref->{oid}>
+      </td>|;
+    } else {
+      $i++ unless ($fx_transaction && $id == $ref->{id});
+      $fx_transaction = 0;
+      $column_data{cleared} = qq|<td>
+      <input name="cleared_$i" type=checkbox class=checkbox value=1 $ref->{cleared}>
+      <input type=hidden name="oid_$i" value=$ref->{oid}>
+      </td>|;
+    }
+    $id = $ref->{id};
+
+    $j++; $j %= 2;
+    print qq|
+       <tr class=listrow$j>
+|;
+
+    map { print "\n$column_data{$_}" } @column_index;
+
+    print qq|
+       </tr>
+|;
+
+  }
+
+  # print totals
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+
+  $column_data{debit} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totaldebits, 2, "&nbsp;")."</th>";
+  $column_data{credit} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalcredits, 2, "&nbsp;")."</th>";
+   
+  print qq|
+       <tr class=listtotal>
+|;
+
+  map { print "\n$column_data{$_}" } @column_index;
+
+  $form->{statementbalance} = $form->parse_amount(\%myconfig, $form->{statementbalance});
+  $difference = $form->format_amount(\%myconfig, $form->{statementbalance} - $clearedbalance - $cleared, 2, 0);
+  
+  $form->{statementbalance} = $form->format_amount(\%myconfig, $form->{statementbalance}, 2, 0);
+
+  $clearedbalance = $form->format_amount(\%myconfig, $clearedbalance, 2, 0);
+  
+  if ($fx) {
+    $fx = $form->format_amount(\%myconfig, $fx, 2, 0);
+    $exchdiff = qq|
+               <th align=right nowrap>|.$locale->text('Exchangerate Difference').qq|</th>
+               <td width=10%></td>
+               <td align=right>$fx</td>
+|;
+  }
+
+  print qq|
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+        <tr valign=top>
+         <td>
+           <table>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Cleared Balance').qq|</th>
+               <td width=10%></td>
+               <td align=right>$clearedbalance</td>
+             </tr>
+             <tr>
+               $exchdiff
+             </tr>
+           </table>
+         </td>
+         <td align=right>
+           <table>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Statement Balance').qq|</th>
+               <td width=10%></td>
+               <td align=right><input name=statementbalance size=11 value=$form->{statementbalance}></td>
+             </tr>
+             <tr>
+               <th align=right nowrap>|.$locale->text('Difference').qq|</th>
+               <td width=10%></td>
+               <td align=right><input name=none size=11 value=$difference></td>
+               <input type=hidden name=difference value=$difference>
+             </tr>
+           </table>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<input type=hidden name=rowcount value=$i>
+<input type=hidden name=accno value=$form->{accno}>
+<input type=hidden name=account value="$form->{account}">
+
+<input type=hidden name=fromdate value=$form->{fromdate}>
+<input type=hidden name=todate value=$form->{todate}>
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<br>
+<input type=submit class=submit name=action value="|.$locale->text('Update').qq|">
+<input type=submit class=submit name=action value="|.$locale->text('Select all').qq|">
+<input type=submit class=submit name=action value="|.$locale->text('Done').qq|">
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub update {
+  
+  RC->payment_transactions(\%myconfig, \%$form);
+
+  foreach $ref (@{ $form->{PR} }) {
+    if (!$ref->{fx_transaction}) {
+      $i++;
+      $ref->{cleared} = "checked" if $form->{"cleared_$i"};
+    }
+  }
+
+  &display_form;
+  
+}
+
+
+sub select_all {
+  
+  RC->payment_transactions(\%myconfig, \%$form);
+
+  map { $_->{cleared} = "checked" unless $_->{fx_transaction} } @{ $form->{PR} };
+
+  &display_form;
+  
+}
+
+
+sub done {
+
+  $form->{callback} = "$form->{script}?path=$form->{path}&action=reconciliation&login=$form->{login}&password=$form->{password}";
+
+  $form->error($locale->text('Out of balance!')) if ($form->{difference} *= 1);
+
+  RC->reconcile(\%myconfig, \%$form);
+  $form->redirect;
+  
+}
+
+
diff --git a/sql-ledger/bin/mozilla/rp.pl b/sql-ledger/bin/mozilla/rp.pl
new file mode 100644 (file)
index 0000000..41cff8c
--- /dev/null
@@ -0,0 +1,1730 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors: Antonio Gallardo <agssa@ibw.com.ni>
+#                Benjamin Lee <benjaminlee@consultant.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# module for preparing Income Statement and Balance Sheet
+# 
+#======================================================================
+
+
+use SL::RP;
+
+1;
+# end of main
+
+# this is for our long dates
+# $locale->text('January')
+# $locale->text('February')
+# $locale->text('March')
+# $locale->text('April')
+# $locale->text('May ')
+# $locale->text('June')
+# $locale->text('July')
+# $locale->text('August')
+# $locale->text('September')
+# $locale->text('October')
+# $locale->text('November')
+# $locale->text('December')
+
+# this is for our short month
+# $locale->text('Jan')
+# $locale->text('Feb')
+# $locale->text('Mar')
+# $locale->text('Apr')
+# $locale->text('May')
+# $locale->text('Jun')
+# $locale->text('Jul')
+# $locale->text('Aug')
+# $locale->text('Sep')
+# $locale->text('Oct')
+# $locale->text('Nov')
+# $locale->text('Dec')
+
+# $locale->text('Balance Sheet')
+# $locale->text('Income Statement')
+# $locale->text('Trial Balance')
+# $locale->text('AR Aging')
+# $locale->text('AP Aging')
+# $locale->text('Tax collected')
+# $locale->text('Tax paid')
+# $locale->text('Receipts')
+# $locale->text('Payments')
+
+
+sub report {
+
+  %title = ( 'balance_sheet'   => 'Balance Sheet',
+             'income_statement'        => 'Income Statement',
+             'trial_balance'   => 'Trial Balance',
+            'ar_aging'         => 'AR Aging',
+            'ap_aging'         => 'AP Aging',
+            'tax_collected'    => 'Tax collected',
+            'tax_paid'         => 'Tax paid',
+            'receipts'         => 'Receipts',
+            'payments'         => 'Payments',
+          );
+  
+  $form->{title} = $locale->text($title{$form->{report}});
+  
+  $form->header;
+  
+  $gifi = qq|
+<tr>
+  <th align=right>|.$locale->text('Accounts').qq|</th>
+  <td><input name=accounttype class=radio type=radio value=standard checked> |.$locale->text('Standard').qq|
+   
+      <input name=accounttype class=radio type=radio value=gifi> |.$locale->text('GIFI').qq|
+  </td>
+</tr>
+|;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<input type=hidden name=title value="$form->{title}">
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table>
+|;
+
+  if ($form->{report} eq "income_statement") {
+    print qq|
+        <input type=hidden name=nextsub value=generate_income_statement>
+       <tr>
+         <th align=right>|.$locale->text('From').qq|</th>
+         <td><input name=fromdate size=11 title="$myconfig{dateformat}" value=$form->{fromdate}></td>
+         <th align=right>|.$locale->text('to').qq|</th>
+         <td><input name=todate size=11 title="$myconfig{dateformat}"></td>
+       </tr>
+       <tr>
+         <th colspan=4>|.$locale->text('Compare to').qq|</th>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('From').qq|</th>
+         <td><input name=comparefromdate size=11 title="$myconfig{dateformat}"></td>
+         <th align=right>|.$locale->text('to').qq|</th>
+         <td><input name=comparetodate size=11 title="$myconfig{dateformat}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Decimalplaces').qq|</th>
+         <td><input name=decimalplaces size=3 maxsize=1></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Include in Report').qq|</th>
+         <td colspan=3><input name=l_heading class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Heading').qq|</td>
+         <td><input name=l_subtotal class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Subtotal').qq|</td>
+       </tr>
+|;
+  }
+
+
+  if ($form->{report} eq "balance_sheet") {
+    print qq|
+        <input type=hidden name=nextsub value=generate_balance_sheet>
+       <tr>
+         <th align=right>|.$locale->text('as at').qq|</th>
+         <td><input name=asofdate size=11 title="$myconfig{dateformat}" value=$form->{asofdate}></td>
+         <th align=right nowrap>|.$locale->text('Compare to').qq|</th>
+         <td><input name=compareasofdate size=11 title="$myconfig{dateformat}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Decimalplaces').qq|</th>
+         <td><input name=decimalplaces size=3 maxsize=1></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Include in Report').qq|</th>
+         <td><input name=l_heading class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Heading').qq|</td>
+         <td><input name=l_subtotal class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Subtotal').qq|</td>
+       </tr>
+|;
+  }
+
+
+  if ($form->{report} eq "trial_balance") {
+    print qq|
+        <input type=hidden name=nextsub value=generate_trial_balance>
+        <tr>
+         <th align=right>|.$locale->text('From').qq|</th>
+         <td><input name=fromdate size=11 title="$myconfig{dateformat}" value=$form->{fromdate}></td>
+         <th align=right>|.$locale->text('to').qq|</th>
+         <td><input name=todate size=11 title="$myconfig{dateformat}"></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Include in Report').qq|</th>
+         <td><input name=l_heading class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Heading').qq|
+         <input name=l_subtotal class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Subtotal').qq|</td>
+       </tr>
+|;
+  }
+
+  
+  if (($form->{report} eq "tax_paid") || ($form->{report} eq "tax_collected")) {
+    $gifi = "";
+
+    $form->{db} = ($form->{report} eq "tax_collected") ? "ar" : "ap";
+    
+    RP->get_taxaccounts(\%myconfig, \%$form);
+
+    print qq|
+        <input type=hidden name=nextsub value=generate_tax_report>
+       <tr>
+         <th align=right>|.$locale->text('From').qq|</th>
+         <td><input name=fromdate size=11 title="$myconfig{dateformat}" value=$form->{fromdate}></td>
+         <th align=right>|.$locale->text('to').qq|</th>
+         <td><input name=todate size=11 title="$myconfig{dateformat}"></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Cash based').qq|</th>
+         <td><input name=cashbased class=checkbox type=checkbox value=Y></td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('Report for').qq|</th>
+         <td>
+|;
+
+  $checked = "checked";
+  foreach $item (@{ $form->{taxaccounts} }) {
+    ($accno, $description) = split /--/, $item;
+    
+    print qq|<input name=accno class=radio type=radio value=$accno $checked>&nbsp;$description
+
+    <input name="${accno}_description" type=hidden value="$description">|;
+
+    $checked = "";
+  }
+
+  print qq|
+  <input type=hidden name=db value=$form->{db}>
+  <input type=hidden name=sort value=transdate>
+
+         </td>
+       </tr>
+|;
+
+
+  if (@{ $form->{gifi_taxaccounts} }) {
+    print qq|
+        <tr>
+         <th align=right>|.$locale->text('GIFI').qq|</th>
+         <td>
+|;
+
+    foreach $item (@{ $form->{gifi_taxaccounts} }) {
+      ($accno, $description) = split /--/, $item;
+      
+      print qq|<input name=accno class=radio type=radio value="gifi_$accno" $checked>&nbsp;$description
+
+      <input name="gifi_${accno}_description" type=hidden value="$description">|;
+
+    }
+
+    print qq|
+         </td>
+       </tr>
+|;
+  }
+
+
+print qq|
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table>
+        <tr>
+         <th align=right>|.$locale->text('Include in Report').qq|</th>
+         <td>
+           <table>
+             <tr>
+               <td><input name="l_id" class=checkbox type=checkbox value=Y></td>
+               <td>|.$locale->text('ID').qq|</td>
+               <td><input name="l_invnumber" class=checkbox type=checkbox value=Y checked></td>
+               <td>|.$locale->text('Invoice').qq|</td>
+               <td><input name="l_transdate" class=checkbox type=checkbox value=Y checked></td>
+               <td>|.$locale->text('Date').qq|</td>
+             </tr>
+             <tr>
+               <td><input name="l_name" class=checkbox type=checkbox value=Y checked></td>
+               <td>|;
+               
+  if ($form->{db} eq 'ar') {
+    print $locale->text('Customer');
+  }
+  if ($form->{db} eq 'ap') {
+    print $locale->text('Vendor');
+  }
+  
+  print qq|</td>
+                <td><input name="l_netamount" class=checkbox type=checkbox value=Y checked></td>
+               <td>|.$locale->text('Amount').qq|</td>
+               <td><input name="l_tax" class=checkbox type=checkbox value=Y checked></td>
+               <td>|.$locale->text('Tax').qq|</td>
+               <td><input name="l_amount" class=checkbox type=checkbox value=Y></td>
+               <td>|.$locale->text('Total').qq|</td>
+             </tr>
+             <tr>
+               <td><input name="l_subtotal" class=checkbox type=checkbox value=Y></td>
+               <td>|.$locale->text('Subtotal').qq|</td>
+             </tr>
+           </table>
+         </td>
+       </tr>
+|;
+
+  }
+
+
+  if (($form->{report} eq "ar_aging") || ($form->{report} eq "ap_aging")) {
+    $gifi = "";
+
+    if ($form->{report} eq 'ar_aging') {
+      $label = $locale->text('Customer');
+      $form->{vc} = 'customer';
+    } else {
+      $label = $locale->text('Vendor');
+      $form->{vc} = 'vendor';
+    }
+      
+    $nextsub = "generate_$form->{report}";
+    
+    # setup vc selection
+    $form->all_vc(\%myconfig, $form->{vc});
+
+    map { $vc .= "<option>$_->{name}--$_->{id}\n" } @{ $form->{"all_$form->{vc}"} };
+    
+    $vc = ($vc) ? qq|<select name=$form->{vc}><option>\n$vc</select>| : qq|<input name=$form->{vc} size=35>|;
+    
+    print qq|
+       <tr>
+         <th align=right>|.$locale->text($label).qq|</th>
+         <td>$vc</td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('to').qq|</th>
+         <td><input name=todate size=11 title="$myconfig{dateformat}"></td>
+       </tr>
+        <input type=hidden name=type value=statement>
+        <input type=hidden name=format value=html>
+       <input type=hidden name=media value=screen>
+
+       <input type=hidden name=nextsub value=$nextsub>
+       <input type=hidden name=action value=$nextsub>
+|;
+  }
+
+# above action can be removed if there is more than one input field
+
+
+  if (($form->{report} eq "receipts") || ($form->{report} eq "payments")) {
+    $gifi = "";
+
+    $form->{db} = ($form->{report} eq "receipts") ? "ar" : "ap";
+
+    RP->paymentaccounts(\%myconfig, \%$form);
+
+    $selection = "<option>\n";
+    foreach $ref (@{ $form->{PR} }) {
+      $paymentaccounts .= "$ref->{accno} ";
+      $selection .= "<option>$ref->{accno}--$ref->{description}\n";
+    }
+    
+    chop $paymentaccounts;
+
+    print qq|
+        <input type=hidden name=nextsub value=list_payments>
+        <tr>
+         <th align=right nowrap>|.$locale->text('Account').qq|</th>
+          <td colspan=3><select name=account>$selection</select>
+           <input type=hidden name=paymentaccounts value="$paymentaccounts">
+         </td>
+       </tr>
+       <tr>
+         <th align=right>|.$locale->text('From').qq|</th>
+         <td><input name=fromdate size=11 title="$myconfig{dateformat}" value=$form->{fromdate}></td>
+         <th align=right>|.$locale->text('to').qq|</th>
+         <td><input name=todate size=11 title="$myconfig{dateformat}"></td>
+       </tr>
+         <input type=hidden name=db value=$form->{db}>
+         <input type=hidden name=sort value=transdate>
+|;
+
+  }
+
+
+  print qq|
+
+$gifi
+
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<br>
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+
+<input type=submit class=submit name=action value="|.$locale->text('Continue').qq|">
+
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub continue { &{$form->{nextsub}} };
+
+
+sub generate_income_statement {
+
+  $form->{padding} = "&nbsp;&nbsp;";
+  $form->{bold} = "<b>";
+  $form->{endbold} = "</b>";
+  $form->{br} = "<br>";
+
+  RP->income_statement(\%myconfig, \%$form);
+
+
+  $form->{period} = $locale->date(\%myconfig, $form->current_date(\%myconfig), 1);
+  $form->{todate} = $form->current_date(\%myconfig) unless $form->{todate};
+
+  # if there are any dates construct a where
+  if ($form->{fromdate} || $form->{todate}) {
+    
+    unless ($form->{todate}) {
+      $form->{todate} = $form->current_date(\%myconfig);
+    }
+
+    $longtodate = $locale->date(\%myconfig, $form->{todate}, 1);
+    $shorttodate = $locale->date(\%myconfig, $form->{todate});
+    
+    $longfromdate = $locale->date(\%myconfig, $form->{fromdate}, 1);
+    $shortfromdate = $locale->date(\%myconfig, $form->{fromdate});
+    
+    $form->{this_period} = "$shortfromdate<br>\n$shorttodate";
+    $form->{period} = $locale->text('for Period').qq|<br>\n$longfromdate |.$locale->text('to').qq| $longtodate|;
+  }
+
+  if ($form->{comparefromdate} || $form->{comparetodate}) {
+    $longcomparefromdate = $locale->date(\%myconfig, $form->{comparefromdate}, 1);
+    $shortcomparefromdate = $locale->date(\%myconfig, $form->{comparefromdate});
+    
+    $longcomparetodate = $locale->date(\%myconfig, $form->{comparetodate}, 1);
+    $shortcomparetodate = $locale->date(\%myconfig, $form->{comparetodate});
+    
+    $form->{last_period} = "$shortcomparefromdate<br>\n$shortcomparetodate";
+    $form->{period} .= "<br>\n$longcomparefromdate ".$locale->text('to').qq| $longcomparetodate|;
+  }
+
+  # setup variables for the form
+  @a = qw(company address businessnumber);
+  map { $form->{$_} = $myconfig{$_} } @a;
+  $form->{address} =~ s/\\n/<br>/g;
+
+  $form->{templates} = $myconfig{templates};
+
+  $form->{IN} = "income_statement.html";
+  
+  $form->parse_template;
+
+}
+
+
+sub generate_balance_sheet {
+
+  $form->{padding} = "&nbsp;&nbsp;";
+  $form->{bold} = "<b>";
+  $form->{endbold} = "</b>";
+  $form->{br} = "<br>";
+
+  RP->balance_sheet(\%myconfig, \%$form);
+
+  $form->{asofdate} = $form->current_date(\%myconfig) unless $form->{asofdate};
+  $form->{period} = $locale->date(\%myconfig, $form->current_date(\%myconfig), 1);
+  
+  # define Retained Earnings account
+  $padding = ($form->{l_heading}) ? $form->{padding} : "";
+  push(@{$form->{equity_account}}, $padding.$locale->text('Retained Earnings'));
+
+  $form->{this_period} = $locale->date(\%myconfig, $form->{asofdate});
+  $form->{last_period} = $locale->date(\%myconfig, $form->{compareasofdate});
+
+  $form->{IN} = "balance_sheet.html";
+
+  # setup company variables for the form
+  map { $form->{$_} = $myconfig{$_} } (qw(company address businessnumber nativecurr));
+  $form->{address} =~ s/\\n/<br>/g;
+
+  $form->{templates} = $myconfig{templates};
+         
+  $form->parse_template;
+
+}
+
+
+# Antonio Gallardo
+#
+# D.S. Feb 16, 2001
+# included links to display transactions for period entered
+# added headers and subtotals
+#
+sub generate_trial_balance {
+  
+  # get for each account initial balance, debits and credits
+  RP->trial_balance_details(\%myconfig, \%$form);
+
+  $form->{nextsub} = "generate_trial_balance";
+  $form->{title} = $locale->text('Trial Balance');
+  &list_accounts;
+
+}
+
+
+sub list_accounts {
+
+  $title = $form->escape($form->{title});
+  
+  if ($form->{projectnumber}) {
+    $options .= $locale->text('Project Number')." : $form->{projectnumber}<br>";
+    $projectnumber = $form->escape($form->{projectnumber});
+  }
+  # if there are any dates
+  if ($form->{fromdate} || $form->{todate}) {
+    if ($form->{fromdate}) {
+      $fromdate = $locale->date(\%myconfig, $form->{fromdate}, 1);
+    }
+    if ($form->{todate}) {
+      $todate = $locale->date(\%myconfig, $form->{todate}, 1);
+    }
+    
+    $form->{period} = "$fromdate - $todate";
+  } else {
+    $form->{period} = $locale->date(\%myconfig, $form->current_date(\%myconfig), 1);
+  }
+  
+  $options .= $form->{period};
+
+  @column_index = qw(accno description begbalance debit credit endbalance);
+
+  $column_header{accno} = qq|<th class=listheading>|.$locale->text('Account').qq|</th>|;
+  $column_header{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</th>|;
+  $column_header{debit} = qq|<th class=listheading>|.$locale->text('Debit').qq|</th>|;
+  $column_header{credit} = qq|<th class=listheading>|.$locale->text('Credit').qq|</th>|;
+  $column_header{begbalance} = qq|<th class=listheading>|.$locale->text('Balance').qq|</th>|;
+  $column_header{endbalance} = qq|<th class=listheading>|.$locale->text('Balance').qq|</th>|;
+
+
+  if ($form->{accounttype} eq 'gifi') {
+    $column_header{accno} = qq|<th class=listheading>|.$locale->text('GIFI').qq|</th>|;
+  }
+  
+
+  $form->header;
+
+  print qq|
+<body>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>$options</td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr>|;
+
+  map { print "$column_header{$_}\n" } @column_index;
+
+  print qq|
+        </tr>
+|;
+
+
+  
+  # sort the whole thing by account numbers and display
+  foreach $ref (sort { $a->{accno} cmp $b->{accno} } @{ $form->{TB} }) {
+
+    $description = $form->escape($ref->{description});
+    
+    $href = qq|ca.pl?path=$form->{path}&action=list_transactions&accounttype=$form->{accounttype}&login=$form->{login}&password=$form->{password}&fromdate=$form->{fromdate}&todate=$form->{todate}&sort=transdate&l_heading=$form->{l_heading}&l_subtotal=$form->{l_subtotal}&projectnumber=$projectnumber&project_id=$form->{project_id}&title=$title&nextsub=$form->{nextsub}|;
+    
+    if ($form->{accounttype} eq 'gifi') {
+      $href .= "&gifi_accno=$ref->{accno}&gifi_description=$description";
+      $na = $locale->text('N/A');
+      map { $ref->{$_} = $na } qw(accno description) unless $ref->{accno};
+    } else {
+      $href .= "&accno=$ref->{accno}&description=$description";
+    }
+
+    $ml = ($ref->{category} =~ /(A|E)/) ? -1 : 1;
+    
+    $debit = $form->format_amount(\%myconfig, $ref->{debit}, 2, "&nbsp;");
+    $credit = $form->format_amount(\%myconfig, $ref->{credit}, 2, "&nbsp;");
+    $begbalance = $form->format_amount(\%myconfig, $ref->{balance} * $ml, 2, "&nbsp;");
+    $endbalance = $form->format_amount(\%myconfig, ($ref->{balance} + $ref->{amount}) * $ml, 2, "&nbsp;");
+
+    next if ($ref->{debit} == 0 && $ref->{credit} == 0);
+    
+    if ($ref->{charttype} eq "H" && $subtotal && $form->{l_subtotal}) {
+      map { $column_data{$_} = "<th>&nbsp;</th>" } qw(accno begbalance endbalance);
+
+      $subtotalbegbalance = $form->format_amount(\%myconfig, $subtotalbegbalance, 2, "&nbsp;");
+      $subtotalendbalance = $form->format_amount(\%myconfig, $subtotalendbalance, 2, "&nbsp;");
+      $subtotaldebit = $form->format_amount(\%myconfig, $subtotaldebit, 2, "&nbsp;");
+      $subtotalcredit = $form->format_amount(\%myconfig, $subtotalcredit, 2, "&nbsp;");
+      $column_data{description} = "<th>$subtotaldescription</th>";
+      $column_data{begbalance} = "<th align=right>$subtotalbegbalance</th>";
+      $column_data{endbalance} = "<th align=right>$subtotalendbalance</th>";
+      $column_data{debit} = "<th align=right>$subtotaldebit</th>";
+      $column_data{credit} = "<th align=right>$subtotalcredit</th>";
+      
+      print qq|
+       <tr class=listsubtotal>
+|;
+      map { print "$column_data{$_}\n" } @column_index;
+      
+      print qq|
+        </tr>
+|;
+    }
+    if ($ref->{charttype} eq "H") {
+      $subtotal = 1;
+      $subtotaldescription = $ref->{description};
+      $subtotaldebit = $ref->{debit};
+      $subtotalcredit = $ref->{credit};
+      $subtotalbegbalance = 0;
+      $subtotalendbalance = 0;
+
+      next unless $form->{l_heading};
+      
+      map { $column_data{$_} = "<th>&nbsp;</th>" } qw(accno debit credit begbalance endbalance);
+      $column_data{description} = "<th class=listheading>$ref->{description}</th>";
+    }
+
+    if ($ref->{charttype} eq "A") {
+      $column_data{accno} = "<td><a href=$href>$ref->{accno}</a></td>";
+      $column_data{description} = "<td>$ref->{description}</td>";
+      $column_data{debit} = "<td align=right>$debit</td>";
+      $column_data{credit} = "<td align=right>$credit</td>";
+      $column_data{begbalance} = "<td align=right>$begbalance</td>";
+      $column_data{endbalance} = "<td align=right>$endbalance</td>";
+    
+      $totaldebit += $ref->{debit};
+      $totalcredit += $ref->{credit};
+
+      $subtotalbegbalance += $ref->{balance} * $ml;
+      $subtotalendbalance += ($ref->{balance} + $ref->{amount}) * $ml;
+
+    }
+    
+    if ($ref->{charttype} eq "H") {
+      print qq|
+      <tr class=listheading>
+|;
+    }
+    if ($ref->{charttype} eq "A") {
+      $i++; $i %= 2;
+      print qq|
+      <tr class=listrow$i>
+|;
+    }
+    
+    map { print "$column_data{$_}\n" } @column_index;
+    
+    print qq|
+      </tr>
+|;
+  }
+
+
+  # print last subtotal
+  if ($subtotal && $form->{l_subtotal}) {
+    map { $column_data{$_} = "<th>&nbsp;</th>" } qw(accno begbalance endbalance);
+    $subtotalbegbalance = $form->format_amount(\%myconfig, $subtotalbegbalance, 2, "&nbsp;");
+    $subtotalendbalance = $form->format_amount(\%myconfig, $subtotalendbalance, 2, "&nbsp;");
+    $subtotaldebit = $form->format_amount(\%myconfig, $subtotaldebit, 2, "&nbsp;");
+    $subtotalcredit = $form->format_amount(\%myconfig, $subtotalcredit, 2, "&nbsp;");
+    $column_data{description} = "<th>$subdescription</th>";
+    $column_data{begbalance} = "<th align=right>$subtotalbegbalance</th>";
+    $column_data{endbalance} = "<th align=right>$subtotalendbalance</th>";
+    $column_data{debit} = "<th align=right>$subtotaldebit</th>";
+    $column_data{credit} = "<th align=right>$subtotalcredit</th>";
+    
+    print qq|
+      <tr class=listsubtotal>
+|;
+    map { print "$column_data{$_}\n" } @column_index;
+    
+    print qq|
+      </tr>
+|;
+  }
+  
+  $totaldebit = $form->format_amount(\%myconfig, $totaldebit, 2, "&nbsp;");
+  $totalcredit = $form->format_amount(\%myconfig, $totalcredit, 2, "&nbsp;");
+
+  map { $column_data{$_} = "<th>&nbsp;</th>" } qw(accno description begbalance endbalance);
+  $column_data{debit} = qq|<th align=right class=listtotal>$totaldebit</th>|;
+  $column_data{credit} = qq|<th align=right class=listtotal>$totalcredit</th>|;
+  
+  print qq|
+        <tr class=listtotal>
+|;
+
+  map { print "$column_data{$_}\n" } @column_index;
+
+  print qq|
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+</body>
+</html>
+|;
+
+}
+
+
+
+sub generate_ar_aging {
+
+  # split customer
+  ($form->{customer}) = split(/--/, $form->{customer});
+
+  $form->{ct} = "customer";
+  $form->{arap} = "ar";
+
+  $form->{callback} = qq|$form->{script}?path=$form->{path}&action=generate_ar_aging&login=$form->{login}&password=$form->{password}&todate=$form->{todate}&customer=|.$form->escape($form->{customer});
+
+  RP->aging(\%myconfig, \%$form);
+  &aging;
+  
+}
+
+
+sub generate_ap_aging {
+  
+  # split vendor
+  ($form->{vendor}) = split(/--/, $form->{vendor});
+
+  $form->{ct} = "vendor";
+  $form->{arap} = "ap";
+  
+  $form->{callback} = qq|$form->{script}?path=$form->{path}&action=generate_ap_aging&login=$form->{login}&password=$form->{password}&todate=$form->{todate}&vendor=|.$form->escape($form->{vendor});
+
+  RP->aging(\%myconfig, \%$form);
+  &aging;
+  
+}
+
+
+sub aging {
+
+
+  $form->header;
+
+  $column_header{statement} = qq|<th class=listheading>&nbsp;</th>|;
+  $column_header{ct} = qq|<th class=listheading>|.$locale->text(ucfirst $form->{ct}).qq|</th>|;
+  $column_header{invnumber} = qq|<th class=listheading>|.$locale->text('Invoice').qq|</th>|;
+  $column_header{transdate} = qq|<th class=listheading>|.$locale->text('Date').qq|</th>|;
+  $column_header{duedate} = qq|<th class=listheading>|.$locale->text('Due').qq|</th>|;
+  $column_header{c0} = qq|<th class=listheading>|.$locale->text('Current').qq|</th>|;
+  $column_header{c30} = qq|<th class=listheading>30</th>|;
+  $column_header{c60} = qq|<th class=listheading>60</th>|;
+  $column_header{c90} = qq|<th class=listheading>90</th>|;
+  
+  @column_index = (qw(statement ct invnumber transdate duedate c0 c30 c60 c90));
+
+  
+  if ($form->{arap} eq 'ar') {
+    if ($form->{customer}) {
+      $option .= "\n<br>" if $option;
+      $option .= $form->{customer};
+    }
+  }
+  if ($form->{arap} eq 'ap') {
+    shift @column_index;
+    if ($form->{vendor}) {
+      $option .= "\n<br>" if $option;
+      $option .= $form->{vendor};
+    }
+  }
+  
+  $todate = $locale->date(\%myconfig, $form->{todate}, 1);
+  $option .= "\n<br>" if $option;
+  $option .= $locale->text('for Period')." ".$locale->text('to')." $todate";
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>$option</td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+|;
+
+  map { print "$column_header{$_}\n" } @column_index;
+  
+  print qq|
+       </tr>
+|;
+
+
+  $ctid = 0;
+  $subtotal = 0;
+  $i = 0;
+
+  foreach $ref (@{ $form->{AG} }) {
+
+    if ($ctid != $ref->{ctid}) {
+
+      $i++;
+
+      if ($subtotal) {
+       $c0subtotal = $form->format_amount(\%myconfig, $c0subtotal, 2, "&nbsp");
+       $c30subtotal = $form->format_amount(\%myconfig, $c30subtotal, 2, "&nbsp");
+       $c60subtotal = $form->format_amount(\%myconfig, $c60subtotal, 2, "&nbsp");
+       $c90subtotal = $form->format_amount(\%myconfig, $c90subtotal, 2, "&nbsp");
+      }
+      
+      $column_data{ct} = qq|<th>&nbsp;</th>|;
+      $column_data{invnumber} = qq|<th>&nbsp;</th>|;
+      $column_data{transdate} = qq|<th>&nbsp;</th>|;
+      $column_data{duedate} = qq|<th>&nbsp;</th>|;
+      $column_data{c0} = qq|<th class=listsubtotal align=right>$c0subtotal</th>|;
+      $column_data{c30} = qq|<th class=listsubtotal align=right>$c30subtotal</th>|;
+      $column_data{c60} = qq|<th class=listsubtotal align=right>$c60subtotal</th>|;
+      $column_data{c90} = qq|<th class=listsubtotal align=right>$c90subtotal</th>|;
+     
+      if ($subtotal) {
+       # print subtotals
+       print qq|
+       <tr class=listsubtotal>
+|;
+
+       map { print "$column_data{$_}\n" } @column_index;
+
+       $column_data{statement} = qq|<td>&nbsp;</td>|;
+
+       print qq|
+        </tr>
+|;
+      }
+   
+      $subtotal = 1;
+
+      $c0subtotal = 0;
+      $c30subtotal = 0;
+      $c60subtotal = 0;
+      $c90subtotal = 0;
+
+      $column_data{ct} = qq|<td>$ref->{name}</td>|;
+      $column_data{statement} = qq|<td><input name="statement_$i" type=checkbox class=checkbox value=1 $ref->{checked}>
+      <input type=hidden name="$form->{ct}_id_$i" value=$ref->{ctid}>
+      </td>|;
+    }
+
+    $c0subtotal += $ref->{c0};
+    $c30subtotal += $ref->{c30};
+    $c60subtotal += $ref->{c60};
+    $c90subtotal += $ref->{c90};
+
+    $c0total += $ref->{c0};
+    $c30total += $ref->{c30};
+    $c60total += $ref->{c60};
+    $c90total += $ref->{c90};
+
+    $ref->{c0} = $form->format_amount(\%myconfig, $ref->{c0}, 2, "&nbsp;");
+    $ref->{c30} = $form->format_amount(\%myconfig, $ref->{c30}, 2, "&nbsp;");
+    $ref->{c60} = $form->format_amount(\%myconfig, $ref->{c60}, 2, "&nbsp;");
+    $ref->{c90} = $form->format_amount(\%myconfig, $ref->{c90}, 2, "&nbsp;");
+    $href = qq|$ref->{module}.pl?path=$form->{path}&action=edit&id=$ref->{id}&login=$form->{login}&password=$form->{password}&callback=|.$form->escape($form->{callback});
+    
+    $column_data{invnumber} = qq|<td><a href=$href>$ref->{invnumber}</a></td>|;
+    $column_data{transdate} = qq|<td>$ref->{transdate}</td>|;
+    $column_data{duedate} = qq|<td>$ref->{duedate}&nbsp;</td>|;
+    $column_data{c0} = qq|<td align=right>$ref->{c0}</td>|;
+    $column_data{c30} = qq|<td align=right>$ref->{c30}</td>|;
+    $column_data{c60} = qq|<td align=right>$ref->{c60}</td>|;
+    $column_data{c90} = qq|<td align=right>$ref->{c90}</td>|;
+    
+    $j++; $j %= 2;
+    print qq|
+       <tr class=listrow$j>
+|;
+
+    map { print "$column_data{$_}\n" } @column_index;
+
+    print qq|
+        </tr>
+|;
+    $column_data{ct} = qq|<td>&nbsp;</td>|;
+    $column_data{statement} = qq|<td>&nbsp;</td>|;
+
+    $ctid = $ref->{ctid};
+
+  }
+  
+  # print subtotals
+  $c0subtotal = $form->format_amount(\%myconfig, $c0subtotal, 2, "&nbsp;");
+  $c30subtotal = $form->format_amount(\%myconfig, $c30subtotal, 2, "&nbsp;");
+  $c60subtotal = $form->format_amount(\%myconfig, $c60subtotal, 2, "&nbsp;");
+  $c90subtotal = $form->format_amount(\%myconfig, $c90subtotal, 2, "&nbsp;");
+  
+  print qq|
+        <tr class=listsubtotal>
+|;
+
+  map { $column_data{$_} = qq|<th>&nbsp;</th>| } @column_index;
+
+  $column_data{c0} = qq|<th class=listsubtotal align=right>$c0subtotal</th>|;
+  $column_data{c30} = qq|<th class=listsubtotal align=right>$c30subtotal</th>|;
+  $column_data{c60} = qq|<th class=listsubtotal align=right>$c60subtotal</th>|;
+  $column_data{c90} = qq|<th class=listsubtotal align=right>$c90subtotal</th>|;
+
+  map { print "$column_data{$_}\n" } @column_index;
+  
+  print qq|
+        </tr>
+        <tr class=listtotal>
+|;
+
+  $c0total = $form->format_amount(\%myconfig, $c0total, 2, "&nbsp;");
+  $c30total = $form->format_amount(\%myconfig, $c30total, 2, "&nbsp;");
+  $c60total = $form->format_amount(\%myconfig, $c60total, 2, "&nbsp;");
+  $c90total = $form->format_amount(\%myconfig, $c90total, 2, "&nbsp;");
+  
+  $column_data{c0} = qq|<th class=listtotal align=right>$c0total</th>|;
+  $column_data{c30} = qq|<th class=listtotal align=right>$c30total</th>|;
+  $column_data{c60} = qq|<th class=listtotal align=right>$c60total</th>|;
+  $column_data{c90} = qq|<th class=listtotal align=right>$c90total</th>|;
+
+  map { print "$column_data{$_}\n" } @column_index;
+
+  
+  print qq|
+          <input type=hidden name=rowcount value=$i>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+|;
+
+  &print_options if ($form->{arap} eq 'ar');
+
+  print qq|
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+|;
+
+  if ($form->{arap} eq 'ar') {
+    print qq|
+<input type=hidden name=todate value=$form->{todate}>
+
+<input type=hidden name=title value="$form->{title}">
+
+<input type=hidden name=arap value=$form->{arap}>
+<input type=hidden name=ct value=$form->{ct}>
+<input type=hidden name=$form->{ct} value="$form->{$form->{ct}}">
+
+<input type=hidden name=path value=$form->{path}>
+<input type=hidden name=login value=$form->{login}>
+<input type=hidden name=password value=$form->{password}>
+  
+<br>
+<input class=submit type=submit name=action value="|.$locale->text('Select all').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('Print').qq|">
+<input class=submit type=submit name=action value="|.$locale->text('E-mail').qq|">
+|;
+  }
+
+  print qq|
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub select_all {
+
+  RP->aging(\%myconfig, \%$form);
+
+  map { $_->{checked} = "checked" } @{ $form->{AG} };
+
+  &aging;
+
+}
+
+
+sub print_options {
+
+  $form->{sendmode} = "attachment";
+  $form->{copies} = 2 unless $form->{copies};
+  
+  $form->{PD}{$form->{type}} = "checked";
+  $form->{DF}{$form->{format}} = "checked";
+  $form->{OP}{$form->{media}} = "checked";
+  $form->{SM}{$form->{sendmode}} = "checked";
+  
+
+  if ($form->{media} eq 'email') {
+    $email = qq|
+       <td><input class=radio type=radio name=sendmode value=attachment $form->{SM}{attachment}> |.$locale->text('Attachment')
+       .qq| <input class=radio type=radio name=sendmode value=inline $form->{SM}{inline}> |.$locale->text('In-line').qq|</td>
+|;
+  } else {
+    $screen = qq|
+       <td><input class=radio type=radio name=media value=screen $form->{OP}{screen}></td>
+       <td>|.$locale->text('Screen').qq|</td>
+|;
+  }
+
+  print qq|
+<table width=100%>
+  <tr valign=top>
+    <td><input class=radio type=radio name=type value=statement $form->{PD}{statement}></td><td>|.$locale->text('Statement').qq|</td>
+    <td><input class=radio type=radio name=format value=html $form->{DF}{html}></td>
+    <td>html</td>
+|;
+
+  if ($latex) {
+      print qq|
+    <td><input class=radio type=radio name=format value=postscript $form->{DF}{postscript}></td>
+    <td>|.$locale->text('Postscript').qq|</td>
+    <td><input class=radio type=radio name=format value=pdf $form->{DF}{pdf}></td>
+    <td>|.$locale->text('PDF').qq|</td>
+|;
+  }
+
+  print qq|
+    $screen
+|;
+
+  if ($screen) {
+    if ($myconfig{printer} && $latex) {
+      print qq|
+    <td><input class=radio type=radio name=media value=printer $form->{OP}{printer}></td>
+    <td>|.$locale->text('Printer')
+    .qq| (|.$locale->text('Copies')
+    .qq| <input name=copies size=2 value=$form->{copies}>)</td>
+|;
+    }
+  }
+
+  print qq|
+    $email
+  </tr>
+</table>
+|;
+
+}
+
+
+sub e_mail {
+
+  # get name and email addresses
+  for $i (1 .. $form->{rowcount}) {
+    if ($form->{"statement_$i"}) {
+      $form->{"$form->{ct}_id"} = $form->{"$form->{ct}_id_$i"};
+      RP->get_customer(\%myconfig, \%$form);
+      $selected = 1;
+      last;
+    }
+  }
+
+  $form->error($locale->text('Nothing selected!')) unless $selected;
+
+  if ($myconfig{admin}) {
+    $bcc = qq|
+          <th align=right nowrap=true>|.$locale->text('Bcc').qq|</th>
+         <td><input name=bcc size=30 value="$form->{bcc}"></td>
+|;
+  }
+
+  $title = $locale->text('E-mail Statement to')." $form->{$form->{ct}}";
+
+  $form->{media} = "email";
+  
+  $form->header;
+
+  print qq|
+<body>
+
+<form method=post action=$form->{script}>
+
+<table width=100%>
+  <tr class=listtop>
+    <th class=listtop>$title</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>
+      <table width=100%>
+        <tr>
+         <th align=right nowrap>|.$locale->text('E-mail').qq|</th>
+         <td><input name=email size=30 value="$form->{email}"></td>
+         <th align=right nowrap>|.$locale->text('Cc').qq|</th>
+         <td><input name=cc size=30 value="$form->{cc}"></td>
+       </tr>
+       <tr>
+         <th align=right nowrap>|.$locale->text('Subject').qq|</th>
+         <td><input name=subject size=30 value="$form->{subject}"></td>
+         $bcc
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+        <tr>
+         <th align=left nowrap>|.$locale->text('Message').qq|</th>
+       </tr>
+       <tr>
+         <td><textarea name=message rows=15 cols=60 wrap=soft>$form->{message}</textarea></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>
+|;
+
+  &print_options;
+
+  map { delete $form->{$_} } qw(action email cc bcc subject message type sendmode format);
+
+  # save all other variables
+  foreach $key (keys %$form) {
+    $form->{$key} =~ s/"/&quot;/g;
+    print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
+  }
+
+  print qq|
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+<input type=hidden name=nextsub value=send_email>
+
+<br>
+<input name=action class=submit type=submit value="|.$locale->text('Continue').qq|">
+</form>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub send_email {
+
+  $form->{OUT} = "$sendmail";
+
+  $form->{subject} = $locale->text('Statement').qq| - $form->{todate}| unless $form->{subject};
+  
+  RP->aging(\%myconfig, \%$form);
+  
+  $form->{"statement_1"} = 1;
+
+  &print_form;
+  
+  $form->redirect($locale->text('Statement sent to')." $form->{$form->{ct}}");
+
+}
+
+
+
+sub print {
+  
+  if ($form->{media} eq 'printer') {
+    $form->error($locale->text('Select postscript or PDF!')) if ($form->{format} !~ /(postscript|pdf)/);
+  }
+  
+  for $i (1 .. $form->{rowcount}) {
+    if ($form->{"statement_$i"}) {
+      $form->{"$form->{ct}_id"} = $form->{"$form->{ct}_id_$i"};
+      $selected = 1;
+      last;
+    }
+  }
+
+  $form->error($locale->text('Nothing selected!')) unless $selected;
+     
+  if ($form->{media} eq 'printer') {
+    $form->{OUT} = "| $myconfig{printer}";
+    $form->{"$form->{ct}_id"} = "";
+  } else {
+    $form->{"statement_1"} = 1;
+  }
+  
+  RP->aging(\%myconfig, \%$form);
+  &print_form;
+
+  $form->redirect($locale->text('Statements sent to printer!')) if ($form->{media} eq 'printer');
+
+}
+
+
+sub print_form {
+  
+  $form->{statementdate} = $locale->date(\%myconfig, $form->{todate}, 1);
+
+  $form->{templates} = "$myconfig{templates}";
+  # setup variables for the form
+  @a = qw(company address businessnumber tel fax);
+  map { $form->{$_} = $myconfig{$_} } @a;
+  $form->format_string(@a);
+  
+  $form->{IN} = "$form->{type}.html";
+
+  if ($form->{format} eq 'postscript') {
+    $form->{postscript} = 1;
+    $form->{IN} =~ s/html$/tex/;
+  }
+  if ($form->{format} eq 'pdf') {
+    $form->{pdf} = 1;
+    $form->{IN} =~ s/html$/tex/;
+  }
+
+  $i = 0;
+  while (@{ $form->{AG} }) {
+
+    $ref = shift @{ $form->{AG} };
+    
+    if ($ctid != $ref->{ctid}) {
+      
+      $ctid = $ref->{ctid};
+      $i++;
+
+      if ($form->{"statement_$i"}) {
+       
+       @a = (name, addr1, addr2, addr3, addr4, contact, "$form->{ct}phone", "$form->{ct}fax");
+       map { $form->{$_} = $ref->{$_} } @a;
+       $form->format_string(@a);
+
+       $form->{$form->{ct}} = $form->{name};
+       $form->{"$form->{ct}_id"} = $ref->{ctid};
+       
+       map { $form->{$_} = () } qw(invnumber invdate duedate);
+       $form->{total} = 0;
+       foreach $item (qw(c0 c30 c60 c90)) {
+         $form->{$item} = ();
+         $form->{"${item}total"} = 0;
+       }
+
+       &statement_details($ref);
+       
+        while ($ref) {
+
+          if (scalar (@{ $form->{AG} }) > 0) {
+           # one or more left to go
+           if ($ctid == $form->{AG}->[0]->{ctid}) {
+             $ref = shift @{ $form->{AG} };
+             &statement_details($ref);
+             # any more?
+             $ref = scalar (@{ $form->{AG} });
+           } else {
+             $ref = 0;
+           }
+         } else {
+           # set initial ref to 0
+           $ref = 0;
+         }
+
+       }
+       
+       map { $form->{"${_}total"} = $form->format_amount(\%myconfig, $form->{"${_}total"}, 2) } (c0, c30, c60, c90, "");
+
+       $form->parse_template(\%myconfig, $userspath);
+       
+      }
+    }
+  }
+
+}
+
+
+sub statement_details {
+  my ($ref) = @_;
+  
+  push @{ $form->{invnumber} }, $ref->{invnumber};
+  push @{ $form->{invdate} }, $ref->{transdate};
+  push @{ $form->{duedate} }, $ref->{duedate};
+  
+  foreach $item (qw(c0 c30 c60 c90)) {
+    $ref->{$item} = $form->round_amount($ref->{$item} / $ref->{exchangerate}, 2);
+    $form->{"${item}total"} += $ref->{$item};
+    $form->{total} += $ref->{$item};
+    push @{ $form->{$item} }, $form->format_amount(\%myconfig, $ref->{$item}, 2);
+  }
+
+}
+
+sub generate_tax_report {
+
+  RP->tax_report(\%myconfig, \%$form);
+
+  $descvar = "$form->{accno}_description";
+  $description = $form->escape($form->{$descvar});
+  
+  # construct href
+  $href = "$form->{script}?path=$form->{path}&action=generate_tax_report&login=$form->{login}&password=$form->{password}&fromdate=$form->{fromdate}&todate=$form->{todate}&db=$form->{db}&accno=$form->{accno}&$descvar=$description";
+
+  # construct callback
+  $callback = $href;
+
+  @columns = $form->sort_columns(qw(id transdate invnumber name netamount tax amount));
+
+  foreach $item (@columns) {
+    if ($form->{"l_$item"} eq "Y") {
+      push @column_index, $item;
+
+      # add column to href and callback
+      $callback .= "&l_$item=Y";
+      $href .= "&l_$item=Y";
+    }
+  }
+
+  if ($form->{l_subtotal} eq 'Y') {
+    $callback .= "&l_subtotal=Y";
+    $href .= "&l_subtotal=Y";
+  }
+  
+  
+  # if there are any dates
+  if ($form->{fromdate} || $form->{todate}) {
+    if ($form->{fromdate}) {
+      $fromdate = $locale->date(\%myconfig, $form->{fromdate}, 1);
+    }
+    if ($form->{todate}) {
+      $todate = $locale->date(\%myconfig, $form->{todate}, 1);
+    }
+    
+    $form->{period} = "$fromdate - $todate";
+  } else {
+    $form->{period} = $locale->date(\%myconfig, $form->current_date(\%myconfig), 1);
+  }
+
+  $form->{title} = $locale->text('GIFI')." - " if ($form->{accno} =~ /^gifi_/);
+  $form->{title} = qq|$form->{"$form->{accno}_description"} |;
+  if ($form->{db} eq 'ar') {
+    $form->{title} .= $locale->text('collected on sales');
+    $name = $locale->text('Customer');
+    $invoice = 'is.pl';
+    $arap = 'ar.pl';
+  }
+  if ($form->{db} eq 'ap') {
+    $form->{title} .= $locale->text('paid on purchases');
+    $name = $locale->text('Vendor');
+    $invoice = 'ir.pl';
+    $arap = 'ap.pl';
+  }
+
+  $column_header{id} = qq|<th><a class=listheading href=$href&sort=id>|.$locale->text('ID').qq|</th>|;
+  $column_header{invnumber} = qq|<th><a class=listheading href=$href&sort=invnumber>|.$locale->text('Invoice').qq|</th>|;
+  $column_header{transdate} = qq|<th><a class=listheading href=$href&sort=transdate>|.$locale->text('Date').qq|</th>|;
+  $column_header{netamount} = qq|<th class=listheading>|.$locale->text('Amount').qq|</th>|;
+  $column_header{tax} = qq|<th class=listheading>|.$locale->text('Tax').qq|</th>|;
+  $column_header{amount} = qq|<th class=listheading>|.$locale->text('Total').qq|</th>|;
+  
+  $column_header{name} = qq|<th><a class=listheading href=$href&sort=name>$name</th>|;
+
+  
+  $form->header;
+
+  print qq|
+<body>
+
+<table width=100%>
+  <tr>
+    <th class=listtop colspan=$colspan>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>$form->{period}</td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+|;
+
+  map { print "$column_header{$_}\n" } @column_index;
+  
+  print qq|
+       </tr>
+|;
+
+  # add sort and escape callback
+  $callback = $form->escape($callback . "&sort=$form->{sort}");
+    
+  if (@{ $form->{TR} }) {
+    $sameitem = $form->{TR}->[0]->{$form->{sort}};
+  }
+
+  foreach $ref (@{ $form->{TR} }) {
+
+    $module = ($ref->{invoice}) ? $invoice : $arap;
+    
+    if ($form->{l_subtotal} eq 'Y') {
+      if ($sameitem ne $ref->{$form->{sort}}) {
+       &tax_subtotal;
+       $sameitem = $ref->{$form->{sort}};
+      }
+    }
+
+    $totalnetamount += $ref->{netamount};
+    $totaltax += $ref->{tax};
+    $ref->{amount} = $ref->{netamount} + $ref->{tax};
+
+    $subtotalnetamount += $ref->{netamount};
+    $subtotaltax += $ref->{tax};
+    
+    map { $ref->{$_} = $form->format_amount(\%myconfig, $ref->{$_}, 2, "&nbsp;"); } qw(netamount tax amount);
+    
+    $column_data{id} = qq|<td>$ref->{id}</td>|;
+    $column_data{invnumber} = qq|<td><a href=$module?path=$form->{path}&action=edit&id=$ref->{id}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{invnumber}</a></td>|;
+    $column_data{transdate} = qq|<td>$ref->{transdate}</td>|;
+    $column_data{name} = qq|<td>$ref->{name}&nbsp;</td>|;
+    
+    map { $column_data{$_} = qq|<td align=right>$ref->{$_}</td>| } qw(netamount tax amount);
+
+    $i++; $i %= 2;
+    print qq|
+       <tr class=listrow$i>
+|;
+
+    map { print "$column_data{$_}\n" } @column_index;
+
+    print qq|
+       </tr>
+|;
+  }
+  if ($form->{l_subtotal} eq 'Y') {
+    &tax_subtotal;
+  }
+
+  
+  map { $column_data{$_} = qq|<th>&nbsp;</th>| } @column_index;
+  
+  print qq|
+        </tr>
+       <tr class=listtotal>
+|;
+
+  $total = $form->format_amount(\%myconfig, $totalnetamount + $totaltax, 2, "&nbsp;");
+  $totalnetamount = $form->format_amount(\%myconfig, $totalnetamount, 2, "&nbsp;");
+  $totaltax = $form->format_amount(\%myconfig, $totaltax, 2, "&nbsp;");
+  
+  $column_data{netamount} = qq|<th class=listtotal align=right>$totalnetamount</th>|;
+  $column_data{tax} = qq|<th class=listtotal align=right>$totaltax</th>|;
+  $column_data{amount} = qq|<th class=listtotal align=right>$total</th>|;
+  map { print "$column_data{$_}\n" } @column_index;
+    
+  print qq|
+        </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+</body>
+</html>
+|;
+
+}
+
+
+sub tax_subtotal {
+
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+
+  $subtotalnetamount = $form->format_amount(\%myconfig, $subtotalnetamount, 2, "&nbsp;");
+  $subtotaltax = $form->format_amount(\%myconfig, $subtotaltax, 2, "&nbsp;");
+  $subtotal = $form->format_amount(\%myconfig, $subtotalnetamount + $subtotaltax, 2, "&nbsp;");
+  
+  $column_data{netamount} = "<th class=listsubtotal align=right>$subtotalnetamount</th>";
+  $column_data{tax} = "<th class=listsubtotal align=right>$subtotaltax</th>";
+  $column_data{amount} = "<th class=listsubtotal align=right>$subtotal</th>";
+
+  $subtotalnetamount = 0;
+  $subtotaltax = 0;
+  
+  print qq|
+       <tr class=listsubtotal>
+|;
+  map { print "\n$column_data{$_}" } @column_index;
+
+  print qq|
+        </tr>
+|;
+  
+}
+
+
+
+sub list_payments {
+
+  if ($form->{account}) {
+    ($form->{paymentaccounts}) = split /--/, $form->{account};
+  }
+
+  RP->payments(\%myconfig, \%$form);
+  
+  @columns = $form->sort_columns(qw(transdate invnumber name paid source));
+
+  # construct href
+  $href = "$form->{script}?path=$form->{path}&action=list_payments&login=$form->{login}&password=$form->{password}&fromdate=$form->{fromdate}&todate=$form->{todate}&db=$form->{db}&title=".$form->escape($form->{title})."&account=".$form->escape($form->{account});
+
+  $form->{paymentaccounts} =~ s/ /%20/g;
+  $href .= "&paymentaccounts=$form->{paymentaccounts}";
+
+
+  # construct callback
+  $form->{callback} = "$href&sort=$form->{sort}";
+  $callback = $form->escape($form->{callback});
+
+  
+  $column_header{name} = "<th><a class=listheading href=$href&sort=name>".$locale->text('Description')."</a></th>";
+  $column_header{invnumber} = "<th><a class=listheading href=$href&sort=invnumber>".$locale->text('Invoice')."</a></th>";
+  $column_header{transdate} = "<th><a class=listheading href=$href&sort=transdate>".$locale->text('Date')."</a></th>";
+  $column_header{paid} = "<th class=listheading>".$locale->text('Amount')."</a></th>";
+  $column_header{source} = "<th><a class=listheading href=$href&sort=source>".$locale->text('Source')."</a></th>";
+  
+
+  if ($form->{fromdate}) {
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('From')."&nbsp;".$locale->date(\%myconfig, $form->{fromdate}, 1);
+  }
+  if ($form->{todate}) {
+    $option .= "\n<br>" if ($option);
+    $option .= $locale->text('to')."&nbsp;".$locale->date(\%myconfig, $form->{todate}, 1);
+  }
+
+  @column_index = @columns;
+  $colspan = $#column_index + 1;
+
+  $form->header;
+
+  print qq|
+<body>
+
+<table width=100%>
+  <tr>
+    <th class=listtop>$form->{title}</th>
+  </tr>
+  <tr height="5"></tr>
+  <tr>
+    <td>$option</td>
+  </tr>
+  <tr>
+    <td>
+      <table width=100%>
+       <tr class=listheading>
+|;
+
+  map { print "\n$column_header{$_}" } @column_index;
+
+  print qq|
+        </tr>
+|;
+
+  
+  foreach $ref (sort { $a->{accno} cmp $b->{accno} } @{ $form->{PR} }) {
+
+    print qq|
+        <tr>
+         <th colspan=$colspan align=left>$ref->{accno}--$ref->{description}</th>
+       </tr>
+|;
+  
+    foreach $payment (@{ $form->{$ref->{id}} }) {
+      
+      $module = $payment->{module};
+      $module = 'is' if ($payment->{invoice} && $payment->{module} eq 'ar');
+      $module = 'ir' if ($payment->{invoice} && $payment->{module} eq 'ap');
+      
+      $href = qq|${module}.pl?path=$form->{path}&action=edit&id=$payment->{id}&login=$form->{login}&password=$form->{password}&callback=$callback|;
+    
+      
+      $column_data{name} = "<td>$payment->{name}&nbsp;</td>";
+      $column_data{invnumber} = qq|<td><a href=$href>$payment->{invnumber}</a></td>|;
+      $column_data{transdate} = "<td>$payment->{transdate}&nbsp;</td>";
+      $column_data{paid} = "<td align=right>".$form->format_amount(\%myconfig, $payment->{paid}, 2, "&nbsp;")."</td>";
+      $column_data{source} = "<td>$payment->{source}&nbsp;</td>";
+
+      $subtotalpaid += $payment->{paid};
+      $totalpaid += $payment->{paid};
+       
+      $i++; $i %= 2;
+      print qq|
+       <tr class=listrow$i>
+|;
+
+      map { print "\n$column_data{$_}" } @column_index;
+
+      print qq|
+        </tr>
+|;
+
+    }
+
+    # print subtotals
+    map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+
+    $column_data{paid} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalpaid, 2, "&nbsp;")."</th>";
+     
+    print qq|
+       <tr class=listsubtotal>
+|;
+
+    map { print "\n$column_data{$_}" } @column_index;
+
+    print qq|
+        </tr>
+|;
+
+    $subtotalpaid = 0;
+     
+  }
+
+
+  # print total
+  map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
+
+  $column_data{paid} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalpaid, 2, "&nbsp;")."</th>";
+     
+  print qq|
+        <tr class=listtotal>
+|;
+
+  map { print "\n$column_data{$_}" } @column_index;
+
+  print qq|
+        </tr>
+
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td><hr size=3 noshade></td>
+  </tr>
+</table>
+
+</body>
+</html>
+|;
+
+}
+
+
+
diff --git a/sql-ledger/css/sql-ledger.css b/sql-ledger/css/sql-ledger.css
new file mode 100644 (file)
index 0000000..20a59cf
--- /dev/null
@@ -0,0 +1,113 @@
+/* stylesheet for sql-ledger */
+
+/* general stuff */
+A:link { color: #a0522d; text-decoration: none; }
+A:visited { color: #a0522d; text-decoration: none; }
+A:active { color: #a0522d; text-decoration: underline; }
+A:hover { color: white;
+          background-color: rgb(187,187,187);
+         text-decoration: none;
+}
+
+body {
+  font-family: Verdana, Arial, Helvetica;
+  font-size: 10pt;
+  background-color: white;
+  color: black
+}
+
+td {
+  font-family: Verdana, Arial, Helvetica;
+  font-size: 10pt;
+}
+
+/* login and admin */
+.login {
+  font-family: Verdana, Arial, Helvetica;
+}
+body.login {
+  background: #5a7d9b;
+  color: black;
+}
+h1.login {
+  font-size: 18pt;
+}
+table.login {
+  background-color: #FBFFE7;
+  padding: 20px;
+}
+td.login {
+  text-align: center;
+}
+th.login {
+  text-align: right;
+}
+
+body.admin {
+  background-color: #FBFFE7;
+  color: black;
+}
+
+body.menu {
+  background-color: #FBFFE7;
+  font-family: Verdana, Arial, Helvetica;
+  font-size: 10pt;
+  color: black;
+}
+
+
+.listtop { font-size: 10pt; background-color: black; color: white; }
+.listheading { font-size: 10pt; background-color: #336666; color: white; }
+A.listheading:link, A.listheading:active, A.listheading:visited {
+  color: white;
+  text-decoration: none; }
+.listrow1 { background-color: #e6e6fa; color: black; vertical-align: top; }
+.listrow0 { background-color: #ffe4e1; color: black; vertical-align: top; }
+.listsubtotal { font-size: 10pt; background-color: #5a7d9b; color: white; }
+.listtotal { font-size: 10pt; background-color: black; color: white; }
+
+.submit {
+  font-size: 12pt
+  font-family: Verdana, Arial, Helvetica;
+  color: #000080;
+}
+.checkbox, .radio {
+  font-family: Verdana, Arial, Helvetica;
+  color: #778899;
+}
+
+.plus0 {    /* font color for negative numbers */
+  color: red;
+}
+
+.plus1 {
+  color: green;
+}
+
+h2.confirm {
+  color: blue;
+  font-size: 14pt;
+}
+
+h2.error {
+  color: red;
+  font-size: 14pt;
+}
+
+
+/* media stuff */
+
+@media screen {
+  .noscreen {   /* items with this class won't display */
+    display: none;
+  }
+}
+
+@media print {
+  .noprint {   /* items with this class won't print */
+    display: none;
+  }
+}
+
+
+
diff --git a/sql-ledger/doc/COPYING b/sql-ledger/doc/COPYING
new file mode 100644 (file)
index 0000000..083bb41
--- /dev/null
@@ -0,0 +1,355 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU General Public License</TITLE>
+</HEAD>
+
+<BODY BGCOLOR=ffffff>
+
+
+<pre>
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+        Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    &lt;one line to give the program's name and a brief idea of what it does.&gt;
+    Copyright (C) 19yy  &lt;name of author&gt;
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  &lt;signature of Ty Coon&gt;, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+
+</BODY>
+</HTML>
+
diff --git a/sql-ledger/doc/README b/sql-ledger/doc/README
new file mode 100644 (file)
index 0000000..7585f53
--- /dev/null
@@ -0,0 +1,287 @@
+                SQL-Ledger Accounting
+                     Version 2.0
+
+
+DESCRIPTION:
+------------
+SQL-Ledger is a double-entry accounting program written
+in perl. It has been tested with PostgreSQL, Oracle,
+Apache, Netscape, Mozilla, Galeon, Explorer, Links, Lynx,
+Konqueror, Voyager, W3M and Opera clients on Linux, FreeBSD,
+Solaris, Windows and Mac computers.
+
+Data is stored in a SQL server, either locally or remote,
+the display is through a text or GUI web browser. The system
+is linked by a chart of accounts.  All transactions for AR,
+AP and GL are stored in a transaction table. Hyper-links
+from the chart of accounts let you view transactions posted
+through AR, AP and GL.
+
+Configuration files let you specify to which SQL server
+to connect to, personal preferences such as company name,
+language, number and date format, etc.
+
+The admin script can be used to create, edit or delete users
+and to create and delete datasets and to setup the Chart
+of Accounts and templates needed for the system.
+It can be used for PostgreSQL and Oracle. If you want to
+use another SQL server the tables and chart of accounts
+must be created by hand.
+
+You can have a group of users using the same dataset and
+templates for generating Invoices, Income Statements and
+Balance Sheets or a different set altogether.
+
+Templates are supplied in html and tex format to generate
+most of the forms. Forms can be printed to screen, sent
+to a printer or to a mailer agent. To use the tex forms
+latex must be installed. Most systems have a latex binary
+installed by default. Latex is also available for Windows
+and the Mac so we stay compatible across all major platforms.
+
+
+COPYRIGHT:
+----------
+You may distribute under the terms of the GNU License.
+
+
+LATEST VERSION:
+---------------
+available from http://www.sql-ledger.org
+
+
+PLATFORMS:
+----------
+Non specific, see requirements.
+
+
+REQUIREMENTS:
+-------------
+1 - Perl, 5+
+2 - http server (Apache, NCSA, httpi, ...)
+3 - SQL Server with transaction support (PostgreSQL 7.0+, Oracle)
+4 - DBD (DBD-Pg, DBD-Oracle)
+5 - DBI
+6 - LaTeX (optional)
+
+
+FOREIGN LANGUAGE SUPPORT:
+-------------------------
+All the required files are in locale/country_code
+The main files are 'all' and 'missing'. You can enter
+translated strings in either file. When you are done
+run locales.pl from the command line to rebuild the
+required files.
+
+Some of the translation files are not 100% complete.
+If strings are missing, English is used instead.
+
+
+INSTALLATION:
+-------------
+unpack the tar.gz file in /usr/local
+
+  tar xzvf sql-ledger-x.x.x.tar.gz
+
+you should now have everything in /usr/local/sql-ledger
+
+copy sql-ledger.conf.default to sql-ledger.conf
+
+edit sql-ledger.conf
+
+create a file sql-ledger-httpd.conf in the same location
+where your httpd.conf is and copy the next section into the file
+
+  Alias /sql-ledger/ /usr/local/sql-ledger/
+  <Directory /usr/local/sql-ledger>
+    AddHandler cgi-script .pl
+    Options ExecCGI Includes FollowSymlinks
+  </Directory>
+
+  <Directory /usr/local/sql-ledger/users>
+    Order Deny,Allow
+    Deny from All
+  </Directory>
+
+edit httpd.conf and add
+
+  # SQL-Ledger
+  Include <ServerRoot>/sql-ledger-httpd.conf
+
+Note: Replace <ServerRoot> with the server's root directory!
+
+restart your web server.
+
+
+Note: /usr/local/sql-ledger is only a suggested
+path, you can install in any directory.
+
+
+INSTALLATION WITH setup.pl:
+---------------------------
+Make a directory
+
+  mkdir /usr/local/sql-ledger
+
+Copy setup.pl to /usr/local/sql-ledger
+
+run setup.pl as root and follow the prompts.
+
+Go to the next step, "PREPARE YOUR SQL SERVER".
+
+
+SET PERMISSION:
+---------------
+change directory to /usr/local/sql-ledger
+
+# chown nobody:nobody users templates
+
+replace nobody:nobody with the web server
+user of your system. Some systems use
+apache:apache, www, www-data, ...
+
+
+PREPARE YOUR SQL SERVER:
+------------------------
+
+  PostgreSQL:
+  -----------
+  add one database user with create database privileges
+  to manage the datasets and tables for SQL-Ledger
+  
+  # su postgres
+  $ createuser -d sql-ledger
+  
+  if you use passwords to access postgres set the user up with a password 
+  $ createuser -d -P sql-ledger
+
+  Answer no to the following question.
+  Shall the new user be allowed to create more new users? (y/n) n
+
+  You can add more database users to keep datasets
+  separated. Each dataset belongs to one company.
+  
+  
+  ORACLE:
+  -------
+  add one user and one tablespace
+  all datasets share the same tablespace
+  
+
+SETUP A DATABASE AND THE TABLES:
+--------------------------------
+Load your web browser and connect to
+http://localhost/sql-ledger/admin.pl
+
+Tables are created with the "Database
+Administration" function.
+
+Select the "Database Administration" link,
+enter a host, port and user you created in the
+previous step.
+
+The "Create Dataset" link queries the server
+for existing datasets and displays them in a
+column. Then you enter a name for the new
+dataset and select one of the Chart of Accounts
+and click on Continue.
+Your new dataset and the tables will be created
+and the selected Chart of Accounts loaded. The
+owner of the tables is the user you entered in
+the previous screen.
+
+NOTE: Be patient, some of the charts are really
+big and take some time to create.
+
+The "Delete Dataset" link queries the server
+for datasets which are in use by SQL-Ledger
+and are not used by any members. This may
+take a while to figure out. "Be patient".
+If there are any datasets not in use, you get
+a screen with the datasets listed where you
+can select the one you want to delete.
+
+NOTE: you cannot manage any other datasets
+from this interface, only the datasets used
+by SQL-Ledger.
+
+
+SETUP A USER:
+-------------
+Load your web browser and connect to
+http://localhost/sql-ledger/admin.pl
+
+Click on "Add User". In the Database
+section select the driver and enter
+the user you used to create the dataset.
+
+
+LOAD THE ACCOUNTING PROGRAM:
+----------------------------
+Load your web browser and connect to
+http://localhost/sql-ledger/login.pl
+
+
+UPGRADING TO A NEWER VERSION:
+-----------------------------
+1. unpack the new version over top
+2. check the doc directory for specific notes
+3. load admin.pl
+   click on "Database Administration"
+   enter the dba in the "Connect to" field
+   click on "Update Dataset"
+   select the datasets and click "Continue"
+
+
+UPGRADING WITH setup.pl:
+------------------------
+run setup.pl from the command line and follow
+the prompts.
+
+
+INSTALLATION CHECKLIST:
+-----------------------
+1. untar SL somewhere
+2. change permissions for the users and templates directory
+3. edit httpd.conf
+4. edit sql-ledger.conf
+5. a) add the database user sql-ledger in PostgreSQL
+   b) add a tablespace and the database user sql-ledger in Oracle
+6. load admin.pl
+7. create datasets for the companies
+8. add users
+
+   In the Database section enter
+   
+   a) PostgreSQL
+   
+      Host:     for local connections leave empty
+      Dataset:  the dataset created in step 7
+      Port:     for local connections leave empty
+      User:     sql-ledger
+      Password: password for sql-ledger
+      
+   b) Oracle
+   
+      SID:      system ID
+      Port:     the port Oracle is listening on
+      Dataset:  the dataset created in step 7
+      Password: password for connection
+   
+
+IF SOMETHING DOESN'T WORK:
+--------------------------
+There is a FAQ online which addresses various questions.
+see http://www.sql-ledger.org/misc/faq.html
+
+There are also several mailing lists at
+http://www.sql-ledger.org/misc/mailinglist.html
+where you can go for help.
+
+If you require support you can order online at
+http://www.sql-ledger.com/misc/support.html
+
+
+=====================================================================
+December 4, 2002
+
diff --git a/sql-ledger/doc/UPGRADE-1.6-1.8 b/sql-ledger/doc/UPGRADE-1.6-1.8
new file mode 100644 (file)
index 0000000..b5631b2
--- /dev/null
@@ -0,0 +1,61 @@
+Upgrading from version 1.6 to 1.8
+
+1. make a backup copy of your databases and SQL-Ledger, just in case!
+   $ cd /usr/local/www/sql-ledger
+   $ pg_dump database > db.out
+   $ tar cvf ~/sql-ledger.tar .
+   
+2. install SQL-Ledger over top of your old installation
+   $ cd /usr/local/www
+   $ tar zxvf sql-ledger-1.8.0.tar.gz
+   
+3. change the tables to the new layout
+   $ cd sql-ledger/sql
+   $ psql database < upgrade-1.6-1.8.sql
+
+4. copy the new master templates to your template directory
+   $ cd ../templates
+
+   $ cp Default-email_purchase_order.html your_template_dir/email_purchase_order.html
+   $ cp Default-purchase_order.html your_template_dir/purchase_order.html
+   $ cp Default-email_sales_order.html your_template_dir/email_sales_order.html
+   $ cp Default-sales_order.html your_template_dir/sales_order.html
+5. Two new accounts were hopefully added to your chart of accounts
+   One account for Foreign Exchange Gains and one for
+   Foreign Exchange Losses
+   edit and change to suit your COA. You can safely change
+   the account number too.
+      
+6. Edit your preferences
+
+   In field 'Stylesheet' enter -> sql-ledger.css
+   Stylesheet is in the css directory
+
+   Add your foreign currencies in the Currencies field
+   The first currency in the list is your default
+   i.e CDN:USD:EUR:YEN
+   If you used a nativecurr than it should be listed in the
+   new currencies field.
+
+7. <%nativecurr%> has changed to <%currency%>
+   edit all your templates and change nativecurr to currency
+
+8. I also added four more variables which can be used in your templates.
+   <%contact%>, <%shiptocontact%>, <%shiptophone%>, <%shiptofax%>
+   
+9. Nameing convention for templates has changed from an
+   underscore to a minus sign. If you designed your own
+   master templates rename the templates from
+   industry_invoice.html to industry-invoice.html,
+   industry_packing_list.html to industry-packing_list.html, etc.
+   The minus sign is used to separate the name and list them in
+   the setup screen.
+   
+   This change only applies to the master templates in the
+   templates root directory NOT the individual templates which
+   are used by users.
+
+It looks more than it really is. Steps 1 to 4 are important,
+the rest is for fine tuning and info.
+
diff --git a/sql-ledger/doc/UPGRADE-1.8-1.8.3 b/sql-ledger/doc/UPGRADE-1.8-1.8.3
new file mode 100644 (file)
index 0000000..babed37
--- /dev/null
@@ -0,0 +1,23 @@
+Upgrading from version 1.8.(0-2) to 1.8.3
+
+1. install SQL-Ledger over top of your old installation
+   $ cd /usr/local
+   $ tar zxvf sql-ledger-1.8.3.tar.gz
+
+2. copy sql-ledger.conf.default to sql-ledger.conf
+   $ cp sql-ledger.conf.default sql-ledger.conf
+
+   if you modified sql-ledger.conf merge the changes from the
+   .default file rather than copying over top.
+
+3. copy the new master templates to your template directory
+   $ cd ../templates
+
+   $ cp Default-invoice.tex your_template_dir/invoice.tex
+   $ cp Default-packing_list.tex your_template_dir/packing_list.tex
+   $ cp Default-purchase_order.tex your_template_dir/purchase_order.tex
+   $ cp Default-sales_order.tex your_template_dir/sales_order.tex
+4. edit sql-ledger.conf
+   instructions are in the file
+
diff --git a/sql-ledger/doc/UPGRADE-1.8.3-1.8.4 b/sql-ledger/doc/UPGRADE-1.8.3-1.8.4
new file mode 100644 (file)
index 0000000..c3ecdf5
--- /dev/null
@@ -0,0 +1,10 @@
+Upgrading from version 1.8.3 to 1.8.4
+
+1. install SQL-Ledger over top of your old installation
+   $ cd /usr/local
+   $ tar zxvf sql-ledger-1.8.4.tar.gz
+
+2. update the tables with the admin script
+
+   You will not be able to log in until you upgraded the tables.
+   
diff --git a/sql-ledger/doc/UPGRADE-1.8.4-1.8.5 b/sql-ledger/doc/UPGRADE-1.8.4-1.8.5
new file mode 100644 (file)
index 0000000..e8c32e1
--- /dev/null
@@ -0,0 +1,18 @@
+Upgrading from version 1.8.4 to 1.8.5
+
+1. install SQL-Ledger over top of your old installation
+   $ cd /usr/local
+   $ tar zxvf sql-ledger-1.8.5.tar.gz
+
+2. update the tables with the admin script
+
+   You will not be able to log in until you upgraded the tables.
+
+
+There are two new variables (<%customernumber%> and <%vendornumber%>)
+which can be used in the forms. These may be used instead of the
+internally generated customer_id and vendor_id.
+
+Typically these numbers are used to retrieve a customer, vendor
+by some ID. In most counter operations the phone number is used.
+
diff --git a/sql-ledger/doc/UPGRADE-1.8.5-1.8.7 b/sql-ledger/doc/UPGRADE-1.8.5-1.8.7
new file mode 100644 (file)
index 0000000..992238c
--- /dev/null
@@ -0,0 +1,6 @@
+Upgrading from version 1.8.5 to 1.8.7
+
+1. install SQL-Ledger over top of your old installation
+   $ cd /usr/local
+   $ tar zxvf sql-ledger-1.8.7.tar.gz
+
diff --git a/sql-ledger/doc/UPGRADE-1.8.7-2.0.0 b/sql-ledger/doc/UPGRADE-1.8.7-2.0.0
new file mode 100644 (file)
index 0000000..e16ba75
--- /dev/null
@@ -0,0 +1,20 @@
+Upgrading to Version 2.0.0
+
+1. install SQL-Ledger over top of your old installation
+   $ cd /usr/local
+   $ tar zxvf sql-ledger-2.0.0.tar.gz
+
+2. load admin.pl and update the tables
+
+   You will not be able to log in until the tables are up to date.
+
+3. copy the new templates to your personal template directory
+
+   $ cd templates
+   $ cp Default-check.tex dir/check.tex
+   $ cp Default-receipt.tex dir/receipt.tex
+   $ cp Default-statement.html dir/statement.html
+   $ cp Default-statement.tex dir/statement.tex
+
+   replace 'dir' with your directory name
+
diff --git a/sql-ledger/doc/UPGRADE-2.0-2.0.8 b/sql-ledger/doc/UPGRADE-2.0-2.0.8
new file mode 100644 (file)
index 0000000..6ddff62
--- /dev/null
@@ -0,0 +1,8 @@
+Upgrading from version 2.0.[0-7] to 2.0.8
+
+1. install SQL-Ledger over top of your old installation
+   $ cd /usr/local
+   $ tar zxvf sql-ledger-2.0.8.tar.gz
+
+2. update your datasets with the admin script
+
diff --git a/sql-ledger/doc/copyright b/sql-ledger/doc/copyright
new file mode 100644 (file)
index 0000000..d493a3d
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2003, Dieter Simader
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/doc/faq.html b/sql-ledger/doc/faq.html
new file mode 100644 (file)
index 0000000..0f6f237
--- /dev/null
@@ -0,0 +1,747 @@
+<ul>
+<p><li><h4>Sub-menus and Apache 2.0</h4>
+Some versions of Apache 2.0 (2.0.44+) don't expand sub-menus and generate
+a 500 error at various points. This stems from workaround developed for
+earlier versions of Apache 2.0. It looks like this workaround must now be
+disabled. If you get an error or the sub-menus don't expand edit
+SL/Form.pm and comment lines 80-82.
+<pre>
+  # for Apache 2 we escape strings twice
+#  if (($ENV{SERVER_SOFTWARE} =~ /Apache\/2/) && !$beenthere) {
+#    $str = $self->escape($str, 1);
+#  }
+</pre>
+
+
+<p><li><h4>About installation</h4>
+The easiest is to use the setup.pl script as root.
+You don't need to know very much about your system, just login as root,
+run 'perl setup.pl' and follow the prompts.
+<p>setup.pl does not check for missing software packages and it is your
+responsibility to make sure you have the required pieces
+installed either from source or from a package supplied with your distro.
+
+<p>Requirements are clearly indicated in the README file and on the
+download page.
+
+
+<p><li><h4>IDENT Authentication failed for user "postgres"</h4>
+
+This error has everything to do with the way the distros set up
+access rights for postgres. They are way too restrictive and leave you
+wondering what to do next.
+
+<p>Do yourself a favour and change authentication in pg_hba.conf to
+
+<pre>
+local           all              trust</pre>
+
+<p>until you have figured what all this stuff in pg_hba.conf does.
+
+<p><b>NOBODY</b>, I repeat, <b>NOBODY</b>, from the Internet will be able to
+connect to postgres. You can't even connect from the inside LAN, the only
+one who is allowed to connect are clients originating from localhost.
+
+<p>Read a bit about the different authentication settings and change
+them as you see fit.
+It is all described in detail in pg_hba.conf
+
+<p>If you can't find the file, there is a wonderful utility called find.
+Use it.
+<pre>
+# find /usr/local -type f -name 'pg_hba.conf'
+</pre>
+
+
+<p><li><h4>DBD-Pg for Mandrake 9.0</h4>
+Mandrake did not package a compiled DBD-Pg package again, so install DBD-Pg
+from the source package.
+Install perl-DBD-Pg-1.01-4mdk.i586.rpm from the 'contrib' area.
+(Mandrake / 9.0 / contrib / RPMS)
+
+<p><li><h4>LaTeX error</h4>
+If for some reason LaTeX produces an error message check for strange
+characters in your account description and parts description
+and use \usepackage[latin1]{inputenc} in the preamble.
+
+
+<p><li><h4>LaTeX templates</h4>
+If you don't want to edit tex code by hand,
+you could use Lyx, Abiword, or any WYSIWYG editor capable of exporting
+latex code.
+To do that you must change the tokens for parameters <% and %> to something
+like << and >>. % is the comment character in tex. There is also a
+pagebreak block which must be commented out.
+When you are done with the changes
+replace << and >> with <% and %> and uncomment the pagebreak block.
+
+<p>LaTeX is difficult but it also offers a much superior interface to produce
+professionally looking forms in postscript and PDF format.
+Unfortunately with power comes some pain too.
+
+
+<p><li><h4>W3M</h4>
+pass terminal=mozilla when you start w3m
+<pre>$ w3m -F http://localhost/sql-ledger/login.pl?terminal=mozilla</pre>
+
+To use without frames
+<pre>$ w3m http://localhost/sql-ledger/login.pl?terminal=lynx</pre>
+
+<p><li><h4>PDF option disappeared</h4>
+Edit sql-ledger.conf and set $latex = 1;
+<br>sql-ledger.conf is perl code, check if it compiles, if it does not
+the internal defaults are used which set $latex to 0, hence no PDF option.
+
+<p><li><h4>SQL-Ledger on Mac Os X 10.1.5</h4>
+Jaume Teixi put together
+<a href=http://www.rocacorbit.com/techdocs/sql_ledger_os_x.html>
+installation instructions</a> to run SL on a Mac.
+<br>The instructions are for 1.8.5 however they still apply to any of the
+newer versions.
+
+<p><li><h4>Installation on Windows (WIN32)</h4>
+<ul>
+<li>install Apache, perl,
+<a href=http://techdocs.postgresql.org/guides/InstallingOnWindows>Postgres</a>
+or Oracle, DBI and the appropriate DBD
+module
+<br>if you can't compile DBD-Pg here is a precompiled
+<a href=http://www.edmund-mergl.de/export/>DBD-Pg module</a>
+<li>download the latest version of <a href=/cgi-bin/nav.pl?page=source/index.html&title=Download>SQL-Ledger</a>
+<li>extract the files to c:\apache\sql-ledger
+<li>download
+<a href=../source/sql-ledger-windows.tar.gz>sql-ledger-windows.tar.gz</a>
+and extract the files to c:\apache\sql-ledger
+    <br>the shebang line is changed to c:\perl\bin\perl and the symlinks
+    are regular files
+<br>answer with 'Yes' to overwrite existing files.
+<li>edit c:\apache\conf\httpd.conf and add
+<pre>
+Alias /sql-ledger/ "C:/apache/sql-ledger/"
+&lt;Directory "c:/apache/sql-ledger"&gt;
+  AllowOverride All
+  AddHandler cgi-script .pl
+  Options +ExecCGI
+  Order Allow,Deny
+  Allow from All
+&lt;/Directory&gt;
+
+&lt;Directory "c:/apache/sql-ledger/users"&gt;
+  Order Deny,Allow
+  Deny from All
+&lt;/Directory&gt;
+</pre>
+
+<li>start Apache
+<li>start Postgres|Oracle
+<li>connect to http://localhost/sql-ledger/admin.pl and setup users
+and datasets
+<li>connect to http://localhost/sql-ledger/login.pl and login
+
+</ul>
+
+<p><li><h4>Installation on Windows /w cygwin</h4>
+<ul>
+<li>install <a href=http://sources.redhat.com/cygwin/>cygwin</a>
+Apache, perl, postgres, gcc and lynx
+<li>install <a href=http://search.cpan.org/search?module=DBI>DBI</a>
+<li>tar zxvf DBI-1.30.tar.gz
+<li>cd DBI-1.30
+<li>perl Makefile.PL
+<li>make install
+<li>install <a href=http://search.cpan.org/search?dist=DBD-Pg>DBD-Pg</a>
+<li>tar -zxvf DBD-Pg-1.13.tar.gz
+<li>export POSTGRES_INCLUDE=/usr/include/postgresql
+<li>export POSTGRES_LIB=/usr/lib/postgresql
+<li>cd DBD-Pg-1.13
+<li>perl Makefile.PL
+<li>make install
+<li>edit /etc/apache/httpd.conf and add
+<pre>
+AddHandler cgi-script .pl
+Alias /sql-ledger/ /var/www/sql-ledger/
+&lt;Directory /var/www/sql-ledger&gt;
+  Options +ExecCGI
+&lt;/Directory&gt;
+
+&lt;Directory /var/www/sql-ledger/users&gt;
+  Order Deny,Allow
+  Deny from All
+&lt/Directory&gt;
+</pre>
+<li>install SQL-Ledger
+<li>cd /var/www
+<li>mkdir sql-ledger
+<li>download <a href=/cgi-bin/download.pl?setup.pl>setup.pl</a> and save the file
+in /var/www/sql-ledger
+<li>cd /var/www/sql-ledger
+<li>perl setup.pl
+</ul>
+
+<p><li><h4>What do I enter for the language</h4>
+If you use English, nothing, if you want to use a foreign language for
+the login screen and admin stuff enter the language code. All the
+language specific files are in the locale directory. The long form for
+the language is in the LANGUAGE file.
+
+<p><li><h4>Mandrake 9.0 permission denied error</h4>
+Mandrake says to add this to your commonhttpd.conf
+<pre>
+&lt;Directory /usr/local/sql-ledger&gt;
+   AllowOverride All
+   Options -MultiViews -Indexes -FollowSymLinks
+   Order allow,deny
+   Allow from all
+&lt;/Directory&gt;
+
+The way apache starts is it:
+Blocks all access to the physical file system /
+Opens access to the physical file system /var/www/html
+Opens access to the physical file system /var/www/perl
+Opens access to the physical file system /var/www/cgi-bin
+Opens access to the physical file system /var/www/protected-cgi-bin 
+Opens access to the physical file system /home/*/public_html
+Opens access to the physical file system /home/*/public_html/cgi-bin
+Opens access to the physical file system /var/www/icons
+Opens access to the physical file system /usr/share/doc
+
+Since you're trying to access files outside of those allowed paths, you
+have to specifically allow it.  It's done this way because of some past
+exploits with the pathnames.  Rather than trust that there will never be
+another bug within apache that will let you get somewhere you don't
+want, you set it up securely out of the box so that apache won't let
+itself go somewhere that you don't want it to.
+</pre>
+
+
+<p><li><h4>Incorrect Dataset version</h4>
+The dataset you are trying to use is not compatible with the version.
+When you upgrade datasets use the same database user in the "User"
+field as the one listed in the Database section for the user.
+
+
+<p><li><h4>Mandrake 8.2</h4>
+Mandrake did not include the package "perl-DBD-Pg-1.01-1mdk.i586.rpm"
+You can install the package from Mandrake 8.1
+
+
+<p><li><h4>printing to a printer</h4>
+Setup a printer in the "Printer" field in the users preferences.
+i.e lpr -Plaser
+and set $latex = 1 in sql-ledger.conf
+LaTeX must be installed for this to work.
+
+<p>To send the document to the printer check the "Postscript" or "PDF" format,
+enter the number of copies and click on the "Print" button.
+
+<p>The printer field is available only when you edit the user's
+preferences with admin.pl.
+
+<p>Note: html format is for screen preview. Use your browser's
+print function.
+
+
+<p><li><h4>beginning balances</h4>
+Add a GL Journal entry and enter the beginning balance for your accounts.
+Use your balance sheet. If you also want to add open invoices, add the invoices
+and make the appropriate adjustments. Your balance sheet includes these
+amounts!
+
+
+<p><li><h4>cost for parts and service</h4>
+the cost will be updated when you purchase goods and services. You can
+enter the cost manually. This is so you can have a cost on file without
+making a purchase.
+
+
+<p><li><h4>establish a beginning inventory</h4>
+add the parts with a purchase invoice. Use the <b>real cost</b> for the items
+not zero. If you use zero cost then the cost of goods will be zero when you
+sell the item.
+
+
+<p><li><h4>Assemblies</h4>
+Assemblies are manufactured goods assembled from parts, services and
+assemblies.  Because you do not buy assemblies you 'stock assemblies' by
+adding assembled units to your inventory. The quantity for individual parts 
+is reduced and the quantity for the assembly increased. To disassemble an
+assembly you simply return the parts to inventory by entering a negative
+quantity for the number of assemblies to stock.
+
+
+<p><li><h4>customizing SQL-Ledger</h4>
+The <a href=/cgi-bin/nav.pl?page=feature/api.html&title=Application%20Interface>application interface</a>
+consists of a global and private interface.
+
+
+<p><li><h4>DBD-Pg not installed</h4>
+
+Most modern distributions now package DBD-Pg. If it is
+not packaged follow this recipe to get it working.
+
+<ul>
+  <li>check if you have the header files for PostgreSQL
+  <br>$ find / -name 'libpq-fe.h'
+  <br>if nothing shows up install the development package for PostgreSQL
+  <li>download and untar DBD-Pg
+  <li>set the environment variables POSTGRES_LIB and POSTGRES_INCLUDE
+  <li>cd to DBD-Pg directory
+  <br>as ordinary user
+  <br>$ perl Makefile.PL
+  <br>$ make
+  <br>$ make test
+  <br>if all went well su to root
+  <br># make install
+  <li>remove DBD-Pg
+</ul>
+
+
+<p><li><h4>SuSE 8.1 installation</h4>
+<ol>
+<li>Install the following using YaST2:
+
+<p>- perl-DBD-Pg
+<br>- postgresql
+<br>- postgresql-contrib
+<br>- postgresql-devl
+<br>- postgresql-docs
+<br>- postgresql-libs
+<br>- postgresql-perl
+<br>- postgresql-server
+<br>- postgresql-test
+
+<p><li>Setup directories and paths for PostgreSQL:
+
+<p>> sux -     (change to root)
+
+<p>- If not done by the installation, setup disk directory for your db:
+<br># mkdir /var/lib/pgsql/data
+<br># chown postgres /var/lib/pgsql/data
+
+<p><li>Initialize the database, and start it, as below:
+<p>Note that there are man pages for initdb and pg_ctl.
+          
+<p># touch /var/log/pgsql
+<br># chown postgres:postgres /var/log/pgsql
+<br># sux postgres
+  
+<p>- Initialize postgres:
+<br>> /usr/bin/initdb -D /var/lib/pgsql/data
+<br>(creating ... Success...)
+
+<p>- Start the postgres daemon:
+<br>> /usr/bin/pg_ctl -D /var/lib/pgsql/data -l /var/log/pgsql start (start db)
+<br>(postmaster successfully started)
+
+<p><li>Quick-test the server (still as user postgres):
+
+<p>- > psql -d template1
+<br>(Welcome ... \q to exit psql)
+<br>\q
+
+<p>- Try setting up another db user:
+   
+<p>> createuser &lt;db-user&gt; (&lt;db-user&gt; should match an existing Linux user)
+<br>Shall the new user be allowed to create databases? (y/n) y
+<br>Shall the new user be allowed to create more new users? (y/n) n
+
+<p>Unless a problem with DBD::Pg (perl interface), postgres is ready to go.
+
+<p><li>If a previous sql-ledger database needs to be installed,
+<br>do the following as postgres user.  Steps for dumping the old db,
+   and building the new follow:
+
+<p>> sux postgres
+<br>> psql template1
+<br>=# CREATE DATABASE my_database;  (create your database)
+<br>=# \q
+<br>> cd /var/lib/pgsql/backups        (assuming your backups are here)
+<br>The next command should have been performed earlier from the
+  previous installed version of postgres and your database:
+<br>> pg_dump -d my_database.sql.bak   (from previous ver postgres)
+<br>> cp my_database.sql.bak my_database.sql
+<br>- Use vi to change all occurrances of 'current_date' to current_date
+    in file my_database.sql .
+<br>The vi command for this is :g/'current_date'/s//current_date/g
+<br>> psql my_database < my_database.sql > my_database.log
+<br>- Check my_database.log for errors.
+
+<p><li>Download setup.pl and run it as root while on line to the internet:
+
+<p># mkdir /usr/local/sql-ledger
+<br># cd /usr/local/sql-ledger
+<br># ./setup.pl
+<br>- Enter i
+<br>- Enter httpd owner and group if different than displayed default.
+<br>(Download occurs and status is displayed...)
+
+<p><li>Setup the new sql-ledger with database.
+
+<p>- Surf to http://my_computer/sql-ledger/admin.pl
+<br>- Click enter (no password needed).
+<br>->Database Administration
+<br>- Leave fields Host and Port enpty for local installations.
+<br>          - Enter your database name in the "Connect to" field.
+<br>     - Enter the database user you setup (postgres, sql-ledger, etc.)
+<br>     - Enter a password, only if a password is assigned to the database.
+<br>     - To update an existing sql-ledger database: ->Update Database
+<br>        Should see: The following Datasets need to be updated.
+<br>        ->Continue
+<br>        Do more admin.  You will need to setup at least one login.
+<br>        To exit: ->Database Admin
+
+<p><li>See if it works:
+
+<p>   - Surf to http://my_computer/sql-ledger/login.pl
+<br>   - Enter the login name you just created.  Main menu screen should appear.
+</ol>
+                                   
+
+
+<p><li><h4>Redhat Installation</h4>
+
+<ul>
+<li>Install apache1.3.12-25.i386.rpm
+<li>Install perl5.6.0-9.i386.rpm
+<li>Install postgresql-7.0.2-17.i386.rpm
+<li>Install postgresql-server-7.0.2-17.i386.rpm
+<li>Install postgresql-devel-7.0.2-17.i386.rpm (POSTGRES_INCLUDE)
+<li>tar xvzf DBI-1.14.tar.gz
+<li>cd DBI-1.14
+<li>perl Makefile.PL
+<li>make
+<li>make install
+<li>cd ..
+<li>tar xvzf DBD-Pg-0.95
+<li>cd DBD-Pg-0.95
+<li>export POSTGRES_LIB=/usr/lib/pgsql
+<li>export POSTGRES_INCLUDE=/usr/include/pgsql
+<li>perl Makefile.PL
+<li>make
+<li>make install
+<li>install SQL-Ledger
+</ul>
+
+<p>Some of the applications have newer versions however the installation
+instructions remain the same. Just substitute the old version with a newer
+version.
+
+
+<p><li><h4>Debian Installation</h4>
+
+<ul>
+<li>unpack into /usr/local/www/sql-ledger
+<li>install postgresql (Dselect)
+<li>install apache (Dselect)
+<li>install libdbi-perl (Dselect)
+<li>install libdbd-pg-perl (Dselect)
+<li>install libpgperl (Dselect)
+<li>modify /etc/postgresql/postgresql.conf
+    <br>TCPIP_SOCKET = 1
+<li>create a user for managing SQL-Ledger databases
+<br>from root
+<br>su postgres
+<br>$ createuser -d sql-ledger
+<br>if you use passwords to access postgres set the user up with a password
+<br>$ createuser -d -P sql-ledger
+<li>change /etc/apache/httpd.conf and add
+<pre>
+AddHandler cgi-script .pl
+Alias /sql-ledger/ /usr/local/www/sql-ledger/
+&lt;Directory /usr/local/www/sql-ledger&gt;
+  Options +ExecCGI
+&lt;/Directory&gt;
+
+&lt;Directory /usr/local/www/sql-ledger/users&gt;
+  Order Deny,Allow
+  Deny from All
+&lt;/Directory&gt;
+</pre>
+<li>restart apache
+<li>change fileownership of users and templates to www-data
+    <br>chown www-data: users templates
+<li>From browser enter http://localhost/sql-ledger/admin.pl
+<li>Login as the postgres user (account manager) you have created (above)
+<br>Create a DB
+<br>Create users
+
+<li>then enter http://localhost/sql-ledger/login.pl
+<br>Login as one of the users you have just created
+
+</ul>
+
+<p>
+The long version was provided by Gordon Haverland.
+<p>
+<ul>
+<li>You need to unpack the SQL-Ledger package (compressed tar archive)
+    someplace. Unpacking it in<pre>
+      /usr/local/www/sql-ledger.</pre>
+    Remember where you have unpacked it.
+<li>SQL-Ledger requires that the PostgreSQL database be installed.
+This is a very full-featured database, and has many associated
+packages.  SQL-Ledger requires version 7.0 or better.  The name
+of the basic package on Debian is postgresql.  To find if you
+already have postgresql installed, and if so what version, the
+following command should work:<pre>
+      dpkg -l | grep -i 'ii  postgresql '</pre>
+    A typical response would be:<pre>
+      ii  postgresql     7.1.3-5        Object....[stuff deleted]</pre>
+    Indicating, that version 7.1.3 is installed (the -5 is a
+    Debian patch level).  You can use dselect or apt-get to install
+    postgresql if you need to.  You can visit the Debian maintainer's
+    page for much more information on related packages at<pre>
+      http://people.debian.org/~elphick/postgresql/</pre>
+    Older versions of Debian's PostgreSQL installation use a file
+    called postmaster.init, while newer versions use a file called
+    postmaster.conf, either residing in /etc/postgresql.
+<li>SQL-Ledger requires a HTTP server (or daemon) which is capable of
+    handling CGI scripts.  Apache is the one which is recommended,
+    version 1.3 or better.  Debian calls the base package apache.
+    Debian has two alternative versions of Apache, one with mod-perl
+    (apache-perl) support compiled in, and the other with SSL 
+    (secure sockets layer - apache-ssl) support.  SQL-Ledger doesn't
+    require mod-perl or SSL support, but works with either if
+    you need it installed for other functions you have.  Older versions
+    of Debian Apache installations, spread the configuration of the
+    server across 3 files (srm.conf, access.conf and httpd.conf).
+    Newer versions have consolidated all of this to httpd.conf.
+<li>SQL-Ledger uses the Data Base Interface perl module for communication
+    with PostgreSQL.  The CPAN (Comprehensive Perl Archive Network)
+    name for this module is DBI.  Debian calls this module
+    libdbi-perl.  You should probably deselect (or apt-get) the
+    Debian version of this module to minimize upgrading headaches in
+    the future.
+<li>DBI requires the use of an implementation specific Data Base
+    Driver.  In our case, we need the PostgreSQL specific one.
+    CPAN calls this module DBD::PG, Debian calls it libdbd-pg-perl.
+    You should use dselect (or apt-get) to install it.
+<li>One more layer of Perl - PostgreSQL support is needed.  Debian
+    calls this last package libpgperl.  Use dselect or apt-get to
+    install it.  (You should be able to install all 5 packages at
+    one time.)
+<li>We need to allow your PostgreSQL database to accept queries
+    in a network manner.  To do this, we need to change the value
+    of the TCPIP_SOCKET to 1.  In newer
+    PostgreSQL installs, this variable will be someplace in 
+    /etc/postgresql/postgreslq.conf (older installs will be
+    postmaster.init, same directory.  Note: you shouldn't have
+    both files there.)  Start up your favorite text editor, find
+    the line with that variable on it, change the "no" to a "yes",
+    and make sure the line isn't commented out (a "#" in front
+    of it on the same line).
+<li>PostgreSQL has a set of users and passwords independent of
+    normal user logins.  We need to set up a PostgreSQL user
+    to "own" the SQL-Ledger data (choose a name that makes sense
+    to you, it shouldn't be "root" or "postgres").  The (PostgreSQL)
+    program for doing this is called "createuser".  To make this
+    SQL-Ledger owner user, we first need to "become" the PostgreSQL
+    superuser (on Debian, this is "postgres"), and then we will
+    run the createuser program.  So, once we are logged in as root:
+<pre>
+      # su postgres
+      $ createuser -d sql-ledger
+    ...
+      $ exit
+      # 
+</pre>
+    As shown above, we then typed "exit" after createuser was done,
+    to stop being the "postgres" user.  The "-d" switch (you called
+    also use "--createdb") specifies that this user can create
+    databases.
+<li>We need to adjust the configuration of the HTTP server Apache
+    next.  Older Apache installations (srm.conf, access.conf and
+    httpd.conf) need changes in srm.conf and httpd.conf.  Newer
+    installations just need to edit /etc/apache/httpd.conf.  First,
+    we need to instruct the server that files that end in ".pl"
+    are to be treated as "cgi-script"s (srm.conf if separate).<pre>
+      AddHandler cgi-script .pl</pre>
+    Second, we need to map our SQL-Ledger installation to be easy
+    for users to find it (in srm.conf if separate).<pre>
+      Alias /sql-ledger/ /usr/local/www/sql-ledger/</pre>
+    The "/" at the end of sql-ledger in both strings is important!
+    Next, we need to allow the server to execute files from those
+    directories, include things and follow links.  This information
+    is in httpd.conf (old or new installations).<pre>
+      &lt;Directory /usr/local/www/sql-ledger&gt;
+        Options ExecCGI Includes FollowSymLinks
+      &lt;/Directory&gt;</pre>
+    If we decided to put SQL-Ledger somewhere other than
+    /usr/local/www/sql-ledger, we would use different paths above.
+<li>All the files in the "users" and "templates" subdirectories
+    of /usr/local/www/sql-ledger need to be owned by "www-data".<pre>
+      # cd /usr/local/www/sql-ledger
+      # chown www-data:www-data users templates users/members</pre>
+    You may get an "error" about users/members not existing.  It
+    is safe to ignore this error.
+<li>Restart the apache server.<pre>
+      /etc/init.d/apache restart</pre>
+<li>From a browser, visit the URL<pre>
+      http://localhost/sql-ledger/admin.pl</pre>
+<li>Login as the PostgreSQL user responsible for the SQL-Ledger
+    database you set up.  Create a database and create
+    at least one user.  (It's not a good idea to access your
+    SQL-Ledger data as the "owner" of the data on a regular basis.)
+<li>Visit<pre>
+      http://localhost/sql-ledger/login.pl</pre>
+    and login as the user you created</pre>
+
+</ul>
+
+
+<p><li><h4>login.pl has compilation error</h4>
+
+This could be because of a missing configuration file in the users directory
+
+<p>check the permission for the users directory. The directory must be
+set writeable for the webserver. If your webserver runs under nobody.nogroup
+set it to
+<pre>
+drwxrwx--x   2 johndoe  nogroup    1024 May 26 16:49 users
+
+or
+
+drwx--x--x   2 nobody   nogroup    1024 May 26 16:49 users
+</pre>
+
+
+<p><li><h4>script not executing, shows in browser instead</h4>
+
+Add
+
+<pre>
+  AddHandler cgi-script .pl
+</pre>
+
+in your httpd.conf file.
+
+
+<p><li><h4>unknown terminal!</h4>
+the frontend script couldn't figure out which browser you are using
+<p>include the terminal variable on the URL
+<pre>
+  http://localhost/sql-ledger/login.pl?terminal=lynx</pre>
+<p>Valid terminal variables are lynx and mozilla
+
+
+<p><li><h4>permission denied at filesystem level</h4>
+
+Check if your web server has write permission to write to the following
+files and directories:
+<pre>
+  users/
+  templates/
+  users/members
+
+  # chown nobody:nogroup users templates users/members
+</pre>
+
+
+<p><li><h4>permission denied to access tables</h4>
+The user you entered in the "Database section" must be a valid
+database user who has the rights to access the tables.
+
+<p>If the tables are owned by 'john' and you enter 'mary' as the dba
+you might run into this problem if mary doesn't have the rights to
+access tables owned by john.
+
+
+<p><li><h4>html and graphics files don't show up on screen</h4>
+
+Enable Includes and FollowSymlinks Options in your httpd.conf file
+<pre>  &lt;Directory /usr/local/sql-ledger&gt;
+    Options ExecCGI Includes FollowSymlinks
+  &lt;/Directory&gt;
+</pre>
+
+
+<p><li><h4>Can I use mySQL</h4>
+
+No. mySQL lacks certain features required by SQL-Ledger.
+
+
+<p><li><h4>switch display to a foreign language</h4>
+
+Load your preferences and select the language.
+<br>Language selection is in accordance to 
+<a href=http://www.unece.org/cefact/locode/service/main.htm>
+ISO 3166-1</a> standards.
+
+
+<p><li><h4>Text shows in English when I use a foreign language</h4>
+
+This is because the corresponding hash entry is missing.
+Add the missing text in the locale/cc/all or locale/cc/missing
+file and run 'perl locales.pl' to rebuild the individual files.
+
+<br>cc refers to the country code.
+
+
+<p><li><h4>switch to a foreign language for the login and admin screen</h4>
+
+Edit sql-ledger.conf and enter the code for the variable
+$language. If your language specific files are in 'locales/cc', enter 'cc'
+
+
+</ul>
+
+<p>
+<hr>
+<a name=security>
+<h1>SQL-Ledger security</h1>
+</a>
+
+<ul>
+<li>The security features built into SQL-Ledger provide encrypted passwords
+and access control which makes it fairly safe out of the box to run even in
+front of a firewall.
+Some precautions which are out of our control must be taken though.
+It matters where you install SL and how you configure your web and SQL server.
+
+<pre>
+  Typical setups:
+  
+  /usr/local/vh/www                   <- DocumentRoot for virtual host
+  /usr/local/vh/sql-ledger            <- Alias for sql-ledger
+  /usr/local/vh/users                 <- users directory out of reach
+
+<hr width=60% align=left>
+  /usr/local/vh/www                   <- DocumentRoot for virtual host
+  /usr/local/vh/www/sql-ledger        <- Alias for sql-ledger
+  /usr/local/vh/www/sql-ledger/users  <- users configuration files and tmp space
+
+  &lt;Directory /usr/local/vh/www/sql-ledger/users&gt;  <- disable webserver access
+    Order Deny,Allow                                 for users directory
+    Deny from All
+  &lt;/Directory&gt;
+
+</pre>
+
+The location for the users directory can be specified in sql-ledger.conf
+
+<p><li>Set permission for the users and templates directory to 711
+(most restrictive)
+
+<p><li>If you do not want anyone to change the templates with the built-in
+editor set the files in templates/directory/ to read only or disable
+the menu item to edit the templates.
+
+<p><li>For PostgreSQL you can set who has access to the server in the file
+pg_hba.conf
+<br>Authentication crypt does not work because not all SQL servers
+accept encrypted passwords.
+
+<p><li>in addition you can secure the tables from unauthorized access by
+setting up a different database user and GRANT rights. For instance,
+users without DELETE rights will still be able to use the program, change
+customers or vendors but will not be able to delete transactions.
+To lock all the tables GRANT SELECT rights only.
+
+<p><li>Other security options include a secure shell, your webserver's
+authentication system, SSL, encrypted tunnels, ...
+
+</ul>
+
+</BODY>
+</HTML>
+
diff --git a/sql-ledger/favicon.ico b/sql-ledger/favicon.ico
new file mode 100644 (file)
index 0000000..43578f4
Binary files /dev/null and b/sql-ledger/favicon.ico differ
diff --git a/sql-ledger/locale/br/COPYING b/sql-ledger/locale/br/COPYING
new file mode 100644 (file)
index 0000000..133af7d
--- /dev/null
@@ -0,0 +1,24 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2002
+#
+# Brazilian texts:
+#
+#  Author: Andre Felipe Machado <andremachado@techforce.com.br>
+#          Miguel Koren O'Brien de Lacy <miguelk@konsultex.com.br>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/br/LANGUAGE b/sql-ledger/locale/br/LANGUAGE
new file mode 100644 (file)
index 0000000..d45d52d
--- /dev/null
@@ -0,0 +1 @@
+Brazilian Portuguese
diff --git a/sql-ledger/locale/br/admin b/sql-ledger/locale/br/admin
new file mode 100644 (file)
index 0000000..c5cd2e1
--- /dev/null
@@ -0,0 +1,122 @@
+$self{texts} = {
+  'Access Control'              => 'Controle de Acesso',
+  'Accounting'                  => 'Contabilidade',
+  'Add User'                    => 'Adicionar Usuário',
+  'Address'                     => 'Endereço',
+  'Administration'              => 'Administração',
+  'Administrator'               => 'Administrador',
+  'All Datasets up to date!'    => 'Todos grupos de dados atualizados!',
+  'Change Admin Password'       => 'Trocar senha de administração',
+  'Change Password'             => 'Trocar senha',
+  'Character Set'               => 'Conjunto de caracteres',
+  'Click on login name to edit!' => 'Clique no nome de acesso  para editar',
+  'Company'                     => 'Companhia',
+  'Connect to'                  => 'Conectar a',
+  'Continue'                    => 'Continuar',
+  'Create Chart of Accounts'    => 'Criar Carta de Contas',
+  'Create Dataset'              => 'Criar conjunto de dados',
+  'DBI not installed!'          => 'Driver de Interface de Banco de dados NÃO INSTALADO!',
+  'Database'                    => 'Banco de Dados',
+  'Database Administration'     => 'Administração da Base de Dados',
+  'Database Driver not checked!' => 'Driver do banco de dados não selecionado!',
+  'Database User missing!'      => 'Usuário da base de dados faltando!',
+  'Dataset'                     => 'Conjunto de dados',
+  'Dataset missing!'            => 'Conjunto de dados faltando!',
+  'Dataset updated!'            => 'Conjunto de dados atualizado',
+  'Date Format'                 => 'Formato de Data',
+  'Delete'                      => 'Apagar',
+  'Delete Dataset'              => 'Apagar conjunto de dados',
+  'Directory'                   => 'Diretório',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Limite de dropdown',
+  'E-mail'                      => 'E-Mail',
+  'Edit User'                   => 'Editar Usuário',
+  'Existing Datasets'           => 'Conjunto de dados existentes',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Servidor',
+  'Hostname missing!'           => 'Nome do servidor faltando!',
+  'Incorrect Password!'         => 'Senha incorreta!',
+  'Language'                    => 'Idioma',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Deixe os campos de  servidor e porta vazios a menos que você queira fazer uma conexão remota',
+  'Login'                       => 'Acessar/login',
+  'Name'                        => 'Nome',
+  'New Templates'               => 'Novos Modelos',
+  'No Database Drivers available!' => 'Nenhum driver de banco de dados disponível!',
+  'No Dataset selected!'        => 'Nenhum conjunto de dados selecionado!',
+  'Nothing to delete!'          => 'Nada para apagar!',
+  'Number Format'               => 'Formato de números',
+  'Oracle Database Administration' => 'Administração da Base de Dados Oracle',
+  'Password'                    => 'Senha',
+  'Password changed!'           => 'Senha trocada!',
+  'Pg Database Administration'  => 'Administração da Base de Dados PostgreSQL',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Porta',
+  'Port missing!'               => 'Porta faltando!',
+  'Printer'                     => 'Impressora',
+  'Save'                        => 'Salvar',
+  'Select a Dataset to delete and press "Continue"' => 'Selecione um conjunto de dados para APAGAR e pressione Continue',
+  'Setup Templates'             => 'Modelos de Configuração',
+  'Ship via'                    => 'Transportar via',
+  'Signature'                   => 'Assinatura',
+  'Stylesheet'                  => 'Folha de estilos',
+  'Templates'                   => 'Modelos',
+  'The following Datasets are not in use and can be deleted' => 'Os seguintes conjuntos de dados NÃO estão em uso e PODEM ser apagados',
+  'The following Datasets need to be updated' => 'Os seguintes grupos de dados precisam ser atualizados',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Esta é uma verificação preliminar por fontes existentes. Nada será criado ou apagado neste estágio!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Para adicionar um usuário a um grupo edite um nome, troque o nome de acesso/login e  salve. Um novo usuário com as mesmas variáveis será então salvo sob o novo nome de acesso/login.',
+  'Update Dataset'              => 'Atualizar grupo de dados',
+  'Use Templates'               => 'Use Modelos',
+  'User'                        => 'Usuário',
+  'User deleted!'               => 'Usuário apagado!',
+  'User saved!'                 => 'Usuário salvo',
+  'Version'                     => 'Versão',
+  'You must enter a host and port for local and remote connections!' => 'Você precisa entrar um servidor e uma porta para conexões locais e remotas!',
+  'does not exist'              => 'Não existe',
+  'is already a member!'        => 'já é um membro!',
+  'localhost'                   => 'localhost /servidor local',
+  'successfully created!'       => 'Criado com sucesso!',
+  'successfully deleted!'       => 'Apagado com sucesso!',
+  'website'                     => 'website',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'adicionar_usuário'           => 'add_user',
+  'trocar_senha_de_administração' => 'change_admin_password',
+  'trocar_senha'                => 'change_password',
+  'continuar'                   => 'continue',
+  'criar_conjunto_de_dados'     => 'create_dataset',
+  'apagar'                      => 'delete',
+  'apagar_conjunto_de_dados'    => 'delete_dataset',
+  'acessar/login'               => 'login',
+  'administração_da_base_de_dados_oracle' => 'oracle_database_administration',
+  'administração_da_base_de_dados_postgresql' => 'pg_database_administration',
+  'salvar'                      => 'save',
+  'atualizar_grupo_de_dados'    => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/br/all b/sql-ledger/locale/br/all
new file mode 100644 (file)
index 0000000..b656204
--- /dev/null
@@ -0,0 +1,487 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Contas a Pagar',
+  'AP Aging'                    => 'Contas a Pagar Vencidas',
+  'AP Transaction'              => 'Transação - Contas a Pagar',
+  'AP Transactions'             => 'Transações - Contas a Pagar',
+  'AR'                          => 'Contas a Receber',
+  'AR Aging'                    => 'Contas a Receber Vencidas',
+  'AR Transaction'              => 'Transação - Contas a Receber',
+  'AR Transactions'             => 'Transações - Contas a Receber',
+  'About'                       => 'Sobre',
+  'Access Control'              => 'Controle de Acesso',
+  'Account'                     => 'Conta',
+  'Account Number'              => 'Número da Conta',
+  'Account Number missing!'     => 'Número da Conta não encontrado!',
+  'Account Type'                => 'Tipo de Conta',
+  'Account Type missing!'       => 'Tipo de Conta não encontrado!',
+  'Account deleted!'            => 'Conta apagada!',
+  'Account saved!'              => 'Conta salva!',
+  'Accounting'                  => 'Contabilidade',
+  'Accounting Menu'             => 'Menu de Contabilidade',
+  'Accounts'                    => 'Contas',
+  'Active'                      => 'Ativa',
+  'Add'                         => 'Adicionar',
+  'Add Account'                 => 'Adicionar Conta',
+  'Add Accounts Payables Transaction' => 'Adicionar Transação de contas pagáveis',
+  'Add Accounts Receivables Transaction' => 'Adicionar Transação de contas recebíveis',
+  'Add Assembly'                => 'Adicionar Conjunto',
+  'Add Customer'                => 'Adicionar Cliente',
+  'Add GIFI'                    => 'Adicionar CFOP',
+  'Add General Ledger Transaction' => 'Adicionar Transação Livro Razão',
+  'Add Part'                    => 'Adicionar Parte',
+  'Add Project'                 => 'Adicionar projeto',
+  'Add Purchase Invoice'        => 'Adicionar Fatura de Compra',
+  'Add Purchase Order'          => 'Adicionar Pedido de Compra',
+  'Add Sales Invoice'           => 'Adicionar Fatura de Venda',
+  'Add Sales Order'             => 'Adicionar Pedido de Venda',
+  'Add Service'                 => 'Adicionar Serviço',
+  'Add Transaction'             => 'Adicionar Transação',
+  'Add User'                    => 'Adicionar Usuário',
+  'Add Vendor'                  => 'Adicionar Distribuidor',
+  'Address'                     => 'Endereço',
+  'Administration'              => 'Administração',
+  'Administrator'               => 'Administrador',
+  'All'                         => 'Todas',
+  'All Datasets up to date!'    => 'Todos grupos de dados atualizados!',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Total Devido',
+  'Amount does not equal applied!' => 'Total não é igual ao aplicado!',
+  'Amount missing!'             => 'Total faltando!',
+  'Applied'                     => 'Aplicado',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => 'Tem certeza que quer APAGAR a Fatura Número',
+  'Are you sure you want to delete Order Number' => 'Tem certeza que quer APAGAR tal número de Pedido?',
+  'Are you sure you want to delete Transaction' => 'Tem certeza que quer APAGAR a Transação',
+  'Assemblies'                  => 'Conjuntos',
+  'Assemblies restocked!'       => 'Conjuntos re estocados',
+  'Assembly Number missing!'    => 'Número de conjunto faltando!',
+  'Asset'                       => 'Ativo',
+  'Attachment'                  => 'Anexo',
+  'Audit Control'               => 'Controle de Auditoria',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'BOM'                         => 'Lista de Material',
+  'Backup'                      => 'Cópia de reserva',
+  'Backup sent to'              => 'Cópia reserva enviada para',
+  'Balance'                     => 'Balanço',
+  'Balance Sheet'               => 'Folha de Balanço',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Caixa/bandeja',
+  'Books are open'              => 'Livros estão abertos',
+  'Bought'                      => 'Comprado',
+  'Business Number'             => 'Número de negócio',
+  'C'                           => 'F',
+  'COGS'                        => 'Custo de Vendas',
+  'Cannot delete account!'      => 'Não pode apagar conta!',
+  'Cannot delete customer!'     => 'Não pode apagar cliente!',
+  'Cannot delete default account!' => 'Não pode apagar conta padrão!',
+  'Cannot delete invoice!'      => 'Não pode apagar fatura!',
+  'Cannot delete item already invoiced!' => 'Não posso apagar item já faturado!',
+  'Cannot delete item on order!' => 'Não pode apagar item no pedido',
+  'Cannot delete item which is part of an assembly!' => 'Não posso apagar item que é parte de um conjunto',
+  'Cannot delete item!'         => 'Não pode apagar item!',
+  'Cannot delete order!'        => 'Não pode apagar pedido!',
+  'Cannot delete transaction!'  => 'Não pode apagar transação!',
+  'Cannot delete vendor!'       => 'Não pode apagar fornecedor!',
+  'Cannot have a value in both Debit and Credit!' => 'Não pode ter um valor em ambos Débito e Crédito!',
+  'Cannot post a transaction without a value!' => '',
+  'Cannot post invoice for a closed period!' => 'Não pode lançar fatura em período fechado!',
+  'Cannot post invoice!'        => 'Não pode lançar fatura!',
+  'Cannot post payment for a closed period!' => 'Não pode lançar pagamento em período fechado!',
+  'Cannot post payment!'        => 'Não pode lançar pagamento!',
+  'Cannot post transaction for a closed period!' => 'Não pode lançar transação para um período já encerrado!',
+  'Cannot post transaction!'    => 'Não pode lançar transação',
+  'Cannot process payment for a closed period!' => 'Não pode processar pagamento para um pedíodo já encerrado!',
+  'Cannot save account!'        => 'Não pode salvar conta!',
+  'Cannot save order!'          => 'Não pode salvar pedido!',
+  'Cannot save preferences!'    => 'Não pode salvar preferências!',
+  'Cannot stock assemblies!'    => 'Não pode estocar conjuntos!',
+  'Cash'                        => 'Caixa',
+  'Cash based'                  => 'Baseado no Caixa',
+  'Cc'                          => 'Cc',
+  'Change Admin Password'       => 'Trocar senha de administração',
+  'Change Password'             => 'Trocar senha',
+  'Character Set'               => 'Conjunto de caracteres',
+  'Chart of Accounts'           => 'Código de Contas',
+  'Check'                       => 'Cheque',
+  'Check printed!'              => 'Cheque impresso',
+  'Check printing failed!'      => 'Impressão de cheque falhou!',
+  'Cleared Balance'             => 'Balanço limpo',
+  'Click on login name to edit!' => 'Clique no nome de acesso  para editar',
+  'Close Books up to'           => 'Encerrar livros até',
+  'Closed'                      => 'Fechado',
+  'Company'                     => 'Companhia',
+  'Compare to'                  => 'Comparar a',
+  'Confirm!'                    => 'Confirmar!',
+  'Connect to'                  => 'Conectar a',
+  'Contact'                     => 'Contato',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Copy to COA'                 => 'Copiar para Plano de Contas',
+  'Create Chart of Accounts'    => 'Criar Carta de Contas',
+  'Create Dataset'              => 'Criar conjunto de dados',
+  'Credit'                      => 'Crédito',
+  'Credit Limit'                => 'Limite de Crédito',
+  'Curr'                        => 'Moeda',
+  'Currency'                    => 'Moeda',
+  'Current'                     => '',
+  'Customer'                    => 'Cliente',
+  'Customer deleted!'           => 'Cliente apagado!',
+  'Customer missing!'           => 'Cliente faltando!',
+  'Customer not on file!'       => 'Cliente não está no arquivo!',
+  'Customer saved!'             => 'Cliente salvo',
+  'Customers'                   => 'Clientes',
+  'DBI not installed!'          => 'Driver de Interface de Banco de dados NÃO INSTALADO!',
+  'Database'                    => 'Banco de Dados',
+  'Database Administration'     => 'Administração da Base de Dados',
+  'Database Driver not checked!' => 'Driver do banco de dados não selecionado!',
+  'Database Host'               => 'Servidor de Base de Dados',
+  'Database User missing!'      => 'Usuário da base de dados faltando!',
+  'Dataset'                     => 'Conjunto de dados',
+  'Dataset missing!'            => 'Conjunto de dados faltando!',
+  'Dataset updated!'            => 'Conjunto de dados atualizado',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Data de Vencimento',
+  'Date Format'                 => 'Formato de Data',
+  'Date Paid'                   => 'Data de pagamento',
+  'Date missing!'               => 'Data faltando!',
+  'Debit'                       => 'Débito',
+  'Debit and credit out of balance!' => 'Débito e crédito fora de balanço!',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Decimalplaces'               => 'Casas decimais',
+  'Delete'                      => 'Apagar',
+  'Delete Account'              => 'Apagar Conta',
+  'Delete Dataset'              => 'Apagar conjunto de dados',
+  'Delivery Date'               => 'Data de entrega',
+  'Deposit'                     => 'Depósito',
+  'Description'                 => 'Descrição',
+  'Difference'                  => 'Diferença',
+  'Directory'                   => 'Diretório',
+  'Discount'                    => 'Desconto',
+  'Done'                        => 'Feito',
+  'Drawing'                     => 'Desenho',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Limite de dropdown',
+  'Due'                         => 'Saldo',
+  'Due Date'                    => 'Data de Vencimento',
+  'Due Date missing!'           => 'Data de Vencimento faltando!',
+  'E-mail'                      => 'E-Mail',
+  'E-mail Statement to'         => 'Declaração enviada por email para',
+  'E-mail address missing!'     => 'Endereço de E-mail faltando!',
+  'Edit'                        => 'Editar',
+  'Edit Account'                => 'Editar Conta',
+  'Edit Accounts Payables Transaction' => 'Editar Transação - Contas a Pagar',
+  'Edit Accounts Receivables Transaction' => 'Editar Transação - Contas a Receber',
+  'Edit Assembly'               => 'Editar Conjunto',
+  'Edit GIFI'                   => 'Editar CFOP',
+  'Edit General Ledger Transaction' => 'Editar Transação Livro Razão',
+  'Edit Part'                   => 'Editar Parte',
+  'Edit Preferences for'        => 'Editar Preferências para',
+  'Edit Project'                => 'Editar Projeto',
+  'Edit Purchase Invoice'       => 'Editar Fatura de Compra',
+  'Edit Purchase Order'         => 'Editar Pedido de Compra',
+  'Edit Sales Invoice'          => 'Editar Fatura de Venda',
+  'Edit Sales Order'            => 'Editar Pedido de Venda',
+  'Edit Service'                => 'Editar Serviço',
+  'Edit Template'               => 'Editar Modelo',
+  'Edit User'                   => 'Editar Usuário',
+  'Employee'                    => 'Empregado',
+  'Enforce transaction reversal for all dates' => 'Forçar execução de reversão de transação para todas as datas',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Entre com até 3 letras separadas por dois pontos (i.e CAD:USD:EUR) para sua moeda local e estrangeira',
+  'Equity'                      => 'Capital',
+  'Exch'                        => 'Câmbio',
+  'Exchangerate'                => 'Taxa de câmbio',
+  'Exchangerate Difference'     => 'Diferença da Taxa de Câmbio',
+  'Exchangerate for payment missing!' => 'Falta a taxa de câmbio para o pagamento!',
+  'Exchangerate missing!'       => 'Falta a taxa de câmbio!',
+  'Existing Datasets'           => 'Conjunto de dados existentes',
+  'Expense'                     => 'Despesa',
+  'Expense Account'             => 'Conta de Despesas',
+  'Expense/Asset'               => 'Despesa/Ativo',
+  'Extended'                    => 'Extendida',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'Foreign Exchange Gain'       => 'Ganho com câmbio estrangeiro',
+  'Foreign Exchange Loss'       => 'Perda com câmbio estrangeiro',
+  'From'                        => 'De',
+  'GIFI'                        => 'CFOP - Código Fiscal da Operação',
+  'GIFI deleted!'               => 'CFOP apagado!',
+  'GIFI missing!'               => 'CFOP faltando!',
+  'GIFI saved!'                 => 'CFOP salvo!',
+  'GL Transaction'              => 'Transação do Livro Razão',
+  'General Ledger'              => 'Livro Razão',
+  'Goods & Services'            => 'Produtos e Serviços',
+  'HTML Templates'              => 'Modelos HTML',
+  'Heading'                     => 'Cabeçalho',
+  'Host'                        => 'Servidor',
+  'Hostname missing!'           => 'Nome do servidor faltando!',
+  'ID'                          => 'ID',
+  'Image'                       => 'Imagem',
+  'In-line'                     => 'em linha',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Include in drop-down menus'  => 'Incluir nos menus drop-down (tipo cortina)',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Incluir esta conta nos formulários de cliente/fornecedor para marcar cliente/fornecedor como sujeito a impostos.',
+  'Income'                      => 'Receita',
+  'Income Account'              => 'Conta de Receitas',
+  'Income Statement'            => 'Estado de Receitas',
+  'Incorrect Dataset version!'  => 'Versão incorreta de grupos de dados!',
+  'Incorrect Password!'         => 'Senha incorreta!',
+  'Individual Items'            => 'Ítens individuais',
+  'Inventory'                   => 'Estoque',
+  'Inventory Account'           => 'Conta de Estoque',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Quantidade em estoque TEM de ser zero ANTES que você possa tornar este conjunto obsoleto!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Quantidade em estoque TEM de ser zero ANTES que você possa tornar esta parte/peça  obsoleta!',
+  'Inventory quantity must be zero!' => 'Quantidade em estoque TEM de ser zero!',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date'                => 'Data de Fatura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number'              => 'Número de Fatura',
+  'Invoice Number missing!'     => 'Número de Fatura não encontrado!',
+  'Invoice deleted!'            => 'Fatura apagada!',
+  'Invoice posted!'             => 'Fatura lançada!',
+  'Invoices'                    => 'Faturas',
+  'Is this a summary account to record' => 'Esta é uma conta sumária a registrar?',
+  'Item deleted!'               => 'Item apagado!',
+  'Item not on file!'           => 'Item não está no arquivo!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'LaTeX Templates'             => 'Modelos LaTeX',
+  'Language'                    => 'Idioma',
+  'Last Cost'                   => 'Último Custo',
+  'Last Invoice Number'         => 'Último Número de Fatura',
+  'Last Numbers & Default Accounts' => 'Últimos números e Contas Padrão',
+  'Last Purchase Order Number'  => 'Último Número de Pedido de Compra',
+  'Last Sales Order Number'     => 'Último número de pedido de vendas',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Deixe os campos de  servidor e porta vazios a menos que você queira fazer uma conexão remota',
+  'Liability'                   => 'Passivo',
+  'Licensed to'                 => 'Licenciado a',
+  'Line Total'                  => 'Total da linha',
+  'Link'                        => 'Ligar',
+  'Link Accounts'               => 'Ligar Contas',
+  'List Accounts'               => 'Listar Contas',
+  'List GIFI'                   => 'Listar CFOP',
+  'List Price'                  => 'Preço de lista',
+  'List Transactions'           => 'Listar Transações',
+  'Login'                       => 'Acessar/login',
+  'Logout'                      => 'Logout (sair)',
+  'Make'                        => 'Marca',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'Microfiche'                  => 'Microficha',
+  'Model'                       => 'Modelo',
+  'N/A'                         => 'N/D',
+  'Name'                        => 'Nome',
+  'Name missing!'               => 'Nome faltando!',
+  'New Templates'               => 'Novos Modelos',
+  'No'                          => 'Não',
+  'No Database Drivers available!' => 'Nenhum driver de banco de dados disponível!',
+  'No Dataset selected!'        => 'Nenhum conjunto de dados selecionado!',
+  'No email address for'        => 'Sem endereço de email para',
+  'No.'                         => '',
+  'Notes'                       => 'Notas',
+  'Nothing applied!'            => 'Nada foi aplicado!',
+  'Nothing selected!'           => 'Nada foi selecionado!',
+  'Nothing to delete!'          => 'Nada para apagar!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Formato de números',
+  'Number missing in Row'       => 'Número faltando na linha',
+  'O'                           => 'A',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'On Hand'                     => 'Em Mãos',
+  'On Order'                    => 'Em pedido',
+  'Open'                        => 'Abrir',
+  'Oracle Database Administration' => 'Administração da Base de Dados Oracle',
+  'Order'                       => 'Pedido',
+  'Order Date'                  => 'Data de Pedido',
+  'Order Date missing!'         => 'Data de Pedido Faltando',
+  'Order Entry'                 => 'Entrada de Pedido',
+  'Order Number'                => 'Pedido Número',
+  'Order Number missing!'       => 'Número de pedido faltando!',
+  'Order deleted!'              => 'Pedido apagado!',
+  'Order saved!'                => 'Pedido salvo!',
+  'Ordered'                     => 'Pedido feito',
+  'Orphaned'                    => 'Ficaram órfãs',
+  'Out of balance!'             => 'Fora de balanço!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empacotamento',
+  'Packing List Date missing!'  => 'Data da lista de empacotamento faltando!',
+  'Packing List Number missing!' => 'Número da lista de empacotamento faltando!',
+  'Paid'                        => 'Total Efetuado',
+  'Paid in full'                => '',
+  'Part'                        => 'Parte',
+  'Part Number missing!'        => 'Número da parte não encontrado!',
+  'Parts'                       => 'Partes',
+  'Parts Inventory'             => 'Estoque de Partes',
+  'Password'                    => 'Senha',
+  'Password changed!'           => 'Senha trocada!',
+  'Payables'                    => 'A Pagar',
+  'Payment'                     => 'Pagamento',
+  'Payment date missing!'       => 'Data de pagamento faltando!',
+  'Payment posted!'             => 'Pagamento Lançado',
+  'Payments'                    => 'Pagamentos',
+  'Pg Database Administration'  => 'Administração da Base de Dados PostgreSQL',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Porta',
+  'Port missing!'               => 'Porta faltando!',
+  'Post'                        => 'Lançar',
+  'Post as new'                 => 'Lançar como novo',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Preferências',
+  'Preferences saved!'          => 'Preferências Salvas!',
+  'Price'                       => 'Preço',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Projeto',
+  'Project Number missing!'     => 'Número do Projeto faltando!',
+  'Project deleted!'            => 'Projeto apagado!',
+  'Project not on file!'        => 'Projeto não está no arquivo!',
+  'Project saved!'              => 'Projeto salvo!',
+  'Projects'                    => 'Projetos',
+  'Purchase Invoice'            => 'Fatura de compra',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Purchase Orders'             => 'Ordens de Compra',
+  'Qty'                         => 'Qtde',
+  'ROP'                         => 'Nível mínimo de estoque',
+  'Rate'                        => 'Taxa',
+  'Recd'                        => 'Recebidos',
+  'Receipt'                     => 'Recibo',
+  'Receipts'                    => 'Recibos',
+  'Receivables'                 => 'A Receber',
+  'Reconciliation'              => 'Reconciliação',
+  'Record in'                   => 'Registrar em',
+  'Reference'                   => 'Referência',
+  'Reference missing!'          => 'Referência faltando!',
+  'Remaining'                   => 'Restante',
+  'Report for'                  => 'Relatório para',
+  'Reports'                     => 'Relatórios',
+  'Required by'                 => 'Requerido por',
+  'Retained Earnings'           => 'Lucros Retidos',
+  'Sales'                       => 'Vendas',
+  'Sales Invoice'               => 'Fatura de Venda',
+  'Sales Order'                 => 'Pedido de Venda',
+  'Sales Orders'                => 'Pedidos de Venda',
+  'Save'                        => 'Salvar',
+  'Save as new'                 => 'Salvar como novo',
+  'Save to File'                => 'Salvar para Arquivo',
+  'Screen'                      => 'Tela',
+  'Select a Dataset to delete and press "Continue"' => 'Selecione um conjunto de dados para APAGAR e pressione Continue',
+  'Select all'                  => 'Selecionar todos',
+  'Select from one of the items below' => 'Selecione um dos ítens abaixo',
+  'Select from one of the names below' => 'Selecione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Selecione um dos projetos abaixo',
+  'Select postscript or PDF!'   => 'Selecionar Postscript ou PDF',
+  'Sell Price'                  => 'Preço de Venda',
+  'Send by E-Mail'              => 'Enviar por E-mail',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Service'                     => 'Serviço',
+  'Service Items'               => 'Ítens de Serviço',
+  'Service Number missing!'     => 'Número do serviço não encontrado!',
+  'Services'                    => 'Serviços',
+  'Setup Templates'             => 'Modelos de Configuração',
+  'Ship'                        => 'Transportar',
+  'Ship to'                     => 'Transportar para',
+  'Ship via'                    => 'Transportar via',
+  'Short'                       => 'Curto',
+  'Signature'                   => 'Assinatura',
+  'Sold'                        => 'Vendido',
+  'Source'                      => 'Fonte',
+  'Standard'                    => 'Padrão',
+  'Statement'                   => 'Declaração',
+  'Statement Balance'           => 'Declaração de Balanço',
+  'Statement sent to'           => 'Declaração enviada para',
+  'Statements sent to printer!' => 'Declaração enviada para impressora!',
+  'Stock Assembly'              => 'Conjunto normal de estoque',
+  'Stylesheet'                  => 'Folha de estilos',
+  'Subject'                     => 'Assunto',
+  'Subtotal'                    => 'Sub-total',
+  'System'                      => 'Sistema',
+  'Tax'                         => 'Imposto',
+  'Tax Accounts'                => 'Contas de Impostos',
+  'Tax Included'                => 'Impostos incluídos',
+  'Tax collected'               => 'Imposto recolhido',
+  'Tax paid'                    => 'Imposto pago',
+  'Taxable'                     => 'Sujeito a impostos',
+  'Template saved!'             => 'Modelo salvo!',
+  'Templates'                   => 'Modelos',
+  'Terms: Net'                  => 'Crédito Líquido',
+  'The following Datasets are not in use and can be deleted' => 'Os seguintes conjuntos de dados NÃO estão em uso e PODEM ser apagados',
+  'The following Datasets need to be updated' => 'Os seguintes grupos de dados precisam ser atualizados',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Esta é uma verificação preliminar por fontes existentes. Nada será criado ou apagado neste estágio!',
+  'To'                          => 'Até',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Para adicionar um usuário a um grupo edite um nome, troque o nome de acesso/login e  salve. Um novo usuário com as mesmas variáveis será então salvo sob o novo nome de acesso/login.',
+  'Top Level'                   => 'Nível superior',
+  'Total'                       => 'Total',
+  'Transaction Date missing!'   => 'Data de transação faltando!',
+  'Transaction deleted!'        => 'Transação apagada!',
+  'Transaction posted!'         => 'Transação lançada',
+  'Transaction reversal enforced for all dates' => 'Reversão de transação forçada para todas as datas.',
+  'Transaction reversal enforced up to' => 'Reversão de transação forçada até ',
+  'Transactions'                => 'Tansações',
+  'Transactions exist, cannot delete customer!' => 'Existem transações, não pode apagar o cliente!',
+  'Transactions exist, cannot delete vendor!' => 'Existem transações, não pode apagar fornecedor!',
+  'Transactions exist; cannot delete account!' => 'Existem transações, não pode apagar conta!',
+  'Trial Balance'               => 'Balanço Preliminar',
+  'Unit'                        => 'Unidade',
+  'Unit of measure'             => 'Unidade de medida',
+  'Update'                      => 'Atualizar',
+  'Update Dataset'              => 'Atualizar grupo de dados',
+  'Updated'                     => 'Atualizado',
+  'Use Templates'               => 'Use Modelos',
+  'User'                        => 'Usuário',
+  'User deleted!'               => 'Usuário apagado!',
+  'User saved!'                 => 'Usuário salvo',
+  'Vendor'                      => 'Distribuidor',
+  'Vendor deleted!'             => 'Distribuidor apagado!',
+  'Vendor missing!'             => 'Distribuidor faltando!',
+  'Vendor not on file!'         => 'Distribuidor não está no arquivo!',
+  'Vendor saved!'               => 'Distribuidor salvo!',
+  'Vendors'                     => 'Distribuidores',
+  'Version'                     => 'Versão',
+  'Weight'                      => 'Peso',
+  'Weight Unit'                 => 'Unidade de Peso',
+  'What type of item is this?'  => 'Que tipo de Item é este?',
+  'Year End'                    => 'Fim de ano',
+  'Yes'                         => 'Sim',
+  'You are logged out!'         => 'Você saiu do sistema!',
+  'You did not enter a name!'   => 'Você não entrou com um nome',
+  'You must enter a host and port for local and remote connections!' => 'Você precisa entrar um servidor e uma porta para conexões locais e remotas!',
+  'as at'                       => 'como em',
+  'collected on sales'          => 'recolhido sobre vendas',
+  'days'                        => 'Dias',
+  'does not exist'              => 'Não existe',
+  'ea'                          => 'cada',
+  'emailed to'                  => 'enviado por email para',
+  'for Period'                  => 'pelo período',
+  'hr'                          => 'h',
+  'is already a member!'        => 'já é um membro!',
+  'is not a member!'            => 'não é um membro!',
+  'localhost'                   => 'localhost /servidor local',
+  'paid on purchases'           => 'pago em aquisições',
+  'sent to printer'             => 'enviado para impressora',
+  'successfully created!'       => 'Criado com sucesso!',
+  'successfully deleted!'       => 'Apagado com sucesso!',
+  'to'                          => 'para',
+  'website'                     => 'website',
+};
+
+1;
diff --git a/sql-ledger/locale/br/am b/sql-ledger/locale/br/am
new file mode 100644 (file)
index 0000000..eafe19d
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Contas a Pagar',
+  'AR'                          => 'Contas a Receber',
+  'Account'                     => 'Conta',
+  'Account Number'              => 'Número da Conta',
+  'Account Number missing!'     => 'Número da Conta não encontrado!',
+  'Account Type'                => 'Tipo de Conta',
+  'Account Type missing!'       => 'Tipo de Conta não encontrado!',
+  'Account deleted!'            => 'Conta apagada!',
+  'Account saved!'              => 'Conta salva!',
+  'Add Account'                 => 'Adicionar Conta',
+  'Add GIFI'                    => 'Adicionar CFOP',
+  'Address'                     => 'Endereço',
+  'Asset'                       => 'Ativo',
+  'Audit Control'               => 'Controle de Auditoria',
+  'Backup sent to'              => 'Cópia reserva enviada para',
+  'Books are open'              => 'Livros estão abertos',
+  'Business Number'             => 'Número de negócio',
+  'COGS'                        => 'Custo de Vendas',
+  'Cannot delete account!'      => 'Não pode apagar conta!',
+  'Cannot delete default account!' => 'Não pode apagar conta padrão!',
+  'Cannot save account!'        => 'Não pode salvar conta!',
+  'Cannot save preferences!'    => 'Não pode salvar preferências!',
+  'Character Set'               => 'Conjunto de caracteres',
+  'Chart of Accounts'           => 'Código de Contas',
+  'Close Books up to'           => 'Encerrar livros até',
+  'Company'                     => 'Companhia',
+  'Continue'                    => 'Continuar',
+  'Copy to COA'                 => 'Copiar para Plano de Contas',
+  'Credit'                      => 'Crédito',
+  'Date Format'                 => 'Formato de Data',
+  'Debit'                       => 'Débito',
+  'Delete'                      => 'Apagar',
+  'Delete Account'              => 'Apagar Conta',
+  'Description'                 => 'Descrição',
+  'Dropdown Limit'              => 'Limite de dropdown',
+  'E-mail'                      => 'E-Mail',
+  'Edit'                        => 'Editar',
+  'Edit Account'                => 'Editar Conta',
+  'Edit GIFI'                   => 'Editar CFOP',
+  'Edit Preferences for'        => 'Editar Preferências para',
+  'Edit Template'               => 'Editar Modelo',
+  'Enforce transaction reversal for all dates' => 'Forçar execução de reversão de transação para todas as datas',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Entre com até 3 letras separadas por dois pontos (i.e CAD:USD:EUR) para sua moeda local e estrangeira',
+  'Equity'                      => 'Capital',
+  'Expense'                     => 'Despesa',
+  'Expense Account'             => 'Conta de Despesas',
+  'Expense/Asset'               => 'Despesa/Ativo',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Ganho com câmbio estrangeiro',
+  'Foreign Exchange Loss'       => 'Perda com câmbio estrangeiro',
+  'GIFI'                        => 'CFOP - Código Fiscal da Operação',
+  'GIFI deleted!'               => 'CFOP apagado!',
+  'GIFI missing!'               => 'CFOP faltando!',
+  'GIFI saved!'                 => 'CFOP salvo!',
+  'Heading'                     => 'Cabeçalho',
+  'Include in drop-down menus'  => 'Incluir nos menus drop-down (tipo cortina)',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Incluir esta conta nos formulários de cliente/fornecedor para marcar cliente/fornecedor como sujeito a impostos.',
+  'Income'                      => 'Receita',
+  'Income Account'              => 'Conta de Receitas',
+  'Inventory'                   => 'Estoque',
+  'Inventory Account'           => 'Conta de Estoque',
+  'Is this a summary account to record' => 'Esta é uma conta sumária a registrar?',
+  'Language'                    => 'Idioma',
+  'Last Invoice Number'         => 'Último Número de Fatura',
+  'Last Numbers & Default Accounts' => 'Últimos números e Contas Padrão',
+  'Last Purchase Order Number'  => 'Último Número de Pedido de Compra',
+  'Last Sales Order Number'     => 'Último número de pedido de vendas',
+  'Liability'                   => 'Passivo',
+  'Link'                        => 'Ligar',
+  'Name'                        => 'Nome',
+  'No'                          => 'Não',
+  'No email address for'        => 'Sem endereço de email para',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Formato de números',
+  'Parts Inventory'             => 'Estoque de Partes',
+  'Password'                    => 'Senha',
+  'Payables'                    => 'A Pagar',
+  'Payment'                     => 'Pagamento',
+  'Phone'                       => 'Tel.',
+  'Preferences saved!'          => 'Preferências Salvas!',
+  'Rate'                        => 'Taxa',
+  'Receivables'                 => 'A Receber',
+  'Sales'                       => 'Vendas',
+  'Save'                        => 'Salvar',
+  'Service Items'               => 'Ítens de Serviço',
+  'Ship via'                    => 'Transportar via',
+  'Signature'                   => 'Assinatura',
+  'Stylesheet'                  => 'Folha de estilos',
+  'Tax'                         => 'Imposto',
+  'Tax Accounts'                => 'Contas de Impostos',
+  'Template saved!'             => 'Modelo salvo!',
+  'Transaction reversal enforced for all dates' => 'Reversão de transação forçada para todas as datas.',
+  'Transaction reversal enforced up to' => 'Reversão de transação forçada até ',
+  'Transactions exist; cannot delete account!' => 'Existem transações, não pode apagar conta!',
+  'Weight Unit'                 => 'Unidade de Peso',
+  'Year End'                    => 'Fim de ano',
+  'Yes'                         => 'Sim',
+  'does not exist'              => 'Não existe',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'adicionar_conta'             => 'add_account',
+  'continuar'                   => 'continue',
+  'copiar_para_plano_de_contas' => 'copy_to_coa',
+  'apagar'                      => 'delete',
+  'editar'                      => 'edit',
+  'editar_conta'                => 'edit_account',
+  'salvar'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/br/ap b/sql-ledger/locale/br/ap
new file mode 100644 (file)
index 0000000..dce6c51
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Transação - Contas a Pagar',
+  'AP Transactions'             => 'Transações - Contas a Pagar',
+  'Account'                     => 'Conta',
+  'Add Accounts Payables Transaction' => 'Adicionar Transação de contas pagáveis',
+  'Address'                     => 'Endereço',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Total Devido',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => 'Tem certeza que quer APAGAR a Transação',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Cannot delete transaction!'  => 'Não pode apagar transação!',
+  'Cannot post payment for a closed period!' => 'Não pode lançar pagamento em período fechado!',
+  'Cannot post transaction for a closed period!' => 'Não pode lançar transação para um período já encerrado!',
+  'Cannot post transaction!'    => 'Não pode lançar transação',
+  'Closed'                      => 'Fechado',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Moeda',
+  'Customer not on file!'       => 'Cliente não está no arquivo!',
+  'Date'                        => 'Data',
+  'Date Paid'                   => 'Data de pagamento',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Apagar',
+  'Description'                 => 'Descrição',
+  'Due Date'                    => 'Data de Vencimento',
+  'Due Date missing!'           => 'Data de Vencimento faltando!',
+  'Edit Accounts Payables Transaction' => 'Editar Transação - Contas a Pagar',
+  'Employee'                    => 'Empregado',
+  'Exch'                        => 'Câmbio',
+  'Exchangerate'                => 'Taxa de câmbio',
+  'Exchangerate for payment missing!' => 'Falta a taxa de câmbio para o pagamento!',
+  'Exchangerate missing!'       => 'Falta a taxa de câmbio!',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date'                => 'Data de Fatura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number'              => 'Número de Fatura',
+  'Invoice Number missing!'     => 'Número de Fatura não encontrado!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Open'                        => 'Abrir',
+  'Order'                       => 'Pedido',
+  'Order Number'                => 'Pedido Número',
+  'Paid'                        => 'Total Efetuado',
+  'Payment date missing!'       => 'Data de pagamento faltando!',
+  'Payments'                    => 'Pagamentos',
+  'Post'                        => 'Lançar',
+  'Post as new'                 => 'Lançar como novo',
+  'Project'                     => 'Projeto',
+  'Project not on file!'        => 'Projeto não está no arquivo!',
+  'Purchase Invoice'            => 'Fatura de compra',
+  'Select from one of the names below' => 'Selecione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Selecione um dos projetos abaixo',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Source'                      => 'Fonte',
+  'Subtotal'                    => 'Sub-total',
+  'Tax'                         => 'Imposto',
+  'Tax Included'                => 'Impostos incluídos',
+  'To'                          => 'Até',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transação apagada!',
+  'Transaction posted!'         => 'Transação lançada',
+  'Update'                      => 'Atualizar',
+  'Vendor'                      => 'Distribuidor',
+  'Vendor missing!'             => 'Distribuidor faltando!',
+  'Vendor not on file!'         => 'Distribuidor não está no arquivo!',
+  'Yes'                         => 'Sim',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'transação___contas_a_pagar'  => 'ap_transaction',
+  'adicionar_transação_de_contas_pagáveis' => 'add_accounts_payables_transaction',
+  'continuar'                   => 'continue',
+  'apagar'                      => 'delete',
+  'editar_transação___contas_a_pagar' => 'edit_accounts_payables_transaction',
+  'lançar'                      => 'post',
+  'lançar_como_novo'            => 'post_as_new',
+  'fatura_de_compra'            => 'purchase_invoice',
+  'atualizar'                   => 'update',
+  'sim'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/br/ar b/sql-ledger/locale/br/ar
new file mode 100644 (file)
index 0000000..95efd92
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'Transação - Contas a Receber',
+  'AR Transactions'             => 'Transações - Contas a Receber',
+  'Account'                     => 'Conta',
+  'Add Accounts Receivables Transaction' => 'Adicionar Transação de contas recebíveis',
+  'Address'                     => 'Endereço',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Total Devido',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => 'Tem certeza que quer APAGAR a Transação',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Cannot delete transaction!'  => 'Não pode apagar transação!',
+  'Cannot post payment for a closed period!' => 'Não pode lançar pagamento em período fechado!',
+  'Cannot post transaction for a closed period!' => 'Não pode lançar transação para um período já encerrado!',
+  'Cannot post transaction!'    => 'Não pode lançar transação',
+  'Closed'                      => 'Fechado',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Limite de Crédito',
+  'Currency'                    => 'Moeda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Cliente faltando!',
+  'Customer not on file!'       => 'Cliente não está no arquivo!',
+  'Date'                        => 'Data',
+  'Date Paid'                   => 'Data de pagamento',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Apagar',
+  'Description'                 => 'Descrição',
+  'Due Date'                    => 'Data de Vencimento',
+  'Due Date missing!'           => 'Data de Vencimento faltando!',
+  'Edit Accounts Receivables Transaction' => 'Editar Transação - Contas a Receber',
+  'Employee'                    => 'Empregado',
+  'Exch'                        => 'Câmbio',
+  'Exchangerate'                => 'Taxa de câmbio',
+  'Exchangerate for payment missing!' => 'Falta a taxa de câmbio para o pagamento!',
+  'Exchangerate missing!'       => 'Falta a taxa de câmbio!',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date'                => 'Data de Fatura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number'              => 'Número de Fatura',
+  'Invoice Number missing!'     => 'Número de Fatura não encontrado!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Open'                        => 'Abrir',
+  'Order'                       => 'Pedido',
+  'Order Number'                => 'Pedido Número',
+  'Paid'                        => 'Total Efetuado',
+  'Payment date missing!'       => 'Data de pagamento faltando!',
+  'Payments'                    => 'Pagamentos',
+  'Post'                        => 'Lançar',
+  'Post as new'                 => 'Lançar como novo',
+  'Project'                     => 'Projeto',
+  'Project not on file!'        => 'Projeto não está no arquivo!',
+  'Remaining'                   => 'Restante',
+  'Sales Invoice'               => 'Fatura de Venda',
+  'Select from one of the names below' => 'Selecione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Selecione um dos projetos abaixo',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Source'                      => 'Fonte',
+  'Subtotal'                    => 'Sub-total',
+  'Tax'                         => 'Imposto',
+  'Tax Included'                => 'Impostos incluídos',
+  'To'                          => 'Até',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transação apagada!',
+  'Transaction posted!'         => 'Transação lançada',
+  'Update'                      => 'Atualizar',
+  'Vendor not on file!'         => 'Distribuidor não está no arquivo!',
+  'Yes'                         => 'Sim',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'transação___contas_a_receber' => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'apagar'                      => 'delete',
+  'lançar'                      => 'post',
+  'lançar_como_novo'            => 'post_as_new',
+  'fatura_de_venda'             => 'sales_invoice',
+  'atualizar'                   => 'update',
+  'sim'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/br/arap b/sql-ledger/locale/br/arap
new file mode 100644 (file)
index 0000000..4565db6
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Endereço',
+  'Continue'                    => 'Continuar',
+  'Customer not on file!'       => 'Cliente não está no arquivo!',
+  'Description'                 => 'Descrição',
+  'Number'                      => 'Número',
+  'Project not on file!'        => 'Projeto não está no arquivo!',
+  'Select from one of the names below' => 'Selecione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Selecione um dos projetos abaixo',
+  'Vendor not on file!'         => 'Distribuidor não está no arquivo!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/br/ca b/sql-ledger/locale/br/ca
new file mode 100644 (file)
index 0000000..1f7cbc4
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Conta',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Balanço',
+  'Chart of Accounts'           => 'Código de Contas',
+  'Credit'                      => 'Crédito',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Débito',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Description'                 => 'Descrição',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'GIFI'                        => 'CFOP - Código Fiscal da Operação',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'List Transactions'           => 'Listar Transações',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Reference'                   => 'Referência',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Subtotal'                    => 'Sub-total',
+  'To'                          => 'Até',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'listar_transações'           => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/br/cp b/sql-ledger/locale/br/cp
new file mode 100644 (file)
index 0000000..471654b
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Conta',
+  'Address'                     => 'Endereço',
+  'Amount'                      => 'Total',
+  'Amount does not equal applied!' => 'Total não é igual ao aplicado!',
+  'Amount missing!'             => 'Total faltando!',
+  'Applied'                     => 'Aplicado',
+  'Cannot post payment!'        => 'Não pode lançar pagamento!',
+  'Cannot process payment for a closed period!' => 'Não pode processar pagamento para um pedíodo já encerrado!',
+  'Check'                       => 'Cheque',
+  'Check printed!'              => 'Cheque impresso',
+  'Check printing failed!'      => 'Impressão de cheque falhou!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Moeda',
+  'Customer'                    => 'Cliente',
+  'Customer not on file!'       => 'Cliente não está no arquivo!',
+  'Date'                        => 'Data',
+  'Date missing!'               => 'Data faltando!',
+  'Description'                 => 'Descrição',
+  'Due'                         => 'Saldo',
+  'Exchangerate'                => 'Taxa de câmbio',
+  'From'                        => 'De',
+  'Invoice'                     => 'Fatura',
+  'Invoices'                    => 'Faturas',
+  'Nothing applied!'            => 'Nada foi aplicado!',
+  'Number'                      => 'Número',
+  'Paid in full'                => 'Paid in full',
+  'Payment'                     => 'Pagamento',
+  'Payment posted!'             => 'Pagamento Lançado',
+  'Post'                        => 'Lançar',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impressora',
+  'Project not on file!'        => 'Projeto não está no arquivo!',
+  'Receipt'                     => 'Recibo',
+  'Reference'                   => 'Referência',
+  'Screen'                      => 'Tela',
+  'Select from one of the names below' => 'Selecione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Selecione um dos projetos abaixo',
+  'To'                          => 'Até',
+  'Update'                      => 'Atualizar',
+  'Vendor'                      => 'Distribuidor',
+  'Vendor not on file!'         => 'Distribuidor não está no arquivo!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+  'lançar'                      => 'post',
+  'imprimir'                    => 'print',
+  'atualizar'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/br/ct b/sql-ledger/locale/br/ct
new file mode 100644 (file)
index 0000000..bfc96e5
--- /dev/null
@@ -0,0 +1,69 @@
+$self{texts} = {
+  'Add'                         => 'Adicionar',
+  'Address'                     => 'Endereço',
+  'All'                         => 'Todas',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Não pode apagar cliente!',
+  'Cannot delete vendor!'       => 'Não pode apagar fornecedor!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contato',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Limite de Crédito',
+  'Customer deleted!'           => 'Cliente apagado!',
+  'Customer saved!'             => 'Cliente salvo',
+  'Customers'                   => 'Clientes',
+  'Delete'                      => 'Apagar',
+  'Discount'                    => 'Desconto',
+  'E-mail'                      => 'E-Mail',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Invoice'                     => 'Fatura',
+  'Name'                        => 'Nome',
+  'Name missing!'               => 'Nome faltando!',
+  'Notes'                       => 'Notas',
+  'Number'                      => 'Número',
+  'Order'                       => 'Pedido',
+  'Orphaned'                    => 'Ficaram órfãs',
+  'Phone'                       => 'Tel.',
+  'Save'                        => 'Salvar',
+  'Ship to'                     => 'Transportar para',
+  'Tax Included'                => 'Impostos incluídos',
+  'Taxable'                     => 'Sujeito a impostos',
+  'Terms: Net'                  => 'Crédito Líquido',
+  'Transactions exist, cannot delete customer!' => 'Existem transações, não pode apagar o cliente!',
+  'Transactions exist, cannot delete vendor!' => 'Existem transações, não pode apagar fornecedor!',
+  'Vendor deleted!'             => 'Distribuidor apagado!',
+  'Vendor saved!'               => 'Distribuidor salvo!',
+  'Vendors'                     => 'Distribuidores',
+  'days'                        => 'Dias',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'adicionar'                   => 'add',
+  'continuar'                   => 'continue',
+  'apagar'                      => 'delete',
+  'fatura'                      => 'invoice',
+  'pedido'                      => 'order',
+  'salvar'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/br/gl b/sql-ledger/locale/br/gl
new file mode 100644 (file)
index 0000000..928761c
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Transação - Contas a Pagar',
+  'AR Transaction'              => 'Transação - Contas a Receber',
+  'Account'                     => 'Conta',
+  'Add General Ledger Transaction' => 'Adicionar Transação Livro Razão',
+  'Address'                     => 'Endereço',
+  'All'                         => 'Todas',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => 'Tem certeza que quer APAGAR a Transação',
+  'Asset'                       => 'Ativo',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Balanço',
+  'Cannot delete transaction!'  => 'Não pode apagar transação!',
+  'Cannot have a value in both Debit and Credit!' => 'Não pode ter um valor em ambos Débito e Crédito!',
+  'Cannot post a transaction without a value!' => 'Cannot post a transaction without a value!',
+  'Cannot post transaction for a closed period!' => 'Não pode lançar transação para um período já encerrado!',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Credit'                      => 'Crédito',
+  'Customer not on file!'       => 'Cliente não está no arquivo!',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Débito',
+  'Debit and credit out of balance!' => 'Débito e crédito fora de balanço!',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Apagar',
+  'Description'                 => 'Descrição',
+  'Edit General Ledger Transaction' => 'Editar Transação Livro Razão',
+  'Equity'                      => 'Capital',
+  'Expense'                     => 'Despesa',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'GIFI'                        => 'CFOP - Código Fiscal da Operação',
+  'GL Transaction'              => 'Transação do Livro Razão',
+  'General Ledger'              => 'Livro Razão',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Income'                      => 'Receita',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Liability'                   => 'Passivo',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Post'                        => 'Lançar',
+  'Post as new'                 => 'Lançar como novo',
+  'Project'                     => 'Projeto',
+  'Project not on file!'        => 'Projeto não está no arquivo!',
+  'Purchase Invoice'            => 'Fatura de compra',
+  'Reference'                   => 'Referência',
+  'Reference missing!'          => 'Referência faltando!',
+  'Reports'                     => 'Relatórios',
+  'Sales Invoice'               => 'Fatura de Venda',
+  'Select from one of the names below' => 'Selecione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Selecione um dos projetos abaixo',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Source'                      => 'Fonte',
+  'Subtotal'                    => 'Sub-total',
+  'To'                          => 'Até',
+  'Transaction Date missing!'   => 'Data de transação faltando!',
+  'Transaction deleted!'        => 'Transação apagada!',
+  'Transaction posted!'         => 'Transação lançada',
+  'Update'                      => 'Atualizar',
+  'Vendor not on file!'         => 'Distribuidor não está no arquivo!',
+  'Yes'                         => 'Sim',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'transação___contas_a_pagar'  => 'ap_transaction',
+  'transação___contas_a_receber' => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'apagar'                      => 'delete',
+  'transação_do_livro_razão'    => 'gl_transaction',
+  'lançar'                      => 'post',
+  'lançar_como_novo'            => 'post_as_new',
+  'fatura_de_compra'            => 'purchase_invoice',
+  'fatura_de_venda'             => 'sales_invoice',
+  'atualizar'                   => 'update',
+  'sim'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/br/ic b/sql-ledger/locale/br/ic
new file mode 100644 (file)
index 0000000..c28c265
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Ativa',
+  'Add'                         => 'Adicionar',
+  'Add Assembly'                => 'Adicionar Conjunto',
+  'Add Part'                    => 'Adicionar Parte',
+  'Add Purchase Order'          => 'Adicionar Pedido de Compra',
+  'Add Sales Order'             => 'Adicionar Pedido de Venda',
+  'Add Service'                 => 'Adicionar Serviço',
+  'Address'                     => 'Endereço',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Assemblies'                  => 'Conjuntos',
+  'Assemblies restocked!'       => 'Conjuntos re estocados',
+  'Assembly Number missing!'    => 'Número de conjunto faltando!',
+  'Attachment'                  => 'Anexo',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'BOM'                         => 'Lista de Material',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Caixa/bandeja',
+  'Bought'                      => 'Comprado',
+  'COGS'                        => 'Custo de Vendas',
+  'Cannot delete item already invoiced!' => 'Não posso apagar item já faturado!',
+  'Cannot delete item on order!' => 'Não pode apagar item no pedido',
+  'Cannot delete item which is part of an assembly!' => 'Não posso apagar item que é parte de um conjunto',
+  'Cannot delete item!'         => 'Não pode apagar item!',
+  'Cannot stock assemblies!'    => 'Não pode estocar conjuntos!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contato',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Apagar',
+  'Delivery Date'               => 'Data de entrega',
+  'Description'                 => 'Descrição',
+  'Drawing'                     => 'Desenho',
+  'E-mail'                      => 'E-Mail',
+  'E-mail address missing!'     => 'Endereço de E-mail faltando!',
+  'Edit Assembly'               => 'Editar Conjunto',
+  'Edit Part'                   => 'Editar Parte',
+  'Edit Service'                => 'Editar Serviço',
+  'Expense'                     => 'Despesa',
+  'Extended'                    => 'Extendida',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'Image'                       => 'Imagem',
+  'In-line'                     => 'em linha',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Income'                      => 'Receita',
+  'Individual Items'            => 'Ítens individuais',
+  'Inventory'                   => 'Estoque',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Quantidade em estoque TEM de ser zero ANTES que você possa tornar este conjunto obsoleto!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Quantidade em estoque TEM de ser zero ANTES que você possa tornar esta parte/peça  obsoleta!',
+  'Inventory quantity must be zero!' => 'Quantidade em estoque TEM de ser zero!',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number'              => 'Número de Fatura',
+  'Invoice Number missing!'     => 'Número de Fatura não encontrado!',
+  'Item deleted!'               => 'Item apagado!',
+  'Item not on file!'           => 'Item não está no arquivo!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Last Cost'                   => 'Último Custo',
+  'Line Total'                  => 'Total da linha',
+  'Link Accounts'               => 'Ligar Contas',
+  'List Price'                  => 'Preço de lista',
+  'Make'                        => 'Marca',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'Microfiche'                  => 'Microficha',
+  'Model'                       => 'Modelo',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Número faltando na linha',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'On Hand'                     => 'Em Mãos',
+  'On Order'                    => 'Em pedido',
+  'Order'                       => 'Pedido',
+  'Order Date missing!'         => 'Data de Pedido Faltando',
+  'Order Number'                => 'Pedido Número',
+  'Order Number missing!'       => 'Número de pedido faltando!',
+  'Ordered'                     => 'Pedido feito',
+  'Orphaned'                    => 'Ficaram órfãs',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empacotamento',
+  'Packing List Date missing!'  => 'Data da lista de empacotamento faltando!',
+  'Packing List Number missing!' => 'Número da lista de empacotamento faltando!',
+  'Part'                        => 'Parte',
+  'Part Number missing!'        => 'Número da parte não encontrado!',
+  'Parts'                       => 'Partes',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preço',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Projeto',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Qty'                         => 'Qtde',
+  'ROP'                         => 'Nível mínimo de estoque',
+  'Recd'                        => 'Recebidos',
+  'Required by'                 => 'Requerido por',
+  'Sales'                       => 'Vendas',
+  'Sales Order'                 => 'Pedido de Venda',
+  'Save'                        => 'Salvar',
+  'Screen'                      => 'Tela',
+  'Select from one of the items below' => 'Selecione um dos ítens abaixo',
+  'Select postscript or PDF!'   => 'Selecionar Postscript ou PDF',
+  'Sell Price'                  => 'Preço de Venda',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Service'                     => 'Serviço',
+  'Service Number missing!'     => 'Número do serviço não encontrado!',
+  'Services'                    => 'Serviços',
+  'Ship'                        => 'Transportar',
+  'Ship to'                     => 'Transportar para',
+  'Short'                       => 'Curto',
+  'Sold'                        => 'Vendido',
+  'Stock Assembly'              => 'Conjunto normal de estoque',
+  'Subject'                     => 'Assunto',
+  'Subtotal'                    => 'Sub-total',
+  'Tax'                         => 'Imposto',
+  'To'                          => 'Até',
+  'Top Level'                   => 'Nível superior',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidade',
+  'Unit of measure'             => 'Unidade de medida',
+  'Update'                      => 'Atualizar',
+  'Updated'                     => 'Atualizado',
+  'Weight'                      => 'Peso',
+  'What type of item is this?'  => 'Que tipo de Item é este?',
+  'ea'                          => 'cada',
+  'emailed to'                  => 'enviado por email para',
+  'hr'                          => 'h',
+  'sent to printer'             => 'enviado para impressora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'adicionar'                   => 'add',
+  'adicionar_conjunto'          => 'add_assembly',
+  'adicionar_parte'             => 'add_part',
+  'adicionar_serviço'           => 'add_service',
+  'continuar'                   => 'continue',
+  'apagar'                      => 'delete',
+  'editar_conjunto'             => 'edit_assembly',
+  'editar_parte'                => 'edit_part',
+  'editar_serviço'              => 'edit_service',
+  'salvar'                      => 'save',
+  'atualizar'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/br/io b/sql-ledger/locale/br/io
new file mode 100644 (file)
index 0000000..8d07ecf
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Adicionar Pedido de Compra',
+  'Add Sales Order'             => 'Adicionar Pedido de Venda',
+  'Address'                     => 'Endereço',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Attachment'                  => 'Anexo',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Caixa/bandeja',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contato',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delivery Date'               => 'Data de entrega',
+  'Description'                 => 'Descrição',
+  'E-mail'                      => 'E-Mail',
+  'E-mail address missing!'     => 'Endereço de E-mail faltando!',
+  'Extended'                    => 'Extendida',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'In-line'                     => 'em linha',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number missing!'     => 'Número de Fatura não encontrado!',
+  'Item not on file!'           => 'Item não está no arquivo!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Número faltando na linha',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Order'                       => 'Pedido',
+  'Order Date missing!'         => 'Data de Pedido Faltando',
+  'Order Number missing!'       => 'Número de pedido faltando!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empacotamento',
+  'Packing List Date missing!'  => 'Data da lista de empacotamento faltando!',
+  'Packing List Number missing!' => 'Número da lista de empacotamento faltando!',
+  'Part'                        => 'Parte',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preço',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Projeto',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Qty'                         => 'Qtde',
+  'Recd'                        => 'Recebidos',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Pedido de Venda',
+  'Screen'                      => 'Tela',
+  'Select from one of the items below' => 'Selecione um dos ítens abaixo',
+  'Select postscript or PDF!'   => 'Selecionar Postscript ou PDF',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Service'                     => 'Serviço',
+  'Ship'                        => 'Transportar',
+  'Ship to'                     => 'Transportar para',
+  'Subject'                     => 'Assunto',
+  'To'                          => 'Até',
+  'Unit'                        => 'Unidade',
+  'What type of item is this?'  => 'Que tipo de Item é este?',
+  'emailed to'                  => 'enviado por email para',
+  'sent to printer'             => 'enviado para impressora',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/br/ir b/sql-ledger/locale/br/ir
new file mode 100644 (file)
index 0000000..67bc4d4
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Conta',
+  'Add Purchase Invoice'        => 'Adicionar Fatura de Compra',
+  'Add Purchase Order'          => 'Adicionar Pedido de Compra',
+  'Add Sales Order'             => 'Adicionar Pedido de Venda',
+  'Address'                     => 'Endereço',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => 'Tem certeza que quer APAGAR a Fatura Número',
+  'Attachment'                  => 'Anexo',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Caixa/bandeja',
+  'Cannot delete invoice!'      => 'Não pode apagar fatura!',
+  'Cannot post invoice for a closed period!' => 'Não pode lançar fatura em período fechado!',
+  'Cannot post invoice!'        => 'Não pode lançar fatura!',
+  'Cannot post payment for a closed period!' => 'Não pode lançar pagamento em período fechado!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contato',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Currency'                    => 'Moeda',
+  'Customer not on file!'       => 'Cliente não está no arquivo!',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Data de Vencimento',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Apagar',
+  'Delivery Date'               => 'Data de entrega',
+  'Description'                 => 'Descrição',
+  'E-mail'                      => 'E-Mail',
+  'E-mail address missing!'     => 'Endereço de E-mail faltando!',
+  'Edit Purchase Invoice'       => 'Editar Fatura de Compra',
+  'Exch'                        => 'Câmbio',
+  'Exchangerate'                => 'Taxa de câmbio',
+  'Exchangerate for payment missing!' => 'Falta a taxa de câmbio para o pagamento!',
+  'Exchangerate missing!'       => 'Falta a taxa de câmbio!',
+  'Extended'                    => 'Extendida',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'In-line'                     => 'em linha',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date'                => 'Data de Fatura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number'              => 'Número de Fatura',
+  'Invoice Number missing!'     => 'Número de Fatura não encontrado!',
+  'Invoice deleted!'            => 'Fatura apagada!',
+  'Invoice posted!'             => 'Fatura lançada!',
+  'Item not on file!'           => 'Item não está no arquivo!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Número faltando na linha',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Order'                       => 'Pedido',
+  'Order Date missing!'         => 'Data de Pedido Faltando',
+  'Order Number'                => 'Pedido Número',
+  'Order Number missing!'       => 'Número de pedido faltando!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empacotamento',
+  'Packing List Date missing!'  => 'Data da lista de empacotamento faltando!',
+  'Packing List Number missing!' => 'Número da lista de empacotamento faltando!',
+  'Part'                        => 'Parte',
+  'Payment date missing!'       => 'Data de pagamento faltando!',
+  'Payments'                    => 'Pagamentos',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Lançar',
+  'Post as new'                 => 'Lançar como novo',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preço',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Projeto',
+  'Project not on file!'        => 'Projeto não está no arquivo!',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Qty'                         => 'Qtde',
+  'Recd'                        => 'Recebidos',
+  'Record in'                   => 'Registrar em',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Pedido de Venda',
+  'Screen'                      => 'Tela',
+  'Select from one of the items below' => 'Selecione um dos ítens abaixo',
+  'Select from one of the names below' => 'Selecione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Selecione um dos projetos abaixo',
+  'Select postscript or PDF!'   => 'Selecionar Postscript ou PDF',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Service'                     => 'Serviço',
+  'Ship'                        => 'Transportar',
+  'Ship to'                     => 'Transportar para',
+  'Source'                      => 'Fonte',
+  'Subject'                     => 'Assunto',
+  'Subtotal'                    => 'Sub-total',
+  'Tax Included'                => 'Impostos incluídos',
+  'To'                          => 'Até',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidade',
+  'Update'                      => 'Atualizar',
+  'Vendor'                      => 'Distribuidor',
+  'Vendor missing!'             => 'Distribuidor faltando!',
+  'Vendor not on file!'         => 'Distribuidor não está no arquivo!',
+  'What type of item is this?'  => 'Que tipo de Item é este?',
+  'Yes'                         => 'Sim',
+  'ea'                          => 'cada',
+  'emailed to'                  => 'enviado por email para',
+  'sent to printer'             => 'enviado para impressora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'apagar'                      => 'delete',
+  'pedido'                      => 'order',
+  'lançar'                      => 'post',
+  'lançar_como_novo'            => 'post_as_new',
+  'atualizar'                   => 'update',
+  'sim'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/br/is b/sql-ledger/locale/br/is
new file mode 100644 (file)
index 0000000..7d11365
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Conta',
+  'Add Purchase Order'          => 'Adicionar Pedido de Compra',
+  'Add Sales Invoice'           => 'Adicionar Fatura de Venda',
+  'Add Sales Order'             => 'Adicionar Pedido de Venda',
+  'Address'                     => 'Endereço',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => 'Tem certeza que quer APAGAR a Fatura Número',
+  'Attachment'                  => 'Anexo',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Caixa/bandeja',
+  'Cannot delete invoice!'      => 'Não pode apagar fatura!',
+  'Cannot post invoice for a closed period!' => 'Não pode lançar fatura em período fechado!',
+  'Cannot post invoice!'        => 'Não pode lançar fatura!',
+  'Cannot post payment for a closed period!' => 'Não pode lançar pagamento em período fechado!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contato',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Credit Limit'                => 'Limite de Crédito',
+  'Currency'                    => 'Moeda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Cliente faltando!',
+  'Customer not on file!'       => 'Cliente não está no arquivo!',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Data de Vencimento',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Apagar',
+  'Delivery Date'               => 'Data de entrega',
+  'Description'                 => 'Descrição',
+  'E-mail'                      => 'E-Mail',
+  'E-mail address missing!'     => 'Endereço de E-mail faltando!',
+  'Edit Sales Invoice'          => 'Editar Fatura de Venda',
+  'Exch'                        => 'Câmbio',
+  'Exchangerate'                => 'Taxa de câmbio',
+  'Exchangerate for payment missing!' => 'Falta a taxa de câmbio para o pagamento!',
+  'Exchangerate missing!'       => 'Falta a taxa de câmbio!',
+  'Extended'                    => 'Extendida',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'In-line'                     => 'em linha',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date'                => 'Data de Fatura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number'              => 'Número de Fatura',
+  'Invoice Number missing!'     => 'Número de Fatura não encontrado!',
+  'Invoice deleted!'            => 'Fatura apagada!',
+  'Invoice posted!'             => 'Fatura lançada!',
+  'Item not on file!'           => 'Item não está no arquivo!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Número faltando na linha',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Order'                       => 'Pedido',
+  'Order Date missing!'         => 'Data de Pedido Faltando',
+  'Order Number'                => 'Pedido Número',
+  'Order Number missing!'       => 'Número de pedido faltando!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empacotamento',
+  'Packing List Date missing!'  => 'Data da lista de empacotamento faltando!',
+  'Packing List Number missing!' => 'Número da lista de empacotamento faltando!',
+  'Part'                        => 'Parte',
+  'Payment date missing!'       => 'Data de pagamento faltando!',
+  'Payments'                    => 'Pagamentos',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Lançar',
+  'Post as new'                 => 'Lançar como novo',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preço',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Projeto',
+  'Project not on file!'        => 'Projeto não está no arquivo!',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Qty'                         => 'Qtde',
+  'Recd'                        => 'Recebidos',
+  'Record in'                   => 'Registrar em',
+  'Remaining'                   => 'Restante',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Pedido de Venda',
+  'Screen'                      => 'Tela',
+  'Select from one of the items below' => 'Selecione um dos ítens abaixo',
+  'Select from one of the names below' => 'Selecione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Selecione um dos projetos abaixo',
+  'Select postscript or PDF!'   => 'Selecionar Postscript ou PDF',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Service'                     => 'Serviço',
+  'Ship'                        => 'Transportar',
+  'Ship to'                     => 'Transportar para',
+  'Ship via'                    => 'Transportar via',
+  'Source'                      => 'Fonte',
+  'Subject'                     => 'Assunto',
+  'Subtotal'                    => 'Sub-total',
+  'Tax Included'                => 'Impostos incluídos',
+  'To'                          => 'Até',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidade',
+  'Update'                      => 'Atualizar',
+  'Vendor not on file!'         => 'Distribuidor não está no arquivo!',
+  'What type of item is this?'  => 'Que tipo de Item é este?',
+  'Yes'                         => 'Sim',
+  'ea'                          => 'cada',
+  'emailed to'                  => 'enviado por email para',
+  'sent to printer'             => 'enviado para impressora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'apagar'                      => 'delete',
+  'e_mail'                      => 'e_mail',
+  'pedido'                      => 'order',
+  'lançar'                      => 'post',
+  'lançar_como_novo'            => 'post_as_new',
+  'imprimir'                    => 'print',
+  'transportar_para'            => 'ship_to',
+  'atualizar'                   => 'update',
+  'sim'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/br/login b/sql-ledger/locale/br/login
new file mode 100644 (file)
index 0000000..ff7494c
--- /dev/null
@@ -0,0 +1,28 @@
+$self{texts} = {
+  'About'                       => 'Sobre',
+  'Accounting'                  => 'Contabilidade',
+  'Database Host'               => 'Servidor de Base de Dados',
+  'Dataset'                     => 'Conjunto de dados',
+  'Incorrect Dataset version!'  => 'Versão incorreta de grupos de dados!',
+  'Incorrect Password!'         => 'Senha incorreta!',
+  'Licensed to'                 => 'Licenciado a',
+  'Login'                       => 'Acessar/login',
+  'Name'                        => 'Nome',
+  'Password'                    => 'Senha',
+  'User'                        => 'Usuário',
+  'Version'                     => 'Versão',
+  'You are logged out!'         => 'Você saiu do sistema!',
+  'You did not enter a name!'   => 'Você não entrou com um nome',
+  'is not a member!'            => 'não é um membro!',
+  'localhost'                   => 'localhost /servidor local',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'acessar/login'               => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/br/menu b/sql-ledger/locale/br/menu
new file mode 100644 (file)
index 0000000..1ad51b6
--- /dev/null
@@ -0,0 +1,72 @@
+$self{texts} = {
+  'AP'                          => 'Contas a Pagar',
+  'AP Aging'                    => 'Contas a Pagar Vencidas',
+  'AR'                          => 'Contas a Receber',
+  'AR Aging'                    => 'Contas a Receber Vencidas',
+  'Accounting Menu'             => 'Menu de Contabilidade',
+  'Add Account'                 => 'Adicionar Conta',
+  'Add Assembly'                => 'Adicionar Conjunto',
+  'Add Customer'                => 'Adicionar Cliente',
+  'Add GIFI'                    => 'Adicionar CFOP',
+  'Add Part'                    => 'Adicionar Parte',
+  'Add Project'                 => 'Adicionar projeto',
+  'Add Service'                 => 'Adicionar Serviço',
+  'Add Transaction'             => 'Adicionar Transação',
+  'Add Vendor'                  => 'Adicionar Distribuidor',
+  'Assemblies'                  => 'Conjuntos',
+  'Audit Control'               => 'Controle de Auditoria',
+  'Backup'                      => 'Cópia de reserva',
+  'Balance Sheet'               => 'Folha de Balanço',
+  'Cash'                        => 'Caixa',
+  'Chart of Accounts'           => 'Código de Contas',
+  'Check'                       => 'Cheque',
+  'Customers'                   => 'Clientes',
+  'General Ledger'              => 'Livro Razão',
+  'Goods & Services'            => 'Produtos e Serviços',
+  'HTML Templates'              => 'Modelos HTML',
+  'Income Statement'            => 'Estado de Receitas',
+  'Invoice'                     => 'Fatura',
+  'LaTeX Templates'             => 'Modelos LaTeX',
+  'List Accounts'               => 'Listar Contas',
+  'List GIFI'                   => 'Listar CFOP',
+  'Logout'                      => 'Logout (sair)',
+  'Order Entry'                 => 'Entrada de Pedido',
+  'Packing List'                => 'Lista de Empacotamento',
+  'Parts'                       => 'Partes',
+  'Payment'                     => 'Pagamento',
+  'Payments'                    => 'Pagamentos',
+  'Preferences'                 => 'Preferências',
+  'Projects'                    => 'Projetos',
+  'Purchase Invoice'            => 'Fatura de compra',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Purchase Orders'             => 'Ordens de Compra',
+  'Receipt'                     => 'Recibo',
+  'Receipts'                    => 'Recibos',
+  'Reconciliation'              => 'Reconciliação',
+  'Reports'                     => 'Relatórios',
+  'Sales Invoice'               => 'Fatura de Venda',
+  'Sales Order'                 => 'Pedido de Venda',
+  'Sales Orders'                => 'Pedidos de Venda',
+  'Save to File'                => 'Salvar para Arquivo',
+  'Send by E-Mail'              => 'Enviar por E-mail',
+  'Services'                    => 'Serviços',
+  'Statement'                   => 'Declaração',
+  'Stock Assembly'              => 'Conjunto normal de estoque',
+  'Stylesheet'                  => 'Folha de estilos',
+  'System'                      => 'Sistema',
+  'Tax collected'               => 'Imposto recolhido',
+  'Tax paid'                    => 'Imposto pago',
+  'Transactions'                => 'Tansações',
+  'Trial Balance'               => 'Balanço Preliminar',
+  'Vendors'                     => 'Distribuidores',
+  'Version'                     => 'Versão',
+  'localhost'                   => 'localhost /servidor local',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/br/oe b/sql-ledger/locale/br/oe
new file mode 100644 (file)
index 0000000..d984270
--- /dev/null
@@ -0,0 +1,199 @@
+$self{texts} = {
+  'Add'                         => 'Adicionar',
+  'Add Purchase Invoice'        => 'Adicionar Fatura de Compra',
+  'Add Purchase Order'          => 'Adicionar Pedido de Compra',
+  'Add Sales Invoice'           => 'Adicionar Fatura de Venda',
+  'Add Sales Order'             => 'Adicionar Pedido de Venda',
+  'Address'                     => 'Endereço',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Order Number' => 'Tem certeza que quer APAGAR tal número de Pedido?',
+  'Attachment'                  => 'Anexo',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Caixa/bandeja',
+  'C'                           => 'F',
+  'Cannot delete order!'        => 'Não pode apagar pedido!',
+  'Cannot save order!'          => 'Não pode salvar pedido!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Fechado',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contato',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Credit Limit'                => 'Limite de Crédito',
+  'Curr'                        => 'Moeda',
+  'Currency'                    => 'Moeda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Cliente faltando!',
+  'Customer not on file!'       => 'Cliente não está no arquivo!',
+  'Date'                        => 'Data',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Apagar',
+  'Delivery Date'               => 'Data de entrega',
+  'Description'                 => 'Descrição',
+  'E-mail'                      => 'E-Mail',
+  'E-mail address missing!'     => 'Endereço de E-mail faltando!',
+  'Edit Purchase Order'         => 'Editar Pedido de Compra',
+  'Edit Sales Order'            => 'Editar Pedido de Venda',
+  'Exchangerate'                => 'Taxa de câmbio',
+  'Exchangerate missing!'       => 'Falta a taxa de câmbio!',
+  'Extended'                    => 'Extendida',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'ID'                          => 'ID',
+  'In-line'                     => 'em linha',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number missing!'     => 'Número de Fatura não encontrado!',
+  'Item not on file!'           => 'Item não está no arquivo!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Número faltando na linha',
+  'O'                           => 'A',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Open'                        => 'Abrir',
+  'Order'                       => 'Pedido',
+  'Order Date'                  => 'Data de Pedido',
+  'Order Date missing!'         => 'Data de Pedido Faltando',
+  'Order Number'                => 'Pedido Número',
+  'Order Number missing!'       => 'Número de pedido faltando!',
+  'Order deleted!'              => 'Pedido apagado!',
+  'Order saved!'                => 'Pedido salvo!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empacotamento',
+  'Packing List Date missing!'  => 'Data da lista de empacotamento faltando!',
+  'Packing List Number missing!' => 'Número da lista de empacotamento faltando!',
+  'Part'                        => 'Parte',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preço',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Projeto',
+  'Project not on file!'        => 'Projeto não está no arquivo!',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Purchase Orders'             => 'Ordens de Compra',
+  'Qty'                         => 'Qtde',
+  'Recd'                        => 'Recebidos',
+  'Remaining'                   => 'Restante',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Pedido de Venda',
+  'Sales Orders'                => 'Pedidos de Venda',
+  'Save'                        => 'Salvar',
+  'Save as new'                 => 'Salvar como novo',
+  'Screen'                      => 'Tela',
+  'Select from one of the items below' => 'Selecione um dos ítens abaixo',
+  'Select from one of the names below' => 'Selecione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Selecione um dos projetos abaixo',
+  'Select postscript or PDF!'   => 'Selecionar Postscript ou PDF',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Service'                     => 'Serviço',
+  'Ship'                        => 'Transportar',
+  'Ship to'                     => 'Transportar para',
+  'Ship via'                    => 'Transportar via',
+  'Subject'                     => 'Assunto',
+  'Subtotal'                    => 'Sub-total',
+  'Tax'                         => 'Imposto',
+  'Tax Included'                => 'Impostos incluídos',
+  'Terms: Net'                  => 'Crédito Líquido',
+  'To'                          => 'Até',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidade',
+  'Update'                      => 'Atualizar',
+  'Vendor'                      => 'Distribuidor',
+  'Vendor missing!'             => 'Distribuidor faltando!',
+  'Vendor not on file!'         => 'Distribuidor não está no arquivo!',
+  'What type of item is this?'  => 'Que tipo de Item é este?',
+  'Yes'                         => 'Sim',
+  'days'                        => 'Dias',
+  'ea'                          => 'cada',
+  'emailed to'                  => 'enviado por email para',
+  'sent to printer'             => 'enviado para impressora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'adicionar'                   => 'add',
+  'continuar'                   => 'continue',
+  'apagar'                      => 'delete',
+  'e_mail'                      => 'e_mail',
+  'fatura'                      => 'invoice',
+  'imprimir'                    => 'print',
+  'salvar'                      => 'save',
+  'salvar_como_novo'            => 'save_as_new',
+  'transportar_para'            => 'ship_to',
+  'atualizar'                   => 'update',
+  'sim'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/br/pe b/sql-ledger/locale/br/pe
new file mode 100644 (file)
index 0000000..1441b36
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Adicionar',
+  'Add Project'                 => 'Adicionar projeto',
+  'All'                         => 'Todas',
+  'Continue'                    => 'Continuar',
+  'Delete'                      => 'Apagar',
+  'Description'                 => 'Descrição',
+  'Edit Project'                => 'Editar Projeto',
+  'Number'                      => 'Número',
+  'Orphaned'                    => 'Ficaram órfãs',
+  'Project'                     => 'Projeto',
+  'Project Number missing!'     => 'Número do Projeto faltando!',
+  'Project deleted!'            => 'Projeto apagado!',
+  'Project saved!'              => 'Projeto salvo!',
+  'Projects'                    => 'Projetos',
+  'Save'                        => 'Salvar',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'adicionar'                   => 'add',
+  'continuar'                   => 'continue',
+  'apagar'                      => 'delete',
+  'salvar'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/br/rc b/sql-ledger/locale/br/rc
new file mode 100644 (file)
index 0000000..7fd872b
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Conta',
+  'Balance'                     => 'Balanço',
+  'Cleared Balance'             => 'Balanço limpo',
+  'Continue'                    => 'Continuar',
+  'Date'                        => 'Data',
+  'Deposit'                     => 'Depósito',
+  'Description'                 => 'Descrição',
+  'Difference'                  => 'Diferença',
+  'Done'                        => 'Feito',
+  'Exchangerate Difference'     => 'Diferença da Taxa de Câmbio',
+  'From'                        => 'De',
+  'Out of balance!'             => 'Fora de balanço!',
+  'Payment'                     => 'Pagamento',
+  'Reconciliation'              => 'Reconciliação',
+  'Select all'                  => 'Selecionar todos',
+  'Source'                      => 'Fonte',
+  'Statement Balance'           => 'Declaração de Balanço',
+  'To'                          => 'Até',
+  'Update'                      => 'Atualizar',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'continuar'                   => 'continue',
+  'feito'                       => 'done',
+  'selecionar_todos'            => 'select_all',
+  'atualizar'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/br/rp b/sql-ledger/locale/br/rp
new file mode 100644 (file)
index 0000000..f441153
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'Contas a Pagar Vencidas',
+  'AR Aging'                    => 'Contas a Receber Vencidas',
+  'Account'                     => 'Conta',
+  'Accounts'                    => 'Contas',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Attachment'                  => 'Anexo',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance Sheet'               => 'Folha de Balanço',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Baseado no Caixa',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Comparar a',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Credit'                      => 'Crédito',
+  'Current'                     => 'Current',
+  'Customer'                    => 'Cliente',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Débito',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Decimalplaces'               => 'Casas decimais',
+  'Description'                 => 'Descrição',
+  'Due'                         => 'Saldo',
+  'E-mail'                      => 'E-Mail',
+  'E-mail Statement to'         => 'Declaração enviada por email para',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'GIFI'                        => 'CFOP - Código Fiscal da Operação',
+  'Heading'                     => 'Cabeçalho',
+  'ID'                          => 'ID',
+  'In-line'                     => 'em linha',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Income Statement'            => 'Estado de Receitas',
+  'Invoice'                     => 'Fatura',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'N/A'                         => 'N/D',
+  'Nothing selected!'           => 'Nada foi selecionado!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Pagamentos',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impressora',
+  'Receipts'                    => 'Recibos',
+  'Report for'                  => 'Relatório para',
+  'Retained Earnings'           => 'Lucros Retidos',
+  'Screen'                      => 'Tela',
+  'Select all'                  => 'Selecionar todos',
+  'Select postscript or PDF!'   => 'Selecionar Postscript ou PDF',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Source'                      => 'Fonte',
+  'Standard'                    => 'Padrão',
+  'Statement'                   => 'Declaração',
+  'Statement sent to'           => 'Declaração enviada para',
+  'Statements sent to printer!' => 'Declaração enviada para impressora!',
+  'Subject'                     => 'Assunto',
+  'Subtotal'                    => 'Sub-total',
+  'Tax'                         => 'Imposto',
+  'Tax collected'               => 'Imposto recolhido',
+  'Tax paid'                    => 'Imposto pago',
+  'To'                          => 'Até',
+  'Total'                       => 'Total',
+  'Trial Balance'               => 'Balanço Preliminar',
+  'Vendor'                      => 'Distribuidor',
+  'as at'                       => 'como em',
+  'collected on sales'          => 'recolhido sobre vendas',
+  'for Period'                  => 'pelo período',
+  'paid on purchases'           => 'pago em aquisições',
+  'to'                          => 'para',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'continuar'                   => 'continue',
+  'e_mail'                      => 'e_mail',
+  'imprimir'                    => 'print',
+  'selecionar_todos'            => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/COPYING b/sql-ledger/locale/cn/COPYING
new file mode 100644 (file)
index 0000000..784c015
--- /dev/null
@@ -0,0 +1,24 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Simplified Chinese texts:
+#
+#  Author: Chien Hsin Chang <werther@elixus.org>
+#          Autrijus Tang <autrijus@autrijus.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/cn/LANGUAGE b/sql-ledger/locale/cn/LANGUAGE
new file mode 100644 (file)
index 0000000..42c3708
--- /dev/null
@@ -0,0 +1 @@
+Simplified Chinese
diff --git a/sql-ledger/locale/cn/admin b/sql-ledger/locale/cn/admin
new file mode 100644 (file)
index 0000000..c867787
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => '?¨ÏÞ¿ØÖ?',
+  'Accounting'                  => '»á¼Æ',
+  'Add User'                    => 'ÐÂÔöʹÓÃÕß',
+  'Address'                     => 'µØÖ·',
+  'Administration'              => 'ϵͳ¹ÜÀí',
+  'Administrator'               => 'ϵͳ¹ÜÀíÔ±',
+  'All Datasets up to date!'    => 'ËùÓÐ×ÊÁϽÔÒѸüÐÂ!',
+  'Change Admin Password'       => '¸ü¸Ä¹ÜÀíÔ±ÃÜÂë',
+  'Change Password'             => '¸ü¸ÄÃÜÂë',
+  'Character Set'               => '×ÖÔª¼¯',
+  'Click on login name to edit!' => 'Çë°´µÇ?ëÃ?³ÆÒÔ½øÐÐÐÞ¸Ä!',
+  'Company'                     => '¹«Ë¾Ãû³Æ',
+  'Connect to'                  => 'Á¬½áµ½',
+  'Continue'                    => '¼ÌÐø',
+  'Create Chart of Accounts'    => '½¨Á¢ÕÊ»§Í¼±í',
+  'Create Dataset'              => '½¨Á¢×ÊÁϼ¯',
+  'DBI not installed!'          => 'δ°²×° DBI Ä£×é!',
+  'Database'                    => '×ÊÁÏ¿â',
+  'Database Administration'     => '×ÊÁÏ¿â¹ÜÀí',
+  'Database Driver not checked!' => 'δѡ¶¨×ÊÁÏ¿â??¶¯³Ìʽ!',
+  'Database User missing!'      => 'δָÃ÷×ÊÁÏ¿âʹÓÃÕß!',
+  'Dataset'                     => '×ÊÁϼ¯',
+  'Dataset missing!'            => 'δָÃ÷×ÊÁϼ¯!',
+  'Dataset updated!'            => '²¹³ä×îÐÂ×ÊÁϼ¯!',
+  'Date Format'                 => 'ÈÕÆÚ¸ñʽ',
+  'Delete'                      => 'ɾ³ý',
+  'Delete Dataset'              => 'ɾ³ý×ÊÁϼ¯',
+  'Directory'                   => 'Ŀ¼',
+  'Driver'                      => '??¶¯³Ìʽ',
+  'Dropdown Limit'              => 'ÏÞÖÆ×ÊÁÏÏÔʾ¹¦ÄÜ',
+  'E-mail'                      => 'µç×ÓÓʼþ',
+  'Edit User'                   => '±à¼­Ê¹ÓÃÕß',
+  'Existing Datasets'           => '¼ÈÓеÄ×ÊÁϼ¯',
+  'Fax'                         => '´«Õæ',
+  'Host'                        => 'Ö÷»ú',
+  'Hostname missing!'           => 'δָÃ÷Ö÷»úÃû³Æ!',
+  'Incorrect Password!'         => 'ÃÜÂë´íÎó!',
+  'Language'                    => 'Óïϵ',
+  'Leave host and port field empty unless you want to make a remote connection.' => '³ý·ÇÄúÏëÒª½øÐÐÔ¶¶ËÁ¬Ïß, ·ñÔòÇ뽫Ö÷»ú¼°²ººÅÁô°×.',
+  'Login'                       => 'µÇ??',
+  'Multibyte Encoding'          => 'Multibyte Encoding',
+  'Name'                        => 'Ãû³Æ',
+  'New Templates'               => 'ÐÂÔöÄ£°æ',
+  'No Database Drivers available!' => 'ûÓпÉÓõÄ??¶¯³Ìʽ!',
+  'No Dataset selected!'        => 'δѡ¶¨×ÊÁϼ¯!',
+  'Nothing to delete!'          => 'ûÓпÉɾ³ýµÄÏîÄ¿',
+  'Number Format'               => 'Êý×Ö¸ñʽ',
+  'Oracle Database Administration' => 'Oracle ×ÊÁÏ¿â¹ÜÀí',
+  'Password'                    => 'ÃÜÂë',
+  'Password changed!'           => 'ÃÜÂëÒѾ­¸ü¸Ä',
+  'Pg Database Administration'  => 'Pg ×ÊÁÏ¿â¹ÜÀí',
+  'Phone'                       => 'µç»°ºÅÂë',
+  'Port'                        => '²ººÅ',
+  'Port missing!'               => 'δָÃ÷²ººÅ!',
+  'Printer'                     => 'Ó¡±í»ú',
+  'Save'                        => '´¢´æ',
+  'Select a Dataset to delete and press "Continue"' => 'ÇëÑ¡ÔñÓûɾ³ýµÄ×ÊÁϼ¯, ÔÙ°´ "¼ÌÐø"',
+  'Setup Templates'             => 'É趨ģ°æ',
+  'Ship via'                    => 'º½ÔË·½·¨',
+  'Signature'                   => 'Ç©Ãû',
+  'Stylesheet'                  => 'Ñùʽ±í',
+  'Templates'                   => 'Ä£°æ',
+  'The following Datasets are not in use and can be deleted' => 'ÏÂÁÐ×ÊÁϼ¯²¢Î´Ê¹ÓÃ, ¿ÉÒÔɾ³ý',
+  'The following Datasets need to be updated' => 'ÏÂÁÐ×ÊÁϼ¯ÐèÒª¸üÐÂ',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'ÕâÊǶԼȴæ×ÊÁÏÀ´Ô´µÄ³õ²½¼ì²é. Ôڴ˽׶Î, ²»»áɾ³ý»òÐÂÔö?κÎ×ÊÁ?!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => '?ôÒªÐÂÔöȺ×éÄÚµÄʹÓÃÕ?, Çë±à¼­Ãû³Æ, ¸ü¸ÄµÇ?ëÃ?, ?»ºó´¢´?.  ÕâÑùÒ»À´, ÐÂʹÓÃÕ߻ᱣÁôÏàͬµÄ±äÊý, ²¢ÒÔеĵÇ?ëÃ?´æ??.',
+  'Update Dataset'              => '¸üÐÂ×ÊÁϼ¯',
+  'Use Templates'               => 'ʹÓÃÄ£°æ',
+  'User'                        => 'ʹÓÃÕß',
+  'User deleted!'               => 'ʹÓÃÕßÒÔ±»É¾³ý!',
+  'User saved!'                 => 'ʹÓÃÕßÒÔ±»´¢´æ!',
+  'Version'                     => '°æ±¾',
+  'You must enter a host and port for local and remote connections!' => 'Äú±ØÐè¼ü?ëÖ÷»?¼°²ººÅ, ÒÔ½øÐб¾»ú»òÔ¶¶ËÁ¬Ïß!',
+  'does not exist'              => '²»´æÔÚ',
+  'is already a member!'        => 'ÒѾ­ÊdzÉÔ±ÁË!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'locked!',
+  'successfully created!'       => '³É¹¦½¨Á¢!',
+  'successfully deleted!'       => '³É¹¦É¾³ý!',
+  'website'                     => 'ÍøÕ¾',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'ÐÂÔöʹÓÃÕß'                  => 'add_user',
+  '¸ü¸Ä¹ÜÀíÔ±ÃÜÂë'              => 'change_admin_password',
+  '¸ü¸ÄÃÜÂë'                    => 'change_password',
+  '¼ÌÐø'                        => 'continue',
+  '½¨Á¢×ÊÁϼ¯'                  => 'create_dataset',
+  'ɾ³ý'                        => 'delete',
+  'ɾ³ý×ÊÁϼ¯'                  => 'delete_dataset',
+  'µÇ??'                        => 'login',
+  'oracle_×ÊÁÏ¿â¹ÜÀí'           => 'oracle_database_administration',
+  'pg_×ÊÁÏ¿â¹ÜÀí'               => 'pg_database_administration',
+  '´¢´æ'                        => 'save',
+  '¸üÐÂ×ÊÁϼ¯'                  => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/all b/sql-ledger/locale/cn/all
new file mode 100644 (file)
index 0000000..6b01f15
--- /dev/null
@@ -0,0 +1,495 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Ó¦¸¶ÕÊ¿î',
+  'AP Aging'                    => 'Ó¦¸¶ÕÊÁä·ÖÎö',
+  'AP Transaction'              => 'Ó¦¸¶ÕÊÄ¿',
+  'AP Transactions'             => 'Ó¦¸¶ÕÊÄ¿',
+  'AR'                          => 'Ó¦ÊÕÕÊ¿î',
+  'AR Aging'                    => 'Ó¦ÊÕÕÊÁä·ÖÎö',
+  'AR Transaction'              => 'Ó¦ÊÕÕÊÄ¿',
+  'AR Transactions'             => 'Ó¦ÊÕÕÊÄ¿',
+  'About'                       => '¹Øì¶',
+  'Access Control'              => '?¨ÏÞ¿ØÖ?',
+  'Account'                     => '¿ÆÄ¿',
+  'Account Number'              => '¿ÆÄ¿±àºÅ',
+  'Account Number missing!'     => '©Ìî¿ÆÄ¿±àºÅ!',
+  'Account Type'                => '¿ÆÄ¿Àà±ð',
+  'Account Type missing!'       => '©Ìî¿ÆÄ¿Àà±ð!',
+  'Account deleted!'            => '¿ÆÄ¿ÒÔ±»É¾³ý!',
+  'Account saved!'              => '¿ÆÄ¿ÒÔ±»´¢´æ!',
+  'Accounting'                  => '»á¼Æ',
+  'Accounting Menu'             => '»á¼ÆÑ¡µ¥',
+  'Accounts'                    => 'ÕÊ»§',
+  'Active'                      => '»îÔ¾',
+  'Add'                         => 'ÐÂÔö',
+  'Add Account'                 => 'ÐÂÔö¿ÆÄ¿',
+  'Add Accounts Payables Transaction' => 'ÐÂÔöÓ¦¸¶ÕÊÄ¿',
+  'Add Accounts Receivables Transaction' => 'ÐÂÔöÓ¦ÊÕÕÊÄ¿',
+  'Add Assembly'                => 'ÐÂÔöÉÌÆ·',
+  'Add Customer'                => 'ÐÂÔö¿Í»§',
+  'Add GIFI'                    => 'ÐÂÔö GIFI',
+  'Add General Ledger Transaction' => 'ÐÂÔö×ÜÕÊ',
+  'Add Part'                    => 'ÐÂÔöÔ­ÁÏ',
+  'Add Project'                 => 'ÐÂÔö¹¤³Ì',
+  'Add Purchase Invoice'        => 'ÐÂÔö²É¹º·¢Æ±',
+  'Add Purchase Order'          => 'ÐÂÔö²É¹ºµ¥',
+  'Add Sales Invoice'           => 'ÐÂÔöÏú»õ·¢Æ±',
+  'Add Sales Order'             => 'ÐÂÔöÏú»õµ¥',
+  'Add Service'                 => 'ÐÂÔö·þÎñ',
+  'Add Transaction'             => 'ÐÂÔöÕÊÄ¿',
+  'Add User'                    => 'ÐÂÔöʹÓÃÕß',
+  'Add Vendor'                  => 'ÐÂÔö³§ÉÌ',
+  'Address'                     => 'µØÖ·',
+  'Administration'              => 'ϵͳ¹ÜÀí',
+  'Administrator'               => 'ϵͳ¹ÜÀíÔ±',
+  'All'                         => 'È«²¿',
+  'All Datasets up to date!'    => 'ËùÓÐ×ÊÁϽÔÒѸüÐÂ!',
+  'Amount'                      => '×ܼÆ',
+  'Amount Due'                  => 'µ½ÆÚµÄ×ܼÆ',
+  'Amount does not equal applied!' => '×ܶÏàµÈ!',
+  'Amount missing!'             => 'δָÃ÷×ܶî!',
+  'Applied'                     => 'Ö§¸¶',
+  'Apr'                         => 'ËÄÔÂ',
+  'April'                       => 'ËÄÔÂ',
+  'Are you sure you want to delete Invoice Number' => 'ÄúÈ·¶¨ÒªÉ¾³ý·¢Æ±±àºÅ',
+  'Are you sure you want to delete Order Number' => 'ÄúÊÇ·ñ?·¶¨ÒªÉ¾³?¶©µ¥',
+  'Are you sure you want to delete Transaction' => 'ÄúÈ·¶¨ÒªÉ¾³ýÕÊÄ¿',
+  'Assemblies'                  => 'ÉÌÆ·',
+  'Assemblies restocked!'       => '×°ÅäÖØнø»õ!',
+  'Assembly Number missing!'    => '²éÎÞ´ËÉÌÆ·!',
+  'Asset'                       => '×ʲú',
+  'Attachment'                  => '¸½µµ',
+  'Audit Control'               => '»üºË¿ØÖÆ',
+  'Aug'                         => '°ËÔÂ',
+  'August'                      => '°ËÔÂ',
+  'BOM'                         => '²ÄÁÏÕʵ¥',
+  'Backup'                      => '±¸·Ý',
+  'Backup sent to'              => '±¸·Ý¼ÄË͵½',
+  'Balance'                     => '²î¶î',
+  'Balance Sheet'               => '×ʲú¸ºÕ®±í',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Ïä',
+  'Books are open'              => 'Õʲ¾ÒÑ¿ªÆô',
+  'Bought'                      => 'ÒѹºÂò',
+  'Business Number'             => 'ͳһ±àºÅ',
+  'C'                           => 'C',
+  'COGS'                        => '»õÏú³É±¾',
+  'Cannot delete account!'      => 'ÎÞ·¨É¾³ý¿ÆÄ¿!',
+  'Cannot delete customer!'     => '²»ÄÜɾ³ý¿Í»§!',
+  'Cannot delete default account!' => 'ÎÞ·¨É¾³ýÔ¤ÉèÕʺÅ',
+  'Cannot delete invoice!'      => 'ÎÞ·¨É¾³ý·¢Æ±!',
+  'Cannot delete item already invoiced!' => 'ÎÞ·¨É¾³ý±¾Ïî',
+  'Cannot delete item on order!' => 'ÎÞ·¨É¾³ýµ¥ÉϵÄÏîÄ¿!',
+  'Cannot delete item which is part of an assembly!' => 'ÎÞ·¨É¾³ýÓÃì¶ÉÌÆ·ÖеÄÔ­ÁÏ',
+  'Cannot delete item!'         => 'ÎÞ·¨É¾³ýÏîÄ¿!',
+  'Cannot delete order!'        => 'ÎÞ·¨É¾³ý¶©µ¥!',
+  'Cannot delete transaction!'  => 'ÎÞ·¨É¾³ýÕÊÄ¿!',
+  'Cannot delete vendor!'       => '²»ÄÜɾ³ý³§ÉÌ!',
+  'Cannot have a value in both Debit and Credit!' => '²»µÃͬʱÌîÈëÊýֵ춽跽Óë´û·½À¸Î»',
+  'Cannot post a transaction without a value!' => 'ÎÞ·¨È·ÈÏû¼Û¸ñÕÊÄ¿!',
+  'Cannot post invoice for a closed period!' => 'ÎÞ·¨ÔÚÒѹرյÄʱ¶ÎÄÚÈ·ÈÏ·¢Æ±?ë½»Ò!',
+  'Cannot post invoice!'        => 'ÎÞ·¨È·ÈÏ·¢Æ±!',
+  'Cannot post payment for a closed period!' => 'ÎÞ·¨ÔÚÒѹرյÄʱ¶ÎÄÚ¼Ó?ë½»Ò?!',
+  'Cannot post payment!'        => 'ÎÞ·¨´¦Àí¸¶¿î!',
+  'Cannot post transaction for a closed period!' => 'ÎÞ·¨ÔÚÒѹرյÄʱ¶ÎÄÚ¼Ó?ë½»Ò?!',
+  'Cannot post transaction!'    => 'ÎÞ·¨È·ÈÏÕÊÄ¿!',
+  'Cannot process payment for a closed period!' => 'ÒѹرյÄʱ¶ÎÄÚ´¦Àí¸¶¿î!',
+  'Cannot save account!'        => 'ÎÞ·¨´¢´æ¿ÆÄ¿!',
+  'Cannot save order!'          => 'ÎÞ·¨´¢´æÇåµ¥!',
+  'Cannot save preferences!'    => 'ÎÞ·¨´¢´æÉ趨!',
+  'Cannot stock assemblies!'    => 'ÎÞ·¨É¾³ý×°ÅäÉÌÆ·!',
+  'Cash'                        => 'ÏÖ½ð',
+  'Cash based'                  => 'ÏÖ½ð½»Ò×',
+  'Cc'                          => 'Cc',
+  'Change Admin Password'       => '¸ü¸Ä¹ÜÀíÔ±ÃÜÂë',
+  'Change Password'             => '¸ü¸ÄÃÜÂë',
+  'Character Set'               => '×ÖÔª¼¯',
+  'Chart of Accounts'           => '»á¼Æ¿ÆÄ¿±í',
+  'Check'                       => '֧Ʊ',
+  'Check printed!'              => 'ӡˢ֧Ʊ!',
+  'Check printing failed!'      => 'ÎÞ·¨Ó¡Ë¢Ö§Æ±!',
+  'Cleared Balance'             => 'Ö§¸¶²î¶î×ÜÊý',
+  'Click on login name to edit!' => 'Çë°´µÇ?ëÃ?³ÆÒÔ½øÐÐÐÞ¸Ä!',
+  'Close Books up to'           => '¹Ø±Õµ½´ËΪֹµÄÕʲ¾',
+  'Closed'                      => 'ÒѹرÕ',
+  'Company'                     => '¹«Ë¾Ãû³Æ',
+  'Compare to'                  => '¶ÔÕÕ',
+  'Confirm!'                    => 'ÈëÕʳɹ¦!',
+  'Connect to'                  => 'Á¬½áµ½',
+  'Contact'                     => 'Á¬ÂçÈË',
+  'Continue'                    => '¼ÌÐø',
+  'Copies'                      => '¿½±´',
+  'Copy to COA'                 => '¸´ÖƵ½ COA',
+  'Create Chart of Accounts'    => '½¨Á¢ÕÊ»§Í¼±í',
+  'Create Dataset'              => '½¨Á¢×ÊÁϼ¯',
+  'Credit'                      => '´û·½',
+  'Credit Limit'                => 'ÐÅÓöî¶È',
+  'Curr'                        => 'Ŀǰ',
+  'Currency'                    => '±Ò±ð',
+  'Current'                     => 'ÏÖÔÚ',
+  'Customer'                    => '¿Í»§',
+  'Customer deleted!'           => '¿Í»§¼Ç¼ɾ³ý!',
+  'Customer missing!'           => 'δָÃ÷¿Í»§!',
+  'Customer not on file!'       => '¿Í»§¼Ç¼ûÔÚµµ°¸!',
+  'Customer saved!'             => '¿Í»§¼Ç¼±£´æ!',
+  'Customers'                   => '¿Í»§',
+  'DBI not installed!'          => 'δ°²×° DBI Ä£×é!',
+  'Database'                    => '×ÊÁÏ¿â',
+  'Database Administration'     => '×ÊÁÏ¿â¹ÜÀí',
+  'Database Driver not checked!' => 'δѡ¶¨×ÊÁÏ¿â??¶¯³Ìʽ!',
+  'Database Host'               => '×ÊÁÏ¿âÖ÷»ú',
+  'Database User missing!'      => 'δָÃ÷×ÊÁÏ¿âʹÓÃÕß!',
+  'Dataset'                     => '×ÊÁϼ¯',
+  'Dataset missing!'            => 'δָÃ÷×ÊÁϼ¯!',
+  'Dataset updated!'            => '²¹³ä×îÐÂ×ÊÁϼ¯!',
+  'Date'                        => 'ÈÕÆÚ',
+  'Date Due'                    => 'Ó¦¸¶ÈÕÆÚ',
+  'Date Format'                 => 'ÈÕÆÚ¸ñʽ',
+  'Date Paid'                   => '¸¶¿îÈÕÆÚ',
+  'Date missing!'               => 'δָÃ÷ÈÕÆÚ',
+  'Debit'                       => '½è·½',
+  'Debit and credit out of balance!' => '½è´û²»Æ½ºâ!',
+  'Dec'                         => 'Ê®¶þÔÂ',
+  'December'                    => 'Ê®¶þÔÂ',
+  'Decimalplaces'               => 'СÊýµÄÊýÄ¿',
+  'Delete'                      => 'ɾ³ý',
+  'Delete Account'              => 'ɾ³ý¿ÆÄ¿',
+  'Delete Dataset'              => 'ɾ³ý×ÊÁϼ¯',
+  'Delivery Date'               => 'µÝËÍÈÕÆÚ',
+  'Department'                  => '',
+  'Deposit'                     => '´¢´æ',
+  'Description'                 => '˵Ã÷',
+  'Difference'                  => '²îÒì',
+  'Directory'                   => 'Ŀ¼',
+  'Discount'                    => 'ÕÛ¿Û',
+  'Done'                        => 'Íê³É',
+  'Drawing'                     => 'ͼ',
+  'Driver'                      => '??¶¯³Ìʽ',
+  'Dropdown Limit'              => 'ÏÞÖÆ×ÊÁÏÏÔʾ¹¦ÄÜ',
+  'Due'                         => 'µ½ÆÚ',
+  'Due Date'                    => 'µ½ÆÚÈÕ',
+  'Due Date missing!'           => '©Ìîµ½ÆÚÈÕ!',
+  'E-mail'                      => 'µç×ÓÓʼþ',
+  'E-mail Statement to'         => 'µç×ÓÓʼþÕÊÄ¿³ÂÊöµ½',
+  'E-mail address missing!'     => '©Ìîµç×ÓÓʼþλַ!',
+  'Edit'                        => '±à¼­',
+  'Edit Account'                => '±à¼­¿ÆÄ¿',
+  'Edit Accounts Payables Transaction' => '¸ü»»Ó¦¸¶ÕÊ¿îÕÊÄ¿',
+  'Edit Accounts Receivables Transaction' => '¸ü»»Ó¦ÊÕÕÊ¿îÕÊÄ¿',
+  'Edit Assembly'               => '±à¼­ÉÌÆ·',
+  'Edit Customer'               => '±à¼­¿Í»§',
+  'Edit GIFI'                   => '±à¼­ GIFI',
+  'Edit General Ledger Transaction' => '±à¼­×ÜÕÊ',
+  'Edit Part'                   => '±à¼­Ô­ÁÏ',
+  'Edit Preferences for'        => 'É趨ʹÓÃÕß',
+  'Edit Project'                => '¸ü¸Ä¹¤³Ì',
+  'Edit Purchase Invoice'       => '±à¼­²É¹º·¢Æ±',
+  'Edit Purchase Order'         => '±à¼­²É¹ºµ¥',
+  'Edit Sales Invoice'          => '±à¼­Ïú»õ·¢Æ±',
+  'Edit Sales Order'            => '±à¼­Ïú»õµ¥',
+  'Edit Service'                => '±à¼­·þÎñ',
+  'Edit Template'               => '±à¼­Ä£°æ',
+  'Edit User'                   => '±à¼­Ê¹ÓÃÕß',
+  'Edit Vendor'                 => '±à¼­³§ÉÌ',
+  'Employee'                    => 'ְԱ',
+  'Enforce transaction reversal for all dates' => 'Ç¿ÖÆËùÓÐ?ÕÆڵĽ»Ò׻ظ?',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Çë¼ü?ëÒÔðºÅ·Ö¸ôµÄÓ?ÎÄ×Öĸ, Ã¿Ïî²»³¬¹ý??¸ö×Ö (?? CAD:USD:EUR), ×÷ΪÄúµÄ±¾¹ú¼°Íâ¹ú»õ±Ò',
+  'Equity'                      => '¹ÉȨ',
+  'Exch'                        => '»ãÂÊ',
+  'Exchangerate'                => '»ãÂÊ',
+  'Exchangerate Difference'     => '»ãÂʲîÒì',
+  'Exchangerate for payment missing!' => 'δָÃ÷¸¶¿î»ãÂÊ!',
+  'Exchangerate missing!'       => 'δָÃ÷»ãÂÊ!',
+  'Existing Datasets'           => '¼ÈÓеÄ×ÊÁϼ¯',
+  'Expense'                     => '·ÑÓÃ',
+  'Expense Account'             => '·ÑÓÿÆÄ¿',
+  'Expense/Asset'               => '·ÑÓÃ/×ʲú',
+  'Extended'                    => '¼ÆËãÁÐ',
+  'Fax'                         => '´«Õæ',
+  'Feb'                         => '¶þÔÂ',
+  'February'                    => '¶þÔÂ',
+  'Foreign Exchange Gain'       => 'Íâ»ãÊÕÒæ',
+  'Foreign Exchange Loss'       => 'Íâ»ãËðʧ',
+  'From'                        => '´Ó',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI ¼Ç¼ɾ³ý',
+  'GIFI missing!'               => 'δָÃ÷ GIFI!',
+  'GIFI saved!'                 => 'GIFI ¼Ç¼±£´æ',
+  'GL Transaction'              => '×ÜÕÊ',
+  'General Ledger'              => '×ÜÕÊ',
+  'Goods & Services'            => '',
+  'HTML Templates'              => 'HTML ±íµ¥',
+  'Heading'                     => '±íÍ·',
+  'Host'                        => 'Ö÷»ú',
+  'Hostname missing!'           => 'δָÃ÷Ö÷»úÃû³Æ!',
+  'ID'                          => '±àºÅ',
+  'Image'                       => 'ͼÏó',
+  'In-line'                     => 'ÐÐÄÚ',
+  'Include in Report'           => 'Ò»²¢ÏÔʾ',
+  'Include in drop-down menus'  => '°üº¬ÔÚÏÂÀ­Ê½Ñ¡µ¥ÖÐ',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Òª½«Õâ¸ö¿Í»§/³§É̼ÓÈëÓ¦¼ÓË°Çåµ¥?',
+  'Income'                      => 'ÊÕÒæ',
+  'Income Account'              => 'ËðÒæ¿ÆÄ¿',
+  'Income Statement'            => 'ËðÒæ±í',
+  'Incorrect Dataset version!'  => '×ÊÁϼ¯°æ±¾´íÎó!',
+  'Incorrect Password!'         => 'ÃÜÂë´íÎó!',
+  'Individual Items'            => '×é³ÉÏîÄ¿',
+  'Inventory'                   => '¿â´æ',
+  'Inventory Account'           => '´æ»õ¿ÆÄ¿',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'ÔÚÍ£ÓôËÏî×éºÏƷ֮ǰ, ´æ»õÊýÁ¿±ØÐèΪÁã!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Í£ÓôËÏîÁã¼þ֮ǰ, ´æ»õÊýÁ¿±ØÐèΪÁã!',
+  'Inventory quantity must be zero!' => '´æ»õÊýÁ¿±ØÐèΪÁã!',
+  'Invoice'                     => '·¢Æ±',
+  'Invoice Date'                => '·¢Æ±ÈÕÆÚ',
+  'Invoice Date missing!'       => '·¢Æ±ÈÕÆÚ´íÎó!',
+  'Invoice Number'              => '·¢Æ±±àºÅ',
+  'Invoice Number missing!'     => '·¢Æ±±àºÅ´íÎó!',
+  'Invoice deleted!'            => '·¢Æ±É¾³ý!',
+  'Invoice posted!'             => '·¢Æ±È·ÈÏ!',
+  'Invoices'                    => '·¢Æ±',
+  'Is this a summary account to record' => '´ËΪ×ܽá¿ÆÄ¿Âð?',
+  'Item deleted!'               => 'ÏîĿɾ³ý!',
+  'Item not on file!'           => '²éÎÞ´ËÏîÄ¿',
+  'Jan'                         => 'Ò»ÔÂ',
+  'January'                     => 'Ò»ÔÂ',
+  'Jul'                         => 'ÆßÔÂ',
+  'July'                        => 'ÆßÔÂ',
+  'Jun'                         => 'ÁùÔÂ',
+  'June'                        => 'ÁùÔÂ',
+  'LaTeX Templates'             => 'LaTex Ä£°æ',
+  'Language'                    => 'Óïϵ',
+  'Last Cost'                   => 'ÉÏÒ»±Ê³É±¾',
+  'Last Invoice Number'         => 'ÉÏÒ»±Ê·¢Æ±±àºÅ',
+  'Last Numbers & Default Accounts' => 'ÉÏÒ»±Ê±àºÅ¼°Ô¤Éè¿ÆÄ¿',
+  'Last Purchase Order Number'  => 'Ç°´Î²É¹ºµ¥ºÅ',
+  'Last Sales Order Number'     => 'Ç°´ÎÏú',
+  'Leave host and port field empty unless you want to make a remote connection.' => '³ý·ÇÄúÏëÒª½øÐÐÔ¶¶ËÁ¬Ïß, ·ñÔòÇ뽫Ö÷»ú¼°²ººÅÁô°×.',
+  'Liability'                   => '¸ºÕ®',
+  'Licensed to'                 => 'ÊÚȨÓè',
+  'Line Total'                  => '×ÜÁÐÊý',
+  'Link'                        => 'Á¬½á',
+  'Link Accounts'               => 'Á¬½á¿ÆÄ¿',
+  'List Accounts'               => 'ÁгöÕʺÅ',
+  'List GIFI'                   => 'Áгö GIFI',
+  'List Price'                  => '',
+  'List Transactions'           => 'ÁгöÕÊÄ¿',
+  'Login'                       => 'µÇ??',
+  'Logout'                      => 'µÇ³ö',
+  'Make'                        => 'ÖÆÔì',
+  'Mar'                         => 'ÈýÔÂ',
+  'March'                       => 'ÈýÔÂ',
+  'May'                         => 'ÎåÔÂ',
+  'May '                        => 'ÎåÔÂ',
+  'Message'                     => 'ѶϢ',
+  'Microfiche'                  => 'Ëõ΢½ºÆ¬',
+  'Model'                       => 'ÐͺÅ',
+  'Multibyte Encoding'          => '',
+  'N/A'                         => '²»ÊÊÓÃ',
+  'Name'                        => 'Ãû³Æ',
+  'Name missing!'               => 'ȱÉÙÃû³Æ!',
+  'New Templates'               => 'ÐÂÔöÄ£°æ',
+  'No'                          => '·ñ',
+  'No Database Drivers available!' => 'ûÓпÉÓõÄ??¶¯³Ìʽ!',
+  'No Dataset selected!'        => 'δѡ¶¨×ÊÁϼ¯!',
+  'No email address for'        => 'δָÃ÷µç×ÓÓʼþλÖÃ',
+  'No.'                         => '±àºÅ',
+  'Notes'                       => '±¸×¢',
+  'Nothing applied!'            => 'δָÃ÷Ö§¸¶×ܶî!',
+  'Nothing selected!'           => 'δѡ¶¨×Ê!',
+  'Nothing to delete!'          => 'ûÓпÉɾ³ýµÄÏîÄ¿',
+  'Nov'                         => 'ʮһÔÂ',
+  'November'                    => 'ʮһÔÂ',
+  'Number'                      => '±àºÅ',
+  'Number Format'               => 'Êý×Ö¸ñʽ',
+  'Number missing in Row'       => 'δָÃ÷ºÅÂë',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Í£ÓÃ',
+  'Oct'                         => 'Ê®ÔÂ',
+  'October'                     => 'Ê®ÔÂ',
+  'On Hand'                     => '´æÁ¿',
+  'On Order'                    => 'ÒÑϵ¥¶©¹º',
+  'Open'                        => '¿ªÆô',
+  'Oracle Database Administration' => 'Oracle ×ÊÁÏ¿â¹ÜÀí',
+  'Order'                       => '¶©µ¥',
+  'Order Date'                  => 'ϵ¥?ÕÆ?',
+  'Order Date missing!'         => 'δָÃ÷ϵ¥?ÕÆ?!',
+  'Order Entry'                 => 'ϵ¥ÏîÄ¿',
+  'Order Number'                => '¶©µ¥±àºÅ',
+  'Order Number missing!'       => 'δָÃ÷¶©µ¥±àºÅ!',
+  'Order deleted!'              => 'ɾ³ý¶©µ¥!',
+  'Order saved!'                => '´¢´æ¶©µ¥!',
+  'Ordered'                     => 'ÒÑ϶©¹º',
+  'Orphaned'                    => 'ÎÞÖ÷',
+  'Out of balance!'             => '³öÓÚ²î¶î!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => '³ö»õµ¥',
+  'Packing List Date missing!'  => 'δָÃ÷°ü×°Çåµ¥?ÕÆ?!',
+  'Packing List Number missing!' => 'δָÃ÷°ü×°Çåµ¥±àºÅ!',
+  'Paid'                        => 'ÒѸ¶',
+  'Paid in full'                => 'Ö§¸¶È«²¿×ܶî',
+  'Part'                        => 'Ô­ÁÏ',
+  'Part Number missing!'        => '©ÌîÔ­ÁϱàºÅ!',
+  'Parts'                       => 'Ô­ÁÏ',
+  'Parts Inventory'             => '¿â´æÔ­ÁÏ',
+  'Password'                    => 'ÃÜÂë',
+  'Password changed!'           => 'ÃÜÂëÒѾ­¸ü¸Ä',
+  'Payables'                    => 'Ó¦¸¶¿ÆÄ¿',
+  'Payment'                     => '¸¶¿î·½Ê½',
+  'Payment date missing!'       => 'δָÃ÷¸¶¿î?ÕÆ?!',
+  'Payment posted!'             => '',
+  'Payments'                    => '¸¶¿î',
+  'Pg Database Administration'  => 'Pg ×ÊÁÏ¿â¹ÜÀí',
+  'Phone'                       => 'µç»°ºÅÂë',
+  'Port'                        => '²ººÅ',
+  'Port missing!'               => 'δָÃ÷²ººÅ!',
+  'Post'                        => 'È·ÈÏ',
+  'Post as new'                 => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => '¸öÈËÉ趨',
+  'Preferences saved!'          => '¸öÈËÉ趨ÒÑ´¢´æ!',
+  'Price'                       => '¼Û¸ñ',
+  'Print'                       => 'ӡˢ',
+  'Printer'                     => 'Ó¡±í»ú',
+  'Project'                     => '¹¤³Ì',
+  'Project Number'              => '',
+  'Project Number missing!'     => 'δָÃ÷¹¤³ÌºÅÂë!',
+  'Project deleted!'            => '¹¤³ÌÒÔ±»É¾³ý!',
+  'Project not on file!'        => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Project saved!'              => '¹¤³ÌÒÔ±»´¢´æ!',
+  'Projects'                    => '¹¤³Ì',
+  'Purchase Invoice'            => '²É¹º·¢Æ±',
+  'Purchase Order'              => '²É¹ºµ¥',
+  'Purchase Orders'             => '²É¹ºµ¥',
+  'Qty'                         => 'ÊýÁ¿',
+  'ROP'                         => 'ÔÙ¶©µã',
+  'Rate'                        => 'Ë°ÂÊ',
+  'Recd'                        => 'Recd',
+  'Receipt'                     => 'ÊÕ¾Ý',
+  'Receipt printed!'            => '',
+  'Receipt printing failed!'    => '',
+  'Receipts'                    => 'ÊÕ¾Ý',
+  'Receivables'                 => 'Ó¦ÊÕ¿ÆÄ¿',
+  'Reconciliation'              => 'µ÷Í£',
+  'Record in'                   => '¼Ç¼ì¶',
+  'Reference'                   => '²Î¿¼ºÅÂë',
+  'Reference missing!'          => 'δָÃ÷²Î¿¼ºÅÂë!',
+  'Remaining'                   => 'ÉÐâÅ',
+  'Report for'                  => '±¨±íÀ´Ô´',
+  'Reports'                     => '±¨±í',
+  'Required by'                 => '×ÓÏîÄ¿',
+  'Retained Earnings'           => '±£ÁôÓ¯âÅ',
+  'Sales'                       => 'ÒµÎñ',
+  'Sales Invoice'               => 'Ïú»õ·¢Æ±',
+  'Sales Order'                 => 'Ïú»õµ¥',
+  'Sales Orders'                => 'Ïú»õµ¥',
+  'Save'                        => '´¢´æ',
+  'Save as new'                 => '´¢´æ',
+  'Save to File'                => '´¢´æÖÁµµ°¸',
+  'Screen'                      => 'өĻ',
+  'Select a Dataset to delete and press "Continue"' => 'ÇëÑ¡ÔñÓûɾ³ýµÄ×ÊÁϼ¯, ÔÙ°´ "¼ÌÐø"',
+  'Select all'                  => 'Ñ¡ÔñÈ«²¿',
+  'Select from one of the items below' => 'ì¶ÏÂÁÐÏîÄ¿ÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the names below' => 'ì¶ÏÂÁÐÃû×ÖÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the projects below' => 'ì¶ÏÂÁй¤³ÌÖÐÑ¡ÔñÒ»Ïî',
+  'Select postscript or PDF!'   => 'Ñ¡Ôñ postscript »ò PDF!',
+  'Sell Price'                  => 'ÊÛ¼Û',
+  'Send by E-Mail'              => 'ÒÔµç×ÓÓʼþ¼ÄËÍ',
+  'Sep'                         => '¾ÅÔÂ',
+  'September'                   => '¾ÅÔÂ',
+  'Service'                     => '·þÎñ',
+  'Service Items'               => '·þÎñÏîÄ¿',
+  'Service Number missing!'     => '©Ìî·þÎñ±àºÅ!',
+  'Services'                    => '·þÎñ',
+  'Setup Templates'             => 'É趨ģ°æ',
+  'Ship'                        => 'º½ÔË',
+  'Ship to'                     => 'ÏúÊÛ´ú±í',
+  'Ship via'                    => 'º½ÔË·½·¨',
+  'Short'                       => '¶Ì',
+  'Signature'                   => 'Ç©Ãû',
+  'Sold'                        => 'ÒÑÂô³ö',
+  'Source'                      => 'À´Ô´',
+  'Standard'                    => '±ê×¼',
+  'Statement'                   => 'ÕÊÄ¿³ÂÊö',
+  'Statement Balance'           => 'ÕÊÄ¿³ÂÊö²î¶î',
+  'Statement sent to'           => 'ÕÊÄ¿³ÂÊöË͵½',
+  'Statements sent to printer!' => 'ÕÊÄ¿³ÂÊöË͵½Ó¡±í»ú!',
+  'Stock Assembly'              => 'Å̵ã',
+  'Stylesheet'                  => 'Ñùʽ±í',
+  'Subject'                     => '±êÌâ',
+  'Subtotal'                    => 'С¼Æ',
+  'System'                      => 'ϵͳ',
+  'Tax'                         => 'Ë°½ð',
+  'Tax Accounts'                => 'Ë°½ð¿ÆÄ¿',
+  'Tax Included'                => '²»ÊÕ·þÎñ·Ñ',
+  'Tax collected'               => 'ÊÕµ½µÄË°',
+  'Tax paid'                    => 'Ö§¸¶µÄË°',
+  'Taxable'                     => 'Ӧ˰',
+  'Template saved!'             => 'Ä£°æÒÑ´¢´æ',
+  'Templates'                   => 'Ä£°æ',
+  'Terms: Net'                  => 'ƱÆÚ¾»¼Æ',
+  'The following Datasets are not in use and can be deleted' => 'ÏÂÁÐ×ÊÁϼ¯²¢Î´Ê¹ÓÃ, ¿ÉÒÔɾ³ý',
+  'The following Datasets need to be updated' => 'ÏÂÁÐ×ÊÁϼ¯ÐèÒª¸üÐÂ',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'ÕâÊǶԼȴæ×ÊÁÏÀ´Ô´µÄ³õ²½¼ì²é. Ôڴ˽׶Î, ²»»áɾ³ý»òÐÂÔö?κÎ×ÊÁ?!',
+  'To'                          => 'ÖÁ',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => '?ôÒªÐÂÔöȺ×éÄÚµÄʹÓÃÕ?, Çë±à¼­Ãû³Æ, ¸ü¸ÄµÇ?ëÃ?, ?»ºó´¢´?.  ÕâÑùÒ»À´, ÐÂʹÓÃÕ߻ᱣÁôÏàͬµÄ±äÊý, ²¢ÒÔеĵÇ?ëÃ?´æ??.',
+  'Top Level'                   => '×î¸ßµÈ¼¶',
+  'Total'                       => '×ܼÆ',
+  'Transaction Date missing!'   => '©ÌîÕÊÄ¿ÈÕÆÚ!',
+  'Transaction deleted!'        => 'ÕÊĿɾ³ý!',
+  'Transaction posted!'         => 'ÕÊÄ¿È·ÈÏ!',
+  'Transaction reversal enforced for all dates' => 'Ç¿Öƻظ´ËùÓÐ?ÕÆڵĽ»Ò?',
+  'Transaction reversal enforced up to' => 'Ç¿Öƻظ´½»Ò×Ö±µ½',
+  'Transactions'                => 'ÕÊÄ¿',
+  'Transactions exist, cannot delete customer!' => '´Ë¿Í»§ÒÑÓÐÕÊÄ¿, ²»ÄÜɾ³ý!',
+  'Transactions exist, cannot delete vendor!' => '´Ë³§ÉÌÒÑÓÐÕÊÄ¿, ²»ÄÜɾ³ý!',
+  'Transactions exist; cannot delete account!' => 'ÉÐÓн»Ò×´æÔÚ; ÎÞ·¨É¾³ýÕÊ»§!',
+  'Trial Balance'               => 'ÊÔËã±í',
+  'Unit'                        => 'µ¥Î»',
+  'Unit of measure'             => '¶ÈÁ¿µ¥Î»',
+  'Update'                      => '¸üÐÂ',
+  'Update Dataset'              => '¸üÐÂ×ÊÁϼ¯',
+  'Updated'                     => 'ÒѸüÐÂ',
+  'Use Templates'               => 'ʹÓÃÄ£°æ',
+  'User'                        => 'ʹÓÃÕß',
+  'User deleted!'               => 'ʹÓÃÕßÒÔ±»É¾³ý!',
+  'User saved!'                 => 'ʹÓÃÕßÒÔ±»´¢´æ!',
+  'Vendor'                      => '³§ÉÌ',
+  'Vendor deleted!'             => '³§ÉÌɾ³ý!',
+  'Vendor missing!'             => 'δָÃ÷³§ÉÌ!',
+  'Vendor not on file!'         => '´Ë³§ÉÌδÔÚµµ°¸!',
+  'Vendor saved!'               => '³§É̱£´æ!',
+  'Vendors'                     => '³§ÉÌ',
+  'Version'                     => '°æ±¾',
+  'Weight'                      => 'ÖØÁ¿',
+  'Weight Unit'                 => 'ÖØÁ¿µ¥Î»',
+  'What type of item is this?'  => '´ËÏîÄ¿µÄÐÍ̬?',
+  'Year End'                    => '»á¼ÆÄê¶È',
+  'Yes'                         => 'ÊÇ',
+  'You are logged out!'         => 'ÄãÒԵdzö!',
+  'You did not enter a name!'   => 'Äú²¢Î´¼ü?ëÃ?³Æ!',
+  'You must enter a host and port for local and remote connections!' => 'Äú±ØÐè¼ü?ëÖ÷»?¼°²ººÅ, ÒÔ½øÐб¾»ú»òÔ¶¶ËÁ¬Ïß!',
+  'as at'                       => '¸ù¾Ý',
+  'collected on sales'          => 'ÔÚÏú»õʱ½áÇå',
+  'days'                        => 'ÈÕ',
+  'does not exist'              => '²»´æÔÚ',
+  'ea'                          => '',
+  'emailed to'                  => 'ÒѼÄÖÁ',
+  'for Period'                  => 'ÆÚ¼ä',
+  'hr'                          => 'hr',
+  'is already a member!'        => 'ÒѾ­ÊdzÉÔ±ÁË!',
+  'is not a member!'            => '²¢²»ÊdzÉÔ±!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => '',
+  'paid on purchases'           => 'ÔڲɹºÊ±½áÇå',
+  'sent to printer'             => 'ËÍÖÁÓ¡±í»ú',
+  'successfully created!'       => '³É¹¦½¨Á¢!',
+  'successfully deleted!'       => '³É¹¦É¾³ý!',
+  'to'                          => 'ÖÁ',
+  'website'                     => 'ÍøÕ¾',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/am b/sql-ledger/locale/cn/am
new file mode 100644 (file)
index 0000000..610d7dd
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Ó¦¸¶ÕÊ¿î',
+  'AR'                          => 'Ó¦ÊÕÕÊ¿î',
+  'Account'                     => '¿ÆÄ¿',
+  'Account Number'              => '¿ÆÄ¿±àºÅ',
+  'Account Number missing!'     => '©Ìî¿ÆÄ¿±àºÅ!',
+  'Account Type'                => '¿ÆÄ¿Àà±ð',
+  'Account Type missing!'       => '©Ìî¿ÆÄ¿Àà±ð!',
+  'Account deleted!'            => '¿ÆÄ¿ÒÔ±»É¾³ý!',
+  'Account saved!'              => '¿ÆÄ¿ÒÔ±»´¢´æ!',
+  'Add Account'                 => 'ÐÂÔö¿ÆÄ¿',
+  'Add GIFI'                    => 'ÐÂÔö GIFI',
+  'Address'                     => 'µØÖ·',
+  'Asset'                       => '×ʲú',
+  'Audit Control'               => '»üºË¿ØÖÆ',
+  'Backup sent to'              => '±¸·Ý¼ÄË͵½',
+  'Books are open'              => 'Õʲ¾ÒÑ¿ªÆô',
+  'Business Number'             => 'ͳһ±àºÅ',
+  'COGS'                        => '»õÏú³É±¾',
+  'Cannot delete account!'      => 'ÎÞ·¨É¾³ý¿ÆÄ¿!',
+  'Cannot delete default account!' => 'ÎÞ·¨É¾³ýÔ¤ÉèÕʺÅ',
+  'Cannot save account!'        => 'ÎÞ·¨´¢´æ¿ÆÄ¿!',
+  'Cannot save preferences!'    => 'ÎÞ·¨´¢´æÉ趨!',
+  'Character Set'               => '×ÖÔª¼¯',
+  'Chart of Accounts'           => '»á¼Æ¿ÆÄ¿±í',
+  'Close Books up to'           => '¹Ø±Õµ½´ËΪֹµÄÕʲ¾',
+  'Company'                     => '¹«Ë¾Ãû³Æ',
+  'Continue'                    => '¼ÌÐø',
+  'Copy to COA'                 => '¸´ÖƵ½ COA',
+  'Credit'                      => '´û·½',
+  'Date Format'                 => 'ÈÕÆÚ¸ñʽ',
+  'Debit'                       => '½è·½',
+  'Delete'                      => 'ɾ³ý',
+  'Delete Account'              => 'ɾ³ý¿ÆÄ¿',
+  'Description'                 => '˵Ã÷',
+  'Dropdown Limit'              => 'ÏÞÖÆ×ÊÁÏÏÔʾ¹¦ÄÜ',
+  'E-mail'                      => 'µç×ÓÓʼþ',
+  'Edit'                        => '±à¼­',
+  'Edit Account'                => '±à¼­¿ÆÄ¿',
+  'Edit GIFI'                   => '±à¼­ GIFI',
+  'Edit Preferences for'        => 'É趨ʹÓÃÕß',
+  'Edit Template'               => '±à¼­Ä£°æ',
+  'Enforce transaction reversal for all dates' => 'Ç¿ÖÆËùÓÐ?ÕÆڵĽ»Ò׻ظ?',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Çë¼ü?ëÒÔðºÅ·Ö¸ôµÄÓ?ÎÄ×Öĸ, Ã¿Ïî²»³¬¹ý??¸ö×Ö (?? CAD:USD:EUR), ×÷ΪÄúµÄ±¾¹ú¼°Íâ¹ú»õ±Ò',
+  'Equity'                      => '¹ÉȨ',
+  'Expense'                     => '·ÑÓÃ',
+  'Expense Account'             => '·ÑÓÿÆÄ¿',
+  'Expense/Asset'               => '·ÑÓÃ/×ʲú',
+  'Fax'                         => '´«Õæ',
+  'Foreign Exchange Gain'       => 'Íâ»ãÊÕÒæ',
+  'Foreign Exchange Loss'       => 'Íâ»ãËðʧ',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI ¼Ç¼ɾ³ý',
+  'GIFI missing!'               => 'δָÃ÷ GIFI!',
+  'GIFI saved!'                 => 'GIFI ¼Ç¼±£´æ',
+  'Heading'                     => '±íÍ·',
+  'Include in drop-down menus'  => '°üº¬ÔÚÏÂÀ­Ê½Ñ¡µ¥ÖÐ',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Òª½«Õâ¸ö¿Í»§/³§É̼ÓÈëÓ¦¼ÓË°Çåµ¥?',
+  'Income'                      => 'ÊÕÒæ',
+  'Income Account'              => 'ËðÒæ¿ÆÄ¿',
+  'Inventory'                   => '¿â´æ',
+  'Inventory Account'           => '´æ»õ¿ÆÄ¿',
+  'Is this a summary account to record' => '´ËΪ×ܽá¿ÆÄ¿Âð?',
+  'Language'                    => 'Óïϵ',
+  'Last Invoice Number'         => 'ÉÏÒ»±Ê·¢Æ±±àºÅ',
+  'Last Numbers & Default Accounts' => 'ÉÏÒ»±Ê±àºÅ¼°Ô¤Éè¿ÆÄ¿',
+  'Last Purchase Order Number'  => 'Ç°´Î²É¹ºµ¥ºÅ',
+  'Last Sales Order Number'     => 'Ç°´ÎÏú',
+  'Liability'                   => '¸ºÕ®',
+  'Link'                        => 'Á¬½á',
+  'Name'                        => 'Ãû³Æ',
+  'No'                          => '·ñ',
+  'No email address for'        => 'δָÃ÷µç×ÓÓʼþλÖÃ',
+  'Number'                      => '±àºÅ',
+  'Number Format'               => 'Êý×Ö¸ñʽ',
+  'Parts Inventory'             => '¿â´æÔ­ÁÏ',
+  'Password'                    => 'ÃÜÂë',
+  'Payables'                    => 'Ó¦¸¶¿ÆÄ¿',
+  'Payment'                     => '¸¶¿î·½Ê½',
+  'Phone'                       => 'µç»°ºÅÂë',
+  'Preferences saved!'          => '¸öÈËÉ趨ÒÑ´¢´æ!',
+  'Rate'                        => 'Ë°ÂÊ',
+  'Receivables'                 => 'Ó¦ÊÕ¿ÆÄ¿',
+  'Sales'                       => 'ÒµÎñ',
+  'Save'                        => '´¢´æ',
+  'Service Items'               => '·þÎñÏîÄ¿',
+  'Ship via'                    => 'º½ÔË·½·¨',
+  'Signature'                   => 'Ç©Ãû',
+  'Stylesheet'                  => 'Ñùʽ±í',
+  'Tax'                         => 'Ë°½ð',
+  'Tax Accounts'                => 'Ë°½ð¿ÆÄ¿',
+  'Template saved!'             => 'Ä£°æÒÑ´¢´æ',
+  'Transaction reversal enforced for all dates' => 'Ç¿Öƻظ´ËùÓÐ?ÕÆڵĽ»Ò?',
+  'Transaction reversal enforced up to' => 'Ç¿Öƻظ´½»Ò×Ö±µ½',
+  'Transactions exist; cannot delete account!' => 'ÉÐÓн»Ò×´æÔÚ; ÎÞ·¨É¾³ýÕÊ»§!',
+  'Weight Unit'                 => 'ÖØÁ¿µ¥Î»',
+  'Year End'                    => '»á¼ÆÄê¶È',
+  'Yes'                         => 'ÊÇ',
+  'does not exist'              => '²»´æÔÚ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'ÐÂÔö¿ÆÄ¿'                    => 'add_account',
+  '¼ÌÐø'                        => 'continue',
+  '¸´ÖƵ½_coa'                  => 'copy_to_coa',
+  'ɾ³ý'                        => 'delete',
+  '±à¼­'                        => 'edit',
+  '±à¼­¿ÆÄ¿'                    => 'edit_account',
+  '´¢´æ'                        => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/ap b/sql-ledger/locale/cn/ap
new file mode 100644 (file)
index 0000000..03dc72c
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Ó¦¸¶ÕÊÄ¿',
+  'AP Transactions'             => 'Ó¦¸¶ÕÊÄ¿',
+  'Account'                     => '¿ÆÄ¿',
+  'Add Accounts Payables Transaction' => 'ÐÂÔöÓ¦¸¶ÕÊÄ¿',
+  'Address'                     => 'µØÖ·',
+  'Amount'                      => '×ܼÆ',
+  'Amount Due'                  => 'µ½ÆÚµÄ×ܼÆ',
+  'Apr'                         => 'ËÄÔÂ',
+  'April'                       => 'ËÄÔÂ',
+  'Are you sure you want to delete Transaction' => 'ÄúÈ·¶¨ÒªÉ¾³ýÕÊÄ¿',
+  'Aug'                         => '°ËÔÂ',
+  'August'                      => '°ËÔÂ',
+  'Cannot delete transaction!'  => 'ÎÞ·¨É¾³ýÕÊÄ¿!',
+  'Cannot post payment for a closed period!' => 'ÎÞ·¨ÔÚÒѹرյÄʱ¶ÎÄÚ¼Ó?ë½»Ò?!',
+  'Cannot post transaction for a closed period!' => 'ÎÞ·¨ÔÚÒѹرյÄʱ¶ÎÄÚ¼Ó?ë½»Ò?!',
+  'Cannot post transaction!'    => 'ÎÞ·¨È·ÈÏÕÊÄ¿!',
+  'Closed'                      => 'ÒѹرÕ',
+  'Confirm!'                    => 'ÈëÕʳɹ¦!',
+  'Continue'                    => '¼ÌÐø',
+  'Currency'                    => '±Ò±ð',
+  'Customer not on file!'       => '¿Í»§¼Ç¼ûÔÚµµ°¸!',
+  'Date'                        => 'ÈÕÆÚ',
+  'Date Paid'                   => '¸¶¿îÈÕÆÚ',
+  'Dec'                         => 'Ê®¶þÔÂ',
+  'December'                    => 'Ê®¶þÔÂ',
+  'Delete'                      => 'ɾ³ý',
+  'Description'                 => '˵Ã÷',
+  'Due Date'                    => 'µ½ÆÚÈÕ',
+  'Due Date missing!'           => '©Ìîµ½ÆÚÈÕ!',
+  'Edit Accounts Payables Transaction' => '¸ü»»Ó¦¸¶ÕÊ¿îÕÊÄ¿',
+  'Employee'                    => 'ְԱ',
+  'Exch'                        => '»ãÂÊ',
+  'Exchangerate'                => '»ãÂÊ',
+  'Exchangerate for payment missing!' => 'δָÃ÷¸¶¿î»ãÂÊ!',
+  'Exchangerate missing!'       => 'δָÃ÷»ãÂÊ!',
+  'Feb'                         => '¶þÔÂ',
+  'February'                    => '¶þÔÂ',
+  'From'                        => '´Ó',
+  'ID'                          => '±àºÅ',
+  'Include in Report'           => 'Ò»²¢ÏÔʾ',
+  'Invoice'                     => '·¢Æ±',
+  'Invoice Date'                => '·¢Æ±ÈÕÆÚ',
+  'Invoice Date missing!'       => '·¢Æ±ÈÕÆÚ´íÎó!',
+  'Invoice Number'              => '·¢Æ±±àºÅ',
+  'Invoice Number missing!'     => '·¢Æ±±àºÅ´íÎó!',
+  'Jan'                         => 'Ò»ÔÂ',
+  'January'                     => 'Ò»ÔÂ',
+  'Jul'                         => 'ÆßÔÂ',
+  'July'                        => 'ÆßÔÂ',
+  'Jun'                         => 'ÁùÔÂ',
+  'June'                        => 'ÁùÔÂ',
+  'Mar'                         => 'ÈýÔÂ',
+  'March'                       => 'ÈýÔÂ',
+  'May'                         => 'ÎåÔÂ',
+  'May '                        => 'ÎåÔÂ',
+  'Notes'                       => '±¸×¢',
+  'Nov'                         => 'ʮһÔÂ',
+  'November'                    => 'ʮһÔÂ',
+  'Number'                      => '±àºÅ',
+  'Oct'                         => 'Ê®ÔÂ',
+  'October'                     => 'Ê®ÔÂ',
+  'Open'                        => '¿ªÆô',
+  'Order'                       => '¶©µ¥',
+  'Order Number'                => '¶©µ¥±àºÅ',
+  'Paid'                        => 'ÒѸ¶',
+  'Payment date missing!'       => 'δָÃ÷¸¶¿î?ÕÆ?!',
+  'Payments'                    => '¸¶¿î',
+  'Post'                        => 'È·ÈÏ',
+  'Post as new'                 => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Project'                     => '¹¤³Ì',
+  'Project not on file!'        => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Purchase Invoice'            => '²É¹º·¢Æ±',
+  'Select from one of the names below' => 'ì¶ÏÂÁÐÃû×ÖÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the projects below' => 'ì¶ÏÂÁй¤³ÌÖÐÑ¡ÔñÒ»Ïî',
+  'Sep'                         => '¾ÅÔÂ',
+  'September'                   => '¾ÅÔÂ',
+  'Source'                      => 'À´Ô´',
+  'Subtotal'                    => 'С¼Æ',
+  'Tax'                         => 'Ë°½ð',
+  'Tax Included'                => '²»ÊÕ·þÎñ·Ñ',
+  'Total'                       => '×ܼÆ',
+  'Transaction deleted!'        => 'ÕÊĿɾ³ý!',
+  'Transaction posted!'         => 'ÕÊÄ¿È·ÈÏ!',
+  'Update'                      => '¸üÐÂ',
+  'Vendor'                      => '³§ÉÌ',
+  'Vendor missing!'             => 'δָÃ÷³§ÉÌ!',
+  'Vendor not on file!'         => '´Ë³§ÉÌδÔÚµµ°¸!',
+  'Yes'                         => 'ÊÇ',
+  'to'                          => 'ÖÁ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'Ó¦¸¶ÕÊÄ¿'                    => 'ap_transaction',
+  'ÐÂÔöÓ¦¸¶ÕÊÄ¿'                => 'add_accounts_payables_transaction',
+  '¼ÌÐø'                        => 'continue',
+  'ɾ³ý'                        => 'delete',
+  '¸ü»»Ó¦¸¶ÕÊ¿îÕÊÄ¿'            => 'edit_accounts_payables_transaction',
+  'È·ÈÏ'                        => 'post',
+  'È·ÈϳÉΪÐÂÕÊÄ¿'              => 'post_as_new',
+  '²É¹º·¢Æ±'                    => 'purchase_invoice',
+  '¸üÐÂ'                        => 'update',
+  'ÊÇ'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/ar b/sql-ledger/locale/cn/ar
new file mode 100644 (file)
index 0000000..f6fb3ff
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'Ó¦ÊÕÕÊÄ¿',
+  'AR Transactions'             => 'Ó¦ÊÕÕÊÄ¿',
+  'Account'                     => '¿ÆÄ¿',
+  'Add Accounts Receivables Transaction' => 'ÐÂÔöÓ¦ÊÕÕÊÄ¿',
+  'Address'                     => 'µØÖ·',
+  'Amount'                      => '×ܼÆ',
+  'Amount Due'                  => 'µ½ÆÚµÄ×ܼÆ',
+  'Apr'                         => 'ËÄÔÂ',
+  'April'                       => 'ËÄÔÂ',
+  'Are you sure you want to delete Transaction' => 'ÄúÈ·¶¨ÒªÉ¾³ýÕÊÄ¿',
+  'Aug'                         => '°ËÔÂ',
+  'August'                      => '°ËÔÂ',
+  'Cannot delete transaction!'  => 'ÎÞ·¨É¾³ýÕÊÄ¿!',
+  'Cannot post payment for a closed period!' => 'ÎÞ·¨ÔÚÒѹرյÄʱ¶ÎÄÚ¼Ó?ë½»Ò?!',
+  'Cannot post transaction for a closed period!' => 'ÎÞ·¨ÔÚÒѹرյÄʱ¶ÎÄÚ¼Ó?ë½»Ò?!',
+  'Cannot post transaction!'    => 'ÎÞ·¨È·ÈÏÕÊÄ¿!',
+  'Closed'                      => 'ÒѹرÕ',
+  'Confirm!'                    => 'ÈëÕʳɹ¦!',
+  'Continue'                    => '¼ÌÐø',
+  'Credit Limit'                => 'ÐÅÓöî¶È',
+  'Currency'                    => '±Ò±ð',
+  'Customer'                    => '¿Í»§',
+  'Customer missing!'           => 'δָÃ÷¿Í»§!',
+  'Customer not on file!'       => '¿Í»§¼Ç¼ûÔÚµµ°¸!',
+  'Date'                        => 'ÈÕÆÚ',
+  'Date Paid'                   => '¸¶¿îÈÕÆÚ',
+  'Dec'                         => 'Ê®¶þÔÂ',
+  'December'                    => 'Ê®¶þÔÂ',
+  'Delete'                      => 'ɾ³ý',
+  'Description'                 => '˵Ã÷',
+  'Due Date'                    => 'µ½ÆÚÈÕ',
+  'Due Date missing!'           => '©Ìîµ½ÆÚÈÕ!',
+  'Edit Accounts Receivables Transaction' => '¸ü»»Ó¦ÊÕÕÊ¿îÕÊÄ¿',
+  'Employee'                    => 'ְԱ',
+  'Exch'                        => '»ãÂÊ',
+  'Exchangerate'                => '»ãÂÊ',
+  'Exchangerate for payment missing!' => 'δָÃ÷¸¶¿î»ãÂÊ!',
+  'Exchangerate missing!'       => 'δָÃ÷»ãÂÊ!',
+  'Feb'                         => '¶þÔÂ',
+  'February'                    => '¶þÔÂ',
+  'From'                        => '´Ó',
+  'ID'                          => '±àºÅ',
+  'Include in Report'           => 'Ò»²¢ÏÔʾ',
+  'Invoice'                     => '·¢Æ±',
+  'Invoice Date'                => '·¢Æ±ÈÕÆÚ',
+  'Invoice Date missing!'       => '·¢Æ±ÈÕÆÚ´íÎó!',
+  'Invoice Number'              => '·¢Æ±±àºÅ',
+  'Invoice Number missing!'     => '·¢Æ±±àºÅ´íÎó!',
+  'Jan'                         => 'Ò»ÔÂ',
+  'January'                     => 'Ò»ÔÂ',
+  'Jul'                         => 'ÆßÔÂ',
+  'July'                        => 'ÆßÔÂ',
+  'Jun'                         => 'ÁùÔÂ',
+  'June'                        => 'ÁùÔÂ',
+  'Mar'                         => 'ÈýÔÂ',
+  'March'                       => 'ÈýÔÂ',
+  'May'                         => 'ÎåÔÂ',
+  'May '                        => 'ÎåÔÂ',
+  'Notes'                       => '±¸×¢',
+  'Nov'                         => 'ʮһÔÂ',
+  'November'                    => 'ʮһÔÂ',
+  'Number'                      => '±àºÅ',
+  'Oct'                         => 'Ê®ÔÂ',
+  'October'                     => 'Ê®ÔÂ',
+  'Open'                        => '¿ªÆô',
+  'Order'                       => '¶©µ¥',
+  'Order Number'                => '¶©µ¥±àºÅ',
+  'Paid'                        => 'ÒѸ¶',
+  'Payment date missing!'       => 'δָÃ÷¸¶¿î?ÕÆ?!',
+  'Payments'                    => '¸¶¿î',
+  'Post'                        => 'È·ÈÏ',
+  'Post as new'                 => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Project'                     => '¹¤³Ì',
+  'Project not on file!'        => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Remaining'                   => 'ÉÐâÅ',
+  'Sales Invoice'               => 'Ïú»õ·¢Æ±',
+  'Select from one of the names below' => 'ì¶ÏÂÁÐÃû×ÖÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the projects below' => 'ì¶ÏÂÁй¤³ÌÖÐÑ¡ÔñÒ»Ïî',
+  'Sep'                         => '¾ÅÔÂ',
+  'September'                   => '¾ÅÔÂ',
+  'Source'                      => 'À´Ô´',
+  'Subtotal'                    => 'С¼Æ',
+  'Tax'                         => 'Ë°½ð',
+  'Tax Included'                => '²»ÊÕ·þÎñ·Ñ',
+  'Total'                       => '×ܼÆ',
+  'Transaction deleted!'        => 'ÕÊĿɾ³ý!',
+  'Transaction posted!'         => 'ÕÊÄ¿È·ÈÏ!',
+  'Update'                      => '¸üÐÂ',
+  'Vendor not on file!'         => '´Ë³§ÉÌδÔÚµµ°¸!',
+  'Yes'                         => 'ÊÇ',
+  'to'                          => 'ÖÁ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'Ó¦ÊÕÕÊÄ¿'                    => 'ar_transaction',
+  '¼ÌÐø'                        => 'continue',
+  'ɾ³ý'                        => 'delete',
+  'È·ÈÏ'                        => 'post',
+  'È·ÈϳÉΪÐÂÕÊÄ¿'              => 'post_as_new',
+  'Ïú»õ·¢Æ±'                    => 'sales_invoice',
+  '¸üÐÂ'                        => 'update',
+  'ÊÇ'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/arap b/sql-ledger/locale/cn/arap
new file mode 100644 (file)
index 0000000..a6a3975
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'µØÖ·',
+  'Continue'                    => '¼ÌÐø',
+  'Customer not on file!'       => '¿Í»§¼Ç¼ûÔÚµµ°¸!',
+  'Description'                 => '˵Ã÷',
+  'Number'                      => '±àºÅ',
+  'Project not on file!'        => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Select from one of the names below' => 'ì¶ÏÂÁÐÃû×ÖÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the projects below' => 'ì¶ÏÂÁй¤³ÌÖÐÑ¡ÔñÒ»Ïî',
+  'Vendor not on file!'         => '´Ë³§ÉÌδÔÚµµ°¸!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  '¼ÌÐø'                        => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/ca b/sql-ledger/locale/cn/ca
new file mode 100644 (file)
index 0000000..91587fb
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => '¿ÆÄ¿',
+  'Apr'                         => 'ËÄÔÂ',
+  'April'                       => 'ËÄÔÂ',
+  'Aug'                         => '°ËÔÂ',
+  'August'                      => '°ËÔÂ',
+  'Balance'                     => '²î¶î',
+  'Chart of Accounts'           => '»á¼Æ¿ÆÄ¿±í',
+  'Credit'                      => '´û·½',
+  'Date'                        => 'ÈÕÆÚ',
+  'Debit'                       => '½è·½',
+  'Dec'                         => 'Ê®¶þÔÂ',
+  'December'                    => 'Ê®¶þÔÂ',
+  'Description'                 => '˵Ã÷',
+  'Feb'                         => '¶þÔÂ',
+  'February'                    => '¶þÔÂ',
+  'From'                        => '´Ó',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Ò»²¢ÏÔʾ',
+  'Jan'                         => 'Ò»ÔÂ',
+  'January'                     => 'Ò»ÔÂ',
+  'Jul'                         => 'ÆßÔÂ',
+  'July'                        => 'ÆßÔÂ',
+  'Jun'                         => 'ÁùÔÂ',
+  'June'                        => 'ÁùÔÂ',
+  'List Transactions'           => 'ÁгöÕÊÄ¿',
+  'Mar'                         => 'ÈýÔÂ',
+  'March'                       => 'ÈýÔÂ',
+  'May'                         => 'ÎåÔÂ',
+  'May '                        => 'ÎåÔÂ',
+  'Nov'                         => 'ʮһÔÂ',
+  'November'                    => 'ʮһÔÂ',
+  'Oct'                         => 'Ê®ÔÂ',
+  'October'                     => 'Ê®ÔÂ',
+  'Reference'                   => '²Î¿¼ºÅÂë',
+  'Sep'                         => '¾ÅÔÂ',
+  'September'                   => '¾ÅÔÂ',
+  'Subtotal'                    => 'С¼Æ',
+  'to'                          => 'ÖÁ',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'ÁгöÕÊÄ¿'                    => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/cp b/sql-ledger/locale/cn/cp
new file mode 100644 (file)
index 0000000..fb357dc
--- /dev/null
@@ -0,0 +1,77 @@
+$self{texts} = {
+  'Account'                     => '¿ÆÄ¿',
+  'Address'                     => 'µØÖ·',
+  'Amount'                      => '×ܼÆ',
+  'Amount does not equal applied!' => '×ܶÏàµÈ!',
+  'Amount missing!'             => 'δָÃ÷×ܶî!',
+  'Applied'                     => 'Ö§¸¶',
+  'Cannot post payment!'        => 'ÎÞ·¨´¦Àí¸¶¿î!',
+  'Cannot process payment for a closed period!' => 'ÒѹرյÄʱ¶ÎÄÚ´¦Àí¸¶¿î!',
+  'Check'                       => '֧Ʊ',
+  'Check printed!'              => 'ӡˢ֧Ʊ!',
+  'Check printing failed!'      => 'ÎÞ·¨Ó¡Ë¢Ö§Æ±!',
+  'Continue'                    => '¼ÌÐø',
+  'Currency'                    => '±Ò±ð',
+  'Customer'                    => '¿Í»§',
+  'Customer not on file!'       => '¿Í»§¼Ç¼ûÔÚµµ°¸!',
+  'Date'                        => 'ÈÕÆÚ',
+  'Date missing!'               => 'δָÃ÷ÈÕÆÚ',
+  'Description'                 => '˵Ã÷',
+  'Due'                         => 'µ½ÆÚ',
+  'Exchangerate'                => '»ãÂÊ',
+  'From'                        => '´Ó',
+  'Invoice'                     => '·¢Æ±',
+  'Invoices'                    => '·¢Æ±',
+  'Nothing applied!'            => 'δָÃ÷Ö§¸¶×ܶî!',
+  'Number'                      => '±àºÅ',
+  'Paid in full'                => 'Ö§¸¶È«²¿×ܶî',
+  'Payment'                     => '¸¶¿î·½Ê½',
+  'Payment posted!'             => 'Payment posted!',
+  'Post'                        => 'È·ÈÏ',
+  'Print'                       => 'ӡˢ',
+  'Printer'                     => 'Ó¡±í»ú',
+  'Project not on file!'        => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Receipt'                     => 'ÊÕ¾Ý',
+  'Receipt printed!'            => 'Receipt printed!',
+  'Receipt printing failed!'    => 'Receipt printing failed!',
+  'Reference'                   => '²Î¿¼ºÅÂë',
+  'Screen'                      => 'өĻ',
+  'Select from one of the names below' => 'ì¶ÏÂÁÐÃû×ÖÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the projects below' => 'ì¶ÏÂÁй¤³ÌÖÐÑ¡ÔñÒ»Ïî',
+  'Update'                      => '¸üÐÂ',
+  'Vendor'                      => '³§ÉÌ',
+  'Vendor not on file!'         => '´Ë³§ÉÌδÔÚµµ°¸!',
+  'to'                          => 'ÖÁ',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  '¼ÌÐø'                        => 'continue',
+  'È·ÈÏ'                        => 'post',
+  'ӡˢ'                        => 'print',
+  '¸üÐÂ'                        => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/ct b/sql-ledger/locale/cn/ct
new file mode 100644 (file)
index 0000000..7793fea
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'ÐÂÔö',
+  'Address'                     => 'µØÖ·',
+  'All'                         => 'È«²¿',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => '²»ÄÜɾ³ý¿Í»§!',
+  'Cannot delete vendor!'       => '²»ÄÜɾ³ý³§ÉÌ!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Á¬ÂçÈË',
+  'Continue'                    => '¼ÌÐø',
+  'Credit Limit'                => 'ÐÅÓöî¶È',
+  'Customer deleted!'           => '¿Í»§¼Ç¼ɾ³ý!',
+  'Customer saved!'             => '¿Í»§¼Ç¼±£´æ!',
+  'Customers'                   => '¿Í»§',
+  'Delete'                      => 'ɾ³ý',
+  'Discount'                    => 'ÕÛ¿Û',
+  'E-mail'                      => 'µç×ÓÓʼþ',
+  'Edit Customer'               => '±à¼­¿Í»§',
+  'Edit Vendor'                 => '±à¼­³§ÉÌ',
+  'Fax'                         => '´«Õæ',
+  'Include in Report'           => 'Ò»²¢ÏÔʾ',
+  'Invoice'                     => '·¢Æ±',
+  'Name'                        => 'Ãû³Æ',
+  'Name missing!'               => 'ȱÉÙÃû³Æ!',
+  'Notes'                       => '±¸×¢',
+  'Number'                      => '±àºÅ',
+  'Order'                       => '¶©µ¥',
+  'Orphaned'                    => 'ÎÞÖ÷',
+  'Phone'                       => 'µç»°ºÅÂë',
+  'Save'                        => '´¢´æ',
+  'Ship to'                     => 'ÏúÊÛ´ú±í',
+  'Tax Included'                => '²»ÊÕ·þÎñ·Ñ',
+  'Taxable'                     => 'Ӧ˰',
+  'Terms: Net'                  => 'ƱÆÚ¾»¼Æ',
+  'Transactions exist, cannot delete customer!' => '´Ë¿Í»§ÒÑÓÐÕÊÄ¿, ²»ÄÜɾ³ý!',
+  'Transactions exist, cannot delete vendor!' => '´Ë³§ÉÌÒÑÓÐÕÊÄ¿, ²»ÄÜɾ³ý!',
+  'Vendor deleted!'             => '³§ÉÌɾ³ý!',
+  'Vendor saved!'               => '³§É̱£´æ!',
+  'Vendors'                     => '³§ÉÌ',
+  'days'                        => 'ÈÕ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'ÐÂÔö'                        => 'add',
+  '¼ÌÐø'                        => 'continue',
+  'ɾ³ý'                        => 'delete',
+  '·¢Æ±'                        => 'invoice',
+  '¶©µ¥'                        => 'order',
+  '´¢´æ'                        => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/gl b/sql-ledger/locale/cn/gl
new file mode 100644 (file)
index 0000000..df81370
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Ó¦¸¶ÕÊÄ¿',
+  'AR Transaction'              => 'Ó¦ÊÕÕÊÄ¿',
+  'Account'                     => '¿ÆÄ¿',
+  'Add General Ledger Transaction' => 'ÐÂÔö×ÜÕÊ',
+  'Address'                     => 'µØÖ·',
+  'All'                         => 'È«²¿',
+  'Apr'                         => 'ËÄÔÂ',
+  'April'                       => 'ËÄÔÂ',
+  'Are you sure you want to delete Transaction' => 'ÄúÈ·¶¨ÒªÉ¾³ýÕÊÄ¿',
+  'Asset'                       => '×ʲú',
+  'Aug'                         => '°ËÔÂ',
+  'August'                      => '°ËÔÂ',
+  'Balance'                     => '²î¶î',
+  'Cannot delete transaction!'  => 'ÎÞ·¨É¾³ýÕÊÄ¿!',
+  'Cannot have a value in both Debit and Credit!' => '²»µÃͬʱÌîÈëÊýֵ춽跽Óë´û·½À¸Î»',
+  'Cannot post a transaction without a value!' => 'ÎÞ·¨È·ÈÏû¼Û¸ñÕÊÄ¿!',
+  'Cannot post transaction for a closed period!' => 'ÎÞ·¨ÔÚÒѹرյÄʱ¶ÎÄÚ¼Ó?ë½»Ò?!',
+  'Confirm!'                    => 'ÈëÕʳɹ¦!',
+  'Continue'                    => '¼ÌÐø',
+  'Credit'                      => '´û·½',
+  'Customer not on file!'       => '¿Í»§¼Ç¼ûÔÚµµ°¸!',
+  'Date'                        => 'ÈÕÆÚ',
+  'Debit'                       => '½è·½',
+  'Debit and credit out of balance!' => '½è´û²»Æ½ºâ!',
+  'Dec'                         => 'Ê®¶þÔÂ',
+  'December'                    => 'Ê®¶þÔÂ',
+  'Delete'                      => 'ɾ³ý',
+  'Description'                 => '˵Ã÷',
+  'Edit General Ledger Transaction' => '±à¼­×ÜÕÊ',
+  'Equity'                      => '¹ÉȨ',
+  'Expense'                     => '·ÑÓÃ',
+  'Feb'                         => '¶þÔÂ',
+  'February'                    => '¶þÔÂ',
+  'From'                        => '´Ó',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => '×ÜÕÊ',
+  'General Ledger'              => '×ÜÕÊ',
+  'ID'                          => '±àºÅ',
+  'Include in Report'           => 'Ò»²¢ÏÔʾ',
+  'Income'                      => 'ÊÕÒæ',
+  'Jan'                         => 'Ò»ÔÂ',
+  'January'                     => 'Ò»ÔÂ',
+  'Jul'                         => 'ÆßÔÂ',
+  'July'                        => 'ÆßÔÂ',
+  'Jun'                         => 'ÁùÔÂ',
+  'June'                        => 'ÁùÔÂ',
+  'Liability'                   => '¸ºÕ®',
+  'Mar'                         => 'ÈýÔÂ',
+  'March'                       => 'ÈýÔÂ',
+  'May'                         => 'ÎåÔÂ',
+  'May '                        => 'ÎåÔÂ',
+  'Notes'                       => '±¸×¢',
+  'Nov'                         => 'ʮһÔÂ',
+  'November'                    => 'ʮһÔÂ',
+  'Number'                      => '±àºÅ',
+  'Oct'                         => 'Ê®ÔÂ',
+  'October'                     => 'Ê®ÔÂ',
+  'Post'                        => 'È·ÈÏ',
+  'Post as new'                 => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Project'                     => '¹¤³Ì',
+  'Project not on file!'        => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Purchase Invoice'            => '²É¹º·¢Æ±',
+  'Reference'                   => '²Î¿¼ºÅÂë',
+  'Reference missing!'          => 'δָÃ÷²Î¿¼ºÅÂë!',
+  'Reports'                     => '±¨±í',
+  'Sales Invoice'               => 'Ïú»õ·¢Æ±',
+  'Select from one of the names below' => 'ì¶ÏÂÁÐÃû×ÖÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the projects below' => 'ì¶ÏÂÁй¤³ÌÖÐÑ¡ÔñÒ»Ïî',
+  'Sep'                         => '¾ÅÔÂ',
+  'September'                   => '¾ÅÔÂ',
+  'Source'                      => 'À´Ô´',
+  'Subtotal'                    => 'С¼Æ',
+  'Transaction Date missing!'   => '©ÌîÕÊÄ¿ÈÕÆÚ!',
+  'Transaction deleted!'        => 'ÕÊĿɾ³ý!',
+  'Transaction posted!'         => 'ÕÊÄ¿È·ÈÏ!',
+  'Update'                      => '¸üÐÂ',
+  'Vendor not on file!'         => '´Ë³§ÉÌδÔÚµµ°¸!',
+  'Yes'                         => 'ÊÇ',
+  'to'                          => 'ÖÁ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'Ó¦¸¶ÕÊÄ¿'                    => 'ap_transaction',
+  'Ó¦ÊÕÕÊÄ¿'                    => 'ar_transaction',
+  '¼ÌÐø'                        => 'continue',
+  'ɾ³ý'                        => 'delete',
+  '×ÜÕÊ'                        => 'gl_transaction',
+  'È·ÈÏ'                        => 'post',
+  'È·ÈϳÉΪÐÂÕÊÄ¿'              => 'post_as_new',
+  '²É¹º·¢Æ±'                    => 'purchase_invoice',
+  'Ïú»õ·¢Æ±'                    => 'sales_invoice',
+  '¸üÐÂ'                        => 'update',
+  'ÊÇ'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/ic b/sql-ledger/locale/cn/ic
new file mode 100644 (file)
index 0000000..e9bc870
--- /dev/null
@@ -0,0 +1,206 @@
+$self{texts} = {
+  'Active'                      => '»îÔ¾',
+  'Add'                         => 'ÐÂÔö',
+  'Add Assembly'                => 'ÐÂÔöÉÌÆ·',
+  'Add Part'                    => 'ÐÂÔöÔ­ÁÏ',
+  'Add Purchase Order'          => 'ÐÂÔö²É¹ºµ¥',
+  'Add Sales Order'             => 'ÐÂÔöÏú»õµ¥',
+  'Add Service'                 => 'ÐÂÔö·þÎñ',
+  'Address'                     => 'µØÖ·',
+  'Apr'                         => 'ËÄÔÂ',
+  'April'                       => 'ËÄÔÂ',
+  'Assemblies'                  => 'ÉÌÆ·',
+  'Assemblies restocked!'       => '×°ÅäÖØнø»õ!',
+  'Assembly Number missing!'    => '²éÎÞ´ËÉÌÆ·!',
+  'Attachment'                  => '¸½µµ',
+  'Aug'                         => '°ËÔÂ',
+  'August'                      => '°ËÔÂ',
+  'BOM'                         => '²ÄÁÏÕʵ¥',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Ïä',
+  'Bought'                      => 'ÒѹºÂò',
+  'COGS'                        => '»õÏú³É±¾',
+  'Cannot delete item already invoiced!' => 'ÎÞ·¨É¾³ý±¾Ïî',
+  'Cannot delete item on order!' => 'ÎÞ·¨É¾³ýµ¥ÉϵÄÏîÄ¿!',
+  'Cannot delete item which is part of an assembly!' => 'ÎÞ·¨É¾³ýÓÃì¶ÉÌÆ·ÖеÄÔ­ÁÏ',
+  'Cannot delete item!'         => 'ÎÞ·¨É¾³ýÏîÄ¿!',
+  'Cannot stock assemblies!'    => 'ÎÞ·¨É¾³ý×°ÅäÉÌÆ·!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Á¬ÂçÈË',
+  'Continue'                    => '¼ÌÐø',
+  'Copies'                      => '¿½±´',
+  'Dec'                         => 'Ê®¶þÔÂ',
+  'December'                    => 'Ê®¶þÔÂ',
+  'Delete'                      => 'ɾ³ý',
+  'Delivery Date'               => 'µÝËÍÈÕÆÚ',
+  'Description'                 => '˵Ã÷',
+  'Drawing'                     => 'ͼ',
+  'E-mail'                      => 'µç×ÓÓʼþ',
+  'E-mail address missing!'     => '©Ìîµç×ÓÓʼþλַ!',
+  'Edit Assembly'               => '±à¼­ÉÌÆ·',
+  'Edit Part'                   => '±à¼­Ô­ÁÏ',
+  'Edit Service'                => '±à¼­·þÎñ',
+  'Expense'                     => '·ÑÓÃ',
+  'Extended'                    => '¼ÆËãÁÐ',
+  'Fax'                         => '´«Õæ',
+  'Feb'                         => '¶þÔÂ',
+  'February'                    => '¶þÔÂ',
+  'From'                        => '´Ó',
+  'Image'                       => 'ͼÏó',
+  'In-line'                     => 'ÐÐÄÚ',
+  'Include in Report'           => 'Ò»²¢ÏÔʾ',
+  'Income'                      => 'ÊÕÒæ',
+  'Individual Items'            => '×é³ÉÏîÄ¿',
+  'Inventory'                   => '¿â´æ',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'ÔÚÍ£ÓôËÏî×éºÏƷ֮ǰ, ´æ»õÊýÁ¿±ØÐèΪÁã!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Í£ÓôËÏîÁã¼þ֮ǰ, ´æ»õÊýÁ¿±ØÐèΪÁã!',
+  'Inventory quantity must be zero!' => '´æ»õÊýÁ¿±ØÐèΪÁã!',
+  'Invoice'                     => '·¢Æ±',
+  'Invoice Date missing!'       => '·¢Æ±ÈÕÆÚ´íÎó!',
+  'Invoice Number'              => '·¢Æ±±àºÅ',
+  'Invoice Number missing!'     => '·¢Æ±±àºÅ´íÎó!',
+  'Item deleted!'               => 'ÏîĿɾ³ý!',
+  'Item not on file!'           => '²éÎÞ´ËÏîÄ¿',
+  'Jan'                         => 'Ò»ÔÂ',
+  'January'                     => 'Ò»ÔÂ',
+  'Jul'                         => 'ÆßÔÂ',
+  'July'                        => 'ÆßÔÂ',
+  'Jun'                         => 'ÁùÔÂ',
+  'June'                        => 'ÁùÔÂ',
+  'Last Cost'                   => 'ÉÏÒ»±Ê³É±¾',
+  'Line Total'                  => '×ÜÁÐÊý',
+  'Link Accounts'               => 'Á¬½á¿ÆÄ¿',
+  'List Price'                  => 'List Price',
+  'Make'                        => 'ÖÆÔì',
+  'Mar'                         => 'ÈýÔÂ',
+  'March'                       => 'ÈýÔÂ',
+  'May'                         => 'ÎåÔÂ',
+  'May '                        => 'ÎåÔÂ',
+  'Message'                     => 'ѶϢ',
+  'Microfiche'                  => 'Ëõ΢½ºÆ¬',
+  'Model'                       => 'ÐͺÅ',
+  'Name'                        => 'Ãû³Æ',
+  'No.'                         => '±àºÅ',
+  'Notes'                       => '±¸×¢',
+  'Nov'                         => 'ʮһÔÂ',
+  'November'                    => 'ʮһÔÂ',
+  'Number'                      => '±àºÅ',
+  'Number missing in Row'       => 'δָÃ÷ºÅÂë',
+  'Obsolete'                    => 'Í£ÓÃ',
+  'Oct'                         => 'Ê®ÔÂ',
+  'October'                     => 'Ê®ÔÂ',
+  'On Hand'                     => '´æÁ¿',
+  'On Order'                    => 'ÒÑϵ¥¶©¹º',
+  'Order'                       => '¶©µ¥',
+  'Order Date missing!'         => 'δָÃ÷ϵ¥?ÕÆ?!',
+  'Order Number'                => '¶©µ¥±àºÅ',
+  'Order Number missing!'       => 'δָÃ÷¶©µ¥±àºÅ!',
+  'Ordered'                     => 'ÒÑ϶©¹º',
+  'Orphaned'                    => 'ÎÞÖ÷',
+  'PDF'                         => 'PDF',
+  'Packing List'                => '³ö»õµ¥',
+  'Packing List Date missing!'  => 'δָÃ÷°ü×°Çåµ¥?ÕÆ?!',
+  'Packing List Number missing!' => 'δָÃ÷°ü×°Çåµ¥±àºÅ!',
+  'Part'                        => 'Ô­ÁÏ',
+  'Part Number missing!'        => '©ÌîÔ­ÁϱàºÅ!',
+  'Parts'                       => 'Ô­ÁÏ',
+  'Phone'                       => 'µç»°ºÅÂë',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => '¼Û¸ñ',
+  'Printer'                     => 'Ó¡±í»ú',
+  'Project'                     => '¹¤³Ì',
+  'Purchase Order'              => '²É¹ºµ¥',
+  'Qty'                         => 'ÊýÁ¿',
+  'ROP'                         => 'ÔÙ¶©µã',
+  'Recd'                        => 'Recd',
+  'Required by'                 => '×ÓÏîÄ¿',
+  'Sales'                       => 'ÒµÎñ',
+  'Sales Order'                 => 'Ïú»õµ¥',
+  'Save'                        => '´¢´æ',
+  'Screen'                      => 'өĻ',
+  'Select from one of the items below' => 'ì¶ÏÂÁÐÏîÄ¿ÖÐÑ¡ÔñÒ»Ïî',
+  'Select postscript or PDF!'   => 'Ñ¡Ôñ postscript »ò PDF!',
+  'Sell Price'                  => 'ÊÛ¼Û',
+  'Sep'                         => '¾ÅÔÂ',
+  'September'                   => '¾ÅÔÂ',
+  'Service'                     => '·þÎñ',
+  'Service Number missing!'     => '©Ìî·þÎñ±àºÅ!',
+  'Services'                    => '·þÎñ',
+  'Ship'                        => 'º½ÔË',
+  'Ship to'                     => 'ÏúÊÛ´ú±í',
+  'Short'                       => '¶Ì',
+  'Sold'                        => 'ÒÑÂô³ö',
+  'Stock Assembly'              => 'Å̵ã',
+  'Subject'                     => '±êÌâ',
+  'Subtotal'                    => 'С¼Æ',
+  'Tax'                         => 'Ë°½ð',
+  'To'                          => 'ÖÁ',
+  'Top Level'                   => '×î¸ßµÈ¼¶',
+  'Total'                       => '×ܼÆ',
+  'Unit'                        => 'µ¥Î»',
+  'Unit of measure'             => '¶ÈÁ¿µ¥Î»',
+  'Update'                      => '¸üÐÂ',
+  'Updated'                     => 'ÒѸüÐÂ',
+  'Weight'                      => 'ÖØÁ¿',
+  'What type of item is this?'  => '´ËÏîÄ¿µÄÐÍ̬?',
+  'ea'                          => 'ea',
+  'emailed to'                  => 'ÒѼÄÖÁ',
+  'hr'                          => 'hr',
+  'sent to printer'             => 'ËÍÖÁÓ¡±í»ú',
+  'to'                          => 'ÖÁ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'ÐÂÔö'                        => 'add',
+  'ÐÂÔöÉÌÆ·'                    => 'add_assembly',
+  'ÐÂÔöÔ­ÁÏ'                    => 'add_part',
+  'ÐÂÔö·þÎñ'                    => 'add_service',
+  '¼ÌÐø'                        => 'continue',
+  'ɾ³ý'                        => 'delete',
+  '±à¼­ÉÌÆ·'                    => 'edit_assembly',
+  '±à¼­Ô­ÁÏ'                    => 'edit_part',
+  '±à¼­·þÎñ'                    => 'edit_service',
+  '´¢´æ'                        => 'save',
+  '¸üÐÂ'                        => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/io b/sql-ledger/locale/cn/io
new file mode 100644 (file)
index 0000000..fb68738
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'ÐÂÔö²É¹ºµ¥',
+  'Add Sales Order'             => 'ÐÂÔöÏú»õµ¥',
+  'Address'                     => 'µØÖ·',
+  'Apr'                         => 'ËÄÔÂ',
+  'April'                       => 'ËÄÔÂ',
+  'Attachment'                  => '¸½µµ',
+  'Aug'                         => '°ËÔÂ',
+  'August'                      => '°ËÔÂ',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Ïä',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Á¬ÂçÈË',
+  'Continue'                    => '¼ÌÐø',
+  'Copies'                      => '¿½±´',
+  'Dec'                         => 'Ê®¶þÔÂ',
+  'December'                    => 'Ê®¶þÔÂ',
+  'Delivery Date'               => 'µÝËÍÈÕÆÚ',
+  'Description'                 => '˵Ã÷',
+  'E-mail'                      => 'µç×ÓÓʼþ',
+  'E-mail address missing!'     => '©Ìîµç×ÓÓʼþλַ!',
+  'Extended'                    => '¼ÆËãÁÐ',
+  'Fax'                         => '´«Õæ',
+  'Feb'                         => '¶þÔÂ',
+  'February'                    => '¶þÔÂ',
+  'In-line'                     => 'ÐÐÄÚ',
+  'Invoice'                     => '·¢Æ±',
+  'Invoice Date missing!'       => '·¢Æ±ÈÕÆÚ´íÎó!',
+  'Invoice Number missing!'     => '·¢Æ±±àºÅ´íÎó!',
+  'Item not on file!'           => '²éÎÞ´ËÏîÄ¿',
+  'Jan'                         => 'Ò»ÔÂ',
+  'January'                     => 'Ò»ÔÂ',
+  'Jul'                         => 'ÆßÔÂ',
+  'July'                        => 'ÆßÔÂ',
+  'Jun'                         => 'ÁùÔÂ',
+  'June'                        => 'ÁùÔÂ',
+  'Mar'                         => 'ÈýÔÂ',
+  'March'                       => 'ÈýÔÂ',
+  'May'                         => 'ÎåÔÂ',
+  'May '                        => 'ÎåÔÂ',
+  'Message'                     => 'ѶϢ',
+  'Name'                        => 'Ãû³Æ',
+  'No.'                         => '±àºÅ',
+  'Nov'                         => 'ʮһÔÂ',
+  'November'                    => 'ʮһÔÂ',
+  'Number'                      => '±àºÅ',
+  'Number missing in Row'       => 'δָÃ÷ºÅÂë',
+  'Oct'                         => 'Ê®ÔÂ',
+  'October'                     => 'Ê®ÔÂ',
+  'Order'                       => '¶©µ¥',
+  'Order Date missing!'         => 'δָÃ÷ϵ¥?ÕÆ?!',
+  'Order Number missing!'       => 'δָÃ÷¶©µ¥±àºÅ!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => '³ö»õµ¥',
+  'Packing List Date missing!'  => 'δָÃ÷°ü×°Çåµ¥?ÕÆ?!',
+  'Packing List Number missing!' => 'δָÃ÷°ü×°Çåµ¥±àºÅ!',
+  'Part'                        => 'Ô­ÁÏ',
+  'Phone'                       => 'µç»°ºÅÂë',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => '¼Û¸ñ',
+  'Printer'                     => 'Ó¡±í»ú',
+  'Project'                     => '¹¤³Ì',
+  'Purchase Order'              => '²É¹ºµ¥',
+  'Qty'                         => 'ÊýÁ¿',
+  'Recd'                        => 'Recd',
+  'Required by'                 => '×ÓÏîÄ¿',
+  'Sales Order'                 => 'Ïú»õµ¥',
+  'Screen'                      => 'өĻ',
+  'Select from one of the items below' => 'ì¶ÏÂÁÐÏîÄ¿ÖÐÑ¡ÔñÒ»Ïî',
+  'Select postscript or PDF!'   => 'Ñ¡Ôñ postscript »ò PDF!',
+  'Sep'                         => '¾ÅÔÂ',
+  'September'                   => '¾ÅÔÂ',
+  'Service'                     => '·þÎñ',
+  'Ship'                        => 'º½ÔË',
+  'Ship to'                     => 'ÏúÊÛ´ú±í',
+  'Subject'                     => '±êÌâ',
+  'To'                          => 'ÖÁ',
+  'Unit'                        => 'µ¥Î»',
+  'What type of item is this?'  => '´ËÏîÄ¿µÄÐÍ̬?',
+  'emailed to'                  => 'ÒѼÄÖÁ',
+  'sent to printer'             => 'ËÍÖÁÓ¡±í»ú',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  '¼ÌÐø'                        => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/ir b/sql-ledger/locale/cn/ir
new file mode 100644 (file)
index 0000000..321d812
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => '¿ÆÄ¿',
+  'Add Purchase Invoice'        => 'ÐÂÔö²É¹º·¢Æ±',
+  'Add Purchase Order'          => 'ÐÂÔö²É¹ºµ¥',
+  'Add Sales Order'             => 'ÐÂÔöÏú»õµ¥',
+  'Address'                     => 'µØÖ·',
+  'Amount'                      => '×ܼÆ',
+  'Apr'                         => 'ËÄÔÂ',
+  'April'                       => 'ËÄÔÂ',
+  'Are you sure you want to delete Invoice Number' => 'ÄúÈ·¶¨ÒªÉ¾³ý·¢Æ±±àºÅ',
+  'Attachment'                  => '¸½µµ',
+  'Aug'                         => '°ËÔÂ',
+  'August'                      => '°ËÔÂ',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Ïä',
+  'Cannot delete invoice!'      => 'ÎÞ·¨É¾³ý·¢Æ±!',
+  'Cannot post invoice for a closed period!' => 'ÎÞ·¨ÔÚÒѹرյÄʱ¶ÎÄÚÈ·ÈÏ·¢Æ±?ë½»Ò!',
+  'Cannot post invoice!'        => 'ÎÞ·¨È·ÈÏ·¢Æ±!',
+  'Cannot post payment for a closed period!' => 'ÎÞ·¨ÔÚÒѹرյÄʱ¶ÎÄÚ¼Ó?ë½»Ò?!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'ÈëÕʳɹ¦!',
+  'Contact'                     => 'Á¬ÂçÈË',
+  'Continue'                    => '¼ÌÐø',
+  'Copies'                      => '¿½±´',
+  'Currency'                    => '±Ò±ð',
+  'Customer not on file!'       => '¿Í»§¼Ç¼ûÔÚµµ°¸!',
+  'Date'                        => 'ÈÕÆÚ',
+  'Date Due'                    => 'Ó¦¸¶ÈÕÆÚ',
+  'Dec'                         => 'Ê®¶þÔÂ',
+  'December'                    => 'Ê®¶þÔÂ',
+  'Delete'                      => 'ɾ³ý',
+  'Delivery Date'               => 'µÝËÍÈÕÆÚ',
+  'Description'                 => '˵Ã÷',
+  'E-mail'                      => 'µç×ÓÓʼþ',
+  'E-mail address missing!'     => '©Ìîµç×ÓÓʼþλַ!',
+  'Edit Purchase Invoice'       => '±à¼­²É¹º·¢Æ±',
+  'Exch'                        => '»ãÂÊ',
+  'Exchangerate'                => '»ãÂÊ',
+  'Exchangerate for payment missing!' => 'δָÃ÷¸¶¿î»ãÂÊ!',
+  'Exchangerate missing!'       => 'δָÃ÷»ãÂÊ!',
+  'Extended'                    => '¼ÆËãÁÐ',
+  'Fax'                         => '´«Õæ',
+  'Feb'                         => '¶þÔÂ',
+  'February'                    => '¶þÔÂ',
+  'In-line'                     => 'ÐÐÄÚ',
+  'Invoice'                     => '·¢Æ±',
+  'Invoice Date'                => '·¢Æ±ÈÕÆÚ',
+  'Invoice Date missing!'       => '·¢Æ±ÈÕÆÚ´íÎó!',
+  'Invoice Number'              => '·¢Æ±±àºÅ',
+  'Invoice Number missing!'     => '·¢Æ±±àºÅ´íÎó!',
+  'Invoice deleted!'            => '·¢Æ±É¾³ý!',
+  'Invoice posted!'             => '·¢Æ±È·ÈÏ!',
+  'Item not on file!'           => '²éÎÞ´ËÏîÄ¿',
+  'Jan'                         => 'Ò»ÔÂ',
+  'January'                     => 'Ò»ÔÂ',
+  'Jul'                         => 'ÆßÔÂ',
+  'July'                        => 'ÆßÔÂ',
+  'Jun'                         => 'ÁùÔÂ',
+  'June'                        => 'ÁùÔÂ',
+  'Mar'                         => 'ÈýÔÂ',
+  'March'                       => 'ÈýÔÂ',
+  'May'                         => 'ÎåÔÂ',
+  'May '                        => 'ÎåÔÂ',
+  'Message'                     => 'ѶϢ',
+  'Name'                        => 'Ãû³Æ',
+  'No.'                         => '±àºÅ',
+  'Notes'                       => '±¸×¢',
+  'Nov'                         => 'ʮһÔÂ',
+  'November'                    => 'ʮһÔÂ',
+  'Number'                      => '±àºÅ',
+  'Number missing in Row'       => 'δָÃ÷ºÅÂë',
+  'Oct'                         => 'Ê®ÔÂ',
+  'October'                     => 'Ê®ÔÂ',
+  'Order'                       => '¶©µ¥',
+  'Order Date missing!'         => 'δָÃ÷ϵ¥?ÕÆ?!',
+  'Order Number'                => '¶©µ¥±àºÅ',
+  'Order Number missing!'       => 'δָÃ÷¶©µ¥±àºÅ!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => '³ö»õµ¥',
+  'Packing List Date missing!'  => 'δָÃ÷°ü×°Çåµ¥?ÕÆ?!',
+  'Packing List Number missing!' => 'δָÃ÷°ü×°Çåµ¥±àºÅ!',
+  'Part'                        => 'Ô­ÁÏ',
+  'Payment date missing!'       => 'δָÃ÷¸¶¿î?ÕÆ?!',
+  'Payments'                    => '¸¶¿î',
+  'Phone'                       => 'µç»°ºÅÂë',
+  'Post'                        => 'È·ÈÏ',
+  'Post as new'                 => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => '¼Û¸ñ',
+  'Printer'                     => 'Ó¡±í»ú',
+  'Project'                     => '¹¤³Ì',
+  'Project not on file!'        => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Purchase Order'              => '²É¹ºµ¥',
+  'Qty'                         => 'ÊýÁ¿',
+  'Recd'                        => 'Recd',
+  'Record in'                   => '¼Ç¼ì¶',
+  'Required by'                 => '×ÓÏîÄ¿',
+  'Sales Order'                 => 'Ïú»õµ¥',
+  'Screen'                      => 'өĻ',
+  'Select from one of the items below' => 'ì¶ÏÂÁÐÏîÄ¿ÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the names below' => 'ì¶ÏÂÁÐÃû×ÖÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the projects below' => 'ì¶ÏÂÁй¤³ÌÖÐÑ¡ÔñÒ»Ïî',
+  'Select postscript or PDF!'   => 'Ñ¡Ôñ postscript »ò PDF!',
+  'Sep'                         => '¾ÅÔÂ',
+  'September'                   => '¾ÅÔÂ',
+  'Service'                     => '·þÎñ',
+  'Ship'                        => 'º½ÔË',
+  'Ship to'                     => 'ÏúÊÛ´ú±í',
+  'Source'                      => 'À´Ô´',
+  'Subject'                     => '±êÌâ',
+  'Subtotal'                    => 'С¼Æ',
+  'Tax Included'                => '²»ÊÕ·þÎñ·Ñ',
+  'To'                          => 'ÖÁ',
+  'Total'                       => '×ܼÆ',
+  'Unit'                        => 'µ¥Î»',
+  'Update'                      => '¸üÐÂ',
+  'Vendor'                      => '³§ÉÌ',
+  'Vendor missing!'             => 'δָÃ÷³§ÉÌ!',
+  'Vendor not on file!'         => '´Ë³§ÉÌδÔÚµµ°¸!',
+  'What type of item is this?'  => '´ËÏîÄ¿µÄÐÍ̬?',
+  'Yes'                         => 'ÊÇ',
+  'ea'                          => 'ea',
+  'emailed to'                  => 'ÒѼÄÖÁ',
+  'sent to printer'             => 'ËÍÖÁÓ¡±í»ú',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  '¼ÌÐø'                        => 'continue',
+  'ɾ³ý'                        => 'delete',
+  '¶©µ¥'                        => 'order',
+  'È·ÈÏ'                        => 'post',
+  'È·ÈϳÉΪÐÂÕÊÄ¿'              => 'post_as_new',
+  '¸üÐÂ'                        => 'update',
+  'ÊÇ'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/is b/sql-ledger/locale/cn/is
new file mode 100644 (file)
index 0000000..d55c467
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => '¿ÆÄ¿',
+  'Add Purchase Order'          => 'ÐÂÔö²É¹ºµ¥',
+  'Add Sales Invoice'           => 'ÐÂÔöÏú»õ·¢Æ±',
+  'Add Sales Order'             => 'ÐÂÔöÏú»õµ¥',
+  'Address'                     => 'µØÖ·',
+  'Amount'                      => '×ܼÆ',
+  'Apr'                         => 'ËÄÔÂ',
+  'April'                       => 'ËÄÔÂ',
+  'Are you sure you want to delete Invoice Number' => 'ÄúÈ·¶¨ÒªÉ¾³ý·¢Æ±±àºÅ',
+  'Attachment'                  => '¸½µµ',
+  'Aug'                         => '°ËÔÂ',
+  'August'                      => '°ËÔÂ',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Ïä',
+  'Cannot delete invoice!'      => 'ÎÞ·¨É¾³ý·¢Æ±!',
+  'Cannot post invoice for a closed period!' => 'ÎÞ·¨ÔÚÒѹرյÄʱ¶ÎÄÚÈ·ÈÏ·¢Æ±?ë½»Ò!',
+  'Cannot post invoice!'        => 'ÎÞ·¨È·ÈÏ·¢Æ±!',
+  'Cannot post payment for a closed period!' => 'ÎÞ·¨ÔÚÒѹرյÄʱ¶ÎÄÚ¼Ó?ë½»Ò?!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'ÈëÕʳɹ¦!',
+  'Contact'                     => 'Á¬ÂçÈË',
+  'Continue'                    => '¼ÌÐø',
+  'Copies'                      => '¿½±´',
+  'Credit Limit'                => 'ÐÅÓöî¶È',
+  'Currency'                    => '±Ò±ð',
+  'Customer'                    => '¿Í»§',
+  'Customer missing!'           => 'δָÃ÷¿Í»§!',
+  'Customer not on file!'       => '¿Í»§¼Ç¼ûÔÚµµ°¸!',
+  'Date'                        => 'ÈÕÆÚ',
+  'Date Due'                    => 'Ó¦¸¶ÈÕÆÚ',
+  'Dec'                         => 'Ê®¶þÔÂ',
+  'December'                    => 'Ê®¶þÔÂ',
+  'Delete'                      => 'ɾ³ý',
+  'Delivery Date'               => 'µÝËÍÈÕÆÚ',
+  'Description'                 => '˵Ã÷',
+  'E-mail'                      => 'µç×ÓÓʼþ',
+  'E-mail address missing!'     => '©Ìîµç×ÓÓʼþλַ!',
+  'Edit Sales Invoice'          => '±à¼­Ïú»õ·¢Æ±',
+  'Exch'                        => '»ãÂÊ',
+  'Exchangerate'                => '»ãÂÊ',
+  'Exchangerate for payment missing!' => 'δָÃ÷¸¶¿î»ãÂÊ!',
+  'Exchangerate missing!'       => 'δָÃ÷»ãÂÊ!',
+  'Extended'                    => '¼ÆËãÁÐ',
+  'Fax'                         => '´«Õæ',
+  'Feb'                         => '¶þÔÂ',
+  'February'                    => '¶þÔÂ',
+  'In-line'                     => 'ÐÐÄÚ',
+  'Invoice'                     => '·¢Æ±',
+  'Invoice Date'                => '·¢Æ±ÈÕÆÚ',
+  'Invoice Date missing!'       => '·¢Æ±ÈÕÆÚ´íÎó!',
+  'Invoice Number'              => '·¢Æ±±àºÅ',
+  'Invoice Number missing!'     => '·¢Æ±±àºÅ´íÎó!',
+  'Invoice deleted!'            => '·¢Æ±É¾³ý!',
+  'Invoice posted!'             => '·¢Æ±È·ÈÏ!',
+  'Item not on file!'           => '²éÎÞ´ËÏîÄ¿',
+  'Jan'                         => 'Ò»ÔÂ',
+  'January'                     => 'Ò»ÔÂ',
+  'Jul'                         => 'ÆßÔÂ',
+  'July'                        => 'ÆßÔÂ',
+  'Jun'                         => 'ÁùÔÂ',
+  'June'                        => 'ÁùÔÂ',
+  'Mar'                         => 'ÈýÔÂ',
+  'March'                       => 'ÈýÔÂ',
+  'May'                         => 'ÎåÔÂ',
+  'May '                        => 'ÎåÔÂ',
+  'Message'                     => 'ѶϢ',
+  'Name'                        => 'Ãû³Æ',
+  'No.'                         => '±àºÅ',
+  'Notes'                       => '±¸×¢',
+  'Nov'                         => 'ʮһÔÂ',
+  'November'                    => 'ʮһÔÂ',
+  'Number'                      => '±àºÅ',
+  'Number missing in Row'       => 'δָÃ÷ºÅÂë',
+  'Oct'                         => 'Ê®ÔÂ',
+  'October'                     => 'Ê®ÔÂ',
+  'Order'                       => '¶©µ¥',
+  'Order Date missing!'         => 'δָÃ÷ϵ¥?ÕÆ?!',
+  'Order Number'                => '¶©µ¥±àºÅ',
+  'Order Number missing!'       => 'δָÃ÷¶©µ¥±àºÅ!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => '³ö»õµ¥',
+  'Packing List Date missing!'  => 'δָÃ÷°ü×°Çåµ¥?ÕÆ?!',
+  'Packing List Number missing!' => 'δָÃ÷°ü×°Çåµ¥±àºÅ!',
+  'Part'                        => 'Ô­ÁÏ',
+  'Payment date missing!'       => 'δָÃ÷¸¶¿î?ÕÆ?!',
+  'Payments'                    => '¸¶¿î',
+  'Phone'                       => 'µç»°ºÅÂë',
+  'Post'                        => 'È·ÈÏ',
+  'Post as new'                 => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => '¼Û¸ñ',
+  'Print'                       => 'ӡˢ',
+  'Printer'                     => 'Ó¡±í»ú',
+  'Project'                     => '¹¤³Ì',
+  'Project not on file!'        => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Purchase Order'              => '²É¹ºµ¥',
+  'Qty'                         => 'ÊýÁ¿',
+  'Recd'                        => 'Recd',
+  'Record in'                   => '¼Ç¼ì¶',
+  'Remaining'                   => 'ÉÐâÅ',
+  'Required by'                 => '×ÓÏîÄ¿',
+  'Sales Order'                 => 'Ïú»õµ¥',
+  'Screen'                      => 'өĻ',
+  'Select from one of the items below' => 'ì¶ÏÂÁÐÏîÄ¿ÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the names below' => 'ì¶ÏÂÁÐÃû×ÖÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the projects below' => 'ì¶ÏÂÁй¤³ÌÖÐÑ¡ÔñÒ»Ïî',
+  'Select postscript or PDF!'   => 'Ñ¡Ôñ postscript »ò PDF!',
+  'Sep'                         => '¾ÅÔÂ',
+  'September'                   => '¾ÅÔÂ',
+  'Service'                     => '·þÎñ',
+  'Ship'                        => 'º½ÔË',
+  'Ship to'                     => 'ÏúÊÛ´ú±í',
+  'Ship via'                    => 'º½ÔË·½·¨',
+  'Source'                      => 'À´Ô´',
+  'Subject'                     => '±êÌâ',
+  'Subtotal'                    => 'С¼Æ',
+  'Tax Included'                => '²»ÊÕ·þÎñ·Ñ',
+  'To'                          => 'ÖÁ',
+  'Total'                       => '×ܼÆ',
+  'Unit'                        => 'µ¥Î»',
+  'Update'                      => '¸üÐÂ',
+  'Vendor not on file!'         => '´Ë³§ÉÌδÔÚµµ°¸!',
+  'What type of item is this?'  => '´ËÏîÄ¿µÄÐÍ̬?',
+  'Yes'                         => 'ÊÇ',
+  'ea'                          => 'ea',
+  'emailed to'                  => 'ÒѼÄÖÁ',
+  'sent to printer'             => 'ËÍÖÁÓ¡±í»ú',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  '¼ÌÐø'                        => 'continue',
+  'ɾ³ý'                        => 'delete',
+  'µç×ÓÓʼþ'                    => 'e_mail',
+  '¶©µ¥'                        => 'order',
+  'È·ÈÏ'                        => 'post',
+  'È·ÈϳÉΪÐÂÕÊÄ¿'              => 'post_as_new',
+  'ӡˢ'                        => 'print',
+  'ÏúÊÛ´ú±í'                    => 'ship_to',
+  '¸üÐÂ'                        => 'update',
+  'ÊÇ'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/login b/sql-ledger/locale/cn/login
new file mode 100644 (file)
index 0000000..e22cfe3
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => '¹Øì¶',
+  'Database Host'               => '×ÊÁÏ¿âÖ÷»ú',
+  'Dataset'                     => '×ÊÁϼ¯',
+  'Incorrect Dataset version!'  => '×ÊÁϼ¯°æ±¾´íÎó!',
+  'Incorrect Password!'         => 'ÃÜÂë´íÎó!',
+  'Licensed to'                 => 'ÊÚȨÓè',
+  'Login'                       => 'µÇ??',
+  'Name'                        => 'Ãû³Æ',
+  'Password'                    => 'ÃÜÂë',
+  'User'                        => 'ʹÓÃÕß',
+  'Version'                     => '°æ±¾',
+  'You are logged out!'         => 'ÄãÒԵdzö!',
+  'You did not enter a name!'   => 'Äú²¢Î´¼ü?ëÃ?³Æ!',
+  'is not a member!'            => '²¢²»ÊdzÉÔ±!',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'µÇ??'                        => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/menu b/sql-ledger/locale/cn/menu
new file mode 100644 (file)
index 0000000..c1d4657
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => 'Ó¦¸¶ÕÊ¿î',
+  'AP Aging'                    => 'Ó¦¸¶ÕÊÁä·ÖÎö',
+  'AR'                          => 'Ó¦ÊÕÕÊ¿î',
+  'AR Aging'                    => 'Ó¦ÊÕÕÊÁä·ÖÎö',
+  'Accounting Menu'             => '»á¼ÆÑ¡µ¥',
+  'Add Account'                 => 'ÐÂÔö¿ÆÄ¿',
+  'Add Assembly'                => 'ÐÂÔöÉÌÆ·',
+  'Add Customer'                => 'ÐÂÔö¿Í»§',
+  'Add GIFI'                    => 'ÐÂÔö GIFI',
+  'Add Part'                    => 'ÐÂÔöÔ­ÁÏ',
+  'Add Project'                 => 'ÐÂÔö¹¤³Ì',
+  'Add Service'                 => 'ÐÂÔö·þÎñ',
+  'Add Transaction'             => 'ÐÂÔöÕÊÄ¿',
+  'Add Vendor'                  => 'ÐÂÔö³§ÉÌ',
+  'Assemblies'                  => 'ÉÌÆ·',
+  'Audit Control'               => '»üºË¿ØÖÆ',
+  'Backup'                      => '±¸·Ý',
+  'Balance Sheet'               => '×ʲú¸ºÕ®±í',
+  'Cash'                        => 'ÏÖ½ð',
+  'Chart of Accounts'           => '»á¼Æ¿ÆÄ¿±í',
+  'Check'                       => '֧Ʊ',
+  'Customers'                   => '¿Í»§',
+  'General Ledger'              => '×ÜÕÊ',
+  'Goods & Services'            => 'Goods & Services',
+  'HTML Templates'              => 'HTML ±íµ¥',
+  'Income Statement'            => 'ËðÒæ±í',
+  'Invoice'                     => '·¢Æ±',
+  'LaTeX Templates'             => 'LaTex Ä£°æ',
+  'List Accounts'               => 'ÁгöÕʺÅ',
+  'List GIFI'                   => 'Áгö GIFI',
+  'Logout'                      => 'µÇ³ö',
+  'Order Entry'                 => 'ϵ¥ÏîÄ¿',
+  'Packing List'                => '³ö»õµ¥',
+  'Parts'                       => 'Ô­ÁÏ',
+  'Payment'                     => '¸¶¿î·½Ê½',
+  'Payments'                    => '¸¶¿î',
+  'Preferences'                 => '¸öÈËÉ趨',
+  'Projects'                    => '¹¤³Ì',
+  'Purchase Invoice'            => '²É¹º·¢Æ±',
+  'Purchase Order'              => '²É¹ºµ¥',
+  'Purchase Orders'             => '²É¹ºµ¥',
+  'Receipt'                     => 'ÊÕ¾Ý',
+  'Receipts'                    => 'ÊÕ¾Ý',
+  'Reconciliation'              => 'µ÷Í£',
+  'Reports'                     => '±¨±í',
+  'Sales Invoice'               => 'Ïú»õ·¢Æ±',
+  'Sales Order'                 => 'Ïú»õµ¥',
+  'Sales Orders'                => 'Ïú»õµ¥',
+  'Save to File'                => '´¢´æÖÁµµ°¸',
+  'Send by E-Mail'              => 'ÒÔµç×ÓÓʼþ¼ÄËÍ',
+  'Services'                    => '·þÎñ',
+  'Statement'                   => 'ÕÊÄ¿³ÂÊö',
+  'Stock Assembly'              => 'Å̵ã',
+  'Stylesheet'                  => 'Ñùʽ±í',
+  'System'                      => 'ϵͳ',
+  'Tax collected'               => 'ÊÕµ½µÄË°',
+  'Tax paid'                    => 'Ö§¸¶µÄË°',
+  'Transactions'                => 'ÕÊÄ¿',
+  'Trial Balance'               => 'ÊÔËã±í',
+  'Vendors'                     => '³§ÉÌ',
+  'Version'                     => '°æ±¾',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/oe b/sql-ledger/locale/cn/oe
new file mode 100644 (file)
index 0000000..5054b9b
--- /dev/null
@@ -0,0 +1,200 @@
+$self{texts} = {
+  'Add'                         => 'ÐÂÔö',
+  'Add Purchase Invoice'        => 'ÐÂÔö²É¹º·¢Æ±',
+  'Add Purchase Order'          => 'ÐÂÔö²É¹ºµ¥',
+  'Add Sales Invoice'           => 'ÐÂÔöÏú»õ·¢Æ±',
+  'Add Sales Order'             => 'ÐÂÔöÏú»õµ¥',
+  'Address'                     => 'µØÖ·',
+  'Amount'                      => '×ܼÆ',
+  'Apr'                         => 'ËÄÔÂ',
+  'April'                       => 'ËÄÔÂ',
+  'Are you sure you want to delete Order Number' => 'ÄúÊÇ·ñ?·¶¨ÒªÉ¾³?¶©µ¥',
+  'Attachment'                  => '¸½µµ',
+  'Aug'                         => '°ËÔÂ',
+  'August'                      => '°ËÔÂ',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Ïä',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'ÎÞ·¨É¾³ý¶©µ¥!',
+  'Cannot save order!'          => 'ÎÞ·¨´¢´æÇåµ¥!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'ÒѹرÕ',
+  'Confirm!'                    => 'ÈëÕʳɹ¦!',
+  'Contact'                     => 'Á¬ÂçÈË',
+  'Continue'                    => '¼ÌÐø',
+  'Copies'                      => '¿½±´',
+  'Credit Limit'                => 'ÐÅÓöî¶È',
+  'Curr'                        => 'Ŀǰ',
+  'Currency'                    => '±Ò±ð',
+  'Customer'                    => '¿Í»§',
+  'Customer missing!'           => 'δָÃ÷¿Í»§!',
+  'Customer not on file!'       => '¿Í»§¼Ç¼ûÔÚµµ°¸!',
+  'Date'                        => 'ÈÕÆÚ',
+  'Dec'                         => 'Ê®¶þÔÂ',
+  'December'                    => 'Ê®¶þÔÂ',
+  'Delete'                      => 'ɾ³ý',
+  'Delivery Date'               => 'µÝËÍÈÕÆÚ',
+  'Description'                 => '˵Ã÷',
+  'E-mail'                      => 'µç×ÓÓʼþ',
+  'E-mail address missing!'     => '©Ìîµç×ÓÓʼþλַ!',
+  'Edit Purchase Order'         => '±à¼­²É¹ºµ¥',
+  'Edit Sales Order'            => '±à¼­Ïú»õµ¥',
+  'Exchangerate'                => '»ãÂÊ',
+  'Exchangerate missing!'       => 'δָÃ÷»ãÂÊ!',
+  'Extended'                    => '¼ÆËãÁÐ',
+  'Fax'                         => '´«Õæ',
+  'Feb'                         => '¶þÔÂ',
+  'February'                    => '¶þÔÂ',
+  'From'                        => '´Ó',
+  'ID'                          => '±àºÅ',
+  'In-line'                     => 'ÐÐÄÚ',
+  'Include in Report'           => 'Ò»²¢ÏÔʾ',
+  'Invoice'                     => '·¢Æ±',
+  'Invoice Date missing!'       => '·¢Æ±ÈÕÆÚ´íÎó!',
+  'Invoice Number missing!'     => '·¢Æ±±àºÅ´íÎó!',
+  'Item not on file!'           => '²éÎÞ´ËÏîÄ¿',
+  'Jan'                         => 'Ò»ÔÂ',
+  'January'                     => 'Ò»ÔÂ',
+  'Jul'                         => 'ÆßÔÂ',
+  'July'                        => 'ÆßÔÂ',
+  'Jun'                         => 'ÁùÔÂ',
+  'June'                        => 'ÁùÔÂ',
+  'Mar'                         => 'ÈýÔÂ',
+  'March'                       => 'ÈýÔÂ',
+  'May'                         => 'ÎåÔÂ',
+  'May '                        => 'ÎåÔÂ',
+  'Message'                     => 'ѶϢ',
+  'Name'                        => 'Ãû³Æ',
+  'No.'                         => '±àºÅ',
+  'Notes'                       => '±¸×¢',
+  'Nov'                         => 'ʮһÔÂ',
+  'November'                    => 'ʮһÔÂ',
+  'Number'                      => '±àºÅ',
+  'Number missing in Row'       => 'δָÃ÷ºÅÂë',
+  'O'                           => 'O',
+  'Oct'                         => 'Ê®ÔÂ',
+  'October'                     => 'Ê®ÔÂ',
+  'Open'                        => '¿ªÆô',
+  'Order'                       => '¶©µ¥',
+  'Order Date'                  => 'ϵ¥?ÕÆ?',
+  'Order Date missing!'         => 'δָÃ÷ϵ¥?ÕÆ?!',
+  'Order Number'                => '¶©µ¥±àºÅ',
+  'Order Number missing!'       => 'δָÃ÷¶©µ¥±àºÅ!',
+  'Order deleted!'              => 'ɾ³ý¶©µ¥!',
+  'Order saved!'                => '´¢´æ¶©µ¥!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => '³ö»õµ¥',
+  'Packing List Date missing!'  => 'δָÃ÷°ü×°Çåµ¥?ÕÆ?!',
+  'Packing List Number missing!' => 'δָÃ÷°ü×°Çåµ¥±àºÅ!',
+  'Part'                        => 'Ô­ÁÏ',
+  'Phone'                       => 'µç»°ºÅÂë',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => '¼Û¸ñ',
+  'Print'                       => 'ӡˢ',
+  'Printer'                     => 'Ó¡±í»ú',
+  'Project'                     => '¹¤³Ì',
+  'Project not on file!'        => 'È·ÈϳÉΪÐÂÕÊÄ¿',
+  'Purchase Order'              => '²É¹ºµ¥',
+  'Purchase Orders'             => '²É¹ºµ¥',
+  'Qty'                         => 'ÊýÁ¿',
+  'Recd'                        => 'Recd',
+  'Remaining'                   => 'ÉÐâÅ',
+  'Required by'                 => '×ÓÏîÄ¿',
+  'Sales Order'                 => 'Ïú»õµ¥',
+  'Sales Orders'                => 'Ïú»õµ¥',
+  'Save'                        => '´¢´æ',
+  'Save as new'                 => '´¢´æ',
+  'Screen'                      => 'өĻ',
+  'Select from one of the items below' => 'ì¶ÏÂÁÐÏîÄ¿ÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the names below' => 'ì¶ÏÂÁÐÃû×ÖÖÐÑ¡ÔñÒ»Ïî',
+  'Select from one of the projects below' => 'ì¶ÏÂÁй¤³ÌÖÐÑ¡ÔñÒ»Ïî',
+  'Select postscript or PDF!'   => 'Ñ¡Ôñ postscript »ò PDF!',
+  'Sep'                         => '¾ÅÔÂ',
+  'September'                   => '¾ÅÔÂ',
+  'Service'                     => '·þÎñ',
+  'Ship'                        => 'º½ÔË',
+  'Ship to'                     => 'ÏúÊÛ´ú±í',
+  'Ship via'                    => 'º½ÔË·½·¨',
+  'Subject'                     => '±êÌâ',
+  'Subtotal'                    => 'С¼Æ',
+  'Tax'                         => 'Ë°½ð',
+  'Tax Included'                => '²»ÊÕ·þÎñ·Ñ',
+  'Terms: Net'                  => 'ƱÆÚ¾»¼Æ',
+  'To'                          => 'ÖÁ',
+  'Total'                       => '×ܼÆ',
+  'Unit'                        => 'µ¥Î»',
+  'Update'                      => '¸üÐÂ',
+  'Vendor'                      => '³§ÉÌ',
+  'Vendor missing!'             => 'δָÃ÷³§ÉÌ!',
+  'Vendor not on file!'         => '´Ë³§ÉÌδÔÚµµ°¸!',
+  'What type of item is this?'  => '´ËÏîÄ¿µÄÐÍ̬?',
+  'Yes'                         => 'ÊÇ',
+  'days'                        => 'ÈÕ',
+  'ea'                          => 'ea',
+  'emailed to'                  => 'ÒѼÄÖÁ',
+  'sent to printer'             => 'ËÍÖÁÓ¡±í»ú',
+  'to'                          => 'ÖÁ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'ÐÂÔö'                        => 'add',
+  '¼ÌÐø'                        => 'continue',
+  'ɾ³ý'                        => 'delete',
+  'µç×ÓÓʼþ'                    => 'e_mail',
+  '·¢Æ±'                        => 'invoice',
+  'ӡˢ'                        => 'print',
+  '´¢´æ'                        => 'save',
+  '´¢´æ'                        => 'save_as_new',
+  'ÏúÊÛ´ú±í'                    => 'ship_to',
+  '¸üÐÂ'                        => 'update',
+  'ÊÇ'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/pe b/sql-ledger/locale/cn/pe
new file mode 100644 (file)
index 0000000..35372d3
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'ÐÂÔö',
+  'Add Project'                 => 'ÐÂÔö¹¤³Ì',
+  'All'                         => 'È«²¿',
+  'Continue'                    => '¼ÌÐø',
+  'Delete'                      => 'ɾ³ý',
+  'Description'                 => '˵Ã÷',
+  'Edit Project'                => '¸ü¸Ä¹¤³Ì',
+  'Number'                      => '±àºÅ',
+  'Orphaned'                    => 'ÎÞÖ÷',
+  'Project'                     => '¹¤³Ì',
+  'Project Number missing!'     => 'δָÃ÷¹¤³ÌºÅÂë!',
+  'Project deleted!'            => '¹¤³ÌÒÔ±»É¾³ý!',
+  'Project saved!'              => '¹¤³ÌÒÔ±»´¢´æ!',
+  'Projects'                    => '¹¤³Ì',
+  'Save'                        => '´¢´æ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'ÐÂÔö'                        => 'add',
+  '¼ÌÐø'                        => 'continue',
+  'ɾ³ý'                        => 'delete',
+  '´¢´æ'                        => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/rc b/sql-ledger/locale/cn/rc
new file mode 100644 (file)
index 0000000..31f35f2
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => '¿ÆÄ¿',
+  'Balance'                     => '²î¶î',
+  'Cleared Balance'             => 'Ö§¸¶²î¶î×ÜÊý',
+  'Continue'                    => '¼ÌÐø',
+  'Date'                        => 'ÈÕÆÚ',
+  'Deposit'                     => '´¢´æ',
+  'Description'                 => '˵Ã÷',
+  'Difference'                  => '²îÒì',
+  'Done'                        => 'Íê³É',
+  'Exchangerate Difference'     => '»ãÂʲîÒì',
+  'From'                        => '´Ó',
+  'Out of balance!'             => '³öÓÚ²î¶î!',
+  'Payment'                     => '¸¶¿î·½Ê½',
+  'Reconciliation'              => 'µ÷Í£',
+  'Select all'                  => 'Ñ¡ÔñÈ«²¿',
+  'Source'                      => 'À´Ô´',
+  'Statement Balance'           => 'ÕÊÄ¿³ÂÊö²î¶î',
+  'Update'                      => '¸üÐÂ',
+  'to'                          => 'ÖÁ',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  '¼ÌÐø'                        => 'continue',
+  'Íê³É'                        => 'done',
+  'Ñ¡ÔñÈ«²¿'                    => 'select_all',
+  '¸üÐÂ'                        => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/cn/rp b/sql-ledger/locale/cn/rp
new file mode 100644 (file)
index 0000000..6d80cf8
--- /dev/null
@@ -0,0 +1,120 @@
+$self{texts} = {
+  'AP Aging'                    => 'Ó¦¸¶ÕÊÁä·ÖÎö',
+  'AR Aging'                    => 'Ó¦ÊÕÕÊÁä·ÖÎö',
+  'Account'                     => '¿ÆÄ¿',
+  'Accounts'                    => 'ÕÊ»§',
+  'Amount'                      => '×ܼÆ',
+  'Apr'                         => 'ËÄÔÂ',
+  'April'                       => 'ËÄÔÂ',
+  'Attachment'                  => '¸½µµ',
+  'Aug'                         => '°ËÔÂ',
+  'August'                      => '°ËÔÂ',
+  'Balance'                     => '²î¶î',
+  'Balance Sheet'               => '×ʲú¸ºÕ®±í',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'ÏÖ½ð½»Ò×',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => '¶ÔÕÕ',
+  'Continue'                    => '¼ÌÐø',
+  'Copies'                      => '¿½±´',
+  'Credit'                      => '´û·½',
+  'Current'                     => 'ÏÖÔÚ',
+  'Customer'                    => '¿Í»§',
+  'Date'                        => 'ÈÕÆÚ',
+  'Debit'                       => '½è·½',
+  'Dec'                         => 'Ê®¶þÔÂ',
+  'December'                    => 'Ê®¶þÔÂ',
+  'Decimalplaces'               => 'СÊýµÄÊýÄ¿',
+  'Department'                  => 'Department',
+  'Description'                 => '˵Ã÷',
+  'Due'                         => 'µ½ÆÚ',
+  'E-mail'                      => 'µç×ÓÓʼþ',
+  'E-mail Statement to'         => 'µç×ÓÓʼþÕÊÄ¿³ÂÊöµ½',
+  'Feb'                         => '¶þÔÂ',
+  'February'                    => '¶þÔÂ',
+  'From'                        => '´Ó',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => '±íÍ·',
+  'ID'                          => '±àºÅ',
+  'In-line'                     => 'ÐÐÄÚ',
+  'Include in Report'           => 'Ò»²¢ÏÔʾ',
+  'Income Statement'            => 'ËðÒæ±í',
+  'Invoice'                     => '·¢Æ±',
+  'Jan'                         => 'Ò»ÔÂ',
+  'January'                     => 'Ò»ÔÂ',
+  'Jul'                         => 'ÆßÔÂ',
+  'July'                        => 'ÆßÔÂ',
+  'Jun'                         => 'ÁùÔÂ',
+  'June'                        => 'ÁùÔÂ',
+  'Mar'                         => 'ÈýÔÂ',
+  'March'                       => 'ÈýÔÂ',
+  'May'                         => 'ÎåÔÂ',
+  'May '                        => 'ÎåÔÂ',
+  'Message'                     => 'ѶϢ',
+  'N/A'                         => '²»ÊÊÓÃ',
+  'Nothing selected!'           => 'δѡ¶¨×Ê!',
+  'Nov'                         => 'ʮһÔÂ',
+  'November'                    => 'ʮһÔÂ',
+  'Oct'                         => 'Ê®ÔÂ',
+  'October'                     => 'Ê®ÔÂ',
+  'PDF'                         => 'PDF',
+  'Payments'                    => '¸¶¿î',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'ӡˢ',
+  'Printer'                     => 'Ó¡±í»ú',
+  'Project Number'              => 'Project Number',
+  'Receipts'                    => 'ÊÕ¾Ý',
+  'Report for'                  => '±¨±íÀ´Ô´',
+  'Retained Earnings'           => '±£ÁôÓ¯âÅ',
+  'Screen'                      => 'өĻ',
+  'Select all'                  => 'Ñ¡ÔñÈ«²¿',
+  'Select postscript or PDF!'   => 'Ñ¡Ôñ postscript »ò PDF!',
+  'Sep'                         => '¾ÅÔÂ',
+  'September'                   => '¾ÅÔÂ',
+  'Source'                      => 'À´Ô´',
+  'Standard'                    => '±ê×¼',
+  'Statement'                   => 'ÕÊÄ¿³ÂÊö',
+  'Statement sent to'           => 'ÕÊÄ¿³ÂÊöË͵½',
+  'Statements sent to printer!' => 'ÕÊÄ¿³ÂÊöË͵½Ó¡±í»ú!',
+  'Subject'                     => '±êÌâ',
+  'Subtotal'                    => 'С¼Æ',
+  'Tax'                         => 'Ë°½ð',
+  'Tax collected'               => 'ÊÕµ½µÄË°',
+  'Tax paid'                    => 'Ö§¸¶µÄË°',
+  'Total'                       => '×ܼÆ',
+  'Trial Balance'               => 'ÊÔËã±í',
+  'Vendor'                      => '³§ÉÌ',
+  'as at'                       => '¸ù¾Ý',
+  'collected on sales'          => 'ÔÚÏú»õʱ½áÇå',
+  'for Period'                  => 'ÆÚ¼ä',
+  'paid on purchases'           => 'ÔڲɹºÊ±½áÇå',
+  'to'                          => 'ÖÁ',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_accounts'               => 'list_accounts',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  '¼ÌÐø'                        => 'continue',
+  'µç×ÓÓʼþ'                    => 'e_mail',
+  'ӡˢ'                        => 'print',
+  'Ñ¡ÔñÈ«²¿'                    => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/COPYING b/sql-ledger/locale/ct/COPYING
new file mode 100644 (file)
index 0000000..fbb7b61
--- /dev/null
@@ -0,0 +1,21 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (C) 2002
+#
+# Catalan Translation:
+#
+#  Author: Jaume Teixi <teixi@rocacorbit.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+######################################################################
diff --git a/sql-ledger/locale/ct/LANGUAGE b/sql-ledger/locale/ct/LANGUAGE
new file mode 100644 (file)
index 0000000..f37af43
--- /dev/null
@@ -0,0 +1 @@
+Catalan
diff --git a/sql-ledger/locale/ct/admin b/sql-ledger/locale/ct/admin
new file mode 100644 (file)
index 0000000..a394d28
--- /dev/null
@@ -0,0 +1,122 @@
+$self{texts} = {
+  'Access Control'              => 'Control d\'Accés',
+  'Accounting'                  => 'Comptabilitat',
+  'Add User'                    => 'Afegir Usuari',
+  'Address'                     => 'Adreça',
+  'Administration'              => 'Administració',
+  'Administrator'               => 'Administrator',
+  'All Datasets up to date!'    => 'Totes les Base de Dades Actualitzades!',
+  'Change Admin Password'       => 'Canviar la contrasenya de l\'administrador',
+  'Change Password'             => 'Canviar contrasenya',
+  'Character Set'               => 'Canviar Tipus Caràcters',
+  'Click on login name to edit!' => 'Clicar en el nom d\'accés per editar',
+  'Company'                     => 'Empresa',
+  'Connect to'                  => 'Connectar a',
+  'Continue'                    => 'Continuar',
+  'Create Chart of Accounts'    => 'Crear la Taula de Comptes',
+  'Create Dataset'              => 'Crear el Conjunt de Dades',
+  'DBI not installed!'          => 'DBI no instal.lat',
+  'Database'                    => 'Base de Dades',
+  'Database Administration'     => 'Administrar Base de Dades',
+  'Database Driver not checked!' => 'Mòdul de la Base de Dades no comprovat!',
+  'Database User missing!'      => 'Falta el usuari de la Base de Dades!',
+  'Dataset'                     => 'Conjunt de Dades',
+  'Dataset missing!'            => 'Falta el Conjunt de Dades',
+  'Dataset updated!'            => 'Dataset updated!',
+  'Date Format'                 => 'Format Data',
+  'Delete'                      => 'Esborrar',
+  'Delete Dataset'              => 'Esborrar Conjunt de Dades',
+  'Directory'                   => 'Directori',
+  'Driver'                      => 'Mòdul',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'Email',
+  'Edit User'                   => 'Editar Usuari',
+  'Existing Datasets'           => 'Conjunt de Dades Existents',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Servidor',
+  'Hostname missing!'           => 'Falta el Nom del Servidor!',
+  'Incorrect Password!'         => 'Contrasenya no Vàlida!',
+  'Language'                    => 'Idioma',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Deixar en blanc el servidor i el port excepte per fer una connexió remota',
+  'Login'                       => 'Entrar',
+  'Name'                        => 'Nom',
+  'New Templates'               => 'Noves Plantilles',
+  'No Database Drivers available!' => 'Cap Mòdul de Base de Dades disponible!',
+  'No Dataset selected!'        => 'No hi ha cap Conjunt de Dades seleccionat!',
+  'Nothing to delete!'          => 'No hi ha res per esborrar!',
+  'Number Format'               => 'Format Número',
+  'Oracle Database Administration' => 'Administració Base de Dades Oracle',
+  'Password'                    => 'Contrasenya',
+  'Password changed!'           => 'Password changed!',
+  'Pg Database Administration'  => 'Administració Base de Dades PostgreSQL',
+  'Phone'                       => 'Tel',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Falta Port!',
+  'Printer'                     => 'Impressora',
+  'Save'                        => 'Guardar',
+  'Select a Dataset to delete and press "Continue"' => 'Seleccionar Conjunt de Dades a esborrar i prèmer "Continuar"',
+  'Setup Templates'             => 'Configurar Plantilles',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'Signatura',
+  'Stylesheet'                  => 'Fulla Estils',
+  'Templates'                   => 'Plantilles',
+  'The following Datasets are not in use and can be deleted' => 'Els següents conjunt de dades no s\'usen i poden esborrar-se',
+  'The following Datasets need to be updated' => 'Cal actualitzar els següents conjunt de dades',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Comprovació preliminar de les fonts existents. No es crearà ni s\'esborrra res en aquest punt!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Per afegir un usuari a un grup, editar el nom, canviar el nom d\'accés i guardar. Un nou usuari amb les mateixes variables es guardarà amb el nou nom d\«accés',
+  'Update Dataset'              => 'Actualitzar Conjut de Dades',
+  'Use Templates'               => 'Emprar Plantilles',
+  'User'                        => 'Usuari',
+  'User deleted!'               => 'User deleted!',
+  'User saved!'                 => 'User saved!',
+  'Version'                     => 'Versió',
+  'You must enter a host and port for local and remote connections!' => 'Heu d\'entrar el servidor i el port per les connexions locals i remotes!',
+  'does not exist'              => 'no existeix',
+  'is already a member!'        => 'ja és membre!',
+  'localhost'                   => 'màquina local',
+  'successfully created!'       => 'creat correctament!',
+  'successfully deleted!'       => 'esborrat correctament!',
+  'website'                     => 'web',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'afegir_usuari'               => 'add_user',
+  'canviar_la_contrasenya_de_l\'administrador' => 'change_admin_password',
+  'canviar_contrasenya'         => 'change_password',
+  'continuar'                   => 'continue',
+  'crear_el_conjunt_de_dades'   => 'create_dataset',
+  'esborrar'                    => 'delete',
+  'esborrar_conjunt_de_dades'   => 'delete_dataset',
+  'entrar'                      => 'login',
+  'administració_base_de_dades_oracle' => 'oracle_database_administration',
+  'administració_base_de_dades_postgresql' => 'pg_database_administration',
+  'guardar'                     => 'save',
+  'actualitzar_conjut_de_dades' => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/all b/sql-ledger/locale/ct/all
new file mode 100644 (file)
index 0000000..c2c9327
--- /dev/null
@@ -0,0 +1,487 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Despeses',
+  'AP Aging'                    => 'Diari de Despeses',
+  'AP Transaction'              => '',
+  'AP Transactions'             => 'Transaccions de Despeses',
+  'AR'                          => 'Ingressos',
+  'AR Aging'                    => 'Diari d\'Ingressos',
+  'AR Transaction'              => '',
+  'AR Transactions'             => 'Transaccions d\'Ingressos',
+  'About'                       => 'Referent',
+  'Access Control'              => 'Control d\'Accés',
+  'Account'                     => 'Compta',
+  'Account Number'              => 'Num. Compta',
+  'Account Number missing!'     => 'Falta el Num. Compta!',
+  'Account Type'                => 'Tipus de Compta',
+  'Account Type missing!'       => 'Falta el Tipus de Compta!',
+  'Account deleted!'            => '',
+  'Account saved!'              => '',
+  'Accounting'                  => 'Comptabilitat',
+  'Accounting Menu'             => 'Menú Comptable',
+  'Accounts'                    => '',
+  'Active'                      => '',
+  'Add'                         => 'Afegir',
+  'Add Account'                 => 'Afegir Compta',
+  'Add Accounts Payables Transaction' => '',
+  'Add Accounts Receivables Transaction' => '',
+  'Add Assembly'                => 'Afegir Compost',
+  'Add Customer'                => 'Afegir Client',
+  'Add GIFI'                    => '',
+  'Add General Ledger Transaction' => 'Afegir Transacció Llibre Major',
+  'Add Part'                    => 'Afegir Article',
+  'Add Project'                 => '',
+  'Add Purchase Invoice'        => '',
+  'Add Purchase Order'          => 'Afegir Ordre Compra',
+  'Add Sales Invoice'           => '',
+  'Add Sales Order'             => 'Afegir Pressupost',
+  'Add Service'                 => 'Afegir Servei',
+  'Add Transaction'             => 'Afegir Transacció',
+  'Add User'                    => 'Afegir Usuari',
+  'Add Vendor'                  => 'Afegir Proveïdor',
+  'Address'                     => 'Adreça',
+  'Administration'              => 'Administració',
+  'Administrator'               => '',
+  'All'                         => 'Tots',
+  'All Datasets up to date!'    => 'Totes les Base de Dades Actualitzades!',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => '',
+  'Amount does not equal applied!' => '',
+  'Amount missing!'             => '',
+  'Applied'                     => '',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => 'Segur que voleu esborrar la Fra. Num.',
+  'Are you sure you want to delete Order Number' => 'Segur que voleu esborrar l\'Ordre',
+  'Are you sure you want to delete Transaction' => 'Segur que voleu esborrar la Transacció',
+  'Assemblies'                  => 'Compostos',
+  'Assemblies restocked!'       => '',
+  'Assembly Number missing!'    => 'Falta el Num. del Compost',
+  'Asset'                       => 'Activat',
+  'Attachment'                  => 'Adjunt',
+  'Audit Control'               => 'Control Auditoria',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agost',
+  'BOM'                         => '',
+  'Backup'                      => 'Còpia de Seguretat',
+  'Backup sent to'              => 'Còpia de Seguretat enviada a',
+  'Balance'                     => '',
+  'Balance Sheet'               => 'Fulla de Balanç',
+  'Bcc'                         => '',
+  'Bin'                         => 'Bin',
+  'Books are open'              => 'Els Llibres estan Oberts',
+  'Bought'                      => 'Comprat',
+  'Business Number'             => 'Núm. Negoci',
+  'C'                           => '',
+  'COGS'                        => 'Cost de Preu',
+  'Cannot delete account!'      => '',
+  'Cannot delete customer!'     => '',
+  'Cannot delete default account!' => 'No es pot esborrar la compta per defecte!',
+  'Cannot delete invoice!'      => '',
+  'Cannot delete item already invoiced!' => 'No es pot esborrar un element facturat!',
+  'Cannot delete item on order!' => 'No es pot esborrar un element pressupostat!',
+  'Cannot delete item which is part of an assembly!' => 'No es pot eliminar un element que és part d\'un compost',
+  'Cannot delete item!'         => '',
+  'Cannot delete order!'        => '',
+  'Cannot delete transaction!'  => '',
+  'Cannot delete vendor!'       => '',
+  'Cannot have a value in both Debit and Credit!' => 'No es pot tenir un valor simultàniament a Dèbit i a Crèdit',
+  'Cannot post a transaction without a value!' => '',
+  'Cannot post invoice for a closed period!' => '',
+  'Cannot post invoice!'        => '',
+  'Cannot post payment for a closed period!' => '',
+  'Cannot post payment!'        => '',
+  'Cannot post transaction for a closed period!' => 'No es pot registrar una transacció per un període tancat',
+  'Cannot post transaction!'    => '',
+  'Cannot process payment for a closed period!' => '',
+  'Cannot save account!'        => '',
+  'Cannot save order!'          => '',
+  'Cannot save preferences!'    => '',
+  'Cannot stock assemblies!'    => '',
+  'Cash'                        => '',
+  'Cash based'                  => '',
+  'Cc'                          => '',
+  'Change Admin Password'       => 'Canviar la contrasenya de l\'administrador',
+  'Change Password'             => 'Canviar contrasenya',
+  'Character Set'               => 'Canviar Tipus Caràcters',
+  'Chart of Accounts'           => 'Taula de Comptes',
+  'Check'                       => '',
+  'Check printed!'              => '',
+  'Check printing failed!'      => '',
+  'Cleared Balance'             => '',
+  'Click on login name to edit!' => 'Clicar en el nom d\'accés per editar',
+  'Close Books up to'           => 'Tancar els llibres fins',
+  'Closed'                      => 'Tancat',
+  'Company'                     => 'Empresa',
+  'Compare to'                  => 'Comparar amb',
+  'Confirm!'                    => 'Confirmar!',
+  'Connect to'                  => 'Connectar a',
+  'Contact'                     => 'Contacte',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Còpies',
+  'Copy to COA'                 => '',
+  'Create Chart of Accounts'    => 'Crear la Taula de Comptes',
+  'Create Dataset'              => 'Crear el Conjunt de Dades',
+  'Credit'                      => 'Crèdit',
+  'Credit Limit'                => 'Límit de Crèdit',
+  'Curr'                        => '',
+  'Currency'                    => 'Moneda',
+  'Current'                     => '',
+  'Customer'                    => 'Client',
+  'Customer deleted!'           => '',
+  'Customer missing!'           => '',
+  'Customer not on file!'       => '',
+  'Customer saved!'             => '',
+  'Customers'                   => '',
+  'DBI not installed!'          => 'DBI no instal.lat',
+  'Database'                    => 'Base de Dades',
+  'Database Administration'     => 'Administrar Base de Dades',
+  'Database Driver not checked!' => 'Mòdul de la Base de Dades no comprovat!',
+  'Database Host'               => 'Servidor Base de Dades',
+  'Database User missing!'      => 'Falta el usuari de la Base de Dades!',
+  'Dataset'                     => 'Conjunt de Dades',
+  'Dataset missing!'            => 'Falta el Conjunt de Dades',
+  'Dataset updated!'            => '',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Data Venciment',
+  'Date Format'                 => 'Format Data',
+  'Date Paid'                   => 'Data Pagament',
+  'Date missing!'               => '',
+  'Debit'                       => 'Dèbit',
+  'Debit and credit out of balance!' => 'Dèbit i Crèdit fora de balanç!',
+  'Dec'                         => 'Des',
+  'December'                    => 'Desembre',
+  'Decimalplaces'               => '',
+  'Delete'                      => 'Esborrar',
+  'Delete Account'              => 'Esborrar Compta',
+  'Delete Dataset'              => 'Esborrar Conjunt de Dades',
+  'Delivery Date'               => '',
+  'Deposit'                     => '',
+  'Description'                 => 'Descripció',
+  'Difference'                  => '',
+  'Directory'                   => 'Directori',
+  'Discount'                    => 'Descompte',
+  'Done'                        => '',
+  'Drawing'                     => '',
+  'Driver'                      => 'Mòdul',
+  'Dropdown Limit'              => '',
+  'Due'                         => 'Venciment',
+  'Due Date'                    => 'Data Venciment',
+  'Due Date missing!'           => 'Falta la Data Venciment!',
+  'E-mail'                      => 'Email',
+  'E-mail Statement to'         => '',
+  'E-mail address missing!'     => 'Falta Email!',
+  'Edit'                        => '',
+  'Edit Account'                => 'Editar Compta',
+  'Edit Accounts Payables Transaction' => '',
+  'Edit Accounts Receivables Transaction' => '',
+  'Edit Assembly'               => 'Editar Compost',
+  'Edit GIFI'                   => '',
+  'Edit General Ledger Transaction' => 'Editar Transacció del LLibre Major',
+  'Edit Part'                   => 'Editar Article',
+  'Edit Preferences for'        => 'Editar Preferències per',
+  'Edit Project'                => '',
+  'Edit Purchase Invoice'       => '',
+  'Edit Purchase Order'         => 'Editar Ordre Compra',
+  'Edit Sales Invoice'          => '',
+  'Edit Sales Order'            => 'Editar Pressupost',
+  'Edit Service'                => 'Editar Servei',
+  'Edit Template'               => 'Editar Plantilla',
+  'Edit User'                   => 'Editar Usuari',
+  'Employee'                    => '',
+  'Enforce transaction reversal for all dates' => 'Forçar l\'anul.lació de transaccions per totes les dates',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Entrar fins a 3 caràcters separats per dos punts (p.e. EUR:USD:CAD) per les monedes nacionals i estrangeres',
+  'Equity'                      => 'Balanç',
+  'Exch'                        => 'Canvi',
+  'Exchangerate'                => 'Taxa de Canvi',
+  'Exchangerate Difference'     => '',
+  'Exchangerate for payment missing!' => '',
+  'Exchangerate missing!'       => '',
+  'Existing Datasets'           => 'Conjunt de Dades Existents',
+  'Expense'                     => 'Despeses',
+  'Expense Account'             => 'Compta Despeses',
+  'Expense/Asset'               => 'Despesa/Activa',
+  'Extended'                    => '',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrer',
+  'Foreign Exchange Gain'       => 'Guany en Bescanvi Moneda',
+  'Foreign Exchange Loss'       => 'Pèrdua en Bescanvi Moneda',
+  'From'                        => 'De',
+  'GIFI'                        => '',
+  'GIFI deleted!'               => '',
+  'GIFI missing!'               => '',
+  'GIFI saved!'                 => '',
+  'GL Transaction'              => '',
+  'General Ledger'              => 'Llibre Major',
+  'Goods & Services'            => 'Bèns i Serveis',
+  'HTML Templates'              => 'Plantilles HTML',
+  'Heading'                     => 'Capçalera',
+  'Host'                        => 'Servidor',
+  'Hostname missing!'           => 'Falta el Nom del Servidor!',
+  'ID'                          => 'ID',
+  'Image'                       => '',
+  'In-line'                     => 'Afegit',
+  'Include in Report'           => 'Incloure en l\'Informe',
+  'Include in drop-down menus'  => 'Incloure en Menús Desplegables',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Incloure aquesta compta en els formularis client/proveïdor per marcar els impostos aplicables client/proveïdor?',
+  'Income'                      => 'Ingressos',
+  'Income Account'              => 'Compta Ingressos',
+  'Income Statement'            => 'Balanç Situació',
+  'Incorrect Dataset version!'  => 'Versió Incorrecta del Conjunt de Dades!',
+  'Incorrect Password!'         => 'Contrasenya no Vàlida!',
+  'Individual Items'            => 'Elements Individuals',
+  'Inventory'                   => 'Inventari',
+  'Inventory Account'           => 'Compta Inventari',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'La quantitat en l\'inventari ha de ser zero abans de marcar-lo com obsolet',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'La quantitat en l\'inventari ha de ser zero abans de marcar-lo com obsolet',
+  'Inventory quantity must be zero!' => 'La quantitat en l\'inventari ha de ser zero',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Data Fra.',
+  'Invoice Date missing!'       => 'Falta Data Fra.!',
+  'Invoice Number'              => 'Núm Fra.',
+  'Invoice Number missing!'     => 'Falta Núm Fra.!',
+  'Invoice deleted!'            => '',
+  'Invoice posted!'             => '',
+  'Invoices'                    => '',
+  'Is this a summary account to record' => 'És una compta resum a registrar?',
+  'Item deleted!'               => '',
+  'Item not on file!'           => 'No es troba cap arxiu amb aquest element!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gener',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juliol',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juny',
+  'LaTeX Templates'             => 'Plantilles LaTeX',
+  'Language'                    => 'Idioma',
+  'Last Cost'                   => 'Darrer Cost',
+  'Last Invoice Number'         => 'Darrer Núm Fra.',
+  'Last Numbers & Default Accounts' => 'Darrers Núms & Comptes per Defecte',
+  'Last Purchase Order Number'  => 'Darrera Ordre de Compra',
+  'Last Sales Order Number'     => '',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Deixar en blanc el servidor i el port excepte per fer una connexió remota',
+  'Liability'                   => 'Passiu',
+  'Licensed to'                 => 'Adaptat per',
+  'Line Total'                  => 'Total Línia',
+  'Link'                        => 'Enllaç',
+  'Link Accounts'               => 'Enllaçar Comptes',
+  'List Accounts'               => 'Llistar Comptes',
+  'List GIFI'                   => '',
+  'List Price'                  => 'Llistar Preu',
+  'List Transactions'           => 'Llistar Transaccions',
+  'Login'                       => 'Entrar',
+  'Logout'                      => 'Desconnectar',
+  'Make'                        => 'Fer',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Març',
+  'May'                         => 'Mai',
+  'May '                        => 'Maig',
+  'Message'                     => '',
+  'Microfiche'                  => '',
+  'Model'                       => 'Model',
+  'N/A'                         => '',
+  'Name'                        => 'Nom',
+  'Name missing!'               => '',
+  'New Templates'               => 'Noves Plantilles',
+  'No'                          => 'No',
+  'No Database Drivers available!' => 'Cap Mòdul de Base de Dades disponible!',
+  'No Dataset selected!'        => 'No hi ha cap Conjunt de Dades seleccionat!',
+  'No email address for'        => 'Falta adreça email de',
+  'No.'                         => '',
+  'Notes'                       => 'Notes',
+  'Nothing applied!'            => '',
+  'Nothing selected!'           => '',
+  'Nothing to delete!'          => 'No hi ha res per esborrar!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Format Número',
+  'Number missing in Row'       => 'Falta en número en la fila',
+  'O'                           => '',
+  'Obsolete'                    => 'Obsolet',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'On Hand'                     => 'Disponible',
+  'On Order'                    => '',
+  'Open'                        => 'Obert',
+  'Oracle Database Administration' => 'Administració Base de Dades Oracle',
+  'Order'                       => 'Ordre',
+  'Order Date'                  => 'Data Ordre',
+  'Order Date missing!'         => 'Falta Data Ordre!',
+  'Order Entry'                 => 'Pressupostos i Comandes',
+  'Order Number'                => 'Número Ordre',
+  'Order Number missing!'       => 'Falta Número Ordre!',
+  'Order deleted!'              => '',
+  'Order saved!'                => '',
+  'Ordered'                     => '',
+  'Orphaned'                    => 'Orfe',
+  'Out of balance!'             => '',
+  'PDF'                         => '',
+  'Packing List'                => 'Albarà',
+  'Packing List Date missing!'  => 'Falta Data Albarà!',
+  'Packing List Number missing!' => 'Falta Número Albarà!',
+  'Paid'                        => 'Pagat',
+  'Paid in full'                => '',
+  'Part'                        => 'Article',
+  'Part Number missing!'        => 'Falta Número Article!',
+  'Parts'                       => 'Articles',
+  'Parts Inventory'             => 'Inventari Articles',
+  'Password'                    => 'Contrasenya',
+  'Password changed!'           => '',
+  'Payables'                    => 'Pagables',
+  'Payment'                     => 'Pagament',
+  'Payment date missing!'       => 'Falta Data Pagament!',
+  'Payment posted!'             => '',
+  'Payments'                    => 'Pagaments',
+  'Pg Database Administration'  => 'Administració Base de Dades PostgreSQL',
+  'Phone'                       => 'Tel',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Falta Port!',
+  'Post'                        => '',
+  'Post as new'                 => '',
+  'Postscript'                  => '',
+  'Preferences'                 => 'Preferències',
+  'Preferences saved!'          => 'Preferències Guardades!',
+  'Price'                       => 'Preu',
+  'Print'                       => '',
+  'Printer'                     => 'Impressora',
+  'Project'                     => '',
+  'Project Number missing!'     => '',
+  'Project deleted!'            => '',
+  'Project not on file!'        => '',
+  'Project saved!'              => '',
+  'Projects'                    => '',
+  'Purchase Invoice'            => '',
+  'Purchase Order'              => 'Ordre de Compra',
+  'Purchase Orders'             => 'Ordres de Compra',
+  'Qty'                         => 'Quantitat',
+  'ROP'                         => 'ROP',
+  'Rate'                        => 'Tarifa',
+  'Recd'                        => '',
+  'Receipt'                     => '',
+  'Receipts'                    => '',
+  'Receivables'                 => 'Cobraments',
+  'Reconciliation'              => '',
+  'Record in'                   => 'Registar en',
+  'Reference'                   => '',
+  'Reference missing!'          => '',
+  'Remaining'                   => 'Remanent',
+  'Report for'                  => 'Registrar per',
+  'Reports'                     => 'Informes',
+  'Required by'                 => 'Soliciat per',
+  'Retained Earnings'           => 'Guanys Retinguts',
+  'Sales'                       => 'Vendes',
+  'Sales Invoice'               => '',
+  'Sales Order'                 => 'Pressupost',
+  'Sales Orders'                => 'Pressupostos',
+  'Save'                        => 'Guardar',
+  'Save as new'                 => '',
+  'Save to File'                => 'Guardar a Fitxer',
+  'Screen'                      => 'Pantalla',
+  'Select a Dataset to delete and press "Continue"' => 'Seleccionar Conjunt de Dades a esborrar i prèmer "Continuar"',
+  'Select all'                  => '',
+  'Select from one of the items below' => 'Seleccionar d\'un dels elements de sota',
+  'Select from one of the names below' => '',
+  'Select from one of the projects below' => '',
+  'Select postscript or PDF!'   => '',
+  'Sell Price'                  => 'Preu Venta',
+  'Send by E-Mail'              => 'Enviar per Email',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembre',
+  'Service'                     => 'Servei',
+  'Service Items'               => 'Elements Servei',
+  'Service Number missing!'     => 'Falta Nombre Servei!',
+  'Services'                    => 'Serveis',
+  'Setup Templates'             => 'Configurar Plantilles',
+  'Ship'                        => '',
+  'Ship to'                     => '',
+  'Ship via'                    => '',
+  'Short'                       => 'Curt',
+  'Signature'                   => 'Signatura',
+  'Sold'                        => 'Venut',
+  'Source'                      => 'Font',
+  'Standard'                    => '',
+  'Statement'                   => '',
+  'Statement Balance'           => '',
+  'Statement sent to'           => '',
+  'Statements sent to printer!' => '',
+  'Stock Assembly'              => 'Inventari Compost',
+  'Stylesheet'                  => 'Fulla Estils',
+  'Subject'                     => '',
+  'Subtotal'                    => 'Subtotal',
+  'System'                      => 'Sistema',
+  'Tax'                         => 'Impost',
+  'Tax Accounts'                => 'Comptes Impostos',
+  'Tax Included'                => 'Impostos Inclosos',
+  'Tax collected'               => '',
+  'Tax paid'                    => '',
+  'Taxable'                     => 'Imponible',
+  'Template saved!'             => '',
+  'Templates'                   => 'Plantilles',
+  'Terms: Net'                  => 'Terms:Net',
+  'The following Datasets are not in use and can be deleted' => 'Els següents conjunt de dades no s\'usen i poden esborrar-se',
+  'The following Datasets need to be updated' => 'Cal actualitzar els següents conjunt de dades',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Comprovació preliminar de les fonts existents. No es crearà ni s\'esborrra res en aquest punt!',
+  'To'                          => 'Fins',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Per afegir un usuari a un grup, editar el nom, canviar el nom d\'accés i guardar. Un nou usuari amb les mateixes variables es guardarà amb el nou nom d\«accés',
+  'Top Level'                   => '',
+  'Total'                       => 'Total',
+  'Transaction Date missing!'   => 'Falta Data Transacció!',
+  'Transaction deleted!'        => '',
+  'Transaction posted!'         => '',
+  'Transaction reversal enforced for all dates' => 'Anul.lació transaccions forçada per totes les dates',
+  'Transaction reversal enforced up to' => 'Anul.lació transaccions forçada a',
+  'Transactions'                => 'Transaccions',
+  'Transactions exist, cannot delete customer!' => 'Hi han transaccions, no esborrar el client!',
+  'Transactions exist, cannot delete vendor!' => 'Hi han transaccions, no esborrar el proveïdor',
+  'Transactions exist; cannot delete account!' => 'Hi han transaccions, no esborrar compta',
+  'Trial Balance'               => 'Balanç de Comprovació',
+  'Unit'                        => 'Unitat',
+  'Unit of measure'             => 'Unitat de Mesura',
+  'Update'                      => '',
+  'Update Dataset'              => 'Actualitzar Conjut de Dades',
+  'Updated'                     => '',
+  'Use Templates'               => 'Emprar Plantilles',
+  'User'                        => 'Usuari',
+  'User deleted!'               => '',
+  'User saved!'                 => '',
+  'Vendor'                      => 'Proveïdor',
+  'Vendor deleted!'             => '',
+  'Vendor missing!'             => '',
+  'Vendor not on file!'         => '',
+  'Vendor saved!'               => '',
+  'Vendors'                     => '',
+  'Version'                     => 'Versió',
+  'Weight'                      => 'Pes',
+  'Weight Unit'                 => 'Unitat Pes',
+  'What type of item is this?'  => 'Quin tipus d\'element és?',
+  'Year End'                    => 'Fí Any',
+  'Yes'                         => 'Sí',
+  'You are logged out!'         => '',
+  'You did not enter a name!'   => 'No heu entrat cap nom!',
+  'You must enter a host and port for local and remote connections!' => 'Heu d\'entrar el servidor i el port per les connexions locals i remotes!',
+  'as at'                       => '',
+  'collected on sales'          => 'recollit en vendes',
+  'days'                        => 'dies',
+  'does not exist'              => 'no existeix',
+  'ea'                          => 'unit.',
+  'emailed to'                  => 'emailejat a',
+  'for Period'                  => 'pel període',
+  'hr'                          => 'hr',
+  'is already a member!'        => 'ja és membre!',
+  'is not a member!'            => 'no és membre!',
+  'localhost'                   => 'màquina local',
+  'paid on purchases'           => 'pagat al comprat',
+  'sent to printer'             => 'enviat a impressora',
+  'successfully created!'       => 'creat correctament!',
+  'successfully deleted!'       => 'esborrat correctament!',
+  'to'                          => '',
+  'website'                     => 'web',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/am b/sql-ledger/locale/ct/am
new file mode 100644 (file)
index 0000000..6dc7a2c
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Despeses',
+  'AR'                          => 'Ingressos',
+  'Account'                     => 'Compta',
+  'Account Number'              => 'Num. Compta',
+  'Account Number missing!'     => 'Falta el Num. Compta!',
+  'Account Type'                => 'Tipus de Compta',
+  'Account Type missing!'       => 'Falta el Tipus de Compta!',
+  'Account deleted!'            => 'Account deleted!',
+  'Account saved!'              => 'Account saved!',
+  'Add Account'                 => 'Afegir Compta',
+  'Add GIFI'                    => 'Add GIFI',
+  'Address'                     => 'Adreça',
+  'Asset'                       => 'Activat',
+  'Audit Control'               => 'Control Auditoria',
+  'Backup sent to'              => 'Còpia de Seguretat enviada a',
+  'Books are open'              => 'Els Llibres estan Oberts',
+  'Business Number'             => 'Núm. Negoci',
+  'COGS'                        => 'Cost de Preu',
+  'Cannot delete account!'      => 'Cannot delete account!',
+  'Cannot delete default account!' => 'No es pot esborrar la compta per defecte!',
+  'Cannot save account!'        => 'Cannot save account!',
+  'Cannot save preferences!'    => 'Cannot save preferences!',
+  'Character Set'               => 'Canviar Tipus Caràcters',
+  'Chart of Accounts'           => 'Taula de Comptes',
+  'Close Books up to'           => 'Tancar els llibres fins',
+  'Company'                     => 'Empresa',
+  'Continue'                    => 'Continuar',
+  'Copy to COA'                 => 'Copy to COA',
+  'Credit'                      => 'Crèdit',
+  'Date Format'                 => 'Format Data',
+  'Debit'                       => 'Dèbit',
+  'Delete'                      => 'Esborrar',
+  'Delete Account'              => 'Esborrar Compta',
+  'Description'                 => 'Descripció',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'Email',
+  'Edit'                        => 'Edit',
+  'Edit Account'                => 'Editar Compta',
+  'Edit GIFI'                   => 'Edit GIFI',
+  'Edit Preferences for'        => 'Editar Preferències per',
+  'Edit Template'               => 'Editar Plantilla',
+  'Enforce transaction reversal for all dates' => 'Forçar l\'anul.lació de transaccions per totes les dates',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Entrar fins a 3 caràcters separats per dos punts (p.e. EUR:USD:CAD) per les monedes nacionals i estrangeres',
+  'Equity'                      => 'Balanç',
+  'Expense'                     => 'Despeses',
+  'Expense Account'             => 'Compta Despeses',
+  'Expense/Asset'               => 'Despesa/Activa',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Guany en Bescanvi Moneda',
+  'Foreign Exchange Loss'       => 'Pèrdua en Bescanvi Moneda',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI deleted!',
+  'GIFI missing!'               => 'GIFI missing!',
+  'GIFI saved!'                 => 'GIFI saved!',
+  'Heading'                     => 'Capçalera',
+  'Include in drop-down menus'  => 'Incloure en Menús Desplegables',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Incloure aquesta compta en els formularis client/proveïdor per marcar els impostos aplicables client/proveïdor?',
+  'Income'                      => 'Ingressos',
+  'Income Account'              => 'Compta Ingressos',
+  'Inventory'                   => 'Inventari',
+  'Inventory Account'           => 'Compta Inventari',
+  'Is this a summary account to record' => 'És una compta resum a registrar?',
+  'Language'                    => 'Idioma',
+  'Last Invoice Number'         => 'Darrer Núm Fra.',
+  'Last Numbers & Default Accounts' => 'Darrers Núms & Comptes per Defecte',
+  'Last Purchase Order Number'  => 'Darrera Ordre de Compra',
+  'Last Sales Order Number'     => 'Last Sales Order Number',
+  'Liability'                   => 'Passiu',
+  'Link'                        => 'Enllaç',
+  'Name'                        => 'Nom',
+  'No'                          => 'No',
+  'No email address for'        => 'Falta adreça email de',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Format Número',
+  'Parts Inventory'             => 'Inventari Articles',
+  'Password'                    => 'Contrasenya',
+  'Payables'                    => 'Pagables',
+  'Payment'                     => 'Pagament',
+  'Phone'                       => 'Tel',
+  'Preferences saved!'          => 'Preferències Guardades!',
+  'Rate'                        => 'Tarifa',
+  'Receivables'                 => 'Cobraments',
+  'Sales'                       => 'Vendes',
+  'Save'                        => 'Guardar',
+  'Service Items'               => 'Elements Servei',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'Signatura',
+  'Stylesheet'                  => 'Fulla Estils',
+  'Tax'                         => 'Impost',
+  'Tax Accounts'                => 'Comptes Impostos',
+  'Template saved!'             => 'Template saved!',
+  'Transaction reversal enforced for all dates' => 'Anul.lació transaccions forçada per totes les dates',
+  'Transaction reversal enforced up to' => 'Anul.lació transaccions forçada a',
+  'Transactions exist; cannot delete account!' => 'Hi han transaccions, no esborrar compta',
+  'Weight Unit'                 => 'Unitat Pes',
+  'Year End'                    => 'Fí Any',
+  'Yes'                         => 'Sí',
+  'does not exist'              => 'no existeix',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'afegir_compta'               => 'add_account',
+  'continuar'                   => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'esborrar'                    => 'delete',
+  'edit'                        => 'edit',
+  'editar_compta'               => 'edit_account',
+  'guardar'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/ap b/sql-ledger/locale/ct/ap
new file mode 100644 (file)
index 0000000..7520fd0
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AP Transactions'             => 'Transaccions de Despeses',
+  'Account'                     => 'Compta',
+  'Add Accounts Payables Transaction' => 'Add Accounts Payables Transaction',
+  'Address'                     => 'Adreça',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => 'Segur que voleu esborrar la Transacció',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agost',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cannot post transaction for a closed period!' => 'No es pot registrar una transacció per un període tancat',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'Tancat',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Moneda',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Data',
+  'Date Paid'                   => 'Data Pagament',
+  'Dec'                         => 'Des',
+  'December'                    => 'Desembre',
+  'Delete'                      => 'Esborrar',
+  'Description'                 => 'Descripció',
+  'Due Date'                    => 'Data Venciment',
+  'Due Date missing!'           => 'Falta la Data Venciment!',
+  'Edit Accounts Payables Transaction' => 'Edit Accounts Payables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'Canvi',
+  'Exchangerate'                => 'Taxa de Canvi',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrer',
+  'From'                        => 'De',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incloure en l\'Informe',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Data Fra.',
+  'Invoice Date missing!'       => 'Falta Data Fra.!',
+  'Invoice Number'              => 'Núm Fra.',
+  'Invoice Number missing!'     => 'Falta Núm Fra.!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gener',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juliol',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juny',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Març',
+  'May'                         => 'Mai',
+  'May '                        => 'Maig',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Open'                        => 'Obert',
+  'Order'                       => 'Ordre',
+  'Order Number'                => 'Número Ordre',
+  'Paid'                        => 'Pagat',
+  'Payment date missing!'       => 'Falta Data Pagament!',
+  'Payments'                    => 'Pagaments',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembre',
+  'Source'                      => 'Font',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impost',
+  'Tax Included'                => 'Impostos Inclosos',
+  'To'                          => 'Fins',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Proveïdor',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Sí',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'add_accounts_payables_transaction' => 'add_accounts_payables_transaction',
+  'continuar'                   => 'continue',
+  'esborrar'                    => 'delete',
+  'edit_accounts_payables_transaction' => 'edit_accounts_payables_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'update'                      => 'update',
+  'sí'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/ar b/sql-ledger/locale/ct/ar
new file mode 100644 (file)
index 0000000..90a111d
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'AR Transaction',
+  'AR Transactions'             => 'Transaccions d\'Ingressos',
+  'Account'                     => 'Compta',
+  'Add Accounts Receivables Transaction' => 'Add Accounts Receivables Transaction',
+  'Address'                     => 'Adreça',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => 'Segur que voleu esborrar la Transacció',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agost',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cannot post transaction for a closed period!' => 'No es pot registrar una transacció per un període tancat',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'Tancat',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Límit de Crèdit',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Client',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Data',
+  'Date Paid'                   => 'Data Pagament',
+  'Dec'                         => 'Des',
+  'December'                    => 'Desembre',
+  'Delete'                      => 'Esborrar',
+  'Description'                 => 'Descripció',
+  'Due Date'                    => 'Data Venciment',
+  'Due Date missing!'           => 'Falta la Data Venciment!',
+  'Edit Accounts Receivables Transaction' => 'Edit Accounts Receivables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'Canvi',
+  'Exchangerate'                => 'Taxa de Canvi',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrer',
+  'From'                        => 'De',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incloure en l\'Informe',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Data Fra.',
+  'Invoice Date missing!'       => 'Falta Data Fra.!',
+  'Invoice Number'              => 'Núm Fra.',
+  'Invoice Number missing!'     => 'Falta Núm Fra.!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gener',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juliol',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juny',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Març',
+  'May'                         => 'Mai',
+  'May '                        => 'Maig',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Open'                        => 'Obert',
+  'Order'                       => 'Ordre',
+  'Order Number'                => 'Número Ordre',
+  'Paid'                        => 'Pagat',
+  'Payment date missing!'       => 'Falta Data Pagament!',
+  'Payments'                    => 'Pagaments',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Remaining'                   => 'Remanent',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembre',
+  'Source'                      => 'Font',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impost',
+  'Tax Included'                => 'Impostos Inclosos',
+  'To'                          => 'Fins',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Sí',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ar_transaction'              => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'esborrar'                    => 'delete',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'sí'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/arap b/sql-ledger/locale/ct/arap
new file mode 100644 (file)
index 0000000..688a019
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Adreça',
+  'Continue'                    => 'Continuar',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Description'                 => 'Descripció',
+  'Number'                      => 'Número',
+  'Project not on file!'        => 'Project not on file!',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/ca b/sql-ledger/locale/ct/ca
new file mode 100644 (file)
index 0000000..89a4023
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Compta',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agost',
+  'Balance'                     => 'Balance',
+  'Chart of Accounts'           => 'Taula de Comptes',
+  'Credit'                      => 'Crèdit',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Dèbit',
+  'Dec'                         => 'Des',
+  'December'                    => 'Desembre',
+  'Description'                 => 'Descripció',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrer',
+  'From'                        => 'De',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Incloure en l\'Informe',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gener',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juliol',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juny',
+  'List Transactions'           => 'Llistar Transaccions',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Març',
+  'May'                         => 'Mai',
+  'May '                        => 'Maig',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Reference'                   => 'Reference',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembre',
+  'Subtotal'                    => 'Subtotal',
+  'To'                          => 'Fins',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'llistar_transaccions'        => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/cp b/sql-ledger/locale/ct/cp
new file mode 100644 (file)
index 0000000..4bb685f
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Compta',
+  'Address'                     => 'Adreça',
+  'Amount'                      => 'Total',
+  'Amount does not equal applied!' => 'Amount does not equal applied!',
+  'Amount missing!'             => 'Amount missing!',
+  'Applied'                     => 'Applied',
+  'Cannot post payment!'        => 'Cannot post payment!',
+  'Cannot process payment for a closed period!' => 'Cannot process payment for a closed period!',
+  'Check'                       => 'Check',
+  'Check printed!'              => 'Check printed!',
+  'Check printing failed!'      => 'Check printing failed!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Client',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Data',
+  'Date missing!'               => 'Date missing!',
+  'Description'                 => 'Descripció',
+  'Due'                         => 'Venciment',
+  'Exchangerate'                => 'Taxa de Canvi',
+  'From'                        => 'De',
+  'Invoice'                     => 'Factura',
+  'Invoices'                    => 'Invoices',
+  'Nothing applied!'            => 'Nothing applied!',
+  'Number'                      => 'Número',
+  'Paid in full'                => 'Paid in full',
+  'Payment'                     => 'Pagament',
+  'Payment posted!'             => 'Payment posted!',
+  'Post'                        => 'Post',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Impressora',
+  'Project not on file!'        => 'Project not on file!',
+  'Receipt'                     => 'Receipt',
+  'Reference'                   => 'Reference',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'To'                          => 'Fins',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Proveïdor',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/ct b/sql-ledger/locale/ct/ct
new file mode 100644 (file)
index 0000000..d88db2a
--- /dev/null
@@ -0,0 +1,69 @@
+$self{texts} = {
+  'Add'                         => 'Afegir',
+  'Address'                     => 'Adreça',
+  'All'                         => 'Tots',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Cannot delete customer!',
+  'Cannot delete vendor!'       => 'Cannot delete vendor!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacte',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Límit de Crèdit',
+  'Customer deleted!'           => 'Customer deleted!',
+  'Customer saved!'             => 'Customer saved!',
+  'Customers'                   => 'Customers',
+  'Delete'                      => 'Esborrar',
+  'Discount'                    => 'Descompte',
+  'E-mail'                      => 'Email',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Incloure en l\'Informe',
+  'Invoice'                     => 'Factura',
+  'Name'                        => 'Nom',
+  'Name missing!'               => 'Name missing!',
+  'Notes'                       => 'Notes',
+  'Number'                      => 'Número',
+  'Order'                       => 'Ordre',
+  'Orphaned'                    => 'Orfe',
+  'Phone'                       => 'Tel',
+  'Save'                        => 'Guardar',
+  'Ship to'                     => 'Ship to',
+  'Tax Included'                => 'Impostos Inclosos',
+  'Taxable'                     => 'Imponible',
+  'Terms: Net'                  => 'Terms:Net',
+  'Transactions exist, cannot delete customer!' => 'Hi han transaccions, no esborrar el client!',
+  'Transactions exist, cannot delete vendor!' => 'Hi han transaccions, no esborrar el proveïdor',
+  'Vendor deleted!'             => 'Vendor deleted!',
+  'Vendor saved!'               => 'Vendor saved!',
+  'Vendors'                     => 'Vendors',
+  'days'                        => 'dies',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'afegir'                      => 'add',
+  'continuar'                   => 'continue',
+  'esborrar'                    => 'delete',
+  'factura'                     => 'invoice',
+  'ordre'                       => 'order',
+  'guardar'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/gl b/sql-ledger/locale/ct/gl
new file mode 100644 (file)
index 0000000..7e25978
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AR Transaction'              => 'AR Transaction',
+  'Account'                     => 'Compta',
+  'Add General Ledger Transaction' => 'Afegir Transacció Llibre Major',
+  'Address'                     => 'Adreça',
+  'All'                         => 'Tots',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => 'Segur que voleu esborrar la Transacció',
+  'Asset'                       => 'Activat',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agost',
+  'Balance'                     => 'Balance',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot have a value in both Debit and Credit!' => 'No es pot tenir un valor simultàniament a Dèbit i a Crèdit',
+  'Cannot post a transaction without a value!' => 'Cannot post a transaction without a value!',
+  'Cannot post transaction for a closed period!' => 'No es pot registrar una transacció per un període tancat',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Credit'                      => 'Crèdit',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Dèbit',
+  'Debit and credit out of balance!' => 'Dèbit i Crèdit fora de balanç!',
+  'Dec'                         => 'Des',
+  'December'                    => 'Desembre',
+  'Delete'                      => 'Esborrar',
+  'Description'                 => 'Descripció',
+  'Edit General Ledger Transaction' => 'Editar Transacció del LLibre Major',
+  'Equity'                      => 'Balanç',
+  'Expense'                     => 'Despeses',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrer',
+  'From'                        => 'De',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'GL Transaction',
+  'General Ledger'              => 'Llibre Major',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incloure en l\'Informe',
+  'Income'                      => 'Ingressos',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gener',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juliol',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juny',
+  'Liability'                   => 'Passiu',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Març',
+  'May'                         => 'Mai',
+  'May '                        => 'Maig',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Reference'                   => 'Reference',
+  'Reference missing!'          => 'Reference missing!',
+  'Reports'                     => 'Informes',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembre',
+  'Source'                      => 'Font',
+  'Subtotal'                    => 'Subtotal',
+  'To'                          => 'Fins',
+  'Transaction Date missing!'   => 'Falta Data Transacció!',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Sí',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'esborrar'                    => 'delete',
+  'gl_transaction'              => 'gl_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'sí'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/ic b/sql-ledger/locale/ct/ic
new file mode 100644 (file)
index 0000000..66c84d7
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Active',
+  'Add'                         => 'Afegir',
+  'Add Assembly'                => 'Afegir Compost',
+  'Add Part'                    => 'Afegir Article',
+  'Add Purchase Order'          => 'Afegir Ordre Compra',
+  'Add Sales Order'             => 'Afegir Pressupost',
+  'Add Service'                 => 'Afegir Servei',
+  'Address'                     => 'Adreça',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Assemblies'                  => 'Compostos',
+  'Assemblies restocked!'       => 'Assemblies restocked!',
+  'Assembly Number missing!'    => 'Falta el Num. del Compost',
+  'Attachment'                  => 'Adjunt',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agost',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Bought'                      => 'Comprat',
+  'COGS'                        => 'Cost de Preu',
+  'Cannot delete item already invoiced!' => 'No es pot esborrar un element facturat!',
+  'Cannot delete item on order!' => 'No es pot esborrar un element pressupostat!',
+  'Cannot delete item which is part of an assembly!' => 'No es pot eliminar un element que és part d\'un compost',
+  'Cannot delete item!'         => 'Cannot delete item!',
+  'Cannot stock assemblies!'    => 'Cannot stock assemblies!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacte',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Còpies',
+  'Dec'                         => 'Des',
+  'December'                    => 'Desembre',
+  'Delete'                      => 'Esborrar',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripció',
+  'Drawing'                     => 'Drawing',
+  'E-mail'                      => 'Email',
+  'E-mail address missing!'     => 'Falta Email!',
+  'Edit Assembly'               => 'Editar Compost',
+  'Edit Part'                   => 'Editar Article',
+  'Edit Service'                => 'Editar Servei',
+  'Expense'                     => 'Despeses',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrer',
+  'From'                        => 'De',
+  'Image'                       => 'Image',
+  'In-line'                     => 'Afegit',
+  'Include in Report'           => 'Incloure en l\'Informe',
+  'Income'                      => 'Ingressos',
+  'Individual Items'            => 'Elements Individuals',
+  'Inventory'                   => 'Inventari',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'La quantitat en l\'inventari ha de ser zero abans de marcar-lo com obsolet',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'La quantitat en l\'inventari ha de ser zero abans de marcar-lo com obsolet',
+  'Inventory quantity must be zero!' => 'La quantitat en l\'inventari ha de ser zero',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Falta Data Fra.!',
+  'Invoice Number'              => 'Núm Fra.',
+  'Invoice Number missing!'     => 'Falta Núm Fra.!',
+  'Item deleted!'               => 'Item deleted!',
+  'Item not on file!'           => 'No es troba cap arxiu amb aquest element!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gener',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juliol',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juny',
+  'Last Cost'                   => 'Darrer Cost',
+  'Line Total'                  => 'Total Línia',
+  'Link Accounts'               => 'Enllaçar Comptes',
+  'List Price'                  => 'Llistar Preu',
+  'Make'                        => 'Fer',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Març',
+  'May'                         => 'Mai',
+  'May '                        => 'Maig',
+  'Message'                     => 'Message',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Model',
+  'Name'                        => 'Nom',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta en número en la fila',
+  'Obsolete'                    => 'Obsolet',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'On Hand'                     => 'Disponible',
+  'On Order'                    => 'On Order',
+  'Order'                       => 'Ordre',
+  'Order Date missing!'         => 'Falta Data Ordre!',
+  'Order Number'                => 'Número Ordre',
+  'Order Number missing!'       => 'Falta Número Ordre!',
+  'Ordered'                     => 'Ordered',
+  'Orphaned'                    => 'Orfe',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Albarà',
+  'Packing List Date missing!'  => 'Falta Data Albarà!',
+  'Packing List Number missing!' => 'Falta Número Albarà!',
+  'Part'                        => 'Article',
+  'Part Number missing!'        => 'Falta Número Article!',
+  'Parts'                       => 'Articles',
+  'Phone'                       => 'Tel',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preu',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Ordre de Compra',
+  'Qty'                         => 'Quantitat',
+  'ROP'                         => 'ROP',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Soliciat per',
+  'Sales'                       => 'Vendes',
+  'Sales Order'                 => 'Pressupost',
+  'Save'                        => 'Guardar',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccionar d\'un dels elements de sota',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sell Price'                  => 'Preu Venta',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembre',
+  'Service'                     => 'Servei',
+  'Service Number missing!'     => 'Falta Nombre Servei!',
+  'Services'                    => 'Serveis',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Short'                       => 'Curt',
+  'Sold'                        => 'Venut',
+  'Stock Assembly'              => 'Inventari Compost',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impost',
+  'To'                          => 'Fins',
+  'Top Level'                   => 'Top Level',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unitat',
+  'Unit of measure'             => 'Unitat de Mesura',
+  'Update'                      => 'Update',
+  'Updated'                     => 'Updated',
+  'Weight'                      => 'Pes',
+  'What type of item is this?'  => 'Quin tipus d\'element és?',
+  'ea'                          => 'unit.',
+  'emailed to'                  => 'emailejat a',
+  'hr'                          => 'hr',
+  'sent to printer'             => 'enviat a impressora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'afegir'                      => 'add',
+  'afegir_compost'              => 'add_assembly',
+  'afegir_article'              => 'add_part',
+  'afegir_servei'               => 'add_service',
+  'continuar'                   => 'continue',
+  'esborrar'                    => 'delete',
+  'editar_compost'              => 'edit_assembly',
+  'editar_article'              => 'edit_part',
+  'editar_servei'               => 'edit_service',
+  'guardar'                     => 'save',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/io b/sql-ledger/locale/ct/io
new file mode 100644 (file)
index 0000000..b48c79b
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Afegir Ordre Compra',
+  'Add Sales Order'             => 'Afegir Pressupost',
+  'Address'                     => 'Adreça',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Attachment'                  => 'Adjunt',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agost',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacte',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Còpies',
+  'Dec'                         => 'Des',
+  'December'                    => 'Desembre',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripció',
+  'E-mail'                      => 'Email',
+  'E-mail address missing!'     => 'Falta Email!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrer',
+  'In-line'                     => 'Afegit',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Falta Data Fra.!',
+  'Invoice Number missing!'     => 'Falta Núm Fra.!',
+  'Item not on file!'           => 'No es troba cap arxiu amb aquest element!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gener',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juliol',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juny',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Març',
+  'May'                         => 'Mai',
+  'May '                        => 'Maig',
+  'Message'                     => 'Message',
+  'Name'                        => 'Nom',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta en número en la fila',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Order'                       => 'Ordre',
+  'Order Date missing!'         => 'Falta Data Ordre!',
+  'Order Number missing!'       => 'Falta Número Ordre!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Albarà',
+  'Packing List Date missing!'  => 'Falta Data Albarà!',
+  'Packing List Number missing!' => 'Falta Número Albarà!',
+  'Part'                        => 'Article',
+  'Phone'                       => 'Tel',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preu',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Ordre de Compra',
+  'Qty'                         => 'Quantitat',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Soliciat per',
+  'Sales Order'                 => 'Pressupost',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccionar d\'un dels elements de sota',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembre',
+  'Service'                     => 'Servei',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Subject'                     => 'Subject',
+  'To'                          => 'Fins',
+  'Unit'                        => 'Unitat',
+  'What type of item is this?'  => 'Quin tipus d\'element és?',
+  'emailed to'                  => 'emailejat a',
+  'sent to printer'             => 'enviat a impressora',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/ir b/sql-ledger/locale/ct/ir
new file mode 100644 (file)
index 0000000..c6a42bc
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Compta',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => 'Afegir Ordre Compra',
+  'Add Sales Order'             => 'Afegir Pressupost',
+  'Address'                     => 'Adreça',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => 'Segur que voleu esborrar la Fra. Num.',
+  'Attachment'                  => 'Adjunt',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agost',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'Cannot post invoice for a closed period!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacte',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Còpies',
+  'Currency'                    => 'Moneda',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Data Venciment',
+  'Dec'                         => 'Des',
+  'December'                    => 'Desembre',
+  'Delete'                      => 'Esborrar',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripció',
+  'E-mail'                      => 'Email',
+  'E-mail address missing!'     => 'Falta Email!',
+  'Edit Purchase Invoice'       => 'Edit Purchase Invoice',
+  'Exch'                        => 'Canvi',
+  'Exchangerate'                => 'Taxa de Canvi',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrer',
+  'In-line'                     => 'Afegit',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Data Fra.',
+  'Invoice Date missing!'       => 'Falta Data Fra.!',
+  'Invoice Number'              => 'Núm Fra.',
+  'Invoice Number missing!'     => 'Falta Núm Fra.!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => 'No es troba cap arxiu amb aquest element!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gener',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juliol',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juny',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Març',
+  'May'                         => 'Mai',
+  'May '                        => 'Maig',
+  'Message'                     => 'Message',
+  'Name'                        => 'Nom',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta en número en la fila',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Order'                       => 'Ordre',
+  'Order Date missing!'         => 'Falta Data Ordre!',
+  'Order Number'                => 'Número Ordre',
+  'Order Number missing!'       => 'Falta Número Ordre!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Albarà',
+  'Packing List Date missing!'  => 'Falta Data Albarà!',
+  'Packing List Number missing!' => 'Falta Número Albarà!',
+  'Part'                        => 'Article',
+  'Payment date missing!'       => 'Falta Data Pagament!',
+  'Payments'                    => 'Pagaments',
+  'Phone'                       => 'Tel',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preu',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Ordre de Compra',
+  'Qty'                         => 'Quantitat',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'Registar en',
+  'Required by'                 => 'Soliciat per',
+  'Sales Order'                 => 'Pressupost',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccionar d\'un dels elements de sota',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembre',
+  'Service'                     => 'Servei',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Source'                      => 'Font',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Impostos Inclosos',
+  'To'                          => 'Fins',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unitat',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Proveïdor',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'Quin tipus d\'element és?',
+  'Yes'                         => 'Sí',
+  'ea'                          => 'unit.',
+  'emailed to'                  => 'emailejat a',
+  'sent to printer'             => 'enviat a impressora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'esborrar'                    => 'delete',
+  'ordre'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'update'                      => 'update',
+  'sí'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/is b/sql-ledger/locale/ct/is
new file mode 100644 (file)
index 0000000..7afaebb
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Compta',
+  'Add Purchase Order'          => 'Afegir Ordre Compra',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'Afegir Pressupost',
+  'Address'                     => 'Adreça',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => 'Segur que voleu esborrar la Fra. Num.',
+  'Attachment'                  => 'Adjunt',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agost',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'Cannot post invoice for a closed period!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacte',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Còpies',
+  'Credit Limit'                => 'Límit de Crèdit',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Client',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Data Venciment',
+  'Dec'                         => 'Des',
+  'December'                    => 'Desembre',
+  'Delete'                      => 'Esborrar',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripció',
+  'E-mail'                      => 'Email',
+  'E-mail address missing!'     => 'Falta Email!',
+  'Edit Sales Invoice'          => 'Edit Sales Invoice',
+  'Exch'                        => 'Canvi',
+  'Exchangerate'                => 'Taxa de Canvi',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrer',
+  'In-line'                     => 'Afegit',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Data Fra.',
+  'Invoice Date missing!'       => 'Falta Data Fra.!',
+  'Invoice Number'              => 'Núm Fra.',
+  'Invoice Number missing!'     => 'Falta Núm Fra.!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => 'No es troba cap arxiu amb aquest element!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gener',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juliol',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juny',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Març',
+  'May'                         => 'Mai',
+  'May '                        => 'Maig',
+  'Message'                     => 'Message',
+  'Name'                        => 'Nom',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta en número en la fila',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Order'                       => 'Ordre',
+  'Order Date missing!'         => 'Falta Data Ordre!',
+  'Order Number'                => 'Número Ordre',
+  'Order Number missing!'       => 'Falta Número Ordre!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Albarà',
+  'Packing List Date missing!'  => 'Falta Data Albarà!',
+  'Packing List Number missing!' => 'Falta Número Albarà!',
+  'Part'                        => 'Article',
+  'Payment date missing!'       => 'Falta Data Pagament!',
+  'Payments'                    => 'Pagaments',
+  'Phone'                       => 'Tel',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preu',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Ordre de Compra',
+  'Qty'                         => 'Quantitat',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'Registar en',
+  'Remaining'                   => 'Remanent',
+  'Required by'                 => 'Soliciat per',
+  'Sales Order'                 => 'Pressupost',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccionar d\'un dels elements de sota',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembre',
+  'Service'                     => 'Servei',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Source'                      => 'Font',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Impostos Inclosos',
+  'To'                          => 'Fins',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unitat',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'Quin tipus d\'element és?',
+  'Yes'                         => 'Sí',
+  'ea'                          => 'unit.',
+  'emailed to'                  => 'emailejat a',
+  'sent to printer'             => 'enviat a impressora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'esborrar'                    => 'delete',
+  'email'                       => 'e_mail',
+  'ordre'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'sí'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/login b/sql-ledger/locale/ct/login
new file mode 100644 (file)
index 0000000..09baae0
--- /dev/null
@@ -0,0 +1,28 @@
+$self{texts} = {
+  'About'                       => 'Referent',
+  'Accounting'                  => 'Comptabilitat',
+  'Database Host'               => 'Servidor Base de Dades',
+  'Dataset'                     => 'Conjunt de Dades',
+  'Incorrect Dataset version!'  => 'Versió Incorrecta del Conjunt de Dades!',
+  'Incorrect Password!'         => 'Contrasenya no Vàlida!',
+  'Licensed to'                 => 'Adaptat per',
+  'Login'                       => 'Entrar',
+  'Name'                        => 'Nom',
+  'Password'                    => 'Contrasenya',
+  'User'                        => 'Usuari',
+  'Version'                     => 'Versió',
+  'You are logged out!'         => 'You are logged out!',
+  'You did not enter a name!'   => 'No heu entrat cap nom!',
+  'is not a member!'            => 'no és membre!',
+  'localhost'                   => 'màquina local',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'entrar'                      => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/menu b/sql-ledger/locale/ct/menu
new file mode 100644 (file)
index 0000000..4defaf1
--- /dev/null
@@ -0,0 +1,72 @@
+$self{texts} = {
+  'AP'                          => 'Despeses',
+  'AP Aging'                    => 'Diari de Despeses',
+  'AR'                          => 'Ingressos',
+  'AR Aging'                    => 'Diari d\'Ingressos',
+  'Accounting Menu'             => 'Menú Comptable',
+  'Add Account'                 => 'Afegir Compta',
+  'Add Assembly'                => 'Afegir Compost',
+  'Add Customer'                => 'Afegir Client',
+  'Add GIFI'                    => 'Add GIFI',
+  'Add Part'                    => 'Afegir Article',
+  'Add Project'                 => 'Add Project',
+  'Add Service'                 => 'Afegir Servei',
+  'Add Transaction'             => 'Afegir Transacció',
+  'Add Vendor'                  => 'Afegir Proveïdor',
+  'Assemblies'                  => 'Compostos',
+  'Audit Control'               => 'Control Auditoria',
+  'Backup'                      => 'Còpia de Seguretat',
+  'Balance Sheet'               => 'Fulla de Balanç',
+  'Cash'                        => 'Cash',
+  'Chart of Accounts'           => 'Taula de Comptes',
+  'Check'                       => 'Check',
+  'Customers'                   => 'Customers',
+  'General Ledger'              => 'Llibre Major',
+  'Goods & Services'            => 'Bèns i Serveis',
+  'HTML Templates'              => 'Plantilles HTML',
+  'Income Statement'            => 'Balanç Situació',
+  'Invoice'                     => 'Factura',
+  'LaTeX Templates'             => 'Plantilles LaTeX',
+  'List Accounts'               => 'Llistar Comptes',
+  'List GIFI'                   => 'List GIFI',
+  'Logout'                      => 'Desconnectar',
+  'Order Entry'                 => 'Pressupostos i Comandes',
+  'Packing List'                => 'Albarà',
+  'Parts'                       => 'Articles',
+  'Payment'                     => 'Pagament',
+  'Payments'                    => 'Pagaments',
+  'Preferences'                 => 'Preferències',
+  'Projects'                    => 'Projects',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Purchase Order'              => 'Ordre de Compra',
+  'Purchase Orders'             => 'Ordres de Compra',
+  'Receipt'                     => 'Receipt',
+  'Receipts'                    => 'Receipts',
+  'Reconciliation'              => 'Reconciliation',
+  'Reports'                     => 'Informes',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Sales Order'                 => 'Pressupost',
+  'Sales Orders'                => 'Pressupostos',
+  'Save to File'                => 'Guardar a Fitxer',
+  'Send by E-Mail'              => 'Enviar per Email',
+  'Services'                    => 'Serveis',
+  'Statement'                   => 'Statement',
+  'Stock Assembly'              => 'Inventari Compost',
+  'Stylesheet'                  => 'Fulla Estils',
+  'System'                      => 'Sistema',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'Transactions'                => 'Transaccions',
+  'Trial Balance'               => 'Balanç de Comprovació',
+  'Vendors'                     => 'Vendors',
+  'Version'                     => 'Versió',
+  'localhost'                   => 'màquina local',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/oe b/sql-ledger/locale/ct/oe
new file mode 100644 (file)
index 0000000..951fd1b
--- /dev/null
@@ -0,0 +1,199 @@
+$self{texts} = {
+  'Add'                         => 'Afegir',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => 'Afegir Ordre Compra',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'Afegir Pressupost',
+  'Address'                     => 'Adreça',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Order Number' => 'Segur que voleu esborrar l\'Ordre',
+  'Attachment'                  => 'Adjunt',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agost',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Cannot delete order!',
+  'Cannot save order!'          => 'Cannot save order!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Tancat',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacte',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Còpies',
+  'Credit Limit'                => 'Límit de Crèdit',
+  'Curr'                        => 'Curr',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Client',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Data',
+  'Dec'                         => 'Des',
+  'December'                    => 'Desembre',
+  'Delete'                      => 'Esborrar',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripció',
+  'E-mail'                      => 'Email',
+  'E-mail address missing!'     => 'Falta Email!',
+  'Edit Purchase Order'         => 'Editar Ordre Compra',
+  'Edit Sales Order'            => 'Editar Pressupost',
+  'Exchangerate'                => 'Taxa de Canvi',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrer',
+  'From'                        => 'De',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Afegit',
+  'Include in Report'           => 'Incloure en l\'Informe',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Falta Data Fra.!',
+  'Invoice Number missing!'     => 'Falta Núm Fra.!',
+  'Item not on file!'           => 'No es troba cap arxiu amb aquest element!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gener',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juliol',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juny',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Març',
+  'May'                         => 'Mai',
+  'May '                        => 'Maig',
+  'Message'                     => 'Message',
+  'Name'                        => 'Nom',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta en número en la fila',
+  'O'                           => 'O',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Open'                        => 'Obert',
+  'Order'                       => 'Ordre',
+  'Order Date'                  => 'Data Ordre',
+  'Order Date missing!'         => 'Falta Data Ordre!',
+  'Order Number'                => 'Número Ordre',
+  'Order Number missing!'       => 'Falta Número Ordre!',
+  'Order deleted!'              => 'Order deleted!',
+  'Order saved!'                => 'Order saved!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Albarà',
+  'Packing List Date missing!'  => 'Falta Data Albarà!',
+  'Packing List Number missing!' => 'Falta Número Albarà!',
+  'Part'                        => 'Article',
+  'Phone'                       => 'Tel',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preu',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Ordre de Compra',
+  'Purchase Orders'             => 'Ordres de Compra',
+  'Qty'                         => 'Quantitat',
+  'Recd'                        => 'Recd',
+  'Remaining'                   => 'Remanent',
+  'Required by'                 => 'Soliciat per',
+  'Sales Order'                 => 'Pressupost',
+  'Sales Orders'                => 'Pressupostos',
+  'Save'                        => 'Guardar',
+  'Save as new'                 => 'Save as new',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccionar d\'un dels elements de sota',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembre',
+  'Service'                     => 'Servei',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impost',
+  'Tax Included'                => 'Impostos Inclosos',
+  'Terms: Net'                  => 'Terms:Net',
+  'To'                          => 'Fins',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unitat',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Proveïdor',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'Quin tipus d\'element és?',
+  'Yes'                         => 'Sí',
+  'days'                        => 'dies',
+  'ea'                          => 'unit.',
+  'emailed to'                  => 'emailejat a',
+  'sent to printer'             => 'enviat a impressora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'afegir'                      => 'add',
+  'continuar'                   => 'continue',
+  'esborrar'                    => 'delete',
+  'email'                       => 'e_mail',
+  'factura'                     => 'invoice',
+  'print'                       => 'print',
+  'guardar'                     => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'sí'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/pe b/sql-ledger/locale/ct/pe
new file mode 100644 (file)
index 0000000..01856d5
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Afegir',
+  'Add Project'                 => 'Add Project',
+  'All'                         => 'Tots',
+  'Continue'                    => 'Continuar',
+  'Delete'                      => 'Esborrar',
+  'Description'                 => 'Descripció',
+  'Edit Project'                => 'Edit Project',
+  'Number'                      => 'Número',
+  'Orphaned'                    => 'Orfe',
+  'Project'                     => 'Project',
+  'Project Number missing!'     => 'Project Number missing!',
+  'Project deleted!'            => 'Project deleted!',
+  'Project saved!'              => 'Project saved!',
+  'Projects'                    => 'Projects',
+  'Save'                        => 'Guardar',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'afegir'                      => 'add',
+  'continuar'                   => 'continue',
+  'esborrar'                    => 'delete',
+  'guardar'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/rc b/sql-ledger/locale/ct/rc
new file mode 100644 (file)
index 0000000..8b6112c
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Compta',
+  'Balance'                     => 'Balance',
+  'Cleared Balance'             => 'Cleared Balance',
+  'Continue'                    => 'Continuar',
+  'Date'                        => 'Data',
+  'Deposit'                     => 'Deposit',
+  'Description'                 => 'Descripció',
+  'Difference'                  => 'Difference',
+  'Done'                        => 'Done',
+  'Exchangerate Difference'     => 'Exchangerate Difference',
+  'From'                        => 'De',
+  'Out of balance!'             => 'Out of balance!',
+  'Payment'                     => 'Pagament',
+  'Reconciliation'              => 'Reconciliation',
+  'Select all'                  => 'Select all',
+  'Source'                      => 'Font',
+  'Statement Balance'           => 'Statement Balance',
+  'To'                          => 'Fins',
+  'Update'                      => 'Update',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'continuar'                   => 'continue',
+  'done'                        => 'done',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ct/rp b/sql-ledger/locale/ct/rp
new file mode 100644 (file)
index 0000000..75eff42
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'Diari de Despeses',
+  'AR Aging'                    => 'Diari d\'Ingressos',
+  'Account'                     => 'Compta',
+  'Accounts'                    => 'Accounts',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Attachment'                  => 'Adjunt',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agost',
+  'Balance Sheet'               => 'Fulla de Balanç',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Cash based',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Comparar amb',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Còpies',
+  'Credit'                      => 'Crèdit',
+  'Current'                     => 'Current',
+  'Customer'                    => 'Client',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Dèbit',
+  'Dec'                         => 'Des',
+  'December'                    => 'Desembre',
+  'Decimalplaces'               => 'Decimalplaces',
+  'Description'                 => 'Descripció',
+  'Due'                         => 'Venciment',
+  'E-mail'                      => 'Email',
+  'E-mail Statement to'         => 'E-mail Statement to',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrer',
+  'From'                        => 'De',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Capçalera',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Afegit',
+  'Include in Report'           => 'Incloure en l\'Informe',
+  'Income Statement'            => 'Balanç Situació',
+  'Invoice'                     => 'Factura',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gener',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juliol',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juny',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Març',
+  'May'                         => 'Mai',
+  'May '                        => 'Maig',
+  'Message'                     => 'Message',
+  'N/A'                         => 'N/A',
+  'Nothing selected!'           => 'Nothing selected!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Pagaments',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Impressora',
+  'Receipts'                    => 'Receipts',
+  'Report for'                  => 'Registrar per',
+  'Retained Earnings'           => 'Guanys Retinguts',
+  'Screen'                      => 'Pantalla',
+  'Select all'                  => 'Select all',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembre',
+  'Source'                      => 'Font',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Statement',
+  'Statement sent to'           => 'Statement sent to',
+  'Statements sent to printer!' => 'Statements sent to printer!',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impost',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'To'                          => 'Fins',
+  'Total'                       => 'Total',
+  'Trial Balance'               => 'Balanç de Comprovació',
+  'Vendor'                      => 'Proveïdor',
+  'as at'                       => 'as at',
+  'collected on sales'          => 'recollit en vendes',
+  'for Period'                  => 'pel període',
+  'paid on purchases'           => 'pagat al comprat',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'continuar'                   => 'continue',
+  'email'                       => 'e_mail',
+  'print'                       => 'print',
+  'select_all'                  => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/COPYING b/sql-ledger/locale/cz/COPYING
new file mode 100644 (file)
index 0000000..64c58a2
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Czech texts:
+#
+#  Author: Tomas Fencl <tomas.fencl@centrum.cz>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/cz/LANGUAGE b/sql-ledger/locale/cz/LANGUAGE
new file mode 100644 (file)
index 0000000..618b7f5
--- /dev/null
@@ -0,0 +1 @@
+Czech
diff --git a/sql-ledger/locale/cz/admin b/sql-ledger/locale/cz/admin
new file mode 100644 (file)
index 0000000..4a238b5
--- /dev/null
@@ -0,0 +1,122 @@
+$self{texts} = {
+  'Access Control'              => 'Pøístupová práva',
+  'Accounting'                  => 'Úèetnictví',
+  'Add User'                    => 'Nový u¾ivatel',
+  'Address'                     => 'Adresa',
+  'Administration'              => 'Administrace',
+  'Administrator'               => 'Administrator',
+  'All Datasets up to date!'    => 'V¹echna data jsou aktualizována',
+  'Change Admin Password'       => 'Zmìnit heslo administrátora',
+  'Change Password'             => 'Zmìnit heslo',
+  'Character Set'               => 'Znaková sada',
+  'Click on login name to edit!' => 'Pro úpravy kliknìte na jméno u¾ivatele',
+  'Company'                     => 'Firma',
+  'Connect to'                  => 'Pøipojit k serveru',
+  'Continue'                    => 'Pokraèování',
+  'Create Chart of Accounts'    => 'Vytvoøit úètový rozvrh',
+  'Create Dataset'              => 'Vytvoøit dataset',
+  'DBI not installed!'          => 'DBI není nainstalováno',
+  'Database'                    => 'Databáze',
+  'Database Administration'     => 'Správa databáze',
+  'Database Driver not checked!' => 'Nepodaøilo se zkontrolovat ovladaè databáze',
+  'Database User missing!'      => 'Chybí jméno pro pøihlá¹ení k databázi!',
+  'Dataset'                     => 'Dataset',
+  'Dataset missing!'            => 'Není zadán dataset',
+  'Dataset updated!'            => 'Dataset updated!',
+  'Date Format'                 => 'Formát data',
+  'Delete'                      => 'Vymazat',
+  'Delete Dataset'              => 'Zru¹it dataset',
+  'Directory'                   => 'Adresáø',
+  'Driver'                      => 'Øidiè',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'E-mail',
+  'Edit User'                   => 'Upravit u¾ivatele',
+  'Existing Datasets'           => 'Datasety',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Server',
+  'Hostname missing!'           => 'Chybí jméno serveru!',
+  'Incorrect Password!'         => 'Nesprávné heslo!',
+  'Language'                    => 'Jazyk',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Pro lokální databázi, nezadávejte adresu serveru a port.',
+  'Login'                       => 'U¾ivatelské jméno',
+  'Name'                        => 'Jméno',
+  'New Templates'               => 'Nové ¹ablony',
+  'No Database Drivers available!' => 'Není instalován ¾ádný ovladaè databáze!',
+  'No Dataset selected!'        => 'Není zvolen ¾ádný dataset!',
+  'Nothing to delete!'          => 'Nejsou polo¾ky k vymazání!',
+  'Number Format'               => 'Èíselný formát',
+  'Oracle Database Administration' => 'Oracle Správa databáze',
+  'Password'                    => 'Heslo',
+  'Password changed!'           => 'Password changed!',
+  'Pg Database Administration'  => 'Pg Správa databáze',
+  'Phone'                       => 'Telefon',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Chybí èíslo portu!',
+  'Printer'                     => 'Tiskárna',
+  'Save'                        => 'Ulo¾it',
+  'Select a Dataset to delete and press "Continue"' => 'Zvolte dataset, který chcete vymazat a stisknìte "Pokraèovat"',
+  'Setup Templates'             => 'Nastavení ¹ablon',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'Podpis',
+  'Stylesheet'                  => 'Stylesheet',
+  'Templates'                   => '©ablony',
+  'The following Datasets are not in use and can be deleted' => 'Uvedené datasety nejsou vyu¾ívány a mohou být vymazány',
+  'The following Datasets need to be updated' => 'Následující data musí být aktualizována',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Toto je pøedbì¾ná kontrola existence zdrojových dokumentù. V této fázi nebude databáze aktualizována.',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Pro pøidání u¾ivatele do skupiny otevøete existujícího u¾ivatele a ulo¾te jej s jiným u¾ivatelským jménem. Nový u¾ivatel bude vytvoøen s toto¾ným nastavením v¹ech promìnných.',
+  'Update Dataset'              => 'Aktualizovat data',
+  'Use Templates'               => 'Vyu¾ít ¹ablony',
+  'User'                        => 'U¾ivatel',
+  'User deleted!'               => 'User deleted!',
+  'User saved!'                 => 'User saved!',
+  'Version'                     => 'Verze',
+  'You must enter a host and port for local and remote connections!' => 'Pro lokální i vzdálené pøipojení je nutné  zadat adresu serveru a port!',
+  'does not exist'              => 'neexistuje',
+  'is already a member!'        => 'ji¾ existuje!',
+  'localhost'                   => 'lokální server',
+  'successfully created!'       => 'úspì¹nì vytvoøen!',
+  'successfully deleted!'       => 'úspì¹nì smazán!',
+  'website'                     => 'www adresa',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'nový_u¾ivatel'               => 'add_user',
+  'zmìnit_heslo_administrátora' => 'change_admin_password',
+  'zmìnit_heslo'                => 'change_password',
+  'pokraèování'                 => 'continue',
+  'vytvoøit_dataset'            => 'create_dataset',
+  'vymazat'                     => 'delete',
+  'zru¹it_dataset'              => 'delete_dataset',
+  'u¾ivatelské_jméno'           => 'login',
+  'oracle_správa_databáze'      => 'oracle_database_administration',
+  'pg_správa_databáze'          => 'pg_database_administration',
+  'ulo¾it'                      => 'save',
+  'aktualizovat_data'           => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/all b/sql-ledger/locale/cz/all
new file mode 100644 (file)
index 0000000..71704c1
--- /dev/null
@@ -0,0 +1,487 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Závazky',
+  'AP Aging'                    => 'Analýza splatnosti',
+  'AP Transaction'              => '',
+  'AP Transactions'             => 'Faktury pøijaté',
+  'AR'                          => 'Pohledávky',
+  'AR Aging'                    => 'Analýza splatnosti',
+  'AR Transaction'              => '',
+  'AR Transactions'             => 'Faktury vydané',
+  'About'                       => 'O programu',
+  'Access Control'              => 'Pøístupová práva',
+  'Account'                     => 'Úèet',
+  'Account Number'              => 'Èíslo úètu',
+  'Account Number missing!'     => 'Chybí èíslo úètu!',
+  'Account Type'                => 'Typ úètu',
+  'Account Type missing!'       => 'Chybí typ úètu!',
+  'Account deleted!'            => '',
+  'Account saved!'              => '',
+  'Accounting'                  => 'Úèetnictví',
+  'Accounting Menu'             => 'Menu úèetnictví',
+  'Accounts'                    => 'Úèty',
+  'Active'                      => '',
+  'Add'                         => 'Pøidat',
+  'Add Account'                 => 'Zalo¾it úèet',
+  'Add Accounts Payables Transaction' => '',
+  'Add Accounts Receivables Transaction' => '',
+  'Add Assembly'                => 'Nový výrobek',
+  'Add Customer'                => 'Nový zákazník',
+  'Add GIFI'                    => 'Doplnit úètovací øetìzec',
+  'Add General Ledger Transaction' => 'Nový zápis do hlavní knihy',
+  'Add Part'                    => 'Pøíjem zbo¾í',
+  'Add Project'                 => '',
+  'Add Purchase Invoice'        => '',
+  'Add Purchase Order'          => 'Nová objednávka (nákup)',
+  'Add Sales Invoice'           => '',
+  'Add Sales Order'             => 'Nová objednávka (pøíjem)',
+  'Add Service'                 => 'Nový druh slu¾by',
+  'Add Transaction'             => 'Nová transakce',
+  'Add User'                    => 'Nový u¾ivatel',
+  'Add Vendor'                  => 'Nový dodavatel',
+  'Address'                     => 'Adresa',
+  'Administration'              => 'Administrace',
+  'Administrator'               => '',
+  'All'                         => 'V¹e',
+  'All Datasets up to date!'    => 'V¹echna data jsou aktualizována',
+  'Amount'                      => 'Èástka',
+  'Amount Due'                  => '',
+  'Amount does not equal applied!' => '',
+  'Amount missing!'             => '',
+  'Applied'                     => '',
+  'Apr'                         => 'Dub',
+  'April'                       => 'Duben',
+  'Are you sure you want to delete Invoice Number' => 'Opravdu chcete vymazat fakturu èíslo',
+  'Are you sure you want to delete Order Number' => 'Opravdu chcete vymazat objednávku èíslo',
+  'Are you sure you want to delete Transaction' => 'Opravdu chcete vymazat transakci?',
+  'Assemblies'                  => 'Výrobky',
+  'Assemblies restocked!'       => '',
+  'Assembly Number missing!'    => 'Chybí èíslo výrobku',
+  'Asset'                       => 'Aktiva',
+  'Attachment'                  => 'Pøílohy',
+  'Audit Control'               => 'Kontrola pøístupù',
+  'Aug'                         => 'Srp',
+  'August'                      => 'Srpen',
+  'BOM'                         => '',
+  'Backup'                      => 'Záloha',
+  'Backup sent to'              => 'Záloha odeslána na adresu',
+  'Balance'                     => '',
+  'Balance Sheet'               => 'Rozvaha',
+  'Bcc'                         => '',
+  'Bin'                         => 'Paleta',
+  'Books are open'              => '¡Uèetní knihy jsou otevøeny',
+  'Bought'                      => 'Nakoupeno',
+  'Business Number'             => 'IÈO',
+  'C'                           => '',
+  'COGS'                        => 'Náklady na prodané zbo¾í',
+  'Cannot delete account!'      => '',
+  'Cannot delete customer!'     => '',
+  'Cannot delete default account!' => 'Úèet je nastaven jako defaultní, nelze jej proto vymamazat!',
+  'Cannot delete invoice!'      => '',
+  'Cannot delete item already invoiced!' => 'Ji¾ fakturované polo¾ky nelze vymazat!',
+  'Cannot delete item on order!' => 'Polo¾ku objednávky nelze vymazat!',
+  'Cannot delete item which is part of an assembly!' => 'Nelze vymazat polo¾ku, která je souèástí výrobku!',
+  'Cannot delete item!'         => '',
+  'Cannot delete order!'        => '',
+  'Cannot delete transaction!'  => '',
+  'Cannot delete vendor!'       => '',
+  'Cannot have a value in both Debit and Credit!' => 'Nelze úètovat souèasnì Má dáti i Dal!',
+  'Cannot post a transaction without a value!' => '',
+  'Cannot post invoice for a closed period!' => '',
+  'Cannot post invoice!'        => '',
+  'Cannot post payment for a closed period!' => '',
+  'Cannot post payment!'        => '',
+  'Cannot post transaction for a closed period!' => 'Do uzavøeného období nelze úètovat!',
+  'Cannot post transaction!'    => '',
+  'Cannot process payment for a closed period!' => '',
+  'Cannot save account!'        => '',
+  'Cannot save order!'          => '',
+  'Cannot save preferences!'    => '',
+  'Cannot stock assemblies!'    => '',
+  'Cash'                        => '',
+  'Cash based'                  => '',
+  'Cc'                          => '',
+  'Change Admin Password'       => 'Zmìnit heslo administrátora',
+  'Change Password'             => 'Zmìnit heslo',
+  'Character Set'               => 'Znaková sada',
+  'Chart of Accounts'           => 'Úètový rozvrh',
+  'Check'                       => '',
+  'Check printed!'              => '',
+  'Check printing failed!'      => '',
+  'Cleared Balance'             => '',
+  'Click on login name to edit!' => 'Pro úpravy kliknìte na jméno u¾ivatele',
+  'Close Books up to'           => 'Uzavøít úèetní knihy do',
+  'Closed'                      => 'Zaplaceno',
+  'Company'                     => 'Firma',
+  'Compare to'                  => 'Porovnáno k',
+  'Confirm!'                    => 'Podtvrïte!',
+  'Connect to'                  => 'Pøipojit k serveru',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Pokraèování',
+  'Copies'                      => 'Kopie',
+  'Copy to COA'                 => 'Zkopírovat do úètového rozvrhu',
+  'Create Chart of Accounts'    => 'Vytvoøit úètový rozvrh',
+  'Create Dataset'              => 'Vytvoøit dataset',
+  'Credit'                      => 'Dal',
+  'Credit Limit'                => 'Úvìrový limit',
+  'Curr'                        => 'Mìna',
+  'Currency'                    => 'Mìna',
+  'Current'                     => '',
+  'Customer'                    => 'Odbìratel',
+  'Customer deleted!'           => '',
+  'Customer missing!'           => '',
+  'Customer not on file!'       => '',
+  'Customer saved!'             => '',
+  'Customers'                   => '',
+  'DBI not installed!'          => 'DBI není nainstalováno',
+  'Database'                    => 'Databáze',
+  'Database Administration'     => 'Správa databáze',
+  'Database Driver not checked!' => 'Nepodaøilo se zkontrolovat ovladaè databáze',
+  'Database Host'               => 'Databázový server',
+  'Database User missing!'      => 'Chybí jméno pro pøihlá¹ení k databázi!',
+  'Dataset'                     => 'Dataset',
+  'Dataset missing!'            => 'Není zadán dataset',
+  'Dataset updated!'            => '',
+  'Date'                        => 'Datum',
+  'Date Due'                    => 'Datum splatnosti',
+  'Date Format'                 => 'Formát data',
+  'Date Paid'                   => 'Zaplaceno',
+  'Date missing!'               => '',
+  'Debit'                       => 'Má dáti',
+  'Debit and credit out of balance!' => 'Má dáti a Dal se nerovnají.',
+  'Dec'                         => 'Pro',
+  'December'                    => 'Prosinec',
+  'Decimalplaces'               => '',
+  'Delete'                      => 'Vymazat',
+  'Delete Account'              => 'Vymazat úèet',
+  'Delete Dataset'              => 'Zru¹it dataset',
+  'Delivery Date'               => '',
+  'Deposit'                     => '',
+  'Description'                 => 'Popis',
+  'Difference'                  => '',
+  'Directory'                   => 'Adresáø',
+  'Discount'                    => 'Sleva',
+  'Done'                        => '',
+  'Drawing'                     => '',
+  'Driver'                      => 'Øidiè',
+  'Dropdown Limit'              => '',
+  'Due'                         => 'Splatno',
+  'Due Date'                    => 'Datum splatnosti',
+  'Due Date missing!'           => 'Chybí datum splatnosti!',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => '',
+  'E-mail address missing!'     => 'Chybí E-mailová adresa!',
+  'Edit'                        => '',
+  'Edit Account'                => 'Upravit úèet',
+  'Edit Accounts Payables Transaction' => '',
+  'Edit Accounts Receivables Transaction' => '',
+  'Edit Assembly'               => 'Upravit výrobek',
+  'Edit GIFI'                   => 'Upravit úètovací øetìzec',
+  'Edit General Ledger Transaction' => 'Opravit záznam v hlavní knize',
+  'Edit Part'                   => 'Upravit zbo¾í',
+  'Edit Preferences for'        => 'Nastavení pro',
+  'Edit Project'                => '',
+  'Edit Purchase Invoice'       => '',
+  'Edit Purchase Order'         => 'Upravit vystavenou objednávku',
+  'Edit Sales Invoice'          => '',
+  'Edit Sales Order'            => 'Upravit pøijatou objednávku',
+  'Edit Service'                => 'Upravit slu¾bu',
+  'Edit Template'               => 'Upravit ¹ablonu',
+  'Edit User'                   => 'Upravit u¾ivatele',
+  'Employee'                    => '',
+  'Enforce transaction reversal for all dates' => 'Zakázat editaci v¹ech úèetních polo¾ek',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Vlo¾te zkratky mìn (max. 3 znaky) oddìlené dvojteèkou pro domácí i cizí mìny (napø. CZK:USD:EUR)',
+  'Equity'                      => 'Vlastní jmìní',
+  'Exch'                        => 'Kurz',
+  'Exchangerate'                => 'Mìnový kurz',
+  'Exchangerate Difference'     => '',
+  'Exchangerate for payment missing!' => '',
+  'Exchangerate missing!'       => '',
+  'Existing Datasets'           => 'Datasety',
+  'Expense'                     => 'Náklady',
+  'Expense Account'             => 'Nákladový úèet',
+  'Expense/Asset'               => 'Náklad',
+  'Extended'                    => '',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Úno',
+  'February'                    => 'Únor',
+  'Foreign Exchange Gain'       => 'Kurzový zisk',
+  'Foreign Exchange Loss'       => 'Kurzová ztráta',
+  'From'                        => 'z',
+  'GIFI'                        => 'Úètovací øetìzec',
+  'GIFI deleted!'               => '',
+  'GIFI missing!'               => 'Chybí úètovací øetìzec!',
+  'GIFI saved!'                 => '',
+  'GL Transaction'              => '',
+  'General Ledger'              => 'Hlavní kniha',
+  'Goods & Services'            => 'Zbo¾í a slu¾by',
+  'HTML Templates'              => 'HTML ¹ablony',
+  'Heading'                     => 'Nadpis',
+  'Host'                        => 'Server',
+  'Hostname missing!'           => 'Chybí jméno serveru!',
+  'ID'                          => 'ID',
+  'Image'                       => '',
+  'In-line'                     => 'Vlo¾ené',
+  'Include in Report'           => 'Zahrnovat v sestavì',
+  'Include in drop-down menus'  => 'Ukazovat v drop-down menu',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Zahrnovat tento úèet ve formuláøích odbìratelù/dodavatelù, aby bylo mo¾né oznaèit je za zdanitelné?',
+  'Income'                      => 'Výnosy',
+  'Income Account'              => 'Výnosový úèet',
+  'Income Statement'            => 'Výsledovka',
+  'Incorrect Dataset version!'  => '©patná verze dat!',
+  'Incorrect Password!'         => 'Nesprávné heslo!',
+  'Individual Items'            => 'Komponenty výrobku',
+  'Inventory'                   => 'Zásoby',
+  'Inventory Account'           => 'Úèet zásob',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Pøed vyøazením výrobu, musí být stav na skladì nulový!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Pøed vyøazením zbo¾í musí být mno¾ství na skladì nulové',
+  'Inventory quantity must be zero!' => 'Stav skladu musí být nulový!',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Datum vystavení',
+  'Invoice Date missing!'       => 'Chybí datum vystavení!',
+  'Invoice Number'              => 'Èíslo faktury',
+  'Invoice Number missing!'     => 'Chybí èíslo faktury!',
+  'Invoice deleted!'            => '',
+  'Invoice posted!'             => '',
+  'Invoices'                    => '',
+  'Is this a summary account to record' => 'Øídící úèet pro',
+  'Item deleted!'               => '',
+  'Item not on file!'           => 'Tato polo¾ka není v databázi!',
+  'Jan'                         => 'Led',
+  'January'                     => 'Leden',
+  'Jul'                         => 'Èec',
+  'July'                        => 'Èervenec',
+  'Jun'                         => 'Èer',
+  'June'                        => 'Èerven',
+  'LaTeX Templates'             => 'LaTeX ¹ablony',
+  'Language'                    => 'Jazyk',
+  'Last Cost'                   => 'Poslední cena',
+  'Last Invoice Number'         => 'Èíslo poslední faktury',
+  'Last Numbers & Default Accounts' => 'Poslední èísla a standardní èísla úètù',
+  'Last Purchase Order Number'  => 'Èíslo poslední objednávky',
+  'Last Sales Order Number'     => 'Èíslo poslední objednávky',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Pro lokální databázi, nezadávejte adresu serveru a port.',
+  'Liability'                   => 'Závazek',
+  'Licensed to'                 => 'Licencováno pro',
+  'Line Total'                  => 'Øádek celkem',
+  'Link'                        => 'Vazby',
+  'Link Accounts'               => 'Vazby mezi úèty',
+  'List Accounts'               => 'Seznam úètù',
+  'List GIFI'                   => 'Vypsat úètovací øetìzce',
+  'List Price'                  => 'Výrobní cena',
+  'List Transactions'           => 'Vypsat transakce',
+  'Login'                       => 'U¾ivatelské jméno',
+  'Logout'                      => 'Odhlásit',
+  'Make'                        => 'Výrobce',
+  'Mar'                         => 'Bøe',
+  'March'                       => 'Bøezen',
+  'May'                         => 'Kvìten',
+  'May '                        => 'Kvì',
+  'Message'                     => 'Zpráva',
+  'Microfiche'                  => '',
+  'Model'                       => 'Model',
+  'N/A'                         => '---',
+  'Name'                        => 'Jméno',
+  'Name missing!'               => '',
+  'New Templates'               => 'Nové ¹ablony',
+  'No'                          => 'Ne',
+  'No Database Drivers available!' => 'Není instalován ¾ádný ovladaè databáze!',
+  'No Dataset selected!'        => 'Není zvolen ¾ádný dataset!',
+  'No email address for'        => 'Chybí emailová adresy pro',
+  'No.'                         => '',
+  'Notes'                       => 'Poznámky',
+  'Nothing applied!'            => '',
+  'Nothing selected!'           => '',
+  'Nothing to delete!'          => 'Nejsou polo¾ky k vymazání!',
+  'Nov'                         => 'Lis',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Èíslo',
+  'Number Format'               => 'Èíselný formát',
+  'Number missing in Row'       => 'Chybìjící èíslo na øádku',
+  'O'                           => '',
+  'Obsolete'                    => 'Vyøazené',
+  'Oct'                         => 'Øíj',
+  'October'                     => 'Øíjen',
+  'On Hand'                     => 'K dispozici',
+  'On Order'                    => '',
+  'Open'                        => 'Otevøené',
+  'Oracle Database Administration' => 'Oracle Správa databáze',
+  'Order'                       => 'Objednávka',
+  'Order Date'                  => 'Datum objednávky',
+  'Order Date missing!'         => 'Chybí datum objednávky!',
+  'Order Entry'                 => 'Zadání objednávky',
+  'Order Number'                => 'Objednávka èíslo',
+  'Order Number missing!'       => 'Chybí èíslo objednávky!',
+  'Order deleted!'              => '',
+  'Order saved!'                => '',
+  'Ordered'                     => '',
+  'Orphaned'                    => 'Neprodejné',
+  'Out of balance!'             => '',
+  'PDF'                         => '',
+  'Packing List'                => 'Dodací list',
+  'Packing List Date missing!'  => 'Chybí datum dodacího listu',
+  'Packing List Number missing!' => 'Chybí èíslo dodacího listu',
+  'Paid'                        => 'Zaplaceno',
+  'Paid in full'                => '',
+  'Part'                        => 'Zbo¾í',
+  'Part Number missing!'        => 'Chybí èíslo zbo¾í!',
+  'Parts'                       => 'Díly',
+  'Parts Inventory'             => 'Zbo¾í',
+  'Password'                    => 'Heslo',
+  'Password changed!'           => '',
+  'Payables'                    => 'Závazky',
+  'Payment'                     => 'Platba',
+  'Payment date missing!'       => 'Chybí datum platby!',
+  'Payment posted!'             => '',
+  'Payments'                    => 'Platby',
+  'Pg Database Administration'  => 'Pg Správa databáze',
+  'Phone'                       => 'Telefon',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Chybí èíslo portu!',
+  'Post'                        => '',
+  'Post as new'                 => '',
+  'Postscript'                  => '',
+  'Preferences'                 => 'Nastavení',
+  'Preferences saved!'          => 'Nastavení bylo ulo¾eno!',
+  'Price'                       => 'Cena',
+  'Print'                       => '',
+  'Printer'                     => 'Tiskárna',
+  'Project'                     => '',
+  'Project Number missing!'     => '',
+  'Project deleted!'            => '',
+  'Project not on file!'        => '',
+  'Project saved!'              => '',
+  'Projects'                    => '',
+  'Purchase Invoice'            => '',
+  'Purchase Order'              => 'Vystavená objednávka',
+  'Purchase Orders'             => 'Vystavené objednávky',
+  'Qty'                         => 'Mno¾ství',
+  'ROP'                         => 'ROP',
+  'Rate'                        => 'Sazba',
+  'Recd'                        => '',
+  'Receipt'                     => '',
+  'Receipts'                    => '',
+  'Receivables'                 => 'Pohledávky',
+  'Reconciliation'              => '',
+  'Record in'                   => 'Zaúètovat do',
+  'Reference'                   => '',
+  'Reference missing!'          => '',
+  'Remaining'                   => 'Zbývá',
+  'Report for'                  => 'Výkaz za',
+  'Reports'                     => 'Sestavy',
+  'Required by'                 => 'Po¾adováno do',
+  'Retained Earnings'           => 'Nerozdìlený zisk',
+  'Sales'                       => 'Pøíjmy z prodeje',
+  'Sales Invoice'               => '',
+  'Sales Order'                 => 'Pøijatá objednávka',
+  'Sales Orders'                => 'Pøijaté objednávky',
+  'Save'                        => 'Ulo¾it',
+  'Save as new'                 => '',
+  'Save to File'                => 'Ulo¾it do souboru',
+  'Screen'                      => 'Na obrazovku',
+  'Select a Dataset to delete and press "Continue"' => 'Zvolte dataset, který chcete vymazat a stisknìte "Pokraèovat"',
+  'Select all'                  => '',
+  'Select from one of the items below' => 'Zvolte z ní¾e uvedených polo¾ek',
+  'Select from one of the names below' => '',
+  'Select from one of the projects below' => '',
+  'Select postscript or PDF!'   => '',
+  'Sell Price'                  => 'Prodejní cena',
+  'Send by E-Mail'              => 'Poslat e-mailem',
+  'Sep'                         => 'Záø',
+  'September'                   => 'Záøí',
+  'Service'                     => 'Slu¾ba',
+  'Service Items'               => 'Polo¾ky slu¾eb',
+  'Service Number missing!'     => 'Chybí èíslo slu¾by!',
+  'Services'                    => 'Slu¾by',
+  'Setup Templates'             => 'Nastavení ¹ablon',
+  'Ship'                        => '',
+  'Ship to'                     => '',
+  'Ship via'                    => '',
+  'Short'                       => 'Krátký výpis',
+  'Signature'                   => 'Podpis',
+  'Sold'                        => 'Prodané',
+  'Source'                      => 'Zdroj',
+  'Standard'                    => 'Standardní',
+  'Statement'                   => '',
+  'Statement Balance'           => '',
+  'Statement sent to'           => '',
+  'Statements sent to printer!' => '',
+  'Stock Assembly'              => 'Výrobky',
+  'Stylesheet'                  => 'Stylesheet',
+  'Subject'                     => 'Pøedmìt',
+  'Subtotal'                    => 'Mezisouèet',
+  'System'                      => 'Systém',
+  'Tax'                         => 'Daò',
+  'Tax Accounts'                => 'Daòové úèty',
+  'Tax Included'                => 'Cena vèetnì danì',
+  'Tax collected'               => '',
+  'Tax paid'                    => '',
+  'Taxable'                     => 'Zdanitelné',
+  'Template saved!'             => '',
+  'Templates'                   => '©ablony',
+  'Terms: Net'                  => 'Netto',
+  'The following Datasets are not in use and can be deleted' => 'Uvedené datasety nejsou vyu¾ívány a mohou být vymazány',
+  'The following Datasets need to be updated' => 'Následující data musí být aktualizována',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Toto je pøedbì¾ná kontrola existence zdrojových dokumentù. V této fázi nebude databáze aktualizována.',
+  'To'                          => 'do',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Pro pøidání u¾ivatele do skupiny otevøete existujícího u¾ivatele a ulo¾te jej s jiným u¾ivatelským jménem. Nový u¾ivatel bude vytvoøen s toto¾ným nastavením v¹ech promìnných.',
+  'Top Level'                   => '',
+  'Total'                       => 'Celkem',
+  'Transaction Date missing!'   => 'Chybí datum!',
+  'Transaction deleted!'        => '',
+  'Transaction posted!'         => '',
+  'Transaction reversal enforced for all dates' => 'Editace v¹ech polo¾ek zakázána (je nutné provést storno a nové zadání)',
+  'Transaction reversal enforced up to' => 'Editace polo¾ek zakázána do',
+  'Transactions'                => 'Polo¾ky',
+  'Transactions exist, cannot delete customer!' => 'Odbìratele nelze vymazat, proto¾e k nìmu existují transakce!',
+  'Transactions exist, cannot delete vendor!' => 'Dodavatele nelze vymazat, proto¾e k nìmu existují transakce!',
+  'Transactions exist; cannot delete account!' => 'Úèet nelze vymazat, proto¾e na nìm je úètováno!',
+  'Trial Balance'               => 'Obratová pøedvaha',
+  'Unit'                        => 'Jednotka',
+  'Unit of measure'             => 'Mìrná jednotka',
+  'Update'                      => '',
+  'Update Dataset'              => 'Aktualizovat data',
+  'Updated'                     => '',
+  'Use Templates'               => 'Vyu¾ít ¹ablony',
+  'User'                        => 'U¾ivatel',
+  'User deleted!'               => '',
+  'User saved!'                 => '',
+  'Vendor'                      => 'Dodavatel',
+  'Vendor deleted!'             => '',
+  'Vendor missing!'             => '',
+  'Vendor not on file!'         => '',
+  'Vendor saved!'               => '',
+  'Vendors'                     => '',
+  'Version'                     => 'Verze',
+  'Weight'                      => 'Váha',
+  'Weight Unit'                 => 'Jednotka váhy',
+  'What type of item is this?'  => 'O jaký typ polo¾ky se jedná?',
+  'Year End'                    => 'Konec roku',
+  'Yes'                         => 'Ano',
+  'You are logged out!'         => '',
+  'You did not enter a name!'   => 'Nezadal jste jméno!',
+  'You must enter a host and port for local and remote connections!' => 'Pro lokální i vzdálené pøipojení je nutné  zadat adresu serveru a port!',
+  'as at'                       => '',
+  'collected on sales'          => 'vybráno na výstupu',
+  'days'                        => 'dní',
+  'does not exist'              => 'neexistuje',
+  'ea'                          => 'm.j.',
+  'emailed to'                  => 'odesláno na adresu',
+  'for Period'                  => 'za období',
+  'hr'                          => 'hod',
+  'is already a member!'        => 'ji¾ existuje!',
+  'is not a member!'            => 'není platným u¾ivatelem',
+  'localhost'                   => 'lokální server',
+  'paid on purchases'           => 'zaplaceno na vstupu',
+  'sent to printer'             => 'vyti¹tìno',
+  'successfully created!'       => 'úspì¹nì vytvoøen!',
+  'successfully deleted!'       => 'úspì¹nì smazán!',
+  'to'                          => '',
+  'website'                     => 'www adresa',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/am b/sql-ledger/locale/cz/am
new file mode 100644 (file)
index 0000000..caee54c
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Závazky',
+  'AR'                          => 'Pohledávky',
+  'Account'                     => 'Úèet',
+  'Account Number'              => 'Èíslo úètu',
+  'Account Number missing!'     => 'Chybí èíslo úètu!',
+  'Account Type'                => 'Typ úètu',
+  'Account Type missing!'       => 'Chybí typ úètu!',
+  'Account deleted!'            => 'Account deleted!',
+  'Account saved!'              => 'Account saved!',
+  'Add Account'                 => 'Zalo¾it úèet',
+  'Add GIFI'                    => 'Doplnit úètovací øetìzec',
+  'Address'                     => 'Adresa',
+  'Asset'                       => 'Aktiva',
+  'Audit Control'               => 'Kontrola pøístupù',
+  'Backup sent to'              => 'Záloha odeslána na adresu',
+  'Books are open'              => '¡Uèetní knihy jsou otevøeny',
+  'Business Number'             => 'IÈO',
+  'COGS'                        => 'Náklady na prodané zbo¾í',
+  'Cannot delete account!'      => 'Cannot delete account!',
+  'Cannot delete default account!' => 'Úèet je nastaven jako defaultní, nelze jej proto vymamazat!',
+  'Cannot save account!'        => 'Cannot save account!',
+  'Cannot save preferences!'    => 'Cannot save preferences!',
+  'Character Set'               => 'Znaková sada',
+  'Chart of Accounts'           => 'Úètový rozvrh',
+  'Close Books up to'           => 'Uzavøít úèetní knihy do',
+  'Company'                     => 'Firma',
+  'Continue'                    => 'Pokraèování',
+  'Copy to COA'                 => 'Zkopírovat do úètového rozvrhu',
+  'Credit'                      => 'Dal',
+  'Date Format'                 => 'Formát data',
+  'Debit'                       => 'Má dáti',
+  'Delete'                      => 'Vymazat',
+  'Delete Account'              => 'Vymazat úèet',
+  'Description'                 => 'Popis',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'E-mail',
+  'Edit'                        => 'Edit',
+  'Edit Account'                => 'Upravit úèet',
+  'Edit GIFI'                   => 'Upravit úètovací øetìzec',
+  'Edit Preferences for'        => 'Nastavení pro',
+  'Edit Template'               => 'Upravit ¹ablonu',
+  'Enforce transaction reversal for all dates' => 'Zakázat editaci v¹ech úèetních polo¾ek',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Vlo¾te zkratky mìn (max. 3 znaky) oddìlené dvojteèkou pro domácí i cizí mìny (napø. CZK:USD:EUR)',
+  'Equity'                      => 'Vlastní jmìní',
+  'Expense'                     => 'Náklady',
+  'Expense Account'             => 'Nákladový úèet',
+  'Expense/Asset'               => 'Náklad',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Kurzový zisk',
+  'Foreign Exchange Loss'       => 'Kurzová ztráta',
+  'GIFI'                        => 'Úètovací øetìzec',
+  'GIFI deleted!'               => 'GIFI deleted!',
+  'GIFI missing!'               => 'Chybí úètovací øetìzec!',
+  'GIFI saved!'                 => 'GIFI saved!',
+  'Heading'                     => 'Nadpis',
+  'Include in drop-down menus'  => 'Ukazovat v drop-down menu',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Zahrnovat tento úèet ve formuláøích odbìratelù/dodavatelù, aby bylo mo¾né oznaèit je za zdanitelné?',
+  'Income'                      => 'Výnosy',
+  'Income Account'              => 'Výnosový úèet',
+  'Inventory'                   => 'Zásoby',
+  'Inventory Account'           => 'Úèet zásob',
+  'Is this a summary account to record' => 'Øídící úèet pro',
+  'Language'                    => 'Jazyk',
+  'Last Invoice Number'         => 'Èíslo poslední faktury',
+  'Last Numbers & Default Accounts' => 'Poslední èísla a standardní èísla úètù',
+  'Last Purchase Order Number'  => 'Èíslo poslední objednávky',
+  'Last Sales Order Number'     => 'Èíslo poslední objednávky',
+  'Liability'                   => 'Závazek',
+  'Link'                        => 'Vazby',
+  'Name'                        => 'Jméno',
+  'No'                          => 'Ne',
+  'No email address for'        => 'Chybí emailová adresy pro',
+  'Number'                      => 'Èíslo',
+  'Number Format'               => 'Èíselný formát',
+  'Parts Inventory'             => 'Zbo¾í',
+  'Password'                    => 'Heslo',
+  'Payables'                    => 'Závazky',
+  'Payment'                     => 'Platba',
+  'Phone'                       => 'Telefon',
+  'Preferences saved!'          => 'Nastavení bylo ulo¾eno!',
+  'Rate'                        => 'Sazba',
+  'Receivables'                 => 'Pohledávky',
+  'Sales'                       => 'Pøíjmy z prodeje',
+  'Save'                        => 'Ulo¾it',
+  'Service Items'               => 'Polo¾ky slu¾eb',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'Podpis',
+  'Stylesheet'                  => 'Stylesheet',
+  'Tax'                         => 'Daò',
+  'Tax Accounts'                => 'Daòové úèty',
+  'Template saved!'             => 'Template saved!',
+  'Transaction reversal enforced for all dates' => 'Editace v¹ech polo¾ek zakázána (je nutné provést storno a nové zadání)',
+  'Transaction reversal enforced up to' => 'Editace polo¾ek zakázána do',
+  'Transactions exist; cannot delete account!' => 'Úèet nelze vymazat, proto¾e na nìm je úètováno!',
+  'Weight Unit'                 => 'Jednotka váhy',
+  'Year End'                    => 'Konec roku',
+  'Yes'                         => 'Ano',
+  'does not exist'              => 'neexistuje',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'zalo¾it_úèet'                => 'add_account',
+  'pokraèování'                 => 'continue',
+  'zkopírovat_do_úètového_rozvrhu' => 'copy_to_coa',
+  'vymazat'                     => 'delete',
+  'edit'                        => 'edit',
+  'upravit_úèet'                => 'edit_account',
+  'ulo¾it'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/ap b/sql-ledger/locale/cz/ap
new file mode 100644 (file)
index 0000000..609bcbb
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AP Transactions'             => 'Faktury pøijaté',
+  'Account'                     => 'Úèet',
+  'Add Accounts Payables Transaction' => 'Add Accounts Payables Transaction',
+  'Address'                     => 'Adresa',
+  'Amount'                      => 'Èástka',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'Dub',
+  'April'                       => 'Duben',
+  'Are you sure you want to delete Transaction' => 'Opravdu chcete vymazat transakci?',
+  'Aug'                         => 'Srp',
+  'August'                      => 'Srpen',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cannot post transaction for a closed period!' => 'Do uzavøeného období nelze úètovat!',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'Zaplaceno',
+  'Confirm!'                    => 'Podtvrïte!',
+  'Continue'                    => 'Pokraèování',
+  'Currency'                    => 'Mìna',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Datum',
+  'Date Paid'                   => 'Zaplaceno',
+  'Dec'                         => 'Pro',
+  'December'                    => 'Prosinec',
+  'Delete'                      => 'Vymazat',
+  'Description'                 => 'Popis',
+  'Due Date'                    => 'Datum splatnosti',
+  'Due Date missing!'           => 'Chybí datum splatnosti!',
+  'Edit Accounts Payables Transaction' => 'Edit Accounts Payables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'Kurz',
+  'Exchangerate'                => 'Mìnový kurz',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Feb'                         => 'Úno',
+  'February'                    => 'Únor',
+  'From'                        => 'z',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Zahrnovat v sestavì',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Datum vystavení',
+  'Invoice Date missing!'       => 'Chybí datum vystavení!',
+  'Invoice Number'              => 'Èíslo faktury',
+  'Invoice Number missing!'     => 'Chybí èíslo faktury!',
+  'Jan'                         => 'Led',
+  'January'                     => 'Leden',
+  'Jul'                         => 'Èec',
+  'July'                        => 'Èervenec',
+  'Jun'                         => 'Èer',
+  'June'                        => 'Èerven',
+  'Mar'                         => 'Bøe',
+  'March'                       => 'Bøezen',
+  'May'                         => 'Kvìten',
+  'May '                        => 'Kvì',
+  'Notes'                       => 'Poznámky',
+  'Nov'                         => 'Lis',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Èíslo',
+  'Oct'                         => 'Øíj',
+  'October'                     => 'Øíjen',
+  'Open'                        => 'Otevøené',
+  'Order'                       => 'Objednávka',
+  'Order Number'                => 'Objednávka èíslo',
+  'Paid'                        => 'Zaplaceno',
+  'Payment date missing!'       => 'Chybí datum platby!',
+  'Payments'                    => 'Platby',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Záø',
+  'September'                   => 'Záøí',
+  'Source'                      => 'Zdroj',
+  'Subtotal'                    => 'Mezisouèet',
+  'Tax'                         => 'Daò',
+  'Tax Included'                => 'Cena vèetnì danì',
+  'To'                          => 'do',
+  'Total'                       => 'Celkem',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Dodavatel',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Ano',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'add_accounts_payables_transaction' => 'add_accounts_payables_transaction',
+  'pokraèování'                 => 'continue',
+  'vymazat'                     => 'delete',
+  'edit_accounts_payables_transaction' => 'edit_accounts_payables_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'update'                      => 'update',
+  'ano'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/ar b/sql-ledger/locale/cz/ar
new file mode 100644 (file)
index 0000000..512634f
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'AR Transaction',
+  'AR Transactions'             => 'Faktury vydané',
+  'Account'                     => 'Úèet',
+  'Add Accounts Receivables Transaction' => 'Add Accounts Receivables Transaction',
+  'Address'                     => 'Adresa',
+  'Amount'                      => 'Èástka',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'Dub',
+  'April'                       => 'Duben',
+  'Are you sure you want to delete Transaction' => 'Opravdu chcete vymazat transakci?',
+  'Aug'                         => 'Srp',
+  'August'                      => 'Srpen',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cannot post transaction for a closed period!' => 'Do uzavøeného období nelze úètovat!',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'Zaplaceno',
+  'Confirm!'                    => 'Podtvrïte!',
+  'Continue'                    => 'Pokraèování',
+  'Credit Limit'                => 'Úvìrový limit',
+  'Currency'                    => 'Mìna',
+  'Customer'                    => 'Odbìratel',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Datum',
+  'Date Paid'                   => 'Zaplaceno',
+  'Dec'                         => 'Pro',
+  'December'                    => 'Prosinec',
+  'Delete'                      => 'Vymazat',
+  'Description'                 => 'Popis',
+  'Due Date'                    => 'Datum splatnosti',
+  'Due Date missing!'           => 'Chybí datum splatnosti!',
+  'Edit Accounts Receivables Transaction' => 'Edit Accounts Receivables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'Kurz',
+  'Exchangerate'                => 'Mìnový kurz',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Feb'                         => 'Úno',
+  'February'                    => 'Únor',
+  'From'                        => 'z',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Zahrnovat v sestavì',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Datum vystavení',
+  'Invoice Date missing!'       => 'Chybí datum vystavení!',
+  'Invoice Number'              => 'Èíslo faktury',
+  'Invoice Number missing!'     => 'Chybí èíslo faktury!',
+  'Jan'                         => 'Led',
+  'January'                     => 'Leden',
+  'Jul'                         => 'Èec',
+  'July'                        => 'Èervenec',
+  'Jun'                         => 'Èer',
+  'June'                        => 'Èerven',
+  'Mar'                         => 'Bøe',
+  'March'                       => 'Bøezen',
+  'May'                         => 'Kvìten',
+  'May '                        => 'Kvì',
+  'Notes'                       => 'Poznámky',
+  'Nov'                         => 'Lis',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Èíslo',
+  'Oct'                         => 'Øíj',
+  'October'                     => 'Øíjen',
+  'Open'                        => 'Otevøené',
+  'Order'                       => 'Objednávka',
+  'Order Number'                => 'Objednávka èíslo',
+  'Paid'                        => 'Zaplaceno',
+  'Payment date missing!'       => 'Chybí datum platby!',
+  'Payments'                    => 'Platby',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Remaining'                   => 'Zbývá',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Záø',
+  'September'                   => 'Záøí',
+  'Source'                      => 'Zdroj',
+  'Subtotal'                    => 'Mezisouèet',
+  'Tax'                         => 'Daò',
+  'Tax Included'                => 'Cena vèetnì danì',
+  'To'                          => 'do',
+  'Total'                       => 'Celkem',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Ano',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ar_transaction'              => 'ar_transaction',
+  'pokraèování'                 => 'continue',
+  'vymazat'                     => 'delete',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'ano'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/arap b/sql-ledger/locale/cz/arap
new file mode 100644 (file)
index 0000000..3db4284
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Adresa',
+  'Continue'                    => 'Pokraèování',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Description'                 => 'Popis',
+  'Number'                      => 'Èíslo',
+  'Project not on file!'        => 'Project not on file!',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'pokraèování'                 => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/ca b/sql-ledger/locale/cz/ca
new file mode 100644 (file)
index 0000000..cd48d2f
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Úèet',
+  'Apr'                         => 'Dub',
+  'April'                       => 'Duben',
+  'Aug'                         => 'Srp',
+  'August'                      => 'Srpen',
+  'Balance'                     => 'Balance',
+  'Chart of Accounts'           => 'Úètový rozvrh',
+  'Credit'                      => 'Dal',
+  'Date'                        => 'Datum',
+  'Debit'                       => 'Má dáti',
+  'Dec'                         => 'Pro',
+  'December'                    => 'Prosinec',
+  'Description'                 => 'Popis',
+  'Feb'                         => 'Úno',
+  'February'                    => 'Únor',
+  'From'                        => 'z',
+  'GIFI'                        => 'Úètovací øetìzec',
+  'Include in Report'           => 'Zahrnovat v sestavì',
+  'Jan'                         => 'Led',
+  'January'                     => 'Leden',
+  'Jul'                         => 'Èec',
+  'July'                        => 'Èervenec',
+  'Jun'                         => 'Èer',
+  'June'                        => 'Èerven',
+  'List Transactions'           => 'Vypsat transakce',
+  'Mar'                         => 'Bøe',
+  'March'                       => 'Bøezen',
+  'May'                         => 'Kvìten',
+  'May '                        => 'Kvì',
+  'Nov'                         => 'Lis',
+  'November'                    => 'Listopad',
+  'Oct'                         => 'Øíj',
+  'October'                     => 'Øíjen',
+  'Reference'                   => 'Reference',
+  'Sep'                         => 'Záø',
+  'September'                   => 'Záøí',
+  'Subtotal'                    => 'Mezisouèet',
+  'To'                          => 'do',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'vypsat_transakce'            => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/cp b/sql-ledger/locale/cz/cp
new file mode 100644 (file)
index 0000000..f85ed50
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Úèet',
+  'Address'                     => 'Adresa',
+  'Amount'                      => 'Èástka',
+  'Amount does not equal applied!' => 'Amount does not equal applied!',
+  'Amount missing!'             => 'Amount missing!',
+  'Applied'                     => 'Applied',
+  'Cannot post payment!'        => 'Cannot post payment!',
+  'Cannot process payment for a closed period!' => 'Cannot process payment for a closed period!',
+  'Check'                       => 'Check',
+  'Check printed!'              => 'Check printed!',
+  'Check printing failed!'      => 'Check printing failed!',
+  'Continue'                    => 'Pokraèování',
+  'Currency'                    => 'Mìna',
+  'Customer'                    => 'Odbìratel',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Datum',
+  'Date missing!'               => 'Date missing!',
+  'Description'                 => 'Popis',
+  'Due'                         => 'Splatno',
+  'Exchangerate'                => 'Mìnový kurz',
+  'From'                        => 'z',
+  'Invoice'                     => 'Faktura',
+  'Invoices'                    => 'Invoices',
+  'Nothing applied!'            => 'Nothing applied!',
+  'Number'                      => 'Èíslo',
+  'Paid in full'                => 'Paid in full',
+  'Payment'                     => 'Platba',
+  'Payment posted!'             => 'Payment posted!',
+  'Post'                        => 'Post',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Tiskárna',
+  'Project not on file!'        => 'Project not on file!',
+  'Receipt'                     => 'Receipt',
+  'Reference'                   => 'Reference',
+  'Screen'                      => 'Na obrazovku',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'To'                          => 'do',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Dodavatel',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'pokraèování'                 => 'continue',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/ct b/sql-ledger/locale/cz/ct
new file mode 100644 (file)
index 0000000..7c2863d
--- /dev/null
@@ -0,0 +1,69 @@
+$self{texts} = {
+  'Add'                         => 'Pøidat',
+  'Address'                     => 'Adresa',
+  'All'                         => 'V¹e',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Cannot delete customer!',
+  'Cannot delete vendor!'       => 'Cannot delete vendor!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Pokraèování',
+  'Credit Limit'                => 'Úvìrový limit',
+  'Customer deleted!'           => 'Customer deleted!',
+  'Customer saved!'             => 'Customer saved!',
+  'Customers'                   => 'Customers',
+  'Delete'                      => 'Vymazat',
+  'Discount'                    => 'Sleva',
+  'E-mail'                      => 'E-mail',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Zahrnovat v sestavì',
+  'Invoice'                     => 'Faktura',
+  'Name'                        => 'Jméno',
+  'Name missing!'               => 'Name missing!',
+  'Notes'                       => 'Poznámky',
+  'Number'                      => 'Èíslo',
+  'Order'                       => 'Objednávka',
+  'Orphaned'                    => 'Neprodejné',
+  'Phone'                       => 'Telefon',
+  'Save'                        => 'Ulo¾it',
+  'Ship to'                     => 'Ship to',
+  'Tax Included'                => 'Cena vèetnì danì',
+  'Taxable'                     => 'Zdanitelné',
+  'Terms: Net'                  => 'Netto',
+  'Transactions exist, cannot delete customer!' => 'Odbìratele nelze vymazat, proto¾e k nìmu existují transakce!',
+  'Transactions exist, cannot delete vendor!' => 'Dodavatele nelze vymazat, proto¾e k nìmu existují transakce!',
+  'Vendor deleted!'             => 'Vendor deleted!',
+  'Vendor saved!'               => 'Vendor saved!',
+  'Vendors'                     => 'Vendors',
+  'days'                        => 'dní',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'pøidat'                      => 'add',
+  'pokraèování'                 => 'continue',
+  'vymazat'                     => 'delete',
+  'faktura'                     => 'invoice',
+  'objednávka'                  => 'order',
+  'ulo¾it'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/gl b/sql-ledger/locale/cz/gl
new file mode 100644 (file)
index 0000000..1928de8
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AR Transaction'              => 'AR Transaction',
+  'Account'                     => 'Úèet',
+  'Add General Ledger Transaction' => 'Nový zápis do hlavní knihy',
+  'Address'                     => 'Adresa',
+  'All'                         => 'V¹e',
+  'Apr'                         => 'Dub',
+  'April'                       => 'Duben',
+  'Are you sure you want to delete Transaction' => 'Opravdu chcete vymazat transakci?',
+  'Asset'                       => 'Aktiva',
+  'Aug'                         => 'Srp',
+  'August'                      => 'Srpen',
+  'Balance'                     => 'Balance',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot have a value in both Debit and Credit!' => 'Nelze úètovat souèasnì Má dáti i Dal!',
+  'Cannot post a transaction without a value!' => 'Cannot post a transaction without a value!',
+  'Cannot post transaction for a closed period!' => 'Do uzavøeného období nelze úètovat!',
+  'Confirm!'                    => 'Podtvrïte!',
+  'Continue'                    => 'Pokraèování',
+  'Credit'                      => 'Dal',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Datum',
+  'Debit'                       => 'Má dáti',
+  'Debit and credit out of balance!' => 'Má dáti a Dal se nerovnají.',
+  'Dec'                         => 'Pro',
+  'December'                    => 'Prosinec',
+  'Delete'                      => 'Vymazat',
+  'Description'                 => 'Popis',
+  'Edit General Ledger Transaction' => 'Opravit záznam v hlavní knize',
+  'Equity'                      => 'Vlastní jmìní',
+  'Expense'                     => 'Náklady',
+  'Feb'                         => 'Úno',
+  'February'                    => 'Únor',
+  'From'                        => 'z',
+  'GIFI'                        => 'Úètovací øetìzec',
+  'GL Transaction'              => 'GL Transaction',
+  'General Ledger'              => 'Hlavní kniha',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Zahrnovat v sestavì',
+  'Income'                      => 'Výnosy',
+  'Jan'                         => 'Led',
+  'January'                     => 'Leden',
+  'Jul'                         => 'Èec',
+  'July'                        => 'Èervenec',
+  'Jun'                         => 'Èer',
+  'June'                        => 'Èerven',
+  'Liability'                   => 'Závazek',
+  'Mar'                         => 'Bøe',
+  'March'                       => 'Bøezen',
+  'May'                         => 'Kvìten',
+  'May '                        => 'Kvì',
+  'Notes'                       => 'Poznámky',
+  'Nov'                         => 'Lis',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Èíslo',
+  'Oct'                         => 'Øíj',
+  'October'                     => 'Øíjen',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Reference'                   => 'Reference',
+  'Reference missing!'          => 'Reference missing!',
+  'Reports'                     => 'Sestavy',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Záø',
+  'September'                   => 'Záøí',
+  'Source'                      => 'Zdroj',
+  'Subtotal'                    => 'Mezisouèet',
+  'To'                          => 'do',
+  'Transaction Date missing!'   => 'Chybí datum!',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Ano',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'pokraèování'                 => 'continue',
+  'vymazat'                     => 'delete',
+  'gl_transaction'              => 'gl_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'ano'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/ic b/sql-ledger/locale/cz/ic
new file mode 100644 (file)
index 0000000..effb534
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Active',
+  'Add'                         => 'Pøidat',
+  'Add Assembly'                => 'Nový výrobek',
+  'Add Part'                    => 'Pøíjem zbo¾í',
+  'Add Purchase Order'          => 'Nová objednávka (nákup)',
+  'Add Sales Order'             => 'Nová objednávka (pøíjem)',
+  'Add Service'                 => 'Nový druh slu¾by',
+  'Address'                     => 'Adresa',
+  'Apr'                         => 'Dub',
+  'April'                       => 'Duben',
+  'Assemblies'                  => 'Výrobky',
+  'Assemblies restocked!'       => 'Assemblies restocked!',
+  'Assembly Number missing!'    => 'Chybí èíslo výrobku',
+  'Attachment'                  => 'Pøílohy',
+  'Aug'                         => 'Srp',
+  'August'                      => 'Srpen',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Paleta',
+  'Bought'                      => 'Nakoupeno',
+  'COGS'                        => 'Náklady na prodané zbo¾í',
+  'Cannot delete item already invoiced!' => 'Ji¾ fakturované polo¾ky nelze vymazat!',
+  'Cannot delete item on order!' => 'Polo¾ku objednávky nelze vymazat!',
+  'Cannot delete item which is part of an assembly!' => 'Nelze vymazat polo¾ku, která je souèástí výrobku!',
+  'Cannot delete item!'         => 'Cannot delete item!',
+  'Cannot stock assemblies!'    => 'Cannot stock assemblies!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Pokraèování',
+  'Copies'                      => 'Kopie',
+  'Dec'                         => 'Pro',
+  'December'                    => 'Prosinec',
+  'Delete'                      => 'Vymazat',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Popis',
+  'Drawing'                     => 'Drawing',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Chybí E-mailová adresa!',
+  'Edit Assembly'               => 'Upravit výrobek',
+  'Edit Part'                   => 'Upravit zbo¾í',
+  'Edit Service'                => 'Upravit slu¾bu',
+  'Expense'                     => 'Náklady',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Úno',
+  'February'                    => 'Únor',
+  'From'                        => 'z',
+  'Image'                       => 'Image',
+  'In-line'                     => 'Vlo¾ené',
+  'Include in Report'           => 'Zahrnovat v sestavì',
+  'Income'                      => 'Výnosy',
+  'Individual Items'            => 'Komponenty výrobku',
+  'Inventory'                   => 'Zásoby',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Pøed vyøazením výrobu, musí být stav na skladì nulový!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Pøed vyøazením zbo¾í musí být mno¾ství na skladì nulové',
+  'Inventory quantity must be zero!' => 'Stav skladu musí být nulový!',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Chybí datum vystavení!',
+  'Invoice Number'              => 'Èíslo faktury',
+  'Invoice Number missing!'     => 'Chybí èíslo faktury!',
+  'Item deleted!'               => 'Item deleted!',
+  'Item not on file!'           => 'Tato polo¾ka není v databázi!',
+  'Jan'                         => 'Led',
+  'January'                     => 'Leden',
+  'Jul'                         => 'Èec',
+  'July'                        => 'Èervenec',
+  'Jun'                         => 'Èer',
+  'June'                        => 'Èerven',
+  'Last Cost'                   => 'Poslední cena',
+  'Line Total'                  => 'Øádek celkem',
+  'Link Accounts'               => 'Vazby mezi úèty',
+  'List Price'                  => 'Výrobní cena',
+  'Make'                        => 'Výrobce',
+  'Mar'                         => 'Bøe',
+  'March'                       => 'Bøezen',
+  'May'                         => 'Kvìten',
+  'May '                        => 'Kvì',
+  'Message'                     => 'Zpráva',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Model',
+  'Name'                        => 'Jméno',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Poznámky',
+  'Nov'                         => 'Lis',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Èíslo',
+  'Number missing in Row'       => 'Chybìjící èíslo na øádku',
+  'Obsolete'                    => 'Vyøazené',
+  'Oct'                         => 'Øíj',
+  'October'                     => 'Øíjen',
+  'On Hand'                     => 'K dispozici',
+  'On Order'                    => 'On Order',
+  'Order'                       => 'Objednávka',
+  'Order Date missing!'         => 'Chybí datum objednávky!',
+  'Order Number'                => 'Objednávka èíslo',
+  'Order Number missing!'       => 'Chybí èíslo objednávky!',
+  'Ordered'                     => 'Ordered',
+  'Orphaned'                    => 'Neprodejné',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Dodací list',
+  'Packing List Date missing!'  => 'Chybí datum dodacího listu',
+  'Packing List Number missing!' => 'Chybí èíslo dodacího listu',
+  'Part'                        => 'Zbo¾í',
+  'Part Number missing!'        => 'Chybí èíslo zbo¾í!',
+  'Parts'                       => 'Díly',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena',
+  'Printer'                     => 'Tiskárna',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Vystavená objednávka',
+  'Qty'                         => 'Mno¾ství',
+  'ROP'                         => 'ROP',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Po¾adováno do',
+  'Sales'                       => 'Pøíjmy z prodeje',
+  'Sales Order'                 => 'Pøijatá objednávka',
+  'Save'                        => 'Ulo¾it',
+  'Screen'                      => 'Na obrazovku',
+  'Select from one of the items below' => 'Zvolte z ní¾e uvedených polo¾ek',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sell Price'                  => 'Prodejní cena',
+  'Sep'                         => 'Záø',
+  'September'                   => 'Záøí',
+  'Service'                     => 'Slu¾ba',
+  'Service Number missing!'     => 'Chybí èíslo slu¾by!',
+  'Services'                    => 'Slu¾by',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Short'                       => 'Krátký výpis',
+  'Sold'                        => 'Prodané',
+  'Stock Assembly'              => 'Výrobky',
+  'Subject'                     => 'Pøedmìt',
+  'Subtotal'                    => 'Mezisouèet',
+  'Tax'                         => 'Daò',
+  'To'                          => 'do',
+  'Top Level'                   => 'Top Level',
+  'Total'                       => 'Celkem',
+  'Unit'                        => 'Jednotka',
+  'Unit of measure'             => 'Mìrná jednotka',
+  'Update'                      => 'Update',
+  'Updated'                     => 'Updated',
+  'Weight'                      => 'Váha',
+  'What type of item is this?'  => 'O jaký typ polo¾ky se jedná?',
+  'ea'                          => 'm.j.',
+  'emailed to'                  => 'odesláno na adresu',
+  'hr'                          => 'hod',
+  'sent to printer'             => 'vyti¹tìno',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'pøidat'                      => 'add',
+  'nový_výrobek'                => 'add_assembly',
+  'pøíjem_zbo¾í'                => 'add_part',
+  'nový_druh_slu¾by'            => 'add_service',
+  'pokraèování'                 => 'continue',
+  'vymazat'                     => 'delete',
+  'upravit_výrobek'             => 'edit_assembly',
+  'upravit_zbo¾í'               => 'edit_part',
+  'upravit_slu¾bu'              => 'edit_service',
+  'ulo¾it'                      => 'save',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/io b/sql-ledger/locale/cz/io
new file mode 100644 (file)
index 0000000..9fa6c63
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Nová objednávka (nákup)',
+  'Add Sales Order'             => 'Nová objednávka (pøíjem)',
+  'Address'                     => 'Adresa',
+  'Apr'                         => 'Dub',
+  'April'                       => 'Duben',
+  'Attachment'                  => 'Pøílohy',
+  'Aug'                         => 'Srp',
+  'August'                      => 'Srpen',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Paleta',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Pokraèování',
+  'Copies'                      => 'Kopie',
+  'Dec'                         => 'Pro',
+  'December'                    => 'Prosinec',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Popis',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Chybí E-mailová adresa!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Úno',
+  'February'                    => 'Únor',
+  'In-line'                     => 'Vlo¾ené',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Chybí datum vystavení!',
+  'Invoice Number missing!'     => 'Chybí èíslo faktury!',
+  'Item not on file!'           => 'Tato polo¾ka není v databázi!',
+  'Jan'                         => 'Led',
+  'January'                     => 'Leden',
+  'Jul'                         => 'Èec',
+  'July'                        => 'Èervenec',
+  'Jun'                         => 'Èer',
+  'June'                        => 'Èerven',
+  'Mar'                         => 'Bøe',
+  'March'                       => 'Bøezen',
+  'May'                         => 'Kvìten',
+  'May '                        => 'Kvì',
+  'Message'                     => 'Zpráva',
+  'Name'                        => 'Jméno',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Lis',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Èíslo',
+  'Number missing in Row'       => 'Chybìjící èíslo na øádku',
+  'Oct'                         => 'Øíj',
+  'October'                     => 'Øíjen',
+  'Order'                       => 'Objednávka',
+  'Order Date missing!'         => 'Chybí datum objednávky!',
+  'Order Number missing!'       => 'Chybí èíslo objednávky!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Dodací list',
+  'Packing List Date missing!'  => 'Chybí datum dodacího listu',
+  'Packing List Number missing!' => 'Chybí èíslo dodacího listu',
+  'Part'                        => 'Zbo¾í',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena',
+  'Printer'                     => 'Tiskárna',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Vystavená objednávka',
+  'Qty'                         => 'Mno¾ství',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Po¾adováno do',
+  'Sales Order'                 => 'Pøijatá objednávka',
+  'Screen'                      => 'Na obrazovku',
+  'Select from one of the items below' => 'Zvolte z ní¾e uvedených polo¾ek',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Záø',
+  'September'                   => 'Záøí',
+  'Service'                     => 'Slu¾ba',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Subject'                     => 'Pøedmìt',
+  'To'                          => 'do',
+  'Unit'                        => 'Jednotka',
+  'What type of item is this?'  => 'O jaký typ polo¾ky se jedná?',
+  'emailed to'                  => 'odesláno na adresu',
+  'sent to printer'             => 'vyti¹tìno',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'pokraèování'                 => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/ir b/sql-ledger/locale/cz/ir
new file mode 100644 (file)
index 0000000..5e36073
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Úèet',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => 'Nová objednávka (nákup)',
+  'Add Sales Order'             => 'Nová objednávka (pøíjem)',
+  'Address'                     => 'Adresa',
+  'Amount'                      => 'Èástka',
+  'Apr'                         => 'Dub',
+  'April'                       => 'Duben',
+  'Are you sure you want to delete Invoice Number' => 'Opravdu chcete vymazat fakturu èíslo',
+  'Attachment'                  => 'Pøílohy',
+  'Aug'                         => 'Srp',
+  'August'                      => 'Srpen',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Paleta',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'Cannot post invoice for a closed period!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Podtvrïte!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Pokraèování',
+  'Copies'                      => 'Kopie',
+  'Currency'                    => 'Mìna',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Datum',
+  'Date Due'                    => 'Datum splatnosti',
+  'Dec'                         => 'Pro',
+  'December'                    => 'Prosinec',
+  'Delete'                      => 'Vymazat',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Popis',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Chybí E-mailová adresa!',
+  'Edit Purchase Invoice'       => 'Edit Purchase Invoice',
+  'Exch'                        => 'Kurz',
+  'Exchangerate'                => 'Mìnový kurz',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Úno',
+  'February'                    => 'Únor',
+  'In-line'                     => 'Vlo¾ené',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Datum vystavení',
+  'Invoice Date missing!'       => 'Chybí datum vystavení!',
+  'Invoice Number'              => 'Èíslo faktury',
+  'Invoice Number missing!'     => 'Chybí èíslo faktury!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => 'Tato polo¾ka není v databázi!',
+  'Jan'                         => 'Led',
+  'January'                     => 'Leden',
+  'Jul'                         => 'Èec',
+  'July'                        => 'Èervenec',
+  'Jun'                         => 'Èer',
+  'June'                        => 'Èerven',
+  'Mar'                         => 'Bøe',
+  'March'                       => 'Bøezen',
+  'May'                         => 'Kvìten',
+  'May '                        => 'Kvì',
+  'Message'                     => 'Zpráva',
+  'Name'                        => 'Jméno',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Poznámky',
+  'Nov'                         => 'Lis',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Èíslo',
+  'Number missing in Row'       => 'Chybìjící èíslo na øádku',
+  'Oct'                         => 'Øíj',
+  'October'                     => 'Øíjen',
+  'Order'                       => 'Objednávka',
+  'Order Date missing!'         => 'Chybí datum objednávky!',
+  'Order Number'                => 'Objednávka èíslo',
+  'Order Number missing!'       => 'Chybí èíslo objednávky!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Dodací list',
+  'Packing List Date missing!'  => 'Chybí datum dodacího listu',
+  'Packing List Number missing!' => 'Chybí èíslo dodacího listu',
+  'Part'                        => 'Zbo¾í',
+  'Payment date missing!'       => 'Chybí datum platby!',
+  'Payments'                    => 'Platby',
+  'Phone'                       => 'Telefon',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena',
+  'Printer'                     => 'Tiskárna',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Vystavená objednávka',
+  'Qty'                         => 'Mno¾ství',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'Zaúètovat do',
+  'Required by'                 => 'Po¾adováno do',
+  'Sales Order'                 => 'Pøijatá objednávka',
+  'Screen'                      => 'Na obrazovku',
+  'Select from one of the items below' => 'Zvolte z ní¾e uvedených polo¾ek',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Záø',
+  'September'                   => 'Záøí',
+  'Service'                     => 'Slu¾ba',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Source'                      => 'Zdroj',
+  'Subject'                     => 'Pøedmìt',
+  'Subtotal'                    => 'Mezisouèet',
+  'Tax Included'                => 'Cena vèetnì danì',
+  'To'                          => 'do',
+  'Total'                       => 'Celkem',
+  'Unit'                        => 'Jednotka',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Dodavatel',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'O jaký typ polo¾ky se jedná?',
+  'Yes'                         => 'Ano',
+  'ea'                          => 'm.j.',
+  'emailed to'                  => 'odesláno na adresu',
+  'sent to printer'             => 'vyti¹tìno',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'pokraèování'                 => 'continue',
+  'vymazat'                     => 'delete',
+  'objednávka'                  => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'update'                      => 'update',
+  'ano'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/is b/sql-ledger/locale/cz/is
new file mode 100644 (file)
index 0000000..845b381
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Úèet',
+  'Add Purchase Order'          => 'Nová objednávka (nákup)',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'Nová objednávka (pøíjem)',
+  'Address'                     => 'Adresa',
+  'Amount'                      => 'Èástka',
+  'Apr'                         => 'Dub',
+  'April'                       => 'Duben',
+  'Are you sure you want to delete Invoice Number' => 'Opravdu chcete vymazat fakturu èíslo',
+  'Attachment'                  => 'Pøílohy',
+  'Aug'                         => 'Srp',
+  'August'                      => 'Srpen',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Paleta',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'Cannot post invoice for a closed period!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Podtvrïte!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Pokraèování',
+  'Copies'                      => 'Kopie',
+  'Credit Limit'                => 'Úvìrový limit',
+  'Currency'                    => 'Mìna',
+  'Customer'                    => 'Odbìratel',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Datum',
+  'Date Due'                    => 'Datum splatnosti',
+  'Dec'                         => 'Pro',
+  'December'                    => 'Prosinec',
+  'Delete'                      => 'Vymazat',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Popis',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Chybí E-mailová adresa!',
+  'Edit Sales Invoice'          => 'Edit Sales Invoice',
+  'Exch'                        => 'Kurz',
+  'Exchangerate'                => 'Mìnový kurz',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Úno',
+  'February'                    => 'Únor',
+  'In-line'                     => 'Vlo¾ené',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Datum vystavení',
+  'Invoice Date missing!'       => 'Chybí datum vystavení!',
+  'Invoice Number'              => 'Èíslo faktury',
+  'Invoice Number missing!'     => 'Chybí èíslo faktury!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => 'Tato polo¾ka není v databázi!',
+  'Jan'                         => 'Led',
+  'January'                     => 'Leden',
+  'Jul'                         => 'Èec',
+  'July'                        => 'Èervenec',
+  'Jun'                         => 'Èer',
+  'June'                        => 'Èerven',
+  'Mar'                         => 'Bøe',
+  'March'                       => 'Bøezen',
+  'May'                         => 'Kvìten',
+  'May '                        => 'Kvì',
+  'Message'                     => 'Zpráva',
+  'Name'                        => 'Jméno',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Poznámky',
+  'Nov'                         => 'Lis',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Èíslo',
+  'Number missing in Row'       => 'Chybìjící èíslo na øádku',
+  'Oct'                         => 'Øíj',
+  'October'                     => 'Øíjen',
+  'Order'                       => 'Objednávka',
+  'Order Date missing!'         => 'Chybí datum objednávky!',
+  'Order Number'                => 'Objednávka èíslo',
+  'Order Number missing!'       => 'Chybí èíslo objednávky!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Dodací list',
+  'Packing List Date missing!'  => 'Chybí datum dodacího listu',
+  'Packing List Number missing!' => 'Chybí èíslo dodacího listu',
+  'Part'                        => 'Zbo¾í',
+  'Payment date missing!'       => 'Chybí datum platby!',
+  'Payments'                    => 'Platby',
+  'Phone'                       => 'Telefon',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Tiskárna',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Vystavená objednávka',
+  'Qty'                         => 'Mno¾ství',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'Zaúètovat do',
+  'Remaining'                   => 'Zbývá',
+  'Required by'                 => 'Po¾adováno do',
+  'Sales Order'                 => 'Pøijatá objednávka',
+  'Screen'                      => 'Na obrazovku',
+  'Select from one of the items below' => 'Zvolte z ní¾e uvedených polo¾ek',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Záø',
+  'September'                   => 'Záøí',
+  'Service'                     => 'Slu¾ba',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Source'                      => 'Zdroj',
+  'Subject'                     => 'Pøedmìt',
+  'Subtotal'                    => 'Mezisouèet',
+  'Tax Included'                => 'Cena vèetnì danì',
+  'To'                          => 'do',
+  'Total'                       => 'Celkem',
+  'Unit'                        => 'Jednotka',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'O jaký typ polo¾ky se jedná?',
+  'Yes'                         => 'Ano',
+  'ea'                          => 'm.j.',
+  'emailed to'                  => 'odesláno na adresu',
+  'sent to printer'             => 'vyti¹tìno',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'pokraèování'                 => 'continue',
+  'vymazat'                     => 'delete',
+  'e_mail'                      => 'e_mail',
+  'objednávka'                  => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'ano'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/login b/sql-ledger/locale/cz/login
new file mode 100644 (file)
index 0000000..c0d9264
--- /dev/null
@@ -0,0 +1,28 @@
+$self{texts} = {
+  'About'                       => 'O programu',
+  'Accounting'                  => 'Úèetnictví',
+  'Database Host'               => 'Databázový server',
+  'Dataset'                     => 'Dataset',
+  'Incorrect Dataset version!'  => '©patná verze dat!',
+  'Incorrect Password!'         => 'Nesprávné heslo!',
+  'Licensed to'                 => 'Licencováno pro',
+  'Login'                       => 'U¾ivatelské jméno',
+  'Name'                        => 'Jméno',
+  'Password'                    => 'Heslo',
+  'User'                        => 'U¾ivatel',
+  'Version'                     => 'Verze',
+  'You are logged out!'         => 'You are logged out!',
+  'You did not enter a name!'   => 'Nezadal jste jméno!',
+  'is not a member!'            => 'není platným u¾ivatelem',
+  'localhost'                   => 'lokální server',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'u¾ivatelské_jméno'           => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/menu b/sql-ledger/locale/cz/menu
new file mode 100644 (file)
index 0000000..bb77601
--- /dev/null
@@ -0,0 +1,72 @@
+$self{texts} = {
+  'AP'                          => 'Závazky',
+  'AP Aging'                    => 'Analýza splatnosti',
+  'AR'                          => 'Pohledávky',
+  'AR Aging'                    => 'Analýza splatnosti',
+  'Accounting Menu'             => 'Menu úèetnictví',
+  'Add Account'                 => 'Zalo¾it úèet',
+  'Add Assembly'                => 'Nový výrobek',
+  'Add Customer'                => 'Nový zákazník',
+  'Add GIFI'                    => 'Doplnit úètovací øetìzec',
+  'Add Part'                    => 'Pøíjem zbo¾í',
+  'Add Project'                 => 'Add Project',
+  'Add Service'                 => 'Nový druh slu¾by',
+  'Add Transaction'             => 'Nová transakce',
+  'Add Vendor'                  => 'Nový dodavatel',
+  'Assemblies'                  => 'Výrobky',
+  'Audit Control'               => 'Kontrola pøístupù',
+  'Backup'                      => 'Záloha',
+  'Balance Sheet'               => 'Rozvaha',
+  'Cash'                        => 'Cash',
+  'Chart of Accounts'           => 'Úètový rozvrh',
+  'Check'                       => 'Check',
+  'Customers'                   => 'Customers',
+  'General Ledger'              => 'Hlavní kniha',
+  'Goods & Services'            => 'Zbo¾í a slu¾by',
+  'HTML Templates'              => 'HTML ¹ablony',
+  'Income Statement'            => 'Výsledovka',
+  'Invoice'                     => 'Faktura',
+  'LaTeX Templates'             => 'LaTeX ¹ablony',
+  'List Accounts'               => 'Seznam úètù',
+  'List GIFI'                   => 'Vypsat úètovací øetìzce',
+  'Logout'                      => 'Odhlásit',
+  'Order Entry'                 => 'Zadání objednávky',
+  'Packing List'                => 'Dodací list',
+  'Parts'                       => 'Díly',
+  'Payment'                     => 'Platba',
+  'Payments'                    => 'Platby',
+  'Preferences'                 => 'Nastavení',
+  'Projects'                    => 'Projects',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Purchase Order'              => 'Vystavená objednávka',
+  'Purchase Orders'             => 'Vystavené objednávky',
+  'Receipt'                     => 'Receipt',
+  'Receipts'                    => 'Receipts',
+  'Reconciliation'              => 'Reconciliation',
+  'Reports'                     => 'Sestavy',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Sales Order'                 => 'Pøijatá objednávka',
+  'Sales Orders'                => 'Pøijaté objednávky',
+  'Save to File'                => 'Ulo¾it do souboru',
+  'Send by E-Mail'              => 'Poslat e-mailem',
+  'Services'                    => 'Slu¾by',
+  'Statement'                   => 'Statement',
+  'Stock Assembly'              => 'Výrobky',
+  'Stylesheet'                  => 'Stylesheet',
+  'System'                      => 'Systém',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'Transactions'                => 'Polo¾ky',
+  'Trial Balance'               => 'Obratová pøedvaha',
+  'Vendors'                     => 'Vendors',
+  'Version'                     => 'Verze',
+  'localhost'                   => 'lokální server',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/oe b/sql-ledger/locale/cz/oe
new file mode 100644 (file)
index 0000000..609a9f1
--- /dev/null
@@ -0,0 +1,199 @@
+$self{texts} = {
+  'Add'                         => 'Pøidat',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => 'Nová objednávka (nákup)',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'Nová objednávka (pøíjem)',
+  'Address'                     => 'Adresa',
+  'Amount'                      => 'Èástka',
+  'Apr'                         => 'Dub',
+  'April'                       => 'Duben',
+  'Are you sure you want to delete Order Number' => 'Opravdu chcete vymazat objednávku èíslo',
+  'Attachment'                  => 'Pøílohy',
+  'Aug'                         => 'Srp',
+  'August'                      => 'Srpen',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Paleta',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Cannot delete order!',
+  'Cannot save order!'          => 'Cannot save order!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Zaplaceno',
+  'Confirm!'                    => 'Podtvrïte!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Pokraèování',
+  'Copies'                      => 'Kopie',
+  'Credit Limit'                => 'Úvìrový limit',
+  'Curr'                        => 'Mìna',
+  'Currency'                    => 'Mìna',
+  'Customer'                    => 'Odbìratel',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Datum',
+  'Dec'                         => 'Pro',
+  'December'                    => 'Prosinec',
+  'Delete'                      => 'Vymazat',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Popis',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Chybí E-mailová adresa!',
+  'Edit Purchase Order'         => 'Upravit vystavenou objednávku',
+  'Edit Sales Order'            => 'Upravit pøijatou objednávku',
+  'Exchangerate'                => 'Mìnový kurz',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Úno',
+  'February'                    => 'Únor',
+  'From'                        => 'z',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Vlo¾ené',
+  'Include in Report'           => 'Zahrnovat v sestavì',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Chybí datum vystavení!',
+  'Invoice Number missing!'     => 'Chybí èíslo faktury!',
+  'Item not on file!'           => 'Tato polo¾ka není v databázi!',
+  'Jan'                         => 'Led',
+  'January'                     => 'Leden',
+  'Jul'                         => 'Èec',
+  'July'                        => 'Èervenec',
+  'Jun'                         => 'Èer',
+  'June'                        => 'Èerven',
+  'Mar'                         => 'Bøe',
+  'March'                       => 'Bøezen',
+  'May'                         => 'Kvìten',
+  'May '                        => 'Kvì',
+  'Message'                     => 'Zpráva',
+  'Name'                        => 'Jméno',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Poznámky',
+  'Nov'                         => 'Lis',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Èíslo',
+  'Number missing in Row'       => 'Chybìjící èíslo na øádku',
+  'O'                           => 'O',
+  'Oct'                         => 'Øíj',
+  'October'                     => 'Øíjen',
+  'Open'                        => 'Otevøené',
+  'Order'                       => 'Objednávka',
+  'Order Date'                  => 'Datum objednávky',
+  'Order Date missing!'         => 'Chybí datum objednávky!',
+  'Order Number'                => 'Objednávka èíslo',
+  'Order Number missing!'       => 'Chybí èíslo objednávky!',
+  'Order deleted!'              => 'Order deleted!',
+  'Order saved!'                => 'Order saved!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Dodací list',
+  'Packing List Date missing!'  => 'Chybí datum dodacího listu',
+  'Packing List Number missing!' => 'Chybí èíslo dodacího listu',
+  'Part'                        => 'Zbo¾í',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Tiskárna',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Vystavená objednávka',
+  'Purchase Orders'             => 'Vystavené objednávky',
+  'Qty'                         => 'Mno¾ství',
+  'Recd'                        => 'Recd',
+  'Remaining'                   => 'Zbývá',
+  'Required by'                 => 'Po¾adováno do',
+  'Sales Order'                 => 'Pøijatá objednávka',
+  'Sales Orders'                => 'Pøijaté objednávky',
+  'Save'                        => 'Ulo¾it',
+  'Save as new'                 => 'Save as new',
+  'Screen'                      => 'Na obrazovku',
+  'Select from one of the items below' => 'Zvolte z ní¾e uvedených polo¾ek',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Záø',
+  'September'                   => 'Záøí',
+  'Service'                     => 'Slu¾ba',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Subject'                     => 'Pøedmìt',
+  'Subtotal'                    => 'Mezisouèet',
+  'Tax'                         => 'Daò',
+  'Tax Included'                => 'Cena vèetnì danì',
+  'Terms: Net'                  => 'Netto',
+  'To'                          => 'do',
+  'Total'                       => 'Celkem',
+  'Unit'                        => 'Jednotka',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Dodavatel',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'O jaký typ polo¾ky se jedná?',
+  'Yes'                         => 'Ano',
+  'days'                        => 'dní',
+  'ea'                          => 'm.j.',
+  'emailed to'                  => 'odesláno na adresu',
+  'sent to printer'             => 'vyti¹tìno',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'pøidat'                      => 'add',
+  'pokraèování'                 => 'continue',
+  'vymazat'                     => 'delete',
+  'e_mail'                      => 'e_mail',
+  'faktura'                     => 'invoice',
+  'print'                       => 'print',
+  'ulo¾it'                      => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'ano'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/pe b/sql-ledger/locale/cz/pe
new file mode 100644 (file)
index 0000000..de5aad3
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Pøidat',
+  'Add Project'                 => 'Add Project',
+  'All'                         => 'V¹e',
+  'Continue'                    => 'Pokraèování',
+  'Delete'                      => 'Vymazat',
+  'Description'                 => 'Popis',
+  'Edit Project'                => 'Edit Project',
+  'Number'                      => 'Èíslo',
+  'Orphaned'                    => 'Neprodejné',
+  'Project'                     => 'Project',
+  'Project Number missing!'     => 'Project Number missing!',
+  'Project deleted!'            => 'Project deleted!',
+  'Project saved!'              => 'Project saved!',
+  'Projects'                    => 'Projects',
+  'Save'                        => 'Ulo¾it',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'pøidat'                      => 'add',
+  'pokraèování'                 => 'continue',
+  'vymazat'                     => 'delete',
+  'ulo¾it'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/rc b/sql-ledger/locale/cz/rc
new file mode 100644 (file)
index 0000000..38999ec
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Úèet',
+  'Balance'                     => 'Balance',
+  'Cleared Balance'             => 'Cleared Balance',
+  'Continue'                    => 'Pokraèování',
+  'Date'                        => 'Datum',
+  'Deposit'                     => 'Deposit',
+  'Description'                 => 'Popis',
+  'Difference'                  => 'Difference',
+  'Done'                        => 'Done',
+  'Exchangerate Difference'     => 'Exchangerate Difference',
+  'From'                        => 'z',
+  'Out of balance!'             => 'Out of balance!',
+  'Payment'                     => 'Platba',
+  'Reconciliation'              => 'Reconciliation',
+  'Select all'                  => 'Select all',
+  'Source'                      => 'Zdroj',
+  'Statement Balance'           => 'Statement Balance',
+  'To'                          => 'do',
+  'Update'                      => 'Update',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'pokraèování'                 => 'continue',
+  'done'                        => 'done',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/cz/rp b/sql-ledger/locale/cz/rp
new file mode 100644 (file)
index 0000000..0896ce4
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'Analýza splatnosti',
+  'AR Aging'                    => 'Analýza splatnosti',
+  'Account'                     => 'Úèet',
+  'Accounts'                    => 'Úèty',
+  'Amount'                      => 'Èástka',
+  'Apr'                         => 'Dub',
+  'April'                       => 'Duben',
+  'Attachment'                  => 'Pøílohy',
+  'Aug'                         => 'Srp',
+  'August'                      => 'Srpen',
+  'Balance Sheet'               => 'Rozvaha',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Cash based',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Porovnáno k',
+  'Continue'                    => 'Pokraèování',
+  'Copies'                      => 'Kopie',
+  'Credit'                      => 'Dal',
+  'Current'                     => 'Current',
+  'Customer'                    => 'Odbìratel',
+  'Date'                        => 'Datum',
+  'Debit'                       => 'Má dáti',
+  'Dec'                         => 'Pro',
+  'December'                    => 'Prosinec',
+  'Decimalplaces'               => 'Decimalplaces',
+  'Description'                 => 'Popis',
+  'Due'                         => 'Splatno',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'E-mail Statement to',
+  'Feb'                         => 'Úno',
+  'February'                    => 'Únor',
+  'From'                        => 'z',
+  'GIFI'                        => 'Úètovací øetìzec',
+  'Heading'                     => 'Nadpis',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Vlo¾ené',
+  'Include in Report'           => 'Zahrnovat v sestavì',
+  'Income Statement'            => 'Výsledovka',
+  'Invoice'                     => 'Faktura',
+  'Jan'                         => 'Led',
+  'January'                     => 'Leden',
+  'Jul'                         => 'Èec',
+  'July'                        => 'Èervenec',
+  'Jun'                         => 'Èer',
+  'June'                        => 'Èerven',
+  'Mar'                         => 'Bøe',
+  'March'                       => 'Bøezen',
+  'May'                         => 'Kvìten',
+  'May '                        => 'Kvì',
+  'Message'                     => 'Zpráva',
+  'N/A'                         => '---',
+  'Nothing selected!'           => 'Nothing selected!',
+  'Nov'                         => 'Lis',
+  'November'                    => 'Listopad',
+  'Oct'                         => 'Øíj',
+  'October'                     => 'Øíjen',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Platby',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Tiskárna',
+  'Receipts'                    => 'Receipts',
+  'Report for'                  => 'Výkaz za',
+  'Retained Earnings'           => 'Nerozdìlený zisk',
+  'Screen'                      => 'Na obrazovku',
+  'Select all'                  => 'Select all',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Záø',
+  'September'                   => 'Záøí',
+  'Source'                      => 'Zdroj',
+  'Standard'                    => 'Standardní',
+  'Statement'                   => 'Statement',
+  'Statement sent to'           => 'Statement sent to',
+  'Statements sent to printer!' => 'Statements sent to printer!',
+  'Subject'                     => 'Pøedmìt',
+  'Subtotal'                    => 'Mezisouèet',
+  'Tax'                         => 'Daò',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'To'                          => 'do',
+  'Total'                       => 'Celkem',
+  'Trial Balance'               => 'Obratová pøedvaha',
+  'Vendor'                      => 'Dodavatel',
+  'as at'                       => 'as at',
+  'collected on sales'          => 'vybráno na výstupu',
+  'for Period'                  => 'za období',
+  'paid on purchases'           => 'zaplaceno na vstupu',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'pokraèování'                 => 'continue',
+  'e_mail'                      => 'e_mail',
+  'print'                       => 'print',
+  'select_all'                  => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/de/COPYING b/sql-ledger/locale/de/COPYING
new file mode 100644 (file)
index 0000000..b12eb1b
--- /dev/null
@@ -0,0 +1,22 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (C) 2002
+#
+# German texts:
+#
+#  Author: Thomas Bayen <tbayen@bayen.de>
+#          Gunter Ohrner <G.Ohrner@post.rwth-aachen.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+######################################################################
diff --git a/sql-ledger/locale/de/LANGUAGE b/sql-ledger/locale/de/LANGUAGE
new file mode 100644 (file)
index 0000000..fc0b977
--- /dev/null
@@ -0,0 +1 @@
+German
diff --git a/sql-ledger/locale/de/Num2text b/sql-ledger/locale/de/Num2text
new file mode 100644 (file)
index 0000000..be84a3c
--- /dev/null
@@ -0,0 +1,185 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# this is a variation of the Lingua package
+# written for check and receipt printing
+# it returns a properly formatted text string
+# for a number up to 10**12
+
+sub init {
+  my $self = shift;
+
+  %{ $self->{numbername} } =
+                   (0 => 'Null',
+                    1 => 'ein',
+                    2 => 'zwei',
+                   3 => 'drei',
+                   4 => 'vier',
+                   5 => 'fünf',
+                   6 => 'sechs',
+                   7 => 'sieben',
+                   8 => 'acht',
+                   9 => 'neun',
+                  10 => 'zehn',
+                  11 => 'elf',
+                  12 => 'zwölf',
+                  13 => 'dreizehn',
+                  14 => 'vierzehn',
+                  15 => 'fünfzehn',
+                  16 => 'sechzehn',
+                  17 => 'siebzehn',
+                  18 => 'achtzehn',
+                  19 => 'neunzehn',
+                  20 => 'zwanzig',
+                  30 => 'dreissig',
+                  40 => 'vierzig',
+                  50 => 'fünfzig',
+                  60 => 'sechzig',
+                  70 => 'siebzig',
+                  80 => 'achtzig',
+                  90 => 'neunzig',
+                10**2 => 'hundert',
+                10**3 => 'tausend',
+               10**6 => 'million',
+               10**9 => 'milliarde',
+              10**12 => 'billion'
+               );
+
+}
+
+
+sub num2text {
+  my ($self, $amount) = @_;
+
+  return $self->{numbername}{0} unless $amount;
+
+  my @textnumber = ();
+
+  # split amount into chunks of 3
+  my @num = reverse split //, $amount;
+  my @numblock = ();
+  my ($i, $appendn);
+  my @a = ();
+
+  while (@num) {
+    @a = ();
+    for (1 .. 3) {
+      push @a, shift @num;
+    }
+    push @numblock, join / /, reverse @a;
+  }
+  
+  my $belowhundred = !$#numblock;
+  
+  while (@numblock) {
+
+    $i = $#numblock;
+    @num = split //, $numblock[$i];
+    $appendn = "";
+    
+    $numblock[$i] *= 1;
+    
+    if ($numblock[$i] == 0) {
+      pop @numblock;
+      next;
+    }
+   
+    if ($numblock[$i] > 99) {
+      # the one from hundreds
+      push @textnumber, $self->{numbername}{$num[0]};
+     
+      # add hundred designation
+      push @textnumber, $self->{numbername}{10**2};
+
+      # reduce numblock
+      $numblock[$i] -= $num[0] * 100;
+    }
+    
+    $appendn = 'en' if ($i == 2);
+    $appendn = 'n' if ($i > 2);
+
+    if ($numblock[$i] > 9) {
+      # tens
+      push @textnumber, $self->format_ten($numblock[$i], $belowhundred);
+    } elsif ($numblock[$i] > 1) {
+      # ones
+      push @textnumber, $self->{numbername}{$numblock[$i]};
+    } elsif ($numblock[$i] == 1) {
+      if ($i == 0) {
+       push @textnumber, $self->{numbername}{$numblock[$i]}.'s';
+      } else {
+       if ($i >= 2) {
+         push @textnumber, $self->{numbername}{$numblock[$i]}.'e';
+       } else {
+         push @textnumber, $self->{numbername}{$numblock[$i]};
+       }
+      }
+      $appendn = "";
+    }
+    
+    # add thousand, million
+    if ($i) {
+      $amount = 10**($i * 3);
+      push @textnumber, $self->{numbername}{$amount}.$appendn;
+    }
+    
+    pop @numblock;
+    
+  }
+
+  join '', @textnumber;
+
+}
+
+
+sub format_ten {
+  my ($self, $amount, $belowhundred) = @_;
+  
+  my $textnumber = "";
+  my @num = split //, $amount;
+
+  if ($amount > 20) {
+    if ($num[1] == 0) { 
+      $textnumber = $self->{numbername}{$amount}; 
+    } else {
+      if ($belowhundred) {
+       $amount = $num[0] * 10;
+       $textnumber = $self->{numbername}{$num[1]}.'und'.$self->{numbername}{$amount};
+      } else {
+       $amount = $num[0] * 10;
+       $textnumber = $self->{numbername}{$amount}.$self->{numbername}{$num[1]};
+       $textnumber .= 's' if ($num[1] == 1);
+      }
+    }
+  } else {
+    $textnumber = $self->{numbername}{$amount};
+  }
+  
+  $textnumber;
+  
+}
+
+
+1;
+
diff --git a/sql-ledger/locale/de/admin b/sql-ledger/locale/de/admin
new file mode 100644 (file)
index 0000000..f41796d
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Zugriffkontrolle',
+  'Accounting'                  => 'Buchhaltung',
+  'Add User'                    => 'Benutzer anlegen',
+  'Address'                     => 'Adresse',
+  'Administration'              => 'Administration',
+  'Administrator'               => 'Verwalter',
+  'All Datasets up to date!'    => 'Alle Datenbanken sind auf aktuellem Stand.',
+  'Change Admin Password'       => 'Administratorpasswort ändern',
+  'Change Password'             => 'Passwort ändern',
+  'Character Set'               => 'Zeichensatz',
+  'Click on login name to edit!' => 'Zum Bearbeiten den Zugriffs-Namen anklicken!',
+  'Company'                     => 'Firma',
+  'Connect to'                  => 'Als Vorlage verwenden',
+  'Continue'                    => 'Weiter',
+  'Create Chart of Accounts'    => 'Kontenplan anlegen',
+  'Create Dataset'              => 'Datenbank anlegen',
+  'DBI not installed!'          => 'DBI ist nicht installiert!',
+  'Database'                    => 'Datenbank',
+  'Database Administration'     => 'Datenbank Administration',
+  'Database Driver not checked!' => 'Kein Datenbank-Treiber ausgewählt!',
+  'Database User missing!'      => 'Datenbank Benutzer fehlt!',
+  'Dataset'                     => 'Datenbank',
+  'Dataset missing!'            => 'Datenbank fehlt!',
+  'Dataset updated!'            => 'Datenbank erneuert!',
+  'Date Format'                 => 'Datumsformat',
+  'Delete'                      => 'Löschen',
+  'Delete Dataset'              => 'Datenbank löschen',
+  'Directory'                   => 'Verzeichnis',
+  'Driver'                      => 'Treiber',
+  'Dropdown Limit'              => 'Auswahllistenbegrenzung',
+  'E-mail'                      => 'eMail',
+  'Edit User'                   => 'Benutzerdaten bearbeiten',
+  'Existing Datasets'           => 'Existierende Datenbanken',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Datenbank-Rechner',
+  'Hostname missing!'           => 'Rechnername fehlt!',
+  'Incorrect Password!'         => 'Ungültiges Passwort!',
+  'Language'                    => 'Sprache',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Für lokale Verbindungen "Rechner" und "Port" freilassen.',
+  'Login'                       => 'Anmelden',
+  'Multibyte Encoding'          => 'Muiltibyte Encoding',
+  'Name'                        => 'Name',
+  'New Templates'               => 'Neue Vorlagen',
+  'No Database Drivers available!' => 'Kein Datenbank-Treiber verfügbar!',
+  'No Dataset selected!'        => 'Keine Datenbank ausgewählt!',
+  'Nothing to delete!'          => 'Es konnte nichts gelöscht werden!',
+  'Number Format'               => 'Zahlenformat',
+  'Oracle Database Administration' => 'Oracle Datenbank Administration',
+  'Password'                    => 'Passwort',
+  'Password changed!'           => 'Passwort geändert!',
+  'Pg Database Administration'  => 'Pg Datenbank Administration',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Portangabe fehlt!',
+  'Printer'                     => 'Drucker',
+  'Save'                        => 'Speichern',
+  'Select a Dataset to delete and press "Continue"' => 'Wählen Sie eine Datenbank und klicken Sie auf "Weiter"',
+  'Setup Templates'             => 'Vorlagen auswählen',
+  'Ship via'                    => 'Transportmittel',
+  'Signature'                   => 'Unterschrift',
+  'Stylesheet'                  => 'Stilvorlage',
+  'Templates'                   => 'Vorlagen',
+  'The following Datasets are not in use and can be deleted' => 'Die folgenden Datenbanken sind nicht in Verwendung und können gelöscht werden',
+  'The following Datasets need to be updated' => 'Folgende Datenbanken müssen aktualisiert werden',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'In diesem Schritt werden bestehende Datenbanken gesucht. Es werden noch keine Änderungen vorgenommen!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Um einer Gruppe einen neuen Benutzer hinzuzufügen, ändern und speichern Sie am einfachsten einen bestehenden Zugriffsnamen. Unter dem neuen Namen wird dann ein Benutzer mit denselben Einstellungen angelegt.',
+  'Update Dataset'              => 'Datenbank aktualisieren',
+  'Use Templates'               => 'Benutze Vorlagen',
+  'User'                        => 'Benutzer',
+  'User deleted!'               => 'Benutzer gelöscht!',
+  'User saved!'                 => 'Benutzer gespeichert!',
+  'Version'                     => 'Version',
+  'You must enter a host and port for local and remote connections!' => '"Rechner" und "Port" müssen für lokale und externe Verbindungen eingetragen werden!',
+  'does not exist'              => 'existiert nicht',
+  'is already a member!'        => 'ist bereits ein Mitglied!',
+  'localhost'                   => 'lokaler Rechner',
+  'locked!'                     => 'gesperrt!',
+  'successfully created!'       => 'wurde erfolgreich erstellt',
+  'successfully deleted!'       => 'wurde erfolgreich gelöscht',
+  'website'                     => 'Website',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'benutzer_anlegen'            => 'add_user',
+  'administratorpasswort_ändern' => 'change_admin_password',
+  'passwort_ändern'             => 'change_password',
+  'weiter'                      => 'continue',
+  'datenbank_anlegen'           => 'create_dataset',
+  'löschen'                     => 'delete',
+  'datenbank_löschen'           => 'delete_dataset',
+  'anmelden'                    => 'login',
+  'oracle_datenbank_administration' => 'oracle_database_administration',
+  'pg_datenbank_administration' => 'pg_database_administration',
+  'speichern'                   => 'save',
+  'datenbank_aktualisieren'     => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/de/all b/sql-ledger/locale/de/all
new file mode 100644 (file)
index 0000000..7e1d9b4
--- /dev/null
@@ -0,0 +1,499 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Verbindlichkeiten',
+  'AP Aging'                    => 'Offene Verbindl.',
+  'AP Transaction'              => 'Eingangsbuchung',
+  'AP Transactions'             => 'Eingangsbuchungen',
+  'AR'                          => 'Forderungen',
+  'AR Aging'                    => 'Offene Forderungen',
+  'AR Transaction'              => 'Ausgangsbuchung',
+  'AR Transactions'             => 'Ausgangsbuchungen',
+  'About'                       => 'Über',
+  'Access Control'              => 'Zugriffkontrolle',
+  'Account'                     => 'Konto',
+  'Account Number'              => 'Kontonummer',
+  'Account Number missing!'     => 'Kontonummer fehlt!',
+  'Account Type'                => 'Kontoart',
+  'Account Type missing!'       => 'Kontoart fehlt!',
+  'Account deleted!'            => 'Konto gelöscht!',
+  'Account saved!'              => 'Konto gespeichert!',
+  'Accounting'                  => 'Buchhaltung',
+  'Accounting Menu'             => 'Kontoverwaltung',
+  'Accounts'                    => 'Konten',
+  'Active'                      => 'Aktiv',
+  'Add'                         => 'Hinzufügen',
+  'Add Account'                 => 'Konto anlegen',
+  'Add Accounts Payables Transaction' => 'Eingangsbuchung anlegen',
+  'Add Accounts Receivables Transaction' => 'Ausgangsbuchung anlegen',
+  'Add Assembly'                => 'Erzeugnis anlegen',
+  'Add Customer'                => 'Kunde anlegen',
+  'Add GIFI'                    => 'GIFI anlegen',
+  'Add General Ledger Transaction' => 'Hinzufügen einer Buchung zum Hauptbuch',
+  'Add Group'                   => 'Gruppe anlegen',
+  'Add Part'                    => 'Ware anlegen',
+  'Add Project'                 => 'Projekt anlegen',
+  'Add Purchase Order'          => 'Einkaufsbeleg anlegen',
+  'Add Sales Invoice'           => 'Ausgangsrechnung anlegen',
+  'Add Sales Order'             => 'Verkaufsbeleg anlegen',
+  'Add Service'                 => 'Dienstleistung anlegen',
+  'Add Transaction'             => 'Buchung anlegen',
+  'Add User'                    => 'Benutzer anlegen',
+  'Add Vendor'                  => 'Lieferant anlegen',
+  'Add Vendor Invoice'          => 'Einkaufsrechnung anlegen',
+  'Address'                     => 'Adresse',
+  'Administration'              => 'Administration',
+  'Administrator'               => 'Verwalter',
+  'All'                         => 'Alle',
+  'All Datasets up to date!'    => 'Alle Datenbanken sind auf aktuellem Stand.',
+  'Amount'                      => 'Betrag',
+  'Amount Due'                  => 'Betrag fällig',
+  'Amount does not equal applied!' => 'Betrag stimmt nicht überein!',
+  'Amount missing!'             => 'Betrag fehlt!',
+  'Applied'                     => 'Ausgewählt',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Invoice Number' => 'Soll die Rechnung mit folgender Nummer wirklich gelöscht werden:',
+  'Are you sure you want to delete Order Number' => 'Soll die Bestellung mit folgender Nummer wirklich gelöscht werden:',
+  'Are you sure you want to delete Transaction' => 'Buchung wirklich löschen?',
+  'Assemblies'                  => 'Erzeugnisse',
+  'Assemblies restocked!'       => 'Erzeugnisse sind im Lager!',
+  'Assembly Number missing!'    => 'Erzeugnisnummer fehlt!',
+  'Asset'                       => 'Aktiva/Mittelverwendung',
+  'Attachment'                  => 'als Anhang',
+  'Audit Control'               => 'Bücherkontrolle',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'BOM'                         => 'Stückliste',
+  'Backup'                      => 'Sicherung',
+  'Backup sent to'              => 'Eine Sicherungskopie wurde gesandt an',
+  'Balance'                     => 'Bilanz',
+  'Balance Sheet'               => 'Bilanz',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Stellage',
+  'Books are open'              => 'Die Bücher sind geöffnet.',
+  'Bought'                      => 'Gekauft',
+  'Business Number'             => 'Firmennummer',
+  'C'                           => 'G',
+  'COGS'                        => 'Umsatzkosten',
+  'Cannot delete account!'      => 'Konto kann nicht gelöscht werden!',
+  'Cannot delete customer!'     => 'Kunde kann nicht gelöscht werden!',
+  'Cannot delete default account!' => 'Das Standard-Konto kann nicht gelöscht werden!',
+  'Cannot delete invoice!'      => 'Rechnung kann nicht gelöscht werden!',
+  'Cannot delete item!'         => 'Artikel kann nicht gelöscht werden!',
+  'Cannot delete order!'        => 'Bestellung kann nicht gelöscht werden!',
+  'Cannot delete transaction!'  => 'Buchung kann nicht gelöscht werden!',
+  'Cannot delete vendor!'       => 'Lieferant kann nicht gelöscht werden!',
+  'Cannot have a value in both Debit and Credit!' => 'Es kann nicht gleichzeitig Soll und Haben gebucht werden!',
+  'Cannot post a transaction without a value!' => 'Eine Buchung ohne Betrag kann nicht verbucht werden!',
+  'Cannot post invoice for a closed period!' => 'Das Rechnungsdatum fällt in einen abgeschlossen Zeitraum!',
+  'Cannot post invoice!'        => 'Rechnung kann nicht gebucht werden!',
+  'Cannot post payment for a closed period!' => 'Es können keine Zahlungen für abgeschlossene Bücher gebucht werden!',
+  'Cannot post payment!'        => 'Zahlung kann nicht gebucht werden!',
+  'Cannot post transaction for a closed period!' => 'Für einen bereits abgeschlossenen Zeitraum kann keine Buchung angelegt werden!',
+  'Cannot post transaction!'    => 'Rechnung kann nicht gebucht werden!',
+  'Cannot process payment for a closed period!' => 'Es kann keine Zahlung in einem abgeschlossenen Zeitraum verbucht werden!',
+  'Cannot save account!'        => 'Konto kann nicht gespeichert werden!',
+  'Cannot save order!'          => 'Bestellung kann nicht gespeichert werden!',
+  'Cannot save preferences!'    => 'Benutzereinstellungen können nicht gespeichert werden!',
+  'Cannot stock assemblies!'    => 'Erzeugnisse können nicht ins Lager!',
+  'Cash'                        => 'Kasse',
+  'Cash based'                  => 'basierend auf Barzahlung',
+  'Cc'                          => 'Cc',
+  'Change Admin Password'       => 'Administratorpasswort ändern',
+  'Change Password'             => 'Passwort ändern',
+  'Character Set'               => 'Zeichensatz',
+  'Chart of Accounts'           => 'Kontenübersicht',
+  'Check'                       => 'Scheck',
+  'Check printed!'              => 'Scheck ist gedruckt!',
+  'Check printing failed!'      => 'Scheck drucken ist fehlgeschlagen!',
+  'Cleared Balance'             => 'Abgeschlossen',
+  'Click on login name to edit!' => 'Zum Bearbeiten den Zugriffs-Namen anklicken!',
+  'Close Books up to'           => 'Die Bücher abschließen bis zum',
+  'Closed'                      => 'Geschlossen',
+  'Company'                     => 'Firma',
+  'Compare to'                  => 'Gegenüberstellen zu',
+  'Confirm!'                    => 'Bestätigen Sie!',
+  'Connect to'                  => 'Als Vorlage verwenden',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Weiter',
+  'Copies'                      => 'Kopien',
+  'Copy to COA'                 => 'In Kontenplan kopieren',
+  'Create Chart of Accounts'    => 'Kontenplan anlegen',
+  'Create Dataset'              => 'Datenbank anlegen',
+  'Credit'                      => 'Haben',
+  'Credit Limit'                => 'Kreditlimit',
+  'Curr'                        => 'Währung',
+  'Currency'                    => 'Währung',
+  'Current'                     => 'Betrag',
+  'Customer'                    => 'Kunde',
+  'Customer deleted!'           => 'Kunde gelöscht!',
+  'Customer missing!'           => 'Kundenname fehlt!',
+  'Customer not on file!'       => 'Kunde ist nicht in der Datenbank!',
+  'Customer saved!'             => 'Kunde gespeichert!',
+  'Customers'                   => 'Kunden',
+  'DBI not installed!'          => 'DBI ist nicht installiert!',
+  'Database'                    => 'Datenbank',
+  'Database Administration'     => 'Datenbank Administration',
+  'Database Driver not checked!' => 'Kein Datenbank-Treiber ausgewählt!',
+  'Database Host'               => 'Datenbank-Rechner',
+  'Database User missing!'      => 'Datenbank Benutzer fehlt!',
+  'Dataset'                     => 'Datenbank',
+  'Dataset missing!'            => 'Datenbank fehlt!',
+  'Dataset updated!'            => 'Datenbank erneuert!',
+  'Date'                        => 'Datum',
+  'Date Format'                 => 'Datumsformat',
+  'Date Paid'                   => 'Zahlungsdatum',
+  'Date missing!'               => 'Datum fehlt!',
+  'Debit'                       => 'Soll',
+  'Debit and credit out of balance!' => 'Soll und Haben müssen gleich sein.',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezember',
+  'Decimalplaces'               => 'Dezimalstellen',
+  'Delete'                      => 'Löschen',
+  'Delete Account'              => 'Konto löschen',
+  'Delete Dataset'              => 'Datenbank löschen',
+  'Delivery Date'               => 'Lieferung',
+  'Deposit'                     => 'Gutschrift',
+  'Description'                 => 'Beschreibung',
+  'Difference'                  => 'Differenz',
+  'Directory'                   => 'Verzeichnis',
+  'Discount'                    => 'Rabatt',
+  'Done'                        => 'Fertig',
+  'Drawing'                     => 'Zeichnung',
+  'Driver'                      => 'Treiber',
+  'Dropdown Limit'              => 'Auswahllistenbegrenzung',
+  'Due'                         => 'Fällig',
+  'Due Date'                    => 'Fälligkeitsdatum',
+  'Due Date missing!'           => 'Fälligkeitsdatum fehlt!',
+  'E-mail'                      => 'eMail',
+  'E-mail Statement to'         => 'eMail Fälligkeitsabrechnung an',
+  'E-mail address missing!'     => 'eMail-Adresse fehlt!',
+  'Edit'                        => 'Bearbeiten',
+  'Edit Account'                => 'Kontodaten bearbeiten',
+  'Edit Accounts Payables Transaction' => 'Einkaufsbuchung bearbeiten',
+  'Edit Accounts Receivables Transaction' => 'Ausgangsbuchung bearbeiten',
+  'Edit Assembly'               => 'Erzeugnis bearbeiten',
+  'Edit Customer'               => 'Kunde editieren',
+  'Edit GIFI'                   => 'GIFI editieren',
+  'Edit General Ledger Transaction' => 'Buchung im Hauptbuch bearbeiten',
+  'Edit Group'                  => 'Gruppe editieren',
+  'Edit Part'                   => 'Ware bearbeiten',
+  'Edit Preferences for'        => 'Benutzereinstellungen für',
+  'Edit Project'                => 'Projekt bearbeiten',
+  'Edit Purchase Order'         => 'Einkaufsbeleg bearbeiten',
+  'Edit Sales Invoice'          => 'Ausgangsrechnung bearbeiten',
+  'Edit Sales Order'            => 'Verkaufsbeleg bearbeiten',
+  'Edit Service'                => 'Dienstleistung bearbeiten',
+  'Edit Template'               => 'Vorlage bearbeiten',
+  'Edit User'                   => 'Benutzerdaten bearbeiten',
+  'Edit Vendor'                 => 'Lieferant editieren',
+  'Edit Vendor Invoice'         => 'Einkaufsrechnung bearbeiten',
+  'Employee'                    => 'Bearbeiter',
+  'Enforce transaction reversal for all dates' => 'Kontraeintragungen für jeden Zeitraum aktualisieren',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Durch Doppelpunkte getrennte Währungskürzel mit maximal 3 Buchstaben aufführen; Ihre eigene Landeswährung zuerst (z.B. EUR:USD:CAD)',
+  'Equity'                      => 'Passiva/Eigenkapital',
+  'Exch'                        => 'Wkurs.',
+  'Exchangerate'                => 'Wechselkurs',
+  'Exchangerate Difference'     => 'Wechselkursunterschied',
+  'Exchangerate for payment missing!' => 'Es fehlt der Wechselkurs für die Bezahlung!',
+  'Exchangerate missing!'       => 'Es fehlt der Wechselkurs!',
+  'Existing Datasets'           => 'Existierende Datenbanken',
+  'Expense'                     => 'Aufwand',
+  'Expense Account'             => 'Aufwandskonto',
+  'Expense/Asset'               => 'Aufwand/Anlagen',
+  'Extended'                    => 'Total',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februar',
+  'Foreign Exchange Gain'       => 'Wechselkurserträge',
+  'Foreign Exchange Loss'       => 'Wechselkursaufwendungen',
+  'From'                        => 'Von',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI gelöscht!',
+  'GIFI missing!'               => 'GIFI fehlt!',
+  'GIFI saved!'                 => 'GIFI gespeichert!',
+  'GL Transaction'              => 'Hauptbucheintragung',
+  'General Ledger'              => 'Hauptbuch',
+  'Goods & Services'            => 'Waren und Dienstleistungen',
+  'Group'                       => 'Gruppe',
+  'Group Items'                 => 'Waren gruppieren',
+  'Group deleted!'              => 'Gruppe gelöscht!',
+  'Group missing!'              => 'Gruppe fehlt!',
+  'Group saved!'                => 'Gruppe gespeichert!',
+  'Groups'                      => 'Gruppen',
+  'HTML Templates'              => 'HTML Vorlagen',
+  'Heading'                     => 'Überschrift',
+  'Host'                        => 'Datenbank-Rechner',
+  'Hostname missing!'           => 'Rechnername fehlt!',
+  'ID'                          => 'Nr.',
+  'Image'                       => 'Grafik',
+  'In-line'                     => 'im Textkörper (Inline)',
+  'Include in Report'           => 'In Bericht aufnehmen',
+  'Include in drop-down menus'  => 'In Aufklapp-Menü aufnehmen',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Soll dieses Konto auf dem Kunden- und Lieferantenformular angezeigt werden, um den Kunden/Lieferanten als steuerpflichtig zu markieren?',
+  'Income'                      => 'Einkommen',
+  'Income Account'              => 'Einkommenkonto',
+  'Income Statement'            => 'G & V',
+  'Incorrect Dataset version!'  => 'Datenbankversion stimmt nicht überein!',
+  'Incorrect Password!'         => 'Ungültiges Passwort!',
+  'Individual Items'            => 'Einzelteile',
+  'Inventory'                   => 'Inventar',
+  'Inventory Account'           => 'Warenbestand',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Bevor dieses Erzeugnis als ungültig markiert werden kann, muß das Inventar auf Null sein!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Bevor diese Ware als ungültig markiert werden kann, muß das Inventar Null sein!',
+  'Invoice'                     => 'Rechnung',
+  'Invoice Date'                => 'Rechnungsdatum',
+  'Invoice Date missing!'       => 'Rechnungsdatum fehlt!',
+  'Invoice Number'              => 'Rechnungsnummer',
+  'Invoice Number missing!'     => 'Rechnungsnummer fehlt!',
+  'Invoice deleted!'            => 'Rechnung gelöscht!',
+  'Invoice posted!'             => 'Rechnung verbucht!',
+  'Invoices'                    => 'Rechnungen',
+  'Is this a summary account to record' => 'Summenkonto für',
+  'Item deleted!'               => 'Artikel gelöscht!',
+  'Item not on file!'           => 'Dieser Artikel ist nicht in der Datenbank!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januar',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'LaTeX Templates'             => 'LaTeX Vorlagen',
+  'Language'                    => 'Sprache',
+  'Last Cost'                   => 'Letzte Kosten',
+  'Last Invoice Number'         => 'Letzte Rechnungsnummer',
+  'Last Numbers & Default Accounts' => 'Laufende Zähler und Standardkonten',
+  'Last Purchase Order Number'  => 'Letzte Enkaufsbelegnummer',
+  'Last Sales Order Number'     => 'Letzte Verkaufsbelegnummer',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Für lokale Verbindungen "Rechner" und "Port" freilassen.',
+  'Liability'                   => 'Passiva/Mittelherkunft',
+  'Licensed to'                 => 'Lizensiert für',
+  'Line Total'                  => 'Zeilensumme',
+  'Link'                        => 'Verknüpfungen',
+  'Link Accounts'               => 'Konten verknüpfen',
+  'List Accounts'               => 'Kontenliste',
+  'List GIFI'                   => 'GIFI aufzeigen',
+  'List Price'                  => 'Listenpreis',
+  'List Transactions'           => 'Buchungsliste',
+  'Login'                       => 'Anmelden',
+  'Logout'                      => 'Abmelden',
+  'Make'                        => 'Hersteller',
+  'Mar'                         => 'Mär',
+  'March'                       => 'März',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai',
+  'Message'                     => 'Nachricht',
+  'Microfiche'                  => 'Mikrofilm',
+  'Model'                       => 'Modell',
+  'Multibyte Encoding'          => 'Muiltibyte Encoding',
+  'N/A'                         => 'N.Z.',
+  'Name'                        => 'Name',
+  'Name missing!'               => 'Name fehlt!',
+  'New Templates'               => 'Neue Vorlagen',
+  'No'                          => 'Nein',
+  'No Database Drivers available!' => 'Kein Datenbank-Treiber verfügbar!',
+  'No Dataset selected!'        => 'Keine Datenbank ausgewählt!',
+  'No email address for'        => 'Keine eMail-Addresse für',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Bemerkungen',
+  'Nothing applied!'            => 'Sie haben nichts ausgewählt',
+  'Nothing selected!'           => 'Es wurde nichts ausgewählt!',
+  'Nothing to delete!'          => 'Es konnte nichts gelöscht werden!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number Format'               => 'Zahlenformat',
+  'Number missing in Row'       => 'Nummer fehlt in Zeile',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Ungültig',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'On Hand'                     => 'auf Lager',
+  'On Order'                    => 'auf Bestellung',
+  'Open'                        => 'Offen',
+  'Oracle Database Administration' => 'Oracle Datenbank Administration',
+  'Order'                       => 'Auftrag',
+  'Order Date'                  => 'Auftragsdatum',
+  'Order Date missing!'         => 'Auftragsdatum fehlt!',
+  'Order Entry'                 => 'Aufträge',
+  'Order Number'                => 'Auftragsnummer',
+  'Order Number missing!'       => 'Auftragsnummer fehlt!',
+  'Order deleted!'              => 'Auftrag gelöscht!',
+  'Order saved!'                => 'Auftrag gespeichert!',
+  'Ordered'                     => 'Vom Kunde bestellt',
+  'Orphaned'                    => 'nie benutzt',
+  'Out of balance!'             => 'Summen stimmen nicht überein!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Verpackungsliste',
+  'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
+  'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
+  'Paid'                        => 'Bezahlt',
+  'Paid in full'                => 'Voll bezahlt',
+  'Part'                        => 'Ware',
+  'Part Number missing!'        => 'Warennummer fehlt!',
+  'Parts'                       => 'Waren',
+  'Parts Inventory'             => 'Warenliste',
+  'Password'                    => 'Passwort',
+  'Password changed!'           => 'Passwort geändert!',
+  'Payables'                    => 'Verbindlichkeiten',
+  'Payment'                     => 'Zahlung',
+  'Payment date missing!'       => 'Tag der Zahlung fehlt!',
+  'Payment posted!'             => 'Zahlung gebucht!',
+  'Payments'                    => 'Zahlungen',
+  'Pg Database Administration'  => 'Pg Datenbank Administration',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Portangabe fehlt!',
+  'Post'                        => 'Buchen',
+  'Post as new'                 => 'Neu buchen',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Benutzereinstellungen',
+  'Preferences saved!'          => 'Einstellungen gespeichert!',
+  'Price'                       => 'Preis',
+  'Print'                       => 'Drucken',
+  'Printer'                     => 'Drucker',
+  'Project'                     => 'Projekt',
+  'Project Number'              => 'Projektnummer',
+  'Project Number missing!'     => 'Projektnummer fehlt!',
+  'Project deleted!'            => 'Projekt gelöscht!',
+  'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
+  'Project saved!'              => 'Projekt gespeichert!',
+  'Projects'                    => 'Projekte',
+  'Purchase Order'              => 'Einkaufsbeleg',
+  'Purchase Orders'             => 'Einkaufsbelege',
+  'Qty'                         => 'Anz',
+  'ROP'                         => 'UAB',
+  'Rate'                        => 'Rate',
+  'Recd'                        => 'Erh',
+  'Receipt'                     => 'Quittung',
+  'Receipt printed!'            => 'Quittung gedruckt!',
+  'Receipt printing failed!'    => 'Quittung konnte nicht gedruckt werden!',
+  'Receipts'                    => 'Quittungen',
+  'Receivables'                 => 'Forderungen',
+  'Reconciliation'              => 'Abgleichung',
+  'Record in'                   => 'Buchen auf',
+  'Reference'                   => 'Referenz',
+  'Reference missing!'          => 'Referenz fehlt!',
+  'Remaining'                   => 'Rest',
+  'Report for'                  => 'Bericht für',
+  'Reports'                     => 'Berichte',
+  'Required by'                 => 'Erforderlich am',
+  'Retained Earnings'           => 'Verbliebenes Einkommen',
+  'Sales'                       => 'Warenverkauf',
+  'Sales Invoice'               => 'Ausgangsrechnung',
+  'Sales Order'                 => 'Verkaufsbeleg',
+  'Sales Orders'                => 'Verkaufsbelege',
+  'Salesperson'                 => 'Verkaufsperson',
+  'Save'                        => 'Speichern',
+  'Save as new'                 => 'als neu speichern',
+  'Save to File'                => 'Auf Festplatte speichern',
+  'Screen'                      => 'Bildschirm',
+  'Select a Dataset to delete and press "Continue"' => 'Wählen Sie eine Datenbank und klicken Sie auf "Weiter"',
+  'Select all'                  => 'Alle auswählen',
+  'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
+  'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
+  'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
+  'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
+  'Sell Price'                  => 'Verkaufspreis',
+  'Send by E-Mail'              => 'Per eMail schicken',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Dienstleistung',
+  'Service Items'               => 'Dienstleistungen',
+  'Service Number missing!'     => 'Dienstleistungsnummer fehlt!',
+  'Services'                    => 'Leistungen',
+  'Setup Templates'             => 'Vorlagen auswählen',
+  'Ship'                        => 'Versand',
+  'Ship to'                     => 'Verschicken an',
+  'Ship via'                    => 'Transportmittel',
+  'Short'                       => 'Kurz',
+  'Signature'                   => 'Unterschrift',
+  'Sold'                        => 'Verkauft',
+  'Source'                      => 'Beleg',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Sammelrechnung',
+  'Statement Balance'           => 'Sammelrechnungsbilanz',
+  'Statement sent to'           => 'Sammelrechnung verschickt an',
+  'Statements sent to printer!' => 'Sammelrechnungen an Drucker geschickt!',
+  'Stock'                       => 'einlagern',
+  'Stock Assembly'              => 'Erzeugnis einlagern',
+  'Stylesheet'                  => 'Stilvorlage',
+  'Subject'                     => 'Betreff',
+  'Subtotal'                    => 'Zwischensumme',
+  'System'                      => 'System',
+  'Tax'                         => 'Steuer',
+  'Tax Accounts'                => 'Steuerkonto',
+  'Tax Included'                => 'Steuer im Preis inbegriffen',
+  'Tax collected'               => 'vereinnahmte Steuer',
+  'Tax paid'                    => 'Vorsteuer',
+  'Taxable'                     => 'Steuerpflichtig',
+  'Template saved!'             => 'Schablone gespeichert!',
+  'Templates'                   => 'Vorlagen',
+  'Terms: Net'                  => 'Zahlungsziel',
+  'The following Datasets are not in use and can be deleted' => 'Die folgenden Datenbanken sind nicht in Verwendung und können gelöscht werden',
+  'The following Datasets need to be updated' => 'Folgende Datenbanken müssen aktualisiert werden',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'In diesem Schritt werden bestehende Datenbanken gesucht. Es werden noch keine Änderungen vorgenommen!',
+  'To'                          => 'An',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Um einer Gruppe einen neuen Benutzer hinzuzufügen, ändern und speichern Sie am einfachsten einen bestehenden Zugriffsnamen. Unter dem neuen Namen wird dann ein Benutzer mit denselben Einstellungen angelegt.',
+  'Top Level'                   => 'Hauptbeschreibung',
+  'Total'                       => 'Summe',
+  'Transaction Date missing!'   => 'Buchungsdatum fehlt!',
+  'Transaction deleted!'        => 'Buchung gelöscht!',
+  'Transaction posted!'         => 'Buchung verbucht!',
+  'Transaction reversal enforced for all dates' => 'Fehleintragungen müssen für jeden Zeitraum mit einer Kontraeintragung ausgebessert werden',
+  'Transaction reversal enforced up to' => 'Fehleintragungen können bis zu dem angenebenen Zeitraum nur mit einer Kontraeintragung ausgebessert werden',
+  'Transactions'                => 'Buchungen',
+  'Transactions exist, cannot delete customer!' => 'Der Kunde kann nicht gelöscht werden, da Buchungen vorhanden sind!',
+  'Transactions exist, cannot delete vendor!' => 'Der Lieferant kann nicht gelöscht werden, da Buchungen vorhanden sind!',
+  'Transactions exist; cannot delete account!' => 'Das Konto kann nicht gelöscht werden, da es Buchungen enthält!',
+  'Trial Balance'               => 'Vergleichsbilanz',
+  'Unit'                        => 'Einh',
+  'Unit of measure'             => 'Maßeinheit',
+  'Update'                      => 'Erneuern',
+  'Update Dataset'              => 'Datenbank aktualisieren',
+  'Updated'                     => 'Erneuert am',
+  'Use Templates'               => 'Benutze Vorlagen',
+  'User'                        => 'Benutzer',
+  'User deleted!'               => 'Benutzer gelöscht!',
+  'User saved!'                 => 'Benutzer gespeichert!',
+  'Vendor'                      => 'Lieferant',
+  'Vendor Invoice'              => 'Einkaufsrechnung',
+  'Vendor deleted!'             => 'Lieferant gelöscht!',
+  'Vendor missing!'             => 'Lieferant fehlt!',
+  'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'Vendor saved!'               => 'Lieferant gespeichert!',
+  'Vendors'                     => 'Lieferanten',
+  'Version'                     => 'Version',
+  'Weight'                      => 'Gewicht',
+  'Weight Unit'                 => 'Gewichtseinh.',
+  'What type of item is this?'  => 'Was ist dieser Artikel?',
+  'Year End'                    => 'Jahresende',
+  'Yes'                         => 'Ja',
+  'You are logged out!'         => 'Auf wiedersehen!',
+  'You did not enter a name!'   => 'Sie haben keinen Namen eingegeben!',
+  'You must enter a host and port for local and remote connections!' => '"Rechner" und "Port" müssen für lokale und externe Verbindungen eingetragen werden!',
+  'as at'                       => 'zum Stand',
+  'collected on sales'          => 'erhalten durch Verkäufe',
+  'days'                        => 'Tage',
+  'does not exist'              => 'existiert nicht',
+  'ea'                          => 'pro',
+  'emailed to'                  => 'gemailt an',
+  'for Period'                  => 'für den Zeitraum',
+  'hr'                          => 'Std',
+  'is already a member!'        => 'ist bereits ein Mitglied!',
+  'is not a member!'            => 'ist kein Mitglied!',
+  'localhost'                   => 'lokaler Rechner',
+  'locked!'                     => 'gesperrt!',
+  'paid on purchases'           => 'gezahlt durch Einkäufe',
+  'sent to printer'             => 'an Drucker geschickt',
+  'successfully created!'       => 'wurde erfolgreich erstellt',
+  'successfully deleted!'       => 'wurde erfolgreich gelöscht',
+  'to'                          => 'bis',
+  'website'                     => 'Website',
+};
+
+1;
diff --git a/sql-ledger/locale/de/am b/sql-ledger/locale/de/am
new file mode 100644 (file)
index 0000000..9b93287
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Verbindlichkeiten',
+  'AR'                          => 'Forderungen',
+  'Account'                     => 'Konto',
+  'Account Number'              => 'Kontonummer',
+  'Account Number missing!'     => 'Kontonummer fehlt!',
+  'Account Type'                => 'Kontoart',
+  'Account Type missing!'       => 'Kontoart fehlt!',
+  'Account deleted!'            => 'Konto gelöscht!',
+  'Account saved!'              => 'Konto gespeichert!',
+  'Add Account'                 => 'Konto anlegen',
+  'Add GIFI'                    => 'GIFI anlegen',
+  'Address'                     => 'Adresse',
+  'Asset'                       => 'Aktiva/Mittelverwendung',
+  'Audit Control'               => 'Bücherkontrolle',
+  'Backup sent to'              => 'Eine Sicherungskopie wurde gesandt an',
+  'Books are open'              => 'Die Bücher sind geöffnet.',
+  'Business Number'             => 'Firmennummer',
+  'COGS'                        => 'Umsatzkosten',
+  'Cannot delete account!'      => 'Konto kann nicht gelöscht werden!',
+  'Cannot delete default account!' => 'Das Standard-Konto kann nicht gelöscht werden!',
+  'Cannot save account!'        => 'Konto kann nicht gespeichert werden!',
+  'Cannot save preferences!'    => 'Benutzereinstellungen können nicht gespeichert werden!',
+  'Character Set'               => 'Zeichensatz',
+  'Chart of Accounts'           => 'Kontenübersicht',
+  'Close Books up to'           => 'Die Bücher abschließen bis zum',
+  'Company'                     => 'Firma',
+  'Continue'                    => 'Weiter',
+  'Copy to COA'                 => 'In Kontenplan kopieren',
+  'Credit'                      => 'Haben',
+  'Date Format'                 => 'Datumsformat',
+  'Debit'                       => 'Soll',
+  'Delete'                      => 'Löschen',
+  'Delete Account'              => 'Konto löschen',
+  'Description'                 => 'Beschreibung',
+  'Dropdown Limit'              => 'Auswahllistenbegrenzung',
+  'E-mail'                      => 'eMail',
+  'Edit'                        => 'Bearbeiten',
+  'Edit Account'                => 'Kontodaten bearbeiten',
+  'Edit GIFI'                   => 'GIFI editieren',
+  'Edit Preferences for'        => 'Benutzereinstellungen für',
+  'Edit Template'               => 'Vorlage bearbeiten',
+  'Enforce transaction reversal for all dates' => 'Kontraeintragungen für jeden Zeitraum aktualisieren',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Durch Doppelpunkte getrennte Währungskürzel mit maximal 3 Buchstaben aufführen; Ihre eigene Landeswährung zuerst (z.B. EUR:USD:CAD)',
+  'Equity'                      => 'Passiva/Eigenkapital',
+  'Expense'                     => 'Aufwand',
+  'Expense Account'             => 'Aufwandskonto',
+  'Expense/Asset'               => 'Aufwand/Anlagen',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Wechselkurserträge',
+  'Foreign Exchange Loss'       => 'Wechselkursaufwendungen',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI gelöscht!',
+  'GIFI missing!'               => 'GIFI fehlt!',
+  'GIFI saved!'                 => 'GIFI gespeichert!',
+  'Heading'                     => 'Überschrift',
+  'Include in drop-down menus'  => 'In Aufklapp-Menü aufnehmen',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Soll dieses Konto auf dem Kunden- und Lieferantenformular angezeigt werden, um den Kunden/Lieferanten als steuerpflichtig zu markieren?',
+  'Income'                      => 'Einkommen',
+  'Income Account'              => 'Einkommenkonto',
+  'Inventory'                   => 'Inventar',
+  'Inventory Account'           => 'Warenbestand',
+  'Is this a summary account to record' => 'Summenkonto für',
+  'Language'                    => 'Sprache',
+  'Last Invoice Number'         => 'Letzte Rechnungsnummer',
+  'Last Numbers & Default Accounts' => 'Laufende Zähler und Standardkonten',
+  'Last Purchase Order Number'  => 'Letzte Enkaufsbelegnummer',
+  'Last Sales Order Number'     => 'Letzte Verkaufsbelegnummer',
+  'Liability'                   => 'Passiva/Mittelherkunft',
+  'Link'                        => 'Verknüpfungen',
+  'Name'                        => 'Name',
+  'No'                          => 'Nein',
+  'No email address for'        => 'Keine eMail-Addresse für',
+  'Number'                      => 'Nummer',
+  'Number Format'               => 'Zahlenformat',
+  'Parts Inventory'             => 'Warenliste',
+  'Password'                    => 'Passwort',
+  'Payables'                    => 'Verbindlichkeiten',
+  'Payment'                     => 'Zahlung',
+  'Phone'                       => 'Tel.',
+  'Preferences saved!'          => 'Einstellungen gespeichert!',
+  'Rate'                        => 'Rate',
+  'Receivables'                 => 'Forderungen',
+  'Sales'                       => 'Warenverkauf',
+  'Save'                        => 'Speichern',
+  'Service Items'               => 'Dienstleistungen',
+  'Ship via'                    => 'Transportmittel',
+  'Signature'                   => 'Unterschrift',
+  'Stylesheet'                  => 'Stilvorlage',
+  'Tax'                         => 'Steuer',
+  'Tax Accounts'                => 'Steuerkonto',
+  'Template saved!'             => 'Schablone gespeichert!',
+  'Transaction reversal enforced for all dates' => 'Fehleintragungen müssen für jeden Zeitraum mit einer Kontraeintragung ausgebessert werden',
+  'Transaction reversal enforced up to' => 'Fehleintragungen können bis zu dem angenebenen Zeitraum nur mit einer Kontraeintragung ausgebessert werden',
+  'Transactions exist; cannot delete account!' => 'Das Konto kann nicht gelöscht werden, da es Buchungen enthält!',
+  'Weight Unit'                 => 'Gewichtseinh.',
+  'Year End'                    => 'Jahresende',
+  'Yes'                         => 'Ja',
+  'does not exist'              => 'existiert nicht',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'konto_anlegen'               => 'add_account',
+  'weiter'                      => 'continue',
+  'in_kontenplan_kopieren'      => 'copy_to_coa',
+  'löschen'                     => 'delete',
+  'bearbeiten'                  => 'edit',
+  'kontodaten_bearbeiten'       => 'edit_account',
+  'speichern'                   => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/de/ap b/sql-ledger/locale/de/ap
new file mode 100644 (file)
index 0000000..59a6d47
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Eingangsbuchung',
+  'AP Transactions'             => 'Eingangsbuchungen',
+  'Account'                     => 'Konto',
+  'Add Accounts Payables Transaction' => 'Eingangsbuchung anlegen',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Betrag',
+  'Amount Due'                  => 'Betrag fällig',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Transaction' => 'Buchung wirklich löschen?',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Cannot delete transaction!'  => 'Buchung kann nicht gelöscht werden!',
+  'Cannot post payment for a closed period!' => 'Es können keine Zahlungen für abgeschlossene Bücher gebucht werden!',
+  'Cannot post transaction for a closed period!' => 'Für einen bereits abgeschlossenen Zeitraum kann keine Buchung angelegt werden!',
+  'Cannot post transaction!'    => 'Rechnung kann nicht gebucht werden!',
+  'Closed'                      => 'Geschlossen',
+  'Confirm!'                    => 'Bestätigen Sie!',
+  'Continue'                    => 'Weiter',
+  'Currency'                    => 'Währung',
+  'Customer not on file!'       => 'Kunde ist nicht in der Datenbank!',
+  'Date'                        => 'Datum',
+  'Date Paid'                   => 'Zahlungsdatum',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezember',
+  'Delete'                      => 'Löschen',
+  'Description'                 => 'Beschreibung',
+  'Due Date'                    => 'Fälligkeitsdatum',
+  'Due Date missing!'           => 'Fälligkeitsdatum fehlt!',
+  'Edit Accounts Payables Transaction' => 'Einkaufsbuchung bearbeiten',
+  'Employee'                    => 'Bearbeiter',
+  'Exch'                        => 'Wkurs.',
+  'Exchangerate'                => 'Wechselkurs',
+  'Exchangerate for payment missing!' => 'Es fehlt der Wechselkurs für die Bezahlung!',
+  'Exchangerate missing!'       => 'Es fehlt der Wechselkurs!',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februar',
+  'From'                        => 'Von',
+  'ID'                          => 'Nr.',
+  'Include in Report'           => 'In Bericht aufnehmen',
+  'Invoice'                     => 'Rechnung',
+  'Invoice Date'                => 'Rechnungsdatum',
+  'Invoice Date missing!'       => 'Rechnungsdatum fehlt!',
+  'Invoice Number'              => 'Rechnungsnummer',
+  'Invoice Number missing!'     => 'Rechnungsnummer fehlt!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januar',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'März',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai',
+  'Notes'                       => 'Bemerkungen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Open'                        => 'Offen',
+  'Order'                       => 'Auftrag',
+  'Order Number'                => 'Auftragsnummer',
+  'Paid'                        => 'Bezahlt',
+  'Payment date missing!'       => 'Tag der Zahlung fehlt!',
+  'Payments'                    => 'Zahlungen',
+  'Post'                        => 'Buchen',
+  'Post as new'                 => 'Neu buchen',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
+  'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
+  'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Beleg',
+  'Subtotal'                    => 'Zwischensumme',
+  'Tax'                         => 'Steuer',
+  'Tax Included'                => 'Steuer im Preis inbegriffen',
+  'Total'                       => 'Summe',
+  'Transaction deleted!'        => 'Buchung gelöscht!',
+  'Transaction posted!'         => 'Buchung verbucht!',
+  'Update'                      => 'Erneuern',
+  'Vendor'                      => 'Lieferant',
+  'Vendor Invoice'              => 'Einkaufsrechnung',
+  'Vendor missing!'             => 'Lieferant fehlt!',
+  'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'Yes'                         => 'Ja',
+  'to'                          => 'bis',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'eingangsbuchung'             => 'ap_transaction',
+  'eingangsbuchung_anlegen'     => 'add_accounts_payables_transaction',
+  'weiter'                      => 'continue',
+  'löschen'                     => 'delete',
+  'einkaufsbuchung_bearbeiten'  => 'edit_accounts_payables_transaction',
+  'buchen'                      => 'post',
+  'neu_buchen'                  => 'post_as_new',
+  'erneuern'                    => 'update',
+  'einkaufsrechnung'            => 'vendor_invoice',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/de/ar b/sql-ledger/locale/de/ar
new file mode 100644 (file)
index 0000000..741bc92
--- /dev/null
@@ -0,0 +1,134 @@
+$self{texts} = {
+  'AR Transaction'              => 'Ausgangsbuchung',
+  'AR Transactions'             => 'Ausgangsbuchungen',
+  'Account'                     => 'Konto',
+  'Add Accounts Receivables Transaction' => 'Ausgangsbuchung anlegen',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Betrag',
+  'Amount Due'                  => 'Betrag fällig',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Transaction' => 'Buchung wirklich löschen?',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Cannot delete transaction!'  => 'Buchung kann nicht gelöscht werden!',
+  'Cannot post payment for a closed period!' => 'Es können keine Zahlungen für abgeschlossene Bücher gebucht werden!',
+  'Cannot post transaction for a closed period!' => 'Für einen bereits abgeschlossenen Zeitraum kann keine Buchung angelegt werden!',
+  'Cannot post transaction!'    => 'Rechnung kann nicht gebucht werden!',
+  'Closed'                      => 'Geschlossen',
+  'Confirm!'                    => 'Bestätigen Sie!',
+  'Continue'                    => 'Weiter',
+  'Credit Limit'                => 'Kreditlimit',
+  'Currency'                    => 'Währung',
+  'Customer'                    => 'Kunde',
+  'Customer missing!'           => 'Kundenname fehlt!',
+  'Customer not on file!'       => 'Kunde ist nicht in der Datenbank!',
+  'Date'                        => 'Datum',
+  'Date Paid'                   => 'Zahlungsdatum',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezember',
+  'Delete'                      => 'Löschen',
+  'Description'                 => 'Beschreibung',
+  'Due Date'                    => 'Fälligkeitsdatum',
+  'Due Date missing!'           => 'Fälligkeitsdatum fehlt!',
+  'Edit Accounts Receivables Transaction' => 'Ausgangsbuchung bearbeiten',
+  'Exch'                        => 'Wkurs.',
+  'Exchangerate'                => 'Wechselkurs',
+  'Exchangerate for payment missing!' => 'Es fehlt der Wechselkurs für die Bezahlung!',
+  'Exchangerate missing!'       => 'Es fehlt der Wechselkurs!',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februar',
+  'From'                        => 'Von',
+  'ID'                          => 'Nr.',
+  'Include in Report'           => 'In Bericht aufnehmen',
+  'Invoice'                     => 'Rechnung',
+  'Invoice Date'                => 'Rechnungsdatum',
+  'Invoice Date missing!'       => 'Rechnungsdatum fehlt!',
+  'Invoice Number'              => 'Rechnungsnummer',
+  'Invoice Number missing!'     => 'Rechnungsnummer fehlt!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januar',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'März',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai',
+  'Notes'                       => 'Bemerkungen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Open'                        => 'Offen',
+  'Order'                       => 'Auftrag',
+  'Order Number'                => 'Auftragsnummer',
+  'Paid'                        => 'Bezahlt',
+  'Payment date missing!'       => 'Tag der Zahlung fehlt!',
+  'Payments'                    => 'Zahlungen',
+  'Post'                        => 'Buchen',
+  'Post as new'                 => 'Neu buchen',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
+  'Remaining'                   => 'Rest',
+  'Sales Invoice'               => 'Ausgangsrechnung',
+  'Salesperson'                 => 'Verkaufsperson',
+  'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
+  'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Ship via'                    => 'Transportmittel',
+  'Source'                      => 'Beleg',
+  'Subtotal'                    => 'Zwischensumme',
+  'Tax'                         => 'Steuer',
+  'Tax Included'                => 'Steuer im Preis inbegriffen',
+  'Total'                       => 'Summe',
+  'Transaction deleted!'        => 'Buchung gelöscht!',
+  'Transaction posted!'         => 'Buchung verbucht!',
+  'Update'                      => 'Erneuern',
+  'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'Yes'                         => 'Ja',
+  'to'                          => 'bis',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'ausgangsbuchung'             => 'ar_transaction',
+  'weiter'                      => 'continue',
+  'löschen'                     => 'delete',
+  'buchen'                      => 'post',
+  'neu_buchen'                  => 'post_as_new',
+  'ausgangsrechnung'            => 'sales_invoice',
+  'erneuern'                    => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/de/arap b/sql-ledger/locale/de/arap
new file mode 100644 (file)
index 0000000..7070ce1
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Adresse',
+  'Continue'                    => 'Weiter',
+  'Customer not on file!'       => 'Kunde ist nicht in der Datenbank!',
+  'Description'                 => 'Beschreibung',
+  'Number'                      => 'Nummer',
+  'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
+  'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
+  'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
+  'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'vendor_invoice'              => 'vendor_invoice',
+  'weiter'                      => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/de/ca b/sql-ledger/locale/de/ca
new file mode 100644 (file)
index 0000000..d140801
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Balance'                     => 'Bilanz',
+  'Chart of Accounts'           => 'Kontenübersicht',
+  'Credit'                      => 'Haben',
+  'Date'                        => 'Datum',
+  'Debit'                       => 'Soll',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezember',
+  'Description'                 => 'Beschreibung',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februar',
+  'From'                        => 'Von',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'In Bericht aufnehmen',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januar',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'List Transactions'           => 'Buchungsliste',
+  'Mar'                         => 'Mär',
+  'March'                       => 'März',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Reference'                   => 'Referenz',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Subtotal'                    => 'Zwischensumme',
+  'to'                          => 'bis',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'buchungsliste'               => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/de/cp b/sql-ledger/locale/de/cp
new file mode 100644 (file)
index 0000000..125874e
--- /dev/null
@@ -0,0 +1,77 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Betrag',
+  'Amount does not equal applied!' => 'Betrag stimmt nicht überein!',
+  'Amount missing!'             => 'Betrag fehlt!',
+  'Applied'                     => 'Ausgewählt',
+  'Cannot post payment!'        => 'Zahlung kann nicht gebucht werden!',
+  'Cannot process payment for a closed period!' => 'Es kann keine Zahlung in einem abgeschlossenen Zeitraum verbucht werden!',
+  'Check'                       => 'Scheck',
+  'Check printed!'              => 'Scheck ist gedruckt!',
+  'Check printing failed!'      => 'Scheck drucken ist fehlgeschlagen!',
+  'Continue'                    => 'Weiter',
+  'Currency'                    => 'Währung',
+  'Customer'                    => 'Kunde',
+  'Customer not on file!'       => 'Kunde ist nicht in der Datenbank!',
+  'Date'                        => 'Datum',
+  'Date missing!'               => 'Datum fehlt!',
+  'Description'                 => 'Beschreibung',
+  'Due'                         => 'Fällig',
+  'Exchangerate'                => 'Wechselkurs',
+  'From'                        => 'Von',
+  'Invoice'                     => 'Rechnung',
+  'Invoices'                    => 'Rechnungen',
+  'Nothing applied!'            => 'Sie haben nichts ausgewählt',
+  'Number'                      => 'Nummer',
+  'Paid in full'                => 'Voll bezahlt',
+  'Payment'                     => 'Zahlung',
+  'Payment posted!'             => 'Zahlung gebucht!',
+  'Post'                        => 'Buchen',
+  'Print'                       => 'Drucken',
+  'Printer'                     => 'Drucker',
+  'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
+  'Receipt'                     => 'Quittung',
+  'Receipt printed!'            => 'Quittung gedruckt!',
+  'Receipt printing failed!'    => 'Quittung konnte nicht gedruckt werden!',
+  'Reference'                   => 'Referenz',
+  'Screen'                      => 'Bildschirm',
+  'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
+  'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
+  'Update'                      => 'Erneuern',
+  'Vendor'                      => 'Lieferant',
+  'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'to'                          => 'bis',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'weiter'                      => 'continue',
+  'buchen'                      => 'post',
+  'drucken'                     => 'print',
+  'erneuern'                    => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/de/ct b/sql-ledger/locale/de/ct
new file mode 100644 (file)
index 0000000..07d2607
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Hinzufügen',
+  'Address'                     => 'Adresse',
+  'All'                         => 'Alle',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Kunde kann nicht gelöscht werden!',
+  'Cannot delete vendor!'       => 'Lieferant kann nicht gelöscht werden!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Weiter',
+  'Credit Limit'                => 'Kreditlimit',
+  'Customer deleted!'           => 'Kunde gelöscht!',
+  'Customer saved!'             => 'Kunde gespeichert!',
+  'Customers'                   => 'Kunden',
+  'Delete'                      => 'Löschen',
+  'Discount'                    => 'Rabatt',
+  'E-mail'                      => 'eMail',
+  'Edit Customer'               => 'Kunde editieren',
+  'Edit Vendor'                 => 'Lieferant editieren',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'In Bericht aufnehmen',
+  'Invoice'                     => 'Rechnung',
+  'Name'                        => 'Name',
+  'Name missing!'               => 'Name fehlt!',
+  'Notes'                       => 'Bemerkungen',
+  'Number'                      => 'Nummer',
+  'Order'                       => 'Auftrag',
+  'Orphaned'                    => 'nie benutzt',
+  'Phone'                       => 'Tel.',
+  'Save'                        => 'Speichern',
+  'Ship to'                     => 'Verschicken an',
+  'Tax Included'                => 'Steuer im Preis inbegriffen',
+  'Taxable'                     => 'Steuerpflichtig',
+  'Terms: Net'                  => 'Zahlungsziel',
+  'Transactions exist, cannot delete customer!' => 'Der Kunde kann nicht gelöscht werden, da Buchungen vorhanden sind!',
+  'Transactions exist, cannot delete vendor!' => 'Der Lieferant kann nicht gelöscht werden, da Buchungen vorhanden sind!',
+  'Vendor deleted!'             => 'Lieferant gelöscht!',
+  'Vendor saved!'               => 'Lieferant gespeichert!',
+  'Vendors'                     => 'Lieferanten',
+  'days'                        => 'Tage',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'hinzufügen'                  => 'add',
+  'weiter'                      => 'continue',
+  'löschen'                     => 'delete',
+  'rechnung'                    => 'invoice',
+  'auftrag'                     => 'order',
+  'speichern'                   => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/de/gl b/sql-ledger/locale/de/gl
new file mode 100644 (file)
index 0000000..7163493
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Eingangsbuchung',
+  'AR Transaction'              => 'Ausgangsbuchung',
+  'Account'                     => 'Konto',
+  'Add General Ledger Transaction' => 'Hinzufügen einer Buchung zum Hauptbuch',
+  'Address'                     => 'Adresse',
+  'All'                         => 'Alle',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Transaction' => 'Buchung wirklich löschen?',
+  'Asset'                       => 'Aktiva/Mittelverwendung',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Balance'                     => 'Bilanz',
+  'Cannot delete transaction!'  => 'Buchung kann nicht gelöscht werden!',
+  'Cannot have a value in both Debit and Credit!' => 'Es kann nicht gleichzeitig Soll und Haben gebucht werden!',
+  'Cannot post a transaction without a value!' => 'Eine Buchung ohne Betrag kann nicht verbucht werden!',
+  'Cannot post transaction for a closed period!' => 'Für einen bereits abgeschlossenen Zeitraum kann keine Buchung angelegt werden!',
+  'Confirm!'                    => 'Bestätigen Sie!',
+  'Continue'                    => 'Weiter',
+  'Credit'                      => 'Haben',
+  'Customer not on file!'       => 'Kunde ist nicht in der Datenbank!',
+  'Date'                        => 'Datum',
+  'Debit'                       => 'Soll',
+  'Debit and credit out of balance!' => 'Soll und Haben müssen gleich sein.',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezember',
+  'Delete'                      => 'Löschen',
+  'Description'                 => 'Beschreibung',
+  'Edit General Ledger Transaction' => 'Buchung im Hauptbuch bearbeiten',
+  'Equity'                      => 'Passiva/Eigenkapital',
+  'Expense'                     => 'Aufwand',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februar',
+  'From'                        => 'Von',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'Hauptbucheintragung',
+  'General Ledger'              => 'Hauptbuch',
+  'ID'                          => 'Nr.',
+  'Include in Report'           => 'In Bericht aufnehmen',
+  'Income'                      => 'Einkommen',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januar',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Liability'                   => 'Passiva/Mittelherkunft',
+  'Mar'                         => 'Mär',
+  'March'                       => 'März',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai',
+  'Notes'                       => 'Bemerkungen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Post'                        => 'Buchen',
+  'Post as new'                 => 'Neu buchen',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
+  'Reference'                   => 'Referenz',
+  'Reference missing!'          => 'Referenz fehlt!',
+  'Reports'                     => 'Berichte',
+  'Sales Invoice'               => 'Ausgangsrechnung',
+  'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
+  'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Beleg',
+  'Subtotal'                    => 'Zwischensumme',
+  'Transaction Date missing!'   => 'Buchungsdatum fehlt!',
+  'Transaction deleted!'        => 'Buchung gelöscht!',
+  'Transaction posted!'         => 'Buchung verbucht!',
+  'Update'                      => 'Erneuern',
+  'Vendor Invoice'              => 'Einkaufsrechnung',
+  'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'Yes'                         => 'Ja',
+  'to'                          => 'bis',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'eingangsbuchung'             => 'ap_transaction',
+  'ausgangsbuchung'             => 'ar_transaction',
+  'weiter'                      => 'continue',
+  'löschen'                     => 'delete',
+  'hauptbucheintragung'         => 'gl_transaction',
+  'buchen'                      => 'post',
+  'neu_buchen'                  => 'post_as_new',
+  'ausgangsrechnung'            => 'sales_invoice',
+  'erneuern'                    => 'update',
+  'einkaufsrechnung'            => 'vendor_invoice',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/de/ic b/sql-ledger/locale/de/ic
new file mode 100644 (file)
index 0000000..6fa30d1
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Aktiv',
+  'Add'                         => 'Hinzufügen',
+  'Add Assembly'                => 'Erzeugnis anlegen',
+  'Add Part'                    => 'Ware anlegen',
+  'Add Purchase Order'          => 'Einkaufsbeleg anlegen',
+  'Add Sales Order'             => 'Verkaufsbeleg anlegen',
+  'Add Service'                 => 'Dienstleistung anlegen',
+  'Address'                     => 'Adresse',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Assemblies'                  => 'Erzeugnisse',
+  'Assemblies restocked!'       => 'Erzeugnisse sind im Lager!',
+  'Assembly Number missing!'    => 'Erzeugnisnummer fehlt!',
+  'Attachment'                  => 'als Anhang',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'BOM'                         => 'Stückliste',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Stellage',
+  'Bought'                      => 'Gekauft',
+  'COGS'                        => 'Umsatzkosten',
+  'Cannot delete item!'         => 'Artikel kann nicht gelöscht werden!',
+  'Cannot stock assemblies!'    => 'Erzeugnisse können nicht ins Lager!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Geschlossen',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Weiter',
+  'Copies'                      => 'Kopien',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezember',
+  'Delete'                      => 'Löschen',
+  'Delivery Date'               => 'Lieferung',
+  'Description'                 => 'Beschreibung',
+  'Drawing'                     => 'Zeichnung',
+  'E-mail'                      => 'eMail',
+  'E-mail address missing!'     => 'eMail-Adresse fehlt!',
+  'Edit Assembly'               => 'Erzeugnis bearbeiten',
+  'Edit Part'                   => 'Ware bearbeiten',
+  'Edit Service'                => 'Dienstleistung bearbeiten',
+  'Expense'                     => 'Aufwand',
+  'Extended'                    => 'Total',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februar',
+  'From'                        => 'Von',
+  'Group'                       => 'Gruppe',
+  'Group Items'                 => 'Waren gruppieren',
+  'Image'                       => 'Grafik',
+  'In-line'                     => 'im Textkörper (Inline)',
+  'Include in Report'           => 'In Bericht aufnehmen',
+  'Income'                      => 'Einkommen',
+  'Individual Items'            => 'Einzelteile',
+  'Inventory'                   => 'Inventar',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Bevor dieses Erzeugnis als ungültig markiert werden kann, muß das Inventar auf Null sein!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Bevor diese Ware als ungültig markiert werden kann, muß das Inventar Null sein!',
+  'Invoice'                     => 'Rechnung',
+  'Invoice Date missing!'       => 'Rechnungsdatum fehlt!',
+  'Invoice Number'              => 'Rechnungsnummer',
+  'Invoice Number missing!'     => 'Rechnungsnummer fehlt!',
+  'Item deleted!'               => 'Artikel gelöscht!',
+  'Item not on file!'           => 'Dieser Artikel ist nicht in der Datenbank!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januar',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Last Cost'                   => 'Letzte Kosten',
+  'Line Total'                  => 'Zeilensumme',
+  'Link Accounts'               => 'Konten verknüpfen',
+  'List Price'                  => 'Listenpreis',
+  'Make'                        => 'Hersteller',
+  'Mar'                         => 'Mär',
+  'March'                       => 'März',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai',
+  'Message'                     => 'Nachricht',
+  'Microfiche'                  => 'Mikrofilm',
+  'Model'                       => 'Modell',
+  'Name'                        => 'Name',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Bemerkungen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Nummer fehlt in Zeile',
+  'Obsolete'                    => 'Ungültig',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'On Hand'                     => 'auf Lager',
+  'On Order'                    => 'auf Bestellung',
+  'Order'                       => 'Auftrag',
+  'Order Date missing!'         => 'Auftragsdatum fehlt!',
+  'Order Number'                => 'Auftragsnummer',
+  'Order Number missing!'       => 'Auftragsnummer fehlt!',
+  'Ordered'                     => 'Vom Kunde bestellt',
+  'Orphaned'                    => 'nie benutzt',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Verpackungsliste',
+  'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
+  'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
+  'Part'                        => 'Ware',
+  'Part Number missing!'        => 'Warennummer fehlt!',
+  'Parts'                       => 'Waren',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preis',
+  'Printer'                     => 'Drucker',
+  'Project'                     => 'Projekt',
+  'Purchase Order'              => 'Einkaufsbeleg',
+  'Qty'                         => 'Anz',
+  'ROP'                         => 'UAB',
+  'Recd'                        => 'Erh',
+  'Required by'                 => 'Erforderlich am',
+  'Sales'                       => 'Warenverkauf',
+  'Sales Order'                 => 'Verkaufsbeleg',
+  'Save'                        => 'Speichern',
+  'Save as new'                 => 'als neu speichern',
+  'Screen'                      => 'Bildschirm',
+  'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
+  'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
+  'Sell Price'                  => 'Verkaufspreis',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Dienstleistung',
+  'Service Number missing!'     => 'Dienstleistungsnummer fehlt!',
+  'Services'                    => 'Leistungen',
+  'Ship'                        => 'Versand',
+  'Ship to'                     => 'Verschicken an',
+  'Short'                       => 'Kurz',
+  'Sold'                        => 'Verkauft',
+  'Stock'                       => 'einlagern',
+  'Stock Assembly'              => 'Erzeugnis einlagern',
+  'Subject'                     => 'Betreff',
+  'Subtotal'                    => 'Zwischensumme',
+  'Tax'                         => 'Steuer',
+  'To'                          => 'An',
+  'Top Level'                   => 'Hauptbeschreibung',
+  'Total'                       => 'Summe',
+  'Unit'                        => 'Einh',
+  'Unit of measure'             => 'Maßeinheit',
+  'Update'                      => 'Erneuern',
+  'Updated'                     => 'Erneuert am',
+  'Weight'                      => 'Gewicht',
+  'What type of item is this?'  => 'Was ist dieser Artikel?',
+  'ea'                          => 'pro',
+  'emailed to'                  => 'gemailt an',
+  'hr'                          => 'Std',
+  'sent to printer'             => 'an Drucker geschickt',
+  'to'                          => 'bis',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'hinzufügen'                  => 'add',
+  'erzeugnis_anlegen'           => 'add_assembly',
+  'ware_anlegen'                => 'add_part',
+  'dienstleistung_anlegen'      => 'add_service',
+  'weiter'                      => 'continue',
+  'löschen'                     => 'delete',
+  'erzeugnis_bearbeiten'        => 'edit_assembly',
+  'ware_bearbeiten'             => 'edit_part',
+  'dienstleistung_bearbeiten'   => 'edit_service',
+  'speichern'                   => 'save',
+  'als_neu_speichern'           => 'save_as_new',
+  'erneuern'                    => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/de/io b/sql-ledger/locale/de/io
new file mode 100644 (file)
index 0000000..3e94eb8
--- /dev/null
@@ -0,0 +1,108 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Einkaufsbeleg anlegen',
+  'Add Sales Order'             => 'Verkaufsbeleg anlegen',
+  'Address'                     => 'Adresse',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Attachment'                  => 'als Anhang',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Stellage',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Weiter',
+  'Copies'                      => 'Kopien',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezember',
+  'Delivery Date'               => 'Lieferung',
+  'Description'                 => 'Beschreibung',
+  'E-mail'                      => 'eMail',
+  'E-mail address missing!'     => 'eMail-Adresse fehlt!',
+  'Extended'                    => 'Total',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februar',
+  'Group'                       => 'Gruppe',
+  'Group Items'                 => 'Waren gruppieren',
+  'In-line'                     => 'im Textkörper (Inline)',
+  'Invoice'                     => 'Rechnung',
+  'Invoice Date missing!'       => 'Rechnungsdatum fehlt!',
+  'Invoice Number missing!'     => 'Rechnungsnummer fehlt!',
+  'Item not on file!'           => 'Dieser Artikel ist nicht in der Datenbank!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januar',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'März',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai',
+  'Message'                     => 'Nachricht',
+  'Name'                        => 'Name',
+  'No.'                         => 'Nr.',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Nummer fehlt in Zeile',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Order'                       => 'Auftrag',
+  'Order Date missing!'         => 'Auftragsdatum fehlt!',
+  'Order Number missing!'       => 'Auftragsnummer fehlt!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Verpackungsliste',
+  'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
+  'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
+  'Part'                        => 'Ware',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preis',
+  'Printer'                     => 'Drucker',
+  'Project'                     => 'Projekt',
+  'Purchase Order'              => 'Einkaufsbeleg',
+  'Qty'                         => 'Anz',
+  'Recd'                        => 'Erh',
+  'Required by'                 => 'Erforderlich am',
+  'Sales Order'                 => 'Verkaufsbeleg',
+  'Screen'                      => 'Bildschirm',
+  'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
+  'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Dienstleistung',
+  'Ship'                        => 'Versand',
+  'Ship to'                     => 'Verschicken an',
+  'Subject'                     => 'Betreff',
+  'To'                          => 'An',
+  'Unit'                        => 'Einh',
+  'What type of item is this?'  => 'Was ist dieser Artikel?',
+  'emailed to'                  => 'gemailt an',
+  'sent to printer'             => 'an Drucker geschickt',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'weiter'                      => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/de/ir b/sql-ledger/locale/de/ir
new file mode 100644 (file)
index 0000000..7b60e47
--- /dev/null
@@ -0,0 +1,180 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Add Purchase Order'          => 'Einkaufsbeleg anlegen',
+  'Add Sales Order'             => 'Verkaufsbeleg anlegen',
+  'Add Vendor Invoice'          => 'Einkaufsrechnung anlegen',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Betrag',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Invoice Number' => 'Soll die Rechnung mit folgender Nummer wirklich gelöscht werden:',
+  'Attachment'                  => 'als Anhang',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Stellage',
+  'Cannot delete invoice!'      => 'Rechnung kann nicht gelöscht werden!',
+  'Cannot post invoice for a closed period!' => 'Das Rechnungsdatum fällt in einen abgeschlossen Zeitraum!',
+  'Cannot post invoice!'        => 'Rechnung kann nicht gebucht werden!',
+  'Cannot post payment for a closed period!' => 'Es können keine Zahlungen für abgeschlossene Bücher gebucht werden!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Bestätigen Sie!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Weiter',
+  'Copies'                      => 'Kopien',
+  'Currency'                    => 'Währung',
+  'Customer not on file!'       => 'Kunde ist nicht in der Datenbank!',
+  'Date'                        => 'Datum',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezember',
+  'Delete'                      => 'Löschen',
+  'Delivery Date'               => 'Lieferung',
+  'Description'                 => 'Beschreibung',
+  'Due Date'                    => 'Fälligkeitsdatum',
+  'E-mail'                      => 'eMail',
+  'E-mail address missing!'     => 'eMail-Adresse fehlt!',
+  'Edit Vendor Invoice'         => 'Einkaufsrechnung bearbeiten',
+  'Exch'                        => 'Wkurs.',
+  'Exchangerate'                => 'Wechselkurs',
+  'Exchangerate for payment missing!' => 'Es fehlt der Wechselkurs für die Bezahlung!',
+  'Exchangerate missing!'       => 'Es fehlt der Wechselkurs!',
+  'Extended'                    => 'Total',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februar',
+  'Group'                       => 'Gruppe',
+  'Group Items'                 => 'Waren gruppieren',
+  'In-line'                     => 'im Textkörper (Inline)',
+  'Invoice'                     => 'Rechnung',
+  'Invoice Date'                => 'Rechnungsdatum',
+  'Invoice Date missing!'       => 'Rechnungsdatum fehlt!',
+  'Invoice Number'              => 'Rechnungsnummer',
+  'Invoice Number missing!'     => 'Rechnungsnummer fehlt!',
+  'Invoice deleted!'            => 'Rechnung gelöscht!',
+  'Invoice posted!'             => 'Rechnung verbucht!',
+  'Item not on file!'           => 'Dieser Artikel ist nicht in der Datenbank!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januar',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'März',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai',
+  'Message'                     => 'Nachricht',
+  'Name'                        => 'Name',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Bemerkungen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Nummer fehlt in Zeile',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Order'                       => 'Auftrag',
+  'Order Date missing!'         => 'Auftragsdatum fehlt!',
+  'Order Number'                => 'Auftragsnummer',
+  'Order Number missing!'       => 'Auftragsnummer fehlt!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Verpackungsliste',
+  'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
+  'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
+  'Part'                        => 'Ware',
+  'Payment date missing!'       => 'Tag der Zahlung fehlt!',
+  'Payments'                    => 'Zahlungen',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Buchen',
+  'Post as new'                 => 'Neu buchen',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preis',
+  'Printer'                     => 'Drucker',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
+  'Purchase Order'              => 'Einkaufsbeleg',
+  'Qty'                         => 'Anz',
+  'Recd'                        => 'Erh',
+  'Record in'                   => 'Buchen auf',
+  'Required by'                 => 'Erforderlich am',
+  'Sales Order'                 => 'Verkaufsbeleg',
+  'Screen'                      => 'Bildschirm',
+  'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
+  'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
+  'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
+  'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Dienstleistung',
+  'Ship'                        => 'Versand',
+  'Ship to'                     => 'Verschicken an',
+  'Source'                      => 'Beleg',
+  'Subject'                     => 'Betreff',
+  'Subtotal'                    => 'Zwischensumme',
+  'Tax Included'                => 'Steuer im Preis inbegriffen',
+  'To'                          => 'An',
+  'Total'                       => 'Summe',
+  'Unit'                        => 'Einh',
+  'Update'                      => 'Erneuern',
+  'Vendor'                      => 'Lieferant',
+  'Vendor missing!'             => 'Lieferant fehlt!',
+  'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'What type of item is this?'  => 'Was ist dieser Artikel?',
+  'Yes'                         => 'Ja',
+  'ea'                          => 'pro',
+  'emailed to'                  => 'gemailt an',
+  'sent to printer'             => 'an Drucker geschickt',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'weiter'                      => 'continue',
+  'löschen'                     => 'delete',
+  'auftrag'                     => 'order',
+  'buchen'                      => 'post',
+  'neu_buchen'                  => 'post_as_new',
+  'erneuern'                    => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/de/is b/sql-ledger/locale/de/is
new file mode 100644 (file)
index 0000000..f5edab6
--- /dev/null
@@ -0,0 +1,187 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Add Purchase Order'          => 'Einkaufsbeleg anlegen',
+  'Add Sales Invoice'           => 'Ausgangsrechnung anlegen',
+  'Add Sales Order'             => 'Verkaufsbeleg anlegen',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Betrag',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Invoice Number' => 'Soll die Rechnung mit folgender Nummer wirklich gelöscht werden:',
+  'Attachment'                  => 'als Anhang',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Stellage',
+  'Cannot delete invoice!'      => 'Rechnung kann nicht gelöscht werden!',
+  'Cannot post invoice for a closed period!' => 'Das Rechnungsdatum fällt in einen abgeschlossen Zeitraum!',
+  'Cannot post invoice!'        => 'Rechnung kann nicht gebucht werden!',
+  'Cannot post payment for a closed period!' => 'Es können keine Zahlungen für abgeschlossene Bücher gebucht werden!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Bestätigen Sie!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Weiter',
+  'Copies'                      => 'Kopien',
+  'Credit Limit'                => 'Kreditlimit',
+  'Currency'                    => 'Währung',
+  'Customer'                    => 'Kunde',
+  'Customer missing!'           => 'Kundenname fehlt!',
+  'Customer not on file!'       => 'Kunde ist nicht in der Datenbank!',
+  'Date'                        => 'Datum',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezember',
+  'Delete'                      => 'Löschen',
+  'Delivery Date'               => 'Lieferung',
+  'Description'                 => 'Beschreibung',
+  'Due Date'                    => 'Fälligkeitsdatum',
+  'E-mail'                      => 'eMail',
+  'E-mail address missing!'     => 'eMail-Adresse fehlt!',
+  'Edit Sales Invoice'          => 'Ausgangsrechnung bearbeiten',
+  'Exch'                        => 'Wkurs.',
+  'Exchangerate'                => 'Wechselkurs',
+  'Exchangerate for payment missing!' => 'Es fehlt der Wechselkurs für die Bezahlung!',
+  'Exchangerate missing!'       => 'Es fehlt der Wechselkurs!',
+  'Extended'                    => 'Total',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februar',
+  'Group'                       => 'Gruppe',
+  'Group Items'                 => 'Waren gruppieren',
+  'In-line'                     => 'im Textkörper (Inline)',
+  'Invoice'                     => 'Rechnung',
+  'Invoice Date'                => 'Rechnungsdatum',
+  'Invoice Date missing!'       => 'Rechnungsdatum fehlt!',
+  'Invoice Number'              => 'Rechnungsnummer',
+  'Invoice Number missing!'     => 'Rechnungsnummer fehlt!',
+  'Invoice deleted!'            => 'Rechnung gelöscht!',
+  'Invoice posted!'             => 'Rechnung verbucht!',
+  'Item not on file!'           => 'Dieser Artikel ist nicht in der Datenbank!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januar',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'März',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai',
+  'Message'                     => 'Nachricht',
+  'Name'                        => 'Name',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Bemerkungen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Nummer fehlt in Zeile',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Order'                       => 'Auftrag',
+  'Order Date missing!'         => 'Auftragsdatum fehlt!',
+  'Order Number'                => 'Auftragsnummer',
+  'Order Number missing!'       => 'Auftragsnummer fehlt!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Verpackungsliste',
+  'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
+  'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
+  'Part'                        => 'Ware',
+  'Payment date missing!'       => 'Tag der Zahlung fehlt!',
+  'Payments'                    => 'Zahlungen',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Buchen',
+  'Post as new'                 => 'Neu buchen',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preis',
+  'Print'                       => 'Drucken',
+  'Printer'                     => 'Drucker',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
+  'Purchase Order'              => 'Einkaufsbeleg',
+  'Qty'                         => 'Anz',
+  'Recd'                        => 'Erh',
+  'Record in'                   => 'Buchen auf',
+  'Remaining'                   => 'Rest',
+  'Required by'                 => 'Erforderlich am',
+  'Sales Order'                 => 'Verkaufsbeleg',
+  'Screen'                      => 'Bildschirm',
+  'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
+  'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
+  'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
+  'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Dienstleistung',
+  'Ship'                        => 'Versand',
+  'Ship to'                     => 'Verschicken an',
+  'Ship via'                    => 'Transportmittel',
+  'Source'                      => 'Beleg',
+  'Subject'                     => 'Betreff',
+  'Subtotal'                    => 'Zwischensumme',
+  'Tax Included'                => 'Steuer im Preis inbegriffen',
+  'To'                          => 'An',
+  'Total'                       => 'Summe',
+  'Unit'                        => 'Einh',
+  'Update'                      => 'Erneuern',
+  'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'What type of item is this?'  => 'Was ist dieser Artikel?',
+  'Yes'                         => 'Ja',
+  'ea'                          => 'pro',
+  'emailed to'                  => 'gemailt an',
+  'sent to printer'             => 'an Drucker geschickt',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'weiter'                      => 'continue',
+  'löschen'                     => 'delete',
+  'email'                       => 'e_mail',
+  'auftrag'                     => 'order',
+  'buchen'                      => 'post',
+  'neu_buchen'                  => 'post_as_new',
+  'drucken'                     => 'print',
+  'verschicken_an'              => 'ship_to',
+  'erneuern'                    => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/de/locales.pl b/sql-ledger/locale/de/locales.pl
new file mode 100755 (executable)
index 0000000..a358a90
--- /dev/null
@@ -0,0 +1,303 @@
+#!/usr/bin/perl
+
+# -n do not include custom_ scripts
+
+use FileHandle;
+
+
+$basedir = "../..";
+$bindir = "$basedir/bin/mozilla";
+$menufile = "menu.ini";
+
+foreach $item (@ARGV) {
+  $item =~ s/-//g;
+  $arg{$item} = 1;
+}
+
+opendir DIR, "$bindir" or die "$!";
+@progfiles = grep { /\.pl/; !/(_|^\.)/ } readdir DIR;
+seekdir DIR, 0;
+@customfiles = grep /_/, readdir DIR;
+closedir DIR;
+
+# put customized files into @customfiles
+@customfiles = () if ($arg{n});
+
+if ($arg{n}) {
+  @menufiles = ($menufile);
+} else {
+  opendir DIR, "$basedir" or die "$!";
+  @menufiles = grep { /.*?_$menufile$/ } readdir DIR;
+  closedir DIR;
+  unshift @menufiles, $menufile;
+}
+
+
+# slurp the translations in
+if (-f 'all') {
+  require "all";
+}
+
+
+foreach $file (@progfiles) {
+  
+  %locale = ();
+  %submit = ();
+  %subrt = ();
+  
+  &scanfile("$bindir/$file");
+
+  # scan custom_{module}.pl or {login}_{module}.pl files
+  foreach $customfile (@customfiles) {
+    if ($customfile =~ /_$file/) {
+      if (-f "$bindir/$customfile") {
+       &scanfile("$bindir/$customfile");
+      }
+    }
+  }
+  
+  # if this is the menu.pl file
+  if ($file eq 'menu.pl') {
+    foreach $item (@menufiles) {
+      &scanmenu("$basedir/$item");
+    }
+  }
+  
+  $file =~ s/\.pl//;
+
+
+  eval { require 'missing'; };
+  unlink 'missing';
+
+  foreach $text (keys %$missing) {
+    if ($locale{$text}) {
+      unless ($self{texts}{$text}) {
+       $self{texts}{$text} = $missing->{$text};
+      }
+    }
+  }
+
+
+  open FH, ">$file" or die "$! : $file";
+
+  print FH q|$self{texts} = {
+|;
+
+  foreach $key (sort keys %locale) {
+    if ($self{texts}{$key}) {
+      $text = $self{texts}{$key};
+    } else {
+      $text = $key;
+    }
+    $text =~ s/'/\\'/g;
+    $text =~ s/\\$/\\\\/;
+
+    $keytext = $key;
+    $keytext =~ s/'/\\'/g;
+    $keytext =~ s/\\$/\\\\/;
+    
+    print FH qq|  '$keytext'|.(' ' x (27-length($keytext))).qq| => '$text',\n|;
+  }
+
+  print FH q|};
+
+$self{subs} = {
+|;
+  
+  foreach $key (sort keys %subrt) {
+    $text = $key;
+    $text =~ s/'/\\'/g;
+    $text =~ s/\\$/\\\\/;
+    print FH qq|  '$text'|.(' ' x (27-length($text))).qq| => '$text',\n|;
+  }
+
+  foreach $key (sort keys %submit) {
+    $text = ($self{texts}{$key}) ? $self{texts}{$key} : $key;
+    $text =~ s/'/\\'/g;
+    $text =~ s/\\$/\\\\/;
+
+    $english_sub = $key;
+    $english_sub =~ s/'/\\'/g;
+    $english_sub =~ s/\\$/\\\\/;
+    $english_sub = lc $key;
+    
+    $translated_sub = lc $text;
+    $english_sub =~ s/( |-|,)/_/g;
+    $translated_sub =~ s/( |-|,)/_/g;
+    print FH qq|  '$translated_sub'|.(' ' x (27-length($translated_sub))).qq| => '$english_sub',\n|;
+  }
+  
+  print FH q|};
+
+1;
+|;
+
+  close FH;
+}
+
+
+# now print out all
+
+open FH, ">all" or die "$! : all";
+
+print FH q|# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+|;
+
+
+foreach $key (sort keys %alllocales) {
+  $text = $self{texts}{$key};
+
+  $count++;
+  
+  $text =~ s/'/\\'/g;
+  $text =~ s/\\$/\\\\/;
+  $key =~ s/'/\\'/g;
+  $key =~ s/\\$/\\\\/;
+
+  unless ($text) {
+    $notext++;
+    push @missing, $key;
+  }
+
+  print FH qq|  '$key'|.(' ' x (27-length($key))).qq| => '$text',\n|;
+
+}
+
+print FH q|};
+
+1;
+|;
+
+close FH;
+
+
+if (@missing) {
+  open FH, ">missing" or die "$! : missing";
+
+  print FH q|# add the missing texts and run locales.pl to rebuild
+
+$missing = {
+|;
+
+  foreach $text (@missing) {
+    print FH qq|  '$text'|.(' ' x (27-length($text))).qq| => '',\n|;
+  }
+
+  print FH q|};
+
+1;
+|;
+
+  close FH;
+  
+}
+
+open(FH, "LANGUAGE");
+@language = <FH>;
+close(FH);
+$trlanguage = $language[0];
+chomp $trlanguage;
+
+$per = sprintf("%.1f", ($count - $notext) / $count * 100);
+print "\n$trlanguage - ${per}%\n";
+
+exit;
+# eom
+
+
+sub scanfile {
+  my $file = shift;
+
+  return unless (-f "$file");
+  
+  my $fh = new FileHandle;
+  open $fh, "$file" or die "$! : $file";
+
+  while (<$fh>) {
+    # is this another file
+    if (/require\s+\W.*\.pl/) {
+      my $newfile = $&;
+      $newfile =~ s/require\s+\W//;
+      $newfile =~ s/\$form->{path}\///;
+      &scanfile("$bindir/$newfile");
+    }
+   
+    # is this a sub ?
+    if (/^sub /) {
+      ($null, $subrt) = split / +/;
+      $subrt{$subrt} = 1;
+      next;
+    }
+    
+    my $rc = 1;
+    
+    while ($rc) {
+      if (/Locale/) {
+       unless (/^use /) {
+         my ($null, $country) = split /,/;
+         $country =~ s/^ +["']//;
+         $country =~ s/["'].*//;
+       }
+      }
+
+      if (/\$locale->text.*?\W\)/) {
+       my $string = $&;
+       $string =~ s/\$locale->text\(\s*['"(q|qq)]['\/\\\|~]*//;
+       $string =~ s/\W\)+.*$//;
+
+        # if there is no $ in the string record it
+       unless ($string =~ /\$\D.*/) {
+         # this guarantees one instance of string
+         $locale{$string} = 1;
+
+          # this one is for all the locales
+         $alllocales{$string} = 1;
+
+          # is it a submit button before $locale->
+          if (/type=submit/) {
+           $submit{$string} = 1;
+          }
+       }
+      }
+
+      # exit loop if there are no more locales on this line
+      ($rc) = ($' =~ /\$locale->text/);
+      # strip text
+      s/^.*?\$locale->text.*?\)//;
+    }
+  }
+
+  close($fh);
+
+}
+
+
+sub scanmenu {
+  my $file = shift;
+
+  my $fh = new FileHandle;
+  open $fh, "$file" or die "$! : $file";
+
+  my @a = grep /^\[/, <$fh>;
+  close($fh);
+
+  # strip []
+  grep { s/(\[|\])//g } @a;
+  
+  foreach my $item (@a) {
+    @b = split /--/, $item;
+    foreach $string (@b) {
+      chomp $string;
+      $locale{$string} = 1;
+      $alllocales{$string} = 1;
+    }
+  }
+  
+}
+
+
diff --git a/sql-ledger/locale/de/login b/sql-ledger/locale/de/login
new file mode 100644 (file)
index 0000000..c90df6f
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'Über',
+  'Database Host'               => 'Datenbank-Rechner',
+  'Dataset'                     => 'Datenbank',
+  'Incorrect Dataset version!'  => 'Datenbankversion stimmt nicht überein!',
+  'Incorrect Password!'         => 'Ungültiges Passwort!',
+  'Licensed to'                 => 'Lizensiert für',
+  'Login'                       => 'Anmelden',
+  'Name'                        => 'Name',
+  'Password'                    => 'Passwort',
+  'User'                        => 'Benutzer',
+  'Version'                     => 'Version',
+  'You are logged out!'         => 'Auf wiedersehen!',
+  'You did not enter a name!'   => 'Sie haben keinen Namen eingegeben!',
+  'is not a member!'            => 'ist kein Mitglied!',
+  'localhost'                   => 'lokaler Rechner',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'anmelden'                    => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/de/menu b/sql-ledger/locale/de/menu
new file mode 100644 (file)
index 0000000..c61e760
--- /dev/null
@@ -0,0 +1,73 @@
+$self{texts} = {
+  'AP'                          => 'Verbindlichkeiten',
+  'AP Aging'                    => 'Offene Verbindl.',
+  'AR'                          => 'Forderungen',
+  'AR Aging'                    => 'Offene Forderungen',
+  'Accounting Menu'             => 'Kontoverwaltung',
+  'Add Account'                 => 'Konto anlegen',
+  'Add Assembly'                => 'Erzeugnis anlegen',
+  'Add Customer'                => 'Kunde anlegen',
+  'Add GIFI'                    => 'GIFI anlegen',
+  'Add Group'                   => 'Gruppe anlegen',
+  'Add Part'                    => 'Ware anlegen',
+  'Add Project'                 => 'Projekt anlegen',
+  'Add Service'                 => 'Dienstleistung anlegen',
+  'Add Transaction'             => 'Buchung anlegen',
+  'Add Vendor'                  => 'Lieferant anlegen',
+  'Assemblies'                  => 'Erzeugnisse',
+  'Audit Control'               => 'Bücherkontrolle',
+  'Backup'                      => 'Sicherung',
+  'Balance Sheet'               => 'Bilanz',
+  'Cash'                        => 'Kasse',
+  'Chart of Accounts'           => 'Kontenübersicht',
+  'Check'                       => 'Scheck',
+  'Customers'                   => 'Kunden',
+  'General Ledger'              => 'Hauptbuch',
+  'Goods & Services'            => 'Waren und Dienstleistungen',
+  'Groups'                      => 'Gruppen',
+  'HTML Templates'              => 'HTML Vorlagen',
+  'Income Statement'            => 'G & V',
+  'Invoice'                     => 'Rechnung',
+  'LaTeX Templates'             => 'LaTeX Vorlagen',
+  'List Accounts'               => 'Kontenliste',
+  'List GIFI'                   => 'GIFI aufzeigen',
+  'Logout'                      => 'Abmelden',
+  'Order Entry'                 => 'Aufträge',
+  'Packing List'                => 'Verpackungsliste',
+  'Parts'                       => 'Waren',
+  'Payment'                     => 'Zahlung',
+  'Payments'                    => 'Zahlungen',
+  'Preferences'                 => 'Benutzereinstellungen',
+  'Projects'                    => 'Projekte',
+  'Purchase Order'              => 'Einkaufsbeleg',
+  'Purchase Orders'             => 'Einkaufsbelege',
+  'Receipt'                     => 'Quittung',
+  'Receipts'                    => 'Quittungen',
+  'Reconciliation'              => 'Abgleichung',
+  'Reports'                     => 'Berichte',
+  'Sales Invoice'               => 'Ausgangsrechnung',
+  'Sales Order'                 => 'Verkaufsbeleg',
+  'Sales Orders'                => 'Verkaufsbelege',
+  'Save to File'                => 'Auf Festplatte speichern',
+  'Send by E-Mail'              => 'Per eMail schicken',
+  'Services'                    => 'Leistungen',
+  'Statement'                   => 'Sammelrechnung',
+  'Stock Assembly'              => 'Erzeugnis einlagern',
+  'Stylesheet'                  => 'Stilvorlage',
+  'System'                      => 'System',
+  'Tax collected'               => 'vereinnahmte Steuer',
+  'Tax paid'                    => 'Vorsteuer',
+  'Transactions'                => 'Buchungen',
+  'Trial Balance'               => 'Vergleichsbilanz',
+  'Vendor Invoice'              => 'Einkaufsrechnung',
+  'Vendors'                     => 'Lieferanten',
+  'Version'                     => 'Version',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/de/oe b/sql-ledger/locale/de/oe
new file mode 100644 (file)
index 0000000..abf31ba
--- /dev/null
@@ -0,0 +1,202 @@
+$self{texts} = {
+  'Add'                         => 'Hinzufügen',
+  'Add Purchase Order'          => 'Einkaufsbeleg anlegen',
+  'Add Sales Invoice'           => 'Ausgangsrechnung anlegen',
+  'Add Sales Order'             => 'Verkaufsbeleg anlegen',
+  'Add Vendor Invoice'          => 'Einkaufsrechnung anlegen',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Betrag',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Order Number' => 'Soll die Bestellung mit folgender Nummer wirklich gelöscht werden:',
+  'Attachment'                  => 'als Anhang',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Stellage',
+  'C'                           => 'G',
+  'Cannot delete order!'        => 'Bestellung kann nicht gelöscht werden!',
+  'Cannot save order!'          => 'Bestellung kann nicht gespeichert werden!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Geschlossen',
+  'Confirm!'                    => 'Bestätigen Sie!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Weiter',
+  'Copies'                      => 'Kopien',
+  'Credit Limit'                => 'Kreditlimit',
+  'Curr'                        => 'Währung',
+  'Currency'                    => 'Währung',
+  'Customer'                    => 'Kunde',
+  'Customer missing!'           => 'Kundenname fehlt!',
+  'Customer not on file!'       => 'Kunde ist nicht in der Datenbank!',
+  'Date'                        => 'Datum',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezember',
+  'Delete'                      => 'Löschen',
+  'Delivery Date'               => 'Lieferung',
+  'Description'                 => 'Beschreibung',
+  'E-mail'                      => 'eMail',
+  'E-mail address missing!'     => 'eMail-Adresse fehlt!',
+  'Edit Purchase Order'         => 'Einkaufsbeleg bearbeiten',
+  'Edit Sales Order'            => 'Verkaufsbeleg bearbeiten',
+  'Exchangerate'                => 'Wechselkurs',
+  'Exchangerate missing!'       => 'Es fehlt der Wechselkurs!',
+  'Extended'                    => 'Total',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februar',
+  'From'                        => 'Von',
+  'Group'                       => 'Gruppe',
+  'Group Items'                 => 'Waren gruppieren',
+  'ID'                          => 'Nr.',
+  'In-line'                     => 'im Textkörper (Inline)',
+  'Include in Report'           => 'In Bericht aufnehmen',
+  'Invoice'                     => 'Rechnung',
+  'Invoice Date missing!'       => 'Rechnungsdatum fehlt!',
+  'Invoice Number missing!'     => 'Rechnungsnummer fehlt!',
+  'Item not on file!'           => 'Dieser Artikel ist nicht in der Datenbank!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januar',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'März',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai',
+  'Message'                     => 'Nachricht',
+  'Name'                        => 'Name',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Bemerkungen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Nummer fehlt in Zeile',
+  'O'                           => 'O',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Open'                        => 'Offen',
+  'Order'                       => 'Auftrag',
+  'Order Date'                  => 'Auftragsdatum',
+  'Order Date missing!'         => 'Auftragsdatum fehlt!',
+  'Order Number'                => 'Auftragsnummer',
+  'Order Number missing!'       => 'Auftragsnummer fehlt!',
+  'Order deleted!'              => 'Auftrag gelöscht!',
+  'Order saved!'                => 'Auftrag gespeichert!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Verpackungsliste',
+  'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
+  'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
+  'Part'                        => 'Ware',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Preis',
+  'Print'                       => 'Drucken',
+  'Printer'                     => 'Drucker',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Dieses Projekt ist nicht in der Datenbank!',
+  'Purchase Order'              => 'Einkaufsbeleg',
+  'Purchase Orders'             => 'Einkaufsbelege',
+  'Qty'                         => 'Anz',
+  'Recd'                        => 'Erh',
+  'Remaining'                   => 'Rest',
+  'Required by'                 => 'Erforderlich am',
+  'Sales Order'                 => 'Verkaufsbeleg',
+  'Sales Orders'                => 'Verkaufsbelege',
+  'Save'                        => 'Speichern',
+  'Save as new'                 => 'als neu speichern',
+  'Screen'                      => 'Bildschirm',
+  'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
+  'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
+  'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
+  'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Dienstleistung',
+  'Ship'                        => 'Versand',
+  'Ship to'                     => 'Verschicken an',
+  'Ship via'                    => 'Transportmittel',
+  'Subject'                     => 'Betreff',
+  'Subtotal'                    => 'Zwischensumme',
+  'Tax'                         => 'Steuer',
+  'Tax Included'                => 'Steuer im Preis inbegriffen',
+  'Terms: Net'                  => 'Zahlungsziel',
+  'To'                          => 'An',
+  'Total'                       => 'Summe',
+  'Unit'                        => 'Einh',
+  'Update'                      => 'Erneuern',
+  'Vendor'                      => 'Lieferant',
+  'Vendor missing!'             => 'Lieferant fehlt!',
+  'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'What type of item is this?'  => 'Was ist dieser Artikel?',
+  'Yes'                         => 'Ja',
+  'days'                        => 'Tage',
+  'ea'                          => 'pro',
+  'emailed to'                  => 'gemailt an',
+  'sent to printer'             => 'an Drucker geschickt',
+  'to'                          => 'bis',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'hinzufügen'                  => 'add',
+  'weiter'                      => 'continue',
+  'löschen'                     => 'delete',
+  'email'                       => 'e_mail',
+  'rechnung'                    => 'invoice',
+  'drucken'                     => 'print',
+  'speichern'                   => 'save',
+  'als_neu_speichern'           => 'save_as_new',
+  'verschicken_an'              => 'ship_to',
+  'erneuern'                    => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/de/pe b/sql-ledger/locale/de/pe
new file mode 100644 (file)
index 0000000..d3618cc
--- /dev/null
@@ -0,0 +1,45 @@
+$self{texts} = {
+  'Add'                         => 'Hinzufügen',
+  'Add Group'                   => 'Gruppe anlegen',
+  'Add Project'                 => 'Projekt anlegen',
+  'All'                         => 'Alle',
+  'Continue'                    => 'Weiter',
+  'Delete'                      => 'Löschen',
+  'Description'                 => 'Beschreibung',
+  'Edit Group'                  => 'Gruppe editieren',
+  'Edit Project'                => 'Projekt bearbeiten',
+  'Group'                       => 'Gruppe',
+  'Group deleted!'              => 'Gruppe gelöscht!',
+  'Group missing!'              => 'Gruppe fehlt!',
+  'Group saved!'                => 'Gruppe gespeichert!',
+  'Groups'                      => 'Gruppen',
+  'Number'                      => 'Nummer',
+  'Orphaned'                    => 'nie benutzt',
+  'Project'                     => 'Projekt',
+  'Project Number missing!'     => 'Projektnummer fehlt!',
+  'Project deleted!'            => 'Projekt gelöscht!',
+  'Project saved!'              => 'Projekt gespeichert!',
+  'Projects'                    => 'Projekte',
+  'Save'                        => 'Speichern',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_partsgroup_footer'      => 'form_partsgroup_footer',
+  'form_partsgroup_header'      => 'form_partsgroup_header',
+  'form_project_footer'         => 'form_project_footer',
+  'form_project_header'         => 'form_project_header',
+  'partsgroup_report'           => 'partsgroup_report',
+  'project_report'              => 'project_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'hinzufügen'                  => 'add',
+  'weiter'                      => 'continue',
+  'löschen'                     => 'delete',
+  'speichern'                   => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/de/rc b/sql-ledger/locale/de/rc
new file mode 100644 (file)
index 0000000..47f5f6e
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Balance'                     => 'Bilanz',
+  'Cleared Balance'             => 'Abgeschlossen',
+  'Continue'                    => 'Weiter',
+  'Date'                        => 'Datum',
+  'Deposit'                     => 'Gutschrift',
+  'Description'                 => 'Beschreibung',
+  'Difference'                  => 'Differenz',
+  'Done'                        => 'Fertig',
+  'Exchangerate Difference'     => 'Wechselkursunterschied',
+  'From'                        => 'Von',
+  'Out of balance!'             => 'Summen stimmen nicht überein!',
+  'Payment'                     => 'Zahlung',
+  'Reconciliation'              => 'Abgleichung',
+  'Select all'                  => 'Alle auswählen',
+  'Source'                      => 'Beleg',
+  'Statement Balance'           => 'Sammelrechnungsbilanz',
+  'Update'                      => 'Erneuern',
+  'to'                          => 'bis',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'weiter'                      => 'continue',
+  'fertig'                      => 'done',
+  'alle_auswählen'              => 'select_all',
+  'erneuern'                    => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/de/rp b/sql-ledger/locale/de/rp
new file mode 100644 (file)
index 0000000..f1ffdf4
--- /dev/null
@@ -0,0 +1,119 @@
+$self{texts} = {
+  'AP Aging'                    => 'Offene Verbindl.',
+  'AR Aging'                    => 'Offene Forderungen',
+  'Account'                     => 'Konto',
+  'Accounts'                    => 'Konten',
+  'Amount'                      => 'Betrag',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Attachment'                  => 'als Anhang',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Balance'                     => 'Bilanz',
+  'Balance Sheet'               => 'Bilanz',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'basierend auf Barzahlung',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Gegenüberstellen zu',
+  'Continue'                    => 'Weiter',
+  'Copies'                      => 'Kopien',
+  'Credit'                      => 'Haben',
+  'Current'                     => 'Betrag',
+  'Customer'                    => 'Kunde',
+  'Date'                        => 'Datum',
+  'Debit'                       => 'Soll',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezember',
+  'Decimalplaces'               => 'Dezimalstellen',
+  'Description'                 => 'Beschreibung',
+  'Due'                         => 'Fällig',
+  'E-mail'                      => 'eMail',
+  'E-mail Statement to'         => 'eMail Fälligkeitsabrechnung an',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februar',
+  'From'                        => 'Von',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Überschrift',
+  'ID'                          => 'Nr.',
+  'In-line'                     => 'im Textkörper (Inline)',
+  'Include in Report'           => 'In Bericht aufnehmen',
+  'Income Statement'            => 'G & V',
+  'Invoice'                     => 'Rechnung',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januar',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'März',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai',
+  'Message'                     => 'Nachricht',
+  'N/A'                         => 'N.Z.',
+  'Nothing selected!'           => 'Es wurde nichts ausgewählt!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Zahlungen',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Drucken',
+  'Printer'                     => 'Drucker',
+  'Project Number'              => 'Projektnummer',
+  'Receipts'                    => 'Quittungen',
+  'Report for'                  => 'Bericht für',
+  'Retained Earnings'           => 'Verbliebenes Einkommen',
+  'Screen'                      => 'Bildschirm',
+  'Select all'                  => 'Alle auswählen',
+  'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Beleg',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Sammelrechnung',
+  'Statement sent to'           => 'Sammelrechnung verschickt an',
+  'Statements sent to printer!' => 'Sammelrechnungen an Drucker geschickt!',
+  'Subject'                     => 'Betreff',
+  'Subtotal'                    => 'Zwischensumme',
+  'Tax'                         => 'Steuer',
+  'Tax collected'               => 'vereinnahmte Steuer',
+  'Tax paid'                    => 'Vorsteuer',
+  'Total'                       => 'Summe',
+  'Trial Balance'               => 'Vergleichsbilanz',
+  'Vendor'                      => 'Lieferant',
+  'as at'                       => 'zum Stand',
+  'collected on sales'          => 'erhalten durch Verkäufe',
+  'for Period'                  => 'für den Zeitraum',
+  'paid on purchases'           => 'gezahlt durch Einkäufe',
+  'to'                          => 'bis',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_accounts'               => 'list_accounts',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'weiter'                      => 'continue',
+  'email'                       => 'e_mail',
+  'drucken'                     => 'print',
+  'alle_auswählen'              => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/COPYING b/sql-ledger/locale/dk/COPYING
new file mode 100644 (file)
index 0000000..e010710
--- /dev/null
@@ -0,0 +1,24 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Danish texts:
+#
+#  Author: Keld Jørn Simonsen <keld@dkuug.dk>
+#          Jonas Smedegaard <jonas@jones.dk>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/dk/LANGUAGE b/sql-ledger/locale/dk/LANGUAGE
new file mode 100644 (file)
index 0000000..bd082a2
--- /dev/null
@@ -0,0 +1 @@
+Danish
diff --git a/sql-ledger/locale/dk/admin b/sql-ledger/locale/dk/admin
new file mode 100644 (file)
index 0000000..e74af7d
--- /dev/null
@@ -0,0 +1,122 @@
+$self{texts} = {
+  'Access Control'              => 'Adgangskontrol',
+  'Accounting'                  => 'Bogføring',
+  'Add User'                    => 'Ny bruger',
+  'Address'                     => 'Adresse',
+  'Administration'              => 'Administration',
+  'Administrator'               => 'Administrator',
+  'All Datasets up to date!'    => 'Alle datasæt opdaterede',
+  'Change Admin Password'       => 'Ændr adgangskode for administrator',
+  'Change Password'             => 'Ændr adgangskode',
+  'Character Set'               => 'Tegnsæt',
+  'Click on login name to edit!' => 'Klik på brugernavn for at redigere',
+  'Company'                     => 'Firma',
+  'Connect to'                  => 'Forbind til',
+  'Continue'                    => 'Fortsæt',
+  'Create Chart of Accounts'    => 'Opret kontoplan',
+  'Create Dataset'              => 'Opret datasæt',
+  'DBI not installed!'          => 'DBI ikke installeret',
+  'Database'                    => 'Database',
+  'Database Administration'     => 'Administration af database',
+  'Database Driver not checked!' => 'Databasedriver ikke kontrolleret',
+  'Database User missing!'      => 'Bruger af database mangler!',
+  'Dataset'                     => 'Datasæt',
+  'Dataset missing!'            => 'Datasæt mangler!',
+  'Dataset updated!'            => 'Datasæt opdateret!',
+  'Date Format'                 => 'Datoformat',
+  'Delete'                      => 'Fjern',
+  'Delete Dataset'              => 'Fjern datasæt',
+  'Directory'                   => 'Katalog',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Grænse for nedtræk',
+  'E-mail'                      => 'E-post',
+  'Edit User'                   => 'Redigér bruger',
+  'Existing Datasets'           => 'Eksisterende datasæt',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Vært',
+  'Hostname missing!'           => 'Værtsnavn mangler',
+  'Incorrect Password!'         => 'Forkert adgangskode',
+  'Language'                    => 'Sprog',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Lad felterne "vært" og "port" være tomme medmindre du vil etablere en ekstern forbindelse.',
+  'Login'                       => 'Log på',
+  'Name'                        => 'Navn',
+  'New Templates'               => 'Nye skabeloner',
+  'No Database Drivers available!' => 'Ingen databasedrivere tilgængelige',
+  'No Dataset selected!'        => 'Intet datasæt valgt',
+  'Nothing to delete!'          => 'Intet at slette!',
+  'Number Format'               => 'Numerisk format',
+  'Oracle Database Administration' => 'Oracle Administration af database',
+  'Password'                    => 'Adgangskode',
+  'Password changed!'           => 'Adgangskode ændret',
+  'Pg Database Administration'  => 'Pg Administration af database',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port mangler',
+  'Printer'                     => 'Printer',
+  'Save'                        => 'Gem',
+  'Select a Dataset to delete and press "Continue"' => 'Vælg et datasæt og tryk "Fortsæt"',
+  'Setup Templates'             => 'Skabeloner for opsætning',
+  'Ship via'                    => 'Send via',
+  'Signature'                   => 'Underskrift',
+  'Stylesheet'                  => 'Stilark',
+  'Templates'                   => 'Skabeloner',
+  'The following Datasets are not in use and can be deleted' => 'De følgende datasæt er ikke i brug og kan slettes',
+  'The following Datasets need to be updated' => 'De følgende datasæt skal opdateres',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Dette er en indledende kontrol af eksisterende kilder. Ingenting vil blive oprettet eller slettet på dette trin',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Skift brugernavnet for en eksisterende bruger og gem for at tilføje en ny bruger til en gruppe. Den nye bruger vil så bive gemt med de samme indstillinger under det nye brugernavn.',
+  'Update Dataset'              => 'Opdatér datasæt',
+  'Use Templates'               => 'Brug skabeloner',
+  'User'                        => 'Bruger',
+  'User deleted!'               => 'Bruger slettet!',
+  'User saved!'                 => 'Bruger gemt!',
+  'Version'                     => 'Version',
+  'You must enter a host and port for local and remote connections!' => 'Du skal angive en vært og en port for lokale og eksterne forbindelser!',
+  'does not exist'              => 'eksisterer ikke',
+  'is already a member!'        => 'er allerede et medlem',
+  'localhost'                   => 'lokalt',
+  'successfully created!'       => 'oprettet!',
+  'successfully deleted!'       => 'slettet!',
+  'website'                     => 'på Internet',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'ny_bruger'                   => 'add_user',
+  'Ændr_adgangskode_for_administrator' => 'change_admin_password',
+  'Ændr_adgangskode'            => 'change_password',
+  'fortsæt'                     => 'continue',
+  'opret_datasæt'               => 'create_dataset',
+  'fjern'                       => 'delete',
+  'fjern_datasæt'               => 'delete_dataset',
+  'log_på'                      => 'login',
+  'oracle_administration_af_database' => 'oracle_database_administration',
+  'pg_administration_af_database' => 'pg_database_administration',
+  'gem'                         => 'save',
+  'opdatér_datasæt'             => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/all b/sql-ledger/locale/dk/all
new file mode 100644 (file)
index 0000000..e57ed1f
--- /dev/null
@@ -0,0 +1,487 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Kreditorer',
+  'AP Aging'                    => 'Aldersfordeling',
+  'AP Transaction'              => 'Leverandørfaktura',
+  'AP Transactions'             => 'Leverandørfakturaer',
+  'AR'                          => 'Debitorer',
+  'AR Aging'                    => 'Aldersfordeling',
+  'AR Transaction'              => 'Debitorpostering',
+  'AR Transactions'             => 'Debitorposteringer',
+  'About'                       => 'Om',
+  'Access Control'              => 'Adgangskontrol',
+  'Account'                     => 'Konto',
+  'Account Number'              => 'Kontonummer',
+  'Account Number missing!'     => 'Kontonummer mangler!',
+  'Account Type'                => 'Kontotype',
+  'Account Type missing!'       => 'Kontotype mangler!',
+  'Account deleted!'            => 'Konto slettet!',
+  'Account saved!'              => 'Konto gemt!',
+  'Accounting'                  => 'Bogføring',
+  'Accounting Menu'             => 'Konto-menu',
+  'Accounts'                    => 'Konti',
+  'Active'                      => 'Aktiv',
+  'Add'                         => 'Tilføj',
+  'Add Account'                 => 'Ny konto',
+  'Add Accounts Payables Transaction' => 'Ny leverandørpostering',
+  'Add Accounts Receivables Transaction' => 'Ny debitorpostering',
+  'Add Assembly'                => 'Ny sammensætning',
+  'Add Customer'                => 'Ny kunde',
+  'Add GIFI'                    => 'Ny GIFI',
+  'Add General Ledger Transaction' => 'Ny postering i hovedbog',
+  'Add Part'                    => 'Ny vare',
+  'Add Project'                 => 'Nyt projekt',
+  'Add Purchase Invoice'        => 'Ny indkøbsfaktura',
+  'Add Purchase Order'          => 'Ny indkøbsordre',
+  'Add Sales Invoice'           => 'Ny salgsfaktura',
+  'Add Sales Order'             => 'Ny salgsordre',
+  'Add Service'                 => 'Ny tjeneste',
+  'Add Transaction'             => 'Ny postering',
+  'Add User'                    => 'Ny bruger',
+  'Add Vendor'                  => 'Ny leverandør',
+  'Address'                     => 'Adresse',
+  'Administration'              => 'Administration',
+  'Administrator'               => 'Administrator',
+  'All'                         => 'Alt',
+  'All Datasets up to date!'    => 'Alle datasæt opdaterede',
+  'Amount'                      => 'Beløb',
+  'Amount Due'                  => 'Forfaldent',
+  'Amount does not equal applied!' => 'Beløb er ikke det samme som brugt!',
+  'Amount missing!'             => 'Konto mangler!',
+  'Applied'                     => 'Udført',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Invoice Number' => 'Er du sikker på du vil fjerne fakturanummer',
+  'Are you sure you want to delete Order Number' => 'Er du sikker på at du vil fjerne ordrenummer',
+  'Are you sure you want to delete Transaction' => 'Er du sikker på du vil fjerne postering',
+  'Assemblies'                  => 'Sammensætninger',
+  'Assemblies restocked!'       => 'Sammensætninger genlagret',
+  'Assembly Number missing!'    => 'Sammensætningsnummer mangler',
+  'Asset'                       => 'Aktiv',
+  'Attachment'                  => 'Bilag',
+  'Audit Control'               => 'Revisionskontrol',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'BOM'                         => 'BOM',
+  'Backup'                      => 'Sikkerheskopi',
+  'Backup sent to'              => 'Sikkerhedskopier sendt til',
+  'Balance'                     => 'Balance',
+  'Balance Sheet'               => 'Status',
+  'Bcc'                         => 'Blind kopi',
+  'Bin'                         => 'Varelager',
+  'Books are open'              => 'Bogføringen er åben for rettelser',
+  'Bought'                      => 'Købt',
+  'Business Number'             => 'CVR-nummer',
+  'C'                           => 'C',
+  'COGS'                        => 'Indkøb',
+  'Cannot delete account!'      => 'Kan ikke slette konto!',
+  'Cannot delete customer!'     => 'Kan ikke slette kunde!',
+  'Cannot delete default account!' => 'Kan ikke slette standardkonto!',
+  'Cannot delete invoice!'      => 'Kan ikke slette faktura!',
+  'Cannot delete item already invoiced!' => 'Kan ikke slette allerede faktureret enkeltdel!',
+  'Cannot delete item on order!' => 'Kan ikke slette bestilt enkeltdel!',
+  'Cannot delete item which is part of an assembly!' => 'kan ikke slette en enhed som er en del af en sammensætning!',
+  'Cannot delete item!'         => 'Kan ikke slette enhed!',
+  'Cannot delete order!'        => 'Kan ikke slette ordre!',
+  'Cannot delete transaction!'  => 'Kan ikke slette postering!',
+  'Cannot delete vendor!'       => 'Kan ikke slette leverandør!',
+  'Cannot have a value in both Debit and Credit!' => 'Kan ikke have en værdi i både debet og kredit!',
+  'Cannot post a transaction without a value!' => '',
+  'Cannot post invoice for a closed period!' => 'Kan ikke bogføre faktura for en afsluttet periode!',
+  'Cannot post invoice!'        => 'Kan ikke bogføre faktura!',
+  'Cannot post payment for a closed period!' => 'Kan ikke bogføre betaling for en afsluttet periode',
+  'Cannot post payment!'        => 'Kan ikke bogføre betaling',
+  'Cannot post transaction for a closed period!' => 'Kan ikke bogføre postering for en afsluttet periode!',
+  'Cannot post transaction!'    => 'Kan ikke bogføre postering!',
+  'Cannot process payment for a closed period!' => 'Kan ikke behandle betaling for en afsluttet periode!',
+  'Cannot save account!'        => 'Kan ikke gemme konto!',
+  'Cannot save order!'          => 'Kan ikke gemme ordre!',
+  'Cannot save preferences!'    => 'Kan ikke gemme præferencer!',
+  'Cannot stock assemblies!'    => 'Kan ikke genbesætte sammensætninger',
+  'Cash'                        => 'Kontanter',
+  'Cash based'                  => 'Kontantbaseret',
+  'Cc'                          => 'Kopi',
+  'Change Admin Password'       => 'Ændr adgangskode for administrator',
+  'Change Password'             => 'Ændr adgangskode',
+  'Character Set'               => 'Tegnsæt',
+  'Chart of Accounts'           => 'Kontoplan',
+  'Check'                       => 'Check',
+  'Check printed!'              => 'Check udskrevet',
+  'Check printing failed!'      => 'Udskrivning af check mislykkedes',
+  'Cleared Balance'             => 'Udjævnede balance',
+  'Click on login name to edit!' => 'Klik på brugernavn for at redigere',
+  'Close Books up to'           => 'Afslut bogføring op til',
+  'Closed'                      => 'Afsluttet',
+  'Company'                     => 'Firma',
+  'Compare to'                  => 'Sammenlign med',
+  'Confirm!'                    => 'Bekræft!',
+  'Connect to'                  => 'Forbind til',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsæt',
+  'Copies'                      => 'Kopier',
+  'Copy to COA'                 => 'Kopiér til COA',
+  'Create Chart of Accounts'    => 'Opret kontoplan',
+  'Create Dataset'              => 'Opret datasæt',
+  'Credit'                      => 'Kredit',
+  'Credit Limit'                => 'Kreditgrænse',
+  'Curr'                        => 'Val',
+  'Currency'                    => 'Valuta',
+  'Current'                     => '',
+  'Customer'                    => 'Kunde',
+  'Customer deleted!'           => 'Kunde slettet!',
+  'Customer missing!'           => 'Kunde mangler!',
+  'Customer not on file!'       => 'Kunde ikke i databasen!',
+  'Customer saved!'             => 'Kunde gemt!',
+  'Customers'                   => 'Kunder',
+  'DBI not installed!'          => 'DBI ikke installeret',
+  'Database'                    => 'Database',
+  'Database Administration'     => 'Administration af database',
+  'Database Driver not checked!' => 'Databasedriver ikke kontrolleret',
+  'Database Host'               => 'Database-vært',
+  'Database User missing!'      => 'Bruger af database mangler!',
+  'Dataset'                     => 'Datasæt',
+  'Dataset missing!'            => 'Datasæt mangler!',
+  'Dataset updated!'            => 'Datasæt opdateret!',
+  'Date'                        => 'Dato',
+  'Date Due'                    => 'Forfaldsdato',
+  'Date Format'                 => 'Datoformat',
+  'Date Paid'                   => 'Betalingsdato',
+  'Date missing!'               => 'Dato mangler!',
+  'Debit'                       => 'Debet',
+  'Debit and credit out of balance!' => 'Debet og kredit skal være det samme!',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Decimalplaces'               => 'Decimalpladser',
+  'Delete'                      => 'Fjern',
+  'Delete Account'              => 'Fjern konto',
+  'Delete Dataset'              => 'Fjern datasæt',
+  'Delivery Date'               => 'Leveringsdato',
+  'Deposit'                     => 'Depositum',
+  'Description'                 => 'Beskrivelse',
+  'Difference'                  => 'Difference',
+  'Directory'                   => 'Katalog',
+  'Discount'                    => 'Rabat',
+  'Done'                        => 'Færdig',
+  'Drawing'                     => 'Træk',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Grænse for nedtræk',
+  'Due'                         => 'Forfald',
+  'Due Date'                    => 'Forfaldsdato',
+  'Due Date missing!'           => 'Forfaldsdato mangler!',
+  'E-mail'                      => 'E-post',
+  'E-mail Statement to'         => 'Send opgørelse til',
+  'E-mail address missing!'     => 'E-post-adresse mangler!',
+  'Edit'                        => 'Redigér',
+  'Edit Account'                => 'Redigér konto',
+  'Edit Accounts Payables Transaction' => 'Redigér leverandørpostering',
+  'Edit Accounts Receivables Transaction' => 'Redigér debitorpostering',
+  'Edit Assembly'               => 'Redigér sammensætning',
+  'Edit GIFI'                   => 'Redigér GIFI',
+  'Edit General Ledger Transaction' => 'Redigér en postering i hovedbog',
+  'Edit Part'                   => 'Redigér vare',
+  'Edit Preferences for'        => 'Redigér opsætning for',
+  'Edit Project'                => 'Redigér præferencer for',
+  'Edit Purchase Invoice'       => 'Redigér projekt',
+  'Edit Purchase Order'         => 'Redigér indkøbsordre',
+  'Edit Sales Invoice'          => 'Redigér salgsfaktura',
+  'Edit Sales Order'            => 'Redigér salgsordre',
+  'Edit Service'                => 'Redigér tjeneste',
+  'Edit Template'               => 'Redigér skabelon',
+  'Edit User'                   => 'Redigér bruger',
+  'Employee'                    => 'Ansat',
+  'Enforce transaction reversal for all dates' => 'Gennemtving explicitte rettelser af posteringer for alle datoer',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Angiv op til 3 bogstaver adskilt med kolon (fx DKK:EUR:USD) for dine indenlandske og udenlandske valutaer',
+  'Equity'                      => 'Egenkapital',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Vekselkurs',
+  'Exchangerate Difference'     => 'Difference for vekselkurs',
+  'Exchangerate for payment missing!' => 'Valutakurs for betaling mangler!',
+  'Exchangerate missing!'       => 'Vekselkurs mangler!',
+  'Existing Datasets'           => 'Eksisterende datasæt',
+  'Expense'                     => 'Udgift',
+  'Expense Account'             => 'Udgiftskonto',
+  'Expense/Asset'               => 'Udgift/Aktiv',
+  'Extended'                    => 'Udvidet',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'Foreign Exchange Gain'       => 'Gevinst på valutahandel',
+  'Foreign Exchange Loss'       => 'Tab på valutahandel',
+  'From'                        => 'Fra',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI slettet!',
+  'GIFI missing!'               => 'GIFI mangler!',
+  'GIFI saved!'                 => 'GIFI gemt!',
+  'GL Transaction'              => 'Postering i hovedbog',
+  'General Ledger'              => 'Hovedbog',
+  'Goods & Services'            => 'Varer og tjenester',
+  'HTML Templates'              => 'HTML-skabeloner',
+  'Heading'                     => 'Overskrift',
+  'Host'                        => 'Vært',
+  'Hostname missing!'           => 'Værtsnavn mangler',
+  'ID'                          => 'ID',
+  'Image'                       => 'Billede',
+  'In-line'                     => 'Indlejret',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Include in drop-down menus'  => 'Inkludér i rullegardin-menuer',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Skal denne konto kunne vælges som afgifts- eller momskonto ved oprettelsen af kunder/leverandører?',
+  'Income'                      => 'Indtægt',
+  'Income Account'              => 'Indtægtskonto',
+  'Income Statement'            => 'Driftsregnskab',
+  'Incorrect Dataset version!'  => 'Forkert version af datasæt!',
+  'Incorrect Password!'         => 'Forkert adgangskode',
+  'Individual Items'            => 'Individuelle enheder',
+  'Inventory'                   => 'Artikler',
+  'Inventory Account'           => 'Lagerkonto',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Lagerbeholdning skal være nul for at du kan forælde denne sammensætning',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Lagerbeholdning skal være nul for at du kan forælde denne enhed',
+  'Inventory quantity must be zero!' => 'Lagerbeholdning skal være nul',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadato',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Invoice deleted!'            => 'Faktura slettet!',
+  'Invoice posted!'             => 'Faktura bogført!',
+  'Invoices'                    => 'Fakturaer',
+  'Is this a summary account to record' => 'Samlekonto for',
+  'Item deleted!'               => 'Enkeltdel slettet!',
+  'Item not on file!'           => 'Enkeltdel er ikke i databasen!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'LaTeX Templates'             => 'LaTeX-skabeloner',
+  'Language'                    => 'Sprog',
+  'Last Cost'                   => 'Seneste pris',
+  'Last Invoice Number'         => 'Seneste fakturanummer',
+  'Last Numbers & Default Accounts' => 'Løbenumre og standardkonti',
+  'Last Purchase Order Number'  => 'Seneste nummer på indkøbsordre',
+  'Last Sales Order Number'     => 'Seneste salgsordrenummer',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Lad felterne "vært" og "port" være tomme medmindre du vil etablere en ekstern forbindelse.',
+  'Liability'                   => 'Passiv',
+  'Licensed to'                 => 'Udført for',
+  'Line Total'                  => 'Antal linjer',
+  'Link'                        => 'Referencer',
+  'Link Accounts'               => 'Forbind konti',
+  'List Accounts'               => 'List konti',
+  'List GIFI'                   => 'List GIFI',
+  'List Price'                  => 'Listepris',
+  'List Transactions'           => 'Vis bogføringer',
+  'Login'                       => 'Log på',
+  'Logout'                      => 'Log af',
+  'Make'                        => 'Fabrikat',
+  'Mar'                         => 'mar',
+  'March'                       => 'marts',
+  'May'                         => 'maj',
+  'May '                        => 'maj ',
+  'Message'                     => 'Besked',
+  'Microfiche'                  => 'Mikrofilm',
+  'Model'                       => 'Model',
+  'N/A'                         => 'I/T',
+  'Name'                        => 'Navn',
+  'Name missing!'               => 'Navn mangler!',
+  'New Templates'               => 'Nye skabeloner',
+  'No'                          => 'Nej',
+  'No Database Drivers available!' => 'Ingen databasedrivere tilgængelige',
+  'No Dataset selected!'        => 'Intet datasæt valgt',
+  'No email address for'        => 'Ingen epostadresse for',
+  'No.'                         => '',
+  'Notes'                       => 'Bemærkninger',
+  'Nothing applied!'            => 'Ingenting udført!',
+  'Nothing selected!'           => 'Ingenting valgt!',
+  'Nothing to delete!'          => 'Intet at slette!',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Number Format'               => 'Numerisk format',
+  'Number missing in Row'       => 'Tal mangler i række',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Forældet',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'On Hand'                     => 'På lager',
+  'On Order'                    => 'I ordre',
+  'Open'                        => 'Åbn',
+  'Oracle Database Administration' => 'Oracle Administration af database',
+  'Order'                       => 'Ordre',
+  'Order Date'                  => 'Ordredato',
+  'Order Date missing!'         => 'Ordredato mangler',
+  'Order Entry'                 => 'Ordreindgang',
+  'Order Number'                => 'Ordrenummer',
+  'Order Number missing!'       => 'Ordrenummer mangler',
+  'Order deleted!'              => 'Ordre slettet',
+  'Order saved!'                => 'Ordre gemt',
+  'Ordered'                     => 'bestilt',
+  'Orphaned'                    => 'Fritstående',
+  'Out of balance!'             => 'Ikke i balance!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Følgeseddel',
+  'Packing List Date missing!'  => 'Dato for pakkeliste mangler!',
+  'Packing List Number missing!' => 'Nummer for pakkeliste mangler!',
+  'Paid'                        => 'Betalt',
+  'Paid in full'                => '',
+  'Part'                        => 'Vare',
+  'Part Number missing!'        => 'Varenummer mangler!',
+  'Parts'                       => 'Dele',
+  'Parts Inventory'             => 'Vareliste',
+  'Password'                    => 'Adgangskode',
+  'Password changed!'           => 'Adgangskode ændret',
+  'Payables'                    => 'Udeståender',
+  'Payment'                     => 'Betaling',
+  'Payment date missing!'       => 'Betalingsdato mangler!',
+  'Payment posted!'             => 'Betaling bogført!',
+  'Payments'                    => 'Betalinger',
+  'Pg Database Administration'  => 'Pg Administration af database',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port mangler',
+  'Post'                        => 'Bogfør',
+  'Post as new'                 => 'Bogfør som ny',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Præferencer',
+  'Preferences saved!'          => 'Indstillinger gemt!',
+  'Price'                       => 'Pris',
+  'Print'                       => 'Udskriv',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Projekt',
+  'Project Number missing!'     => 'Projektnummer mangler!',
+  'Project deleted!'            => 'Projekt slettet!',
+  'Project not on file!'        => 'Projekt ikke i databasen!',
+  'Project saved!'              => 'Projekt gemt!',
+  'Projects'                    => 'Projekter',
+  'Purchase Invoice'            => 'Indkøbsfaktura',
+  'Purchase Order'              => 'Indkøbsordre',
+  'Purchase Orders'             => 'Indkøbsordrer',
+  'Qty'                         => 'Antal',
+  'ROP'                         => 'Genbestil ved',
+  'Rate'                        => 'Rate',
+  'Recd'                        => 'Modtaget',
+  'Receipt'                     => 'Kvittering',
+  'Receipts'                    => 'Kvitteringer',
+  'Receivables'                 => 'Indbetalinger',
+  'Reconciliation'              => 'Afstemning',
+  'Record in'                   => 'Bogfør på',
+  'Reference'                   => 'Reference',
+  'Reference missing!'          => 'Reference mangler',
+  'Remaining'                   => 'Resterer',
+  'Report for'                  => 'Rapport for',
+  'Reports'                     => 'Rapporter',
+  'Required by'                 => 'Bestilt af',
+  'Retained Earnings'           => 'Realiseret overskud',
+  'Sales'                       => 'Salg',
+  'Sales Invoice'               => 'Salgsfaktura',
+  'Sales Order'                 => 'Salgsordre',
+  'Sales Orders'                => 'Salgsordrer',
+  'Save'                        => 'Gem',
+  'Save as new'                 => 'Gem som ny',
+  'Save to File'                => 'Gem i fil',
+  'Screen'                      => 'Skærm',
+  'Select a Dataset to delete and press "Continue"' => 'Vælg et datasæt og tryk "Fortsæt"',
+  'Select all'                  => 'Vælg alt',
+  'Select from one of the items below' => 'Vælg fra en af tingene nedenfor, og tryk "Fortsæt"',
+  'Select from one of the names below' => 'Vælg en af navnene nedenfor',
+  'Select from one of the projects below' => 'Vælg et af projekterne nedenfor',
+  'Select postscript or PDF!'   => 'Vælg postscript eller PDF',
+  'Sell Price'                  => 'Salgspris',
+  'Send by E-Mail'              => 'Sendt med epost',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Tjeneste',
+  'Service Items'               => 'Tjenester',
+  'Service Number missing!'     => 'Tjenestenummer mangler!',
+  'Services'                    => 'Tjenester',
+  'Setup Templates'             => 'Skabeloner for opsætning',
+  'Ship'                        => 'Send',
+  'Ship to'                     => 'Send til',
+  'Ship via'                    => 'Send via',
+  'Short'                       => 'Kort',
+  'Signature'                   => 'Underskrift',
+  'Sold'                        => 'Solgt',
+  'Source'                      => 'Bilag',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Opgørelse',
+  'Statement Balance'           => 'Balanceopgørelse',
+  'Statement sent to'           => 'Opgørelse sendt til',
+  'Statements sent to printer!' => 'Opgørelser sendt til printer',
+  'Stock Assembly'              => 'Lagr sammensætning',
+  'Stylesheet'                  => 'Stilark',
+  'Subject'                     => 'Emne',
+  'Subtotal'                    => 'Subtotal',
+  'System'                      => 'System',
+  'Tax'                         => 'Afgift/Moms',
+  'Tax Accounts'                => 'Afgift/Momskonti',
+  'Tax Included'                => 'Inkl. afgifter og moms',
+  'Tax collected'               => 'Skat opkrævet',
+  'Tax paid'                    => 'Skat betalt',
+  'Taxable'                     => 'Afgifts/momspligtig',
+  'Template saved!'             => 'Skabelon gemt!',
+  'Templates'                   => 'Skabeloner',
+  'Terms: Net'                  => 'Netto',
+  'The following Datasets are not in use and can be deleted' => 'De følgende datasæt er ikke i brug og kan slettes',
+  'The following Datasets need to be updated' => 'De følgende datasæt skal opdateres',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Dette er en indledende kontrol af eksisterende kilder. Ingenting vil blive oprettet eller slettet på dette trin',
+  'To'                          => 'til',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Skift brugernavnet for en eksisterende bruger og gem for at tilføje en ny bruger til en gruppe. Den nye bruger vil så bive gemt med de samme indstillinger under det nye brugernavn.',
+  'Top Level'                   => 'Topniveau',
+  'Total'                       => 'I alt',
+  'Transaction Date missing!'   => 'Dato mangler!',
+  'Transaction deleted!'        => 'Postering slettet!',
+  'Transaction posted!'         => 'Postering bogført!',
+  'Transaction reversal enforced for all dates' => 'Rettelser af posteringer skal altid bogføres explicit',
+  'Transaction reversal enforced up to' => 'Rettelser af posteringer skal bogføres explicit indtil',
+  'Transactions'                => 'Posteringer',
+  'Transactions exist, cannot delete customer!' => 'Kunde kan ikke fjernes da der er posteringer!',
+  'Transactions exist, cannot delete vendor!' => 'Leverandør kan ikke fjernes da der er posteringer!',
+  'Transactions exist; cannot delete account!' => 'Konto kan ikke fjernes da der er posteringer!',
+  'Trial Balance'               => 'Foreløbig status',
+  'Unit'                        => 'Enhed',
+  'Unit of measure'             => 'Måleenhed',
+  'Update'                      => 'Opdatér',
+  'Update Dataset'              => 'Opdatér datasæt',
+  'Updated'                     => 'Opdateret',
+  'Use Templates'               => 'Brug skabeloner',
+  'User'                        => 'Bruger',
+  'User deleted!'               => 'Bruger slettet!',
+  'User saved!'                 => 'Bruger gemt!',
+  'Vendor'                      => 'Leverandør',
+  'Vendor deleted!'             => 'Leverandør slettet!',
+  'Vendor missing!'             => 'Leverandør mangler!',
+  'Vendor not on file!'         => 'Leverandør ikke i databasen!',
+  'Vendor saved!'               => 'Leverandør gemt!',
+  'Vendors'                     => 'Leverandører',
+  'Version'                     => 'Version',
+  'Weight'                      => 'Vægt',
+  'Weight Unit'                 => 'Vægtenhed',
+  'What type of item is this?'  => 'Hvilken type ting er dette?',
+  'Year End'                    => 'Årsafslutning',
+  'Yes'                         => 'Ja',
+  'You are logged out!'         => 'Du er logget ud',
+  'You did not enter a name!'   => 'Du angav ikke et navn',
+  'You must enter a host and port for local and remote connections!' => 'Du skal angive en vært og en port for lokale og eksterne forbindelser!',
+  'as at'                       => 'som ved',
+  'collected on sales'          => 'indsamlet ved salg',
+  'days'                        => 'dage',
+  'does not exist'              => 'eksisterer ikke',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendt via e-post til',
+  'for Period'                  => 'for perioden',
+  'hr'                          => 'time',
+  'is already a member!'        => 'er allerede et medlem',
+  'is not a member!'            => 'er ikke et medlem!',
+  'localhost'                   => 'lokalt',
+  'paid on purchases'           => 'betalt ved indkøb',
+  'sent to printer'             => 'sendt til printer',
+  'successfully created!'       => 'oprettet!',
+  'successfully deleted!'       => 'slettet!',
+  'to'                          => 'til',
+  'website'                     => 'på Internet',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/am b/sql-ledger/locale/dk/am
new file mode 100644 (file)
index 0000000..7546a0d
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Kreditorer',
+  'AR'                          => 'Debitorer',
+  'Account'                     => 'Konto',
+  'Account Number'              => 'Kontonummer',
+  'Account Number missing!'     => 'Kontonummer mangler!',
+  'Account Type'                => 'Kontotype',
+  'Account Type missing!'       => 'Kontotype mangler!',
+  'Account deleted!'            => 'Konto slettet!',
+  'Account saved!'              => 'Konto gemt!',
+  'Add Account'                 => 'Ny konto',
+  'Add GIFI'                    => 'Ny GIFI',
+  'Address'                     => 'Adresse',
+  'Asset'                       => 'Aktiv',
+  'Audit Control'               => 'Revisionskontrol',
+  'Backup sent to'              => 'Sikkerhedskopier sendt til',
+  'Books are open'              => 'Bogføringen er åben for rettelser',
+  'Business Number'             => 'CVR-nummer',
+  'COGS'                        => 'Indkøb',
+  'Cannot delete account!'      => 'Kan ikke slette konto!',
+  'Cannot delete default account!' => 'Kan ikke slette standardkonto!',
+  'Cannot save account!'        => 'Kan ikke gemme konto!',
+  'Cannot save preferences!'    => 'Kan ikke gemme præferencer!',
+  'Character Set'               => 'Tegnsæt',
+  'Chart of Accounts'           => 'Kontoplan',
+  'Close Books up to'           => 'Afslut bogføring op til',
+  'Company'                     => 'Firma',
+  'Continue'                    => 'Fortsæt',
+  'Copy to COA'                 => 'Kopiér til COA',
+  'Credit'                      => 'Kredit',
+  'Date Format'                 => 'Datoformat',
+  'Debit'                       => 'Debet',
+  'Delete'                      => 'Fjern',
+  'Delete Account'              => 'Fjern konto',
+  'Description'                 => 'Beskrivelse',
+  'Dropdown Limit'              => 'Grænse for nedtræk',
+  'E-mail'                      => 'E-post',
+  'Edit'                        => 'Redigér',
+  'Edit Account'                => 'Redigér konto',
+  'Edit GIFI'                   => 'Redigér GIFI',
+  'Edit Preferences for'        => 'Redigér opsætning for',
+  'Edit Template'               => 'Redigér skabelon',
+  'Enforce transaction reversal for all dates' => 'Gennemtving explicitte rettelser af posteringer for alle datoer',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Angiv op til 3 bogstaver adskilt med kolon (fx DKK:EUR:USD) for dine indenlandske og udenlandske valutaer',
+  'Equity'                      => 'Egenkapital',
+  'Expense'                     => 'Udgift',
+  'Expense Account'             => 'Udgiftskonto',
+  'Expense/Asset'               => 'Udgift/Aktiv',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Gevinst på valutahandel',
+  'Foreign Exchange Loss'       => 'Tab på valutahandel',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI slettet!',
+  'GIFI missing!'               => 'GIFI mangler!',
+  'GIFI saved!'                 => 'GIFI gemt!',
+  'Heading'                     => 'Overskrift',
+  'Include in drop-down menus'  => 'Inkludér i rullegardin-menuer',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Skal denne konto kunne vælges som afgifts- eller momskonto ved oprettelsen af kunder/leverandører?',
+  'Income'                      => 'Indtægt',
+  'Income Account'              => 'Indtægtskonto',
+  'Inventory'                   => 'Artikler',
+  'Inventory Account'           => 'Lagerkonto',
+  'Is this a summary account to record' => 'Samlekonto for',
+  'Language'                    => 'Sprog',
+  'Last Invoice Number'         => 'Seneste fakturanummer',
+  'Last Numbers & Default Accounts' => 'Løbenumre og standardkonti',
+  'Last Purchase Order Number'  => 'Seneste nummer på indkøbsordre',
+  'Last Sales Order Number'     => 'Seneste salgsordrenummer',
+  'Liability'                   => 'Passiv',
+  'Link'                        => 'Referencer',
+  'Name'                        => 'Navn',
+  'No'                          => 'Nej',
+  'No email address for'        => 'Ingen epostadresse for',
+  'Number'                      => 'Nummer',
+  'Number Format'               => 'Numerisk format',
+  'Parts Inventory'             => 'Vareliste',
+  'Password'                    => 'Adgangskode',
+  'Payables'                    => 'Udeståender',
+  'Payment'                     => 'Betaling',
+  'Phone'                       => 'Tel.',
+  'Preferences saved!'          => 'Indstillinger gemt!',
+  'Rate'                        => 'Rate',
+  'Receivables'                 => 'Indbetalinger',
+  'Sales'                       => 'Salg',
+  'Save'                        => 'Gem',
+  'Service Items'               => 'Tjenester',
+  'Ship via'                    => 'Send via',
+  'Signature'                   => 'Underskrift',
+  'Stylesheet'                  => 'Stilark',
+  'Tax'                         => 'Afgift/Moms',
+  'Tax Accounts'                => 'Afgift/Momskonti',
+  'Template saved!'             => 'Skabelon gemt!',
+  'Transaction reversal enforced for all dates' => 'Rettelser af posteringer skal altid bogføres explicit',
+  'Transaction reversal enforced up to' => 'Rettelser af posteringer skal bogføres explicit indtil',
+  'Transactions exist; cannot delete account!' => 'Konto kan ikke fjernes da der er posteringer!',
+  'Weight Unit'                 => 'Vægtenhed',
+  'Year End'                    => 'Årsafslutning',
+  'Yes'                         => 'Ja',
+  'does not exist'              => 'eksisterer ikke',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'ny_konto'                    => 'add_account',
+  'fortsæt'                     => 'continue',
+  'kopiér_til_coa'              => 'copy_to_coa',
+  'fjern'                       => 'delete',
+  'redigér'                     => 'edit',
+  'redigér_konto'               => 'edit_account',
+  'gem'                         => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/ap b/sql-ledger/locale/dk/ap
new file mode 100644 (file)
index 0000000..424926d
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Leverandørfaktura',
+  'AP Transactions'             => 'Leverandørfakturaer',
+  'Account'                     => 'Konto',
+  'Add Accounts Payables Transaction' => 'Ny leverandørpostering',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Beløb',
+  'Amount Due'                  => 'Forfaldent',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Transaction' => 'Er du sikker på du vil fjerne postering',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Cannot delete transaction!'  => 'Kan ikke slette postering!',
+  'Cannot post payment for a closed period!' => 'Kan ikke bogføre betaling for en afsluttet periode',
+  'Cannot post transaction for a closed period!' => 'Kan ikke bogføre postering for en afsluttet periode!',
+  'Cannot post transaction!'    => 'Kan ikke bogføre postering!',
+  'Closed'                      => 'Afsluttet',
+  'Confirm!'                    => 'Bekræft!',
+  'Continue'                    => 'Fortsæt',
+  'Currency'                    => 'Valuta',
+  'Customer not on file!'       => 'Kunde ikke i databasen!',
+  'Date'                        => 'Dato',
+  'Date Paid'                   => 'Betalingsdato',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Fjern',
+  'Description'                 => 'Beskrivelse',
+  'Due Date'                    => 'Forfaldsdato',
+  'Due Date missing!'           => 'Forfaldsdato mangler!',
+  'Edit Accounts Payables Transaction' => 'Redigér leverandørpostering',
+  'Employee'                    => 'Ansat',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Vekselkurs',
+  'Exchangerate for payment missing!' => 'Valutakurs for betaling mangler!',
+  'Exchangerate missing!'       => 'Vekselkurs mangler!',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadato',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'marts',
+  'May'                         => 'maj',
+  'May '                        => 'maj ',
+  'Notes'                       => 'Bemærkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Open'                        => 'Åbn',
+  'Order'                       => 'Ordre',
+  'Order Number'                => 'Ordrenummer',
+  'Paid'                        => 'Betalt',
+  'Payment date missing!'       => 'Betalingsdato mangler!',
+  'Payments'                    => 'Betalinger',
+  'Post'                        => 'Bogfør',
+  'Post as new'                 => 'Bogfør som ny',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekt ikke i databasen!',
+  'Purchase Invoice'            => 'Indkøbsfaktura',
+  'Select from one of the names below' => 'Vælg en af navnene nedenfor',
+  'Select from one of the projects below' => 'Vælg et af projekterne nedenfor',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Source'                      => 'Bilag',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Afgift/Moms',
+  'Tax Included'                => 'Inkl. afgifter og moms',
+  'To'                          => 'til',
+  'Total'                       => 'I alt',
+  'Transaction deleted!'        => 'Postering slettet!',
+  'Transaction posted!'         => 'Postering bogført!',
+  'Update'                      => 'Opdatér',
+  'Vendor'                      => 'Leverandør',
+  'Vendor missing!'             => 'Leverandør mangler!',
+  'Vendor not on file!'         => 'Leverandør ikke i databasen!',
+  'Yes'                         => 'Ja',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'leverandørfaktura'           => 'ap_transaction',
+  'ny_leverandørpostering'      => 'add_accounts_payables_transaction',
+  'fortsæt'                     => 'continue',
+  'fjern'                       => 'delete',
+  'redigér_leverandørpostering' => 'edit_accounts_payables_transaction',
+  'bogfør'                      => 'post',
+  'bogfør_som_ny'               => 'post_as_new',
+  'indkøbsfaktura'              => 'purchase_invoice',
+  'opdatér'                     => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/ar b/sql-ledger/locale/dk/ar
new file mode 100644 (file)
index 0000000..9f778b0
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'Debitorpostering',
+  'AR Transactions'             => 'Debitorposteringer',
+  'Account'                     => 'Konto',
+  'Add Accounts Receivables Transaction' => 'Ny debitorpostering',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Beløb',
+  'Amount Due'                  => 'Forfaldent',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Transaction' => 'Er du sikker på du vil fjerne postering',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Cannot delete transaction!'  => 'Kan ikke slette postering!',
+  'Cannot post payment for a closed period!' => 'Kan ikke bogføre betaling for en afsluttet periode',
+  'Cannot post transaction for a closed period!' => 'Kan ikke bogføre postering for en afsluttet periode!',
+  'Cannot post transaction!'    => 'Kan ikke bogføre postering!',
+  'Closed'                      => 'Afsluttet',
+  'Confirm!'                    => 'Bekræft!',
+  'Continue'                    => 'Fortsæt',
+  'Credit Limit'                => 'Kreditgrænse',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Kunde',
+  'Customer missing!'           => 'Kunde mangler!',
+  'Customer not on file!'       => 'Kunde ikke i databasen!',
+  'Date'                        => 'Dato',
+  'Date Paid'                   => 'Betalingsdato',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Fjern',
+  'Description'                 => 'Beskrivelse',
+  'Due Date'                    => 'Forfaldsdato',
+  'Due Date missing!'           => 'Forfaldsdato mangler!',
+  'Edit Accounts Receivables Transaction' => 'Redigér debitorpostering',
+  'Employee'                    => 'Ansat',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Vekselkurs',
+  'Exchangerate for payment missing!' => 'Valutakurs for betaling mangler!',
+  'Exchangerate missing!'       => 'Vekselkurs mangler!',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadato',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'marts',
+  'May'                         => 'maj',
+  'May '                        => 'maj ',
+  'Notes'                       => 'Bemærkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Open'                        => 'Åbn',
+  'Order'                       => 'Ordre',
+  'Order Number'                => 'Ordrenummer',
+  'Paid'                        => 'Betalt',
+  'Payment date missing!'       => 'Betalingsdato mangler!',
+  'Payments'                    => 'Betalinger',
+  'Post'                        => 'Bogfør',
+  'Post as new'                 => 'Bogfør som ny',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekt ikke i databasen!',
+  'Remaining'                   => 'Resterer',
+  'Sales Invoice'               => 'Salgsfaktura',
+  'Select from one of the names below' => 'Vælg en af navnene nedenfor',
+  'Select from one of the projects below' => 'Vælg et af projekterne nedenfor',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Source'                      => 'Bilag',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Afgift/Moms',
+  'Tax Included'                => 'Inkl. afgifter og moms',
+  'To'                          => 'til',
+  'Total'                       => 'I alt',
+  'Transaction deleted!'        => 'Postering slettet!',
+  'Transaction posted!'         => 'Postering bogført!',
+  'Update'                      => 'Opdatér',
+  'Vendor not on file!'         => 'Leverandør ikke i databasen!',
+  'Yes'                         => 'Ja',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'debitorpostering'            => 'ar_transaction',
+  'fortsæt'                     => 'continue',
+  'fjern'                       => 'delete',
+  'bogfør'                      => 'post',
+  'bogfør_som_ny'               => 'post_as_new',
+  'salgsfaktura'                => 'sales_invoice',
+  'opdatér'                     => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/arap b/sql-ledger/locale/dk/arap
new file mode 100644 (file)
index 0000000..af22061
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Adresse',
+  'Continue'                    => 'Fortsæt',
+  'Customer not on file!'       => 'Kunde ikke i databasen!',
+  'Description'                 => 'Beskrivelse',
+  'Number'                      => 'Nummer',
+  'Project not on file!'        => 'Projekt ikke i databasen!',
+  'Select from one of the names below' => 'Vælg en af navnene nedenfor',
+  'Select from one of the projects below' => 'Vælg et af projekterne nedenfor',
+  'Vendor not on file!'         => 'Leverandør ikke i databasen!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'fortsæt'                     => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/ca b/sql-ledger/locale/dk/ca
new file mode 100644 (file)
index 0000000..302aeea
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Balance'                     => 'Balance',
+  'Chart of Accounts'           => 'Kontoplan',
+  'Credit'                      => 'Kredit',
+  'Date'                        => 'Dato',
+  'Debit'                       => 'Debet',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Description'                 => 'Beskrivelse',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'List Transactions'           => 'Vis bogføringer',
+  'Mar'                         => 'mar',
+  'March'                       => 'marts',
+  'May'                         => 'maj',
+  'May '                        => 'maj ',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Reference'                   => 'Reference',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Subtotal'                    => 'Subtotal',
+  'To'                          => 'til',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'vis_bogføringer'             => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/cp b/sql-ledger/locale/dk/cp
new file mode 100644 (file)
index 0000000..79d0579
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Beløb',
+  'Amount does not equal applied!' => 'Beløb er ikke det samme som brugt!',
+  'Amount missing!'             => 'Konto mangler!',
+  'Applied'                     => 'Udført',
+  'Cannot post payment!'        => 'Kan ikke bogføre betaling',
+  'Cannot process payment for a closed period!' => 'Kan ikke behandle betaling for en afsluttet periode!',
+  'Check'                       => 'Check',
+  'Check printed!'              => 'Check udskrevet',
+  'Check printing failed!'      => 'Udskrivning af check mislykkedes',
+  'Continue'                    => 'Fortsæt',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Kunde',
+  'Customer not on file!'       => 'Kunde ikke i databasen!',
+  'Date'                        => 'Dato',
+  'Date missing!'               => 'Dato mangler!',
+  'Description'                 => 'Beskrivelse',
+  'Due'                         => 'Forfald',
+  'Exchangerate'                => 'Vekselkurs',
+  'From'                        => 'Fra',
+  'Invoice'                     => 'Faktura',
+  'Invoices'                    => 'Fakturaer',
+  'Nothing applied!'            => 'Ingenting udført!',
+  'Number'                      => 'Nummer',
+  'Paid in full'                => 'Paid in full',
+  'Payment'                     => 'Betaling',
+  'Payment posted!'             => 'Betaling bogført!',
+  'Post'                        => 'Bogfør',
+  'Print'                       => 'Udskriv',
+  'Printer'                     => 'Printer',
+  'Project not on file!'        => 'Projekt ikke i databasen!',
+  'Receipt'                     => 'Kvittering',
+  'Reference'                   => 'Reference',
+  'Screen'                      => 'Skærm',
+  'Select from one of the names below' => 'Vælg en af navnene nedenfor',
+  'Select from one of the projects below' => 'Vælg et af projekterne nedenfor',
+  'To'                          => 'til',
+  'Update'                      => 'Opdatér',
+  'Vendor'                      => 'Leverandør',
+  'Vendor not on file!'         => 'Leverandør ikke i databasen!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'fortsæt'                     => 'continue',
+  'bogfør'                      => 'post',
+  'udskriv'                     => 'print',
+  'opdatér'                     => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/ct b/sql-ledger/locale/dk/ct
new file mode 100644 (file)
index 0000000..2b8f91b
--- /dev/null
@@ -0,0 +1,69 @@
+$self{texts} = {
+  'Add'                         => 'Tilføj',
+  'Address'                     => 'Adresse',
+  'All'                         => 'Alt',
+  'Bcc'                         => 'Blind kopi',
+  'Cannot delete customer!'     => 'Kan ikke slette kunde!',
+  'Cannot delete vendor!'       => 'Kan ikke slette leverandør!',
+  'Cc'                          => 'Kopi',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsæt',
+  'Credit Limit'                => 'Kreditgrænse',
+  'Customer deleted!'           => 'Kunde slettet!',
+  'Customer saved!'             => 'Kunde gemt!',
+  'Customers'                   => 'Kunder',
+  'Delete'                      => 'Fjern',
+  'Discount'                    => 'Rabat',
+  'E-mail'                      => 'E-post',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Invoice'                     => 'Faktura',
+  'Name'                        => 'Navn',
+  'Name missing!'               => 'Navn mangler!',
+  'Notes'                       => 'Bemærkninger',
+  'Number'                      => 'Nummer',
+  'Order'                       => 'Ordre',
+  'Orphaned'                    => 'Fritstående',
+  'Phone'                       => 'Tel.',
+  'Save'                        => 'Gem',
+  'Ship to'                     => 'Send til',
+  'Tax Included'                => 'Inkl. afgifter og moms',
+  'Taxable'                     => 'Afgifts/momspligtig',
+  'Terms: Net'                  => 'Netto',
+  'Transactions exist, cannot delete customer!' => 'Kunde kan ikke fjernes da der er posteringer!',
+  'Transactions exist, cannot delete vendor!' => 'Leverandør kan ikke fjernes da der er posteringer!',
+  'Vendor deleted!'             => 'Leverandør slettet!',
+  'Vendor saved!'               => 'Leverandør gemt!',
+  'Vendors'                     => 'Leverandører',
+  'days'                        => 'dage',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'tilføj'                      => 'add',
+  'fortsæt'                     => 'continue',
+  'fjern'                       => 'delete',
+  'faktura'                     => 'invoice',
+  'ordre'                       => 'order',
+  'gem'                         => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/gl b/sql-ledger/locale/dk/gl
new file mode 100644 (file)
index 0000000..3693fa2
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Leverandørfaktura',
+  'AR Transaction'              => 'Debitorpostering',
+  'Account'                     => 'Konto',
+  'Add General Ledger Transaction' => 'Ny postering i hovedbog',
+  'Address'                     => 'Adresse',
+  'All'                         => 'Alt',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Transaction' => 'Er du sikker på du vil fjerne postering',
+  'Asset'                       => 'Aktiv',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Balance'                     => 'Balance',
+  'Cannot delete transaction!'  => 'Kan ikke slette postering!',
+  'Cannot have a value in both Debit and Credit!' => 'Kan ikke have en værdi i både debet og kredit!',
+  'Cannot post a transaction without a value!' => 'Cannot post a transaction without a value!',
+  'Cannot post transaction for a closed period!' => 'Kan ikke bogføre postering for en afsluttet periode!',
+  'Confirm!'                    => 'Bekræft!',
+  'Continue'                    => 'Fortsæt',
+  'Credit'                      => 'Kredit',
+  'Customer not on file!'       => 'Kunde ikke i databasen!',
+  'Date'                        => 'Dato',
+  'Debit'                       => 'Debet',
+  'Debit and credit out of balance!' => 'Debet og kredit skal være det samme!',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Fjern',
+  'Description'                 => 'Beskrivelse',
+  'Edit General Ledger Transaction' => 'Redigér en postering i hovedbog',
+  'Equity'                      => 'Egenkapital',
+  'Expense'                     => 'Udgift',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'Postering i hovedbog',
+  'General Ledger'              => 'Hovedbog',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Income'                      => 'Indtægt',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Liability'                   => 'Passiv',
+  'Mar'                         => 'mar',
+  'March'                       => 'marts',
+  'May'                         => 'maj',
+  'May '                        => 'maj ',
+  'Notes'                       => 'Bemærkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Post'                        => 'Bogfør',
+  'Post as new'                 => 'Bogfør som ny',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekt ikke i databasen!',
+  'Purchase Invoice'            => 'Indkøbsfaktura',
+  'Reference'                   => 'Reference',
+  'Reference missing!'          => 'Reference mangler',
+  'Reports'                     => 'Rapporter',
+  'Sales Invoice'               => 'Salgsfaktura',
+  'Select from one of the names below' => 'Vælg en af navnene nedenfor',
+  'Select from one of the projects below' => 'Vælg et af projekterne nedenfor',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Source'                      => 'Bilag',
+  'Subtotal'                    => 'Subtotal',
+  'To'                          => 'til',
+  'Transaction Date missing!'   => 'Dato mangler!',
+  'Transaction deleted!'        => 'Postering slettet!',
+  'Transaction posted!'         => 'Postering bogført!',
+  'Update'                      => 'Opdatér',
+  'Vendor not on file!'         => 'Leverandør ikke i databasen!',
+  'Yes'                         => 'Ja',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'leverandørfaktura'           => 'ap_transaction',
+  'debitorpostering'            => 'ar_transaction',
+  'fortsæt'                     => 'continue',
+  'fjern'                       => 'delete',
+  'postering_i_hovedbog'        => 'gl_transaction',
+  'bogfør'                      => 'post',
+  'bogfør_som_ny'               => 'post_as_new',
+  'indkøbsfaktura'              => 'purchase_invoice',
+  'salgsfaktura'                => 'sales_invoice',
+  'opdatér'                     => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/ic b/sql-ledger/locale/dk/ic
new file mode 100644 (file)
index 0000000..38e0d70
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Aktiv',
+  'Add'                         => 'Tilføj',
+  'Add Assembly'                => 'Ny sammensætning',
+  'Add Part'                    => 'Ny vare',
+  'Add Purchase Order'          => 'Ny indkøbsordre',
+  'Add Sales Order'             => 'Ny salgsordre',
+  'Add Service'                 => 'Ny tjeneste',
+  'Address'                     => 'Adresse',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Assemblies'                  => 'Sammensætninger',
+  'Assemblies restocked!'       => 'Sammensætninger genlagret',
+  'Assembly Number missing!'    => 'Sammensætningsnummer mangler',
+  'Attachment'                  => 'Bilag',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Blind kopi',
+  'Bin'                         => 'Varelager',
+  'Bought'                      => 'Købt',
+  'COGS'                        => 'Indkøb',
+  'Cannot delete item already invoiced!' => 'Kan ikke slette allerede faktureret enkeltdel!',
+  'Cannot delete item on order!' => 'Kan ikke slette bestilt enkeltdel!',
+  'Cannot delete item which is part of an assembly!' => 'kan ikke slette en enhed som er en del af en sammensætning!',
+  'Cannot delete item!'         => 'Kan ikke slette enhed!',
+  'Cannot stock assemblies!'    => 'Kan ikke genbesætte sammensætninger',
+  'Cc'                          => 'Kopi',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsæt',
+  'Copies'                      => 'Kopier',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Fjern',
+  'Delivery Date'               => 'Leveringsdato',
+  'Description'                 => 'Beskrivelse',
+  'Drawing'                     => 'Træk',
+  'E-mail'                      => 'E-post',
+  'E-mail address missing!'     => 'E-post-adresse mangler!',
+  'Edit Assembly'               => 'Redigér sammensætning',
+  'Edit Part'                   => 'Redigér vare',
+  'Edit Service'                => 'Redigér tjeneste',
+  'Expense'                     => 'Udgift',
+  'Extended'                    => 'Udvidet',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'Image'                       => 'Billede',
+  'In-line'                     => 'Indlejret',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Income'                      => 'Indtægt',
+  'Individual Items'            => 'Individuelle enheder',
+  'Inventory'                   => 'Artikler',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Lagerbeholdning skal være nul for at du kan forælde denne sammensætning',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Lagerbeholdning skal være nul for at du kan forælde denne enhed',
+  'Inventory quantity must be zero!' => 'Lagerbeholdning skal være nul',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Item deleted!'               => 'Enkeltdel slettet!',
+  'Item not on file!'           => 'Enkeltdel er ikke i databasen!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Last Cost'                   => 'Seneste pris',
+  'Line Total'                  => 'Antal linjer',
+  'Link Accounts'               => 'Forbind konti',
+  'List Price'                  => 'Listepris',
+  'Make'                        => 'Fabrikat',
+  'Mar'                         => 'mar',
+  'March'                       => 'marts',
+  'May'                         => 'maj',
+  'May '                        => 'maj ',
+  'Message'                     => 'Besked',
+  'Microfiche'                  => 'Mikrofilm',
+  'Model'                       => 'Model',
+  'Name'                        => 'Navn',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Bemærkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Tal mangler i række',
+  'Obsolete'                    => 'Forældet',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'On Hand'                     => 'På lager',
+  'On Order'                    => 'I ordre',
+  'Order'                       => 'Ordre',
+  'Order Date missing!'         => 'Ordredato mangler',
+  'Order Number'                => 'Ordrenummer',
+  'Order Number missing!'       => 'Ordrenummer mangler',
+  'Ordered'                     => 'bestilt',
+  'Orphaned'                    => 'Fritstående',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Følgeseddel',
+  'Packing List Date missing!'  => 'Dato for pakkeliste mangler!',
+  'Packing List Number missing!' => 'Nummer for pakkeliste mangler!',
+  'Part'                        => 'Vare',
+  'Part Number missing!'        => 'Varenummer mangler!',
+  'Parts'                       => 'Dele',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Projekt',
+  'Purchase Order'              => 'Indkøbsordre',
+  'Qty'                         => 'Antal',
+  'ROP'                         => 'Genbestil ved',
+  'Recd'                        => 'Modtaget',
+  'Required by'                 => 'Bestilt af',
+  'Sales'                       => 'Salg',
+  'Sales Order'                 => 'Salgsordre',
+  'Save'                        => 'Gem',
+  'Screen'                      => 'Skærm',
+  'Select from one of the items below' => 'Vælg fra en af tingene nedenfor, og tryk "Fortsæt"',
+  'Select postscript or PDF!'   => 'Vælg postscript eller PDF',
+  'Sell Price'                  => 'Salgspris',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Tjeneste',
+  'Service Number missing!'     => 'Tjenestenummer mangler!',
+  'Services'                    => 'Tjenester',
+  'Ship'                        => 'Send',
+  'Ship to'                     => 'Send til',
+  'Short'                       => 'Kort',
+  'Sold'                        => 'Solgt',
+  'Stock Assembly'              => 'Lagr sammensætning',
+  'Subject'                     => 'Emne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Afgift/Moms',
+  'To'                          => 'til',
+  'Top Level'                   => 'Topniveau',
+  'Total'                       => 'I alt',
+  'Unit'                        => 'Enhed',
+  'Unit of measure'             => 'Måleenhed',
+  'Update'                      => 'Opdatér',
+  'Updated'                     => 'Opdateret',
+  'Weight'                      => 'Vægt',
+  'What type of item is this?'  => 'Hvilken type ting er dette?',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendt via e-post til',
+  'hr'                          => 'time',
+  'sent to printer'             => 'sendt til printer',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'tilføj'                      => 'add',
+  'ny_sammensætning'            => 'add_assembly',
+  'ny_vare'                     => 'add_part',
+  'ny_tjeneste'                 => 'add_service',
+  'fortsæt'                     => 'continue',
+  'fjern'                       => 'delete',
+  'redigér_sammensætning'       => 'edit_assembly',
+  'redigér_vare'                => 'edit_part',
+  'redigér_tjeneste'            => 'edit_service',
+  'gem'                         => 'save',
+  'opdatér'                     => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/io b/sql-ledger/locale/dk/io
new file mode 100644 (file)
index 0000000..117e8d2
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Ny indkøbsordre',
+  'Add Sales Order'             => 'Ny salgsordre',
+  'Address'                     => 'Adresse',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Attachment'                  => 'Bilag',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Bcc'                         => 'Blind kopi',
+  'Bin'                         => 'Varelager',
+  'Cc'                          => 'Kopi',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsæt',
+  'Copies'                      => 'Kopier',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delivery Date'               => 'Leveringsdato',
+  'Description'                 => 'Beskrivelse',
+  'E-mail'                      => 'E-post',
+  'E-mail address missing!'     => 'E-post-adresse mangler!',
+  'Extended'                    => 'Udvidet',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'In-line'                     => 'Indlejret',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Item not on file!'           => 'Enkeltdel er ikke i databasen!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'marts',
+  'May'                         => 'maj',
+  'May '                        => 'maj ',
+  'Message'                     => 'Besked',
+  'Name'                        => 'Navn',
+  'No.'                         => 'No.',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Tal mangler i række',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Order'                       => 'Ordre',
+  'Order Date missing!'         => 'Ordredato mangler',
+  'Order Number missing!'       => 'Ordrenummer mangler',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Følgeseddel',
+  'Packing List Date missing!'  => 'Dato for pakkeliste mangler!',
+  'Packing List Number missing!' => 'Nummer for pakkeliste mangler!',
+  'Part'                        => 'Vare',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Projekt',
+  'Purchase Order'              => 'Indkøbsordre',
+  'Qty'                         => 'Antal',
+  'Recd'                        => 'Modtaget',
+  'Required by'                 => 'Bestilt af',
+  'Sales Order'                 => 'Salgsordre',
+  'Screen'                      => 'Skærm',
+  'Select from one of the items below' => 'Vælg fra en af tingene nedenfor, og tryk "Fortsæt"',
+  'Select postscript or PDF!'   => 'Vælg postscript eller PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Tjeneste',
+  'Ship'                        => 'Send',
+  'Ship to'                     => 'Send til',
+  'Subject'                     => 'Emne',
+  'To'                          => 'til',
+  'Unit'                        => 'Enhed',
+  'What type of item is this?'  => 'Hvilken type ting er dette?',
+  'emailed to'                  => 'sendt via e-post til',
+  'sent to printer'             => 'sendt til printer',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'fortsæt'                     => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/ir b/sql-ledger/locale/dk/ir
new file mode 100644 (file)
index 0000000..cf77f62
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Add Purchase Invoice'        => 'Ny indkøbsfaktura',
+  'Add Purchase Order'          => 'Ny indkøbsordre',
+  'Add Sales Order'             => 'Ny salgsordre',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Beløb',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Invoice Number' => 'Er du sikker på du vil fjerne fakturanummer',
+  'Attachment'                  => 'Bilag',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Bcc'                         => 'Blind kopi',
+  'Bin'                         => 'Varelager',
+  'Cannot delete invoice!'      => 'Kan ikke slette faktura!',
+  'Cannot post invoice for a closed period!' => 'Kan ikke bogføre faktura for en afsluttet periode!',
+  'Cannot post invoice!'        => 'Kan ikke bogføre faktura!',
+  'Cannot post payment for a closed period!' => 'Kan ikke bogføre betaling for en afsluttet periode',
+  'Cc'                          => 'Kopi',
+  'Confirm!'                    => 'Bekræft!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsæt',
+  'Copies'                      => 'Kopier',
+  'Currency'                    => 'Valuta',
+  'Customer not on file!'       => 'Kunde ikke i databasen!',
+  'Date'                        => 'Dato',
+  'Date Due'                    => 'Forfaldsdato',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Fjern',
+  'Delivery Date'               => 'Leveringsdato',
+  'Description'                 => 'Beskrivelse',
+  'E-mail'                      => 'E-post',
+  'E-mail address missing!'     => 'E-post-adresse mangler!',
+  'Edit Purchase Invoice'       => 'Redigér projekt',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Vekselkurs',
+  'Exchangerate for payment missing!' => 'Valutakurs for betaling mangler!',
+  'Exchangerate missing!'       => 'Vekselkurs mangler!',
+  'Extended'                    => 'Udvidet',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'In-line'                     => 'Indlejret',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadato',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Invoice deleted!'            => 'Faktura slettet!',
+  'Invoice posted!'             => 'Faktura bogført!',
+  'Item not on file!'           => 'Enkeltdel er ikke i databasen!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'marts',
+  'May'                         => 'maj',
+  'May '                        => 'maj ',
+  'Message'                     => 'Besked',
+  'Name'                        => 'Navn',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Bemærkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Tal mangler i række',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Order'                       => 'Ordre',
+  'Order Date missing!'         => 'Ordredato mangler',
+  'Order Number'                => 'Ordrenummer',
+  'Order Number missing!'       => 'Ordrenummer mangler',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Følgeseddel',
+  'Packing List Date missing!'  => 'Dato for pakkeliste mangler!',
+  'Packing List Number missing!' => 'Nummer for pakkeliste mangler!',
+  'Part'                        => 'Vare',
+  'Payment date missing!'       => 'Betalingsdato mangler!',
+  'Payments'                    => 'Betalinger',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Bogfør',
+  'Post as new'                 => 'Bogfør som ny',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekt ikke i databasen!',
+  'Purchase Order'              => 'Indkøbsordre',
+  'Qty'                         => 'Antal',
+  'Recd'                        => 'Modtaget',
+  'Record in'                   => 'Bogfør på',
+  'Required by'                 => 'Bestilt af',
+  'Sales Order'                 => 'Salgsordre',
+  'Screen'                      => 'Skærm',
+  'Select from one of the items below' => 'Vælg fra en af tingene nedenfor, og tryk "Fortsæt"',
+  'Select from one of the names below' => 'Vælg en af navnene nedenfor',
+  'Select from one of the projects below' => 'Vælg et af projekterne nedenfor',
+  'Select postscript or PDF!'   => 'Vælg postscript eller PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Tjeneste',
+  'Ship'                        => 'Send',
+  'Ship to'                     => 'Send til',
+  'Source'                      => 'Bilag',
+  'Subject'                     => 'Emne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Inkl. afgifter og moms',
+  'To'                          => 'til',
+  'Total'                       => 'I alt',
+  'Unit'                        => 'Enhed',
+  'Update'                      => 'Opdatér',
+  'Vendor'                      => 'Leverandør',
+  'Vendor missing!'             => 'Leverandør mangler!',
+  'Vendor not on file!'         => 'Leverandør ikke i databasen!',
+  'What type of item is this?'  => 'Hvilken type ting er dette?',
+  'Yes'                         => 'Ja',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendt via e-post til',
+  'sent to printer'             => 'sendt til printer',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'fortsæt'                     => 'continue',
+  'fjern'                       => 'delete',
+  'ordre'                       => 'order',
+  'bogfør'                      => 'post',
+  'bogfør_som_ny'               => 'post_as_new',
+  'opdatér'                     => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/is b/sql-ledger/locale/dk/is
new file mode 100644 (file)
index 0000000..5697185
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Add Purchase Order'          => 'Ny indkøbsordre',
+  'Add Sales Invoice'           => 'Ny salgsfaktura',
+  'Add Sales Order'             => 'Ny salgsordre',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Beløb',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Invoice Number' => 'Er du sikker på du vil fjerne fakturanummer',
+  'Attachment'                  => 'Bilag',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Bcc'                         => 'Blind kopi',
+  'Bin'                         => 'Varelager',
+  'Cannot delete invoice!'      => 'Kan ikke slette faktura!',
+  'Cannot post invoice for a closed period!' => 'Kan ikke bogføre faktura for en afsluttet periode!',
+  'Cannot post invoice!'        => 'Kan ikke bogføre faktura!',
+  'Cannot post payment for a closed period!' => 'Kan ikke bogføre betaling for en afsluttet periode',
+  'Cc'                          => 'Kopi',
+  'Confirm!'                    => 'Bekræft!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsæt',
+  'Copies'                      => 'Kopier',
+  'Credit Limit'                => 'Kreditgrænse',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Kunde',
+  'Customer missing!'           => 'Kunde mangler!',
+  'Customer not on file!'       => 'Kunde ikke i databasen!',
+  'Date'                        => 'Dato',
+  'Date Due'                    => 'Forfaldsdato',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Fjern',
+  'Delivery Date'               => 'Leveringsdato',
+  'Description'                 => 'Beskrivelse',
+  'E-mail'                      => 'E-post',
+  'E-mail address missing!'     => 'E-post-adresse mangler!',
+  'Edit Sales Invoice'          => 'Redigér salgsfaktura',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Vekselkurs',
+  'Exchangerate for payment missing!' => 'Valutakurs for betaling mangler!',
+  'Exchangerate missing!'       => 'Vekselkurs mangler!',
+  'Extended'                    => 'Udvidet',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'In-line'                     => 'Indlejret',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadato',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Invoice deleted!'            => 'Faktura slettet!',
+  'Invoice posted!'             => 'Faktura bogført!',
+  'Item not on file!'           => 'Enkeltdel er ikke i databasen!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'marts',
+  'May'                         => 'maj',
+  'May '                        => 'maj ',
+  'Message'                     => 'Besked',
+  'Name'                        => 'Navn',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Bemærkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Tal mangler i række',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Order'                       => 'Ordre',
+  'Order Date missing!'         => 'Ordredato mangler',
+  'Order Number'                => 'Ordrenummer',
+  'Order Number missing!'       => 'Ordrenummer mangler',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Følgeseddel',
+  'Packing List Date missing!'  => 'Dato for pakkeliste mangler!',
+  'Packing List Number missing!' => 'Nummer for pakkeliste mangler!',
+  'Part'                        => 'Vare',
+  'Payment date missing!'       => 'Betalingsdato mangler!',
+  'Payments'                    => 'Betalinger',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Bogfør',
+  'Post as new'                 => 'Bogfør som ny',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Print'                       => 'Udskriv',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekt ikke i databasen!',
+  'Purchase Order'              => 'Indkøbsordre',
+  'Qty'                         => 'Antal',
+  'Recd'                        => 'Modtaget',
+  'Record in'                   => 'Bogfør på',
+  'Remaining'                   => 'Resterer',
+  'Required by'                 => 'Bestilt af',
+  'Sales Order'                 => 'Salgsordre',
+  'Screen'                      => 'Skærm',
+  'Select from one of the items below' => 'Vælg fra en af tingene nedenfor, og tryk "Fortsæt"',
+  'Select from one of the names below' => 'Vælg en af navnene nedenfor',
+  'Select from one of the projects below' => 'Vælg et af projekterne nedenfor',
+  'Select postscript or PDF!'   => 'Vælg postscript eller PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Tjeneste',
+  'Ship'                        => 'Send',
+  'Ship to'                     => 'Send til',
+  'Ship via'                    => 'Send via',
+  'Source'                      => 'Bilag',
+  'Subject'                     => 'Emne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Inkl. afgifter og moms',
+  'To'                          => 'til',
+  'Total'                       => 'I alt',
+  'Unit'                        => 'Enhed',
+  'Update'                      => 'Opdatér',
+  'Vendor not on file!'         => 'Leverandør ikke i databasen!',
+  'What type of item is this?'  => 'Hvilken type ting er dette?',
+  'Yes'                         => 'Ja',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendt via e-post til',
+  'sent to printer'             => 'sendt til printer',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'fortsæt'                     => 'continue',
+  'fjern'                       => 'delete',
+  'e_post'                      => 'e_mail',
+  'ordre'                       => 'order',
+  'bogfør'                      => 'post',
+  'bogfør_som_ny'               => 'post_as_new',
+  'udskriv'                     => 'print',
+  'send_til'                    => 'ship_to',
+  'opdatér'                     => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/login b/sql-ledger/locale/dk/login
new file mode 100644 (file)
index 0000000..19adf11
--- /dev/null
@@ -0,0 +1,28 @@
+$self{texts} = {
+  'About'                       => 'Om',
+  'Accounting'                  => 'Bogføring',
+  'Database Host'               => 'Database-vært',
+  'Dataset'                     => 'Datasæt',
+  'Incorrect Dataset version!'  => 'Forkert version af datasæt!',
+  'Incorrect Password!'         => 'Forkert adgangskode',
+  'Licensed to'                 => 'Udført for',
+  'Login'                       => 'Log på',
+  'Name'                        => 'Navn',
+  'Password'                    => 'Adgangskode',
+  'User'                        => 'Bruger',
+  'Version'                     => 'Version',
+  'You are logged out!'         => 'Du er logget ud',
+  'You did not enter a name!'   => 'Du angav ikke et navn',
+  'is not a member!'            => 'er ikke et medlem!',
+  'localhost'                   => 'lokalt',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'log_på'                      => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/menu b/sql-ledger/locale/dk/menu
new file mode 100644 (file)
index 0000000..b4649c6
--- /dev/null
@@ -0,0 +1,72 @@
+$self{texts} = {
+  'AP'                          => 'Kreditorer',
+  'AP Aging'                    => 'Aldersfordeling',
+  'AR'                          => 'Debitorer',
+  'AR Aging'                    => 'Aldersfordeling',
+  'Accounting Menu'             => 'Konto-menu',
+  'Add Account'                 => 'Ny konto',
+  'Add Assembly'                => 'Ny sammensætning',
+  'Add Customer'                => 'Ny kunde',
+  'Add GIFI'                    => 'Ny GIFI',
+  'Add Part'                    => 'Ny vare',
+  'Add Project'                 => 'Nyt projekt',
+  'Add Service'                 => 'Ny tjeneste',
+  'Add Transaction'             => 'Ny postering',
+  'Add Vendor'                  => 'Ny leverandør',
+  'Assemblies'                  => 'Sammensætninger',
+  'Audit Control'               => 'Revisionskontrol',
+  'Backup'                      => 'Sikkerheskopi',
+  'Balance Sheet'               => 'Status',
+  'Cash'                        => 'Kontanter',
+  'Chart of Accounts'           => 'Kontoplan',
+  'Check'                       => 'Check',
+  'Customers'                   => 'Kunder',
+  'General Ledger'              => 'Hovedbog',
+  'Goods & Services'            => 'Varer og tjenester',
+  'HTML Templates'              => 'HTML-skabeloner',
+  'Income Statement'            => 'Driftsregnskab',
+  'Invoice'                     => 'Faktura',
+  'LaTeX Templates'             => 'LaTeX-skabeloner',
+  'List Accounts'               => 'List konti',
+  'List GIFI'                   => 'List GIFI',
+  'Logout'                      => 'Log af',
+  'Order Entry'                 => 'Ordreindgang',
+  'Packing List'                => 'Følgeseddel',
+  'Parts'                       => 'Dele',
+  'Payment'                     => 'Betaling',
+  'Payments'                    => 'Betalinger',
+  'Preferences'                 => 'Præferencer',
+  'Projects'                    => 'Projekter',
+  'Purchase Invoice'            => 'Indkøbsfaktura',
+  'Purchase Order'              => 'Indkøbsordre',
+  'Purchase Orders'             => 'Indkøbsordrer',
+  'Receipt'                     => 'Kvittering',
+  'Receipts'                    => 'Kvitteringer',
+  'Reconciliation'              => 'Afstemning',
+  'Reports'                     => 'Rapporter',
+  'Sales Invoice'               => 'Salgsfaktura',
+  'Sales Order'                 => 'Salgsordre',
+  'Sales Orders'                => 'Salgsordrer',
+  'Save to File'                => 'Gem i fil',
+  'Send by E-Mail'              => 'Sendt med epost',
+  'Services'                    => 'Tjenester',
+  'Statement'                   => 'Opgørelse',
+  'Stock Assembly'              => 'Lagr sammensætning',
+  'Stylesheet'                  => 'Stilark',
+  'System'                      => 'System',
+  'Tax collected'               => 'Skat opkrævet',
+  'Tax paid'                    => 'Skat betalt',
+  'Transactions'                => 'Posteringer',
+  'Trial Balance'               => 'Foreløbig status',
+  'Vendors'                     => 'Leverandører',
+  'Version'                     => 'Version',
+  'localhost'                   => 'lokalt',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/oe b/sql-ledger/locale/dk/oe
new file mode 100644 (file)
index 0000000..1b58c08
--- /dev/null
@@ -0,0 +1,199 @@
+$self{texts} = {
+  'Add'                         => 'Tilføj',
+  'Add Purchase Invoice'        => 'Ny indkøbsfaktura',
+  'Add Purchase Order'          => 'Ny indkøbsordre',
+  'Add Sales Invoice'           => 'Ny salgsfaktura',
+  'Add Sales Order'             => 'Ny salgsordre',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Beløb',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Order Number' => 'Er du sikker på at du vil fjerne ordrenummer',
+  'Attachment'                  => 'Bilag',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Bcc'                         => 'Blind kopi',
+  'Bin'                         => 'Varelager',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Kan ikke slette ordre!',
+  'Cannot save order!'          => 'Kan ikke gemme ordre!',
+  'Cc'                          => 'Kopi',
+  'Closed'                      => 'Afsluttet',
+  'Confirm!'                    => 'Bekræft!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsæt',
+  'Copies'                      => 'Kopier',
+  'Credit Limit'                => 'Kreditgrænse',
+  'Curr'                        => 'Val',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Kunde',
+  'Customer missing!'           => 'Kunde mangler!',
+  'Customer not on file!'       => 'Kunde ikke i databasen!',
+  'Date'                        => 'Dato',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Fjern',
+  'Delivery Date'               => 'Leveringsdato',
+  'Description'                 => 'Beskrivelse',
+  'E-mail'                      => 'E-post',
+  'E-mail address missing!'     => 'E-post-adresse mangler!',
+  'Edit Purchase Order'         => 'Redigér indkøbsordre',
+  'Edit Sales Order'            => 'Redigér salgsordre',
+  'Exchangerate'                => 'Vekselkurs',
+  'Exchangerate missing!'       => 'Vekselkurs mangler!',
+  'Extended'                    => 'Udvidet',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Indlejret',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Item not on file!'           => 'Enkeltdel er ikke i databasen!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'marts',
+  'May'                         => 'maj',
+  'May '                        => 'maj ',
+  'Message'                     => 'Besked',
+  'Name'                        => 'Navn',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Bemærkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Tal mangler i række',
+  'O'                           => 'O',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Open'                        => 'Åbn',
+  'Order'                       => 'Ordre',
+  'Order Date'                  => 'Ordredato',
+  'Order Date missing!'         => 'Ordredato mangler',
+  'Order Number'                => 'Ordrenummer',
+  'Order Number missing!'       => 'Ordrenummer mangler',
+  'Order deleted!'              => 'Ordre slettet',
+  'Order saved!'                => 'Ordre gemt',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Følgeseddel',
+  'Packing List Date missing!'  => 'Dato for pakkeliste mangler!',
+  'Packing List Number missing!' => 'Nummer for pakkeliste mangler!',
+  'Part'                        => 'Vare',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Print'                       => 'Udskriv',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekt ikke i databasen!',
+  'Purchase Order'              => 'Indkøbsordre',
+  'Purchase Orders'             => 'Indkøbsordrer',
+  'Qty'                         => 'Antal',
+  'Recd'                        => 'Modtaget',
+  'Remaining'                   => 'Resterer',
+  'Required by'                 => 'Bestilt af',
+  'Sales Order'                 => 'Salgsordre',
+  'Sales Orders'                => 'Salgsordrer',
+  'Save'                        => 'Gem',
+  'Save as new'                 => 'Gem som ny',
+  'Screen'                      => 'Skærm',
+  'Select from one of the items below' => 'Vælg fra en af tingene nedenfor, og tryk "Fortsæt"',
+  'Select from one of the names below' => 'Vælg en af navnene nedenfor',
+  'Select from one of the projects below' => 'Vælg et af projekterne nedenfor',
+  'Select postscript or PDF!'   => 'Vælg postscript eller PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Tjeneste',
+  'Ship'                        => 'Send',
+  'Ship to'                     => 'Send til',
+  'Ship via'                    => 'Send via',
+  'Subject'                     => 'Emne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Afgift/Moms',
+  'Tax Included'                => 'Inkl. afgifter og moms',
+  'Terms: Net'                  => 'Netto',
+  'To'                          => 'til',
+  'Total'                       => 'I alt',
+  'Unit'                        => 'Enhed',
+  'Update'                      => 'Opdatér',
+  'Vendor'                      => 'Leverandør',
+  'Vendor missing!'             => 'Leverandør mangler!',
+  'Vendor not on file!'         => 'Leverandør ikke i databasen!',
+  'What type of item is this?'  => 'Hvilken type ting er dette?',
+  'Yes'                         => 'Ja',
+  'days'                        => 'dage',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendt via e-post til',
+  'sent to printer'             => 'sendt til printer',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'tilføj'                      => 'add',
+  'fortsæt'                     => 'continue',
+  'fjern'                       => 'delete',
+  'e_post'                      => 'e_mail',
+  'faktura'                     => 'invoice',
+  'udskriv'                     => 'print',
+  'gem'                         => 'save',
+  'gem_som_ny'                  => 'save_as_new',
+  'send_til'                    => 'ship_to',
+  'opdatér'                     => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/pe b/sql-ledger/locale/dk/pe
new file mode 100644 (file)
index 0000000..66c62ee
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Tilføj',
+  'Add Project'                 => 'Nyt projekt',
+  'All'                         => 'Alt',
+  'Continue'                    => 'Fortsæt',
+  'Delete'                      => 'Fjern',
+  'Description'                 => 'Beskrivelse',
+  'Edit Project'                => 'Redigér præferencer for',
+  'Number'                      => 'Nummer',
+  'Orphaned'                    => 'Fritstående',
+  'Project'                     => 'Projekt',
+  'Project Number missing!'     => 'Projektnummer mangler!',
+  'Project deleted!'            => 'Projekt slettet!',
+  'Project saved!'              => 'Projekt gemt!',
+  'Projects'                    => 'Projekter',
+  'Save'                        => 'Gem',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'tilføj'                      => 'add',
+  'fortsæt'                     => 'continue',
+  'fjern'                       => 'delete',
+  'gem'                         => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/rc b/sql-ledger/locale/dk/rc
new file mode 100644 (file)
index 0000000..ea645b9
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Balance'                     => 'Balance',
+  'Cleared Balance'             => 'Udjævnede balance',
+  'Continue'                    => 'Fortsæt',
+  'Date'                        => 'Dato',
+  'Deposit'                     => 'Depositum',
+  'Description'                 => 'Beskrivelse',
+  'Difference'                  => 'Difference',
+  'Done'                        => 'Færdig',
+  'Exchangerate Difference'     => 'Difference for vekselkurs',
+  'From'                        => 'Fra',
+  'Out of balance!'             => 'Ikke i balance!',
+  'Payment'                     => 'Betaling',
+  'Reconciliation'              => 'Afstemning',
+  'Select all'                  => 'Vælg alt',
+  'Source'                      => 'Bilag',
+  'Statement Balance'           => 'Balanceopgørelse',
+  'To'                          => 'til',
+  'Update'                      => 'Opdatér',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'fortsæt'                     => 'continue',
+  'færdig'                      => 'done',
+  'vælg_alt'                    => 'select_all',
+  'opdatér'                     => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/dk/rp b/sql-ledger/locale/dk/rp
new file mode 100644 (file)
index 0000000..607d80c
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'Aldersfordeling',
+  'AR Aging'                    => 'Aldersfordeling',
+  'Account'                     => 'Konto',
+  'Accounts'                    => 'Konti',
+  'Amount'                      => 'Beløb',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Attachment'                  => 'Bilag',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Balance Sheet'               => 'Status',
+  'Bcc'                         => 'Blind kopi',
+  'Cash based'                  => 'Kontantbaseret',
+  'Cc'                          => 'Kopi',
+  'Compare to'                  => 'Sammenlign med',
+  'Continue'                    => 'Fortsæt',
+  'Copies'                      => 'Kopier',
+  'Credit'                      => 'Kredit',
+  'Current'                     => 'Current',
+  'Customer'                    => 'Kunde',
+  'Date'                        => 'Dato',
+  'Debit'                       => 'Debet',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Decimalplaces'               => 'Decimalpladser',
+  'Description'                 => 'Beskrivelse',
+  'Due'                         => 'Forfald',
+  'E-mail'                      => 'E-post',
+  'E-mail Statement to'         => 'Send opgørelse til',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Overskrift',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Indlejret',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Income Statement'            => 'Driftsregnskab',
+  'Invoice'                     => 'Faktura',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'marts',
+  'May'                         => 'maj',
+  'May '                        => 'maj ',
+  'Message'                     => 'Besked',
+  'N/A'                         => 'I/T',
+  'Nothing selected!'           => 'Ingenting valgt!',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Betalinger',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Udskriv',
+  'Printer'                     => 'Printer',
+  'Receipts'                    => 'Kvitteringer',
+  'Report for'                  => 'Rapport for',
+  'Retained Earnings'           => 'Realiseret overskud',
+  'Screen'                      => 'Skærm',
+  'Select all'                  => 'Vælg alt',
+  'Select postscript or PDF!'   => 'Vælg postscript eller PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Source'                      => 'Bilag',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Opgørelse',
+  'Statement sent to'           => 'Opgørelse sendt til',
+  'Statements sent to printer!' => 'Opgørelser sendt til printer',
+  'Subject'                     => 'Emne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Afgift/Moms',
+  'Tax collected'               => 'Skat opkrævet',
+  'Tax paid'                    => 'Skat betalt',
+  'To'                          => 'til',
+  'Total'                       => 'I alt',
+  'Trial Balance'               => 'Foreløbig status',
+  'Vendor'                      => 'Leverandør',
+  'as at'                       => 'som ved',
+  'collected on sales'          => 'indsamlet ved salg',
+  'for Period'                  => 'for perioden',
+  'paid on purchases'           => 'betalt ved indkøb',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'fortsæt'                     => 'continue',
+  'e_post'                      => 'e_mail',
+  'udskriv'                     => 'print',
+  'vælg_alt'                    => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/COPYING b/sql-ledger/locale/ee/COPYING
new file mode 100644 (file)
index 0000000..fe5ef7d
--- /dev/null
@@ -0,0 +1,25 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Estonian texts:
+#
+#  Author: Martin Lillepuu <martin@lillepuu.com>
+#          Lauri Jesmin <jesmin@ut.ee>
+#          Tanel Kurvits <rauge@hot.ee>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/ee/LANGUAGE b/sql-ledger/locale/ee/LANGUAGE
new file mode 100644 (file)
index 0000000..5d88c2d
--- /dev/null
@@ -0,0 +1 @@
+Estonian
diff --git a/sql-ledger/locale/ee/admin b/sql-ledger/locale/ee/admin
new file mode 100644 (file)
index 0000000..00c683e
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Ligipääsukontroll',
+  'Accounting'                  => 'Raamatupidamine',
+  'Add User'                    => 'Lisa kasutaja',
+  'Address'                     => 'Aadress',
+  'Administration'              => 'Administreerimine',
+  'Administrator'               => 'Administraator',
+  'All Datasets up to date!'    => 'Kõik andmebaasid on uuendatud',
+  'Change Admin Password'       => 'Muuda admini parool',
+  'Change Password'             => 'Muuda parool',
+  'Character Set'               => 'Kooditabel',
+  'Click on login name to edit!' => 'Redigeerimiseks kliki kasutajanimel',
+  'Company'                     => 'Ettevõte',
+  'Connect to'                  => 'Ühenda',
+  'Continue'                    => 'Edasi',
+  'Create Chart of Accounts'    => 'Uus kontoplaan',
+  'Create Dataset'              => 'Uus andmebaas',
+  'DBI not installed!'          => 'DBI on installeerimata',
+  'Database'                    => 'Andmebaas',
+  'Database Administration'     => 'Andmebaasi administreerimine',
+  'Database Driver not checked!' => 'Andmebaasi draiver valimata!',
+  'Database User missing!'      => 'Andmebaasi kasutaja puudub',
+  'Dataset'                     => 'Andmebaas',
+  'Dataset missing!'            => 'Andmebaas puudub!',
+  'Dataset updated!'            => 'Andmebaas uuendatud!',
+  'Date Format'                 => 'Kuupäeva formaat',
+  'Delete'                      => 'Kustuta',
+  'Delete Dataset'              => 'Kustuta andmebaas',
+  'Directory'                   => 'Kataloog',
+  'Driver'                      => 'Draiver',
+  'Dropdown Limit'              => 'Rippmenüü piirang',
+  'E-mail'                      => 'E-mail',
+  'Edit User'                   => 'Kasutajaandmete muutmine',
+  'Existing Datasets'           => 'Olemasolevad andmebaasid',
+  'Fax'                         => 'Faks',
+  'Host'                        => 'Server',
+  'Hostname missing!'           => 'Serveri nimi puudub!',
+  'Incorrect Password!'         => 'Vale parool!',
+  'Language'                    => 'Keel',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Jäta serveri ja pordi väljad tühjaks kui sa ei soovi kaugühendust luua',
+  'Login'                       => 'Login',
+  'Multibyte Encoding'          => 'Mitmebaidine kodeering',
+  'Name'                        => 'Nimi',
+  'New Templates'               => 'Uued dokumendipõhjad',
+  'No Database Drivers available!' => 'Ühtegi andmebaasidraiverit ei leitud!',
+  'No Dataset selected!'        => 'Andmebaas valimata!',
+  'Nothing to delete!'          => 'Midagi ei ole kustutada',
+  'Number Format'               => 'Numbri formaat',
+  'Oracle Database Administration' => 'Oracle andmebaasi administreerimine',
+  'Password'                    => 'Parool',
+  'Password changed!'           => 'Parool muudetud',
+  'Pg Database Administration'  => 'Pg andmebaasi administreerimine',
+  'Phone'                       => 'Telefon',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port puudub',
+  'Printer'                     => 'Printer',
+  'Save'                        => 'Salvesta',
+  'Select a Dataset to delete and press "Continue"' => 'Vali andmebaas ja vajuta "Jätka"',
+  'Setup Templates'             => 'Dokumendipõhjade seadistamine',
+  'Ship via'                    => 'Tarneviis',
+  'Signature'                   => 'Signatuur',
+  'Stylesheet'                  => 'Laaditabel',
+  'Templates'                   => 'Dokumendipõhjad',
+  'The following Datasets are not in use and can be deleted' => 'Järgnevad andmebaasid ei ole kasutusel ning võib kustutada',
+  'The following Datasets need to be updated' => 'Järgmised andmebaasid vajavad uuendamist',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Olemasolevate allikate eelkontroll. Praeguses staadiumis ei toimu andmete lisamist ega kustutamist.',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Kasutaja gruppi lisamiseks redigeeri nime, muuda kasutajanimi ja salvesta. Luuakse samade parameetritega uus kasutaja',
+  'Update Dataset'              => 'Uuenda andmebaas',
+  'Use Templates'               => 'Kasuta dokumendipõhja',
+  'User'                        => 'Kasutaja',
+  'User deleted!'               => 'Kasutaja kustutatud!',
+  'User saved!'                 => 'Kasutaja salvestatud!',
+  'Version'                     => 'Versioon',
+  'You must enter a host and port for local and remote connections!' => 'Ühenduse loomiseks palun sisesta serveri nimi ja port',
+  'does not exist'              => 'ei eksisteeri',
+  'is already a member!'        => 'on juba kasutaja!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'lukustatud!',
+  'successfully created!'       => 'loodud!',
+  'successfully deleted!'       => 'kustutatud!',
+  'website'                     => 'kodulehekülg',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'lisa_kasutaja'               => 'add_user',
+  'muuda_admini_parool'         => 'change_admin_password',
+  'muuda_parool'                => 'change_password',
+  'edasi'                       => 'continue',
+  'uus_andmebaas'               => 'create_dataset',
+  'kustuta'                     => 'delete',
+  'kustuta_andmebaas'           => 'delete_dataset',
+  'login'                       => 'login',
+  'oracle_andmebaasi_administreerimine' => 'oracle_database_administration',
+  'pg_andmebaasi_administreerimine' => 'pg_database_administration',
+  'salvesta'                    => 'save',
+  'uuenda_andmebaas'            => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/all b/sql-ledger/locale/ee/all
new file mode 100644 (file)
index 0000000..122f34a
--- /dev/null
@@ -0,0 +1,497 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Kohustused',
+  'AP Aging'                    => 'Võlad',
+  'AP Transaction'              => 'Kohustuste kanne',
+  'AP Transactions'             => 'Kohustuste kanded',
+  'AR'                          => 'Nõuded',
+  'AR Aging'                    => 'Võlglased',
+  'AR Transaction'              => 'Nõuete kanne',
+  'AR Transactions'             => 'Nõuete kanded',
+  'About'                       => 'Programmi Info',
+  'Access Control'              => 'Ligipääsukontroll',
+  'Account'                     => 'Konto',
+  'Account Number'              => 'Konto number',
+  'Account Number missing!'     => 'Konto number puudub',
+  'Account Type'                => 'Konto tüüp',
+  'Account Type missing!'       => 'Konto tüüp puudub!',
+  'Account deleted!'            => 'Konto kustutatud!',
+  'Account saved!'              => 'Konto salvestatud',
+  'Accounting'                  => 'Raamatupidamine',
+  'Accounting Menu'             => 'Raamatupidamise Menüü',
+  'Accounts'                    => 'Kontod',
+  'Active'                      => 'Aktiva',
+  'Add'                         => 'Lisa',
+  'Add Account'                 => 'Lisa konto',
+  'Add Accounts Payables Transaction' => 'Lisa kohustuste kanne',
+  'Add Accounts Receivables Transaction' => 'Lisa nõuete kanne',
+  'Add Assembly'                => 'Lisa komplekt',
+  'Add Customer'                => 'Lisa klient',
+  'Add GIFI'                    => 'Lisa GIFI',
+  'Add General Ledger Transaction' => 'Lisa pearaamatu kanne',
+  'Add Part'                    => 'Lisa toode',
+  'Add Project'                 => 'Lisa Projekt',
+  'Add Purchase Order'          => 'Lisa ostutellimus',
+  'Add Sales Invoice'           => 'Lisa Müügiarve',
+  'Add Sales Order'             => 'Lisa müügitellimus',
+  'Add Service'                 => 'Lisa teenus',
+  'Add Transaction'             => 'Lisa kanne',
+  'Add User'                    => 'Lisa kasutaja',
+  'Add Vendor'                  => 'Lisa hankija',
+  'Add Vendor Invoice'          => '',
+  'Address'                     => 'Aadress',
+  'Administration'              => 'Administreerimine',
+  'Administrator'               => 'Administraator',
+  'All'                         => 'Kõik',
+  'All Datasets up to date!'    => 'Kõik andmebaasid on uuendatud',
+  'Amount'                      => 'Summa',
+  'Amount Due'                  => 'Tasumata',
+  'Amount does not equal applied!' => 'Amount does not equal applied!',
+  'Amount missing!'             => 'Summa puudub!',
+  'Applied'                     => 'Makstud',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprill',
+  'Are you sure you want to delete Invoice Number' => 'Kas oled kindel, et soovid kustutada arve',
+  'Are you sure you want to delete Order Number' => 'Kas oled kindel, et soovid kustutada tellimuse',
+  'Are you sure you want to delete Transaction' => 'Kas oled kindel, et soovid kustutada kande',
+  'Assemblies'                  => 'Komplektid',
+  'Assemblies restocked!'       => 'Komplektid lattu tagastatud!',
+  'Assembly Number missing!'    => 'Komplekti number puudub!',
+  'Asset'                       => 'Vara',
+  'Attachment'                  => 'Kaasatud fail',
+  'Audit Control'               => 'Audit',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'BOM'                         => 'Materjalide nimekiri',
+  'Backup'                      => 'Varukoopia',
+  'Backup sent to'              => 'Varukoopia saadetakse',
+  'Balance'                     => 'Bilanss',
+  'Balance Sheet'               => 'Bilansitabel',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Kast',
+  'Books are open'              => 'Kanded on avatud',
+  'Bought'                      => 'Ostetud',
+  'Business Number'             => 'Ettevõtte kood',
+  'C'                           => 'C',
+  'COGS'                        => 'COGS',
+  'Cannot delete account!'      => 'Kontot ei saa kustutada!',
+  'Cannot delete customer!'     => 'Kienti ei saa kustutada!',
+  'Cannot delete default account!' => 'Vaikimisi kontot ei saa kustutada!',
+  'Cannot delete invoice!'      => 'Arvet ei saa kustutada',
+  'Cannot delete item already invoiced!' => 'Esitatud arvega toodet ei saa kustutada!',
+  'Cannot delete item on order!' => 'Tellimusega seotud artiklit ei saa kustutada!',
+  'Cannot delete item which is part of an assembly!' => 'Komplekti kuuluvat toodet ei saa kustutada!',
+  'Cannot delete item!'         => 'Toodet ei saa kustutada!',
+  'Cannot delete order!'        => 'Tellimust ei saa kustutada!',
+  'Cannot delete transaction!'  => 'Kannet ei saa kustutada!',
+  'Cannot delete vendor!'       => 'Tarnijat ei saa kustutada!',
+  'Cannot have a value in both Debit and Credit!' => 'Deebet ja Kreedit väljad ei tohi olla samaaegselt täidetud!',
+  'Cannot post a transaction without a value!' => 'Tühja väärtusega kannet pole võimalik salvestada!',
+  'Cannot post invoice for a closed period!' => 'Arvet ei saa salvestada suletud perioodile!',
+  'Cannot post invoice!'        => 'Arvet ei saa saata!',
+  'Cannot post payment for a closed period!' => 'Makset ei saa salvestada suletud perioodile',
+  'Cannot post payment!'        => 'Makset ei saa salvestada!',
+  'Cannot post transaction for a closed period!' => 'Kannet ei saa salvestada suletud perioodile',
+  'Cannot post transaction!'    => 'Kannet ei saa salvestada!',
+  'Cannot process payment for a closed period!' => 'Suletud perioodi makset ei saa töödelda!',
+  'Cannot save account!'        => 'Kontot ei saa salvestada',
+  'Cannot save order!'          => 'Arvet ei saa salvestada',
+  'Cannot save preferences!'    => 'Maaranguid ei saa salvestada',
+  'Cannot stock assemblies!'    => 'Komplekte ei saa lattu võtta',
+  'Cash'                        => 'Kassa',
+  'Cash based'                  => 'Kassapõhine',
+  'Cc'                          => 'Cc',
+  'Change Admin Password'       => 'Muuda admini parool',
+  'Change Password'             => 'Muuda parool',
+  'Character Set'               => 'Kooditabel',
+  'Chart of Accounts'           => 'Kontoplaan',
+  'Check'                       => 'T?ekk',
+  'Check printed!'              => 'T?ekk on türkitud',
+  'Check printing failed!'      => 'T?eki trükkimine ebaõnnestus',
+  'Cleared Balance'             => 'Puhastatud bilanss',
+  'Click on login name to edit!' => 'Redigeerimiseks kliki kasutajanimel',
+  'Close Books up to'           => 'Sulge kanded kuni',
+  'Closed'                      => 'Suletud',
+  'Company'                     => 'Ettevõte',
+  'Compare to'                  => 'Võrdlus perioodiga',
+  'Confirm!'                    => 'Kinnita!',
+  'Connect to'                  => 'Ühenda',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Edasi',
+  'Copies'                      => 'koopiat',
+  'Copy to COA'                 => 'Kopeeri kontoplaani',
+  'Create Chart of Accounts'    => 'Uus kontoplaan',
+  'Create Dataset'              => 'Uus andmebaas',
+  'Credit'                      => 'Kreedit',
+  'Credit Limit'                => 'Krediidilimiit',
+  'Curr'                        => 'Val.',
+  'Currency'                    => 'Valuuta',
+  'Current'                     => 'Praegune',
+  'Customer'                    => 'Klient',
+  'Customer deleted!'           => 'Klient on kustutatud!',
+  'Customer missing!'           => 'Klienti pole määratud!',
+  'Customer not on file!'       => 'Klienti pole failis!',
+  'Customer saved!'             => 'Klient salvestatud',
+  'Customers'                   => 'Kliendid',
+  'DBI not installed!'          => 'DBI on installeerimata',
+  'Database'                    => 'Andmebaas',
+  'Database Administration'     => 'Andmebaasi administreerimine',
+  'Database Driver not checked!' => 'Andmebaasi draiver valimata!',
+  'Database Host'               => 'Andmebaasiserver',
+  'Database User missing!'      => 'Andmebaasi kasutaja puudub',
+  'Dataset'                     => 'Andmebaas',
+  'Dataset missing!'            => 'Andmebaas puudub!',
+  'Dataset updated!'            => 'Andmebaas uuendatud!',
+  'Date'                        => 'Kuupäev',
+  'Date Format'                 => 'Kuupäeva formaat',
+  'Date Paid'                   => 'Maksekuupäev',
+  'Date missing!'               => 'Kuupäev puudub!',
+  'Debit'                       => 'Deebet',
+  'Debit and credit out of balance!' => 'Deebet ja Kreedit tasakaalust väljas!',
+  'Dec'                         => 'Dets',
+  'December'                    => 'Detsember',
+  'Decimalplaces'               => 'Komakohti',
+  'Delete'                      => 'Kustuta',
+  'Delete Account'              => 'Kustuta konto',
+  'Delete Dataset'              => 'Kustuta andmebaas',
+  'Delivery Date'               => 'Tarne kuupäev',
+  'Department'                  => 'Osakond',
+  'Deposit'                     => 'Tarnimata',
+  'Description'                 => 'Selgitus',
+  'Difference'                  => 'Vahe',
+  'Directory'                   => 'Kataloog',
+  'Discount'                    => 'Allahindlus',
+  'Done'                        => 'Teostatud',
+  'Drawing'                     => 'Pildid',
+  'Driver'                      => 'Draiver',
+  'Dropdown Limit'              => 'Rippmenüü piirang',
+  'Due'                         => 'Tasuda',
+  'Due Date'                    => 'Maksetähtaeg',
+  'Due Date missing!'           => 'Maksetähtaeg puudub',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'E-mail teatis',
+  'E-mail address missing!'     => 'E-maili aadress puudub',
+  'Edit'                        => 'Muudatused',
+  'Edit Account'                => 'Konto muudatused',
+  'Edit Accounts Payables Transaction' => 'Muuda nõuete kannet',
+  'Edit Accounts Receivables Transaction' => 'Muuda kohustuste kannet',
+  'Edit Assembly'               => 'Muuda Komplekti',
+  'Edit Customer'               => 'Muuda Kliendi andmeid',
+  'Edit GIFI'                   => 'Muuda GIFI',
+  'Edit General Ledger Transaction' => 'Pearaamatu kande redigeerimine',
+  'Edit Part'                   => 'Toote redigeerimine',
+  'Edit Preferences for'        => 'Määrangute muutmine: ',
+  'Edit Project'                => 'Muuda Projekti',
+  'Edit Purchase Order'         => 'Ostutellimuse muutmine',
+  'Edit Sales Invoice'          => 'Müügiarve muutmine',
+  'Edit Sales Order'            => 'Müügitellimuse muutmine',
+  'Edit Service'                => 'Teenuse muutmine',
+  'Edit Template'               => 'Dokumendipõhja muutmine',
+  'Edit User'                   => 'Kasutajaandmete muutmine',
+  'Edit Vendor'                 => 'Muuda Tarnija andmeid',
+  'Edit Vendor Invoice'         => '',
+  'Employee'                    => 'Töötaja',
+  'Enforce transaction reversal for all dates' => 'Muuda kannete pööramine kõikide kuupäevade ulatuses kohustuslikuks',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Sisesta kohalikud- ja välisvaluutad (kuni 3 tähemärki, koolonitega eraltatud, nt. CAD:USD:EUR)',
+  'Equity'                      => 'Omakapital',
+  'Exch'                        => 'Kurss',
+  'Exchangerate'                => 'Valuutakurss',
+  'Exchangerate Difference'     => 'Valuutakursi muutus',
+  'Exchangerate for payment missing!' => 'Maksel ei ole valuutakurssi!',
+  'Exchangerate missing!'       => 'Valuutakurssi ei ole',
+  'Existing Datasets'           => 'Olemasolevad andmebaasid',
+  'Expense'                     => 'Kulu',
+  'Expense Account'             => 'Kulukonto',
+  'Expense/Asset'               => 'Kulu/Vara',
+  'Extended'                    => 'Summa',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'Veebr',
+  'February'                    => 'Veebruar',
+  'Foreign Exchange Gain'       => 'Valuutakursside vahe kasum',
+  'Foreign Exchange Loss'       => 'Valuutakursside vahe kahjum',
+  'From'                        => 'Alates',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI kustutatud',
+  'GIFI missing!'               => 'GIFI puudub',
+  'GIFI saved!'                 => 'GIFI salvestatud',
+  'GL Transaction'              => 'Pearaamatu kanne',
+  'General Ledger'              => 'Pearaamat',
+  'Goods & Services'            => 'Tooted ja teenused',
+  'Group'                       => '',
+  'Group Items'                 => '',
+  'HTML Templates'              => 'HTML dokumendipõhjad',
+  'Heading'                     => 'Päis',
+  'Host'                        => 'Server',
+  'Hostname missing!'           => 'Serveri nimi puudub!',
+  'ID'                          => 'ID',
+  'Image'                       => 'Pilt',
+  'In-line'                     => 'Dokumendisisene',
+  'Include in Report'           => 'Kaasa aruandesse',
+  'Include in drop-down menus'  => 'Kaasa valikmenüüdes',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Kaasa antud konto klient/tarnija vormides, et märkida klient/tarnija maksustatavaks',
+  'Income'                      => 'Tulu',
+  'Income Account'              => 'Tulukonto',
+  'Income Statement'            => 'Kasumiaruanne',
+  'Incorrect Dataset version!'  => 'Vale andmebaasi versioon',
+  'Incorrect Password!'         => 'Vale parool!',
+  'Individual Items'            => 'Komponendid',
+  'Inventory'                   => 'Ladu',
+  'Inventory Account'           => 'Laokonto',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Enne komplekti aegunuks märkimist peab laoseis null olema!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Enne toote aegunuks märkimist peab laoseis null olema!',
+  'Inventory quantity must be zero!' => 'Laoseis peab null olema!',
+  'Invoice'                     => 'Arve',
+  'Invoice Date'                => 'Arve kuupäev',
+  'Invoice Date missing!'       => 'Arve kuupäev puudub!',
+  'Invoice Number'              => 'Arve number',
+  'Invoice Number missing!'     => 'Arve number puudub!',
+  'Invoice deleted!'            => 'Arve kustutatud!',
+  'Invoice posted!'             => 'Arve salvestatud!',
+  'Invoices'                    => 'Arved',
+  'Is this a summary account to record' => 'Kirje summaarne konto',
+  'Item deleted!'               => 'Toode kustutatud!',
+  'Item not on file!'           => 'Toode puudub andmebaasist!',
+  'Jan'                         => 'Jaan',
+  'January'                     => 'Jaanuar',
+  'Jul'                         => 'Juul',
+  'July'                        => 'Juuli',
+  'Jun'                         => 'Juun',
+  'June'                        => 'Juuni',
+  'LaTeX Templates'             => 'LaTeX dokumendipõhjad',
+  'Language'                    => 'Keel',
+  'Last Cost'                   => 'Viimane ostuhind',
+  'Last Invoice Number'         => 'Viimane arve number',
+  'Last Numbers & Default Accounts' => 'Viimased numbrid ja vaikimisi kontod',
+  'Last Purchase Order Number'  => 'Viimane ostutellimuse number',
+  'Last Sales Order Number'     => 'Viimane müügitellimuse number',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Jäta serveri ja pordi väljad tühjaks kui sa ei soovi kaugühendust luua',
+  'Liability'                   => 'Kohustus',
+  'Licensed to'                 => 'Kasutaja andmed:',
+  'Line Total'                  => 'Rea summa',
+  'Link'                        => 'Seosed',
+  'Link Accounts'               => 'Seosta kontod',
+  'List Accounts'               => 'Kontode nimekiri',
+  'List GIFI'                   => 'GIFI nimekiri',
+  'List Price'                  => 'Hinnakirja hind',
+  'List Transactions'           => 'Kannete sirvimine',
+  'Login'                       => 'Login',
+  'Logout'                      => 'Logi välja',
+  'Make'                        => 'Tootja',
+  'Mar'                         => 'Mär',
+  'March'                       => 'Märts',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Teade',
+  'Microfiche'                  => 'Mikrofilm',
+  'Model'                       => 'Mudel',
+  'Multibyte Encoding'          => 'Mitmebaidine kodeering',
+  'N/A'                         => 'Puudub',
+  'Name'                        => 'Nimi',
+  'Name missing!'               => 'Nimi puudub!',
+  'New Templates'               => 'Uued dokumendipõhjad',
+  'No'                          => 'Ei',
+  'No Database Drivers available!' => 'Ühtegi andmebaasidraiverit ei leitud!',
+  'No Dataset selected!'        => 'Andmebaas valimata!',
+  'No email address for'        => 'E-maili aadress puudub',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Märkused',
+  'Nothing applied!'            => 'Midagi ei muudetud',
+  'Nothing selected!'           => 'Midagi ei ole valitud',
+  'Nothing to delete!'          => 'Midagi ei ole kustutada',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Kood',
+  'Number Format'               => 'Numbri formaat',
+  'Number missing in Row'       => 'Antud real puudub kood',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Aegunud',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktoober',
+  'On Hand'                     => 'Laos',
+  'On Order'                    => 'Tellimisel',
+  'Open'                        => 'Avatud',
+  'Oracle Database Administration' => 'Oracle andmebaasi administreerimine',
+  'Order'                       => 'Tellimus',
+  'Order Date'                  => 'Tellimuse kuupäev',
+  'Order Date missing!'         => 'Tellimuse kuupäev puudub',
+  'Order Entry'                 => 'Tellimuse sisestamine',
+  'Order Number'                => 'Tellimuse number',
+  'Order Number missing!'       => 'Tellimuse number puudub',
+  'Order deleted!'              => 'Tellimus kustutatud',
+  'Order saved!'                => 'Tellimus salvestatud',
+  'Ordered'                     => 'Tellitud',
+  'Orphaned'                    => 'Seosteta',
+  'Out of balance!'             => 'Bilanss ei klapi!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Saateleht',
+  'Packing List Date missing!'  => 'Saatelehe kuupäev puudub',
+  'Packing List Number missing!' => 'Saatelehe number puudub',
+  'Paid'                        => 'Makstud',
+  'Paid in full'                => 'Täielikult tasutud',
+  'Part'                        => 'Toode',
+  'Part Number missing!'        => 'Toote kood puudub',
+  'Parts'                       => 'Tooted',
+  'Parts Inventory'             => 'Tooted',
+  'Password'                    => 'Parool',
+  'Password changed!'           => 'Parool muudetud',
+  'Payables'                    => 'Kohustused',
+  'Payment'                     => 'Maksed',
+  'Payment date missing!'       => 'Maksekuupäev puudub',
+  'Payment posted!'             => 'Makse salvestatud',
+  'Payments'                    => 'Maksed',
+  'Pg Database Administration'  => 'Pg andmebaasi administreerimine',
+  'Phone'                       => 'Telefon',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port puudub',
+  'Post'                        => 'Salvesta',
+  'Post as new'                 => 'Salvesta uuena',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Määrangud',
+  'Preferences saved!'          => 'Määrangud salvestatud',
+  'Price'                       => 'Hind',
+  'Print'                       => 'Trüki',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Projekt',
+  'Project Number'              => 'Projekti number',
+  'Project Number missing!'     => 'Projekti number puudub',
+  'Project deleted!'            => 'Projekt kustutatud',
+  'Project not on file!'        => 'Projekti pole failis',
+  'Project saved!'              => 'Projekt salvestatud',
+  'Projects'                    => 'Projektid',
+  'Purchase Order'              => 'Ostutellimus',
+  'Purchase Orders'             => 'Ostutellimused',
+  'Qty'                         => 'Kogus',
+  'ROP'                         => 'TM',
+  'Rate'                        => 'Määr',
+  'Recd'                        => 'Saabunud',
+  'Receipt'                     => 'Laekumised',
+  'Receipt printed!'            => 'Tshekk trükitud',
+  'Receipt printing failed!'    => 'Tsheki trükkkimine ebaõnnestus',
+  'Receipts'                    => 'Laekumised',
+  'Receivables'                 => 'Nõuded',
+  'Reconciliation'              => 'Tasaarveldused',
+  'Record in'                   => 'Sihtkonto',
+  'Reference'                   => 'Viide',
+  'Reference missing!'          => 'Viide puudub!',
+  'Remaining'                   => 'Kasutamata',
+  'Report for'                  => 'Aruanne',
+  'Reports'                     => 'Aruanded',
+  'Required by'                 => 'Tarneaeg',
+  'Retained Earnings'           => 'Jaotamata kasum',
+  'Sales'                       => 'Müük',
+  'Sales Invoice'               => 'Müügiarve',
+  'Sales Order'                 => 'Müügitellimus',
+  'Sales Orders'                => 'Müügitellimused',
+  'Salesperson'                 => '',
+  'Save'                        => 'Salvesta',
+  'Save as new'                 => 'Salvesta uuena',
+  'Save to File'                => 'Salvesta faili',
+  'Screen'                      => 'Ekraan',
+  'Select a Dataset to delete and press "Continue"' => 'Vali andmebaas ja vajuta "Jätka"',
+  'Select all'                  => 'Vali kõik',
+  'Select from one of the items below' => 'Vali üks alltoodud toodetest',
+  'Select from one of the names below' => 'Vali üks alltoodud nimedest',
+  'Select from one of the projects below' => 'Vali üks alltoodud projektidest',
+  'Select postscript or PDF!'   => 'Vali kas postscript või PDF',
+  'Sell Price'                  => 'Müügihind',
+  'Send by E-Mail'              => 'Saada e-postiga',
+  'Sep'                         => 'Sept',
+  'September'                   => 'September',
+  'Service'                     => 'Teenus',
+  'Service Items'               => 'Teenused',
+  'Service Number missing!'     => 'teenuse kood puudub!',
+  'Services'                    => 'Teenused',
+  'Setup Templates'             => 'Dokumendipõhjade seadistamine',
+  'Ship'                        => 'Tarnimine',
+  'Ship to'                     => 'Tarneaadress',
+  'Ship via'                    => 'Tarneviis',
+  'Short'                       => 'Lühike',
+  'Signature'                   => 'Signatuur',
+  'Sold'                        => 'Müüdud',
+  'Source'                      => 'Allikas',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Aruanne',
+  'Statement Balance'           => 'Bilansiaruanne',
+  'Statement sent to'           => 'Saata aruanne aadressil',
+  'Statements sent to printer!' => 'Saata aruanne printerile',
+  'Stock Assembly'              => 'Komplekti lattu võtmine',
+  'Stylesheet'                  => 'Laaditabel',
+  'Subject'                     => 'Pealkiri',
+  'Subtotal'                    => 'Vahesumma',
+  'System'                      => 'Süsteem',
+  'Tax'                         => 'Maks',
+  'Tax Accounts'                => 'Maksukontod',
+  'Tax Included'                => 'Koos maksuga',
+  'Tax collected'               => 'Kogutud maksud',
+  'Tax paid'                    => 'Makstud makse',
+  'Taxable'                     => 'Maksustatav',
+  'Template saved!'             => 'Dokumendipõhjad salvestatud!',
+  'Templates'                   => 'Dokumendipõhjad',
+  'Terms: Net'                  => 'Maksetingimus',
+  'The following Datasets are not in use and can be deleted' => 'Järgnevad andmebaasid ei ole kasutusel ning võib kustutada',
+  'The following Datasets need to be updated' => 'Järgmised andmebaasid vajavad uuendamist',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Olemasolevate allikate eelkontroll. Praeguses staadiumis ei toimu andmete lisamist ega kustutamist.',
+  'To'                          => 'Kuhu',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Kasutaja gruppi lisamiseks redigeeri nime, muuda kasutajanimi ja salvesta. Luuakse samade parameetritega uus kasutaja',
+  'Top Level'                   => 'Ülemine tase',
+  'Total'                       => 'Kokku',
+  'Transaction Date missing!'   => 'Kande kuupäev puudub!',
+  'Transaction deleted!'        => 'Kanne kustutatud!',
+  'Transaction posted!'         => 'Kanne tud!',
+  'Transaction reversal enforced for all dates' => 'Kannete pööramine on kohustuslik kõikide kuupäevade ulatuses',
+  'Transaction reversal enforced up to' => 'Kannete pööramine on kohustuslik kuni',
+  'Transactions'                => 'Kanded',
+  'Transactions exist, cannot delete customer!' => 'Kanded aktiivsed, klienti ei saa kustutada!',
+  'Transactions exist, cannot delete vendor!' => 'Kanded aktiivsed, hankijat ei saa kustutada!',
+  'Transactions exist; cannot delete account!' => 'Kanded aktiivsed; kontot ei saa kustutada!',
+  'Trial Balance'               => 'Proovibilanss',
+  'Unit'                        => 'Ühik',
+  'Unit of measure'             => 'Mõõtühik',
+  'Update'                      => 'Uuenda',
+  'Update Dataset'              => 'Uuenda andmebaas',
+  'Updated'                     => 'Uuendatud',
+  'Use Templates'               => 'Kasuta dokumendipõhja',
+  'User'                        => 'Kasutaja',
+  'User deleted!'               => 'Kasutaja kustutatud!',
+  'User saved!'                 => 'Kasutaja salvestatud!',
+  'Vendor'                      => 'Hankija',
+  'Vendor Invoice'              => '',
+  'Vendor deleted!'             => 'Hankija kustutatud!',
+  'Vendor missing!'             => 'Hankija puudub!',
+  'Vendor not on file!'         => 'Hankijat pole failis!',
+  'Vendor saved!'               => 'Hankija salvestatud!',
+  'Vendors'                     => 'Hankijad',
+  'Version'                     => 'Versioon',
+  'Weight'                      => 'Kaal',
+  'Weight Unit'                 => 'Kaaluühik',
+  'What type of item is this?'  => 'Mis tüüpi tootega on tegemist?',
+  'Year End'                    => 'Aasta lõpp',
+  'Yes'                         => 'Jah',
+  'You are logged out!'         => 'Oled välja loginud!',
+  'You did not enter a name!'   => 'Nimi sisestamata!',
+  'You must enter a host and port for local and remote connections!' => 'Ühenduse loomiseks palun sisesta serveri nimi ja port',
+  'as at'                       => 'Seisuga',
+  'collected on sales'          => 'kogutud müügilt',
+  'days'                        => 'päeva',
+  'does not exist'              => 'ei eksisteeri',
+  'ea'                          => 'tk',
+  'emailed to'                  => 'salvestatud aadressile',
+  'for Period'                  => 'Periood',
+  'hr'                          => 't',
+  'is already a member!'        => 'on juba kasutaja!',
+  'is not a member!'            => 'ei ole kasutaja!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'lukustatud!',
+  'paid on purchases'           => 'makstud ostudelt',
+  'sent to printer'             => 'printerile saadetud',
+  'successfully created!'       => 'loodud!',
+  'successfully deleted!'       => 'kustutatud!',
+  'to'                          => 'kuni',
+  'website'                     => 'kodulehekülg',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/am b/sql-ledger/locale/ee/am
new file mode 100644 (file)
index 0000000..ebf0bf1
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Kohustused',
+  'AR'                          => 'Nõuded',
+  'Account'                     => 'Konto',
+  'Account Number'              => 'Konto number',
+  'Account Number missing!'     => 'Konto number puudub',
+  'Account Type'                => 'Konto tüüp',
+  'Account Type missing!'       => 'Konto tüüp puudub!',
+  'Account deleted!'            => 'Konto kustutatud!',
+  'Account saved!'              => 'Konto salvestatud',
+  'Add Account'                 => 'Lisa konto',
+  'Add GIFI'                    => 'Lisa GIFI',
+  'Address'                     => 'Aadress',
+  'Asset'                       => 'Vara',
+  'Audit Control'               => 'Audit',
+  'Backup sent to'              => 'Varukoopia saadetakse',
+  'Books are open'              => 'Kanded on avatud',
+  'Business Number'             => 'Ettevõtte kood',
+  'COGS'                        => 'COGS',
+  'Cannot delete account!'      => 'Kontot ei saa kustutada!',
+  'Cannot delete default account!' => 'Vaikimisi kontot ei saa kustutada!',
+  'Cannot save account!'        => 'Kontot ei saa salvestada',
+  'Cannot save preferences!'    => 'Maaranguid ei saa salvestada',
+  'Character Set'               => 'Kooditabel',
+  'Chart of Accounts'           => 'Kontoplaan',
+  'Close Books up to'           => 'Sulge kanded kuni',
+  'Company'                     => 'Ettevõte',
+  'Continue'                    => 'Edasi',
+  'Copy to COA'                 => 'Kopeeri kontoplaani',
+  'Credit'                      => 'Kreedit',
+  'Date Format'                 => 'Kuupäeva formaat',
+  'Debit'                       => 'Deebet',
+  'Delete'                      => 'Kustuta',
+  'Delete Account'              => 'Kustuta konto',
+  'Description'                 => 'Selgitus',
+  'Dropdown Limit'              => 'Rippmenüü piirang',
+  'E-mail'                      => 'E-mail',
+  'Edit'                        => 'Muudatused',
+  'Edit Account'                => 'Konto muudatused',
+  'Edit GIFI'                   => 'Muuda GIFI',
+  'Edit Preferences for'        => 'Määrangute muutmine: ',
+  'Edit Template'               => 'Dokumendipõhja muutmine',
+  'Enforce transaction reversal for all dates' => 'Muuda kannete pööramine kõikide kuupäevade ulatuses kohustuslikuks',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Sisesta kohalikud- ja välisvaluutad (kuni 3 tähemärki, koolonitega eraltatud, nt. CAD:USD:EUR)',
+  'Equity'                      => 'Omakapital',
+  'Expense'                     => 'Kulu',
+  'Expense Account'             => 'Kulukonto',
+  'Expense/Asset'               => 'Kulu/Vara',
+  'Fax'                         => 'Faks',
+  'Foreign Exchange Gain'       => 'Valuutakursside vahe kasum',
+  'Foreign Exchange Loss'       => 'Valuutakursside vahe kahjum',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI kustutatud',
+  'GIFI missing!'               => 'GIFI puudub',
+  'GIFI saved!'                 => 'GIFI salvestatud',
+  'Heading'                     => 'Päis',
+  'Include in drop-down menus'  => 'Kaasa valikmenüüdes',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Kaasa antud konto klient/tarnija vormides, et märkida klient/tarnija maksustatavaks',
+  'Income'                      => 'Tulu',
+  'Income Account'              => 'Tulukonto',
+  'Inventory'                   => 'Ladu',
+  'Inventory Account'           => 'Laokonto',
+  'Is this a summary account to record' => 'Kirje summaarne konto',
+  'Language'                    => 'Keel',
+  'Last Invoice Number'         => 'Viimane arve number',
+  'Last Numbers & Default Accounts' => 'Viimased numbrid ja vaikimisi kontod',
+  'Last Purchase Order Number'  => 'Viimane ostutellimuse number',
+  'Last Sales Order Number'     => 'Viimane müügitellimuse number',
+  'Liability'                   => 'Kohustus',
+  'Link'                        => 'Seosed',
+  'Name'                        => 'Nimi',
+  'No'                          => 'Ei',
+  'No email address for'        => 'E-maili aadress puudub',
+  'Number'                      => 'Kood',
+  'Number Format'               => 'Numbri formaat',
+  'Parts Inventory'             => 'Tooted',
+  'Password'                    => 'Parool',
+  'Payables'                    => 'Kohustused',
+  'Payment'                     => 'Maksed',
+  'Phone'                       => 'Telefon',
+  'Preferences saved!'          => 'Määrangud salvestatud',
+  'Rate'                        => 'Määr',
+  'Receivables'                 => 'Nõuded',
+  'Sales'                       => 'Müük',
+  'Save'                        => 'Salvesta',
+  'Service Items'               => 'Teenused',
+  'Ship via'                    => 'Tarneviis',
+  'Signature'                   => 'Signatuur',
+  'Stylesheet'                  => 'Laaditabel',
+  'Tax'                         => 'Maks',
+  'Tax Accounts'                => 'Maksukontod',
+  'Template saved!'             => 'Dokumendipõhjad salvestatud!',
+  'Transaction reversal enforced for all dates' => 'Kannete pööramine on kohustuslik kõikide kuupäevade ulatuses',
+  'Transaction reversal enforced up to' => 'Kannete pööramine on kohustuslik kuni',
+  'Transactions exist; cannot delete account!' => 'Kanded aktiivsed; kontot ei saa kustutada!',
+  'Weight Unit'                 => 'Kaaluühik',
+  'Year End'                    => 'Aasta lõpp',
+  'Yes'                         => 'Jah',
+  'does not exist'              => 'ei eksisteeri',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'lisa_konto'                  => 'add_account',
+  'edasi'                       => 'continue',
+  'kopeeri_kontoplaani'         => 'copy_to_coa',
+  'kustuta'                     => 'delete',
+  'muudatused'                  => 'edit',
+  'konto_muudatused'            => 'edit_account',
+  'salvesta'                    => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/ap b/sql-ledger/locale/ee/ap
new file mode 100644 (file)
index 0000000..f2b3052
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Kohustuste kanne',
+  'AP Transactions'             => 'Kohustuste kanded',
+  'Account'                     => 'Konto',
+  'Add Accounts Payables Transaction' => 'Lisa kohustuste kanne',
+  'Address'                     => 'Aadress',
+  'Amount'                      => 'Summa',
+  'Amount Due'                  => 'Tasumata',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprill',
+  'Are you sure you want to delete Transaction' => 'Kas oled kindel, et soovid kustutada kande',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Cannot delete transaction!'  => 'Kannet ei saa kustutada!',
+  'Cannot post payment for a closed period!' => 'Makset ei saa salvestada suletud perioodile',
+  'Cannot post transaction for a closed period!' => 'Kannet ei saa salvestada suletud perioodile',
+  'Cannot post transaction!'    => 'Kannet ei saa salvestada!',
+  'Closed'                      => 'Suletud',
+  'Confirm!'                    => 'Kinnita!',
+  'Continue'                    => 'Edasi',
+  'Currency'                    => 'Valuuta',
+  'Customer not on file!'       => 'Klienti pole failis!',
+  'Date'                        => 'Kuupäev',
+  'Date Paid'                   => 'Maksekuupäev',
+  'Dec'                         => 'Dets',
+  'December'                    => 'Detsember',
+  'Delete'                      => 'Kustuta',
+  'Description'                 => 'Selgitus',
+  'Due Date'                    => 'Maksetähtaeg',
+  'Due Date missing!'           => 'Maksetähtaeg puudub',
+  'Edit Accounts Payables Transaction' => 'Muuda nõuete kannet',
+  'Employee'                    => 'Töötaja',
+  'Exch'                        => 'Kurss',
+  'Exchangerate'                => 'Valuutakurss',
+  'Exchangerate for payment missing!' => 'Maksel ei ole valuutakurssi!',
+  'Exchangerate missing!'       => 'Valuutakurssi ei ole',
+  'Feb'                         => 'Veebr',
+  'February'                    => 'Veebruar',
+  'From'                        => 'Alates',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Kaasa aruandesse',
+  'Invoice'                     => 'Arve',
+  'Invoice Date'                => 'Arve kuupäev',
+  'Invoice Date missing!'       => 'Arve kuupäev puudub!',
+  'Invoice Number'              => 'Arve number',
+  'Invoice Number missing!'     => 'Arve number puudub!',
+  'Jan'                         => 'Jaan',
+  'January'                     => 'Jaanuar',
+  'Jul'                         => 'Juul',
+  'July'                        => 'Juuli',
+  'Jun'                         => 'Juun',
+  'June'                        => 'Juuni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'Märts',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Notes'                       => 'Märkused',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Kood',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktoober',
+  'Open'                        => 'Avatud',
+  'Order'                       => 'Tellimus',
+  'Order Number'                => 'Tellimuse number',
+  'Paid'                        => 'Makstud',
+  'Payment date missing!'       => 'Maksekuupäev puudub',
+  'Payments'                    => 'Maksed',
+  'Post'                        => 'Salvesta',
+  'Post as new'                 => 'Salvesta uuena',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekti pole failis',
+  'Select from one of the names below' => 'Vali üks alltoodud nimedest',
+  'Select from one of the projects below' => 'Vali üks alltoodud projektidest',
+  'Sep'                         => 'Sept',
+  'September'                   => 'September',
+  'Source'                      => 'Allikas',
+  'Subtotal'                    => 'Vahesumma',
+  'Tax'                         => 'Maks',
+  'Tax Included'                => 'Koos maksuga',
+  'Total'                       => 'Kokku',
+  'Transaction deleted!'        => 'Kanne kustutatud!',
+  'Transaction posted!'         => 'Kanne tud!',
+  'Update'                      => 'Uuenda',
+  'Vendor'                      => 'Hankija',
+  'Vendor Invoice'              => 'Vendor Invoice',
+  'Vendor missing!'             => 'Hankija puudub!',
+  'Vendor not on file!'         => 'Hankijat pole failis!',
+  'Yes'                         => 'Jah',
+  'to'                          => 'kuni',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'kohustuste_kanne'            => 'ap_transaction',
+  'lisa_kohustuste_kanne'       => 'add_accounts_payables_transaction',
+  'edasi'                       => 'continue',
+  'kustuta'                     => 'delete',
+  'muuda_nõuete_kannet'         => 'edit_accounts_payables_transaction',
+  'salvesta'                    => 'post',
+  'salvesta_uuena'              => 'post_as_new',
+  'uuenda'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'jah'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/ar b/sql-ledger/locale/ee/ar
new file mode 100644 (file)
index 0000000..e940d94
--- /dev/null
@@ -0,0 +1,134 @@
+$self{texts} = {
+  'AR Transaction'              => 'Nõuete kanne',
+  'AR Transactions'             => 'Nõuete kanded',
+  'Account'                     => 'Konto',
+  'Add Accounts Receivables Transaction' => 'Lisa nõuete kanne',
+  'Address'                     => 'Aadress',
+  'Amount'                      => 'Summa',
+  'Amount Due'                  => 'Tasumata',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprill',
+  'Are you sure you want to delete Transaction' => 'Kas oled kindel, et soovid kustutada kande',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Cannot delete transaction!'  => 'Kannet ei saa kustutada!',
+  'Cannot post payment for a closed period!' => 'Makset ei saa salvestada suletud perioodile',
+  'Cannot post transaction for a closed period!' => 'Kannet ei saa salvestada suletud perioodile',
+  'Cannot post transaction!'    => 'Kannet ei saa salvestada!',
+  'Closed'                      => 'Suletud',
+  'Confirm!'                    => 'Kinnita!',
+  'Continue'                    => 'Edasi',
+  'Credit Limit'                => 'Krediidilimiit',
+  'Currency'                    => 'Valuuta',
+  'Customer'                    => 'Klient',
+  'Customer missing!'           => 'Klienti pole määratud!',
+  'Customer not on file!'       => 'Klienti pole failis!',
+  'Date'                        => 'Kuupäev',
+  'Date Paid'                   => 'Maksekuupäev',
+  'Dec'                         => 'Dets',
+  'December'                    => 'Detsember',
+  'Delete'                      => 'Kustuta',
+  'Description'                 => 'Selgitus',
+  'Due Date'                    => 'Maksetähtaeg',
+  'Due Date missing!'           => 'Maksetähtaeg puudub',
+  'Edit Accounts Receivables Transaction' => 'Muuda kohustuste kannet',
+  'Exch'                        => 'Kurss',
+  'Exchangerate'                => 'Valuutakurss',
+  'Exchangerate for payment missing!' => 'Maksel ei ole valuutakurssi!',
+  'Exchangerate missing!'       => 'Valuutakurssi ei ole',
+  'Feb'                         => 'Veebr',
+  'February'                    => 'Veebruar',
+  'From'                        => 'Alates',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Kaasa aruandesse',
+  'Invoice'                     => 'Arve',
+  'Invoice Date'                => 'Arve kuupäev',
+  'Invoice Date missing!'       => 'Arve kuupäev puudub!',
+  'Invoice Number'              => 'Arve number',
+  'Invoice Number missing!'     => 'Arve number puudub!',
+  'Jan'                         => 'Jaan',
+  'January'                     => 'Jaanuar',
+  'Jul'                         => 'Juul',
+  'July'                        => 'Juuli',
+  'Jun'                         => 'Juun',
+  'June'                        => 'Juuni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'Märts',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Notes'                       => 'Märkused',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Kood',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktoober',
+  'Open'                        => 'Avatud',
+  'Order'                       => 'Tellimus',
+  'Order Number'                => 'Tellimuse number',
+  'Paid'                        => 'Makstud',
+  'Payment date missing!'       => 'Maksekuupäev puudub',
+  'Payments'                    => 'Maksed',
+  'Post'                        => 'Salvesta',
+  'Post as new'                 => 'Salvesta uuena',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekti pole failis',
+  'Remaining'                   => 'Kasutamata',
+  'Sales Invoice'               => 'Müügiarve',
+  'Salesperson'                 => 'Salesperson',
+  'Select from one of the names below' => 'Vali üks alltoodud nimedest',
+  'Select from one of the projects below' => 'Vali üks alltoodud projektidest',
+  'Sep'                         => 'Sept',
+  'September'                   => 'September',
+  'Ship via'                    => 'Tarneviis',
+  'Source'                      => 'Allikas',
+  'Subtotal'                    => 'Vahesumma',
+  'Tax'                         => 'Maks',
+  'Tax Included'                => 'Koos maksuga',
+  'Total'                       => 'Kokku',
+  'Transaction deleted!'        => 'Kanne kustutatud!',
+  'Transaction posted!'         => 'Kanne tud!',
+  'Update'                      => 'Uuenda',
+  'Vendor not on file!'         => 'Hankijat pole failis!',
+  'Yes'                         => 'Jah',
+  'to'                          => 'kuni',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'nõuete_kanne'                => 'ar_transaction',
+  'edasi'                       => 'continue',
+  'kustuta'                     => 'delete',
+  'salvesta'                    => 'post',
+  'salvesta_uuena'              => 'post_as_new',
+  'müügiarve'                   => 'sales_invoice',
+  'uuenda'                      => 'update',
+  'jah'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/arap b/sql-ledger/locale/ee/arap
new file mode 100644 (file)
index 0000000..061f6d3
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Aadress',
+  'Continue'                    => 'Edasi',
+  'Customer not on file!'       => 'Klienti pole failis!',
+  'Description'                 => 'Selgitus',
+  'Number'                      => 'Kood',
+  'Project not on file!'        => 'Projekti pole failis',
+  'Select from one of the names below' => 'Vali üks alltoodud nimedest',
+  'Select from one of the projects below' => 'Vali üks alltoodud projektidest',
+  'Vendor not on file!'         => 'Hankijat pole failis!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'vendor_invoice'              => 'vendor_invoice',
+  'edasi'                       => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/ca b/sql-ledger/locale/ee/ca
new file mode 100644 (file)
index 0000000..4695ea4
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprill',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Balance'                     => 'Bilanss',
+  'Chart of Accounts'           => 'Kontoplaan',
+  'Credit'                      => 'Kreedit',
+  'Date'                        => 'Kuupäev',
+  'Debit'                       => 'Deebet',
+  'Dec'                         => 'Dets',
+  'December'                    => 'Detsember',
+  'Description'                 => 'Selgitus',
+  'Feb'                         => 'Veebr',
+  'February'                    => 'Veebruar',
+  'From'                        => 'Alates',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Kaasa aruandesse',
+  'Jan'                         => 'Jaan',
+  'January'                     => 'Jaanuar',
+  'Jul'                         => 'Juul',
+  'July'                        => 'Juuli',
+  'Jun'                         => 'Juun',
+  'June'                        => 'Juuni',
+  'List Transactions'           => 'Kannete sirvimine',
+  'Mar'                         => 'Mär',
+  'March'                       => 'Märts',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktoober',
+  'Reference'                   => 'Viide',
+  'Sep'                         => 'Sept',
+  'September'                   => 'September',
+  'Subtotal'                    => 'Vahesumma',
+  'to'                          => 'kuni',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'kannete_sirvimine'           => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/cp b/sql-ledger/locale/ee/cp
new file mode 100644 (file)
index 0000000..c1353d5
--- /dev/null
@@ -0,0 +1,77 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Address'                     => 'Aadress',
+  'Amount'                      => 'Summa',
+  'Amount does not equal applied!' => 'Amount does not equal applied!',
+  'Amount missing!'             => 'Summa puudub!',
+  'Applied'                     => 'Makstud',
+  'Cannot post payment!'        => 'Makset ei saa salvestada!',
+  'Cannot process payment for a closed period!' => 'Suletud perioodi makset ei saa töödelda!',
+  'Check'                       => 'T?ekk',
+  'Check printed!'              => 'T?ekk on türkitud',
+  'Check printing failed!'      => 'T?eki trükkimine ebaõnnestus',
+  'Continue'                    => 'Edasi',
+  'Currency'                    => 'Valuuta',
+  'Customer'                    => 'Klient',
+  'Customer not on file!'       => 'Klienti pole failis!',
+  'Date'                        => 'Kuupäev',
+  'Date missing!'               => 'Kuupäev puudub!',
+  'Description'                 => 'Selgitus',
+  'Due'                         => 'Tasuda',
+  'Exchangerate'                => 'Valuutakurss',
+  'From'                        => 'Alates',
+  'Invoice'                     => 'Arve',
+  'Invoices'                    => 'Arved',
+  'Nothing applied!'            => 'Midagi ei muudetud',
+  'Number'                      => 'Kood',
+  'Paid in full'                => 'Täielikult tasutud',
+  'Payment'                     => 'Maksed',
+  'Payment posted!'             => 'Makse salvestatud',
+  'Post'                        => 'Salvesta',
+  'Print'                       => 'Trüki',
+  'Printer'                     => 'Printer',
+  'Project not on file!'        => 'Projekti pole failis',
+  'Receipt'                     => 'Laekumised',
+  'Receipt printed!'            => 'Tshekk trükitud',
+  'Receipt printing failed!'    => 'Tsheki trükkkimine ebaõnnestus',
+  'Reference'                   => 'Viide',
+  'Screen'                      => 'Ekraan',
+  'Select from one of the names below' => 'Vali üks alltoodud nimedest',
+  'Select from one of the projects below' => 'Vali üks alltoodud projektidest',
+  'Update'                      => 'Uuenda',
+  'Vendor'                      => 'Hankija',
+  'Vendor not on file!'         => 'Hankijat pole failis!',
+  'to'                          => 'kuni',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'edasi'                       => 'continue',
+  'salvesta'                    => 'post',
+  'trüki'                       => 'print',
+  'uuenda'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/ct b/sql-ledger/locale/ee/ct
new file mode 100644 (file)
index 0000000..4d167b2
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Lisa',
+  'Address'                     => 'Aadress',
+  'All'                         => 'Kõik',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Kienti ei saa kustutada!',
+  'Cannot delete vendor!'       => 'Tarnijat ei saa kustutada!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Edasi',
+  'Credit Limit'                => 'Krediidilimiit',
+  'Customer deleted!'           => 'Klient on kustutatud!',
+  'Customer saved!'             => 'Klient salvestatud',
+  'Customers'                   => 'Kliendid',
+  'Delete'                      => 'Kustuta',
+  'Discount'                    => 'Allahindlus',
+  'E-mail'                      => 'E-mail',
+  'Edit Customer'               => 'Muuda Kliendi andmeid',
+  'Edit Vendor'                 => 'Muuda Tarnija andmeid',
+  'Fax'                         => 'Faks',
+  'Include in Report'           => 'Kaasa aruandesse',
+  'Invoice'                     => 'Arve',
+  'Name'                        => 'Nimi',
+  'Name missing!'               => 'Nimi puudub!',
+  'Notes'                       => 'Märkused',
+  'Number'                      => 'Kood',
+  'Order'                       => 'Tellimus',
+  'Orphaned'                    => 'Seosteta',
+  'Phone'                       => 'Telefon',
+  'Save'                        => 'Salvesta',
+  'Ship to'                     => 'Tarneaadress',
+  'Tax Included'                => 'Koos maksuga',
+  'Taxable'                     => 'Maksustatav',
+  'Terms: Net'                  => 'Maksetingimus',
+  'Transactions exist, cannot delete customer!' => 'Kanded aktiivsed, klienti ei saa kustutada!',
+  'Transactions exist, cannot delete vendor!' => 'Kanded aktiivsed, hankijat ei saa kustutada!',
+  'Vendor deleted!'             => 'Hankija kustutatud!',
+  'Vendor saved!'               => 'Hankija salvestatud!',
+  'Vendors'                     => 'Hankijad',
+  'days'                        => 'päeva',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'lisa'                        => 'add',
+  'edasi'                       => 'continue',
+  'kustuta'                     => 'delete',
+  'arve'                        => 'invoice',
+  'tellimus'                    => 'order',
+  'salvesta'                    => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/gl b/sql-ledger/locale/ee/gl
new file mode 100644 (file)
index 0000000..dd25e8f
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Kohustuste kanne',
+  'AR Transaction'              => 'Nõuete kanne',
+  'Account'                     => 'Konto',
+  'Add General Ledger Transaction' => 'Lisa pearaamatu kanne',
+  'Address'                     => 'Aadress',
+  'All'                         => 'Kõik',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprill',
+  'Are you sure you want to delete Transaction' => 'Kas oled kindel, et soovid kustutada kande',
+  'Asset'                       => 'Vara',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Balance'                     => 'Bilanss',
+  'Cannot delete transaction!'  => 'Kannet ei saa kustutada!',
+  'Cannot have a value in both Debit and Credit!' => 'Deebet ja Kreedit väljad ei tohi olla samaaegselt täidetud!',
+  'Cannot post a transaction without a value!' => 'Tühja väärtusega kannet pole võimalik salvestada!',
+  'Cannot post transaction for a closed period!' => 'Kannet ei saa salvestada suletud perioodile',
+  'Confirm!'                    => 'Kinnita!',
+  'Continue'                    => 'Edasi',
+  'Credit'                      => 'Kreedit',
+  'Customer not on file!'       => 'Klienti pole failis!',
+  'Date'                        => 'Kuupäev',
+  'Debit'                       => 'Deebet',
+  'Debit and credit out of balance!' => 'Deebet ja Kreedit tasakaalust väljas!',
+  'Dec'                         => 'Dets',
+  'December'                    => 'Detsember',
+  'Delete'                      => 'Kustuta',
+  'Description'                 => 'Selgitus',
+  'Edit General Ledger Transaction' => 'Pearaamatu kande redigeerimine',
+  'Equity'                      => 'Omakapital',
+  'Expense'                     => 'Kulu',
+  'Feb'                         => 'Veebr',
+  'February'                    => 'Veebruar',
+  'From'                        => 'Alates',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'Pearaamatu kanne',
+  'General Ledger'              => 'Pearaamat',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Kaasa aruandesse',
+  'Income'                      => 'Tulu',
+  'Jan'                         => 'Jaan',
+  'January'                     => 'Jaanuar',
+  'Jul'                         => 'Juul',
+  'July'                        => 'Juuli',
+  'Jun'                         => 'Juun',
+  'June'                        => 'Juuni',
+  'Liability'                   => 'Kohustus',
+  'Mar'                         => 'Mär',
+  'March'                       => 'Märts',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Notes'                       => 'Märkused',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Kood',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktoober',
+  'Post'                        => 'Salvesta',
+  'Post as new'                 => 'Salvesta uuena',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekti pole failis',
+  'Reference'                   => 'Viide',
+  'Reference missing!'          => 'Viide puudub!',
+  'Reports'                     => 'Aruanded',
+  'Sales Invoice'               => 'Müügiarve',
+  'Select from one of the names below' => 'Vali üks alltoodud nimedest',
+  'Select from one of the projects below' => 'Vali üks alltoodud projektidest',
+  'Sep'                         => 'Sept',
+  'September'                   => 'September',
+  'Source'                      => 'Allikas',
+  'Subtotal'                    => 'Vahesumma',
+  'Transaction Date missing!'   => 'Kande kuupäev puudub!',
+  'Transaction deleted!'        => 'Kanne kustutatud!',
+  'Transaction posted!'         => 'Kanne tud!',
+  'Update'                      => 'Uuenda',
+  'Vendor Invoice'              => 'Vendor Invoice',
+  'Vendor not on file!'         => 'Hankijat pole failis!',
+  'Yes'                         => 'Jah',
+  'to'                          => 'kuni',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'kohustuste_kanne'            => 'ap_transaction',
+  'nõuete_kanne'                => 'ar_transaction',
+  'edasi'                       => 'continue',
+  'kustuta'                     => 'delete',
+  'pearaamatu_kanne'            => 'gl_transaction',
+  'salvesta'                    => 'post',
+  'salvesta_uuena'              => 'post_as_new',
+  'müügiarve'                   => 'sales_invoice',
+  'uuenda'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'jah'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/ic b/sql-ledger/locale/ee/ic
new file mode 100644 (file)
index 0000000..7e86e29
--- /dev/null
@@ -0,0 +1,208 @@
+$self{texts} = {
+  'Active'                      => 'Aktiva',
+  'Add'                         => 'Lisa',
+  'Add Assembly'                => 'Lisa komplekt',
+  'Add Part'                    => 'Lisa toode',
+  'Add Purchase Order'          => 'Lisa ostutellimus',
+  'Add Sales Order'             => 'Lisa müügitellimus',
+  'Add Service'                 => 'Lisa teenus',
+  'Address'                     => 'Aadress',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprill',
+  'Assemblies'                  => 'Komplektid',
+  'Assemblies restocked!'       => 'Komplektid lattu tagastatud!',
+  'Assembly Number missing!'    => 'Komplekti number puudub!',
+  'Attachment'                  => 'Kaasatud fail',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'BOM'                         => 'Materjalide nimekiri',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Kast',
+  'Bought'                      => 'Ostetud',
+  'COGS'                        => 'COGS',
+  'Cannot delete item already invoiced!' => 'Esitatud arvega toodet ei saa kustutada!',
+  'Cannot delete item on order!' => 'Tellimusega seotud artiklit ei saa kustutada!',
+  'Cannot delete item which is part of an assembly!' => 'Komplekti kuuluvat toodet ei saa kustutada!',
+  'Cannot delete item!'         => 'Toodet ei saa kustutada!',
+  'Cannot stock assemblies!'    => 'Komplekte ei saa lattu võtta',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Edasi',
+  'Copies'                      => 'koopiat',
+  'Dec'                         => 'Dets',
+  'December'                    => 'Detsember',
+  'Delete'                      => 'Kustuta',
+  'Delivery Date'               => 'Tarne kuupäev',
+  'Description'                 => 'Selgitus',
+  'Drawing'                     => 'Pildid',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-maili aadress puudub',
+  'Edit Assembly'               => 'Muuda Komplekti',
+  'Edit Part'                   => 'Toote redigeerimine',
+  'Edit Service'                => 'Teenuse muutmine',
+  'Expense'                     => 'Kulu',
+  'Extended'                    => 'Summa',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'Veebr',
+  'February'                    => 'Veebruar',
+  'From'                        => 'Alates',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'Image'                       => 'Pilt',
+  'In-line'                     => 'Dokumendisisene',
+  'Include in Report'           => 'Kaasa aruandesse',
+  'Income'                      => 'Tulu',
+  'Individual Items'            => 'Komponendid',
+  'Inventory'                   => 'Ladu',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Enne komplekti aegunuks märkimist peab laoseis null olema!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Enne toote aegunuks märkimist peab laoseis null olema!',
+  'Inventory quantity must be zero!' => 'Laoseis peab null olema!',
+  'Invoice'                     => 'Arve',
+  'Invoice Date missing!'       => 'Arve kuupäev puudub!',
+  'Invoice Number'              => 'Arve number',
+  'Invoice Number missing!'     => 'Arve number puudub!',
+  'Item deleted!'               => 'Toode kustutatud!',
+  'Item not on file!'           => 'Toode puudub andmebaasist!',
+  'Jan'                         => 'Jaan',
+  'January'                     => 'Jaanuar',
+  'Jul'                         => 'Juul',
+  'July'                        => 'Juuli',
+  'Jun'                         => 'Juun',
+  'June'                        => 'Juuni',
+  'Last Cost'                   => 'Viimane ostuhind',
+  'Line Total'                  => 'Rea summa',
+  'Link Accounts'               => 'Seosta kontod',
+  'List Price'                  => 'Hinnakirja hind',
+  'Make'                        => 'Tootja',
+  'Mar'                         => 'Mär',
+  'March'                       => 'Märts',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Teade',
+  'Microfiche'                  => 'Mikrofilm',
+  'Model'                       => 'Mudel',
+  'Name'                        => 'Nimi',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Märkused',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Kood',
+  'Number missing in Row'       => 'Antud real puudub kood',
+  'Obsolete'                    => 'Aegunud',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktoober',
+  'On Hand'                     => 'Laos',
+  'On Order'                    => 'Tellimisel',
+  'Order'                       => 'Tellimus',
+  'Order Date missing!'         => 'Tellimuse kuupäev puudub',
+  'Order Number'                => 'Tellimuse number',
+  'Order Number missing!'       => 'Tellimuse number puudub',
+  'Ordered'                     => 'Tellitud',
+  'Orphaned'                    => 'Seosteta',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Saateleht',
+  'Packing List Date missing!'  => 'Saatelehe kuupäev puudub',
+  'Packing List Number missing!' => 'Saatelehe number puudub',
+  'Part'                        => 'Toode',
+  'Part Number missing!'        => 'Toote kood puudub',
+  'Parts'                       => 'Tooted',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Hind',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Projekt',
+  'Purchase Order'              => 'Ostutellimus',
+  'Qty'                         => 'Kogus',
+  'ROP'                         => 'TM',
+  'Recd'                        => 'Saabunud',
+  'Required by'                 => 'Tarneaeg',
+  'Sales'                       => 'Müük',
+  'Sales Order'                 => 'Müügitellimus',
+  'Save'                        => 'Salvesta',
+  'Screen'                      => 'Ekraan',
+  'Select from one of the items below' => 'Vali üks alltoodud toodetest',
+  'Select postscript or PDF!'   => 'Vali kas postscript või PDF',
+  'Sell Price'                  => 'Müügihind',
+  'Sep'                         => 'Sept',
+  'September'                   => 'September',
+  'Service'                     => 'Teenus',
+  'Service Number missing!'     => 'teenuse kood puudub!',
+  'Services'                    => 'Teenused',
+  'Ship'                        => 'Tarnimine',
+  'Ship to'                     => 'Tarneaadress',
+  'Short'                       => 'Lühike',
+  'Sold'                        => 'Müüdud',
+  'Stock Assembly'              => 'Komplekti lattu võtmine',
+  'Subject'                     => 'Pealkiri',
+  'Subtotal'                    => 'Vahesumma',
+  'Tax'                         => 'Maks',
+  'To'                          => 'Kuhu',
+  'Top Level'                   => 'Ülemine tase',
+  'Total'                       => 'Kokku',
+  'Unit'                        => 'Ühik',
+  'Unit of measure'             => 'Mõõtühik',
+  'Update'                      => 'Uuenda',
+  'Updated'                     => 'Uuendatud',
+  'Weight'                      => 'Kaal',
+  'What type of item is this?'  => 'Mis tüüpi tootega on tegemist?',
+  'ea'                          => 'tk',
+  'emailed to'                  => 'salvestatud aadressile',
+  'hr'                          => 't',
+  'sent to printer'             => 'printerile saadetud',
+  'to'                          => 'kuni',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'lisa'                        => 'add',
+  'lisa_komplekt'               => 'add_assembly',
+  'lisa_toode'                  => 'add_part',
+  'lisa_teenus'                 => 'add_service',
+  'edasi'                       => 'continue',
+  'kustuta'                     => 'delete',
+  'muuda_komplekti'             => 'edit_assembly',
+  'toote_redigeerimine'         => 'edit_part',
+  'teenuse_muutmine'            => 'edit_service',
+  'salvesta'                    => 'save',
+  'uuenda'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/io b/sql-ledger/locale/ee/io
new file mode 100644 (file)
index 0000000..ccf21af
--- /dev/null
@@ -0,0 +1,108 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Lisa ostutellimus',
+  'Add Sales Order'             => 'Lisa müügitellimus',
+  'Address'                     => 'Aadress',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprill',
+  'Attachment'                  => 'Kaasatud fail',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Kast',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Edasi',
+  'Copies'                      => 'koopiat',
+  'Dec'                         => 'Dets',
+  'December'                    => 'Detsember',
+  'Delivery Date'               => 'Tarne kuupäev',
+  'Description'                 => 'Selgitus',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-maili aadress puudub',
+  'Extended'                    => 'Summa',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'Veebr',
+  'February'                    => 'Veebruar',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'In-line'                     => 'Dokumendisisene',
+  'Invoice'                     => 'Arve',
+  'Invoice Date missing!'       => 'Arve kuupäev puudub!',
+  'Invoice Number missing!'     => 'Arve number puudub!',
+  'Item not on file!'           => 'Toode puudub andmebaasist!',
+  'Jan'                         => 'Jaan',
+  'January'                     => 'Jaanuar',
+  'Jul'                         => 'Juul',
+  'July'                        => 'Juuli',
+  'Jun'                         => 'Juun',
+  'June'                        => 'Juuni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'Märts',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Teade',
+  'Name'                        => 'Nimi',
+  'No.'                         => 'Nr.',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Kood',
+  'Number missing in Row'       => 'Antud real puudub kood',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktoober',
+  'Order'                       => 'Tellimus',
+  'Order Date missing!'         => 'Tellimuse kuupäev puudub',
+  'Order Number missing!'       => 'Tellimuse number puudub',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Saateleht',
+  'Packing List Date missing!'  => 'Saatelehe kuupäev puudub',
+  'Packing List Number missing!' => 'Saatelehe number puudub',
+  'Part'                        => 'Toode',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Hind',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Projekt',
+  'Purchase Order'              => 'Ostutellimus',
+  'Qty'                         => 'Kogus',
+  'Recd'                        => 'Saabunud',
+  'Required by'                 => 'Tarneaeg',
+  'Sales Order'                 => 'Müügitellimus',
+  'Screen'                      => 'Ekraan',
+  'Select from one of the items below' => 'Vali üks alltoodud toodetest',
+  'Select postscript or PDF!'   => 'Vali kas postscript või PDF',
+  'Sep'                         => 'Sept',
+  'September'                   => 'September',
+  'Service'                     => 'Teenus',
+  'Ship'                        => 'Tarnimine',
+  'Ship to'                     => 'Tarneaadress',
+  'Subject'                     => 'Pealkiri',
+  'To'                          => 'Kuhu',
+  'Unit'                        => 'Ühik',
+  'What type of item is this?'  => 'Mis tüüpi tootega on tegemist?',
+  'emailed to'                  => 'salvestatud aadressile',
+  'sent to printer'             => 'printerile saadetud',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'edasi'                       => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/ir b/sql-ledger/locale/ee/ir
new file mode 100644 (file)
index 0000000..0606a42
--- /dev/null
@@ -0,0 +1,180 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Add Purchase Order'          => 'Lisa ostutellimus',
+  'Add Sales Order'             => 'Lisa müügitellimus',
+  'Add Vendor Invoice'          => 'Add Vendor Invoice',
+  'Address'                     => 'Aadress',
+  'Amount'                      => 'Summa',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprill',
+  'Are you sure you want to delete Invoice Number' => 'Kas oled kindel, et soovid kustutada arve',
+  'Attachment'                  => 'Kaasatud fail',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Kast',
+  'Cannot delete invoice!'      => 'Arvet ei saa kustutada',
+  'Cannot post invoice for a closed period!' => 'Arvet ei saa salvestada suletud perioodile!',
+  'Cannot post invoice!'        => 'Arvet ei saa saata!',
+  'Cannot post payment for a closed period!' => 'Makset ei saa salvestada suletud perioodile',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Kinnita!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Edasi',
+  'Copies'                      => 'koopiat',
+  'Currency'                    => 'Valuuta',
+  'Customer not on file!'       => 'Klienti pole failis!',
+  'Date'                        => 'Kuupäev',
+  'Dec'                         => 'Dets',
+  'December'                    => 'Detsember',
+  'Delete'                      => 'Kustuta',
+  'Delivery Date'               => 'Tarne kuupäev',
+  'Description'                 => 'Selgitus',
+  'Due Date'                    => 'Maksetähtaeg',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-maili aadress puudub',
+  'Edit Vendor Invoice'         => 'Edit Vendor Invoice',
+  'Exch'                        => 'Kurss',
+  'Exchangerate'                => 'Valuutakurss',
+  'Exchangerate for payment missing!' => 'Maksel ei ole valuutakurssi!',
+  'Exchangerate missing!'       => 'Valuutakurssi ei ole',
+  'Extended'                    => 'Summa',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'Veebr',
+  'February'                    => 'Veebruar',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'In-line'                     => 'Dokumendisisene',
+  'Invoice'                     => 'Arve',
+  'Invoice Date'                => 'Arve kuupäev',
+  'Invoice Date missing!'       => 'Arve kuupäev puudub!',
+  'Invoice Number'              => 'Arve number',
+  'Invoice Number missing!'     => 'Arve number puudub!',
+  'Invoice deleted!'            => 'Arve kustutatud!',
+  'Invoice posted!'             => 'Arve salvestatud!',
+  'Item not on file!'           => 'Toode puudub andmebaasist!',
+  'Jan'                         => 'Jaan',
+  'January'                     => 'Jaanuar',
+  'Jul'                         => 'Juul',
+  'July'                        => 'Juuli',
+  'Jun'                         => 'Juun',
+  'June'                        => 'Juuni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'Märts',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Teade',
+  'Name'                        => 'Nimi',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Märkused',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Kood',
+  'Number missing in Row'       => 'Antud real puudub kood',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktoober',
+  'Order'                       => 'Tellimus',
+  'Order Date missing!'         => 'Tellimuse kuupäev puudub',
+  'Order Number'                => 'Tellimuse number',
+  'Order Number missing!'       => 'Tellimuse number puudub',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Saateleht',
+  'Packing List Date missing!'  => 'Saatelehe kuupäev puudub',
+  'Packing List Number missing!' => 'Saatelehe number puudub',
+  'Part'                        => 'Toode',
+  'Payment date missing!'       => 'Maksekuupäev puudub',
+  'Payments'                    => 'Maksed',
+  'Phone'                       => 'Telefon',
+  'Post'                        => 'Salvesta',
+  'Post as new'                 => 'Salvesta uuena',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Hind',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekti pole failis',
+  'Purchase Order'              => 'Ostutellimus',
+  'Qty'                         => 'Kogus',
+  'Recd'                        => 'Saabunud',
+  'Record in'                   => 'Sihtkonto',
+  'Required by'                 => 'Tarneaeg',
+  'Sales Order'                 => 'Müügitellimus',
+  'Screen'                      => 'Ekraan',
+  'Select from one of the items below' => 'Vali üks alltoodud toodetest',
+  'Select from one of the names below' => 'Vali üks alltoodud nimedest',
+  'Select from one of the projects below' => 'Vali üks alltoodud projektidest',
+  'Select postscript or PDF!'   => 'Vali kas postscript või PDF',
+  'Sep'                         => 'Sept',
+  'September'                   => 'September',
+  'Service'                     => 'Teenus',
+  'Ship'                        => 'Tarnimine',
+  'Ship to'                     => 'Tarneaadress',
+  'Source'                      => 'Allikas',
+  'Subject'                     => 'Pealkiri',
+  'Subtotal'                    => 'Vahesumma',
+  'Tax Included'                => 'Koos maksuga',
+  'To'                          => 'Kuhu',
+  'Total'                       => 'Kokku',
+  'Unit'                        => 'Ühik',
+  'Update'                      => 'Uuenda',
+  'Vendor'                      => 'Hankija',
+  'Vendor missing!'             => 'Hankija puudub!',
+  'Vendor not on file!'         => 'Hankijat pole failis!',
+  'What type of item is this?'  => 'Mis tüüpi tootega on tegemist?',
+  'Yes'                         => 'Jah',
+  'ea'                          => 'tk',
+  'emailed to'                  => 'salvestatud aadressile',
+  'sent to printer'             => 'printerile saadetud',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'edasi'                       => 'continue',
+  'kustuta'                     => 'delete',
+  'tellimus'                    => 'order',
+  'salvesta'                    => 'post',
+  'salvesta_uuena'              => 'post_as_new',
+  'uuenda'                      => 'update',
+  'jah'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/is b/sql-ledger/locale/ee/is
new file mode 100644 (file)
index 0000000..c380e76
--- /dev/null
@@ -0,0 +1,187 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Add Purchase Order'          => 'Lisa ostutellimus',
+  'Add Sales Invoice'           => 'Lisa Müügiarve',
+  'Add Sales Order'             => 'Lisa müügitellimus',
+  'Address'                     => 'Aadress',
+  'Amount'                      => 'Summa',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprill',
+  'Are you sure you want to delete Invoice Number' => 'Kas oled kindel, et soovid kustutada arve',
+  'Attachment'                  => 'Kaasatud fail',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Kast',
+  'Cannot delete invoice!'      => 'Arvet ei saa kustutada',
+  'Cannot post invoice for a closed period!' => 'Arvet ei saa salvestada suletud perioodile!',
+  'Cannot post invoice!'        => 'Arvet ei saa saata!',
+  'Cannot post payment for a closed period!' => 'Makset ei saa salvestada suletud perioodile',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Kinnita!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Edasi',
+  'Copies'                      => 'koopiat',
+  'Credit Limit'                => 'Krediidilimiit',
+  'Currency'                    => 'Valuuta',
+  'Customer'                    => 'Klient',
+  'Customer missing!'           => 'Klienti pole määratud!',
+  'Customer not on file!'       => 'Klienti pole failis!',
+  'Date'                        => 'Kuupäev',
+  'Dec'                         => 'Dets',
+  'December'                    => 'Detsember',
+  'Delete'                      => 'Kustuta',
+  'Delivery Date'               => 'Tarne kuupäev',
+  'Description'                 => 'Selgitus',
+  'Due Date'                    => 'Maksetähtaeg',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-maili aadress puudub',
+  'Edit Sales Invoice'          => 'Müügiarve muutmine',
+  'Exch'                        => 'Kurss',
+  'Exchangerate'                => 'Valuutakurss',
+  'Exchangerate for payment missing!' => 'Maksel ei ole valuutakurssi!',
+  'Exchangerate missing!'       => 'Valuutakurssi ei ole',
+  'Extended'                    => 'Summa',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'Veebr',
+  'February'                    => 'Veebruar',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'In-line'                     => 'Dokumendisisene',
+  'Invoice'                     => 'Arve',
+  'Invoice Date'                => 'Arve kuupäev',
+  'Invoice Date missing!'       => 'Arve kuupäev puudub!',
+  'Invoice Number'              => 'Arve number',
+  'Invoice Number missing!'     => 'Arve number puudub!',
+  'Invoice deleted!'            => 'Arve kustutatud!',
+  'Invoice posted!'             => 'Arve salvestatud!',
+  'Item not on file!'           => 'Toode puudub andmebaasist!',
+  'Jan'                         => 'Jaan',
+  'January'                     => 'Jaanuar',
+  'Jul'                         => 'Juul',
+  'July'                        => 'Juuli',
+  'Jun'                         => 'Juun',
+  'June'                        => 'Juuni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'Märts',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Teade',
+  'Name'                        => 'Nimi',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Märkused',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Kood',
+  'Number missing in Row'       => 'Antud real puudub kood',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktoober',
+  'Order'                       => 'Tellimus',
+  'Order Date missing!'         => 'Tellimuse kuupäev puudub',
+  'Order Number'                => 'Tellimuse number',
+  'Order Number missing!'       => 'Tellimuse number puudub',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Saateleht',
+  'Packing List Date missing!'  => 'Saatelehe kuupäev puudub',
+  'Packing List Number missing!' => 'Saatelehe number puudub',
+  'Part'                        => 'Toode',
+  'Payment date missing!'       => 'Maksekuupäev puudub',
+  'Payments'                    => 'Maksed',
+  'Phone'                       => 'Telefon',
+  'Post'                        => 'Salvesta',
+  'Post as new'                 => 'Salvesta uuena',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Hind',
+  'Print'                       => 'Trüki',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekti pole failis',
+  'Purchase Order'              => 'Ostutellimus',
+  'Qty'                         => 'Kogus',
+  'Recd'                        => 'Saabunud',
+  'Record in'                   => 'Sihtkonto',
+  'Remaining'                   => 'Kasutamata',
+  'Required by'                 => 'Tarneaeg',
+  'Sales Order'                 => 'Müügitellimus',
+  'Screen'                      => 'Ekraan',
+  'Select from one of the items below' => 'Vali üks alltoodud toodetest',
+  'Select from one of the names below' => 'Vali üks alltoodud nimedest',
+  'Select from one of the projects below' => 'Vali üks alltoodud projektidest',
+  'Select postscript or PDF!'   => 'Vali kas postscript või PDF',
+  'Sep'                         => 'Sept',
+  'September'                   => 'September',
+  'Service'                     => 'Teenus',
+  'Ship'                        => 'Tarnimine',
+  'Ship to'                     => 'Tarneaadress',
+  'Ship via'                    => 'Tarneviis',
+  'Source'                      => 'Allikas',
+  'Subject'                     => 'Pealkiri',
+  'Subtotal'                    => 'Vahesumma',
+  'Tax Included'                => 'Koos maksuga',
+  'To'                          => 'Kuhu',
+  'Total'                       => 'Kokku',
+  'Unit'                        => 'Ühik',
+  'Update'                      => 'Uuenda',
+  'Vendor not on file!'         => 'Hankijat pole failis!',
+  'What type of item is this?'  => 'Mis tüüpi tootega on tegemist?',
+  'Yes'                         => 'Jah',
+  'ea'                          => 'tk',
+  'emailed to'                  => 'salvestatud aadressile',
+  'sent to printer'             => 'printerile saadetud',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'edasi'                       => 'continue',
+  'kustuta'                     => 'delete',
+  'e_mail'                      => 'e_mail',
+  'tellimus'                    => 'order',
+  'salvesta'                    => 'post',
+  'salvesta_uuena'              => 'post_as_new',
+  'trüki'                       => 'print',
+  'tarneaadress'                => 'ship_to',
+  'uuenda'                      => 'update',
+  'jah'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/login b/sql-ledger/locale/ee/login
new file mode 100644 (file)
index 0000000..18cb05b
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'Programmi Info',
+  'Database Host'               => 'Andmebaasiserver',
+  'Dataset'                     => 'Andmebaas',
+  'Incorrect Dataset version!'  => 'Vale andmebaasi versioon',
+  'Incorrect Password!'         => 'Vale parool!',
+  'Licensed to'                 => 'Kasutaja andmed:',
+  'Login'                       => 'Login',
+  'Name'                        => 'Nimi',
+  'Password'                    => 'Parool',
+  'User'                        => 'Kasutaja',
+  'Version'                     => 'Versioon',
+  'You are logged out!'         => 'Oled välja loginud!',
+  'You did not enter a name!'   => 'Nimi sisestamata!',
+  'is not a member!'            => 'ei ole kasutaja!',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'login'                       => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/menu b/sql-ledger/locale/ee/menu
new file mode 100644 (file)
index 0000000..7d77737
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => 'Kohustused',
+  'AP Aging'                    => 'Võlad',
+  'AR'                          => 'Nõuded',
+  'AR Aging'                    => 'Võlglased',
+  'Accounting Menu'             => 'Raamatupidamise Menüü',
+  'Add Account'                 => 'Lisa konto',
+  'Add Assembly'                => 'Lisa komplekt',
+  'Add Customer'                => 'Lisa klient',
+  'Add GIFI'                    => 'Lisa GIFI',
+  'Add Part'                    => 'Lisa toode',
+  'Add Project'                 => 'Lisa Projekt',
+  'Add Service'                 => 'Lisa teenus',
+  'Add Transaction'             => 'Lisa kanne',
+  'Add Vendor'                  => 'Lisa hankija',
+  'Assemblies'                  => 'Komplektid',
+  'Audit Control'               => 'Audit',
+  'Backup'                      => 'Varukoopia',
+  'Balance Sheet'               => 'Bilansitabel',
+  'Cash'                        => 'Kassa',
+  'Chart of Accounts'           => 'Kontoplaan',
+  'Check'                       => 'T?ekk',
+  'Customers'                   => 'Kliendid',
+  'General Ledger'              => 'Pearaamat',
+  'Goods & Services'            => 'Tooted ja teenused',
+  'HTML Templates'              => 'HTML dokumendipõhjad',
+  'Income Statement'            => 'Kasumiaruanne',
+  'Invoice'                     => 'Arve',
+  'LaTeX Templates'             => 'LaTeX dokumendipõhjad',
+  'List Accounts'               => 'Kontode nimekiri',
+  'List GIFI'                   => 'GIFI nimekiri',
+  'Logout'                      => 'Logi välja',
+  'Order Entry'                 => 'Tellimuse sisestamine',
+  'Packing List'                => 'Saateleht',
+  'Parts'                       => 'Tooted',
+  'Payment'                     => 'Maksed',
+  'Payments'                    => 'Maksed',
+  'Preferences'                 => 'Määrangud',
+  'Projects'                    => 'Projektid',
+  'Purchase Order'              => 'Ostutellimus',
+  'Purchase Orders'             => 'Ostutellimused',
+  'Receipt'                     => 'Laekumised',
+  'Receipts'                    => 'Laekumised',
+  'Reconciliation'              => 'Tasaarveldused',
+  'Reports'                     => 'Aruanded',
+  'Sales Invoice'               => 'Müügiarve',
+  'Sales Order'                 => 'Müügitellimus',
+  'Sales Orders'                => 'Müügitellimused',
+  'Save to File'                => 'Salvesta faili',
+  'Send by E-Mail'              => 'Saada e-postiga',
+  'Services'                    => 'Teenused',
+  'Statement'                   => 'Aruanne',
+  'Stock Assembly'              => 'Komplekti lattu võtmine',
+  'Stylesheet'                  => 'Laaditabel',
+  'System'                      => 'Süsteem',
+  'Tax collected'               => 'Kogutud maksud',
+  'Tax paid'                    => 'Makstud makse',
+  'Transactions'                => 'Kanded',
+  'Trial Balance'               => 'Proovibilanss',
+  'Vendor Invoice'              => 'Vendor Invoice',
+  'Vendors'                     => 'Hankijad',
+  'Version'                     => 'Versioon',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/oe b/sql-ledger/locale/ee/oe
new file mode 100644 (file)
index 0000000..dd5a09b
--- /dev/null
@@ -0,0 +1,202 @@
+$self{texts} = {
+  'Add'                         => 'Lisa',
+  'Add Purchase Order'          => 'Lisa ostutellimus',
+  'Add Sales Invoice'           => 'Lisa Müügiarve',
+  'Add Sales Order'             => 'Lisa müügitellimus',
+  'Add Vendor Invoice'          => 'Add Vendor Invoice',
+  'Address'                     => 'Aadress',
+  'Amount'                      => 'Summa',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprill',
+  'Are you sure you want to delete Order Number' => 'Kas oled kindel, et soovid kustutada tellimuse',
+  'Attachment'                  => 'Kaasatud fail',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Kast',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Tellimust ei saa kustutada!',
+  'Cannot save order!'          => 'Arvet ei saa salvestada',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Suletud',
+  'Confirm!'                    => 'Kinnita!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Edasi',
+  'Copies'                      => 'koopiat',
+  'Credit Limit'                => 'Krediidilimiit',
+  'Curr'                        => 'Val.',
+  'Currency'                    => 'Valuuta',
+  'Customer'                    => 'Klient',
+  'Customer missing!'           => 'Klienti pole määratud!',
+  'Customer not on file!'       => 'Klienti pole failis!',
+  'Date'                        => 'Kuupäev',
+  'Dec'                         => 'Dets',
+  'December'                    => 'Detsember',
+  'Delete'                      => 'Kustuta',
+  'Delivery Date'               => 'Tarne kuupäev',
+  'Description'                 => 'Selgitus',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-maili aadress puudub',
+  'Edit Purchase Order'         => 'Ostutellimuse muutmine',
+  'Edit Sales Order'            => 'Müügitellimuse muutmine',
+  'Exchangerate'                => 'Valuutakurss',
+  'Exchangerate missing!'       => 'Valuutakurssi ei ole',
+  'Extended'                    => 'Summa',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'Veebr',
+  'February'                    => 'Veebruar',
+  'From'                        => 'Alates',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Dokumendisisene',
+  'Include in Report'           => 'Kaasa aruandesse',
+  'Invoice'                     => 'Arve',
+  'Invoice Date missing!'       => 'Arve kuupäev puudub!',
+  'Invoice Number missing!'     => 'Arve number puudub!',
+  'Item not on file!'           => 'Toode puudub andmebaasist!',
+  'Jan'                         => 'Jaan',
+  'January'                     => 'Jaanuar',
+  'Jul'                         => 'Juul',
+  'July'                        => 'Juuli',
+  'Jun'                         => 'Juun',
+  'June'                        => 'Juuni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'Märts',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Teade',
+  'Name'                        => 'Nimi',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Märkused',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Kood',
+  'Number missing in Row'       => 'Antud real puudub kood',
+  'O'                           => 'O',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktoober',
+  'Open'                        => 'Avatud',
+  'Order'                       => 'Tellimus',
+  'Order Date'                  => 'Tellimuse kuupäev',
+  'Order Date missing!'         => 'Tellimuse kuupäev puudub',
+  'Order Number'                => 'Tellimuse number',
+  'Order Number missing!'       => 'Tellimuse number puudub',
+  'Order deleted!'              => 'Tellimus kustutatud',
+  'Order saved!'                => 'Tellimus salvestatud',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Saateleht',
+  'Packing List Date missing!'  => 'Saatelehe kuupäev puudub',
+  'Packing List Number missing!' => 'Saatelehe number puudub',
+  'Part'                        => 'Toode',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Hind',
+  'Print'                       => 'Trüki',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekti pole failis',
+  'Purchase Order'              => 'Ostutellimus',
+  'Purchase Orders'             => 'Ostutellimused',
+  'Qty'                         => 'Kogus',
+  'Recd'                        => 'Saabunud',
+  'Remaining'                   => 'Kasutamata',
+  'Required by'                 => 'Tarneaeg',
+  'Sales Order'                 => 'Müügitellimus',
+  'Sales Orders'                => 'Müügitellimused',
+  'Save'                        => 'Salvesta',
+  'Save as new'                 => 'Salvesta uuena',
+  'Screen'                      => 'Ekraan',
+  'Select from one of the items below' => 'Vali üks alltoodud toodetest',
+  'Select from one of the names below' => 'Vali üks alltoodud nimedest',
+  'Select from one of the projects below' => 'Vali üks alltoodud projektidest',
+  'Select postscript or PDF!'   => 'Vali kas postscript või PDF',
+  'Sep'                         => 'Sept',
+  'September'                   => 'September',
+  'Service'                     => 'Teenus',
+  'Ship'                        => 'Tarnimine',
+  'Ship to'                     => 'Tarneaadress',
+  'Ship via'                    => 'Tarneviis',
+  'Subject'                     => 'Pealkiri',
+  'Subtotal'                    => 'Vahesumma',
+  'Tax'                         => 'Maks',
+  'Tax Included'                => 'Koos maksuga',
+  'Terms: Net'                  => 'Maksetingimus',
+  'To'                          => 'Kuhu',
+  'Total'                       => 'Kokku',
+  'Unit'                        => 'Ühik',
+  'Update'                      => 'Uuenda',
+  'Vendor'                      => 'Hankija',
+  'Vendor missing!'             => 'Hankija puudub!',
+  'Vendor not on file!'         => 'Hankijat pole failis!',
+  'What type of item is this?'  => 'Mis tüüpi tootega on tegemist?',
+  'Yes'                         => 'Jah',
+  'days'                        => 'päeva',
+  'ea'                          => 'tk',
+  'emailed to'                  => 'salvestatud aadressile',
+  'sent to printer'             => 'printerile saadetud',
+  'to'                          => 'kuni',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'lisa'                        => 'add',
+  'edasi'                       => 'continue',
+  'kustuta'                     => 'delete',
+  'e_mail'                      => 'e_mail',
+  'arve'                        => 'invoice',
+  'trüki'                       => 'print',
+  'salvesta'                    => 'save',
+  'salvesta_uuena'              => 'save_as_new',
+  'tarneaadress'                => 'ship_to',
+  'uuenda'                      => 'update',
+  'jah'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/pe b/sql-ledger/locale/ee/pe
new file mode 100644 (file)
index 0000000..7ce3815
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Lisa',
+  'Add Project'                 => 'Lisa Projekt',
+  'All'                         => 'Kõik',
+  'Continue'                    => 'Edasi',
+  'Delete'                      => 'Kustuta',
+  'Description'                 => 'Selgitus',
+  'Edit Project'                => 'Muuda Projekti',
+  'Number'                      => 'Kood',
+  'Orphaned'                    => 'Seosteta',
+  'Project'                     => 'Projekt',
+  'Project Number missing!'     => 'Projekti number puudub',
+  'Project deleted!'            => 'Projekt kustutatud',
+  'Project saved!'              => 'Projekt salvestatud',
+  'Projects'                    => 'Projektid',
+  'Save'                        => 'Salvesta',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'lisa'                        => 'add',
+  'edasi'                       => 'continue',
+  'kustuta'                     => 'delete',
+  'salvesta'                    => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/rc b/sql-ledger/locale/ee/rc
new file mode 100644 (file)
index 0000000..af52fde
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Balance'                     => 'Bilanss',
+  'Cleared Balance'             => 'Puhastatud bilanss',
+  'Continue'                    => 'Edasi',
+  'Date'                        => 'Kuupäev',
+  'Deposit'                     => 'Tarnimata',
+  'Description'                 => 'Selgitus',
+  'Difference'                  => 'Vahe',
+  'Done'                        => 'Teostatud',
+  'Exchangerate Difference'     => 'Valuutakursi muutus',
+  'From'                        => 'Alates',
+  'Out of balance!'             => 'Bilanss ei klapi!',
+  'Payment'                     => 'Maksed',
+  'Reconciliation'              => 'Tasaarveldused',
+  'Select all'                  => 'Vali kõik',
+  'Source'                      => 'Allikas',
+  'Statement Balance'           => 'Bilansiaruanne',
+  'Update'                      => 'Uuenda',
+  'to'                          => 'kuni',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'edasi'                       => 'continue',
+  'teostatud'                   => 'done',
+  'vali_kõik'                   => 'select_all',
+  'uuenda'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ee/rp b/sql-ledger/locale/ee/rp
new file mode 100644 (file)
index 0000000..9d0e6bc
--- /dev/null
@@ -0,0 +1,120 @@
+$self{texts} = {
+  'AP Aging'                    => 'Võlad',
+  'AR Aging'                    => 'Võlglased',
+  'Account'                     => 'Konto',
+  'Accounts'                    => 'Kontod',
+  'Amount'                      => 'Summa',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprill',
+  'Attachment'                  => 'Kaasatud fail',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Balance'                     => 'Bilanss',
+  'Balance Sheet'               => 'Bilansitabel',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Kassapõhine',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Võrdlus perioodiga',
+  'Continue'                    => 'Edasi',
+  'Copies'                      => 'koopiat',
+  'Credit'                      => 'Kreedit',
+  'Current'                     => 'Praegune',
+  'Customer'                    => 'Klient',
+  'Date'                        => 'Kuupäev',
+  'Debit'                       => 'Deebet',
+  'Dec'                         => 'Dets',
+  'December'                    => 'Detsember',
+  'Decimalplaces'               => 'Komakohti',
+  'Department'                  => 'Osakond',
+  'Description'                 => 'Selgitus',
+  'Due'                         => 'Tasuda',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'E-mail teatis',
+  'Feb'                         => 'Veebr',
+  'February'                    => 'Veebruar',
+  'From'                        => 'Alates',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Päis',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Dokumendisisene',
+  'Include in Report'           => 'Kaasa aruandesse',
+  'Income Statement'            => 'Kasumiaruanne',
+  'Invoice'                     => 'Arve',
+  'Jan'                         => 'Jaan',
+  'January'                     => 'Jaanuar',
+  'Jul'                         => 'Juul',
+  'July'                        => 'Juuli',
+  'Jun'                         => 'Juun',
+  'June'                        => 'Juuni',
+  'Mar'                         => 'Mär',
+  'March'                       => 'Märts',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Teade',
+  'N/A'                         => 'Puudub',
+  'Nothing selected!'           => 'Midagi ei ole valitud',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktoober',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Maksed',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Trüki',
+  'Printer'                     => 'Printer',
+  'Project Number'              => 'Projekti number',
+  'Receipts'                    => 'Laekumised',
+  'Report for'                  => 'Aruanne',
+  'Retained Earnings'           => 'Jaotamata kasum',
+  'Screen'                      => 'Ekraan',
+  'Select all'                  => 'Vali kõik',
+  'Select postscript or PDF!'   => 'Vali kas postscript või PDF',
+  'Sep'                         => 'Sept',
+  'September'                   => 'September',
+  'Source'                      => 'Allikas',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Aruanne',
+  'Statement sent to'           => 'Saata aruanne aadressil',
+  'Statements sent to printer!' => 'Saata aruanne printerile',
+  'Subject'                     => 'Pealkiri',
+  'Subtotal'                    => 'Vahesumma',
+  'Tax'                         => 'Maks',
+  'Tax collected'               => 'Kogutud maksud',
+  'Tax paid'                    => 'Makstud makse',
+  'Total'                       => 'Kokku',
+  'Trial Balance'               => 'Proovibilanss',
+  'Vendor'                      => 'Hankija',
+  'as at'                       => 'Seisuga',
+  'collected on sales'          => 'kogutud müügilt',
+  'for Period'                  => 'Periood',
+  'paid on purchases'           => 'makstud ostudelt',
+  'to'                          => 'kuni',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_accounts'               => 'list_accounts',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'edasi'                       => 'continue',
+  'e_mail'                      => 'e_mail',
+  'trüki'                       => 'print',
+  'vali_kõik'                   => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/COPYING b/sql-ledger/locale/en_GB/COPYING
new file mode 100644 (file)
index 0000000..ceaa769
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2003
+#
+# British English texts:
+#
+#  Author:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/en_GB/LANGUAGE b/sql-ledger/locale/en_GB/LANGUAGE
new file mode 100644 (file)
index 0000000..bed69f7
--- /dev/null
@@ -0,0 +1 @@
+British English
diff --git a/sql-ledger/locale/en_GB/admin b/sql-ledger/locale/en_GB/admin
new file mode 100644 (file)
index 0000000..580d1c6
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Access Control',
+  'Accounting'                  => 'Accounting',
+  'Add User'                    => 'Add User',
+  'Address'                     => 'Address',
+  'Administration'              => 'Administration',
+  'Administrator'               => 'Administrator',
+  'All Datasets up to date!'    => 'All Datasets up to date!',
+  'Change Admin Password'       => 'Change Admin Password',
+  'Change Password'             => 'Change Password',
+  'Character Set'               => 'Character Set',
+  'Click on login name to edit!' => 'Click on login name to edit!',
+  'Company'                     => 'Company',
+  'Connect to'                  => 'Connect to',
+  'Continue'                    => 'Continue',
+  'Create Chart of Accounts'    => 'Create Chart of Accounts',
+  'Create Dataset'              => 'Create Dataset',
+  'DBI not installed!'          => 'DBI not installed!',
+  'Database'                    => 'Database',
+  'Database Administration'     => 'Database Administration',
+  'Database Driver not checked!' => 'Database Driver not checked!',
+  'Database User missing!'      => 'Database User missing!',
+  'Dataset'                     => 'Dataset',
+  'Dataset missing!'            => 'Dataset missing!',
+  'Dataset updated!'            => 'Dataset updated!',
+  'Date Format'                 => 'Date Format',
+  'Delete'                      => 'Delete',
+  'Delete Dataset'              => 'Delete Dataset',
+  'Directory'                   => 'Directory',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'E-mail',
+  'Edit User'                   => 'Edit User',
+  'Existing Datasets'           => 'Existing Datasets',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Hostname missing!',
+  'Incorrect Password!'         => 'Incorrect Password!',
+  'Language'                    => 'Language',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Leave host and port field empty unless you want to make a remote connection.',
+  'Login'                       => 'Login',
+  'Multibyte Encoding'          => 'Multibyte Encoding',
+  'Name'                        => 'Name',
+  'New Templates'               => 'New Templates',
+  'No Database Drivers available!' => 'No Database Drivers available!',
+  'No Dataset selected!'        => 'No Dataset selected!',
+  'Nothing to delete!'          => 'Nothing to delete!',
+  'Number Format'               => 'Number Format',
+  'Oracle Database Administration' => 'Oracle Database Administration',
+  'Password'                    => 'Password',
+  'Password changed!'           => 'Password changed!',
+  'Pg Database Administration'  => 'Pg Database Administration',
+  'Phone'                       => 'Phone',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port missing!',
+  'Printer'                     => 'Printer',
+  'Save'                        => 'Save',
+  'Select a Dataset to delete and press "Continue"' => 'Select a Dataset to delete and press "Continue"',
+  'Setup Templates'             => 'Setup Templates',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'Signature',
+  'Stylesheet'                  => 'Stylesheet',
+  'Templates'                   => 'Templates',
+  'The following Datasets are not in use and can be deleted' => 'The following Datasets are not in use and can be deleted',
+  'The following Datasets need to be updated' => 'The following Datasets need to be updated',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.',
+  'Update Dataset'              => 'Update Dataset',
+  'Use Templates'               => 'Use Templates',
+  'User'                        => 'User',
+  'User deleted!'               => 'User deleted!',
+  'User saved!'                 => 'User saved!',
+  'Version'                     => 'Version',
+  'You must enter a host and port for local and remote connections!' => 'You must enter a host and port for local and remote connections!',
+  'does not exist'              => 'does not exist',
+  'is already a member!'        => 'is already a member!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'locked!',
+  'successfully created!'       => 'successfully created!',
+  'successfully deleted!'       => 'successfully deleted!',
+  'website'                     => 'website',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'add_user'                    => 'add_user',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'login'                       => 'login',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/all b/sql-ledger/locale/en_GB/all
new file mode 100644 (file)
index 0000000..e45542a
--- /dev/null
@@ -0,0 +1,499 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Purchases',
+  'AP Aging'                    => 'Creditor Aging',
+  'AP Transaction'              => 'Purchase Transaction',
+  'AP Transactions'             => 'Purchase Transactions',
+  'AR'                          => 'Sales',
+  'AR Aging'                    => 'Debtor Aging',
+  'AR Transaction'              => 'Sales Transaction',
+  'AR Transactions'             => 'Sales Transactions',
+  'About'                       => '',
+  'Access Control'              => '',
+  'Account'                     => '',
+  'Account Number'              => '',
+  'Account Number missing!'     => '',
+  'Account Type'                => '',
+  'Account Type missing!'       => '',
+  'Account deleted!'            => '',
+  'Account saved!'              => '',
+  'Accounting'                  => '',
+  'Accounting Menu'             => '',
+  'Accounts'                    => '',
+  'Active'                      => '',
+  'Add'                         => '',
+  'Add Account'                 => '',
+  'Add Accounts Payables Transaction' => 'Add Purchase Transaction',
+  'Add Accounts Receivables Transaction' => 'Add Sales Transaction',
+  'Add Assembly'                => '',
+  'Add Customer'                => '',
+  'Add GIFI'                    => '',
+  'Add General Ledger Transaction' => '',
+  'Add Group'                   => '',
+  'Add Part'                    => '',
+  'Add Project'                 => '',
+  'Add Purchase Order'          => '',
+  'Add Sales Invoice'           => '',
+  'Add Sales Order'             => '',
+  'Add Service'                 => '',
+  'Add Transaction'             => '',
+  'Add User'                    => '',
+  'Add Vendor'                  => '',
+  'Add Vendor Invoice'          => '',
+  'Address'                     => '',
+  'Administration'              => '',
+  'Administrator'               => '',
+  'All'                         => '',
+  'All Datasets up to date!'    => '',
+  'Amount'                      => '',
+  'Amount Due'                  => '',
+  'Amount does not equal applied!' => '',
+  'Amount missing!'             => '',
+  'Applied'                     => '',
+  'Apr'                         => '',
+  'April'                       => '',
+  'Are you sure you want to delete Invoice Number' => '',
+  'Are you sure you want to delete Order Number' => '',
+  'Are you sure you want to delete Transaction' => '',
+  'Assemblies'                  => '',
+  'Assemblies restocked!'       => '',
+  'Assembly Number missing!'    => '',
+  'Asset'                       => '',
+  'Attachment'                  => '',
+  'Audit Control'               => '',
+  'Aug'                         => '',
+  'August'                      => '',
+  'BOM'                         => '',
+  'Backup'                      => '',
+  'Backup sent to'              => '',
+  'Balance'                     => '',
+  'Balance Sheet'               => '',
+  'Bcc'                         => '',
+  'Bin'                         => '',
+  'Books are open'              => '',
+  'Bought'                      => '',
+  'Business Number'             => '',
+  'C'                           => '',
+  'COGS'                        => '',
+  'Cannot delete account!'      => '',
+  'Cannot delete customer!'     => '',
+  'Cannot delete default account!' => '',
+  'Cannot delete invoice!'      => '',
+  'Cannot delete item!'         => '',
+  'Cannot delete order!'        => '',
+  'Cannot delete transaction!'  => '',
+  'Cannot delete vendor!'       => '',
+  'Cannot have a value in both Debit and Credit!' => '',
+  'Cannot post a transaction without a value!' => '',
+  'Cannot post invoice for a closed period!' => '',
+  'Cannot post invoice!'        => '',
+  'Cannot post payment for a closed period!' => '',
+  'Cannot post payment!'        => '',
+  'Cannot post transaction for a closed period!' => '',
+  'Cannot post transaction!'    => '',
+  'Cannot process payment for a closed period!' => '',
+  'Cannot save account!'        => '',
+  'Cannot save order!'          => '',
+  'Cannot save preferences!'    => '',
+  'Cannot stock assemblies!'    => '',
+  'Cash'                        => '',
+  'Cash based'                  => '',
+  'Cc'                          => '',
+  'Change Admin Password'       => '',
+  'Change Password'             => '',
+  'Character Set'               => '',
+  'Chart of Accounts'           => '',
+  'Check'                       => 'Cheque',
+  'Check printed!'              => '',
+  'Check printing failed!'      => '',
+  'Cleared Balance'             => '',
+  'Click on login name to edit!' => '',
+  'Close Books up to'           => '',
+  'Closed'                      => '',
+  'Company'                     => '',
+  'Compare to'                  => '',
+  'Confirm!'                    => '',
+  'Connect to'                  => '',
+  'Contact'                     => '',
+  'Continue'                    => '',
+  'Copies'                      => '',
+  'Copy to COA'                 => '',
+  'Create Chart of Accounts'    => '',
+  'Create Dataset'              => '',
+  'Credit'                      => '',
+  'Credit Limit'                => '',
+  'Curr'                        => '',
+  'Currency'                    => '',
+  'Current'                     => '',
+  'Customer'                    => '',
+  'Customer deleted!'           => '',
+  'Customer missing!'           => '',
+  'Customer not on file!'       => '',
+  'Customer saved!'             => '',
+  'Customers'                   => '',
+  'DBI not installed!'          => '',
+  'Database'                    => '',
+  'Database Administration'     => '',
+  'Database Driver not checked!' => '',
+  'Database Host'               => '',
+  'Database User missing!'      => '',
+  'Dataset'                     => '',
+  'Dataset missing!'            => '',
+  'Dataset updated!'            => '',
+  'Date'                        => '',
+  'Date Format'                 => '',
+  'Date Paid'                   => '',
+  'Date missing!'               => '',
+  'Debit'                       => '',
+  'Debit and credit out of balance!' => '',
+  'Dec'                         => '',
+  'December'                    => '',
+  'Decimalplaces'               => '',
+  'Delete'                      => '',
+  'Delete Account'              => '',
+  'Delete Dataset'              => '',
+  'Delivery Date'               => '',
+  'Deposit'                     => '',
+  'Description'                 => '',
+  'Difference'                  => '',
+  'Directory'                   => '',
+  'Discount'                    => '',
+  'Done'                        => '',
+  'Drawing'                     => '',
+  'Driver'                      => '',
+  'Dropdown Limit'              => '',
+  'Due'                         => '',
+  'Due Date'                    => '',
+  'Due Date missing!'           => '',
+  'E-mail'                      => '',
+  'E-mail Statement to'         => '',
+  'E-mail address missing!'     => '',
+  'Edit'                        => '',
+  'Edit Account'                => '',
+  'Edit Accounts Payables Transaction' => 'Edit Creditor Transaction',
+  'Edit Accounts Receivables Transaction' => 'Edit Debtor Transaction',
+  'Edit Assembly'               => '',
+  'Edit Customer'               => '',
+  'Edit GIFI'                   => '',
+  'Edit General Ledger Transaction' => '',
+  'Edit Group'                  => '',
+  'Edit Part'                   => '',
+  'Edit Preferences for'        => '',
+  'Edit Project'                => '',
+  'Edit Purchase Order'         => '',
+  'Edit Sales Invoice'          => '',
+  'Edit Sales Order'            => '',
+  'Edit Service'                => '',
+  'Edit Template'               => '',
+  'Edit User'                   => '',
+  'Edit Vendor'                 => '',
+  'Edit Vendor Invoice'         => '',
+  'Employee'                    => '',
+  'Enforce transaction reversal for all dates' => '',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => '',
+  'Equity'                      => '',
+  'Exch'                        => '',
+  'Exchangerate'                => '',
+  'Exchangerate Difference'     => '',
+  'Exchangerate for payment missing!' => '',
+  'Exchangerate missing!'       => '',
+  'Existing Datasets'           => '',
+  'Expense'                     => '',
+  'Expense Account'             => '',
+  'Expense/Asset'               => '',
+  'Extended'                    => '',
+  'Fax'                         => '',
+  'Feb'                         => '',
+  'February'                    => '',
+  'Foreign Exchange Gain'       => '',
+  'Foreign Exchange Loss'       => '',
+  'From'                        => '',
+  'GIFI'                        => '',
+  'GIFI deleted!'               => '',
+  'GIFI missing!'               => '',
+  'GIFI saved!'                 => '',
+  'GL Transaction'              => '',
+  'General Ledger'              => '',
+  'Goods & Services'            => '',
+  'Group'                       => '',
+  'Group Items'                 => '',
+  'Group deleted!'              => '',
+  'Group missing!'              => '',
+  'Group saved!'                => '',
+  'Groups'                      => '',
+  'HTML Templates'              => '',
+  'Heading'                     => '',
+  'Host'                        => '',
+  'Hostname missing!'           => '',
+  'ID'                          => '',
+  'Image'                       => '',
+  'In-line'                     => '',
+  'Include in Report'           => '',
+  'Include in drop-down menus'  => '',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Include this account on debtor/creditor forms to set debtor/creditor taxable?',
+  'Income'                      => 'Revenue',
+  'Income Account'              => 'Revenue Account',
+  'Income Statement'            => '',
+  'Incorrect Dataset version!'  => '',
+  'Incorrect Password!'         => '',
+  'Individual Items'            => '',
+  'Inventory'                   => '',
+  'Inventory Account'           => '',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => '',
+  'Inventory quantity must be zero before you can set this part obsolete!' => '',
+  'Invoice'                     => '',
+  'Invoice Date'                => '',
+  'Invoice Date missing!'       => '',
+  'Invoice Number'              => '',
+  'Invoice Number missing!'     => '',
+  'Invoice deleted!'            => '',
+  'Invoice posted!'             => '',
+  'Invoices'                    => '',
+  'Is this a summary account to record' => '',
+  'Item deleted!'               => '',
+  'Item not on file!'           => '',
+  'Jan'                         => '',
+  'January'                     => '',
+  'Jul'                         => '',
+  'July'                        => '',
+  'Jun'                         => '',
+  'June'                        => '',
+  'LaTeX Templates'             => '',
+  'Language'                    => '',
+  'Last Cost'                   => '',
+  'Last Invoice Number'         => '',
+  'Last Numbers & Default Accounts' => '',
+  'Last Purchase Order Number'  => '',
+  'Last Sales Order Number'     => '',
+  'Leave host and port field empty unless you want to make a remote connection.' => '',
+  'Liability'                   => '',
+  'Licensed to'                 => '',
+  'Line Total'                  => '',
+  'Link'                        => '',
+  'Link Accounts'               => '',
+  'List Accounts'               => '',
+  'List GIFI'                   => '',
+  'List Price'                  => '',
+  'List Transactions'           => '',
+  'Login'                       => '',
+  'Logout'                      => '',
+  'Make'                        => '',
+  'Mar'                         => '',
+  'March'                       => '',
+  'May'                         => '',
+  'May '                        => '',
+  'Message'                     => '',
+  'Microfiche'                  => '',
+  'Model'                       => '',
+  'Multibyte Encoding'          => '',
+  'N/A'                         => '',
+  'Name'                        => '',
+  'Name missing!'               => '',
+  'New Templates'               => '',
+  'No'                          => '',
+  'No Database Drivers available!' => '',
+  'No Dataset selected!'        => '',
+  'No email address for'        => '',
+  'No.'                         => '',
+  'Notes'                       => '',
+  'Nothing applied!'            => '',
+  'Nothing selected!'           => '',
+  'Nothing to delete!'          => '',
+  'Nov'                         => '',
+  'November'                    => '',
+  'Number'                      => '',
+  'Number Format'               => '',
+  'Number missing in Row'       => '',
+  'O'                           => '',
+  'Obsolete'                    => '',
+  'Oct'                         => '',
+  'October'                     => '',
+  'On Hand'                     => '',
+  'On Order'                    => '',
+  'Open'                        => '',
+  'Oracle Database Administration' => '',
+  'Order'                       => '',
+  'Order Date'                  => '',
+  'Order Date missing!'         => '',
+  'Order Entry'                 => '',
+  'Order Number'                => '',
+  'Order Number missing!'       => '',
+  'Order deleted!'              => '',
+  'Order saved!'                => '',
+  'Ordered'                     => '',
+  'Orphaned'                    => '',
+  'Out of balance!'             => '',
+  'PDF'                         => '',
+  'Packing List'                => '',
+  'Packing List Date missing!'  => '',
+  'Packing List Number missing!' => '',
+  'Paid'                        => '',
+  'Paid in full'                => '',
+  'Part'                        => '',
+  'Part Number missing!'        => '',
+  'Parts'                       => '',
+  'Parts Inventory'             => '',
+  'Password'                    => '',
+  'Password changed!'           => '',
+  'Payables'                    => '',
+  'Payment'                     => '',
+  'Payment date missing!'       => '',
+  'Payment posted!'             => '',
+  'Payments'                    => '',
+  'Pg Database Administration'  => '',
+  'Phone'                       => '',
+  'Port'                        => '',
+  'Port missing!'               => '',
+  'Post'                        => '',
+  'Post as new'                 => '',
+  'Postscript'                  => '',
+  'Preferences'                 => '',
+  'Preferences saved!'          => '',
+  'Price'                       => '',
+  'Print'                       => '',
+  'Printer'                     => '',
+  'Project'                     => '',
+  'Project Number'              => '',
+  'Project Number missing!'     => '',
+  'Project deleted!'            => '',
+  'Project not on file!'        => '',
+  'Project saved!'              => '',
+  'Projects'                    => '',
+  'Purchase Order'              => '',
+  'Purchase Orders'             => '',
+  'Qty'                         => '',
+  'ROP'                         => '',
+  'Rate'                        => '',
+  'Recd'                        => '',
+  'Receipt'                     => '',
+  'Receipt printed!'            => '',
+  'Receipt printing failed!'    => '',
+  'Receipts'                    => '',
+  'Receivables'                 => '',
+  'Reconciliation'              => '',
+  'Record in'                   => '',
+  'Reference'                   => '',
+  'Reference missing!'          => '',
+  'Remaining'                   => '',
+  'Report for'                  => '',
+  'Reports'                     => '',
+  'Required by'                 => '',
+  'Retained Earnings'           => '',
+  'Sales'                       => '',
+  'Sales Invoice'               => '',
+  'Sales Order'                 => '',
+  'Sales Orders'                => '',
+  'Salesperson'                 => '',
+  'Save'                        => '',
+  'Save as new'                 => '',
+  'Save to File'                => '',
+  'Screen'                      => '',
+  'Select a Dataset to delete and press "Continue"' => '',
+  'Select all'                  => '',
+  'Select from one of the items below' => '',
+  'Select from one of the names below' => '',
+  'Select from one of the projects below' => '',
+  'Select postscript or PDF!'   => '',
+  'Sell Price'                  => '',
+  'Send by E-Mail'              => '',
+  'Sep'                         => '',
+  'September'                   => '',
+  'Service'                     => '',
+  'Service Items'               => '',
+  'Service Number missing!'     => '',
+  'Services'                    => '',
+  'Setup Templates'             => '',
+  'Ship'                        => '',
+  'Ship to'                     => '',
+  'Ship via'                    => '',
+  'Short'                       => '',
+  'Signature'                   => '',
+  'Sold'                        => '',
+  'Source'                      => '',
+  'Standard'                    => '',
+  'Statement'                   => '',
+  'Statement Balance'           => '',
+  'Statement sent to'           => '',
+  'Statements sent to printer!' => '',
+  'Stock'                       => '',
+  'Stock Assembly'              => '',
+  'Stylesheet'                  => '',
+  'Subject'                     => '',
+  'Subtotal'                    => '',
+  'System'                      => '',
+  'Tax'                         => '',
+  'Tax Accounts'                => '',
+  'Tax Included'                => '',
+  'Tax collected'               => '',
+  'Tax paid'                    => '',
+  'Taxable'                     => '',
+  'Template saved!'             => '',
+  'Templates'                   => '',
+  'Terms: Net'                  => '',
+  'The following Datasets are not in use and can be deleted' => '',
+  'The following Datasets need to be updated' => '',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => '',
+  'To'                          => '',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => '',
+  'Top Level'                   => '',
+  'Total'                       => '',
+  'Transaction Date missing!'   => '',
+  'Transaction deleted!'        => '',
+  'Transaction posted!'         => '',
+  'Transaction reversal enforced for all dates' => '',
+  'Transaction reversal enforced up to' => '',
+  'Transactions'                => '',
+  'Transactions exist, cannot delete customer!' => '',
+  'Transactions exist, cannot delete vendor!' => '',
+  'Transactions exist; cannot delete account!' => '',
+  'Trial Balance'               => '',
+  'Unit'                        => '',
+  'Unit of measure'             => '',
+  'Update'                      => '',
+  'Update Dataset'              => '',
+  'Updated'                     => '',
+  'Use Templates'               => '',
+  'User'                        => '',
+  'User deleted!'               => '',
+  'User saved!'                 => '',
+  'Vendor'                      => '',
+  'Vendor Invoice'              => '',
+  'Vendor deleted!'             => '',
+  'Vendor missing!'             => '',
+  'Vendor not on file!'         => '',
+  'Vendor saved!'               => '',
+  'Vendors'                     => '',
+  'Version'                     => '',
+  'Weight'                      => '',
+  'Weight Unit'                 => '',
+  'What type of item is this?'  => '',
+  'Year End'                    => '',
+  'Yes'                         => '',
+  'You are logged out!'         => '',
+  'You did not enter a name!'   => '',
+  'You must enter a host and port for local and remote connections!' => '',
+  'as at'                       => '',
+  'collected on sales'          => '',
+  'days'                        => '',
+  'does not exist'              => '',
+  'ea'                          => '',
+  'emailed to'                  => '',
+  'for Period'                  => '',
+  'hr'                          => '',
+  'is already a member!'        => '',
+  'is not a member!'            => '',
+  'localhost'                   => '',
+  'locked!'                     => '',
+  'paid on purchases'           => '',
+  'sent to printer'             => '',
+  'successfully created!'       => '',
+  'successfully deleted!'       => '',
+  'to'                          => '',
+  'website'                     => '',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/am b/sql-ledger/locale/en_GB/am
new file mode 100644 (file)
index 0000000..6e322ca
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Purchases',
+  'AR'                          => 'Sales',
+  'Account'                     => 'Account',
+  'Account Number'              => 'Account Number',
+  'Account Number missing!'     => 'Account Number missing!',
+  'Account Type'                => 'Account Type',
+  'Account Type missing!'       => 'Account Type missing!',
+  'Account deleted!'            => 'Account deleted!',
+  'Account saved!'              => 'Account saved!',
+  'Add Account'                 => 'Add Account',
+  'Add GIFI'                    => 'Add GIFI',
+  'Address'                     => 'Address',
+  'Asset'                       => 'Asset',
+  'Audit Control'               => 'Audit Control',
+  'Backup sent to'              => 'Backup sent to',
+  'Books are open'              => 'Books are open',
+  'Business Number'             => 'Business Number',
+  'COGS'                        => 'COGS',
+  'Cannot delete account!'      => 'Cannot delete account!',
+  'Cannot delete default account!' => 'Cannot delete default account!',
+  'Cannot save account!'        => 'Cannot save account!',
+  'Cannot save preferences!'    => 'Cannot save preferences!',
+  'Character Set'               => 'Character Set',
+  'Chart of Accounts'           => 'Chart of Accounts',
+  'Close Books up to'           => 'Close Books up to',
+  'Company'                     => 'Company',
+  'Continue'                    => 'Continue',
+  'Copy to COA'                 => 'Copy to COA',
+  'Credit'                      => 'Credit',
+  'Date Format'                 => 'Date Format',
+  'Debit'                       => 'Debit',
+  'Delete'                      => 'Delete',
+  'Delete Account'              => 'Delete Account',
+  'Description'                 => 'Description',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'E-mail',
+  'Edit'                        => 'Edit',
+  'Edit Account'                => 'Edit Account',
+  'Edit GIFI'                   => 'Edit GIFI',
+  'Edit Preferences for'        => 'Edit Preferences for',
+  'Edit Template'               => 'Edit Template',
+  'Enforce transaction reversal for all dates' => 'Enforce transaction reversal for all dates',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies',
+  'Equity'                      => 'Equity',
+  'Expense'                     => 'Expense',
+  'Expense Account'             => 'Expense Account',
+  'Expense/Asset'               => 'Expense/Asset',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Foreign Exchange Gain',
+  'Foreign Exchange Loss'       => 'Foreign Exchange Loss',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI deleted!',
+  'GIFI missing!'               => 'GIFI missing!',
+  'GIFI saved!'                 => 'GIFI saved!',
+  'Heading'                     => 'Heading',
+  'Include in drop-down menus'  => 'Include in drop-down menus',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Include this account on debtor/creditor forms to set debtor/creditor taxable?',
+  'Income'                      => 'Revenue',
+  'Income Account'              => 'Revenue Account',
+  'Inventory'                   => 'Inventory',
+  'Inventory Account'           => 'Inventory Account',
+  'Is this a summary account to record' => 'Is this a summary account to record',
+  'Language'                    => 'Language',
+  'Last Invoice Number'         => 'Last Invoice Number',
+  'Last Numbers & Default Accounts' => 'Last Numbers & Default Accounts',
+  'Last Purchase Order Number'  => 'Last Purchase Order Number',
+  'Last Sales Order Number'     => 'Last Sales Order Number',
+  'Liability'                   => 'Liability',
+  'Link'                        => 'Link',
+  'Name'                        => 'Name',
+  'No'                          => 'No',
+  'No email address for'        => 'No email address for',
+  'Number'                      => 'Number',
+  'Number Format'               => 'Number Format',
+  'Parts Inventory'             => 'Parts Inventory',
+  'Password'                    => 'Password',
+  'Payables'                    => 'Payables',
+  'Payment'                     => 'Payment',
+  'Phone'                       => 'Phone',
+  'Preferences saved!'          => 'Preferences saved!',
+  'Rate'                        => 'Rate',
+  'Receivables'                 => 'Receivables',
+  'Sales'                       => 'Sales',
+  'Save'                        => 'Save',
+  'Service Items'               => 'Service Items',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'Signature',
+  'Stylesheet'                  => 'Stylesheet',
+  'Tax'                         => 'Tax',
+  'Tax Accounts'                => 'Tax Accounts',
+  'Template saved!'             => 'Template saved!',
+  'Transaction reversal enforced for all dates' => 'Transaction reversal enforced for all dates',
+  'Transaction reversal enforced up to' => 'Transaction reversal enforced up to',
+  'Transactions exist; cannot delete account!' => 'Transactions exist; cannot delete account!',
+  'Weight Unit'                 => 'Weight Unit',
+  'Year End'                    => 'Year End',
+  'Yes'                         => 'Yes',
+  'does not exist'              => 'does not exist',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'add_account'                 => 'add_account',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'edit_account'                => 'edit_account',
+  'save'                        => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/ap b/sql-ledger/locale/en_GB/ap
new file mode 100644 (file)
index 0000000..4cad878
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Purchase Transaction',
+  'AP Transactions'             => 'Purchase Transactions',
+  'Account'                     => 'Account',
+  'Add Accounts Payables Transaction' => 'Add Purchase Transaction',
+  'Address'                     => 'Address',
+  'Amount'                      => 'Amount',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Transaction' => 'Are you sure you want to delete Transaction',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cannot post transaction for a closed period!' => 'Cannot post transaction for a closed period!',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'Closed',
+  'Confirm!'                    => 'Confirm!',
+  'Continue'                    => 'Continue',
+  'Currency'                    => 'Currency',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Date',
+  'Date Paid'                   => 'Date Paid',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Delete',
+  'Description'                 => 'Description',
+  'Due Date'                    => 'Due Date',
+  'Due Date missing!'           => 'Due Date missing!',
+  'Edit Accounts Payables Transaction' => 'Edit Creditor Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'Exch',
+  'Exchangerate'                => 'Exchangerate',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Feb'                         => 'Feb',
+  'February'                    => 'February',
+  'From'                        => 'From',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Include in Report',
+  'Invoice'                     => 'Invoice',
+  'Invoice Date'                => 'Invoice Date',
+  'Invoice Date missing!'       => 'Invoice Date missing!',
+  'Invoice Number'              => 'Invoice Number',
+  'Invoice Number missing!'     => 'Invoice Number missing!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'January',
+  'Jul'                         => 'Jul',
+  'July'                        => 'July',
+  'Jun'                         => 'Jun',
+  'June'                        => 'June',
+  'Mar'                         => 'Mar',
+  'March'                       => 'March',
+  'May'                         => 'May',
+  'May '                        => 'May ',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Number',
+  'Oct'                         => 'Oct',
+  'October'                     => 'October',
+  'Open'                        => 'Open',
+  'Order'                       => 'Order',
+  'Order Number'                => 'Order Number',
+  'Paid'                        => 'Paid',
+  'Payment date missing!'       => 'Payment date missing!',
+  'Payments'                    => 'Payments',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Source',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Tax',
+  'Tax Included'                => 'Tax Included',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Vendor',
+  'Vendor Invoice'              => 'Vendor Invoice',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Yes',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'purchase_transaction'        => 'ap_transaction',
+  'add_purchase_transaction'    => 'add_accounts_payables_transaction',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit_creditor_transaction'   => 'edit_accounts_payables_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/ar b/sql-ledger/locale/en_GB/ar
new file mode 100644 (file)
index 0000000..926d80a
--- /dev/null
@@ -0,0 +1,134 @@
+$self{texts} = {
+  'AR Transaction'              => 'Sales Transaction',
+  'AR Transactions'             => 'Sales Transactions',
+  'Account'                     => 'Account',
+  'Add Accounts Receivables Transaction' => 'Add Sales Transaction',
+  'Address'                     => 'Address',
+  'Amount'                      => 'Amount',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Transaction' => 'Are you sure you want to delete Transaction',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cannot post transaction for a closed period!' => 'Cannot post transaction for a closed period!',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'Closed',
+  'Confirm!'                    => 'Confirm!',
+  'Continue'                    => 'Continue',
+  'Credit Limit'                => 'Credit Limit',
+  'Currency'                    => 'Currency',
+  'Customer'                    => 'Customer',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Date',
+  'Date Paid'                   => 'Date Paid',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Delete',
+  'Description'                 => 'Description',
+  'Due Date'                    => 'Due Date',
+  'Due Date missing!'           => 'Due Date missing!',
+  'Edit Accounts Receivables Transaction' => 'Edit Debtor Transaction',
+  'Exch'                        => 'Exch',
+  'Exchangerate'                => 'Exchangerate',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Feb'                         => 'Feb',
+  'February'                    => 'February',
+  'From'                        => 'From',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Include in Report',
+  'Invoice'                     => 'Invoice',
+  'Invoice Date'                => 'Invoice Date',
+  'Invoice Date missing!'       => 'Invoice Date missing!',
+  'Invoice Number'              => 'Invoice Number',
+  'Invoice Number missing!'     => 'Invoice Number missing!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'January',
+  'Jul'                         => 'Jul',
+  'July'                        => 'July',
+  'Jun'                         => 'Jun',
+  'June'                        => 'June',
+  'Mar'                         => 'Mar',
+  'March'                       => 'March',
+  'May'                         => 'May',
+  'May '                        => 'May ',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Number',
+  'Oct'                         => 'Oct',
+  'October'                     => 'October',
+  'Open'                        => 'Open',
+  'Order'                       => 'Order',
+  'Order Number'                => 'Order Number',
+  'Paid'                        => 'Paid',
+  'Payment date missing!'       => 'Payment date missing!',
+  'Payments'                    => 'Payments',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Remaining'                   => 'Remaining',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Salesperson'                 => 'Salesperson',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Ship via'                    => 'Ship via',
+  'Source'                      => 'Source',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Tax',
+  'Tax Included'                => 'Tax Included',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Yes',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'sales_transaction'           => 'ar_transaction',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/arap b/sql-ledger/locale/en_GB/arap
new file mode 100644 (file)
index 0000000..fe711dd
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Address',
+  'Continue'                    => 'Continue',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Description'                 => 'Description',
+  'Number'                      => 'Number',
+  'Project not on file!'        => 'Project not on file!',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'vendor_invoice'              => 'vendor_invoice',
+  'continue'                    => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/bp b/sql-ledger/locale/en_GB/bp
new file mode 100644 (file)
index 0000000..fa9e347
--- /dev/null
@@ -0,0 +1,54 @@
+$self{texts} = {
+  'Account'                     => 'Account',
+  'Are you sure you want to remove the marked entries from the queue?' => 'Are you sure you want to remove the marked entries from the queue?',
+  'Cannot remove files!'        => 'Cannot remove files!',
+  'Checks'                      => 'Cheques',
+  'Confirm!'                    => 'Confirm!',
+  'Continue'                    => 'Continue',
+  'Customer'                    => 'Debtor',
+  'Date'                        => 'Date',
+  'From'                        => 'From',
+  'Invoice'                     => 'Invoice',
+  'Invoice Number'              => 'Invoice Number',
+  'Marked entries printed!'     => 'Marked entries printed!',
+  'Order'                       => 'Order',
+  'Order Number'                => 'Order Number',
+  'Packing Lists'               => 'Packing Lists',
+  'Print'                       => 'Print',
+  'Printing ... '               => 'Printing ... ',
+  'Purchase Orders'             => 'Purchase Orders',
+  'Quotation'                   => 'Quotation',
+  'Quotation Number'            => 'Quotation Number',
+  'Quotations'                  => 'Quotations',
+  'RFQs'                        => 'RFQs',
+  'Receipts'                    => 'Receipts',
+  'Reference'                   => 'Reference',
+  'Remove'                      => 'Remove',
+  'Removed spoolfiles!'         => 'Removed spoolfiles!',
+  'Removing marked entries from queue ...' => 'Removing marked entries from queue ...',
+  'Sales Invoices'              => 'Sales Invoices',
+  'Sales Orders'                => 'Sales Orders',
+  'Select all'                  => 'Select all',
+  'Spoolfile'                   => 'Spoolfile',
+  'To'                          => 'To',
+  'Vendor'                      => 'Creditor',
+  'Yes'                         => 'Yes',
+  'done'                        => 'done',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'list_spool'                  => 'list_spool',
+  'print'                       => 'print',
+  'remove'                      => 'remove',
+  'search'                      => 'search',
+  'select_all'                  => 'select_all',
+  'yes'                         => 'yes',
+  'continue'                    => 'continue',
+  'print'                       => 'print',
+  'remove'                      => 'remove',
+  'select_all'                  => 'select_all',
+  'yes'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/ca b/sql-ledger/locale/en_GB/ca
new file mode 100644 (file)
index 0000000..ed5ddc2
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Account',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Balance'                     => 'Balance',
+  'Chart of Accounts'           => 'Chart of Accounts',
+  'Credit'                      => 'Credit',
+  'Date'                        => 'Date',
+  'Debit'                       => 'Debit',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Description'                 => 'Description',
+  'Feb'                         => 'Feb',
+  'February'                    => 'February',
+  'From'                        => 'From',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Include in Report',
+  'Jan'                         => 'Jan',
+  'January'                     => 'January',
+  'Jul'                         => 'Jul',
+  'July'                        => 'July',
+  'Jun'                         => 'Jun',
+  'June'                        => 'June',
+  'List Transactions'           => 'List Transactions',
+  'Mar'                         => 'Mar',
+  'March'                       => 'March',
+  'May'                         => 'May',
+  'May '                        => 'May ',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Oct'                         => 'Oct',
+  'October'                     => 'October',
+  'Reference'                   => 'Reference',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Subtotal'                    => 'Subtotal',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'list_transactions'           => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/cp b/sql-ledger/locale/en_GB/cp
new file mode 100644 (file)
index 0000000..fd0ade6
--- /dev/null
@@ -0,0 +1,77 @@
+$self{texts} = {
+  'Account'                     => 'Account',
+  'Address'                     => 'Address',
+  'Amount'                      => 'Amount',
+  'Amount does not equal applied!' => 'Amount does not equal applied!',
+  'Amount missing!'             => 'Amount missing!',
+  'Applied'                     => 'Applied',
+  'Cannot post payment!'        => 'Cannot post payment!',
+  'Cannot process payment for a closed period!' => 'Cannot process payment for a closed period!',
+  'Check'                       => 'Cheque',
+  'Check printed!'              => 'Check printed!',
+  'Check printing failed!'      => 'Check printing failed!',
+  'Continue'                    => 'Continue',
+  'Currency'                    => 'Currency',
+  'Customer'                    => 'Customer',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Date',
+  'Date missing!'               => 'Date missing!',
+  'Description'                 => 'Description',
+  'Due'                         => 'Due',
+  'Exchangerate'                => 'Exchangerate',
+  'From'                        => 'From',
+  'Invoice'                     => 'Invoice',
+  'Invoices'                    => 'Invoices',
+  'Nothing applied!'            => 'Nothing applied!',
+  'Number'                      => 'Number',
+  'Paid in full'                => 'Paid in full',
+  'Payment'                     => 'Payment',
+  'Payment posted!'             => 'Payment posted!',
+  'Post'                        => 'Post',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Printer',
+  'Project not on file!'        => 'Project not on file!',
+  'Receipt'                     => 'Receipt',
+  'Receipt printed!'            => 'Receipt printed!',
+  'Receipt printing failed!'    => 'Receipt printing failed!',
+  'Reference'                   => 'Reference',
+  'Screen'                      => 'Screen',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Vendor',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'continue'                    => 'continue',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/ct b/sql-ledger/locale/en_GB/ct
new file mode 100644 (file)
index 0000000..3daa8f4
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Add',
+  'Address'                     => 'Address',
+  'All'                         => 'All',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Cannot delete customer!',
+  'Cannot delete vendor!'       => 'Cannot delete vendor!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continue',
+  'Credit Limit'                => 'Credit Limit',
+  'Customer deleted!'           => 'Customer deleted!',
+  'Customer saved!'             => 'Customer saved!',
+  'Customers'                   => 'Customers',
+  'Delete'                      => 'Delete',
+  'Discount'                    => 'Discount',
+  'E-mail'                      => 'E-mail',
+  'Edit Customer'               => 'Edit Customer',
+  'Edit Vendor'                 => 'Edit Vendor',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Include in Report',
+  'Invoice'                     => 'Invoice',
+  'Name'                        => 'Name',
+  'Name missing!'               => 'Name missing!',
+  'Notes'                       => 'Notes',
+  'Number'                      => 'Number',
+  'Order'                       => 'Order',
+  'Orphaned'                    => 'Orphaned',
+  'Phone'                       => 'Phone',
+  'Save'                        => 'Save',
+  'Ship to'                     => 'Ship to',
+  'Tax Included'                => 'Tax Included',
+  'Taxable'                     => 'Taxable',
+  'Terms: Net'                  => 'Terms: Net',
+  'Transactions exist, cannot delete customer!' => 'Transactions exist, cannot delete customer!',
+  'Transactions exist, cannot delete vendor!' => 'Transactions exist, cannot delete vendor!',
+  'Vendor deleted!'             => 'Vendor deleted!',
+  'Vendor saved!'               => 'Vendor saved!',
+  'Vendors'                     => 'Vendors',
+  'days'                        => 'days',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'invoice'                     => 'invoice',
+  'order'                       => 'order',
+  'save'                        => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/gl b/sql-ledger/locale/en_GB/gl
new file mode 100644 (file)
index 0000000..dae8e86
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Purchase Transaction',
+  'AR Transaction'              => 'Sales Transaction',
+  'Account'                     => 'Account',
+  'Add General Ledger Transaction' => 'Add General Ledger Transaction',
+  'Address'                     => 'Address',
+  'All'                         => 'All',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Transaction' => 'Are you sure you want to delete Transaction',
+  'Asset'                       => 'Asset',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Balance'                     => 'Balance',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot have a value in both Debit and Credit!' => 'Cannot have a value in both Debit and Credit!',
+  'Cannot post a transaction without a value!' => 'Cannot post a transaction without a value!',
+  'Cannot post transaction for a closed period!' => 'Cannot post transaction for a closed period!',
+  'Confirm!'                    => 'Confirm!',
+  'Continue'                    => 'Continue',
+  'Credit'                      => 'Credit',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Date',
+  'Debit'                       => 'Debit',
+  'Debit and credit out of balance!' => 'Debit and credit out of balance!',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Delete',
+  'Description'                 => 'Description',
+  'Edit General Ledger Transaction' => 'Edit General Ledger Transaction',
+  'Equity'                      => 'Equity',
+  'Expense'                     => 'Expense',
+  'Feb'                         => 'Feb',
+  'February'                    => 'February',
+  'From'                        => 'From',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'GL Transaction',
+  'General Ledger'              => 'General Ledger',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Include in Report',
+  'Income'                      => 'Revenue',
+  'Jan'                         => 'Jan',
+  'January'                     => 'January',
+  'Jul'                         => 'Jul',
+  'July'                        => 'July',
+  'Jun'                         => 'Jun',
+  'June'                        => 'June',
+  'Liability'                   => 'Liability',
+  'Mar'                         => 'Mar',
+  'March'                       => 'March',
+  'May'                         => 'May',
+  'May '                        => 'May ',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Number',
+  'Oct'                         => 'Oct',
+  'October'                     => 'October',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Reference'                   => 'Reference',
+  'Reference missing!'          => 'Reference missing!',
+  'Reports'                     => 'Reports',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Source',
+  'Subtotal'                    => 'Subtotal',
+  'Transaction Date missing!'   => 'Transaction Date missing!',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor Invoice'              => 'Vendor Invoice',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Yes',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'purchase_transaction'        => 'ap_transaction',
+  'sales_transaction'           => 'ar_transaction',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'gl_transaction'              => 'gl_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/ic b/sql-ledger/locale/en_GB/ic
new file mode 100644 (file)
index 0000000..2e61619
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Active',
+  'Add'                         => 'Add',
+  'Add Assembly'                => 'Add Assembly',
+  'Add Part'                    => 'Add Part',
+  'Add Purchase Order'          => 'Add Purchase Order',
+  'Add Sales Order'             => 'Add Sales Order',
+  'Add Service'                 => 'Add Service',
+  'Address'                     => 'Address',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Assemblies'                  => 'Assemblies',
+  'Assemblies restocked!'       => 'Assemblies restocked!',
+  'Assembly Number missing!'    => 'Assembly Number missing!',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Bought'                      => 'Bought',
+  'COGS'                        => 'COGS',
+  'Cannot delete item!'         => 'Cannot delete item!',
+  'Cannot stock assemblies!'    => 'Cannot stock assemblies!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Closed',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continue',
+  'Copies'                      => 'Copies',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Delete',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Description',
+  'Drawing'                     => 'Drawing',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mail address missing!',
+  'Edit Assembly'               => 'Edit Assembly',
+  'Edit Part'                   => 'Edit Part',
+  'Edit Service'                => 'Edit Service',
+  'Expense'                     => 'Expense',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'February',
+  'From'                        => 'From',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'Image'                       => 'Image',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Include in Report',
+  'Income'                      => 'Revenue',
+  'Individual Items'            => 'Individual Items',
+  'Inventory'                   => 'Inventory',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Inventory quantity must be zero before you can set this assembly obsolete!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Inventory quantity must be zero before you can set this part obsolete!',
+  'Invoice'                     => 'Invoice',
+  'Invoice Date missing!'       => 'Invoice Date missing!',
+  'Invoice Number'              => 'Invoice Number',
+  'Invoice Number missing!'     => 'Invoice Number missing!',
+  'Item deleted!'               => 'Item deleted!',
+  'Item not on file!'           => 'Item not on file!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'January',
+  'Jul'                         => 'Jul',
+  'July'                        => 'July',
+  'Jun'                         => 'Jun',
+  'June'                        => 'June',
+  'Last Cost'                   => 'Last Cost',
+  'Line Total'                  => 'Line Total',
+  'Link Accounts'               => 'Link Accounts',
+  'List Price'                  => 'List Price',
+  'Make'                        => 'Make',
+  'Mar'                         => 'Mar',
+  'March'                       => 'March',
+  'May'                         => 'May',
+  'May '                        => 'May ',
+  'Message'                     => 'Message',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Model',
+  'Name'                        => 'Name',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Number',
+  'Number missing in Row'       => 'Number missing in Row',
+  'Obsolete'                    => 'Obsolete',
+  'Oct'                         => 'Oct',
+  'October'                     => 'October',
+  'On Hand'                     => 'On Hand',
+  'On Order'                    => 'On Order',
+  'Order'                       => 'Order',
+  'Order Date missing!'         => 'Order Date missing!',
+  'Order Number'                => 'Order Number',
+  'Order Number missing!'       => 'Order Number missing!',
+  'Ordered'                     => 'Ordered',
+  'Orphaned'                    => 'Orphaned',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Packing List',
+  'Packing List Date missing!'  => 'Packing List Date missing!',
+  'Packing List Number missing!' => 'Packing List Number missing!',
+  'Part'                        => 'Part',
+  'Part Number missing!'        => 'Part Number missing!',
+  'Parts'                       => 'Parts',
+  'Phone'                       => 'Phone',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Price',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Purchase Order',
+  'Qty'                         => 'Qty',
+  'ROP'                         => 'ROP',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Required by',
+  'Sales'                       => 'Sales',
+  'Sales Order'                 => 'Sales Order',
+  'Save'                        => 'Save',
+  'Save as new'                 => 'Save as new',
+  'Screen'                      => 'Screen',
+  'Select from one of the items below' => 'Select from one of the items below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sell Price'                  => 'Sell Price',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Service',
+  'Service Number missing!'     => 'Service Number missing!',
+  'Services'                    => 'Services',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Short'                       => 'Short',
+  'Sold'                        => 'Sold',
+  'Stock'                       => 'Stock',
+  'Stock Assembly'              => 'Stock Assembly',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Tax',
+  'To'                          => 'To',
+  'Top Level'                   => 'Top Level',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unit',
+  'Unit of measure'             => 'Unit of measure',
+  'Update'                      => 'Update',
+  'Updated'                     => 'Updated',
+  'Weight'                      => 'Weight',
+  'What type of item is this?'  => 'What type of item is this?',
+  'ea'                          => 'ea',
+  'emailed to'                  => 'emailed to',
+  'hr'                          => 'hr',
+  'sent to printer'             => 'sent to printer',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'add'                         => 'add',
+  'add_assembly'                => 'add_assembly',
+  'add_part'                    => 'add_part',
+  'add_service'                 => 'add_service',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit_assembly'               => 'edit_assembly',
+  'edit_part'                   => 'edit_part',
+  'edit_service'                => 'edit_service',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/io b/sql-ledger/locale/en_GB/io
new file mode 100644 (file)
index 0000000..1deb6dc
--- /dev/null
@@ -0,0 +1,108 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Add Purchase Order',
+  'Add Sales Order'             => 'Add Sales Order',
+  'Address'                     => 'Address',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continue',
+  'Copies'                      => 'Copies',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Description',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mail address missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'February',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'In-line'                     => 'In-line',
+  'Invoice'                     => 'Invoice',
+  'Invoice Date missing!'       => 'Invoice Date missing!',
+  'Invoice Number missing!'     => 'Invoice Number missing!',
+  'Item not on file!'           => 'Item not on file!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'January',
+  'Jul'                         => 'Jul',
+  'July'                        => 'July',
+  'Jun'                         => 'Jun',
+  'June'                        => 'June',
+  'Mar'                         => 'Mar',
+  'March'                       => 'March',
+  'May'                         => 'May',
+  'May '                        => 'May ',
+  'Message'                     => 'Message',
+  'Name'                        => 'Name',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Number',
+  'Number missing in Row'       => 'Number missing in Row',
+  'Oct'                         => 'Oct',
+  'October'                     => 'October',
+  'Order'                       => 'Order',
+  'Order Date missing!'         => 'Order Date missing!',
+  'Order Number missing!'       => 'Order Number missing!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Packing List',
+  'Packing List Date missing!'  => 'Packing List Date missing!',
+  'Packing List Number missing!' => 'Packing List Number missing!',
+  'Part'                        => 'Part',
+  'Phone'                       => 'Phone',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Price',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Purchase Order',
+  'Qty'                         => 'Qty',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Required by',
+  'Sales Order'                 => 'Sales Order',
+  'Screen'                      => 'Screen',
+  'Select from one of the items below' => 'Select from one of the items below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Service',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Subject'                     => 'Subject',
+  'To'                          => 'To',
+  'Unit'                        => 'Unit',
+  'What type of item is this?'  => 'What type of item is this?',
+  'emailed to'                  => 'emailed to',
+  'sent to printer'             => 'sent to printer',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'continue'                    => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/ir b/sql-ledger/locale/en_GB/ir
new file mode 100644 (file)
index 0000000..a87c72a
--- /dev/null
@@ -0,0 +1,180 @@
+$self{texts} = {
+  'Account'                     => 'Account',
+  'Add Purchase Order'          => 'Add Purchase Order',
+  'Add Sales Order'             => 'Add Sales Order',
+  'Add Vendor Invoice'          => 'Add Vendor Invoice',
+  'Address'                     => 'Address',
+  'Amount'                      => 'Amount',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Invoice Number' => 'Are you sure you want to delete Invoice Number',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'Cannot post invoice for a closed period!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirm!',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continue',
+  'Copies'                      => 'Copies',
+  'Currency'                    => 'Currency',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Date',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Delete',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Description',
+  'Due Date'                    => 'Due Date',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mail address missing!',
+  'Edit Vendor Invoice'         => 'Edit Vendor Invoice',
+  'Exch'                        => 'Exch',
+  'Exchangerate'                => 'Exchangerate',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'February',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'In-line'                     => 'In-line',
+  'Invoice'                     => 'Invoice',
+  'Invoice Date'                => 'Invoice Date',
+  'Invoice Date missing!'       => 'Invoice Date missing!',
+  'Invoice Number'              => 'Invoice Number',
+  'Invoice Number missing!'     => 'Invoice Number missing!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => 'Item not on file!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'January',
+  'Jul'                         => 'Jul',
+  'July'                        => 'July',
+  'Jun'                         => 'Jun',
+  'June'                        => 'June',
+  'Mar'                         => 'Mar',
+  'March'                       => 'March',
+  'May'                         => 'May',
+  'May '                        => 'May ',
+  'Message'                     => 'Message',
+  'Name'                        => 'Name',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Number',
+  'Number missing in Row'       => 'Number missing in Row',
+  'Oct'                         => 'Oct',
+  'October'                     => 'October',
+  'Order'                       => 'Order',
+  'Order Date missing!'         => 'Order Date missing!',
+  'Order Number'                => 'Order Number',
+  'Order Number missing!'       => 'Order Number missing!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Packing List',
+  'Packing List Date missing!'  => 'Packing List Date missing!',
+  'Packing List Number missing!' => 'Packing List Number missing!',
+  'Part'                        => 'Part',
+  'Payment date missing!'       => 'Payment date missing!',
+  'Payments'                    => 'Payments',
+  'Phone'                       => 'Phone',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Price',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Purchase Order',
+  'Qty'                         => 'Qty',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'Record in',
+  'Required by'                 => 'Required by',
+  'Sales Order'                 => 'Sales Order',
+  'Screen'                      => 'Screen',
+  'Select from one of the items below' => 'Select from one of the items below',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Service',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Source'                      => 'Source',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Tax Included',
+  'To'                          => 'To',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unit',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Vendor',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'What type of item is this?',
+  'Yes'                         => 'Yes',
+  'ea'                          => 'ea',
+  'emailed to'                  => 'emailed to',
+  'sent to printer'             => 'sent to printer',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/is b/sql-ledger/locale/en_GB/is
new file mode 100644 (file)
index 0000000..bbfa3f0
--- /dev/null
@@ -0,0 +1,187 @@
+$self{texts} = {
+  'Account'                     => 'Account',
+  'Add Purchase Order'          => 'Add Purchase Order',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'Add Sales Order',
+  'Address'                     => 'Address',
+  'Amount'                      => 'Amount',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Invoice Number' => 'Are you sure you want to delete Invoice Number',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'Cannot post invoice for a closed period!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirm!',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continue',
+  'Copies'                      => 'Copies',
+  'Credit Limit'                => 'Credit Limit',
+  'Currency'                    => 'Currency',
+  'Customer'                    => 'Customer',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Date',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Delete',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Description',
+  'Due Date'                    => 'Due Date',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mail address missing!',
+  'Edit Sales Invoice'          => 'Edit Sales Invoice',
+  'Exch'                        => 'Exch',
+  'Exchangerate'                => 'Exchangerate',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'February',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'In-line'                     => 'In-line',
+  'Invoice'                     => 'Invoice',
+  'Invoice Date'                => 'Invoice Date',
+  'Invoice Date missing!'       => 'Invoice Date missing!',
+  'Invoice Number'              => 'Invoice Number',
+  'Invoice Number missing!'     => 'Invoice Number missing!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => 'Item not on file!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'January',
+  'Jul'                         => 'Jul',
+  'July'                        => 'July',
+  'Jun'                         => 'Jun',
+  'June'                        => 'June',
+  'Mar'                         => 'Mar',
+  'March'                       => 'March',
+  'May'                         => 'May',
+  'May '                        => 'May ',
+  'Message'                     => 'Message',
+  'Name'                        => 'Name',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Number',
+  'Number missing in Row'       => 'Number missing in Row',
+  'Oct'                         => 'Oct',
+  'October'                     => 'October',
+  'Order'                       => 'Order',
+  'Order Date missing!'         => 'Order Date missing!',
+  'Order Number'                => 'Order Number',
+  'Order Number missing!'       => 'Order Number missing!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Packing List',
+  'Packing List Date missing!'  => 'Packing List Date missing!',
+  'Packing List Number missing!' => 'Packing List Number missing!',
+  'Part'                        => 'Part',
+  'Payment date missing!'       => 'Payment date missing!',
+  'Payments'                    => 'Payments',
+  'Phone'                       => 'Phone',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Price',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Purchase Order',
+  'Qty'                         => 'Qty',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'Record in',
+  'Remaining'                   => 'Remaining',
+  'Required by'                 => 'Required by',
+  'Sales Order'                 => 'Sales Order',
+  'Screen'                      => 'Screen',
+  'Select from one of the items below' => 'Select from one of the items below',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Service',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Source'                      => 'Source',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Tax Included',
+  'To'                          => 'To',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unit',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'What type of item is this?',
+  'Yes'                         => 'Yes',
+  'ea'                          => 'ea',
+  'emailed to'                  => 'emailed to',
+  'sent to printer'             => 'sent to printer',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'e_mail'                      => 'e_mail',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/login b/sql-ledger/locale/en_GB/login
new file mode 100644 (file)
index 0000000..262a18c
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'About',
+  'Database Host'               => 'Database Host',
+  'Dataset'                     => 'Dataset',
+  'Incorrect Dataset version!'  => 'Incorrect Dataset version!',
+  'Incorrect Password!'         => 'Incorrect Password!',
+  'Licensed to'                 => 'Licensed to',
+  'Login'                       => 'Login',
+  'Name'                        => 'Name',
+  'Password'                    => 'Password',
+  'User'                        => 'User',
+  'Version'                     => 'Version',
+  'You are logged out!'         => 'You are logged out!',
+  'You did not enter a name!'   => 'You did not enter a name!',
+  'is not a member!'            => 'is not a member!',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'login'                       => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/menu b/sql-ledger/locale/en_GB/menu
new file mode 100644 (file)
index 0000000..4e47815
--- /dev/null
@@ -0,0 +1,73 @@
+$self{texts} = {
+  'AP'                          => 'Purchases',
+  'AP Aging'                    => 'Creditor Aging',
+  'AR'                          => 'Sales',
+  'AR Aging'                    => 'Debtor Aging',
+  'Accounting Menu'             => 'Accounting Menu',
+  'Add Account'                 => 'Add Account',
+  'Add Assembly'                => 'Add Assembly',
+  'Add Customer'                => 'Add Customer',
+  'Add GIFI'                    => 'Add GIFI',
+  'Add Group'                   => 'Add Group',
+  'Add Part'                    => 'Add Part',
+  'Add Project'                 => 'Add Project',
+  'Add Service'                 => 'Add Service',
+  'Add Transaction'             => 'Add Transaction',
+  'Add Vendor'                  => 'Add Vendor',
+  'Assemblies'                  => 'Assemblies',
+  'Audit Control'               => 'Audit Control',
+  'Backup'                      => 'Backup',
+  'Balance Sheet'               => 'Balance Sheet',
+  'Cash'                        => 'Cash',
+  'Chart of Accounts'           => 'Chart of Accounts',
+  'Check'                       => 'Cheque',
+  'Customers'                   => 'Customers',
+  'General Ledger'              => 'General Ledger',
+  'Goods & Services'            => 'Goods & Services',
+  'Groups'                      => 'Groups',
+  'HTML Templates'              => 'HTML Templates',
+  'Income Statement'            => 'Income Statement',
+  'Invoice'                     => 'Invoice',
+  'LaTeX Templates'             => 'LaTeX Templates',
+  'List Accounts'               => 'List Accounts',
+  'List GIFI'                   => 'List GIFI',
+  'Logout'                      => 'Logout',
+  'Order Entry'                 => 'Order Entry',
+  'Packing List'                => 'Packing List',
+  'Parts'                       => 'Parts',
+  'Payment'                     => 'Payment',
+  'Payments'                    => 'Payments',
+  'Preferences'                 => 'Preferences',
+  'Projects'                    => 'Projects',
+  'Purchase Order'              => 'Purchase Order',
+  'Purchase Orders'             => 'Purchase Orders',
+  'Receipt'                     => 'Receipt',
+  'Receipts'                    => 'Receipts',
+  'Reconciliation'              => 'Reconciliation',
+  'Reports'                     => 'Reports',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Sales Order'                 => 'Sales Order',
+  'Sales Orders'                => 'Sales Orders',
+  'Save to File'                => 'Save to File',
+  'Send by E-Mail'              => 'Send by E-Mail',
+  'Services'                    => 'Services',
+  'Statement'                   => 'Statement',
+  'Stock Assembly'              => 'Stock Assembly',
+  'Stylesheet'                  => 'Stylesheet',
+  'System'                      => 'System',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'Transactions'                => 'Transactions',
+  'Trial Balance'               => 'Trial Balance',
+  'Vendor Invoice'              => 'Vendor Invoice',
+  'Vendors'                     => 'Vendors',
+  'Version'                     => 'Version',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/oe b/sql-ledger/locale/en_GB/oe
new file mode 100644 (file)
index 0000000..2dfbb47
--- /dev/null
@@ -0,0 +1,202 @@
+$self{texts} = {
+  'Add'                         => 'Add',
+  'Add Purchase Order'          => 'Add Purchase Order',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'Add Sales Order',
+  'Add Vendor Invoice'          => 'Add Vendor Invoice',
+  'Address'                     => 'Address',
+  'Amount'                      => 'Amount',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Order Number' => 'Are you sure you want to delete Order Number',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Cannot delete order!',
+  'Cannot save order!'          => 'Cannot save order!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Closed',
+  'Confirm!'                    => 'Confirm!',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continue',
+  'Copies'                      => 'Copies',
+  'Credit Limit'                => 'Credit Limit',
+  'Curr'                        => 'Curr',
+  'Currency'                    => 'Currency',
+  'Customer'                    => 'Customer',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Date',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Delete',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Description',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mail address missing!',
+  'Edit Purchase Order'         => 'Edit Purchase Order',
+  'Edit Sales Order'            => 'Edit Sales Order',
+  'Exchangerate'                => 'Exchangerate',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'February',
+  'From'                        => 'From',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'ID'                          => 'ID',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Include in Report',
+  'Invoice'                     => 'Invoice',
+  'Invoice Date missing!'       => 'Invoice Date missing!',
+  'Invoice Number missing!'     => 'Invoice Number missing!',
+  'Item not on file!'           => 'Item not on file!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'January',
+  'Jul'                         => 'Jul',
+  'July'                        => 'July',
+  'Jun'                         => 'Jun',
+  'June'                        => 'June',
+  'Mar'                         => 'Mar',
+  'March'                       => 'March',
+  'May'                         => 'May',
+  'May '                        => 'May ',
+  'Message'                     => 'Message',
+  'Name'                        => 'Name',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Number',
+  'Number missing in Row'       => 'Number missing in Row',
+  'O'                           => 'O',
+  'Oct'                         => 'Oct',
+  'October'                     => 'October',
+  'Open'                        => 'Open',
+  'Order'                       => 'Order',
+  'Order Date'                  => 'Order Date',
+  'Order Date missing!'         => 'Order Date missing!',
+  'Order Number'                => 'Order Number',
+  'Order Number missing!'       => 'Order Number missing!',
+  'Order deleted!'              => 'Order deleted!',
+  'Order saved!'                => 'Order saved!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Packing List',
+  'Packing List Date missing!'  => 'Packing List Date missing!',
+  'Packing List Number missing!' => 'Packing List Number missing!',
+  'Part'                        => 'Part',
+  'Phone'                       => 'Phone',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Price',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Purchase Order',
+  'Purchase Orders'             => 'Purchase Orders',
+  'Qty'                         => 'Qty',
+  'Recd'                        => 'Recd',
+  'Remaining'                   => 'Remaining',
+  'Required by'                 => 'Required by',
+  'Sales Order'                 => 'Sales Order',
+  'Sales Orders'                => 'Sales Orders',
+  'Save'                        => 'Save',
+  'Save as new'                 => 'Save as new',
+  'Screen'                      => 'Screen',
+  'Select from one of the items below' => 'Select from one of the items below',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Service',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Tax',
+  'Tax Included'                => 'Tax Included',
+  'Terms: Net'                  => 'Terms: Net',
+  'To'                          => 'To',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unit',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Vendor',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'What type of item is this?',
+  'Yes'                         => 'Yes',
+  'days'                        => 'days',
+  'ea'                          => 'ea',
+  'emailed to'                  => 'emailed to',
+  'sent to printer'             => 'sent to printer',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'e_mail'                      => 'e_mail',
+  'invoice'                     => 'invoice',
+  'print'                       => 'print',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/pe b/sql-ledger/locale/en_GB/pe
new file mode 100644 (file)
index 0000000..58cd57a
--- /dev/null
@@ -0,0 +1,45 @@
+$self{texts} = {
+  'Add'                         => 'Add',
+  'Add Group'                   => 'Add Group',
+  'Add Project'                 => 'Add Project',
+  'All'                         => 'All',
+  'Continue'                    => 'Continue',
+  'Delete'                      => 'Delete',
+  'Description'                 => 'Description',
+  'Edit Group'                  => 'Edit Group',
+  'Edit Project'                => 'Edit Project',
+  'Group'                       => 'Group',
+  'Group deleted!'              => 'Group deleted!',
+  'Group missing!'              => 'Group missing!',
+  'Group saved!'                => 'Group saved!',
+  'Groups'                      => 'Groups',
+  'Number'                      => 'Number',
+  'Orphaned'                    => 'Orphaned',
+  'Project'                     => 'Project',
+  'Project Number missing!'     => 'Project Number missing!',
+  'Project deleted!'            => 'Project deleted!',
+  'Project saved!'              => 'Project saved!',
+  'Projects'                    => 'Projects',
+  'Save'                        => 'Save',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_partsgroup_footer'      => 'form_partsgroup_footer',
+  'form_partsgroup_header'      => 'form_partsgroup_header',
+  'form_project_footer'         => 'form_project_footer',
+  'form_project_header'         => 'form_project_header',
+  'partsgroup_report'           => 'partsgroup_report',
+  'project_report'              => 'project_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'save'                        => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/rc b/sql-ledger/locale/en_GB/rc
new file mode 100644 (file)
index 0000000..952c378
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Account',
+  'Balance'                     => 'Balance',
+  'Cleared Balance'             => 'Cleared Balance',
+  'Continue'                    => 'Continue',
+  'Date'                        => 'Date',
+  'Deposit'                     => 'Deposit',
+  'Description'                 => 'Description',
+  'Difference'                  => 'Difference',
+  'Done'                        => 'Done',
+  'Exchangerate Difference'     => 'Exchangerate Difference',
+  'From'                        => 'From',
+  'Out of balance!'             => 'Out of balance!',
+  'Payment'                     => 'Payment',
+  'Reconciliation'              => 'Reconciliation',
+  'Select all'                  => 'Select all',
+  'Source'                      => 'Source',
+  'Statement Balance'           => 'Statement Balance',
+  'Update'                      => 'Update',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'continue'                    => 'continue',
+  'done'                        => 'done',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/en_GB/rp b/sql-ledger/locale/en_GB/rp
new file mode 100644 (file)
index 0000000..a66828e
--- /dev/null
@@ -0,0 +1,119 @@
+$self{texts} = {
+  'AP Aging'                    => 'Creditor Aging',
+  'AR Aging'                    => 'Debtor Aging',
+  'Account'                     => 'Account',
+  'Accounts'                    => 'Accounts',
+  'Amount'                      => 'Amount',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Aug',
+  'August'                      => 'August',
+  'Balance'                     => 'Balance',
+  'Balance Sheet'               => 'Balance Sheet',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Cash based',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Compare to',
+  'Continue'                    => 'Continue',
+  'Copies'                      => 'Copies',
+  'Credit'                      => 'Credit',
+  'Current'                     => 'Current',
+  'Customer'                    => 'Customer',
+  'Date'                        => 'Date',
+  'Debit'                       => 'Debit',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Decimalplaces'               => 'Decimalplaces',
+  'Description'                 => 'Description',
+  'Due'                         => 'Due',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'E-mail Statement to',
+  'Feb'                         => 'Feb',
+  'February'                    => 'February',
+  'From'                        => 'From',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Heading',
+  'ID'                          => 'ID',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Include in Report',
+  'Income Statement'            => 'Income Statement',
+  'Invoice'                     => 'Invoice',
+  'Jan'                         => 'Jan',
+  'January'                     => 'January',
+  'Jul'                         => 'Jul',
+  'July'                        => 'July',
+  'Jun'                         => 'Jun',
+  'June'                        => 'June',
+  'Mar'                         => 'Mar',
+  'March'                       => 'March',
+  'May'                         => 'May',
+  'May '                        => 'May ',
+  'Message'                     => 'Message',
+  'N/A'                         => 'N/A',
+  'Nothing selected!'           => 'Nothing selected!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Oct'                         => 'Oct',
+  'October'                     => 'October',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Payments',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Printer',
+  'Project Number'              => 'Project Number',
+  'Receipts'                    => 'Receipts',
+  'Report for'                  => 'Report for',
+  'Retained Earnings'           => 'Retained Earnings',
+  'Screen'                      => 'Screen',
+  'Select all'                  => 'Select all',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Source',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Statement',
+  'Statement sent to'           => 'Statement sent to',
+  'Statements sent to printer!' => 'Statements sent to printer!',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Tax',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'Total'                       => 'Total',
+  'Trial Balance'               => 'Trial Balance',
+  'Vendor'                      => 'Vendor',
+  'as at'                       => 'as at',
+  'collected on sales'          => 'collected on sales',
+  'for Period'                  => 'for Period',
+  'paid on purchases'           => 'paid on purchases',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_accounts'               => 'list_accounts',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'print'                       => 'print',
+  'select_all'                  => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/es/COPYING b/sql-ledger/locale/es/COPYING
new file mode 100644 (file)
index 0000000..bf7ca4b
--- /dev/null
@@ -0,0 +1,26 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2002
+#
+# Spanish texts:
+#
+#  Author: Maria Gabriela Fong <mgfong@maga.tzo.org>
+#          John Stoddart <jstypo@imagencolor.com.ve>
+#          Federico Montesino Pouzols <fedemp@arrok.com>
+#          Tomás Pereira <topec@percar.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/es/LANGUAGE b/sql-ledger/locale/es/LANGUAGE
new file mode 100644 (file)
index 0000000..c1a0de2
--- /dev/null
@@ -0,0 +1 @@
+Spanish
diff --git a/sql-ledger/locale/es/Num2text b/sql-ledger/locale/es/Num2text
new file mode 100644 (file)
index 0000000..a5424ff
--- /dev/null
@@ -0,0 +1,195 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+
+
+sub init {
+  my $self = shift;
+
+  %{ $self->{numbername} } =
+                   (0 => 'cero',
+                    1 => 'un',
+                '1o' => 'uno',
+                    2 => 'dos',
+                   3 => 'tres',
+                   4 => 'cuatro',
+                   5 => 'cinco',
+                   6 => 'seis',
+                   7 => 'siete',
+                   8 => 'ocho',
+                   9 => 'nueve',
+                  10 => 'diez',
+                  11 => 'once',
+                  12 => 'doce',
+                  13 => 'trece',
+                  14 => 'catorce',
+                  15 => 'quince',
+                  16 => 'dieciséis',
+                  17 => 'diecisiete',
+                  18 => 'dieciocho',
+                  19 => 'diecinueve',
+                  20 => 'veinte',
+                  21 => 'veintiún',
+               '21o' => 'veintiuno',
+                  22 => 'veintidós',
+                  23 => 'veintitrés',
+                  24 => 'veinticuatro',
+                  25 => 'veinticinco',
+                  26 => 'veintiséis',
+                  27 => 'veintisiete',
+                  28 => 'veintiocho',
+                  29 => 'veintinueve',
+                  30 => 'treinta',
+                  40 => 'cuarenta',
+                  50 => 'cincuenta',
+                  60 => 'sesenta',
+                  70 => 'setenta',
+                  80 => 'ochenta',
+                  90 => 'noventa',
+                10**2 => 'ciento',
+                10**3 => 'mil',
+               10**6 => 'millón',
+               10**9 => 'millardo',
+              10**12 => 'billón',
+               );
+
+}
+
+
+sub num2text {
+  my ($self, $amount) = @_;
+
+  return $self->{numbername}{0} unless $amount;
+
+  my @textnumber = ();
+
+  # split amount into chunks of 3
+  my @num = reverse split //, $amount;
+  my @numblock = ();
+  my $stripun = 0;
+  my @a = ();
+  my $i;
+
+  while (@num) {
+    @a = ();
+    for (1 .. 3) {
+      push @a, shift @num;
+    }
+    push @numblock, join / /, reverse @a;
+  }
+  
+  # special case for 1000
+  if ($numblock[1] eq '1' && $numblock[0] gt '000') {
+    # remove first array element from textnumber
+    $stripun = 1;
+  }
+
+  while (@numblock) {
+
+    $i = $#numblock;
+    @num = split //, $numblock[$i];
+    
+    $numblock[$i] *= 1;
+
+    if ($numblock[$i] == 0) {
+      pop @numblock;
+      next;
+    }
+    
+    if ($numblock[$i] > 99) {
+      if ($num[0] == 1) {
+       push @textnumber, $self->{numbername}{10**2};
+      } else {
+       # the one from hundreds, append cientos
+       push @textnumber, $self->{numbername}{$num[0]}.$self->{numbername}{10**2}.'s';
+      }
+     
+      # reduce numblock
+      $numblock[$i] -= $num[0] * 100;
+    }
+    
+    if ($numblock[$i] > 9) {
+      # tens
+      push @textnumber, $self->format_ten($numblock[$i], $i);
+    } elsif ($numblock[$i] > 0) {
+      # ones
+      $num = $numblock[$i];
+      $num .= 'o' if ($num == 1 && $i == 0);
+      push @textnumber, $self->{numbername}{$num};
+    }
+    
+    # add thousand, million
+    if ($i) {
+      $num = 10**($i * 3);
+      if ($numblock[$i] > 1) {
+       if ($i == 2 || $i == 4) {
+         $a = $self->{numbername}{$num}."es";
+         $a =~ s/ó/o/;
+         push @textnumber, $a;
+       } else {
+         if ($i == 1) {
+           push @textnumber, $self->{numbername}{$num};
+         } else {
+           push @textnumber, $self->{numbername}{$num}.'s';
+         }
+       }
+      } else {
+       push @textnumber, $self->{numbername}{$num};
+      }
+    }
+      
+    pop @numblock;
+    
+  }
+
+  shift @textnumber if $stripun;
+
+  join ' ', @textnumber;
+
+}
+
+
+sub format_ten {
+  my ($self, $amount, $i) = @_;
+  
+  my $textnumber = "";
+  my @num = split //, $amount;
+
+  if ($amount > 30) {
+    $textnumber = $self->{numbername}{$num[0]*10};
+    $amount = $num[1];
+  } else {
+    $amount .= 'o' if ($num[1] == 1 && $i == 0);
+    $textnumber = $self->{numbername}{$amount};
+    $amount = 0;
+  }
+
+  $textnumber .= " y ".$self->{numbername}{$amount} if $amount;
+
+  $textnumber;
+  
+}
+
+
+1;
+
diff --git a/sql-ledger/locale/es/admin b/sql-ledger/locale/es/admin
new file mode 100644 (file)
index 0000000..a78f755
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Control de Acceso',
+  'Accounting'                  => 'Contabilidad',
+  'Add User'                    => 'Añadir usuario',
+  'Address'                     => 'Dirección',
+  'Administration'              => 'Administración',
+  'Administrator'               => 'Administrador',
+  'All Datasets up to date!'    => 'Todas las bases de datos están actualizadas',
+  'Change Admin Password'       => 'Cambiar la contraseña del administrador',
+  'Change Password'             => 'Cambiar contraseña',
+  'Character Set'               => 'Conjunto de caracteres',
+  'Click on login name to edit!' => 'Haga clic en el nombre de usuario por
+editar',
+  'Company'                     => 'Compañía',
+  'Connect to'                  => 'Conectar a',
+  'Continue'                    => 'Continuar',
+  'Create Chart of Accounts'    => 'Crear catálogo de cuentas',
+  'Create Dataset'              => 'Crear base de datos',
+  'DBI not installed!'          => 'No se ha instalado DBI',
+  'Database'                    => 'Base de datos',
+  'Database Administration'     => 'Administración de las bases de datos',
+  'Database Driver not checked!' => 'No se ha podido verificar el gestor de la base de datos',
+  'Database User missing!'      => 'No se ha definido el usuario de la base de datos',
+  'Dataset'                     => 'Base de datos',
+  'Dataset missing!'            => 'No se ha definido la base de datos',
+  'Dataset updated!'            => 'Base de datos actualizada',
+  'Date Format'                 => 'Formato de fecha',
+  'Delete'                      => 'Borrar',
+  'Delete Dataset'              => 'Borrar base de datos',
+  'Directory'                   => 'Directorio',
+  'Driver'                      => 'Gestor',
+  'Dropdown Limit'              => 'Límite de efectivo',
+  'E-mail'                      => 'Correo electrónico',
+  'Edit User'                   => 'Editar usuario',
+  'Existing Datasets'           => 'Bases de datos existentes',
+  'Fax'                         => 'Fax',
+  'File locked!'                => 'File locked!',
+  'Host'                        => 'Máquina servidor de base de datos',
+  'Hostname missing!'           => 'No se ha definido la máquina servidor de base de datos',
+  'Incorrect Password!'         => 'Contraseña incorrecta',
+  'Language'                    => 'Lenguaje',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Deje los campos de máquina servidor de base de datos y puerto vacíos al menos que quiera hacer una conexión remota',
+  'Login'                       => 'Entrar',
+  'Name'                        => 'Nombre',
+  'New Templates'               => 'Nuevas plantillas',
+  'No Database Drivers available!' => 'No hay ningún gestor de base de datos disponible',
+  'No Dataset selected!'        => 'No se ha seleccionado ninguna base de datos',
+  'Nothing to delete!'          => '¡No hay nada para borrar!',
+  'Number Format'               => 'Formato de número',
+  'Oracle Database Administration' => 'Administración de la base de datos Oracle',
+  'Password'                    => 'Contraseña',
+  'Password changed!'           => '¡Contraseña cambiada!',
+  'Pg Database Administration'  => 'Administración de la base de datos PostgreSQL',
+  'Phone'                       => 'Teléfono',
+  'Port'                        => 'Puerto',
+  'Port missing!'               => 'No se ha definido  el puerto',
+  'Printer'                     => 'Impresora',
+  'Save'                        => 'Guardar',
+  'Select a Dataset to delete and press "Continue"' => 'Seleccione una base de datos para borrar y presione "Continuar"',
+  'Setup Templates'             => 'Configurar plantillas',
+  'Ship via'                    => 'Envio por',
+  'Signature'                   => 'Firma',
+  'Stylesheet'                  => 'Hoja de estilo',
+  'Templates'                   => 'Plantillas',
+  'The following Datasets are not in use and can be deleted' => 'Las siguientes bases de datos no están en uso y se pueden borrar',
+  'The following Datasets need to be updated' => 'Es necesario actualizar las siguientes bases de datos',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Esta es una verificacion preliminar de fuentes existentes.  No se creará ni borrará nada durante esta etapa',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Para añadir un usuario a un grupo, edite un nombre, cambie el nombre de usuario (login) y guarde los cambios.  Un nuevo usuario, con las mismas propiedades se guardará bajo el nuevo nombre de usuario (login).',
+  'Update Dataset'              => 'Actualizar base de datos',
+  'Use Templates'               => 'Plantillas de usuarios',
+  'User'                        => 'Usuario',
+  'User deleted!'               => '¡Usuario borrado!',
+  'User saved!'                 => '¡Usuario guardado!',
+  'Version'                     => 'Versión',
+  'You must enter a host and port for local and remote connections!' => 'Debe introducir una máquina servidor de bases de datos y un puerto para conexiones locales y remotas',
+  'does not exist'              => 'no existe',
+  'is already a member!'        => 'ya es actualmente un miembro',
+  'localhost'                   => 'máquina local',
+  'successfully created!'       => 'creado satisfactoriamente',
+  'successfully deleted!'       => 'borrado satisfactoriamente',
+  'website'                     => 'sitio web',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'añadir_usuario'              => 'add_user',
+  'cambiar_la_contraseña_del_administrador' => 'change_admin_password',
+  'cambiar_contraseña'          => 'change_password',
+  'continuar'                   => 'continue',
+  'crear_base_de_datos'         => 'create_dataset',
+  'borrar'                      => 'delete',
+  'borrar_base_de_datos'        => 'delete_dataset',
+  'entrar'                      => 'login',
+  'administración_de_la_base_de_datos_oracle' => 'oracle_database_administration',
+  'administración_de_la_base_de_datos_postgresql' => 'pg_database_administration',
+  'guardar'                     => 'save',
+  'actualizar_base_de_datos'    => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/es/all b/sql-ledger/locale/es/all
new file mode 100644 (file)
index 0000000..5e33b01
--- /dev/null
@@ -0,0 +1,490 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Cartera de pagos',
+  'AP Aging'                    => 'Diario resumido de pagos',
+  'AP Transaction'              => 'Gestión se pago',
+  'AP Transactions'             => 'Gestiones de pagos',
+  'AR'                          => 'Cartera de cobros',
+  'AR Aging'                    => 'Diario resumido de cobros ',
+  'AR Transaction'              => 'Gestión de cobro',
+  'AR Transactions'             => 'Gestiones de cobros',
+  'About'                       => 'Acerca de',
+  'Access Control'              => 'Control de Acceso',
+  'Account'                     => 'Cuenta',
+  'Account Number'              => 'Número de cuenta',
+  'Account Number missing!'     => 'No se ha definido el número de la cuenta',
+  'Account Type'                => 'Categoría de cuenta',
+  'Account Type missing!'       => 'No se ha definido el tipo de la cuenta',
+  'Account deleted!'            => '¡Cuenta borraba!',
+  'Account saved!'              => '¡Cuenta guardada!',
+  'Accounting'                  => 'Contabilidad',
+  'Accounting Menu'             => 'Menú general',
+  'Accounts'                    => 'Cuentas',
+  'Active'                      => 'Activo',
+  'Add'                         => 'Añadir',
+  'Add Account'                 => 'Añadir cuenta',
+  'Add Accounts Payables Transaction' => 'Añadir cuenta de transacciones a pagar',
+  'Add Accounts Receivables Transaction' => 'Añadir cuenta de transacciones a cobrar',
+  'Add Assembly'                => 'Añadir compuesto',
+  'Add Customer'                => 'Añadir cliente',
+  'Add GIFI'                    => 'Añadir código GIFI',
+  'Add General Ledger Transaction' => 'Añadir transacción al libro mayor general',
+  'Add Part'                    => 'Añadir artículo',
+  'Add Project'                 => 'Añadir proyecto',
+  'Add Purchase Invoice'        => 'Añadir factura de compra',
+  'Add Purchase Order'          => 'Añadir pedido',
+  'Add Sales Invoice'           => 'Añadir factura',
+  'Add Sales Order'             => 'Añadir presupuesto',
+  'Add Service'                 => 'Añadir servicio',
+  'Add Transaction'             => 'Añadir',
+  'Add User'                    => 'Añadir usuario',
+  'Add Vendor'                  => 'Añadir proveedor',
+  'Address'                     => 'Dirección',
+  'Administration'              => 'Administración',
+  'Administrator'               => 'Administrador',
+  'All'                         => 'Todos',
+  'All Datasets up to date!'    => 'Todas las bases de datos están actualizadas',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Cantidad adeudada',
+  'Amount does not equal applied!' => '¡La cantidad no es igual a lo aplicado!',
+  'Amount missing!'             => '¡Falta la cantidad!',
+  'Applied'                     => 'Aplicado',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => '¿Esta seguro de que desea borrar la factura número',
+  'Are you sure you want to delete Order Number' => '¿Esta seguro de que desea
+borrar la orden número?',
+  'Are you sure you want to delete Transaction' => '¿Está seguro de que desea borrar la transacción?',
+  'Assemblies'                  => 'Compuestos',
+  'Assemblies restocked!'       => '¡Compuestos actualizados en almacen!',
+  'Assembly Number missing!'    => 'No se ha definido el número de compuesto',
+  'Asset'                       => 'Activo',
+  'Attachment'                  => 'Adjunto',
+  'Audit Control'               => 'Control de auditoría',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'BOM'                         => 'Listado de piezas',
+  'Backup'                      => 'Copia de seguridad de los datos',
+  'Backup sent to'              => 'Copia de seguridad enviada a',
+  'Balance'                     => 'Balance',
+  'Balance Sheet'               => 'Hoja de balance',
+  'Bcc'                         => '',
+  'Bin'                         => 'Bin',
+  'Books are open'              => 'Los libros están abiertos',
+  'Bought'                      => 'Comprado',
+  'Business Number'             => 'Numero de negocio',
+  'C'                           => '',
+  'COGS'                        => 'Costo de los artículos',
+  'Cannot delete account!'      => '¡No se puede borrar la cuenta!',
+  'Cannot delete customer!'     => '¡No se puede borrar el cliente!',
+  'Cannot delete default account!' => 'No se puede borrar la cuenta por omisión',
+  'Cannot delete invoice!'      => '¡No se puede borrar la factura!',
+  'Cannot delete item already invoiced!' => 'No se puede borrar un artículo ya facturado',
+  'Cannot delete item on order!' => 'No se puede eliminar un elemento presente en una orden',
+  'Cannot delete item which is part of an assembly!' => 'No puede eliminar un artículo que es parte de un compuesto',
+  'Cannot delete item!'         => '¡No se puede borrar el artículo!',
+  'Cannot delete order!'        => '¡No se puede borrar el pedido!',
+  'Cannot delete transaction!'  => '¡No se puede borrar la transacción!',
+  'Cannot delete vendor!'       => '¡No se puede borrar el vendedor!',
+  'Cannot have a value in both Debit and Credit!' => 'No puede tener un valor en débito y crédito simultáneamente!',
+  'Cannot post a transaction without a value!' => '¡No se puede registrar una transacción sin valor!',
+  'Cannot post invoice for a closed period!' => '¡No se puede registrar una factura en un periodo ya cerrado!',
+  'Cannot post invoice!'        => '¡No se puede registrar la factura!',
+  'Cannot post payment for a closed period!' => '¡No se puede registrar un pago en un periodo ya cerrado!',
+  'Cannot post payment!'        => '¡No se puede registrar el pago!',
+  'Cannot post transaction for a closed period!' => '¡No se puede registrar una transacción para un periodo cerrado',
+  'Cannot post transaction!'    => '¡No se puede registrar la transacción',
+  'Cannot process payment for a closed period!' => '¡No se puede procesar un pago de un periodo ya cerrado!',
+  'Cannot save account!'        => '¡No se puede guardar la cuenta!',
+  'Cannot save order!'          => '¡No se puede guardar el pedido!',
+  'Cannot save preferences!'    => '¡No se puede guardar las preferencias!',
+  'Cannot stock assemblies!'    => '¡No se pueden almacenar los compuestos!',
+  'Cash'                        => 'Efectivo',
+  'Cash based'                  => 'Efectivo inicial',
+  'Cc'                          => '',
+  'Change Admin Password'       => 'Cambiar la contraseña del administrador',
+  'Change Password'             => 'Cambiar contraseña',
+  'Character Set'               => 'Conjunto de caracteres',
+  'Chart of Accounts'           => 'Cuadro de cuentas',
+  'Check'                       => 'Cheque',
+  'Check printed!'              => '¡Cheque impreso!',
+  'Check printing failed!'      => '¡Fallo al imprimir el cheque!',
+  'Cleared Balance'             => 'Balance cerrado',
+  'Click on login name to edit!' => 'Haga clic en el nombre de usuario por
+editar',
+  'Close Books up to'           => 'Cerrar los libros hasta',
+  'Closed'                      => 'Cerrado',
+  'Company'                     => 'Compañía',
+  'Compare to'                  => 'Comparar con',
+  'Confirm!'                    => 'Confirmar',
+  'Connect to'                  => 'Conectar a',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Copy to COA'                 => 'Copiar al catálogo de cuentas',
+  'Create Chart of Accounts'    => 'Crear catálogo de cuentas',
+  'Create Dataset'              => 'Crear base de datos',
+  'Credit'                      => 'Crédito',
+  'Credit Limit'                => 'Limite de credito',
+  'Curr'                        => 'Mon.',
+  'Currency'                    => 'Moneda',
+  'Current'                     => 'Actual',
+  'Customer'                    => 'Cliente',
+  'Customer deleted!'           => '¡Cliente borrado!',
+  'Customer missing!'           => '¡Falta el cliente!',
+  'Customer not on file!'       => '¡El cliente no existe!',
+  'Customer saved!'             => '¡Cliente guardado!',
+  'Customers'                   => 'Clientes',
+  'DBI not installed!'          => 'No se ha instalado DBI',
+  'Database'                    => 'Base de datos',
+  'Database Administration'     => 'Administración de las bases de datos',
+  'Database Driver not checked!' => 'No se ha podido verificar el gestor de la base de datos',
+  'Database Host'               => 'Máquina servidor de base de datos',
+  'Database User missing!'      => 'No se ha definido el usuario de la base de datos',
+  'Dataset'                     => 'Base de datos',
+  'Dataset missing!'            => 'No se ha definido la base de datos',
+  'Dataset updated!'            => 'Base de datos actualizada',
+  'Date'                        => 'Fecha',
+  'Date Due'                    => 'Fecha de vencimiento',
+  'Date Format'                 => 'Formato de fecha',
+  'Date Paid'                   => 'Fecha de pago',
+  'Date missing!'               => '¡Falta la fecha!',
+  'Debit'                       => 'Débito',
+  'Debit and credit out of balance!' => 'Los débitos y créditos están fuera de balance',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Decimalplaces'               => 'Lugar de los decimales',
+  'Delete'                      => 'Borrar',
+  'Delete Account'              => 'Borrar cuenta',
+  'Delete Dataset'              => 'Borrar base de datos',
+  'Delivery Date'               => 'Fecha de entrega',
+  'Deposit'                     => 'Depósito',
+  'Description'                 => 'Descripción',
+  'Difference'                  => 'Diferencia',
+  'Directory'                   => 'Directorio',
+  'Discount'                    => 'Descuento',
+  'Done'                        => 'Hecho',
+  'Drawing'                     => 'Reintegro',
+  'Driver'                      => 'Gestor',
+  'Dropdown Limit'              => 'Límite de efectivo',
+  'Due'                         => 'Vence',
+  'Due Date'                    => 'Fecha de vencimiento',
+  'Due Date missing!'           => 'Falta la fecha de vencimiento',
+  'E-mail'                      => 'Correo electrónico',
+  'E-mail Statement to'         => 'Enviar comprobante por correo electrónico a',
+  'E-mail address missing!'     => 'No se ha definido el correo electrónico',
+  'Edit'                        => 'Editar',
+  'Edit Account'                => 'Editar cuenta',
+  'Edit Accounts Payables Transaction' => 'Editar las cuentas de las transacciones a pagar',
+  'Edit Accounts Receivables Transaction' => 'Editar las cuentas de las transacciones a cobrar',
+  'Edit Assembly'               => 'Editar compuesto',
+  'Edit GIFI'                   => 'Editar GIFI',
+  'Edit General Ledger Transaction' => 'Editar transacción del libro mayor general',
+  'Edit Part'                   => 'Editar compuesto',
+  'Edit Preferences for'        => 'Editar preferencias de',
+  'Edit Project'                => 'Editar proyecto',
+  'Edit Purchase Invoice'       => 'Editar factura de compra',
+  'Edit Purchase Order'         => 'Editar pedido',
+  'Edit Sales Invoice'          => 'Edirar factura de venta',
+  'Edit Sales Order'            => 'Editar presupuesto',
+  'Edit Service'                => 'Editar servicio',
+  'Edit Template'               => 'Editar plantilla',
+  'Edit User'                   => 'Editar usuario',
+  'Employee'                    => 'Colaborador/Empleado',
+  'Enforce transaction reversal for all dates' => 'Forzar la anulación de las transacciones para todas las fechas',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Introduzca hasta 3 letras separadas por dos puntos (p.e. CAD:USD:EUR) para las monedas locales y las extranjeras',
+  'Equity'                      => 'Balance',
+  'Exch'                        => 'Cambio',
+  'Exchangerate'                => 'Tasa de cambio',
+  'Exchangerate Difference'     => 'Diferencia en la tasa cambio a moneda extranjera',
+  'Exchangerate for payment missing!' => '¡Falta la tasa de cambio para el pago!',
+  'Exchangerate missing!'       => '¡Falta la tasa de cambio!',
+  'Existing Datasets'           => 'Bases de datos existentes',
+  'Expense'                     => 'Gastos',
+  'Expense Account'             => 'Cuenta de gastos',
+  'Expense/Asset'               => 'Gastos/Activo',
+  'Extended'                    => 'Extendido',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'File locked!'                => '',
+  'Foreign Exchange Gain'       => 'Ganancia en moneda extranjera',
+  'Foreign Exchange Loss'       => 'Pérdida en moneda extranjera',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'Código GIFI',
+  'GIFI deleted!'               => '¡Borrado el código GIFI!',
+  'GIFI missing!'               => 'No se ha definido el código GIFI',
+  'GIFI saved!'                 => '¡Guardado el código GIFI!',
+  'GL Transaction'              => 'Transacción en el libro mayor',
+  'General Ledger'              => 'Libro mayor general',
+  'Goods & Services'            => 'Bienes y servicios',
+  'HTML Templates'              => 'Plantillas HTML',
+  'Heading'                     => 'Encabezado',
+  'Host'                        => 'Máquina servidor de base de datos',
+  'Hostname missing!'           => 'No se ha definido la máquina servidor de base de datos',
+  'ID'                          => 'ID',
+  'Image'                       => 'Imagen',
+  'In-line'                     => 'Incrustado',
+  'Include in Report'           => 'Incluir en informe',
+  'Include in drop-down menus'  => 'Incluir en menúes desplegables:',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Mostrar esta cuenta en los formularios de cliente/proveedor para seleccionar si hay que aplicar impuestos al cliente/proveedor?',
+  'Income'                      => 'Ingresos',
+  'Income Account'              => 'Cuenta de ingresos',
+  'Income Statement'            => 'Balance de situación',
+  'Incorrect Dataset version!'  => 'Versión de base de datos incorrecta',
+  'Incorrect Password!'         => 'Contraseña incorrecta',
+  'Individual Items'            => 'Artículos individuales',
+  'Inventory'                   => 'Inventario',
+  'Inventory Account'           => 'Cuenta de inventario',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'La cantidad en inventario debe ser cero antes de cambiar este compuesto a obsoleto',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'La cantidad en inventario debe ser cero antes de cambiar este artículo a obsoleto',
+  'Inventory quantity must be zero!' => 'La cantidad en inventario debe ser cero',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de factura',
+  'Invoice Date missing!'       => 'No se ha definido la fecha de la factura',
+  'Invoice Number'              => 'Número de factura',
+  'Invoice Number missing!'     => 'No se ha definido el número de la factura',
+  'Invoice deleted!'            => '¡Factura borrada!',
+  'Invoice posted!'             => '¡Factura registrada!',
+  'Invoices'                    => 'Facturas',
+  'Is this a summary account to record' => '¿Es esta una cuenta de resumen a registrar?',
+  'Item deleted!'               => '¡Concepto borrado!',
+  'Item not on file!'           => 'El concepto no se encuentra en ningún archivo',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'LaTeX Templates'             => 'Plantillas LaTeX',
+  'Language'                    => 'Lenguaje',
+  'Last Cost'                   => 'Ultimo costo',
+  'Last Invoice Number'         => 'Último número de factura',
+  'Last Numbers & Default Accounts' => 'Últimos números y cuentas por omisión',
+  'Last Purchase Order Number'  => 'Último pedido',
+  'Last Sales Order Number'     => 'Número del último presupuesto',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Deje los campos de máquina servidor de base de datos y puerto vacíos al menos que quiera hacer una conexión remota',
+  'Liability'                   => 'Pasivo',
+  'Licensed to'                 => 'Adaptado para',
+  'Line Total'                  => 'Total de la línea',
+  'Link'                        => 'Enlaces',
+  'Link Accounts'               => 'Enlazar cuentas',
+  'List Accounts'               => 'Listar cuentas',
+  'List GIFI'                   => 'Listar código GIFI',
+  'List Price'                  => 'Precio de lista',
+  'List Transactions'           => 'Listar transacciones',
+  'Login'                       => 'Entrar',
+  'Logout'                      => 'Salir',
+  'Make'                        => 'Marca',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Microfiche'                  => 'Microficha',
+  'Model'                       => 'Modelo',
+  'N/A'                         => 'Sin respuesta',
+  'Name'                        => 'Nombre',
+  'Name missing!'               => '¡Falta el nombre!',
+  'New Templates'               => 'Nuevas plantillas',
+  'No'                          => 'No',
+  'No Database Drivers available!' => 'No hay ningún gestor de base de datos disponible',
+  'No Dataset selected!'        => 'No se ha seleccionado ninguna base de datos',
+  'No email address for'        => 'Falta la dirección de correo electrónico de',
+  'No.'                         => '',
+  'Notes'                       => 'Notas',
+  'Nothing applied!'            => '¡No es aplicable a nada!',
+  'Nothing selected!'           => '¡No es seleccionado nada!',
+  'Nothing to delete!'          => '¡No hay nada para borrar!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Formato de número',
+  'Number missing in Row'       => 'No se ha definido el número en la fila',
+  'O'                           => '',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'On Hand'                     => 'Disponible',
+  'On Order'                    => 'En pedido',
+  'Open'                        => 'Abierto',
+  'Oracle Database Administration' => 'Administración de la base de datos Oracle',
+  'Order'                       => 'Orden',
+  'Order Date'                  => 'Fecha de elaboración',
+  'Order Date missing!'         => 'No se ha definido la fecha de la elaboración',
+  'Order Entry'                 => 'Presupuestos y pedidos',
+  'Order Number'                => 'Número de orden',
+  'Order Number missing!'       => 'No se ha definido el número de la orden',
+  'Order deleted!'              => '¡Orden borrada!',
+  'Order saved!'                => '¡Orden guardada!',
+  'Ordered'                     => 'Pedido realizado',
+  'Orphaned'                    => 'Huérfano',
+  'Out of balance!'             => '¡Fuera de balance!',
+  'PDF'                         => '',
+  'Packing List'                => 'Albarán',
+  'Packing List Date missing!'  => 'No se ha definido la fecha del albarán',
+  'Packing List Number missing!' => 'No se ha definido el número del albarán',
+  'Paid'                        => 'Pagado',
+  'Paid in full'                => 'Pago al completo',
+  'Part'                        => 'Artículo',
+  'Part Number missing!'        => 'No se ha definido el número del artículo',
+  'Parts'                       => 'Artículos',
+  'Parts Inventory'             => 'Inventario de artículos',
+  'Password'                    => 'Contraseña',
+  'Password changed!'           => '¡Contraseña cambiada!',
+  'Payables'                    => 'Pagos',
+  'Payment'                     => 'Pago',
+  'Payment date missing!'       => 'No se encuentra la fecha de pago',
+  'Payment posted!'             => '¡Pago registrado!',
+  'Payments'                    => 'Vencimientos impagados',
+  'Pg Database Administration'  => 'Administración de la base de datos PostgreSQL',
+  'Phone'                       => 'Teléfono',
+  'Port'                        => 'Puerto',
+  'Port missing!'               => 'No se ha definido  el puerto',
+  'Post'                        => 'Registrar',
+  'Post as new'                 => 'Registrar como nuevo',
+  'Postscript'                  => '',
+  'Preferences'                 => 'Preferencias',
+  'Preferences saved!'          => 'Preferencias guardadas',
+  'Price'                       => 'Precio',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Proyecto',
+  'Project Number missing!'     => '¡Falta el número de proyecto!',
+  'Project deleted!'            => '¡Proyecto borrado!',
+  'Project not on file!'        => '¡No se encuentra el proyecto en la base de datos!',
+  'Project saved!'              => '¡Proyecto guardado ',
+  'Projects'                    => 'Proyectos',
+  'Purchase Invoice'            => 'Factura de compras',
+  'Purchase Order'              => 'Pedido',
+  'Purchase Orders'             => 'Pedidos',
+  'Qty'                         => 'Cantidad',
+  'ROP'                         => 'Tope de envio',
+  'Rate'                        => 'Tarifa',
+  'Recd'                        => 'Cobrado',
+  'Receipt'                     => 'Recibo',
+  'Receipts'                    => 'Recibos',
+  'Receivables'                 => 'Cobros',
+  'Reconciliation'              => 'Reconciliación',
+  'Record in'                   => 'Registrar en',
+  'Reference'                   => 'Referencia',
+  'Reference missing!'          => '¡Falta la referencia!',
+  'Remaining'                   => 'Resto',
+  'Report for'                  => 'Informe para',
+  'Reports'                     => 'Informes',
+  'Required by'                 => 'Aceptado el',
+  'Retained Earnings'           => 'Ganacias retenidas',
+  'Sales'                       => 'Ventas',
+  'Sales Invoice'               => 'Facturas de ventas',
+  'Sales Order'                 => 'Presupuesto',
+  'Sales Orders'                => 'Presupuestos',
+  'Save'                        => 'Guardar',
+  'Save as new'                 => 'Guardar como nuevo',
+  'Save to File'                => 'Guardar en un archivo',
+  'Screen'                      => 'Pantalla',
+  'Select a Dataset to delete and press "Continue"' => 'Seleccione una base de datos para borrar y presione "Continuar"',
+  'Select all'                  => 'Guardar todo',
+  'Select from one of the items below' => 'Seleccione uno de los artículos siguientes',
+  'Select from one of the names below' => 'Seleccione uno de los nombres de la lista',
+  'Select from one of the projects below' => 'Seleccione uno de los proyectos de la lista',
+  'Select postscript or PDF!'   => '¡Seleccione postscript o PDF',
+  'Sell Price'                  => 'Precio de venta',
+  'Send by E-Mail'              => 'Enviar por correo electrónico',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Service Items'               => 'Servicios',
+  'Service Number missing!'     => 'No se ha definido el número de servicio',
+  'Services'                    => 'Servicios',
+  'Setup Templates'             => 'Configurar plantillas',
+  'Ship'                        => 'Envio',
+  'Ship to'                     => 'Destino',
+  'Ship via'                    => 'Envio por',
+  'Short'                       => 'Corto',
+  'Signature'                   => 'Firma',
+  'Sold'                        => 'Vendido',
+  'Source'                      => 'Fuente',
+  'Standard'                    => 'Estándard',
+  'Statement'                   => 'Estado de cuenta',
+  'Statement Balance'           => 'Balance de cuenta',
+  'Statement sent to'           => 'Estado de cuenta enviado a',
+  'Statements sent to printer!' => '¡Estado de cuenta enviado a la impresora!',
+  'Stock Assembly'              => 'Inventariar compuesto',
+  'Stylesheet'                  => 'Hoja de estilo',
+  'Subject'                     => 'Asunto',
+  'Subtotal'                    => 'Subtotal',
+  'System'                      => 'Sistema',
+  'Tax'                         => 'Impuesto',
+  'Tax Accounts'                => 'Cuentas de impuestos',
+  'Tax Included'                => 'Impuestos incluidos en el precio',
+  'Tax collected'               => 'Impuestos cobrados',
+  'Tax paid'                    => 'Impuestos pagados',
+  'Taxable'                     => 'Impuestos gravables',
+  'Template saved!'             => '¡Plantilla guardada!',
+  'Templates'                   => 'Plantillas',
+  'Terms: Net'                  => 'Crédito',
+  'The following Datasets are not in use and can be deleted' => 'Las siguientes bases de datos no están en uso y se pueden borrar',
+  'The following Datasets need to be updated' => 'Es necesario actualizar las siguientes bases de datos',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Esta es una verificacion preliminar de fuentes existentes.  No se creará ni borrará nada durante esta etapa',
+  'To'                          => 'Hasta ',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Para añadir un usuario a un grupo, edite un nombre, cambie el nombre de usuario (login) y guarde los cambios.  Un nuevo usuario, con las mismas propiedades se guardará bajo el nuevo nombre de usuario (login).',
+  'Top Level'                   => '',
+  'Total'                       => 'Total',
+  'Transaction Date missing!'   => 'No se ha definido la fecha de la transacción',
+  'Transaction deleted!'        => '¡Transacción borrada!',
+  'Transaction posted!'         => '¡Transacción registrada!',
+  'Transaction reversal enforced for all dates' => 'Se ha forzado la anulación de las transacciones para todas las fechas',
+  'Transaction reversal enforced up to' => 'Se ha forzado la anulación de las transacciones hasta',
+  'Transactions'                => 'Impagados',
+  'Transactions exist, cannot delete customer!' => 'Existen transacciones para este cliente, por tanto, no puede borrarlo',
+  'Transactions exist, cannot delete vendor!' => 'Existen transacciones para este proveedor, por tanto, no puede borrarlo',
+  'Transactions exist; cannot delete account!' => 'Las transacciones existen, no puede suprimir la cuenta!',
+  'Trial Balance'               => 'Balance de comprobación',
+  'Unit'                        => 'Unidad',
+  'Unit of measure'             => 'Unidad de medida',
+  'Update'                      => 'Actualizar',
+  'Update Dataset'              => 'Actualizar base de datos',
+  'Updated'                     => '¡Actualizado!',
+  'Use Templates'               => 'Plantillas de usuarios',
+  'User'                        => 'Usuario',
+  'User deleted!'               => '¡Usuario borrado!',
+  'User saved!'                 => '¡Usuario guardado!',
+  'Vendor'                      => 'Proveedor',
+  'Vendor deleted!'             => '¡Proveedor borrado!',
+  'Vendor missing!'             => '¡Falta el proveedor!',
+  'Vendor not on file!'         => '¡No se encuentra el proveedor en la base de datos!',
+  'Vendor saved!'               => '¡Proveedor guardado!',
+  'Vendors'                     => 'Proveedores',
+  'Version'                     => 'Versión',
+  'Weight'                      => 'Peso',
+  'Weight Unit'                 => 'Unidad de peso',
+  'What type of item is this?'  => '¿De qué tipo es este concepto?',
+  'Year End'                    => 'Fin del año fiscal',
+  'Yes'                         => 'Si',
+  'You are logged out!'         => '¡Ya está desconectado del sistema!',
+  'You did not enter a name!'   => 'No ha introducido el nombre',
+  'You must enter a host and port for local and remote connections!' => 'Debe introducir una máquina servidor de bases de datos y un puerto para conexiones locales y remotas',
+  'as at'                       => 'al',
+  'collected on sales'          => 'ingresado en ventas',
+  'days'                        => 'días',
+  'does not exist'              => 'no existe',
+  'ea'                          => 'unid.',
+  'emailed to'                  => 'enviado por correo electrónico a',
+  'for Period'                  => 'para el periodo',
+  'hr'                          => 'hr',
+  'is already a member!'        => 'ya es actualmente un miembro',
+  'is not a member!'            => 'no es miembro',
+  'localhost'                   => 'máquina local',
+  'paid on purchases'           => 'pagado en compras',
+  'sent to printer'             => 'enviado a la impresora',
+  'successfully created!'       => 'creado satisfactoriamente',
+  'successfully deleted!'       => 'borrado satisfactoriamente',
+  'to'                          => 'a',
+  'website'                     => 'sitio web',
+};
+
+1;
diff --git a/sql-ledger/locale/es/am b/sql-ledger/locale/es/am
new file mode 100644 (file)
index 0000000..a19042d
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Cartera de pagos',
+  'AR'                          => 'Cartera de cobros',
+  'Account'                     => 'Cuenta',
+  'Account Number'              => 'Número de cuenta',
+  'Account Number missing!'     => 'No se ha definido el número de la cuenta',
+  'Account Type'                => 'Categoría de cuenta',
+  'Account Type missing!'       => 'No se ha definido el tipo de la cuenta',
+  'Account deleted!'            => '¡Cuenta borraba!',
+  'Account saved!'              => '¡Cuenta guardada!',
+  'Add Account'                 => 'Añadir cuenta',
+  'Add GIFI'                    => 'Añadir código GIFI',
+  'Address'                     => 'Dirección',
+  'Asset'                       => 'Activo',
+  'Audit Control'               => 'Control de auditoría',
+  'Backup sent to'              => 'Copia de seguridad enviada a',
+  'Books are open'              => 'Los libros están abiertos',
+  'Business Number'             => 'Numero de negocio',
+  'COGS'                        => 'Costo de los artículos',
+  'Cannot delete account!'      => '¡No se puede borrar la cuenta!',
+  'Cannot delete default account!' => 'No se puede borrar la cuenta por omisión',
+  'Cannot save account!'        => '¡No se puede guardar la cuenta!',
+  'Cannot save preferences!'    => '¡No se puede guardar las preferencias!',
+  'Character Set'               => 'Conjunto de caracteres',
+  'Chart of Accounts'           => 'Cuadro de cuentas',
+  'Close Books up to'           => 'Cerrar los libros hasta',
+  'Company'                     => 'Compañía',
+  'Continue'                    => 'Continuar',
+  'Copy to COA'                 => 'Copiar al catálogo de cuentas',
+  'Credit'                      => 'Crédito',
+  'Date Format'                 => 'Formato de fecha',
+  'Debit'                       => 'Débito',
+  'Delete'                      => 'Borrar',
+  'Delete Account'              => 'Borrar cuenta',
+  'Description'                 => 'Descripción',
+  'Dropdown Limit'              => 'Límite de efectivo',
+  'E-mail'                      => 'Correo electrónico',
+  'Edit'                        => 'Editar',
+  'Edit Account'                => 'Editar cuenta',
+  'Edit GIFI'                   => 'Editar GIFI',
+  'Edit Preferences for'        => 'Editar preferencias de',
+  'Edit Template'               => 'Editar plantilla',
+  'Enforce transaction reversal for all dates' => 'Forzar la anulación de las transacciones para todas las fechas',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Introduzca hasta 3 letras separadas por dos puntos (p.e. CAD:USD:EUR) para las monedas locales y las extranjeras',
+  'Equity'                      => 'Balance',
+  'Expense'                     => 'Gastos',
+  'Expense Account'             => 'Cuenta de gastos',
+  'Expense/Asset'               => 'Gastos/Activo',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Ganancia en moneda extranjera',
+  'Foreign Exchange Loss'       => 'Pérdida en moneda extranjera',
+  'GIFI'                        => 'Código GIFI',
+  'GIFI deleted!'               => '¡Borrado el código GIFI!',
+  'GIFI missing!'               => 'No se ha definido el código GIFI',
+  'GIFI saved!'                 => '¡Guardado el código GIFI!',
+  'Heading'                     => 'Encabezado',
+  'Include in drop-down menus'  => 'Incluir en menúes desplegables:',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Mostrar esta cuenta en los formularios de cliente/proveedor para seleccionar si hay que aplicar impuestos al cliente/proveedor?',
+  'Income'                      => 'Ingresos',
+  'Income Account'              => 'Cuenta de ingresos',
+  'Inventory'                   => 'Inventario',
+  'Inventory Account'           => 'Cuenta de inventario',
+  'Is this a summary account to record' => '¿Es esta una cuenta de resumen a registrar?',
+  'Language'                    => 'Lenguaje',
+  'Last Invoice Number'         => 'Último número de factura',
+  'Last Numbers & Default Accounts' => 'Últimos números y cuentas por omisión',
+  'Last Purchase Order Number'  => 'Último pedido',
+  'Last Sales Order Number'     => 'Número del último presupuesto',
+  'Liability'                   => 'Pasivo',
+  'Link'                        => 'Enlaces',
+  'Name'                        => 'Nombre',
+  'No'                          => 'No',
+  'No email address for'        => 'Falta la dirección de correo electrónico de',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Formato de número',
+  'Parts Inventory'             => 'Inventario de artículos',
+  'Password'                    => 'Contraseña',
+  'Payables'                    => 'Pagos',
+  'Payment'                     => 'Pago',
+  'Phone'                       => 'Teléfono',
+  'Preferences saved!'          => 'Preferencias guardadas',
+  'Rate'                        => 'Tarifa',
+  'Receivables'                 => 'Cobros',
+  'Sales'                       => 'Ventas',
+  'Save'                        => 'Guardar',
+  'Service Items'               => 'Servicios',
+  'Ship via'                    => 'Envio por',
+  'Signature'                   => 'Firma',
+  'Stylesheet'                  => 'Hoja de estilo',
+  'Tax'                         => 'Impuesto',
+  'Tax Accounts'                => 'Cuentas de impuestos',
+  'Template saved!'             => '¡Plantilla guardada!',
+  'Transaction reversal enforced for all dates' => 'Se ha forzado la anulación de las transacciones para todas las fechas',
+  'Transaction reversal enforced up to' => 'Se ha forzado la anulación de las transacciones hasta',
+  'Transactions exist; cannot delete account!' => 'Las transacciones existen, no puede suprimir la cuenta!',
+  'Weight Unit'                 => 'Unidad de peso',
+  'Year End'                    => 'Fin del año fiscal',
+  'Yes'                         => 'Si',
+  'does not exist'              => 'no existe',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'añadir_cuenta'               => 'add_account',
+  'continuar'                   => 'continue',
+  'copiar_al_catálogo_de_cuentas' => 'copy_to_coa',
+  'borrar'                      => 'delete',
+  'editar'                      => 'edit',
+  'editar_cuenta'               => 'edit_account',
+  'guardar'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/es/ap b/sql-ledger/locale/es/ap
new file mode 100644 (file)
index 0000000..1a8f37c
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Gestión se pago',
+  'AP Transactions'             => 'Gestiones de pagos',
+  'Account'                     => 'Cuenta',
+  'Add Accounts Payables Transaction' => 'Añadir cuenta de transacciones a pagar',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Cantidad adeudada',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => '¿Está seguro de que desea borrar la transacción?',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Cannot delete transaction!'  => '¡No se puede borrar la transacción!',
+  'Cannot post payment for a closed period!' => '¡No se puede registrar un pago en un periodo ya cerrado!',
+  'Cannot post transaction for a closed period!' => '¡No se puede registrar una transacción para un periodo cerrado',
+  'Cannot post transaction!'    => '¡No se puede registrar la transacción',
+  'Closed'                      => 'Cerrado',
+  'Confirm!'                    => 'Confirmar',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Moneda',
+  'Customer not on file!'       => '¡El cliente no existe!',
+  'Date'                        => 'Fecha',
+  'Date Paid'                   => 'Fecha de pago',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Due Date'                    => 'Fecha de vencimiento',
+  'Due Date missing!'           => 'Falta la fecha de vencimiento',
+  'Edit Accounts Payables Transaction' => 'Editar las cuentas de las transacciones a pagar',
+  'Employee'                    => 'Colaborador/Empleado',
+  'Exch'                        => 'Cambio',
+  'Exchangerate'                => 'Tasa de cambio',
+  'Exchangerate for payment missing!' => '¡Falta la tasa de cambio para el pago!',
+  'Exchangerate missing!'       => '¡Falta la tasa de cambio!',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluir en informe',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de factura',
+  'Invoice Date missing!'       => 'No se ha definido la fecha de la factura',
+  'Invoice Number'              => 'Número de factura',
+  'Invoice Number missing!'     => 'No se ha definido el número de la factura',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Open'                        => 'Abierto',
+  'Order'                       => 'Orden',
+  'Order Number'                => 'Número de orden',
+  'Paid'                        => 'Pagado',
+  'Payment date missing!'       => 'No se encuentra la fecha de pago',
+  'Payments'                    => 'Vencimientos impagados',
+  'Post'                        => 'Registrar',
+  'Post as new'                 => 'Registrar como nuevo',
+  'Project'                     => 'Proyecto',
+  'Project not on file!'        => '¡No se encuentra el proyecto en la base de datos!',
+  'Purchase Invoice'            => 'Factura de compras',
+  'Select from one of the names below' => 'Seleccione uno de los nombres de la lista',
+  'Select from one of the projects below' => 'Seleccione uno de los proyectos de la lista',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Source'                      => 'Fuente',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'Tax Included'                => 'Impuestos incluidos en el precio',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => '¡Transacción borrada!',
+  'Transaction posted!'         => '¡Transacción registrada!',
+  'Update'                      => 'Actualizar',
+  'Vendor'                      => 'Proveedor',
+  'Vendor missing!'             => '¡Falta el proveedor!',
+  'Vendor not on file!'         => '¡No se encuentra el proveedor en la base de datos!',
+  'Yes'                         => 'Si',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'gestión_se_pago'             => 'ap_transaction',
+  'añadir_cuenta_de_transacciones_a_pagar' => 'add_accounts_payables_transaction',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'editar_las_cuentas_de_las_transacciones_a_pagar' => 'edit_accounts_payables_transaction',
+  'registrar'                   => 'post',
+  'registrar_como_nuevo'        => 'post_as_new',
+  'factura_de_compras'          => 'purchase_invoice',
+  'actualizar'                  => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/es/ar b/sql-ledger/locale/es/ar
new file mode 100644 (file)
index 0000000..e24b004
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'Gestión de cobro',
+  'AR Transactions'             => 'Gestiones de cobros',
+  'Account'                     => 'Cuenta',
+  'Add Accounts Receivables Transaction' => 'Añadir cuenta de transacciones a cobrar',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Cantidad adeudada',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => '¿Está seguro de que desea borrar la transacción?',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Cannot delete transaction!'  => '¡No se puede borrar la transacción!',
+  'Cannot post payment for a closed period!' => '¡No se puede registrar un pago en un periodo ya cerrado!',
+  'Cannot post transaction for a closed period!' => '¡No se puede registrar una transacción para un periodo cerrado',
+  'Cannot post transaction!'    => '¡No se puede registrar la transacción',
+  'Closed'                      => 'Cerrado',
+  'Confirm!'                    => 'Confirmar',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Limite de credito',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => '¡Falta el cliente!',
+  'Customer not on file!'       => '¡El cliente no existe!',
+  'Date'                        => 'Fecha',
+  'Date Paid'                   => 'Fecha de pago',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Due Date'                    => 'Fecha de vencimiento',
+  'Due Date missing!'           => 'Falta la fecha de vencimiento',
+  'Edit Accounts Receivables Transaction' => 'Editar las cuentas de las transacciones a cobrar',
+  'Employee'                    => 'Colaborador/Empleado',
+  'Exch'                        => 'Cambio',
+  'Exchangerate'                => 'Tasa de cambio',
+  'Exchangerate for payment missing!' => '¡Falta la tasa de cambio para el pago!',
+  'Exchangerate missing!'       => '¡Falta la tasa de cambio!',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluir en informe',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de factura',
+  'Invoice Date missing!'       => 'No se ha definido la fecha de la factura',
+  'Invoice Number'              => 'Número de factura',
+  'Invoice Number missing!'     => 'No se ha definido el número de la factura',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Open'                        => 'Abierto',
+  'Order'                       => 'Orden',
+  'Order Number'                => 'Número de orden',
+  'Paid'                        => 'Pagado',
+  'Payment date missing!'       => 'No se encuentra la fecha de pago',
+  'Payments'                    => 'Vencimientos impagados',
+  'Post'                        => 'Registrar',
+  'Post as new'                 => 'Registrar como nuevo',
+  'Project'                     => 'Proyecto',
+  'Project not on file!'        => '¡No se encuentra el proyecto en la base de datos!',
+  'Remaining'                   => 'Resto',
+  'Sales Invoice'               => 'Facturas de ventas',
+  'Select from one of the names below' => 'Seleccione uno de los nombres de la lista',
+  'Select from one of the projects below' => 'Seleccione uno de los proyectos de la lista',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Source'                      => 'Fuente',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'Tax Included'                => 'Impuestos incluidos en el precio',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => '¡Transacción borrada!',
+  'Transaction posted!'         => '¡Transacción registrada!',
+  'Update'                      => 'Actualizar',
+  'Vendor not on file!'         => '¡No se encuentra el proveedor en la base de datos!',
+  'Yes'                         => 'Si',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'gestión_de_cobro'            => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'registrar'                   => 'post',
+  'registrar_como_nuevo'        => 'post_as_new',
+  'facturas_de_ventas'          => 'sales_invoice',
+  'actualizar'                  => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/es/arap b/sql-ledger/locale/es/arap
new file mode 100644 (file)
index 0000000..be33676
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Dirección',
+  'Continue'                    => 'Continuar',
+  'Customer not on file!'       => '¡El cliente no existe!',
+  'Description'                 => 'Descripción',
+  'Number'                      => 'Número',
+  'Project not on file!'        => '¡No se encuentra el proyecto en la base de datos!',
+  'Select from one of the names below' => 'Seleccione uno de los nombres de la lista',
+  'Select from one of the projects below' => 'Seleccione uno de los proyectos de la lista',
+  'Vendor not on file!'         => '¡No se encuentra el proveedor en la base de datos!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/es/ca b/sql-ledger/locale/es/ca
new file mode 100644 (file)
index 0000000..536d00a
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Balance',
+  'Chart of Accounts'           => 'Cuadro de cuentas',
+  'Credit'                      => 'Crédito',
+  'Date'                        => 'Fecha',
+  'Debit'                       => 'Débito',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Description'                 => 'Descripción',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'Código GIFI',
+  'Include in Report'           => 'Incluir en informe',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'List Transactions'           => 'Listar transacciones',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Reference'                   => 'Referencia',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Subtotal'                    => 'Subtotal',
+  'To'                          => 'Hasta ',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'listar_transacciones'        => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/es/cp b/sql-ledger/locale/es/cp
new file mode 100644 (file)
index 0000000..aa93a34
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Amount does not equal applied!' => '¡La cantidad no es igual a lo aplicado!',
+  'Amount missing!'             => '¡Falta la cantidad!',
+  'Applied'                     => 'Aplicado',
+  'Cannot post payment!'        => '¡No se puede registrar el pago!',
+  'Cannot process payment for a closed period!' => '¡No se puede procesar un pago de un periodo ya cerrado!',
+  'Check'                       => 'Cheque',
+  'Check printed!'              => '¡Cheque impreso!',
+  'Check printing failed!'      => '¡Fallo al imprimir el cheque!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Cliente',
+  'Customer not on file!'       => '¡El cliente no existe!',
+  'Date'                        => 'Fecha',
+  'Date missing!'               => '¡Falta la fecha!',
+  'Description'                 => 'Descripción',
+  'Due'                         => 'Vence',
+  'Exchangerate'                => 'Tasa de cambio',
+  'From'                        => 'Desde',
+  'Invoice'                     => 'Factura',
+  'Invoices'                    => 'Facturas',
+  'Nothing applied!'            => '¡No es aplicable a nada!',
+  'Number'                      => 'Número',
+  'Paid in full'                => 'Pago al completo',
+  'Payment'                     => 'Pago',
+  'Payment posted!'             => '¡Pago registrado!',
+  'Post'                        => 'Registrar',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impresora',
+  'Project not on file!'        => '¡No se encuentra el proyecto en la base de datos!',
+  'Receipt'                     => 'Recibo',
+  'Reference'                   => 'Referencia',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the names below' => 'Seleccione uno de los nombres de la lista',
+  'Select from one of the projects below' => 'Seleccione uno de los proyectos de la lista',
+  'To'                          => 'Hasta ',
+  'Update'                      => 'Actualizar',
+  'Vendor'                      => 'Proveedor',
+  'Vendor not on file!'         => '¡No se encuentra el proveedor en la base de datos!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+  'registrar'                   => 'post',
+  'imprimir'                    => 'print',
+  'actualizar'                  => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/es/ct b/sql-ledger/locale/es/ct
new file mode 100644 (file)
index 0000000..e37ddd8
--- /dev/null
@@ -0,0 +1,69 @@
+$self{texts} = {
+  'Add'                         => 'Añadir',
+  'Address'                     => 'Dirección',
+  'All'                         => 'Todos',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => '¡No se puede borrar el cliente!',
+  'Cannot delete vendor!'       => '¡No se puede borrar el vendedor!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Limite de credito',
+  'Customer deleted!'           => '¡Cliente borrado!',
+  'Customer saved!'             => '¡Cliente guardado!',
+  'Customers'                   => 'Clientes',
+  'Delete'                      => 'Borrar',
+  'Discount'                    => 'Descuento',
+  'E-mail'                      => 'Correo electrónico',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Incluir en informe',
+  'Invoice'                     => 'Factura',
+  'Name'                        => 'Nombre',
+  'Name missing!'               => '¡Falta el nombre!',
+  'Notes'                       => 'Notas',
+  'Number'                      => 'Número',
+  'Order'                       => 'Orden',
+  'Orphaned'                    => 'Huérfano',
+  'Phone'                       => 'Teléfono',
+  'Save'                        => 'Guardar',
+  'Ship to'                     => 'Destino',
+  'Tax Included'                => 'Impuestos incluidos en el precio',
+  'Taxable'                     => 'Impuestos gravables',
+  'Terms: Net'                  => 'Crédito',
+  'Transactions exist, cannot delete customer!' => 'Existen transacciones para este cliente, por tanto, no puede borrarlo',
+  'Transactions exist, cannot delete vendor!' => 'Existen transacciones para este proveedor, por tanto, no puede borrarlo',
+  'Vendor deleted!'             => '¡Proveedor borrado!',
+  'Vendor saved!'               => '¡Proveedor guardado!',
+  'Vendors'                     => 'Proveedores',
+  'days'                        => 'días',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'añadir'                      => 'add',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'factura'                     => 'invoice',
+  'orden'                       => 'order',
+  'guardar'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/es/gl b/sql-ledger/locale/es/gl
new file mode 100644 (file)
index 0000000..10978f9
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Gestión se pago',
+  'AR Transaction'              => 'Gestión de cobro',
+  'Account'                     => 'Cuenta',
+  'Add General Ledger Transaction' => 'Añadir transacción al libro mayor general',
+  'Address'                     => 'Dirección',
+  'All'                         => 'Todos',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => '¿Está seguro de que desea borrar la transacción?',
+  'Asset'                       => 'Activo',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Balance',
+  'Cannot delete transaction!'  => '¡No se puede borrar la transacción!',
+  'Cannot have a value in both Debit and Credit!' => 'No puede tener un valor en débito y crédito simultáneamente!',
+  'Cannot post a transaction without a value!' => '¡No se puede registrar una transacción sin valor!',
+  'Cannot post transaction for a closed period!' => '¡No se puede registrar una transacción para un periodo cerrado',
+  'Confirm!'                    => 'Confirmar',
+  'Continue'                    => 'Continuar',
+  'Credit'                      => 'Crédito',
+  'Customer not on file!'       => '¡El cliente no existe!',
+  'Date'                        => 'Fecha',
+  'Debit'                       => 'Débito',
+  'Debit and credit out of balance!' => 'Los débitos y créditos están fuera de balance',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Edit General Ledger Transaction' => 'Editar transacción del libro mayor general',
+  'Equity'                      => 'Balance',
+  'Expense'                     => 'Gastos',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'Código GIFI',
+  'GL Transaction'              => 'Transacción en el libro mayor',
+  'General Ledger'              => 'Libro mayor general',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluir en informe',
+  'Income'                      => 'Ingresos',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Liability'                   => 'Pasivo',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Post'                        => 'Registrar',
+  'Post as new'                 => 'Registrar como nuevo',
+  'Project'                     => 'Proyecto',
+  'Project not on file!'        => '¡No se encuentra el proyecto en la base de datos!',
+  'Purchase Invoice'            => 'Factura de compras',
+  'Reference'                   => 'Referencia',
+  'Reference missing!'          => '¡Falta la referencia!',
+  'Reports'                     => 'Informes',
+  'Sales Invoice'               => 'Facturas de ventas',
+  'Select from one of the names below' => 'Seleccione uno de los nombres de la lista',
+  'Select from one of the projects below' => 'Seleccione uno de los proyectos de la lista',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Source'                      => 'Fuente',
+  'Subtotal'                    => 'Subtotal',
+  'To'                          => 'Hasta ',
+  'Transaction Date missing!'   => 'No se ha definido la fecha de la transacción',
+  'Transaction deleted!'        => '¡Transacción borrada!',
+  'Transaction posted!'         => '¡Transacción registrada!',
+  'Update'                      => 'Actualizar',
+  'Vendor not on file!'         => '¡No se encuentra el proveedor en la base de datos!',
+  'Yes'                         => 'Si',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'gestión_se_pago'             => 'ap_transaction',
+  'gestión_de_cobro'            => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'transacción_en_el_libro_mayor' => 'gl_transaction',
+  'registrar'                   => 'post',
+  'registrar_como_nuevo'        => 'post_as_new',
+  'factura_de_compras'          => 'purchase_invoice',
+  'facturas_de_ventas'          => 'sales_invoice',
+  'actualizar'                  => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/es/ic b/sql-ledger/locale/es/ic
new file mode 100644 (file)
index 0000000..9db330b
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Activo',
+  'Add'                         => 'Añadir',
+  'Add Assembly'                => 'Añadir compuesto',
+  'Add Part'                    => 'Añadir artículo',
+  'Add Purchase Order'          => 'Añadir pedido',
+  'Add Sales Order'             => 'Añadir presupuesto',
+  'Add Service'                 => 'Añadir servicio',
+  'Address'                     => 'Dirección',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Assemblies'                  => 'Compuestos',
+  'Assemblies restocked!'       => '¡Compuestos actualizados en almacen!',
+  'Assembly Number missing!'    => 'No se ha definido el número de compuesto',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'BOM'                         => 'Listado de piezas',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Bought'                      => 'Comprado',
+  'COGS'                        => 'Costo de los artículos',
+  'Cannot delete item already invoiced!' => 'No se puede borrar un artículo ya facturado',
+  'Cannot delete item on order!' => 'No se puede eliminar un elemento presente en una orden',
+  'Cannot delete item which is part of an assembly!' => 'No puede eliminar un artículo que es parte de un compuesto',
+  'Cannot delete item!'         => '¡No se puede borrar el artículo!',
+  'Cannot stock assemblies!'    => '¡No se pueden almacenar los compuestos!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Fecha de entrega',
+  'Description'                 => 'Descripción',
+  'Drawing'                     => 'Reintegro',
+  'E-mail'                      => 'Correo electrónico',
+  'E-mail address missing!'     => 'No se ha definido el correo electrónico',
+  'Edit Assembly'               => 'Editar compuesto',
+  'Edit Part'                   => 'Editar compuesto',
+  'Edit Service'                => 'Editar servicio',
+  'Expense'                     => 'Gastos',
+  'Extended'                    => 'Extendido',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'Image'                       => 'Imagen',
+  'In-line'                     => 'Incrustado',
+  'Include in Report'           => 'Incluir en informe',
+  'Income'                      => 'Ingresos',
+  'Individual Items'            => 'Artículos individuales',
+  'Inventory'                   => 'Inventario',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'La cantidad en inventario debe ser cero antes de cambiar este compuesto a obsoleto',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'La cantidad en inventario debe ser cero antes de cambiar este artículo a obsoleto',
+  'Inventory quantity must be zero!' => 'La cantidad en inventario debe ser cero',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'No se ha definido la fecha de la factura',
+  'Invoice Number'              => 'Número de factura',
+  'Invoice Number missing!'     => 'No se ha definido el número de la factura',
+  'Item deleted!'               => '¡Concepto borrado!',
+  'Item not on file!'           => 'El concepto no se encuentra en ningún archivo',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Last Cost'                   => 'Ultimo costo',
+  'Line Total'                  => 'Total de la línea',
+  'Link Accounts'               => 'Enlazar cuentas',
+  'List Price'                  => 'Precio de lista',
+  'Make'                        => 'Marca',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Microfiche'                  => 'Microficha',
+  'Model'                       => 'Modelo',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se ha definido el número en la fila',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'On Hand'                     => 'Disponible',
+  'On Order'                    => 'En pedido',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'No se ha definido la fecha de la elaboración',
+  'Order Number'                => 'Número de orden',
+  'Order Number missing!'       => 'No se ha definido el número de la orden',
+  'Ordered'                     => 'Pedido realizado',
+  'Orphaned'                    => 'Huérfano',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Albarán',
+  'Packing List Date missing!'  => 'No se ha definido la fecha del albarán',
+  'Packing List Number missing!' => 'No se ha definido el número del albarán',
+  'Part'                        => 'Artículo',
+  'Part Number missing!'        => 'No se ha definido el número del artículo',
+  'Parts'                       => 'Artículos',
+  'Phone'                       => 'Teléfono',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Proyecto',
+  'Purchase Order'              => 'Pedido',
+  'Qty'                         => 'Cantidad',
+  'ROP'                         => 'Tope de envio',
+  'Recd'                        => 'Cobrado',
+  'Required by'                 => 'Aceptado el',
+  'Sales'                       => 'Ventas',
+  'Sales Order'                 => 'Presupuesto',
+  'Save'                        => 'Guardar',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los artículos siguientes',
+  'Select postscript or PDF!'   => '¡Seleccione postscript o PDF',
+  'Sell Price'                  => 'Precio de venta',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Service Number missing!'     => 'No se ha definido el número de servicio',
+  'Services'                    => 'Servicios',
+  'Ship'                        => 'Envio',
+  'Ship to'                     => 'Destino',
+  'Short'                       => 'Corto',
+  'Sold'                        => 'Vendido',
+  'Stock Assembly'              => 'Inventariar compuesto',
+  'Subject'                     => 'Asunto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'To'                          => 'Hasta ',
+  'Top Level'                   => 'Top Level',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Unit of measure'             => 'Unidad de medida',
+  'Update'                      => 'Actualizar',
+  'Updated'                     => '¡Actualizado!',
+  'Weight'                      => 'Peso',
+  'What type of item is this?'  => '¿De qué tipo es este concepto?',
+  'ea'                          => 'unid.',
+  'emailed to'                  => 'enviado por correo electrónico a',
+  'hr'                          => 'hr',
+  'sent to printer'             => 'enviado a la impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'añadir'                      => 'add',
+  'añadir_compuesto'            => 'add_assembly',
+  'añadir_artículo'             => 'add_part',
+  'añadir_servicio'             => 'add_service',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'editar_compuesto'            => 'edit_assembly',
+  'editar_compuesto'            => 'edit_part',
+  'editar_servicio'             => 'edit_service',
+  'guardar'                     => 'save',
+  'actualizar'                  => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/es/io b/sql-ledger/locale/es/io
new file mode 100644 (file)
index 0000000..0f12d08
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Añadir pedido',
+  'Add Sales Order'             => 'Añadir presupuesto',
+  'Address'                     => 'Dirección',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delivery Date'               => 'Fecha de entrega',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'Correo electrónico',
+  'E-mail address missing!'     => 'No se ha definido el correo electrónico',
+  'Extended'                    => 'Extendido',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'In-line'                     => 'Incrustado',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'No se ha definido la fecha de la factura',
+  'Invoice Number missing!'     => 'No se ha definido el número de la factura',
+  'Item not on file!'           => 'El concepto no se encuentra en ningún archivo',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se ha definido el número en la fila',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'No se ha definido la fecha de la elaboración',
+  'Order Number missing!'       => 'No se ha definido el número de la orden',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Albarán',
+  'Packing List Date missing!'  => 'No se ha definido la fecha del albarán',
+  'Packing List Number missing!' => 'No se ha definido el número del albarán',
+  'Part'                        => 'Artículo',
+  'Phone'                       => 'Teléfono',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Proyecto',
+  'Purchase Order'              => 'Pedido',
+  'Qty'                         => 'Cantidad',
+  'Recd'                        => 'Cobrado',
+  'Required by'                 => 'Aceptado el',
+  'Sales Order'                 => 'Presupuesto',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los artículos siguientes',
+  'Select postscript or PDF!'   => '¡Seleccione postscript o PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Envio',
+  'Ship to'                     => 'Destino',
+  'Subject'                     => 'Asunto',
+  'To'                          => 'Hasta ',
+  'Unit'                        => 'Unidad',
+  'What type of item is this?'  => '¿De qué tipo es este concepto?',
+  'emailed to'                  => 'enviado por correo electrónico a',
+  'sent to printer'             => 'enviado a la impresora',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/es/ir b/sql-ledger/locale/es/ir
new file mode 100644 (file)
index 0000000..0e0aa7b
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Add Purchase Invoice'        => 'Añadir factura de compra',
+  'Add Purchase Order'          => 'Añadir pedido',
+  'Add Sales Order'             => 'Añadir presupuesto',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => '¿Esta seguro de que desea borrar la factura número',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => '¡No se puede borrar la factura!',
+  'Cannot post invoice for a closed period!' => '¡No se puede registrar una factura en un periodo ya cerrado!',
+  'Cannot post invoice!'        => '¡No se puede registrar la factura!',
+  'Cannot post payment for a closed period!' => '¡No se puede registrar un pago en un periodo ya cerrado!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Currency'                    => 'Moneda',
+  'Customer not on file!'       => '¡El cliente no existe!',
+  'Date'                        => 'Fecha',
+  'Date Due'                    => 'Fecha de vencimiento',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Fecha de entrega',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'Correo electrónico',
+  'E-mail address missing!'     => 'No se ha definido el correo electrónico',
+  'Edit Purchase Invoice'       => 'Editar factura de compra',
+  'Exch'                        => 'Cambio',
+  'Exchangerate'                => 'Tasa de cambio',
+  'Exchangerate for payment missing!' => '¡Falta la tasa de cambio para el pago!',
+  'Exchangerate missing!'       => '¡Falta la tasa de cambio!',
+  'Extended'                    => 'Extendido',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'In-line'                     => 'Incrustado',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de factura',
+  'Invoice Date missing!'       => 'No se ha definido la fecha de la factura',
+  'Invoice Number'              => 'Número de factura',
+  'Invoice Number missing!'     => 'No se ha definido el número de la factura',
+  'Invoice deleted!'            => '¡Factura borrada!',
+  'Invoice posted!'             => '¡Factura registrada!',
+  'Item not on file!'           => 'El concepto no se encuentra en ningún archivo',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se ha definido el número en la fila',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'No se ha definido la fecha de la elaboración',
+  'Order Number'                => 'Número de orden',
+  'Order Number missing!'       => 'No se ha definido el número de la orden',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Albarán',
+  'Packing List Date missing!'  => 'No se ha definido la fecha del albarán',
+  'Packing List Number missing!' => 'No se ha definido el número del albarán',
+  'Part'                        => 'Artículo',
+  'Payment date missing!'       => 'No se encuentra la fecha de pago',
+  'Payments'                    => 'Vencimientos impagados',
+  'Phone'                       => 'Teléfono',
+  'Post'                        => 'Registrar',
+  'Post as new'                 => 'Registrar como nuevo',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Proyecto',
+  'Project not on file!'        => '¡No se encuentra el proyecto en la base de datos!',
+  'Purchase Order'              => 'Pedido',
+  'Qty'                         => 'Cantidad',
+  'Recd'                        => 'Cobrado',
+  'Record in'                   => 'Registrar en',
+  'Required by'                 => 'Aceptado el',
+  'Sales Order'                 => 'Presupuesto',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los artículos siguientes',
+  'Select from one of the names below' => 'Seleccione uno de los nombres de la lista',
+  'Select from one of the projects below' => 'Seleccione uno de los proyectos de la lista',
+  'Select postscript or PDF!'   => '¡Seleccione postscript o PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Envio',
+  'Ship to'                     => 'Destino',
+  'Source'                      => 'Fuente',
+  'Subject'                     => 'Asunto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Impuestos incluidos en el precio',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Update'                      => 'Actualizar',
+  'Vendor'                      => 'Proveedor',
+  'Vendor missing!'             => '¡Falta el proveedor!',
+  'Vendor not on file!'         => '¡No se encuentra el proveedor en la base de datos!',
+  'What type of item is this?'  => '¿De qué tipo es este concepto?',
+  'Yes'                         => 'Si',
+  'ea'                          => 'unid.',
+  'emailed to'                  => 'enviado por correo electrónico a',
+  'sent to printer'             => 'enviado a la impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'orden'                       => 'order',
+  'registrar'                   => 'post',
+  'registrar_como_nuevo'        => 'post_as_new',
+  'actualizar'                  => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/es/is b/sql-ledger/locale/es/is
new file mode 100644 (file)
index 0000000..c1fa75a
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Add Purchase Order'          => 'Añadir pedido',
+  'Add Sales Invoice'           => 'Añadir factura',
+  'Add Sales Order'             => 'Añadir presupuesto',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => '¿Esta seguro de que desea borrar la factura número',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => '¡No se puede borrar la factura!',
+  'Cannot post invoice for a closed period!' => '¡No se puede registrar una factura en un periodo ya cerrado!',
+  'Cannot post invoice!'        => '¡No se puede registrar la factura!',
+  'Cannot post payment for a closed period!' => '¡No se puede registrar un pago en un periodo ya cerrado!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Credit Limit'                => 'Limite de credito',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => '¡Falta el cliente!',
+  'Customer not on file!'       => '¡El cliente no existe!',
+  'Date'                        => 'Fecha',
+  'Date Due'                    => 'Fecha de vencimiento',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Fecha de entrega',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'Correo electrónico',
+  'E-mail address missing!'     => 'No se ha definido el correo electrónico',
+  'Edit Sales Invoice'          => 'Edirar factura de venta',
+  'Exch'                        => 'Cambio',
+  'Exchangerate'                => 'Tasa de cambio',
+  'Exchangerate for payment missing!' => '¡Falta la tasa de cambio para el pago!',
+  'Exchangerate missing!'       => '¡Falta la tasa de cambio!',
+  'Extended'                    => 'Extendido',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'In-line'                     => 'Incrustado',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de factura',
+  'Invoice Date missing!'       => 'No se ha definido la fecha de la factura',
+  'Invoice Number'              => 'Número de factura',
+  'Invoice Number missing!'     => 'No se ha definido el número de la factura',
+  'Invoice deleted!'            => '¡Factura borrada!',
+  'Invoice posted!'             => '¡Factura registrada!',
+  'Item not on file!'           => 'El concepto no se encuentra en ningún archivo',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se ha definido el número en la fila',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'No se ha definido la fecha de la elaboración',
+  'Order Number'                => 'Número de orden',
+  'Order Number missing!'       => 'No se ha definido el número de la orden',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Albarán',
+  'Packing List Date missing!'  => 'No se ha definido la fecha del albarán',
+  'Packing List Number missing!' => 'No se ha definido el número del albarán',
+  'Part'                        => 'Artículo',
+  'Payment date missing!'       => 'No se encuentra la fecha de pago',
+  'Payments'                    => 'Vencimientos impagados',
+  'Phone'                       => 'Teléfono',
+  'Post'                        => 'Registrar',
+  'Post as new'                 => 'Registrar como nuevo',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Proyecto',
+  'Project not on file!'        => '¡No se encuentra el proyecto en la base de datos!',
+  'Purchase Order'              => 'Pedido',
+  'Qty'                         => 'Cantidad',
+  'Recd'                        => 'Cobrado',
+  'Record in'                   => 'Registrar en',
+  'Remaining'                   => 'Resto',
+  'Required by'                 => 'Aceptado el',
+  'Sales Order'                 => 'Presupuesto',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los artículos siguientes',
+  'Select from one of the names below' => 'Seleccione uno de los nombres de la lista',
+  'Select from one of the projects below' => 'Seleccione uno de los proyectos de la lista',
+  'Select postscript or PDF!'   => '¡Seleccione postscript o PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Envio',
+  'Ship to'                     => 'Destino',
+  'Ship via'                    => 'Envio por',
+  'Source'                      => 'Fuente',
+  'Subject'                     => 'Asunto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Impuestos incluidos en el precio',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Update'                      => 'Actualizar',
+  'Vendor not on file!'         => '¡No se encuentra el proveedor en la base de datos!',
+  'What type of item is this?'  => '¿De qué tipo es este concepto?',
+  'Yes'                         => 'Si',
+  'ea'                          => 'unid.',
+  'emailed to'                  => 'enviado por correo electrónico a',
+  'sent to printer'             => 'enviado a la impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'correo_electrónico'          => 'e_mail',
+  'orden'                       => 'order',
+  'registrar'                   => 'post',
+  'registrar_como_nuevo'        => 'post_as_new',
+  'imprimir'                    => 'print',
+  'destino'                     => 'ship_to',
+  'actualizar'                  => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/es/login b/sql-ledger/locale/es/login
new file mode 100644 (file)
index 0000000..f7a7cf0
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'Acerca de',
+  'Database Host'               => 'Máquina servidor de base de datos',
+  'Dataset'                     => 'Base de datos',
+  'Incorrect Dataset version!'  => 'Versión de base de datos incorrecta',
+  'Incorrect Password!'         => 'Contraseña incorrecta',
+  'Licensed to'                 => 'Adaptado para',
+  'Login'                       => 'Entrar',
+  'Name'                        => 'Nombre',
+  'Password'                    => 'Contraseña',
+  'User'                        => 'Usuario',
+  'Version'                     => 'Versión',
+  'You are logged out!'         => '¡Ya está desconectado del sistema!',
+  'You did not enter a name!'   => 'No ha introducido el nombre',
+  'is not a member!'            => 'no es miembro',
+  'localhost'                   => 'máquina local',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'entrar'                      => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/es/menu b/sql-ledger/locale/es/menu
new file mode 100644 (file)
index 0000000..d9aa9e0
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => 'Cartera de pagos',
+  'AP Aging'                    => 'Diario resumido de pagos',
+  'AR'                          => 'Cartera de cobros',
+  'AR Aging'                    => 'Diario resumido de cobros ',
+  'Accounting Menu'             => 'Menú general',
+  'Add Account'                 => 'Añadir cuenta',
+  'Add Assembly'                => 'Añadir compuesto',
+  'Add Customer'                => 'Añadir cliente',
+  'Add GIFI'                    => 'Añadir código GIFI',
+  'Add Part'                    => 'Añadir artículo',
+  'Add Project'                 => 'Añadir proyecto',
+  'Add Service'                 => 'Añadir servicio',
+  'Add Transaction'             => 'Añadir',
+  'Add Vendor'                  => 'Añadir proveedor',
+  'Assemblies'                  => 'Compuestos',
+  'Audit Control'               => 'Control de auditoría',
+  'Backup'                      => 'Copia de seguridad de los datos',
+  'Balance Sheet'               => 'Hoja de balance',
+  'Cash'                        => 'Efectivo',
+  'Chart of Accounts'           => 'Cuadro de cuentas',
+  'Check'                       => 'Cheque',
+  'Customers'                   => 'Clientes',
+  'General Ledger'              => 'Libro mayor general',
+  'Goods & Services'            => 'Bienes y servicios',
+  'HTML Templates'              => 'Plantillas HTML',
+  'Income Statement'            => 'Balance de situación',
+  'Invoice'                     => 'Factura',
+  'LaTeX Templates'             => 'Plantillas LaTeX',
+  'List Accounts'               => 'Listar cuentas',
+  'List GIFI'                   => 'Listar código GIFI',
+  'Logout'                      => 'Salir',
+  'Order Entry'                 => 'Presupuestos y pedidos',
+  'Packing List'                => 'Albarán',
+  'Parts'                       => 'Artículos',
+  'Payment'                     => 'Pago',
+  'Payments'                    => 'Vencimientos impagados',
+  'Preferences'                 => 'Preferencias',
+  'Projects'                    => 'Proyectos',
+  'Purchase Invoice'            => 'Factura de compras',
+  'Purchase Order'              => 'Pedido',
+  'Purchase Orders'             => 'Pedidos',
+  'Receipt'                     => 'Recibo',
+  'Receipts'                    => 'Recibos',
+  'Reconciliation'              => 'Reconciliación',
+  'Reports'                     => 'Informes',
+  'Sales Invoice'               => 'Facturas de ventas',
+  'Sales Order'                 => 'Presupuesto',
+  'Sales Orders'                => 'Presupuestos',
+  'Save to File'                => 'Guardar en un archivo',
+  'Send by E-Mail'              => 'Enviar por correo electrónico',
+  'Services'                    => 'Servicios',
+  'Statement'                   => 'Estado de cuenta',
+  'Stock Assembly'              => 'Inventariar compuesto',
+  'Stylesheet'                  => 'Hoja de estilo',
+  'System'                      => 'Sistema',
+  'Tax collected'               => 'Impuestos cobrados',
+  'Tax paid'                    => 'Impuestos pagados',
+  'Transactions'                => 'Impagados',
+  'Trial Balance'               => 'Balance de comprobación',
+  'Vendors'                     => 'Proveedores',
+  'Version'                     => 'Versión',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/es/oe b/sql-ledger/locale/es/oe
new file mode 100644 (file)
index 0000000..3eb55b9
--- /dev/null
@@ -0,0 +1,200 @@
+$self{texts} = {
+  'Add'                         => 'Añadir',
+  'Add Purchase Invoice'        => 'Añadir factura de compra',
+  'Add Purchase Order'          => 'Añadir pedido',
+  'Add Sales Invoice'           => 'Añadir factura',
+  'Add Sales Order'             => 'Añadir presupuesto',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Order Number' => '¿Esta seguro de que desea
+borrar la orden número?',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'C'                           => 'C',
+  'Cannot delete order!'        => '¡No se puede borrar el pedido!',
+  'Cannot save order!'          => '¡No se puede guardar el pedido!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Cerrado',
+  'Confirm!'                    => 'Confirmar',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Credit Limit'                => 'Limite de credito',
+  'Curr'                        => 'Mon.',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => '¡Falta el cliente!',
+  'Customer not on file!'       => '¡El cliente no existe!',
+  'Date'                        => 'Fecha',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Fecha de entrega',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'Correo electrónico',
+  'E-mail address missing!'     => 'No se ha definido el correo electrónico',
+  'Edit Purchase Order'         => 'Editar pedido',
+  'Edit Sales Order'            => 'Editar presupuesto',
+  'Exchangerate'                => 'Tasa de cambio',
+  'Exchangerate missing!'       => '¡Falta la tasa de cambio!',
+  'Extended'                    => 'Extendido',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Incrustado',
+  'Include in Report'           => 'Incluir en informe',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'No se ha definido la fecha de la factura',
+  'Invoice Number missing!'     => 'No se ha definido el número de la factura',
+  'Item not on file!'           => 'El concepto no se encuentra en ningún archivo',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se ha definido el número en la fila',
+  'O'                           => 'O',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Open'                        => 'Abierto',
+  'Order'                       => 'Orden',
+  'Order Date'                  => 'Fecha de elaboración',
+  'Order Date missing!'         => 'No se ha definido la fecha de la elaboración',
+  'Order Number'                => 'Número de orden',
+  'Order Number missing!'       => 'No se ha definido el número de la orden',
+  'Order deleted!'              => '¡Orden borrada!',
+  'Order saved!'                => '¡Orden guardada!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Albarán',
+  'Packing List Date missing!'  => 'No se ha definido la fecha del albarán',
+  'Packing List Number missing!' => 'No se ha definido el número del albarán',
+  'Part'                        => 'Artículo',
+  'Phone'                       => 'Teléfono',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Proyecto',
+  'Project not on file!'        => '¡No se encuentra el proyecto en la base de datos!',
+  'Purchase Order'              => 'Pedido',
+  'Purchase Orders'             => 'Pedidos',
+  'Qty'                         => 'Cantidad',
+  'Recd'                        => 'Cobrado',
+  'Remaining'                   => 'Resto',
+  'Required by'                 => 'Aceptado el',
+  'Sales Order'                 => 'Presupuesto',
+  'Sales Orders'                => 'Presupuestos',
+  'Save'                        => 'Guardar',
+  'Save as new'                 => 'Guardar como nuevo',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los artículos siguientes',
+  'Select from one of the names below' => 'Seleccione uno de los nombres de la lista',
+  'Select from one of the projects below' => 'Seleccione uno de los proyectos de la lista',
+  'Select postscript or PDF!'   => '¡Seleccione postscript o PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Envio',
+  'Ship to'                     => 'Destino',
+  'Ship via'                    => 'Envio por',
+  'Subject'                     => 'Asunto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'Tax Included'                => 'Impuestos incluidos en el precio',
+  'Terms: Net'                  => 'Crédito',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Update'                      => 'Actualizar',
+  'Vendor'                      => 'Proveedor',
+  'Vendor missing!'             => '¡Falta el proveedor!',
+  'Vendor not on file!'         => '¡No se encuentra el proveedor en la base de datos!',
+  'What type of item is this?'  => '¿De qué tipo es este concepto?',
+  'Yes'                         => 'Si',
+  'days'                        => 'días',
+  'ea'                          => 'unid.',
+  'emailed to'                  => 'enviado por correo electrónico a',
+  'sent to printer'             => 'enviado a la impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'añadir'                      => 'add',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'correo_electrónico'          => 'e_mail',
+  'factura'                     => 'invoice',
+  'imprimir'                    => 'print',
+  'guardar'                     => 'save',
+  'guardar_como_nuevo'          => 'save_as_new',
+  'destino'                     => 'ship_to',
+  'actualizar'                  => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/es/pe b/sql-ledger/locale/es/pe
new file mode 100644 (file)
index 0000000..3599b7e
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Añadir',
+  'Add Project'                 => 'Añadir proyecto',
+  'All'                         => 'Todos',
+  'Continue'                    => 'Continuar',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Edit Project'                => 'Editar proyecto',
+  'Number'                      => 'Número',
+  'Orphaned'                    => 'Huérfano',
+  'Project'                     => 'Proyecto',
+  'Project Number missing!'     => '¡Falta el número de proyecto!',
+  'Project deleted!'            => '¡Proyecto borrado!',
+  'Project saved!'              => '¡Proyecto guardado ',
+  'Projects'                    => 'Proyectos',
+  'Save'                        => 'Guardar',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'añadir'                      => 'add',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'guardar'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/es/rc b/sql-ledger/locale/es/rc
new file mode 100644 (file)
index 0000000..20183f1
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Balance'                     => 'Balance',
+  'Cleared Balance'             => 'Balance cerrado',
+  'Continue'                    => 'Continuar',
+  'Date'                        => 'Fecha',
+  'Deposit'                     => 'Depósito',
+  'Description'                 => 'Descripción',
+  'Difference'                  => 'Diferencia',
+  'Done'                        => 'Hecho',
+  'Exchangerate Difference'     => 'Diferencia en la tasa cambio a moneda extranjera',
+  'From'                        => 'Desde',
+  'Out of balance!'             => '¡Fuera de balance!',
+  'Payment'                     => 'Pago',
+  'Reconciliation'              => 'Reconciliación',
+  'Select all'                  => 'Guardar todo',
+  'Source'                      => 'Fuente',
+  'Statement Balance'           => 'Balance de cuenta',
+  'To'                          => 'Hasta ',
+  'Update'                      => 'Actualizar',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'continuar'                   => 'continue',
+  'hecho'                       => 'done',
+  'guardar_todo'                => 'select_all',
+  'actualizar'                  => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/es/rp b/sql-ledger/locale/es/rp
new file mode 100644 (file)
index 0000000..bce27f7
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'Diario resumido de pagos',
+  'AR Aging'                    => 'Diario resumido de cobros ',
+  'Account'                     => 'Cuenta',
+  'Accounts'                    => 'Cuentas',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance Sheet'               => 'Hoja de balance',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Efectivo inicial',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Comparar con',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Credit'                      => 'Crédito',
+  'Current'                     => 'Actual',
+  'Customer'                    => 'Cliente',
+  'Date'                        => 'Fecha',
+  'Debit'                       => 'Débito',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Decimalplaces'               => 'Lugar de los decimales',
+  'Description'                 => 'Descripción',
+  'Due'                         => 'Vence',
+  'E-mail'                      => 'Correo electrónico',
+  'E-mail Statement to'         => 'Enviar comprobante por correo electrónico a',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'Código GIFI',
+  'Heading'                     => 'Encabezado',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Incrustado',
+  'Include in Report'           => 'Incluir en informe',
+  'Income Statement'            => 'Balance de situación',
+  'Invoice'                     => 'Factura',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'N/A'                         => 'Sin respuesta',
+  'Nothing selected!'           => '¡No es seleccionado nada!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Vencimientos impagados',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impresora',
+  'Receipts'                    => 'Recibos',
+  'Report for'                  => 'Informe para',
+  'Retained Earnings'           => 'Ganacias retenidas',
+  'Screen'                      => 'Pantalla',
+  'Select all'                  => 'Guardar todo',
+  'Select postscript or PDF!'   => '¡Seleccione postscript o PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Source'                      => 'Fuente',
+  'Standard'                    => 'Estándard',
+  'Statement'                   => 'Estado de cuenta',
+  'Statement sent to'           => 'Estado de cuenta enviado a',
+  'Statements sent to printer!' => '¡Estado de cuenta enviado a la impresora!',
+  'Subject'                     => 'Asunto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'Tax collected'               => 'Impuestos cobrados',
+  'Tax paid'                    => 'Impuestos pagados',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Trial Balance'               => 'Balance de comprobación',
+  'Vendor'                      => 'Proveedor',
+  'as at'                       => 'al',
+  'collected on sales'          => 'ingresado en ventas',
+  'for Period'                  => 'para el periodo',
+  'paid on purchases'           => 'pagado en compras',
+  'to'                          => 'a',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'continuar'                   => 'continue',
+  'correo_electrónico'          => 'e_mail',
+  'imprimir'                    => 'print',
+  'guardar_todo'                => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/COPYING b/sql-ledger/locale/fi/COPYING
new file mode 100644 (file)
index 0000000..823094c
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2002
+#
+# Finish texts:
+#
+#  Author: Petri Leppänen <mpj@mail.htk.fi>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/fi/LANGUAGE b/sql-ledger/locale/fi/LANGUAGE
new file mode 100644 (file)
index 0000000..3435014
--- /dev/null
@@ -0,0 +1 @@
+Finnish
diff --git a/sql-ledger/locale/fi/admin b/sql-ledger/locale/fi/admin
new file mode 100644 (file)
index 0000000..b59d03b
--- /dev/null
@@ -0,0 +1,126 @@
+$self{texts} = {
+  'Access Control'              => 'Kulunvalvonta',
+  'Accounting'                  => 'Kirjanpito',
+  'Add User'                    => 'Lisää käyttäjä',
+  'Address'                     => 'Osoite',
+  'Administration'              => 'Ylläpito',
+  'Administrator'               => 'Pääkäyttäjä',
+  'All Datasets up to date!'    => 'Kaikki tietolähteet ajan tasalla',
+  'Change Admin Password'       => 'Muuta pääkäyttäjän salasana',
+  'Change Password'             => 'Muuta salasana',
+  'Character Set'               => 'Näppäimistökartta ',
+  'Click on login name to edit!' => 'Klikkaa kirjautumisnimeä muokataksesi sitä!',
+  'Company'                     => 'Yritys',
+  'Connect to'                  => 'Yhdistä',
+  'Continue'                    => 'Jatka',
+  'Create Chart of Accounts'    => 'Luo tilikartta',
+  'Create Dataset'              => 'Luo tietolähteet',
+  'DBI not installed!'          => 'DBI ei ole asennettu!',
+  'Database'                    => 'Tietokanta',
+  'Database Administration'     => 'Tietokannan ylläpito',
+  'Database Driver not checked!' => 'Tietokanta-ajuria ei ole tarkastettu',
+  'Database User missing!'      => 'Tietokannan käyttäjä puuttuu',
+  'Dataset'                     => 'Tietolähde',
+  'Dataset missing!'            => 'Tietolähde puuttuu',
+  'Dataset updated!'            => 'Tietolähde päivitetty',
+  'Date Format'                 => 'Päiväyksen muoto',
+  'Delete'                      => 'Poista',
+  'Delete Dataset'              => 'Poista tietolähde',
+  'Directory'                   => 'Hakemisto',
+  'Driver'                      => 'Ajuri',
+  'Dropdown Limit'              => 'Pudotusvalikkon rivimäärä',
+  'E-mail'                      => 'Sähköposti',
+  'Edit User'                   => 'Muokkaa käyttäjää',
+  'Existing Datasets'           => 'Nykyiset tietolähteet',
+  'Fax'                         => 'Faksi',
+  'File locked!'                => 'Tiedosto lukittu',
+  'Host'                        => 'Isäntätietokone',
+  'Hostname missing!'           => 'Isäntätietokoneen nimi puuttuu',
+  'Incorrect Password!'         => 'Väärä salasana!',
+  'Language'                    => 'Kieli',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Jätä isäntä- ja porttikentät tyhjiksi mikäli et halua ottaa etäyhteyttä.',
+  'Login'                       => 'Kirjaudu',
+  'Multibyte Encoding'          => 'Itämaisten kielten tuki',
+  'Name'                        => 'Nimi',
+  'New Templates'               => 'Uusi malli',
+  'No Database Drivers available!' => 'Tietokanta-ajuria ei saatavilla!',
+  'No Dataset selected!'        => 'Ei tietolähdettä valittuna!',
+  'Nothing to delete!'          => 'Ei poistettavaa!',
+  'Number Format'               => 'Numeron muoto',
+  'Oracle Database Administration' => 'Oracle-tietokannan ylläpito',
+  'Password'                    => 'Salasana',
+  'Password changed!'           => 'Salasana muutettu!',
+  'Pg Database Administration'  => 'Postgres tietokannan ylläpito',
+  'Phone'                       => 'Puhelin',
+  'Port'                        => 'Portti',
+  'Port missing!'               => 'Portti puuttuu!',
+  'Printer'                     => 'Kirjoitin',
+  'Save'                        => 'Tallenna',
+  'Select a Dataset to delete and press "Continue"' => 'Valitse poistettava tietolähde ja 
+paina jatka',
+  'Setup Templates'             => 'Aseta mallit',
+  'Ship via'                    => 'Lähetä kautta',
+  'Signature'                   => 'Allekirjoitus',
+  'Stylesheet'                  => 'Tyylimalli',
+  'Templates'                   => 'Mallit',
+  'The following Datasets are not in use and can be deleted' => 'Seuraavat tietolähteet 
+eivät ole käytössä ja voidaan poistaa',
+  'The following Datasets need to be updated' => 'Seuraavat tietolähteet päivitettävä',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Tämä on olemassa olevien lähteiden ennakkotarkistus. Mitään ei luoda tai poisteta tässä vaiheessa!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Lisätäksesi käyttäjän ryhmään muokkaa nimeä, muuta kirjautumisnimi ja tallenna.',
+  'Update Dataset'              => 'Päivitä tietolähde',
+  'Use Templates'               => 'Käytä mallia',
+  'User'                        => 'Käyttäjä',
+  'User deleted!'               => 'Käyttäjä poistettu!',
+  'User saved!'                 => 'Käyttäjä tallennettu!',
+  'Version'                     => 'Versio',
+  'You must enter a host and port for local and remote connections!' => 'Sinun täytyy antaa isäntäkone ja portti paikallisille ja etäyhteyksille!',
+  'does not exist'              => 'ei löydy',
+  'is already a member!'        => 'on jo käyttäjä',
+  'localhost'                   => 'paikallinen tietokone',
+  'successfully created!'       => 'onnistuneesti luotu',
+  'successfully deleted!'       => 'onnistuneesti poistettu',
+  'website'                     => 'www-sivu',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'lisää_käyttäjä'              => 'add_user',
+  'muuta_pääkäyttäjän_salasana' => 'change_admin_password',
+  'muuta_salasana'              => 'change_password',
+  'jatka'                       => 'continue',
+  'luo_tietolähteet'            => 'create_dataset',
+  'poista'                      => 'delete',
+  'poista_tietolähde'           => 'delete_dataset',
+  'kirjaudu'                    => 'login',
+  'oracle_tietokannan_ylläpito' => 'oracle_database_administration',
+  'postgres_tietokannan_ylläpito' => 'pg_database_administration',
+  'tallenna'                    => 'save',
+  'päivitä_tietolähde'          => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/all b/sql-ledger/locale/fi/all
new file mode 100644 (file)
index 0000000..a3c22c5
--- /dev/null
@@ -0,0 +1,494 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Ostot',
+  'AP Aging'                    => 'Erääntyvät ostolaskut',
+  'AP Transaction'              => 'Ostotapahtuma',
+  'AP Transactions'             => 'Ostotapahtumat',
+  'AR'                          => 'Myynnit',
+  'AR Aging'                    => 'Erääntyvät myyntilaskut',
+  'AR Transaction'              => 'Myyntitapahtuma',
+  'AR Transactions'             => 'Myyntitapahtumat',
+  'About'                       => 'Lisätietoja',
+  'Access Control'              => 'Kulunvalvonta',
+  'Account'                     => 'Tili',
+  'Account Number'              => 'Tilinumero',
+  'Account Number missing!'     => 'Tilinumero puuttuu',
+  'Account Type'                => 'Tilityyppi',
+  'Account Type missing!'       => 'Tilityyppi puuttuu',
+  'Account deleted!'            => 'Tili poistettu',
+  'Account saved!'              => 'Tili lisätty',
+  'Accounting'                  => 'Kirjanpito',
+  'Accounting Menu'             => 'Kirjanpitovalikko',
+  'Accounts'                    => 'Tilit',
+  'Active'                      => 'Avoin',
+  'Add'                         => 'Lisää',
+  'Add Account'                 => 'Lisää tili',
+  'Add Accounts Payables Transaction' => 'Lisää ostotapahtuma',
+  'Add Accounts Receivables Transaction' => 'Lisää myyntitapahtuma',
+  'Add Assembly'                => 'Lisää tuote',
+  'Add Customer'                => 'Lisää asiakas',
+  'Add GIFI'                    => 'Lisää GIFI',
+  'Add General Ledger Transaction' => 'Lisää pääkirjatapahtuma',
+  'Add Part'                    => 'Lisää raaka-aine/tarvike',
+  'Add Project'                 => 'Lisää projekti',
+  'Add Purchase Invoice'        => 'Lisää ostolasku',
+  'Add Purchase Order'          => 'Ostotilaus',
+  'Add Sales Invoice'           => 'Lisää myyntilasku',
+  'Add Sales Order'             => 'Lisää tilausvahvistus',
+  'Add Service'                 => 'Lisää palvelu',
+  'Add Transaction'             => 'Lisää tapahtuma',
+  'Add User'                    => 'Lisää käyttäjä',
+  'Add Vendor'                  => 'Lisää toimittaja',
+  'Address'                     => 'Osoite',
+  'Administration'              => 'Ylläpito',
+  'Administrator'               => 'Pääkäyttäjä',
+  'All'                         => 'Kaikki',
+  'All Datasets up to date!'    => 'Kaikki tietolähteet ajan tasalla',
+  'Amount'                      => 'Summa',
+  'Amount Due'                  => 'Erääntyvä summa',
+  'Amount does not equal applied!' => 'Määrä eri kuin sovellettu',
+  'Amount missing!'             => 'Määrä puuttuu',
+  'Applied'                     => 'Sovellettu',
+  'Apr'                         => 'Huh',
+  'April'                       => 'Huhtikuu',
+  'Are you sure you want to delete Invoice Number' => 'Haluatko poistaa laskun numero?',
+  'Are you sure you want to delete Order Number' => 'Haluatko poistaa tilauksen numero',
+  'Are you sure you want to delete Transaction' => 'Haluatko poistaa viennin?',
+  'Assemblies'                  => 'Tuotteet',
+  'Assemblies restocked!'       => 'Tuotteet viety varastoon',
+  'Assembly Number missing!'    => 'Tuotenumero puuttuu!',
+  'Asset'                       => 'Vastaavaa',
+  'Attachment'                  => 'Liite',
+  'Audit Control'               => 'Tilien tarkistus',
+  'Aug'                         => 'Elo',
+  'August'                      => 'Elokuu',
+  'BOM'                         => 'Materiaalilista',
+  'Backup'                      => 'Varmuuskopio',
+  'Backup sent to'              => 'Varmuuskopio lähetetty',
+  'Balance'                     => 'Tase',
+  'Balance Sheet'               => 'Taselaskelma',
+  'Bcc'                         => 'Näkymätön kopio',
+  'Bin'                         => 'Varastopaikka',
+  'Books are open'              => 'Kirjat ovat avoinna',
+  'Bought'                      => 'Ostettu',
+  'Business Number'             => 'Y-numero',
+  'C'                           => 'C',
+  'COGS'                        => 'Myydyn tuotteen kulut',
+  'Cannot delete account!'      => 'Tiliä ei voi poistaa!',
+  'Cannot delete customer!'     => 'Asiakasta ei voi poistaa!',
+  'Cannot delete default account!' => 'Oletustiliä ei voi poistaa!',
+  'Cannot delete invoice!'      => 'Laskua ei voi poistaa!',
+  'Cannot delete item already invoiced!' => 'Laskutettua nimikettä ei voi poistaa!',
+  'Cannot delete item on order!' => 'Nimikettä tilauksessa ei voi poistaa',
+  'Cannot delete item which is part of an assembly!' => 'Tuotteen raaka-ainetta/tarviketta ei voi poistaa!',
+  'Cannot delete item!'         => 'Nimikettä ei voi poistaa!',
+  'Cannot delete order!'        => 'Tilausta ei voi poistaa!',
+  'Cannot delete transaction!'  => 'Vientiä ei voi poistaa',
+  'Cannot delete vendor!'       => 'Toimittajaa ei voi poistaa!',
+  'Cannot have a value in both Debit and Credit!' => 'Arvo sekä Kreditissä että Debetissä kielletty!',
+  'Cannot post a transaction without a value!' => 'Viennin kirjaus ilman arvoa kielletty!',
+  'Cannot post invoice for a closed period!' => 'Laskun kirjaus suljetulle ajanjaksolle kielletty!',
+  'Cannot post invoice!'        => 'Laskua ei voi kirjata!',
+  'Cannot post payment for a closed period!' => 'Maksun kirjaus suljetulle ajanjaksolle kielletty ',
+  'Cannot post payment!'        => 'Maksua ei voi kirjata!',
+  'Cannot post transaction for a closed period!' => 'Viennin kirjaus suljetulle ajanjaksolle kielletty',
+  'Cannot post transaction!'    => 'Vientiä ei voi kirjata',
+  'Cannot process payment for a closed period!' => 'Suljetun ajanjakson maksua ei voi käsitellä',
+  'Cannot save account!'        => 'Tilin tallennus ei onnistu!',
+  'Cannot save order!'          => 'Tilauksen tallennus ei onnistu!',
+  'Cannot save preferences!'    => 'Asetuksien tallennus ei onnistu!',
+  'Cannot stock assemblies!'    => 'Tuotteiden varastointi ei onnistu!',
+  'Cash'                        => 'Käteiskauppa',
+  'Cash based'                  => 'Käteiseen perustuva',
+  'Cc'                          => 'Kopio',
+  'Change Admin Password'       => 'Muuta pääkäyttäjän salasana',
+  'Change Password'             => 'Muuta salasana',
+  'Character Set'               => 'Näppäimistökartta ',
+  'Chart of Accounts'           => 'Tilikartta',
+  'Check'                       => 'Sekki',
+  'Check printed!'              => 'Sekki tulostettu!',
+  'Check printing failed!'      => 'Sekin tulostus epäonnistui!',
+  'Cleared Balance'             => 'Tarkistettu tase',
+  'Click on login name to edit!' => 'Klikkaa kirjautumisnimeä muokataksesi sitä!',
+  'Close Books up to'           => 'Sulje kirjat hetkeen',
+  'Closed'                      => 'Suljettu',
+  'Company'                     => 'Yritys',
+  'Compare to'                  => 'verrattuna',
+  'Confirm!'                    => 'Vahvista!',
+  'Connect to'                  => 'Yhdistä',
+  'Contact'                     => 'Yhteyshenkilö',
+  'Continue'                    => 'Jatka',
+  'Copies'                      => 'Kopiot',
+  'Copy to COA'                 => 'Kopioi tilikarttaan',
+  'Create Chart of Accounts'    => 'Luo tilikartta',
+  'Create Dataset'              => 'Luo tietolähteet',
+  'Credit'                      => 'Kredit',
+  'Credit Limit'                => 'Luottoraja',
+  'Curr'                        => 'Valuutta',
+  'Currency'                    => 'Valuutta',
+  'Current'                     => 'Erääntyy',
+  'Customer'                    => 'Asiakas',
+  'Customer deleted!'           => 'Asiakas poistettu!',
+  'Customer missing!'           => 'Asiakas puuttuu!',
+  'Customer not on file!'       => 'Asiakas ei järjestelmässä!',
+  'Customer saved!'             => 'Asiakas tallennettu!',
+  'Customers'                   => 'Asiakkaat',
+  'DBI not installed!'          => 'DBI ei ole asennettu!',
+  'Database'                    => 'Tietokanta',
+  'Database Administration'     => 'Tietokannan ylläpito',
+  'Database Driver not checked!' => 'Tietokanta-ajuria ei ole tarkastettu',
+  'Database Host'               => 'Tietokannan isäntä',
+  'Database User missing!'      => 'Tietokannan käyttäjä puuttuu',
+  'Dataset'                     => 'Tietolähde',
+  'Dataset missing!'            => 'Tietolähde puuttuu',
+  'Dataset updated!'            => 'Tietolähde päivitetty',
+  'Date'                        => 'Päiväys',
+  'Date Due'                    => 'Eräpäivä',
+  'Date Format'                 => 'Päiväyksen muoto',
+  'Date Paid'                   => 'Maksupäivä',
+  'Date missing!'               => 'Päiväys puuttuu',
+  'Debit'                       => 'Debet',
+  'Debit and credit out of balance!' => 'Debet ja kredit erisuuruiset',
+  'Dec'                         => 'Jou',
+  'December'                    => 'Joulukuu',
+  'Decimalplaces'               => 'Desimaalipaikkoja',
+  'Delete'                      => 'Poista',
+  'Delete Account'              => 'Poista tili',
+  'Delete Dataset'              => 'Poista tietolähde',
+  'Delivery Date'               => 'Toimituspäivä',
+  'Deposit'                     => 'Rahatallennus',
+  'Description'                 => 'Kuvaus',
+  'Difference'                  => 'Ero',
+  'Directory'                   => 'Hakemisto',
+  'Discount'                    => 'Alennus',
+  'Done'                        => 'Suoritettu!',
+  'Drawing'                     => 'Piirros',
+  'Driver'                      => 'Ajuri',
+  'Dropdown Limit'              => 'Pudotusvalikkon rivimäärä',
+  'Due'                         => 'Eräpv',
+  'Due Date'                    => 'Eräpäivä',
+  'Due Date missing!'           => 'Eräpäivä puuttuu!',
+  'E-mail'                      => 'Sähköposti',
+  'E-mail Statement to'         => 'Sähköpostilla tiliote kenelle',
+  'E-mail address missing!'     => 'Sähköpostiosoite puuttuu!',
+  'Edit'                        => 'Muokkaa',
+  'Edit Account'                => 'Muokkaa tiliä',
+  'Edit Accounts Payables Transaction' => 'Muokkaa ostovientiä',
+  'Edit Accounts Receivables Transaction' => 'Muokkaa myyntivientiä',
+  'Edit Assembly'               => 'Muokkaa tuotetta',
+  'Edit Customer'               => 'Muokkaa asiakas',
+  'Edit GIFI'                   => 'Muokkaa GIFI',
+  'Edit General Ledger Transaction' => 'Muokkaa pääkirjavientiä',
+  'Edit Part'                   => 'Muokkaa raaka-ainetta/tarviketta',
+  'Edit Preferences for'        => 'Muokkaa asetuksia',
+  'Edit Project'                => 'Muokkaa projektia',
+  'Edit Purchase Invoice'       => 'Muokkaa ostolaskua',
+  'Edit Purchase Order'         => 'Muokkaa ostotilausta',
+  'Edit Sales Invoice'          => 'Muokkaa myyntilaskua',
+  'Edit Sales Order'            => 'Muokkaa myyntitilausta',
+  'Edit Service'                => 'Muokkaa palvelua',
+  'Edit Template'               => 'Muokkaa mallia',
+  'Edit User'                   => 'Muokkaa käyttäjää',
+  'Edit Vendor'                 => 'Muokkaa ',
+  'Employee'                    => 'Työntekijä',
+  'Enforce transaction reversal for all dates' => 'Pakota muunnos kaikille viennille',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Merkitse käyttämäsi valuutat 3 kirjaimella ja erota ne kaksoispisteellä, esim.(EUR:USD:SEK).',
+  'Equity'                      => 'Oma pääoma',
+  'Exch'                        => 'Vaihtokurssi',
+  'Exchangerate'                => 'Vaihtokurssi',
+  'Exchangerate Difference'     => 'Vaihtokurssin ero',
+  'Exchangerate for payment missing!' => 'Maksun vaihtokurssi puuttuu',
+  'Exchangerate missing!'       => 'Vaihtokurssi puuttuu',
+  'Existing Datasets'           => 'Nykyiset tietolähteet',
+  'Expense'                     => 'Menot',
+  'Expense Account'             => 'Menotili',
+  'Expense/Asset'               => 'Menot/Varat',
+  'Extended'                    => 'Pidennetty',
+  'Fax'                         => 'Faksi',
+  'Feb'                         => 'Hel',
+  'February'                    => 'Helmikuu',
+  'File locked!'                => 'Tiedosto lukittu',
+  'Foreign Exchange Gain'       => 'Vaihtokurssivoitto',
+  'Foreign Exchange Loss'       => 'Vaihtokurssitappio',
+  'From'                        => 'Alkaen',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI poistettu!',
+  'GIFI missing!'               => 'GIFI puuttuu!',
+  'GIFI saved!'                 => 'GIFI tallennettu!',
+  'GL Transaction'              => 'Pääkirjavienti',
+  'General Ledger'              => 'Pääkirja',
+  'Goods & Services'            => 'Hyödykkeet ja palvelut',
+  'HTML Templates'              => 'HTML mallit',
+  'Heading'                     => 'Otsikko',
+  'Host'                        => 'Isäntätietokone',
+  'Hostname missing!'           => 'Isäntätietokoneen nimi puuttuu',
+  'ID'                          => 'ID',
+  'Image'                       => 'Kuva',
+  'In-line'                     => 'Linjalla',
+  'Include in Report'           => 'Sisällytä raporttiin',
+  'Include in drop-down menus'  => 'Sisällytä pudotusvalikkoon',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Liitetäänkö tämä tili 
+asiakas/toimittaja-lomakkeisiin merkitäkseen hänet verokelpoiseksi!',
+  'Income'                      => 'Tulot',
+  'Income Account'              => 'Tulotili',
+  'Income Statement'            => 'Tuloslaskelma',
+  'Incorrect Dataset version!'  => 'Väärä tietolähdeversio!',
+  'Incorrect Password!'         => 'Väärä salasana!',
+  'Individual Items'            => 'Yksittäiset nimikkeet',
+  'Inventory'                   => 'Varasto',
+  'Inventory Account'           => 'Varastotili',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Tuotteen varaston on oltava nolla ennen asettamista epäkurantiksi!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Raaka-aineen/tarvikkeen varaston määrä on oltava nolla ennen asettamista epäkurantiksi!',
+  'Inventory quantity must be zero!' => 'Varaston määrä on oltava nolla!',
+  'Invoice'                     => 'Lasku',
+  'Invoice Date'                => 'Laskun päiväys',
+  'Invoice Date missing!'       => 'Laskun päiväys puuttuu!',
+  'Invoice Number'              => 'Laskun numero',
+  'Invoice Number missing!'     => 'Laskun numero puuttuu!',
+  'Invoice deleted!'            => 'Lasku poistettu!',
+  'Invoice posted!'             => 'Lasku kirjattu!',
+  'Invoices'                    => 'Laskut',
+  'Is this a summary account to record' => 'Onko tämä tallennettava yhteenvetotili?',
+  'Item deleted!'               => 'Nimike poistettu!',
+  'Item not on file!'           => 'Nimikettä ei ole järjestelmässä!',
+  'Jan'                         => 'Tam',
+  'January'                     => 'Tammikuu',
+  'Jul'                         => 'Hei',
+  'July'                        => 'Heinäkuu',
+  'Jun'                         => 'Kes',
+  'June'                        => 'Kesäkuu',
+  'LaTeX Templates'             => 'LaTeX mallit',
+  'Language'                    => 'Kieli',
+  'Last Cost'                   => 'Edellinen kustannus',
+  'Last Invoice Number'         => 'Edellinen laskunumero',
+  'Last Numbers & Default Accounts' => 'Edelliset numerot ja oletustilit',
+  'Last Purchase Order Number'  => 'Edellisen ostotilauksen numero',
+  'Last Sales Order Number'     => 'Edellinen myyntinumero',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Jätä isäntä- ja porttikentät tyhjiksi mikäli et halua ottaa etäyhteyttä.',
+  'Liability'                   => 'Vastattavaa',
+  'Licensed to'                 => 'Lisenssin omistaja',
+  'Line Total'                  => 'Rivi yhteensä',
+  'Link'                        => 'Linkki',
+  'Link Accounts'               => 'Linkkaa tilit',
+  'List Accounts'               => 'Listaa tilit',
+  'List GIFI'                   => 'Listaa GIFI',
+  'List Price'                  => 'Listaa hinnat',
+  'List Transactions'           => 'Listaa viennit',
+  'Login'                       => 'Kirjaudu',
+  'Logout'                      => 'Kirjaudu ulos',
+  'Make'                        => 'Valmistaja',
+  'Mar'                         => 'Maa',
+  'March'                       => 'Maaliskuu',
+  'May'                         => 'Tou',
+  'May '                        => 'Toukokuu',
+  'Message'                     => 'Viesti',
+  'Microfiche'                  => 'Mikrokuva',
+  'Model'                       => 'Tuotenimi',
+  'Multibyte Encoding'          => 'Itämaisten kielten tuki',
+  'N/A'                         => 'Ei saatavilla',
+  'Name'                        => 'Nimi',
+  'Name missing!'               => 'Nimi puuttuu!',
+  'New Templates'               => 'Uusi malli',
+  'No'                          => 'Ei',
+  'No Database Drivers available!' => 'Tietokanta-ajuria ei saatavilla!',
+  'No Dataset selected!'        => 'Ei tietolähdettä valittuna!',
+  'No email address for'        => 'Sähköpostiosoite puuttuu',
+  'No.'                         => 'no',
+  'Notes'                       => 'Lisätietoja',
+  'Nothing applied!'            => 'Mitään soveltamatta!',
+  'Nothing selected!'           => 'Mitään valitsematta!',
+  'Nothing to delete!'          => 'Ei poistettavaa!',
+  'Nov'                         => 'Mar',
+  'November'                    => 'Marraskuu',
+  'Number'                      => 'Numero',
+  'Number Format'               => 'Numeron muoto',
+  'Number missing in Row'       => 'Numero puuttuu kannan riviltä',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Epäkurantti',
+  'Oct'                         => 'Lok',
+  'October'                     => 'Lokakuu',
+  'On Hand'                     => 'Varastossa',
+  'On Order'                    => 'Tilauksesta',
+  'Open'                        => 'Avoinna',
+  'Oracle Database Administration' => 'Oracle-tietokannan ylläpito',
+  'Order'                       => 'Tilaus',
+  'Order Date'                  => 'Tilauspäivämäärä',
+  'Order Date missing!'         => 'Tilauspäivämäärä puuttuu!',
+  'Order Entry'                 => 'Tilauksen kirjaus',
+  'Order Number'                => 'Tilausnumero',
+  'Order Number missing!'       => 'Tilausnumero puuttuu!',
+  'Order deleted!'              => 'Tilaus poistettu!',
+  'Order saved!'                => 'Tilaus tallennettu!',
+  'Ordered'                     => 'Tilattu',
+  'Orphaned'                    => 'Hylätyt',
+  'Out of balance!'             => 'Ei tasapainossa',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Pakkauslista',
+  'Packing List Date missing!'  => 'Pakkauslistan päiväys puuttuu!',
+  'Packing List Number missing!' => 'Pakkauslistan numero puuttuu!',
+  'Paid'                        => 'Maksettu',
+  'Paid in full'                => 'Täysin maksettu',
+  'Part'                        => 'Raaka-aine/tarvike',
+  'Part Number missing!'        => 'Raaka-aine/tarvikenumero puuttuu!',
+  'Parts'                       => 'Raaka-aineet/tarvikkeet',
+  'Parts Inventory'             => 'Raaka-aine/tarvikevarasto',
+  'Password'                    => 'Salasana',
+  'Password changed!'           => 'Salasana muutettu!',
+  'Payables'                    => 'Maksettavaa',
+  'Payment'                     => 'Maksu',
+  'Payment date missing!'       => 'Maksupäivä puuttuu!',
+  'Payment posted!'             => 'Maksu kirjattu!',
+  'Payments'                    => 'Maksut',
+  'Pg Database Administration'  => 'Postgres tietokannan ylläpito',
+  'Phone'                       => 'Puhelin',
+  'Port'                        => 'Portti',
+  'Port missing!'               => 'Portti puuttuu!',
+  'Post'                        => 'Kirjaa',
+  'Post as new'                 => 'Kirjaa uutena',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Asetukset',
+  'Preferences saved!'          => 'Asetukset tallennettu!',
+  'Price'                       => 'Hinta',
+  'Print'                       => 'Tulosta',
+  'Printer'                     => 'Kirjoitin',
+  'Project'                     => 'Projekti',
+  'Project Number missing!'     => 'Projektinumero puuttuu!',
+  'Project deleted!'            => 'Projekti poistettu!',
+  'Project not on file!'        => 'Projekti ei ole järjestelmässä!',
+  'Project saved!'              => 'Projekti tallennettu!',
+  'Projects'                    => 'Projektit',
+  'Purchase Invoice'            => 'Ostolasku',
+  'Purchase Order'              => 'Ostotilaus',
+  'Purchase Orders'             => 'Ostotilaukset',
+  'Qty'                         => 'Määrä',
+  'ROP'                         => 'Uudelleentilausraja',
+  'Rate'                        => 'Kurssi',
+  'Recd'                        => 'Vastaanotettu',
+  'Receipt'                     => 'Kuitti',
+  'Receipts'                    => 'Kuitit',
+  'Receivables'                 => 'Saamiset',
+  'Reconciliation'              => 'Sovitus',
+  'Record in'                   => 'Talleta tilille',
+  'Reference'                   => 'Viite',
+  'Reference missing!'          => 'Viite puuttuu',
+  'Remaining'                   => 'Jäljellä',
+  'Report for'                  => 'Raportti',
+  'Reports'                     => 'Raportit',
+  'Required by'                 => 'Toimituspäivä',
+  'Retained Earnings'           => 'Käyttörahasto\jakamaton voitto',
+  'Sales'                       => 'Myynti',
+  'Sales Invoice'               => 'Myyntilasku',
+  'Sales Order'                 => 'Tilausvahvistus',
+  'Sales Orders'                => 'Tilausvahvistukset',
+  'Save'                        => 'Tallenna',
+  'Save as new'                 => 'Tallenna uutena',
+  'Save to File'                => 'Tallenna tiedostoon',
+  'Screen'                      => 'Näyttö',
+  'Select a Dataset to delete and press "Continue"' => 'Valitse poistettava tietolähde ja 
+paina jatka',
+  'Select all'                  => 'Valitse kaikki',
+  'Select from one of the items below' => 'Valitse yksi nimike alapuolelta',
+  'Select from one of the names below' => 'Valitse yksi nimi alapuolelta',
+  'Select from one of the projects below' => 'Valitse yksi projekti alapuolelta',
+  'Select postscript or PDF!'   => 'Valitse postscript tai PDF',
+  'Sell Price'                  => 'Myyntihinta',
+  'Send by E-Mail'              => 'Lähetä sähköpostilla',
+  'Sep'                         => 'Syy',
+  'September'                   => 'Syyskuu',
+  'Service'                     => 'Palvelu',
+  'Service Items'               => 'Palvelun nimikkeet',
+  'Service Number missing!'     => 'Palvelun numero puuttuu',
+  'Services'                    => 'Palvelut',
+  'Setup Templates'             => 'Aseta mallit',
+  'Ship'                        => 'Lähetä',
+  'Ship to'                     => 'Toimitusosoite',
+  'Ship via'                    => 'Lähetä kautta',
+  'Short'                       => 'Lyhytaikaiset',
+  'Signature'                   => 'Allekirjoitus',
+  'Sold'                        => 'Myyty',
+  'Source'                      => 'Lähde',
+  'Standard'                    => 'Vakio',
+  'Statement'                   => 'Tiliote',
+  'Statement Balance'           => 'Tiliotteen tase',
+  'Statement sent to'           => 'Tiliote lähetetty',
+  'Statements sent to printer!' => 'Tiliotteet lähetetty tulostimelle!',
+  'Stock Assembly'              => 'Varastoi tuote',
+  'Stylesheet'                  => 'Tyylimalli',
+  'Subject'                     => 'Aihe',
+  'Subtotal'                    => 'Välisumma',
+  'System'                      => 'Järjestelmä',
+  'Tax'                         => 'Vero',
+  'Tax Accounts'                => 'Verotilit',
+  'Tax Included'                => 'ALV sisältyy ',
+  'Tax collected'               => 'Veroa kerätty',
+  'Tax paid'                    => 'Veroa maksettu  ',
+  'Taxable'                     => 'Verotettavaa',
+  'Template saved!'             => 'Malli tallennettu',
+  'Templates'                   => 'Mallit',
+  'Terms: Net'                  => 'Maksuehto',
+  'The following Datasets are not in use and can be deleted' => 'Seuraavat tietolähteet 
+eivät ole käytössä ja voidaan poistaa',
+  'The following Datasets need to be updated' => 'Seuraavat tietolähteet päivitettävä',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Tämä on olemassa olevien lähteiden ennakkotarkistus. Mitään ei luoda tai poisteta tässä vaiheessa!',
+  'To'                          => 'Hetkeen',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Lisätäksesi käyttäjän ryhmään muokkaa nimeä, muuta kirjautumisnimi ja tallenna.',
+  'Top Level'                   => 'Ylin taso',
+  'Total'                       => 'Yhteensä',
+  'Transaction Date missing!'   => 'Viennin päiväys puuttuu!',
+  'Transaction deleted!'        => 'Vienti poistettu!',
+  'Transaction posted!'         => 'Vienti kirjattu!',
+  'Transaction reversal enforced for all dates' => 'Kirjaukset muunnettu kaikille päiväyksille',
+  'Transaction reversal enforced up to' => 'Kirjaukset muunnnettu hetkeen ',
+  'Transactions'                => 'Tapahtumat',
+  'Transactions exist, cannot delete customer!' => 'Vientejä olemassa. Asiakasta ei voi poistaa!',
+  'Transactions exist, cannot delete vendor!' => 'Vientejä olemassa. Toimittajaa ei voi poistaa!',
+  'Transactions exist; cannot delete account!' => 'Vientejä olemassa. Tiliä ei voi poistaa!',
+  'Trial Balance'               => 'Saldolista',
+  'Unit'                        => 'Yksikkö',
+  'Unit of measure'             => 'mittayksikkö',
+  'Update'                      => 'Päivitä',
+  'Update Dataset'              => 'Päivitä tietolähde',
+  'Updated'                     => 'Päivitetty',
+  'Use Templates'               => 'Käytä mallia',
+  'User'                        => 'Käyttäjä',
+  'User deleted!'               => 'Käyttäjä poistettu!',
+  'User saved!'                 => 'Käyttäjä tallennettu!',
+  'Vendor'                      => 'Toimittaja',
+  'Vendor deleted!'             => 'Toimittaja poistettu!',
+  'Vendor missing!'             => 'Toimittaja puuttuu!',
+  'Vendor not on file!'         => 'Toimittajaa ei järjestelmässä!',
+  'Vendor saved!'               => 'Toimittaja tallennettu',
+  'Vendors'                     => 'Toimittajat',
+  'Version'                     => 'Versio',
+  'Weight'                      => 'Paino',
+  'Weight Unit'                 => 'Painoyksikkö',
+  'What type of item is this?'  => 'Minkä tyyppinen nimike tämä on?',
+  'Year End'                    => 'Tilikauden loppuun',
+  'Yes'                         => 'Kyllä',
+  'You are logged out!'         => 'Olet poistunut järjestelmästä',
+  'You did not enter a name!'   => 'Et kirjoittanut nimeä',
+  'You must enter a host and port for local and remote connections!' => 'Sinun täytyy antaa isäntäkone ja portti paikallisille ja etäyhteyksille!',
+  'as at'                       => 'päivänä ',
+  'collected on sales'          => 'Kerätty myynneistä',
+  'days'                        => 'päivää',
+  'does not exist'              => 'ei löydy',
+  'ea'                          => 'kpl',
+  'emailed to'                  => 'lähetetty sähköpostilla',
+  'for Period'                  => 'jaksolta',
+  'hr'                          => 't',
+  'is already a member!'        => 'on jo käyttäjä',
+  'is not a member!'            => 'ei ole käyttäjä',
+  'localhost'                   => 'paikallinen tietokone',
+  'paid on purchases'           => 'maksettu ostoista',
+  'sent to printer'             => 'lähetetty tulostimelle',
+  'successfully created!'       => 'onnistuneesti luotu',
+  'successfully deleted!'       => 'onnistuneesti poistettu',
+  'to'                          => 'Kenelle',
+  'website'                     => 'www-sivu',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/am b/sql-ledger/locale/fi/am
new file mode 100644 (file)
index 0000000..061e862
--- /dev/null
@@ -0,0 +1,140 @@
+$self{texts} = {
+  'AP'                          => 'Ostot',
+  'AR'                          => 'Myynnit',
+  'Account'                     => 'Tili',
+  'Account Number'              => 'Tilinumero',
+  'Account Number missing!'     => 'Tilinumero puuttuu',
+  'Account Type'                => 'Tilityyppi',
+  'Account Type missing!'       => 'Tilityyppi puuttuu',
+  'Account deleted!'            => 'Tili poistettu',
+  'Account saved!'              => 'Tili lisätty',
+  'Add Account'                 => 'Lisää tili',
+  'Add GIFI'                    => 'Lisää GIFI',
+  'Address'                     => 'Osoite',
+  'Asset'                       => 'Vastaavaa',
+  'Audit Control'               => 'Tilien tarkistus',
+  'Backup sent to'              => 'Varmuuskopio lähetetty',
+  'Books are open'              => 'Kirjat ovat avoinna',
+  'Business Number'             => 'Y-numero',
+  'COGS'                        => 'Myydyn tuotteen kulut',
+  'Cannot delete account!'      => 'Tiliä ei voi poistaa!',
+  'Cannot delete default account!' => 'Oletustiliä ei voi poistaa!',
+  'Cannot save account!'        => 'Tilin tallennus ei onnistu!',
+  'Cannot save preferences!'    => 'Asetuksien tallennus ei onnistu!',
+  'Character Set'               => 'Näppäimistökartta ',
+  'Chart of Accounts'           => 'Tilikartta',
+  'Close Books up to'           => 'Sulje kirjat hetkeen',
+  'Company'                     => 'Yritys',
+  'Continue'                    => 'Jatka',
+  'Copy to COA'                 => 'Kopioi tilikarttaan',
+  'Credit'                      => 'Kredit',
+  'Date Format'                 => 'Päiväyksen muoto',
+  'Debit'                       => 'Debet',
+  'Delete'                      => 'Poista',
+  'Delete Account'              => 'Poista tili',
+  'Description'                 => 'Kuvaus',
+  'Dropdown Limit'              => 'Pudotusvalikkon rivimäärä',
+  'E-mail'                      => 'Sähköposti',
+  'Edit'                        => 'Muokkaa',
+  'Edit Account'                => 'Muokkaa tiliä',
+  'Edit GIFI'                   => 'Muokkaa GIFI',
+  'Edit Preferences for'        => 'Muokkaa asetuksia',
+  'Edit Template'               => 'Muokkaa mallia',
+  'Enforce transaction reversal for all dates' => 'Pakota muunnos kaikille viennille',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Merkitse käyttämäsi valuutat 3 kirjaimella ja erota ne kaksoispisteellä, esim.(EUR:USD:SEK).',
+  'Equity'                      => 'Oma pääoma',
+  'Expense'                     => 'Menot',
+  'Expense Account'             => 'Menotili',
+  'Expense/Asset'               => 'Menot/Varat',
+  'Fax'                         => 'Faksi',
+  'Foreign Exchange Gain'       => 'Vaihtokurssivoitto',
+  'Foreign Exchange Loss'       => 'Vaihtokurssitappio',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI poistettu!',
+  'GIFI missing!'               => 'GIFI puuttuu!',
+  'GIFI saved!'                 => 'GIFI tallennettu!',
+  'Heading'                     => 'Otsikko',
+  'Include in drop-down menus'  => 'Sisällytä pudotusvalikkoon',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Liitetäänkö tämä tili 
+asiakas/toimittaja-lomakkeisiin merkitäkseen hänet verokelpoiseksi!',
+  'Income'                      => 'Tulot',
+  'Income Account'              => 'Tulotili',
+  'Inventory'                   => 'Varasto',
+  'Inventory Account'           => 'Varastotili',
+  'Is this a summary account to record' => 'Onko tämä tallennettava yhteenvetotili?',
+  'Language'                    => 'Kieli',
+  'Last Invoice Number'         => 'Edellinen laskunumero',
+  'Last Numbers & Default Accounts' => 'Edelliset numerot ja oletustilit',
+  'Last Purchase Order Number'  => 'Edellisen ostotilauksen numero',
+  'Last Sales Order Number'     => 'Edellinen myyntinumero',
+  'Liability'                   => 'Vastattavaa',
+  'Link'                        => 'Linkki',
+  'Name'                        => 'Nimi',
+  'No'                          => 'Ei',
+  'No email address for'        => 'Sähköpostiosoite puuttuu',
+  'Number'                      => 'Numero',
+  'Number Format'               => 'Numeron muoto',
+  'Parts Inventory'             => 'Raaka-aine/tarvikevarasto',
+  'Password'                    => 'Salasana',
+  'Payables'                    => 'Maksettavaa',
+  'Payment'                     => 'Maksu',
+  'Phone'                       => 'Puhelin',
+  'Preferences saved!'          => 'Asetukset tallennettu!',
+  'Rate'                        => 'Kurssi',
+  'Receivables'                 => 'Saamiset',
+  'Sales'                       => 'Myynti',
+  'Save'                        => 'Tallenna',
+  'Service Items'               => 'Palvelun nimikkeet',
+  'Ship via'                    => 'Lähetä kautta',
+  'Signature'                   => 'Allekirjoitus',
+  'Stylesheet'                  => 'Tyylimalli',
+  'Tax'                         => 'Vero',
+  'Tax Accounts'                => 'Verotilit',
+  'Template saved!'             => 'Malli tallennettu',
+  'Transaction reversal enforced for all dates' => 'Kirjaukset muunnettu kaikille päiväyksille',
+  'Transaction reversal enforced up to' => 'Kirjaukset muunnnettu hetkeen ',
+  'Transactions exist; cannot delete account!' => 'Vientejä olemassa. Tiliä ei voi poistaa!',
+  'Weight Unit'                 => 'Painoyksikkö',
+  'Year End'                    => 'Tilikauden loppuun',
+  'Yes'                         => 'Kyllä',
+  'does not exist'              => 'ei löydy',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'lisää_tili'                  => 'add_account',
+  'jatka'                       => 'continue',
+  'kopioi_tilikarttaan'         => 'copy_to_coa',
+  'poista'                      => 'delete',
+  'muokkaa'                     => 'edit',
+  'muokkaa_tiliä'               => 'edit_account',
+  'tallenna'                    => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/ap b/sql-ledger/locale/fi/ap
new file mode 100644 (file)
index 0000000..ba053c8
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Ostotapahtuma',
+  'AP Transactions'             => 'Ostotapahtumat',
+  'Account'                     => 'Tili',
+  'Add Accounts Payables Transaction' => 'Lisää ostotapahtuma',
+  'Address'                     => 'Osoite',
+  'Amount'                      => 'Summa',
+  'Amount Due'                  => 'Erääntyvä summa',
+  'Apr'                         => 'Huh',
+  'April'                       => 'Huhtikuu',
+  'Are you sure you want to delete Transaction' => 'Haluatko poistaa viennin?',
+  'Aug'                         => 'Elo',
+  'August'                      => 'Elokuu',
+  'Cannot delete transaction!'  => 'Vientiä ei voi poistaa',
+  'Cannot post payment for a closed period!' => 'Maksun kirjaus suljetulle ajanjaksolle kielletty ',
+  'Cannot post transaction for a closed period!' => 'Viennin kirjaus suljetulle ajanjaksolle kielletty',
+  'Cannot post transaction!'    => 'Vientiä ei voi kirjata',
+  'Closed'                      => 'Suljettu',
+  'Confirm!'                    => 'Vahvista!',
+  'Continue'                    => 'Jatka',
+  'Currency'                    => 'Valuutta',
+  'Customer not on file!'       => 'Asiakas ei järjestelmässä!',
+  'Date'                        => 'Päiväys',
+  'Date Paid'                   => 'Maksupäivä',
+  'Dec'                         => 'Jou',
+  'December'                    => 'Joulukuu',
+  'Delete'                      => 'Poista',
+  'Description'                 => 'Kuvaus',
+  'Due Date'                    => 'Eräpäivä',
+  'Due Date missing!'           => 'Eräpäivä puuttuu!',
+  'Edit Accounts Payables Transaction' => 'Muokkaa ostovientiä',
+  'Employee'                    => 'Työntekijä',
+  'Exch'                        => 'Vaihtokurssi',
+  'Exchangerate'                => 'Vaihtokurssi',
+  'Exchangerate for payment missing!' => 'Maksun vaihtokurssi puuttuu',
+  'Exchangerate missing!'       => 'Vaihtokurssi puuttuu',
+  'Feb'                         => 'Hel',
+  'February'                    => 'Helmikuu',
+  'From'                        => 'Alkaen',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Sisällytä raporttiin',
+  'Invoice'                     => 'Lasku',
+  'Invoice Date'                => 'Laskun päiväys',
+  'Invoice Date missing!'       => 'Laskun päiväys puuttuu!',
+  'Invoice Number'              => 'Laskun numero',
+  'Invoice Number missing!'     => 'Laskun numero puuttuu!',
+  'Jan'                         => 'Tam',
+  'January'                     => 'Tammikuu',
+  'Jul'                         => 'Hei',
+  'July'                        => 'Heinäkuu',
+  'Jun'                         => 'Kes',
+  'June'                        => 'Kesäkuu',
+  'Mar'                         => 'Maa',
+  'March'                       => 'Maaliskuu',
+  'May'                         => 'Tou',
+  'May '                        => 'Toukokuu',
+  'Notes'                       => 'Lisätietoja',
+  'Nov'                         => 'Mar',
+  'November'                    => 'Marraskuu',
+  'Number'                      => 'Numero',
+  'Oct'                         => 'Lok',
+  'October'                     => 'Lokakuu',
+  'Open'                        => 'Avoinna',
+  'Order'                       => 'Tilaus',
+  'Order Number'                => 'Tilausnumero',
+  'Paid'                        => 'Maksettu',
+  'Payment date missing!'       => 'Maksupäivä puuttuu!',
+  'Payments'                    => 'Maksut',
+  'Post'                        => 'Kirjaa',
+  'Post as new'                 => 'Kirjaa uutena',
+  'Project'                     => 'Projekti',
+  'Project not on file!'        => 'Projekti ei ole järjestelmässä!',
+  'Purchase Invoice'            => 'Ostolasku',
+  'Select from one of the names below' => 'Valitse yksi nimi alapuolelta',
+  'Select from one of the projects below' => 'Valitse yksi projekti alapuolelta',
+  'Sep'                         => 'Syy',
+  'September'                   => 'Syyskuu',
+  'Source'                      => 'Lähde',
+  'Subtotal'                    => 'Välisumma',
+  'Tax'                         => 'Vero',
+  'Tax Included'                => 'ALV sisältyy ',
+  'To'                          => 'Hetkeen',
+  'Total'                       => 'Yhteensä',
+  'Transaction deleted!'        => 'Vienti poistettu!',
+  'Transaction posted!'         => 'Vienti kirjattu!',
+  'Update'                      => 'Päivitä',
+  'Vendor'                      => 'Toimittaja',
+  'Vendor missing!'             => 'Toimittaja puuttuu!',
+  'Vendor not on file!'         => 'Toimittajaa ei järjestelmässä!',
+  'Yes'                         => 'Kyllä',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ostotapahtuma'               => 'ap_transaction',
+  'lisää_ostotapahtuma'         => 'add_accounts_payables_transaction',
+  'jatka'                       => 'continue',
+  'poista'                      => 'delete',
+  'muokkaa_ostovientiä'         => 'edit_accounts_payables_transaction',
+  'kirjaa'                      => 'post',
+  'kirjaa_uutena'               => 'post_as_new',
+  'ostolasku'                   => 'purchase_invoice',
+  'päivitä'                     => 'update',
+  'kyllä'                       => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/ar b/sql-ledger/locale/fi/ar
new file mode 100644 (file)
index 0000000..0394021
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'Myyntitapahtuma',
+  'AR Transactions'             => 'Myyntitapahtumat',
+  'Account'                     => 'Tili',
+  'Add Accounts Receivables Transaction' => 'Lisää myyntitapahtuma',
+  'Address'                     => 'Osoite',
+  'Amount'                      => 'Summa',
+  'Amount Due'                  => 'Erääntyvä summa',
+  'Apr'                         => 'Huh',
+  'April'                       => 'Huhtikuu',
+  'Are you sure you want to delete Transaction' => 'Haluatko poistaa viennin?',
+  'Aug'                         => 'Elo',
+  'August'                      => 'Elokuu',
+  'Cannot delete transaction!'  => 'Vientiä ei voi poistaa',
+  'Cannot post payment for a closed period!' => 'Maksun kirjaus suljetulle ajanjaksolle kielletty ',
+  'Cannot post transaction for a closed period!' => 'Viennin kirjaus suljetulle ajanjaksolle kielletty',
+  'Cannot post transaction!'    => 'Vientiä ei voi kirjata',
+  'Closed'                      => 'Suljettu',
+  'Confirm!'                    => 'Vahvista!',
+  'Continue'                    => 'Jatka',
+  'Credit Limit'                => 'Luottoraja',
+  'Currency'                    => 'Valuutta',
+  'Customer'                    => 'Asiakas',
+  'Customer missing!'           => 'Asiakas puuttuu!',
+  'Customer not on file!'       => 'Asiakas ei järjestelmässä!',
+  'Date'                        => 'Päiväys',
+  'Date Paid'                   => 'Maksupäivä',
+  'Dec'                         => 'Jou',
+  'December'                    => 'Joulukuu',
+  'Delete'                      => 'Poista',
+  'Description'                 => 'Kuvaus',
+  'Due Date'                    => 'Eräpäivä',
+  'Due Date missing!'           => 'Eräpäivä puuttuu!',
+  'Edit Accounts Receivables Transaction' => 'Muokkaa myyntivientiä',
+  'Employee'                    => 'Työntekijä',
+  'Exch'                        => 'Vaihtokurssi',
+  'Exchangerate'                => 'Vaihtokurssi',
+  'Exchangerate for payment missing!' => 'Maksun vaihtokurssi puuttuu',
+  'Exchangerate missing!'       => 'Vaihtokurssi puuttuu',
+  'Feb'                         => 'Hel',
+  'February'                    => 'Helmikuu',
+  'From'                        => 'Alkaen',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Sisällytä raporttiin',
+  'Invoice'                     => 'Lasku',
+  'Invoice Date'                => 'Laskun päiväys',
+  'Invoice Date missing!'       => 'Laskun päiväys puuttuu!',
+  'Invoice Number'              => 'Laskun numero',
+  'Invoice Number missing!'     => 'Laskun numero puuttuu!',
+  'Jan'                         => 'Tam',
+  'January'                     => 'Tammikuu',
+  'Jul'                         => 'Hei',
+  'July'                        => 'Heinäkuu',
+  'Jun'                         => 'Kes',
+  'June'                        => 'Kesäkuu',
+  'Mar'                         => 'Maa',
+  'March'                       => 'Maaliskuu',
+  'May'                         => 'Tou',
+  'May '                        => 'Toukokuu',
+  'Notes'                       => 'Lisätietoja',
+  'Nov'                         => 'Mar',
+  'November'                    => 'Marraskuu',
+  'Number'                      => 'Numero',
+  'Oct'                         => 'Lok',
+  'October'                     => 'Lokakuu',
+  'Open'                        => 'Avoinna',
+  'Order'                       => 'Tilaus',
+  'Order Number'                => 'Tilausnumero',
+  'Paid'                        => 'Maksettu',
+  'Payment date missing!'       => 'Maksupäivä puuttuu!',
+  'Payments'                    => 'Maksut',
+  'Post'                        => 'Kirjaa',
+  'Post as new'                 => 'Kirjaa uutena',
+  'Project'                     => 'Projekti',
+  'Project not on file!'        => 'Projekti ei ole järjestelmässä!',
+  'Remaining'                   => 'Jäljellä',
+  'Sales Invoice'               => 'Myyntilasku',
+  'Select from one of the names below' => 'Valitse yksi nimi alapuolelta',
+  'Select from one of the projects below' => 'Valitse yksi projekti alapuolelta',
+  'Sep'                         => 'Syy',
+  'September'                   => 'Syyskuu',
+  'Source'                      => 'Lähde',
+  'Subtotal'                    => 'Välisumma',
+  'Tax'                         => 'Vero',
+  'Tax Included'                => 'ALV sisältyy ',
+  'To'                          => 'Hetkeen',
+  'Total'                       => 'Yhteensä',
+  'Transaction deleted!'        => 'Vienti poistettu!',
+  'Transaction posted!'         => 'Vienti kirjattu!',
+  'Update'                      => 'Päivitä',
+  'Vendor not on file!'         => 'Toimittajaa ei järjestelmässä!',
+  'Yes'                         => 'Kyllä',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'myyntitapahtuma'             => 'ar_transaction',
+  'jatka'                       => 'continue',
+  'poista'                      => 'delete',
+  'kirjaa'                      => 'post',
+  'kirjaa_uutena'               => 'post_as_new',
+  'myyntilasku'                 => 'sales_invoice',
+  'päivitä'                     => 'update',
+  'kyllä'                       => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/arap b/sql-ledger/locale/fi/arap
new file mode 100644 (file)
index 0000000..8ba26e1
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Osoite',
+  'Continue'                    => 'Jatka',
+  'Customer not on file!'       => 'Asiakas ei järjestelmässä!',
+  'Description'                 => 'Kuvaus',
+  'Number'                      => 'Numero',
+  'Project not on file!'        => 'Projekti ei ole järjestelmässä!',
+  'Select from one of the names below' => 'Valitse yksi nimi alapuolelta',
+  'Select from one of the projects below' => 'Valitse yksi projekti alapuolelta',
+  'Vendor not on file!'         => 'Toimittajaa ei järjestelmässä!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'jatka'                       => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/ca b/sql-ledger/locale/fi/ca
new file mode 100644 (file)
index 0000000..c5f3b37
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Tili',
+  'Apr'                         => 'Huh',
+  'April'                       => 'Huhtikuu',
+  'Aug'                         => 'Elo',
+  'August'                      => 'Elokuu',
+  'Balance'                     => 'Tase',
+  'Chart of Accounts'           => 'Tilikartta',
+  'Credit'                      => 'Kredit',
+  'Date'                        => 'Päiväys',
+  'Debit'                       => 'Debet',
+  'Dec'                         => 'Jou',
+  'December'                    => 'Joulukuu',
+  'Description'                 => 'Kuvaus',
+  'Feb'                         => 'Hel',
+  'February'                    => 'Helmikuu',
+  'From'                        => 'Alkaen',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Sisällytä raporttiin',
+  'Jan'                         => 'Tam',
+  'January'                     => 'Tammikuu',
+  'Jul'                         => 'Hei',
+  'July'                        => 'Heinäkuu',
+  'Jun'                         => 'Kes',
+  'June'                        => 'Kesäkuu',
+  'List Transactions'           => 'Listaa viennit',
+  'Mar'                         => 'Maa',
+  'March'                       => 'Maaliskuu',
+  'May'                         => 'Tou',
+  'May '                        => 'Toukokuu',
+  'Nov'                         => 'Mar',
+  'November'                    => 'Marraskuu',
+  'Oct'                         => 'Lok',
+  'October'                     => 'Lokakuu',
+  'Reference'                   => 'Viite',
+  'Sep'                         => 'Syy',
+  'September'                   => 'Syyskuu',
+  'Subtotal'                    => 'Välisumma',
+  'To'                          => 'Hetkeen',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'listaa_viennit'              => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/cp b/sql-ledger/locale/fi/cp
new file mode 100644 (file)
index 0000000..202e8cf
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Tili',
+  'Address'                     => 'Osoite',
+  'Amount'                      => 'Summa',
+  'Amount does not equal applied!' => 'Määrä eri kuin sovellettu',
+  'Amount missing!'             => 'Määrä puuttuu',
+  'Applied'                     => 'Sovellettu',
+  'Cannot post payment!'        => 'Maksua ei voi kirjata!',
+  'Cannot process payment for a closed period!' => 'Suljetun ajanjakson maksua ei voi käsitellä',
+  'Check'                       => 'Sekki',
+  'Check printed!'              => 'Sekki tulostettu!',
+  'Check printing failed!'      => 'Sekin tulostus epäonnistui!',
+  'Continue'                    => 'Jatka',
+  'Currency'                    => 'Valuutta',
+  'Customer'                    => 'Asiakas',
+  'Customer not on file!'       => 'Asiakas ei järjestelmässä!',
+  'Date'                        => 'Päiväys',
+  'Date missing!'               => 'Päiväys puuttuu',
+  'Description'                 => 'Kuvaus',
+  'Due'                         => 'Eräpv',
+  'Exchangerate'                => 'Vaihtokurssi',
+  'From'                        => 'Alkaen',
+  'Invoice'                     => 'Lasku',
+  'Invoices'                    => 'Laskut',
+  'Nothing applied!'            => 'Mitään soveltamatta!',
+  'Number'                      => 'Numero',
+  'Paid in full'                => 'Täysin maksettu',
+  'Payment'                     => 'Maksu',
+  'Payment posted!'             => 'Maksu kirjattu!',
+  'Post'                        => 'Kirjaa',
+  'Print'                       => 'Tulosta',
+  'Printer'                     => 'Kirjoitin',
+  'Project not on file!'        => 'Projekti ei ole järjestelmässä!',
+  'Receipt'                     => 'Kuitti',
+  'Reference'                   => 'Viite',
+  'Screen'                      => 'Näyttö',
+  'Select from one of the names below' => 'Valitse yksi nimi alapuolelta',
+  'Select from one of the projects below' => 'Valitse yksi projekti alapuolelta',
+  'To'                          => 'Hetkeen',
+  'Update'                      => 'Päivitä',
+  'Vendor'                      => 'Toimittaja',
+  'Vendor not on file!'         => 'Toimittajaa ei järjestelmässä!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'jatka'                       => 'continue',
+  'kirjaa'                      => 'post',
+  'tulosta'                     => 'print',
+  'päivitä'                     => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/ct b/sql-ledger/locale/fi/ct
new file mode 100644 (file)
index 0000000..186b25d
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Lisää',
+  'Address'                     => 'Osoite',
+  'All'                         => 'Kaikki',
+  'Bcc'                         => 'Näkymätön kopio',
+  'Cannot delete customer!'     => 'Asiakasta ei voi poistaa!',
+  'Cannot delete vendor!'       => 'Toimittajaa ei voi poistaa!',
+  'Cc'                          => 'Kopio',
+  'Contact'                     => 'Yhteyshenkilö',
+  'Continue'                    => 'Jatka',
+  'Credit Limit'                => 'Luottoraja',
+  'Customer deleted!'           => 'Asiakas poistettu!',
+  'Customer saved!'             => 'Asiakas tallennettu!',
+  'Customers'                   => 'Asiakkaat',
+  'Delete'                      => 'Poista',
+  'Discount'                    => 'Alennus',
+  'E-mail'                      => 'Sähköposti',
+  'Edit Customer'               => 'Muokkaa asiakas',
+  'Edit Vendor'                 => 'Muokkaa ',
+  'Fax'                         => 'Faksi',
+  'Include in Report'           => 'Sisällytä raporttiin',
+  'Invoice'                     => 'Lasku',
+  'Name'                        => 'Nimi',
+  'Name missing!'               => 'Nimi puuttuu!',
+  'Notes'                       => 'Lisätietoja',
+  'Number'                      => 'Numero',
+  'Order'                       => 'Tilaus',
+  'Orphaned'                    => 'Hylätyt',
+  'Phone'                       => 'Puhelin',
+  'Save'                        => 'Tallenna',
+  'Ship to'                     => 'Toimitusosoite',
+  'Tax Included'                => 'ALV sisältyy ',
+  'Taxable'                     => 'Verotettavaa',
+  'Terms: Net'                  => 'Maksuehto',
+  'Transactions exist, cannot delete customer!' => 'Vientejä olemassa. Asiakasta ei voi poistaa!',
+  'Transactions exist, cannot delete vendor!' => 'Vientejä olemassa. Toimittajaa ei voi poistaa!',
+  'Vendor deleted!'             => 'Toimittaja poistettu!',
+  'Vendor saved!'               => 'Toimittaja tallennettu',
+  'Vendors'                     => 'Toimittajat',
+  'days'                        => 'päivää',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'lisää'                       => 'add',
+  'jatka'                       => 'continue',
+  'poista'                      => 'delete',
+  'lasku'                       => 'invoice',
+  'tilaus'                      => 'order',
+  'tallenna'                    => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/gl b/sql-ledger/locale/fi/gl
new file mode 100644 (file)
index 0000000..6a07b15
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Ostotapahtuma',
+  'AR Transaction'              => 'Myyntitapahtuma',
+  'Account'                     => 'Tili',
+  'Add General Ledger Transaction' => 'Lisää pääkirjatapahtuma',
+  'Address'                     => 'Osoite',
+  'All'                         => 'Kaikki',
+  'Apr'                         => 'Huh',
+  'April'                       => 'Huhtikuu',
+  'Are you sure you want to delete Transaction' => 'Haluatko poistaa viennin?',
+  'Asset'                       => 'Vastaavaa',
+  'Aug'                         => 'Elo',
+  'August'                      => 'Elokuu',
+  'Balance'                     => 'Tase',
+  'Cannot delete transaction!'  => 'Vientiä ei voi poistaa',
+  'Cannot have a value in both Debit and Credit!' => 'Arvo sekä Kreditissä että Debetissä kielletty!',
+  'Cannot post a transaction without a value!' => 'Viennin kirjaus ilman arvoa kielletty!',
+  'Cannot post transaction for a closed period!' => 'Viennin kirjaus suljetulle ajanjaksolle kielletty',
+  'Confirm!'                    => 'Vahvista!',
+  'Continue'                    => 'Jatka',
+  'Credit'                      => 'Kredit',
+  'Customer not on file!'       => 'Asiakas ei järjestelmässä!',
+  'Date'                        => 'Päiväys',
+  'Debit'                       => 'Debet',
+  'Debit and credit out of balance!' => 'Debet ja kredit erisuuruiset',
+  'Dec'                         => 'Jou',
+  'December'                    => 'Joulukuu',
+  'Delete'                      => 'Poista',
+  'Description'                 => 'Kuvaus',
+  'Edit General Ledger Transaction' => 'Muokkaa pääkirjavientiä',
+  'Equity'                      => 'Oma pääoma',
+  'Expense'                     => 'Menot',
+  'Feb'                         => 'Hel',
+  'February'                    => 'Helmikuu',
+  'From'                        => 'Alkaen',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'Pääkirjavienti',
+  'General Ledger'              => 'Pääkirja',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Sisällytä raporttiin',
+  'Income'                      => 'Tulot',
+  'Jan'                         => 'Tam',
+  'January'                     => 'Tammikuu',
+  'Jul'                         => 'Hei',
+  'July'                        => 'Heinäkuu',
+  'Jun'                         => 'Kes',
+  'June'                        => 'Kesäkuu',
+  'Liability'                   => 'Vastattavaa',
+  'Mar'                         => 'Maa',
+  'March'                       => 'Maaliskuu',
+  'May'                         => 'Tou',
+  'May '                        => 'Toukokuu',
+  'Notes'                       => 'Lisätietoja',
+  'Nov'                         => 'Mar',
+  'November'                    => 'Marraskuu',
+  'Number'                      => 'Numero',
+  'Oct'                         => 'Lok',
+  'October'                     => 'Lokakuu',
+  'Post'                        => 'Kirjaa',
+  'Post as new'                 => 'Kirjaa uutena',
+  'Project'                     => 'Projekti',
+  'Project not on file!'        => 'Projekti ei ole järjestelmässä!',
+  'Purchase Invoice'            => 'Ostolasku',
+  'Reference'                   => 'Viite',
+  'Reference missing!'          => 'Viite puuttuu',
+  'Reports'                     => 'Raportit',
+  'Sales Invoice'               => 'Myyntilasku',
+  'Select from one of the names below' => 'Valitse yksi nimi alapuolelta',
+  'Select from one of the projects below' => 'Valitse yksi projekti alapuolelta',
+  'Sep'                         => 'Syy',
+  'September'                   => 'Syyskuu',
+  'Source'                      => 'Lähde',
+  'Subtotal'                    => 'Välisumma',
+  'To'                          => 'Hetkeen',
+  'Transaction Date missing!'   => 'Viennin päiväys puuttuu!',
+  'Transaction deleted!'        => 'Vienti poistettu!',
+  'Transaction posted!'         => 'Vienti kirjattu!',
+  'Update'                      => 'Päivitä',
+  'Vendor not on file!'         => 'Toimittajaa ei järjestelmässä!',
+  'Yes'                         => 'Kyllä',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ostotapahtuma'               => 'ap_transaction',
+  'myyntitapahtuma'             => 'ar_transaction',
+  'jatka'                       => 'continue',
+  'poista'                      => 'delete',
+  'pääkirjavienti'              => 'gl_transaction',
+  'kirjaa'                      => 'post',
+  'kirjaa_uutena'               => 'post_as_new',
+  'ostolasku'                   => 'purchase_invoice',
+  'myyntilasku'                 => 'sales_invoice',
+  'päivitä'                     => 'update',
+  'kyllä'                       => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/ic b/sql-ledger/locale/fi/ic
new file mode 100644 (file)
index 0000000..55f37a1
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Avoin',
+  'Add'                         => 'Lisää',
+  'Add Assembly'                => 'Lisää tuote',
+  'Add Part'                    => 'Lisää raaka-aine/tarvike',
+  'Add Purchase Order'          => 'Ostotilaus',
+  'Add Sales Order'             => 'Lisää tilausvahvistus',
+  'Add Service'                 => 'Lisää palvelu',
+  'Address'                     => 'Osoite',
+  'Apr'                         => 'Huh',
+  'April'                       => 'Huhtikuu',
+  'Assemblies'                  => 'Tuotteet',
+  'Assemblies restocked!'       => 'Tuotteet viety varastoon',
+  'Assembly Number missing!'    => 'Tuotenumero puuttuu!',
+  'Attachment'                  => 'Liite',
+  'Aug'                         => 'Elo',
+  'August'                      => 'Elokuu',
+  'BOM'                         => 'Materiaalilista',
+  'Bcc'                         => 'Näkymätön kopio',
+  'Bin'                         => 'Varastopaikka',
+  'Bought'                      => 'Ostettu',
+  'COGS'                        => 'Myydyn tuotteen kulut',
+  'Cannot delete item already invoiced!' => 'Laskutettua nimikettä ei voi poistaa!',
+  'Cannot delete item on order!' => 'Nimikettä tilauksessa ei voi poistaa',
+  'Cannot delete item which is part of an assembly!' => 'Tuotteen raaka-ainetta/tarviketta ei voi poistaa!',
+  'Cannot delete item!'         => 'Nimikettä ei voi poistaa!',
+  'Cannot stock assemblies!'    => 'Tuotteiden varastointi ei onnistu!',
+  'Cc'                          => 'Kopio',
+  'Contact'                     => 'Yhteyshenkilö',
+  'Continue'                    => 'Jatka',
+  'Copies'                      => 'Kopiot',
+  'Dec'                         => 'Jou',
+  'December'                    => 'Joulukuu',
+  'Delete'                      => 'Poista',
+  'Delivery Date'               => 'Toimituspäivä',
+  'Description'                 => 'Kuvaus',
+  'Drawing'                     => 'Piirros',
+  'E-mail'                      => 'Sähköposti',
+  'E-mail address missing!'     => 'Sähköpostiosoite puuttuu!',
+  'Edit Assembly'               => 'Muokkaa tuotetta',
+  'Edit Part'                   => 'Muokkaa raaka-ainetta/tarviketta',
+  'Edit Service'                => 'Muokkaa palvelua',
+  'Expense'                     => 'Menot',
+  'Extended'                    => 'Pidennetty',
+  'Fax'                         => 'Faksi',
+  'Feb'                         => 'Hel',
+  'February'                    => 'Helmikuu',
+  'From'                        => 'Alkaen',
+  'Image'                       => 'Kuva',
+  'In-line'                     => 'Linjalla',
+  'Include in Report'           => 'Sisällytä raporttiin',
+  'Income'                      => 'Tulot',
+  'Individual Items'            => 'Yksittäiset nimikkeet',
+  'Inventory'                   => 'Varasto',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Tuotteen varaston on oltava nolla ennen asettamista epäkurantiksi!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Raaka-aineen/tarvikkeen varaston määrä on oltava nolla ennen asettamista epäkurantiksi!',
+  'Inventory quantity must be zero!' => 'Varaston määrä on oltava nolla!',
+  'Invoice'                     => 'Lasku',
+  'Invoice Date missing!'       => 'Laskun päiväys puuttuu!',
+  'Invoice Number'              => 'Laskun numero',
+  'Invoice Number missing!'     => 'Laskun numero puuttuu!',
+  'Item deleted!'               => 'Nimike poistettu!',
+  'Item not on file!'           => 'Nimikettä ei ole järjestelmässä!',
+  'Jan'                         => 'Tam',
+  'January'                     => 'Tammikuu',
+  'Jul'                         => 'Hei',
+  'July'                        => 'Heinäkuu',
+  'Jun'                         => 'Kes',
+  'June'                        => 'Kesäkuu',
+  'Last Cost'                   => 'Edellinen kustannus',
+  'Line Total'                  => 'Rivi yhteensä',
+  'Link Accounts'               => 'Linkkaa tilit',
+  'List Price'                  => 'Listaa hinnat',
+  'Make'                        => 'Valmistaja',
+  'Mar'                         => 'Maa',
+  'March'                       => 'Maaliskuu',
+  'May'                         => 'Tou',
+  'May '                        => 'Toukokuu',
+  'Message'                     => 'Viesti',
+  'Microfiche'                  => 'Mikrokuva',
+  'Model'                       => 'Tuotenimi',
+  'Name'                        => 'Nimi',
+  'No.'                         => 'no',
+  'Notes'                       => 'Lisätietoja',
+  'Nov'                         => 'Mar',
+  'November'                    => 'Marraskuu',
+  'Number'                      => 'Numero',
+  'Number missing in Row'       => 'Numero puuttuu kannan riviltä',
+  'Obsolete'                    => 'Epäkurantti',
+  'Oct'                         => 'Lok',
+  'October'                     => 'Lokakuu',
+  'On Hand'                     => 'Varastossa',
+  'On Order'                    => 'Tilauksesta',
+  'Order'                       => 'Tilaus',
+  'Order Date missing!'         => 'Tilauspäivämäärä puuttuu!',
+  'Order Number'                => 'Tilausnumero',
+  'Order Number missing!'       => 'Tilausnumero puuttuu!',
+  'Ordered'                     => 'Tilattu',
+  'Orphaned'                    => 'Hylätyt',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Pakkauslista',
+  'Packing List Date missing!'  => 'Pakkauslistan päiväys puuttuu!',
+  'Packing List Number missing!' => 'Pakkauslistan numero puuttuu!',
+  'Part'                        => 'Raaka-aine/tarvike',
+  'Part Number missing!'        => 'Raaka-aine/tarvikenumero puuttuu!',
+  'Parts'                       => 'Raaka-aineet/tarvikkeet',
+  'Phone'                       => 'Puhelin',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Hinta',
+  'Printer'                     => 'Kirjoitin',
+  'Project'                     => 'Projekti',
+  'Purchase Order'              => 'Ostotilaus',
+  'Qty'                         => 'Määrä',
+  'ROP'                         => 'Uudelleentilausraja',
+  'Recd'                        => 'Vastaanotettu',
+  'Required by'                 => 'Toimituspäivä',
+  'Sales'                       => 'Myynti',
+  'Sales Order'                 => 'Tilausvahvistus',
+  'Save'                        => 'Tallenna',
+  'Screen'                      => 'Näyttö',
+  'Select from one of the items below' => 'Valitse yksi nimike alapuolelta',
+  'Select postscript or PDF!'   => 'Valitse postscript tai PDF',
+  'Sell Price'                  => 'Myyntihinta',
+  'Sep'                         => 'Syy',
+  'September'                   => 'Syyskuu',
+  'Service'                     => 'Palvelu',
+  'Service Number missing!'     => 'Palvelun numero puuttuu',
+  'Services'                    => 'Palvelut',
+  'Ship'                        => 'Lähetä',
+  'Ship to'                     => 'Toimitusosoite',
+  'Short'                       => 'Lyhytaikaiset',
+  'Sold'                        => 'Myyty',
+  'Stock Assembly'              => 'Varastoi tuote',
+  'Subject'                     => 'Aihe',
+  'Subtotal'                    => 'Välisumma',
+  'Tax'                         => 'Vero',
+  'To'                          => 'Hetkeen',
+  'Top Level'                   => 'Ylin taso',
+  'Total'                       => 'Yhteensä',
+  'Unit'                        => 'Yksikkö',
+  'Unit of measure'             => 'mittayksikkö',
+  'Update'                      => 'Päivitä',
+  'Updated'                     => 'Päivitetty',
+  'Weight'                      => 'Paino',
+  'What type of item is this?'  => 'Minkä tyyppinen nimike tämä on?',
+  'ea'                          => 'kpl',
+  'emailed to'                  => 'lähetetty sähköpostilla',
+  'hr'                          => 't',
+  'sent to printer'             => 'lähetetty tulostimelle',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'lisää'                       => 'add',
+  'lisää_tuote'                 => 'add_assembly',
+  'lisää_raaka_aine/tarvike'    => 'add_part',
+  'lisää_palvelu'               => 'add_service',
+  'jatka'                       => 'continue',
+  'poista'                      => 'delete',
+  'muokkaa_tuotetta'            => 'edit_assembly',
+  'muokkaa_raaka_ainetta/tarviketta' => 'edit_part',
+  'muokkaa_palvelua'            => 'edit_service',
+  'tallenna'                    => 'save',
+  'päivitä'                     => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/io b/sql-ledger/locale/fi/io
new file mode 100644 (file)
index 0000000..cc147a8
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Ostotilaus',
+  'Add Sales Order'             => 'Lisää tilausvahvistus',
+  'Address'                     => 'Osoite',
+  'Apr'                         => 'Huh',
+  'April'                       => 'Huhtikuu',
+  'Attachment'                  => 'Liite',
+  'Aug'                         => 'Elo',
+  'August'                      => 'Elokuu',
+  'Bcc'                         => 'Näkymätön kopio',
+  'Bin'                         => 'Varastopaikka',
+  'Cc'                          => 'Kopio',
+  'Contact'                     => 'Yhteyshenkilö',
+  'Continue'                    => 'Jatka',
+  'Copies'                      => 'Kopiot',
+  'Dec'                         => 'Jou',
+  'December'                    => 'Joulukuu',
+  'Delivery Date'               => 'Toimituspäivä',
+  'Description'                 => 'Kuvaus',
+  'E-mail'                      => 'Sähköposti',
+  'E-mail address missing!'     => 'Sähköpostiosoite puuttuu!',
+  'Extended'                    => 'Pidennetty',
+  'Fax'                         => 'Faksi',
+  'Feb'                         => 'Hel',
+  'February'                    => 'Helmikuu',
+  'In-line'                     => 'Linjalla',
+  'Invoice'                     => 'Lasku',
+  'Invoice Date missing!'       => 'Laskun päiväys puuttuu!',
+  'Invoice Number missing!'     => 'Laskun numero puuttuu!',
+  'Item not on file!'           => 'Nimikettä ei ole järjestelmässä!',
+  'Jan'                         => 'Tam',
+  'January'                     => 'Tammikuu',
+  'Jul'                         => 'Hei',
+  'July'                        => 'Heinäkuu',
+  'Jun'                         => 'Kes',
+  'June'                        => 'Kesäkuu',
+  'Mar'                         => 'Maa',
+  'March'                       => 'Maaliskuu',
+  'May'                         => 'Tou',
+  'May '                        => 'Toukokuu',
+  'Message'                     => 'Viesti',
+  'Name'                        => 'Nimi',
+  'No.'                         => 'no',
+  'Nov'                         => 'Mar',
+  'November'                    => 'Marraskuu',
+  'Number'                      => 'Numero',
+  'Number missing in Row'       => 'Numero puuttuu kannan riviltä',
+  'Oct'                         => 'Lok',
+  'October'                     => 'Lokakuu',
+  'Order'                       => 'Tilaus',
+  'Order Date missing!'         => 'Tilauspäivämäärä puuttuu!',
+  'Order Number missing!'       => 'Tilausnumero puuttuu!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Pakkauslista',
+  'Packing List Date missing!'  => 'Pakkauslistan päiväys puuttuu!',
+  'Packing List Number missing!' => 'Pakkauslistan numero puuttuu!',
+  'Part'                        => 'Raaka-aine/tarvike',
+  'Phone'                       => 'Puhelin',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Hinta',
+  'Printer'                     => 'Kirjoitin',
+  'Project'                     => 'Projekti',
+  'Purchase Order'              => 'Ostotilaus',
+  'Qty'                         => 'Määrä',
+  'Recd'                        => 'Vastaanotettu',
+  'Required by'                 => 'Toimituspäivä',
+  'Sales Order'                 => 'Tilausvahvistus',
+  'Screen'                      => 'Näyttö',
+  'Select from one of the items below' => 'Valitse yksi nimike alapuolelta',
+  'Select postscript or PDF!'   => 'Valitse postscript tai PDF',
+  'Sep'                         => 'Syy',
+  'September'                   => 'Syyskuu',
+  'Service'                     => 'Palvelu',
+  'Ship'                        => 'Lähetä',
+  'Ship to'                     => 'Toimitusosoite',
+  'Subject'                     => 'Aihe',
+  'To'                          => 'Hetkeen',
+  'Unit'                        => 'Yksikkö',
+  'What type of item is this?'  => 'Minkä tyyppinen nimike tämä on?',
+  'emailed to'                  => 'lähetetty sähköpostilla',
+  'sent to printer'             => 'lähetetty tulostimelle',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'jatka'                       => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/ir b/sql-ledger/locale/fi/ir
new file mode 100644 (file)
index 0000000..1070f99
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Tili',
+  'Add Purchase Invoice'        => 'Lisää ostolasku',
+  'Add Purchase Order'          => 'Ostotilaus',
+  'Add Sales Order'             => 'Lisää tilausvahvistus',
+  'Address'                     => 'Osoite',
+  'Amount'                      => 'Summa',
+  'Apr'                         => 'Huh',
+  'April'                       => 'Huhtikuu',
+  'Are you sure you want to delete Invoice Number' => 'Haluatko poistaa laskun numero?',
+  'Attachment'                  => 'Liite',
+  'Aug'                         => 'Elo',
+  'August'                      => 'Elokuu',
+  'Bcc'                         => 'Näkymätön kopio',
+  'Bin'                         => 'Varastopaikka',
+  'Cannot delete invoice!'      => 'Laskua ei voi poistaa!',
+  'Cannot post invoice for a closed period!' => 'Laskun kirjaus suljetulle ajanjaksolle kielletty!',
+  'Cannot post invoice!'        => 'Laskua ei voi kirjata!',
+  'Cannot post payment for a closed period!' => 'Maksun kirjaus suljetulle ajanjaksolle kielletty ',
+  'Cc'                          => 'Kopio',
+  'Confirm!'                    => 'Vahvista!',
+  'Contact'                     => 'Yhteyshenkilö',
+  'Continue'                    => 'Jatka',
+  'Copies'                      => 'Kopiot',
+  'Currency'                    => 'Valuutta',
+  'Customer not on file!'       => 'Asiakas ei järjestelmässä!',
+  'Date'                        => 'Päiväys',
+  'Date Due'                    => 'Eräpäivä',
+  'Dec'                         => 'Jou',
+  'December'                    => 'Joulukuu',
+  'Delete'                      => 'Poista',
+  'Delivery Date'               => 'Toimituspäivä',
+  'Description'                 => 'Kuvaus',
+  'E-mail'                      => 'Sähköposti',
+  'E-mail address missing!'     => 'Sähköpostiosoite puuttuu!',
+  'Edit Purchase Invoice'       => 'Muokkaa ostolaskua',
+  'Exch'                        => 'Vaihtokurssi',
+  'Exchangerate'                => 'Vaihtokurssi',
+  'Exchangerate for payment missing!' => 'Maksun vaihtokurssi puuttuu',
+  'Exchangerate missing!'       => 'Vaihtokurssi puuttuu',
+  'Extended'                    => 'Pidennetty',
+  'Fax'                         => 'Faksi',
+  'Feb'                         => 'Hel',
+  'February'                    => 'Helmikuu',
+  'In-line'                     => 'Linjalla',
+  'Invoice'                     => 'Lasku',
+  'Invoice Date'                => 'Laskun päiväys',
+  'Invoice Date missing!'       => 'Laskun päiväys puuttuu!',
+  'Invoice Number'              => 'Laskun numero',
+  'Invoice Number missing!'     => 'Laskun numero puuttuu!',
+  'Invoice deleted!'            => 'Lasku poistettu!',
+  'Invoice posted!'             => 'Lasku kirjattu!',
+  'Item not on file!'           => 'Nimikettä ei ole järjestelmässä!',
+  'Jan'                         => 'Tam',
+  'January'                     => 'Tammikuu',
+  'Jul'                         => 'Hei',
+  'July'                        => 'Heinäkuu',
+  'Jun'                         => 'Kes',
+  'June'                        => 'Kesäkuu',
+  'Mar'                         => 'Maa',
+  'March'                       => 'Maaliskuu',
+  'May'                         => 'Tou',
+  'May '                        => 'Toukokuu',
+  'Message'                     => 'Viesti',
+  'Name'                        => 'Nimi',
+  'No.'                         => 'no',
+  'Notes'                       => 'Lisätietoja',
+  'Nov'                         => 'Mar',
+  'November'                    => 'Marraskuu',
+  'Number'                      => 'Numero',
+  'Number missing in Row'       => 'Numero puuttuu kannan riviltä',
+  'Oct'                         => 'Lok',
+  'October'                     => 'Lokakuu',
+  'Order'                       => 'Tilaus',
+  'Order Date missing!'         => 'Tilauspäivämäärä puuttuu!',
+  'Order Number'                => 'Tilausnumero',
+  'Order Number missing!'       => 'Tilausnumero puuttuu!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Pakkauslista',
+  'Packing List Date missing!'  => 'Pakkauslistan päiväys puuttuu!',
+  'Packing List Number missing!' => 'Pakkauslistan numero puuttuu!',
+  'Part'                        => 'Raaka-aine/tarvike',
+  'Payment date missing!'       => 'Maksupäivä puuttuu!',
+  'Payments'                    => 'Maksut',
+  'Phone'                       => 'Puhelin',
+  'Post'                        => 'Kirjaa',
+  'Post as new'                 => 'Kirjaa uutena',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Hinta',
+  'Printer'                     => 'Kirjoitin',
+  'Project'                     => 'Projekti',
+  'Project not on file!'        => 'Projekti ei ole järjestelmässä!',
+  'Purchase Order'              => 'Ostotilaus',
+  'Qty'                         => 'Määrä',
+  'Recd'                        => 'Vastaanotettu',
+  'Record in'                   => 'Talleta tilille',
+  'Required by'                 => 'Toimituspäivä',
+  'Sales Order'                 => 'Tilausvahvistus',
+  'Screen'                      => 'Näyttö',
+  'Select from one of the items below' => 'Valitse yksi nimike alapuolelta',
+  'Select from one of the names below' => 'Valitse yksi nimi alapuolelta',
+  'Select from one of the projects below' => 'Valitse yksi projekti alapuolelta',
+  'Select postscript or PDF!'   => 'Valitse postscript tai PDF',
+  'Sep'                         => 'Syy',
+  'September'                   => 'Syyskuu',
+  'Service'                     => 'Palvelu',
+  'Ship'                        => 'Lähetä',
+  'Ship to'                     => 'Toimitusosoite',
+  'Source'                      => 'Lähde',
+  'Subject'                     => 'Aihe',
+  'Subtotal'                    => 'Välisumma',
+  'Tax Included'                => 'ALV sisältyy ',
+  'To'                          => 'Hetkeen',
+  'Total'                       => 'Yhteensä',
+  'Unit'                        => 'Yksikkö',
+  'Update'                      => 'Päivitä',
+  'Vendor'                      => 'Toimittaja',
+  'Vendor missing!'             => 'Toimittaja puuttuu!',
+  'Vendor not on file!'         => 'Toimittajaa ei järjestelmässä!',
+  'What type of item is this?'  => 'Minkä tyyppinen nimike tämä on?',
+  'Yes'                         => 'Kyllä',
+  'ea'                          => 'kpl',
+  'emailed to'                  => 'lähetetty sähköpostilla',
+  'sent to printer'             => 'lähetetty tulostimelle',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'jatka'                       => 'continue',
+  'poista'                      => 'delete',
+  'tilaus'                      => 'order',
+  'kirjaa'                      => 'post',
+  'kirjaa_uutena'               => 'post_as_new',
+  'päivitä'                     => 'update',
+  'kyllä'                       => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/is b/sql-ledger/locale/fi/is
new file mode 100644 (file)
index 0000000..da492f9
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Tili',
+  'Add Purchase Order'          => 'Ostotilaus',
+  'Add Sales Invoice'           => 'Lisää myyntilasku',
+  'Add Sales Order'             => 'Lisää tilausvahvistus',
+  'Address'                     => 'Osoite',
+  'Amount'                      => 'Summa',
+  'Apr'                         => 'Huh',
+  'April'                       => 'Huhtikuu',
+  'Are you sure you want to delete Invoice Number' => 'Haluatko poistaa laskun numero?',
+  'Attachment'                  => 'Liite',
+  'Aug'                         => 'Elo',
+  'August'                      => 'Elokuu',
+  'Bcc'                         => 'Näkymätön kopio',
+  'Bin'                         => 'Varastopaikka',
+  'Cannot delete invoice!'      => 'Laskua ei voi poistaa!',
+  'Cannot post invoice for a closed period!' => 'Laskun kirjaus suljetulle ajanjaksolle kielletty!',
+  'Cannot post invoice!'        => 'Laskua ei voi kirjata!',
+  'Cannot post payment for a closed period!' => 'Maksun kirjaus suljetulle ajanjaksolle kielletty ',
+  'Cc'                          => 'Kopio',
+  'Confirm!'                    => 'Vahvista!',
+  'Contact'                     => 'Yhteyshenkilö',
+  'Continue'                    => 'Jatka',
+  'Copies'                      => 'Kopiot',
+  'Credit Limit'                => 'Luottoraja',
+  'Currency'                    => 'Valuutta',
+  'Customer'                    => 'Asiakas',
+  'Customer missing!'           => 'Asiakas puuttuu!',
+  'Customer not on file!'       => 'Asiakas ei järjestelmässä!',
+  'Date'                        => 'Päiväys',
+  'Date Due'                    => 'Eräpäivä',
+  'Dec'                         => 'Jou',
+  'December'                    => 'Joulukuu',
+  'Delete'                      => 'Poista',
+  'Delivery Date'               => 'Toimituspäivä',
+  'Description'                 => 'Kuvaus',
+  'E-mail'                      => 'Sähköposti',
+  'E-mail address missing!'     => 'Sähköpostiosoite puuttuu!',
+  'Edit Sales Invoice'          => 'Muokkaa myyntilaskua',
+  'Exch'                        => 'Vaihtokurssi',
+  'Exchangerate'                => 'Vaihtokurssi',
+  'Exchangerate for payment missing!' => 'Maksun vaihtokurssi puuttuu',
+  'Exchangerate missing!'       => 'Vaihtokurssi puuttuu',
+  'Extended'                    => 'Pidennetty',
+  'Fax'                         => 'Faksi',
+  'Feb'                         => 'Hel',
+  'February'                    => 'Helmikuu',
+  'In-line'                     => 'Linjalla',
+  'Invoice'                     => 'Lasku',
+  'Invoice Date'                => 'Laskun päiväys',
+  'Invoice Date missing!'       => 'Laskun päiväys puuttuu!',
+  'Invoice Number'              => 'Laskun numero',
+  'Invoice Number missing!'     => 'Laskun numero puuttuu!',
+  'Invoice deleted!'            => 'Lasku poistettu!',
+  'Invoice posted!'             => 'Lasku kirjattu!',
+  'Item not on file!'           => 'Nimikettä ei ole järjestelmässä!',
+  'Jan'                         => 'Tam',
+  'January'                     => 'Tammikuu',
+  'Jul'                         => 'Hei',
+  'July'                        => 'Heinäkuu',
+  'Jun'                         => 'Kes',
+  'June'                        => 'Kesäkuu',
+  'Mar'                         => 'Maa',
+  'March'                       => 'Maaliskuu',
+  'May'                         => 'Tou',
+  'May '                        => 'Toukokuu',
+  'Message'                     => 'Viesti',
+  'Name'                        => 'Nimi',
+  'No.'                         => 'no',
+  'Notes'                       => 'Lisätietoja',
+  'Nov'                         => 'Mar',
+  'November'                    => 'Marraskuu',
+  'Number'                      => 'Numero',
+  'Number missing in Row'       => 'Numero puuttuu kannan riviltä',
+  'Oct'                         => 'Lok',
+  'October'                     => 'Lokakuu',
+  'Order'                       => 'Tilaus',
+  'Order Date missing!'         => 'Tilauspäivämäärä puuttuu!',
+  'Order Number'                => 'Tilausnumero',
+  'Order Number missing!'       => 'Tilausnumero puuttuu!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Pakkauslista',
+  'Packing List Date missing!'  => 'Pakkauslistan päiväys puuttuu!',
+  'Packing List Number missing!' => 'Pakkauslistan numero puuttuu!',
+  'Part'                        => 'Raaka-aine/tarvike',
+  'Payment date missing!'       => 'Maksupäivä puuttuu!',
+  'Payments'                    => 'Maksut',
+  'Phone'                       => 'Puhelin',
+  'Post'                        => 'Kirjaa',
+  'Post as new'                 => 'Kirjaa uutena',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Hinta',
+  'Print'                       => 'Tulosta',
+  'Printer'                     => 'Kirjoitin',
+  'Project'                     => 'Projekti',
+  'Project not on file!'        => 'Projekti ei ole järjestelmässä!',
+  'Purchase Order'              => 'Ostotilaus',
+  'Qty'                         => 'Määrä',
+  'Recd'                        => 'Vastaanotettu',
+  'Record in'                   => 'Talleta tilille',
+  'Remaining'                   => 'Jäljellä',
+  'Required by'                 => 'Toimituspäivä',
+  'Sales Order'                 => 'Tilausvahvistus',
+  'Screen'                      => 'Näyttö',
+  'Select from one of the items below' => 'Valitse yksi nimike alapuolelta',
+  'Select from one of the names below' => 'Valitse yksi nimi alapuolelta',
+  'Select from one of the projects below' => 'Valitse yksi projekti alapuolelta',
+  'Select postscript or PDF!'   => 'Valitse postscript tai PDF',
+  'Sep'                         => 'Syy',
+  'September'                   => 'Syyskuu',
+  'Service'                     => 'Palvelu',
+  'Ship'                        => 'Lähetä',
+  'Ship to'                     => 'Toimitusosoite',
+  'Ship via'                    => 'Lähetä kautta',
+  'Source'                      => 'Lähde',
+  'Subject'                     => 'Aihe',
+  'Subtotal'                    => 'Välisumma',
+  'Tax Included'                => 'ALV sisältyy ',
+  'To'                          => 'Hetkeen',
+  'Total'                       => 'Yhteensä',
+  'Unit'                        => 'Yksikkö',
+  'Update'                      => 'Päivitä',
+  'Vendor not on file!'         => 'Toimittajaa ei järjestelmässä!',
+  'What type of item is this?'  => 'Minkä tyyppinen nimike tämä on?',
+  'Yes'                         => 'Kyllä',
+  'ea'                          => 'kpl',
+  'emailed to'                  => 'lähetetty sähköpostilla',
+  'sent to printer'             => 'lähetetty tulostimelle',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'jatka'                       => 'continue',
+  'poista'                      => 'delete',
+  'sähköposti'                  => 'e_mail',
+  'tilaus'                      => 'order',
+  'kirjaa'                      => 'post',
+  'kirjaa_uutena'               => 'post_as_new',
+  'tulosta'                     => 'print',
+  'toimitusosoite'              => 'ship_to',
+  'päivitä'                     => 'update',
+  'kyllä'                       => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/login b/sql-ledger/locale/fi/login
new file mode 100644 (file)
index 0000000..783ae05
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'Lisätietoja',
+  'Database Host'               => 'Tietokannan isäntä',
+  'Dataset'                     => 'Tietolähde',
+  'Incorrect Dataset version!'  => 'Väärä tietolähdeversio!',
+  'Incorrect Password!'         => 'Väärä salasana!',
+  'Licensed to'                 => 'Lisenssin omistaja',
+  'Login'                       => 'Kirjaudu',
+  'Name'                        => 'Nimi',
+  'Password'                    => 'Salasana',
+  'User'                        => 'Käyttäjä',
+  'Version'                     => 'Versio',
+  'You are logged out!'         => 'Olet poistunut järjestelmästä',
+  'You did not enter a name!'   => 'Et kirjoittanut nimeä',
+  'is not a member!'            => 'ei ole käyttäjä',
+  'localhost'                   => 'paikallinen tietokone',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'kirjaudu'                    => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/menu b/sql-ledger/locale/fi/menu
new file mode 100644 (file)
index 0000000..c3cde8b
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => 'Ostot',
+  'AP Aging'                    => 'Erääntyvät ostolaskut',
+  'AR'                          => 'Myynnit',
+  'AR Aging'                    => 'Erääntyvät myyntilaskut',
+  'Accounting Menu'             => 'Kirjanpitovalikko',
+  'Add Account'                 => 'Lisää tili',
+  'Add Assembly'                => 'Lisää tuote',
+  'Add Customer'                => 'Lisää asiakas',
+  'Add GIFI'                    => 'Lisää GIFI',
+  'Add Part'                    => 'Lisää raaka-aine/tarvike',
+  'Add Project'                 => 'Lisää projekti',
+  'Add Service'                 => 'Lisää palvelu',
+  'Add Transaction'             => 'Lisää tapahtuma',
+  'Add Vendor'                  => 'Lisää toimittaja',
+  'Assemblies'                  => 'Tuotteet',
+  'Audit Control'               => 'Tilien tarkistus',
+  'Backup'                      => 'Varmuuskopio',
+  'Balance Sheet'               => 'Taselaskelma',
+  'Cash'                        => 'Käteiskauppa',
+  'Chart of Accounts'           => 'Tilikartta',
+  'Check'                       => 'Sekki',
+  'Customers'                   => 'Asiakkaat',
+  'General Ledger'              => 'Pääkirja',
+  'Goods & Services'            => 'Hyödykkeet ja palvelut',
+  'HTML Templates'              => 'HTML mallit',
+  'Income Statement'            => 'Tuloslaskelma',
+  'Invoice'                     => 'Lasku',
+  'LaTeX Templates'             => 'LaTeX mallit',
+  'List Accounts'               => 'Listaa tilit',
+  'List GIFI'                   => 'Listaa GIFI',
+  'Logout'                      => 'Kirjaudu ulos',
+  'Order Entry'                 => 'Tilauksen kirjaus',
+  'Packing List'                => 'Pakkauslista',
+  'Parts'                       => 'Raaka-aineet/tarvikkeet',
+  'Payment'                     => 'Maksu',
+  'Payments'                    => 'Maksut',
+  'Preferences'                 => 'Asetukset',
+  'Projects'                    => 'Projektit',
+  'Purchase Invoice'            => 'Ostolasku',
+  'Purchase Order'              => 'Ostotilaus',
+  'Purchase Orders'             => 'Ostotilaukset',
+  'Receipt'                     => 'Kuitti',
+  'Receipts'                    => 'Kuitit',
+  'Reconciliation'              => 'Sovitus',
+  'Reports'                     => 'Raportit',
+  'Sales Invoice'               => 'Myyntilasku',
+  'Sales Order'                 => 'Tilausvahvistus',
+  'Sales Orders'                => 'Tilausvahvistukset',
+  'Save to File'                => 'Tallenna tiedostoon',
+  'Send by E-Mail'              => 'Lähetä sähköpostilla',
+  'Services'                    => 'Palvelut',
+  'Statement'                   => 'Tiliote',
+  'Stock Assembly'              => 'Varastoi tuote',
+  'Stylesheet'                  => 'Tyylimalli',
+  'System'                      => 'Järjestelmä',
+  'Tax collected'               => 'Veroa kerätty',
+  'Tax paid'                    => 'Veroa maksettu  ',
+  'Transactions'                => 'Tapahtumat',
+  'Trial Balance'               => 'Saldolista',
+  'Vendors'                     => 'Toimittajat',
+  'Version'                     => 'Versio',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/oe b/sql-ledger/locale/fi/oe
new file mode 100644 (file)
index 0000000..bf1f726
--- /dev/null
@@ -0,0 +1,199 @@
+$self{texts} = {
+  'Add'                         => 'Lisää',
+  'Add Purchase Invoice'        => 'Lisää ostolasku',
+  'Add Purchase Order'          => 'Ostotilaus',
+  'Add Sales Invoice'           => 'Lisää myyntilasku',
+  'Add Sales Order'             => 'Lisää tilausvahvistus',
+  'Address'                     => 'Osoite',
+  'Amount'                      => 'Summa',
+  'Apr'                         => 'Huh',
+  'April'                       => 'Huhtikuu',
+  'Are you sure you want to delete Order Number' => 'Haluatko poistaa tilauksen numero',
+  'Attachment'                  => 'Liite',
+  'Aug'                         => 'Elo',
+  'August'                      => 'Elokuu',
+  'Bcc'                         => 'Näkymätön kopio',
+  'Bin'                         => 'Varastopaikka',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Tilausta ei voi poistaa!',
+  'Cannot save order!'          => 'Tilauksen tallennus ei onnistu!',
+  'Cc'                          => 'Kopio',
+  'Closed'                      => 'Suljettu',
+  'Confirm!'                    => 'Vahvista!',
+  'Contact'                     => 'Yhteyshenkilö',
+  'Continue'                    => 'Jatka',
+  'Copies'                      => 'Kopiot',
+  'Credit Limit'                => 'Luottoraja',
+  'Curr'                        => 'Valuutta',
+  'Currency'                    => 'Valuutta',
+  'Customer'                    => 'Asiakas',
+  'Customer missing!'           => 'Asiakas puuttuu!',
+  'Customer not on file!'       => 'Asiakas ei järjestelmässä!',
+  'Date'                        => 'Päiväys',
+  'Dec'                         => 'Jou',
+  'December'                    => 'Joulukuu',
+  'Delete'                      => 'Poista',
+  'Delivery Date'               => 'Toimituspäivä',
+  'Description'                 => 'Kuvaus',
+  'E-mail'                      => 'Sähköposti',
+  'E-mail address missing!'     => 'Sähköpostiosoite puuttuu!',
+  'Edit Purchase Order'         => 'Muokkaa ostotilausta',
+  'Edit Sales Order'            => 'Muokkaa myyntitilausta',
+  'Exchangerate'                => 'Vaihtokurssi',
+  'Exchangerate missing!'       => 'Vaihtokurssi puuttuu',
+  'Extended'                    => 'Pidennetty',
+  'Fax'                         => 'Faksi',
+  'Feb'                         => 'Hel',
+  'February'                    => 'Helmikuu',
+  'From'                        => 'Alkaen',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Linjalla',
+  'Include in Report'           => 'Sisällytä raporttiin',
+  'Invoice'                     => 'Lasku',
+  'Invoice Date missing!'       => 'Laskun päiväys puuttuu!',
+  'Invoice Number missing!'     => 'Laskun numero puuttuu!',
+  'Item not on file!'           => 'Nimikettä ei ole järjestelmässä!',
+  'Jan'                         => 'Tam',
+  'January'                     => 'Tammikuu',
+  'Jul'                         => 'Hei',
+  'July'                        => 'Heinäkuu',
+  'Jun'                         => 'Kes',
+  'June'                        => 'Kesäkuu',
+  'Mar'                         => 'Maa',
+  'March'                       => 'Maaliskuu',
+  'May'                         => 'Tou',
+  'May '                        => 'Toukokuu',
+  'Message'                     => 'Viesti',
+  'Name'                        => 'Nimi',
+  'No.'                         => 'no',
+  'Notes'                       => 'Lisätietoja',
+  'Nov'                         => 'Mar',
+  'November'                    => 'Marraskuu',
+  'Number'                      => 'Numero',
+  'Number missing in Row'       => 'Numero puuttuu kannan riviltä',
+  'O'                           => 'O',
+  'Oct'                         => 'Lok',
+  'October'                     => 'Lokakuu',
+  'Open'                        => 'Avoinna',
+  'Order'                       => 'Tilaus',
+  'Order Date'                  => 'Tilauspäivämäärä',
+  'Order Date missing!'         => 'Tilauspäivämäärä puuttuu!',
+  'Order Number'                => 'Tilausnumero',
+  'Order Number missing!'       => 'Tilausnumero puuttuu!',
+  'Order deleted!'              => 'Tilaus poistettu!',
+  'Order saved!'                => 'Tilaus tallennettu!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Pakkauslista',
+  'Packing List Date missing!'  => 'Pakkauslistan päiväys puuttuu!',
+  'Packing List Number missing!' => 'Pakkauslistan numero puuttuu!',
+  'Part'                        => 'Raaka-aine/tarvike',
+  'Phone'                       => 'Puhelin',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Hinta',
+  'Print'                       => 'Tulosta',
+  'Printer'                     => 'Kirjoitin',
+  'Project'                     => 'Projekti',
+  'Project not on file!'        => 'Projekti ei ole järjestelmässä!',
+  'Purchase Order'              => 'Ostotilaus',
+  'Purchase Orders'             => 'Ostotilaukset',
+  'Qty'                         => 'Määrä',
+  'Recd'                        => 'Vastaanotettu',
+  'Remaining'                   => 'Jäljellä',
+  'Required by'                 => 'Toimituspäivä',
+  'Sales Order'                 => 'Tilausvahvistus',
+  'Sales Orders'                => 'Tilausvahvistukset',
+  'Save'                        => 'Tallenna',
+  'Save as new'                 => 'Tallenna uutena',
+  'Screen'                      => 'Näyttö',
+  'Select from one of the items below' => 'Valitse yksi nimike alapuolelta',
+  'Select from one of the names below' => 'Valitse yksi nimi alapuolelta',
+  'Select from one of the projects below' => 'Valitse yksi projekti alapuolelta',
+  'Select postscript or PDF!'   => 'Valitse postscript tai PDF',
+  'Sep'                         => 'Syy',
+  'September'                   => 'Syyskuu',
+  'Service'                     => 'Palvelu',
+  'Ship'                        => 'Lähetä',
+  'Ship to'                     => 'Toimitusosoite',
+  'Ship via'                    => 'Lähetä kautta',
+  'Subject'                     => 'Aihe',
+  'Subtotal'                    => 'Välisumma',
+  'Tax'                         => 'Vero',
+  'Tax Included'                => 'ALV sisältyy ',
+  'Terms: Net'                  => 'Maksuehto',
+  'To'                          => 'Hetkeen',
+  'Total'                       => 'Yhteensä',
+  'Unit'                        => 'Yksikkö',
+  'Update'                      => 'Päivitä',
+  'Vendor'                      => 'Toimittaja',
+  'Vendor missing!'             => 'Toimittaja puuttuu!',
+  'Vendor not on file!'         => 'Toimittajaa ei järjestelmässä!',
+  'What type of item is this?'  => 'Minkä tyyppinen nimike tämä on?',
+  'Yes'                         => 'Kyllä',
+  'days'                        => 'päivää',
+  'ea'                          => 'kpl',
+  'emailed to'                  => 'lähetetty sähköpostilla',
+  'sent to printer'             => 'lähetetty tulostimelle',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'lisää'                       => 'add',
+  'jatka'                       => 'continue',
+  'poista'                      => 'delete',
+  'sähköposti'                  => 'e_mail',
+  'lasku'                       => 'invoice',
+  'tulosta'                     => 'print',
+  'tallenna'                    => 'save',
+  'tallenna_uutena'             => 'save_as_new',
+  'toimitusosoite'              => 'ship_to',
+  'päivitä'                     => 'update',
+  'kyllä'                       => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/pe b/sql-ledger/locale/fi/pe
new file mode 100644 (file)
index 0000000..c9fe2c1
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Lisää',
+  'Add Project'                 => 'Lisää projekti',
+  'All'                         => 'Kaikki',
+  'Continue'                    => 'Jatka',
+  'Delete'                      => 'Poista',
+  'Description'                 => 'Kuvaus',
+  'Edit Project'                => 'Muokkaa projektia',
+  'Number'                      => 'Numero',
+  'Orphaned'                    => 'Hylätyt',
+  'Project'                     => 'Projekti',
+  'Project Number missing!'     => 'Projektinumero puuttuu!',
+  'Project deleted!'            => 'Projekti poistettu!',
+  'Project saved!'              => 'Projekti tallennettu!',
+  'Projects'                    => 'Projektit',
+  'Save'                        => 'Tallenna',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'lisää'                       => 'add',
+  'jatka'                       => 'continue',
+  'poista'                      => 'delete',
+  'tallenna'                    => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/rc b/sql-ledger/locale/fi/rc
new file mode 100644 (file)
index 0000000..57ea0da
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Tili',
+  'Balance'                     => 'Tase',
+  'Cleared Balance'             => 'Tarkistettu tase',
+  'Continue'                    => 'Jatka',
+  'Date'                        => 'Päiväys',
+  'Deposit'                     => 'Rahatallennus',
+  'Description'                 => 'Kuvaus',
+  'Difference'                  => 'Ero',
+  'Done'                        => 'Suoritettu!',
+  'Exchangerate Difference'     => 'Vaihtokurssin ero',
+  'From'                        => 'Alkaen',
+  'Out of balance!'             => 'Ei tasapainossa',
+  'Payment'                     => 'Maksu',
+  'Reconciliation'              => 'Sovitus',
+  'Select all'                  => 'Valitse kaikki',
+  'Source'                      => 'Lähde',
+  'Statement Balance'           => 'Tiliotteen tase',
+  'To'                          => 'Hetkeen',
+  'Update'                      => 'Päivitä',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'jatka'                       => 'continue',
+  'suoritettu!'                 => 'done',
+  'valitse_kaikki'              => 'select_all',
+  'päivitä'                     => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/fi/rp b/sql-ledger/locale/fi/rp
new file mode 100644 (file)
index 0000000..cbc572f
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'Erääntyvät ostolaskut',
+  'AR Aging'                    => 'Erääntyvät myyntilaskut',
+  'Account'                     => 'Tili',
+  'Accounts'                    => 'Tilit',
+  'Amount'                      => 'Summa',
+  'Apr'                         => 'Huh',
+  'April'                       => 'Huhtikuu',
+  'Attachment'                  => 'Liite',
+  'Aug'                         => 'Elo',
+  'August'                      => 'Elokuu',
+  'Balance Sheet'               => 'Taselaskelma',
+  'Bcc'                         => 'Näkymätön kopio',
+  'Cash based'                  => 'Käteiseen perustuva',
+  'Cc'                          => 'Kopio',
+  'Compare to'                  => 'verrattuna',
+  'Continue'                    => 'Jatka',
+  'Copies'                      => 'Kopiot',
+  'Credit'                      => 'Kredit',
+  'Current'                     => 'Erääntyy',
+  'Customer'                    => 'Asiakas',
+  'Date'                        => 'Päiväys',
+  'Debit'                       => 'Debet',
+  'Dec'                         => 'Jou',
+  'December'                    => 'Joulukuu',
+  'Decimalplaces'               => 'Desimaalipaikkoja',
+  'Description'                 => 'Kuvaus',
+  'Due'                         => 'Eräpv',
+  'E-mail'                      => 'Sähköposti',
+  'E-mail Statement to'         => 'Sähköpostilla tiliote kenelle',
+  'Feb'                         => 'Hel',
+  'February'                    => 'Helmikuu',
+  'From'                        => 'Alkaen',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Otsikko',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Linjalla',
+  'Include in Report'           => 'Sisällytä raporttiin',
+  'Income Statement'            => 'Tuloslaskelma',
+  'Invoice'                     => 'Lasku',
+  'Jan'                         => 'Tam',
+  'January'                     => 'Tammikuu',
+  'Jul'                         => 'Hei',
+  'July'                        => 'Heinäkuu',
+  'Jun'                         => 'Kes',
+  'June'                        => 'Kesäkuu',
+  'Mar'                         => 'Maa',
+  'March'                       => 'Maaliskuu',
+  'May'                         => 'Tou',
+  'May '                        => 'Toukokuu',
+  'Message'                     => 'Viesti',
+  'N/A'                         => 'Ei saatavilla',
+  'Nothing selected!'           => 'Mitään valitsematta!',
+  'Nov'                         => 'Mar',
+  'November'                    => 'Marraskuu',
+  'Oct'                         => 'Lok',
+  'October'                     => 'Lokakuu',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Maksut',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Tulosta',
+  'Printer'                     => 'Kirjoitin',
+  'Receipts'                    => 'Kuitit',
+  'Report for'                  => 'Raportti',
+  'Retained Earnings'           => 'Käyttörahasto\jakamaton voitto',
+  'Screen'                      => 'Näyttö',
+  'Select all'                  => 'Valitse kaikki',
+  'Select postscript or PDF!'   => 'Valitse postscript tai PDF',
+  'Sep'                         => 'Syy',
+  'September'                   => 'Syyskuu',
+  'Source'                      => 'Lähde',
+  'Standard'                    => 'Vakio',
+  'Statement'                   => 'Tiliote',
+  'Statement sent to'           => 'Tiliote lähetetty',
+  'Statements sent to printer!' => 'Tiliotteet lähetetty tulostimelle!',
+  'Subject'                     => 'Aihe',
+  'Subtotal'                    => 'Välisumma',
+  'Tax'                         => 'Vero',
+  'Tax collected'               => 'Veroa kerätty',
+  'Tax paid'                    => 'Veroa maksettu  ',
+  'To'                          => 'Hetkeen',
+  'Total'                       => 'Yhteensä',
+  'Trial Balance'               => 'Saldolista',
+  'Vendor'                      => 'Toimittaja',
+  'as at'                       => 'päivänä ',
+  'collected on sales'          => 'Kerätty myynneistä',
+  'for Period'                  => 'jaksolta',
+  'paid on purchases'           => 'maksettu ostoista',
+  'to'                          => 'Kenelle',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'jatka'                       => 'continue',
+  'sähköposti'                  => 'e_mail',
+  'tulosta'                     => 'print',
+  'valitse_kaikki'              => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/COPYING b/sql-ledger/locale/fr/COPYING
new file mode 100644 (file)
index 0000000..2010dcc
--- /dev/null
@@ -0,0 +1,27 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2003
+#
+# French texts:
+#
+#  Author: Sèbastien Brassard <sbrassar.cgocable.ca>
+#          Oscar Buijten <oscar@elbie.com>
+#          Wolfgang Sourdeau <wolfgang@contre.com>
+#          Aguibou KONE <aguibou.kone@rocketmail.com>
+#          Jens-Ingo Brodesser <jens-ingo@all2all.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/fr/LANGUAGE b/sql-ledger/locale/fr/LANGUAGE
new file mode 100644 (file)
index 0000000..744b2c3
--- /dev/null
@@ -0,0 +1 @@
+French
diff --git a/sql-ledger/locale/fr/admin b/sql-ledger/locale/fr/admin
new file mode 100644 (file)
index 0000000..38498b1
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Contrôle d\'accès',
+  'Accounting'                  => 'Comptabilité',
+  'Add User'                    => 'Ajouter utilisateur',
+  'Address'                     => 'Adresse',
+  'Administration'              => 'Administration',
+  'Administrator'               => 'Administrateur',
+  'All Datasets up to date!'    => 'Tous les fichiers de données sont à jour!',
+  'Change Admin Password'       => 'Changement de mot de passe administrateur',
+  'Change Password'             => 'Changement de mot de passe',
+  'Character Set'               => 'Encodage des caractères',
+  'Click on login name to edit!' => 'Cliquer sur votre identifiant pour editer',
+  'Company'                     => 'Société',
+  'Connect to'                  => 'Connecter à',
+  'Continue'                    => 'Continuer',
+  'Create Chart of Accounts'    => 'Créer le Plan Comptable',
+  'Create Dataset'              => 'Créer fichier de données',
+  'DBI not installed!'          => 'DBI non installée!',
+  'Database'                    => 'Base de données',
+  'Database Administration'     => 'Gérer base de données',
+  'Database Driver not checked!' => 'Pilotes de base de données pas verifiés!',
+  'Database User missing!'      => 'Utilisateur base de données manquante!',
+  'Dataset'                     => 'Fichier de données',
+  'Dataset missing!'            => 'Fichier de données manquant!',
+  'Dataset updated!'            => 'Base de données mise à jour!',
+  'Date Format'                 => 'Format de Date',
+  'Delete'                      => 'Supprimer',
+  'Delete Dataset'              => 'Supprimer fichier de données',
+  'Directory'                   => 'Répertoire',
+  'Driver'                      => 'Pilote',
+  'Dropdown Limit'              => 'Limit de déroulement',
+  'E-mail'                      => 'Email',
+  'Edit User'                   => 'Modifier utilisateur',
+  'Existing Datasets'           => 'Fichiers de données existants',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Hôte',
+  'Hostname missing!'           => 'Nom de l\'hôte manquant',
+  'Incorrect Password!'         => 'Mot de passe incorrect!',
+  'Language'                    => 'Langue',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Laisser "port" et "hôte" vide, sauf si vous voulez vous connecter à distance (par réseau)',
+  'Login'                       => 'Login',
+  'Multibyte Encoding'          => 'Encodage multibyte',
+  'Name'                        => 'Nom',
+  'New Templates'               => 'Nouveaux modèles',
+  'No Database Drivers available!' => 'Pas de pilotes de base de données disponibles!',
+  'No Dataset selected!'        => 'Pas de fichier de données sélectioné!',
+  'Nothing to delete!'          => 'Rien à supprimer',
+  'Number Format'               => 'Format des numéros',
+  'Oracle Database Administration' => 'Administration de base de données Oracle',
+  'Password'                    => 'Mot de Passe',
+  'Password changed!'           => 'Mot de passe changé!',
+  'Pg Database Administration'  => 'Administration base de données PostgreSQL',
+  'Phone'                       => 'Tél.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port manquant!',
+  'Printer'                     => 'Imprimante',
+  'Save'                        => 'Enregistrer',
+  'Select a Dataset to delete and press "Continue"' => 'Sélectionner la base de données à supprimer et cliquer sur "Continuer"',
+  'Setup Templates'             => 'Configuration des Gabarits',
+  'Ship via'                    => 'Expédier via',
+  'Signature'                   => 'Signature',
+  'Stylesheet'                  => 'Feuille de style',
+  'Templates'                   => 'Gabarits',
+  'The following Datasets are not in use and can be deleted' => 'Les fichiers de données suivants ne sont pas utilisés et peuvent être supprimés.',
+  'The following Datasets need to be updated' => 'Les fichiers de données suivants doivent être mis a jour',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Ceci est un test préliminaire des sources existante. Aucune modification à ce stade!!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Pour ajouter un utilisateur à un groupe, editer un "nom", changer le "login" et enregistrer. Un nouveau utilisateur avec les mêmes données sera enregistré avec le nouveau "login".',
+  'Update Dataset'              => 'Mis à jour de la base de données',
+  'Use Templates'               => 'Utiliser les modèles',
+  'User'                        => 'Utilisateur',
+  'User deleted!'               => 'Utilisateur supprimé!',
+  'User saved!'                 => 'Utilisateur enregistré!',
+  'Version'                     => 'Version',
+  'You must enter a host and port for local and remote connections!' => 'Vous devez saisir un "hôte" et un "port" pour les connexions distantes!',
+  'does not exist'              => 'n\'existe pas!',
+  'is already a member!'        => 'est déjà un membre!',
+  'localhost'                   => 'hôte local',
+  'locked!'                     => 'verrouillé!',
+  'successfully created!'       => 'créé avec succès',
+  'successfully deleted!'       => 'supprimé avec succès',
+  'website'                     => 'site web',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'ajouter_utilisateur'         => 'add_user',
+  'changement_de_mot_de_passe_administrateur' => 'change_admin_password',
+  'changement_de_mot_de_passe'  => 'change_password',
+  'continuer'                   => 'continue',
+  'créer_fichier_de_données'    => 'create_dataset',
+  'supprimer'                   => 'delete',
+  'supprimer_fichier_de_données' => 'delete_dataset',
+  'login'                       => 'login',
+  'administration_de_base_de_données_oracle' => 'oracle_database_administration',
+  'administration_base_de_données_postgresql' => 'pg_database_administration',
+  'enregistrer'                 => 'save',
+  'mis_à_jour_de_la_base_de_données' => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/all b/sql-ledger/locale/fr/all
new file mode 100644 (file)
index 0000000..3d514c3
--- /dev/null
@@ -0,0 +1,495 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Dépenses',
+  'AP Aging'                    => 'Dépenses exigibles',
+  'AP Transaction'              => 'Ecriture Dépense',
+  'AP Transactions'             => 'Mouvements - Dépenses',
+  'AR'                          => 'Recettes',
+  'AR Aging'                    => 'Recettes exigibles',
+  'AR Transaction'              => 'Ecriture Recette',
+  'AR Transactions'             => 'Mouvements - Recettes',
+  'About'                       => 'A propos',
+  'Access Control'              => 'Contrôle d\'accès',
+  'Account'                     => 'Compte',
+  'Account Number'              => 'Numéro de compte',
+  'Account Number missing!'     => 'Numéro de compte manquant!',
+  'Account Type'                => 'Type de compte',
+  'Account Type missing!'       => 'Type de compte manquant!',
+  'Account deleted!'            => 'Compte supprimé',
+  'Account saved!'              => 'Compte enregistré',
+  'Accounting'                  => 'Comptabilité',
+  'Accounting Menu'             => 'Menu de comptabilité',
+  'Accounts'                    => 'Comptes',
+  'Active'                      => 'Actif',
+  'Add'                         => 'Ajouter',
+  'Add Account'                 => 'Ajouter compte',
+  'Add Accounts Payables Transaction' => 'Saisie d\'écriture - Dépenses',
+  'Add Accounts Receivables Transaction' => 'Saisie d\'écriture - Recettes',
+  'Add Assembly'                => 'Ajouter produit',
+  'Add Customer'                => 'Ajouter client',
+  'Add GIFI'                    => 'Ajouter Code d\'Identification Comptable ou Fiscale',
+  'Add General Ledger Transaction' => 'Ajouter une écriture au Grand Livre',
+  'Add Part'                    => 'Ajouter marchandise',
+  'Add Project'                 => 'Ajouter projet',
+  'Add Purchase Invoice'        => 'Etablir facture d\'achat',
+  'Add Purchase Order'          => 'Etablir commande d\'achat',
+  'Add Sales Invoice'           => 'Etablir facture de vente',
+  'Add Sales Order'             => 'Etablir commande de vente',
+  'Add Service'                 => 'Ajouter service',
+  'Add Transaction'             => 'Saisie d\'écriture',
+  'Add User'                    => 'Ajouter utilisateur',
+  'Add Vendor'                  => 'Ajouter fournisseur',
+  'Address'                     => 'Adresse',
+  'Administration'              => 'Administration',
+  'Administrator'               => 'Administrateur',
+  'All'                         => 'Tous',
+  'All Datasets up to date!'    => 'Tous les fichiers de données sont à jour!',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Montant dû',
+  'Amount does not equal applied!' => 'Le montant n\'est égal à celui appliqué!',
+  'Amount missing!'             => 'Montant manquant',
+  'Applied'                     => 'Appliquer',
+  'Apr'                         => 'Avril',
+  'April'                       => 'Avril',
+  'Are you sure you want to delete Invoice Number' => 'Êtes-vous sûr de vouloir supprimer la Facture No.:',
+  'Are you sure you want to delete Order Number' => 'Êtes vous sûr de vouloir supprimer Commande N°',
+  'Are you sure you want to delete Transaction' => 'Êtes vous sûr de vouloir effacer la saisie?',
+  'Assemblies'                  => 'Produits finis',
+  'Assemblies restocked!'       => 'Renvoyer produits vers stock!',
+  'Assembly Number missing!'    => 'Numéro de produit manquant',
+  'Asset'                       => 'Actif',
+  'Attachment'                  => 'Pièce jointe',
+  'Audit Control'               => 'Clôture périodique',
+  'Aug'                         => 'Août',
+  'August'                      => 'Août',
+  'BOM'                         => 'Nomenclature composantes',
+  'Backup'                      => 'Sauvegarder',
+  'Backup sent to'              => 'Sauvegarde envoyée à',
+  'Balance'                     => 'Solde',
+  'Balance Sheet'               => 'Bilan',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Localisation',
+  'Books are open'              => 'Début exercice',
+  'Bought'                      => 'Acheté',
+  'Business Number'             => 'Numéro d\'enregistrement société',
+  'C'                           => 'C',
+  'COGS'                        => 'CMV',
+  'Cannot delete account!'      => 'Impossible de supprimer le compte!',
+  'Cannot delete customer!'     => 'Impossible de supprimer le client!',
+  'Cannot delete default account!' => 'Ne peut pas supprimer le compte par defaut!',
+  'Cannot delete invoice!'      => 'Impossible de supprimer la facture',
+  'Cannot delete item already invoiced!' => 'Ne peut pas effacer un élément qui est déjà facturé!',
+  'Cannot delete item on order!' => 'Impossible de supprimer un élément faisant partie d\'une commande',
+  'Cannot delete item which is part of an assembly!' => 'Ne peut pas supprimer une marchandise qui est intégrée dans un produit fini!',
+  'Cannot delete item!'         => 'Impossible de supprimer ce poste!',
+  'Cannot delete order!'        => 'Impossible de supprimer la commande!',
+  'Cannot delete transaction!'  => 'Impossible de supprimer la saisie!',
+  'Cannot delete vendor!'       => 'Impossible de supprimer le fournisseur!',
+  'Cannot have a value in both Debit and Credit!' => 'Impossible d\'avoir des valeurs dans Crédit et Débit en même temps!',
+  'Cannot post a transaction without a value!' => 'Impossible d\'effectuer une écriture sans valeur!',
+  'Cannot post invoice for a closed period!' => 'Impossible d\'enregistrer la facture sur un exercice clos!',
+  'Cannot post invoice!'        => 'Impossible d\'enregistrer la facture!',
+  'Cannot post payment for a closed period!' => 'Impossible d\'enregistrer le paiement sur un exercice clos!',
+  'Cannot post payment!'        => 'Impossible d\'enregistrer le paiement!',
+  'Cannot post transaction for a closed period!' => 'Impossible d\'enregistrer l\'écriture sur un exercice clos!',
+  'Cannot post transaction!'    => 'Impossible d\'enregistrer l\'écriture!',
+  'Cannot process payment for a closed period!' => 'Impossible de faire un paiement sur un exercice clos!',
+  'Cannot save account!'        => 'Impossible d\'enregistrer le compte!',
+  'Cannot save order!'          => 'Impossible d\'enregistrer la commande!',
+  'Cannot save preferences!'    => 'Impossible d\'enregistrer les préférences',
+  'Cannot stock assemblies!'    => 'Impossible de stocker l\'assemblage!',
+  'Cash'                        => 'Caisse',
+  'Cash based'                  => 'En liquide',
+  'Cc'                          => 'Cc',
+  'Change Admin Password'       => 'Changement de mot de passe administrateur',
+  'Change Password'             => 'Changement de mot de passe',
+  'Character Set'               => 'Encodage des caractères',
+  'Chart of Accounts'           => 'Plan Comptable',
+  'Check'                       => 'Chèque',
+  'Check printed!'              => 'Chèque imprimé!',
+  'Check printing failed!'      => 'Impression du chèque échoué!',
+  'Cleared Balance'             => 'Solde rapproché',
+  'Click on login name to edit!' => 'Cliquer sur votre identifiant pour editer',
+  'Close Books up to'           => 'Clôturer l\'exercice jusqu\'au',
+  'Closed'                      => 'Clôturé',
+  'Company'                     => 'Société',
+  'Compare to'                  => 'Comparer à',
+  'Confirm!'                    => 'Confirmez!',
+  'Connect to'                  => 'Connecter à',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continuer',
+  'Copies'                      => 'Copies',
+  'Copy to COA'                 => 'Copier dans le Plan Comptable',
+  'Create Chart of Accounts'    => 'Créer le Plan Comptable',
+  'Create Dataset'              => 'Créer fichier de données',
+  'Credit'                      => 'Crédit',
+  'Credit Limit'                => 'Encours autorisé',
+  'Curr'                        => 'En cours',
+  'Currency'                    => 'Devise',
+  'Current'                     => 'En cours',
+  'Customer'                    => 'Client',
+  'Customer deleted!'           => 'Client supprimé!',
+  'Customer missing!'           => 'Client manquant!',
+  'Customer not on file!'       => 'Client absent du fichier!',
+  'Customer saved!'             => 'Client enregistré!',
+  'Customers'                   => 'Clients',
+  'DBI not installed!'          => 'DBI non installée!',
+  'Database'                    => 'Base de données',
+  'Database Administration'     => 'Gérer base de données',
+  'Database Driver not checked!' => 'Pilotes de base de données pas verifiés!',
+  'Database Host'               => 'Hôte de base de données',
+  'Database User missing!'      => 'Utilisateur base de données manquante!',
+  'Dataset'                     => 'Fichier de données',
+  'Dataset missing!'            => 'Fichier de données manquant!',
+  'Dataset updated!'            => 'Base de données mise à jour!',
+  'Date'                        => 'Date',
+  'Date Due'                    => 'Date d\'échéance',
+  'Date Format'                 => 'Format de Date',
+  'Date Paid'                   => 'Date de paiement',
+  'Date missing!'               => 'Date manquante!',
+  'Debit'                       => 'Débit',
+  'Debit and credit out of balance!' => 'Le débit et le crédit ne sont pas équilibrés!',
+  'Dec'                         => 'Déc.',
+  'December'                    => 'Décembre',
+  'Decimalplaces'               => 'Décimales',
+  'Delete'                      => 'Supprimer',
+  'Delete Account'              => 'Supprimer compte',
+  'Delete Dataset'              => 'Supprimer fichier de données',
+  'Delivery Date'               => 'Date de livraison',
+  'Department'                  => '',
+  'Deposit'                     => 'Dépôt',
+  'Description'                 => 'Description',
+  'Difference'                  => 'Différence',
+  'Directory'                   => 'Répertoire',
+  'Discount'                    => 'Remise',
+  'Done'                        => 'Fait!',
+  'Drawing'                     => 'Dessin',
+  'Driver'                      => 'Pilote',
+  'Dropdown Limit'              => 'Limit de déroulement',
+  'Due'                         => 'Echéance',
+  'Due Date'                    => 'Date d\'échéance',
+  'Due Date missing!'           => 'Date d\'échéance manquante!',
+  'E-mail'                      => 'Email',
+  'E-mail Statement to'         => 'Message éléctronique à',
+  'E-mail address missing!'     => 'Adresse email manquante!',
+  'Edit'                        => 'Modifier',
+  'Edit Account'                => 'Modifier le compte',
+  'Edit Accounts Payables Transaction' => 'Modifier Mouvements - Dépenses',
+  'Edit Accounts Receivables Transaction' => 'Modifier Mouvements - Recettes',
+  'Edit Assembly'               => 'Modifier produit fini / transformé',
+  'Edit Customer'               => 'Modifier client',
+  'Edit GIFI'                   => 'Modifier Code d\'Identification Comptable ou Fiscale',
+  'Edit General Ledger Transaction' => 'Modifier écriture Grand Livre',
+  'Edit Part'                   => 'Modifier marchandise',
+  'Edit Preferences for'        => 'Modifier les préférences pour',
+  'Edit Project'                => 'Modifier projet',
+  'Edit Purchase Invoice'       => 'Modifier facture d\'achat',
+  'Edit Purchase Order'         => 'Modifier commande d\'achat',
+  'Edit Sales Invoice'          => 'Modifier facture de vente',
+  'Edit Sales Order'            => 'Modifier commande de vente',
+  'Edit Service'                => 'Modifier service',
+  'Edit Template'               => 'Modifier modèle',
+  'Edit User'                   => 'Modifier utilisateur',
+  'Edit Vendor'                 => 'Modifier fournisseur',
+  'Employee'                    => 'Employé',
+  'Enforce transaction reversal for all dates' => 'Appliquer l\'inversion des écritures pour toutes les dates',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Entrer le nom de la monnaie nationale et des monnaies étrangères en 3 lettres séparées par (:) (Ex: EUR:USD:CAD)',
+  'Equity'                      => 'Capital',
+  'Exch'                        => 'Change',
+  'Exchangerate'                => 'Taux de change',
+  'Exchangerate Difference'     => 'Différence de taux de change',
+  'Exchangerate for payment missing!' => 'Taux de change manquant pour le paiement!',
+  'Exchangerate missing!'       => 'Taux de change manquant!',
+  'Existing Datasets'           => 'Fichiers de données existants',
+  'Expense'                     => 'Dépense',
+  'Expense Account'             => 'Compte Dépenses',
+  'Expense/Asset'               => 'Dépense/Actif',
+  'Extended'                    => 'Prix Total',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fév.',
+  'February'                    => 'Février',
+  'Foreign Exchange Gain'       => 'Produit conversion devises',
+  'Foreign Exchange Loss'       => 'Perte conversion devises',
+  'From'                        => 'De',
+  'GIFI'                        => 'Code d\'Identification Comptable ou Fiscale',
+  'GIFI deleted!'               => 'Code d\'Identification Comptable ou Fiscale supprimé!',
+  'GIFI missing!'               => 'Code d\'Identification Comptable ou Fiscale manquant!',
+  'GIFI saved!'                 => 'Code d\'Identification Comptable ou Fiscale enregistré!',
+  'GL Transaction'              => 'Transaction Grand Livre',
+  'General Ledger'              => 'Grand Livre',
+  'Goods & Services'            => 'Articles & Services',
+  'HTML Templates'              => 'Gabarits HTML',
+  'Heading'                     => 'En-tête',
+  'Host'                        => 'Hôte',
+  'Hostname missing!'           => 'Nom de l\'hôte manquant',
+  'ID'                          => 'ID',
+  'Image'                       => 'Image',
+  'In-line'                     => 'En ligne',
+  'Include in Report'           => 'Inclure dans l\'état',
+  'Include in drop-down menus'  => 'Inclure dans les menus deroulants',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Afficher ce compte sur les formulaires de client/fournisseur pour le marquer comme imposable?',
+  'Income'                      => 'Recettes',
+  'Income Account'              => 'Compte Recettes',
+  'Income Statement'            => 'Compte de Résultat',
+  'Incorrect Dataset version!'  => 'Fichier de données incorrect!',
+  'Incorrect Password!'         => 'Mot de passe incorrect!',
+  'Individual Items'            => 'Composition en marchandises individuelles',
+  'Inventory'                   => 'Inventaire',
+  'Inventory Account'           => 'Compte d\'Inventaire',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'La quantité en stock doit être à zéro avant de pouvoir indiquer cet assemblage comme obsolète!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'La quantité en stock devrait être zero avant de pouvoir indiquer cette pièce comme obsolète!',
+  'Inventory quantity must be zero!' => 'La quantité en stock doit être zero!',
+  'Invoice'                     => 'Facture',
+  'Invoice Date'                => 'Date de facturation',
+  'Invoice Date missing!'       => 'Date de facture manquante!',
+  'Invoice Number'              => 'Numéro de facture',
+  'Invoice Number missing!'     => 'Numéro de facture manquant!',
+  'Invoice deleted!'            => 'Facture supprimé!',
+  'Invoice posted!'             => 'Facture enregistré!',
+  'Invoices'                    => 'Factures',
+  'Is this a summary account to record' => 'Est-ce que c\'est un compte sommaire à enregistrer?',
+  'Item deleted!'               => 'Objet supprimé!',
+  'Item not on file!'           => 'Objet non-listé!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Janvier',
+  'Jul'                         => 'Juil.',
+  'July'                        => 'Juillet',
+  'Jun'                         => 'Juin',
+  'June'                        => 'Juin',
+  'LaTeX Templates'             => 'Gabarits LaTeX',
+  'Language'                    => 'Langue',
+  'Last Cost'                   => 'Dernier prix',
+  'Last Invoice Number'         => 'Dernier numéro de facture',
+  'Last Numbers & Default Accounts' => 'Derniers numéros et comptes par défauts',
+  'Last Purchase Order Number'  => 'Dernier numéro de commande d\'achat',
+  'Last Sales Order Number'     => 'Numéro de la dernière commande de vente',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Laisser "port" et "hôte" vide, sauf si vous voulez vous connecter à distance (par réseau)',
+  'Liability'                   => 'Passif',
+  'Licensed to'                 => 'Licence à',
+  'Line Total'                  => 'Total ligne',
+  'Link'                        => 'Liens',
+  'Link Accounts'               => 'Lier Comptes',
+  'List Accounts'               => 'Liste des comptes',
+  'List GIFI'                   => 'Afficher la liste des Codes d\'Identification Comptable ou Fiscale',
+  'List Price'                  => 'Prix d\'achat',
+  'List Transactions'           => 'Afficher écritures',
+  'Login'                       => 'Login',
+  'Logout'                      => 'Déconnexion',
+  'Make'                        => 'Marque',
+  'Mar'                         => 'Mars',
+  'March'                       => 'Mars',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Message',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Modèle',
+  'Multibyte Encoding'          => 'Encodage multibyte',
+  'N/A'                         => 'Non Applicable',
+  'Name'                        => 'Nom',
+  'Name missing!'               => 'Nom manquant!',
+  'New Templates'               => 'Nouveaux modèles',
+  'No'                          => 'Non',
+  'No Database Drivers available!' => 'Pas de pilotes de base de données disponibles!',
+  'No Dataset selected!'        => 'Pas de fichier de données sélectioné!',
+  'No email address for'        => 'Pas d\'adresse email pour',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nothing applied!'            => 'Rien n\'a été appliqué!',
+  'Nothing selected!'           => 'Pas de sélection!',
+  'Nothing to delete!'          => 'Rien à supprimer',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numéro',
+  'Number Format'               => 'Format des numéros',
+  'Number missing in Row'       => 'Numéro manquant dans ligne',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Obsolète',
+  'Oct'                         => 'Oct.',
+  'October'                     => 'Octobre',
+  'On Hand'                     => 'En Stock / Disponible',
+  'On Order'                    => 'Sur Commande',
+  'Open'                        => 'Ouvert',
+  'Oracle Database Administration' => 'Administration de base de données Oracle',
+  'Order'                       => 'Commande',
+  'Order Date'                  => 'Date commande',
+  'Order Date missing!'         => 'Date de commande manquante!',
+  'Order Entry'                 => 'Bons de Commandes',
+  'Order Number'                => 'Numéro de commande',
+  'Order Number missing!'       => 'Numéro de commande manquant!',
+  'Order deleted!'              => 'Commande supprimé!',
+  'Order saved!'                => 'Commande enregistré!',
+  'Ordered'                     => 'Commandé',
+  'Orphaned'                    => 'Orphelin',
+  'Out of balance!'             => 'Solde non équilibré!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Liste d\'envoi',
+  'Packing List Date missing!'  => 'La date est manquante sur la liste d\'envoi!',
+  'Packing List Number missing!' => 'Le numéro de liste d\'envoi est manquant!',
+  'Paid'                        => 'Total Payé',
+  'Paid in full'                => 'Complètement payé',
+  'Part'                        => 'Marchandise',
+  'Part Number missing!'        => 'Numéro de marchandise manquant!',
+  'Parts'                       => 'Marchandises',
+  'Parts Inventory'             => 'Inventaire marchandises',
+  'Password'                    => 'Mot de Passe',
+  'Password changed!'           => 'Mot de passe changé!',
+  'Payables'                    => 'À Payer',
+  'Payment'                     => 'Paiement',
+  'Payment date missing!'       => 'Date de paiement manquant!',
+  'Payment posted!'             => 'Paiement enregistré!',
+  'Payments'                    => 'Paiements',
+  'Pg Database Administration'  => 'Administration base de données PostgreSQL',
+  'Phone'                       => 'Tél.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port manquant!',
+  'Post'                        => 'Enregistrer',
+  'Post as new'                 => 'Enregistrer comme nouveau',
+  'Postscript'                  => 'Postcript',
+  'Preferences'                 => 'Préférences',
+  'Preferences saved!'          => 'Préférences enregistrées!',
+  'Price'                       => 'Prix',
+  'Print'                       => 'Imprimer',
+  'Printer'                     => 'Imprimante',
+  'Project'                     => 'Projet',
+  'Project Number'              => '',
+  'Project Number missing!'     => 'Numéro du projet manquant!',
+  'Project deleted!'            => 'Projet supprimé!',
+  'Project not on file!'        => 'Projet absent du fichier!',
+  'Project saved!'              => 'Projet enregistré!',
+  'Projects'                    => 'Projets',
+  'Purchase Invoice'            => 'Facture d\'Achat',
+  'Purchase Order'              => 'Commande d\'Achat',
+  'Purchase Orders'             => 'Commandes d\'Achats',
+  'Qty'                         => 'Qté',
+  'ROP'                         => 'Niveau de commande',
+  'Rate'                        => 'Cadence',
+  'Recd'                        => 'Reçu',
+  'Receipt'                     => 'Reçu',
+  'Receipt printed!'            => '',
+  'Receipt printing failed!'    => '',
+  'Receipts'                    => 'Reçus',
+  'Receivables'                 => 'À recevoir',
+  'Reconciliation'              => 'Rapprochement',
+  'Record in'                   => 'Enregistrer dans',
+  'Reference'                   => 'Référence',
+  'Reference missing!'          => 'Référence manquant!',
+  'Remaining'                   => 'Restant',
+  'Report for'                  => 'Rapport de',
+  'Reports'                     => 'Rapports',
+  'Required by'                 => 'Requis pour',
+  'Retained Earnings'           => 'Éxcédents non distribués',
+  'Sales'                       => 'Ventes',
+  'Sales Invoice'               => 'Facture de Vente',
+  'Sales Order'                 => 'Commande de Vente',
+  'Sales Orders'                => 'Commandes de Vente',
+  'Save'                        => 'Enregistrer',
+  'Save as new'                 => 'Enregistrer comme nouveau',
+  'Save to File'                => 'Enregistrer comme fichier',
+  'Screen'                      => 'Écran',
+  'Select a Dataset to delete and press "Continue"' => 'Sélectionner la base de données à supprimer et cliquer sur "Continuer"',
+  'Select all'                  => 'Sélectionner tout',
+  'Select from one of the items below' => 'Sélectionner un des postes ci-dessous',
+  'Select from one of the names below' => 'Sélectionner un des noms ci-dessous',
+  'Select from one of the projects below' => 'Sélectionner un des projets ci-dessous',
+  'Select postscript or PDF!'   => 'Sélectionner Postscript ou PDF',
+  'Sell Price'                  => 'Prix de vente',
+  'Send by E-Mail'              => 'Envoyer par email',
+  'Sep'                         => 'Sept.',
+  'September'                   => 'Septembre',
+  'Service'                     => 'Service',
+  'Service Items'               => 'Services',
+  'Service Number missing!'     => 'Numéro de service manquant!',
+  'Services'                    => 'Services',
+  'Setup Templates'             => 'Configuration des Gabarits',
+  'Ship'                        => 'Expédier',
+  'Ship to'                     => 'Expédier à',
+  'Ship via'                    => 'Expédier via',
+  'Short'                       => 'Court',
+  'Signature'                   => 'Signature',
+  'Sold'                        => 'Vendu',
+  'Source'                      => 'Source',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Relevé',
+  'Statement Balance'           => 'Relevé de compte',
+  'Statement sent to'           => 'Relevé envoyé à',
+  'Statements sent to printer!' => 'Relevés envoyés à l\'imprimante!',
+  'Stock Assembly'              => 'Stock de produits',
+  'Stylesheet'                  => 'Feuille de style',
+  'Subject'                     => 'Objet',
+  'Subtotal'                    => 'Sous Total',
+  'System'                      => 'Système',
+  'Tax'                         => 'Taxe',
+  'Tax Accounts'                => 'Comptes de taxe',
+  'Tax Included'                => 'Taxe incluse',
+  'Tax collected'               => 'Taxe collectée',
+  'Tax paid'                    => 'Taxe payée',
+  'Taxable'                     => 'Imposable',
+  'Template saved!'             => 'Gabarit enregistré!',
+  'Templates'                   => 'Gabarits',
+  'Terms: Net'                  => 'Crédit limité à',
+  'The following Datasets are not in use and can be deleted' => 'Les fichiers de données suivants ne sont pas utilisés et peuvent être supprimés.',
+  'The following Datasets need to be updated' => 'Les fichiers de données suivants doivent être mis a jour',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Ceci est un test préliminaire des sources existante. Aucune modification à ce stade!!',
+  'To'                          => 'à ',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Pour ajouter un utilisateur à un groupe, editer un "nom", changer le "login" et enregistrer. Un nouveau utilisateur avec les mêmes données sera enregistré avec le nouveau "login".',
+  'Top Level'                   => 'Description principale',
+  'Total'                       => 'Total',
+  'Transaction Date missing!'   => 'Date d\'écriture manquante!',
+  'Transaction deleted!'        => 'Ecriture supprimée!',
+  'Transaction posted!'         => 'Ecriture enregistrée!',
+  'Transaction reversal enforced for all dates' => 'Inversion des écritures exécuté pour toutes les dates',
+  'Transaction reversal enforced up to' => 'Inversion des écritures exécuté jusqu\'au',
+  'Transactions'                => 'Mouvements',
+  'Transactions exist, cannot delete customer!' => 'Des écritures existent, impossible d\'effacer le client!',
+  'Transactions exist, cannot delete vendor!' => 'Des écritures existent, impossible d\'effacer le fournisseur!',
+  'Transactions exist; cannot delete account!' => 'Des écritures existent, impossible d\'effacer le compte!',
+  'Trial Balance'               => 'Balance Globale',
+  'Unit'                        => 'Unité',
+  'Unit of measure'             => 'Unité de mesure',
+  'Update'                      => 'Mettre à jour',
+  'Update Dataset'              => 'Mis à jour de la base de données',
+  'Updated'                     => 'Mis à jour',
+  'Use Templates'               => 'Utiliser les modèles',
+  'User'                        => 'Utilisateur',
+  'User deleted!'               => 'Utilisateur supprimé!',
+  'User saved!'                 => 'Utilisateur enregistré!',
+  'Vendor'                      => 'Fournisseur',
+  'Vendor deleted!'             => 'Fournisseur supprimé!',
+  'Vendor missing!'             => 'Fournisseur manquant!',
+  'Vendor not on file!'         => 'Fournisseur absent du fichier!',
+  'Vendor saved!'               => 'Fournisseur enregistré!',
+  'Vendors'                     => 'Fournisseurs',
+  'Version'                     => 'Version',
+  'Weight'                      => 'Poids',
+  'Weight Unit'                 => 'Unité de poids',
+  'What type of item is this?'  => 'De quel type est ce poste?',
+  'Year End'                    => 'Fin d\'année',
+  'Yes'                         => 'Oui',
+  'You are logged out!'         => 'Vous êtes déconnecté!',
+  'You did not enter a name!'   => 'Vous n\'avez pas saisi de nom!',
+  'You must enter a host and port for local and remote connections!' => 'Vous devez saisir un "hôte" et un "port" pour les connexions distantes!',
+  'as at'                       => 'au',
+  'collected on sales'          => 'collectées sur les ventes',
+  'days'                        => 'jours',
+  'does not exist'              => 'n\'existe pas!',
+  'ea'                          => 'ch',
+  'emailed to'                  => 'envoyé par email à',
+  'for Period'                  => 'pour la période',
+  'hr'                          => 'h',
+  'is already a member!'        => 'est déjà un membre!',
+  'is not a member!'            => 'n\'est pas un membre',
+  'localhost'                   => 'hôte local',
+  'locked!'                     => 'verrouillé!',
+  'paid on purchases'           => 'payées sur les achats',
+  'sent to printer'             => 'envoyé à l\'imprimante',
+  'successfully created!'       => 'créé avec succès',
+  'successfully deleted!'       => 'supprimé avec succès',
+  'to'                          => 'jusqu\'au',
+  'website'                     => 'site web',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/am b/sql-ledger/locale/fr/am
new file mode 100644 (file)
index 0000000..2c61263
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Dépenses',
+  'AR'                          => 'Recettes',
+  'Account'                     => 'Compte',
+  'Account Number'              => 'Numéro de compte',
+  'Account Number missing!'     => 'Numéro de compte manquant!',
+  'Account Type'                => 'Type de compte',
+  'Account Type missing!'       => 'Type de compte manquant!',
+  'Account deleted!'            => 'Compte supprimé',
+  'Account saved!'              => 'Compte enregistré',
+  'Add Account'                 => 'Ajouter compte',
+  'Add GIFI'                    => 'Ajouter Code d\'Identification Comptable ou Fiscale',
+  'Address'                     => 'Adresse',
+  'Asset'                       => 'Actif',
+  'Audit Control'               => 'Clôture périodique',
+  'Backup sent to'              => 'Sauvegarde envoyée à',
+  'Books are open'              => 'Début exercice',
+  'Business Number'             => 'Numéro d\'enregistrement société',
+  'COGS'                        => 'CMV',
+  'Cannot delete account!'      => 'Impossible de supprimer le compte!',
+  'Cannot delete default account!' => 'Ne peut pas supprimer le compte par defaut!',
+  'Cannot save account!'        => 'Impossible d\'enregistrer le compte!',
+  'Cannot save preferences!'    => 'Impossible d\'enregistrer les préférences',
+  'Character Set'               => 'Encodage des caractères',
+  'Chart of Accounts'           => 'Plan Comptable',
+  'Close Books up to'           => 'Clôturer l\'exercice jusqu\'au',
+  'Company'                     => 'Société',
+  'Continue'                    => 'Continuer',
+  'Copy to COA'                 => 'Copier dans le Plan Comptable',
+  'Credit'                      => 'Crédit',
+  'Date Format'                 => 'Format de Date',
+  'Debit'                       => 'Débit',
+  'Delete'                      => 'Supprimer',
+  'Delete Account'              => 'Supprimer compte',
+  'Description'                 => 'Description',
+  'Dropdown Limit'              => 'Limit de déroulement',
+  'E-mail'                      => 'Email',
+  'Edit'                        => 'Modifier',
+  'Edit Account'                => 'Modifier le compte',
+  'Edit GIFI'                   => 'Modifier Code d\'Identification Comptable ou Fiscale',
+  'Edit Preferences for'        => 'Modifier les préférences pour',
+  'Edit Template'               => 'Modifier modèle',
+  'Enforce transaction reversal for all dates' => 'Appliquer l\'inversion des écritures pour toutes les dates',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Entrer le nom de la monnaie nationale et des monnaies étrangères en 3 lettres séparées par (:) (Ex: EUR:USD:CAD)',
+  'Equity'                      => 'Capital',
+  'Expense'                     => 'Dépense',
+  'Expense Account'             => 'Compte Dépenses',
+  'Expense/Asset'               => 'Dépense/Actif',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Produit conversion devises',
+  'Foreign Exchange Loss'       => 'Perte conversion devises',
+  'GIFI'                        => 'Code d\'Identification Comptable ou Fiscale',
+  'GIFI deleted!'               => 'Code d\'Identification Comptable ou Fiscale supprimé!',
+  'GIFI missing!'               => 'Code d\'Identification Comptable ou Fiscale manquant!',
+  'GIFI saved!'                 => 'Code d\'Identification Comptable ou Fiscale enregistré!',
+  'Heading'                     => 'En-tête',
+  'Include in drop-down menus'  => 'Inclure dans les menus deroulants',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Afficher ce compte sur les formulaires de client/fournisseur pour le marquer comme imposable?',
+  'Income'                      => 'Recettes',
+  'Income Account'              => 'Compte Recettes',
+  'Inventory'                   => 'Inventaire',
+  'Inventory Account'           => 'Compte d\'Inventaire',
+  'Is this a summary account to record' => 'Est-ce que c\'est un compte sommaire à enregistrer?',
+  'Language'                    => 'Langue',
+  'Last Invoice Number'         => 'Dernier numéro de facture',
+  'Last Numbers & Default Accounts' => 'Derniers numéros et comptes par défauts',
+  'Last Purchase Order Number'  => 'Dernier numéro de commande d\'achat',
+  'Last Sales Order Number'     => 'Numéro de la dernière commande de vente',
+  'Liability'                   => 'Passif',
+  'Link'                        => 'Liens',
+  'Name'                        => 'Nom',
+  'No'                          => 'Non',
+  'No email address for'        => 'Pas d\'adresse email pour',
+  'Number'                      => 'Numéro',
+  'Number Format'               => 'Format des numéros',
+  'Parts Inventory'             => 'Inventaire marchandises',
+  'Password'                    => 'Mot de Passe',
+  'Payables'                    => 'À Payer',
+  'Payment'                     => 'Paiement',
+  'Phone'                       => 'Tél.',
+  'Preferences saved!'          => 'Préférences enregistrées!',
+  'Rate'                        => 'Cadence',
+  'Receivables'                 => 'À recevoir',
+  'Sales'                       => 'Ventes',
+  'Save'                        => 'Enregistrer',
+  'Service Items'               => 'Services',
+  'Ship via'                    => 'Expédier via',
+  'Signature'                   => 'Signature',
+  'Stylesheet'                  => 'Feuille de style',
+  'Tax'                         => 'Taxe',
+  'Tax Accounts'                => 'Comptes de taxe',
+  'Template saved!'             => 'Gabarit enregistré!',
+  'Transaction reversal enforced for all dates' => 'Inversion des écritures exécuté pour toutes les dates',
+  'Transaction reversal enforced up to' => 'Inversion des écritures exécuté jusqu\'au',
+  'Transactions exist; cannot delete account!' => 'Des écritures existent, impossible d\'effacer le compte!',
+  'Weight Unit'                 => 'Unité de poids',
+  'Year End'                    => 'Fin d\'année',
+  'Yes'                         => 'Oui',
+  'does not exist'              => 'n\'existe pas!',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'ajouter_compte'              => 'add_account',
+  'continuer'                   => 'continue',
+  'copier_dans_le_plan_comptable' => 'copy_to_coa',
+  'supprimer'                   => 'delete',
+  'modifier'                    => 'edit',
+  'modifier_le_compte'          => 'edit_account',
+  'enregistrer'                 => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/ap b/sql-ledger/locale/fr/ap
new file mode 100644 (file)
index 0000000..ac20a09
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Ecriture Dépense',
+  'AP Transactions'             => 'Mouvements - Dépenses',
+  'Account'                     => 'Compte',
+  'Add Accounts Payables Transaction' => 'Saisie d\'écriture - Dépenses',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Montant dû',
+  'Apr'                         => 'Avril',
+  'April'                       => 'Avril',
+  'Are you sure you want to delete Transaction' => 'Êtes vous sûr de vouloir effacer la saisie?',
+  'Aug'                         => 'Août',
+  'August'                      => 'Août',
+  'Cannot delete transaction!'  => 'Impossible de supprimer la saisie!',
+  'Cannot post payment for a closed period!' => 'Impossible d\'enregistrer le paiement sur un exercice clos!',
+  'Cannot post transaction for a closed period!' => 'Impossible d\'enregistrer l\'écriture sur un exercice clos!',
+  'Cannot post transaction!'    => 'Impossible d\'enregistrer l\'écriture!',
+  'Closed'                      => 'Clôturé',
+  'Confirm!'                    => 'Confirmez!',
+  'Continue'                    => 'Continuer',
+  'Currency'                    => 'Devise',
+  'Customer not on file!'       => 'Client absent du fichier!',
+  'Date'                        => 'Date',
+  'Date Paid'                   => 'Date de paiement',
+  'Dec'                         => 'Déc.',
+  'December'                    => 'Décembre',
+  'Delete'                      => 'Supprimer',
+  'Description'                 => 'Description',
+  'Due Date'                    => 'Date d\'échéance',
+  'Due Date missing!'           => 'Date d\'échéance manquante!',
+  'Edit Accounts Payables Transaction' => 'Modifier Mouvements - Dépenses',
+  'Employee'                    => 'Employé',
+  'Exch'                        => 'Change',
+  'Exchangerate'                => 'Taux de change',
+  'Exchangerate for payment missing!' => 'Taux de change manquant pour le paiement!',
+  'Exchangerate missing!'       => 'Taux de change manquant!',
+  'Feb'                         => 'Fév.',
+  'February'                    => 'Février',
+  'From'                        => 'De',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Inclure dans l\'état',
+  'Invoice'                     => 'Facture',
+  'Invoice Date'                => 'Date de facturation',
+  'Invoice Date missing!'       => 'Date de facture manquante!',
+  'Invoice Number'              => 'Numéro de facture',
+  'Invoice Number missing!'     => 'Numéro de facture manquant!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Janvier',
+  'Jul'                         => 'Juil.',
+  'July'                        => 'Juillet',
+  'Jun'                         => 'Juin',
+  'June'                        => 'Juin',
+  'Mar'                         => 'Mars',
+  'March'                       => 'Mars',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numéro',
+  'Oct'                         => 'Oct.',
+  'October'                     => 'Octobre',
+  'Open'                        => 'Ouvert',
+  'Order'                       => 'Commande',
+  'Order Number'                => 'Numéro de commande',
+  'Paid'                        => 'Total Payé',
+  'Payment date missing!'       => 'Date de paiement manquant!',
+  'Payments'                    => 'Paiements',
+  'Post'                        => 'Enregistrer',
+  'Post as new'                 => 'Enregistrer comme nouveau',
+  'Project'                     => 'Projet',
+  'Project not on file!'        => 'Projet absent du fichier!',
+  'Purchase Invoice'            => 'Facture d\'Achat',
+  'Select from one of the names below' => 'Sélectionner un des noms ci-dessous',
+  'Select from one of the projects below' => 'Sélectionner un des projets ci-dessous',
+  'Sep'                         => 'Sept.',
+  'September'                   => 'Septembre',
+  'Source'                      => 'Source',
+  'Subtotal'                    => 'Sous Total',
+  'Tax'                         => 'Taxe',
+  'Tax Included'                => 'Taxe incluse',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Ecriture supprimée!',
+  'Transaction posted!'         => 'Ecriture enregistrée!',
+  'Update'                      => 'Mettre à jour',
+  'Vendor'                      => 'Fournisseur',
+  'Vendor missing!'             => 'Fournisseur manquant!',
+  'Vendor not on file!'         => 'Fournisseur absent du fichier!',
+  'Yes'                         => 'Oui',
+  'to'                          => 'jusqu\'au',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ecriture_dépense'            => 'ap_transaction',
+  'saisie_d\'écriture___dépenses' => 'add_accounts_payables_transaction',
+  'continuer'                   => 'continue',
+  'supprimer'                   => 'delete',
+  'modifier_mouvements___dépenses' => 'edit_accounts_payables_transaction',
+  'enregistrer'                 => 'post',
+  'enregistrer_comme_nouveau'   => 'post_as_new',
+  'facture_d\'achat'            => 'purchase_invoice',
+  'mettre_à_jour'               => 'update',
+  'oui'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/ar b/sql-ledger/locale/fr/ar
new file mode 100644 (file)
index 0000000..49f2828
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'Ecriture Recette',
+  'AR Transactions'             => 'Mouvements - Recettes',
+  'Account'                     => 'Compte',
+  'Add Accounts Receivables Transaction' => 'Saisie d\'écriture - Recettes',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Montant dû',
+  'Apr'                         => 'Avril',
+  'April'                       => 'Avril',
+  'Are you sure you want to delete Transaction' => 'Êtes vous sûr de vouloir effacer la saisie?',
+  'Aug'                         => 'Août',
+  'August'                      => 'Août',
+  'Cannot delete transaction!'  => 'Impossible de supprimer la saisie!',
+  'Cannot post payment for a closed period!' => 'Impossible d\'enregistrer le paiement sur un exercice clos!',
+  'Cannot post transaction for a closed period!' => 'Impossible d\'enregistrer l\'écriture sur un exercice clos!',
+  'Cannot post transaction!'    => 'Impossible d\'enregistrer l\'écriture!',
+  'Closed'                      => 'Clôturé',
+  'Confirm!'                    => 'Confirmez!',
+  'Continue'                    => 'Continuer',
+  'Credit Limit'                => 'Encours autorisé',
+  'Currency'                    => 'Devise',
+  'Customer'                    => 'Client',
+  'Customer missing!'           => 'Client manquant!',
+  'Customer not on file!'       => 'Client absent du fichier!',
+  'Date'                        => 'Date',
+  'Date Paid'                   => 'Date de paiement',
+  'Dec'                         => 'Déc.',
+  'December'                    => 'Décembre',
+  'Delete'                      => 'Supprimer',
+  'Description'                 => 'Description',
+  'Due Date'                    => 'Date d\'échéance',
+  'Due Date missing!'           => 'Date d\'échéance manquante!',
+  'Edit Accounts Receivables Transaction' => 'Modifier Mouvements - Recettes',
+  'Employee'                    => 'Employé',
+  'Exch'                        => 'Change',
+  'Exchangerate'                => 'Taux de change',
+  'Exchangerate for payment missing!' => 'Taux de change manquant pour le paiement!',
+  'Exchangerate missing!'       => 'Taux de change manquant!',
+  'Feb'                         => 'Fév.',
+  'February'                    => 'Février',
+  'From'                        => 'De',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Inclure dans l\'état',
+  'Invoice'                     => 'Facture',
+  'Invoice Date'                => 'Date de facturation',
+  'Invoice Date missing!'       => 'Date de facture manquante!',
+  'Invoice Number'              => 'Numéro de facture',
+  'Invoice Number missing!'     => 'Numéro de facture manquant!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Janvier',
+  'Jul'                         => 'Juil.',
+  'July'                        => 'Juillet',
+  'Jun'                         => 'Juin',
+  'June'                        => 'Juin',
+  'Mar'                         => 'Mars',
+  'March'                       => 'Mars',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numéro',
+  'Oct'                         => 'Oct.',
+  'October'                     => 'Octobre',
+  'Open'                        => 'Ouvert',
+  'Order'                       => 'Commande',
+  'Order Number'                => 'Numéro de commande',
+  'Paid'                        => 'Total Payé',
+  'Payment date missing!'       => 'Date de paiement manquant!',
+  'Payments'                    => 'Paiements',
+  'Post'                        => 'Enregistrer',
+  'Post as new'                 => 'Enregistrer comme nouveau',
+  'Project'                     => 'Projet',
+  'Project not on file!'        => 'Projet absent du fichier!',
+  'Remaining'                   => 'Restant',
+  'Sales Invoice'               => 'Facture de Vente',
+  'Select from one of the names below' => 'Sélectionner un des noms ci-dessous',
+  'Select from one of the projects below' => 'Sélectionner un des projets ci-dessous',
+  'Sep'                         => 'Sept.',
+  'September'                   => 'Septembre',
+  'Source'                      => 'Source',
+  'Subtotal'                    => 'Sous Total',
+  'Tax'                         => 'Taxe',
+  'Tax Included'                => 'Taxe incluse',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Ecriture supprimée!',
+  'Transaction posted!'         => 'Ecriture enregistrée!',
+  'Update'                      => 'Mettre à jour',
+  'Vendor not on file!'         => 'Fournisseur absent du fichier!',
+  'Yes'                         => 'Oui',
+  'to'                          => 'jusqu\'au',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ecriture_recette'            => 'ar_transaction',
+  'continuer'                   => 'continue',
+  'supprimer'                   => 'delete',
+  'enregistrer'                 => 'post',
+  'enregistrer_comme_nouveau'   => 'post_as_new',
+  'facture_de_vente'            => 'sales_invoice',
+  'mettre_à_jour'               => 'update',
+  'oui'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/arap b/sql-ledger/locale/fr/arap
new file mode 100644 (file)
index 0000000..369913f
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Adresse',
+  'Continue'                    => 'Continuer',
+  'Customer not on file!'       => 'Client absent du fichier!',
+  'Description'                 => 'Description',
+  'Number'                      => 'Numéro',
+  'Project not on file!'        => 'Projet absent du fichier!',
+  'Select from one of the names below' => 'Sélectionner un des noms ci-dessous',
+  'Select from one of the projects below' => 'Sélectionner un des projets ci-dessous',
+  'Vendor not on file!'         => 'Fournisseur absent du fichier!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'continuer'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/ca b/sql-ledger/locale/fr/ca
new file mode 100644 (file)
index 0000000..1e011ac
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Compte',
+  'Apr'                         => 'Avril',
+  'April'                       => 'Avril',
+  'Aug'                         => 'Août',
+  'August'                      => 'Août',
+  'Balance'                     => 'Solde',
+  'Chart of Accounts'           => 'Plan Comptable',
+  'Credit'                      => 'Crédit',
+  'Date'                        => 'Date',
+  'Debit'                       => 'Débit',
+  'Dec'                         => 'Déc.',
+  'December'                    => 'Décembre',
+  'Description'                 => 'Description',
+  'Feb'                         => 'Fév.',
+  'February'                    => 'Février',
+  'From'                        => 'De',
+  'GIFI'                        => 'Code d\'Identification Comptable ou Fiscale',
+  'Include in Report'           => 'Inclure dans l\'état',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Janvier',
+  'Jul'                         => 'Juil.',
+  'July'                        => 'Juillet',
+  'Jun'                         => 'Juin',
+  'June'                        => 'Juin',
+  'List Transactions'           => 'Afficher écritures',
+  'Mar'                         => 'Mars',
+  'March'                       => 'Mars',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'Novembre',
+  'Oct'                         => 'Oct.',
+  'October'                     => 'Octobre',
+  'Reference'                   => 'Référence',
+  'Sep'                         => 'Sept.',
+  'September'                   => 'Septembre',
+  'Subtotal'                    => 'Sous Total',
+  'to'                          => 'jusqu\'au',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'afficher_écritures'          => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/cp b/sql-ledger/locale/fr/cp
new file mode 100644 (file)
index 0000000..b769513
--- /dev/null
@@ -0,0 +1,77 @@
+$self{texts} = {
+  'Account'                     => 'Compte',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Total',
+  'Amount does not equal applied!' => 'Le montant n\'est égal à celui appliqué!',
+  'Amount missing!'             => 'Montant manquant',
+  'Applied'                     => 'Appliquer',
+  'Cannot post payment!'        => 'Impossible d\'enregistrer le paiement!',
+  'Cannot process payment for a closed period!' => 'Impossible de faire un paiement sur un exercice clos!',
+  'Check'                       => 'Chèque',
+  'Check printed!'              => 'Chèque imprimé!',
+  'Check printing failed!'      => 'Impression du chèque échoué!',
+  'Continue'                    => 'Continuer',
+  'Currency'                    => 'Devise',
+  'Customer'                    => 'Client',
+  'Customer not on file!'       => 'Client absent du fichier!',
+  'Date'                        => 'Date',
+  'Date missing!'               => 'Date manquante!',
+  'Description'                 => 'Description',
+  'Due'                         => 'Echéance',
+  'Exchangerate'                => 'Taux de change',
+  'From'                        => 'De',
+  'Invoice'                     => 'Facture',
+  'Invoices'                    => 'Factures',
+  'Nothing applied!'            => 'Rien n\'a été appliqué!',
+  'Number'                      => 'Numéro',
+  'Paid in full'                => 'Complètement payé',
+  'Payment'                     => 'Paiement',
+  'Payment posted!'             => 'Paiement enregistré!',
+  'Post'                        => 'Enregistrer',
+  'Print'                       => 'Imprimer',
+  'Printer'                     => 'Imprimante',
+  'Project not on file!'        => 'Projet absent du fichier!',
+  'Receipt'                     => 'Reçu',
+  'Receipt printed!'            => 'Receipt printed!',
+  'Receipt printing failed!'    => 'Receipt printing failed!',
+  'Reference'                   => 'Référence',
+  'Screen'                      => 'Écran',
+  'Select from one of the names below' => 'Sélectionner un des noms ci-dessous',
+  'Select from one of the projects below' => 'Sélectionner un des projets ci-dessous',
+  'Update'                      => 'Mettre à jour',
+  'Vendor'                      => 'Fournisseur',
+  'Vendor not on file!'         => 'Fournisseur absent du fichier!',
+  'to'                          => 'jusqu\'au',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'continuer'                   => 'continue',
+  'enregistrer'                 => 'post',
+  'imprimer'                    => 'print',
+  'mettre_à_jour'               => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/ct b/sql-ledger/locale/fr/ct
new file mode 100644 (file)
index 0000000..21be5e2
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Ajouter',
+  'Address'                     => 'Adresse',
+  'All'                         => 'Tous',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Impossible de supprimer le client!',
+  'Cannot delete vendor!'       => 'Impossible de supprimer le fournisseur!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continuer',
+  'Credit Limit'                => 'Encours autorisé',
+  'Customer deleted!'           => 'Client supprimé!',
+  'Customer saved!'             => 'Client enregistré!',
+  'Customers'                   => 'Clients',
+  'Delete'                      => 'Supprimer',
+  'Discount'                    => 'Remise',
+  'E-mail'                      => 'Email',
+  'Edit Customer'               => 'Modifier client',
+  'Edit Vendor'                 => 'Modifier fournisseur',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Inclure dans l\'état',
+  'Invoice'                     => 'Facture',
+  'Name'                        => 'Nom',
+  'Name missing!'               => 'Nom manquant!',
+  'Notes'                       => 'Notes',
+  'Number'                      => 'Numéro',
+  'Order'                       => 'Commande',
+  'Orphaned'                    => 'Orphelin',
+  'Phone'                       => 'Tél.',
+  'Save'                        => 'Enregistrer',
+  'Ship to'                     => 'Expédier à',
+  'Tax Included'                => 'Taxe incluse',
+  'Taxable'                     => 'Imposable',
+  'Terms: Net'                  => 'Crédit limité à',
+  'Transactions exist, cannot delete customer!' => 'Des écritures existent, impossible d\'effacer le client!',
+  'Transactions exist, cannot delete vendor!' => 'Des écritures existent, impossible d\'effacer le fournisseur!',
+  'Vendor deleted!'             => 'Fournisseur supprimé!',
+  'Vendor saved!'               => 'Fournisseur enregistré!',
+  'Vendors'                     => 'Fournisseurs',
+  'days'                        => 'jours',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'ajouter'                     => 'add',
+  'continuer'                   => 'continue',
+  'supprimer'                   => 'delete',
+  'facture'                     => 'invoice',
+  'commande'                    => 'order',
+  'enregistrer'                 => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/gl b/sql-ledger/locale/fr/gl
new file mode 100644 (file)
index 0000000..da2e0ce
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Ecriture Dépense',
+  'AR Transaction'              => 'Ecriture Recette',
+  'Account'                     => 'Compte',
+  'Add General Ledger Transaction' => 'Ajouter une écriture au Grand Livre',
+  'Address'                     => 'Adresse',
+  'All'                         => 'Tous',
+  'Apr'                         => 'Avril',
+  'April'                       => 'Avril',
+  'Are you sure you want to delete Transaction' => 'Êtes vous sûr de vouloir effacer la saisie?',
+  'Asset'                       => 'Actif',
+  'Aug'                         => 'Août',
+  'August'                      => 'Août',
+  'Balance'                     => 'Solde',
+  'Cannot delete transaction!'  => 'Impossible de supprimer la saisie!',
+  'Cannot have a value in both Debit and Credit!' => 'Impossible d\'avoir des valeurs dans Crédit et Débit en même temps!',
+  'Cannot post a transaction without a value!' => 'Impossible d\'effectuer une écriture sans valeur!',
+  'Cannot post transaction for a closed period!' => 'Impossible d\'enregistrer l\'écriture sur un exercice clos!',
+  'Confirm!'                    => 'Confirmez!',
+  'Continue'                    => 'Continuer',
+  'Credit'                      => 'Crédit',
+  'Customer not on file!'       => 'Client absent du fichier!',
+  'Date'                        => 'Date',
+  'Debit'                       => 'Débit',
+  'Debit and credit out of balance!' => 'Le débit et le crédit ne sont pas équilibrés!',
+  'Dec'                         => 'Déc.',
+  'December'                    => 'Décembre',
+  'Delete'                      => 'Supprimer',
+  'Description'                 => 'Description',
+  'Edit General Ledger Transaction' => 'Modifier écriture Grand Livre',
+  'Equity'                      => 'Capital',
+  'Expense'                     => 'Dépense',
+  'Feb'                         => 'Fév.',
+  'February'                    => 'Février',
+  'From'                        => 'De',
+  'GIFI'                        => 'Code d\'Identification Comptable ou Fiscale',
+  'GL Transaction'              => 'Transaction Grand Livre',
+  'General Ledger'              => 'Grand Livre',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Inclure dans l\'état',
+  'Income'                      => 'Recettes',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Janvier',
+  'Jul'                         => 'Juil.',
+  'July'                        => 'Juillet',
+  'Jun'                         => 'Juin',
+  'June'                        => 'Juin',
+  'Liability'                   => 'Passif',
+  'Mar'                         => 'Mars',
+  'March'                       => 'Mars',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numéro',
+  'Oct'                         => 'Oct.',
+  'October'                     => 'Octobre',
+  'Post'                        => 'Enregistrer',
+  'Post as new'                 => 'Enregistrer comme nouveau',
+  'Project'                     => 'Projet',
+  'Project not on file!'        => 'Projet absent du fichier!',
+  'Purchase Invoice'            => 'Facture d\'Achat',
+  'Reference'                   => 'Référence',
+  'Reference missing!'          => 'Référence manquant!',
+  'Reports'                     => 'Rapports',
+  'Sales Invoice'               => 'Facture de Vente',
+  'Select from one of the names below' => 'Sélectionner un des noms ci-dessous',
+  'Select from one of the projects below' => 'Sélectionner un des projets ci-dessous',
+  'Sep'                         => 'Sept.',
+  'September'                   => 'Septembre',
+  'Source'                      => 'Source',
+  'Subtotal'                    => 'Sous Total',
+  'Transaction Date missing!'   => 'Date d\'écriture manquante!',
+  'Transaction deleted!'        => 'Ecriture supprimée!',
+  'Transaction posted!'         => 'Ecriture enregistrée!',
+  'Update'                      => 'Mettre à jour',
+  'Vendor not on file!'         => 'Fournisseur absent du fichier!',
+  'Yes'                         => 'Oui',
+  'to'                          => 'jusqu\'au',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ecriture_dépense'            => 'ap_transaction',
+  'ecriture_recette'            => 'ar_transaction',
+  'continuer'                   => 'continue',
+  'supprimer'                   => 'delete',
+  'transaction_grand_livre'     => 'gl_transaction',
+  'enregistrer'                 => 'post',
+  'enregistrer_comme_nouveau'   => 'post_as_new',
+  'facture_d\'achat'            => 'purchase_invoice',
+  'facture_de_vente'            => 'sales_invoice',
+  'mettre_à_jour'               => 'update',
+  'oui'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/ic b/sql-ledger/locale/fr/ic
new file mode 100644 (file)
index 0000000..58ffab7
--- /dev/null
@@ -0,0 +1,206 @@
+$self{texts} = {
+  'Active'                      => 'Actif',
+  'Add'                         => 'Ajouter',
+  'Add Assembly'                => 'Ajouter produit',
+  'Add Part'                    => 'Ajouter marchandise',
+  'Add Purchase Order'          => 'Etablir commande d\'achat',
+  'Add Sales Order'             => 'Etablir commande de vente',
+  'Add Service'                 => 'Ajouter service',
+  'Address'                     => 'Adresse',
+  'Apr'                         => 'Avril',
+  'April'                       => 'Avril',
+  'Assemblies'                  => 'Produits finis',
+  'Assemblies restocked!'       => 'Renvoyer produits vers stock!',
+  'Assembly Number missing!'    => 'Numéro de produit manquant',
+  'Attachment'                  => 'Pièce jointe',
+  'Aug'                         => 'Août',
+  'August'                      => 'Août',
+  'BOM'                         => 'Nomenclature composantes',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Localisation',
+  'Bought'                      => 'Acheté',
+  'COGS'                        => 'CMV',
+  'Cannot delete item already invoiced!' => 'Ne peut pas effacer un élément qui est déjà facturé!',
+  'Cannot delete item on order!' => 'Impossible de supprimer un élément faisant partie d\'une commande',
+  'Cannot delete item which is part of an assembly!' => 'Ne peut pas supprimer une marchandise qui est intégrée dans un produit fini!',
+  'Cannot delete item!'         => 'Impossible de supprimer ce poste!',
+  'Cannot stock assemblies!'    => 'Impossible de stocker l\'assemblage!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continuer',
+  'Copies'                      => 'Copies',
+  'Dec'                         => 'Déc.',
+  'December'                    => 'Décembre',
+  'Delete'                      => 'Supprimer',
+  'Delivery Date'               => 'Date de livraison',
+  'Description'                 => 'Description',
+  'Drawing'                     => 'Dessin',
+  'E-mail'                      => 'Email',
+  'E-mail address missing!'     => 'Adresse email manquante!',
+  'Edit Assembly'               => 'Modifier produit fini / transformé',
+  'Edit Part'                   => 'Modifier marchandise',
+  'Edit Service'                => 'Modifier service',
+  'Expense'                     => 'Dépense',
+  'Extended'                    => 'Prix Total',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fév.',
+  'February'                    => 'Février',
+  'From'                        => 'De',
+  'Image'                       => 'Image',
+  'In-line'                     => 'En ligne',
+  'Include in Report'           => 'Inclure dans l\'état',
+  'Income'                      => 'Recettes',
+  'Individual Items'            => 'Composition en marchandises individuelles',
+  'Inventory'                   => 'Inventaire',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'La quantité en stock doit être à zéro avant de pouvoir indiquer cet assemblage comme obsolète!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'La quantité en stock devrait être zero avant de pouvoir indiquer cette pièce comme obsolète!',
+  'Inventory quantity must be zero!' => 'La quantité en stock doit être zero!',
+  'Invoice'                     => 'Facture',
+  'Invoice Date missing!'       => 'Date de facture manquante!',
+  'Invoice Number'              => 'Numéro de facture',
+  'Invoice Number missing!'     => 'Numéro de facture manquant!',
+  'Item deleted!'               => 'Objet supprimé!',
+  'Item not on file!'           => 'Objet non-listé!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Janvier',
+  'Jul'                         => 'Juil.',
+  'July'                        => 'Juillet',
+  'Jun'                         => 'Juin',
+  'June'                        => 'Juin',
+  'Last Cost'                   => 'Dernier prix',
+  'Line Total'                  => 'Total ligne',
+  'Link Accounts'               => 'Lier Comptes',
+  'List Price'                  => 'Prix d\'achat',
+  'Make'                        => 'Marque',
+  'Mar'                         => 'Mars',
+  'March'                       => 'Mars',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Message',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Modèle',
+  'Name'                        => 'Nom',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numéro',
+  'Number missing in Row'       => 'Numéro manquant dans ligne',
+  'Obsolete'                    => 'Obsolète',
+  'Oct'                         => 'Oct.',
+  'October'                     => 'Octobre',
+  'On Hand'                     => 'En Stock / Disponible',
+  'On Order'                    => 'Sur Commande',
+  'Order'                       => 'Commande',
+  'Order Date missing!'         => 'Date de commande manquante!',
+  'Order Number'                => 'Numéro de commande',
+  'Order Number missing!'       => 'Numéro de commande manquant!',
+  'Ordered'                     => 'Commandé',
+  'Orphaned'                    => 'Orphelin',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Liste d\'envoi',
+  'Packing List Date missing!'  => 'La date est manquante sur la liste d\'envoi!',
+  'Packing List Number missing!' => 'Le numéro de liste d\'envoi est manquant!',
+  'Part'                        => 'Marchandise',
+  'Part Number missing!'        => 'Numéro de marchandise manquant!',
+  'Parts'                       => 'Marchandises',
+  'Phone'                       => 'Tél.',
+  'Postscript'                  => 'Postcript',
+  'Price'                       => 'Prix',
+  'Printer'                     => 'Imprimante',
+  'Project'                     => 'Projet',
+  'Purchase Order'              => 'Commande d\'Achat',
+  'Qty'                         => 'Qté',
+  'ROP'                         => 'Niveau de commande',
+  'Recd'                        => 'Reçu',
+  'Required by'                 => 'Requis pour',
+  'Sales'                       => 'Ventes',
+  'Sales Order'                 => 'Commande de Vente',
+  'Save'                        => 'Enregistrer',
+  'Screen'                      => 'Écran',
+  'Select from one of the items below' => 'Sélectionner un des postes ci-dessous',
+  'Select postscript or PDF!'   => 'Sélectionner Postscript ou PDF',
+  'Sell Price'                  => 'Prix de vente',
+  'Sep'                         => 'Sept.',
+  'September'                   => 'Septembre',
+  'Service'                     => 'Service',
+  'Service Number missing!'     => 'Numéro de service manquant!',
+  'Services'                    => 'Services',
+  'Ship'                        => 'Expédier',
+  'Ship to'                     => 'Expédier à',
+  'Short'                       => 'Court',
+  'Sold'                        => 'Vendu',
+  'Stock Assembly'              => 'Stock de produits',
+  'Subject'                     => 'Objet',
+  'Subtotal'                    => 'Sous Total',
+  'Tax'                         => 'Taxe',
+  'To'                          => 'à ',
+  'Top Level'                   => 'Description principale',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unité',
+  'Unit of measure'             => 'Unité de mesure',
+  'Update'                      => 'Mettre à jour',
+  'Updated'                     => 'Mis à jour',
+  'Weight'                      => 'Poids',
+  'What type of item is this?'  => 'De quel type est ce poste?',
+  'ea'                          => 'ch',
+  'emailed to'                  => 'envoyé par email à',
+  'hr'                          => 'h',
+  'sent to printer'             => 'envoyé à l\'imprimante',
+  'to'                          => 'jusqu\'au',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'ajouter'                     => 'add',
+  'ajouter_produit'             => 'add_assembly',
+  'ajouter_marchandise'         => 'add_part',
+  'ajouter_service'             => 'add_service',
+  'continuer'                   => 'continue',
+  'supprimer'                   => 'delete',
+  'modifier_produit_fini_/_transformé' => 'edit_assembly',
+  'modifier_marchandise'        => 'edit_part',
+  'modifier_service'            => 'edit_service',
+  'enregistrer'                 => 'save',
+  'mettre_à_jour'               => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/io b/sql-ledger/locale/fr/io
new file mode 100644 (file)
index 0000000..2ad48bc
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Etablir commande d\'achat',
+  'Add Sales Order'             => 'Etablir commande de vente',
+  'Address'                     => 'Adresse',
+  'Apr'                         => 'Avril',
+  'April'                       => 'Avril',
+  'Attachment'                  => 'Pièce jointe',
+  'Aug'                         => 'Août',
+  'August'                      => 'Août',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Localisation',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continuer',
+  'Copies'                      => 'Copies',
+  'Dec'                         => 'Déc.',
+  'December'                    => 'Décembre',
+  'Delivery Date'               => 'Date de livraison',
+  'Description'                 => 'Description',
+  'E-mail'                      => 'Email',
+  'E-mail address missing!'     => 'Adresse email manquante!',
+  'Extended'                    => 'Prix Total',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fév.',
+  'February'                    => 'Février',
+  'In-line'                     => 'En ligne',
+  'Invoice'                     => 'Facture',
+  'Invoice Date missing!'       => 'Date de facture manquante!',
+  'Invoice Number missing!'     => 'Numéro de facture manquant!',
+  'Item not on file!'           => 'Objet non-listé!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Janvier',
+  'Jul'                         => 'Juil.',
+  'July'                        => 'Juillet',
+  'Jun'                         => 'Juin',
+  'June'                        => 'Juin',
+  'Mar'                         => 'Mars',
+  'March'                       => 'Mars',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Message',
+  'Name'                        => 'Nom',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numéro',
+  'Number missing in Row'       => 'Numéro manquant dans ligne',
+  'Oct'                         => 'Oct.',
+  'October'                     => 'Octobre',
+  'Order'                       => 'Commande',
+  'Order Date missing!'         => 'Date de commande manquante!',
+  'Order Number missing!'       => 'Numéro de commande manquant!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Liste d\'envoi',
+  'Packing List Date missing!'  => 'La date est manquante sur la liste d\'envoi!',
+  'Packing List Number missing!' => 'Le numéro de liste d\'envoi est manquant!',
+  'Part'                        => 'Marchandise',
+  'Phone'                       => 'Tél.',
+  'Postscript'                  => 'Postcript',
+  'Price'                       => 'Prix',
+  'Printer'                     => 'Imprimante',
+  'Project'                     => 'Projet',
+  'Purchase Order'              => 'Commande d\'Achat',
+  'Qty'                         => 'Qté',
+  'Recd'                        => 'Reçu',
+  'Required by'                 => 'Requis pour',
+  'Sales Order'                 => 'Commande de Vente',
+  'Screen'                      => 'Écran',
+  'Select from one of the items below' => 'Sélectionner un des postes ci-dessous',
+  'Select postscript or PDF!'   => 'Sélectionner Postscript ou PDF',
+  'Sep'                         => 'Sept.',
+  'September'                   => 'Septembre',
+  'Service'                     => 'Service',
+  'Ship'                        => 'Expédier',
+  'Ship to'                     => 'Expédier à',
+  'Subject'                     => 'Objet',
+  'To'                          => 'à ',
+  'Unit'                        => 'Unité',
+  'What type of item is this?'  => 'De quel type est ce poste?',
+  'emailed to'                  => 'envoyé par email à',
+  'sent to printer'             => 'envoyé à l\'imprimante',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'continuer'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/ir b/sql-ledger/locale/fr/ir
new file mode 100644 (file)
index 0000000..edeec1f
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Compte',
+  'Add Purchase Invoice'        => 'Etablir facture d\'achat',
+  'Add Purchase Order'          => 'Etablir commande d\'achat',
+  'Add Sales Order'             => 'Etablir commande de vente',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Avril',
+  'April'                       => 'Avril',
+  'Are you sure you want to delete Invoice Number' => 'Êtes-vous sûr de vouloir supprimer la Facture No.:',
+  'Attachment'                  => 'Pièce jointe',
+  'Aug'                         => 'Août',
+  'August'                      => 'Août',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Localisation',
+  'Cannot delete invoice!'      => 'Impossible de supprimer la facture',
+  'Cannot post invoice for a closed period!' => 'Impossible d\'enregistrer la facture sur un exercice clos!',
+  'Cannot post invoice!'        => 'Impossible d\'enregistrer la facture!',
+  'Cannot post payment for a closed period!' => 'Impossible d\'enregistrer le paiement sur un exercice clos!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmez!',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continuer',
+  'Copies'                      => 'Copies',
+  'Currency'                    => 'Devise',
+  'Customer not on file!'       => 'Client absent du fichier!',
+  'Date'                        => 'Date',
+  'Date Due'                    => 'Date d\'échéance',
+  'Dec'                         => 'Déc.',
+  'December'                    => 'Décembre',
+  'Delete'                      => 'Supprimer',
+  'Delivery Date'               => 'Date de livraison',
+  'Description'                 => 'Description',
+  'E-mail'                      => 'Email',
+  'E-mail address missing!'     => 'Adresse email manquante!',
+  'Edit Purchase Invoice'       => 'Modifier facture d\'achat',
+  'Exch'                        => 'Change',
+  'Exchangerate'                => 'Taux de change',
+  'Exchangerate for payment missing!' => 'Taux de change manquant pour le paiement!',
+  'Exchangerate missing!'       => 'Taux de change manquant!',
+  'Extended'                    => 'Prix Total',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fév.',
+  'February'                    => 'Février',
+  'In-line'                     => 'En ligne',
+  'Invoice'                     => 'Facture',
+  'Invoice Date'                => 'Date de facturation',
+  'Invoice Date missing!'       => 'Date de facture manquante!',
+  'Invoice Number'              => 'Numéro de facture',
+  'Invoice Number missing!'     => 'Numéro de facture manquant!',
+  'Invoice deleted!'            => 'Facture supprimé!',
+  'Invoice posted!'             => 'Facture enregistré!',
+  'Item not on file!'           => 'Objet non-listé!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Janvier',
+  'Jul'                         => 'Juil.',
+  'July'                        => 'Juillet',
+  'Jun'                         => 'Juin',
+  'June'                        => 'Juin',
+  'Mar'                         => 'Mars',
+  'March'                       => 'Mars',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Message',
+  'Name'                        => 'Nom',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numéro',
+  'Number missing in Row'       => 'Numéro manquant dans ligne',
+  'Oct'                         => 'Oct.',
+  'October'                     => 'Octobre',
+  'Order'                       => 'Commande',
+  'Order Date missing!'         => 'Date de commande manquante!',
+  'Order Number'                => 'Numéro de commande',
+  'Order Number missing!'       => 'Numéro de commande manquant!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Liste d\'envoi',
+  'Packing List Date missing!'  => 'La date est manquante sur la liste d\'envoi!',
+  'Packing List Number missing!' => 'Le numéro de liste d\'envoi est manquant!',
+  'Part'                        => 'Marchandise',
+  'Payment date missing!'       => 'Date de paiement manquant!',
+  'Payments'                    => 'Paiements',
+  'Phone'                       => 'Tél.',
+  'Post'                        => 'Enregistrer',
+  'Post as new'                 => 'Enregistrer comme nouveau',
+  'Postscript'                  => 'Postcript',
+  'Price'                       => 'Prix',
+  'Printer'                     => 'Imprimante',
+  'Project'                     => 'Projet',
+  'Project not on file!'        => 'Projet absent du fichier!',
+  'Purchase Order'              => 'Commande d\'Achat',
+  'Qty'                         => 'Qté',
+  'Recd'                        => 'Reçu',
+  'Record in'                   => 'Enregistrer dans',
+  'Required by'                 => 'Requis pour',
+  'Sales Order'                 => 'Commande de Vente',
+  'Screen'                      => 'Écran',
+  'Select from one of the items below' => 'Sélectionner un des postes ci-dessous',
+  'Select from one of the names below' => 'Sélectionner un des noms ci-dessous',
+  'Select from one of the projects below' => 'Sélectionner un des projets ci-dessous',
+  'Select postscript or PDF!'   => 'Sélectionner Postscript ou PDF',
+  'Sep'                         => 'Sept.',
+  'September'                   => 'Septembre',
+  'Service'                     => 'Service',
+  'Ship'                        => 'Expédier',
+  'Ship to'                     => 'Expédier à',
+  'Source'                      => 'Source',
+  'Subject'                     => 'Objet',
+  'Subtotal'                    => 'Sous Total',
+  'Tax Included'                => 'Taxe incluse',
+  'To'                          => 'à ',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unité',
+  'Update'                      => 'Mettre à jour',
+  'Vendor'                      => 'Fournisseur',
+  'Vendor missing!'             => 'Fournisseur manquant!',
+  'Vendor not on file!'         => 'Fournisseur absent du fichier!',
+  'What type of item is this?'  => 'De quel type est ce poste?',
+  'Yes'                         => 'Oui',
+  'ea'                          => 'ch',
+  'emailed to'                  => 'envoyé par email à',
+  'sent to printer'             => 'envoyé à l\'imprimante',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuer'                   => 'continue',
+  'supprimer'                   => 'delete',
+  'commande'                    => 'order',
+  'enregistrer'                 => 'post',
+  'enregistrer_comme_nouveau'   => 'post_as_new',
+  'mettre_à_jour'               => 'update',
+  'oui'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/is b/sql-ledger/locale/fr/is
new file mode 100644 (file)
index 0000000..583e627
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Compte',
+  'Add Purchase Order'          => 'Etablir commande d\'achat',
+  'Add Sales Invoice'           => 'Etablir facture de vente',
+  'Add Sales Order'             => 'Etablir commande de vente',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Avril',
+  'April'                       => 'Avril',
+  'Are you sure you want to delete Invoice Number' => 'Êtes-vous sûr de vouloir supprimer la Facture No.:',
+  'Attachment'                  => 'Pièce jointe',
+  'Aug'                         => 'Août',
+  'August'                      => 'Août',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Localisation',
+  'Cannot delete invoice!'      => 'Impossible de supprimer la facture',
+  'Cannot post invoice for a closed period!' => 'Impossible d\'enregistrer la facture sur un exercice clos!',
+  'Cannot post invoice!'        => 'Impossible d\'enregistrer la facture!',
+  'Cannot post payment for a closed period!' => 'Impossible d\'enregistrer le paiement sur un exercice clos!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmez!',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continuer',
+  'Copies'                      => 'Copies',
+  'Credit Limit'                => 'Encours autorisé',
+  'Currency'                    => 'Devise',
+  'Customer'                    => 'Client',
+  'Customer missing!'           => 'Client manquant!',
+  'Customer not on file!'       => 'Client absent du fichier!',
+  'Date'                        => 'Date',
+  'Date Due'                    => 'Date d\'échéance',
+  'Dec'                         => 'Déc.',
+  'December'                    => 'Décembre',
+  'Delete'                      => 'Supprimer',
+  'Delivery Date'               => 'Date de livraison',
+  'Description'                 => 'Description',
+  'E-mail'                      => 'Email',
+  'E-mail address missing!'     => 'Adresse email manquante!',
+  'Edit Sales Invoice'          => 'Modifier facture de vente',
+  'Exch'                        => 'Change',
+  'Exchangerate'                => 'Taux de change',
+  'Exchangerate for payment missing!' => 'Taux de change manquant pour le paiement!',
+  'Exchangerate missing!'       => 'Taux de change manquant!',
+  'Extended'                    => 'Prix Total',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fév.',
+  'February'                    => 'Février',
+  'In-line'                     => 'En ligne',
+  'Invoice'                     => 'Facture',
+  'Invoice Date'                => 'Date de facturation',
+  'Invoice Date missing!'       => 'Date de facture manquante!',
+  'Invoice Number'              => 'Numéro de facture',
+  'Invoice Number missing!'     => 'Numéro de facture manquant!',
+  'Invoice deleted!'            => 'Facture supprimé!',
+  'Invoice posted!'             => 'Facture enregistré!',
+  'Item not on file!'           => 'Objet non-listé!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Janvier',
+  'Jul'                         => 'Juil.',
+  'July'                        => 'Juillet',
+  'Jun'                         => 'Juin',
+  'June'                        => 'Juin',
+  'Mar'                         => 'Mars',
+  'March'                       => 'Mars',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Message',
+  'Name'                        => 'Nom',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numéro',
+  'Number missing in Row'       => 'Numéro manquant dans ligne',
+  'Oct'                         => 'Oct.',
+  'October'                     => 'Octobre',
+  'Order'                       => 'Commande',
+  'Order Date missing!'         => 'Date de commande manquante!',
+  'Order Number'                => 'Numéro de commande',
+  'Order Number missing!'       => 'Numéro de commande manquant!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Liste d\'envoi',
+  'Packing List Date missing!'  => 'La date est manquante sur la liste d\'envoi!',
+  'Packing List Number missing!' => 'Le numéro de liste d\'envoi est manquant!',
+  'Part'                        => 'Marchandise',
+  'Payment date missing!'       => 'Date de paiement manquant!',
+  'Payments'                    => 'Paiements',
+  'Phone'                       => 'Tél.',
+  'Post'                        => 'Enregistrer',
+  'Post as new'                 => 'Enregistrer comme nouveau',
+  'Postscript'                  => 'Postcript',
+  'Price'                       => 'Prix',
+  'Print'                       => 'Imprimer',
+  'Printer'                     => 'Imprimante',
+  'Project'                     => 'Projet',
+  'Project not on file!'        => 'Projet absent du fichier!',
+  'Purchase Order'              => 'Commande d\'Achat',
+  'Qty'                         => 'Qté',
+  'Recd'                        => 'Reçu',
+  'Record in'                   => 'Enregistrer dans',
+  'Remaining'                   => 'Restant',
+  'Required by'                 => 'Requis pour',
+  'Sales Order'                 => 'Commande de Vente',
+  'Screen'                      => 'Écran',
+  'Select from one of the items below' => 'Sélectionner un des postes ci-dessous',
+  'Select from one of the names below' => 'Sélectionner un des noms ci-dessous',
+  'Select from one of the projects below' => 'Sélectionner un des projets ci-dessous',
+  'Select postscript or PDF!'   => 'Sélectionner Postscript ou PDF',
+  'Sep'                         => 'Sept.',
+  'September'                   => 'Septembre',
+  'Service'                     => 'Service',
+  'Ship'                        => 'Expédier',
+  'Ship to'                     => 'Expédier à',
+  'Ship via'                    => 'Expédier via',
+  'Source'                      => 'Source',
+  'Subject'                     => 'Objet',
+  'Subtotal'                    => 'Sous Total',
+  'Tax Included'                => 'Taxe incluse',
+  'To'                          => 'à ',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unité',
+  'Update'                      => 'Mettre à jour',
+  'Vendor not on file!'         => 'Fournisseur absent du fichier!',
+  'What type of item is this?'  => 'De quel type est ce poste?',
+  'Yes'                         => 'Oui',
+  'ea'                          => 'ch',
+  'emailed to'                  => 'envoyé par email à',
+  'sent to printer'             => 'envoyé à l\'imprimante',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuer'                   => 'continue',
+  'supprimer'                   => 'delete',
+  'email'                       => 'e_mail',
+  'commande'                    => 'order',
+  'enregistrer'                 => 'post',
+  'enregistrer_comme_nouveau'   => 'post_as_new',
+  'imprimer'                    => 'print',
+  'expédier_à'                  => 'ship_to',
+  'mettre_à_jour'               => 'update',
+  'oui'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/login b/sql-ledger/locale/fr/login
new file mode 100644 (file)
index 0000000..1020ac2
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'A propos',
+  'Database Host'               => 'Hôte de base de données',
+  'Dataset'                     => 'Fichier de données',
+  'Incorrect Dataset version!'  => 'Fichier de données incorrect!',
+  'Incorrect Password!'         => 'Mot de passe incorrect!',
+  'Licensed to'                 => 'Licence à',
+  'Login'                       => 'Login',
+  'Name'                        => 'Nom',
+  'Password'                    => 'Mot de Passe',
+  'User'                        => 'Utilisateur',
+  'Version'                     => 'Version',
+  'You are logged out!'         => 'Vous êtes déconnecté!',
+  'You did not enter a name!'   => 'Vous n\'avez pas saisi de nom!',
+  'is not a member!'            => 'n\'est pas un membre',
+  'localhost'                   => 'hôte local',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'login'                       => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/menu b/sql-ledger/locale/fr/menu
new file mode 100644 (file)
index 0000000..102a1c2
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => 'Dépenses',
+  'AP Aging'                    => 'Dépenses exigibles',
+  'AR'                          => 'Recettes',
+  'AR Aging'                    => 'Recettes exigibles',
+  'Accounting Menu'             => 'Menu de comptabilité',
+  'Add Account'                 => 'Ajouter compte',
+  'Add Assembly'                => 'Ajouter produit',
+  'Add Customer'                => 'Ajouter client',
+  'Add GIFI'                    => 'Ajouter Code d\'Identification Comptable ou Fiscale',
+  'Add Part'                    => 'Ajouter marchandise',
+  'Add Project'                 => 'Ajouter projet',
+  'Add Service'                 => 'Ajouter service',
+  'Add Transaction'             => 'Saisie d\'écriture',
+  'Add Vendor'                  => 'Ajouter fournisseur',
+  'Assemblies'                  => 'Produits finis',
+  'Audit Control'               => 'Clôture périodique',
+  'Backup'                      => 'Sauvegarder',
+  'Balance Sheet'               => 'Bilan',
+  'Cash'                        => 'Caisse',
+  'Chart of Accounts'           => 'Plan Comptable',
+  'Check'                       => 'Chèque',
+  'Customers'                   => 'Clients',
+  'General Ledger'              => 'Grand Livre',
+  'Goods & Services'            => 'Articles & Services',
+  'HTML Templates'              => 'Gabarits HTML',
+  'Income Statement'            => 'Compte de Résultat',
+  'Invoice'                     => 'Facture',
+  'LaTeX Templates'             => 'Gabarits LaTeX',
+  'List Accounts'               => 'Liste des comptes',
+  'List GIFI'                   => 'Afficher la liste des Codes d\'Identification Comptable ou Fiscale',
+  'Logout'                      => 'Déconnexion',
+  'Order Entry'                 => 'Bons de Commandes',
+  'Packing List'                => 'Liste d\'envoi',
+  'Parts'                       => 'Marchandises',
+  'Payment'                     => 'Paiement',
+  'Payments'                    => 'Paiements',
+  'Preferences'                 => 'Préférences',
+  'Projects'                    => 'Projets',
+  'Purchase Invoice'            => 'Facture d\'Achat',
+  'Purchase Order'              => 'Commande d\'Achat',
+  'Purchase Orders'             => 'Commandes d\'Achats',
+  'Receipt'                     => 'Reçu',
+  'Receipts'                    => 'Reçus',
+  'Reconciliation'              => 'Rapprochement',
+  'Reports'                     => 'Rapports',
+  'Sales Invoice'               => 'Facture de Vente',
+  'Sales Order'                 => 'Commande de Vente',
+  'Sales Orders'                => 'Commandes de Vente',
+  'Save to File'                => 'Enregistrer comme fichier',
+  'Send by E-Mail'              => 'Envoyer par email',
+  'Services'                    => 'Services',
+  'Statement'                   => 'Relevé',
+  'Stock Assembly'              => 'Stock de produits',
+  'Stylesheet'                  => 'Feuille de style',
+  'System'                      => 'Système',
+  'Tax collected'               => 'Taxe collectée',
+  'Tax paid'                    => 'Taxe payée',
+  'Transactions'                => 'Mouvements',
+  'Trial Balance'               => 'Balance Globale',
+  'Vendors'                     => 'Fournisseurs',
+  'Version'                     => 'Version',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/oe b/sql-ledger/locale/fr/oe
new file mode 100644 (file)
index 0000000..d1c2b74
--- /dev/null
@@ -0,0 +1,200 @@
+$self{texts} = {
+  'Add'                         => 'Ajouter',
+  'Add Purchase Invoice'        => 'Etablir facture d\'achat',
+  'Add Purchase Order'          => 'Etablir commande d\'achat',
+  'Add Sales Invoice'           => 'Etablir facture de vente',
+  'Add Sales Order'             => 'Etablir commande de vente',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Avril',
+  'April'                       => 'Avril',
+  'Are you sure you want to delete Order Number' => 'Êtes vous sûr de vouloir supprimer Commande N°',
+  'Attachment'                  => 'Pièce jointe',
+  'Aug'                         => 'Août',
+  'August'                      => 'Août',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Localisation',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Impossible de supprimer la commande!',
+  'Cannot save order!'          => 'Impossible d\'enregistrer la commande!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Clôturé',
+  'Confirm!'                    => 'Confirmez!',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Continuer',
+  'Copies'                      => 'Copies',
+  'Credit Limit'                => 'Encours autorisé',
+  'Curr'                        => 'En cours',
+  'Currency'                    => 'Devise',
+  'Customer'                    => 'Client',
+  'Customer missing!'           => 'Client manquant!',
+  'Customer not on file!'       => 'Client absent du fichier!',
+  'Date'                        => 'Date',
+  'Dec'                         => 'Déc.',
+  'December'                    => 'Décembre',
+  'Delete'                      => 'Supprimer',
+  'Delivery Date'               => 'Date de livraison',
+  'Description'                 => 'Description',
+  'E-mail'                      => 'Email',
+  'E-mail address missing!'     => 'Adresse email manquante!',
+  'Edit Purchase Order'         => 'Modifier commande d\'achat',
+  'Edit Sales Order'            => 'Modifier commande de vente',
+  'Exchangerate'                => 'Taux de change',
+  'Exchangerate missing!'       => 'Taux de change manquant!',
+  'Extended'                    => 'Prix Total',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fév.',
+  'February'                    => 'Février',
+  'From'                        => 'De',
+  'ID'                          => 'ID',
+  'In-line'                     => 'En ligne',
+  'Include in Report'           => 'Inclure dans l\'état',
+  'Invoice'                     => 'Facture',
+  'Invoice Date missing!'       => 'Date de facture manquante!',
+  'Invoice Number missing!'     => 'Numéro de facture manquant!',
+  'Item not on file!'           => 'Objet non-listé!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Janvier',
+  'Jul'                         => 'Juil.',
+  'July'                        => 'Juillet',
+  'Jun'                         => 'Juin',
+  'June'                        => 'Juin',
+  'Mar'                         => 'Mars',
+  'March'                       => 'Mars',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Message',
+  'Name'                        => 'Nom',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notes',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numéro',
+  'Number missing in Row'       => 'Numéro manquant dans ligne',
+  'O'                           => 'O',
+  'Oct'                         => 'Oct.',
+  'October'                     => 'Octobre',
+  'Open'                        => 'Ouvert',
+  'Order'                       => 'Commande',
+  'Order Date'                  => 'Date commande',
+  'Order Date missing!'         => 'Date de commande manquante!',
+  'Order Number'                => 'Numéro de commande',
+  'Order Number missing!'       => 'Numéro de commande manquant!',
+  'Order deleted!'              => 'Commande supprimé!',
+  'Order saved!'                => 'Commande enregistré!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Liste d\'envoi',
+  'Packing List Date missing!'  => 'La date est manquante sur la liste d\'envoi!',
+  'Packing List Number missing!' => 'Le numéro de liste d\'envoi est manquant!',
+  'Part'                        => 'Marchandise',
+  'Phone'                       => 'Tél.',
+  'Postscript'                  => 'Postcript',
+  'Price'                       => 'Prix',
+  'Print'                       => 'Imprimer',
+  'Printer'                     => 'Imprimante',
+  'Project'                     => 'Projet',
+  'Project not on file!'        => 'Projet absent du fichier!',
+  'Purchase Order'              => 'Commande d\'Achat',
+  'Purchase Orders'             => 'Commandes d\'Achats',
+  'Qty'                         => 'Qté',
+  'Recd'                        => 'Reçu',
+  'Remaining'                   => 'Restant',
+  'Required by'                 => 'Requis pour',
+  'Sales Order'                 => 'Commande de Vente',
+  'Sales Orders'                => 'Commandes de Vente',
+  'Save'                        => 'Enregistrer',
+  'Save as new'                 => 'Enregistrer comme nouveau',
+  'Screen'                      => 'Écran',
+  'Select from one of the items below' => 'Sélectionner un des postes ci-dessous',
+  'Select from one of the names below' => 'Sélectionner un des noms ci-dessous',
+  'Select from one of the projects below' => 'Sélectionner un des projets ci-dessous',
+  'Select postscript or PDF!'   => 'Sélectionner Postscript ou PDF',
+  'Sep'                         => 'Sept.',
+  'September'                   => 'Septembre',
+  'Service'                     => 'Service',
+  'Ship'                        => 'Expédier',
+  'Ship to'                     => 'Expédier à',
+  'Ship via'                    => 'Expédier via',
+  'Subject'                     => 'Objet',
+  'Subtotal'                    => 'Sous Total',
+  'Tax'                         => 'Taxe',
+  'Tax Included'                => 'Taxe incluse',
+  'Terms: Net'                  => 'Crédit limité à',
+  'To'                          => 'à ',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unité',
+  'Update'                      => 'Mettre à jour',
+  'Vendor'                      => 'Fournisseur',
+  'Vendor missing!'             => 'Fournisseur manquant!',
+  'Vendor not on file!'         => 'Fournisseur absent du fichier!',
+  'What type of item is this?'  => 'De quel type est ce poste?',
+  'Yes'                         => 'Oui',
+  'days'                        => 'jours',
+  'ea'                          => 'ch',
+  'emailed to'                  => 'envoyé par email à',
+  'sent to printer'             => 'envoyé à l\'imprimante',
+  'to'                          => 'jusqu\'au',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'ajouter'                     => 'add',
+  'continuer'                   => 'continue',
+  'supprimer'                   => 'delete',
+  'email'                       => 'e_mail',
+  'facture'                     => 'invoice',
+  'imprimer'                    => 'print',
+  'enregistrer'                 => 'save',
+  'enregistrer_comme_nouveau'   => 'save_as_new',
+  'expédier_à'                  => 'ship_to',
+  'mettre_à_jour'               => 'update',
+  'oui'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/pe b/sql-ledger/locale/fr/pe
new file mode 100644 (file)
index 0000000..84127de
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Ajouter',
+  'Add Project'                 => 'Ajouter projet',
+  'All'                         => 'Tous',
+  'Continue'                    => 'Continuer',
+  'Delete'                      => 'Supprimer',
+  'Description'                 => 'Description',
+  'Edit Project'                => 'Modifier projet',
+  'Number'                      => 'Numéro',
+  'Orphaned'                    => 'Orphelin',
+  'Project'                     => 'Projet',
+  'Project Number missing!'     => 'Numéro du projet manquant!',
+  'Project deleted!'            => 'Projet supprimé!',
+  'Project saved!'              => 'Projet enregistré!',
+  'Projects'                    => 'Projets',
+  'Save'                        => 'Enregistrer',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'ajouter'                     => 'add',
+  'continuer'                   => 'continue',
+  'supprimer'                   => 'delete',
+  'enregistrer'                 => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/rc b/sql-ledger/locale/fr/rc
new file mode 100644 (file)
index 0000000..092aabe
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Compte',
+  'Balance'                     => 'Solde',
+  'Cleared Balance'             => 'Solde rapproché',
+  'Continue'                    => 'Continuer',
+  'Date'                        => 'Date',
+  'Deposit'                     => 'Dépôt',
+  'Description'                 => 'Description',
+  'Difference'                  => 'Différence',
+  'Done'                        => 'Fait!',
+  'Exchangerate Difference'     => 'Différence de taux de change',
+  'From'                        => 'De',
+  'Out of balance!'             => 'Solde non équilibré!',
+  'Payment'                     => 'Paiement',
+  'Reconciliation'              => 'Rapprochement',
+  'Select all'                  => 'Sélectionner tout',
+  'Source'                      => 'Source',
+  'Statement Balance'           => 'Relevé de compte',
+  'Update'                      => 'Mettre à jour',
+  'to'                          => 'jusqu\'au',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'continuer'                   => 'continue',
+  'fait!'                       => 'done',
+  'sélectionner_tout'           => 'select_all',
+  'mettre_à_jour'               => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/fr/rp b/sql-ledger/locale/fr/rp
new file mode 100644 (file)
index 0000000..dad49de
--- /dev/null
@@ -0,0 +1,120 @@
+$self{texts} = {
+  'AP Aging'                    => 'Dépenses exigibles',
+  'AR Aging'                    => 'Recettes exigibles',
+  'Account'                     => 'Compte',
+  'Accounts'                    => 'Comptes',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Avril',
+  'April'                       => 'Avril',
+  'Attachment'                  => 'Pièce jointe',
+  'Aug'                         => 'Août',
+  'August'                      => 'Août',
+  'Balance'                     => 'Solde',
+  'Balance Sheet'               => 'Bilan',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'En liquide',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Comparer à',
+  'Continue'                    => 'Continuer',
+  'Copies'                      => 'Copies',
+  'Credit'                      => 'Crédit',
+  'Current'                     => 'En cours',
+  'Customer'                    => 'Client',
+  'Date'                        => 'Date',
+  'Debit'                       => 'Débit',
+  'Dec'                         => 'Déc.',
+  'December'                    => 'Décembre',
+  'Decimalplaces'               => 'Décimales',
+  'Department'                  => 'Department',
+  'Description'                 => 'Description',
+  'Due'                         => 'Echéance',
+  'E-mail'                      => 'Email',
+  'E-mail Statement to'         => 'Message éléctronique à',
+  'Feb'                         => 'Fév.',
+  'February'                    => 'Février',
+  'From'                        => 'De',
+  'GIFI'                        => 'Code d\'Identification Comptable ou Fiscale',
+  'Heading'                     => 'En-tête',
+  'ID'                          => 'ID',
+  'In-line'                     => 'En ligne',
+  'Include in Report'           => 'Inclure dans l\'état',
+  'Income Statement'            => 'Compte de Résultat',
+  'Invoice'                     => 'Facture',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Janvier',
+  'Jul'                         => 'Juil.',
+  'July'                        => 'Juillet',
+  'Jun'                         => 'Juin',
+  'June'                        => 'Juin',
+  'Mar'                         => 'Mars',
+  'March'                       => 'Mars',
+  'May'                         => 'Mai',
+  'May '                        => 'Mai ',
+  'Message'                     => 'Message',
+  'N/A'                         => 'Non Applicable',
+  'Nothing selected!'           => 'Pas de sélection!',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'Novembre',
+  'Oct'                         => 'Oct.',
+  'October'                     => 'Octobre',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Paiements',
+  'Postscript'                  => 'Postcript',
+  'Print'                       => 'Imprimer',
+  'Printer'                     => 'Imprimante',
+  'Project Number'              => 'Project Number',
+  'Receipts'                    => 'Reçus',
+  'Report for'                  => 'Rapport de',
+  'Retained Earnings'           => 'Éxcédents non distribués',
+  'Screen'                      => 'Écran',
+  'Select all'                  => 'Sélectionner tout',
+  'Select postscript or PDF!'   => 'Sélectionner Postscript ou PDF',
+  'Sep'                         => 'Sept.',
+  'September'                   => 'Septembre',
+  'Source'                      => 'Source',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Relevé',
+  'Statement sent to'           => 'Relevé envoyé à',
+  'Statements sent to printer!' => 'Relevés envoyés à l\'imprimante!',
+  'Subject'                     => 'Objet',
+  'Subtotal'                    => 'Sous Total',
+  'Tax'                         => 'Taxe',
+  'Tax collected'               => 'Taxe collectée',
+  'Tax paid'                    => 'Taxe payée',
+  'Total'                       => 'Total',
+  'Trial Balance'               => 'Balance Globale',
+  'Vendor'                      => 'Fournisseur',
+  'as at'                       => 'au',
+  'collected on sales'          => 'collectées sur les ventes',
+  'for Period'                  => 'pour la période',
+  'paid on purchases'           => 'payées sur les achats',
+  'to'                          => 'jusqu\'au',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_accounts'               => 'list_accounts',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'continuer'                   => 'continue',
+  'email'                       => 'e_mail',
+  'imprimer'                    => 'print',
+  'sélectionner_tout'           => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/COPYING b/sql-ledger/locale/hu/COPYING
new file mode 100644 (file)
index 0000000..890d2e8
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2003
+#
+# Hungarian texts:
+#
+#  Author: Kabai József <kabai@investor.hu>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/hu/LANGUAGE b/sql-ledger/locale/hu/LANGUAGE
new file mode 100644 (file)
index 0000000..3459bb2
--- /dev/null
@@ -0,0 +1 @@
+Hungarian
diff --git a/sql-ledger/locale/hu/admin b/sql-ledger/locale/hu/admin
new file mode 100644 (file)
index 0000000..3aca70a
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Hozzáférési jogok',
+  'Accounting'                  => 'Könyvelés',
+  'Add User'                    => 'Új felhasználó',
+  'Address'                     => 'Cím',
+  'Administration'              => 'Rendszerfelügyelet',
+  'Administrator'               => 'Rendszergazda',
+  'All Datasets up to date!'    => 'Összes ügyféladatbázis frissítve!',
+  'Change Admin Password'       => 'Rendszergazda jelszavának megváltoztatása',
+  'Change Password'             => 'Jelszó megváltoztatása',
+  'Character Set'               => 'Betû kódlap',
+  'Click on login name to edit!' => 'Módosításhoz klikkeljen a felhasználó nevére!',
+  'Company'                     => 'Társaság',
+  'Connect to'                  => 'Csatlakozva ehhez:',
+  'Continue'                    => 'Folytatás',
+  'Create Chart of Accounts'    => 'Számlatükör készítése',
+  'Create Dataset'              => 'Új cégadatbázis',
+  'DBI not installed!'          => 'DBI program nincs installálva!',
+  'Database'                    => 'Adatbázis',
+  'Database Administration'     => 'Adatbázis felügyelet',
+  'Database Driver not checked!' => 'Nincs kijelölve az adatbázismotor típusa!',
+  'Database User missing!'      => 'Adatbázis felhasználója hiányzik!',
+  'Dataset'                     => 'Cégadatbázis',
+  'Dataset missing!'            => 'Cégadatbázis hiányzik!',
+  'Dataset updated!'            => 'Cégadatbázis frissítve!',
+  'Date Format'                 => 'Dátumformátum',
+  'Delete'                      => 'Törlés',
+  'Delete Dataset'              => 'Cégadatbázis törlése',
+  'Directory'                   => 'Könyvtár',
+  'Driver'                      => 'Meghajtó',
+  'Dropdown Limit'              => 'Lenyíló ablak limit',
+  'E-mail'                      => 'E-mail',
+  'Edit User'                   => 'Felhasználó módosítása',
+  'Existing Datasets'           => 'Létezõ cégadatbázisok',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Adatbázis helye:',
+  'Hostname missing!'           => 'Adatbázis helye hiányzik!',
+  'Incorrect Password!'         => 'Érvénytelen jelszó!',
+  'Language'                    => 'Nyelv',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Hagyja üresen a Hely és a Port mezõket, hacsak nem akar távoli kapcsolatot létesíteni',
+  'Login'                       => 'Belépés',
+  'Multibyte Encoding'          => 'Multibyte kódolás',
+  'Name'                        => 'Név',
+  'New Templates'               => 'Új sablonok',
+  'No Database Drivers available!' => 'Nincs elérhetõ adatbázismeghajtó!',
+  'No Dataset selected!'        => 'Nincs kiválasztott cégadatbázis!',
+  'Nothing to delete!'          => 'Nincs mit törölni!',
+  'Number Format'               => 'Számformátum',
+  'Oracle Database Administration' => 'Oracle adatbázis felügyelet',
+  'Password'                    => 'Jelszó',
+  'Password changed!'           => 'Jelszó megváltozott!',
+  'Pg Database Administration'  => 'Postgresql adatbázis felügyelet',
+  'Phone'                       => 'Telefon',
+  'Port'                        => 'Port száma',
+  'Port missing!'               => 'Port száma  hiányzik!',
+  'Printer'                     => 'Nyomtató',
+  'Save'                        => 'Mentés',
+  'Select a Dataset to delete and press "Continue"' => 'Válassza ki a törölni kívánt cégadatbázist, és klikkeljen a "Folytatás"-ra',
+  'Setup Templates'             => 'Sablonok beállítása',
+  'Ship via'                    => 'Szállítás innen:',
+  'Signature'                   => 'Aláírás',
+  'Stylesheet'                  => 'Stíluslap',
+  'Templates'                   => 'Sablonok',
+  'The following Datasets are not in use and can be deleted' => 'Az alábbi cégadatbázisok üresek, és törölhetõk',
+  'The following Datasets need to be updated' => 'Az alábbi cégadatbázisokat frissíteni kell',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'A meglévõ adatbázisok elõzetes ellenõrzése. A program itt még nem töröl és nem hoz létre semmit!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Új felhasználót úgy hozhat létre egy meglévõ cégadatbázishoz, hogy egy létezõ felhasználóra kattint, és a belépési nevet és a jelszót megváltoztatja és elmenti. Az új felhasználó örökli a beállításokat.',
+  'Update Dataset'              => 'Cégadatbázis frissítése',
+  'Use Templates'               => 'Sablon használata',
+  'User'                        => 'Felhasználó',
+  'User deleted!'               => 'Felhasználó törölve!',
+  'User saved!'                 => 'Felhasználó elmentve!',
+  'Version'                     => 'Verzió',
+  'You must enter a host and port for local and remote connections!' => 'A helyi és távoli kapcsolat eléréséhez írjon be helyet, és portszámot!',
+  'does not exist'              => 'nem létezik',
+  'is already a member!'        => 'már tag!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'zárolva',
+  'successfully created!'       => 'sikeresen létrehozva!',
+  'successfully deleted!'       => 'sikeresen törölve!',
+  'website'                     => 'honlap',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'Új_felhasználó'              => 'add_user',
+  'rendszergazda_jelszavának_megváltoztatása' => 'change_admin_password',
+  'jelszó_megváltoztatása'      => 'change_password',
+  'folytatás'                   => 'continue',
+  'Új_cégadatbázis'             => 'create_dataset',
+  'törlés'                      => 'delete',
+  'cégadatbázis_törlése'        => 'delete_dataset',
+  'belépés'                     => 'login',
+  'oracle_adatbázis_felügyelet' => 'oracle_database_administration',
+  'postgresql_adatbázis_felügyelet' => 'pg_database_administration',
+  'mentés'                      => 'save',
+  'cégadatbázis_frissítése'     => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/all b/sql-ledger/locale/hu/all
new file mode 100644 (file)
index 0000000..823f366
--- /dev/null
@@ -0,0 +1,499 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Szállítók',
+  'AP Aging'                    => 'Szállító lejárati lista',
+  'AP Transaction'              => 'Szállító tranzakció',
+  'AP Transactions'             => 'Szállító tranzakciók',
+  'AR'                          => 'Vevõk',
+  'AR Aging'                    => 'Vevõ lejárati lista',
+  'AR Transaction'              => 'Vevõ tranzakció',
+  'AR Transactions'             => 'Vevõ tranzakciók',
+  'About'                       => ' ',
+  'Access Control'              => 'Hozzáférési jogok',
+  'Account'                     => 'Számla',
+  'Account Number'              => 'Számlaszám',
+  'Account Number missing!'     => 'Számlaszám hiányzik!',
+  'Account Type'                => 'Számlatípus',
+  'Account Type missing!'       => 'Számlatípus hiányzik!',
+  'Account deleted!'            => 'Számla törölve!',
+  'Account saved!'              => 'Számla elmentve!',
+  'Accounting'                  => 'Könyvelés',
+  'Accounting Menu'             => 'Menü',
+  'Accounts'                    => 'Számlák',
+  'Active'                      => 'Aktív',
+  'Add'                         => 'Új',
+  'Add Account'                 => 'Új számla',
+  'Add Accounts Payables Transaction' => 'Új szállító tranzakció',
+  'Add Accounts Receivables Transaction' => 'Új vevõ tranzakció',
+  'Add Assembly'                => 'Új saját termék',
+  'Add Customer'                => 'Új vevõ',
+  'Add GIFI'                    => 'Új gyûjtõkód',
+  'Add General Ledger Transaction' => 'Új fõkönyvi könyvelés',
+  'Add Group'                   => '',
+  'Add Part'                    => 'Új cikk',
+  'Add Project'                 => 'Új munkaszám',
+  'Add Purchase Order'          => 'Új beszerzési rendelés',
+  'Add Sales Invoice'           => 'Új vevõszámla',
+  'Add Sales Order'             => 'Új vevõrendelés',
+  'Add Service'                 => 'Új szolgáltatás',
+  'Add Transaction'             => 'Új tranzakció',
+  'Add User'                    => 'Új felhasználó',
+  'Add Vendor'                  => 'Új szállító',
+  'Add Vendor Invoice'          => '',
+  'Address'                     => 'Cím',
+  'Administration'              => 'Rendszerfelügyelet',
+  'Administrator'               => 'Rendszergazda',
+  'All'                         => 'Összes',
+  'All Datasets up to date!'    => 'Összes ügyféladatbázis frissítve!',
+  'Amount'                      => 'Összeg',
+  'Amount Due'                  => 'Esedékes összeg',
+  'Amount does not equal applied!' => 'Az összeg nem egyezik a kitöltött szám(ok) összegével',
+  'Amount missing!'             => 'Összeg hiányzik!',
+  'Applied'                     => 'Kitöltés',
+  'Apr'                         => 'Ápr.',
+  'April'                       => 'Április',
+  'Are you sure you want to delete Invoice Number' => 'Biztos, hogy törölni akarja? Számlaszám:',
+  'Are you sure you want to delete Order Number' => 'Biztos, hogy törölni akarja? Megrendelésszám:',
+  'Are you sure you want to delete Transaction' => 'Biztos, hogy törölni akarja? Tranzakció:',
+  'Assemblies'                  => 'Saját termékek',
+  'Assemblies restocked!'       => 'Saját termékek készletre véve',
+  'Assembly Number missing!'    => 'Saját termékszám hiányzik!',
+  'Asset'                       => 'Eszköz',
+  'Attachment'                  => 'Csatolás',
+  'Audit Control'               => 'Audit Kontroll',
+  'Aug'                         => 'Aug.',
+  'August'                      => 'Augusztus',
+  'BOM'                         => '',
+  'Backup'                      => 'Biztonsági másolat',
+  'Backup sent to'              => 'Biztonsági másolat elküldve:',
+  'Balance'                     => 'Egyenleg',
+  'Balance Sheet'               => 'Mérleg',
+  'Bcc'                         => 'Titkos másolat',
+  'Bin'                         => 'Bin',
+  'Books are open'              => 'Az ügyféladatbázisban lehet könyvelni',
+  'Bought'                      => 'Vásárolt',
+  'Business Number'             => 'Cégszám',
+  'C'                           => 'C',
+  'COGS'                        => 'ELÁBÉ',
+  'Cannot delete account!'      => 'A számlát nem lehet törölni',
+  'Cannot delete customer!'     => 'A vevõt nem lehet törölni!',
+  'Cannot delete default account!' => 'Az alapbeállítású számlát nem lehet törölni!',
+  'Cannot delete invoice!'      => 'A partnerszámlát nem lehet törölni!',
+  'Cannot delete item!'         => 'A tételt nem lehet törölni!',
+  'Cannot delete order!'        => 'A rendelést nem lehet törölni!',
+  'Cannot delete transaction!'  => 'A tranzakciót nem lehet törölni!',
+  'Cannot delete vendor!'       => 'Szállítót nem lehet törölni!',
+  'Cannot have a value in both Debit and Credit!' => 'A Tartozik és Követel oldal is tartalmaz értéket!',
+  'Cannot post a transaction without a value!' => 'Az összeg megadása nélkül nem lehet a tranzakciót rögzíteni!',
+  'Cannot post invoice for a closed period!' => 'A lezárt idõszakban nem lehet számlát kiállítani!',
+  'Cannot post invoice!'        => 'A partnerszámlát nem lehet kiállítani',
+  'Cannot post payment for a closed period!' => 'A lezárt idõszakban nem lehet fizetést rögzíteni!',
+  'Cannot post payment!'        => 'A pénzmozgást nem lehet rögzíteni',
+  'Cannot post transaction for a closed period!' => 'A lezárt idõszakban nem lehet tranzakciót rögzíteni!!',
+  'Cannot post transaction!'    => 'A tranzakciót nem lehet rögzíteni!',
+  'Cannot process payment for a closed period!' => 'A pénzmozgást nem lehet lezárt idõszakban rögzíteni!',
+  'Cannot save account!'        => 'A számlát nem lehet elmenteni!',
+  'Cannot save order!'          => 'A rendelést nem lehet elmenteni!',
+  'Cannot save preferences!'    => 'A beállításokat nem lehet elmenteni',
+  'Cannot stock assemblies!'    => 'A saját terméket nem lehet készletre venni!',
+  'Cash'                        => 'Pénzmozgások',
+  'Cash based'                  => 'Pénzmozgás alapján',
+  'Cc'                          => 'Másolat',
+  'Change Admin Password'       => 'Rendszergazda jelszavának megváltoztatása',
+  'Change Password'             => 'Jelszó megváltoztatása',
+  'Character Set'               => 'Betû kódlap',
+  'Chart of Accounts'           => 'Számlatükör',
+  'Check'                       => 'Csekk',
+  'Check printed!'              => 'Csekk kinyomtatva!',
+  'Check printing failed!'      => 'A csekk nyomtatása nem sikerült!',
+  'Cleared Balance'             => 'Egyeztetett egyenleg',
+  'Click on login name to edit!' => 'Módosításhoz klikkeljen a felhasználó nevére!',
+  'Close Books up to'           => 'Könyvelés lezárása eddig az idõpontig:',
+  'Closed'                      => 'Lezárt',
+  'Company'                     => 'Társaság',
+  'Compare to'                  => 'Összehasonlítva:',
+  'Confirm!'                    => 'Megerõsítés:',
+  'Connect to'                  => 'Csatlakozva ehhez:',
+  'Contact'                     => 'Kapcsolat',
+  'Continue'                    => 'Folytatás',
+  'Copies'                      => 'Másolatok',
+  'Copy to COA'                 => 'Másolás a számlatükörbe',
+  'Create Chart of Accounts'    => 'Számlatükör készítése',
+  'Create Dataset'              => 'Új cégadatbázis',
+  'Credit'                      => 'Követel',
+  'Credit Limit'                => 'Hitelkeret',
+  'Curr'                        => 'Dev',
+  'Currency'                    => 'Deviza',
+  'Current'                     => 'Nem lejárt',
+  'Customer'                    => 'Vevõ',
+  'Customer deleted!'           => 'Vevõ törölve!',
+  'Customer missing!'           => 'Vevõ hiányzik!',
+  'Customer not on file!'       => 'A vevõ hiányzik az adatbázisból!',
+  'Customer saved!'             => 'Vevõ elmentve!',
+  'Customers'                   => 'Vevõadatok',
+  'DBI not installed!'          => 'DBI program nincs installálva!',
+  'Database'                    => 'Adatbázis',
+  'Database Administration'     => 'Adatbázis felügyelet',
+  'Database Driver not checked!' => 'Nincs kijelölve az adatbázismotor típusa!',
+  'Database Host'               => 'Adatbázis helye',
+  'Database User missing!'      => 'Adatbázis felhasználója hiányzik!',
+  'Dataset'                     => 'Cégadatbázis',
+  'Dataset missing!'            => 'Cégadatbázis hiányzik!',
+  'Dataset updated!'            => 'Cégadatbázis frissítve!',
+  'Date'                        => 'Dátum',
+  'Date Format'                 => 'Dátumformátum',
+  'Date Paid'                   => 'Fizetés napja',
+  'Date missing!'               => 'Dátum hiányzik',
+  'Debit'                       => 'Tartozik',
+  'Debit and credit out of balance!' => 'Tartozik Követel összege nem egyezik!',
+  'Dec'                         => 'Dec.',
+  'December'                    => 'December',
+  'Decimalplaces'               => 'Tizedeshelyek',
+  'Delete'                      => 'Törlés',
+  'Delete Account'              => 'Számla törlése',
+  'Delete Dataset'              => 'Cégadatbázis törlése',
+  'Delivery Date'               => 'Szállítás dátuma',
+  'Deposit'                     => 'Betét',
+  'Description'                 => 'Szöveges leírás',
+  'Difference'                  => 'Eltérés',
+  'Directory'                   => 'Könyvtár',
+  'Discount'                    => 'Engedmény',
+  'Done'                        => 'Elvégezve',
+  'Drawing'                     => 'Rajz',
+  'Driver'                      => 'Meghajtó',
+  'Dropdown Limit'              => 'Lenyíló ablak limit',
+  'Due'                         => 'Esedékes',
+  'Due Date'                    => 'Esedékesség',
+  'Due Date missing!'           => 'Esedékesség hiányzik!',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'Kimutatás küldése e-mail-ben:',
+  'E-mail address missing!'     => 'E-mail cím hiányzik!',
+  'Edit'                        => 'Módosítás',
+  'Edit Account'                => 'Számlaszám módosítása',
+  'Edit Accounts Payables Transaction' => 'Szállító tranzakció módosítása',
+  'Edit Accounts Receivables Transaction' => 'Vevõ tranzakció módosítása',
+  'Edit Assembly'               => 'Saját termék módosítása',
+  'Edit Customer'               => 'Vevõ módosítása',
+  'Edit GIFI'                   => 'Gyûjtõkód módosítása',
+  'Edit General Ledger Transaction' => 'Vegyes könyvelési tétel módosítása',
+  'Edit Group'                  => '',
+  'Edit Part'                   => 'Cikk módosítása',
+  'Edit Preferences for'        => 'Felhasználói paraméterek módosítása:',
+  'Edit Project'                => 'Projekt módosítása',
+  'Edit Purchase Order'         => 'Beszerzési rendelés módosítása',
+  'Edit Sales Invoice'          => 'Vevõszámla módosítása',
+  'Edit Sales Order'            => 'Vevõrendelés módosítása',
+  'Edit Service'                => 'Szolgáltatás módosítása',
+  'Edit Template'               => 'Sablon módosítása',
+  'Edit User'                   => 'Felhasználó módosítása',
+  'Edit Vendor'                 => 'Szállító módosítása',
+  'Edit Vendor Invoice'         => '',
+  'Employee'                    => 'Alkalmazott',
+  'Enforce transaction reversal for all dates' => 'Minden dátum esetében visszautasítsa a tranzakció rögzítését?',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'A saját és külföldi devizákat jelölje 3 betûvel kettõsponttal elválasztva! (pl. HUF:EUR:USD)',
+  'Equity'                      => 'Tõke',
+  'Exch'                        => 'Árf',
+  'Exchangerate'                => 'Átváltási árfolyam',
+  'Exchangerate Difference'     => 'Árfolyamkülönbség',
+  'Exchangerate for payment missing!' => 'A fizetett összeg átváltási árfolyama hiányzik!',
+  'Exchangerate missing!'       => 'Átváltási árfolyam hiányzik!',
+  'Existing Datasets'           => 'Létezõ cégadatbázisok',
+  'Expense'                     => 'Költség',
+  'Expense Account'             => 'Költségszámla',
+  'Expense/Asset'               => 'Költség/Eszköz',
+  'Extended'                    => 'Összeg',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb.',
+  'February'                    => 'Február',
+  'Foreign Exchange Gain'       => 'Árfolyamnyereség',
+  'Foreign Exchange Loss'       => 'Árfolyamveszteség',
+  'From'                        => 'Mikortól:',
+  'GIFI'                        => 'Gyûjtõkód',
+  'GIFI deleted!'               => 'Gyûjtõkód törölve!',
+  'GIFI missing!'               => 'Gyûjtõkód hiányzik!',
+  'GIFI saved!'                 => 'Gyûjtõkód elmentve!',
+  'GL Transaction'              => 'Fõkönyvi tranzakció!',
+  'General Ledger'              => 'Fõkönyvi könyvelés',
+  'Goods & Services'            => 'Áruk & Szolgáltatások',
+  'Group'                       => '',
+  'Group Items'                 => '',
+  'Group deleted!'              => '',
+  'Group missing!'              => '',
+  'Group saved!'                => '',
+  'Groups'                      => '',
+  'HTML Templates'              => 'HTML sablonok',
+  'Heading'                     => 'Fejléc',
+  'Host'                        => 'Adatbázis helye:',
+  'Hostname missing!'           => 'Adatbázis helye hiányzik!',
+  'ID'                          => 'Azonosító',
+  'Image'                       => 'Kép',
+  'In-line'                     => 'Beágyazva',
+  'Include in Report'           => 'Oszlopok:',
+  'Include in drop-down menus'  => 'Mely tranzakció(k)-nál lehessen kiválasztani?:',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Kiválasztható legyen a vevõ/szállító ûrlapokon, mint adószámla?',
+  'Income'                      => 'Árbevétel',
+  'Income Account'              => 'Árbevételszámla',
+  'Income Statement'            => 'Eredménykimutatás',
+  'Incorrect Dataset version!'  => 'Érvénytelen adatbázisverzió!',
+  'Incorrect Password!'         => 'Érvénytelen jelszó!',
+  'Individual Items'            => 'Összetevõk',
+  'Inventory'                   => 'Készlet',
+  'Inventory Account'           => 'Készletszámla',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Mielõtt ezt a saját terméket elévültnek nyilvánítja,a mennyiségnek nullának kell lennie!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Mielõtt ezt az anyagot/árut elévültnek nyilvánítja,a mennyiségnek nullának kell lennie!!',
+  'Invoice'                     => 'Számla',
+  'Invoice Date'                => 'Teljesítés dátuma',
+  'Invoice Date missing!'       => 'Teljesítés dátuma hiányzik!',
+  'Invoice Number'              => 'Számlaszám',
+  'Invoice Number missing!'     => 'Számlaszám hiányzik!',
+  'Invoice deleted!'            => 'Számla törölve!',
+  'Invoice posted!'             => 'Számla rögzítve!',
+  'Invoices'                    => 'Számlák',
+  'Is this a summary account to record' => 'Gyûjtõszámlaként szerepeljen ezeknél a tranzakcióknál:',
+  'Item deleted!'               => 'Tétel törölve!',
+  'Item not on file!'           => 'A tétel nincs az adatbázisban!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Január',
+  'Jul'                         => 'Júl.',
+  'July'                        => 'Július',
+  'Jun'                         => 'Jún.',
+  'June'                        => 'Június',
+  'LaTeX Templates'             => 'LaTeX sablonok',
+  'Language'                    => 'Nyelv',
+  'Last Cost'                   => 'Utolsó beszerzési ár',
+  'Last Invoice Number'         => 'Utolsó számlaszám',
+  'Last Numbers & Default Accounts' => 'Legutolsó számok & Alapszámlák',
+  'Last Purchase Order Number'  => 'Utolsó beszerzési rendelésszám',
+  'Last Sales Order Number'     => 'Utolsó vevõ rendelésszám',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Hagyja üresen a Hely és a Port mezõket, hacsak nem akar távoli kapcsolatot létesíteni',
+  'Liability'                   => 'Kötelezettség',
+  'Licensed to'                 => 'Cég:',
+  'Line Total'                  => 'Sor összesen',
+  'Link'                        => 'Kapcsolat',
+  'Link Accounts'               => 'Számlakapcsolatok',
+  'List Accounts'               => 'Számlák listázása',
+  'List GIFI'                   => 'Gyûjtõkódok listázása',
+  'List Price'                  => 'Listaár',
+  'List Transactions'           => 'Tranzakciók listázása',
+  'Login'                       => 'Belépés',
+  'Logout'                      => 'Kilépés',
+  'Make'                        => 'Gyártmány',
+  'Mar'                         => 'Márc.',
+  'March'                       => 'Március',
+  'May'                         => 'Máj.',
+  'May '                        => 'Május',
+  'Message'                     => 'Üzenet',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Modell',
+  'Multibyte Encoding'          => 'Multibyte kódolás',
+  'N/A'                         => 'N/A',
+  'Name'                        => 'Név',
+  'Name missing!'               => 'Név hiányzik',
+  'New Templates'               => 'Új sablonok',
+  'No'                          => 'Nem',
+  'No Database Drivers available!' => 'Nincs elérhetõ adatbázismeghajtó!',
+  'No Dataset selected!'        => 'Nincs kiválasztott cégadatbázis!',
+  'No email address for'        => 'Nincs e-mail címe:',
+  'No.'                         => 'Sz.',
+  'Notes'                       => 'Megjegyzés',
+  'Nothing applied!'            => 'Nincs semmi kitöltve!',
+  'Nothing selected!'           => 'Nincs semmi kiválasztva!',
+  'Nothing to delete!'          => 'Nincs mit törölni!',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'November',
+  'Number'                      => 'Szám',
+  'Number Format'               => 'Számformátum',
+  'Number missing in Row'       => 'Ebbõl a sorból hiányzik a szám:',
+  'O'                           => 'Ny.',
+  'Obsolete'                    => 'Elévült',
+  'Oct'                         => 'Okt.',
+  'October'                     => 'Október',
+  'On Hand'                     => 'Készleten',
+  'On Order'                    => 'Beszerzési rendelések',
+  'Open'                        => 'Nyitott',
+  'Oracle Database Administration' => 'Oracle adatbázis felügyelet',
+  'Order'                       => 'Rendelés',
+  'Order Date'                  => 'Rendelés dátuma',
+  'Order Date missing!'         => 'Rendelés dátuma hiányzik!',
+  'Order Entry'                 => 'Rendelések',
+  'Order Number'                => 'Rendelés száma',
+  'Order Number missing!'       => 'Rendelés száma hiányzik!',
+  'Order deleted!'              => 'Rendelés törölve!',
+  'Order saved!'                => 'Rendelés elmentve!',
+  'Ordered'                     => 'Vevõrendelések',
+  'Orphaned'                    => 'Tranzakció nélküli',
+  'Out of balance!'             => 'Az egyenleg nem stimmel!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Szállítólevél',
+  'Packing List Date missing!'  => 'Szállítólevél dátuma hiányzik!',
+  'Packing List Number missing!' => 'Szállítólevél száma hiányzik!',
+  'Paid'                        => 'Fizetve',
+  'Paid in full'                => 'Teljesen fizetve',
+  'Part'                        => 'Cikk',
+  'Part Number missing!'        => 'Cikk száma hiányzik!',
+  'Parts'                       => 'Cikkek',
+  'Parts Inventory'             => 'Cikkek készlete',
+  'Password'                    => 'Jelszó',
+  'Password changed!'           => 'Jelszó megváltozott!',
+  'Payables'                    => 'Szállítók',
+  'Payment'                     => 'Kifizetés',
+  'Payment date missing!'       => 'Pénzmozgás dátuma hiányzik!',
+  'Payment posted!'             => 'Pénzmozgás rögzítve',
+  'Payments'                    => 'Kifizetések',
+  'Pg Database Administration'  => 'Postgresql adatbázis felügyelet',
+  'Phone'                       => 'Telefon',
+  'Port'                        => 'Port száma',
+  'Port missing!'               => 'Port száma  hiányzik!',
+  'Post'                        => 'Rögzítés',
+  'Post as new'                 => 'Rögzítés új tranzakcióként',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Beállítások',
+  'Preferences saved!'          => 'Beállítások elmentve!',
+  'Price'                       => 'Ár',
+  'Print'                       => 'Nyomtatás',
+  'Printer'                     => 'Nyomtató',
+  'Project'                     => 'Munkaszám',
+  'Project Number'              => 'Munkaszám',
+  'Project Number missing!'     => 'Munkaszám száma hiányzik!',
+  'Project deleted!'            => 'Munkaszám törölve!',
+  'Project not on file!'        => 'Munkaszám hiányzik az adatbázisból!',
+  'Project saved!'              => 'Munkaszám elmentve!',
+  'Projects'                    => 'Munkaszámok',
+  'Purchase Order'              => 'Beszerzési rendelés',
+  'Purchase Orders'             => 'Beszerzési rendelések',
+  'Qty'                         => 'Menny.',
+  'ROP'                         => 'Rendelési pont',
+  'Rate'                        => 'Árfolyam',
+  'Recd'                        => 'Kapott',
+  'Receipt'                     => 'Bevétel',
+  'Receipt printed!'            => 'Nyugta nyomtatva!',
+  'Receipt printing failed!'    => 'A nyugta nyomtatása nem sikerült!',
+  'Receipts'                    => 'Bevételek',
+  'Receivables'                 => 'Vevõk',
+  'Reconciliation'              => 'Egyeztetés',
+  'Record in'                   => 'Feladás:',
+  'Reference'                   => 'Hivatkozás',
+  'Reference missing!'          => 'Hivatkozás hiányzik',
+  'Remaining'                   => 'Maradék',
+  'Report for'                  => 'Jelentés:',
+  'Reports'                     => 'Jelentések',
+  'Required by'                 => 'Leszállítás',
+  'Retained Earnings'           => 'Adózás elõtti eredmény',
+  'Sales'                       => 'Eladás',
+  'Sales Invoice'               => 'Számlázás',
+  'Sales Order'                 => 'Vevõrendelés',
+  'Sales Orders'                => 'Vevõrendelések',
+  'Salesperson'                 => '',
+  'Save'                        => 'Mentés',
+  'Save as new'                 => 'Mentés újként',
+  'Save to File'                => 'Másolat File-ba',
+  'Screen'                      => 'Képernyõre',
+  'Select a Dataset to delete and press "Continue"' => 'Válassza ki a törölni kívánt cégadatbázist, és klikkeljen a "Folytatás"-ra',
+  'Select all'                  => 'Mindent kijelöl',
+  'Select from one of the items below' => 'Válasszon ki egyet az alábbi tételek közül',
+  'Select from one of the names below' => 'Válasszon ki egyet az alábbi nevek közül',
+  'Select from one of the projects below' => 'Válasszon ki egyet az alábbi munkaszámok közül',
+  'Select postscript or PDF!'   => 'Válassza ki a postscript vagy a PDF formátumot!',
+  'Sell Price'                  => 'Eladási ár',
+  'Send by E-Mail'              => 'Másolat E-mail-ben',
+  'Sep'                         => 'Szept.',
+  'September'                   => 'Szeptember',
+  'Service'                     => 'Szolgáltatás',
+  'Service Items'               => 'Szolgáltatás tételek',
+  'Service Number missing!'     => 'Szolgáltatás száma hiányzik!',
+  'Services'                    => 'Szolgáltatások',
+  'Setup Templates'             => 'Sablonok beállítása',
+  'Ship'                        => 'Szállítás',
+  'Ship to'                     => 'Szállítási cím',
+  'Ship via'                    => 'Szállítás innen:',
+  'Short'                       => 'Hiányzó',
+  'Signature'                   => 'Aláírás',
+  'Sold'                        => 'Eladva',
+  'Source'                      => 'Bizonylatszám',
+  'Standard'                    => 'Sztenderd',
+  'Statement'                   => 'Kimutatás',
+  'Statement Balance'           => 'Kimutatás egyenlege',
+  'Statement sent to'           => 'Kimutatás elküldve:',
+  'Statements sent to printer!' => 'Kimutatás kinyomtatva!',
+  'Stock'                       => '',
+  'Stock Assembly'              => 'Saját termék bevételezése',
+  'Stylesheet'                  => 'Stíluslap',
+  'Subject'                     => 'Tárgy',
+  'Subtotal'                    => 'Részösszeg',
+  'System'                      => 'Törzsadatok',
+  'Tax'                         => 'Adó',
+  'Tax Accounts'                => 'Adószámlák',
+  'Tax Included'                => 'Adót tartalmazza',
+  'Tax collected'               => 'Fizetendõ ÁFA',
+  'Tax paid'                    => 'Levonható ÁFA',
+  'Taxable'                     => 'Adó:',
+  'Template saved!'             => 'Sablon elmentve!',
+  'Templates'                   => 'Sablonok',
+  'Terms: Net'                  => 'Határidõ',
+  'The following Datasets are not in use and can be deleted' => 'Az alábbi cégadatbázisok üresek, és törölhetõk',
+  'The following Datasets need to be updated' => 'Az alábbi cégadatbázisokat frissíteni kell',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'A meglévõ adatbázisok elõzetes ellenõrzése. A program itt még nem töröl és nem hoz létre semmit!',
+  'To'                          => 'Meddig:',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Új felhasználót úgy hozhat létre egy meglévõ cégadatbázishoz, hogy egy létezõ felhasználóra kattint, és a belépési nevet és a jelszót megváltoztatja és elmenti. Az új felhasználó örökli a beállításokat.',
+  'Top Level'                   => 'Legfelsõ szint',
+  'Total'                       => 'Végösszeg',
+  'Transaction Date missing!'   => 'Tranzakció dátuma hiányzik!',
+  'Transaction deleted!'        => 'Tranzakció törölve!',
+  'Transaction posted!'         => 'Tranzakció rögzítve!',
+  'Transaction reversal enforced for all dates' => 'Bármilyen dátumú tranzakciót visszautasít',
+  'Transaction reversal enforced up to' => 'E dátumig utasítja vissza a tranzakciókat',
+  'Transactions'                => 'Tranzakciók',
+  'Transactions exist, cannot delete customer!' => 'A vevõhöz tranzakciók tartoznak, nem lehet törölni!',
+  'Transactions exist, cannot delete vendor!' => 'A szállítóhoz tranzakciók tartoznak, nem lehet törölni!',
+  'Transactions exist; cannot delete account!' => 'A számlához tranzakciók tartoznak, nem lehet törölni!',
+  'Trial Balance'               => 'Fõkönyvi kivonat',
+  'Unit'                        => 'Egység',
+  'Unit of measure'             => 'Mértékegység',
+  'Update'                      => 'Frissítés',
+  'Update Dataset'              => 'Cégadatbázis frissítése',
+  'Updated'                     => 'Frissítve',
+  'Use Templates'               => 'Sablon használata',
+  'User'                        => 'Felhasználó',
+  'User deleted!'               => 'Felhasználó törölve!',
+  'User saved!'                 => 'Felhasználó elmentve!',
+  'Vendor'                      => 'Szállító',
+  'Vendor Invoice'              => '',
+  'Vendor deleted!'             => 'Szállító törölve!',
+  'Vendor missing!'             => 'Szállító hiányzik!',
+  'Vendor not on file!'         => 'Szállító nincs az adatbázisban!',
+  'Vendor saved!'               => 'Szállító elmentve!',
+  'Vendors'                     => 'Szállítók',
+  'Version'                     => 'Verzió',
+  'Weight'                      => 'Súly',
+  'Weight Unit'                 => 'Súlyegység',
+  'What type of item is this?'  => 'Ez milyen típusú tétel?',
+  'Year End'                    => 'Évzárás',
+  'Yes'                         => 'Igen',
+  'You are logged out!'         => 'Már kijelentkezett!',
+  'You did not enter a name!'   => 'Nem írt be nevet!',
+  'You must enter a host and port for local and remote connections!' => 'A helyi és távoli kapcsolat eléréséhez írjon be helyet, és portszámot!',
+  'as at'                       => 'Fordulónap:',
+  'collected on sales'          => 'vevõszámlák alapján',
+  'days'                        => 'nap',
+  'does not exist'              => 'nem létezik',
+  'ea'                          => 'db',
+  'emailed to'                  => 'e-mail küldve:',
+  'for Period'                  => 'Idõszak:',
+  'hr'                          => 'óra',
+  'is already a member!'        => 'már tag!',
+  'is not a member!'            => 'nem tag!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'zárolva',
+  'paid on purchases'           => 'szállítószámlák alapján',
+  'sent to printer'             => 'kinyomtatva',
+  'successfully created!'       => 'sikeresen létrehozva!',
+  'successfully deleted!'       => 'sikeresen törölve!',
+  'to'                          => 'Meddig:',
+  'website'                     => 'honlap',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/am b/sql-ledger/locale/hu/am
new file mode 100644 (file)
index 0000000..0bb2b83
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Szállítók',
+  'AR'                          => 'Vevõk',
+  'Account'                     => 'Számla',
+  'Account Number'              => 'Számlaszám',
+  'Account Number missing!'     => 'Számlaszám hiányzik!',
+  'Account Type'                => 'Számlatípus',
+  'Account Type missing!'       => 'Számlatípus hiányzik!',
+  'Account deleted!'            => 'Számla törölve!',
+  'Account saved!'              => 'Számla elmentve!',
+  'Add Account'                 => 'Új számla',
+  'Add GIFI'                    => 'Új gyûjtõkód',
+  'Address'                     => 'Cím',
+  'Asset'                       => 'Eszköz',
+  'Audit Control'               => 'Audit Kontroll',
+  'Backup sent to'              => 'Biztonsági másolat elküldve:',
+  'Books are open'              => 'Az ügyféladatbázisban lehet könyvelni',
+  'Business Number'             => 'Cégszám',
+  'COGS'                        => 'ELÁBÉ',
+  'Cannot delete account!'      => 'A számlát nem lehet törölni',
+  'Cannot delete default account!' => 'Az alapbeállítású számlát nem lehet törölni!',
+  'Cannot save account!'        => 'A számlát nem lehet elmenteni!',
+  'Cannot save preferences!'    => 'A beállításokat nem lehet elmenteni',
+  'Character Set'               => 'Betû kódlap',
+  'Chart of Accounts'           => 'Számlatükör',
+  'Close Books up to'           => 'Könyvelés lezárása eddig az idõpontig:',
+  'Company'                     => 'Társaság',
+  'Continue'                    => 'Folytatás',
+  'Copy to COA'                 => 'Másolás a számlatükörbe',
+  'Credit'                      => 'Követel',
+  'Date Format'                 => 'Dátumformátum',
+  'Debit'                       => 'Tartozik',
+  'Delete'                      => 'Törlés',
+  'Delete Account'              => 'Számla törlése',
+  'Description'                 => 'Szöveges leírás',
+  'Dropdown Limit'              => 'Lenyíló ablak limit',
+  'E-mail'                      => 'E-mail',
+  'Edit'                        => 'Módosítás',
+  'Edit Account'                => 'Számlaszám módosítása',
+  'Edit GIFI'                   => 'Gyûjtõkód módosítása',
+  'Edit Preferences for'        => 'Felhasználói paraméterek módosítása:',
+  'Edit Template'               => 'Sablon módosítása',
+  'Enforce transaction reversal for all dates' => 'Minden dátum esetében visszautasítsa a tranzakció rögzítését?',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'A saját és külföldi devizákat jelölje 3 betûvel kettõsponttal elválasztva! (pl. HUF:EUR:USD)',
+  'Equity'                      => 'Tõke',
+  'Expense'                     => 'Költség',
+  'Expense Account'             => 'Költségszámla',
+  'Expense/Asset'               => 'Költség/Eszköz',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Árfolyamnyereség',
+  'Foreign Exchange Loss'       => 'Árfolyamveszteség',
+  'GIFI'                        => 'Gyûjtõkód',
+  'GIFI deleted!'               => 'Gyûjtõkód törölve!',
+  'GIFI missing!'               => 'Gyûjtõkód hiányzik!',
+  'GIFI saved!'                 => 'Gyûjtõkód elmentve!',
+  'Heading'                     => 'Fejléc',
+  'Include in drop-down menus'  => 'Mely tranzakció(k)-nál lehessen kiválasztani?:',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Kiválasztható legyen a vevõ/szállító ûrlapokon, mint adószámla?',
+  'Income'                      => 'Árbevétel',
+  'Income Account'              => 'Árbevételszámla',
+  'Inventory'                   => 'Készlet',
+  'Inventory Account'           => 'Készletszámla',
+  'Is this a summary account to record' => 'Gyûjtõszámlaként szerepeljen ezeknél a tranzakcióknál:',
+  'Language'                    => 'Nyelv',
+  'Last Invoice Number'         => 'Utolsó számlaszám',
+  'Last Numbers & Default Accounts' => 'Legutolsó számok & Alapszámlák',
+  'Last Purchase Order Number'  => 'Utolsó beszerzési rendelésszám',
+  'Last Sales Order Number'     => 'Utolsó vevõ rendelésszám',
+  'Liability'                   => 'Kötelezettség',
+  'Link'                        => 'Kapcsolat',
+  'Name'                        => 'Név',
+  'No'                          => 'Nem',
+  'No email address for'        => 'Nincs e-mail címe:',
+  'Number'                      => 'Szám',
+  'Number Format'               => 'Számformátum',
+  'Parts Inventory'             => 'Cikkek készlete',
+  'Password'                    => 'Jelszó',
+  'Payables'                    => 'Szállítók',
+  'Payment'                     => 'Kifizetés',
+  'Phone'                       => 'Telefon',
+  'Preferences saved!'          => 'Beállítások elmentve!',
+  'Rate'                        => 'Árfolyam',
+  'Receivables'                 => 'Vevõk',
+  'Sales'                       => 'Eladás',
+  'Save'                        => 'Mentés',
+  'Service Items'               => 'Szolgáltatás tételek',
+  'Ship via'                    => 'Szállítás innen:',
+  'Signature'                   => 'Aláírás',
+  'Stylesheet'                  => 'Stíluslap',
+  'Tax'                         => 'Adó',
+  'Tax Accounts'                => 'Adószámlák',
+  'Template saved!'             => 'Sablon elmentve!',
+  'Transaction reversal enforced for all dates' => 'Bármilyen dátumú tranzakciót visszautasít',
+  'Transaction reversal enforced up to' => 'E dátumig utasítja vissza a tranzakciókat',
+  'Transactions exist; cannot delete account!' => 'A számlához tranzakciók tartoznak, nem lehet törölni!',
+  'Weight Unit'                 => 'Súlyegység',
+  'Year End'                    => 'Évzárás',
+  'Yes'                         => 'Igen',
+  'does not exist'              => 'nem létezik',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'Új_számla'                   => 'add_account',
+  'folytatás'                   => 'continue',
+  'másolás_a_számlatükörbe'     => 'copy_to_coa',
+  'törlés'                      => 'delete',
+  'módosítás'                   => 'edit',
+  'számlaszám_módosítása'       => 'edit_account',
+  'mentés'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/ap b/sql-ledger/locale/hu/ap
new file mode 100644 (file)
index 0000000..e39bd70
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Szállító tranzakció',
+  'AP Transactions'             => 'Szállító tranzakciók',
+  'Account'                     => 'Számla',
+  'Add Accounts Payables Transaction' => 'Új szállító tranzakció',
+  'Address'                     => 'Cím',
+  'Amount'                      => 'Összeg',
+  'Amount Due'                  => 'Esedékes összeg',
+  'Apr'                         => 'Ápr.',
+  'April'                       => 'Április',
+  'Are you sure you want to delete Transaction' => 'Biztos, hogy törölni akarja? Tranzakció:',
+  'Aug'                         => 'Aug.',
+  'August'                      => 'Augusztus',
+  'Cannot delete transaction!'  => 'A tranzakciót nem lehet törölni!',
+  'Cannot post payment for a closed period!' => 'A lezárt idõszakban nem lehet fizetést rögzíteni!',
+  'Cannot post transaction for a closed period!' => 'A lezárt idõszakban nem lehet tranzakciót rögzíteni!!',
+  'Cannot post transaction!'    => 'A tranzakciót nem lehet rögzíteni!',
+  'Closed'                      => 'Lezárt',
+  'Confirm!'                    => 'Megerõsítés:',
+  'Continue'                    => 'Folytatás',
+  'Currency'                    => 'Deviza',
+  'Customer not on file!'       => 'A vevõ hiányzik az adatbázisból!',
+  'Date'                        => 'Dátum',
+  'Date Paid'                   => 'Fizetés napja',
+  'Dec'                         => 'Dec.',
+  'December'                    => 'December',
+  'Delete'                      => 'Törlés',
+  'Description'                 => 'Szöveges leírás',
+  'Due Date'                    => 'Esedékesség',
+  'Due Date missing!'           => 'Esedékesség hiányzik!',
+  'Edit Accounts Payables Transaction' => 'Szállító tranzakció módosítása',
+  'Employee'                    => 'Alkalmazott',
+  'Exch'                        => 'Árf',
+  'Exchangerate'                => 'Átváltási árfolyam',
+  'Exchangerate for payment missing!' => 'A fizetett összeg átváltási árfolyama hiányzik!',
+  'Exchangerate missing!'       => 'Átváltási árfolyam hiányzik!',
+  'Feb'                         => 'Feb.',
+  'February'                    => 'Február',
+  'From'                        => 'Mikortól:',
+  'ID'                          => 'Azonosító',
+  'Include in Report'           => 'Oszlopok:',
+  'Invoice'                     => 'Számla',
+  'Invoice Date'                => 'Teljesítés dátuma',
+  'Invoice Date missing!'       => 'Teljesítés dátuma hiányzik!',
+  'Invoice Number'              => 'Számlaszám',
+  'Invoice Number missing!'     => 'Számlaszám hiányzik!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Január',
+  'Jul'                         => 'Júl.',
+  'July'                        => 'Július',
+  'Jun'                         => 'Jún.',
+  'June'                        => 'Június',
+  'Mar'                         => 'Márc.',
+  'March'                       => 'Március',
+  'May'                         => 'Máj.',
+  'May '                        => 'Május',
+  'Notes'                       => 'Megjegyzés',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'November',
+  'Number'                      => 'Szám',
+  'Oct'                         => 'Okt.',
+  'October'                     => 'Október',
+  'Open'                        => 'Nyitott',
+  'Order'                       => 'Rendelés',
+  'Order Number'                => 'Rendelés száma',
+  'Paid'                        => 'Fizetve',
+  'Payment date missing!'       => 'Pénzmozgás dátuma hiányzik!',
+  'Payments'                    => 'Kifizetések',
+  'Post'                        => 'Rögzítés',
+  'Post as new'                 => 'Rögzítés új tranzakcióként',
+  'Project'                     => 'Munkaszám',
+  'Project not on file!'        => 'Munkaszám hiányzik az adatbázisból!',
+  'Select from one of the names below' => 'Válasszon ki egyet az alábbi nevek közül',
+  'Select from one of the projects below' => 'Válasszon ki egyet az alábbi munkaszámok közül',
+  'Sep'                         => 'Szept.',
+  'September'                   => 'Szeptember',
+  'Source'                      => 'Bizonylatszám',
+  'Subtotal'                    => 'Részösszeg',
+  'Tax'                         => 'Adó',
+  'Tax Included'                => 'Adót tartalmazza',
+  'Total'                       => 'Végösszeg',
+  'Transaction deleted!'        => 'Tranzakció törölve!',
+  'Transaction posted!'         => 'Tranzakció rögzítve!',
+  'Update'                      => 'Frissítés',
+  'Vendor'                      => 'Szállító',
+  'Vendor Invoice'              => 'Vendor Invoice',
+  'Vendor missing!'             => 'Szállító hiányzik!',
+  'Vendor not on file!'         => 'Szállító nincs az adatbázisban!',
+  'Yes'                         => 'Igen',
+  'to'                          => 'Meddig:',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'szállító_tranzakció'         => 'ap_transaction',
+  'Új_szállító_tranzakció'      => 'add_accounts_payables_transaction',
+  'folytatás'                   => 'continue',
+  'törlés'                      => 'delete',
+  'szállító_tranzakció_módosítása' => 'edit_accounts_payables_transaction',
+  'rögzítés'                    => 'post',
+  'rögzítés_új_tranzakcióként'  => 'post_as_new',
+  'frissítés'                   => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'igen'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/ar b/sql-ledger/locale/hu/ar
new file mode 100644 (file)
index 0000000..2243070
--- /dev/null
@@ -0,0 +1,134 @@
+$self{texts} = {
+  'AR Transaction'              => 'Vevõ tranzakció',
+  'AR Transactions'             => 'Vevõ tranzakciók',
+  'Account'                     => 'Számla',
+  'Add Accounts Receivables Transaction' => 'Új vevõ tranzakció',
+  'Address'                     => 'Cím',
+  'Amount'                      => 'Összeg',
+  'Amount Due'                  => 'Esedékes összeg',
+  'Apr'                         => 'Ápr.',
+  'April'                       => 'Április',
+  'Are you sure you want to delete Transaction' => 'Biztos, hogy törölni akarja? Tranzakció:',
+  'Aug'                         => 'Aug.',
+  'August'                      => 'Augusztus',
+  'Cannot delete transaction!'  => 'A tranzakciót nem lehet törölni!',
+  'Cannot post payment for a closed period!' => 'A lezárt idõszakban nem lehet fizetést rögzíteni!',
+  'Cannot post transaction for a closed period!' => 'A lezárt idõszakban nem lehet tranzakciót rögzíteni!!',
+  'Cannot post transaction!'    => 'A tranzakciót nem lehet rögzíteni!',
+  'Closed'                      => 'Lezárt',
+  'Confirm!'                    => 'Megerõsítés:',
+  'Continue'                    => 'Folytatás',
+  'Credit Limit'                => 'Hitelkeret',
+  'Currency'                    => 'Deviza',
+  'Customer'                    => 'Vevõ',
+  'Customer missing!'           => 'Vevõ hiányzik!',
+  'Customer not on file!'       => 'A vevõ hiányzik az adatbázisból!',
+  'Date'                        => 'Dátum',
+  'Date Paid'                   => 'Fizetés napja',
+  'Dec'                         => 'Dec.',
+  'December'                    => 'December',
+  'Delete'                      => 'Törlés',
+  'Description'                 => 'Szöveges leírás',
+  'Due Date'                    => 'Esedékesség',
+  'Due Date missing!'           => 'Esedékesség hiányzik!',
+  'Edit Accounts Receivables Transaction' => 'Vevõ tranzakció módosítása',
+  'Exch'                        => 'Árf',
+  'Exchangerate'                => 'Átváltási árfolyam',
+  'Exchangerate for payment missing!' => 'A fizetett összeg átváltási árfolyama hiányzik!',
+  'Exchangerate missing!'       => 'Átváltási árfolyam hiányzik!',
+  'Feb'                         => 'Feb.',
+  'February'                    => 'Február',
+  'From'                        => 'Mikortól:',
+  'ID'                          => 'Azonosító',
+  'Include in Report'           => 'Oszlopok:',
+  'Invoice'                     => 'Számla',
+  'Invoice Date'                => 'Teljesítés dátuma',
+  'Invoice Date missing!'       => 'Teljesítés dátuma hiányzik!',
+  'Invoice Number'              => 'Számlaszám',
+  'Invoice Number missing!'     => 'Számlaszám hiányzik!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Január',
+  'Jul'                         => 'Júl.',
+  'July'                        => 'Július',
+  'Jun'                         => 'Jún.',
+  'June'                        => 'Június',
+  'Mar'                         => 'Márc.',
+  'March'                       => 'Március',
+  'May'                         => 'Máj.',
+  'May '                        => 'Május',
+  'Notes'                       => 'Megjegyzés',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'November',
+  'Number'                      => 'Szám',
+  'Oct'                         => 'Okt.',
+  'October'                     => 'Október',
+  'Open'                        => 'Nyitott',
+  'Order'                       => 'Rendelés',
+  'Order Number'                => 'Rendelés száma',
+  'Paid'                        => 'Fizetve',
+  'Payment date missing!'       => 'Pénzmozgás dátuma hiányzik!',
+  'Payments'                    => 'Kifizetések',
+  'Post'                        => 'Rögzítés',
+  'Post as new'                 => 'Rögzítés új tranzakcióként',
+  'Project'                     => 'Munkaszám',
+  'Project not on file!'        => 'Munkaszám hiányzik az adatbázisból!',
+  'Remaining'                   => 'Maradék',
+  'Sales Invoice'               => 'Számlázás',
+  'Salesperson'                 => 'Salesperson',
+  'Select from one of the names below' => 'Válasszon ki egyet az alábbi nevek közül',
+  'Select from one of the projects below' => 'Válasszon ki egyet az alábbi munkaszámok közül',
+  'Sep'                         => 'Szept.',
+  'September'                   => 'Szeptember',
+  'Ship via'                    => 'Szállítás innen:',
+  'Source'                      => 'Bizonylatszám',
+  'Subtotal'                    => 'Részösszeg',
+  'Tax'                         => 'Adó',
+  'Tax Included'                => 'Adót tartalmazza',
+  'Total'                       => 'Végösszeg',
+  'Transaction deleted!'        => 'Tranzakció törölve!',
+  'Transaction posted!'         => 'Tranzakció rögzítve!',
+  'Update'                      => 'Frissítés',
+  'Vendor not on file!'         => 'Szállító nincs az adatbázisban!',
+  'Yes'                         => 'Igen',
+  'to'                          => 'Meddig:',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'vevõ_tranzakció'             => 'ar_transaction',
+  'folytatás'                   => 'continue',
+  'törlés'                      => 'delete',
+  'rögzítés'                    => 'post',
+  'rögzítés_új_tranzakcióként'  => 'post_as_new',
+  'számlázás'                   => 'sales_invoice',
+  'frissítés'                   => 'update',
+  'igen'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/arap b/sql-ledger/locale/hu/arap
new file mode 100644 (file)
index 0000000..9809e35
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Cím',
+  'Continue'                    => 'Folytatás',
+  'Customer not on file!'       => 'A vevõ hiányzik az adatbázisból!',
+  'Description'                 => 'Szöveges leírás',
+  'Number'                      => 'Szám',
+  'Project not on file!'        => 'Munkaszám hiányzik az adatbázisból!',
+  'Select from one of the names below' => 'Válasszon ki egyet az alábbi nevek közül',
+  'Select from one of the projects below' => 'Válasszon ki egyet az alábbi munkaszámok közül',
+  'Vendor not on file!'         => 'Szállító nincs az adatbázisban!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'vendor_invoice'              => 'vendor_invoice',
+  'folytatás'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/ca b/sql-ledger/locale/hu/ca
new file mode 100644 (file)
index 0000000..df4726c
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Számla',
+  'Apr'                         => 'Ápr.',
+  'April'                       => 'Április',
+  'Aug'                         => 'Aug.',
+  'August'                      => 'Augusztus',
+  'Balance'                     => 'Egyenleg',
+  'Chart of Accounts'           => 'Számlatükör',
+  'Credit'                      => 'Követel',
+  'Date'                        => 'Dátum',
+  'Debit'                       => 'Tartozik',
+  'Dec'                         => 'Dec.',
+  'December'                    => 'December',
+  'Description'                 => 'Szöveges leírás',
+  'Feb'                         => 'Feb.',
+  'February'                    => 'Február',
+  'From'                        => 'Mikortól:',
+  'GIFI'                        => 'Gyûjtõkód',
+  'Include in Report'           => 'Oszlopok:',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Január',
+  'Jul'                         => 'Júl.',
+  'July'                        => 'Július',
+  'Jun'                         => 'Jún.',
+  'June'                        => 'Június',
+  'List Transactions'           => 'Tranzakciók listázása',
+  'Mar'                         => 'Márc.',
+  'March'                       => 'Március',
+  'May'                         => 'Máj.',
+  'May '                        => 'Május',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'November',
+  'Oct'                         => 'Okt.',
+  'October'                     => 'Október',
+  'Reference'                   => 'Hivatkozás',
+  'Sep'                         => 'Szept.',
+  'September'                   => 'Szeptember',
+  'Subtotal'                    => 'Részösszeg',
+  'to'                          => 'Meddig:',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'tranzakciók_listázása'       => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/cp b/sql-ledger/locale/hu/cp
new file mode 100644 (file)
index 0000000..2a2b09a
--- /dev/null
@@ -0,0 +1,77 @@
+$self{texts} = {
+  'Account'                     => 'Számla',
+  'Address'                     => 'Cím',
+  'Amount'                      => 'Összeg',
+  'Amount does not equal applied!' => 'Az összeg nem egyezik a kitöltött szám(ok) összegével',
+  'Amount missing!'             => 'Összeg hiányzik!',
+  'Applied'                     => 'Kitöltés',
+  'Cannot post payment!'        => 'A pénzmozgást nem lehet rögzíteni',
+  'Cannot process payment for a closed period!' => 'A pénzmozgást nem lehet lezárt idõszakban rögzíteni!',
+  'Check'                       => 'Csekk',
+  'Check printed!'              => 'Csekk kinyomtatva!',
+  'Check printing failed!'      => 'A csekk nyomtatása nem sikerült!',
+  'Continue'                    => 'Folytatás',
+  'Currency'                    => 'Deviza',
+  'Customer'                    => 'Vevõ',
+  'Customer not on file!'       => 'A vevõ hiányzik az adatbázisból!',
+  'Date'                        => 'Dátum',
+  'Date missing!'               => 'Dátum hiányzik',
+  'Description'                 => 'Szöveges leírás',
+  'Due'                         => 'Esedékes',
+  'Exchangerate'                => 'Átváltási árfolyam',
+  'From'                        => 'Mikortól:',
+  'Invoice'                     => 'Számla',
+  'Invoices'                    => 'Számlák',
+  'Nothing applied!'            => 'Nincs semmi kitöltve!',
+  'Number'                      => 'Szám',
+  'Paid in full'                => 'Teljesen fizetve',
+  'Payment'                     => 'Kifizetés',
+  'Payment posted!'             => 'Pénzmozgás rögzítve',
+  'Post'                        => 'Rögzítés',
+  'Print'                       => 'Nyomtatás',
+  'Printer'                     => 'Nyomtató',
+  'Project not on file!'        => 'Munkaszám hiányzik az adatbázisból!',
+  'Receipt'                     => 'Bevétel',
+  'Receipt printed!'            => 'Nyugta nyomtatva!',
+  'Receipt printing failed!'    => 'A nyugta nyomtatása nem sikerült!',
+  'Reference'                   => 'Hivatkozás',
+  'Screen'                      => 'Képernyõre',
+  'Select from one of the names below' => 'Válasszon ki egyet az alábbi nevek közül',
+  'Select from one of the projects below' => 'Válasszon ki egyet az alábbi munkaszámok közül',
+  'Update'                      => 'Frissítés',
+  'Vendor'                      => 'Szállító',
+  'Vendor not on file!'         => 'Szállító nincs az adatbázisban!',
+  'to'                          => 'Meddig:',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'folytatás'                   => 'continue',
+  'rögzítés'                    => 'post',
+  'nyomtatás'                   => 'print',
+  'frissítés'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/ct b/sql-ledger/locale/hu/ct
new file mode 100644 (file)
index 0000000..55680ad
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Új',
+  'Address'                     => 'Cím',
+  'All'                         => 'Összes',
+  'Bcc'                         => 'Titkos másolat',
+  'Cannot delete customer!'     => 'A vevõt nem lehet törölni!',
+  'Cannot delete vendor!'       => 'Szállítót nem lehet törölni!',
+  'Cc'                          => 'Másolat',
+  'Contact'                     => 'Kapcsolat',
+  'Continue'                    => 'Folytatás',
+  'Credit Limit'                => 'Hitelkeret',
+  'Customer deleted!'           => 'Vevõ törölve!',
+  'Customer saved!'             => 'Vevõ elmentve!',
+  'Customers'                   => 'Vevõadatok',
+  'Delete'                      => 'Törlés',
+  'Discount'                    => 'Engedmény',
+  'E-mail'                      => 'E-mail',
+  'Edit Customer'               => 'Vevõ módosítása',
+  'Edit Vendor'                 => 'Szállító módosítása',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Oszlopok:',
+  'Invoice'                     => 'Számla',
+  'Name'                        => 'Név',
+  'Name missing!'               => 'Név hiányzik',
+  'Notes'                       => 'Megjegyzés',
+  'Number'                      => 'Szám',
+  'Order'                       => 'Rendelés',
+  'Orphaned'                    => 'Tranzakció nélküli',
+  'Phone'                       => 'Telefon',
+  'Save'                        => 'Mentés',
+  'Ship to'                     => 'Szállítási cím',
+  'Tax Included'                => 'Adót tartalmazza',
+  'Taxable'                     => 'Adó:',
+  'Terms: Net'                  => 'Határidõ',
+  'Transactions exist, cannot delete customer!' => 'A vevõhöz tranzakciók tartoznak, nem lehet törölni!',
+  'Transactions exist, cannot delete vendor!' => 'A szállítóhoz tranzakciók tartoznak, nem lehet törölni!',
+  'Vendor deleted!'             => 'Szállító törölve!',
+  'Vendor saved!'               => 'Szállító elmentve!',
+  'Vendors'                     => 'Szállítók',
+  'days'                        => 'nap',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'Új'                          => 'add',
+  'folytatás'                   => 'continue',
+  'törlés'                      => 'delete',
+  'számla'                      => 'invoice',
+  'rendelés'                    => 'order',
+  'mentés'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/gl b/sql-ledger/locale/hu/gl
new file mode 100644 (file)
index 0000000..f62d538
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Szállító tranzakció',
+  'AR Transaction'              => 'Vevõ tranzakció',
+  'Account'                     => 'Számla',
+  'Add General Ledger Transaction' => 'Új fõkönyvi könyvelés',
+  'Address'                     => 'Cím',
+  'All'                         => 'Összes',
+  'Apr'                         => 'Ápr.',
+  'April'                       => 'Április',
+  'Are you sure you want to delete Transaction' => 'Biztos, hogy törölni akarja? Tranzakció:',
+  'Asset'                       => 'Eszköz',
+  'Aug'                         => 'Aug.',
+  'August'                      => 'Augusztus',
+  'Balance'                     => 'Egyenleg',
+  'Cannot delete transaction!'  => 'A tranzakciót nem lehet törölni!',
+  'Cannot have a value in both Debit and Credit!' => 'A Tartozik és Követel oldal is tartalmaz értéket!',
+  'Cannot post a transaction without a value!' => 'Az összeg megadása nélkül nem lehet a tranzakciót rögzíteni!',
+  'Cannot post transaction for a closed period!' => 'A lezárt idõszakban nem lehet tranzakciót rögzíteni!!',
+  'Confirm!'                    => 'Megerõsítés:',
+  'Continue'                    => 'Folytatás',
+  'Credit'                      => 'Követel',
+  'Customer not on file!'       => 'A vevõ hiányzik az adatbázisból!',
+  'Date'                        => 'Dátum',
+  'Debit'                       => 'Tartozik',
+  'Debit and credit out of balance!' => 'Tartozik Követel összege nem egyezik!',
+  'Dec'                         => 'Dec.',
+  'December'                    => 'December',
+  'Delete'                      => 'Törlés',
+  'Description'                 => 'Szöveges leírás',
+  'Edit General Ledger Transaction' => 'Vegyes könyvelési tétel módosítása',
+  'Equity'                      => 'Tõke',
+  'Expense'                     => 'Költség',
+  'Feb'                         => 'Feb.',
+  'February'                    => 'Február',
+  'From'                        => 'Mikortól:',
+  'GIFI'                        => 'Gyûjtõkód',
+  'GL Transaction'              => 'Fõkönyvi tranzakció!',
+  'General Ledger'              => 'Fõkönyvi könyvelés',
+  'ID'                          => 'Azonosító',
+  'Include in Report'           => 'Oszlopok:',
+  'Income'                      => 'Árbevétel',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Január',
+  'Jul'                         => 'Júl.',
+  'July'                        => 'Július',
+  'Jun'                         => 'Jún.',
+  'June'                        => 'Június',
+  'Liability'                   => 'Kötelezettség',
+  'Mar'                         => 'Márc.',
+  'March'                       => 'Március',
+  'May'                         => 'Máj.',
+  'May '                        => 'Május',
+  'Notes'                       => 'Megjegyzés',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'November',
+  'Number'                      => 'Szám',
+  'Oct'                         => 'Okt.',
+  'October'                     => 'Október',
+  'Post'                        => 'Rögzítés',
+  'Post as new'                 => 'Rögzítés új tranzakcióként',
+  'Project'                     => 'Munkaszám',
+  'Project not on file!'        => 'Munkaszám hiányzik az adatbázisból!',
+  'Reference'                   => 'Hivatkozás',
+  'Reference missing!'          => 'Hivatkozás hiányzik',
+  'Reports'                     => 'Jelentések',
+  'Sales Invoice'               => 'Számlázás',
+  'Select from one of the names below' => 'Válasszon ki egyet az alábbi nevek közül',
+  'Select from one of the projects below' => 'Válasszon ki egyet az alábbi munkaszámok közül',
+  'Sep'                         => 'Szept.',
+  'September'                   => 'Szeptember',
+  'Source'                      => 'Bizonylatszám',
+  'Subtotal'                    => 'Részösszeg',
+  'Transaction Date missing!'   => 'Tranzakció dátuma hiányzik!',
+  'Transaction deleted!'        => 'Tranzakció törölve!',
+  'Transaction posted!'         => 'Tranzakció rögzítve!',
+  'Update'                      => 'Frissítés',
+  'Vendor Invoice'              => 'Vendor Invoice',
+  'Vendor not on file!'         => 'Szállító nincs az adatbázisban!',
+  'Yes'                         => 'Igen',
+  'to'                          => 'Meddig:',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'szállító_tranzakció'         => 'ap_transaction',
+  'vevõ_tranzakció'             => 'ar_transaction',
+  'folytatás'                   => 'continue',
+  'törlés'                      => 'delete',
+  'fõkönyvi_tranzakció!'        => 'gl_transaction',
+  'rögzítés'                    => 'post',
+  'rögzítés_új_tranzakcióként'  => 'post_as_new',
+  'számlázás'                   => 'sales_invoice',
+  'frissítés'                   => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'igen'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/ic b/sql-ledger/locale/hu/ic
new file mode 100644 (file)
index 0000000..768ba21
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Aktív',
+  'Add'                         => 'Új',
+  'Add Assembly'                => 'Új saját termék',
+  'Add Part'                    => 'Új cikk',
+  'Add Purchase Order'          => 'Új beszerzési rendelés',
+  'Add Sales Order'             => 'Új vevõrendelés',
+  'Add Service'                 => 'Új szolgáltatás',
+  'Address'                     => 'Cím',
+  'Apr'                         => 'Ápr.',
+  'April'                       => 'Április',
+  'Assemblies'                  => 'Saját termékek',
+  'Assemblies restocked!'       => 'Saját termékek készletre véve',
+  'Assembly Number missing!'    => 'Saját termékszám hiányzik!',
+  'Attachment'                  => 'Csatolás',
+  'Aug'                         => 'Aug.',
+  'August'                      => 'Augusztus',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Titkos másolat',
+  'Bin'                         => 'Bin',
+  'Bought'                      => 'Vásárolt',
+  'COGS'                        => 'ELÁBÉ',
+  'Cannot delete item!'         => 'A tételt nem lehet törölni!',
+  'Cannot stock assemblies!'    => 'A saját terméket nem lehet készletre venni!',
+  'Cc'                          => 'Másolat',
+  'Closed'                      => 'Lezárt',
+  'Contact'                     => 'Kapcsolat',
+  'Continue'                    => 'Folytatás',
+  'Copies'                      => 'Másolatok',
+  'Dec'                         => 'Dec.',
+  'December'                    => 'December',
+  'Delete'                      => 'Törlés',
+  'Delivery Date'               => 'Szállítás dátuma',
+  'Description'                 => 'Szöveges leírás',
+  'Drawing'                     => 'Rajz',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mail cím hiányzik!',
+  'Edit Assembly'               => 'Saját termék módosítása',
+  'Edit Part'                   => 'Cikk módosítása',
+  'Edit Service'                => 'Szolgáltatás módosítása',
+  'Expense'                     => 'Költség',
+  'Extended'                    => 'Összeg',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb.',
+  'February'                    => 'Február',
+  'From'                        => 'Mikortól:',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'Image'                       => 'Kép',
+  'In-line'                     => 'Beágyazva',
+  'Include in Report'           => 'Oszlopok:',
+  'Income'                      => 'Árbevétel',
+  'Individual Items'            => 'Összetevõk',
+  'Inventory'                   => 'Készlet',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Mielõtt ezt a saját terméket elévültnek nyilvánítja,a mennyiségnek nullának kell lennie!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Mielõtt ezt az anyagot/árut elévültnek nyilvánítja,a mennyiségnek nullának kell lennie!!',
+  'Invoice'                     => 'Számla',
+  'Invoice Date missing!'       => 'Teljesítés dátuma hiányzik!',
+  'Invoice Number'              => 'Számlaszám',
+  'Invoice Number missing!'     => 'Számlaszám hiányzik!',
+  'Item deleted!'               => 'Tétel törölve!',
+  'Item not on file!'           => 'A tétel nincs az adatbázisban!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Január',
+  'Jul'                         => 'Júl.',
+  'July'                        => 'Július',
+  'Jun'                         => 'Jún.',
+  'June'                        => 'Június',
+  'Last Cost'                   => 'Utolsó beszerzési ár',
+  'Line Total'                  => 'Sor összesen',
+  'Link Accounts'               => 'Számlakapcsolatok',
+  'List Price'                  => 'Listaár',
+  'Make'                        => 'Gyártmány',
+  'Mar'                         => 'Márc.',
+  'March'                       => 'Március',
+  'May'                         => 'Máj.',
+  'May '                        => 'Május',
+  'Message'                     => 'Üzenet',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Modell',
+  'Name'                        => 'Név',
+  'No.'                         => 'Sz.',
+  'Notes'                       => 'Megjegyzés',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'November',
+  'Number'                      => 'Szám',
+  'Number missing in Row'       => 'Ebbõl a sorból hiányzik a szám:',
+  'Obsolete'                    => 'Elévült',
+  'Oct'                         => 'Okt.',
+  'October'                     => 'Október',
+  'On Hand'                     => 'Készleten',
+  'On Order'                    => 'Beszerzési rendelések',
+  'Order'                       => 'Rendelés',
+  'Order Date missing!'         => 'Rendelés dátuma hiányzik!',
+  'Order Number'                => 'Rendelés száma',
+  'Order Number missing!'       => 'Rendelés száma hiányzik!',
+  'Ordered'                     => 'Vevõrendelések',
+  'Orphaned'                    => 'Tranzakció nélküli',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Szállítólevél',
+  'Packing List Date missing!'  => 'Szállítólevél dátuma hiányzik!',
+  'Packing List Number missing!' => 'Szállítólevél száma hiányzik!',
+  'Part'                        => 'Cikk',
+  'Part Number missing!'        => 'Cikk száma hiányzik!',
+  'Parts'                       => 'Cikkek',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Ár',
+  'Printer'                     => 'Nyomtató',
+  'Project'                     => 'Munkaszám',
+  'Purchase Order'              => 'Beszerzési rendelés',
+  'Qty'                         => 'Menny.',
+  'ROP'                         => 'Rendelési pont',
+  'Recd'                        => 'Kapott',
+  'Required by'                 => 'Leszállítás',
+  'Sales'                       => 'Eladás',
+  'Sales Order'                 => 'Vevõrendelés',
+  'Save'                        => 'Mentés',
+  'Save as new'                 => 'Mentés újként',
+  'Screen'                      => 'Képernyõre',
+  'Select from one of the items below' => 'Válasszon ki egyet az alábbi tételek közül',
+  'Select postscript or PDF!'   => 'Válassza ki a postscript vagy a PDF formátumot!',
+  'Sell Price'                  => 'Eladási ár',
+  'Sep'                         => 'Szept.',
+  'September'                   => 'Szeptember',
+  'Service'                     => 'Szolgáltatás',
+  'Service Number missing!'     => 'Szolgáltatás száma hiányzik!',
+  'Services'                    => 'Szolgáltatások',
+  'Ship'                        => 'Szállítás',
+  'Ship to'                     => 'Szállítási cím',
+  'Short'                       => 'Hiányzó',
+  'Sold'                        => 'Eladva',
+  'Stock'                       => 'Stock',
+  'Stock Assembly'              => 'Saját termék bevételezése',
+  'Subject'                     => 'Tárgy',
+  'Subtotal'                    => 'Részösszeg',
+  'Tax'                         => 'Adó',
+  'To'                          => 'Meddig:',
+  'Top Level'                   => 'Legfelsõ szint',
+  'Total'                       => 'Végösszeg',
+  'Unit'                        => 'Egység',
+  'Unit of measure'             => 'Mértékegység',
+  'Update'                      => 'Frissítés',
+  'Updated'                     => 'Frissítve',
+  'Weight'                      => 'Súly',
+  'What type of item is this?'  => 'Ez milyen típusú tétel?',
+  'ea'                          => 'db',
+  'emailed to'                  => 'e-mail küldve:',
+  'hr'                          => 'óra',
+  'sent to printer'             => 'kinyomtatva',
+  'to'                          => 'Meddig:',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'Új'                          => 'add',
+  'Új_saját_termék'             => 'add_assembly',
+  'Új_cikk'                     => 'add_part',
+  'Új_szolgáltatás'             => 'add_service',
+  'folytatás'                   => 'continue',
+  'törlés'                      => 'delete',
+  'saját_termék_módosítása'     => 'edit_assembly',
+  'cikk_módosítása'             => 'edit_part',
+  'szolgáltatás_módosítása'     => 'edit_service',
+  'mentés'                      => 'save',
+  'mentés_újként'               => 'save_as_new',
+  'frissítés'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/io b/sql-ledger/locale/hu/io
new file mode 100644 (file)
index 0000000..c30d7e9
--- /dev/null
@@ -0,0 +1,108 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Új beszerzési rendelés',
+  'Add Sales Order'             => 'Új vevõrendelés',
+  'Address'                     => 'Cím',
+  'Apr'                         => 'Ápr.',
+  'April'                       => 'Április',
+  'Attachment'                  => 'Csatolás',
+  'Aug'                         => 'Aug.',
+  'August'                      => 'Augusztus',
+  'Bcc'                         => 'Titkos másolat',
+  'Bin'                         => 'Bin',
+  'Cc'                          => 'Másolat',
+  'Contact'                     => 'Kapcsolat',
+  'Continue'                    => 'Folytatás',
+  'Copies'                      => 'Másolatok',
+  'Dec'                         => 'Dec.',
+  'December'                    => 'December',
+  'Delivery Date'               => 'Szállítás dátuma',
+  'Description'                 => 'Szöveges leírás',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mail cím hiányzik!',
+  'Extended'                    => 'Összeg',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb.',
+  'February'                    => 'Február',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'In-line'                     => 'Beágyazva',
+  'Invoice'                     => 'Számla',
+  'Invoice Date missing!'       => 'Teljesítés dátuma hiányzik!',
+  'Invoice Number missing!'     => 'Számlaszám hiányzik!',
+  'Item not on file!'           => 'A tétel nincs az adatbázisban!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Január',
+  'Jul'                         => 'Júl.',
+  'July'                        => 'Július',
+  'Jun'                         => 'Jún.',
+  'June'                        => 'Június',
+  'Mar'                         => 'Márc.',
+  'March'                       => 'Március',
+  'May'                         => 'Máj.',
+  'May '                        => 'Május',
+  'Message'                     => 'Üzenet',
+  'Name'                        => 'Név',
+  'No.'                         => 'Sz.',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'November',
+  'Number'                      => 'Szám',
+  'Number missing in Row'       => 'Ebbõl a sorból hiányzik a szám:',
+  'Oct'                         => 'Okt.',
+  'October'                     => 'Október',
+  'Order'                       => 'Rendelés',
+  'Order Date missing!'         => 'Rendelés dátuma hiányzik!',
+  'Order Number missing!'       => 'Rendelés száma hiányzik!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Szállítólevél',
+  'Packing List Date missing!'  => 'Szállítólevél dátuma hiányzik!',
+  'Packing List Number missing!' => 'Szállítólevél száma hiányzik!',
+  'Part'                        => 'Cikk',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Ár',
+  'Printer'                     => 'Nyomtató',
+  'Project'                     => 'Munkaszám',
+  'Purchase Order'              => 'Beszerzési rendelés',
+  'Qty'                         => 'Menny.',
+  'Recd'                        => 'Kapott',
+  'Required by'                 => 'Leszállítás',
+  'Sales Order'                 => 'Vevõrendelés',
+  'Screen'                      => 'Képernyõre',
+  'Select from one of the items below' => 'Válasszon ki egyet az alábbi tételek közül',
+  'Select postscript or PDF!'   => 'Válassza ki a postscript vagy a PDF formátumot!',
+  'Sep'                         => 'Szept.',
+  'September'                   => 'Szeptember',
+  'Service'                     => 'Szolgáltatás',
+  'Ship'                        => 'Szállítás',
+  'Ship to'                     => 'Szállítási cím',
+  'Subject'                     => 'Tárgy',
+  'To'                          => 'Meddig:',
+  'Unit'                        => 'Egység',
+  'What type of item is this?'  => 'Ez milyen típusú tétel?',
+  'emailed to'                  => 'e-mail küldve:',
+  'sent to printer'             => 'kinyomtatva',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'folytatás'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/ir b/sql-ledger/locale/hu/ir
new file mode 100644 (file)
index 0000000..5e81745
--- /dev/null
@@ -0,0 +1,180 @@
+$self{texts} = {
+  'Account'                     => 'Számla',
+  'Add Purchase Order'          => 'Új beszerzési rendelés',
+  'Add Sales Order'             => 'Új vevõrendelés',
+  'Add Vendor Invoice'          => 'Add Vendor Invoice',
+  'Address'                     => 'Cím',
+  'Amount'                      => 'Összeg',
+  'Apr'                         => 'Ápr.',
+  'April'                       => 'Április',
+  'Are you sure you want to delete Invoice Number' => 'Biztos, hogy törölni akarja? Számlaszám:',
+  'Attachment'                  => 'Csatolás',
+  'Aug'                         => 'Aug.',
+  'August'                      => 'Augusztus',
+  'Bcc'                         => 'Titkos másolat',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'A partnerszámlát nem lehet törölni!',
+  'Cannot post invoice for a closed period!' => 'A lezárt idõszakban nem lehet számlát kiállítani!',
+  'Cannot post invoice!'        => 'A partnerszámlát nem lehet kiállítani',
+  'Cannot post payment for a closed period!' => 'A lezárt idõszakban nem lehet fizetést rögzíteni!',
+  'Cc'                          => 'Másolat',
+  'Confirm!'                    => 'Megerõsítés:',
+  'Contact'                     => 'Kapcsolat',
+  'Continue'                    => 'Folytatás',
+  'Copies'                      => 'Másolatok',
+  'Currency'                    => 'Deviza',
+  'Customer not on file!'       => 'A vevõ hiányzik az adatbázisból!',
+  'Date'                        => 'Dátum',
+  'Dec'                         => 'Dec.',
+  'December'                    => 'December',
+  'Delete'                      => 'Törlés',
+  'Delivery Date'               => 'Szállítás dátuma',
+  'Description'                 => 'Szöveges leírás',
+  'Due Date'                    => 'Esedékesség',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mail cím hiányzik!',
+  'Edit Vendor Invoice'         => 'Edit Vendor Invoice',
+  'Exch'                        => 'Árf',
+  'Exchangerate'                => 'Átváltási árfolyam',
+  'Exchangerate for payment missing!' => 'A fizetett összeg átváltási árfolyama hiányzik!',
+  'Exchangerate missing!'       => 'Átváltási árfolyam hiányzik!',
+  'Extended'                    => 'Összeg',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb.',
+  'February'                    => 'Február',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'In-line'                     => 'Beágyazva',
+  'Invoice'                     => 'Számla',
+  'Invoice Date'                => 'Teljesítés dátuma',
+  'Invoice Date missing!'       => 'Teljesítés dátuma hiányzik!',
+  'Invoice Number'              => 'Számlaszám',
+  'Invoice Number missing!'     => 'Számlaszám hiányzik!',
+  'Invoice deleted!'            => 'Számla törölve!',
+  'Invoice posted!'             => 'Számla rögzítve!',
+  'Item not on file!'           => 'A tétel nincs az adatbázisban!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Január',
+  'Jul'                         => 'Júl.',
+  'July'                        => 'Július',
+  'Jun'                         => 'Jún.',
+  'June'                        => 'Június',
+  'Mar'                         => 'Márc.',
+  'March'                       => 'Március',
+  'May'                         => 'Máj.',
+  'May '                        => 'Május',
+  'Message'                     => 'Üzenet',
+  'Name'                        => 'Név',
+  'No.'                         => 'Sz.',
+  'Notes'                       => 'Megjegyzés',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'November',
+  'Number'                      => 'Szám',
+  'Number missing in Row'       => 'Ebbõl a sorból hiányzik a szám:',
+  'Oct'                         => 'Okt.',
+  'October'                     => 'Október',
+  'Order'                       => 'Rendelés',
+  'Order Date missing!'         => 'Rendelés dátuma hiányzik!',
+  'Order Number'                => 'Rendelés száma',
+  'Order Number missing!'       => 'Rendelés száma hiányzik!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Szállítólevél',
+  'Packing List Date missing!'  => 'Szállítólevél dátuma hiányzik!',
+  'Packing List Number missing!' => 'Szállítólevél száma hiányzik!',
+  'Part'                        => 'Cikk',
+  'Payment date missing!'       => 'Pénzmozgás dátuma hiányzik!',
+  'Payments'                    => 'Kifizetések',
+  'Phone'                       => 'Telefon',
+  'Post'                        => 'Rögzítés',
+  'Post as new'                 => 'Rögzítés új tranzakcióként',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Ár',
+  'Printer'                     => 'Nyomtató',
+  'Project'                     => 'Munkaszám',
+  'Project not on file!'        => 'Munkaszám hiányzik az adatbázisból!',
+  'Purchase Order'              => 'Beszerzési rendelés',
+  'Qty'                         => 'Menny.',
+  'Recd'                        => 'Kapott',
+  'Record in'                   => 'Feladás:',
+  'Required by'                 => 'Leszállítás',
+  'Sales Order'                 => 'Vevõrendelés',
+  'Screen'                      => 'Képernyõre',
+  'Select from one of the items below' => 'Válasszon ki egyet az alábbi tételek közül',
+  'Select from one of the names below' => 'Válasszon ki egyet az alábbi nevek közül',
+  'Select from one of the projects below' => 'Válasszon ki egyet az alábbi munkaszámok közül',
+  'Select postscript or PDF!'   => 'Válassza ki a postscript vagy a PDF formátumot!',
+  'Sep'                         => 'Szept.',
+  'September'                   => 'Szeptember',
+  'Service'                     => 'Szolgáltatás',
+  'Ship'                        => 'Szállítás',
+  'Ship to'                     => 'Szállítási cím',
+  'Source'                      => 'Bizonylatszám',
+  'Subject'                     => 'Tárgy',
+  'Subtotal'                    => 'Részösszeg',
+  'Tax Included'                => 'Adót tartalmazza',
+  'To'                          => 'Meddig:',
+  'Total'                       => 'Végösszeg',
+  'Unit'                        => 'Egység',
+  'Update'                      => 'Frissítés',
+  'Vendor'                      => 'Szállító',
+  'Vendor missing!'             => 'Szállító hiányzik!',
+  'Vendor not on file!'         => 'Szállító nincs az adatbázisban!',
+  'What type of item is this?'  => 'Ez milyen típusú tétel?',
+  'Yes'                         => 'Igen',
+  'ea'                          => 'db',
+  'emailed to'                  => 'e-mail küldve:',
+  'sent to printer'             => 'kinyomtatva',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'folytatás'                   => 'continue',
+  'törlés'                      => 'delete',
+  'rendelés'                    => 'order',
+  'rögzítés'                    => 'post',
+  'rögzítés_új_tranzakcióként'  => 'post_as_new',
+  'frissítés'                   => 'update',
+  'igen'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/is b/sql-ledger/locale/hu/is
new file mode 100644 (file)
index 0000000..54cc04a
--- /dev/null
@@ -0,0 +1,187 @@
+$self{texts} = {
+  'Account'                     => 'Számla',
+  'Add Purchase Order'          => 'Új beszerzési rendelés',
+  'Add Sales Invoice'           => 'Új vevõszámla',
+  'Add Sales Order'             => 'Új vevõrendelés',
+  'Address'                     => 'Cím',
+  'Amount'                      => 'Összeg',
+  'Apr'                         => 'Ápr.',
+  'April'                       => 'Április',
+  'Are you sure you want to delete Invoice Number' => 'Biztos, hogy törölni akarja? Számlaszám:',
+  'Attachment'                  => 'Csatolás',
+  'Aug'                         => 'Aug.',
+  'August'                      => 'Augusztus',
+  'Bcc'                         => 'Titkos másolat',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'A partnerszámlát nem lehet törölni!',
+  'Cannot post invoice for a closed period!' => 'A lezárt idõszakban nem lehet számlát kiállítani!',
+  'Cannot post invoice!'        => 'A partnerszámlát nem lehet kiállítani',
+  'Cannot post payment for a closed period!' => 'A lezárt idõszakban nem lehet fizetést rögzíteni!',
+  'Cc'                          => 'Másolat',
+  'Confirm!'                    => 'Megerõsítés:',
+  'Contact'                     => 'Kapcsolat',
+  'Continue'                    => 'Folytatás',
+  'Copies'                      => 'Másolatok',
+  'Credit Limit'                => 'Hitelkeret',
+  'Currency'                    => 'Deviza',
+  'Customer'                    => 'Vevõ',
+  'Customer missing!'           => 'Vevõ hiányzik!',
+  'Customer not on file!'       => 'A vevõ hiányzik az adatbázisból!',
+  'Date'                        => 'Dátum',
+  'Dec'                         => 'Dec.',
+  'December'                    => 'December',
+  'Delete'                      => 'Törlés',
+  'Delivery Date'               => 'Szállítás dátuma',
+  'Description'                 => 'Szöveges leírás',
+  'Due Date'                    => 'Esedékesség',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mail cím hiányzik!',
+  'Edit Sales Invoice'          => 'Vevõszámla módosítása',
+  'Exch'                        => 'Árf',
+  'Exchangerate'                => 'Átváltási árfolyam',
+  'Exchangerate for payment missing!' => 'A fizetett összeg átváltási árfolyama hiányzik!',
+  'Exchangerate missing!'       => 'Átváltási árfolyam hiányzik!',
+  'Extended'                    => 'Összeg',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb.',
+  'February'                    => 'Február',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'In-line'                     => 'Beágyazva',
+  'Invoice'                     => 'Számla',
+  'Invoice Date'                => 'Teljesítés dátuma',
+  'Invoice Date missing!'       => 'Teljesítés dátuma hiányzik!',
+  'Invoice Number'              => 'Számlaszám',
+  'Invoice Number missing!'     => 'Számlaszám hiányzik!',
+  'Invoice deleted!'            => 'Számla törölve!',
+  'Invoice posted!'             => 'Számla rögzítve!',
+  'Item not on file!'           => 'A tétel nincs az adatbázisban!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Január',
+  'Jul'                         => 'Júl.',
+  'July'                        => 'Július',
+  'Jun'                         => 'Jún.',
+  'June'                        => 'Június',
+  'Mar'                         => 'Márc.',
+  'March'                       => 'Március',
+  'May'                         => 'Máj.',
+  'May '                        => 'Május',
+  'Message'                     => 'Üzenet',
+  'Name'                        => 'Név',
+  'No.'                         => 'Sz.',
+  'Notes'                       => 'Megjegyzés',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'November',
+  'Number'                      => 'Szám',
+  'Number missing in Row'       => 'Ebbõl a sorból hiányzik a szám:',
+  'Oct'                         => 'Okt.',
+  'October'                     => 'Október',
+  'Order'                       => 'Rendelés',
+  'Order Date missing!'         => 'Rendelés dátuma hiányzik!',
+  'Order Number'                => 'Rendelés száma',
+  'Order Number missing!'       => 'Rendelés száma hiányzik!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Szállítólevél',
+  'Packing List Date missing!'  => 'Szállítólevél dátuma hiányzik!',
+  'Packing List Number missing!' => 'Szállítólevél száma hiányzik!',
+  'Part'                        => 'Cikk',
+  'Payment date missing!'       => 'Pénzmozgás dátuma hiányzik!',
+  'Payments'                    => 'Kifizetések',
+  'Phone'                       => 'Telefon',
+  'Post'                        => 'Rögzítés',
+  'Post as new'                 => 'Rögzítés új tranzakcióként',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Ár',
+  'Print'                       => 'Nyomtatás',
+  'Printer'                     => 'Nyomtató',
+  'Project'                     => 'Munkaszám',
+  'Project not on file!'        => 'Munkaszám hiányzik az adatbázisból!',
+  'Purchase Order'              => 'Beszerzési rendelés',
+  'Qty'                         => 'Menny.',
+  'Recd'                        => 'Kapott',
+  'Record in'                   => 'Feladás:',
+  'Remaining'                   => 'Maradék',
+  'Required by'                 => 'Leszállítás',
+  'Sales Order'                 => 'Vevõrendelés',
+  'Screen'                      => 'Képernyõre',
+  'Select from one of the items below' => 'Válasszon ki egyet az alábbi tételek közül',
+  'Select from one of the names below' => 'Válasszon ki egyet az alábbi nevek közül',
+  'Select from one of the projects below' => 'Válasszon ki egyet az alábbi munkaszámok közül',
+  'Select postscript or PDF!'   => 'Válassza ki a postscript vagy a PDF formátumot!',
+  'Sep'                         => 'Szept.',
+  'September'                   => 'Szeptember',
+  'Service'                     => 'Szolgáltatás',
+  'Ship'                        => 'Szállítás',
+  'Ship to'                     => 'Szállítási cím',
+  'Ship via'                    => 'Szállítás innen:',
+  'Source'                      => 'Bizonylatszám',
+  'Subject'                     => 'Tárgy',
+  'Subtotal'                    => 'Részösszeg',
+  'Tax Included'                => 'Adót tartalmazza',
+  'To'                          => 'Meddig:',
+  'Total'                       => 'Végösszeg',
+  'Unit'                        => 'Egység',
+  'Update'                      => 'Frissítés',
+  'Vendor not on file!'         => 'Szállító nincs az adatbázisban!',
+  'What type of item is this?'  => 'Ez milyen típusú tétel?',
+  'Yes'                         => 'Igen',
+  'ea'                          => 'db',
+  'emailed to'                  => 'e-mail küldve:',
+  'sent to printer'             => 'kinyomtatva',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'folytatás'                   => 'continue',
+  'törlés'                      => 'delete',
+  'e_mail'                      => 'e_mail',
+  'rendelés'                    => 'order',
+  'rögzítés'                    => 'post',
+  'rögzítés_új_tranzakcióként'  => 'post_as_new',
+  'nyomtatás'                   => 'print',
+  'szállítási_cím'              => 'ship_to',
+  'frissítés'                   => 'update',
+  'igen'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/login b/sql-ledger/locale/hu/login
new file mode 100644 (file)
index 0000000..1b73088
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => ' ',
+  'Database Host'               => 'Adatbázis helye',
+  'Dataset'                     => 'Cégadatbázis',
+  'Incorrect Dataset version!'  => 'Érvénytelen adatbázisverzió!',
+  'Incorrect Password!'         => 'Érvénytelen jelszó!',
+  'Licensed to'                 => 'Cég:',
+  'Login'                       => 'Belépés',
+  'Name'                        => 'Név',
+  'Password'                    => 'Jelszó',
+  'User'                        => 'Felhasználó',
+  'Version'                     => 'Verzió',
+  'You are logged out!'         => 'Már kijelentkezett!',
+  'You did not enter a name!'   => 'Nem írt be nevet!',
+  'is not a member!'            => 'nem tag!',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'belépés'                     => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/menu b/sql-ledger/locale/hu/menu
new file mode 100644 (file)
index 0000000..e1c3682
--- /dev/null
@@ -0,0 +1,73 @@
+$self{texts} = {
+  'AP'                          => 'Szállítók',
+  'AP Aging'                    => 'Szállító lejárati lista',
+  'AR'                          => 'Vevõk',
+  'AR Aging'                    => 'Vevõ lejárati lista',
+  'Accounting Menu'             => 'Menü',
+  'Add Account'                 => 'Új számla',
+  'Add Assembly'                => 'Új saját termék',
+  'Add Customer'                => 'Új vevõ',
+  'Add GIFI'                    => 'Új gyûjtõkód',
+  'Add Group'                   => 'Add Group',
+  'Add Part'                    => 'Új cikk',
+  'Add Project'                 => 'Új munkaszám',
+  'Add Service'                 => 'Új szolgáltatás',
+  'Add Transaction'             => 'Új tranzakció',
+  'Add Vendor'                  => 'Új szállító',
+  'Assemblies'                  => 'Saját termékek',
+  'Audit Control'               => 'Audit Kontroll',
+  'Backup'                      => 'Biztonsági másolat',
+  'Balance Sheet'               => 'Mérleg',
+  'Cash'                        => 'Pénzmozgások',
+  'Chart of Accounts'           => 'Számlatükör',
+  'Check'                       => 'Csekk',
+  'Customers'                   => 'Vevõadatok',
+  'General Ledger'              => 'Fõkönyvi könyvelés',
+  'Goods & Services'            => 'Áruk & Szolgáltatások',
+  'Groups'                      => 'Groups',
+  'HTML Templates'              => 'HTML sablonok',
+  'Income Statement'            => 'Eredménykimutatás',
+  'Invoice'                     => 'Számla',
+  'LaTeX Templates'             => 'LaTeX sablonok',
+  'List Accounts'               => 'Számlák listázása',
+  'List GIFI'                   => 'Gyûjtõkódok listázása',
+  'Logout'                      => 'Kilépés',
+  'Order Entry'                 => 'Rendelések',
+  'Packing List'                => 'Szállítólevél',
+  'Parts'                       => 'Cikkek',
+  'Payment'                     => 'Kifizetés',
+  'Payments'                    => 'Kifizetések',
+  'Preferences'                 => 'Beállítások',
+  'Projects'                    => 'Munkaszámok',
+  'Purchase Order'              => 'Beszerzési rendelés',
+  'Purchase Orders'             => 'Beszerzési rendelések',
+  'Receipt'                     => 'Bevétel',
+  'Receipts'                    => 'Bevételek',
+  'Reconciliation'              => 'Egyeztetés',
+  'Reports'                     => 'Jelentések',
+  'Sales Invoice'               => 'Számlázás',
+  'Sales Order'                 => 'Vevõrendelés',
+  'Sales Orders'                => 'Vevõrendelések',
+  'Save to File'                => 'Másolat File-ba',
+  'Send by E-Mail'              => 'Másolat E-mail-ben',
+  'Services'                    => 'Szolgáltatások',
+  'Statement'                   => 'Kimutatás',
+  'Stock Assembly'              => 'Saját termék bevételezése',
+  'Stylesheet'                  => 'Stíluslap',
+  'System'                      => 'Törzsadatok',
+  'Tax collected'               => 'Fizetendõ ÁFA',
+  'Tax paid'                    => 'Levonható ÁFA',
+  'Transactions'                => 'Tranzakciók',
+  'Trial Balance'               => 'Fõkönyvi kivonat',
+  'Vendor Invoice'              => 'Vendor Invoice',
+  'Vendors'                     => 'Szállítók',
+  'Version'                     => 'Verzió',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/oe b/sql-ledger/locale/hu/oe
new file mode 100644 (file)
index 0000000..c182bc6
--- /dev/null
@@ -0,0 +1,202 @@
+$self{texts} = {
+  'Add'                         => 'Új',
+  'Add Purchase Order'          => 'Új beszerzési rendelés',
+  'Add Sales Invoice'           => 'Új vevõszámla',
+  'Add Sales Order'             => 'Új vevõrendelés',
+  'Add Vendor Invoice'          => 'Add Vendor Invoice',
+  'Address'                     => 'Cím',
+  'Amount'                      => 'Összeg',
+  'Apr'                         => 'Ápr.',
+  'April'                       => 'Április',
+  'Are you sure you want to delete Order Number' => 'Biztos, hogy törölni akarja? Megrendelésszám:',
+  'Attachment'                  => 'Csatolás',
+  'Aug'                         => 'Aug.',
+  'August'                      => 'Augusztus',
+  'Bcc'                         => 'Titkos másolat',
+  'Bin'                         => 'Bin',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'A rendelést nem lehet törölni!',
+  'Cannot save order!'          => 'A rendelést nem lehet elmenteni!',
+  'Cc'                          => 'Másolat',
+  'Closed'                      => 'Lezárt',
+  'Confirm!'                    => 'Megerõsítés:',
+  'Contact'                     => 'Kapcsolat',
+  'Continue'                    => 'Folytatás',
+  'Copies'                      => 'Másolatok',
+  'Credit Limit'                => 'Hitelkeret',
+  'Curr'                        => 'Dev',
+  'Currency'                    => 'Deviza',
+  'Customer'                    => 'Vevõ',
+  'Customer missing!'           => 'Vevõ hiányzik!',
+  'Customer not on file!'       => 'A vevõ hiányzik az adatbázisból!',
+  'Date'                        => 'Dátum',
+  'Dec'                         => 'Dec.',
+  'December'                    => 'December',
+  'Delete'                      => 'Törlés',
+  'Delivery Date'               => 'Szállítás dátuma',
+  'Description'                 => 'Szöveges leírás',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mail cím hiányzik!',
+  'Edit Purchase Order'         => 'Beszerzési rendelés módosítása',
+  'Edit Sales Order'            => 'Vevõrendelés módosítása',
+  'Exchangerate'                => 'Átváltási árfolyam',
+  'Exchangerate missing!'       => 'Átváltási árfolyam hiányzik!',
+  'Extended'                    => 'Összeg',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb.',
+  'February'                    => 'Február',
+  'From'                        => 'Mikortól:',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'ID'                          => 'Azonosító',
+  'In-line'                     => 'Beágyazva',
+  'Include in Report'           => 'Oszlopok:',
+  'Invoice'                     => 'Számla',
+  'Invoice Date missing!'       => 'Teljesítés dátuma hiányzik!',
+  'Invoice Number missing!'     => 'Számlaszám hiányzik!',
+  'Item not on file!'           => 'A tétel nincs az adatbázisban!',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Január',
+  'Jul'                         => 'Júl.',
+  'July'                        => 'Július',
+  'Jun'                         => 'Jún.',
+  'June'                        => 'Június',
+  'Mar'                         => 'Márc.',
+  'March'                       => 'Március',
+  'May'                         => 'Máj.',
+  'May '                        => 'Május',
+  'Message'                     => 'Üzenet',
+  'Name'                        => 'Név',
+  'No.'                         => 'Sz.',
+  'Notes'                       => 'Megjegyzés',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'November',
+  'Number'                      => 'Szám',
+  'Number missing in Row'       => 'Ebbõl a sorból hiányzik a szám:',
+  'O'                           => 'Ny.',
+  'Oct'                         => 'Okt.',
+  'October'                     => 'Október',
+  'Open'                        => 'Nyitott',
+  'Order'                       => 'Rendelés',
+  'Order Date'                  => 'Rendelés dátuma',
+  'Order Date missing!'         => 'Rendelés dátuma hiányzik!',
+  'Order Number'                => 'Rendelés száma',
+  'Order Number missing!'       => 'Rendelés száma hiányzik!',
+  'Order deleted!'              => 'Rendelés törölve!',
+  'Order saved!'                => 'Rendelés elmentve!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Szállítólevél',
+  'Packing List Date missing!'  => 'Szállítólevél dátuma hiányzik!',
+  'Packing List Number missing!' => 'Szállítólevél száma hiányzik!',
+  'Part'                        => 'Cikk',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Ár',
+  'Print'                       => 'Nyomtatás',
+  'Printer'                     => 'Nyomtató',
+  'Project'                     => 'Munkaszám',
+  'Project not on file!'        => 'Munkaszám hiányzik az adatbázisból!',
+  'Purchase Order'              => 'Beszerzési rendelés',
+  'Purchase Orders'             => 'Beszerzési rendelések',
+  'Qty'                         => 'Menny.',
+  'Recd'                        => 'Kapott',
+  'Remaining'                   => 'Maradék',
+  'Required by'                 => 'Leszállítás',
+  'Sales Order'                 => 'Vevõrendelés',
+  'Sales Orders'                => 'Vevõrendelések',
+  'Save'                        => 'Mentés',
+  'Save as new'                 => 'Mentés újként',
+  'Screen'                      => 'Képernyõre',
+  'Select from one of the items below' => 'Válasszon ki egyet az alábbi tételek közül',
+  'Select from one of the names below' => 'Válasszon ki egyet az alábbi nevek közül',
+  'Select from one of the projects below' => 'Válasszon ki egyet az alábbi munkaszámok közül',
+  'Select postscript or PDF!'   => 'Válassza ki a postscript vagy a PDF formátumot!',
+  'Sep'                         => 'Szept.',
+  'September'                   => 'Szeptember',
+  'Service'                     => 'Szolgáltatás',
+  'Ship'                        => 'Szállítás',
+  'Ship to'                     => 'Szállítási cím',
+  'Ship via'                    => 'Szállítás innen:',
+  'Subject'                     => 'Tárgy',
+  'Subtotal'                    => 'Részösszeg',
+  'Tax'                         => 'Adó',
+  'Tax Included'                => 'Adót tartalmazza',
+  'Terms: Net'                  => 'Határidõ',
+  'To'                          => 'Meddig:',
+  'Total'                       => 'Végösszeg',
+  'Unit'                        => 'Egység',
+  'Update'                      => 'Frissítés',
+  'Vendor'                      => 'Szállító',
+  'Vendor missing!'             => 'Szállító hiányzik!',
+  'Vendor not on file!'         => 'Szállító nincs az adatbázisban!',
+  'What type of item is this?'  => 'Ez milyen típusú tétel?',
+  'Yes'                         => 'Igen',
+  'days'                        => 'nap',
+  'ea'                          => 'db',
+  'emailed to'                  => 'e-mail küldve:',
+  'sent to printer'             => 'kinyomtatva',
+  'to'                          => 'Meddig:',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'Új'                          => 'add',
+  'folytatás'                   => 'continue',
+  'törlés'                      => 'delete',
+  'e_mail'                      => 'e_mail',
+  'számla'                      => 'invoice',
+  'nyomtatás'                   => 'print',
+  'mentés'                      => 'save',
+  'mentés_újként'               => 'save_as_new',
+  'szállítási_cím'              => 'ship_to',
+  'frissítés'                   => 'update',
+  'igen'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/pe b/sql-ledger/locale/hu/pe
new file mode 100644 (file)
index 0000000..1105848
--- /dev/null
@@ -0,0 +1,45 @@
+$self{texts} = {
+  'Add'                         => 'Új',
+  'Add Group'                   => 'Add Group',
+  'Add Project'                 => 'Új munkaszám',
+  'All'                         => 'Összes',
+  'Continue'                    => 'Folytatás',
+  'Delete'                      => 'Törlés',
+  'Description'                 => 'Szöveges leírás',
+  'Edit Group'                  => 'Edit Group',
+  'Edit Project'                => 'Projekt módosítása',
+  'Group'                       => 'Group',
+  'Group deleted!'              => 'Group deleted!',
+  'Group missing!'              => 'Group missing!',
+  'Group saved!'                => 'Group saved!',
+  'Groups'                      => 'Groups',
+  'Number'                      => 'Szám',
+  'Orphaned'                    => 'Tranzakció nélküli',
+  'Project'                     => 'Munkaszám',
+  'Project Number missing!'     => 'Munkaszám száma hiányzik!',
+  'Project deleted!'            => 'Munkaszám törölve!',
+  'Project saved!'              => 'Munkaszám elmentve!',
+  'Projects'                    => 'Munkaszámok',
+  'Save'                        => 'Mentés',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_partsgroup_footer'      => 'form_partsgroup_footer',
+  'form_partsgroup_header'      => 'form_partsgroup_header',
+  'form_project_footer'         => 'form_project_footer',
+  'form_project_header'         => 'form_project_header',
+  'partsgroup_report'           => 'partsgroup_report',
+  'project_report'              => 'project_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'Új'                          => 'add',
+  'folytatás'                   => 'continue',
+  'törlés'                      => 'delete',
+  'mentés'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/rc b/sql-ledger/locale/hu/rc
new file mode 100644 (file)
index 0000000..f9fc615
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Számla',
+  'Balance'                     => 'Egyenleg',
+  'Cleared Balance'             => 'Egyeztetett egyenleg',
+  'Continue'                    => 'Folytatás',
+  'Date'                        => 'Dátum',
+  'Deposit'                     => 'Betét',
+  'Description'                 => 'Szöveges leírás',
+  'Difference'                  => 'Eltérés',
+  'Done'                        => 'Elvégezve',
+  'Exchangerate Difference'     => 'Árfolyamkülönbség',
+  'From'                        => 'Mikortól:',
+  'Out of balance!'             => 'Az egyenleg nem stimmel!',
+  'Payment'                     => 'Kifizetés',
+  'Reconciliation'              => 'Egyeztetés',
+  'Select all'                  => 'Mindent kijelöl',
+  'Source'                      => 'Bizonylatszám',
+  'Statement Balance'           => 'Kimutatás egyenlege',
+  'Update'                      => 'Frissítés',
+  'to'                          => 'Meddig:',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'folytatás'                   => 'continue',
+  'elvégezve'                   => 'done',
+  'mindent_kijelöl'             => 'select_all',
+  'frissítés'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/hu/rp b/sql-ledger/locale/hu/rp
new file mode 100644 (file)
index 0000000..3cdf7d4
--- /dev/null
@@ -0,0 +1,119 @@
+$self{texts} = {
+  'AP Aging'                    => 'Szállító lejárati lista',
+  'AR Aging'                    => 'Vevõ lejárati lista',
+  'Account'                     => 'Számla',
+  'Accounts'                    => 'Számlák',
+  'Amount'                      => 'Összeg',
+  'Apr'                         => 'Ápr.',
+  'April'                       => 'Április',
+  'Attachment'                  => 'Csatolás',
+  'Aug'                         => 'Aug.',
+  'August'                      => 'Augusztus',
+  'Balance'                     => 'Egyenleg',
+  'Balance Sheet'               => 'Mérleg',
+  'Bcc'                         => 'Titkos másolat',
+  'Cash based'                  => 'Pénzmozgás alapján',
+  'Cc'                          => 'Másolat',
+  'Compare to'                  => 'Összehasonlítva:',
+  'Continue'                    => 'Folytatás',
+  'Copies'                      => 'Másolatok',
+  'Credit'                      => 'Követel',
+  'Current'                     => 'Nem lejárt',
+  'Customer'                    => 'Vevõ',
+  'Date'                        => 'Dátum',
+  'Debit'                       => 'Tartozik',
+  'Dec'                         => 'Dec.',
+  'December'                    => 'December',
+  'Decimalplaces'               => 'Tizedeshelyek',
+  'Description'                 => 'Szöveges leírás',
+  'Due'                         => 'Esedékes',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'Kimutatás küldése e-mail-ben:',
+  'Feb'                         => 'Feb.',
+  'February'                    => 'Február',
+  'From'                        => 'Mikortól:',
+  'GIFI'                        => 'Gyûjtõkód',
+  'Heading'                     => 'Fejléc',
+  'ID'                          => 'Azonosító',
+  'In-line'                     => 'Beágyazva',
+  'Include in Report'           => 'Oszlopok:',
+  'Income Statement'            => 'Eredménykimutatás',
+  'Invoice'                     => 'Számla',
+  'Jan'                         => 'Jan.',
+  'January'                     => 'Január',
+  'Jul'                         => 'Júl.',
+  'July'                        => 'Július',
+  'Jun'                         => 'Jún.',
+  'June'                        => 'Június',
+  'Mar'                         => 'Márc.',
+  'March'                       => 'Március',
+  'May'                         => 'Máj.',
+  'May '                        => 'Május',
+  'Message'                     => 'Üzenet',
+  'N/A'                         => 'N/A',
+  'Nothing selected!'           => 'Nincs semmi kiválasztva!',
+  'Nov'                         => 'Nov.',
+  'November'                    => 'November',
+  'Oct'                         => 'Okt.',
+  'October'                     => 'Október',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Kifizetések',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Nyomtatás',
+  'Printer'                     => 'Nyomtató',
+  'Project Number'              => 'Munkaszám',
+  'Receipts'                    => 'Bevételek',
+  'Report for'                  => 'Jelentés:',
+  'Retained Earnings'           => 'Adózás elõtti eredmény',
+  'Screen'                      => 'Képernyõre',
+  'Select all'                  => 'Mindent kijelöl',
+  'Select postscript or PDF!'   => 'Válassza ki a postscript vagy a PDF formátumot!',
+  'Sep'                         => 'Szept.',
+  'September'                   => 'Szeptember',
+  'Source'                      => 'Bizonylatszám',
+  'Standard'                    => 'Sztenderd',
+  'Statement'                   => 'Kimutatás',
+  'Statement sent to'           => 'Kimutatás elküldve:',
+  'Statements sent to printer!' => 'Kimutatás kinyomtatva!',
+  'Subject'                     => 'Tárgy',
+  'Subtotal'                    => 'Részösszeg',
+  'Tax'                         => 'Adó',
+  'Tax collected'               => 'Fizetendõ ÁFA',
+  'Tax paid'                    => 'Levonható ÁFA',
+  'Total'                       => 'Végösszeg',
+  'Trial Balance'               => 'Fõkönyvi kivonat',
+  'Vendor'                      => 'Szállító',
+  'as at'                       => 'Fordulónap:',
+  'collected on sales'          => 'vevõszámlák alapján',
+  'for Period'                  => 'Idõszak:',
+  'paid on purchases'           => 'szállítószámlák alapján',
+  'to'                          => 'Meddig:',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_accounts'               => 'list_accounts',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'folytatás'                   => 'continue',
+  'e_mail'                      => 'e_mail',
+  'nyomtatás'                   => 'print',
+  'mindent_kijelöl'             => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/is/COPYING b/sql-ledger/locale/is/COPYING
new file mode 100644 (file)
index 0000000..1992b50
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2003
+#
+# Icelandic texts:
+#
+#  Author: Margeir Reynisson <margeir@met.is>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/is/LANGUAGE b/sql-ledger/locale/is/LANGUAGE
new file mode 100644 (file)
index 0000000..b91caef
--- /dev/null
@@ -0,0 +1 @@
+Icelandic
diff --git a/sql-ledger/locale/is/admin b/sql-ledger/locale/is/admin
new file mode 100644 (file)
index 0000000..ddf4c1a
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Aðgangsheimildir',
+  'Accounting'                  => 'Bókhald',
+  'Add User'                    => 'Nýr notandi',
+  'Address'                     => 'Heimilisfang',
+  'Administration'              => 'Kerfisstjórnun',
+  'Administrator'               => 'Kerfisstjóri',
+  'All Datasets up to date!'    => 'Öll gagnasöfn uppfærð',
+  'Change Admin Password'       => 'Breyta kerfisstjóra lykilorði',
+  'Change Password'             => 'Breyta lykilorði',
+  'Character Set'               => 'Stafaset',
+  'Click on login name to edit!' => 'Smellið á notendanafn til þess að breyta',
+  'Company'                     => 'Fyritæki',
+  'Connect to'                  => 'Tengjast við',
+  'Continue'                    => 'Áfram',
+  'Create Chart of Accounts'    => 'Búa til lykklasett',
+  'Create Dataset'              => 'Búa til gagnasafn',
+  'DBI not installed!'          => 'DBI ekki virkt',
+  'Database'                    => 'Gagnagrunnur',
+  'Database Administration'     => 'Kerfisstjórn gagnagrunns',
+  'Database Driver not checked!' => 'Gagnagrunnstengi ekki athugað',
+  'Database User missing!'      => 'Gagnagrunns notanda vantar!',
+  'Dataset'                     => 'Gagnasafn',
+  'Dataset missing!'            => 'Gagnasafn vantar!',
+  'Dataset updated!'            => 'gagnasafn uppfært!',
+  'Date Format'                 => 'Dagsetningarform',
+  'Delete'                      => 'Eyða',
+  'Delete Dataset'              => 'Eyða gagnasafni',
+  'Directory'                   => 'Mapa',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Takmörk fyrir valmynd',
+  'E-mail'                      => 'R-póstur',
+  'Edit User'                   => 'Breyta notanda',
+  'Existing Datasets'           => 'Hætta með gagnasafn',
+  'Fax'                         => 'Símbréf',
+  'Host'                        => 'Netþjónn',
+  'Hostname missing!'           => 'Nafn netþjóns vantar',
+  'Incorrect Password!'         => 'Rangt lykilorð',
+  'Language'                    => 'Túngumál',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Setjið engar upplýsingar í netþjónn og port nema um sé að ræða annan netþjón.',
+  'Login'                       => 'Tengjast',
+  'Multibyte Encoding'          => 'Multibyte Encoding',
+  'Name'                        => 'Nafn',
+  'New Templates'               => 'Nýtt skabalón',
+  'No Database Drivers available!' => 'Engin gagnagrunnstengin til',
+  'No Dataset selected!'        => 'Ekkert gagnasafn valið',
+  'Nothing to delete!'          => 'Ekkert til þess að eyða!',
+  'Number Format'               => 'Númera útlit',
+  'Oracle Database Administration' => 'Oracle kerfisstjórnun á gagnagrunni',
+  'Password'                    => 'Aðgangsorð',
+  'Password changed!'           => 'Aðgangsorði breytt',
+  'Pg Database Administration'  => 'Pg kerfisstjórnun gagnarunns',
+  'Phone'                       => 'Sími.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port vantar',
+  'Printer'                     => 'Prentari',
+  'Save'                        => 'Geyma',
+  'Select a Dataset to delete and press "Continue"' => 'Veljið gagnasafn og ýtið á "Áfram"',
+  'Setup Templates'             => 'Skabalón fyrir uppsetningu',
+  'Ship via'                    => 'Senda með',
+  'Signature'                   => 'Undirskrift',
+  'Stylesheet'                  => 'Stílblað',
+  'Templates'                   => 'Skabalón',
+  'The following Datasets are not in use and can be deleted' => 'Eftirfarandi gagnasöfn eru ekki í notkunn og er því ekki hægt að eyða þeim',
+  'The following Datasets need to be updated' => 'Eftirfarandi gagnasafn þarfnast uppfærslu',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Engu verður eytt eða breytt með þessu ',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Þú getur notað notanda sem til er til þess að útbúa nýjan notanda með þvi að breyta bara notendanafninu.',
+  'Update Dataset'              => 'Uppfæra gagnasafn',
+  'Use Templates'               => 'Nota skabalón',
+  'User'                        => 'Notandi',
+  'User deleted!'               => 'Notanda eytt!',
+  'User saved!'                 => 'Notandi geymdur!',
+  'Version'                     => 'Útgáfa',
+  'You must enter a host and port for local and remote connections!' => 'Þú verður að gefa upp netþjón of port til þess að geta tengst!',
+  'does not exist'              => 'er ekki til',
+  'is already a member!'        => 'er þegar meðlimur',
+  'localhost'                   => 'lokal',
+  'locked!'                     => 'læst',
+  'successfully created!'       => 'uppfært!',
+  'successfully deleted!'       => 'eytt!',
+  'website'                     => 'á Internetinu',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'nýr_notandi'                 => 'add_user',
+  'breyta_kerfisstjóra_lykilorði' => 'change_admin_password',
+  'breyta_lykilorði'            => 'change_password',
+  'Áfram'                       => 'continue',
+  'búa_til_gagnasafn'           => 'create_dataset',
+  'eyða'                        => 'delete',
+  'eyða_gagnasafni'             => 'delete_dataset',
+  'tengjast'                    => 'login',
+  'oracle_kerfisstjórnun_á_gagnagrunni' => 'oracle_database_administration',
+  'pg_kerfisstjórnun_gagnarunns' => 'pg_database_administration',
+  'geyma'                       => 'save',
+  'uppfæra_gagnasafn'           => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/is/all b/sql-ledger/locale/is/all
new file mode 100644 (file)
index 0000000..4fc7b2d
--- /dev/null
@@ -0,0 +1,496 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Innkaupakerfi',
+  'AP Aging'                    => 'Aldursgreining',
+  'AP Transaction'              => 'Innkaupafærsla',
+  'AP Transactions'             => 'Innkaupafærslur',
+  'AR'                          => 'Sölukerfi',
+  'AR Aging'                    => 'Aldursgreining',
+  'AR Transaction'              => 'Sölufærsla',
+  'AR Transactions'             => 'Sölufærslur',
+  'About'                       => 'Um',
+  'Access Control'              => 'Aðgangsheimildir',
+  'Account'                     => 'Reikningur',
+  'Account Number'              => 'Reikningsnúmer',
+  'Account Number missing!'     => 'Reikningsnúmer vantar!',
+  'Account Type'                => 'Reikningstegund',
+  'Account Type missing!'       => 'Reikningstegund vantar!',
+  'Account deleted!'            => 'Reikningi eytt!',
+  'Account saved!'              => 'Reikningur geymdur!',
+  'Accounting'                  => 'Bókhald',
+  'Accounting Menu'             => 'Bókhalds valmynd',
+  'Accounts'                    => 'Reikningar',
+  'Active'                      => 'Virkja',
+  'Add'                         => 'Nýr',
+  'Add Account'                 => 'Nýr reikningur',
+  'Add Accounts Payables Transaction' => 'Ný kredit færsla',
+  'Add Accounts Receivables Transaction' => 'Ný debit færsla',
+  'Add Assembly'                => 'Ný samsetning',
+  'Add Customer'                => 'Nýr viðskiptavinur',
+  'Add GIFI'                    => 'Ný GIFI',
+  'Add General Ledger Transaction' => 'Ný höfuðfærsla',
+  'Add Part'                    => 'Ný vara',
+  'Add Project'                 => 'Nýt verkefni',
+  'Add Purchase Invoice'        => 'Nýr innkaupsreikningur',
+  'Add Purchase Order'          => 'Ný innkaupspöntun',
+  'Add Sales Invoice'           => 'Nýr sölureikningur',
+  'Add Sales Order'             => 'Ný sölupöntun',
+  'Add Service'                 => 'Ný þjónusta',
+  'Add Transaction'             => 'Ný bókhaldsfærsla',
+  'Add User'                    => 'Nýr notandi',
+  'Add Vendor'                  => 'Nýr byrgir',
+  'Address'                     => 'Heimilisfang',
+  'Administration'              => 'Kerfisstjórnun',
+  'Administrator'               => 'Kerfisstjóri',
+  'All'                         => 'Allt',
+  'All Datasets up to date!'    => 'Öll gagnasöfn uppfærð',
+  'Amount'                      => 'Upphæð',
+  'Amount Due'                  => 'Eindagi',
+  'Amount does not equal applied!' => 'Upphæð stemmir ekki!',
+  'Amount missing!'             => 'Reikning vantar!',
+  'Applied'                     => 'Uppfært',
+  'Apr'                         => 'apr',
+  'April'                       => 'apríl',
+  'Are you sure you want to delete Invoice Number' => 'Ert þú viss um að þú viljir eyða reikningi númer',
+  'Are you sure you want to delete Order Number' => 'Ert þú viss um að þú viljir eyða pöntun númer',
+  'Are you sure you want to delete Transaction' => 'Ert þú viss um að þú viljir eyða færslunni',
+  'Assemblies'                  => 'Samsetningar',
+  'Assemblies restocked!'       => 'Samsetningar endurunnar',
+  'Assembly Number missing!'    => 'Samsetningar númer vantar',
+  'Asset'                       => 'Eignir',
+  'Attachment'                  => 'Hjálagt',
+  'Audit Control'               => 'Yfirlit stjórnun',
+  'Aug'                         => 'ágú',
+  'August'                      => 'ágúst',
+  'BOM'                         => 'BOM',
+  'Backup'                      => 'Afrit',
+  'Backup sent to'              => 'Afrit sendist til',
+  'Balance'                     => 'Afstemming',
+  'Balance Sheet'               => 'Staða',
+  'Bcc'                         => 'Blint afrit',
+  'Bin'                         => 'Vörulager',
+  'Books are open'              => 'Bókhald er opið fyrir leiðréttingar',
+  'Bought'                      => 'Keypt',
+  'Business Number'             => 'Viðskiptanúmer',
+  'C'                           => 'C',
+  'COGS'                        => 'Innkaup',
+  'Cannot delete account!'      => 'Get ekki eytt reikningi!',
+  'Cannot delete customer!'     => 'Get ekki eytt viðskiptavini!',
+  'Cannot delete default account!' => 'Get ekki eytt grunnreikningi!',
+  'Cannot delete invoice!'      => 'Get ekki eytt sölureikningi!',
+  'Cannot delete item already invoiced!' => 'Get ekki eytt hlut sem þegar er til á sölureikningi!',
+  'Cannot delete item on order!' => 'Get ekki eytt hlut sem er í pöntun!',
+  'Cannot delete item which is part of an assembly!' => 'Get ekki eytt hlut sem er partur af samsetningu!',
+  'Cannot delete item!'         => 'Get ekki eytt hlut!',
+  'Cannot delete order!'        => 'Get ekki eytt pöntun!',
+  'Cannot delete transaction!'  => 'Get ekki eytt færslu!',
+  'Cannot delete vendor!'       => 'Get ekki eytt framleiðanda!',
+  'Cannot have a value in both Debit and Credit!' => 'Get ekki haft gildi bæði í debit og kredit!',
+  'Cannot post a transaction without a value!' => 'Get ekki bókað án upphæðar',
+  'Cannot post invoice for a closed period!' => 'Get ekki bókað á lokað tímabil!',
+  'Cannot post invoice!'        => 'Get ekki bókað sölureikning!',
+  'Cannot post payment for a closed period!' => 'Get ekki bókað greiðslu á lokað tímabil',
+  'Cannot post payment!'        => 'Get ekki bókað greiðslu',
+  'Cannot post transaction for a closed period!' => 'Get ekki bókað færslu á lokað tímabil!',
+  'Cannot post transaction!'    => 'Get ekki bókað færslu!',
+  'Cannot process payment for a closed period!' => 'Get ekki meðhöndlað greiðslu fyrir lokað tímabil!',
+  'Cannot save account!'        => 'Get ekki geymt reikning!',
+  'Cannot save order!'          => 'Get ekki geymt pöntun!',
+  'Cannot save preferences!'    => 'Get ekki geymt uppsetningu!',
+  'Cannot stock assemblies!'    => 'Get ekki fært samsetningar',
+  'Cash'                        => 'Reiðufé',
+  'Cash based'                  => 'Reiðufétengt',
+  'Cc'                          => 'Afrit',
+  'Change Admin Password'       => 'Breyta kerfisstjóra lykilorði',
+  'Change Password'             => 'Breyta lykilorði',
+  'Character Set'               => 'Stafaset',
+  'Chart of Accounts'           => 'Listi yfir lykkla/reikninga',
+  'Check'                       => 'Ávísun',
+  'Check printed!'              => 'Ávísun prentuð',
+  'Check printing failed!'      => 'Villa við prentun á ávísun',
+  'Cleared Balance'             => 'Hreynsað jafvægi',
+  'Click on login name to edit!' => 'Smellið á notendanafn til þess að breyta',
+  'Close Books up to'           => 'Loka bókhaldi til dags',
+  'Closed'                      => 'Lokað',
+  'Company'                     => 'Fyritæki',
+  'Compare to'                  => 'Bera saman við',
+  'Confirm!'                    => 'Staðfesta!',
+  'Connect to'                  => 'Tengjast við',
+  'Contact'                     => 'Talsmaður',
+  'Continue'                    => 'Áfram',
+  'Copies'                      => 'Afrit',
+  'Copy to COA'                 => 'Afrita í COA',
+  'Create Chart of Accounts'    => 'Búa til lykklasett',
+  'Create Dataset'              => 'Búa til gagnasafn',
+  'Credit'                      => 'Kredit',
+  'Credit Limit'                => 'Kreditmörk',
+  'Curr'                        => 'Gjaldm',
+  'Currency'                    => 'Gjaldmiðill',
+  'Current'                     => 'Núvirði',
+  'Customer'                    => 'Viðskiptavinur',
+  'Customer deleted!'           => 'Viðskiptavini eytt!',
+  'Customer missing!'           => 'Viðskiptavin vantar!',
+  'Customer not on file!'       => 'Viðskiptavinur ekki á skrá!',
+  'Customer saved!'             => 'Viðskiptavinur geymdur!',
+  'Customers'                   => 'Viðskiptavinir',
+  'DBI not installed!'          => 'DBI ekki virkt',
+  'Database'                    => 'Gagnagrunnur',
+  'Database Administration'     => 'Kerfisstjórn gagnagrunns',
+  'Database Driver not checked!' => 'Gagnagrunnstengi ekki athugað',
+  'Database Host'               => 'Gagnagrunns-netþjónn',
+  'Database User missing!'      => 'Gagnagrunns notanda vantar!',
+  'Dataset'                     => 'Gagnasafn',
+  'Dataset missing!'            => 'Gagnasafn vantar!',
+  'Dataset updated!'            => 'gagnasafn uppfært!',
+  'Date'                        => 'Dagsetning',
+  'Date Due'                    => 'Eindagi',
+  'Date Format'                 => 'Dagsetningarform',
+  'Date Paid'                   => 'Greiðsludagur',
+  'Date missing!'               => 'Dagsetningu vantar!',
+  'Debit'                       => 'Debit',
+  'Debit and credit out of balance!' => 'Debit og kredit skulu vera eins!',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Decimalplaces'               => 'Aukastafir',
+  'Delete'                      => 'Eyða',
+  'Delete Account'              => 'Eyða reikningi',
+  'Delete Dataset'              => 'Eyða gagnasafni',
+  'Delivery Date'               => 'Afgreiðsludags.',
+  'Department'                  => '',
+  'Deposit'                     => 'Innlagt',
+  'Description'                 => 'Skýringar',
+  'Difference'                  => 'Mismunur',
+  'Directory'                   => 'Mapa',
+  'Discount'                    => 'Afsláttur',
+  'Done'                        => 'Búið',
+  'Drawing'                     => 'Dregið',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Takmörk fyrir valmynd',
+  'Due'                         => 'Lokið',
+  'Due Date'                    => 'Dags. lokið',
+  'Due Date missing!'           => 'Vantar dags. lokið!',
+  'E-mail'                      => 'R-póstur',
+  'E-mail Statement to'         => 'Senda yfirlit til',
+  'E-mail address missing!'     => 'R-póst vantar!',
+  'Edit'                        => 'Breyta',
+  'Edit Account'                => 'Breyta reikningi',
+  'Edit Accounts Payables Transaction' => 'Breyta greiðslufærslum',
+  'Edit Accounts Receivables Transaction' => 'Breyta inn-færslum',
+  'Edit Assembly'               => 'Breyta samsetningu',
+  'Edit Customer'               => 'Breyta viðskiptavini',
+  'Edit GIFI'                   => 'Breyta GIFI',
+  'Edit General Ledger Transaction' => 'Breyta yfitbókunar færslum',
+  'Edit Part'                   => 'Breyta vöru',
+  'Edit Preferences for'        => 'Breyta uppsetningu fyrir',
+  'Edit Project'                => 'Breyta verkefni',
+  'Edit Purchase Invoice'       => 'Breyta innkaupareikningi',
+  'Edit Purchase Order'         => 'Breyta innkaupapöntun',
+  'Edit Sales Invoice'          => 'Breyta sölureikningi',
+  'Edit Sales Order'            => 'Breyta sölupöntun',
+  'Edit Service'                => 'Breyta þjónustu',
+  'Edit Template'               => 'Breyta skabalóni',
+  'Edit User'                   => 'Breyta notanda',
+  'Edit Vendor'                 => 'Breyta byrgja',
+  'Employee'                    => 'Starfsmenn',
+  'Enforce transaction reversal for all dates' => 'Gennemtving explicitte rettelser af posteringer for alle datoer',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Vinsamlega sláið inn 3 stafa nafn á gjaldeyri sem á að nota setji tvípúnkt á milli.',
+  'Equity'                      => 'Eigiðfé',
+  'Exch'                        => 'Vx',
+  'Exchangerate'                => 'Vextir',
+  'Exchangerate Difference'     => 'Vaxtamunur',
+  'Exchangerate for payment missing!' => 'Vextir fyrir greiðslu vantar!',
+  'Exchangerate missing!'       => 'Vantar vexti!',
+  'Existing Datasets'           => 'Hætta með gagnasafn',
+  'Expense'                     => 'Kostnaður',
+  'Expense Account'             => 'Kostnaðarreikningur',
+  'Expense/Asset'               => 'Kostnaður/Eignir',
+  'Extended'                    => 'Framlengt',
+  'Fax'                         => 'Símbréf',
+  'Feb'                         => 'feb',
+  'February'                    => 'febrúar',
+  'Foreign Exchange Gain'       => 'Gengishagnaður',
+  'Foreign Exchange Loss'       => 'Gengistap',
+  'From'                        => 'Frá',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI eytt!',
+  'GIFI missing!'               => 'GIFI vantar!',
+  'GIFI saved!'                 => 'GIFI geymt!',
+  'GL Transaction'              => 'Færslur í aðalbók',
+  'General Ledger'              => 'Aðalbók',
+  'Goods & Services'            => 'Vörur og þjónusta',
+  'HTML Templates'              => 'HTML-skabalón',
+  'Heading'                     => 'Yfirskriftir',
+  'Host'                        => 'Netþjónn',
+  'Hostname missing!'           => 'Nafn netþjóns vantar',
+  'ID'                          => 'ID',
+  'Image'                       => 'Mynd',
+  'In-line'                     => 'Inndregið',
+  'Include in Report'           => 'Innifela í skýrslu',
+  'Include in drop-down menus'  => 'Innifela í fellivalmynd',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Innifela þennan lykil hjá viðskiptavinum til þess að geta gert hann vask skildan',
+  'Income'                      => 'Innkoma',
+  'Income Account'              => 'Inn reikningur',
+  'Income Statement'            => 'Inn yfirlýsing',
+  'Incorrect Dataset version!'  => 'Röng útgáfa af gagnasfni!',
+  'Incorrect Password!'         => 'Rangt lykilorð',
+  'Individual Items'            => 'Sjálfstæðir hlutir',
+  'Inventory'                   => 'Lager',
+  'Inventory Account'           => 'Lagerlykill',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Lagerbeholdning skal være nul for at du kan forælde denne sammensætning',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Lagerbeholdning skal være nul for at du kan forælde denne enhed',
+  'Inventory quantity must be zero!' => 'Lagerbeholdning skal være nul',
+  'Invoice'                     => 'Sölureikningur',
+  'Invoice Date'                => 'Sölureikningur dags.',
+  'Invoice Date missing!'       => 'Sölureiknings dags. vantar!',
+  'Invoice Number'              => 'Sölureikningur Númer',
+  'Invoice Number missing!'     => 'Sölureikningsnúmer vantar!',
+  'Invoice deleted!'            => 'Sölureikningi eytt!',
+  'Invoice posted!'             => 'Sölureikningur bókfærður!',
+  'Invoices'                    => 'Sölureikningar',
+  'Is this a summary account to record' => 'Söfnunarreikningur fyrir',
+  'Item deleted!'               => 'Hlut eytt!',
+  'Item not on file!'           => 'Hlutur ekki á skrá!',
+  'Jan'                         => 'jan',
+  'January'                     => 'janúar',
+  'Jul'                         => 'júl',
+  'July'                        => 'júlí',
+  'Jun'                         => 'jún',
+  'June'                        => 'júní',
+  'LaTeX Templates'             => 'LaTeX-skabalón',
+  'Language'                    => 'Túngumál',
+  'Last Cost'                   => 'Síðasta verð',
+  'Last Invoice Number'         => 'Síðasta sölureiknings númer',
+  'Last Numbers & Default Accounts' => 'Síðasta númer og sjálfgefin reikningur',
+  'Last Purchase Order Number'  => 'Síðasta innkaupa pöntunar númer´',
+  'Last Sales Order Number'     => 'Síðasta sölupöntunar númer',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Setjið engar upplýsingar í netþjónn og port nema um sé að ræða annan netþjón.',
+  'Liability'                   => 'Passiv',
+  'Licensed to'                 => 'Skráð á',
+  'Line Total'                  => 'Samtals línur',
+  'Link'                        => 'Tenglar',
+  'Link Accounts'               => 'Tengja lykla',
+  'List Accounts'               => 'Sýna lykla',
+  'List GIFI'                   => 'Sýna GIFI',
+  'List Price'                  => 'Sýna verð',
+  'List Transactions'           => 'Sýna færslur',
+  'Login'                       => 'Tengjast',
+  'Logout'                      => 'Aftengjast',
+  'Make'                        => 'Tegund',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'maí',
+  'May '                        => 'maí',
+  'Message'                     => 'Skilaboð',
+  'Microfiche'                  => 'Mikrofilm',
+  'Model'                       => 'Model',
+  'Multibyte Encoding'          => '',
+  'N/A'                         => '',
+  'Name'                        => 'Nafn',
+  'Name missing!'               => 'Nafn vantar!',
+  'New Templates'               => 'Nýtt skabalón',
+  'No'                          => 'Nei',
+  'No Database Drivers available!' => 'Engin gagnagrunnstengin til',
+  'No Dataset selected!'        => 'Ekkert gagnasafn valið',
+  'No email address for'        => 'Ekkert netfang fyrir',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Upplýsinar',
+  'Nothing applied!'            => 'Ekkert bókað!',
+  'Nothing selected!'           => 'Ekkert valið!',
+  'Nothing to delete!'          => 'Ekkert til þess að eyða!',
+  'Nov'                         => 'nóv',
+  'November'                    => 'nóvember',
+  'Number'                      => 'Númer',
+  'Number Format'               => 'Númera útlit',
+  'Number missing in Row'       => 'Tölu vantar í röð',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Úrelt',
+  'Oct'                         => 'ókt',
+  'October'                     => 'óktóber',
+  'On Hand'                     => 'Á lager',
+  'On Order'                    => 'Í pöntun',
+  'Open'                        => 'opna',
+  'Oracle Database Administration' => 'Oracle kerfisstjórnun á gagnagrunni',
+  'Order'                       => 'Pöntun',
+  'Order Date'                  => 'Pöntunar dags.',
+  'Order Date missing!'         => 'Pöntunar dags. vantar',
+  'Order Entry'                 => 'Pöntunarblað',
+  'Order Number'                => 'Pöntun númer',
+  'Order Number missing!'       => 'Númer pöntunar vantar',
+  'Order deleted!'              => 'Pöntun eytt',
+  'Order saved!'                => 'Pöntun geymd',
+  'Ordered'                     => 'pantað',
+  'Orphaned'                    => 'Sjáfstætt',
+  'Out of balance!'             => 'Ekki jafnvægi!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Fylgiseðill',
+  'Packing List Date missing!'  => 'Dags. fylgiseðils vantar!',
+  'Packing List Number missing!' => 'Númer fylgiseðils vantar!',
+  'Paid'                        => 'Greitt',
+  'Paid in full'                => 'Greitt að fullu',
+  'Part'                        => 'Vara',
+  'Part Number missing!'        => 'Vörunúmer vantar!',
+  'Parts'                       => 'Vörur',
+  'Parts Inventory'             => 'Vörulisti',
+  'Password'                    => 'Aðgangsorð',
+  'Password changed!'           => 'Aðgangsorði breytt',
+  'Payables'                    => 'Útistandandi',
+  'Payment'                     => 'Greislur',
+  'Payment date missing!'       => 'Greiðsudags. vantar!',
+  'Payment posted!'             => 'Greiðsla bókuð',
+  'Payments'                    => 'Greiðslur',
+  'Pg Database Administration'  => 'Pg kerfisstjórnun gagnarunns',
+  'Phone'                       => 'Sími.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port vantar',
+  'Post'                        => 'Bókfæra',
+  'Post as new'                 => 'Bókfæra sem nýjan',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Uppsetningar',
+  'Preferences saved!'          => 'Uppsetningar geymdar!',
+  'Price'                       => 'Verð',
+  'Print'                       => 'Prenta',
+  'Printer'                     => 'Prentari',
+  'Project'                     => 'Verkefni',
+  'Project Number'              => '',
+  'Project Number missing!'     => 'Verkefnisnúmer vantar!',
+  'Project deleted!'            => 'Verkefni eytt!',
+  'Project not on file!'        => 'Verkefni ekki á skrá!',
+  'Project saved!'              => 'verkefni geymt!',
+  'Projects'                    => 'Verkefni',
+  'Purchase Invoice'            => 'Innkaupsreikningur',
+  'Purchase Order'              => 'Innkaupspöntun',
+  'Purchase Orders'             => 'Innkaupspantanir',
+  'Qty'                         => 'Magn',
+  'ROP'                         => '',
+  'Rate'                        => 'Taxti',
+  'Recd'                        => 'Mótt:',
+  'Receipt'                     => 'Kvittun',
+  'Receipt printed!'            => '',
+  'Receipt printing failed!'    => '',
+  'Receipts'                    => 'Kvittanir',
+  'Receivables'                 => 'Innborganir',
+  'Reconciliation'              => 'Afstemingar',
+  'Record in'                   => 'Bóka á',
+  'Reference'                   => 'Fylgiskjal',
+  'Reference missing!'          => 'Fylgiskjal vantar',
+  'Remaining'                   => 'Eftir',
+  'Report for'                  => 'Skýrsla fyrir',
+  'Reports'                     => 'Skýrslur',
+  'Required by'                 => 'Pantað af',
+  'Retained Earnings'           => 'Realiseret overskud',
+  'Sales'                       => 'Sala',
+  'Sales Invoice'               => 'Sölureikningur',
+  'Sales Order'                 => 'Sölupöntun',
+  'Sales Orders'                => 'Sölupantanir',
+  'Salesperson'                 => '',
+  'Save'                        => 'Geyma',
+  'Save as new'                 => 'Geyma sem nýtt',
+  'Save to File'                => 'Geyma í skrá',
+  'Screen'                      => 'Skjá',
+  'Select a Dataset to delete and press "Continue"' => 'Veljið gagnasafn og ýtið á "Áfram"',
+  'Select all'                  => 'Velja allt',
+  'Select from one of the items below' => 'Veljið einhver að neðangreindum hlutum, og ýtið á "Áfram"',
+  'Select from one of the names below' => 'Veljið einhvað að neðangreindum nöfnum',
+  'Select from one of the projects below' => 'Veljið einhvað að neðangreindum verkefnum',
+  'Select postscript or PDF!'   => 'Veljið postscript eða PDF',
+  'Sell Price'                  => 'Söluverð',
+  'Send by E-Mail'              => 'Senda með rafpósti',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Þjónusta',
+  'Service Items'               => 'Þjónustu hlutur',
+  'Service Number missing!'     => 'Þjónustunúmer vantar!',
+  'Services'                    => 'Þjónustur',
+  'Setup Templates'             => 'Skabalón fyrir uppsetningu',
+  'Ship'                        => 'Senda',
+  'Ship to'                     => 'Senda til',
+  'Ship via'                    => 'Senda með',
+  'Short'                       => 'Stutt',
+  'Signature'                   => 'Undirskrift',
+  'Sold'                        => 'Selt',
+  'Source'                      => 'Frálag',
+  'Standard'                    => 'Standart',
+  'Statement'                   => 'Uppgjör',
+  'Statement Balance'           => 'jöfnunaruppgjör',
+  'Statement sent to'           => 'Uppgjör sendist til',
+  'Statements sent to printer!' => 'Uppgjör sendist á prentara',
+  'Stock Assembly'              => 'Lager samsetning',
+  'Stylesheet'                  => 'Stílblað',
+  'Subject'                     => 'Efni',
+  'Subtotal'                    => 'Samtala',
+  'System'                      => 'Kerfi',
+  'Tax'                         => 'Virðisaukaskattur',
+  'Tax Accounts'                => 'VSK lykill',
+  'Tax Included'                => 'Taka með VSK',
+  'Tax collected'               => 'VSK samtals',
+  'Tax paid'                    => 'VSK greitt',
+  'Taxable'                     => 'Skatskildur',
+  'Template saved!'             => 'Skabalón geymt!',
+  'Templates'                   => 'Skabalón',
+  'Terms: Net'                  => 'Nettó',
+  'The following Datasets are not in use and can be deleted' => 'Eftirfarandi gagnasöfn eru ekki í notkunn og er því ekki hægt að eyða þeim',
+  'The following Datasets need to be updated' => 'Eftirfarandi gagnasafn þarfnast uppfærslu',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Engu verður eytt eða breytt með þessu ',
+  'To'                          => 'til',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Þú getur notað notanda sem til er til þess að útbúa nýjan notanda með þvi að breyta bara notendanafninu.',
+  'Top Level'                   => 'Efsta þrep',
+  'Total'                       => 'Samtals',
+  'Transaction Date missing!'   => 'Dags. vantar!',
+  'Transaction deleted!'        => 'Færslu eytt!',
+  'Transaction posted!'         => 'Færsla bókfærð!',
+  'Transaction reversal enforced for all dates' => 'Rettelser af posteringer skal altid bogføres explicit',
+  'Transaction reversal enforced up to' => 'Rettelser af posteringer skal bogføres explicit indtil',
+  'Transactions'                => 'Færslur',
+  'Transactions exist, cannot delete customer!' => 'Ekki er hægt að eyða viðskipamanni með færslur!',
+  'Transactions exist, cannot delete vendor!' => 'Ekki er hægt að eyða byrgja með færslur!',
+  'Transactions exist; cannot delete account!' => 'Ekki hægt að eyða reikningi með færslur!',
+  'Trial Balance'               => 'Prufu staða',
+  'Unit'                        => 'Einingar',
+  'Unit of measure'             => 'Mælieining',
+  'Update'                      => 'Uppfærsla',
+  'Update Dataset'              => 'Uppfæra gagnasafn',
+  'Updated'                     => 'Uppfæra',
+  'Use Templates'               => 'Nota skabalón',
+  'User'                        => 'Notandi',
+  'User deleted!'               => 'Notanda eytt!',
+  'User saved!'                 => 'Notandi geymdur!',
+  'Vendor'                      => 'Byrgir',
+  'Vendor deleted!'             => 'Byrgja eytt!',
+  'Vendor missing!'             => 'Byrgja vantar!',
+  'Vendor not on file!'         => 'Byrgir ekki til í gagnagrunni!',
+  'Vendor saved!'               => 'Byrgir geymdur!',
+  'Vendors'                     => 'Byrgjar',
+  'Version'                     => 'Útgáfa',
+  'Weight'                      => 'Vigt',
+  'Weight Unit'                 => 'Vigtareining',
+  'What type of item is this?'  => 'Hvernig hlutur er þetta?',
+  'Year End'                    => 'Ársuppgjör',
+  'Yes'                         => 'Já',
+  'You are logged out!'         => 'Þú ert loggaður út',
+  'You did not enter a name!'   => 'Þú gafst ekki upp nafn',
+  'You must enter a host and port for local and remote connections!' => 'Þú verður að gefa upp netþjón of port til þess að geta tengst!',
+  'as at'                       => 'líkt og með',
+  'collected on sales'          => 'samanlagt við sölu',
+  'days'                        => 'dagar',
+  'does not exist'              => 'er ekki til',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendist með rafpósti',
+  'for Period'                  => 'fyrir tímabilið',
+  'hr'                          => 'tími',
+  'is already a member!'        => 'er þegar meðlimur',
+  'is not a member!'            => 'er ekki meðlimur!',
+  'localhost'                   => 'lokal',
+  'locked!'                     => 'læst',
+  'paid on purchases'           => 'greitt við innkaup',
+  'sent to printer'             => 'sendist á prentara',
+  'successfully created!'       => 'uppfært!',
+  'successfully deleted!'       => 'eytt!',
+  'to'                          => 'til',
+  'website'                     => 'á Internetinu',
+};
+
+1;
diff --git a/sql-ledger/locale/is/am b/sql-ledger/locale/is/am
new file mode 100644 (file)
index 0000000..e8d66bf
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Innkaupakerfi',
+  'AR'                          => 'Sölukerfi',
+  'Account'                     => 'Reikningur',
+  'Account Number'              => 'Reikningsnúmer',
+  'Account Number missing!'     => 'Reikningsnúmer vantar!',
+  'Account Type'                => 'Reikningstegund',
+  'Account Type missing!'       => 'Reikningstegund vantar!',
+  'Account deleted!'            => 'Reikningi eytt!',
+  'Account saved!'              => 'Reikningur geymdur!',
+  'Add Account'                 => 'Nýr reikningur',
+  'Add GIFI'                    => 'Ný GIFI',
+  'Address'                     => 'Heimilisfang',
+  'Asset'                       => 'Eignir',
+  'Audit Control'               => 'Yfirlit stjórnun',
+  'Backup sent to'              => 'Afrit sendist til',
+  'Books are open'              => 'Bókhald er opið fyrir leiðréttingar',
+  'Business Number'             => 'Viðskiptanúmer',
+  'COGS'                        => 'Innkaup',
+  'Cannot delete account!'      => 'Get ekki eytt reikningi!',
+  'Cannot delete default account!' => 'Get ekki eytt grunnreikningi!',
+  'Cannot save account!'        => 'Get ekki geymt reikning!',
+  'Cannot save preferences!'    => 'Get ekki geymt uppsetningu!',
+  'Character Set'               => 'Stafaset',
+  'Chart of Accounts'           => 'Listi yfir lykkla/reikninga',
+  'Close Books up to'           => 'Loka bókhaldi til dags',
+  'Company'                     => 'Fyritæki',
+  'Continue'                    => 'Áfram',
+  'Copy to COA'                 => 'Afrita í COA',
+  'Credit'                      => 'Kredit',
+  'Date Format'                 => 'Dagsetningarform',
+  'Debit'                       => 'Debit',
+  'Delete'                      => 'Eyða',
+  'Delete Account'              => 'Eyða reikningi',
+  'Description'                 => 'Skýringar',
+  'Dropdown Limit'              => 'Takmörk fyrir valmynd',
+  'E-mail'                      => 'R-póstur',
+  'Edit'                        => 'Breyta',
+  'Edit Account'                => 'Breyta reikningi',
+  'Edit GIFI'                   => 'Breyta GIFI',
+  'Edit Preferences for'        => 'Breyta uppsetningu fyrir',
+  'Edit Template'               => 'Breyta skabalóni',
+  'Enforce transaction reversal for all dates' => 'Gennemtving explicitte rettelser af posteringer for alle datoer',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Vinsamlega sláið inn 3 stafa nafn á gjaldeyri sem á að nota setji tvípúnkt á milli.',
+  'Equity'                      => 'Eigiðfé',
+  'Expense'                     => 'Kostnaður',
+  'Expense Account'             => 'Kostnaðarreikningur',
+  'Expense/Asset'               => 'Kostnaður/Eignir',
+  'Fax'                         => 'Símbréf',
+  'Foreign Exchange Gain'       => 'Gengishagnaður',
+  'Foreign Exchange Loss'       => 'Gengistap',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI eytt!',
+  'GIFI missing!'               => 'GIFI vantar!',
+  'GIFI saved!'                 => 'GIFI geymt!',
+  'Heading'                     => 'Yfirskriftir',
+  'Include in drop-down menus'  => 'Innifela í fellivalmynd',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Innifela þennan lykil hjá viðskiptavinum til þess að geta gert hann vask skildan',
+  'Income'                      => 'Innkoma',
+  'Income Account'              => 'Inn reikningur',
+  'Inventory'                   => 'Lager',
+  'Inventory Account'           => 'Lagerlykill',
+  'Is this a summary account to record' => 'Söfnunarreikningur fyrir',
+  'Language'                    => 'Túngumál',
+  'Last Invoice Number'         => 'Síðasta sölureiknings númer',
+  'Last Numbers & Default Accounts' => 'Síðasta númer og sjálfgefin reikningur',
+  'Last Purchase Order Number'  => 'Síðasta innkaupa pöntunar númer´',
+  'Last Sales Order Number'     => 'Síðasta sölupöntunar númer',
+  'Liability'                   => 'Passiv',
+  'Link'                        => 'Tenglar',
+  'Name'                        => 'Nafn',
+  'No'                          => 'Nei',
+  'No email address for'        => 'Ekkert netfang fyrir',
+  'Number'                      => 'Númer',
+  'Number Format'               => 'Númera útlit',
+  'Parts Inventory'             => 'Vörulisti',
+  'Password'                    => 'Aðgangsorð',
+  'Payables'                    => 'Útistandandi',
+  'Payment'                     => 'Greislur',
+  'Phone'                       => 'Sími.',
+  'Preferences saved!'          => 'Uppsetningar geymdar!',
+  'Rate'                        => 'Taxti',
+  'Receivables'                 => 'Innborganir',
+  'Sales'                       => 'Sala',
+  'Save'                        => 'Geyma',
+  'Service Items'               => 'Þjónustu hlutur',
+  'Ship via'                    => 'Senda með',
+  'Signature'                   => 'Undirskrift',
+  'Stylesheet'                  => 'Stílblað',
+  'Tax'                         => 'Virðisaukaskattur',
+  'Tax Accounts'                => 'VSK lykill',
+  'Template saved!'             => 'Skabalón geymt!',
+  'Transaction reversal enforced for all dates' => 'Rettelser af posteringer skal altid bogføres explicit',
+  'Transaction reversal enforced up to' => 'Rettelser af posteringer skal bogføres explicit indtil',
+  'Transactions exist; cannot delete account!' => 'Ekki hægt að eyða reikningi með færslur!',
+  'Weight Unit'                 => 'Vigtareining',
+  'Year End'                    => 'Ársuppgjör',
+  'Yes'                         => 'Já',
+  'does not exist'              => 'er ekki til',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'nýr_reikningur'              => 'add_account',
+  'Áfram'                       => 'continue',
+  'afrita_í_coa'                => 'copy_to_coa',
+  'eyða'                        => 'delete',
+  'breyta'                      => 'edit',
+  'breyta_reikningi'            => 'edit_account',
+  'geyma'                       => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/is/ap b/sql-ledger/locale/is/ap
new file mode 100644 (file)
index 0000000..ea4afb2
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Innkaupafærsla',
+  'AP Transactions'             => 'Innkaupafærslur',
+  'Account'                     => 'Reikningur',
+  'Add Accounts Payables Transaction' => 'Ný kredit færsla',
+  'Address'                     => 'Heimilisfang',
+  'Amount'                      => 'Upphæð',
+  'Amount Due'                  => 'Eindagi',
+  'Apr'                         => 'apr',
+  'April'                       => 'apríl',
+  'Are you sure you want to delete Transaction' => 'Ert þú viss um að þú viljir eyða færslunni',
+  'Aug'                         => 'ágú',
+  'August'                      => 'ágúst',
+  'Cannot delete transaction!'  => 'Get ekki eytt færslu!',
+  'Cannot post payment for a closed period!' => 'Get ekki bókað greiðslu á lokað tímabil',
+  'Cannot post transaction for a closed period!' => 'Get ekki bókað færslu á lokað tímabil!',
+  'Cannot post transaction!'    => 'Get ekki bókað færslu!',
+  'Closed'                      => 'Lokað',
+  'Confirm!'                    => 'Staðfesta!',
+  'Continue'                    => 'Áfram',
+  'Currency'                    => 'Gjaldmiðill',
+  'Customer not on file!'       => 'Viðskiptavinur ekki á skrá!',
+  'Date'                        => 'Dagsetning',
+  'Date Paid'                   => 'Greiðsludagur',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Eyða',
+  'Description'                 => 'Skýringar',
+  'Due Date'                    => 'Dags. lokið',
+  'Due Date missing!'           => 'Vantar dags. lokið!',
+  'Edit Accounts Payables Transaction' => 'Breyta greiðslufærslum',
+  'Employee'                    => 'Starfsmenn',
+  'Exch'                        => 'Vx',
+  'Exchangerate'                => 'Vextir',
+  'Exchangerate for payment missing!' => 'Vextir fyrir greiðslu vantar!',
+  'Exchangerate missing!'       => 'Vantar vexti!',
+  'Feb'                         => 'feb',
+  'February'                    => 'febrúar',
+  'From'                        => 'Frá',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Innifela í skýrslu',
+  'Invoice'                     => 'Sölureikningur',
+  'Invoice Date'                => 'Sölureikningur dags.',
+  'Invoice Date missing!'       => 'Sölureiknings dags. vantar!',
+  'Invoice Number'              => 'Sölureikningur Númer',
+  'Invoice Number missing!'     => 'Sölureikningsnúmer vantar!',
+  'Jan'                         => 'jan',
+  'January'                     => 'janúar',
+  'Jul'                         => 'júl',
+  'July'                        => 'júlí',
+  'Jun'                         => 'jún',
+  'June'                        => 'júní',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'maí',
+  'May '                        => 'maí',
+  'Notes'                       => 'Upplýsinar',
+  'Nov'                         => 'nóv',
+  'November'                    => 'nóvember',
+  'Number'                      => 'Númer',
+  'Oct'                         => 'ókt',
+  'October'                     => 'óktóber',
+  'Open'                        => 'opna',
+  'Order'                       => 'Pöntun',
+  'Order Number'                => 'Pöntun númer',
+  'Paid'                        => 'Greitt',
+  'Payment date missing!'       => 'Greiðsudags. vantar!',
+  'Payments'                    => 'Greiðslur',
+  'Post'                        => 'Bókfæra',
+  'Post as new'                 => 'Bókfæra sem nýjan',
+  'Project'                     => 'Verkefni',
+  'Project not on file!'        => 'Verkefni ekki á skrá!',
+  'Purchase Invoice'            => 'Innkaupsreikningur',
+  'Select from one of the names below' => 'Veljið einhvað að neðangreindum nöfnum',
+  'Select from one of the projects below' => 'Veljið einhvað að neðangreindum verkefnum',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Source'                      => 'Frálag',
+  'Subtotal'                    => 'Samtala',
+  'Tax'                         => 'Virðisaukaskattur',
+  'Tax Included'                => 'Taka með VSK',
+  'Total'                       => 'Samtals',
+  'Transaction deleted!'        => 'Færslu eytt!',
+  'Transaction posted!'         => 'Færsla bókfærð!',
+  'Update'                      => 'Uppfærsla',
+  'Vendor'                      => 'Byrgir',
+  'Vendor missing!'             => 'Byrgja vantar!',
+  'Vendor not on file!'         => 'Byrgir ekki til í gagnagrunni!',
+  'Yes'                         => 'Já',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'innkaupafærsla'              => 'ap_transaction',
+  'ný_kredit_færsla'            => 'add_accounts_payables_transaction',
+  'Áfram'                       => 'continue',
+  'eyða'                        => 'delete',
+  'breyta_greiðslufærslum'      => 'edit_accounts_payables_transaction',
+  'bókfæra'                     => 'post',
+  'bókfæra_sem_nýjan'           => 'post_as_new',
+  'innkaupsreikningur'          => 'purchase_invoice',
+  'uppfærsla'                   => 'update',
+  'já'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/is/ar b/sql-ledger/locale/is/ar
new file mode 100644 (file)
index 0000000..6619389
--- /dev/null
@@ -0,0 +1,134 @@
+$self{texts} = {
+  'AR Transaction'              => 'Sölufærsla',
+  'AR Transactions'             => 'Sölufærslur',
+  'Account'                     => 'Reikningur',
+  'Add Accounts Receivables Transaction' => 'Ný debit færsla',
+  'Address'                     => 'Heimilisfang',
+  'Amount'                      => 'Upphæð',
+  'Amount Due'                  => 'Eindagi',
+  'Apr'                         => 'apr',
+  'April'                       => 'apríl',
+  'Are you sure you want to delete Transaction' => 'Ert þú viss um að þú viljir eyða færslunni',
+  'Aug'                         => 'ágú',
+  'August'                      => 'ágúst',
+  'Cannot delete transaction!'  => 'Get ekki eytt færslu!',
+  'Cannot post payment for a closed period!' => 'Get ekki bókað greiðslu á lokað tímabil',
+  'Cannot post transaction for a closed period!' => 'Get ekki bókað færslu á lokað tímabil!',
+  'Cannot post transaction!'    => 'Get ekki bókað færslu!',
+  'Closed'                      => 'Lokað',
+  'Confirm!'                    => 'Staðfesta!',
+  'Continue'                    => 'Áfram',
+  'Credit Limit'                => 'Kreditmörk',
+  'Currency'                    => 'Gjaldmiðill',
+  'Customer'                    => 'Viðskiptavinur',
+  'Customer missing!'           => 'Viðskiptavin vantar!',
+  'Customer not on file!'       => 'Viðskiptavinur ekki á skrá!',
+  'Date'                        => 'Dagsetning',
+  'Date Paid'                   => 'Greiðsludagur',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Eyða',
+  'Description'                 => 'Skýringar',
+  'Due Date'                    => 'Dags. lokið',
+  'Due Date missing!'           => 'Vantar dags. lokið!',
+  'Edit Accounts Receivables Transaction' => 'Breyta inn-færslum',
+  'Exch'                        => 'Vx',
+  'Exchangerate'                => 'Vextir',
+  'Exchangerate for payment missing!' => 'Vextir fyrir greiðslu vantar!',
+  'Exchangerate missing!'       => 'Vantar vexti!',
+  'Feb'                         => 'feb',
+  'February'                    => 'febrúar',
+  'From'                        => 'Frá',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Innifela í skýrslu',
+  'Invoice'                     => 'Sölureikningur',
+  'Invoice Date'                => 'Sölureikningur dags.',
+  'Invoice Date missing!'       => 'Sölureiknings dags. vantar!',
+  'Invoice Number'              => 'Sölureikningur Númer',
+  'Invoice Number missing!'     => 'Sölureikningsnúmer vantar!',
+  'Jan'                         => 'jan',
+  'January'                     => 'janúar',
+  'Jul'                         => 'júl',
+  'July'                        => 'júlí',
+  'Jun'                         => 'jún',
+  'June'                        => 'júní',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'maí',
+  'May '                        => 'maí',
+  'Notes'                       => 'Upplýsinar',
+  'Nov'                         => 'nóv',
+  'November'                    => 'nóvember',
+  'Number'                      => 'Númer',
+  'Oct'                         => 'ókt',
+  'October'                     => 'óktóber',
+  'Open'                        => 'opna',
+  'Order'                       => 'Pöntun',
+  'Order Number'                => 'Pöntun númer',
+  'Paid'                        => 'Greitt',
+  'Payment date missing!'       => 'Greiðsudags. vantar!',
+  'Payments'                    => 'Greiðslur',
+  'Post'                        => 'Bókfæra',
+  'Post as new'                 => 'Bókfæra sem nýjan',
+  'Project'                     => 'Verkefni',
+  'Project not on file!'        => 'Verkefni ekki á skrá!',
+  'Remaining'                   => 'Eftir',
+  'Sales Invoice'               => 'Sölureikningur',
+  'Salesperson'                 => 'Salesperson',
+  'Select from one of the names below' => 'Veljið einhvað að neðangreindum nöfnum',
+  'Select from one of the projects below' => 'Veljið einhvað að neðangreindum verkefnum',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Ship via'                    => 'Senda með',
+  'Source'                      => 'Frálag',
+  'Subtotal'                    => 'Samtala',
+  'Tax'                         => 'Virðisaukaskattur',
+  'Tax Included'                => 'Taka með VSK',
+  'Total'                       => 'Samtals',
+  'Transaction deleted!'        => 'Færslu eytt!',
+  'Transaction posted!'         => 'Færsla bókfærð!',
+  'Update'                      => 'Uppfærsla',
+  'Vendor not on file!'         => 'Byrgir ekki til í gagnagrunni!',
+  'Yes'                         => 'Já',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'sölufærsla'                  => 'ar_transaction',
+  'Áfram'                       => 'continue',
+  'eyða'                        => 'delete',
+  'bókfæra'                     => 'post',
+  'bókfæra_sem_nýjan'           => 'post_as_new',
+  'sölureikningur'              => 'sales_invoice',
+  'uppfærsla'                   => 'update',
+  'já'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/is/arap b/sql-ledger/locale/is/arap
new file mode 100644 (file)
index 0000000..3e63011
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Heimilisfang',
+  'Continue'                    => 'Áfram',
+  'Customer not on file!'       => 'Viðskiptavinur ekki á skrá!',
+  'Description'                 => 'Skýringar',
+  'Number'                      => 'Númer',
+  'Project not on file!'        => 'Verkefni ekki á skrá!',
+  'Select from one of the names below' => 'Veljið einhvað að neðangreindum nöfnum',
+  'Select from one of the projects below' => 'Veljið einhvað að neðangreindum verkefnum',
+  'Vendor not on file!'         => 'Byrgir ekki til í gagnagrunni!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'Áfram'                       => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/is/ca b/sql-ledger/locale/is/ca
new file mode 100644 (file)
index 0000000..8d3b384
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Reikningur',
+  'Apr'                         => 'apr',
+  'April'                       => 'apríl',
+  'Aug'                         => 'ágú',
+  'August'                      => 'ágúst',
+  'Balance'                     => 'Afstemming',
+  'Chart of Accounts'           => 'Listi yfir lykkla/reikninga',
+  'Credit'                      => 'Kredit',
+  'Date'                        => 'Dagsetning',
+  'Debit'                       => 'Debit',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Description'                 => 'Skýringar',
+  'Feb'                         => 'feb',
+  'February'                    => 'febrúar',
+  'From'                        => 'Frá',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Innifela í skýrslu',
+  'Jan'                         => 'jan',
+  'January'                     => 'janúar',
+  'Jul'                         => 'júl',
+  'July'                        => 'júlí',
+  'Jun'                         => 'jún',
+  'June'                        => 'júní',
+  'List Transactions'           => 'Sýna færslur',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'maí',
+  'May '                        => 'maí',
+  'Nov'                         => 'nóv',
+  'November'                    => 'nóvember',
+  'Oct'                         => 'ókt',
+  'October'                     => 'óktóber',
+  'Reference'                   => 'Fylgiskjal',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Subtotal'                    => 'Samtala',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'sýna_færslur'                => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/is/cp b/sql-ledger/locale/is/cp
new file mode 100644 (file)
index 0000000..d21df27
--- /dev/null
@@ -0,0 +1,77 @@
+$self{texts} = {
+  'Account'                     => 'Reikningur',
+  'Address'                     => 'Heimilisfang',
+  'Amount'                      => 'Upphæð',
+  'Amount does not equal applied!' => 'Upphæð stemmir ekki!',
+  'Amount missing!'             => 'Reikning vantar!',
+  'Applied'                     => 'Uppfært',
+  'Cannot post payment!'        => 'Get ekki bókað greiðslu',
+  'Cannot process payment for a closed period!' => 'Get ekki meðhöndlað greiðslu fyrir lokað tímabil!',
+  'Check'                       => 'Ávísun',
+  'Check printed!'              => 'Ávísun prentuð',
+  'Check printing failed!'      => 'Villa við prentun á ávísun',
+  'Continue'                    => 'Áfram',
+  'Currency'                    => 'Gjaldmiðill',
+  'Customer'                    => 'Viðskiptavinur',
+  'Customer not on file!'       => 'Viðskiptavinur ekki á skrá!',
+  'Date'                        => 'Dagsetning',
+  'Date missing!'               => 'Dagsetningu vantar!',
+  'Description'                 => 'Skýringar',
+  'Due'                         => 'Lokið',
+  'Exchangerate'                => 'Vextir',
+  'From'                        => 'Frá',
+  'Invoice'                     => 'Sölureikningur',
+  'Invoices'                    => 'Sölureikningar',
+  'Nothing applied!'            => 'Ekkert bókað!',
+  'Number'                      => 'Númer',
+  'Paid in full'                => 'Greitt að fullu',
+  'Payment'                     => 'Greislur',
+  'Payment posted!'             => 'Greiðsla bókuð',
+  'Post'                        => 'Bókfæra',
+  'Print'                       => 'Prenta',
+  'Printer'                     => 'Prentari',
+  'Project not on file!'        => 'Verkefni ekki á skrá!',
+  'Receipt'                     => 'Kvittun',
+  'Receipt printed!'            => 'Receipt printed!',
+  'Receipt printing failed!'    => 'Receipt printing failed!',
+  'Reference'                   => 'Fylgiskjal',
+  'Screen'                      => 'Skjá',
+  'Select from one of the names below' => 'Veljið einhvað að neðangreindum nöfnum',
+  'Select from one of the projects below' => 'Veljið einhvað að neðangreindum verkefnum',
+  'Update'                      => 'Uppfærsla',
+  'Vendor'                      => 'Byrgir',
+  'Vendor not on file!'         => 'Byrgir ekki til í gagnagrunni!',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'Áfram'                       => 'continue',
+  'bókfæra'                     => 'post',
+  'prenta'                      => 'print',
+  'uppfærsla'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/is/ct b/sql-ledger/locale/is/ct
new file mode 100644 (file)
index 0000000..d2be965
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Nýr',
+  'Address'                     => 'Heimilisfang',
+  'All'                         => 'Allt',
+  'Bcc'                         => 'Blint afrit',
+  'Cannot delete customer!'     => 'Get ekki eytt viðskiptavini!',
+  'Cannot delete vendor!'       => 'Get ekki eytt framleiðanda!',
+  'Cc'                          => 'Afrit',
+  'Contact'                     => 'Talsmaður',
+  'Continue'                    => 'Áfram',
+  'Credit Limit'                => 'Kreditmörk',
+  'Customer deleted!'           => 'Viðskiptavini eytt!',
+  'Customer saved!'             => 'Viðskiptavinur geymdur!',
+  'Customers'                   => 'Viðskiptavinir',
+  'Delete'                      => 'Eyða',
+  'Discount'                    => 'Afsláttur',
+  'E-mail'                      => 'R-póstur',
+  'Edit Customer'               => 'Breyta viðskiptavini',
+  'Edit Vendor'                 => 'Breyta byrgja',
+  'Fax'                         => 'Símbréf',
+  'Include in Report'           => 'Innifela í skýrslu',
+  'Invoice'                     => 'Sölureikningur',
+  'Name'                        => 'Nafn',
+  'Name missing!'               => 'Nafn vantar!',
+  'Notes'                       => 'Upplýsinar',
+  'Number'                      => 'Númer',
+  'Order'                       => 'Pöntun',
+  'Orphaned'                    => 'Sjáfstætt',
+  'Phone'                       => 'Sími.',
+  'Save'                        => 'Geyma',
+  'Ship to'                     => 'Senda til',
+  'Tax Included'                => 'Taka með VSK',
+  'Taxable'                     => 'Skatskildur',
+  'Terms: Net'                  => 'Nettó',
+  'Transactions exist, cannot delete customer!' => 'Ekki er hægt að eyða viðskipamanni með færslur!',
+  'Transactions exist, cannot delete vendor!' => 'Ekki er hægt að eyða byrgja með færslur!',
+  'Vendor deleted!'             => 'Byrgja eytt!',
+  'Vendor saved!'               => 'Byrgir geymdur!',
+  'Vendors'                     => 'Byrgjar',
+  'days'                        => 'dagar',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'nýr'                         => 'add',
+  'Áfram'                       => 'continue',
+  'eyða'                        => 'delete',
+  'sölureikningur'              => 'invoice',
+  'pöntun'                      => 'order',
+  'geyma'                       => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/is/gl b/sql-ledger/locale/is/gl
new file mode 100644 (file)
index 0000000..e659b9d
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Innkaupafærsla',
+  'AR Transaction'              => 'Sölufærsla',
+  'Account'                     => 'Reikningur',
+  'Add General Ledger Transaction' => 'Ný höfuðfærsla',
+  'Address'                     => 'Heimilisfang',
+  'All'                         => 'Allt',
+  'Apr'                         => 'apr',
+  'April'                       => 'apríl',
+  'Are you sure you want to delete Transaction' => 'Ert þú viss um að þú viljir eyða færslunni',
+  'Asset'                       => 'Eignir',
+  'Aug'                         => 'ágú',
+  'August'                      => 'ágúst',
+  'Balance'                     => 'Afstemming',
+  'Cannot delete transaction!'  => 'Get ekki eytt færslu!',
+  'Cannot have a value in both Debit and Credit!' => 'Get ekki haft gildi bæði í debit og kredit!',
+  'Cannot post a transaction without a value!' => 'Get ekki bókað án upphæðar',
+  'Cannot post transaction for a closed period!' => 'Get ekki bókað færslu á lokað tímabil!',
+  'Confirm!'                    => 'Staðfesta!',
+  'Continue'                    => 'Áfram',
+  'Credit'                      => 'Kredit',
+  'Customer not on file!'       => 'Viðskiptavinur ekki á skrá!',
+  'Date'                        => 'Dagsetning',
+  'Debit'                       => 'Debit',
+  'Debit and credit out of balance!' => 'Debit og kredit skulu vera eins!',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Eyða',
+  'Description'                 => 'Skýringar',
+  'Edit General Ledger Transaction' => 'Breyta yfitbókunar færslum',
+  'Equity'                      => 'Eigiðfé',
+  'Expense'                     => 'Kostnaður',
+  'Feb'                         => 'feb',
+  'February'                    => 'febrúar',
+  'From'                        => 'Frá',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'Færslur í aðalbók',
+  'General Ledger'              => 'Aðalbók',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Innifela í skýrslu',
+  'Income'                      => 'Innkoma',
+  'Jan'                         => 'jan',
+  'January'                     => 'janúar',
+  'Jul'                         => 'júl',
+  'July'                        => 'júlí',
+  'Jun'                         => 'jún',
+  'June'                        => 'júní',
+  'Liability'                   => 'Passiv',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'maí',
+  'May '                        => 'maí',
+  'Notes'                       => 'Upplýsinar',
+  'Nov'                         => 'nóv',
+  'November'                    => 'nóvember',
+  'Number'                      => 'Númer',
+  'Oct'                         => 'ókt',
+  'October'                     => 'óktóber',
+  'Post'                        => 'Bókfæra',
+  'Post as new'                 => 'Bókfæra sem nýjan',
+  'Project'                     => 'Verkefni',
+  'Project not on file!'        => 'Verkefni ekki á skrá!',
+  'Purchase Invoice'            => 'Innkaupsreikningur',
+  'Reference'                   => 'Fylgiskjal',
+  'Reference missing!'          => 'Fylgiskjal vantar',
+  'Reports'                     => 'Skýrslur',
+  'Sales Invoice'               => 'Sölureikningur',
+  'Select from one of the names below' => 'Veljið einhvað að neðangreindum nöfnum',
+  'Select from one of the projects below' => 'Veljið einhvað að neðangreindum verkefnum',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Source'                      => 'Frálag',
+  'Subtotal'                    => 'Samtala',
+  'Transaction Date missing!'   => 'Dags. vantar!',
+  'Transaction deleted!'        => 'Færslu eytt!',
+  'Transaction posted!'         => 'Færsla bókfærð!',
+  'Update'                      => 'Uppfærsla',
+  'Vendor not on file!'         => 'Byrgir ekki til í gagnagrunni!',
+  'Yes'                         => 'Já',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'innkaupafærsla'              => 'ap_transaction',
+  'sölufærsla'                  => 'ar_transaction',
+  'Áfram'                       => 'continue',
+  'eyða'                        => 'delete',
+  'færslur_í_aðalbók'           => 'gl_transaction',
+  'bókfæra'                     => 'post',
+  'bókfæra_sem_nýjan'           => 'post_as_new',
+  'innkaupsreikningur'          => 'purchase_invoice',
+  'sölureikningur'              => 'sales_invoice',
+  'uppfærsla'                   => 'update',
+  'já'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/is/ic b/sql-ledger/locale/is/ic
new file mode 100644 (file)
index 0000000..7950a0c
--- /dev/null
@@ -0,0 +1,206 @@
+$self{texts} = {
+  'Active'                      => 'Virkja',
+  'Add'                         => 'Nýr',
+  'Add Assembly'                => 'Ný samsetning',
+  'Add Part'                    => 'Ný vara',
+  'Add Purchase Order'          => 'Ný innkaupspöntun',
+  'Add Sales Order'             => 'Ný sölupöntun',
+  'Add Service'                 => 'Ný þjónusta',
+  'Address'                     => 'Heimilisfang',
+  'Apr'                         => 'apr',
+  'April'                       => 'apríl',
+  'Assemblies'                  => 'Samsetningar',
+  'Assemblies restocked!'       => 'Samsetningar endurunnar',
+  'Assembly Number missing!'    => 'Samsetningar númer vantar',
+  'Attachment'                  => 'Hjálagt',
+  'Aug'                         => 'ágú',
+  'August'                      => 'ágúst',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Blint afrit',
+  'Bin'                         => 'Vörulager',
+  'Bought'                      => 'Keypt',
+  'COGS'                        => 'Innkaup',
+  'Cannot delete item already invoiced!' => 'Get ekki eytt hlut sem þegar er til á sölureikningi!',
+  'Cannot delete item on order!' => 'Get ekki eytt hlut sem er í pöntun!',
+  'Cannot delete item which is part of an assembly!' => 'Get ekki eytt hlut sem er partur af samsetningu!',
+  'Cannot delete item!'         => 'Get ekki eytt hlut!',
+  'Cannot stock assemblies!'    => 'Get ekki fært samsetningar',
+  'Cc'                          => 'Afrit',
+  'Contact'                     => 'Talsmaður',
+  'Continue'                    => 'Áfram',
+  'Copies'                      => 'Afrit',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Eyða',
+  'Delivery Date'               => 'Afgreiðsludags.',
+  'Description'                 => 'Skýringar',
+  'Drawing'                     => 'Dregið',
+  'E-mail'                      => 'R-póstur',
+  'E-mail address missing!'     => 'R-póst vantar!',
+  'Edit Assembly'               => 'Breyta samsetningu',
+  'Edit Part'                   => 'Breyta vöru',
+  'Edit Service'                => 'Breyta þjónustu',
+  'Expense'                     => 'Kostnaður',
+  'Extended'                    => 'Framlengt',
+  'Fax'                         => 'Símbréf',
+  'Feb'                         => 'feb',
+  'February'                    => 'febrúar',
+  'From'                        => 'Frá',
+  'Image'                       => 'Mynd',
+  'In-line'                     => 'Inndregið',
+  'Include in Report'           => 'Innifela í skýrslu',
+  'Income'                      => 'Innkoma',
+  'Individual Items'            => 'Sjálfstæðir hlutir',
+  'Inventory'                   => 'Lager',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Lagerbeholdning skal være nul for at du kan forælde denne sammensætning',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Lagerbeholdning skal være nul for at du kan forælde denne enhed',
+  'Inventory quantity must be zero!' => 'Lagerbeholdning skal være nul',
+  'Invoice'                     => 'Sölureikningur',
+  'Invoice Date missing!'       => 'Sölureiknings dags. vantar!',
+  'Invoice Number'              => 'Sölureikningur Númer',
+  'Invoice Number missing!'     => 'Sölureikningsnúmer vantar!',
+  'Item deleted!'               => 'Hlut eytt!',
+  'Item not on file!'           => 'Hlutur ekki á skrá!',
+  'Jan'                         => 'jan',
+  'January'                     => 'janúar',
+  'Jul'                         => 'júl',
+  'July'                        => 'júlí',
+  'Jun'                         => 'jún',
+  'June'                        => 'júní',
+  'Last Cost'                   => 'Síðasta verð',
+  'Line Total'                  => 'Samtals línur',
+  'Link Accounts'               => 'Tengja lykla',
+  'List Price'                  => 'Sýna verð',
+  'Make'                        => 'Tegund',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'maí',
+  'May '                        => 'maí',
+  'Message'                     => 'Skilaboð',
+  'Microfiche'                  => 'Mikrofilm',
+  'Model'                       => 'Model',
+  'Name'                        => 'Nafn',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Upplýsinar',
+  'Nov'                         => 'nóv',
+  'November'                    => 'nóvember',
+  'Number'                      => 'Númer',
+  'Number missing in Row'       => 'Tölu vantar í röð',
+  'Obsolete'                    => 'Úrelt',
+  'Oct'                         => 'ókt',
+  'October'                     => 'óktóber',
+  'On Hand'                     => 'Á lager',
+  'On Order'                    => 'Í pöntun',
+  'Order'                       => 'Pöntun',
+  'Order Date missing!'         => 'Pöntunar dags. vantar',
+  'Order Number'                => 'Pöntun númer',
+  'Order Number missing!'       => 'Númer pöntunar vantar',
+  'Ordered'                     => 'pantað',
+  'Orphaned'                    => 'Sjáfstætt',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Fylgiseðill',
+  'Packing List Date missing!'  => 'Dags. fylgiseðils vantar!',
+  'Packing List Number missing!' => 'Númer fylgiseðils vantar!',
+  'Part'                        => 'Vara',
+  'Part Number missing!'        => 'Vörunúmer vantar!',
+  'Parts'                       => 'Vörur',
+  'Phone'                       => 'Sími.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Verð',
+  'Printer'                     => 'Prentari',
+  'Project'                     => 'Verkefni',
+  'Purchase Order'              => 'Innkaupspöntun',
+  'Qty'                         => 'Magn',
+  'ROP'                         => 'ROP',
+  'Recd'                        => 'Mótt:',
+  'Required by'                 => 'Pantað af',
+  'Sales'                       => 'Sala',
+  'Sales Order'                 => 'Sölupöntun',
+  'Save'                        => 'Geyma',
+  'Screen'                      => 'Skjá',
+  'Select from one of the items below' => 'Veljið einhver að neðangreindum hlutum, og ýtið á "Áfram"',
+  'Select postscript or PDF!'   => 'Veljið postscript eða PDF',
+  'Sell Price'                  => 'Söluverð',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Þjónusta',
+  'Service Number missing!'     => 'Þjónustunúmer vantar!',
+  'Services'                    => 'Þjónustur',
+  'Ship'                        => 'Senda',
+  'Ship to'                     => 'Senda til',
+  'Short'                       => 'Stutt',
+  'Sold'                        => 'Selt',
+  'Stock Assembly'              => 'Lager samsetning',
+  'Subject'                     => 'Efni',
+  'Subtotal'                    => 'Samtala',
+  'Tax'                         => 'Virðisaukaskattur',
+  'To'                          => 'til',
+  'Top Level'                   => 'Efsta þrep',
+  'Total'                       => 'Samtals',
+  'Unit'                        => 'Einingar',
+  'Unit of measure'             => 'Mælieining',
+  'Update'                      => 'Uppfærsla',
+  'Updated'                     => 'Uppfæra',
+  'Weight'                      => 'Vigt',
+  'What type of item is this?'  => 'Hvernig hlutur er þetta?',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendist með rafpósti',
+  'hr'                          => 'tími',
+  'sent to printer'             => 'sendist á prentara',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'nýr'                         => 'add',
+  'ný_samsetning'               => 'add_assembly',
+  'ný_vara'                     => 'add_part',
+  'ný_þjónusta'                 => 'add_service',
+  'Áfram'                       => 'continue',
+  'eyða'                        => 'delete',
+  'breyta_samsetningu'          => 'edit_assembly',
+  'breyta_vöru'                 => 'edit_part',
+  'breyta_þjónustu'             => 'edit_service',
+  'geyma'                       => 'save',
+  'uppfærsla'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/is/io b/sql-ledger/locale/is/io
new file mode 100644 (file)
index 0000000..def8209
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Ný innkaupspöntun',
+  'Add Sales Order'             => 'Ný sölupöntun',
+  'Address'                     => 'Heimilisfang',
+  'Apr'                         => 'apr',
+  'April'                       => 'apríl',
+  'Attachment'                  => 'Hjálagt',
+  'Aug'                         => 'ágú',
+  'August'                      => 'ágúst',
+  'Bcc'                         => 'Blint afrit',
+  'Bin'                         => 'Vörulager',
+  'Cc'                          => 'Afrit',
+  'Contact'                     => 'Talsmaður',
+  'Continue'                    => 'Áfram',
+  'Copies'                      => 'Afrit',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delivery Date'               => 'Afgreiðsludags.',
+  'Description'                 => 'Skýringar',
+  'E-mail'                      => 'R-póstur',
+  'E-mail address missing!'     => 'R-póst vantar!',
+  'Extended'                    => 'Framlengt',
+  'Fax'                         => 'Símbréf',
+  'Feb'                         => 'feb',
+  'February'                    => 'febrúar',
+  'In-line'                     => 'Inndregið',
+  'Invoice'                     => 'Sölureikningur',
+  'Invoice Date missing!'       => 'Sölureiknings dags. vantar!',
+  'Invoice Number missing!'     => 'Sölureikningsnúmer vantar!',
+  'Item not on file!'           => 'Hlutur ekki á skrá!',
+  'Jan'                         => 'jan',
+  'January'                     => 'janúar',
+  'Jul'                         => 'júl',
+  'July'                        => 'júlí',
+  'Jun'                         => 'jún',
+  'June'                        => 'júní',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'maí',
+  'May '                        => 'maí',
+  'Message'                     => 'Skilaboð',
+  'Name'                        => 'Nafn',
+  'No.'                         => 'Nr.',
+  'Nov'                         => 'nóv',
+  'November'                    => 'nóvember',
+  'Number'                      => 'Númer',
+  'Number missing in Row'       => 'Tölu vantar í röð',
+  'Oct'                         => 'ókt',
+  'October'                     => 'óktóber',
+  'Order'                       => 'Pöntun',
+  'Order Date missing!'         => 'Pöntunar dags. vantar',
+  'Order Number missing!'       => 'Númer pöntunar vantar',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Fylgiseðill',
+  'Packing List Date missing!'  => 'Dags. fylgiseðils vantar!',
+  'Packing List Number missing!' => 'Númer fylgiseðils vantar!',
+  'Part'                        => 'Vara',
+  'Phone'                       => 'Sími.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Verð',
+  'Printer'                     => 'Prentari',
+  'Project'                     => 'Verkefni',
+  'Purchase Order'              => 'Innkaupspöntun',
+  'Qty'                         => 'Magn',
+  'Recd'                        => 'Mótt:',
+  'Required by'                 => 'Pantað af',
+  'Sales Order'                 => 'Sölupöntun',
+  'Screen'                      => 'Skjá',
+  'Select from one of the items below' => 'Veljið einhver að neðangreindum hlutum, og ýtið á "Áfram"',
+  'Select postscript or PDF!'   => 'Veljið postscript eða PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Þjónusta',
+  'Ship'                        => 'Senda',
+  'Ship to'                     => 'Senda til',
+  'Subject'                     => 'Efni',
+  'To'                          => 'til',
+  'Unit'                        => 'Einingar',
+  'What type of item is this?'  => 'Hvernig hlutur er þetta?',
+  'emailed to'                  => 'sendist með rafpósti',
+  'sent to printer'             => 'sendist á prentara',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'Áfram'                       => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/is/ir b/sql-ledger/locale/is/ir
new file mode 100644 (file)
index 0000000..f941395
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Reikningur',
+  'Add Purchase Invoice'        => 'Nýr innkaupsreikningur',
+  'Add Purchase Order'          => 'Ný innkaupspöntun',
+  'Add Sales Order'             => 'Ný sölupöntun',
+  'Address'                     => 'Heimilisfang',
+  'Amount'                      => 'Upphæð',
+  'Apr'                         => 'apr',
+  'April'                       => 'apríl',
+  'Are you sure you want to delete Invoice Number' => 'Ert þú viss um að þú viljir eyða reikningi númer',
+  'Attachment'                  => 'Hjálagt',
+  'Aug'                         => 'ágú',
+  'August'                      => 'ágúst',
+  'Bcc'                         => 'Blint afrit',
+  'Bin'                         => 'Vörulager',
+  'Cannot delete invoice!'      => 'Get ekki eytt sölureikningi!',
+  'Cannot post invoice for a closed period!' => 'Get ekki bókað á lokað tímabil!',
+  'Cannot post invoice!'        => 'Get ekki bókað sölureikning!',
+  'Cannot post payment for a closed period!' => 'Get ekki bókað greiðslu á lokað tímabil',
+  'Cc'                          => 'Afrit',
+  'Confirm!'                    => 'Staðfesta!',
+  'Contact'                     => 'Talsmaður',
+  'Continue'                    => 'Áfram',
+  'Copies'                      => 'Afrit',
+  'Currency'                    => 'Gjaldmiðill',
+  'Customer not on file!'       => 'Viðskiptavinur ekki á skrá!',
+  'Date'                        => 'Dagsetning',
+  'Date Due'                    => 'Eindagi',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Eyða',
+  'Delivery Date'               => 'Afgreiðsludags.',
+  'Description'                 => 'Skýringar',
+  'E-mail'                      => 'R-póstur',
+  'E-mail address missing!'     => 'R-póst vantar!',
+  'Edit Purchase Invoice'       => 'Breyta innkaupareikningi',
+  'Exch'                        => 'Vx',
+  'Exchangerate'                => 'Vextir',
+  'Exchangerate for payment missing!' => 'Vextir fyrir greiðslu vantar!',
+  'Exchangerate missing!'       => 'Vantar vexti!',
+  'Extended'                    => 'Framlengt',
+  'Fax'                         => 'Símbréf',
+  'Feb'                         => 'feb',
+  'February'                    => 'febrúar',
+  'In-line'                     => 'Inndregið',
+  'Invoice'                     => 'Sölureikningur',
+  'Invoice Date'                => 'Sölureikningur dags.',
+  'Invoice Date missing!'       => 'Sölureiknings dags. vantar!',
+  'Invoice Number'              => 'Sölureikningur Númer',
+  'Invoice Number missing!'     => 'Sölureikningsnúmer vantar!',
+  'Invoice deleted!'            => 'Sölureikningi eytt!',
+  'Invoice posted!'             => 'Sölureikningur bókfærður!',
+  'Item not on file!'           => 'Hlutur ekki á skrá!',
+  'Jan'                         => 'jan',
+  'January'                     => 'janúar',
+  'Jul'                         => 'júl',
+  'July'                        => 'júlí',
+  'Jun'                         => 'jún',
+  'June'                        => 'júní',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'maí',
+  'May '                        => 'maí',
+  'Message'                     => 'Skilaboð',
+  'Name'                        => 'Nafn',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Upplýsinar',
+  'Nov'                         => 'nóv',
+  'November'                    => 'nóvember',
+  'Number'                      => 'Númer',
+  'Number missing in Row'       => 'Tölu vantar í röð',
+  'Oct'                         => 'ókt',
+  'October'                     => 'óktóber',
+  'Order'                       => 'Pöntun',
+  'Order Date missing!'         => 'Pöntunar dags. vantar',
+  'Order Number'                => 'Pöntun númer',
+  'Order Number missing!'       => 'Númer pöntunar vantar',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Fylgiseðill',
+  'Packing List Date missing!'  => 'Dags. fylgiseðils vantar!',
+  'Packing List Number missing!' => 'Númer fylgiseðils vantar!',
+  'Part'                        => 'Vara',
+  'Payment date missing!'       => 'Greiðsudags. vantar!',
+  'Payments'                    => 'Greiðslur',
+  'Phone'                       => 'Sími.',
+  'Post'                        => 'Bókfæra',
+  'Post as new'                 => 'Bókfæra sem nýjan',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Verð',
+  'Printer'                     => 'Prentari',
+  'Project'                     => 'Verkefni',
+  'Project not on file!'        => 'Verkefni ekki á skrá!',
+  'Purchase Order'              => 'Innkaupspöntun',
+  'Qty'                         => 'Magn',
+  'Recd'                        => 'Mótt:',
+  'Record in'                   => 'Bóka á',
+  'Required by'                 => 'Pantað af',
+  'Sales Order'                 => 'Sölupöntun',
+  'Screen'                      => 'Skjá',
+  'Select from one of the items below' => 'Veljið einhver að neðangreindum hlutum, og ýtið á "Áfram"',
+  'Select from one of the names below' => 'Veljið einhvað að neðangreindum nöfnum',
+  'Select from one of the projects below' => 'Veljið einhvað að neðangreindum verkefnum',
+  'Select postscript or PDF!'   => 'Veljið postscript eða PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Þjónusta',
+  'Ship'                        => 'Senda',
+  'Ship to'                     => 'Senda til',
+  'Source'                      => 'Frálag',
+  'Subject'                     => 'Efni',
+  'Subtotal'                    => 'Samtala',
+  'Tax Included'                => 'Taka með VSK',
+  'To'                          => 'til',
+  'Total'                       => 'Samtals',
+  'Unit'                        => 'Einingar',
+  'Update'                      => 'Uppfærsla',
+  'Vendor'                      => 'Byrgir',
+  'Vendor missing!'             => 'Byrgja vantar!',
+  'Vendor not on file!'         => 'Byrgir ekki til í gagnagrunni!',
+  'What type of item is this?'  => 'Hvernig hlutur er þetta?',
+  'Yes'                         => 'Já',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendist með rafpósti',
+  'sent to printer'             => 'sendist á prentara',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'Áfram'                       => 'continue',
+  'eyða'                        => 'delete',
+  'pöntun'                      => 'order',
+  'bókfæra'                     => 'post',
+  'bókfæra_sem_nýjan'           => 'post_as_new',
+  'uppfærsla'                   => 'update',
+  'já'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/is/is b/sql-ledger/locale/is/is
new file mode 100644 (file)
index 0000000..0416418
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Reikningur',
+  'Add Purchase Order'          => 'Ný innkaupspöntun',
+  'Add Sales Invoice'           => 'Nýr sölureikningur',
+  'Add Sales Order'             => 'Ný sölupöntun',
+  'Address'                     => 'Heimilisfang',
+  'Amount'                      => 'Upphæð',
+  'Apr'                         => 'apr',
+  'April'                       => 'apríl',
+  'Are you sure you want to delete Invoice Number' => 'Ert þú viss um að þú viljir eyða reikningi númer',
+  'Attachment'                  => 'Hjálagt',
+  'Aug'                         => 'ágú',
+  'August'                      => 'ágúst',
+  'Bcc'                         => 'Blint afrit',
+  'Bin'                         => 'Vörulager',
+  'Cannot delete invoice!'      => 'Get ekki eytt sölureikningi!',
+  'Cannot post invoice for a closed period!' => 'Get ekki bókað á lokað tímabil!',
+  'Cannot post invoice!'        => 'Get ekki bókað sölureikning!',
+  'Cannot post payment for a closed period!' => 'Get ekki bókað greiðslu á lokað tímabil',
+  'Cc'                          => 'Afrit',
+  'Confirm!'                    => 'Staðfesta!',
+  'Contact'                     => 'Talsmaður',
+  'Continue'                    => 'Áfram',
+  'Copies'                      => 'Afrit',
+  'Credit Limit'                => 'Kreditmörk',
+  'Currency'                    => 'Gjaldmiðill',
+  'Customer'                    => 'Viðskiptavinur',
+  'Customer missing!'           => 'Viðskiptavin vantar!',
+  'Customer not on file!'       => 'Viðskiptavinur ekki á skrá!',
+  'Date'                        => 'Dagsetning',
+  'Date Due'                    => 'Eindagi',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Eyða',
+  'Delivery Date'               => 'Afgreiðsludags.',
+  'Description'                 => 'Skýringar',
+  'E-mail'                      => 'R-póstur',
+  'E-mail address missing!'     => 'R-póst vantar!',
+  'Edit Sales Invoice'          => 'Breyta sölureikningi',
+  'Exch'                        => 'Vx',
+  'Exchangerate'                => 'Vextir',
+  'Exchangerate for payment missing!' => 'Vextir fyrir greiðslu vantar!',
+  'Exchangerate missing!'       => 'Vantar vexti!',
+  'Extended'                    => 'Framlengt',
+  'Fax'                         => 'Símbréf',
+  'Feb'                         => 'feb',
+  'February'                    => 'febrúar',
+  'In-line'                     => 'Inndregið',
+  'Invoice'                     => 'Sölureikningur',
+  'Invoice Date'                => 'Sölureikningur dags.',
+  'Invoice Date missing!'       => 'Sölureiknings dags. vantar!',
+  'Invoice Number'              => 'Sölureikningur Númer',
+  'Invoice Number missing!'     => 'Sölureikningsnúmer vantar!',
+  'Invoice deleted!'            => 'Sölureikningi eytt!',
+  'Invoice posted!'             => 'Sölureikningur bókfærður!',
+  'Item not on file!'           => 'Hlutur ekki á skrá!',
+  'Jan'                         => 'jan',
+  'January'                     => 'janúar',
+  'Jul'                         => 'júl',
+  'July'                        => 'júlí',
+  'Jun'                         => 'jún',
+  'June'                        => 'júní',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'maí',
+  'May '                        => 'maí',
+  'Message'                     => 'Skilaboð',
+  'Name'                        => 'Nafn',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Upplýsinar',
+  'Nov'                         => 'nóv',
+  'November'                    => 'nóvember',
+  'Number'                      => 'Númer',
+  'Number missing in Row'       => 'Tölu vantar í röð',
+  'Oct'                         => 'ókt',
+  'October'                     => 'óktóber',
+  'Order'                       => 'Pöntun',
+  'Order Date missing!'         => 'Pöntunar dags. vantar',
+  'Order Number'                => 'Pöntun númer',
+  'Order Number missing!'       => 'Númer pöntunar vantar',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Fylgiseðill',
+  'Packing List Date missing!'  => 'Dags. fylgiseðils vantar!',
+  'Packing List Number missing!' => 'Númer fylgiseðils vantar!',
+  'Part'                        => 'Vara',
+  'Payment date missing!'       => 'Greiðsudags. vantar!',
+  'Payments'                    => 'Greiðslur',
+  'Phone'                       => 'Sími.',
+  'Post'                        => 'Bókfæra',
+  'Post as new'                 => 'Bókfæra sem nýjan',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Verð',
+  'Print'                       => 'Prenta',
+  'Printer'                     => 'Prentari',
+  'Project'                     => 'Verkefni',
+  'Project not on file!'        => 'Verkefni ekki á skrá!',
+  'Purchase Order'              => 'Innkaupspöntun',
+  'Qty'                         => 'Magn',
+  'Recd'                        => 'Mótt:',
+  'Record in'                   => 'Bóka á',
+  'Remaining'                   => 'Eftir',
+  'Required by'                 => 'Pantað af',
+  'Sales Order'                 => 'Sölupöntun',
+  'Screen'                      => 'Skjá',
+  'Select from one of the items below' => 'Veljið einhver að neðangreindum hlutum, og ýtið á "Áfram"',
+  'Select from one of the names below' => 'Veljið einhvað að neðangreindum nöfnum',
+  'Select from one of the projects below' => 'Veljið einhvað að neðangreindum verkefnum',
+  'Select postscript or PDF!'   => 'Veljið postscript eða PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Þjónusta',
+  'Ship'                        => 'Senda',
+  'Ship to'                     => 'Senda til',
+  'Ship via'                    => 'Senda með',
+  'Source'                      => 'Frálag',
+  'Subject'                     => 'Efni',
+  'Subtotal'                    => 'Samtala',
+  'Tax Included'                => 'Taka með VSK',
+  'To'                          => 'til',
+  'Total'                       => 'Samtals',
+  'Unit'                        => 'Einingar',
+  'Update'                      => 'Uppfærsla',
+  'Vendor not on file!'         => 'Byrgir ekki til í gagnagrunni!',
+  'What type of item is this?'  => 'Hvernig hlutur er þetta?',
+  'Yes'                         => 'Já',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendist með rafpósti',
+  'sent to printer'             => 'sendist á prentara',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'Áfram'                       => 'continue',
+  'eyða'                        => 'delete',
+  'r_póstur'                    => 'e_mail',
+  'pöntun'                      => 'order',
+  'bókfæra'                     => 'post',
+  'bókfæra_sem_nýjan'           => 'post_as_new',
+  'prenta'                      => 'print',
+  'senda_til'                   => 'ship_to',
+  'uppfærsla'                   => 'update',
+  'já'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/is/login b/sql-ledger/locale/is/login
new file mode 100644 (file)
index 0000000..2bb761d
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'Um',
+  'Database Host'               => 'Gagnagrunns-netþjónn',
+  'Dataset'                     => 'Gagnasafn',
+  'Incorrect Dataset version!'  => 'Röng útgáfa af gagnasfni!',
+  'Incorrect Password!'         => 'Rangt lykilorð',
+  'Licensed to'                 => 'Skráð á',
+  'Login'                       => 'Tengjast',
+  'Name'                        => 'Nafn',
+  'Password'                    => 'Aðgangsorð',
+  'User'                        => 'Notandi',
+  'Version'                     => 'Útgáfa',
+  'You are logged out!'         => 'Þú ert loggaður út',
+  'You did not enter a name!'   => 'Þú gafst ekki upp nafn',
+  'is not a member!'            => 'er ekki meðlimur!',
+  'localhost'                   => 'lokal',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'tengjast'                    => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/is/menu b/sql-ledger/locale/is/menu
new file mode 100644 (file)
index 0000000..1bfede9
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => 'Innkaupakerfi',
+  'AP Aging'                    => 'Aldursgreining',
+  'AR'                          => 'Sölukerfi',
+  'AR Aging'                    => 'Aldursgreining',
+  'Accounting Menu'             => 'Bókhalds valmynd',
+  'Add Account'                 => 'Nýr reikningur',
+  'Add Assembly'                => 'Ný samsetning',
+  'Add Customer'                => 'Nýr viðskiptavinur',
+  'Add GIFI'                    => 'Ný GIFI',
+  'Add Part'                    => 'Ný vara',
+  'Add Project'                 => 'Nýt verkefni',
+  'Add Service'                 => 'Ný þjónusta',
+  'Add Transaction'             => 'Ný bókhaldsfærsla',
+  'Add Vendor'                  => 'Nýr byrgir',
+  'Assemblies'                  => 'Samsetningar',
+  'Audit Control'               => 'Yfirlit stjórnun',
+  'Backup'                      => 'Afrit',
+  'Balance Sheet'               => 'Staða',
+  'Cash'                        => 'Reiðufé',
+  'Chart of Accounts'           => 'Listi yfir lykkla/reikninga',
+  'Check'                       => 'Ávísun',
+  'Customers'                   => 'Viðskiptavinir',
+  'General Ledger'              => 'Aðalbók',
+  'Goods & Services'            => 'Vörur og þjónusta',
+  'HTML Templates'              => 'HTML-skabalón',
+  'Income Statement'            => 'Inn yfirlýsing',
+  'Invoice'                     => 'Sölureikningur',
+  'LaTeX Templates'             => 'LaTeX-skabalón',
+  'List Accounts'               => 'Sýna lykla',
+  'List GIFI'                   => 'Sýna GIFI',
+  'Logout'                      => 'Aftengjast',
+  'Order Entry'                 => 'Pöntunarblað',
+  'Packing List'                => 'Fylgiseðill',
+  'Parts'                       => 'Vörur',
+  'Payment'                     => 'Greislur',
+  'Payments'                    => 'Greiðslur',
+  'Preferences'                 => 'Uppsetningar',
+  'Projects'                    => 'Verkefni',
+  'Purchase Invoice'            => 'Innkaupsreikningur',
+  'Purchase Order'              => 'Innkaupspöntun',
+  'Purchase Orders'             => 'Innkaupspantanir',
+  'Receipt'                     => 'Kvittun',
+  'Receipts'                    => 'Kvittanir',
+  'Reconciliation'              => 'Afstemingar',
+  'Reports'                     => 'Skýrslur',
+  'Sales Invoice'               => 'Sölureikningur',
+  'Sales Order'                 => 'Sölupöntun',
+  'Sales Orders'                => 'Sölupantanir',
+  'Save to File'                => 'Geyma í skrá',
+  'Send by E-Mail'              => 'Senda með rafpósti',
+  'Services'                    => 'Þjónustur',
+  'Statement'                   => 'Uppgjör',
+  'Stock Assembly'              => 'Lager samsetning',
+  'Stylesheet'                  => 'Stílblað',
+  'System'                      => 'Kerfi',
+  'Tax collected'               => 'VSK samtals',
+  'Tax paid'                    => 'VSK greitt',
+  'Transactions'                => 'Færslur',
+  'Trial Balance'               => 'Prufu staða',
+  'Vendors'                     => 'Byrgjar',
+  'Version'                     => 'Útgáfa',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/is/oe b/sql-ledger/locale/is/oe
new file mode 100644 (file)
index 0000000..9675640
--- /dev/null
@@ -0,0 +1,200 @@
+$self{texts} = {
+  'Add'                         => 'Nýr',
+  'Add Purchase Invoice'        => 'Nýr innkaupsreikningur',
+  'Add Purchase Order'          => 'Ný innkaupspöntun',
+  'Add Sales Invoice'           => 'Nýr sölureikningur',
+  'Add Sales Order'             => 'Ný sölupöntun',
+  'Address'                     => 'Heimilisfang',
+  'Amount'                      => 'Upphæð',
+  'Apr'                         => 'apr',
+  'April'                       => 'apríl',
+  'Are you sure you want to delete Order Number' => 'Ert þú viss um að þú viljir eyða pöntun númer',
+  'Attachment'                  => 'Hjálagt',
+  'Aug'                         => 'ágú',
+  'August'                      => 'ágúst',
+  'Bcc'                         => 'Blint afrit',
+  'Bin'                         => 'Vörulager',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Get ekki eytt pöntun!',
+  'Cannot save order!'          => 'Get ekki geymt pöntun!',
+  'Cc'                          => 'Afrit',
+  'Closed'                      => 'Lokað',
+  'Confirm!'                    => 'Staðfesta!',
+  'Contact'                     => 'Talsmaður',
+  'Continue'                    => 'Áfram',
+  'Copies'                      => 'Afrit',
+  'Credit Limit'                => 'Kreditmörk',
+  'Curr'                        => 'Gjaldm',
+  'Currency'                    => 'Gjaldmiðill',
+  'Customer'                    => 'Viðskiptavinur',
+  'Customer missing!'           => 'Viðskiptavin vantar!',
+  'Customer not on file!'       => 'Viðskiptavinur ekki á skrá!',
+  'Date'                        => 'Dagsetning',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Eyða',
+  'Delivery Date'               => 'Afgreiðsludags.',
+  'Description'                 => 'Skýringar',
+  'E-mail'                      => 'R-póstur',
+  'E-mail address missing!'     => 'R-póst vantar!',
+  'Edit Purchase Order'         => 'Breyta innkaupapöntun',
+  'Edit Sales Order'            => 'Breyta sölupöntun',
+  'Exchangerate'                => 'Vextir',
+  'Exchangerate missing!'       => 'Vantar vexti!',
+  'Extended'                    => 'Framlengt',
+  'Fax'                         => 'Símbréf',
+  'Feb'                         => 'feb',
+  'February'                    => 'febrúar',
+  'From'                        => 'Frá',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Inndregið',
+  'Include in Report'           => 'Innifela í skýrslu',
+  'Invoice'                     => 'Sölureikningur',
+  'Invoice Date missing!'       => 'Sölureiknings dags. vantar!',
+  'Invoice Number missing!'     => 'Sölureikningsnúmer vantar!',
+  'Item not on file!'           => 'Hlutur ekki á skrá!',
+  'Jan'                         => 'jan',
+  'January'                     => 'janúar',
+  'Jul'                         => 'júl',
+  'July'                        => 'júlí',
+  'Jun'                         => 'jún',
+  'June'                        => 'júní',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'maí',
+  'May '                        => 'maí',
+  'Message'                     => 'Skilaboð',
+  'Name'                        => 'Nafn',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Upplýsinar',
+  'Nov'                         => 'nóv',
+  'November'                    => 'nóvember',
+  'Number'                      => 'Númer',
+  'Number missing in Row'       => 'Tölu vantar í röð',
+  'O'                           => 'O',
+  'Oct'                         => 'ókt',
+  'October'                     => 'óktóber',
+  'Open'                        => 'opna',
+  'Order'                       => 'Pöntun',
+  'Order Date'                  => 'Pöntunar dags.',
+  'Order Date missing!'         => 'Pöntunar dags. vantar',
+  'Order Number'                => 'Pöntun númer',
+  'Order Number missing!'       => 'Númer pöntunar vantar',
+  'Order deleted!'              => 'Pöntun eytt',
+  'Order saved!'                => 'Pöntun geymd',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Fylgiseðill',
+  'Packing List Date missing!'  => 'Dags. fylgiseðils vantar!',
+  'Packing List Number missing!' => 'Númer fylgiseðils vantar!',
+  'Part'                        => 'Vara',
+  'Phone'                       => 'Sími.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Verð',
+  'Print'                       => 'Prenta',
+  'Printer'                     => 'Prentari',
+  'Project'                     => 'Verkefni',
+  'Project not on file!'        => 'Verkefni ekki á skrá!',
+  'Purchase Order'              => 'Innkaupspöntun',
+  'Purchase Orders'             => 'Innkaupspantanir',
+  'Qty'                         => 'Magn',
+  'Recd'                        => 'Mótt:',
+  'Remaining'                   => 'Eftir',
+  'Required by'                 => 'Pantað af',
+  'Sales Order'                 => 'Sölupöntun',
+  'Sales Orders'                => 'Sölupantanir',
+  'Save'                        => 'Geyma',
+  'Save as new'                 => 'Geyma sem nýtt',
+  'Screen'                      => 'Skjá',
+  'Select from one of the items below' => 'Veljið einhver að neðangreindum hlutum, og ýtið á "Áfram"',
+  'Select from one of the names below' => 'Veljið einhvað að neðangreindum nöfnum',
+  'Select from one of the projects below' => 'Veljið einhvað að neðangreindum verkefnum',
+  'Select postscript or PDF!'   => 'Veljið postscript eða PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Þjónusta',
+  'Ship'                        => 'Senda',
+  'Ship to'                     => 'Senda til',
+  'Ship via'                    => 'Senda með',
+  'Subject'                     => 'Efni',
+  'Subtotal'                    => 'Samtala',
+  'Tax'                         => 'Virðisaukaskattur',
+  'Tax Included'                => 'Taka með VSK',
+  'Terms: Net'                  => 'Nettó',
+  'To'                          => 'til',
+  'Total'                       => 'Samtals',
+  'Unit'                        => 'Einingar',
+  'Update'                      => 'Uppfærsla',
+  'Vendor'                      => 'Byrgir',
+  'Vendor missing!'             => 'Byrgja vantar!',
+  'Vendor not on file!'         => 'Byrgir ekki til í gagnagrunni!',
+  'What type of item is this?'  => 'Hvernig hlutur er þetta?',
+  'Yes'                         => 'Já',
+  'days'                        => 'dagar',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendist með rafpósti',
+  'sent to printer'             => 'sendist á prentara',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'nýr'                         => 'add',
+  'Áfram'                       => 'continue',
+  'eyða'                        => 'delete',
+  'r_póstur'                    => 'e_mail',
+  'sölureikningur'              => 'invoice',
+  'prenta'                      => 'print',
+  'geyma'                       => 'save',
+  'geyma_sem_nýtt'              => 'save_as_new',
+  'senda_til'                   => 'ship_to',
+  'uppfærsla'                   => 'update',
+  'já'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/is/pe b/sql-ledger/locale/is/pe
new file mode 100644 (file)
index 0000000..38b9169
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Nýr',
+  'Add Project'                 => 'Nýt verkefni',
+  'All'                         => 'Allt',
+  'Continue'                    => 'Áfram',
+  'Delete'                      => 'Eyða',
+  'Description'                 => 'Skýringar',
+  'Edit Project'                => 'Breyta verkefni',
+  'Number'                      => 'Númer',
+  'Orphaned'                    => 'Sjáfstætt',
+  'Project'                     => 'Verkefni',
+  'Project Number missing!'     => 'Verkefnisnúmer vantar!',
+  'Project deleted!'            => 'Verkefni eytt!',
+  'Project saved!'              => 'verkefni geymt!',
+  'Projects'                    => 'Verkefni',
+  'Save'                        => 'Geyma',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'nýr'                         => 'add',
+  'Áfram'                       => 'continue',
+  'eyða'                        => 'delete',
+  'geyma'                       => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/is/rc b/sql-ledger/locale/is/rc
new file mode 100644 (file)
index 0000000..cdd9c82
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Reikningur',
+  'Balance'                     => 'Afstemming',
+  'Cleared Balance'             => 'Hreynsað jafvægi',
+  'Continue'                    => 'Áfram',
+  'Date'                        => 'Dagsetning',
+  'Deposit'                     => 'Innlagt',
+  'Description'                 => 'Skýringar',
+  'Difference'                  => 'Mismunur',
+  'Done'                        => 'Búið',
+  'Exchangerate Difference'     => 'Vaxtamunur',
+  'From'                        => 'Frá',
+  'Out of balance!'             => 'Ekki jafnvægi!',
+  'Payment'                     => 'Greislur',
+  'Reconciliation'              => 'Afstemingar',
+  'Select all'                  => 'Velja allt',
+  'Source'                      => 'Frálag',
+  'Statement Balance'           => 'jöfnunaruppgjör',
+  'Update'                      => 'Uppfærsla',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'Áfram'                       => 'continue',
+  'búið'                        => 'done',
+  'velja_allt'                  => 'select_all',
+  'uppfærsla'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/is/rp b/sql-ledger/locale/is/rp
new file mode 100644 (file)
index 0000000..ba164d8
--- /dev/null
@@ -0,0 +1,120 @@
+$self{texts} = {
+  'AP Aging'                    => 'Aldursgreining',
+  'AR Aging'                    => 'Aldursgreining',
+  'Account'                     => 'Reikningur',
+  'Accounts'                    => 'Reikningar',
+  'Amount'                      => 'Upphæð',
+  'Apr'                         => 'apr',
+  'April'                       => 'apríl',
+  'Attachment'                  => 'Hjálagt',
+  'Aug'                         => 'ágú',
+  'August'                      => 'ágúst',
+  'Balance'                     => 'Afstemming',
+  'Balance Sheet'               => 'Staða',
+  'Bcc'                         => 'Blint afrit',
+  'Cash based'                  => 'Reiðufétengt',
+  'Cc'                          => 'Afrit',
+  'Compare to'                  => 'Bera saman við',
+  'Continue'                    => 'Áfram',
+  'Copies'                      => 'Afrit',
+  'Credit'                      => 'Kredit',
+  'Current'                     => 'Núvirði',
+  'Customer'                    => 'Viðskiptavinur',
+  'Date'                        => 'Dagsetning',
+  'Debit'                       => 'Debit',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Decimalplaces'               => 'Aukastafir',
+  'Department'                  => 'Department',
+  'Description'                 => 'Skýringar',
+  'Due'                         => 'Lokið',
+  'E-mail'                      => 'R-póstur',
+  'E-mail Statement to'         => 'Senda yfirlit til',
+  'Feb'                         => 'feb',
+  'February'                    => 'febrúar',
+  'From'                        => 'Frá',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Yfirskriftir',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Inndregið',
+  'Include in Report'           => 'Innifela í skýrslu',
+  'Income Statement'            => 'Inn yfirlýsing',
+  'Invoice'                     => 'Sölureikningur',
+  'Jan'                         => 'jan',
+  'January'                     => 'janúar',
+  'Jul'                         => 'júl',
+  'July'                        => 'júlí',
+  'Jun'                         => 'jún',
+  'June'                        => 'júní',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'maí',
+  'May '                        => 'maí',
+  'Message'                     => 'Skilaboð',
+  'N/A'                         => 'N/A',
+  'Nothing selected!'           => 'Ekkert valið!',
+  'Nov'                         => 'nóv',
+  'November'                    => 'nóvember',
+  'Oct'                         => 'ókt',
+  'October'                     => 'óktóber',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Greiðslur',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Prenta',
+  'Printer'                     => 'Prentari',
+  'Project Number'              => 'Project Number',
+  'Receipts'                    => 'Kvittanir',
+  'Report for'                  => 'Skýrsla fyrir',
+  'Retained Earnings'           => 'Realiseret overskud',
+  'Screen'                      => 'Skjá',
+  'Select all'                  => 'Velja allt',
+  'Select postscript or PDF!'   => 'Veljið postscript eða PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Source'                      => 'Frálag',
+  'Standard'                    => 'Standart',
+  'Statement'                   => 'Uppgjör',
+  'Statement sent to'           => 'Uppgjör sendist til',
+  'Statements sent to printer!' => 'Uppgjör sendist á prentara',
+  'Subject'                     => 'Efni',
+  'Subtotal'                    => 'Samtala',
+  'Tax'                         => 'Virðisaukaskattur',
+  'Tax collected'               => 'VSK samtals',
+  'Tax paid'                    => 'VSK greitt',
+  'Total'                       => 'Samtals',
+  'Trial Balance'               => 'Prufu staða',
+  'Vendor'                      => 'Byrgir',
+  'as at'                       => 'líkt og með',
+  'collected on sales'          => 'samanlagt við sölu',
+  'for Period'                  => 'fyrir tímabilið',
+  'paid on purchases'           => 'greitt við innkaup',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_accounts'               => 'list_accounts',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'Áfram'                       => 'continue',
+  'r_póstur'                    => 'e_mail',
+  'prenta'                      => 'print',
+  'velja_allt'                  => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/it/COPYING b/sql-ledger/locale/it/COPYING
new file mode 100644 (file)
index 0000000..55c8de3
--- /dev/null
@@ -0,0 +1,25 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Italien texts:
+#
+#  Author: Paolo Bizzarri <p.bizzarri@icube.it>
+#          Luca Venturini <luca@yepa.com>
+#          Alessandro Pasotti <apasotti@isoleborromee.it>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/it/LANGUAGE b/sql-ledger/locale/it/LANGUAGE
new file mode 100644 (file)
index 0000000..4e07e7e
--- /dev/null
@@ -0,0 +1 @@
+Italian
diff --git a/sql-ledger/locale/it/Num2text b/sql-ledger/locale/it/Num2text
new file mode 100644 (file)
index 0000000..fccc1d4
--- /dev/null
@@ -0,0 +1,163 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors: Luca Venturini <luca@yepa.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# this is a variation of the Lingua package
+# written for check and receipt printing
+# it returns a properly formatted text string
+# for a number up to 10**12
+
+sub init {
+  my $self = shift;
+
+  %{ $self->{numbername} } =
+                   (0 => 'Zero',
+                    1 => 'uno',
+                    2 => 'due',
+                   3 => 'tre',
+                   4 => 'quattro',
+                   5 => 'cinque',
+                   6 => 'sei',
+                   7 => 'sette',
+                   8 => 'otto',
+                   9 => 'nove',
+                  10 => 'dieci',
+                  11 => 'undici',
+                  12 => 'dodici',
+                  13 => 'tredici',
+                  14 => 'quattrodici',
+                  15 => 'quindici',
+                  16 => 'sedici',
+                  17 => 'diciassette',
+                  18 => 'diciotto',
+                  19 => 'diciannove',
+                  20 => 'venti',
+                  30 => 'trenta',
+                  40 => 'quaranta',
+                  50 => 'cinquanta',
+                  60 => 'sessanta',
+                  70 => 'settanta',
+                  80 => 'ottanta',
+                  90 => 'novanta',
+                10**2 => 'cento',
+                10**3 => 'mille',
+               10**6 => 'milione',
+               10**9 => 'miliardo',
+              10**12 => 'mille miliardi'
+               );
+
+}
+
+
+sub num2text {
+  my ($self, $amount) = @_;
+
+  return $self->{numbername}{0} unless $amount;
+
+  my @textnumber = ();
+
+  # split amount into chunks of 3
+  my @num = reverse split //, $amount;
+  my @numblock = ();
+  my ($i, $appendn);
+  my @a = ();
+
+  while (@num) {
+    @a = ();
+    for (1 .. 3) {
+      push @a, shift @num;
+    }
+    push @numblock, join / /, reverse @a;
+  }
+  
+  while (@numblock) {
+
+    $i = $#numblock;
+    @num = split //, $numblock[$i];
+    
+    $numblock[$i] *= 1;
+    
+    if ($numblock[$i] == 0) {
+      pop @numblock;
+      next;
+    }
+   
+    if ($numblock[$i] > 99) {
+      # the one from hundreds
+      push @textnumber, $self->{numbername}{$num[0]};
+     
+      # add hundred designation
+      push @textnumber, $self->{numbername}{10**2};
+
+      # reduce numblock
+      $numblock[$i] -= $num[0] * 100;
+    }
+    
+    if ($numblock[$i] > 9) {
+      # tens
+      push @textnumber, $self->format_ten($numblock[$i]);
+    } elsif ($numblock[$i] > 1) {
+      # ones
+      push @textnumber, $self->{numbername}{$numblock[$i]};
+    }
+    
+    # add thousand, million
+    if ($i) {
+      $amount = 10**($i * 3);
+      push @textnumber, $self->{numbername}{$amount};
+    }
+    
+    pop @numblock;
+    
+  }
+
+  join '', @textnumber;
+
+}
+
+
+sub format_ten {
+  my ($self, $amount) = @_;
+  
+  my $textnumber = "";
+  my @num = split //, $amount;
+
+  if ($amount > 20) {
+    if ($num[1] == 0) { 
+      $textnumber = $self->{numbername}{$amount}; 
+    } else {
+       $amount = $num[0] * 10;
+       $textnumber = $self->{numbername}{$amount}.$self->{numbername}{$num[1]};
+      }
+    }
+  } else {
+    $textnumber = $self->{numbername}{$amount};
+  }
+  
+  $textnumber;
+  
+}
+
+
+1;
+
diff --git a/sql-ledger/locale/it/admin b/sql-ledger/locale/it/admin
new file mode 100644 (file)
index 0000000..2294823
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Controllo degli accessi',
+  'Accounting'                  => 'Contabilit&agrave;',
+  'Add User'                    => 'Aggiungi Utente',
+  'Address'                     => 'Indirizzo',
+  'Administration'              => 'Amministrazione',
+  'Administrator'               => 'Amministratore',
+  'All Datasets up to date!'    => 'Tutti i Dataset sono aggiornati!',
+  'Change Admin Password'       => 'Cambia password dell\'amministratore',
+  'Change Password'             => 'Cambia password',
+  'Character Set'               => 'Set di Caratteri',
+  'Click on login name to edit!' => 'Clicca sul nome per effettuare modifiche',
+  'Company'                     => 'Ragione Sociale',
+  'Connect to'                  => 'Connetti a',
+  'Continue'                    => 'Continua',
+  'Create Chart of Accounts'    => 'Crea Piano dei Conti',
+  'Create Dataset'              => 'Crea Dataset',
+  'DBI not installed!'          => 'Modulo DBI non installato',
+  'Database'                    => 'Database',
+  'Database Administration'     => 'Amministratore del Database',
+  'Database Driver not checked!' => 'Il driver del database non e\' stato controllato!',
+  'Database User missing!'      => 'Manca l\'utente del Database!',
+  'Dataset'                     => 'Dataset',
+  'Dataset missing!'            => 'Dataset mancante!',
+  'Dataset updated!'            => 'Dataset aggiornato!',
+  'Date Format'                 => 'Formato della data',
+  'Delete'                      => 'Cancella',
+  'Delete Dataset'              => 'Cancella Dataset',
+  'Directory'                   => 'Directory',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Limite per i menu a discesa',
+  'E-mail'                      => 'E-mail',
+  'Edit User'                   => 'Modifica Utente',
+  'Existing Datasets'           => 'Datasets esistenti',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Manca il nome del server',
+  'Incorrect Password!'         => 'Password sbagliata!',
+  'Language'                    => 'Lingua',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Lascia in bianco il server e la porta a meno che tu non voglia fare una connessione remota',
+  'Login'                       => 'Login',
+  'Multibyte Encoding'          => 'Multibyte Encoding',
+  'Name'                        => 'Nome',
+  'New Templates'               => 'Nuovi Modelli',
+  'No Database Drivers available!' => 'Nessun Database Driver disponibile!',
+  'No Dataset selected!'        => 'Nessun Dataset selezionato!',
+  'Nothing to delete!'          => 'Nulla da cancellare!',
+  'Number Format'               => 'Formato Numerico',
+  'Oracle Database Administration' => 'Amministratore del Database Oracle',
+  'Password'                    => 'Password',
+  'Password changed!'           => 'Password cambiata!',
+  'Pg Database Administration'  => 'Amministratore del Database Pg',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Porta',
+  'Port missing!'               => 'Manca la Porta',
+  'Printer'                     => 'Stampante',
+  'Save'                        => 'Salva',
+  'Select a Dataset to delete and press "Continue"' => 'Seleziona un dataset da cancellare e premi "Continua"',
+  'Setup Templates'             => 'Configurazione dei modelli',
+  'Ship via'                    => 'Porto',
+  'Signature'                   => 'Firma',
+  'Stylesheet'                  => 'Foglio di Stile',
+  'Templates'                   => 'Modelli',
+  'The following Datasets are not in use and can be deleted' => 'I seguenti datasets non sono in uso e possono essere cancellati',
+  'The following Datasets need to be updated' => 'I seguenti datasets devono essere aggiornati',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Questo &egrave; un controllo preliminare per verificare le risorse esistenti. Nulla verr&agrave; creato o cancellato in questa fase!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Per aggiungere un utente ad un gruppo, modifica i dati dell\'utente, cambia lo username e salva. Un nuovo utente con gli stessi dati verr&agrave; salvato con il nuovo username.',
+  'Update Dataset'              => 'Aggiorna il Dataset',
+  'Use Templates'               => 'Usa Modelli',
+  'User'                        => 'Utente',
+  'User deleted!'               => 'Utente cancellato!',
+  'User saved!'                 => 'Utente salvato!',
+  'Version'                     => 'Versione',
+  'You must enter a host and port for local and remote connections!' => 'Devi inserire un server ed una porta per le connessioni locali e remote!',
+  'does not exist'              => 'non esiste',
+  'is already a member!'        => '&egrave; gi&agrave; utente!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'locked!',
+  'successfully created!'       => 'creato!',
+  'successfully deleted!'       => 'cancellato!',
+  'website'                     => 'sito web',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'aggiungi_utente'             => 'add_user',
+  'cambia_password_dell\'amministratore' => 'change_admin_password',
+  'cambia_password'             => 'change_password',
+  'continua'                    => 'continue',
+  'crea_dataset'                => 'create_dataset',
+  'cancella'                    => 'delete',
+  'cancella_dataset'            => 'delete_dataset',
+  'login'                       => 'login',
+  'amministratore_del_database_oracle' => 'oracle_database_administration',
+  'amministratore_del_database_pg' => 'pg_database_administration',
+  'salva'                       => 'save',
+  'aggiorna_il_dataset'         => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/it/all b/sql-ledger/locale/it/all
new file mode 100644 (file)
index 0000000..8f47e6c
--- /dev/null
@@ -0,0 +1,495 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Debiti Fornitori',
+  'AP Aging'                    => 'Partite Aperte',
+  'AP Transaction'              => 'Transazione Fornitore',
+  'AP Transactions'             => 'Transazioni Fornitori',
+  'AR'                          => 'Crediti Clienti',
+  'AR Aging'                    => 'Partite Aperte',
+  'AR Transaction'              => 'Transazione Cliente',
+  'AR Transactions'             => 'Transazioni Clienti',
+  'About'                       => 'Informazioni',
+  'Access Control'              => 'Controllo degli accessi',
+  'Account'                     => 'Conto',
+  'Account Number'              => 'Numero di conto',
+  'Account Number missing!'     => 'Manca il numero di conto!',
+  'Account Type'                => 'Tipo di conto',
+  'Account Type missing!'       => 'Manca il tipo del conto!',
+  'Account deleted!'            => 'Conto cancellato!',
+  'Account saved!'              => 'Conto salvato!',
+  'Accounting'                  => 'Contabilit&agrave;',
+  'Accounting Menu'             => 'Menu Contabilit&agrave;',
+  'Accounts'                    => 'Conti',
+  'Active'                      => 'Attivo',
+  'Add'                         => 'Aggiungi',
+  'Add Account'                 => 'Aggiungi conto',
+  'Add Accounts Payables Transaction' => 'Aggiungi Transazione Fornitori',
+  'Add Accounts Receivables Transaction' => 'Aggiungi Transazione Clienti',
+  'Add Assembly'                => 'Aggiungi Assemblato',
+  'Add Customer'                => 'Aggiungi Cliente',
+  'Add GIFI'                    => 'Aggiungi codice GIFI',
+  'Add General Ledger Transaction' => 'Aggiungi Transazione di Contabilità Generale',
+  'Add Part'                    => 'Aggiungi Articolo',
+  'Add Project'                 => 'Aggiungi Progetto',
+  'Add Purchase Invoice'        => 'Aggiungi Fattura di acquisto',
+  'Add Purchase Order'          => 'Aggiungi Ordine di acquisto',
+  'Add Sales Invoice'           => 'Aggiungi Fattura di vendita',
+  'Add Sales Order'             => 'Aggiungi Ordine di vendita',
+  'Add Service'                 => 'Aggiungi Servizio',
+  'Add Transaction'             => 'Aggiungi Transazione',
+  'Add User'                    => 'Aggiungi Utente',
+  'Add Vendor'                  => 'Aggiungi Fornitore',
+  'Address'                     => 'Indirizzo',
+  'Administration'              => 'Amministrazione',
+  'Administrator'               => 'Amministratore',
+  'All'                         => 'Tutti',
+  'All Datasets up to date!'    => 'Tutti i Dataset sono aggiornati!',
+  'Amount'                      => 'Importo',
+  'Amount Due'                  => 'Importo Dovuto',
+  'Amount does not equal applied!' => 'L\'importo non &egrave; uguale a quanto applicato alle diverse fatture!',
+  'Amount missing!'             => 'Manca l\'importo',
+  'Applied'                     => 'Applicato a',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprile',
+  'Are you sure you want to delete Invoice Number' => 'Sei sicuro di voler cancellare la Fattura numero',
+  'Are you sure you want to delete Order Number' => 'Sei sicuro di voler cancellare l\'ordine numero',
+  'Are you sure you want to delete Transaction' => 'Sei sicuro di voler cancellare la Transazione',
+  'Assemblies'                  => 'Assemblati',
+  'Assemblies restocked!'       => 'Assemblati ricaricati!',
+  'Assembly Number missing!'    => 'Manca il codice dell\'assemblato',
+  'Asset'                       => 'Attivit&agrave;',
+  'Attachment'                  => 'Allegato',
+  'Audit Control'               => 'Controllo accessi',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'BOM'                         => 'BOM',
+  'Backup'                      => 'Backup',
+  'Backup sent to'              => 'Backup inviato a',
+  'Balance'                     => 'Saldo',
+  'Balance Sheet'               => 'Stato Patrimoniale',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Codice BIN',
+  'Books are open'              => 'I conti sono aperti',
+  'Bought'                      => 'Comprato',
+  'Business Number'             => 'Partita IVA',
+  'C'                           => 'C',
+  'COGS'                        => 'Costo dei Beni Venduti',
+  'Cannot delete account!'      => 'Non puoi cancellare il conto!',
+  'Cannot delete customer!'     => 'Non puoi cancellare il cliente!',
+  'Cannot delete default account!' => 'Non puoi cancellare il conto predefinito!',
+  'Cannot delete invoice!'      => 'Non puoi cancellare la fattura!',
+  'Cannot delete item already invoiced!' => 'Non puoi cancellare un articolo gi&agrave; fatturato!',
+  'Cannot delete item on order!' => 'Non puoi cancellare un articolo ordinato!',
+  'Cannot delete item which is part of an assembly!' => 'Non puoi cancellare un articolo che fa parte di un assemblato!',
+  'Cannot delete item!'         => 'Non puoi cancellare l\'articolo',
+  'Cannot delete order!'        => 'Non puoi cancellare l\'ordine',
+  'Cannot delete transaction!'  => 'Non puoi cancellare la transazione',
+  'Cannot delete vendor!'       => 'Non puoi cancellare il fornitore',
+  'Cannot have a value in both Debit and Credit!' => 'Non pu&ograve; esserci un valore sia in Dare che in Avere!',
+  'Cannot post a transaction without a value!' => 'Non puoi salvare una transazione senza un valore!',
+  'Cannot post invoice for a closed period!' => 'Non puoi salvare una transazione per un periodo chiuso!',
+  'Cannot post invoice!'        => 'Non puoi salvare la fattura!',
+  'Cannot post payment for a closed period!' => 'Non puoi salvare pagamenti per un periodo chiuso!',
+  'Cannot post payment!'        => 'Non puoi salvare il pagamento!',
+  'Cannot post transaction for a closed period!' => 'Non puoi salvare una transazione per un periodo chiuso!',
+  'Cannot post transaction!'    => 'Non puoi salvare la transazione!',
+  'Cannot process payment for a closed period!' => 'Non puoi processare un pagamento per un periodo chiuso!',
+  'Cannot save account!'        => 'Non puoi salvare il conto!',
+  'Cannot save order!'          => 'Non puoi salvare l\'ordine!',
+  'Cannot save preferences!'    => 'Non puoi salvare le preferenze!',
+  'Cannot stock assemblies!'    => 'Non puoi caricare gli assemblati!',
+  'Cash'                        => 'Cassa',
+  'Cash based'                  => 'Basato sulla cassa',
+  'Cc'                          => 'Cc',
+  'Change Admin Password'       => 'Cambia password dell\'amministratore',
+  'Change Password'             => 'Cambia password',
+  'Character Set'               => 'Set di Caratteri',
+  'Chart of Accounts'           => 'Piano dei Conti',
+  'Check'                       => 'Assegno',
+  'Check printed!'              => 'Assegno stampato!',
+  'Check printing failed!'      => 'Stampa dell\'assegno fallita!',
+  'Cleared Balance'             => 'Saldo gi&agrave; Conciliato',
+  'Click on login name to edit!' => 'Clicca sul nome per effettuare modifiche',
+  'Close Books up to'           => 'Chiudi i conti fino a',
+  'Closed'                      => 'Chiuso',
+  'Company'                     => 'Ragione Sociale',
+  'Compare to'                  => 'Confronta con',
+  'Confirm!'                    => 'Conferma!',
+  'Connect to'                  => 'Connetti a',
+  'Contact'                     => 'Contatto',
+  'Continue'                    => 'Continua',
+  'Copies'                      => 'Copie',
+  'Copy to COA'                 => 'Inserisci come Conto',
+  'Create Chart of Accounts'    => 'Crea Piano dei Conti',
+  'Create Dataset'              => 'Crea Dataset',
+  'Credit'                      => 'Avere',
+  'Credit Limit'                => 'Fido',
+  'Curr'                        => 'Valuta',
+  'Currency'                    => 'Valuta',
+  'Current'                     => 'Corrente',
+  'Customer'                    => 'Cliente',
+  'Customer deleted!'           => 'Cliente cancellato!',
+  'Customer missing!'           => 'Cliente mancante!',
+  'Customer not on file!'       => 'Cliente non sul file!',
+  'Customer saved!'             => 'Cliente salvato!',
+  'Customers'                   => 'Clienti',
+  'DBI not installed!'          => 'Modulo DBI non installato',
+  'Database'                    => 'Database',
+  'Database Administration'     => 'Amministratore del Database',
+  'Database Driver not checked!' => 'Il driver del database non e\' stato controllato!',
+  'Database Host'               => 'Server',
+  'Database User missing!'      => 'Manca l\'utente del Database!',
+  'Dataset'                     => 'Dataset',
+  'Dataset missing!'            => 'Dataset mancante!',
+  'Dataset updated!'            => 'Dataset aggiornato!',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Data di Scadenza',
+  'Date Format'                 => 'Formato della data',
+  'Date Paid'                   => 'Data di pagamento',
+  'Date missing!'               => 'Manca la data!',
+  'Debit'                       => 'Dare',
+  'Debit and credit out of balance!' => 'Dare e Avere non concordano!.',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Dicembre',
+  'Decimalplaces'               => 'Numero di decimali',
+  'Delete'                      => 'Cancella',
+  'Delete Account'              => 'Cancella Conto',
+  'Delete Dataset'              => 'Cancella Dataset',
+  'Delivery Date'               => 'Data di spedizione',
+  'Department'                  => '',
+  'Deposit'                     => 'Deposito',
+  'Description'                 => 'Descrizione',
+  'Difference'                  => 'Differenza',
+  'Directory'                   => 'Directory',
+  'Discount'                    => 'Sconto',
+  'Done'                        => 'Fatto',
+  'Drawing'                     => 'Disegno',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Limite per i menu a discesa',
+  'Due'                         => 'Dovuto',
+  'Due Date'                    => 'Scadenza Fattura',
+  'Due Date missing!'           => 'Data di Scadenza mancante!',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'Manda il sollecito via e-mail a',
+  'E-mail address missing!'     => 'Indirizzo e-mail mancante!',
+  'Edit'                        => 'Modifica',
+  'Edit Account'                => 'Modifica Conto',
+  'Edit Accounts Payables Transaction' => 'Modifica Transazione Fornitori',
+  'Edit Accounts Receivables Transaction' => 'Modifica Transazione Clienti',
+  'Edit Assembly'               => 'Modifica Assemblato',
+  'Edit Customer'               => '',
+  'Edit GIFI'                   => 'Modifica codice GIFI',
+  'Edit General Ledger Transaction' => 'Modifica Transazione di Contabilit&agrave; Generale',
+  'Edit Part'                   => 'Modifica Articolo',
+  'Edit Preferences for'        => 'Modifica Preferenze di',
+  'Edit Project'                => 'Modifica Progetto',
+  'Edit Purchase Invoice'       => 'Modifica Fattura di acquisto',
+  'Edit Purchase Order'         => 'Modifica Ordine di acquisto',
+  'Edit Sales Invoice'          => 'Modifica Fattura di Vendita',
+  'Edit Sales Order'            => 'Modifica Ordine di vendita',
+  'Edit Service'                => 'Modifica Servizio',
+  'Edit Template'               => 'Modifica Modello',
+  'Edit User'                   => 'Modifica Utente',
+  'Edit Vendor'                 => '',
+  'Employee'                    => 'Dipendente',
+  'Enforce transaction reversal for all dates' => 'Forza l\'uso delle transazioni inverse per tutte le date',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Inserisci fino a 3 valute separate da ":" (es.: EUR:USD:CAD) per la valuta locale e quelle straniere',
+  'Equity'                      => 'Capitale',
+  'Exch'                        => 'Cambio',
+  'Exchangerate'                => 'Tasso di Cambio',
+  'Exchangerate Difference'     => 'Differenza sul Tasso di Cambio',
+  'Exchangerate for payment missing!' => 'Manca il Tasso di Cambio per il pagamento!',
+  'Exchangerate missing!'       => 'Manca il Tasso di Cambio!',
+  'Existing Datasets'           => 'Datasets esistenti',
+  'Expense'                     => 'Uscite',
+  'Expense Account'             => 'Conto Acquisti',
+  'Expense/Asset'               => 'Acquisti/Attivit&agrave;',
+  'Extended'                    => 'Esteso',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febbraio',
+  'Foreign Exchange Gain'       => 'Guadagno da cambio valuta',
+  'Foreign Exchange Loss'       => 'Perdita da cambio valuta',
+  'From'                        => 'Dal',
+  'GIFI'                        => 'Codice GIFI',
+  'GIFI deleted!'               => 'Codice GIFI cancellato!',
+  'GIFI missing!'               => 'Codice GIFI mancante!',
+  'GIFI saved!'                 => 'Codice GIFI salvato!',
+  'GL Transaction'              => 'Transazione di Contabilit&agrave; generale',
+  'General Ledger'              => 'Contabilit&agrave; generale',
+  'Goods & Services'            => 'Beni e Servizi',
+  'HTML Templates'              => 'Modelli HTML',
+  'Heading'                     => 'Intestazione',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Manca il nome del server',
+  'ID'                          => 'ID',
+  'Image'                       => 'Immagine',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Includi nel Prospetto',
+  'Include in drop-down menus'  => 'Da includere nei menu a discesa dei seguenti moduli',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Includere questo conto nei moduli fornitore/cliente per identificare il soggetto come tassabile?',
+  'Income'                      => 'Entrate',
+  'Income Account'              => 'Vendite',
+  'Income Statement'            => 'Conto Economico',
+  'Incorrect Dataset version!'  => 'Versione del Dataset non corretta!',
+  'Incorrect Password!'         => 'Password sbagliata!',
+  'Individual Items'            => 'Articoli Individuali',
+  'Inventory'                   => 'Inventario',
+  'Inventory Account'           => 'Conto Inventario',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'La quantit&agrave; in inventario deve essere zero per poter mettere l\'assemblato come obsoleto!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'La quantit&agrave; in inventario deve essere zero per poter mettere l\'articolo come obsoleto!',
+  'Inventory quantity must be zero!' => 'La quantit&agrave; in inventario deve essere zero!',
+  'Invoice'                     => 'Fattura',
+  'Invoice Date'                => 'Data Fattura',
+  'Invoice Date missing!'       => 'Manca la data della Fattura!',
+  'Invoice Number'              => 'Fattura Numero',
+  'Invoice Number missing!'     => 'Manca il numero della Fattura!',
+  'Invoice deleted!'            => 'Fattura Cancellata!',
+  'Invoice posted!'             => 'Fattura Salvata!',
+  'Invoices'                    => 'Fatture',
+  'Is this a summary account to record' => 'Conto di riferimento del modulo:',
+  'Item deleted!'               => 'Articolo Cancellato!',
+  'Item not on file!'           => 'Articolo non in archivio!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gennaio',
+  'Jul'                         => 'Lug',
+  'July'                        => 'Luglio',
+  'Jun'                         => 'Giu',
+  'June'                        => 'Giugno',
+  'LaTeX Templates'             => 'Modelli LaTeX',
+  'Language'                    => 'Lingua',
+  'Last Cost'                   => 'Ultimo Costo',
+  'Last Invoice Number'         => 'Ultimo Numero di Fattura',
+  'Last Numbers & Default Accounts' => 'Ultimi numeri e Conti di Default',
+  'Last Purchase Order Number'  => 'Ultimo numero d\'ordine di acquisto',
+  'Last Sales Order Number'     => 'Ultimo numero d\'ordine di vendita',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Lascia in bianco il server e la porta a meno che tu non voglia fare una connessione remota',
+  'Liability'                   => 'Passivit&agrave;',
+  'Licensed to'                 => 'Dato in Licenza a',
+  'Line Total'                  => 'Totale Linea',
+  'Link'                        => 'Collegamenti',
+  'Link Accounts'               => 'Collegamenti tra Conti',
+  'List Accounts'               => 'Lista Conti',
+  'List GIFI'                   => 'Lista codici GIFI',
+  'List Price'                  => 'Prezzo di Listino',
+  'List Transactions'           => 'Lista Transazioni',
+  'Login'                       => 'Login',
+  'Logout'                      => 'Logout',
+  'Make'                        => 'Produttore',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'Mag',
+  'May '                        => 'Mag ',
+  'Message'                     => 'Messaggio',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Modello',
+  'Multibyte Encoding'          => '',
+  'N/A'                         => 'N/A',
+  'Name'                        => 'Nome',
+  'Name missing!'               => 'Manca il Nome!',
+  'New Templates'               => 'Nuovi Modelli',
+  'No'                          => 'No',
+  'No Database Drivers available!' => 'Nessun Database Driver disponibile!',
+  'No Dataset selected!'        => 'Nessun Dataset selezionato!',
+  'No email address for'        => 'Manca l\'indirizzo e-mail per',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Note',
+  'Nothing applied!'            => 'Nulla di applicato!',
+  'Nothing selected!'           => 'Non hai selezionato nulla!',
+  'Nothing to delete!'          => 'Nulla da cancellare!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numero',
+  'Number Format'               => 'Formato Numerico',
+  'Number missing in Row'       => 'Manca il codice nella riga',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'Ott',
+  'October'                     => 'Ottobre',
+  'On Hand'                     => 'Disponibilit&agrave;',
+  'On Order'                    => 'Mandato ordine fornitore',
+  'Open'                        => 'Aperto',
+  'Oracle Database Administration' => 'Amministratore del Database Oracle',
+  'Order'                       => 'Ordine',
+  'Order Date'                  => 'Data dell\'ordine',
+  'Order Date missing!'         => 'Manca la data dell\'ordine',
+  'Order Entry'                 => 'Ordini',
+  'Order Number'                => 'Ordine Numero',
+  'Order Number missing!'       => 'Manca il numero dell\'ordine!',
+  'Order deleted!'              => 'Ordine Cancellato!',
+  'Order saved!'                => 'Ordine Salvato!',
+  'Ordered'                     => 'Ricevuto ordine da cliente',
+  'Orphaned'                    => 'Orfano',
+  'Out of balance!'             => 'Non conciliato!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista Etichette',
+  'Packing List Date missing!'  => 'Manca la data della Packing List!',
+  'Packing List Number missing!' => 'Manca il codice della Packing List!',
+  'Paid'                        => 'Importo Pagato',
+  'Paid in full'                => 'Pagato completamente',
+  'Part'                        => 'Articolo',
+  'Part Number missing!'        => 'Manca il Codice dell\'articolo!',
+  'Parts'                       => 'Articoli',
+  'Parts Inventory'             => 'Inventario degli articoli',
+  'Password'                    => 'Password',
+  'Password changed!'           => 'Password cambiata!',
+  'Payables'                    => 'Debiti Fornitori',
+  'Payment'                     => 'Pagamento',
+  'Payment date missing!'       => 'Manca la data del pagamento!',
+  'Payment posted!'             => 'Pagamento Salvato',
+  'Payments'                    => 'Pagamenti',
+  'Pg Database Administration'  => 'Amministratore del Database Pg',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Porta',
+  'Port missing!'               => 'Manca la Porta',
+  'Post'                        => 'Salva',
+  'Post as new'                 => 'Salva come nuovo',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Preferenze',
+  'Preferences saved!'          => 'Preferenze Salvate!',
+  'Price'                       => 'Prezzo',
+  'Print'                       => 'Stampa',
+  'Printer'                     => 'Stampante',
+  'Project'                     => 'Progetto',
+  'Project Number'              => '',
+  'Project Number missing!'     => 'Manca il codice del progetto!',
+  'Project deleted!'            => 'Progetto cancellato!',
+  'Project not on file!'        => 'Progetto non archiviato!',
+  'Project saved!'              => 'Progetto salvato!',
+  'Projects'                    => 'Progetti',
+  'Purchase Invoice'            => 'Fattura di acquisto',
+  'Purchase Order'              => 'Ordine di acquisto',
+  'Purchase Orders'             => 'Ordini di acquisto',
+  'Qty'                         => 'Q.t&agrave;',
+  'ROP'                         => 'Soglia di Riordino',
+  'Rate'                        => 'Tasso',
+  'Recd'                        => 'Ricevuto',
+  'Receipt'                     => 'Incasso',
+  'Receipt printed!'            => '',
+  'Receipt printing failed!'    => '',
+  'Receipts'                    => 'Incassi',
+  'Receivables'                 => 'Crediti Clienti',
+  'Reconciliation'              => 'Conciliazione',
+  'Record in'                   => 'Registra in',
+  'Reference'                   => 'Riferimento',
+  'Reference missing!'          => 'Manca il riferimento!',
+  'Remaining'                   => 'Rimanente',
+  'Report for'                  => 'Prospetto per',
+  'Reports'                     => 'Prospetti',
+  'Required by'                 => 'Necessario dal',
+  'Retained Earnings'           => 'Guadagni',
+  'Sales'                       => 'Vendite',
+  'Sales Invoice'               => 'Fattura di vendita',
+  'Sales Order'                 => 'Ordine di vendita',
+  'Sales Orders'                => 'Ordini di vendita',
+  'Save'                        => 'Salva',
+  'Save as new'                 => 'Salva come nuovo',
+  'Save to File'                => 'Salva su file',
+  'Screen'                      => 'Schermo',
+  'Select a Dataset to delete and press "Continue"' => 'Seleziona un dataset da cancellare e premi "Continua"',
+  'Select all'                  => 'Seleziona tutto',
+  'Select from one of the items below' => 'Seleziona uno dei seguenti Articoli',
+  'Select from one of the names below' => 'Seleziona uno dei seguenti nomi',
+  'Select from one of the projects below' => 'Seleziona uno dei seguenti progetti',
+  'Select postscript or PDF!'   => 'Scegli tra postscript e PDF!',
+  'Sell Price'                  => 'Prezzo di Vendita',
+  'Send by E-Mail'              => 'Spedisci via e-mail',
+  'Sep'                         => 'Set',
+  'September'                   => 'Settembre',
+  'Service'                     => 'Servizio',
+  'Service Items'               => 'Inventario (Servizi)',
+  'Service Number missing!'     => 'Manca il codice del servizio',
+  'Services'                    => 'Servizi',
+  'Setup Templates'             => 'Configurazione dei modelli',
+  'Ship'                        => 'Invio',
+  'Ship to'                     => 'Spedire a',
+  'Ship via'                    => 'Porto',
+  'Short'                       => 'Corto',
+  'Signature'                   => 'Firma',
+  'Sold'                        => 'Venduto',
+  'Source'                      => 'Sorgente',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Sollecito',
+  'Statement Balance'           => 'Saldo',
+  'Statement sent to'           => 'Sollecito mandato a',
+  'Statements sent to printer!' => 'Solleciti mandati in stampa!',
+  'Stock Assembly'              => 'Magazzino Assemblati',
+  'Stylesheet'                  => 'Foglio di Stile',
+  'Subject'                     => 'Oggetto',
+  'Subtotal'                    => 'Totale Parziale',
+  'System'                      => 'Sistema',
+  'Tax'                         => 'Tassa',
+  'Tax Accounts'                => 'Conti relativi a tasse',
+  'Tax Included'                => 'Tasse Incluse',
+  'Tax collected'               => 'Debito IVA',
+  'Tax paid'                    => 'Credito IVA',
+  'Taxable'                     => 'Tassabile',
+  'Template saved!'             => 'Modello salvato!',
+  'Templates'                   => 'Modelli',
+  'Terms: Net'                  => 'Termini: Netto',
+  'The following Datasets are not in use and can be deleted' => 'I seguenti datasets non sono in uso e possono essere cancellati',
+  'The following Datasets need to be updated' => 'I seguenti datasets devono essere aggiornati',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Questo &egrave; un controllo preliminare per verificare le risorse esistenti. Nulla verr&agrave; creato o cancellato in questa fase!',
+  'To'                          => 'Al',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Per aggiungere un utente ad un gruppo, modifica i dati dell\'utente, cambia lo username e salva. Un nuovo utente con gli stessi dati verr&agrave; salvato con il nuovo username.',
+  'Top Level'                   => 'Livello Top',
+  'Total'                       => 'Totale',
+  'Transaction Date missing!'   => 'Manca la data della transazione!',
+  'Transaction deleted!'        => 'Transazione cancellata!',
+  'Transaction posted!'         => 'Transazione salvata!',
+  'Transaction reversal enforced for all dates' => 'Uso delle transazioni inverse forzato per tutte le date',
+  'Transaction reversal enforced up to' => 'Uso delle transazioni inverse forzato fino a',
+  'Transactions'                => 'Transazioni',
+  'Transactions exist, cannot delete customer!' => 'Impossibile cancellare il Cliente: ci sono transazioni a suo nome!',
+  'Transactions exist, cannot delete vendor!' => 'Impossibile cancellare il Fornitore: ci sono transazioni a suo nome!',
+  'Transactions exist; cannot delete account!' => 'Impossibile cancellare il Conto: ci sono transazioni!',
+  'Trial Balance'               => 'Bilancio di Verifica',
+  'Unit'                        => 'Unit&agrave;',
+  'Unit of measure'             => 'Unit&agrave; di misura',
+  'Update'                      => 'Aggiorna',
+  'Update Dataset'              => 'Aggiorna il Dataset',
+  'Updated'                     => 'Aggiornato',
+  'Use Templates'               => 'Usa Modelli',
+  'User'                        => 'Utente',
+  'User deleted!'               => 'Utente cancellato!',
+  'User saved!'                 => 'Utente salvato!',
+  'Vendor'                      => 'Fornitore',
+  'Vendor deleted!'             => 'Fornitore cancellato!',
+  'Vendor missing!'             => 'Manca il fornitore!',
+  'Vendor not on file!'         => 'Fornitore non in archivio!',
+  'Vendor saved!'               => 'Fornitore salvato!',
+  'Vendors'                     => 'Fornitori',
+  'Version'                     => 'Versione',
+  'Weight'                      => 'Peso',
+  'Weight Unit'                 => 'Unit&agrave; di misura',
+  'What type of item is this?'  => 'Che tipo di Articolo &egrave; questo?',
+  'Year End'                    => 'Fine anno',
+  'Yes'                         => 'Si',
+  'You are logged out!'         => 'Sei disconnesso!',
+  'You did not enter a name!'   => 'Non hai inserito il nome!',
+  'You must enter a host and port for local and remote connections!' => 'Devi inserire un server ed una porta per le connessioni locali e remote!',
+  'as at'                       => 'Al',
+  'collected on sales'          => 'incassate su vendite',
+  'days'                        => 'giorni',
+  'does not exist'              => 'non esiste',
+  'ea'                          => 'ci',
+  'emailed to'                  => 'Mandato via e-mail a',
+  'for Period'                  => 'per il Periodo',
+  'hr'                          => 'ore',
+  'is already a member!'        => '&egrave; gi&agrave; utente!',
+  'is not a member!'            => 'non &eacute; un utente!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => '',
+  'paid on purchases'           => 'pagato sugli acquisti',
+  'sent to printer'             => 'mandato in stampa',
+  'successfully created!'       => 'creato!',
+  'successfully deleted!'       => 'cancellato!',
+  'to'                          => 'al',
+  'website'                     => 'sito web',
+};
+
+1;
diff --git a/sql-ledger/locale/it/am b/sql-ledger/locale/it/am
new file mode 100644 (file)
index 0000000..285fa50
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Debiti Fornitori',
+  'AR'                          => 'Crediti Clienti',
+  'Account'                     => 'Conto',
+  'Account Number'              => 'Numero di conto',
+  'Account Number missing!'     => 'Manca il numero di conto!',
+  'Account Type'                => 'Tipo di conto',
+  'Account Type missing!'       => 'Manca il tipo del conto!',
+  'Account deleted!'            => 'Conto cancellato!',
+  'Account saved!'              => 'Conto salvato!',
+  'Add Account'                 => 'Aggiungi conto',
+  'Add GIFI'                    => 'Aggiungi codice GIFI',
+  'Address'                     => 'Indirizzo',
+  'Asset'                       => 'Attivit&agrave;',
+  'Audit Control'               => 'Controllo accessi',
+  'Backup sent to'              => 'Backup inviato a',
+  'Books are open'              => 'I conti sono aperti',
+  'Business Number'             => 'Partita IVA',
+  'COGS'                        => 'Costo dei Beni Venduti',
+  'Cannot delete account!'      => 'Non puoi cancellare il conto!',
+  'Cannot delete default account!' => 'Non puoi cancellare il conto predefinito!',
+  'Cannot save account!'        => 'Non puoi salvare il conto!',
+  'Cannot save preferences!'    => 'Non puoi salvare le preferenze!',
+  'Character Set'               => 'Set di Caratteri',
+  'Chart of Accounts'           => 'Piano dei Conti',
+  'Close Books up to'           => 'Chiudi i conti fino a',
+  'Company'                     => 'Ragione Sociale',
+  'Continue'                    => 'Continua',
+  'Copy to COA'                 => 'Inserisci come Conto',
+  'Credit'                      => 'Avere',
+  'Date Format'                 => 'Formato della data',
+  'Debit'                       => 'Dare',
+  'Delete'                      => 'Cancella',
+  'Delete Account'              => 'Cancella Conto',
+  'Description'                 => 'Descrizione',
+  'Dropdown Limit'              => 'Limite per i menu a discesa',
+  'E-mail'                      => 'E-mail',
+  'Edit'                        => 'Modifica',
+  'Edit Account'                => 'Modifica Conto',
+  'Edit GIFI'                   => 'Modifica codice GIFI',
+  'Edit Preferences for'        => 'Modifica Preferenze di',
+  'Edit Template'               => 'Modifica Modello',
+  'Enforce transaction reversal for all dates' => 'Forza l\'uso delle transazioni inverse per tutte le date',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Inserisci fino a 3 valute separate da ":" (es.: EUR:USD:CAD) per la valuta locale e quelle straniere',
+  'Equity'                      => 'Capitale',
+  'Expense'                     => 'Uscite',
+  'Expense Account'             => 'Conto Acquisti',
+  'Expense/Asset'               => 'Acquisti/Attivit&agrave;',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Guadagno da cambio valuta',
+  'Foreign Exchange Loss'       => 'Perdita da cambio valuta',
+  'GIFI'                        => 'Codice GIFI',
+  'GIFI deleted!'               => 'Codice GIFI cancellato!',
+  'GIFI missing!'               => 'Codice GIFI mancante!',
+  'GIFI saved!'                 => 'Codice GIFI salvato!',
+  'Heading'                     => 'Intestazione',
+  'Include in drop-down menus'  => 'Da includere nei menu a discesa dei seguenti moduli',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Includere questo conto nei moduli fornitore/cliente per identificare il soggetto come tassabile?',
+  'Income'                      => 'Entrate',
+  'Income Account'              => 'Vendite',
+  'Inventory'                   => 'Inventario',
+  'Inventory Account'           => 'Conto Inventario',
+  'Is this a summary account to record' => 'Conto di riferimento del modulo:',
+  'Language'                    => 'Lingua',
+  'Last Invoice Number'         => 'Ultimo Numero di Fattura',
+  'Last Numbers & Default Accounts' => 'Ultimi numeri e Conti di Default',
+  'Last Purchase Order Number'  => 'Ultimo numero d\'ordine di acquisto',
+  'Last Sales Order Number'     => 'Ultimo numero d\'ordine di vendita',
+  'Liability'                   => 'Passivit&agrave;',
+  'Link'                        => 'Collegamenti',
+  'Name'                        => 'Nome',
+  'No'                          => 'No',
+  'No email address for'        => 'Manca l\'indirizzo e-mail per',
+  'Number'                      => 'Numero',
+  'Number Format'               => 'Formato Numerico',
+  'Parts Inventory'             => 'Inventario degli articoli',
+  'Password'                    => 'Password',
+  'Payables'                    => 'Debiti Fornitori',
+  'Payment'                     => 'Pagamento',
+  'Phone'                       => 'Tel.',
+  'Preferences saved!'          => 'Preferenze Salvate!',
+  'Rate'                        => 'Tasso',
+  'Receivables'                 => 'Crediti Clienti',
+  'Sales'                       => 'Vendite',
+  'Save'                        => 'Salva',
+  'Service Items'               => 'Inventario (Servizi)',
+  'Ship via'                    => 'Porto',
+  'Signature'                   => 'Firma',
+  'Stylesheet'                  => 'Foglio di Stile',
+  'Tax'                         => 'Tassa',
+  'Tax Accounts'                => 'Conti relativi a tasse',
+  'Template saved!'             => 'Modello salvato!',
+  'Transaction reversal enforced for all dates' => 'Uso delle transazioni inverse forzato per tutte le date',
+  'Transaction reversal enforced up to' => 'Uso delle transazioni inverse forzato fino a',
+  'Transactions exist; cannot delete account!' => 'Impossibile cancellare il Conto: ci sono transazioni!',
+  'Weight Unit'                 => 'Unit&agrave; di misura',
+  'Year End'                    => 'Fine anno',
+  'Yes'                         => 'Si',
+  'does not exist'              => 'non esiste',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'aggiungi_conto'              => 'add_account',
+  'continua'                    => 'continue',
+  'inserisci_come_conto'        => 'copy_to_coa',
+  'cancella'                    => 'delete',
+  'modifica'                    => 'edit',
+  'modifica_conto'              => 'edit_account',
+  'salva'                       => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/it/ap b/sql-ledger/locale/it/ap
new file mode 100644 (file)
index 0000000..3b57b5c
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Transazione Fornitore',
+  'AP Transactions'             => 'Transazioni Fornitori',
+  'Account'                     => 'Conto',
+  'Add Accounts Payables Transaction' => 'Aggiungi Transazione Fornitori',
+  'Address'                     => 'Indirizzo',
+  'Amount'                      => 'Importo',
+  'Amount Due'                  => 'Importo Dovuto',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprile',
+  'Are you sure you want to delete Transaction' => 'Sei sicuro di voler cancellare la Transazione',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Cannot delete transaction!'  => 'Non puoi cancellare la transazione',
+  'Cannot post payment for a closed period!' => 'Non puoi salvare pagamenti per un periodo chiuso!',
+  'Cannot post transaction for a closed period!' => 'Non puoi salvare una transazione per un periodo chiuso!',
+  'Cannot post transaction!'    => 'Non puoi salvare la transazione!',
+  'Closed'                      => 'Chiuso',
+  'Confirm!'                    => 'Conferma!',
+  'Continue'                    => 'Continua',
+  'Currency'                    => 'Valuta',
+  'Customer not on file!'       => 'Cliente non sul file!',
+  'Date'                        => 'Data',
+  'Date Paid'                   => 'Data di pagamento',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Dicembre',
+  'Delete'                      => 'Cancella',
+  'Description'                 => 'Descrizione',
+  'Due Date'                    => 'Scadenza Fattura',
+  'Due Date missing!'           => 'Data di Scadenza mancante!',
+  'Edit Accounts Payables Transaction' => 'Modifica Transazione Fornitori',
+  'Employee'                    => 'Dipendente',
+  'Exch'                        => 'Cambio',
+  'Exchangerate'                => 'Tasso di Cambio',
+  'Exchangerate for payment missing!' => 'Manca il Tasso di Cambio per il pagamento!',
+  'Exchangerate missing!'       => 'Manca il Tasso di Cambio!',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febbraio',
+  'From'                        => 'Dal',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Includi nel Prospetto',
+  'Invoice'                     => 'Fattura',
+  'Invoice Date'                => 'Data Fattura',
+  'Invoice Date missing!'       => 'Manca la data della Fattura!',
+  'Invoice Number'              => 'Fattura Numero',
+  'Invoice Number missing!'     => 'Manca il numero della Fattura!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gennaio',
+  'Jul'                         => 'Lug',
+  'July'                        => 'Luglio',
+  'Jun'                         => 'Giu',
+  'June'                        => 'Giugno',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'Mag',
+  'May '                        => 'Mag ',
+  'Notes'                       => 'Note',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numero',
+  'Oct'                         => 'Ott',
+  'October'                     => 'Ottobre',
+  'Open'                        => 'Aperto',
+  'Order'                       => 'Ordine',
+  'Order Number'                => 'Ordine Numero',
+  'Paid'                        => 'Importo Pagato',
+  'Payment date missing!'       => 'Manca la data del pagamento!',
+  'Payments'                    => 'Pagamenti',
+  'Post'                        => 'Salva',
+  'Post as new'                 => 'Salva come nuovo',
+  'Project'                     => 'Progetto',
+  'Project not on file!'        => 'Progetto non archiviato!',
+  'Purchase Invoice'            => 'Fattura di acquisto',
+  'Select from one of the names below' => 'Seleziona uno dei seguenti nomi',
+  'Select from one of the projects below' => 'Seleziona uno dei seguenti progetti',
+  'Sep'                         => 'Set',
+  'September'                   => 'Settembre',
+  'Source'                      => 'Sorgente',
+  'Subtotal'                    => 'Totale Parziale',
+  'Tax'                         => 'Tassa',
+  'Tax Included'                => 'Tasse Incluse',
+  'Total'                       => 'Totale',
+  'Transaction deleted!'        => 'Transazione cancellata!',
+  'Transaction posted!'         => 'Transazione salvata!',
+  'Update'                      => 'Aggiorna',
+  'Vendor'                      => 'Fornitore',
+  'Vendor missing!'             => 'Manca il fornitore!',
+  'Vendor not on file!'         => 'Fornitore non in archivio!',
+  'Yes'                         => 'Si',
+  'to'                          => 'al',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'transazione_fornitore'       => 'ap_transaction',
+  'aggiungi_transazione_fornitori' => 'add_accounts_payables_transaction',
+  'continua'                    => 'continue',
+  'cancella'                    => 'delete',
+  'modifica_transazione_fornitori' => 'edit_accounts_payables_transaction',
+  'salva'                       => 'post',
+  'salva_come_nuovo'            => 'post_as_new',
+  'fattura_di_acquisto'         => 'purchase_invoice',
+  'aggiorna'                    => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/it/ar b/sql-ledger/locale/it/ar
new file mode 100644 (file)
index 0000000..301d421
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'Transazione Cliente',
+  'AR Transactions'             => 'Transazioni Clienti',
+  'Account'                     => 'Conto',
+  'Add Accounts Receivables Transaction' => 'Aggiungi Transazione Clienti',
+  'Address'                     => 'Indirizzo',
+  'Amount'                      => 'Importo',
+  'Amount Due'                  => 'Importo Dovuto',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprile',
+  'Are you sure you want to delete Transaction' => 'Sei sicuro di voler cancellare la Transazione',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Cannot delete transaction!'  => 'Non puoi cancellare la transazione',
+  'Cannot post payment for a closed period!' => 'Non puoi salvare pagamenti per un periodo chiuso!',
+  'Cannot post transaction for a closed period!' => 'Non puoi salvare una transazione per un periodo chiuso!',
+  'Cannot post transaction!'    => 'Non puoi salvare la transazione!',
+  'Closed'                      => 'Chiuso',
+  'Confirm!'                    => 'Conferma!',
+  'Continue'                    => 'Continua',
+  'Credit Limit'                => 'Fido',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Cliente mancante!',
+  'Customer not on file!'       => 'Cliente non sul file!',
+  'Date'                        => 'Data',
+  'Date Paid'                   => 'Data di pagamento',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Dicembre',
+  'Delete'                      => 'Cancella',
+  'Description'                 => 'Descrizione',
+  'Due Date'                    => 'Scadenza Fattura',
+  'Due Date missing!'           => 'Data di Scadenza mancante!',
+  'Edit Accounts Receivables Transaction' => 'Modifica Transazione Clienti',
+  'Employee'                    => 'Dipendente',
+  'Exch'                        => 'Cambio',
+  'Exchangerate'                => 'Tasso di Cambio',
+  'Exchangerate for payment missing!' => 'Manca il Tasso di Cambio per il pagamento!',
+  'Exchangerate missing!'       => 'Manca il Tasso di Cambio!',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febbraio',
+  'From'                        => 'Dal',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Includi nel Prospetto',
+  'Invoice'                     => 'Fattura',
+  'Invoice Date'                => 'Data Fattura',
+  'Invoice Date missing!'       => 'Manca la data della Fattura!',
+  'Invoice Number'              => 'Fattura Numero',
+  'Invoice Number missing!'     => 'Manca il numero della Fattura!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gennaio',
+  'Jul'                         => 'Lug',
+  'July'                        => 'Luglio',
+  'Jun'                         => 'Giu',
+  'June'                        => 'Giugno',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'Mag',
+  'May '                        => 'Mag ',
+  'Notes'                       => 'Note',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numero',
+  'Oct'                         => 'Ott',
+  'October'                     => 'Ottobre',
+  'Open'                        => 'Aperto',
+  'Order'                       => 'Ordine',
+  'Order Number'                => 'Ordine Numero',
+  'Paid'                        => 'Importo Pagato',
+  'Payment date missing!'       => 'Manca la data del pagamento!',
+  'Payments'                    => 'Pagamenti',
+  'Post'                        => 'Salva',
+  'Post as new'                 => 'Salva come nuovo',
+  'Project'                     => 'Progetto',
+  'Project not on file!'        => 'Progetto non archiviato!',
+  'Remaining'                   => 'Rimanente',
+  'Sales Invoice'               => 'Fattura di vendita',
+  'Select from one of the names below' => 'Seleziona uno dei seguenti nomi',
+  'Select from one of the projects below' => 'Seleziona uno dei seguenti progetti',
+  'Sep'                         => 'Set',
+  'September'                   => 'Settembre',
+  'Source'                      => 'Sorgente',
+  'Subtotal'                    => 'Totale Parziale',
+  'Tax'                         => 'Tassa',
+  'Tax Included'                => 'Tasse Incluse',
+  'Total'                       => 'Totale',
+  'Transaction deleted!'        => 'Transazione cancellata!',
+  'Transaction posted!'         => 'Transazione salvata!',
+  'Update'                      => 'Aggiorna',
+  'Vendor not on file!'         => 'Fornitore non in archivio!',
+  'Yes'                         => 'Si',
+  'to'                          => 'al',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'transazione_cliente'         => 'ar_transaction',
+  'continua'                    => 'continue',
+  'cancella'                    => 'delete',
+  'salva'                       => 'post',
+  'salva_come_nuovo'            => 'post_as_new',
+  'fattura_di_vendita'          => 'sales_invoice',
+  'aggiorna'                    => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/it/arap b/sql-ledger/locale/it/arap
new file mode 100644 (file)
index 0000000..57651a9
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Indirizzo',
+  'Continue'                    => 'Continua',
+  'Customer not on file!'       => 'Cliente non sul file!',
+  'Description'                 => 'Descrizione',
+  'Number'                      => 'Numero',
+  'Project not on file!'        => 'Progetto non archiviato!',
+  'Select from one of the names below' => 'Seleziona uno dei seguenti nomi',
+  'Select from one of the projects below' => 'Seleziona uno dei seguenti progetti',
+  'Vendor not on file!'         => 'Fornitore non in archivio!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'continua'                    => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/it/ca b/sql-ledger/locale/it/ca
new file mode 100644 (file)
index 0000000..1fdc01d
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Conto',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprile',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Saldo',
+  'Chart of Accounts'           => 'Piano dei Conti',
+  'Credit'                      => 'Avere',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Dare',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Dicembre',
+  'Description'                 => 'Descrizione',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febbraio',
+  'From'                        => 'Dal',
+  'GIFI'                        => 'Codice GIFI',
+  'Include in Report'           => 'Includi nel Prospetto',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gennaio',
+  'Jul'                         => 'Lug',
+  'July'                        => 'Luglio',
+  'Jun'                         => 'Giu',
+  'June'                        => 'Giugno',
+  'List Transactions'           => 'Lista Transazioni',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'Mag',
+  'May '                        => 'Mag ',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Oct'                         => 'Ott',
+  'October'                     => 'Ottobre',
+  'Reference'                   => 'Riferimento',
+  'Sep'                         => 'Set',
+  'September'                   => 'Settembre',
+  'Subtotal'                    => 'Totale Parziale',
+  'to'                          => 'al',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'lista_transazioni'           => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/it/cp b/sql-ledger/locale/it/cp
new file mode 100644 (file)
index 0000000..3dacb5f
--- /dev/null
@@ -0,0 +1,77 @@
+$self{texts} = {
+  'Account'                     => 'Conto',
+  'Address'                     => 'Indirizzo',
+  'Amount'                      => 'Importo',
+  'Amount does not equal applied!' => 'L\'importo non &egrave; uguale a quanto applicato alle diverse fatture!',
+  'Amount missing!'             => 'Manca l\'importo',
+  'Applied'                     => 'Applicato a',
+  'Cannot post payment!'        => 'Non puoi salvare il pagamento!',
+  'Cannot process payment for a closed period!' => 'Non puoi processare un pagamento per un periodo chiuso!',
+  'Check'                       => 'Assegno',
+  'Check printed!'              => 'Assegno stampato!',
+  'Check printing failed!'      => 'Stampa dell\'assegno fallita!',
+  'Continue'                    => 'Continua',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Cliente',
+  'Customer not on file!'       => 'Cliente non sul file!',
+  'Date'                        => 'Data',
+  'Date missing!'               => 'Manca la data!',
+  'Description'                 => 'Descrizione',
+  'Due'                         => 'Dovuto',
+  'Exchangerate'                => 'Tasso di Cambio',
+  'From'                        => 'Dal',
+  'Invoice'                     => 'Fattura',
+  'Invoices'                    => 'Fatture',
+  'Nothing applied!'            => 'Nulla di applicato!',
+  'Number'                      => 'Numero',
+  'Paid in full'                => 'Pagato completamente',
+  'Payment'                     => 'Pagamento',
+  'Payment posted!'             => 'Pagamento Salvato',
+  'Post'                        => 'Salva',
+  'Print'                       => 'Stampa',
+  'Printer'                     => 'Stampante',
+  'Project not on file!'        => 'Progetto non archiviato!',
+  'Receipt'                     => 'Incasso',
+  'Receipt printed!'            => 'Receipt printed!',
+  'Receipt printing failed!'    => 'Receipt printing failed!',
+  'Reference'                   => 'Riferimento',
+  'Screen'                      => 'Schermo',
+  'Select from one of the names below' => 'Seleziona uno dei seguenti nomi',
+  'Select from one of the projects below' => 'Seleziona uno dei seguenti progetti',
+  'Update'                      => 'Aggiorna',
+  'Vendor'                      => 'Fornitore',
+  'Vendor not on file!'         => 'Fornitore non in archivio!',
+  'to'                          => 'al',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'continua'                    => 'continue',
+  'salva'                       => 'post',
+  'stampa'                      => 'print',
+  'aggiorna'                    => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/it/ct b/sql-ledger/locale/it/ct
new file mode 100644 (file)
index 0000000..12bfa6e
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Aggiungi',
+  'Address'                     => 'Indirizzo',
+  'All'                         => 'Tutti',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Non puoi cancellare il cliente!',
+  'Cannot delete vendor!'       => 'Non puoi cancellare il fornitore',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contatto',
+  'Continue'                    => 'Continua',
+  'Credit Limit'                => 'Fido',
+  'Customer deleted!'           => 'Cliente cancellato!',
+  'Customer saved!'             => 'Cliente salvato!',
+  'Customers'                   => 'Clienti',
+  'Delete'                      => 'Cancella',
+  'Discount'                    => 'Sconto',
+  'E-mail'                      => 'E-mail',
+  'Edit Customer'               => 'Edit Customer',
+  'Edit Vendor'                 => 'Edit Vendor',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Includi nel Prospetto',
+  'Invoice'                     => 'Fattura',
+  'Name'                        => 'Nome',
+  'Name missing!'               => 'Manca il Nome!',
+  'Notes'                       => 'Note',
+  'Number'                      => 'Numero',
+  'Order'                       => 'Ordine',
+  'Orphaned'                    => 'Orfano',
+  'Phone'                       => 'Tel.',
+  'Save'                        => 'Salva',
+  'Ship to'                     => 'Spedire a',
+  'Tax Included'                => 'Tasse Incluse',
+  'Taxable'                     => 'Tassabile',
+  'Terms: Net'                  => 'Termini: Netto',
+  'Transactions exist, cannot delete customer!' => 'Impossibile cancellare il Cliente: ci sono transazioni a suo nome!',
+  'Transactions exist, cannot delete vendor!' => 'Impossibile cancellare il Fornitore: ci sono transazioni a suo nome!',
+  'Vendor deleted!'             => 'Fornitore cancellato!',
+  'Vendor saved!'               => 'Fornitore salvato!',
+  'Vendors'                     => 'Fornitori',
+  'days'                        => 'giorni',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'aggiungi'                    => 'add',
+  'continua'                    => 'continue',
+  'cancella'                    => 'delete',
+  'fattura'                     => 'invoice',
+  'ordine'                      => 'order',
+  'salva'                       => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/it/gl b/sql-ledger/locale/it/gl
new file mode 100644 (file)
index 0000000..087fb3e
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Transazione Fornitore',
+  'AR Transaction'              => 'Transazione Cliente',
+  'Account'                     => 'Conto',
+  'Add General Ledger Transaction' => 'Aggiungi Transazione di Contabilità Generale',
+  'Address'                     => 'Indirizzo',
+  'All'                         => 'Tutti',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprile',
+  'Are you sure you want to delete Transaction' => 'Sei sicuro di voler cancellare la Transazione',
+  'Asset'                       => 'Attivit&agrave;',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Saldo',
+  'Cannot delete transaction!'  => 'Non puoi cancellare la transazione',
+  'Cannot have a value in both Debit and Credit!' => 'Non pu&ograve; esserci un valore sia in Dare che in Avere!',
+  'Cannot post a transaction without a value!' => 'Non puoi salvare una transazione senza un valore!',
+  'Cannot post transaction for a closed period!' => 'Non puoi salvare una transazione per un periodo chiuso!',
+  'Confirm!'                    => 'Conferma!',
+  'Continue'                    => 'Continua',
+  'Credit'                      => 'Avere',
+  'Customer not on file!'       => 'Cliente non sul file!',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Dare',
+  'Debit and credit out of balance!' => 'Dare e Avere non concordano!.',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Dicembre',
+  'Delete'                      => 'Cancella',
+  'Description'                 => 'Descrizione',
+  'Edit General Ledger Transaction' => 'Modifica Transazione di Contabilit&agrave; Generale',
+  'Equity'                      => 'Capitale',
+  'Expense'                     => 'Uscite',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febbraio',
+  'From'                        => 'Dal',
+  'GIFI'                        => 'Codice GIFI',
+  'GL Transaction'              => 'Transazione di Contabilit&agrave; generale',
+  'General Ledger'              => 'Contabilit&agrave; generale',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Includi nel Prospetto',
+  'Income'                      => 'Entrate',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gennaio',
+  'Jul'                         => 'Lug',
+  'July'                        => 'Luglio',
+  'Jun'                         => 'Giu',
+  'June'                        => 'Giugno',
+  'Liability'                   => 'Passivit&agrave;',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'Mag',
+  'May '                        => 'Mag ',
+  'Notes'                       => 'Note',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numero',
+  'Oct'                         => 'Ott',
+  'October'                     => 'Ottobre',
+  'Post'                        => 'Salva',
+  'Post as new'                 => 'Salva come nuovo',
+  'Project'                     => 'Progetto',
+  'Project not on file!'        => 'Progetto non archiviato!',
+  'Purchase Invoice'            => 'Fattura di acquisto',
+  'Reference'                   => 'Riferimento',
+  'Reference missing!'          => 'Manca il riferimento!',
+  'Reports'                     => 'Prospetti',
+  'Sales Invoice'               => 'Fattura di vendita',
+  'Select from one of the names below' => 'Seleziona uno dei seguenti nomi',
+  'Select from one of the projects below' => 'Seleziona uno dei seguenti progetti',
+  'Sep'                         => 'Set',
+  'September'                   => 'Settembre',
+  'Source'                      => 'Sorgente',
+  'Subtotal'                    => 'Totale Parziale',
+  'Transaction Date missing!'   => 'Manca la data della transazione!',
+  'Transaction deleted!'        => 'Transazione cancellata!',
+  'Transaction posted!'         => 'Transazione salvata!',
+  'Update'                      => 'Aggiorna',
+  'Vendor not on file!'         => 'Fornitore non in archivio!',
+  'Yes'                         => 'Si',
+  'to'                          => 'al',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'transazione_fornitore'       => 'ap_transaction',
+  'transazione_cliente'         => 'ar_transaction',
+  'continua'                    => 'continue',
+  'cancella'                    => 'delete',
+  'transazione_di_contabilit&agrave;_generale' => 'gl_transaction',
+  'salva'                       => 'post',
+  'salva_come_nuovo'            => 'post_as_new',
+  'fattura_di_acquisto'         => 'purchase_invoice',
+  'fattura_di_vendita'          => 'sales_invoice',
+  'aggiorna'                    => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/it/ic b/sql-ledger/locale/it/ic
new file mode 100644 (file)
index 0000000..2f0dc95
--- /dev/null
@@ -0,0 +1,206 @@
+$self{texts} = {
+  'Active'                      => 'Attivo',
+  'Add'                         => 'Aggiungi',
+  'Add Assembly'                => 'Aggiungi Assemblato',
+  'Add Part'                    => 'Aggiungi Articolo',
+  'Add Purchase Order'          => 'Aggiungi Ordine di acquisto',
+  'Add Sales Order'             => 'Aggiungi Ordine di vendita',
+  'Add Service'                 => 'Aggiungi Servizio',
+  'Address'                     => 'Indirizzo',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprile',
+  'Assemblies'                  => 'Assemblati',
+  'Assemblies restocked!'       => 'Assemblati ricaricati!',
+  'Assembly Number missing!'    => 'Manca il codice dell\'assemblato',
+  'Attachment'                  => 'Allegato',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Codice BIN',
+  'Bought'                      => 'Comprato',
+  'COGS'                        => 'Costo dei Beni Venduti',
+  'Cannot delete item already invoiced!' => 'Non puoi cancellare un articolo gi&agrave; fatturato!',
+  'Cannot delete item on order!' => 'Non puoi cancellare un articolo ordinato!',
+  'Cannot delete item which is part of an assembly!' => 'Non puoi cancellare un articolo che fa parte di un assemblato!',
+  'Cannot delete item!'         => 'Non puoi cancellare l\'articolo',
+  'Cannot stock assemblies!'    => 'Non puoi caricare gli assemblati!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contatto',
+  'Continue'                    => 'Continua',
+  'Copies'                      => 'Copie',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Dicembre',
+  'Delete'                      => 'Cancella',
+  'Delivery Date'               => 'Data di spedizione',
+  'Description'                 => 'Descrizione',
+  'Drawing'                     => 'Disegno',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Indirizzo e-mail mancante!',
+  'Edit Assembly'               => 'Modifica Assemblato',
+  'Edit Part'                   => 'Modifica Articolo',
+  'Edit Service'                => 'Modifica Servizio',
+  'Expense'                     => 'Uscite',
+  'Extended'                    => 'Esteso',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febbraio',
+  'From'                        => 'Dal',
+  'Image'                       => 'Immagine',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Includi nel Prospetto',
+  'Income'                      => 'Entrate',
+  'Individual Items'            => 'Articoli Individuali',
+  'Inventory'                   => 'Inventario',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'La quantit&agrave; in inventario deve essere zero per poter mettere l\'assemblato come obsoleto!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'La quantit&agrave; in inventario deve essere zero per poter mettere l\'articolo come obsoleto!',
+  'Inventory quantity must be zero!' => 'La quantit&agrave; in inventario deve essere zero!',
+  'Invoice'                     => 'Fattura',
+  'Invoice Date missing!'       => 'Manca la data della Fattura!',
+  'Invoice Number'              => 'Fattura Numero',
+  'Invoice Number missing!'     => 'Manca il numero della Fattura!',
+  'Item deleted!'               => 'Articolo Cancellato!',
+  'Item not on file!'           => 'Articolo non in archivio!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gennaio',
+  'Jul'                         => 'Lug',
+  'July'                        => 'Luglio',
+  'Jun'                         => 'Giu',
+  'June'                        => 'Giugno',
+  'Last Cost'                   => 'Ultimo Costo',
+  'Line Total'                  => 'Totale Linea',
+  'Link Accounts'               => 'Collegamenti tra Conti',
+  'List Price'                  => 'Prezzo di Listino',
+  'Make'                        => 'Produttore',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'Mag',
+  'May '                        => 'Mag ',
+  'Message'                     => 'Messaggio',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Modello',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Note',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numero',
+  'Number missing in Row'       => 'Manca il codice nella riga',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'Ott',
+  'October'                     => 'Ottobre',
+  'On Hand'                     => 'Disponibilit&agrave;',
+  'On Order'                    => 'Mandato ordine fornitore',
+  'Order'                       => 'Ordine',
+  'Order Date missing!'         => 'Manca la data dell\'ordine',
+  'Order Number'                => 'Ordine Numero',
+  'Order Number missing!'       => 'Manca il numero dell\'ordine!',
+  'Ordered'                     => 'Ricevuto ordine da cliente',
+  'Orphaned'                    => 'Orfano',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista Etichette',
+  'Packing List Date missing!'  => 'Manca la data della Packing List!',
+  'Packing List Number missing!' => 'Manca il codice della Packing List!',
+  'Part'                        => 'Articolo',
+  'Part Number missing!'        => 'Manca il Codice dell\'articolo!',
+  'Parts'                       => 'Articoli',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Prezzo',
+  'Printer'                     => 'Stampante',
+  'Project'                     => 'Progetto',
+  'Purchase Order'              => 'Ordine di acquisto',
+  'Qty'                         => 'Q.t&agrave;',
+  'ROP'                         => 'Soglia di Riordino',
+  'Recd'                        => 'Ricevuto',
+  'Required by'                 => 'Necessario dal',
+  'Sales'                       => 'Vendite',
+  'Sales Order'                 => 'Ordine di vendita',
+  'Save'                        => 'Salva',
+  'Screen'                      => 'Schermo',
+  'Select from one of the items below' => 'Seleziona uno dei seguenti Articoli',
+  'Select postscript or PDF!'   => 'Scegli tra postscript e PDF!',
+  'Sell Price'                  => 'Prezzo di Vendita',
+  'Sep'                         => 'Set',
+  'September'                   => 'Settembre',
+  'Service'                     => 'Servizio',
+  'Service Number missing!'     => 'Manca il codice del servizio',
+  'Services'                    => 'Servizi',
+  'Ship'                        => 'Invio',
+  'Ship to'                     => 'Spedire a',
+  'Short'                       => 'Corto',
+  'Sold'                        => 'Venduto',
+  'Stock Assembly'              => 'Magazzino Assemblati',
+  'Subject'                     => 'Oggetto',
+  'Subtotal'                    => 'Totale Parziale',
+  'Tax'                         => 'Tassa',
+  'To'                          => 'Al',
+  'Top Level'                   => 'Livello Top',
+  'Total'                       => 'Totale',
+  'Unit'                        => 'Unit&agrave;',
+  'Unit of measure'             => 'Unit&agrave; di misura',
+  'Update'                      => 'Aggiorna',
+  'Updated'                     => 'Aggiornato',
+  'Weight'                      => 'Peso',
+  'What type of item is this?'  => 'Che tipo di Articolo &egrave; questo?',
+  'ea'                          => 'ci',
+  'emailed to'                  => 'Mandato via e-mail a',
+  'hr'                          => 'ore',
+  'sent to printer'             => 'mandato in stampa',
+  'to'                          => 'al',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'aggiungi'                    => 'add',
+  'aggiungi_assemblato'         => 'add_assembly',
+  'aggiungi_articolo'           => 'add_part',
+  'aggiungi_servizio'           => 'add_service',
+  'continua'                    => 'continue',
+  'cancella'                    => 'delete',
+  'modifica_assemblato'         => 'edit_assembly',
+  'modifica_articolo'           => 'edit_part',
+  'modifica_servizio'           => 'edit_service',
+  'salva'                       => 'save',
+  'aggiorna'                    => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/it/io b/sql-ledger/locale/it/io
new file mode 100644 (file)
index 0000000..2914945
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Aggiungi Ordine di acquisto',
+  'Add Sales Order'             => 'Aggiungi Ordine di vendita',
+  'Address'                     => 'Indirizzo',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprile',
+  'Attachment'                  => 'Allegato',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Codice BIN',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contatto',
+  'Continue'                    => 'Continua',
+  'Copies'                      => 'Copie',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Dicembre',
+  'Delivery Date'               => 'Data di spedizione',
+  'Description'                 => 'Descrizione',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Indirizzo e-mail mancante!',
+  'Extended'                    => 'Esteso',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febbraio',
+  'In-line'                     => 'In-line',
+  'Invoice'                     => 'Fattura',
+  'Invoice Date missing!'       => 'Manca la data della Fattura!',
+  'Invoice Number missing!'     => 'Manca il numero della Fattura!',
+  'Item not on file!'           => 'Articolo non in archivio!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gennaio',
+  'Jul'                         => 'Lug',
+  'July'                        => 'Luglio',
+  'Jun'                         => 'Giu',
+  'June'                        => 'Giugno',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'Mag',
+  'May '                        => 'Mag ',
+  'Message'                     => 'Messaggio',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numero',
+  'Number missing in Row'       => 'Manca il codice nella riga',
+  'Oct'                         => 'Ott',
+  'October'                     => 'Ottobre',
+  'Order'                       => 'Ordine',
+  'Order Date missing!'         => 'Manca la data dell\'ordine',
+  'Order Number missing!'       => 'Manca il numero dell\'ordine!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista Etichette',
+  'Packing List Date missing!'  => 'Manca la data della Packing List!',
+  'Packing List Number missing!' => 'Manca il codice della Packing List!',
+  'Part'                        => 'Articolo',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Prezzo',
+  'Printer'                     => 'Stampante',
+  'Project'                     => 'Progetto',
+  'Purchase Order'              => 'Ordine di acquisto',
+  'Qty'                         => 'Q.t&agrave;',
+  'Recd'                        => 'Ricevuto',
+  'Required by'                 => 'Necessario dal',
+  'Sales Order'                 => 'Ordine di vendita',
+  'Screen'                      => 'Schermo',
+  'Select from one of the items below' => 'Seleziona uno dei seguenti Articoli',
+  'Select postscript or PDF!'   => 'Scegli tra postscript e PDF!',
+  'Sep'                         => 'Set',
+  'September'                   => 'Settembre',
+  'Service'                     => 'Servizio',
+  'Ship'                        => 'Invio',
+  'Ship to'                     => 'Spedire a',
+  'Subject'                     => 'Oggetto',
+  'To'                          => 'Al',
+  'Unit'                        => 'Unit&agrave;',
+  'What type of item is this?'  => 'Che tipo di Articolo &egrave; questo?',
+  'emailed to'                  => 'Mandato via e-mail a',
+  'sent to printer'             => 'mandato in stampa',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'continua'                    => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/it/ir b/sql-ledger/locale/it/ir
new file mode 100644 (file)
index 0000000..242142e
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Conto',
+  'Add Purchase Invoice'        => 'Aggiungi Fattura di acquisto',
+  'Add Purchase Order'          => 'Aggiungi Ordine di acquisto',
+  'Add Sales Order'             => 'Aggiungi Ordine di vendita',
+  'Address'                     => 'Indirizzo',
+  'Amount'                      => 'Importo',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprile',
+  'Are you sure you want to delete Invoice Number' => 'Sei sicuro di voler cancellare la Fattura numero',
+  'Attachment'                  => 'Allegato',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Codice BIN',
+  'Cannot delete invoice!'      => 'Non puoi cancellare la fattura!',
+  'Cannot post invoice for a closed period!' => 'Non puoi salvare una transazione per un periodo chiuso!',
+  'Cannot post invoice!'        => 'Non puoi salvare la fattura!',
+  'Cannot post payment for a closed period!' => 'Non puoi salvare pagamenti per un periodo chiuso!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Conferma!',
+  'Contact'                     => 'Contatto',
+  'Continue'                    => 'Continua',
+  'Copies'                      => 'Copie',
+  'Currency'                    => 'Valuta',
+  'Customer not on file!'       => 'Cliente non sul file!',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Data di Scadenza',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Dicembre',
+  'Delete'                      => 'Cancella',
+  'Delivery Date'               => 'Data di spedizione',
+  'Description'                 => 'Descrizione',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Indirizzo e-mail mancante!',
+  'Edit Purchase Invoice'       => 'Modifica Fattura di acquisto',
+  'Exch'                        => 'Cambio',
+  'Exchangerate'                => 'Tasso di Cambio',
+  'Exchangerate for payment missing!' => 'Manca il Tasso di Cambio per il pagamento!',
+  'Exchangerate missing!'       => 'Manca il Tasso di Cambio!',
+  'Extended'                    => 'Esteso',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febbraio',
+  'In-line'                     => 'In-line',
+  'Invoice'                     => 'Fattura',
+  'Invoice Date'                => 'Data Fattura',
+  'Invoice Date missing!'       => 'Manca la data della Fattura!',
+  'Invoice Number'              => 'Fattura Numero',
+  'Invoice Number missing!'     => 'Manca il numero della Fattura!',
+  'Invoice deleted!'            => 'Fattura Cancellata!',
+  'Invoice posted!'             => 'Fattura Salvata!',
+  'Item not on file!'           => 'Articolo non in archivio!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gennaio',
+  'Jul'                         => 'Lug',
+  'July'                        => 'Luglio',
+  'Jun'                         => 'Giu',
+  'June'                        => 'Giugno',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'Mag',
+  'May '                        => 'Mag ',
+  'Message'                     => 'Messaggio',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Note',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numero',
+  'Number missing in Row'       => 'Manca il codice nella riga',
+  'Oct'                         => 'Ott',
+  'October'                     => 'Ottobre',
+  'Order'                       => 'Ordine',
+  'Order Date missing!'         => 'Manca la data dell\'ordine',
+  'Order Number'                => 'Ordine Numero',
+  'Order Number missing!'       => 'Manca il numero dell\'ordine!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista Etichette',
+  'Packing List Date missing!'  => 'Manca la data della Packing List!',
+  'Packing List Number missing!' => 'Manca il codice della Packing List!',
+  'Part'                        => 'Articolo',
+  'Payment date missing!'       => 'Manca la data del pagamento!',
+  'Payments'                    => 'Pagamenti',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Salva',
+  'Post as new'                 => 'Salva come nuovo',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Prezzo',
+  'Printer'                     => 'Stampante',
+  'Project'                     => 'Progetto',
+  'Project not on file!'        => 'Progetto non archiviato!',
+  'Purchase Order'              => 'Ordine di acquisto',
+  'Qty'                         => 'Q.t&agrave;',
+  'Recd'                        => 'Ricevuto',
+  'Record in'                   => 'Registra in',
+  'Required by'                 => 'Necessario dal',
+  'Sales Order'                 => 'Ordine di vendita',
+  'Screen'                      => 'Schermo',
+  'Select from one of the items below' => 'Seleziona uno dei seguenti Articoli',
+  'Select from one of the names below' => 'Seleziona uno dei seguenti nomi',
+  'Select from one of the projects below' => 'Seleziona uno dei seguenti progetti',
+  'Select postscript or PDF!'   => 'Scegli tra postscript e PDF!',
+  'Sep'                         => 'Set',
+  'September'                   => 'Settembre',
+  'Service'                     => 'Servizio',
+  'Ship'                        => 'Invio',
+  'Ship to'                     => 'Spedire a',
+  'Source'                      => 'Sorgente',
+  'Subject'                     => 'Oggetto',
+  'Subtotal'                    => 'Totale Parziale',
+  'Tax Included'                => 'Tasse Incluse',
+  'To'                          => 'Al',
+  'Total'                       => 'Totale',
+  'Unit'                        => 'Unit&agrave;',
+  'Update'                      => 'Aggiorna',
+  'Vendor'                      => 'Fornitore',
+  'Vendor missing!'             => 'Manca il fornitore!',
+  'Vendor not on file!'         => 'Fornitore non in archivio!',
+  'What type of item is this?'  => 'Che tipo di Articolo &egrave; questo?',
+  'Yes'                         => 'Si',
+  'ea'                          => 'ci',
+  'emailed to'                  => 'Mandato via e-mail a',
+  'sent to printer'             => 'mandato in stampa',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continua'                    => 'continue',
+  'cancella'                    => 'delete',
+  'ordine'                      => 'order',
+  'salva'                       => 'post',
+  'salva_come_nuovo'            => 'post_as_new',
+  'aggiorna'                    => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/it/is b/sql-ledger/locale/it/is
new file mode 100644 (file)
index 0000000..beb9593
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Conto',
+  'Add Purchase Order'          => 'Aggiungi Ordine di acquisto',
+  'Add Sales Invoice'           => 'Aggiungi Fattura di vendita',
+  'Add Sales Order'             => 'Aggiungi Ordine di vendita',
+  'Address'                     => 'Indirizzo',
+  'Amount'                      => 'Importo',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprile',
+  'Are you sure you want to delete Invoice Number' => 'Sei sicuro di voler cancellare la Fattura numero',
+  'Attachment'                  => 'Allegato',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Codice BIN',
+  'Cannot delete invoice!'      => 'Non puoi cancellare la fattura!',
+  'Cannot post invoice for a closed period!' => 'Non puoi salvare una transazione per un periodo chiuso!',
+  'Cannot post invoice!'        => 'Non puoi salvare la fattura!',
+  'Cannot post payment for a closed period!' => 'Non puoi salvare pagamenti per un periodo chiuso!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Conferma!',
+  'Contact'                     => 'Contatto',
+  'Continue'                    => 'Continua',
+  'Copies'                      => 'Copie',
+  'Credit Limit'                => 'Fido',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Cliente mancante!',
+  'Customer not on file!'       => 'Cliente non sul file!',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Data di Scadenza',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Dicembre',
+  'Delete'                      => 'Cancella',
+  'Delivery Date'               => 'Data di spedizione',
+  'Description'                 => 'Descrizione',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Indirizzo e-mail mancante!',
+  'Edit Sales Invoice'          => 'Modifica Fattura di Vendita',
+  'Exch'                        => 'Cambio',
+  'Exchangerate'                => 'Tasso di Cambio',
+  'Exchangerate for payment missing!' => 'Manca il Tasso di Cambio per il pagamento!',
+  'Exchangerate missing!'       => 'Manca il Tasso di Cambio!',
+  'Extended'                    => 'Esteso',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febbraio',
+  'In-line'                     => 'In-line',
+  'Invoice'                     => 'Fattura',
+  'Invoice Date'                => 'Data Fattura',
+  'Invoice Date missing!'       => 'Manca la data della Fattura!',
+  'Invoice Number'              => 'Fattura Numero',
+  'Invoice Number missing!'     => 'Manca il numero della Fattura!',
+  'Invoice deleted!'            => 'Fattura Cancellata!',
+  'Invoice posted!'             => 'Fattura Salvata!',
+  'Item not on file!'           => 'Articolo non in archivio!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gennaio',
+  'Jul'                         => 'Lug',
+  'July'                        => 'Luglio',
+  'Jun'                         => 'Giu',
+  'June'                        => 'Giugno',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'Mag',
+  'May '                        => 'Mag ',
+  'Message'                     => 'Messaggio',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Note',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numero',
+  'Number missing in Row'       => 'Manca il codice nella riga',
+  'Oct'                         => 'Ott',
+  'October'                     => 'Ottobre',
+  'Order'                       => 'Ordine',
+  'Order Date missing!'         => 'Manca la data dell\'ordine',
+  'Order Number'                => 'Ordine Numero',
+  'Order Number missing!'       => 'Manca il numero dell\'ordine!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista Etichette',
+  'Packing List Date missing!'  => 'Manca la data della Packing List!',
+  'Packing List Number missing!' => 'Manca il codice della Packing List!',
+  'Part'                        => 'Articolo',
+  'Payment date missing!'       => 'Manca la data del pagamento!',
+  'Payments'                    => 'Pagamenti',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Salva',
+  'Post as new'                 => 'Salva come nuovo',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Prezzo',
+  'Print'                       => 'Stampa',
+  'Printer'                     => 'Stampante',
+  'Project'                     => 'Progetto',
+  'Project not on file!'        => 'Progetto non archiviato!',
+  'Purchase Order'              => 'Ordine di acquisto',
+  'Qty'                         => 'Q.t&agrave;',
+  'Recd'                        => 'Ricevuto',
+  'Record in'                   => 'Registra in',
+  'Remaining'                   => 'Rimanente',
+  'Required by'                 => 'Necessario dal',
+  'Sales Order'                 => 'Ordine di vendita',
+  'Screen'                      => 'Schermo',
+  'Select from one of the items below' => 'Seleziona uno dei seguenti Articoli',
+  'Select from one of the names below' => 'Seleziona uno dei seguenti nomi',
+  'Select from one of the projects below' => 'Seleziona uno dei seguenti progetti',
+  'Select postscript or PDF!'   => 'Scegli tra postscript e PDF!',
+  'Sep'                         => 'Set',
+  'September'                   => 'Settembre',
+  'Service'                     => 'Servizio',
+  'Ship'                        => 'Invio',
+  'Ship to'                     => 'Spedire a',
+  'Ship via'                    => 'Porto',
+  'Source'                      => 'Sorgente',
+  'Subject'                     => 'Oggetto',
+  'Subtotal'                    => 'Totale Parziale',
+  'Tax Included'                => 'Tasse Incluse',
+  'To'                          => 'Al',
+  'Total'                       => 'Totale',
+  'Unit'                        => 'Unit&agrave;',
+  'Update'                      => 'Aggiorna',
+  'Vendor not on file!'         => 'Fornitore non in archivio!',
+  'What type of item is this?'  => 'Che tipo di Articolo &egrave; questo?',
+  'Yes'                         => 'Si',
+  'ea'                          => 'ci',
+  'emailed to'                  => 'Mandato via e-mail a',
+  'sent to printer'             => 'mandato in stampa',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continua'                    => 'continue',
+  'cancella'                    => 'delete',
+  'e_mail'                      => 'e_mail',
+  'ordine'                      => 'order',
+  'salva'                       => 'post',
+  'salva_come_nuovo'            => 'post_as_new',
+  'stampa'                      => 'print',
+  'spedire_a'                   => 'ship_to',
+  'aggiorna'                    => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/it/login b/sql-ledger/locale/it/login
new file mode 100644 (file)
index 0000000..aaca32d
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'Informazioni',
+  'Database Host'               => 'Server',
+  'Dataset'                     => 'Dataset',
+  'Incorrect Dataset version!'  => 'Versione del Dataset non corretta!',
+  'Incorrect Password!'         => 'Password sbagliata!',
+  'Licensed to'                 => 'Dato in Licenza a',
+  'Login'                       => 'Login',
+  'Name'                        => 'Nome',
+  'Password'                    => 'Password',
+  'User'                        => 'Utente',
+  'Version'                     => 'Versione',
+  'You are logged out!'         => 'Sei disconnesso!',
+  'You did not enter a name!'   => 'Non hai inserito il nome!',
+  'is not a member!'            => 'non &eacute; un utente!',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'login'                       => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/it/menu b/sql-ledger/locale/it/menu
new file mode 100644 (file)
index 0000000..58ed36a
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => 'Debiti Fornitori',
+  'AP Aging'                    => 'Partite Aperte',
+  'AR'                          => 'Crediti Clienti',
+  'AR Aging'                    => 'Partite Aperte',
+  'Accounting Menu'             => 'Menu Contabilit&agrave;',
+  'Add Account'                 => 'Aggiungi conto',
+  'Add Assembly'                => 'Aggiungi Assemblato',
+  'Add Customer'                => 'Aggiungi Cliente',
+  'Add GIFI'                    => 'Aggiungi codice GIFI',
+  'Add Part'                    => 'Aggiungi Articolo',
+  'Add Project'                 => 'Aggiungi Progetto',
+  'Add Service'                 => 'Aggiungi Servizio',
+  'Add Transaction'             => 'Aggiungi Transazione',
+  'Add Vendor'                  => 'Aggiungi Fornitore',
+  'Assemblies'                  => 'Assemblati',
+  'Audit Control'               => 'Controllo accessi',
+  'Backup'                      => 'Backup',
+  'Balance Sheet'               => 'Stato Patrimoniale',
+  'Cash'                        => 'Cassa',
+  'Chart of Accounts'           => 'Piano dei Conti',
+  'Check'                       => 'Assegno',
+  'Customers'                   => 'Clienti',
+  'General Ledger'              => 'Contabilit&agrave; generale',
+  'Goods & Services'            => 'Beni e Servizi',
+  'HTML Templates'              => 'Modelli HTML',
+  'Income Statement'            => 'Conto Economico',
+  'Invoice'                     => 'Fattura',
+  'LaTeX Templates'             => 'Modelli LaTeX',
+  'List Accounts'               => 'Lista Conti',
+  'List GIFI'                   => 'Lista codici GIFI',
+  'Logout'                      => 'Logout',
+  'Order Entry'                 => 'Ordini',
+  'Packing List'                => 'Lista Etichette',
+  'Parts'                       => 'Articoli',
+  'Payment'                     => 'Pagamento',
+  'Payments'                    => 'Pagamenti',
+  'Preferences'                 => 'Preferenze',
+  'Projects'                    => 'Progetti',
+  'Purchase Invoice'            => 'Fattura di acquisto',
+  'Purchase Order'              => 'Ordine di acquisto',
+  'Purchase Orders'             => 'Ordini di acquisto',
+  'Receipt'                     => 'Incasso',
+  'Receipts'                    => 'Incassi',
+  'Reconciliation'              => 'Conciliazione',
+  'Reports'                     => 'Prospetti',
+  'Sales Invoice'               => 'Fattura di vendita',
+  'Sales Order'                 => 'Ordine di vendita',
+  'Sales Orders'                => 'Ordini di vendita',
+  'Save to File'                => 'Salva su file',
+  'Send by E-Mail'              => 'Spedisci via e-mail',
+  'Services'                    => 'Servizi',
+  'Statement'                   => 'Sollecito',
+  'Stock Assembly'              => 'Magazzino Assemblati',
+  'Stylesheet'                  => 'Foglio di Stile',
+  'System'                      => 'Sistema',
+  'Tax collected'               => 'Debito IVA',
+  'Tax paid'                    => 'Credito IVA',
+  'Transactions'                => 'Transazioni',
+  'Trial Balance'               => 'Bilancio di Verifica',
+  'Vendors'                     => 'Fornitori',
+  'Version'                     => 'Versione',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/it/oe b/sql-ledger/locale/it/oe
new file mode 100644 (file)
index 0000000..b14d61b
--- /dev/null
@@ -0,0 +1,200 @@
+$self{texts} = {
+  'Add'                         => 'Aggiungi',
+  'Add Purchase Invoice'        => 'Aggiungi Fattura di acquisto',
+  'Add Purchase Order'          => 'Aggiungi Ordine di acquisto',
+  'Add Sales Invoice'           => 'Aggiungi Fattura di vendita',
+  'Add Sales Order'             => 'Aggiungi Ordine di vendita',
+  'Address'                     => 'Indirizzo',
+  'Amount'                      => 'Importo',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprile',
+  'Are you sure you want to delete Order Number' => 'Sei sicuro di voler cancellare l\'ordine numero',
+  'Attachment'                  => 'Allegato',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Codice BIN',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Non puoi cancellare l\'ordine',
+  'Cannot save order!'          => 'Non puoi salvare l\'ordine!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Chiuso',
+  'Confirm!'                    => 'Conferma!',
+  'Contact'                     => 'Contatto',
+  'Continue'                    => 'Continua',
+  'Copies'                      => 'Copie',
+  'Credit Limit'                => 'Fido',
+  'Curr'                        => 'Valuta',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Cliente mancante!',
+  'Customer not on file!'       => 'Cliente non sul file!',
+  'Date'                        => 'Data',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Dicembre',
+  'Delete'                      => 'Cancella',
+  'Delivery Date'               => 'Data di spedizione',
+  'Description'                 => 'Descrizione',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Indirizzo e-mail mancante!',
+  'Edit Purchase Order'         => 'Modifica Ordine di acquisto',
+  'Edit Sales Order'            => 'Modifica Ordine di vendita',
+  'Exchangerate'                => 'Tasso di Cambio',
+  'Exchangerate missing!'       => 'Manca il Tasso di Cambio!',
+  'Extended'                    => 'Esteso',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febbraio',
+  'From'                        => 'Dal',
+  'ID'                          => 'ID',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Includi nel Prospetto',
+  'Invoice'                     => 'Fattura',
+  'Invoice Date missing!'       => 'Manca la data della Fattura!',
+  'Invoice Number missing!'     => 'Manca il numero della Fattura!',
+  'Item not on file!'           => 'Articolo non in archivio!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gennaio',
+  'Jul'                         => 'Lug',
+  'July'                        => 'Luglio',
+  'Jun'                         => 'Giu',
+  'June'                        => 'Giugno',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'Mag',
+  'May '                        => 'Mag ',
+  'Message'                     => 'Messaggio',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Note',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Numero',
+  'Number missing in Row'       => 'Manca il codice nella riga',
+  'O'                           => 'O',
+  'Oct'                         => 'Ott',
+  'October'                     => 'Ottobre',
+  'Open'                        => 'Aperto',
+  'Order'                       => 'Ordine',
+  'Order Date'                  => 'Data dell\'ordine',
+  'Order Date missing!'         => 'Manca la data dell\'ordine',
+  'Order Number'                => 'Ordine Numero',
+  'Order Number missing!'       => 'Manca il numero dell\'ordine!',
+  'Order deleted!'              => 'Ordine Cancellato!',
+  'Order saved!'                => 'Ordine Salvato!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista Etichette',
+  'Packing List Date missing!'  => 'Manca la data della Packing List!',
+  'Packing List Number missing!' => 'Manca il codice della Packing List!',
+  'Part'                        => 'Articolo',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Prezzo',
+  'Print'                       => 'Stampa',
+  'Printer'                     => 'Stampante',
+  'Project'                     => 'Progetto',
+  'Project not on file!'        => 'Progetto non archiviato!',
+  'Purchase Order'              => 'Ordine di acquisto',
+  'Purchase Orders'             => 'Ordini di acquisto',
+  'Qty'                         => 'Q.t&agrave;',
+  'Recd'                        => 'Ricevuto',
+  'Remaining'                   => 'Rimanente',
+  'Required by'                 => 'Necessario dal',
+  'Sales Order'                 => 'Ordine di vendita',
+  'Sales Orders'                => 'Ordini di vendita',
+  'Save'                        => 'Salva',
+  'Save as new'                 => 'Salva come nuovo',
+  'Screen'                      => 'Schermo',
+  'Select from one of the items below' => 'Seleziona uno dei seguenti Articoli',
+  'Select from one of the names below' => 'Seleziona uno dei seguenti nomi',
+  'Select from one of the projects below' => 'Seleziona uno dei seguenti progetti',
+  'Select postscript or PDF!'   => 'Scegli tra postscript e PDF!',
+  'Sep'                         => 'Set',
+  'September'                   => 'Settembre',
+  'Service'                     => 'Servizio',
+  'Ship'                        => 'Invio',
+  'Ship to'                     => 'Spedire a',
+  'Ship via'                    => 'Porto',
+  'Subject'                     => 'Oggetto',
+  'Subtotal'                    => 'Totale Parziale',
+  'Tax'                         => 'Tassa',
+  'Tax Included'                => 'Tasse Incluse',
+  'Terms: Net'                  => 'Termini: Netto',
+  'To'                          => 'Al',
+  'Total'                       => 'Totale',
+  'Unit'                        => 'Unit&agrave;',
+  'Update'                      => 'Aggiorna',
+  'Vendor'                      => 'Fornitore',
+  'Vendor missing!'             => 'Manca il fornitore!',
+  'Vendor not on file!'         => 'Fornitore non in archivio!',
+  'What type of item is this?'  => 'Che tipo di Articolo &egrave; questo?',
+  'Yes'                         => 'Si',
+  'days'                        => 'giorni',
+  'ea'                          => 'ci',
+  'emailed to'                  => 'Mandato via e-mail a',
+  'sent to printer'             => 'mandato in stampa',
+  'to'                          => 'al',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'aggiungi'                    => 'add',
+  'continua'                    => 'continue',
+  'cancella'                    => 'delete',
+  'e_mail'                      => 'e_mail',
+  'fattura'                     => 'invoice',
+  'stampa'                      => 'print',
+  'salva'                       => 'save',
+  'salva_come_nuovo'            => 'save_as_new',
+  'spedire_a'                   => 'ship_to',
+  'aggiorna'                    => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/it/pe b/sql-ledger/locale/it/pe
new file mode 100644 (file)
index 0000000..c37877b
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Aggiungi',
+  'Add Project'                 => 'Aggiungi Progetto',
+  'All'                         => 'Tutti',
+  'Continue'                    => 'Continua',
+  'Delete'                      => 'Cancella',
+  'Description'                 => 'Descrizione',
+  'Edit Project'                => 'Modifica Progetto',
+  'Number'                      => 'Numero',
+  'Orphaned'                    => 'Orfano',
+  'Project'                     => 'Progetto',
+  'Project Number missing!'     => 'Manca il codice del progetto!',
+  'Project deleted!'            => 'Progetto cancellato!',
+  'Project saved!'              => 'Progetto salvato!',
+  'Projects'                    => 'Progetti',
+  'Save'                        => 'Salva',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'aggiungi'                    => 'add',
+  'continua'                    => 'continue',
+  'cancella'                    => 'delete',
+  'salva'                       => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/it/qe b/sql-ledger/locale/it/qe
new file mode 100644 (file)
index 0000000..67da640
--- /dev/null
@@ -0,0 +1,199 @@
+$self{texts} = {
+  'Add'                         => 'Aggiungi',
+  'Add Purchase Invoice'        => 'Aggiungi Fattura di acquisto',
+  'Add Purchase Order'          => 'Aggiungi Ordine di acquisto',
+  'Add Sales Invoice'           => 'Aggiungi Fattura di vendita',
+  'Add Sales Order'             => 'Aggiungi Ordine di vendita',
+  'Address'                     => 'Indirizzo',
+  'Amount'                      => 'Importo',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprile',
+  'Are you sure you want to delete Order Number' => 'Sei sicuro di volre cancellare l\'ordine numero',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Codice BIN',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Non puoi cancellare l\'ordine',
+  'Cannot save order!'          => 'Non puoi salvare l\'ordine!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Chiuso',
+  'Confirm!'                    => 'Conferma!',
+  'Contact'                     => 'Contatto',
+  'Continue'                    => 'Continua',
+  'Copies'                      => 'Copie',
+  'Credit Limit'                => 'Fido',
+  'Curr'                        => 'Valuta',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Cliente mancante!',
+  'Customer not on file!'       => 'Cliente non sul file!',
+  'Date'                        => 'Data',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Dicembre',
+  'Delete'                      => 'Cancella',
+  'Delivery Date'               => 'Data di spedizione',
+  'Description'                 => 'Descrizione',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Indirizzo e-mail mancante!',
+  'Edit Purchase Order'         => 'Modifica Ordine di acquisto',
+  'Edit Sales Order'            => 'Modifica Ordine di vendita',
+  'Exchangerate'                => 'Tasso di Cambio',
+  'Exchangerate missing!'       => 'Manca il Tasso di Cambio!',
+  'Extended'                    => 'Esteso',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febbraio',
+  'From'                        => 'Dal',
+  'ID'                          => 'ID',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Includi nel Prospetto',
+  'Invoice'                     => 'Fattura',
+  'Invoice Date missing!'       => 'Manca la data della Fattura!',
+  'Invoice Number missing!'     => 'Manca il numero della Fattura!',
+  'Item not on file!'           => 'Articolo non in archivio!',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gennaio',
+  'Jul'                         => 'Lug',
+  'July'                        => 'Luglio',
+  'Jun'                         => 'Giu',
+  'June'                        => 'Giugno',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'Mag',
+  'May '                        => 'Mag ',
+  'Message'                     => 'Messaggio',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Note',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Number'                      => 'Partita IVA',
+  'Number missing in Row'       => 'Manca il codice nella riga',
+  'O'                           => 'O',
+  'Oct'                         => 'Ott',
+  'October'                     => 'Ottobre',
+  'Open'                        => 'Aperto',
+  'Order'                       => 'Ordine',
+  'Order Date'                  => 'Data dell\'ordine',
+  'Order Date missing!'         => 'Manca la data dell\'ordine',
+  'Order Number'                => 'Ordine Numero',
+  'Order Number missing!'       => 'Manca il numero dell\'ordine!',
+  'Order deleted!'              => 'Ordine Cancellato!',
+  'Order saved!'                => 'Ordine Salvato!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista Etichette',
+  'Packing List Date missing!'  => 'Manca la data della Packing List!',
+  'Packing List Number missing!' => 'Manca il codice della Packing List!',
+  'Part'                        => 'Articolo',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Prezzo',
+  'Print'                       => 'Stampa',
+  'Printer'                     => 'Stampante',
+  'Project'                     => 'Progetto',
+  'Project not on file!'        => 'Progetto non archiviato!',
+  'Purchase Order'              => 'Ordine di acquisto',
+  'Purchase Orders'             => 'Ordini di acquisto',
+  'Qty'                         => 'Q.t&agrave;',
+  'Recd'                        => 'Ricevuto',
+  'Remaining'                   => 'Rimanente',
+  'Required by'                 => 'Necessario dal',
+  'Sales Order'                 => 'Ordine di vendita',
+  'Sales Orders'                => 'Ordini di vendita',
+  'Save'                        => 'Salva',
+  'Save as new'                 => 'Salva come nuovo',
+  'Screen'                      => 'Schermo',
+  'Select from one of the items below' => 'Seleziona uno dei seguenti Articoli',
+  'Select from one of the names below' => 'Seleziona uno dei seguenti nomi',
+  'Select from one of the projects below' => 'Seleziona uno dei seguenti progetti',
+  'Select postscript or PDF!'   => 'Scegli tra postscript e PDF!',
+  'Sep'                         => 'Set',
+  'September'                   => 'Settembre',
+  'Service'                     => 'Servizio',
+  'Ship'                        => 'Invio',
+  'Ship to'                     => 'Spedire a',
+  'Ship via'                    => 'Porto',
+  'Subject'                     => 'Oggetto',
+  'Subtotal'                    => 'Totale Parziale',
+  'Tax'                         => 'Tassa',
+  'Tax Included'                => 'Tasse Incluse',
+  'Terms: Net'                  => 'Termini: Netto',
+  'To'                          => 'Al',
+  'Total'                       => 'Totale',
+  'Unit'                        => 'Unit&agrave;',
+  'Update'                      => 'Aggiorna',
+  'Vendor'                      => 'Fornitore',
+  'Vendor missing!'             => 'Manca il fornitore!',
+  'Vendor not on file!'         => 'Fornitore non in archivio!',
+  'What type of item is this?'  => 'Che tipo di Articolo &egrave; questo?',
+  'Yes'                         => 'Si',
+  'days'                        => 'giorni',
+  'ea'                          => 'ci',
+  'emailed to'                  => 'Mandato via e-mail a',
+  'sent to printer'             => 'mandato in stampa',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'aggiungi'                    => 'add',
+  'continua'                    => 'continue',
+  'cancella'                    => 'delete',
+  'e_mail'                      => 'e_mail',
+  'fattura'                     => 'invoice',
+  'stampa'                      => 'print',
+  'salva'                       => 'save',
+  'salva_come_nuovo'            => 'save_as_new',
+  'spedire_a'                   => 'ship_to',
+  'aggiorna'                    => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/it/rc b/sql-ledger/locale/it/rc
new file mode 100644 (file)
index 0000000..48aa805
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Conto',
+  'Balance'                     => 'Saldo',
+  'Cleared Balance'             => 'Saldo gi&agrave; Conciliato',
+  'Continue'                    => 'Continua',
+  'Date'                        => 'Data',
+  'Deposit'                     => 'Deposito',
+  'Description'                 => 'Descrizione',
+  'Difference'                  => 'Differenza',
+  'Done'                        => 'Fatto',
+  'Exchangerate Difference'     => 'Differenza sul Tasso di Cambio',
+  'From'                        => 'Dal',
+  'Out of balance!'             => 'Non conciliato!',
+  'Payment'                     => 'Pagamento',
+  'Reconciliation'              => 'Conciliazione',
+  'Select all'                  => 'Seleziona tutto',
+  'Source'                      => 'Sorgente',
+  'Statement Balance'           => 'Saldo',
+  'Update'                      => 'Aggiorna',
+  'to'                          => 'al',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'continua'                    => 'continue',
+  'fatto'                       => 'done',
+  'seleziona_tutto'             => 'select_all',
+  'aggiorna'                    => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/it/rp b/sql-ledger/locale/it/rp
new file mode 100644 (file)
index 0000000..3a8c51a
--- /dev/null
@@ -0,0 +1,120 @@
+$self{texts} = {
+  'AP Aging'                    => 'Partite Aperte',
+  'AR Aging'                    => 'Partite Aperte',
+  'Account'                     => 'Conto',
+  'Accounts'                    => 'Conti',
+  'Amount'                      => 'Importo',
+  'Apr'                         => 'Apr',
+  'April'                       => 'Aprile',
+  'Attachment'                  => 'Allegato',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Saldo',
+  'Balance Sheet'               => 'Stato Patrimoniale',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Basato sulla cassa',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Confronta con',
+  'Continue'                    => 'Continua',
+  'Copies'                      => 'Copie',
+  'Credit'                      => 'Avere',
+  'Current'                     => 'Corrente',
+  'Customer'                    => 'Cliente',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Dare',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Dicembre',
+  'Decimalplaces'               => 'Numero di decimali',
+  'Department'                  => 'Department',
+  'Description'                 => 'Descrizione',
+  'Due'                         => 'Dovuto',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'Manda il sollecito via e-mail a',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febbraio',
+  'From'                        => 'Dal',
+  'GIFI'                        => 'Codice GIFI',
+  'Heading'                     => 'Intestazione',
+  'ID'                          => 'ID',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Includi nel Prospetto',
+  'Income Statement'            => 'Conto Economico',
+  'Invoice'                     => 'Fattura',
+  'Jan'                         => 'Gen',
+  'January'                     => 'Gennaio',
+  'Jul'                         => 'Lug',
+  'July'                        => 'Luglio',
+  'Jun'                         => 'Giu',
+  'June'                        => 'Giugno',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'Mag',
+  'May '                        => 'Mag ',
+  'Message'                     => 'Messaggio',
+  'N/A'                         => 'N/A',
+  'Nothing selected!'           => 'Non hai selezionato nulla!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembre',
+  'Oct'                         => 'Ott',
+  'October'                     => 'Ottobre',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Pagamenti',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Stampa',
+  'Printer'                     => 'Stampante',
+  'Project Number'              => 'Project Number',
+  'Receipts'                    => 'Incassi',
+  'Report for'                  => 'Prospetto per',
+  'Retained Earnings'           => 'Guadagni',
+  'Screen'                      => 'Schermo',
+  'Select all'                  => 'Seleziona tutto',
+  'Select postscript or PDF!'   => 'Scegli tra postscript e PDF!',
+  'Sep'                         => 'Set',
+  'September'                   => 'Settembre',
+  'Source'                      => 'Sorgente',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Sollecito',
+  'Statement sent to'           => 'Sollecito mandato a',
+  'Statements sent to printer!' => 'Solleciti mandati in stampa!',
+  'Subject'                     => 'Oggetto',
+  'Subtotal'                    => 'Totale Parziale',
+  'Tax'                         => 'Tassa',
+  'Tax collected'               => 'Debito IVA',
+  'Tax paid'                    => 'Credito IVA',
+  'Total'                       => 'Totale',
+  'Trial Balance'               => 'Bilancio di Verifica',
+  'Vendor'                      => 'Fornitore',
+  'as at'                       => 'Al',
+  'collected on sales'          => 'incassate su vendite',
+  'for Period'                  => 'per il Periodo',
+  'paid on purchases'           => 'pagato sugli acquisti',
+  'to'                          => 'al',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_accounts'               => 'list_accounts',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'continua'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'stampa'                      => 'print',
+  'seleziona_tutto'             => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/COPYING b/sql-ledger/locale/lt/COPYING
new file mode 100644 (file)
index 0000000..763715b
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2003
+#
+# Lithuanian texts:
+#
+#  Author:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/lt/LANGUAGE b/sql-ledger/locale/lt/LANGUAGE
new file mode 100644 (file)
index 0000000..dc243c5
--- /dev/null
@@ -0,0 +1 @@
+Lithuanian
diff --git a/sql-ledger/locale/lt/admin b/sql-ledger/locale/lt/admin
new file mode 100644 (file)
index 0000000..83cfc84
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Priëjimo kontrolë',
+  'Accounting'                  => 'Apskaita',
+  'Add User'                    => 'Pridëti Vartotojà',
+  'Address'                     => 'Adresas',
+  'Administration'              => 'Administracija',
+  'Administrator'               => 'Administratorius',
+  'All Datasets up to date!'    => 'All Datasets up to date!',
+  'Change Admin Password'       => 'Pakeisti Administratoriaus slaptaþodá',
+  'Change Password'             => 'Pakeisti slaptaþodá',
+  'Character Set'               => 'Simboliø aibë',
+  'Click on login name to edit!' => 'Paspauskit prisijungimo vardà redagavimui!',
+  'Company'                     => 'Firma',
+  'Connect to'                  => 'Prisijungti prie',
+  'Continue'                    => 'Tæsti',
+  'Create Chart of Accounts'    => 'Sukûrti sàskaitø planà',
+  'Create Dataset'              => 'Sukûrti duomenø aibæ',
+  'DBI not installed!'          => 'DBI ne instaliuotas!',
+  'Database'                    => 'Duomenø bazë',
+  'Database Administration'     => 'Duomenø bazës administravimas',
+  'Database Driver not checked!' => 'Duomenø bazës tvarkiklë nepatikrinta!',
+  'Database User missing!'      => 'Duomenø bazës vartotojo nëra!',
+  'Dataset'                     => 'Duomenø aibë',
+  'Dataset missing!'            => 'Duomenø aibës nëra!',
+  'Dataset updated!'            => 'Duomenø aibë atnaujinta!',
+  'Date Format'                 => 'Datos Formatas',
+  'Delete'                      => 'Iðtrinti',
+  'Delete Dataset'              => 'Iðtrinti Duomenø aibë',
+  'Directory'                   => 'Direktorija',
+  'Driver'                      => 'Tvarkyklë',
+  'Dropdown Limit'              => 'Iðsiskleidþianèio meniu riba',
+  'E-mail'                      => 'E-paðtas',
+  'Edit User'                   => 'Redaguoti vartotojà',
+  'Existing Datasets'           => 'Egzistuojanèios duomenø aibës',
+  'Fax'                         => 'Faksas',
+  'Host'                        => 'Hostas',
+  'Hostname missing!'           => 'Hosto vardo nëra!',
+  'Incorrect Password!'         => 'Neteisingas slaptaþodis!',
+  'Language'                    => 'Kalba',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Lokaliam prisijungimui palikite hosto ir porto laukelius tuðèiais',
+  'Login'                       => 'Prisijungimas',
+  'Multibyte Encoding'          => 'Multibaitinë kodiruotë',
+  'Name'                        => 'Vardas',
+  'New Templates'               => 'Nauji ðablonai',
+  'No Database Drivers available!' => 'Nëra Duomenø baziø tvarkykliø!',
+  'No Dataset selected!'        => 'Duomenø aibë neiðrinkta!',
+  'Nothing to delete!'          => 'Nëra ko trinti!',
+  'Number Format'               => 'Skaièiaus formatas',
+  'Oracle Database Administration' => 'Oracle Duomenø bazës Administravimas',
+  'Password'                    => 'Slaptaþodis',
+  'Password changed!'           => 'Slaptaþodis pakeistas!',
+  'Pg Database Administration'  => 'Pg Duomenø bazës Administravimas',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Portas',
+  'Port missing!'               => 'Porto numerio nëra!',
+  'Printer'                     => 'Spausdintuvas',
+  'Save'                        => 'Iðsaugoti',
+  'Select a Dataset to delete and press "Continue"' => 'Iðrinkite Duomenø aibæ trinimui ir paspauskite "Tæsti"',
+  'Setup Templates'             => 'Nustatyti ðablonus',
+  'Ship via'                    => 'Pristatyti per',
+  'Signature'                   => 'Paraðas',
+  'Stylesheet'                  => 'Stiliø lentelë',
+  'Templates'                   => 'Ðablonai',
+  'The following Datasets are not in use and can be deleted' => 'Ðios duomenø aibës nëra naudojamos ir gali bûti iðtrintos',
+  'The following Datasets need to be updated' => 'Ðios duomenø aibës turi bûti atnaujintos',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Èia preliminarus egzistuojanèiø ðaltiniø patikrinimas. Niekas negali bûti sukurta arba iðtrinta ðioje stadijoje.',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Kad pridëti vartotojà á grupæ redaguokite vardà, pakeiskite prisijungimo vardà ir iðsaugokite. Bus sukurtas naujas vartotojas su tais paèiais kintamaisiais ir nauju prisijungimo vardu',
+  'Update Dataset'              => 'Atnaujinti Duomenø Aibæ',
+  'Use Templates'               => 'Naudoti ðablonus',
+  'User'                        => 'Vartotojas',
+  'User deleted!'               => 'Vartotojas iðtrintas!',
+  'User saved!'                 => 'Vartotojas iðsaugotas!',
+  'Version'                     => 'Versija',
+  'You must enter a host and port for local and remote connections!' => 'Turite ávesti hostà ir portà lokalioms ir nuotoliniams prisijungimams!',
+  'does not exist'              => 'ne egzistuoja',
+  'is already a member!'        => 'jau narys',
+  'localhost'                   => 'lokalhostas',
+  'locked!'                     => 'uþblokuotas',
+  'successfully created!'       => 'sëkmingai sukurta',
+  'successfully deleted!'       => 'sëkmingai iðtrinta',
+  'website'                     => 'Websaitas',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'pridëti_vartotojà'           => 'add_user',
+  'pakeisti_administratoriaus_slaptaþodá' => 'change_admin_password',
+  'pakeisti_slaptaþodá'         => 'change_password',
+  'tæsti'                       => 'continue',
+  'sukûrti_duomenø_aibæ'        => 'create_dataset',
+  'iðtrinti'                    => 'delete',
+  'iðtrinti_duomenø_aibë'       => 'delete_dataset',
+  'prisijungimas'               => 'login',
+  'oracle_duomenø_bazës_administravimas' => 'oracle_database_administration',
+  'pg_duomenø_bazës_administravimas' => 'pg_database_administration',
+  'iðsaugoti'                   => 'save',
+  'atnaujinti_duomenø_aibæ'     => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/all b/sql-ledger/locale/lt/all
new file mode 100644 (file)
index 0000000..93a8771
--- /dev/null
@@ -0,0 +1,497 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Pirkimai',
+  'AP Aging'                    => 'Pirkimo Skolos',
+  'AP Transaction'              => 'Pirkimo Operacijà',
+  'AP Transactions'             => 'Pirkimo Operacijos',
+  'AR'                          => 'Pardavimai',
+  'AR Aging'                    => 'Pardavimo Skolos',
+  'AR Transaction'              => 'Pardavimo Operacijà',
+  'AR Transactions'             => 'Pardavimo Operacijos',
+  'About'                       => 'Apie...',
+  'Access Control'              => 'Priëjimo kontrolë',
+  'Account'                     => 'Sàskaita',
+  'Account Number'              => 'Sàskaitos numeris',
+  'Account Number missing!'     => 'Sàskaitos numerio nëra!',
+  'Account Type'                => 'Sàskaitos tipas',
+  'Account Type missing!'       => 'Sàskaitos tipo nëra!',
+  'Account deleted!'            => 'Sàskaitos iðtrintos',
+  'Account saved!'              => 'Sàskaitos iðsaugotos',
+  'Accounting'                  => 'Apskaita',
+  'Accounting Menu'             => 'Apskaitos Menu',
+  'Accounts'                    => 'Sàskaitos',
+  'Active'                      => 'Aktyvus',
+  'Add'                         => 'Pridëti',
+  'Add Account'                 => 'Pridëti sàskaità',
+  'Add Accounts Payables Transaction' => 'Pridëti Pirkimo Sàskaitas Operacijà',
+  'Add Accounts Receivables Transaction' => 'Pridëti Pardavimo Sàskaitas Operacijà',
+  'Add Assembly'                => 'Pridëti rinkiná',
+  'Add Customer'                => 'Pridëti klientà',
+  'Add GIFI'                    => 'Pridëti GIFI',
+  'Add General Ledger Transaction' => 'Pridëti Bendroji Þurnalo Operacijà',
+  'Add Part'                    => 'Pridëti prekæ',
+  'Add Project'                 => 'Pridëti proektà',
+  'Add Purchase Order'          => 'Pridëti Pirkimo uþsakymà',
+  'Add Sales Invoice'           => 'Pridëti Pardavimo sàskaità-faktûrà',
+  'Add Sales Order'             => 'Pridëti Pardavimo uþsakymà',
+  'Add Service'                 => 'Pridëti Paslaugà',
+  'Add Transaction'             => 'Pridëti Operacijà',
+  'Add User'                    => 'Pridëti Vartotojà',
+  'Add Vendor'                  => 'Pridëti Tiekëja',
+  'Add Vendor Invoice'          => '',
+  'Address'                     => 'Adresas',
+  'Administration'              => 'Administracija',
+  'Administrator'               => 'Administratorius',
+  'All'                         => 'Visi',
+  'All Datasets up to date!'    => 'All Datasets up to date!',
+  'Amount'                      => 'Suma',
+  'Amount Due'                  => 'Suma iki',
+  'Amount does not equal applied!' => 'Suma ne lygi pritaikytai!',
+  'Amount missing!'             => 'Nëra sumos!',
+  'Applied'                     => 'Pritaikyta',
+  'Apr'                         => 'Bal',
+  'April'                       => 'Balandis',
+  'Are you sure you want to delete Invoice Number' => 'Ar Jus tikrai norite iðtrinti saskaitu-fakturos numeris:',
+  'Are you sure you want to delete Order Number' => 'Ar Jus tikrai norite iðtrinti uzsakimas numeris:',
+  'Are you sure you want to delete Transaction' => 'Ar Jus tikrai norite iðtrinti operacijà?',
+  'Assemblies'                  => 'Rinkiniai',
+  'Assemblies restocked!'       => 'Rinkiniai persandeliuoti!',
+  'Assembly Number missing!'    => 'Rinkiniø numeriø nëra!',
+  'Asset'                       => 'Turtas',
+  'Attachment'                  => 'Prisegta',
+  'Audit Control'               => 'Audito kontrolë',
+  'Aug'                         => 'Rug',
+  'August'                      => 'Rugpjûtis',
+  'BOM'                         => 'BOM',
+  'Backup'                      => 'Reservinë kopija',
+  'Backup sent to'              => 'Reservinë kopija iðsiusta á',
+  'Balance'                     => 'Balansas',
+  'Balance Sheet'               => 'Balanso lëntelë',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Dëþë',
+  'Books are open'              => 'Þurnalai atidaryti',
+  'Bought'                      => 'Nupirkta',
+  'Business Number'             => 'Ámonës kodas',
+  'C'                           => 'C',
+  'COGS'                        => 'PPS',
+  'Cannot delete account!'      => 'Neámanoma iðtrinti sàskaitos!',
+  'Cannot delete customer!'     => 'Neámanoma iðtrinti kliento!',
+  'Cannot delete default account!' => 'Neámanoma iðtrinti sàskaitos pagal nutylejimà!',
+  'Cannot delete invoice!'      => 'Neámanoma iðtrinti sàskaitos-faktûros!',
+  'Cannot delete item already invoiced!' => 'Negalima iðtrinti prekës, kuriai sukurta sàskaita-faktûra!',
+  'Cannot delete item on order!' => 'Negalima iðtrinti prekës, kuri yra uþsakyme!',
+  'Cannot delete item which is part of an assembly!' => 'Negalima iðtrinti prekës, kuri yra rinkinio dalis!',
+  'Cannot delete item!'         => 'Neámanoma iðtrinti prekës!',
+  'Cannot delete order!'        => 'Neámanoma iðtrinti uþsakymo!',
+  'Cannot delete transaction!'  => 'Neámanoma iðtrinti operacijos!',
+  'Cannot delete vendor!'       => 'Neámanoma iðtrinti tiekëjo!',
+  'Cannot have a value in both Debit and Credit!' => 'Negalima turëti tos paèios reikðmës Debete ir Kredite!',
+  'Cannot post a transaction without a value!' => 'Neámanoma patvirtinti operacijos be reikðmës!',
+  'Cannot post invoice for a closed period!' => 'Neámanoma patvirtinti sàskaitos-faktûros uþdarajam periodui!',
+  'Cannot post invoice!'        => 'Neámanoma patvirtinti sàskaitos-faktûros!',
+  'Cannot post payment for a closed period!' => 'Neámanoma patvirtinti mokëjimo uþdarajam periodui!',
+  'Cannot post payment!'        => 'Neámanoma patvirtinti mokëjimo!',
+  'Cannot post transaction for a closed period!' => 'Neámanoma patvirtinti operacijos uþdarajam periodui!',
+  'Cannot post transaction!'    => 'Neámanoma patvirtinti operacijos!',
+  'Cannot process payment for a closed period!' => 'Neámanoma vykdyti mokëjimo uþdarajam periodui!',
+  'Cannot save account!'        => 'Neámanoma iðsaugoti sàskaitos!',
+  'Cannot save order!'          => 'Neámanoma iðsaugoti uþsakymo!',
+  'Cannot save preferences!'    => 'Neámanoma iðsaugoti nuostatø!',
+  'Cannot stock assemblies!'    => 'Neámanoma sandelioti rinkinius!',
+  'Cash'                        => 'Kasa',
+  'Cash based'                  => 'Grynais',
+  'Cc'                          => 'Cc',
+  'Change Admin Password'       => 'Pakeisti Administratoriaus slaptaþodá',
+  'Change Password'             => 'Pakeisti slaptaþodá',
+  'Character Set'               => 'Simboliø aibë',
+  'Chart of Accounts'           => 'Sàskaitø planas',
+  'Check'                       => 'Èekis',
+  'Check printed!'              => 'Èekis atspausdintas!',
+  'Check printing failed!'      => 'Èekio spausdinimas nepavyko!',
+  'Cleared Balance'             => 'Baigiamasis balansas',
+  'Click on login name to edit!' => 'Paspauskit prisijungimo vardà redagavimui!',
+  'Close Books up to'           => 'Uþdaryti þurnalus iki',
+  'Closed'                      => 'Uþdaryta',
+  'Company'                     => 'Firma',
+  'Compare to'                  => 'Palyginti su',
+  'Confirm!'                    => 'Patvirtinti!',
+  'Connect to'                  => 'Prisijungti prie',
+  'Contact'                     => 'Kontaktas',
+  'Continue'                    => 'Tæsti',
+  'Copies'                      => 'Kopijos',
+  'Copy to COA'                 => 'Kopijuoti á SP',
+  'Create Chart of Accounts'    => 'Sukûrti sàskaitø planà',
+  'Create Dataset'              => 'Sukûrti duomenø aibæ',
+  'Credit'                      => 'Kreditas',
+  'Credit Limit'                => 'Kredito riba',
+  'Curr'                        => 'Val.',
+  'Currency'                    => 'Valiûta',
+  'Current'                     => 'Dabartinis',
+  'Customer'                    => 'Klientas',
+  'Customer deleted!'           => 'Klientas iðtrintas!',
+  'Customer missing!'           => 'Kliento vardo nëra!',
+  'Customer not on file!'       => 'Tokio kliento nëra!',
+  'Customer saved!'             => 'Klientas iðsaugotas!',
+  'Customers'                   => 'Klientai',
+  'DBI not installed!'          => 'DBI ne instaliuotas!',
+  'Database'                    => 'Duomenø bazë',
+  'Database Administration'     => 'Duomenø bazës administravimas',
+  'Database Driver not checked!' => 'Duomenø bazës tvarkiklë nepatikrinta!',
+  'Database Host'               => 'Duomenø bazës hostas',
+  'Database User missing!'      => 'Duomenø bazës vartotojo nëra!',
+  'Dataset'                     => 'Duomenø aibë',
+  'Dataset missing!'            => 'Duomenø aibës nëra!',
+  'Dataset updated!'            => 'Duomenø aibë atnaujinta!',
+  'Date'                        => 'Data',
+  'Date Format'                 => 'Datos Formatas',
+  'Date Paid'                   => 'Mokëjimo Data',
+  'Date missing!'               => 'Datos nëra!',
+  'Debit'                       => 'Debetas',
+  'Debit and credit out of balance!' => 'Debetas ir Kreditas nesubalansuoti!',
+  'Dec'                         => 'Grd',
+  'December'                    => 'Gruodis',
+  'Decimalplaces'               => 'Skaièiø po taðko',
+  'Delete'                      => 'Iðtrinti',
+  'Delete Account'              => 'Iðtrinti sàskaità',
+  'Delete Dataset'              => 'Iðtrinti Duomenø aibë',
+  'Delivery Date'               => 'Prystatimo Data',
+  'Department'                  => '',
+  'Deposit'                     => 'Depozitas',
+  'Description'                 => 'Apraðymas',
+  'Difference'                  => 'Skirtumas',
+  'Directory'                   => 'Direktorija',
+  'Discount'                    => 'Nuolaidos',
+  'Done'                        => 'Ávykdyta',
+  'Drawing'                     => 'Brieþinys',
+  'Driver'                      => 'Tvarkyklë',
+  'Dropdown Limit'              => 'Iðsiskleidþianèio meniu riba',
+  'Due'                         => 'Iki',
+  'Due Date'                    => 'Iki Data',
+  'Due Date missing!'           => 'Nëra Iki Datos!',
+  'E-mail'                      => 'E-paðtas',
+  'E-mail Statement to'         => 'Suvestinæ suisti per e-pastà á',
+  'E-mail address missing!'     => 'E-paðto adreso nëra!',
+  'Edit'                        => 'Redaguoti',
+  'Edit Account'                => 'Redaguoti sàskaità',
+  'Edit Accounts Payables Transaction' => 'Redaguoti pirkimo sàskaitø operacijià',
+  'Edit Accounts Receivables Transaction' => 'Redaguoti pardavimo sàskaitø operacijià',
+  'Edit Assembly'               => 'Redaguoti rinkiná',
+  'Edit Customer'               => 'Redaguoti Klientà',
+  'Edit GIFI'                   => 'Redaguoti GIFI',
+  'Edit General Ledger Transaction' => 'Redaguoti Bendrojo Þurnalo operacijà',
+  'Edit Part'                   => 'Redaguoti prekæ',
+  'Edit Preferences for'        => 'Redaguoti nuostatas...',
+  'Edit Project'                => 'Redaguoti projektà',
+  'Edit Purchase Order'         => 'Redaguoti pirkimo uþsakymà',
+  'Edit Sales Invoice'          => 'Redaguoti pardavimo sàskaità-faktûrà',
+  'Edit Sales Order'            => 'Redaguoti pardavimo uþsakymà',
+  'Edit Service'                => 'Redaguoti paslaugà',
+  'Edit Template'               => 'Redaguoti ðablonà',
+  'Edit User'                   => 'Redaguoti vartotojà',
+  'Edit Vendor'                 => 'Redaguoti Tiekijà',
+  'Edit Vendor Invoice'         => '',
+  'Employee'                    => 'Darbuotojas',
+  'Enforce transaction reversal for all dates' => 'Reversuoti operacijas visoms datoms',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Áveskite iki 3-jø raidþiø, iðskirtø taðkais (Pvz. LTL:EUR:USD:YEN) savo ir uþsienio valiutoms paþymëti',
+  'Equity'                      => 'Turtas/Nuosavybë',
+  'Exch'                        => 'Kurs.',
+  'Exchangerate'                => 'Keitimo kursas',
+  'Exchangerate Difference'     => 'Keitimo kurso skirtumas',
+  'Exchangerate for payment missing!' => 'Mokëjimo keitimo kurso nëra!',
+  'Exchangerate missing!'       => 'Keitimo kurso nëra!',
+  'Existing Datasets'           => 'Egzistuojanèios duomenø aibës',
+  'Expense'                     => 'Sànaudos',
+  'Expense Account'             => 'Sànaudø sàskaita',
+  'Expense/Asset'               => 'Sànaudos/Aktyvai',
+  'Extended'                    => 'Iðplësta',
+  'Fax'                         => 'Faksas',
+  'Feb'                         => 'Vas',
+  'February'                    => 'Vasaris',
+  'Foreign Exchange Gain'       => 'Valiûtos keitimo pelnas',
+  'Foreign Exchange Loss'       => 'Valiûtos keitimo nuostolis',
+  'From'                        => 'Nuo',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI iðtrintas!',
+  'GIFI missing!'               => 'GIFI nëra!',
+  'GIFI saved!'                 => 'GIFI iðsaugotas!',
+  'GL Transaction'              => 'BÞ operacija',
+  'General Ledger'              => 'Bendrasis þurnalas',
+  'Goods & Services'            => 'Prekës ir Paslaugos',
+  'Group'                       => '',
+  'Group Items'                 => '',
+  'HTML Templates'              => 'HTML ðablonai',
+  'Heading'                     => 'Antraðtë',
+  'Host'                        => 'Hostas',
+  'Hostname missing!'           => 'Hosto vardo nëra!',
+  'ID'                          => 'ID',
+  'Image'                       => 'Pieðinys',
+  'In-line'                     => 'Vienaeilis',
+  'Include in Report'           => 'Ádëti á ataskaità',
+  'Include in drop-down menus'  => 'Ádëti á iðsáskleidþianèius meniu',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Ádëti ðià sàskaità á kliento/tiekëjo formas, kad paþymëti klientà/tiekëjà kaip apmokestinamà?',
+  'Income'                      => 'Pajamos',
+  'Income Account'              => 'Pajamø sàskaita',
+  'Income Statement'            => 'Pelno/nuostolio ataskaita',
+  'Incorrect Dataset version!'  => 'Neteisinga duomenø aibës versija!',
+  'Incorrect Password!'         => 'Neteisingas slaptaþodis!',
+  'Individual Items'            => 'Individualios prekës',
+  'Inventory'                   => 'Prekës',
+  'Inventory Account'           => 'Prekës sàskaita',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Prekës kiekis turi bûti lygus nuliui prieð paþymint rinkiná pasenusiu!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Prekës kiekis turi bûti lygus nuliui prieð paþymint ðià dalá pasenusia!',
+  'Inventory quantity must be zero!' => 'Prekës kiekis turi bûti lygus nuliui!',
+  'Invoice'                     => 'Sàskaita-faktûra',
+  'Invoice Date'                => 'Sàskaitos-faktûros data',
+  'Invoice Date missing!'       => 'Sàskaitos-faktûros datos nëra!',
+  'Invoice Number'              => 'Sàskaitos-faktûros numeris',
+  'Invoice Number missing!'     => 'Sàskaitos-faktûra numerio nëra!',
+  'Invoice deleted!'            => 'Sàskaitos-faktûra iðtrintos!',
+  'Invoice posted!'             => 'Sàskaitos-faktûra patvirtintos!',
+  'Invoices'                    => 'Sàskaitos-faktûros',
+  'Is this a summary account to record' => 'Ar èia apibendrinta áraðo sàskaita',
+  'Item deleted!'               => 'Vienetas iðtrintas!',
+  'Item not on file!'           => 'Vieneto nëra áraðuose!',
+  'Jan'                         => 'Sau',
+  'January'                     => 'Sausis',
+  'Jul'                         => 'Lie',
+  'July'                        => 'Liepa',
+  'Jun'                         => 'Bir',
+  'June'                        => 'Birþelis',
+  'LaTeX Templates'             => 'LaTeX ðablonai',
+  'Language'                    => 'Kalba',
+  'Last Cost'                   => 'Paskutinë kaina',
+  'Last Invoice Number'         => 'Paskutinës sàskaitos-faktûros numeris',
+  'Last Numbers & Default Accounts' => 'Paskutinieji numeriai ir sàskaitos pagal nutylëjimà',
+  'Last Purchase Order Number'  => 'Paskutinio pirkimo uþsakymo numeris',
+  'Last Sales Order Number'     => 'Paskutinio pardavimo uþsakymo numeris',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Lokaliam prisijungimui palikite hosto ir porto laukelius tuðèiais',
+  'Liability'                   => 'Nuosavybë',
+  'Licensed to'                 => 'Licenzijuota...',
+  'Line Total'                  => 'Viso eilutëje',
+  'Link'                        => 'Ryðys',
+  'Link Accounts'               => 'Suriðti sàskaitas',
+  'List Accounts'               => 'Sàskaitø sàraðas',
+  'List GIFI'                   => 'GIFI sàraðas',
+  'List Price'                  => 'Pirkimo kaina',
+  'List Transactions'           => 'Parodyti operacijas',
+  'Login'                       => 'Prisijungimas',
+  'Logout'                      => 'Iðsijungti',
+  'Make'                        => 'Gamintojas',
+  'Mar'                         => 'Kov',
+  'March'                       => 'Kovas',
+  'May'                         => 'Geg',
+  'May '                        => 'Geguþë',
+  'Message'                     => 'Þinutë',
+  'Microfiche'                  => 'Mikrofiða',
+  'Model'                       => 'Modelis',
+  'Multibyte Encoding'          => 'Multibaitinë kodiruotë',
+  'N/A'                         => 'N/A',
+  'Name'                        => 'Vardas',
+  'Name missing!'               => 'Pavadinimo nëra',
+  'New Templates'               => 'Nauji ðablonai',
+  'No'                          => 'Ne',
+  'No Database Drivers available!' => 'Nëra Duomenø baziø tvarkykliø!',
+  'No Dataset selected!'        => 'Duomenø aibë neiðrinkta!',
+  'No email address for'        => 'Nëra e-paðto adreso...',
+  'No.'                         => 'Num',
+  'Notes'                       => 'Pastaba',
+  'Nothing applied!'            => 'Niekas nepanaudota!',
+  'Nothing selected!'           => 'Nieko neiðrinkta!',
+  'Nothing to delete!'          => 'Nëra ko trinti!',
+  'Nov'                         => 'Lap',
+  'November'                    => 'Lapkritis',
+  'Number'                      => 'Numeris',
+  'Number Format'               => 'Skaièiaus formatas',
+  'Number missing in Row'       => 'Numerio nëra eilëje',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Pasenæ',
+  'Oct'                         => 'Spa',
+  'October'                     => 'Spalis',
+  'On Hand'                     => 'Likutis',
+  'On Order'                    => 'Uþsakyme',
+  'Open'                        => 'Atidaryti',
+  'Oracle Database Administration' => 'Oracle Duomenø bazës Administravimas',
+  'Order'                       => 'Uþsakymas',
+  'Order Date'                  => 'Uþsakymo data',
+  'Order Date missing!'         => 'Uþsakymo datos nëra!',
+  'Order Entry'                 => 'Uþsakymo áraðas',
+  'Order Number'                => 'Uþsakymo numeris',
+  'Order Number missing!'       => 'Uþsakymo numerio nëra!',
+  'Order deleted!'              => 'Uþsakymai iðtrinti!',
+  'Order saved!'                => 'Uþsakymas iðsaugotas!',
+  'Ordered'                     => 'Uþsakyta',
+  'Orphaned'                    => 'Naðlaitinis',
+  'Out of balance!'             => 'Nesubalansuota!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Ápakavimo sàraðas',
+  'Packing List Date missing!'  => 'Ápakavimo sàraðo datos nëra!',
+  'Packing List Number missing!' => 'Ápakavimo sàraðo numerio nëra!',
+  'Paid'                        => 'Apmokëta',
+  'Paid in full'                => 'Pilnai apmokëta',
+  'Part'                        => 'Prekë',
+  'Part Number missing!'        => 'Prekës numerio nëra!',
+  'Parts'                       => 'Prekës',
+  'Parts Inventory'             => 'Prekiø saraðas',
+  'Password'                    => 'Slaptaþodis',
+  'Password changed!'           => 'Slaptaþodis pakeistas!',
+  'Payables'                    => 'Pirkimai',
+  'Payment'                     => 'Mokëjimas',
+  'Payment date missing!'       => 'Mokëjimo datos nëra',
+  'Payment posted!'             => 'Mokëjimas patvirtintas!',
+  'Payments'                    => 'Mokëjimai',
+  'Pg Database Administration'  => 'Pg Duomenø bazës Administravimas',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Portas',
+  'Port missing!'               => 'Porto numerio nëra!',
+  'Post'                        => 'Patvirtinti',
+  'Post as new'                 => 'Patvirtinti kaip naujà',
+  'Postscript'                  => 'Postscript(TM)',
+  'Preferences'                 => 'Nuostatos',
+  'Preferences saved!'          => 'Nuostatos iðsaugotos!',
+  'Price'                       => 'Kaina',
+  'Print'                       => 'Spausdinti',
+  'Printer'                     => 'Spausdintuvas',
+  'Project'                     => 'Projektas',
+  'Project Number'              => '',
+  'Project Number missing!'     => 'Projekto numerio nëra!',
+  'Project deleted!'            => 'Projektas iðtrintas!',
+  'Project not on file!'        => 'Nëra tokio projekto!',
+  'Project saved!'              => 'Projektas iðsaugotas!',
+  'Projects'                    => 'Projektai',
+  'Purchase Order'              => 'Pirkimo uþsakymas',
+  'Purchase Orders'             => 'Pirkimo uþsakymai',
+  'Qty'                         => 'Kks',
+  'ROP'                         => 'ROP',
+  'Rate'                        => 'Kursas',
+  'Recd'                        => 'Gaut',
+  'Receipt'                     => 'Kasos orderis',
+  'Receipt printed!'            => '',
+  'Receipt printing failed!'    => '',
+  'Receipts'                    => 'Kasos orderiai',
+  'Receivables'                 => 'Pardavimai',
+  'Reconciliation'              => 'Sutaikinimas',
+  'Record in'                   => 'Áraðyti á',
+  'Reference'                   => 'Nuorodos',
+  'Reference missing!'          => 'Nuorodos nëra!',
+  'Remaining'                   => 'Likutis',
+  'Report for'                  => 'Ataskaita...',
+  'Reports'                     => 'Ataskaitos',
+  'Required by'                 => 'Iki kada',
+  'Retained Earnings'           => 'Turimi uþdarbiai',
+  'Sales'                       => 'Pardavimai',
+  'Sales Invoice'               => 'Pardavimo SF',
+  'Sales Order'                 => 'Pardavimø uþsakymas',
+  'Sales Orders'                => 'Pardavimø uþsakymai',
+  'Salesperson'                 => '',
+  'Save'                        => 'Iðsaugoti',
+  'Save as new'                 => 'Iðsaugoti kaip naujà',
+  'Save to File'                => 'Iðsaugoti á failà',
+  'Screen'                      => 'Ekranas',
+  'Select a Dataset to delete and press "Continue"' => 'Iðrinkite Duomenø aibæ trinimui ir paspauskite "Tæsti"',
+  'Select all'                  => 'Iðrinkti viskà',
+  'Select from one of the items below' => 'Iðrinkite vienà ið prekiø apaèioje',
+  'Select from one of the names below' => 'Iðrinkite vienà ið pavadinimø apaèioje',
+  'Select from one of the projects below' => 'Iðrinkite vienà ið projektø apaèioje',
+  'Select postscript or PDF!'   => 'Iðrinkite postscript arba PDF!',
+  'Sell Price'                  => 'Pardavimo kaina',
+  'Send by E-Mail'              => 'Iðsiûsti e-paðtu',
+  'Sep'                         => 'Rgs',
+  'September'                   => 'Rûgsëjis',
+  'Service'                     => 'Paslauga',
+  'Service Items'               => 'Paslaugø sàraðas',
+  'Service Number missing!'     => 'Paslaugos numerio nëra!',
+  'Services'                    => 'Paslaugos',
+  'Setup Templates'             => 'Nustatyti ðablonus',
+  'Ship'                        => 'Pristatymas',
+  'Ship to'                     => 'Pristatyti á',
+  'Ship via'                    => 'Pristatyti per',
+  'Short'                       => 'Stoka',
+  'Signature'                   => 'Paraðas',
+  'Sold'                        => 'Parduota',
+  'Source'                      => 'Dokumentas',
+  'Standard'                    => 'Standartas',
+  'Statement'                   => 'Suvestinë',
+  'Statement Balance'           => 'Balanso suvestinë',
+  'Statement sent to'           => 'Siusti suvestinæ á',
+  'Statements sent to printer!' => 'Siusti suvestinæ á spausdintuvà!',
+  'Stock Assembly'              => 'Rinkiniai sandëlyje',
+  'Stylesheet'                  => 'Stiliø lentelë',
+  'Subject'                     => 'Dalykas',
+  'Subtotal'                    => 'Viso',
+  'System'                      => 'Sistema',
+  'Tax'                         => 'Mokëstis',
+  'Tax Accounts'                => 'Mokesèiø sàskaitos',
+  'Tax Included'                => 'su mokesèiais',
+  'Tax collected'               => 'Mokesèiai surinkti',
+  'Tax paid'                    => 'Mokesèiai sumokëti',
+  'Taxable'                     => 'Apmokestinama',
+  'Template saved!'             => 'Ðablonai iðsaugoti!',
+  'Templates'                   => 'Ðablonai',
+  'Terms: Net'                  => 'Terminas: ',
+  'The following Datasets are not in use and can be deleted' => 'Ðios duomenø aibës nëra naudojamos ir gali bûti iðtrintos',
+  'The following Datasets need to be updated' => 'Ðios duomenø aibës turi bûti atnaujintos',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Èia preliminarus egzistuojanèiø ðaltiniø patikrinimas. Niekas negali bûti sukurta arba iðtrinta ðioje stadijoje.',
+  'To'                          => 'iki',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Kad pridëti vartotojà á grupæ redaguokite vardà, pakeiskite prisijungimo vardà ir iðsaugokite. Bus sukurtas naujas vartotojas su tais paèiais kintamaisiais ir nauju prisijungimo vardu',
+  'Top Level'                   => 'Aukðèiausias lygis',
+  'Total'                       => 'Ið viso',
+  'Transaction Date missing!'   => 'Operacijos datos nëra!',
+  'Transaction deleted!'        => 'Operacija iðtrinta!',
+  'Transaction posted!'         => 'Operacija patvirtinta!',
+  'Transaction reversal enforced for all dates' => 'Operacijos bus reversuojamos visoms datoms',
+  'Transaction reversal enforced up to' => 'Operacijos bus reversuojamos iki',
+  'Transactions'                => 'Operacijos',
+  'Transactions exist, cannot delete customer!' => 'Operacijos egzistuoja, negalima iðtrinti kliento!',
+  'Transactions exist, cannot delete vendor!' => 'Operacijos egzistuoja, negalima iðtrinti tiekëjo!',
+  'Transactions exist; cannot delete account!' => 'Operacijos egzistuoja, negalima iðtrinti sàskaitos!',
+  'Trial Balance'               => 'Bandomasis balansas',
+  'Unit'                        => 'Vienetas',
+  'Unit of measure'             => 'Matavimo vienetas',
+  'Update'                      => 'Atnaujinti',
+  'Update Dataset'              => 'Atnaujinti Duomenø Aibæ',
+  'Updated'                     => 'Atnaujinta',
+  'Use Templates'               => 'Naudoti ðablonus',
+  'User'                        => 'Vartotojas',
+  'User deleted!'               => 'Vartotojas iðtrintas!',
+  'User saved!'                 => 'Vartotojas iðsaugotas!',
+  'Vendor'                      => 'Tiekëjas',
+  'Vendor Invoice'              => '',
+  'Vendor deleted!'             => 'Tiekëjas iðtrintas!',
+  'Vendor missing!'             => 'Tiekëjo Vardo nëra!',
+  'Vendor not on file!'         => 'Tokio tiekëjo nëra!',
+  'Vendor saved!'               => 'Tiekëjai iðsaugoti',
+  'Vendors'                     => 'Tiekëjai',
+  'Version'                     => 'Versija',
+  'Weight'                      => 'Svoris',
+  'Weight Unit'                 => 'Svorio vienetas.',
+  'What type of item is this?'  => 'Koks ðio dalyko tipas?',
+  'Year End'                    => 'Metø pabaiga',
+  'Yes'                         => 'Taip',
+  'You are logged out!'         => 'Jûs iðsijungëte!',
+  'You did not enter a name!'   => 'Neávedëte vardo!',
+  'You must enter a host and port for local and remote connections!' => 'Turite ávesti hostà ir portà lokalioms ir nuotoliniams prisijungimams!',
+  'as at'                       => 'kaip',
+  'collected on sales'          => 'surinkta per pardavimus',
+  'days'                        => 'dienos',
+  'does not exist'              => 'ne egzistuoja',
+  'ea'                          => 'kk',
+  'emailed to'                  => 'email do',
+  'for Period'                  => 'periodui',
+  'hr'                          => 'val',
+  'is already a member!'        => 'jau narys',
+  'is not a member!'            => 'nëra narys!',
+  'localhost'                   => 'lokalhostas',
+  'locked!'                     => 'uþblokuotas',
+  'paid on purchases'           => 'apmokëta per pirkimus',
+  'sent to printer'             => 'pasiûsta á spausdintuvà',
+  'successfully created!'       => 'sëkmingai sukurta',
+  'successfully deleted!'       => 'sëkmingai iðtrinta',
+  'to'                          => 'iki',
+  'website'                     => 'Websaitas',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/am b/sql-ledger/locale/lt/am
new file mode 100644 (file)
index 0000000..4796a2b
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Pirkimai',
+  'AR'                          => 'Pardavimai',
+  'Account'                     => 'Sàskaita',
+  'Account Number'              => 'Sàskaitos numeris',
+  'Account Number missing!'     => 'Sàskaitos numerio nëra!',
+  'Account Type'                => 'Sàskaitos tipas',
+  'Account Type missing!'       => 'Sàskaitos tipo nëra!',
+  'Account deleted!'            => 'Sàskaitos iðtrintos',
+  'Account saved!'              => 'Sàskaitos iðsaugotos',
+  'Add Account'                 => 'Pridëti sàskaità',
+  'Add GIFI'                    => 'Pridëti GIFI',
+  'Address'                     => 'Adresas',
+  'Asset'                       => 'Turtas',
+  'Audit Control'               => 'Audito kontrolë',
+  'Backup sent to'              => 'Reservinë kopija iðsiusta á',
+  'Books are open'              => 'Þurnalai atidaryti',
+  'Business Number'             => 'Ámonës kodas',
+  'COGS'                        => 'PPS',
+  'Cannot delete account!'      => 'Neámanoma iðtrinti sàskaitos!',
+  'Cannot delete default account!' => 'Neámanoma iðtrinti sàskaitos pagal nutylejimà!',
+  'Cannot save account!'        => 'Neámanoma iðsaugoti sàskaitos!',
+  'Cannot save preferences!'    => 'Neámanoma iðsaugoti nuostatø!',
+  'Character Set'               => 'Simboliø aibë',
+  'Chart of Accounts'           => 'Sàskaitø planas',
+  'Close Books up to'           => 'Uþdaryti þurnalus iki',
+  'Company'                     => 'Firma',
+  'Continue'                    => 'Tæsti',
+  'Copy to COA'                 => 'Kopijuoti á SP',
+  'Credit'                      => 'Kreditas',
+  'Date Format'                 => 'Datos Formatas',
+  'Debit'                       => 'Debetas',
+  'Delete'                      => 'Iðtrinti',
+  'Delete Account'              => 'Iðtrinti sàskaità',
+  'Description'                 => 'Apraðymas',
+  'Dropdown Limit'              => 'Iðsiskleidþianèio meniu riba',
+  'E-mail'                      => 'E-paðtas',
+  'Edit'                        => 'Redaguoti',
+  'Edit Account'                => 'Redaguoti sàskaità',
+  'Edit GIFI'                   => 'Redaguoti GIFI',
+  'Edit Preferences for'        => 'Redaguoti nuostatas...',
+  'Edit Template'               => 'Redaguoti ðablonà',
+  'Enforce transaction reversal for all dates' => 'Reversuoti operacijas visoms datoms',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Áveskite iki 3-jø raidþiø, iðskirtø taðkais (Pvz. LTL:EUR:USD:YEN) savo ir uþsienio valiutoms paþymëti',
+  'Equity'                      => 'Turtas/Nuosavybë',
+  'Expense'                     => 'Sànaudos',
+  'Expense Account'             => 'Sànaudø sàskaita',
+  'Expense/Asset'               => 'Sànaudos/Aktyvai',
+  'Fax'                         => 'Faksas',
+  'Foreign Exchange Gain'       => 'Valiûtos keitimo pelnas',
+  'Foreign Exchange Loss'       => 'Valiûtos keitimo nuostolis',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI iðtrintas!',
+  'GIFI missing!'               => 'GIFI nëra!',
+  'GIFI saved!'                 => 'GIFI iðsaugotas!',
+  'Heading'                     => 'Antraðtë',
+  'Include in drop-down menus'  => 'Ádëti á iðsáskleidþianèius meniu',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Ádëti ðià sàskaità á kliento/tiekëjo formas, kad paþymëti klientà/tiekëjà kaip apmokestinamà?',
+  'Income'                      => 'Pajamos',
+  'Income Account'              => 'Pajamø sàskaita',
+  'Inventory'                   => 'Prekës',
+  'Inventory Account'           => 'Prekës sàskaita',
+  'Is this a summary account to record' => 'Ar èia apibendrinta áraðo sàskaita',
+  'Language'                    => 'Kalba',
+  'Last Invoice Number'         => 'Paskutinës sàskaitos-faktûros numeris',
+  'Last Numbers & Default Accounts' => 'Paskutinieji numeriai ir sàskaitos pagal nutylëjimà',
+  'Last Purchase Order Number'  => 'Paskutinio pirkimo uþsakymo numeris',
+  'Last Sales Order Number'     => 'Paskutinio pardavimo uþsakymo numeris',
+  'Liability'                   => 'Nuosavybë',
+  'Link'                        => 'Ryðys',
+  'Name'                        => 'Vardas',
+  'No'                          => 'Ne',
+  'No email address for'        => 'Nëra e-paðto adreso...',
+  'Number'                      => 'Numeris',
+  'Number Format'               => 'Skaièiaus formatas',
+  'Parts Inventory'             => 'Prekiø saraðas',
+  'Password'                    => 'Slaptaþodis',
+  'Payables'                    => 'Pirkimai',
+  'Payment'                     => 'Mokëjimas',
+  'Phone'                       => 'Tel.',
+  'Preferences saved!'          => 'Nuostatos iðsaugotos!',
+  'Rate'                        => 'Kursas',
+  'Receivables'                 => 'Pardavimai',
+  'Sales'                       => 'Pardavimai',
+  'Save'                        => 'Iðsaugoti',
+  'Service Items'               => 'Paslaugø sàraðas',
+  'Ship via'                    => 'Pristatyti per',
+  'Signature'                   => 'Paraðas',
+  'Stylesheet'                  => 'Stiliø lentelë',
+  'Tax'                         => 'Mokëstis',
+  'Tax Accounts'                => 'Mokesèiø sàskaitos',
+  'Template saved!'             => 'Ðablonai iðsaugoti!',
+  'Transaction reversal enforced for all dates' => 'Operacijos bus reversuojamos visoms datoms',
+  'Transaction reversal enforced up to' => 'Operacijos bus reversuojamos iki',
+  'Transactions exist; cannot delete account!' => 'Operacijos egzistuoja, negalima iðtrinti sàskaitos!',
+  'Weight Unit'                 => 'Svorio vienetas.',
+  'Year End'                    => 'Metø pabaiga',
+  'Yes'                         => 'Taip',
+  'does not exist'              => 'ne egzistuoja',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'pridëti_sàskaità'            => 'add_account',
+  'tæsti'                       => 'continue',
+  'kopijuoti_á_sp'              => 'copy_to_coa',
+  'iðtrinti'                    => 'delete',
+  'redaguoti'                   => 'edit',
+  'redaguoti_sàskaità'          => 'edit_account',
+  'iðsaugoti'                   => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/ap b/sql-ledger/locale/lt/ap
new file mode 100644 (file)
index 0000000..749dbfb
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Pirkimo Operacijà',
+  'AP Transactions'             => 'Pirkimo Operacijos',
+  'Account'                     => 'Sàskaita',
+  'Add Accounts Payables Transaction' => 'Pridëti Pirkimo Sàskaitas Operacijà',
+  'Address'                     => 'Adresas',
+  'Amount'                      => 'Suma',
+  'Amount Due'                  => 'Suma iki',
+  'Apr'                         => 'Bal',
+  'April'                       => 'Balandis',
+  'Are you sure you want to delete Transaction' => 'Ar Jus tikrai norite iðtrinti operacijà?',
+  'Aug'                         => 'Rug',
+  'August'                      => 'Rugpjûtis',
+  'Cannot delete transaction!'  => 'Neámanoma iðtrinti operacijos!',
+  'Cannot post payment for a closed period!' => 'Neámanoma patvirtinti mokëjimo uþdarajam periodui!',
+  'Cannot post transaction for a closed period!' => 'Neámanoma patvirtinti operacijos uþdarajam periodui!',
+  'Cannot post transaction!'    => 'Neámanoma patvirtinti operacijos!',
+  'Closed'                      => 'Uþdaryta',
+  'Confirm!'                    => 'Patvirtinti!',
+  'Continue'                    => 'Tæsti',
+  'Currency'                    => 'Valiûta',
+  'Customer not on file!'       => 'Tokio kliento nëra!',
+  'Date'                        => 'Data',
+  'Date Paid'                   => 'Mokëjimo Data',
+  'Dec'                         => 'Grd',
+  'December'                    => 'Gruodis',
+  'Delete'                      => 'Iðtrinti',
+  'Description'                 => 'Apraðymas',
+  'Due Date'                    => 'Iki Data',
+  'Due Date missing!'           => 'Nëra Iki Datos!',
+  'Edit Accounts Payables Transaction' => 'Redaguoti pirkimo sàskaitø operacijià',
+  'Employee'                    => 'Darbuotojas',
+  'Exch'                        => 'Kurs.',
+  'Exchangerate'                => 'Keitimo kursas',
+  'Exchangerate for payment missing!' => 'Mokëjimo keitimo kurso nëra!',
+  'Exchangerate missing!'       => 'Keitimo kurso nëra!',
+  'Feb'                         => 'Vas',
+  'February'                    => 'Vasaris',
+  'From'                        => 'Nuo',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Ádëti á ataskaità',
+  'Invoice'                     => 'Sàskaita-faktûra',
+  'Invoice Date'                => 'Sàskaitos-faktûros data',
+  'Invoice Date missing!'       => 'Sàskaitos-faktûros datos nëra!',
+  'Invoice Number'              => 'Sàskaitos-faktûros numeris',
+  'Invoice Number missing!'     => 'Sàskaitos-faktûra numerio nëra!',
+  'Jan'                         => 'Sau',
+  'January'                     => 'Sausis',
+  'Jul'                         => 'Lie',
+  'July'                        => 'Liepa',
+  'Jun'                         => 'Bir',
+  'June'                        => 'Birþelis',
+  'Mar'                         => 'Kov',
+  'March'                       => 'Kovas',
+  'May'                         => 'Geg',
+  'May '                        => 'Geguþë',
+  'Notes'                       => 'Pastaba',
+  'Nov'                         => 'Lap',
+  'November'                    => 'Lapkritis',
+  'Number'                      => 'Numeris',
+  'Oct'                         => 'Spa',
+  'October'                     => 'Spalis',
+  'Open'                        => 'Atidaryti',
+  'Order'                       => 'Uþsakymas',
+  'Order Number'                => 'Uþsakymo numeris',
+  'Paid'                        => 'Apmokëta',
+  'Payment date missing!'       => 'Mokëjimo datos nëra',
+  'Payments'                    => 'Mokëjimai',
+  'Post'                        => 'Patvirtinti',
+  'Post as new'                 => 'Patvirtinti kaip naujà',
+  'Project'                     => 'Projektas',
+  'Project not on file!'        => 'Nëra tokio projekto!',
+  'Select from one of the names below' => 'Iðrinkite vienà ið pavadinimø apaèioje',
+  'Select from one of the projects below' => 'Iðrinkite vienà ið projektø apaèioje',
+  'Sep'                         => 'Rgs',
+  'September'                   => 'Rûgsëjis',
+  'Source'                      => 'Dokumentas',
+  'Subtotal'                    => 'Viso',
+  'Tax'                         => 'Mokëstis',
+  'Tax Included'                => 'su mokesèiais',
+  'Total'                       => 'Ið viso',
+  'Transaction deleted!'        => 'Operacija iðtrinta!',
+  'Transaction posted!'         => 'Operacija patvirtinta!',
+  'Update'                      => 'Atnaujinti',
+  'Vendor'                      => 'Tiekëjas',
+  'Vendor Invoice'              => 'Vendor Invoice',
+  'Vendor missing!'             => 'Tiekëjo Vardo nëra!',
+  'Vendor not on file!'         => 'Tokio tiekëjo nëra!',
+  'Yes'                         => 'Taip',
+  'to'                          => 'iki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'pirkimo_operacijà'           => 'ap_transaction',
+  'pridëti_pirkimo_sàskaitas_operacijà' => 'add_accounts_payables_transaction',
+  'tæsti'                       => 'continue',
+  'iðtrinti'                    => 'delete',
+  'redaguoti_pirkimo_sàskaitø_operacijià' => 'edit_accounts_payables_transaction',
+  'patvirtinti'                 => 'post',
+  'patvirtinti_kaip_naujà'      => 'post_as_new',
+  'atnaujinti'                  => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'taip'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/ar b/sql-ledger/locale/lt/ar
new file mode 100644 (file)
index 0000000..1b5616d
--- /dev/null
@@ -0,0 +1,134 @@
+$self{texts} = {
+  'AR Transaction'              => 'Pardavimo Operacijà',
+  'AR Transactions'             => 'Pardavimo Operacijos',
+  'Account'                     => 'Sàskaita',
+  'Add Accounts Receivables Transaction' => 'Pridëti Pardavimo Sàskaitas Operacijà',
+  'Address'                     => 'Adresas',
+  'Amount'                      => 'Suma',
+  'Amount Due'                  => 'Suma iki',
+  'Apr'                         => 'Bal',
+  'April'                       => 'Balandis',
+  'Are you sure you want to delete Transaction' => 'Ar Jus tikrai norite iðtrinti operacijà?',
+  'Aug'                         => 'Rug',
+  'August'                      => 'Rugpjûtis',
+  'Cannot delete transaction!'  => 'Neámanoma iðtrinti operacijos!',
+  'Cannot post payment for a closed period!' => 'Neámanoma patvirtinti mokëjimo uþdarajam periodui!',
+  'Cannot post transaction for a closed period!' => 'Neámanoma patvirtinti operacijos uþdarajam periodui!',
+  'Cannot post transaction!'    => 'Neámanoma patvirtinti operacijos!',
+  'Closed'                      => 'Uþdaryta',
+  'Confirm!'                    => 'Patvirtinti!',
+  'Continue'                    => 'Tæsti',
+  'Credit Limit'                => 'Kredito riba',
+  'Currency'                    => 'Valiûta',
+  'Customer'                    => 'Klientas',
+  'Customer missing!'           => 'Kliento vardo nëra!',
+  'Customer not on file!'       => 'Tokio kliento nëra!',
+  'Date'                        => 'Data',
+  'Date Paid'                   => 'Mokëjimo Data',
+  'Dec'                         => 'Grd',
+  'December'                    => 'Gruodis',
+  'Delete'                      => 'Iðtrinti',
+  'Description'                 => 'Apraðymas',
+  'Due Date'                    => 'Iki Data',
+  'Due Date missing!'           => 'Nëra Iki Datos!',
+  'Edit Accounts Receivables Transaction' => 'Redaguoti pardavimo sàskaitø operacijià',
+  'Exch'                        => 'Kurs.',
+  'Exchangerate'                => 'Keitimo kursas',
+  'Exchangerate for payment missing!' => 'Mokëjimo keitimo kurso nëra!',
+  'Exchangerate missing!'       => 'Keitimo kurso nëra!',
+  'Feb'                         => 'Vas',
+  'February'                    => 'Vasaris',
+  'From'                        => 'Nuo',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Ádëti á ataskaità',
+  'Invoice'                     => 'Sàskaita-faktûra',
+  'Invoice Date'                => 'Sàskaitos-faktûros data',
+  'Invoice Date missing!'       => 'Sàskaitos-faktûros datos nëra!',
+  'Invoice Number'              => 'Sàskaitos-faktûros numeris',
+  'Invoice Number missing!'     => 'Sàskaitos-faktûra numerio nëra!',
+  'Jan'                         => 'Sau',
+  'January'                     => 'Sausis',
+  'Jul'                         => 'Lie',
+  'July'                        => 'Liepa',
+  'Jun'                         => 'Bir',
+  'June'                        => 'Birþelis',
+  'Mar'                         => 'Kov',
+  'March'                       => 'Kovas',
+  'May'                         => 'Geg',
+  'May '                        => 'Geguþë',
+  'Notes'                       => 'Pastaba',
+  'Nov'                         => 'Lap',
+  'November'                    => 'Lapkritis',
+  'Number'                      => 'Numeris',
+  'Oct'                         => 'Spa',
+  'October'                     => 'Spalis',
+  'Open'                        => 'Atidaryti',
+  'Order'                       => 'Uþsakymas',
+  'Order Number'                => 'Uþsakymo numeris',
+  'Paid'                        => 'Apmokëta',
+  'Payment date missing!'       => 'Mokëjimo datos nëra',
+  'Payments'                    => 'Mokëjimai',
+  'Post'                        => 'Patvirtinti',
+  'Post as new'                 => 'Patvirtinti kaip naujà',
+  'Project'                     => 'Projektas',
+  'Project not on file!'        => 'Nëra tokio projekto!',
+  'Remaining'                   => 'Likutis',
+  'Sales Invoice'               => 'Pardavimo SF',
+  'Salesperson'                 => 'Salesperson',
+  'Select from one of the names below' => 'Iðrinkite vienà ið pavadinimø apaèioje',
+  'Select from one of the projects below' => 'Iðrinkite vienà ið projektø apaèioje',
+  'Sep'                         => 'Rgs',
+  'September'                   => 'Rûgsëjis',
+  'Ship via'                    => 'Pristatyti per',
+  'Source'                      => 'Dokumentas',
+  'Subtotal'                    => 'Viso',
+  'Tax'                         => 'Mokëstis',
+  'Tax Included'                => 'su mokesèiais',
+  'Total'                       => 'Ið viso',
+  'Transaction deleted!'        => 'Operacija iðtrinta!',
+  'Transaction posted!'         => 'Operacija patvirtinta!',
+  'Update'                      => 'Atnaujinti',
+  'Vendor not on file!'         => 'Tokio tiekëjo nëra!',
+  'Yes'                         => 'Taip',
+  'to'                          => 'iki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'pardavimo_operacijà'         => 'ar_transaction',
+  'tæsti'                       => 'continue',
+  'iðtrinti'                    => 'delete',
+  'patvirtinti'                 => 'post',
+  'patvirtinti_kaip_naujà'      => 'post_as_new',
+  'pardavimo_sf'                => 'sales_invoice',
+  'atnaujinti'                  => 'update',
+  'taip'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/arap b/sql-ledger/locale/lt/arap
new file mode 100644 (file)
index 0000000..0033472
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Adresas',
+  'Continue'                    => 'Tæsti',
+  'Customer not on file!'       => 'Tokio kliento nëra!',
+  'Description'                 => 'Apraðymas',
+  'Number'                      => 'Numeris',
+  'Project not on file!'        => 'Nëra tokio projekto!',
+  'Select from one of the names below' => 'Iðrinkite vienà ið pavadinimø apaèioje',
+  'Select from one of the projects below' => 'Iðrinkite vienà ið projektø apaèioje',
+  'Vendor not on file!'         => 'Tokio tiekëjo nëra!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'vendor_invoice'              => 'vendor_invoice',
+  'tæsti'                       => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/ca b/sql-ledger/locale/lt/ca
new file mode 100644 (file)
index 0000000..89d18c3
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Sàskaita',
+  'Apr'                         => 'Bal',
+  'April'                       => 'Balandis',
+  'Aug'                         => 'Rug',
+  'August'                      => 'Rugpjûtis',
+  'Balance'                     => 'Balansas',
+  'Chart of Accounts'           => 'Sàskaitø planas',
+  'Credit'                      => 'Kreditas',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Debetas',
+  'Dec'                         => 'Grd',
+  'December'                    => 'Gruodis',
+  'Description'                 => 'Apraðymas',
+  'Feb'                         => 'Vas',
+  'February'                    => 'Vasaris',
+  'From'                        => 'Nuo',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Ádëti á ataskaità',
+  'Jan'                         => 'Sau',
+  'January'                     => 'Sausis',
+  'Jul'                         => 'Lie',
+  'July'                        => 'Liepa',
+  'Jun'                         => 'Bir',
+  'June'                        => 'Birþelis',
+  'List Transactions'           => 'Parodyti operacijas',
+  'Mar'                         => 'Kov',
+  'March'                       => 'Kovas',
+  'May'                         => 'Geg',
+  'May '                        => 'Geguþë',
+  'Nov'                         => 'Lap',
+  'November'                    => 'Lapkritis',
+  'Oct'                         => 'Spa',
+  'October'                     => 'Spalis',
+  'Reference'                   => 'Nuorodos',
+  'Sep'                         => 'Rgs',
+  'September'                   => 'Rûgsëjis',
+  'Subtotal'                    => 'Viso',
+  'to'                          => 'iki',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'parodyti_operacijas'         => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/cp b/sql-ledger/locale/lt/cp
new file mode 100644 (file)
index 0000000..ec73d18
--- /dev/null
@@ -0,0 +1,77 @@
+$self{texts} = {
+  'Account'                     => 'Sàskaita',
+  'Address'                     => 'Adresas',
+  'Amount'                      => 'Suma',
+  'Amount does not equal applied!' => 'Suma ne lygi pritaikytai!',
+  'Amount missing!'             => 'Nëra sumos!',
+  'Applied'                     => 'Pritaikyta',
+  'Cannot post payment!'        => 'Neámanoma patvirtinti mokëjimo!',
+  'Cannot process payment for a closed period!' => 'Neámanoma vykdyti mokëjimo uþdarajam periodui!',
+  'Check'                       => 'Èekis',
+  'Check printed!'              => 'Èekis atspausdintas!',
+  'Check printing failed!'      => 'Èekio spausdinimas nepavyko!',
+  'Continue'                    => 'Tæsti',
+  'Currency'                    => 'Valiûta',
+  'Customer'                    => 'Klientas',
+  'Customer not on file!'       => 'Tokio kliento nëra!',
+  'Date'                        => 'Data',
+  'Date missing!'               => 'Datos nëra!',
+  'Description'                 => 'Apraðymas',
+  'Due'                         => 'Iki',
+  'Exchangerate'                => 'Keitimo kursas',
+  'From'                        => 'Nuo',
+  'Invoice'                     => 'Sàskaita-faktûra',
+  'Invoices'                    => 'Sàskaitos-faktûros',
+  'Nothing applied!'            => 'Niekas nepanaudota!',
+  'Number'                      => 'Numeris',
+  'Paid in full'                => 'Pilnai apmokëta',
+  'Payment'                     => 'Mokëjimas',
+  'Payment posted!'             => 'Mokëjimas patvirtintas!',
+  'Post'                        => 'Patvirtinti',
+  'Print'                       => 'Spausdinti',
+  'Printer'                     => 'Spausdintuvas',
+  'Project not on file!'        => 'Nëra tokio projekto!',
+  'Receipt'                     => 'Kasos orderis',
+  'Receipt printed!'            => 'Receipt printed!',
+  'Receipt printing failed!'    => 'Receipt printing failed!',
+  'Reference'                   => 'Nuorodos',
+  'Screen'                      => 'Ekranas',
+  'Select from one of the names below' => 'Iðrinkite vienà ið pavadinimø apaèioje',
+  'Select from one of the projects below' => 'Iðrinkite vienà ið projektø apaèioje',
+  'Update'                      => 'Atnaujinti',
+  'Vendor'                      => 'Tiekëjas',
+  'Vendor not on file!'         => 'Tokio tiekëjo nëra!',
+  'to'                          => 'iki',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'tæsti'                       => 'continue',
+  'patvirtinti'                 => 'post',
+  'spausdinti'                  => 'print',
+  'atnaujinti'                  => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/ct b/sql-ledger/locale/lt/ct
new file mode 100644 (file)
index 0000000..5de12f6
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Pridëti',
+  'Address'                     => 'Adresas',
+  'All'                         => 'Visi',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Neámanoma iðtrinti kliento!',
+  'Cannot delete vendor!'       => 'Neámanoma iðtrinti tiekëjo!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontaktas',
+  'Continue'                    => 'Tæsti',
+  'Credit Limit'                => 'Kredito riba',
+  'Customer deleted!'           => 'Klientas iðtrintas!',
+  'Customer saved!'             => 'Klientas iðsaugotas!',
+  'Customers'                   => 'Klientai',
+  'Delete'                      => 'Iðtrinti',
+  'Discount'                    => 'Nuolaidos',
+  'E-mail'                      => 'E-paðtas',
+  'Edit Customer'               => 'Redaguoti Klientà',
+  'Edit Vendor'                 => 'Redaguoti Tiekijà',
+  'Fax'                         => 'Faksas',
+  'Include in Report'           => 'Ádëti á ataskaità',
+  'Invoice'                     => 'Sàskaita-faktûra',
+  'Name'                        => 'Vardas',
+  'Name missing!'               => 'Pavadinimo nëra',
+  'Notes'                       => 'Pastaba',
+  'Number'                      => 'Numeris',
+  'Order'                       => 'Uþsakymas',
+  'Orphaned'                    => 'Naðlaitinis',
+  'Phone'                       => 'Tel.',
+  'Save'                        => 'Iðsaugoti',
+  'Ship to'                     => 'Pristatyti á',
+  'Tax Included'                => 'su mokesèiais',
+  'Taxable'                     => 'Apmokestinama',
+  'Terms: Net'                  => 'Terminas: ',
+  'Transactions exist, cannot delete customer!' => 'Operacijos egzistuoja, negalima iðtrinti kliento!',
+  'Transactions exist, cannot delete vendor!' => 'Operacijos egzistuoja, negalima iðtrinti tiekëjo!',
+  'Vendor deleted!'             => 'Tiekëjas iðtrintas!',
+  'Vendor saved!'               => 'Tiekëjai iðsaugoti',
+  'Vendors'                     => 'Tiekëjai',
+  'days'                        => 'dienos',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'pridëti'                     => 'add',
+  'tæsti'                       => 'continue',
+  'iðtrinti'                    => 'delete',
+  'sàskaita_faktûra'            => 'invoice',
+  'uþsakymas'                   => 'order',
+  'iðsaugoti'                   => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/gl b/sql-ledger/locale/lt/gl
new file mode 100644 (file)
index 0000000..db28f7e
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Pirkimo Operacijà',
+  'AR Transaction'              => 'Pardavimo Operacijà',
+  'Account'                     => 'Sàskaita',
+  'Add General Ledger Transaction' => 'Pridëti Bendroji Þurnalo Operacijà',
+  'Address'                     => 'Adresas',
+  'All'                         => 'Visi',
+  'Apr'                         => 'Bal',
+  'April'                       => 'Balandis',
+  'Are you sure you want to delete Transaction' => 'Ar Jus tikrai norite iðtrinti operacijà?',
+  'Asset'                       => 'Turtas',
+  'Aug'                         => 'Rug',
+  'August'                      => 'Rugpjûtis',
+  'Balance'                     => 'Balansas',
+  'Cannot delete transaction!'  => 'Neámanoma iðtrinti operacijos!',
+  'Cannot have a value in both Debit and Credit!' => 'Negalima turëti tos paèios reikðmës Debete ir Kredite!',
+  'Cannot post a transaction without a value!' => 'Neámanoma patvirtinti operacijos be reikðmës!',
+  'Cannot post transaction for a closed period!' => 'Neámanoma patvirtinti operacijos uþdarajam periodui!',
+  'Confirm!'                    => 'Patvirtinti!',
+  'Continue'                    => 'Tæsti',
+  'Credit'                      => 'Kreditas',
+  'Customer not on file!'       => 'Tokio kliento nëra!',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Debetas',
+  'Debit and credit out of balance!' => 'Debetas ir Kreditas nesubalansuoti!',
+  'Dec'                         => 'Grd',
+  'December'                    => 'Gruodis',
+  'Delete'                      => 'Iðtrinti',
+  'Description'                 => 'Apraðymas',
+  'Edit General Ledger Transaction' => 'Redaguoti Bendrojo Þurnalo operacijà',
+  'Equity'                      => 'Turtas/Nuosavybë',
+  'Expense'                     => 'Sànaudos',
+  'Feb'                         => 'Vas',
+  'February'                    => 'Vasaris',
+  'From'                        => 'Nuo',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'BÞ operacija',
+  'General Ledger'              => 'Bendrasis þurnalas',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Ádëti á ataskaità',
+  'Income'                      => 'Pajamos',
+  'Jan'                         => 'Sau',
+  'January'                     => 'Sausis',
+  'Jul'                         => 'Lie',
+  'July'                        => 'Liepa',
+  'Jun'                         => 'Bir',
+  'June'                        => 'Birþelis',
+  'Liability'                   => 'Nuosavybë',
+  'Mar'                         => 'Kov',
+  'March'                       => 'Kovas',
+  'May'                         => 'Geg',
+  'May '                        => 'Geguþë',
+  'Notes'                       => 'Pastaba',
+  'Nov'                         => 'Lap',
+  'November'                    => 'Lapkritis',
+  'Number'                      => 'Numeris',
+  'Oct'                         => 'Spa',
+  'October'                     => 'Spalis',
+  'Post'                        => 'Patvirtinti',
+  'Post as new'                 => 'Patvirtinti kaip naujà',
+  'Project'                     => 'Projektas',
+  'Project not on file!'        => 'Nëra tokio projekto!',
+  'Reference'                   => 'Nuorodos',
+  'Reference missing!'          => 'Nuorodos nëra!',
+  'Reports'                     => 'Ataskaitos',
+  'Sales Invoice'               => 'Pardavimo SF',
+  'Select from one of the names below' => 'Iðrinkite vienà ið pavadinimø apaèioje',
+  'Select from one of the projects below' => 'Iðrinkite vienà ið projektø apaèioje',
+  'Sep'                         => 'Rgs',
+  'September'                   => 'Rûgsëjis',
+  'Source'                      => 'Dokumentas',
+  'Subtotal'                    => 'Viso',
+  'Transaction Date missing!'   => 'Operacijos datos nëra!',
+  'Transaction deleted!'        => 'Operacija iðtrinta!',
+  'Transaction posted!'         => 'Operacija patvirtinta!',
+  'Update'                      => 'Atnaujinti',
+  'Vendor Invoice'              => 'Vendor Invoice',
+  'Vendor not on file!'         => 'Tokio tiekëjo nëra!',
+  'Yes'                         => 'Taip',
+  'to'                          => 'iki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'pirkimo_operacijà'           => 'ap_transaction',
+  'pardavimo_operacijà'         => 'ar_transaction',
+  'tæsti'                       => 'continue',
+  'iðtrinti'                    => 'delete',
+  'bÞ_operacija'                => 'gl_transaction',
+  'patvirtinti'                 => 'post',
+  'patvirtinti_kaip_naujà'      => 'post_as_new',
+  'pardavimo_sf'                => 'sales_invoice',
+  'atnaujinti'                  => 'update',
+  'vendor_invoice'              => 'vendor_invoice',
+  'taip'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/ic b/sql-ledger/locale/lt/ic
new file mode 100644 (file)
index 0000000..e749d21
--- /dev/null
@@ -0,0 +1,208 @@
+$self{texts} = {
+  'Active'                      => 'Aktyvus',
+  'Add'                         => 'Pridëti',
+  'Add Assembly'                => 'Pridëti rinkiná',
+  'Add Part'                    => 'Pridëti prekæ',
+  'Add Purchase Order'          => 'Pridëti Pirkimo uþsakymà',
+  'Add Sales Order'             => 'Pridëti Pardavimo uþsakymà',
+  'Add Service'                 => 'Pridëti Paslaugà',
+  'Address'                     => 'Adresas',
+  'Apr'                         => 'Bal',
+  'April'                       => 'Balandis',
+  'Assemblies'                  => 'Rinkiniai',
+  'Assemblies restocked!'       => 'Rinkiniai persandeliuoti!',
+  'Assembly Number missing!'    => 'Rinkiniø numeriø nëra!',
+  'Attachment'                  => 'Prisegta',
+  'Aug'                         => 'Rug',
+  'August'                      => 'Rugpjûtis',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Dëþë',
+  'Bought'                      => 'Nupirkta',
+  'COGS'                        => 'PPS',
+  'Cannot delete item already invoiced!' => 'Negalima iðtrinti prekës, kuriai sukurta sàskaita-faktûra!',
+  'Cannot delete item on order!' => 'Negalima iðtrinti prekës, kuri yra uþsakyme!',
+  'Cannot delete item which is part of an assembly!' => 'Negalima iðtrinti prekës, kuri yra rinkinio dalis!',
+  'Cannot delete item!'         => 'Neámanoma iðtrinti prekës!',
+  'Cannot stock assemblies!'    => 'Neámanoma sandelioti rinkinius!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontaktas',
+  'Continue'                    => 'Tæsti',
+  'Copies'                      => 'Kopijos',
+  'Dec'                         => 'Grd',
+  'December'                    => 'Gruodis',
+  'Delete'                      => 'Iðtrinti',
+  'Delivery Date'               => 'Prystatimo Data',
+  'Description'                 => 'Apraðymas',
+  'Drawing'                     => 'Brieþinys',
+  'E-mail'                      => 'E-paðtas',
+  'E-mail address missing!'     => 'E-paðto adreso nëra!',
+  'Edit Assembly'               => 'Redaguoti rinkiná',
+  'Edit Part'                   => 'Redaguoti prekæ',
+  'Edit Service'                => 'Redaguoti paslaugà',
+  'Expense'                     => 'Sànaudos',
+  'Extended'                    => 'Iðplësta',
+  'Fax'                         => 'Faksas',
+  'Feb'                         => 'Vas',
+  'February'                    => 'Vasaris',
+  'From'                        => 'Nuo',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'Image'                       => 'Pieðinys',
+  'In-line'                     => 'Vienaeilis',
+  'Include in Report'           => 'Ádëti á ataskaità',
+  'Income'                      => 'Pajamos',
+  'Individual Items'            => 'Individualios prekës',
+  'Inventory'                   => 'Prekës',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Prekës kiekis turi bûti lygus nuliui prieð paþymint rinkiná pasenusiu!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Prekës kiekis turi bûti lygus nuliui prieð paþymint ðià dalá pasenusia!',
+  'Inventory quantity must be zero!' => 'Prekës kiekis turi bûti lygus nuliui!',
+  'Invoice'                     => 'Sàskaita-faktûra',
+  'Invoice Date missing!'       => 'Sàskaitos-faktûros datos nëra!',
+  'Invoice Number'              => 'Sàskaitos-faktûros numeris',
+  'Invoice Number missing!'     => 'Sàskaitos-faktûra numerio nëra!',
+  'Item deleted!'               => 'Vienetas iðtrintas!',
+  'Item not on file!'           => 'Vieneto nëra áraðuose!',
+  'Jan'                         => 'Sau',
+  'January'                     => 'Sausis',
+  'Jul'                         => 'Lie',
+  'July'                        => 'Liepa',
+  'Jun'                         => 'Bir',
+  'June'                        => 'Birþelis',
+  'Last Cost'                   => 'Paskutinë kaina',
+  'Line Total'                  => 'Viso eilutëje',
+  'Link Accounts'               => 'Suriðti sàskaitas',
+  'List Price'                  => 'Pirkimo kaina',
+  'Make'                        => 'Gamintojas',
+  'Mar'                         => 'Kov',
+  'March'                       => 'Kovas',
+  'May'                         => 'Geg',
+  'May '                        => 'Geguþë',
+  'Message'                     => 'Þinutë',
+  'Microfiche'                  => 'Mikrofiða',
+  'Model'                       => 'Modelis',
+  'Name'                        => 'Vardas',
+  'No.'                         => 'Num',
+  'Notes'                       => 'Pastaba',
+  'Nov'                         => 'Lap',
+  'November'                    => 'Lapkritis',
+  'Number'                      => 'Numeris',
+  'Number missing in Row'       => 'Numerio nëra eilëje',
+  'Obsolete'                    => 'Pasenæ',
+  'Oct'                         => 'Spa',
+  'October'                     => 'Spalis',
+  'On Hand'                     => 'Likutis',
+  'On Order'                    => 'Uþsakyme',
+  'Order'                       => 'Uþsakymas',
+  'Order Date missing!'         => 'Uþsakymo datos nëra!',
+  'Order Number'                => 'Uþsakymo numeris',
+  'Order Number missing!'       => 'Uþsakymo numerio nëra!',
+  'Ordered'                     => 'Uþsakyta',
+  'Orphaned'                    => 'Naðlaitinis',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Ápakavimo sàraðas',
+  'Packing List Date missing!'  => 'Ápakavimo sàraðo datos nëra!',
+  'Packing List Number missing!' => 'Ápakavimo sàraðo numerio nëra!',
+  'Part'                        => 'Prekë',
+  'Part Number missing!'        => 'Prekës numerio nëra!',
+  'Parts'                       => 'Prekës',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript(TM)',
+  'Price'                       => 'Kaina',
+  'Printer'                     => 'Spausdintuvas',
+  'Project'                     => 'Projektas',
+  'Purchase Order'              => 'Pirkimo uþsakymas',
+  'Qty'                         => 'Kks',
+  'ROP'                         => 'ROP',
+  'Recd'                        => 'Gaut',
+  'Required by'                 => 'Iki kada',
+  'Sales'                       => 'Pardavimai',
+  'Sales Order'                 => 'Pardavimø uþsakymas',
+  'Save'                        => 'Iðsaugoti',
+  'Screen'                      => 'Ekranas',
+  'Select from one of the items below' => 'Iðrinkite vienà ið prekiø apaèioje',
+  'Select postscript or PDF!'   => 'Iðrinkite postscript arba PDF!',
+  'Sell Price'                  => 'Pardavimo kaina',
+  'Sep'                         => 'Rgs',
+  'September'                   => 'Rûgsëjis',
+  'Service'                     => 'Paslauga',
+  'Service Number missing!'     => 'Paslaugos numerio nëra!',
+  'Services'                    => 'Paslaugos',
+  'Ship'                        => 'Pristatymas',
+  'Ship to'                     => 'Pristatyti á',
+  'Short'                       => 'Stoka',
+  'Sold'                        => 'Parduota',
+  'Stock Assembly'              => 'Rinkiniai sandëlyje',
+  'Subject'                     => 'Dalykas',
+  'Subtotal'                    => 'Viso',
+  'Tax'                         => 'Mokëstis',
+  'To'                          => 'iki',
+  'Top Level'                   => 'Aukðèiausias lygis',
+  'Total'                       => 'Ið viso',
+  'Unit'                        => 'Vienetas',
+  'Unit of measure'             => 'Matavimo vienetas',
+  'Update'                      => 'Atnaujinti',
+  'Updated'                     => 'Atnaujinta',
+  'Weight'                      => 'Svoris',
+  'What type of item is this?'  => 'Koks ðio dalyko tipas?',
+  'ea'                          => 'kk',
+  'emailed to'                  => 'email do',
+  'hr'                          => 'val',
+  'sent to printer'             => 'pasiûsta á spausdintuvà',
+  'to'                          => 'iki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'pridëti'                     => 'add',
+  'pridëti_rinkiná'             => 'add_assembly',
+  'pridëti_prekæ'               => 'add_part',
+  'pridëti_paslaugà'            => 'add_service',
+  'tæsti'                       => 'continue',
+  'iðtrinti'                    => 'delete',
+  'redaguoti_rinkiná'           => 'edit_assembly',
+  'redaguoti_prekæ'             => 'edit_part',
+  'redaguoti_paslaugà'          => 'edit_service',
+  'iðsaugoti'                   => 'save',
+  'atnaujinti'                  => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/io b/sql-ledger/locale/lt/io
new file mode 100644 (file)
index 0000000..3b28ede
--- /dev/null
@@ -0,0 +1,108 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Pridëti Pirkimo uþsakymà',
+  'Add Sales Order'             => 'Pridëti Pardavimo uþsakymà',
+  'Address'                     => 'Adresas',
+  'Apr'                         => 'Bal',
+  'April'                       => 'Balandis',
+  'Attachment'                  => 'Prisegta',
+  'Aug'                         => 'Rug',
+  'August'                      => 'Rugpjûtis',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Dëþë',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontaktas',
+  'Continue'                    => 'Tæsti',
+  'Copies'                      => 'Kopijos',
+  'Dec'                         => 'Grd',
+  'December'                    => 'Gruodis',
+  'Delivery Date'               => 'Prystatimo Data',
+  'Description'                 => 'Apraðymas',
+  'E-mail'                      => 'E-paðtas',
+  'E-mail address missing!'     => 'E-paðto adreso nëra!',
+  'Extended'                    => 'Iðplësta',
+  'Fax'                         => 'Faksas',
+  'Feb'                         => 'Vas',
+  'February'                    => 'Vasaris',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'In-line'                     => 'Vienaeilis',
+  'Invoice'                     => 'Sàskaita-faktûra',
+  'Invoice Date missing!'       => 'Sàskaitos-faktûros datos nëra!',
+  'Invoice Number missing!'     => 'Sàskaitos-faktûra numerio nëra!',
+  'Item not on file!'           => 'Vieneto nëra áraðuose!',
+  'Jan'                         => 'Sau',
+  'January'                     => 'Sausis',
+  'Jul'                         => 'Lie',
+  'July'                        => 'Liepa',
+  'Jun'                         => 'Bir',
+  'June'                        => 'Birþelis',
+  'Mar'                         => 'Kov',
+  'March'                       => 'Kovas',
+  'May'                         => 'Geg',
+  'May '                        => 'Geguþë',
+  'Message'                     => 'Þinutë',
+  'Name'                        => 'Vardas',
+  'No.'                         => 'Num',
+  'Nov'                         => 'Lap',
+  'November'                    => 'Lapkritis',
+  'Number'                      => 'Numeris',
+  'Number missing in Row'       => 'Numerio nëra eilëje',
+  'Oct'                         => 'Spa',
+  'October'                     => 'Spalis',
+  'Order'                       => 'Uþsakymas',
+  'Order Date missing!'         => 'Uþsakymo datos nëra!',
+  'Order Number missing!'       => 'Uþsakymo numerio nëra!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Ápakavimo sàraðas',
+  'Packing List Date missing!'  => 'Ápakavimo sàraðo datos nëra!',
+  'Packing List Number missing!' => 'Ápakavimo sàraðo numerio nëra!',
+  'Part'                        => 'Prekë',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript(TM)',
+  'Price'                       => 'Kaina',
+  'Printer'                     => 'Spausdintuvas',
+  'Project'                     => 'Projektas',
+  'Purchase Order'              => 'Pirkimo uþsakymas',
+  'Qty'                         => 'Kks',
+  'Recd'                        => 'Gaut',
+  'Required by'                 => 'Iki kada',
+  'Sales Order'                 => 'Pardavimø uþsakymas',
+  'Screen'                      => 'Ekranas',
+  'Select from one of the items below' => 'Iðrinkite vienà ið prekiø apaèioje',
+  'Select postscript or PDF!'   => 'Iðrinkite postscript arba PDF!',
+  'Sep'                         => 'Rgs',
+  'September'                   => 'Rûgsëjis',
+  'Service'                     => 'Paslauga',
+  'Ship'                        => 'Pristatymas',
+  'Ship to'                     => 'Pristatyti á',
+  'Subject'                     => 'Dalykas',
+  'To'                          => 'iki',
+  'Unit'                        => 'Vienetas',
+  'What type of item is this?'  => 'Koks ðio dalyko tipas?',
+  'emailed to'                  => 'email do',
+  'sent to printer'             => 'pasiûsta á spausdintuvà',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'tæsti'                       => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/ir b/sql-ledger/locale/lt/ir
new file mode 100644 (file)
index 0000000..003b9a6
--- /dev/null
@@ -0,0 +1,180 @@
+$self{texts} = {
+  'Account'                     => 'Sàskaita',
+  'Add Purchase Order'          => 'Pridëti Pirkimo uþsakymà',
+  'Add Sales Order'             => 'Pridëti Pardavimo uþsakymà',
+  'Add Vendor Invoice'          => 'Add Vendor Invoice',
+  'Address'                     => 'Adresas',
+  'Amount'                      => 'Suma',
+  'Apr'                         => 'Bal',
+  'April'                       => 'Balandis',
+  'Are you sure you want to delete Invoice Number' => 'Ar Jus tikrai norite iðtrinti saskaitu-fakturos numeris:',
+  'Attachment'                  => 'Prisegta',
+  'Aug'                         => 'Rug',
+  'August'                      => 'Rugpjûtis',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Dëþë',
+  'Cannot delete invoice!'      => 'Neámanoma iðtrinti sàskaitos-faktûros!',
+  'Cannot post invoice for a closed period!' => 'Neámanoma patvirtinti sàskaitos-faktûros uþdarajam periodui!',
+  'Cannot post invoice!'        => 'Neámanoma patvirtinti sàskaitos-faktûros!',
+  'Cannot post payment for a closed period!' => 'Neámanoma patvirtinti mokëjimo uþdarajam periodui!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Patvirtinti!',
+  'Contact'                     => 'Kontaktas',
+  'Continue'                    => 'Tæsti',
+  'Copies'                      => 'Kopijos',
+  'Currency'                    => 'Valiûta',
+  'Customer not on file!'       => 'Tokio kliento nëra!',
+  'Date'                        => 'Data',
+  'Dec'                         => 'Grd',
+  'December'                    => 'Gruodis',
+  'Delete'                      => 'Iðtrinti',
+  'Delivery Date'               => 'Prystatimo Data',
+  'Description'                 => 'Apraðymas',
+  'Due Date'                    => 'Iki Data',
+  'E-mail'                      => 'E-paðtas',
+  'E-mail address missing!'     => 'E-paðto adreso nëra!',
+  'Edit Vendor Invoice'         => 'Edit Vendor Invoice',
+  'Exch'                        => 'Kurs.',
+  'Exchangerate'                => 'Keitimo kursas',
+  'Exchangerate for payment missing!' => 'Mokëjimo keitimo kurso nëra!',
+  'Exchangerate missing!'       => 'Keitimo kurso nëra!',
+  'Extended'                    => 'Iðplësta',
+  'Fax'                         => 'Faksas',
+  'Feb'                         => 'Vas',
+  'February'                    => 'Vasaris',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'In-line'                     => 'Vienaeilis',
+  'Invoice'                     => 'Sàskaita-faktûra',
+  'Invoice Date'                => 'Sàskaitos-faktûros data',
+  'Invoice Date missing!'       => 'Sàskaitos-faktûros datos nëra!',
+  'Invoice Number'              => 'Sàskaitos-faktûros numeris',
+  'Invoice Number missing!'     => 'Sàskaitos-faktûra numerio nëra!',
+  'Invoice deleted!'            => 'Sàskaitos-faktûra iðtrintos!',
+  'Invoice posted!'             => 'Sàskaitos-faktûra patvirtintos!',
+  'Item not on file!'           => 'Vieneto nëra áraðuose!',
+  'Jan'                         => 'Sau',
+  'January'                     => 'Sausis',
+  'Jul'                         => 'Lie',
+  'July'                        => 'Liepa',
+  'Jun'                         => 'Bir',
+  'June'                        => 'Birþelis',
+  'Mar'                         => 'Kov',
+  'March'                       => 'Kovas',
+  'May'                         => 'Geg',
+  'May '                        => 'Geguþë',
+  'Message'                     => 'Þinutë',
+  'Name'                        => 'Vardas',
+  'No.'                         => 'Num',
+  'Notes'                       => 'Pastaba',
+  'Nov'                         => 'Lap',
+  'November'                    => 'Lapkritis',
+  'Number'                      => 'Numeris',
+  'Number missing in Row'       => 'Numerio nëra eilëje',
+  'Oct'                         => 'Spa',
+  'October'                     => 'Spalis',
+  'Order'                       => 'Uþsakymas',
+  'Order Date missing!'         => 'Uþsakymo datos nëra!',
+  'Order Number'                => 'Uþsakymo numeris',
+  'Order Number missing!'       => 'Uþsakymo numerio nëra!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Ápakavimo sàraðas',
+  'Packing List Date missing!'  => 'Ápakavimo sàraðo datos nëra!',
+  'Packing List Number missing!' => 'Ápakavimo sàraðo numerio nëra!',
+  'Part'                        => 'Prekë',
+  'Payment date missing!'       => 'Mokëjimo datos nëra',
+  'Payments'                    => 'Mokëjimai',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Patvirtinti',
+  'Post as new'                 => 'Patvirtinti kaip naujà',
+  'Postscript'                  => 'Postscript(TM)',
+  'Price'                       => 'Kaina',
+  'Printer'                     => 'Spausdintuvas',
+  'Project'                     => 'Projektas',
+  'Project not on file!'        => 'Nëra tokio projekto!',
+  'Purchase Order'              => 'Pirkimo uþsakymas',
+  'Qty'                         => 'Kks',
+  'Recd'                        => 'Gaut',
+  'Record in'                   => 'Áraðyti á',
+  'Required by'                 => 'Iki kada',
+  'Sales Order'                 => 'Pardavimø uþsakymas',
+  'Screen'                      => 'Ekranas',
+  'Select from one of the items below' => 'Iðrinkite vienà ið prekiø apaèioje',
+  'Select from one of the names below' => 'Iðrinkite vienà ið pavadinimø apaèioje',
+  'Select from one of the projects below' => 'Iðrinkite vienà ið projektø apaèioje',
+  'Select postscript or PDF!'   => 'Iðrinkite postscript arba PDF!',
+  'Sep'                         => 'Rgs',
+  'September'                   => 'Rûgsëjis',
+  'Service'                     => 'Paslauga',
+  'Ship'                        => 'Pristatymas',
+  'Ship to'                     => 'Pristatyti á',
+  'Source'                      => 'Dokumentas',
+  'Subject'                     => 'Dalykas',
+  'Subtotal'                    => 'Viso',
+  'Tax Included'                => 'su mokesèiais',
+  'To'                          => 'iki',
+  'Total'                       => 'Ið viso',
+  'Unit'                        => 'Vienetas',
+  'Update'                      => 'Atnaujinti',
+  'Vendor'                      => 'Tiekëjas',
+  'Vendor missing!'             => 'Tiekëjo Vardo nëra!',
+  'Vendor not on file!'         => 'Tokio tiekëjo nëra!',
+  'What type of item is this?'  => 'Koks ðio dalyko tipas?',
+  'Yes'                         => 'Taip',
+  'ea'                          => 'kk',
+  'emailed to'                  => 'email do',
+  'sent to printer'             => 'pasiûsta á spausdintuvà',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'tæsti'                       => 'continue',
+  'iðtrinti'                    => 'delete',
+  'uþsakymas'                   => 'order',
+  'patvirtinti'                 => 'post',
+  'patvirtinti_kaip_naujà'      => 'post_as_new',
+  'atnaujinti'                  => 'update',
+  'taip'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/is b/sql-ledger/locale/lt/is
new file mode 100644 (file)
index 0000000..d7b1e50
--- /dev/null
@@ -0,0 +1,187 @@
+$self{texts} = {
+  'Account'                     => 'Sàskaita',
+  'Add Purchase Order'          => 'Pridëti Pirkimo uþsakymà',
+  'Add Sales Invoice'           => 'Pridëti Pardavimo sàskaità-faktûrà',
+  'Add Sales Order'             => 'Pridëti Pardavimo uþsakymà',
+  'Address'                     => 'Adresas',
+  'Amount'                      => 'Suma',
+  'Apr'                         => 'Bal',
+  'April'                       => 'Balandis',
+  'Are you sure you want to delete Invoice Number' => 'Ar Jus tikrai norite iðtrinti saskaitu-fakturos numeris:',
+  'Attachment'                  => 'Prisegta',
+  'Aug'                         => 'Rug',
+  'August'                      => 'Rugpjûtis',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Dëþë',
+  'Cannot delete invoice!'      => 'Neámanoma iðtrinti sàskaitos-faktûros!',
+  'Cannot post invoice for a closed period!' => 'Neámanoma patvirtinti sàskaitos-faktûros uþdarajam periodui!',
+  'Cannot post invoice!'        => 'Neámanoma patvirtinti sàskaitos-faktûros!',
+  'Cannot post payment for a closed period!' => 'Neámanoma patvirtinti mokëjimo uþdarajam periodui!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Patvirtinti!',
+  'Contact'                     => 'Kontaktas',
+  'Continue'                    => 'Tæsti',
+  'Copies'                      => 'Kopijos',
+  'Credit Limit'                => 'Kredito riba',
+  'Currency'                    => 'Valiûta',
+  'Customer'                    => 'Klientas',
+  'Customer missing!'           => 'Kliento vardo nëra!',
+  'Customer not on file!'       => 'Tokio kliento nëra!',
+  'Date'                        => 'Data',
+  'Dec'                         => 'Grd',
+  'December'                    => 'Gruodis',
+  'Delete'                      => 'Iðtrinti',
+  'Delivery Date'               => 'Prystatimo Data',
+  'Description'                 => 'Apraðymas',
+  'Due Date'                    => 'Iki Data',
+  'E-mail'                      => 'E-paðtas',
+  'E-mail address missing!'     => 'E-paðto adreso nëra!',
+  'Edit Sales Invoice'          => 'Redaguoti pardavimo sàskaità-faktûrà',
+  'Exch'                        => 'Kurs.',
+  'Exchangerate'                => 'Keitimo kursas',
+  'Exchangerate for payment missing!' => 'Mokëjimo keitimo kurso nëra!',
+  'Exchangerate missing!'       => 'Keitimo kurso nëra!',
+  'Extended'                    => 'Iðplësta',
+  'Fax'                         => 'Faksas',
+  'Feb'                         => 'Vas',
+  'February'                    => 'Vasaris',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'In-line'                     => 'Vienaeilis',
+  'Invoice'                     => 'Sàskaita-faktûra',
+  'Invoice Date'                => 'Sàskaitos-faktûros data',
+  'Invoice Date missing!'       => 'Sàskaitos-faktûros datos nëra!',
+  'Invoice Number'              => 'Sàskaitos-faktûros numeris',
+  'Invoice Number missing!'     => 'Sàskaitos-faktûra numerio nëra!',
+  'Invoice deleted!'            => 'Sàskaitos-faktûra iðtrintos!',
+  'Invoice posted!'             => 'Sàskaitos-faktûra patvirtintos!',
+  'Item not on file!'           => 'Vieneto nëra áraðuose!',
+  'Jan'                         => 'Sau',
+  'January'                     => 'Sausis',
+  'Jul'                         => 'Lie',
+  'July'                        => 'Liepa',
+  'Jun'                         => 'Bir',
+  'June'                        => 'Birþelis',
+  'Mar'                         => 'Kov',
+  'March'                       => 'Kovas',
+  'May'                         => 'Geg',
+  'May '                        => 'Geguþë',
+  'Message'                     => 'Þinutë',
+  'Name'                        => 'Vardas',
+  'No.'                         => 'Num',
+  'Notes'                       => 'Pastaba',
+  'Nov'                         => 'Lap',
+  'November'                    => 'Lapkritis',
+  'Number'                      => 'Numeris',
+  'Number missing in Row'       => 'Numerio nëra eilëje',
+  'Oct'                         => 'Spa',
+  'October'                     => 'Spalis',
+  'Order'                       => 'Uþsakymas',
+  'Order Date missing!'         => 'Uþsakymo datos nëra!',
+  'Order Number'                => 'Uþsakymo numeris',
+  'Order Number missing!'       => 'Uþsakymo numerio nëra!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Ápakavimo sàraðas',
+  'Packing List Date missing!'  => 'Ápakavimo sàraðo datos nëra!',
+  'Packing List Number missing!' => 'Ápakavimo sàraðo numerio nëra!',
+  'Part'                        => 'Prekë',
+  'Payment date missing!'       => 'Mokëjimo datos nëra',
+  'Payments'                    => 'Mokëjimai',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Patvirtinti',
+  'Post as new'                 => 'Patvirtinti kaip naujà',
+  'Postscript'                  => 'Postscript(TM)',
+  'Price'                       => 'Kaina',
+  'Print'                       => 'Spausdinti',
+  'Printer'                     => 'Spausdintuvas',
+  'Project'                     => 'Projektas',
+  'Project not on file!'        => 'Nëra tokio projekto!',
+  'Purchase Order'              => 'Pirkimo uþsakymas',
+  'Qty'                         => 'Kks',
+  'Recd'                        => 'Gaut',
+  'Record in'                   => 'Áraðyti á',
+  'Remaining'                   => 'Likutis',
+  'Required by'                 => 'Iki kada',
+  'Sales Order'                 => 'Pardavimø uþsakymas',
+  'Screen'                      => 'Ekranas',
+  'Select from one of the items below' => 'Iðrinkite vienà ið prekiø apaèioje',
+  'Select from one of the names below' => 'Iðrinkite vienà ið pavadinimø apaèioje',
+  'Select from one of the projects below' => 'Iðrinkite vienà ið projektø apaèioje',
+  'Select postscript or PDF!'   => 'Iðrinkite postscript arba PDF!',
+  'Sep'                         => 'Rgs',
+  'September'                   => 'Rûgsëjis',
+  'Service'                     => 'Paslauga',
+  'Ship'                        => 'Pristatymas',
+  'Ship to'                     => 'Pristatyti á',
+  'Ship via'                    => 'Pristatyti per',
+  'Source'                      => 'Dokumentas',
+  'Subject'                     => 'Dalykas',
+  'Subtotal'                    => 'Viso',
+  'Tax Included'                => 'su mokesèiais',
+  'To'                          => 'iki',
+  'Total'                       => 'Ið viso',
+  'Unit'                        => 'Vienetas',
+  'Update'                      => 'Atnaujinti',
+  'Vendor not on file!'         => 'Tokio tiekëjo nëra!',
+  'What type of item is this?'  => 'Koks ðio dalyko tipas?',
+  'Yes'                         => 'Taip',
+  'ea'                          => 'kk',
+  'emailed to'                  => 'email do',
+  'sent to printer'             => 'pasiûsta á spausdintuvà',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'tæsti'                       => 'continue',
+  'iðtrinti'                    => 'delete',
+  'e_paðtas'                    => 'e_mail',
+  'uþsakymas'                   => 'order',
+  'patvirtinti'                 => 'post',
+  'patvirtinti_kaip_naujà'      => 'post_as_new',
+  'spausdinti'                  => 'print',
+  'pristatyti_á'                => 'ship_to',
+  'atnaujinti'                  => 'update',
+  'taip'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/login b/sql-ledger/locale/lt/login
new file mode 100644 (file)
index 0000000..8a42d2a
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'Apie...',
+  'Database Host'               => 'Duomenø bazës hostas',
+  'Dataset'                     => 'Duomenø aibë',
+  'Incorrect Dataset version!'  => 'Neteisinga duomenø aibës versija!',
+  'Incorrect Password!'         => 'Neteisingas slaptaþodis!',
+  'Licensed to'                 => 'Licenzijuota...',
+  'Login'                       => 'Prisijungimas',
+  'Name'                        => 'Vardas',
+  'Password'                    => 'Slaptaþodis',
+  'User'                        => 'Vartotojas',
+  'Version'                     => 'Versija',
+  'You are logged out!'         => 'Jûs iðsijungëte!',
+  'You did not enter a name!'   => 'Neávedëte vardo!',
+  'is not a member!'            => 'nëra narys!',
+  'localhost'                   => 'lokalhostas',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'prisijungimas'               => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/menu b/sql-ledger/locale/lt/menu
new file mode 100644 (file)
index 0000000..460ea5b
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => 'Pirkimai',
+  'AP Aging'                    => 'Pirkimo Skolos',
+  'AR'                          => 'Pardavimai',
+  'AR Aging'                    => 'Pardavimo Skolos',
+  'Accounting Menu'             => 'Apskaitos Menu',
+  'Add Account'                 => 'Pridëti sàskaità',
+  'Add Assembly'                => 'Pridëti rinkiná',
+  'Add Customer'                => 'Pridëti klientà',
+  'Add GIFI'                    => 'Pridëti GIFI',
+  'Add Part'                    => 'Pridëti prekæ',
+  'Add Project'                 => 'Pridëti proektà',
+  'Add Service'                 => 'Pridëti Paslaugà',
+  'Add Transaction'             => 'Pridëti Operacijà',
+  'Add Vendor'                  => 'Pridëti Tiekëja',
+  'Assemblies'                  => 'Rinkiniai',
+  'Audit Control'               => 'Audito kontrolë',
+  'Backup'                      => 'Reservinë kopija',
+  'Balance Sheet'               => 'Balanso lëntelë',
+  'Cash'                        => 'Kasa',
+  'Chart of Accounts'           => 'Sàskaitø planas',
+  'Check'                       => 'Èekis',
+  'Customers'                   => 'Klientai',
+  'General Ledger'              => 'Bendrasis þurnalas',
+  'Goods & Services'            => 'Prekës ir Paslaugos',
+  'HTML Templates'              => 'HTML ðablonai',
+  'Income Statement'            => 'Pelno/nuostolio ataskaita',
+  'Invoice'                     => 'Sàskaita-faktûra',
+  'LaTeX Templates'             => 'LaTeX ðablonai',
+  'List Accounts'               => 'Sàskaitø sàraðas',
+  'List GIFI'                   => 'GIFI sàraðas',
+  'Logout'                      => 'Iðsijungti',
+  'Order Entry'                 => 'Uþsakymo áraðas',
+  'Packing List'                => 'Ápakavimo sàraðas',
+  'Parts'                       => 'Prekës',
+  'Payment'                     => 'Mokëjimas',
+  'Payments'                    => 'Mokëjimai',
+  'Preferences'                 => 'Nuostatos',
+  'Projects'                    => 'Projektai',
+  'Purchase Order'              => 'Pirkimo uþsakymas',
+  'Purchase Orders'             => 'Pirkimo uþsakymai',
+  'Receipt'                     => 'Kasos orderis',
+  'Receipts'                    => 'Kasos orderiai',
+  'Reconciliation'              => 'Sutaikinimas',
+  'Reports'                     => 'Ataskaitos',
+  'Sales Invoice'               => 'Pardavimo SF',
+  'Sales Order'                 => 'Pardavimø uþsakymas',
+  'Sales Orders'                => 'Pardavimø uþsakymai',
+  'Save to File'                => 'Iðsaugoti á failà',
+  'Send by E-Mail'              => 'Iðsiûsti e-paðtu',
+  'Services'                    => 'Paslaugos',
+  'Statement'                   => 'Suvestinë',
+  'Stock Assembly'              => 'Rinkiniai sandëlyje',
+  'Stylesheet'                  => 'Stiliø lentelë',
+  'System'                      => 'Sistema',
+  'Tax collected'               => 'Mokesèiai surinkti',
+  'Tax paid'                    => 'Mokesèiai sumokëti',
+  'Transactions'                => 'Operacijos',
+  'Trial Balance'               => 'Bandomasis balansas',
+  'Vendor Invoice'              => 'Vendor Invoice',
+  'Vendors'                     => 'Tiekëjai',
+  'Version'                     => 'Versija',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/oe b/sql-ledger/locale/lt/oe
new file mode 100644 (file)
index 0000000..c0786c1
--- /dev/null
@@ -0,0 +1,202 @@
+$self{texts} = {
+  'Add'                         => 'Pridëti',
+  'Add Purchase Order'          => 'Pridëti Pirkimo uþsakymà',
+  'Add Sales Invoice'           => 'Pridëti Pardavimo sàskaità-faktûrà',
+  'Add Sales Order'             => 'Pridëti Pardavimo uþsakymà',
+  'Add Vendor Invoice'          => 'Add Vendor Invoice',
+  'Address'                     => 'Adresas',
+  'Amount'                      => 'Suma',
+  'Apr'                         => 'Bal',
+  'April'                       => 'Balandis',
+  'Are you sure you want to delete Order Number' => 'Ar Jus tikrai norite iðtrinti uzsakimas numeris:',
+  'Attachment'                  => 'Prisegta',
+  'Aug'                         => 'Rug',
+  'August'                      => 'Rugpjûtis',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Dëþë',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Neámanoma iðtrinti uþsakymo!',
+  'Cannot save order!'          => 'Neámanoma iðsaugoti uþsakymo!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Uþdaryta',
+  'Confirm!'                    => 'Patvirtinti!',
+  'Contact'                     => 'Kontaktas',
+  'Continue'                    => 'Tæsti',
+  'Copies'                      => 'Kopijos',
+  'Credit Limit'                => 'Kredito riba',
+  'Curr'                        => 'Val.',
+  'Currency'                    => 'Valiûta',
+  'Customer'                    => 'Klientas',
+  'Customer missing!'           => 'Kliento vardo nëra!',
+  'Customer not on file!'       => 'Tokio kliento nëra!',
+  'Date'                        => 'Data',
+  'Dec'                         => 'Grd',
+  'December'                    => 'Gruodis',
+  'Delete'                      => 'Iðtrinti',
+  'Delivery Date'               => 'Prystatimo Data',
+  'Description'                 => 'Apraðymas',
+  'E-mail'                      => 'E-paðtas',
+  'E-mail address missing!'     => 'E-paðto adreso nëra!',
+  'Edit Purchase Order'         => 'Redaguoti pirkimo uþsakymà',
+  'Edit Sales Order'            => 'Redaguoti pardavimo uþsakymà',
+  'Exchangerate'                => 'Keitimo kursas',
+  'Exchangerate missing!'       => 'Keitimo kurso nëra!',
+  'Extended'                    => 'Iðplësta',
+  'Fax'                         => 'Faksas',
+  'Feb'                         => 'Vas',
+  'February'                    => 'Vasaris',
+  'From'                        => 'Nuo',
+  'Group'                       => 'Group',
+  'Group Items'                 => 'Group Items',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Vienaeilis',
+  'Include in Report'           => 'Ádëti á ataskaità',
+  'Invoice'                     => 'Sàskaita-faktûra',
+  'Invoice Date missing!'       => 'Sàskaitos-faktûros datos nëra!',
+  'Invoice Number missing!'     => 'Sàskaitos-faktûra numerio nëra!',
+  'Item not on file!'           => 'Vieneto nëra áraðuose!',
+  'Jan'                         => 'Sau',
+  'January'                     => 'Sausis',
+  'Jul'                         => 'Lie',
+  'July'                        => 'Liepa',
+  'Jun'                         => 'Bir',
+  'June'                        => 'Birþelis',
+  'Mar'                         => 'Kov',
+  'March'                       => 'Kovas',
+  'May'                         => 'Geg',
+  'May '                        => 'Geguþë',
+  'Message'                     => 'Þinutë',
+  'Name'                        => 'Vardas',
+  'No.'                         => 'Num',
+  'Notes'                       => 'Pastaba',
+  'Nov'                         => 'Lap',
+  'November'                    => 'Lapkritis',
+  'Number'                      => 'Numeris',
+  'Number missing in Row'       => 'Numerio nëra eilëje',
+  'O'                           => 'O',
+  'Oct'                         => 'Spa',
+  'October'                     => 'Spalis',
+  'Open'                        => 'Atidaryti',
+  'Order'                       => 'Uþsakymas',
+  'Order Date'                  => 'Uþsakymo data',
+  'Order Date missing!'         => 'Uþsakymo datos nëra!',
+  'Order Number'                => 'Uþsakymo numeris',
+  'Order Number missing!'       => 'Uþsakymo numerio nëra!',
+  'Order deleted!'              => 'Uþsakymai iðtrinti!',
+  'Order saved!'                => 'Uþsakymas iðsaugotas!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Ápakavimo sàraðas',
+  'Packing List Date missing!'  => 'Ápakavimo sàraðo datos nëra!',
+  'Packing List Number missing!' => 'Ápakavimo sàraðo numerio nëra!',
+  'Part'                        => 'Prekë',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript(TM)',
+  'Price'                       => 'Kaina',
+  'Print'                       => 'Spausdinti',
+  'Printer'                     => 'Spausdintuvas',
+  'Project'                     => 'Projektas',
+  'Project not on file!'        => 'Nëra tokio projekto!',
+  'Purchase Order'              => 'Pirkimo uþsakymas',
+  'Purchase Orders'             => 'Pirkimo uþsakymai',
+  'Qty'                         => 'Kks',
+  'Recd'                        => 'Gaut',
+  'Remaining'                   => 'Likutis',
+  'Required by'                 => 'Iki kada',
+  'Sales Order'                 => 'Pardavimø uþsakymas',
+  'Sales Orders'                => 'Pardavimø uþsakymai',
+  'Save'                        => 'Iðsaugoti',
+  'Save as new'                 => 'Iðsaugoti kaip naujà',
+  'Screen'                      => 'Ekranas',
+  'Select from one of the items below' => 'Iðrinkite vienà ið prekiø apaèioje',
+  'Select from one of the names below' => 'Iðrinkite vienà ið pavadinimø apaèioje',
+  'Select from one of the projects below' => 'Iðrinkite vienà ið projektø apaèioje',
+  'Select postscript or PDF!'   => 'Iðrinkite postscript arba PDF!',
+  'Sep'                         => 'Rgs',
+  'September'                   => 'Rûgsëjis',
+  'Service'                     => 'Paslauga',
+  'Ship'                        => 'Pristatymas',
+  'Ship to'                     => 'Pristatyti á',
+  'Ship via'                    => 'Pristatyti per',
+  'Subject'                     => 'Dalykas',
+  'Subtotal'                    => 'Viso',
+  'Tax'                         => 'Mokëstis',
+  'Tax Included'                => 'su mokesèiais',
+  'Terms: Net'                  => 'Terminas: ',
+  'To'                          => 'iki',
+  'Total'                       => 'Ið viso',
+  'Unit'                        => 'Vienetas',
+  'Update'                      => 'Atnaujinti',
+  'Vendor'                      => 'Tiekëjas',
+  'Vendor missing!'             => 'Tiekëjo Vardo nëra!',
+  'Vendor not on file!'         => 'Tokio tiekëjo nëra!',
+  'What type of item is this?'  => 'Koks ðio dalyko tipas?',
+  'Yes'                         => 'Taip',
+  'days'                        => 'dienos',
+  'ea'                          => 'kk',
+  'emailed to'                  => 'email do',
+  'sent to printer'             => 'pasiûsta á spausdintuvà',
+  'to'                          => 'iki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'vendor_invoice'              => 'vendor_invoice',
+  'yes'                         => 'yes',
+  'pridëti'                     => 'add',
+  'tæsti'                       => 'continue',
+  'iðtrinti'                    => 'delete',
+  'e_paðtas'                    => 'e_mail',
+  'sàskaita_faktûra'            => 'invoice',
+  'spausdinti'                  => 'print',
+  'iðsaugoti'                   => 'save',
+  'iðsaugoti_kaip_naujà'        => 'save_as_new',
+  'pristatyti_á'                => 'ship_to',
+  'atnaujinti'                  => 'update',
+  'taip'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/pe b/sql-ledger/locale/lt/pe
new file mode 100644 (file)
index 0000000..fa58e62
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Pridëti',
+  'Add Project'                 => 'Pridëti proektà',
+  'All'                         => 'Visi',
+  'Continue'                    => 'Tæsti',
+  'Delete'                      => 'Iðtrinti',
+  'Description'                 => 'Apraðymas',
+  'Edit Project'                => 'Redaguoti projektà',
+  'Number'                      => 'Numeris',
+  'Orphaned'                    => 'Naðlaitinis',
+  'Project'                     => 'Projektas',
+  'Project Number missing!'     => 'Projekto numerio nëra!',
+  'Project deleted!'            => 'Projektas iðtrintas!',
+  'Project saved!'              => 'Projektas iðsaugotas!',
+  'Projects'                    => 'Projektai',
+  'Save'                        => 'Iðsaugoti',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'pridëti'                     => 'add',
+  'tæsti'                       => 'continue',
+  'iðtrinti'                    => 'delete',
+  'iðsaugoti'                   => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/rc b/sql-ledger/locale/lt/rc
new file mode 100644 (file)
index 0000000..7e57584
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Sàskaita',
+  'Balance'                     => 'Balansas',
+  'Cleared Balance'             => 'Baigiamasis balansas',
+  'Continue'                    => 'Tæsti',
+  'Date'                        => 'Data',
+  'Deposit'                     => 'Depozitas',
+  'Description'                 => 'Apraðymas',
+  'Difference'                  => 'Skirtumas',
+  'Done'                        => 'Ávykdyta',
+  'Exchangerate Difference'     => 'Keitimo kurso skirtumas',
+  'From'                        => 'Nuo',
+  'Out of balance!'             => 'Nesubalansuota!',
+  'Payment'                     => 'Mokëjimas',
+  'Reconciliation'              => 'Sutaikinimas',
+  'Select all'                  => 'Iðrinkti viskà',
+  'Source'                      => 'Dokumentas',
+  'Statement Balance'           => 'Balanso suvestinë',
+  'Update'                      => 'Atnaujinti',
+  'to'                          => 'iki',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'tæsti'                       => 'continue',
+  'Ávykdyta'                    => 'done',
+  'iðrinkti_viskà'              => 'select_all',
+  'atnaujinti'                  => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/lt/rp b/sql-ledger/locale/lt/rp
new file mode 100644 (file)
index 0000000..83cb9c0
--- /dev/null
@@ -0,0 +1,120 @@
+$self{texts} = {
+  'AP Aging'                    => 'Pirkimo Skolos',
+  'AR Aging'                    => 'Pardavimo Skolos',
+  'Account'                     => 'Sàskaita',
+  'Accounts'                    => 'Sàskaitos',
+  'Amount'                      => 'Suma',
+  'Apr'                         => 'Bal',
+  'April'                       => 'Balandis',
+  'Attachment'                  => 'Prisegta',
+  'Aug'                         => 'Rug',
+  'August'                      => 'Rugpjûtis',
+  'Balance'                     => 'Balansas',
+  'Balance Sheet'               => 'Balanso lëntelë',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Grynais',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Palyginti su',
+  'Continue'                    => 'Tæsti',
+  'Copies'                      => 'Kopijos',
+  'Credit'                      => 'Kreditas',
+  'Current'                     => 'Dabartinis',
+  'Customer'                    => 'Klientas',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Debetas',
+  'Dec'                         => 'Grd',
+  'December'                    => 'Gruodis',
+  'Decimalplaces'               => 'Skaièiø po taðko',
+  'Department'                  => 'Department',
+  'Description'                 => 'Apraðymas',
+  'Due'                         => 'Iki',
+  'E-mail'                      => 'E-paðtas',
+  'E-mail Statement to'         => 'Suvestinæ suisti per e-pastà á',
+  'Feb'                         => 'Vas',
+  'February'                    => 'Vasaris',
+  'From'                        => 'Nuo',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Antraðtë',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Vienaeilis',
+  'Include in Report'           => 'Ádëti á ataskaità',
+  'Income Statement'            => 'Pelno/nuostolio ataskaita',
+  'Invoice'                     => 'Sàskaita-faktûra',
+  'Jan'                         => 'Sau',
+  'January'                     => 'Sausis',
+  'Jul'                         => 'Lie',
+  'July'                        => 'Liepa',
+  'Jun'                         => 'Bir',
+  'June'                        => 'Birþelis',
+  'Mar'                         => 'Kov',
+  'March'                       => 'Kovas',
+  'May'                         => 'Geg',
+  'May '                        => 'Geguþë',
+  'Message'                     => 'Þinutë',
+  'N/A'                         => 'N/A',
+  'Nothing selected!'           => 'Nieko neiðrinkta!',
+  'Nov'                         => 'Lap',
+  'November'                    => 'Lapkritis',
+  'Oct'                         => 'Spa',
+  'October'                     => 'Spalis',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Mokëjimai',
+  'Postscript'                  => 'Postscript(TM)',
+  'Print'                       => 'Spausdinti',
+  'Printer'                     => 'Spausdintuvas',
+  'Project Number'              => 'Project Number',
+  'Receipts'                    => 'Kasos orderiai',
+  'Report for'                  => 'Ataskaita...',
+  'Retained Earnings'           => 'Turimi uþdarbiai',
+  'Screen'                      => 'Ekranas',
+  'Select all'                  => 'Iðrinkti viskà',
+  'Select postscript or PDF!'   => 'Iðrinkite postscript arba PDF!',
+  'Sep'                         => 'Rgs',
+  'September'                   => 'Rûgsëjis',
+  'Source'                      => 'Dokumentas',
+  'Standard'                    => 'Standartas',
+  'Statement'                   => 'Suvestinë',
+  'Statement sent to'           => 'Siusti suvestinæ á',
+  'Statements sent to printer!' => 'Siusti suvestinæ á spausdintuvà!',
+  'Subject'                     => 'Dalykas',
+  'Subtotal'                    => 'Viso',
+  'Tax'                         => 'Mokëstis',
+  'Tax collected'               => 'Mokesèiai surinkti',
+  'Tax paid'                    => 'Mokesèiai sumokëti',
+  'Total'                       => 'Ið viso',
+  'Trial Balance'               => 'Bandomasis balansas',
+  'Vendor'                      => 'Tiekëjas',
+  'as at'                       => 'kaip',
+  'collected on sales'          => 'surinkta per pardavimus',
+  'for Period'                  => 'periodui',
+  'paid on purchases'           => 'apmokëta per pirkimus',
+  'to'                          => 'iki',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_accounts'               => 'list_accounts',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'tæsti'                       => 'continue',
+  'e_paðtas'                    => 'e_mail',
+  'spausdinti'                  => 'print',
+  'iðrinkti_viskà'              => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/COPYING b/sql-ledger/locale/mx/COPYING
new file mode 100644 (file)
index 0000000..314fc90
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Spanish texts (Mexico):
+#
+#  Author: Alberto Ladron <h@grupoh.com.mx>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/mx/LANGUAGE b/sql-ledger/locale/mx/LANGUAGE
new file mode 100644 (file)
index 0000000..22549db
--- /dev/null
@@ -0,0 +1 @@
+Mexican Spanish
diff --git a/sql-ledger/locale/mx/admin b/sql-ledger/locale/mx/admin
new file mode 100644 (file)
index 0000000..707b489
--- /dev/null
@@ -0,0 +1,128 @@
+$self{texts} = {
+  'Access Control'              => 'Control de Acceso',
+  'Accounting'                  => 'Contabilidad',
+  'Add User'                    => 'Agregar Usuario',
+  'Address'                     => 'Dirección',
+  'Administration'              => 'Administración',
+  'Administrator'               => 'Administrator',
+  'All Datasets up to date!'    => '! Todos los conjuntos de datos estan actualizados !',
+  'Change Admin Password'       => 'Cambiar Contraseña de Administrador',
+  'Change Password'             => 'Cambiar Contraseña',
+  'Character Set'               => 'Tabla de Caracteres',
+  'Click on login name to edit!' => 'Haga clic en el nombre de entrada a
+editar',
+  'Company'                     => 'Compañía',
+  'Connect to'                  => 'Conectar a',
+  'Continue'                    => 'Continuar',
+  'Create Chart of Accounts'    => 'Crear catálogo de cuentas',
+  'Create Dataset'              => 'Crear set de datos',
+  'DBI not installed!'          => 'DBI no instalado!',
+  'Database'                    => 'Base de datos',
+  'Database Administration'     => 'Administración de base de datos',
+  'Database Driver not checked!' => '!No selecciono driver de base de datos!',
+  'Database User missing!'      => 'No se encuentra usuario de base de datos',
+  'Dataset'                     => 'Set de datos',
+  'Dataset missing!'            => 'No se encuentra Set de datos!',
+  'Dataset updated!'            => 'Dataset updated!',
+  'Date Format'                 => 'Formato de Fecha',
+  'Delete'                      => 'Borrar',
+  'Delete Dataset'              => 'Borrar Set de Datos',
+  'Directory'                   => 'Directorio',
+  'Driver'                      => 'Manejador',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'Correo Electrónico',
+  'Edit User'                   => 'Editar Usuario',
+  'Existing Datasets'           => 'Sets de dato existentes',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Servidor base de datos',
+  'Hostname missing!'           => 'No se encuentra servidor de base de datos',
+  'Incorrect Password!'         => 'Contraseña Incorrecta!',
+  'Language'                    => 'Lenguaje',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Deje los campos de servidor de base de datos y puerto vacíos al menos que quiera hacer una conexión remota',
+  'Login'                       => 'Login',
+  'Name'                        => 'Nombre',
+  'New Templates'               => 'Nuevas Plantillas',
+  'No Database Drivers available!' => 'No hay manejador de base de datos
+disponible!',
+  'No Dataset selected!'        => 'No se ha seleccionado el set de datos',
+  'Nothing to delete!'          => '!Nada para borrar!',
+  'Number Format'               => 'Formato de Numero',
+  'Oracle Database Administration' => 'Oracle Administración de base de datos',
+  'Password'                    => 'Contraseña',
+  'Password changed!'           => 'Password changed!',
+  'Pg Database Administration'  => 'Pg Administración de base de datos',
+  'Phone'                       => 'Teléfono',
+  'Port'                        => 'Puerto',
+  'Port missing!'               => 'No se encuentra el Puerto!',
+  'Printer'                     => 'Impresora',
+  'Save'                        => 'Salvar',
+  'Select a Dataset to delete and press "Continue"' => 'Seleccione un set de
+datos para borrar y presione "Continuar"',
+  'Setup Templates'             => 'Configurar Plantillas',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'Firma',
+  'Stylesheet'                  => 'Estilo de hoja',
+  'Templates'                   => 'Plantillas',
+  'The following Datasets are not in use and can be deleted' => 'Los
+siguientes sets de datos no estan en uso y pueden ser borrados',
+  'The following Datasets need to be updated' => 'Es necesario actualizar las siguientes bases de datos',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Esta es una verificacion preliminar de fuentes existentes.  Nada será creado o borrado en esta etapa!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Para agregar un usuario a un grupo, edite un nombre, cambie el nombre de entrada (login) y guarde los cambios.  Un nuevo usuario, con las mismas variables será guardado bajo el nuevo nombre de entrada. (login)',
+  'Update Dataset'              => 'Actualizar conjunto de datos',
+  'Use Templates'               => 'Plantillas de Usuarios',
+  'User'                        => 'Usuario',
+  'User deleted!'               => 'User deleted!',
+  'User saved!'                 => 'User saved!',
+  'Version'                     => 'Versión',
+  'You must enter a host and port for local and remote connections!' => 'Debe
+introducir un servidor de base de datos y un puerto para conexiones locales y
+remotas!',
+  'does not exist'              => 'No existe',
+  'is already a member!'        => 'ya es miembro!',
+  'localhost'                   => 'servidor local',
+  'successfully created!'       => 'creado con éxito!',
+  'successfully deleted!'       => 'creado con éxito!',
+  'website'                     => 'sitio web',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'agregar_usuario'             => 'add_user',
+  'cambiar_contraseña_de_administrador' => 'change_admin_password',
+  'cambiar_contraseña'          => 'change_password',
+  'continuar'                   => 'continue',
+  'crear_set_de_datos'          => 'create_dataset',
+  'borrar'                      => 'delete',
+  'borrar_set_de_datos'         => 'delete_dataset',
+  'login'                       => 'login',
+  'oracle_administración_de_base_de_datos' => 'oracle_database_administration',
+  'pg_administración_de_base_de_datos' => 'pg_database_administration',
+  'salvar'                      => 'save',
+  'actualizar_conjunto_de_datos' => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/all b/sql-ledger/locale/mx/all
new file mode 100644 (file)
index 0000000..b3761a7
--- /dev/null
@@ -0,0 +1,496 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Ctas X Pagar',
+  'AP Aging'                    => 'Envejecimiento - CxP',
+  'AP Transaction'              => '',
+  'AP Transactions'             => 'Transacciones - Cuentas por Pagar',
+  'AR'                          => 'Ctas X Cobrar',
+  'AR Aging'                    => 'Envejecimiento - CxC ',
+  'AR Transaction'              => '',
+  'AR Transactions'             => 'Transacciones de Cuentas por Cobrar',
+  'About'                       => 'Acerca',
+  'Access Control'              => 'Control de Acceso',
+  'Account'                     => 'Cuenta',
+  'Account Number'              => 'Número de Cuenta',
+  'Account Number missing!'     => 'No existe el número de cuenta!',
+  'Account Type'                => 'Tipo de Cuenta',
+  'Account Type missing!'       => 'No existe el tipo de la cuenta!',
+  'Account deleted!'            => '',
+  'Account saved!'              => '',
+  'Accounting'                  => 'Contabilidad',
+  'Accounting Menu'             => 'Menú de Contabilidad',
+  'Accounts'                    => 'Cuentas',
+  'Active'                      => '',
+  'Add'                         => 'Agregar',
+  'Add Account'                 => 'Agregar Cuenta',
+  'Add Accounts Payables Transaction' => '',
+  'Add Accounts Receivables Transaction' => '',
+  'Add Assembly'                => 'Agregar Ensamblaje',
+  'Add Customer'                => 'Agregar Cliente',
+  'Add GIFI'                    => 'Añadir código GIFI',
+  'Add General Ledger Transaction' => 'Agregar Transacción - Mayor General',
+  'Add Part'                    => 'Agregar Parte',
+  'Add Project'                 => '',
+  'Add Purchase Invoice'        => '',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Invoice'           => '',
+  'Add Sales Order'             => 'Agregar Nota de Remisión',
+  'Add Service'                 => 'Agregar Servicio',
+  'Add Transaction'             => 'Agregar Transaccion',
+  'Add User'                    => 'Agregar Usuario',
+  'Add Vendor'                  => 'Agregar Proveedor',
+  'Address'                     => 'Dirección',
+  'Administration'              => 'Administración',
+  'Administrator'               => '',
+  'All'                         => 'Todos',
+  'All Datasets up to date!'    => '! Todos los conjuntos de datos estan actualizados !',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => '',
+  'Amount does not equal applied!' => '',
+  'Amount missing!'             => '',
+  'Applied'                     => '',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => '¿Esta seguro de que desea borrar la Factura No.:',
+  'Are you sure you want to delete Order Number' => '¿Esta seguro de que desea
+borrar la Orden No.:?',
+  'Are you sure you want to delete Transaction' => '¿Está usted seguro de que desea suprimir la transacción?',
+  'Assemblies'                  => 'Ensamblajes',
+  'Assemblies restocked!'       => '',
+  'Assembly Number missing!'    => 'No existe Numero de Ensamblaje!',
+  'Asset'                       => 'Activo',
+  'Attachment'                  => 'Adjunto',
+  'Audit Control'               => 'Control de auditoria',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'BOM'                         => '',
+  'Backup'                      => 'Respaldo',
+  'Backup sent to'              => 'Respaldo enviado a',
+  'Balance'                     => '',
+  'Balance Sheet'               => 'Hoja de Balance',
+  'Bcc'                         => '',
+  'Bin'                         => 'Bin',
+  'Books are open'              => 'Los libros estan abiertos',
+  'Bought'                      => 'Comprado',
+  'Business Number'             => 'Numero de Negocio',
+  'C'                           => '',
+  'COGS'                        => 'Costo de Ventas',
+  'Cannot delete account!'      => '',
+  'Cannot delete customer!'     => '',
+  'Cannot delete default account!' => 'No se puede borrar cuenta por defecto!',
+  'Cannot delete invoice!'      => '',
+  'Cannot delete item already invoiced!' => 'No puede suprimir el item ya facturado!',
+  'Cannot delete item on order!' => 'No se puede eliminar un elemnto presente en una orden',
+  'Cannot delete item which is part of an assembly!' => 'No puede suprimir un item que es parte de un ensamblaje!',
+  'Cannot delete item!'         => '',
+  'Cannot delete order!'        => '',
+  'Cannot delete transaction!'  => '',
+  'Cannot delete vendor!'       => '',
+  'Cannot have a value in both Debit and Credit!' => 'No puede tener un valor en Débito y Crédito simultáneamente!',
+  'Cannot post a transaction without a value!' => '',
+  'Cannot post invoice for a closed period!' => 'No se puede registrar factura para un periodo cerrado!',
+  'Cannot post invoice!'        => '',
+  'Cannot post payment for a closed period!' => 'No se puede registrar pago para un periodo cerrado',
+  'Cannot post payment!'        => '',
+  'Cannot post transaction for a closed period!' => 'No se puede registrar una transacción para un periodo cerrado',
+  'Cannot post transaction!'    => '',
+  'Cannot process payment for a closed period!' => '',
+  'Cannot save account!'        => '',
+  'Cannot save order!'          => '',
+  'Cannot save preferences!'    => '',
+  'Cannot stock assemblies!'    => '',
+  'Cash'                        => '',
+  'Cash based'                  => '',
+  'Cc'                          => '',
+  'Change Admin Password'       => 'Cambiar Contraseña de Administrador',
+  'Change Password'             => 'Cambiar Contraseña',
+  'Character Set'               => 'Tabla de Caracteres',
+  'Chart of Accounts'           => 'Catálogo Contable',
+  'Check'                       => '',
+  'Check printed!'              => '',
+  'Check printing failed!'      => '',
+  'Cleared Balance'             => '',
+  'Click on login name to edit!' => 'Haga clic en el nombre de entrada a
+editar',
+  'Close Books up to'           => 'Se cerraron los libros hasta',
+  'Closed'                      => 'Cerrado',
+  'Company'                     => 'Compañía',
+  'Compare to'                  => 'Comparar a',
+  'Confirm!'                    => 'Confirmar!',
+  'Connect to'                  => 'Conectar a',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Copy to COA'                 => 'Copiar al catálogo de cuentas',
+  'Create Chart of Accounts'    => 'Crear catálogo de cuentas',
+  'Create Dataset'              => 'Crear set de datos',
+  'Credit'                      => 'Crédito',
+  'Credit Limit'                => 'Limite de Credito',
+  'Curr'                        => 'Mon.',
+  'Currency'                    => 'Moneda',
+  'Current'                     => '',
+  'Customer'                    => 'Cliente',
+  'Customer deleted!'           => '',
+  'Customer missing!'           => '',
+  'Customer not on file!'       => '',
+  'Customer saved!'             => '',
+  'Customers'                   => '',
+  'DBI not installed!'          => 'DBI no instalado!',
+  'Database'                    => 'Base de datos',
+  'Database Administration'     => 'Administración de base de datos',
+  'Database Driver not checked!' => '!No selecciono driver de base de datos!',
+  'Database Host'               => 'Servidor de Base de Datos',
+  'Database User missing!'      => 'No se encuentra usuario de base de datos',
+  'Dataset'                     => 'Set de datos',
+  'Dataset missing!'            => 'No se encuentra Set de datos!',
+  'Dataset updated!'            => '',
+  'Date'                        => 'Fecha',
+  'Date Due'                    => 'Fecha de Vencimiento',
+  'Date Format'                 => 'Formato de Fecha',
+  'Date Paid'                   => 'Fecha de pago',
+  'Date missing!'               => '',
+  'Debit'                       => 'Débito',
+  'Debit and credit out of balance!' => 'Débito y Crédito fuera de balance.',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Decimalplaces'               => '',
+  'Delete'                      => 'Borrar',
+  'Delete Account'              => 'Borrar Cuenta',
+  'Delete Dataset'              => 'Borrar Set de Datos',
+  'Delivery Date'               => '',
+  'Deposit'                     => '',
+  'Description'                 => 'Descripción',
+  'Difference'                  => '',
+  'Directory'                   => 'Directorio',
+  'Discount'                    => 'Descuento',
+  'Done'                        => '',
+  'Drawing'                     => '',
+  'Driver'                      => 'Manejador',
+  'Dropdown Limit'              => '',
+  'Due'                         => 'Vence',
+  'Due Date'                    => 'Fecha de Vencimiento',
+  'Due Date missing!'           => 'Falta Fecha de Vencimiento!',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail Statement to'         => '',
+  'E-mail address missing!'     => 'Falta E-mail!',
+  'Edit'                        => '',
+  'Edit Account'                => 'Editar Cuenta',
+  'Edit Accounts Payables Transaction' => '',
+  'Edit Accounts Receivables Transaction' => '',
+  'Edit Assembly'               => 'Editar Ensamblaje',
+  'Edit GIFI'                   => 'Editar GIFI',
+  'Edit General Ledger Transaction' => 'Editar Transacción de Mayor General',
+  'Edit Part'                   => 'Editar Parte',
+  'Edit Preferences for'        => 'Editar Preferencias para',
+  'Edit Project'                => '',
+  'Edit Purchase Invoice'       => '',
+  'Edit Purchase Order'         => 'Editar Orden de Compra',
+  'Edit Sales Invoice'          => '',
+  'Edit Sales Order'            => 'Editar Remisión',
+  'Edit Service'                => 'Editar Servicio',
+  'Edit Template'               => 'Editar Plantilla',
+  'Edit User'                   => 'Editar Usuario',
+  'Employee'                    => '',
+  'Enforce transaction reversal for all dates' => 'Forzar la anulación de las transacciones para todas las fechas',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => '',
+  'Equity'                      => 'Capital',
+  'Exch'                        => 'Interc.',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'Exchangerate Difference'     => '',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Existing Datasets'           => 'Sets de dato existentes',
+  'Expense'                     => 'Egreso',
+  'Expense Account'             => 'Cuenta de Egreso',
+  'Expense/Asset'               => 'Egreso/Activo',
+  'Extended'                    => '',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'Foreign Exchange Gain'       => 'Ganancia en Moneda Extranjera',
+  'Foreign Exchange Loss'       => 'Pérdida en Moneda Extranjera',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'Código GIFI',
+  'GIFI deleted!'               => '',
+  'GIFI missing!'               => 'No se ha definido el código GIFI',
+  'GIFI saved!'                 => '',
+  'GL Transaction'              => '',
+  'General Ledger'              => 'Mayor General',
+  'Goods & Services'            => 'Bienes y servicios',
+  'HTML Templates'              => 'Plantillas HTML',
+  'Heading'                     => 'Encabezado',
+  'Host'                        => 'Servidor base de datos',
+  'Hostname missing!'           => 'No se encuentra servidor de base de datos',
+  'ID'                          => 'ID',
+  'Image'                       => '',
+  'In-line'                     => 'En linea',
+  'Include in Report'           => 'Incluya en informe',
+  'Include in drop-down menus'  => 'Incluya en menús desplegables',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Incluya esta cuenta en las formas del cliente/proveedor para señalar al cliente/proveedor como gravable de impuesto?',
+  'Income'                      => 'Ingreso',
+  'Income Account'              => 'Cuenta de Ingreso',
+  'Income Statement'            => 'Estado de Cuentas',
+  'Incorrect Dataset version!'  => '!Versisn incorrecta de conjunto de datos!',
+  'Incorrect Password!'         => 'Contraseña Incorrecta!',
+  'Individual Items'            => 'Items Individuales',
+  'Inventory'                   => 'Inventario',
+  'Inventory Account'           => 'Cuenta de Inventario',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'La cantidad en inventario debe ser cero antes de cambiar este ensamblaje a obsoleto!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'La cantidad en inventario debe ser cero antes de cambiar esta parte a obsoleto',
+  'Inventory quantity must be zero!' => 'La cantidad en inventario debe ser
+cero!',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Invoice deleted!'            => '',
+  'Invoice posted!'             => '',
+  'Invoices'                    => '',
+  'Is this a summary account to record' => 'Es esta una cuenta de resumen a registrar?',
+  'Item deleted!'               => '',
+  'Item not on file!'           => '¡El artículo no se encuentra en archivo!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'LaTeX Templates'             => 'Plantillas de LaTeX',
+  'Language'                    => 'Lenguaje',
+  'Last Cost'                   => 'Ultimo Costo',
+  'Last Invoice Number'         => 'Último Número de Factura',
+  'Last Numbers & Default Accounts' => 'Últimos Números y Cuentas por Defecto',
+  'Last Purchase Order Number'  => 'Ultima Orden de Compra',
+  'Last Sales Order Number'     => 'Número del último presupuesto',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Deje los campos de servidor de base de datos y puerto vacíos al menos que quiera hacer una conexión remota',
+  'Liability'                   => 'Pasivo',
+  'Licensed to'                 => 'Licenciado a',
+  'Line Total'                  => 'Total de la linea',
+  'Link'                        => 'Enlaces',
+  'Link Accounts'               => 'Enlazar Cuentas',
+  'List Accounts'               => 'Listar Cuentas',
+  'List GIFI'                   => 'Listar código GIFI',
+  'List Price'                  => 'Precio de Lista',
+  'List Transactions'           => 'Listar Transacciones',
+  'Login'                       => 'Login',
+  'Logout'                      => 'Salir',
+  'Make'                        => 'Marca',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Microfiche'                  => '',
+  'Model'                       => 'Modelo',
+  'N/A'                         => 'N/A',
+  'Name'                        => 'Nombre',
+  'Name missing!'               => '',
+  'New Templates'               => 'Nuevas Plantillas',
+  'No'                          => 'No',
+  'No Database Drivers available!' => 'No hay manejador de base de datos
+disponible!',
+  'No Dataset selected!'        => 'No se ha seleccionado el set de datos',
+  'No email address for'        => 'Falta email para',
+  'No.'                         => '',
+  'Notes'                       => 'Notas',
+  'Nothing applied!'            => '',
+  'Nothing selected!'           => '',
+  'Nothing to delete!'          => '!Nada para borrar!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Formato de Numero',
+  'Number missing in Row'       => 'No se encuentra el número en la fila',
+  'O'                           => '',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'On Hand'                     => 'En Existencia',
+  'On Order'                    => '',
+  'Open'                        => 'Abierto',
+  'Oracle Database Administration' => 'Oracle Administración de base de datos',
+  'Order'                       => 'Orden',
+  'Order Date'                  => 'Fecha de Orden',
+  'Order Date missing!'         => 'No se encuentra la fecha de orden!',
+  'Order Entry'                 => 'Orden de Entrada',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'No se encuentra el número de orden!',
+  'Order deleted!'              => '',
+  'Order saved!'                => '',
+  'Ordered'                     => '',
+  'Orphaned'                    => 'Huerfano',
+  'Out of balance!'             => '',
+  'PDF'                         => '',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => '!Falta fecha en lista de empaque!',
+  'Packing List Number missing!' => '!Falta nzmero en lista de empaque!',
+  'Paid'                        => 'Total Pagado',
+  'Paid in full'                => '',
+  'Part'                        => 'Partes',
+  'Part Number missing!'        => 'Falta del número de pieza!',
+  'Parts'                       => 'Partes',
+  'Parts Inventory'             => 'Inventario de Partes',
+  'Password'                    => 'Contraseña',
+  'Password changed!'           => '',
+  'Payables'                    => 'Por Pagar',
+  'Payment'                     => 'Pago',
+  'Payment date missing!'       => 'No se encuentra la fecha de Pago!',
+  'Payment posted!'             => '',
+  'Payments'                    => 'Pagos',
+  'Pg Database Administration'  => 'Pg Administración de base de datos',
+  'Phone'                       => 'Teléfono',
+  'Port'                        => 'Puerto',
+  'Port missing!'               => 'No se encuentra el Puerto!',
+  'Post'                        => '',
+  'Post as new'                 => '',
+  'Postscript'                  => '',
+  'Preferences'                 => 'Preferencias',
+  'Preferences saved!'          => 'Preferencias guardadas!',
+  'Price'                       => 'Precio',
+  'Print'                       => '',
+  'Printer'                     => 'Impresora',
+  'Project'                     => '',
+  'Project Number missing!'     => '',
+  'Project deleted!'            => '',
+  'Project not on file!'        => '',
+  'Project saved!'              => '',
+  'Projects'                    => '',
+  'Purchase Invoice'            => '',
+  'Purchase Order'              => 'Orden de Compra',
+  'Purchase Orders'             => 'Ordenes de Compra',
+  'Qty'                         => 'Cantidad',
+  'ROP'                         => 'ROP',
+  'Rate'                        => 'Tarifa',
+  'Recd'                        => '',
+  'Receipt'                     => '',
+  'Receipts'                    => '',
+  'Receivables'                 => 'Por Cobrar',
+  'Reconciliation'              => '',
+  'Record in'                   => 'Registrar en',
+  'Reference'                   => '',
+  'Reference missing!'          => '',
+  'Remaining'                   => 'Faltan',
+  'Report for'                  => 'Informe para',
+  'Reports'                     => 'Reportes',
+  'Required by'                 => 'Requerido por',
+  'Retained Earnings'           => 'Ganacias Retenidas',
+  'Sales'                       => 'Ventas',
+  'Sales Invoice'               => '',
+  'Sales Order'                 => 'Orden de venta',
+  'Sales Orders'                => 'Ordenes de venta',
+  'Save'                        => 'Salvar',
+  'Save as new'                 => '',
+  'Save to File'                => 'Guardar en archivo',
+  'Screen'                      => 'Pantalla',
+  'Select a Dataset to delete and press "Continue"' => 'Seleccione un set de
+datos para borrar y presione "Continuar"',
+  'Select all'                  => '',
+  'Select from one of the items below' => 'Seleccione uno de los items',
+  'Select from one of the names below' => '',
+  'Select from one of the projects below' => '',
+  'Select postscript or PDF!'   => '',
+  'Sell Price'                  => 'Precio de Venta',
+  'Send by E-Mail'              => 'Enviar por E-Mail',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Service Items'               => 'Items de Servicio',
+  'Service Number missing!'     => 'Falta el número de servicio!',
+  'Services'                    => 'Servicios',
+  'Setup Templates'             => 'Configurar Plantillas',
+  'Ship'                        => '',
+  'Ship to'                     => '',
+  'Ship via'                    => '',
+  'Short'                       => 'Corto',
+  'Signature'                   => 'Firma',
+  'Sold'                        => 'Vendido',
+  'Source'                      => 'Fuente',
+  'Standard'                    => 'Estándard',
+  'Statement'                   => '',
+  'Statement Balance'           => '',
+  'Statement sent to'           => '',
+  'Statements sent to printer!' => '',
+  'Stock Assembly'              => 'Inventariar Ensamblaje?',
+  'Stylesheet'                  => 'Estilo de hoja',
+  'Subject'                     => 'Asunto',
+  'Subtotal'                    => 'Subtotal',
+  'System'                      => 'Sistema',
+  'Tax'                         => 'Impuesto',
+  'Tax Accounts'                => 'Cuentas De Impuesto',
+  'Tax Included'                => 'Impuesto Incluido',
+  'Tax collected'               => '',
+  'Tax paid'                    => '',
+  'Taxable'                     => 'Gravable de Impuesto',
+  'Template saved!'             => '',
+  'Templates'                   => 'Plantillas',
+  'Terms: Net'                  => 'Crédito',
+  'The following Datasets are not in use and can be deleted' => 'Los
+siguientes sets de datos no estan en uso y pueden ser borrados',
+  'The following Datasets need to be updated' => 'Es necesario actualizar las siguientes bases de datos',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Esta es una verificacion preliminar de fuentes existentes.  Nada será creado o borrado en esta etapa!',
+  'To'                          => 'Hasta ',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Para agregar un usuario a un grupo, edite un nombre, cambie el nombre de entrada (login) y guarde los cambios.  Un nuevo usuario, con las mismas variables será guardado bajo el nuevo nombre de entrada. (login)',
+  'Top Level'                   => '',
+  'Total'                       => 'Total',
+  'Transaction Date missing!'   => 'Falta la fecha de la transacción!',
+  'Transaction deleted!'        => '',
+  'Transaction posted!'         => '',
+  'Transaction reversal enforced for all dates' => 'Se ha forzado la anulación de las transacciones para todas las fechas',
+  'Transaction reversal enforced up to' => 'Se ha forzado la anulación de las transacciones hasta',
+  'Transactions'                => 'Transacciones',
+  'Transactions exist, cannot delete customer!' => 'Las transacciones existen, no pueden suprimir el cliente!',
+  'Transactions exist, cannot delete vendor!' => 'Las transacciones existen, no pueden suprimir a proveedor',
+  'Transactions exist; cannot delete account!' => 'Las transacciones existen,
+no puede suprimir la cuenta!',
+  'Trial Balance'               => 'Balance De Comprobación',
+  'Unit'                        => 'Unidad',
+  'Unit of measure'             => 'Unidad de medida',
+  'Update'                      => '',
+  'Update Dataset'              => 'Actualizar conjunto de datos',
+  'Updated'                     => '',
+  'Use Templates'               => 'Plantillas de Usuarios',
+  'User'                        => 'Usuario',
+  'User deleted!'               => '',
+  'User saved!'                 => '',
+  'Vendor'                      => 'Proveedor',
+  'Vendor deleted!'             => '',
+  'Vendor missing!'             => '',
+  'Vendor not on file!'         => '',
+  'Vendor saved!'               => '',
+  'Vendors'                     => '',
+  'Version'                     => 'Versión',
+  'Weight'                      => 'Peso',
+  'Weight Unit'                 => 'Unidad de Peso',
+  'What type of item is this?'  => '¿Que tipo de Item es este?',
+  'Year End'                    => 'Fin del Año Fiscal',
+  'Yes'                         => 'Si',
+  'You are logged out!'         => '',
+  'You did not enter a name!'   => 'No introdujo un nombre!',
+  'You must enter a host and port for local and remote connections!' => 'Debe
+introducir un servidor de base de datos y un puerto para conexiones locales y
+remotas!',
+  'as at'                       => '',
+  'collected on sales'          => 'ingresado en ventas',
+  'days'                        => 'Días',
+  'does not exist'              => 'No existe',
+  'ea'                          => 'c/u',
+  'emailed to'                  => 'Se envio email a',
+  'for Period'                  => 'para el período',
+  'hr'                          => 'hr',
+  'is already a member!'        => 'ya es miembro!',
+  'is not a member!'            => '!no es miembro!',
+  'localhost'                   => 'servidor local',
+  'paid on purchases'           => 'pagado en compras',
+  'sent to printer'             => 'Enviado a la impresora',
+  'successfully created!'       => 'creado con éxito!',
+  'successfully deleted!'       => 'creado con éxito!',
+  'to'                          => '',
+  'website'                     => 'sitio web',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/am b/sql-ledger/locale/mx/am
new file mode 100644 (file)
index 0000000..d96b138
--- /dev/null
@@ -0,0 +1,140 @@
+$self{texts} = {
+  'AP'                          => 'Ctas X Pagar',
+  'AR'                          => 'Ctas X Cobrar',
+  'Account'                     => 'Cuenta',
+  'Account Number'              => 'Número de Cuenta',
+  'Account Number missing!'     => 'No existe el número de cuenta!',
+  'Account Type'                => 'Tipo de Cuenta',
+  'Account Type missing!'       => 'No existe el tipo de la cuenta!',
+  'Account deleted!'            => 'Account deleted!',
+  'Account saved!'              => 'Account saved!',
+  'Add Account'                 => 'Agregar Cuenta',
+  'Add GIFI'                    => 'Añadir código GIFI',
+  'Address'                     => 'Dirección',
+  'Asset'                       => 'Activo',
+  'Audit Control'               => 'Control de auditoria',
+  'Backup sent to'              => 'Respaldo enviado a',
+  'Books are open'              => 'Los libros estan abiertos',
+  'Business Number'             => 'Numero de Negocio',
+  'COGS'                        => 'Costo de Ventas',
+  'Cannot delete account!'      => 'Cannot delete account!',
+  'Cannot delete default account!' => 'No se puede borrar cuenta por defecto!',
+  'Cannot save account!'        => 'Cannot save account!',
+  'Cannot save preferences!'    => 'Cannot save preferences!',
+  'Character Set'               => 'Tabla de Caracteres',
+  'Chart of Accounts'           => 'Catálogo Contable',
+  'Close Books up to'           => 'Se cerraron los libros hasta',
+  'Company'                     => 'Compañía',
+  'Continue'                    => 'Continuar',
+  'Copy to COA'                 => 'Copiar al catálogo de cuentas',
+  'Credit'                      => 'Crédito',
+  'Date Format'                 => 'Formato de Fecha',
+  'Debit'                       => 'Débito',
+  'Delete'                      => 'Borrar',
+  'Delete Account'              => 'Borrar Cuenta',
+  'Description'                 => 'Descripción',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'Correo Electrónico',
+  'Edit'                        => 'Edit',
+  'Edit Account'                => 'Editar Cuenta',
+  'Edit GIFI'                   => 'Editar GIFI',
+  'Edit Preferences for'        => 'Editar Preferencias para',
+  'Edit Template'               => 'Editar Plantilla',
+  'Enforce transaction reversal for all dates' => 'Forzar la anulación de las transacciones para todas las fechas',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies',
+  'Equity'                      => 'Capital',
+  'Expense'                     => 'Egreso',
+  'Expense Account'             => 'Cuenta de Egreso',
+  'Expense/Asset'               => 'Egreso/Activo',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Ganancia en Moneda Extranjera',
+  'Foreign Exchange Loss'       => 'Pérdida en Moneda Extranjera',
+  'GIFI'                        => 'Código GIFI',
+  'GIFI deleted!'               => 'GIFI deleted!',
+  'GIFI missing!'               => 'No se ha definido el código GIFI',
+  'GIFI saved!'                 => 'GIFI saved!',
+  'Heading'                     => 'Encabezado',
+  'Include in drop-down menus'  => 'Incluya en menús desplegables',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Incluya esta cuenta en las formas del cliente/proveedor para señalar al cliente/proveedor como gravable de impuesto?',
+  'Income'                      => 'Ingreso',
+  'Income Account'              => 'Cuenta de Ingreso',
+  'Inventory'                   => 'Inventario',
+  'Inventory Account'           => 'Cuenta de Inventario',
+  'Is this a summary account to record' => 'Es esta una cuenta de resumen a registrar?',
+  'Language'                    => 'Lenguaje',
+  'Last Invoice Number'         => 'Último Número de Factura',
+  'Last Numbers & Default Accounts' => 'Últimos Números y Cuentas por Defecto',
+  'Last Purchase Order Number'  => 'Ultima Orden de Compra',
+  'Last Sales Order Number'     => 'Número del último presupuesto',
+  'Liability'                   => 'Pasivo',
+  'Link'                        => 'Enlaces',
+  'Name'                        => 'Nombre',
+  'No'                          => 'No',
+  'No email address for'        => 'Falta email para',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Formato de Numero',
+  'Parts Inventory'             => 'Inventario de Partes',
+  'Password'                    => 'Contraseña',
+  'Payables'                    => 'Por Pagar',
+  'Payment'                     => 'Pago',
+  'Phone'                       => 'Teléfono',
+  'Preferences saved!'          => 'Preferencias guardadas!',
+  'Rate'                        => 'Tarifa',
+  'Receivables'                 => 'Por Cobrar',
+  'Sales'                       => 'Ventas',
+  'Save'                        => 'Salvar',
+  'Service Items'               => 'Items de Servicio',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'Firma',
+  'Stylesheet'                  => 'Estilo de hoja',
+  'Tax'                         => 'Impuesto',
+  'Tax Accounts'                => 'Cuentas De Impuesto',
+  'Template saved!'             => 'Template saved!',
+  'Transaction reversal enforced for all dates' => 'Se ha forzado la anulación de las transacciones para todas las fechas',
+  'Transaction reversal enforced up to' => 'Se ha forzado la anulación de las transacciones hasta',
+  'Transactions exist; cannot delete account!' => 'Las transacciones existen,
+no puede suprimir la cuenta!',
+  'Weight Unit'                 => 'Unidad de Peso',
+  'Year End'                    => 'Fin del Año Fiscal',
+  'Yes'                         => 'Si',
+  'does not exist'              => 'No existe',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'agregar_cuenta'              => 'add_account',
+  'continuar'                   => 'continue',
+  'copiar_al_catálogo_de_cuentas' => 'copy_to_coa',
+  'borrar'                      => 'delete',
+  'edit'                        => 'edit',
+  'editar_cuenta'               => 'edit_account',
+  'salvar'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/ap b/sql-ledger/locale/mx/ap
new file mode 100644 (file)
index 0000000..68d095c
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AP Transactions'             => 'Transacciones - Cuentas por Pagar',
+  'Account'                     => 'Cuenta',
+  'Add Accounts Payables Transaction' => 'Add Accounts Payables Transaction',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => '¿Está usted seguro de que desea suprimir la transacción?',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'No se puede registrar pago para un periodo cerrado',
+  'Cannot post transaction for a closed period!' => 'No se puede registrar una transacción para un periodo cerrado',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'Cerrado',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Moneda',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Date Paid'                   => 'Fecha de pago',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Due Date'                    => 'Fecha de Vencimiento',
+  'Due Date missing!'           => 'Falta Fecha de Vencimiento!',
+  'Edit Accounts Payables Transaction' => 'Edit Accounts Payables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'Interc.',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluya en informe',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Open'                        => 'Abierto',
+  'Order'                       => 'Orden',
+  'Order Number'                => 'Orden Número',
+  'Paid'                        => 'Total Pagado',
+  'Payment date missing!'       => 'No se encuentra la fecha de Pago!',
+  'Payments'                    => 'Pagos',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Source'                      => 'Fuente',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'Tax Included'                => 'Impuesto Incluido',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Proveedor',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Si',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'add_accounts_payables_transaction' => 'add_accounts_payables_transaction',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'edit_accounts_payables_transaction' => 'edit_accounts_payables_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'update'                      => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/ar b/sql-ledger/locale/mx/ar
new file mode 100644 (file)
index 0000000..3f2fd0e
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'AR Transaction',
+  'AR Transactions'             => 'Transacciones de Cuentas por Cobrar',
+  'Account'                     => 'Cuenta',
+  'Add Accounts Receivables Transaction' => 'Add Accounts Receivables Transaction',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => '¿Está usted seguro de que desea suprimir la transacción?',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'No se puede registrar pago para un periodo cerrado',
+  'Cannot post transaction for a closed period!' => 'No se puede registrar una transacción para un periodo cerrado',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'Cerrado',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Limite de Credito',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Date Paid'                   => 'Fecha de pago',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Due Date'                    => 'Fecha de Vencimiento',
+  'Due Date missing!'           => 'Falta Fecha de Vencimiento!',
+  'Edit Accounts Receivables Transaction' => 'Edit Accounts Receivables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'Interc.',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluya en informe',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Open'                        => 'Abierto',
+  'Order'                       => 'Orden',
+  'Order Number'                => 'Orden Número',
+  'Paid'                        => 'Total Pagado',
+  'Payment date missing!'       => 'No se encuentra la fecha de Pago!',
+  'Payments'                    => 'Pagos',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Remaining'                   => 'Faltan',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Source'                      => 'Fuente',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'Tax Included'                => 'Impuesto Incluido',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Si',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ar_transaction'              => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/arap b/sql-ledger/locale/mx/arap
new file mode 100644 (file)
index 0000000..f541192
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Dirección',
+  'Continue'                    => 'Continuar',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Description'                 => 'Descripción',
+  'Number'                      => 'Número',
+  'Project not on file!'        => 'Project not on file!',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/ca b/sql-ledger/locale/mx/ca
new file mode 100644 (file)
index 0000000..5d43318
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Balance',
+  'Chart of Accounts'           => 'Catálogo Contable',
+  'Credit'                      => 'Crédito',
+  'Date'                        => 'Fecha',
+  'Debit'                       => 'Débito',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Description'                 => 'Descripción',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'Código GIFI',
+  'Include in Report'           => 'Incluya en informe',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'List Transactions'           => 'Listar Transacciones',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Reference'                   => 'Reference',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Subtotal'                    => 'Subtotal',
+  'To'                          => 'Hasta ',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'listar_transacciones'        => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/cp b/sql-ledger/locale/mx/cp
new file mode 100644 (file)
index 0000000..95085e0
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Amount does not equal applied!' => 'Amount does not equal applied!',
+  'Amount missing!'             => 'Amount missing!',
+  'Applied'                     => 'Applied',
+  'Cannot post payment!'        => 'Cannot post payment!',
+  'Cannot process payment for a closed period!' => 'Cannot process payment for a closed period!',
+  'Check'                       => 'Check',
+  'Check printed!'              => 'Check printed!',
+  'Check printing failed!'      => 'Check printing failed!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Cliente',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Date missing!'               => 'Date missing!',
+  'Description'                 => 'Descripción',
+  'Due'                         => 'Vence',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'From'                        => 'Desde',
+  'Invoice'                     => 'Factura',
+  'Invoices'                    => 'Invoices',
+  'Nothing applied!'            => 'Nothing applied!',
+  'Number'                      => 'Número',
+  'Paid in full'                => 'Paid in full',
+  'Payment'                     => 'Pago',
+  'Payment posted!'             => 'Payment posted!',
+  'Post'                        => 'Post',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Impresora',
+  'Project not on file!'        => 'Project not on file!',
+  'Receipt'                     => 'Receipt',
+  'Reference'                   => 'Reference',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'To'                          => 'Hasta ',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Proveedor',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/ct b/sql-ledger/locale/mx/ct
new file mode 100644 (file)
index 0000000..0db8902
--- /dev/null
@@ -0,0 +1,69 @@
+$self{texts} = {
+  'Add'                         => 'Agregar',
+  'Address'                     => 'Dirección',
+  'All'                         => 'Todos',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Cannot delete customer!',
+  'Cannot delete vendor!'       => 'Cannot delete vendor!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Limite de Credito',
+  'Customer deleted!'           => 'Customer deleted!',
+  'Customer saved!'             => 'Customer saved!',
+  'Customers'                   => 'Customers',
+  'Delete'                      => 'Borrar',
+  'Discount'                    => 'Descuento',
+  'E-mail'                      => 'Correo Electrónico',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Incluya en informe',
+  'Invoice'                     => 'Factura',
+  'Name'                        => 'Nombre',
+  'Name missing!'               => 'Name missing!',
+  'Notes'                       => 'Notas',
+  'Number'                      => 'Número',
+  'Order'                       => 'Orden',
+  'Orphaned'                    => 'Huerfano',
+  'Phone'                       => 'Teléfono',
+  'Save'                        => 'Salvar',
+  'Ship to'                     => 'Ship to',
+  'Tax Included'                => 'Impuesto Incluido',
+  'Taxable'                     => 'Gravable de Impuesto',
+  'Terms: Net'                  => 'Crédito',
+  'Transactions exist, cannot delete customer!' => 'Las transacciones existen, no pueden suprimir el cliente!',
+  'Transactions exist, cannot delete vendor!' => 'Las transacciones existen, no pueden suprimir a proveedor',
+  'Vendor deleted!'             => 'Vendor deleted!',
+  'Vendor saved!'               => 'Vendor saved!',
+  'Vendors'                     => 'Vendors',
+  'days'                        => 'Días',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'agregar'                     => 'add',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'factura'                     => 'invoice',
+  'orden'                       => 'order',
+  'salvar'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/gl b/sql-ledger/locale/mx/gl
new file mode 100644 (file)
index 0000000..b0957b6
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AR Transaction'              => 'AR Transaction',
+  'Account'                     => 'Cuenta',
+  'Add General Ledger Transaction' => 'Agregar Transacción - Mayor General',
+  'Address'                     => 'Dirección',
+  'All'                         => 'Todos',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => '¿Está usted seguro de que desea suprimir la transacción?',
+  'Asset'                       => 'Activo',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Balance',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot have a value in both Debit and Credit!' => 'No puede tener un valor en Débito y Crédito simultáneamente!',
+  'Cannot post a transaction without a value!' => 'Cannot post a transaction without a value!',
+  'Cannot post transaction for a closed period!' => 'No se puede registrar una transacción para un periodo cerrado',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Credit'                      => 'Crédito',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Debit'                       => 'Débito',
+  'Debit and credit out of balance!' => 'Débito y Crédito fuera de balance.',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Edit General Ledger Transaction' => 'Editar Transacción de Mayor General',
+  'Equity'                      => 'Capital',
+  'Expense'                     => 'Egreso',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'Código GIFI',
+  'GL Transaction'              => 'GL Transaction',
+  'General Ledger'              => 'Mayor General',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluya en informe',
+  'Income'                      => 'Ingreso',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Liability'                   => 'Pasivo',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Reference'                   => 'Reference',
+  'Reference missing!'          => 'Reference missing!',
+  'Reports'                     => 'Reportes',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Source'                      => 'Fuente',
+  'Subtotal'                    => 'Subtotal',
+  'To'                          => 'Hasta ',
+  'Transaction Date missing!'   => 'Falta la fecha de la transacción!',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Si',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'gl_transaction'              => 'gl_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/ic b/sql-ledger/locale/mx/ic
new file mode 100644 (file)
index 0000000..e5e1a86
--- /dev/null
@@ -0,0 +1,206 @@
+$self{texts} = {
+  'Active'                      => 'Active',
+  'Add'                         => 'Agregar',
+  'Add Assembly'                => 'Agregar Ensamblaje',
+  'Add Part'                    => 'Agregar Parte',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Order'             => 'Agregar Nota de Remisión',
+  'Add Service'                 => 'Agregar Servicio',
+  'Address'                     => 'Dirección',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Assemblies'                  => 'Ensamblajes',
+  'Assemblies restocked!'       => 'Assemblies restocked!',
+  'Assembly Number missing!'    => 'No existe Numero de Ensamblaje!',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Bought'                      => 'Comprado',
+  'COGS'                        => 'Costo de Ventas',
+  'Cannot delete item already invoiced!' => 'No puede suprimir el item ya facturado!',
+  'Cannot delete item on order!' => 'No se puede eliminar un elemnto presente en una orden',
+  'Cannot delete item which is part of an assembly!' => 'No puede suprimir un item que es parte de un ensamblaje!',
+  'Cannot delete item!'         => 'Cannot delete item!',
+  'Cannot stock assemblies!'    => 'Cannot stock assemblies!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripción',
+  'Drawing'                     => 'Drawing',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail address missing!'     => 'Falta E-mail!',
+  'Edit Assembly'               => 'Editar Ensamblaje',
+  'Edit Part'                   => 'Editar Parte',
+  'Edit Service'                => 'Editar Servicio',
+  'Expense'                     => 'Egreso',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'Image'                       => 'Image',
+  'In-line'                     => 'En linea',
+  'Include in Report'           => 'Incluya en informe',
+  'Income'                      => 'Ingreso',
+  'Individual Items'            => 'Items Individuales',
+  'Inventory'                   => 'Inventario',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'La cantidad en inventario debe ser cero antes de cambiar este ensamblaje a obsoleto!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'La cantidad en inventario debe ser cero antes de cambiar esta parte a obsoleto',
+  'Inventory quantity must be zero!' => 'La cantidad en inventario debe ser
+cero!',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Item deleted!'               => 'Item deleted!',
+  'Item not on file!'           => '¡El artículo no se encuentra en archivo!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Last Cost'                   => 'Ultimo Costo',
+  'Line Total'                  => 'Total de la linea',
+  'Link Accounts'               => 'Enlazar Cuentas',
+  'List Price'                  => 'Precio de Lista',
+  'Make'                        => 'Marca',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Modelo',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se encuentra el número en la fila',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'On Hand'                     => 'En Existencia',
+  'On Order'                    => 'On Order',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'No se encuentra la fecha de orden!',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'No se encuentra el número de orden!',
+  'Ordered'                     => 'Ordered',
+  'Orphaned'                    => 'Huerfano',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => '!Falta fecha en lista de empaque!',
+  'Packing List Number missing!' => '!Falta nzmero en lista de empaque!',
+  'Part'                        => 'Partes',
+  'Part Number missing!'        => 'Falta del número de pieza!',
+  'Parts'                       => 'Partes',
+  'Phone'                       => 'Teléfono',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Orden de Compra',
+  'Qty'                         => 'Cantidad',
+  'ROP'                         => 'ROP',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Requerido por',
+  'Sales'                       => 'Ventas',
+  'Sales Order'                 => 'Orden de venta',
+  'Save'                        => 'Salvar',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los items',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sell Price'                  => 'Precio de Venta',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Service Number missing!'     => 'Falta el número de servicio!',
+  'Services'                    => 'Servicios',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Short'                       => 'Corto',
+  'Sold'                        => 'Vendido',
+  'Stock Assembly'              => 'Inventariar Ensamblaje?',
+  'Subject'                     => 'Asunto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'To'                          => 'Hasta ',
+  'Top Level'                   => 'Top Level',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Unit of measure'             => 'Unidad de medida',
+  'Update'                      => 'Update',
+  'Updated'                     => 'Updated',
+  'Weight'                      => 'Peso',
+  'What type of item is this?'  => '¿Que tipo de Item es este?',
+  'ea'                          => 'c/u',
+  'emailed to'                  => 'Se envio email a',
+  'hr'                          => 'hr',
+  'sent to printer'             => 'Enviado a la impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'agregar'                     => 'add',
+  'agregar_ensamblaje'          => 'add_assembly',
+  'agregar_parte'               => 'add_part',
+  'agregar_servicio'            => 'add_service',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'editar_ensamblaje'           => 'edit_assembly',
+  'editar_parte'                => 'edit_part',
+  'editar_servicio'             => 'edit_service',
+  'salvar'                      => 'save',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/io b/sql-ledger/locale/mx/io
new file mode 100644 (file)
index 0000000..89258a8
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Order'             => 'Agregar Nota de Remisión',
+  'Address'                     => 'Dirección',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail address missing!'     => 'Falta E-mail!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'In-line'                     => 'En linea',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Item not on file!'           => '¡El artículo no se encuentra en archivo!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se encuentra el número en la fila',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'No se encuentra la fecha de orden!',
+  'Order Number missing!'       => 'No se encuentra el número de orden!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => '!Falta fecha en lista de empaque!',
+  'Packing List Number missing!' => '!Falta nzmero en lista de empaque!',
+  'Part'                        => 'Partes',
+  'Phone'                       => 'Teléfono',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Orden de Compra',
+  'Qty'                         => 'Cantidad',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Orden de venta',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los items',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Subject'                     => 'Asunto',
+  'To'                          => 'Hasta ',
+  'Unit'                        => 'Unidad',
+  'What type of item is this?'  => '¿Que tipo de Item es este?',
+  'emailed to'                  => 'Se envio email a',
+  'sent to printer'             => 'Enviado a la impresora',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/ir b/sql-ledger/locale/mx/ir
new file mode 100644 (file)
index 0000000..2df2b83
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Order'             => 'Agregar Nota de Remisión',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => '¿Esta seguro de que desea borrar la Factura No.:',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'No se puede registrar factura para un periodo cerrado!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'No se puede registrar pago para un periodo cerrado',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Currency'                    => 'Moneda',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Date Due'                    => 'Fecha de Vencimiento',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail address missing!'     => 'Falta E-mail!',
+  'Edit Purchase Invoice'       => 'Edit Purchase Invoice',
+  'Exch'                        => 'Interc.',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'In-line'                     => 'En linea',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => '¡El artículo no se encuentra en archivo!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se encuentra el número en la fila',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'No se encuentra la fecha de orden!',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'No se encuentra el número de orden!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => '!Falta fecha en lista de empaque!',
+  'Packing List Number missing!' => '!Falta nzmero en lista de empaque!',
+  'Part'                        => 'Partes',
+  'Payment date missing!'       => 'No se encuentra la fecha de Pago!',
+  'Payments'                    => 'Pagos',
+  'Phone'                       => 'Teléfono',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Orden de Compra',
+  'Qty'                         => 'Cantidad',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'Registrar en',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Orden de venta',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los items',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Source'                      => 'Fuente',
+  'Subject'                     => 'Asunto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Impuesto Incluido',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Proveedor',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => '¿Que tipo de Item es este?',
+  'Yes'                         => 'Si',
+  'ea'                          => 'c/u',
+  'emailed to'                  => 'Se envio email a',
+  'sent to printer'             => 'Enviado a la impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'orden'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'update'                      => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/is b/sql-ledger/locale/mx/is
new file mode 100644 (file)
index 0000000..9286ecb
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'Agregar Nota de Remisión',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => '¿Esta seguro de que desea borrar la Factura No.:',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'No se puede registrar factura para un periodo cerrado!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'No se puede registrar pago para un periodo cerrado',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Credit Limit'                => 'Limite de Credito',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Date Due'                    => 'Fecha de Vencimiento',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail address missing!'     => 'Falta E-mail!',
+  'Edit Sales Invoice'          => 'Edit Sales Invoice',
+  'Exch'                        => 'Interc.',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'In-line'                     => 'En linea',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => '¡El artículo no se encuentra en archivo!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se encuentra el número en la fila',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'No se encuentra la fecha de orden!',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'No se encuentra el número de orden!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => '!Falta fecha en lista de empaque!',
+  'Packing List Number missing!' => '!Falta nzmero en lista de empaque!',
+  'Part'                        => 'Partes',
+  'Payment date missing!'       => 'No se encuentra la fecha de Pago!',
+  'Payments'                    => 'Pagos',
+  'Phone'                       => 'Teléfono',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Orden de Compra',
+  'Qty'                         => 'Cantidad',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'Registrar en',
+  'Remaining'                   => 'Faltan',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Orden de venta',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los items',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Source'                      => 'Fuente',
+  'Subject'                     => 'Asunto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Impuesto Incluido',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => '¿Que tipo de Item es este?',
+  'Yes'                         => 'Si',
+  'ea'                          => 'c/u',
+  'emailed to'                  => 'Se envio email a',
+  'sent to printer'             => 'Enviado a la impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'correo_electrónico'          => 'e_mail',
+  'orden'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/login b/sql-ledger/locale/mx/login
new file mode 100644 (file)
index 0000000..0e7f5b8
--- /dev/null
@@ -0,0 +1,28 @@
+$self{texts} = {
+  'About'                       => 'Acerca',
+  'Accounting'                  => 'Contabilidad',
+  'Database Host'               => 'Servidor de Base de Datos',
+  'Dataset'                     => 'Set de datos',
+  'Incorrect Dataset version!'  => '!Versisn incorrecta de conjunto de datos!',
+  'Incorrect Password!'         => 'Contraseña Incorrecta!',
+  'Licensed to'                 => 'Licenciado a',
+  'Login'                       => 'Login',
+  'Name'                        => 'Nombre',
+  'Password'                    => 'Contraseña',
+  'User'                        => 'Usuario',
+  'Version'                     => 'Versión',
+  'You are logged out!'         => 'You are logged out!',
+  'You did not enter a name!'   => 'No introdujo un nombre!',
+  'is not a member!'            => '!no es miembro!',
+  'localhost'                   => 'servidor local',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'login'                       => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/menu b/sql-ledger/locale/mx/menu
new file mode 100644 (file)
index 0000000..c0f9e4b
--- /dev/null
@@ -0,0 +1,72 @@
+$self{texts} = {
+  'AP'                          => 'Ctas X Pagar',
+  'AP Aging'                    => 'Envejecimiento - CxP',
+  'AR'                          => 'Ctas X Cobrar',
+  'AR Aging'                    => 'Envejecimiento - CxC ',
+  'Accounting Menu'             => 'Menú de Contabilidad',
+  'Add Account'                 => 'Agregar Cuenta',
+  'Add Assembly'                => 'Agregar Ensamblaje',
+  'Add Customer'                => 'Agregar Cliente',
+  'Add GIFI'                    => 'Añadir código GIFI',
+  'Add Part'                    => 'Agregar Parte',
+  'Add Project'                 => 'Add Project',
+  'Add Service'                 => 'Agregar Servicio',
+  'Add Transaction'             => 'Agregar Transaccion',
+  'Add Vendor'                  => 'Agregar Proveedor',
+  'Assemblies'                  => 'Ensamblajes',
+  'Audit Control'               => 'Control de auditoria',
+  'Backup'                      => 'Respaldo',
+  'Balance Sheet'               => 'Hoja de Balance',
+  'Cash'                        => 'Cash',
+  'Chart of Accounts'           => 'Catálogo Contable',
+  'Check'                       => 'Check',
+  'Customers'                   => 'Customers',
+  'General Ledger'              => 'Mayor General',
+  'Goods & Services'            => 'Bienes y servicios',
+  'HTML Templates'              => 'Plantillas HTML',
+  'Income Statement'            => 'Estado de Cuentas',
+  'Invoice'                     => 'Factura',
+  'LaTeX Templates'             => 'Plantillas de LaTeX',
+  'List Accounts'               => 'Listar Cuentas',
+  'List GIFI'                   => 'Listar código GIFI',
+  'Logout'                      => 'Salir',
+  'Order Entry'                 => 'Orden de Entrada',
+  'Packing List'                => 'Lista de Empaque',
+  'Parts'                       => 'Partes',
+  'Payment'                     => 'Pago',
+  'Payments'                    => 'Pagos',
+  'Preferences'                 => 'Preferencias',
+  'Projects'                    => 'Projects',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Purchase Order'              => 'Orden de Compra',
+  'Purchase Orders'             => 'Ordenes de Compra',
+  'Receipt'                     => 'Receipt',
+  'Receipts'                    => 'Receipts',
+  'Reconciliation'              => 'Reconciliation',
+  'Reports'                     => 'Reportes',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Sales Order'                 => 'Orden de venta',
+  'Sales Orders'                => 'Ordenes de venta',
+  'Save to File'                => 'Guardar en archivo',
+  'Send by E-Mail'              => 'Enviar por E-Mail',
+  'Services'                    => 'Servicios',
+  'Statement'                   => 'Statement',
+  'Stock Assembly'              => 'Inventariar Ensamblaje?',
+  'Stylesheet'                  => 'Estilo de hoja',
+  'System'                      => 'Sistema',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'Transactions'                => 'Transacciones',
+  'Trial Balance'               => 'Balance De Comprobación',
+  'Vendors'                     => 'Vendors',
+  'Version'                     => 'Versión',
+  'localhost'                   => 'servidor local',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/oe b/sql-ledger/locale/mx/oe
new file mode 100644 (file)
index 0000000..6acc57a
--- /dev/null
@@ -0,0 +1,200 @@
+$self{texts} = {
+  'Add'                         => 'Agregar',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'Agregar Nota de Remisión',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Order Number' => '¿Esta seguro de que desea
+borrar la Orden No.:?',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Cannot delete order!',
+  'Cannot save order!'          => 'Cannot save order!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Cerrado',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Credit Limit'                => 'Limite de Credito',
+  'Curr'                        => 'Mon.',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail address missing!'     => 'Falta E-mail!',
+  'Edit Purchase Order'         => 'Editar Orden de Compra',
+  'Edit Sales Order'            => 'Editar Remisión',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'ID'                          => 'ID',
+  'In-line'                     => 'En linea',
+  'Include in Report'           => 'Incluya en informe',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Item not on file!'           => '¡El artículo no se encuentra en archivo!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se encuentra el número en la fila',
+  'O'                           => 'O',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Open'                        => 'Abierto',
+  'Order'                       => 'Orden',
+  'Order Date'                  => 'Fecha de Orden',
+  'Order Date missing!'         => 'No se encuentra la fecha de orden!',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'No se encuentra el número de orden!',
+  'Order deleted!'              => 'Order deleted!',
+  'Order saved!'                => 'Order saved!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => '!Falta fecha en lista de empaque!',
+  'Packing List Number missing!' => '!Falta nzmero en lista de empaque!',
+  'Part'                        => 'Partes',
+  'Phone'                       => 'Teléfono',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Orden de Compra',
+  'Purchase Orders'             => 'Ordenes de Compra',
+  'Qty'                         => 'Cantidad',
+  'Recd'                        => 'Recd',
+  'Remaining'                   => 'Faltan',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Orden de venta',
+  'Sales Orders'                => 'Ordenes de venta',
+  'Save'                        => 'Salvar',
+  'Save as new'                 => 'Save as new',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los items',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Subject'                     => 'Asunto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'Tax Included'                => 'Impuesto Incluido',
+  'Terms: Net'                  => 'Crédito',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Proveedor',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => '¿Que tipo de Item es este?',
+  'Yes'                         => 'Si',
+  'days'                        => 'Días',
+  'ea'                          => 'c/u',
+  'emailed to'                  => 'Se envio email a',
+  'sent to printer'             => 'Enviado a la impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'agregar'                     => 'add',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'correo_electrónico'          => 'e_mail',
+  'factura'                     => 'invoice',
+  'print'                       => 'print',
+  'salvar'                      => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/pe b/sql-ledger/locale/mx/pe
new file mode 100644 (file)
index 0000000..e1306ae
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Agregar',
+  'Add Project'                 => 'Add Project',
+  'All'                         => 'Todos',
+  'Continue'                    => 'Continuar',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Edit Project'                => 'Edit Project',
+  'Number'                      => 'Número',
+  'Orphaned'                    => 'Huerfano',
+  'Project'                     => 'Project',
+  'Project Number missing!'     => 'Project Number missing!',
+  'Project deleted!'            => 'Project deleted!',
+  'Project saved!'              => 'Project saved!',
+  'Projects'                    => 'Projects',
+  'Save'                        => 'Salvar',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'agregar'                     => 'add',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'salvar'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/rc b/sql-ledger/locale/mx/rc
new file mode 100644 (file)
index 0000000..7e0dbb1
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Balance'                     => 'Balance',
+  'Cleared Balance'             => 'Cleared Balance',
+  'Continue'                    => 'Continuar',
+  'Date'                        => 'Fecha',
+  'Deposit'                     => 'Deposit',
+  'Description'                 => 'Descripción',
+  'Difference'                  => 'Difference',
+  'Done'                        => 'Done',
+  'Exchangerate Difference'     => 'Exchangerate Difference',
+  'From'                        => 'Desde',
+  'Out of balance!'             => 'Out of balance!',
+  'Payment'                     => 'Pago',
+  'Reconciliation'              => 'Reconciliation',
+  'Select all'                  => 'Select all',
+  'Source'                      => 'Fuente',
+  'Statement Balance'           => 'Statement Balance',
+  'To'                          => 'Hasta ',
+  'Update'                      => 'Update',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'continuar'                   => 'continue',
+  'done'                        => 'done',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/mx/rp b/sql-ledger/locale/mx/rp
new file mode 100644 (file)
index 0000000..f198c6f
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'Envejecimiento - CxP',
+  'AR Aging'                    => 'Envejecimiento - CxC ',
+  'Account'                     => 'Cuenta',
+  'Accounts'                    => 'Cuentas',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance Sheet'               => 'Hoja de Balance',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Cash based',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Comparar a',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Credit'                      => 'Crédito',
+  'Current'                     => 'Current',
+  'Customer'                    => 'Cliente',
+  'Date'                        => 'Fecha',
+  'Debit'                       => 'Débito',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Decimalplaces'               => 'Decimalplaces',
+  'Description'                 => 'Descripción',
+  'Due'                         => 'Vence',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail Statement to'         => 'E-mail Statement to',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'Código GIFI',
+  'Heading'                     => 'Encabezado',
+  'ID'                          => 'ID',
+  'In-line'                     => 'En linea',
+  'Include in Report'           => 'Incluya en informe',
+  'Income Statement'            => 'Estado de Cuentas',
+  'Invoice'                     => 'Factura',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'N/A'                         => 'N/A',
+  'Nothing selected!'           => 'Nothing selected!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Pagos',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Impresora',
+  'Receipts'                    => 'Receipts',
+  'Report for'                  => 'Informe para',
+  'Retained Earnings'           => 'Ganacias Retenidas',
+  'Screen'                      => 'Pantalla',
+  'Select all'                  => 'Select all',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Source'                      => 'Fuente',
+  'Standard'                    => 'Estándard',
+  'Statement'                   => 'Statement',
+  'Statement sent to'           => 'Statement sent to',
+  'Statements sent to printer!' => 'Statements sent to printer!',
+  'Subject'                     => 'Asunto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Trial Balance'               => 'Balance De Comprobación',
+  'Vendor'                      => 'Proveedor',
+  'as at'                       => 'as at',
+  'collected on sales'          => 'ingresado en ventas',
+  'for Period'                  => 'para el período',
+  'paid on purchases'           => 'pagado en compras',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'continuar'                   => 'continue',
+  'correo_electrónico'          => 'e_mail',
+  'print'                       => 'print',
+  'select_all'                  => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/COPYING b/sql-ledger/locale/nl/COPYING
new file mode 100644 (file)
index 0000000..c5dd519
--- /dev/null
@@ -0,0 +1,26 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Dutch texts:
+#
+#  Author: AJ Hettema <Ignite@ecosse.net>
+#          Oscar Buijten <oscar@elbie.com>
+#          Bert Tijhuis <domino@dse.nl>
+#          Paul Tammes <ptammes@home.nl>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/nl/LANGUAGE b/sql-ledger/locale/nl/LANGUAGE
new file mode 100644 (file)
index 0000000..890d7d5
--- /dev/null
@@ -0,0 +1 @@
+Dutch
diff --git a/sql-ledger/locale/nl/Num2text b/sql-ledger/locale/nl/Num2text
new file mode 100644 (file)
index 0000000..777c2f3
--- /dev/null
@@ -0,0 +1,161 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors: Paul Tammes <finance@bermuda-holding.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# this is a variation of the Lingua package
+# written for check and receipt printing
+# it returns a properly formatted text string
+# for a number up to 10**12
+
+sub init {
+  my $self = shift;
+
+  %{ $self->{numbername} } =
+                   (0 => 'nul',
+                    1 => 'een',
+                    2 => 'twee',
+                   3 => 'drie',
+                   4 => 'vier',
+                   5 => 'vijf',
+                   6 => 'zes',
+                   7 => 'zeven',
+                   8 => 'acht',
+                   9 => 'negen',
+                  10 => 'tien',
+                  11 => 'elf',
+                  12 => 'twalf',
+                  13 => 'dertien',
+                  14 => 'veertien',
+                  15 => 'vijftien',
+                  16 => 'zestien',
+                  17 => 'zeventien',
+                  18 => 'achtien',
+                  19 => 'negentien',
+                  20 => 'twintig',
+                  30 => 'dertig',
+                  40 => 'veertig',
+                  50 => 'vijftig',
+                  60 => 'zestig',
+                  70 => 'zeventig',
+                  80 => 'tachtig',
+                  90 => 'negentig',
+                10**2 => 'honderd',
+                10**3 => 'duizend',
+               10**6 => 'miljoen',
+               10**9 => 'miljard',
+              10**12 => 'biljoen'
+               );
+
+}
+
+
+sub num2text {
+  my ($self, $amount) = @_;
+
+  return $self->{numbername}{0} unless $amount;
+
+  my @textnumber = ('**');
+
+  # split amount into chunks of 3
+  my @num = reverse split //, $amount;
+  my @numblock = ();
+  my ($i, $appendn);
+  my @a = ();
+
+  while (@num) {
+    @a = ();
+    for (1 .. 3) {
+      push @a, shift @num;
+    }
+    push @numblock, join / /, reverse @a;
+  }
+  
+  
+  while (@numblock) {
+
+    $i = $#numblock;
+    @num = split //, $numblock[$i];
+    
+    $numblock[$i] *= 1;
+    
+    if ($numblock[$i] == 0) {
+      pop @numblock;
+      next;
+    }
+   
+    if ($numblock[$i] > 99) {
+      # the one from hundreds
+      push @textnumber, $self->{numbername}{$num[0]};
+     
+      # add hundred designation
+      push @textnumber, $self->{numbername}{10**2};
+
+      # reduce numblock
+      $numblock[$i] -= $num[0] * 100;
+    }
+    
+    if ($numblock[$i] > 9) {
+      # tens
+      push @textnumber, $self->format_ten($numblock[$i]);
+    } else {
+      # ones
+      push @textnumber, $self->{numbername}{$numblock[$i]};
+    }
+    
+    # add thousand, million
+    if ($i) {
+      $amount = 10**($i * 3);
+      push @textnumber, $self->{numbername}{$amount};
+    }
+    
+    pop @numblock;
+    
+  }
+
+  push @textnumber, '**';
+  join '', @textnumber;
+
+}
+
+
+sub format_ten {
+  my ($self, $amount) = @_;
+  
+  my $textnumber = "";
+  my @num = split //, $amount;
+
+  if ($amount > 20) {
+    # reverse one and ten and glue together with 'en'
+    $amount = $num[0] * 10;
+    $textnumber = $self->{numbername}{$num[1]}.'en'.$self->{numbername}{$amount}; 
+  } else {
+    $textnumber = $self->{numbername}{$amount};
+  }
+  
+  $textnumber;
+  
+}
+
+
+1;
+
diff --git a/sql-ledger/locale/nl/admin b/sql-ledger/locale/nl/admin
new file mode 100644 (file)
index 0000000..37f5a0b
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Toegangsbeheer',
+  'Accounting'                  => 'Boekhouding',
+  'Add User'                    => 'Gebruiker toevoegen',
+  'Address'                     => 'Adres',
+  'Administration'              => 'Administratie',
+  'Administrator'               => 'Beheerder',
+  'All Datasets up to date!'    => 'Alle Datasets actueel',
+  'Change Admin Password'       => 'Admin wachtwoord veranderen',
+  'Change Password'             => 'Verander wachtwoord',
+  'Character Set'               => 'Karakter set',
+  'Click on login name to edit!' => 'Klik op login naam om deze te bewerken.',
+  'Company'                     => 'Bedrijf',
+  'Connect to'                  => 'Verbinden met',
+  'Continue'                    => 'Verder',
+  'Create Chart of Accounts'    => 'Maak rekeningstelsel',
+  'Create Dataset'              => 'Maak dataset',
+  'DBI not installed!'          => 'DBI niet geinstalleerd',
+  'Database'                    => 'Database',
+  'Database Administration'     => 'Database administratie',
+  'Database Driver not checked!' => 'Database Driver niet aangevinkt',
+  'Database User missing!'      => 'Geen database gebruiker aanwezig!',
+  'Dataset'                     => 'Dataset',
+  'Dataset missing!'            => 'Geen dataset aanwezig',
+  'Dataset updated!'            => 'Dataset aangepast aan nieuwe versie!',
+  'Date Format'                 => 'Datum formaat',
+  'Delete'                      => 'Verwijder',
+  'Delete Dataset'              => 'Verwijder dataset',
+  'Directory'                   => 'Directory',
+  'Driver'                      => 'Besturings programma',
+  'Dropdown Limit'              => 'Maximum in dropdown-lijst',
+  'E-mail'                      => 'E-mail',
+  'Edit User'                   => 'Gebruiker wijzigen',
+  'Existing Datasets'           => 'Bestaande datasets',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Geen hostnaam!',
+  'Incorrect Password!'         => 'Verkeerd paswoord',
+  'Language'                    => 'Taal',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Laat host en port veld leeg, tenzij u een netwerk connectie wilt opzetten.',
+  'Login'                       => 'Login',
+  'Multibyte Encoding'          => 'Multibyte Encoding',
+  'Name'                        => 'Naam',
+  'New Templates'               => 'Nieuwe templates',
+  'No Database Drivers available!' => 'Geen database besturings programma aanwezig',
+  'No Dataset selected!'        => 'Geen dataset geselecteerd',
+  'Nothing to delete!'          => 'Niets te verwijderen',
+  'Number Format'               => 'Nummeraanduiding',
+  'Oracle Database Administration' => 'Oracle Database Administratie',
+  'Password'                    => 'Wachtwoord',
+  'Password changed!'           => 'Wachtwoord gewijzigd!',
+  'Pg Database Administration'  => 'Pg Database Administratie',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Geen port aanwezig',
+  'Printer'                     => 'Printer',
+  'Save'                        => 'Opslaan',
+  'Select a Dataset to delete and press "Continue"' => 'Selecteer de te verwijderen dataset en klik op "verder"',
+  'Setup Templates'             => 'Setup templates',
+  'Ship via'                    => 'Verzenden via',
+  'Signature'                   => 'Handtekening',
+  'Stylesheet'                  => 'Stylesheet',
+  'Templates'                   => 'Templates',
+  'The following Datasets are not in use and can be deleted' => 'De volgende datasets zijn niet ingebruik en kunnen worder verwijderd.',
+  'The following Datasets need to be updated' => 'De volgende datasets moeten worden bijgewerkt',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Dit is een eerste controle. Er wordt niks gecreéerd of verwijderd.',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Om een gebruiker aan een groep toe te voegen, een naam te wijzigen, een login naam te wijzigen en op te slaan. Een nieuwe gebruiker zal dan worder opgeslagen met dezelfde gegevens onder de nieuwe login naam.',
+  'Update Dataset'              => 'Dataset bijwerken',
+  'Use Templates'               => 'Gebruik templates',
+  'User'                        => 'Gebruiker',
+  'User deleted!'               => 'Gebruiker verwijderd!',
+  'User saved!'                 => 'Gebruiker opgeslagen!',
+  'Version'                     => 'Versie',
+  'You must enter a host and port for local and remote connections!' => 'Vul een "host" en een "port" voor netwerk connecties!',
+  'does not exist'              => 'bestaat niet',
+  'is already a member!'        => 'is al een gebruiker',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'geblokkeerd',
+  'successfully created!'       => 'Succesvol aangemaakt',
+  'successfully deleted!'       => 'Verwijderen succesvol',
+  'website'                     => 'website',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'gebruiker_toevoegen'         => 'add_user',
+  'admin_wachtwoord_veranderen' => 'change_admin_password',
+  'verander_wachtwoord'         => 'change_password',
+  'verder'                      => 'continue',
+  'maak_dataset'                => 'create_dataset',
+  'verwijder'                   => 'delete',
+  'verwijder_dataset'           => 'delete_dataset',
+  'login'                       => 'login',
+  'oracle_database_administratie' => 'oracle_database_administration',
+  'pg_database_administratie'   => 'pg_database_administration',
+  'opslaan'                     => 'save',
+  'dataset_bijwerken'           => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/all b/sql-ledger/locale/nl/all
new file mode 100644 (file)
index 0000000..2e55089
--- /dev/null
@@ -0,0 +1,491 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Crediteuren',
+  'AP Aging'                    => 'Crediteuren Ouderdomsoverzicht',
+  'AP Transaction'              => 'Crediteurenboeking',
+  'AP Transactions'             => 'Crediteurenboekingen',
+  'AR'                          => 'Debiteuren',
+  'AR Aging'                    => 'Debiteuren Ouderdomsoverzicht',
+  'AR Transaction'              => 'Debiteurenboeking',
+  'AR Transactions'             => 'Debiteurenboekingen',
+  'About'                       => 'Over',
+  'Access Control'              => 'Toegangsbeheer',
+  'Account'                     => 'Rekening',
+  'Account Number'              => 'Rekeningnummer',
+  'Account Number missing!'     => 'Rekeningnummer mist!',
+  'Account Type'                => 'Rekeningtype',
+  'Account Type missing!'       => 'Rekeningtype mist!',
+  'Account deleted!'            => 'Rekening verwijderd',
+  'Account saved!'              => 'Rekening opgeslagen',
+  'Accounting'                  => 'Boekhouding',
+  'Accounting Menu'             => 'Boekhoudmenu',
+  'Accounts'                    => 'Rekeningen',
+  'Active'                      => 'Actief',
+  'Add'                         => 'Toevoegen',
+  'Add Account'                 => 'Rekening toevoegen',
+  'Add Accounts Payables Transaction' => 'Crediteurenboeking toevoegen',
+  'Add Accounts Receivables Transaction' => 'Debiteurenboeking toevoegen',
+  'Add Assembly'                => 'Assemblage toevoegen',
+  'Add Customer'                => 'Klant toevoegen',
+  'Add GIFI'                    => 'Toevoegen GIFI',
+  'Add General Ledger Transaction' => 'Journaalpost toevoegen',
+  'Add Part'                    => 'Artikel toevoegen',
+  'Add Project'                 => 'Project toevoegen',
+  'Add Purchase Invoice'        => 'Inkoopfactuur toevoegen',
+  'Add Purchase Order'          => 'Inkooporder toevoegen',
+  'Add Sales Invoice'           => 'Verkoopfactuur toevoegen',
+  'Add Sales Order'             => 'Verkooporder toevoegen',
+  'Add Service'                 => 'Dienst toevoegen',
+  'Add Transaction'             => 'Boeking toevoegen',
+  'Add User'                    => 'Gebruiker toevoegen',
+  'Add Vendor'                  => 'Leverancier toevoegen',
+  'Address'                     => 'Adres',
+  'Administration'              => 'Administratie',
+  'Administrator'               => 'Beheerder',
+  'All'                         => 'Allemaal',
+  'All Datasets up to date!'    => 'Alle Datasets actueel',
+  'Amount'                      => 'Bedrag',
+  'Amount Due'                  => 'Verschuldigd bedrag',
+  'Amount does not equal applied!' => 'Bedrag is ongelijk aan toewijzing!',
+  'Amount missing!'             => 'Bedrag ontbreekt!',
+  'Applied'                     => 'Toewijzing',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Invoice Number' => 'Weet u zeker dat u dit factuurnummer wilt verwijderen?',
+  'Are you sure you want to delete Order Number' => 'Weet u zeker dat u dit ordernummer wilt verwijderen?',
+  'Are you sure you want to delete Transaction' => 'Weet u zeker dat u deze boeking wilt verwijderen?',
+  'Assemblies'                  => 'Assemblage, samengestelde artikelen',
+  'Assemblies restocked!'       => 'Assemblage naar voorraad geboekt',
+  'Assembly Number missing!'    => 'Assemblagenummer mist!',
+  'Asset'                       => 'Activa (bezittingen)',
+  'Attachment'                  => 'Bijlage',
+  'Audit Control'               => 'Accountants Controle',
+  'Aug'                         => 'Aug',
+  'August'                      => 'Augustus',
+  'BOM'                         => 'Onderdelenlijst',
+  'Backup'                      => 'Backup',
+  'Backup sent to'              => 'Backup gezonden aan',
+  'Balance'                     => 'Saldo',
+  'Balance Sheet'               => 'Balans',
+  'Bcc'                         => 'Onzichtbare kopie aan',
+  'Bin'                         => 'Locatie',
+  'Books are open'              => 'Boekingsperiode is open',
+  'Bought'                      => 'Ingekocht',
+  'Business Number'             => 'Kamer van Koophandel nummer',
+  'C'                           => 'C',
+  'COGS'                        => 'Kostprijs Verkopen',
+  'Cannot delete account!'      => 'Kan bedrag niet verwijderen!',
+  'Cannot delete customer!'     => 'Kan klant niet verwijderen!',
+  'Cannot delete default account!' => 'Kan standaardrekening niet verwijderen!',
+  'Cannot delete invoice!'      => 'Kan factuur niet verwijderen!',
+  'Cannot delete item already invoiced!' => 'Kan reeds gefactureerd artikel niet verwijderen!',
+  'Cannot delete item on order!' => 'Kan onderdeel van de order niet verwijderen',
+  'Cannot delete item which is part of an assembly!' => 'Kan onderdeel van een samengesteld artikel niet verwijderen!',
+  'Cannot delete item!'         => 'Kan onderdeel niet verwijderen!',
+  'Cannot delete order!'        => 'Kan order niet verwijderen!',
+  'Cannot delete transaction!'  => 'Kan transactie niet verwijderen!',
+  'Cannot delete vendor!'       => 'Kan leverancier niet verwijderen!',
+  'Cannot have a value in both Debit and Credit!' => 'Waarde kan alleen debet of credit voorkomen!',
+  'Cannot post a transaction without a value!' => 'Kan geen boeking maken zonder waarde!',
+  'Cannot post invoice for a closed period!' => 'Kan geen factuur boeken in afgesloten periode!',
+  'Cannot post invoice!'        => 'Kan factuur niet boeken!',
+  'Cannot post payment for a closed period!' => 'Kan geen betaling boeken voor afgesloten periode!',
+  'Cannot post payment!'        => 'Kan betaling niet boeken!',
+  'Cannot post transaction for a closed period!' => 'Kan geen boeking maken in afgesloten periode',
+  'Cannot post transaction!'    => 'Kan transactie niet boeken!',
+  'Cannot process payment for a closed period!' => 'Kan geen betaling verwerken voor afgesloten periode!',
+  'Cannot save account!'        => 'Kan rekening niet opslaan!',
+  'Cannot save order!'          => 'Kan order niet opslaan!',
+  'Cannot save preferences!'    => 'Kan voorkeuren niet opslaan!',
+  'Cannot stock assemblies!'    => 'Kan assemblages niet in voorraad nemen!',
+  'Cash'                        => 'Kas (contant)',
+  'Cash based'                  => 'Kasbasis (contante verkopen)',
+  'Cc'                          => 'Copie aan',
+  'Change Admin Password'       => 'Admin wachtwoord veranderen',
+  'Change Password'             => 'Verander wachtwoord',
+  'Character Set'               => 'Karakter set',
+  'Chart of Accounts'           => 'Rekeningstelsel',
+  'Check'                       => 'Cheque',
+  'Check printed!'              => 'Cheque geprint!',
+  'Check printing failed!'      => 'Cheque printen mislukt!',
+  'Cleared Balance'             => 'Totaal geboekt vorige afschriften',
+  'Click on login name to edit!' => 'Klik op login naam om deze te bewerken.',
+  'Close Books up to'           => 'Boeken afsluiten tot',
+  'Closed'                      => 'Afgesloten',
+  'Company'                     => 'Bedrijf',
+  'Compare to'                  => 'Vergelijk met',
+  'Confirm!'                    => 'Bevestig!',
+  'Connect to'                  => 'Verbinden met',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Verder',
+  'Copies'                      => 'Kopieën',
+  'Copy to COA'                 => 'Kopieër naar rekeningstelsel',
+  'Create Chart of Accounts'    => 'Maak rekeningstelsel',
+  'Create Dataset'              => 'Maak dataset',
+  'Credit'                      => 'Credit',
+  'Credit Limit'                => 'Kredietlimiet',
+  'Curr'                        => 'Val.',
+  'Currency'                    => 'Valuta',
+  'Current'                     => 'Huidig',
+  'Customer'                    => 'Klant',
+  'Customer deleted!'           => 'Klant verwijderd!',
+  'Customer missing!'           => 'Klant ontbreekt!',
+  'Customer not on file!'       => 'Klant bestaat niet!',
+  'Customer saved!'             => 'Klant opgeslagen!',
+  'Customers'                   => 'Klanten',
+  'DBI not installed!'          => 'DBI niet geinstalleerd',
+  'Database'                    => 'Database',
+  'Database Administration'     => 'Database administratie',
+  'Database Driver not checked!' => 'Database Driver niet aangevinkt',
+  'Database Host'               => 'Database computer',
+  'Database User missing!'      => 'Geen database gebruiker aanwezig!',
+  'Dataset'                     => 'Dataset',
+  'Dataset missing!'            => 'Geen dataset aanwezig',
+  'Dataset updated!'            => 'Dataset aangepast aan nieuwe versie!',
+  'Date'                        => 'Datum',
+  'Date Due'                    => 'Vervaldatum',
+  'Date Format'                 => 'Datum formaat',
+  'Date Paid'                   => 'Betaaldatum',
+  'Date missing!'               => 'Datum ontbreekt!',
+  'Debit'                       => 'Debet',
+  'Debit and credit out of balance!' => 'Debet en credit moeten gelijk zijn!',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Decimalplaces'               => 'Aantal Decimalen',
+  'Delete'                      => 'Verwijder',
+  'Delete Account'              => 'Rekening verwijderen',
+  'Delete Dataset'              => 'Verwijder dataset',
+  'Delivery Date'               => 'Leverdatum',
+  'Deposit'                     => 'Storting',
+  'Description'                 => 'Omschrijving',
+  'Difference'                  => 'Verschil',
+  'Directory'                   => 'Directory',
+  'Discount'                    => 'Korting',
+  'Done'                        => 'Klaar',
+  'Drawing'                     => 'Tekening',
+  'Driver'                      => 'Besturings programma',
+  'Dropdown Limit'              => 'Maximum in dropdown-lijst',
+  'Due'                         => 'Verschuldigd',
+  'Due Date'                    => 'Vervaldatum',
+  'Due Date missing!'           => 'Vervaldatum mist!',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'E-mail Overzicht aan',
+  'E-mail address missing!'     => 'E-mailadres mist!',
+  'Edit'                        => 'Wijzig',
+  'Edit Account'                => 'Rekening wijzigen',
+  'Edit Accounts Payables Transaction' => 'Wijzig Crediteurenboeking',
+  'Edit Accounts Receivables Transaction' => 'Wijzig Debiteurenboeking',
+  'Edit Assembly'               => 'Assemblage wijzigen',
+  'Edit Customer'               => 'Klant wijzigen',
+  'Edit GIFI'                   => 'Wijzig GIFI',
+  'Edit General Ledger Transaction' => 'Boeking in grootboek wijzigen',
+  'Edit Part'                   => 'Artikel wijzigen',
+  'Edit Preferences for'        => 'Instellingen wijzigen voor',
+  'Edit Project'                => 'Project wijzigen',
+  'Edit Purchase Invoice'       => 'Inkoopfactuur wijzigen',
+  'Edit Purchase Order'         => 'Inkooporder wijzigen',
+  'Edit Sales Invoice'          => 'Verkoopfactuur wijzigen',
+  'Edit Sales Order'            => 'Verkoop order wijzigen',
+  'Edit Service'                => 'Dienst wijzigen',
+  'Edit Template'               => 'Template wijzigen',
+  'Edit User'                   => 'Gebruiker wijzigen',
+  'Edit Vendor'                 => 'Leverancier wijzigen',
+  'Employee'                    => 'Werknemer',
+  'Enforce transaction reversal for all dates' => 'Boeking terugdraaien voor alle data',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Vul max drie karakters in, gescheiden door een dubbelepunt (b.v. EUR:USD:GBP:CAD) voor lokale en buitenlandse valuta',
+  'Equity'                      => 'Passiva/Eigen Vermogen',
+  'Exch'                        => 'Wisselkoers',
+  'Exchangerate'                => 'Wisselkoers',
+  'Exchangerate Difference'     => 'Koersverschil',
+  'Exchangerate for payment missing!' => 'Wisselkoers voor Betaling mist!',
+  'Exchangerate missing!'       => 'Wisselkoers mist!',
+  'Existing Datasets'           => 'Bestaande datasets',
+  'Expense'                     => 'Onkosten',
+  'Expense Account'             => 'Onkostenrekening',
+  'Expense/Asset'               => 'Uitgaven',
+  'Extended'                    => 'Uitgebreid',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'Foreign Exchange Gain'       => 'Wisselkoers winst',
+  'Foreign Exchange Loss'       => 'Wisselkoers verlies',
+  'From'                        => 'Van',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI verwijderd!',
+  'GIFI missing!'               => 'GIFI ontbreekt!',
+  'GIFI saved!'                 => 'GIFI opgeslagen!',
+  'GL Transaction'              => 'Grootboekboeking (memoriaal) ',
+  'General Ledger'              => 'Grootboek',
+  'Goods & Services'            => 'Goederen & Diensten',
+  'HTML Templates'              => 'HTML Sjablonen',
+  'Heading'                     => 'Kopregel',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Geen hostnaam!',
+  'ID'                          => 'ID',
+  'Image'                       => 'Plaatje',
+  'In-line'                     => 'In Lijn',
+  'Include in Report'           => 'Uitvoer inclusief',
+  'Include in drop-down menus'  => 'Invoegen in drop-down menus',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Deze klant/leverancier toevoegen als belastbaar?',
+  'Income'                      => 'Inkomsten',
+  'Income Account'              => 'Inkomstenrekening',
+  'Income Statement'            => 'Inkomstenoverzicht',
+  'Incorrect Dataset version!'  => 'Ongeldige versie Dataset!!',
+  'Incorrect Password!'         => 'Verkeerd paswoord',
+  'Individual Items'            => 'Onderliggede onderdelen',
+  'Inventory'                   => 'Voorraad',
+  'Inventory Account'           => 'Voorraadrekening',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Aanwezige voorraad moet nul zijn voordat een assemblage als \'niet actief\' kan worder gemarkeerd.',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Aanwezige voorraad moet nul zijn voordat een product als \'niet actief\' kan worder gemarkeerd.',
+  'Inventory quantity must be zero!' => 'Aanwezige voorraad moet nul zijn!',
+  'Invoice'                     => 'Factuur',
+  'Invoice Date'                => 'Factuurdatum',
+  'Invoice Date missing!'       => 'Factuurdatum mist!',
+  'Invoice Number'              => 'Factuurnummer',
+  'Invoice Number missing!'     => 'Factuurnummer mist!',
+  'Invoice deleted!'            => 'Factuur verwijderd!',
+  'Invoice posted!'             => 'Factuur geboekt!',
+  'Invoices'                    => 'Facturen',
+  'Is this a summary account to record' => 'Totaalrekening voor',
+  'Item deleted!'               => 'Onderdeel verwijderd!',
+  'Item not on file!'           => 'Dit onderdeel is niet in de database gevonden!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'LaTeX Templates'             => 'Latex Sjablonen',
+  'Language'                    => 'Taal',
+  'Last Cost'                   => 'Vorige kostprijs',
+  'Last Invoice Number'         => 'Laatste factuurnummer',
+  'Last Numbers & Default Accounts' => 'Laatst toegekende nummers & Standaard Rekeningen',
+  'Last Purchase Order Number'  => 'Laatste inkoopordernummer',
+  'Last Sales Order Number'     => 'Laatste Verkooporder nummer',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Laat host en port veld leeg, tenzij u een netwerk connectie wilt opzetten.',
+  'Liability'                   => 'Passiva',
+  'Licensed to'                 => 'Gelicenseerd aan',
+  'Line Total'                  => 'Totaal Regel',
+  'Link'                        => 'Verbinding',
+  'Link Accounts'               => 'Rekeningen verbinden',
+  'List Accounts'               => 'Rekeningen weergeven',
+  'List GIFI'                   => 'GIFI weergeven',
+  'List Price'                  => 'Prijzen weergeven',
+  'List Transactions'           => 'Boekingen tonen',
+  'Login'                       => 'Login',
+  'Logout'                      => 'Logout',
+  'Make'                        => 'Fabrikant',
+  'Mar'                         => 'Mrt',
+  'March'                       => 'Maart',
+  'May'                         => 'Mei',
+  'May '                        => 'Mei',
+  'Message'                     => 'Boodschap',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Type',
+  'Multibyte Encoding'          => '',
+  'N/A'                         => 'N/A',
+  'Name'                        => 'Naam',
+  'Name missing!'               => 'Naam ontbreekt!',
+  'New Templates'               => 'Nieuwe templates',
+  'No'                          => 'Nee',
+  'No Database Drivers available!' => 'Geen database besturings programma aanwezig',
+  'No Dataset selected!'        => 'Geen dataset geselecteerd',
+  'No email address for'        => 'Geen email adres voor',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Opmerkingen',
+  'Nothing applied!'            => 'Niets toegewezen!',
+  'Nothing selected!'           => 'Niets geselecteerd!',
+  'Nothing to delete!'          => 'Niets te verwijderen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number Format'               => 'Nummeraanduiding',
+  'Number missing in Row'       => 'Getal missend in regel',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Niet actief',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'On Hand'                     => 'Op voorraad',
+  'On Order'                    => 'In bestelling',
+  'Open'                        => 'Open',
+  'Oracle Database Administration' => 'Oracle Database Administratie',
+  'Order'                       => 'Bestelling',
+  'Order Date'                  => 'Orderdatum',
+  'Order Date missing!'         => 'Geen order datum aanwezig',
+  'Order Entry'                 => 'Order invoer',
+  'Order Number'                => 'Referentie',
+  'Order Number missing!'       => 'Geen ordernummer aanwezig',
+  'Order deleted!'              => 'Order verwijderd!',
+  'Order saved!'                => 'Order opgeslagen!',
+  'Ordered'                     => 'Besteld',
+  'Orphaned'                    => 'Wees',
+  'Out of balance!'             => 'Niet in evenwicht!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Pakbon',
+  'Packing List Date missing!'  => 'Pakbon datum mist!',
+  'Packing List Number missing!' => 'Pakbon nummer mist!',
+  'Paid'                        => 'Betaald',
+  'Paid in full'                => 'Volledig betaald',
+  'Part'                        => 'Artikel',
+  'Part Number missing!'        => 'Artikelnummer mist!',
+  'Parts'                       => 'Artikelen',
+  'Parts Inventory'             => 'Artikelenvrd',
+  'Password'                    => 'Wachtwoord',
+  'Password changed!'           => 'Wachtwoord gewijzigd!',
+  'Payables'                    => 'Betalingen',
+  'Payment'                     => 'Betaling',
+  'Payment date missing!'       => 'Geen betalingsdatum aanwezig!',
+  'Payment posted!'             => 'Betaling geboekt!',
+  'Payments'                    => 'Betalingen',
+  'Pg Database Administration'  => 'Pg Database Administratie',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Geen port aanwezig',
+  'Post'                        => 'Boek',
+  'Post as new'                 => 'Boek als nieuw',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Instellingen',
+  'Preferences saved!'          => 'Instellingen bewaard!',
+  'Price'                       => 'Prijs',
+  'Print'                       => 'Afdrukken',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Project',
+  'Project Number missing!'     => 'Projectnummer ontbreekt!',
+  'Project deleted!'            => 'Project verwijderd!',
+  'Project not on file!'        => 'Project bestaat niet!',
+  'Project saved!'              => 'Project opgeslagen!',
+  'Projects'                    => 'Projecten',
+  'Purchase Invoice'            => 'Inkoopfactuur',
+  'Purchase Order'              => 'Inkooporder',
+  'Purchase Orders'             => 'Inkooporders',
+  'Qty'                         => 'Aantal',
+  'ROP'                         => 'Minimum voorraad',
+  'Rate'                        => 'Percentage',
+  'Recd'                        => 'Ontvangen',
+  'Receipt'                     => 'Ontvangstbewijs',
+  'Receipts'                    => 'Ontvangstbewijzen',
+  'Receivables'                 => 'Vorderingen',
+  'Reconciliation'              => 'Bank Overzicht',
+  'Record in'                   => 'Boeken op',
+  'Reference'                   => 'Referentie',
+  'Reference missing!'          => 'Referentie ontbreekt!',
+  'Remaining'                   => 'Resterend',
+  'Report for'                  => 'Rapport voor',
+  'Reports'                     => 'Rapporten',
+  'Required by'                 => 'Nodig voor',
+  'Retained Earnings'           => 'Winstreserve',
+  'Sales'                       => 'Verkoop',
+  'Sales Invoice'               => 'Verkoopfactuur',
+  'Sales Order'                 => 'Verkooporder',
+  'Sales Orders'                => 'Verkooporders',
+  'Save'                        => 'Opslaan',
+  'Save as new'                 => 'Opslaan als nieuw',
+  'Save to File'                => 'Opslaan als bestand',
+  'Screen'                      => 'Scherm',
+  'Select a Dataset to delete and press "Continue"' => 'Selecteer de te verwijderen dataset en klik op "verder"',
+  'Select all'                  => 'Selecteer alles',
+  'Select from one of the items below' => 'Kies een van de onderstaande items',
+  'Select from one of the names below' => 'Kies een van de onderstaande namen',
+  'Select from one of the projects below' => 'Kies een van de onderstaande projecten',
+  'Select postscript or PDF!'   => 'Kies postscript of PDF',
+  'Sell Price'                  => 'Verkoopprijs',
+  'Send by E-Mail'              => 'Verzenden per E-mail',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Dienst',
+  'Service Items'               => 'Dienst',
+  'Service Number missing!'     => 'Dienstnummer mist',
+  'Services'                    => 'Diensten',
+  'Setup Templates'             => 'Setup templates',
+  'Ship'                        => 'Verzenden',
+  'Ship to'                     => 'Verzenden aan',
+  'Ship via'                    => 'Verzenden via',
+  'Short'                       => 'Kort',
+  'Signature'                   => 'Handtekening',
+  'Sold'                        => 'Verkocht',
+  'Source'                      => 'Herkomst',
+  'Standard'                    => 'Standaard',
+  'Statement'                   => 'Overzicht',
+  'Statement Balance'           => 'Saldo Overzicht',
+  'Statement sent to'           => 'Overzicht verzonden aan',
+  'Statements sent to printer!' => 'Overzichten afgedrukt',
+  'Stock Assembly'              => 'Assemblage voorraad',
+  'Stylesheet'                  => 'Stylesheet',
+  'Subject'                     => 'Onderwerp',
+  'Subtotal'                    => 'Subtotaal',
+  'System'                      => 'Systeem',
+  'Tax'                         => 'Belasting',
+  'Tax Accounts'                => 'Belasting Rekeningen',
+  'Tax Included'                => 'Inclusief Belasting',
+  'Tax collected'               => 'Belasting verschuldigd',
+  'Tax paid'                    => 'Belasting Betaald',
+  'Taxable'                     => 'Belastbaar percentage',
+  'Template saved!'             => 'Template opgeslagen!',
+  'Templates'                   => 'Templates',
+  'Terms: Net'                  => 'Netto',
+  'The following Datasets are not in use and can be deleted' => 'De volgende datasets zijn niet ingebruik en kunnen worder verwijderd.',
+  'The following Datasets need to be updated' => 'De volgende datasets moeten worden bijgewerkt',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Dit is een eerste controle. Er wordt niks gecreéerd of verwijderd.',
+  'To'                          => 'Tot',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Om een gebruiker aan een groep toe te voegen, een naam te wijzigen, een login naam te wijzigen en op te slaan. Een nieuwe gebruiker zal dan worder opgeslagen met dezelfde gegevens onder de nieuwe login naam.',
+  'Top Level'                   => 'Top Niveau',
+  'Total'                       => 'Totaal',
+  'Transaction Date missing!'   => 'Boekingsdatum mist!',
+  'Transaction deleted!'        => 'Boeking verwijderd!',
+  'Transaction posted!'         => 'Boeking opgeslagen!',
+  'Transaction reversal enforced for all dates' => 'Boekingen verplicht terugdraaien voor alle datums',
+  'Transaction reversal enforced up to' => 'Boekingen verplicht terugdraaien tot aan',
+  'Transactions'                => 'Boekingen',
+  'Transactions exist, cannot delete customer!' => 'Kan klant niet verwijderen, er zijn onderliggende boekingen!',
+  'Transactions exist, cannot delete vendor!' => 'Kan leverancier niet verwijderen, er zijn onderliggende boekingen!',
+  'Transactions exist; cannot delete account!' => 'Kan rekening niet verwijderen, er zijn onderliggende boekingen!',
+  'Trial Balance'               => 'Proefbalans',
+  'Unit'                        => 'Eenheid',
+  'Unit of measure'             => 'Rekeneenheid',
+  'Update'                      => 'Bijwerken',
+  'Update Dataset'              => 'Dataset bijwerken',
+  'Updated'                     => 'Bijgewerkt',
+  'Use Templates'               => 'Gebruik templates',
+  'User'                        => 'Gebruiker',
+  'User deleted!'               => 'Gebruiker verwijderd!',
+  'User saved!'                 => 'Gebruiker opgeslagen!',
+  'Vendor'                      => 'Leverancier',
+  'Vendor deleted!'             => 'Leverancier verwijderd!',
+  'Vendor missing!'             => 'Leverancier ontbreekt!',
+  'Vendor not on file!'         => 'Leverancier bestaat niet!',
+  'Vendor saved!'               => 'Leverancier opgeslagen!',
+  'Vendors'                     => 'Leveranciers',
+  'Version'                     => 'Versie',
+  'Weight'                      => 'Gewicht',
+  'Weight Unit'                 => 'Gewichtseenheid',
+  'What type of item is this?'  => 'Wat voor soort artikel is dit?',
+  'Year End'                    => 'Einde van het boekjaar',
+  'Yes'                         => 'Ja',
+  'You are logged out!'         => 'U bent uitgelogd!',
+  'You did not enter a name!'   => 'U heeft geen naam gegeven!',
+  'You must enter a host and port for local and remote connections!' => 'Vul een "host" en een "port" voor netwerk connecties!',
+  'as at'                       => 'per',
+  'collected on sales'          => 'verzameld voor de verkoop',
+  'days'                        => 'dagen',
+  'does not exist'              => 'bestaat niet',
+  'ea'                          => 'voor',
+  'emailed to'                  => 'per email verzonden aan',
+  'for Period'                  => 'voor periode',
+  'hr'                          => 'uur',
+  'is already a member!'        => 'is al een gebruiker',
+  'is not a member!'            => 'is geen gebruiker',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'geblokkeerd',
+  'paid on purchases'           => 'betaald op inkopen',
+  'sent to printer'             => 'Afgedrukt',
+  'successfully created!'       => 'Succesvol aangemaakt',
+  'successfully deleted!'       => 'Verwijderen succesvol',
+  'to'                          => 'tot',
+  'website'                     => 'website',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/am b/sql-ledger/locale/nl/am
new file mode 100644 (file)
index 0000000..0b3633b
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Crediteuren',
+  'AR'                          => 'Debiteuren',
+  'Account'                     => 'Rekening',
+  'Account Number'              => 'Rekeningnummer',
+  'Account Number missing!'     => 'Rekeningnummer mist!',
+  'Account Type'                => 'Rekeningtype',
+  'Account Type missing!'       => 'Rekeningtype mist!',
+  'Account deleted!'            => 'Rekening verwijderd',
+  'Account saved!'              => 'Rekening opgeslagen',
+  'Add Account'                 => 'Rekening toevoegen',
+  'Add GIFI'                    => 'Toevoegen GIFI',
+  'Address'                     => 'Adres',
+  'Asset'                       => 'Activa (bezittingen)',
+  'Audit Control'               => 'Accountants Controle',
+  'Backup sent to'              => 'Backup gezonden aan',
+  'Books are open'              => 'Boekingsperiode is open',
+  'Business Number'             => 'Kamer van Koophandel nummer',
+  'COGS'                        => 'Kostprijs Verkopen',
+  'Cannot delete account!'      => 'Kan bedrag niet verwijderen!',
+  'Cannot delete default account!' => 'Kan standaardrekening niet verwijderen!',
+  'Cannot save account!'        => 'Kan rekening niet opslaan!',
+  'Cannot save preferences!'    => 'Kan voorkeuren niet opslaan!',
+  'Character Set'               => 'Karakter set',
+  'Chart of Accounts'           => 'Rekeningstelsel',
+  'Close Books up to'           => 'Boeken afsluiten tot',
+  'Company'                     => 'Bedrijf',
+  'Continue'                    => 'Verder',
+  'Copy to COA'                 => 'Kopieër naar rekeningstelsel',
+  'Credit'                      => 'Credit',
+  'Date Format'                 => 'Datum formaat',
+  'Debit'                       => 'Debet',
+  'Delete'                      => 'Verwijder',
+  'Delete Account'              => 'Rekening verwijderen',
+  'Description'                 => 'Omschrijving',
+  'Dropdown Limit'              => 'Maximum in dropdown-lijst',
+  'E-mail'                      => 'E-mail',
+  'Edit'                        => 'Wijzig',
+  'Edit Account'                => 'Rekening wijzigen',
+  'Edit GIFI'                   => 'Wijzig GIFI',
+  'Edit Preferences for'        => 'Instellingen wijzigen voor',
+  'Edit Template'               => 'Template wijzigen',
+  'Enforce transaction reversal for all dates' => 'Boeking terugdraaien voor alle data',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Vul max drie karakters in, gescheiden door een dubbelepunt (b.v. EUR:USD:GBP:CAD) voor lokale en buitenlandse valuta',
+  'Equity'                      => 'Passiva/Eigen Vermogen',
+  'Expense'                     => 'Onkosten',
+  'Expense Account'             => 'Onkostenrekening',
+  'Expense/Asset'               => 'Uitgaven',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Wisselkoers winst',
+  'Foreign Exchange Loss'       => 'Wisselkoers verlies',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI verwijderd!',
+  'GIFI missing!'               => 'GIFI ontbreekt!',
+  'GIFI saved!'                 => 'GIFI opgeslagen!',
+  'Heading'                     => 'Kopregel',
+  'Include in drop-down menus'  => 'Invoegen in drop-down menus',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Deze klant/leverancier toevoegen als belastbaar?',
+  'Income'                      => 'Inkomsten',
+  'Income Account'              => 'Inkomstenrekening',
+  'Inventory'                   => 'Voorraad',
+  'Inventory Account'           => 'Voorraadrekening',
+  'Is this a summary account to record' => 'Totaalrekening voor',
+  'Language'                    => 'Taal',
+  'Last Invoice Number'         => 'Laatste factuurnummer',
+  'Last Numbers & Default Accounts' => 'Laatst toegekende nummers & Standaard Rekeningen',
+  'Last Purchase Order Number'  => 'Laatste inkoopordernummer',
+  'Last Sales Order Number'     => 'Laatste Verkooporder nummer',
+  'Liability'                   => 'Passiva',
+  'Link'                        => 'Verbinding',
+  'Name'                        => 'Naam',
+  'No'                          => 'Nee',
+  'No email address for'        => 'Geen email adres voor',
+  'Number'                      => 'Nummer',
+  'Number Format'               => 'Nummeraanduiding',
+  'Parts Inventory'             => 'Artikelenvrd',
+  'Password'                    => 'Wachtwoord',
+  'Payables'                    => 'Betalingen',
+  'Payment'                     => 'Betaling',
+  'Phone'                       => 'Tel.',
+  'Preferences saved!'          => 'Instellingen bewaard!',
+  'Rate'                        => 'Percentage',
+  'Receivables'                 => 'Vorderingen',
+  'Sales'                       => 'Verkoop',
+  'Save'                        => 'Opslaan',
+  'Service Items'               => 'Dienst',
+  'Ship via'                    => 'Verzenden via',
+  'Signature'                   => 'Handtekening',
+  'Stylesheet'                  => 'Stylesheet',
+  'Tax'                         => 'Belasting',
+  'Tax Accounts'                => 'Belasting Rekeningen',
+  'Template saved!'             => 'Template opgeslagen!',
+  'Transaction reversal enforced for all dates' => 'Boekingen verplicht terugdraaien voor alle datums',
+  'Transaction reversal enforced up to' => 'Boekingen verplicht terugdraaien tot aan',
+  'Transactions exist; cannot delete account!' => 'Kan rekening niet verwijderen, er zijn onderliggende boekingen!',
+  'Weight Unit'                 => 'Gewichtseenheid',
+  'Year End'                    => 'Einde van het boekjaar',
+  'Yes'                         => 'Ja',
+  'does not exist'              => 'bestaat niet',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'rekening_toevoegen'          => 'add_account',
+  'verder'                      => 'continue',
+  'kopieër_naar_rekeningstelsel' => 'copy_to_coa',
+  'verwijder'                   => 'delete',
+  'wijzig'                      => 'edit',
+  'rekening_wijzigen'           => 'edit_account',
+  'opslaan'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/ap b/sql-ledger/locale/nl/ap
new file mode 100644 (file)
index 0000000..177034c
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Crediteurenboeking',
+  'AP Transactions'             => 'Crediteurenboekingen',
+  'Account'                     => 'Rekening',
+  'Add Accounts Payables Transaction' => 'Crediteurenboeking toevoegen',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Bedrag',
+  'Amount Due'                  => 'Verschuldigd bedrag',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Transaction' => 'Weet u zeker dat u deze boeking wilt verwijderen?',
+  'Aug'                         => 'Aug',
+  'August'                      => 'Augustus',
+  'Cannot delete transaction!'  => 'Kan transactie niet verwijderen!',
+  'Cannot post payment for a closed period!' => 'Kan geen betaling boeken voor afgesloten periode!',
+  'Cannot post transaction for a closed period!' => 'Kan geen boeking maken in afgesloten periode',
+  'Cannot post transaction!'    => 'Kan transactie niet boeken!',
+  'Closed'                      => 'Afgesloten',
+  'Confirm!'                    => 'Bevestig!',
+  'Continue'                    => 'Verder',
+  'Currency'                    => 'Valuta',
+  'Customer not on file!'       => 'Klant bestaat niet!',
+  'Date'                        => 'Datum',
+  'Date Paid'                   => 'Betaaldatum',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Verwijder',
+  'Description'                 => 'Omschrijving',
+  'Due Date'                    => 'Vervaldatum',
+  'Due Date missing!'           => 'Vervaldatum mist!',
+  'Edit Accounts Payables Transaction' => 'Wijzig Crediteurenboeking',
+  'Employee'                    => 'Werknemer',
+  'Exch'                        => 'Wisselkoers',
+  'Exchangerate'                => 'Wisselkoers',
+  'Exchangerate for payment missing!' => 'Wisselkoers voor Betaling mist!',
+  'Exchangerate missing!'       => 'Wisselkoers mist!',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Van',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Uitvoer inclusief',
+  'Invoice'                     => 'Factuur',
+  'Invoice Date'                => 'Factuurdatum',
+  'Invoice Date missing!'       => 'Factuurdatum mist!',
+  'Invoice Number'              => 'Factuurnummer',
+  'Invoice Number missing!'     => 'Factuurnummer mist!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mrt',
+  'March'                       => 'Maart',
+  'May'                         => 'Mei',
+  'May '                        => 'Mei',
+  'Notes'                       => 'Opmerkingen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Open'                        => 'Open',
+  'Order'                       => 'Bestelling',
+  'Order Number'                => 'Referentie',
+  'Paid'                        => 'Betaald',
+  'Payment date missing!'       => 'Geen betalingsdatum aanwezig!',
+  'Payments'                    => 'Betalingen',
+  'Post'                        => 'Boek',
+  'Post as new'                 => 'Boek als nieuw',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project bestaat niet!',
+  'Purchase Invoice'            => 'Inkoopfactuur',
+  'Select from one of the names below' => 'Kies een van de onderstaande namen',
+  'Select from one of the projects below' => 'Kies een van de onderstaande projecten',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Herkomst',
+  'Subtotal'                    => 'Subtotaal',
+  'Tax'                         => 'Belasting',
+  'Tax Included'                => 'Inclusief Belasting',
+  'Total'                       => 'Totaal',
+  'Transaction deleted!'        => 'Boeking verwijderd!',
+  'Transaction posted!'         => 'Boeking opgeslagen!',
+  'Update'                      => 'Bijwerken',
+  'Vendor'                      => 'Leverancier',
+  'Vendor missing!'             => 'Leverancier ontbreekt!',
+  'Vendor not on file!'         => 'Leverancier bestaat niet!',
+  'Yes'                         => 'Ja',
+  'to'                          => 'tot',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'crediteurenboeking'          => 'ap_transaction',
+  'crediteurenboeking_toevoegen' => 'add_accounts_payables_transaction',
+  'verder'                      => 'continue',
+  'verwijder'                   => 'delete',
+  'wijzig_crediteurenboeking'   => 'edit_accounts_payables_transaction',
+  'boek'                        => 'post',
+  'boek_als_nieuw'              => 'post_as_new',
+  'inkoopfactuur'               => 'purchase_invoice',
+  'bijwerken'                   => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/ar b/sql-ledger/locale/nl/ar
new file mode 100644 (file)
index 0000000..73aed90
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'Debiteurenboeking',
+  'AR Transactions'             => 'Debiteurenboekingen',
+  'Account'                     => 'Rekening',
+  'Add Accounts Receivables Transaction' => 'Debiteurenboeking toevoegen',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Bedrag',
+  'Amount Due'                  => 'Verschuldigd bedrag',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Transaction' => 'Weet u zeker dat u deze boeking wilt verwijderen?',
+  'Aug'                         => 'Aug',
+  'August'                      => 'Augustus',
+  'Cannot delete transaction!'  => 'Kan transactie niet verwijderen!',
+  'Cannot post payment for a closed period!' => 'Kan geen betaling boeken voor afgesloten periode!',
+  'Cannot post transaction for a closed period!' => 'Kan geen boeking maken in afgesloten periode',
+  'Cannot post transaction!'    => 'Kan transactie niet boeken!',
+  'Closed'                      => 'Afgesloten',
+  'Confirm!'                    => 'Bevestig!',
+  'Continue'                    => 'Verder',
+  'Credit Limit'                => 'Kredietlimiet',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Klant',
+  'Customer missing!'           => 'Klant ontbreekt!',
+  'Customer not on file!'       => 'Klant bestaat niet!',
+  'Date'                        => 'Datum',
+  'Date Paid'                   => 'Betaaldatum',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Verwijder',
+  'Description'                 => 'Omschrijving',
+  'Due Date'                    => 'Vervaldatum',
+  'Due Date missing!'           => 'Vervaldatum mist!',
+  'Edit Accounts Receivables Transaction' => 'Wijzig Debiteurenboeking',
+  'Employee'                    => 'Werknemer',
+  'Exch'                        => 'Wisselkoers',
+  'Exchangerate'                => 'Wisselkoers',
+  'Exchangerate for payment missing!' => 'Wisselkoers voor Betaling mist!',
+  'Exchangerate missing!'       => 'Wisselkoers mist!',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Van',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Uitvoer inclusief',
+  'Invoice'                     => 'Factuur',
+  'Invoice Date'                => 'Factuurdatum',
+  'Invoice Date missing!'       => 'Factuurdatum mist!',
+  'Invoice Number'              => 'Factuurnummer',
+  'Invoice Number missing!'     => 'Factuurnummer mist!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mrt',
+  'March'                       => 'Maart',
+  'May'                         => 'Mei',
+  'May '                        => 'Mei',
+  'Notes'                       => 'Opmerkingen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Open'                        => 'Open',
+  'Order'                       => 'Bestelling',
+  'Order Number'                => 'Referentie',
+  'Paid'                        => 'Betaald',
+  'Payment date missing!'       => 'Geen betalingsdatum aanwezig!',
+  'Payments'                    => 'Betalingen',
+  'Post'                        => 'Boek',
+  'Post as new'                 => 'Boek als nieuw',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project bestaat niet!',
+  'Remaining'                   => 'Resterend',
+  'Sales Invoice'               => 'Verkoopfactuur',
+  'Select from one of the names below' => 'Kies een van de onderstaande namen',
+  'Select from one of the projects below' => 'Kies een van de onderstaande projecten',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Herkomst',
+  'Subtotal'                    => 'Subtotaal',
+  'Tax'                         => 'Belasting',
+  'Tax Included'                => 'Inclusief Belasting',
+  'Total'                       => 'Totaal',
+  'Transaction deleted!'        => 'Boeking verwijderd!',
+  'Transaction posted!'         => 'Boeking opgeslagen!',
+  'Update'                      => 'Bijwerken',
+  'Vendor not on file!'         => 'Leverancier bestaat niet!',
+  'Yes'                         => 'Ja',
+  'to'                          => 'tot',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'debiteurenboeking'           => 'ar_transaction',
+  'verder'                      => 'continue',
+  'verwijder'                   => 'delete',
+  'boek'                        => 'post',
+  'boek_als_nieuw'              => 'post_as_new',
+  'verkoopfactuur'              => 'sales_invoice',
+  'bijwerken'                   => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/arap b/sql-ledger/locale/nl/arap
new file mode 100644 (file)
index 0000000..70f1eb3
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Adres',
+  'Continue'                    => 'Verder',
+  'Customer not on file!'       => 'Klant bestaat niet!',
+  'Description'                 => 'Omschrijving',
+  'Number'                      => 'Nummer',
+  'Project not on file!'        => 'Project bestaat niet!',
+  'Select from one of the names below' => 'Kies een van de onderstaande namen',
+  'Select from one of the projects below' => 'Kies een van de onderstaande projecten',
+  'Vendor not on file!'         => 'Leverancier bestaat niet!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'verder'                      => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/ca b/sql-ledger/locale/nl/ca
new file mode 100644 (file)
index 0000000..aeb0fab
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Rekening',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Aug'                         => 'Aug',
+  'August'                      => 'Augustus',
+  'Balance'                     => 'Saldo',
+  'Chart of Accounts'           => 'Rekeningstelsel',
+  'Credit'                      => 'Credit',
+  'Date'                        => 'Datum',
+  'Debit'                       => 'Debet',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Description'                 => 'Omschrijving',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Van',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Uitvoer inclusief',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'List Transactions'           => 'Boekingen tonen',
+  'Mar'                         => 'Mrt',
+  'March'                       => 'Maart',
+  'May'                         => 'Mei',
+  'May '                        => 'Mei',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Reference'                   => 'Referentie',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Subtotal'                    => 'Subtotaal',
+  'to'                          => 'tot',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'boekingen_tonen'             => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/cp b/sql-ledger/locale/nl/cp
new file mode 100644 (file)
index 0000000..c1ae7d5
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Rekening',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Bedrag',
+  'Amount does not equal applied!' => 'Bedrag is ongelijk aan toewijzing!',
+  'Amount missing!'             => 'Bedrag ontbreekt!',
+  'Applied'                     => 'Toewijzing',
+  'Cannot post payment!'        => 'Kan betaling niet boeken!',
+  'Cannot process payment for a closed period!' => 'Kan geen betaling verwerken voor afgesloten periode!',
+  'Check'                       => 'Cheque',
+  'Check printed!'              => 'Cheque geprint!',
+  'Check printing failed!'      => 'Cheque printen mislukt!',
+  'Continue'                    => 'Verder',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Klant',
+  'Customer not on file!'       => 'Klant bestaat niet!',
+  'Date'                        => 'Datum',
+  'Date missing!'               => 'Datum ontbreekt!',
+  'Description'                 => 'Omschrijving',
+  'Due'                         => 'Verschuldigd',
+  'Exchangerate'                => 'Wisselkoers',
+  'From'                        => 'Van',
+  'Invoice'                     => 'Factuur',
+  'Invoices'                    => 'Facturen',
+  'Nothing applied!'            => 'Niets toegewezen!',
+  'Number'                      => 'Nummer',
+  'Paid in full'                => 'Volledig betaald',
+  'Payment'                     => 'Betaling',
+  'Payment posted!'             => 'Betaling geboekt!',
+  'Post'                        => 'Boek',
+  'Print'                       => 'Afdrukken',
+  'Printer'                     => 'Printer',
+  'Project not on file!'        => 'Project bestaat niet!',
+  'Receipt'                     => 'Ontvangstbewijs',
+  'Reference'                   => 'Referentie',
+  'Screen'                      => 'Scherm',
+  'Select from one of the names below' => 'Kies een van de onderstaande namen',
+  'Select from one of the projects below' => 'Kies een van de onderstaande projecten',
+  'Update'                      => 'Bijwerken',
+  'Vendor'                      => 'Leverancier',
+  'Vendor not on file!'         => 'Leverancier bestaat niet!',
+  'to'                          => 'tot',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'verder'                      => 'continue',
+  'boek'                        => 'post',
+  'afdrukken'                   => 'print',
+  'bijwerken'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/ct b/sql-ledger/locale/nl/ct
new file mode 100644 (file)
index 0000000..430053a
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Toevoegen',
+  'Address'                     => 'Adres',
+  'All'                         => 'Allemaal',
+  'Bcc'                         => 'Onzichtbare kopie aan',
+  'Cannot delete customer!'     => 'Kan klant niet verwijderen!',
+  'Cannot delete vendor!'       => 'Kan leverancier niet verwijderen!',
+  'Cc'                          => 'Copie aan',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Verder',
+  'Credit Limit'                => 'Kredietlimiet',
+  'Customer deleted!'           => 'Klant verwijderd!',
+  'Customer saved!'             => 'Klant opgeslagen!',
+  'Customers'                   => 'Klanten',
+  'Delete'                      => 'Verwijder',
+  'Discount'                    => 'Korting',
+  'E-mail'                      => 'E-mail',
+  'Edit Customer'               => 'Klant wijzigen',
+  'Edit Vendor'                 => 'Leverancier wijzigen',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Uitvoer inclusief',
+  'Invoice'                     => 'Factuur',
+  'Name'                        => 'Naam',
+  'Name missing!'               => 'Naam ontbreekt!',
+  'Notes'                       => 'Opmerkingen',
+  'Number'                      => 'Nummer',
+  'Order'                       => 'Bestelling',
+  'Orphaned'                    => 'Wees',
+  'Phone'                       => 'Tel.',
+  'Save'                        => 'Opslaan',
+  'Ship to'                     => 'Verzenden aan',
+  'Tax Included'                => 'Inclusief Belasting',
+  'Taxable'                     => 'Belastbaar percentage',
+  'Terms: Net'                  => 'Netto',
+  'Transactions exist, cannot delete customer!' => 'Kan klant niet verwijderen, er zijn onderliggende boekingen!',
+  'Transactions exist, cannot delete vendor!' => 'Kan leverancier niet verwijderen, er zijn onderliggende boekingen!',
+  'Vendor deleted!'             => 'Leverancier verwijderd!',
+  'Vendor saved!'               => 'Leverancier opgeslagen!',
+  'Vendors'                     => 'Leveranciers',
+  'days'                        => 'dagen',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'toevoegen'                   => 'add',
+  'verder'                      => 'continue',
+  'verwijder'                   => 'delete',
+  'factuur'                     => 'invoice',
+  'bestelling'                  => 'order',
+  'opslaan'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/gl b/sql-ledger/locale/nl/gl
new file mode 100644 (file)
index 0000000..9e76622
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Crediteurenboeking',
+  'AR Transaction'              => 'Debiteurenboeking',
+  'Account'                     => 'Rekening',
+  'Add General Ledger Transaction' => 'Journaalpost toevoegen',
+  'Address'                     => 'Adres',
+  'All'                         => 'Allemaal',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Transaction' => 'Weet u zeker dat u deze boeking wilt verwijderen?',
+  'Asset'                       => 'Activa (bezittingen)',
+  'Aug'                         => 'Aug',
+  'August'                      => 'Augustus',
+  'Balance'                     => 'Saldo',
+  'Cannot delete transaction!'  => 'Kan transactie niet verwijderen!',
+  'Cannot have a value in both Debit and Credit!' => 'Waarde kan alleen debet of credit voorkomen!',
+  'Cannot post a transaction without a value!' => 'Kan geen boeking maken zonder waarde!',
+  'Cannot post transaction for a closed period!' => 'Kan geen boeking maken in afgesloten periode',
+  'Confirm!'                    => 'Bevestig!',
+  'Continue'                    => 'Verder',
+  'Credit'                      => 'Credit',
+  'Customer not on file!'       => 'Klant bestaat niet!',
+  'Date'                        => 'Datum',
+  'Debit'                       => 'Debet',
+  'Debit and credit out of balance!' => 'Debet en credit moeten gelijk zijn!',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Verwijder',
+  'Description'                 => 'Omschrijving',
+  'Edit General Ledger Transaction' => 'Boeking in grootboek wijzigen',
+  'Equity'                      => 'Passiva/Eigen Vermogen',
+  'Expense'                     => 'Onkosten',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Van',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'Grootboekboeking (memoriaal) ',
+  'General Ledger'              => 'Grootboek',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Uitvoer inclusief',
+  'Income'                      => 'Inkomsten',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Liability'                   => 'Passiva',
+  'Mar'                         => 'Mrt',
+  'March'                       => 'Maart',
+  'May'                         => 'Mei',
+  'May '                        => 'Mei',
+  'Notes'                       => 'Opmerkingen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Post'                        => 'Boek',
+  'Post as new'                 => 'Boek als nieuw',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project bestaat niet!',
+  'Purchase Invoice'            => 'Inkoopfactuur',
+  'Reference'                   => 'Referentie',
+  'Reference missing!'          => 'Referentie ontbreekt!',
+  'Reports'                     => 'Rapporten',
+  'Sales Invoice'               => 'Verkoopfactuur',
+  'Select from one of the names below' => 'Kies een van de onderstaande namen',
+  'Select from one of the projects below' => 'Kies een van de onderstaande projecten',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Herkomst',
+  'Subtotal'                    => 'Subtotaal',
+  'Transaction Date missing!'   => 'Boekingsdatum mist!',
+  'Transaction deleted!'        => 'Boeking verwijderd!',
+  'Transaction posted!'         => 'Boeking opgeslagen!',
+  'Update'                      => 'Bijwerken',
+  'Vendor not on file!'         => 'Leverancier bestaat niet!',
+  'Yes'                         => 'Ja',
+  'to'                          => 'tot',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'crediteurenboeking'          => 'ap_transaction',
+  'debiteurenboeking'           => 'ar_transaction',
+  'verder'                      => 'continue',
+  'verwijder'                   => 'delete',
+  'grootboekboeking_(memoriaal)_' => 'gl_transaction',
+  'boek'                        => 'post',
+  'boek_als_nieuw'              => 'post_as_new',
+  'inkoopfactuur'               => 'purchase_invoice',
+  'verkoopfactuur'              => 'sales_invoice',
+  'bijwerken'                   => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/ic b/sql-ledger/locale/nl/ic
new file mode 100644 (file)
index 0000000..e8d7eea
--- /dev/null
@@ -0,0 +1,206 @@
+$self{texts} = {
+  'Active'                      => 'Actief',
+  'Add'                         => 'Toevoegen',
+  'Add Assembly'                => 'Assemblage toevoegen',
+  'Add Part'                    => 'Artikel toevoegen',
+  'Add Purchase Order'          => 'Inkooporder toevoegen',
+  'Add Sales Order'             => 'Verkooporder toevoegen',
+  'Add Service'                 => 'Dienst toevoegen',
+  'Address'                     => 'Adres',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Assemblies'                  => 'Assemblage, samengestelde artikelen',
+  'Assemblies restocked!'       => 'Assemblage naar voorraad geboekt',
+  'Assembly Number missing!'    => 'Assemblagenummer mist!',
+  'Attachment'                  => 'Bijlage',
+  'Aug'                         => 'Aug',
+  'August'                      => 'Augustus',
+  'BOM'                         => 'Onderdelenlijst',
+  'Bcc'                         => 'Onzichtbare kopie aan',
+  'Bin'                         => 'Locatie',
+  'Bought'                      => 'Ingekocht',
+  'COGS'                        => 'Kostprijs Verkopen',
+  'Cannot delete item already invoiced!' => 'Kan reeds gefactureerd artikel niet verwijderen!',
+  'Cannot delete item on order!' => 'Kan onderdeel van de order niet verwijderen',
+  'Cannot delete item which is part of an assembly!' => 'Kan onderdeel van een samengesteld artikel niet verwijderen!',
+  'Cannot delete item!'         => 'Kan onderdeel niet verwijderen!',
+  'Cannot stock assemblies!'    => 'Kan assemblages niet in voorraad nemen!',
+  'Cc'                          => 'Copie aan',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Verder',
+  'Copies'                      => 'Kopieën',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Verwijder',
+  'Delivery Date'               => 'Leverdatum',
+  'Description'                 => 'Omschrijving',
+  'Drawing'                     => 'Tekening',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mailadres mist!',
+  'Edit Assembly'               => 'Assemblage wijzigen',
+  'Edit Part'                   => 'Artikel wijzigen',
+  'Edit Service'                => 'Dienst wijzigen',
+  'Expense'                     => 'Onkosten',
+  'Extended'                    => 'Uitgebreid',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Van',
+  'Image'                       => 'Plaatje',
+  'In-line'                     => 'In Lijn',
+  'Include in Report'           => 'Uitvoer inclusief',
+  'Income'                      => 'Inkomsten',
+  'Individual Items'            => 'Onderliggede onderdelen',
+  'Inventory'                   => 'Voorraad',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Aanwezige voorraad moet nul zijn voordat een assemblage als \'niet actief\' kan worder gemarkeerd.',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Aanwezige voorraad moet nul zijn voordat een product als \'niet actief\' kan worder gemarkeerd.',
+  'Inventory quantity must be zero!' => 'Aanwezige voorraad moet nul zijn!',
+  'Invoice'                     => 'Factuur',
+  'Invoice Date missing!'       => 'Factuurdatum mist!',
+  'Invoice Number'              => 'Factuurnummer',
+  'Invoice Number missing!'     => 'Factuurnummer mist!',
+  'Item deleted!'               => 'Onderdeel verwijderd!',
+  'Item not on file!'           => 'Dit onderdeel is niet in de database gevonden!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Last Cost'                   => 'Vorige kostprijs',
+  'Line Total'                  => 'Totaal Regel',
+  'Link Accounts'               => 'Rekeningen verbinden',
+  'List Price'                  => 'Prijzen weergeven',
+  'Make'                        => 'Fabrikant',
+  'Mar'                         => 'Mrt',
+  'March'                       => 'Maart',
+  'May'                         => 'Mei',
+  'May '                        => 'Mei',
+  'Message'                     => 'Boodschap',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Type',
+  'Name'                        => 'Naam',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Opmerkingen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Getal missend in regel',
+  'Obsolete'                    => 'Niet actief',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'On Hand'                     => 'Op voorraad',
+  'On Order'                    => 'In bestelling',
+  'Order'                       => 'Bestelling',
+  'Order Date missing!'         => 'Geen order datum aanwezig',
+  'Order Number'                => 'Referentie',
+  'Order Number missing!'       => 'Geen ordernummer aanwezig',
+  'Ordered'                     => 'Besteld',
+  'Orphaned'                    => 'Wees',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Pakbon',
+  'Packing List Date missing!'  => 'Pakbon datum mist!',
+  'Packing List Number missing!' => 'Pakbon nummer mist!',
+  'Part'                        => 'Artikel',
+  'Part Number missing!'        => 'Artikelnummer mist!',
+  'Parts'                       => 'Artikelen',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Prijs',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Inkooporder',
+  'Qty'                         => 'Aantal',
+  'ROP'                         => 'Minimum voorraad',
+  'Recd'                        => 'Ontvangen',
+  'Required by'                 => 'Nodig voor',
+  'Sales'                       => 'Verkoop',
+  'Sales Order'                 => 'Verkooporder',
+  'Save'                        => 'Opslaan',
+  'Screen'                      => 'Scherm',
+  'Select from one of the items below' => 'Kies een van de onderstaande items',
+  'Select postscript or PDF!'   => 'Kies postscript of PDF',
+  'Sell Price'                  => 'Verkoopprijs',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Dienst',
+  'Service Number missing!'     => 'Dienstnummer mist',
+  'Services'                    => 'Diensten',
+  'Ship'                        => 'Verzenden',
+  'Ship to'                     => 'Verzenden aan',
+  'Short'                       => 'Kort',
+  'Sold'                        => 'Verkocht',
+  'Stock Assembly'              => 'Assemblage voorraad',
+  'Subject'                     => 'Onderwerp',
+  'Subtotal'                    => 'Subtotaal',
+  'Tax'                         => 'Belasting',
+  'To'                          => 'Tot',
+  'Top Level'                   => 'Top Niveau',
+  'Total'                       => 'Totaal',
+  'Unit'                        => 'Eenheid',
+  'Unit of measure'             => 'Rekeneenheid',
+  'Update'                      => 'Bijwerken',
+  'Updated'                     => 'Bijgewerkt',
+  'Weight'                      => 'Gewicht',
+  'What type of item is this?'  => 'Wat voor soort artikel is dit?',
+  'ea'                          => 'voor',
+  'emailed to'                  => 'per email verzonden aan',
+  'hr'                          => 'uur',
+  'sent to printer'             => 'Afgedrukt',
+  'to'                          => 'tot',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'toevoegen'                   => 'add',
+  'assemblage_toevoegen'        => 'add_assembly',
+  'artikel_toevoegen'           => 'add_part',
+  'dienst_toevoegen'            => 'add_service',
+  'verder'                      => 'continue',
+  'verwijder'                   => 'delete',
+  'assemblage_wijzigen'         => 'edit_assembly',
+  'artikel_wijzigen'            => 'edit_part',
+  'dienst_wijzigen'             => 'edit_service',
+  'opslaan'                     => 'save',
+  'bijwerken'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/io b/sql-ledger/locale/nl/io
new file mode 100644 (file)
index 0000000..432a8e0
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Inkooporder toevoegen',
+  'Add Sales Order'             => 'Verkooporder toevoegen',
+  'Address'                     => 'Adres',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Attachment'                  => 'Bijlage',
+  'Aug'                         => 'Aug',
+  'August'                      => 'Augustus',
+  'Bcc'                         => 'Onzichtbare kopie aan',
+  'Bin'                         => 'Locatie',
+  'Cc'                          => 'Copie aan',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Verder',
+  'Copies'                      => 'Kopieën',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delivery Date'               => 'Leverdatum',
+  'Description'                 => 'Omschrijving',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mailadres mist!',
+  'Extended'                    => 'Uitgebreid',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'In-line'                     => 'In Lijn',
+  'Invoice'                     => 'Factuur',
+  'Invoice Date missing!'       => 'Factuurdatum mist!',
+  'Invoice Number missing!'     => 'Factuurnummer mist!',
+  'Item not on file!'           => 'Dit onderdeel is niet in de database gevonden!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mrt',
+  'March'                       => 'Maart',
+  'May'                         => 'Mei',
+  'May '                        => 'Mei',
+  'Message'                     => 'Boodschap',
+  'Name'                        => 'Naam',
+  'No.'                         => 'Nr.',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Getal missend in regel',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Order'                       => 'Bestelling',
+  'Order Date missing!'         => 'Geen order datum aanwezig',
+  'Order Number missing!'       => 'Geen ordernummer aanwezig',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Pakbon',
+  'Packing List Date missing!'  => 'Pakbon datum mist!',
+  'Packing List Number missing!' => 'Pakbon nummer mist!',
+  'Part'                        => 'Artikel',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Prijs',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Inkooporder',
+  'Qty'                         => 'Aantal',
+  'Recd'                        => 'Ontvangen',
+  'Required by'                 => 'Nodig voor',
+  'Sales Order'                 => 'Verkooporder',
+  'Screen'                      => 'Scherm',
+  'Select from one of the items below' => 'Kies een van de onderstaande items',
+  'Select postscript or PDF!'   => 'Kies postscript of PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Dienst',
+  'Ship'                        => 'Verzenden',
+  'Ship to'                     => 'Verzenden aan',
+  'Subject'                     => 'Onderwerp',
+  'To'                          => 'Tot',
+  'Unit'                        => 'Eenheid',
+  'What type of item is this?'  => 'Wat voor soort artikel is dit?',
+  'emailed to'                  => 'per email verzonden aan',
+  'sent to printer'             => 'Afgedrukt',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'verder'                      => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/ir b/sql-ledger/locale/nl/ir
new file mode 100644 (file)
index 0000000..235a7d4
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Rekening',
+  'Add Purchase Invoice'        => 'Inkoopfactuur toevoegen',
+  'Add Purchase Order'          => 'Inkooporder toevoegen',
+  'Add Sales Order'             => 'Verkooporder toevoegen',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Bedrag',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Invoice Number' => 'Weet u zeker dat u dit factuurnummer wilt verwijderen?',
+  'Attachment'                  => 'Bijlage',
+  'Aug'                         => 'Aug',
+  'August'                      => 'Augustus',
+  'Bcc'                         => 'Onzichtbare kopie aan',
+  'Bin'                         => 'Locatie',
+  'Cannot delete invoice!'      => 'Kan factuur niet verwijderen!',
+  'Cannot post invoice for a closed period!' => 'Kan geen factuur boeken in afgesloten periode!',
+  'Cannot post invoice!'        => 'Kan factuur niet boeken!',
+  'Cannot post payment for a closed period!' => 'Kan geen betaling boeken voor afgesloten periode!',
+  'Cc'                          => 'Copie aan',
+  'Confirm!'                    => 'Bevestig!',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Verder',
+  'Copies'                      => 'Kopieën',
+  'Currency'                    => 'Valuta',
+  'Customer not on file!'       => 'Klant bestaat niet!',
+  'Date'                        => 'Datum',
+  'Date Due'                    => 'Vervaldatum',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Verwijder',
+  'Delivery Date'               => 'Leverdatum',
+  'Description'                 => 'Omschrijving',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mailadres mist!',
+  'Edit Purchase Invoice'       => 'Inkoopfactuur wijzigen',
+  'Exch'                        => 'Wisselkoers',
+  'Exchangerate'                => 'Wisselkoers',
+  'Exchangerate for payment missing!' => 'Wisselkoers voor Betaling mist!',
+  'Exchangerate missing!'       => 'Wisselkoers mist!',
+  'Extended'                    => 'Uitgebreid',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'In-line'                     => 'In Lijn',
+  'Invoice'                     => 'Factuur',
+  'Invoice Date'                => 'Factuurdatum',
+  'Invoice Date missing!'       => 'Factuurdatum mist!',
+  'Invoice Number'              => 'Factuurnummer',
+  'Invoice Number missing!'     => 'Factuurnummer mist!',
+  'Invoice deleted!'            => 'Factuur verwijderd!',
+  'Invoice posted!'             => 'Factuur geboekt!',
+  'Item not on file!'           => 'Dit onderdeel is niet in de database gevonden!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mrt',
+  'March'                       => 'Maart',
+  'May'                         => 'Mei',
+  'May '                        => 'Mei',
+  'Message'                     => 'Boodschap',
+  'Name'                        => 'Naam',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Opmerkingen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Getal missend in regel',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Order'                       => 'Bestelling',
+  'Order Date missing!'         => 'Geen order datum aanwezig',
+  'Order Number'                => 'Referentie',
+  'Order Number missing!'       => 'Geen ordernummer aanwezig',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Pakbon',
+  'Packing List Date missing!'  => 'Pakbon datum mist!',
+  'Packing List Number missing!' => 'Pakbon nummer mist!',
+  'Part'                        => 'Artikel',
+  'Payment date missing!'       => 'Geen betalingsdatum aanwezig!',
+  'Payments'                    => 'Betalingen',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Boek',
+  'Post as new'                 => 'Boek als nieuw',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Prijs',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project bestaat niet!',
+  'Purchase Order'              => 'Inkooporder',
+  'Qty'                         => 'Aantal',
+  'Recd'                        => 'Ontvangen',
+  'Record in'                   => 'Boeken op',
+  'Required by'                 => 'Nodig voor',
+  'Sales Order'                 => 'Verkooporder',
+  'Screen'                      => 'Scherm',
+  'Select from one of the items below' => 'Kies een van de onderstaande items',
+  'Select from one of the names below' => 'Kies een van de onderstaande namen',
+  'Select from one of the projects below' => 'Kies een van de onderstaande projecten',
+  'Select postscript or PDF!'   => 'Kies postscript of PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Dienst',
+  'Ship'                        => 'Verzenden',
+  'Ship to'                     => 'Verzenden aan',
+  'Source'                      => 'Herkomst',
+  'Subject'                     => 'Onderwerp',
+  'Subtotal'                    => 'Subtotaal',
+  'Tax Included'                => 'Inclusief Belasting',
+  'To'                          => 'Tot',
+  'Total'                       => 'Totaal',
+  'Unit'                        => 'Eenheid',
+  'Update'                      => 'Bijwerken',
+  'Vendor'                      => 'Leverancier',
+  'Vendor missing!'             => 'Leverancier ontbreekt!',
+  'Vendor not on file!'         => 'Leverancier bestaat niet!',
+  'What type of item is this?'  => 'Wat voor soort artikel is dit?',
+  'Yes'                         => 'Ja',
+  'ea'                          => 'voor',
+  'emailed to'                  => 'per email verzonden aan',
+  'sent to printer'             => 'Afgedrukt',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'verder'                      => 'continue',
+  'verwijder'                   => 'delete',
+  'bestelling'                  => 'order',
+  'boek'                        => 'post',
+  'boek_als_nieuw'              => 'post_as_new',
+  'bijwerken'                   => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/is b/sql-ledger/locale/nl/is
new file mode 100644 (file)
index 0000000..f868dac
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Rekening',
+  'Add Purchase Order'          => 'Inkooporder toevoegen',
+  'Add Sales Invoice'           => 'Verkoopfactuur toevoegen',
+  'Add Sales Order'             => 'Verkooporder toevoegen',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Bedrag',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Invoice Number' => 'Weet u zeker dat u dit factuurnummer wilt verwijderen?',
+  'Attachment'                  => 'Bijlage',
+  'Aug'                         => 'Aug',
+  'August'                      => 'Augustus',
+  'Bcc'                         => 'Onzichtbare kopie aan',
+  'Bin'                         => 'Locatie',
+  'Cannot delete invoice!'      => 'Kan factuur niet verwijderen!',
+  'Cannot post invoice for a closed period!' => 'Kan geen factuur boeken in afgesloten periode!',
+  'Cannot post invoice!'        => 'Kan factuur niet boeken!',
+  'Cannot post payment for a closed period!' => 'Kan geen betaling boeken voor afgesloten periode!',
+  'Cc'                          => 'Copie aan',
+  'Confirm!'                    => 'Bevestig!',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Verder',
+  'Copies'                      => 'Kopieën',
+  'Credit Limit'                => 'Kredietlimiet',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Klant',
+  'Customer missing!'           => 'Klant ontbreekt!',
+  'Customer not on file!'       => 'Klant bestaat niet!',
+  'Date'                        => 'Datum',
+  'Date Due'                    => 'Vervaldatum',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Verwijder',
+  'Delivery Date'               => 'Leverdatum',
+  'Description'                 => 'Omschrijving',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mailadres mist!',
+  'Edit Sales Invoice'          => 'Verkoopfactuur wijzigen',
+  'Exch'                        => 'Wisselkoers',
+  'Exchangerate'                => 'Wisselkoers',
+  'Exchangerate for payment missing!' => 'Wisselkoers voor Betaling mist!',
+  'Exchangerate missing!'       => 'Wisselkoers mist!',
+  'Extended'                    => 'Uitgebreid',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'In-line'                     => 'In Lijn',
+  'Invoice'                     => 'Factuur',
+  'Invoice Date'                => 'Factuurdatum',
+  'Invoice Date missing!'       => 'Factuurdatum mist!',
+  'Invoice Number'              => 'Factuurnummer',
+  'Invoice Number missing!'     => 'Factuurnummer mist!',
+  'Invoice deleted!'            => 'Factuur verwijderd!',
+  'Invoice posted!'             => 'Factuur geboekt!',
+  'Item not on file!'           => 'Dit onderdeel is niet in de database gevonden!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mrt',
+  'March'                       => 'Maart',
+  'May'                         => 'Mei',
+  'May '                        => 'Mei',
+  'Message'                     => 'Boodschap',
+  'Name'                        => 'Naam',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Opmerkingen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Getal missend in regel',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Order'                       => 'Bestelling',
+  'Order Date missing!'         => 'Geen order datum aanwezig',
+  'Order Number'                => 'Referentie',
+  'Order Number missing!'       => 'Geen ordernummer aanwezig',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Pakbon',
+  'Packing List Date missing!'  => 'Pakbon datum mist!',
+  'Packing List Number missing!' => 'Pakbon nummer mist!',
+  'Part'                        => 'Artikel',
+  'Payment date missing!'       => 'Geen betalingsdatum aanwezig!',
+  'Payments'                    => 'Betalingen',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Boek',
+  'Post as new'                 => 'Boek als nieuw',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Prijs',
+  'Print'                       => 'Afdrukken',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project bestaat niet!',
+  'Purchase Order'              => 'Inkooporder',
+  'Qty'                         => 'Aantal',
+  'Recd'                        => 'Ontvangen',
+  'Record in'                   => 'Boeken op',
+  'Remaining'                   => 'Resterend',
+  'Required by'                 => 'Nodig voor',
+  'Sales Order'                 => 'Verkooporder',
+  'Screen'                      => 'Scherm',
+  'Select from one of the items below' => 'Kies een van de onderstaande items',
+  'Select from one of the names below' => 'Kies een van de onderstaande namen',
+  'Select from one of the projects below' => 'Kies een van de onderstaande projecten',
+  'Select postscript or PDF!'   => 'Kies postscript of PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Dienst',
+  'Ship'                        => 'Verzenden',
+  'Ship to'                     => 'Verzenden aan',
+  'Ship via'                    => 'Verzenden via',
+  'Source'                      => 'Herkomst',
+  'Subject'                     => 'Onderwerp',
+  'Subtotal'                    => 'Subtotaal',
+  'Tax Included'                => 'Inclusief Belasting',
+  'To'                          => 'Tot',
+  'Total'                       => 'Totaal',
+  'Unit'                        => 'Eenheid',
+  'Update'                      => 'Bijwerken',
+  'Vendor not on file!'         => 'Leverancier bestaat niet!',
+  'What type of item is this?'  => 'Wat voor soort artikel is dit?',
+  'Yes'                         => 'Ja',
+  'ea'                          => 'voor',
+  'emailed to'                  => 'per email verzonden aan',
+  'sent to printer'             => 'Afgedrukt',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'verder'                      => 'continue',
+  'verwijder'                   => 'delete',
+  'e_mail'                      => 'e_mail',
+  'bestelling'                  => 'order',
+  'boek'                        => 'post',
+  'boek_als_nieuw'              => 'post_as_new',
+  'afdrukken'                   => 'print',
+  'verzenden_aan'               => 'ship_to',
+  'bijwerken'                   => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/login b/sql-ledger/locale/nl/login
new file mode 100644 (file)
index 0000000..4e01eb0
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'Over',
+  'Database Host'               => 'Database computer',
+  'Dataset'                     => 'Dataset',
+  'Incorrect Dataset version!'  => 'Ongeldige versie Dataset!!',
+  'Incorrect Password!'         => 'Verkeerd paswoord',
+  'Licensed to'                 => 'Gelicenseerd aan',
+  'Login'                       => 'Login',
+  'Name'                        => 'Naam',
+  'Password'                    => 'Wachtwoord',
+  'User'                        => 'Gebruiker',
+  'Version'                     => 'Versie',
+  'You are logged out!'         => 'U bent uitgelogd!',
+  'You did not enter a name!'   => 'U heeft geen naam gegeven!',
+  'is not a member!'            => 'is geen gebruiker',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'login'                       => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/menu b/sql-ledger/locale/nl/menu
new file mode 100644 (file)
index 0000000..2c1a257
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => 'Crediteuren',
+  'AP Aging'                    => 'Crediteuren Ouderdomsoverzicht',
+  'AR'                          => 'Debiteuren',
+  'AR Aging'                    => 'Debiteuren Ouderdomsoverzicht',
+  'Accounting Menu'             => 'Boekhoudmenu',
+  'Add Account'                 => 'Rekening toevoegen',
+  'Add Assembly'                => 'Assemblage toevoegen',
+  'Add Customer'                => 'Klant toevoegen',
+  'Add GIFI'                    => 'Toevoegen GIFI',
+  'Add Part'                    => 'Artikel toevoegen',
+  'Add Project'                 => 'Project toevoegen',
+  'Add Service'                 => 'Dienst toevoegen',
+  'Add Transaction'             => 'Boeking toevoegen',
+  'Add Vendor'                  => 'Leverancier toevoegen',
+  'Assemblies'                  => 'Assemblage, samengestelde artikelen',
+  'Audit Control'               => 'Accountants Controle',
+  'Backup'                      => 'Backup',
+  'Balance Sheet'               => 'Balans',
+  'Cash'                        => 'Kas (contant)',
+  'Chart of Accounts'           => 'Rekeningstelsel',
+  'Check'                       => 'Cheque',
+  'Customers'                   => 'Klanten',
+  'General Ledger'              => 'Grootboek',
+  'Goods & Services'            => 'Goederen & Diensten',
+  'HTML Templates'              => 'HTML Sjablonen',
+  'Income Statement'            => 'Inkomstenoverzicht',
+  'Invoice'                     => 'Factuur',
+  'LaTeX Templates'             => 'Latex Sjablonen',
+  'List Accounts'               => 'Rekeningen weergeven',
+  'List GIFI'                   => 'GIFI weergeven',
+  'Logout'                      => 'Logout',
+  'Order Entry'                 => 'Order invoer',
+  'Packing List'                => 'Pakbon',
+  'Parts'                       => 'Artikelen',
+  'Payment'                     => 'Betaling',
+  'Payments'                    => 'Betalingen',
+  'Preferences'                 => 'Instellingen',
+  'Projects'                    => 'Projecten',
+  'Purchase Invoice'            => 'Inkoopfactuur',
+  'Purchase Order'              => 'Inkooporder',
+  'Purchase Orders'             => 'Inkooporders',
+  'Receipt'                     => 'Ontvangstbewijs',
+  'Receipts'                    => 'Ontvangstbewijzen',
+  'Reconciliation'              => 'Bank Overzicht',
+  'Reports'                     => 'Rapporten',
+  'Sales Invoice'               => 'Verkoopfactuur',
+  'Sales Order'                 => 'Verkooporder',
+  'Sales Orders'                => 'Verkooporders',
+  'Save to File'                => 'Opslaan als bestand',
+  'Send by E-Mail'              => 'Verzenden per E-mail',
+  'Services'                    => 'Diensten',
+  'Statement'                   => 'Overzicht',
+  'Stock Assembly'              => 'Assemblage voorraad',
+  'Stylesheet'                  => 'Stylesheet',
+  'System'                      => 'Systeem',
+  'Tax collected'               => 'Belasting verschuldigd',
+  'Tax paid'                    => 'Belasting Betaald',
+  'Transactions'                => 'Boekingen',
+  'Trial Balance'               => 'Proefbalans',
+  'Vendors'                     => 'Leveranciers',
+  'Version'                     => 'Versie',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/oe b/sql-ledger/locale/nl/oe
new file mode 100644 (file)
index 0000000..cf3a062
--- /dev/null
@@ -0,0 +1,200 @@
+$self{texts} = {
+  'Add'                         => 'Toevoegen',
+  'Add Purchase Invoice'        => 'Inkoopfactuur toevoegen',
+  'Add Purchase Order'          => 'Inkooporder toevoegen',
+  'Add Sales Invoice'           => 'Verkoopfactuur toevoegen',
+  'Add Sales Order'             => 'Verkooporder toevoegen',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Bedrag',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Are you sure you want to delete Order Number' => 'Weet u zeker dat u dit ordernummer wilt verwijderen?',
+  'Attachment'                  => 'Bijlage',
+  'Aug'                         => 'Aug',
+  'August'                      => 'Augustus',
+  'Bcc'                         => 'Onzichtbare kopie aan',
+  'Bin'                         => 'Locatie',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Kan order niet verwijderen!',
+  'Cannot save order!'          => 'Kan order niet opslaan!',
+  'Cc'                          => 'Copie aan',
+  'Closed'                      => 'Afgesloten',
+  'Confirm!'                    => 'Bevestig!',
+  'Contact'                     => 'Contact',
+  'Continue'                    => 'Verder',
+  'Copies'                      => 'Kopieën',
+  'Credit Limit'                => 'Kredietlimiet',
+  'Curr'                        => 'Val.',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Klant',
+  'Customer missing!'           => 'Klant ontbreekt!',
+  'Customer not on file!'       => 'Klant bestaat niet!',
+  'Date'                        => 'Datum',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Delete'                      => 'Verwijder',
+  'Delivery Date'               => 'Leverdatum',
+  'Description'                 => 'Omschrijving',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'E-mailadres mist!',
+  'Edit Purchase Order'         => 'Inkooporder wijzigen',
+  'Edit Sales Order'            => 'Verkoop order wijzigen',
+  'Exchangerate'                => 'Wisselkoers',
+  'Exchangerate missing!'       => 'Wisselkoers mist!',
+  'Extended'                    => 'Uitgebreid',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Van',
+  'ID'                          => 'ID',
+  'In-line'                     => 'In Lijn',
+  'Include in Report'           => 'Uitvoer inclusief',
+  'Invoice'                     => 'Factuur',
+  'Invoice Date missing!'       => 'Factuurdatum mist!',
+  'Invoice Number missing!'     => 'Factuurnummer mist!',
+  'Item not on file!'           => 'Dit onderdeel is niet in de database gevonden!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mrt',
+  'March'                       => 'Maart',
+  'May'                         => 'Mei',
+  'May '                        => 'Mei',
+  'Message'                     => 'Boodschap',
+  'Name'                        => 'Naam',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Opmerkingen',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Getal missend in regel',
+  'O'                           => 'O',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Open'                        => 'Open',
+  'Order'                       => 'Bestelling',
+  'Order Date'                  => 'Orderdatum',
+  'Order Date missing!'         => 'Geen order datum aanwezig',
+  'Order Number'                => 'Referentie',
+  'Order Number missing!'       => 'Geen ordernummer aanwezig',
+  'Order deleted!'              => 'Order verwijderd!',
+  'Order saved!'                => 'Order opgeslagen!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Pakbon',
+  'Packing List Date missing!'  => 'Pakbon datum mist!',
+  'Packing List Number missing!' => 'Pakbon nummer mist!',
+  'Part'                        => 'Artikel',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Prijs',
+  'Print'                       => 'Afdrukken',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project bestaat niet!',
+  'Purchase Order'              => 'Inkooporder',
+  'Purchase Orders'             => 'Inkooporders',
+  'Qty'                         => 'Aantal',
+  'Recd'                        => 'Ontvangen',
+  'Remaining'                   => 'Resterend',
+  'Required by'                 => 'Nodig voor',
+  'Sales Order'                 => 'Verkooporder',
+  'Sales Orders'                => 'Verkooporders',
+  'Save'                        => 'Opslaan',
+  'Save as new'                 => 'Opslaan als nieuw',
+  'Screen'                      => 'Scherm',
+  'Select from one of the items below' => 'Kies een van de onderstaande items',
+  'Select from one of the names below' => 'Kies een van de onderstaande namen',
+  'Select from one of the projects below' => 'Kies een van de onderstaande projecten',
+  'Select postscript or PDF!'   => 'Kies postscript of PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Dienst',
+  'Ship'                        => 'Verzenden',
+  'Ship to'                     => 'Verzenden aan',
+  'Ship via'                    => 'Verzenden via',
+  'Subject'                     => 'Onderwerp',
+  'Subtotal'                    => 'Subtotaal',
+  'Tax'                         => 'Belasting',
+  'Tax Included'                => 'Inclusief Belasting',
+  'Terms: Net'                  => 'Netto',
+  'To'                          => 'Tot',
+  'Total'                       => 'Totaal',
+  'Unit'                        => 'Eenheid',
+  'Update'                      => 'Bijwerken',
+  'Vendor'                      => 'Leverancier',
+  'Vendor missing!'             => 'Leverancier ontbreekt!',
+  'Vendor not on file!'         => 'Leverancier bestaat niet!',
+  'What type of item is this?'  => 'Wat voor soort artikel is dit?',
+  'Yes'                         => 'Ja',
+  'days'                        => 'dagen',
+  'ea'                          => 'voor',
+  'emailed to'                  => 'per email verzonden aan',
+  'sent to printer'             => 'Afgedrukt',
+  'to'                          => 'tot',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'toevoegen'                   => 'add',
+  'verder'                      => 'continue',
+  'verwijder'                   => 'delete',
+  'e_mail'                      => 'e_mail',
+  'factuur'                     => 'invoice',
+  'afdrukken'                   => 'print',
+  'opslaan'                     => 'save',
+  'opslaan_als_nieuw'           => 'save_as_new',
+  'verzenden_aan'               => 'ship_to',
+  'bijwerken'                   => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/pe b/sql-ledger/locale/nl/pe
new file mode 100644 (file)
index 0000000..bf05662
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Toevoegen',
+  'Add Project'                 => 'Project toevoegen',
+  'All'                         => 'Allemaal',
+  'Continue'                    => 'Verder',
+  'Delete'                      => 'Verwijder',
+  'Description'                 => 'Omschrijving',
+  'Edit Project'                => 'Project wijzigen',
+  'Number'                      => 'Nummer',
+  'Orphaned'                    => 'Wees',
+  'Project'                     => 'Project',
+  'Project Number missing!'     => 'Projectnummer ontbreekt!',
+  'Project deleted!'            => 'Project verwijderd!',
+  'Project saved!'              => 'Project opgeslagen!',
+  'Projects'                    => 'Projecten',
+  'Save'                        => 'Opslaan',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'toevoegen'                   => 'add',
+  'verder'                      => 'continue',
+  'verwijder'                   => 'delete',
+  'opslaan'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/rc b/sql-ledger/locale/nl/rc
new file mode 100644 (file)
index 0000000..d86b58e
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Rekening',
+  'Balance'                     => 'Saldo',
+  'Cleared Balance'             => 'Totaal geboekt vorige afschriften',
+  'Continue'                    => 'Verder',
+  'Date'                        => 'Datum',
+  'Deposit'                     => 'Storting',
+  'Description'                 => 'Omschrijving',
+  'Difference'                  => 'Verschil',
+  'Done'                        => 'Klaar',
+  'Exchangerate Difference'     => 'Koersverschil',
+  'From'                        => 'Van',
+  'Out of balance!'             => 'Niet in evenwicht!',
+  'Payment'                     => 'Betaling',
+  'Reconciliation'              => 'Bank Overzicht',
+  'Select all'                  => 'Selecteer alles',
+  'Source'                      => 'Herkomst',
+  'Statement Balance'           => 'Saldo Overzicht',
+  'Update'                      => 'Bijwerken',
+  'to'                          => 'tot',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'verder'                      => 'continue',
+  'klaar'                       => 'done',
+  'selecteer_alles'             => 'select_all',
+  'bijwerken'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/nl/rp b/sql-ledger/locale/nl/rp
new file mode 100644 (file)
index 0000000..9061318
--- /dev/null
@@ -0,0 +1,116 @@
+$self{texts} = {
+  'AP Aging'                    => 'Crediteuren Ouderdomsoverzicht',
+  'AR Aging'                    => 'Debiteuren Ouderdomsoverzicht',
+  'Account'                     => 'Rekening',
+  'Accounts'                    => 'Rekeningen',
+  'Amount'                      => 'Bedrag',
+  'Apr'                         => 'Apr',
+  'April'                       => 'April',
+  'Attachment'                  => 'Bijlage',
+  'Aug'                         => 'Aug',
+  'August'                      => 'Augustus',
+  'Balance Sheet'               => 'Balans',
+  'Bcc'                         => 'Onzichtbare kopie aan',
+  'Cash based'                  => 'Kasbasis (contante verkopen)',
+  'Cc'                          => 'Copie aan',
+  'Compare to'                  => 'Vergelijk met',
+  'Continue'                    => 'Verder',
+  'Copies'                      => 'Kopieën',
+  'Credit'                      => 'Credit',
+  'Current'                     => 'Huidig',
+  'Customer'                    => 'Klant',
+  'Date'                        => 'Datum',
+  'Debit'                       => 'Debet',
+  'Dec'                         => 'Dec',
+  'December'                    => 'December',
+  'Decimalplaces'               => 'Aantal Decimalen',
+  'Description'                 => 'Omschrijving',
+  'Due'                         => 'Verschuldigd',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'E-mail Overzicht aan',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Van',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Kopregel',
+  'ID'                          => 'ID',
+  'In-line'                     => 'In Lijn',
+  'Include in Report'           => 'Uitvoer inclusief',
+  'Income Statement'            => 'Inkomstenoverzicht',
+  'Invoice'                     => 'Factuur',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mrt',
+  'March'                       => 'Maart',
+  'May'                         => 'Mei',
+  'May '                        => 'Mei',
+  'Message'                     => 'Boodschap',
+  'N/A'                         => 'N/A',
+  'Nothing selected!'           => 'Niets geselecteerd!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Betalingen',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Afdrukken',
+  'Printer'                     => 'Printer',
+  'Receipts'                    => 'Ontvangstbewijzen',
+  'Report for'                  => 'Rapport voor',
+  'Retained Earnings'           => 'Winstreserve',
+  'Screen'                      => 'Scherm',
+  'Select all'                  => 'Selecteer alles',
+  'Select postscript or PDF!'   => 'Kies postscript of PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Herkomst',
+  'Standard'                    => 'Standaard',
+  'Statement'                   => 'Overzicht',
+  'Statement sent to'           => 'Overzicht verzonden aan',
+  'Statements sent to printer!' => 'Overzichten afgedrukt',
+  'Subject'                     => 'Onderwerp',
+  'Subtotal'                    => 'Subtotaal',
+  'Tax'                         => 'Belasting',
+  'Tax collected'               => 'Belasting verschuldigd',
+  'Tax paid'                    => 'Belasting Betaald',
+  'Total'                       => 'Totaal',
+  'Trial Balance'               => 'Proefbalans',
+  'Vendor'                      => 'Leverancier',
+  'as at'                       => 'per',
+  'collected on sales'          => 'verzameld voor de verkoop',
+  'for Period'                  => 'voor periode',
+  'paid on purchases'           => 'betaald op inkopen',
+  'to'                          => 'tot',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'verder'                      => 'continue',
+  'e_mail'                      => 'e_mail',
+  'afdrukken'                   => 'print',
+  'selecteer_alles'             => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/no/COPYING b/sql-ledger/locale/no/COPYING
new file mode 100644 (file)
index 0000000..b853d6c
--- /dev/null
@@ -0,0 +1,24 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Norwegian texts:
+#
+#  Author: Keld Jørn Simonsen <keld@dkuug.dk>
+#          Morten Pedersen <morten@workzone.no>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/no/LANGUAGE b/sql-ledger/locale/no/LANGUAGE
new file mode 100644 (file)
index 0000000..ed23589
--- /dev/null
@@ -0,0 +1 @@
+Norwegian
diff --git a/sql-ledger/locale/no/admin b/sql-ledger/locale/no/admin
new file mode 100644 (file)
index 0000000..f28ff84
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Aksesskontroll',
+  'Accounting'                  => 'Bokføring',
+  'Add User'                    => 'Ny bruker',
+  'Address'                     => 'Adresse',
+  'Administration'              => 'Administrasjon',
+  'Administrator'               => 'Administrator',
+  'All Datasets up to date!'    => 'Alle datasett oppdatert!',
+  'Change Admin Password'       => 'Endre passord for admin',
+  'Change Password'             => 'Endre passord',
+  'Character Set'               => 'Tegnsett',
+  'Click on login name to edit!' => 'Klikk på brukernavn for å redigere!',
+  'Company'                     => 'Firma',
+  'Connect to'                  => 'Forbind til',
+  'Continue'                    => 'Fortsett',
+  'Create Chart of Accounts'    => 'Opprett kontoplan',
+  'Create Dataset'              => 'Opprett datasett',
+  'DBI not installed!'          => 'DBI ikke installert!',
+  'Database'                    => 'Database',
+  'Database Administration'     => 'Administrasjon av database',
+  'Database Driver not checked!' => 'Databasedriver ikke kontrollert!',
+  'Database User missing!'      => 'Bruker av database mangler!',
+  'Dataset'                     => 'Datasett',
+  'Dataset missing!'            => 'Datasett mangler!',
+  'Dataset updated!'            => 'Datasett oppdatert!',
+  'Date Format'                 => 'Datoformat',
+  'Delete'                      => 'Fjern',
+  'Delete Dataset'              => 'Fjern datasett',
+  'Directory'                   => 'Katalog',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Grense for dropdown',
+  'E-mail'                      => 'E-post',
+  'Edit User'                   => 'Redigér bruker',
+  'Existing Datasets'           => 'Eksisterende datasett',
+  'Fax'                         => 'Faks',
+  'Host'                        => 'Vert',
+  'Hostname missing!'           => 'Vertsnavn mangler!',
+  'Incorrect Password!'         => 'Galt passord!',
+  'Language'                    => 'Språk',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'La vert- og port-felt være tomme med mindre du vil lage en ekstern forbindelse.',
+  'Login'                       => 'Login',
+  'Multibyte Encoding'          => 'Tegnsett',
+  'Name'                        => 'Navn',
+  'New Templates'               => 'Nye maler',
+  'No Database Drivers available!' => 'Ingen databasedrivere tilgjengelige!',
+  'No Dataset selected!'        => 'Ingen datasett valgt!',
+  'Nothing to delete!'          => 'Intet å slette!',
+  'Number Format'               => 'Numerisk format',
+  'Oracle Database Administration' => 'Administrasjon av database Oracle',
+  'Password'                    => 'Passord',
+  'Password changed!'           => 'Passord endret!',
+  'Pg Database Administration'  => 'Administrasjon av database Pg',
+  'Phone'                       => 'Tel',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port mangler!',
+  'Printer'                     => 'Printer',
+  'Save'                        => 'Lagre',
+  'Select a Dataset to delete and press "Continue"' => 'Velg et datasett det skal fjernes og trykk "Fortsett"',
+  'Setup Templates'             => 'Oppsett av maler',
+  'Ship via'                    => 'Avsend via',
+  'Signature'                   => 'Underskrift',
+  'Stylesheet'                  => 'Stílark',
+  'Templates'                   => 'Maler',
+  'The following Datasets are not in use and can be deleted' => 'De følgende datasett er ikke i bruk og kan slettes',
+  'The following Datasets need to be updated' => 'De følgende datasettene skal oppdateres',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Dette er en innledende kontroll for eksisterende kilder. Ingenting vil bli opprettet eller stettet på dette trinnet!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'For å tilføye en bruker til en gruppe må du endre et brukernavn og så lagre. Den nye brukeren vil så bli lagret med de samme variablene under det nye loginnavn.',
+  'Update Dataset'              => 'Oppdatér datasett',
+  'Use Templates'               => 'Bruk maler',
+  'User'                        => 'Bruker',
+  'User deleted!'               => 'Bruker slettet!',
+  'User saved!'                 => 'Bruker lagret!',
+  'Version'                     => 'Versjon',
+  'You must enter a host and port for local and remote connections!' => 'Du må oppgi en vert og en port for lokale og eksterne forbindelser!',
+  'does not exist'              => 'eksisterer ikke',
+  'is already a member!'        => 'er allerede et medlem!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'Låst!',
+  'successfully created!'       => 'opprettet!',
+  'successfully deleted!'       => 'fjernet!',
+  'website'                     => 'nettsted',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'ny_bruker'                   => 'add_user',
+  'endre_passord_for_admin'     => 'change_admin_password',
+  'endre_passord'               => 'change_password',
+  'fortsett'                    => 'continue',
+  'opprett_datasett'            => 'create_dataset',
+  'fjern'                       => 'delete',
+  'fjern_datasett'              => 'delete_dataset',
+  'login'                       => 'login',
+  'administrasjon_av_database_oracle' => 'oracle_database_administration',
+  'administrasjon_av_database_pg' => 'pg_database_administration',
+  'lagre'                       => 'save',
+  'oppdatér_datasett'           => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/no/all b/sql-ledger/locale/no/all
new file mode 100644 (file)
index 0000000..1c5d704
--- /dev/null
@@ -0,0 +1,496 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Kreditorer',
+  'AP Aging'                    => 'Aldersfordeling',
+  'AP Transaction'              => 'Leverandørfaktura',
+  'AP Transactions'             => 'Leverandørfakturaer',
+  'AR'                          => 'Debitorer',
+  'AR Aging'                    => 'Aldersfordeling',
+  'AR Transaction'              => 'Debitorpostering',
+  'AR Transactions'             => 'Debitorposteringer',
+  'About'                       => 'Om',
+  'Access Control'              => 'Aksesskontroll',
+  'Account'                     => 'Konto',
+  'Account Number'              => 'Kontonummer',
+  'Account Number missing!'     => 'Kontonummer mangler!',
+  'Account Type'                => 'Kontotype',
+  'Account Type missing!'       => 'Kontotype mangler!',
+  'Account deleted!'            => 'Konto slettet!',
+  'Account saved!'              => 'Konto lagret!',
+  'Accounting'                  => 'Bokføring',
+  'Accounting Menu'             => 'Konto-meny',
+  'Accounts'                    => 'Kontoer',
+  'Active'                      => 'Aktiv',
+  'Add'                         => 'Legg til',
+  'Add Account'                 => 'Ny konto',
+  'Add Accounts Payables Transaction' => 'Ny leverandørfaktura',
+  'Add Accounts Receivables Transaction' => 'Ny debitorpostering',
+  'Add Assembly'                => 'Ny sammensetting',
+  'Add Customer'                => 'Ny kunde',
+  'Add GIFI'                    => 'Ny GIFI',
+  'Add General Ledger Transaction' => 'Ny postering i hovedbok',
+  'Add Part'                    => 'Ny vare',
+  'Add Project'                 => 'Nytt prosjekt',
+  'Add Purchase Invoice'        => 'Ny innkjøpsfaktura',
+  'Add Purchase Order'          => 'Ny innkjøpsordre',
+  'Add Sales Invoice'           => 'Ny salgsfaktura',
+  'Add Sales Order'             => 'Ny salgsordre',
+  'Add Service'                 => 'Ny tjeneste',
+  'Add Transaction'             => 'Ny postering',
+  'Add User'                    => 'Ny bruker',
+  'Add Vendor'                  => 'Ny leverandør',
+  'Address'                     => 'Adresse',
+  'Administration'              => 'Administrasjon',
+  'Administrator'               => 'Administrator',
+  'All'                         => 'Alle',
+  'All Datasets up to date!'    => 'Alle datasett oppdatert!',
+  'Amount'                      => 'Beløp',
+  'Amount Due'                  => 'Forfallent beløp',
+  'Amount does not equal applied!' => 'Beløp er ikke likt utført!',
+  'Amount missing!'             => 'Konto mangler!',
+  'Applied'                     => 'Utført',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Invoice Number' => 'Er du sikker på at du vil fjerne fakturanummer',
+  'Are you sure you want to delete Order Number' => 'Er du sikker på at du vil fjerne ordrenummer',
+  'Are you sure you want to delete Transaction' => 'Er du sikker på at du vil fjerne postering',
+  'Assemblies'                  => 'Sammensettinger',
+  'Assemblies restocked!'       => 'Sammensettinger omplassert!',
+  'Assembly Number missing!'    => 'Sammensettingsnummer mangler!',
+  'Asset'                       => 'Aktiv',
+  'Attachment'                  => 'Vedlegg',
+  'Audit Control'               => 'Revisjonskontroll',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'BOM'                         => 'BOM',
+  'Backup'                      => 'Sikkerhetskopi',
+  'Backup sent to'              => 'Sikkerhetskopier sendt til',
+  'Balance'                     => 'Balanse',
+  'Balance Sheet'               => 'Status',
+  'Bcc'                         => 'Blind kopi',
+  'Bin'                         => 'Papirkurv',
+  'Books are open'              => 'Bokføringen er åpen for rettelser',
+  'Bought'                      => 'Kjøpt',
+  'Business Number'             => 'Organisasjonsnummer',
+  'C'                           => 'C',
+  'COGS'                        => 'Innkjøp',
+  'Cannot delete account!'      => 'Kan ikke slette konto!',
+  'Cannot delete customer!'     => 'Kan ikke slette kunde!',
+  'Cannot delete default account!' => 'Kan ikke slette standardkonto!',
+  'Cannot delete invoice!'      => 'Kan ikke slette faktura!',
+  'Cannot delete item already invoiced!' => 'Kan ikke slette allerede fakturert enkeltdel!',
+  'Cannot delete item on order!' => 'Kan ikke slette enkeltdel i ordre!',
+  'Cannot delete item which is part of an assembly!' => 'kan ikke slette en enhet som er en del av en sammensetting!',
+  'Cannot delete item!'         => 'Kan ikke slette enkeltdel!',
+  'Cannot delete order!'        => 'Kan ikke slette ordre!',
+  'Cannot delete transaction!'  => 'Kan ikke slette postering!',
+  'Cannot delete vendor!'       => 'Kan ikke slette leverandør!',
+  'Cannot have a value in both Debit and Credit!' => 'Kan ikke ha en verdi i både debet og kredit!',
+  'Cannot post a transaction without a value!' => 'Kan ikke bokføre transaksjon uten verdi!',
+  'Cannot post invoice for a closed period!' => 'Kan ikke bokføre faktura for en avsluttet periode!',
+  'Cannot post invoice!'        => 'Kan ikke bokføre faktura!',
+  'Cannot post payment for a closed period!' => 'Kan ikke bokføre betaling for en avsluttet periode!',
+  'Cannot post payment!'        => 'Kan ikke bokføre betaling!',
+  'Cannot post transaction for a closed period!' => 'Kan ikke bokføre postering for en avsluttet periode!',
+  'Cannot post transaction!'    => 'Kan ikke bokføre postering!',
+  'Cannot process payment for a closed period!' => 'Kan ikke behandle betaling for avsluttet periode!',
+  'Cannot save account!'        => 'Kan ikke lagre konto!',
+  'Cannot save order!'          => 'Kan ikke lagre ordre!',
+  'Cannot save preferences!'    => 'Kan ikke lagre preferenser!',
+  'Cannot stock assemblies!'    => 'Kan ikke plasere sammensetninger!',
+  'Cash'                        => 'Bank',
+  'Cash based'                  => 'Bank basert',
+  'Cc'                          => 'Kopi til',
+  'Change Admin Password'       => 'Endre passord for admin',
+  'Change Password'             => 'Endre passord',
+  'Character Set'               => 'Tegnsett',
+  'Chart of Accounts'           => 'Kontoplan',
+  'Check'                       => 'Sjekk',
+  'Check printed!'              => 'Sjekk utskrift!',
+  'Check printing failed!'      => 'Utskrift av sjekk feilet!',
+  'Cleared Balance'             => 'Utlignet balanse',
+  'Click on login name to edit!' => 'Klikk på brukernavn for å redigere!',
+  'Close Books up to'           => 'Avslutt bokføring opp til',
+  'Closed'                      => 'Avsluttet',
+  'Company'                     => 'Firma',
+  'Compare to'                  => 'Sammenlign med',
+  'Confirm!'                    => 'Bekreft!',
+  'Connect to'                  => 'Forbind til',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsett',
+  'Copies'                      => 'Kopier',
+  'Copy to COA'                 => 'Kopiér til COA',
+  'Create Chart of Accounts'    => 'Opprett kontoplan',
+  'Create Dataset'              => 'Opprett datasett',
+  'Credit'                      => 'Kredit',
+  'Credit Limit'                => 'Kreditgrense',
+  'Curr'                        => 'Val',
+  'Currency'                    => 'Valuta',
+  'Current'                     => 'Nåværende',
+  'Customer'                    => 'Kunde',
+  'Customer deleted!'           => 'Kunde slettet!',
+  'Customer missing!'           => 'Kunde mangler!',
+  'Customer not on file!'       => 'Kunde ikke i database!',
+  'Customer saved!'             => 'Kunde lagret!',
+  'Customers'                   => 'Kunder',
+  'DBI not installed!'          => 'DBI ikke installert!',
+  'Database'                    => 'Database',
+  'Database Administration'     => 'Administrasjon av database',
+  'Database Driver not checked!' => 'Databasedriver ikke kontrollert!',
+  'Database Host'               => 'Database-vert',
+  'Database User missing!'      => 'Bruker av database mangler!',
+  'Dataset'                     => 'Datasett',
+  'Dataset missing!'            => 'Datasett mangler!',
+  'Dataset updated!'            => 'Datasett oppdatert!',
+  'Date'                        => 'Dato',
+  'Date Due'                    => 'Forfallsdato',
+  'Date Format'                 => 'Datoformat',
+  'Date Paid'                   => 'Betalingsdato',
+  'Date missing!'               => 'Dato mangler!',
+  'Debit'                       => 'Debet',
+  'Debit and credit out of balance!' => 'Debet og kredit må være det samme!',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Decimalplaces'               => 'Desimalplasser',
+  'Delete'                      => 'Fjern',
+  'Delete Account'              => 'Fjern konto',
+  'Delete Dataset'              => 'Fjern datasett',
+  'Delivery Date'               => 'Leveringsdato',
+  'Department'                  => 'Avdeling',
+  'Deposit'                     => 'Depositum',
+  'Description'                 => 'Beskrivelse',
+  'Difference'                  => 'Forskjell',
+  'Directory'                   => 'Katalog',
+  'Discount'                    => 'Rabatt',
+  'Done'                        => 'Ferdig',
+  'Drawing'                     => 'Tegning',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Grense for dropdown',
+  'Due'                         => 'Forfall',
+  'Due Date'                    => 'Forfallsdato',
+  'Due Date missing!'           => 'Forfallsdato mangler!',
+  'E-mail'                      => 'E-post',
+  'E-mail Statement to'         => 'Send oppgjør til',
+  'E-mail address missing!'     => 'E-post-adresse mangler!',
+  'Edit'                        => 'Redigér',
+  'Edit Account'                => 'Redigér konto',
+  'Edit Accounts Payables Transaction' => 'Redigér leverandørpostering',
+  'Edit Accounts Receivables Transaction' => 'Redigér debitorpostering',
+  'Edit Assembly'               => 'Redigér sammensetting',
+  'Edit Customer'               => 'Endre kundeopplysninger',
+  'Edit GIFI'                   => 'Redigér GIFI',
+  'Edit General Ledger Transaction' => 'Redigér en postering i hovedbok',
+  'Edit Part'                   => 'Redigér vare',
+  'Edit Preferences for'        => 'Redigér innstillinger for',
+  'Edit Project'                => 'Redigér prosjekt',
+  'Edit Purchase Invoice'       => 'Redigér innkjøpsfaktura',
+  'Edit Purchase Order'         => 'Redigér innkjøpsordre',
+  'Edit Sales Invoice'          => 'Redigér salgsfaktura',
+  'Edit Sales Order'            => 'Redigér salgsordre',
+  'Edit Service'                => 'Redigér tjeneste',
+  'Edit Template'               => 'Redigér mal',
+  'Edit User'                   => 'Redigér bruker',
+  'Edit Vendor'                 => 'Endre produsent',
+  'Employee'                    => 'Ansatt',
+  'Enforce transaction reversal for all dates' => 'Tving eksplisitte transaksjonsrettelser for alle datoer',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Angi opp til 3 bokstaver adskilt med kolon (fx NOK:EUR:USD:JPY) for innenlandske og utenlandske valutaer',
+  'Equity'                      => 'Egenkapital',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Vekslingskurs',
+  'Exchangerate Difference'     => 'Forskjell på vekslingskurs',
+  'Exchangerate for payment missing!' => 'Vekslingskurs for betaling mangler!',
+  'Exchangerate missing!'       => 'Vekslingskurs mangler!',
+  'Existing Datasets'           => 'Eksisterende datasett',
+  'Expense'                     => 'Utgift',
+  'Expense Account'             => 'Utgiftskonto',
+  'Expense/Asset'               => 'Utgift/Aktiv',
+  'Extended'                    => 'Utvigt',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'Foreign Exchange Gain'       => 'Gevinst på valutahandel',
+  'Foreign Exchange Loss'       => 'Tap på valutahandel',
+  'From'                        => 'Fra',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI slettet!',
+  'GIFI missing!'               => 'GIFI mangler!',
+  'GIFI saved!'                 => 'GIFI lagret!',
+  'GL Transaction'              => 'Postering i hovedbok',
+  'General Ledger'              => 'Hovedbok',
+  'Goods & Services'            => 'Varer og tjenester',
+  'HTML Templates'              => 'HTML-maler',
+  'Heading'                     => 'Overskrift',
+  'Host'                        => 'Vert',
+  'Hostname missing!'           => 'Vertsnavn mangler!',
+  'ID'                          => 'ID',
+  'Image'                       => 'Bilde',
+  'In-line'                     => 'Inne i',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Include in drop-down menus'  => 'Inkludér i rullegardin-menyer',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Skal denne konto kunne velges som avgifts- eller mva-konto ved opprettelsen av kunder/leverandører?',
+  'Income'                      => 'Inntekt',
+  'Income Account'              => 'Inntektskonto',
+  'Income Statement'            => 'Driftsregnskap',
+  'Incorrect Dataset version!'  => 'Gal versjon av datasett!',
+  'Incorrect Password!'         => 'Galt passord!',
+  'Individual Items'            => 'Individuelle enheter',
+  'Inventory'                   => 'Artikler',
+  'Inventory Account'           => 'Lagerkonto',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Lagerbeholdning må være null for at du kan sette denne sammensetting som foreldet!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Lagerbeholdning må være null for at du kan sette denne enhet som foreldet!',
+  'Inventory quantity must be zero!' => 'Lagerbeholdning må være null!',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadato',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Invoice deleted!'            => 'Faktura slettet!',
+  'Invoice posted!'             => 'Faktura bokført!',
+  'Invoices'                    => 'Fakturaer',
+  'Is this a summary account to record' => 'Samlekonto for',
+  'Item deleted!'               => 'Enkeltdel slettet!',
+  'Item not on file!'           => 'Enkeltdel er ikke i databasen!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'LaTeX Templates'             => 'LaTeX-maler',
+  'Language'                    => 'Språk',
+  'Last Cost'                   => 'Seneste pris',
+  'Last Invoice Number'         => 'Seneste fakturanummer',
+  'Last Numbers & Default Accounts' => 'Løpenumre og standardkontoer',
+  'Last Purchase Order Number'  => 'Seneste innkjøpsordrenummer',
+  'Last Sales Order Number'     => 'Seneste salgsordrenummer',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'La vert- og port-felt være tomme med mindre du vil lage en ekstern forbindelse.',
+  'Liability'                   => 'Passiv',
+  'Licensed to'                 => 'Utført for',
+  'Line Total'                  => 'Antall linjer',
+  'Link'                        => 'Referanse',
+  'Link Accounts'               => 'Kople kontoer',
+  'List Accounts'               => 'List kontoer',
+  'List GIFI'                   => 'List GIFI',
+  'List Price'                  => 'Listepris',
+  'List Transactions'           => 'Vis bokføringer',
+  'Login'                       => 'Login',
+  'Logout'                      => 'Log ut',
+  'Make'                        => 'Fabrikat',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'mai',
+  'May '                        => 'mai ',
+  'Message'                     => 'Melding',
+  'Microfiche'                  => 'Mikrofilm',
+  'Model'                       => 'Modell',
+  'Multibyte Encoding'          => 'Tegnsett',
+  'N/A'                         => 'I/T',
+  'Name'                        => 'Navn',
+  'Name missing!'               => 'Navn mangler!',
+  'New Templates'               => 'Nye maler',
+  'No'                          => 'Nei',
+  'No Database Drivers available!' => 'Ingen databasedrivere tilgjengelige!',
+  'No Dataset selected!'        => 'Ingen datasett valgt!',
+  'No email address for'        => 'Ingen emailadresse for',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Bemerkninger',
+  'Nothing applied!'            => 'Ingenting utført!',
+  'Nothing selected!'           => 'Ingenting valgt!',
+  'Nothing to delete!'          => 'Intet å slette!',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Number Format'               => 'Numerisk format',
+  'Number missing in Row'       => 'Tall mangler i rad',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Foreldet',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'On Hand'                     => 'På lager',
+  'On Order'                    => 'I ordre',
+  'Open'                        => 'Åpne',
+  'Oracle Database Administration' => 'Administrasjon av database Oracle',
+  'Order'                       => 'Ordre',
+  'Order Date'                  => 'Ordredato',
+  'Order Date missing!'         => 'Ordredato mangler!',
+  'Order Entry'                 => 'Ordreinngang',
+  'Order Number'                => 'Ordrenummer',
+  'Order Number missing!'       => 'Ordrenummer mangler!',
+  'Order deleted!'              => 'Ordre slettet!',
+  'Order saved!'                => 'Ordre lagret!',
+  'Ordered'                     => 'Ordrer',
+  'Orphaned'                    => 'Frittstående',
+  'Out of balance!'             => 'Ute av balanse!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Følgeseddel',
+  'Packing List Date missing!'  => 'Dato for pakkeliste mangler!',
+  'Packing List Number missing!' => 'Nummer for pakkeliste mangler!',
+  'Paid'                        => 'Betalt',
+  'Paid in full'                => 'Alt betalt',
+  'Part'                        => 'Vare',
+  'Part Number missing!'        => 'Varenummer mangler!',
+  'Parts'                       => 'Deler',
+  'Parts Inventory'             => 'Vareliste',
+  'Password'                    => 'Passord',
+  'Password changed!'           => 'Passord endret!',
+  'Payables'                    => 'Utbetalinger',
+  'Payment'                     => 'Betaling',
+  'Payment date missing!'       => 'Betalingsdato mangler!',
+  'Payment posted!'             => 'Betaling bokført!',
+  'Payments'                    => 'Utbetaling',
+  'Pg Database Administration'  => 'Administrasjon av database Pg',
+  'Phone'                       => 'Tel',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port mangler!',
+  'Post'                        => 'Bokfør',
+  'Post as new'                 => 'Bokfør som ny',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Innstillinger',
+  'Preferences saved!'          => 'Innstillinger lagret!',
+  'Price'                       => 'Pris',
+  'Print'                       => 'Skriv ut',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Prosjekt',
+  'Project Number'              => 'Prosjektnummer',
+  'Project Number missing!'     => 'Prosjektnummer mangler!',
+  'Project deleted!'            => 'Prosjekt slettet!',
+  'Project not on file!'        => 'Prosjekt er ikke i database!',
+  'Project saved!'              => 'Prosjekt lagret!',
+  'Projects'                    => 'Prosjekter',
+  'Purchase Invoice'            => 'Innkjøpsfaktura',
+  'Purchase Order'              => 'Innkjøpsordre',
+  'Purchase Orders'             => 'Innkjøpsordrer',
+  'Qty'                         => 'Antall',
+  'ROP'                         => 'Etterbestill ved',
+  'Rate'                        => 'Rate',
+  'Recd'                        => 'Mottatt',
+  'Receipt'                     => 'Kvittering',
+  'Receipt printed!'            => 'Kvittering skrevet!',
+  'Receipt printing failed!'    => 'Kvitteringsutskrift feilet!',
+  'Receipts'                    => 'Kvitteringer',
+  'Receivables'                 => 'Innbetalinger',
+  'Reconciliation'              => 'Bankoppgjør',
+  'Record in'                   => 'Bokfør på',
+  'Reference'                   => 'Referanse',
+  'Reference missing!'          => 'Referanser mangler!',
+  'Remaining'                   => 'Resterende',
+  'Report for'                  => 'Rapport for',
+  'Reports'                     => 'Rapporter',
+  'Required by'                 => 'Bestilt av',
+  'Retained Earnings'           => 'Realisert overskudd',
+  'Sales'                       => 'Salg',
+  'Sales Invoice'               => 'Salgsfaktura',
+  'Sales Order'                 => 'Salgsordre',
+  'Sales Orders'                => 'Salgsordrer',
+  'Salesperson'                 => '',
+  'Save'                        => 'Lagre',
+  'Save as new'                 => 'Lagre som ny',
+  'Save to File'                => 'Lagre i fil',
+  'Screen'                      => 'Skjerm',
+  'Select a Dataset to delete and press "Continue"' => 'Velg et datasett det skal fjernes og trykk "Fortsett"',
+  'Select all'                  => 'Velg alt',
+  'Select from one of the items below' => 'Velg en fra listen under, og trykk "Fortsett"',
+  'Select from one of the names below' => 'Velg fra et av navnene under',
+  'Select from one of the projects below' => 'Velg fra et av prosjektene under',
+  'Select postscript or PDF!'   => 'Velg postscript eller PDF!',
+  'Sell Price'                  => 'Salgspris',
+  'Send by E-Mail'              => 'Sendt per email',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Tjeneste',
+  'Service Items'               => 'Tjenester',
+  'Service Number missing!'     => 'Tjenestenummer mangler!',
+  'Services'                    => 'Tjenester',
+  'Setup Templates'             => 'Oppsett av maler',
+  'Ship'                        => 'Avsend',
+  'Ship to'                     => 'Avsend til',
+  'Ship via'                    => 'Avsend via',
+  'Short'                       => 'Kort',
+  'Signature'                   => 'Underskrift',
+  'Sold'                        => 'Solgt',
+  'Source'                      => 'Bilag',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Oppgjør',
+  'Statement Balance'           => 'Balanseoppgjør',
+  'Statement sent to'           => 'Oppgjør sendt til',
+  'Statements sent to printer!' => 'Oppgjør sendt til skriver!',
+  'Stock Assembly'              => 'Lagersammensetting',
+  'Stylesheet'                  => 'Stílark',
+  'Subject'                     => 'Emne',
+  'Subtotal'                    => 'Subtotal',
+  'System'                      => 'System',
+  'Tax'                         => 'Avgift/mva',
+  'Tax Accounts'                => 'Avgift/mva-kontoer',
+  'Tax Included'                => 'Inkl. avgifter og mva',
+  'Tax collected'               => 'Inngående avgift',
+  'Tax paid'                    => 'Betalt avgift',
+  'Taxable'                     => 'Avgifts/mvapliktig',
+  'Template saved!'             => 'Mal lagret!',
+  'Templates'                   => 'Maler',
+  'Terms: Net'                  => 'Netto',
+  'The following Datasets are not in use and can be deleted' => 'De følgende datasett er ikke i bruk og kan slettes',
+  'The following Datasets need to be updated' => 'De følgende datasettene skal oppdateres',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Dette er en innledende kontroll for eksisterende kilder. Ingenting vil bli opprettet eller stettet på dette trinnet!',
+  'To'                          => 'Til',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'For å tilføye en bruker til en gruppe må du endre et brukernavn og så lagre. Den nye brukeren vil så bli lagret med de samme variablene under det nye loginnavn.',
+  'Top Level'                   => 'Toppnivå',
+  'Total'                       => 'I alt',
+  'Transaction Date missing!'   => 'Transaksjonsdato mangler!',
+  'Transaction deleted!'        => 'Postering slettet!',
+  'Transaction posted!'         => 'Postering bokført!',
+  'Transaction reversal enforced for all dates' => 'Transaksjonsrettelser skal alltid bokføres eksplisitt',
+  'Transaction reversal enforced up to' => 'Transaksjonsrettelser skal bokføres eksplisitt inntil',
+  'Transactions'                => 'Posteringer',
+  'Transactions exist, cannot delete customer!' => 'Kunde kan ikke fjernes da det er posteringer!',
+  'Transactions exist, cannot delete vendor!' => 'Leverandør kan ikke fjernes da det er posteringer!',
+  'Transactions exist; cannot delete account!' => 'Konto kan ikke fjernes da det er posteringer!',
+  'Trial Balance'               => 'Foreløpig status',
+  'Unit'                        => 'Enhet',
+  'Unit of measure'             => 'Måleenhet',
+  'Update'                      => 'Oppdatér',
+  'Update Dataset'              => 'Oppdatér datasett',
+  'Updated'                     => 'Oppdateret',
+  'Use Templates'               => 'Bruk maler',
+  'User'                        => 'Bruker',
+  'User deleted!'               => 'Bruker slettet!',
+  'User saved!'                 => 'Bruker lagret!',
+  'Vendor'                      => 'Leverandør',
+  'Vendor deleted!'             => 'Leverandør slettet!',
+  'Vendor missing!'             => 'Leverandør mangler!',
+  'Vendor not on file!'         => 'Leverandør er ikke i database!',
+  'Vendor saved!'               => 'Leverandør lagret!',
+  'Vendors'                     => 'Leverandører',
+  'Version'                     => 'Versjon',
+  'Weight'                      => 'Vekt',
+  'Weight Unit'                 => 'Vektenhet',
+  'What type of item is this?'  => 'Hvilken type ting er dette?',
+  'Year End'                    => 'Årsslutt',
+  'Yes'                         => 'Ja',
+  'You are logged out!'         => 'Du er logget av!',
+  'You did not enter a name!'   => 'Du gav ikke et navn!',
+  'You must enter a host and port for local and remote connections!' => 'Du må oppgi en vert og en port for lokale og eksterne forbindelser!',
+  'as at'                       => 'som ved',
+  'collected on sales'          => 'innbetalt på salg',
+  'days'                        => 'dager',
+  'does not exist'              => 'eksisterer ikke',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendt på epost til',
+  'for Period'                  => 'for periode',
+  'hr'                          => 'time',
+  'is already a member!'        => 'er allerede et medlem!',
+  'is not a member!'            => 'er ikke et medlem!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'Låst!',
+  'paid on purchases'           => 'betalt på kjøp',
+  'sent to printer'             => 'sendt til skriver',
+  'successfully created!'       => 'opprettet!',
+  'successfully deleted!'       => 'fjernet!',
+  'to'                          => 'til',
+  'website'                     => 'nettsted',
+};
+
+1;
diff --git a/sql-ledger/locale/no/am b/sql-ledger/locale/no/am
new file mode 100644 (file)
index 0000000..5e56e9a
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Kreditorer',
+  'AR'                          => 'Debitorer',
+  'Account'                     => 'Konto',
+  'Account Number'              => 'Kontonummer',
+  'Account Number missing!'     => 'Kontonummer mangler!',
+  'Account Type'                => 'Kontotype',
+  'Account Type missing!'       => 'Kontotype mangler!',
+  'Account deleted!'            => 'Konto slettet!',
+  'Account saved!'              => 'Konto lagret!',
+  'Add Account'                 => 'Ny konto',
+  'Add GIFI'                    => 'Ny GIFI',
+  'Address'                     => 'Adresse',
+  'Asset'                       => 'Aktiv',
+  'Audit Control'               => 'Revisjonskontroll',
+  'Backup sent to'              => 'Sikkerhetskopier sendt til',
+  'Books are open'              => 'Bokføringen er åpen for rettelser',
+  'Business Number'             => 'Organisasjonsnummer',
+  'COGS'                        => 'Innkjøp',
+  'Cannot delete account!'      => 'Kan ikke slette konto!',
+  'Cannot delete default account!' => 'Kan ikke slette standardkonto!',
+  'Cannot save account!'        => 'Kan ikke lagre konto!',
+  'Cannot save preferences!'    => 'Kan ikke lagre preferenser!',
+  'Character Set'               => 'Tegnsett',
+  'Chart of Accounts'           => 'Kontoplan',
+  'Close Books up to'           => 'Avslutt bokføring opp til',
+  'Company'                     => 'Firma',
+  'Continue'                    => 'Fortsett',
+  'Copy to COA'                 => 'Kopiér til COA',
+  'Credit'                      => 'Kredit',
+  'Date Format'                 => 'Datoformat',
+  'Debit'                       => 'Debet',
+  'Delete'                      => 'Fjern',
+  'Delete Account'              => 'Fjern konto',
+  'Description'                 => 'Beskrivelse',
+  'Dropdown Limit'              => 'Grense for dropdown',
+  'E-mail'                      => 'E-post',
+  'Edit'                        => 'Redigér',
+  'Edit Account'                => 'Redigér konto',
+  'Edit GIFI'                   => 'Redigér GIFI',
+  'Edit Preferences for'        => 'Redigér innstillinger for',
+  'Edit Template'               => 'Redigér mal',
+  'Enforce transaction reversal for all dates' => 'Tving eksplisitte transaksjonsrettelser for alle datoer',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Angi opp til 3 bokstaver adskilt med kolon (fx NOK:EUR:USD:JPY) for innenlandske og utenlandske valutaer',
+  'Equity'                      => 'Egenkapital',
+  'Expense'                     => 'Utgift',
+  'Expense Account'             => 'Utgiftskonto',
+  'Expense/Asset'               => 'Utgift/Aktiv',
+  'Fax'                         => 'Faks',
+  'Foreign Exchange Gain'       => 'Gevinst på valutahandel',
+  'Foreign Exchange Loss'       => 'Tap på valutahandel',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI slettet!',
+  'GIFI missing!'               => 'GIFI mangler!',
+  'GIFI saved!'                 => 'GIFI lagret!',
+  'Heading'                     => 'Overskrift',
+  'Include in drop-down menus'  => 'Inkludér i rullegardin-menyer',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Skal denne konto kunne velges som avgifts- eller mva-konto ved opprettelsen av kunder/leverandører?',
+  'Income'                      => 'Inntekt',
+  'Income Account'              => 'Inntektskonto',
+  'Inventory'                   => 'Artikler',
+  'Inventory Account'           => 'Lagerkonto',
+  'Is this a summary account to record' => 'Samlekonto for',
+  'Language'                    => 'Språk',
+  'Last Invoice Number'         => 'Seneste fakturanummer',
+  'Last Numbers & Default Accounts' => 'Løpenumre og standardkontoer',
+  'Last Purchase Order Number'  => 'Seneste innkjøpsordrenummer',
+  'Last Sales Order Number'     => 'Seneste salgsordrenummer',
+  'Liability'                   => 'Passiv',
+  'Link'                        => 'Referanse',
+  'Name'                        => 'Navn',
+  'No'                          => 'Nei',
+  'No email address for'        => 'Ingen emailadresse for',
+  'Number'                      => 'Nummer',
+  'Number Format'               => 'Numerisk format',
+  'Parts Inventory'             => 'Vareliste',
+  'Password'                    => 'Passord',
+  'Payables'                    => 'Utbetalinger',
+  'Payment'                     => 'Betaling',
+  'Phone'                       => 'Tel',
+  'Preferences saved!'          => 'Innstillinger lagret!',
+  'Rate'                        => 'Rate',
+  'Receivables'                 => 'Innbetalinger',
+  'Sales'                       => 'Salg',
+  'Save'                        => 'Lagre',
+  'Service Items'               => 'Tjenester',
+  'Ship via'                    => 'Avsend via',
+  'Signature'                   => 'Underskrift',
+  'Stylesheet'                  => 'Stílark',
+  'Tax'                         => 'Avgift/mva',
+  'Tax Accounts'                => 'Avgift/mva-kontoer',
+  'Template saved!'             => 'Mal lagret!',
+  'Transaction reversal enforced for all dates' => 'Transaksjonsrettelser skal alltid bokføres eksplisitt',
+  'Transaction reversal enforced up to' => 'Transaksjonsrettelser skal bokføres eksplisitt inntil',
+  'Transactions exist; cannot delete account!' => 'Konto kan ikke fjernes da det er posteringer!',
+  'Weight Unit'                 => 'Vektenhet',
+  'Year End'                    => 'Årsslutt',
+  'Yes'                         => 'Ja',
+  'does not exist'              => 'eksisterer ikke',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'ny_konto'                    => 'add_account',
+  'fortsett'                    => 'continue',
+  'kopiér_til_coa'              => 'copy_to_coa',
+  'fjern'                       => 'delete',
+  'redigér'                     => 'edit',
+  'redigér_konto'               => 'edit_account',
+  'lagre'                       => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/no/ap b/sql-ledger/locale/no/ap
new file mode 100644 (file)
index 0000000..896bc69
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Leverandørfaktura',
+  'AP Transactions'             => 'Leverandørfakturaer',
+  'Account'                     => 'Konto',
+  'Add Accounts Payables Transaction' => 'Ny leverandørfaktura',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Beløp',
+  'Amount Due'                  => 'Forfallent beløp',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Transaction' => 'Er du sikker på at du vil fjerne postering',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Cannot delete transaction!'  => 'Kan ikke slette postering!',
+  'Cannot post payment for a closed period!' => 'Kan ikke bokføre betaling for en avsluttet periode!',
+  'Cannot post transaction for a closed period!' => 'Kan ikke bokføre postering for en avsluttet periode!',
+  'Cannot post transaction!'    => 'Kan ikke bokføre postering!',
+  'Closed'                      => 'Avsluttet',
+  'Confirm!'                    => 'Bekreft!',
+  'Continue'                    => 'Fortsett',
+  'Currency'                    => 'Valuta',
+  'Customer not on file!'       => 'Kunde ikke i database!',
+  'Date'                        => 'Dato',
+  'Date Paid'                   => 'Betalingsdato',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Fjern',
+  'Description'                 => 'Beskrivelse',
+  'Due Date'                    => 'Forfallsdato',
+  'Due Date missing!'           => 'Forfallsdato mangler!',
+  'Edit Accounts Payables Transaction' => 'Redigér leverandørpostering',
+  'Employee'                    => 'Ansatt',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Vekslingskurs',
+  'Exchangerate for payment missing!' => 'Vekslingskurs for betaling mangler!',
+  'Exchangerate missing!'       => 'Vekslingskurs mangler!',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadato',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'mai',
+  'May '                        => 'mai ',
+  'Notes'                       => 'Bemerkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Open'                        => 'Åpne',
+  'Order'                       => 'Ordre',
+  'Order Number'                => 'Ordrenummer',
+  'Paid'                        => 'Betalt',
+  'Payment date missing!'       => 'Betalingsdato mangler!',
+  'Payments'                    => 'Utbetaling',
+  'Post'                        => 'Bokfør',
+  'Post as new'                 => 'Bokfør som ny',
+  'Project'                     => 'Prosjekt',
+  'Project not on file!'        => 'Prosjekt er ikke i database!',
+  'Purchase Invoice'            => 'Innkjøpsfaktura',
+  'Select from one of the names below' => 'Velg fra et av navnene under',
+  'Select from one of the projects below' => 'Velg fra et av prosjektene under',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Source'                      => 'Bilag',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Avgift/mva',
+  'Tax Included'                => 'Inkl. avgifter og mva',
+  'Total'                       => 'I alt',
+  'Transaction deleted!'        => 'Postering slettet!',
+  'Transaction posted!'         => 'Postering bokført!',
+  'Update'                      => 'Oppdatér',
+  'Vendor'                      => 'Leverandør',
+  'Vendor missing!'             => 'Leverandør mangler!',
+  'Vendor not on file!'         => 'Leverandør er ikke i database!',
+  'Yes'                         => 'Ja',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'leverandørfaktura'           => 'ap_transaction',
+  'ny_leverandørfaktura'        => 'add_accounts_payables_transaction',
+  'fortsett'                    => 'continue',
+  'fjern'                       => 'delete',
+  'redigér_leverandørpostering' => 'edit_accounts_payables_transaction',
+  'bokfør'                      => 'post',
+  'bokfør_som_ny'               => 'post_as_new',
+  'innkjøpsfaktura'             => 'purchase_invoice',
+  'oppdatér'                    => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/no/ar b/sql-ledger/locale/no/ar
new file mode 100644 (file)
index 0000000..d9ec705
--- /dev/null
@@ -0,0 +1,134 @@
+$self{texts} = {
+  'AR Transaction'              => 'Debitorpostering',
+  'AR Transactions'             => 'Debitorposteringer',
+  'Account'                     => 'Konto',
+  'Add Accounts Receivables Transaction' => 'Ny debitorpostering',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Beløp',
+  'Amount Due'                  => 'Forfallent beløp',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Transaction' => 'Er du sikker på at du vil fjerne postering',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Cannot delete transaction!'  => 'Kan ikke slette postering!',
+  'Cannot post payment for a closed period!' => 'Kan ikke bokføre betaling for en avsluttet periode!',
+  'Cannot post transaction for a closed period!' => 'Kan ikke bokføre postering for en avsluttet periode!',
+  'Cannot post transaction!'    => 'Kan ikke bokføre postering!',
+  'Closed'                      => 'Avsluttet',
+  'Confirm!'                    => 'Bekreft!',
+  'Continue'                    => 'Fortsett',
+  'Credit Limit'                => 'Kreditgrense',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Kunde',
+  'Customer missing!'           => 'Kunde mangler!',
+  'Customer not on file!'       => 'Kunde ikke i database!',
+  'Date'                        => 'Dato',
+  'Date Paid'                   => 'Betalingsdato',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Fjern',
+  'Description'                 => 'Beskrivelse',
+  'Due Date'                    => 'Forfallsdato',
+  'Due Date missing!'           => 'Forfallsdato mangler!',
+  'Edit Accounts Receivables Transaction' => 'Redigér debitorpostering',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Vekslingskurs',
+  'Exchangerate for payment missing!' => 'Vekslingskurs for betaling mangler!',
+  'Exchangerate missing!'       => 'Vekslingskurs mangler!',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadato',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'mai',
+  'May '                        => 'mai ',
+  'Notes'                       => 'Bemerkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Open'                        => 'Åpne',
+  'Order'                       => 'Ordre',
+  'Order Number'                => 'Ordrenummer',
+  'Paid'                        => 'Betalt',
+  'Payment date missing!'       => 'Betalingsdato mangler!',
+  'Payments'                    => 'Utbetaling',
+  'Post'                        => 'Bokfør',
+  'Post as new'                 => 'Bokfør som ny',
+  'Project'                     => 'Prosjekt',
+  'Project not on file!'        => 'Prosjekt er ikke i database!',
+  'Remaining'                   => 'Resterende',
+  'Sales Invoice'               => 'Salgsfaktura',
+  'Salesperson'                 => 'Salesperson',
+  'Select from one of the names below' => 'Velg fra et av navnene under',
+  'Select from one of the projects below' => 'Velg fra et av prosjektene under',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Ship via'                    => 'Avsend via',
+  'Source'                      => 'Bilag',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Avgift/mva',
+  'Tax Included'                => 'Inkl. avgifter og mva',
+  'Total'                       => 'I alt',
+  'Transaction deleted!'        => 'Postering slettet!',
+  'Transaction posted!'         => 'Postering bokført!',
+  'Update'                      => 'Oppdatér',
+  'Vendor not on file!'         => 'Leverandør er ikke i database!',
+  'Yes'                         => 'Ja',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'debitorpostering'            => 'ar_transaction',
+  'fortsett'                    => 'continue',
+  'fjern'                       => 'delete',
+  'bokfør'                      => 'post',
+  'bokfør_som_ny'               => 'post_as_new',
+  'salgsfaktura'                => 'sales_invoice',
+  'oppdatér'                    => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/no/arap b/sql-ledger/locale/no/arap
new file mode 100644 (file)
index 0000000..048ea79
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Adresse',
+  'Continue'                    => 'Fortsett',
+  'Customer not on file!'       => 'Kunde ikke i database!',
+  'Description'                 => 'Beskrivelse',
+  'Number'                      => 'Nummer',
+  'Project not on file!'        => 'Prosjekt er ikke i database!',
+  'Select from one of the names below' => 'Velg fra et av navnene under',
+  'Select from one of the projects below' => 'Velg fra et av prosjektene under',
+  'Vendor not on file!'         => 'Leverandør er ikke i database!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'fortsett'                    => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/no/ca b/sql-ledger/locale/no/ca
new file mode 100644 (file)
index 0000000..1b5cfac
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Balance'                     => 'Balanse',
+  'Chart of Accounts'           => 'Kontoplan',
+  'Credit'                      => 'Kredit',
+  'Date'                        => 'Dato',
+  'Debit'                       => 'Debet',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Description'                 => 'Beskrivelse',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'List Transactions'           => 'Vis bokføringer',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'mai',
+  'May '                        => 'mai ',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Reference'                   => 'Referanse',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Subtotal'                    => 'Subtotal',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'vis_bokføringer'             => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/no/cp b/sql-ledger/locale/no/cp
new file mode 100644 (file)
index 0000000..670c80c
--- /dev/null
@@ -0,0 +1,77 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Beløp',
+  'Amount does not equal applied!' => 'Beløp er ikke likt utført!',
+  'Amount missing!'             => 'Konto mangler!',
+  'Applied'                     => 'Utført',
+  'Cannot post payment!'        => 'Kan ikke bokføre betaling!',
+  'Cannot process payment for a closed period!' => 'Kan ikke behandle betaling for avsluttet periode!',
+  'Check'                       => 'Sjekk',
+  'Check printed!'              => 'Sjekk utskrift!',
+  'Check printing failed!'      => 'Utskrift av sjekk feilet!',
+  'Continue'                    => 'Fortsett',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Kunde',
+  'Customer not on file!'       => 'Kunde ikke i database!',
+  'Date'                        => 'Dato',
+  'Date missing!'               => 'Dato mangler!',
+  'Description'                 => 'Beskrivelse',
+  'Due'                         => 'Forfall',
+  'Exchangerate'                => 'Vekslingskurs',
+  'From'                        => 'Fra',
+  'Invoice'                     => 'Faktura',
+  'Invoices'                    => 'Fakturaer',
+  'Nothing applied!'            => 'Ingenting utført!',
+  'Number'                      => 'Nummer',
+  'Paid in full'                => 'Alt betalt',
+  'Payment'                     => 'Betaling',
+  'Payment posted!'             => 'Betaling bokført!',
+  'Post'                        => 'Bokfør',
+  'Print'                       => 'Skriv ut',
+  'Printer'                     => 'Printer',
+  'Project not on file!'        => 'Prosjekt er ikke i database!',
+  'Receipt'                     => 'Kvittering',
+  'Receipt printed!'            => 'Kvittering skrevet!',
+  'Receipt printing failed!'    => 'Kvitteringsutskrift feilet!',
+  'Reference'                   => 'Referanse',
+  'Screen'                      => 'Skjerm',
+  'Select from one of the names below' => 'Velg fra et av navnene under',
+  'Select from one of the projects below' => 'Velg fra et av prosjektene under',
+  'Update'                      => 'Oppdatér',
+  'Vendor'                      => 'Leverandør',
+  'Vendor not on file!'         => 'Leverandør er ikke i database!',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'fortsett'                    => 'continue',
+  'bokfør'                      => 'post',
+  'skriv_ut'                    => 'print',
+  'oppdatér'                    => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/no/ct b/sql-ledger/locale/no/ct
new file mode 100644 (file)
index 0000000..994a0cf
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Legg til',
+  'Address'                     => 'Adresse',
+  'All'                         => 'Alle',
+  'Bcc'                         => 'Blind kopi',
+  'Cannot delete customer!'     => 'Kan ikke slette kunde!',
+  'Cannot delete vendor!'       => 'Kan ikke slette leverandør!',
+  'Cc'                          => 'Kopi til',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsett',
+  'Credit Limit'                => 'Kreditgrense',
+  'Customer deleted!'           => 'Kunde slettet!',
+  'Customer saved!'             => 'Kunde lagret!',
+  'Customers'                   => 'Kunder',
+  'Delete'                      => 'Fjern',
+  'Discount'                    => 'Rabatt',
+  'E-mail'                      => 'E-post',
+  'Edit Customer'               => 'Endre kundeopplysninger',
+  'Edit Vendor'                 => 'Endre produsent',
+  'Fax'                         => 'Faks',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Invoice'                     => 'Faktura',
+  'Name'                        => 'Navn',
+  'Name missing!'               => 'Navn mangler!',
+  'Notes'                       => 'Bemerkninger',
+  'Number'                      => 'Nummer',
+  'Order'                       => 'Ordre',
+  'Orphaned'                    => 'Frittstående',
+  'Phone'                       => 'Tel',
+  'Save'                        => 'Lagre',
+  'Ship to'                     => 'Avsend til',
+  'Tax Included'                => 'Inkl. avgifter og mva',
+  'Taxable'                     => 'Avgifts/mvapliktig',
+  'Terms: Net'                  => 'Netto',
+  'Transactions exist, cannot delete customer!' => 'Kunde kan ikke fjernes da det er posteringer!',
+  'Transactions exist, cannot delete vendor!' => 'Leverandør kan ikke fjernes da det er posteringer!',
+  'Vendor deleted!'             => 'Leverandør slettet!',
+  'Vendor saved!'               => 'Leverandør lagret!',
+  'Vendors'                     => 'Leverandører',
+  'days'                        => 'dager',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'legg_til'                    => 'add',
+  'fortsett'                    => 'continue',
+  'fjern'                       => 'delete',
+  'faktura'                     => 'invoice',
+  'ordre'                       => 'order',
+  'lagre'                       => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/no/gl b/sql-ledger/locale/no/gl
new file mode 100644 (file)
index 0000000..0ce247d
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Leverandørfaktura',
+  'AR Transaction'              => 'Debitorpostering',
+  'Account'                     => 'Konto',
+  'Add General Ledger Transaction' => 'Ny postering i hovedbok',
+  'Address'                     => 'Adresse',
+  'All'                         => 'Alle',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Transaction' => 'Er du sikker på at du vil fjerne postering',
+  'Asset'                       => 'Aktiv',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Balance'                     => 'Balanse',
+  'Cannot delete transaction!'  => 'Kan ikke slette postering!',
+  'Cannot have a value in both Debit and Credit!' => 'Kan ikke ha en verdi i både debet og kredit!',
+  'Cannot post a transaction without a value!' => 'Kan ikke bokføre transaksjon uten verdi!',
+  'Cannot post transaction for a closed period!' => 'Kan ikke bokføre postering for en avsluttet periode!',
+  'Confirm!'                    => 'Bekreft!',
+  'Continue'                    => 'Fortsett',
+  'Credit'                      => 'Kredit',
+  'Customer not on file!'       => 'Kunde ikke i database!',
+  'Date'                        => 'Dato',
+  'Debit'                       => 'Debet',
+  'Debit and credit out of balance!' => 'Debet og kredit må være det samme!',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Fjern',
+  'Description'                 => 'Beskrivelse',
+  'Edit General Ledger Transaction' => 'Redigér en postering i hovedbok',
+  'Equity'                      => 'Egenkapital',
+  'Expense'                     => 'Utgift',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'Postering i hovedbok',
+  'General Ledger'              => 'Hovedbok',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Income'                      => 'Inntekt',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Liability'                   => 'Passiv',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'mai',
+  'May '                        => 'mai ',
+  'Notes'                       => 'Bemerkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Post'                        => 'Bokfør',
+  'Post as new'                 => 'Bokfør som ny',
+  'Project'                     => 'Prosjekt',
+  'Project not on file!'        => 'Prosjekt er ikke i database!',
+  'Purchase Invoice'            => 'Innkjøpsfaktura',
+  'Reference'                   => 'Referanse',
+  'Reference missing!'          => 'Referanser mangler!',
+  'Reports'                     => 'Rapporter',
+  'Sales Invoice'               => 'Salgsfaktura',
+  'Select from one of the names below' => 'Velg fra et av navnene under',
+  'Select from one of the projects below' => 'Velg fra et av prosjektene under',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Source'                      => 'Bilag',
+  'Subtotal'                    => 'Subtotal',
+  'Transaction Date missing!'   => 'Transaksjonsdato mangler!',
+  'Transaction deleted!'        => 'Postering slettet!',
+  'Transaction posted!'         => 'Postering bokført!',
+  'Update'                      => 'Oppdatér',
+  'Vendor not on file!'         => 'Leverandør er ikke i database!',
+  'Yes'                         => 'Ja',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'leverandørfaktura'           => 'ap_transaction',
+  'debitorpostering'            => 'ar_transaction',
+  'fortsett'                    => 'continue',
+  'fjern'                       => 'delete',
+  'postering_i_hovedbok'        => 'gl_transaction',
+  'bokfør'                      => 'post',
+  'bokfør_som_ny'               => 'post_as_new',
+  'innkjøpsfaktura'             => 'purchase_invoice',
+  'salgsfaktura'                => 'sales_invoice',
+  'oppdatér'                    => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/no/ic b/sql-ledger/locale/no/ic
new file mode 100644 (file)
index 0000000..37c9015
--- /dev/null
@@ -0,0 +1,206 @@
+$self{texts} = {
+  'Active'                      => 'Aktiv',
+  'Add'                         => 'Legg til',
+  'Add Assembly'                => 'Ny sammensetting',
+  'Add Part'                    => 'Ny vare',
+  'Add Purchase Order'          => 'Ny innkjøpsordre',
+  'Add Sales Order'             => 'Ny salgsordre',
+  'Add Service'                 => 'Ny tjeneste',
+  'Address'                     => 'Adresse',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Assemblies'                  => 'Sammensettinger',
+  'Assemblies restocked!'       => 'Sammensettinger omplassert!',
+  'Assembly Number missing!'    => 'Sammensettingsnummer mangler!',
+  'Attachment'                  => 'Vedlegg',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Blind kopi',
+  'Bin'                         => 'Papirkurv',
+  'Bought'                      => 'Kjøpt',
+  'COGS'                        => 'Innkjøp',
+  'Cannot delete item already invoiced!' => 'Kan ikke slette allerede fakturert enkeltdel!',
+  'Cannot delete item on order!' => 'Kan ikke slette enkeltdel i ordre!',
+  'Cannot delete item which is part of an assembly!' => 'kan ikke slette en enhet som er en del av en sammensetting!',
+  'Cannot delete item!'         => 'Kan ikke slette enkeltdel!',
+  'Cannot stock assemblies!'    => 'Kan ikke plasere sammensetninger!',
+  'Cc'                          => 'Kopi til',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsett',
+  'Copies'                      => 'Kopier',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Fjern',
+  'Delivery Date'               => 'Leveringsdato',
+  'Description'                 => 'Beskrivelse',
+  'Drawing'                     => 'Tegning',
+  'E-mail'                      => 'E-post',
+  'E-mail address missing!'     => 'E-post-adresse mangler!',
+  'Edit Assembly'               => 'Redigér sammensetting',
+  'Edit Part'                   => 'Redigér vare',
+  'Edit Service'                => 'Redigér tjeneste',
+  'Expense'                     => 'Utgift',
+  'Extended'                    => 'Utvigt',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'Image'                       => 'Bilde',
+  'In-line'                     => 'Inne i',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Income'                      => 'Inntekt',
+  'Individual Items'            => 'Individuelle enheter',
+  'Inventory'                   => 'Artikler',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Lagerbeholdning må være null for at du kan sette denne sammensetting som foreldet!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Lagerbeholdning må være null for at du kan sette denne enhet som foreldet!',
+  'Inventory quantity must be zero!' => 'Lagerbeholdning må være null!',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Item deleted!'               => 'Enkeltdel slettet!',
+  'Item not on file!'           => 'Enkeltdel er ikke i databasen!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Last Cost'                   => 'Seneste pris',
+  'Line Total'                  => 'Antall linjer',
+  'Link Accounts'               => 'Kople kontoer',
+  'List Price'                  => 'Listepris',
+  'Make'                        => 'Fabrikat',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'mai',
+  'May '                        => 'mai ',
+  'Message'                     => 'Melding',
+  'Microfiche'                  => 'Mikrofilm',
+  'Model'                       => 'Modell',
+  'Name'                        => 'Navn',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Bemerkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Tall mangler i rad',
+  'Obsolete'                    => 'Foreldet',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'On Hand'                     => 'På lager',
+  'On Order'                    => 'I ordre',
+  'Order'                       => 'Ordre',
+  'Order Date missing!'         => 'Ordredato mangler!',
+  'Order Number'                => 'Ordrenummer',
+  'Order Number missing!'       => 'Ordrenummer mangler!',
+  'Ordered'                     => 'Ordrer',
+  'Orphaned'                    => 'Frittstående',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Følgeseddel',
+  'Packing List Date missing!'  => 'Dato for pakkeliste mangler!',
+  'Packing List Number missing!' => 'Nummer for pakkeliste mangler!',
+  'Part'                        => 'Vare',
+  'Part Number missing!'        => 'Varenummer mangler!',
+  'Parts'                       => 'Deler',
+  'Phone'                       => 'Tel',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Prosjekt',
+  'Purchase Order'              => 'Innkjøpsordre',
+  'Qty'                         => 'Antall',
+  'ROP'                         => 'Etterbestill ved',
+  'Recd'                        => 'Mottatt',
+  'Required by'                 => 'Bestilt av',
+  'Sales'                       => 'Salg',
+  'Sales Order'                 => 'Salgsordre',
+  'Save'                        => 'Lagre',
+  'Screen'                      => 'Skjerm',
+  'Select from one of the items below' => 'Velg en fra listen under, og trykk "Fortsett"',
+  'Select postscript or PDF!'   => 'Velg postscript eller PDF!',
+  'Sell Price'                  => 'Salgspris',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Tjeneste',
+  'Service Number missing!'     => 'Tjenestenummer mangler!',
+  'Services'                    => 'Tjenester',
+  'Ship'                        => 'Avsend',
+  'Ship to'                     => 'Avsend til',
+  'Short'                       => 'Kort',
+  'Sold'                        => 'Solgt',
+  'Stock Assembly'              => 'Lagersammensetting',
+  'Subject'                     => 'Emne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Avgift/mva',
+  'To'                          => 'Til',
+  'Top Level'                   => 'Toppnivå',
+  'Total'                       => 'I alt',
+  'Unit'                        => 'Enhet',
+  'Unit of measure'             => 'Måleenhet',
+  'Update'                      => 'Oppdatér',
+  'Updated'                     => 'Oppdateret',
+  'Weight'                      => 'Vekt',
+  'What type of item is this?'  => 'Hvilken type ting er dette?',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendt på epost til',
+  'hr'                          => 'time',
+  'sent to printer'             => 'sendt til skriver',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'legg_til'                    => 'add',
+  'ny_sammensetting'            => 'add_assembly',
+  'ny_vare'                     => 'add_part',
+  'ny_tjeneste'                 => 'add_service',
+  'fortsett'                    => 'continue',
+  'fjern'                       => 'delete',
+  'redigér_sammensetting'       => 'edit_assembly',
+  'redigér_vare'                => 'edit_part',
+  'redigér_tjeneste'            => 'edit_service',
+  'lagre'                       => 'save',
+  'oppdatér'                    => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/no/io b/sql-ledger/locale/no/io
new file mode 100644 (file)
index 0000000..064657b
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Ny innkjøpsordre',
+  'Add Sales Order'             => 'Ny salgsordre',
+  'Address'                     => 'Adresse',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Attachment'                  => 'Vedlegg',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Bcc'                         => 'Blind kopi',
+  'Bin'                         => 'Papirkurv',
+  'Cc'                          => 'Kopi til',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsett',
+  'Copies'                      => 'Kopier',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delivery Date'               => 'Leveringsdato',
+  'Description'                 => 'Beskrivelse',
+  'E-mail'                      => 'E-post',
+  'E-mail address missing!'     => 'E-post-adresse mangler!',
+  'Extended'                    => 'Utvigt',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'In-line'                     => 'Inne i',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Item not on file!'           => 'Enkeltdel er ikke i databasen!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'mai',
+  'May '                        => 'mai ',
+  'Message'                     => 'Melding',
+  'Name'                        => 'Navn',
+  'No.'                         => 'Nr.',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Tall mangler i rad',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Order'                       => 'Ordre',
+  'Order Date missing!'         => 'Ordredato mangler!',
+  'Order Number missing!'       => 'Ordrenummer mangler!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Følgeseddel',
+  'Packing List Date missing!'  => 'Dato for pakkeliste mangler!',
+  'Packing List Number missing!' => 'Nummer for pakkeliste mangler!',
+  'Part'                        => 'Vare',
+  'Phone'                       => 'Tel',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Prosjekt',
+  'Purchase Order'              => 'Innkjøpsordre',
+  'Qty'                         => 'Antall',
+  'Recd'                        => 'Mottatt',
+  'Required by'                 => 'Bestilt av',
+  'Sales Order'                 => 'Salgsordre',
+  'Screen'                      => 'Skjerm',
+  'Select from one of the items below' => 'Velg en fra listen under, og trykk "Fortsett"',
+  'Select postscript or PDF!'   => 'Velg postscript eller PDF!',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Tjeneste',
+  'Ship'                        => 'Avsend',
+  'Ship to'                     => 'Avsend til',
+  'Subject'                     => 'Emne',
+  'To'                          => 'Til',
+  'Unit'                        => 'Enhet',
+  'What type of item is this?'  => 'Hvilken type ting er dette?',
+  'emailed to'                  => 'sendt på epost til',
+  'sent to printer'             => 'sendt til skriver',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'fortsett'                    => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/no/ir b/sql-ledger/locale/no/ir
new file mode 100644 (file)
index 0000000..ab755ba
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Add Purchase Invoice'        => 'Ny innkjøpsfaktura',
+  'Add Purchase Order'          => 'Ny innkjøpsordre',
+  'Add Sales Order'             => 'Ny salgsordre',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Beløp',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Invoice Number' => 'Er du sikker på at du vil fjerne fakturanummer',
+  'Attachment'                  => 'Vedlegg',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Bcc'                         => 'Blind kopi',
+  'Bin'                         => 'Papirkurv',
+  'Cannot delete invoice!'      => 'Kan ikke slette faktura!',
+  'Cannot post invoice for a closed period!' => 'Kan ikke bokføre faktura for en avsluttet periode!',
+  'Cannot post invoice!'        => 'Kan ikke bokføre faktura!',
+  'Cannot post payment for a closed period!' => 'Kan ikke bokføre betaling for en avsluttet periode!',
+  'Cc'                          => 'Kopi til',
+  'Confirm!'                    => 'Bekreft!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsett',
+  'Copies'                      => 'Kopier',
+  'Currency'                    => 'Valuta',
+  'Customer not on file!'       => 'Kunde ikke i database!',
+  'Date'                        => 'Dato',
+  'Date Due'                    => 'Forfallsdato',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Fjern',
+  'Delivery Date'               => 'Leveringsdato',
+  'Description'                 => 'Beskrivelse',
+  'E-mail'                      => 'E-post',
+  'E-mail address missing!'     => 'E-post-adresse mangler!',
+  'Edit Purchase Invoice'       => 'Redigér innkjøpsfaktura',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Vekslingskurs',
+  'Exchangerate for payment missing!' => 'Vekslingskurs for betaling mangler!',
+  'Exchangerate missing!'       => 'Vekslingskurs mangler!',
+  'Extended'                    => 'Utvigt',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'In-line'                     => 'Inne i',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadato',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Invoice deleted!'            => 'Faktura slettet!',
+  'Invoice posted!'             => 'Faktura bokført!',
+  'Item not on file!'           => 'Enkeltdel er ikke i databasen!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'mai',
+  'May '                        => 'mai ',
+  'Message'                     => 'Melding',
+  'Name'                        => 'Navn',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Bemerkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Tall mangler i rad',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Order'                       => 'Ordre',
+  'Order Date missing!'         => 'Ordredato mangler!',
+  'Order Number'                => 'Ordrenummer',
+  'Order Number missing!'       => 'Ordrenummer mangler!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Følgeseddel',
+  'Packing List Date missing!'  => 'Dato for pakkeliste mangler!',
+  'Packing List Number missing!' => 'Nummer for pakkeliste mangler!',
+  'Part'                        => 'Vare',
+  'Payment date missing!'       => 'Betalingsdato mangler!',
+  'Payments'                    => 'Utbetaling',
+  'Phone'                       => 'Tel',
+  'Post'                        => 'Bokfør',
+  'Post as new'                 => 'Bokfør som ny',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Prosjekt',
+  'Project not on file!'        => 'Prosjekt er ikke i database!',
+  'Purchase Order'              => 'Innkjøpsordre',
+  'Qty'                         => 'Antall',
+  'Recd'                        => 'Mottatt',
+  'Record in'                   => 'Bokfør på',
+  'Required by'                 => 'Bestilt av',
+  'Sales Order'                 => 'Salgsordre',
+  'Screen'                      => 'Skjerm',
+  'Select from one of the items below' => 'Velg en fra listen under, og trykk "Fortsett"',
+  'Select from one of the names below' => 'Velg fra et av navnene under',
+  'Select from one of the projects below' => 'Velg fra et av prosjektene under',
+  'Select postscript or PDF!'   => 'Velg postscript eller PDF!',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Tjeneste',
+  'Ship'                        => 'Avsend',
+  'Ship to'                     => 'Avsend til',
+  'Source'                      => 'Bilag',
+  'Subject'                     => 'Emne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Inkl. avgifter og mva',
+  'To'                          => 'Til',
+  'Total'                       => 'I alt',
+  'Unit'                        => 'Enhet',
+  'Update'                      => 'Oppdatér',
+  'Vendor'                      => 'Leverandør',
+  'Vendor missing!'             => 'Leverandør mangler!',
+  'Vendor not on file!'         => 'Leverandør er ikke i database!',
+  'What type of item is this?'  => 'Hvilken type ting er dette?',
+  'Yes'                         => 'Ja',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendt på epost til',
+  'sent to printer'             => 'sendt til skriver',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'fortsett'                    => 'continue',
+  'fjern'                       => 'delete',
+  'ordre'                       => 'order',
+  'bokfør'                      => 'post',
+  'bokfør_som_ny'               => 'post_as_new',
+  'oppdatér'                    => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/no/is b/sql-ledger/locale/no/is
new file mode 100644 (file)
index 0000000..47f3222
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Add Purchase Order'          => 'Ny innkjøpsordre',
+  'Add Sales Invoice'           => 'Ny salgsfaktura',
+  'Add Sales Order'             => 'Ny salgsordre',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Beløp',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Invoice Number' => 'Er du sikker på at du vil fjerne fakturanummer',
+  'Attachment'                  => 'Vedlegg',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Bcc'                         => 'Blind kopi',
+  'Bin'                         => 'Papirkurv',
+  'Cannot delete invoice!'      => 'Kan ikke slette faktura!',
+  'Cannot post invoice for a closed period!' => 'Kan ikke bokføre faktura for en avsluttet periode!',
+  'Cannot post invoice!'        => 'Kan ikke bokføre faktura!',
+  'Cannot post payment for a closed period!' => 'Kan ikke bokføre betaling for en avsluttet periode!',
+  'Cc'                          => 'Kopi til',
+  'Confirm!'                    => 'Bekreft!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsett',
+  'Copies'                      => 'Kopier',
+  'Credit Limit'                => 'Kreditgrense',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Kunde',
+  'Customer missing!'           => 'Kunde mangler!',
+  'Customer not on file!'       => 'Kunde ikke i database!',
+  'Date'                        => 'Dato',
+  'Date Due'                    => 'Forfallsdato',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Fjern',
+  'Delivery Date'               => 'Leveringsdato',
+  'Description'                 => 'Beskrivelse',
+  'E-mail'                      => 'E-post',
+  'E-mail address missing!'     => 'E-post-adresse mangler!',
+  'Edit Sales Invoice'          => 'Redigér salgsfaktura',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Vekslingskurs',
+  'Exchangerate for payment missing!' => 'Vekslingskurs for betaling mangler!',
+  'Exchangerate missing!'       => 'Vekslingskurs mangler!',
+  'Extended'                    => 'Utvigt',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'In-line'                     => 'Inne i',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadato',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Invoice deleted!'            => 'Faktura slettet!',
+  'Invoice posted!'             => 'Faktura bokført!',
+  'Item not on file!'           => 'Enkeltdel er ikke i databasen!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'mai',
+  'May '                        => 'mai ',
+  'Message'                     => 'Melding',
+  'Name'                        => 'Navn',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Bemerkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Tall mangler i rad',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Order'                       => 'Ordre',
+  'Order Date missing!'         => 'Ordredato mangler!',
+  'Order Number'                => 'Ordrenummer',
+  'Order Number missing!'       => 'Ordrenummer mangler!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Følgeseddel',
+  'Packing List Date missing!'  => 'Dato for pakkeliste mangler!',
+  'Packing List Number missing!' => 'Nummer for pakkeliste mangler!',
+  'Part'                        => 'Vare',
+  'Payment date missing!'       => 'Betalingsdato mangler!',
+  'Payments'                    => 'Utbetaling',
+  'Phone'                       => 'Tel',
+  'Post'                        => 'Bokfør',
+  'Post as new'                 => 'Bokfør som ny',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Print'                       => 'Skriv ut',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Prosjekt',
+  'Project not on file!'        => 'Prosjekt er ikke i database!',
+  'Purchase Order'              => 'Innkjøpsordre',
+  'Qty'                         => 'Antall',
+  'Recd'                        => 'Mottatt',
+  'Record in'                   => 'Bokfør på',
+  'Remaining'                   => 'Resterende',
+  'Required by'                 => 'Bestilt av',
+  'Sales Order'                 => 'Salgsordre',
+  'Screen'                      => 'Skjerm',
+  'Select from one of the items below' => 'Velg en fra listen under, og trykk "Fortsett"',
+  'Select from one of the names below' => 'Velg fra et av navnene under',
+  'Select from one of the projects below' => 'Velg fra et av prosjektene under',
+  'Select postscript or PDF!'   => 'Velg postscript eller PDF!',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Tjeneste',
+  'Ship'                        => 'Avsend',
+  'Ship to'                     => 'Avsend til',
+  'Ship via'                    => 'Avsend via',
+  'Source'                      => 'Bilag',
+  'Subject'                     => 'Emne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Inkl. avgifter og mva',
+  'To'                          => 'Til',
+  'Total'                       => 'I alt',
+  'Unit'                        => 'Enhet',
+  'Update'                      => 'Oppdatér',
+  'Vendor not on file!'         => 'Leverandør er ikke i database!',
+  'What type of item is this?'  => 'Hvilken type ting er dette?',
+  'Yes'                         => 'Ja',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendt på epost til',
+  'sent to printer'             => 'sendt til skriver',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'fortsett'                    => 'continue',
+  'fjern'                       => 'delete',
+  'e_post'                      => 'e_mail',
+  'ordre'                       => 'order',
+  'bokfør'                      => 'post',
+  'bokfør_som_ny'               => 'post_as_new',
+  'skriv_ut'                    => 'print',
+  'avsend_til'                  => 'ship_to',
+  'oppdatér'                    => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/no/login b/sql-ledger/locale/no/login
new file mode 100644 (file)
index 0000000..742ef4a
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'Om',
+  'Database Host'               => 'Database-vert',
+  'Dataset'                     => 'Datasett',
+  'Incorrect Dataset version!'  => 'Gal versjon av datasett!',
+  'Incorrect Password!'         => 'Galt passord!',
+  'Licensed to'                 => 'Utført for',
+  'Login'                       => 'Login',
+  'Name'                        => 'Navn',
+  'Password'                    => 'Passord',
+  'User'                        => 'Bruker',
+  'Version'                     => 'Versjon',
+  'You are logged out!'         => 'Du er logget av!',
+  'You did not enter a name!'   => 'Du gav ikke et navn!',
+  'is not a member!'            => 'er ikke et medlem!',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'login'                       => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/no/menu b/sql-ledger/locale/no/menu
new file mode 100644 (file)
index 0000000..f8f95a0
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => 'Kreditorer',
+  'AP Aging'                    => 'Aldersfordeling',
+  'AR'                          => 'Debitorer',
+  'AR Aging'                    => 'Aldersfordeling',
+  'Accounting Menu'             => 'Konto-meny',
+  'Add Account'                 => 'Ny konto',
+  'Add Assembly'                => 'Ny sammensetting',
+  'Add Customer'                => 'Ny kunde',
+  'Add GIFI'                    => 'Ny GIFI',
+  'Add Part'                    => 'Ny vare',
+  'Add Project'                 => 'Nytt prosjekt',
+  'Add Service'                 => 'Ny tjeneste',
+  'Add Transaction'             => 'Ny postering',
+  'Add Vendor'                  => 'Ny leverandør',
+  'Assemblies'                  => 'Sammensettinger',
+  'Audit Control'               => 'Revisjonskontroll',
+  'Backup'                      => 'Sikkerhetskopi',
+  'Balance Sheet'               => 'Status',
+  'Cash'                        => 'Bank',
+  'Chart of Accounts'           => 'Kontoplan',
+  'Check'                       => 'Sjekk',
+  'Customers'                   => 'Kunder',
+  'General Ledger'              => 'Hovedbok',
+  'Goods & Services'            => 'Varer og tjenester',
+  'HTML Templates'              => 'HTML-maler',
+  'Income Statement'            => 'Driftsregnskap',
+  'Invoice'                     => 'Faktura',
+  'LaTeX Templates'             => 'LaTeX-maler',
+  'List Accounts'               => 'List kontoer',
+  'List GIFI'                   => 'List GIFI',
+  'Logout'                      => 'Log ut',
+  'Order Entry'                 => 'Ordreinngang',
+  'Packing List'                => 'Følgeseddel',
+  'Parts'                       => 'Deler',
+  'Payment'                     => 'Betaling',
+  'Payments'                    => 'Utbetaling',
+  'Preferences'                 => 'Innstillinger',
+  'Projects'                    => 'Prosjekter',
+  'Purchase Invoice'            => 'Innkjøpsfaktura',
+  'Purchase Order'              => 'Innkjøpsordre',
+  'Purchase Orders'             => 'Innkjøpsordrer',
+  'Receipt'                     => 'Kvittering',
+  'Receipts'                    => 'Kvitteringer',
+  'Reconciliation'              => 'Bankoppgjør',
+  'Reports'                     => 'Rapporter',
+  'Sales Invoice'               => 'Salgsfaktura',
+  'Sales Order'                 => 'Salgsordre',
+  'Sales Orders'                => 'Salgsordrer',
+  'Save to File'                => 'Lagre i fil',
+  'Send by E-Mail'              => 'Sendt per email',
+  'Services'                    => 'Tjenester',
+  'Statement'                   => 'Oppgjør',
+  'Stock Assembly'              => 'Lagersammensetting',
+  'Stylesheet'                  => 'Stílark',
+  'System'                      => 'System',
+  'Tax collected'               => 'Inngående avgift',
+  'Tax paid'                    => 'Betalt avgift',
+  'Transactions'                => 'Posteringer',
+  'Trial Balance'               => 'Foreløpig status',
+  'Vendors'                     => 'Leverandører',
+  'Version'                     => 'Versjon',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/no/oe b/sql-ledger/locale/no/oe
new file mode 100644 (file)
index 0000000..efadfa6
--- /dev/null
@@ -0,0 +1,200 @@
+$self{texts} = {
+  'Add'                         => 'Legg til',
+  'Add Purchase Invoice'        => 'Ny innkjøpsfaktura',
+  'Add Purchase Order'          => 'Ny innkjøpsordre',
+  'Add Sales Invoice'           => 'Ny salgsfaktura',
+  'Add Sales Order'             => 'Ny salgsordre',
+  'Address'                     => 'Adresse',
+  'Amount'                      => 'Beløp',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Order Number' => 'Er du sikker på at du vil fjerne ordrenummer',
+  'Attachment'                  => 'Vedlegg',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Bcc'                         => 'Blind kopi',
+  'Bin'                         => 'Papirkurv',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Kan ikke slette ordre!',
+  'Cannot save order!'          => 'Kan ikke lagre ordre!',
+  'Cc'                          => 'Kopi til',
+  'Closed'                      => 'Avsluttet',
+  'Confirm!'                    => 'Bekreft!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsett',
+  'Copies'                      => 'Kopier',
+  'Credit Limit'                => 'Kreditgrense',
+  'Curr'                        => 'Val',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Kunde',
+  'Customer missing!'           => 'Kunde mangler!',
+  'Customer not on file!'       => 'Kunde ikke i database!',
+  'Date'                        => 'Dato',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Delete'                      => 'Fjern',
+  'Delivery Date'               => 'Leveringsdato',
+  'Description'                 => 'Beskrivelse',
+  'E-mail'                      => 'E-post',
+  'E-mail address missing!'     => 'E-post-adresse mangler!',
+  'Edit Purchase Order'         => 'Redigér innkjøpsordre',
+  'Edit Sales Order'            => 'Redigér salgsordre',
+  'Exchangerate'                => 'Vekslingskurs',
+  'Exchangerate missing!'       => 'Vekslingskurs mangler!',
+  'Extended'                    => 'Utvigt',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Inne i',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Fakturadato mangler!',
+  'Invoice Number missing!'     => 'Fakturanummer mangler!',
+  'Item not on file!'           => 'Enkeltdel er ikke i databasen!',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'mai',
+  'May '                        => 'mai ',
+  'Message'                     => 'Melding',
+  'Name'                        => 'Navn',
+  'No.'                         => 'Nr.',
+  'Notes'                       => 'Bemerkninger',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Tall mangler i rad',
+  'O'                           => 'O',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'Open'                        => 'Åpne',
+  'Order'                       => 'Ordre',
+  'Order Date'                  => 'Ordredato',
+  'Order Date missing!'         => 'Ordredato mangler!',
+  'Order Number'                => 'Ordrenummer',
+  'Order Number missing!'       => 'Ordrenummer mangler!',
+  'Order deleted!'              => 'Ordre slettet!',
+  'Order saved!'                => 'Ordre lagret!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Følgeseddel',
+  'Packing List Date missing!'  => 'Dato for pakkeliste mangler!',
+  'Packing List Number missing!' => 'Nummer for pakkeliste mangler!',
+  'Part'                        => 'Vare',
+  'Phone'                       => 'Tel',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Print'                       => 'Skriv ut',
+  'Printer'                     => 'Printer',
+  'Project'                     => 'Prosjekt',
+  'Project not on file!'        => 'Prosjekt er ikke i database!',
+  'Purchase Order'              => 'Innkjøpsordre',
+  'Purchase Orders'             => 'Innkjøpsordrer',
+  'Qty'                         => 'Antall',
+  'Recd'                        => 'Mottatt',
+  'Remaining'                   => 'Resterende',
+  'Required by'                 => 'Bestilt av',
+  'Sales Order'                 => 'Salgsordre',
+  'Sales Orders'                => 'Salgsordrer',
+  'Save'                        => 'Lagre',
+  'Save as new'                 => 'Lagre som ny',
+  'Screen'                      => 'Skjerm',
+  'Select from one of the items below' => 'Velg en fra listen under, og trykk "Fortsett"',
+  'Select from one of the names below' => 'Velg fra et av navnene under',
+  'Select from one of the projects below' => 'Velg fra et av prosjektene under',
+  'Select postscript or PDF!'   => 'Velg postscript eller PDF!',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Service'                     => 'Tjeneste',
+  'Ship'                        => 'Avsend',
+  'Ship to'                     => 'Avsend til',
+  'Ship via'                    => 'Avsend via',
+  'Subject'                     => 'Emne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Avgift/mva',
+  'Tax Included'                => 'Inkl. avgifter og mva',
+  'Terms: Net'                  => 'Netto',
+  'To'                          => 'Til',
+  'Total'                       => 'I alt',
+  'Unit'                        => 'Enhet',
+  'Update'                      => 'Oppdatér',
+  'Vendor'                      => 'Leverandør',
+  'Vendor missing!'             => 'Leverandør mangler!',
+  'Vendor not on file!'         => 'Leverandør er ikke i database!',
+  'What type of item is this?'  => 'Hvilken type ting er dette?',
+  'Yes'                         => 'Ja',
+  'days'                        => 'dager',
+  'ea'                          => 'stk',
+  'emailed to'                  => 'sendt på epost til',
+  'sent to printer'             => 'sendt til skriver',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'legg_til'                    => 'add',
+  'fortsett'                    => 'continue',
+  'fjern'                       => 'delete',
+  'e_post'                      => 'e_mail',
+  'faktura'                     => 'invoice',
+  'skriv_ut'                    => 'print',
+  'lagre'                       => 'save',
+  'lagre_som_ny'                => 'save_as_new',
+  'avsend_til'                  => 'ship_to',
+  'oppdatér'                    => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/no/pe b/sql-ledger/locale/no/pe
new file mode 100644 (file)
index 0000000..95a1fa2
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Legg til',
+  'Add Project'                 => 'Nytt prosjekt',
+  'All'                         => 'Alle',
+  'Continue'                    => 'Fortsett',
+  'Delete'                      => 'Fjern',
+  'Description'                 => 'Beskrivelse',
+  'Edit Project'                => 'Redigér prosjekt',
+  'Number'                      => 'Nummer',
+  'Orphaned'                    => 'Frittstående',
+  'Project'                     => 'Prosjekt',
+  'Project Number missing!'     => 'Prosjektnummer mangler!',
+  'Project deleted!'            => 'Prosjekt slettet!',
+  'Project saved!'              => 'Prosjekt lagret!',
+  'Projects'                    => 'Prosjekter',
+  'Save'                        => 'Lagre',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'legg_til'                    => 'add',
+  'fortsett'                    => 'continue',
+  'fjern'                       => 'delete',
+  'lagre'                       => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/no/rc b/sql-ledger/locale/no/rc
new file mode 100644 (file)
index 0000000..4ff2cc8
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Balance'                     => 'Balanse',
+  'Cleared Balance'             => 'Utlignet balanse',
+  'Continue'                    => 'Fortsett',
+  'Date'                        => 'Dato',
+  'Deposit'                     => 'Depositum',
+  'Description'                 => 'Beskrivelse',
+  'Difference'                  => 'Forskjell',
+  'Done'                        => 'Ferdig',
+  'Exchangerate Difference'     => 'Forskjell på vekslingskurs',
+  'From'                        => 'Fra',
+  'Out of balance!'             => 'Ute av balanse!',
+  'Payment'                     => 'Betaling',
+  'Reconciliation'              => 'Bankoppgjør',
+  'Select all'                  => 'Velg alt',
+  'Source'                      => 'Bilag',
+  'Statement Balance'           => 'Balanseoppgjør',
+  'Update'                      => 'Oppdatér',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'fortsett'                    => 'continue',
+  'ferdig'                      => 'done',
+  'velg_alt'                    => 'select_all',
+  'oppdatér'                    => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/no/rp b/sql-ledger/locale/no/rp
new file mode 100644 (file)
index 0000000..3592fd1
--- /dev/null
@@ -0,0 +1,120 @@
+$self{texts} = {
+  'AP Aging'                    => 'Aldersfordeling',
+  'AR Aging'                    => 'Aldersfordeling',
+  'Account'                     => 'Konto',
+  'Accounts'                    => 'Kontoer',
+  'Amount'                      => 'Beløp',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Attachment'                  => 'Vedlegg',
+  'Aug'                         => 'aug',
+  'August'                      => 'august',
+  'Balance'                     => 'Balanse',
+  'Balance Sheet'               => 'Status',
+  'Bcc'                         => 'Blind kopi',
+  'Cash based'                  => 'Bank basert',
+  'Cc'                          => 'Kopi til',
+  'Compare to'                  => 'Sammenlign med',
+  'Continue'                    => 'Fortsett',
+  'Copies'                      => 'Kopier',
+  'Credit'                      => 'Kredit',
+  'Current'                     => 'Nåværende',
+  'Customer'                    => 'Kunde',
+  'Date'                        => 'Dato',
+  'Debit'                       => 'Debet',
+  'Dec'                         => 'des',
+  'December'                    => 'desember',
+  'Decimalplaces'               => 'Desimalplasser',
+  'Department'                  => 'Avdeling',
+  'Description'                 => 'Beskrivelse',
+  'Due'                         => 'Forfall',
+  'E-mail'                      => 'E-post',
+  'E-mail Statement to'         => 'Send oppgjør til',
+  'Feb'                         => 'feb',
+  'February'                    => 'februar',
+  'From'                        => 'Fra',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Overskrift',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Inne i',
+  'Include in Report'           => 'Inkludér i rapport',
+  'Income Statement'            => 'Driftsregnskap',
+  'Invoice'                     => 'Faktura',
+  'Jan'                         => 'jan',
+  'January'                     => 'januar',
+  'Jul'                         => 'jul',
+  'July'                        => 'juli',
+  'Jun'                         => 'jun',
+  'June'                        => 'juni',
+  'Mar'                         => 'mar',
+  'March'                       => 'mars',
+  'May'                         => 'mai',
+  'May '                        => 'mai ',
+  'Message'                     => 'Melding',
+  'N/A'                         => 'I/T',
+  'Nothing selected!'           => 'Ingenting valgt!',
+  'Nov'                         => 'nov',
+  'November'                    => 'november',
+  'Oct'                         => 'okt',
+  'October'                     => 'oktober',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Utbetaling',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Skriv ut',
+  'Printer'                     => 'Printer',
+  'Project Number'              => 'Prosjektnummer',
+  'Receipts'                    => 'Kvitteringer',
+  'Report for'                  => 'Rapport for',
+  'Retained Earnings'           => 'Realisert overskudd',
+  'Screen'                      => 'Skjerm',
+  'Select all'                  => 'Velg alt',
+  'Select postscript or PDF!'   => 'Velg postscript eller PDF!',
+  'Sep'                         => 'sep',
+  'September'                   => 'september',
+  'Source'                      => 'Bilag',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Oppgjør',
+  'Statement sent to'           => 'Oppgjør sendt til',
+  'Statements sent to printer!' => 'Oppgjør sendt til skriver!',
+  'Subject'                     => 'Emne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Avgift/mva',
+  'Tax collected'               => 'Inngående avgift',
+  'Tax paid'                    => 'Betalt avgift',
+  'Total'                       => 'I alt',
+  'Trial Balance'               => 'Foreløpig status',
+  'Vendor'                      => 'Leverandør',
+  'as at'                       => 'som ved',
+  'collected on sales'          => 'innbetalt på salg',
+  'for Period'                  => 'for periode',
+  'paid on purchases'           => 'betalt på kjøp',
+  'to'                          => 'til',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_accounts'               => 'list_accounts',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'fortsett'                    => 'continue',
+  'e_post'                      => 'e_mail',
+  'skriv_ut'                    => 'print',
+  'velg_alt'                    => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/COPYING b/sql-ledger/locale/pa/COPYING
new file mode 100644 (file)
index 0000000..44b6a93
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Spanish texts:
+#
+#  Author: Maria Gabriela Fong <mgfong@maga.tzo.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/pa/LANGUAGE b/sql-ledger/locale/pa/LANGUAGE
new file mode 100644 (file)
index 0000000..012de50
--- /dev/null
@@ -0,0 +1 @@
+Panamanian Spanish
diff --git a/sql-ledger/locale/pa/admin b/sql-ledger/locale/pa/admin
new file mode 100644 (file)
index 0000000..1e69b26
--- /dev/null
@@ -0,0 +1,128 @@
+$self{texts} = {
+  'Access Control'              => 'Control de Acceso',
+  'Accounting'                  => 'Contabilidad',
+  'Add User'                    => 'Agregar Usuario',
+  'Address'                     => 'Dirección',
+  'Administration'              => 'Administración',
+  'Administrator'               => 'Administrator',
+  'All Datasets up to date!'    => 'Todos los datasets actualizados',
+  'Change Admin Password'       => 'Cambiar Contraseña de Administrador',
+  'Change Password'             => 'Cambiar Contraseña',
+  'Character Set'               => 'Tabla de Caracteres',
+  'Click on login name to edit!' => 'Haga clic en el nombre de entrada a
+editar',
+  'Company'                     => 'Compañía',
+  'Connect to'                  => 'Conectar a',
+  'Continue'                    => 'Continuar',
+  'Create Chart of Accounts'    => 'Crear catálogo de cuentas',
+  'Create Dataset'              => 'Crear set de datos',
+  'DBI not installed!'          => 'DBI no instalado!',
+  'Database'                    => 'Base de datos',
+  'Database Administration'     => 'Administración de base de datos',
+  'Database Driver not checked!' => 'Driver de base de datos no revisado',
+  'Database User missing!'      => 'No se encuentra usuario de base de datos',
+  'Dataset'                     => 'Set de datos',
+  'Dataset missing!'            => 'No se encuentra Set de datos!',
+  'Dataset updated!'            => 'Dataset updated!',
+  'Date Format'                 => 'Formato de Fecha',
+  'Delete'                      => 'Borrar',
+  'Delete Dataset'              => 'Borrar Set de Datos',
+  'Directory'                   => 'Directorio',
+  'Driver'                      => 'Manejador',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'Correo Electrónico',
+  'Edit User'                   => 'Editar Usuario',
+  'Existing Datasets'           => 'Sets de dato existentes',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Servidor base de datos',
+  'Hostname missing!'           => 'No se encuentra servidor de base de datos',
+  'Incorrect Password!'         => 'Contraseña Incorrecta!',
+  'Language'                    => 'Lenguaje',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Deje los campos de servidor de base de datos y puerto vacíos al menos que quiera hacer una conexión remota',
+  'Login'                       => 'Login',
+  'Name'                        => 'Nombre',
+  'New Templates'               => 'Nuevas Plantillas',
+  'No Database Drivers available!' => 'No hay manejador de base de datos
+disponible!',
+  'No Dataset selected!'        => 'No se ha seleccionado el set de datos',
+  'Nothing to delete!'          => 'Noda que borrar',
+  'Number Format'               => 'Formato de Numero',
+  'Oracle Database Administration' => 'Administración de base de datos Oracle',
+  'Password'                    => 'Contraseña',
+  'Password changed!'           => 'Password changed!',
+  'Pg Database Administration'  => 'Administración de base de datos Pg',
+  'Phone'                       => 'Teléfono',
+  'Port'                        => 'Puerto',
+  'Port missing!'               => 'No se encuentra el Puerto!',
+  'Printer'                     => 'Impresora',
+  'Save'                        => 'Salvar',
+  'Select a Dataset to delete and press "Continue"' => 'Seleccione un set de
+datos para borrar y presione "Continuar"',
+  'Setup Templates'             => 'Configurar Plantillas',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'Firma',
+  'Stylesheet'                  => 'Estilo de hoja',
+  'Templates'                   => 'Plantillas',
+  'The following Datasets are not in use and can be deleted' => 'Los
+siguientes sets de datos no estan en uso y pueden ser borrados',
+  'The following Datasets need to be updated' => 'Los siguientes datasets necesitan ser actualizados',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Esta es una verificacion preliminar de fuentes existentes.  Nada será creado o borrado en esta etapa!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Para agregar un usuario a un grupo, edite un nombre, cambie el nombre de entrada (login) y guarde los cambios.  Un nuevo usuario, con las mismas variables será guardado bajo el nuevo nombre de entrada. (login)',
+  'Update Dataset'              => 'Actualizar Dataset',
+  'Use Templates'               => 'Plantillas de Usuarios',
+  'User'                        => 'Usuario',
+  'User deleted!'               => 'User deleted!',
+  'User saved!'                 => 'User saved!',
+  'Version'                     => 'Versión',
+  'You must enter a host and port for local and remote connections!' => 'Debe
+introducir un servidor de base de datos y un puerto para conexiones locales y
+remotas!',
+  'does not exist'              => 'No existe',
+  'is already a member!'        => 'ya es miembro!',
+  'localhost'                   => 'servidor local',
+  'successfully created!'       => 'creado con éxito!',
+  'successfully deleted!'       => 'creado con éxito!',
+  'website'                     => 'sitio web',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'agregar_usuario'             => 'add_user',
+  'cambiar_contraseña_de_administrador' => 'change_admin_password',
+  'cambiar_contraseña'          => 'change_password',
+  'continuar'                   => 'continue',
+  'crear_set_de_datos'          => 'create_dataset',
+  'borrar'                      => 'delete',
+  'borrar_set_de_datos'         => 'delete_dataset',
+  'login'                       => 'login',
+  'administración_de_base_de_datos_oracle' => 'oracle_database_administration',
+  'administración_de_base_de_datos_pg' => 'pg_database_administration',
+  'salvar'                      => 'save',
+  'actualizar_dataset'          => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/all b/sql-ledger/locale/pa/all
new file mode 100644 (file)
index 0000000..2981a10
--- /dev/null
@@ -0,0 +1,496 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Ctas X Pagar',
+  'AP Aging'                    => 'Envejecimiento - CxP',
+  'AP Transaction'              => '',
+  'AP Transactions'             => 'Transacciones - Cuentas por Pagar',
+  'AR'                          => 'Ctas X Cobrar',
+  'AR Aging'                    => 'Envejecimiento - CxC ',
+  'AR Transaction'              => '',
+  'AR Transactions'             => 'Transacciones de Cuentas por Cobrar',
+  'About'                       => 'Acerca',
+  'Access Control'              => 'Control de Acceso',
+  'Account'                     => 'Cuenta',
+  'Account Number'              => 'Número de Cuenta',
+  'Account Number missing!'     => 'No existe el número de cuenta!',
+  'Account Type'                => 'Tipo de Cuenta',
+  'Account Type missing!'       => 'No existe el tipo de la cuenta!',
+  'Account deleted!'            => '',
+  'Account saved!'              => '',
+  'Accounting'                  => 'Contabilidad',
+  'Accounting Menu'             => 'Menú de Contabilidad',
+  'Accounts'                    => 'Cuentas',
+  'Active'                      => '',
+  'Add'                         => 'Agregar',
+  'Add Account'                 => 'Agregar Cuenta',
+  'Add Accounts Payables Transaction' => '',
+  'Add Accounts Receivables Transaction' => '',
+  'Add Assembly'                => 'Agregar Ensamblaje',
+  'Add Customer'                => 'Agregar Cliente',
+  'Add GIFI'                    => 'Agregar GIFI',
+  'Add General Ledger Transaction' => 'Agregar Transacción - Mayor General',
+  'Add Part'                    => 'Agregar Parte',
+  'Add Project'                 => '',
+  'Add Purchase Invoice'        => '',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Invoice'           => '',
+  'Add Sales Order'             => 'Agregar Orden de Venta',
+  'Add Service'                 => 'Agregar Servicio',
+  'Add Transaction'             => 'Agregar Transaccion',
+  'Add User'                    => 'Agregar Usuario',
+  'Add Vendor'                  => 'Agregar Proveedor',
+  'Address'                     => 'Dirección',
+  'Administration'              => 'Administración',
+  'Administrator'               => '',
+  'All'                         => 'Todos',
+  'All Datasets up to date!'    => 'Todos los datasets actualizados',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => '',
+  'Amount does not equal applied!' => '',
+  'Amount missing!'             => '',
+  'Applied'                     => '',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => '¿Esta seguro de que desea borrar la Factura No.:',
+  'Are you sure you want to delete Order Number' => '¿Esta seguro de que desea
+borrar la Orden No.:?',
+  'Are you sure you want to delete Transaction' => '¿Está usted seguro de que desea suprimir la transacción?',
+  'Assemblies'                  => 'Ensamblajes',
+  'Assemblies restocked!'       => '',
+  'Assembly Number missing!'    => 'No existe Numero de Ensamblaje!',
+  'Asset'                       => 'Activo',
+  'Attachment'                  => 'Adjunto',
+  'Audit Control'               => 'Control de Audito',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'BOM'                         => '',
+  'Backup'                      => 'Respaldar datos',
+  'Backup sent to'              => 'Respaldo enviado a',
+  'Balance'                     => '',
+  'Balance Sheet'               => 'Hoja de Balance',
+  'Bcc'                         => '',
+  'Bin'                         => 'Bin',
+  'Books are open'              => 'Libros estan abiertos',
+  'Bought'                      => 'Comprado',
+  'Business Number'             => 'Numero de Negocio',
+  'C'                           => '',
+  'COGS'                        => 'Costo de Ventas',
+  'Cannot delete account!'      => '',
+  'Cannot delete customer!'     => '',
+  'Cannot delete default account!' => 'No se puede borrar cuenta por defecto!',
+  'Cannot delete invoice!'      => '',
+  'Cannot delete item already invoiced!' => 'No puede suprimir el item ya facturado!',
+  'Cannot delete item on order!' => 'No se puede borrar el item ya en cotizacion',
+  'Cannot delete item which is part of an assembly!' => 'No puede suprimir un item que es parte de un ensamblaje!',
+  'Cannot delete item!'         => '',
+  'Cannot delete order!'        => '',
+  'Cannot delete transaction!'  => '',
+  'Cannot delete vendor!'       => '',
+  'Cannot have a value in both Debit and Credit!' => 'No puede tener un valor en Débito y Crédito simultáneamente!',
+  'Cannot post a transaction without a value!' => '',
+  'Cannot post invoice for a closed period!' => 'No se puede registrar factura para un periodo cerrado!',
+  'Cannot post invoice!'        => '',
+  'Cannot post payment for a closed period!' => 'No se puede registrar pago para un periodo cerrado',
+  'Cannot post payment!'        => '',
+  'Cannot post transaction for a closed period!' => 'No puede guardar transaccion para un periodo cerrado',
+  'Cannot post transaction!'    => '',
+  'Cannot process payment for a closed period!' => '',
+  'Cannot save account!'        => '',
+  'Cannot save order!'          => '',
+  'Cannot save preferences!'    => '',
+  'Cannot stock assemblies!'    => '',
+  'Cash'                        => '',
+  'Cash based'                  => '',
+  'Cc'                          => '',
+  'Change Admin Password'       => 'Cambiar Contraseña de Administrador',
+  'Change Password'             => 'Cambiar Contraseña',
+  'Character Set'               => 'Tabla de Caracteres',
+  'Chart of Accounts'           => 'Catálogo Contable',
+  'Check'                       => '',
+  'Check printed!'              => '',
+  'Check printing failed!'      => '',
+  'Cleared Balance'             => '',
+  'Click on login name to edit!' => 'Haga clic en el nombre de entrada a
+editar',
+  'Close Books up to'           => 'Cerrar libros hasta',
+  'Closed'                      => 'Cerrado',
+  'Company'                     => 'Compañía',
+  'Compare to'                  => 'Comparar a',
+  'Confirm!'                    => 'Confirmar!',
+  'Connect to'                  => 'Conectar a',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Copy to COA'                 => 'Copiar a catálogo de cuentas',
+  'Create Chart of Accounts'    => 'Crear catálogo de cuentas',
+  'Create Dataset'              => 'Crear set de datos',
+  'Credit'                      => 'Crédito',
+  'Credit Limit'                => 'Limite de Credito',
+  'Curr'                        => '$',
+  'Currency'                    => 'Moneda',
+  'Current'                     => '',
+  'Customer'                    => 'Cliente',
+  'Customer deleted!'           => '',
+  'Customer missing!'           => '',
+  'Customer not on file!'       => '',
+  'Customer saved!'             => '',
+  'Customers'                   => '',
+  'DBI not installed!'          => 'DBI no instalado!',
+  'Database'                    => 'Base de datos',
+  'Database Administration'     => 'Administración de base de datos',
+  'Database Driver not checked!' => 'Driver de base de datos no revisado',
+  'Database Host'               => 'Servidor de Base de Datos',
+  'Database User missing!'      => 'No se encuentra usuario de base de datos',
+  'Dataset'                     => 'Set de datos',
+  'Dataset missing!'            => 'No se encuentra Set de datos!',
+  'Dataset updated!'            => '',
+  'Date'                        => 'Fecha',
+  'Date Due'                    => 'Fecha de Vencimiento',
+  'Date Format'                 => 'Formato de Fecha',
+  'Date Paid'                   => 'Fecha de pago',
+  'Date missing!'               => '',
+  'Debit'                       => 'Débito',
+  'Debit and credit out of balance!' => 'Débito y Crédito fuera de balance.',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Decimalplaces'               => '',
+  'Delete'                      => 'Borrar',
+  'Delete Account'              => 'Borrar Cuenta',
+  'Delete Dataset'              => 'Borrar Set de Datos',
+  'Delivery Date'               => '',
+  'Deposit'                     => '',
+  'Description'                 => 'Descripción',
+  'Difference'                  => '',
+  'Directory'                   => 'Directorio',
+  'Discount'                    => 'Descuento',
+  'Done'                        => '',
+  'Drawing'                     => '',
+  'Driver'                      => 'Manejador',
+  'Dropdown Limit'              => '',
+  'Due'                         => 'Vence',
+  'Due Date'                    => 'Fecha de Vencimiento',
+  'Due Date missing!'           => 'Falta Fecha de Vencimiento!',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail Statement to'         => '',
+  'E-mail address missing!'     => 'Falta E-mail!',
+  'Edit'                        => '',
+  'Edit Account'                => 'Editar Cuenta',
+  'Edit Accounts Payables Transaction' => '',
+  'Edit Accounts Receivables Transaction' => '',
+  'Edit Assembly'               => 'Editar Ensamblaje',
+  'Edit GIFI'                   => 'Editar GIFI',
+  'Edit General Ledger Transaction' => 'Editar Transacción de Mayor General',
+  'Edit Part'                   => 'Editar Parte',
+  'Edit Preferences for'        => 'Editar Preferencias para',
+  'Edit Project'                => '',
+  'Edit Purchase Invoice'       => '',
+  'Edit Purchase Order'         => 'Editar Orden de Compra',
+  'Edit Sales Invoice'          => '',
+  'Edit Sales Order'            => 'Editar Orden de Venta',
+  'Edit Service'                => 'Editar Servicio',
+  'Edit Template'               => 'Editar Plantilla',
+  'Edit User'                   => 'Editar Usuario',
+  'Employee'                    => '',
+  'Enforce transaction reversal for all dates' => 'Forzar reversión de transacciones para todas las fechas',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => '',
+  'Equity'                      => 'Capital',
+  'Exch'                        => 'Interc.',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'Exchangerate Difference'     => '',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Existing Datasets'           => 'Sets de dato existentes',
+  'Expense'                     => 'Egreso',
+  'Expense Account'             => 'Cuenta de Egreso',
+  'Expense/Asset'               => 'Egreso/Activo',
+  'Extended'                    => '',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'Foreign Exchange Gain'       => 'Ganancia en Moneda Extranjera',
+  'Foreign Exchange Loss'       => 'Pérdida en Moneda Extranjera',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => '',
+  'GIFI missing!'               => 'No se encuentra GIFI',
+  'GIFI saved!'                 => '',
+  'GL Transaction'              => '',
+  'General Ledger'              => 'Mayor General',
+  'Goods & Services'            => 'Partes y Servicios',
+  'HTML Templates'              => 'Plantillas HTML',
+  'Heading'                     => 'Encabezado',
+  'Host'                        => 'Servidor base de datos',
+  'Hostname missing!'           => 'No se encuentra servidor de base de datos',
+  'ID'                          => 'ID',
+  'Image'                       => '',
+  'In-line'                     => 'En-linea',
+  'Include in Report'           => 'Incluya en informe',
+  'Include in drop-down menus'  => 'Incluya en menús desplegables',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Incluya esta cuenta en las formas del cliente/proveedor para señalar al cliente/proveedor como gravable de impuesto?',
+  'Income'                      => 'Ingreso',
+  'Income Account'              => 'Cuenta de Ingreso',
+  'Income Statement'            => 'Estado de Cuentas',
+  'Incorrect Dataset version!'  => 'Version de dataset Incorrecta',
+  'Incorrect Password!'         => 'Contraseña Incorrecta!',
+  'Individual Items'            => 'Items Individuales',
+  'Inventory'                   => 'Inventario',
+  'Inventory Account'           => 'Cuenta de Inventario',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'La cantidad en inventario debe ser cero antes de cambiar este ensamblaje a obsoleto!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'La cantidad en inventario debe ser cero antes de cambiar esta parte a obsoleto',
+  'Inventory quantity must be zero!' => 'La cantidad en inventario debe ser
+cero!',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Invoice deleted!'            => '',
+  'Invoice posted!'             => '',
+  'Invoices'                    => '',
+  'Is this a summary account to record' => 'Es esta una cuenta de resumen a registrar?',
+  'Item deleted!'               => '',
+  'Item not on file!'           => 'El item no se encuentra en archivo!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'LaTeX Templates'             => 'Plantillas LaTeX',
+  'Language'                    => 'Lenguaje',
+  'Last Cost'                   => 'Ultimo Costo',
+  'Last Invoice Number'         => 'Último Número de Factura',
+  'Last Numbers & Default Accounts' => 'Últimos Números y Cuentas por Defecto',
+  'Last Purchase Order Number'  => 'Ultima Orden de Compra',
+  'Last Sales Order Number'     => 'Ultima Orden de Venta',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Deje los campos de servidor de base de datos y puerto vacíos al menos que quiera hacer una conexión remota',
+  'Liability'                   => 'Pasivo',
+  'Licensed to'                 => 'Licenciado a',
+  'Line Total'                  => 'Total de Línea',
+  'Link'                        => 'Enlaces',
+  'Link Accounts'               => 'Enlazar Cuentas',
+  'List Accounts'               => 'Listar Cuentas',
+  'List GIFI'                   => 'Listar GIFI',
+  'List Price'                  => 'Precio de Lista',
+  'List Transactions'           => 'Listar Transacciones',
+  'Login'                       => 'Login',
+  'Logout'                      => 'Logout',
+  'Make'                        => 'Marca',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Microfiche'                  => '',
+  'Model'                       => 'Modelo',
+  'N/A'                         => 'N/D',
+  'Name'                        => 'Nombre',
+  'Name missing!'               => '',
+  'New Templates'               => 'Nuevas Plantillas',
+  'No'                          => 'No',
+  'No Database Drivers available!' => 'No hay manejador de base de datos
+disponible!',
+  'No Dataset selected!'        => 'No se ha seleccionado el set de datos',
+  'No email address for'        => 'Falta dirección email para',
+  'No.'                         => '',
+  'Notes'                       => 'Notas',
+  'Nothing applied!'            => '',
+  'Nothing selected!'           => '',
+  'Nothing to delete!'          => 'Noda que borrar',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Formato de Numero',
+  'Number missing in Row'       => 'No se encuentra el número en la fila',
+  'O'                           => '',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'On Hand'                     => 'En Existencia',
+  'On Order'                    => '',
+  'Open'                        => 'Abierto',
+  'Oracle Database Administration' => 'Administración de base de datos Oracle',
+  'Order'                       => 'Orden',
+  'Order Date'                  => 'Fecha de Orden',
+  'Order Date missing!'         => 'No se encuentra la fecha de orden!',
+  'Order Entry'                 => 'Orden de Entrada',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'No se encuentra el número de orden!',
+  'Order deleted!'              => '',
+  'Order saved!'                => '',
+  'Ordered'                     => '',
+  'Orphaned'                    => 'Huerfano',
+  'Out of balance!'             => '',
+  'PDF'                         => '',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => 'No se encuentra fecha de Lista de Empaque',
+  'Packing List Number missing!' => 'No se encuentra Número de Lista de Empaque',
+  'Paid'                        => 'Total Pagado',
+  'Paid in full'                => '',
+  'Part'                        => 'Partes',
+  'Part Number missing!'        => 'Falta del número de pieza!',
+  'Parts'                       => 'Partes',
+  'Parts Inventory'             => 'Inventario de Partes',
+  'Password'                    => 'Contraseña',
+  'Password changed!'           => '',
+  'Payables'                    => 'Por Pagar',
+  'Payment'                     => 'Pago',
+  'Payment date missing!'       => 'No se encuentra la fecha de Pago!',
+  'Payment posted!'             => '',
+  'Payments'                    => 'Pagos',
+  'Pg Database Administration'  => 'Administración de base de datos Pg',
+  'Phone'                       => 'Teléfono',
+  'Port'                        => 'Puerto',
+  'Port missing!'               => 'No se encuentra el Puerto!',
+  'Post'                        => '',
+  'Post as new'                 => '',
+  'Postscript'                  => '',
+  'Preferences'                 => 'Preferencias',
+  'Preferences saved!'          => 'Preferencias guardadas!',
+  'Price'                       => 'Precio',
+  'Print'                       => '',
+  'Printer'                     => 'Impresora',
+  'Project'                     => '',
+  'Project Number missing!'     => '',
+  'Project deleted!'            => '',
+  'Project not on file!'        => '',
+  'Project saved!'              => '',
+  'Projects'                    => '',
+  'Purchase Invoice'            => '',
+  'Purchase Order'              => 'Orden de Compra',
+  'Purchase Orders'             => 'Ordenes de Compra',
+  'Qty'                         => 'Cantidad',
+  'ROP'                         => 'ROP',
+  'Rate'                        => 'Tarifa',
+  'Recd'                        => '',
+  'Receipt'                     => '',
+  'Receipts'                    => '',
+  'Receivables'                 => 'Por Cobrar',
+  'Reconciliation'              => '',
+  'Record in'                   => 'Registrar en',
+  'Reference'                   => '',
+  'Reference missing!'          => '',
+  'Remaining'                   => 'Remanente',
+  'Report for'                  => 'Reportar por',
+  'Reports'                     => 'Reportes',
+  'Required by'                 => 'Requerido por',
+  'Retained Earnings'           => 'Ganacias Retenidas',
+  'Sales'                       => 'Ventas',
+  'Sales Invoice'               => '',
+  'Sales Order'                 => 'Orden de venta',
+  'Sales Orders'                => 'Ordenes de venta',
+  'Save'                        => 'Salvar',
+  'Save as new'                 => '',
+  'Save to File'                => 'Respaldar a Archivo',
+  'Screen'                      => 'Pantalla',
+  'Select a Dataset to delete and press "Continue"' => 'Seleccione un set de
+datos para borrar y presione "Continuar"',
+  'Select all'                  => '',
+  'Select from one of the items below' => 'Seleccione uno de los items',
+  'Select from one of the names below' => '',
+  'Select from one of the projects below' => '',
+  'Select postscript or PDF!'   => '',
+  'Sell Price'                  => 'Precio de Venta',
+  'Send by E-Mail'              => 'Enviar por E-Mail',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Service Items'               => 'Items de Servicio',
+  'Service Number missing!'     => 'Falta el número de servicio!',
+  'Services'                    => 'Servicios',
+  'Setup Templates'             => 'Configurar Plantillas',
+  'Ship'                        => '',
+  'Ship to'                     => '',
+  'Ship via'                    => '',
+  'Short'                       => 'Corto',
+  'Signature'                   => 'Firma',
+  'Sold'                        => 'Vendido',
+  'Source'                      => 'Fuente',
+  'Standard'                    => 'Estandar',
+  'Statement'                   => '',
+  'Statement Balance'           => '',
+  'Statement sent to'           => '',
+  'Statements sent to printer!' => '',
+  'Stock Assembly'              => 'Inventariar Ensamblaje?',
+  'Stylesheet'                  => 'Estilo de hoja',
+  'Subject'                     => 'Sujeto',
+  'Subtotal'                    => 'Subtotal',
+  'System'                      => 'Sistema',
+  'Tax'                         => 'Impuesto',
+  'Tax Accounts'                => 'Cuentas De Impuesto',
+  'Tax Included'                => 'Impuesto Incluido',
+  'Tax collected'               => '',
+  'Tax paid'                    => '',
+  'Taxable'                     => 'Gravable de Impuesto',
+  'Template saved!'             => '',
+  'Templates'                   => 'Plantillas',
+  'Terms: Net'                  => 'Crédito',
+  'The following Datasets are not in use and can be deleted' => 'Los
+siguientes sets de datos no estan en uso y pueden ser borrados',
+  'The following Datasets need to be updated' => 'Los siguientes datasets necesitan ser actualizados',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Esta es una verificacion preliminar de fuentes existentes.  Nada será creado o borrado en esta etapa!',
+  'To'                          => 'Hasta ',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Para agregar un usuario a un grupo, edite un nombre, cambie el nombre de entrada (login) y guarde los cambios.  Un nuevo usuario, con las mismas variables será guardado bajo el nuevo nombre de entrada. (login)',
+  'Top Level'                   => '',
+  'Total'                       => 'Total',
+  'Transaction Date missing!'   => 'Falta la fecha de la transacción!',
+  'Transaction deleted!'        => '',
+  'Transaction posted!'         => '',
+  'Transaction reversal enforced for all dates' => 'Retorno de transacciones forzado para todas las fechas',
+  'Transaction reversal enforced up to' => 'Reversal de transacciones forzado hasta ',
+  'Transactions'                => 'Transacciones',
+  'Transactions exist, cannot delete customer!' => 'Las transacciones existen, no pueden suprimir el cliente!',
+  'Transactions exist, cannot delete vendor!' => 'Las transacciones existen, no pueden suprimir a proveedor',
+  'Transactions exist; cannot delete account!' => 'Las transacciones existen,
+no puede suprimir la cuenta!',
+  'Trial Balance'               => 'Balance De Comprobación',
+  'Unit'                        => 'Unidad',
+  'Unit of measure'             => 'Unidad de medida',
+  'Update'                      => '',
+  'Update Dataset'              => 'Actualizar Dataset',
+  'Updated'                     => '',
+  'Use Templates'               => 'Plantillas de Usuarios',
+  'User'                        => 'Usuario',
+  'User deleted!'               => '',
+  'User saved!'                 => '',
+  'Vendor'                      => 'Proveedor',
+  'Vendor deleted!'             => '',
+  'Vendor missing!'             => '',
+  'Vendor not on file!'         => '',
+  'Vendor saved!'               => '',
+  'Vendors'                     => '',
+  'Version'                     => 'Versión',
+  'Weight'                      => 'Peso',
+  'Weight Unit'                 => 'Unidad de Peso',
+  'What type of item is this?'  => '¿Que tipo de Item es este?',
+  'Year End'                    => 'Fin del Año Fiscal',
+  'Yes'                         => 'Si',
+  'You are logged out!'         => '',
+  'You did not enter a name!'   => 'No introdujo un nombre!',
+  'You must enter a host and port for local and remote connections!' => 'Debe
+introducir un servidor de base de datos y un puerto para conexiones locales y
+remotas!',
+  'as at'                       => '',
+  'collected on sales'          => 'Recabado en ventas',
+  'days'                        => 'Días',
+  'does not exist'              => 'No existe',
+  'ea'                          => 'c/u',
+  'emailed to'                  => 'enviado a (e-mail)',
+  'for Period'                  => 'para el período',
+  'hr'                          => 'hr',
+  'is already a member!'        => 'ya es miembro!',
+  'is not a member!'            => 'no es un miembro!',
+  'localhost'                   => 'servidor local',
+  'paid on purchases'           => 'pagado en compras',
+  'sent to printer'             => 'enviar a impresora',
+  'successfully created!'       => 'creado con éxito!',
+  'successfully deleted!'       => 'creado con éxito!',
+  'to'                          => '',
+  'website'                     => 'sitio web',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/am b/sql-ledger/locale/pa/am
new file mode 100644 (file)
index 0000000..47edf44
--- /dev/null
@@ -0,0 +1,140 @@
+$self{texts} = {
+  'AP'                          => 'Ctas X Pagar',
+  'AR'                          => 'Ctas X Cobrar',
+  'Account'                     => 'Cuenta',
+  'Account Number'              => 'Número de Cuenta',
+  'Account Number missing!'     => 'No existe el número de cuenta!',
+  'Account Type'                => 'Tipo de Cuenta',
+  'Account Type missing!'       => 'No existe el tipo de la cuenta!',
+  'Account deleted!'            => 'Account deleted!',
+  'Account saved!'              => 'Account saved!',
+  'Add Account'                 => 'Agregar Cuenta',
+  'Add GIFI'                    => 'Agregar GIFI',
+  'Address'                     => 'Dirección',
+  'Asset'                       => 'Activo',
+  'Audit Control'               => 'Control de Audito',
+  'Backup sent to'              => 'Respaldo enviado a',
+  'Books are open'              => 'Libros estan abiertos',
+  'Business Number'             => 'Numero de Negocio',
+  'COGS'                        => 'Costo de Ventas',
+  'Cannot delete account!'      => 'Cannot delete account!',
+  'Cannot delete default account!' => 'No se puede borrar cuenta por defecto!',
+  'Cannot save account!'        => 'Cannot save account!',
+  'Cannot save preferences!'    => 'Cannot save preferences!',
+  'Character Set'               => 'Tabla de Caracteres',
+  'Chart of Accounts'           => 'Catálogo Contable',
+  'Close Books up to'           => 'Cerrar libros hasta',
+  'Company'                     => 'Compañía',
+  'Continue'                    => 'Continuar',
+  'Copy to COA'                 => 'Copiar a catálogo de cuentas',
+  'Credit'                      => 'Crédito',
+  'Date Format'                 => 'Formato de Fecha',
+  'Debit'                       => 'Débito',
+  'Delete'                      => 'Borrar',
+  'Delete Account'              => 'Borrar Cuenta',
+  'Description'                 => 'Descripción',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'Correo Electrónico',
+  'Edit'                        => 'Edit',
+  'Edit Account'                => 'Editar Cuenta',
+  'Edit GIFI'                   => 'Editar GIFI',
+  'Edit Preferences for'        => 'Editar Preferencias para',
+  'Edit Template'               => 'Editar Plantilla',
+  'Enforce transaction reversal for all dates' => 'Forzar reversión de transacciones para todas las fechas',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies',
+  'Equity'                      => 'Capital',
+  'Expense'                     => 'Egreso',
+  'Expense Account'             => 'Cuenta de Egreso',
+  'Expense/Asset'               => 'Egreso/Activo',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Ganancia en Moneda Extranjera',
+  'Foreign Exchange Loss'       => 'Pérdida en Moneda Extranjera',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI deleted!',
+  'GIFI missing!'               => 'No se encuentra GIFI',
+  'GIFI saved!'                 => 'GIFI saved!',
+  'Heading'                     => 'Encabezado',
+  'Include in drop-down menus'  => 'Incluya en menús desplegables',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Incluya esta cuenta en las formas del cliente/proveedor para señalar al cliente/proveedor como gravable de impuesto?',
+  'Income'                      => 'Ingreso',
+  'Income Account'              => 'Cuenta de Ingreso',
+  'Inventory'                   => 'Inventario',
+  'Inventory Account'           => 'Cuenta de Inventario',
+  'Is this a summary account to record' => 'Es esta una cuenta de resumen a registrar?',
+  'Language'                    => 'Lenguaje',
+  'Last Invoice Number'         => 'Último Número de Factura',
+  'Last Numbers & Default Accounts' => 'Últimos Números y Cuentas por Defecto',
+  'Last Purchase Order Number'  => 'Ultima Orden de Compra',
+  'Last Sales Order Number'     => 'Ultima Orden de Venta',
+  'Liability'                   => 'Pasivo',
+  'Link'                        => 'Enlaces',
+  'Name'                        => 'Nombre',
+  'No'                          => 'No',
+  'No email address for'        => 'Falta dirección email para',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Formato de Numero',
+  'Parts Inventory'             => 'Inventario de Partes',
+  'Password'                    => 'Contraseña',
+  'Payables'                    => 'Por Pagar',
+  'Payment'                     => 'Pago',
+  'Phone'                       => 'Teléfono',
+  'Preferences saved!'          => 'Preferencias guardadas!',
+  'Rate'                        => 'Tarifa',
+  'Receivables'                 => 'Por Cobrar',
+  'Sales'                       => 'Ventas',
+  'Save'                        => 'Salvar',
+  'Service Items'               => 'Items de Servicio',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'Firma',
+  'Stylesheet'                  => 'Estilo de hoja',
+  'Tax'                         => 'Impuesto',
+  'Tax Accounts'                => 'Cuentas De Impuesto',
+  'Template saved!'             => 'Template saved!',
+  'Transaction reversal enforced for all dates' => 'Retorno de transacciones forzado para todas las fechas',
+  'Transaction reversal enforced up to' => 'Reversal de transacciones forzado hasta ',
+  'Transactions exist; cannot delete account!' => 'Las transacciones existen,
+no puede suprimir la cuenta!',
+  'Weight Unit'                 => 'Unidad de Peso',
+  'Year End'                    => 'Fin del Año Fiscal',
+  'Yes'                         => 'Si',
+  'does not exist'              => 'No existe',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'agregar_cuenta'              => 'add_account',
+  'continuar'                   => 'continue',
+  'copiar_a_catálogo_de_cuentas' => 'copy_to_coa',
+  'borrar'                      => 'delete',
+  'edit'                        => 'edit',
+  'editar_cuenta'               => 'edit_account',
+  'salvar'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/ap b/sql-ledger/locale/pa/ap
new file mode 100644 (file)
index 0000000..0741d00
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AP Transactions'             => 'Transacciones - Cuentas por Pagar',
+  'Account'                     => 'Cuenta',
+  'Add Accounts Payables Transaction' => 'Add Accounts Payables Transaction',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => '¿Está usted seguro de que desea suprimir la transacción?',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'No se puede registrar pago para un periodo cerrado',
+  'Cannot post transaction for a closed period!' => 'No puede guardar transaccion para un periodo cerrado',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'Cerrado',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Moneda',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Date Paid'                   => 'Fecha de pago',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Due Date'                    => 'Fecha de Vencimiento',
+  'Due Date missing!'           => 'Falta Fecha de Vencimiento!',
+  'Edit Accounts Payables Transaction' => 'Edit Accounts Payables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'Interc.',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluya en informe',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Open'                        => 'Abierto',
+  'Order'                       => 'Orden',
+  'Order Number'                => 'Orden Número',
+  'Paid'                        => 'Total Pagado',
+  'Payment date missing!'       => 'No se encuentra la fecha de Pago!',
+  'Payments'                    => 'Pagos',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Source'                      => 'Fuente',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'Tax Included'                => 'Impuesto Incluido',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Proveedor',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Si',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'add_accounts_payables_transaction' => 'add_accounts_payables_transaction',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'edit_accounts_payables_transaction' => 'edit_accounts_payables_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'update'                      => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/ar b/sql-ledger/locale/pa/ar
new file mode 100644 (file)
index 0000000..7106f79
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'AR Transaction',
+  'AR Transactions'             => 'Transacciones de Cuentas por Cobrar',
+  'Account'                     => 'Cuenta',
+  'Add Accounts Receivables Transaction' => 'Add Accounts Receivables Transaction',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => '¿Está usted seguro de que desea suprimir la transacción?',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'No se puede registrar pago para un periodo cerrado',
+  'Cannot post transaction for a closed period!' => 'No puede guardar transaccion para un periodo cerrado',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'Cerrado',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Limite de Credito',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Date Paid'                   => 'Fecha de pago',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Due Date'                    => 'Fecha de Vencimiento',
+  'Due Date missing!'           => 'Falta Fecha de Vencimiento!',
+  'Edit Accounts Receivables Transaction' => 'Edit Accounts Receivables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'Interc.',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluya en informe',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Open'                        => 'Abierto',
+  'Order'                       => 'Orden',
+  'Order Number'                => 'Orden Número',
+  'Paid'                        => 'Total Pagado',
+  'Payment date missing!'       => 'No se encuentra la fecha de Pago!',
+  'Payments'                    => 'Pagos',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Remaining'                   => 'Remanente',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Source'                      => 'Fuente',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'Tax Included'                => 'Impuesto Incluido',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Si',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ar_transaction'              => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/arap b/sql-ledger/locale/pa/arap
new file mode 100644 (file)
index 0000000..f541192
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Dirección',
+  'Continue'                    => 'Continuar',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Description'                 => 'Descripción',
+  'Number'                      => 'Número',
+  'Project not on file!'        => 'Project not on file!',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/ca b/sql-ledger/locale/pa/ca
new file mode 100644 (file)
index 0000000..0d3d00e
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Balance',
+  'Chart of Accounts'           => 'Catálogo Contable',
+  'Credit'                      => 'Crédito',
+  'Date'                        => 'Fecha',
+  'Debit'                       => 'Débito',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Description'                 => 'Descripción',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Incluya en informe',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'List Transactions'           => 'Listar Transacciones',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Reference'                   => 'Reference',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Subtotal'                    => 'Subtotal',
+  'To'                          => 'Hasta ',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'listar_transacciones'        => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/cp b/sql-ledger/locale/pa/cp
new file mode 100644 (file)
index 0000000..95085e0
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Amount does not equal applied!' => 'Amount does not equal applied!',
+  'Amount missing!'             => 'Amount missing!',
+  'Applied'                     => 'Applied',
+  'Cannot post payment!'        => 'Cannot post payment!',
+  'Cannot process payment for a closed period!' => 'Cannot process payment for a closed period!',
+  'Check'                       => 'Check',
+  'Check printed!'              => 'Check printed!',
+  'Check printing failed!'      => 'Check printing failed!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Cliente',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Date missing!'               => 'Date missing!',
+  'Description'                 => 'Descripción',
+  'Due'                         => 'Vence',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'From'                        => 'Desde',
+  'Invoice'                     => 'Factura',
+  'Invoices'                    => 'Invoices',
+  'Nothing applied!'            => 'Nothing applied!',
+  'Number'                      => 'Número',
+  'Paid in full'                => 'Paid in full',
+  'Payment'                     => 'Pago',
+  'Payment posted!'             => 'Payment posted!',
+  'Post'                        => 'Post',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Impresora',
+  'Project not on file!'        => 'Project not on file!',
+  'Receipt'                     => 'Receipt',
+  'Reference'                   => 'Reference',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'To'                          => 'Hasta ',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Proveedor',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/ct b/sql-ledger/locale/pa/ct
new file mode 100644 (file)
index 0000000..0db8902
--- /dev/null
@@ -0,0 +1,69 @@
+$self{texts} = {
+  'Add'                         => 'Agregar',
+  'Address'                     => 'Dirección',
+  'All'                         => 'Todos',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Cannot delete customer!',
+  'Cannot delete vendor!'       => 'Cannot delete vendor!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Limite de Credito',
+  'Customer deleted!'           => 'Customer deleted!',
+  'Customer saved!'             => 'Customer saved!',
+  'Customers'                   => 'Customers',
+  'Delete'                      => 'Borrar',
+  'Discount'                    => 'Descuento',
+  'E-mail'                      => 'Correo Electrónico',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Incluya en informe',
+  'Invoice'                     => 'Factura',
+  'Name'                        => 'Nombre',
+  'Name missing!'               => 'Name missing!',
+  'Notes'                       => 'Notas',
+  'Number'                      => 'Número',
+  'Order'                       => 'Orden',
+  'Orphaned'                    => 'Huerfano',
+  'Phone'                       => 'Teléfono',
+  'Save'                        => 'Salvar',
+  'Ship to'                     => 'Ship to',
+  'Tax Included'                => 'Impuesto Incluido',
+  'Taxable'                     => 'Gravable de Impuesto',
+  'Terms: Net'                  => 'Crédito',
+  'Transactions exist, cannot delete customer!' => 'Las transacciones existen, no pueden suprimir el cliente!',
+  'Transactions exist, cannot delete vendor!' => 'Las transacciones existen, no pueden suprimir a proveedor',
+  'Vendor deleted!'             => 'Vendor deleted!',
+  'Vendor saved!'               => 'Vendor saved!',
+  'Vendors'                     => 'Vendors',
+  'days'                        => 'Días',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'agregar'                     => 'add',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'factura'                     => 'invoice',
+  'orden'                       => 'order',
+  'salvar'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/gl b/sql-ledger/locale/pa/gl
new file mode 100644 (file)
index 0000000..8667f1c
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AR Transaction'              => 'AR Transaction',
+  'Account'                     => 'Cuenta',
+  'Add General Ledger Transaction' => 'Agregar Transacción - Mayor General',
+  'Address'                     => 'Dirección',
+  'All'                         => 'Todos',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => '¿Está usted seguro de que desea suprimir la transacción?',
+  'Asset'                       => 'Activo',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Balance',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot have a value in both Debit and Credit!' => 'No puede tener un valor en Débito y Crédito simultáneamente!',
+  'Cannot post a transaction without a value!' => 'Cannot post a transaction without a value!',
+  'Cannot post transaction for a closed period!' => 'No puede guardar transaccion para un periodo cerrado',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Credit'                      => 'Crédito',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Debit'                       => 'Débito',
+  'Debit and credit out of balance!' => 'Débito y Crédito fuera de balance.',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Edit General Ledger Transaction' => 'Editar Transacción de Mayor General',
+  'Equity'                      => 'Capital',
+  'Expense'                     => 'Egreso',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'GL Transaction',
+  'General Ledger'              => 'Mayor General',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluya en informe',
+  'Income'                      => 'Ingreso',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Liability'                   => 'Pasivo',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Reference'                   => 'Reference',
+  'Reference missing!'          => 'Reference missing!',
+  'Reports'                     => 'Reportes',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Source'                      => 'Fuente',
+  'Subtotal'                    => 'Subtotal',
+  'To'                          => 'Hasta ',
+  'Transaction Date missing!'   => 'Falta la fecha de la transacción!',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Si',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'gl_transaction'              => 'gl_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/ic b/sql-ledger/locale/pa/ic
new file mode 100644 (file)
index 0000000..44cfa36
--- /dev/null
@@ -0,0 +1,206 @@
+$self{texts} = {
+  'Active'                      => 'Active',
+  'Add'                         => 'Agregar',
+  'Add Assembly'                => 'Agregar Ensamblaje',
+  'Add Part'                    => 'Agregar Parte',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Order'             => 'Agregar Orden de Venta',
+  'Add Service'                 => 'Agregar Servicio',
+  'Address'                     => 'Dirección',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Assemblies'                  => 'Ensamblajes',
+  'Assemblies restocked!'       => 'Assemblies restocked!',
+  'Assembly Number missing!'    => 'No existe Numero de Ensamblaje!',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Bought'                      => 'Comprado',
+  'COGS'                        => 'Costo de Ventas',
+  'Cannot delete item already invoiced!' => 'No puede suprimir el item ya facturado!',
+  'Cannot delete item on order!' => 'No se puede borrar el item ya en cotizacion',
+  'Cannot delete item which is part of an assembly!' => 'No puede suprimir un item que es parte de un ensamblaje!',
+  'Cannot delete item!'         => 'Cannot delete item!',
+  'Cannot stock assemblies!'    => 'Cannot stock assemblies!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripción',
+  'Drawing'                     => 'Drawing',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail address missing!'     => 'Falta E-mail!',
+  'Edit Assembly'               => 'Editar Ensamblaje',
+  'Edit Part'                   => 'Editar Parte',
+  'Edit Service'                => 'Editar Servicio',
+  'Expense'                     => 'Egreso',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'Image'                       => 'Image',
+  'In-line'                     => 'En-linea',
+  'Include in Report'           => 'Incluya en informe',
+  'Income'                      => 'Ingreso',
+  'Individual Items'            => 'Items Individuales',
+  'Inventory'                   => 'Inventario',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'La cantidad en inventario debe ser cero antes de cambiar este ensamblaje a obsoleto!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'La cantidad en inventario debe ser cero antes de cambiar esta parte a obsoleto',
+  'Inventory quantity must be zero!' => 'La cantidad en inventario debe ser
+cero!',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Item deleted!'               => 'Item deleted!',
+  'Item not on file!'           => 'El item no se encuentra en archivo!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Last Cost'                   => 'Ultimo Costo',
+  'Line Total'                  => 'Total de Línea',
+  'Link Accounts'               => 'Enlazar Cuentas',
+  'List Price'                  => 'Precio de Lista',
+  'Make'                        => 'Marca',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Modelo',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se encuentra el número en la fila',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'On Hand'                     => 'En Existencia',
+  'On Order'                    => 'On Order',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'No se encuentra la fecha de orden!',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'No se encuentra el número de orden!',
+  'Ordered'                     => 'Ordered',
+  'Orphaned'                    => 'Huerfano',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => 'No se encuentra fecha de Lista de Empaque',
+  'Packing List Number missing!' => 'No se encuentra Número de Lista de Empaque',
+  'Part'                        => 'Partes',
+  'Part Number missing!'        => 'Falta del número de pieza!',
+  'Parts'                       => 'Partes',
+  'Phone'                       => 'Teléfono',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Orden de Compra',
+  'Qty'                         => 'Cantidad',
+  'ROP'                         => 'ROP',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Requerido por',
+  'Sales'                       => 'Ventas',
+  'Sales Order'                 => 'Orden de venta',
+  'Save'                        => 'Salvar',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los items',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sell Price'                  => 'Precio de Venta',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Service Number missing!'     => 'Falta el número de servicio!',
+  'Services'                    => 'Servicios',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Short'                       => 'Corto',
+  'Sold'                        => 'Vendido',
+  'Stock Assembly'              => 'Inventariar Ensamblaje?',
+  'Subject'                     => 'Sujeto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'To'                          => 'Hasta ',
+  'Top Level'                   => 'Top Level',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Unit of measure'             => 'Unidad de medida',
+  'Update'                      => 'Update',
+  'Updated'                     => 'Updated',
+  'Weight'                      => 'Peso',
+  'What type of item is this?'  => '¿Que tipo de Item es este?',
+  'ea'                          => 'c/u',
+  'emailed to'                  => 'enviado a (e-mail)',
+  'hr'                          => 'hr',
+  'sent to printer'             => 'enviar a impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'agregar'                     => 'add',
+  'agregar_ensamblaje'          => 'add_assembly',
+  'agregar_parte'               => 'add_part',
+  'agregar_servicio'            => 'add_service',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'editar_ensamblaje'           => 'edit_assembly',
+  'editar_parte'                => 'edit_part',
+  'editar_servicio'             => 'edit_service',
+  'salvar'                      => 'save',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/io b/sql-ledger/locale/pa/io
new file mode 100644 (file)
index 0000000..1252b51
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Order'             => 'Agregar Orden de Venta',
+  'Address'                     => 'Dirección',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail address missing!'     => 'Falta E-mail!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'In-line'                     => 'En-linea',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Item not on file!'           => 'El item no se encuentra en archivo!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se encuentra el número en la fila',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'No se encuentra la fecha de orden!',
+  'Order Number missing!'       => 'No se encuentra el número de orden!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => 'No se encuentra fecha de Lista de Empaque',
+  'Packing List Number missing!' => 'No se encuentra Número de Lista de Empaque',
+  'Part'                        => 'Partes',
+  'Phone'                       => 'Teléfono',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Orden de Compra',
+  'Qty'                         => 'Cantidad',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Orden de venta',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los items',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Subject'                     => 'Sujeto',
+  'To'                          => 'Hasta ',
+  'Unit'                        => 'Unidad',
+  'What type of item is this?'  => '¿Que tipo de Item es este?',
+  'emailed to'                  => 'enviado a (e-mail)',
+  'sent to printer'             => 'enviar a impresora',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/ir b/sql-ledger/locale/pa/ir
new file mode 100644 (file)
index 0000000..042ca21
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Order'             => 'Agregar Orden de Venta',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => '¿Esta seguro de que desea borrar la Factura No.:',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'No se puede registrar factura para un periodo cerrado!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'No se puede registrar pago para un periodo cerrado',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Currency'                    => 'Moneda',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Date Due'                    => 'Fecha de Vencimiento',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail address missing!'     => 'Falta E-mail!',
+  'Edit Purchase Invoice'       => 'Edit Purchase Invoice',
+  'Exch'                        => 'Interc.',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'In-line'                     => 'En-linea',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => 'El item no se encuentra en archivo!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se encuentra el número en la fila',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'No se encuentra la fecha de orden!',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'No se encuentra el número de orden!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => 'No se encuentra fecha de Lista de Empaque',
+  'Packing List Number missing!' => 'No se encuentra Número de Lista de Empaque',
+  'Part'                        => 'Partes',
+  'Payment date missing!'       => 'No se encuentra la fecha de Pago!',
+  'Payments'                    => 'Pagos',
+  'Phone'                       => 'Teléfono',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Orden de Compra',
+  'Qty'                         => 'Cantidad',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'Registrar en',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Orden de venta',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los items',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Source'                      => 'Fuente',
+  'Subject'                     => 'Sujeto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Impuesto Incluido',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Proveedor',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => '¿Que tipo de Item es este?',
+  'Yes'                         => 'Si',
+  'ea'                          => 'c/u',
+  'emailed to'                  => 'enviado a (e-mail)',
+  'sent to printer'             => 'enviar a impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'orden'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'update'                      => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/is b/sql-ledger/locale/pa/is
new file mode 100644 (file)
index 0000000..577b51f
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'Agregar Orden de Venta',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => '¿Esta seguro de que desea borrar la Factura No.:',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'No se puede registrar factura para un periodo cerrado!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'No se puede registrar pago para un periodo cerrado',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Credit Limit'                => 'Limite de Credito',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Date Due'                    => 'Fecha de Vencimiento',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail address missing!'     => 'Falta E-mail!',
+  'Edit Sales Invoice'          => 'Edit Sales Invoice',
+  'Exch'                        => 'Interc.',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'In-line'                     => 'En-linea',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha de Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => 'El item no se encuentra en archivo!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se encuentra el número en la fila',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'No se encuentra la fecha de orden!',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'No se encuentra el número de orden!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => 'No se encuentra fecha de Lista de Empaque',
+  'Packing List Number missing!' => 'No se encuentra Número de Lista de Empaque',
+  'Part'                        => 'Partes',
+  'Payment date missing!'       => 'No se encuentra la fecha de Pago!',
+  'Payments'                    => 'Pagos',
+  'Phone'                       => 'Teléfono',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Orden de Compra',
+  'Qty'                         => 'Cantidad',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'Registrar en',
+  'Remaining'                   => 'Remanente',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Orden de venta',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los items',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Source'                      => 'Fuente',
+  'Subject'                     => 'Sujeto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Impuesto Incluido',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => '¿Que tipo de Item es este?',
+  'Yes'                         => 'Si',
+  'ea'                          => 'c/u',
+  'emailed to'                  => 'enviado a (e-mail)',
+  'sent to printer'             => 'enviar a impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'correo_electrónico'          => 'e_mail',
+  'orden'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/login b/sql-ledger/locale/pa/login
new file mode 100644 (file)
index 0000000..d6199be
--- /dev/null
@@ -0,0 +1,28 @@
+$self{texts} = {
+  'About'                       => 'Acerca',
+  'Accounting'                  => 'Contabilidad',
+  'Database Host'               => 'Servidor de Base de Datos',
+  'Dataset'                     => 'Set de datos',
+  'Incorrect Dataset version!'  => 'Version de dataset Incorrecta',
+  'Incorrect Password!'         => 'Contraseña Incorrecta!',
+  'Licensed to'                 => 'Licenciado a',
+  'Login'                       => 'Login',
+  'Name'                        => 'Nombre',
+  'Password'                    => 'Contraseña',
+  'User'                        => 'Usuario',
+  'Version'                     => 'Versión',
+  'You are logged out!'         => 'You are logged out!',
+  'You did not enter a name!'   => 'No introdujo un nombre!',
+  'is not a member!'            => 'no es un miembro!',
+  'localhost'                   => 'servidor local',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'login'                       => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/menu b/sql-ledger/locale/pa/menu
new file mode 100644 (file)
index 0000000..25ba596
--- /dev/null
@@ -0,0 +1,72 @@
+$self{texts} = {
+  'AP'                          => 'Ctas X Pagar',
+  'AP Aging'                    => 'Envejecimiento - CxP',
+  'AR'                          => 'Ctas X Cobrar',
+  'AR Aging'                    => 'Envejecimiento - CxC ',
+  'Accounting Menu'             => 'Menú de Contabilidad',
+  'Add Account'                 => 'Agregar Cuenta',
+  'Add Assembly'                => 'Agregar Ensamblaje',
+  'Add Customer'                => 'Agregar Cliente',
+  'Add GIFI'                    => 'Agregar GIFI',
+  'Add Part'                    => 'Agregar Parte',
+  'Add Project'                 => 'Add Project',
+  'Add Service'                 => 'Agregar Servicio',
+  'Add Transaction'             => 'Agregar Transaccion',
+  'Add Vendor'                  => 'Agregar Proveedor',
+  'Assemblies'                  => 'Ensamblajes',
+  'Audit Control'               => 'Control de Audito',
+  'Backup'                      => 'Respaldar datos',
+  'Balance Sheet'               => 'Hoja de Balance',
+  'Cash'                        => 'Cash',
+  'Chart of Accounts'           => 'Catálogo Contable',
+  'Check'                       => 'Check',
+  'Customers'                   => 'Customers',
+  'General Ledger'              => 'Mayor General',
+  'Goods & Services'            => 'Partes y Servicios',
+  'HTML Templates'              => 'Plantillas HTML',
+  'Income Statement'            => 'Estado de Cuentas',
+  'Invoice'                     => 'Factura',
+  'LaTeX Templates'             => 'Plantillas LaTeX',
+  'List Accounts'               => 'Listar Cuentas',
+  'List GIFI'                   => 'Listar GIFI',
+  'Logout'                      => 'Logout',
+  'Order Entry'                 => 'Orden de Entrada',
+  'Packing List'                => 'Lista de Empaque',
+  'Parts'                       => 'Partes',
+  'Payment'                     => 'Pago',
+  'Payments'                    => 'Pagos',
+  'Preferences'                 => 'Preferencias',
+  'Projects'                    => 'Projects',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Purchase Order'              => 'Orden de Compra',
+  'Purchase Orders'             => 'Ordenes de Compra',
+  'Receipt'                     => 'Receipt',
+  'Receipts'                    => 'Receipts',
+  'Reconciliation'              => 'Reconciliation',
+  'Reports'                     => 'Reportes',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Sales Order'                 => 'Orden de venta',
+  'Sales Orders'                => 'Ordenes de venta',
+  'Save to File'                => 'Respaldar a Archivo',
+  'Send by E-Mail'              => 'Enviar por E-Mail',
+  'Services'                    => 'Servicios',
+  'Statement'                   => 'Statement',
+  'Stock Assembly'              => 'Inventariar Ensamblaje?',
+  'Stylesheet'                  => 'Estilo de hoja',
+  'System'                      => 'Sistema',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'Transactions'                => 'Transacciones',
+  'Trial Balance'               => 'Balance De Comprobación',
+  'Vendors'                     => 'Vendors',
+  'Version'                     => 'Versión',
+  'localhost'                   => 'servidor local',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/oe b/sql-ledger/locale/pa/oe
new file mode 100644 (file)
index 0000000..a7ee60a
--- /dev/null
@@ -0,0 +1,200 @@
+$self{texts} = {
+  'Add'                         => 'Agregar',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'Agregar Orden de Venta',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Order Number' => '¿Esta seguro de que desea
+borrar la Orden No.:?',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Cannot delete order!',
+  'Cannot save order!'          => 'Cannot save order!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Cerrado',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Credit Limit'                => 'Limite de Credito',
+  'Curr'                        => '$',
+  'Currency'                    => 'Moneda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Fecha',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail address missing!'     => 'Falta E-mail!',
+  'Edit Purchase Order'         => 'Editar Orden de Compra',
+  'Edit Sales Order'            => 'Editar Orden de Venta',
+  'Exchangerate'                => 'Tasa de Intercambio',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'ID'                          => 'ID',
+  'In-line'                     => 'En-linea',
+  'Include in Report'           => 'Incluya en informe',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Falta la Fecha de la Factura!',
+  'Invoice Number missing!'     => 'Falta el Número de Factura!',
+  'Item not on file!'           => 'El item no se encuentra en archivo!',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'No se encuentra el número en la fila',
+  'O'                           => 'O',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'Open'                        => 'Abierto',
+  'Order'                       => 'Orden',
+  'Order Date'                  => 'Fecha de Orden',
+  'Order Date missing!'         => 'No se encuentra la fecha de orden!',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'No se encuentra el número de orden!',
+  'Order deleted!'              => 'Order deleted!',
+  'Order saved!'                => 'Order saved!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => 'No se encuentra fecha de Lista de Empaque',
+  'Packing List Number missing!' => 'No se encuentra Número de Lista de Empaque',
+  'Part'                        => 'Partes',
+  'Phone'                       => 'Teléfono',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Orden de Compra',
+  'Purchase Orders'             => 'Ordenes de Compra',
+  'Qty'                         => 'Cantidad',
+  'Recd'                        => 'Recd',
+  'Remaining'                   => 'Remanente',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Orden de venta',
+  'Sales Orders'                => 'Ordenes de venta',
+  'Save'                        => 'Salvar',
+  'Save as new'                 => 'Save as new',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los items',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Subject'                     => 'Sujeto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'Tax Included'                => 'Impuesto Incluido',
+  'Terms: Net'                  => 'Crédito',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Proveedor',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => '¿Que tipo de Item es este?',
+  'Yes'                         => 'Si',
+  'days'                        => 'Días',
+  'ea'                          => 'c/u',
+  'emailed to'                  => 'enviado a (e-mail)',
+  'sent to printer'             => 'enviar a impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'agregar'                     => 'add',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'correo_electrónico'          => 'e_mail',
+  'factura'                     => 'invoice',
+  'print'                       => 'print',
+  'salvar'                      => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'si'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/pe b/sql-ledger/locale/pa/pe
new file mode 100644 (file)
index 0000000..e1306ae
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Agregar',
+  'Add Project'                 => 'Add Project',
+  'All'                         => 'Todos',
+  'Continue'                    => 'Continuar',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Edit Project'                => 'Edit Project',
+  'Number'                      => 'Número',
+  'Orphaned'                    => 'Huerfano',
+  'Project'                     => 'Project',
+  'Project Number missing!'     => 'Project Number missing!',
+  'Project deleted!'            => 'Project deleted!',
+  'Project saved!'              => 'Project saved!',
+  'Projects'                    => 'Projects',
+  'Save'                        => 'Salvar',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'agregar'                     => 'add',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'salvar'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/rc b/sql-ledger/locale/pa/rc
new file mode 100644 (file)
index 0000000..7e0dbb1
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Balance'                     => 'Balance',
+  'Cleared Balance'             => 'Cleared Balance',
+  'Continue'                    => 'Continuar',
+  'Date'                        => 'Fecha',
+  'Deposit'                     => 'Deposit',
+  'Description'                 => 'Descripción',
+  'Difference'                  => 'Difference',
+  'Done'                        => 'Done',
+  'Exchangerate Difference'     => 'Exchangerate Difference',
+  'From'                        => 'Desde',
+  'Out of balance!'             => 'Out of balance!',
+  'Payment'                     => 'Pago',
+  'Reconciliation'              => 'Reconciliation',
+  'Select all'                  => 'Select all',
+  'Source'                      => 'Fuente',
+  'Statement Balance'           => 'Statement Balance',
+  'To'                          => 'Hasta ',
+  'Update'                      => 'Update',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'continuar'                   => 'continue',
+  'done'                        => 'done',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/pa/rp b/sql-ledger/locale/pa/rp
new file mode 100644 (file)
index 0000000..ad8b35b
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'Envejecimiento - CxP',
+  'AR Aging'                    => 'Envejecimiento - CxC ',
+  'Account'                     => 'Cuenta',
+  'Accounts'                    => 'Cuentas',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Attachment'                  => 'Adjunto',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance Sheet'               => 'Hoja de Balance',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Cash based',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Comparar a',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Credit'                      => 'Crédito',
+  'Current'                     => 'Current',
+  'Customer'                    => 'Cliente',
+  'Date'                        => 'Fecha',
+  'Debit'                       => 'Débito',
+  'Dec'                         => 'Dic',
+  'December'                    => 'Diciembre',
+  'Decimalplaces'               => 'Decimalplaces',
+  'Description'                 => 'Descripción',
+  'Due'                         => 'Vence',
+  'E-mail'                      => 'Correo Electrónico',
+  'E-mail Statement to'         => 'E-mail Statement to',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Febrero',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Encabezado',
+  'ID'                          => 'ID',
+  'In-line'                     => 'En-linea',
+  'Include in Report'           => 'Incluya en informe',
+  'Income Statement'            => 'Estado de Cuentas',
+  'Invoice'                     => 'Factura',
+  'Jan'                         => 'Ene',
+  'January'                     => 'Enero',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julio',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junio',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Marzo',
+  'May'                         => 'May',
+  'May '                        => 'Mayo',
+  'Message'                     => 'Mensaje',
+  'N/A'                         => 'N/D',
+  'Nothing selected!'           => 'Nothing selected!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Noviembre',
+  'Oct'                         => 'Oct',
+  'October'                     => 'Octubre',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Pagos',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Impresora',
+  'Receipts'                    => 'Receipts',
+  'Report for'                  => 'Reportar por',
+  'Retained Earnings'           => 'Ganacias Retenidas',
+  'Screen'                      => 'Pantalla',
+  'Select all'                  => 'Select all',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Sep',
+  'September'                   => 'Septiembre',
+  'Source'                      => 'Fuente',
+  'Standard'                    => 'Estandar',
+  'Statement'                   => 'Statement',
+  'Statement sent to'           => 'Statement sent to',
+  'Statements sent to printer!' => 'Statements sent to printer!',
+  'Subject'                     => 'Sujeto',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Impuesto',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'To'                          => 'Hasta ',
+  'Total'                       => 'Total',
+  'Trial Balance'               => 'Balance De Comprobación',
+  'Vendor'                      => 'Proveedor',
+  'as at'                       => 'as at',
+  'collected on sales'          => 'Recabado en ventas',
+  'for Period'                  => 'para el período',
+  'paid on purchases'           => 'pagado en compras',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'continuar'                   => 'continue',
+  'correo_electrónico'          => 'e_mail',
+  'print'                       => 'print',
+  'select_all'                  => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/COPYING b/sql-ledger/locale/pl/COPYING
new file mode 100644 (file)
index 0000000..e8ae224
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Polish texts:
+#
+#  Author: Peter Dabrowski <meritage@mail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/pl/LANGUAGE b/sql-ledger/locale/pl/LANGUAGE
new file mode 100644 (file)
index 0000000..692d024
--- /dev/null
@@ -0,0 +1 @@
+Polish
diff --git a/sql-ledger/locale/pl/admin b/sql-ledger/locale/pl/admin
new file mode 100644 (file)
index 0000000..9dc5b6a
--- /dev/null
@@ -0,0 +1,122 @@
+$self{texts} = {
+  'Access Control'              => 'Kontrola Dostêpu',
+  'Accounting'                  => 'Ksiêgowo¶æ',
+  'Add User'                    => 'Dodaj U¿ytkownika',
+  'Address'                     => 'Adres',
+  'Administration'              => 'Administracja',
+  'Administrator'               => 'Administrator',
+  'All Datasets up to date!'    => 'Zbiory Danych uzupe³nione!',
+  'Change Admin Password'       => 'Zmiana Has³a Administratora',
+  'Change Password'             => 'Zmieñ Has³o',
+  'Character Set'               => 'Zestaw Znaków',
+  'Click on login name to edit!' => 'Kliknij  nazwê u¿ytkownika ¿eby dokonaæ zmian!',
+  'Company'                     => 'Firma',
+  'Connect to'                  => 'Pod³±cz do',
+  'Continue'                    => 'Kontynuj',
+  'Create Chart of Accounts'    => 'Utwórz Wzór Kont',
+  'Create Dataset'              => 'Utwórz Zbiór Danych',
+  'DBI not installed!'          => 'Nie zainstalowane DBI!',
+  'Database'                    => 'Baza Danych',
+  'Database Administration'     => 'Administracja Bazy Danych',
+  'Database Driver not checked!' => 'Sterownik Bazy Danych nie zaznaczony!',
+  'Database User missing!'      => 'Brak U¿ytkownika Bazy Danych!',
+  'Dataset'                     => 'Zbiór Danych',
+  'Dataset missing!'            => 'Brak Zbioru Danych',
+  'Dataset updated!'            => 'Zbiór Danych uzupe³niony!',
+  'Date Format'                 => 'Format Daty',
+  'Delete'                      => 'Usuñ',
+  'Delete Dataset'              => 'Usuñ Zbior Danych',
+  'Directory'                   => 'Katalog',
+  'Driver'                      => 'Sterownik',
+  'Dropdown Limit'              => 'Limit Rozwiniêcia',
+  'E-mail'                      => 'E-mail',
+  'Edit User'                   => 'Zmiany U¿ytkownika',
+  'Existing Datasets'           => 'Istniej±cy Zbiór Danych',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Brak Nazwy Hosta',
+  'Incorrect Password!'         => 'Nieprawid³owe Has³o',
+  'Language'                    => 'Jêzyk',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Opu¶æ pole wêz³a i portu, chyba ¿e chcesz mieæ zdalne po³±czenie',
+  'Login'                       => 'Zarejestrój siê',
+  'Name'                        => 'Nazwa',
+  'New Templates'               => 'Nowe Szablony',
+  'No Database Drivers available!' => 'Sterownik Bazy Danych jest niedostêpny',
+  'No Dataset selected!'        => 'Nie jest zaznaczony Zbiór Danych',
+  'Nothing to delete!'          => 'Niema nic do usuniêcia!',
+  'Number Format'               => 'Format Numeru',
+  'Oracle Database Administration' => 'Administracja Bazy Danych Oracle',
+  'Password'                    => 'Has³o',
+  'Password changed!'           => 'Has³o zmienione',
+  'Pg Database Administration'  => 'Administracja Bazy Danych Pg',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Brak Portu',
+  'Printer'                     => 'Drukarka',
+  'Save'                        => 'Zapisz',
+  'Select a Dataset to delete and press "Continue"' => 'Wybierz Zbiór Danych do usuniêcia i naci¶nij "Kontynuj"',
+  'Setup Templates'             => 'Ustaw Szablony',
+  'Ship via'                    => 'Wy¶lij przez',
+  'Signature'                   => 'Podpis',
+  'Stylesheet'                  => 'Strona Stylowa',
+  'Templates'                   => 'Szablony',
+  'The following Datasets are not in use and can be deleted' => 'Te Zbiory Danych s± nieu¿ywane i mo¿na je usun±æ',
+  'The following Datasets need to be updated' => 'Zbiory Danych do uzupe³nienia',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Jest to wstêpne sprawdzenie istniej±cych ¿róde³. Narazie nic nie bêdzie utworzone lub usuniête.',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => '¯eby dodaæ do grupy u¿ytkownika zmieñ nazwê, nazwê zarejestrowania i zapisz. Nowy u¿ytkownik z tymi samymi zmiennymi warto¶ciami bêdzie zapisany pod now± nazw± rejestruj±c±',
+  'Update Dataset'              => 'Uzupe³nij Zbiór Danych',
+  'Use Templates'               => 'U¿yj Szablony',
+  'User'                        => 'U¿ytkownik',
+  'User deleted!'               => 'U¿ytkownik usuniêty',
+  'User saved!'                 => 'U¿ytkownik zapisany',
+  'Version'                     => 'Wersja',
+  'You must enter a host and port for local and remote connections!' => 'Wstaw wêze³ i port dla lokalnego i zdalnego po³±czenia',
+  'does not exist'              => 'nie istnieje',
+  'is already a member!'        => 'Jest ju¿ cz³onkiem',
+  'localhost'                   => 'host lokalny',
+  'successfully created!'       => 'stworzone z powodzeniem',
+  'successfully deleted!'       => 'usuniête z powodzeniem',
+  'website'                     => 'witryna WWW',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'dodaj_u¿ytkownika'           => 'add_user',
+  'zmiana_has³a_administratora' => 'change_admin_password',
+  'zmieñ_has³o'                 => 'change_password',
+  'kontynuj'                    => 'continue',
+  'utwórz_zbiór_danych'         => 'create_dataset',
+  'usuñ'                        => 'delete',
+  'usuñ_zbior_danych'           => 'delete_dataset',
+  'zarejestrój_siê'             => 'login',
+  'administracja_bazy_danych_oracle' => 'oracle_database_administration',
+  'administracja_bazy_danych_pg' => 'pg_database_administration',
+  'zapisz'                      => 'save',
+  'uzupe³nij_zbiór_danych'      => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/all b/sql-ledger/locale/pl/all
new file mode 100644 (file)
index 0000000..fabdb59
--- /dev/null
@@ -0,0 +1,487 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Ksiêga Zobowi±zañ',
+  'AP Aging'                    => 'Zobowi±zania Przeterminowane',
+  'AP Transaction'              => 'Transakcja Zobowi±zañ',
+  'AP Transactions'             => 'Transakcje Zobowi±zañ',
+  'AR'                          => 'Ksiêga Nale¿no¶ci',
+  'AR Aging'                    => 'Nale¿no¶ci Przeterminowane',
+  'AR Transaction'              => 'Transakcja Nale¿no¶ci',
+  'AR Transactions'             => 'Transakcje Nale¿no¶ci',
+  'About'                       => 'Na Temat',
+  'Access Control'              => 'Kontrola Dostêpu',
+  'Account'                     => 'Konto',
+  'Account Number'              => 'Numer Konta',
+  'Account Number missing!'     => 'Brak Numeru Konta!',
+  'Account Type'                => 'Rodzaj Konta',
+  'Account Type missing!'       => 'Brak Rodzaju Konta!',
+  'Account deleted!'            => 'Usuniêto Konto',
+  'Account saved!'              => 'Zapisano Konto',
+  'Accounting'                  => 'Ksiêgowo¶æ',
+  'Accounting Menu'             => 'Menu Ksiêgowo¶ci',
+  'Accounts'                    => 'Konta',
+  'Active'                      => 'Aktywne',
+  'Add'                         => 'Dodaj',
+  'Add Account'                 => 'Dodaj Konto',
+  'Add Accounts Payables Transaction' => 'Rejestr w Ksiêdze Zobowi±zañ',
+  'Add Accounts Receivables Transaction' => 'Rejestr w Ksiêdze Nale¿no¶ci',
+  'Add Assembly'                => 'Dodaj Zestawienie',
+  'Add Customer'                => 'Dodaj Odbiorcê',
+  'Add GIFI'                    => 'Dodaj GIFI',
+  'Add General Ledger Transaction' => 'Dodaj Transakcjê w Ksiêdze G³ównej',
+  'Add Part'                    => 'Dodaj Produkt',
+  'Add Project'                 => 'Dodaj Projekt',
+  'Add Purchase Invoice'        => 'Zarejestrój Fakturê VAT Zakupu',
+  'Add Purchase Order'          => 'Dodaj Zamówienie Zakupu',
+  'Add Sales Invoice'           => 'Zarejestrój Fakturê VAT Sprzeda¿y',
+  'Add Sales Order'             => 'Dodaj Zamówienie Klienta',
+  'Add Service'                 => 'Dodaj Us³ugi',
+  'Add Transaction'             => 'Dodaj Transakcjê',
+  'Add User'                    => 'Dodaj U¿ytkownika',
+  'Add Vendor'                  => 'Dodaj Dostawcê',
+  'Address'                     => 'Adres',
+  'Administration'              => 'Administracja',
+  'Administrator'               => 'Administrator',
+  'All'                         => 'Wszystko',
+  'All Datasets up to date!'    => 'Zbiory Danych uzupe³nione!',
+  'Amount'                      => 'Kwota',
+  'Amount Due'                  => 'Kwota Nale¿na',
+  'Amount does not equal applied!' => 'Kwota nie jest równa',
+  'Amount missing!'             => 'Brakuje kwoty!',
+  'Applied'                     => 'Zastosowano',
+  'Apr'                         => 'Kwiecieñ',
+  'April'                       => 'Kwiecieñ',
+  'Are you sure you want to delete Invoice Number' => 'Czy chcesz usun±æ Numer Faktury?',
+  'Are you sure you want to delete Order Number' => 'Czy chcesz usun±æ Numer Zamówienia?',
+  'Are you sure you want to delete Transaction' => 'Czy chcesz usun±æ Transakcjê?',
+  'Assemblies'                  => 'Zestawienia',
+  'Assemblies restocked!'       => 'Zestawienia uzupe³nione',
+  'Assembly Number missing!'    => 'Brak Numeru Zestawienia!',
+  'Asset'                       => 'Aktywy',
+  'Attachment'                  => 'Za³±cznik',
+  'Audit Control'               => 'Kontrola Audytu',
+  'Aug'                         => 'Sierpieñ',
+  'August'                      => 'Sierpieñ',
+  'BOM'                         => 'Zestawienie materia³owe',
+  'Backup'                      => 'Kopia Zapasowa',
+  'Backup sent to'              => 'Kopia Zapasowa wys³ana do',
+  'Balance'                     => 'Saldo',
+  'Balance Sheet'               => 'Bilans',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Pojemnik',
+  'Books are open'              => 'Ksiêgi otwarte',
+  'Bought'                      => 'Zakupione',
+  'Business Number'             => 'NIP',
+  'C'                           => 'C',
+  'COGS'                        => 'Koszta Sprzeda¿y',
+  'Cannot delete account!'      => 'Nie mo¿esz usun±æ konta!',
+  'Cannot delete customer!'     => 'Nie mo¿esz usun±æ klienta!',
+  'Cannot delete default account!' => 'Konto Domy¶lne nie mo¿e byæ usuniête!',
+  'Cannot delete invoice!'      => 'Nie mo¿esz usun±æ factury!',
+  'Cannot delete item already invoiced!' => 'Nie mo¿na usun±æ pozycji zafakturowanej!',
+  'Cannot delete item on order!' => 'Nie mo¿na usunac zamówionego produktu!',
+  'Cannot delete item which is part of an assembly!' => 'Nie mo¿na usun±æ czê¶ci z zestawienia!',
+  'Cannot delete item!'         => 'Nie mo¿esz usun±æ pozycji!',
+  'Cannot delete order!'        => 'Nie mo¿esz usun±æ zamówienia!',
+  'Cannot delete transaction!'  => 'Nie mo¿esz usun±æ transakcji!',
+  'Cannot delete vendor!'       => 'Nie mo¿esz usun±æ dostawcy!',
+  'Cannot have a value in both Debit and Credit!' => 'Nie mo¿na wpisaæ warto¶ci w Debet i Kredyt równocze¶nie!',
+  'Cannot post a transaction without a value!' => 'Nie mo¿esz zatwierdziæ transakcji bez warto¶ci',
+  'Cannot post invoice for a closed period!' => 'Nie mo¿na zksiêgowaæ faktury pozamkniêciu okresu!',
+  'Cannot post invoice!'        => 'Nie mo¿esz zatwierdziæ faktury!',
+  'Cannot post payment for a closed period!' => 'Nie mo¿na zaksiêgowaæ p³atno¶ci po zamkniêciu okresu!',
+  'Cannot post payment!'        => 'Nie mo¿esz zatwierdziæ p³atno¶ci!',
+  'Cannot post transaction for a closed period!' => 'Nie mo¿na zaksiêgowaæ transakcji po zamkniêciu okresu!',
+  'Cannot post transaction!'    => 'Nie mo¿esz zatwierdziæ transakcji!',
+  'Cannot process payment for a closed period!' => 'Niemo¿na przetworzyæ p³atno¶ci po zamkniêciu okresu',
+  'Cannot save account!'        => 'Nie mo¿na zapisaæ konta!',
+  'Cannot save order!'          => 'Nie mo¿na zapisaæ zamowienia!',
+  'Cannot save preferences!'    => 'Nie mo¿na zapisaæ preferencji!',
+  'Cannot stock assemblies!'    => 'Nie mo¿na wstawiæ z³o¿enia',
+  'Cash'                        => 'Kasa',
+  'Cash based'                  => 'Tryb Kasowy',
+  'Cc'                          => 'Cc',
+  'Change Admin Password'       => 'Zmiana Has³a Administratora',
+  'Change Password'             => 'Zmieñ Has³o',
+  'Character Set'               => 'Zestaw Znaków',
+  'Chart of Accounts'           => 'Plan Kont',
+  'Check'                       => 'Czek',
+  'Check printed!'              => 'Czek wydrukowany!',
+  'Check printing failed!'      => 'B³±dw drukowaniu czeku',
+  'Cleared Balance'             => 'Zgadzaj±ce Saldo',
+  'Click on login name to edit!' => 'Kliknij  nazwê u¿ytkownika ¿eby dokonaæ zmian!',
+  'Close Books up to'           => 'Zamkniêcie Ksi±g do',
+  'Closed'                      => 'Zamkniêto',
+  'Company'                     => 'Firma',
+  'Compare to'                  => 'Porównaj z',
+  'Confirm!'                    => 'Potwierd¿!',
+  'Connect to'                  => 'Pod³±cz do',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Kontynuj',
+  'Copies'                      => 'Kopie',
+  'Copy to COA'                 => 'Skopiuj do Planu Kont',
+  'Create Chart of Accounts'    => 'Utwórz Wzór Kont',
+  'Create Dataset'              => 'Utwórz Zbiór Danych',
+  'Credit'                      => 'Kredyt',
+  'Credit Limit'                => 'Limit Kredytu',
+  'Curr'                        => 'Waluta',
+  'Currency'                    => 'Waluta',
+  'Current'                     => 'Bi¿±cy',
+  'Customer'                    => 'Klient',
+  'Customer deleted!'           => 'Klient usuniêty',
+  'Customer missing!'           => 'Brak Klienta',
+  'Customer not on file!'       => 'Brak Klienta w bazie danych',
+  'Customer saved!'             => 'Klient zapisany!',
+  'Customers'                   => 'Klienci',
+  'DBI not installed!'          => 'Nie zainstalowane DBI!',
+  'Database'                    => 'Baza Danych',
+  'Database Administration'     => 'Administracja Bazy Danych',
+  'Database Driver not checked!' => 'Sterownik Bazy Danych nie zaznaczony!',
+  'Database Host'               => 'Host Bazy Danych',
+  'Database User missing!'      => 'Brak U¿ytkownika Bazy Danych!',
+  'Dataset'                     => 'Zbiór Danych',
+  'Dataset missing!'            => 'Brak Zbioru Danych',
+  'Dataset updated!'            => 'Zbiór Danych uzupe³niony!',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Termin P³atno¶ci',
+  'Date Format'                 => 'Format Daty',
+  'Date Paid'                   => 'Data Zap³aty',
+  'Date missing!'               => 'Brak Daty',
+  'Debit'                       => 'Debet',
+  'Debit and credit out of balance!' => 'Debet i Kredyt siê niebalansuj±!',
+  'Dec'                         => 'Grudzieñ',
+  'December'                    => 'Grudzieñ',
+  'Decimalplaces'               => 'Miejsca Dziesiêtne',
+  'Delete'                      => 'Usuñ',
+  'Delete Account'              => 'Usuñ Konto',
+  'Delete Dataset'              => 'Usuñ Zbior Danych',
+  'Delivery Date'               => 'Data Dostawy',
+  'Deposit'                     => 'Wp³ata',
+  'Description'                 => 'Opis',
+  'Difference'                  => 'Ró¿nica',
+  'Directory'                   => 'Katalog',
+  'Discount'                    => 'Rabat',
+  'Done'                        => 'Zrobione',
+  'Drawing'                     => 'Rysunek',
+  'Driver'                      => 'Sterownik',
+  'Dropdown Limit'              => 'Limit Rozwiniêcia',
+  'Due'                         => 'P³atno¶æ',
+  'Due Date'                    => 'Termin P³atno¶ci',
+  'Due Date missing!'           => 'Brak Terminu P³atno¶ci!',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'E-mail Wykaz do',
+  'E-mail address missing!'     => 'Brak adresu E-mail!',
+  'Edit'                        => 'Zmieñ',
+  'Edit Account'                => 'Zmiany Konta',
+  'Edit Accounts Payables Transaction' => 'Zmiany Transakcji Konta Zobowi±zañ',
+  'Edit Accounts Receivables Transaction' => 'Zmiany Transakcji Konta Nale¿no¶ci',
+  'Edit Assembly'               => 'Zmiany Zestawieñ',
+  'Edit GIFI'                   => 'Zmieñ GIFI',
+  'Edit General Ledger Transaction' => 'Zmiany w Ksiêdze G³ównej',
+  'Edit Part'                   => 'Zmiany Produktu',
+  'Edit Preferences for'        => 'Zmiany Preferencji dla',
+  'Edit Project'                => 'Zmiany Projektu',
+  'Edit Purchase Invoice'       => 'Zmiany Faktury Zamówienia',
+  'Edit Purchase Order'         => 'Zmiany Zamówienia Zakupu',
+  'Edit Sales Invoice'          => 'Zmiany Faktury Sprzeda¿y',
+  'Edit Sales Order'            => 'Zmiany Zamówienia Klienta',
+  'Edit Service'                => 'Zmiany Us³ug',
+  'Edit Template'               => 'Zmiany Wzorca',
+  'Edit User'                   => 'Zmiany U¿ytkownika',
+  'Employee'                    => 'Pracownik',
+  'Enforce transaction reversal for all dates' => 'Egzekwój zmiany transakcji dla wszystkich okresów',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Wpisz symbole (nap. PLN:USD:EUR:YEN) krajowych i zagranicznych walut ',
+  'Equity'                      => 'Kapita³',
+  'Exch'                        => 'Kurs',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'Exchangerate Difference'     => 'Ró¿nica Kursowa',
+  'Exchangerate for payment missing!' => 'Brakuje kursu wymiany dla p³atno¶ci!',
+  'Exchangerate missing!'       => 'Brakuje kursu wymiany',
+  'Existing Datasets'           => 'Istniej±cy Zbiór Danych',
+  'Expense'                     => 'Koszt',
+  'Expense Account'             => 'Konto Kosztów',
+  'Expense/Asset'               => 'Koszt/Aktywy',
+  'Extended'                    => 'Warto¶æ Netto',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'Foreign Exchange Gain'       => 'Zysk przy Wymianie Walut',
+  'Foreign Exchange Loss'       => 'Strata przy Wymianie Walut',
+  'From'                        => 'Od',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI usuniête',
+  'GIFI missing!'               => 'Brakuje GIFI',
+  'GIFI saved!'                 => 'GIFI zapisane',
+  'GL Transaction'              => 'Transakcja Ksiêgi G³ównej',
+  'General Ledger'              => 'Ksiêga G³ówna',
+  'Goods & Services'            => 'Produkty i Us³ugi',
+  'HTML Templates'              => 'Szablony HTML',
+  'Heading'                     => 'Nag³ówek',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Brak Nazwy Hosta',
+  'ID'                          => 'Identyfikator',
+  'Image'                       => 'Grafika',
+  'In-line'                     => 'W³±czony',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Include in drop-down menus'  => 'Do³±cz w menu rozwijanym',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Do³±cz Konto w formularzach Kontrachentów ¿eby wskazaæ ¿e podlegaj± opodatkowaniu',
+  'Income'                      => 'Przychód',
+  'Income Account'              => 'Konto Przychodów',
+  'Income Statement'            => 'Rachunek Zysków i Strat',
+  'Incorrect Dataset version!'  => 'Nieprawid³owa wersja Zbioru Danych',
+  'Incorrect Password!'         => 'Nieprawid³owe Has³o',
+  'Individual Items'            => 'Indywidualne Czê¶ci',
+  'Inventory'                   => 'Inwentarz',
+  'Inventory Account'           => 'Konto Materia³owe',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Ilo¶æ Inventarza musi byæ równa zero zanim bêdzie mozna zdezaktualizowaæ to z³o¿enie!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Ilo¶æ inventarza musi byæ równa zero zanim bêdzie mo¿na zdezaktualizowaæ t± czê¶æ!',
+  'Inventory quantity must be zero!' => 'Ilo¶æc Inventarza musi byæ równa zero',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Data Wystawienia',
+  'Invoice Date missing!'       => 'Brak Daty Wystawienia',
+  'Invoice Number'              => 'Numer Faktury',
+  'Invoice Number missing!'     => 'Brak Numeru Faktury',
+  'Invoice deleted!'            => 'Faktura usuniêta',
+  'Invoice posted!'             => 'Faktura zatwierdzona',
+  'Invoices'                    => 'Faktury',
+  'Is this a summary account to record' => 'Czy jest to konto sumaryczne?',
+  'Item deleted!'               => 'Pozycja usuniêta',
+  'Item not on file!'           => 'Produkt nie jest w zbiorze!',
+  'Jan'                         => 'Styczeñ',
+  'January'                     => 'Styczeñ',
+  'Jul'                         => 'Lipiec',
+  'July'                        => 'Lipiec',
+  'Jun'                         => 'Czerwiec',
+  'June'                        => 'Czerwiec',
+  'LaTeX Templates'             => 'Szablony LaTeX',
+  'Language'                    => 'Jêzyk',
+  'Last Cost'                   => 'Cena Zakupu',
+  'Last Invoice Number'         => 'Ostatni Numer Faktury',
+  'Last Numbers & Default Accounts' => 'Ostatnie Numery i Konta Domy¶lne',
+  'Last Purchase Order Number'  => 'Ostatni Numer Faktury Zamówienia',
+  'Last Sales Order Number'     => 'Ostatni Numer Faktury Sprzeda¿y',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Opu¶æ pole wêz³a i portu, chyba ¿e chcesz mieæ zdalne po³±czenie',
+  'Liability'                   => 'Zobowi±zania',
+  'Licensed to'                 => 'Licencja nale¿y do:',
+  'Line Total'                  => 'Suma ca³kowita',
+  'Link'                        => 'Dowi±zanie',
+  'Link Accounts'               => 'Konta dowi±zane',
+  'List Accounts'               => 'Spis Kont',
+  'List GIFI'                   => 'Wykaz GIFI',
+  'List Price'                  => 'Cena',
+  'List Transactions'           => 'Wykaz Transakcji',
+  'Login'                       => 'Zarejestrój siê',
+  'Logout'                      => 'Wyrejestrój siê',
+  'Make'                        => 'Marka',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'Microfiche'                  => 'Mikrofilm',
+  'Model'                       => 'Model',
+  'N/A'                         => 'N/A',
+  'Name'                        => 'Nazwa',
+  'Name missing!'               => 'Brak Nazwy',
+  'New Templates'               => 'Nowe Szablony',
+  'No'                          => 'Nie',
+  'No Database Drivers available!' => 'Sterownik Bazy Danych jest niedostêpny',
+  'No Dataset selected!'        => 'Nie jest zaznaczony Zbiór Danych',
+  'No email address for'        => 'Brak adresu email',
+  'No.'                         => '',
+  'Notes'                       => 'Noty',
+  'Nothing applied!'            => 'Niczego nie zastosowano',
+  'Nothing selected!'           => 'Nic nie zaznaczone!',
+  'Nothing to delete!'          => 'Niema nic do usuniêcia!',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Number Format'               => 'Format Numeru',
+  'Number missing in Row'       => 'Brak Numeru w Rzêdzie',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Zdezaktualizowane',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'On Hand'                     => 'Na Stanie',
+  'On Order'                    => 'Zamawiane',
+  'Open'                        => 'Otworzono',
+  'Oracle Database Administration' => 'Administracja Bazy Danych Oracle',
+  'Order'                       => 'Zamówienie',
+  'Order Date'                  => 'Data Zamówienia',
+  'Order Date missing!'         => 'Brak Daty Zamówienia',
+  'Order Entry'                 => 'Wystawianie Zamówieñ',
+  'Order Number'                => 'Numer Zamówienia',
+  'Order Number missing!'       => 'Brak Numeru Zamówienia',
+  'Order deleted!'              => 'Zamówienie usuniête',
+  'Order saved!'                => 'Zamówienie zapisane',
+  'Ordered'                     => 'Zamówione',
+  'Orphaned'                    => 'Zbêdne',
+  'Out of balance!'             => 'Niezgodne Saldo',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Packing List Date missing!'  => 'Brak Daty Wykazu Dostawy',
+  'Packing List Number missing!' => 'Brak Numeru Wykazu Dostawy',
+  'Paid'                        => 'Zap³acono',
+  'Paid in full'                => 'Zap³acono w ca³o¶ci',
+  'Part'                        => 'Produkt',
+  'Part Number missing!'        => 'Brak Symbolu Produktu!',
+  'Parts'                       => 'Produkty',
+  'Parts Inventory'             => 'Inwentarz',
+  'Password'                    => 'Has³o',
+  'Password changed!'           => 'Has³o zmienione',
+  'Payables'                    => 'Zobowi±zania',
+  'Payment'                     => 'P³atno¶æ',
+  'Payment date missing!'       => 'Brak Daty P³atno¶ci',
+  'Payment posted!'             => 'P³atno¶æ zatwierdzona',
+  'Payments'                    => 'P³atno¶ci',
+  'Pg Database Administration'  => 'Administracja Bazy Danych Pg',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Brak Portu',
+  'Post'                        => 'Zatwierd¿',
+  'Post as new'                 => 'Zatwierd¿ jako nowe',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Preferencje',
+  'Preferences saved!'          => 'Preferencje Zapisane!',
+  'Price'                       => 'Cena Netto',
+  'Print'                       => 'Drukuj',
+  'Printer'                     => 'Drukarka',
+  'Project'                     => 'Projekt',
+  'Project Number missing!'     => 'Brak Numeru Projektu',
+  'Project deleted!'            => 'Projekt usuniêty',
+  'Project not on file!'        => 'Brak Projektu w zbiorze danych!',
+  'Project saved!'              => 'Projekt zapisany',
+  'Projects'                    => 'Projekty',
+  'Purchase Invoice'            => 'Faktura VAT Zakupu',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Purchase Orders'             => 'Zamówienia Zakupu',
+  'Qty'                         => 'Ilo¶æ',
+  'ROP'                         => 'PPZ',
+  'Rate'                        => 'Stawka',
+  'Recd'                        => 'Otrzymano',
+  'Receipt'                     => 'Wp³ata',
+  'Receipts'                    => 'Wp³aty',
+  'Receivables'                 => 'Nale¿no¶ci',
+  'Reconciliation'              => 'Zgodno¶æ Rozliczeñ',
+  'Record in'                   => 'Zapisz w',
+  'Reference'                   => 'Odno¶nik',
+  'Reference missing!'          => 'Brak Odno¶nika',
+  'Remaining'                   => 'Pozosta³e',
+  'Report for'                  => 'Raport dla',
+  'Reports'                     => 'Sprawozdania',
+  'Required by'                 => 'Termin Dostawy',
+  'Retained Earnings'           => 'Zysk',
+  'Sales'                       => 'Sprzeda¿',
+  'Sales Invoice'               => 'Faktura VAT Sprzeda¿y',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Sales Orders'                => 'Zamówienia Klientów',
+  'Save'                        => 'Zapisz',
+  'Save as new'                 => 'Zapisz jako nowe',
+  'Save to File'                => 'Zapisz w zbiorze',
+  'Screen'                      => 'Ekran',
+  'Select a Dataset to delete and press "Continue"' => 'Wybierz Zbiór Danych do usuniêcia i naci¶nij "Kontynuj"',
+  'Select all'                  => 'Wybierz wszystko',
+  'Select from one of the items below' => 'Wybierz jeden z poni¿szych artyku³ów',
+  'Select from one of the names below' => 'Wybierz nazwê z poni¿szych',
+  'Select from one of the projects below' => 'Wybierz z projektów',
+  'Select postscript or PDF!'   => 'Wybierz postscript lub PDF',
+  'Sell Price'                  => 'Cena Sprzeda¿y',
+  'Send by E-Mail'              => 'Wys³ano przy u¿yciu E-Mail',
+  'Sep'                         => 'Wrzesieñ',
+  'September'                   => 'Wrzesieñ',
+  'Service'                     => 'Us³ugi',
+  'Service Items'               => 'Artyku³y Us³ugowe',
+  'Service Number missing!'     => 'Brak Numeru Us³ugi!',
+  'Services'                    => 'Us³ugi',
+  'Setup Templates'             => 'Ustaw Szablony',
+  'Ship'                        => 'Wy¶lij',
+  'Ship to'                     => 'Wy¶lij do',
+  'Ship via'                    => 'Wy¶lij przez',
+  'Short'                       => 'Niedobór',
+  'Signature'                   => 'Podpis',
+  'Sold'                        => 'Sprzedane',
+  'Source'                      => '¯ród³o',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Wykaz',
+  'Statement Balance'           => 'Wykaz Salda',
+  'Statement sent to'           => 'Wykaz wys³any do',
+  'Statements sent to printer!' => 'Wykaz wys³any do drukarki',
+  'Stock Assembly'              => 'Wstaw Z³o¿enie',
+  'Stylesheet'                  => 'Strona Stylowa',
+  'Subject'                     => 'Tre¶æ',
+  'Subtotal'                    => 'Warto¶æ Netto',
+  'System'                      => 'System',
+  'Tax'                         => 'Podatek',
+  'Tax Accounts'                => 'Konta Podatkowe',
+  'Tax Included'                => 'Podatek Wliczony',
+  'Tax collected'               => 'Podatek pobrany',
+  'Tax paid'                    => 'Podatek zap³acony',
+  'Taxable'                     => 'Opodatkowane',
+  'Template saved!'             => 'Szablon zapisany',
+  'Templates'                   => 'Szablony',
+  'Terms: Net'                  => 'Warunki: Netto',
+  'The following Datasets are not in use and can be deleted' => 'Te Zbiory Danych s± nieu¿ywane i mo¿na je usun±æ',
+  'The following Datasets need to be updated' => 'Zbiory Danych do uzupe³nienia',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Jest to wstêpne sprawdzenie istniej±cych ¿róde³. Narazie nic nie bêdzie utworzone lub usuniête.',
+  'To'                          => 'do',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => '¯eby dodaæ do grupy u¿ytkownika zmieñ nazwê, nazwê zarejestrowania i zapisz. Nowy u¿ytkownik z tymi samymi zmiennymi warto¶ciami bêdzie zapisany pod now± nazw± rejestruj±c±',
+  'Top Level'                   => 'Najwy¿szy Poziom',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Transaction Date missing!'   => 'Brak Daty Transakcji!',
+  'Transaction deleted!'        => 'Transakcja usuniêta',
+  'Transaction posted!'         => 'Transakcja zatwierdzona',
+  'Transaction reversal enforced for all dates' => 'Zmiana transakcji narzucona dla wszystkich okresów',
+  'Transaction reversal enforced up to' => 'Zmiana transakcji narzucona do',
+  'Transactions'                => 'Transakcje',
+  'Transactions exist, cannot delete customer!' => 'Istniej± Transakcje, niemo¿na usun±æ odbiorcy',
+  'Transactions exist, cannot delete vendor!' => 'Istniej± Transakcje, nie mo¿na usun±æ dostawcy',
+  'Transactions exist; cannot delete account!' => 'Istniej± Transakcje, nie mo¿na usun±æ konta',
+  'Trial Balance'               => 'Bilans Porównawczy',
+  'Unit'                        => 'Jednostka',
+  'Unit of measure'             => 'Jednostka miary',
+  'Update'                      => 'Uzupe³nij',
+  'Update Dataset'              => 'Uzupe³nij Zbiór Danych',
+  'Updated'                     => 'Uzupe³nione',
+  'Use Templates'               => 'U¿yj Szablony',
+  'User'                        => 'U¿ytkownik',
+  'User deleted!'               => 'U¿ytkownik usuniêty',
+  'User saved!'                 => 'U¿ytkownik zapisany',
+  'Vendor'                      => 'Dostawca',
+  'Vendor deleted!'             => 'Dostawca usuniêty',
+  'Vendor missing!'             => 'Brak Dostawcy',
+  'Vendor not on file!'         => 'Brak Dostawcy w bazie danych',
+  'Vendor saved!'               => 'Dostawca zapisany',
+  'Vendors'                     => 'Dostawcy',
+  'Version'                     => 'Wersja',
+  'Weight'                      => 'Waga',
+  'Weight Unit'                 => 'Jednostka Wagi',
+  'What type of item is this?'  => 'Co to za rodzaj artyku³u',
+  'Year End'                    => 'Koniec Roku Finansowego',
+  'Yes'                         => 'Tak',
+  'You are logged out!'         => 'Jeste¶ wyrejestrowany!',
+  'You did not enter a name!'   => 'Nie wstawiono nazwy!',
+  'You must enter a host and port for local and remote connections!' => 'Wstaw wêze³ i port dla lokalnego i zdalnego po³±czenia',
+  'as at'                       => 'tak samo',
+  'collected on sales'          => 'zebrany przy sprzeda¿y',
+  'days'                        => 'dni',
+  'does not exist'              => 'nie istnieje',
+  'ea'                          => 'szt',
+  'emailed to'                  => 'email do',
+  'for Period'                  => 'za Okres',
+  'hr'                          => 'godz',
+  'is already a member!'        => 'Jest ju¿ cz³onkiem',
+  'is not a member!'            => 'Nie jest cz³onkiem',
+  'localhost'                   => 'host lokalny',
+  'paid on purchases'           => 'zap³acony przy zakupach',
+  'sent to printer'             => 'wys³ano do drukarki',
+  'successfully created!'       => 'stworzone z powodzeniem',
+  'successfully deleted!'       => 'usuniête z powodzeniem',
+  'to'                          => 'do',
+  'website'                     => 'witryna WWW',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/am b/sql-ledger/locale/pl/am
new file mode 100644 (file)
index 0000000..98de453
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Ksiêga Zobowi±zañ',
+  'AR'                          => 'Ksiêga Nale¿no¶ci',
+  'Account'                     => 'Konto',
+  'Account Number'              => 'Numer Konta',
+  'Account Number missing!'     => 'Brak Numeru Konta!',
+  'Account Type'                => 'Rodzaj Konta',
+  'Account Type missing!'       => 'Brak Rodzaju Konta!',
+  'Account deleted!'            => 'Usuniêto Konto',
+  'Account saved!'              => 'Zapisano Konto',
+  'Add Account'                 => 'Dodaj Konto',
+  'Add GIFI'                    => 'Dodaj GIFI',
+  'Address'                     => 'Adres',
+  'Asset'                       => 'Aktywy',
+  'Audit Control'               => 'Kontrola Audytu',
+  'Backup sent to'              => 'Kopia Zapasowa wys³ana do',
+  'Books are open'              => 'Ksiêgi otwarte',
+  'Business Number'             => 'NIP',
+  'COGS'                        => 'Koszta Sprzeda¿y',
+  'Cannot delete account!'      => 'Nie mo¿esz usun±æ konta!',
+  'Cannot delete default account!' => 'Konto Domy¶lne nie mo¿e byæ usuniête!',
+  'Cannot save account!'        => 'Nie mo¿na zapisaæ konta!',
+  'Cannot save preferences!'    => 'Nie mo¿na zapisaæ preferencji!',
+  'Character Set'               => 'Zestaw Znaków',
+  'Chart of Accounts'           => 'Plan Kont',
+  'Close Books up to'           => 'Zamkniêcie Ksi±g do',
+  'Company'                     => 'Firma',
+  'Continue'                    => 'Kontynuj',
+  'Copy to COA'                 => 'Skopiuj do Planu Kont',
+  'Credit'                      => 'Kredyt',
+  'Date Format'                 => 'Format Daty',
+  'Debit'                       => 'Debet',
+  'Delete'                      => 'Usuñ',
+  'Delete Account'              => 'Usuñ Konto',
+  'Description'                 => 'Opis',
+  'Dropdown Limit'              => 'Limit Rozwiniêcia',
+  'E-mail'                      => 'E-mail',
+  'Edit'                        => 'Zmieñ',
+  'Edit Account'                => 'Zmiany Konta',
+  'Edit GIFI'                   => 'Zmieñ GIFI',
+  'Edit Preferences for'        => 'Zmiany Preferencji dla',
+  'Edit Template'               => 'Zmiany Wzorca',
+  'Enforce transaction reversal for all dates' => 'Egzekwój zmiany transakcji dla wszystkich okresów',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Wpisz symbole (nap. PLN:USD:EUR:YEN) krajowych i zagranicznych walut ',
+  'Equity'                      => 'Kapita³',
+  'Expense'                     => 'Koszt',
+  'Expense Account'             => 'Konto Kosztów',
+  'Expense/Asset'               => 'Koszt/Aktywy',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Zysk przy Wymianie Walut',
+  'Foreign Exchange Loss'       => 'Strata przy Wymianie Walut',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI usuniête',
+  'GIFI missing!'               => 'Brakuje GIFI',
+  'GIFI saved!'                 => 'GIFI zapisane',
+  'Heading'                     => 'Nag³ówek',
+  'Include in drop-down menus'  => 'Do³±cz w menu rozwijanym',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Do³±cz Konto w formularzach Kontrachentów ¿eby wskazaæ ¿e podlegaj± opodatkowaniu',
+  'Income'                      => 'Przychód',
+  'Income Account'              => 'Konto Przychodów',
+  'Inventory'                   => 'Inwentarz',
+  'Inventory Account'           => 'Konto Materia³owe',
+  'Is this a summary account to record' => 'Czy jest to konto sumaryczne?',
+  'Language'                    => 'Jêzyk',
+  'Last Invoice Number'         => 'Ostatni Numer Faktury',
+  'Last Numbers & Default Accounts' => 'Ostatnie Numery i Konta Domy¶lne',
+  'Last Purchase Order Number'  => 'Ostatni Numer Faktury Zamówienia',
+  'Last Sales Order Number'     => 'Ostatni Numer Faktury Sprzeda¿y',
+  'Liability'                   => 'Zobowi±zania',
+  'Link'                        => 'Dowi±zanie',
+  'Name'                        => 'Nazwa',
+  'No'                          => 'Nie',
+  'No email address for'        => 'Brak adresu email',
+  'Number'                      => 'Numer Katalogu',
+  'Number Format'               => 'Format Numeru',
+  'Parts Inventory'             => 'Inwentarz',
+  'Password'                    => 'Has³o',
+  'Payables'                    => 'Zobowi±zania',
+  'Payment'                     => 'P³atno¶æ',
+  'Phone'                       => 'Tel.',
+  'Preferences saved!'          => 'Preferencje Zapisane!',
+  'Rate'                        => 'Stawka',
+  'Receivables'                 => 'Nale¿no¶ci',
+  'Sales'                       => 'Sprzeda¿',
+  'Save'                        => 'Zapisz',
+  'Service Items'               => 'Artyku³y Us³ugowe',
+  'Ship via'                    => 'Wy¶lij przez',
+  'Signature'                   => 'Podpis',
+  'Stylesheet'                  => 'Strona Stylowa',
+  'Tax'                         => 'Podatek',
+  'Tax Accounts'                => 'Konta Podatkowe',
+  'Template saved!'             => 'Szablon zapisany',
+  'Transaction reversal enforced for all dates' => 'Zmiana transakcji narzucona dla wszystkich okresów',
+  'Transaction reversal enforced up to' => 'Zmiana transakcji narzucona do',
+  'Transactions exist; cannot delete account!' => 'Istniej± Transakcje, nie mo¿na usun±æ konta',
+  'Weight Unit'                 => 'Jednostka Wagi',
+  'Year End'                    => 'Koniec Roku Finansowego',
+  'Yes'                         => 'Tak',
+  'does not exist'              => 'nie istnieje',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'dodaj_konto'                 => 'add_account',
+  'kontynuj'                    => 'continue',
+  'skopiuj_do_planu_kont'       => 'copy_to_coa',
+  'usuñ'                        => 'delete',
+  'zmieñ'                       => 'edit',
+  'zmiany_konta'                => 'edit_account',
+  'zapisz'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/ap b/sql-ledger/locale/pl/ap
new file mode 100644 (file)
index 0000000..5e5f8f8
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Transakcja Zobowi±zañ',
+  'AP Transactions'             => 'Transakcje Zobowi±zañ',
+  'Account'                     => 'Konto',
+  'Add Accounts Payables Transaction' => 'Rejestr w Ksiêdze Zobowi±zañ',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Kwota',
+  'Amount Due'                  => 'Kwota Nale¿na',
+  'Apr'                         => 'Kwiecieñ',
+  'April'                       => 'Kwiecieñ',
+  'Are you sure you want to delete Transaction' => 'Czy chcesz usun±æ Transakcjê?',
+  'Aug'                         => 'Sierpieñ',
+  'August'                      => 'Sierpieñ',
+  'Cannot delete transaction!'  => 'Nie mo¿esz usun±æ transakcji!',
+  'Cannot post payment for a closed period!' => 'Nie mo¿na zaksiêgowaæ p³atno¶ci po zamkniêciu okresu!',
+  'Cannot post transaction for a closed period!' => 'Nie mo¿na zaksiêgowaæ transakcji po zamkniêciu okresu!',
+  'Cannot post transaction!'    => 'Nie mo¿esz zatwierdziæ transakcji!',
+  'Closed'                      => 'Zamkniêto',
+  'Confirm!'                    => 'Potwierd¿!',
+  'Continue'                    => 'Kontynuj',
+  'Currency'                    => 'Waluta',
+  'Customer not on file!'       => 'Brak Klienta w bazie danych',
+  'Date'                        => 'Data',
+  'Date Paid'                   => 'Data Zap³aty',
+  'Dec'                         => 'Grudzieñ',
+  'December'                    => 'Grudzieñ',
+  'Delete'                      => 'Usuñ',
+  'Description'                 => 'Opis',
+  'Due Date'                    => 'Termin P³atno¶ci',
+  'Due Date missing!'           => 'Brak Terminu P³atno¶ci!',
+  'Edit Accounts Payables Transaction' => 'Zmiany Transakcji Konta Zobowi±zañ',
+  'Employee'                    => 'Pracownik',
+  'Exch'                        => 'Kurs',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'Exchangerate for payment missing!' => 'Brakuje kursu wymiany dla p³atno¶ci!',
+  'Exchangerate missing!'       => 'Brakuje kursu wymiany',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'ID'                          => 'Identyfikator',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Data Wystawienia',
+  'Invoice Date missing!'       => 'Brak Daty Wystawienia',
+  'Invoice Number'              => 'Numer Faktury',
+  'Invoice Number missing!'     => 'Brak Numeru Faktury',
+  'Jan'                         => 'Styczeñ',
+  'January'                     => 'Styczeñ',
+  'Jul'                         => 'Lipiec',
+  'July'                        => 'Lipiec',
+  'Jun'                         => 'Czerwiec',
+  'June'                        => 'Czerwiec',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Open'                        => 'Otworzono',
+  'Order'                       => 'Zamówienie',
+  'Order Number'                => 'Numer Zamówienia',
+  'Paid'                        => 'Zap³acono',
+  'Payment date missing!'       => 'Brak Daty P³atno¶ci',
+  'Payments'                    => 'P³atno¶ci',
+  'Post'                        => 'Zatwierd¿',
+  'Post as new'                 => 'Zatwierd¿ jako nowe',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Brak Projektu w zbiorze danych!',
+  'Purchase Invoice'            => 'Faktura VAT Zakupu',
+  'Select from one of the names below' => 'Wybierz nazwê z poni¿szych',
+  'Select from one of the projects below' => 'Wybierz z projektów',
+  'Sep'                         => 'Wrzesieñ',
+  'September'                   => 'Wrzesieñ',
+  'Source'                      => '¯ród³o',
+  'Subtotal'                    => 'Warto¶æ Netto',
+  'Tax'                         => 'Podatek',
+  'Tax Included'                => 'Podatek Wliczony',
+  'To'                          => 'do',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Transaction deleted!'        => 'Transakcja usuniêta',
+  'Transaction posted!'         => 'Transakcja zatwierdzona',
+  'Update'                      => 'Uzupe³nij',
+  'Vendor'                      => 'Dostawca',
+  'Vendor missing!'             => 'Brak Dostawcy',
+  'Vendor not on file!'         => 'Brak Dostawcy w bazie danych',
+  'Yes'                         => 'Tak',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'transakcja_zobowi±zañ'       => 'ap_transaction',
+  'rejestr_w_ksiêdze_zobowi±zañ' => 'add_accounts_payables_transaction',
+  'kontynuj'                    => 'continue',
+  'usuñ'                        => 'delete',
+  'zmiany_transakcji_konta_zobowi±zañ' => 'edit_accounts_payables_transaction',
+  'zatwierd¿'                   => 'post',
+  'zatwierd¿_jako_nowe'         => 'post_as_new',
+  'faktura_vat_zakupu'          => 'purchase_invoice',
+  'uzupe³nij'                   => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/ar b/sql-ledger/locale/pl/ar
new file mode 100644 (file)
index 0000000..22a90b8
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'Transakcja Nale¿no¶ci',
+  'AR Transactions'             => 'Transakcje Nale¿no¶ci',
+  'Account'                     => 'Konto',
+  'Add Accounts Receivables Transaction' => 'Rejestr w Ksiêdze Nale¿no¶ci',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Kwota',
+  'Amount Due'                  => 'Kwota Nale¿na',
+  'Apr'                         => 'Kwiecieñ',
+  'April'                       => 'Kwiecieñ',
+  'Are you sure you want to delete Transaction' => 'Czy chcesz usun±æ Transakcjê?',
+  'Aug'                         => 'Sierpieñ',
+  'August'                      => 'Sierpieñ',
+  'Cannot delete transaction!'  => 'Nie mo¿esz usun±æ transakcji!',
+  'Cannot post payment for a closed period!' => 'Nie mo¿na zaksiêgowaæ p³atno¶ci po zamkniêciu okresu!',
+  'Cannot post transaction for a closed period!' => 'Nie mo¿na zaksiêgowaæ transakcji po zamkniêciu okresu!',
+  'Cannot post transaction!'    => 'Nie mo¿esz zatwierdziæ transakcji!',
+  'Closed'                      => 'Zamkniêto',
+  'Confirm!'                    => 'Potwierd¿!',
+  'Continue'                    => 'Kontynuj',
+  'Credit Limit'                => 'Limit Kredytu',
+  'Currency'                    => 'Waluta',
+  'Customer'                    => 'Klient',
+  'Customer missing!'           => 'Brak Klienta',
+  'Customer not on file!'       => 'Brak Klienta w bazie danych',
+  'Date'                        => 'Data',
+  'Date Paid'                   => 'Data Zap³aty',
+  'Dec'                         => 'Grudzieñ',
+  'December'                    => 'Grudzieñ',
+  'Delete'                      => 'Usuñ',
+  'Description'                 => 'Opis',
+  'Due Date'                    => 'Termin P³atno¶ci',
+  'Due Date missing!'           => 'Brak Terminu P³atno¶ci!',
+  'Edit Accounts Receivables Transaction' => 'Zmiany Transakcji Konta Nale¿no¶ci',
+  'Employee'                    => 'Pracownik',
+  'Exch'                        => 'Kurs',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'Exchangerate for payment missing!' => 'Brakuje kursu wymiany dla p³atno¶ci!',
+  'Exchangerate missing!'       => 'Brakuje kursu wymiany',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'ID'                          => 'Identyfikator',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Data Wystawienia',
+  'Invoice Date missing!'       => 'Brak Daty Wystawienia',
+  'Invoice Number'              => 'Numer Faktury',
+  'Invoice Number missing!'     => 'Brak Numeru Faktury',
+  'Jan'                         => 'Styczeñ',
+  'January'                     => 'Styczeñ',
+  'Jul'                         => 'Lipiec',
+  'July'                        => 'Lipiec',
+  'Jun'                         => 'Czerwiec',
+  'June'                        => 'Czerwiec',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Open'                        => 'Otworzono',
+  'Order'                       => 'Zamówienie',
+  'Order Number'                => 'Numer Zamówienia',
+  'Paid'                        => 'Zap³acono',
+  'Payment date missing!'       => 'Brak Daty P³atno¶ci',
+  'Payments'                    => 'P³atno¶ci',
+  'Post'                        => 'Zatwierd¿',
+  'Post as new'                 => 'Zatwierd¿ jako nowe',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Brak Projektu w zbiorze danych!',
+  'Remaining'                   => 'Pozosta³e',
+  'Sales Invoice'               => 'Faktura VAT Sprzeda¿y',
+  'Select from one of the names below' => 'Wybierz nazwê z poni¿szych',
+  'Select from one of the projects below' => 'Wybierz z projektów',
+  'Sep'                         => 'Wrzesieñ',
+  'September'                   => 'Wrzesieñ',
+  'Source'                      => '¯ród³o',
+  'Subtotal'                    => 'Warto¶æ Netto',
+  'Tax'                         => 'Podatek',
+  'Tax Included'                => 'Podatek Wliczony',
+  'To'                          => 'do',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Transaction deleted!'        => 'Transakcja usuniêta',
+  'Transaction posted!'         => 'Transakcja zatwierdzona',
+  'Update'                      => 'Uzupe³nij',
+  'Vendor not on file!'         => 'Brak Dostawcy w bazie danych',
+  'Yes'                         => 'Tak',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'transakcja_nale¿no¶ci'       => 'ar_transaction',
+  'kontynuj'                    => 'continue',
+  'usuñ'                        => 'delete',
+  'zatwierd¿'                   => 'post',
+  'zatwierd¿_jako_nowe'         => 'post_as_new',
+  'faktura_vat_sprzeda¿y'       => 'sales_invoice',
+  'uzupe³nij'                   => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/arap b/sql-ledger/locale/pl/arap
new file mode 100644 (file)
index 0000000..b24860e
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Adres',
+  'Continue'                    => 'Kontynuj',
+  'Customer not on file!'       => 'Brak Klienta w bazie danych',
+  'Description'                 => 'Opis',
+  'Number'                      => 'Numer Katalogu',
+  'Project not on file!'        => 'Brak Projektu w zbiorze danych!',
+  'Select from one of the names below' => 'Wybierz nazwê z poni¿szych',
+  'Select from one of the projects below' => 'Wybierz z projektów',
+  'Vendor not on file!'         => 'Brak Dostawcy w bazie danych',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'kontynuj'                    => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/ca b/sql-ledger/locale/pl/ca
new file mode 100644 (file)
index 0000000..07f9e6d
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Apr'                         => 'Kwiecieñ',
+  'April'                       => 'Kwiecieñ',
+  'Aug'                         => 'Sierpieñ',
+  'August'                      => 'Sierpieñ',
+  'Balance'                     => 'Saldo',
+  'Chart of Accounts'           => 'Plan Kont',
+  'Credit'                      => 'Kredyt',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Debet',
+  'Dec'                         => 'Grudzieñ',
+  'December'                    => 'Grudzieñ',
+  'Description'                 => 'Opis',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Jan'                         => 'Styczeñ',
+  'January'                     => 'Styczeñ',
+  'Jul'                         => 'Lipiec',
+  'July'                        => 'Lipiec',
+  'Jun'                         => 'Czerwiec',
+  'June'                        => 'Czerwiec',
+  'List Transactions'           => 'Wykaz Transakcji',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Reference'                   => 'Odno¶nik',
+  'Sep'                         => 'Wrzesieñ',
+  'September'                   => 'Wrzesieñ',
+  'Subtotal'                    => 'Warto¶æ Netto',
+  'To'                          => 'do',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'wykaz_transakcji'            => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/cp b/sql-ledger/locale/pl/cp
new file mode 100644 (file)
index 0000000..bd154d9
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Kwota',
+  'Amount does not equal applied!' => 'Kwota nie jest równa',
+  'Amount missing!'             => 'Brakuje kwoty!',
+  'Applied'                     => 'Zastosowano',
+  'Cannot post payment!'        => 'Nie mo¿esz zatwierdziæ p³atno¶ci!',
+  'Cannot process payment for a closed period!' => 'Niemo¿na przetworzyæ p³atno¶ci po zamkniêciu okresu',
+  'Check'                       => 'Czek',
+  'Check printed!'              => 'Czek wydrukowany!',
+  'Check printing failed!'      => 'B³±dw drukowaniu czeku',
+  'Continue'                    => 'Kontynuj',
+  'Currency'                    => 'Waluta',
+  'Customer'                    => 'Klient',
+  'Customer not on file!'       => 'Brak Klienta w bazie danych',
+  'Date'                        => 'Data',
+  'Date missing!'               => 'Brak Daty',
+  'Description'                 => 'Opis',
+  'Due'                         => 'P³atno¶æ',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'From'                        => 'Od',
+  'Invoice'                     => 'Faktura',
+  'Invoices'                    => 'Faktury',
+  'Nothing applied!'            => 'Niczego nie zastosowano',
+  'Number'                      => 'Numer Katalogu',
+  'Paid in full'                => 'Zap³acono w ca³o¶ci',
+  'Payment'                     => 'P³atno¶æ',
+  'Payment posted!'             => 'P³atno¶æ zatwierdzona',
+  'Post'                        => 'Zatwierd¿',
+  'Print'                       => 'Drukuj',
+  'Printer'                     => 'Drukarka',
+  'Project not on file!'        => 'Brak Projektu w zbiorze danych!',
+  'Receipt'                     => 'Wp³ata',
+  'Reference'                   => 'Odno¶nik',
+  'Screen'                      => 'Ekran',
+  'Select from one of the names below' => 'Wybierz nazwê z poni¿szych',
+  'Select from one of the projects below' => 'Wybierz z projektów',
+  'To'                          => 'do',
+  'Update'                      => 'Uzupe³nij',
+  'Vendor'                      => 'Dostawca',
+  'Vendor not on file!'         => 'Brak Dostawcy w bazie danych',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'kontynuj'                    => 'continue',
+  'zatwierd¿'                   => 'post',
+  'drukuj'                      => 'print',
+  'uzupe³nij'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/ct b/sql-ledger/locale/pl/ct
new file mode 100644 (file)
index 0000000..e210cda
--- /dev/null
@@ -0,0 +1,69 @@
+$self{texts} = {
+  'Add'                         => 'Dodaj',
+  'Address'                     => 'Adres',
+  'All'                         => 'Wszystko',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Nie mo¿esz usun±æ klienta!',
+  'Cannot delete vendor!'       => 'Nie mo¿esz usun±æ dostawcy!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Kontynuj',
+  'Credit Limit'                => 'Limit Kredytu',
+  'Customer deleted!'           => 'Klient usuniêty',
+  'Customer saved!'             => 'Klient zapisany!',
+  'Customers'                   => 'Klienci',
+  'Delete'                      => 'Usuñ',
+  'Discount'                    => 'Rabat',
+  'E-mail'                      => 'E-mail',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Invoice'                     => 'Faktura',
+  'Name'                        => 'Nazwa',
+  'Name missing!'               => 'Brak Nazwy',
+  'Notes'                       => 'Noty',
+  'Number'                      => 'Numer Katalogu',
+  'Order'                       => 'Zamówienie',
+  'Orphaned'                    => 'Zbêdne',
+  'Phone'                       => 'Tel.',
+  'Save'                        => 'Zapisz',
+  'Ship to'                     => 'Wy¶lij do',
+  'Tax Included'                => 'Podatek Wliczony',
+  'Taxable'                     => 'Opodatkowane',
+  'Terms: Net'                  => 'Warunki: Netto',
+  'Transactions exist, cannot delete customer!' => 'Istniej± Transakcje, niemo¿na usun±æ odbiorcy',
+  'Transactions exist, cannot delete vendor!' => 'Istniej± Transakcje, nie mo¿na usun±æ dostawcy',
+  'Vendor deleted!'             => 'Dostawca usuniêty',
+  'Vendor saved!'               => 'Dostawca zapisany',
+  'Vendors'                     => 'Dostawcy',
+  'days'                        => 'dni',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'dodaj'                       => 'add',
+  'kontynuj'                    => 'continue',
+  'usuñ'                        => 'delete',
+  'faktura'                     => 'invoice',
+  'zamówienie'                  => 'order',
+  'zapisz'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/gl b/sql-ledger/locale/pl/gl
new file mode 100644 (file)
index 0000000..1f8883f
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Transakcja Zobowi±zañ',
+  'AR Transaction'              => 'Transakcja Nale¿no¶ci',
+  'Account'                     => 'Konto',
+  'Add General Ledger Transaction' => 'Dodaj Transakcjê w Ksiêdze G³ównej',
+  'Address'                     => 'Adres',
+  'All'                         => 'Wszystko',
+  'Apr'                         => 'Kwiecieñ',
+  'April'                       => 'Kwiecieñ',
+  'Are you sure you want to delete Transaction' => 'Czy chcesz usun±æ Transakcjê?',
+  'Asset'                       => 'Aktywy',
+  'Aug'                         => 'Sierpieñ',
+  'August'                      => 'Sierpieñ',
+  'Balance'                     => 'Saldo',
+  'Cannot delete transaction!'  => 'Nie mo¿esz usun±æ transakcji!',
+  'Cannot have a value in both Debit and Credit!' => 'Nie mo¿na wpisaæ warto¶ci w Debet i Kredyt równocze¶nie!',
+  'Cannot post a transaction without a value!' => 'Nie mo¿esz zatwierdziæ transakcji bez warto¶ci',
+  'Cannot post transaction for a closed period!' => 'Nie mo¿na zaksiêgowaæ transakcji po zamkniêciu okresu!',
+  'Confirm!'                    => 'Potwierd¿!',
+  'Continue'                    => 'Kontynuj',
+  'Credit'                      => 'Kredyt',
+  'Customer not on file!'       => 'Brak Klienta w bazie danych',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Debet',
+  'Debit and credit out of balance!' => 'Debet i Kredyt siê niebalansuj±!',
+  'Dec'                         => 'Grudzieñ',
+  'December'                    => 'Grudzieñ',
+  'Delete'                      => 'Usuñ',
+  'Description'                 => 'Opis',
+  'Edit General Ledger Transaction' => 'Zmiany w Ksiêdze G³ównej',
+  'Equity'                      => 'Kapita³',
+  'Expense'                     => 'Koszt',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'Transakcja Ksiêgi G³ównej',
+  'General Ledger'              => 'Ksiêga G³ówna',
+  'ID'                          => 'Identyfikator',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Income'                      => 'Przychód',
+  'Jan'                         => 'Styczeñ',
+  'January'                     => 'Styczeñ',
+  'Jul'                         => 'Lipiec',
+  'July'                        => 'Lipiec',
+  'Jun'                         => 'Czerwiec',
+  'June'                        => 'Czerwiec',
+  'Liability'                   => 'Zobowi±zania',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Post'                        => 'Zatwierd¿',
+  'Post as new'                 => 'Zatwierd¿ jako nowe',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Brak Projektu w zbiorze danych!',
+  'Purchase Invoice'            => 'Faktura VAT Zakupu',
+  'Reference'                   => 'Odno¶nik',
+  'Reference missing!'          => 'Brak Odno¶nika',
+  'Reports'                     => 'Sprawozdania',
+  'Sales Invoice'               => 'Faktura VAT Sprzeda¿y',
+  'Select from one of the names below' => 'Wybierz nazwê z poni¿szych',
+  'Select from one of the projects below' => 'Wybierz z projektów',
+  'Sep'                         => 'Wrzesieñ',
+  'September'                   => 'Wrzesieñ',
+  'Source'                      => '¯ród³o',
+  'Subtotal'                    => 'Warto¶æ Netto',
+  'To'                          => 'do',
+  'Transaction Date missing!'   => 'Brak Daty Transakcji!',
+  'Transaction deleted!'        => 'Transakcja usuniêta',
+  'Transaction posted!'         => 'Transakcja zatwierdzona',
+  'Update'                      => 'Uzupe³nij',
+  'Vendor not on file!'         => 'Brak Dostawcy w bazie danych',
+  'Yes'                         => 'Tak',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'transakcja_zobowi±zañ'       => 'ap_transaction',
+  'transakcja_nale¿no¶ci'       => 'ar_transaction',
+  'kontynuj'                    => 'continue',
+  'usuñ'                        => 'delete',
+  'transakcja_ksiêgi_g³ównej'   => 'gl_transaction',
+  'zatwierd¿'                   => 'post',
+  'zatwierd¿_jako_nowe'         => 'post_as_new',
+  'faktura_vat_zakupu'          => 'purchase_invoice',
+  'faktura_vat_sprzeda¿y'       => 'sales_invoice',
+  'uzupe³nij'                   => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/ic b/sql-ledger/locale/pl/ic
new file mode 100644 (file)
index 0000000..c7fc309
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Aktywne',
+  'Add'                         => 'Dodaj',
+  'Add Assembly'                => 'Dodaj Zestawienie',
+  'Add Part'                    => 'Dodaj Produkt',
+  'Add Purchase Order'          => 'Dodaj Zamówienie Zakupu',
+  'Add Sales Order'             => 'Dodaj Zamówienie Klienta',
+  'Add Service'                 => 'Dodaj Us³ugi',
+  'Address'                     => 'Adres',
+  'Apr'                         => 'Kwiecieñ',
+  'April'                       => 'Kwiecieñ',
+  'Assemblies'                  => 'Zestawienia',
+  'Assemblies restocked!'       => 'Zestawienia uzupe³nione',
+  'Assembly Number missing!'    => 'Brak Numeru Zestawienia!',
+  'Attachment'                  => 'Za³±cznik',
+  'Aug'                         => 'Sierpieñ',
+  'August'                      => 'Sierpieñ',
+  'BOM'                         => 'Zestawienie materia³owe',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Pojemnik',
+  'Bought'                      => 'Zakupione',
+  'COGS'                        => 'Koszta Sprzeda¿y',
+  'Cannot delete item already invoiced!' => 'Nie mo¿na usun±æ pozycji zafakturowanej!',
+  'Cannot delete item on order!' => 'Nie mo¿na usunac zamówionego produktu!',
+  'Cannot delete item which is part of an assembly!' => 'Nie mo¿na usun±æ czê¶ci z zestawienia!',
+  'Cannot delete item!'         => 'Nie mo¿esz usun±æ pozycji!',
+  'Cannot stock assemblies!'    => 'Nie mo¿na wstawiæ z³o¿enia',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Kontynuj',
+  'Copies'                      => 'Kopie',
+  'Dec'                         => 'Grudzieñ',
+  'December'                    => 'Grudzieñ',
+  'Delete'                      => 'Usuñ',
+  'Delivery Date'               => 'Data Dostawy',
+  'Description'                 => 'Opis',
+  'Drawing'                     => 'Rysunek',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Brak adresu E-mail!',
+  'Edit Assembly'               => 'Zmiany Zestawieñ',
+  'Edit Part'                   => 'Zmiany Produktu',
+  'Edit Service'                => 'Zmiany Us³ug',
+  'Expense'                     => 'Koszt',
+  'Extended'                    => 'Warto¶æ Netto',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'Image'                       => 'Grafika',
+  'In-line'                     => 'W³±czony',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Income'                      => 'Przychód',
+  'Individual Items'            => 'Indywidualne Czê¶ci',
+  'Inventory'                   => 'Inwentarz',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Ilo¶æ Inventarza musi byæ równa zero zanim bêdzie mozna zdezaktualizowaæ to z³o¿enie!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Ilo¶æ inventarza musi byæ równa zero zanim bêdzie mo¿na zdezaktualizowaæ t± czê¶æ!',
+  'Inventory quantity must be zero!' => 'Ilo¶æc Inventarza musi byæ równa zero',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Brak Daty Wystawienia',
+  'Invoice Number'              => 'Numer Faktury',
+  'Invoice Number missing!'     => 'Brak Numeru Faktury',
+  'Item deleted!'               => 'Pozycja usuniêta',
+  'Item not on file!'           => 'Produkt nie jest w zbiorze!',
+  'Jan'                         => 'Styczeñ',
+  'January'                     => 'Styczeñ',
+  'Jul'                         => 'Lipiec',
+  'July'                        => 'Lipiec',
+  'Jun'                         => 'Czerwiec',
+  'June'                        => 'Czerwiec',
+  'Last Cost'                   => 'Cena Zakupu',
+  'Line Total'                  => 'Suma ca³kowita',
+  'Link Accounts'               => 'Konta dowi±zane',
+  'List Price'                  => 'Cena',
+  'Make'                        => 'Marka',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'Microfiche'                  => 'Mikrofilm',
+  'Model'                       => 'Model',
+  'Name'                        => 'Nazwa',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Number missing in Row'       => 'Brak Numeru w Rzêdzie',
+  'Obsolete'                    => 'Zdezaktualizowane',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'On Hand'                     => 'Na Stanie',
+  'On Order'                    => 'Zamawiane',
+  'Order'                       => 'Zamówienie',
+  'Order Date missing!'         => 'Brak Daty Zamówienia',
+  'Order Number'                => 'Numer Zamówienia',
+  'Order Number missing!'       => 'Brak Numeru Zamówienia',
+  'Ordered'                     => 'Zamówione',
+  'Orphaned'                    => 'Zbêdne',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Packing List Date missing!'  => 'Brak Daty Wykazu Dostawy',
+  'Packing List Number missing!' => 'Brak Numeru Wykazu Dostawy',
+  'Part'                        => 'Produkt',
+  'Part Number missing!'        => 'Brak Symbolu Produktu!',
+  'Parts'                       => 'Produkty',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena Netto',
+  'Printer'                     => 'Drukarka',
+  'Project'                     => 'Projekt',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Qty'                         => 'Ilo¶æ',
+  'ROP'                         => 'PPZ',
+  'Recd'                        => 'Otrzymano',
+  'Required by'                 => 'Termin Dostawy',
+  'Sales'                       => 'Sprzeda¿',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Save'                        => 'Zapisz',
+  'Screen'                      => 'Ekran',
+  'Select from one of the items below' => 'Wybierz jeden z poni¿szych artyku³ów',
+  'Select postscript or PDF!'   => 'Wybierz postscript lub PDF',
+  'Sell Price'                  => 'Cena Sprzeda¿y',
+  'Sep'                         => 'Wrzesieñ',
+  'September'                   => 'Wrzesieñ',
+  'Service'                     => 'Us³ugi',
+  'Service Number missing!'     => 'Brak Numeru Us³ugi!',
+  'Services'                    => 'Us³ugi',
+  'Ship'                        => 'Wy¶lij',
+  'Ship to'                     => 'Wy¶lij do',
+  'Short'                       => 'Niedobór',
+  'Sold'                        => 'Sprzedane',
+  'Stock Assembly'              => 'Wstaw Z³o¿enie',
+  'Subject'                     => 'Tre¶æ',
+  'Subtotal'                    => 'Warto¶æ Netto',
+  'Tax'                         => 'Podatek',
+  'To'                          => 'do',
+  'Top Level'                   => 'Najwy¿szy Poziom',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Unit'                        => 'Jednostka',
+  'Unit of measure'             => 'Jednostka miary',
+  'Update'                      => 'Uzupe³nij',
+  'Updated'                     => 'Uzupe³nione',
+  'Weight'                      => 'Waga',
+  'What type of item is this?'  => 'Co to za rodzaj artyku³u',
+  'ea'                          => 'szt',
+  'emailed to'                  => 'email do',
+  'hr'                          => 'godz',
+  'sent to printer'             => 'wys³ano do drukarki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'dodaj'                       => 'add',
+  'dodaj_zestawienie'           => 'add_assembly',
+  'dodaj_produkt'               => 'add_part',
+  'dodaj_us³ugi'                => 'add_service',
+  'kontynuj'                    => 'continue',
+  'usuñ'                        => 'delete',
+  'zmiany_zestawieñ'            => 'edit_assembly',
+  'zmiany_produktu'             => 'edit_part',
+  'zmiany_us³ug'                => 'edit_service',
+  'zapisz'                      => 'save',
+  'uzupe³nij'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/io b/sql-ledger/locale/pl/io
new file mode 100644 (file)
index 0000000..9807907
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Dodaj Zamówienie Zakupu',
+  'Add Sales Order'             => 'Dodaj Zamówienie Klienta',
+  'Address'                     => 'Adres',
+  'Apr'                         => 'Kwiecieñ',
+  'April'                       => 'Kwiecieñ',
+  'Attachment'                  => 'Za³±cznik',
+  'Aug'                         => 'Sierpieñ',
+  'August'                      => 'Sierpieñ',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Pojemnik',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Kontynuj',
+  'Copies'                      => 'Kopie',
+  'Dec'                         => 'Grudzieñ',
+  'December'                    => 'Grudzieñ',
+  'Delivery Date'               => 'Data Dostawy',
+  'Description'                 => 'Opis',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Brak adresu E-mail!',
+  'Extended'                    => 'Warto¶æ Netto',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'In-line'                     => 'W³±czony',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Brak Daty Wystawienia',
+  'Invoice Number missing!'     => 'Brak Numeru Faktury',
+  'Item not on file!'           => 'Produkt nie jest w zbiorze!',
+  'Jan'                         => 'Styczeñ',
+  'January'                     => 'Styczeñ',
+  'Jul'                         => 'Lipiec',
+  'July'                        => 'Lipiec',
+  'Jun'                         => 'Czerwiec',
+  'June'                        => 'Czerwiec',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'Name'                        => 'Nazwa',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Number missing in Row'       => 'Brak Numeru w Rzêdzie',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Order'                       => 'Zamówienie',
+  'Order Date missing!'         => 'Brak Daty Zamówienia',
+  'Order Number missing!'       => 'Brak Numeru Zamówienia',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Packing List Date missing!'  => 'Brak Daty Wykazu Dostawy',
+  'Packing List Number missing!' => 'Brak Numeru Wykazu Dostawy',
+  'Part'                        => 'Produkt',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena Netto',
+  'Printer'                     => 'Drukarka',
+  'Project'                     => 'Projekt',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Qty'                         => 'Ilo¶æ',
+  'Recd'                        => 'Otrzymano',
+  'Required by'                 => 'Termin Dostawy',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Screen'                      => 'Ekran',
+  'Select from one of the items below' => 'Wybierz jeden z poni¿szych artyku³ów',
+  'Select postscript or PDF!'   => 'Wybierz postscript lub PDF',
+  'Sep'                         => 'Wrzesieñ',
+  'September'                   => 'Wrzesieñ',
+  'Service'                     => 'Us³ugi',
+  'Ship'                        => 'Wy¶lij',
+  'Ship to'                     => 'Wy¶lij do',
+  'Subject'                     => 'Tre¶æ',
+  'To'                          => 'do',
+  'Unit'                        => 'Jednostka',
+  'What type of item is this?'  => 'Co to za rodzaj artyku³u',
+  'emailed to'                  => 'email do',
+  'sent to printer'             => 'wys³ano do drukarki',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'kontynuj'                    => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/ir b/sql-ledger/locale/pl/ir
new file mode 100644 (file)
index 0000000..2196cd1
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Add Purchase Invoice'        => 'Zarejestrój Fakturê VAT Zakupu',
+  'Add Purchase Order'          => 'Dodaj Zamówienie Zakupu',
+  'Add Sales Order'             => 'Dodaj Zamówienie Klienta',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Kwota',
+  'Apr'                         => 'Kwiecieñ',
+  'April'                       => 'Kwiecieñ',
+  'Are you sure you want to delete Invoice Number' => 'Czy chcesz usun±æ Numer Faktury?',
+  'Attachment'                  => 'Za³±cznik',
+  'Aug'                         => 'Sierpieñ',
+  'August'                      => 'Sierpieñ',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Pojemnik',
+  'Cannot delete invoice!'      => 'Nie mo¿esz usun±æ factury!',
+  'Cannot post invoice for a closed period!' => 'Nie mo¿na zksiêgowaæ faktury pozamkniêciu okresu!',
+  'Cannot post invoice!'        => 'Nie mo¿esz zatwierdziæ faktury!',
+  'Cannot post payment for a closed period!' => 'Nie mo¿na zaksiêgowaæ p³atno¶ci po zamkniêciu okresu!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Potwierd¿!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Kontynuj',
+  'Copies'                      => 'Kopie',
+  'Currency'                    => 'Waluta',
+  'Customer not on file!'       => 'Brak Klienta w bazie danych',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Termin P³atno¶ci',
+  'Dec'                         => 'Grudzieñ',
+  'December'                    => 'Grudzieñ',
+  'Delete'                      => 'Usuñ',
+  'Delivery Date'               => 'Data Dostawy',
+  'Description'                 => 'Opis',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Brak adresu E-mail!',
+  'Edit Purchase Invoice'       => 'Zmiany Faktury Zamówienia',
+  'Exch'                        => 'Kurs',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'Exchangerate for payment missing!' => 'Brakuje kursu wymiany dla p³atno¶ci!',
+  'Exchangerate missing!'       => 'Brakuje kursu wymiany',
+  'Extended'                    => 'Warto¶æ Netto',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'In-line'                     => 'W³±czony',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Data Wystawienia',
+  'Invoice Date missing!'       => 'Brak Daty Wystawienia',
+  'Invoice Number'              => 'Numer Faktury',
+  'Invoice Number missing!'     => 'Brak Numeru Faktury',
+  'Invoice deleted!'            => 'Faktura usuniêta',
+  'Invoice posted!'             => 'Faktura zatwierdzona',
+  'Item not on file!'           => 'Produkt nie jest w zbiorze!',
+  'Jan'                         => 'Styczeñ',
+  'January'                     => 'Styczeñ',
+  'Jul'                         => 'Lipiec',
+  'July'                        => 'Lipiec',
+  'Jun'                         => 'Czerwiec',
+  'June'                        => 'Czerwiec',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'Name'                        => 'Nazwa',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Number missing in Row'       => 'Brak Numeru w Rzêdzie',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Order'                       => 'Zamówienie',
+  'Order Date missing!'         => 'Brak Daty Zamówienia',
+  'Order Number'                => 'Numer Zamówienia',
+  'Order Number missing!'       => 'Brak Numeru Zamówienia',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Packing List Date missing!'  => 'Brak Daty Wykazu Dostawy',
+  'Packing List Number missing!' => 'Brak Numeru Wykazu Dostawy',
+  'Part'                        => 'Produkt',
+  'Payment date missing!'       => 'Brak Daty P³atno¶ci',
+  'Payments'                    => 'P³atno¶ci',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Zatwierd¿',
+  'Post as new'                 => 'Zatwierd¿ jako nowe',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena Netto',
+  'Printer'                     => 'Drukarka',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Brak Projektu w zbiorze danych!',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Qty'                         => 'Ilo¶æ',
+  'Recd'                        => 'Otrzymano',
+  'Record in'                   => 'Zapisz w',
+  'Required by'                 => 'Termin Dostawy',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Screen'                      => 'Ekran',
+  'Select from one of the items below' => 'Wybierz jeden z poni¿szych artyku³ów',
+  'Select from one of the names below' => 'Wybierz nazwê z poni¿szych',
+  'Select from one of the projects below' => 'Wybierz z projektów',
+  'Select postscript or PDF!'   => 'Wybierz postscript lub PDF',
+  'Sep'                         => 'Wrzesieñ',
+  'September'                   => 'Wrzesieñ',
+  'Service'                     => 'Us³ugi',
+  'Ship'                        => 'Wy¶lij',
+  'Ship to'                     => 'Wy¶lij do',
+  'Source'                      => '¯ród³o',
+  'Subject'                     => 'Tre¶æ',
+  'Subtotal'                    => 'Warto¶æ Netto',
+  'Tax Included'                => 'Podatek Wliczony',
+  'To'                          => 'do',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Unit'                        => 'Jednostka',
+  'Update'                      => 'Uzupe³nij',
+  'Vendor'                      => 'Dostawca',
+  'Vendor missing!'             => 'Brak Dostawcy',
+  'Vendor not on file!'         => 'Brak Dostawcy w bazie danych',
+  'What type of item is this?'  => 'Co to za rodzaj artyku³u',
+  'Yes'                         => 'Tak',
+  'ea'                          => 'szt',
+  'emailed to'                  => 'email do',
+  'sent to printer'             => 'wys³ano do drukarki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'kontynuj'                    => 'continue',
+  'usuñ'                        => 'delete',
+  'zamówienie'                  => 'order',
+  'zatwierd¿'                   => 'post',
+  'zatwierd¿_jako_nowe'         => 'post_as_new',
+  'uzupe³nij'                   => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/is b/sql-ledger/locale/pl/is
new file mode 100644 (file)
index 0000000..b431b77
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Add Purchase Order'          => 'Dodaj Zamówienie Zakupu',
+  'Add Sales Invoice'           => 'Zarejestrój Fakturê VAT Sprzeda¿y',
+  'Add Sales Order'             => 'Dodaj Zamówienie Klienta',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Kwota',
+  'Apr'                         => 'Kwiecieñ',
+  'April'                       => 'Kwiecieñ',
+  'Are you sure you want to delete Invoice Number' => 'Czy chcesz usun±æ Numer Faktury?',
+  'Attachment'                  => 'Za³±cznik',
+  'Aug'                         => 'Sierpieñ',
+  'August'                      => 'Sierpieñ',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Pojemnik',
+  'Cannot delete invoice!'      => 'Nie mo¿esz usun±æ factury!',
+  'Cannot post invoice for a closed period!' => 'Nie mo¿na zksiêgowaæ faktury pozamkniêciu okresu!',
+  'Cannot post invoice!'        => 'Nie mo¿esz zatwierdziæ faktury!',
+  'Cannot post payment for a closed period!' => 'Nie mo¿na zaksiêgowaæ p³atno¶ci po zamkniêciu okresu!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Potwierd¿!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Kontynuj',
+  'Copies'                      => 'Kopie',
+  'Credit Limit'                => 'Limit Kredytu',
+  'Currency'                    => 'Waluta',
+  'Customer'                    => 'Klient',
+  'Customer missing!'           => 'Brak Klienta',
+  'Customer not on file!'       => 'Brak Klienta w bazie danych',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Termin P³atno¶ci',
+  'Dec'                         => 'Grudzieñ',
+  'December'                    => 'Grudzieñ',
+  'Delete'                      => 'Usuñ',
+  'Delivery Date'               => 'Data Dostawy',
+  'Description'                 => 'Opis',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Brak adresu E-mail!',
+  'Edit Sales Invoice'          => 'Zmiany Faktury Sprzeda¿y',
+  'Exch'                        => 'Kurs',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'Exchangerate for payment missing!' => 'Brakuje kursu wymiany dla p³atno¶ci!',
+  'Exchangerate missing!'       => 'Brakuje kursu wymiany',
+  'Extended'                    => 'Warto¶æ Netto',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'In-line'                     => 'W³±czony',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Data Wystawienia',
+  'Invoice Date missing!'       => 'Brak Daty Wystawienia',
+  'Invoice Number'              => 'Numer Faktury',
+  'Invoice Number missing!'     => 'Brak Numeru Faktury',
+  'Invoice deleted!'            => 'Faktura usuniêta',
+  'Invoice posted!'             => 'Faktura zatwierdzona',
+  'Item not on file!'           => 'Produkt nie jest w zbiorze!',
+  'Jan'                         => 'Styczeñ',
+  'January'                     => 'Styczeñ',
+  'Jul'                         => 'Lipiec',
+  'July'                        => 'Lipiec',
+  'Jun'                         => 'Czerwiec',
+  'June'                        => 'Czerwiec',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'Name'                        => 'Nazwa',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Number missing in Row'       => 'Brak Numeru w Rzêdzie',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Order'                       => 'Zamówienie',
+  'Order Date missing!'         => 'Brak Daty Zamówienia',
+  'Order Number'                => 'Numer Zamówienia',
+  'Order Number missing!'       => 'Brak Numeru Zamówienia',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Packing List Date missing!'  => 'Brak Daty Wykazu Dostawy',
+  'Packing List Number missing!' => 'Brak Numeru Wykazu Dostawy',
+  'Part'                        => 'Produkt',
+  'Payment date missing!'       => 'Brak Daty P³atno¶ci',
+  'Payments'                    => 'P³atno¶ci',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Zatwierd¿',
+  'Post as new'                 => 'Zatwierd¿ jako nowe',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena Netto',
+  'Print'                       => 'Drukuj',
+  'Printer'                     => 'Drukarka',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Brak Projektu w zbiorze danych!',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Qty'                         => 'Ilo¶æ',
+  'Recd'                        => 'Otrzymano',
+  'Record in'                   => 'Zapisz w',
+  'Remaining'                   => 'Pozosta³e',
+  'Required by'                 => 'Termin Dostawy',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Screen'                      => 'Ekran',
+  'Select from one of the items below' => 'Wybierz jeden z poni¿szych artyku³ów',
+  'Select from one of the names below' => 'Wybierz nazwê z poni¿szych',
+  'Select from one of the projects below' => 'Wybierz z projektów',
+  'Select postscript or PDF!'   => 'Wybierz postscript lub PDF',
+  'Sep'                         => 'Wrzesieñ',
+  'September'                   => 'Wrzesieñ',
+  'Service'                     => 'Us³ugi',
+  'Ship'                        => 'Wy¶lij',
+  'Ship to'                     => 'Wy¶lij do',
+  'Ship via'                    => 'Wy¶lij przez',
+  'Source'                      => '¯ród³o',
+  'Subject'                     => 'Tre¶æ',
+  'Subtotal'                    => 'Warto¶æ Netto',
+  'Tax Included'                => 'Podatek Wliczony',
+  'To'                          => 'do',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Unit'                        => 'Jednostka',
+  'Update'                      => 'Uzupe³nij',
+  'Vendor not on file!'         => 'Brak Dostawcy w bazie danych',
+  'What type of item is this?'  => 'Co to za rodzaj artyku³u',
+  'Yes'                         => 'Tak',
+  'ea'                          => 'szt',
+  'emailed to'                  => 'email do',
+  'sent to printer'             => 'wys³ano do drukarki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'kontynuj'                    => 'continue',
+  'usuñ'                        => 'delete',
+  'e_mail'                      => 'e_mail',
+  'zamówienie'                  => 'order',
+  'zatwierd¿'                   => 'post',
+  'zatwierd¿_jako_nowe'         => 'post_as_new',
+  'drukuj'                      => 'print',
+  'wy¶lij_do'                   => 'ship_to',
+  'uzupe³nij'                   => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/login b/sql-ledger/locale/pl/login
new file mode 100644 (file)
index 0000000..cd96d95
--- /dev/null
@@ -0,0 +1,28 @@
+$self{texts} = {
+  'About'                       => 'Na Temat',
+  'Accounting'                  => 'Ksiêgowo¶æ',
+  'Database Host'               => 'Host Bazy Danych',
+  'Dataset'                     => 'Zbiór Danych',
+  'Incorrect Dataset version!'  => 'Nieprawid³owa wersja Zbioru Danych',
+  'Incorrect Password!'         => 'Nieprawid³owe Has³o',
+  'Licensed to'                 => 'Licencja nale¿y do:',
+  'Login'                       => 'Zarejestrój siê',
+  'Name'                        => 'Nazwa',
+  'Password'                    => 'Has³o',
+  'User'                        => 'U¿ytkownik',
+  'Version'                     => 'Wersja',
+  'You are logged out!'         => 'Jeste¶ wyrejestrowany!',
+  'You did not enter a name!'   => 'Nie wstawiono nazwy!',
+  'is not a member!'            => 'Nie jest cz³onkiem',
+  'localhost'                   => 'host lokalny',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'zarejestrój_siê'             => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/menu b/sql-ledger/locale/pl/menu
new file mode 100644 (file)
index 0000000..0bd3b89
--- /dev/null
@@ -0,0 +1,72 @@
+$self{texts} = {
+  'AP'                          => 'Ksiêga Zobowi±zañ',
+  'AP Aging'                    => 'Zobowi±zania Przeterminowane',
+  'AR'                          => 'Ksiêga Nale¿no¶ci',
+  'AR Aging'                    => 'Nale¿no¶ci Przeterminowane',
+  'Accounting Menu'             => 'Menu Ksiêgowo¶ci',
+  'Add Account'                 => 'Dodaj Konto',
+  'Add Assembly'                => 'Dodaj Zestawienie',
+  'Add Customer'                => 'Dodaj Odbiorcê',
+  'Add GIFI'                    => 'Dodaj GIFI',
+  'Add Part'                    => 'Dodaj Produkt',
+  'Add Project'                 => 'Dodaj Projekt',
+  'Add Service'                 => 'Dodaj Us³ugi',
+  'Add Transaction'             => 'Dodaj Transakcjê',
+  'Add Vendor'                  => 'Dodaj Dostawcê',
+  'Assemblies'                  => 'Zestawienia',
+  'Audit Control'               => 'Kontrola Audytu',
+  'Backup'                      => 'Kopia Zapasowa',
+  'Balance Sheet'               => 'Bilans',
+  'Cash'                        => 'Kasa',
+  'Chart of Accounts'           => 'Plan Kont',
+  'Check'                       => 'Czek',
+  'Customers'                   => 'Klienci',
+  'General Ledger'              => 'Ksiêga G³ówna',
+  'Goods & Services'            => 'Produkty i Us³ugi',
+  'HTML Templates'              => 'Szablony HTML',
+  'Income Statement'            => 'Rachunek Zysków i Strat',
+  'Invoice'                     => 'Faktura',
+  'LaTeX Templates'             => 'Szablony LaTeX',
+  'List Accounts'               => 'Spis Kont',
+  'List GIFI'                   => 'Wykaz GIFI',
+  'Logout'                      => 'Wyrejestrój siê',
+  'Order Entry'                 => 'Wystawianie Zamówieñ',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Parts'                       => 'Produkty',
+  'Payment'                     => 'P³atno¶æ',
+  'Payments'                    => 'P³atno¶ci',
+  'Preferences'                 => 'Preferencje',
+  'Projects'                    => 'Projekty',
+  'Purchase Invoice'            => 'Faktura VAT Zakupu',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Purchase Orders'             => 'Zamówienia Zakupu',
+  'Receipt'                     => 'Wp³ata',
+  'Receipts'                    => 'Wp³aty',
+  'Reconciliation'              => 'Zgodno¶æ Rozliczeñ',
+  'Reports'                     => 'Sprawozdania',
+  'Sales Invoice'               => 'Faktura VAT Sprzeda¿y',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Sales Orders'                => 'Zamówienia Klientów',
+  'Save to File'                => 'Zapisz w zbiorze',
+  'Send by E-Mail'              => 'Wys³ano przy u¿yciu E-Mail',
+  'Services'                    => 'Us³ugi',
+  'Statement'                   => 'Wykaz',
+  'Stock Assembly'              => 'Wstaw Z³o¿enie',
+  'Stylesheet'                  => 'Strona Stylowa',
+  'System'                      => 'System',
+  'Tax collected'               => 'Podatek pobrany',
+  'Tax paid'                    => 'Podatek zap³acony',
+  'Transactions'                => 'Transakcje',
+  'Trial Balance'               => 'Bilans Porównawczy',
+  'Vendors'                     => 'Dostawcy',
+  'Version'                     => 'Wersja',
+  'localhost'                   => 'host lokalny',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/oe b/sql-ledger/locale/pl/oe
new file mode 100644 (file)
index 0000000..511b834
--- /dev/null
@@ -0,0 +1,199 @@
+$self{texts} = {
+  'Add'                         => 'Dodaj',
+  'Add Purchase Invoice'        => 'Zarejestrój Fakturê VAT Zakupu',
+  'Add Purchase Order'          => 'Dodaj Zamówienie Zakupu',
+  'Add Sales Invoice'           => 'Zarejestrój Fakturê VAT Sprzeda¿y',
+  'Add Sales Order'             => 'Dodaj Zamówienie Klienta',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Kwota',
+  'Apr'                         => 'Kwiecieñ',
+  'April'                       => 'Kwiecieñ',
+  'Are you sure you want to delete Order Number' => 'Czy chcesz usun±æ Numer Zamówienia?',
+  'Attachment'                  => 'Za³±cznik',
+  'Aug'                         => 'Sierpieñ',
+  'August'                      => 'Sierpieñ',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Pojemnik',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Nie mo¿esz usun±æ zamówienia!',
+  'Cannot save order!'          => 'Nie mo¿na zapisaæ zamowienia!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Zamkniêto',
+  'Confirm!'                    => 'Potwierd¿!',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Kontynuj',
+  'Copies'                      => 'Kopie',
+  'Credit Limit'                => 'Limit Kredytu',
+  'Curr'                        => 'Waluta',
+  'Currency'                    => 'Waluta',
+  'Customer'                    => 'Klient',
+  'Customer missing!'           => 'Brak Klienta',
+  'Customer not on file!'       => 'Brak Klienta w bazie danych',
+  'Date'                        => 'Data',
+  'Dec'                         => 'Grudzieñ',
+  'December'                    => 'Grudzieñ',
+  'Delete'                      => 'Usuñ',
+  'Delivery Date'               => 'Data Dostawy',
+  'Description'                 => 'Opis',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Brak adresu E-mail!',
+  'Edit Purchase Order'         => 'Zmiany Zamówienia Zakupu',
+  'Edit Sales Order'            => 'Zmiany Zamówienia Klienta',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'Exchangerate missing!'       => 'Brakuje kursu wymiany',
+  'Extended'                    => 'Warto¶æ Netto',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'ID'                          => 'Identyfikator',
+  'In-line'                     => 'W³±czony',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Brak Daty Wystawienia',
+  'Invoice Number missing!'     => 'Brak Numeru Faktury',
+  'Item not on file!'           => 'Produkt nie jest w zbiorze!',
+  'Jan'                         => 'Styczeñ',
+  'January'                     => 'Styczeñ',
+  'Jul'                         => 'Lipiec',
+  'July'                        => 'Lipiec',
+  'Jun'                         => 'Czerwiec',
+  'June'                        => 'Czerwiec',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'Name'                        => 'Nazwa',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Number missing in Row'       => 'Brak Numeru w Rzêdzie',
+  'O'                           => 'O',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Open'                        => 'Otworzono',
+  'Order'                       => 'Zamówienie',
+  'Order Date'                  => 'Data Zamówienia',
+  'Order Date missing!'         => 'Brak Daty Zamówienia',
+  'Order Number'                => 'Numer Zamówienia',
+  'Order Number missing!'       => 'Brak Numeru Zamówienia',
+  'Order deleted!'              => 'Zamówienie usuniête',
+  'Order saved!'                => 'Zamówienie zapisane',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Packing List Date missing!'  => 'Brak Daty Wykazu Dostawy',
+  'Packing List Number missing!' => 'Brak Numeru Wykazu Dostawy',
+  'Part'                        => 'Produkt',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena Netto',
+  'Print'                       => 'Drukuj',
+  'Printer'                     => 'Drukarka',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Brak Projektu w zbiorze danych!',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Purchase Orders'             => 'Zamówienia Zakupu',
+  'Qty'                         => 'Ilo¶æ',
+  'Recd'                        => 'Otrzymano',
+  'Remaining'                   => 'Pozosta³e',
+  'Required by'                 => 'Termin Dostawy',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Sales Orders'                => 'Zamówienia Klientów',
+  'Save'                        => 'Zapisz',
+  'Save as new'                 => 'Zapisz jako nowe',
+  'Screen'                      => 'Ekran',
+  'Select from one of the items below' => 'Wybierz jeden z poni¿szych artyku³ów',
+  'Select from one of the names below' => 'Wybierz nazwê z poni¿szych',
+  'Select from one of the projects below' => 'Wybierz z projektów',
+  'Select postscript or PDF!'   => 'Wybierz postscript lub PDF',
+  'Sep'                         => 'Wrzesieñ',
+  'September'                   => 'Wrzesieñ',
+  'Service'                     => 'Us³ugi',
+  'Ship'                        => 'Wy¶lij',
+  'Ship to'                     => 'Wy¶lij do',
+  'Ship via'                    => 'Wy¶lij przez',
+  'Subject'                     => 'Tre¶æ',
+  'Subtotal'                    => 'Warto¶æ Netto',
+  'Tax'                         => 'Podatek',
+  'Tax Included'                => 'Podatek Wliczony',
+  'Terms: Net'                  => 'Warunki: Netto',
+  'To'                          => 'do',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Unit'                        => 'Jednostka',
+  'Update'                      => 'Uzupe³nij',
+  'Vendor'                      => 'Dostawca',
+  'Vendor missing!'             => 'Brak Dostawcy',
+  'Vendor not on file!'         => 'Brak Dostawcy w bazie danych',
+  'What type of item is this?'  => 'Co to za rodzaj artyku³u',
+  'Yes'                         => 'Tak',
+  'days'                        => 'dni',
+  'ea'                          => 'szt',
+  'emailed to'                  => 'email do',
+  'sent to printer'             => 'wys³ano do drukarki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'dodaj'                       => 'add',
+  'kontynuj'                    => 'continue',
+  'usuñ'                        => 'delete',
+  'e_mail'                      => 'e_mail',
+  'faktura'                     => 'invoice',
+  'drukuj'                      => 'print',
+  'zapisz'                      => 'save',
+  'zapisz_jako_nowe'            => 'save_as_new',
+  'wy¶lij_do'                   => 'ship_to',
+  'uzupe³nij'                   => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/pe b/sql-ledger/locale/pl/pe
new file mode 100644 (file)
index 0000000..88ab7fd
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Dodaj',
+  'Add Project'                 => 'Dodaj Projekt',
+  'All'                         => 'Wszystko',
+  'Continue'                    => 'Kontynuj',
+  'Delete'                      => 'Usuñ',
+  'Description'                 => 'Opis',
+  'Edit Project'                => 'Zmiany Projektu',
+  'Number'                      => 'Numer Katalogu',
+  'Orphaned'                    => 'Zbêdne',
+  'Project'                     => 'Projekt',
+  'Project Number missing!'     => 'Brak Numeru Projektu',
+  'Project deleted!'            => 'Projekt usuniêty',
+  'Project saved!'              => 'Projekt zapisany',
+  'Projects'                    => 'Projekty',
+  'Save'                        => 'Zapisz',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'dodaj'                       => 'add',
+  'kontynuj'                    => 'continue',
+  'usuñ'                        => 'delete',
+  'zapisz'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/rc b/sql-ledger/locale/pl/rc
new file mode 100644 (file)
index 0000000..98bc9bd
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Balance'                     => 'Saldo',
+  'Cleared Balance'             => 'Zgadzaj±ce Saldo',
+  'Continue'                    => 'Kontynuj',
+  'Date'                        => 'Data',
+  'Deposit'                     => 'Wp³ata',
+  'Description'                 => 'Opis',
+  'Difference'                  => 'Ró¿nica',
+  'Done'                        => 'Zrobione',
+  'Exchangerate Difference'     => 'Ró¿nica Kursowa',
+  'From'                        => 'Od',
+  'Out of balance!'             => 'Niezgodne Saldo',
+  'Payment'                     => 'P³atno¶æ',
+  'Reconciliation'              => 'Zgodno¶æ Rozliczeñ',
+  'Select all'                  => 'Wybierz wszystko',
+  'Source'                      => '¯ród³o',
+  'Statement Balance'           => 'Wykaz Salda',
+  'To'                          => 'do',
+  'Update'                      => 'Uzupe³nij',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'kontynuj'                    => 'continue',
+  'zrobione'                    => 'done',
+  'wybierz_wszystko'            => 'select_all',
+  'uzupe³nij'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/pl/rp b/sql-ledger/locale/pl/rp
new file mode 100644 (file)
index 0000000..6abd702
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'Zobowi±zania Przeterminowane',
+  'AR Aging'                    => 'Nale¿no¶ci Przeterminowane',
+  'Account'                     => 'Konto',
+  'Accounts'                    => 'Konta',
+  'Amount'                      => 'Kwota',
+  'Apr'                         => 'Kwiecieñ',
+  'April'                       => 'Kwiecieñ',
+  'Attachment'                  => 'Za³±cznik',
+  'Aug'                         => 'Sierpieñ',
+  'August'                      => 'Sierpieñ',
+  'Balance Sheet'               => 'Bilans',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Tryb Kasowy',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Porównaj z',
+  'Continue'                    => 'Kontynuj',
+  'Copies'                      => 'Kopie',
+  'Credit'                      => 'Kredyt',
+  'Current'                     => 'Bi¿±cy',
+  'Customer'                    => 'Klient',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Debet',
+  'Dec'                         => 'Grudzieñ',
+  'December'                    => 'Grudzieñ',
+  'Decimalplaces'               => 'Miejsca Dziesiêtne',
+  'Description'                 => 'Opis',
+  'Due'                         => 'P³atno¶æ',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'E-mail Wykaz do',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Nag³ówek',
+  'ID'                          => 'Identyfikator',
+  'In-line'                     => 'W³±czony',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Income Statement'            => 'Rachunek Zysków i Strat',
+  'Invoice'                     => 'Faktura',
+  'Jan'                         => 'Styczeñ',
+  'January'                     => 'Styczeñ',
+  'Jul'                         => 'Lipiec',
+  'July'                        => 'Lipiec',
+  'Jun'                         => 'Czerwiec',
+  'June'                        => 'Czerwiec',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'N/A'                         => 'N/A',
+  'Nothing selected!'           => 'Nic nie zaznaczone!',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'P³atno¶ci',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Drukuj',
+  'Printer'                     => 'Drukarka',
+  'Receipts'                    => 'Wp³aty',
+  'Report for'                  => 'Raport dla',
+  'Retained Earnings'           => 'Zysk',
+  'Screen'                      => 'Ekran',
+  'Select all'                  => 'Wybierz wszystko',
+  'Select postscript or PDF!'   => 'Wybierz postscript lub PDF',
+  'Sep'                         => 'Wrzesieñ',
+  'September'                   => 'Wrzesieñ',
+  'Source'                      => '¯ród³o',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Wykaz',
+  'Statement sent to'           => 'Wykaz wys³any do',
+  'Statements sent to printer!' => 'Wykaz wys³any do drukarki',
+  'Subject'                     => 'Tre¶æ',
+  'Subtotal'                    => 'Warto¶æ Netto',
+  'Tax'                         => 'Podatek',
+  'Tax collected'               => 'Podatek pobrany',
+  'Tax paid'                    => 'Podatek zap³acony',
+  'To'                          => 'do',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Trial Balance'               => 'Bilans Porównawczy',
+  'Vendor'                      => 'Dostawca',
+  'as at'                       => 'tak samo',
+  'collected on sales'          => 'zebrany przy sprzeda¿y',
+  'for Period'                  => 'za Okres',
+  'paid on purchases'           => 'zap³acony przy zakupach',
+  'to'                          => 'do',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'kontynuj'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'drukuj'                      => 'print',
+  'wybierz_wszystko'            => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/COPYING b/sql-ledger/locale/pt/COPYING
new file mode 100644 (file)
index 0000000..bd508c5
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Portugese texts:
+#
+#  Author: Paulo Rodrigues <prodrigues@vianetworks.pt>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/pt/LANGUAGE b/sql-ledger/locale/pt/LANGUAGE
new file mode 100644 (file)
index 0000000..3d5f0c1
--- /dev/null
@@ -0,0 +1 @@
+Portuguese
diff --git a/sql-ledger/locale/pt/admin b/sql-ledger/locale/pt/admin
new file mode 100644 (file)
index 0000000..827c4e9
--- /dev/null
@@ -0,0 +1,122 @@
+$self{texts} = {
+  'Access Control'              => 'Controlo de Acessos',
+  'Accounting'                  => 'Contabilidade',
+  'Add User'                    => 'Novo Utilizador',
+  'Address'                     => 'Endereço',
+  'Administration'              => 'Administração',
+  'Administrator'               => 'Administrador',
+  'All Datasets up to date!'    => 'Todos os Datasets estão Actualizados!',
+  'Change Admin Password'       => 'Mudar Password Admin',
+  'Change Password'             => 'Mudar Password',
+  'Character Set'               => 'Character Set',
+  'Click on login name to edit!' => 'Clique no login para editar!',
+  'Company'                     => 'Companhia',
+  'Connect to'                  => 'Ligar a',
+  'Continue'                    => 'Continuar',
+  'Create Chart of Accounts'    => 'Criar Plano de Contas',
+  'Create Dataset'              => 'Criar Dataset',
+  'DBI not installed!'          => 'DBI não está instalado!',
+  'Database'                    => 'Base de Dados',
+  'Database Administration'     => 'Administração de Base de Dados',
+  'Database Driver not checked!' => 'Não seleccionou Driver Base de Dados',
+  'Database User missing!'      => 'Não existe Utilizador de Base de Dados',
+  'Dataset'                     => 'Dataset',
+  'Dataset missing!'            => 'Dataset não existe!',
+  'Dataset updated!'            => 'Dataset actualizado!',
+  'Date Format'                 => 'Formato de Data',
+  'Delete'                      => 'Remover',
+  'Delete Dataset'              => 'Remover Dataset',
+  'Directory'                   => 'Directoria',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'E-Mail',
+  'Edit User'                   => 'Editar Utilizador',
+  'Existing Datasets'           => 'Datasets Existentes',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Não indicou Hostname!',
+  'Incorrect Password!'         => 'Password Incorrecta!',
+  'Language'                    => 'Língua',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Não indique host nem port, a não ser que deseje efectuar uma ligação remota',
+  'Login'                       => 'Login',
+  'Name'                        => 'Nome',
+  'New Templates'               => 'Novos Modelos',
+  'No Database Drivers available!' => 'Não há Drivers de Base de Dados disponiveis!',
+  'No Dataset selected!'        => 'Não seleccionou Dataset!',
+  'Nothing to delete!'          => 'Nada para remover!',
+  'Number Format'               => 'Formato numérico',
+  'Oracle Database Administration' => 'Administração Base de Dados Oracle',
+  'Password'                    => 'Password',
+  'Password changed!'           => 'Password alterada',
+  'Pg Database Administration'  => 'Administração Base de Dados Postgres',
+  'Phone'                       => 'Tel',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Falta o port!',
+  'Printer'                     => 'Impressora',
+  'Save'                        => 'Guardar',
+  'Select a Dataset to delete and press "Continue"' => 'Seleccione um Dataset a remover e clique "Continuar"',
+  'Setup Templates'             => 'Configurar Modelos',
+  'Ship via'                    => 'Expedir via',
+  'Signature'                   => 'Assinatura',
+  'Stylesheet'                  => 'Stylesheet',
+  'Templates'                   => 'Modelos',
+  'The following Datasets are not in use and can be deleted' => 'Os seguintes Datasets estão em uso e não podem ser removidos',
+  'The following Datasets need to be updated' => 'Os seguintes Datasets necessitam ser actualizados',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Esta é uma validação preliminar. Nada será criado nem removido neste ponto!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Para adicionar um utilizador a um grupo, edite um nome, mude o login e guarde. O novo utilizador com as mesmas variáveis será guardado sob o novo login',
+  'Update Dataset'              => 'Actualizar Dataset',
+  'Use Templates'               => 'Usar Templates',
+  'User'                        => 'Utilizador',
+  'User deleted!'               => 'Utilizador removido',
+  'User saved!'                 => 'Utilizador guardado',
+  'Version'                     => 'Versão',
+  'You must enter a host and port for local and remote connections!' => 'Tem de indicar host e port para ligações locais e remotas!',
+  'does not exist'              => 'não existe',
+  'is already a member!'        => 'já é membro!',
+  'localhost'                   => 'localhost',
+  'successfully created!'       => 'criado com sucesso!',
+  'successfully deleted!'       => 'removido com sucesso!',
+  'website'                     => 'website',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'novo_utilizador'             => 'add_user',
+  'mudar_password_admin'        => 'change_admin_password',
+  'mudar_password'              => 'change_password',
+  'continuar'                   => 'continue',
+  'criar_dataset'               => 'create_dataset',
+  'remover'                     => 'delete',
+  'remover_dataset'             => 'delete_dataset',
+  'login'                       => 'login',
+  'administração_base_de_dados_oracle' => 'oracle_database_administration',
+  'administração_base_de_dados_postgres' => 'pg_database_administration',
+  'guardar'                     => 'save',
+  'actualizar_dataset'          => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/all b/sql-ledger/locale/pt/all
new file mode 100644 (file)
index 0000000..bcfd222
--- /dev/null
@@ -0,0 +1,487 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Fornecedores',
+  'AP Aging'                    => 'Idade Saldos Fornecedores',
+  'AP Transaction'              => 'Transacção Fornecedores',
+  'AP Transactions'             => 'Transacções Fornecedores',
+  'AR'                          => 'Clientes',
+  'AR Aging'                    => 'Idade Saldos Clientes',
+  'AR Transaction'              => 'Transacção Clientes',
+  'AR Transactions'             => 'Transacções Clientes',
+  'About'                       => 'Acerca',
+  'Access Control'              => 'Controlo de Acessos',
+  'Account'                     => 'Conta',
+  'Account Number'              => 'Número da Conta',
+  'Account Number missing!'     => 'Número da Conta não encontrado!',
+  'Account Type'                => 'Tipo de Conta',
+  'Account Type missing!'       => 'Tipo de Conta não encontrado!',
+  'Account deleted!'            => 'Conta apagada',
+  'Account saved!'              => 'Conta guardada',
+  'Accounting'                  => 'Contabilidade',
+  'Accounting Menu'             => 'Menu de Contabilidade',
+  'Accounts'                    => 'Contas',
+  'Active'                      => 'Activo',
+  'Add'                         => 'Novo',
+  'Add Account'                 => 'Nova Conta',
+  'Add Accounts Payables Transaction' => 'Nova Transacção Fornecedores',
+  'Add Accounts Receivables Transaction' => 'Nova Transacção Clientes',
+  'Add Assembly'                => 'Novo Conjunto',
+  'Add Customer'                => 'Novo Cliente',
+  'Add GIFI'                    => 'Adicionar CFOP',
+  'Add General Ledger Transaction' => 'Nova Transacção Livro Razão',
+  'Add Part'                    => 'Novo Produto',
+  'Add Project'                 => 'Novo Projecto',
+  'Add Purchase Invoice'        => 'Nova Factura de Compra',
+  'Add Purchase Order'          => 'Nova Ordem de Compra',
+  'Add Sales Invoice'           => 'Nova Factura de Venda',
+  'Add Sales Order'             => 'Nova Encomenda de Cliente',
+  'Add Service'                 => 'Novo Serviço',
+  'Add Transaction'             => 'Nova Transacção',
+  'Add User'                    => 'Novo Utilizador',
+  'Add Vendor'                  => 'Novo Fornecedor',
+  'Address'                     => 'Endereço',
+  'Administration'              => 'Administração',
+  'Administrator'               => 'Administrador',
+  'All'                         => 'Todos',
+  'All Datasets up to date!'    => 'Todos os Datasets estão Actualizados!',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Total em dívida',
+  'Amount does not equal applied!' => 'Valor diferente do aplicado!',
+  'Amount missing!'             => 'Falta o valor!',
+  'Applied'                     => 'Aplicado',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => 'Tem a certeza que quer APAGAR a Factura Número',
+  'Are you sure you want to delete Order Number' => 'Confirma a remoção da Encomenda?',
+  'Are you sure you want to delete Transaction' => 'Tem a certeza que quer APAGAR a Transacção',
+  'Assemblies'                  => 'Conjuntos',
+  'Assemblies restocked!'       => '',
+  'Assembly Number missing!'    => 'Falta o Número de Produto',
+  'Asset'                       => 'Activo',
+  'Attachment'                  => 'Attachment',
+  'Audit Control'               => 'Controlo de Auditoria',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'BOM'                         => 'BOM',
+  'Backup'                      => 'Backup',
+  'Backup sent to'              => 'Backup enviado para',
+  'Balance'                     => 'Saldo',
+  'Balance Sheet'               => 'Folha de Balanço',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Books are open'              => 'Livros Abertos',
+  'Bought'                      => 'Comprado',
+  'Business Number'             => 'Número de negócio',
+  'C'                           => '',
+  'COGS'                        => 'Custo de Vendas',
+  'Cannot delete account!'      => 'Não é possivel apagar a conta!',
+  'Cannot delete customer!'     => 'Não é possivel apagar o cliente!',
+  'Cannot delete default account!' => 'Não é possível apagar a conta por defeito!',
+  'Cannot delete invoice!'      => 'Não é possivel apagar a factura!',
+  'Cannot delete item already invoiced!' => 'Não posso apagar item já facturado!',
+  'Cannot delete item on order!' => 'Não pode apagar item no pedido',
+  'Cannot delete item which is part of an assembly!' => 'Não é possível apagar Produto que faz parte de um Conjunto!',
+  'Cannot delete item!'         => 'Não é possivel apagar o item!',
+  'Cannot delete order!'        => 'Não é possivel apagar a encomenda!',
+  'Cannot delete transaction!'  => 'Não é possivel apagar a transacção',
+  'Cannot delete vendor!'       => 'Não é possivel apagar o fornecedor',
+  'Cannot have a value in both Debit and Credit!' => 'Não pode ter o valor a Débito E Crédito!',
+  'Cannot post a transaction without a value!' => '',
+  'Cannot post invoice for a closed period!' => 'Não pode lançar factura em período fechado!',
+  'Cannot post invoice!'        => 'Não é possivel lançar factura!',
+  'Cannot post payment for a closed period!' => 'Não pode lançar pagamento em período fechado!',
+  'Cannot post payment!'        => 'Não é possivel lançar pagamento',
+  'Cannot post transaction for a closed period!' => 'Não é possivel lançar transacção para um periodo fechado!',
+  'Cannot post transaction!'    => 'Não é possivel lançar transacção',
+  'Cannot process payment for a closed period!' => 'Não é possivel lançar pagamento para um período fechado',
+  'Cannot save account!'        => 'Não é possível guardar conta!',
+  'Cannot save order!'          => 'Não é possível guardar encomenda!',
+  'Cannot save preferences!'    => 'Não é possível guardar preferências!',
+  'Cannot stock assemblies!'    => '',
+  'Cash'                        => 'Dinheiro',
+  'Cash based'                  => '',
+  'Cc'                          => 'Cc',
+  'Change Admin Password'       => 'Mudar Password Admin',
+  'Change Password'             => 'Mudar Password',
+  'Character Set'               => 'Character Set',
+  'Chart of Accounts'           => 'Plano de Contas',
+  'Check'                       => 'Cheque',
+  'Check printed!'              => 'Cheque impresso!',
+  'Check printing failed!'      => 'Falhou a impressão de cheques!',
+  'Cleared Balance'             => '',
+  'Click on login name to edit!' => 'Clique no login para editar!',
+  'Close Books up to'           => 'Fechar Livros até',
+  'Closed'                      => 'Fechado',
+  'Company'                     => 'Companhia',
+  'Compare to'                  => 'Comparar com',
+  'Confirm!'                    => 'Confirmar!',
+  'Connect to'                  => 'Ligar a',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Copy to COA'                 => 'Copiar para Plano de Contas',
+  'Create Chart of Accounts'    => 'Criar Plano de Contas',
+  'Create Dataset'              => 'Criar Dataset',
+  'Credit'                      => 'Crédito',
+  'Credit Limit'                => 'Limite de Crédito',
+  'Curr'                        => 'Moeda',
+  'Currency'                    => 'Moeda',
+  'Current'                     => '',
+  'Customer'                    => 'Cliente',
+  'Customer deleted!'           => 'Cliente apagado!',
+  'Customer missing!'           => 'Falta cliente!',
+  'Customer not on file!'       => 'Cliente inexistente!',
+  'Customer saved!'             => 'Cliente guardado!',
+  'Customers'                   => 'Clientes',
+  'DBI not installed!'          => 'DBI não está instalado!',
+  'Database'                    => 'Base de Dados',
+  'Database Administration'     => 'Administração de Base de Dados',
+  'Database Driver not checked!' => 'Não seleccionou Driver Base de Dados',
+  'Database Host'               => 'Servidor de Base de Dados',
+  'Database User missing!'      => 'Não existe Utilizador de Base de Dados',
+  'Dataset'                     => 'Dataset',
+  'Dataset missing!'            => 'Dataset não existe!',
+  'Dataset updated!'            => 'Dataset actualizado!',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Data de Vencimento',
+  'Date Format'                 => 'Formato de Data',
+  'Date Paid'                   => 'Data de pagamento',
+  'Date missing!'               => 'Falta a data!',
+  'Debit'                       => 'Débito',
+  'Debit and credit out of balance!' => 'Débito e crédito fora de balanço!',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Decimalplaces'               => 'Casas decimais',
+  'Delete'                      => 'Remover',
+  'Delete Account'              => 'Apagar Conta',
+  'Delete Dataset'              => 'Remover Dataset',
+  'Delivery Date'               => 'Data de entrega',
+  'Deposit'                     => 'Depósito',
+  'Description'                 => 'Descrição',
+  'Difference'                  => 'Diferença',
+  'Directory'                   => 'Directoria',
+  'Discount'                    => 'Desconto',
+  'Done'                        => 'Pronto',
+  'Drawing'                     => '',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => '',
+  'Due'                         => 'Vence',
+  'Due Date'                    => 'Data de Vencimento',
+  'Due Date missing!'           => 'Falta Data de Vencimento!',
+  'E-mail'                      => 'E-Mail',
+  'E-mail Statement to'         => '',
+  'E-mail address missing!'     => 'Falta Endereço de E-mail!',
+  'Edit'                        => 'Editar',
+  'Edit Account'                => 'Editar Conta',
+  'Edit Accounts Payables Transaction' => 'Editar transacção Fornecedores',
+  'Edit Accounts Receivables Transaction' => 'Editar transacção Clientes',
+  'Edit Assembly'               => 'Editar Conjunto',
+  'Edit GIFI'                   => 'Editar CFOP',
+  'Edit General Ledger Transaction' => 'Editar Transacção Livro Razão',
+  'Edit Part'                   => 'Editar Produto',
+  'Edit Preferences for'        => 'Editar Preferências para',
+  'Edit Project'                => 'Editar Projecto',
+  'Edit Purchase Invoice'       => 'Editar Factura de Compra',
+  'Edit Purchase Order'         => 'Editar Ordem de Compra',
+  'Edit Sales Invoice'          => 'Editar Factura de Venda',
+  'Edit Sales Order'            => 'Editar Encomenda',
+  'Edit Service'                => 'Editar Serviço',
+  'Edit Template'               => 'Editar Modelo',
+  'Edit User'                   => 'Editar Utilizador',
+  'Employee'                    => 'Funcionário',
+  'Enforce transaction reversal for all dates' => 'Forçar anulação das transacções para todas as datas',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Indique as suas moedas nativa e estrangeiras usando os códigos de 3 letras (p.ex. EUR:USD:CAD)',
+  'Equity'                      => 'Capital',
+  'Exch'                        => 'Câmbio',
+  'Exchangerate'                => 'Taxa de Câmbio',
+  'Exchangerate Difference'     => 'Diferença na Taxa de Câmbio',
+  'Exchangerate for payment missing!' => 'Falta a taxa de câmbio para o pagamento!',
+  'Exchangerate missing!'       => 'Falta a taxa de câmbio!',
+  'Existing Datasets'           => 'Datasets Existentes',
+  'Expense'                     => 'Despesa',
+  'Expense Account'             => 'Conta de Despesas',
+  'Expense/Asset'               => 'Despesa/Activo',
+  'Extended'                    => '',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'Foreign Exchange Gain'       => 'Diferenças de Câmbio - Proveitos',
+  'Foreign Exchange Loss'       => 'Diferenças de Câmbio - Prejuizos',
+  'From'                        => 'De',
+  'GIFI'                        => 'CFOP - Código Fiscal da Operação',
+  'GIFI deleted!'               => 'CFOP apagado',
+  'GIFI missing!'               => 'Falta CFOP!',
+  'GIFI saved!'                 => 'CFOP guardado',
+  'GL Transaction'              => 'Transacção Livro Razão',
+  'General Ledger'              => 'Livro Razão',
+  'Goods & Services'            => 'Bens e Serviços',
+  'HTML Templates'              => 'Templates HTML',
+  'Heading'                     => 'Cabeçalho',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Não indicou Hostname!',
+  'ID'                          => 'ID',
+  'Image'                       => 'Imagem',
+  'In-line'                     => 'Inline',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Include in drop-down menus'  => 'Incluir nos menus drop-down',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Incluir esta conta nos formulários de cliente/fornecedor para marcar cliente/fornecedor como sujeito a impostos.',
+  'Income'                      => 'Receita',
+  'Income Account'              => 'Conta de Receitas',
+  'Income Statement'            => 'Estado de Receitas',
+  'Incorrect Dataset version!'  => 'Versão Dataset incorrecta!',
+  'Incorrect Password!'         => 'Password Incorrecta!',
+  'Individual Items'            => 'Produtos Individuais',
+  'Inventory'                   => 'Inventário',
+  'Inventory Account'           => 'Conta de Inventário',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Quantidade em Stock tem de ser zero para poder declarar este conjunto obsoleto!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Quantidade em Stock tem de ser zero para poder declarar esta peça obsoleta!',
+  'Inventory quantity must be zero!' => 'Quantidade em Stock tem de ser zero!',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Data de Factura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Número de Factura não encontrado!',
+  'Invoice deleted!'            => 'Factura apagada',
+  'Invoice posted!'             => 'Factura processada',
+  'Invoices'                    => 'Facturas',
+  'Is this a summary account to record' => 'Esta é uma conta sumária a registar',
+  'Item deleted!'               => 'Item apagado',
+  'Item not on file!'           => 'Item não está no arquivo!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'LaTeX Templates'             => 'Modelos LaTeX',
+  'Language'                    => 'Língua',
+  'Last Cost'                   => 'Último Custo',
+  'Last Invoice Number'         => 'Último Número de Factura',
+  'Last Numbers & Default Accounts' => 'Últimos números e Contas por defeito',
+  'Last Purchase Order Number'  => 'Ultimo numero de Ordem de Compra',
+  'Last Sales Order Number'     => 'Último número de Encomenda de vendas',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Não indique host nem port, a não ser que deseje efectuar uma ligação remota',
+  'Liability'                   => 'Passivo',
+  'Licensed to'                 => 'Licenciado a',
+  'Line Total'                  => 'Total da Linha',
+  'Link'                        => 'Ligar',
+  'Link Accounts'               => 'Ligar Contas',
+  'List Accounts'               => 'Listar Contas',
+  'List GIFI'                   => 'Listar CFOP',
+  'List Price'                  => 'Listar Preço',
+  'List Transactions'           => 'Listar Transacções',
+  'Login'                       => 'Login',
+  'Logout'                      => 'Logout',
+  'Make'                        => 'Marca',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'Microfiche'                  => 'Microficha',
+  'Model'                       => 'Modelo',
+  'N/A'                         => 'N/D',
+  'Name'                        => 'Nome',
+  'Name missing!'               => 'Falta o nome!',
+  'New Templates'               => 'Novos Modelos',
+  'No'                          => 'Não',
+  'No Database Drivers available!' => 'Não há Drivers de Base de Dados disponiveis!',
+  'No Dataset selected!'        => 'Não seleccionou Dataset!',
+  'No email address for'        => 'Não existe endereço de email para',
+  'No.'                         => '',
+  'Notes'                       => 'Notas',
+  'Nothing applied!'            => 'Nada aplicado',
+  'Nothing selected!'           => 'Nada seleccionado',
+  'Nothing to delete!'          => 'Nada para remover!',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Formato numérico',
+  'Number missing in Row'       => 'Falta numero na Linha',
+  'O'                           => '',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'On Hand'                     => 'Em Stock',
+  'On Order'                    => 'Encomendado',
+  'Open'                        => 'Abrir',
+  'Oracle Database Administration' => 'Administração Base de Dados Oracle',
+  'Order'                       => 'Encomenda',
+  'Order Date'                  => 'Data da Encomenda',
+  'Order Date missing!'         => 'Falta data da Encomenda',
+  'Order Entry'                 => 'Encomendas de Clientes',
+  'Order Number'                => 'Encomenda Número',
+  'Order Number missing!'       => 'Falta numero da Encomenda!',
+  'Order deleted!'              => 'Encomenda apagada',
+  'Order saved!'                => 'Encomenda guardada',
+  'Ordered'                     => 'Encomendado',
+  'Orphaned'                    => 'Órfão',
+  'Out of balance!'             => '',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Expedição',
+  'Packing List Date missing!'  => 'Falta Data da Lista de Expedição',
+  'Packing List Number missing!' => 'Falta Numero de Lista de Expedição',
+  'Paid'                        => 'Total Pago',
+  'Paid in full'                => '',
+  'Part'                        => 'Produto',
+  'Part Number missing!'        => 'Número de produto não encontrado!',
+  'Parts'                       => 'Produtos',
+  'Parts Inventory'             => 'Inventário',
+  'Password'                    => 'Password',
+  'Password changed!'           => 'Password alterada',
+  'Payables'                    => 'Fornecedores',
+  'Payment'                     => 'Pagamento',
+  'Payment date missing!'       => 'Falta Data de Pagamento!',
+  'Payment posted!'             => 'Pagamento processado',
+  'Payments'                    => 'Pagamentos',
+  'Pg Database Administration'  => 'Administração Base de Dados Postgres',
+  'Phone'                       => 'Tel',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Falta o port!',
+  'Post'                        => 'Processar',
+  'Post as new'                 => 'Processar como novo',
+  'Postscript'                  => 'PostScript',
+  'Preferences'                 => 'Preferências',
+  'Preferences saved!'          => 'Preferências Guardadas!',
+  'Price'                       => 'Preço',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Projecto',
+  'Project Number missing!'     => 'Falta o número do projecto',
+  'Project deleted!'            => 'Projecto apagado',
+  'Project not on file!'        => 'Projecto não existe',
+  'Project saved!'              => 'Projecto guardado',
+  'Projects'                    => 'Projectos',
+  'Purchase Invoice'            => 'Factura de Compra',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Purchase Orders'             => 'Ordens de Compra',
+  'Qty'                         => 'Qtd',
+  'ROP'                         => 'Nível mínimo de stock',
+  'Rate'                        => 'Taxa',
+  'Recd'                        => 'Recebido',
+  'Receipt'                     => 'Recibo',
+  'Receipts'                    => 'Recibos',
+  'Receivables'                 => 'Clientes',
+  'Reconciliation'              => 'Reconciliação',
+  'Record in'                   => 'Registar em',
+  'Reference'                   => 'Referência',
+  'Reference missing!'          => 'Falta referência',
+  'Remaining'                   => 'Sobram',
+  'Report for'                  => 'Relatório para',
+  'Reports'                     => 'Relatórios',
+  'Required by'                 => 'Requerido por',
+  'Retained Earnings'           => 'Lucros Retidos',
+  'Sales'                       => 'Vendas',
+  'Sales Invoice'               => 'Factura de Venda',
+  'Sales Order'                 => 'Encomenda de Venda',
+  'Sales Orders'                => 'Encomendas de Venda',
+  'Save'                        => 'Guardar',
+  'Save as new'                 => 'Guardar como novo',
+  'Save to File'                => 'Guardar em Ficheiro',
+  'Screen'                      => 'Ecran',
+  'Select a Dataset to delete and press "Continue"' => 'Seleccione um Dataset a remover e clique "Continuar"',
+  'Select all'                  => 'Seleccionar todos',
+  'Select from one of the items below' => 'Seleccione um dos items abaixo',
+  'Select from one of the names below' => 'Seleccione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Seleccione um dos projectos abaixo',
+  'Select postscript or PDF!'   => 'Seleccione PostScript ou PDF',
+  'Sell Price'                  => 'Preço de Venda',
+  'Send by E-Mail'              => 'Enviar por Email',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Service'                     => 'Serviço',
+  'Service Items'               => 'Items de Serviço',
+  'Service Number missing!'     => 'Número do serviço não encontrado!',
+  'Services'                    => 'Serviços',
+  'Setup Templates'             => 'Configurar Modelos',
+  'Ship'                        => 'Expedir',
+  'Ship to'                     => 'Expedir para',
+  'Ship via'                    => 'Expedir via',
+  'Short'                       => 'Curta',
+  'Signature'                   => 'Assinatura',
+  'Sold'                        => 'Vendido',
+  'Source'                      => 'Origem',
+  'Standard'                    => 'Padrão',
+  'Statement'                   => '',
+  'Statement Balance'           => '',
+  'Statement sent to'           => '',
+  'Statements sent to printer!' => '',
+  'Stock Assembly'              => 'Conjunto em stock',
+  'Stylesheet'                  => 'Stylesheet',
+  'Subject'                     => 'Assunto',
+  'Subtotal'                    => 'Sub-total',
+  'System'                      => 'Sistema',
+  'Tax'                         => 'Imposto',
+  'Tax Accounts'                => 'Contas de Impostos',
+  'Tax Included'                => 'Impostos incluídos',
+  'Tax collected'               => 'Imposto recolhido',
+  'Tax paid'                    => 'Imposto pago',
+  'Taxable'                     => 'Sujeito a impostos',
+  'Template saved!'             => 'Modelo guardado',
+  'Templates'                   => 'Modelos',
+  'Terms: Net'                  => 'Termos: A pronto',
+  'The following Datasets are not in use and can be deleted' => 'Os seguintes Datasets estão em uso e não podem ser removidos',
+  'The following Datasets need to be updated' => 'Os seguintes Datasets necessitam ser actualizados',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Esta é uma validação preliminar. Nada será criado nem removido neste ponto!',
+  'To'                          => 'Até',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Para adicionar um utilizador a um grupo, edite um nome, mude o login e guarde. O novo utilizador com as mesmas variáveis será guardado sob o novo login',
+  'Top Level'                   => 'Nivel de topo',
+  'Total'                       => 'Total',
+  'Transaction Date missing!'   => 'Falta Data de transacção!',
+  'Transaction deleted!'        => 'Transacção apagada',
+  'Transaction posted!'         => 'Transacção processada',
+  'Transaction reversal enforced for all dates' => 'Cancelamento de transacção forçado para todas as datas',
+  'Transaction reversal enforced up to' => 'Cancelamento de transacção forçado até',
+  'Transactions'                => 'Transacções',
+  'Transactions exist, cannot delete customer!' => 'Existem transacções, não pode apagar o cliente!',
+  'Transactions exist, cannot delete vendor!' => 'Existem transacções, não pode apagar fornecedor!',
+  'Transactions exist; cannot delete account!' => 'Existem Transacções, não é possivel remover conta!',
+  'Trial Balance'               => 'Balancete',
+  'Unit'                        => 'Unidade',
+  'Unit of measure'             => 'Unidade de medida',
+  'Update'                      => 'Actualizar',
+  'Update Dataset'              => 'Actualizar Dataset',
+  'Updated'                     => 'Actualizado',
+  'Use Templates'               => 'Usar Templates',
+  'User'                        => 'Utilizador',
+  'User deleted!'               => 'Utilizador removido',
+  'User saved!'                 => 'Utilizador guardado',
+  'Vendor'                      => 'Fornecedor',
+  'Vendor deleted!'             => 'Fornecedor apagado',
+  'Vendor missing!'             => 'Falta fornecedor',
+  'Vendor not on file!'         => 'Fornecedor não existe',
+  'Vendor saved!'               => 'Fornecedor guardado',
+  'Vendors'                     => 'Fornecedores',
+  'Version'                     => 'Versão',
+  'Weight'                      => 'Peso',
+  'Weight Unit'                 => 'Unidade de Peso',
+  'What type of item is this?'  => 'Que tipo de Item é este?',
+  'Year End'                    => 'Fim de ano',
+  'Yes'                         => 'Sim',
+  'You are logged out!'         => 'Terminou a sessão!',
+  'You did not enter a name!'   => 'Não indicou nome!',
+  'You must enter a host and port for local and remote connections!' => 'Tem de indicar host e port para ligações locais e remotas!',
+  'as at'                       => '',
+  'collected on sales'          => 'recolhido sobre vendas',
+  'days'                        => 'dias',
+  'does not exist'              => 'não existe',
+  'ea'                          => 'cd',
+  'emailed to'                  => 'enviado por email para',
+  'for Period'                  => 'pelo período',
+  'hr'                          => 'hr',
+  'is already a member!'        => 'já é membro!',
+  'is not a member!'            => 'não é membro!',
+  'localhost'                   => 'localhost',
+  'paid on purchases'           => 'pago em aquisições',
+  'sent to printer'             => 'enviado para a impressora',
+  'successfully created!'       => 'criado com sucesso!',
+  'successfully deleted!'       => 'removido com sucesso!',
+  'to'                          => 'para',
+  'website'                     => 'website',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/am b/sql-ledger/locale/pt/am
new file mode 100644 (file)
index 0000000..a926fe3
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Fornecedores',
+  'AR'                          => 'Clientes',
+  'Account'                     => 'Conta',
+  'Account Number'              => 'Número da Conta',
+  'Account Number missing!'     => 'Número da Conta não encontrado!',
+  'Account Type'                => 'Tipo de Conta',
+  'Account Type missing!'       => 'Tipo de Conta não encontrado!',
+  'Account deleted!'            => 'Conta apagada',
+  'Account saved!'              => 'Conta guardada',
+  'Add Account'                 => 'Nova Conta',
+  'Add GIFI'                    => 'Adicionar CFOP',
+  'Address'                     => 'Endereço',
+  'Asset'                       => 'Activo',
+  'Audit Control'               => 'Controlo de Auditoria',
+  'Backup sent to'              => 'Backup enviado para',
+  'Books are open'              => 'Livros Abertos',
+  'Business Number'             => 'Número de negócio',
+  'COGS'                        => 'Custo de Vendas',
+  'Cannot delete account!'      => 'Não é possivel apagar a conta!',
+  'Cannot delete default account!' => 'Não é possível apagar a conta por defeito!',
+  'Cannot save account!'        => 'Não é possível guardar conta!',
+  'Cannot save preferences!'    => 'Não é possível guardar preferências!',
+  'Character Set'               => 'Character Set',
+  'Chart of Accounts'           => 'Plano de Contas',
+  'Close Books up to'           => 'Fechar Livros até',
+  'Company'                     => 'Companhia',
+  'Continue'                    => 'Continuar',
+  'Copy to COA'                 => 'Copiar para Plano de Contas',
+  'Credit'                      => 'Crédito',
+  'Date Format'                 => 'Formato de Data',
+  'Debit'                       => 'Débito',
+  'Delete'                      => 'Remover',
+  'Delete Account'              => 'Apagar Conta',
+  'Description'                 => 'Descrição',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'E-Mail',
+  'Edit'                        => 'Editar',
+  'Edit Account'                => 'Editar Conta',
+  'Edit GIFI'                   => 'Editar CFOP',
+  'Edit Preferences for'        => 'Editar Preferências para',
+  'Edit Template'               => 'Editar Modelo',
+  'Enforce transaction reversal for all dates' => 'Forçar anulação das transacções para todas as datas',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Indique as suas moedas nativa e estrangeiras usando os códigos de 3 letras (p.ex. EUR:USD:CAD)',
+  'Equity'                      => 'Capital',
+  'Expense'                     => 'Despesa',
+  'Expense Account'             => 'Conta de Despesas',
+  'Expense/Asset'               => 'Despesa/Activo',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Diferenças de Câmbio - Proveitos',
+  'Foreign Exchange Loss'       => 'Diferenças de Câmbio - Prejuizos',
+  'GIFI'                        => 'CFOP - Código Fiscal da Operação',
+  'GIFI deleted!'               => 'CFOP apagado',
+  'GIFI missing!'               => 'Falta CFOP!',
+  'GIFI saved!'                 => 'CFOP guardado',
+  'Heading'                     => 'Cabeçalho',
+  'Include in drop-down menus'  => 'Incluir nos menus drop-down',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Incluir esta conta nos formulários de cliente/fornecedor para marcar cliente/fornecedor como sujeito a impostos.',
+  'Income'                      => 'Receita',
+  'Income Account'              => 'Conta de Receitas',
+  'Inventory'                   => 'Inventário',
+  'Inventory Account'           => 'Conta de Inventário',
+  'Is this a summary account to record' => 'Esta é uma conta sumária a registar',
+  'Language'                    => 'Língua',
+  'Last Invoice Number'         => 'Último Número de Factura',
+  'Last Numbers & Default Accounts' => 'Últimos números e Contas por defeito',
+  'Last Purchase Order Number'  => 'Ultimo numero de Ordem de Compra',
+  'Last Sales Order Number'     => 'Último número de Encomenda de vendas',
+  'Liability'                   => 'Passivo',
+  'Link'                        => 'Ligar',
+  'Name'                        => 'Nome',
+  'No'                          => 'Não',
+  'No email address for'        => 'Não existe endereço de email para',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Formato numérico',
+  'Parts Inventory'             => 'Inventário',
+  'Password'                    => 'Password',
+  'Payables'                    => 'Fornecedores',
+  'Payment'                     => 'Pagamento',
+  'Phone'                       => 'Tel',
+  'Preferences saved!'          => 'Preferências Guardadas!',
+  'Rate'                        => 'Taxa',
+  'Receivables'                 => 'Clientes',
+  'Sales'                       => 'Vendas',
+  'Save'                        => 'Guardar',
+  'Service Items'               => 'Items de Serviço',
+  'Ship via'                    => 'Expedir via',
+  'Signature'                   => 'Assinatura',
+  'Stylesheet'                  => 'Stylesheet',
+  'Tax'                         => 'Imposto',
+  'Tax Accounts'                => 'Contas de Impostos',
+  'Template saved!'             => 'Modelo guardado',
+  'Transaction reversal enforced for all dates' => 'Cancelamento de transacção forçado para todas as datas',
+  'Transaction reversal enforced up to' => 'Cancelamento de transacção forçado até',
+  'Transactions exist; cannot delete account!' => 'Existem Transacções, não é possivel remover conta!',
+  'Weight Unit'                 => 'Unidade de Peso',
+  'Year End'                    => 'Fim de ano',
+  'Yes'                         => 'Sim',
+  'does not exist'              => 'não existe',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'nova_conta'                  => 'add_account',
+  'continuar'                   => 'continue',
+  'copiar_para_plano_de_contas' => 'copy_to_coa',
+  'remover'                     => 'delete',
+  'editar'                      => 'edit',
+  'editar_conta'                => 'edit_account',
+  'guardar'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/ap b/sql-ledger/locale/pt/ap
new file mode 100644 (file)
index 0000000..f3a6467
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Transacção Fornecedores',
+  'AP Transactions'             => 'Transacções Fornecedores',
+  'Account'                     => 'Conta',
+  'Add Accounts Payables Transaction' => 'Nova Transacção Fornecedores',
+  'Address'                     => 'Endereço',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Total em dívida',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => 'Tem a certeza que quer APAGAR a Transacção',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Cannot delete transaction!'  => 'Não é possivel apagar a transacção',
+  'Cannot post payment for a closed period!' => 'Não pode lançar pagamento em período fechado!',
+  'Cannot post transaction for a closed period!' => 'Não é possivel lançar transacção para um periodo fechado!',
+  'Cannot post transaction!'    => 'Não é possivel lançar transacção',
+  'Closed'                      => 'Fechado',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Moeda',
+  'Customer not on file!'       => 'Cliente inexistente!',
+  'Date'                        => 'Data',
+  'Date Paid'                   => 'Data de pagamento',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Remover',
+  'Description'                 => 'Descrição',
+  'Due Date'                    => 'Data de Vencimento',
+  'Due Date missing!'           => 'Falta Data de Vencimento!',
+  'Edit Accounts Payables Transaction' => 'Editar transacção Fornecedores',
+  'Employee'                    => 'Funcionário',
+  'Exch'                        => 'Câmbio',
+  'Exchangerate'                => 'Taxa de Câmbio',
+  'Exchangerate for payment missing!' => 'Falta a taxa de câmbio para o pagamento!',
+  'Exchangerate missing!'       => 'Falta a taxa de câmbio!',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Data de Factura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Número de Factura não encontrado!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Open'                        => 'Abrir',
+  'Order'                       => 'Encomenda',
+  'Order Number'                => 'Encomenda Número',
+  'Paid'                        => 'Total Pago',
+  'Payment date missing!'       => 'Falta Data de Pagamento!',
+  'Payments'                    => 'Pagamentos',
+  'Post'                        => 'Processar',
+  'Post as new'                 => 'Processar como novo',
+  'Project'                     => 'Projecto',
+  'Project not on file!'        => 'Projecto não existe',
+  'Purchase Invoice'            => 'Factura de Compra',
+  'Select from one of the names below' => 'Seleccione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Seleccione um dos projectos abaixo',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Source'                      => 'Origem',
+  'Subtotal'                    => 'Sub-total',
+  'Tax'                         => 'Imposto',
+  'Tax Included'                => 'Impostos incluídos',
+  'To'                          => 'Até',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transacção apagada',
+  'Transaction posted!'         => 'Transacção processada',
+  'Update'                      => 'Actualizar',
+  'Vendor'                      => 'Fornecedor',
+  'Vendor missing!'             => 'Falta fornecedor',
+  'Vendor not on file!'         => 'Fornecedor não existe',
+  'Yes'                         => 'Sim',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'transacção_fornecedores'     => 'ap_transaction',
+  'nova_transacção_fornecedores' => 'add_accounts_payables_transaction',
+  'continuar'                   => 'continue',
+  'remover'                     => 'delete',
+  'editar_transacção_fornecedores' => 'edit_accounts_payables_transaction',
+  'processar'                   => 'post',
+  'processar_como_novo'         => 'post_as_new',
+  'factura_de_compra'           => 'purchase_invoice',
+  'actualizar'                  => 'update',
+  'sim'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/ar b/sql-ledger/locale/pt/ar
new file mode 100644 (file)
index 0000000..7790e3c
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'Transacção Clientes',
+  'AR Transactions'             => 'Transacções Clientes',
+  'Account'                     => 'Conta',
+  'Add Accounts Receivables Transaction' => 'Nova Transacção Clientes',
+  'Address'                     => 'Endereço',
+  'Amount'                      => 'Total',
+  'Amount Due'                  => 'Total em dívida',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => 'Tem a certeza que quer APAGAR a Transacção',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Cannot delete transaction!'  => 'Não é possivel apagar a transacção',
+  'Cannot post payment for a closed period!' => 'Não pode lançar pagamento em período fechado!',
+  'Cannot post transaction for a closed period!' => 'Não é possivel lançar transacção para um periodo fechado!',
+  'Cannot post transaction!'    => 'Não é possivel lançar transacção',
+  'Closed'                      => 'Fechado',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Limite de Crédito',
+  'Currency'                    => 'Moeda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Falta cliente!',
+  'Customer not on file!'       => 'Cliente inexistente!',
+  'Date'                        => 'Data',
+  'Date Paid'                   => 'Data de pagamento',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Remover',
+  'Description'                 => 'Descrição',
+  'Due Date'                    => 'Data de Vencimento',
+  'Due Date missing!'           => 'Falta Data de Vencimento!',
+  'Edit Accounts Receivables Transaction' => 'Editar transacção Clientes',
+  'Employee'                    => 'Funcionário',
+  'Exch'                        => 'Câmbio',
+  'Exchangerate'                => 'Taxa de Câmbio',
+  'Exchangerate for payment missing!' => 'Falta a taxa de câmbio para o pagamento!',
+  'Exchangerate missing!'       => 'Falta a taxa de câmbio!',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Data de Factura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Número de Factura não encontrado!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Open'                        => 'Abrir',
+  'Order'                       => 'Encomenda',
+  'Order Number'                => 'Encomenda Número',
+  'Paid'                        => 'Total Pago',
+  'Payment date missing!'       => 'Falta Data de Pagamento!',
+  'Payments'                    => 'Pagamentos',
+  'Post'                        => 'Processar',
+  'Post as new'                 => 'Processar como novo',
+  'Project'                     => 'Projecto',
+  'Project not on file!'        => 'Projecto não existe',
+  'Remaining'                   => 'Sobram',
+  'Sales Invoice'               => 'Factura de Venda',
+  'Select from one of the names below' => 'Seleccione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Seleccione um dos projectos abaixo',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Source'                      => 'Origem',
+  'Subtotal'                    => 'Sub-total',
+  'Tax'                         => 'Imposto',
+  'Tax Included'                => 'Impostos incluídos',
+  'To'                          => 'Até',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transacção apagada',
+  'Transaction posted!'         => 'Transacção processada',
+  'Update'                      => 'Actualizar',
+  'Vendor not on file!'         => 'Fornecedor não existe',
+  'Yes'                         => 'Sim',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'transacção_clientes'         => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'remover'                     => 'delete',
+  'processar'                   => 'post',
+  'processar_como_novo'         => 'post_as_new',
+  'factura_de_venda'            => 'sales_invoice',
+  'actualizar'                  => 'update',
+  'sim'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/arap b/sql-ledger/locale/pt/arap
new file mode 100644 (file)
index 0000000..bbfaad0
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Endereço',
+  'Continue'                    => 'Continuar',
+  'Customer not on file!'       => 'Cliente inexistente!',
+  'Description'                 => 'Descrição',
+  'Number'                      => 'Número',
+  'Project not on file!'        => 'Projecto não existe',
+  'Select from one of the names below' => 'Seleccione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Seleccione um dos projectos abaixo',
+  'Vendor not on file!'         => 'Fornecedor não existe',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/ca b/sql-ledger/locale/pt/ca
new file mode 100644 (file)
index 0000000..01ea0fe
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Conta',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Saldo',
+  'Chart of Accounts'           => 'Plano de Contas',
+  'Credit'                      => 'Crédito',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Débito',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Description'                 => 'Descrição',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'GIFI'                        => 'CFOP - Código Fiscal da Operação',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'List Transactions'           => 'Listar Transacções',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Reference'                   => 'Referência',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Subtotal'                    => 'Sub-total',
+  'To'                          => 'Até',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'listar_transacções'          => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/cp b/sql-ledger/locale/pt/cp
new file mode 100644 (file)
index 0000000..1d62d31
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Conta',
+  'Address'                     => 'Endereço',
+  'Amount'                      => 'Total',
+  'Amount does not equal applied!' => 'Valor diferente do aplicado!',
+  'Amount missing!'             => 'Falta o valor!',
+  'Applied'                     => 'Aplicado',
+  'Cannot post payment!'        => 'Não é possivel lançar pagamento',
+  'Cannot process payment for a closed period!' => 'Não é possivel lançar pagamento para um período fechado',
+  'Check'                       => 'Cheque',
+  'Check printed!'              => 'Cheque impresso!',
+  'Check printing failed!'      => 'Falhou a impressão de cheques!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Moeda',
+  'Customer'                    => 'Cliente',
+  'Customer not on file!'       => 'Cliente inexistente!',
+  'Date'                        => 'Data',
+  'Date missing!'               => 'Falta a data!',
+  'Description'                 => 'Descrição',
+  'Due'                         => 'Vence',
+  'Exchangerate'                => 'Taxa de Câmbio',
+  'From'                        => 'De',
+  'Invoice'                     => 'Factura',
+  'Invoices'                    => 'Facturas',
+  'Nothing applied!'            => 'Nada aplicado',
+  'Number'                      => 'Número',
+  'Paid in full'                => 'Paid in full',
+  'Payment'                     => 'Pagamento',
+  'Payment posted!'             => 'Pagamento processado',
+  'Post'                        => 'Processar',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impressora',
+  'Project not on file!'        => 'Projecto não existe',
+  'Receipt'                     => 'Recibo',
+  'Reference'                   => 'Referência',
+  'Screen'                      => 'Ecran',
+  'Select from one of the names below' => 'Seleccione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Seleccione um dos projectos abaixo',
+  'To'                          => 'Até',
+  'Update'                      => 'Actualizar',
+  'Vendor'                      => 'Fornecedor',
+  'Vendor not on file!'         => 'Fornecedor não existe',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+  'processar'                   => 'post',
+  'imprimir'                    => 'print',
+  'actualizar'                  => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/ct b/sql-ledger/locale/pt/ct
new file mode 100644 (file)
index 0000000..74187f2
--- /dev/null
@@ -0,0 +1,69 @@
+$self{texts} = {
+  'Add'                         => 'Novo',
+  'Address'                     => 'Endereço',
+  'All'                         => 'Todos',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Não é possivel apagar o cliente!',
+  'Cannot delete vendor!'       => 'Não é possivel apagar o fornecedor',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Limite de Crédito',
+  'Customer deleted!'           => 'Cliente apagado!',
+  'Customer saved!'             => 'Cliente guardado!',
+  'Customers'                   => 'Clientes',
+  'Delete'                      => 'Remover',
+  'Discount'                    => 'Desconto',
+  'E-mail'                      => 'E-Mail',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Invoice'                     => 'Factura',
+  'Name'                        => 'Nome',
+  'Name missing!'               => 'Falta o nome!',
+  'Notes'                       => 'Notas',
+  'Number'                      => 'Número',
+  'Order'                       => 'Encomenda',
+  'Orphaned'                    => 'Órfão',
+  'Phone'                       => 'Tel',
+  'Save'                        => 'Guardar',
+  'Ship to'                     => 'Expedir para',
+  'Tax Included'                => 'Impostos incluídos',
+  'Taxable'                     => 'Sujeito a impostos',
+  'Terms: Net'                  => 'Termos: A pronto',
+  'Transactions exist, cannot delete customer!' => 'Existem transacções, não pode apagar o cliente!',
+  'Transactions exist, cannot delete vendor!' => 'Existem transacções, não pode apagar fornecedor!',
+  'Vendor deleted!'             => 'Fornecedor apagado',
+  'Vendor saved!'               => 'Fornecedor guardado',
+  'Vendors'                     => 'Fornecedores',
+  'days'                        => 'dias',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'novo'                        => 'add',
+  'continuar'                   => 'continue',
+  'remover'                     => 'delete',
+  'factura'                     => 'invoice',
+  'encomenda'                   => 'order',
+  'guardar'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/gl b/sql-ledger/locale/pt/gl
new file mode 100644 (file)
index 0000000..e2065ec
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Transacção Fornecedores',
+  'AR Transaction'              => 'Transacção Clientes',
+  'Account'                     => 'Conta',
+  'Add General Ledger Transaction' => 'Nova Transacção Livro Razão',
+  'Address'                     => 'Endereço',
+  'All'                         => 'Todos',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Transaction' => 'Tem a certeza que quer APAGAR a Transacção',
+  'Asset'                       => 'Activo',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance'                     => 'Saldo',
+  'Cannot delete transaction!'  => 'Não é possivel apagar a transacção',
+  'Cannot have a value in both Debit and Credit!' => 'Não pode ter o valor a Débito E Crédito!',
+  'Cannot post a transaction without a value!' => 'Cannot post a transaction without a value!',
+  'Cannot post transaction for a closed period!' => 'Não é possivel lançar transacção para um periodo fechado!',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Credit'                      => 'Crédito',
+  'Customer not on file!'       => 'Cliente inexistente!',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Débito',
+  'Debit and credit out of balance!' => 'Débito e crédito fora de balanço!',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Remover',
+  'Description'                 => 'Descrição',
+  'Edit General Ledger Transaction' => 'Editar Transacção Livro Razão',
+  'Equity'                      => 'Capital',
+  'Expense'                     => 'Despesa',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'GIFI'                        => 'CFOP - Código Fiscal da Operação',
+  'GL Transaction'              => 'Transacção Livro Razão',
+  'General Ledger'              => 'Livro Razão',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Income'                      => 'Receita',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Liability'                   => 'Passivo',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Post'                        => 'Processar',
+  'Post as new'                 => 'Processar como novo',
+  'Project'                     => 'Projecto',
+  'Project not on file!'        => 'Projecto não existe',
+  'Purchase Invoice'            => 'Factura de Compra',
+  'Reference'                   => 'Referência',
+  'Reference missing!'          => 'Falta referência',
+  'Reports'                     => 'Relatórios',
+  'Sales Invoice'               => 'Factura de Venda',
+  'Select from one of the names below' => 'Seleccione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Seleccione um dos projectos abaixo',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Source'                      => 'Origem',
+  'Subtotal'                    => 'Sub-total',
+  'To'                          => 'Até',
+  'Transaction Date missing!'   => 'Falta Data de transacção!',
+  'Transaction deleted!'        => 'Transacção apagada',
+  'Transaction posted!'         => 'Transacção processada',
+  'Update'                      => 'Actualizar',
+  'Vendor not on file!'         => 'Fornecedor não existe',
+  'Yes'                         => 'Sim',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'transacção_fornecedores'     => 'ap_transaction',
+  'transacção_clientes'         => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'remover'                     => 'delete',
+  'transacção_livro_razão'      => 'gl_transaction',
+  'processar'                   => 'post',
+  'processar_como_novo'         => 'post_as_new',
+  'factura_de_compra'           => 'purchase_invoice',
+  'factura_de_venda'            => 'sales_invoice',
+  'actualizar'                  => 'update',
+  'sim'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/ic b/sql-ledger/locale/pt/ic
new file mode 100644 (file)
index 0000000..80d4eb6
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Activo',
+  'Add'                         => 'Novo',
+  'Add Assembly'                => 'Novo Conjunto',
+  'Add Part'                    => 'Novo Produto',
+  'Add Purchase Order'          => 'Nova Ordem de Compra',
+  'Add Sales Order'             => 'Nova Encomenda de Cliente',
+  'Add Service'                 => 'Novo Serviço',
+  'Address'                     => 'Endereço',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Assemblies'                  => 'Conjuntos',
+  'Assemblies restocked!'       => 'Assemblies restocked!',
+  'Assembly Number missing!'    => 'Falta o Número de Produto',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Bought'                      => 'Comprado',
+  'COGS'                        => 'Custo de Vendas',
+  'Cannot delete item already invoiced!' => 'Não posso apagar item já facturado!',
+  'Cannot delete item on order!' => 'Não pode apagar item no pedido',
+  'Cannot delete item which is part of an assembly!' => 'Não é possível apagar Produto que faz parte de um Conjunto!',
+  'Cannot delete item!'         => 'Não é possivel apagar o item!',
+  'Cannot stock assemblies!'    => 'Cannot stock assemblies!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Remover',
+  'Delivery Date'               => 'Data de entrega',
+  'Description'                 => 'Descrição',
+  'Drawing'                     => 'Drawing',
+  'E-mail'                      => 'E-Mail',
+  'E-mail address missing!'     => 'Falta Endereço de E-mail!',
+  'Edit Assembly'               => 'Editar Conjunto',
+  'Edit Part'                   => 'Editar Produto',
+  'Edit Service'                => 'Editar Serviço',
+  'Expense'                     => 'Despesa',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'Image'                       => 'Imagem',
+  'In-line'                     => 'Inline',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Income'                      => 'Receita',
+  'Individual Items'            => 'Produtos Individuais',
+  'Inventory'                   => 'Inventário',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Quantidade em Stock tem de ser zero para poder declarar este conjunto obsoleto!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Quantidade em Stock tem de ser zero para poder declarar esta peça obsoleta!',
+  'Inventory quantity must be zero!' => 'Quantidade em Stock tem de ser zero!',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Número de Factura não encontrado!',
+  'Item deleted!'               => 'Item apagado',
+  'Item not on file!'           => 'Item não está no arquivo!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Last Cost'                   => 'Último Custo',
+  'Line Total'                  => 'Total da Linha',
+  'Link Accounts'               => 'Ligar Contas',
+  'List Price'                  => 'Listar Preço',
+  'Make'                        => 'Marca',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'Microfiche'                  => 'Microficha',
+  'Model'                       => 'Modelo',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta numero na Linha',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'On Hand'                     => 'Em Stock',
+  'On Order'                    => 'Encomendado',
+  'Order'                       => 'Encomenda',
+  'Order Date missing!'         => 'Falta data da Encomenda',
+  'Order Number'                => 'Encomenda Número',
+  'Order Number missing!'       => 'Falta numero da Encomenda!',
+  'Ordered'                     => 'Encomendado',
+  'Orphaned'                    => 'Órfão',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Expedição',
+  'Packing List Date missing!'  => 'Falta Data da Lista de Expedição',
+  'Packing List Number missing!' => 'Falta Numero de Lista de Expedição',
+  'Part'                        => 'Produto',
+  'Part Number missing!'        => 'Número de produto não encontrado!',
+  'Parts'                       => 'Produtos',
+  'Phone'                       => 'Tel',
+  'Postscript'                  => 'PostScript',
+  'Price'                       => 'Preço',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Projecto',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Qty'                         => 'Qtd',
+  'ROP'                         => 'Nível mínimo de stock',
+  'Recd'                        => 'Recebido',
+  'Required by'                 => 'Requerido por',
+  'Sales'                       => 'Vendas',
+  'Sales Order'                 => 'Encomenda de Venda',
+  'Save'                        => 'Guardar',
+  'Screen'                      => 'Ecran',
+  'Select from one of the items below' => 'Seleccione um dos items abaixo',
+  'Select postscript or PDF!'   => 'Seleccione PostScript ou PDF',
+  'Sell Price'                  => 'Preço de Venda',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Service'                     => 'Serviço',
+  'Service Number missing!'     => 'Número do serviço não encontrado!',
+  'Services'                    => 'Serviços',
+  'Ship'                        => 'Expedir',
+  'Ship to'                     => 'Expedir para',
+  'Short'                       => 'Curta',
+  'Sold'                        => 'Vendido',
+  'Stock Assembly'              => 'Conjunto em stock',
+  'Subject'                     => 'Assunto',
+  'Subtotal'                    => 'Sub-total',
+  'Tax'                         => 'Imposto',
+  'To'                          => 'Até',
+  'Top Level'                   => 'Nivel de topo',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidade',
+  'Unit of measure'             => 'Unidade de medida',
+  'Update'                      => 'Actualizar',
+  'Updated'                     => 'Actualizado',
+  'Weight'                      => 'Peso',
+  'What type of item is this?'  => 'Que tipo de Item é este?',
+  'ea'                          => 'cd',
+  'emailed to'                  => 'enviado por email para',
+  'hr'                          => 'hr',
+  'sent to printer'             => 'enviado para a impressora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'novo'                        => 'add',
+  'novo_conjunto'               => 'add_assembly',
+  'novo_produto'                => 'add_part',
+  'novo_serviço'                => 'add_service',
+  'continuar'                   => 'continue',
+  'remover'                     => 'delete',
+  'editar_conjunto'             => 'edit_assembly',
+  'editar_produto'              => 'edit_part',
+  'editar_serviço'              => 'edit_service',
+  'guardar'                     => 'save',
+  'actualizar'                  => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/io b/sql-ledger/locale/pt/io
new file mode 100644 (file)
index 0000000..b85c352
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Nova Ordem de Compra',
+  'Add Sales Order'             => 'Nova Encomenda de Cliente',
+  'Address'                     => 'Endereço',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delivery Date'               => 'Data de entrega',
+  'Description'                 => 'Descrição',
+  'E-mail'                      => 'E-Mail',
+  'E-mail address missing!'     => 'Falta Endereço de E-mail!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'In-line'                     => 'Inline',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number missing!'     => 'Número de Factura não encontrado!',
+  'Item not on file!'           => 'Item não está no arquivo!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta numero na Linha',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Order'                       => 'Encomenda',
+  'Order Date missing!'         => 'Falta data da Encomenda',
+  'Order Number missing!'       => 'Falta numero da Encomenda!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Expedição',
+  'Packing List Date missing!'  => 'Falta Data da Lista de Expedição',
+  'Packing List Number missing!' => 'Falta Numero de Lista de Expedição',
+  'Part'                        => 'Produto',
+  'Phone'                       => 'Tel',
+  'Postscript'                  => 'PostScript',
+  'Price'                       => 'Preço',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Projecto',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Qty'                         => 'Qtd',
+  'Recd'                        => 'Recebido',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Encomenda de Venda',
+  'Screen'                      => 'Ecran',
+  'Select from one of the items below' => 'Seleccione um dos items abaixo',
+  'Select postscript or PDF!'   => 'Seleccione PostScript ou PDF',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Service'                     => 'Serviço',
+  'Ship'                        => 'Expedir',
+  'Ship to'                     => 'Expedir para',
+  'Subject'                     => 'Assunto',
+  'To'                          => 'Até',
+  'Unit'                        => 'Unidade',
+  'What type of item is this?'  => 'Que tipo de Item é este?',
+  'emailed to'                  => 'enviado por email para',
+  'sent to printer'             => 'enviado para a impressora',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/ir b/sql-ledger/locale/pt/ir
new file mode 100644 (file)
index 0000000..88fb49e
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Conta',
+  'Add Purchase Invoice'        => 'Nova Factura de Compra',
+  'Add Purchase Order'          => 'Nova Ordem de Compra',
+  'Add Sales Order'             => 'Nova Encomenda de Cliente',
+  'Address'                     => 'Endereço',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => 'Tem a certeza que quer APAGAR a Factura Número',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Não é possivel apagar a factura!',
+  'Cannot post invoice for a closed period!' => 'Não pode lançar factura em período fechado!',
+  'Cannot post invoice!'        => 'Não é possivel lançar factura!',
+  'Cannot post payment for a closed period!' => 'Não pode lançar pagamento em período fechado!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Currency'                    => 'Moeda',
+  'Customer not on file!'       => 'Cliente inexistente!',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Data de Vencimento',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Remover',
+  'Delivery Date'               => 'Data de entrega',
+  'Description'                 => 'Descrição',
+  'E-mail'                      => 'E-Mail',
+  'E-mail address missing!'     => 'Falta Endereço de E-mail!',
+  'Edit Purchase Invoice'       => 'Editar Factura de Compra',
+  'Exch'                        => 'Câmbio',
+  'Exchangerate'                => 'Taxa de Câmbio',
+  'Exchangerate for payment missing!' => 'Falta a taxa de câmbio para o pagamento!',
+  'Exchangerate missing!'       => 'Falta a taxa de câmbio!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'In-line'                     => 'Inline',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Data de Factura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Número de Factura não encontrado!',
+  'Invoice deleted!'            => 'Factura apagada',
+  'Invoice posted!'             => 'Factura processada',
+  'Item not on file!'           => 'Item não está no arquivo!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta numero na Linha',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Order'                       => 'Encomenda',
+  'Order Date missing!'         => 'Falta data da Encomenda',
+  'Order Number'                => 'Encomenda Número',
+  'Order Number missing!'       => 'Falta numero da Encomenda!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Expedição',
+  'Packing List Date missing!'  => 'Falta Data da Lista de Expedição',
+  'Packing List Number missing!' => 'Falta Numero de Lista de Expedição',
+  'Part'                        => 'Produto',
+  'Payment date missing!'       => 'Falta Data de Pagamento!',
+  'Payments'                    => 'Pagamentos',
+  'Phone'                       => 'Tel',
+  'Post'                        => 'Processar',
+  'Post as new'                 => 'Processar como novo',
+  'Postscript'                  => 'PostScript',
+  'Price'                       => 'Preço',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Projecto',
+  'Project not on file!'        => 'Projecto não existe',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Qty'                         => 'Qtd',
+  'Recd'                        => 'Recebido',
+  'Record in'                   => 'Registar em',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Encomenda de Venda',
+  'Screen'                      => 'Ecran',
+  'Select from one of the items below' => 'Seleccione um dos items abaixo',
+  'Select from one of the names below' => 'Seleccione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Seleccione um dos projectos abaixo',
+  'Select postscript or PDF!'   => 'Seleccione PostScript ou PDF',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Service'                     => 'Serviço',
+  'Ship'                        => 'Expedir',
+  'Ship to'                     => 'Expedir para',
+  'Source'                      => 'Origem',
+  'Subject'                     => 'Assunto',
+  'Subtotal'                    => 'Sub-total',
+  'Tax Included'                => 'Impostos incluídos',
+  'To'                          => 'Até',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidade',
+  'Update'                      => 'Actualizar',
+  'Vendor'                      => 'Fornecedor',
+  'Vendor missing!'             => 'Falta fornecedor',
+  'Vendor not on file!'         => 'Fornecedor não existe',
+  'What type of item is this?'  => 'Que tipo de Item é este?',
+  'Yes'                         => 'Sim',
+  'ea'                          => 'cd',
+  'emailed to'                  => 'enviado por email para',
+  'sent to printer'             => 'enviado para a impressora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'remover'                     => 'delete',
+  'encomenda'                   => 'order',
+  'processar'                   => 'post',
+  'processar_como_novo'         => 'post_as_new',
+  'actualizar'                  => 'update',
+  'sim'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/is b/sql-ledger/locale/pt/is
new file mode 100644 (file)
index 0000000..9a33604
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Conta',
+  'Add Purchase Order'          => 'Nova Ordem de Compra',
+  'Add Sales Invoice'           => 'Nova Factura de Venda',
+  'Add Sales Order'             => 'Nova Encomenda de Cliente',
+  'Address'                     => 'Endereço',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Invoice Number' => 'Tem a certeza que quer APAGAR a Factura Número',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Não é possivel apagar a factura!',
+  'Cannot post invoice for a closed period!' => 'Não pode lançar factura em período fechado!',
+  'Cannot post invoice!'        => 'Não é possivel lançar factura!',
+  'Cannot post payment for a closed period!' => 'Não pode lançar pagamento em período fechado!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Credit Limit'                => 'Limite de Crédito',
+  'Currency'                    => 'Moeda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Falta cliente!',
+  'Customer not on file!'       => 'Cliente inexistente!',
+  'Date'                        => 'Data',
+  'Date Due'                    => 'Data de Vencimento',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Remover',
+  'Delivery Date'               => 'Data de entrega',
+  'Description'                 => 'Descrição',
+  'E-mail'                      => 'E-Mail',
+  'E-mail address missing!'     => 'Falta Endereço de E-mail!',
+  'Edit Sales Invoice'          => 'Editar Factura de Venda',
+  'Exch'                        => 'Câmbio',
+  'Exchangerate'                => 'Taxa de Câmbio',
+  'Exchangerate for payment missing!' => 'Falta a taxa de câmbio para o pagamento!',
+  'Exchangerate missing!'       => 'Falta a taxa de câmbio!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'In-line'                     => 'Inline',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Data de Factura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number'              => 'Número de Factura',
+  'Invoice Number missing!'     => 'Número de Factura não encontrado!',
+  'Invoice deleted!'            => 'Factura apagada',
+  'Invoice posted!'             => 'Factura processada',
+  'Item not on file!'           => 'Item não está no arquivo!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta numero na Linha',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Order'                       => 'Encomenda',
+  'Order Date missing!'         => 'Falta data da Encomenda',
+  'Order Number'                => 'Encomenda Número',
+  'Order Number missing!'       => 'Falta numero da Encomenda!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Expedição',
+  'Packing List Date missing!'  => 'Falta Data da Lista de Expedição',
+  'Packing List Number missing!' => 'Falta Numero de Lista de Expedição',
+  'Part'                        => 'Produto',
+  'Payment date missing!'       => 'Falta Data de Pagamento!',
+  'Payments'                    => 'Pagamentos',
+  'Phone'                       => 'Tel',
+  'Post'                        => 'Processar',
+  'Post as new'                 => 'Processar como novo',
+  'Postscript'                  => 'PostScript',
+  'Price'                       => 'Preço',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Projecto',
+  'Project not on file!'        => 'Projecto não existe',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Qty'                         => 'Qtd',
+  'Recd'                        => 'Recebido',
+  'Record in'                   => 'Registar em',
+  'Remaining'                   => 'Sobram',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Encomenda de Venda',
+  'Screen'                      => 'Ecran',
+  'Select from one of the items below' => 'Seleccione um dos items abaixo',
+  'Select from one of the names below' => 'Seleccione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Seleccione um dos projectos abaixo',
+  'Select postscript or PDF!'   => 'Seleccione PostScript ou PDF',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Service'                     => 'Serviço',
+  'Ship'                        => 'Expedir',
+  'Ship to'                     => 'Expedir para',
+  'Ship via'                    => 'Expedir via',
+  'Source'                      => 'Origem',
+  'Subject'                     => 'Assunto',
+  'Subtotal'                    => 'Sub-total',
+  'Tax Included'                => 'Impostos incluídos',
+  'To'                          => 'Até',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidade',
+  'Update'                      => 'Actualizar',
+  'Vendor not on file!'         => 'Fornecedor não existe',
+  'What type of item is this?'  => 'Que tipo de Item é este?',
+  'Yes'                         => 'Sim',
+  'ea'                          => 'cd',
+  'emailed to'                  => 'enviado por email para',
+  'sent to printer'             => 'enviado para a impressora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'remover'                     => 'delete',
+  'e_mail'                      => 'e_mail',
+  'encomenda'                   => 'order',
+  'processar'                   => 'post',
+  'processar_como_novo'         => 'post_as_new',
+  'imprimir'                    => 'print',
+  'expedir_para'                => 'ship_to',
+  'actualizar'                  => 'update',
+  'sim'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/login b/sql-ledger/locale/pt/login
new file mode 100644 (file)
index 0000000..cbe7624
--- /dev/null
@@ -0,0 +1,28 @@
+$self{texts} = {
+  'About'                       => 'Acerca',
+  'Accounting'                  => 'Contabilidade',
+  'Database Host'               => 'Servidor de Base de Dados',
+  'Dataset'                     => 'Dataset',
+  'Incorrect Dataset version!'  => 'Versão Dataset incorrecta!',
+  'Incorrect Password!'         => 'Password Incorrecta!',
+  'Licensed to'                 => 'Licenciado a',
+  'Login'                       => 'Login',
+  'Name'                        => 'Nome',
+  'Password'                    => 'Password',
+  'User'                        => 'Utilizador',
+  'Version'                     => 'Versão',
+  'You are logged out!'         => 'Terminou a sessão!',
+  'You did not enter a name!'   => 'Não indicou nome!',
+  'is not a member!'            => 'não é membro!',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'login'                       => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/menu b/sql-ledger/locale/pt/menu
new file mode 100644 (file)
index 0000000..97b81f7
--- /dev/null
@@ -0,0 +1,72 @@
+$self{texts} = {
+  'AP'                          => 'Fornecedores',
+  'AP Aging'                    => 'Idade Saldos Fornecedores',
+  'AR'                          => 'Clientes',
+  'AR Aging'                    => 'Idade Saldos Clientes',
+  'Accounting Menu'             => 'Menu de Contabilidade',
+  'Add Account'                 => 'Nova Conta',
+  'Add Assembly'                => 'Novo Conjunto',
+  'Add Customer'                => 'Novo Cliente',
+  'Add GIFI'                    => 'Adicionar CFOP',
+  'Add Part'                    => 'Novo Produto',
+  'Add Project'                 => 'Novo Projecto',
+  'Add Service'                 => 'Novo Serviço',
+  'Add Transaction'             => 'Nova Transacção',
+  'Add Vendor'                  => 'Novo Fornecedor',
+  'Assemblies'                  => 'Conjuntos',
+  'Audit Control'               => 'Controlo de Auditoria',
+  'Backup'                      => 'Backup',
+  'Balance Sheet'               => 'Folha de Balanço',
+  'Cash'                        => 'Dinheiro',
+  'Chart of Accounts'           => 'Plano de Contas',
+  'Check'                       => 'Cheque',
+  'Customers'                   => 'Clientes',
+  'General Ledger'              => 'Livro Razão',
+  'Goods & Services'            => 'Bens e Serviços',
+  'HTML Templates'              => 'Templates HTML',
+  'Income Statement'            => 'Estado de Receitas',
+  'Invoice'                     => 'Factura',
+  'LaTeX Templates'             => 'Modelos LaTeX',
+  'List Accounts'               => 'Listar Contas',
+  'List GIFI'                   => 'Listar CFOP',
+  'Logout'                      => 'Logout',
+  'Order Entry'                 => 'Encomendas de Clientes',
+  'Packing List'                => 'Lista de Expedição',
+  'Parts'                       => 'Produtos',
+  'Payment'                     => 'Pagamento',
+  'Payments'                    => 'Pagamentos',
+  'Preferences'                 => 'Preferências',
+  'Projects'                    => 'Projectos',
+  'Purchase Invoice'            => 'Factura de Compra',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Purchase Orders'             => 'Ordens de Compra',
+  'Receipt'                     => 'Recibo',
+  'Receipts'                    => 'Recibos',
+  'Reconciliation'              => 'Reconciliação',
+  'Reports'                     => 'Relatórios',
+  'Sales Invoice'               => 'Factura de Venda',
+  'Sales Order'                 => 'Encomenda de Venda',
+  'Sales Orders'                => 'Encomendas de Venda',
+  'Save to File'                => 'Guardar em Ficheiro',
+  'Send by E-Mail'              => 'Enviar por Email',
+  'Services'                    => 'Serviços',
+  'Statement'                   => 'Statement',
+  'Stock Assembly'              => 'Conjunto em stock',
+  'Stylesheet'                  => 'Stylesheet',
+  'System'                      => 'Sistema',
+  'Tax collected'               => 'Imposto recolhido',
+  'Tax paid'                    => 'Imposto pago',
+  'Transactions'                => 'Transacções',
+  'Trial Balance'               => 'Balancete',
+  'Vendors'                     => 'Fornecedores',
+  'Version'                     => 'Versão',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/oe b/sql-ledger/locale/pt/oe
new file mode 100644 (file)
index 0000000..1be330f
--- /dev/null
@@ -0,0 +1,199 @@
+$self{texts} = {
+  'Add'                         => 'Novo',
+  'Add Purchase Invoice'        => 'Nova Factura de Compra',
+  'Add Purchase Order'          => 'Nova Ordem de Compra',
+  'Add Sales Invoice'           => 'Nova Factura de Venda',
+  'Add Sales Order'             => 'Nova Encomenda de Cliente',
+  'Address'                     => 'Endereço',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Are you sure you want to delete Order Number' => 'Confirma a remoção da Encomenda?',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Não é possivel apagar a encomenda!',
+  'Cannot save order!'          => 'Não é possível guardar encomenda!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Fechado',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Credit Limit'                => 'Limite de Crédito',
+  'Curr'                        => 'Moeda',
+  'Currency'                    => 'Moeda',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Falta cliente!',
+  'Customer not on file!'       => 'Cliente inexistente!',
+  'Date'                        => 'Data',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Delete'                      => 'Remover',
+  'Delivery Date'               => 'Data de entrega',
+  'Description'                 => 'Descrição',
+  'E-mail'                      => 'E-Mail',
+  'E-mail address missing!'     => 'Falta Endereço de E-mail!',
+  'Edit Purchase Order'         => 'Editar Ordem de Compra',
+  'Edit Sales Order'            => 'Editar Encomenda',
+  'Exchangerate'                => 'Taxa de Câmbio',
+  'Exchangerate missing!'       => 'Falta a taxa de câmbio!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Inline',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Data de Factura não encontrada!',
+  'Invoice Number missing!'     => 'Número de Factura não encontrado!',
+  'Item not on file!'           => 'Item não está no arquivo!',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'Name'                        => 'Nome',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notas',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta numero na Linha',
+  'O'                           => 'O',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'Open'                        => 'Abrir',
+  'Order'                       => 'Encomenda',
+  'Order Date'                  => 'Data da Encomenda',
+  'Order Date missing!'         => 'Falta data da Encomenda',
+  'Order Number'                => 'Encomenda Número',
+  'Order Number missing!'       => 'Falta numero da Encomenda!',
+  'Order deleted!'              => 'Encomenda apagada',
+  'Order saved!'                => 'Encomenda guardada',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Expedição',
+  'Packing List Date missing!'  => 'Falta Data da Lista de Expedição',
+  'Packing List Number missing!' => 'Falta Numero de Lista de Expedição',
+  'Part'                        => 'Produto',
+  'Phone'                       => 'Tel',
+  'Postscript'                  => 'PostScript',
+  'Price'                       => 'Preço',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impressora',
+  'Project'                     => 'Projecto',
+  'Project not on file!'        => 'Projecto não existe',
+  'Purchase Order'              => 'Ordem de Compra',
+  'Purchase Orders'             => 'Ordens de Compra',
+  'Qty'                         => 'Qtd',
+  'Recd'                        => 'Recebido',
+  'Remaining'                   => 'Sobram',
+  'Required by'                 => 'Requerido por',
+  'Sales Order'                 => 'Encomenda de Venda',
+  'Sales Orders'                => 'Encomendas de Venda',
+  'Save'                        => 'Guardar',
+  'Save as new'                 => 'Guardar como novo',
+  'Screen'                      => 'Ecran',
+  'Select from one of the items below' => 'Seleccione um dos items abaixo',
+  'Select from one of the names below' => 'Seleccione um dos nomes abaixo',
+  'Select from one of the projects below' => 'Seleccione um dos projectos abaixo',
+  'Select postscript or PDF!'   => 'Seleccione PostScript ou PDF',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Service'                     => 'Serviço',
+  'Ship'                        => 'Expedir',
+  'Ship to'                     => 'Expedir para',
+  'Ship via'                    => 'Expedir via',
+  'Subject'                     => 'Assunto',
+  'Subtotal'                    => 'Sub-total',
+  'Tax'                         => 'Imposto',
+  'Tax Included'                => 'Impostos incluídos',
+  'Terms: Net'                  => 'Termos: A pronto',
+  'To'                          => 'Até',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidade',
+  'Update'                      => 'Actualizar',
+  'Vendor'                      => 'Fornecedor',
+  'Vendor missing!'             => 'Falta fornecedor',
+  'Vendor not on file!'         => 'Fornecedor não existe',
+  'What type of item is this?'  => 'Que tipo de Item é este?',
+  'Yes'                         => 'Sim',
+  'days'                        => 'dias',
+  'ea'                          => 'cd',
+  'emailed to'                  => 'enviado por email para',
+  'sent to printer'             => 'enviado para a impressora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'novo'                        => 'add',
+  'continuar'                   => 'continue',
+  'remover'                     => 'delete',
+  'e_mail'                      => 'e_mail',
+  'factura'                     => 'invoice',
+  'imprimir'                    => 'print',
+  'guardar'                     => 'save',
+  'guardar_como_novo'           => 'save_as_new',
+  'expedir_para'                => 'ship_to',
+  'actualizar'                  => 'update',
+  'sim'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/pe b/sql-ledger/locale/pt/pe
new file mode 100644 (file)
index 0000000..fc71393
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Novo',
+  'Add Project'                 => 'Novo Projecto',
+  'All'                         => 'Todos',
+  'Continue'                    => 'Continuar',
+  'Delete'                      => 'Remover',
+  'Description'                 => 'Descrição',
+  'Edit Project'                => 'Editar Projecto',
+  'Number'                      => 'Número',
+  'Orphaned'                    => 'Órfão',
+  'Project'                     => 'Projecto',
+  'Project Number missing!'     => 'Falta o número do projecto',
+  'Project deleted!'            => 'Projecto apagado',
+  'Project saved!'              => 'Projecto guardado',
+  'Projects'                    => 'Projectos',
+  'Save'                        => 'Guardar',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'novo'                        => 'add',
+  'continuar'                   => 'continue',
+  'remover'                     => 'delete',
+  'guardar'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/rc b/sql-ledger/locale/pt/rc
new file mode 100644 (file)
index 0000000..28c8216
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Conta',
+  'Balance'                     => 'Saldo',
+  'Cleared Balance'             => 'Cleared Balance',
+  'Continue'                    => 'Continuar',
+  'Date'                        => 'Data',
+  'Deposit'                     => 'Depósito',
+  'Description'                 => 'Descrição',
+  'Difference'                  => 'Diferença',
+  'Done'                        => 'Pronto',
+  'Exchangerate Difference'     => 'Diferença na Taxa de Câmbio',
+  'From'                        => 'De',
+  'Out of balance!'             => 'Out of balance!',
+  'Payment'                     => 'Pagamento',
+  'Reconciliation'              => 'Reconciliação',
+  'Select all'                  => 'Seleccionar todos',
+  'Source'                      => 'Origem',
+  'Statement Balance'           => 'Statement Balance',
+  'To'                          => 'Até',
+  'Update'                      => 'Actualizar',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'continuar'                   => 'continue',
+  'pronto'                      => 'done',
+  'seleccionar_todos'           => 'select_all',
+  'actualizar'                  => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/pt/rp b/sql-ledger/locale/pt/rp
new file mode 100644 (file)
index 0000000..c452e9c
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'Idade Saldos Fornecedores',
+  'AR Aging'                    => 'Idade Saldos Clientes',
+  'Account'                     => 'Conta',
+  'Accounts'                    => 'Contas',
+  'Amount'                      => 'Total',
+  'Apr'                         => 'Abr',
+  'April'                       => 'Abril',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Ago',
+  'August'                      => 'Agosto',
+  'Balance Sheet'               => 'Folha de Balanço',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Cash based',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Comparar com',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Cópias',
+  'Credit'                      => 'Crédito',
+  'Current'                     => 'Current',
+  'Customer'                    => 'Cliente',
+  'Date'                        => 'Data',
+  'Debit'                       => 'Débito',
+  'Dec'                         => 'Dez',
+  'December'                    => 'Dezembro',
+  'Decimalplaces'               => 'Casas decimais',
+  'Description'                 => 'Descrição',
+  'Due'                         => 'Vence',
+  'E-mail'                      => 'E-Mail',
+  'E-mail Statement to'         => 'E-mail Statement to',
+  'Feb'                         => 'Fev',
+  'February'                    => 'Fevereiro',
+  'From'                        => 'De',
+  'GIFI'                        => 'CFOP - Código Fiscal da Operação',
+  'Heading'                     => 'Cabeçalho',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Inline',
+  'Include in Report'           => 'Incluir no Relatório',
+  'Income Statement'            => 'Estado de Receitas',
+  'Invoice'                     => 'Factura',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Janeiro',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Julho',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Junho',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Março',
+  'May'                         => 'Mai',
+  'May '                        => 'Maio',
+  'Message'                     => 'Mensagem',
+  'N/A'                         => 'N/D',
+  'Nothing selected!'           => 'Nada seleccionado',
+  'Nov'                         => 'Nov',
+  'November'                    => 'Novembro',
+  'Oct'                         => 'Out',
+  'October'                     => 'Outubro',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Pagamentos',
+  'Postscript'                  => 'PostScript',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impressora',
+  'Receipts'                    => 'Recibos',
+  'Report for'                  => 'Relatório para',
+  'Retained Earnings'           => 'Lucros Retidos',
+  'Screen'                      => 'Ecran',
+  'Select all'                  => 'Seleccionar todos',
+  'Select postscript or PDF!'   => 'Seleccione PostScript ou PDF',
+  'Sep'                         => 'Set',
+  'September'                   => 'Setembro',
+  'Source'                      => 'Origem',
+  'Standard'                    => 'Padrão',
+  'Statement'                   => 'Statement',
+  'Statement sent to'           => 'Statement sent to',
+  'Statements sent to printer!' => 'Statements sent to printer!',
+  'Subject'                     => 'Assunto',
+  'Subtotal'                    => 'Sub-total',
+  'Tax'                         => 'Imposto',
+  'Tax collected'               => 'Imposto recolhido',
+  'Tax paid'                    => 'Imposto pago',
+  'To'                          => 'Até',
+  'Total'                       => 'Total',
+  'Trial Balance'               => 'Balancete',
+  'Vendor'                      => 'Fornecedor',
+  'as at'                       => 'as at',
+  'collected on sales'          => 'recolhido sobre vendas',
+  'for Period'                  => 'pelo período',
+  'paid on purchases'           => 'pago em aquisições',
+  'to'                          => 'para',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'continuar'                   => 'continue',
+  'e_mail'                      => 'e_mail',
+  'imprimir'                    => 'print',
+  'seleccionar_todos'           => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/COPYING b/sql-ledger/locale/ru/COPYING
new file mode 100644 (file)
index 0000000..411c170
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2002
+#
+# Russian texts:
+#
+#  Author:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/ru/LANGUAGE b/sql-ledger/locale/ru/LANGUAGE
new file mode 100644 (file)
index 0000000..64c9578
--- /dev/null
@@ -0,0 +1 @@
+Russian
diff --git a/sql-ledger/locale/ru/admin b/sql-ledger/locale/ru/admin
new file mode 100644 (file)
index 0000000..3f10bcf
--- /dev/null
@@ -0,0 +1,122 @@
+$self{texts} = {
+  'Access Control'              => 'ëÏÎÔÒÏÌØ ÄÏÓÔÕÐÁ',
+  'Accounting'                  => 'Accounting',
+  'Add User'                    => 'îÏ×ÙÊ ÐÏÌØÚÏ×ÁÔÅÌØ',
+  'Address'                     => 'áÄÒÅÓ',
+  'Administration'              => 'áÄÍÉÎÉÓÔÒÉÒÏ×ÁÎÉÅ',
+  'Administrator'               => 'Administrator',
+  'All Datasets up to date!'    => 'All Datasets up to date!',
+  'Change Admin Password'       => 'éÚÍÅÎÉÔØ ÐÁÒÏÌØ áÄÍÉÎÉÓÔÒÁÔÏÒÁ',
+  'Change Password'             => 'éÚÍÅÎÉÔØ ÐÁÒÏÌØ',
+  'Character Set'               => 'ëÏÄÉÒÏ×ËÁ',
+  'Click on login name to edit!' => 'Kliknij  nazwê u¿ytkownika ¿eby dokonaæ zmian',
+  'Company'                     => 'ïÒÇÁÎÉÚÁÃÉÑ',
+  'Connect to'                  => 'ðÏÄËÌÀÞÉÔØÓÑ Ë',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Create Chart of Accounts'    => 'óÏÚÄÁÔØ çðó',
+  'Create Dataset'              => 'Utwórz Zbiór Danych',
+  'DBI not installed!'          => 'îÅ ÕÓÔÁÎÏ×ÌÅΠÄÒÁÊ×ÅÒ DBI!',
+  'Database'                    => 'âÁÚÁ ÄÁÎÎÙÈ',
+  'Database Administration'     => 'áÄÍÉÎÉÓÔÒÉÒÏ×ÁÎÉÅ ÂÁÚÙ ÄÁÎÎÙÈ',
+  'Database Driver not checked!' => 'Sterownik Bazy Danych nie zaznaczony!',
+  'Database User missing!'      => 'Brak U¿ytkownika Bazy Danych!',
+  'Dataset'                     => 'Zbiór Danych',
+  'Dataset missing!'            => 'Brak Zbioru Danych',
+  'Dataset updated!'            => 'Dataset updated!',
+  'Date Format'                 => 'æÏÒÍÁÔ ÄÁÔÙ',
+  'Delete'                      => 'õÄÁÌÉÔØ',
+  'Delete Dataset'              => 'Usuñ Zbior Danych',
+  'Directory'                   => 'ëÁÔÁÌÏÇ',
+  'Driver'                      => 'Sterownik',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'E-mail',
+  'Edit User'                   => 'Zmiany U¿ytkownika',
+  'Existing Datasets'           => 'Istniej±cy Zbiór Danych',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Wêze³',
+  'Hostname missing!'           => 'Brak Nazwy Wêz³a',
+  'Incorrect Password!'         => 'Nieprawid³owe Has³o',
+  'Language'                    => 'ñÚÙË',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Opu¶æ pole wêz³a i portu, chyba ¿e chcesz mieæ zdalne po³±czenie',
+  'Login'                       => 'Zarejestrój siê',
+  'Name'                        => 'Nazwa',
+  'New Templates'               => 'Nowe Szablony',
+  'No Database Drivers available!' => 'Sterownik Bazy Danych jest niedostêpny',
+  'No Dataset selected!'        => 'Nie jest zaznaczony Zbiór Danych',
+  'Nothing to delete!'          => 'Niema nic do usuniêcia!',
+  'Number Format'               => 'Format Numeru',
+  'Oracle Database Administration' => 'Administracja Bazy Danych Oracle',
+  'Password'                    => 'Has³o',
+  'Password changed!'           => 'Password changed!',
+  'Pg Database Administration'  => 'Administracja Bazy Danych Pg',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Brak Portu',
+  'Printer'                     => 'Drukarka',
+  'Save'                        => 'Zapisz',
+  'Select a Dataset to delete and press "Continue"' => 'Wybierz Zbiór Danych do usuniêcia i naci¶nij "Kontynuj"',
+  'Setup Templates'             => 'Ustaw Szablony',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'ðÏÄÐÉÓØ',
+  'Stylesheet'                  => 'ïÆÏÒÍÌÅÎÉÅ',
+  'Templates'                   => 'æÏÒÍÙ',
+  'The following Datasets are not in use and can be deleted' => 'Te Zbiory Danych s± nieu¿ywane i mo¿na je usun±æ',
+  'The following Datasets need to be updated' => 'Zbiory Danych do uzupe³nienia',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Jest to wstêpne sprawdzenie istniej±cych ¿róde³. Narazie nic nie bêdzie utworzone lub usuniête.',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => '¯eby dodaæ do grupy u¿ytkownika zmieñ nazwê, nazwê zarejestrowania i zapisz. Nowy u¿ytkownik z tymi samymi zmiennymi warto¶ciami bêdzie zapisany pod now± nazw± rejestruj±c±',
+  'Update Dataset'              => 'Uzupe³nij Zbiór Danych',
+  'Use Templates'               => 'U¿yj Szablony',
+  'User'                        => 'U¿ytkownik',
+  'User deleted!'               => 'User deleted!',
+  'User saved!'                 => 'User saved!',
+  'Version'                     => '÷ÅÒÓÉÑ',
+  'You must enter a host and port for local and remote connections!' => 'Wstaw wêze³ i port dla lokalnego i zdalnego po³±czenia',
+  'does not exist'              => 'nie istnieje',
+  'is already a member!'        => 'Jest ju¿ cz³onkiem',
+  'localhost'                   => 'wêze³',
+  'successfully created!'       => 'stworzone z powodzeniem',
+  'successfully deleted!'       => 'usuniête z powodzeniem',
+  'website'                     => 'witryna WWW',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'îÏ×ÙÊ_ÐÏÌØÚÏ×ÁÔÅÌØ'          => 'add_user',
+  'éÚÍÅÎÉÔØ_ÐÁÒÏÌØ_áÄÍÉÎÉÓÔÒÁÔÏÒÁ' => 'change_admin_password',
+  'éÚÍÅÎÉÔØ_ÐÁÒÏÌØ'             => 'change_password',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'utwórz_zbiór_danych'         => 'create_dataset',
+  'õÄÁÌÉÔØ'                     => 'delete',
+  'usuñ_zbior_danych'           => 'delete_dataset',
+  'zarejestrój_siê'             => 'login',
+  'administracja_bazy_danych_oracle' => 'oracle_database_administration',
+  'administracja_bazy_danych_pg' => 'pg_database_administration',
+  'zapisz'                      => 'save',
+  'uzupe³nij_zbiór_danych'      => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/all b/sql-ledger/locale/ru/all
new file mode 100644 (file)
index 0000000..a87eee9
--- /dev/null
@@ -0,0 +1,487 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'òÁÓÈÏÄ',
+  'AP Aging'                    => 'AP Aging',
+  'AP Transaction'              => '',
+  'AP Transactions'             => 'ðÒÏ×ÏÄËÉ ÒÁÓÈÏÄÁ',
+  'AR'                          => 'äÏÈÏÄ',
+  'AR Aging'                    => 'AR Aging',
+  'AR Transaction'              => '',
+  'AR Transactions'             => 'ðÒÏ×ÏÄËÉ ÄÏÈÏÄÁ',
+  'About'                       => 'ï ÐÒÏÇÒÁÍÍÅ',
+  'Access Control'              => 'ëÏÎÔÒÏÌØ ÄÏÓÔÕÐÁ',
+  'Account'                     => 'óÞÅÔ',
+  'Account Number'              => 'ëÏÄ ÓÞÅÔÁ',
+  'Account Number missing!'     => 'îÅ ÕËÁÚÁΠÎÏÍÅÒ ÓÞÅÔÁ!',
+  'Account Type'                => 'ôÉРÓÞÅÔÁ',
+  'Account Type missing!'       => 'îÅ ÕËÁÚÁΠÔÉРÓÞÅÔÁ!',
+  'Account deleted!'            => '',
+  'Account saved!'              => '',
+  'Accounting'                  => 'Accounting',
+  'Accounting Menu'             => 'Accounting Menu',
+  'Accounts'                    => 'óÞÅÔÁ',
+  'Active'                      => '',
+  'Add'                         => 'îÏ×ÙÊ',
+  'Add Account'                 => 'îÏ×ÙÊ ÓÞÅÔ',
+  'Add Accounts Payables Transaction' => '',
+  'Add Accounts Receivables Transaction' => '',
+  'Add Assembly'                => 'îÏ×ÙÊ ËÏÍÐÌÅËÔ',
+  'Add Customer'                => 'îÏ×ÙÊ ËÌÉÅÎÔ',
+  'Add GIFI'                    => 'îÏ×ÙÊ GIFI',
+  'Add General Ledger Transaction' => 'îÏ×ÁÑ ÐÒÏ×ÏÄËÁ',
+  'Add Part'                    => 'îÏ×ÙÊ ÐÒÏÄÕËÔ',
+  'Add Project'                 => '',
+  'Add Purchase Invoice'        => '',
+  'Add Purchase Order'          => 'îÏ×ÙÊ ÚÁËÁÚ ÐÏÓÔÁ×ÝÉËÁ',
+  'Add Sales Invoice'           => '',
+  'Add Sales Order'             => 'îÏ×ÙÊ ÚÁËÁÚ ËÌÉÅÎÔÁ',
+  'Add Service'                 => 'îÏ×ÁÑ ÕÓÌÕÇÁ',
+  'Add Transaction'             => 'îÏ×ÁÑ ÐÒÏ×ÏÄËÁ',
+  'Add User'                    => 'îÏ×ÙÊ ÐÏÌØÚÏ×ÁÔÅÌØ',
+  'Add Vendor'                  => 'îÏ×ÙÊ ÐÏÓÔÁ×ÝÉË',
+  'Address'                     => 'áÄÒÅÓ',
+  'Administration'              => 'áÄÍÉÎÉÓÔÒÉÒÏ×ÁÎÉÅ',
+  'Administrator'               => '',
+  'All'                         => '÷ÓÅ',
+  'All Datasets up to date!'    => 'All Datasets up to date!',
+  'Amount'                      => 'óÕÍÍÁ',
+  'Amount Due'                  => '',
+  'Amount does not equal applied!' => '',
+  'Amount missing!'             => '',
+  'Applied'                     => '',
+  'Apr'                         => 'áÐÒ',
+  'April'                       => 'áÐÒÅÌØ',
+  'Are you sure you want to delete Invoice Number' => '÷Ù Õ×ÅÒÅÎÙ, ÞÔÏ ÈÏÔÉÔÅ ÕÄÁÌÉÔØ ÄÁÎÎÙÊ ÓÞÅÔ?',
+  'Are you sure you want to delete Order Number' => '÷Ù Õ×ÅÒÅÎÙ, ÞÔÏ ÈÏÔÉÔÅ ÕÄÁÌÉÔØ ÄÁÎÎÙÊ ÚÁËÁÚ?',
+  'Are you sure you want to delete Transaction' => '÷Ù Õ×ÅÒÅÎÙ, ÓÔÏ ÈÏÔÉÔÅ ÕÄÁÌÉÔØ ÄÁÎÎÕÀ ÐÒÏ×ÏÄËÕ?',
+  'Assemblies'                  => 'ëÏÍÐÌÅËÔÙ',
+  'Assemblies restocked!'       => '',
+  'Assembly Number missing!'    => 'îÅ ÕËÁÚÁΠÎÏÍÅÒ ËÏÍÐÌÅËÔÁ!',
+  'Asset'                       => 'áËÔÉ×',
+  'Attachment'                  => '÷ÌÏÖÅÎÉÅ',
+  'Audit Control'               => 'ëÏÎÔÒÏÌØ',
+  'Aug'                         => 'á×Ç',
+  'August'                      => 'á×ÇÕÓÔ',
+  'BOM'                         => '',
+  'Backup'                      => 'òÅÚÅÒ×ÎÁÑ ËÏÐÉÑ',
+  'Backup sent to'              => 'òÅÚÅÒ×ÎÁÑ ËÏÐÉÑ ÏÔÏÓÌÁÎÁ ÎÁ',
+  'Balance'                     => '',
+  'Balance Sheet'               => 'âÁÌÁÎÓ',
+  'Bcc'                         => '',
+  'Bin'                         => 'Bin',
+  'Books are open'              => 'ëÎÉÇÁ ÏÔËÒÙÔÁ',
+  'Bought'                      => 'ëÕÐÌÅÎÏ',
+  'Business Number'             => 'òîî',
+  'C'                           => '',
+  'COGS'                        => 'COGS',
+  'Cannot delete account!'      => '',
+  'Cannot delete customer!'     => '',
+  'Cannot delete default account!' => 'îÅÌØÚÑ ÕÄÁÌÉÔØ ÏÓÎÏ×ÎÏÊ ÓÞÅÔ!',
+  'Cannot delete invoice!'      => '',
+  'Cannot delete item already invoiced!' => 'Nie mo¿na usun±æ pozycji zafakturowanej!',
+  'Cannot delete item on order!' => 'Nie mo¿na usunac zamówionego produktu!',
+  'Cannot delete item which is part of an assembly!' => 'Nie mo¿na usun±æ czê¶ci z zestawienia!',
+  'Cannot delete item!'         => '',
+  'Cannot delete order!'        => '',
+  'Cannot delete transaction!'  => '',
+  'Cannot delete vendor!'       => '',
+  'Cannot have a value in both Debit and Credit!' => 'Nie mo¿na wpisaæ warto¶ci w Debet i Kredyt równocze¶nie!',
+  'Cannot post a transaction without a value!' => '',
+  'Cannot post invoice for a closed period!' => 'Nie mo¿na zksiêgowaæ faktury pozamkniêciu okresu',
+  'Cannot post invoice!'        => '',
+  'Cannot post payment for a closed period!' => 'Nie mo¿na zaksiêgowaæ p³atno¶ci po zamkniêciu okresu!',
+  'Cannot post payment!'        => '',
+  'Cannot post transaction for a closed period!' => 'Nie mo¿na zaksiêgowaæ transakcji w zamkniêtym okresie',
+  'Cannot post transaction!'    => '',
+  'Cannot process payment for a closed period!' => '',
+  'Cannot save account!'        => '',
+  'Cannot save order!'          => '',
+  'Cannot save preferences!'    => '',
+  'Cannot stock assemblies!'    => '',
+  'Cash'                        => '',
+  'Cash based'                  => '',
+  'Cc'                          => '',
+  'Change Admin Password'       => 'éÚÍÅÎÉÔØ ÐÁÒÏÌØ áÄÍÉÎÉÓÔÒÁÔÏÒÁ',
+  'Change Password'             => 'éÚÍÅÎÉÔØ ÐÁÒÏÌØ',
+  'Character Set'               => 'ëÏÄÉÒÏ×ËÁ',
+  'Chart of Accounts'           => 'ðÌÁΠÓÞÅÔÏ×',
+  'Check'                       => '',
+  'Check printed!'              => '',
+  'Check printing failed!'      => '',
+  'Cleared Balance'             => '',
+  'Click on login name to edit!' => 'Kliknij  nazwê u¿ytkownika ¿eby dokonaæ zmian',
+  'Close Books up to'           => 'Zamkniêcie Ksi±g do!',
+  'Closed'                      => 'úÁËÒÙÔ',
+  'Company'                     => 'ïÒÇÁÎÉÚÁÃÉÑ',
+  'Compare to'                  => 'óÒÁ×ÎÉÔØ Ó',
+  'Confirm!'                    => 'ðÏÄÔ×ÅÒÄÉÔØ!',
+  'Connect to'                  => 'ðÏÄËÌÀÞÉÔØÓÑ Ë',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÏÅ ÌÉÃÏ',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Copies'                      => 'ëÏÐÉÊ',
+  'Copy to COA'                 => 'ëÏÐÉÒÏ×ÁÔØ × çðó',
+  'Create Chart of Accounts'    => 'óÏÚÄÁÔØ çðó',
+  'Create Dataset'              => 'Utwórz Zbiór Danych',
+  'Credit'                      => 'ëÒÅÄÉÔ',
+  'Credit Limit'                => 'ìÉÍÉÔ ËÒÅÄÉÔÁ',
+  'Curr'                        => '÷ÁÌÀÔÁ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Current'                     => '',
+  'Customer'                    => 'ëÌÉÅÎÔ',
+  'Customer deleted!'           => '',
+  'Customer missing!'           => '',
+  'Customer not on file!'       => '',
+  'Customer saved!'             => '',
+  'Customers'                   => '',
+  'DBI not installed!'          => 'îÅ ÕÓÔÁÎÏ×ÌÅΠÄÒÁÊ×ÅÒ DBI!',
+  'Database'                    => 'âÁÚÁ ÄÁÎÎÙÈ',
+  'Database Administration'     => 'áÄÍÉÎÉÓÔÒÉÒÏ×ÁÎÉÅ ÂÁÚÙ ÄÁÎÎÙÈ',
+  'Database Driver not checked!' => 'Sterownik Bazy Danych nie zaznaczony!',
+  'Database Host'               => 'Wêze³ Bazy Danych',
+  'Database User missing!'      => 'Brak U¿ytkownika Bazy Danych!',
+  'Dataset'                     => 'Zbiór Danych',
+  'Dataset missing!'            => 'Brak Zbioru Danych',
+  'Dataset updated!'            => '',
+  'Date'                        => 'äÁÔÁ',
+  'Date Due'                    => 'ïÐÌÁÔÉÔØ ÄÏ',
+  'Date Format'                 => 'æÏÒÍÁÔ ÄÁÔÙ',
+  'Date Paid'                   => 'äÁÔÁ ÏÐÌÁÔÙ',
+  'Date missing!'               => '',
+  'Debit'                       => 'äÅÂÅÔ',
+  'Debit and credit out of balance!' => 'Debet i Kredyt siê niebalansuj±!',
+  'Dec'                         => 'äÅË',
+  'December'                    => 'äÅËÁÂÒØ',
+  'Decimalplaces'               => '',
+  'Delete'                      => 'õÄÁÌÉÔØ',
+  'Delete Account'              => 'õÄÁÌÍÔØ ÓÞÅÔ',
+  'Delete Dataset'              => 'Usuñ Zbior Danych',
+  'Delivery Date'               => '',
+  'Deposit'                     => '',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'Difference'                  => '',
+  'Directory'                   => 'ëÁÔÁÌÏÇ',
+  'Discount'                    => 'óËÉÄËÁ',
+  'Done'                        => '',
+  'Drawing'                     => '',
+  'Driver'                      => 'Sterownik',
+  'Dropdown Limit'              => '',
+  'Due'                         => 'äÏ',
+  'Due Date'                    => 'ïÐÌÁÔÉÔØ ÄÏ',
+  'Due Date missing!'           => 'îÅ ÕËÁÚÁΠÓÒÏË ÏÐÌÁÔÙ!',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => '',
+  'E-mail address missing!'     => 'îÅ ÕËÁÚÁΠÁÄÒÅÓ E-mail!',
+  'Edit'                        => '',
+  'Edit Account'                => 'éÚÍÅÎÉÔØ ÓÞÅÔ',
+  'Edit Accounts Payables Transaction' => '',
+  'Edit Accounts Receivables Transaction' => '',
+  'Edit Assembly'               => 'éÚÍÅÎÉÔØ ËÏÍÐÌÅËÔ',
+  'Edit GIFI'                   => 'éÚÍÅÎÉÔØ GIFI',
+  'Edit General Ledger Transaction' => 'Zmiany w Ksiêdze G³ównej',
+  'Edit Part'                   => 'Zmiany Produktu',
+  'Edit Preferences for'        => 'Zmiany Preferencji dla',
+  'Edit Project'                => '',
+  'Edit Purchase Invoice'       => '',
+  'Edit Purchase Order'         => 'Zmiany Zamówienia Zakupu',
+  'Edit Sales Invoice'          => '',
+  'Edit Sales Order'            => 'Zmiany Zamówienia Klienta',
+  'Edit Service'                => 'éÚÍÅÎÉÔØ ÕÓÌÕÇÕ',
+  'Edit Template'               => 'Zmiany Wzorca',
+  'Edit User'                   => 'Zmiany U¿ytkownika',
+  'Employee'                    => '',
+  'Enforce transaction reversal for all dates' => 'Egzekwuj zmiany transakcji dla wszystkich terminów',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => '',
+  'Equity'                      => 'Kapita³',
+  'Exch'                        => 'Kurs',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'Exchangerate Difference'     => '',
+  'Exchangerate for payment missing!' => 'Brakuje kursu wymiany dla p³atno¶ci!',
+  'Exchangerate missing!'       => 'Brakuje kursu wymiany',
+  'Existing Datasets'           => 'Istniej±cy Zbiór Danych',
+  'Expense'                     => 'òÁÓÈÏÄ',
+  'Expense Account'             => 'Konto Kosztów',
+  'Expense/Asset'               => 'Koszt/Aktywy',
+  'Extended'                    => '',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'Foreign Exchange Gain'       => 'Zysk przy Wymianie Walut',
+  'Foreign Exchange Loss'       => 'Strata przy Wymianie Walut',
+  'From'                        => 'Od',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => '',
+  'GIFI missing!'               => 'Brakuje GIFI',
+  'GIFI saved!'                 => '',
+  'GL Transaction'              => '',
+  'General Ledger'              => 'Ksiêga G³ówna',
+  'Goods & Services'            => 'Produkty i Us³ugi',
+  'HTML Templates'              => 'Szablony HTML',
+  'Heading'                     => 'òÁÚÄÅÌ',
+  'Host'                        => 'Wêze³',
+  'Hostname missing!'           => 'Brak Nazwy Wêz³a',
+  'ID'                          => 'Identyfikator',
+  'Image'                       => '',
+  'In-line'                     => 'W³±czony',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Include in drop-down menus'  => 'Do³±cz w menu rozwijanym',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Do³±cz Konto w formularzach Kontrachentów ¿eby wskazaæ ¿e podlegaj± opodatkowaniu',
+  'Income'                      => 'äÏÈÏÄ',
+  'Income Account'              => 'Konto Przychodów',
+  'Income Statement'            => 'Rachunek Zysków i Strat',
+  'Incorrect Dataset version!'  => 'Nieprawid³owa wersja Zbioru Danych',
+  'Incorrect Password!'         => 'Nieprawid³owe Has³o',
+  'Individual Items'            => 'Indywidualne Czê¶ci',
+  'Inventory'                   => 'éÎ×ÅÎÔÁÒÎÙÊ',
+  'Inventory Account'           => 'Konto Materia³owe',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Ilo¶æ Inventarza musi byæ równa zero zanim bêdzie mozna zdezaktualizowaæ to z³o¿enie!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Ilo¶æ inventarza musi byæ równa zero zanim bêdzie mo¿na zdezaktualizowaæ t± czê¶æ!',
+  'Inventory quantity must be zero!' => 'Ilo¶æc Inventarza musi byæ równa zero',
+  'Invoice'                     => 'óÞÅÔ-ÆÁËÔÕÒÁ',
+  'Invoice Date'                => 'äÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ',
+  'Invoice Date missing!'       => 'îÅ ÕËÁÚÁÎÁ ÄÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number'              => 'îÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number missing!'     => 'îÅ ÕËÁÚÁΠÎÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice deleted!'            => '',
+  'Invoice posted!'             => '',
+  'Invoices'                    => '',
+  'Is this a summary account to record' => 'Czy jest to konto sumaryczne?',
+  'Item deleted!'               => '',
+  'Item not on file!'           => 'Produkt nie jest w zbiorze!',
+  'Jan'                         => 'ñÎ×',
+  'January'                     => 'ñÎ×ÁÒØ',
+  'Jul'                         => 'éÀÌ',
+  'July'                        => 'éÀÌØ',
+  'Jun'                         => 'éÀÎ',
+  'June'                        => 'éÀÎØ',
+  'LaTeX Templates'             => 'Szablony LaTeX',
+  'Language'                    => 'ñÚÙË',
+  'Last Cost'                   => 'Cena Zakupu',
+  'Last Invoice Number'         => 'Ostatni Numer Faktury',
+  'Last Numbers & Default Accounts' => 'Ostatnie Numery i Konta Domy¶lne',
+  'Last Purchase Order Number'  => 'Ostatni Numer Faktury Zamówienia',
+  'Last Sales Order Number'     => 'Ostatni Numer Faktury Sprzeda¿y',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Opu¶æ pole wêz³a i portu, chyba ¿e chcesz mieæ zdalne po³±czenie',
+  'Liability'                   => 'ðÁÓÓÉ×',
+  'Licensed to'                 => 'ìÉÃÅÎÚÉÅÊ ÏÂÌÁÄÁÅÔ:',
+  'Line Total'                  => 'Suma ca³kowita',
+  'Link'                        => 'Dowi±zanie',
+  'Link Accounts'               => 'Konta dowi±zane',
+  'List Accounts'               => 'Spis Kont',
+  'List GIFI'                   => 'Wykaz GIFI',
+  'List Price'                  => 'Cena',
+  'List Transactions'           => 'Wykaz Transakcji',
+  'Login'                       => 'Zarejestrój siê',
+  'Logout'                      => 'Wyrejestrój siê',
+  'Make'                        => 'Marka',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'Microfiche'                  => '',
+  'Model'                       => 'Model',
+  'N/A'                         => 'N/A',
+  'Name'                        => 'Nazwa',
+  'Name missing!'               => '',
+  'New Templates'               => 'Nowe Szablony',
+  'No'                          => 'Nie',
+  'No Database Drivers available!' => 'Sterownik Bazy Danych jest niedostêpny',
+  'No Dataset selected!'        => 'Nie jest zaznaczony Zbiór Danych',
+  'No email address for'        => 'Brak adresu email',
+  'No.'                         => '',
+  'Notes'                       => 'Noty',
+  'Nothing applied!'            => '',
+  'Nothing selected!'           => '',
+  'Nothing to delete!'          => 'Niema nic do usuniêcia!',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Number Format'               => 'Format Numeru',
+  'Number missing in Row'       => 'Brak Numeru w Rzêdzie',
+  'O'                           => '',
+  'Obsolete'                    => 'Zdezaktualizowany',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'On Hand'                     => 'Na Stanie',
+  'On Order'                    => '',
+  'Open'                        => 'Otwórz',
+  'Oracle Database Administration' => 'Administracja Bazy Danych Oracle',
+  'Order'                       => 'Zamówienie',
+  'Order Date'                  => 'Data Zamówienia',
+  'Order Date missing!'         => 'Brak Daty Zamówienia',
+  'Order Entry'                 => 'Wystawianie Zamówieñ',
+  'Order Number'                => 'Numer Zamówienia',
+  'Order Number missing!'       => 'Brak Numeru Zamówienia',
+  'Order deleted!'              => '',
+  'Order saved!'                => '',
+  'Ordered'                     => '',
+  'Orphaned'                    => 'Zbêdny',
+  'Out of balance!'             => '',
+  'PDF'                         => '',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Packing List Date missing!'  => 'Brak Daty Wykazu Dostawy',
+  'Packing List Number missing!' => 'Brak Numeru Wykazu Dostawy',
+  'Paid'                        => 'Zap³acono',
+  'Paid in full'                => '',
+  'Part'                        => 'Produkt',
+  'Part Number missing!'        => 'Brak Symbolu Produktu!',
+  'Parts'                       => 'Produkty',
+  'Parts Inventory'             => 'Inwentarz',
+  'Password'                    => 'Has³o',
+  'Password changed!'           => '',
+  'Payables'                    => 'Zobowi±zania',
+  'Payment'                     => 'P³atno¶æ',
+  'Payment date missing!'       => 'Brak Daty P³atno¶ci',
+  'Payment posted!'             => '',
+  'Payments'                    => 'Rozliczenia P³atno¶ci',
+  'Pg Database Administration'  => 'Administracja Bazy Danych Pg',
+  'Phone'                       => 'Tel.',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Brak Portu',
+  'Post'                        => '',
+  'Post as new'                 => '',
+  'Postscript'                  => '',
+  'Preferences'                 => 'Preferencje',
+  'Preferences saved!'          => 'Preferencje Zapisane!',
+  'Price'                       => 'Cena Netto',
+  'Print'                       => '',
+  'Printer'                     => 'Drukarka',
+  'Project'                     => '',
+  'Project Number missing!'     => '',
+  'Project deleted!'            => '',
+  'Project not on file!'        => '',
+  'Project saved!'              => '',
+  'Projects'                    => '',
+  'Purchase Invoice'            => '',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Purchase Orders'             => 'Zamówienia Zakupu',
+  'Qty'                         => 'Ilo¶æ',
+  'ROP'                         => 'PPZ',
+  'Rate'                        => 'Stawka',
+  'Recd'                        => '',
+  'Receipt'                     => '',
+  'Receipts'                    => '',
+  'Receivables'                 => 'Nale¿no¶ci',
+  'Reconciliation'              => '',
+  'Record in'                   => 'ïÔÎÅÓÔÉ ÎÁ ÓÞÅÔ',
+  'Reference'                   => '',
+  'Reference missing!'          => '',
+  'Remaining'                   => 'Pozosta³e',
+  'Report for'                  => 'Raport dla',
+  'Reports'                     => 'Sprawozdania',
+  'Required by'                 => 'Termin Dostawy',
+  'Retained Earnings'           => 'Zysk',
+  'Sales'                       => 'Sprzeda¿',
+  'Sales Invoice'               => '',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Sales Orders'                => 'Zamówienia Klientów',
+  'Save'                        => 'Zapisz',
+  'Save as new'                 => '',
+  'Save to File'                => 'Zapisz w zbiorze',
+  'Screen'                      => 'Ekran',
+  'Select a Dataset to delete and press "Continue"' => 'Wybierz Zbiór Danych do usuniêcia i naci¶nij "Kontynuj"',
+  'Select all'                  => '',
+  'Select from one of the items below' => 'Wybie¿ jeden z poni¿szych artyku³ów',
+  'Select from one of the names below' => '',
+  'Select from one of the projects below' => '',
+  'Select postscript or PDF!'   => '',
+  'Sell Price'                  => 'Cena Sprzeda¿y',
+  'Send by E-Mail'              => 'Wys³ano przy u¿yciu E-Mail',
+  'Sep'                         => 'óÅÎ',
+  'September'                   => 'óÅÎÔÑÂÒØ',
+  'Service'                     => 'õÓÌÕÇÁ',
+  'Service Items'               => 'Artyku³y Us³ugowe',
+  'Service Number missing!'     => 'Brak Numeru Us³ugi!',
+  'Services'                    => 'õÓÌÕÇÉ',
+  'Setup Templates'             => 'Ustaw Szablony',
+  'Ship'                        => '',
+  'Ship to'                     => '',
+  'Ship via'                    => '',
+  'Short'                       => 'Niedobór',
+  'Signature'                   => 'ðÏÄÐÉÓØ',
+  'Sold'                        => 'Sprzedano',
+  'Source'                      => '¯ród³o',
+  'Standard'                    => 'óÔÁÎÄÁÒÔÎÙÅ',
+  'Statement'                   => '',
+  'Statement Balance'           => '',
+  'Statement sent to'           => '',
+  'Statements sent to printer!' => '',
+  'Stock Assembly'              => 'Wstaw Z³o¿enie',
+  'Stylesheet'                  => 'ïÆÏÒÍÌÅÎÉÅ',
+  'Subject'                     => 'ôÅÍÁ',
+  'Subtotal'                    => 'éÔÏÇÏ ÐÏ ÒÁÚÄÅÌÕ',
+  'System'                      => 'óÉÓÔÅÍÁ',
+  'Tax'                         => 'îÁÌÏÇ',
+  'Tax Accounts'                => 'Konta Podatkowe',
+  'Tax Included'                => 'Podatek Wliczony',
+  'Tax collected'               => '',
+  'Tax paid'                    => '',
+  'Taxable'                     => 'Opodatkowane',
+  'Template saved!'             => '',
+  'Templates'                   => 'æÏÒÍÙ',
+  'Terms: Net'                  => 'Warunki: Netto',
+  'The following Datasets are not in use and can be deleted' => 'Te Zbiory Danych s± nieu¿ywane i mo¿na je usun±æ',
+  'The following Datasets need to be updated' => 'Zbiory Danych do uzupe³nienia',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Jest to wstêpne sprawdzenie istniej±cych ¿róde³. Narazie nic nie bêdzie utworzone lub usuniête.',
+  'To'                          => 'do',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => '¯eby dodaæ do grupy u¿ytkownika zmieñ nazwê, nazwê zarejestrowania i zapisz. Nowy u¿ytkownik z tymi samymi zmiennymi warto¶ciami bêdzie zapisany pod now± nazw± rejestruj±c±',
+  'Top Level'                   => '',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Transaction Date missing!'   => 'Brak Daty Transakcji!',
+  'Transaction deleted!'        => '',
+  'Transaction posted!'         => '',
+  'Transaction reversal enforced for all dates' => 'Zmiana transakcji narzucona dla wszystkich okresów',
+  'Transaction reversal enforced up to' => 'Zmiana transakcji narzucona do',
+  'Transactions'                => 'Transakcje',
+  'Transactions exist, cannot delete customer!' => 'Istniej± Transakcje, niemo¿na usun±æ odbiorcy',
+  'Transactions exist, cannot delete vendor!' => 'Istniej± Transakcje, nie mo¿na usun±æ dostawcy',
+  'Transactions exist; cannot delete account!' => 'Istniej± Transakcje, nie mo¿na usun±æ konta',
+  'Trial Balance'               => 'Bilans Porównawczy',
+  'Unit'                        => 'Jednostka',
+  'Unit of measure'             => 'Jednostka miary',
+  'Update'                      => '',
+  'Update Dataset'              => 'Uzupe³nij Zbiór Danych',
+  'Updated'                     => '',
+  'Use Templates'               => 'U¿yj Szablony',
+  'User'                        => 'U¿ytkownik',
+  'User deleted!'               => '',
+  'User saved!'                 => '',
+  'Vendor'                      => 'Dostawca',
+  'Vendor deleted!'             => '',
+  'Vendor missing!'             => '',
+  'Vendor not on file!'         => '',
+  'Vendor saved!'               => '',
+  'Vendors'                     => '',
+  'Version'                     => '÷ÅÒÓÉÑ',
+  'Weight'                      => 'Waga',
+  'Weight Unit'                 => 'Jednostka Wagi',
+  'What type of item is this?'  => 'Co to za rodzaj artyku³u',
+  'Year End'                    => 'Koniec Roku Finansowego',
+  'Yes'                         => 'Tak',
+  'You are logged out!'         => '',
+  'You did not enter a name!'   => 'Nie wstawiono nazwy!',
+  'You must enter a host and port for local and remote connections!' => 'Wstaw wêze³ i port dla lokalnego i zdalnego po³±czenia',
+  'as at'                       => '',
+  'collected on sales'          => 'zebranego przy sprzeda¿y',
+  'days'                        => 'dni',
+  'does not exist'              => 'nie istnieje',
+  'ea'                          => 'szt',
+  'emailed to'                  => 'email do',
+  'for Period'                  => 'za Okres',
+  'hr'                          => 'godz',
+  'is already a member!'        => 'Jest ju¿ cz³onkiem',
+  'is not a member!'            => 'Nie jest cz³onkiem',
+  'localhost'                   => 'wêze³',
+  'paid on purchases'           => 'zap³aconego przy zakupach',
+  'sent to printer'             => 'wys³ano do drukarki',
+  'successfully created!'       => 'stworzone z powodzeniem',
+  'successfully deleted!'       => 'usuniête z powodzeniem',
+  'to'                          => '',
+  'website'                     => 'witryna WWW',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/am b/sql-ledger/locale/ru/am
new file mode 100644 (file)
index 0000000..204e1c3
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'òÁÓÈÏÄ',
+  'AR'                          => 'äÏÈÏÄ',
+  'Account'                     => 'óÞÅÔ',
+  'Account Number'              => 'ëÏÄ ÓÞÅÔÁ',
+  'Account Number missing!'     => 'îÅ ÕËÁÚÁΠÎÏÍÅÒ ÓÞÅÔÁ!',
+  'Account Type'                => 'ôÉРÓÞÅÔÁ',
+  'Account Type missing!'       => 'îÅ ÕËÁÚÁΠÔÉРÓÞÅÔÁ!',
+  'Account deleted!'            => 'Account deleted!',
+  'Account saved!'              => 'Account saved!',
+  'Add Account'                 => 'îÏ×ÙÊ ÓÞÅÔ',
+  'Add GIFI'                    => 'îÏ×ÙÊ GIFI',
+  'Address'                     => 'áÄÒÅÓ',
+  'Asset'                       => 'áËÔÉ×',
+  'Audit Control'               => 'ëÏÎÔÒÏÌØ',
+  'Backup sent to'              => 'òÅÚÅÒ×ÎÁÑ ËÏÐÉÑ ÏÔÏÓÌÁÎÁ ÎÁ',
+  'Books are open'              => 'ëÎÉÇÁ ÏÔËÒÙÔÁ',
+  'Business Number'             => 'òîî',
+  'COGS'                        => 'COGS',
+  'Cannot delete account!'      => 'Cannot delete account!',
+  'Cannot delete default account!' => 'îÅÌØÚÑ ÕÄÁÌÉÔØ ÏÓÎÏ×ÎÏÊ ÓÞÅÔ!',
+  'Cannot save account!'        => 'Cannot save account!',
+  'Cannot save preferences!'    => 'Cannot save preferences!',
+  'Character Set'               => 'ëÏÄÉÒÏ×ËÁ',
+  'Chart of Accounts'           => 'ðÌÁΠÓÞÅÔÏ×',
+  'Close Books up to'           => 'Zamkniêcie Ksi±g do!',
+  'Company'                     => 'ïÒÇÁÎÉÚÁÃÉÑ',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Copy to COA'                 => 'ëÏÐÉÒÏ×ÁÔØ × çðó',
+  'Credit'                      => 'ëÒÅÄÉÔ',
+  'Date Format'                 => 'æÏÒÍÁÔ ÄÁÔÙ',
+  'Debit'                       => 'äÅÂÅÔ',
+  'Delete'                      => 'õÄÁÌÉÔØ',
+  'Delete Account'              => 'õÄÁÌÍÔØ ÓÞÅÔ',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'E-mail',
+  'Edit'                        => 'Edit',
+  'Edit Account'                => 'éÚÍÅÎÉÔØ ÓÞÅÔ',
+  'Edit GIFI'                   => 'éÚÍÅÎÉÔØ GIFI',
+  'Edit Preferences for'        => 'Zmiany Preferencji dla',
+  'Edit Template'               => 'Zmiany Wzorca',
+  'Enforce transaction reversal for all dates' => 'Egzekwuj zmiany transakcji dla wszystkich terminów',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies',
+  'Equity'                      => 'Kapita³',
+  'Expense'                     => 'òÁÓÈÏÄ',
+  'Expense Account'             => 'Konto Kosztów',
+  'Expense/Asset'               => 'Koszt/Aktywy',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Zysk przy Wymianie Walut',
+  'Foreign Exchange Loss'       => 'Strata przy Wymianie Walut',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI deleted!',
+  'GIFI missing!'               => 'Brakuje GIFI',
+  'GIFI saved!'                 => 'GIFI saved!',
+  'Heading'                     => 'òÁÚÄÅÌ',
+  'Include in drop-down menus'  => 'Do³±cz w menu rozwijanym',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Do³±cz Konto w formularzach Kontrachentów ¿eby wskazaæ ¿e podlegaj± opodatkowaniu',
+  'Income'                      => 'äÏÈÏÄ',
+  'Income Account'              => 'Konto Przychodów',
+  'Inventory'                   => 'éÎ×ÅÎÔÁÒÎÙÊ',
+  'Inventory Account'           => 'Konto Materia³owe',
+  'Is this a summary account to record' => 'Czy jest to konto sumaryczne?',
+  'Language'                    => 'ñÚÙË',
+  'Last Invoice Number'         => 'Ostatni Numer Faktury',
+  'Last Numbers & Default Accounts' => 'Ostatnie Numery i Konta Domy¶lne',
+  'Last Purchase Order Number'  => 'Ostatni Numer Faktury Zamówienia',
+  'Last Sales Order Number'     => 'Ostatni Numer Faktury Sprzeda¿y',
+  'Liability'                   => 'ðÁÓÓÉ×',
+  'Link'                        => 'Dowi±zanie',
+  'Name'                        => 'Nazwa',
+  'No'                          => 'Nie',
+  'No email address for'        => 'Brak adresu email',
+  'Number'                      => 'Numer Katalogu',
+  'Number Format'               => 'Format Numeru',
+  'Parts Inventory'             => 'Inwentarz',
+  'Password'                    => 'Has³o',
+  'Payables'                    => 'Zobowi±zania',
+  'Payment'                     => 'P³atno¶æ',
+  'Phone'                       => 'Tel.',
+  'Preferences saved!'          => 'Preferencje Zapisane!',
+  'Rate'                        => 'Stawka',
+  'Receivables'                 => 'Nale¿no¶ci',
+  'Sales'                       => 'Sprzeda¿',
+  'Save'                        => 'Zapisz',
+  'Service Items'               => 'Artyku³y Us³ugowe',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'ðÏÄÐÉÓØ',
+  'Stylesheet'                  => 'ïÆÏÒÍÌÅÎÉÅ',
+  'Tax'                         => 'îÁÌÏÇ',
+  'Tax Accounts'                => 'Konta Podatkowe',
+  'Template saved!'             => 'Template saved!',
+  'Transaction reversal enforced for all dates' => 'Zmiana transakcji narzucona dla wszystkich okresów',
+  'Transaction reversal enforced up to' => 'Zmiana transakcji narzucona do',
+  'Transactions exist; cannot delete account!' => 'Istniej± Transakcje, nie mo¿na usun±æ konta',
+  'Weight Unit'                 => 'Jednostka Wagi',
+  'Year End'                    => 'Koniec Roku Finansowego',
+  'Yes'                         => 'Tak',
+  'does not exist'              => 'nie istnieje',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'îÏ×ÙÊ_ÓÞÅÔ'                  => 'add_account',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'ëÏÐÉÒÏ×ÁÔØ_×_çðó'            => 'copy_to_coa',
+  'õÄÁÌÉÔØ'                     => 'delete',
+  'edit'                        => 'edit',
+  'éÚÍÅÎÉÔØ_ÓÞÅÔ'               => 'edit_account',
+  'zapisz'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/ap b/sql-ledger/locale/ru/ap
new file mode 100644 (file)
index 0000000..3c243eb
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AP Transactions'             => 'ðÒÏ×ÏÄËÉ ÒÁÓÈÏÄÁ',
+  'Account'                     => 'óÞÅÔ',
+  'Add Accounts Payables Transaction' => 'Add Accounts Payables Transaction',
+  'Address'                     => 'áÄÒÅÓ',
+  'Amount'                      => 'óÕÍÍÁ',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'áÐÒ',
+  'April'                       => 'áÐÒÅÌØ',
+  'Are you sure you want to delete Transaction' => '÷Ù Õ×ÅÒÅÎÙ, ÓÔÏ ÈÏÔÉÔÅ ÕÄÁÌÉÔØ ÄÁÎÎÕÀ ÐÒÏ×ÏÄËÕ?',
+  'Aug'                         => 'á×Ç',
+  'August'                      => 'á×ÇÕÓÔ',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'Nie mo¿na zaksiêgowaæ p³atno¶ci po zamkniêciu okresu!',
+  'Cannot post transaction for a closed period!' => 'Nie mo¿na zaksiêgowaæ transakcji w zamkniêtym okresie',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'úÁËÒÙÔ',
+  'Confirm!'                    => 'ðÏÄÔ×ÅÒÄÉÔØ!',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'äÁÔÁ',
+  'Date Paid'                   => 'äÁÔÁ ÏÐÌÁÔÙ',
+  'Dec'                         => 'äÅË',
+  'December'                    => 'äÅËÁÂÒØ',
+  'Delete'                      => 'õÄÁÌÉÔØ',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'Due Date'                    => 'ïÐÌÁÔÉÔØ ÄÏ',
+  'Due Date missing!'           => 'îÅ ÕËÁÚÁΠÓÒÏË ÏÐÌÁÔÙ!',
+  'Edit Accounts Payables Transaction' => 'Edit Accounts Payables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'Kurs',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'Exchangerate for payment missing!' => 'Brakuje kursu wymiany dla p³atno¶ci!',
+  'Exchangerate missing!'       => 'Brakuje kursu wymiany',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'ID'                          => 'Identyfikator',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Invoice'                     => 'óÞÅÔ-ÆÁËÔÕÒÁ',
+  'Invoice Date'                => 'äÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ',
+  'Invoice Date missing!'       => 'îÅ ÕËÁÚÁÎÁ ÄÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number'              => 'îÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number missing!'     => 'îÅ ÕËÁÚÁΠÎÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Jan'                         => 'ñÎ×',
+  'January'                     => 'ñÎ×ÁÒØ',
+  'Jul'                         => 'éÀÌ',
+  'July'                        => 'éÀÌØ',
+  'Jun'                         => 'éÀÎ',
+  'June'                        => 'éÀÎØ',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Open'                        => 'Otwórz',
+  'Order'                       => 'Zamówienie',
+  'Order Number'                => 'Numer Zamówienia',
+  'Paid'                        => 'Zap³acono',
+  'Payment date missing!'       => 'Brak Daty P³atno¶ci',
+  'Payments'                    => 'Rozliczenia P³atno¶ci',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'óÅÎ',
+  'September'                   => 'óÅÎÔÑÂÒØ',
+  'Source'                      => '¯ród³o',
+  'Subtotal'                    => 'éÔÏÇÏ ÐÏ ÒÁÚÄÅÌÕ',
+  'Tax'                         => 'îÁÌÏÇ',
+  'Tax Included'                => 'Podatek Wliczony',
+  'To'                          => 'do',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Dostawca',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Tak',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'add_accounts_payables_transaction' => 'add_accounts_payables_transaction',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'õÄÁÌÉÔØ'                     => 'delete',
+  'edit_accounts_payables_transaction' => 'edit_accounts_payables_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'update'                      => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/ar b/sql-ledger/locale/ru/ar
new file mode 100644 (file)
index 0000000..3970754
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'AR Transaction',
+  'AR Transactions'             => 'ðÒÏ×ÏÄËÉ ÄÏÈÏÄÁ',
+  'Account'                     => 'óÞÅÔ',
+  'Add Accounts Receivables Transaction' => 'Add Accounts Receivables Transaction',
+  'Address'                     => 'áÄÒÅÓ',
+  'Amount'                      => 'óÕÍÍÁ',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'áÐÒ',
+  'April'                       => 'áÐÒÅÌØ',
+  'Are you sure you want to delete Transaction' => '÷Ù Õ×ÅÒÅÎÙ, ÓÔÏ ÈÏÔÉÔÅ ÕÄÁÌÉÔØ ÄÁÎÎÕÀ ÐÒÏ×ÏÄËÕ?',
+  'Aug'                         => 'á×Ç',
+  'August'                      => 'á×ÇÕÓÔ',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'Nie mo¿na zaksiêgowaæ p³atno¶ci po zamkniêciu okresu!',
+  'Cannot post transaction for a closed period!' => 'Nie mo¿na zaksiêgowaæ transakcji w zamkniêtym okresie',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'úÁËÒÙÔ',
+  'Confirm!'                    => 'ðÏÄÔ×ÅÒÄÉÔØ!',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Credit Limit'                => 'ìÉÍÉÔ ËÒÅÄÉÔÁ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Customer'                    => 'ëÌÉÅÎÔ',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'äÁÔÁ',
+  'Date Paid'                   => 'äÁÔÁ ÏÐÌÁÔÙ',
+  'Dec'                         => 'äÅË',
+  'December'                    => 'äÅËÁÂÒØ',
+  'Delete'                      => 'õÄÁÌÉÔØ',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'Due Date'                    => 'ïÐÌÁÔÉÔØ ÄÏ',
+  'Due Date missing!'           => 'îÅ ÕËÁÚÁΠÓÒÏË ÏÐÌÁÔÙ!',
+  'Edit Accounts Receivables Transaction' => 'Edit Accounts Receivables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'Kurs',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'Exchangerate for payment missing!' => 'Brakuje kursu wymiany dla p³atno¶ci!',
+  'Exchangerate missing!'       => 'Brakuje kursu wymiany',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'ID'                          => 'Identyfikator',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Invoice'                     => 'óÞÅÔ-ÆÁËÔÕÒÁ',
+  'Invoice Date'                => 'äÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ',
+  'Invoice Date missing!'       => 'îÅ ÕËÁÚÁÎÁ ÄÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number'              => 'îÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number missing!'     => 'îÅ ÕËÁÚÁΠÎÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Jan'                         => 'ñÎ×',
+  'January'                     => 'ñÎ×ÁÒØ',
+  'Jul'                         => 'éÀÌ',
+  'July'                        => 'éÀÌØ',
+  'Jun'                         => 'éÀÎ',
+  'June'                        => 'éÀÎØ',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Open'                        => 'Otwórz',
+  'Order'                       => 'Zamówienie',
+  'Order Number'                => 'Numer Zamówienia',
+  'Paid'                        => 'Zap³acono',
+  'Payment date missing!'       => 'Brak Daty P³atno¶ci',
+  'Payments'                    => 'Rozliczenia P³atno¶ci',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Remaining'                   => 'Pozosta³e',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'óÅÎ',
+  'September'                   => 'óÅÎÔÑÂÒØ',
+  'Source'                      => '¯ród³o',
+  'Subtotal'                    => 'éÔÏÇÏ ÐÏ ÒÁÚÄÅÌÕ',
+  'Tax'                         => 'îÁÌÏÇ',
+  'Tax Included'                => 'Podatek Wliczony',
+  'To'                          => 'do',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Tak',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ar_transaction'              => 'ar_transaction',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'õÄÁÌÉÔØ'                     => 'delete',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/arap b/sql-ledger/locale/ru/arap
new file mode 100644 (file)
index 0000000..24fe716
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'áÄÒÅÓ',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'Number'                      => 'Numer Katalogu',
+  'Project not on file!'        => 'Project not on file!',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/ca b/sql-ledger/locale/ru/ca
new file mode 100644 (file)
index 0000000..1b1b139
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'óÞÅÔ',
+  'Apr'                         => 'áÐÒ',
+  'April'                       => 'áÐÒÅÌØ',
+  'Aug'                         => 'á×Ç',
+  'August'                      => 'á×ÇÕÓÔ',
+  'Balance'                     => 'Balance',
+  'Chart of Accounts'           => 'ðÌÁΠÓÞÅÔÏ×',
+  'Credit'                      => 'ëÒÅÄÉÔ',
+  'Date'                        => 'äÁÔÁ',
+  'Debit'                       => 'äÅÂÅÔ',
+  'Dec'                         => 'äÅË',
+  'December'                    => 'äÅËÁÂÒØ',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Jan'                         => 'ñÎ×',
+  'January'                     => 'ñÎ×ÁÒØ',
+  'Jul'                         => 'éÀÌ',
+  'July'                        => 'éÀÌØ',
+  'Jun'                         => 'éÀÎ',
+  'June'                        => 'éÀÎØ',
+  'List Transactions'           => 'Wykaz Transakcji',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Reference'                   => 'Reference',
+  'Sep'                         => 'óÅÎ',
+  'September'                   => 'óÅÎÔÑÂÒØ',
+  'Subtotal'                    => 'éÔÏÇÏ ÐÏ ÒÁÚÄÅÌÕ',
+  'To'                          => 'do',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'wykaz_transakcji'            => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/cp b/sql-ledger/locale/ru/cp
new file mode 100644 (file)
index 0000000..6ff1936
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'óÞÅÔ',
+  'Address'                     => 'áÄÒÅÓ',
+  'Amount'                      => 'óÕÍÍÁ',
+  'Amount does not equal applied!' => 'Amount does not equal applied!',
+  'Amount missing!'             => 'Amount missing!',
+  'Applied'                     => 'Applied',
+  'Cannot post payment!'        => 'Cannot post payment!',
+  'Cannot process payment for a closed period!' => 'Cannot process payment for a closed period!',
+  'Check'                       => 'Check',
+  'Check printed!'              => 'Check printed!',
+  'Check printing failed!'      => 'Check printing failed!',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Customer'                    => 'ëÌÉÅÎÔ',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'äÁÔÁ',
+  'Date missing!'               => 'Date missing!',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'Due'                         => 'äÏ',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'From'                        => 'Od',
+  'Invoice'                     => 'óÞÅÔ-ÆÁËÔÕÒÁ',
+  'Invoices'                    => 'Invoices',
+  'Nothing applied!'            => 'Nothing applied!',
+  'Number'                      => 'Numer Katalogu',
+  'Paid in full'                => 'Paid in full',
+  'Payment'                     => 'P³atno¶æ',
+  'Payment posted!'             => 'Payment posted!',
+  'Post'                        => 'Post',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Drukarka',
+  'Project not on file!'        => 'Project not on file!',
+  'Receipt'                     => 'Receipt',
+  'Reference'                   => 'Reference',
+  'Screen'                      => 'Ekran',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'To'                          => 'do',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Dostawca',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/ct b/sql-ledger/locale/ru/ct
new file mode 100644 (file)
index 0000000..7c39884
--- /dev/null
@@ -0,0 +1,69 @@
+$self{texts} = {
+  'Add'                         => 'îÏ×ÙÊ',
+  'Address'                     => 'áÄÒÅÓ',
+  'All'                         => '÷ÓÅ',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Cannot delete customer!',
+  'Cannot delete vendor!'       => 'Cannot delete vendor!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÏÅ ÌÉÃÏ',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Credit Limit'                => 'ìÉÍÉÔ ËÒÅÄÉÔÁ',
+  'Customer deleted!'           => 'Customer deleted!',
+  'Customer saved!'             => 'Customer saved!',
+  'Customers'                   => 'Customers',
+  'Delete'                      => 'õÄÁÌÉÔØ',
+  'Discount'                    => 'óËÉÄËÁ',
+  'E-mail'                      => 'E-mail',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Invoice'                     => 'óÞÅÔ-ÆÁËÔÕÒÁ',
+  'Name'                        => 'Nazwa',
+  'Name missing!'               => 'Name missing!',
+  'Notes'                       => 'Noty',
+  'Number'                      => 'Numer Katalogu',
+  'Order'                       => 'Zamówienie',
+  'Orphaned'                    => 'Zbêdny',
+  'Phone'                       => 'Tel.',
+  'Save'                        => 'Zapisz',
+  'Ship to'                     => 'Ship to',
+  'Tax Included'                => 'Podatek Wliczony',
+  'Taxable'                     => 'Opodatkowane',
+  'Terms: Net'                  => 'Warunki: Netto',
+  'Transactions exist, cannot delete customer!' => 'Istniej± Transakcje, niemo¿na usun±æ odbiorcy',
+  'Transactions exist, cannot delete vendor!' => 'Istniej± Transakcje, nie mo¿na usun±æ dostawcy',
+  'Vendor deleted!'             => 'Vendor deleted!',
+  'Vendor saved!'               => 'Vendor saved!',
+  'Vendors'                     => 'Vendors',
+  'days'                        => 'dni',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'îÏ×ÙÊ'                       => 'add',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'õÄÁÌÉÔØ'                     => 'delete',
+  'óÞÅÔ_ÆÁËÔÕÒÁ'                => 'invoice',
+  'zamówienie'                  => 'order',
+  'zapisz'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/gl b/sql-ledger/locale/ru/gl
new file mode 100644 (file)
index 0000000..28292ad
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AR Transaction'              => 'AR Transaction',
+  'Account'                     => 'óÞÅÔ',
+  'Add General Ledger Transaction' => 'îÏ×ÁÑ ÐÒÏ×ÏÄËÁ',
+  'Address'                     => 'áÄÒÅÓ',
+  'All'                         => '÷ÓÅ',
+  'Apr'                         => 'áÐÒ',
+  'April'                       => 'áÐÒÅÌØ',
+  'Are you sure you want to delete Transaction' => '÷Ù Õ×ÅÒÅÎÙ, ÓÔÏ ÈÏÔÉÔÅ ÕÄÁÌÉÔØ ÄÁÎÎÕÀ ÐÒÏ×ÏÄËÕ?',
+  'Asset'                       => 'áËÔÉ×',
+  'Aug'                         => 'á×Ç',
+  'August'                      => 'á×ÇÕÓÔ',
+  'Balance'                     => 'Balance',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot have a value in both Debit and Credit!' => 'Nie mo¿na wpisaæ warto¶ci w Debet i Kredyt równocze¶nie!',
+  'Cannot post a transaction without a value!' => 'Cannot post a transaction without a value!',
+  'Cannot post transaction for a closed period!' => 'Nie mo¿na zaksiêgowaæ transakcji w zamkniêtym okresie',
+  'Confirm!'                    => 'ðÏÄÔ×ÅÒÄÉÔØ!',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Credit'                      => 'ëÒÅÄÉÔ',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'äÁÔÁ',
+  'Debit'                       => 'äÅÂÅÔ',
+  'Debit and credit out of balance!' => 'Debet i Kredyt siê niebalansuj±!',
+  'Dec'                         => 'äÅË',
+  'December'                    => 'äÅËÁÂÒØ',
+  'Delete'                      => 'õÄÁÌÉÔØ',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'Edit General Ledger Transaction' => 'Zmiany w Ksiêdze G³ównej',
+  'Equity'                      => 'Kapita³',
+  'Expense'                     => 'òÁÓÈÏÄ',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'GL Transaction',
+  'General Ledger'              => 'Ksiêga G³ówna',
+  'ID'                          => 'Identyfikator',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Income'                      => 'äÏÈÏÄ',
+  'Jan'                         => 'ñÎ×',
+  'January'                     => 'ñÎ×ÁÒØ',
+  'Jul'                         => 'éÀÌ',
+  'July'                        => 'éÀÌØ',
+  'Jun'                         => 'éÀÎ',
+  'June'                        => 'éÀÎØ',
+  'Liability'                   => 'ðÁÓÓÉ×',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Reference'                   => 'Reference',
+  'Reference missing!'          => 'Reference missing!',
+  'Reports'                     => 'Sprawozdania',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'óÅÎ',
+  'September'                   => 'óÅÎÔÑÂÒØ',
+  'Source'                      => '¯ród³o',
+  'Subtotal'                    => 'éÔÏÇÏ ÐÏ ÒÁÚÄÅÌÕ',
+  'To'                          => 'do',
+  'Transaction Date missing!'   => 'Brak Daty Transakcji!',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Tak',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'õÄÁÌÉÔØ'                     => 'delete',
+  'gl_transaction'              => 'gl_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/ic b/sql-ledger/locale/ru/ic
new file mode 100644 (file)
index 0000000..b879e88
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Active',
+  'Add'                         => 'îÏ×ÙÊ',
+  'Add Assembly'                => 'îÏ×ÙÊ ËÏÍÐÌÅËÔ',
+  'Add Part'                    => 'îÏ×ÙÊ ÐÒÏÄÕËÔ',
+  'Add Purchase Order'          => 'îÏ×ÙÊ ÚÁËÁÚ ÐÏÓÔÁ×ÝÉËÁ',
+  'Add Sales Order'             => 'îÏ×ÙÊ ÚÁËÁÚ ËÌÉÅÎÔÁ',
+  'Add Service'                 => 'îÏ×ÁÑ ÕÓÌÕÇÁ',
+  'Address'                     => 'áÄÒÅÓ',
+  'Apr'                         => 'áÐÒ',
+  'April'                       => 'áÐÒÅÌØ',
+  'Assemblies'                  => 'ëÏÍÐÌÅËÔÙ',
+  'Assemblies restocked!'       => 'Assemblies restocked!',
+  'Assembly Number missing!'    => 'îÅ ÕËÁÚÁΠÎÏÍÅÒ ËÏÍÐÌÅËÔÁ!',
+  'Attachment'                  => '÷ÌÏÖÅÎÉÅ',
+  'Aug'                         => 'á×Ç',
+  'August'                      => 'á×ÇÕÓÔ',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Bought'                      => 'ëÕÐÌÅÎÏ',
+  'COGS'                        => 'COGS',
+  'Cannot delete item already invoiced!' => 'Nie mo¿na usun±æ pozycji zafakturowanej!',
+  'Cannot delete item on order!' => 'Nie mo¿na usunac zamówionego produktu!',
+  'Cannot delete item which is part of an assembly!' => 'Nie mo¿na usun±æ czê¶ci z zestawienia!',
+  'Cannot delete item!'         => 'Cannot delete item!',
+  'Cannot stock assemblies!'    => 'Cannot stock assemblies!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÏÅ ÌÉÃÏ',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Copies'                      => 'ëÏÐÉÊ',
+  'Dec'                         => 'äÅË',
+  'December'                    => 'äÅËÁÂÒØ',
+  'Delete'                      => 'õÄÁÌÉÔØ',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'Drawing'                     => 'Drawing',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'îÅ ÕËÁÚÁΠÁÄÒÅÓ E-mail!',
+  'Edit Assembly'               => 'éÚÍÅÎÉÔØ ËÏÍÐÌÅËÔ',
+  'Edit Part'                   => 'Zmiany Produktu',
+  'Edit Service'                => 'éÚÍÅÎÉÔØ ÕÓÌÕÇÕ',
+  'Expense'                     => 'òÁÓÈÏÄ',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'Image'                       => 'Image',
+  'In-line'                     => 'W³±czony',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Income'                      => 'äÏÈÏÄ',
+  'Individual Items'            => 'Indywidualne Czê¶ci',
+  'Inventory'                   => 'éÎ×ÅÎÔÁÒÎÙÊ',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Ilo¶æ Inventarza musi byæ równa zero zanim bêdzie mozna zdezaktualizowaæ to z³o¿enie!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Ilo¶æ inventarza musi byæ równa zero zanim bêdzie mo¿na zdezaktualizowaæ t± czê¶æ!',
+  'Inventory quantity must be zero!' => 'Ilo¶æc Inventarza musi byæ równa zero',
+  'Invoice'                     => 'óÞÅÔ-ÆÁËÔÕÒÁ',
+  'Invoice Date missing!'       => 'îÅ ÕËÁÚÁÎÁ ÄÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number'              => 'îÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number missing!'     => 'îÅ ÕËÁÚÁΠÎÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Item deleted!'               => 'Item deleted!',
+  'Item not on file!'           => 'Produkt nie jest w zbiorze!',
+  'Jan'                         => 'ñÎ×',
+  'January'                     => 'ñÎ×ÁÒØ',
+  'Jul'                         => 'éÀÌ',
+  'July'                        => 'éÀÌØ',
+  'Jun'                         => 'éÀÎ',
+  'June'                        => 'éÀÎØ',
+  'Last Cost'                   => 'Cena Zakupu',
+  'Line Total'                  => 'Suma ca³kowita',
+  'Link Accounts'               => 'Konta dowi±zane',
+  'List Price'                  => 'Cena',
+  'Make'                        => 'Marka',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Model',
+  'Name'                        => 'Nazwa',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Number missing in Row'       => 'Brak Numeru w Rzêdzie',
+  'Obsolete'                    => 'Zdezaktualizowany',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'On Hand'                     => 'Na Stanie',
+  'On Order'                    => 'On Order',
+  'Order'                       => 'Zamówienie',
+  'Order Date missing!'         => 'Brak Daty Zamówienia',
+  'Order Number'                => 'Numer Zamówienia',
+  'Order Number missing!'       => 'Brak Numeru Zamówienia',
+  'Ordered'                     => 'Ordered',
+  'Orphaned'                    => 'Zbêdny',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Packing List Date missing!'  => 'Brak Daty Wykazu Dostawy',
+  'Packing List Number missing!' => 'Brak Numeru Wykazu Dostawy',
+  'Part'                        => 'Produkt',
+  'Part Number missing!'        => 'Brak Symbolu Produktu!',
+  'Parts'                       => 'Produkty',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena Netto',
+  'Printer'                     => 'Drukarka',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Qty'                         => 'Ilo¶æ',
+  'ROP'                         => 'PPZ',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Termin Dostawy',
+  'Sales'                       => 'Sprzeda¿',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Save'                        => 'Zapisz',
+  'Screen'                      => 'Ekran',
+  'Select from one of the items below' => 'Wybie¿ jeden z poni¿szych artyku³ów',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sell Price'                  => 'Cena Sprzeda¿y',
+  'Sep'                         => 'óÅÎ',
+  'September'                   => 'óÅÎÔÑÂÒØ',
+  'Service'                     => 'õÓÌÕÇÁ',
+  'Service Number missing!'     => 'Brak Numeru Us³ugi!',
+  'Services'                    => 'õÓÌÕÇÉ',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Short'                       => 'Niedobór',
+  'Sold'                        => 'Sprzedano',
+  'Stock Assembly'              => 'Wstaw Z³o¿enie',
+  'Subject'                     => 'ôÅÍÁ',
+  'Subtotal'                    => 'éÔÏÇÏ ÐÏ ÒÁÚÄÅÌÕ',
+  'Tax'                         => 'îÁÌÏÇ',
+  'To'                          => 'do',
+  'Top Level'                   => 'Top Level',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Unit'                        => 'Jednostka',
+  'Unit of measure'             => 'Jednostka miary',
+  'Update'                      => 'Update',
+  'Updated'                     => 'Updated',
+  'Weight'                      => 'Waga',
+  'What type of item is this?'  => 'Co to za rodzaj artyku³u',
+  'ea'                          => 'szt',
+  'emailed to'                  => 'email do',
+  'hr'                          => 'godz',
+  'sent to printer'             => 'wys³ano do drukarki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'îÏ×ÙÊ'                       => 'add',
+  'îÏ×ÙÊ_ËÏÍÐÌÅËÔ'              => 'add_assembly',
+  'îÏ×ÙÊ_ÐÒÏÄÕËÔ'               => 'add_part',
+  'îÏ×ÁÑ_ÕÓÌÕÇÁ'                => 'add_service',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'õÄÁÌÉÔØ'                     => 'delete',
+  'éÚÍÅÎÉÔØ_ËÏÍÐÌÅËÔ'           => 'edit_assembly',
+  'zmiany_produktu'             => 'edit_part',
+  'éÚÍÅÎÉÔØ_ÕÓÌÕÇÕ'             => 'edit_service',
+  'zapisz'                      => 'save',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/io b/sql-ledger/locale/ru/io
new file mode 100644 (file)
index 0000000..36137b2
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'îÏ×ÙÊ ÚÁËÁÚ ÐÏÓÔÁ×ÝÉËÁ',
+  'Add Sales Order'             => 'îÏ×ÙÊ ÚÁËÁÚ ËÌÉÅÎÔÁ',
+  'Address'                     => 'áÄÒÅÓ',
+  'Apr'                         => 'áÐÒ',
+  'April'                       => 'áÐÒÅÌØ',
+  'Attachment'                  => '÷ÌÏÖÅÎÉÅ',
+  'Aug'                         => 'á×Ç',
+  'August'                      => 'á×ÇÕÓÔ',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÏÅ ÌÉÃÏ',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Copies'                      => 'ëÏÐÉÊ',
+  'Dec'                         => 'äÅË',
+  'December'                    => 'äÅËÁÂÒØ',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'îÅ ÕËÁÚÁΠÁÄÒÅÓ E-mail!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'In-line'                     => 'W³±czony',
+  'Invoice'                     => 'óÞÅÔ-ÆÁËÔÕÒÁ',
+  'Invoice Date missing!'       => 'îÅ ÕËÁÚÁÎÁ ÄÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number missing!'     => 'îÅ ÕËÁÚÁΠÎÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Item not on file!'           => 'Produkt nie jest w zbiorze!',
+  'Jan'                         => 'ñÎ×',
+  'January'                     => 'ñÎ×ÁÒØ',
+  'Jul'                         => 'éÀÌ',
+  'July'                        => 'éÀÌØ',
+  'Jun'                         => 'éÀÎ',
+  'June'                        => 'éÀÎØ',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'Name'                        => 'Nazwa',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Number missing in Row'       => 'Brak Numeru w Rzêdzie',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Order'                       => 'Zamówienie',
+  'Order Date missing!'         => 'Brak Daty Zamówienia',
+  'Order Number missing!'       => 'Brak Numeru Zamówienia',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Packing List Date missing!'  => 'Brak Daty Wykazu Dostawy',
+  'Packing List Number missing!' => 'Brak Numeru Wykazu Dostawy',
+  'Part'                        => 'Produkt',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena Netto',
+  'Printer'                     => 'Drukarka',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Qty'                         => 'Ilo¶æ',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Termin Dostawy',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Screen'                      => 'Ekran',
+  'Select from one of the items below' => 'Wybie¿ jeden z poni¿szych artyku³ów',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'óÅÎ',
+  'September'                   => 'óÅÎÔÑÂÒØ',
+  'Service'                     => 'õÓÌÕÇÁ',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Subject'                     => 'ôÅÍÁ',
+  'To'                          => 'do',
+  'Unit'                        => 'Jednostka',
+  'What type of item is this?'  => 'Co to za rodzaj artyku³u',
+  'emailed to'                  => 'email do',
+  'sent to printer'             => 'wys³ano do drukarki',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/ir b/sql-ledger/locale/ru/ir
new file mode 100644 (file)
index 0000000..67db203
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'óÞÅÔ',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => 'îÏ×ÙÊ ÚÁËÁÚ ÐÏÓÔÁ×ÝÉËÁ',
+  'Add Sales Order'             => 'îÏ×ÙÊ ÚÁËÁÚ ËÌÉÅÎÔÁ',
+  'Address'                     => 'áÄÒÅÓ',
+  'Amount'                      => 'óÕÍÍÁ',
+  'Apr'                         => 'áÐÒ',
+  'April'                       => 'áÐÒÅÌØ',
+  'Are you sure you want to delete Invoice Number' => '÷Ù Õ×ÅÒÅÎÙ, ÞÔÏ ÈÏÔÉÔÅ ÕÄÁÌÉÔØ ÄÁÎÎÙÊ ÓÞÅÔ?',
+  'Attachment'                  => '÷ÌÏÖÅÎÉÅ',
+  'Aug'                         => 'á×Ç',
+  'August'                      => 'á×ÇÕÓÔ',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'Nie mo¿na zksiêgowaæ faktury pozamkniêciu okresu',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'Nie mo¿na zaksiêgowaæ p³atno¶ci po zamkniêciu okresu!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'ðÏÄÔ×ÅÒÄÉÔØ!',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÏÅ ÌÉÃÏ',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Copies'                      => 'ëÏÐÉÊ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'äÁÔÁ',
+  'Date Due'                    => 'ïÐÌÁÔÉÔØ ÄÏ',
+  'Dec'                         => 'äÅË',
+  'December'                    => 'äÅËÁÂÒØ',
+  'Delete'                      => 'õÄÁÌÉÔØ',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'îÅ ÕËÁÚÁΠÁÄÒÅÓ E-mail!',
+  'Edit Purchase Invoice'       => 'Edit Purchase Invoice',
+  'Exch'                        => 'Kurs',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'Exchangerate for payment missing!' => 'Brakuje kursu wymiany dla p³atno¶ci!',
+  'Exchangerate missing!'       => 'Brakuje kursu wymiany',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'In-line'                     => 'W³±czony',
+  'Invoice'                     => 'óÞÅÔ-ÆÁËÔÕÒÁ',
+  'Invoice Date'                => 'äÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ',
+  'Invoice Date missing!'       => 'îÅ ÕËÁÚÁÎÁ ÄÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number'              => 'îÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number missing!'     => 'îÅ ÕËÁÚÁΠÎÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => 'Produkt nie jest w zbiorze!',
+  'Jan'                         => 'ñÎ×',
+  'January'                     => 'ñÎ×ÁÒØ',
+  'Jul'                         => 'éÀÌ',
+  'July'                        => 'éÀÌØ',
+  'Jun'                         => 'éÀÎ',
+  'June'                        => 'éÀÎØ',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'Name'                        => 'Nazwa',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Number missing in Row'       => 'Brak Numeru w Rzêdzie',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Order'                       => 'Zamówienie',
+  'Order Date missing!'         => 'Brak Daty Zamówienia',
+  'Order Number'                => 'Numer Zamówienia',
+  'Order Number missing!'       => 'Brak Numeru Zamówienia',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Packing List Date missing!'  => 'Brak Daty Wykazu Dostawy',
+  'Packing List Number missing!' => 'Brak Numeru Wykazu Dostawy',
+  'Part'                        => 'Produkt',
+  'Payment date missing!'       => 'Brak Daty P³atno¶ci',
+  'Payments'                    => 'Rozliczenia P³atno¶ci',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena Netto',
+  'Printer'                     => 'Drukarka',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Qty'                         => 'Ilo¶æ',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'ïÔÎÅÓÔÉ ÎÁ ÓÞÅÔ',
+  'Required by'                 => 'Termin Dostawy',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Screen'                      => 'Ekran',
+  'Select from one of the items below' => 'Wybie¿ jeden z poni¿szych artyku³ów',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'óÅÎ',
+  'September'                   => 'óÅÎÔÑÂÒØ',
+  'Service'                     => 'õÓÌÕÇÁ',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Source'                      => '¯ród³o',
+  'Subject'                     => 'ôÅÍÁ',
+  'Subtotal'                    => 'éÔÏÇÏ ÐÏ ÒÁÚÄÅÌÕ',
+  'Tax Included'                => 'Podatek Wliczony',
+  'To'                          => 'do',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Unit'                        => 'Jednostka',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Dostawca',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'Co to za rodzaj artyku³u',
+  'Yes'                         => 'Tak',
+  'ea'                          => 'szt',
+  'emailed to'                  => 'email do',
+  'sent to printer'             => 'wys³ano do drukarki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'õÄÁÌÉÔØ'                     => 'delete',
+  'zamówienie'                  => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'update'                      => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/is b/sql-ledger/locale/ru/is
new file mode 100644 (file)
index 0000000..a4a4621
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'óÞÅÔ',
+  'Add Purchase Order'          => 'îÏ×ÙÊ ÚÁËÁÚ ÐÏÓÔÁ×ÝÉËÁ',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'îÏ×ÙÊ ÚÁËÁÚ ËÌÉÅÎÔÁ',
+  'Address'                     => 'áÄÒÅÓ',
+  'Amount'                      => 'óÕÍÍÁ',
+  'Apr'                         => 'áÐÒ',
+  'April'                       => 'áÐÒÅÌØ',
+  'Are you sure you want to delete Invoice Number' => '÷Ù Õ×ÅÒÅÎÙ, ÞÔÏ ÈÏÔÉÔÅ ÕÄÁÌÉÔØ ÄÁÎÎÙÊ ÓÞÅÔ?',
+  'Attachment'                  => '÷ÌÏÖÅÎÉÅ',
+  'Aug'                         => 'á×Ç',
+  'August'                      => 'á×ÇÕÓÔ',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'Nie mo¿na zksiêgowaæ faktury pozamkniêciu okresu',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'Nie mo¿na zaksiêgowaæ p³atno¶ci po zamkniêciu okresu!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'ðÏÄÔ×ÅÒÄÉÔØ!',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÏÅ ÌÉÃÏ',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Copies'                      => 'ëÏÐÉÊ',
+  'Credit Limit'                => 'ìÉÍÉÔ ËÒÅÄÉÔÁ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Customer'                    => 'ëÌÉÅÎÔ',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'äÁÔÁ',
+  'Date Due'                    => 'ïÐÌÁÔÉÔØ ÄÏ',
+  'Dec'                         => 'äÅË',
+  'December'                    => 'äÅËÁÂÒØ',
+  'Delete'                      => 'õÄÁÌÉÔØ',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'îÅ ÕËÁÚÁΠÁÄÒÅÓ E-mail!',
+  'Edit Sales Invoice'          => 'Edit Sales Invoice',
+  'Exch'                        => 'Kurs',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'Exchangerate for payment missing!' => 'Brakuje kursu wymiany dla p³atno¶ci!',
+  'Exchangerate missing!'       => 'Brakuje kursu wymiany',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'In-line'                     => 'W³±czony',
+  'Invoice'                     => 'óÞÅÔ-ÆÁËÔÕÒÁ',
+  'Invoice Date'                => 'äÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ',
+  'Invoice Date missing!'       => 'îÅ ÕËÁÚÁÎÁ ÄÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number'              => 'îÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number missing!'     => 'îÅ ÕËÁÚÁΠÎÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => 'Produkt nie jest w zbiorze!',
+  'Jan'                         => 'ñÎ×',
+  'January'                     => 'ñÎ×ÁÒØ',
+  'Jul'                         => 'éÀÌ',
+  'July'                        => 'éÀÌØ',
+  'Jun'                         => 'éÀÎ',
+  'June'                        => 'éÀÎØ',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'Name'                        => 'Nazwa',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Number missing in Row'       => 'Brak Numeru w Rzêdzie',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Order'                       => 'Zamówienie',
+  'Order Date missing!'         => 'Brak Daty Zamówienia',
+  'Order Number'                => 'Numer Zamówienia',
+  'Order Number missing!'       => 'Brak Numeru Zamówienia',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Packing List Date missing!'  => 'Brak Daty Wykazu Dostawy',
+  'Packing List Number missing!' => 'Brak Numeru Wykazu Dostawy',
+  'Part'                        => 'Produkt',
+  'Payment date missing!'       => 'Brak Daty P³atno¶ci',
+  'Payments'                    => 'Rozliczenia P³atno¶ci',
+  'Phone'                       => 'Tel.',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena Netto',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Drukarka',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Qty'                         => 'Ilo¶æ',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'ïÔÎÅÓÔÉ ÎÁ ÓÞÅÔ',
+  'Remaining'                   => 'Pozosta³e',
+  'Required by'                 => 'Termin Dostawy',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Screen'                      => 'Ekran',
+  'Select from one of the items below' => 'Wybie¿ jeden z poni¿szych artyku³ów',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'óÅÎ',
+  'September'                   => 'óÅÎÔÑÂÒØ',
+  'Service'                     => 'õÓÌÕÇÁ',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Source'                      => '¯ród³o',
+  'Subject'                     => 'ôÅÍÁ',
+  'Subtotal'                    => 'éÔÏÇÏ ÐÏ ÒÁÚÄÅÌÕ',
+  'Tax Included'                => 'Podatek Wliczony',
+  'To'                          => 'do',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Unit'                        => 'Jednostka',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'Co to za rodzaj artyku³u',
+  'Yes'                         => 'Tak',
+  'ea'                          => 'szt',
+  'emailed to'                  => 'email do',
+  'sent to printer'             => 'wys³ano do drukarki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'õÄÁÌÉÔØ'                     => 'delete',
+  'e_mail'                      => 'e_mail',
+  'zamówienie'                  => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/login b/sql-ledger/locale/ru/login
new file mode 100644 (file)
index 0000000..4ff4eff
--- /dev/null
@@ -0,0 +1,28 @@
+$self{texts} = {
+  'About'                       => 'ï ÐÒÏÇÒÁÍÍÅ',
+  'Accounting'                  => 'Accounting',
+  'Database Host'               => 'Wêze³ Bazy Danych',
+  'Dataset'                     => 'Zbiór Danych',
+  'Incorrect Dataset version!'  => 'Nieprawid³owa wersja Zbioru Danych',
+  'Incorrect Password!'         => 'Nieprawid³owe Has³o',
+  'Licensed to'                 => 'ìÉÃÅÎÚÉÅÊ ÏÂÌÁÄÁÅÔ:',
+  'Login'                       => 'Zarejestrój siê',
+  'Name'                        => 'Nazwa',
+  'Password'                    => 'Has³o',
+  'User'                        => 'U¿ytkownik',
+  'Version'                     => '÷ÅÒÓÉÑ',
+  'You are logged out!'         => 'You are logged out!',
+  'You did not enter a name!'   => 'Nie wstawiono nazwy!',
+  'is not a member!'            => 'Nie jest cz³onkiem',
+  'localhost'                   => 'wêze³',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'zarejestrój_siê'             => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/menu b/sql-ledger/locale/ru/menu
new file mode 100644 (file)
index 0000000..af96c02
--- /dev/null
@@ -0,0 +1,72 @@
+$self{texts} = {
+  'AP'                          => 'òÁÓÈÏÄ',
+  'AP Aging'                    => 'AP Aging',
+  'AR'                          => 'äÏÈÏÄ',
+  'AR Aging'                    => 'AR Aging',
+  'Accounting Menu'             => 'Accounting Menu',
+  'Add Account'                 => 'îÏ×ÙÊ ÓÞÅÔ',
+  'Add Assembly'                => 'îÏ×ÙÊ ËÏÍÐÌÅËÔ',
+  'Add Customer'                => 'îÏ×ÙÊ ËÌÉÅÎÔ',
+  'Add GIFI'                    => 'îÏ×ÙÊ GIFI',
+  'Add Part'                    => 'îÏ×ÙÊ ÐÒÏÄÕËÔ',
+  'Add Project'                 => 'Add Project',
+  'Add Service'                 => 'îÏ×ÁÑ ÕÓÌÕÇÁ',
+  'Add Transaction'             => 'îÏ×ÁÑ ÐÒÏ×ÏÄËÁ',
+  'Add Vendor'                  => 'îÏ×ÙÊ ÐÏÓÔÁ×ÝÉË',
+  'Assemblies'                  => 'ëÏÍÐÌÅËÔÙ',
+  'Audit Control'               => 'ëÏÎÔÒÏÌØ',
+  'Backup'                      => 'òÅÚÅÒ×ÎÁÑ ËÏÐÉÑ',
+  'Balance Sheet'               => 'âÁÌÁÎÓ',
+  'Cash'                        => 'Cash',
+  'Chart of Accounts'           => 'ðÌÁΠÓÞÅÔÏ×',
+  'Check'                       => 'Check',
+  'Customers'                   => 'Customers',
+  'General Ledger'              => 'Ksiêga G³ówna',
+  'Goods & Services'            => 'Produkty i Us³ugi',
+  'HTML Templates'              => 'Szablony HTML',
+  'Income Statement'            => 'Rachunek Zysków i Strat',
+  'Invoice'                     => 'óÞÅÔ-ÆÁËÔÕÒÁ',
+  'LaTeX Templates'             => 'Szablony LaTeX',
+  'List Accounts'               => 'Spis Kont',
+  'List GIFI'                   => 'Wykaz GIFI',
+  'Logout'                      => 'Wyrejestrój siê',
+  'Order Entry'                 => 'Wystawianie Zamówieñ',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Parts'                       => 'Produkty',
+  'Payment'                     => 'P³atno¶æ',
+  'Payments'                    => 'Rozliczenia P³atno¶ci',
+  'Preferences'                 => 'Preferencje',
+  'Projects'                    => 'Projects',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Purchase Orders'             => 'Zamówienia Zakupu',
+  'Receipt'                     => 'Receipt',
+  'Receipts'                    => 'Receipts',
+  'Reconciliation'              => 'Reconciliation',
+  'Reports'                     => 'Sprawozdania',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Sales Orders'                => 'Zamówienia Klientów',
+  'Save to File'                => 'Zapisz w zbiorze',
+  'Send by E-Mail'              => 'Wys³ano przy u¿yciu E-Mail',
+  'Services'                    => 'õÓÌÕÇÉ',
+  'Statement'                   => 'Statement',
+  'Stock Assembly'              => 'Wstaw Z³o¿enie',
+  'Stylesheet'                  => 'ïÆÏÒÍÌÅÎÉÅ',
+  'System'                      => 'óÉÓÔÅÍÁ',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'Transactions'                => 'Transakcje',
+  'Trial Balance'               => 'Bilans Porównawczy',
+  'Vendors'                     => 'Vendors',
+  'Version'                     => '÷ÅÒÓÉÑ',
+  'localhost'                   => 'wêze³',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/oe b/sql-ledger/locale/ru/oe
new file mode 100644 (file)
index 0000000..24b26df
--- /dev/null
@@ -0,0 +1,199 @@
+$self{texts} = {
+  'Add'                         => 'îÏ×ÙÊ',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => 'îÏ×ÙÊ ÚÁËÁÚ ÐÏÓÔÁ×ÝÉËÁ',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'îÏ×ÙÊ ÚÁËÁÚ ËÌÉÅÎÔÁ',
+  'Address'                     => 'áÄÒÅÓ',
+  'Amount'                      => 'óÕÍÍÁ',
+  'Apr'                         => 'áÐÒ',
+  'April'                       => 'áÐÒÅÌØ',
+  'Are you sure you want to delete Order Number' => '÷Ù Õ×ÅÒÅÎÙ, ÞÔÏ ÈÏÔÉÔÅ ÕÄÁÌÉÔØ ÄÁÎÎÙÊ ÚÁËÁÚ?',
+  'Attachment'                  => '÷ÌÏÖÅÎÉÅ',
+  'Aug'                         => 'á×Ç',
+  'August'                      => 'á×ÇÕÓÔ',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Cannot delete order!',
+  'Cannot save order!'          => 'Cannot save order!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'úÁËÒÙÔ',
+  'Confirm!'                    => 'ðÏÄÔ×ÅÒÄÉÔØ!',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÏÅ ÌÉÃÏ',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Copies'                      => 'ëÏÐÉÊ',
+  'Credit Limit'                => 'ìÉÍÉÔ ËÒÅÄÉÔÁ',
+  'Curr'                        => '÷ÁÌÀÔÁ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Customer'                    => 'ëÌÉÅÎÔ',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'äÁÔÁ',
+  'Dec'                         => 'äÅË',
+  'December'                    => 'äÅËÁÂÒØ',
+  'Delete'                      => 'õÄÁÌÉÔØ',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'îÅ ÕËÁÚÁΠÁÄÒÅÓ E-mail!',
+  'Edit Purchase Order'         => 'Zmiany Zamówienia Zakupu',
+  'Edit Sales Order'            => 'Zmiany Zamówienia Klienta',
+  'Exchangerate'                => 'Kurs Wymiany',
+  'Exchangerate missing!'       => 'Brakuje kursu wymiany',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'ID'                          => 'Identyfikator',
+  'In-line'                     => 'W³±czony',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Invoice'                     => 'óÞÅÔ-ÆÁËÔÕÒÁ',
+  'Invoice Date missing!'       => 'îÅ ÕËÁÚÁÎÁ ÄÁÔÁ ×ÙÓÔÁ×ÌÅÎÉÑ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Invoice Number missing!'     => 'îÅ ÕËÁÚÁΠÎÏÍÅÒ ÓÞÅÔÁ-ÆÁËÔÕÒÙ',
+  'Item not on file!'           => 'Produkt nie jest w zbiorze!',
+  'Jan'                         => 'ñÎ×',
+  'January'                     => 'ñÎ×ÁÒØ',
+  'Jul'                         => 'éÀÌ',
+  'July'                        => 'éÀÌØ',
+  'Jun'                         => 'éÀÎ',
+  'June'                        => 'éÀÎØ',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'Name'                        => 'Nazwa',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Noty',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Number'                      => 'Numer Katalogu',
+  'Number missing in Row'       => 'Brak Numeru w Rzêdzie',
+  'O'                           => 'O',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'Open'                        => 'Otwórz',
+  'Order'                       => 'Zamówienie',
+  'Order Date'                  => 'Data Zamówienia',
+  'Order Date missing!'         => 'Brak Daty Zamówienia',
+  'Order Number'                => 'Numer Zamówienia',
+  'Order Number missing!'       => 'Brak Numeru Zamówienia',
+  'Order deleted!'              => 'Order deleted!',
+  'Order saved!'                => 'Order saved!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Wykaz Dostawy',
+  'Packing List Date missing!'  => 'Brak Daty Wykazu Dostawy',
+  'Packing List Number missing!' => 'Brak Numeru Wykazu Dostawy',
+  'Part'                        => 'Produkt',
+  'Phone'                       => 'Tel.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Cena Netto',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Drukarka',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Zamówienie Zakupu',
+  'Purchase Orders'             => 'Zamówienia Zakupu',
+  'Qty'                         => 'Ilo¶æ',
+  'Recd'                        => 'Recd',
+  'Remaining'                   => 'Pozosta³e',
+  'Required by'                 => 'Termin Dostawy',
+  'Sales Order'                 => 'Zamówienie Klienta',
+  'Sales Orders'                => 'Zamówienia Klientów',
+  'Save'                        => 'Zapisz',
+  'Save as new'                 => 'Save as new',
+  'Screen'                      => 'Ekran',
+  'Select from one of the items below' => 'Wybie¿ jeden z poni¿szych artyku³ów',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'óÅÎ',
+  'September'                   => 'óÅÎÔÑÂÒØ',
+  'Service'                     => 'õÓÌÕÇÁ',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Subject'                     => 'ôÅÍÁ',
+  'Subtotal'                    => 'éÔÏÇÏ ÐÏ ÒÁÚÄÅÌÕ',
+  'Tax'                         => 'îÁÌÏÇ',
+  'Tax Included'                => 'Podatek Wliczony',
+  'Terms: Net'                  => 'Warunki: Netto',
+  'To'                          => 'do',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Unit'                        => 'Jednostka',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Dostawca',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'Co to za rodzaj artyku³u',
+  'Yes'                         => 'Tak',
+  'days'                        => 'dni',
+  'ea'                          => 'szt',
+  'emailed to'                  => 'email do',
+  'sent to printer'             => 'wys³ano do drukarki',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'îÏ×ÙÊ'                       => 'add',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'õÄÁÌÉÔØ'                     => 'delete',
+  'e_mail'                      => 'e_mail',
+  'óÞÅÔ_ÆÁËÔÕÒÁ'                => 'invoice',
+  'print'                       => 'print',
+  'zapisz'                      => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/pe b/sql-ledger/locale/ru/pe
new file mode 100644 (file)
index 0000000..2505a26
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'îÏ×ÙÊ',
+  'Add Project'                 => 'Add Project',
+  'All'                         => '÷ÓÅ',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Delete'                      => 'õÄÁÌÉÔØ',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'Edit Project'                => 'Edit Project',
+  'Number'                      => 'Numer Katalogu',
+  'Orphaned'                    => 'Zbêdny',
+  'Project'                     => 'Project',
+  'Project Number missing!'     => 'Project Number missing!',
+  'Project deleted!'            => 'Project deleted!',
+  'Project saved!'              => 'Project saved!',
+  'Projects'                    => 'Projects',
+  'Save'                        => 'Zapisz',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'îÏ×ÙÊ'                       => 'add',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'õÄÁÌÉÔØ'                     => 'delete',
+  'zapisz'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/rc b/sql-ledger/locale/ru/rc
new file mode 100644 (file)
index 0000000..a14f22a
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'óÞÅÔ',
+  'Balance'                     => 'Balance',
+  'Cleared Balance'             => 'Cleared Balance',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Date'                        => 'äÁÔÁ',
+  'Deposit'                     => 'Deposit',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'Difference'                  => 'Difference',
+  'Done'                        => 'Done',
+  'Exchangerate Difference'     => 'Exchangerate Difference',
+  'From'                        => 'Od',
+  'Out of balance!'             => 'Out of balance!',
+  'Payment'                     => 'P³atno¶æ',
+  'Reconciliation'              => 'Reconciliation',
+  'Select all'                  => 'Select all',
+  'Source'                      => '¯ród³o',
+  'Statement Balance'           => 'Statement Balance',
+  'To'                          => 'do',
+  'Update'                      => 'Update',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'done'                        => 'done',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ru/rp b/sql-ledger/locale/ru/rp
new file mode 100644 (file)
index 0000000..acea23f
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'AP Aging',
+  'AR Aging'                    => 'AR Aging',
+  'Account'                     => 'óÞÅÔ',
+  'Accounts'                    => 'óÞÅÔÁ',
+  'Amount'                      => 'óÕÍÍÁ',
+  'Apr'                         => 'áÐÒ',
+  'April'                       => 'áÐÒÅÌØ',
+  'Attachment'                  => '÷ÌÏÖÅÎÉÅ',
+  'Aug'                         => 'á×Ç',
+  'August'                      => 'á×ÇÕÓÔ',
+  'Balance Sheet'               => 'âÁÌÁÎÓ',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Cash based',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'óÒÁ×ÎÉÔØ Ó',
+  'Continue'                    => 'ðÒÏÄÏÌÖÉÔØ',
+  'Copies'                      => 'ëÏÐÉÊ',
+  'Credit'                      => 'ëÒÅÄÉÔ',
+  'Current'                     => 'Current',
+  'Customer'                    => 'ëÌÉÅÎÔ',
+  'Date'                        => 'äÁÔÁ',
+  'Debit'                       => 'äÅÂÅÔ',
+  'Dec'                         => 'äÅË',
+  'December'                    => 'äÅËÁÂÒØ',
+  'Decimalplaces'               => 'Decimalplaces',
+  'Description'                 => 'ïÐÉÓÁÎÉÅ',
+  'Due'                         => 'äÏ',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'E-mail Statement to',
+  'Feb'                         => 'Luty',
+  'February'                    => 'Luty',
+  'From'                        => 'Od',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'òÁÚÄÅÌ',
+  'ID'                          => 'Identyfikator',
+  'In-line'                     => 'W³±czony',
+  'Include in Report'           => 'Do³±cz w Sprawozdaniu',
+  'Income Statement'            => 'Rachunek Zysków i Strat',
+  'Invoice'                     => 'óÞÅÔ-ÆÁËÔÕÒÁ',
+  'Jan'                         => 'ñÎ×',
+  'January'                     => 'ñÎ×ÁÒØ',
+  'Jul'                         => 'éÀÌ',
+  'July'                        => 'éÀÌØ',
+  'Jun'                         => 'éÀÎ',
+  'June'                        => 'éÀÎØ',
+  'Mar'                         => 'Marzec',
+  'March'                       => 'Marzec',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Wiadomo¶æ',
+  'N/A'                         => 'N/A',
+  'Nothing selected!'           => 'Nothing selected!',
+  'Nov'                         => 'Listopad',
+  'November'                    => 'Listopad',
+  'Oct'                         => 'Pa¿dziernik',
+  'October'                     => 'Pa¿dziernik',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Rozliczenia P³atno¶ci',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Drukarka',
+  'Receipts'                    => 'Receipts',
+  'Report for'                  => 'Raport dla',
+  'Retained Earnings'           => 'Zysk',
+  'Screen'                      => 'Ekran',
+  'Select all'                  => 'Select all',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'óÅÎ',
+  'September'                   => 'óÅÎÔÑÂÒØ',
+  'Source'                      => '¯ród³o',
+  'Standard'                    => 'óÔÁÎÄÁÒÔÎÙÅ',
+  'Statement'                   => 'Statement',
+  'Statement sent to'           => 'Statement sent to',
+  'Statements sent to printer!' => 'Statements sent to printer!',
+  'Subject'                     => 'ôÅÍÁ',
+  'Subtotal'                    => 'éÔÏÇÏ ÐÏ ÒÁÚÄÅÌÕ',
+  'Tax'                         => 'îÁÌÏÇ',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'To'                          => 'do',
+  'Total'                       => 'Warto¶æ Brutto',
+  'Trial Balance'               => 'Bilans Porównawczy',
+  'Vendor'                      => 'Dostawca',
+  'as at'                       => 'as at',
+  'collected on sales'          => 'zebranego przy sprzeda¿y',
+  'for Period'                  => 'za Okres',
+  'paid on purchases'           => 'zap³aconego przy zakupach',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'ðÒÏÄÏÌÖÉÔØ'                  => 'continue',
+  'e_mail'                      => 'e_mail',
+  'print'                       => 'print',
+  'select_all'                  => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/se/COPYING b/sql-ledger/locale/se/COPYING
new file mode 100644 (file)
index 0000000..5e4eee3
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2002
+#
+# Swedish texts:
+#
+#  Author: jonny@lernbo.com
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/se/LANGUAGE b/sql-ledger/locale/se/LANGUAGE
new file mode 100644 (file)
index 0000000..e375393
--- /dev/null
@@ -0,0 +1 @@
+Swedish
diff --git a/sql-ledger/locale/se/admin b/sql-ledger/locale/se/admin
new file mode 100644 (file)
index 0000000..5b8e140
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Accesskontroll',
+  'Accounting'                  => 'Bokföring',
+  'Add User'                    => 'Ny användare',
+  'Address'                     => 'Adress',
+  'Administration'              => 'Administration',
+  'Administrator'               => 'Administratör',
+  'All Datasets up to date!'    => 'Alla dataset uppdaterade',
+  'Change Admin Password'       => 'Ändra lösenord för admin',
+  'Change Password'             => 'Ändra lösenord',
+  'Character Set'               => 'Teckenuppsättning',
+  'Click on login name to edit!' => 'Klicka på användarnamn för att redigera!',
+  'Company'                     => 'Företag',
+  'Connect to'                  => 'Anslut till',
+  'Continue'                    => 'Fortsätt',
+  'Create Chart of Accounts'    => 'Skapa kontoplan',
+  'Create Dataset'              => 'Skapa dataset',
+  'DBI not installed!'          => 'DBI inte installerad',
+  'Database'                    => 'Databas',
+  'Database Administration'     => 'Administration av databas',
+  'Database Driver not checked!' => 'Databasedriver icke kontrollerad',
+  'Database User missing!'      => 'Databasanvändare saknas',
+  'Dataset'                     => 'Dataset',
+  'Dataset missing!'            => 'Dataset saknas',
+  'Dataset updated!'            => 'Dataset uppdaterat',
+  'Date Format'                 => 'Datumformat',
+  'Delete'                      => 'Radera',
+  'Delete Dataset'              => 'Radera dataset',
+  'Directory'                   => 'Katalog',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Dropdown gräns',
+  'E-mail'                      => 'E-Post',
+  'Edit User'                   => 'Redigera användare',
+  'Existing Datasets'           => 'Existerande Dataset',
+  'Fax'                         => 'Fax',
+  'File locked!'                => 'Fil låst',
+  'Host'                        => 'Värd',
+  'Hostname missing!'           => 'Värdnamn saknas',
+  'Incorrect Password!'         => 'Felaktigt lösenord',
+  'Language'                    => 'Språk',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Lämna värd och port fälten tomma om du inte vill göra en fjärranslutning',
+  'Login'                       => 'Logga in',
+  'Multibyte Encoding'          => 'Multibytekodning',
+  'Name'                        => 'Namn',
+  'New Templates'               => 'Ny mall',
+  'No Database Drivers available!' => 'Inga databasdrivers tillgängliga',
+  'No Dataset selected!'        => 'Inget Dataset valt',
+  'Nothing to delete!'          => 'Inget att radera',
+  'Number Format'               => 'Nummerformat',
+  'Oracle Database Administration' => 'Oracle Databasadministration',
+  'Password'                    => 'Lösenord',
+  'Password changed!'           => 'Lösenord ändrat',
+  'Pg Database Administration'  => 'Administration av databas PG',
+  'Phone'                       => 'Telefon',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port saknas',
+  'Printer'                     => 'Skrivare',
+  'Save'                        => 'Spara',
+  'Select a Dataset to delete and press "Continue"' => 'Välj en databas att radera och klicka på "Fortsätt"',
+  'Setup Templates'             => 'Sätt upp mallar',
+  'Ship via'                    => 'Skicka via',
+  'Signature'                   => 'Signatur',
+  'Stylesheet'                  => 'Stilmall',
+  'Templates'                   => 'Mallar',
+  'The following Datasets are not in use and can be deleted' => 'Följande Dataset är inte i bruk och kan raderas',
+  'The following Datasets need to be updated' => 'Följande Dataset behöver uppdateras',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Det här är en preliminär kontroll av existerande källor. Ingenting kommer att sparas eller raderas vid detta tillfälle',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'För att lägga till en användare till en grupp, editera namnet, ändra login namnet och spara. En ny användare med samma variabler sparas då under det nya namnet.',
+  'Update Dataset'              => 'Uppdatera dataset',
+  'Use Templates'               => 'Använd mallar',
+  'User'                        => 'Användare',
+  'User deleted!'               => 'Användare raderad',
+  'User saved!'                 => 'Användare sparad',
+  'Version'                     => 'Version',
+  'You must enter a host and port for local and remote connections!' => 'Du måste ange en värd och en port för att göra en fjärrsnslutning',
+  'does not exist'              => 'finns inte',
+  'is already a member!'        => 'är redan medlem!',
+  'localhost'                   => 'localhost',
+  'successfully created!'       => 'skapades',
+  'successfully deleted!'       => 'raderades',
+  'website'                     => 'website',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'ny_användare'                => 'add_user',
+  'Ändra_lösenord_för_admin'    => 'change_admin_password',
+  'Ändra_lösenord'              => 'change_password',
+  'fortsätt'                    => 'continue',
+  'skapa_dataset'               => 'create_dataset',
+  'radera'                      => 'delete',
+  'radera_dataset'              => 'delete_dataset',
+  'logga_in'                    => 'login',
+  'oracle_databasadministration' => 'oracle_database_administration',
+  'administration_av_databas_pg' => 'pg_database_administration',
+  'spara'                       => 'save',
+  'uppdatera_dataset'           => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/se/all b/sql-ledger/locale/se/all
new file mode 100644 (file)
index 0000000..dc1dd2d
--- /dev/null
@@ -0,0 +1,491 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Kredit',
+  'AP Aging'                    => 'Kredit åldersfördeling',
+  'AP Transaction'              => 'Kredit verifikat',
+  'AP Transactions'             => 'Kredit verifikationer',
+  'AR'                          => 'Debet',
+  'AR Aging'                    => 'Debet åldersfördeling',
+  'AR Transaction'              => 'Debet verifikat',
+  'AR Transactions'             => 'Debet verifikationer',
+  'About'                       => 'Om',
+  'Access Control'              => 'Accesskontroll',
+  'Account'                     => 'Konto',
+  'Account Number'              => 'Kontonummer',
+  'Account Number missing!'     => 'Kontonummer saknas',
+  'Account Type'                => 'Kontotyp',
+  'Account Type missing!'       => 'Kontotyp saknas!',
+  'Account deleted!'            => 'Konto raderat!',
+  'Account saved!'              => 'Konto sparat!',
+  'Accounting'                  => 'Bokföring',
+  'Accounting Menu'             => 'Konto-meny',
+  'Accounts'                    => 'Konton',
+  'Active'                      => 'Aktiv',
+  'Add'                         => 'Lägg til',
+  'Add Account'                 => 'Nytt konto',
+  'Add Accounts Payables Transaction' => 'Lägg till kreditverifikat',
+  'Add Accounts Receivables Transaction' => 'Lägg till debetverifikat',
+  'Add Assembly'                => 'Ny sammansätting',
+  'Add Customer'                => 'Ny kund',
+  'Add GIFI'                    => 'Ny GIFI',
+  'Add General Ledger Transaction' => 'Ny post i huvudbok',
+  'Add Part'                    => 'Ny vara',
+  'Add Project'                 => 'Nytt projekt',
+  'Add Purchase Invoice'        => 'Ny inköpsfaktura',
+  'Add Purchase Order'          => 'Ny inköpsorder',
+  'Add Sales Invoice'           => 'Ny säljfaktura',
+  'Add Sales Order'             => 'Ny säljorder',
+  'Add Service'                 => 'Ny tjänst',
+  'Add Transaction'             => 'Ny post',
+  'Add User'                    => 'Ny användare',
+  'Add Vendor'                  => 'Ny leverantör',
+  'Address'                     => 'Adress',
+  'Administration'              => 'Administration',
+  'Administrator'               => 'Administratör',
+  'All'                         => 'Alla',
+  'All Datasets up to date!'    => 'Alla dataset uppdaterade',
+  'Amount'                      => 'Belopp',
+  'Amount Due'                  => 'Belopp förfallet',
+  'Amount does not equal applied!' => 'Förfallet belopp stämmer ej med det tillagda',
+  'Amount missing!'             => 'Summa saknas',
+  'Applied'                     => 'Tillagt',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Invoice Number' => 'Är du säker på att du vill radera Faktura Nummer',
+  'Are you sure you want to delete Order Number' => 'Är du säker på att du vill radera Order Nummer',
+  'Are you sure you want to delete Transaction' => 'Är du säker på att du vill radera Transaktionen',
+  'Assemblies'                  => 'Sammansättningar',
+  'Assemblies restocked!'       => 'Sammansättningar åter i lager',
+  'Assembly Number missing!'    => 'Sammansättningsnummer saknas',
+  'Asset'                       => 'Tillgång',
+  'Attachment'                  => 'Bilaga',
+  'Audit Control'               => 'Revisionskontroll',
+  'Aug'                         => 'aug',
+  'August'                      => 'augusti',
+  'BOM'                         => 'BOM',
+  'Backup'                      => 'Säkerhetkopia',
+  'Backup sent to'              => 'Säkerhetskopia har sänts till',
+  'Balance'                     => 'Balans',
+  'Balance Sheet'               => 'Status',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Antal i lager',
+  'Books are open'              => 'Bokföringen är öppen för rättning',
+  'Bought'                      => 'Köpt',
+  'Business Number'             => 'Organisationsnummer',
+  'C'                           => 'C',
+  'COGS'                        => 'Inköp',
+  'Cannot delete account!'      => 'Kan inte radera konto',
+  'Cannot delete customer!'     => 'Kan inte radera kund',
+  'Cannot delete default account!' => 'Kan inte radera standardkonto',
+  'Cannot delete invoice!'      => 'Kan inte radera faktura',
+  'Cannot delete item already invoiced!' => 'Kan inte radera redan fakturerade varor!',
+  'Cannot delete item on order!' => 'Kan inte radera vara i order!',
+  'Cannot delete item which is part of an assembly!' => 'Kan inte radera vara som är del av en sammansättning!',
+  'Cannot delete item!'         => 'Kan inte radera vara',
+  'Cannot delete order!'        => 'Kan inte radera order',
+  'Cannot delete transaction!'  => 'Kan inte radera händelse',
+  'Cannot delete vendor!'       => 'Kan inte radera Leverantör',
+  'Cannot have a value in both Debit and Credit!' => 'Kan inte ha värde i både Debet och Kredit!',
+  'Cannot post a transaction without a value!' => 'Kan inte lägga till en händelse utan ett värde',
+  'Cannot post invoice for a closed period!' => 'Kan inte lägga till en faktura för en avslutad period',
+  'Cannot post invoice!'        => 'Kan inte lägga till faktura',
+  'Cannot post payment for a closed period!' => 'Kan inte lägga till en betalning för en stängd period',
+  'Cannot post payment!'        => 'Kan inte lägga till betalning',
+  'Cannot post transaction for a closed period!' => 'Kan inte bokföra för en stängd period',
+  'Cannot post transaction!'    => 'Kan inte lägga till händelsen',
+  'Cannot process payment for a closed period!' => 'Kan inte processa betalning för en avslutad period',
+  'Cannot save account!'        => 'Kan inte spara konto',
+  'Cannot save order!'          => 'Kan inte spara order',
+  'Cannot save preferences!'    => 'Kan inte spara preferenser',
+  'Cannot stock assemblies!'    => 'Kan lagerföra sammansättningar',
+  'Cash'                        => 'Kontant',
+  'Cash based'                  => 'Kontantbaserad',
+  'Cc'                          => 'Kopia',
+  'Change Admin Password'       => 'Ändra lösenord för admin',
+  'Change Password'             => 'Ändra lösenord',
+  'Character Set'               => 'Teckenuppsättning',
+  'Chart of Accounts'           => 'Kontoplan',
+  'Check'                       => 'Check',
+  'Check printed!'              => 'Check utskriven',
+  'Check printing failed!'      => 'Utskrift av check misslyckades',
+  'Cleared Balance'             => 'Rensade balans',
+  'Click on login name to edit!' => 'Klicka på användarnamn för att redigera!',
+  'Close Books up to'           => 'Avsluta bokföring fram till och med',
+  'Closed'                      => 'Avslutad',
+  'Company'                     => 'Företag',
+  'Compare to'                  => 'Jämför med',
+  'Confirm!'                    => 'Bekräfta',
+  'Connect to'                  => 'Anslut till',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsätt',
+  'Copies'                      => 'Kopior',
+  'Copy to COA'                 => 'Kopiera till COA',
+  'Create Chart of Accounts'    => 'Skapa kontoplan',
+  'Create Dataset'              => 'Skapa dataset',
+  'Credit'                      => 'Kredit',
+  'Credit Limit'                => 'Kreditgräns',
+  'Curr'                        => 'Val',
+  'Currency'                    => 'Valuta',
+  'Current'                     => 'Nuvarande',
+  'Customer'                    => 'Kund',
+  'Customer deleted!'           => 'Kund raderad',
+  'Customer missing!'           => 'Kund saknas',
+  'Customer not on file!'       => 'Kund finns ej',
+  'Customer saved!'             => 'Kund sparad',
+  'Customers'                   => 'Kunder',
+  'DBI not installed!'          => 'DBI inte installerad',
+  'Database'                    => 'Databas',
+  'Database Administration'     => 'Administration av databas',
+  'Database Driver not checked!' => 'Databasedriver icke kontrollerad',
+  'Database Host'               => 'Databasvärd',
+  'Database User missing!'      => 'Databasanvändare saknas',
+  'Dataset'                     => 'Dataset',
+  'Dataset missing!'            => 'Dataset saknas',
+  'Dataset updated!'            => 'Dataset uppdaterat',
+  'Date'                        => 'Datum',
+  'Date Due'                    => 'Förfallodatum',
+  'Date Format'                 => 'Datumformat',
+  'Date Paid'                   => 'Betalningsdatum',
+  'Date missing!'               => 'Datum saknas',
+  'Debit'                       => 'Debet',
+  'Debit and credit out of balance!' => 'Debet och kredit måste vara lika!',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Decimalplaces'               => 'Decimalplaceringar',
+  'Delete'                      => 'Radera',
+  'Delete Account'              => 'Radera konto',
+  'Delete Dataset'              => 'Radera dataset',
+  'Delivery Date'               => 'Leveransdatum',
+  'Deposit'                     => 'Säkerhet',
+  'Description'                 => 'Beskrivning',
+  'Difference'                  => 'Differens',
+  'Directory'                   => 'Katalog',
+  'Discount'                    => 'Rabatt',
+  'Done'                        => 'Klart',
+  'Drawing'                     => 'Ritning',
+  'Driver'                      => 'Driver',
+  'Dropdown Limit'              => 'Dropdown gräns',
+  'Due'                         => 'Förfallen',
+  'Due Date'                    => 'Förfallodatum',
+  'Due Date missing!'           => 'Förfallodatum saknas',
+  'E-mail'                      => 'E-Post',
+  'E-mail Statement to'         => 'E-Post anmaning till',
+  'E-mail address missing!'     => 'E-Postadress saknas',
+  'Edit'                        => 'Redigera',
+  'Edit Account'                => 'Redigera konto',
+  'Edit Accounts Payables Transaction' => 'Redigera kreditkonton',
+  'Edit Accounts Receivables Transaction' => 'Redigera debetkonton',
+  'Edit Assembly'               => 'Redigera sammansättning',
+  'Edit Customer'               => 'Redigera kund',
+  'Edit GIFI'                   => 'Redigera GIFI',
+  'Edit General Ledger Transaction' => 'Redigera en post i Huvudboken',
+  'Edit Part'                   => 'Redigera vara',
+  'Edit Preferences for'        => 'Redigera inställningar för',
+  'Edit Project'                => 'Redigera projekt',
+  'Edit Purchase Invoice'       => 'Redigera inköpsfakturor',
+  'Edit Purchase Order'         => 'Redigera inköpsorder',
+  'Edit Sales Invoice'          => 'Redigera säljfakturor',
+  'Edit Sales Order'            => 'Redigera säljorder',
+  'Edit Service'                => 'Redigera tjänster',
+  'Edit Template'               => 'Redigera mall',
+  'Edit User'                   => 'Redigera användare',
+  'Edit Vendor'                 => 'Redigera Leverantör',
+  'Employee'                    => 'Anställd',
+  'Enforce transaction reversal for all dates' => 'Tvinga rättelser för alla konton',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Ange upp till 3 bokstäver (SEK:EUR:USD) för egen och utländsk valuta',
+  'Equity'                      => 'Eget kapital',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Växlingskurs',
+  'Exchangerate Difference'     => 'Differens Växlingskurs',
+  'Exchangerate for payment missing!' => 'Växlingskurs för saknad betalning',
+  'Exchangerate missing!'       => 'Växelkurs saknas',
+  'Existing Datasets'           => 'Existerande Dataset',
+  'Expense'                     => 'Utgift',
+  'Expense Account'             => 'Utgiftskonto',
+  'Expense/Asset'               => 'Utgift/Tillgång',
+  'Extended'                    => 'Utökad',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'File locked!'                => 'Fil låst',
+  'Foreign Exchange Gain'       => 'Vinst på valutahandel',
+  'Foreign Exchange Loss'       => 'Förlust på valutahandel',
+  'From'                        => 'Från',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI raderad',
+  'GIFI missing!'               => 'GIFI saknas',
+  'GIFI saved!'                 => 'GIFI sparad',
+  'GL Transaction'              => 'GL händelse',
+  'General Ledger'              => 'Huvudbok',
+  'Goods & Services'            => 'Varor och Tjänster',
+  'HTML Templates'              => 'HTML mallar',
+  'Heading'                     => 'Överskrift',
+  'Host'                        => 'Värd',
+  'Hostname missing!'           => 'Värdnamn saknas',
+  'ID'                          => 'ID',
+  'Image'                       => 'Bild',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Inkludera i rapport',
+  'Include in drop-down menus'  => 'Inkludera i rullgardinsmenyer',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Inkludera det här kontot för kund/leverantör för att markera kund/leverantör som momspliktig',
+  'Income'                      => 'Intäkt',
+  'Income Account'              => 'Intäktskonto',
+  'Income Statement'            => 'Inkomstberäkning',
+  'Incorrect Dataset version!'  => 'Felaktig databasversion',
+  'Incorrect Password!'         => 'Felaktigt lösenord',
+  'Individual Items'            => 'Individuella enheter',
+  'Inventory'                   => 'Lager',
+  'Inventory Account'           => 'Lagerkonto',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Lagerkvantitet måste vara noll innan du kan sätta sammansättningen som utgången!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Lagerkvantitet måste vara noll innan du kan sätta varan som utgången!',
+  'Inventory quantity must be zero!' => 'Lagerkvantiteten måste vara noll!',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadatum',
+  'Invoice Date missing!'       => 'Fakturadatum saknas',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer saknas',
+  'Invoice deleted!'            => 'Faktura raderad',
+  'Invoice posted!'             => 'Faktura postad',
+  'Invoices'                    => 'Fakturor',
+  'Is this a summary account to record' => 'Samlingskonto för',
+  'Item deleted!'               => 'Vara raderad',
+  'Item not on file!'           => 'Varan finns inte i databasen',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'LaTeX Templates'             => 'LaTeX Mallar',
+  'Language'                    => 'Språk',
+  'Last Cost'                   => 'Senaste kostnad',
+  'Last Invoice Number'         => 'Senaste fakturanummer',
+  'Last Numbers & Default Accounts' => 'Senaste nummer och standardkonto',
+  'Last Purchase Order Number'  => 'Senaste inköpsordernummer',
+  'Last Sales Order Number'     => 'Senaste säljordernummer',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Lämna värd och port fälten tomma om du inte vill göra en fjärranslutning',
+  'Liability'                   => 'Ansvar',
+  'Licensed to'                 => 'Licensierad till',
+  'Line Total'                  => 'Antal rader',
+  'Link'                        => 'Referens',
+  'Link Accounts'               => 'Koppla konton',
+  'List Accounts'               => 'Lista konton',
+  'List GIFI'                   => 'Lista GIFI',
+  'List Price'                  => 'Inköpspris',
+  'List Transactions'           => 'Lista transaktioner',
+  'Login'                       => 'Logga in',
+  'Logout'                      => 'Logga ut',
+  'Make'                        => 'Skapa',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mars',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Meddelande',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Modell',
+  'Multibyte Encoding'          => 'Multibytekodning',
+  'N/A'                         => 'N/A',
+  'Name'                        => 'Namn',
+  'Name missing!'               => 'Namn saknas',
+  'New Templates'               => 'Ny mall',
+  'No'                          => 'Rad',
+  'No Database Drivers available!' => 'Inga databasdrivers tillgängliga',
+  'No Dataset selected!'        => 'Inget Dataset valt',
+  'No email address for'        => 'Ingen E-Postadress för',
+  'No.'                         => 'Rad',
+  'Notes'                       => 'Anmärkningar',
+  'Nothing applied!'            => 'Ingenting lades till',
+  'Nothing selected!'           => 'Ingenting valt',
+  'Nothing to delete!'          => 'Inget att radera',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number Format'               => 'Nummerformat',
+  'Number missing in Row'       => 'Nummer saknas i rad',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Utgången',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'On Hand'                     => 'I lager',
+  'On Order'                    => 'På order',
+  'Open'                        => 'Öppen',
+  'Oracle Database Administration' => 'Oracle Databasadministration',
+  'Order'                       => 'Order',
+  'Order Date'                  => 'Orderdatum',
+  'Order Date missing!'         => 'Orderdatum saknas',
+  'Order Entry'                 => 'Orderingång',
+  'Order Number'                => 'Ordernummer',
+  'Order Number missing!'       => 'Ordernummer saknas',
+  'Order deleted!'              => 'Order raderad',
+  'Order saved!'                => 'Order sparad',
+  'Ordered'                     => 'Beställt',
+  'Orphaned'                    => 'Fristående',
+  'Out of balance!'             => 'Ej i balans',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Packsedel',
+  'Packing List Date missing!'  => 'Packsedelsdatum saknas',
+  'Packing List Number missing!' => 'Packsedelsnummer saknas',
+  'Paid'                        => 'Betalt',
+  'Paid in full'                => 'Slutbetalt',
+  'Part'                        => 'Vara',
+  'Part Number missing!'        => 'Artikelnummer saknas',
+  'Parts'                       => 'Varor',
+  'Parts Inventory'             => 'Artikellista',
+  'Password'                    => 'Lösenord',
+  'Password changed!'           => 'Lösenord ändrat',
+  'Payables'                    => 'Utbetalningar',
+  'Payment'                     => 'Betalning',
+  'Payment date missing!'       => 'Betalningsdatum saknas',
+  'Payment posted!'             => 'Betalning postad',
+  'Payments'                    => 'Betalningar',
+  'Pg Database Administration'  => 'Administration av databas PG',
+  'Phone'                       => 'Telefon',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port saknas',
+  'Post'                        => 'Lägg till',
+  'Post as new'                 => 'Lägg till som ny',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Inställningar',
+  'Preferences saved!'          => 'Inställningar sparade',
+  'Price'                       => 'Pris',
+  'Print'                       => 'Skriv ut',
+  'Printer'                     => 'Skrivare',
+  'Project'                     => 'Projekt',
+  'Project Number missing!'     => 'Projektnummer saknas',
+  'Project deleted!'            => 'Projekt raderat',
+  'Project not on file!'        => 'Projekt finns ej',
+  'Project saved!'              => 'Projekt sparat',
+  'Projects'                    => 'Projekt',
+  'Purchase Invoice'            => 'Inköpsfaktura',
+  'Purchase Order'              => 'Inköpsorder',
+  'Purchase Orders'             => 'Inköpsordrar',
+  'Qty'                         => 'Antal',
+  'ROP'                         => 'Efterbeställning vid',
+  'Rate'                        => 'Rate',
+  'Recd'                        => 'Mottagen',
+  'Receipt'                     => 'Kvitto',
+  'Receipts'                    => 'Kvitton',
+  'Receivables'                 => 'Inbetalningar',
+  'Reconciliation'              => 'Bankuppgörelse',
+  'Record in'                   => 'Bokför på',
+  'Reference'                   => 'Referens',
+  'Reference missing!'          => 'Referens saknas',
+  'Remaining'                   => 'Resterar',
+  'Report for'                  => 'Rapport för',
+  'Reports'                     => 'Rapporter',
+  'Required by'                 => 'Beställt den',
+  'Retained Earnings'           => 'Realiserat överskott',
+  'Sales'                       => 'Försäljning',
+  'Sales Invoice'               => 'Säljfaktura',
+  'Sales Order'                 => 'Säljorder',
+  'Sales Orders'                => 'Säljordrar',
+  'Save'                        => 'Spara',
+  'Save as new'                 => 'Spara som ny',
+  'Save to File'                => 'Spara till fil',
+  'Screen'                      => 'Skärm',
+  'Select a Dataset to delete and press "Continue"' => 'Välj en databas att radera och klicka på "Fortsätt"',
+  'Select all'                  => 'Välj alla',
+  'Select from one of the items below' => 'Välj en artikel nedan',
+  'Select from one of the names below' => 'Välj ett av namnen nedan',
+  'Select from one of the projects below' => 'Välj ett av projekten nedan',
+  'Select postscript or PDF!'   => 'Välj Postscript eller PDF',
+  'Sell Price'                  => 'Försäljningspris',
+  'Send by E-Mail'              => 'Skicka via E-Post',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Tjänster',
+  'Service Items'               => 'Tjänsteartiklar',
+  'Service Number missing!'     => 'Tjänstenummer saknas',
+  'Services'                    => 'Tjänster',
+  'Setup Templates'             => 'Sätt upp mallar',
+  'Ship'                        => 'Skicka',
+  'Ship to'                     => 'Skicka till',
+  'Ship via'                    => 'Skicka via',
+  'Short'                       => 'Kort',
+  'Signature'                   => 'Signatur',
+  'Sold'                        => 'Såld',
+  'Source'                      => 'Källa',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Anmärkning',
+  'Statement Balance'           => 'Anmärkning status',
+  'Statement sent to'           => 'Anmärkning skickad till',
+  'Statements sent to printer!' => 'Anmärkningar skickade till skrivare',
+  'Stock Assembly'              => 'Lagersammansättning',
+  'Stylesheet'                  => 'Stilmall',
+  'Subject'                     => 'Ämne',
+  'Subtotal'                    => 'Subtotal',
+  'System'                      => 'System',
+  'Tax'                         => 'Moms',
+  'Tax Accounts'                => 'Momskonton',
+  'Tax Included'                => 'Moms ingår',
+  'Tax collected'               => 'Moms total',
+  'Tax paid'                    => 'Moms betalad',
+  'Taxable'                     => 'Momspliktigt',
+  'Template saved!'             => 'Mall sparad',
+  'Templates'                   => 'Mallar',
+  'Terms: Net'                  => 'Netto',
+  'The following Datasets are not in use and can be deleted' => 'Följande Dataset är inte i bruk och kan raderas',
+  'The following Datasets need to be updated' => 'Följande Dataset behöver uppdateras',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Det här är en preliminär kontroll av existerande källor. Ingenting kommer att sparas eller raderas vid detta tillfälle',
+  'To'                          => 'Till',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'För att lägga till en användare till en grupp, editera namnet, ändra login namnet och spara. En ny användare med samma variabler sparas då under det nya namnet.',
+  'Top Level'                   => 'Toppnivå',
+  'Total'                       => 'Total',
+  'Transaction Date missing!'   => 'Transaktionsdatum saknas',
+  'Transaction deleted!'        => 'Transaktion raderad',
+  'Transaction posted!'         => 'Transaktion sparad',
+  'Transaction reversal enforced for all dates' => 'Transaktion påtvingas för alla datum',
+  'Transaction reversal enforced up to' => 'Transaktion påtvingas upp till',
+  'Transactions'                => 'Transaktioner',
+  'Transactions exist, cannot delete customer!' => 'Transaktioner finns, kan inte radera kund',
+  'Transactions exist, cannot delete vendor!' => 'Transaktioner finns, kan inte radera leverantör',
+  'Transactions exist; cannot delete account!' => 'Transaktioner finns, kan inte radera konto',
+  'Trial Balance'               => 'Provbalans',
+  'Unit'                        => 'Enhet',
+  'Unit of measure'             => 'Måttenhet',
+  'Update'                      => 'Uppdatera',
+  'Update Dataset'              => 'Uppdatera dataset',
+  'Updated'                     => 'Uppdaterad',
+  'Use Templates'               => 'Använd mallar',
+  'User'                        => 'Användare',
+  'User deleted!'               => 'Användare raderad',
+  'User saved!'                 => 'Användare sparad',
+  'Vendor'                      => 'Leverantör',
+  'Vendor deleted!'             => 'Leverantör raderad',
+  'Vendor missing!'             => 'Leverantör saknas',
+  'Vendor not on file!'         => 'Leverantör finns ej',
+  'Vendor saved!'               => 'Leverantör sparad',
+  'Vendors'                     => 'Leverantörer',
+  'Version'                     => 'Version',
+  'Weight'                      => 'Vikt',
+  'Weight Unit'                 => 'Viktenhet',
+  'What type of item is this?'  => 'Vilken typ av artikel är detta?',
+  'Year End'                    => 'Årsslut',
+  'Yes'                         => 'Ja',
+  'You are logged out!'         => 'Du är utloggad',
+  'You did not enter a name!'   => 'Du skrev inte in något namn',
+  'You must enter a host and port for local and remote connections!' => 'Du måste ange en värd och en port för att göra en fjärrsnslutning',
+  'as at'                       => 'som vid',
+  'collected on sales'          => 'inbetalt på försäljning',
+  'days'                        => 'dagar',
+  'does not exist'              => 'finns inte',
+  'ea'                          => 'st',
+  'emailed to'                  => 'E-Postat till',
+  'for Period'                  => 'för perioden',
+  'hr'                          => 'timme',
+  'is already a member!'        => 'är redan medlem!',
+  'is not a member!'            => 'är inte medlem!',
+  'localhost'                   => 'localhost',
+  'paid on purchases'           => 'betalt vid köp',
+  'sent to printer'             => 'skickat till skrivare',
+  'successfully created!'       => 'skapades',
+  'successfully deleted!'       => 'raderades',
+  'to'                          => 'till',
+  'website'                     => 'website',
+};
+
+1;
diff --git a/sql-ledger/locale/se/am b/sql-ledger/locale/se/am
new file mode 100644 (file)
index 0000000..d8e084b
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Kredit',
+  'AR'                          => 'Debet',
+  'Account'                     => 'Konto',
+  'Account Number'              => 'Kontonummer',
+  'Account Number missing!'     => 'Kontonummer saknas',
+  'Account Type'                => 'Kontotyp',
+  'Account Type missing!'       => 'Kontotyp saknas!',
+  'Account deleted!'            => 'Konto raderat!',
+  'Account saved!'              => 'Konto sparat!',
+  'Add Account'                 => 'Nytt konto',
+  'Add GIFI'                    => 'Ny GIFI',
+  'Address'                     => 'Adress',
+  'Asset'                       => 'Tillgång',
+  'Audit Control'               => 'Revisionskontroll',
+  'Backup sent to'              => 'Säkerhetskopia har sänts till',
+  'Books are open'              => 'Bokföringen är öppen för rättning',
+  'Business Number'             => 'Organisationsnummer',
+  'COGS'                        => 'Inköp',
+  'Cannot delete account!'      => 'Kan inte radera konto',
+  'Cannot delete default account!' => 'Kan inte radera standardkonto',
+  'Cannot save account!'        => 'Kan inte spara konto',
+  'Cannot save preferences!'    => 'Kan inte spara preferenser',
+  'Character Set'               => 'Teckenuppsättning',
+  'Chart of Accounts'           => 'Kontoplan',
+  'Close Books up to'           => 'Avsluta bokföring fram till och med',
+  'Company'                     => 'Företag',
+  'Continue'                    => 'Fortsätt',
+  'Copy to COA'                 => 'Kopiera till COA',
+  'Credit'                      => 'Kredit',
+  'Date Format'                 => 'Datumformat',
+  'Debit'                       => 'Debet',
+  'Delete'                      => 'Radera',
+  'Delete Account'              => 'Radera konto',
+  'Description'                 => 'Beskrivning',
+  'Dropdown Limit'              => 'Dropdown gräns',
+  'E-mail'                      => 'E-Post',
+  'Edit'                        => 'Redigera',
+  'Edit Account'                => 'Redigera konto',
+  'Edit GIFI'                   => 'Redigera GIFI',
+  'Edit Preferences for'        => 'Redigera inställningar för',
+  'Edit Template'               => 'Redigera mall',
+  'Enforce transaction reversal for all dates' => 'Tvinga rättelser för alla konton',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Ange upp till 3 bokstäver (SEK:EUR:USD) för egen och utländsk valuta',
+  'Equity'                      => 'Eget kapital',
+  'Expense'                     => 'Utgift',
+  'Expense Account'             => 'Utgiftskonto',
+  'Expense/Asset'               => 'Utgift/Tillgång',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Vinst på valutahandel',
+  'Foreign Exchange Loss'       => 'Förlust på valutahandel',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI raderad',
+  'GIFI missing!'               => 'GIFI saknas',
+  'GIFI saved!'                 => 'GIFI sparad',
+  'Heading'                     => 'Överskrift',
+  'Include in drop-down menus'  => 'Inkludera i rullgardinsmenyer',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Inkludera det här kontot för kund/leverantör för att markera kund/leverantör som momspliktig',
+  'Income'                      => 'Intäkt',
+  'Income Account'              => 'Intäktskonto',
+  'Inventory'                   => 'Lager',
+  'Inventory Account'           => 'Lagerkonto',
+  'Is this a summary account to record' => 'Samlingskonto för',
+  'Language'                    => 'Språk',
+  'Last Invoice Number'         => 'Senaste fakturanummer',
+  'Last Numbers & Default Accounts' => 'Senaste nummer och standardkonto',
+  'Last Purchase Order Number'  => 'Senaste inköpsordernummer',
+  'Last Sales Order Number'     => 'Senaste säljordernummer',
+  'Liability'                   => 'Ansvar',
+  'Link'                        => 'Referens',
+  'Name'                        => 'Namn',
+  'No'                          => 'Rad',
+  'No email address for'        => 'Ingen E-Postadress för',
+  'Number'                      => 'Nummer',
+  'Number Format'               => 'Nummerformat',
+  'Parts Inventory'             => 'Artikellista',
+  'Password'                    => 'Lösenord',
+  'Payables'                    => 'Utbetalningar',
+  'Payment'                     => 'Betalning',
+  'Phone'                       => 'Telefon',
+  'Preferences saved!'          => 'Inställningar sparade',
+  'Rate'                        => 'Rate',
+  'Receivables'                 => 'Inbetalningar',
+  'Sales'                       => 'Försäljning',
+  'Save'                        => 'Spara',
+  'Service Items'               => 'Tjänsteartiklar',
+  'Ship via'                    => 'Skicka via',
+  'Signature'                   => 'Signatur',
+  'Stylesheet'                  => 'Stilmall',
+  'Tax'                         => 'Moms',
+  'Tax Accounts'                => 'Momskonton',
+  'Template saved!'             => 'Mall sparad',
+  'Transaction reversal enforced for all dates' => 'Transaktion påtvingas för alla datum',
+  'Transaction reversal enforced up to' => 'Transaktion påtvingas upp till',
+  'Transactions exist; cannot delete account!' => 'Transaktioner finns, kan inte radera konto',
+  'Weight Unit'                 => 'Viktenhet',
+  'Year End'                    => 'Årsslut',
+  'Yes'                         => 'Ja',
+  'does not exist'              => 'finns inte',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'nytt_konto'                  => 'add_account',
+  'fortsätt'                    => 'continue',
+  'kopiera_till_coa'            => 'copy_to_coa',
+  'radera'                      => 'delete',
+  'redigera'                    => 'edit',
+  'redigera_konto'              => 'edit_account',
+  'spara'                       => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/se/ap b/sql-ledger/locale/se/ap
new file mode 100644 (file)
index 0000000..94021c9
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Kredit verifikat',
+  'AP Transactions'             => 'Kredit verifikationer',
+  'Account'                     => 'Konto',
+  'Add Accounts Payables Transaction' => 'Lägg till kreditverifikat',
+  'Address'                     => 'Adress',
+  'Amount'                      => 'Belopp',
+  'Amount Due'                  => 'Belopp förfallet',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Transaction' => 'Är du säker på att du vill radera Transaktionen',
+  'Aug'                         => 'aug',
+  'August'                      => 'augusti',
+  'Cannot delete transaction!'  => 'Kan inte radera händelse',
+  'Cannot post payment for a closed period!' => 'Kan inte lägga till en betalning för en stängd period',
+  'Cannot post transaction for a closed period!' => 'Kan inte bokföra för en stängd period',
+  'Cannot post transaction!'    => 'Kan inte lägga till händelsen',
+  'Closed'                      => 'Avslutad',
+  'Confirm!'                    => 'Bekräfta',
+  'Continue'                    => 'Fortsätt',
+  'Currency'                    => 'Valuta',
+  'Customer not on file!'       => 'Kund finns ej',
+  'Date'                        => 'Datum',
+  'Date Paid'                   => 'Betalningsdatum',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Radera',
+  'Description'                 => 'Beskrivning',
+  'Due Date'                    => 'Förfallodatum',
+  'Due Date missing!'           => 'Förfallodatum saknas',
+  'Edit Accounts Payables Transaction' => 'Redigera kreditkonton',
+  'Employee'                    => 'Anställd',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Växlingskurs',
+  'Exchangerate for payment missing!' => 'Växlingskurs för saknad betalning',
+  'Exchangerate missing!'       => 'Växelkurs saknas',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Från',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Inkludera i rapport',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadatum',
+  'Invoice Date missing!'       => 'Fakturadatum saknas',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer saknas',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mars',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Notes'                       => 'Anmärkningar',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Open'                        => 'Öppen',
+  'Order'                       => 'Order',
+  'Order Number'                => 'Ordernummer',
+  'Paid'                        => 'Betalt',
+  'Payment date missing!'       => 'Betalningsdatum saknas',
+  'Payments'                    => 'Betalningar',
+  'Post'                        => 'Lägg till',
+  'Post as new'                 => 'Lägg till som ny',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekt finns ej',
+  'Purchase Invoice'            => 'Inköpsfaktura',
+  'Select from one of the names below' => 'Välj ett av namnen nedan',
+  'Select from one of the projects below' => 'Välj ett av projekten nedan',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Källa',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Moms',
+  'Tax Included'                => 'Moms ingår',
+  'To'                          => 'Till',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transaktion raderad',
+  'Transaction posted!'         => 'Transaktion sparad',
+  'Update'                      => 'Uppdatera',
+  'Vendor'                      => 'Leverantör',
+  'Vendor missing!'             => 'Leverantör saknas',
+  'Vendor not on file!'         => 'Leverantör finns ej',
+  'Yes'                         => 'Ja',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'kredit_verifikat'            => 'ap_transaction',
+  'lägg_till_kreditverifikat'   => 'add_accounts_payables_transaction',
+  'fortsätt'                    => 'continue',
+  'radera'                      => 'delete',
+  'redigera_kreditkonton'       => 'edit_accounts_payables_transaction',
+  'lägg_till'                   => 'post',
+  'lägg_till_som_ny'            => 'post_as_new',
+  'inköpsfaktura'               => 'purchase_invoice',
+  'uppdatera'                   => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/se/ar b/sql-ledger/locale/se/ar
new file mode 100644 (file)
index 0000000..c72f7cf
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'Debet verifikat',
+  'AR Transactions'             => 'Debet verifikationer',
+  'Account'                     => 'Konto',
+  'Add Accounts Receivables Transaction' => 'Lägg till debetverifikat',
+  'Address'                     => 'Adress',
+  'Amount'                      => 'Belopp',
+  'Amount Due'                  => 'Belopp förfallet',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Transaction' => 'Är du säker på att du vill radera Transaktionen',
+  'Aug'                         => 'aug',
+  'August'                      => 'augusti',
+  'Cannot delete transaction!'  => 'Kan inte radera händelse',
+  'Cannot post payment for a closed period!' => 'Kan inte lägga till en betalning för en stängd period',
+  'Cannot post transaction for a closed period!' => 'Kan inte bokföra för en stängd period',
+  'Cannot post transaction!'    => 'Kan inte lägga till händelsen',
+  'Closed'                      => 'Avslutad',
+  'Confirm!'                    => 'Bekräfta',
+  'Continue'                    => 'Fortsätt',
+  'Credit Limit'                => 'Kreditgräns',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Kund',
+  'Customer missing!'           => 'Kund saknas',
+  'Customer not on file!'       => 'Kund finns ej',
+  'Date'                        => 'Datum',
+  'Date Paid'                   => 'Betalningsdatum',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Radera',
+  'Description'                 => 'Beskrivning',
+  'Due Date'                    => 'Förfallodatum',
+  'Due Date missing!'           => 'Förfallodatum saknas',
+  'Edit Accounts Receivables Transaction' => 'Redigera debetkonton',
+  'Employee'                    => 'Anställd',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Växlingskurs',
+  'Exchangerate for payment missing!' => 'Växlingskurs för saknad betalning',
+  'Exchangerate missing!'       => 'Växelkurs saknas',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Från',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Inkludera i rapport',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadatum',
+  'Invoice Date missing!'       => 'Fakturadatum saknas',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer saknas',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mars',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Notes'                       => 'Anmärkningar',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Open'                        => 'Öppen',
+  'Order'                       => 'Order',
+  'Order Number'                => 'Ordernummer',
+  'Paid'                        => 'Betalt',
+  'Payment date missing!'       => 'Betalningsdatum saknas',
+  'Payments'                    => 'Betalningar',
+  'Post'                        => 'Lägg till',
+  'Post as new'                 => 'Lägg till som ny',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekt finns ej',
+  'Remaining'                   => 'Resterar',
+  'Sales Invoice'               => 'Säljfaktura',
+  'Select from one of the names below' => 'Välj ett av namnen nedan',
+  'Select from one of the projects below' => 'Välj ett av projekten nedan',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Källa',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Moms',
+  'Tax Included'                => 'Moms ingår',
+  'To'                          => 'Till',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transaktion raderad',
+  'Transaction posted!'         => 'Transaktion sparad',
+  'Update'                      => 'Uppdatera',
+  'Vendor not on file!'         => 'Leverantör finns ej',
+  'Yes'                         => 'Ja',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'debet_verifikat'             => 'ar_transaction',
+  'fortsätt'                    => 'continue',
+  'radera'                      => 'delete',
+  'lägg_till'                   => 'post',
+  'lägg_till_som_ny'            => 'post_as_new',
+  'säljfaktura'                 => 'sales_invoice',
+  'uppdatera'                   => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/se/arap b/sql-ledger/locale/se/arap
new file mode 100644 (file)
index 0000000..51fa73a
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Adress',
+  'Continue'                    => 'Fortsätt',
+  'Customer not on file!'       => 'Kund finns ej',
+  'Description'                 => 'Beskrivning',
+  'Number'                      => 'Nummer',
+  'Project not on file!'        => 'Projekt finns ej',
+  'Select from one of the names below' => 'Välj ett av namnen nedan',
+  'Select from one of the projects below' => 'Välj ett av projekten nedan',
+  'Vendor not on file!'         => 'Leverantör finns ej',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'fortsätt'                    => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/se/ca b/sql-ledger/locale/se/ca
new file mode 100644 (file)
index 0000000..d186a62
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Aug'                         => 'aug',
+  'August'                      => 'augusti',
+  'Balance'                     => 'Balans',
+  'Chart of Accounts'           => 'Kontoplan',
+  'Credit'                      => 'Kredit',
+  'Date'                        => 'Datum',
+  'Debit'                       => 'Debet',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Description'                 => 'Beskrivning',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Från',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Inkludera i rapport',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'List Transactions'           => 'Lista transaktioner',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mars',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Reference'                   => 'Referens',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Subtotal'                    => 'Subtotal',
+  'To'                          => 'Till',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'lista_transaktioner'         => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/se/cp b/sql-ledger/locale/se/cp
new file mode 100644 (file)
index 0000000..c6b1f47
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Address'                     => 'Adress',
+  'Amount'                      => 'Belopp',
+  'Amount does not equal applied!' => 'Förfallet belopp stämmer ej med det tillagda',
+  'Amount missing!'             => 'Summa saknas',
+  'Applied'                     => 'Tillagt',
+  'Cannot post payment!'        => 'Kan inte lägga till betalning',
+  'Cannot process payment for a closed period!' => 'Kan inte processa betalning för en avslutad period',
+  'Check'                       => 'Check',
+  'Check printed!'              => 'Check utskriven',
+  'Check printing failed!'      => 'Utskrift av check misslyckades',
+  'Continue'                    => 'Fortsätt',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Kund',
+  'Customer not on file!'       => 'Kund finns ej',
+  'Date'                        => 'Datum',
+  'Date missing!'               => 'Datum saknas',
+  'Description'                 => 'Beskrivning',
+  'Due'                         => 'Förfallen',
+  'Exchangerate'                => 'Växlingskurs',
+  'From'                        => 'Från',
+  'Invoice'                     => 'Faktura',
+  'Invoices'                    => 'Fakturor',
+  'Nothing applied!'            => 'Ingenting lades till',
+  'Number'                      => 'Nummer',
+  'Paid in full'                => 'Slutbetalt',
+  'Payment'                     => 'Betalning',
+  'Payment posted!'             => 'Betalning postad',
+  'Post'                        => 'Lägg till',
+  'Print'                       => 'Skriv ut',
+  'Printer'                     => 'Skrivare',
+  'Project not on file!'        => 'Projekt finns ej',
+  'Receipt'                     => 'Kvitto',
+  'Reference'                   => 'Referens',
+  'Screen'                      => 'Skärm',
+  'Select from one of the names below' => 'Välj ett av namnen nedan',
+  'Select from one of the projects below' => 'Välj ett av projekten nedan',
+  'To'                          => 'Till',
+  'Update'                      => 'Uppdatera',
+  'Vendor'                      => 'Leverantör',
+  'Vendor not on file!'         => 'Leverantör finns ej',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'fortsätt'                    => 'continue',
+  'lägg_till'                   => 'post',
+  'skriv_ut'                    => 'print',
+  'uppdatera'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/se/ct b/sql-ledger/locale/se/ct
new file mode 100644 (file)
index 0000000..16d6b64
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Lägg til',
+  'Address'                     => 'Adress',
+  'All'                         => 'Alla',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Kan inte radera kund',
+  'Cannot delete vendor!'       => 'Kan inte radera Leverantör',
+  'Cc'                          => 'Kopia',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsätt',
+  'Credit Limit'                => 'Kreditgräns',
+  'Customer deleted!'           => 'Kund raderad',
+  'Customer saved!'             => 'Kund sparad',
+  'Customers'                   => 'Kunder',
+  'Delete'                      => 'Radera',
+  'Discount'                    => 'Rabatt',
+  'E-mail'                      => 'E-Post',
+  'Edit Customer'               => 'Redigera kund',
+  'Edit Vendor'                 => 'Redigera Leverantör',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Inkludera i rapport',
+  'Invoice'                     => 'Faktura',
+  'Name'                        => 'Namn',
+  'Name missing!'               => 'Namn saknas',
+  'Notes'                       => 'Anmärkningar',
+  'Number'                      => 'Nummer',
+  'Order'                       => 'Order',
+  'Orphaned'                    => 'Fristående',
+  'Phone'                       => 'Telefon',
+  'Save'                        => 'Spara',
+  'Ship to'                     => 'Skicka till',
+  'Tax Included'                => 'Moms ingår',
+  'Taxable'                     => 'Momspliktigt',
+  'Terms: Net'                  => 'Netto',
+  'Transactions exist, cannot delete customer!' => 'Transaktioner finns, kan inte radera kund',
+  'Transactions exist, cannot delete vendor!' => 'Transaktioner finns, kan inte radera leverantör',
+  'Vendor deleted!'             => 'Leverantör raderad',
+  'Vendor saved!'               => 'Leverantör sparad',
+  'Vendors'                     => 'Leverantörer',
+  'days'                        => 'dagar',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'lägg_til'                    => 'add',
+  'fortsätt'                    => 'continue',
+  'radera'                      => 'delete',
+  'faktura'                     => 'invoice',
+  'order'                       => 'order',
+  'spara'                       => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/se/gl b/sql-ledger/locale/se/gl
new file mode 100644 (file)
index 0000000..314839f
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Kredit verifikat',
+  'AR Transaction'              => 'Debet verifikat',
+  'Account'                     => 'Konto',
+  'Add General Ledger Transaction' => 'Ny post i huvudbok',
+  'Address'                     => 'Adress',
+  'All'                         => 'Alla',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Transaction' => 'Är du säker på att du vill radera Transaktionen',
+  'Asset'                       => 'Tillgång',
+  'Aug'                         => 'aug',
+  'August'                      => 'augusti',
+  'Balance'                     => 'Balans',
+  'Cannot delete transaction!'  => 'Kan inte radera händelse',
+  'Cannot have a value in both Debit and Credit!' => 'Kan inte ha värde i både Debet och Kredit!',
+  'Cannot post a transaction without a value!' => 'Kan inte lägga till en händelse utan ett värde',
+  'Cannot post transaction for a closed period!' => 'Kan inte bokföra för en stängd period',
+  'Confirm!'                    => 'Bekräfta',
+  'Continue'                    => 'Fortsätt',
+  'Credit'                      => 'Kredit',
+  'Customer not on file!'       => 'Kund finns ej',
+  'Date'                        => 'Datum',
+  'Debit'                       => 'Debet',
+  'Debit and credit out of balance!' => 'Debet och kredit måste vara lika!',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Radera',
+  'Description'                 => 'Beskrivning',
+  'Edit General Ledger Transaction' => 'Redigera en post i Huvudboken',
+  'Equity'                      => 'Eget kapital',
+  'Expense'                     => 'Utgift',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Från',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'GL händelse',
+  'General Ledger'              => 'Huvudbok',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Inkludera i rapport',
+  'Income'                      => 'Intäkt',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Liability'                   => 'Ansvar',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mars',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Notes'                       => 'Anmärkningar',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Post'                        => 'Lägg till',
+  'Post as new'                 => 'Lägg till som ny',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekt finns ej',
+  'Purchase Invoice'            => 'Inköpsfaktura',
+  'Reference'                   => 'Referens',
+  'Reference missing!'          => 'Referens saknas',
+  'Reports'                     => 'Rapporter',
+  'Sales Invoice'               => 'Säljfaktura',
+  'Select from one of the names below' => 'Välj ett av namnen nedan',
+  'Select from one of the projects below' => 'Välj ett av projekten nedan',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Källa',
+  'Subtotal'                    => 'Subtotal',
+  'To'                          => 'Till',
+  'Transaction Date missing!'   => 'Transaktionsdatum saknas',
+  'Transaction deleted!'        => 'Transaktion raderad',
+  'Transaction posted!'         => 'Transaktion sparad',
+  'Update'                      => 'Uppdatera',
+  'Vendor not on file!'         => 'Leverantör finns ej',
+  'Yes'                         => 'Ja',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'kredit_verifikat'            => 'ap_transaction',
+  'debet_verifikat'             => 'ar_transaction',
+  'fortsätt'                    => 'continue',
+  'radera'                      => 'delete',
+  'gl_händelse'                 => 'gl_transaction',
+  'lägg_till'                   => 'post',
+  'lägg_till_som_ny'            => 'post_as_new',
+  'inköpsfaktura'               => 'purchase_invoice',
+  'säljfaktura'                 => 'sales_invoice',
+  'uppdatera'                   => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/se/ic b/sql-ledger/locale/se/ic
new file mode 100644 (file)
index 0000000..176b68b
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Aktiv',
+  'Add'                         => 'Lägg til',
+  'Add Assembly'                => 'Ny sammansätting',
+  'Add Part'                    => 'Ny vara',
+  'Add Purchase Order'          => 'Ny inköpsorder',
+  'Add Sales Order'             => 'Ny säljorder',
+  'Add Service'                 => 'Ny tjänst',
+  'Address'                     => 'Adress',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Assemblies'                  => 'Sammansättningar',
+  'Assemblies restocked!'       => 'Sammansättningar åter i lager',
+  'Assembly Number missing!'    => 'Sammansättningsnummer saknas',
+  'Attachment'                  => 'Bilaga',
+  'Aug'                         => 'aug',
+  'August'                      => 'augusti',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Antal i lager',
+  'Bought'                      => 'Köpt',
+  'COGS'                        => 'Inköp',
+  'Cannot delete item already invoiced!' => 'Kan inte radera redan fakturerade varor!',
+  'Cannot delete item on order!' => 'Kan inte radera vara i order!',
+  'Cannot delete item which is part of an assembly!' => 'Kan inte radera vara som är del av en sammansättning!',
+  'Cannot delete item!'         => 'Kan inte radera vara',
+  'Cannot stock assemblies!'    => 'Kan lagerföra sammansättningar',
+  'Cc'                          => 'Kopia',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsätt',
+  'Copies'                      => 'Kopior',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Radera',
+  'Delivery Date'               => 'Leveransdatum',
+  'Description'                 => 'Beskrivning',
+  'Drawing'                     => 'Ritning',
+  'E-mail'                      => 'E-Post',
+  'E-mail address missing!'     => 'E-Postadress saknas',
+  'Edit Assembly'               => 'Redigera sammansättning',
+  'Edit Part'                   => 'Redigera vara',
+  'Edit Service'                => 'Redigera tjänster',
+  'Expense'                     => 'Utgift',
+  'Extended'                    => 'Utökad',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Från',
+  'Image'                       => 'Bild',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Inkludera i rapport',
+  'Income'                      => 'Intäkt',
+  'Individual Items'            => 'Individuella enheter',
+  'Inventory'                   => 'Lager',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Lagerkvantitet måste vara noll innan du kan sätta sammansättningen som utgången!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Lagerkvantitet måste vara noll innan du kan sätta varan som utgången!',
+  'Inventory quantity must be zero!' => 'Lagerkvantiteten måste vara noll!',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Fakturadatum saknas',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer saknas',
+  'Item deleted!'               => 'Vara raderad',
+  'Item not on file!'           => 'Varan finns inte i databasen',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Last Cost'                   => 'Senaste kostnad',
+  'Line Total'                  => 'Antal rader',
+  'Link Accounts'               => 'Koppla konton',
+  'List Price'                  => 'Inköpspris',
+  'Make'                        => 'Skapa',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mars',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Meddelande',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Modell',
+  'Name'                        => 'Namn',
+  'No.'                         => 'Rad',
+  'Notes'                       => 'Anmärkningar',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Nummer saknas i rad',
+  'Obsolete'                    => 'Utgången',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'On Hand'                     => 'I lager',
+  'On Order'                    => 'På order',
+  'Order'                       => 'Order',
+  'Order Date missing!'         => 'Orderdatum saknas',
+  'Order Number'                => 'Ordernummer',
+  'Order Number missing!'       => 'Ordernummer saknas',
+  'Ordered'                     => 'Beställt',
+  'Orphaned'                    => 'Fristående',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Packsedel',
+  'Packing List Date missing!'  => 'Packsedelsdatum saknas',
+  'Packing List Number missing!' => 'Packsedelsnummer saknas',
+  'Part'                        => 'Vara',
+  'Part Number missing!'        => 'Artikelnummer saknas',
+  'Parts'                       => 'Varor',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Printer'                     => 'Skrivare',
+  'Project'                     => 'Projekt',
+  'Purchase Order'              => 'Inköpsorder',
+  'Qty'                         => 'Antal',
+  'ROP'                         => 'Efterbeställning vid',
+  'Recd'                        => 'Mottagen',
+  'Required by'                 => 'Beställt den',
+  'Sales'                       => 'Försäljning',
+  'Sales Order'                 => 'Säljorder',
+  'Save'                        => 'Spara',
+  'Screen'                      => 'Skärm',
+  'Select from one of the items below' => 'Välj en artikel nedan',
+  'Select postscript or PDF!'   => 'Välj Postscript eller PDF',
+  'Sell Price'                  => 'Försäljningspris',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Tjänster',
+  'Service Number missing!'     => 'Tjänstenummer saknas',
+  'Services'                    => 'Tjänster',
+  'Ship'                        => 'Skicka',
+  'Ship to'                     => 'Skicka till',
+  'Short'                       => 'Kort',
+  'Sold'                        => 'Såld',
+  'Stock Assembly'              => 'Lagersammansättning',
+  'Subject'                     => 'Ämne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Moms',
+  'To'                          => 'Till',
+  'Top Level'                   => 'Toppnivå',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Enhet',
+  'Unit of measure'             => 'Måttenhet',
+  'Update'                      => 'Uppdatera',
+  'Updated'                     => 'Uppdaterad',
+  'Weight'                      => 'Vikt',
+  'What type of item is this?'  => 'Vilken typ av artikel är detta?',
+  'ea'                          => 'st',
+  'emailed to'                  => 'E-Postat till',
+  'hr'                          => 'timme',
+  'sent to printer'             => 'skickat till skrivare',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'lägg_til'                    => 'add',
+  'ny_sammansätting'            => 'add_assembly',
+  'ny_vara'                     => 'add_part',
+  'ny_tjänst'                   => 'add_service',
+  'fortsätt'                    => 'continue',
+  'radera'                      => 'delete',
+  'redigera_sammansättning'     => 'edit_assembly',
+  'redigera_vara'               => 'edit_part',
+  'redigera_tjänster'           => 'edit_service',
+  'spara'                       => 'save',
+  'uppdatera'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/se/io b/sql-ledger/locale/se/io
new file mode 100644 (file)
index 0000000..68418c3
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Ny inköpsorder',
+  'Add Sales Order'             => 'Ny säljorder',
+  'Address'                     => 'Adress',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Attachment'                  => 'Bilaga',
+  'Aug'                         => 'aug',
+  'August'                      => 'augusti',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Antal i lager',
+  'Cc'                          => 'Kopia',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsätt',
+  'Copies'                      => 'Kopior',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delivery Date'               => 'Leveransdatum',
+  'Description'                 => 'Beskrivning',
+  'E-mail'                      => 'E-Post',
+  'E-mail address missing!'     => 'E-Postadress saknas',
+  'Extended'                    => 'Utökad',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'In-line'                     => 'In-line',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Fakturadatum saknas',
+  'Invoice Number missing!'     => 'Fakturanummer saknas',
+  'Item not on file!'           => 'Varan finns inte i databasen',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mars',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Meddelande',
+  'Name'                        => 'Namn',
+  'No.'                         => 'Rad',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Nummer saknas i rad',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Order'                       => 'Order',
+  'Order Date missing!'         => 'Orderdatum saknas',
+  'Order Number missing!'       => 'Ordernummer saknas',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Packsedel',
+  'Packing List Date missing!'  => 'Packsedelsdatum saknas',
+  'Packing List Number missing!' => 'Packsedelsnummer saknas',
+  'Part'                        => 'Vara',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Printer'                     => 'Skrivare',
+  'Project'                     => 'Projekt',
+  'Purchase Order'              => 'Inköpsorder',
+  'Qty'                         => 'Antal',
+  'Recd'                        => 'Mottagen',
+  'Required by'                 => 'Beställt den',
+  'Sales Order'                 => 'Säljorder',
+  'Screen'                      => 'Skärm',
+  'Select from one of the items below' => 'Välj en artikel nedan',
+  'Select postscript or PDF!'   => 'Välj Postscript eller PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Tjänster',
+  'Ship'                        => 'Skicka',
+  'Ship to'                     => 'Skicka till',
+  'Subject'                     => 'Ämne',
+  'To'                          => 'Till',
+  'Unit'                        => 'Enhet',
+  'What type of item is this?'  => 'Vilken typ av artikel är detta?',
+  'emailed to'                  => 'E-Postat till',
+  'sent to printer'             => 'skickat till skrivare',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'fortsätt'                    => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/se/ir b/sql-ledger/locale/se/ir
new file mode 100644 (file)
index 0000000..113fa9c
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Add Purchase Invoice'        => 'Ny inköpsfaktura',
+  'Add Purchase Order'          => 'Ny inköpsorder',
+  'Add Sales Order'             => 'Ny säljorder',
+  'Address'                     => 'Adress',
+  'Amount'                      => 'Belopp',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Invoice Number' => 'Är du säker på att du vill radera Faktura Nummer',
+  'Attachment'                  => 'Bilaga',
+  'Aug'                         => 'aug',
+  'August'                      => 'augusti',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Antal i lager',
+  'Cannot delete invoice!'      => 'Kan inte radera faktura',
+  'Cannot post invoice for a closed period!' => 'Kan inte lägga till en faktura för en avslutad period',
+  'Cannot post invoice!'        => 'Kan inte lägga till faktura',
+  'Cannot post payment for a closed period!' => 'Kan inte lägga till en betalning för en stängd period',
+  'Cc'                          => 'Kopia',
+  'Confirm!'                    => 'Bekräfta',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsätt',
+  'Copies'                      => 'Kopior',
+  'Currency'                    => 'Valuta',
+  'Customer not on file!'       => 'Kund finns ej',
+  'Date'                        => 'Datum',
+  'Date Due'                    => 'Förfallodatum',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Radera',
+  'Delivery Date'               => 'Leveransdatum',
+  'Description'                 => 'Beskrivning',
+  'E-mail'                      => 'E-Post',
+  'E-mail address missing!'     => 'E-Postadress saknas',
+  'Edit Purchase Invoice'       => 'Redigera inköpsfakturor',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Växlingskurs',
+  'Exchangerate for payment missing!' => 'Växlingskurs för saknad betalning',
+  'Exchangerate missing!'       => 'Växelkurs saknas',
+  'Extended'                    => 'Utökad',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'In-line'                     => 'In-line',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadatum',
+  'Invoice Date missing!'       => 'Fakturadatum saknas',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer saknas',
+  'Invoice deleted!'            => 'Faktura raderad',
+  'Invoice posted!'             => 'Faktura postad',
+  'Item not on file!'           => 'Varan finns inte i databasen',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mars',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Meddelande',
+  'Name'                        => 'Namn',
+  'No.'                         => 'Rad',
+  'Notes'                       => 'Anmärkningar',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Nummer saknas i rad',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Order'                       => 'Order',
+  'Order Date missing!'         => 'Orderdatum saknas',
+  'Order Number'                => 'Ordernummer',
+  'Order Number missing!'       => 'Ordernummer saknas',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Packsedel',
+  'Packing List Date missing!'  => 'Packsedelsdatum saknas',
+  'Packing List Number missing!' => 'Packsedelsnummer saknas',
+  'Part'                        => 'Vara',
+  'Payment date missing!'       => 'Betalningsdatum saknas',
+  'Payments'                    => 'Betalningar',
+  'Phone'                       => 'Telefon',
+  'Post'                        => 'Lägg till',
+  'Post as new'                 => 'Lägg till som ny',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Printer'                     => 'Skrivare',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekt finns ej',
+  'Purchase Order'              => 'Inköpsorder',
+  'Qty'                         => 'Antal',
+  'Recd'                        => 'Mottagen',
+  'Record in'                   => 'Bokför på',
+  'Required by'                 => 'Beställt den',
+  'Sales Order'                 => 'Säljorder',
+  'Screen'                      => 'Skärm',
+  'Select from one of the items below' => 'Välj en artikel nedan',
+  'Select from one of the names below' => 'Välj ett av namnen nedan',
+  'Select from one of the projects below' => 'Välj ett av projekten nedan',
+  'Select postscript or PDF!'   => 'Välj Postscript eller PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Tjänster',
+  'Ship'                        => 'Skicka',
+  'Ship to'                     => 'Skicka till',
+  'Source'                      => 'Källa',
+  'Subject'                     => 'Ämne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Moms ingår',
+  'To'                          => 'Till',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Enhet',
+  'Update'                      => 'Uppdatera',
+  'Vendor'                      => 'Leverantör',
+  'Vendor missing!'             => 'Leverantör saknas',
+  'Vendor not on file!'         => 'Leverantör finns ej',
+  'What type of item is this?'  => 'Vilken typ av artikel är detta?',
+  'Yes'                         => 'Ja',
+  'ea'                          => 'st',
+  'emailed to'                  => 'E-Postat till',
+  'sent to printer'             => 'skickat till skrivare',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'fortsätt'                    => 'continue',
+  'radera'                      => 'delete',
+  'order'                       => 'order',
+  'lägg_till'                   => 'post',
+  'lägg_till_som_ny'            => 'post_as_new',
+  'uppdatera'                   => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/se/is b/sql-ledger/locale/se/is
new file mode 100644 (file)
index 0000000..92f640a
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Add Purchase Order'          => 'Ny inköpsorder',
+  'Add Sales Invoice'           => 'Ny säljfaktura',
+  'Add Sales Order'             => 'Ny säljorder',
+  'Address'                     => 'Adress',
+  'Amount'                      => 'Belopp',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Invoice Number' => 'Är du säker på att du vill radera Faktura Nummer',
+  'Attachment'                  => 'Bilaga',
+  'Aug'                         => 'aug',
+  'August'                      => 'augusti',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Antal i lager',
+  'Cannot delete invoice!'      => 'Kan inte radera faktura',
+  'Cannot post invoice for a closed period!' => 'Kan inte lägga till en faktura för en avslutad period',
+  'Cannot post invoice!'        => 'Kan inte lägga till faktura',
+  'Cannot post payment for a closed period!' => 'Kan inte lägga till en betalning för en stängd period',
+  'Cc'                          => 'Kopia',
+  'Confirm!'                    => 'Bekräfta',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsätt',
+  'Copies'                      => 'Kopior',
+  'Credit Limit'                => 'Kreditgräns',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Kund',
+  'Customer missing!'           => 'Kund saknas',
+  'Customer not on file!'       => 'Kund finns ej',
+  'Date'                        => 'Datum',
+  'Date Due'                    => 'Förfallodatum',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Radera',
+  'Delivery Date'               => 'Leveransdatum',
+  'Description'                 => 'Beskrivning',
+  'E-mail'                      => 'E-Post',
+  'E-mail address missing!'     => 'E-Postadress saknas',
+  'Edit Sales Invoice'          => 'Redigera säljfakturor',
+  'Exch'                        => 'Vxl',
+  'Exchangerate'                => 'Växlingskurs',
+  'Exchangerate for payment missing!' => 'Växlingskurs för saknad betalning',
+  'Exchangerate missing!'       => 'Växelkurs saknas',
+  'Extended'                    => 'Utökad',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'In-line'                     => 'In-line',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date'                => 'Fakturadatum',
+  'Invoice Date missing!'       => 'Fakturadatum saknas',
+  'Invoice Number'              => 'Fakturanummer',
+  'Invoice Number missing!'     => 'Fakturanummer saknas',
+  'Invoice deleted!'            => 'Faktura raderad',
+  'Invoice posted!'             => 'Faktura postad',
+  'Item not on file!'           => 'Varan finns inte i databasen',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mars',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Meddelande',
+  'Name'                        => 'Namn',
+  'No.'                         => 'Rad',
+  'Notes'                       => 'Anmärkningar',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Nummer saknas i rad',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Order'                       => 'Order',
+  'Order Date missing!'         => 'Orderdatum saknas',
+  'Order Number'                => 'Ordernummer',
+  'Order Number missing!'       => 'Ordernummer saknas',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Packsedel',
+  'Packing List Date missing!'  => 'Packsedelsdatum saknas',
+  'Packing List Number missing!' => 'Packsedelsnummer saknas',
+  'Part'                        => 'Vara',
+  'Payment date missing!'       => 'Betalningsdatum saknas',
+  'Payments'                    => 'Betalningar',
+  'Phone'                       => 'Telefon',
+  'Post'                        => 'Lägg till',
+  'Post as new'                 => 'Lägg till som ny',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Print'                       => 'Skriv ut',
+  'Printer'                     => 'Skrivare',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekt finns ej',
+  'Purchase Order'              => 'Inköpsorder',
+  'Qty'                         => 'Antal',
+  'Recd'                        => 'Mottagen',
+  'Record in'                   => 'Bokför på',
+  'Remaining'                   => 'Resterar',
+  'Required by'                 => 'Beställt den',
+  'Sales Order'                 => 'Säljorder',
+  'Screen'                      => 'Skärm',
+  'Select from one of the items below' => 'Välj en artikel nedan',
+  'Select from one of the names below' => 'Välj ett av namnen nedan',
+  'Select from one of the projects below' => 'Välj ett av projekten nedan',
+  'Select postscript or PDF!'   => 'Välj Postscript eller PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Tjänster',
+  'Ship'                        => 'Skicka',
+  'Ship to'                     => 'Skicka till',
+  'Ship via'                    => 'Skicka via',
+  'Source'                      => 'Källa',
+  'Subject'                     => 'Ämne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Moms ingår',
+  'To'                          => 'Till',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Enhet',
+  'Update'                      => 'Uppdatera',
+  'Vendor not on file!'         => 'Leverantör finns ej',
+  'What type of item is this?'  => 'Vilken typ av artikel är detta?',
+  'Yes'                         => 'Ja',
+  'ea'                          => 'st',
+  'emailed to'                  => 'E-Postat till',
+  'sent to printer'             => 'skickat till skrivare',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'fortsätt'                    => 'continue',
+  'radera'                      => 'delete',
+  'e_post'                      => 'e_mail',
+  'order'                       => 'order',
+  'lägg_till'                   => 'post',
+  'lägg_till_som_ny'            => 'post_as_new',
+  'skriv_ut'                    => 'print',
+  'skicka_till'                 => 'ship_to',
+  'uppdatera'                   => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/se/login b/sql-ledger/locale/se/login
new file mode 100644 (file)
index 0000000..2fe34aa
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'Om',
+  'Database Host'               => 'Databasvärd',
+  'Dataset'                     => 'Dataset',
+  'Incorrect Dataset version!'  => 'Felaktig databasversion',
+  'Incorrect Password!'         => 'Felaktigt lösenord',
+  'Licensed to'                 => 'Licensierad till',
+  'Login'                       => 'Logga in',
+  'Name'                        => 'Namn',
+  'Password'                    => 'Lösenord',
+  'User'                        => 'Användare',
+  'Version'                     => 'Version',
+  'You are logged out!'         => 'Du är utloggad',
+  'You did not enter a name!'   => 'Du skrev inte in något namn',
+  'is not a member!'            => 'är inte medlem!',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'logga_in'                    => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/se/menu b/sql-ledger/locale/se/menu
new file mode 100644 (file)
index 0000000..2e7ae34
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => 'Kredit',
+  'AP Aging'                    => 'Kredit åldersfördeling',
+  'AR'                          => 'Debet',
+  'AR Aging'                    => 'Debet åldersfördeling',
+  'Accounting Menu'             => 'Konto-meny',
+  'Add Account'                 => 'Nytt konto',
+  'Add Assembly'                => 'Ny sammansätting',
+  'Add Customer'                => 'Ny kund',
+  'Add GIFI'                    => 'Ny GIFI',
+  'Add Part'                    => 'Ny vara',
+  'Add Project'                 => 'Nytt projekt',
+  'Add Service'                 => 'Ny tjänst',
+  'Add Transaction'             => 'Ny post',
+  'Add Vendor'                  => 'Ny leverantör',
+  'Assemblies'                  => 'Sammansättningar',
+  'Audit Control'               => 'Revisionskontroll',
+  'Backup'                      => 'Säkerhetkopia',
+  'Balance Sheet'               => 'Status',
+  'Cash'                        => 'Kontant',
+  'Chart of Accounts'           => 'Kontoplan',
+  'Check'                       => 'Check',
+  'Customers'                   => 'Kunder',
+  'General Ledger'              => 'Huvudbok',
+  'Goods & Services'            => 'Varor och Tjänster',
+  'HTML Templates'              => 'HTML mallar',
+  'Income Statement'            => 'Inkomstberäkning',
+  'Invoice'                     => 'Faktura',
+  'LaTeX Templates'             => 'LaTeX Mallar',
+  'List Accounts'               => 'Lista konton',
+  'List GIFI'                   => 'Lista GIFI',
+  'Logout'                      => 'Logga ut',
+  'Order Entry'                 => 'Orderingång',
+  'Packing List'                => 'Packsedel',
+  'Parts'                       => 'Varor',
+  'Payment'                     => 'Betalning',
+  'Payments'                    => 'Betalningar',
+  'Preferences'                 => 'Inställningar',
+  'Projects'                    => 'Projekt',
+  'Purchase Invoice'            => 'Inköpsfaktura',
+  'Purchase Order'              => 'Inköpsorder',
+  'Purchase Orders'             => 'Inköpsordrar',
+  'Receipt'                     => 'Kvitto',
+  'Receipts'                    => 'Kvitton',
+  'Reconciliation'              => 'Bankuppgörelse',
+  'Reports'                     => 'Rapporter',
+  'Sales Invoice'               => 'Säljfaktura',
+  'Sales Order'                 => 'Säljorder',
+  'Sales Orders'                => 'Säljordrar',
+  'Save to File'                => 'Spara till fil',
+  'Send by E-Mail'              => 'Skicka via E-Post',
+  'Services'                    => 'Tjänster',
+  'Statement'                   => 'Anmärkning',
+  'Stock Assembly'              => 'Lagersammansättning',
+  'Stylesheet'                  => 'Stilmall',
+  'System'                      => 'System',
+  'Tax collected'               => 'Moms total',
+  'Tax paid'                    => 'Moms betalad',
+  'Transactions'                => 'Transaktioner',
+  'Trial Balance'               => 'Provbalans',
+  'Vendors'                     => 'Leverantörer',
+  'Version'                     => 'Version',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/se/oe b/sql-ledger/locale/se/oe
new file mode 100644 (file)
index 0000000..2a62a15
--- /dev/null
@@ -0,0 +1,199 @@
+$self{texts} = {
+  'Add'                         => 'Lägg til',
+  'Add Purchase Invoice'        => 'Ny inköpsfaktura',
+  'Add Purchase Order'          => 'Ny inköpsorder',
+  'Add Sales Invoice'           => 'Ny säljfaktura',
+  'Add Sales Order'             => 'Ny säljorder',
+  'Address'                     => 'Adress',
+  'Amount'                      => 'Belopp',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Are you sure you want to delete Order Number' => 'Är du säker på att du vill radera Order Nummer',
+  'Attachment'                  => 'Bilaga',
+  'Aug'                         => 'aug',
+  'August'                      => 'augusti',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Antal i lager',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Kan inte radera order',
+  'Cannot save order!'          => 'Kan inte spara order',
+  'Cc'                          => 'Kopia',
+  'Closed'                      => 'Avslutad',
+  'Confirm!'                    => 'Bekräfta',
+  'Contact'                     => 'Kontakt',
+  'Continue'                    => 'Fortsätt',
+  'Copies'                      => 'Kopior',
+  'Credit Limit'                => 'Kreditgräns',
+  'Curr'                        => 'Val',
+  'Currency'                    => 'Valuta',
+  'Customer'                    => 'Kund',
+  'Customer missing!'           => 'Kund saknas',
+  'Customer not on file!'       => 'Kund finns ej',
+  'Date'                        => 'Datum',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Delete'                      => 'Radera',
+  'Delivery Date'               => 'Leveransdatum',
+  'Description'                 => 'Beskrivning',
+  'E-mail'                      => 'E-Post',
+  'E-mail address missing!'     => 'E-Postadress saknas',
+  'Edit Purchase Order'         => 'Redigera inköpsorder',
+  'Edit Sales Order'            => 'Redigera säljorder',
+  'Exchangerate'                => 'Växlingskurs',
+  'Exchangerate missing!'       => 'Växelkurs saknas',
+  'Extended'                    => 'Utökad',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Från',
+  'ID'                          => 'ID',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Inkludera i rapport',
+  'Invoice'                     => 'Faktura',
+  'Invoice Date missing!'       => 'Fakturadatum saknas',
+  'Invoice Number missing!'     => 'Fakturanummer saknas',
+  'Item not on file!'           => 'Varan finns inte i databasen',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mars',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Meddelande',
+  'Name'                        => 'Namn',
+  'No.'                         => 'Rad',
+  'Notes'                       => 'Anmärkningar',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Number'                      => 'Nummer',
+  'Number missing in Row'       => 'Nummer saknas i rad',
+  'O'                           => 'O',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'Open'                        => 'Öppen',
+  'Order'                       => 'Order',
+  'Order Date'                  => 'Orderdatum',
+  'Order Date missing!'         => 'Orderdatum saknas',
+  'Order Number'                => 'Ordernummer',
+  'Order Number missing!'       => 'Ordernummer saknas',
+  'Order deleted!'              => 'Order raderad',
+  'Order saved!'                => 'Order sparad',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Packsedel',
+  'Packing List Date missing!'  => 'Packsedelsdatum saknas',
+  'Packing List Number missing!' => 'Packsedelsnummer saknas',
+  'Part'                        => 'Vara',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Pris',
+  'Print'                       => 'Skriv ut',
+  'Printer'                     => 'Skrivare',
+  'Project'                     => 'Projekt',
+  'Project not on file!'        => 'Projekt finns ej',
+  'Purchase Order'              => 'Inköpsorder',
+  'Purchase Orders'             => 'Inköpsordrar',
+  'Qty'                         => 'Antal',
+  'Recd'                        => 'Mottagen',
+  'Remaining'                   => 'Resterar',
+  'Required by'                 => 'Beställt den',
+  'Sales Order'                 => 'Säljorder',
+  'Sales Orders'                => 'Säljordrar',
+  'Save'                        => 'Spara',
+  'Save as new'                 => 'Spara som ny',
+  'Screen'                      => 'Skärm',
+  'Select from one of the items below' => 'Välj en artikel nedan',
+  'Select from one of the names below' => 'Välj ett av namnen nedan',
+  'Select from one of the projects below' => 'Välj ett av projekten nedan',
+  'Select postscript or PDF!'   => 'Välj Postscript eller PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Service'                     => 'Tjänster',
+  'Ship'                        => 'Skicka',
+  'Ship to'                     => 'Skicka till',
+  'Ship via'                    => 'Skicka via',
+  'Subject'                     => 'Ämne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Moms',
+  'Tax Included'                => 'Moms ingår',
+  'Terms: Net'                  => 'Netto',
+  'To'                          => 'Till',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Enhet',
+  'Update'                      => 'Uppdatera',
+  'Vendor'                      => 'Leverantör',
+  'Vendor missing!'             => 'Leverantör saknas',
+  'Vendor not on file!'         => 'Leverantör finns ej',
+  'What type of item is this?'  => 'Vilken typ av artikel är detta?',
+  'Yes'                         => 'Ja',
+  'days'                        => 'dagar',
+  'ea'                          => 'st',
+  'emailed to'                  => 'E-Postat till',
+  'sent to printer'             => 'skickat till skrivare',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'lägg_til'                    => 'add',
+  'fortsätt'                    => 'continue',
+  'radera'                      => 'delete',
+  'e_post'                      => 'e_mail',
+  'faktura'                     => 'invoice',
+  'skriv_ut'                    => 'print',
+  'spara'                       => 'save',
+  'spara_som_ny'                => 'save_as_new',
+  'skicka_till'                 => 'ship_to',
+  'uppdatera'                   => 'update',
+  'ja'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/se/pe b/sql-ledger/locale/se/pe
new file mode 100644 (file)
index 0000000..c8d5b42
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Lägg til',
+  'Add Project'                 => 'Nytt projekt',
+  'All'                         => 'Alla',
+  'Continue'                    => 'Fortsätt',
+  'Delete'                      => 'Radera',
+  'Description'                 => 'Beskrivning',
+  'Edit Project'                => 'Redigera projekt',
+  'Number'                      => 'Nummer',
+  'Orphaned'                    => 'Fristående',
+  'Project'                     => 'Projekt',
+  'Project Number missing!'     => 'Projektnummer saknas',
+  'Project deleted!'            => 'Projekt raderat',
+  'Project saved!'              => 'Projekt sparat',
+  'Projects'                    => 'Projekt',
+  'Save'                        => 'Spara',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'lägg_til'                    => 'add',
+  'fortsätt'                    => 'continue',
+  'radera'                      => 'delete',
+  'spara'                       => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/se/rc b/sql-ledger/locale/se/rc
new file mode 100644 (file)
index 0000000..84df25d
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Konto',
+  'Balance'                     => 'Balans',
+  'Cleared Balance'             => 'Rensade balans',
+  'Continue'                    => 'Fortsätt',
+  'Date'                        => 'Datum',
+  'Deposit'                     => 'Säkerhet',
+  'Description'                 => 'Beskrivning',
+  'Difference'                  => 'Differens',
+  'Done'                        => 'Klart',
+  'Exchangerate Difference'     => 'Differens Växlingskurs',
+  'From'                        => 'Från',
+  'Out of balance!'             => 'Ej i balans',
+  'Payment'                     => 'Betalning',
+  'Reconciliation'              => 'Bankuppgörelse',
+  'Select all'                  => 'Välj alla',
+  'Source'                      => 'Källa',
+  'Statement Balance'           => 'Anmärkning status',
+  'To'                          => 'Till',
+  'Update'                      => 'Uppdatera',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'fortsätt'                    => 'continue',
+  'klart'                       => 'done',
+  'välj_alla'                   => 'select_all',
+  'uppdatera'                   => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/se/rp b/sql-ledger/locale/se/rp
new file mode 100644 (file)
index 0000000..da93e1b
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'Kredit åldersfördeling',
+  'AR Aging'                    => 'Debet åldersfördeling',
+  'Account'                     => 'Konto',
+  'Accounts'                    => 'Konton',
+  'Amount'                      => 'Belopp',
+  'Apr'                         => 'apr',
+  'April'                       => 'april',
+  'Attachment'                  => 'Bilaga',
+  'Aug'                         => 'aug',
+  'August'                      => 'augusti',
+  'Balance Sheet'               => 'Status',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Kontantbaserad',
+  'Cc'                          => 'Kopia',
+  'Compare to'                  => 'Jämför med',
+  'Continue'                    => 'Fortsätt',
+  'Copies'                      => 'Kopior',
+  'Credit'                      => 'Kredit',
+  'Current'                     => 'Nuvarande',
+  'Customer'                    => 'Kund',
+  'Date'                        => 'Datum',
+  'Debit'                       => 'Debet',
+  'Dec'                         => 'dec',
+  'December'                    => 'december',
+  'Decimalplaces'               => 'Decimalplaceringar',
+  'Description'                 => 'Beskrivning',
+  'Due'                         => 'Förfallen',
+  'E-mail'                      => 'E-Post',
+  'E-mail Statement to'         => 'E-Post anmaning till',
+  'Feb'                         => 'Feb',
+  'February'                    => 'Februari',
+  'From'                        => 'Från',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Överskrift',
+  'ID'                          => 'ID',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Inkludera i rapport',
+  'Income Statement'            => 'Inkomstberäkning',
+  'Invoice'                     => 'Faktura',
+  'Jan'                         => 'Jan',
+  'January'                     => 'Januari',
+  'Jul'                         => 'Jul',
+  'July'                        => 'Juli',
+  'Jun'                         => 'Jun',
+  'June'                        => 'Juni',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mars',
+  'May'                         => 'Maj',
+  'May '                        => 'Maj',
+  'Message'                     => 'Meddelande',
+  'N/A'                         => 'N/A',
+  'Nothing selected!'           => 'Ingenting valt',
+  'Nov'                         => 'Nov',
+  'November'                    => 'November',
+  'Oct'                         => 'Okt',
+  'October'                     => 'Oktober',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Betalningar',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Skriv ut',
+  'Printer'                     => 'Skrivare',
+  'Receipts'                    => 'Kvitton',
+  'Report for'                  => 'Rapport för',
+  'Retained Earnings'           => 'Realiserat överskott',
+  'Screen'                      => 'Skärm',
+  'Select all'                  => 'Välj alla',
+  'Select postscript or PDF!'   => 'Välj Postscript eller PDF',
+  'Sep'                         => 'Sep',
+  'September'                   => 'September',
+  'Source'                      => 'Källa',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Anmärkning',
+  'Statement sent to'           => 'Anmärkning skickad till',
+  'Statements sent to printer!' => 'Anmärkningar skickade till skrivare',
+  'Subject'                     => 'Ämne',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'Moms',
+  'Tax collected'               => 'Moms total',
+  'Tax paid'                    => 'Moms betalad',
+  'To'                          => 'Till',
+  'Total'                       => 'Total',
+  'Trial Balance'               => 'Provbalans',
+  'Vendor'                      => 'Leverantör',
+  'as at'                       => 'som vid',
+  'collected on sales'          => 'inbetalt på försäljning',
+  'for Period'                  => 'för perioden',
+  'paid on purchases'           => 'betalt vid köp',
+  'to'                          => 'till',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'fortsätt'                    => 'continue',
+  'e_post'                      => 'e_mail',
+  'skriv_ut'                    => 'print',
+  'välj_alla'                   => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/COPYING b/sql-ledger/locale/tr/COPYING
new file mode 100644 (file)
index 0000000..523dffa
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Turkish texts:
+#
+#  Author: Mufit Eribol <meribol@deltagrup.com.tr>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/tr/LANGUAGE b/sql-ledger/locale/tr/LANGUAGE
new file mode 100644 (file)
index 0000000..d7b2f1f
--- /dev/null
@@ -0,0 +1 @@
+Turkish
diff --git a/sql-ledger/locale/tr/admin b/sql-ledger/locale/tr/admin
new file mode 100644 (file)
index 0000000..5d0b0fd
--- /dev/null
@@ -0,0 +1,122 @@
+$self{texts} = {
+  'Access Control'              => 'Giriþ Kontrol',
+  'Accounting'                  => 'Muhasebe',
+  'Add User'                    => 'Kullanýcý Ekle',
+  'Address'                     => 'Adres',
+  'Administration'              => 'Yönetim',
+  'Administrator'               => 'Administrator',
+  'All Datasets up to date!'    => 'All Datasets up to date!',
+  'Change Admin Password'       => 'Yönetici Þifresini Deðiþtir',
+  'Change Password'             => 'Þifre Deðiþtir',
+  'Character Set'               => 'Karakter Seti',
+  'Click on login name to edit!' => 'Düzenlemek için giriþ ismini týklayýn.',
+  'Company'                     => 'Þirket',
+  'Connect to'                  => 'Baðlan',
+  'Continue'                    => 'Devam',
+  'Create Chart of Accounts'    => 'Hesap Planý Oluþtur',
+  'Create Dataset'              => 'Veriseti Oluþtur',
+  'DBI not installed!'          => 'DBJ kurulu deðil',
+  'Database'                    => 'Veritabaný',
+  'Database Administration'     => 'Veritabani Yonetimi',
+  'Database Driver not checked!' => 'Database Driver not checked!',
+  'Database User missing!'      => 'Veritabaný Kullanýcýsý yok!',
+  'Dataset'                     => 'Veriseti',
+  'Dataset missing!'            => 'Veriseti Yok!',
+  'Dataset updated!'            => 'Dataset updated!',
+  'Date Format'                 => 'Tarih Formatý',
+  'Delete'                      => 'Sil',
+  'Delete Dataset'              => 'Verisetini Sil',
+  'Directory'                   => 'Dizin',
+  'Driver'                      => 'Sürücü',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'Posta',
+  'Edit User'                   => 'Kullanýcý Bilgilerini Düzenle',
+  'Existing Datasets'           => 'Verisetleri',
+  'Fax'                         => 'Faks',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Host yok!',
+  'Incorrect Password!'         => 'Yanlýþ Þifre!',
+  'Language'                    => 'Dil',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Uzakta baglantý yapmak istemiyorsanýz host ve port alanlarýný boþ býrakýnýz.',
+  'Login'                       => 'Giriþ',
+  'Name'                        => 'Ýsim',
+  'New Templates'               => 'Yeni Þablonlar',
+  'No Database Drivers available!' => 'Veritabaný Sürücüsü yok!',
+  'No Dataset selected!'        => 'Veriseti seçilmedi!',
+  'Nothing to delete!'          => 'Nothing to delete!',
+  'Number Format'               => 'Rakam Formatý',
+  'Oracle Database Administration' => 'Oracle Veritabaný Yönetimi',
+  'Password'                    => 'Þifre',
+  'Password changed!'           => 'Password changed!',
+  'Pg Database Administration'  => 'Pg Veritabaný Yönetimi',
+  'Phone'                       => 'Telefon',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port yok!',
+  'Printer'                     => 'Yazýcý',
+  'Save'                        => 'Kaydet',
+  'Select a Dataset to delete and press "Continue"' => 'Silmek için bir Veriseti seçin ve "Devam"ý týklayýn.',
+  'Setup Templates'             => 'Þablon Kur',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'Ýmza',
+  'Stylesheet'                  => 'Düzen Sayfasý',
+  'Templates'                   => 'Þablonlar',
+  'The following Datasets are not in use and can be deleted' => 'Aþaðýdaki Verisetleri kullanýlmamaktadýr ve silinebilir',
+  'The following Datasets need to be updated' => 'The following Datasets need to be updated',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Mevcut fiþ bilgileri için bu bir ön kontroldür. Bu aþamada hiçbirþey oluþturulmaz ve silinemez',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Gruba yeni kullanýcý eklemek için, giriþ ismini deðiþtirin ve kaydedin. Yeni kullanýcý yeni giriþ altýnda ayný parametrelerle kaydedilecektir.',
+  'Update Dataset'              => 'Update Dataset',
+  'Use Templates'               => 'Þablon Kullan',
+  'User'                        => 'Kullanýcý',
+  'User deleted!'               => 'User deleted!',
+  'User saved!'                 => 'User saved!',
+  'Version'                     => 'Versiyon',
+  'You must enter a host and port for local and remote connections!' => 'Yerel ve uzak baðlantýlar için bir host ve port girmek zorundasýnýz!',
+  'does not exist'              => 'mevcut deðil',
+  'is already a member!'        => 'üyedir!',
+  'localhost'                   => 'Yerelhost',
+  'successfully created!'       => 'baþarýyla oluþturuldu!',
+  'successfully deleted!'       => 'baþarýyla silindi!',
+  'website'                     => 'Websitesi',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'kullanýcý_ekle'              => 'add_user',
+  'yönetici_Þifresini_deðiþtir' => 'change_admin_password',
+  'Þifre_deðiþtir'              => 'change_password',
+  'devam'                       => 'continue',
+  'veriseti_oluþtur'            => 'create_dataset',
+  'sil'                         => 'delete',
+  'verisetini_sil'              => 'delete_dataset',
+  'giriþ'                       => 'login',
+  'oracle_veritabaný_yönetimi'  => 'oracle_database_administration',
+  'pg_veritabaný_yönetimi'      => 'pg_database_administration',
+  'kaydet'                      => 'save',
+  'update_dataset'              => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/all b/sql-ledger/locale/tr/all
new file mode 100644 (file)
index 0000000..2eefc62
--- /dev/null
@@ -0,0 +1,487 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'Borçlar',
+  'AP Aging'                    => 'Gecikmiþ Borçlar',
+  'AP Transaction'              => '',
+  'AP Transactions'             => 'Borç Ýþlemleri',
+  'AR'                          => 'Alacaklar',
+  'AR Aging'                    => 'Gecikmiþ Alacaklar',
+  'AR Transaction'              => '',
+  'AR Transactions'             => 'Alacak Ýþlemleri',
+  'About'                       => 'Program bilgileri',
+  'Access Control'              => 'Giriþ Kontrol',
+  'Account'                     => 'Hesap',
+  'Account Number'              => 'Hesap Numarasý',
+  'Account Number missing!'     => 'Hesap Numarasý yok!',
+  'Account Type'                => 'Hesap Türü',
+  'Account Type missing!'       => 'Hesap Türü yok!',
+  'Account deleted!'            => '',
+  'Account saved!'              => '',
+  'Accounting'                  => 'Muhasebe',
+  'Accounting Menu'             => 'Muhasebe Menüsü',
+  'Accounts'                    => '',
+  'Active'                      => '',
+  'Add'                         => 'Ekle',
+  'Add Account'                 => 'Hesap Ekle',
+  'Add Accounts Payables Transaction' => '',
+  'Add Accounts Receivables Transaction' => '',
+  'Add Assembly'                => 'Grup Ekle',
+  'Add Customer'                => 'Alýcý Ekle',
+  'Add GIFI'                    => '',
+  'Add General Ledger Transaction' => 'Defteri Kebire Ýþlem Ekle',
+  'Add Part'                    => 'Parça Ekle',
+  'Add Project'                 => '',
+  'Add Purchase Invoice'        => '',
+  'Add Purchase Order'          => 'Satýnalma Sip. Ekle',
+  'Add Sales Invoice'           => '',
+  'Add Sales Order'             => 'Satýþ Sipariþi Ekle',
+  'Add Service'                 => 'Hizmet Ekle',
+  'Add Transaction'             => 'Ýþlem Ekle',
+  'Add User'                    => 'Kullanýcý Ekle',
+  'Add Vendor'                  => 'Satýcý Ekle',
+  'Address'                     => 'Adres',
+  'Administration'              => 'Yönetim',
+  'Administrator'               => '',
+  'All'                         => 'Hepsi',
+  'All Datasets up to date!'    => '',
+  'Amount'                      => 'Miktar',
+  'Amount Due'                  => '',
+  'Amount does not equal applied!' => '',
+  'Amount missing!'             => '',
+  'Applied'                     => '',
+  'Apr'                         => 'Nis',
+  'April'                       => 'Nisan',
+  'Are you sure you want to delete Invoice Number' => 'Fatura Numarasýný silmek istediðinizden emin misiniz? Fiþ: ',
+  'Are you sure you want to delete Order Number' => 'Sipariþ Numarasýný silmek istediðinizden emin misiniz? Fiþ: ',
+  'Are you sure you want to delete Transaction' => 'Ýþlemi silmek istediðinizden emin misiniz? Fiþ: ',
+  'Assemblies'                  => 'Gruplar',
+  'Assemblies restocked!'       => '',
+  'Assembly Number missing!'    => 'Grup Numarasý yok!',
+  'Asset'                       => 'Aktif',
+  'Attachment'                  => '',
+  'Audit Control'               => '',
+  'Aug'                         => 'Aðu',
+  'August'                      => 'Aðustos',
+  'BOM'                         => '',
+  'Backup'                      => 'Yedekleme',
+  'Backup sent to'              => '',
+  'Balance'                     => '',
+  'Balance Sheet'               => 'Bilanço',
+  'Bcc'                         => '',
+  'Bin'                         => '',
+  'Books are open'              => '',
+  'Bought'                      => 'Alýnan',
+  'Business Number'             => 'ÞirketNo',
+  'C'                           => '',
+  'COGS'                        => 'SMM',
+  'Cannot delete account!'      => '',
+  'Cannot delete customer!'     => '',
+  'Cannot delete default account!' => 'Öntanýmlý hesap silinmez!',
+  'Cannot delete invoice!'      => '',
+  'Cannot delete item already invoiced!' => 'Faturalanmýþ kalem silinemez!',
+  'Cannot delete item on order!' => '',
+  'Cannot delete item which is part of an assembly!' => 'Grubun parçasý olan kalem silinemez!',
+  'Cannot delete item!'         => '',
+  'Cannot delete order!'        => '',
+  'Cannot delete transaction!'  => '',
+  'Cannot delete vendor!'       => '',
+  'Cannot have a value in both Debit and Credit!' => 'Borç ve Alacak hanelerine ayný anda deðer yazýlamaz!',
+  'Cannot post a transaction without a value!' => '',
+  'Cannot post invoice for a closed period!' => '',
+  'Cannot post invoice!'        => '',
+  'Cannot post payment for a closed period!' => '',
+  'Cannot post payment!'        => '',
+  'Cannot post transaction for a closed period!' => '',
+  'Cannot post transaction!'    => '',
+  'Cannot process payment for a closed period!' => '',
+  'Cannot save account!'        => '',
+  'Cannot save order!'          => '',
+  'Cannot save preferences!'    => '',
+  'Cannot stock assemblies!'    => '',
+  'Cash'                        => '',
+  'Cash based'                  => '',
+  'Cc'                          => '',
+  'Change Admin Password'       => 'Yönetici Þifresini Deðiþtir',
+  'Change Password'             => 'Þifre Deðiþtir',
+  'Character Set'               => 'Karakter Seti',
+  'Chart of Accounts'           => 'Hesap Planý',
+  'Check'                       => '',
+  'Check printed!'              => '',
+  'Check printing failed!'      => '',
+  'Cleared Balance'             => '',
+  'Click on login name to edit!' => 'Düzenlemek için giriþ ismini týklayýn.',
+  'Close Books up to'           => '',
+  'Closed'                      => '',
+  'Company'                     => 'Þirket',
+  'Compare to'                  => '...kýyasla',
+  'Confirm!'                    => 'Onayla!',
+  'Connect to'                  => 'Baðlan',
+  'Contact'                     => 'Kontak',
+  'Continue'                    => 'Devam',
+  'Copies'                      => '',
+  'Copy to COA'                 => '',
+  'Create Chart of Accounts'    => 'Hesap Planý Oluþtur',
+  'Create Dataset'              => 'Veriseti Oluþtur',
+  'Credit'                      => 'Alacak',
+  'Credit Limit'                => 'Kredi Limiti',
+  'Curr'                        => '',
+  'Currency'                    => 'Para Birimi',
+  'Current'                     => '',
+  'Customer'                    => 'Alýcý',
+  'Customer deleted!'           => '',
+  'Customer missing!'           => '',
+  'Customer not on file!'       => '',
+  'Customer saved!'             => '',
+  'Customers'                   => '',
+  'DBI not installed!'          => 'DBJ kurulu deðil',
+  'Database'                    => 'Veritabaný',
+  'Database Administration'     => 'Veritabani Yonetimi',
+  'Database Driver not checked!' => '',
+  'Database Host'               => 'Veritabaný Hostu',
+  'Database User missing!'      => 'Veritabaný Kullanýcýsý yok!',
+  'Dataset'                     => 'Veriseti',
+  'Dataset missing!'            => 'Veriseti Yok!',
+  'Dataset updated!'            => '',
+  'Date'                        => 'Tarih',
+  'Date Due'                    => 'Vade Tarihi',
+  'Date Format'                 => 'Tarih Formatý',
+  'Date Paid'                   => 'Ödendiði Tarih',
+  'Date missing!'               => '',
+  'Debit'                       => 'Borç',
+  'Debit and credit out of balance!' => 'Borç ve alacak eþit deðil!',
+  'Dec'                         => 'Ara',
+  'December'                    => 'Aralýk',
+  'Decimalplaces'               => '',
+  'Delete'                      => 'Sil',
+  'Delete Account'              => 'Hesabý Sil',
+  'Delete Dataset'              => 'Verisetini Sil',
+  'Delivery Date'               => '',
+  'Deposit'                     => '',
+  'Description'                 => 'Açýklama',
+  'Difference'                  => '',
+  'Directory'                   => 'Dizin',
+  'Discount'                    => 'Ýndirim',
+  'Done'                        => '',
+  'Drawing'                     => '',
+  'Driver'                      => 'Sürücü',
+  'Dropdown Limit'              => '',
+  'Due'                         => 'Vade',
+  'Due Date'                    => 'Vade Tarihi',
+  'Due Date missing!'           => 'Vade Tarihi yok!',
+  'E-mail'                      => 'Posta',
+  'E-mail Statement to'         => '',
+  'E-mail address missing!'     => 'Posta adresi yok!',
+  'Edit'                        => '',
+  'Edit Account'                => 'Hesabý Düzenle',
+  'Edit Accounts Payables Transaction' => '',
+  'Edit Accounts Receivables Transaction' => '',
+  'Edit Assembly'               => 'Grubu Düzenle',
+  'Edit GIFI'                   => '',
+  'Edit General Ledger Transaction' => 'Defteri Kebir Ýþlemini Düzenle',
+  'Edit Part'                   => 'Parçayý Düzenle',
+  'Edit Preferences for'        => 'Tercihleri Düzenle: ',
+  'Edit Project'                => '',
+  'Edit Purchase Invoice'       => '',
+  'Edit Purchase Order'         => 'Alýþ Sipariþini Düzenle',
+  'Edit Sales Invoice'          => '',
+  'Edit Sales Order'            => 'Satýþ Sipariþini Düzenle',
+  'Edit Service'                => 'Hizmeti Düzenle',
+  'Edit Template'               => 'Þablonu Düzenle',
+  'Edit User'                   => 'Kullanýcý Bilgilerini Düzenle',
+  'Employee'                    => '',
+  'Enforce transaction reversal for all dates' => '',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Yerel ve yabancý para birimleri için 3 harfli tanýmlama giriniz yi týklayýnýz (USD:TRL:EUR)',
+  'Equity'                      => 'Sermaye',
+  'Exch'                        => 'D.Kuru',
+  'Exchangerate'                => 'Döviz Kuru',
+  'Exchangerate Difference'     => '',
+  'Exchangerate for payment missing!' => '',
+  'Exchangerate missing!'       => '',
+  'Existing Datasets'           => 'Verisetleri',
+  'Expense'                     => 'Gider',
+  'Expense Account'             => 'Gider Hesabý',
+  'Expense/Asset'               => 'Gider/Varlýklar',
+  'Extended'                    => '',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'Þub',
+  'February'                    => 'Þubat',
+  'Foreign Exchange Gain'       => 'Kur Kazancý',
+  'Foreign Exchange Loss'       => 'Kur Kaybý',
+  'From'                        => 'Baþlangýç',
+  'GIFI'                        => '',
+  'GIFI deleted!'               => '',
+  'GIFI missing!'               => '',
+  'GIFI saved!'                 => '',
+  'GL Transaction'              => '',
+  'General Ledger'              => 'Defteri Kebir',
+  'Goods & Services'            => '',
+  'HTML Templates'              => '',
+  'Heading'                     => 'Baþlýk',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Host yok!',
+  'ID'                          => '',
+  'Image'                       => '',
+  'In-line'                     => '',
+  'Include in Report'           => 'Raporla',
+  'Include in drop-down menus'  => 'Seçmeli Menüye dahil et',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Vergiye tabi alýcý/satýcý belirlemek için bu hesabý alýcý/aatýcý formlarýna dahil ediniz?',
+  'Income'                      => 'Gelirler',
+  'Income Account'              => 'Gelir Hesabý',
+  'Income Statement'            => 'Gelir Tablosu',
+  'Incorrect Dataset version!'  => '',
+  'Incorrect Password!'         => 'Yanlýþ Þifre!',
+  'Individual Items'            => 'Farklý Kalemler',
+  'Inventory'                   => 'Stok',
+  'Inventory Account'           => 'Stok Hesabý',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Bu grubu çýkarmadan önce stok miktarý sýfýr olmalýdýr',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Bu Parçayý çýkarmadan önce stok miktarý sýfýr olmalýdýr',
+  'Inventory quantity must be zero!' => 'Stok miktarý sýfýr olmalý!',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date'                => 'Fatura Tarihi',
+  'Invoice Date missing!'       => 'Fatura Tarihi yok!',
+  'Invoice Number'              => 'Fatura No',
+  'Invoice Number missing!'     => 'Fatura Numarasý yok!',
+  'Invoice deleted!'            => '',
+  'Invoice posted!'             => '',
+  'Invoices'                    => '',
+  'Is this a summary account to record' => 'Bu kaydedilecek hesap özeti mi',
+  'Item deleted!'               => '',
+  'Item not on file!'           => 'Bu kalem dosyada yok!',
+  'Jan'                         => 'Oca',
+  'January'                     => 'Ocak',
+  'Jul'                         => 'Tem',
+  'July'                        => 'Temmuz',
+  'Jun'                         => 'Haz',
+  'June'                        => 'Haziran',
+  'LaTeX Templates'             => '',
+  'Language'                    => 'Dil',
+  'Last Cost'                   => 'Son Maliyet',
+  'Last Invoice Number'         => 'Son Fatura Numarasý',
+  'Last Numbers & Default Accounts' => 'Son Numaralar ve Öntanýmlý Hesaplar',
+  'Last Purchase Order Number'  => 'Son Satýnalma Sipariþ Numarasý',
+  'Last Sales Order Number'     => '',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Uzakta baglantý yapmak istemiyorsanýz host ve port alanlarýný boþ býrakýnýz.',
+  'Liability'                   => 'Pasif',
+  'Licensed to'                 => 'Lisans Sahibi:',
+  'Line Total'                  => '',
+  'Link'                        => 'Baðla',
+  'Link Accounts'               => 'Baðlý Hesaplar',
+  'List Accounts'               => '',
+  'List GIFI'                   => '',
+  'List Price'                  => 'Liste Fiyatý',
+  'List Transactions'           => 'Ýþlemleri Listele',
+  'Login'                       => 'Giriþ',
+  'Logout'                      => '',
+  'Make'                        => 'Marka',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mart',
+  'May'                         => 'May',
+  'May '                        => 'Mayýs',
+  'Message'                     => '',
+  'Microfiche'                  => '',
+  'Model'                       => 'Model',
+  'N/A'                         => '',
+  'Name'                        => 'Ýsim',
+  'Name missing!'               => '',
+  'New Templates'               => 'Yeni Þablonlar',
+  'No'                          => 'Hayýr',
+  'No Database Drivers available!' => 'Veritabaný Sürücüsü yok!',
+  'No Dataset selected!'        => 'Veriseti seçilmedi!',
+  'No email address for'        => 'E-posta adresi yok: ',
+  'No.'                         => '',
+  'Notes'                       => 'Notlar:',
+  'Nothing applied!'            => '',
+  'Nothing selected!'           => '',
+  'Nothing to delete!'          => '',
+  'Nov'                         => 'Kas',
+  'November'                    => 'Kasým',
+  'Number'                      => 'Numara',
+  'Number Format'               => 'Rakam Formatý',
+  'Number missing in Row'       => 'Sýrada Numara yok!',
+  'O'                           => '',
+  'Obsolete'                    => 'Eski',
+  'Oct'                         => 'Eki',
+  'October'                     => 'Ekim',
+  'On Hand'                     => 'Stok:',
+  'On Order'                    => '',
+  'Open'                        => '',
+  'Oracle Database Administration' => 'Oracle Veritabaný Yönetimi',
+  'Order'                       => 'Sipariþ',
+  'Order Date'                  => 'Sipariþ Tarihi',
+  'Order Date missing!'         => 'Sipariþ Tarihi yok!',
+  'Order Entry'                 => 'Sipariþ Giriþi',
+  'Order Number'                => 'Sipariþ No',
+  'Order Number missing!'       => 'Sipariþ Numarasý yok!',
+  'Order deleted!'              => '',
+  'Order saved!'                => '',
+  'Ordered'                     => '',
+  'Orphaned'                    => '',
+  'Out of balance!'             => '',
+  'PDF'                         => '',
+  'Packing List'                => 'Paketleme Listesi',
+  'Packing List Date missing!'  => '',
+  'Packing List Number missing!' => '',
+  'Paid'                        => 'Ödendi',
+  'Paid in full'                => '',
+  'Part'                        => 'Parça',
+  'Part Number missing!'        => 'Parça Numarasý yok!',
+  'Parts'                       => 'Parçalar',
+  'Parts Inventory'             => 'Parça Stoðu',
+  'Password'                    => 'Þifre',
+  'Password changed!'           => '',
+  'Payables'                    => 'Borçlar',
+  'Payment'                     => 'Ödeme',
+  'Payment date missing!'       => 'Ödeme Tarihi yok',
+  'Payment posted!'             => '',
+  'Payments'                    => 'Ödemeler',
+  'Pg Database Administration'  => 'Pg Veritabaný Yönetimi',
+  'Phone'                       => 'Telefon',
+  'Port'                        => 'Port',
+  'Port missing!'               => 'Port yok!',
+  'Post'                        => '',
+  'Post as new'                 => '',
+  'Postscript'                  => '',
+  'Preferences'                 => 'Tercihler',
+  'Preferences saved!'          => 'Tercihler kaydedildi!',
+  'Price'                       => 'Fiyat',
+  'Print'                       => '',
+  'Printer'                     => 'Yazýcý',
+  'Project'                     => '',
+  'Project Number missing!'     => '',
+  'Project deleted!'            => '',
+  'Project not on file!'        => '',
+  'Project saved!'              => '',
+  'Projects'                    => '',
+  'Purchase Invoice'            => '',
+  'Purchase Order'              => 'Satýnalma Sipariþi',
+  'Purchase Orders'             => 'Satýnalma Sipariþleri',
+  'Qty'                         => 'Adet',
+  'ROP'                         => '',
+  'Rate'                        => 'Oran',
+  'Recd'                        => '',
+  'Receipt'                     => '',
+  'Receipts'                    => '',
+  'Receivables'                 => 'Alacaklar',
+  'Reconciliation'              => '',
+  'Record in'                   => 'Kaydet',
+  'Reference'                   => '',
+  'Reference missing!'          => '',
+  'Remaining'                   => '',
+  'Report for'                  => '',
+  'Reports'                     => 'Raporlar',
+  'Required by'                 => 'Talep tarihi:',
+  'Retained Earnings'           => 'Net Dönem Karý (Zararý)',
+  'Sales'                       => 'Satýþlar',
+  'Sales Invoice'               => '',
+  'Sales Order'                 => 'Satýþ Sipariþi',
+  'Sales Orders'                => 'Satýþ Sipariþleri',
+  'Save'                        => 'Kaydet',
+  'Save as new'                 => '',
+  'Save to File'                => 'Dosyaya Kaydet',
+  'Screen'                      => '',
+  'Select a Dataset to delete and press "Continue"' => 'Silmek için bir Veriseti seçin ve "Devam"ý týklayýn.',
+  'Select all'                  => '',
+  'Select from one of the items below' => 'Aþaðýdaki kalemlerden birini seç',
+  'Select from one of the names below' => '',
+  'Select from one of the projects below' => '',
+  'Select postscript or PDF!'   => '',
+  'Sell Price'                  => 'Satýþ Fiyatý',
+  'Send by E-Mail'              => 'E-postayla gönder',
+  'Sep'                         => 'Eyl',
+  'September'                   => 'Eylül',
+  'Service'                     => 'servis',
+  'Service Items'               => 'Hizmet Kalemleri',
+  'Service Number missing!'     => 'Hizmet Numarasý yok!',
+  'Services'                    => 'Servisler',
+  'Setup Templates'             => 'Þablon Kur',
+  'Ship'                        => '',
+  'Ship to'                     => '',
+  'Ship via'                    => '',
+  'Short'                       => 'Kýsa',
+  'Signature'                   => 'Ýmza',
+  'Sold'                        => 'satýlan',
+  'Source'                      => 'Kaynak',
+  'Standard'                    => '',
+  'Statement'                   => '',
+  'Statement Balance'           => '',
+  'Statement sent to'           => '',
+  'Statements sent to printer!' => '',
+  'Stock Assembly'              => 'Grubu Stokla',
+  'Stylesheet'                  => 'Düzen Sayfasý',
+  'Subject'                     => '',
+  'Subtotal'                    => 'Aratoplam',
+  'System'                      => '',
+  'Tax'                         => 'Vergi',
+  'Tax Accounts'                => 'Vergi Hesaplarý',
+  'Tax Included'                => 'Vergi Dahil',
+  'Tax collected'               => '',
+  'Tax paid'                    => '',
+  'Taxable'                     => 'Vergiye tabi',
+  'Template saved!'             => '',
+  'Templates'                   => 'Þablonlar',
+  'Terms: Net'                  => 'Þartlar: Net',
+  'The following Datasets are not in use and can be deleted' => 'Aþaðýdaki Verisetleri kullanýlmamaktadýr ve silinebilir',
+  'The following Datasets need to be updated' => '',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Mevcut fiþ bilgileri için bu bir ön kontroldür. Bu aþamada hiçbirþey oluþturulmaz ve silinemez',
+  'To'                          => 'Bitiþ',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Gruba yeni kullanýcý eklemek için, giriþ ismini deðiþtirin ve kaydedin. Yeni kullanýcý yeni giriþ altýnda ayný parametrelerle kaydedilecektir.',
+  'Top Level'                   => '',
+  'Total'                       => 'Toplam',
+  'Transaction Date missing!'   => 'Ýþlem Tarihi yok!',
+  'Transaction deleted!'        => '',
+  'Transaction posted!'         => '',
+  'Transaction reversal enforced for all dates' => '',
+  'Transaction reversal enforced up to' => '',
+  'Transactions'                => 'Ýþlemler',
+  'Transactions exist, cannot delete customer!' => 'Ýþlem var, alýcý silinemez!',
+  'Transactions exist, cannot delete vendor!' => 'Ýþlem var, satýcý silinemez!',
+  'Transactions exist; cannot delete account!' => 'Ýþlem var, hesap silinemez!',
+  'Trial Balance'               => 'Proforma Bilanço',
+  'Unit'                        => 'Birim',
+  'Unit of measure'             => 'Ölçme Birimi',
+  'Update'                      => '',
+  'Update Dataset'              => '',
+  'Updated'                     => '',
+  'Use Templates'               => 'Þablon Kullan',
+  'User'                        => 'Kullanýcý',
+  'User deleted!'               => '',
+  'User saved!'                 => '',
+  'Vendor'                      => 'Satýcý',
+  'Vendor deleted!'             => '',
+  'Vendor missing!'             => '',
+  'Vendor not on file!'         => '',
+  'Vendor saved!'               => '',
+  'Vendors'                     => '',
+  'Version'                     => 'Versiyon',
+  'Weight'                      => 'Aðýrlýk',
+  'Weight Unit'                 => 'Aðýrlýk Birimi',
+  'What type of item is this?'  => 'Bu ne çeþit bir kalemdir?',
+  'Year End'                    => 'Sene Sonu',
+  'Yes'                         => 'Evet',
+  'You are logged out!'         => '',
+  'You did not enter a name!'   => 'Ýsim girmediniz!',
+  'You must enter a host and port for local and remote connections!' => 'Yerel ve uzak baðlantýlar için bir host ve port girmek zorundasýnýz!',
+  'as at'                       => '',
+  'collected on sales'          => '',
+  'days'                        => 'gün. ',
+  'does not exist'              => 'mevcut deðil',
+  'ea'                          => 'ad',
+  'emailed to'                  => '',
+  'for Period'                  => 'Dönem:',
+  'hr'                          => 'sa',
+  'is already a member!'        => 'üyedir!',
+  'is not a member!'            => '',
+  'localhost'                   => 'Yerelhost',
+  'paid on purchases'           => '',
+  'sent to printer'             => '',
+  'successfully created!'       => 'baþarýyla oluþturuldu!',
+  'successfully deleted!'       => 'baþarýyla silindi!',
+  'to'                          => '',
+  'website'                     => 'Websitesi',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/am b/sql-ledger/locale/tr/am
new file mode 100644 (file)
index 0000000..1ce2de0
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'Borçlar',
+  'AR'                          => 'Alacaklar',
+  'Account'                     => 'Hesap',
+  'Account Number'              => 'Hesap Numarasý',
+  'Account Number missing!'     => 'Hesap Numarasý yok!',
+  'Account Type'                => 'Hesap Türü',
+  'Account Type missing!'       => 'Hesap Türü yok!',
+  'Account deleted!'            => 'Account deleted!',
+  'Account saved!'              => 'Account saved!',
+  'Add Account'                 => 'Hesap Ekle',
+  'Add GIFI'                    => 'Add GIFI',
+  'Address'                     => 'Adres',
+  'Asset'                       => 'Aktif',
+  'Audit Control'               => 'Audit Control',
+  'Backup sent to'              => 'Backup sent to',
+  'Books are open'              => 'Books are open',
+  'Business Number'             => 'ÞirketNo',
+  'COGS'                        => 'SMM',
+  'Cannot delete account!'      => 'Cannot delete account!',
+  'Cannot delete default account!' => 'Öntanýmlý hesap silinmez!',
+  'Cannot save account!'        => 'Cannot save account!',
+  'Cannot save preferences!'    => 'Cannot save preferences!',
+  'Character Set'               => 'Karakter Seti',
+  'Chart of Accounts'           => 'Hesap Planý',
+  'Close Books up to'           => 'Close Books up to',
+  'Company'                     => 'Þirket',
+  'Continue'                    => 'Devam',
+  'Copy to COA'                 => 'Copy to COA',
+  'Credit'                      => 'Alacak',
+  'Date Format'                 => 'Tarih Formatý',
+  'Debit'                       => 'Borç',
+  'Delete'                      => 'Sil',
+  'Delete Account'              => 'Hesabý Sil',
+  'Description'                 => 'Açýklama',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => 'Posta',
+  'Edit'                        => 'Edit',
+  'Edit Account'                => 'Hesabý Düzenle',
+  'Edit GIFI'                   => 'Edit GIFI',
+  'Edit Preferences for'        => 'Tercihleri Düzenle: ',
+  'Edit Template'               => 'Þablonu Düzenle',
+  'Enforce transaction reversal for all dates' => 'Enforce transaction reversal for all dates',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Yerel ve yabancý para birimleri için 3 harfli tanýmlama giriniz yi týklayýnýz (USD:TRL:EUR)',
+  'Equity'                      => 'Sermaye',
+  'Expense'                     => 'Gider',
+  'Expense Account'             => 'Gider Hesabý',
+  'Expense/Asset'               => 'Gider/Varlýklar',
+  'Fax'                         => 'Faks',
+  'Foreign Exchange Gain'       => 'Kur Kazancý',
+  'Foreign Exchange Loss'       => 'Kur Kaybý',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI deleted!',
+  'GIFI missing!'               => 'GIFI missing!',
+  'GIFI saved!'                 => 'GIFI saved!',
+  'Heading'                     => 'Baþlýk',
+  'Include in drop-down menus'  => 'Seçmeli Menüye dahil et',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Vergiye tabi alýcý/satýcý belirlemek için bu hesabý alýcý/aatýcý formlarýna dahil ediniz?',
+  'Income'                      => 'Gelirler',
+  'Income Account'              => 'Gelir Hesabý',
+  'Inventory'                   => 'Stok',
+  'Inventory Account'           => 'Stok Hesabý',
+  'Is this a summary account to record' => 'Bu kaydedilecek hesap özeti mi',
+  'Language'                    => 'Dil',
+  'Last Invoice Number'         => 'Son Fatura Numarasý',
+  'Last Numbers & Default Accounts' => 'Son Numaralar ve Öntanýmlý Hesaplar',
+  'Last Purchase Order Number'  => 'Son Satýnalma Sipariþ Numarasý',
+  'Last Sales Order Number'     => 'Last Sales Order Number',
+  'Liability'                   => 'Pasif',
+  'Link'                        => 'Baðla',
+  'Name'                        => 'Ýsim',
+  'No'                          => 'Hayýr',
+  'No email address for'        => 'E-posta adresi yok: ',
+  'Number'                      => 'Numara',
+  'Number Format'               => 'Rakam Formatý',
+  'Parts Inventory'             => 'Parça Stoðu',
+  'Password'                    => 'Þifre',
+  'Payables'                    => 'Borçlar',
+  'Payment'                     => 'Ödeme',
+  'Phone'                       => 'Telefon',
+  'Preferences saved!'          => 'Tercihler kaydedildi!',
+  'Rate'                        => 'Oran',
+  'Receivables'                 => 'Alacaklar',
+  'Sales'                       => 'Satýþlar',
+  'Save'                        => 'Kaydet',
+  'Service Items'               => 'Hizmet Kalemleri',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'Ýmza',
+  'Stylesheet'                  => 'Düzen Sayfasý',
+  'Tax'                         => 'Vergi',
+  'Tax Accounts'                => 'Vergi Hesaplarý',
+  'Template saved!'             => 'Template saved!',
+  'Transaction reversal enforced for all dates' => 'Transaction reversal enforced for all dates',
+  'Transaction reversal enforced up to' => 'Transaction reversal enforced up to',
+  'Transactions exist; cannot delete account!' => 'Ýþlem var, hesap silinemez!',
+  'Weight Unit'                 => 'Aðýrlýk Birimi',
+  'Year End'                    => 'Sene Sonu',
+  'Yes'                         => 'Evet',
+  'does not exist'              => 'mevcut deðil',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'hesap_ekle'                  => 'add_account',
+  'devam'                       => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'sil'                         => 'delete',
+  'edit'                        => 'edit',
+  'hesabý_düzenle'              => 'edit_account',
+  'kaydet'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/ap b/sql-ledger/locale/tr/ap
new file mode 100644 (file)
index 0000000..f6c817f
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AP Transactions'             => 'Borç Ýþlemleri',
+  'Account'                     => 'Hesap',
+  'Add Accounts Payables Transaction' => 'Add Accounts Payables Transaction',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Miktar',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'Nis',
+  'April'                       => 'Nisan',
+  'Are you sure you want to delete Transaction' => 'Ýþlemi silmek istediðinizden emin misiniz? Fiþ: ',
+  'Aug'                         => 'Aðu',
+  'August'                      => 'Aðustos',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cannot post transaction for a closed period!' => 'Cannot post transaction for a closed period!',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'Closed',
+  'Confirm!'                    => 'Onayla!',
+  'Continue'                    => 'Devam',
+  'Currency'                    => 'Para Birimi',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Tarih',
+  'Date Paid'                   => 'Ödendiði Tarih',
+  'Dec'                         => 'Ara',
+  'December'                    => 'Aralýk',
+  'Delete'                      => 'Sil',
+  'Description'                 => 'Açýklama',
+  'Due Date'                    => 'Vade Tarihi',
+  'Due Date missing!'           => 'Vade Tarihi yok!',
+  'Edit Accounts Payables Transaction' => 'Edit Accounts Payables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'D.Kuru',
+  'Exchangerate'                => 'Döviz Kuru',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Feb'                         => 'Þub',
+  'February'                    => 'Þubat',
+  'From'                        => 'Baþlangýç',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Raporla',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date'                => 'Fatura Tarihi',
+  'Invoice Date missing!'       => 'Fatura Tarihi yok!',
+  'Invoice Number'              => 'Fatura No',
+  'Invoice Number missing!'     => 'Fatura Numarasý yok!',
+  'Jan'                         => 'Oca',
+  'January'                     => 'Ocak',
+  'Jul'                         => 'Tem',
+  'July'                        => 'Temmuz',
+  'Jun'                         => 'Haz',
+  'June'                        => 'Haziran',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mart',
+  'May'                         => 'May',
+  'May '                        => 'Mayýs',
+  'Notes'                       => 'Notlar:',
+  'Nov'                         => 'Kas',
+  'November'                    => 'Kasým',
+  'Number'                      => 'Numara',
+  'Oct'                         => 'Eki',
+  'October'                     => 'Ekim',
+  'Open'                        => 'Open',
+  'Order'                       => 'Sipariþ',
+  'Order Number'                => 'Sipariþ No',
+  'Paid'                        => 'Ödendi',
+  'Payment date missing!'       => 'Ödeme Tarihi yok',
+  'Payments'                    => 'Ödemeler',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Eyl',
+  'September'                   => 'Eylül',
+  'Source'                      => 'Kaynak',
+  'Subtotal'                    => 'Aratoplam',
+  'Tax'                         => 'Vergi',
+  'Tax Included'                => 'Vergi Dahil',
+  'To'                          => 'Bitiþ',
+  'Total'                       => 'Toplam',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Satýcý',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Evet',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'add_accounts_payables_transaction' => 'add_accounts_payables_transaction',
+  'devam'                       => 'continue',
+  'sil'                         => 'delete',
+  'edit_accounts_payables_transaction' => 'edit_accounts_payables_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'update'                      => 'update',
+  'evet'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/ar b/sql-ledger/locale/tr/ar
new file mode 100644 (file)
index 0000000..642c556
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'AR Transaction',
+  'AR Transactions'             => 'Alacak Ýþlemleri',
+  'Account'                     => 'Hesap',
+  'Add Accounts Receivables Transaction' => 'Add Accounts Receivables Transaction',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Miktar',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => 'Nis',
+  'April'                       => 'Nisan',
+  'Are you sure you want to delete Transaction' => 'Ýþlemi silmek istediðinizden emin misiniz? Fiþ: ',
+  'Aug'                         => 'Aðu',
+  'August'                      => 'Aðustos',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cannot post transaction for a closed period!' => 'Cannot post transaction for a closed period!',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => 'Closed',
+  'Confirm!'                    => 'Onayla!',
+  'Continue'                    => 'Devam',
+  'Credit Limit'                => 'Kredi Limiti',
+  'Currency'                    => 'Para Birimi',
+  'Customer'                    => 'Alýcý',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Tarih',
+  'Date Paid'                   => 'Ödendiði Tarih',
+  'Dec'                         => 'Ara',
+  'December'                    => 'Aralýk',
+  'Delete'                      => 'Sil',
+  'Description'                 => 'Açýklama',
+  'Due Date'                    => 'Vade Tarihi',
+  'Due Date missing!'           => 'Vade Tarihi yok!',
+  'Edit Accounts Receivables Transaction' => 'Edit Accounts Receivables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => 'D.Kuru',
+  'Exchangerate'                => 'Döviz Kuru',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Feb'                         => 'Þub',
+  'February'                    => 'Þubat',
+  'From'                        => 'Baþlangýç',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Raporla',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date'                => 'Fatura Tarihi',
+  'Invoice Date missing!'       => 'Fatura Tarihi yok!',
+  'Invoice Number'              => 'Fatura No',
+  'Invoice Number missing!'     => 'Fatura Numarasý yok!',
+  'Jan'                         => 'Oca',
+  'January'                     => 'Ocak',
+  'Jul'                         => 'Tem',
+  'July'                        => 'Temmuz',
+  'Jun'                         => 'Haz',
+  'June'                        => 'Haziran',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mart',
+  'May'                         => 'May',
+  'May '                        => 'Mayýs',
+  'Notes'                       => 'Notlar:',
+  'Nov'                         => 'Kas',
+  'November'                    => 'Kasým',
+  'Number'                      => 'Numara',
+  'Oct'                         => 'Eki',
+  'October'                     => 'Ekim',
+  'Open'                        => 'Open',
+  'Order'                       => 'Sipariþ',
+  'Order Number'                => 'Sipariþ No',
+  'Paid'                        => 'Ödendi',
+  'Payment date missing!'       => 'Ödeme Tarihi yok',
+  'Payments'                    => 'Ödemeler',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Remaining'                   => 'Remaining',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Eyl',
+  'September'                   => 'Eylül',
+  'Source'                      => 'Kaynak',
+  'Subtotal'                    => 'Aratoplam',
+  'Tax'                         => 'Vergi',
+  'Tax Included'                => 'Vergi Dahil',
+  'To'                          => 'Bitiþ',
+  'Total'                       => 'Toplam',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Evet',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ar_transaction'              => 'ar_transaction',
+  'devam'                       => 'continue',
+  'sil'                         => 'delete',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'evet'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/arap b/sql-ledger/locale/tr/arap
new file mode 100644 (file)
index 0000000..fb56368
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Adres',
+  'Continue'                    => 'Devam',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Description'                 => 'Açýklama',
+  'Number'                      => 'Numara',
+  'Project not on file!'        => 'Project not on file!',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'devam'                       => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/ca b/sql-ledger/locale/tr/ca
new file mode 100644 (file)
index 0000000..f379cd6
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Hesap',
+  'Apr'                         => 'Nis',
+  'April'                       => 'Nisan',
+  'Aug'                         => 'Aðu',
+  'August'                      => 'Aðustos',
+  'Balance'                     => 'Balance',
+  'Chart of Accounts'           => 'Hesap Planý',
+  'Credit'                      => 'Alacak',
+  'Date'                        => 'Tarih',
+  'Debit'                       => 'Borç',
+  'Dec'                         => 'Ara',
+  'December'                    => 'Aralýk',
+  'Description'                 => 'Açýklama',
+  'Feb'                         => 'Þub',
+  'February'                    => 'Þubat',
+  'From'                        => 'Baþlangýç',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Raporla',
+  'Jan'                         => 'Oca',
+  'January'                     => 'Ocak',
+  'Jul'                         => 'Tem',
+  'July'                        => 'Temmuz',
+  'Jun'                         => 'Haz',
+  'June'                        => 'Haziran',
+  'List Transactions'           => 'Ýþlemleri Listele',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mart',
+  'May'                         => 'May',
+  'May '                        => 'Mayýs',
+  'Nov'                         => 'Kas',
+  'November'                    => 'Kasým',
+  'Oct'                         => 'Eki',
+  'October'                     => 'Ekim',
+  'Reference'                   => 'Reference',
+  'Sep'                         => 'Eyl',
+  'September'                   => 'Eylül',
+  'Subtotal'                    => 'Aratoplam',
+  'To'                          => 'Bitiþ',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'Ýþlemleri_listele'           => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/cp b/sql-ledger/locale/tr/cp
new file mode 100644 (file)
index 0000000..a08a0b7
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Hesap',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Miktar',
+  'Amount does not equal applied!' => 'Amount does not equal applied!',
+  'Amount missing!'             => 'Amount missing!',
+  'Applied'                     => 'Applied',
+  'Cannot post payment!'        => 'Cannot post payment!',
+  'Cannot process payment for a closed period!' => 'Cannot process payment for a closed period!',
+  'Check'                       => 'Check',
+  'Check printed!'              => 'Check printed!',
+  'Check printing failed!'      => 'Check printing failed!',
+  'Continue'                    => 'Devam',
+  'Currency'                    => 'Para Birimi',
+  'Customer'                    => 'Alýcý',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Tarih',
+  'Date missing!'               => 'Date missing!',
+  'Description'                 => 'Açýklama',
+  'Due'                         => 'Vade',
+  'Exchangerate'                => 'Döviz Kuru',
+  'From'                        => 'Baþlangýç',
+  'Invoice'                     => 'Fatura',
+  'Invoices'                    => 'Invoices',
+  'Nothing applied!'            => 'Nothing applied!',
+  'Number'                      => 'Numara',
+  'Paid in full'                => 'Paid in full',
+  'Payment'                     => 'Ödeme',
+  'Payment posted!'             => 'Payment posted!',
+  'Post'                        => 'Post',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Yazýcý',
+  'Project not on file!'        => 'Project not on file!',
+  'Receipt'                     => 'Receipt',
+  'Reference'                   => 'Reference',
+  'Screen'                      => 'Screen',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'To'                          => 'Bitiþ',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Satýcý',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'devam'                       => 'continue',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/ct b/sql-ledger/locale/tr/ct
new file mode 100644 (file)
index 0000000..b7b0e4f
--- /dev/null
@@ -0,0 +1,69 @@
+$self{texts} = {
+  'Add'                         => 'Ekle',
+  'Address'                     => 'Adres',
+  'All'                         => 'Hepsi',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Cannot delete customer!',
+  'Cannot delete vendor!'       => 'Cannot delete vendor!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontak',
+  'Continue'                    => 'Devam',
+  'Credit Limit'                => 'Kredi Limiti',
+  'Customer deleted!'           => 'Customer deleted!',
+  'Customer saved!'             => 'Customer saved!',
+  'Customers'                   => 'Customers',
+  'Delete'                      => 'Sil',
+  'Discount'                    => 'Ýndirim',
+  'E-mail'                      => 'Posta',
+  'Fax'                         => 'Faks',
+  'Include in Report'           => 'Raporla',
+  'Invoice'                     => 'Fatura',
+  'Name'                        => 'Ýsim',
+  'Name missing!'               => 'Name missing!',
+  'Notes'                       => 'Notlar:',
+  'Number'                      => 'Numara',
+  'Order'                       => 'Sipariþ',
+  'Orphaned'                    => 'Orphaned',
+  'Phone'                       => 'Telefon',
+  'Save'                        => 'Kaydet',
+  'Ship to'                     => 'Ship to',
+  'Tax Included'                => 'Vergi Dahil',
+  'Taxable'                     => 'Vergiye tabi',
+  'Terms: Net'                  => 'Þartlar: Net',
+  'Transactions exist, cannot delete customer!' => 'Ýþlem var, alýcý silinemez!',
+  'Transactions exist, cannot delete vendor!' => 'Ýþlem var, satýcý silinemez!',
+  'Vendor deleted!'             => 'Vendor deleted!',
+  'Vendor saved!'               => 'Vendor saved!',
+  'Vendors'                     => 'Vendors',
+  'days'                        => 'gün. ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'ekle'                        => 'add',
+  'devam'                       => 'continue',
+  'sil'                         => 'delete',
+  'fatura'                      => 'invoice',
+  'sipariþ'                     => 'order',
+  'kaydet'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/gl b/sql-ledger/locale/tr/gl
new file mode 100644 (file)
index 0000000..7370def
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AR Transaction'              => 'AR Transaction',
+  'Account'                     => 'Hesap',
+  'Add General Ledger Transaction' => 'Defteri Kebire Ýþlem Ekle',
+  'Address'                     => 'Adres',
+  'All'                         => 'Hepsi',
+  'Apr'                         => 'Nis',
+  'April'                       => 'Nisan',
+  'Are you sure you want to delete Transaction' => 'Ýþlemi silmek istediðinizden emin misiniz? Fiþ: ',
+  'Asset'                       => 'Aktif',
+  'Aug'                         => 'Aðu',
+  'August'                      => 'Aðustos',
+  'Balance'                     => 'Balance',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot have a value in both Debit and Credit!' => 'Borç ve Alacak hanelerine ayný anda deðer yazýlamaz!',
+  'Cannot post a transaction without a value!' => 'Cannot post a transaction without a value!',
+  'Cannot post transaction for a closed period!' => 'Cannot post transaction for a closed period!',
+  'Confirm!'                    => 'Onayla!',
+  'Continue'                    => 'Devam',
+  'Credit'                      => 'Alacak',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Tarih',
+  'Debit'                       => 'Borç',
+  'Debit and credit out of balance!' => 'Borç ve alacak eþit deðil!',
+  'Dec'                         => 'Ara',
+  'December'                    => 'Aralýk',
+  'Delete'                      => 'Sil',
+  'Description'                 => 'Açýklama',
+  'Edit General Ledger Transaction' => 'Defteri Kebir Ýþlemini Düzenle',
+  'Equity'                      => 'Sermaye',
+  'Expense'                     => 'Gider',
+  'Feb'                         => 'Þub',
+  'February'                    => 'Þubat',
+  'From'                        => 'Baþlangýç',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'GL Transaction',
+  'General Ledger'              => 'Defteri Kebir',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Raporla',
+  'Income'                      => 'Gelirler',
+  'Jan'                         => 'Oca',
+  'January'                     => 'Ocak',
+  'Jul'                         => 'Tem',
+  'July'                        => 'Temmuz',
+  'Jun'                         => 'Haz',
+  'June'                        => 'Haziran',
+  'Liability'                   => 'Pasif',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mart',
+  'May'                         => 'May',
+  'May '                        => 'Mayýs',
+  'Notes'                       => 'Notlar:',
+  'Nov'                         => 'Kas',
+  'November'                    => 'Kasým',
+  'Number'                      => 'Numara',
+  'Oct'                         => 'Eki',
+  'October'                     => 'Ekim',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Reference'                   => 'Reference',
+  'Reference missing!'          => 'Reference missing!',
+  'Reports'                     => 'Raporlar',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => 'Eyl',
+  'September'                   => 'Eylül',
+  'Source'                      => 'Kaynak',
+  'Subtotal'                    => 'Aratoplam',
+  'To'                          => 'Bitiþ',
+  'Transaction Date missing!'   => 'Ýþlem Tarihi yok!',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => 'Evet',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'devam'                       => 'continue',
+  'sil'                         => 'delete',
+  'gl_transaction'              => 'gl_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  'evet'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/ic b/sql-ledger/locale/tr/ic
new file mode 100644 (file)
index 0000000..b069b81
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Active',
+  'Add'                         => 'Ekle',
+  'Add Assembly'                => 'Grup Ekle',
+  'Add Part'                    => 'Parça Ekle',
+  'Add Purchase Order'          => 'Satýnalma Sip. Ekle',
+  'Add Sales Order'             => 'Satýþ Sipariþi Ekle',
+  'Add Service'                 => 'Hizmet Ekle',
+  'Address'                     => 'Adres',
+  'Apr'                         => 'Nis',
+  'April'                       => 'Nisan',
+  'Assemblies'                  => 'Gruplar',
+  'Assemblies restocked!'       => 'Assemblies restocked!',
+  'Assembly Number missing!'    => 'Grup Numarasý yok!',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Aðu',
+  'August'                      => 'Aðustos',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Bought'                      => 'Alýnan',
+  'COGS'                        => 'SMM',
+  'Cannot delete item already invoiced!' => 'Faturalanmýþ kalem silinemez!',
+  'Cannot delete item on order!' => 'Cannot delete item on order!',
+  'Cannot delete item which is part of an assembly!' => 'Grubun parçasý olan kalem silinemez!',
+  'Cannot delete item!'         => 'Cannot delete item!',
+  'Cannot stock assemblies!'    => 'Cannot stock assemblies!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontak',
+  'Continue'                    => 'Devam',
+  'Copies'                      => 'Copies',
+  'Dec'                         => 'Ara',
+  'December'                    => 'Aralýk',
+  'Delete'                      => 'Sil',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Açýklama',
+  'Drawing'                     => 'Drawing',
+  'E-mail'                      => 'Posta',
+  'E-mail address missing!'     => 'Posta adresi yok!',
+  'Edit Assembly'               => 'Grubu Düzenle',
+  'Edit Part'                   => 'Parçayý Düzenle',
+  'Edit Service'                => 'Hizmeti Düzenle',
+  'Expense'                     => 'Gider',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'Þub',
+  'February'                    => 'Þubat',
+  'From'                        => 'Baþlangýç',
+  'Image'                       => 'Image',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Raporla',
+  'Income'                      => 'Gelirler',
+  'Individual Items'            => 'Farklý Kalemler',
+  'Inventory'                   => 'Stok',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Bu grubu çýkarmadan önce stok miktarý sýfýr olmalýdýr',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Bu Parçayý çýkarmadan önce stok miktarý sýfýr olmalýdýr',
+  'Inventory quantity must be zero!' => 'Stok miktarý sýfýr olmalý!',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date missing!'       => 'Fatura Tarihi yok!',
+  'Invoice Number'              => 'Fatura No',
+  'Invoice Number missing!'     => 'Fatura Numarasý yok!',
+  'Item deleted!'               => 'Item deleted!',
+  'Item not on file!'           => 'Bu kalem dosyada yok!',
+  'Jan'                         => 'Oca',
+  'January'                     => 'Ocak',
+  'Jul'                         => 'Tem',
+  'July'                        => 'Temmuz',
+  'Jun'                         => 'Haz',
+  'June'                        => 'Haziran',
+  'Last Cost'                   => 'Son Maliyet',
+  'Line Total'                  => 'Line Total',
+  'Link Accounts'               => 'Baðlý Hesaplar',
+  'List Price'                  => 'Liste Fiyatý',
+  'Make'                        => 'Marka',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mart',
+  'May'                         => 'May',
+  'May '                        => 'Mayýs',
+  'Message'                     => 'Message',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => 'Model',
+  'Name'                        => 'Ýsim',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notlar:',
+  'Nov'                         => 'Kas',
+  'November'                    => 'Kasým',
+  'Number'                      => 'Numara',
+  'Number missing in Row'       => 'Sýrada Numara yok!',
+  'Obsolete'                    => 'Eski',
+  'Oct'                         => 'Eki',
+  'October'                     => 'Ekim',
+  'On Hand'                     => 'Stok:',
+  'On Order'                    => 'On Order',
+  'Order'                       => 'Sipariþ',
+  'Order Date missing!'         => 'Sipariþ Tarihi yok!',
+  'Order Number'                => 'Sipariþ No',
+  'Order Number missing!'       => 'Sipariþ Numarasý yok!',
+  'Ordered'                     => 'Ordered',
+  'Orphaned'                    => 'Orphaned',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Paketleme Listesi',
+  'Packing List Date missing!'  => 'Packing List Date missing!',
+  'Packing List Number missing!' => 'Packing List Number missing!',
+  'Part'                        => 'Parça',
+  'Part Number missing!'        => 'Parça Numarasý yok!',
+  'Parts'                       => 'Parçalar',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Fiyat',
+  'Printer'                     => 'Yazýcý',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Satýnalma Sipariþi',
+  'Qty'                         => 'Adet',
+  'ROP'                         => 'ROP',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Talep tarihi:',
+  'Sales'                       => 'Satýþlar',
+  'Sales Order'                 => 'Satýþ Sipariþi',
+  'Save'                        => 'Kaydet',
+  'Screen'                      => 'Screen',
+  'Select from one of the items below' => 'Aþaðýdaki kalemlerden birini seç',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sell Price'                  => 'Satýþ Fiyatý',
+  'Sep'                         => 'Eyl',
+  'September'                   => 'Eylül',
+  'Service'                     => 'servis',
+  'Service Number missing!'     => 'Hizmet Numarasý yok!',
+  'Services'                    => 'Servisler',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Short'                       => 'Kýsa',
+  'Sold'                        => 'satýlan',
+  'Stock Assembly'              => 'Grubu Stokla',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Aratoplam',
+  'Tax'                         => 'Vergi',
+  'To'                          => 'Bitiþ',
+  'Top Level'                   => 'Top Level',
+  'Total'                       => 'Toplam',
+  'Unit'                        => 'Birim',
+  'Unit of measure'             => 'Ölçme Birimi',
+  'Update'                      => 'Update',
+  'Updated'                     => 'Updated',
+  'Weight'                      => 'Aðýrlýk',
+  'What type of item is this?'  => 'Bu ne çeþit bir kalemdir?',
+  'ea'                          => 'ad',
+  'emailed to'                  => 'emailed to',
+  'hr'                          => 'sa',
+  'sent to printer'             => 'sent to printer',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'ekle'                        => 'add',
+  'grup_ekle'                   => 'add_assembly',
+  'parça_ekle'                  => 'add_part',
+  'hizmet_ekle'                 => 'add_service',
+  'devam'                       => 'continue',
+  'sil'                         => 'delete',
+  'grubu_düzenle'               => 'edit_assembly',
+  'parçayý_düzenle'             => 'edit_part',
+  'hizmeti_düzenle'             => 'edit_service',
+  'kaydet'                      => 'save',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/io b/sql-ledger/locale/tr/io
new file mode 100644 (file)
index 0000000..8ce89dd
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Satýnalma Sip. Ekle',
+  'Add Sales Order'             => 'Satýþ Sipariþi Ekle',
+  'Address'                     => 'Adres',
+  'Apr'                         => 'Nis',
+  'April'                       => 'Nisan',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Aðu',
+  'August'                      => 'Aðustos',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Kontak',
+  'Continue'                    => 'Devam',
+  'Copies'                      => 'Copies',
+  'Dec'                         => 'Ara',
+  'December'                    => 'Aralýk',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Açýklama',
+  'E-mail'                      => 'Posta',
+  'E-mail address missing!'     => 'Posta adresi yok!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'Þub',
+  'February'                    => 'Þubat',
+  'In-line'                     => 'In-line',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date missing!'       => 'Fatura Tarihi yok!',
+  'Invoice Number missing!'     => 'Fatura Numarasý yok!',
+  'Item not on file!'           => 'Bu kalem dosyada yok!',
+  'Jan'                         => 'Oca',
+  'January'                     => 'Ocak',
+  'Jul'                         => 'Tem',
+  'July'                        => 'Temmuz',
+  'Jun'                         => 'Haz',
+  'June'                        => 'Haziran',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mart',
+  'May'                         => 'May',
+  'May '                        => 'Mayýs',
+  'Message'                     => 'Message',
+  'Name'                        => 'Ýsim',
+  'No.'                         => 'No.',
+  'Nov'                         => 'Kas',
+  'November'                    => 'Kasým',
+  'Number'                      => 'Numara',
+  'Number missing in Row'       => 'Sýrada Numara yok!',
+  'Oct'                         => 'Eki',
+  'October'                     => 'Ekim',
+  'Order'                       => 'Sipariþ',
+  'Order Date missing!'         => 'Sipariþ Tarihi yok!',
+  'Order Number missing!'       => 'Sipariþ Numarasý yok!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Paketleme Listesi',
+  'Packing List Date missing!'  => 'Packing List Date missing!',
+  'Packing List Number missing!' => 'Packing List Number missing!',
+  'Part'                        => 'Parça',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Fiyat',
+  'Printer'                     => 'Yazýcý',
+  'Project'                     => 'Project',
+  'Purchase Order'              => 'Satýnalma Sipariþi',
+  'Qty'                         => 'Adet',
+  'Recd'                        => 'Recd',
+  'Required by'                 => 'Talep tarihi:',
+  'Sales Order'                 => 'Satýþ Sipariþi',
+  'Screen'                      => 'Screen',
+  'Select from one of the items below' => 'Aþaðýdaki kalemlerden birini seç',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Eyl',
+  'September'                   => 'Eylül',
+  'Service'                     => 'servis',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Subject'                     => 'Subject',
+  'To'                          => 'Bitiþ',
+  'Unit'                        => 'Birim',
+  'What type of item is this?'  => 'Bu ne çeþit bir kalemdir?',
+  'emailed to'                  => 'emailed to',
+  'sent to printer'             => 'sent to printer',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'devam'                       => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/ir b/sql-ledger/locale/tr/ir
new file mode 100644 (file)
index 0000000..c62536a
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Hesap',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => 'Satýnalma Sip. Ekle',
+  'Add Sales Order'             => 'Satýþ Sipariþi Ekle',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Miktar',
+  'Apr'                         => 'Nis',
+  'April'                       => 'Nisan',
+  'Are you sure you want to delete Invoice Number' => 'Fatura Numarasýný silmek istediðinizden emin misiniz? Fiþ: ',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Aðu',
+  'August'                      => 'Aðustos',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'Cannot post invoice for a closed period!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Onayla!',
+  'Contact'                     => 'Kontak',
+  'Continue'                    => 'Devam',
+  'Copies'                      => 'Copies',
+  'Currency'                    => 'Para Birimi',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Tarih',
+  'Date Due'                    => 'Vade Tarihi',
+  'Dec'                         => 'Ara',
+  'December'                    => 'Aralýk',
+  'Delete'                      => 'Sil',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Açýklama',
+  'E-mail'                      => 'Posta',
+  'E-mail address missing!'     => 'Posta adresi yok!',
+  'Edit Purchase Invoice'       => 'Edit Purchase Invoice',
+  'Exch'                        => 'D.Kuru',
+  'Exchangerate'                => 'Döviz Kuru',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'Þub',
+  'February'                    => 'Þubat',
+  'In-line'                     => 'In-line',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date'                => 'Fatura Tarihi',
+  'Invoice Date missing!'       => 'Fatura Tarihi yok!',
+  'Invoice Number'              => 'Fatura No',
+  'Invoice Number missing!'     => 'Fatura Numarasý yok!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => 'Bu kalem dosyada yok!',
+  'Jan'                         => 'Oca',
+  'January'                     => 'Ocak',
+  'Jul'                         => 'Tem',
+  'July'                        => 'Temmuz',
+  'Jun'                         => 'Haz',
+  'June'                        => 'Haziran',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mart',
+  'May'                         => 'May',
+  'May '                        => 'Mayýs',
+  'Message'                     => 'Message',
+  'Name'                        => 'Ýsim',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notlar:',
+  'Nov'                         => 'Kas',
+  'November'                    => 'Kasým',
+  'Number'                      => 'Numara',
+  'Number missing in Row'       => 'Sýrada Numara yok!',
+  'Oct'                         => 'Eki',
+  'October'                     => 'Ekim',
+  'Order'                       => 'Sipariþ',
+  'Order Date missing!'         => 'Sipariþ Tarihi yok!',
+  'Order Number'                => 'Sipariþ No',
+  'Order Number missing!'       => 'Sipariþ Numarasý yok!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Paketleme Listesi',
+  'Packing List Date missing!'  => 'Packing List Date missing!',
+  'Packing List Number missing!' => 'Packing List Number missing!',
+  'Part'                        => 'Parça',
+  'Payment date missing!'       => 'Ödeme Tarihi yok',
+  'Payments'                    => 'Ödemeler',
+  'Phone'                       => 'Telefon',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Fiyat',
+  'Printer'                     => 'Yazýcý',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Satýnalma Sipariþi',
+  'Qty'                         => 'Adet',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'Kaydet',
+  'Required by'                 => 'Talep tarihi:',
+  'Sales Order'                 => 'Satýþ Sipariþi',
+  'Screen'                      => 'Screen',
+  'Select from one of the items below' => 'Aþaðýdaki kalemlerden birini seç',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Eyl',
+  'September'                   => 'Eylül',
+  'Service'                     => 'servis',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Source'                      => 'Kaynak',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Aratoplam',
+  'Tax Included'                => 'Vergi Dahil',
+  'To'                          => 'Bitiþ',
+  'Total'                       => 'Toplam',
+  'Unit'                        => 'Birim',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Satýcý',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'Bu ne çeþit bir kalemdir?',
+  'Yes'                         => 'Evet',
+  'ea'                          => 'ad',
+  'emailed to'                  => 'emailed to',
+  'sent to printer'             => 'sent to printer',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'devam'                       => 'continue',
+  'sil'                         => 'delete',
+  'sipariþ'                     => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'update'                      => 'update',
+  'evet'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/is b/sql-ledger/locale/tr/is
new file mode 100644 (file)
index 0000000..29342c3
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Hesap',
+  'Add Purchase Order'          => 'Satýnalma Sip. Ekle',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'Satýþ Sipariþi Ekle',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Miktar',
+  'Apr'                         => 'Nis',
+  'April'                       => 'Nisan',
+  'Are you sure you want to delete Invoice Number' => 'Fatura Numarasýný silmek istediðinizden emin misiniz? Fiþ: ',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Aðu',
+  'August'                      => 'Aðustos',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'Cannot post invoice for a closed period!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Onayla!',
+  'Contact'                     => 'Kontak',
+  'Continue'                    => 'Devam',
+  'Copies'                      => 'Copies',
+  'Credit Limit'                => 'Kredi Limiti',
+  'Currency'                    => 'Para Birimi',
+  'Customer'                    => 'Alýcý',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Tarih',
+  'Date Due'                    => 'Vade Tarihi',
+  'Dec'                         => 'Ara',
+  'December'                    => 'Aralýk',
+  'Delete'                      => 'Sil',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Açýklama',
+  'E-mail'                      => 'Posta',
+  'E-mail address missing!'     => 'Posta adresi yok!',
+  'Edit Sales Invoice'          => 'Edit Sales Invoice',
+  'Exch'                        => 'D.Kuru',
+  'Exchangerate'                => 'Döviz Kuru',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'Þub',
+  'February'                    => 'Þubat',
+  'In-line'                     => 'In-line',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date'                => 'Fatura Tarihi',
+  'Invoice Date missing!'       => 'Fatura Tarihi yok!',
+  'Invoice Number'              => 'Fatura No',
+  'Invoice Number missing!'     => 'Fatura Numarasý yok!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => 'Bu kalem dosyada yok!',
+  'Jan'                         => 'Oca',
+  'January'                     => 'Ocak',
+  'Jul'                         => 'Tem',
+  'July'                        => 'Temmuz',
+  'Jun'                         => 'Haz',
+  'June'                        => 'Haziran',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mart',
+  'May'                         => 'May',
+  'May '                        => 'Mayýs',
+  'Message'                     => 'Message',
+  'Name'                        => 'Ýsim',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notlar:',
+  'Nov'                         => 'Kas',
+  'November'                    => 'Kasým',
+  'Number'                      => 'Numara',
+  'Number missing in Row'       => 'Sýrada Numara yok!',
+  'Oct'                         => 'Eki',
+  'October'                     => 'Ekim',
+  'Order'                       => 'Sipariþ',
+  'Order Date missing!'         => 'Sipariþ Tarihi yok!',
+  'Order Number'                => 'Sipariþ No',
+  'Order Number missing!'       => 'Sipariþ Numarasý yok!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Paketleme Listesi',
+  'Packing List Date missing!'  => 'Packing List Date missing!',
+  'Packing List Number missing!' => 'Packing List Number missing!',
+  'Part'                        => 'Parça',
+  'Payment date missing!'       => 'Ödeme Tarihi yok',
+  'Payments'                    => 'Ödemeler',
+  'Phone'                       => 'Telefon',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Fiyat',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Yazýcý',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Satýnalma Sipariþi',
+  'Qty'                         => 'Adet',
+  'Recd'                        => 'Recd',
+  'Record in'                   => 'Kaydet',
+  'Remaining'                   => 'Remaining',
+  'Required by'                 => 'Talep tarihi:',
+  'Sales Order'                 => 'Satýþ Sipariþi',
+  'Screen'                      => 'Screen',
+  'Select from one of the items below' => 'Aþaðýdaki kalemlerden birini seç',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Eyl',
+  'September'                   => 'Eylül',
+  'Service'                     => 'servis',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Source'                      => 'Kaynak',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Aratoplam',
+  'Tax Included'                => 'Vergi Dahil',
+  'To'                          => 'Bitiþ',
+  'Total'                       => 'Toplam',
+  'Unit'                        => 'Birim',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'Bu ne çeþit bir kalemdir?',
+  'Yes'                         => 'Evet',
+  'ea'                          => 'ad',
+  'emailed to'                  => 'emailed to',
+  'sent to printer'             => 'sent to printer',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'devam'                       => 'continue',
+  'sil'                         => 'delete',
+  'posta'                       => 'e_mail',
+  'sipariþ'                     => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'evet'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/login b/sql-ledger/locale/tr/login
new file mode 100644 (file)
index 0000000..3c6fb0b
--- /dev/null
@@ -0,0 +1,28 @@
+$self{texts} = {
+  'About'                       => 'Program bilgileri',
+  'Accounting'                  => 'Muhasebe',
+  'Database Host'               => 'Veritabaný Hostu',
+  'Dataset'                     => 'Veriseti',
+  'Incorrect Dataset version!'  => 'Incorrect Dataset version!',
+  'Incorrect Password!'         => 'Yanlýþ Þifre!',
+  'Licensed to'                 => 'Lisans Sahibi:',
+  'Login'                       => 'Giriþ',
+  'Name'                        => 'Ýsim',
+  'Password'                    => 'Þifre',
+  'User'                        => 'Kullanýcý',
+  'Version'                     => 'Versiyon',
+  'You are logged out!'         => 'You are logged out!',
+  'You did not enter a name!'   => 'Ýsim girmediniz!',
+  'is not a member!'            => 'is not a member!',
+  'localhost'                   => 'Yerelhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'giriþ'                       => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/menu b/sql-ledger/locale/tr/menu
new file mode 100644 (file)
index 0000000..45a4296
--- /dev/null
@@ -0,0 +1,72 @@
+$self{texts} = {
+  'AP'                          => 'Borçlar',
+  'AP Aging'                    => 'Gecikmiþ Borçlar',
+  'AR'                          => 'Alacaklar',
+  'AR Aging'                    => 'Gecikmiþ Alacaklar',
+  'Accounting Menu'             => 'Muhasebe Menüsü',
+  'Add Account'                 => 'Hesap Ekle',
+  'Add Assembly'                => 'Grup Ekle',
+  'Add Customer'                => 'Alýcý Ekle',
+  'Add GIFI'                    => 'Add GIFI',
+  'Add Part'                    => 'Parça Ekle',
+  'Add Project'                 => 'Add Project',
+  'Add Service'                 => 'Hizmet Ekle',
+  'Add Transaction'             => 'Ýþlem Ekle',
+  'Add Vendor'                  => 'Satýcý Ekle',
+  'Assemblies'                  => 'Gruplar',
+  'Audit Control'               => 'Audit Control',
+  'Backup'                      => 'Yedekleme',
+  'Balance Sheet'               => 'Bilanço',
+  'Cash'                        => 'Cash',
+  'Chart of Accounts'           => 'Hesap Planý',
+  'Check'                       => 'Check',
+  'Customers'                   => 'Customers',
+  'General Ledger'              => 'Defteri Kebir',
+  'Goods & Services'            => 'Goods & Services',
+  'HTML Templates'              => 'HTML Templates',
+  'Income Statement'            => 'Gelir Tablosu',
+  'Invoice'                     => 'Fatura',
+  'LaTeX Templates'             => 'LaTeX Templates',
+  'List Accounts'               => 'List Accounts',
+  'List GIFI'                   => 'List GIFI',
+  'Logout'                      => 'Logout',
+  'Order Entry'                 => 'Sipariþ Giriþi',
+  'Packing List'                => 'Paketleme Listesi',
+  'Parts'                       => 'Parçalar',
+  'Payment'                     => 'Ödeme',
+  'Payments'                    => 'Ödemeler',
+  'Preferences'                 => 'Tercihler',
+  'Projects'                    => 'Projects',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Purchase Order'              => 'Satýnalma Sipariþi',
+  'Purchase Orders'             => 'Satýnalma Sipariþleri',
+  'Receipt'                     => 'Receipt',
+  'Receipts'                    => 'Receipts',
+  'Reconciliation'              => 'Reconciliation',
+  'Reports'                     => 'Raporlar',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Sales Order'                 => 'Satýþ Sipariþi',
+  'Sales Orders'                => 'Satýþ Sipariþleri',
+  'Save to File'                => 'Dosyaya Kaydet',
+  'Send by E-Mail'              => 'E-postayla gönder',
+  'Services'                    => 'Servisler',
+  'Statement'                   => 'Statement',
+  'Stock Assembly'              => 'Grubu Stokla',
+  'Stylesheet'                  => 'Düzen Sayfasý',
+  'System'                      => 'System',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'Transactions'                => 'Ýþlemler',
+  'Trial Balance'               => 'Proforma Bilanço',
+  'Vendors'                     => 'Vendors',
+  'Version'                     => 'Versiyon',
+  'localhost'                   => 'Yerelhost',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/oe b/sql-ledger/locale/tr/oe
new file mode 100644 (file)
index 0000000..31415c6
--- /dev/null
@@ -0,0 +1,199 @@
+$self{texts} = {
+  'Add'                         => 'Ekle',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => 'Satýnalma Sip. Ekle',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => 'Satýþ Sipariþi Ekle',
+  'Address'                     => 'Adres',
+  'Amount'                      => 'Miktar',
+  'Apr'                         => 'Nis',
+  'April'                       => 'Nisan',
+  'Are you sure you want to delete Order Number' => 'Sipariþ Numarasýný silmek istediðinizden emin misiniz? Fiþ: ',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Aðu',
+  'August'                      => 'Aðustos',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Bin',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Cannot delete order!',
+  'Cannot save order!'          => 'Cannot save order!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Closed',
+  'Confirm!'                    => 'Onayla!',
+  'Contact'                     => 'Kontak',
+  'Continue'                    => 'Devam',
+  'Copies'                      => 'Copies',
+  'Credit Limit'                => 'Kredi Limiti',
+  'Curr'                        => 'Curr',
+  'Currency'                    => 'Para Birimi',
+  'Customer'                    => 'Alýcý',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => 'Tarih',
+  'Dec'                         => 'Ara',
+  'December'                    => 'Aralýk',
+  'Delete'                      => 'Sil',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => 'Açýklama',
+  'E-mail'                      => 'Posta',
+  'E-mail address missing!'     => 'Posta adresi yok!',
+  'Edit Purchase Order'         => 'Alýþ Sipariþini Düzenle',
+  'Edit Sales Order'            => 'Satýþ Sipariþini Düzenle',
+  'Exchangerate'                => 'Döviz Kuru',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => 'Faks',
+  'Feb'                         => 'Þub',
+  'February'                    => 'Þubat',
+  'From'                        => 'Baþlangýç',
+  'ID'                          => 'ID',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Raporla',
+  'Invoice'                     => 'Fatura',
+  'Invoice Date missing!'       => 'Fatura Tarihi yok!',
+  'Invoice Number missing!'     => 'Fatura Numarasý yok!',
+  'Item not on file!'           => 'Bu kalem dosyada yok!',
+  'Jan'                         => 'Oca',
+  'January'                     => 'Ocak',
+  'Jul'                         => 'Tem',
+  'July'                        => 'Temmuz',
+  'Jun'                         => 'Haz',
+  'June'                        => 'Haziran',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mart',
+  'May'                         => 'May',
+  'May '                        => 'Mayýs',
+  'Message'                     => 'Message',
+  'Name'                        => 'Ýsim',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Notlar:',
+  'Nov'                         => 'Kas',
+  'November'                    => 'Kasým',
+  'Number'                      => 'Numara',
+  'Number missing in Row'       => 'Sýrada Numara yok!',
+  'O'                           => 'O',
+  'Oct'                         => 'Eki',
+  'October'                     => 'Ekim',
+  'Open'                        => 'Open',
+  'Order'                       => 'Sipariþ',
+  'Order Date'                  => 'Sipariþ Tarihi',
+  'Order Date missing!'         => 'Sipariþ Tarihi yok!',
+  'Order Number'                => 'Sipariþ No',
+  'Order Number missing!'       => 'Sipariþ Numarasý yok!',
+  'Order deleted!'              => 'Order deleted!',
+  'Order saved!'                => 'Order saved!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Paketleme Listesi',
+  'Packing List Date missing!'  => 'Packing List Date missing!',
+  'Packing List Number missing!' => 'Packing List Number missing!',
+  'Part'                        => 'Parça',
+  'Phone'                       => 'Telefon',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Fiyat',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Yazýcý',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => 'Satýnalma Sipariþi',
+  'Purchase Orders'             => 'Satýnalma Sipariþleri',
+  'Qty'                         => 'Adet',
+  'Recd'                        => 'Recd',
+  'Remaining'                   => 'Remaining',
+  'Required by'                 => 'Talep tarihi:',
+  'Sales Order'                 => 'Satýþ Sipariþi',
+  'Sales Orders'                => 'Satýþ Sipariþleri',
+  'Save'                        => 'Kaydet',
+  'Save as new'                 => 'Save as new',
+  'Screen'                      => 'Screen',
+  'Select from one of the items below' => 'Aþaðýdaki kalemlerden birini seç',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Eyl',
+  'September'                   => 'Eylül',
+  'Service'                     => 'servis',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Aratoplam',
+  'Tax'                         => 'Vergi',
+  'Tax Included'                => 'Vergi Dahil',
+  'Terms: Net'                  => 'Þartlar: Net',
+  'To'                          => 'Bitiþ',
+  'Total'                       => 'Toplam',
+  'Unit'                        => 'Birim',
+  'Update'                      => 'Update',
+  'Vendor'                      => 'Satýcý',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => 'Bu ne çeþit bir kalemdir?',
+  'Yes'                         => 'Evet',
+  'days'                        => 'gün. ',
+  'ea'                          => 'ad',
+  'emailed to'                  => 'emailed to',
+  'sent to printer'             => 'sent to printer',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'ekle'                        => 'add',
+  'devam'                       => 'continue',
+  'sil'                         => 'delete',
+  'posta'                       => 'e_mail',
+  'fatura'                      => 'invoice',
+  'print'                       => 'print',
+  'kaydet'                      => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'evet'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/pe b/sql-ledger/locale/tr/pe
new file mode 100644 (file)
index 0000000..d010eca
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Ekle',
+  'Add Project'                 => 'Add Project',
+  'All'                         => 'Hepsi',
+  'Continue'                    => 'Devam',
+  'Delete'                      => 'Sil',
+  'Description'                 => 'Açýklama',
+  'Edit Project'                => 'Edit Project',
+  'Number'                      => 'Numara',
+  'Orphaned'                    => 'Orphaned',
+  'Project'                     => 'Project',
+  'Project Number missing!'     => 'Project Number missing!',
+  'Project deleted!'            => 'Project deleted!',
+  'Project saved!'              => 'Project saved!',
+  'Projects'                    => 'Projects',
+  'Save'                        => 'Kaydet',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'ekle'                        => 'add',
+  'devam'                       => 'continue',
+  'sil'                         => 'delete',
+  'kaydet'                      => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/rc b/sql-ledger/locale/tr/rc
new file mode 100644 (file)
index 0000000..4e71d0c
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Hesap',
+  'Balance'                     => 'Balance',
+  'Cleared Balance'             => 'Cleared Balance',
+  'Continue'                    => 'Devam',
+  'Date'                        => 'Tarih',
+  'Deposit'                     => 'Deposit',
+  'Description'                 => 'Açýklama',
+  'Difference'                  => 'Difference',
+  'Done'                        => 'Done',
+  'Exchangerate Difference'     => 'Exchangerate Difference',
+  'From'                        => 'Baþlangýç',
+  'Out of balance!'             => 'Out of balance!',
+  'Payment'                     => 'Ödeme',
+  'Reconciliation'              => 'Reconciliation',
+  'Select all'                  => 'Select all',
+  'Source'                      => 'Kaynak',
+  'Statement Balance'           => 'Statement Balance',
+  'To'                          => 'Bitiþ',
+  'Update'                      => 'Update',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'devam'                       => 'continue',
+  'done'                        => 'done',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/tr/rp b/sql-ledger/locale/tr/rp
new file mode 100644 (file)
index 0000000..7807262
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'Gecikmiþ Borçlar',
+  'AR Aging'                    => 'Gecikmiþ Alacaklar',
+  'Account'                     => 'Hesap',
+  'Accounts'                    => 'Accounts',
+  'Amount'                      => 'Miktar',
+  'Apr'                         => 'Nis',
+  'April'                       => 'Nisan',
+  'Attachment'                  => 'Attachment',
+  'Aug'                         => 'Aðu',
+  'August'                      => 'Aðustos',
+  'Balance Sheet'               => 'Bilanço',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Cash based',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => '...kýyasla',
+  'Continue'                    => 'Devam',
+  'Copies'                      => 'Copies',
+  'Credit'                      => 'Alacak',
+  'Current'                     => 'Current',
+  'Customer'                    => 'Alýcý',
+  'Date'                        => 'Tarih',
+  'Debit'                       => 'Borç',
+  'Dec'                         => 'Ara',
+  'December'                    => 'Aralýk',
+  'Decimalplaces'               => 'Decimalplaces',
+  'Description'                 => 'Açýklama',
+  'Due'                         => 'Vade',
+  'E-mail'                      => 'Posta',
+  'E-mail Statement to'         => 'E-mail Statement to',
+  'Feb'                         => 'Þub',
+  'February'                    => 'Þubat',
+  'From'                        => 'Baþlangýç',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Baþlýk',
+  'ID'                          => 'ID',
+  'In-line'                     => 'In-line',
+  'Include in Report'           => 'Raporla',
+  'Income Statement'            => 'Gelir Tablosu',
+  'Invoice'                     => 'Fatura',
+  'Jan'                         => 'Oca',
+  'January'                     => 'Ocak',
+  'Jul'                         => 'Tem',
+  'July'                        => 'Temmuz',
+  'Jun'                         => 'Haz',
+  'June'                        => 'Haziran',
+  'Mar'                         => 'Mar',
+  'March'                       => 'Mart',
+  'May'                         => 'May',
+  'May '                        => 'Mayýs',
+  'Message'                     => 'Message',
+  'N/A'                         => 'N/A',
+  'Nothing selected!'           => 'Nothing selected!',
+  'Nov'                         => 'Kas',
+  'November'                    => 'Kasým',
+  'Oct'                         => 'Eki',
+  'October'                     => 'Ekim',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Ödemeler',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Print',
+  'Printer'                     => 'Yazýcý',
+  'Receipts'                    => 'Receipts',
+  'Report for'                  => 'Report for',
+  'Retained Earnings'           => 'Net Dönem Karý (Zararý)',
+  'Screen'                      => 'Screen',
+  'Select all'                  => 'Select all',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => 'Eyl',
+  'September'                   => 'Eylül',
+  'Source'                      => 'Kaynak',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Statement',
+  'Statement sent to'           => 'Statement sent to',
+  'Statements sent to printer!' => 'Statements sent to printer!',
+  'Subject'                     => 'Subject',
+  'Subtotal'                    => 'Aratoplam',
+  'Tax'                         => 'Vergi',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'To'                          => 'Bitiþ',
+  'Total'                       => 'Toplam',
+  'Trial Balance'               => 'Proforma Bilanço',
+  'Vendor'                      => 'Satýcý',
+  'as at'                       => 'as at',
+  'collected on sales'          => 'collected on sales',
+  'for Period'                  => 'Dönem:',
+  'paid on purchases'           => 'paid on purchases',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'devam'                       => 'continue',
+  'posta'                       => 'e_mail',
+  'print'                       => 'print',
+  'select_all'                  => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/COPYING b/sql-ledger/locale/tw/COPYING
new file mode 100644 (file)
index 0000000..835a214
--- /dev/null
@@ -0,0 +1,25 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+# Traditional Chinese texts:
+#
+#  Author: ¤è²»³Ç (Jacky Fang) <jackyf@5star.com.tw>
+#          Chien Hsin Chang <werther@elixus.org>
+#          Autrijus Tang <autrijus@autrijus.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/tw/LANGUAGE b/sql-ledger/locale/tw/LANGUAGE
new file mode 100644 (file)
index 0000000..b8ba9c3
--- /dev/null
@@ -0,0 +1 @@
+Traditional Chinese
diff --git a/sql-ledger/locale/tw/admin b/sql-ledger/locale/tw/admin
new file mode 100644 (file)
index 0000000..6c19c11
--- /dev/null
@@ -0,0 +1,122 @@
+$self{texts} = {
+  'Access Control'              => 'Åv­­±±¨î',
+  'Accounting'                  => '·|­p',
+  'Add User'                    => '·s¼W¨Ï¥ÎªÌ',
+  'Address'                     => '¦a§}',
+  'Administration'              => '¨t²ÎºÞ²z',
+  'Administrator'               => 'Administrator',
+  'All Datasets up to date!'    => '©Ò¦³¸ê®Æ¬Ò¤w§ó·s!',
+  'Change Admin Password'       => '§ó§ïºÞ²z­û±K½X',
+  'Change Password'             => '§ó§ï±K½X',
+  'Character Set'               => '¦r¤¸¶°',
+  'Click on login name to edit!' => '½Ð«öµn¤J¦WºÙ¥H¶i¦æ­×§ï!',
+  'Company'                     => '¤½¥q¦WºÙ',
+  'Connect to'                  => '³sµ²¨ì',
+  'Continue'                    => 'Ä~Äò',
+  'Create Chart of Accounts'    => '«Ø¥ß±b¤á¹Ïªí',
+  'Create Dataset'              => '«Ø¥ß¸ê®Æ¶°',
+  'DBI not installed!'          => '¥¼¦w¸Ë DBI ¼Ò²Õ!',
+  'Database'                    => '¸ê®Æ®w',
+  'Database Administration'     => '¸ê®Æ®wºÞ²z',
+  'Database Driver not checked!' => '¥¼¿ï©w¸ê®Æ®wÅX°Êµ{¦¡!',
+  'Database User missing!'      => '¥¼«ü©ú¸ê®Æ®w¨Ï¥ÎªÌ!',
+  'Dataset'                     => '¸ê®Æ¶°',
+  'Dataset missing!'            => '¥¼«ü©ú¸ê®Æ¶°!',
+  'Dataset updated!'            => 'Dataset updated!',
+  'Date Format'                 => '¤é´Á®æ¦¡',
+  'Delete'                      => '§R°£',
+  'Delete Dataset'              => '§R°£¸ê®Æ¶°',
+  'Directory'                   => '¥Ø¿ý',
+  'Driver'                      => 'ÅX°Êµ{¦¡',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => '¹q¤l¶l¥ó',
+  'Edit User'                   => '½s¿è¨Ï¥ÎªÌ',
+  'Existing Datasets'           => '¬J¦³ªº¸ê®Æ¶°',
+  'Fax'                         => '¶Ç¯u',
+  'Host'                        => '¥D¾÷',
+  'Hostname missing!'           => '¥¼«ü©ú¥D¾÷¦WºÙ!',
+  'Incorrect Password!'         => '±K½X¿ù»~!',
+  'Language'                    => '»y¨t',
+  'Leave host and port field empty unless you want to make a remote connection.' => '°£«D±z·Q­n¶i¦æ»·ºÝ³s½u, §_«h½Ð±N¥D¾÷¤Î°ð¸¹¯d¥Õ.',
+  'Login'                       => 'µn¤J',
+  'Name'                        => '¦WºÙ',
+  'New Templates'               => '·s¼W¼Òª©',
+  'No Database Drivers available!' => '¨S¦³¥i¥ÎªºÅX°Êµ{¦¡!',
+  'No Dataset selected!'        => '¥¼¿ï©w¸ê®Æ¶°!',
+  'Nothing to delete!'          => '¨S¦³¥i§R°£ªº¶µ¥Ø',
+  'Number Format'               => '¼Æ¦r®æ¦¡',
+  'Oracle Database Administration' => 'Oracle ¸ê®Æ®wºÞ²z',
+  'Password'                    => '±K½X',
+  'Password changed!'           => 'Password changed!',
+  'Pg Database Administration'  => 'Pg ¸ê®Æ®wºÞ²z',
+  'Phone'                       => '¹q¸Ü¸¹½X',
+  'Port'                        => '°ð¸¹',
+  'Port missing!'               => '¥¼«ü©ú°ð¸¹!',
+  'Printer'                     => '¦Lªí¾÷',
+  'Save'                        => 'Àx¦s',
+  'Select a Dataset to delete and press "Continue"' => '½Ð¿ï¾Ü±ý§R°£ªº¸ê®Æ¶°, ¦A«ö "Ä~Äò"',
+  'Setup Templates'             => '³]©w¼Òª©',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'ñ¦W',
+  'Stylesheet'                  => '¼Ë¦¡ªí',
+  'Templates'                   => '¼Òª©',
+  'The following Datasets are not in use and can be deleted' => '¤U¦C¸ê®Æ¶°¨Ã¥¼¨Ï¥Î, ¥i¥H§R°£',
+  'The following Datasets need to be updated' => '¤U¦C¸ê®Æ¶°»Ý­n§ó·s',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => '³o¬O¹ï¬J¦s¸ê®Æ¨Ó·½ªºªì¨BÀˬd. ¦b¦¹¶¥¬q, ¤£·|§R°£©Î·s¼W¥ô¦ó¸ê®Æ!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => '­Y­n·s¼W¸s²Õ¤ºªº¨Ï¥ÎªÌ, ½Ð½s¿è¦WºÙ, §ó§ïµn¤J¦W, µM«áÀx¦s.  ³o¼Ë¤@¨Ó, ·s¨Ï¥ÎªÌ·|«O¯d¬Û¦PªºÅܼÆ, ¨Ã¥H·sªºµn¤J¦W¦s¤J.',
+  'Update Dataset'              => '§ó·s¸ê®Æ¶°',
+  'Use Templates'               => '¨Ï¥Î¼Òª©',
+  'User'                        => '¨Ï¥ÎªÌ',
+  'User deleted!'               => 'User deleted!',
+  'User saved!'                 => 'User saved!',
+  'Version'                     => 'ª©¥»',
+  'You must enter a host and port for local and remote connections!' => '±z¥²»ÝÁä¤J¥D¾÷¤Î°ð¸¹, ¥H¶i¦æ¥»¾÷©Î»·ºÝ³s½u!',
+  'does not exist'              => '¤£¦s¦b',
+  'is already a member!'        => '¤w¸g¬O¦¨­û¤F!',
+  'localhost'                   => 'localhost',
+  'successfully created!'       => '¦¨¥\«Ø¥ß!',
+  'successfully deleted!'       => '¦¨¥\§R°£!',
+  'website'                     => 'ºô¯¸',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  '·s¼w¨Ï¥ÎªÌ'                  => 'add_user',
+  '§ó§ïºÞ²z­û±k½x'              => 'change_admin_password',
+  '§ó§ï±k½x'                    => 'change_password',
+  'Ä~Äò'                        => 'continue',
+  '«Ø¥ß¸ê®Æ¶°'                  => 'create_dataset',
+  '§r°£'                        => 'delete',
+  '§r°£¸ê®Æ¶°'                  => 'delete_dataset',
+  'µn¤j'                        => 'login',
+  'oracle_¸ê®Æ®wºÞ²z'           => 'oracle_database_administration',
+  'pg_¸ê®Æ®wºÞ²z'               => 'pg_database_administration',
+  'Àx¦s'                        => 'save',
+  '§ó·s¸ê®Æ¶°'                  => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/all b/sql-ledger/locale/tw/all
new file mode 100644 (file)
index 0000000..016df2c
--- /dev/null
@@ -0,0 +1,487 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'À³¥I±b´Ú',
+  'AP Aging'                    => 'À³¥I±bÄÖ¤ÀªR',
+  'AP Transaction'              => '',
+  'AP Transactions'             => 'À³¥I±b¥Ø',
+  'AR'                          => 'À³¦¬±b´Ú',
+  'AR Aging'                    => 'À³¦¬±bÄÖ¤ÀªR',
+  'AR Transaction'              => '',
+  'AR Transactions'             => 'À³¦¬±b¥Ø',
+  'About'                       => 'Ãö©ó',
+  'Access Control'              => 'Åv­­±±¨î',
+  'Account'                     => '¬ì¥Ø',
+  'Account Number'              => '¬ì¥Ø½s¸¹',
+  'Account Number missing!'     => 'º|¶ñ¬ì¥Ø½s¸¹!',
+  'Account Type'                => '¬ì¥ØÃþ§O',
+  'Account Type missing!'       => 'º|¶ñ¬ì¥ØÃþ§O!',
+  'Account deleted!'            => '',
+  'Account saved!'              => '',
+  'Accounting'                  => '·|­p',
+  'Accounting Menu'             => '·|­p¿ï³æ',
+  'Accounts'                    => '±b¤á',
+  'Active'                      => '',
+  'Add'                         => '·s¼W',
+  'Add Account'                 => '·s¼W¬ì¥Ø',
+  'Add Accounts Payables Transaction' => '',
+  'Add Accounts Receivables Transaction' => '',
+  'Add Assembly'                => '·s¼W°Ó«~',
+  'Add Customer'                => '·s¼W«È¤á',
+  'Add GIFI'                    => '·s¼W GIFI',
+  'Add General Ledger Transaction' => '·s¼WÁ`±b',
+  'Add Part'                    => '·s¼W­ì®Æ',
+  'Add Project'                 => '',
+  'Add Purchase Invoice'        => '',
+  'Add Purchase Order'          => '·s¼W±ÄÁʳæ',
+  'Add Sales Invoice'           => '',
+  'Add Sales Order'             => '·s¼W¾P³f³æ',
+  'Add Service'                 => '·s¼WªA°È',
+  'Add Transaction'             => '·s¼W±b¥Ø',
+  'Add User'                    => '·s¼W¨Ï¥ÎªÌ',
+  'Add Vendor'                  => '·s¼W¼t°Ó',
+  'Address'                     => '¦a§}',
+  'Administration'              => '¨t²ÎºÞ²z',
+  'Administrator'               => '',
+  'All'                         => '¥þ³¡',
+  'All Datasets up to date!'    => '©Ò¦³¸ê®Æ¬Ò¤w§ó·s!',
+  'Amount'                      => 'Á`­p',
+  'Amount Due'                  => '',
+  'Amount does not equal applied!' => '',
+  'Amount missing!'             => '',
+  'Applied'                     => '',
+  'Apr'                         => '¥|¤ë',
+  'April'                       => '¥|¤ë',
+  'Are you sure you want to delete Invoice Number' => '±z½T©w­n§R°£µo²¼½s¸¹',
+  'Are you sure you want to delete Order Number' => '±z¬O§_½T©w­n§R°£­q³æ',
+  'Are you sure you want to delete Transaction' => '±z½T©w­n§R°£±b¥Ø',
+  'Assemblies'                  => '°Ó«~',
+  'Assemblies restocked!'       => '',
+  'Assembly Number missing!'    => '¬dµL¦¹°Ó«~!',
+  'Asset'                       => '¸ê²£',
+  'Attachment'                  => 'ªþÀÉ',
+  'Audit Control'               => '½]®Ö±±¨î',
+  'Aug'                         => '¤K¤ë',
+  'August'                      => '¤K¤ë',
+  'BOM'                         => '',
+  'Backup'                      => '³Æ¥÷',
+  'Backup sent to'              => '³Æ¥÷±H°e¨ì',
+  'Balance'                     => '',
+  'Balance Sheet'               => '¸ê²£­t¶Åªí',
+  'Bcc'                         => '',
+  'Bin'                         => '½c',
+  'Books are open'              => '±bï¤w¶}±Ò',
+  'Bought'                      => '¤wÁʶR',
+  'Business Number'             => '²Î¤@½s¸¹',
+  'C'                           => '',
+  'COGS'                        => '³f¾P¦¨¥»',
+  'Cannot delete account!'      => '',
+  'Cannot delete customer!'     => '',
+  'Cannot delete default account!' => '',
+  'Cannot delete invoice!'      => '',
+  'Cannot delete item already invoiced!' => '',
+  'Cannot delete item on order!' => 'µLªk§R°£³æ¤Wªº¶µ¥Ø!',
+  'Cannot delete item which is part of an assembly!' => '',
+  'Cannot delete item!'         => '',
+  'Cannot delete order!'        => '',
+  'Cannot delete transaction!'  => '',
+  'Cannot delete vendor!'       => '',
+  'Cannot have a value in both Debit and Credit!' => '',
+  'Cannot post a transaction without a value!' => '',
+  'Cannot post invoice for a closed period!' => '',
+  'Cannot post invoice!'        => '',
+  'Cannot post payment for a closed period!' => '',
+  'Cannot post payment!'        => '',
+  'Cannot post transaction for a closed period!' => 'µLªk¦b¤wÃö³¬ªº®É¬q¤º¥[¤J¥æ©ö!',
+  'Cannot post transaction!'    => '',
+  'Cannot process payment for a closed period!' => '',
+  'Cannot save account!'        => '',
+  'Cannot save order!'          => '',
+  'Cannot save preferences!'    => '',
+  'Cannot stock assemblies!'    => '',
+  'Cash'                        => '',
+  'Cash based'                  => '',
+  'Cc'                          => '',
+  'Change Admin Password'       => '§ó§ïºÞ²z­û±K½X',
+  'Change Password'             => '§ó§ï±K½X',
+  'Character Set'               => '¦r¤¸¶°',
+  'Chart of Accounts'           => '·|­p¬ì¥Øªí',
+  'Check'                       => '',
+  'Check printed!'              => '',
+  'Check printing failed!'      => '',
+  'Cleared Balance'             => '',
+  'Click on login name to edit!' => '½Ð«öµn¤J¦WºÙ¥H¶i¦æ­×§ï!',
+  'Close Books up to'           => 'Ãö³¬¨ì¦¹¬°¤îªº±bï',
+  'Closed'                      => '¤wÃö³¬',
+  'Company'                     => '¤½¥q¦WºÙ',
+  'Compare to'                  => '¹ï·Ó',
+  'Confirm!'                    => '¤J±b¦¨¥\!',
+  'Connect to'                  => '³sµ²¨ì',
+  'Contact'                     => '³sµ¸¤H',
+  'Continue'                    => 'Ä~Äò',
+  'Copies'                      => '«þ¨©',
+  'Copy to COA'                 => '½Æ»s¨ì COA',
+  'Create Chart of Accounts'    => '«Ø¥ß±b¤á¹Ïªí',
+  'Create Dataset'              => '«Ø¥ß¸ê®Æ¶°',
+  'Credit'                      => '¶U¤è',
+  'Credit Limit'                => '«H¥ÎÃB«×',
+  'Curr'                        => '¥Ø«e',
+  'Currency'                    => '¹ô§O',
+  'Current'                     => '',
+  'Customer'                    => '«È¤á',
+  'Customer deleted!'           => '',
+  'Customer missing!'           => '',
+  'Customer not on file!'       => '',
+  'Customer saved!'             => '',
+  'Customers'                   => '',
+  'DBI not installed!'          => '¥¼¦w¸Ë DBI ¼Ò²Õ!',
+  'Database'                    => '¸ê®Æ®w',
+  'Database Administration'     => '¸ê®Æ®wºÞ²z',
+  'Database Driver not checked!' => '¥¼¿ï©w¸ê®Æ®wÅX°Êµ{¦¡!',
+  'Database Host'               => '¸ê®Æ®w¥D¾÷',
+  'Database User missing!'      => '¥¼«ü©ú¸ê®Æ®w¨Ï¥ÎªÌ!',
+  'Dataset'                     => '¸ê®Æ¶°',
+  'Dataset missing!'            => '¥¼«ü©ú¸ê®Æ¶°!',
+  'Dataset updated!'            => '',
+  'Date'                        => '¤é´Á',
+  'Date Due'                    => 'À³¥I¤é´Á',
+  'Date Format'                 => '¤é´Á®æ¦¡',
+  'Date Paid'                   => '¥I´Ú¤é´Á',
+  'Date missing!'               => '',
+  'Debit'                       => '­É¤è',
+  'Debit and credit out of balance!' => '­É¶U¤£¥­¿Å!',
+  'Dec'                         => '¤Q¤G¤ë',
+  'December'                    => '¤Q¤G¤ë',
+  'Decimalplaces'               => '',
+  'Delete'                      => '§R°£',
+  'Delete Account'              => '§R°£¬ì¥Ø',
+  'Delete Dataset'              => '§R°£¸ê®Æ¶°',
+  'Delivery Date'               => '',
+  'Deposit'                     => '',
+  'Description'                 => '»¡©ú',
+  'Difference'                  => '',
+  'Directory'                   => '¥Ø¿ý',
+  'Discount'                    => '§é¦©',
+  'Done'                        => '',
+  'Drawing'                     => '',
+  'Driver'                      => 'ÅX°Êµ{¦¡',
+  'Dropdown Limit'              => '',
+  'Due'                         => '¨ì´Á',
+  'Due Date'                    => '¨ì´Á¤é',
+  'Due Date missing!'           => 'º|¶ñ¨ì´Á¤é!',
+  'E-mail'                      => '¹q¤l¶l¥ó',
+  'E-mail Statement to'         => '',
+  'E-mail address missing!'     => 'º|¶ñ¹q¤l¶l¥ó¦ì§}!',
+  'Edit'                        => '',
+  'Edit Account'                => '½s¿è¬ì¥Ø',
+  'Edit Accounts Payables Transaction' => '',
+  'Edit Accounts Receivables Transaction' => '',
+  'Edit Assembly'               => '½s¿è°Ó«~',
+  'Edit GIFI'                   => '½s¿è GIFI',
+  'Edit General Ledger Transaction' => '½s¿èÁ`±b',
+  'Edit Part'                   => '½s¿è­ì®Æ',
+  'Edit Preferences for'        => '³]©w¨Ï¥ÎªÌ',
+  'Edit Project'                => '',
+  'Edit Purchase Invoice'       => '',
+  'Edit Purchase Order'         => '½s¿è±ÄÁʳæ',
+  'Edit Sales Invoice'          => '',
+  'Edit Sales Order'            => '½s¿è¾P³f³æ',
+  'Edit Service'                => '½s¿èªA°È',
+  'Edit Template'               => '½s¿è¼Òª©',
+  'Edit User'                   => '½s¿è¨Ï¥ÎªÌ',
+  'Employee'                    => '',
+  'Enforce transaction reversal for all dates' => '±j¨î©Ò¦³¤é´Áªº¥æ©ö¦^´_',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => '½ÐÁä¤J¥H«_¸¹¤À¹jªº­^¤å¦r¥À, ¨C¶µ¤£¶W¹L¤T­Ó¦r (¦p CAD:USD:EUR), §@¬°±zªº¥»°ê¤Î¥~°ê³f¹ô',
+  'Equity'                      => 'ªÑÅv',
+  'Exch'                        => '¶×²v',
+  'Exchangerate'                => '¶×²v',
+  'Exchangerate Difference'     => '',
+  'Exchangerate for payment missing!' => '',
+  'Exchangerate missing!'       => '',
+  'Existing Datasets'           => '¬J¦³ªº¸ê®Æ¶°',
+  'Expense'                     => '¶O¥Î',
+  'Expense Account'             => '¶O¥Î¬ì¥Ø',
+  'Expense/Asset'               => '¶O¥Î/¸ê²£',
+  'Extended'                    => '',
+  'Fax'                         => '¶Ç¯u',
+  'Feb'                         => '¤G¤ë',
+  'February'                    => '¤G¤ë',
+  'Foreign Exchange Gain'       => '¥~¶×¦¬¯q',
+  'Foreign Exchange Loss'       => '¥~¶×·l¥¢',
+  'From'                        => '±q',
+  'GIFI'                        => '',
+  'GIFI deleted!'               => '',
+  'GIFI missing!'               => '¥¼«ü©ú GIFI!',
+  'GIFI saved!'                 => '',
+  'GL Transaction'              => '',
+  'General Ledger'              => 'Á`±b',
+  'Goods & Services'            => '³fª«¤ÎªA°È',
+  'HTML Templates'              => 'HTML ªí³æ',
+  'Heading'                     => 'ªíÀY',
+  'Host'                        => '¥D¾÷',
+  'Hostname missing!'           => '¥¼«ü©ú¥D¾÷¦WºÙ!',
+  'ID'                          => '½s¸¹',
+  'Image'                       => '',
+  'In-line'                     => '¦æ¤º',
+  'Include in Report'           => '¤@¨ÖÅã¥Ü',
+  'Include in drop-down menus'  => '¥]§t¦b¤U©Ô¦¡¿ï³æ¤¤',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => '­n±N³o­Ó«È¤á/¼t°Ó¥[¤JÀ³¥[µ|²M³æ?',
+  'Income'                      => '¦¬¯q',
+  'Income Account'              => '·l¯q¬ì¥Ø',
+  'Income Statement'            => '·l¯qªí',
+  'Incorrect Dataset version!'  => '¸ê®Æ¶°ª©¥»¿ù»~!',
+  'Incorrect Password!'         => '±K½X¿ù»~!',
+  'Individual Items'            => '²Õ¦¨¶µ¥Ø',
+  'Inventory'                   => '®w¦s',
+  'Inventory Account'           => '¦s³f¬ì¥Ø',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => '¦b°±¥Î¦¹¶µ²Õ¦X«~¤§«e, ¦s³f¼Æ¶q¥²»Ý¬°¹s!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => '°±¥Î¦¹¶µ¹s¥ó¤§«e, ¦s³f¼Æ¶q¥²»Ý¬°¹s!',
+  'Inventory quantity must be zero!' => '¦s³f¼Æ¶q¥²»Ý¬°¹s!',
+  'Invoice'                     => 'µo²¼',
+  'Invoice Date'                => 'µo²¼¤é´Á',
+  'Invoice Date missing!'       => 'µo²¼¤é´Á¿ù»~!',
+  'Invoice Number'              => 'µo²¼½s¸¹',
+  'Invoice Number missing!'     => 'µo²¼½s¸¹¿ù»~!',
+  'Invoice deleted!'            => '',
+  'Invoice posted!'             => '',
+  'Invoices'                    => '',
+  'Is this a summary account to record' => '¦¹¬°Á`µ²¬ì¥Ø¶Ü?',
+  'Item deleted!'               => '',
+  'Item not on file!'           => '¬dµL¦¹¶µ¥Ø',
+  'Jan'                         => '¤@¤ë',
+  'January'                     => '¤@¤ë',
+  'Jul'                         => '¤C¤ë',
+  'July'                        => '¤C¤ë',
+  'Jun'                         => '¤»¤ë',
+  'June'                        => '¤»¤ë',
+  'LaTeX Templates'             => 'LaTex ¼Òª©',
+  'Language'                    => '»y¨t',
+  'Last Cost'                   => '¤W¤@µ§¦¨¥»',
+  'Last Invoice Number'         => '¤W¤@µ§µo²¼½s¸¹',
+  'Last Numbers & Default Accounts' => '¤W¤@µ§½s¸¹¤Î¹w³]¬ì¥Ø',
+  'Last Purchase Order Number'  => '«e¦¸±ÄÁʳ渹',
+  'Last Sales Order Number'     => '«e¦¸¾P',
+  'Leave host and port field empty unless you want to make a remote connection.' => '°£«D±z·Q­n¶i¦æ»·ºÝ³s½u, §_«h½Ð±N¥D¾÷¤Î°ð¸¹¯d¥Õ.',
+  'Liability'                   => '­t¶Å',
+  'Licensed to'                 => '±ÂÅv¤©',
+  'Line Total'                  => 'Á`¦C¼Æ',
+  'Link'                        => '³sµ²',
+  'Link Accounts'               => '³sµ²¬ì¥Ø',
+  'List Accounts'               => '¦C¥X±b¸¹',
+  'List GIFI'                   => '¦C¥X GIFI',
+  'List Price'                  => '¶i»ù',
+  'List Transactions'           => '¦C¥X±b¥Ø',
+  'Login'                       => 'µn¤J',
+  'Logout'                      => 'µn¥X',
+  'Make'                        => '»s³y',
+  'Mar'                         => '¤T¤ë',
+  'March'                       => '¤T¤ë',
+  'May'                         => '¤­¤ë',
+  'May '                        => '¤­¤ë',
+  'Message'                     => '°T®§',
+  'Microfiche'                  => '',
+  'Model'                       => '«¬¸¹',
+  'N/A'                         => '¤£¾A¥Î',
+  'Name'                        => '¦WºÙ',
+  'Name missing!'               => '',
+  'New Templates'               => '·s¼W¼Òª©',
+  'No'                          => '§_',
+  'No Database Drivers available!' => '¨S¦³¥i¥ÎªºÅX°Êµ{¦¡!',
+  'No Dataset selected!'        => '¥¼¿ï©w¸ê®Æ¶°!',
+  'No email address for'        => '¥¼«ü©ú¹q¤l¶l¥ó¦ì¸m',
+  'No.'                         => '',
+  'Notes'                       => '³Æµù',
+  'Nothing applied!'            => '',
+  'Nothing selected!'           => '',
+  'Nothing to delete!'          => '¨S¦³¥i§R°£ªº¶µ¥Ø',
+  'Nov'                         => '¤Q¤@¤ë',
+  'November'                    => '¤Q¤@¤ë',
+  'Number'                      => '½s¸¹',
+  'Number Format'               => '¼Æ¦r®æ¦¡',
+  'Number missing in Row'       => '¦¹¦C¤¤¯Ê¤Ö¼Æ­È',
+  'O'                           => '',
+  'Obsolete'                    => '°±¥Î',
+  'Oct'                         => '¤Q¤ë',
+  'October'                     => '¤Q¤ë',
+  'On Hand'                     => '¦s¶q',
+  'On Order'                    => '',
+  'Open'                        => '¶}±Ò',
+  'Oracle Database Administration' => 'Oracle ¸ê®Æ®wºÞ²z',
+  'Order'                       => '­q³æ',
+  'Order Date'                  => '¤U³æ¤é´Á',
+  'Order Date missing!'         => '¥¼«ü©ú¤U³æ¤é´Á!',
+  'Order Entry'                 => '¤U³æ¶µ¥Ø',
+  'Order Number'                => '­q³æ½s¸¹',
+  'Order Number missing!'       => '¥¼«ü©ú­q³æ½s¸¹!',
+  'Order deleted!'              => '',
+  'Order saved!'                => '',
+  'Ordered'                     => '',
+  'Orphaned'                    => 'µL¥D',
+  'Out of balance!'             => '',
+  'PDF'                         => '',
+  'Packing List'                => '¥X³f³æ',
+  'Packing List Date missing!'  => '¥¼«ü©ú¥]¸Ë²M³æ¤é´Á!',
+  'Packing List Number missing!' => '¥¼«ü©ú¥]¸Ë²M³æ½s¸¹!',
+  'Paid'                        => '¤w¥I',
+  'Paid in full'                => '',
+  'Part'                        => '­ì®Æ',
+  'Part Number missing!'        => 'º|¶ñ­ì®Æ½s¸¹!',
+  'Parts'                       => '­ì®Æ',
+  'Parts Inventory'             => '®w¦s­ì®Æ',
+  'Password'                    => '±K½X',
+  'Password changed!'           => '',
+  'Payables'                    => 'À³¥I¬ì¥Ø',
+  'Payment'                     => '¥I´Ú¤è¦¡',
+  'Payment date missing!'       => '¥¼«ü©ú¥I´Ú¤é´Á!',
+  'Payment posted!'             => '',
+  'Payments'                    => '¥I´Ú',
+  'Pg Database Administration'  => 'Pg ¸ê®Æ®wºÞ²z',
+  'Phone'                       => '¹q¸Ü¸¹½X',
+  'Port'                        => '°ð¸¹',
+  'Port missing!'               => '¥¼«ü©ú°ð¸¹!',
+  'Post'                        => '',
+  'Post as new'                 => '',
+  'Postscript'                  => '',
+  'Preferences'                 => '­Ó¤H³]©w',
+  'Preferences saved!'          => '­Ó¤H³]©w¤wÀx¦s!',
+  'Price'                       => '»ù®æ',
+  'Print'                       => '',
+  'Printer'                     => '¦Lªí¾÷',
+  'Project'                     => '',
+  'Project Number missing!'     => '',
+  'Project deleted!'            => '',
+  'Project not on file!'        => '',
+  'Project saved!'              => '',
+  'Projects'                    => '',
+  'Purchase Invoice'            => '',
+  'Purchase Order'              => '±ÄÁʳæ',
+  'Purchase Orders'             => '±ÄÁʳæ',
+  'Qty'                         => '¼Æ¶q',
+  'ROP'                         => '¦A­qÂI',
+  'Rate'                        => 'µ|²v',
+  'Recd'                        => '',
+  'Receipt'                     => '',
+  'Receipts'                    => '',
+  'Receivables'                 => 'À³¦¬¬ì¥Ø',
+  'Reconciliation'              => '',
+  'Record in'                   => '°O¿ý©ó',
+  'Reference'                   => '',
+  'Reference missing!'          => '',
+  'Remaining'                   => '©|¾l',
+  'Report for'                  => '³øªí¨Ó·½',
+  'Reports'                     => '³øªí',
+  'Required by'                 => '¤l¶µ¥Ø',
+  'Retained Earnings'           => '«O¯d¬Õ¾l',
+  'Sales'                       => '·~°È',
+  'Sales Invoice'               => '',
+  'Sales Order'                 => '¾P³f³æ',
+  'Sales Orders'                => '¾P³f³æ',
+  'Save'                        => 'Àx¦s',
+  'Save as new'                 => '',
+  'Save to File'                => 'Àx¦s¦ÜÀÉ®×',
+  'Screen'                      => '¿Ã¹õ',
+  'Select a Dataset to delete and press "Continue"' => '½Ð¿ï¾Ü±ý§R°£ªº¸ê®Æ¶°, ¦A«ö "Ä~Äò"',
+  'Select all'                  => '',
+  'Select from one of the items below' => '©ó¤U¦C¶µ¥Ø¤¤¿ï¾Ü¤@¶µ',
+  'Select from one of the names below' => '',
+  'Select from one of the projects below' => '',
+  'Select postscript or PDF!'   => '',
+  'Sell Price'                  => '°â»ù',
+  'Send by E-Mail'              => '¥H¹q¤l¶l¥ó±H°e',
+  'Sep'                         => '¤E¤ë',
+  'September'                   => '¤E¤ë',
+  'Service'                     => 'ªA°È',
+  'Service Items'               => 'ªA°È¶µ¥Ø',
+  'Service Number missing!'     => 'º|¶ñªA°È½s¸¹!',
+  'Services'                    => 'ªA°È',
+  'Setup Templates'             => '³]©w¼Òª©',
+  'Ship'                        => '',
+  'Ship to'                     => '',
+  'Ship via'                    => '',
+  'Short'                       => 'µu',
+  'Signature'                   => 'ñ¦W',
+  'Sold'                        => '¤w½æ¥X',
+  'Source'                      => '¨Ó·½',
+  'Standard'                    => '¼Ð·Ç',
+  'Statement'                   => '',
+  'Statement Balance'           => '',
+  'Statement sent to'           => '',
+  'Statements sent to printer!' => '',
+  'Stock Assembly'              => '½LÂI',
+  'Stylesheet'                  => '¼Ë¦¡ªí',
+  'Subject'                     => '¼ÐÃD',
+  'Subtotal'                    => '¤p­p',
+  'System'                      => '¨t²Î',
+  'Tax'                         => 'µ|ª÷',
+  'Tax Accounts'                => 'µ|ª÷¬ì¥Ø',
+  'Tax Included'                => '¤£¦¬ªA°È¶O',
+  'Tax collected'               => '',
+  'Tax paid'                    => '',
+  'Taxable'                     => 'À³µ|',
+  'Template saved!'             => '',
+  'Templates'                   => '¼Òª©',
+  'Terms: Net'                  => '²¼´Á²b­p',
+  'The following Datasets are not in use and can be deleted' => '¤U¦C¸ê®Æ¶°¨Ã¥¼¨Ï¥Î, ¥i¥H§R°£',
+  'The following Datasets need to be updated' => '¤U¦C¸ê®Æ¶°»Ý­n§ó·s',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => '³o¬O¹ï¬J¦s¸ê®Æ¨Ó·½ªºªì¨BÀˬd. ¦b¦¹¶¥¬q, ¤£·|§R°£©Î·s¼W¥ô¦ó¸ê®Æ!',
+  'To'                          => '¦Ü',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => '­Y­n·s¼W¸s²Õ¤ºªº¨Ï¥ÎªÌ, ½Ð½s¿è¦WºÙ, §ó§ïµn¤J¦W, µM«áÀx¦s.  ³o¼Ë¤@¨Ó, ·s¨Ï¥ÎªÌ·|«O¯d¬Û¦PªºÅܼÆ, ¨Ã¥H·sªºµn¤J¦W¦s¤J.',
+  'Top Level'                   => '',
+  'Total'                       => 'Á`­p',
+  'Transaction Date missing!'   => 'º|¶ñ±b¥Ø¤é´Á!',
+  'Transaction deleted!'        => '',
+  'Transaction posted!'         => '',
+  'Transaction reversal enforced for all dates' => '±j¨î¦^´_©Ò¦³¤é´Áªº¥æ©ö',
+  'Transaction reversal enforced up to' => '±j¨î¦^´_¥æ©öª½¨ì',
+  'Transactions'                => '±b¥Ø',
+  'Transactions exist, cannot delete customer!' => '¦¹«È¤á¤w¦³±b¥Ø, ¤£¯à§R°£!',
+  'Transactions exist, cannot delete vendor!' => '¦¹¼t°Ó¤w¦³±b¥Ø, ¤£¯à§R°£!',
+  'Transactions exist; cannot delete account!' => '©|¦³¥æ©ö¦s¦b; µLªk§R°£±b¤á!',
+  'Trial Balance'               => '¸Õºâªí',
+  'Unit'                        => '³æ¦ì',
+  'Unit of measure'             => '«×¶q³æ¦ì',
+  'Update'                      => '',
+  'Update Dataset'              => '§ó·s¸ê®Æ¶°',
+  'Updated'                     => '',
+  'Use Templates'               => '¨Ï¥Î¼Òª©',
+  'User'                        => '¨Ï¥ÎªÌ',
+  'User deleted!'               => '',
+  'User saved!'                 => '',
+  'Vendor'                      => '¼t°Ó',
+  'Vendor deleted!'             => '',
+  'Vendor missing!'             => '',
+  'Vendor not on file!'         => '',
+  'Vendor saved!'               => '',
+  'Vendors'                     => '',
+  'Version'                     => 'ª©¥»',
+  'Weight'                      => '­«¶q',
+  'Weight Unit'                 => '­«¶q³æ¦ì',
+  'What type of item is this?'  => '¦¹¶µ¥Øªº«¬ºA?',
+  'Year End'                    => '·|­p¦~«×',
+  'Yes'                         => '¬O',
+  'You are logged out!'         => '',
+  'You did not enter a name!'   => '±z¨Ã¥¼Áä¤J¦WºÙ!',
+  'You must enter a host and port for local and remote connections!' => '±z¥²»ÝÁä¤J¥D¾÷¤Î°ð¸¹, ¥H¶i¦æ¥»¾÷©Î»·ºÝ³s½u!',
+  'as at'                       => '',
+  'collected on sales'          => '¦b¾P³f®Éµ²²M',
+  'days'                        => '¤é',
+  'does not exist'              => '¤£¦s¦b',
+  'ea'                          => '­Ó',
+  'emailed to'                  => '¤w±H¦Ü',
+  'for Period'                  => '´Á¶¡',
+  'hr'                          => 'hr',
+  'is already a member!'        => '¤w¸g¬O¦¨­û¤F!',
+  'is not a member!'            => '¨Ã¤£¬O¦¨­û!',
+  'localhost'                   => 'localhost',
+  'paid on purchases'           => '¦b±ÄÁʮɵ²²M',
+  'sent to printer'             => '°e¦Ü¦Lªí¾÷',
+  'successfully created!'       => '¦¨¥\«Ø¥ß!',
+  'successfully deleted!'       => '¦¨¥\§R°£!',
+  'to'                          => '',
+  'website'                     => 'ºô¯¸',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/am b/sql-ledger/locale/tw/am
new file mode 100644 (file)
index 0000000..77df0d3
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'À³¥I±b´Ú',
+  'AR'                          => 'À³¦¬±b´Ú',
+  'Account'                     => '¬ì¥Ø',
+  'Account Number'              => '¬ì¥Ø½s¸¹',
+  'Account Number missing!'     => 'º|¶ñ¬ì¥Ø½s¸¹!',
+  'Account Type'                => '¬ì¥ØÃþ§O',
+  'Account Type missing!'       => 'º|¶ñ¬ì¥ØÃþ§O!',
+  'Account deleted!'            => 'Account deleted!',
+  'Account saved!'              => 'Account saved!',
+  'Add Account'                 => '·s¼W¬ì¥Ø',
+  'Add GIFI'                    => '·s¼W GIFI',
+  'Address'                     => '¦a§}',
+  'Asset'                       => '¸ê²£',
+  'Audit Control'               => '½]®Ö±±¨î',
+  'Backup sent to'              => '³Æ¥÷±H°e¨ì',
+  'Books are open'              => '±bï¤w¶}±Ò',
+  'Business Number'             => '²Î¤@½s¸¹',
+  'COGS'                        => '³f¾P¦¨¥»',
+  'Cannot delete account!'      => 'Cannot delete account!',
+  'Cannot delete default account!' => 'Cannot delete default account!',
+  'Cannot save account!'        => 'Cannot save account!',
+  'Cannot save preferences!'    => 'Cannot save preferences!',
+  'Character Set'               => '¦r¤¸¶°',
+  'Chart of Accounts'           => '·|­p¬ì¥Øªí',
+  'Close Books up to'           => 'Ãö³¬¨ì¦¹¬°¤îªº±bï',
+  'Company'                     => '¤½¥q¦WºÙ',
+  'Continue'                    => 'Ä~Äò',
+  'Copy to COA'                 => '½Æ»s¨ì COA',
+  'Credit'                      => '¶U¤è',
+  'Date Format'                 => '¤é´Á®æ¦¡',
+  'Debit'                       => '­É¤è',
+  'Delete'                      => '§R°£',
+  'Delete Account'              => '§R°£¬ì¥Ø',
+  'Description'                 => '»¡©ú',
+  'Dropdown Limit'              => 'Dropdown Limit',
+  'E-mail'                      => '¹q¤l¶l¥ó',
+  'Edit'                        => 'Edit',
+  'Edit Account'                => '½s¿è¬ì¥Ø',
+  'Edit GIFI'                   => '½s¿è GIFI',
+  'Edit Preferences for'        => '³]©w¨Ï¥ÎªÌ',
+  'Edit Template'               => '½s¿è¼Òª©',
+  'Enforce transaction reversal for all dates' => '±j¨î©Ò¦³¤é´Áªº¥æ©ö¦^´_',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => '½ÐÁä¤J¥H«_¸¹¤À¹jªº­^¤å¦r¥À, ¨C¶µ¤£¶W¹L¤T­Ó¦r (¦p CAD:USD:EUR), §@¬°±zªº¥»°ê¤Î¥~°ê³f¹ô',
+  'Equity'                      => 'ªÑÅv',
+  'Expense'                     => '¶O¥Î',
+  'Expense Account'             => '¶O¥Î¬ì¥Ø',
+  'Expense/Asset'               => '¶O¥Î/¸ê²£',
+  'Fax'                         => '¶Ç¯u',
+  'Foreign Exchange Gain'       => '¥~¶×¦¬¯q',
+  'Foreign Exchange Loss'       => '¥~¶×·l¥¢',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI deleted!',
+  'GIFI missing!'               => '¥¼«ü©ú GIFI!',
+  'GIFI saved!'                 => 'GIFI saved!',
+  'Heading'                     => 'ªíÀY',
+  'Include in drop-down menus'  => '¥]§t¦b¤U©Ô¦¡¿ï³æ¤¤',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => '­n±N³o­Ó«È¤á/¼t°Ó¥[¤JÀ³¥[µ|²M³æ?',
+  'Income'                      => '¦¬¯q',
+  'Income Account'              => '·l¯q¬ì¥Ø',
+  'Inventory'                   => '®w¦s',
+  'Inventory Account'           => '¦s³f¬ì¥Ø',
+  'Is this a summary account to record' => '¦¹¬°Á`µ²¬ì¥Ø¶Ü?',
+  'Language'                    => '»y¨t',
+  'Last Invoice Number'         => '¤W¤@µ§µo²¼½s¸¹',
+  'Last Numbers & Default Accounts' => '¤W¤@µ§½s¸¹¤Î¹w³]¬ì¥Ø',
+  'Last Purchase Order Number'  => '«e¦¸±ÄÁʳ渹',
+  'Last Sales Order Number'     => '«e¦¸¾P',
+  'Liability'                   => '­t¶Å',
+  'Link'                        => '³sµ²',
+  'Name'                        => '¦WºÙ',
+  'No'                          => '§_',
+  'No email address for'        => '¥¼«ü©ú¹q¤l¶l¥ó¦ì¸m',
+  'Number'                      => '½s¸¹',
+  'Number Format'               => '¼Æ¦r®æ¦¡',
+  'Parts Inventory'             => '®w¦s­ì®Æ',
+  'Password'                    => '±K½X',
+  'Payables'                    => 'À³¥I¬ì¥Ø',
+  'Payment'                     => '¥I´Ú¤è¦¡',
+  'Phone'                       => '¹q¸Ü¸¹½X',
+  'Preferences saved!'          => '­Ó¤H³]©w¤wÀx¦s!',
+  'Rate'                        => 'µ|²v',
+  'Receivables'                 => 'À³¦¬¬ì¥Ø',
+  'Sales'                       => '·~°È',
+  'Save'                        => 'Àx¦s',
+  'Service Items'               => 'ªA°È¶µ¥Ø',
+  'Ship via'                    => 'Ship via',
+  'Signature'                   => 'ñ¦W',
+  'Stylesheet'                  => '¼Ë¦¡ªí',
+  'Tax'                         => 'µ|ª÷',
+  'Tax Accounts'                => 'µ|ª÷¬ì¥Ø',
+  'Template saved!'             => 'Template saved!',
+  'Transaction reversal enforced for all dates' => '±j¨î¦^´_©Ò¦³¤é´Áªº¥æ©ö',
+  'Transaction reversal enforced up to' => '±j¨î¦^´_¥æ©öª½¨ì',
+  'Transactions exist; cannot delete account!' => '©|¦³¥æ©ö¦s¦b; µLªk§R°£±b¤á!',
+  'Weight Unit'                 => '­«¶q³æ¦ì',
+  'Year End'                    => '·|­p¦~«×',
+  'Yes'                         => '¬O',
+  'does not exist'              => '¤£¦s¦b',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  '·s¼w¬ì¥Ø'                    => 'add_account',
+  'Ä~Äò'                        => 'continue',
+  '½Æ»s¨ì_coa'                  => 'copy_to_coa',
+  '§r°£'                        => 'delete',
+  'edit'                        => 'edit',
+  '½s¿è¬ì¥Ø'                    => 'edit_account',
+  'Àx¦s'                        => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/ap b/sql-ledger/locale/tw/ap
new file mode 100644 (file)
index 0000000..c251797
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AP Transactions'             => 'À³¥I±b¥Ø',
+  'Account'                     => '¬ì¥Ø',
+  'Add Accounts Payables Transaction' => 'Add Accounts Payables Transaction',
+  'Address'                     => '¦a§}',
+  'Amount'                      => 'Á`­p',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => '¥|¤ë',
+  'April'                       => '¥|¤ë',
+  'Are you sure you want to delete Transaction' => '±z½T©w­n§R°£±b¥Ø',
+  'Aug'                         => '¤K¤ë',
+  'August'                      => '¤K¤ë',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cannot post transaction for a closed period!' => 'µLªk¦b¤wÃö³¬ªº®É¬q¤º¥[¤J¥æ©ö!',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => '¤wÃö³¬',
+  'Confirm!'                    => '¤J±b¦¨¥\!',
+  'Continue'                    => 'Ä~Äò',
+  'Currency'                    => '¹ô§O',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => '¤é´Á',
+  'Date Paid'                   => '¥I´Ú¤é´Á',
+  'Dec'                         => '¤Q¤G¤ë',
+  'December'                    => '¤Q¤G¤ë',
+  'Delete'                      => '§R°£',
+  'Description'                 => '»¡©ú',
+  'Due Date'                    => '¨ì´Á¤é',
+  'Due Date missing!'           => 'º|¶ñ¨ì´Á¤é!',
+  'Edit Accounts Payables Transaction' => 'Edit Accounts Payables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => '¶×²v',
+  'Exchangerate'                => '¶×²v',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Feb'                         => '¤G¤ë',
+  'February'                    => '¤G¤ë',
+  'From'                        => '±q',
+  'ID'                          => '½s¸¹',
+  'Include in Report'           => '¤@¨ÖÅã¥Ü',
+  'Invoice'                     => 'µo²¼',
+  'Invoice Date'                => 'µo²¼¤é´Á',
+  'Invoice Date missing!'       => 'µo²¼¤é´Á¿ù»~!',
+  'Invoice Number'              => 'µo²¼½s¸¹',
+  'Invoice Number missing!'     => 'µo²¼½s¸¹¿ù»~!',
+  'Jan'                         => '¤@¤ë',
+  'January'                     => '¤@¤ë',
+  'Jul'                         => '¤C¤ë',
+  'July'                        => '¤C¤ë',
+  'Jun'                         => '¤»¤ë',
+  'June'                        => '¤»¤ë',
+  'Mar'                         => '¤T¤ë',
+  'March'                       => '¤T¤ë',
+  'May'                         => '¤­¤ë',
+  'May '                        => '¤­¤ë',
+  'Notes'                       => '³Æµù',
+  'Nov'                         => '¤Q¤@¤ë',
+  'November'                    => '¤Q¤@¤ë',
+  'Number'                      => '½s¸¹',
+  'Oct'                         => '¤Q¤ë',
+  'October'                     => '¤Q¤ë',
+  'Open'                        => '¶}±Ò',
+  'Order'                       => '­q³æ',
+  'Order Number'                => '­q³æ½s¸¹',
+  'Paid'                        => '¤w¥I',
+  'Payment date missing!'       => '¥¼«ü©ú¥I´Ú¤é´Á!',
+  'Payments'                    => '¥I´Ú',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => '¤E¤ë',
+  'September'                   => '¤E¤ë',
+  'Source'                      => '¨Ó·½',
+  'Subtotal'                    => '¤p­p',
+  'Tax'                         => 'µ|ª÷',
+  'Tax Included'                => '¤£¦¬ªA°È¶O',
+  'To'                          => '¦Ü',
+  'Total'                       => 'Á`­p',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor'                      => '¼t°Ó',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => '¬O',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'add_accounts_payables_transaction' => 'add_accounts_payables_transaction',
+  'Ä~Äò'                        => 'continue',
+  '§r°£'                        => 'delete',
+  'edit_accounts_payables_transaction' => 'edit_accounts_payables_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'update'                      => 'update',
+  '¬o'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/ar b/sql-ledger/locale/tw/ar
new file mode 100644 (file)
index 0000000..a864b41
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'AR Transaction',
+  'AR Transactions'             => 'À³¦¬±b¥Ø',
+  'Account'                     => '¬ì¥Ø',
+  'Add Accounts Receivables Transaction' => 'Add Accounts Receivables Transaction',
+  'Address'                     => '¦a§}',
+  'Amount'                      => 'Á`­p',
+  'Amount Due'                  => 'Amount Due',
+  'Apr'                         => '¥|¤ë',
+  'April'                       => '¥|¤ë',
+  'Are you sure you want to delete Transaction' => '±z½T©w­n§R°£±b¥Ø',
+  'Aug'                         => '¤K¤ë',
+  'August'                      => '¤K¤ë',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cannot post transaction for a closed period!' => 'µLªk¦b¤wÃö³¬ªº®É¬q¤º¥[¤J¥æ©ö!',
+  'Cannot post transaction!'    => 'Cannot post transaction!',
+  'Closed'                      => '¤wÃö³¬',
+  'Confirm!'                    => '¤J±b¦¨¥\!',
+  'Continue'                    => 'Ä~Äò',
+  'Credit Limit'                => '«H¥ÎÃB«×',
+  'Currency'                    => '¹ô§O',
+  'Customer'                    => '«È¤á',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => '¤é´Á',
+  'Date Paid'                   => '¥I´Ú¤é´Á',
+  'Dec'                         => '¤Q¤G¤ë',
+  'December'                    => '¤Q¤G¤ë',
+  'Delete'                      => '§R°£',
+  'Description'                 => '»¡©ú',
+  'Due Date'                    => '¨ì´Á¤é',
+  'Due Date missing!'           => 'º|¶ñ¨ì´Á¤é!',
+  'Edit Accounts Receivables Transaction' => 'Edit Accounts Receivables Transaction',
+  'Employee'                    => 'Employee',
+  'Exch'                        => '¶×²v',
+  'Exchangerate'                => '¶×²v',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Feb'                         => '¤G¤ë',
+  'February'                    => '¤G¤ë',
+  'From'                        => '±q',
+  'ID'                          => '½s¸¹',
+  'Include in Report'           => '¤@¨ÖÅã¥Ü',
+  'Invoice'                     => 'µo²¼',
+  'Invoice Date'                => 'µo²¼¤é´Á',
+  'Invoice Date missing!'       => 'µo²¼¤é´Á¿ù»~!',
+  'Invoice Number'              => 'µo²¼½s¸¹',
+  'Invoice Number missing!'     => 'µo²¼½s¸¹¿ù»~!',
+  'Jan'                         => '¤@¤ë',
+  'January'                     => '¤@¤ë',
+  'Jul'                         => '¤C¤ë',
+  'July'                        => '¤C¤ë',
+  'Jun'                         => '¤»¤ë',
+  'June'                        => '¤»¤ë',
+  'Mar'                         => '¤T¤ë',
+  'March'                       => '¤T¤ë',
+  'May'                         => '¤­¤ë',
+  'May '                        => '¤­¤ë',
+  'Notes'                       => '³Æµù',
+  'Nov'                         => '¤Q¤@¤ë',
+  'November'                    => '¤Q¤@¤ë',
+  'Number'                      => '½s¸¹',
+  'Oct'                         => '¤Q¤ë',
+  'October'                     => '¤Q¤ë',
+  'Open'                        => '¶}±Ò',
+  'Order'                       => '­q³æ',
+  'Order Number'                => '­q³æ½s¸¹',
+  'Paid'                        => '¤w¥I',
+  'Payment date missing!'       => '¥¼«ü©ú¥I´Ú¤é´Á!',
+  'Payments'                    => '¥I´Ú',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Remaining'                   => '©|¾l',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => '¤E¤ë',
+  'September'                   => '¤E¤ë',
+  'Source'                      => '¨Ó·½',
+  'Subtotal'                    => '¤p­p',
+  'Tax'                         => 'µ|ª÷',
+  'Tax Included'                => '¤£¦¬ªA°È¶O',
+  'To'                          => '¦Ü',
+  'Total'                       => 'Á`­p',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => '¬O',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ar_transaction'              => 'ar_transaction',
+  'Ä~Äò'                        => 'continue',
+  '§r°£'                        => 'delete',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  '¬o'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/arap b/sql-ledger/locale/tw/arap
new file mode 100644 (file)
index 0000000..e82552c
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => '¦a§}',
+  'Continue'                    => 'Ä~Äò',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Description'                 => '»¡©ú',
+  'Number'                      => '½s¸¹',
+  'Project not on file!'        => 'Project not on file!',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'Ä~Äò'                        => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/ca b/sql-ledger/locale/tw/ca
new file mode 100644 (file)
index 0000000..677a41f
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => '¬ì¥Ø',
+  'Apr'                         => '¥|¤ë',
+  'April'                       => '¥|¤ë',
+  'Aug'                         => '¤K¤ë',
+  'August'                      => '¤K¤ë',
+  'Balance'                     => 'Balance',
+  'Chart of Accounts'           => '·|­p¬ì¥Øªí',
+  'Credit'                      => '¶U¤è',
+  'Date'                        => '¤é´Á',
+  'Debit'                       => '­É¤è',
+  'Dec'                         => '¤Q¤G¤ë',
+  'December'                    => '¤Q¤G¤ë',
+  'Description'                 => '»¡©ú',
+  'Feb'                         => '¤G¤ë',
+  'February'                    => '¤G¤ë',
+  'From'                        => '±q',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => '¤@¨ÖÅã¥Ü',
+  'Jan'                         => '¤@¤ë',
+  'January'                     => '¤@¤ë',
+  'Jul'                         => '¤C¤ë',
+  'July'                        => '¤C¤ë',
+  'Jun'                         => '¤»¤ë',
+  'June'                        => '¤»¤ë',
+  'List Transactions'           => '¦C¥X±b¥Ø',
+  'Mar'                         => '¤T¤ë',
+  'March'                       => '¤T¤ë',
+  'May'                         => '¤­¤ë',
+  'May '                        => '¤­¤ë',
+  'Nov'                         => '¤Q¤@¤ë',
+  'November'                    => '¤Q¤@¤ë',
+  'Oct'                         => '¤Q¤ë',
+  'October'                     => '¤Q¤ë',
+  'Reference'                   => 'Reference',
+  'Sep'                         => '¤E¤ë',
+  'September'                   => '¤E¤ë',
+  'Subtotal'                    => '¤p­p',
+  'To'                          => '¦Ü',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  '¦c¥x±b¥Ø'                    => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/cp b/sql-ledger/locale/tw/cp
new file mode 100644 (file)
index 0000000..af8421a
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => '¬ì¥Ø',
+  'Address'                     => '¦a§}',
+  'Amount'                      => 'Á`­p',
+  'Amount does not equal applied!' => 'Amount does not equal applied!',
+  'Amount missing!'             => 'Amount missing!',
+  'Applied'                     => 'Applied',
+  'Cannot post payment!'        => 'Cannot post payment!',
+  'Cannot process payment for a closed period!' => 'Cannot process payment for a closed period!',
+  'Check'                       => 'Check',
+  'Check printed!'              => 'Check printed!',
+  'Check printing failed!'      => 'Check printing failed!',
+  'Continue'                    => 'Ä~Äò',
+  'Currency'                    => '¹ô§O',
+  'Customer'                    => '«È¤á',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => '¤é´Á',
+  'Date missing!'               => 'Date missing!',
+  'Description'                 => '»¡©ú',
+  'Due'                         => '¨ì´Á',
+  'Exchangerate'                => '¶×²v',
+  'From'                        => '±q',
+  'Invoice'                     => 'µo²¼',
+  'Invoices'                    => 'Invoices',
+  'Nothing applied!'            => 'Nothing applied!',
+  'Number'                      => '½s¸¹',
+  'Paid in full'                => 'Paid in full',
+  'Payment'                     => '¥I´Ú¤è¦¡',
+  'Payment posted!'             => 'Payment posted!',
+  'Post'                        => 'Post',
+  'Print'                       => 'Print',
+  'Printer'                     => '¦Lªí¾÷',
+  'Project not on file!'        => 'Project not on file!',
+  'Receipt'                     => 'Receipt',
+  'Reference'                   => 'Reference',
+  'Screen'                      => '¿Ã¹õ',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'To'                          => '¦Ü',
+  'Update'                      => 'Update',
+  'Vendor'                      => '¼t°Ó',
+  'Vendor not on file!'         => 'Vendor not on file!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'Ä~Äò'                        => 'continue',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/ct b/sql-ledger/locale/tw/ct
new file mode 100644 (file)
index 0000000..1597c9f
--- /dev/null
@@ -0,0 +1,69 @@
+$self{texts} = {
+  'Add'                         => '·s¼W',
+  'Address'                     => '¦a§}',
+  'All'                         => '¥þ³¡',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'Cannot delete customer!',
+  'Cannot delete vendor!'       => 'Cannot delete vendor!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => '³sµ¸¤H',
+  'Continue'                    => 'Ä~Äò',
+  'Credit Limit'                => '«H¥ÎÃB«×',
+  'Customer deleted!'           => 'Customer deleted!',
+  'Customer saved!'             => 'Customer saved!',
+  'Customers'                   => 'Customers',
+  'Delete'                      => '§R°£',
+  'Discount'                    => '§é¦©',
+  'E-mail'                      => '¹q¤l¶l¥ó',
+  'Fax'                         => '¶Ç¯u',
+  'Include in Report'           => '¤@¨ÖÅã¥Ü',
+  'Invoice'                     => 'µo²¼',
+  'Name'                        => '¦WºÙ',
+  'Name missing!'               => 'Name missing!',
+  'Notes'                       => '³Æµù',
+  'Number'                      => '½s¸¹',
+  'Order'                       => '­q³æ',
+  'Orphaned'                    => 'µL¥D',
+  'Phone'                       => '¹q¸Ü¸¹½X',
+  'Save'                        => 'Àx¦s',
+  'Ship to'                     => 'Ship to',
+  'Tax Included'                => '¤£¦¬ªA°È¶O',
+  'Taxable'                     => 'À³µ|',
+  'Terms: Net'                  => '²¼´Á²b­p',
+  'Transactions exist, cannot delete customer!' => '¦¹«È¤á¤w¦³±b¥Ø, ¤£¯à§R°£!',
+  'Transactions exist, cannot delete vendor!' => '¦¹¼t°Ó¤w¦³±b¥Ø, ¤£¯à§R°£!',
+  'Vendor deleted!'             => 'Vendor deleted!',
+  'Vendor saved!'               => 'Vendor saved!',
+  'Vendors'                     => 'Vendors',
+  'days'                        => '¤é',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  '·s¼w'                        => 'add',
+  'Ä~Äò'                        => 'continue',
+  '§r°£'                        => 'delete',
+  'µo²¼'                        => 'invoice',
+  '­q³æ'                        => 'order',
+  'Àx¦s'                        => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/gl b/sql-ledger/locale/tw/gl
new file mode 100644 (file)
index 0000000..ce671a9
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'AP Transaction',
+  'AR Transaction'              => 'AR Transaction',
+  'Account'                     => '¬ì¥Ø',
+  'Add General Ledger Transaction' => '·s¼WÁ`±b',
+  'Address'                     => '¦a§}',
+  'All'                         => '¥þ³¡',
+  'Apr'                         => '¥|¤ë',
+  'April'                       => '¥|¤ë',
+  'Are you sure you want to delete Transaction' => '±z½T©w­n§R°£±b¥Ø',
+  'Asset'                       => '¸ê²£',
+  'Aug'                         => '¤K¤ë',
+  'August'                      => '¤K¤ë',
+  'Balance'                     => 'Balance',
+  'Cannot delete transaction!'  => 'Cannot delete transaction!',
+  'Cannot have a value in both Debit and Credit!' => 'Cannot have a value in both Debit and Credit!',
+  'Cannot post a transaction without a value!' => 'Cannot post a transaction without a value!',
+  'Cannot post transaction for a closed period!' => 'µLªk¦b¤wÃö³¬ªº®É¬q¤º¥[¤J¥æ©ö!',
+  'Confirm!'                    => '¤J±b¦¨¥\!',
+  'Continue'                    => 'Ä~Äò',
+  'Credit'                      => '¶U¤è',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => '¤é´Á',
+  'Debit'                       => '­É¤è',
+  'Debit and credit out of balance!' => '­É¶U¤£¥­¿Å!',
+  'Dec'                         => '¤Q¤G¤ë',
+  'December'                    => '¤Q¤G¤ë',
+  'Delete'                      => '§R°£',
+  'Description'                 => '»¡©ú',
+  'Edit General Ledger Transaction' => '½s¿èÁ`±b',
+  'Equity'                      => 'ªÑÅv',
+  'Expense'                     => '¶O¥Î',
+  'Feb'                         => '¤G¤ë',
+  'February'                    => '¤G¤ë',
+  'From'                        => '±q',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'GL Transaction',
+  'General Ledger'              => 'Á`±b',
+  'ID'                          => '½s¸¹',
+  'Include in Report'           => '¤@¨ÖÅã¥Ü',
+  'Income'                      => '¦¬¯q',
+  'Jan'                         => '¤@¤ë',
+  'January'                     => '¤@¤ë',
+  'Jul'                         => '¤C¤ë',
+  'July'                        => '¤C¤ë',
+  'Jun'                         => '¤»¤ë',
+  'June'                        => '¤»¤ë',
+  'Liability'                   => '­t¶Å',
+  'Mar'                         => '¤T¤ë',
+  'March'                       => '¤T¤ë',
+  'May'                         => '¤­¤ë',
+  'May '                        => '¤­¤ë',
+  'Notes'                       => '³Æµù',
+  'Nov'                         => '¤Q¤@¤ë',
+  'November'                    => '¤Q¤@¤ë',
+  'Number'                      => '½s¸¹',
+  'Oct'                         => '¤Q¤ë',
+  'October'                     => '¤Q¤ë',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Reference'                   => 'Reference',
+  'Reference missing!'          => 'Reference missing!',
+  'Reports'                     => '³øªí',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Sep'                         => '¤E¤ë',
+  'September'                   => '¤E¤ë',
+  'Source'                      => '¨Ó·½',
+  'Subtotal'                    => '¤p­p',
+  'To'                          => '¦Ü',
+  'Transaction Date missing!'   => 'º|¶ñ±b¥Ø¤é´Á!',
+  'Transaction deleted!'        => 'Transaction deleted!',
+  'Transaction posted!'         => 'Transaction posted!',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'Yes'                         => '¬O',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'Ä~Äò'                        => 'continue',
+  '§r°£'                        => 'delete',
+  'gl_transaction'              => 'gl_transaction',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'update'                      => 'update',
+  '¬o'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/ic b/sql-ledger/locale/tw/ic
new file mode 100644 (file)
index 0000000..7be481d
--- /dev/null
@@ -0,0 +1,205 @@
+$self{texts} = {
+  'Active'                      => 'Active',
+  'Add'                         => '·s¼W',
+  'Add Assembly'                => '·s¼W°Ó«~',
+  'Add Part'                    => '·s¼W­ì®Æ',
+  'Add Purchase Order'          => '·s¼W±ÄÁʳæ',
+  'Add Sales Order'             => '·s¼W¾P³f³æ',
+  'Add Service'                 => '·s¼WªA°È',
+  'Address'                     => '¦a§}',
+  'Apr'                         => '¥|¤ë',
+  'April'                       => '¥|¤ë',
+  'Assemblies'                  => '°Ó«~',
+  'Assemblies restocked!'       => 'Assemblies restocked!',
+  'Assembly Number missing!'    => '¬dµL¦¹°Ó«~!',
+  'Attachment'                  => 'ªþÀÉ',
+  'Aug'                         => '¤K¤ë',
+  'August'                      => '¤K¤ë',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => '½c',
+  'Bought'                      => '¤wÁʶR',
+  'COGS'                        => '³f¾P¦¨¥»',
+  'Cannot delete item already invoiced!' => 'Cannot delete item already invoiced!',
+  'Cannot delete item on order!' => 'µLªk§R°£³æ¤Wªº¶µ¥Ø!',
+  'Cannot delete item which is part of an assembly!' => 'Cannot delete item which is part of an assembly!',
+  'Cannot delete item!'         => 'Cannot delete item!',
+  'Cannot stock assemblies!'    => 'Cannot stock assemblies!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => '³sµ¸¤H',
+  'Continue'                    => 'Ä~Äò',
+  'Copies'                      => '«þ¨©',
+  'Dec'                         => '¤Q¤G¤ë',
+  'December'                    => '¤Q¤G¤ë',
+  'Delete'                      => '§R°£',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => '»¡©ú',
+  'Drawing'                     => 'Drawing',
+  'E-mail'                      => '¹q¤l¶l¥ó',
+  'E-mail address missing!'     => 'º|¶ñ¹q¤l¶l¥ó¦ì§}!',
+  'Edit Assembly'               => '½s¿è°Ó«~',
+  'Edit Part'                   => '½s¿è­ì®Æ',
+  'Edit Service'                => '½s¿èªA°È',
+  'Expense'                     => '¶O¥Î',
+  'Extended'                    => 'Extended',
+  'Fax'                         => '¶Ç¯u',
+  'Feb'                         => '¤G¤ë',
+  'February'                    => '¤G¤ë',
+  'From'                        => '±q',
+  'Image'                       => 'Image',
+  'In-line'                     => '¦æ¤º',
+  'Include in Report'           => '¤@¨ÖÅã¥Ü',
+  'Income'                      => '¦¬¯q',
+  'Individual Items'            => '²Õ¦¨¶µ¥Ø',
+  'Inventory'                   => '®w¦s',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => '¦b°±¥Î¦¹¶µ²Õ¦X«~¤§«e, ¦s³f¼Æ¶q¥²»Ý¬°¹s!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => '°±¥Î¦¹¶µ¹s¥ó¤§«e, ¦s³f¼Æ¶q¥²»Ý¬°¹s!',
+  'Inventory quantity must be zero!' => '¦s³f¼Æ¶q¥²»Ý¬°¹s!',
+  'Invoice'                     => 'µo²¼',
+  'Invoice Date missing!'       => 'µo²¼¤é´Á¿ù»~!',
+  'Invoice Number'              => 'µo²¼½s¸¹',
+  'Invoice Number missing!'     => 'µo²¼½s¸¹¿ù»~!',
+  'Item deleted!'               => 'Item deleted!',
+  'Item not on file!'           => '¬dµL¦¹¶µ¥Ø',
+  'Jan'                         => '¤@¤ë',
+  'January'                     => '¤@¤ë',
+  'Jul'                         => '¤C¤ë',
+  'July'                        => '¤C¤ë',
+  'Jun'                         => '¤»¤ë',
+  'June'                        => '¤»¤ë',
+  'Last Cost'                   => '¤W¤@µ§¦¨¥»',
+  'Line Total'                  => 'Á`¦C¼Æ',
+  'Link Accounts'               => '³sµ²¬ì¥Ø',
+  'List Price'                  => '¶i»ù',
+  'Make'                        => '»s³y',
+  'Mar'                         => '¤T¤ë',
+  'March'                       => '¤T¤ë',
+  'May'                         => '¤­¤ë',
+  'May '                        => '¤­¤ë',
+  'Message'                     => '°T®§',
+  'Microfiche'                  => 'Microfiche',
+  'Model'                       => '«¬¸¹',
+  'Name'                        => '¦WºÙ',
+  'No.'                         => 'No.',
+  'Notes'                       => '³Æµù',
+  'Nov'                         => '¤Q¤@¤ë',
+  'November'                    => '¤Q¤@¤ë',
+  'Number'                      => '½s¸¹',
+  'Number missing in Row'       => '¦¹¦C¤¤¯Ê¤Ö¼Æ­È',
+  'Obsolete'                    => '°±¥Î',
+  'Oct'                         => '¤Q¤ë',
+  'October'                     => '¤Q¤ë',
+  'On Hand'                     => '¦s¶q',
+  'On Order'                    => 'On Order',
+  'Order'                       => '­q³æ',
+  'Order Date missing!'         => '¥¼«ü©ú¤U³æ¤é´Á!',
+  'Order Number'                => '­q³æ½s¸¹',
+  'Order Number missing!'       => '¥¼«ü©ú­q³æ½s¸¹!',
+  'Ordered'                     => 'Ordered',
+  'Orphaned'                    => 'µL¥D',
+  'PDF'                         => 'PDF',
+  'Packing List'                => '¥X³f³æ',
+  'Packing List Date missing!'  => '¥¼«ü©ú¥]¸Ë²M³æ¤é´Á!',
+  'Packing List Number missing!' => '¥¼«ü©ú¥]¸Ë²M³æ½s¸¹!',
+  'Part'                        => '­ì®Æ',
+  'Part Number missing!'        => 'º|¶ñ­ì®Æ½s¸¹!',
+  'Parts'                       => '­ì®Æ',
+  'Phone'                       => '¹q¸Ü¸¹½X',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => '»ù®æ',
+  'Printer'                     => '¦Lªí¾÷',
+  'Project'                     => 'Project',
+  'Purchase Order'              => '±ÄÁʳæ',
+  'Qty'                         => '¼Æ¶q',
+  'ROP'                         => '¦A­qÂI',
+  'Recd'                        => 'Recd',
+  'Required by'                 => '¤l¶µ¥Ø',
+  'Sales'                       => '·~°È',
+  'Sales Order'                 => '¾P³f³æ',
+  'Save'                        => 'Àx¦s',
+  'Screen'                      => '¿Ã¹õ',
+  'Select from one of the items below' => '©ó¤U¦C¶µ¥Ø¤¤¿ï¾Ü¤@¶µ',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sell Price'                  => '°â»ù',
+  'Sep'                         => '¤E¤ë',
+  'September'                   => '¤E¤ë',
+  'Service'                     => 'ªA°È',
+  'Service Number missing!'     => 'º|¶ñªA°È½s¸¹!',
+  'Services'                    => 'ªA°È',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Short'                       => 'µu',
+  'Sold'                        => '¤w½æ¥X',
+  'Stock Assembly'              => '½LÂI',
+  'Subject'                     => '¼ÐÃD',
+  'Subtotal'                    => '¤p­p',
+  'Tax'                         => 'µ|ª÷',
+  'To'                          => '¦Ü',
+  'Top Level'                   => 'Top Level',
+  'Total'                       => 'Á`­p',
+  'Unit'                        => '³æ¦ì',
+  'Unit of measure'             => '«×¶q³æ¦ì',
+  'Update'                      => 'Update',
+  'Updated'                     => 'Updated',
+  'Weight'                      => '­«¶q',
+  'What type of item is this?'  => '¦¹¶µ¥Øªº«¬ºA?',
+  'ea'                          => '­Ó',
+  'emailed to'                  => '¤w±H¦Ü',
+  'hr'                          => 'hr',
+  'sent to printer'             => '°e¦Ü¦Lªí¾÷',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  '·s¼w'                        => 'add',
+  '·s¼w°Ó«~'                    => 'add_assembly',
+  '·s¼w­ì®Æ'                    => 'add_part',
+  '·s¼wªa°È'                    => 'add_service',
+  'Ä~Äò'                        => 'continue',
+  '§r°£'                        => 'delete',
+  '½s¿è°Ó«~'                    => 'edit_assembly',
+  '½s¿è­ì®Æ'                    => 'edit_part',
+  '½s¿èªa°È'                    => 'edit_service',
+  'Àx¦s'                        => 'save',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/io b/sql-ledger/locale/tw/io
new file mode 100644 (file)
index 0000000..64c8ed7
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => '·s¼W±ÄÁʳæ',
+  'Add Sales Order'             => '·s¼W¾P³f³æ',
+  'Address'                     => '¦a§}',
+  'Apr'                         => '¥|¤ë',
+  'April'                       => '¥|¤ë',
+  'Attachment'                  => 'ªþÀÉ',
+  'Aug'                         => '¤K¤ë',
+  'August'                      => '¤K¤ë',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => '½c',
+  'Cc'                          => 'Cc',
+  'Contact'                     => '³sµ¸¤H',
+  'Continue'                    => 'Ä~Äò',
+  'Copies'                      => '«þ¨©',
+  'Dec'                         => '¤Q¤G¤ë',
+  'December'                    => '¤Q¤G¤ë',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => '»¡©ú',
+  'E-mail'                      => '¹q¤l¶l¥ó',
+  'E-mail address missing!'     => 'º|¶ñ¹q¤l¶l¥ó¦ì§}!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => '¶Ç¯u',
+  'Feb'                         => '¤G¤ë',
+  'February'                    => '¤G¤ë',
+  'In-line'                     => '¦æ¤º',
+  'Invoice'                     => 'µo²¼',
+  'Invoice Date missing!'       => 'µo²¼¤é´Á¿ù»~!',
+  'Invoice Number missing!'     => 'µo²¼½s¸¹¿ù»~!',
+  'Item not on file!'           => '¬dµL¦¹¶µ¥Ø',
+  'Jan'                         => '¤@¤ë',
+  'January'                     => '¤@¤ë',
+  'Jul'                         => '¤C¤ë',
+  'July'                        => '¤C¤ë',
+  'Jun'                         => '¤»¤ë',
+  'June'                        => '¤»¤ë',
+  'Mar'                         => '¤T¤ë',
+  'March'                       => '¤T¤ë',
+  'May'                         => '¤­¤ë',
+  'May '                        => '¤­¤ë',
+  'Message'                     => '°T®§',
+  'Name'                        => '¦WºÙ',
+  'No.'                         => 'No.',
+  'Nov'                         => '¤Q¤@¤ë',
+  'November'                    => '¤Q¤@¤ë',
+  'Number'                      => '½s¸¹',
+  'Number missing in Row'       => '¦¹¦C¤¤¯Ê¤Ö¼Æ­È',
+  'Oct'                         => '¤Q¤ë',
+  'October'                     => '¤Q¤ë',
+  'Order'                       => '­q³æ',
+  'Order Date missing!'         => '¥¼«ü©ú¤U³æ¤é´Á!',
+  'Order Number missing!'       => '¥¼«ü©ú­q³æ½s¸¹!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => '¥X³f³æ',
+  'Packing List Date missing!'  => '¥¼«ü©ú¥]¸Ë²M³æ¤é´Á!',
+  'Packing List Number missing!' => '¥¼«ü©ú¥]¸Ë²M³æ½s¸¹!',
+  'Part'                        => '­ì®Æ',
+  'Phone'                       => '¹q¸Ü¸¹½X',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => '»ù®æ',
+  'Printer'                     => '¦Lªí¾÷',
+  'Project'                     => 'Project',
+  'Purchase Order'              => '±ÄÁʳæ',
+  'Qty'                         => '¼Æ¶q',
+  'Recd'                        => 'Recd',
+  'Required by'                 => '¤l¶µ¥Ø',
+  'Sales Order'                 => '¾P³f³æ',
+  'Screen'                      => '¿Ã¹õ',
+  'Select from one of the items below' => '©ó¤U¦C¶µ¥Ø¤¤¿ï¾Ü¤@¶µ',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => '¤E¤ë',
+  'September'                   => '¤E¤ë',
+  'Service'                     => 'ªA°È',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Subject'                     => '¼ÐÃD',
+  'To'                          => '¦Ü',
+  'Unit'                        => '³æ¦ì',
+  'What type of item is this?'  => '¦¹¶µ¥Øªº«¬ºA?',
+  'emailed to'                  => '¤w±H¦Ü',
+  'sent to printer'             => '°e¦Ü¦Lªí¾÷',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'Ä~Äò'                        => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/ir b/sql-ledger/locale/tw/ir
new file mode 100644 (file)
index 0000000..daa90e4
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => '¬ì¥Ø',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => '·s¼W±ÄÁʳæ',
+  'Add Sales Order'             => '·s¼W¾P³f³æ',
+  'Address'                     => '¦a§}',
+  'Amount'                      => 'Á`­p',
+  'Apr'                         => '¥|¤ë',
+  'April'                       => '¥|¤ë',
+  'Are you sure you want to delete Invoice Number' => '±z½T©w­n§R°£µo²¼½s¸¹',
+  'Attachment'                  => 'ªþÀÉ',
+  'Aug'                         => '¤K¤ë',
+  'August'                      => '¤K¤ë',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => '½c',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'Cannot post invoice for a closed period!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => '¤J±b¦¨¥\!',
+  'Contact'                     => '³sµ¸¤H',
+  'Continue'                    => 'Ä~Äò',
+  'Copies'                      => '«þ¨©',
+  'Currency'                    => '¹ô§O',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => '¤é´Á',
+  'Date Due'                    => 'À³¥I¤é´Á',
+  'Dec'                         => '¤Q¤G¤ë',
+  'December'                    => '¤Q¤G¤ë',
+  'Delete'                      => '§R°£',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => '»¡©ú',
+  'E-mail'                      => '¹q¤l¶l¥ó',
+  'E-mail address missing!'     => 'º|¶ñ¹q¤l¶l¥ó¦ì§}!',
+  'Edit Purchase Invoice'       => 'Edit Purchase Invoice',
+  'Exch'                        => '¶×²v',
+  'Exchangerate'                => '¶×²v',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => '¶Ç¯u',
+  'Feb'                         => '¤G¤ë',
+  'February'                    => '¤G¤ë',
+  'In-line'                     => '¦æ¤º',
+  'Invoice'                     => 'µo²¼',
+  'Invoice Date'                => 'µo²¼¤é´Á',
+  'Invoice Date missing!'       => 'µo²¼¤é´Á¿ù»~!',
+  'Invoice Number'              => 'µo²¼½s¸¹',
+  'Invoice Number missing!'     => 'µo²¼½s¸¹¿ù»~!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => '¬dµL¦¹¶µ¥Ø',
+  'Jan'                         => '¤@¤ë',
+  'January'                     => '¤@¤ë',
+  'Jul'                         => '¤C¤ë',
+  'July'                        => '¤C¤ë',
+  'Jun'                         => '¤»¤ë',
+  'June'                        => '¤»¤ë',
+  'Mar'                         => '¤T¤ë',
+  'March'                       => '¤T¤ë',
+  'May'                         => '¤­¤ë',
+  'May '                        => '¤­¤ë',
+  'Message'                     => '°T®§',
+  'Name'                        => '¦WºÙ',
+  'No.'                         => 'No.',
+  'Notes'                       => '³Æµù',
+  'Nov'                         => '¤Q¤@¤ë',
+  'November'                    => '¤Q¤@¤ë',
+  'Number'                      => '½s¸¹',
+  'Number missing in Row'       => '¦¹¦C¤¤¯Ê¤Ö¼Æ­È',
+  'Oct'                         => '¤Q¤ë',
+  'October'                     => '¤Q¤ë',
+  'Order'                       => '­q³æ',
+  'Order Date missing!'         => '¥¼«ü©ú¤U³æ¤é´Á!',
+  'Order Number'                => '­q³æ½s¸¹',
+  'Order Number missing!'       => '¥¼«ü©ú­q³æ½s¸¹!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => '¥X³f³æ',
+  'Packing List Date missing!'  => '¥¼«ü©ú¥]¸Ë²M³æ¤é´Á!',
+  'Packing List Number missing!' => '¥¼«ü©ú¥]¸Ë²M³æ½s¸¹!',
+  'Part'                        => '­ì®Æ',
+  'Payment date missing!'       => '¥¼«ü©ú¥I´Ú¤é´Á!',
+  'Payments'                    => '¥I´Ú',
+  'Phone'                       => '¹q¸Ü¸¹½X',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => '»ù®æ',
+  'Printer'                     => '¦Lªí¾÷',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => '±ÄÁʳæ',
+  'Qty'                         => '¼Æ¶q',
+  'Recd'                        => 'Recd',
+  'Record in'                   => '°O¿ý©ó',
+  'Required by'                 => '¤l¶µ¥Ø',
+  'Sales Order'                 => '¾P³f³æ',
+  'Screen'                      => '¿Ã¹õ',
+  'Select from one of the items below' => '©ó¤U¦C¶µ¥Ø¤¤¿ï¾Ü¤@¶µ',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => '¤E¤ë',
+  'September'                   => '¤E¤ë',
+  'Service'                     => 'ªA°È',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Source'                      => '¨Ó·½',
+  'Subject'                     => '¼ÐÃD',
+  'Subtotal'                    => '¤p­p',
+  'Tax Included'                => '¤£¦¬ªA°È¶O',
+  'To'                          => '¦Ü',
+  'Total'                       => 'Á`­p',
+  'Unit'                        => '³æ¦ì',
+  'Update'                      => 'Update',
+  'Vendor'                      => '¼t°Ó',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => '¦¹¶µ¥Øªº«¬ºA?',
+  'Yes'                         => '¬O',
+  'ea'                          => '­Ó',
+  'emailed to'                  => '¤w±H¦Ü',
+  'sent to printer'             => '°e¦Ü¦Lªí¾÷',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'Ä~Äò'                        => 'continue',
+  '§r°£'                        => 'delete',
+  '­q³æ'                        => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'update'                      => 'update',
+  '¬o'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/is b/sql-ledger/locale/tw/is
new file mode 100644 (file)
index 0000000..1b0c6ec
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => '¬ì¥Ø',
+  'Add Purchase Order'          => '·s¼W±ÄÁʳæ',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => '·s¼W¾P³f³æ',
+  'Address'                     => '¦a§}',
+  'Amount'                      => 'Á`­p',
+  'Apr'                         => '¥|¤ë',
+  'April'                       => '¥|¤ë',
+  'Are you sure you want to delete Invoice Number' => '±z½T©w­n§R°£µo²¼½s¸¹',
+  'Attachment'                  => 'ªþÀÉ',
+  'Aug'                         => '¤K¤ë',
+  'August'                      => '¤K¤ë',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => '½c',
+  'Cannot delete invoice!'      => 'Cannot delete invoice!',
+  'Cannot post invoice for a closed period!' => 'Cannot post invoice for a closed period!',
+  'Cannot post invoice!'        => 'Cannot post invoice!',
+  'Cannot post payment for a closed period!' => 'Cannot post payment for a closed period!',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => '¤J±b¦¨¥\!',
+  'Contact'                     => '³sµ¸¤H',
+  'Continue'                    => 'Ä~Äò',
+  'Copies'                      => '«þ¨©',
+  'Credit Limit'                => '«H¥ÎÃB«×',
+  'Currency'                    => '¹ô§O',
+  'Customer'                    => '«È¤á',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => '¤é´Á',
+  'Date Due'                    => 'À³¥I¤é´Á',
+  'Dec'                         => '¤Q¤G¤ë',
+  'December'                    => '¤Q¤G¤ë',
+  'Delete'                      => '§R°£',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => '»¡©ú',
+  'E-mail'                      => '¹q¤l¶l¥ó',
+  'E-mail address missing!'     => 'º|¶ñ¹q¤l¶l¥ó¦ì§}!',
+  'Edit Sales Invoice'          => 'Edit Sales Invoice',
+  'Exch'                        => '¶×²v',
+  'Exchangerate'                => '¶×²v',
+  'Exchangerate for payment missing!' => 'Exchangerate for payment missing!',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => '¶Ç¯u',
+  'Feb'                         => '¤G¤ë',
+  'February'                    => '¤G¤ë',
+  'In-line'                     => '¦æ¤º',
+  'Invoice'                     => 'µo²¼',
+  'Invoice Date'                => 'µo²¼¤é´Á',
+  'Invoice Date missing!'       => 'µo²¼¤é´Á¿ù»~!',
+  'Invoice Number'              => 'µo²¼½s¸¹',
+  'Invoice Number missing!'     => 'µo²¼½s¸¹¿ù»~!',
+  'Invoice deleted!'            => 'Invoice deleted!',
+  'Invoice posted!'             => 'Invoice posted!',
+  'Item not on file!'           => '¬dµL¦¹¶µ¥Ø',
+  'Jan'                         => '¤@¤ë',
+  'January'                     => '¤@¤ë',
+  'Jul'                         => '¤C¤ë',
+  'July'                        => '¤C¤ë',
+  'Jun'                         => '¤»¤ë',
+  'June'                        => '¤»¤ë',
+  'Mar'                         => '¤T¤ë',
+  'March'                       => '¤T¤ë',
+  'May'                         => '¤­¤ë',
+  'May '                        => '¤­¤ë',
+  'Message'                     => '°T®§',
+  'Name'                        => '¦WºÙ',
+  'No.'                         => 'No.',
+  'Notes'                       => '³Æµù',
+  'Nov'                         => '¤Q¤@¤ë',
+  'November'                    => '¤Q¤@¤ë',
+  'Number'                      => '½s¸¹',
+  'Number missing in Row'       => '¦¹¦C¤¤¯Ê¤Ö¼Æ­È',
+  'Oct'                         => '¤Q¤ë',
+  'October'                     => '¤Q¤ë',
+  'Order'                       => '­q³æ',
+  'Order Date missing!'         => '¥¼«ü©ú¤U³æ¤é´Á!',
+  'Order Number'                => '­q³æ½s¸¹',
+  'Order Number missing!'       => '¥¼«ü©ú­q³æ½s¸¹!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => '¥X³f³æ',
+  'Packing List Date missing!'  => '¥¼«ü©ú¥]¸Ë²M³æ¤é´Á!',
+  'Packing List Number missing!' => '¥¼«ü©ú¥]¸Ë²M³æ½s¸¹!',
+  'Part'                        => '­ì®Æ',
+  'Payment date missing!'       => '¥¼«ü©ú¥I´Ú¤é´Á!',
+  'Payments'                    => '¥I´Ú',
+  'Phone'                       => '¹q¸Ü¸¹½X',
+  'Post'                        => 'Post',
+  'Post as new'                 => 'Post as new',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => '»ù®æ',
+  'Print'                       => 'Print',
+  'Printer'                     => '¦Lªí¾÷',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => '±ÄÁʳæ',
+  'Qty'                         => '¼Æ¶q',
+  'Recd'                        => 'Recd',
+  'Record in'                   => '°O¿ý©ó',
+  'Remaining'                   => '©|¾l',
+  'Required by'                 => '¤l¶µ¥Ø',
+  'Sales Order'                 => '¾P³f³æ',
+  'Screen'                      => '¿Ã¹õ',
+  'Select from one of the items below' => '©ó¤U¦C¶µ¥Ø¤¤¿ï¾Ü¤@¶µ',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => '¤E¤ë',
+  'September'                   => '¤E¤ë',
+  'Service'                     => 'ªA°È',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Source'                      => '¨Ó·½',
+  'Subject'                     => '¼ÐÃD',
+  'Subtotal'                    => '¤p­p',
+  'Tax Included'                => '¤£¦¬ªA°È¶O',
+  'To'                          => '¦Ü',
+  'Total'                       => 'Á`­p',
+  'Unit'                        => '³æ¦ì',
+  'Update'                      => 'Update',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => '¦¹¶µ¥Øªº«¬ºA?',
+  'Yes'                         => '¬O',
+  'ea'                          => '­Ó',
+  'emailed to'                  => '¤w±H¦Ü',
+  'sent to printer'             => '°e¦Ü¦Lªí¾÷',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'Ä~Äò'                        => 'continue',
+  '§r°£'                        => 'delete',
+  '¹q¤l¶l¥ó'                    => 'e_mail',
+  '­q³æ'                        => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  '¬o'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/login b/sql-ledger/locale/tw/login
new file mode 100644 (file)
index 0000000..d934f5a
--- /dev/null
@@ -0,0 +1,28 @@
+$self{texts} = {
+  'About'                       => 'Ãö©ó',
+  'Accounting'                  => '·|­p',
+  'Database Host'               => '¸ê®Æ®w¥D¾÷',
+  'Dataset'                     => '¸ê®Æ¶°',
+  'Incorrect Dataset version!'  => '¸ê®Æ¶°ª©¥»¿ù»~!',
+  'Incorrect Password!'         => '±K½X¿ù»~!',
+  'Licensed to'                 => '±ÂÅv¤©',
+  'Login'                       => 'µn¤J',
+  'Name'                        => '¦WºÙ',
+  'Password'                    => '±K½X',
+  'User'                        => '¨Ï¥ÎªÌ',
+  'Version'                     => 'ª©¥»',
+  'You are logged out!'         => 'You are logged out!',
+  'You did not enter a name!'   => '±z¨Ã¥¼Áä¤J¦WºÙ!',
+  'is not a member!'            => '¨Ã¤£¬O¦¨­û!',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'µn¤j'                        => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/menu b/sql-ledger/locale/tw/menu
new file mode 100644 (file)
index 0000000..54a3f07
--- /dev/null
@@ -0,0 +1,72 @@
+$self{texts} = {
+  'AP'                          => 'À³¥I±b´Ú',
+  'AP Aging'                    => 'À³¥I±bÄÖ¤ÀªR',
+  'AR'                          => 'À³¦¬±b´Ú',
+  'AR Aging'                    => 'À³¦¬±bÄÖ¤ÀªR',
+  'Accounting Menu'             => '·|­p¿ï³æ',
+  'Add Account'                 => '·s¼W¬ì¥Ø',
+  'Add Assembly'                => '·s¼W°Ó«~',
+  'Add Customer'                => '·s¼W«È¤á',
+  'Add GIFI'                    => '·s¼W GIFI',
+  'Add Part'                    => '·s¼W­ì®Æ',
+  'Add Project'                 => 'Add Project',
+  'Add Service'                 => '·s¼WªA°È',
+  'Add Transaction'             => '·s¼W±b¥Ø',
+  'Add Vendor'                  => '·s¼W¼t°Ó',
+  'Assemblies'                  => '°Ó«~',
+  'Audit Control'               => '½]®Ö±±¨î',
+  'Backup'                      => '³Æ¥÷',
+  'Balance Sheet'               => '¸ê²£­t¶Åªí',
+  'Cash'                        => 'Cash',
+  'Chart of Accounts'           => '·|­p¬ì¥Øªí',
+  'Check'                       => 'Check',
+  'Customers'                   => 'Customers',
+  'General Ledger'              => 'Á`±b',
+  'Goods & Services'            => '³fª«¤ÎªA°È',
+  'HTML Templates'              => 'HTML ªí³æ',
+  'Income Statement'            => '·l¯qªí',
+  'Invoice'                     => 'µo²¼',
+  'LaTeX Templates'             => 'LaTex ¼Òª©',
+  'List Accounts'               => '¦C¥X±b¸¹',
+  'List GIFI'                   => '¦C¥X GIFI',
+  'Logout'                      => 'µn¥X',
+  'Order Entry'                 => '¤U³æ¶µ¥Ø',
+  'Packing List'                => '¥X³f³æ',
+  'Parts'                       => '­ì®Æ',
+  'Payment'                     => '¥I´Ú¤è¦¡',
+  'Payments'                    => '¥I´Ú',
+  'Preferences'                 => '­Ó¤H³]©w',
+  'Projects'                    => 'Projects',
+  'Purchase Invoice'            => 'Purchase Invoice',
+  'Purchase Order'              => '±ÄÁʳæ',
+  'Purchase Orders'             => '±ÄÁʳæ',
+  'Receipt'                     => 'Receipt',
+  'Receipts'                    => 'Receipts',
+  'Reconciliation'              => 'Reconciliation',
+  'Reports'                     => '³øªí',
+  'Sales Invoice'               => 'Sales Invoice',
+  'Sales Order'                 => '¾P³f³æ',
+  'Sales Orders'                => '¾P³f³æ',
+  'Save to File'                => 'Àx¦s¦ÜÀÉ®×',
+  'Send by E-Mail'              => '¥H¹q¤l¶l¥ó±H°e',
+  'Services'                    => 'ªA°È',
+  'Statement'                   => 'Statement',
+  'Stock Assembly'              => '½LÂI',
+  'Stylesheet'                  => '¼Ë¦¡ªí',
+  'System'                      => '¨t²Î',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'Transactions'                => '±b¥Ø',
+  'Trial Balance'               => '¸Õºâªí',
+  'Vendors'                     => 'Vendors',
+  'Version'                     => 'ª©¥»',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/oe b/sql-ledger/locale/tw/oe
new file mode 100644 (file)
index 0000000..57dd382
--- /dev/null
@@ -0,0 +1,199 @@
+$self{texts} = {
+  'Add'                         => '·s¼W',
+  'Add Purchase Invoice'        => 'Add Purchase Invoice',
+  'Add Purchase Order'          => '·s¼W±ÄÁʳæ',
+  'Add Sales Invoice'           => 'Add Sales Invoice',
+  'Add Sales Order'             => '·s¼W¾P³f³æ',
+  'Address'                     => '¦a§}',
+  'Amount'                      => 'Á`­p',
+  'Apr'                         => '¥|¤ë',
+  'April'                       => '¥|¤ë',
+  'Are you sure you want to delete Order Number' => '±z¬O§_½T©w­n§R°£­q³æ',
+  'Attachment'                  => 'ªþÀÉ',
+  'Aug'                         => '¤K¤ë',
+  'August'                      => '¤K¤ë',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => '½c',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'Cannot delete order!',
+  'Cannot save order!'          => 'Cannot save order!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => '¤wÃö³¬',
+  'Confirm!'                    => '¤J±b¦¨¥\!',
+  'Contact'                     => '³sµ¸¤H',
+  'Continue'                    => 'Ä~Äò',
+  'Copies'                      => '«þ¨©',
+  'Credit Limit'                => '«H¥ÎÃB«×',
+  'Curr'                        => '¥Ø«e',
+  'Currency'                    => '¹ô§O',
+  'Customer'                    => '«È¤á',
+  'Customer missing!'           => 'Customer missing!',
+  'Customer not on file!'       => 'Customer not on file!',
+  'Date'                        => '¤é´Á',
+  'Dec'                         => '¤Q¤G¤ë',
+  'December'                    => '¤Q¤G¤ë',
+  'Delete'                      => '§R°£',
+  'Delivery Date'               => 'Delivery Date',
+  'Description'                 => '»¡©ú',
+  'E-mail'                      => '¹q¤l¶l¥ó',
+  'E-mail address missing!'     => 'º|¶ñ¹q¤l¶l¥ó¦ì§}!',
+  'Edit Purchase Order'         => '½s¿è±ÄÁʳæ',
+  'Edit Sales Order'            => '½s¿è¾P³f³æ',
+  'Exchangerate'                => '¶×²v',
+  'Exchangerate missing!'       => 'Exchangerate missing!',
+  'Extended'                    => 'Extended',
+  'Fax'                         => '¶Ç¯u',
+  'Feb'                         => '¤G¤ë',
+  'February'                    => '¤G¤ë',
+  'From'                        => '±q',
+  'ID'                          => '½s¸¹',
+  'In-line'                     => '¦æ¤º',
+  'Include in Report'           => '¤@¨ÖÅã¥Ü',
+  'Invoice'                     => 'µo²¼',
+  'Invoice Date missing!'       => 'µo²¼¤é´Á¿ù»~!',
+  'Invoice Number missing!'     => 'µo²¼½s¸¹¿ù»~!',
+  'Item not on file!'           => '¬dµL¦¹¶µ¥Ø',
+  'Jan'                         => '¤@¤ë',
+  'January'                     => '¤@¤ë',
+  'Jul'                         => '¤C¤ë',
+  'July'                        => '¤C¤ë',
+  'Jun'                         => '¤»¤ë',
+  'June'                        => '¤»¤ë',
+  'Mar'                         => '¤T¤ë',
+  'March'                       => '¤T¤ë',
+  'May'                         => '¤­¤ë',
+  'May '                        => '¤­¤ë',
+  'Message'                     => '°T®§',
+  'Name'                        => '¦WºÙ',
+  'No.'                         => 'No.',
+  'Notes'                       => '³Æµù',
+  'Nov'                         => '¤Q¤@¤ë',
+  'November'                    => '¤Q¤@¤ë',
+  'Number'                      => '½s¸¹',
+  'Number missing in Row'       => '¦¹¦C¤¤¯Ê¤Ö¼Æ­È',
+  'O'                           => 'O',
+  'Oct'                         => '¤Q¤ë',
+  'October'                     => '¤Q¤ë',
+  'Open'                        => '¶}±Ò',
+  'Order'                       => '­q³æ',
+  'Order Date'                  => '¤U³æ¤é´Á',
+  'Order Date missing!'         => '¥¼«ü©ú¤U³æ¤é´Á!',
+  'Order Number'                => '­q³æ½s¸¹',
+  'Order Number missing!'       => '¥¼«ü©ú­q³æ½s¸¹!',
+  'Order deleted!'              => 'Order deleted!',
+  'Order saved!'                => 'Order saved!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => '¥X³f³æ',
+  'Packing List Date missing!'  => '¥¼«ü©ú¥]¸Ë²M³æ¤é´Á!',
+  'Packing List Number missing!' => '¥¼«ü©ú¥]¸Ë²M³æ½s¸¹!',
+  'Part'                        => '­ì®Æ',
+  'Phone'                       => '¹q¸Ü¸¹½X',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => '»ù®æ',
+  'Print'                       => 'Print',
+  'Printer'                     => '¦Lªí¾÷',
+  'Project'                     => 'Project',
+  'Project not on file!'        => 'Project not on file!',
+  'Purchase Order'              => '±ÄÁʳæ',
+  'Purchase Orders'             => '±ÄÁʳæ',
+  'Qty'                         => '¼Æ¶q',
+  'Recd'                        => 'Recd',
+  'Remaining'                   => '©|¾l',
+  'Required by'                 => '¤l¶µ¥Ø',
+  'Sales Order'                 => '¾P³f³æ',
+  'Sales Orders'                => '¾P³f³æ',
+  'Save'                        => 'Àx¦s',
+  'Save as new'                 => 'Save as new',
+  'Screen'                      => '¿Ã¹õ',
+  'Select from one of the items below' => '©ó¤U¦C¶µ¥Ø¤¤¿ï¾Ü¤@¶µ',
+  'Select from one of the names below' => 'Select from one of the names below',
+  'Select from one of the projects below' => 'Select from one of the projects below',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => '¤E¤ë',
+  'September'                   => '¤E¤ë',
+  'Service'                     => 'ªA°È',
+  'Ship'                        => 'Ship',
+  'Ship to'                     => 'Ship to',
+  'Ship via'                    => 'Ship via',
+  'Subject'                     => '¼ÐÃD',
+  'Subtotal'                    => '¤p­p',
+  'Tax'                         => 'µ|ª÷',
+  'Tax Included'                => '¤£¦¬ªA°È¶O',
+  'Terms: Net'                  => '²¼´Á²b­p',
+  'To'                          => '¦Ü',
+  'Total'                       => 'Á`­p',
+  'Unit'                        => '³æ¦ì',
+  'Update'                      => 'Update',
+  'Vendor'                      => '¼t°Ó',
+  'Vendor missing!'             => 'Vendor missing!',
+  'Vendor not on file!'         => 'Vendor not on file!',
+  'What type of item is this?'  => '¦¹¶µ¥Øªº«¬ºA?',
+  'Yes'                         => '¬O',
+  'days'                        => '¤é',
+  'ea'                          => '­Ó',
+  'emailed to'                  => '¤w±H¦Ü',
+  'sent to printer'             => '°e¦Ü¦Lªí¾÷',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  '·s¼w'                        => 'add',
+  'Ä~Äò'                        => 'continue',
+  '§r°£'                        => 'delete',
+  '¹q¤l¶l¥ó'                    => 'e_mail',
+  'µo²¼'                        => 'invoice',
+  'print'                       => 'print',
+  'Àx¦s'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  '¬o'                          => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/pe b/sql-ledger/locale/tw/pe
new file mode 100644 (file)
index 0000000..6e7b638
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => '·s¼W',
+  'Add Project'                 => 'Add Project',
+  'All'                         => '¥þ³¡',
+  'Continue'                    => 'Ä~Äò',
+  'Delete'                      => '§R°£',
+  'Description'                 => '»¡©ú',
+  'Edit Project'                => 'Edit Project',
+  'Number'                      => '½s¸¹',
+  'Orphaned'                    => 'µL¥D',
+  'Project'                     => 'Project',
+  'Project Number missing!'     => 'Project Number missing!',
+  'Project deleted!'            => 'Project deleted!',
+  'Project saved!'              => 'Project saved!',
+  'Projects'                    => 'Projects',
+  'Save'                        => 'Àx¦s',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  '·s¼w'                        => 'add',
+  'Ä~Äò'                        => 'continue',
+  '§r°£'                        => 'delete',
+  'Àx¦s'                        => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/rc b/sql-ledger/locale/tw/rc
new file mode 100644 (file)
index 0000000..2f813ab
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => '¬ì¥Ø',
+  'Balance'                     => 'Balance',
+  'Cleared Balance'             => 'Cleared Balance',
+  'Continue'                    => 'Ä~Äò',
+  'Date'                        => '¤é´Á',
+  'Deposit'                     => 'Deposit',
+  'Description'                 => '»¡©ú',
+  'Difference'                  => 'Difference',
+  'Done'                        => 'Done',
+  'Exchangerate Difference'     => 'Exchangerate Difference',
+  'From'                        => '±q',
+  'Out of balance!'             => 'Out of balance!',
+  'Payment'                     => '¥I´Ú¤è¦¡',
+  'Reconciliation'              => 'Reconciliation',
+  'Select all'                  => 'Select all',
+  'Source'                      => '¨Ó·½',
+  'Statement Balance'           => 'Statement Balance',
+  'To'                          => '¦Ü',
+  'Update'                      => 'Update',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'Ä~Äò'                        => 'continue',
+  'done'                        => 'done',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/tw/rp b/sql-ledger/locale/tw/rp
new file mode 100644 (file)
index 0000000..603745b
--- /dev/null
@@ -0,0 +1,117 @@
+$self{texts} = {
+  'AP Aging'                    => 'À³¥I±bÄÖ¤ÀªR',
+  'AR Aging'                    => 'À³¦¬±bÄÖ¤ÀªR',
+  'Account'                     => '¬ì¥Ø',
+  'Accounts'                    => '±b¤á',
+  'Amount'                      => 'Á`­p',
+  'Apr'                         => '¥|¤ë',
+  'April'                       => '¥|¤ë',
+  'Attachment'                  => 'ªþÀÉ',
+  'Aug'                         => '¤K¤ë',
+  'August'                      => '¤K¤ë',
+  'Balance Sheet'               => '¸ê²£­t¶Åªí',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Cash based',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => '¹ï·Ó',
+  'Continue'                    => 'Ä~Äò',
+  'Copies'                      => '«þ¨©',
+  'Credit'                      => '¶U¤è',
+  'Current'                     => 'Current',
+  'Customer'                    => '«È¤á',
+  'Date'                        => '¤é´Á',
+  'Debit'                       => '­É¤è',
+  'Dec'                         => '¤Q¤G¤ë',
+  'December'                    => '¤Q¤G¤ë',
+  'Decimalplaces'               => 'Decimalplaces',
+  'Description'                 => '»¡©ú',
+  'Due'                         => '¨ì´Á',
+  'E-mail'                      => '¹q¤l¶l¥ó',
+  'E-mail Statement to'         => 'E-mail Statement to',
+  'Feb'                         => '¤G¤ë',
+  'February'                    => '¤G¤ë',
+  'From'                        => '±q',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'ªíÀY',
+  'ID'                          => '½s¸¹',
+  'In-line'                     => '¦æ¤º',
+  'Include in Report'           => '¤@¨ÖÅã¥Ü',
+  'Income Statement'            => '·l¯qªí',
+  'Invoice'                     => 'µo²¼',
+  'Jan'                         => '¤@¤ë',
+  'January'                     => '¤@¤ë',
+  'Jul'                         => '¤C¤ë',
+  'July'                        => '¤C¤ë',
+  'Jun'                         => '¤»¤ë',
+  'June'                        => '¤»¤ë',
+  'Mar'                         => '¤T¤ë',
+  'March'                       => '¤T¤ë',
+  'May'                         => '¤­¤ë',
+  'May '                        => '¤­¤ë',
+  'Message'                     => '°T®§',
+  'N/A'                         => '¤£¾A¥Î',
+  'Nothing selected!'           => 'Nothing selected!',
+  'Nov'                         => '¤Q¤@¤ë',
+  'November'                    => '¤Q¤@¤ë',
+  'Oct'                         => '¤Q¤ë',
+  'October'                     => '¤Q¤ë',
+  'PDF'                         => 'PDF',
+  'Payments'                    => '¥I´Ú',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Print',
+  'Printer'                     => '¦Lªí¾÷',
+  'Receipts'                    => 'Receipts',
+  'Report for'                  => '³øªí¨Ó·½',
+  'Retained Earnings'           => '«O¯d¬Õ¾l',
+  'Screen'                      => '¿Ã¹õ',
+  'Select all'                  => 'Select all',
+  'Select postscript or PDF!'   => 'Select postscript or PDF!',
+  'Sep'                         => '¤E¤ë',
+  'September'                   => '¤E¤ë',
+  'Source'                      => '¨Ó·½',
+  'Standard'                    => '¼Ð·Ç',
+  'Statement'                   => 'Statement',
+  'Statement sent to'           => 'Statement sent to',
+  'Statements sent to printer!' => 'Statements sent to printer!',
+  'Subject'                     => '¼ÐÃD',
+  'Subtotal'                    => '¤p­p',
+  'Tax'                         => 'µ|ª÷',
+  'Tax collected'               => 'Tax collected',
+  'Tax paid'                    => 'Tax paid',
+  'To'                          => '¦Ü',
+  'Total'                       => 'Á`­p',
+  'Trial Balance'               => '¸Õºâªí',
+  'Vendor'                      => '¼t°Ó',
+  'as at'                       => 'as at',
+  'collected on sales'          => '¦b¾P³f®Éµ²²M',
+  'for Period'                  => '´Á¶¡',
+  'paid on purchases'           => '¦b±ÄÁʮɵ²²M',
+  'to'                          => 'to',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'Ä~Äò'                        => 'continue',
+  '¹q¤l¶l¥ó'                    => 'e_mail',
+  'print'                       => 'print',
+  'select_all'                  => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/COPYING b/sql-ledger/locale/ua/COPYING
new file mode 100644 (file)
index 0000000..001a4f8
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (c) 2003
+#
+# Ukrainian texts:
+#
+# Author: Ivan Petrouchtchak <impe@telus.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/ua/LANGUAGE b/sql-ledger/locale/ua/LANGUAGE
new file mode 100644 (file)
index 0000000..368ad3b
--- /dev/null
@@ -0,0 +1 @@
+Ukrainian
diff --git a/sql-ledger/locale/ua/admin b/sql-ledger/locale/ua/admin
new file mode 100644 (file)
index 0000000..2ba71b0
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'ëÏÎÔÒÏÌØ äÏÓÔÕÐÕ',
+  'Accounting'                  => 'ïÂ̦Ë',
+  'Add User'                    => 'îÏ×ÉÊ ËÏÒÉÓÔÕ×ÁÞ',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'Administration'              => 'áÄͦΦÓÔÒÕ×ÁÎÎÑ',
+  'Administrator'               => 'áÄͦΦÓÔÒÁÔÏÒ',
+  'All Datasets up to date!'    => 'âÁÚÉ äÁÎÉÈ ÎÅ ÐÏÔÒÅÂÕÀÔØ ÐÏÎÏ×ÌÅÎÎÑ!',
+  'Change Admin Password'       => 'úͦÎÉÔÉ ÐÁÒÏÌØ áÄͦΦÓÔÒÁÔÏÒÁ',
+  'Change Password'             => 'úͦÎÉÔÉ ÐÁÒÏÌØ',
+  'Character Set'               => 'ëÏÄÉÒÏ×ËÁ',
+  'Click on login name to edit!' => 'îÁÔÉÓΦÔØ ÎÁ ÎÁÚ×Õ ËÏÒÉÓÔÕ×ÁÞÁ, ÝÏ ÚÒÏÂÉÔÉ ÚͦÎÉ!',
+  'Company'                     => 'ð¦ÄÐÒɤÍÓÔ×Ï',
+  'Connect to'                  => 'ð¦ÄËÌÀÞÉÔÉÓØ ÄÏ',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Create Chart of Accounts'    => 'óÔ×ÏÒÉÔÉ ðÌÁΠòÁÈÕÎ˦×',
+  'Create Dataset'              => 'óÔ×ÏÒÉÔÉ âÁÚÕ äÁÎÉÈ',
+  'DBI not installed!'          => 'îÅ ×ÓÔÁÎÏ×ÌÅÎÉÊ ÄÒÁÊ×ÅÒ DBI!',
+  'Database'                    => 'âÁÚÁ äÁÎÉÈ',
+  'Database Administration'     => 'áÄͦΦÓÔÒÕ×ÁÎÎÑ ÂÁÚÉ ÄÁÎÉÈ',
+  'Database Driver not checked!' => 'îÅ ÚÁÚÎÁÞÅÎÉÊ ÄÒÁÊ×ÅÒ âÁÚÉ äÁÎÉÈ (Pg)!',
+  'Database User missing!'      => 'îÅ ×ËÁÚÁÎÉÊ ëÏÒÉÓÔÕ×ÁÞ âÁÚÉ äÁÎÉÈ!',
+  'Dataset'                     => 'âÁÚÁ äÁÎÉÈ',
+  'Dataset missing!'            => 'îÅ ×ËÁÚÁÎÁ âÁÚÁ äÁÎÉÈ!',
+  'Dataset updated!'            => 'âÁÚÁ äÁÎÉÈ ÐÏÎÏ×ÌÅÎÁ!',
+  'Date Format'                 => 'æÏÒÍÁÔ ÄÁÔÉ',
+  'Delete'                      => '÷ÉÄÁÌÉÔÉ',
+  'Delete Dataset'              => '÷ÉÄÁÌÉÔÉ âÁÚÕ äÁÎÉÈ',
+  'Directory'                   => 'ëÁÔÁÌÏÇ',
+  'Driver'                      => 'äÒÁÊ×ÅÒ',
+  'Dropdown Limit'              => 'ïÂÍÅÖÅÎÎÑ ÌÉÓÔÏ×ÏÇÏ ÍÅÎÀ',
+  'E-mail'                      => 'åÌ. ÐÏÛÔÁ',
+  'Edit User'                   => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ëÏÒÉÓÔÕ×ÁÞÁ',
+  'Existing Datasets'           => '¶ÓÎÕÀÞ¦ âÁÚÉ äÁÎÉÈ',
+  'Fax'                         => 'æÁÈ',
+  'Host'                        => 'íÁÛÉÎÁ/Host',
+  'Hostname missing!'           => 'îÅ ×ËÁÚÁÎÁ ÎÁÚ×Á ÍÁÛÉÎÉ!',
+  'Incorrect Password!'         => 'îÅצÒÎÉÊ ðÁÒÏÌØ!',
+  'Language'                    => 'íÏ×Á',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'ñËÝÏ ×É ÎÅ ÂÁÖÁ¤ÔÅ ×ÓÔÁÎÏ×ÉÔɠצÄÄÁÌÅÎÉÊ Ú×ÑÚÏË, ÎÅ ÚÁÐÏ×ÎÀÊÔÅ ÐÏÌÑ ÍÁÛÉÎÉ ¦ ÐÏÒÔÕ.',
+  'Login'                       => 'ðÏÞÁÔÏË óÅÁÎÓÕ',
+  'Multibyte Encoding'          => 'íÕÌØÔÉÂÉÔÎÅ ëÏÄÕ×ÁÎÎÑ',
+  'Name'                        => '¶Í\'Ñ / îÁÚ×Á',
+  'New Templates'               => 'îÏצ ûÁÂÌÏÎÉ',
+  'No Database Drivers available!' => 'îÅÄÏÓÔÕÐÎÉÊ ÄÒÁÊ×ÅÒ âÁÚÉ äÁÎÉÈ!',
+  'No Dataset selected!'        => 'îÅ ÐÏÚÎÁÞÅÎÏ ×ÉÂÒÁÎÕ âÁÚÕ äÁÎÉÈ!',
+  'Nothing to delete!'          => 'îÅÍÁ ÝÏ ×ÉÄÁÌÉÔÉ!',
+  'Number Format'               => 'æÏÒÍÁÔ þÉÓÌÁ',
+  'Oracle Database Administration' => 'áÄͦΦÓÔÒÁæѠâÁÚÉ äÁÎÉÈ Oracle',
+  'Password'                    => 'ðÁÒÏÌØ',
+  'Password changed!'           => 'ðÁÒÏÌØ ÚͦÎÅÎÏ!',
+  'Pg Database Administration'  => 'áÄͦΦÓÔÒÁæѠâÁÚÉ äÁÎÉÈ Pg',
+  'Phone'                       => 'ôÅÌ.',
+  'Port'                        => 'ðÏÒÔ',
+  'Port missing!'               => 'ðÏÒÔ ÎÅ ×ËÁÚÁÎÏ!',
+  'Printer'                     => 'ðÒÉÎÔÅÒ',
+  'Save'                        => 'úÂÅÒÅÇÔÉ',
+  'Select a Dataset to delete and press "Continue"' => '÷ÉÂÅÒ¦ÔØ âÁÚÕ äÁÎÉÈ ÄÌÑ ×ÉÄÁÌÅÎÎÑ ¦ ÎÁÔÉÓΦÔØ "ðÒÏÄÏ×ÖÉÔÉ"',
+  'Setup Templates'             => 'îÁÌÁÛÔÕ×ÁÔÉ ûÁÂÌÏÎÉ',
+  'Ship via'                    => 'ðÏÓÌÁÔÉ ÞÅÒÅÚ',
+  'Signature'                   => 'ð¦ÄÐÉÓ',
+  'Stylesheet'                  => 'ïÆÏÒÍÌÅÎÎÎÑ',
+  'Templates'                   => 'ûÁÂÌÏÎÉ',
+  'The following Datasets are not in use and can be deleted' => 'îÁÓÔÕÐΦ âÁÚÉ äÁÎÉÈ ÎÅ ×ÉËÏÒÉÓÔÏ×ÕÀÔØÓÑ ¦ ÍÏÖÕÔØ ÂÕÔÉ ×ÉÄÁÌÅΦ',
+  'The following Datasets need to be updated' => 'îÁÓÔÕÐΦ âÁÚÉ äÁÎÉÈ ÐÏ×ÉÎΦ ÂÕÔÉ ÐÏÎÏ×ÌÅΦ',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'ðÏÐÅÒÅÄÎÑ ÐÅÒÅצÒËÁ ¦ÓÎÕÀÞÉÈ ÄÖÅÒÅÌ. ðÏËÉ ÝϠΦÞÏÇÏ ÎÅ ÂÕÄÅ ÓÔ×ÏÒÅÎÏ ÁÂÏ ×ÉÄÁÌÅÎÏ!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'ýÏ ÄÏÄÁÔÉ ËÏÒÉÓÔÕ×ÁÞÁ ÄÏ ÇÒÕÐÉ, ÔÒÅÂÁ ÐÏͦÎÑÔÉ ¦Í\'Ñ, login/××ÏÄÎÅ ¦ÍÑ ¦ ÚÂÅÒÅÇÔÉ. îÏ×ÉÊ ËÏÒÉÓÔÕ×ÁÞÁ ¦Ú ÏÄÎÁËÏ×ÉÍÉ ÐÁÒÁÍÅÔÒÁÍÉ ÂÕÄÅ ÚÂÅÒÅÖÅÎϠЦĠÎÏ×ÉÍ login/××ÏÄÎÉÍ ¦Í\'ÑÍ.',
+  'Update Dataset'              => 'ðÏÎÏ×ÉÔÉ âÁÚÕ äÁÎÉÈ',
+  'Use Templates'               => '÷ÉËÏÒÉÓÔÏ×Õ×ÁÔÉ ûÁÂÌÏÎÉ',
+  'User'                        => 'ëÏÒÉÓÔÕ×ÁÞ',
+  'User deleted!'               => 'ëÏÒÉÓÔÕ×ÁÞ ÷ÉÄÁÌÅÎÉÊ',
+  'User saved!'                 => 'ëÏÒÉÓÔÕ×ÁÞ ÚÂÅÒÅÖÅÎÉÊ',
+  'Version'                     => '÷ÅÒÓ¦Ñ',
+  'You must enter a host and port for local and remote connections!' => 'íÕÓÉÔÅ ××ÅÓÔÉ ÎÁÚ×Õ ÍÁÛÉÎÉ ¦ ÐÏÒÔÁ ÄÌѠͦÓÃÅ×ÏÇÏ ¦ ×¦ÄÄÁÌÅÎÏÇÏ Ú×ÑÚËÕ!',
+  'does not exist'              => 'ÎÅ ¦ÓÎÕ¤',
+  'is already a member!'        => '×ÖÅ ¤ ÞÌÅÎÏÍ!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'ÚÁÍËÎÕÔÉÊ!',
+  'successfully created!'       => 'ÕÓЦÛÎÏ ÓÔ×ÏÒÅÎÏ!',
+  'successfully deleted!'       => 'ÕÓЦÛÎÏ ×ÉÄÁÌÅÎÏ!',
+  'website'                     => '×ÅÂ-ÓÔÏÒ¦ÎËÁ',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'îÏ×ÉÊ_ËÏÒÉÓÔÕ×ÁÞ'            => 'add_user',
+  'úͦÎÉÔÉ_ÐÁÒÏÌØ_áÄͦΦÓÔÒÁÔÏÒÁ' => 'change_admin_password',
+  'úͦÎÉÔÉ_ÐÁÒÏÌØ'              => 'change_password',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  'óÔ×ÏÒÉÔÉ_âÁÚÕ_äÁÎÉÈ'         => 'create_dataset',
+  '÷ÉÄÁÌÉÔÉ'                    => 'delete',
+  '÷ÉÄÁÌÉÔÉ_âÁÚÕ_äÁÎÉÈ'         => 'delete_dataset',
+  'ðÏÞÁÔÏË_óÅÁÎÓÕ'              => 'login',
+  'áÄͦΦÓÔÒÁæÑ_âÁÚÉ_äÁÎÉÈ_oracle' => 'oracle_database_administration',
+  'áÄͦΦÓÔÒÁæÑ_âÁÚÉ_äÁÎÉÈ_pg' => 'pg_database_administration',
+  'úÂÅÒÅÇÔÉ'                    => 'save',
+  'ðÏÎÏ×ÉÔÉ_âÁÚÕ_äÁÎÉÈ'         => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/all b/sql-ledger/locale/ua/all
new file mode 100644 (file)
index 0000000..c863ea3
--- /dev/null
@@ -0,0 +1,495 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => '÷ÉÔÒÁÔÉ',
+  'AP Aging'                    => 'AP Aging (×ÉÔÒÁÔÉ)',
+  'AP Transaction'              => 'ïÐÅÒÁ槠÷ÉÔÒÁÔ',
+  'AP Transactions'             => 'ïÐÅÒÁ槠÷ÉÔÒÁÔ',
+  'AR'                          => 'äÏÈÏÄÉ',
+  'AR Aging'                    => 'AR Aging (ÄÏÈÏÄÉ)',
+  'AR Transaction'              => 'ïÐÅÒÁæѠäÏÈÏĦ×',
+  'AR Transactions'             => 'ïÐÅÒÁæѠäÏÈÏĦ×',
+  'About'                       => 'ðÒÏ ÐÒÏÇÒÁÍÕ',
+  'Access Control'              => 'ëÏÎÔÒÏÌØ äÏÓÔÕÐÕ',
+  'Account'                     => 'òÁÈÕÎÏË',
+  'Account Number'              => 'îÏÍÅÒ òÁÈÕÎËÕ',
+  'Account Number missing!'     => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ÒÁÈÕÎËÕ!',
+  'Account Type'                => '÷ÉÄ ÒÁÈÕÎËÕ',
+  'Account Type missing!'       => 'îÅ ×ËÁÚÁÎÉÊ ×ÉÄ ÒÁÈÕÎËÕ!',
+  'Account deleted!'            => 'òÁÈÕÎÏË ×ÉÄÁÌÅÎÉÊ',
+  'Account saved!'              => 'òÁÈÕÎÏË ÚÂÅÒÅÖÅÎÏ',
+  'Accounting'                  => 'ïÂ̦Ë',
+  'Accounting Menu'             => 'íÅÎÀ ïÂ̦ËÕ',
+  'Accounts'                    => 'òÁÈÕÎËÉ',
+  'Active'                      => 'áËÔÉ×ÎÉÊ',
+  'Add'                         => 'îÏ×ÉÊ',
+  'Add Account'                 => 'îÏ×ÉÊ ÒÁÈÕÎÏË',
+  'Add Accounts Payables Transaction' => 'îÏ×Á ÏÐÅÒÁæѠ×ÉÔÒÁÔ',
+  'Add Accounts Receivables Transaction' => 'îÏ×Á ÏÐÅÒÁæѠÄÏÈÏĦ×',
+  'Add Assembly'                => 'îÏ×ÉÊ ËÏÍÐÌÅËÔ',
+  'Add Customer'                => 'îÏ×ÉÊ Ë̦¤ÎÔ',
+  'Add GIFI'                    => 'îÏ×ÉÊ GIFI',
+  'Add General Ledger Transaction' => 'îÏ×Á ÏÐÅÒÁæÑ',
+  'Add Part'                    => 'îÏ×ÉÊ ôÏ×ÁÒ',
+  'Add Project'                 => 'îÏ×ÉÊ ðÒÏÅËÔ',
+  'Add Purchase Invoice'        => 'îÏ×ÉÊ ëÕЦ×ÅÌØÎÉÊ òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Add Purchase Order'          => 'îÏ×Å ÚÁÍÏ×ÌÅÎÎÑ ÎÁ ËÕЦ×ÌÀ',
+  'Add Sales Invoice'           => 'îÏ×ÉÊ òÁÈÕÎÏ-ÆÁËÔÕÒÁ',
+  'Add Sales Order'             => 'îÏ×Å ÚÁÍÏ×ÌÅÎÎÑ ÎÁ ÐÒÏÄÁÖ',
+  'Add Service'                 => 'îÏ×Á ÐÏÓÌÕÇÁ',
+  'Add Transaction'             => 'îÏ×Á ÏÐÅÒÁæÑ',
+  'Add User'                    => 'îÏ×ÉÊ ËÏÒÉÓÔÕ×ÁÞ',
+  'Add Vendor'                  => 'îÏ×ÉÊ ÐÏÓÔÁÞÁÌØÎÉË',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'Administration'              => 'áÄͦΦÓÔÒÕ×ÁÎÎÑ',
+  'Administrator'               => 'áÄͦΦÓÔÒÁÔÏÒ',
+  'All'                         => '÷Ó¦',
+  'All Datasets up to date!'    => 'âÁÚÉ äÁÎÉÈ ÎÅ ÐÏÔÒÅÂÕÀÔØ ÐÏÎÏ×ÌÅÎÎÑ!',
+  'Amount'                      => 'óÕÍÁ',
+  'Amount Due'                  => 'úÁÐÌÁÔÉÔÉ óÕÍÕ',
+  'Amount does not equal applied!' => 'óÕÍÁ ÎÅ ÄÏÒ¦×ÎÀ¤ ÚÁÓÔÏÓÏ×ÁΦÊ!',
+  'Amount missing!'             => 'îÅ ×ËÁÚÁÎÁ ÓÕÍÁ!',
+  'Applied'                     => 'úÁÓÔÏÓÏ×ÁÎÏ',
+  'Apr'                         => 'ËצÔÎÑ',
+  'April'                       => 'ëצÔÅÎØ',
+  'Are you sure you want to delete Invoice Number' => '÷É ÐÅ×Φ, ÝÏ ÈÏÞÅÔÅ ×ÉÄÁÌÉÔÉ ÄÁÎÉÊ ÒÁÈÕÎÏË?',
+  'Are you sure you want to delete Order Number' => '÷É ÐÅ×Φ, ÝÏ ÈÏÞÅÔÅ ×ÉÄÁÌÉÔÉ ÄÁÎÅ ÚÁÍÏ×ÌÅÎÎÑ?',
+  'Are you sure you want to delete Transaction' => '÷É ÐÅ×Φ, ÝÏ ÈÏÞÅÔÅ ×ÉÄÁÌÉÔÉ ÄÁÎÕ ÏÐÅÒÁæÀ?',
+  'Assemblies'                  => 'ëÏÍÐÌÅËÔÉ',
+  'Assemblies restocked!'       => 'ëÏÍÐÌÅËÔÉ ¦Î×ÅÎÔÁÒÉÚÏ×ÁΦ!',
+  'Assembly Number missing!'    => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ËÏÍÐÌÅËÔÕ!',
+  'Asset'                       => 'áËÔÉ×',
+  'Attachment'                  => 'äÏÄÁÔÏË',
+  'Audit Control'               => 'ëÏÎÔÒÏÌØ',
+  'Aug'                         => 'ÓÅÒÐÎÑ',
+  'August'                      => 'óÅÒÐÅÎØ',
+  'BOM'                         => 'BOM',
+  'Backup'                      => 'òÅÚÅÒ×ÎÁ ËÏЦÑ',
+  'Backup sent to'              => 'òÅÚÅÒ×ÎÁ ËÏЦѠÐÏÓÌÁÎÁ ÄÏ',
+  'Balance'                     => 'âÁÌÁÎÓ',
+  'Balance Sheet'               => 'âÁÌÁÎÓ',
+  'Bcc'                         => 'ðÒÉ×ÁÔÎÁ ËÏЦѠÄÏ',
+  'Bin'                         => 'Bin',
+  'Books are open'              => 'ëÎÉÇÁ ×¦ÄËÒÉÔÁ',
+  'Bought'                      => 'ëÕÐÌÅÎÏ',
+  'Business Number'             => 'â¦ÚÎÅÓ-ÎÏÍÅÒ',
+  'C'                           => 'ó',
+  'COGS'                        => 'COGS',
+  'Cannot delete account!'      => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÒÁÈÕÎÏË',
+  'Cannot delete customer!'     => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ Ë̦¤ÎÔÁ',
+  'Cannot delete default account!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÏÓÎÏ×ÎÉÊ ÒÁÈÕÎÏË!',
+  'Cannot delete invoice!'      => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÒÁÈÕÎÏË-ÆÁËÔÕÒÕ',
+  'Cannot delete item already invoiced!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÔÏ×ÁÒ, ÎÁ ÑËÉÊ ×ÖÅ ×ÉÐÉÓÁÎÁ ÒÁÈÕÎÏË-ÆÁËÔÕÒÁ!',
+  'Cannot delete item on order!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ Ò¦Þ ¦Ú ÚÁÍÏ×ÌÅÎÎÑ!',
+  'Cannot delete item which is part of an assembly!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÔÏ×ÁÒ, ÑËÉÊ ¤ ÞÁÓÔÉÎÏÀ ËÏÍÐÌÅËÔÕ!',
+  'Cannot delete item!'         => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÃÅÊ ÅÌÅÍÅÎÔ',
+  'Cannot delete order!'        => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÚÁÍÏ×ÌÅÎÎÑ!',
+  'Cannot delete transaction!'  => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÏÒÅ!',
+  'Cannot delete vendor!'       => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÐÏÓÔÁÞÁÌØÎÉËÁ!',
+  'Cannot have a value in both Debit and Credit!' => 'îÅ ÍÏÖÎÁ ÏÄÎÏÞÁÓÎÏ ÍÁÔÉ ÓÕÍÉ × äÅÂÉÔ¦ ¦ ëÒÅÄÉÔ¦',
+  'Cannot post a transaction without a value!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÏÐÅÒÁæÀ ÂÅÚ ×ÁÒÔÏÓÔ¦!',
+  'Cannot post invoice for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÒÁÈÕÎÏË-ÆÁËÔÕÒÕ ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Cannot post invoice!'        => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÒÁÈÕÎÏË-ÆÁËÔÕÒÕ!',
+  'Cannot post payment for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÐÌÁÔ¦Ö ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Cannot post payment!'        => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÐÌÁÔ¦Ö!',
+  'Cannot post transaction for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÏÐÅÒÁæÀ ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Cannot post transaction!'    => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÏÐÅÒÁæÀ!',
+  'Cannot process payment for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ÐÒÏ×ÅÓÔÉ ÐÌÁÔ¦Ö ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Cannot save account!'        => 'îÅ ÍÏÖÌÉ×Ï ÚÂÅÒÅÇÔÉ ÒÁÈÕÎÏË!',
+  'Cannot save order!'          => 'îÅ ÍÏÖÌÉ×Ï ÚÂÅÒÅÇÔÉ ÚÁÍÏ×ÌÅÎÎÑ!',
+  'Cannot save preferences!'    => 'îÅ ÍÏÖÌÉ×Ï ÚÂÅÒÅÇÔÉ ÎÁÓÔÒÏÊËÉ!',
+  'Cannot stock assemblies!'    => 'îÅ ÍÏÖÌÉ×Ï ¦Î×ÅÎÔÁÒÉÚÕ×ÁÔÉ ËÏÍÐÌÅËÔÉ!',
+  'Cash'                        => 'çÏÔ¦×ËÁ',
+  'Cash based'                  => 'çÏÔ¦×ËÏ×ÉÊ',
+  'Cc'                          => 'ëÏЦѠÄÏ',
+  'Change Admin Password'       => 'úͦÎÉÔÉ ÐÁÒÏÌØ áÄͦΦÓÔÒÁÔÏÒÁ',
+  'Change Password'             => 'úͦÎÉÔÉ ÐÁÒÏÌØ',
+  'Character Set'               => 'ëÏÄÉÒÏ×ËÁ',
+  'Chart of Accounts'           => 'ðÌÁΠòÁÈÕÎ˦×',
+  'Check'                       => 'þÅË',
+  'Check printed!'              => 'þÅË ÎÁÄÒÕËÏ×ÁÎÏ!',
+  'Check printing failed!'      => 'äÒÕË ÞÅËÕ ÎÅ ×ÄÁ×ÓÑ!',
+  'Cleared Balance'             => 'ë¦ÎÃÅ×Å óÁÌØÄÏ',
+  'Click on login name to edit!' => 'îÁÔÉÓΦÔØ ÎÁ ÎÁÚ×Õ ËÏÒÉÓÔÕ×ÁÞÁ, ÝÏ ÚÒÏÂÉÔÉ ÚͦÎÉ!',
+  'Close Books up to'           => 'úÁËÒÉÔÉ ëÎÉÇÉ ÄÏ',
+  'Closed'                      => 'úÁËÒÉÔÏ',
+  'Company'                     => 'ð¦ÄÐÒɤÍÓÔ×Ï',
+  'Compare to'                  => 'ðÏÒ¦×ÎÑÔÉ Ú',
+  'Confirm!'                    => 'ð¦ÄÔ×ÅÒĦÔØ!',
+  'Connect to'                  => 'ð¦ÄËÌÀÞÉÔÉÓØ ÄÏ',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÁ ÏÓÏÂÁ',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Copies'                      => 'ëÏЦÊ',
+  'Copy to COA'                 => 'óËÏЦÀ×ÁÔÉ ÄÏ ðÌÁÎÕ òÁÈÕÎ˦×',
+  'Create Chart of Accounts'    => 'óÔ×ÏÒÉÔÉ ðÌÁΠòÁÈÕÎ˦×',
+  'Create Dataset'              => 'óÔ×ÏÒÉÔÉ âÁÚÕ äÁÎÉÈ',
+  'Credit'                      => 'ëÒÅÄÉÔ',
+  'Credit Limit'                => 'ì¦Í¦Ô ËÒÅÄÉÔÕ',
+  'Curr'                        => '÷ÁÌÀÔÁ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Current'                     => 'ðÏÔÏÞÎÉÊ',
+  'Customer'                    => 'ë̦¤ÎÔ',
+  'Customer deleted!'           => 'ë̦¤ÎÔÁ ×ÉÄÁÌÅÎÏ!',
+  'Customer missing!'           => 'îÅ ×ËÁÚÁÎÉÊ Ë̦¤ÎÔ!',
+  'Customer not on file!'       => 'ë̦¤ÎÔÁ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Customer saved!'             => 'ë̦¤ÎÔÁ ÚÂÅÒÅÖÅÎÏ!',
+  'Customers'                   => 'ë̦¤ÎÔÉ',
+  'DBI not installed!'          => 'îÅ ×ÓÔÁÎÏ×ÌÅÎÉÊ ÄÒÁÊ×ÅÒ DBI!',
+  'Database'                    => 'âÁÚÁ äÁÎÉÈ',
+  'Database Administration'     => 'áÄͦΦÓÔÒÕ×ÁÎÎÑ ÂÁÚÉ ÄÁÎÉÈ',
+  'Database Driver not checked!' => 'îÅ ÚÁÚÎÁÞÅÎÉÊ ÄÒÁÊ×ÅÒ âÁÚÉ äÁÎÉÈ (Pg)!',
+  'Database Host'               => 'íÁÛÉÎÁ âÁÚÉ äÁÎÉÈ',
+  'Database User missing!'      => 'îÅ ×ËÁÚÁÎÉÊ ëÏÒÉÓÔÕ×ÁÞ âÁÚÉ äÁÎÉÈ!',
+  'Dataset'                     => 'âÁÚÁ äÁÎÉÈ',
+  'Dataset missing!'            => 'îÅ ×ËÁÚÁÎÁ âÁÚÁ äÁÎÉÈ!',
+  'Dataset updated!'            => 'âÁÚÁ äÁÎÉÈ ÐÏÎÏ×ÌÅÎÁ!',
+  'Date'                        => 'äÁÔÁ',
+  'Date Due'                    => 'úÁÐÌÁÔÉÔÉ ÄÏ',
+  'Date Format'                 => 'æÏÒÍÁÔ ÄÁÔÉ',
+  'Date Paid'                   => 'äÁÔÁ ÏÐÌÁÔÉ',
+  'Date missing!'               => 'îÅ ×ËÁÚÁÎÁ ÄÁÔÁ!',
+  'Debit'                       => 'äÅÂÉÔ',
+  'Debit and credit out of balance!' => 'äÅÂÉÔ ¦ ËÒÅÄÉÔ ÎÅ ÚÂÁÌÁÎÓÏ×ÁΦ!',
+  'Dec'                         => 'ÇÒÕÄÎÑ',
+  'December'                    => 'çÒÕÄÅÎØ',
+  'Decimalplaces'               => 'äÅÓÑÔÉÞΦ Í¦ÓÃÑ',
+  'Delete'                      => '÷ÉÄÁÌÉÔÉ',
+  'Delete Account'              => '÷ÉÄÁÌÉÔÉ ÒÁÈÕÎÏË',
+  'Delete Dataset'              => '÷ÉÄÁÌÉÔÉ âÁÚÕ äÁÎÉÈ',
+  'Delivery Date'               => 'äÁÔÁ ÄÏÓÔÁ×ËÉ',
+  'Department'                  => '',
+  'Deposit'                     => 'äÅÐÏÚÉÔ/÷ËÌÁÄ',
+  'Description'                 => 'ïÐÉÓ',
+  'Difference'                  => 'ò¦ÚÎÉÃÑ',
+  'Directory'                   => 'ëÁÔÁÌÏÇ',
+  'Discount'                    => 'óËÉÄËÁ',
+  'Done'                        => 'úÒÏÂÌÅÎÏ',
+  'Drawing'                     => 'íÁÌÀÎÏË',
+  'Driver'                      => 'äÒÁÊ×ÅÒ',
+  'Dropdown Limit'              => 'ïÂÍÅÖÅÎÎÑ ÌÉÓÔÏ×ÏÇÏ ÍÅÎÀ',
+  'Due'                         => 'äÏ',
+  'Due Date'                    => 'úÁÐÌÁÔÉÔÉ ÄÏ',
+  'Due Date missing!'           => 'îÅ ×ËÁÚÁÎÉÊ ÔÅÒͦΠÏÐÌÁÔÉ!',
+  'E-mail'                      => 'åÌ. ÐÏÛÔÁ',
+  'E-mail Statement to'         => 'ðÏÓÌÁÔÉ ÐÏ ÅÌ. ÐÏÛÔ¦ ÄÏ',
+  'E-mail address missing!'     => 'îÅ ×ËÁÚÁÎÁ ÁÄÒÅÓÁ ÅÌ. ÐÏÛÔÉ!',
+  'Edit'                        => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ',
+  'Edit Account'                => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ òÁÈÕÎÏË',
+  'Edit Accounts Payables Transaction' => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ðÒÏ×ÏÄËÕ ÷ÉÔÒÁÔ',
+  'Edit Accounts Receivables Transaction' => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ðÒÏ×ÏÄËÕ äÏÈÏĦ×',
+  'Edit Assembly'               => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ËÏÍÐÌÅËÔ',
+  'Edit Customer'               => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ë̦¤ÎÔÁ',
+  'Edit GIFI'                   => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ GIFI',
+  'Edit General Ledger Transaction' => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ïÐÅÒÁæÀ çÏÌÏ×Îϧ ëÎÉÇÉ',
+  'Edit Part'                   => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ôÏ×ÁÒ',
+  'Edit Preferences for'        => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ îÁÓÔÒÏÊËÉ',
+  'Edit Project'                => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ðÒÏÅËÔ',
+  'Edit Purchase Invoice'       => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ëÕЦ×ÅÌØÎÉÊ òÁÈÕÎÏË-ÆÁËÔÕÒÕ',
+  'Edit Purchase Order'         => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ëÕЦ×ÅÌØÎÅ úÁÍÏ×ÌÅÎÎÑ',
+  'Edit Sales Invoice'          => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ òÁÈÕÎÏË-ÆÁËÔÕÒÕ',
+  'Edit Sales Order'            => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ îÁËÌÁÄÎÕ ðÒÏÄÁÖÕ',
+  'Edit Service'                => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ÐÏÓÌÕÇÕ',
+  'Edit Template'               => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ûÁÂÌÏÎ',
+  'Edit User'                   => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ëÏÒÉÓÔÕ×ÁÞÁ',
+  'Edit Vendor'                 => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ðÏÓÔÁÞÁÌØÎÉËÁ',
+  'Employee'                    => 'ðÒÁæ×ÎÉË',
+  'Enforce transaction reversal for all dates' => 'úÁÓÔÁ×ÉÔÉ Ú×ÏÒÏÔÎÕ ÚͦÎÕ ÐÒÏ×ÏÄÏË ÄÌÑ ×ӦȠÄÁÔ',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => '÷×ÅĦÔØ ÄÏ 3 Ì¦ÔÅÒ ÒÏÚĦÌÅÎÉÈ Ä×ÏËÒÁÐËÁÍÉ (i.e CAD:USD:EUR) ÄÌÑ ÐÏÚÎÁÞÅÎÎѠͦÓÃÅ×ϧ ¦ ¦ÎÏÚÅÍÎÉÈ ÇÒÏÛÏ×ÉÈ ÏÄÉÎÉÃØ',
+  'Equity'                      => 'ëÁЦÔÁÌ',
+  'Exch'                        => 'ëÕÒÓ',
+  'Exchangerate'                => 'ëÕÒÓ ×ÁÌÀÔÉ',
+  'Exchangerate Difference'     => 'ò¦ÚÎÉÃÑ ëÕÒÓÕ ×ÁÌÀÔÉ',
+  'Exchangerate for payment missing!' => 'îÅ ×ËÁÚÁÎÉÊ ËÕÒÓ ×ÁÌÀÔÉ ÄÌÑ ÐÌÁÔÅÖÕ!',
+  'Exchangerate missing!'       => 'îÅ ×ËÁÚÁÎÉÊ ËÕÒÓ ×ÁÌÀÔÉ!',
+  'Existing Datasets'           => '¶ÓÎÕÀÞ¦ âÁÚÉ äÁÎÉÈ',
+  'Expense'                     => '÷ÉÄÁÔËÉ',
+  'Expense Account'             => 'òÁÈÕÎÏË ÷ÉÄÁÔ˦×',
+  'Expense/Asset'               => '÷ÉÄÁÔÏË/áËÔÉ×',
+  'Extended'                    => 'ðÒÏÄÏ×ÖÅÎÏ',
+  'Fax'                         => 'æÁÈ',
+  'Feb'                         => 'ÌÀÔÏÇÏ',
+  'February'                    => 'ìÀÔÉÊ',
+  'Foreign Exchange Gain'       => 'ðÒÉÂÕÔÏË Ú ïÂͦÎÕ ÷ÁÌÀÔÉ',
+  'Foreign Exchange Loss'       => '÷ÔÒÁÔÁ ÎÁ ïÂͦΦ ÷ÁÌÀÔÉ',
+  'From'                        => '÷¦Ä / Ú',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI ×ÉÄÁÌÅÎÏ!',
+  'GIFI missing!'               => 'îÅ ×ËÁÚÁÎÏ GIFI!',
+  'GIFI saved!'                 => 'GIFI ÚÂÅÒÅÖÅÎÏ!',
+  'GL Transaction'              => 'çë ïÐÅÒÁæÑ',
+  'General Ledger'              => 'çÏÌÏ×ÎÁ ëÎÉÇÁ',
+  'Goods & Services'            => 'ôÏ×ÁÒÉ ¦ ðÏÓÌÕÇÉ',
+  'HTML Templates'              => 'HTML ûÁÂÌÏÎÉ ',
+  'Heading'                     => 'òÏÚĦÌ',
+  'Host'                        => 'íÁÛÉÎÁ/Host',
+  'Hostname missing!'           => 'îÅ ×ËÁÚÁÎÁ ÎÁÚ×Á ÍÁÛÉÎÉ!',
+  'ID'                          => '¶ÄÅÎÔÉƦËÁæÊÎÉÊ ÎÏÍÅÒ',
+  'Image'                       => 'úÏÂÒÁÖÅÎÎÑ',
+  'In-line'                     => '÷ËÌÀÞÅÎÏ (In-line)',
+  'Include in Report'           => 'äÏÄÁÔÉ ÄÏ úצÔÕ',
+  'Include in drop-down menus'  => 'äÏÄÁÔÉ ÄÏ ÌÉÓÔÏ×ÉÈ ÍÅÎÀ',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'äÏÄÁÔÉ ÒÁÈÕÎÏË ÄÏ ÆÏÒÍ Ë̦¤ÎÔ¦×/ÐÏÓÔÁÞÁÌØÎÉ˦×, ÝÏ ÐÏÚÎÁÞÁÔÉ Ë̦¤ÎÔ¦×/ÐÏÓÔÁÞÁÌØÎÉ˦נڠÑËÉÈ ÓÔÑÇÕÀÔØÓÑ ÐÏÄÁÔËÉ?',
+  'Income'                      => 'ðÒÉÂÕÔÏË',
+  'Income Account'              => 'òÁÈÕÎÏË ðÒÉÂÕÔ˦×',
+  'Income Statement'            => 'úצԠÐÒÏ ÄÏÈÏÄÉ ¦ ×ÉÄÁÔËÉ',
+  'Incorrect Dataset version!'  => 'îÅצÒÎÁ ×ÅÒӦѠâÁÚÉ äÁÎÉÈ!',
+  'Incorrect Password!'         => 'îÅצÒÎÉÊ ðÁÒÏÌØ!',
+  'Individual Items'            => '¶ÎÄÉצÄÕÁÌØΦ þÁÓÔÉÎÉ',
+  'Inventory'                   => '¶Î×ÅÎÔÁÒ',
+  'Inventory Account'           => '¶Î×ÅÎÔÁÒÎÉÊ ÒÁÈÕÎÏË',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'ë¦ÌØ˦ÓÔØ × ¦Î×ÅÎÔÁÒ¦ ÐÏ×ÉÎÎÁ ÂÕÔÉ ÎÕÌØ, ÐÅÒ۠Φ֠ÍÏÖÎÁ ÐÏÚÎÁÞÉÔÉ ËÏÍÐÌÅËÔ ÚÁÓÔÁÒ¦ÌÉÍ!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'ë¦ÌØ˦ÓÔØ × ¦Î×ÅÎÔÁÒ¦ ÐÏ×ÉÎÎÁ ÂÕÔÉ ÎÕÌØ, ÐÅÒ۠Φ֠ÍÏÖÎÁ ÐÏÚÎÁÞÉÔÉ ÃÉÊ ÔÏ×ÁÒ ÚÁÓÔÁÒ¦ÌÉÍ!',
+  'Inventory quantity must be zero!' => 'ë¦ÌØ˦ÓÔØ × ¦Î×ÅÎÔÁÒ¦ ÐÏ×ÉÎÎÁ ÂÕÔÉ ÎÕÌØ!',
+  'Invoice'                     => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Invoice Date'                => 'äÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ',
+  'Invoice Date missing!'       => 'îÅ ×ËÁÚÁÎÁ ÄÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Invoice Number'              => 'îÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ',
+  'Invoice Number missing!'     => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Invoice deleted!'            => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ ×ÉÄÁÌÅÎÉÊ!',
+  'Invoice posted!'             => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ ×ÉÓÔÁ×ÌÅÎÉÊ!',
+  'Invoices'                    => 'òÁÈÕÎËÉ-ÆÁËÔÕÒÉ',
+  'Is this a summary account to record' => 'þɠÊЦÄÓÕÍËÏ×ÉÊ ÒÁÈÕÎÏË ÄÌÑ ÚÁÐÉÓÕ?',
+  'Item deleted!'               => 'ò¦Þ ×ÉÄÁÌÅÎÏ!',
+  'Item not on file!'           => 'òÅÞ¦ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Jan'                         => 'Ó¦ÞÎÑ',
+  'January'                     => 'Ó¦ÞÅÎØ',
+  'Jul'                         => 'ÌÉÐÎÑ',
+  'July'                        => 'ìÉÐÅÎØ',
+  'Jun'                         => 'ÞÅÒ×ÎÑ',
+  'June'                        => 'þÅÒ×ÅÎØ',
+  'LaTeX Templates'             => 'LaTeX ûÁÂÌÏÎÉ',
+  'Language'                    => 'íÏ×Á',
+  'Last Cost'                   => 'ëÕЦ×ÅÌØÎÁ ã¦ÎÁ',
+  'Last Invoice Number'         => 'îÏÍÅÒ ïÓÔÁÎÎØÏÇÏ òÁÈÕÎËÕ-æÁËÔÕÒÉ',
+  'Last Numbers & Default Accounts' => 'ïÓÔÁÎΦ îÏÍÅÒÉ ¦ ôÉÐÏצ òÁÈÕÎËÉ',
+  'Last Purchase Order Number'  => 'îÏÍÅÒ ÏÓÔÁÎÎØÏÇÏ úÁÍÏ×ÌÅÎÎÑ ÎÁ ðÏÓÔÁÞÕ',
+  'Last Sales Order Number'     => 'îÏÍÅÒ ÏÓÔÁÎÎØϧ ðÒÏÄÁÖÎϧ îÁËÌÁÄÎϧ',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'ñËÝÏ ×É ÎÅ ÂÁÖÁ¤ÔÅ ×ÓÔÁÎÏ×ÉÔɠצÄÄÁÌÅÎÉÊ Ú×ÑÚÏË, ÎÅ ÚÁÐÏ×ÎÀÊÔÅ ÐÏÌÑ ÍÁÛÉÎÉ ¦ ÐÏÒÔÕ.',
+  'Liability'                   => 'ðÁÓÓÉ×',
+  'Licensed to'                 => 'ì¦ÃÅÎÚ¦¤À ×ÏÌÏĦ¤:',
+  'Line Total'                  => 'úÁÇÁÌØÎÁ óÕÍÁ',
+  'Link'                        => 'ðÏÓÉÌÁÎÎÑ',
+  'Link Accounts'               => 'ðÏ×ÑÚÁÔÉ òÁÈÕÎËÉ',
+  'List Accounts'               => 'óÐÉÓÏË òÁÈÕÎ˦×',
+  'List GIFI'                   => 'óÐÉÓÏË GIFI',
+  'List Price'                  => 'ã¦ÎÁ',
+  'List Transactions'           => 'óÐÉÓÏË ðÒÏ×ÏÄÏË',
+  'Login'                       => 'ðÏÞÁÔÏË óÅÁÎÓÕ',
+  'Logout'                      => 'ë¦ÎÅÃØ óÅÁÎÓÕ',
+  'Make'                        => '÷ÉÒÏÂÎÉÃÔ×Ï',
+  'Mar'                         => 'ÂÅÒÅÚÎÑ',
+  'March'                       => 'âÅÒÅÚÅÎØ',
+  'May'                         => 'ÔÒÁ×ÎÑ',
+  'May '                        => 'ôÒÁ×ÅÎØ',
+  'Message'                     => 'ðÏצÄÏÍÌÅÎÎÑ',
+  'Microfiche'                  => 'í¦ËÒÏƦÛÁ',
+  'Model'                       => 'íÏÄÅÌØ',
+  'Multibyte Encoding'          => 'íÕÌØÔÉÂÉÔÎÅ ëÏÄÕ×ÁÎÎÑ',
+  'N/A'                         => 'îÅ óÔÏÓÕ¤ÔØÓÑ',
+  'Name'                        => '¶Í\'Ñ / îÁÚ×Á',
+  'Name missing!'               => 'îÅ ×ËÁÚÁÎÅ ¦Í\'Ñ (ÎÁÚ×Á)!',
+  'New Templates'               => 'îÏצ ûÁÂÌÏÎÉ',
+  'No'                          => 'î¦',
+  'No Database Drivers available!' => 'îÅÄÏÓÔÕÐÎÉÊ ÄÒÁÊ×ÅÒ âÁÚÉ äÁÎÉÈ!',
+  'No Dataset selected!'        => 'îÅ ÐÏÚÎÁÞÅÎÏ ×ÉÂÒÁÎÕ âÁÚÕ äÁÎÉÈ!',
+  'No email address for'        => 'îÅ ×ËÁÚÁÎÁ ÁÄÒÅÓÁ ÅÌ. ÐÏÛÔÉ ÄÌÑ',
+  'No.'                         => 'No.',
+  'Notes'                       => 'ðÒÉͦÔËÉ',
+  'Nothing applied!'            => 'î¦ÞÏÇÏ ÎÅ ÚÁÓÔÏÓÏ×ÁÎÏ!',
+  'Nothing selected!'           => 'î¦ÞÏÇÏ ÎÅ ×ÉÂÒÁÎÏ!',
+  'Nothing to delete!'          => 'îÅÍÁ ÝÏ ×ÉÄÁÌÉÔÉ!',
+  'Nov'                         => 'ÌÉÓÔÏÐÁÄÁ',
+  'November'                    => 'ìÉÓÔÏÐÁÄ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Number Format'               => 'æÏÒÍÁÔ þÉÓÌÁ',
+  'Number missing in Row'       => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ Õ ÒÑÄËÕ',
+  'O'                           => 'ï',
+  'Obsolete'                    => 'úÁÓÔÁÒ¦ÌÅ',
+  'Oct'                         => 'ÖÏ×ÔÎÑ',
+  'October'                     => 'öÏ×ÔÅÎØ',
+  'On Hand'                     => 'îÁ òÕËÁÈ',
+  'On Order'                    => 'îÁ úÁÍÏ×ÌÅÎΦ',
+  'Open'                        => '÷¦ÄËÒÉÔÏ',
+  'Oracle Database Administration' => 'áÄͦΦÓÔÒÁæѠâÁÚÉ äÁÎÉÈ Oracle',
+  'Order'                       => 'úÁÍÏ×ÌÅÎÎÑ',
+  'Order Date'                  => 'äÁÔÁ úÁÍÏ×ÌÅÎÎÑ',
+  'Order Date missing!'         => 'îÅ ×ËÁÚÁÎÁ äÁÔÁ úÁÍÏ×ÌÅÎÎÑ!',
+  'Order Entry'                 => '÷ÉÓÔÁ×ÌÅÎÎÑ úÁÍÏ×ÌÅÎÎÑ',
+  'Order Number'                => 'îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'Order Number missing!'       => 'îÅ ×ËÁÚÁÎÏ îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'Order deleted!'              => 'úÁÍÏ×ÌÅÎÎÑ ×ÉÄÁÌÅÎÏ!',
+  'Order saved!'                => 'úÁÍÏ×ÌÅÎÎÑ ÚÂÅÒÅÖÅÎÏ!',
+  'Ordered'                     => 'úÁÍÏ×ÌÅÎÏ',
+  'Orphaned'                    => '÷¦ÄÏËÒÅÍÌÅÎÉÊ/ïÓÉÒÏÔ¦ÌÉÊ',
+  'Out of balance!'             => 'îÅ ÚÂÁÌÁÎÓÏ×ÁÎÏ!',
+  'PDF'                         => 'PDF ÆÏÒÍÁÔ',
+  'Packing List'                => 'ðÁËÕ×ÁÌØÎÉÊ óÐÉÓÏË',
+  'Packing List Date missing!'  => 'îÅ ×ËÁÚÁÎÁ äÁÔÁ ðÁËÕ×ÁÌØÎÏÇÏ óÐÉÓÏËÕ',
+  'Packing List Number missing!' => 'îÅ ×ËÁÚÁÎÉÊ îÏÍÅÒ ðÁËÕ×ÁÌØÎÏÇÏ óÐÉÓÏËÕ',
+  'Paid'                        => 'úÁÐÌÁÞÅÎÏ',
+  'Paid in full'                => 'úÁÐÌÁÞÅÎÏ ×ÐÏ×Φ',
+  'Part'                        => 'ôÏ×ÁÒ',
+  'Part Number missing!'        => 'îÅ ×ËÁÚÁÎÏ îÏÍÅÒ ôÏ×ÁÒÕ!',
+  'Parts'                       => 'ÔÏ×ÁÒÉ',
+  'Parts Inventory'             => '¶Î×ÅÎÔÁÒ ôÏ×ÁÒ¦×',
+  'Password'                    => 'ðÁÒÏÌØ',
+  'Password changed!'           => 'ðÁÒÏÌØ ÚͦÎÅÎÏ!',
+  'Payables'                    => 'úÏÂÏ×ÑÚÁÎÎÑ (ÐÌÁÔ¦ÖΦ)',
+  'Payment'                     => 'ðÌÁÔ¦Ö',
+  'Payment date missing!'       => 'îÅ ×ËÁÚÁÎÏ ÄÁÔÕ ðÌÁÔÅÖÕ!',
+  'Payment posted!'             => 'ðÌÁÔ¦Ö ×ÉÓÔÁ×ÌÅÎÏ!',
+  'Payments'                    => 'ðÌÁÔÅÖ¦',
+  'Pg Database Administration'  => 'áÄͦΦÓÔÒÁæѠâÁÚÉ äÁÎÉÈ Pg',
+  'Phone'                       => 'ôÅÌ.',
+  'Port'                        => 'ðÏÒÔ',
+  'Port missing!'               => 'ðÏÒÔ ÎÅ ×ËÁÚÁÎÏ!',
+  'Post'                        => '÷ÉÓÔÁ×ÉÔÉ',
+  'Post as new'                 => '÷ÉÓÔÁ×ÉÔÉ ÑË ÎÏ×ÉÊ',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'îÁÓÔÒÏÊËÉ',
+  'Preferences saved!'          => 'îÁÓÔÒÏÊËÉ ÚÂÅÒÅÖÅÎÏ!',
+  'Price'                       => 'ã¦ÎÁ',
+  'Print'                       => 'îÁÄÒÕËÕ×ÁÔÉ',
+  'Printer'                     => 'ðÒÉÎÔÅÒ',
+  'Project'                     => 'ðÒÏÅËÔ',
+  'Project Number'              => '',
+  'Project Number missing!'     => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ÐÒÏÅËÔÕ!',
+  'Project deleted!'            => 'ðÒÏÅËÔ ×ÉÄÁÌÅÎÏ!',
+  'Project not on file!'        => 'ðÒÏÅËÔÕ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Project saved!'              => 'ðÒÏÅËÔ ÚÂÅÒÅÖÅÎÏ!',
+  'Projects'                    => 'ðÒÏÅËÔÉ',
+  'Purchase Invoice'            => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Purchase Order'              => 'ëÕЦ×ÅÌØÎÅ úÁÍÏ×ÌÅÎÎÑ',
+  'Purchase Orders'             => 'ëÕЦ×ÅÌØΦ úÁÍÏ×ÌÅÎÎÑ',
+  'Qty'                         => 'ë¦ÌØ˦ÓÔØ',
+  'ROP'                         => 'ROP',
+  'Rate'                        => 'òÏÚæÎËÁ',
+  'Recd'                        => 'ïÔÒÉÍÁÎÏ',
+  'Receipt'                     => 'ë×ÉÔÁÎæÑ',
+  'Receipt printed!'            => '',
+  'Receipt printing failed!'    => '',
+  'Receipts'                    => 'ë×ÉÔÁÎæ§',
+  'Receivables'                 => 'îÁÌÅÖÎÏÓÔ¦ (ÄÅÂÉÔÉ)',
+  'Reconciliation'              => 'õÚÇÏÄÖÅÎÎÑ',
+  'Record in'                   => '÷ÎÅÓÔÉ ×',
+  'Reference'                   => 'úÓÉÌËÁ',
+  'Reference missing!'          => 'îÅ ×ËÁÚÁÎÁ ÚÓÉÌËÁ!',
+  'Remaining'                   => 'úÁÌÉÛÉÌÏÓØ',
+  'Report for'                  => 'úצԠÄÌÑ',
+  'Reports'                     => 'úצÔÉ',
+  'Required by'                 => 'ôÅÒͦΠÄÏÓÔÁ×ËÉ',
+  'Retained Earnings'           => 'ðÒÉÂÕÔÏË (ÎÅÒÏÚÐÏĦÌÅÎÉÊ)',
+  'Sales'                       => 'úÂÕÔ',
+  'Sales Invoice'               => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Sales Order'                 => 'îÁËÌÁÄÎÁ ðÒÏÄÁÖÕ ',
+  'Sales Orders'                => 'îÁËÌÁÄΦ ðÒÏÄÁÖÕ',
+  'Save'                        => 'úÂÅÒÅÇÔÉ',
+  'Save as new'                 => 'úÂÅÒÅÇÔÉ ÑË ÎÏ×Å',
+  'Save to File'                => 'úÂÅÒÅÇÔÉ Õ æÁÊ̦',
+  'Screen'                      => 'åËÒÁÎ',
+  'Select a Dataset to delete and press "Continue"' => '÷ÉÂÅÒ¦ÔØ âÁÚÕ äÁÎÉÈ ÄÌÑ ×ÉÄÁÌÅÎÎÑ ¦ ÎÁÔÉÓΦÔØ "ðÒÏÄÏ×ÖÉÔÉ"',
+  'Select all'                  => '÷ÉÂÒÁÔÉ ×ÓÅ',
+  'Select from one of the items below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÕ ¦Ú ÎÁÓÔÕÐÎÉÈ ÒÅÞÅÊ',
+  'Select from one of the names below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÅ ¦Ú ÎÁÓÔÕÐÎÉÈ ¦ÍÅÎ/ÎÁÚ×',
+  'Select from one of the projects below' => '÷ÉÂÅÒ¦ÔØ ÏÄÉΠ¦Ú ÎÁÓÔÕÐÎÉÈ ÐÒÏÅËÔ¦×',
+  'Select postscript or PDF!'   => '÷ÉÂÅÒ¦ÔØ postscript ÁÂÏ PDF ÆÏÒÍÁÔ!',
+  'Sell Price'                  => '÷¦ÄÐÕÓËÎÁ ã¦ÎÁ',
+  'Send by E-Mail'              => '÷ÉÓÌÁÔÉ ÐÏ ÅÌ. ÐÏÛÔ¦',
+  'Sep'                         => '×ÅÒÅÓÎÑ',
+  'September'                   => '÷ÅÒÅÓÅÎØ',
+  'Service'                     => 'ðÏÓÌÕÇÁ',
+  'Service Items'               => 'ðÏÓÌÕÇÉ',
+  'Service Number missing!'     => 'îÏÍÅÒ ðÏÓÌÕÇÉ ÎÅ ×ËÁÚÁÎÏ',
+  'Services'                    => 'ðÏÓÌÕÇÉ',
+  'Setup Templates'             => 'îÁÌÁÛÔÕ×ÁÔÉ ûÁÂÌÏÎÉ',
+  'Ship'                        => 'ðÏÓÌÁÔÉ',
+  'Ship to'                     => 'ðÏÓÌÁÔÉ ÄÏ',
+  'Ship via'                    => 'ðÏÓÌÁÔÉ ÞÅÒÅÚ',
+  'Short'                       => 'óËÏÒÏÞÅÎÏ',
+  'Signature'                   => 'ð¦ÄÐÉÓ',
+  'Sold'                        => 'ðÒÏÄÁÎÏ',
+  'Source'                      => 'äÖÅÒÅÌÏ',
+  'Standard'                    => 'óÔÁÎÄÁÒÔΦ',
+  'Statement'                   => 'úצÔ',
+  'Statement Balance'           => 'âÁÌÁÎÓÏ×ÉÊ úצÔ',
+  'Statement sent to'           => 'úצԠÐÏÓÌÁÎÏ ÄÏ',
+  'Statements sent to printer!' => 'úצԠÐÏÓÌÁÎÏ ÄÏ ÐÒÉÎÔÅÒÁ!',
+  'Stock Assembly'              => '¶Î×ÅÎÔÁÒ ëÏÍÐÌÅËÔÕ',
+  'Stylesheet'                  => 'ïÆÏÒÍÌÅÎÎÎÑ',
+  'Subject'                     => 'ôÅÍÁ',
+  'Subtotal'                    => 'ð¦ÄÓÕÍÏË ÐÏ ÒÏÚĦÌÕ',
+  'System'                      => 'óÉÓÔÅÍÁ',
+  'Tax'                         => 'ðÏÄÁÔÏË',
+  'Tax Accounts'                => 'ðÏÄÁÔËÏצ òÁÈÕÎËÉ',
+  'Tax Included'                => 'ðÏÄÁÔÏË ×ËÌÀÞÅÎÏ',
+  'Tax collected'               => 'ú¦ÂÒÁÎÏ ÐÏÄÁÔ˦נ',
+  'Tax paid'                    => 'ðÏÄÁÔÏË ÚÁÐÌÁÞÅÎÏ',
+  'Taxable'                     => 'ïÐÏÄÁÔËÏ×Õ¤ÔØÓÑ',
+  'Template saved!'             => 'ûÁÂÌÏΠÚÂÅÒÅÖÅÎÏ!',
+  'Templates'                   => 'ûÁÂÌÏÎÉ',
+  'Terms: Net'                  => 'õÍÏ×É: úÁÐÌÁÔÉÔÉ',
+  'The following Datasets are not in use and can be deleted' => 'îÁÓÔÕÐΦ âÁÚÉ äÁÎÉÈ ÎÅ ×ÉËÏÒÉÓÔÏ×ÕÀÔØÓÑ ¦ ÍÏÖÕÔØ ÂÕÔÉ ×ÉÄÁÌÅΦ',
+  'The following Datasets need to be updated' => 'îÁÓÔÕÐΦ âÁÚÉ äÁÎÉÈ ÐÏ×ÉÎΦ ÂÕÔÉ ÐÏÎÏ×ÌÅΦ',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'ðÏÐÅÒÅÄÎÑ ÐÅÒÅצÒËÁ ¦ÓÎÕÀÞÉÈ ÄÖÅÒÅÌ. ðÏËÉ ÝϠΦÞÏÇÏ ÎÅ ÂÕÄÅ ÓÔ×ÏÒÅÎÏ ÁÂÏ ×ÉÄÁÌÅÎÏ!',
+  'To'                          => 'äÏ',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'ýÏ ÄÏÄÁÔÉ ËÏÒÉÓÔÕ×ÁÞÁ ÄÏ ÇÒÕÐÉ, ÔÒÅÂÁ ÐÏͦÎÑÔÉ ¦Í\'Ñ, login/××ÏÄÎÅ ¦ÍÑ ¦ ÚÂÅÒÅÇÔÉ. îÏ×ÉÊ ËÏÒÉÓÔÕ×ÁÞÁ ¦Ú ÏÄÎÁËÏ×ÉÍÉ ÐÁÒÁÍÅÔÒÁÍÉ ÂÕÄÅ ÚÂÅÒÅÖÅÎϠЦĠÎÏ×ÉÍ login/××ÏÄÎÉÍ ¦Í\'ÑÍ.',
+  'Top Level'                   => '÷ÅÒÈΦʠò¦×ÅÎØ',
+  'Total'                       => 'úÁÇÁÌØÎÁ óÕÍÁ',
+  'Transaction Date missing!'   => 'îÅ ×ËÁÚÁÎÁ ÄÁÔÁ ÏÐÅÒÁæ§',
+  'Transaction deleted!'        => 'ïÐÅÒÁæѠ×ÉÄÁÌÅÎÁ',
+  'Transaction posted!'         => 'ïÐÅÒÁæѠÚĦÊÓÎÅÎÁ',
+  'Transaction reversal enforced for all dates' => 'ðÒÉÚÎÁÞÅÎÏ ÒÅ×ÅÓÉ×ÎÕ ÚͦÎÕ ÏÐÅÒÁæʠÄÌÑ ×ӦȠÄÁÔ',
+  'Transaction reversal enforced up to' => ' ðÒÉÚÎÁÞÅÎÏ ÒÅ×ÅÓÉ×ÎÕ ÚͦÎÁ ÏÐÅÒÁæʠÁÖ ÄÏ',
+  'Transactions'                => 'ïÐÅÒÁæ§',
+  'Transactions exist, cannot delete customer!' => '¶ÓÎÕÀÔØ ÏÐÅÒÁæ§, ÎÅ ÍÏÖÎÁ ×ÉÄÁÌÉÔÉ Ë̦¤ÎÔÁ',
+  'Transactions exist, cannot delete vendor!' => '¶ÓÎÕÀÔØ ÏÐÅÒÁæ§, ÎÅ ÍÏÖÎÁ ×ÉÄÁÌÉÔÉ ÐÏÓÔÁÞÁÌØÎÉËÁ',
+  'Transactions exist; cannot delete account!' => '¶ÓÎÕÀÔØ ÏÐÅÒÁæ§, ÎÅ ÍÏÖÎÁ ×ÉÄÁÌÉÔÉ ÒÁÈÕÎÏË',
+  'Trial Balance'               => 'ðÒÏÂÎÉÊ âÁÌÁÎÓ',
+  'Unit'                        => 'ïÄÉÎÉÃÑ',
+  'Unit of measure'             => 'ïÄÉÎÉÃÑ ×ÉͦÒÕ',
+  'Update'                      => 'ðÏÎÏ×ÉÔÉ',
+  'Update Dataset'              => 'ðÏÎÏ×ÉÔÉ âÁÚÕ äÁÎÉÈ',
+  'Updated'                     => 'ðÏÎÏ×ÌÅÎÏ',
+  'Use Templates'               => '÷ÉËÏÒÉÓÔÏ×Õ×ÁÔÉ ûÁÂÌÏÎÉ',
+  'User'                        => 'ëÏÒÉÓÔÕ×ÁÞ',
+  'User deleted!'               => 'ëÏÒÉÓÔÕ×ÁÞ ÷ÉÄÁÌÅÎÉÊ',
+  'User saved!'                 => 'ëÏÒÉÓÔÕ×ÁÞ ÚÂÅÒÅÖÅÎÉÊ',
+  'Vendor'                      => 'ðÏÓÔÁÞÁÌØÎÉË',
+  'Vendor deleted!'             => 'ðÏÓÔÁÞÁÌØÎÉË ×ÉÄÁÌÅÎÉÊ',
+  'Vendor missing!'             => 'ðÏÓÔÁÞÁÌØÎÉË ÎÅ ¦ÓÎÕ¤',
+  'Vendor not on file!'         => 'ðÏÔÁÞÁÌØÎÉËÁ ÎÅÍÁ Õ ÓÐÉÓËÕ ',
+  'Vendor saved!'               => 'ðÏÓÔÁÞÁÌØÎÉËÁ ÚÂÅÒÅÖÅÎÏ',
+  'Vendors'                     => 'ðÏÓÔÁÞÁÌØÎÉËÉ',
+  'Version'                     => '÷ÅÒÓ¦Ñ',
+  'Weight'                      => '÷ÁÇÁ',
+  'Weight Unit'                 => 'ïÄÉÎÉÃÑ ÷ÁÇÉ',
+  'What type of item is this?'  => 'ñËÉÊ ÃÅ ×ÉÄ/ÔÉРÔÏ×ÁÒÕ',
+  'Year End'                    => 'ë¦ÎÅÃØ æ¦ÎÁÎÓÏ×ÏÇÏ òÏËÕ',
+  'Yes'                         => 'Tak',
+  'You are logged out!'         => '÷ÁÛ ÓÅÁÎÓ ÚÁ˦ÎÞÉ×ÓÑ!',
+  'You did not enter a name!'   => 'îÅ ××ÅÄÅÎÏ ¦Í\'Ñ/ÎÁÚ×Õ',
+  'You must enter a host and port for local and remote connections!' => 'íÕÓÉÔÅ ××ÅÓÔÉ ÎÁÚ×Õ ÍÁÛÉÎÉ ¦ ÐÏÒÔÁ ÄÌѠͦÓÃÅ×ÏÇÏ ¦ ×¦ÄÄÁÌÅÎÏÇÏ Ú×ÑÚËÕ!',
+  'as at'                       => 'ÑË ×',
+  'collected on sales'          => 'Ú¦ÂÒÁÎÏ ÐÒÉ ÐÒÏÄÁÖÕ',
+  'days'                        => 'ÄΦ×',
+  'does not exist'              => 'ÎÅ ¦ÓÎÕ¤',
+  'ea'                          => 'ÛÔ.',
+  'emailed to'                  => 'ÐÏÓÌÁÎÏ ÐÏ ÅÌ. ÐÏÛÔ¦ ÄÏ',
+  'for Period'                  => 'ÚÁ ðÅÒ¦ÏÄ',
+  'hr'                          => 'ÇÏÄ.',
+  'is already a member!'        => '×ÖÅ ¤ ÞÌÅÎÏÍ!',
+  'is not a member!'            => 'ÎÅ ¤ ÞÌÅÎÏÍ!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'ÚÁÍËÎÕÔÉÊ!',
+  'paid on purchases'           => 'ÚÁÐÌÁÞÅÎÏ ÎÁ ÐÏËÕÐËÉ',
+  'sent to printer'             => 'ÐÏÓÌÁÎÏ ÄÏ ÐÒÉÎÔÅÒÁ',
+  'successfully created!'       => 'ÕÓЦÛÎÏ ÓÔ×ÏÒÅÎÏ!',
+  'successfully deleted!'       => 'ÕÓЦÛÎÏ ×ÉÄÁÌÅÎÏ!',
+  'to'                          => 'ÄÏ',
+  'website'                     => '×ÅÂ-ÓÔÏÒ¦ÎËÁ',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/am b/sql-ledger/locale/ua/am
new file mode 100644 (file)
index 0000000..9064301
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => '÷ÉÔÒÁÔÉ',
+  'AR'                          => 'äÏÈÏÄÉ',
+  'Account'                     => 'òÁÈÕÎÏË',
+  'Account Number'              => 'îÏÍÅÒ òÁÈÕÎËÕ',
+  'Account Number missing!'     => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ÒÁÈÕÎËÕ!',
+  'Account Type'                => '÷ÉÄ ÒÁÈÕÎËÕ',
+  'Account Type missing!'       => 'îÅ ×ËÁÚÁÎÉÊ ×ÉÄ ÒÁÈÕÎËÕ!',
+  'Account deleted!'            => 'òÁÈÕÎÏË ×ÉÄÁÌÅÎÉÊ',
+  'Account saved!'              => 'òÁÈÕÎÏË ÚÂÅÒÅÖÅÎÏ',
+  'Add Account'                 => 'îÏ×ÉÊ ÒÁÈÕÎÏË',
+  'Add GIFI'                    => 'îÏ×ÉÊ GIFI',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'Asset'                       => 'áËÔÉ×',
+  'Audit Control'               => 'ëÏÎÔÒÏÌØ',
+  'Backup sent to'              => 'òÅÚÅÒ×ÎÁ ËÏЦѠÐÏÓÌÁÎÁ ÄÏ',
+  'Books are open'              => 'ëÎÉÇÁ ×¦ÄËÒÉÔÁ',
+  'Business Number'             => 'â¦ÚÎÅÓ-ÎÏÍÅÒ',
+  'COGS'                        => 'COGS',
+  'Cannot delete account!'      => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÒÁÈÕÎÏË',
+  'Cannot delete default account!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÏÓÎÏ×ÎÉÊ ÒÁÈÕÎÏË!',
+  'Cannot save account!'        => 'îÅ ÍÏÖÌÉ×Ï ÚÂÅÒÅÇÔÉ ÒÁÈÕÎÏË!',
+  'Cannot save preferences!'    => 'îÅ ÍÏÖÌÉ×Ï ÚÂÅÒÅÇÔÉ ÎÁÓÔÒÏÊËÉ!',
+  'Character Set'               => 'ëÏÄÉÒÏ×ËÁ',
+  'Chart of Accounts'           => 'ðÌÁΠòÁÈÕÎ˦×',
+  'Close Books up to'           => 'úÁËÒÉÔÉ ëÎÉÇÉ ÄÏ',
+  'Company'                     => 'ð¦ÄÐÒɤÍÓÔ×Ï',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Copy to COA'                 => 'óËÏЦÀ×ÁÔÉ ÄÏ ðÌÁÎÕ òÁÈÕÎ˦×',
+  'Credit'                      => 'ëÒÅÄÉÔ',
+  'Date Format'                 => 'æÏÒÍÁÔ ÄÁÔÉ',
+  'Debit'                       => 'äÅÂÉÔ',
+  'Delete'                      => '÷ÉÄÁÌÉÔÉ',
+  'Delete Account'              => '÷ÉÄÁÌÉÔÉ ÒÁÈÕÎÏË',
+  'Description'                 => 'ïÐÉÓ',
+  'Dropdown Limit'              => 'ïÂÍÅÖÅÎÎÑ ÌÉÓÔÏ×ÏÇÏ ÍÅÎÀ',
+  'E-mail'                      => 'åÌ. ÐÏÛÔÁ',
+  'Edit'                        => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ',
+  'Edit Account'                => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ òÁÈÕÎÏË',
+  'Edit GIFI'                   => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ GIFI',
+  'Edit Preferences for'        => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ îÁÓÔÒÏÊËÉ',
+  'Edit Template'               => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ûÁÂÌÏÎ',
+  'Enforce transaction reversal for all dates' => 'úÁÓÔÁ×ÉÔÉ Ú×ÏÒÏÔÎÕ ÚͦÎÕ ÐÒÏ×ÏÄÏË ÄÌÑ ×ӦȠÄÁÔ',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => '÷×ÅĦÔØ ÄÏ 3 Ì¦ÔÅÒ ÒÏÚĦÌÅÎÉÈ Ä×ÏËÒÁÐËÁÍÉ (i.e CAD:USD:EUR) ÄÌÑ ÐÏÚÎÁÞÅÎÎѠͦÓÃÅ×ϧ ¦ ¦ÎÏÚÅÍÎÉÈ ÇÒÏÛÏ×ÉÈ ÏÄÉÎÉÃØ',
+  'Equity'                      => 'ëÁЦÔÁÌ',
+  'Expense'                     => '÷ÉÄÁÔËÉ',
+  'Expense Account'             => 'òÁÈÕÎÏË ÷ÉÄÁÔ˦×',
+  'Expense/Asset'               => '÷ÉÄÁÔÏË/áËÔÉ×',
+  'Fax'                         => 'æÁÈ',
+  'Foreign Exchange Gain'       => 'ðÒÉÂÕÔÏË Ú ïÂͦÎÕ ÷ÁÌÀÔÉ',
+  'Foreign Exchange Loss'       => '÷ÔÒÁÔÁ ÎÁ ïÂͦΦ ÷ÁÌÀÔÉ',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI ×ÉÄÁÌÅÎÏ!',
+  'GIFI missing!'               => 'îÅ ×ËÁÚÁÎÏ GIFI!',
+  'GIFI saved!'                 => 'GIFI ÚÂÅÒÅÖÅÎÏ!',
+  'Heading'                     => 'òÏÚĦÌ',
+  'Include in drop-down menus'  => 'äÏÄÁÔÉ ÄÏ ÌÉÓÔÏ×ÉÈ ÍÅÎÀ',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'äÏÄÁÔÉ ÒÁÈÕÎÏË ÄÏ ÆÏÒÍ Ë̦¤ÎÔ¦×/ÐÏÓÔÁÞÁÌØÎÉ˦×, ÝÏ ÐÏÚÎÁÞÁÔÉ Ë̦¤ÎÔ¦×/ÐÏÓÔÁÞÁÌØÎÉ˦נڠÑËÉÈ ÓÔÑÇÕÀÔØÓÑ ÐÏÄÁÔËÉ?',
+  'Income'                      => 'ðÒÉÂÕÔÏË',
+  'Income Account'              => 'òÁÈÕÎÏË ðÒÉÂÕÔ˦×',
+  'Inventory'                   => '¶Î×ÅÎÔÁÒ',
+  'Inventory Account'           => '¶Î×ÅÎÔÁÒÎÉÊ ÒÁÈÕÎÏË',
+  'Is this a summary account to record' => 'þɠÊЦÄÓÕÍËÏ×ÉÊ ÒÁÈÕÎÏË ÄÌÑ ÚÁÐÉÓÕ?',
+  'Language'                    => 'íÏ×Á',
+  'Last Invoice Number'         => 'îÏÍÅÒ ïÓÔÁÎÎØÏÇÏ òÁÈÕÎËÕ-æÁËÔÕÒÉ',
+  'Last Numbers & Default Accounts' => 'ïÓÔÁÎΦ îÏÍÅÒÉ ¦ ôÉÐÏצ òÁÈÕÎËÉ',
+  'Last Purchase Order Number'  => 'îÏÍÅÒ ÏÓÔÁÎÎØÏÇÏ úÁÍÏ×ÌÅÎÎÑ ÎÁ ðÏÓÔÁÞÕ',
+  'Last Sales Order Number'     => 'îÏÍÅÒ ÏÓÔÁÎÎØϧ ðÒÏÄÁÖÎϧ îÁËÌÁÄÎϧ',
+  'Liability'                   => 'ðÁÓÓÉ×',
+  'Link'                        => 'ðÏÓÉÌÁÎÎÑ',
+  'Name'                        => '¶Í\'Ñ / îÁÚ×Á',
+  'No'                          => 'î¦',
+  'No email address for'        => 'îÅ ×ËÁÚÁÎÁ ÁÄÒÅÓÁ ÅÌ. ÐÏÛÔÉ ÄÌÑ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Number Format'               => 'æÏÒÍÁÔ þÉÓÌÁ',
+  'Parts Inventory'             => '¶Î×ÅÎÔÁÒ ôÏ×ÁÒ¦×',
+  'Password'                    => 'ðÁÒÏÌØ',
+  'Payables'                    => 'úÏÂÏ×ÑÚÁÎÎÑ (ÐÌÁÔ¦ÖΦ)',
+  'Payment'                     => 'ðÌÁÔ¦Ö',
+  'Phone'                       => 'ôÅÌ.',
+  'Preferences saved!'          => 'îÁÓÔÒÏÊËÉ ÚÂÅÒÅÖÅÎÏ!',
+  'Rate'                        => 'òÏÚæÎËÁ',
+  'Receivables'                 => 'îÁÌÅÖÎÏÓÔ¦ (ÄÅÂÉÔÉ)',
+  'Sales'                       => 'úÂÕÔ',
+  'Save'                        => 'úÂÅÒÅÇÔÉ',
+  'Service Items'               => 'ðÏÓÌÕÇÉ',
+  'Ship via'                    => 'ðÏÓÌÁÔÉ ÞÅÒÅÚ',
+  'Signature'                   => 'ð¦ÄÐÉÓ',
+  'Stylesheet'                  => 'ïÆÏÒÍÌÅÎÎÎÑ',
+  'Tax'                         => 'ðÏÄÁÔÏË',
+  'Tax Accounts'                => 'ðÏÄÁÔËÏצ òÁÈÕÎËÉ',
+  'Template saved!'             => 'ûÁÂÌÏΠÚÂÅÒÅÖÅÎÏ!',
+  'Transaction reversal enforced for all dates' => 'ðÒÉÚÎÁÞÅÎÏ ÒÅ×ÅÓÉ×ÎÕ ÚͦÎÕ ÏÐÅÒÁæʠÄÌÑ ×ӦȠÄÁÔ',
+  'Transaction reversal enforced up to' => ' ðÒÉÚÎÁÞÅÎÏ ÒÅ×ÅÓÉ×ÎÕ ÚͦÎÁ ÏÐÅÒÁæʠÁÖ ÄÏ',
+  'Transactions exist; cannot delete account!' => '¶ÓÎÕÀÔØ ÏÐÅÒÁæ§, ÎÅ ÍÏÖÎÁ ×ÉÄÁÌÉÔÉ ÒÁÈÕÎÏË',
+  'Weight Unit'                 => 'ïÄÉÎÉÃÑ ÷ÁÇÉ',
+  'Year End'                    => 'ë¦ÎÅÃØ æ¦ÎÁÎÓÏ×ÏÇÏ òÏËÕ',
+  'Yes'                         => 'Tak',
+  'does not exist'              => 'ÎÅ ¦ÓÎÕ¤',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'îÏ×ÉÊ_ÒÁÈÕÎÏË'               => 'add_account',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  'óËÏЦÀ×ÁÔÉ_ÄÏ_ðÌÁÎÕ_òÁÈÕÎ˦×' => 'copy_to_coa',
+  '÷ÉÄÁÌÉÔÉ'                    => 'delete',
+  '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ'               => 'edit',
+  '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ_òÁÈÕÎÏË'       => 'edit_account',
+  'úÂÅÒÅÇÔÉ'                    => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/ap b/sql-ledger/locale/ua/ap
new file mode 100644 (file)
index 0000000..a5ec52d
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'ïÐÅÒÁ槠÷ÉÔÒÁÔ',
+  'AP Transactions'             => 'ïÐÅÒÁ槠÷ÉÔÒÁÔ',
+  'Account'                     => 'òÁÈÕÎÏË',
+  'Add Accounts Payables Transaction' => 'îÏ×Á ÏÐÅÒÁæѠ×ÉÔÒÁÔ',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'Amount'                      => 'óÕÍÁ',
+  'Amount Due'                  => 'úÁÐÌÁÔÉÔÉ óÕÍÕ',
+  'Apr'                         => 'ËצÔÎÑ',
+  'April'                       => 'ëצÔÅÎØ',
+  'Are you sure you want to delete Transaction' => '÷É ÐÅ×Φ, ÝÏ ÈÏÞÅÔÅ ×ÉÄÁÌÉÔÉ ÄÁÎÕ ÏÐÅÒÁæÀ?',
+  'Aug'                         => 'ÓÅÒÐÎÑ',
+  'August'                      => 'óÅÒÐÅÎØ',
+  'Cannot delete transaction!'  => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÏÒÅ!',
+  'Cannot post payment for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÐÌÁÔ¦Ö ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Cannot post transaction for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÏÐÅÒÁæÀ ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Cannot post transaction!'    => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÏÐÅÒÁæÀ!',
+  'Closed'                      => 'úÁËÒÉÔÏ',
+  'Confirm!'                    => 'ð¦ÄÔ×ÅÒĦÔØ!',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Customer not on file!'       => 'ë̦¤ÎÔÁ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Date'                        => 'äÁÔÁ',
+  'Date Paid'                   => 'äÁÔÁ ÏÐÌÁÔÉ',
+  'Dec'                         => 'ÇÒÕÄÎÑ',
+  'December'                    => 'çÒÕÄÅÎØ',
+  'Delete'                      => '÷ÉÄÁÌÉÔÉ',
+  'Description'                 => 'ïÐÉÓ',
+  'Due Date'                    => 'úÁÐÌÁÔÉÔÉ ÄÏ',
+  'Due Date missing!'           => 'îÅ ×ËÁÚÁÎÉÊ ÔÅÒͦΠÏÐÌÁÔÉ!',
+  'Edit Accounts Payables Transaction' => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ðÒÏ×ÏÄËÕ ÷ÉÔÒÁÔ',
+  'Employee'                    => 'ðÒÁæ×ÎÉË',
+  'Exch'                        => 'ëÕÒÓ',
+  'Exchangerate'                => 'ëÕÒÓ ×ÁÌÀÔÉ',
+  'Exchangerate for payment missing!' => 'îÅ ×ËÁÚÁÎÉÊ ËÕÒÓ ×ÁÌÀÔÉ ÄÌÑ ÐÌÁÔÅÖÕ!',
+  'Exchangerate missing!'       => 'îÅ ×ËÁÚÁÎÉÊ ËÕÒÓ ×ÁÌÀÔÉ!',
+  'Feb'                         => 'ÌÀÔÏÇÏ',
+  'February'                    => 'ìÀÔÉÊ',
+  'From'                        => '÷¦Ä / Ú',
+  'ID'                          => '¶ÄÅÎÔÉƦËÁæÊÎÉÊ ÎÏÍÅÒ',
+  'Include in Report'           => 'äÏÄÁÔÉ ÄÏ úצÔÕ',
+  'Invoice'                     => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Invoice Date'                => 'äÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ',
+  'Invoice Date missing!'       => 'îÅ ×ËÁÚÁÎÁ ÄÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Invoice Number'              => 'îÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ',
+  'Invoice Number missing!'     => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Jan'                         => 'Ó¦ÞÎÑ',
+  'January'                     => 'Ó¦ÞÅÎØ',
+  'Jul'                         => 'ÌÉÐÎÑ',
+  'July'                        => 'ìÉÐÅÎØ',
+  'Jun'                         => 'ÞÅÒ×ÎÑ',
+  'June'                        => 'þÅÒ×ÅÎØ',
+  'Mar'                         => 'ÂÅÒÅÚÎÑ',
+  'March'                       => 'âÅÒÅÚÅÎØ',
+  'May'                         => 'ÔÒÁ×ÎÑ',
+  'May '                        => 'ôÒÁ×ÅÎØ',
+  'Notes'                       => 'ðÒÉͦÔËÉ',
+  'Nov'                         => 'ÌÉÓÔÏÐÁÄÁ',
+  'November'                    => 'ìÉÓÔÏÐÁÄ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Oct'                         => 'ÖÏ×ÔÎÑ',
+  'October'                     => 'öÏ×ÔÅÎØ',
+  'Open'                        => '÷¦ÄËÒÉÔÏ',
+  'Order'                       => 'úÁÍÏ×ÌÅÎÎÑ',
+  'Order Number'                => 'îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'Paid'                        => 'úÁÐÌÁÞÅÎÏ',
+  'Payment date missing!'       => 'îÅ ×ËÁÚÁÎÏ ÄÁÔÕ ðÌÁÔÅÖÕ!',
+  'Payments'                    => 'ðÌÁÔÅÖ¦',
+  'Post'                        => '÷ÉÓÔÁ×ÉÔÉ',
+  'Post as new'                 => '÷ÉÓÔÁ×ÉÔÉ ÑË ÎÏ×ÉÊ',
+  'Project'                     => 'ðÒÏÅËÔ',
+  'Project not on file!'        => 'ðÒÏÅËÔÕ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Purchase Invoice'            => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Select from one of the names below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÅ ¦Ú ÎÁÓÔÕÐÎÉÈ ¦ÍÅÎ/ÎÁÚ×',
+  'Select from one of the projects below' => '÷ÉÂÅÒ¦ÔØ ÏÄÉΠ¦Ú ÎÁÓÔÕÐÎÉÈ ÐÒÏÅËÔ¦×',
+  'Sep'                         => '×ÅÒÅÓÎÑ',
+  'September'                   => '÷ÅÒÅÓÅÎØ',
+  'Source'                      => 'äÖÅÒÅÌÏ',
+  'Subtotal'                    => 'ð¦ÄÓÕÍÏË ÐÏ ÒÏÚĦÌÕ',
+  'Tax'                         => 'ðÏÄÁÔÏË',
+  'Tax Included'                => 'ðÏÄÁÔÏË ×ËÌÀÞÅÎÏ',
+  'Total'                       => 'úÁÇÁÌØÎÁ óÕÍÁ',
+  'Transaction deleted!'        => 'ïÐÅÒÁæѠ×ÉÄÁÌÅÎÁ',
+  'Transaction posted!'         => 'ïÐÅÒÁæѠÚĦÊÓÎÅÎÁ',
+  'Update'                      => 'ðÏÎÏ×ÉÔÉ',
+  'Vendor'                      => 'ðÏÓÔÁÞÁÌØÎÉË',
+  'Vendor missing!'             => 'ðÏÓÔÁÞÁÌØÎÉË ÎÅ ¦ÓÎÕ¤',
+  'Vendor not on file!'         => 'ðÏÔÁÞÁÌØÎÉËÁ ÎÅÍÁ Õ ÓÐÉÓËÕ ',
+  'Yes'                         => 'Tak',
+  'to'                          => 'ÄÏ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ïÐÅÒÁæ§_÷ÉÔÒÁÔ'             => 'ap_transaction',
+  'îÏ×Á_ÏÐÅÒÁæÑ_×ÉÔÒÁÔ'        => 'add_accounts_payables_transaction',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  '÷ÉÄÁÌÉÔÉ'                    => 'delete',
+  '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ_ðÒÏ×ÏÄËÕ_÷ÉÔÒÁÔ' => 'edit_accounts_payables_transaction',
+  '÷ÉÓÔÁ×ÉÔÉ'                   => 'post',
+  '÷ÉÓÔÁ×ÉÔÉ_ÑË_ÎÏ×ÉÊ'          => 'post_as_new',
+  'òÁÈÕÎÏË_ÆÁËÔÕÒÁ'             => 'purchase_invoice',
+  'ðÏÎÏ×ÉÔÉ'                    => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/ar b/sql-ledger/locale/ua/ar
new file mode 100644 (file)
index 0000000..cbbc5b1
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'ïÐÅÒÁæѠäÏÈÏĦ×',
+  'AR Transactions'             => 'ïÐÅÒÁæѠäÏÈÏĦ×',
+  'Account'                     => 'òÁÈÕÎÏË',
+  'Add Accounts Receivables Transaction' => 'îÏ×Á ÏÐÅÒÁæѠÄÏÈÏĦ×',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'Amount'                      => 'óÕÍÁ',
+  'Amount Due'                  => 'úÁÐÌÁÔÉÔÉ óÕÍÕ',
+  'Apr'                         => 'ËצÔÎÑ',
+  'April'                       => 'ëצÔÅÎØ',
+  'Are you sure you want to delete Transaction' => '÷É ÐÅ×Φ, ÝÏ ÈÏÞÅÔÅ ×ÉÄÁÌÉÔÉ ÄÁÎÕ ÏÐÅÒÁæÀ?',
+  'Aug'                         => 'ÓÅÒÐÎÑ',
+  'August'                      => 'óÅÒÐÅÎØ',
+  'Cannot delete transaction!'  => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÏÒÅ!',
+  'Cannot post payment for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÐÌÁÔ¦Ö ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Cannot post transaction for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÏÐÅÒÁæÀ ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Cannot post transaction!'    => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÏÐÅÒÁæÀ!',
+  'Closed'                      => 'úÁËÒÉÔÏ',
+  'Confirm!'                    => 'ð¦ÄÔ×ÅÒĦÔØ!',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Credit Limit'                => 'ì¦Í¦Ô ËÒÅÄÉÔÕ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Customer'                    => 'ë̦¤ÎÔ',
+  'Customer missing!'           => 'îÅ ×ËÁÚÁÎÉÊ Ë̦¤ÎÔ!',
+  'Customer not on file!'       => 'ë̦¤ÎÔÁ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Date'                        => 'äÁÔÁ',
+  'Date Paid'                   => 'äÁÔÁ ÏÐÌÁÔÉ',
+  'Dec'                         => 'ÇÒÕÄÎÑ',
+  'December'                    => 'çÒÕÄÅÎØ',
+  'Delete'                      => '÷ÉÄÁÌÉÔÉ',
+  'Description'                 => 'ïÐÉÓ',
+  'Due Date'                    => 'úÁÐÌÁÔÉÔÉ ÄÏ',
+  'Due Date missing!'           => 'îÅ ×ËÁÚÁÎÉÊ ÔÅÒͦΠÏÐÌÁÔÉ!',
+  'Edit Accounts Receivables Transaction' => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ðÒÏ×ÏÄËÕ äÏÈÏĦ×',
+  'Employee'                    => 'ðÒÁæ×ÎÉË',
+  'Exch'                        => 'ëÕÒÓ',
+  'Exchangerate'                => 'ëÕÒÓ ×ÁÌÀÔÉ',
+  'Exchangerate for payment missing!' => 'îÅ ×ËÁÚÁÎÉÊ ËÕÒÓ ×ÁÌÀÔÉ ÄÌÑ ÐÌÁÔÅÖÕ!',
+  'Exchangerate missing!'       => 'îÅ ×ËÁÚÁÎÉÊ ËÕÒÓ ×ÁÌÀÔÉ!',
+  'Feb'                         => 'ÌÀÔÏÇÏ',
+  'February'                    => 'ìÀÔÉÊ',
+  'From'                        => '÷¦Ä / Ú',
+  'ID'                          => '¶ÄÅÎÔÉƦËÁæÊÎÉÊ ÎÏÍÅÒ',
+  'Include in Report'           => 'äÏÄÁÔÉ ÄÏ úצÔÕ',
+  'Invoice'                     => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Invoice Date'                => 'äÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ',
+  'Invoice Date missing!'       => 'îÅ ×ËÁÚÁÎÁ ÄÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Invoice Number'              => 'îÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ',
+  'Invoice Number missing!'     => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Jan'                         => 'Ó¦ÞÎÑ',
+  'January'                     => 'Ó¦ÞÅÎØ',
+  'Jul'                         => 'ÌÉÐÎÑ',
+  'July'                        => 'ìÉÐÅÎØ',
+  'Jun'                         => 'ÞÅÒ×ÎÑ',
+  'June'                        => 'þÅÒ×ÅÎØ',
+  'Mar'                         => 'ÂÅÒÅÚÎÑ',
+  'March'                       => 'âÅÒÅÚÅÎØ',
+  'May'                         => 'ÔÒÁ×ÎÑ',
+  'May '                        => 'ôÒÁ×ÅÎØ',
+  'Notes'                       => 'ðÒÉͦÔËÉ',
+  'Nov'                         => 'ÌÉÓÔÏÐÁÄÁ',
+  'November'                    => 'ìÉÓÔÏÐÁÄ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Oct'                         => 'ÖÏ×ÔÎÑ',
+  'October'                     => 'öÏ×ÔÅÎØ',
+  'Open'                        => '÷¦ÄËÒÉÔÏ',
+  'Order'                       => 'úÁÍÏ×ÌÅÎÎÑ',
+  'Order Number'                => 'îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'Paid'                        => 'úÁÐÌÁÞÅÎÏ',
+  'Payment date missing!'       => 'îÅ ×ËÁÚÁÎÏ ÄÁÔÕ ðÌÁÔÅÖÕ!',
+  'Payments'                    => 'ðÌÁÔÅÖ¦',
+  'Post'                        => '÷ÉÓÔÁ×ÉÔÉ',
+  'Post as new'                 => '÷ÉÓÔÁ×ÉÔÉ ÑË ÎÏ×ÉÊ',
+  'Project'                     => 'ðÒÏÅËÔ',
+  'Project not on file!'        => 'ðÒÏÅËÔÕ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Remaining'                   => 'úÁÌÉÛÉÌÏÓØ',
+  'Sales Invoice'               => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Select from one of the names below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÅ ¦Ú ÎÁÓÔÕÐÎÉÈ ¦ÍÅÎ/ÎÁÚ×',
+  'Select from one of the projects below' => '÷ÉÂÅÒ¦ÔØ ÏÄÉΠ¦Ú ÎÁÓÔÕÐÎÉÈ ÐÒÏÅËÔ¦×',
+  'Sep'                         => '×ÅÒÅÓÎÑ',
+  'September'                   => '÷ÅÒÅÓÅÎØ',
+  'Source'                      => 'äÖÅÒÅÌÏ',
+  'Subtotal'                    => 'ð¦ÄÓÕÍÏË ÐÏ ÒÏÚĦÌÕ',
+  'Tax'                         => 'ðÏÄÁÔÏË',
+  'Tax Included'                => 'ðÏÄÁÔÏË ×ËÌÀÞÅÎÏ',
+  'Total'                       => 'úÁÇÁÌØÎÁ óÕÍÁ',
+  'Transaction deleted!'        => 'ïÐÅÒÁæѠ×ÉÄÁÌÅÎÁ',
+  'Transaction posted!'         => 'ïÐÅÒÁæѠÚĦÊÓÎÅÎÁ',
+  'Update'                      => 'ðÏÎÏ×ÉÔÉ',
+  'Vendor not on file!'         => 'ðÏÔÁÞÁÌØÎÉËÁ ÎÅÍÁ Õ ÓÐÉÓËÕ ',
+  'Yes'                         => 'Tak',
+  'to'                          => 'ÄÏ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ïÐÅÒÁæÑ_äÏÈÏĦ×'            => 'ar_transaction',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  '÷ÉÄÁÌÉÔÉ'                    => 'delete',
+  '÷ÉÓÔÁ×ÉÔÉ'                   => 'post',
+  '÷ÉÓÔÁ×ÉÔÉ_ÑË_ÎÏ×ÉÊ'          => 'post_as_new',
+  'òÁÈÕÎÏË_ÆÁËÔÕÒÁ'             => 'sales_invoice',
+  'ðÏÎÏ×ÉÔÉ'                    => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/arap b/sql-ledger/locale/ua/arap
new file mode 100644 (file)
index 0000000..64f47c5
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'áÄÒÅÓÁ',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Customer not on file!'       => 'ë̦¤ÎÔÁ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Description'                 => 'ïÐÉÓ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Project not on file!'        => 'ðÒÏÅËÔÕ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Select from one of the names below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÅ ¦Ú ÎÁÓÔÕÐÎÉÈ ¦ÍÅÎ/ÎÁÚ×',
+  'Select from one of the projects below' => '÷ÉÂÅÒ¦ÔØ ÏÄÉΠ¦Ú ÎÁÓÔÕÐÎÉÈ ÐÒÏÅËÔ¦×',
+  'Vendor not on file!'         => 'ðÏÔÁÞÁÌØÎÉËÁ ÎÅÍÁ Õ ÓÐÉÓËÕ ',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/ca b/sql-ledger/locale/ua/ca
new file mode 100644 (file)
index 0000000..64f42dd
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'òÁÈÕÎÏË',
+  'Apr'                         => 'ËצÔÎÑ',
+  'April'                       => 'ëצÔÅÎØ',
+  'Aug'                         => 'ÓÅÒÐÎÑ',
+  'August'                      => 'óÅÒÐÅÎØ',
+  'Balance'                     => 'âÁÌÁÎÓ',
+  'Chart of Accounts'           => 'ðÌÁΠòÁÈÕÎ˦×',
+  'Credit'                      => 'ëÒÅÄÉÔ',
+  'Date'                        => 'äÁÔÁ',
+  'Debit'                       => 'äÅÂÉÔ',
+  'Dec'                         => 'ÇÒÕÄÎÑ',
+  'December'                    => 'çÒÕÄÅÎØ',
+  'Description'                 => 'ïÐÉÓ',
+  'Feb'                         => 'ÌÀÔÏÇÏ',
+  'February'                    => 'ìÀÔÉÊ',
+  'From'                        => '÷¦Ä / Ú',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'äÏÄÁÔÉ ÄÏ úצÔÕ',
+  'Jan'                         => 'Ó¦ÞÎÑ',
+  'January'                     => 'Ó¦ÞÅÎØ',
+  'Jul'                         => 'ÌÉÐÎÑ',
+  'July'                        => 'ìÉÐÅÎØ',
+  'Jun'                         => 'ÞÅÒ×ÎÑ',
+  'June'                        => 'þÅÒ×ÅÎØ',
+  'List Transactions'           => 'óÐÉÓÏË ðÒÏ×ÏÄÏË',
+  'Mar'                         => 'ÂÅÒÅÚÎÑ',
+  'March'                       => 'âÅÒÅÚÅÎØ',
+  'May'                         => 'ÔÒÁ×ÎÑ',
+  'May '                        => 'ôÒÁ×ÅÎØ',
+  'Nov'                         => 'ÌÉÓÔÏÐÁÄÁ',
+  'November'                    => 'ìÉÓÔÏÐÁÄ',
+  'Oct'                         => 'ÖÏ×ÔÎÑ',
+  'October'                     => 'öÏ×ÔÅÎØ',
+  'Reference'                   => 'úÓÉÌËÁ',
+  'Sep'                         => '×ÅÒÅÓÎÑ',
+  'September'                   => '÷ÅÒÅÓÅÎØ',
+  'Subtotal'                    => 'ð¦ÄÓÕÍÏË ÐÏ ÒÏÚĦÌÕ',
+  'to'                          => 'ÄÏ',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'óÐÉÓÏË_ðÒÏ×ÏÄÏË'             => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/cp b/sql-ledger/locale/ua/cp
new file mode 100644 (file)
index 0000000..0a74130
--- /dev/null
@@ -0,0 +1,77 @@
+$self{texts} = {
+  'Account'                     => 'òÁÈÕÎÏË',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'Amount'                      => 'óÕÍÁ',
+  'Amount does not equal applied!' => 'óÕÍÁ ÎÅ ÄÏÒ¦×ÎÀ¤ ÚÁÓÔÏÓÏ×ÁΦÊ!',
+  'Amount missing!'             => 'îÅ ×ËÁÚÁÎÁ ÓÕÍÁ!',
+  'Applied'                     => 'úÁÓÔÏÓÏ×ÁÎÏ',
+  'Cannot post payment!'        => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÐÌÁÔ¦Ö!',
+  'Cannot process payment for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ÐÒÏ×ÅÓÔÉ ÐÌÁÔ¦Ö ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Check'                       => 'þÅË',
+  'Check printed!'              => 'þÅË ÎÁÄÒÕËÏ×ÁÎÏ!',
+  'Check printing failed!'      => 'äÒÕË ÞÅËÕ ÎÅ ×ÄÁ×ÓÑ!',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Customer'                    => 'ë̦¤ÎÔ',
+  'Customer not on file!'       => 'ë̦¤ÎÔÁ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Date'                        => 'äÁÔÁ',
+  'Date missing!'               => 'îÅ ×ËÁÚÁÎÁ ÄÁÔÁ!',
+  'Description'                 => 'ïÐÉÓ',
+  'Due'                         => 'äÏ',
+  'Exchangerate'                => 'ëÕÒÓ ×ÁÌÀÔÉ',
+  'From'                        => '÷¦Ä / Ú',
+  'Invoice'                     => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Invoices'                    => 'òÁÈÕÎËÉ-ÆÁËÔÕÒÉ',
+  'Nothing applied!'            => 'î¦ÞÏÇÏ ÎÅ ÚÁÓÔÏÓÏ×ÁÎÏ!',
+  'Number'                      => 'îÏÍÅÒ',
+  'Paid in full'                => 'úÁÐÌÁÞÅÎÏ ×ÐÏ×Φ',
+  'Payment'                     => 'ðÌÁÔ¦Ö',
+  'Payment posted!'             => 'ðÌÁÔ¦Ö ×ÉÓÔÁ×ÌÅÎÏ!',
+  'Post'                        => '÷ÉÓÔÁ×ÉÔÉ',
+  'Print'                       => 'îÁÄÒÕËÕ×ÁÔÉ',
+  'Printer'                     => 'ðÒÉÎÔÅÒ',
+  'Project not on file!'        => 'ðÒÏÅËÔÕ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Receipt'                     => 'ë×ÉÔÁÎæÑ',
+  'Receipt printed!'            => 'Receipt printed!',
+  'Receipt printing failed!'    => 'Receipt printing failed!',
+  'Reference'                   => 'úÓÉÌËÁ',
+  'Screen'                      => 'åËÒÁÎ',
+  'Select from one of the names below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÅ ¦Ú ÎÁÓÔÕÐÎÉÈ ¦ÍÅÎ/ÎÁÚ×',
+  'Select from one of the projects below' => '÷ÉÂÅÒ¦ÔØ ÏÄÉΠ¦Ú ÎÁÓÔÕÐÎÉÈ ÐÒÏÅËÔ¦×',
+  'Update'                      => 'ðÏÎÏ×ÉÔÉ',
+  'Vendor'                      => 'ðÏÓÔÁÞÁÌØÎÉË',
+  'Vendor not on file!'         => 'ðÏÔÁÞÁÌØÎÉËÁ ÎÅÍÁ Õ ÓÐÉÓËÕ ',
+  'to'                          => 'ÄÏ',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  '÷ÉÓÔÁ×ÉÔÉ'                   => 'post',
+  'îÁÄÒÕËÕ×ÁÔÉ'                 => 'print',
+  'ðÏÎÏ×ÉÔÉ'                    => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/ct b/sql-ledger/locale/ua/ct
new file mode 100644 (file)
index 0000000..80db8df
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'îÏ×ÉÊ',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'All'                         => '÷Ó¦',
+  'Bcc'                         => 'ðÒÉ×ÁÔÎÁ ËÏЦѠÄÏ',
+  'Cannot delete customer!'     => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ Ë̦¤ÎÔÁ',
+  'Cannot delete vendor!'       => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÐÏÓÔÁÞÁÌØÎÉËÁ!',
+  'Cc'                          => 'ëÏЦѠÄÏ',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÁ ÏÓÏÂÁ',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Credit Limit'                => 'ì¦Í¦Ô ËÒÅÄÉÔÕ',
+  'Customer deleted!'           => 'ë̦¤ÎÔÁ ×ÉÄÁÌÅÎÏ!',
+  'Customer saved!'             => 'ë̦¤ÎÔÁ ÚÂÅÒÅÖÅÎÏ!',
+  'Customers'                   => 'ë̦¤ÎÔÉ',
+  'Delete'                      => '÷ÉÄÁÌÉÔÉ',
+  'Discount'                    => 'óËÉÄËÁ',
+  'E-mail'                      => 'åÌ. ÐÏÛÔÁ',
+  'Edit Customer'               => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ë̦¤ÎÔÁ',
+  'Edit Vendor'                 => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ðÏÓÔÁÞÁÌØÎÉËÁ',
+  'Fax'                         => 'æÁÈ',
+  'Include in Report'           => 'äÏÄÁÔÉ ÄÏ úצÔÕ',
+  'Invoice'                     => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Name'                        => '¶Í\'Ñ / îÁÚ×Á',
+  'Name missing!'               => 'îÅ ×ËÁÚÁÎÅ ¦Í\'Ñ (ÎÁÚ×Á)!',
+  'Notes'                       => 'ðÒÉͦÔËÉ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Order'                       => 'úÁÍÏ×ÌÅÎÎÑ',
+  'Orphaned'                    => '÷¦ÄÏËÒÅÍÌÅÎÉÊ/ïÓÉÒÏÔ¦ÌÉÊ',
+  'Phone'                       => 'ôÅÌ.',
+  'Save'                        => 'úÂÅÒÅÇÔÉ',
+  'Ship to'                     => 'ðÏÓÌÁÔÉ ÄÏ',
+  'Tax Included'                => 'ðÏÄÁÔÏË ×ËÌÀÞÅÎÏ',
+  'Taxable'                     => 'ïÐÏÄÁÔËÏ×Õ¤ÔØÓÑ',
+  'Terms: Net'                  => 'õÍÏ×É: úÁÐÌÁÔÉÔÉ',
+  'Transactions exist, cannot delete customer!' => '¶ÓÎÕÀÔØ ÏÐÅÒÁæ§, ÎÅ ÍÏÖÎÁ ×ÉÄÁÌÉÔÉ Ë̦¤ÎÔÁ',
+  'Transactions exist, cannot delete vendor!' => '¶ÓÎÕÀÔØ ÏÐÅÒÁæ§, ÎÅ ÍÏÖÎÁ ×ÉÄÁÌÉÔÉ ÐÏÓÔÁÞÁÌØÎÉËÁ',
+  'Vendor deleted!'             => 'ðÏÓÔÁÞÁÌØÎÉË ×ÉÄÁÌÅÎÉÊ',
+  'Vendor saved!'               => 'ðÏÓÔÁÞÁÌØÎÉËÁ ÚÂÅÒÅÖÅÎÏ',
+  'Vendors'                     => 'ðÏÓÔÁÞÁÌØÎÉËÉ',
+  'days'                        => 'ÄΦ×',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'îÏ×ÉÊ'                       => 'add',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  '÷ÉÄÁÌÉÔÉ'                    => 'delete',
+  'òÁÈÕÎÏË_ÆÁËÔÕÒÁ'             => 'invoice',
+  'úÁÍÏ×ÌÅÎÎÑ'                  => 'order',
+  'úÂÅÒÅÇÔÉ'                    => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/gl b/sql-ledger/locale/ua/gl
new file mode 100644 (file)
index 0000000..77e0736
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'ïÐÅÒÁ槠÷ÉÔÒÁÔ',
+  'AR Transaction'              => 'ïÐÅÒÁæѠäÏÈÏĦ×',
+  'Account'                     => 'òÁÈÕÎÏË',
+  'Add General Ledger Transaction' => 'îÏ×Á ÏÐÅÒÁæÑ',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'All'                         => '÷Ó¦',
+  'Apr'                         => 'ËצÔÎÑ',
+  'April'                       => 'ëצÔÅÎØ',
+  'Are you sure you want to delete Transaction' => '÷É ÐÅ×Φ, ÝÏ ÈÏÞÅÔÅ ×ÉÄÁÌÉÔÉ ÄÁÎÕ ÏÐÅÒÁæÀ?',
+  'Asset'                       => 'áËÔÉ×',
+  'Aug'                         => 'ÓÅÒÐÎÑ',
+  'August'                      => 'óÅÒÐÅÎØ',
+  'Balance'                     => 'âÁÌÁÎÓ',
+  'Cannot delete transaction!'  => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÏÒÅ!',
+  'Cannot have a value in both Debit and Credit!' => 'îÅ ÍÏÖÎÁ ÏÄÎÏÞÁÓÎÏ ÍÁÔÉ ÓÕÍÉ × äÅÂÉÔ¦ ¦ ëÒÅÄÉÔ¦',
+  'Cannot post a transaction without a value!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÏÐÅÒÁæÀ ÂÅÚ ×ÁÒÔÏÓÔ¦!',
+  'Cannot post transaction for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÏÐÅÒÁæÀ ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Confirm!'                    => 'ð¦ÄÔ×ÅÒĦÔØ!',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Credit'                      => 'ëÒÅÄÉÔ',
+  'Customer not on file!'       => 'ë̦¤ÎÔÁ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Date'                        => 'äÁÔÁ',
+  'Debit'                       => 'äÅÂÉÔ',
+  'Debit and credit out of balance!' => 'äÅÂÉÔ ¦ ËÒÅÄÉÔ ÎÅ ÚÂÁÌÁÎÓÏ×ÁΦ!',
+  'Dec'                         => 'ÇÒÕÄÎÑ',
+  'December'                    => 'çÒÕÄÅÎØ',
+  'Delete'                      => '÷ÉÄÁÌÉÔÉ',
+  'Description'                 => 'ïÐÉÓ',
+  'Edit General Ledger Transaction' => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ïÐÅÒÁæÀ çÏÌÏ×Îϧ ëÎÉÇÉ',
+  'Equity'                      => 'ëÁЦÔÁÌ',
+  'Expense'                     => '÷ÉÄÁÔËÉ',
+  'Feb'                         => 'ÌÀÔÏÇÏ',
+  'February'                    => 'ìÀÔÉÊ',
+  'From'                        => '÷¦Ä / Ú',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'çë ïÐÅÒÁæÑ',
+  'General Ledger'              => 'çÏÌÏ×ÎÁ ëÎÉÇÁ',
+  'ID'                          => '¶ÄÅÎÔÉƦËÁæÊÎÉÊ ÎÏÍÅÒ',
+  'Include in Report'           => 'äÏÄÁÔÉ ÄÏ úצÔÕ',
+  'Income'                      => 'ðÒÉÂÕÔÏË',
+  'Jan'                         => 'Ó¦ÞÎÑ',
+  'January'                     => 'Ó¦ÞÅÎØ',
+  'Jul'                         => 'ÌÉÐÎÑ',
+  'July'                        => 'ìÉÐÅÎØ',
+  'Jun'                         => 'ÞÅÒ×ÎÑ',
+  'June'                        => 'þÅÒ×ÅÎØ',
+  'Liability'                   => 'ðÁÓÓÉ×',
+  'Mar'                         => 'ÂÅÒÅÚÎÑ',
+  'March'                       => 'âÅÒÅÚÅÎØ',
+  'May'                         => 'ÔÒÁ×ÎÑ',
+  'May '                        => 'ôÒÁ×ÅÎØ',
+  'Notes'                       => 'ðÒÉͦÔËÉ',
+  'Nov'                         => 'ÌÉÓÔÏÐÁÄÁ',
+  'November'                    => 'ìÉÓÔÏÐÁÄ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Oct'                         => 'ÖÏ×ÔÎÑ',
+  'October'                     => 'öÏ×ÔÅÎØ',
+  'Post'                        => '÷ÉÓÔÁ×ÉÔÉ',
+  'Post as new'                 => '÷ÉÓÔÁ×ÉÔÉ ÑË ÎÏ×ÉÊ',
+  'Project'                     => 'ðÒÏÅËÔ',
+  'Project not on file!'        => 'ðÒÏÅËÔÕ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Purchase Invoice'            => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Reference'                   => 'úÓÉÌËÁ',
+  'Reference missing!'          => 'îÅ ×ËÁÚÁÎÁ ÚÓÉÌËÁ!',
+  'Reports'                     => 'úצÔÉ',
+  'Sales Invoice'               => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Select from one of the names below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÅ ¦Ú ÎÁÓÔÕÐÎÉÈ ¦ÍÅÎ/ÎÁÚ×',
+  'Select from one of the projects below' => '÷ÉÂÅÒ¦ÔØ ÏÄÉΠ¦Ú ÎÁÓÔÕÐÎÉÈ ÐÒÏÅËÔ¦×',
+  'Sep'                         => '×ÅÒÅÓÎÑ',
+  'September'                   => '÷ÅÒÅÓÅÎØ',
+  'Source'                      => 'äÖÅÒÅÌÏ',
+  'Subtotal'                    => 'ð¦ÄÓÕÍÏË ÐÏ ÒÏÚĦÌÕ',
+  'Transaction Date missing!'   => 'îÅ ×ËÁÚÁÎÁ ÄÁÔÁ ÏÐÅÒÁæ§',
+  'Transaction deleted!'        => 'ïÐÅÒÁæѠ×ÉÄÁÌÅÎÁ',
+  'Transaction posted!'         => 'ïÐÅÒÁæѠÚĦÊÓÎÅÎÁ',
+  'Update'                      => 'ðÏÎÏ×ÉÔÉ',
+  'Vendor not on file!'         => 'ðÏÔÁÞÁÌØÎÉËÁ ÎÅÍÁ Õ ÓÐÉÓËÕ ',
+  'Yes'                         => 'Tak',
+  'to'                          => 'ÄÏ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'ïÐÅÒÁæ§_÷ÉÔÒÁÔ'             => 'ap_transaction',
+  'ïÐÅÒÁæÑ_äÏÈÏĦ×'            => 'ar_transaction',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  '÷ÉÄÁÌÉÔÉ'                    => 'delete',
+  'çë_ïÐÅÒÁæÑ'                 => 'gl_transaction',
+  '÷ÉÓÔÁ×ÉÔÉ'                   => 'post',
+  '÷ÉÓÔÁ×ÉÔÉ_ÑË_ÎÏ×ÉÊ'          => 'post_as_new',
+  'òÁÈÕÎÏË_ÆÁËÔÕÒÁ'             => 'purchase_invoice',
+  'òÁÈÕÎÏË_ÆÁËÔÕÒÁ'             => 'sales_invoice',
+  'ðÏÎÏ×ÉÔÉ'                    => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/ic b/sql-ledger/locale/ua/ic
new file mode 100644 (file)
index 0000000..9a32568
--- /dev/null
@@ -0,0 +1,206 @@
+$self{texts} = {
+  'Active'                      => 'áËÔÉ×ÎÉÊ',
+  'Add'                         => 'îÏ×ÉÊ',
+  'Add Assembly'                => 'îÏ×ÉÊ ËÏÍÐÌÅËÔ',
+  'Add Part'                    => 'îÏ×ÉÊ ôÏ×ÁÒ',
+  'Add Purchase Order'          => 'îÏ×Å ÚÁÍÏ×ÌÅÎÎÑ ÎÁ ËÕЦ×ÌÀ',
+  'Add Sales Order'             => 'îÏ×Å ÚÁÍÏ×ÌÅÎÎÑ ÎÁ ÐÒÏÄÁÖ',
+  'Add Service'                 => 'îÏ×Á ÐÏÓÌÕÇÁ',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'Apr'                         => 'ËצÔÎÑ',
+  'April'                       => 'ëצÔÅÎØ',
+  'Assemblies'                  => 'ëÏÍÐÌÅËÔÉ',
+  'Assemblies restocked!'       => 'ëÏÍÐÌÅËÔÉ ¦Î×ÅÎÔÁÒÉÚÏ×ÁΦ!',
+  'Assembly Number missing!'    => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ËÏÍÐÌÅËÔÕ!',
+  'Attachment'                  => 'äÏÄÁÔÏË',
+  'Aug'                         => 'ÓÅÒÐÎÑ',
+  'August'                      => 'óÅÒÐÅÎØ',
+  'BOM'                         => 'BOM',
+  'Bcc'                         => 'ðÒÉ×ÁÔÎÁ ËÏЦѠÄÏ',
+  'Bin'                         => 'Bin',
+  'Bought'                      => 'ëÕÐÌÅÎÏ',
+  'COGS'                        => 'COGS',
+  'Cannot delete item already invoiced!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÔÏ×ÁÒ, ÎÁ ÑËÉÊ ×ÖÅ ×ÉÐÉÓÁÎÁ ÒÁÈÕÎÏË-ÆÁËÔÕÒÁ!',
+  'Cannot delete item on order!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ Ò¦Þ ¦Ú ÚÁÍÏ×ÌÅÎÎÑ!',
+  'Cannot delete item which is part of an assembly!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÔÏ×ÁÒ, ÑËÉÊ ¤ ÞÁÓÔÉÎÏÀ ËÏÍÐÌÅËÔÕ!',
+  'Cannot delete item!'         => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÃÅÊ ÅÌÅÍÅÎÔ',
+  'Cannot stock assemblies!'    => 'îÅ ÍÏÖÌÉ×Ï ¦Î×ÅÎÔÁÒÉÚÕ×ÁÔÉ ËÏÍÐÌÅËÔÉ!',
+  'Cc'                          => 'ëÏЦѠÄÏ',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÁ ÏÓÏÂÁ',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Copies'                      => 'ëÏЦÊ',
+  'Dec'                         => 'ÇÒÕÄÎÑ',
+  'December'                    => 'çÒÕÄÅÎØ',
+  'Delete'                      => '÷ÉÄÁÌÉÔÉ',
+  'Delivery Date'               => 'äÁÔÁ ÄÏÓÔÁ×ËÉ',
+  'Description'                 => 'ïÐÉÓ',
+  'Drawing'                     => 'íÁÌÀÎÏË',
+  'E-mail'                      => 'åÌ. ÐÏÛÔÁ',
+  'E-mail address missing!'     => 'îÅ ×ËÁÚÁÎÁ ÁÄÒÅÓÁ ÅÌ. ÐÏÛÔÉ!',
+  'Edit Assembly'               => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ËÏÍÐÌÅËÔ',
+  'Edit Part'                   => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ôÏ×ÁÒ',
+  'Edit Service'                => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ÐÏÓÌÕÇÕ',
+  'Expense'                     => '÷ÉÄÁÔËÉ',
+  'Extended'                    => 'ðÒÏÄÏ×ÖÅÎÏ',
+  'Fax'                         => 'æÁÈ',
+  'Feb'                         => 'ÌÀÔÏÇÏ',
+  'February'                    => 'ìÀÔÉÊ',
+  'From'                        => '÷¦Ä / Ú',
+  'Image'                       => 'úÏÂÒÁÖÅÎÎÑ',
+  'In-line'                     => '÷ËÌÀÞÅÎÏ (In-line)',
+  'Include in Report'           => 'äÏÄÁÔÉ ÄÏ úצÔÕ',
+  'Income'                      => 'ðÒÉÂÕÔÏË',
+  'Individual Items'            => '¶ÎÄÉצÄÕÁÌØΦ þÁÓÔÉÎÉ',
+  'Inventory'                   => '¶Î×ÅÎÔÁÒ',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'ë¦ÌØ˦ÓÔØ × ¦Î×ÅÎÔÁÒ¦ ÐÏ×ÉÎÎÁ ÂÕÔÉ ÎÕÌØ, ÐÅÒ۠Φ֠ÍÏÖÎÁ ÐÏÚÎÁÞÉÔÉ ËÏÍÐÌÅËÔ ÚÁÓÔÁÒ¦ÌÉÍ!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'ë¦ÌØ˦ÓÔØ × ¦Î×ÅÎÔÁÒ¦ ÐÏ×ÉÎÎÁ ÂÕÔÉ ÎÕÌØ, ÐÅÒ۠Φ֠ÍÏÖÎÁ ÐÏÚÎÁÞÉÔÉ ÃÉÊ ÔÏ×ÁÒ ÚÁÓÔÁÒ¦ÌÉÍ!',
+  'Inventory quantity must be zero!' => 'ë¦ÌØ˦ÓÔØ × ¦Î×ÅÎÔÁÒ¦ ÐÏ×ÉÎÎÁ ÂÕÔÉ ÎÕÌØ!',
+  'Invoice'                     => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Invoice Date missing!'       => 'îÅ ×ËÁÚÁÎÁ ÄÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Invoice Number'              => 'îÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ',
+  'Invoice Number missing!'     => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Item deleted!'               => 'ò¦Þ ×ÉÄÁÌÅÎÏ!',
+  'Item not on file!'           => 'òÅÞ¦ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Jan'                         => 'Ó¦ÞÎÑ',
+  'January'                     => 'Ó¦ÞÅÎØ',
+  'Jul'                         => 'ÌÉÐÎÑ',
+  'July'                        => 'ìÉÐÅÎØ',
+  'Jun'                         => 'ÞÅÒ×ÎÑ',
+  'June'                        => 'þÅÒ×ÅÎØ',
+  'Last Cost'                   => 'ëÕЦ×ÅÌØÎÁ ã¦ÎÁ',
+  'Line Total'                  => 'úÁÇÁÌØÎÁ óÕÍÁ',
+  'Link Accounts'               => 'ðÏ×ÑÚÁÔÉ òÁÈÕÎËÉ',
+  'List Price'                  => 'ã¦ÎÁ',
+  'Make'                        => '÷ÉÒÏÂÎÉÃÔ×Ï',
+  'Mar'                         => 'ÂÅÒÅÚÎÑ',
+  'March'                       => 'âÅÒÅÚÅÎØ',
+  'May'                         => 'ÔÒÁ×ÎÑ',
+  'May '                        => 'ôÒÁ×ÅÎØ',
+  'Message'                     => 'ðÏצÄÏÍÌÅÎÎÑ',
+  'Microfiche'                  => 'í¦ËÒÏƦÛÁ',
+  'Model'                       => 'íÏÄÅÌØ',
+  'Name'                        => '¶Í\'Ñ / îÁÚ×Á',
+  'No.'                         => 'No.',
+  'Notes'                       => 'ðÒÉͦÔËÉ',
+  'Nov'                         => 'ÌÉÓÔÏÐÁÄÁ',
+  'November'                    => 'ìÉÓÔÏÐÁÄ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Number missing in Row'       => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ Õ ÒÑÄËÕ',
+  'Obsolete'                    => 'úÁÓÔÁÒ¦ÌÅ',
+  'Oct'                         => 'ÖÏ×ÔÎÑ',
+  'October'                     => 'öÏ×ÔÅÎØ',
+  'On Hand'                     => 'îÁ òÕËÁÈ',
+  'On Order'                    => 'îÁ úÁÍÏ×ÌÅÎΦ',
+  'Order'                       => 'úÁÍÏ×ÌÅÎÎÑ',
+  'Order Date missing!'         => 'îÅ ×ËÁÚÁÎÁ äÁÔÁ úÁÍÏ×ÌÅÎÎÑ!',
+  'Order Number'                => 'îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'Order Number missing!'       => 'îÅ ×ËÁÚÁÎÏ îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'Ordered'                     => 'úÁÍÏ×ÌÅÎÏ',
+  'Orphaned'                    => '÷¦ÄÏËÒÅÍÌÅÎÉÊ/ïÓÉÒÏÔ¦ÌÉÊ',
+  'PDF'                         => 'PDF ÆÏÒÍÁÔ',
+  'Packing List'                => 'ðÁËÕ×ÁÌØÎÉÊ óÐÉÓÏË',
+  'Packing List Date missing!'  => 'îÅ ×ËÁÚÁÎÁ äÁÔÁ ðÁËÕ×ÁÌØÎÏÇÏ óÐÉÓÏËÕ',
+  'Packing List Number missing!' => 'îÅ ×ËÁÚÁÎÉÊ îÏÍÅÒ ðÁËÕ×ÁÌØÎÏÇÏ óÐÉÓÏËÕ',
+  'Part'                        => 'ôÏ×ÁÒ',
+  'Part Number missing!'        => 'îÅ ×ËÁÚÁÎÏ îÏÍÅÒ ôÏ×ÁÒÕ!',
+  'Parts'                       => 'ÔÏ×ÁÒÉ',
+  'Phone'                       => 'ôÅÌ.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'ã¦ÎÁ',
+  'Printer'                     => 'ðÒÉÎÔÅÒ',
+  'Project'                     => 'ðÒÏÅËÔ',
+  'Purchase Order'              => 'ëÕЦ×ÅÌØÎÅ úÁÍÏ×ÌÅÎÎÑ',
+  'Qty'                         => 'ë¦ÌØ˦ÓÔØ',
+  'ROP'                         => 'ROP',
+  'Recd'                        => 'ïÔÒÉÍÁÎÏ',
+  'Required by'                 => 'ôÅÒͦΠÄÏÓÔÁ×ËÉ',
+  'Sales'                       => 'úÂÕÔ',
+  'Sales Order'                 => 'îÁËÌÁÄÎÁ ðÒÏÄÁÖÕ ',
+  'Save'                        => 'úÂÅÒÅÇÔÉ',
+  'Screen'                      => 'åËÒÁÎ',
+  'Select from one of the items below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÕ ¦Ú ÎÁÓÔÕÐÎÉÈ ÒÅÞÅÊ',
+  'Select postscript or PDF!'   => '÷ÉÂÅÒ¦ÔØ postscript ÁÂÏ PDF ÆÏÒÍÁÔ!',
+  'Sell Price'                  => '÷¦ÄÐÕÓËÎÁ ã¦ÎÁ',
+  'Sep'                         => '×ÅÒÅÓÎÑ',
+  'September'                   => '÷ÅÒÅÓÅÎØ',
+  'Service'                     => 'ðÏÓÌÕÇÁ',
+  'Service Number missing!'     => 'îÏÍÅÒ ðÏÓÌÕÇÉ ÎÅ ×ËÁÚÁÎÏ',
+  'Services'                    => 'ðÏÓÌÕÇÉ',
+  'Ship'                        => 'ðÏÓÌÁÔÉ',
+  'Ship to'                     => 'ðÏÓÌÁÔÉ ÄÏ',
+  'Short'                       => 'óËÏÒÏÞÅÎÏ',
+  'Sold'                        => 'ðÒÏÄÁÎÏ',
+  'Stock Assembly'              => '¶Î×ÅÎÔÁÒ ëÏÍÐÌÅËÔÕ',
+  'Subject'                     => 'ôÅÍÁ',
+  'Subtotal'                    => 'ð¦ÄÓÕÍÏË ÐÏ ÒÏÚĦÌÕ',
+  'Tax'                         => 'ðÏÄÁÔÏË',
+  'To'                          => 'äÏ',
+  'Top Level'                   => '÷ÅÒÈΦʠò¦×ÅÎØ',
+  'Total'                       => 'úÁÇÁÌØÎÁ óÕÍÁ',
+  'Unit'                        => 'ïÄÉÎÉÃÑ',
+  'Unit of measure'             => 'ïÄÉÎÉÃÑ ×ÉͦÒÕ',
+  'Update'                      => 'ðÏÎÏ×ÉÔÉ',
+  'Updated'                     => 'ðÏÎÏ×ÌÅÎÏ',
+  'Weight'                      => '÷ÁÇÁ',
+  'What type of item is this?'  => 'ñËÉÊ ÃÅ ×ÉÄ/ÔÉРÔÏ×ÁÒÕ',
+  'ea'                          => 'ÛÔ.',
+  'emailed to'                  => 'ÐÏÓÌÁÎÏ ÐÏ ÅÌ. ÐÏÛÔ¦ ÄÏ',
+  'hr'                          => 'ÇÏÄ.',
+  'sent to printer'             => 'ÐÏÓÌÁÎÏ ÄÏ ÐÒÉÎÔÅÒÁ',
+  'to'                          => 'ÄÏ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'îÏ×ÉÊ'                       => 'add',
+  'îÏ×ÉÊ_ËÏÍÐÌÅËÔ'              => 'add_assembly',
+  'îÏ×ÉÊ_ôÏ×ÁÒ'                 => 'add_part',
+  'îÏ×Á_ÐÏÓÌÕÇÁ'                => 'add_service',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  '÷ÉÄÁÌÉÔÉ'                    => 'delete',
+  '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ_ËÏÍÐÌÅËÔ'      => 'edit_assembly',
+  '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ_ôÏ×ÁÒ'         => 'edit_part',
+  '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ_ÐÏÓÌÕÇÕ'       => 'edit_service',
+  'úÂÅÒÅÇÔÉ'                    => 'save',
+  'ðÏÎÏ×ÉÔÉ'                    => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/io b/sql-ledger/locale/ua/io
new file mode 100644 (file)
index 0000000..dba8567
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'îÏ×Å ÚÁÍÏ×ÌÅÎÎÑ ÎÁ ËÕЦ×ÌÀ',
+  'Add Sales Order'             => 'îÏ×Å ÚÁÍÏ×ÌÅÎÎÑ ÎÁ ÐÒÏÄÁÖ',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'Apr'                         => 'ËצÔÎÑ',
+  'April'                       => 'ëצÔÅÎØ',
+  'Attachment'                  => 'äÏÄÁÔÏË',
+  'Aug'                         => 'ÓÅÒÐÎÑ',
+  'August'                      => 'óÅÒÐÅÎØ',
+  'Bcc'                         => 'ðÒÉ×ÁÔÎÁ ËÏЦѠÄÏ',
+  'Bin'                         => 'Bin',
+  'Cc'                          => 'ëÏЦѠÄÏ',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÁ ÏÓÏÂÁ',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Copies'                      => 'ëÏЦÊ',
+  'Dec'                         => 'ÇÒÕÄÎÑ',
+  'December'                    => 'çÒÕÄÅÎØ',
+  'Delivery Date'               => 'äÁÔÁ ÄÏÓÔÁ×ËÉ',
+  'Description'                 => 'ïÐÉÓ',
+  'E-mail'                      => 'åÌ. ÐÏÛÔÁ',
+  'E-mail address missing!'     => 'îÅ ×ËÁÚÁÎÁ ÁÄÒÅÓÁ ÅÌ. ÐÏÛÔÉ!',
+  'Extended'                    => 'ðÒÏÄÏ×ÖÅÎÏ',
+  'Fax'                         => 'æÁÈ',
+  'Feb'                         => 'ÌÀÔÏÇÏ',
+  'February'                    => 'ìÀÔÉÊ',
+  'In-line'                     => '÷ËÌÀÞÅÎÏ (In-line)',
+  'Invoice'                     => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Invoice Date missing!'       => 'îÅ ×ËÁÚÁÎÁ ÄÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Invoice Number missing!'     => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Item not on file!'           => 'òÅÞ¦ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Jan'                         => 'Ó¦ÞÎÑ',
+  'January'                     => 'Ó¦ÞÅÎØ',
+  'Jul'                         => 'ÌÉÐÎÑ',
+  'July'                        => 'ìÉÐÅÎØ',
+  'Jun'                         => 'ÞÅÒ×ÎÑ',
+  'June'                        => 'þÅÒ×ÅÎØ',
+  'Mar'                         => 'ÂÅÒÅÚÎÑ',
+  'March'                       => 'âÅÒÅÚÅÎØ',
+  'May'                         => 'ÔÒÁ×ÎÑ',
+  'May '                        => 'ôÒÁ×ÅÎØ',
+  'Message'                     => 'ðÏצÄÏÍÌÅÎÎÑ',
+  'Name'                        => '¶Í\'Ñ / îÁÚ×Á',
+  'No.'                         => 'No.',
+  'Nov'                         => 'ÌÉÓÔÏÐÁÄÁ',
+  'November'                    => 'ìÉÓÔÏÐÁÄ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Number missing in Row'       => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ Õ ÒÑÄËÕ',
+  'Oct'                         => 'ÖÏ×ÔÎÑ',
+  'October'                     => 'öÏ×ÔÅÎØ',
+  'Order'                       => 'úÁÍÏ×ÌÅÎÎÑ',
+  'Order Date missing!'         => 'îÅ ×ËÁÚÁÎÁ äÁÔÁ úÁÍÏ×ÌÅÎÎÑ!',
+  'Order Number missing!'       => 'îÅ ×ËÁÚÁÎÏ îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'PDF'                         => 'PDF ÆÏÒÍÁÔ',
+  'Packing List'                => 'ðÁËÕ×ÁÌØÎÉÊ óÐÉÓÏË',
+  'Packing List Date missing!'  => 'îÅ ×ËÁÚÁÎÁ äÁÔÁ ðÁËÕ×ÁÌØÎÏÇÏ óÐÉÓÏËÕ',
+  'Packing List Number missing!' => 'îÅ ×ËÁÚÁÎÉÊ îÏÍÅÒ ðÁËÕ×ÁÌØÎÏÇÏ óÐÉÓÏËÕ',
+  'Part'                        => 'ôÏ×ÁÒ',
+  'Phone'                       => 'ôÅÌ.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'ã¦ÎÁ',
+  'Printer'                     => 'ðÒÉÎÔÅÒ',
+  'Project'                     => 'ðÒÏÅËÔ',
+  'Purchase Order'              => 'ëÕЦ×ÅÌØÎÅ úÁÍÏ×ÌÅÎÎÑ',
+  'Qty'                         => 'ë¦ÌØ˦ÓÔØ',
+  'Recd'                        => 'ïÔÒÉÍÁÎÏ',
+  'Required by'                 => 'ôÅÒͦΠÄÏÓÔÁ×ËÉ',
+  'Sales Order'                 => 'îÁËÌÁÄÎÁ ðÒÏÄÁÖÕ ',
+  'Screen'                      => 'åËÒÁÎ',
+  'Select from one of the items below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÕ ¦Ú ÎÁÓÔÕÐÎÉÈ ÒÅÞÅÊ',
+  'Select postscript or PDF!'   => '÷ÉÂÅÒ¦ÔØ postscript ÁÂÏ PDF ÆÏÒÍÁÔ!',
+  'Sep'                         => '×ÅÒÅÓÎÑ',
+  'September'                   => '÷ÅÒÅÓÅÎØ',
+  'Service'                     => 'ðÏÓÌÕÇÁ',
+  'Ship'                        => 'ðÏÓÌÁÔÉ',
+  'Ship to'                     => 'ðÏÓÌÁÔÉ ÄÏ',
+  'Subject'                     => 'ôÅÍÁ',
+  'To'                          => 'äÏ',
+  'Unit'                        => 'ïÄÉÎÉÃÑ',
+  'What type of item is this?'  => 'ñËÉÊ ÃÅ ×ÉÄ/ÔÉРÔÏ×ÁÒÕ',
+  'emailed to'                  => 'ÐÏÓÌÁÎÏ ÐÏ ÅÌ. ÐÏÛÔ¦ ÄÏ',
+  'sent to printer'             => 'ÐÏÓÌÁÎÏ ÄÏ ÐÒÉÎÔÅÒÁ',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/ir b/sql-ledger/locale/ua/ir
new file mode 100644 (file)
index 0000000..8caf3fd
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'òÁÈÕÎÏË',
+  'Add Purchase Invoice'        => 'îÏ×ÉÊ ëÕЦ×ÅÌØÎÉÊ òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Add Purchase Order'          => 'îÏ×Å ÚÁÍÏ×ÌÅÎÎÑ ÎÁ ËÕЦ×ÌÀ',
+  'Add Sales Order'             => 'îÏ×Å ÚÁÍÏ×ÌÅÎÎÑ ÎÁ ÐÒÏÄÁÖ',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'Amount'                      => 'óÕÍÁ',
+  'Apr'                         => 'ËצÔÎÑ',
+  'April'                       => 'ëצÔÅÎØ',
+  'Are you sure you want to delete Invoice Number' => '÷É ÐÅ×Φ, ÝÏ ÈÏÞÅÔÅ ×ÉÄÁÌÉÔÉ ÄÁÎÉÊ ÒÁÈÕÎÏË?',
+  'Attachment'                  => 'äÏÄÁÔÏË',
+  'Aug'                         => 'ÓÅÒÐÎÑ',
+  'August'                      => 'óÅÒÐÅÎØ',
+  'Bcc'                         => 'ðÒÉ×ÁÔÎÁ ËÏЦѠÄÏ',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÒÁÈÕÎÏË-ÆÁËÔÕÒÕ',
+  'Cannot post invoice for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÒÁÈÕÎÏË-ÆÁËÔÕÒÕ ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Cannot post invoice!'        => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÒÁÈÕÎÏË-ÆÁËÔÕÒÕ!',
+  'Cannot post payment for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÐÌÁÔ¦Ö ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Cc'                          => 'ëÏЦѠÄÏ',
+  'Confirm!'                    => 'ð¦ÄÔ×ÅÒĦÔØ!',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÁ ÏÓÏÂÁ',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Copies'                      => 'ëÏЦÊ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Customer not on file!'       => 'ë̦¤ÎÔÁ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Date'                        => 'äÁÔÁ',
+  'Date Due'                    => 'úÁÐÌÁÔÉÔÉ ÄÏ',
+  'Dec'                         => 'ÇÒÕÄÎÑ',
+  'December'                    => 'çÒÕÄÅÎØ',
+  'Delete'                      => '÷ÉÄÁÌÉÔÉ',
+  'Delivery Date'               => 'äÁÔÁ ÄÏÓÔÁ×ËÉ',
+  'Description'                 => 'ïÐÉÓ',
+  'E-mail'                      => 'åÌ. ÐÏÛÔÁ',
+  'E-mail address missing!'     => 'îÅ ×ËÁÚÁÎÁ ÁÄÒÅÓÁ ÅÌ. ÐÏÛÔÉ!',
+  'Edit Purchase Invoice'       => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ëÕЦ×ÅÌØÎÉÊ òÁÈÕÎÏË-ÆÁËÔÕÒÕ',
+  'Exch'                        => 'ëÕÒÓ',
+  'Exchangerate'                => 'ëÕÒÓ ×ÁÌÀÔÉ',
+  'Exchangerate for payment missing!' => 'îÅ ×ËÁÚÁÎÉÊ ËÕÒÓ ×ÁÌÀÔÉ ÄÌÑ ÐÌÁÔÅÖÕ!',
+  'Exchangerate missing!'       => 'îÅ ×ËÁÚÁÎÉÊ ËÕÒÓ ×ÁÌÀÔÉ!',
+  'Extended'                    => 'ðÒÏÄÏ×ÖÅÎÏ',
+  'Fax'                         => 'æÁÈ',
+  'Feb'                         => 'ÌÀÔÏÇÏ',
+  'February'                    => 'ìÀÔÉÊ',
+  'In-line'                     => '÷ËÌÀÞÅÎÏ (In-line)',
+  'Invoice'                     => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Invoice Date'                => 'äÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ',
+  'Invoice Date missing!'       => 'îÅ ×ËÁÚÁÎÁ ÄÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Invoice Number'              => 'îÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ',
+  'Invoice Number missing!'     => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Invoice deleted!'            => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ ×ÉÄÁÌÅÎÉÊ!',
+  'Invoice posted!'             => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ ×ÉÓÔÁ×ÌÅÎÉÊ!',
+  'Item not on file!'           => 'òÅÞ¦ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Jan'                         => 'Ó¦ÞÎÑ',
+  'January'                     => 'Ó¦ÞÅÎØ',
+  'Jul'                         => 'ÌÉÐÎÑ',
+  'July'                        => 'ìÉÐÅÎØ',
+  'Jun'                         => 'ÞÅÒ×ÎÑ',
+  'June'                        => 'þÅÒ×ÅÎØ',
+  'Mar'                         => 'ÂÅÒÅÚÎÑ',
+  'March'                       => 'âÅÒÅÚÅÎØ',
+  'May'                         => 'ÔÒÁ×ÎÑ',
+  'May '                        => 'ôÒÁ×ÅÎØ',
+  'Message'                     => 'ðÏצÄÏÍÌÅÎÎÑ',
+  'Name'                        => '¶Í\'Ñ / îÁÚ×Á',
+  'No.'                         => 'No.',
+  'Notes'                       => 'ðÒÉͦÔËÉ',
+  'Nov'                         => 'ÌÉÓÔÏÐÁÄÁ',
+  'November'                    => 'ìÉÓÔÏÐÁÄ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Number missing in Row'       => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ Õ ÒÑÄËÕ',
+  'Oct'                         => 'ÖÏ×ÔÎÑ',
+  'October'                     => 'öÏ×ÔÅÎØ',
+  'Order'                       => 'úÁÍÏ×ÌÅÎÎÑ',
+  'Order Date missing!'         => 'îÅ ×ËÁÚÁÎÁ äÁÔÁ úÁÍÏ×ÌÅÎÎÑ!',
+  'Order Number'                => 'îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'Order Number missing!'       => 'îÅ ×ËÁÚÁÎÏ îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'PDF'                         => 'PDF ÆÏÒÍÁÔ',
+  'Packing List'                => 'ðÁËÕ×ÁÌØÎÉÊ óÐÉÓÏË',
+  'Packing List Date missing!'  => 'îÅ ×ËÁÚÁÎÁ äÁÔÁ ðÁËÕ×ÁÌØÎÏÇÏ óÐÉÓÏËÕ',
+  'Packing List Number missing!' => 'îÅ ×ËÁÚÁÎÉÊ îÏÍÅÒ ðÁËÕ×ÁÌØÎÏÇÏ óÐÉÓÏËÕ',
+  'Part'                        => 'ôÏ×ÁÒ',
+  'Payment date missing!'       => 'îÅ ×ËÁÚÁÎÏ ÄÁÔÕ ðÌÁÔÅÖÕ!',
+  'Payments'                    => 'ðÌÁÔÅÖ¦',
+  'Phone'                       => 'ôÅÌ.',
+  'Post'                        => '÷ÉÓÔÁ×ÉÔÉ',
+  'Post as new'                 => '÷ÉÓÔÁ×ÉÔÉ ÑË ÎÏ×ÉÊ',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'ã¦ÎÁ',
+  'Printer'                     => 'ðÒÉÎÔÅÒ',
+  'Project'                     => 'ðÒÏÅËÔ',
+  'Project not on file!'        => 'ðÒÏÅËÔÕ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Purchase Order'              => 'ëÕЦ×ÅÌØÎÅ úÁÍÏ×ÌÅÎÎÑ',
+  'Qty'                         => 'ë¦ÌØ˦ÓÔØ',
+  'Recd'                        => 'ïÔÒÉÍÁÎÏ',
+  'Record in'                   => '÷ÎÅÓÔÉ ×',
+  'Required by'                 => 'ôÅÒͦΠÄÏÓÔÁ×ËÉ',
+  'Sales Order'                 => 'îÁËÌÁÄÎÁ ðÒÏÄÁÖÕ ',
+  'Screen'                      => 'åËÒÁÎ',
+  'Select from one of the items below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÕ ¦Ú ÎÁÓÔÕÐÎÉÈ ÒÅÞÅÊ',
+  'Select from one of the names below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÅ ¦Ú ÎÁÓÔÕÐÎÉÈ ¦ÍÅÎ/ÎÁÚ×',
+  'Select from one of the projects below' => '÷ÉÂÅÒ¦ÔØ ÏÄÉΠ¦Ú ÎÁÓÔÕÐÎÉÈ ÐÒÏÅËÔ¦×',
+  'Select postscript or PDF!'   => '÷ÉÂÅÒ¦ÔØ postscript ÁÂÏ PDF ÆÏÒÍÁÔ!',
+  'Sep'                         => '×ÅÒÅÓÎÑ',
+  'September'                   => '÷ÅÒÅÓÅÎØ',
+  'Service'                     => 'ðÏÓÌÕÇÁ',
+  'Ship'                        => 'ðÏÓÌÁÔÉ',
+  'Ship to'                     => 'ðÏÓÌÁÔÉ ÄÏ',
+  'Source'                      => 'äÖÅÒÅÌÏ',
+  'Subject'                     => 'ôÅÍÁ',
+  'Subtotal'                    => 'ð¦ÄÓÕÍÏË ÐÏ ÒÏÚĦÌÕ',
+  'Tax Included'                => 'ðÏÄÁÔÏË ×ËÌÀÞÅÎÏ',
+  'To'                          => 'äÏ',
+  'Total'                       => 'úÁÇÁÌØÎÁ óÕÍÁ',
+  'Unit'                        => 'ïÄÉÎÉÃÑ',
+  'Update'                      => 'ðÏÎÏ×ÉÔÉ',
+  'Vendor'                      => 'ðÏÓÔÁÞÁÌØÎÉË',
+  'Vendor missing!'             => 'ðÏÓÔÁÞÁÌØÎÉË ÎÅ ¦ÓÎÕ¤',
+  'Vendor not on file!'         => 'ðÏÔÁÞÁÌØÎÉËÁ ÎÅÍÁ Õ ÓÐÉÓËÕ ',
+  'What type of item is this?'  => 'ñËÉÊ ÃÅ ×ÉÄ/ÔÉРÔÏ×ÁÒÕ',
+  'Yes'                         => 'Tak',
+  'ea'                          => 'ÛÔ.',
+  'emailed to'                  => 'ÐÏÓÌÁÎÏ ÐÏ ÅÌ. ÐÏÛÔ¦ ÄÏ',
+  'sent to printer'             => 'ÐÏÓÌÁÎÏ ÄÏ ÐÒÉÎÔÅÒÁ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  '÷ÉÄÁÌÉÔÉ'                    => 'delete',
+  'úÁÍÏ×ÌÅÎÎÑ'                  => 'order',
+  '÷ÉÓÔÁ×ÉÔÉ'                   => 'post',
+  '÷ÉÓÔÁ×ÉÔÉ_ÑË_ÎÏ×ÉÊ'          => 'post_as_new',
+  'ðÏÎÏ×ÉÔÉ'                    => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/is b/sql-ledger/locale/ua/is
new file mode 100644 (file)
index 0000000..f62cc69
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'òÁÈÕÎÏË',
+  'Add Purchase Order'          => 'îÏ×Å ÚÁÍÏ×ÌÅÎÎÑ ÎÁ ËÕЦ×ÌÀ',
+  'Add Sales Invoice'           => 'îÏ×ÉÊ òÁÈÕÎÏ-ÆÁËÔÕÒÁ',
+  'Add Sales Order'             => 'îÏ×Å ÚÁÍÏ×ÌÅÎÎÑ ÎÁ ÐÒÏÄÁÖ',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'Amount'                      => 'óÕÍÁ',
+  'Apr'                         => 'ËצÔÎÑ',
+  'April'                       => 'ëצÔÅÎØ',
+  'Are you sure you want to delete Invoice Number' => '÷É ÐÅ×Φ, ÝÏ ÈÏÞÅÔÅ ×ÉÄÁÌÉÔÉ ÄÁÎÉÊ ÒÁÈÕÎÏË?',
+  'Attachment'                  => 'äÏÄÁÔÏË',
+  'Aug'                         => 'ÓÅÒÐÎÑ',
+  'August'                      => 'óÅÒÐÅÎØ',
+  'Bcc'                         => 'ðÒÉ×ÁÔÎÁ ËÏЦѠÄÏ',
+  'Bin'                         => 'Bin',
+  'Cannot delete invoice!'      => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÒÁÈÕÎÏË-ÆÁËÔÕÒÕ',
+  'Cannot post invoice for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÒÁÈÕÎÏË-ÆÁËÔÕÒÕ ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Cannot post invoice!'        => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÒÁÈÕÎÏË-ÆÁËÔÕÒÕ!',
+  'Cannot post payment for a closed period!' => 'îÅ ÍÏÖÌÉ×Ï ×ÉÓÔÁ×ÉÔÉ ÐÌÁÔ¦Ö ÄÌÑ ÚÁËÒÉÔÏÇÏ ÐÅÒ¦ÏÄÕ!',
+  'Cc'                          => 'ëÏЦѠÄÏ',
+  'Confirm!'                    => 'ð¦ÄÔ×ÅÒĦÔØ!',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÁ ÏÓÏÂÁ',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Copies'                      => 'ëÏЦÊ',
+  'Credit Limit'                => 'ì¦Í¦Ô ËÒÅÄÉÔÕ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Customer'                    => 'ë̦¤ÎÔ',
+  'Customer missing!'           => 'îÅ ×ËÁÚÁÎÉÊ Ë̦¤ÎÔ!',
+  'Customer not on file!'       => 'ë̦¤ÎÔÁ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Date'                        => 'äÁÔÁ',
+  'Date Due'                    => 'úÁÐÌÁÔÉÔÉ ÄÏ',
+  'Dec'                         => 'ÇÒÕÄÎÑ',
+  'December'                    => 'çÒÕÄÅÎØ',
+  'Delete'                      => '÷ÉÄÁÌÉÔÉ',
+  'Delivery Date'               => 'äÁÔÁ ÄÏÓÔÁ×ËÉ',
+  'Description'                 => 'ïÐÉÓ',
+  'E-mail'                      => 'åÌ. ÐÏÛÔÁ',
+  'E-mail address missing!'     => 'îÅ ×ËÁÚÁÎÁ ÁÄÒÅÓÁ ÅÌ. ÐÏÛÔÉ!',
+  'Edit Sales Invoice'          => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ òÁÈÕÎÏË-ÆÁËÔÕÒÕ',
+  'Exch'                        => 'ëÕÒÓ',
+  'Exchangerate'                => 'ëÕÒÓ ×ÁÌÀÔÉ',
+  'Exchangerate for payment missing!' => 'îÅ ×ËÁÚÁÎÉÊ ËÕÒÓ ×ÁÌÀÔÉ ÄÌÑ ÐÌÁÔÅÖÕ!',
+  'Exchangerate missing!'       => 'îÅ ×ËÁÚÁÎÉÊ ËÕÒÓ ×ÁÌÀÔÉ!',
+  'Extended'                    => 'ðÒÏÄÏ×ÖÅÎÏ',
+  'Fax'                         => 'æÁÈ',
+  'Feb'                         => 'ÌÀÔÏÇÏ',
+  'February'                    => 'ìÀÔÉÊ',
+  'In-line'                     => '÷ËÌÀÞÅÎÏ (In-line)',
+  'Invoice'                     => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Invoice Date'                => 'äÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ',
+  'Invoice Date missing!'       => 'îÅ ×ËÁÚÁÎÁ ÄÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Invoice Number'              => 'îÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ',
+  'Invoice Number missing!'     => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Invoice deleted!'            => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ ×ÉÄÁÌÅÎÉÊ!',
+  'Invoice posted!'             => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ ×ÉÓÔÁ×ÌÅÎÉÊ!',
+  'Item not on file!'           => 'òÅÞ¦ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Jan'                         => 'Ó¦ÞÎÑ',
+  'January'                     => 'Ó¦ÞÅÎØ',
+  'Jul'                         => 'ÌÉÐÎÑ',
+  'July'                        => 'ìÉÐÅÎØ',
+  'Jun'                         => 'ÞÅÒ×ÎÑ',
+  'June'                        => 'þÅÒ×ÅÎØ',
+  'Mar'                         => 'ÂÅÒÅÚÎÑ',
+  'March'                       => 'âÅÒÅÚÅÎØ',
+  'May'                         => 'ÔÒÁ×ÎÑ',
+  'May '                        => 'ôÒÁ×ÅÎØ',
+  'Message'                     => 'ðÏצÄÏÍÌÅÎÎÑ',
+  'Name'                        => '¶Í\'Ñ / îÁÚ×Á',
+  'No.'                         => 'No.',
+  'Notes'                       => 'ðÒÉͦÔËÉ',
+  'Nov'                         => 'ÌÉÓÔÏÐÁÄÁ',
+  'November'                    => 'ìÉÓÔÏÐÁÄ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Number missing in Row'       => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ Õ ÒÑÄËÕ',
+  'Oct'                         => 'ÖÏ×ÔÎÑ',
+  'October'                     => 'öÏ×ÔÅÎØ',
+  'Order'                       => 'úÁÍÏ×ÌÅÎÎÑ',
+  'Order Date missing!'         => 'îÅ ×ËÁÚÁÎÁ äÁÔÁ úÁÍÏ×ÌÅÎÎÑ!',
+  'Order Number'                => 'îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'Order Number missing!'       => 'îÅ ×ËÁÚÁÎÏ îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'PDF'                         => 'PDF ÆÏÒÍÁÔ',
+  'Packing List'                => 'ðÁËÕ×ÁÌØÎÉÊ óÐÉÓÏË',
+  'Packing List Date missing!'  => 'îÅ ×ËÁÚÁÎÁ äÁÔÁ ðÁËÕ×ÁÌØÎÏÇÏ óÐÉÓÏËÕ',
+  'Packing List Number missing!' => 'îÅ ×ËÁÚÁÎÉÊ îÏÍÅÒ ðÁËÕ×ÁÌØÎÏÇÏ óÐÉÓÏËÕ',
+  'Part'                        => 'ôÏ×ÁÒ',
+  'Payment date missing!'       => 'îÅ ×ËÁÚÁÎÏ ÄÁÔÕ ðÌÁÔÅÖÕ!',
+  'Payments'                    => 'ðÌÁÔÅÖ¦',
+  'Phone'                       => 'ôÅÌ.',
+  'Post'                        => '÷ÉÓÔÁ×ÉÔÉ',
+  'Post as new'                 => '÷ÉÓÔÁ×ÉÔÉ ÑË ÎÏ×ÉÊ',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'ã¦ÎÁ',
+  'Print'                       => 'îÁÄÒÕËÕ×ÁÔÉ',
+  'Printer'                     => 'ðÒÉÎÔÅÒ',
+  'Project'                     => 'ðÒÏÅËÔ',
+  'Project not on file!'        => 'ðÒÏÅËÔÕ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Purchase Order'              => 'ëÕЦ×ÅÌØÎÅ úÁÍÏ×ÌÅÎÎÑ',
+  'Qty'                         => 'ë¦ÌØ˦ÓÔØ',
+  'Recd'                        => 'ïÔÒÉÍÁÎÏ',
+  'Record in'                   => '÷ÎÅÓÔÉ ×',
+  'Remaining'                   => 'úÁÌÉÛÉÌÏÓØ',
+  'Required by'                 => 'ôÅÒͦΠÄÏÓÔÁ×ËÉ',
+  'Sales Order'                 => 'îÁËÌÁÄÎÁ ðÒÏÄÁÖÕ ',
+  'Screen'                      => 'åËÒÁÎ',
+  'Select from one of the items below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÕ ¦Ú ÎÁÓÔÕÐÎÉÈ ÒÅÞÅÊ',
+  'Select from one of the names below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÅ ¦Ú ÎÁÓÔÕÐÎÉÈ ¦ÍÅÎ/ÎÁÚ×',
+  'Select from one of the projects below' => '÷ÉÂÅÒ¦ÔØ ÏÄÉΠ¦Ú ÎÁÓÔÕÐÎÉÈ ÐÒÏÅËÔ¦×',
+  'Select postscript or PDF!'   => '÷ÉÂÅÒ¦ÔØ postscript ÁÂÏ PDF ÆÏÒÍÁÔ!',
+  'Sep'                         => '×ÅÒÅÓÎÑ',
+  'September'                   => '÷ÅÒÅÓÅÎØ',
+  'Service'                     => 'ðÏÓÌÕÇÁ',
+  'Ship'                        => 'ðÏÓÌÁÔÉ',
+  'Ship to'                     => 'ðÏÓÌÁÔÉ ÄÏ',
+  'Ship via'                    => 'ðÏÓÌÁÔÉ ÞÅÒÅÚ',
+  'Source'                      => 'äÖÅÒÅÌÏ',
+  'Subject'                     => 'ôÅÍÁ',
+  'Subtotal'                    => 'ð¦ÄÓÕÍÏË ÐÏ ÒÏÚĦÌÕ',
+  'Tax Included'                => 'ðÏÄÁÔÏË ×ËÌÀÞÅÎÏ',
+  'To'                          => 'äÏ',
+  'Total'                       => 'úÁÇÁÌØÎÁ óÕÍÁ',
+  'Unit'                        => 'ïÄÉÎÉÃÑ',
+  'Update'                      => 'ðÏÎÏ×ÉÔÉ',
+  'Vendor not on file!'         => 'ðÏÔÁÞÁÌØÎÉËÁ ÎÅÍÁ Õ ÓÐÉÓËÕ ',
+  'What type of item is this?'  => 'ñËÉÊ ÃÅ ×ÉÄ/ÔÉРÔÏ×ÁÒÕ',
+  'Yes'                         => 'Tak',
+  'ea'                          => 'ÛÔ.',
+  'emailed to'                  => 'ÐÏÓÌÁÎÏ ÐÏ ÅÌ. ÐÏÛÔ¦ ÄÏ',
+  'sent to printer'             => 'ÐÏÓÌÁÎÏ ÄÏ ÐÒÉÎÔÅÒÁ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  '÷ÉÄÁÌÉÔÉ'                    => 'delete',
+  'åÌ._ÐÏÛÔÁ'                   => 'e_mail',
+  'úÁÍÏ×ÌÅÎÎÑ'                  => 'order',
+  '÷ÉÓÔÁ×ÉÔÉ'                   => 'post',
+  '÷ÉÓÔÁ×ÉÔÉ_ÑË_ÎÏ×ÉÊ'          => 'post_as_new',
+  'îÁÄÒÕËÕ×ÁÔÉ'                 => 'print',
+  'ðÏÓÌÁÔÉ_ÄÏ'                  => 'ship_to',
+  'ðÏÎÏ×ÉÔÉ'                    => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/login b/sql-ledger/locale/ua/login
new file mode 100644 (file)
index 0000000..4810b07
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'ðÒÏ ÐÒÏÇÒÁÍÕ',
+  'Database Host'               => 'íÁÛÉÎÁ âÁÚÉ äÁÎÉÈ',
+  'Dataset'                     => 'âÁÚÁ äÁÎÉÈ',
+  'Incorrect Dataset version!'  => 'îÅצÒÎÁ ×ÅÒӦѠâÁÚÉ äÁÎÉÈ!',
+  'Incorrect Password!'         => 'îÅצÒÎÉÊ ðÁÒÏÌØ!',
+  'Licensed to'                 => 'ì¦ÃÅÎÚ¦¤À ×ÏÌÏĦ¤:',
+  'Login'                       => 'ðÏÞÁÔÏË óÅÁÎÓÕ',
+  'Name'                        => '¶Í\'Ñ / îÁÚ×Á',
+  'Password'                    => 'ðÁÒÏÌØ',
+  'User'                        => 'ëÏÒÉÓÔÕ×ÁÞ',
+  'Version'                     => '÷ÅÒÓ¦Ñ',
+  'You are logged out!'         => '÷ÁÛ ÓÅÁÎÓ ÚÁ˦ÎÞÉ×ÓÑ!',
+  'You did not enter a name!'   => 'îÅ ××ÅÄÅÎÏ ¦Í\'Ñ/ÎÁÚ×Õ',
+  'is not a member!'            => 'ÎÅ ¤ ÞÌÅÎÏÍ!',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'ðÏÞÁÔÏË_óÅÁÎÓÕ'              => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/menu b/sql-ledger/locale/ua/menu
new file mode 100644 (file)
index 0000000..0417db0
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => '÷ÉÔÒÁÔÉ',
+  'AP Aging'                    => 'AP Aging (×ÉÔÒÁÔÉ)',
+  'AR'                          => 'äÏÈÏÄÉ',
+  'AR Aging'                    => 'AR Aging (ÄÏÈÏÄÉ)',
+  'Accounting Menu'             => 'íÅÎÀ ïÂ̦ËÕ',
+  'Add Account'                 => 'îÏ×ÉÊ ÒÁÈÕÎÏË',
+  'Add Assembly'                => 'îÏ×ÉÊ ËÏÍÐÌÅËÔ',
+  'Add Customer'                => 'îÏ×ÉÊ Ë̦¤ÎÔ',
+  'Add GIFI'                    => 'îÏ×ÉÊ GIFI',
+  'Add Part'                    => 'îÏ×ÉÊ ôÏ×ÁÒ',
+  'Add Project'                 => 'îÏ×ÉÊ ðÒÏÅËÔ',
+  'Add Service'                 => 'îÏ×Á ÐÏÓÌÕÇÁ',
+  'Add Transaction'             => 'îÏ×Á ÏÐÅÒÁæÑ',
+  'Add Vendor'                  => 'îÏ×ÉÊ ÐÏÓÔÁÞÁÌØÎÉË',
+  'Assemblies'                  => 'ëÏÍÐÌÅËÔÉ',
+  'Audit Control'               => 'ëÏÎÔÒÏÌØ',
+  'Backup'                      => 'òÅÚÅÒ×ÎÁ ËÏЦÑ',
+  'Balance Sheet'               => 'âÁÌÁÎÓ',
+  'Cash'                        => 'çÏÔ¦×ËÁ',
+  'Chart of Accounts'           => 'ðÌÁΠòÁÈÕÎ˦×',
+  'Check'                       => 'þÅË',
+  'Customers'                   => 'ë̦¤ÎÔÉ',
+  'General Ledger'              => 'çÏÌÏ×ÎÁ ëÎÉÇÁ',
+  'Goods & Services'            => 'ôÏ×ÁÒÉ ¦ ðÏÓÌÕÇÉ',
+  'HTML Templates'              => 'HTML ûÁÂÌÏÎÉ ',
+  'Income Statement'            => 'úצԠÐÒÏ ÄÏÈÏÄÉ ¦ ×ÉÄÁÔËÉ',
+  'Invoice'                     => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'LaTeX Templates'             => 'LaTeX ûÁÂÌÏÎÉ',
+  'List Accounts'               => 'óÐÉÓÏË òÁÈÕÎ˦×',
+  'List GIFI'                   => 'óÐÉÓÏË GIFI',
+  'Logout'                      => 'ë¦ÎÅÃØ óÅÁÎÓÕ',
+  'Order Entry'                 => '÷ÉÓÔÁ×ÌÅÎÎÑ úÁÍÏ×ÌÅÎÎÑ',
+  'Packing List'                => 'ðÁËÕ×ÁÌØÎÉÊ óÐÉÓÏË',
+  'Parts'                       => 'ÔÏ×ÁÒÉ',
+  'Payment'                     => 'ðÌÁÔ¦Ö',
+  'Payments'                    => 'ðÌÁÔÅÖ¦',
+  'Preferences'                 => 'îÁÓÔÒÏÊËÉ',
+  'Projects'                    => 'ðÒÏÅËÔÉ',
+  'Purchase Invoice'            => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Purchase Order'              => 'ëÕЦ×ÅÌØÎÅ úÁÍÏ×ÌÅÎÎÑ',
+  'Purchase Orders'             => 'ëÕЦ×ÅÌØΦ úÁÍÏ×ÌÅÎÎÑ',
+  'Receipt'                     => 'ë×ÉÔÁÎæÑ',
+  'Receipts'                    => 'ë×ÉÔÁÎæ§',
+  'Reconciliation'              => 'õÚÇÏÄÖÅÎÎÑ',
+  'Reports'                     => 'úצÔÉ',
+  'Sales Invoice'               => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Sales Order'                 => 'îÁËÌÁÄÎÁ ðÒÏÄÁÖÕ ',
+  'Sales Orders'                => 'îÁËÌÁÄΦ ðÒÏÄÁÖÕ',
+  'Save to File'                => 'úÂÅÒÅÇÔÉ Õ æÁÊ̦',
+  'Send by E-Mail'              => '÷ÉÓÌÁÔÉ ÐÏ ÅÌ. ÐÏÛÔ¦',
+  'Services'                    => 'ðÏÓÌÕÇÉ',
+  'Statement'                   => 'úצÔ',
+  'Stock Assembly'              => '¶Î×ÅÎÔÁÒ ëÏÍÐÌÅËÔÕ',
+  'Stylesheet'                  => 'ïÆÏÒÍÌÅÎÎÎÑ',
+  'System'                      => 'óÉÓÔÅÍÁ',
+  'Tax collected'               => 'ú¦ÂÒÁÎÏ ÐÏÄÁÔ˦נ',
+  'Tax paid'                    => 'ðÏÄÁÔÏË ÚÁÐÌÁÞÅÎÏ',
+  'Transactions'                => 'ïÐÅÒÁæ§',
+  'Trial Balance'               => 'ðÒÏÂÎÉÊ âÁÌÁÎÓ',
+  'Vendors'                     => 'ðÏÓÔÁÞÁÌØÎÉËÉ',
+  'Version'                     => '÷ÅÒÓ¦Ñ',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/oe b/sql-ledger/locale/ua/oe
new file mode 100644 (file)
index 0000000..16c9707
--- /dev/null
@@ -0,0 +1,200 @@
+$self{texts} = {
+  'Add'                         => 'îÏ×ÉÊ',
+  'Add Purchase Invoice'        => 'îÏ×ÉÊ ëÕЦ×ÅÌØÎÉÊ òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Add Purchase Order'          => 'îÏ×Å ÚÁÍÏ×ÌÅÎÎÑ ÎÁ ËÕЦ×ÌÀ',
+  'Add Sales Invoice'           => 'îÏ×ÉÊ òÁÈÕÎÏ-ÆÁËÔÕÒÁ',
+  'Add Sales Order'             => 'îÏ×Å ÚÁÍÏ×ÌÅÎÎÑ ÎÁ ÐÒÏÄÁÖ',
+  'Address'                     => 'áÄÒÅÓÁ',
+  'Amount'                      => 'óÕÍÁ',
+  'Apr'                         => 'ËצÔÎÑ',
+  'April'                       => 'ëצÔÅÎØ',
+  'Are you sure you want to delete Order Number' => '÷É ÐÅ×Φ, ÝÏ ÈÏÞÅÔÅ ×ÉÄÁÌÉÔÉ ÄÁÎÅ ÚÁÍÏ×ÌÅÎÎÑ?',
+  'Attachment'                  => 'äÏÄÁÔÏË',
+  'Aug'                         => 'ÓÅÒÐÎÑ',
+  'August'                      => 'óÅÒÐÅÎØ',
+  'Bcc'                         => 'ðÒÉ×ÁÔÎÁ ËÏЦѠÄÏ',
+  'Bin'                         => 'Bin',
+  'C'                           => 'ó',
+  'Cannot delete order!'        => 'îÅ ÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÚÁÍÏ×ÌÅÎÎÑ!',
+  'Cannot save order!'          => 'îÅ ÍÏÖÌÉ×Ï ÚÂÅÒÅÇÔÉ ÚÁÍÏ×ÌÅÎÎÑ!',
+  'Cc'                          => 'ëÏЦѠÄÏ',
+  'Closed'                      => 'úÁËÒÉÔÏ',
+  'Confirm!'                    => 'ð¦ÄÔ×ÅÒĦÔØ!',
+  'Contact'                     => 'ëÏÎÔÁËÔÎÁ ÏÓÏÂÁ',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Copies'                      => 'ëÏЦÊ',
+  'Credit Limit'                => 'ì¦Í¦Ô ËÒÅÄÉÔÕ',
+  'Curr'                        => '÷ÁÌÀÔÁ',
+  'Currency'                    => '÷ÁÌÀÔÁ',
+  'Customer'                    => 'ë̦¤ÎÔ',
+  'Customer missing!'           => 'îÅ ×ËÁÚÁÎÉÊ Ë̦¤ÎÔ!',
+  'Customer not on file!'       => 'ë̦¤ÎÔÁ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Date'                        => 'äÁÔÁ',
+  'Dec'                         => 'ÇÒÕÄÎÑ',
+  'December'                    => 'çÒÕÄÅÎØ',
+  'Delete'                      => '÷ÉÄÁÌÉÔÉ',
+  'Delivery Date'               => 'äÁÔÁ ÄÏÓÔÁ×ËÉ',
+  'Description'                 => 'ïÐÉÓ',
+  'E-mail'                      => 'åÌ. ÐÏÛÔÁ',
+  'E-mail address missing!'     => 'îÅ ×ËÁÚÁÎÁ ÁÄÒÅÓÁ ÅÌ. ÐÏÛÔÉ!',
+  'Edit Purchase Order'         => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ëÕЦ×ÅÌØÎÅ úÁÍÏ×ÌÅÎÎÑ',
+  'Edit Sales Order'            => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ îÁËÌÁÄÎÕ ðÒÏÄÁÖÕ',
+  'Exchangerate'                => 'ëÕÒÓ ×ÁÌÀÔÉ',
+  'Exchangerate missing!'       => 'îÅ ×ËÁÚÁÎÉÊ ËÕÒÓ ×ÁÌÀÔÉ!',
+  'Extended'                    => 'ðÒÏÄÏ×ÖÅÎÏ',
+  'Fax'                         => 'æÁÈ',
+  'Feb'                         => 'ÌÀÔÏÇÏ',
+  'February'                    => 'ìÀÔÉÊ',
+  'From'                        => '÷¦Ä / Ú',
+  'ID'                          => '¶ÄÅÎÔÉƦËÁæÊÎÉÊ ÎÏÍÅÒ',
+  'In-line'                     => '÷ËÌÀÞÅÎÏ (In-line)',
+  'Include in Report'           => 'äÏÄÁÔÉ ÄÏ úצÔÕ',
+  'Invoice'                     => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Invoice Date missing!'       => 'îÅ ×ËÁÚÁÎÁ ÄÁÔÁ ×ÉÓÔÁ×ÌÅÎÎÑ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Invoice Number missing!'     => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ÒÁÈÕÎËÁ-ÆÁËÔÕÒÉ!',
+  'Item not on file!'           => 'òÅÞ¦ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Jan'                         => 'Ó¦ÞÎÑ',
+  'January'                     => 'Ó¦ÞÅÎØ',
+  'Jul'                         => 'ÌÉÐÎÑ',
+  'July'                        => 'ìÉÐÅÎØ',
+  'Jun'                         => 'ÞÅÒ×ÎÑ',
+  'June'                        => 'þÅÒ×ÅÎØ',
+  'Mar'                         => 'ÂÅÒÅÚÎÑ',
+  'March'                       => 'âÅÒÅÚÅÎØ',
+  'May'                         => 'ÔÒÁ×ÎÑ',
+  'May '                        => 'ôÒÁ×ÅÎØ',
+  'Message'                     => 'ðÏצÄÏÍÌÅÎÎÑ',
+  'Name'                        => '¶Í\'Ñ / îÁÚ×Á',
+  'No.'                         => 'No.',
+  'Notes'                       => 'ðÒÉͦÔËÉ',
+  'Nov'                         => 'ÌÉÓÔÏÐÁÄÁ',
+  'November'                    => 'ìÉÓÔÏÐÁÄ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Number missing in Row'       => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ Õ ÒÑÄËÕ',
+  'O'                           => 'ï',
+  'Oct'                         => 'ÖÏ×ÔÎÑ',
+  'October'                     => 'öÏ×ÔÅÎØ',
+  'Open'                        => '÷¦ÄËÒÉÔÏ',
+  'Order'                       => 'úÁÍÏ×ÌÅÎÎÑ',
+  'Order Date'                  => 'äÁÔÁ úÁÍÏ×ÌÅÎÎÑ',
+  'Order Date missing!'         => 'îÅ ×ËÁÚÁÎÁ äÁÔÁ úÁÍÏ×ÌÅÎÎÑ!',
+  'Order Number'                => 'îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'Order Number missing!'       => 'îÅ ×ËÁÚÁÎÏ îÏÍÅÒ úÁÍÏ×ÌÅÎÎÑ',
+  'Order deleted!'              => 'úÁÍÏ×ÌÅÎÎÑ ×ÉÄÁÌÅÎÏ!',
+  'Order saved!'                => 'úÁÍÏ×ÌÅÎÎÑ ÚÂÅÒÅÖÅÎÏ!',
+  'PDF'                         => 'PDF ÆÏÒÍÁÔ',
+  'Packing List'                => 'ðÁËÕ×ÁÌØÎÉÊ óÐÉÓÏË',
+  'Packing List Date missing!'  => 'îÅ ×ËÁÚÁÎÁ äÁÔÁ ðÁËÕ×ÁÌØÎÏÇÏ óÐÉÓÏËÕ',
+  'Packing List Number missing!' => 'îÅ ×ËÁÚÁÎÉÊ îÏÍÅÒ ðÁËÕ×ÁÌØÎÏÇÏ óÐÉÓÏËÕ',
+  'Part'                        => 'ôÏ×ÁÒ',
+  'Phone'                       => 'ôÅÌ.',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'ã¦ÎÁ',
+  'Print'                       => 'îÁÄÒÕËÕ×ÁÔÉ',
+  'Printer'                     => 'ðÒÉÎÔÅÒ',
+  'Project'                     => 'ðÒÏÅËÔ',
+  'Project not on file!'        => 'ðÒÏÅËÔÕ ÎÅÍÁ × ÓÐÉÓËÕ!',
+  'Purchase Order'              => 'ëÕЦ×ÅÌØÎÅ úÁÍÏ×ÌÅÎÎÑ',
+  'Purchase Orders'             => 'ëÕЦ×ÅÌØΦ úÁÍÏ×ÌÅÎÎÑ',
+  'Qty'                         => 'ë¦ÌØ˦ÓÔØ',
+  'Recd'                        => 'ïÔÒÉÍÁÎÏ',
+  'Remaining'                   => 'úÁÌÉÛÉÌÏÓØ',
+  'Required by'                 => 'ôÅÒͦΠÄÏÓÔÁ×ËÉ',
+  'Sales Order'                 => 'îÁËÌÁÄÎÁ ðÒÏÄÁÖÕ ',
+  'Sales Orders'                => 'îÁËÌÁÄΦ ðÒÏÄÁÖÕ',
+  'Save'                        => 'úÂÅÒÅÇÔÉ',
+  'Save as new'                 => 'úÂÅÒÅÇÔÉ ÑË ÎÏ×Å',
+  'Screen'                      => 'åËÒÁÎ',
+  'Select from one of the items below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÕ ¦Ú ÎÁÓÔÕÐÎÉÈ ÒÅÞÅÊ',
+  'Select from one of the names below' => '÷ÉÂÅÒ¦ÔØ ÏÄÎÅ ¦Ú ÎÁÓÔÕÐÎÉÈ ¦ÍÅÎ/ÎÁÚ×',
+  'Select from one of the projects below' => '÷ÉÂÅÒ¦ÔØ ÏÄÉΠ¦Ú ÎÁÓÔÕÐÎÉÈ ÐÒÏÅËÔ¦×',
+  'Select postscript or PDF!'   => '÷ÉÂÅÒ¦ÔØ postscript ÁÂÏ PDF ÆÏÒÍÁÔ!',
+  'Sep'                         => '×ÅÒÅÓÎÑ',
+  'September'                   => '÷ÅÒÅÓÅÎØ',
+  'Service'                     => 'ðÏÓÌÕÇÁ',
+  'Ship'                        => 'ðÏÓÌÁÔÉ',
+  'Ship to'                     => 'ðÏÓÌÁÔÉ ÄÏ',
+  'Ship via'                    => 'ðÏÓÌÁÔÉ ÞÅÒÅÚ',
+  'Subject'                     => 'ôÅÍÁ',
+  'Subtotal'                    => 'ð¦ÄÓÕÍÏË ÐÏ ÒÏÚĦÌÕ',
+  'Tax'                         => 'ðÏÄÁÔÏË',
+  'Tax Included'                => 'ðÏÄÁÔÏË ×ËÌÀÞÅÎÏ',
+  'Terms: Net'                  => 'õÍÏ×É: úÁÐÌÁÔÉÔÉ',
+  'To'                          => 'äÏ',
+  'Total'                       => 'úÁÇÁÌØÎÁ óÕÍÁ',
+  'Unit'                        => 'ïÄÉÎÉÃÑ',
+  'Update'                      => 'ðÏÎÏ×ÉÔÉ',
+  'Vendor'                      => 'ðÏÓÔÁÞÁÌØÎÉË',
+  'Vendor missing!'             => 'ðÏÓÔÁÞÁÌØÎÉË ÎÅ ¦ÓÎÕ¤',
+  'Vendor not on file!'         => 'ðÏÔÁÞÁÌØÎÉËÁ ÎÅÍÁ Õ ÓÐÉÓËÕ ',
+  'What type of item is this?'  => 'ñËÉÊ ÃÅ ×ÉÄ/ÔÉРÔÏ×ÁÒÕ',
+  'Yes'                         => 'Tak',
+  'days'                        => 'ÄΦ×',
+  'ea'                          => 'ÛÔ.',
+  'emailed to'                  => 'ÐÏÓÌÁÎÏ ÐÏ ÅÌ. ÐÏÛÔ¦ ÄÏ',
+  'sent to printer'             => 'ÐÏÓÌÁÎÏ ÄÏ ÐÒÉÎÔÅÒÁ',
+  'to'                          => 'ÄÏ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'îÏ×ÉÊ'                       => 'add',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  '÷ÉÄÁÌÉÔÉ'                    => 'delete',
+  'åÌ._ÐÏÛÔÁ'                   => 'e_mail',
+  'òÁÈÕÎÏË_ÆÁËÔÕÒÁ'             => 'invoice',
+  'îÁÄÒÕËÕ×ÁÔÉ'                 => 'print',
+  'úÂÅÒÅÇÔÉ'                    => 'save',
+  'úÂÅÒÅÇÔÉ_ÑË_ÎÏ×Å'            => 'save_as_new',
+  'ðÏÓÌÁÔÉ_ÄÏ'                  => 'ship_to',
+  'ðÏÎÏ×ÉÔÉ'                    => 'update',
+  'tak'                         => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/pe b/sql-ledger/locale/ua/pe
new file mode 100644 (file)
index 0000000..3f4e959
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'îÏ×ÉÊ',
+  'Add Project'                 => 'îÏ×ÉÊ ðÒÏÅËÔ',
+  'All'                         => '÷Ó¦',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Delete'                      => '÷ÉÄÁÌÉÔÉ',
+  'Description'                 => 'ïÐÉÓ',
+  'Edit Project'                => '÷¦ÄÒÅÄÁÇÕ×ÁÔÉ ðÒÏÅËÔ',
+  'Number'                      => 'îÏÍÅÒ',
+  'Orphaned'                    => '÷¦ÄÏËÒÅÍÌÅÎÉÊ/ïÓÉÒÏÔ¦ÌÉÊ',
+  'Project'                     => 'ðÒÏÅËÔ',
+  'Project Number missing!'     => 'îÅ ×ËÁÚÁÎÉÊ ÎÏÍÅÒ ÐÒÏÅËÔÕ!',
+  'Project deleted!'            => 'ðÒÏÅËÔ ×ÉÄÁÌÅÎÏ!',
+  'Project saved!'              => 'ðÒÏÅËÔ ÚÂÅÒÅÖÅÎÏ!',
+  'Projects'                    => 'ðÒÏÅËÔÉ',
+  'Save'                        => 'úÂÅÒÅÇÔÉ',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'îÏ×ÉÊ'                       => 'add',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  '÷ÉÄÁÌÉÔÉ'                    => 'delete',
+  'úÂÅÒÅÇÔÉ'                    => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/rc b/sql-ledger/locale/ua/rc
new file mode 100644 (file)
index 0000000..0a91d00
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'òÁÈÕÎÏË',
+  'Balance'                     => 'âÁÌÁÎÓ',
+  'Cleared Balance'             => 'ë¦ÎÃÅ×Å óÁÌØÄÏ',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Date'                        => 'äÁÔÁ',
+  'Deposit'                     => 'äÅÐÏÚÉÔ/÷ËÌÁÄ',
+  'Description'                 => 'ïÐÉÓ',
+  'Difference'                  => 'ò¦ÚÎÉÃÑ',
+  'Done'                        => 'úÒÏÂÌÅÎÏ',
+  'Exchangerate Difference'     => 'ò¦ÚÎÉÃÑ ëÕÒÓÕ ×ÁÌÀÔÉ',
+  'From'                        => '÷¦Ä / Ú',
+  'Out of balance!'             => 'îÅ ÚÂÁÌÁÎÓÏ×ÁÎÏ!',
+  'Payment'                     => 'ðÌÁÔ¦Ö',
+  'Reconciliation'              => 'õÚÇÏÄÖÅÎÎÑ',
+  'Select all'                  => '÷ÉÂÒÁÔÉ ×ÓÅ',
+  'Source'                      => 'äÖÅÒÅÌÏ',
+  'Statement Balance'           => 'âÁÌÁÎÓÏ×ÉÊ úצÔ',
+  'Update'                      => 'ðÏÎÏ×ÉÔÉ',
+  'to'                          => 'ÄÏ',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  'úÒÏÂÌÅÎÏ'                    => 'done',
+  '÷ÉÂÒÁÔÉ_×ÓÅ'                 => 'select_all',
+  'ðÏÎÏ×ÉÔÉ'                    => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ua/rp b/sql-ledger/locale/ua/rp
new file mode 100644 (file)
index 0000000..0553ba6
--- /dev/null
@@ -0,0 +1,120 @@
+$self{texts} = {
+  'AP Aging'                    => 'AP Aging (×ÉÔÒÁÔÉ)',
+  'AR Aging'                    => 'AR Aging (ÄÏÈÏÄÉ)',
+  'Account'                     => 'òÁÈÕÎÏË',
+  'Accounts'                    => 'òÁÈÕÎËÉ',
+  'Amount'                      => 'óÕÍÁ',
+  'Apr'                         => 'ËצÔÎÑ',
+  'April'                       => 'ëצÔÅÎØ',
+  'Attachment'                  => 'äÏÄÁÔÏË',
+  'Aug'                         => 'ÓÅÒÐÎÑ',
+  'August'                      => 'óÅÒÐÅÎØ',
+  'Balance'                     => 'âÁÌÁÎÓ',
+  'Balance Sheet'               => 'âÁÌÁÎÓ',
+  'Bcc'                         => 'ðÒÉ×ÁÔÎÁ ËÏЦѠÄÏ',
+  'Cash based'                  => 'çÏÔ¦×ËÏ×ÉÊ',
+  'Cc'                          => 'ëÏЦѠÄÏ',
+  'Compare to'                  => 'ðÏÒ¦×ÎÑÔÉ Ú',
+  'Continue'                    => 'ðÒÏÄÏ×ÖÉÔÉ',
+  'Copies'                      => 'ëÏЦÊ',
+  'Credit'                      => 'ëÒÅÄÉÔ',
+  'Current'                     => 'ðÏÔÏÞÎÉÊ',
+  'Customer'                    => 'ë̦¤ÎÔ',
+  'Date'                        => 'äÁÔÁ',
+  'Debit'                       => 'äÅÂÉÔ',
+  'Dec'                         => 'ÇÒÕÄÎÑ',
+  'December'                    => 'çÒÕÄÅÎØ',
+  'Decimalplaces'               => 'äÅÓÑÔÉÞΦ Í¦ÓÃÑ',
+  'Department'                  => 'Department',
+  'Description'                 => 'ïÐÉÓ',
+  'Due'                         => 'äÏ',
+  'E-mail'                      => 'åÌ. ÐÏÛÔÁ',
+  'E-mail Statement to'         => 'ðÏÓÌÁÔÉ ÐÏ ÅÌ. ÐÏÛÔ¦ ÄÏ',
+  'Feb'                         => 'ÌÀÔÏÇÏ',
+  'February'                    => 'ìÀÔÉÊ',
+  'From'                        => '÷¦Ä / Ú',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'òÏÚĦÌ',
+  'ID'                          => '¶ÄÅÎÔÉƦËÁæÊÎÉÊ ÎÏÍÅÒ',
+  'In-line'                     => '÷ËÌÀÞÅÎÏ (In-line)',
+  'Include in Report'           => 'äÏÄÁÔÉ ÄÏ úצÔÕ',
+  'Income Statement'            => 'úצԠÐÒÏ ÄÏÈÏÄÉ ¦ ×ÉÄÁÔËÉ',
+  'Invoice'                     => 'òÁÈÕÎÏË-ÆÁËÔÕÒÁ',
+  'Jan'                         => 'Ó¦ÞÎÑ',
+  'January'                     => 'Ó¦ÞÅÎØ',
+  'Jul'                         => 'ÌÉÐÎÑ',
+  'July'                        => 'ìÉÐÅÎØ',
+  'Jun'                         => 'ÞÅÒ×ÎÑ',
+  'June'                        => 'þÅÒ×ÅÎØ',
+  'Mar'                         => 'ÂÅÒÅÚÎÑ',
+  'March'                       => 'âÅÒÅÚÅÎØ',
+  'May'                         => 'ÔÒÁ×ÎÑ',
+  'May '                        => 'ôÒÁ×ÅÎØ',
+  'Message'                     => 'ðÏצÄÏÍÌÅÎÎÑ',
+  'N/A'                         => 'îÅ óÔÏÓÕ¤ÔØÓÑ',
+  'Nothing selected!'           => 'î¦ÞÏÇÏ ÎÅ ×ÉÂÒÁÎÏ!',
+  'Nov'                         => 'ÌÉÓÔÏÐÁÄÁ',
+  'November'                    => 'ìÉÓÔÏÐÁÄ',
+  'Oct'                         => 'ÖÏ×ÔÎÑ',
+  'October'                     => 'öÏ×ÔÅÎØ',
+  'PDF'                         => 'PDF ÆÏÒÍÁÔ',
+  'Payments'                    => 'ðÌÁÔÅÖ¦',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'îÁÄÒÕËÕ×ÁÔÉ',
+  'Printer'                     => 'ðÒÉÎÔÅÒ',
+  'Project Number'              => 'Project Number',
+  'Receipts'                    => 'ë×ÉÔÁÎæ§',
+  'Report for'                  => 'úצԠÄÌÑ',
+  'Retained Earnings'           => 'ðÒÉÂÕÔÏË (ÎÅÒÏÚÐÏĦÌÅÎÉÊ)',
+  'Screen'                      => 'åËÒÁÎ',
+  'Select all'                  => '÷ÉÂÒÁÔÉ ×ÓÅ',
+  'Select postscript or PDF!'   => '÷ÉÂÅÒ¦ÔØ postscript ÁÂÏ PDF ÆÏÒÍÁÔ!',
+  'Sep'                         => '×ÅÒÅÓÎÑ',
+  'September'                   => '÷ÅÒÅÓÅÎØ',
+  'Source'                      => 'äÖÅÒÅÌÏ',
+  'Standard'                    => 'óÔÁÎÄÁÒÔΦ',
+  'Statement'                   => 'úצÔ',
+  'Statement sent to'           => 'úצԠÐÏÓÌÁÎÏ ÄÏ',
+  'Statements sent to printer!' => 'úצԠÐÏÓÌÁÎÏ ÄÏ ÐÒÉÎÔÅÒÁ!',
+  'Subject'                     => 'ôÅÍÁ',
+  'Subtotal'                    => 'ð¦ÄÓÕÍÏË ÐÏ ÒÏÚĦÌÕ',
+  'Tax'                         => 'ðÏÄÁÔÏË',
+  'Tax collected'               => 'ú¦ÂÒÁÎÏ ÐÏÄÁÔ˦נ',
+  'Tax paid'                    => 'ðÏÄÁÔÏË ÚÁÐÌÁÞÅÎÏ',
+  'Total'                       => 'úÁÇÁÌØÎÁ óÕÍÁ',
+  'Trial Balance'               => 'ðÒÏÂÎÉÊ âÁÌÁÎÓ',
+  'Vendor'                      => 'ðÏÓÔÁÞÁÌØÎÉË',
+  'as at'                       => 'ÑË ×',
+  'collected on sales'          => 'Ú¦ÂÒÁÎÏ ÐÒÉ ÐÒÏÄÁÖÕ',
+  'for Period'                  => 'ÚÁ ðÅÒ¦ÏÄ',
+  'paid on purchases'           => 'ÚÁÐÌÁÞÅÎÏ ÎÁ ÐÏËÕÐËÉ',
+  'to'                          => 'ÄÏ',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_accounts'               => 'list_accounts',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'ðÒÏÄÏ×ÖÉÔÉ'                  => 'continue',
+  'åÌ._ÐÏÛÔÁ'                   => 'e_mail',
+  'îÁÄÒÕËÕ×ÁÔÉ'                 => 'print',
+  '÷ÉÂÒÁÔÉ_×ÓÅ'                 => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/COPYING b/sql-ledger/locale/ve/COPYING
new file mode 100644 (file)
index 0000000..11c55f3
--- /dev/null
@@ -0,0 +1,23 @@
+######################################################################
+# SQL-Ledger, Accounting Software
+# Copyright (c) 2001
+#
+# Spanish Texts (Venezuela):
+#
+#  Author: John Stoddart <jstypo@imagencolor.com.ve>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+
diff --git a/sql-ledger/locale/ve/LANGUAGE b/sql-ledger/locale/ve/LANGUAGE
new file mode 100644 (file)
index 0000000..182ea84
--- /dev/null
@@ -0,0 +1 @@
+Venezuelan Spanish
diff --git a/sql-ledger/locale/ve/admin b/sql-ledger/locale/ve/admin
new file mode 100644 (file)
index 0000000..19be1bf
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'Access Control'              => 'Control de Acceso',
+  'Accounting'                  => 'Contabilidad',
+  'Add User'                    => 'Agregar Usuario',
+  'Address'                     => 'Dirección',
+  'Administration'              => 'Administración',
+  'Administrator'               => 'Administrador',
+  'All Datasets up to date!'    => 'Bases de datos actualizadas!',
+  'Change Admin Password'       => 'Cambiar contraseña del Administrador',
+  'Change Password'             => 'Cambiar Contraseña',
+  'Character Set'               => 'Conjunto de Caracteres',
+  'Click on login name to edit!' => 'Haga click sobre el login para editar',
+  'Company'                     => 'Compañía',
+  'Connect to'                  => 'Conectar a',
+  'Continue'                    => 'Continuar',
+  'Create Chart of Accounts'    => 'Crear Plan de Cuentas',
+  'Create Dataset'              => 'Crear base de datos',
+  'DBI not installed!'          => 'DBI no ha sido instalado!',
+  'Database'                    => 'Base de Datos',
+  'Database Administration'     => 'Administración de base de datos',
+  'Database Driver not checked!' => 'Manejador no seleccionado!',
+  'Database User missing!'      => 'Falta usuario de base de datos!',
+  'Dataset'                     => 'Base de datos',
+  'Dataset missing!'            => 'Falta base de datos!',
+  'Dataset updated!'            => 'Base de datos actualizada!',
+  'Date Format'                 => 'Formato Fecha',
+  'Delete'                      => 'Borrar',
+  'Delete Dataset'              => 'Borrar base de datos',
+  'Directory'                   => 'Directorio',
+  'Driver'                      => 'Manejador',
+  'Dropdown Limit'              => 'Límite menu dropdown',
+  'E-mail'                      => 'E-mail',
+  'Edit User'                   => 'Editar Usuario',
+  'Existing Datasets'           => 'Bases de datos existentes',
+  'Fax'                         => 'Fax',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Falta nombre del Host!',
+  'Incorrect Password!'         => 'Contraseña equivocada',
+  'Language'                    => 'Idioma',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Deje en blanco los campos Host y Puerto si no requiere una conección remota',
+  'Login'                       => 'Login',
+  'Multibyte Encoding'          => 'Codificación conjunto de caracteres',
+  'Name'                        => 'Nombre',
+  'New Templates'               => 'Plantillas Nuevas',
+  'No Database Drivers available!' => 'No hay manejadores para base de datos!',
+  'No Dataset selected!'        => 'Base de datos no seleccionada!',
+  'Nothing to delete!'          => 'Nada para borrar!',
+  'Number Format'               => 'Formato Numérico',
+  'Oracle Database Administration' => 'Administración bases de datos Oracle',
+  'Password'                    => 'Contraseña',
+  'Password changed!'           => 'Contraseña cambiada!',
+  'Pg Database Administration'  => 'Administración bases de datos Pg',
+  'Phone'                       => 'Teléfono',
+  'Port'                        => 'Número de Puerto',
+  'Port missing!'               => 'Falta número de puerto',
+  'Printer'                     => 'Impresora',
+  'Save'                        => 'Guardar',
+  'Select a Dataset to delete and press "Continue"' => 'Seleccione base de datos a borrar y pulse "Continue"',
+  'Setup Templates'             => 'Configurar Plantillas',
+  'Ship via'                    => 'Envía vía',
+  'Signature'                   => 'Firma',
+  'Stylesheet'                  => 'Hoja de Estilo',
+  'Templates'                   => 'Plantillas',
+  'The following Datasets are not in use and can be deleted' => 'Las siguientes bases de datos no están en uso y pueden ser borradas',
+  'The following Datasets need to be updated' => 'Las siguientes bases de datos requieren actualización',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Chequeo preliminar. En esta etapa no se creará ni se borrará nada!',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Para agregar un usuario a un grupo, edite un nombre, cambie el login y guárdelo de nuevo. Un nuevo usuario con las mismas variables se creará bajo el nuevo login.',
+  'Update Dataset'              => 'Actualizar base de datos',
+  'Use Templates'               => 'Use Plantilla',
+  'User'                        => 'Usuario',
+  'User deleted!'               => 'Usuario borrado!',
+  'User saved!'                 => 'Usuario guardado!',
+  'Version'                     => 'Versión',
+  'You must enter a host and port for local and remote connections!' => 'Debe ingresar un host y un puerto para conecciones locales y remotas!',
+  'does not exist'              => 'no existe',
+  'is already a member!'        => 'ya es miembro!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => 'locked!',
+  'successfully created!'       => 'creado!',
+  'successfully deleted!'       => 'borrado!',
+  'website'                     => 'en internet',
+};
+
+$self{subs} = {
+  'add_user'                    => 'add_user',
+  'adminlogin'                  => 'adminlogin',
+  'change_admin_password'       => 'change_admin_password',
+  'change_password'             => 'change_password',
+  'check_password'              => 'check_password',
+  'continue'                    => 'continue',
+  'create_dataset'              => 'create_dataset',
+  'dbcreate'                    => 'dbcreate',
+  'dbdelete'                    => 'dbdelete',
+  'dbdriver_defaults'           => 'dbdriver_defaults',
+  'dbselect_source'             => 'dbselect_source',
+  'dbupdate'                    => 'dbupdate',
+  'delete'                      => 'delete',
+  'delete_dataset'              => 'delete_dataset',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'get_value'                   => 'get_value',
+  'list_users'                  => 'list_users',
+  'login'                       => 'login',
+  'login_name'                  => 'login_name',
+  'oracle_database_administration' => 'oracle_database_administration',
+  'pg_database_administration'  => 'pg_database_administration',
+  'save'                        => 'save',
+  'update_dataset'              => 'update_dataset',
+  'agregar_usuario'             => 'add_user',
+  'cambiar_contraseña_del_administrador' => 'change_admin_password',
+  'cambiar_contraseña'          => 'change_password',
+  'continuar'                   => 'continue',
+  'crear_base_de_datos'         => 'create_dataset',
+  'borrar'                      => 'delete',
+  'borrar_base_de_datos'        => 'delete_dataset',
+  'login'                       => 'login',
+  'administración_bases_de_datos_oracle' => 'oracle_database_administration',
+  'administración_bases_de_datos_pg' => 'pg_database_administration',
+  'guardar'                     => 'save',
+  'actualizar_base_de_datos'    => 'update_dataset',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/all b/sql-ledger/locale/ve/all
new file mode 100644 (file)
index 0000000..b422b8c
--- /dev/null
@@ -0,0 +1,491 @@
+# These are all the texts to build the translations files.
+# The file has the form of 'english text'  => 'foreign text',
+# you can add the translation in this file or in the 'missing' file
+# run locales.pl from this directory to rebuild the translation files
+
+$self{texts} = {
+  'AP'                          => 'CXP',
+  'AP Aging'                    => 'Vencimientos',
+  'AP Transaction'              => 'Cuenta por Pagar',
+  'AP Transactions'             => 'Cuentas por Pagar',
+  'AR'                          => 'CXC',
+  'AR Aging'                    => 'Vencimientos',
+  'AR Transaction'              => 'Cuenta por Cobrar',
+  'AR Transactions'             => 'Cuentas por Cobrar',
+  'About'                       => 'Acerca de',
+  'Access Control'              => 'Control de Acceso',
+  'Account'                     => 'Cuenta',
+  'Account Number'              => 'Número de Cuenta',
+  'Account Number missing!'     => 'Falta Número de Cuenta!',
+  'Account Type'                => 'Tipo de Cuenta',
+  'Account Type missing!'       => 'Falta Tipo de Cuenta!',
+  'Account deleted!'            => 'Cuenta borrada!',
+  'Account saved!'              => 'Cuenta guardada!',
+  'Accounting'                  => 'Contabilidad',
+  'Accounting Menu'             => 'Menú de Contabilidad',
+  'Accounts'                    => 'Cuentas',
+  'Active'                      => 'Activa',
+  'Add'                         => 'Agregar',
+  'Add Account'                 => 'Agregar Cuenta',
+  'Add Accounts Payables Transaction' => 'Agregar Cuenta por Pagar',
+  'Add Accounts Receivables Transaction' => 'Agregar Cuenta por Cobrar',
+  'Add Assembly'                => 'Agregar Conjunto',
+  'Add Customer'                => 'Agregar Cliente',
+  'Add GIFI'                    => 'Agregar GIFI',
+  'Add General Ledger Transaction' => 'Agregar Transacción al Mayor General',
+  'Add Part'                    => 'Agregar Item',
+  'Add Project'                 => 'Agregar Proyecto',
+  'Add Purchase Invoice'        => 'Agregar Factura de Compra',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Invoice'           => 'Agregar Factura de Venta',
+  'Add Sales Order'             => 'Agregar Pedido',
+  'Add Service'                 => 'Agregar Servicio',
+  'Add Transaction'             => 'Agregar Transacción',
+  'Add User'                    => 'Agregar Usuario',
+  'Add Vendor'                  => 'Agregar Proveedor',
+  'Address'                     => 'Dirección',
+  'Administration'              => 'Administración',
+  'Administrator'               => 'Administrador',
+  'All'                         => 'Todos',
+  'All Datasets up to date!'    => 'Bases de datos actualizadas!',
+  'Amount'                      => 'Monto',
+  'Amount Due'                  => 'Monto Vencido',
+  'Amount does not equal applied!' => 'Monto no es igual!',
+  'Amount missing!'             => 'Falta monto!',
+  'Applied'                     => 'Aplicado',
+  'Apr'                         => 'abr',
+  'April'                       => 'de abril',
+  'Are you sure you want to delete Invoice Number' => '¿Seguro que desea borrar Factura?',
+  'Are you sure you want to delete Order Number' => '¿Seguro que desea borrar Orden de Compra/Pedido?',
+  'Are you sure you want to delete Transaction' => '¿Seguro que desea borrar Transacción?',
+  'Assemblies'                  => 'Conjuntos',
+  'Assemblies restocked!'       => 'Conjuntos re-inventariados',
+  'Assembly Number missing!'    => 'Falta Número Conjunto!',
+  'Asset'                       => 'Activo',
+  'Attachment'                  => 'Anexo',
+  'Audit Control'               => 'Control de Auditoría',
+  'Aug'                         => 'ago',
+  'August'                      => 'de agosto',
+  'BOM'                         => 'Lista de Materiales',
+  'Backup'                      => 'Respaldos',
+  'Backup sent to'              => 'Respaldo enviado a',
+  'Balance'                     => 'Balance',
+  'Balance Sheet'               => 'Hoja de Balance',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Ubicación',
+  'Books are open'              => 'Libros aperturados',
+  'Bought'                      => 'Comprado',
+  'Business Number'             => 'RIF/NIT/CI',
+  'C'                           => 'C',
+  'COGS'                        => 'Costo Perpetuo',
+  'Cannot delete account!'      => 'No puede borrar cuenta!',
+  'Cannot delete customer!'     => 'No puede borrar cliente!',
+  'Cannot delete default account!' => 'No puede borrar cuenta "default"!',
+  'Cannot delete invoice!'      => 'No puede borraar factura!',
+  'Cannot delete item already invoiced!' => 'No puede borrar ítem facturado!',
+  'Cannot delete item on order!' => 'No puede borrar ítem pedido!',
+  'Cannot delete item which is part of an assembly!' => 'No puede borrar ítem parte de conjunto!',
+  'Cannot delete item!'         => 'No puede borrar ítem!',
+  'Cannot delete order!'        => 'No puede borrar pedido!',
+  'Cannot delete transaction!'  => 'No puede borrar transacción!',
+  'Cannot delete vendor!'       => 'No puede borrar proveedor!',
+  'Cannot have a value in both Debit and Credit!' => 'No puede haber Débito y Crédito simultáneamente!',
+  'Cannot post a transaction without a value!' => 'No puede registrar transacción sin monto!',
+  'Cannot post invoice for a closed period!' => 'No puede registrar factura para ejercicio cerrado!',
+  'Cannot post invoice!'        => 'No puede registrar factura!',
+  'Cannot post payment for a closed period!' => 'No puede registrar pago para ejercicio cerrado',
+  'Cannot post payment!'        => 'No puede registrar pago!',
+  'Cannot post transaction for a closed period!' => 'No puede registrar transacción para ejercicio cerrado!',
+  'Cannot post transaction!'    => 'No puede registrar transacción!',
+  'Cannot process payment for a closed period!' => 'No puede procesar pago para ejercicio cerrado!',
+  'Cannot save account!'        => 'No puede guardar cuenta!',
+  'Cannot save order!'          => 'No puede guardar órden!',
+  'Cannot save preferences!'    => 'No puede guardar preferencias!',
+  'Cannot stock assemblies!'    => 'No puede inventariar conjuntos!',
+  'Cash'                        => 'Caja',
+  'Cash based'                  => 'Cash based',
+  'Cc'                          => 'Cc',
+  'Change Admin Password'       => 'Cambiar contraseña del Administrador',
+  'Change Password'             => 'Cambiar Contraseña',
+  'Character Set'               => 'Conjunto de Caracteres',
+  'Chart of Accounts'           => 'Plan de Cuentas',
+  'Check'                       => 'Cheque',
+  'Check printed!'              => 'Cheque impreso!',
+  'Check printing failed!'      => 'No se pudo imprimir cheque!',
+  'Cleared Balance'             => 'Cleared Balance',
+  'Click on login name to edit!' => 'Haga click sobre el login para editar',
+  'Close Books up to'           => 'Cerrar ejercicio hasta',
+  'Closed'                      => 'Cerrado',
+  'Company'                     => 'Compañía',
+  'Compare to'                  => 'Comparar a',
+  'Confirm!'                    => 'Confirmar!',
+  'Connect to'                  => 'Conectar a',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Copy to COA'                 => 'Copiar a Plan de Cuentas',
+  'Create Chart of Accounts'    => 'Crear Plan de Cuentas',
+  'Create Dataset'              => 'Crear base de datos',
+  'Credit'                      => 'Crédito',
+  'Credit Limit'                => 'Límite de Crédito',
+  'Curr'                        => 'Div',
+  'Currency'                    => 'Divisa',
+  'Current'                     => 'Actual',
+  'Customer'                    => 'Cliente',
+  'Customer deleted!'           => 'Cliente borrado!',
+  'Customer missing!'           => 'Falta cliente!',
+  'Customer not on file!'       => 'Cliente no existe en archivo!',
+  'Customer saved!'             => 'Cliente guardado!',
+  'Customers'                   => 'Clientes',
+  'DBI not installed!'          => 'DBI no ha sido instalado!',
+  'Database'                    => 'Base de Datos',
+  'Database Administration'     => 'Administración de base de datos',
+  'Database Driver not checked!' => 'Manejador no seleccionado!',
+  'Database Host'               => 'Servidor de base de datos',
+  'Database User missing!'      => 'Falta usuario de base de datos!',
+  'Dataset'                     => 'Base de datos',
+  'Dataset missing!'            => 'Falta base de datos!',
+  'Dataset updated!'            => 'Base de datos actualizada!',
+  'Date'                        => 'Fecha',
+  'Date Due'                    => 'Vencimiento',
+  'Date Format'                 => 'Formato Fecha',
+  'Date Paid'                   => 'Fecha Pago',
+  'Date missing!'               => 'Falta fecha!',
+  'Debit'                       => 'Débito',
+  'Debit and credit out of balance!' => 'Débito y Crédito fuera de balance!',
+  'Dec'                         => 'dic',
+  'December'                    => 'de diciembre',
+  'Decimalplaces'               => 'Posiciones decimales',
+  'Delete'                      => 'Borrar',
+  'Delete Account'              => 'Borrar Cuenta',
+  'Delete Dataset'              => 'Borrar base de datos',
+  'Delivery Date'               => 'Fecha de Entrega',
+  'Deposit'                     => 'Deposit',
+  'Description'                 => 'Descripción',
+  'Difference'                  => 'Diferencia',
+  'Directory'                   => 'Directorio',
+  'Discount'                    => 'Descuento',
+  'Done'                        => 'Listo',
+  'Drawing'                     => 'Retiro',
+  'Driver'                      => 'Manejador',
+  'Dropdown Limit'              => 'Límite menu dropdown',
+  'Due'                         => 'Vence',
+  'Due Date'                    => 'Vencimiento',
+  'Due Date missing!'           => 'Falta Vencimiento!',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'Enviar estado de cuenta por E-mail a',
+  'E-mail address missing!'     => 'Falta dirección E-mail!',
+  'Edit'                        => 'Editar',
+  'Edit Account'                => 'Editar Cuenta',
+  'Edit Accounts Payables Transaction' => 'Editar Transacción Cuentas por Pagar',
+  'Edit Accounts Receivables Transaction' => 'Editar Transacción Cuentas por Cobrar',
+  'Edit Assembly'               => 'Editar Conjunto',
+  'Edit Customer'               => 'Editar Cliente',
+  'Edit GIFI'                   => 'Editar GIFI',
+  'Edit General Ledger Transaction' => 'Editar Transacción de Mayor General',
+  'Edit Part'                   => 'Editar Item',
+  'Edit Preferences for'        => 'Editar Preferencias para',
+  'Edit Project'                => 'Editar Proyecto',
+  'Edit Purchase Invoice'       => 'Editar Factura de Compra',
+  'Edit Purchase Order'         => 'Editar Orden de Compra',
+  'Edit Sales Invoice'          => 'Editar Factura de Venta',
+  'Edit Sales Order'            => 'Editar Pedido',
+  'Edit Service'                => 'Editar Servicio',
+  'Edit Template'               => 'Editar Plantilla',
+  'Edit User'                   => 'Editar Usuario',
+  'Edit Vendor'                 => 'Editar Proveedor',
+  'Employee'                    => 'Empleado',
+  'Enforce transaction reversal for all dates' => 'Obligar reverso de transacciones para todas las fechas',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Ingrese símbolo de hasta 3 letras para divisas nativa y extranjeras',
+  'Equity'                      => 'Capital',
+  'Exch'                        => 'Tasa',
+  'Exchangerate'                => 'Tasa de Cambio',
+  'Exchangerate Difference'     => 'Diferencial Dambiario',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Existing Datasets'           => 'Bases de datos existentes',
+  'Expense'                     => 'Egreso',
+  'Expense Account'             => 'Cuenta de Gasto',
+  'Expense/Asset'               => 'Egreso/Activo',
+  'Extended'                    => 'Extendido',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'feb',
+  'February'                    => 'de febrero',
+  'Foreign Exchange Gain'       => 'Ganancia Cambiaria',
+  'Foreign Exchange Loss'       => 'Pérdida Cambiaria',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI borrado!',
+  'GIFI missing!'               => 'Falta GIFI!',
+  'GIFI saved!'                 => 'GIFI guardado!',
+  'GL Transaction'              => 'Transacción de mayor',
+  'General Ledger'              => 'Mayor General',
+  'Goods & Services'            => 'Bienes y Servicios',
+  'HTML Templates'              => 'Plantillas HTML',
+  'Heading'                     => 'Encabezado',
+  'Host'                        => 'Host',
+  'Hostname missing!'           => 'Falta nombre del Host!',
+  'ID'                          => 'ID',
+  'Image'                       => 'Imagen',
+  'In-line'                     => 'Incorporado',
+  'Include in Report'           => 'Incluya en Reporte',
+  'Include in drop-down menus'  => 'Incluya en menús "drop-down"',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Incluir cuenta en pantallas Cliente/Proveedor para señalar como contribuyente?',
+  'Income'                      => 'Ingreso',
+  'Income Account'              => 'Cuenta de Ingreso',
+  'Income Statement'            => 'Estado de Cuentas de Ingreso',
+  'Incorrect Dataset version!'  => 'Versión incorrecta de base de datos!',
+  'Incorrect Password!'         => 'Contraseña equivocada',
+  'Individual Items'            => 'Items Individuales',
+  'Inventory'                   => 'Inventario',
+  'Inventory Account'           => 'Cuenta de Inventario',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Existencia debe ser cero antes de hacer obsoleto a este conjunto!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Existencia debe ser cero antes de hacer obsoleto este ítem!',
+  'Inventory quantity must be zero!' => 'Existencia debe ser cero!',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha Factura',
+  'Invoice Date missing!'       => 'Falta Fecha Factura!',
+  'Invoice Number'              => 'Número Factura',
+  'Invoice Number missing!'     => 'Falta Número Factura!',
+  'Invoice deleted!'            => 'Factura borrada!',
+  'Invoice posted!'             => 'Factura registrada!',
+  'Invoices'                    => 'Facturas',
+  'Is this a summary account to record' => 'Registrar en cuenta de resumen ',
+  'Item deleted!'               => 'Item borrado!',
+  'Item not on file!'           => 'Item no archivado!',
+  'Jan'                         => 'ene',
+  'January'                     => 'de enero',
+  'Jul'                         => 'jul',
+  'July'                        => 'de julio',
+  'Jun'                         => 'jun',
+  'June'                        => 'de junio',
+  'LaTeX Templates'             => 'Plantillas LaTeX',
+  'Language'                    => 'Idioma',
+  'Last Cost'                   => 'Ultimo Costo',
+  'Last Invoice Number'         => 'Ultima Factura Emitida',
+  'Last Numbers & Default Accounts' => 'Ultimos Números y Cuentas por Defecto',
+  'Last Purchase Order Number'  => 'Ultimo número Orden de Compra',
+  'Last Sales Order Number'     => 'Ultimo número Pedido',
+  'Leave host and port field empty unless you want to make a remote connection.' => 'Deje en blanco los campos Host y Puerto si no requiere una conección remota',
+  'Liability'                   => 'Pasivo',
+  'Licensed to'                 => 'Licenciatario',
+  'Line Total'                  => 'Total línea',
+  'Link'                        => 'Vinculado a',
+  'Link Accounts'               => 'Vincular Cuentas',
+  'List Accounts'               => 'Listar cuentas',
+  'List GIFI'                   => 'Listar GIFI',
+  'List Price'                  => 'Precio de Lista',
+  'List Transactions'           => 'Listar Transacciones',
+  'Login'                       => 'Login',
+  'Logout'                      => 'Salir del sistema',
+  'Make'                        => 'Marca',
+  'Mar'                         => 'mar',
+  'March'                       => 'de marzo',
+  'May'                         => 'may',
+  'May '                        => 'de mayo',
+  'Message'                     => 'Mensaje',
+  'Microfiche'                  => 'Microficha',
+  'Model'                       => 'Modelo',
+  'Multibyte Encoding'          => 'Codificación conjunto de caracteres',
+  'N/A'                         => 'N/D',
+  'Name'                        => 'Nombre',
+  'Name missing!'               => 'Falta nombre!',
+  'New Templates'               => 'Plantillas Nuevas',
+  'No'                          => ' No ',
+  'No Database Drivers available!' => 'No hay manejadores para base de datos!',
+  'No Dataset selected!'        => 'Base de datos no seleccionada!',
+  'No email address for'        => 'Falta dirección email para',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Comentario',
+  'Nothing applied!'            => 'Nada aplicado!',
+  'Nothing selected!'           => 'Nada seleccionado!',
+  'Nothing to delete!'          => 'Nada para borrar!',
+  'Nov'                         => 'nov',
+  'November'                    => 'de noviembre',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Formato Numérico',
+  'Number missing in Row'       => 'Falta número en Hilera',
+  'O'                           => 'O',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'oct',
+  'October'                     => 'de octubre',
+  'On Hand'                     => 'Existencia',
+  'On Order'                    => 'Pedido',
+  'Open'                        => 'Abierto',
+  'Oracle Database Administration' => 'Administración bases de datos Oracle',
+  'Order'                       => 'Orden',
+  'Order Date'                  => 'Fecha Pedido',
+  'Order Date missing!'         => 'Falta Fecha Pedido!',
+  'Order Entry'                 => 'Pedidos<br>Ordenes de Compra',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'Falta Número de Orden',
+  'Order deleted!'              => 'Orden borrada!',
+  'Order saved!'                => 'Orden guardada!',
+  'Ordered'                     => 'Pedido',
+  'Orphaned'                    => 'Huérfano',
+  'Out of balance!'             => 'Fuera de balance!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => 'Falta Fecha en Nota de Entrega',
+  'Packing List Number missing!' => 'Falta Número en Nota de Entrega',
+  'Paid'                        => 'Pagado',
+  'Paid in full'                => 'Cancelado',
+  'Part'                        => 'Item',
+  'Part Number missing!'        => 'Falta Número de Item!',
+  'Parts'                       => 'Items',
+  'Parts Inventory'             => 'Inventario de Items',
+  'Password'                    => 'Contraseña',
+  'Password changed!'           => 'Contraseña cambiada!',
+  'Payables'                    => 'X Pagar',
+  'Payment'                     => 'Pago',
+  'Payment date missing!'       => 'Falta Fecha de Pago',
+  'Payment posted!'             => 'Pago registrado!',
+  'Payments'                    => 'Pagos',
+  'Pg Database Administration'  => 'Administración bases de datos Pg',
+  'Phone'                       => 'Teléfono',
+  'Port'                        => 'Número de Puerto',
+  'Port missing!'               => 'Falta número de puerto',
+  'Post'                        => 'Registrar',
+  'Post as new'                 => 'Registrar como nuevo',
+  'Postscript'                  => 'Postscript',
+  'Preferences'                 => 'Preferencias',
+  'Preferences saved!'          => 'Preferencias guardadas!',
+  'Price'                       => 'Precio',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Proyecto',
+  'Project Number missing!'     => 'Falta número de proyecto!',
+  'Project deleted!'            => 'Proyecto borrado!',
+  'Project not on file!'        => 'Proyecto no archivado!',
+  'Project saved!'              => 'Proyecto guardado!',
+  'Projects'                    => 'Proyectos',
+  'Purchase Invoice'            => 'Factura de Compra',
+  'Purchase Order'              => 'Orden de Compra',
+  'Purchase Orders'             => 'Ordenes de Compra',
+  'Qty'                         => 'Cnt',
+  'ROP'                         => 'Existencia mínima',
+  'Rate'                        => 'Tasa',
+  'Recd'                        => 'Rec',
+  'Receipt'                     => 'Ingreso',
+  'Receipts'                    => 'Ingresos',
+  'Receivables'                 => 'X Cobrar',
+  'Reconciliation'              => 'Conciliación',
+  'Record in'                   => 'Registrar en',
+  'Reference'                   => 'Referencia',
+  'Reference missing!'          => 'Falta referencia!',
+  'Remaining'                   => 'Quedan',
+  'Report for'                  => 'Reporte de',
+  'Reports'                     => 'Reportes',
+  'Required by'                 => 'Requerido para el',
+  'Retained Earnings'           => 'Ganancias Retenidas',
+  'Sales'                       => 'Ventas',
+  'Sales Invoice'               => 'Factura de Venta',
+  'Sales Order'                 => 'Pedido',
+  'Sales Orders'                => 'Pedidos',
+  'Save'                        => 'Guardar',
+  'Save as new'                 => 'Guardar como nuevo',
+  'Save to File'                => 'Respaldar a Archivo',
+  'Screen'                      => 'Pantalla',
+  'Select a Dataset to delete and press "Continue"' => 'Seleccione base de datos a borrar y pulse "Continue"',
+  'Select all'                  => 'Seleccione todos',
+  'Select from one of the items below' => 'Seleccione uno de los ítems listados',
+  'Select from one of the names below' => 'Seleccione de uno de los nombres a continuación',
+  'Select from one of the projects below' => 'Seleccione de uno de los proyectos a continuación',
+  'Select postscript or PDF!'   => 'Seleccione postscript o PDF',
+  'Sell Price'                  => 'Precio de Venta',
+  'Send by E-Mail'              => 'Enviar por E-Mail',
+  'Sep'                         => 'sep',
+  'September'                   => 'de septiembre',
+  'Service'                     => 'Servicio',
+  'Service Items'               => 'Inventario de Servicios',
+  'Service Number missing!'     => 'Falta Número de Servicio!',
+  'Services'                    => 'Servicios',
+  'Setup Templates'             => 'Configurar Plantillas',
+  'Ship'                        => 'Envíe',
+  'Ship to'                     => 'Envíe a',
+  'Ship via'                    => 'Envía vía',
+  'Short'                       => 'Corto',
+  'Signature'                   => 'Firma',
+  'Sold'                        => 'Vendido',
+  'Source'                      => 'Referencia',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Estado de Cuenta',
+  'Statement Balance'           => 'Balance Estado de Cuenta',
+  'Statement sent to'           => 'Estado de Cuenta enviado a',
+  'Statements sent to printer!' => 'Estados de Cuenta enviados a impresora!',
+  'Stock Assembly'              => 'Reponer Conjuntos',
+  'Stylesheet'                  => 'Hoja de Estilo',
+  'Subject'                     => 'Materia',
+  'Subtotal'                    => 'Subtotal',
+  'System'                      => 'Sistema',
+  'Tax'                         => 'ISV',
+  'Tax Accounts'                => 'Cuentas de Impuesto',
+  'Tax Included'                => 'Impuesto Incluido',
+  'Tax collected'               => 'Impuesto recaudado',
+  'Tax paid'                    => 'Impuesto pagado',
+  'Taxable'                     => 'Base imponible',
+  'Template saved!'             => 'Plantilla guardada!',
+  'Templates'                   => 'Plantillas',
+  'Terms: Net'                  => 'Crédito a',
+  'The following Datasets are not in use and can be deleted' => 'Las siguientes bases de datos no están en uso y pueden ser borradas',
+  'The following Datasets need to be updated' => 'Las siguientes bases de datos requieren actualización',
+  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'Chequeo preliminar. En esta etapa no se creará ni se borrará nada!',
+  'To'                          => 'Hasta',
+  'To add a user to a group edit a name, change the login name and save.  A new user with the same variables will then be saved under the new login name.' => 'Para agregar un usuario a un grupo, edite un nombre, cambie el login y guárdelo de nuevo. Un nuevo usuario con las mismas variables se creará bajo el nuevo login.',
+  'Top Level'                   => 'Nivel superior',
+  'Total'                       => 'Total',
+  'Transaction Date missing!'   => 'Falta Fecha Transacción!',
+  'Transaction deleted!'        => 'Transacción borrada!',
+  'Transaction posted!'         => 'Transacción registrada!',
+  'Transaction reversal enforced for all dates' => 'Reverso de transacciones obligadas para todas la fechas',
+  'Transaction reversal enforced up to' => 'Reverso de transacciones obligadas hasta',
+  'Transactions'                => 'Transacciones',
+  'Transactions exist, cannot delete customer!' => 'No podemos borrar cliente, existen transacciones!',
+  'Transactions exist, cannot delete vendor!' => 'No podemos borrar proveedor, existen transacciones!',
+  'Transactions exist; cannot delete account!' => 'No podemos borrar cuenta, existen transacciones!',
+  'Trial Balance'               => 'Balance de Comprobación',
+  'Unit'                        => 'Unidad',
+  'Unit of measure'             => 'Unidad de medida',
+  'Update'                      => 'Actualizar',
+  'Update Dataset'              => 'Actualizar base de datos',
+  'Updated'                     => 'Actalizado',
+  'Use Templates'               => 'Use Plantilla',
+  'User'                        => 'Usuario',
+  'User deleted!'               => 'Usuario borrado!',
+  'User saved!'                 => 'Usuario guardado!',
+  'Vendor'                      => 'Proveedor',
+  'Vendor deleted!'             => 'Proveedor borrado!',
+  'Vendor missing!'             => 'Falta proveedor',
+  'Vendor not on file!'         => 'Proveedor no está en archivo!',
+  'Vendor saved!'               => 'Proveedor guardado!',
+  'Vendors'                     => 'Proveedores',
+  'Version'                     => 'Versión',
+  'Weight'                      => 'Peso',
+  'Weight Unit'                 => 'Unidad de Peso',
+  'What type of item is this?'  => '¿Qué tipo de ítem es éste?',
+  'Year End'                    => 'Cierre',
+  'Yes'                         => ' Sí ',
+  'You are logged out!'         => 'Ha salido del sistema!',
+  'You did not enter a name!'   => 'No se ingresó un nombre!',
+  'You must enter a host and port for local and remote connections!' => 'Debe ingresar un host y un puerto para conecciones locales y remotas!',
+  'as at'                       => 'Al',
+  'collected on sales'          => 'recaudado sobre ventas',
+  'days'                        => 'días',
+  'does not exist'              => 'no existe',
+  'ea'                          => 'cu',
+  'emailed to'                  => 'enviado por email a',
+  'for Period'                  => 'para el período',
+  'hr'                          => 'hr',
+  'is already a member!'        => 'ya es miembro!',
+  'is not a member!'            => 'no es miembro!',
+  'localhost'                   => 'localhost',
+  'locked!'                     => '',
+  'paid on purchases'           => 'pagado sobre compras',
+  'sent to printer'             => 'enviado a impresora',
+  'successfully created!'       => 'creado!',
+  'successfully deleted!'       => 'borrado!',
+  'to'                          => 'a',
+  'website'                     => 'en internet',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/am b/sql-ledger/locale/ve/am
new file mode 100644 (file)
index 0000000..3002447
--- /dev/null
@@ -0,0 +1,139 @@
+$self{texts} = {
+  'AP'                          => 'CXP',
+  'AR'                          => 'CXC',
+  'Account'                     => 'Cuenta',
+  'Account Number'              => 'Número de Cuenta',
+  'Account Number missing!'     => 'Falta Número de Cuenta!',
+  'Account Type'                => 'Tipo de Cuenta',
+  'Account Type missing!'       => 'Falta Tipo de Cuenta!',
+  'Account deleted!'            => 'Cuenta borrada!',
+  'Account saved!'              => 'Cuenta guardada!',
+  'Add Account'                 => 'Agregar Cuenta',
+  'Add GIFI'                    => 'Agregar GIFI',
+  'Address'                     => 'Dirección',
+  'Asset'                       => 'Activo',
+  'Audit Control'               => 'Control de Auditoría',
+  'Backup sent to'              => 'Respaldo enviado a',
+  'Books are open'              => 'Libros aperturados',
+  'Business Number'             => 'RIF/NIT/CI',
+  'COGS'                        => 'Costo Perpetuo',
+  'Cannot delete account!'      => 'No puede borrar cuenta!',
+  'Cannot delete default account!' => 'No puede borrar cuenta "default"!',
+  'Cannot save account!'        => 'No puede guardar cuenta!',
+  'Cannot save preferences!'    => 'No puede guardar preferencias!',
+  'Character Set'               => 'Conjunto de Caracteres',
+  'Chart of Accounts'           => 'Plan de Cuentas',
+  'Close Books up to'           => 'Cerrar ejercicio hasta',
+  'Company'                     => 'Compañía',
+  'Continue'                    => 'Continuar',
+  'Copy to COA'                 => 'Copiar a Plan de Cuentas',
+  'Credit'                      => 'Crédito',
+  'Date Format'                 => 'Formato Fecha',
+  'Debit'                       => 'Débito',
+  'Delete'                      => 'Borrar',
+  'Delete Account'              => 'Borrar Cuenta',
+  'Description'                 => 'Descripción',
+  'Dropdown Limit'              => 'Límite menu dropdown',
+  'E-mail'                      => 'E-mail',
+  'Edit'                        => 'Editar',
+  'Edit Account'                => 'Editar Cuenta',
+  'Edit GIFI'                   => 'Editar GIFI',
+  'Edit Preferences for'        => 'Editar Preferencias para',
+  'Edit Template'               => 'Editar Plantilla',
+  'Enforce transaction reversal for all dates' => 'Obligar reverso de transacciones para todas las fechas',
+  'Enter up to 3 letters separated by a colon (i.e CAD:USD:EUR) for your native and foreign currencies' => 'Ingrese símbolo de hasta 3 letras para divisas nativa y extranjeras',
+  'Equity'                      => 'Capital',
+  'Expense'                     => 'Egreso',
+  'Expense Account'             => 'Cuenta de Gasto',
+  'Expense/Asset'               => 'Egreso/Activo',
+  'Fax'                         => 'Fax',
+  'Foreign Exchange Gain'       => 'Ganancia Cambiaria',
+  'Foreign Exchange Loss'       => 'Pérdida Cambiaria',
+  'GIFI'                        => 'GIFI',
+  'GIFI deleted!'               => 'GIFI borrado!',
+  'GIFI missing!'               => 'Falta GIFI!',
+  'GIFI saved!'                 => 'GIFI guardado!',
+  'Heading'                     => 'Encabezado',
+  'Include in drop-down menus'  => 'Incluya en menús "drop-down"',
+  'Include this account on the customer/vendor forms to flag customer/vendor as taxable?' => 'Incluir cuenta en pantallas Cliente/Proveedor para señalar como contribuyente?',
+  'Income'                      => 'Ingreso',
+  'Income Account'              => 'Cuenta de Ingreso',
+  'Inventory'                   => 'Inventario',
+  'Inventory Account'           => 'Cuenta de Inventario',
+  'Is this a summary account to record' => 'Registrar en cuenta de resumen ',
+  'Language'                    => 'Idioma',
+  'Last Invoice Number'         => 'Ultima Factura Emitida',
+  'Last Numbers & Default Accounts' => 'Ultimos Números y Cuentas por Defecto',
+  'Last Purchase Order Number'  => 'Ultimo número Orden de Compra',
+  'Last Sales Order Number'     => 'Ultimo número Pedido',
+  'Liability'                   => 'Pasivo',
+  'Link'                        => 'Vinculado a',
+  'Name'                        => 'Nombre',
+  'No'                          => ' No ',
+  'No email address for'        => 'Falta dirección email para',
+  'Number'                      => 'Número',
+  'Number Format'               => 'Formato Numérico',
+  'Parts Inventory'             => 'Inventario de Items',
+  'Password'                    => 'Contraseña',
+  'Payables'                    => 'X Pagar',
+  'Payment'                     => 'Pago',
+  'Phone'                       => 'Teléfono',
+  'Preferences saved!'          => 'Preferencias guardadas!',
+  'Rate'                        => 'Tasa',
+  'Receivables'                 => 'X Cobrar',
+  'Sales'                       => 'Ventas',
+  'Save'                        => 'Guardar',
+  'Service Items'               => 'Inventario de Servicios',
+  'Ship via'                    => 'Envía vía',
+  'Signature'                   => 'Firma',
+  'Stylesheet'                  => 'Hoja de Estilo',
+  'Tax'                         => 'ISV',
+  'Tax Accounts'                => 'Cuentas de Impuesto',
+  'Template saved!'             => 'Plantilla guardada!',
+  'Transaction reversal enforced for all dates' => 'Reverso de transacciones obligadas para todas la fechas',
+  'Transaction reversal enforced up to' => 'Reverso de transacciones obligadas hasta',
+  'Transactions exist; cannot delete account!' => 'No podemos borrar cuenta, existen transacciones!',
+  'Weight Unit'                 => 'Unidad de Peso',
+  'Year End'                    => 'Cierre',
+  'Yes'                         => ' Sí ',
+  'does not exist'              => 'no existe',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_gifi'                    => 'add_gifi',
+  'audit_control'               => 'audit_control',
+  'backup'                      => 'backup',
+  'config'                      => 'config',
+  'continue'                    => 'continue',
+  'copy_to_coa'                 => 'copy_to_coa',
+  'delete'                      => 'delete',
+  'delete_account'              => 'delete_account',
+  'delete_gifi'                 => 'delete_gifi',
+  'display_form'                => 'display_form',
+  'display_stylesheet'          => 'display_stylesheet',
+  'doclose'                     => 'doclose',
+  'edit'                        => 'edit',
+  'edit_gifi'                   => 'edit_gifi',
+  'edit_template'               => 'edit_template',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gifi_footer'                 => 'gifi_footer',
+  'gifi_header'                 => 'gifi_header',
+  'list'                        => 'list',
+  'list_gifi'                   => 'list_gifi',
+  'save'                        => 'save',
+  'save_account'                => 'save_account',
+  'save_gifi'                   => 'save_gifi',
+  'save_preferences'            => 'save_preferences',
+  'save_template'               => 'save_template',
+  'agregar_cuenta'              => 'add_account',
+  'continuar'                   => 'continue',
+  'copiar_a_plan_de_cuentas'    => 'copy_to_coa',
+  'borrar'                      => 'delete',
+  'editar'                      => 'edit',
+  'editar_cuenta'               => 'edit_account',
+  'guardar'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/ap b/sql-ledger/locale/ve/ap
new file mode 100644 (file)
index 0000000..754f856
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AP Transaction'              => 'Cuenta por Pagar',
+  'AP Transactions'             => 'Cuentas por Pagar',
+  'Account'                     => 'Cuenta',
+  'Add Accounts Payables Transaction' => 'Agregar Cuenta por Pagar',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Monto',
+  'Amount Due'                  => 'Monto Vencido',
+  'Apr'                         => 'abr',
+  'April'                       => 'de abril',
+  'Are you sure you want to delete Transaction' => '¿Seguro que desea borrar Transacción?',
+  'Aug'                         => 'ago',
+  'August'                      => 'de agosto',
+  'Cannot delete transaction!'  => 'No puede borrar transacción!',
+  'Cannot post payment for a closed period!' => 'No puede registrar pago para ejercicio cerrado',
+  'Cannot post transaction for a closed period!' => 'No puede registrar transacción para ejercicio cerrado!',
+  'Cannot post transaction!'    => 'No puede registrar transacción!',
+  'Closed'                      => 'Cerrado',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Divisa',
+  'Customer not on file!'       => 'Cliente no existe en archivo!',
+  'Date'                        => 'Fecha',
+  'Date Paid'                   => 'Fecha Pago',
+  'Dec'                         => 'dic',
+  'December'                    => 'de diciembre',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Due Date'                    => 'Vencimiento',
+  'Due Date missing!'           => 'Falta Vencimiento!',
+  'Edit Accounts Payables Transaction' => 'Editar Transacción Cuentas por Pagar',
+  'Employee'                    => 'Empleado',
+  'Exch'                        => 'Tasa',
+  'Exchangerate'                => 'Tasa de Cambio',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Feb'                         => 'feb',
+  'February'                    => 'de febrero',
+  'From'                        => 'Desde',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluya en Reporte',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha Factura',
+  'Invoice Date missing!'       => 'Falta Fecha Factura!',
+  'Invoice Number'              => 'Número Factura',
+  'Invoice Number missing!'     => 'Falta Número Factura!',
+  'Jan'                         => 'ene',
+  'January'                     => 'de enero',
+  'Jul'                         => 'jul',
+  'July'                        => 'de julio',
+  'Jun'                         => 'jun',
+  'June'                        => 'de junio',
+  'Mar'                         => 'mar',
+  'March'                       => 'de marzo',
+  'May'                         => 'may',
+  'May '                        => 'de mayo',
+  'Notes'                       => 'Comentario',
+  'Nov'                         => 'nov',
+  'November'                    => 'de noviembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'oct',
+  'October'                     => 'de octubre',
+  'Open'                        => 'Abierto',
+  'Order'                       => 'Orden',
+  'Order Number'                => 'Orden Número',
+  'Paid'                        => 'Pagado',
+  'Payment date missing!'       => 'Falta Fecha de Pago',
+  'Payments'                    => 'Pagos',
+  'Post'                        => 'Registrar',
+  'Post as new'                 => 'Registrar como nuevo',
+  'Project'                     => 'Proyecto',
+  'Project not on file!'        => 'Proyecto no archivado!',
+  'Purchase Invoice'            => 'Factura de Compra',
+  'Select from one of the names below' => 'Seleccione de uno de los nombres a continuación',
+  'Select from one of the projects below' => 'Seleccione de uno de los proyectos a continuación',
+  'Sep'                         => 'sep',
+  'September'                   => 'de septiembre',
+  'Source'                      => 'Referencia',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'ISV',
+  'Tax Included'                => 'Impuesto Incluido',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transacción borrada!',
+  'Transaction posted!'         => 'Transacción registrada!',
+  'Update'                      => 'Actualizar',
+  'Vendor'                      => 'Proveedor',
+  'Vendor missing!'             => 'Falta proveedor',
+  'Vendor not on file!'         => 'Proveedor no está en archivo!',
+  'Yes'                         => ' Sí ',
+  'to'                          => 'a',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_subtotal'                 => 'ap_subtotal',
+  'ap_transaction'              => 'ap_transaction',
+  'ap_transactions'             => 'ap_transactions',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'cuenta_por_pagar'            => 'ap_transaction',
+  'agregar_cuenta_por_pagar'    => 'add_accounts_payables_transaction',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'editar_transacción_cuentas_por_pagar' => 'edit_accounts_payables_transaction',
+  'registrar'                   => 'post',
+  'registrar_como_nuevo'        => 'post_as_new',
+  'factura_de_compra'           => 'purchase_invoice',
+  'actualizar'                  => 'update',
+  '_sí_'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/ar b/sql-ledger/locale/ve/ar
new file mode 100644 (file)
index 0000000..55da07b
--- /dev/null
@@ -0,0 +1,133 @@
+$self{texts} = {
+  'AR Transaction'              => 'Cuenta por Cobrar',
+  'AR Transactions'             => 'Cuentas por Cobrar',
+  'Account'                     => 'Cuenta',
+  'Add Accounts Receivables Transaction' => 'Agregar Cuenta por Cobrar',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Monto',
+  'Amount Due'                  => 'Monto Vencido',
+  'Apr'                         => 'abr',
+  'April'                       => 'de abril',
+  'Are you sure you want to delete Transaction' => '¿Seguro que desea borrar Transacción?',
+  'Aug'                         => 'ago',
+  'August'                      => 'de agosto',
+  'Cannot delete transaction!'  => 'No puede borrar transacción!',
+  'Cannot post payment for a closed period!' => 'No puede registrar pago para ejercicio cerrado',
+  'Cannot post transaction for a closed period!' => 'No puede registrar transacción para ejercicio cerrado!',
+  'Cannot post transaction!'    => 'No puede registrar transacción!',
+  'Closed'                      => 'Cerrado',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Límite de Crédito',
+  'Currency'                    => 'Divisa',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Falta cliente!',
+  'Customer not on file!'       => 'Cliente no existe en archivo!',
+  'Date'                        => 'Fecha',
+  'Date Paid'                   => 'Fecha Pago',
+  'Dec'                         => 'dic',
+  'December'                    => 'de diciembre',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Due Date'                    => 'Vencimiento',
+  'Due Date missing!'           => 'Falta Vencimiento!',
+  'Edit Accounts Receivables Transaction' => 'Editar Transacción Cuentas por Cobrar',
+  'Employee'                    => 'Empleado',
+  'Exch'                        => 'Tasa',
+  'Exchangerate'                => 'Tasa de Cambio',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Feb'                         => 'feb',
+  'February'                    => 'de febrero',
+  'From'                        => 'Desde',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluya en Reporte',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha Factura',
+  'Invoice Date missing!'       => 'Falta Fecha Factura!',
+  'Invoice Number'              => 'Número Factura',
+  'Invoice Number missing!'     => 'Falta Número Factura!',
+  'Jan'                         => 'ene',
+  'January'                     => 'de enero',
+  'Jul'                         => 'jul',
+  'July'                        => 'de julio',
+  'Jun'                         => 'jun',
+  'June'                        => 'de junio',
+  'Mar'                         => 'mar',
+  'March'                       => 'de marzo',
+  'May'                         => 'may',
+  'May '                        => 'de mayo',
+  'Notes'                       => 'Comentario',
+  'Nov'                         => 'nov',
+  'November'                    => 'de noviembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'oct',
+  'October'                     => 'de octubre',
+  'Open'                        => 'Abierto',
+  'Order'                       => 'Orden',
+  'Order Number'                => 'Orden Número',
+  'Paid'                        => 'Pagado',
+  'Payment date missing!'       => 'Falta Fecha de Pago',
+  'Payments'                    => 'Pagos',
+  'Post'                        => 'Registrar',
+  'Post as new'                 => 'Registrar como nuevo',
+  'Project'                     => 'Proyecto',
+  'Project not on file!'        => 'Proyecto no archivado!',
+  'Remaining'                   => 'Quedan',
+  'Sales Invoice'               => 'Factura de Venta',
+  'Select from one of the names below' => 'Seleccione de uno de los nombres a continuación',
+  'Select from one of the projects below' => 'Seleccione de uno de los proyectos a continuación',
+  'Sep'                         => 'sep',
+  'September'                   => 'de septiembre',
+  'Source'                      => 'Referencia',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'ISV',
+  'Tax Included'                => 'Impuesto Incluido',
+  'Total'                       => 'Total',
+  'Transaction deleted!'        => 'Transacción borrada!',
+  'Transaction posted!'         => 'Transacción registrada!',
+  'Update'                      => 'Actualizar',
+  'Vendor not on file!'         => 'Proveedor no está en archivo!',
+  'Yes'                         => ' Sí ',
+  'to'                          => 'a',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_subtotal'                 => 'ar_subtotal',
+  'ar_transaction'              => 'ar_transaction',
+  'ar_transactions'             => 'ar_transactions',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_links'                => 'create_links',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'cuenta_por_cobrar'           => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'registrar'                   => 'post',
+  'registrar_como_nuevo'        => 'post_as_new',
+  'factura_de_venta'            => 'sales_invoice',
+  'actualizar'                  => 'update',
+  '_sí_'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/arap b/sql-ledger/locale/ve/arap
new file mode 100644 (file)
index 0000000..deba2e5
--- /dev/null
@@ -0,0 +1,30 @@
+$self{texts} = {
+  'Address'                     => 'Dirección',
+  'Continue'                    => 'Continuar',
+  'Customer not on file!'       => 'Cliente no existe en archivo!',
+  'Description'                 => 'Descripción',
+  'Number'                      => 'Número',
+  'Project not on file!'        => 'Proyecto no archivado!',
+  'Select from one of the names below' => 'Seleccione de uno de los nombres a continuación',
+  'Select from one of the projects below' => 'Seleccione de uno de los proyectos a continuación',
+  'Vendor not on file!'         => 'Proveedor no está en archivo!',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/ca b/sql-ledger/locale/ve/ca
new file mode 100644 (file)
index 0000000..8de34b6
--- /dev/null
@@ -0,0 +1,50 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Apr'                         => 'abr',
+  'April'                       => 'de abril',
+  'Aug'                         => 'ago',
+  'August'                      => 'de agosto',
+  'Balance'                     => 'Balance',
+  'Chart of Accounts'           => 'Plan de Cuentas',
+  'Credit'                      => 'Crédito',
+  'Date'                        => 'Fecha',
+  'Debit'                       => 'Débito',
+  'Dec'                         => 'dic',
+  'December'                    => 'de diciembre',
+  'Description'                 => 'Descripción',
+  'Feb'                         => 'feb',
+  'February'                    => 'de febrero',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'GIFI',
+  'Include in Report'           => 'Incluya en Reporte',
+  'Jan'                         => 'ene',
+  'January'                     => 'de enero',
+  'Jul'                         => 'jul',
+  'July'                        => 'de julio',
+  'Jun'                         => 'jun',
+  'June'                        => 'de junio',
+  'List Transactions'           => 'Listar Transacciones',
+  'Mar'                         => 'mar',
+  'March'                       => 'de marzo',
+  'May'                         => 'may',
+  'May '                        => 'de mayo',
+  'Nov'                         => 'nov',
+  'November'                    => 'de noviembre',
+  'Oct'                         => 'oct',
+  'October'                     => 'de octubre',
+  'Reference'                   => 'Referencia',
+  'Sep'                         => 'sep',
+  'September'                   => 'de septiembre',
+  'Subtotal'                    => 'Subtotal',
+  'to'                          => 'a',
+};
+
+$self{subs} = {
+  'ca_subtotal'                 => 'ca_subtotal',
+  'chart_of_accounts'           => 'chart_of_accounts',
+  'list'                        => 'list',
+  'list_transactions'           => 'list_transactions',
+  'listar_transacciones'        => 'list_transactions',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/cp b/sql-ledger/locale/ve/cp
new file mode 100644 (file)
index 0000000..91c9350
--- /dev/null
@@ -0,0 +1,75 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Monto',
+  'Amount does not equal applied!' => 'Monto no es igual!',
+  'Amount missing!'             => 'Falta monto!',
+  'Applied'                     => 'Aplicado',
+  'Cannot post payment!'        => 'No puede registrar pago!',
+  'Cannot process payment for a closed period!' => 'No puede procesar pago para ejercicio cerrado!',
+  'Check'                       => 'Cheque',
+  'Check printed!'              => 'Cheque impreso!',
+  'Check printing failed!'      => 'No se pudo imprimir cheque!',
+  'Continue'                    => 'Continuar',
+  'Currency'                    => 'Divisa',
+  'Customer'                    => 'Cliente',
+  'Customer not on file!'       => 'Cliente no existe en archivo!',
+  'Date'                        => 'Fecha',
+  'Date missing!'               => 'Falta fecha!',
+  'Description'                 => 'Descripción',
+  'Due'                         => 'Vence',
+  'Exchangerate'                => 'Tasa de Cambio',
+  'From'                        => 'Desde',
+  'Invoice'                     => 'Factura',
+  'Invoices'                    => 'Facturas',
+  'Nothing applied!'            => 'Nada aplicado!',
+  'Number'                      => 'Número',
+  'Paid in full'                => 'Cancelado',
+  'Payment'                     => 'Pago',
+  'Payment posted!'             => 'Pago registrado!',
+  'Post'                        => 'Registrar',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impresora',
+  'Project not on file!'        => 'Proyecto no archivado!',
+  'Receipt'                     => 'Ingreso',
+  'Reference'                   => 'Referencia',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the names below' => 'Seleccione de uno de los nombres a continuación',
+  'Select from one of the projects below' => 'Seleccione de uno de los proyectos a continuación',
+  'Update'                      => 'Actualizar',
+  'Vendor'                      => 'Proveedor',
+  'Vendor not on file!'         => 'Proveedor no está en archivo!',
+  'to'                          => 'a',
+};
+
+$self{subs} = {
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'list_invoices'               => 'list_invoices',
+  'name_selected'               => 'name_selected',
+  'payment'                     => 'payment',
+  'post'                        => 'post',
+  'print'                       => 'print',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+  'registrar'                   => 'post',
+  'imprimir'                    => 'print',
+  'actualizar'                  => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/ct b/sql-ledger/locale/ve/ct
new file mode 100644 (file)
index 0000000..60f585b
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'Add'                         => 'Agregar',
+  'Address'                     => 'Dirección',
+  'All'                         => 'Todos',
+  'Bcc'                         => 'Bcc',
+  'Cannot delete customer!'     => 'No puede borrar cliente!',
+  'Cannot delete vendor!'       => 'No puede borrar proveedor!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Credit Limit'                => 'Límite de Crédito',
+  'Customer deleted!'           => 'Cliente borrado!',
+  'Customer saved!'             => 'Cliente guardado!',
+  'Customers'                   => 'Clientes',
+  'Delete'                      => 'Borrar',
+  'Discount'                    => 'Descuento',
+  'E-mail'                      => 'E-mail',
+  'Edit Customer'               => 'Editar Cliente',
+  'Edit Vendor'                 => 'Editar Proveedor',
+  'Fax'                         => 'Fax',
+  'Include in Report'           => 'Incluya en Reporte',
+  'Invoice'                     => 'Factura',
+  'Name'                        => 'Nombre',
+  'Name missing!'               => 'Falta nombre!',
+  'Notes'                       => 'Comentario',
+  'Number'                      => 'Número',
+  'Order'                       => 'Orden',
+  'Orphaned'                    => 'Huérfano',
+  'Phone'                       => 'Teléfono',
+  'Save'                        => 'Guardar',
+  'Ship to'                     => 'Envíe a',
+  'Tax Included'                => 'Impuesto Incluido',
+  'Taxable'                     => 'Base imponible',
+  'Terms: Net'                  => 'Crédito a',
+  'Transactions exist, cannot delete customer!' => 'No podemos borrar cliente, existen transacciones!',
+  'Transactions exist, cannot delete vendor!' => 'No podemos borrar proveedor, existen transacciones!',
+  'Vendor deleted!'             => 'Proveedor borrado!',
+  'Vendor saved!'               => 'Proveedor guardado!',
+  'Vendors'                     => 'Proveedores',
+  'days'                        => 'días',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'customer_invoice'            => 'customer_invoice',
+  'customer_order'              => 'customer_order',
+  'delete'                      => 'delete',
+  'delete_customer'             => 'delete_customer',
+  'delete_vendor'               => 'delete_vendor',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'invoice'                     => 'invoice',
+  'list_names'                  => 'list_names',
+  'order'                       => 'order',
+  'save'                        => 'save',
+  'save_customer'               => 'save_customer',
+  'save_vendor'                 => 'save_vendor',
+  'search'                      => 'search',
+  'vendor_invoice'              => 'vendor_invoice',
+  'vendor_order'                => 'vendor_order',
+  'agregar'                     => 'add',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'factura'                     => 'invoice',
+  'orden'                       => 'order',
+  'guardar'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/gl b/sql-ledger/locale/ve/gl
new file mode 100644 (file)
index 0000000..06c4137
--- /dev/null
@@ -0,0 +1,124 @@
+$self{texts} = {
+  'AP Transaction'              => 'Cuenta por Pagar',
+  'AR Transaction'              => 'Cuenta por Cobrar',
+  'Account'                     => 'Cuenta',
+  'Add General Ledger Transaction' => 'Agregar Transacción al Mayor General',
+  'Address'                     => 'Dirección',
+  'All'                         => 'Todos',
+  'Apr'                         => 'abr',
+  'April'                       => 'de abril',
+  'Are you sure you want to delete Transaction' => '¿Seguro que desea borrar Transacción?',
+  'Asset'                       => 'Activo',
+  'Aug'                         => 'ago',
+  'August'                      => 'de agosto',
+  'Balance'                     => 'Balance',
+  'Cannot delete transaction!'  => 'No puede borrar transacción!',
+  'Cannot have a value in both Debit and Credit!' => 'No puede haber Débito y Crédito simultáneamente!',
+  'Cannot post a transaction without a value!' => 'No puede registrar transacción sin monto!',
+  'Cannot post transaction for a closed period!' => 'No puede registrar transacción para ejercicio cerrado!',
+  'Confirm!'                    => 'Confirmar!',
+  'Continue'                    => 'Continuar',
+  'Credit'                      => 'Crédito',
+  'Customer not on file!'       => 'Cliente no existe en archivo!',
+  'Date'                        => 'Fecha',
+  'Debit'                       => 'Débito',
+  'Debit and credit out of balance!' => 'Débito y Crédito fuera de balance!',
+  'Dec'                         => 'dic',
+  'December'                    => 'de diciembre',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Edit General Ledger Transaction' => 'Editar Transacción de Mayor General',
+  'Equity'                      => 'Capital',
+  'Expense'                     => 'Egreso',
+  'Feb'                         => 'feb',
+  'February'                    => 'de febrero',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'GIFI',
+  'GL Transaction'              => 'Transacción de mayor',
+  'General Ledger'              => 'Mayor General',
+  'ID'                          => 'ID',
+  'Include in Report'           => 'Incluya en Reporte',
+  'Income'                      => 'Ingreso',
+  'Jan'                         => 'ene',
+  'January'                     => 'de enero',
+  'Jul'                         => 'jul',
+  'July'                        => 'de julio',
+  'Jun'                         => 'jun',
+  'June'                        => 'de junio',
+  'Liability'                   => 'Pasivo',
+  'Mar'                         => 'mar',
+  'March'                       => 'de marzo',
+  'May'                         => 'may',
+  'May '                        => 'de mayo',
+  'Notes'                       => 'Comentario',
+  'Nov'                         => 'nov',
+  'November'                    => 'de noviembre',
+  'Number'                      => 'Número',
+  'Oct'                         => 'oct',
+  'October'                     => 'de octubre',
+  'Post'                        => 'Registrar',
+  'Post as new'                 => 'Registrar como nuevo',
+  'Project'                     => 'Proyecto',
+  'Project not on file!'        => 'Proyecto no archivado!',
+  'Purchase Invoice'            => 'Factura de Compra',
+  'Reference'                   => 'Referencia',
+  'Reference missing!'          => 'Falta referencia!',
+  'Reports'                     => 'Reportes',
+  'Sales Invoice'               => 'Factura de Venta',
+  'Select from one of the names below' => 'Seleccione de uno de los nombres a continuación',
+  'Select from one of the projects below' => 'Seleccione de uno de los proyectos a continuación',
+  'Sep'                         => 'sep',
+  'September'                   => 'de septiembre',
+  'Source'                      => 'Referencia',
+  'Subtotal'                    => 'Subtotal',
+  'Transaction Date missing!'   => 'Falta Fecha Transacción!',
+  'Transaction deleted!'        => 'Transacción borrada!',
+  'Transaction posted!'         => 'Transacción registrada!',
+  'Update'                      => 'Actualizar',
+  'Vendor not on file!'         => 'Proveedor no está en archivo!',
+  'Yes'                         => ' Sí ',
+  'to'                          => 'a',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'form_row'                    => 'form_row',
+  'generate_report'             => 'generate_report',
+  'gl_subtotal'                 => 'gl_subtotal',
+  'gl_transaction'              => 'gl_transaction',
+  'name_selected'               => 'name_selected',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'search'                      => 'search',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'update'                      => 'update',
+  'yes'                         => 'yes',
+  'cuenta_por_pagar'            => 'ap_transaction',
+  'cuenta_por_cobrar'           => 'ar_transaction',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'transacción_de_mayor'        => 'gl_transaction',
+  'registrar'                   => 'post',
+  'registrar_como_nuevo'        => 'post_as_new',
+  'factura_de_compra'           => 'purchase_invoice',
+  'factura_de_venta'            => 'sales_invoice',
+  'actualizar'                  => 'update',
+  '_sí_'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/ic b/sql-ledger/locale/ve/ic
new file mode 100644 (file)
index 0000000..9c4e9c8
--- /dev/null
@@ -0,0 +1,206 @@
+$self{texts} = {
+  'Active'                      => 'Activa',
+  'Add'                         => 'Agregar',
+  'Add Assembly'                => 'Agregar Conjunto',
+  'Add Part'                    => 'Agregar Item',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Order'             => 'Agregar Pedido',
+  'Add Service'                 => 'Agregar Servicio',
+  'Address'                     => 'Dirección',
+  'Apr'                         => 'abr',
+  'April'                       => 'de abril',
+  'Assemblies'                  => 'Conjuntos',
+  'Assemblies restocked!'       => 'Conjuntos re-inventariados',
+  'Assembly Number missing!'    => 'Falta Número Conjunto!',
+  'Attachment'                  => 'Anexo',
+  'Aug'                         => 'ago',
+  'August'                      => 'de agosto',
+  'BOM'                         => 'Lista de Materiales',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Ubicación',
+  'Bought'                      => 'Comprado',
+  'COGS'                        => 'Costo Perpetuo',
+  'Cannot delete item already invoiced!' => 'No puede borrar ítem facturado!',
+  'Cannot delete item on order!' => 'No puede borrar ítem pedido!',
+  'Cannot delete item which is part of an assembly!' => 'No puede borrar ítem parte de conjunto!',
+  'Cannot delete item!'         => 'No puede borrar ítem!',
+  'Cannot stock assemblies!'    => 'No puede inventariar conjuntos!',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Dec'                         => 'dic',
+  'December'                    => 'de diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Fecha de Entrega',
+  'Description'                 => 'Descripción',
+  'Drawing'                     => 'Retiro',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Falta dirección E-mail!',
+  'Edit Assembly'               => 'Editar Conjunto',
+  'Edit Part'                   => 'Editar Item',
+  'Edit Service'                => 'Editar Servicio',
+  'Expense'                     => 'Egreso',
+  'Extended'                    => 'Extendido',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'feb',
+  'February'                    => 'de febrero',
+  'From'                        => 'Desde',
+  'Image'                       => 'Imagen',
+  'In-line'                     => 'Incorporado',
+  'Include in Report'           => 'Incluya en Reporte',
+  'Income'                      => 'Ingreso',
+  'Individual Items'            => 'Items Individuales',
+  'Inventory'                   => 'Inventario',
+  'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Existencia debe ser cero antes de hacer obsoleto a este conjunto!',
+  'Inventory quantity must be zero before you can set this part obsolete!' => 'Existencia debe ser cero antes de hacer obsoleto este ítem!',
+  'Inventory quantity must be zero!' => 'Existencia debe ser cero!',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Falta Fecha Factura!',
+  'Invoice Number'              => 'Número Factura',
+  'Invoice Number missing!'     => 'Falta Número Factura!',
+  'Item deleted!'               => 'Item borrado!',
+  'Item not on file!'           => 'Item no archivado!',
+  'Jan'                         => 'ene',
+  'January'                     => 'de enero',
+  'Jul'                         => 'jul',
+  'July'                        => 'de julio',
+  'Jun'                         => 'jun',
+  'June'                        => 'de junio',
+  'Last Cost'                   => 'Ultimo Costo',
+  'Line Total'                  => 'Total línea',
+  'Link Accounts'               => 'Vincular Cuentas',
+  'List Price'                  => 'Precio de Lista',
+  'Make'                        => 'Marca',
+  'Mar'                         => 'mar',
+  'March'                       => 'de marzo',
+  'May'                         => 'may',
+  'May '                        => 'de mayo',
+  'Message'                     => 'Mensaje',
+  'Microfiche'                  => 'Microficha',
+  'Model'                       => 'Modelo',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Comentario',
+  'Nov'                         => 'nov',
+  'November'                    => 'de noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta número en Hilera',
+  'Obsolete'                    => 'Obsoleto',
+  'Oct'                         => 'oct',
+  'October'                     => 'de octubre',
+  'On Hand'                     => 'Existencia',
+  'On Order'                    => 'Pedido',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'Falta Fecha Pedido!',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'Falta Número de Orden',
+  'Ordered'                     => 'Pedido',
+  'Orphaned'                    => 'Huérfano',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => 'Falta Fecha en Nota de Entrega',
+  'Packing List Number missing!' => 'Falta Número en Nota de Entrega',
+  'Part'                        => 'Item',
+  'Part Number missing!'        => 'Falta Número de Item!',
+  'Parts'                       => 'Items',
+  'Phone'                       => 'Teléfono',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Proyecto',
+  'Purchase Order'              => 'Orden de Compra',
+  'Qty'                         => 'Cnt',
+  'ROP'                         => 'Existencia mínima',
+  'Recd'                        => 'Rec',
+  'Required by'                 => 'Requerido para el',
+  'Sales'                       => 'Ventas',
+  'Sales Order'                 => 'Pedido',
+  'Save'                        => 'Guardar',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los ítems listados',
+  'Select postscript or PDF!'   => 'Seleccione postscript o PDF',
+  'Sell Price'                  => 'Precio de Venta',
+  'Sep'                         => 'sep',
+  'September'                   => 'de septiembre',
+  'Service'                     => 'Servicio',
+  'Service Number missing!'     => 'Falta Número de Servicio!',
+  'Services'                    => 'Servicios',
+  'Ship'                        => 'Envíe',
+  'Ship to'                     => 'Envíe a',
+  'Short'                       => 'Corto',
+  'Sold'                        => 'Vendido',
+  'Stock Assembly'              => 'Reponer Conjuntos',
+  'Subject'                     => 'Materia',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'ISV',
+  'To'                          => 'Hasta',
+  'Top Level'                   => 'Nivel superior',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Unit of measure'             => 'Unidad de medida',
+  'Update'                      => 'Actualizar',
+  'Updated'                     => 'Actalizado',
+  'Weight'                      => 'Peso',
+  'What type of item is this?'  => '¿Qué tipo de ítem es éste?',
+  'ea'                          => 'cu',
+  'emailed to'                  => 'enviado por email a',
+  'hr'                          => 'hr',
+  'sent to printer'             => 'enviado a impresora',
+  'to'                          => 'a',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'assembly_row'                => 'assembly_row',
+  'check_form'                  => 'check_form',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'delete_assembly'             => 'delete_assembly',
+  'delete_item'                 => 'delete_item',
+  'delete_part'                 => 'delete_part',
+  'delete_service'              => 'delete_service',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'link_part'                   => 'link_part',
+  'list_assemblies'             => 'list_assemblies',
+  'makemodel_row'               => 'makemodel_row',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'parts_subtotal'              => 'parts_subtotal',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'restock_assemblies'          => 'restock_assemblies',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'stock_assembly'              => 'stock_assembly',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'agregar'                     => 'add',
+  'agregar_conjunto'            => 'add_assembly',
+  'agregar_item'                => 'add_part',
+  'agregar_servicio'            => 'add_service',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'editar_conjunto'             => 'edit_assembly',
+  'editar_item'                 => 'edit_part',
+  'editar_servicio'             => 'edit_service',
+  'guardar'                     => 'save',
+  'actualizar'                  => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/io b/sql-ledger/locale/ve/io
new file mode 100644 (file)
index 0000000..9370f8f
--- /dev/null
@@ -0,0 +1,106 @@
+$self{texts} = {
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Order'             => 'Agregar Pedido',
+  'Address'                     => 'Dirección',
+  'Apr'                         => 'abr',
+  'April'                       => 'de abril',
+  'Attachment'                  => 'Anexo',
+  'Aug'                         => 'ago',
+  'August'                      => 'de agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Ubicación',
+  'Cc'                          => 'Cc',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Dec'                         => 'dic',
+  'December'                    => 'de diciembre',
+  'Delivery Date'               => 'Fecha de Entrega',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Falta dirección E-mail!',
+  'Extended'                    => 'Extendido',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'feb',
+  'February'                    => 'de febrero',
+  'In-line'                     => 'Incorporado',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Falta Fecha Factura!',
+  'Invoice Number missing!'     => 'Falta Número Factura!',
+  'Item not on file!'           => 'Item no archivado!',
+  'Jan'                         => 'ene',
+  'January'                     => 'de enero',
+  'Jul'                         => 'jul',
+  'July'                        => 'de julio',
+  'Jun'                         => 'jun',
+  'June'                        => 'de junio',
+  'Mar'                         => 'mar',
+  'March'                       => 'de marzo',
+  'May'                         => 'may',
+  'May '                        => 'de mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Nov'                         => 'nov',
+  'November'                    => 'de noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta número en Hilera',
+  'Oct'                         => 'oct',
+  'October'                     => 'de octubre',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'Falta Fecha Pedido!',
+  'Order Number missing!'       => 'Falta Número de Orden',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => 'Falta Fecha en Nota de Entrega',
+  'Packing List Number missing!' => 'Falta Número en Nota de Entrega',
+  'Part'                        => 'Item',
+  'Phone'                       => 'Teléfono',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Proyecto',
+  'Purchase Order'              => 'Orden de Compra',
+  'Qty'                         => 'Cnt',
+  'Recd'                        => 'Rec',
+  'Required by'                 => 'Requerido para el',
+  'Sales Order'                 => 'Pedido',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los ítems listados',
+  'Select postscript or PDF!'   => 'Seleccione postscript o PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'de septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Envíe',
+  'Ship to'                     => 'Envíe a',
+  'Subject'                     => 'Materia',
+  'To'                          => 'Hasta',
+  'Unit'                        => 'Unidad',
+  'What type of item is this?'  => '¿Qué tipo de ítem es éste?',
+  'emailed to'                  => 'enviado por email a',
+  'sent to printer'             => 'enviado a impresora',
+};
+
+$self{subs} = {
+  'check_form'                  => 'check_form',
+  'customer_details'            => 'customer_details',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post_as_new'                 => 'post_as_new',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'select_item'                 => 'select_item',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'continuar'                   => 'continue',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/ir b/sql-ledger/locale/ve/ir
new file mode 100644 (file)
index 0000000..29eec22
--- /dev/null
@@ -0,0 +1,178 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Add Purchase Invoice'        => 'Agregar Factura de Compra',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Order'             => 'Agregar Pedido',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Monto',
+  'Apr'                         => 'abr',
+  'April'                       => 'de abril',
+  'Are you sure you want to delete Invoice Number' => '¿Seguro que desea borrar Factura?',
+  'Attachment'                  => 'Anexo',
+  'Aug'                         => 'ago',
+  'August'                      => 'de agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Ubicación',
+  'Cannot delete invoice!'      => 'No puede borraar factura!',
+  'Cannot post invoice for a closed period!' => 'No puede registrar factura para ejercicio cerrado!',
+  'Cannot post invoice!'        => 'No puede registrar factura!',
+  'Cannot post payment for a closed period!' => 'No puede registrar pago para ejercicio cerrado',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Currency'                    => 'Divisa',
+  'Customer not on file!'       => 'Cliente no existe en archivo!',
+  'Date'                        => 'Fecha',
+  'Date Due'                    => 'Vencimiento',
+  'Dec'                         => 'dic',
+  'December'                    => 'de diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Fecha de Entrega',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Falta dirección E-mail!',
+  'Edit Purchase Invoice'       => 'Editar Factura de Compra',
+  'Exch'                        => 'Tasa',
+  'Exchangerate'                => 'Tasa de Cambio',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Extended'                    => 'Extendido',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'feb',
+  'February'                    => 'de febrero',
+  'In-line'                     => 'Incorporado',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha Factura',
+  'Invoice Date missing!'       => 'Falta Fecha Factura!',
+  'Invoice Number'              => 'Número Factura',
+  'Invoice Number missing!'     => 'Falta Número Factura!',
+  'Invoice deleted!'            => 'Factura borrada!',
+  'Invoice posted!'             => 'Factura registrada!',
+  'Item not on file!'           => 'Item no archivado!',
+  'Jan'                         => 'ene',
+  'January'                     => 'de enero',
+  'Jul'                         => 'jul',
+  'July'                        => 'de julio',
+  'Jun'                         => 'jun',
+  'June'                        => 'de junio',
+  'Mar'                         => 'mar',
+  'March'                       => 'de marzo',
+  'May'                         => 'may',
+  'May '                        => 'de mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Comentario',
+  'Nov'                         => 'nov',
+  'November'                    => 'de noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta número en Hilera',
+  'Oct'                         => 'oct',
+  'October'                     => 'de octubre',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'Falta Fecha Pedido!',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'Falta Número de Orden',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => 'Falta Fecha en Nota de Entrega',
+  'Packing List Number missing!' => 'Falta Número en Nota de Entrega',
+  'Part'                        => 'Item',
+  'Payment date missing!'       => 'Falta Fecha de Pago',
+  'Payments'                    => 'Pagos',
+  'Phone'                       => 'Teléfono',
+  'Post'                        => 'Registrar',
+  'Post as new'                 => 'Registrar como nuevo',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Proyecto',
+  'Project not on file!'        => 'Proyecto no archivado!',
+  'Purchase Order'              => 'Orden de Compra',
+  'Qty'                         => 'Cnt',
+  'Recd'                        => 'Rec',
+  'Record in'                   => 'Registrar en',
+  'Required by'                 => 'Requerido para el',
+  'Sales Order'                 => 'Pedido',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los ítems listados',
+  'Select from one of the names below' => 'Seleccione de uno de los nombres a continuación',
+  'Select from one of the projects below' => 'Seleccione de uno de los proyectos a continuación',
+  'Select postscript or PDF!'   => 'Seleccione postscript o PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'de septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Envíe',
+  'Ship to'                     => 'Envíe a',
+  'Source'                      => 'Referencia',
+  'Subject'                     => 'Materia',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Impuesto Incluido',
+  'To'                          => 'Hasta',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Update'                      => 'Actualizar',
+  'Vendor'                      => 'Proveedor',
+  'Vendor missing!'             => 'Falta proveedor',
+  'Vendor not on file!'         => 'Proveedor no está en archivo!',
+  'What type of item is this?'  => '¿Qué tipo de ítem es éste?',
+  'Yes'                         => ' Sí ',
+  'ea'                          => 'cu',
+  'emailed to'                  => 'enviado por email a',
+  'sent to printer'             => 'enviado a impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'orden'                       => 'order',
+  'registrar'                   => 'post',
+  'registrar_como_nuevo'        => 'post_as_new',
+  'actualizar'                  => 'update',
+  '_sí_'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/is b/sql-ledger/locale/ve/is
new file mode 100644 (file)
index 0000000..28d7abd
--- /dev/null
@@ -0,0 +1,185 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Invoice'           => 'Agregar Factura de Venta',
+  'Add Sales Order'             => 'Agregar Pedido',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Monto',
+  'Apr'                         => 'abr',
+  'April'                       => 'de abril',
+  'Are you sure you want to delete Invoice Number' => '¿Seguro que desea borrar Factura?',
+  'Attachment'                  => 'Anexo',
+  'Aug'                         => 'ago',
+  'August'                      => 'de agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Ubicación',
+  'Cannot delete invoice!'      => 'No puede borraar factura!',
+  'Cannot post invoice for a closed period!' => 'No puede registrar factura para ejercicio cerrado!',
+  'Cannot post invoice!'        => 'No puede registrar factura!',
+  'Cannot post payment for a closed period!' => 'No puede registrar pago para ejercicio cerrado',
+  'Cc'                          => 'Cc',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Credit Limit'                => 'Límite de Crédito',
+  'Currency'                    => 'Divisa',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Falta cliente!',
+  'Customer not on file!'       => 'Cliente no existe en archivo!',
+  'Date'                        => 'Fecha',
+  'Date Due'                    => 'Vencimiento',
+  'Dec'                         => 'dic',
+  'December'                    => 'de diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Fecha de Entrega',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Falta dirección E-mail!',
+  'Edit Sales Invoice'          => 'Editar Factura de Venta',
+  'Exch'                        => 'Tasa',
+  'Exchangerate'                => 'Tasa de Cambio',
+  'Exchangerate for payment missing!' => 'No se encuentra pago por cambio de moneda',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Extended'                    => 'Extendido',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'feb',
+  'February'                    => 'de febrero',
+  'In-line'                     => 'Incorporado',
+  'Invoice'                     => 'Factura',
+  'Invoice Date'                => 'Fecha Factura',
+  'Invoice Date missing!'       => 'Falta Fecha Factura!',
+  'Invoice Number'              => 'Número Factura',
+  'Invoice Number missing!'     => 'Falta Número Factura!',
+  'Invoice deleted!'            => 'Factura borrada!',
+  'Invoice posted!'             => 'Factura registrada!',
+  'Item not on file!'           => 'Item no archivado!',
+  'Jan'                         => 'ene',
+  'January'                     => 'de enero',
+  'Jul'                         => 'jul',
+  'July'                        => 'de julio',
+  'Jun'                         => 'jun',
+  'June'                        => 'de junio',
+  'Mar'                         => 'mar',
+  'March'                       => 'de marzo',
+  'May'                         => 'may',
+  'May '                        => 'de mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Comentario',
+  'Nov'                         => 'nov',
+  'November'                    => 'de noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta número en Hilera',
+  'Oct'                         => 'oct',
+  'October'                     => 'de octubre',
+  'Order'                       => 'Orden',
+  'Order Date missing!'         => 'Falta Fecha Pedido!',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'Falta Número de Orden',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => 'Falta Fecha en Nota de Entrega',
+  'Packing List Number missing!' => 'Falta Número en Nota de Entrega',
+  'Part'                        => 'Item',
+  'Payment date missing!'       => 'Falta Fecha de Pago',
+  'Payments'                    => 'Pagos',
+  'Phone'                       => 'Teléfono',
+  'Post'                        => 'Registrar',
+  'Post as new'                 => 'Registrar como nuevo',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Proyecto',
+  'Project not on file!'        => 'Proyecto no archivado!',
+  'Purchase Order'              => 'Orden de Compra',
+  'Qty'                         => 'Cnt',
+  'Recd'                        => 'Rec',
+  'Record in'                   => 'Registrar en',
+  'Remaining'                   => 'Quedan',
+  'Required by'                 => 'Requerido para el',
+  'Sales Order'                 => 'Pedido',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los ítems listados',
+  'Select from one of the names below' => 'Seleccione de uno de los nombres a continuación',
+  'Select from one of the projects below' => 'Seleccione de uno de los proyectos a continuación',
+  'Select postscript or PDF!'   => 'Seleccione postscript o PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'de septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Envíe',
+  'Ship to'                     => 'Envíe a',
+  'Ship via'                    => 'Envía vía',
+  'Source'                      => 'Referencia',
+  'Subject'                     => 'Materia',
+  'Subtotal'                    => 'Subtotal',
+  'Tax Included'                => 'Impuesto Incluido',
+  'To'                          => 'Hasta',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Update'                      => 'Actualizar',
+  'Vendor not on file!'         => 'Proveedor no está en archivo!',
+  'What type of item is this?'  => '¿Qué tipo de ítem es éste?',
+  'Yes'                         => ' Sí ',
+  'ea'                          => 'cu',
+  'emailed to'                  => 'enviado por email a',
+  'sent to printer'             => 'enviado a impresora',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice_links'               => 'invoice_links',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'post'                        => 'post',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_invoice'             => 'prepare_invoice',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'e_mail'                      => 'e_mail',
+  'orden'                       => 'order',
+  'registrar'                   => 'post',
+  'registrar_como_nuevo'        => 'post_as_new',
+  'imprimir'                    => 'print',
+  'envíe_a'                     => 'ship_to',
+  'actualizar'                  => 'update',
+  '_sí_'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/login b/sql-ledger/locale/ve/login
new file mode 100644 (file)
index 0000000..0546b90
--- /dev/null
@@ -0,0 +1,27 @@
+$self{texts} = {
+  'About'                       => 'Acerca de',
+  'Database Host'               => 'Servidor de base de datos',
+  'Dataset'                     => 'Base de datos',
+  'Incorrect Dataset version!'  => 'Versión incorrecta de base de datos!',
+  'Incorrect Password!'         => 'Contraseña equivocada',
+  'Licensed to'                 => 'Licenciatario',
+  'Login'                       => 'Login',
+  'Name'                        => 'Nombre',
+  'Password'                    => 'Contraseña',
+  'User'                        => 'Usuario',
+  'Version'                     => 'Versión',
+  'You are logged out!'         => 'Ha salido del sistema!',
+  'You did not enter a name!'   => 'No se ingresó un nombre!',
+  'is not a member!'            => 'no es miembro!',
+  'localhost'                   => 'localhost',
+};
+
+$self{subs} = {
+  'company_logo'                => 'company_logo',
+  'login'                       => 'login',
+  'login_screen'                => 'login_screen',
+  'logout'                      => 'logout',
+  'login'                       => 'login',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/menu b/sql-ledger/locale/ve/menu
new file mode 100644 (file)
index 0000000..063e0af
--- /dev/null
@@ -0,0 +1,71 @@
+$self{texts} = {
+  'AP'                          => 'CXP',
+  'AP Aging'                    => 'Vencimientos',
+  'AR'                          => 'CXC',
+  'AR Aging'                    => 'Vencimientos',
+  'Accounting Menu'             => 'Menú de Contabilidad',
+  'Add Account'                 => 'Agregar Cuenta',
+  'Add Assembly'                => 'Agregar Conjunto',
+  'Add Customer'                => 'Agregar Cliente',
+  'Add GIFI'                    => 'Agregar GIFI',
+  'Add Part'                    => 'Agregar Item',
+  'Add Project'                 => 'Agregar Proyecto',
+  'Add Service'                 => 'Agregar Servicio',
+  'Add Transaction'             => 'Agregar Transacción',
+  'Add Vendor'                  => 'Agregar Proveedor',
+  'Assemblies'                  => 'Conjuntos',
+  'Audit Control'               => 'Control de Auditoría',
+  'Backup'                      => 'Respaldos',
+  'Balance Sheet'               => 'Hoja de Balance',
+  'Cash'                        => 'Caja',
+  'Chart of Accounts'           => 'Plan de Cuentas',
+  'Check'                       => 'Cheque',
+  'Customers'                   => 'Clientes',
+  'General Ledger'              => 'Mayor General',
+  'Goods & Services'            => 'Bienes y Servicios',
+  'HTML Templates'              => 'Plantillas HTML',
+  'Income Statement'            => 'Estado de Cuentas de Ingreso',
+  'Invoice'                     => 'Factura',
+  'LaTeX Templates'             => 'Plantillas LaTeX',
+  'List Accounts'               => 'Listar cuentas',
+  'List GIFI'                   => 'Listar GIFI',
+  'Logout'                      => 'Salir del sistema',
+  'Order Entry'                 => 'Pedidos<br>Ordenes de Compra',
+  'Packing List'                => 'Lista de Empaque',
+  'Parts'                       => 'Items',
+  'Payment'                     => 'Pago',
+  'Payments'                    => 'Pagos',
+  'Preferences'                 => 'Preferencias',
+  'Projects'                    => 'Proyectos',
+  'Purchase Invoice'            => 'Factura de Compra',
+  'Purchase Order'              => 'Orden de Compra',
+  'Purchase Orders'             => 'Ordenes de Compra',
+  'Receipt'                     => 'Ingreso',
+  'Receipts'                    => 'Ingresos',
+  'Reconciliation'              => 'Conciliación',
+  'Reports'                     => 'Reportes',
+  'Sales Invoice'               => 'Factura de Venta',
+  'Sales Order'                 => 'Pedido',
+  'Sales Orders'                => 'Pedidos',
+  'Save to File'                => 'Respaldar a Archivo',
+  'Send by E-Mail'              => 'Enviar por E-Mail',
+  'Services'                    => 'Servicios',
+  'Statement'                   => 'Estado de Cuenta',
+  'Stock Assembly'              => 'Reponer Conjuntos',
+  'Stylesheet'                  => 'Hoja de Estilo',
+  'System'                      => 'Sistema',
+  'Tax collected'               => 'Impuesto recaudado',
+  'Tax paid'                    => 'Impuesto pagado',
+  'Transactions'                => 'Transacciones',
+  'Trial Balance'               => 'Balance de Comprobación',
+  'Vendors'                     => 'Proveedores',
+  'Version'                     => 'Versión',
+};
+
+$self{subs} = {
+  'acc_menu'                    => 'acc_menu',
+  'display'                     => 'display',
+  'section_menu'                => 'section_menu',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/oe b/sql-ledger/locale/ve/oe
new file mode 100644 (file)
index 0000000..899747c
--- /dev/null
@@ -0,0 +1,200 @@
+$self{texts} = {
+  'Add'                         => 'Agregar',
+  'Add Purchase Invoice'        => 'Agregar Factura de Compra',
+  'Add Purchase Order'          => 'Agregar Orden de Compra',
+  'Add Sales Invoice'           => 'Agregar Factura de Venta',
+  'Add Sales Order'             => 'Agregar Pedido',
+  'Address'                     => 'Dirección',
+  'Amount'                      => 'Monto',
+  'Apr'                         => 'abr',
+  'April'                       => 'de abril',
+  'Are you sure you want to delete Order Number' => '¿Seguro que desea borrar Orden de Compra/Pedido?',
+  'Attachment'                  => 'Anexo',
+  'Aug'                         => 'ago',
+  'August'                      => 'de agosto',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Ubicación',
+  'C'                           => 'C',
+  'Cannot delete order!'        => 'No puede borrar pedido!',
+  'Cannot save order!'          => 'No puede guardar órden!',
+  'Cc'                          => 'Cc',
+  'Closed'                      => 'Cerrado',
+  'Confirm!'                    => 'Confirmar!',
+  'Contact'                     => 'Contacto',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Credit Limit'                => 'Límite de Crédito',
+  'Curr'                        => 'Div',
+  'Currency'                    => 'Divisa',
+  'Customer'                    => 'Cliente',
+  'Customer missing!'           => 'Falta cliente!',
+  'Customer not on file!'       => 'Cliente no existe en archivo!',
+  'Date'                        => 'Fecha',
+  'Dec'                         => 'dic',
+  'December'                    => 'de diciembre',
+  'Delete'                      => 'Borrar',
+  'Delivery Date'               => 'Fecha de Entrega',
+  'Description'                 => 'Descripción',
+  'E-mail'                      => 'E-mail',
+  'E-mail address missing!'     => 'Falta dirección E-mail!',
+  'Edit Purchase Order'         => 'Editar Orden de Compra',
+  'Edit Sales Order'            => 'Editar Pedido',
+  'Exchangerate'                => 'Tasa de Cambio',
+  'Exchangerate missing!'       => 'No se encuentra cambio de moneda',
+  'Extended'                    => 'Extendido',
+  'Fax'                         => 'Fax',
+  'Feb'                         => 'feb',
+  'February'                    => 'de febrero',
+  'From'                        => 'Desde',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Incorporado',
+  'Include in Report'           => 'Incluya en Reporte',
+  'Invoice'                     => 'Factura',
+  'Invoice Date missing!'       => 'Falta Fecha Factura!',
+  'Invoice Number missing!'     => 'Falta Número Factura!',
+  'Item not on file!'           => 'Item no archivado!',
+  'Jan'                         => 'ene',
+  'January'                     => 'de enero',
+  'Jul'                         => 'jul',
+  'July'                        => 'de julio',
+  'Jun'                         => 'jun',
+  'June'                        => 'de junio',
+  'Mar'                         => 'mar',
+  'March'                       => 'de marzo',
+  'May'                         => 'may',
+  'May '                        => 'de mayo',
+  'Message'                     => 'Mensaje',
+  'Name'                        => 'Nombre',
+  'No.'                         => 'No.',
+  'Notes'                       => 'Comentario',
+  'Nov'                         => 'nov',
+  'November'                    => 'de noviembre',
+  'Number'                      => 'Número',
+  'Number missing in Row'       => 'Falta número en Hilera',
+  'O'                           => 'O',
+  'Oct'                         => 'oct',
+  'October'                     => 'de octubre',
+  'Open'                        => 'Abierto',
+  'Order'                       => 'Orden',
+  'Order Date'                  => 'Fecha Pedido',
+  'Order Date missing!'         => 'Falta Fecha Pedido!',
+  'Order Number'                => 'Orden Número',
+  'Order Number missing!'       => 'Falta Número de Orden',
+  'Order deleted!'              => 'Orden borrada!',
+  'Order saved!'                => 'Orden guardada!',
+  'PDF'                         => 'PDF',
+  'Packing List'                => 'Lista de Empaque',
+  'Packing List Date missing!'  => 'Falta Fecha en Nota de Entrega',
+  'Packing List Number missing!' => 'Falta Número en Nota de Entrega',
+  'Part'                        => 'Item',
+  'Phone'                       => 'Teléfono',
+  'Postscript'                  => 'Postscript',
+  'Price'                       => 'Precio',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impresora',
+  'Project'                     => 'Proyecto',
+  'Project not on file!'        => 'Proyecto no archivado!',
+  'Purchase Order'              => 'Orden de Compra',
+  'Purchase Orders'             => 'Ordenes de Compra',
+  'Qty'                         => 'Cnt',
+  'Recd'                        => 'Rec',
+  'Remaining'                   => 'Quedan',
+  'Required by'                 => 'Requerido para el',
+  'Sales Order'                 => 'Pedido',
+  'Sales Orders'                => 'Pedidos',
+  'Save'                        => 'Guardar',
+  'Save as new'                 => 'Guardar como nuevo',
+  'Screen'                      => 'Pantalla',
+  'Select from one of the items below' => 'Seleccione uno de los ítems listados',
+  'Select from one of the names below' => 'Seleccione de uno de los nombres a continuación',
+  'Select from one of the projects below' => 'Seleccione de uno de los proyectos a continuación',
+  'Select postscript or PDF!'   => 'Seleccione postscript o PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'de septiembre',
+  'Service'                     => 'Servicio',
+  'Ship'                        => 'Envíe',
+  'Ship to'                     => 'Envíe a',
+  'Ship via'                    => 'Envía vía',
+  'Subject'                     => 'Materia',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'ISV',
+  'Tax Included'                => 'Impuesto Incluido',
+  'Terms: Net'                  => 'Crédito a',
+  'To'                          => 'Hasta',
+  'Total'                       => 'Total',
+  'Unit'                        => 'Unidad',
+  'Update'                      => 'Actualizar',
+  'Vendor'                      => 'Proveedor',
+  'Vendor missing!'             => 'Falta proveedor',
+  'Vendor not on file!'         => 'Proveedor no está en archivo!',
+  'What type of item is this?'  => '¿Qué tipo de ítem es éste?',
+  'Yes'                         => ' Sí ',
+  'days'                        => 'días',
+  'ea'                          => 'cu',
+  'emailed to'                  => 'enviado por email a',
+  'sent to printer'             => 'enviado a impresora',
+  'to'                          => 'a',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'add_transaction'             => 'add_transaction',
+  'ap_transaction'              => 'ap_transaction',
+  'ar_transaction'              => 'ar_transaction',
+  'check_form'                  => 'check_form',
+  'check_name'                  => 'check_name',
+  'check_project'               => 'check_project',
+  'continue'                    => 'continue',
+  'create_backorder'            => 'create_backorder',
+  'customer_details'            => 'customer_details',
+  'delete'                      => 'delete',
+  'display_form'                => 'display_form',
+  'display_row'                 => 'display_row',
+  'e_mail'                      => 'e_mail',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'gl_transaction'              => 'gl_transaction',
+  'invoice'                     => 'invoice',
+  'invoicetotal'                => 'invoicetotal',
+  'item_selected'               => 'item_selected',
+  'name_selected'               => 'name_selected',
+  'new_item'                    => 'new_item',
+  'order'                       => 'order',
+  'order_links'                 => 'order_links',
+  'orders'                      => 'orders',
+  'post_as_new'                 => 'post_as_new',
+  'prepare_order'               => 'prepare_order',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'project_selected'            => 'project_selected',
+  'purchase_invoice'            => 'purchase_invoice',
+  'sales_invoice'               => 'sales_invoice',
+  'save'                        => 'save',
+  'save_as_new'                 => 'save_as_new',
+  'search'                      => 'search',
+  'select_item'                 => 'select_item',
+  'select_name'                 => 'select_name',
+  'select_project'              => 'select_project',
+  'send_email'                  => 'send_email',
+  'ship_to'                     => 'ship_to',
+  'subtotal'                    => 'subtotal',
+  'update'                      => 'update',
+  'validate_items'              => 'validate_items',
+  'vendor_details'              => 'vendor_details',
+  'yes'                         => 'yes',
+  'agregar'                     => 'add',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'e_mail'                      => 'e_mail',
+  'factura'                     => 'invoice',
+  'imprimir'                    => 'print',
+  'guardar'                     => 'save',
+  'guardar_como_nuevo'          => 'save_as_new',
+  'envíe_a'                     => 'ship_to',
+  'actualizar'                  => 'update',
+  '_sí_'                        => 'yes',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/pe b/sql-ledger/locale/ve/pe
new file mode 100644 (file)
index 0000000..cafe0af
--- /dev/null
@@ -0,0 +1,35 @@
+$self{texts} = {
+  'Add'                         => 'Agregar',
+  'Add Project'                 => 'Agregar Proyecto',
+  'All'                         => 'Todos',
+  'Continue'                    => 'Continuar',
+  'Delete'                      => 'Borrar',
+  'Description'                 => 'Descripción',
+  'Edit Project'                => 'Editar Proyecto',
+  'Number'                      => 'Número',
+  'Orphaned'                    => 'Huérfano',
+  'Project'                     => 'Proyecto',
+  'Project Number missing!'     => 'Falta número de proyecto!',
+  'Project deleted!'            => 'Proyecto borrado!',
+  'Project saved!'              => 'Proyecto guardado!',
+  'Projects'                    => 'Proyectos',
+  'Save'                        => 'Guardar',
+};
+
+$self{subs} = {
+  'add'                         => 'add',
+  'continue'                    => 'continue',
+  'delete'                      => 'delete',
+  'edit'                        => 'edit',
+  'form_footer'                 => 'form_footer',
+  'form_header'                 => 'form_header',
+  'generate_report'             => 'generate_report',
+  'save'                        => 'save',
+  'search'                      => 'search',
+  'agregar'                     => 'add',
+  'continuar'                   => 'continue',
+  'borrar'                      => 'delete',
+  'guardar'                     => 'save',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/rc b/sql-ledger/locale/ve/rc
new file mode 100644 (file)
index 0000000..caeb32a
--- /dev/null
@@ -0,0 +1,37 @@
+$self{texts} = {
+  'Account'                     => 'Cuenta',
+  'Balance'                     => 'Balance',
+  'Cleared Balance'             => 'Cleared Balance',
+  'Continue'                    => 'Continuar',
+  'Date'                        => 'Fecha',
+  'Deposit'                     => 'Deposit',
+  'Description'                 => 'Descripción',
+  'Difference'                  => 'Diferencia',
+  'Done'                        => 'Listo',
+  'Exchangerate Difference'     => 'Diferencial Dambiario',
+  'From'                        => 'Desde',
+  'Out of balance!'             => 'Fuera de balance!',
+  'Payment'                     => 'Pago',
+  'Reconciliation'              => 'Conciliación',
+  'Select all'                  => 'Seleccione todos',
+  'Source'                      => 'Referencia',
+  'Statement Balance'           => 'Balance Estado de Cuenta',
+  'Update'                      => 'Actualizar',
+  'to'                          => 'a',
+};
+
+$self{subs} = {
+  'continue'                    => 'continue',
+  'display_form'                => 'display_form',
+  'done'                        => 'done',
+  'get_payments'                => 'get_payments',
+  'reconciliation'              => 'reconciliation',
+  'select_all'                  => 'select_all',
+  'update'                      => 'update',
+  'continuar'                   => 'continue',
+  'listo'                       => 'done',
+  'seleccione_todos'            => 'select_all',
+  'actualizar'                  => 'update',
+};
+
+1;
diff --git a/sql-ledger/locale/ve/rp b/sql-ledger/locale/ve/rp
new file mode 100644 (file)
index 0000000..bdc2bb6
--- /dev/null
@@ -0,0 +1,116 @@
+$self{texts} = {
+  'AP Aging'                    => 'Vencimientos',
+  'AR Aging'                    => 'Vencimientos',
+  'Account'                     => 'Cuenta',
+  'Accounts'                    => 'Cuentas',
+  'Amount'                      => 'Monto',
+  'Apr'                         => 'abr',
+  'April'                       => 'de abril',
+  'Attachment'                  => 'Anexo',
+  'Aug'                         => 'ago',
+  'August'                      => 'de agosto',
+  'Balance Sheet'               => 'Hoja de Balance',
+  'Bcc'                         => 'Bcc',
+  'Cash based'                  => 'Cash based',
+  'Cc'                          => 'Cc',
+  'Compare to'                  => 'Comparar a',
+  'Continue'                    => 'Continuar',
+  'Copies'                      => 'Copias',
+  'Credit'                      => 'Crédito',
+  'Current'                     => 'Actual',
+  'Customer'                    => 'Cliente',
+  'Date'                        => 'Fecha',
+  'Debit'                       => 'Débito',
+  'Dec'                         => 'dic',
+  'December'                    => 'de diciembre',
+  'Decimalplaces'               => 'Posiciones decimales',
+  'Description'                 => 'Descripción',
+  'Due'                         => 'Vence',
+  'E-mail'                      => 'E-mail',
+  'E-mail Statement to'         => 'Enviar estado de cuenta por E-mail a',
+  'Feb'                         => 'feb',
+  'February'                    => 'de febrero',
+  'From'                        => 'Desde',
+  'GIFI'                        => 'GIFI',
+  'Heading'                     => 'Encabezado',
+  'ID'                          => 'ID',
+  'In-line'                     => 'Incorporado',
+  'Include in Report'           => 'Incluya en Reporte',
+  'Income Statement'            => 'Estado de Cuentas de Ingreso',
+  'Invoice'                     => 'Factura',
+  'Jan'                         => 'ene',
+  'January'                     => 'de enero',
+  'Jul'                         => 'jul',
+  'July'                        => 'de julio',
+  'Jun'                         => 'jun',
+  'June'                        => 'de junio',
+  'Mar'                         => 'mar',
+  'March'                       => 'de marzo',
+  'May'                         => 'may',
+  'May '                        => 'de mayo',
+  'Message'                     => 'Mensaje',
+  'N/A'                         => 'N/D',
+  'Nothing selected!'           => 'Nada seleccionado!',
+  'Nov'                         => 'nov',
+  'November'                    => 'de noviembre',
+  'Oct'                         => 'oct',
+  'October'                     => 'de octubre',
+  'PDF'                         => 'PDF',
+  'Payments'                    => 'Pagos',
+  'Postscript'                  => 'Postscript',
+  'Print'                       => 'Imprimir',
+  'Printer'                     => 'Impresora',
+  'Receipts'                    => 'Ingresos',
+  'Report for'                  => 'Reporte de',
+  'Retained Earnings'           => 'Ganancias Retenidas',
+  'Screen'                      => 'Pantalla',
+  'Select all'                  => 'Seleccione todos',
+  'Select postscript or PDF!'   => 'Seleccione postscript o PDF',
+  'Sep'                         => 'sep',
+  'September'                   => 'de septiembre',
+  'Source'                      => 'Referencia',
+  'Standard'                    => 'Standard',
+  'Statement'                   => 'Estado de Cuenta',
+  'Statement sent to'           => 'Estado de Cuenta enviado a',
+  'Statements sent to printer!' => 'Estados de Cuenta enviados a impresora!',
+  'Subject'                     => 'Materia',
+  'Subtotal'                    => 'Subtotal',
+  'Tax'                         => 'ISV',
+  'Tax collected'               => 'Impuesto recaudado',
+  'Tax paid'                    => 'Impuesto pagado',
+  'Total'                       => 'Total',
+  'Trial Balance'               => 'Balance de Comprobación',
+  'Vendor'                      => 'Proveedor',
+  'as at'                       => 'Al',
+  'collected on sales'          => 'recaudado sobre ventas',
+  'for Period'                  => 'para el período',
+  'paid on purchases'           => 'pagado sobre compras',
+  'to'                          => 'a',
+};
+
+$self{subs} = {
+  'aging'                       => 'aging',
+  'continue'                    => 'continue',
+  'e_mail'                      => 'e_mail',
+  'generate_ap_aging'           => 'generate_ap_aging',
+  'generate_ar_aging'           => 'generate_ar_aging',
+  'generate_balance_sheet'      => 'generate_balance_sheet',
+  'generate_income_statement'   => 'generate_income_statement',
+  'generate_tax_report'         => 'generate_tax_report',
+  'generate_trial_balance'      => 'generate_trial_balance',
+  'list_payments'               => 'list_payments',
+  'print'                       => 'print',
+  'print_form'                  => 'print_form',
+  'print_options'               => 'print_options',
+  'report'                      => 'report',
+  'select_all'                  => 'select_all',
+  'send_email'                  => 'send_email',
+  'statement_details'           => 'statement_details',
+  'tax_subtotal'                => 'tax_subtotal',
+  'continuar'                   => 'continue',
+  'e_mail'                      => 'e_mail',
+  'imprimir'                    => 'print',
+  'seleccione_todos'            => 'select_all',
+};
+
+1;
diff --git a/sql-ledger/login.pl b/sql-ledger/login.pl
new file mode 100755 (executable)
index 0000000..726c780
--- /dev/null
@@ -0,0 +1,132 @@
+#!/usr/bin/perl
+#
+######################################################################
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#######################################################################
+#
+# this script sets up the terminal and runs the scripts
+# in bin/$terminal directory
+# admin.pl is linked to this script
+#
+#######################################################################
+
+
+# setup defaults, these are overidden by sql-ledger.conf
+# DO NOT CHANGE
+$userspath = "users";
+$templates = "templates";
+$memberfile = "users/members";
+$sendmail = "| /usr/sbin/sendmail -t";
+########## end ###########################################
+
+
+$| = 1;
+
+eval { require "sql-ledger.conf"; };
+
+if (-e "$userspath/nologin") {
+  print "
+Login disabled!\n";
+
+  exit;
+}
+
+
+if ($ENV{CONTENT_LENGTH}) {
+  read(STDIN, $_, $ENV{CONTENT_LENGTH});
+}
+
+if ($ENV{QUERY_STRING}) {
+  $_ = $ENV{QUERY_STRING};
+}
+
+if ($ARGV[0]) {
+  $_ = $ARGV[0];
+}
+
+
+%form = split /[&=]/;
+
+# fix for apache 2.0
+map { $form{$_} =~ s/\\$// } keys %form;
+
+# name of this script
+$0 =~ tr/\\/\//;
+$pos = rindex $0, '/';
+$script = substr($0, $pos + 1);
+
+
+if ($form{path}) {
+  $form{path} =~ s/%2[fF]/\//g;
+  $form{path} =~ s/\.\.\///g;
+
+  if ($form{path} !~ /^bin\//) {
+    print "
+Invalid path!\n";
+    die;
+  }
+
+
+  $ARGV[0] = "$_&script=$script";
+  require "$form{path}/$script";
+} else {
+
+  if (!$form{terminal}) {
+    if ($ENV{HTTP_USER_AGENT}) {
+      # web browser
+      if ($ENV{HTTP_USER_AGENT} =~ /(mozilla|links|opera|w3m)/i) {
+       $form{terminal} = "mozilla";
+      }
+
+      if ($ENV{HTTP_USER_AGENT} =~ /lynx/i) {
+       $form{terminal} = "lynx";
+      }
+    } else {
+      if ($ENV{TERM} =~ /xterm/) {
+       $form{terminal} = "xterm";
+      }
+      if ($ENV{TERM} =~ /(console|linux|vt.*)/i) {
+       $form{terminal} = "console";
+      }
+    }
+  }
+
+
+  if ($form{terminal}) {
+
+    $ARGV[0] = "path=bin/$form{terminal}&script=$script";
+    map { $ARGV[0] .= "&${_}=$form{$_}" } keys %form;
+
+    require "bin/$form{terminal}/$script";
+    
+  } else {
+
+    print qq|
+  Unknown terminal
+  |;
+  }
+
+}
+
+# end of main
+
diff --git a/sql-ledger/menu.ini b/sql-ledger/menu.ini
new file mode 100644 (file)
index 0000000..8720798
--- /dev/null
@@ -0,0 +1,394 @@
+[AR]
+
+[AR--Add Transaction]
+module=ar.pl
+action=add
+
+[AR--Sales Invoice]
+module=is.pl
+action=add
+type=invoice
+
+[AR--Reports]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[AR--Reports--Transactions]
+module=ar.pl
+action=search
+nextsub=ar_transactions
+
+[AR--Reports--AR Aging]
+module=rp.pl
+action=report
+report=ar_aging
+
+[AR--Reports--Tax collected]
+module=rp.pl
+action=report
+report=tax_collected
+
+[AR--Customers]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[AR--Customers--Add Customer]
+module=ct.pl
+action=add
+db=customer
+
+[AR--Customers--Reports]
+module=ct.pl
+action=search
+db=customer
+
+[AP]
+
+[AP--Add Transaction]
+module=ap.pl
+action=add
+
+[AP--Vendor Invoice]
+module=ir.pl
+action=add
+type=invoice
+
+[AP--Reports]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[AP--Reports--Transactions]
+module=ap.pl
+action=search
+nextsub=ap_transactions
+
+[AP--Reports--AP Aging]
+module=rp.pl
+action=report
+report=ap_aging
+
+[AP--Reports--Tax paid]
+module=rp.pl
+action=report
+report=tax_paid
+
+[AP--Vendors]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[AP--Vendors--Add Vendor]
+module=ct.pl
+action=add
+db=vendor
+
+[AP--Vendors--Reports]
+module=ct.pl
+action=search
+db=vendor
+
+[Cash]
+
+[Cash--Receipt]
+module=cp.pl
+action=payment
+vc=customer
+
+[Cash--Payment]
+module=cp.pl
+action=payment
+vc=vendor
+
+[Cash--Reports]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[Cash--Reports--Receipts]
+module=rp.pl
+action=report
+report=receipts
+
+[Cash--Reports--Payments]
+module=rp.pl
+action=report
+report=payments
+
+[Cash--Reconciliation]
+module=rc.pl
+action=reconciliation
+
+[Order Entry]
+
+[Order Entry--Sales Order]
+module=oe.pl
+action=add
+type=sales_order
+
+[Order Entry--Purchase Order]
+module=oe.pl
+action=add
+type=purchase_order
+
+[Order Entry--Reports]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[Order Entry--Reports--Sales Orders]
+module=oe.pl
+action=search
+type=sales_order
+
+[Order Entry--Reports--Purchase Orders]
+module=oe.pl
+action=search
+type=purchase_order
+
+[General Ledger]
+
+[General Ledger--Add Transaction]
+module=gl.pl
+action=add
+
+[General Ledger--Reports]
+module=gl.pl
+action=search
+
+[Goods & Services]
+
+[Goods & Services--Add Part]
+module=ic.pl
+action=add
+item=part
+
+[Goods & Services--Add Service]
+module=ic.pl
+action=add
+item=service
+
+[Goods & Services--Add Assembly]
+module=ic.pl
+action=add
+item=assembly
+
+[Goods & Services--Add Group]
+module=pe.pl
+action=add
+type=partsgroup
+
+[Goods & Services--Stock Assembly]
+module=ic.pl
+action=stock_assembly
+
+[Goods & Services--Reports]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[Goods & Services--Reports--Parts]
+module=ic.pl
+action=search
+searchitems=part
+
+[Goods & Services--Reports--Services]
+module=ic.pl
+action=search
+searchitems=service
+
+[Goods & Services--Reports--Assemblies]
+module=ic.pl
+action=search
+searchitems=assembly
+
+[Goods & Services--Reports--Groups]
+module=pe.pl
+action=search
+type=partsgroup
+
+[Projects]
+
+[Projects--Add Project]
+module=pe.pl
+action=add
+type=project
+
+[Projects--Reports]
+module=pe.pl
+action=search
+type=project
+
+[Reports]
+
+[Reports--Chart of Accounts]
+module=ca.pl
+action=chart_of_accounts
+
+[Reports--Trial Balance]
+module=rp.pl
+action=report
+report=trial_balance
+
+[Reports--Income Statement]
+module=rp.pl
+action=report
+report=income_statement
+
+[Reports--Balance Sheet]
+module=rp.pl
+action=report
+report=balance_sheet
+
+[System]
+
+[System--Chart of Accounts]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[System--Chart of Accounts--Add Account]
+module=am.pl
+action=add
+
+[System--Chart of Accounts--List Accounts]
+module=am.pl
+action=list
+
+[System--Chart of Accounts--Add GIFI]
+module=am.pl
+action=add_gifi
+
+[System--Chart of Accounts--List GIFI]
+module=am.pl
+action=list_gifi
+
+[System--HTML Templates]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[System--HTML Templates--Income Statement]
+module=am.pl
+action=display_form
+file=templates=income_statement.html
+
+[System--HTML Templates--Balance Sheet]
+module=am.pl
+action=display_form
+file=templates=balance_sheet.html
+
+[System--HTML Templates--Invoice]
+module=am.pl
+action=display_form
+file=templates=invoice.html
+
+[System--HTML Templates--Packing List]
+module=am.pl
+action=display_form
+file=templates=packing_list.html
+
+[System--HTML Templates--Sales Order]
+module=am.pl
+action=display_form
+file=templates=sales_order.html
+
+[System--HTML Templates--Purchase Order]
+module=am.pl
+action=display_form
+file=templates=purchase_order.html
+
+[System--HTML Templates--Statement]
+module=am.pl
+action=display_form
+file=templates=statement.html
+
+[System--LaTeX Templates]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[System--LaTeX Templates--Invoice]
+module=am.pl
+action=display_form
+file=templates=invoice.tex
+
+[System--LaTeX Templates--Packing List]
+module=am.pl
+action=display_form
+file=templates=packing_list.tex
+
+[System--LaTeX Templates--Sales Order]
+module=am.pl
+action=display_form
+file=templates=sales_order.tex
+
+[System--LaTeX Templates--Purchase Order]
+module=am.pl
+action=display_form
+file=templates=purchase_order.tex
+
+[System--LaTeX Templates--Statement]
+module=am.pl
+action=display_form
+file=templates=statement.tex
+
+[System--LaTeX Templates--Check]
+module=am.pl
+action=display_form
+file=templates=check.tex
+
+[System--LaTeX Templates--Receipt]
+module=am.pl
+action=display_form
+file=templates=receipt.tex
+
+[System--Stylesheet]
+module=am.pl
+action=display_stylesheet
+
+[System--Backup]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[System--Backup--Send by E-Mail]
+module=am.pl
+action=backup
+media=email
+
+[System--Backup--Save to File]
+module=am.pl
+action=backup
+media=file
+
+[System--Audit Control]
+module=am.pl
+action=audit_control
+
+[System--Preferences]
+module=am.pl
+action=config
+
+[Version]
+module=login.pl
+action=company_logo
+
+[Logout]
+module=login.pl
+action=logout
+target=_top
+
diff --git a/sql-ledger/setup.pl b/sql-ledger/setup.pl
new file mode 100755 (executable)
index 0000000..740a869
--- /dev/null
@@ -0,0 +1,594 @@
+#!/usr/bin/perl
+#
+######################################################################
+# SQL-Ledger, Accounting Software Installer
+# Copyright (c) 2002, Dieter Simader
+#
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#######################################################################
+
+$| = 1;
+
+if ($ENV{HTTP_USER_AGENT}) {
+  print "
+This does not work yet!
+use $0 from the command line";
+  exit;
+}
+
+$lynx = `lynx -version`;      # if LWP is not installed use lynx
+$gzip = `gzip -V 2>&1`;            # gz decompression utility
+$tar = `tar --version 2>&1`;       # tar archiver
+$latex = `latex -version`;
+
+@source = ( "http://unc.dl.sourceforge.net/sourceforge/sql-ledger",
+            "http://www.sql-ledger.org/source",
+           "http://abacus.sql-ledger.org/source" );
+
+$userspath = "users";         # default for new installation
+
+eval { require "sql-ledger.conf"; };
+
+$filename = shift;
+
+# is LWP installed
+eval { require LWP::Simple; };
+$lwp = !($@);
+
+unless ($lwp || $lynx || $filename) {
+  die "You must have either lynx or LWP installed
+or specify a filename.
+perl $0 filename\n";
+}
+
+if ($filename) {
+  # extract version
+  die "Not a SQL-Ledger archive\n" if ($filename !~ /^sql-ledger/);
+  
+  $version = $filename;
+  $version =~ s/sql-ledger-(\d+\.\d+\.\d+).*$/$1/;
+
+  $newinstall = 1;
+}
+  
+if (!$filename && -f "VERSION") {
+  # get installed version from VERSION file
+  open(FH, "VERSION");
+  @a = <FH>;
+  close(FH);
+  $version = $a[0];
+  chomp $version;
+
+  $newinstall = !$version;
+} else {
+  $newinstall = 1;
+}
+
+
+$webowner = $<;
+$webgroup = $(;
+
+if ($httpd = `find /etc /usr/local/etc -type f -name 'httpd.conf'`) {
+  chomp $httpd;
+  $webowner = `grep "^User " $httpd`;
+  $webgroup = `grep "^Group " $httpd`;
+  $serverroot = `grep "^ServerRoot " $httpd`;
+
+  chomp $webowner;
+  chomp $webgroup;
+  chomp $serverroot;
+  
+  ($null, $webowner) = split / /, $webowner;
+  ($null, $webgroup) = split / /, $webgroup;
+  ($null, $serverroot) = split / /, $serverroot;
+
+  $serverroot =~ s/"//g;
+  
+}
+
+system("tput clear");
+
+if ($filename) {
+  $install = "\ninstall $version from (f)ile\n";
+}
+
+# check for latest version
+&get_latest_version;
+
+if (!$newinstall) {
+
+  $install .= "\n(r)einstall $version\n";
+  
+}
+
+if ($version && $latest_version) {
+  if (!$filename && $version ne $latest_version) {
+    if (substr($version, 0, rindex($version, ".")) eq substr($latest_version, 0, rindex($latest_version, "."))) {
+      $install .= "\n(u)pgrade to $latest_version\n";
+    }
+  }
+}
+
+
+$install .= "\n(i)nstall $latest_version (from Internet)\n" if $latest_version;
+
+$install .= "\n(d)ownload $latest_version (no installation)" unless $filename;
+
+  print qq|
+
+
+               SQL-Ledger Accounting Software Installation
+
+
+
+$install
+
+
+Enter: |;
+
+$a = <STDIN>;
+chomp $a;
+
+exit unless $a;
+$a = lc $a;
+
+  if ($newinstall && ($a =~ /(i|r|f)/)) {
+
+    print qq|\nEnter httpd owner [$webowner] : |;
+    $web = <STDIN>;
+    chomp $web;
+    $webowner = $web if $web;
+
+    print qq|\nEnter httpd group [$webgroup] : |;
+    $web = <STDIN>;
+    chomp $web;
+    $webgroup = $web if $web;
+    
+  }
+
+if ($a eq 'd') {
+  &download;
+}
+if ($a eq 'i') {
+  &install;
+}
+if ($a eq 'r') {
+  $latest_version = $version;
+  &install;
+}
+if ($a eq 'u') {
+  &upgrade;
+}
+
+if ($a eq 'f') {
+  &install;
+}
+
+exit;
+# end main
+
+
+sub download {
+
+  &get_source_code;
+
+}
+
+
+sub get_latest_version {
+  
+  print "Checking for latest version number .... ";
+
+  if ($filename) {
+    print "skipping, filename supplied\n";
+    return;
+  }
+
+  if ($lwp) {
+    foreach $source (@source) {
+      $host = $source;
+      $host =~ s/(\w\/).*/$1/g;
+      chop $host;
+      print "\nTrying $host ... ";
+
+      $latest_version = LWP::Simple::get("$source/latest_version");
+      
+      if ($latest_version) {
+       last;
+      } else {
+       print "not found";
+      }
+    }
+  } else {
+    if (!$lynx) {
+      print "\nYou must have either lynx or LWP installed";
+      exit 1;
+    }
+
+    foreach $source (@source) {
+      $host = $source;
+      $host =~ s/(\w\/).*/$1/g;
+      chop $host;
+      print "\nTrying $host ... ";
+      $ok = `lynx -dump -head $source/latest_version`;
+      if ($ok = ($ok =~ s/HTTP.*?200 OK//g)) {
+       $latest_version = `lynx -dump $source/latest_version`;
+       chomp $latest_version;
+       last;
+      } else {
+       print "not found";
+      }
+    }
+    die unless $ok;
+  }
+
+  chomp $latest_version;
+  if ($latest_version) {
+    print "ok\n";
+    1;
+  }
+
+}
+
+
+sub get_source_code {
+
+  $err = 0;
+  if ($latest_version) {
+    # download it
+    $latest_version = "sql-ledger-${latest_version}.tar.gz";
+    
+    print "\nStatus\n";
+    print "Downloading $latest_version .... ";
+
+    foreach $source (@source) {
+      $host = $source;
+      $host =~ s/(\w\/).*/$1/g;
+      chop $host;
+      print "\nTrying $host .... ";
+    
+      if ($lwp) {
+       $err = LWP::Simple::getstore("$source/$latest_version", "$latest_version");
+       $err -= 200;
+      } else {
+       $ok = `lynx -dump -head $source/$latest_version`;
+       $err = !($ok =~ s/HTTP.*?200 OK//);
+
+       if (!$err) {
+         $err = system("lynx -dump $source/$latest_version > $latest_version");
+       }
+      }
+
+      last unless $err;
+
+    }
+    
+  } else {
+    $err = -1;
+  }
+  
+  if ($err) {
+    die "Cannot get $latest_version";
+  } else {
+    print "ok\n";
+  }
+
+  $latest_version;
+
+}
+
+
+sub install {
+
+  if ($filename) {
+    $latest_version = $filename;
+  } else {
+    $latest_version = &get_source_code;
+  }
+
+  &decompress;
+
+  if ($upgrade) {
+    print qq|
+
+Don't forget to upgrade the datasets!
+
+Load the admin panel in your web browser
+|;
+  }
+
+  if ($newinstall) {
+    # if this is not root, check if user is part of $webgroup
+    if ($>) {
+      if ($permset = ($) =~ getgrnam $webgroup)) {
+       `chown -R :$webgroup *`;
+      }
+    } else {
+      `chown -R $webowner:$webgroup *`;
+    }
+    
+    chmod 0771, 'users', 'templates';
+
+    open(FH, "sql-ledger.conf.default");
+    @f = <FH>;
+    close(FH);
+    unless ($latex) {
+      grep { s/^\$latex.*/\$latex = 0;/ } @f;
+    }
+    open(FH, ">sql-ledger.conf");
+    print FH @f;
+    close(FH);
+
+    $alias = $absolutealias = $ENV{'PWD'};
+    $alias =~ s/.*\///g;
+    
+    $httpddir = `dirname $httpd`;
+    chomp $httpddir;
+    $filename = "sql-ledger-httpd.conf";
+
+    # do we have write permission?
+    if (!open(FH, ">>$httpddir/$filename")) {
+      open(FH, ">$filename");
+      $norw = 1;
+    }
+
+    $directives = qq|
+Alias /$alias/ $absolutealias/
+<Directory $absolutealias>
+  AllowOverride All
+  AddHandler cgi-script .pl
+  Options ExecCGI Includes FollowSymlinks
+  Order Allow,Deny
+  Allow from All
+</Directory>
+
+<Directory $absolutealias/users>
+  Order Deny,Allow
+  Deny from All
+</Directory>
+  
+|;
+
+    print FH $directives;
+    close(FH);
+    
+    print qq|
+This is a new installation.
+
+|;
+
+    if ($norw) {
+      print qq|
+Webserver directives were written to $filename
+      
+Copy $filename to $httpddir and add
+|;
+
+      # strip serverroot off httpddir
+      $httpddir =~ s/$serverroot\///;
+
+      print qq|
+Include $httpddir/$filename
+
+to $httpd
+
+Don't forget to restart your webserver!
+|;
+
+      if (!$permset) {
+       print qq|
+WARNING: permissions for templates and users directory
+could not be set. Login as root and set permissions
+
+# chown $webowner:$webgroup users templates
+# chmod 771 users templates
+
+|;
+      }
+
+    } else {
+      
+      if (!(`grep "^# SQL-Ledger" $httpd`)) {
+       # append Include directive
+       $httpddir =~ s/$serverroot\///;
+
+       open(FH, ">>$httpd");
+
+       print FH qq|
+
+# SQL-Ledger
+Include $httpddir/$filename
+|;
+       close(FH);
+        
+        print qq|
+Webserver directives were written to
+
+  $httpddir/$filename
+|;
+      }
+    }
+
+    if (!$>) {
+      # send SIGHUP to httpd
+      $pid = `cat /var/run/httpd.pid`;
+      chomp $pid;
+      system("kill -s HUP $pid") if $pid;
+    }
+  }
+
+  unlink "sql-ledger.conf.default";
+
+  &cleanup;
+
+  while ($a !~ /(Y|N)/) {
+    print qq|\nDisplay README (Y/n) : |;
+    $a = <STDIN>;
+    chomp $a;
+    $a = ($a) ? uc $a : 'Y';
+    
+    if ($a eq 'Y') {
+      @args = ("more", "doc/README");
+      system(@args);
+    }
+  }
+  
+}
+
+
+sub decompress {
+  
+  die "Error: gzip not installed\n" unless ($gzip);
+  die "Error: tar not installed\n" unless ($tar);
+  
+  &create_lockfile;
+
+  # ungzip and extract source code
+  print "Decompressing $latest_version ... ";
+    
+  if (system("gzip -df $latest_version")) {
+    print "Error: Could not decompress $latest_version\n";
+    &remove_lockfile;
+    exit;
+  } else {
+    print "done\n";
+  }
+
+  # strip gz from latest_version
+  $latest_version =~ s/\.gz//;
+  
+  # now untar it
+  print "Unpacking $latest_version ... ";
+  if (system("tar -xf $latest_version")) {
+    print "Error: Could not unpack $latest_version\n";
+    &remove_lockfile;
+    exit;
+  } else {
+    # now we have a copy in sql-ledger
+    if (system("tar -cf $latest_version -C sql-ledger .")) {
+      print "Error: Could not create archive for $latest_version\n";
+      &remove_lockfile;
+      exit;
+    } else {
+      if (system("tar -xf $latest_version")) {
+        print "Error: Could not unpack $latest_version\n";
+       &remove_lockfile;
+       exit;
+      } else {
+        print "done\n";
+        print "cleaning up ... ";
+        `rm -rf sql-ledger`;
+        print "done\n";
+      }
+    }
+  }
+}
+
+
+sub create_lockfile {
+
+  if (-d "$userspath") {
+    open(FH, ">$userspath/nologin");
+    close(FH);
+    $upgrade = 1;
+  }
+  
+}
+
+
+sub cleanup {
+
+  unlink "$latest_version";
+  unlink "$userspath/members.default" if (-f "$userspath/members.default");
+
+  &remove_lockfile;
+  
+}
+
+
+sub remove_lockfile { unlink "$userspath/nologin" if (-f "$userspath/nologin") };
+
+
+sub upgrade {
+
+  $latest_version = &get_patch;
+
+  &decompress;
+  &cleanup;
+  
+  # if this is not root, check if user is part of $webgroup
+  if ($>) {
+    if ($permset = ($) =~ getgrnam $webgroup)) {
+      `chown -R :$webgroup *`;
+    }
+  } else {
+    `chown -R $webowner:$webgroup *`;
+  }
+  
+  chmod 0771, 'users', 'templates';
+
+
+  print qq|
+
+Don't forget to upgrade your datasets and read
+the upgrade file in the doc directory.
+
+|;
+
+}
+
+
+
+sub get_patch {
+
+  $err = 0;
+  if ($version) {
+    # download the patch
+    $patchfile = "patch-${latest_version}.tar.gz";
+    
+    print "Status\n";
+    print "Downloading $patchfile .... ";
+    
+    foreach $source (@source) {
+      $host = $source;
+      $host =~ s/(\w\/).*/$1/g;
+      chop $host;
+      print "\nTrying $host .... ";
+    
+      if ($lwp) {
+       $err = LWP::Simple::getstore("$source/$patchfile", "$patchfile");
+       $err -= 200;
+      } else {
+       $ok = `lynx -dump -head $source/$patchfile`;
+       $err = !($ok =~ /HTTP.*?200 OK/);
+       
+       if (!$err) {
+         $err = system("lynx -dump $source/$patchfile > $patchfile");
+       }
+      }
+
+      last unless $err;
+      
+    }
+    
+  } else {
+    $err = -1;
+  }
+  
+  if ($err) {
+    print "Cannot get $patchfile\n";
+    exit;
+  } else {
+    print "ok\n";
+  }
+
+  $patchfile;
+
+}
+
+
diff --git a/sql-ledger/sql-ledger.conf.default b/sql-ledger/sql-ledger.conf.default
new file mode 100644 (file)
index 0000000..96fb9b8
--- /dev/null
@@ -0,0 +1,33 @@
+use vars qw($userspath $memberfile $templates $sendmail $language $sid);
+
+# path to user configuration files
+# you may use an absolute path i.e. /var/tmp
+$userspath = "users";
+
+# templates base directory; this one needs to be here for now
+$templates = "templates";
+
+# member file, could also be in "/usr/local/etc/slusers"
+$memberfile = "users/members";
+
+# location of sendmail
+$sendmail = "| /usr/sbin/sendmail -t";
+
+# set language for login and admin; two letter code
+$language = "";
+
+# Oracle
+$sid = "T80509";
+$ENV{"ORACLE_HOME"} = "/usr/local/oracle";
+
+# if you have latex installed set to 1
+$latex = 1;
+
+# if the server can't find latex, dvips or pdflatex, add the path
+$ENV{PATH} .= ":/usr/local/bin";
+
+# on mac os X using Fink's Perl libs, add the path
+$ENV{PERL5LIB} .= ":/sw/lib/perl5";
+
+
+1;
diff --git a/sql-ledger/sql-ledger.png b/sql-ledger/sql-ledger.png
new file mode 100644 (file)
index 0000000..0297a1b
Binary files /dev/null and b/sql-ledger/sql-ledger.png differ
diff --git a/sql-ledger/sql/Austria-chart.sql b/sql-ledger/sql/Austria-chart.sql
new file mode 100644 (file)
index 0000000..85810c5
--- /dev/null
@@ -0,0 +1,143 @@
+-- Kontoplan für Österreich
+-- Ferdinand Gassauer, Tue, 5 Feb 2002
+-- checked and completed, Thu, 7 Feb 2002, Dieter Simader
+--
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0000','AUFWENDUNGEN FÜR INGANGSETZEN UND ERWEITERN DES BETRIEBES','H','00','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0010','Firmenwert','A','015','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0100','IMMATERIELLE VERMÖGENSGEGENSTÄNDE','H','01','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0110','Rechte','A','011','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0200','GRUNDSTÜCKE','H','02-03','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0210','unbebaute Grundstücke','A','020','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0220','bebaute Grundstücke','A','021','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0229','kum. Abschreibung bebaute Grundstücke','A','039','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0400','MASCHINEN','H','04-05','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0410','Maschinen','A','041','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0419','kum. Abschreibung Maschinen','A','069','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0500','FAHRZEUGE','H','06','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0510','Fahrzeuge','A','063','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0519','kum. Abschreibung Fahrzeuge','A','069','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0600','BETRIEBS- UND GESCHÄFTSAUSSTATTUNG','H','06','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0620','Büroeinrichtungen','A','066','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0625','kum. Abschreibung Betriebs- und Geschäftsausstattung','A','069','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0700','GELEISTETE ANZAHLUNGEN','H','07','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0800','FINANZANLAGEN','H','08-09','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0810','Beteiligungen','A','081','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0820','Wertpapiere','A','080','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1100','ROHSTOFFE','H','1','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1120','Vorräte - Rohstoffe','A','110-119','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1200','BEZOGENE TEILE','H','1','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1220','Vorräte - bezogene Teile','A','120-129','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1300','HILFS- UND BETRIEBSSTOFFE','H','1','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1320','Hilfsstoffe','A','130-134','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1350','Betriebssstoffe','A','135-139','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1400','UNFERTIGE ERZEUGNISSE','H','1','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1420','Vorräte - unfertige Erzeugnisse','A','140-149','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1500','FERTIGE ERZEUGNISSE','H','1','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1520','Vorräte - Hardware','A','150-159','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1530','Vorräte - Software','A','150-159','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1540','Vorräte - Ersatzteile','A','150-159','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1600','WAREN','H','1','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1700','NOCH NICHT ABGERECHNETE LEISTUNGEN','H','1','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1800','GELEISTETE ANZAHLUNGEN','H','1','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1900','WERTBERICHTIGUNGEN','H','1','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2000','FORDEUNGEN AUS LIEFERUNGEN UND LEISTUNGEN','H','2','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2010','Forderungen Lieferung & Leistung','A','200-207','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2019','Wertberichtigung uneinbringliche Forderungen','A','20-21','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2300','SONSTIGE FORDERUNGEN','H','2','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2320','sonstige Forderungen','A','23-24','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2500','FORDERUNGEN AUS ABGABENVERRECHNUNG','H','2','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2520','sonstige Forderungen aus Abgebenverrechnung','A','25','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2600','WERTPAPIERE UND ANTEILE','H','2','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2620','Wertpapiere Umlaufvermögen','A','26','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2700','KASSABESTAND','H','2','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2701','Kassa','A','27-28','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2800','SCHECKS, GUTHABEN BEI KREDITINSTITUTEN','H','2','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2810','Schecks','A','27-28','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2820','Bankguthaben','A','280-288','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3100','LANGFRISTIGE VERBINDLICHKEITEN','H','3','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3110','Bank Verbindlichkeiten','A','31','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3120','Kredite von Eigentümern','A','310','L','AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3300','VERBINDLICHKEITEN AUS LIEFERUNGEN UND LEISTUNGEN','H','33','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3310','Verbindlichkeiten aus Lieferungen und Leistungen','A','330-335','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3500','VERBINDLICHKEITEN FINANZAMT','H','35','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3510','Finanzamt Verrechnung Körperschaftssteuer','A','350-359','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3520','Finanzamt Verrechnung Umsatzsteuer','A','350-359','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3530','Mehrwertsteuer 0%','A','350-359','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3531','Mehrwertsteuer 10%','A','350-359','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3532','Mehrwertsteuer 20%','A','350-359','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3540','Vorsteuer 0%','A','350-359','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3541','Vorsteuer 10%','A','350-359','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3542','Vorsteuer 20%','A','350-359','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4000','UMSATZ','H','4','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4020','Verkauf - Hardware','A','40-44','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4030','Verkauf - Software ','A','40-44','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4040','Verkauf - Ersatzteile','A','40-44','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4300','UMSATZ BERATUNG','H','4','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4320','Erlöse Beratung','A','40-44','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4330','Erlöse Programmierung','A','40-44','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4600','SONSTIGE ERLÖSE','H','4','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4630','Frachterlöse','A','46-49','I','IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5000','WARENEINSATZ','H','5','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5020','Wareneinsatz / Hardware','A','500-509','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5030','Wareneinsatz / Software','A','500-509','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5040','Wareneinsatz / Ersatzteile','A','520-529','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5600','VERBRAUCH BRENN- UND TREIBSTOFFEN, ENERGIE UND WASSER','H','5','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5610','Energie, Wasser','A','560-569','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6000','LOHNAUFWAND','H','6','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6010','Lohn ','A','600-619','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6200','GEAHLTSAUFWAND','H','6','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6210','Gehalt ','A','620-639','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6500','GESETZLICHER SOZIALAUFWAND','H','6','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6510','Dienstgeberanteile','A','645-649','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6700','FREIWILLIGER SOZIALAUFWAND','H','6','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6710','freiwilliger Sozialaufwand','A','660-665','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7000','ABSCHREIBUNGEN','H','7','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7010','Abschreibungen','A','700','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7020','geringwertige Wirtschaftsgüter','A','701-708','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7100','SONSTIGE STEUERN','H','71','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7110','Ertragssteuern','A','710-719','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7120','Grundsteuern','A','710-719','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7200','INSTANDHALTUNGSAUFWAND','H','7','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7210','Reparatur und Instandhaltung','A','720-729','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7300','TRANSPORTKOSTEN','H','73','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7310','Frachtaufwand','A','730-731','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7400','MIET-,PACHT-,LEASING-, LIZENZAUFWAND','H','74','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7410','Miete','A','740-743','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7411','Lizenzen','A','748-749','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7600','VERWALTUNGSKOSTEN','H','76','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7610','Beratungsaufwand','A','775-776','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7611','Büromaterialien','A','760','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7615','Werbung und Marketing','A','765-768','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7620','uneinbringliche Forderungen','A','799','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7630','Telephonkosten','A','738-739','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7631','Internetkosten','A','738-739','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7632','Reise- und Repräsentationsaufwand','A','734-735','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7634','Registrierungsgebühren','A','748-749','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7700','VERSICHERUNGEN','H','77-78','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7710','Versicherung','A','770-774','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8000','FINANZERTRÄGE UND FINANZAUFWENDUNGEN','H','8','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8020','Bankzinsen und Gebühren','A','80-83','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8100','BETEILIGUNGSERTRÄGE','H','8','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8110','Erträge aus Beteiligungen','A','800-804','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9000','KAPITAL','H','9','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9010','Aktien, Geschäftsanteile','A','900-918','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9020','nicht einbezahltes Kapital','A','919','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9200','KAPITALRÜCKLAGEN','H','9','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9210','freie Rücklage','A','920-929','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9300','GEWINN','H','939','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9310','Gewinnvortrag Vorjahr','A','980','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9320','Jahresgewinn','A','985','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9400','RÜCKSTELLUNGEN','H','3','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9420','Abfertigungsrückstellung','A','300','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9430','Urlaubsrückstellung','A','304-309','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9700','EINLAGEN STILLER GESELLSCHAFTER','H','9','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9800','EB,SB,G+V KONTEN','H','9','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4640','Devisengewinne','A','80-83','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8050','Devisenverluste','A','80-83','E','');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '3530'),0.00);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '3531'),0.10);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '3532'),0.20);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '1520'), income_accno_id = (select id from chart where accno = '4020'), expense_accno_id = (select id from chart where accno = '7610'), fxgain_accno_id = (select id from chart where accno = '4640'), fxloss_accno_id = (select id from chart where accno = '8050'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'EUR:USD', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/Austria-gifi.sql b/sql-ledger/sql/Austria-gifi.sql
new file mode 100644 (file)
index 0000000..43f213f
--- /dev/null
@@ -0,0 +1,334 @@
+-- Österreichischer Einheitskontenrahmen / Kontenplan (ÖSV Österreichischer Steuerverein)
+--
+INSERT INTO gifi (accno, description) VALUES ('0', 'Anlagevermögen und Aufwendungen für das Ingangsetzen und Erweitern eines Betriebes');
+--
+INSERT INTO gifi (accno, description) VALUES ('00', 'Aufwendungen für das Ingangsetzen und Erweitern eines Betriebes');
+INSERT INTO gifi (accno, description) VALUES ('001', 'Aufwendungen für das Ingangsetzen und Erweitern eines Betriebes');
+INSERT INTO gifi (accno, description) VALUES ('009', 'Kumulierte Abschreibungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('01', 'Immaterielle Vermögensgegenstände');
+INSERT INTO gifi (accno, description) VALUES ('010', 'Konzessionen');
+INSERT INTO gifi (accno, description) VALUES ('011', 'Patentrechte und Lizenzen');
+INSERT INTO gifi (accno, description) VALUES ('012', 'Datenverarbeitungsprogramme');
+INSERT INTO gifi (accno, description) VALUES ('013', 'Marken, Warenzeichen und Musterschutzrechte, sonstige Urheberrechte');
+INSERT INTO gifi (accno, description) VALUES ('014', 'Pacht- und Mietrechte');
+INSERT INTO gifi (accno, description) VALUES ('015', 'Geschäfts(Firmen)wert');
+INSERT INTO gifi (accno, description) VALUES ('018', 'Geleistete Anzahlungen');
+INSERT INTO gifi (accno, description) VALUES ('019', 'Kumulierte Abschreibungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('02-03', 'Grundstücke, grundstücksgleiche Rechte und Bauten, einschließlich der Bauten auf fremden Grund');
+INSERT INTO gifi (accno, description) VALUES ('020', 'Unbebaute Grundstücke');
+INSERT INTO gifi (accno, description) VALUES ('021', 'Bebaute Grundstücke (Grundwert)');
+INSERT INTO gifi (accno, description) VALUES ('022', 'Grundstücksgleiche Rechte');
+INSERT INTO gifi (accno, description) VALUES ('030', 'Betriebs- und Geschäftsgebäude auf eigenem Grund');
+INSERT INTO gifi (accno, description) VALUES ('031', 'Wohn- und Sozialgebäude auf eigenem Grund');
+INSERT INTO gifi (accno, description) VALUES ('032', 'Betriebs- und Geschäftsgebäude auf fremdem Grund');
+INSERT INTO gifi (accno, description) VALUES ('033', 'Wohn- und Sozialgebäude auf fremdem Grund');
+INSERT INTO gifi (accno, description) VALUES ('034', 'Grundstückseinrichtungen auf eigenem Grund');
+INSERT INTO gifi (accno, description) VALUES ('035', 'Grundstückseinrichtungen auf fremdem Grund');
+INSERT INTO gifi (accno, description) VALUES ('036', 'Bauliche Investitionen in fremden (gepachteten) Betriebs- und Geschäftsgebäuden');
+INSERT INTO gifi (accno, description) VALUES ('037', 'Bauliche Investitionen in fremden (gepachteten) Wohn- und Sozialgebäuden');
+INSERT INTO gifi (accno, description) VALUES ('039', 'Kumulierte Abschreibungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('04-05', 'Technische Anlagen und Maschinen');
+INSERT INTO gifi (accno, description) VALUES ('040', 'Fertigungsmaschinen');
+INSERT INTO gifi (accno, description) VALUES ('041', 'Antriebsmaschinen');
+INSERT INTO gifi (accno, description) VALUES ('042', 'Energieversorgungsanlagen');
+INSERT INTO gifi (accno, description) VALUES ('043', 'Transportanlagen');
+INSERT INTO gifi (accno, description) VALUES ('044-049', 'Sonstige Maschinen und maschinelle Anlagen');
+INSERT INTO gifi (accno, description) VALUES ('050', 'Maschinenwerkzeuge');
+INSERT INTO gifi (accno, description) VALUES ('051', 'Allgemeine Werkzeuge und Handwerkzeuge');
+INSERT INTO gifi (accno, description) VALUES ('052', 'Vorrichtungen, Formen und Modelle');
+INSERT INTO gifi (accno, description) VALUES ('053', 'Andere Erzeugungshilfsmittel');
+INSERT INTO gifi (accno, description) VALUES ('054', 'Hebezeuge und Montageanlagen');
+INSERT INTO gifi (accno, description) VALUES ('055', 'Geringwertige Vermögensgegenstände, soweit im Erzeugungsprozeß verwendet');
+--
+INSERT INTO gifi (accno, description) VALUES ('06', 'Andere Anlagen, Betriebs- und Geschäftsausstattung');
+INSERT INTO gifi (accno, description) VALUES ('060', 'Beheizungs- und Beleuchtungsanlagen');
+INSERT INTO gifi (accno, description) VALUES ('061', 'Nachrichten- und Kontrollanlagen');
+INSERT INTO gifi (accno, description) VALUES ('062', 'Büromaschinen, EDV-Anlagen');
+INSERT INTO gifi (accno, description) VALUES ('063', 'PKW');
+INSERT INTO gifi (accno, description) VALUES ('064', 'LKW');
+INSERT INTO gifi (accno, description) VALUES ('065', 'Andere Beförderungsmittel');
+INSERT INTO gifi (accno, description) VALUES ('066', 'Andere Betriebs- und Geschäftsausstattung');
+INSERT INTO gifi (accno, description) VALUES ('067', 'Gebinde');
+INSERT INTO gifi (accno, description) VALUES ('068', 'Geringwertige Vermögensgegenstände, soweit nicht im Erzeugungsprozeß verwendet');
+INSERT INTO gifi (accno, description) VALUES ('069', 'Kumulierte Abschreibungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('07', 'Geleistete Anzahlungen und Anlagen in Bau');
+INSERT INTO gifi (accno, description) VALUES ('070', 'Geleistete Anzahlungen');
+INSERT INTO gifi (accno, description) VALUES ('071', 'Anlagen in Bau');
+INSERT INTO gifi (accno, description) VALUES ('079', 'Kumulierte Abschreibungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('08-09', 'Finanzanlagen');
+INSERT INTO gifi (accno, description) VALUES ('080', 'Anteile an verbundenen Unternehmen');
+INSERT INTO gifi (accno, description) VALUES ('081', 'Beteiligungen an Gemeinschaftsunternehmen');
+INSERT INTO gifi (accno, description) VALUES ('082', 'Beteiligungen an angeschlossenen (assoziierten) Unternehmen');
+INSERT INTO gifi (accno, description) VALUES ('083', 'Sonstige Beteiligungen');
+INSERT INTO gifi (accno, description) VALUES ('084', 'Ausleihungen an verbundene Unternehmen');
+INSERT INTO gifi (accno, description) VALUES ('085', 'Ausleihungen an Unternehmen, mit denen ein Beteiligungsverhältnis besteht');
+INSERT INTO gifi (accno, description) VALUES ('086', 'Sonstige Ausleihungen');
+INSERT INTO gifi (accno, description) VALUES ('087', 'Anteile an Kapitalgesellschaften ohne Beteiligungscharakter');
+INSERT INTO gifi (accno, description) VALUES ('088', 'Anteile an Personengesellschaften ohne Beteiligungscharakter');
+INSERT INTO gifi (accno, description) VALUES ('090', 'Genossenschaftsanteile ohne Beteiligungscharakter');
+INSERT INTO gifi (accno, description) VALUES ('091', 'Anteile an Investmentfonds');
+INSERT INTO gifi (accno, description) VALUES ('092-093', 'Festverzinsliche Wertpapiere des Anlagevermögens');
+INSERT INTO gifi (accno, description) VALUES ('094-097', 'Sonstige Finanzanlagen, Wertrechte');
+INSERT INTO gifi (accno, description) VALUES ('098', 'Geleistete Anzahlungen');
+INSERT INTO gifi (accno, description) VALUES ('099', 'Kumulierte Abschreibungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('1', 'Vorräte');
+INSERT INTO gifi (accno, description) VALUES ('100-109', 'Bezugsverrechnung');
+INSERT INTO gifi (accno, description) VALUES ('110-119', 'Rohstoffe');
+INSERT INTO gifi (accno, description) VALUES ('120-129', 'Bezogene Teile');
+INSERT INTO gifi (accno, description) VALUES ('130-134', 'Hilfsstoffe');
+INSERT INTO gifi (accno, description) VALUES ('135-139', 'Betriebsstoffe');
+INSERT INTO gifi (accno, description) VALUES ('140-149', 'Unfertige Erzeugnisse');
+INSERT INTO gifi (accno, description) VALUES ('150-159', 'Fertige Erzeugnisse');
+INSERT INTO gifi (accno, description) VALUES ('160-169', 'Waren');
+INSERT INTO gifi (accno, description) VALUES ('170-179', 'Noch nicht abrechenbare Leistungen');
+INSERT INTO gifi (accno, description) VALUES ('180', 'Geleistete Anzahlungen');
+INSERT INTO gifi (accno, description) VALUES ('190-199', 'Wertberichtigungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('2', 'Sonstiges Umlaufvermögen, Rechnungsabgrenzungsposten');
+INSERT INTO gifi (accno, description) VALUES ('20-21', 'Forderungen aus Lieferungen und Leistungen');
+INSERT INTO gifi (accno, description) VALUES ('200-207', 'Forderungen aus Lieferungen und Leistungen Inland');
+INSERT INTO gifi (accno, description) VALUES ('208', 'Einzelwertberichtigungen zu Forderungen aus Lieferungen und Leistungen Inland');
+INSERT INTO gifi (accno, description) VALUES ('209', 'Pauschalwertberichtigungen zu Forderungen aus Lieferungen und Leistungen Inland');
+INSERT INTO gifi (accno, description) VALUES ('210-212', 'Forderungen aus Lieferungen und Leistungen Währungsunion');
+INSERT INTO gifi (accno, description) VALUES ('213', 'Einzelwertberichtigungen zu Forderungen aus Lieferungen und Leistungen Währungsunion');
+INSERT INTO gifi (accno, description) VALUES ('214', 'Pauschalwertberichtigungen zu Forderungen aus Lieferungen und Leistungen Währungsunion');
+INSERT INTO gifi (accno, description) VALUES ('215-217', 'Forderungen aus Lieferungen und Leistungen sonstiges Ausland');
+INSERT INTO gifi (accno, description) VALUES ('218', 'Einzelwertberichtigungen zu Forderungen aus Lieferungen und Leistungen sonstiges Ausland');
+INSERT INTO gifi (accno, description) VALUES ('219', 'Pauschalwertberichtigungen zu Forderungen aus Lieferungen und Leistungen sonstiges Ausland');
+--
+INSERT INTO gifi (accno, description) VALUES ('22', 'Forderungen gegenüber verbundenen Unternehmen und Unternehmen, mit denen ein Beteiligungsverhältnis besteht');
+INSERT INTO gifi (accno, description) VALUES ('220-222', 'Forderungen gegenüber verbundenen Unternehmen');
+INSERT INTO gifi (accno, description) VALUES ('223', 'Einzelwertberichtigungen zu Forderungen gegenüber verbundenen Unternehmen');
+INSERT INTO gifi (accno, description) VALUES ('224', 'Pauschalwertberichtigungen zu Forderungen gegenüber verbundenen Unternehmen');
+INSERT INTO gifi (accno, description) VALUES ('225-227', 'Forderungen gegenüber Unternehmen, mit denen ein Beteiligungsverhältnis besteht');
+INSERT INTO gifi (accno, description) VALUES ('228', 'Einzelwertberichtigungen zu Forderungen gegenüber Unternehmen, mit denen ein Beteiligungsverhältnis besteht');
+INSERT INTO gifi (accno, description) VALUES ('229', 'Pauschalwertberichtigungen zu Forderungen gegenüber Unternehmen, mit denen ein Beteiligungsverhältnis besteht');
+--
+INSERT INTO gifi (accno, description) VALUES ('23-24', 'Sonstige Forderungen und Vermögensgegenstände');
+INSERT INTO gifi (accno, description) VALUES ('230-246', 'Sonstige Forderungen und Vermögensgegenstände');
+INSERT INTO gifi (accno, description) VALUES ('247', 'Eingeforderte, aber noch nicht eingezahlte Einlagen');
+INSERT INTO gifi (accno, description) VALUES ('248', 'Einzelwertberichtigungen zu sonstigen Forderungen und Vermögensgegenständen');
+INSERT INTO gifi (accno, description) VALUES ('249', 'Pauschalwertberichtigungen zu sonstigen Forderungen und Vermögensgegenständen');
+--
+INSERT INTO gifi (accno, description) VALUES ('25', 'Forderungen aus der Abgabenverrechnung');
+INSERT INTO gifi (accno, description) VALUES ('250-259', 'Forderungen aus der Abgabenverrechnung');
+--
+INSERT INTO gifi (accno, description) VALUES ('26', 'Wertpapiere und Anteile');
+INSERT INTO gifi (accno, description) VALUES ('260', 'Eigene Anteile');
+INSERT INTO gifi (accno, description) VALUES ('261', 'Anteile an verbundenen Unternehmen');
+INSERT INTO gifi (accno, description) VALUES ('262', 'Sonstige Anteile');
+INSERT INTO gifi (accno, description) VALUES ('263-267', 'Sonstige Wertpapiere');
+INSERT INTO gifi (accno, description) VALUES ('268', 'Besitzwechsel, soweit dem Unternehmen nicht die der Ausstellung zugrundeliegenden Forderungen zustehen');
+INSERT INTO gifi (accno, description) VALUES ('269', 'Wertberichtigungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('27-28', 'Kassenbestand, Schecks, Guthaben bei Kreditinstituten');
+INSERT INTO gifi (accno, description) VALUES ('270-272', 'Kassenbestände in Inlandswährung');
+INSERT INTO gifi (accno, description) VALUES ('273', 'Postwertzeichen');
+INSERT INTO gifi (accno, description) VALUES ('274', 'Stempelmarken');
+INSERT INTO gifi (accno, description) VALUES ('275-277', 'Kassenbestände in Fremdwährung');
+INSERT INTO gifi (accno, description) VALUES ('278', 'Schecks in Inlandswährung');
+INSERT INTO gifi (accno, description) VALUES ('280-288', 'Guthaben bei Kreditinstituten');
+INSERT INTO gifi (accno, description) VALUES ('289', 'Wertberichtigungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('29', 'Rechnungsabgrenzungsposten');
+INSERT INTO gifi (accno, description) VALUES ('290', 'Aktive Rechnungsabgrenzungsposten');
+INSERT INTO gifi (accno, description) VALUES ('295', 'Disagio');
+INSERT INTO gifi (accno, description) VALUES ('296', 'Unterschiedsbetrag zur gebotenen Pensionsrückstellung');
+INSERT INTO gifi (accno, description) VALUES ('297', 'Unterschiedsbetrag gem. Abschnitt XII Pensionskassengesetz');
+INSERT INTO gifi (accno, description) VALUES ('298', 'Steuerabgrenzung');
+--
+INSERT INTO gifi (accno, description) VALUES ('3', 'Rückstellungen, Verbindlichkeiten und Rechnungsabgrenzungsposten');
+--
+INSERT INTO gifi (accno, description) VALUES ('30', 'Rückstellungen');
+INSERT INTO gifi (accno, description) VALUES ('300', 'Rückstellungen für Abfertigungen');
+INSERT INTO gifi (accno, description) VALUES ('301', 'Rückstellungen für Pensionen');
+INSERT INTO gifi (accno, description) VALUES ('302-303', 'Steuerrückstellungen');
+INSERT INTO gifi (accno, description) VALUES ('304-309', 'Sonstige Rückstellungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('31', 'Anleihen, Verbindlichkeiten gegenüber Kreditinstituten und Finanzinstituten');
+INSERT INTO gifi (accno, description) VALUES ('310', 'Anleihen (einschließlich konvertibler)');
+INSERT INTO gifi (accno, description) VALUES ('311-317', 'Verbindlichkeiten gegenüber Kreditinstituten');
+INSERT INTO gifi (accno, description) VALUES ('318-319', 'Verbindlichkeiten gegenüber Finanzinstituten');
+--
+INSERT INTO gifi (accno, description) VALUES ('32', 'Erhaltene Anzahlungen auf Bestellungen');
+INSERT INTO gifi (accno, description) VALUES ('320', 'Erhaltene Anzahlungen auf Bestellungen');
+INSERT INTO gifi (accno, description) VALUES ('321', 'Umsatzsteuer-Evidenzkonto für erhaltene Anzahlungen auf Bestellungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('33', 'Verbindlichkeiten aus Lieferungen und Leistungen, Verbindlichkeiten aus der Annahme gezogener und der Ausstellung eigener Wechsel');
+INSERT INTO gifi (accno, description) VALUES ('330-335', 'Verbindlichkeiten aus Lieferungen und Leistungen Inland');
+INSERT INTO gifi (accno, description) VALUES ('336', 'Verbindlichkeiten aus Lieferungen und Leistungen Währungsunion');
+INSERT INTO gifi (accno, description) VALUES ('337', 'Verbindlichkeiten aus Lieferungen und Leistungen sonstiges Ausland');
+INSERT INTO gifi (accno, description) VALUES ('338-339', 'Verbindlichkeiten aus der Annahme gezogener Wechsel und der Ausstellung eigener Wechsel');
+--
+INSERT INTO gifi (accno, description) VALUES ('34', 'Verbindlichkeiten gegenüber verbundenen Unternehmen, gegenüber Unternehmen, mit denen ein Beteiligungsverhältnis besteht und gegenüber Gesellschaftern');
+INSERT INTO gifi (accno, description) VALUES ('340-347', 'Verbindlichkeiten gegenüber verbundenen Unternehmen, Verbindlichkeiten gegenüber Unternehmen, mit denen ein Beteiligungsverhältnis besteht');
+INSERT INTO gifi (accno, description) VALUES ('348', 'Verbindlichkeiten gegenüber Gesellschaftern');
+--
+INSERT INTO gifi (accno, description) VALUES ('35', 'Verbindlichkeiten aus Steuern');
+INSERT INTO gifi (accno, description) VALUES ('350-359', 'Verbindlichkeiten aus Steuern');
+--
+INSERT INTO gifi (accno, description) VALUES ('36', 'Verbindlichkeiten im Rahmen der sozialen Sicherheit');
+INSERT INTO gifi (accno, description) VALUES ('360-369', 'Verbindlichkeiten im Rahmen der sozialen Sicherheit');
+--
+INSERT INTO gifi (accno, description) VALUES ('37-38', 'Übrige sonstige Verbindlichkeiten');
+INSERT INTO gifi (accno, description) VALUES ('370-389', 'Übrige sonstige Verbindlichkeiten');
+--
+INSERT INTO gifi (accno, description) VALUES ('39', 'Rechnungsabgrenzungsposten');
+INSERT INTO gifi (accno, description) VALUES ('390-399', 'Passive Rechnungsabgrenzungsposten');
+--
+INSERT INTO gifi (accno, description) VALUES ('4', 'Betriebliche Erträge');
+--
+INSERT INTO gifi (accno, description) VALUES ('40-44', 'Brutto-Umsatzerlöse und Erlösschmälerungen');
+INSERT INTO gifi (accno, description) VALUES ('400-439', 'Brutto-Umsatzerlöse');
+INSERT INTO gifi (accno, description) VALUES ('440-449', 'Erlösschmälerungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('45', 'Bestandsveränderungen und aktivierte Eigenleistungen');
+INSERT INTO gifi (accno, description) VALUES ('450-457', 'Veränderungen des Bestandes an fertigen und unfertigen Erzeugnissen sowie an noch nicht abrechenbaren Leistungen');
+INSERT INTO gifi (accno, description) VALUES ('458-459', 'andere aktivierte Eigenleistungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('46-49', 'Sonstige betriebliche Erträge');
+INSERT INTO gifi (accno, description) VALUES ('460-462', 'Erlöse aus dem Abgang vom Anlagevermögen, ausgenommen Finanzanlagen');
+INSERT INTO gifi (accno, description) VALUES ('463-465', 'Erträge aus dem Abgang vom Anlagevermögen, ausgenommen Finanzanlagen');
+INSERT INTO gifi (accno, description) VALUES ('466-467', 'Erträge aus der Zuschreibung zum Anlagevermögen, ausgenommen Finanzanlagen');
+INSERT INTO gifi (accno, description) VALUES ('470-479', 'Erträge aus der Auflösung von Rückstellungen');
+INSERT INTO gifi (accno, description) VALUES ('480-499', 'Übrige betriebliche Erträge');
+--
+INSERT INTO gifi (accno, description) VALUES ('5', 'Materialaufwand und sonstige bezogene Herstellungsleistungen');
+INSERT INTO gifi (accno, description) VALUES ('500-509', 'Wareneinsatz');
+INSERT INTO gifi (accno, description) VALUES ('510-519', 'Verbrauch von Rohstoffen');
+INSERT INTO gifi (accno, description) VALUES ('520-529', 'Verbrauch von bezogenen Fertig- und Einzelteilen');
+INSERT INTO gifi (accno, description) VALUES ('530-539', 'Verbrauch von Hilfsstoffen');
+INSERT INTO gifi (accno, description) VALUES ('540-549', 'Verbrauch von Betriebsstoffen');
+INSERT INTO gifi (accno, description) VALUES ('550-559', 'Verbrauch von Werkzeugen und anderen Erzeugungshilfsmitteln');
+INSERT INTO gifi (accno, description) VALUES ('560-569', 'Verbrauch von Brenn- und Treibstoffen, Energie und Wasser');
+INSERT INTO gifi (accno, description) VALUES ('570-579', 'Sonstige bezogene Herstellungsleistungen');
+INSERT INTO gifi (accno, description) VALUES ('580', 'Skontoerträge auf Materialaufwand');
+INSERT INTO gifi (accno, description) VALUES ('581', 'Skontoerträge auf sonstige bezogene Herstellungsleistungen');
+INSERT INTO gifi (accno, description) VALUES ('590', 'Aufwandsstellenrechnung');
+--
+INSERT INTO gifi (accno, description) VALUES ('6', 'Personalaufwand');
+INSERT INTO gifi (accno, description) VALUES ('600-619', 'Löhne');
+INSERT INTO gifi (accno, description) VALUES ('620-639', 'Gehälter');
+INSERT INTO gifi (accno, description) VALUES ('640-644', 'Aufwendungen für Abfertigungen');
+INSERT INTO gifi (accno, description) VALUES ('645-649', 'Aufwendungen für Altersversorgung');
+INSERT INTO gifi (accno, description) VALUES ('650-655', 'Gesetzlicher Sozialaufwand Arbeiter');
+INSERT INTO gifi (accno, description) VALUES ('656-659', 'Gesetzlicher Sozialaufwand Angestellte');
+INSERT INTO gifi (accno, description) VALUES ('660-665', 'Lohnabhängige Abgaben und Pflichtbeiträge');
+INSERT INTO gifi (accno, description) VALUES ('666-669', 'Gehaltsabhängige Abgaben und Pflichtbeiträge');
+INSERT INTO gifi (accno, description) VALUES ('670-689', 'Sonstige Sozialaufwendungen');
+INSERT INTO gifi (accno, description) VALUES ('690', 'Aufwandsstellenrechnung');
+--
+INSERT INTO gifi (accno, description) VALUES ('7', 'Abschreibungen und sonstige betriebliche Aufwendunge');
+--
+INSERT INTO gifi (accno, description) VALUES ('70', 'Abschreibungen');
+INSERT INTO gifi (accno, description) VALUES ('700', 'Abschreibungen auf aktivierte Aufwendungen für das Ingangsetzen und Erweitern eines Betriebes');
+INSERT INTO gifi (accno, description) VALUES ('701-708', 'Abschreibungen auf das Anlagevermögen (ausgenommen Finanzanlagen)');
+INSERT INTO gifi (accno, description) VALUES ('709', 'Abschreibungen vom Umlaufvermögen, soweit diese die im Unternehmen üblichen Abschreibungen übersteigen');
+--
+INSERT INTO gifi (accno, description) VALUES ('71', 'Sonstige Steuern');
+INSERT INTO gifi (accno, description) VALUES ('710-719', 'Sonstige Steuern');
+--
+INSERT INTO gifi (accno, description) VALUES ('72-78', 'Übrige betriebliche Aufwendungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('72', 'Instandhaltung und Reinigung durch Dritte, Entsorgung, Beleuchtung');
+INSERT INTO gifi (accno, description) VALUES ('720-729', 'Instandhaltung und Reinigung durch Dritte, Entsorgung, Beleuchtung');
+--
+INSERT INTO gifi (accno, description) VALUES ('73', 'Transport-, Reise- und Fahrtaufwand, Nachrichtenaufwand');
+INSERT INTO gifi (accno, description) VALUES ('730-731', 'Transporte durch Dritte');
+INSERT INTO gifi (accno, description) VALUES ('732-733', 'Kfz-Aufwand');
+INSERT INTO gifi (accno, description) VALUES ('734-735', 'Reise- und Fahrtaufwand');
+INSERT INTO gifi (accno, description) VALUES ('736-737', 'Tag- und Nächtigungsgelder');
+INSERT INTO gifi (accno, description) VALUES ('738-739', 'Nachrichtenaufwand');
+--
+INSERT INTO gifi (accno, description) VALUES ('74', 'Miet-, Pacht-, Leasing- und Lizenzaufwand');
+INSERT INTO gifi (accno, description) VALUES ('740-743', 'Miet- und Pachtaufwand');
+INSERT INTO gifi (accno, description) VALUES ('744-747', 'Leasingaufwand');
+INSERT INTO gifi (accno, description) VALUES ('748-749', 'Lizenzaufwand');
+--
+INSERT INTO gifi (accno, description) VALUES ('75', 'Aufwand für beigestelltes Personal, Provisionen an Dritte, Aufsichtsratsvergütungen');
+INSERT INTO gifi (accno, description) VALUES ('750-753', 'Aufwand für beigestelltes Personal');
+INSERT INTO gifi (accno, description) VALUES ('754-757', 'Provisionen an Dritte');
+INSERT INTO gifi (accno, description) VALUES ('758-759', 'Aufsichtsratsvergütungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('76', 'Büro-, Werbe- und Repräsentationsaufwand');
+INSERT INTO gifi (accno, description) VALUES ('760', 'Büromaterial und Drucksorten');
+INSERT INTO gifi (accno, description) VALUES ('761-762', 'Druckerzeugnisse und Vervielfältigungen');
+INSERT INTO gifi (accno, description) VALUES ('763', 'Fachliteratur und Zeitungen');
+INSERT INTO gifi (accno, description) VALUES ('765-768', 'Werbung und Repräsentation');
+INSERT INTO gifi (accno, description) VALUES ('769', 'Spenden und Trinkgelder');
+--
+INSERT INTO gifi (accno, description) VALUES ('77-78', 'Versicherungen, Übrige Aufwendungen');
+INSERT INTO gifi (accno, description) VALUES ('770-774', 'Versicherungen');
+INSERT INTO gifi (accno, description) VALUES ('775-776', 'Beratungs- und Prüfungsaufwand');
+INSERT INTO gifi (accno, description) VALUES ('777', 'Aus- und Fortbildung');
+INSERT INTO gifi (accno, description) VALUES ('778', 'Mitgliedsbeiträge');
+INSERT INTO gifi (accno, description) VALUES ('779', 'Spesen des Geldverkehrs');
+INSERT INTO gifi (accno, description) VALUES ('780-781', 'Schadensfälle');
+INSERT INTO gifi (accno, description) VALUES ('782', 'Buchwert abgegangener Anlagen, ausgenommen Finanzanlagen');
+INSERT INTO gifi (accno, description) VALUES ('783', 'Verluste aus dem Abgang vom Anlagevermögen, ausgenommen Finanzanlagen');
+INSERT INTO gifi (accno, description) VALUES ('784-788', 'Verschiedene betriebliche Aufwendungen');
+INSERT INTO gifi (accno, description) VALUES ('789', 'Skontoerträge auf sonstige betriebliche Aufwendungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('79', 'Konten für das Umsatzkostenverfahren');
+INSERT INTO gifi (accno, description) VALUES ('790', 'Aufwandsstellenrechnung');
+INSERT INTO gifi (accno, description) VALUES ('791-799', 'Aufwandsstellen im Rahmen des Umsatzkostenverfahrens');
+INSERT INTO gifi (accno, description) VALUES ('791-795', 'Aufwandsstellen der Herstellung');
+INSERT INTO gifi (accno, description) VALUES ('796', 'Herstellungskosten der zur Erzielung der Umsatzerlöse erbrachten Leistungen');
+INSERT INTO gifi (accno, description) VALUES ('797', 'Vertriebskosten');
+INSERT INTO gifi (accno, description) VALUES ('798', 'Verwaltungskosten');
+INSERT INTO gifi (accno, description) VALUES ('799', 'Sonstige betriebliche Aufwendungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('8', 'Finanzerträge und Finanzaufwendungen, a.o. Erträge und a.o. Aufwendungen, Steuern vom Einkommen und vom Ertrag, Rücklagenbewegung');
+--
+INSERT INTO gifi (accno, description) VALUES ('80-83', 'Finanzerträge und Finanzaufwendungen');
+INSERT INTO gifi (accno, description) VALUES ('800-804', 'Erträge aus Beteiligungen');
+INSERT INTO gifi (accno, description) VALUES ('805-809', 'Erträge aus anderen Wertpapieren und Ausleihungen des Finanzanlagevermögens');
+INSERT INTO gifi (accno, description) VALUES ('810-813', 'Sonstige Zinsen und ähnliche Erträge');
+INSERT INTO gifi (accno, description) VALUES ('814', 'Erlöse aus dem Abgang von Beteiligungen');
+INSERT INTO gifi (accno, description) VALUES ('815', 'Erlöse aus dem Abgang von sonstigen Finanzanlagen');
+INSERT INTO gifi (accno, description) VALUES ('816', 'Erlöse aus dem Abgang von Wertpapieren des Umlaufvermögens');
+INSERT INTO gifi (accno, description) VALUES ('817', 'Buchwert abgegangener Beteiligungen');
+INSERT INTO gifi (accno, description) VALUES ('818', 'Buchwert abgegangener sonstiger Finanzanlagen');
+INSERT INTO gifi (accno, description) VALUES ('819', 'Buchwert abgegangener Wertpapiere des Umlaufvermögens');
+INSERT INTO gifi (accno, description) VALUES ('820', 'Erträge aus dem Abgang von und der Zuschreibung zu Finanzanlagen');
+INSERT INTO gifi (accno, description) VALUES ('821', 'Erträge aus dem Abgang von und der Zuschreibung zu Wertpapieren des Umlaufvermögens');
+INSERT INTO gifi (accno, description) VALUES ('822-825', 'Aufwendungen aus Beteiligungen');
+INSERT INTO gifi (accno, description) VALUES ('826-827', 'Aufwendungen aus sonstigen Finanzanlagen und aus Wertpapieren des Umlaufvermögens');
+INSERT INTO gifi (accno, description) VALUES ('828-834', 'Zinsen und ähnliche Aufwendungen');
+INSERT INTO gifi (accno, description) VALUES ('835', 'Nicht ausgenützte Lieferantenskonti');
+--
+INSERT INTO gifi (accno, description) VALUES ('84', 'Außerordentliche Erträge und außerordentliche Aufwendungen');
+INSERT INTO gifi (accno, description) VALUES ('840-844', 'Außerordentliche Erträge');
+INSERT INTO gifi (accno, description) VALUES ('845-849', 'Außerordentliche Aufwendungen');
+--
+INSERT INTO gifi (accno, description) VALUES ('85', 'Steuern vom Einkommen und vom Ertrag');
+INSERT INTO gifi (accno, description) VALUES ('850-859', 'Steuern vom Einkommen und vom Ertrag');
+--
+INSERT INTO gifi (accno, description) VALUES ('86-89', 'Rücklagenbewegung, Ergebnisüberrechnung');
+INSERT INTO gifi (accno, description) VALUES ('860-869', 'Auflösung unversteuerter Rücklagen');
+INSERT INTO gifi (accno, description) VALUES ('870-874', 'Auflösung von Kapitalrücklagen');
+INSERT INTO gifi (accno, description) VALUES ('875-879', 'Auflösung von Gewinnrücklagen');
+INSERT INTO gifi (accno, description) VALUES ('880-889', 'Zuweisung zu unversteuerten Rücklagen');
+INSERT INTO gifi (accno, description) VALUES ('890-895', 'Zuweisung zu Gewinnrücklagen');
+INSERT INTO gifi (accno, description) VALUES ('899', 'Gewinnabfuhr bzw. Verlustüberrechnung aus Ergebnisabführungsverträgen');
+--
+INSERT INTO gifi (accno, description) VALUES ('9', 'Eigenkapital, unversteuerte Rücklagen, Einlagen Stiller Gesellschafter, Abschluß- und Evidenzkonten');
+--
+INSERT INTO gifi (accno, description) VALUES ('900-918', 'Gezeichnetes bzw. gewidmetes Kapital');
+INSERT INTO gifi (accno, description) VALUES ('919', 'Nicht eingeforderte ausstehende Einlagen');
+INSERT INTO gifi (accno, description) VALUES ('920-929', 'Kapitalrücklagen');
+INSERT INTO gifi (accno, description) VALUES ('930-938', 'Gewinnrücklagen');
+INSERT INTO gifi (accno, description) VALUES ('939', 'Bilanzgewinn (-verlust)');
+INSERT INTO gifi (accno, description) VALUES ('940-959', 'Bewertungsreserven und sonstige unversteuerte Rücklagen');
+INSERT INTO gifi (accno, description) VALUES ('960-969', 'Privat- und Verrechnungskonten bei Einzelunternehmen und Personengesellschaften');
+INSERT INTO gifi (accno, description) VALUES ('970-979', 'Einlagen Stiller Gesellschafter');
+INSERT INTO gifi (accno, description) VALUES ('980', 'Eröffnungsbilanz');
+INSERT INTO gifi (accno, description) VALUES ('985', 'Schlußbilanz');
+INSERT INTO gifi (accno, description) VALUES ('989', 'Gewinn- und Verlustrechnung');
+INSERT INTO gifi (accno, description) VALUES ('990-999', 'Evidenzkonten');
diff --git a/sql-ledger/sql/Brazil_General-chart.sql b/sql-ledger/sql/Brazil_General-chart.sql
new file mode 100644 (file)
index 0000000..1c983e6
--- /dev/null
@@ -0,0 +1,70 @@
+-- General Brazilien Portuguese COA
+-- sample only
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1000','RECURSOS ATUAIS','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1060','Checando Cliente','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1065','Caixa Baixo','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1200','Contas a Receber','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1205','Provisão para devedors duvidosos','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1500','INVENTÁRIO DE CLIENTES','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1520','Inventário / Geral','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1530','Inventário / Mercado Secundário','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1540','Inventário / Computer Parts','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1800','CAPITAL ASSETS','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1820','Escritório Móvel & Equipamentos','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1825','Accum. Amort. -Móvel. & Equip.','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1840','Veículo','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1845','Accum. Amort. -Veículo','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2000','BALANÇO ATUAL','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2100','Contas a Pagar','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2170','Taxas federais','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2310','VAT (7%)','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2320','VAT (8%)','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2380','Contas a pagar de férias','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2400','DEDUÇÕES DE FOLHA DE PAGAMENTO','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2450','Imposto de Renda Devido','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2600','Passivi exigível a longo prazo','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2620','Empréstimo bancário','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2680','Empréstimo de Acionistas','A','','L','AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3300','DIVISÃO DE CAPITAL','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3350','Divisão comum','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4000','VENDAS RECEITAS','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4020','Vendas Gerais','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4030','Partes para mercado secundário','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4040','Parte Computacional','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4300','CONSULTANDO FONTES DE RENDA','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4320','Consultando','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4330','Programando','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4340','Loja','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4400','OUTRAS RENDAS','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4430','Transporte & Taxa','A','','I','IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4440','Juros Acumulados','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4450','Ganho de câmbio estrangeiro','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5000','CUSTO DE VENDAS DE PRODUTOS','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5010','Compras','A','','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5050','Mercado Secundário','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5060','Parte Computacional','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5100','Frete','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5400','DESPESAS E FOLHA DE PAGAMENTO','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5410','Salários','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5600','GERAL E DESPESAS ADMINISTRATIVAS','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5610','Contabilidade & Leis','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5615','Publicidade & Promoções','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5620','Balanço','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5660','Amortização','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5680','Imposto de Renda','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5685','Seguro','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5690','Interesses & Encargos Bancários','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5700','Materiais de Escritório','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5760','Aluguel','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5765','Manutenção & Reparos','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5780','Telefone','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5785','Cursos & Entretenimentos','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5790','Serviços Públicos','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5800','Licenciamento para exportações','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5810','Troca com Estrangeiro','A','','E','');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2310'),0.07);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2320'),0.08);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '1520'), income_accno_id = (select id from chart where accno = '4020'), expense_accno_id = (select id from chart where accno = '5010'), fxgain_accno_id = (select id from chart where accno = '4450'), fxloss_accno_id = (select id from chart where accno = '5810'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'R$:EUR:USD', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/Canada-gifi.sql b/sql-ledger/sql/Canada-gifi.sql
new file mode 100644 (file)
index 0000000..fe9641c
--- /dev/null
@@ -0,0 +1,754 @@
+-- GIFI codes as set by the Canadian Government
+-- It's a dirty job, but it seems somebody allready did it
+-- PDF Tammes, Tue , 02 Apr 2002
+-- remarks or questions to finance@bermuda-holding.com
+--
+-- From the GIFI documentation: 
+--
+-- The GIFI information has to balance. We use the following rules to verify the information you provide.
+-- total assets = total liabilities + total shareholder equity
+-- total revenue - total expenses = net non-farming income
+-- total farm revenue - total farm expenses = net farm income
+-- 
+-- You have to provide certain line items so that we can verify the above equations. Each GIFI must include:
+-- balance sheet
+-- Item 2599  Total assets
+-- Item 3499  Total liabilities
+-- Item 3620  Total shareholder equity
+-- non-farming income and expenses
+-- Item 8299  Total revenue
+-- Item 9368  Total expenses 
+-- and/or 
+-- farming income and expenses
+-- Item 9659  Total farm revenue
+-- Item 9898  Total farm expenses
+-- when reporting a breakdown of retained earnings
+-- Item 3849  Retained earnings/deficit end
+-- extraordinary items and income taxes
+-- Item 9999  Net income/loss after taxes and extraordinary items
+-- If the amount of a required item is NIL, you have to enter 0.
+--
+INSERT INTO gifi (accno,description) VALUES ('1000', 'Cash & Deposits');
+INSERT INTO gifi (accno,description) VALUES ('1001', 'Cash');
+INSERT INTO gifi (accno,description) VALUES ('1002', 'Deposits In Canadian Banks And Institutions - Canadian Currency');
+INSERT INTO gifi (accno,description) VALUES ('1003', 'Deposits In Canadian Banks And Institutions - Foreign Currency');
+INSERT INTO gifi (accno,description) VALUES ('1004', 'Deposits In Foreign Banks - Canadian Currency');
+INSERT INTO gifi (accno,description) VALUES ('1005', 'Deposits In Foreign Banks - Foreign Currency');
+INSERT INTO gifi (accno,description) VALUES ('1006', 'Credit Union Central Deposits');
+INSERT INTO gifi (accno,description) VALUES ('1007', 'Other Cash Like Instruments - Gold Bullion, Silver Bullion');
+INSERT INTO gifi (accno,description) VALUES ('1060', 'Accounts Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1061', 'Allowance For Doubtfull Accounts Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1062', 'Trade Accounts Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1063', 'Allowance For Doubtfull Trade Accounts Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1064', 'Trade Accounts Receivable Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('1065', 'Allowance For Doubtfull Trade Accounts Receivable Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('1066', 'Taxes Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1067', 'Intrest Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1068', 'Holdbacks Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1069', 'Leases Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1070', 'Allowance For Doubtfull Leases Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1071', 'Accounts Receivable Employees');
+INSERT INTO gifi (accno,description) VALUES ('1072', 'Allowance For Doubtfull Accounts Receivable Employees');
+INSERT INTO gifi (accno,description) VALUES ('1073', 'Accounts Receivable From Members Of NPO');
+INSERT INTO gifi (accno,description) VALUES ('1120', 'Inventories');
+INSERT INTO gifi (accno,description) VALUES ('1121', 'Inventory Of Goods For Sale/Finished Goods');
+INSERT INTO gifi (accno,description) VALUES ('1122', 'Inventory Of Parts And Supplies');
+INSERT INTO gifi (accno,description) VALUES ('1125', 'Work In Progress');
+INSERT INTO gifi (accno,description) VALUES ('1126', 'Raw Materials');
+INSERT INTO gifi (accno,description) VALUES ('1180', 'Short Term Investments');
+INSERT INTO gifi (accno,description) VALUES ('1181', 'Canadian Term Deposits');
+INSERT INTO gifi (accno,description) VALUES ('1182', 'Canadian Shares');
+INSERT INTO gifi (accno,description) VALUES ('1183', 'Canadian Bonds');
+INSERT INTO gifi (accno,description) VALUES ('1184', 'Canadian Treasury Bills');
+INSERT INTO gifi (accno,description) VALUES ('1185', 'Securities Purchased Under Resale Agreement');
+INSERT INTO gifi (accno,description) VALUES ('1186', 'Other Short Term Canadian Investments');
+INSERT INTO gifi (accno,description) VALUES ('1187', 'Short Term Foreign Investments');
+INSERT INTO gifi (accno,description) VALUES ('1240', 'Loans & Notes Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1241', 'Demand Loans Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1242', 'Other Loans Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1243', 'Notes Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1244', 'Mortgages Receivable');
+INSERT INTO gifi (accno,description) VALUES ('1300', 'Due From Shareholder(s)/Director(s)');
+INSERT INTO gifi (accno,description) VALUES ('1301', 'Due From Individual Shareholder(s)');
+INSERT INTO gifi (accno,description) VALUES ('1302', 'Due From Corporate Shareholder(s)');
+INSERT INTO gifi (accno,description) VALUES ('1303', 'Due From Director(s)');
+INSERT INTO gifi (accno,description) VALUES ('1360', 'Investment In Joint Venture(s)/Partnership(s)');
+INSERT INTO gifi (accno,description) VALUES ('1380', 'Due From Joint Venture(s)/Partnership(s)');
+INSERT INTO gifi (accno,description) VALUES ('1400', 'Due From/Investment In Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('1401', 'Demand Notes From Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('1402', 'Interest Receivable From Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('1403', 'Loans/Advances Due From Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('1480', 'Other Current Assets');
+INSERT INTO gifi (accno,description) VALUES ('1481', 'Deferred Income Taxes');
+INSERT INTO gifi (accno,description) VALUES ('1482', 'Accrued Investment Income');
+INSERT INTO gifi (accno,description) VALUES ('1483', 'Taxes Recoverable/Refundable');
+INSERT INTO gifi (accno,description) VALUES ('1484', 'Prepaid Expenses');
+INSERT INTO gifi (accno,description) VALUES ('1485', 'Drilling Advances');
+INSERT INTO gifi (accno,description) VALUES ('1486', 'Security Deposits');
+INSERT INTO gifi (accno,description) VALUES ('1599', 'Total Current Assets');
+INSERT INTO gifi (accno,description) VALUES ('1600', 'Land');
+INSERT INTO gifi (accno,description) VALUES ('1601', 'Land Improvement');
+INSERT INTO gifi (accno,description) VALUES ('1602', 'Accumulated Amortization Of Land & Land Improvement');
+INSERT INTO gifi (accno,description) VALUES ('1620', 'Depletable Assets');
+INSERT INTO gifi (accno,description) VALUES ('1621', 'Accumulated Amortization Of Depletable Assets');
+INSERT INTO gifi (accno,description) VALUES ('1622', 'Petroleum & Natural Gas Properties');
+INSERT INTO gifi (accno,description) VALUES ('1623', 'Accumulated Amortization Of Petroleum & Natural Gas Properties');
+INSERT INTO gifi (accno,description) VALUES ('1624', 'Mining Properties');
+INSERT INTO gifi (accno,description) VALUES ('1625', 'Accumulated Amortization Of Mining Properties');
+INSERT INTO gifi (accno,description) VALUES ('1626', 'Deferred Exporation & Development charges');
+INSERT INTO gifi (accno,description) VALUES ('1627', 'Accumulated Amortization Of Petroleum & Deferred Exporation & Development charges');
+INSERT INTO gifi (accno,description) VALUES ('1628', 'Quarries');
+INSERT INTO gifi (accno,description) VALUES ('1629', 'Accumulated Amortization Of Quarries');
+INSERT INTO gifi (accno,description) VALUES ('1630', 'Gravel Pits');
+INSERT INTO gifi (accno,description) VALUES ('1631', 'Accumulated Amortization Of Gravel Pits');
+INSERT INTO gifi (accno,description) VALUES ('1632', 'Timber Limits');
+INSERT INTO gifi (accno,description) VALUES ('1633', 'Accumulated Amortization Of Timber Limits');
+INSERT INTO gifi (accno,description) VALUES ('1680', 'Buildings');
+INSERT INTO gifi (accno,description) VALUES ('1681', 'Accumulated Amortization Of Buildings');
+INSERT INTO gifi (accno,description) VALUES ('1682', 'Manufacturing And Processing Plant');
+INSERT INTO gifi (accno,description) VALUES ('1683', 'Accumulated Amortization Of Manufacturing and Processing Plant');
+INSERT INTO gifi (accno,description) VALUES ('1684', 'Buildings Under Construction');
+INSERT INTO gifi (accno,description) VALUES ('1740', 'Machinery, Equipment, furniture & fixtures');
+INSERT INTO gifi (accno,description) VALUES ('1741', 'Accumulated Amortization Of Machinery, Equipment, furniture & fixtures');
+INSERT INTO gifi (accno,description) VALUES ('1742', 'Motor Vehicles');
+INSERT INTO gifi (accno,description) VALUES ('1743', 'Accumulated Amortization Of Motor Vehicles');
+INSERT INTO gifi (accno,description) VALUES ('1744', 'Tools and Dies');
+INSERT INTO gifi (accno,description) VALUES ('1745', 'Accumulated Amortization Of Tools and Dies');
+INSERT INTO gifi (accno,description) VALUES ('1746', 'Construction & Excavating Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1747', 'Accumulated Amortization Of Construction & Excavating Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1748', 'Forestry & Logging Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1749', 'Accumulated Amortization Of Forestry & Logging Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1750', 'Fishing Gear & Nets');
+INSERT INTO gifi (accno,description) VALUES ('1751', 'Accumulated Amortization Of Fishing Gear & Nets');
+INSERT INTO gifi (accno,description) VALUES ('1752', 'Mining Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1753', 'Accumulated Amortization Of Mining Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1754', 'Oil & Gas Systems');
+INSERT INTO gifi (accno,description) VALUES ('1755', 'Accumulated Amortization Of Oil & Gas Systems');
+INSERT INTO gifi (accno,description) VALUES ('1756', 'Production Equipment for resource industries');
+INSERT INTO gifi (accno,description) VALUES ('1757', 'Accumulated Amortization Of Production Equipment for resource industries');
+INSERT INTO gifi (accno,description) VALUES ('1758', 'Production Equipment for other industries');
+INSERT INTO gifi (accno,description) VALUES ('1759', 'Accumulated Amortization Of Production Equipment for other industries');
+INSERT INTO gifi (accno,description) VALUES ('1760', 'Exploration Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1761', 'Accumulated Amortization Of Exploration Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1762', 'Shipping Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1763', 'Accumulated Amortization Of Shipping Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1764', 'Ships & Boats');
+INSERT INTO gifi (accno,description) VALUES ('1765', 'Accumulated Amortization Of Ships & Boats');
+INSERT INTO gifi (accno,description) VALUES ('1766', 'Aircraft');
+INSERT INTO gifi (accno,description) VALUES ('1767', 'Accumulated Amortization Of Aircraft');
+INSERT INTO gifi (accno,description) VALUES ('1768', 'Signs');
+INSERT INTO gifi (accno,description) VALUES ('1769', 'Accumulated Amortization Of Signs');
+INSERT INTO gifi (accno,description) VALUES ('1770', 'Small Tools');
+INSERT INTO gifi (accno,description) VALUES ('1771', 'Accumulated Amortization Of Small Tools');
+INSERT INTO gifi (accno,description) VALUES ('1772', 'Radio & Communication Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1773', 'Accumulated Amortization Of Radio & Communication Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1774', 'Computer Equipment/Software');
+INSERT INTO gifi (accno,description) VALUES ('1775', 'Accumulated Amortization Of Computer Equipment/software');
+INSERT INTO gifi (accno,description) VALUES ('1776', 'Musical Instruments');
+INSERT INTO gifi (accno,description) VALUES ('1777', 'Accumulated Amortization Of Musical Instruments');
+INSERT INTO gifi (accno,description) VALUES ('1778', 'Satellites');
+INSERT INTO gifi (accno,description) VALUES ('1779', 'Accumulated Amortization Of Satellites');
+INSERT INTO gifi (accno,description) VALUES ('1780', 'Earth Stations');
+INSERT INTO gifi (accno,description) VALUES ('1781', 'Accumulated Amortization Of Earth Stations');
+INSERT INTO gifi (accno,description) VALUES ('1782', 'Machinery & Equipment Under Construction');
+INSERT INTO gifi (accno,description) VALUES ('1783', 'Transportation Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1784', 'Accumulated Amortization Of Transportation Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1785', 'Other Machinery & Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1786', 'Accumulated Amortization Of Other Machinery & Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1787', 'Furniture & Fixtures');
+INSERT INTO gifi (accno,description) VALUES ('1788', 'Accumulated Amortization Of Furniture & Fixtures');
+INSERT INTO gifi (accno,description) VALUES ('1900', 'Other Tangible Capital Assets');
+INSERT INTO gifi (accno,description) VALUES ('1901', 'Accumulated Amortization Of Other Tangible Capital Assets');
+INSERT INTO gifi (accno,description) VALUES ('1902', 'Logging Roads');
+INSERT INTO gifi (accno,description) VALUES ('1903', 'Accumulated Amortization Of Logging Roads');
+INSERT INTO gifi (accno,description) VALUES ('1904', 'Asphalt & Parking Areas');
+INSERT INTO gifi (accno,description) VALUES ('1905', 'Accumulated Amortization Of Asphalt & Parking Areas');
+INSERT INTO gifi (accno,description) VALUES ('1906', 'Wharves, Docks & Marinas');
+INSERT INTO gifi (accno,description) VALUES ('1907', 'Accumulated Amortization Of Wharves, Docks & Marinas');
+INSERT INTO gifi (accno,description) VALUES ('1908', 'Fences');
+INSERT INTO gifi (accno,description) VALUES ('1909', 'Accumulated Amortization Of Fences');
+INSERT INTO gifi (accno,description) VALUES ('1910', 'Capital Leases - Buildings');
+INSERT INTO gifi (accno,description) VALUES ('1911', 'Accumulated Amortization Of Capital Leases - Buildings');
+INSERT INTO gifi (accno,description) VALUES ('1912', 'Capital Leases - Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1913', 'Accumulated Amortization Of Capital Leases - Equipment');
+INSERT INTO gifi (accno,description) VALUES ('1914', 'Capital Leases - Vehicles');
+INSERT INTO gifi (accno,description) VALUES ('1915', 'Accumulated Amortization Of Capital Leases - Vehicles');
+INSERT INTO gifi (accno,description) VALUES ('1916', 'Capital Leases - Other');
+INSERT INTO gifi (accno,description) VALUES ('1917', 'Accumulated Amortization Of Capital Leases - Other');
+INSERT INTO gifi (accno,description) VALUES ('1918', 'Leasehold Improvements');
+INSERT INTO gifi (accno,description) VALUES ('1919', 'Accumulated Amortization Of Leasehold Improvements');
+INSERT INTO gifi (accno,description) VALUES ('1920', 'Other Capital Assets Under Construction');
+INSERT INTO gifi (accno,description) VALUES ('1921', 'Campsites');
+INSERT INTO gifi (accno,description) VALUES ('1922', 'Accumulated Amortization Of Campsites');
+INSERT INTO gifi (accno,description) VALUES ('2008', 'Total Tangible Capital Assets');
+INSERT INTO gifi (accno,description) VALUES ('2009', 'Total Accumulated Amortization Of Tangible Capital Assets');
+INSERT INTO gifi (accno,description) VALUES ('2010', 'Intangible Assets');
+INSERT INTO gifi (accno,description) VALUES ('2011', 'Accumulated Amortization Of Intangible Assets');
+INSERT INTO gifi (accno,description) VALUES ('2012', 'Goodwill');
+INSERT INTO gifi (accno,description) VALUES ('2013', 'Accumulated Amortization Of Goodwill');
+INSERT INTO gifi (accno,description) VALUES ('2014', 'Quota');
+INSERT INTO gifi (accno,description) VALUES ('2015', 'Accumulated Amortization Of Quota');
+INSERT INTO gifi (accno,description) VALUES ('2016', 'Licences');
+INSERT INTO gifi (accno,description) VALUES ('2017', 'Accumulated Amortization Of Licences');
+INSERT INTO gifi (accno,description) VALUES ('2018', 'Incorporation Costs');
+INSERT INTO gifi (accno,description) VALUES ('2019', 'Accumulated Amortization Of Incorporation Costs');
+INSERT INTO gifi (accno,description) VALUES ('2020', 'Trademarks & Patents');
+INSERT INTO gifi (accno,description) VALUES ('2021', 'Accumulated Amortization Of Trademarks & Patents');
+INSERT INTO gifi (accno,description) VALUES ('2022', 'Customer Lists');
+INSERT INTO gifi (accno,description) VALUES ('2023', 'Accumulated Amortization Of Customer Lists');
+INSERT INTO gifi (accno,description) VALUES ('2024', 'Rights');
+INSERT INTO gifi (accno,description) VALUES ('2025', 'Accumulated Amortization Of Rights');
+INSERT INTO gifi (accno,description) VALUES ('2026', 'Research & Development');
+INSERT INTO gifi (accno,description) VALUES ('2027', 'Accumulated Amortization Of Research & Development');
+INSERT INTO gifi (accno,description) VALUES ('2070', 'Resource Rights');
+INSERT INTO gifi (accno,description) VALUES ('2071', 'Accumulated Amortization Of Resource Rights');
+INSERT INTO gifi (accno,description) VALUES ('2072', 'Timber Rights');
+INSERT INTO gifi (accno,description) VALUES ('2073', 'Accumulated Amortization Of Timber Rights');
+INSERT INTO gifi (accno,description) VALUES ('2074', 'Mining Rights');
+INSERT INTO gifi (accno,description) VALUES ('2075', 'Accumulated Amortization Of Mining Rights');
+INSERT INTO gifi (accno,description) VALUES ('2076', 'Oil & Gas Rights');
+INSERT INTO gifi (accno,description) VALUES ('2077', 'Accumulated Amortization Of Oil & Gas Rights');
+INSERT INTO gifi (accno,description) VALUES ('2078', 'Total Intangible Capital Assets');
+INSERT INTO gifi (accno,description) VALUES ('2079', 'Total Accumulated Amortization Of Intangible Capital Assets');
+INSERT INTO gifi (accno,description) VALUES ('2180', 'Long Term Due From Shareholder(s)/Director(s)');
+INSERT INTO gifi (accno,description) VALUES ('2181', 'Long Term Due From Individual Shareholder(s)');
+INSERT INTO gifi (accno,description) VALUES ('2182', 'Long Term Due From Corporate Shareholder(s)');
+INSERT INTO gifi (accno,description) VALUES ('2183', 'Long Term Due From Director(s)');
+INSERT INTO gifi (accno,description) VALUES ('2200', 'Long Term Investment In Joint Venture(s)/Partnership(s)');
+INSERT INTO gifi (accno,description) VALUES ('2220', 'Long Term Due From Joint Venture(s)/Partnership(s)');
+INSERT INTO gifi (accno,description) VALUES ('2240', 'Long Term Due From/Investment In Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('2241', 'Due From/Investment In Canadian Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('2242', 'Shares In Canadian Related Corporations');
+INSERT INTO gifi (accno,description) VALUES ('2243', 'Loans/Advances To Canadian Related Corporations');
+INSERT INTO gifi (accno,description) VALUES ('2244', 'Investment In Canadian Related Corporations At Cost');
+INSERT INTO gifi (accno,description) VALUES ('2245', 'Investment In Canadian Related Corporations At Equity');
+INSERT INTO gifi (accno,description) VALUES ('2246', 'Due From/Investment In Foreign Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('2247', 'Shares In Foreign Related Corporations');
+INSERT INTO gifi (accno,description) VALUES ('2248', 'Loans/Advances To Foreign Related Corporations');
+INSERT INTO gifi (accno,description) VALUES ('2249', 'Investment In Foreign Related Corporations At Cost');
+INSERT INTO gifi (accno,description) VALUES ('2250', 'Investment In Foreign Related Corporations At Equity');
+INSERT INTO gifi (accno,description) VALUES ('2280', 'Investment In Co-Tenancy');
+INSERT INTO gifi (accno,description) VALUES ('2300', 'Long Term Investments');
+INSERT INTO gifi (accno,description) VALUES ('2301', 'Foreign Shares');
+INSERT INTO gifi (accno,description) VALUES ('2302', 'Other Type Of Foreign Investments');
+INSERT INTO gifi (accno,description) VALUES ('2303', 'Canadian Shares');
+INSERT INTO gifi (accno,description) VALUES ('2304', 'Government Of Canada Debt');
+INSERT INTO gifi (accno,description) VALUES ('2305', 'Canadian Provinvial & Municipal Government Debt');
+INSERT INTO gifi (accno,description) VALUES ('2306', 'Canadian Corporate Bonds & Debentures');
+INSERT INTO gifi (accno,description) VALUES ('2307', 'Debt Securities');
+INSERT INTO gifi (accno,description) VALUES ('2308', 'Equity Securities');
+INSERT INTO gifi (accno,description) VALUES ('2309', 'Securities Purchased Under Resale Agreements');
+INSERT INTO gifi (accno,description) VALUES ('2310', 'Central Credit Union Shares');
+INSERT INTO gifi (accno,description) VALUES ('2311', 'Other Long Term Canadian Investments');
+INSERT INTO gifi (accno,description) VALUES ('2360', 'Long Term Loans');
+INSERT INTO gifi (accno,description) VALUES ('2361', 'Mortgages');
+INSERT INTO gifi (accno,description) VALUES ('2362', 'Personal & Credit Card Loans');
+INSERT INTO gifi (accno,description) VALUES ('2363', 'Business & Government Loans');
+INSERT INTO gifi (accno,description) VALUES ('2364', 'Line Of Credit');
+INSERT INTO gifi (accno,description) VALUES ('2420', 'Other Long Term Assets');
+INSERT INTO gifi (accno,description) VALUES ('2421', 'Deferred Income Taxes / Tax Reserves');
+INSERT INTO gifi (accno,description) VALUES ('2422', 'Deferred Pension Charges');
+INSERT INTO gifi (accno,description) VALUES ('2423', 'Deferred Unrealized Exchange Losses');
+INSERT INTO gifi (accno,description) VALUES ('2424', 'Other Deferred Items/Charges');
+INSERT INTO gifi (accno,description) VALUES ('2425', 'Accumulated Amortization Of Deferred Charges');
+INSERT INTO gifi (accno,description) VALUES ('2426', 'Reserve Fund');
+INSERT INTO gifi (accno,description) VALUES ('2427', 'Cash Surrender Value Of Life Insurance');
+INSERT INTO gifi (accno,description) VALUES ('2589', 'Total Long Term Assets');
+INSERT INTO gifi (accno,description) VALUES ('2590', 'Assets Held In Trust');
+INSERT INTO gifi (accno,description) VALUES ('2599', 'Total Assets');
+INSERT INTO gifi (accno,description) VALUES ('2600', 'Bank Overdraft');
+INSERT INTO gifi (accno,description) VALUES ('2620', 'Amounts Payable & Accrued Liabilities');
+INSERT INTO gifi (accno,description) VALUES ('2621', 'Accounts Payable Trade');
+INSERT INTO gifi (accno,description) VALUES ('2622', 'Accounts Payable To Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('2623', 'Holdbacks Payable');
+INSERT INTO gifi (accno,description) VALUES ('2624', 'Wages Payable');
+INSERT INTO gifi (accno,description) VALUES ('2625', 'Management Fees Payable');
+INSERT INTO gifi (accno,description) VALUES ('2626', 'Bonuses Payable');
+INSERT INTO gifi (accno,description) VALUES ('2627', 'Employee Deductions Payable');
+INSERT INTO gifi (accno,description) VALUES ('2628', 'Withholding Taxes Payable');
+INSERT INTO gifi (accno,description) VALUES ('2629', 'Intrest Payable');
+INSERT INTO gifi (accno,description) VALUES ('2680', 'Taxes Payable');
+INSERT INTO gifi (accno,description) VALUES ('2681', 'Capital Taxes Payable');
+INSERT INTO gifi (accno,description) VALUES ('2682', 'Foreign Taxes Payable');
+INSERT INTO gifi (accno,description) VALUES ('2683', 'Federal Taxes Payable');
+INSERT INTO gifi (accno,description) VALUES ('2684', 'Provincial Taxes Payable');
+INSERT INTO gifi (accno,description) VALUES ('2685', 'GST Payable');
+INSERT INTO gifi (accno,description) VALUES ('2686', 'PST Payable');
+INSERT INTO gifi (accno,description) VALUES ('2700', 'Short Term Debt');
+INSERT INTO gifi (accno,description) VALUES ('2701', 'Loans From Canadian Banks');
+INSERT INTO gifi (accno,description) VALUES ('2702', 'Liability For Securities Sold Short');
+INSERT INTO gifi (accno,description) VALUES ('2703', 'Liability For Securities Sold Under Repurchase Agreements');
+INSERT INTO gifi (accno,description) VALUES ('2704', 'Gold & Silver Certificates');
+INSERT INTO gifi (accno,description) VALUES ('2705', 'Cheques & Other Items In Transit');
+INSERT INTO gifi (accno,description) VALUES ('2706', 'Lien Notes');
+INSERT INTO gifi (accno,description) VALUES ('2770', 'Deferred Income');
+INSERT INTO gifi (accno,description) VALUES ('2780', 'Due To Shareholder(s)/Director(s)');
+INSERT INTO gifi (accno,description) VALUES ('2781', 'Due To Individual Shareholder(s)');
+INSERT INTO gifi (accno,description) VALUES ('2782', 'Due To Corporate Shareholder(s)');
+INSERT INTO gifi (accno,description) VALUES ('2783', 'Due To Director(s)');
+INSERT INTO gifi (accno,description) VALUES ('2840', 'Due To Joint Venture(s)/Partnership(s)');
+INSERT INTO gifi (accno,description) VALUES ('2860', 'Due To Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('2861', 'Demand Notes Due To Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('2862', 'Interest Payable To Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('2863', 'Advances Due To Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('2920', 'Current Portion Of Long Term Liability');
+INSERT INTO gifi (accno,description) VALUES ('2960', 'Other Current Liabilities');
+INSERT INTO gifi (accno,description) VALUES ('2961', 'Deposits Received');
+INSERT INTO gifi (accno,description) VALUES ('2962', 'Dividends Payable');
+INSERT INTO gifi (accno,description) VALUES ('2963', 'Deferred Income Taxes');
+INSERT INTO gifi (accno,description) VALUES ('2964', 'Reserves For Guarantees, Warranties Or Indemnities');
+INSERT INTO gifi (accno,description) VALUES ('2965', 'General Reserves / Provisions');
+INSERT INTO gifi (accno,description) VALUES ('2966', 'Crew Shares');
+INSERT INTO gifi (accno,description) VALUES ('3139', 'Total Current Liabilities');
+INSERT INTO gifi (accno,description) VALUES ('3140', 'Long Term Debt');
+INSERT INTO gifi (accno,description) VALUES ('3141', 'Mortgages');
+INSERT INTO gifi (accno,description) VALUES ('3142', 'Farm Credit Corporation Loan');
+INSERT INTO gifi (accno,description) VALUES ('3143', 'Chartered Bank Loan');
+INSERT INTO gifi (accno,description) VALUES ('3144', 'Credit Union/Caisse Populaire Loan');
+INSERT INTO gifi (accno,description) VALUES ('3145', 'Provincial Government Loan');
+INSERT INTO gifi (accno,description) VALUES ('3146', 'Supply Company Loan');
+INSERT INTO gifi (accno,description) VALUES ('3147', 'Private Loan');
+INSERT INTO gifi (accno,description) VALUES ('3148', 'Central, Leagues And Federation Loans');
+INSERT INTO gifi (accno,description) VALUES ('3149', 'Line Of Credit');
+INSERT INTO gifi (accno,description) VALUES ('3150', 'Liability For Securities Sold Short');
+INSERT INTO gifi (accno,description) VALUES ('3151', 'Liability For Securities Sold Under Repurchase Agreements');
+INSERT INTO gifi (accno,description) VALUES ('3152', 'Lien Notes');
+INSERT INTO gifi (accno,description) VALUES ('3210', 'Bonds And Debentures');
+INSERT INTO gifi (accno,description) VALUES ('3220', 'Deferred Income');
+INSERT INTO gifi (accno,description) VALUES ('3240', 'Deferred Income Taxes');
+INSERT INTO gifi (accno,description) VALUES ('3260', 'Long Term Due To Shareholder(s)/Director(s)');
+INSERT INTO gifi (accno,description) VALUES ('3261', 'Long Term Due To Individual Shareholder(s)');
+INSERT INTO gifi (accno,description) VALUES ('3262', 'Long Term Due To Corporate Shareholder(s)');
+INSERT INTO gifi (accno,description) VALUES ('3263', 'Long Term Due To Director(s)');
+INSERT INTO gifi (accno,description) VALUES ('3280', 'Long Term Due To Joint Venture(s)/Partnership(s)');
+INSERT INTO gifi (accno,description) VALUES ('3300', 'Long Term Due To Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('3301', 'Amounts Owing To Related Canadian Parties');
+INSERT INTO gifi (accno,description) VALUES ('3302', 'Amounts Owing To Related Foreign Parties');
+INSERT INTO gifi (accno,description) VALUES ('3320', 'Other Long Term Liabilities');
+INSERT INTO gifi (accno,description) VALUES ('3321', 'Long Term Obligations/Commitments/Leases');
+INSERT INTO gifi (accno,description) VALUES ('3322', 'Reserves For Guarantees, Warranties Or Indemnities');
+INSERT INTO gifi (accno,description) VALUES ('3323', 'Provision For Site Restoration');
+INSERT INTO gifi (accno,description) VALUES ('3324', 'Contributions To Qualifying Environmental Trust');
+INSERT INTO gifi (accno,description) VALUES ('3325', 'General Provisions / Reserves');
+INSERT INTO gifi (accno,description) VALUES ('3326', 'Preference Shares Restated');
+INSERT INTO gifi (accno,description) VALUES ('3327', 'Member Allocations');
+INSERT INTO gifi (accno,description) VALUES ('3328', 'Deferred Income From Incomplete Contracts');
+INSERT INTO gifi (accno,description) VALUES ('3450', 'Total Long Term Liabilities');
+INSERT INTO gifi (accno,description) VALUES ('3460', 'Subordinated Debt');
+INSERT INTO gifi (accno,description) VALUES ('3470', 'Amounts Held In Trust');
+INSERT INTO gifi (accno,description) VALUES ('3499', 'Total Liabilities');
+INSERT INTO gifi (accno,description) VALUES ('3500', 'Common Shares');
+INSERT INTO gifi (accno,description) VALUES ('3520', 'Preferred Shares');
+INSERT INTO gifi (accno,description) VALUES ('3540', 'Contributed & Other Surplus');
+INSERT INTO gifi (accno,description) VALUES ('3541', 'Contributed Surplus');
+INSERT INTO gifi (accno,description) VALUES ('3542', 'Appraisal Surplus');
+INSERT INTO gifi (accno,description) VALUES ('3543', 'General Reserve');
+INSERT INTO gifi (accno,description) VALUES ('3570', 'Head Office Account');
+INSERT INTO gifi (accno,description) VALUES ('3600', 'Retained Earnings/Deficit');
+INSERT INTO gifi (accno,description) VALUES ('3620', 'Total Shareholder Equity');
+INSERT INTO gifi (accno,description) VALUES ('3640', 'Total Liabilities & Shareholder Equity');
+INSERT INTO gifi (accno,description) VALUES ('3660', 'Retained Earnings/Deficit Start');
+INSERT INTO gifi (accno,description) VALUES ('3680', 'Net Income/Loss');
+INSERT INTO gifi (accno,description) VALUES ('3700', 'Dividend Declared');
+INSERT INTO gifi (accno,description) VALUES ('3701', 'Cash Dividend');
+INSERT INTO gifi (accno,description) VALUES ('3702', 'Patronage Dividend');
+INSERT INTO gifi (accno,description) VALUES ('3720', 'Prior Year Adjustments');
+INSERT INTO gifi (accno,description) VALUES ('3740', 'Other Items Affecting Retained Earnings');
+INSERT INTO gifi (accno,description) VALUES ('3741', 'Share Redemptions');
+INSERT INTO gifi (accno,description) VALUES ('3742', 'Special Reserves');
+INSERT INTO gifi (accno,description) VALUES ('3743', 'Currency Adjustments');
+INSERT INTO gifi (accno,description) VALUES ('3744', 'Unusual Revenue Items');
+INSERT INTO gifi (accno,description) VALUES ('3745', 'Interfund Transfers (NPO)');
+INSERT INTO gifi (accno,description) VALUES ('3849', 'Retained Earnings/Deficit End');
+INSERT INTO gifi (accno,description) VALUES ('8000', 'Trade Sales of Goods and Services');
+INSERT INTO gifi (accno,description) VALUES ('8020', 'Sales To Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('8030', 'Interdivisional Sales');
+INSERT INTO gifi (accno,description) VALUES ('8040', 'Sales From Resource Properties');
+INSERT INTO gifi (accno,description) VALUES ('8041', 'Petroleum & Natural Gas Sales');
+INSERT INTO gifi (accno,description) VALUES ('8042', 'Petroleum & Natural Gas Sales To Related Parties');
+INSERT INTO gifi (accno,description) VALUES ('8043', 'Gas Marketing');
+INSERT INTO gifi (accno,description) VALUES ('8044', 'Processing Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8045', 'Pipeline Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8046', 'Seismic Sales');
+INSERT INTO gifi (accno,description) VALUES ('8047', 'Mining Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8048', 'Coal Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8049', 'Oil Sands Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8050', 'Royalty Income');
+INSERT INTO gifi (accno,description) VALUES ('8051', 'Oil & Gas Partnership/Joint Venture Income/Loss');
+INSERT INTO gifi (accno,description) VALUES ('8052', 'Mining Partnership/Joint Venture Income/Loss');
+INSERT INTO gifi (accno,description) VALUES ('8053', 'Other Production Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8089', 'Total Sales Of Goods And Services');
+INSERT INTO gifi (accno,description) VALUES ('8090', 'Investment Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8091', 'Interest From Foreign Sources');
+INSERT INTO gifi (accno,description) VALUES ('8092', 'Interest From Canadian Bonds And Debentures');
+INSERT INTO gifi (accno,description) VALUES ('8093', 'Interest From Canadian Mortgage Loans');
+INSERT INTO gifi (accno,description) VALUES ('8094', 'Interest From Other Canadian Sources');
+INSERT INTO gifi (accno,description) VALUES ('8095', 'Dividend Income');
+INSERT INTO gifi (accno,description) VALUES ('8096', 'Dividend From Canadian Sources');
+INSERT INTO gifi (accno,description) VALUES ('8097', 'Interest From Foreign Sources');
+INSERT INTO gifi (accno,description) VALUES ('8120', 'Commission Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8121', 'Commission Income On Real Estate Transactions');
+INSERT INTO gifi (accno,description) VALUES ('8140', 'Rental Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8141', 'Real Estate Rental Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8150', 'Vehicle Leasing');
+INSERT INTO gifi (accno,description) VALUES ('8160', 'Fishing Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8161', 'Fish Products');
+INSERT INTO gifi (accno,description) VALUES ('8162', 'Other Marine Products');
+INSERT INTO gifi (accno,description) VALUES ('8163', 'Fishing Grants, Credits & Rebates');
+INSERT INTO gifi (accno,description) VALUES ('8164', 'Fishing Subsidies');
+INSERT INTO gifi (accno,description) VALUES ('8165', 'Compensation For Loss Of Fishing Income/Property');
+INSERT INTO gifi (accno,description) VALUES ('8166', 'Sharesman Income');
+INSERT INTO gifi (accno,description) VALUES ('8210', 'Realized Gains/Losses On Disposal Of Assets');
+INSERT INTO gifi (accno,description) VALUES ('8211', 'Realized Gains/Losses On Sale Of Investments');
+INSERT INTO gifi (accno,description) VALUES ('8212', 'Realized Gains/Losses On Sale Of Resource Properties');
+INSERT INTO gifi (accno,description) VALUES ('8220', 'NPO Amounts Received');
+INSERT INTO gifi (accno,description) VALUES ('8221', 'Membership Fees');
+INSERT INTO gifi (accno,description) VALUES ('8222', 'Assessments');
+INSERT INTO gifi (accno,description) VALUES ('8223', 'Gifts');
+INSERT INTO gifi (accno,description) VALUES ('8224', 'Gross Sales And Revenues From Organizational Activities');
+INSERT INTO gifi (accno,description) VALUES ('8230', 'Other Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8231', 'Foreign Exchange Gains/Losses');
+INSERT INTO gifi (accno,description) VALUES ('8232', 'Income/Loss Of Subsidiaries/Affiliates');
+INSERT INTO gifi (accno,description) VALUES ('8233', 'Income/Loss Of Other Divisions');
+INSERT INTO gifi (accno,description) VALUES ('8234', 'Income/Loss Of Joint Ventures');
+INSERT INTO gifi (accno,description) VALUES ('8235', 'Income/Loss Of Partnerships');
+INSERT INTO gifi (accno,description) VALUES ('8236', 'RealizaTion Of Deferred Revenues');
+INSERT INTO gifi (accno,description) VALUES ('8237', 'Royalty Income Other Than Resource');
+INSERT INTO gifi (accno,description) VALUES ('8238', 'Alberta Royalty Tax Credits');
+INSERT INTO gifi (accno,description) VALUES ('8239', 'Management & Administration Fees');
+INSERT INTO gifi (accno,description) VALUES ('8240', 'Telecommunications Revenues');
+INSERT INTO gifi (accno,description) VALUES ('8241', 'Consulting Fees');
+INSERT INTO gifi (accno,description) VALUES ('8242', 'Subsidies & Grants');
+INSERT INTO gifi (accno,description) VALUES ('8243', 'Sale Of By-Products');
+INSERT INTO gifi (accno,description) VALUES ('8244', 'Deposit Services');
+INSERT INTO gifi (accno,description) VALUES ('8245', 'Credit Services');
+INSERT INTO gifi (accno,description) VALUES ('8246', 'Card Services');
+INSERT INTO gifi (accno,description) VALUES ('8247', 'Patronage Dividends');
+INSERT INTO gifi (accno,description) VALUES ('8248', 'Insurance Recoveries');
+INSERT INTO gifi (accno,description) VALUES ('8249', 'Expense Recoveries');
+INSERT INTO gifi (accno,description) VALUES ('8250', 'Bad Debt Recoveries');
+INSERT INTO gifi (accno,description) VALUES ('8299', 'Total Revenue');
+INSERT INTO gifi (accno,description) VALUES ('8300', 'Opening Inventory');
+INSERT INTO gifi (accno,description) VALUES ('8301', 'Opening Inventory - finished goods');
+INSERT INTO gifi (accno,description) VALUES ('8302', 'Opening Inventory - raw materials');
+INSERT INTO gifi (accno,description) VALUES ('8303', 'Opening Inventory - goods in process');
+INSERT INTO gifi (accno,description) VALUES ('8304', 'Opening Inventory - work in process');
+INSERT INTO gifi (accno,description) VALUES ('8320', 'Purchases / Cost of Materials');
+INSERT INTO gifi (accno,description) VALUES ('8321', 'Purchases Product A');
+INSERT INTO gifi (accno,description) VALUES ('8322', 'Purchases Product B');
+INSERT INTO gifi (accno,description) VALUES ('8331', 'Price Differences & Discounts On Purchases');
+INSERT INTO gifi (accno,description) VALUES ('8340', 'Direct Wages');
+INSERT INTO gifi (accno,description) VALUES ('8350', 'Benefits On Direct Wages');
+INSERT INTO gifi (accno,description) VALUES ('8360', 'Trades & Sub-contracts');
+INSERT INTO gifi (accno,description) VALUES ('8370', 'Production Costs Other Than Resource');
+INSERT INTO gifi (accno,description) VALUES ('8400', 'Resource Production Costs');
+INSERT INTO gifi (accno,description) VALUES ('8401', 'Pipeline Operations');
+INSERT INTO gifi (accno,description) VALUES ('8402', 'Drilling');
+INSERT INTO gifi (accno,description) VALUES ('8403', 'Site Restoration Costs');
+INSERT INTO gifi (accno,description) VALUES ('8404', 'Gross Overriding Royalty');
+INSERT INTO gifi (accno,description) VALUES ('8405', 'Freehold Royalties');
+INSERT INTO gifi (accno,description) VALUES ('8406', 'Other Producing Properties Rental');
+INSERT INTO gifi (accno,description) VALUES ('8407', 'Prospect & Geological');
+INSERT INTO gifi (accno,description) VALUES ('8408', 'Well Operating, Fuel & Equipment');
+INSERT INTO gifi (accno,description) VALUES ('8409', 'Well Abandonment & Dry Holes');
+INSERT INTO gifi (accno,description) VALUES ('8410', 'Other Lease Rentals');
+INSERT INTO gifi (accno,description) VALUES ('8411', 'Exploration Expenses, Aerial Surveys');
+INSERT INTO gifi (accno,description) VALUES ('8412', 'Development Expenses, stripping costs');
+INSERT INTO gifi (accno,description) VALUES ('8435', 'Crown Charges');
+INSERT INTO gifi (accno,description) VALUES ('8436', 'Crown royalties');
+INSERT INTO gifi (accno,description) VALUES ('8437', 'Crown lease rentals');
+INSERT INTO gifi (accno,description) VALUES ('8438', 'Freehold mineral tax');
+INSERT INTO gifi (accno,description) VALUES ('8439', 'Mining taxes');
+INSERT INTO gifi (accno,description) VALUES ('8440', 'Oil and Sand leases');
+INSERT INTO gifi (accno,description) VALUES ('8441', 'Saskatchewan resource surcharge');
+INSERT INTO gifi (accno,description) VALUES ('8450', 'Other Direct Costs');
+INSERT INTO gifi (accno,description) VALUES ('8451', 'Equipment Hire & Operation');
+INSERT INTO gifi (accno,description) VALUES ('8452', 'Log Yard');
+INSERT INTO gifi (accno,description) VALUES ('8453', 'Forestry costs');
+INSERT INTO gifi (accno,description) VALUES ('8454', 'Logging Road costs');
+INSERT INTO gifi (accno,description) VALUES ('8455', 'Stumpage costs');
+INSERT INTO gifi (accno,description) VALUES ('8456', 'Royalty costs');
+INSERT INTO gifi (accno,description) VALUES ('8457', 'Freight In & Customs Duty');
+INSERT INTO gifi (accno,description) VALUES ('8458', 'Inventory Write Down');
+INSERT INTO gifi (accno,description) VALUES ('8459', 'Direct cost amortization of tangible assets');
+INSERT INTO gifi (accno,description) VALUES ('8460', 'Direct cost amortization of natural resource assets');
+INSERT INTO gifi (accno,description) VALUES ('8461', 'Overhead expenses allocated to cost of sales');
+INSERT INTO gifi (accno,description) VALUES ('8500', 'Closing Inventory');
+INSERT INTO gifi (accno,description) VALUES ('8501', 'Closing Inventory - Finished Goods');
+INSERT INTO gifi (accno,description) VALUES ('8502', 'Closing Inventory - Raw Materials');
+INSERT INTO gifi (accno,description) VALUES ('8503', 'Closing Inventory - Goods In Process');
+INSERT INTO gifi (accno,description) VALUES ('8504', 'Closing Inventory - Work In Process');
+INSERT INTO gifi (accno,description) VALUES ('8518', 'Cost Of Sales');
+INSERT INTO gifi (accno,description) VALUES ('8519', 'Gross Profit/Loss');
+INSERT INTO gifi (accno,description) VALUES ('8520', 'Advertising & Promotion');
+INSERT INTO gifi (accno,description) VALUES ('8521', 'Advertising');
+INSERT INTO gifi (accno,description) VALUES ('8522', 'Donations');
+INSERT INTO gifi (accno,description) VALUES ('8523', 'Meals & Entertainment');
+INSERT INTO gifi (accno,description) VALUES ('8524', 'Promotion');
+INSERT INTO gifi (accno,description) VALUES ('8570', 'Amortization Of Intangible Assets');
+INSERT INTO gifi (accno,description) VALUES ('8590', 'Bad Debt Expense');
+INSERT INTO gifi (accno,description) VALUES ('8610', 'Loan Losses');
+INSERT INTO gifi (accno,description) VALUES ('8611', 'Provision for Loan Losses');
+INSERT INTO gifi (accno,description) VALUES ('8620', 'Employee Benefits');
+INSERT INTO gifi (accno,description) VALUES ('8621', 'Group Insurance Benefits');
+INSERT INTO gifi (accno,description) VALUES ('8622', 'Employers Portion Of Employee Benefits');
+INSERT INTO gifi (accno,description) VALUES ('8623', 'Contributions To Deferred Income Plans');
+INSERT INTO gifi (accno,description) VALUES ('8650', 'Amortization Of Natural Resource Assets');
+INSERT INTO gifi (accno,description) VALUES ('8670', 'Amortization Of Tangible Assets');
+INSERT INTO gifi (accno,description) VALUES ('8690', 'Insurance');
+INSERT INTO gifi (accno,description) VALUES ('8691', 'Life Insurance On Executives');
+INSERT INTO gifi (accno,description) VALUES ('8710', 'Interest & Bank Charges');
+INSERT INTO gifi (accno,description) VALUES ('8711', 'Interest On Short Term Debt');
+INSERT INTO gifi (accno,description) VALUES ('8712', 'Interest On Bonds And Debentures');
+INSERT INTO gifi (accno,description) VALUES ('8713', 'Interest On Mortgages');
+INSERT INTO gifi (accno,description) VALUES ('8714', 'Interest On Long Term Debt');
+INSERT INTO gifi (accno,description) VALUES ('8715', 'Bank Charges');
+INSERT INTO gifi (accno,description) VALUES ('8716', 'Credit Card Charges');
+INSERT INTO gifi (accno,description) VALUES ('8717', 'Collection & Credit costs');
+INSERT INTO gifi (accno,description) VALUES ('8760', 'Business Taxes, Licences & Memberships');
+INSERT INTO gifi (accno,description) VALUES ('8761', 'Memberships');
+INSERT INTO gifi (accno,description) VALUES ('8762', 'Business Taxes');
+INSERT INTO gifi (accno,description) VALUES ('8763', 'Franchise Fees');
+INSERT INTO gifi (accno,description) VALUES ('8764', 'Government Fees');
+INSERT INTO gifi (accno,description) VALUES ('8780', 'New Brunswick Tax On Large Corporations');
+INSERT INTO gifi (accno,description) VALUES ('8790', 'Nova Scotia Tax On Large Corporations');
+INSERT INTO gifi (accno,description) VALUES ('8810', 'Office Expenses');
+INSERT INTO gifi (accno,description) VALUES ('8811', 'Office Stationary And Supplies');
+INSERT INTO gifi (accno,description) VALUES ('8812', 'Office Utilities');
+INSERT INTO gifi (accno,description) VALUES ('8813', 'Data Processing');
+INSERT INTO gifi (accno,description) VALUES ('8860', 'Professional Fees');
+INSERT INTO gifi (accno,description) VALUES ('8861', 'Legal Fees');
+INSERT INTO gifi (accno,description) VALUES ('8862', 'Accounting Fees');
+INSERT INTO gifi (accno,description) VALUES ('8863', 'Consulting Fees');
+INSERT INTO gifi (accno,description) VALUES ('8864', 'Architect Fees');
+INSERT INTO gifi (accno,description) VALUES ('8865', 'Appraisal Fees');
+INSERT INTO gifi (accno,description) VALUES ('8866', 'Laboratory Fees');
+INSERT INTO gifi (accno,description) VALUES ('8867', 'Medical Fees');
+INSERT INTO gifi (accno,description) VALUES ('8868', 'Veterinary Fees');
+INSERT INTO gifi (accno,description) VALUES ('8869', 'Brokerage Fees');
+INSERT INTO gifi (accno,description) VALUES ('8870', 'Transfer Fees');
+INSERT INTO gifi (accno,description) VALUES ('8871', 'Management & Administration Fees');
+INSERT INTO gifi (accno,description) VALUES ('8872', 'Refining & Assay');
+INSERT INTO gifi (accno,description) VALUES ('8873', 'Registrar & Transfer Agent Fees');
+INSERT INTO gifi (accno,description) VALUES ('8874', 'Restructuring Costs');
+INSERT INTO gifi (accno,description) VALUES ('8875', 'Security & Exchange Commission Fees');
+INSERT INTO gifi (accno,description) VALUES ('8876', 'Training Expense');
+INSERT INTO gifi (accno,description) VALUES ('8877', 'Studio & Recording');
+INSERT INTO gifi (accno,description) VALUES ('8910', 'Rental');
+INSERT INTO gifi (accno,description) VALUES ('8911', 'Real Estate Rental');
+INSERT INTO gifi (accno,description) VALUES ('8912', 'Occupancy Costs');
+INSERT INTO gifi (accno,description) VALUES ('8913', 'Condominium Fees');
+INSERT INTO gifi (accno,description) VALUES ('8914', 'Equipment Rental');
+INSERT INTO gifi (accno,description) VALUES ('8915', 'Motor Vehicle Rental');
+INSERT INTO gifi (accno,description) VALUES ('8916', 'Moorage (Boat)');
+INSERT INTO gifi (accno,description) VALUES ('8917', 'Storage');
+INSERT INTO gifi (accno,description) VALUES ('8918', 'Quota Rental');
+INSERT INTO gifi (accno,description) VALUES ('8960', 'Repairs & Maintenance - Aircraft');
+INSERT INTO gifi (accno,description) VALUES ('8961', 'Repairs & Maintenance - Buildings');
+INSERT INTO gifi (accno,description) VALUES ('8962', 'Repairs & Maintenance - Vehicles');
+INSERT INTO gifi (accno,description) VALUES ('8963', 'Repairs & Maintenance - Boats');
+INSERT INTO gifi (accno,description) VALUES ('8964', 'Repairs & Maintenance - Machinery & Equipment');
+INSERT INTO gifi (accno,description) VALUES ('9010', 'Other Repairs & Maintenance - Janitor & Yard');
+INSERT INTO gifi (accno,description) VALUES ('9011', 'Machine Shop Expense');
+INSERT INTO gifi (accno,description) VALUES ('9012', 'Road Costs');
+INSERT INTO gifi (accno,description) VALUES ('9013', 'Security');
+INSERT INTO gifi (accno,description) VALUES ('9014', 'Garbage Removal');
+INSERT INTO gifi (accno,description) VALUES ('9060', 'Salaries & Wages');
+INSERT INTO gifi (accno,description) VALUES ('9061', 'Commissions');
+INSERT INTO gifi (accno,description) VALUES ('9062', 'Crew Share');
+INSERT INTO gifi (accno,description) VALUES ('9063', 'Bonuses');
+INSERT INTO gifi (accno,description) VALUES ('9064', 'Director''s Fees');
+INSERT INTO gifi (accno,description) VALUES ('9065', 'Management Salaries');
+INSERT INTO gifi (accno,description) VALUES ('9066', 'Employee Salaries');
+INSERT INTO gifi (accno,description) VALUES ('9110', 'Sub-Contracts');
+INSERT INTO gifi (accno,description) VALUES ('9130', 'Supplies');
+INSERT INTO gifi (accno,description) VALUES ('9131', 'Small Tools');
+INSERT INTO gifi (accno,description) VALUES ('9132', 'Shop Expense');
+INSERT INTO gifi (accno,description) VALUES ('9133', 'Uniforms');
+INSERT INTO gifi (accno,description) VALUES ('9134', 'Laundry');
+INSERT INTO gifi (accno,description) VALUES ('9135', 'Food & Catering');
+INSERT INTO gifi (accno,description) VALUES ('9136', 'Fishing Gear');
+INSERT INTO gifi (accno,description) VALUES ('9137', 'Nets & Traps');
+INSERT INTO gifi (accno,description) VALUES ('9138', 'Salt, Bait & Ice');
+INSERT INTO gifi (accno,description) VALUES ('9139', 'Camp Supplies');
+INSERT INTO gifi (accno,description) VALUES ('9150', 'Computer Related Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9151', 'Upgrade');
+INSERT INTO gifi (accno,description) VALUES ('9152', 'Internet');
+INSERT INTO gifi (accno,description) VALUES ('9180', 'Property Taxes');
+INSERT INTO gifi (accno,description) VALUES ('9200', 'Travel Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9201', 'Meetings & Conventions');
+INSERT INTO gifi (accno,description) VALUES ('9220', 'Utilities');
+INSERT INTO gifi (accno,description) VALUES ('9221', 'Electricity');
+INSERT INTO gifi (accno,description) VALUES ('9222', 'Water');
+INSERT INTO gifi (accno,description) VALUES ('9223', 'Heat');
+INSERT INTO gifi (accno,description) VALUES ('9224', 'Fuel Costs');
+INSERT INTO gifi (accno,description) VALUES ('9225', 'Telephone & Communications');
+INSERT INTO gifi (accno,description) VALUES ('9270', 'Other Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9271', 'Cash Over/Short');
+INSERT INTO gifi (accno,description) VALUES ('9272', 'Reimbursement Of Parent Company Expense');
+INSERT INTO gifi (accno,description) VALUES ('9273', 'Selling Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9274', 'Shipping & Warehouse Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9275', 'Delivery, Freight & Express');
+INSERT INTO gifi (accno,description) VALUES ('9276', 'Warranty Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9277', 'Royalty Expenses - Resident');
+INSERT INTO gifi (accno,description) VALUES ('9278', 'Royalty Expenses - Non-Resident');
+INSERT INTO gifi (accno,description) VALUES ('9279', 'Dumping Charges');
+INSERT INTO gifi (accno,description) VALUES ('9280', 'Land Fill Fees');
+INSERT INTO gifi (accno,description) VALUES ('9281', 'Vehicle Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9282', 'Research & Development');
+INSERT INTO gifi (accno,description) VALUES ('9283', 'Withholding Taxes');
+INSERT INTO gifi (accno,description) VALUES ('9284', 'General & Administrative Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9285', 'Interdivisional Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9286', 'Interfund Transfer (NPO)');
+INSERT INTO gifi (accno,description) VALUES ('9367', 'Total Operating Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9368', 'Total Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9369', 'Net Non-Farming Income');
+INSERT INTO gifi (accno,description) VALUES ('9370', 'Grains And Oilseeds');
+INSERT INTO gifi (accno,description) VALUES ('9371', 'Wheat');
+INSERT INTO gifi (accno,description) VALUES ('9372', 'Oats');
+INSERT INTO gifi (accno,description) VALUES ('9373', 'Barley');
+INSERT INTO gifi (accno,description) VALUES ('9374', 'Mixed Grains');
+INSERT INTO gifi (accno,description) VALUES ('9375', 'Corn');
+INSERT INTO gifi (accno,description) VALUES ('9376', 'Canola');
+INSERT INTO gifi (accno,description) VALUES ('9377', 'Flaxseed');
+INSERT INTO gifi (accno,description) VALUES ('9378', 'Soya Beans');
+INSERT INTO gifi (accno,description) VALUES ('9379', 'Wheat Board Payments');
+INSERT INTO gifi (accno,description) VALUES ('9420', 'Other Crop Revenues');
+INSERT INTO gifi (accno,description) VALUES ('9321', 'Fruit');
+INSERT INTO gifi (accno,description) VALUES ('9322', 'Potatoes');
+INSERT INTO gifi (accno,description) VALUES ('9323', 'Vegetables');
+INSERT INTO gifi (accno,description) VALUES ('9324', 'Tobacco');
+INSERT INTO gifi (accno,description) VALUES ('9325', 'Greenhouse & Nursery Products');
+INSERT INTO gifi (accno,description) VALUES ('9326', 'Forage Crops');
+INSERT INTO gifi (accno,description) VALUES ('9470', 'Livestock & Animal Products Revenue');
+INSERT INTO gifi (accno,description) VALUES ('9471', 'Cattle');
+INSERT INTO gifi (accno,description) VALUES ('9472', 'Swine');
+INSERT INTO gifi (accno,description) VALUES ('9473', 'Poultry');
+INSERT INTO gifi (accno,description) VALUES ('9474', 'Sheep & Lambs');
+INSERT INTO gifi (accno,description) VALUES ('9475', 'Pregnant Mare Urine (PMU)');
+INSERT INTO gifi (accno,description) VALUES ('9476', 'Milk & Cream - Excluding Dairy Subsidies');
+INSERT INTO gifi (accno,description) VALUES ('9477', 'Eggs For Consumption');
+INSERT INTO gifi (accno,description) VALUES ('9478', 'Hatching Eggs');
+INSERT INTO gifi (accno,description) VALUES ('9479', 'Aquaculture');
+INSERT INTO gifi (accno,description) VALUES ('9480', 'Horses - Breeding & Meat');
+INSERT INTO gifi (accno,description) VALUES ('9520', 'Other Commodities');
+INSERT INTO gifi (accno,description) VALUES ('9521', 'Maple Products');
+INSERT INTO gifi (accno,description) VALUES ('9522', 'Artificial Insemination (AI)');
+INSERT INTO gifi (accno,description) VALUES ('9523', 'Semen Production');
+INSERT INTO gifi (accno,description) VALUES ('9524', 'Embryo Production');
+INSERT INTO gifi (accno,description) VALUES ('9540', 'Program Payment Revenues');
+INSERT INTO gifi (accno,description) VALUES ('9541', 'Dairy Subsidies');
+INSERT INTO gifi (accno,description) VALUES ('9542', 'Crop Insurance');
+INSERT INTO gifi (accno,description) VALUES ('9543', 'NISA Payments');
+INSERT INTO gifi (accno,description) VALUES ('9544', 'Disaster Assistance Program Payments');
+INSERT INTO gifi (accno,description) VALUES ('9570', 'Rebates');
+INSERT INTO gifi (accno,description) VALUES ('9571', 'Rebates - Fuel');
+INSERT INTO gifi (accno,description) VALUES ('9572', 'Rebates - Interest');
+INSERT INTO gifi (accno,description) VALUES ('9573', 'Rebates - Property Taxes');
+INSERT INTO gifi (accno,description) VALUES ('9574', 'Resales, Rebates, GST For NISA Eligible Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9575', 'Rebates, GST For NISA Non-Eligible Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9600', 'Other Farm Revenues/Losses');
+INSERT INTO gifi (accno,description) VALUES ('9601', 'Custom Or Contract Work');
+INSERT INTO gifi (accno,description) VALUES ('9602', 'Wood Sales');
+INSERT INTO gifi (accno,description) VALUES ('9603', 'Horse Racing');
+INSERT INTO gifi (accno,description) VALUES ('9604', 'Insurance Proceeds');
+INSERT INTO gifi (accno,description) VALUES ('9605', 'Patronage Dividends');
+INSERT INTO gifi (accno,description) VALUES ('9606', 'Rental Income');
+INSERT INTO gifi (accno,description) VALUES ('9607', 'Interest Income');
+INSERT INTO gifi (accno,description) VALUES ('9608', 'Dividend Income');
+INSERT INTO gifi (accno,description) VALUES ('9609', 'Gains/Losses On Disposal Of Assets');
+INSERT INTO gifi (accno,description) VALUES ('9610', 'Gravel');
+INSERT INTO gifi (accno,description) VALUES ('9611', 'Trucking');
+INSERT INTO gifi (accno,description) VALUES ('9612', 'Resale Of Commodities Purchased');
+INSERT INTO gifi (accno,description) VALUES ('9613', 'Leases');
+INSERT INTO gifi (accno,description) VALUES ('9614', 'Machine Rentals');
+INSERT INTO gifi (accno,description) VALUES ('9615', 'Farming Partnership Income/Loss');
+INSERT INTO gifi (accno,description) VALUES ('9616', 'Farming Joint Venture Income/Loss');
+INSERT INTO gifi (accno,description) VALUES ('9650', 'Non-Farming Income');
+INSERT INTO gifi (accno,description) VALUES ('9659', 'Total Farm Revenue');
+INSERT INTO gifi (accno,description) VALUES ('9660', 'Crop Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9661', 'Containers, Twine And Baling Wire');
+INSERT INTO gifi (accno,description) VALUES ('9662', 'Fertilizers And Lime');
+INSERT INTO gifi (accno,description) VALUES ('9663', 'Pesticides');
+INSERT INTO gifi (accno,description) VALUES ('9664', 'Seeds & Plants');
+INSERT INTO gifi (accno,description) VALUES ('9665', 'Insurance Premiums (Crop) NISA ACS');
+INSERT INTO gifi (accno,description) VALUES ('9710', 'Livestock Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9711', 'Feed, Supplements, Straw & Bedding');
+INSERT INTO gifi (accno,description) VALUES ('9712', 'Livestock Purchases');
+INSERT INTO gifi (accno,description) VALUES ('9713', 'Veterinary Fees, Medicine & Breeding Fees');
+INSERT INTO gifi (accno,description) VALUES ('9760', 'Machinery Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9761', 'Machinery Insurance');
+INSERT INTO gifi (accno,description) VALUES ('9762', 'Machinery Licences');
+INSERT INTO gifi (accno,description) VALUES ('9763', 'Machinery Repairs');
+INSERT INTO gifi (accno,description) VALUES ('9764', 'Machinery Fuel');
+INSERT INTO gifi (accno,description) VALUES ('9765', 'Machinery Lease');
+INSERT INTO gifi (accno,description) VALUES ('9790', 'General Farm Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9791', 'Amortization Of Tangible Assets');
+INSERT INTO gifi (accno,description) VALUES ('9792', 'Advertising, Marketing Costs & Promotion');
+INSERT INTO gifi (accno,description) VALUES ('9793', 'Bad Debt');
+INSERT INTO gifi (accno,description) VALUES ('9794', 'Benefits Related To Employee Salaries');
+INSERT INTO gifi (accno,description) VALUES ('9795', 'Building Repairs & Maintenance');
+INSERT INTO gifi (accno,description) VALUES ('9796', 'Clearing, Levelling & Draining Land');
+INSERT INTO gifi (accno,description) VALUES ('9797', 'Crop Insurance, GRIP and Stabilization Premiums');
+INSERT INTO gifi (accno,description) VALUES ('9798', 'Custom Or Contract Work');
+INSERT INTO gifi (accno,description) VALUES ('9799', 'Electricity');
+INSERT INTO gifi (accno,description) VALUES ('9800', 'Fence Repairs & Maintenance');
+INSERT INTO gifi (accno,description) VALUES ('9801', 'Freight & Trucking');
+INSERT INTO gifi (accno,description) VALUES ('9802', 'Heating Fuel & Curing Fuel');
+INSERT INTO gifi (accno,description) VALUES ('9803', 'Insurance Program Overpayment Recapture');
+INSERT INTO gifi (accno,description) VALUES ('9804', 'Other Insurance Premiums');
+INSERT INTO gifi (accno,description) VALUES ('9805', 'Interest & Bank Charges');
+INSERT INTO gifi (accno,description) VALUES ('9806', 'Marketing Board Fees');
+INSERT INTO gifi (accno,description) VALUES ('9807', 'Membership/Subscription Fees');
+INSERT INTO gifi (accno,description) VALUES ('9808', 'Office Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9809', 'Professional Fees');
+INSERT INTO gifi (accno,description) VALUES ('9810', 'Property Taxes');
+INSERT INTO gifi (accno,description) VALUES ('9811', 'Rent - Land & Buildings');
+INSERT INTO gifi (accno,description) VALUES ('9812', 'Rent - Machinery');
+INSERT INTO gifi (accno,description) VALUES ('9813', 'Other Rental Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9814', 'Salaries & Wages');
+INSERT INTO gifi (accno,description) VALUES ('9815', 'Salaries & Wages Other Than Spouse Or Dependants');
+INSERT INTO gifi (accno,description) VALUES ('9816', 'Salaries & Wages Paid To Dependants');
+INSERT INTO gifi (accno,description) VALUES ('9817', 'Selling Costs');
+INSERT INTO gifi (accno,description) VALUES ('9818', 'Supplies');
+INSERT INTO gifi (accno,description) VALUES ('9819', 'Motor Vehicle Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9820', 'Small Tools');
+INSERT INTO gifi (accno,description) VALUES ('9821', 'Soil Testing');
+INSERT INTO gifi (accno,description) VALUES ('9822', 'Storage/Drying');
+INSERT INTO gifi (accno,description) VALUES ('9823', 'Licences/Permits');
+INSERT INTO gifi (accno,description) VALUES ('9824', 'Telephone');
+INSERT INTO gifi (accno,description) VALUES ('9825', 'Quota Rental');
+INSERT INTO gifi (accno,description) VALUES ('9826', 'Gravel');
+INSERT INTO gifi (accno,description) VALUES ('9827', 'Purchases Of Commodities Resold');
+INSERT INTO gifi (accno,description) VALUES ('9828', 'Salaries & Wages Paid To Spouse');
+INSERT INTO gifi (accno,description) VALUES ('9829', 'Motor Vehicle Interest And Leasing Costs');
+INSERT INTO gifi (accno,description) VALUES ('9830', 'Prepared Feed');
+INSERT INTO gifi (accno,description) VALUES ('9831', 'Custom Feed');
+INSERT INTO gifi (accno,description) VALUES ('9832', 'Amortization Of Intangible Assets');
+INSERT INTO gifi (accno,description) VALUES ('9833', 'Amortization Of Milk Quota');
+INSERT INTO gifi (accno,description) VALUES ('9834', 'Travel Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9835', 'Capital/Business Taxes');
+INSERT INTO gifi (accno,description) VALUES ('9850', 'Non-Farming Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9870', 'Net Inventory Adjustment');
+INSERT INTO gifi (accno,description) VALUES ('9898', 'Total Farm Expenses');
+INSERT INTO gifi (accno,description) VALUES ('9899', 'Net Farm Income');
+INSERT INTO gifi (accno,description) VALUES ('9970', 'Net Income/Loss Before Taxes And Extraordinary Items');
+INSERT INTO gifi (accno,description) VALUES ('9975', 'Extraordinary Items');
+INSERT INTO gifi (accno,description) VALUES ('9976', 'Legal Settlements');
+INSERT INTO gifi (accno,description) VALUES ('9980', 'Unrealized Gains/Losses');
+INSERT INTO gifi (accno,description) VALUES ('9985', 'Unusual Items');
+INSERT INTO gifi (accno,description) VALUES ('9990', 'Current Income Taxes');
+INSERT INTO gifi (accno,description) VALUES ('9995', 'Deferred Income Tax Provision');
+INSERT INTO gifi (accno,description) VALUES ('9999', 'Net Income/Loss After Taxes And Extraordinary Items');
+-- This item represents the net amount of:
+-- Item 9970 - Net income/loss before taxes and extraordinary items minus 
+-- Item 9975 - Extraordinary item(s) minus 
+-- Item 9976 - Legal settlements plus
+-- Item 9980 - Unrealized gains/losses minus
+-- Item 9985 - Unusual items minus
+-- Item 9990 - Current income taxes minus
+-- Item 9995 - Deferred income tax provision
+-- and must be reported.
+-- Any amount reported in this item should be equal to the amount reported at Item 3680 - Net income/loss, 
+-- in the retained earnings section. 
+--
diff --git a/sql-ledger/sql/Canada_General-chart.sql b/sql-ledger/sql/Canada_General-chart.sql
new file mode 100644 (file)
index 0000000..a0b9e7f
--- /dev/null
@@ -0,0 +1,77 @@
+-- General Canadian COA
+-- sample only
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1000','CURRENT ASSETS','H','1000','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1060','Chequing Account','A','1002','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1065','Petty Cash','A','1001','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1200','Accounts Receivables','A','1060','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1205','Allowance for doubtful accounts','A','1063','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1500','INVENTORY ASSETS','H','1120','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1520','Inventory / General','A','1122','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1530','Inventory / Aftermarket Parts','A','1122','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1540','Inventory / Computer Parts','A','1122','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1800','CAPITAL ASSETS','H','1900','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1820','Office Furniture & Equipment','A','1787','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1825','Accum. Amort. -Furn. & Equip.','A','1788','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1840','Vehicle','A','1742','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1845','Accum. Amort. -Vehicle','A','1743','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2000','CURRENT LIABILITIES','H','2620','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2100','Accounts Payable','A','2621','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2160','Federal Taxes Payable','A','2683','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2170','Provincial Taxes Payable','A','2684','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2310','GST','A','2685','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2320','PST','A','2686','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2380','Vacation Pay Payable','A','2624','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2390','WCB Payable','A','2627','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2400','PAYROLL DEDUCTIONS','H','2620','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2410','EI Payable','A','2627','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2420','CPP Payable','A','2627','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2450','Income Tax Payable','A','2628','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2600','LONG TERM LIABILITIES','H','3140','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2620','Bank Loans','A','2701','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2680','Loans from Shareholders','A','2780','L','AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3300','SHARE CAPITAL','H','3500','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3350','Common Shares','A','3500','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4000','SALES REVENUE','H','8000','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4020','General Sales','A','8000','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4030','Aftermarket Parts','A','8000','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4040','Computer Parts','A','8000','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4300','CONSULTING REVENUE','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4320','Consulting','A','8241','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4330','Programming','A','8000','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4340','Shop Labour','A','8000','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4400','OTHER REVENUE','H','8090','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4430','Shipping & Handling','A','8457','I','IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4440','Interest','A','8090','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4450','Foreign Exchange Gain','A','8231','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5000','COST OF GOODS SOLD','H','8515','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5010','Purchases','A','8320','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5050','Aftermarket Parts','A','8320','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5060','Computer Parts','A','8320','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5100','Freight','A','8457','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5400','PAYROLL EXPENSES','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5410','Wages & Salaries','A','9060','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5420','EI Expense','A','8622','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5430','CPP Expense','A','8622','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5440','WCB Expense','A','8622','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5600','GENERAL & ADMINISTRATIVE EXPENSES','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5610','Accounting & Legal','A','8862','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5615','Advertising & Promotions','A','8520','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5620','Bad Debts','A','8590','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5660','Amortization Expense','A','8670','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5680','Income Taxes','A','9990','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5685','Insurance','A','9804','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5690','Interest & Bank Charges','A','9805','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5700','Office Supplies','A','8811','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5760','Rent','A','9811','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5765','Repair & Maintenance','A','8964','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5780','Telephone','A','9225','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5785','Travel & Entertainment','A','8523','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5790','Utilities','A','8812','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5800','Licenses','A','8760','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5810','Foreign Exchange Loss','A','8231','E','');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2310'),0.07);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2320'),0.08);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '1520'), income_accno_id = (select id from chart where accno = '4020'), expense_accno_id = (select id from chart where accno = '5010'), fxgain_accno_id = (select id from chart where accno = '4450'), fxloss_accno_id = (select id from chart where accno = '5810'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'CAD:USD:EUR', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/Czech_Republic-chart.sql b/sql-ledger/sql/Czech_Republic-chart.sql
new file mode 100644 (file)
index 0000000..c43fed4
--- /dev/null
@@ -0,0 +1,317 @@
+-- Czech chart of accounts
+-- Tomas.Fencl@centrum.cz
+--    Kompletní úètová osnova platná v roce 2001
+--    Osnova má 2 místa pro tvorbu analytik
+--
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1000', 'Dlouhodobý nehmotný majetek','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1100', 'Zøizovací výdaje','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1200', 'Nehmotné výsledky výzkumu a vývoje','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1300', 'Software','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1400', 'Ocenitelná práva','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1800', 'Drobný dlouhodobý nehmotný majetek','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1900', 'Ostatní dlouhodobý nehmotný majetek','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2000', 'Dlouhodobý Hmotný majetek odpisovaný','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2100', 'Stavby','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2200', 'Samostatné movité vìci a soubory movitých vìcí','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2500', 'Pìstitelské celky trvalých porostù','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2600', 'Základní stádo a ta¾ná zvíøata','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2800', 'Drobný dlouhodobý hmotný majetek','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2900', 'Ostatní dlouhodobý hmotný majetek','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3000', 'Dlouhodobý hmotný majetek neodpisovaný','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3100', 'Pozemky','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3200', 'Umìlecká díla a sbírky','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4000', 'Poøízení dlouhodobého nehmotného a hmotného majetku','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4100', 'Poøízení dlouhodobého nehmotného majetku','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4200', 'Poøízení dlouhodobého hmotného majetku','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5000', 'Poskytnuté zálohy na dlouhodobý nehmotný a hmotný majetek','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5100', 'Poskytnuté zálohy na dlouhodobý nehmotný majetek','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5200', 'Poskytnuté zálohy na dlouhodobý hmotný majetek','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6000', 'Dlouhodobý finanèní majetek','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6100', 'Podílové cenné papíry a vklady v podnicích s rozhodujícím','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6200', 'Podílové cenné papíry a vklady v podnicích s podstatným','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6300', 'Ostatní dlouhodobé cenné papíry a vklady','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6600', 'Pùjèky podnikùm ve skupinì','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6700', 'Ostatní pùjèky','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6900', 'Ostatní dlouhodobý finanèní majetek','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7000', 'Oprávky k dlouhodobému nehmotnému majetku','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7100', 'Oprávky ke zøizovacím výdajùm','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7200', 'Oprávky k nehmotným výsledkùm výzkumu a vývoje','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7300', 'Oprávky k softwaru','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7400', 'Oprávky k ocenitelným právùm','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7800', 'Oprávky k drobnému dlouhodobému nehmotnému majetku','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7900', 'Oprávky k ostatnímu dlouhodobému nehmotnému majetku','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8000', 'Oprávky k dlouhodobému hmotnému majetku','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8100', 'Oprávky ke stavbám','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8200', 'Oprávky k samostatným movitým vìcem a souborùm movitých vìcí','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8500', 'Oprávky k pìstitelským celkùm trvalých porostù','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8600', 'Oprávky k základnímu stádu a ta¾ným zvíøatùm','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8800', 'Oprávky k drobnému dlouhodobému hmotnému majetku','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8900', 'Oprávky k ostatnímu dlouhodobému hmotnému majetku','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9000', 'Opravné polo¾ky k dlouhodobému majetku','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9100', 'Opravná polo¾ka k dlouhodobému nehmotnému majetku','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9200', 'Opravná polo¾ka k dlouhodobému hmotnému majetku','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9300', 'Opravná polo¾ka k dlouhodobému nedokonèenému nehmotnému','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9400', 'Opravná polo¾ka k dlouhodobému nedokonèenému hmotnému','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9500', 'Opravná polo¾ka k poskytnutým zálohám','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9600', 'Opravná polo¾ka k dlouhodobému finanènímu majetku','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9700', 'Opravná polo¾ka k nabytému majetku','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9800', 'Oprávky k opravné polo¾ce k nabytému majetku','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('10000', 'Zásoby','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('11000', 'Materiál','H','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('11100', 'Poøízení materiálu','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('11200', 'Materiál na skladì','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('11900', 'Materiál na cestì','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('12000', 'Zásoby vlastní výroby','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('12100', 'Nedokonèená výroba','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('12200', 'Polotovary vlastní výroby','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('12300', 'Výrobky','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('12400', 'Zvíøata','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('13000', 'Zbo¾í','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('13100', 'Poøízení zbo¾í','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('13200', 'Zbo¾í na skladì a v prodejnách','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('13900', 'Zbo¾í na cestì','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('19000', 'Opravné polo¾ky k zásobám','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('19100', 'Opravná polo¾ka k materiálu','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('19200', 'Opravná polo¾ka k nedokonèené výrobì','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('19300', 'Opravná polo¾ka k polotovarùm vlastní výroby','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('19400', 'Opravná polo¾ka k výrobkùm','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('19500', 'Opravná polo¾ka ke zvíøatùm','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('19600', 'Opravná polo¾ka ke zbo¾í','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('20000', 'Finanèní úèty','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('21000', 'Peníze','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('21100', 'Pokladna','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('21300', 'Ceniny','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('22000', 'Úèty v bankách','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('22100', 'Bankovní úèty','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('22200', 'Bankovní úèty klientù','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('23000', 'Bì¾né bankovní úvìry','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('23100', 'Krátkodobé bankovní úvìry','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('23200', 'Eskontní úvìry','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('24000', 'Jiné krátkodobé finanèní výpomoci','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('24100', 'Emitované krátkodobé dluhopisy','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('24900', 'Ostatní krátkodobé finanèní výpomoci','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('25000', 'Krátkodobý finanèní majetek','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('25100', 'Majetkové cenné papíry','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('25200', 'Vlastní akcie a vlastní obchodní podíly','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('25300', 'Dlu¾né cenné papíry','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('25500', 'Vlastní dluhopisy','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('25600', 'Ostatní cenné papíry','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('26000', 'Pøevody mezi finanèními úèty','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('26100', 'Peníze na cestì','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('29000', 'Opravné polo¾ky ke krátkodobému finanènímu majetku','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('29100', 'Opravná polo¾ka k majetkovým cenným papírùm','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('29300', 'Opravná polo¾ka k dlu¾ným cenným papírùm','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('30000', 'Zúètovací vztahy','H','','H','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('31000', 'Pohledávky','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('31100', 'Odbìratelé','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('31200', 'Smìnky k inkasu','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('31300', 'Pohledávky za eskontované cenné papíry','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('31400', 'Poskytnuté provozní zálohy','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('31500', 'Ostatní pohledávky','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('32000', 'Závazky','H','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('32100', 'Dodavatelé','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('32200', 'Smìnky k úhradì','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('32400', 'Pøijaté zálohy','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('32500', 'Ostatní závazky','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('32600', ' Závazky vùèi klientùm','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('32700', ' Závazky vùèi trhùm','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('33000', 'Zúètování se zamìstnanci a institucemi','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('33100', 'Zamìstnanci','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('33300', 'Ostatní závazky vùèi zamìstnancùm','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('33500', 'Pohledávky za zamìstnanci','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('33600', 'Zúètování s institucemi sociálního zabezpeèení a zdravotního','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('34000', 'Zúètování daní a dotací','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('34100', 'Daò z pøíjmù','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('34200', 'Ostatní pøímé danì','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('34300', 'Daò z pøidané hodnoty - zúètování','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('34311', 'DPH 5% vstup','A','','L','AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('34312', 'DPH 22% vstup','A','','L','AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('34321', 'DPH 5% výstup','A','','L','AR_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('34322', 'DPH 22% výstup','A','','L','AR_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('34500', 'Ostatní danì a poplatky','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('34600', 'Dotace ze státního rozpoètu','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('34700', 'Ostatní dotace','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('35000', 'Pohledávky ke spoleèníkùm a sdru¾ení','H','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('35100', 'Pohledávky k podnikùm ve skupinì','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('35300', 'Pohledávky za upsaný vlastní kapitál','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('35400', 'Pohledávky za spoleèníky pøi úhradì ztráty','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('35500', 'Ostatní pohledávky za spoleèníky','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('35800', 'Pohledávky k úèastníkùm sdru¾ení','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('36000', 'Závazky ke spoleèníkùm a sdru¾ení','H','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('36100', 'Závazky k podnikùm ve skupinì','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('36400', 'Závazky ke spoleèníkùm pøi rozdìlování zisku','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('36500', 'Ostatní závazky ke spoleèníkùm','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('36600', 'Závazky ke spoleèníkùm a èlenùm dru¾stva ze závislé','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('36700', 'Závazky z upsaných nesplacených cenných papírù a vkladù','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('36800', 'Závazky k úèastníkùm sdru¾ení','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('37000', 'Jiné pohledávky a závazky','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('37100', 'Odlo¾ená daòová pohledávka a závazek','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('37300', 'Nakoupené opce','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('37400', 'Prodané opce','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('37500', 'Pohledávky z emitovaných dluhopisù','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('37700', ' Zúètování obchodù','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('37800', 'Jiné pohledávky','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('37900', 'Jiné závazky','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('38000', 'Pøechodné úèty aktiv a pasív','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('38100', 'Náklady pøí¹tích období','A','','A','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('38200', 'Komplexní náklady pøí¹tích období','A','','A','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('38300', 'Výdaje pøí¹tích období','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('38400', 'Výnosy pøí¹tích období','A','','L','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('38500', 'Pøíjmy pøí¹tích období','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('38600', 'Kursové rozdíly aktivní','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('38700', 'Kursové rozdíly pasívní','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('38800', 'Dohadné úèty aktivní','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('38900', 'Dohadné úèty pasívní','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('39000', 'Opravná polo¾ka k zúètovacím vztahùm a vnitøní zúètování','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('39100', 'Opravná polo¾ka k pohledávkám','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('39500', 'Vnitøní zúètování','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('39800', 'Spojovací úèet pøi sdru¾ení','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('40000', 'Kapitálové úèty a dlouhodobé závazky','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('41000', 'Základní kapitál a kapitálové fondy','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('41100', 'Základní kapitál','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('41200', 'Emisní á¾io','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('41300', 'Ostatní kapitálové fondy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('41400', 'Oceòovací rozdíly z pøecenìní majetku a závazkù','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('42000', 'Fondy ze zisku a pøevedené hospodáøské výsledky','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('42100', 'Zákonný rezervní fond','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('42200', 'Nedìlitelný fond','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('42300', 'Statutární fondy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('42700', 'Ostatní fondy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('42800', 'Nerozdìlený zisk minulých let','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('42900', 'Neuhrazená ztráta minulých let','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('43000', 'Hospodáøský výsledek','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('43100', 'Hospodáøský výsledek ve schvalovacím øízení','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('45000', 'Rezervy','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('45100', 'Rezervy zákonné','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('45400', 'Rezerva na kursové ztráty','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('45900', 'Ostatní rezervy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('46000', 'Bankovní úvìry','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('46100', 'Bankovní úvìry','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('47000', 'Dlouhodobé závazky','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('47100', 'Dlouhodobé závazky k podnikùm ve skupinì','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('47300', 'Emitované dluhopisy','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('47400', 'Závazky z pronájmu','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('47500', 'Dlouhodobé pøijaté zálohy','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('47800', 'Dlouhodobé smìnky k úhradì','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('47900', 'Ostatní dlouhodobé závazky','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('49000', 'Individuální podnikatel','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('49100', 'Úèet individuálního podnikatele','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('50000', 'Spotøebované nákupy','A','','E','AP_amount:IC_COGS');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('50100', 'Spotøeba materiálu','A','','E','AP_amount:IC_COGS');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('50200', 'Spotøeba energie','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('50300', 'Spotøeba ostatních neskladovatelných dodávek','A','','E','AP_amount:IC_COGS');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('50400', 'Prodané zbo¾í','A','','E','AP_amount:IC_COGS');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('51000', 'Slu¾by','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('51100', 'Opravy a udr¾ování','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('51200', 'Cestovné','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('51300', 'Náklady na reprezentaci','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('51800', 'Ostatní slu¾by','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('52000', 'Osobní náklady','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('52100', 'Mzdové náklady','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('52200', 'Pøíjmy spoleèníkù a èlenù dru¾stva ze závislé èinnosti','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('52300', 'Odmìny èlenùm orgánù spoleènosti a dru¾stva','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('52400', 'Zákonné sociální poji¹tìní','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('52500', 'Ostatní sociální poji¹tìní','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('52600', 'Sociální náklady individuálního podnikatele','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('52700', 'Zákonné sociální náklady','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('52800', 'Ostatní sociální náklady','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('53000', 'Danì a poplatky','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('53100', 'Daò silnièní','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('53200', 'Daò z nemovitostí','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('53800', 'Ostatní danì a poplatky','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('54000', 'Jiné provozní náklady','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('54100', 'Zùstatková cena prodaného dlouhodobého nehmotného a hmotného','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('54200', 'Prodaný materiál','A','','E','IC_COGS');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('54300', 'Dary','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('54400', 'Smluvní pokuty a úroky z prodlení','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('54500', 'Ostatní pokuty a penále','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('54600', 'Odpis pohledávky','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('54800', 'Ostatní provozní náklady','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('55000', 'Odpisy, rezervy a opravné polo¾ky provozních nákladù','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('55100', 'Odpisy dlouhodobého nehmotného a hmotného majetku','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('55200', 'Tvorba zákonných rezerv','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('55400', 'Tvorba ostatních rezerv','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('55500', 'Zúètování komplexních nákladù pøí¹tích období','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('55700', 'Zúètování oprávky k opravné polo¾ce k nabytému majetku','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('55800', 'Tvorba zákonných opravných polo¾ek','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('55900', 'Tvorba opravných polo¾ek','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('56000', 'Finanèní náklady','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('56100', 'Prodané cenné papíry a vklady','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('56200', 'Úroky','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('56300', 'Kursové ztráty','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('56800', 'Ostatní finanèní náklady','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('57000', 'Rezervy a opravné polo¾ky finanèních nákladù','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('57400', 'Tvorba rezerv','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('57900', 'Tvorba opravných polo¾ek','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('58000', 'Mimoøádné náklady','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('58100', 'Náklady na zmìnu metody','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('58200', 'Manka a ¹kody','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('58400', 'Tvorba rezerv','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('58800', 'Ostatní mimoøádné náklady','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('58900', 'Tvorba opravných polo¾ek','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('59000', 'Danì z pøíjmù a pøevodové úèty','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('59100', 'Daò z pøíjmù z bì¾né èinnosti - splatná','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('59200', 'Daò z pøíjmù z bì¾né èinnosti - odlo¾ená','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('59300', 'Daò z pøíjmù z mimoøádné èinnosti - splatná','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('59400', 'Daò z pøíjmù z mimoøádné èinnosti - odlo¾ené','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('59500', 'Dodateèné odvody danì z pøíjmù','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('59600', 'Pøevod podílu na hospodáøském výsledku spoleèníkùm','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('59700', 'Pøevod provozních nákladù','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('59800', 'Pøevod finanèních nákladù','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('60000', 'Tr¾by za vlastní výkony a zbo¾í','A','','I','AR_amount:IC_sale:IC_Income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('60100', 'Tr¾by za vlastní výrobky','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('60200', 'Tr¾by z prodeje slu¾eb','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('60400', 'Tr¾by za zbo¾í','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('61000', 'Zmìny stavu vnitropodnikových zásob','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('61100', 'Zmìna stavu nedokonèené výroby','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('61200', 'Zmìna stavu polotovarù','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('61300', 'Zmìna stavu výrobkù','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('61400', 'Zmìna stavu zvíøat','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('62000', 'Aktivace','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('62100', 'Aktivace materiálu a zbo¾í','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('62200', 'Aktivace vnitropodnikových slu¾eb','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('62300', 'Aktivace dlouhodobého nehmotného majetku','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('62400', 'Aktivace dlouhodobého hmotného majetku','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('64000', 'Jiné provozní výnosy.','A','','I','AR_amount:IC_sale:IC_Income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('64100', 'Tr¾by z prodeje dlouhodobého nehmotného a hmotného majetku','A','','I','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('64200', 'Tr¾by z prodeje materiálu','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('64400', 'Smluvní pokuty a úroky z prodlení','A','','I','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('64600', 'Výnosy z odepsaných pohledávek','A','','I','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('64800', 'Jiné provozní výnosy','A','','I','AR_amount:IC_sale:IC_Income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('65000', 'Zúètování rezerv a opravných polo¾ek provozních výnosù','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('65200', 'Zúètování zákonných rezerv','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('65400', 'Zúètování ostatních rezerv','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('65500', 'Zúètování komplexních nákladù pøí¹tích období','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('65700', 'Zúètování oprávky k opravné polo¾ce k nabytému majetku','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('65800', 'Zúètování zákonných opravných polo¾ek','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('65900', 'Zúètování opravných polo¾ek','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('66000', 'Finanèní výnosy','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('66100', 'Tr¾by z prodeje cenných papírù a vkladù','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('66200', 'Úroky','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('66300', 'Kursové zisky','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('66500', 'Výnosy z dlouhodobého finanèního majetku','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('66600', 'Výnosy z krátkodobého finanèního majetku','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('66800', 'Ostatní finanèní výnosy','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('67000', 'Zúètování rezerv a opravných polo¾ek finanèních výnosù','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('67400', 'Zúètování rezerv','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('67900', 'Zúètování opravných polo¾ek','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('68000', 'Mimoøádné výnosy','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('68100', 'Výnosy ze zmìny metody','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('68400', 'Zúètování rezerv','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('68800', 'Ostatní mimoøádné výnosy','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('68900', 'Zúètování opravných polo¾ek','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('69000', 'Pøevodové úèty','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('69700', 'Pøevod provozních výnosù','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('69800', 'Pøevod finanèních výnosù','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('70000', 'Úèty rozva¾né','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('70100', 'Poèáteèní úèet rozva¾ný','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('70200', 'Koneèný úèet rozva¾ný','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('71000', 'Úèet ziskù a ztrát','A','','A','');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '34311'),0.05);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '34312'),0.22);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '34321'),0.05);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '34322'),0.22);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '13200'), income_accno_id = (select id from chart where accno = '60000'), expense_accno_id = (select id from chart where accno = '50000'), fxgain_accno_id = (select id from chart where accno = '99998'), fxloss_accno_id = (select id from chart where accno = '99999'), invnumber = '1000', sonumber = '5000', ponumber = '1000', curr = 'Kè', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/Danish_Default-chart.sql b/sql-ledger/sql/Danish_Default-chart.sql
new file mode 100644 (file)
index 0000000..aafcfb0
--- /dev/null
@@ -0,0 +1,75 @@
+-- Default chart of accounts
+-- sample only
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1000','KORTFRISTEDE AKTIVER','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1061','Bank','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1065','Kasse','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1200','Indbetalinger','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1205','Hensættelser til formodet gæld','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1210','Moms indgående','A','','A','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1500','LAGER-AKTIVER','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1520','Lager / udstyr','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1530','Lager / programmel','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1540','Lager / tillægssalg','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1550','Lager / arrangementer','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1800','AKTIVER','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1820','Kontorinventar og -udstyr','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1825','Samlede afskrivninger, inventar, udstyr','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1840','Køretøjer','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1845','Samlede afskrivninger, køretøjer','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2000','KORTFRISTET GÆLD','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2100','Udbetalinger','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2160','Selskabsskat','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2190','Afgifter','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2311','Moms udgående','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2600','LANGFRISTET GÆLD','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2620','Banklån','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3300','AKTIEKAPITAL','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3350','Almindelige aktier','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3500','EGENKAPITAL','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3510','Egenkapital primo','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3600','Årets resultat','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4000','SALGSINDTÆGT','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4020','Salg / udstyr','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4030','Salg / programmel','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4040','Salg / tillægssalg','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4050','Salg / arrangementer','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4300','KONSULENTINDTÆGT','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4320','Konsulentbistand','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4330','Programmering','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4400','ANDEN INDTÆGT','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4440','Renter','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4450','Foreign Exchange Gain','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5000','SALGSOMKOSTNINGER','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5020','Omkostninger / udstyr','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5010','Anskaffelser under 8.000','A','','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5011','Anskaffelser over 8.000','A','','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5030','Omkostninger / programmel','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5040','Omkostninger / tillægssalg','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5050','Omkostninger / arrangementer','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5100','Fragt, post','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5400','LØNUDGIFTER','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5410','Lønninger og honorarer','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5420','ATP','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5470','Personalegoder','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5600','GENERELLE & ADMINISTRATIVE UDGIFTER','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5610','Bogføring, revision, advokat','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5615','Marketing','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5620','Dårlige skyldnere','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5660','Afdrag på lån','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5680','A-skat','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5685','Forsikringer','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5690','Renter og bankgebyrer','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5700','Kontorudgifter','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5760','Husleje','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5765','Vedligeholdelse og reparation','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5780','Telefon','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5785','Rejser & repræsentation','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5790','El, vand, varme','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5800','Licenser','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5810','Foreign Exchange Loss','A','','E','');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '1210'),0.25);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2311'),0.25);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '1520'), income_accno_id = (select id from chart where accno = '4020'), expense_accno_id = (select id from chart where accno = '5010'), fxgain_accno_id = (select id from chart where accno = '4450'), fxloss_accno_id = (select id from chart where accno = '5810'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'DKK', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/Default-chart.sql b/sql-ledger/sql/Default-chart.sql
new file mode 100644 (file)
index 0000000..c85d41b
--- /dev/null
@@ -0,0 +1,81 @@
+-- Default chart of accounts
+-- sample only
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1000','CURRENT ASSETS','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1060','Chequing Account','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1065','Petty Cash','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1200','Accounts Receivables','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1205','Allowance for doubtful accounts','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1500','INVENTORY ASSETS','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1520','Inventory / Computer Parts','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1530','Inventory / Software','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1540','Inventory / Aftermarket Parts','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1800','CAPITAL ASSETS','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1820','Office Furniture & Equipment','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1825','Accum. Amort. -Furn. & Equip.','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1840','Vehicle','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1845','Accum. Amort. -Vehicle','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2000','CURRENT LIABILITIES','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2100','Accounts Payable','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2160','Corporate Taxes Payable','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2190','Federal Income Tax Payable','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2210','Workers Comp Payable','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2220','Vacation Pay Payable','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2250','Pension Plan Payable','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2260','Employment Insurance Payable','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2280','Payroll Taxes Payable','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2310','VAT (10%)','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2320','VAT (14%)','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2330','VAT (30%)','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2600','LONG TERM LIABILITIES','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2620','Bank Loans','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2680','Loans from Shareholders','A','','L','AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3300','SHARE CAPITAL','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3350','Common Shares','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4000','SALES REVENUE','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4020','Sales / Hardware','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4030','Sales / Software','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4040','Sales / Aftermarket Parts','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4300','CONSULTING REVENUE','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4320','Consulting','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4330','Programming','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4400','OTHER REVENUE','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4430','Shipping & Handling','A','','I','IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4440','Interest','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4450','Foreign Exchange Gain','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5000','COST OF GOODS SOLD','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5010','Purchases','A','','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5020','COGS / Hardware','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5030','COGS / Software','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5040','COGS / Aftermarket Parts','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5100','Freight','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5400','PAYROLL EXPENSES','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5410','Wages & Salaries','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5420','Employment Insurance Expense','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5430','Pension Plan Expense','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5440','Workers Comp Expense','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5470','Employee Benefits','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5600','GENERAL & ADMINISTRATIVE EXPENSES','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5610','Accounting & Legal','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5615','Advertising & Promotions','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5620','Bad Debts','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5650','Capital Cost Allowance Expense','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5660','Amortization Expense','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5680','Income Taxes','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5685','Insurance','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5690','Interest & Bank Charges','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5700','Office Supplies','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5760','Rent','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5765','Repair & Maintenance','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5780','Telephone','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5785','Travel & Entertainment','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5790','Utilities','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5795','Registrations','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5800','Licenses','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5810','Foreign Exchange Loss','A','','E','');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2310'),0.1);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2320'),0.14);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2330'),0.3);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '1520'), income_accno_id = (select id from chart where accno = '4020'), expense_accno_id = (select id from chart where accno = '5010'), fxgain_accno_id = (select id from chart where accno = '4450'), fxloss_accno_id = (select id from chart where accno = '5810'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'USD:CAD:EUR', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/Dutch_Default-chart.sql b/sql-ledger/sql/Dutch_Default-chart.sql
new file mode 100644 (file)
index 0000000..758d6d4
--- /dev/null
@@ -0,0 +1,80 @@
+--
+-- Dutch Chart of Accounts
+-- AJ Hettema, Mon, 20 Aug 2001
+--
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1000','HUIDIGE ACTIVA','H','','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1061','Bank','A','','A','AR_paid:AP_paid');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1065','Kas','A','','A','AR_paid:AP_paid');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1200','Debiteuren','A','','A','AR');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1205','Toelage voor precaire rekeningen','A','','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1500','VOORRAAD ACTIVA','H','','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1520','Voorraad / Hardware','A','','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1530','Voorraad / Software','A','','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1540','Voorraad / Aftermarket Parts','A','','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1800','LANGE TERMIJN ACTIVA','H','','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1820','Inventaris','A','','A','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1825','Afschrijving inventaris','A','','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1840','Auto','A','','A','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1845','Afschrijving auto','A','','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2000','HUIDIGE PASSIVA','H','','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2100','Crediteuren','A','','L','AP');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2160','Niet-rijks Belastingen','A','','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2170','Omzetbelasting','A','','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2190','Vennootschapsbelasting','A','','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2310','BTW hoog','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2311','BTW laag','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2600','LANGE TERMIJN PASSIVA','H','','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2620','Bank Leningen','A','','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2680','Aandelenvermogen','A','','L','AP_paid');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('3300','AANDELEN KAPITAAL','H','','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('3350','Aandelen in portefeuille','A','','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('3500','WINSTRESERVE','H','','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('3590','Winstreserve voorgaande jaren','A','','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('3600','Huidige winstreserve','A','','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4000','VERKOOP INKOMSTEN','H','','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4020','Verkoop / Hardware','A','','I','AR_amount:IC_sale');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4030','Verkoop / Software','A','','I','AR_amount:IC_sale');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4040','Verkoop / Aftermarket Parts','A','','I','AR_amount:IC_sale');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4300','CONSULTANCY INKOMSTEN','H','','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4320','Consultancy','A','','I','AR_amount:IC_income');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4330','Programmeren','A','','I','AR_amount:IC_income');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4400','ANDERE INKOMSTEN','H','','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4430','Verzend & Administratie','A','','I','IC_income');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4440','Rente','A','','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4450','Foreign Exchange Gain','A','','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5000','INKOOPPRIJS VERKOPEN','H','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5010','Inkoopkosten algemeen','A','','E','AP_amount:IC_cogs:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5020','Inkoopkosten / Hardware','A','','E','AP_amount:IC_cogs');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5030','Inkoopkosten / Software','A','','E','AP_amount:IC_cogs');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5040','Inkoopkosten / Aftermarket Parts','A','','E','AP_amount:IC_cogs');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5100','Vrachtkosten','A','','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5400','PERSONEELS KOSTEN','H','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5410','Salarissen','A','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5420','EI Expense','A','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5430','CPP Expense','A','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5440','WCB Expense','A','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5470','Employee Benefits','A','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5600','GENERAL & ADMINISTRATIVE EXPENSES','H','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5610','Boekhouding- & Rechtkosten','A','','E','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5615','Reclame- & Promotiekosten','A','','E','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5620','Slechte Schulden','A','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5660','Afschrijvingskosten','A','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5680','Inkomsten Belastingen','A','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5685','Verzekeringen','A','','E','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5690','Rente & Bankkosten','A','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5700','Kantoorvoorzieningen','A','','E','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5760','Huurkosten','A','','E','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5765','Reparatie- & Onderhoudskosten','A','','E','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5780','Telefoonkosten','A','','E','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5781','Internetkosten','A','','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5785','Reis- & Vermaakkosten','A','','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5790','NUTS Kosten','A','','E','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5795','Registratie''s','A','','E','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5800','Licenties','A','','E','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5810','Foreign Exchange Loss','A','','E','');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2310'),0.19);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2311'),0.06);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '1520'), income_accno_id = (select id from chart where accno = '4020'), expense_accno_id = (select id from chart where accno = '5010'), fxgain_accno_id = (select id from chart where accno = '4450'), fxloss_accno_id = (select id from chart where accno = '5810'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'EUR:USD', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/Dutch_Standard-chart.sql b/sql-ledger/sql/Dutch_Standard-chart.sql
new file mode 100644 (file)
index 0000000..cd7c8eb
--- /dev/null
@@ -0,0 +1,233 @@
+-- Nederlandstalig Rekeningschema conform het Decimaal Stelsel.
+-- Dutch Chart of Accounts following the Decimal Standards as set by the famous Philips Accounting Department
+-- PDF Tammes, Fri, 29 Mar 2002 ( remarks or questions to finance@bermuda-holding.com )
+-- Just delete any accounts not needed after importing the scheme, beats entering all manually (or add -- at the beginning)
+-- Account groups (first number in accountnumber defines to which group it belongs)
+-- 0 : Vaste Activa, Eigen Vermogen, Voorzieningen en lang vreemd vermogen => Fixed Assets, Capital, Accruals and long term loans
+-- 1 : Financiele Rekeningen => Financial Accounts
+-- 2 : Tussenrekeningen => Intermediate Accounts
+-- 3 : Voorraad grond- en hulpstoffen => Stocks (minerals, parts not yet assembled etc)
+-- 4 : Kostenrekeningen => Costs Accounts
+-- 5 : Verdeling Directe kosten => Accounts to recharge several Direct Costs to separate departments
+-- 6 : Fabricagekosten => Assembly Costs
+-- 7 : Voorraad gereed produkt en product in bewerking => Stocks (Trade Articles, half-finished assemblies, projects under construction)
+-- 8 : Rekeningen voor vaststelling van het verkoopresultaat => Accounts for dediding Sales Result
+-- 9 : Rekeningen voor vaststelling van de resultatenrekening => Accounts for dediding Profit & Loss (P/L)
+-- The general idea is to allocate all costs to the 4/5/6 accounts, all stock transactions to 7 and sales related to 8. At the end of the
+-- year you clean out the seperate accounts via x999 and kick the result to the relevant 9xxx series. That way you have a specialized
+-- P/L in the seperate accounts and an overview/shirt version of the P/L in the 9 series, where also various results not related to normal
+-- operations is recorded (tax, donations, that kind of thing. Finally the 9999 account is used to kick the result to retained earnings and
+-- related accounts in the balance sheet, and we are ready for the next year
+--
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0000','Vaste Activa & Eigen Vermogen','H','0000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0010','Terreinen','A','0010','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0015','Afschrijving Terreinen','A','0015','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0200','Gebouwen','A','0200','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0205','Afschrijving Gebouwen','A','0205','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0230','Inventaris','A','0230','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0235','Afschrijving Inventaris','A','0235','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0240','Computers','A','0240','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0245','Afschrijving Computers','A','0245','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0250','Auto','A','0250','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0255','Afschrijving Auto','A','0255','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0260','Machines','A','0260','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0265','Afschrijving Machines','A','0265','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0290','Goodwill','A','0290','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0295','Afschrijving Goodwill','A','0295','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0370','Overige Leningen u/g','A','0370','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0380','Aandelen & Effecten','A','0380','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0381','Beleggingen Spaarbeleg','A','0381','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0390','Beleggingen Legiolease','A','0390','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0400','Aandelenkapitaal','A','0400','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0410','Aandelen in portefeuille','A','0410','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0420','Aandelen uit te reiken','A','0420','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0430','Agioreserve','A','0430','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0440','Winstreserve','A','0440','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0450','Herwaarderingsreserve','A','0450','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0470','Oprichtingskosten','A','0470','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0480','Winst na belasting lopend jaar','A','0480','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0500','Eigen Vermogen','A','0500','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0510','Prive','A','0510','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0550','Onverdeeld Resultaat','A','0550','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0600','Voorziening Onderhoud','A','0600','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0610','Voorziening Garantie','A','0610','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0620','Voorziening Assurantie','A','0620','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0630','Voorziening Debiteuren','A','0630','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0700','Obligatielening','A','0700','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0710','Obligaties in portefeuille','A','0710','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0720','Converteerbare Obligatielening','A','0720','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0730','Agio op Obligaties','A','0730','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0740','Disagio op Obligaties','A','0740','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('0800','Hypothecaire lening o/g','A','0800','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1000','Financiele Rekeningen','H','1000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1001','Kas','A','1001','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1050','Contante Verkopen','A','1050','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1100','Interbank','A','1100','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1110','ABN-AMRO','A','1110','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1119','Postbank Plus','A','1119','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1120','Postbank Giro','A','1120','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1121','Postbank Kapitaal','A','1121','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1122','Postbank Leeuw','A','1122','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1139','Postbank Effectenrekening','A','1139','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1140','Rabobank','A','1140','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1141','Rabobank Rendementrekening','A','1141','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1160','van Lanschotbank','A','1160','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1170','Finansbank','A','1170','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1180','VISA Creditcard','A','1180','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1190','Kruisposten','A','1190','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1200','Debiteuren','A','1200','A','AR');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1205','Dubieuze Debiteuren','A','1205','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1321','Rekening Courant < A','A','1321','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1322','Rekening Courant < B','A','1322','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1340','Goederen ontvangen / GO','A','1340','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1500','Te betalen loonheffing','A','1500','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1520','Te betalen Sociale Lasten','A','1520','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1530','Te betalen Pensioenpremies','A','1530','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1600','Crediteuren','A','1600','L','AP');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1605','Nog te Ontvangen Facturen / NOF','A','1605','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1610','Te betalen tantiemes','A','1610','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1615','Te betalen Vennootschapsbelasting','A','1615','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1620','Interimdividend','A','1620','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1630','Te betalen dividend','A','1630','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1640','Te betalen dividendbelasting','A','1640','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1650','Aandeelhouders nog te storten','A','1650','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1700','Te betalen interest','A','1700','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1710','Te betalen coupons','A','1710','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1770','Uitgelote obligaties','A','1770','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1800','Te vorderen BTW hoog','A','1800','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1801','Te vorderen BTW laag','A','1801','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1810','Te betalen BTW hoog','A','1810','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1811','Te betalen BTW laag','A','1811','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1850','Saldo BTW','A','1850','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1941','Rekening Courant > A','A','1941','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1942','Rekening Courant > B','A','1942','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1960','Vooruitbetaalde bedragen','A','1960','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1970','Vooruitontvangen bedragen','A','1970','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1980','Nog te ontvangen bedragen','A','1980','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('1990','Nog te betalen bedragen','A','1990','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2000','Tussenrekeningen','H','2000','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2100','Vraagposten','A','2100','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2400','Onbekende betalingen','A','2400','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2800','Tussenrekening Lonen','A','2800','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('2900','Tussenrekening Beginbalans','A','2900','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('3000','Voorraad Grond- en Hulpstoffen','H','3000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('3010','Voorraad Grondstof A','A','3010','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4000','Kostenrekeningen','H','4000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4001','Verbruik Grondstoffen','A','4001','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4100','Directe Loonkosten','A','4100','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4110','Indirecte Loonkosten','A','4110','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4120','Sociale Lasten','A','4120','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4130','Kosten Pensioenen','A','4130','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4190','Overige Personeelskosten','A','4190','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4200','Kosten externe medewerkers','A','4200','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4210','Kosten Personeelsuitjes','A','4210','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4220','Kantinekosten','A','4220','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4240','Lief en Leedpot externe medewerkers','A','4240','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4300','Afschrijvingskosten Gebouwen','A','4300','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4330','Afschrijvingskosten Inventaris','A','4330','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4340','Afschrijvingskosten Computers','A','4340','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4350','Afschrijvingskosten Autos','A','4350','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4360','Afschrijvingskosten Machines','A','4360','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4390','Afschrijvingskosten Goodwill','A','4390','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4400','Huurkosten','A','4400','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4410','Asurantiekosten','A','4410','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4520','Gas, Licht & Water','A','4520','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4530','Vaste Lasten','A','4530','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4540','Reparatie- & Onderhoudskosten','A','4540','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4560','Verzekering en Beveiliging Pand','A','4560','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4600','Directe Verkoopkosten','A','4600','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4650','Indirecte Verkoopkosten','A','4650','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4730','Relatiegeschenken','A','4730','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4740','Reis en Verblijfkosten','A','4740','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4800','Kasverschillen','A','4800','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4810','Voorraadverschillen','A','4810','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4900','Telefoon & Faxkosten','A','4900','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4910','Contributies & Abonnementen','A','4910','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4920','Verzekeringen Algemeen','A','4920','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4930','Kantoorartikelen','A','4930','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4931','Kantoorbenodigdheden','A','4931','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4932','Vakliteratuur','A','4932','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4940','Licenties & Software','A','4940','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4941','Administratie & Acountantskosten','A','4941','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4943','Notaris & Advocaatkosten','A','4943','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4950','Drukwerk & Papier','A','4950','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4970','Porti','A','4970','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4980','Bankkosten','A','4980','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4981','Bankprovisie Effectenhandel','A','4981','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4990','Overige Algemene Kosten','A','4990','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4991','Bijzondere baten en lasten','A','4991','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('4999','Overboekingsrekening Rubriek 4','A','4999','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5000','Verdeling Indirecte Kosten','H','5000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5400','Indirecte fabricagekosten','A','5400','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5450','Opslag Indirecte fabricagekosten','A','5450','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5500','Indirecte verkoopkosten','A','5500','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5550','Opslag Indirecte verkoopkosten','A','5550','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('5999','Overboekingsrekening Rubriek 5','A','5999','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('6000','Fabricagerekeningen','H','6000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('6001','Verbruik Grondstoffen','A','6001','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('6010','Directe Lonen','A','6010','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('6020','Toeslag Indirecte fabricagekosten','A','6020','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('6101','Standaard Verbruik Grondstoffen','A','6101','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('6110','Standaard Directe Lonen','A','6110','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('6120','Standaard Toeslag Indirecte fabricagekosten','A','6120','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('6999','Overboekingsrekening Rubriek 6','A','6999','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('7000','Voorraden gereed product','H','7000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('7001','Voorraad A','A','7001','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('7002','Voorraad B','A','7002','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('7003','Voorraad C','A','7003','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('7010','Voorraad Incourante goederen','A','7010','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('7015','Afschrijving Incourante goederen','A','7015','L','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('7200','Voorraad Goederen in bewerking','A','7200','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('7300','Nog te Ontvangen Goederen / NOG','A','7300','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('7350','Nog af te leveren goederen','A','7350','L','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('7400','Prijsverschillen bij inkoop','A','7400','I','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('7999','Overboekingsrekening Rubriek 7','A','7999','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('8000','Rekeningen tbv Verkoopresultaat','H','8000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('8010','Inkoopkosten algemeen','A','8010','E','AP_amount:IC_cogs:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('8020','Kostprijs Verkopen A','A','8020','E','AP_amount:IC_cogs');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('8030','Kostprijs Verkopen B','A','8030','E','AP_amount:IC_cogs');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('8040','Kostprijs Verkopen C','A','8040','E','AP_amount:IC_cogs');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('8100','Directe Verkoopkosten','A','8100','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('8150','Toeslag Indirecte Verkoopkosten','E','8150','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('8300','Kortingen bij Verkoop','A','8300','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('8520','Opbrengst Verkopen A','A','8520','I','AR_amount:IC_sale');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('8530','Opbrengst Verkopen B','A','8530','I','AR_amount:IC_sale');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('8540','Opbrengst Verkopen C','A','8540','I','AR_amount:IC_sale');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('8999','Overboekingsrekening Rubriek 8','A','8999','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9000','Rekeningen tbv Resultatenrekening','H','9000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9010','Resultaat Indirecte Kosten','A','9010','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9011','Resultaat Fabricage','A','9011','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9012','Resultaat Verkoop','A','9012','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9015','Resultaat Prijsverschillen','A','9015','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9030','Rente bate deposito','A','9030','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9040','Rente bate lening u/g','A','9040','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9050','Rente bate bank','A','9050','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9080','Rente bate Fiscus','A','9080','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9100','Rente last hypothecaire lening','A','9100','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9110','Rente last lening bank','A','9110','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9130','Rente last lening o/g','A','9130','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9150','Rente last bank','A','9150','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9180','Rente last Fiscus','A','9180','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9190','Rente last overig','A','9190','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9200','Ontvangen Dividend (bruto)','A','9200','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9205','Ingehouden Dividendbelasting','A','9205','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9210','Koersresultaat Effecten)','A','9210','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9220','Valutaresultaat','A','9220','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9300','Huuropbrengsten','A','9300','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9400','Resultaat tgv inhaalafschrijvingen','A','9400','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9500','Incidentele Resultaten','A','9500','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9600','Giften en Donaties','A','9600','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9700','Tantiemes','A','9700','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9800','Belasting Lopend Jaar','A','9800','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9810','Belasting Voorgaande Jaren','A','9810','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9900','Vennootschapsbelasting','A','9900','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('9999','Overboekingsrekening','A','9999','I','');
+--
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '1800'),0.19);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '1801'),0.06);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '1810'),0.19);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '1811'),0.06);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '7001'), income_accno_id = (select id from chart where accno = '8520'), expense_accno_id = (select id from chart where accno = '8010'), fxgain_accno_id = (select id from chart where accno = '9220'), fxloss_accno_id = (select id from chart where accno = '9220'), invnumber = '0000', sonumber = '0000', ponumber = '0000', curr = 'EUR:USD', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/France-chart.sql b/sql-ledger/sql/France-chart.sql
new file mode 100644 (file)
index 0000000..a34e013
--- /dev/null
@@ -0,0 +1,951 @@
+-- Chart of Accounts for France
+-- From: Oscar Buijten <oscar@elbie.com>
+-- Mon, 6 Aug 2001
+--
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('101000', 'CAPITAL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('101100', 'CAPITAL SOUSCRIT NON APPELE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('101200', 'CAPITAL SOUSCRIT APPELE NON VERSE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('101300', 'CAPITAL SOUSCRIT APPELE VERSE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('101310', 'CAPITAL NON AMORTI', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('101320', 'CAPITAL AMORTI', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('101800', 'CAPITAL SOUSCR. A REGLEM. PART.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('104000', 'PRIMES LIEES AU CAPITAL SOCIAL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('104100', 'PRIMES D\'EMISSION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('104200', 'PRIMES DE FUSION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('104300', 'PRIMES D\'APPORT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('104400', 'PRIMES CONVERS. OBLIGAT. ACTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('104500', 'BONS DE SOUSCRIPTION D\'ACTION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('105000', 'ECARTS DE REEVALUATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('105100', 'RESERVE SPECIALE DE REEVALUATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('105200', 'ECART DE REEVALUATION LIBRE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('105300', 'RESERVE DE REEVALUATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('105500', 'ECARTS REEVAL. (AUT. OPER. LEG.)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('105700', 'AUT. ECARTS REEVAL. EN FRANCE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('105800', 'AUT. ECARTS REEVAL. A L\'ETRANGER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106000', 'RESERVES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106100', 'RESERVE LEGALE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106110', 'RESERVE LEGALE PROPREMENT DITE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106120', 'PLUS-VALUES NETTES A LONG TERME', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106200', 'RESERVES INDISPONIBLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106300', 'RESERVES STATUT. OU CONTRACTUELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106400', 'RESERVES REGLEMENTEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106410', 'PLUS-VALUES NETTES A LONG TERME', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106430', 'RESER. CONSEC. OCTROI SUBV. INVEST', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106480', 'AUTRES RESERVES REGLEMENTEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106800', 'AUTRES RESERVES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106810', 'RESERVE DE PROPRE ASSUREUR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('106880', 'RESERVES DIVERSES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('107000', 'ECART D\'EQUIVALENCE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('109000', 'ACTIONN. CAPITAL SOUSC. NON APPELE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('110000', 'REPORT A NOUVEAU (SOLDE CREDITEUR)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('119000', 'REPORT A NOUVEAU (SOLDE DEBITEUR)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('120000', 'RESULTAT DE L\'EXERCICE (BENEFICE)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('129000', 'RESULTAT DE L\'EXERCICE (PERTE)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('131000', 'SUBVENTIONS D\'EQUIPEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('131100', 'ETAT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('131200', 'REGIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('131300', 'DEPARTEMENTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('131400', 'COMMUNES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('131500', 'COLLECTIVITES PUBLIQUES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('131600', 'ENTREPRISES PUBLIQUES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('131700', 'ENTREPRISES ET ORGANISMES PRIVES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('131800', 'AUTRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('138000', 'AUTRES SUBVENTIONS D\'INVESTIS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('139000', 'SUBV. INVES. INSC. AU CPTE RESULT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('139100', 'SUBVENTIONS D\'EQUIPEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('139110', 'ETAT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('139120', 'REGIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('139130', 'DEPARTEMENTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('139140', 'COMMUNES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('139150', 'COLLECTIVITES PUBLIQUES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('139160', 'ENTREPRISES PUBLIQUES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('139170', 'ENTREPRISES ET ORGANISMES PRIVES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('139180', 'AUTRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('139800', 'AUTRES SUBVENTIONS D\'INVESTIS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('142000', 'PROVIS. REGLEM. RELATIV. AUX IMMO.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('142300', 'PROVIS. POUR RECONSTITUTION GIS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('142400', 'PROVIS. INVESTIS. (PARTIC. SALAR.)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('143000', 'PROVIS. REGLEMENT. RELATIV. STOCKS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('143100', 'HAUSSE DES PRIX', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('143200', 'FLUCTUATION DES COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('144000', 'PROVIS. REGLEM. RELAT. ELEM. ACTIF', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('145000', 'AMORTISSEMENTS DEROGATOIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('146000', 'PROVISION SPECIALE DE REEVALUATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('147000', 'PLUS-VALUES REINVESTIES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('148000', 'AUTRES PROVISIONS REGLEMENTEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('151000', 'PROVISIONS POUR RISQUES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('151100', 'PROVISIONS POUR LITIGES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('151200', 'PROV. GARANT. DONNEES AUX CLIENTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('151300', 'PROV. PERTES SUR MARCHES A TERME.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('151400', 'PROVIS. POUR AMENDES ET PENALITES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('151500', 'PROVIS. POUR PERTES DE CHANGE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('151800', 'AUTRES PROVISIONS POUR RISQUES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('153000', 'PROVIS. PENSIONS ET OBLIG. SIMIL.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('155000', 'PROVISIONS POUR IMPOTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('156000', 'PROVIS. RENOUV. IMMO (ETS CONCESS)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('157000', 'PROV. CHARG. A REPART. SUR EXERC.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('157200', 'PROVIS. POUR GROSSES REPARATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('158000', 'AUTRES PROVISIONS POUR CHARGES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('158200', 'PROVIS. CHARG. SOCIA. FISC. SUR CP', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('161000', 'EMPRUNTS OBLIGATOIRES CONVERTIBLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('163000', 'AUTRES EMPRUNTS OBLIGATAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('164000', 'EMPRUNTS AUPRES ETABLIS. DE CREDIT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('165000', 'DEPOTS ET CAUTIONNEMENTS RECUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('165100', 'DEPOTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('165500', 'CAUTIONNEMENTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('166000', 'PARTICIP. SALARIES AUX RESULTAS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('166100', 'COMPTES BLOQUES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('166200', 'FONDS DE PARTICIPATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('167000', 'EMPR. DETTES ASSORT. CONDIT. PART.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('167100', 'EMISSION DE TITRES PARTICIPATIFS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('167400', 'AVANCES CONDITIONNEES DE L\'ETAT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('167500', 'EMPRUNTS PARTICIPATIFS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('168000', 'AUTRES EMPR. ET DETTES ASSIMILEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('168100', 'AUTRES EMPRUNTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('168500', 'RENTES VIAGERES CAPITALISEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('168700', 'AUTRES DETTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('168800', 'INTERETS COURUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('168810', 'SUR EMPR. OBLIGATAIR. CONVERTIBLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('168830', 'SUR AUTRES EMPRUNTS OBLIGATAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('168840', 'SUR EMPRUNTS AUPRES ETABLI. CREDIT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('168850', 'SUR DEPOTS ET CAUTIONNEMENTS RECUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('168860', 'SUR PARTICIP. SALAR. RESULTATS ETS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('168870', 'SUR EMPR. DETTES ASSOR. COND. PART', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('168880', 'SUR AUTRES EMPR. DETTES ASSIMILEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('169000', 'PRIMES REMBOURSEMENT OBLIGATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('171000', 'DETTES RATTACH. A PARTIC. (GROUPE)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('174000', 'DETTES RATT. A PART. (HORS GROUPE)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('178000', 'DETTES RATTACH. A STES EN PARTIC.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('178100', 'PRINCIPAL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('178800', 'INTERETS COURUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('181000', 'COMPTE DE LIAISON ETABLISSEMENTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('186000', 'BIENS PREST. SERV. ECH. (CHARGES)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('187000', 'BIENS PREST. SERV. ECH. (PRODUITS)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('188000', 'COMPTES DE LIAISON STES EN PARTIC.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('201100', 'FRAIS DE CONSTITUTION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('201200', 'FRAIS DE PREMIER ETABLISSEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('201210', 'FRAIS DE PROSPECTION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('201220', 'FRAIS DE PUBLICITE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('201300', 'FRAIS AUGMEN. CAPIT. OPER. DIVERS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('203000', 'FRAIS RECHERCHE ET DEVELOPPEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('205000', 'CONCESSIONS ET DROITS SIMILAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('206000', 'DROIT AU BAIL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('207000', 'FONDS COMMERCIAL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('208000', 'AUTRES IMMOBILISATIONS INCORPOR.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211000', 'TERRAINS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211100', 'TERRAINS NUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211200', 'TERRAINS AMENAGES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211300', 'SOUS-SOLS ET SUR-SOLS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211400', 'TERRAINS DE GISEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211410', 'CARRIERES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211500', 'TERRAINS BATIS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211510', 'ENSEMBLES  IMMOBILIERS INDUSTRIELS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211550', 'ENSEMBLES IMMOB. ADM. ET COMMERC.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211580', 'AUTRES ENSEMBLES IMMOBILIERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211581', 'AFFECTES AUX OPERAT. PROFESSION.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211588', 'AFFECTES AUX OPERAT. NON PROF.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('211600', 'COMPTE D\'ORDRE SUR IMMOBILISATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('212000', 'AGENCEMENTS AMENAGEMENTS TERRAINS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213000', 'CONSTRUCTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213100', 'BATIMENTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213110', 'ENSEMBLES IMMOB. INDUSTRIELS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213150', 'ENSEMBLES IMMOB. ADM. ET COMMERC.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213180', 'AUTRES ENSEMBLES IMMOBILIERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213181', 'AFFECTES AUX OPERAT. PROFESSION.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213188', 'AFFECTES AUX OPERAT. NON PROF.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213500', 'INSTALLATIONS GENERALES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213800', 'OUVRAGES D\'INFRASTRUCTURE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213810', 'VOIES DE TERRE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213820', 'VOIES DE FER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213830', 'VOIES D\'EAU', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213840', 'BARRAGES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('213850', 'PISTES D\'AERODROMES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('214000', 'CONSTRUCTIONS SUR SOL D\'AUTRUI', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('215000', 'INSTALL. TECH. MAT. OUTIL. INDUS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('215100', 'INSTALL. COMPLEXES SPECIALISEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('215110', 'SUR SOL PROPRE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('215140', 'SUR SOL D\'AUTRUI', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('215300', 'INSTALL. A CARACTERE SPECIFIQUE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('215310', 'SUR SOL PROPRE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('215340', 'SUR SOL D\'AUTRUI', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('215400', 'MATERIEL INDUSTRIEL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('215500', 'OUTILLAGE INDUSTRIEL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('215700', 'AGENCEM. AMENAG. MAT. OUTIL. INDUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('218000', 'AUTRES IMMOBILISATIONS CORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('218100', 'INSTALL. GENE. AGENC. AMENAG. DIV.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('218200', 'MATERIEL DE TRANSPORT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('218300', 'MATERIEL DE BUREAU ET INFORMATIQUE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('218400', 'MOBILIER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('218500', 'CHEPTEL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('218600', 'EMBALLAGES RECUPERABLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('231000', 'IMMOBILISAT. CORPORELLES EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('231200', 'TERRAINS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('231300', 'CONSTRUCTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('231500', 'INSTALL. TECH. MAT. OUTIL. INDUST.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('231800', 'AUTRES IMMOBILISATIONS CORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('232000', 'IMMO. INCORPORELLES EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('237000', 'AVANC. ACOMPT. VERSES SUR IMM. INC', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('238000', 'AVANC. ACOMP. VERSES CDES IMM. COR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('238200', 'TERRAINS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('238300', 'CONSTRUCTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('238500', 'INSTALL. TECH. MAT. OUTIL. INDUST.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('238800', 'AUTRES IMMOBILISATIONS CORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('261000', 'TITRES DE PARTICIPATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('261100', 'ACTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('261800', 'AUTRES TITRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('266000', 'AUTRES FORMES DE PARTICIPATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('267000', 'CREANCES RATTACHEES A PARTICIPAT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('267100', 'CREANCES RATT. A PART. (GROUPE)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('267400', 'CREANC. RATT. PART. (HORS GROUPE)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('267500', 'VERSEM. D\'APPORTS NON CAPITALISES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('267600', 'AVANCES CONSOLIDABLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('267700', 'AUTRES CREANCES RATT. A PART.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('267800', 'INTERETS COURUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('268000', 'CREANCES RATT. A STE EN PART.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('268100', 'PRINCIPAL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('268800', 'INTERETS COURUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('269000', 'VERS. REST. A EFFECT. SUR T.P.N.L.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('271000', 'TITRES IMMOBILISES (DROIT PROP.)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('271100', 'ACTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('271800', 'AUTRES TITRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('272000', 'TITRES IMMOBILISES (DROIT CREANCE)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('272100', 'OBLIGATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('272200', 'BONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('273000', 'TITRES IMMOBILISES DE L\'ACT. DE PORTEF.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('274000', 'PRETS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('274100', 'PRETS PARTICIPATIFS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('274200', 'PRETS AUX ASSOCIES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('274300', 'PRETS AU PERSONNEL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('274800', 'AUTRES PRETS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('275000', 'DEPOTS ET CAUTIONNEMENTS VERSES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('275100', 'DEPOTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('275500', 'CAUTIONNEMENTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('276000', 'AUTRES CREANCES IMMOBILISEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('276100', 'CREANCES DIVERSES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('276800', 'INTERETS COURUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('276820', 'SUR TITRES IMMOB. (DROIT CREANCE)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('276840', 'SUR PRETS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('276850', 'SUR DEPOTS ET CAUTIONNEMENTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('276880', 'SUR CREANCES DIVERSES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('277100', 'ACTIONS PROPRES OU PARTS PROPRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('277200', 'ACT. PRO. OU PARTS PRO. VOIE D\'ANNUL.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('279000', 'VERSEM. A EFFECT. SUR T.I.N.L.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('280000', 'AMORTISS. IMMOBILISATIONS INCORP.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('280100', 'FRAIS D\'ETABLISSEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('280300', 'FRAIS DE RECHERCHE ET DEVELOPP.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('280500', 'CONCESSIONS ET DROITS SIMILAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('280700', 'FONDS COMMERCIAL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('280800', 'AUTRES IMMOBILISATIONS INCORPOR.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('281000', 'AMORTISS. IMMOBILISATIONS CORPOR.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('281100', 'TERRAINS DE GISEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('281200', 'AGENCEMENTS AMENAGEMENTS TERRAINS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('281300', 'CONSTRUCTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('281400', 'CONSTRUCTIONS SUR SOL D\'AUTRUI', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('281500', 'INSTALL TECH. MAT. OUTIL. INDUST.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('281800', 'AUTRES IMMOBILISATIONS CORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('282000', 'AMORTISS. IMMOBIL. EN CONCESSION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('290000', 'PROVIS. DEPRECIATION IMMOB. INCORP', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('290500', 'MARQUES PROCEDES DROITS ET VALEURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('290600', 'DROIT AU BAIL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('290700', 'FONDS COMMERCIAL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('290800', 'AUTRES IMMOB. INCORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('291000', 'PROVIS. DEPRECIATION IMMOB. CORPOR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('291100', 'TERRAINS (AUTRES QUE GISEMENT)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('292000', 'PROVIS. DEPRECIAT. IMMOB. CONCESS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('293000', 'PROVIS. DEPRECIAT. IMMOB. EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('293100', 'IMMOBILISATIONS CORPOR. EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('293200', 'IMMO. INCORPORELLES EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('296000', 'PROV. DEPREC. PART ET CREANC. PART', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('296100', 'TITRES DE PARTICIPATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('296600', 'AUTRES FORMES DE PARTICIPATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('296700', 'CREANCES RATT. A PARTICIPATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('296800', 'CREANCES RATT. A STE EN PARTICIP.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('297000', 'PROVIS. DEPRECIATION AUTRES IMMOB.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('297100', 'TITRES IMMOBILISES DROIT PROPRIETE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('297200', 'TITRES IMMOBILISES DROIT CREANCE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('297300', 'TITRES IMMO. DE L\'ACT. DE PORTEF.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('297400', 'PRETS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('297500', 'DEPOTS ET CAUTIONNEMENTS VERSES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('297600', 'AUTRES CREANCES IMMOBILISEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('311000', 'MATIERE (OU GROUPE) A', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('312000', 'MATIERE (OU GROUPE) B', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('317000', 'FOURNITURES A, B, C...', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('321000', 'MATIERES CONSOMMABLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('321100', 'MATIERE (OU GROUPE) C', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('321200', 'MATIERE (OU GROUPE) D', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('322000', 'FOURNITURES CONSOMMABLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('322100', 'COMBUSTIBLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('322200', 'PRODUITS D\'ENTRETIEN', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('322300', 'FOURNITURES D\'ATELIER ET D\'USINE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('322400', 'FOURNITURES DE MAGASIN', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('322500', 'FOURNITURES DE BUREAU', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('326000', 'EMBALLAGES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('326100', 'EMBALLAGES PERDUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('326500', 'EMBAL. RECUPER. NON IDENTIFIABLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('326700', 'EMBALLAGES A USAGE MIXTE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('331000', 'PRODUITS EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('331100', 'PRODUITS EN COURS P1', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('331200', 'PRODUITS EN COURS P2', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('335000', 'TRAVAUX EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('335100', 'TRAVAUX EN COURS T1', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('335200', 'TRAVAUX EN COURS T2', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('341000', 'ETUDES EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('341100', 'ETUDE EN COURS E1', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('341200', 'ETUDE EN COURS E2', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('345000', 'PRESTATIONS DE SERVICES EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('345100', 'PRESTATION DE SERVICES S1', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('345200', 'PRESTATION DE SERVICES S2', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('351000', 'PRODUITS INTERMEDIAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('351100', 'PRODUIT INTERMEDIAIRE (OU GRPE) A', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('351200', 'PRODUIT INTERMEDIAIRE (OU GRPE) B', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('355000', 'PRODUITS FINIS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('355100', 'PRODUIT FINI (OU GROUPE) A', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('355200', 'PRODUIT FINI (OU GROUPE) B', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('358000', 'PROD. RESIDUELS (OU MAT. RECUP.)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('358100', 'DECHETS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('358500', 'REBUTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('358600', 'MATIERES DE RECUPERATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('371000', 'MARCHANDISE (OU GROUPE) A', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('372000', 'MARCHANDISE (OU GROUPE) B', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('391000', 'PROVIS. POUR DEPRECIAT. MAT. PREM.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('391100', 'MATIERE (OU GROUPE) A', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('391200', 'MATIERE (OU GROUPE) B', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('391700', 'FOURNITURE A, B, C...', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('392000', 'PROVIS. POUR DEPRECIAT. AUT. APPRO', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('392100', 'MATIERES CONSOMMABLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('392200', 'FOURNITURES CONSOMMABLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('392600', 'EMBALLAGES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('393000', 'PROV. DEPREC. EN-COURS PROD. BIENS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('393100', 'PRODUITS EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('393500', 'TRAVAUX EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('394000', 'PROV. DEPREC. EN-COURS PROD. SERV.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('394100', 'ETUDES EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('394500', 'PRESTATIONS DE SERVICES EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('395000', 'PROV. POUR DEPREC. STOCKS DE PROD.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('395100', 'PRODUITS INTERMEDIAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('395500', 'PRODUITS FINIS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('397000', 'PROV. POUR DEPREC. STOCKS MARCHAN.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('397100', 'MARCHANDISE OU GROUPE A', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('397200', 'MARCHANDISE OU GROUPE B', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('401000', 'FOURNISSEURS DIVERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('403000', 'FOURNISSEURS - EFFETS A PAYER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('404000', 'FOURNISSEURS D\'IMMOBILISATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('404100', 'FOURNISSEURS ACHATS D\'IMMOBILISAT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('404700', 'FOURNIS. D\'IMMOB. RETENUES DE GAR.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('405000', 'FOURNIS. D\'IMMOB. EFFETS A PAYER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('408000', 'FOURNIS. FACTURES NON PARVENUES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('408100', 'FOURNISSEURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('408400', 'FOURNISSEURS D\'IMMOBILISATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('408800', 'FOURNISSEURS INTERETS COURUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('409000', 'FOURNISSEURS DEBITEURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('409100', 'FOURNIS. AVANC. & ACOMPT. SUR CDES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('409600', 'FOURN. CREAN. EMB. & MAT. A RENDRE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('409700', 'FOURNISSEURS AUTRES AVOIRS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('409710', 'FOURNISSEURS D\'EXPLOITATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('409740', 'FOURNISSEURS D\'IMMOBILISATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('409800', 'RABAIS REMISES RISTOUR. A OBTENIR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('410000', 'CLIENTS ET COMPTES RATTACHES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('411000', 'CLIENTS DIVERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('413000', 'CLIENTS EFFETS A RECEVOIR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('416000', 'CLIENTS DOUTEUX OU LITIGIEUX', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('417000', 'CREANC. SUR TRAV. NON ENCORE FACT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('418000', 'CLIENTS PRODUITS NON ENCORE FACT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('418100', 'CLIENTS FACTURES A ETABLIR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('418800', 'CLIENTS INTERETS COURUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('419000', 'CLIENTS CREDITEURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('419100', 'CLTS AVANC. & ACOMP. RECUS SUR CDE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('419600', 'CLTS DETT. POUR EMB. & MAT. CONSIG', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('419700', 'CLIENTS - AUTRES AVOIRS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('419800', 'RABAIS REMISES RIST. A ACCORDER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('421000', 'PERSONNEL REMUNERATIONS DUES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('422000', 'COMITES D\'ENTREPRISE, D\'ETABLIS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('424000', 'PARTICIP. DES SALAR. AUX RESULTATS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('424600', 'RESERVE SPECIALE (ART L442.2)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('424800', 'COMPTES COURANTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('425000', 'PERSONNEL AVANCES ET ACOMPTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('426000', 'PERSONNEL DEPOTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('427000', 'PERSONNEL OPPOSITIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('428000', 'PERS. CHARG. A PAY. & PROD. A REC.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('428200', 'DETTES PROVISIO. POUR CONGES PAYES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('428400', 'DETT. PROV. PART. SAL. AUX RESULT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('428600', 'AUTRES CHARGES A PAYER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('428700', 'PRODUITS A RECEVOIR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('438000', 'ORG. SOC. CHARG. A PAY. & PROD.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('438200', 'CHARGES SOCIALES SUR CONGES PAYES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('438700', 'PRODUITS A RECEVOIR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('441000', 'ETATS SUBVENTIONS A RECEVOIR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('441100', 'SUBVENTIONS D\'INVESTISSEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('441700', 'SUBVENTIONS D\'EXPLOITATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('441800', 'SUBVENTIONS D\'EQUILIBRE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('441900', 'AVANCES SUR SUBVENTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('442000', 'ETAT IMP. & TAX. RECOUV. SUR TIERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('442400', 'OBLIGATAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('442500', 'ASSOCIES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('443000', 'OPERATIONS PART. AVEC L\'ETAT,...', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('443100', 'CREANCES ETAT SUPPR. DECAL. TVA', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('443800', 'INTERES COURUS CREANCES CPTE 443100', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('444000', 'ETAT IMPOTS SUR LES BENEFICES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('444500', 'ETAT TAXES SUR LE CHIFFRE D\'AFF.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445200', 'TVA DUE INTRACOMMUNAUTAIRE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445510', 'TVA A DECAISSER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445580', 'TAXES ASSIMILEES A TVA', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445600', 'TAXES SUR LE CA DEDUCTIBLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445621', 'TVA SUR IMMO.  5.5%', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445622', 'TVA SUR IMMO. 20.6%', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445623', 'TVA SUR IMMO. 19.6%', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445630', 'TVA TRANSFEREE PAR D\'AUTRES ETS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445662', 'TVA DEDUCTIBLE 20.6%', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445670', 'CREDIT DE TVA A REPORTER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445680', 'TAXES ASSIMILEES A LA TVA', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445700', 'TAXE SUR LE C.A. COLLECT. ENTREPR.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445712', 'TVA COLLECTEE 20.6%', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445800', 'TAXES SUR CA A REGULAR. OU EN ATT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445810', 'ACOMPTES REGIME SIMPLIFIE D\'IMPOS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445820', 'ACOMPTES REGIME DU FORFAIT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445830', 'REMBOURS. TAXES SUR CA DEMANDE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445840', 'TVA RECUPEREE D\'AVANCE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445861', 'TVA EN ATTENTE DEDUCTIBLE  5.5%', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445862', 'TVA EN ATTENTE DEDUCTIBLE 20.6%', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445863', 'TVA EN ATTENTE DEDUCTIBLE 19.6%', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445871', 'TVA EN ATTENTE COLLECTEE  5.5%', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445872', 'TVA EN ATTENTE COLLECTEE 20.6%', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445873', 'TVA EN ATTENTE COLLECTEE 19.6%', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('446000', 'TITRES SUR TVA', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('446100', 'OBLIGATIONS CAUTIONNEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('446900', 'CREANCE TVA DECALAGE D\'UN MOIS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('447000', 'AUTRES IMPOTS, TAX. ET VERS. ASSIM', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('448000', 'ETAT CHARG. A PAY. & PROD. A RECEV', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('448200', 'CHARGES FISCALES SUR CONG. A PAYER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('448600', 'AUTRES CHARGES A PAYER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('448700', 'PRODUITS A RECEVOIR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('451000', 'GROUPE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('455000', 'ASSOCIES COMPTES COURANTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('455100', 'PRINCIPAL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('455780', 'TAXES ASSIMILEES A LA TVA', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('455800', 'INTERETS COURUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('456000', 'ASSOCIES OPERATIONS SUR LE CAPITAL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('456100', 'ASSOCIES COMPTES D\'APPORT EN STE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('456110', 'APPORTS EN NATURE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('456150', 'APPORTS EN NUMERAIRE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('456200', 'APPORTEURS CAPIT. APPELE NON VERSE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('456210', 'ACTION. CAP. SOUSC. APP. NON VERSE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('456250', 'ASSOCIES CAPITAL APPELE NON VERSE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('456300', 'ASSOC. VERS. RECUS SUR AUGM. CAPIT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('456400', 'ASSOCIES VERSEMENTS ANTICIPES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('456600', 'ACTIONNAIRES DEFAILLANTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('456700', 'ASSOCIES CAPITAL A REMBOURSER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('457000', 'ASSOCIES DIVIDENDES A PAYER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('458000', 'ASSOC. OPERAT. EN COMMUN ET EN GIE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('458100', 'OPERATIONS COURANTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('458800', 'INTERETS COURUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('462000', 'CREANCES SUR CESSIONS D\'IMMOBILIS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('464000', 'DETTES SUR ACQUIS. VALEURS MOBI.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('465000', 'CREANC. SUR CESSIONS VALEURS MOB.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('467000', 'AUTRES COMPTES DEBIT. OU CREDIT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('467200', 'DEBOURS PAYES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('468000', 'DIVERS CHARG. A PAY. & PROD. A REC', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('468600', 'CHARGES A PAYER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('468700', 'PRODUITS A RECEVOIR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('471000', 'COMPTES D\'ATTENTE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('471100', 'REIMPUTATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('476000', 'DIFFERENCES DE CONVERSION ACTIF', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('476100', 'DIMINUTION DES CREANCES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('476200', 'AUGMENTATION DES DETTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('476800', 'DIFFER. COMPENS. PAR COUV. CHANGE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('477000', 'DIFFERENCES DE CONVERSION PASSIF', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('477100', 'AUGMENTATION DES CREANCES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('477200', 'DIMINUTION DES DETTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('477800', 'DIFFER. COMPENS. PAR COUV. CHANGE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('478000', 'AUTRES COMPTES TRANSITOIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('481000', 'CHARG. A REPART. SUR PLUS. EXERC.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('481100', 'CHARGES DIFFEREES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('481200', 'FRAIS D\'ACQUISITION DES IMMOBILIS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('481600', 'FRAIS D\'EMISSION DES EMPRUNTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('481800', 'CHARGES A ETALER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('486000', 'CHARGES CONSTATEES D\'AVANCE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('487000', 'PRODUITS CONSTATES D\'AVANCE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('488000', 'CPTES REPART. PERIO. CHARG. & PROD', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('488600', 'CHARGES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('488700', 'PRODUITS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('491000', 'PROVIS. POUR DEPREC. CPTES CLIENTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('495000', 'PROV. POUR DEPREC. CPTES GRPE ASS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('495100', 'COMPTES DU GROUPE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('495500', 'COMPTES COURANTS DES ASSOCIES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('495800', 'OPERAT. FAITES EN COMMUN & EN GIE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('496000', 'PROVIS. POUR DEPREC. CPTES DEBIT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('496200', 'CREANCES SUR CESSIONS D\'IMMOBILIS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('496500', 'CREANC. SUR CESSIONS VALEURS MOB.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('496700', 'AUTRES COMPTES DEBITEURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('501000', 'PARTS DANS DES ENTREPRISES LIEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('502000', 'ACTIONS PROPRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('503000', 'ACTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('503100', 'TITRES COTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('503500', 'TITRES NON COTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('504000', 'AUTRES TITRES CONFERANT DROIT PROP', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('505000', 'OBLIG. & BONS EMIS PAR LA SOCIETE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('506000', 'OBLIGATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('506100', 'TITRES COTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('506500', 'TITRES NON COTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('507000', 'BONS TRESOR & BONS CAISSE A CT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('508000', 'AUTRES VALEURS MOB. ET CREANC. ASS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('508100', 'AUTRES VALEURS MOBILIERES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('508200', 'BONS DE SOUSCRIPTION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('508800', 'INTER. COURUS SUR OBLIGATIONS BONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('509000', 'VERS. A EFFECT. SUR VALEURS MOBIL.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('511000', 'VALEURS A L\'ENCAISSEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('511100', 'COUPONS ECHUS A L\'ENCAISSEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('511200', 'CHEQUES A ENCAISSER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('511300', 'EFFETS A L\'ENCAISSEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('511400', 'EFFETS A L\'ESCOMPTE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('512100', 'COMPTES EN MONNAIE NATIONALE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('512400', 'COMPTES EN DEVISES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('514000', 'CHEQUES POSTAUX', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('515000', 'CAISSES DU TRESOR ET ETS PUBLICS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('516000', 'SOCIETE DE BOURSE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('517000', 'AUTRES ORGANISMES FINANCIERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('518000', 'INTERETS EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('518600', 'INTERETS COURUS A PAYER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('518700', 'INTERETS COURUS A RECEVOIR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('519000', 'CONCOURS BANCAIRES COURANTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('519100', 'CREDIT MOBIL. CREANC. CCIALES CMCC', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('519300', 'MOBIL. CREANCES NEES A L\'ETRANGER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('519800', 'INT. COURUS SUR CONCOURS BANCAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('520000', 'INSTRUMENTS DE TRESORERIE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('531000', 'CAISSE SIEGE SOCIAL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('531100', 'CAISSE EN MONNAIE NATIONALE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('531400', 'CAISSE EN DEVISES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('532000', 'CAISSE SUCCURSALE (OU USINE) A', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('533000', 'CAISSE SUCCURSALE (OU USINE) B', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('580100', 'VIREMENT DE TRESORERIE A TRESORERIE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('590000', 'PROVIS. POUR DEPREC. VALEURS MOB.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('590300', 'ACTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('590400', 'AUTRES TIT. CONFERANT DROIT PROP.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('590600', 'OBLIGATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('590800', 'AUTRES VALEURS MOB. & CREANC. ASS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('601100', 'MATIERE (OU GROUPE) A', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('601200', 'MATIERE (OU GROUPE) B', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('601700', 'FOURNITURES A, B, C...', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602000', 'ACHATS STOCKES AUTRES APPROV.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602100', 'MATIERES CONSOMMABLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602110', 'MATIERE (OU GROUPE) C', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602120', 'MATIERE (OU GROUPE) D', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602200', 'FOURNITURES CONSOMMABLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602210', 'COMBUSTIBLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602220', 'PRODUITS D\'ENTRETIEN', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602230', 'FOURNITURES D\'ATELIER / USINES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602240', 'FOURNITURES DE MAGASINS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602250', 'FOURNITURES DE BUREAU', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602600', 'EMBALLAGES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602610', 'EMBALLAGES PERDUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602650', 'EMBALL. RECUPERA. NON IDENTIF.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('602670', 'EMBALLAGES A USAGE MIXTE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('603000', 'VARIATION DES STOCKS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('603100', 'VARIAT. STOCKS MAT. PREM. ET FOURN', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('603200', 'VARIAT. STOCKS AUTRES APPROVISION.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('603700', 'VARIATION STOCKS DE MARCHANDISES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('604000', 'ACHATS ETUDES ET PRESTAT. SERVICES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('605000', 'ACHATS MATERIEL EQUIPEM. TRAVAUX', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('606000', 'ACHATS NON STOCKES DE MAT. PREM.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('606400', 'FOURNITURES ADMINISTRATIVES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('606500', 'ACHATS SPECIAUX', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('606800', 'AUTRES MATIERES ET FOURNITURES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('607100', 'MARCHANDISE (OU GROUPE) A', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('607200', 'MARCHANDISE (OU GROUPE) B', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('608000', 'FRAIS ACCESSOIRES D\'ACHAT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('609000', 'RABAIS REMISES RIST. SUR ACHATS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('609100', 'DE MATIERES PREMIERES (ET FOURN.)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('609200', 'D\'AUTRES APPROVISIONN. STOCKES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('609500', 'DE MATERIEL EQUIPEMENTS DE TRAVAUX', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('609600', 'D\'APPROVISIONNEMENTS NON STOCKES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('609700', 'DE MARCHANDISES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('609800', 'RABAIS REMISES RIST. NON AFFECTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('612000', 'REDEVANCES DE CREDIT-BAIL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('612200', 'CREDIT-BAIL MOBILIER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('612500', 'CREDIT-BAIL IMMOBILIER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('613000', 'LOCATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('613600', 'MALIS SUR EMBALLAGES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('614000', 'CHARGES LOCATIVES & DE COPROPRIETE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('615200', 'SUR BIENS IMMOBILIERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('615500', 'SUR BIENS MOBILIERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('615600', 'MAINTENANCE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('616100', 'MULTIRISQUES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('616200', 'ASSUR. OBLIGAT. DOMMAGE-CONSTRUCT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('616300', 'ASSURANCE-TRANSPORT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('616360', 'SUR ACHATS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('616370', 'SUR VENTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('616380', 'SUR AUTRES BIENS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('616400', 'RISQUES D\'EXPLOITATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('616500', 'INSOLVABILITE CLIENTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('618000', 'DIVERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('618100', 'DOCUMENTATION GENERALE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('618500', 'FRAIS DE COLLOQUES, SEMIN., CONFER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('619000', 'RABAIS REMISES RIST. SUR SERV. EXT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('621000', 'PERSONNEL EXTERIEUR A L\'ENTREPRISE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('621400', 'PERSONNEL DETACHE OU PRETE A L\'ETS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('622000', 'REMUNERAT. D\'INTERM. ET HONORAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('622100', 'COMMISSIONS & COURTAGES SUR ACHATS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('622200', 'COMMISSIONS & COURTAGES SUR VENTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('622400', 'REMUNERATIONS DES TRANSITAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('622500', 'REMUNERATIONS D\'AFFACTURAGE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('622800', 'DIVERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('623000', 'PUBLICITE PUBLICAT. RELAT. PUBLIQ.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('623100', 'ANNONCES ET INSERTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('623200', 'ECHANTILLONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('623300', 'FOIRES ET EXPOSITIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('623500', 'PRIMES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('623600', 'CATALOGUES ET IMPRIMES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('623700', 'PUBLICATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('623800', 'DIVERS (POURBOIRES, DONS COURANTS)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('624000', 'TRANSP. BIENS & TRANSP. COLL. PERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('624100', 'TRANSPORTS SUR ACHATS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('624200', 'TRANSPORTS SUR VENTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('624300', 'TRANSPORTS ENTRE ETS OU CHANTIERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('624400', 'TRANSPORTS ADMINISTRATIFS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('624700', 'TRANSPORTS COLLECTIFS DU PERSONNEL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('624800', 'DIVERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('625000', 'DEPLACEM. MISSIONS ET RECEPTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('625500', 'FRAIS DE DEMENAGEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('625700', 'RECEPTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('627000', 'SERVICES BANCAIRES ET ASSIMILES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('627100', 'FRAIS SUR TITRES (ACHAT, VENTE,.).', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('627200', 'COMMISSIONS & FRAIS SUR EMPRUNTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('627500', 'FRAIS SUR EFFETS (COMM. D\'ENDOS,.)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('627600', 'LOCATION DE COFFRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('627800', 'AUTRES FRAIS & COMM. PREST. SERV.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('628000', 'DIVERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('628400', 'FRAIS DE RECRUTEMENT DU PERSONNEL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('629000', 'RABAIS REMISES RIST. SUR SERV. EXT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('631000', 'IMPOTS TAXES & VERS. SUR REMUNER.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('631100', 'TAXE SUR LES SALAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('631200', 'TAXE D\'APPRENTISSAGE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('631300', 'PART. EMPLOY. A FORM. PROF. CONT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('631400', 'COTIS. DEFAUT INVEST. DANS CONST.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('631800', 'AUTRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('633000', 'IMPOTS TAXES & VERS. SUR REMUNER.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('633100', 'VERSEMENT SUR LE TRANSPORT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('633200', 'ALLOCATION LOGEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('633300', 'PART. EMPLOY. A FORM.  PROF. CONT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('633400', 'PART. EMPLOY. A EFFORT CONSTRUCT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('633500', 'VERS. LIBERAT. A EXONER. TAXE APP.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('635000', 'AUTRES IMPOTS TAXES & VERS. ASS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('635100', 'IMPOTS DIRECTS (SAUF IMPOT BENEF.)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('635120', 'TAXES FONCIERES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('635130', 'AUTRES IMPOTS LOCAUX', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('635140', 'TAXE SUR LES VEHICULES SOCIETES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('635200', 'TAXES SUR CA NON RECUPERABLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('635300', 'IMPOTS INDIRECTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('635400', 'DROITS D\'ENREGISTREMENT ET TIMBRE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('635410', 'DROIT DE MUTATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('635800', 'AUTRES DROITS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('637000', 'AUTRES IMPOTS TAXES ET VERS. ASS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('637100', 'CONTRIB. SOC. SOLID. A CHARGE STES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('637200', 'TAXES PERCUES PAR ORG. PUBLICS INT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('637400', 'IMPOTS & TAXES EXIGIB. A L\'ETRANG.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('637800', 'TAXES DIVERSES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('641100', 'SALAIRES APPOINT. COMMIS. DE BASE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('641200', 'CONGES PAYES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('641300', 'PRIMES ET GRATIFICATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('641400', 'SALAIRES, APPOINTEMENTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('641500', 'SUPPLEMENT FAMILIAL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('644000', 'REMUNERATION TRAVAIL DE L\'EXPLOIT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('647000', 'AUTRES CHARGES SOCIALES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('647100', 'PRESTATIONS DIRECTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('647200', 'VERS. AUX COMITES D\'ETS & D\'ETAB.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('647300', 'VERS. AUX COMITES HYGIENE ET SECUR', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('647400', 'VERSEMENTS AUX OEUVRES SOCIALES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('647500', 'MEDECINE DU TRAVAIL, PHARMACIE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('648000', 'AUTRES CHARGES DE PERSONNEL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('651000', 'REDEVANC. CONCESS. BREV. LICENC,..', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('651100', 'REDEV. CONCESS. BREV, LIC, MARQ,..', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('651600', 'DROITS D\'AUTEUR ET DE REPRODUCT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('651800', 'AUTRES DROITS & VALEURS SIMILAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('653000', 'JETONS DE PRESENCE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('654000', 'PERTES SUR CREANCES IRRECOUVRAB.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('654100', 'CREANCES DE L\'EXERCICE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('654400', 'CREANCES DES EXERCICES ANTERIEURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('655000', 'QUOTE-PARTS RESULT. OPER. EN COMM.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('655100', 'Q-P BENEF. TRANSF. (CPTA GERANT)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('655500', 'QUOTE-PART PERTE SUPP. (CPTA ASS)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('658000', 'CHARGES DIVERSES GESTION COURANTE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('661000', 'CHARGES D\'INTERETS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('661100', 'INTERETS DES EMPRUNTS ET DETTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('661160', 'DES EMPRUNTS ET DETTES ASSIMILEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('661170', 'DES DETTES RATT. A PARTICIPATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('661500', 'INTERETS CPTES COUR. & DEP. CREDIT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('661600', 'INTERETS BANC. & SUR OPER. FINANC.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('661700', 'INTERETS OBLIGATIONS CAUTIONNEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('661800', 'INTERETS DES AUTRES DETTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('661810', 'DES DETTES COMMERCIALES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('661880', 'DES DETTES DIVERSES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('664000', 'PERTES CREANCES LIEES A PARTICIP.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('665000', 'ESCOMPTES ACCORDES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('667000', 'CHARG. NETTES SUR CESS. VAL. MOBIL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('668000', 'AUTRES CHARGES FINANCIERES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('668800', 'ECART DE CONVERSION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('671000', 'CHARG. EXCEPT. SUR OPERAT. GESTION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('671100', 'PENALITES SUR MARCHES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('671200', 'PENALITES AMENDES FISC. & PENALES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('671300', 'DONS, LIBERALITES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('671400', 'CREANC. DEVEN. IRRECOUV. SUR BENEF', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('671500', 'SUBVENTIONS ACCORDEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('671700', 'RAPPEL D\'IMPOTS (AUTRE QUE BENEF)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('671800', 'AUT. CHARG. EXCEP. SUR OPER. GEST.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('672000', 'CHARGES SUR EXERCICES ANTERIEURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('675000', 'VAL. COMPT. DES ELEM. ACTIF CEDES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('675100', 'IMMOBILISATIONS INCORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('675200', 'IMMOBILISATIONS CORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('675600', 'IMMOBILISATIONS FINANCIERES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('675800', 'AUTRES ELEMENTS D\'ACTIF', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('678000', 'AUTRES CHARGES EXCEPTIONNELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('678100', 'MALIS PROVENANT DE CLAUSES INDEXAT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('678200', 'LOTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('678300', 'MALIS DU RACHAT PAR ETS D\'ACTIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('678800', 'CHARGES EXCEPTIONNELLES DIVERSES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('681100', 'DOTAT. AUX AMORT. DES IMMOB. CORPO', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('681110', 'IMMOBILISATIONS INCORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('681120', 'IMMOBILISATIONS CORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('681200', 'DOTAT. AUX AMORT. CHARG. EXPLOIT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('681500', 'DOTAT. AUX PROV. RISQ. & CHARG. EX', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('681600', 'DOTAT. AUX PROV. DEPREC. IMMOB.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('681610', 'IMMOBILISATIONS INCORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('681620', 'IMMOBILISATIONS CORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('681700', 'DOTAT. AUX PROV. DEPREC. ACTIFS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('681740', 'CREANCES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('686000', 'DOTAT. AUX AMORT. ET AUX PROVIS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('686100', 'DOT. AUX AMORT. PRIME REMB. OBLIG.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('686500', 'DOT. AUX PROV. RISQ. & CHARG. FIN.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('686600', 'DOT. AUX PROV. DEPREC. ELEM. FINAN', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('686620', 'IMMOBILISATIONS FINANCIERES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('686650', 'VALEURS MOBILIERES DE PLACEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('686800', 'AUTRES DOTATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('687000', 'DOTAT. AUX AMORT. ET PROVISIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('687100', 'DOTAT. AUX AMORT. EXCEPT. IMMOB.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('687200', 'DOTAT. AUX PROV. REGLEM. (IMMOB)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('687250', 'AMORTISSEMENTS DEROGATOIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('687300', 'DOTAT. AUX PROV. REGLEM. (STOCKS)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('687400', 'DOTAT. AUX AUTRES PROV. REGLEMENT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('687500', 'DOTAT. PROV. RISQ. & CHARG. EXCEP.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('691000', 'PARTICIPATIONS DES SALARIES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('695200', 'CONTRIB. ADDITIO. IMPOT BENEFICES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('695400', 'IMPOTS DUS A L\'ETRANGER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('696000', 'SUPPLEMENT D\'IMPOTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('697000', 'IMPOSITION FORF. ANUELLE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('698000', 'INTEGRATION FISCALE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('698100', 'INTEGRATION FISCALE - CHARGES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('698900', 'INTEGRATION FISCALE - PRODUITS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('699000', 'PRODUITS REP. EN ARR. DES DEFICITS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('701000', 'VENTES DE PRODUITS FINIS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('701100', 'PRODUIT FINI (OU GROUPE) A', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('701200', 'PRODUIT FINI (OU GROUPE) B', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('702000', 'VENTES DE PRODUITS INTERMEDIAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('703000', 'VENTES DE PRODUITS RESIDUELS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('704000', 'TRAVAUX', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('704100', 'TRAVAUX DE CATEG. (OU ACTIV.) A', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('704200', 'TRAVAUX DE CATEG. (OU ACTIV.) B', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('705000', 'ETUDES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('707100', 'MARCHANDISE (OU GROUPE) A', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('707200', 'MARCHANDISE (OU GROUPE) B', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('708000', 'PRODUITS DES ACTIVITES ANNEXES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('708100', 'PROD. SERV. EXPLOIT. INTER. PERSON', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('708200', 'COMMISSIONS ET COURTAGES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('708300', 'LOCATIONS DIVERSES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('708400', 'MISE A DISPOS. PERSONNEL FACTUREE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('708500', 'PORTS ET FRAIS ACCESSOIRES FACT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('708600', 'BONIS SUR REPRISES EMBALL. CONSIG.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('708700', 'BONIFICAT. CLTS & PRIMES VENTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('708800', 'AUTRES PRODUITS ACTIVITES ANNEXES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('709000', 'RABAIS REMISES RIST. ACCORD. A ETS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('709100', 'SUR VENTES DE PRODUITS FINIS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('709200', 'SUR VENTES PRODUITS INTERMEDIAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('709400', 'SUR TRAVAUX', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('709500', 'SUR ETUDES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('709600', 'SUR PRESTATIONS DE SERVICES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('709700', 'SUR VENTES MARCHANDISES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('709800', 'SUR PRODUITS ACTIVITES ANNEXES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('713000', 'VARIAT. STOCKS (EN-COURS PRODUCT.)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('713300', 'VARIATION EN-COURS PRODUC. BIENS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('713310', 'PRODUITS EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('713350', 'TRAVAUX EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('713400', 'VARIATION EN-COURS PROD. SERVICES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('713410', 'ETUDES EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('713450', 'PRESTATIONS SERVICES EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('713500', 'VARIATION STOCKS DE PRODUITS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('713510', 'PRODUITS INTERMEDIAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('713550', 'PRODUITS FINIS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('713580', 'PRODUITS RESIDUELS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('721000', 'IMMOBILISATIONS INCORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('722000', 'IMMOBILISATIONS CORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('731000', 'PROD. NETS PART. SUR OP. EN COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('739000', 'PROD. NETS PART. SUR OP. TERMINEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('751000', 'REDEV. POUR CONCES. BREV. LIC....', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('751100', 'REDEV. POUR CONCES. BREV. LIC...', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('751600', 'DROITS D\'AUTEUR ET DE REPRODUCTION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('751800', 'AUTRES DROITS & VALEURS SIMILAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('752000', 'REV. IMMEUB. NON AFFECT. ACT. PROF', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('753000', 'JETONS PRESENCE ET REMUN. ADMINIST', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('754000', 'RISTOURNES PERCUES COOPERATIVES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('755000', 'QUOTES-PARTS RESULT. OP. EN COMMUN', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('755100', 'QUOTE-PART PERTE TRANSFEREE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('755500', 'QUOTE-PART BENEFICE ATTRIBUEE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('758000', 'PRODUITS DIVERS GESTION COURANTE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('761000', 'PRODUITS DE PARTICIPATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('761100', 'REVENUS TITRES DE PARTICIPATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('761600', 'REVENUS AUTRES FORMES PARTICIP.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('762000', 'PRODUITS AUTRES IMMOB. FINANC.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('762100', 'REVENUS DES TITRES IMMOBILISES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('762400', 'REVENUS DES PRETS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('762700', 'REVENUS CREANCES IMMOBILISEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('763000', 'REVENUS DES AUTRES CREANCES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('763100', 'REVENUS CREANCES COMMERCIALES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('763800', 'REVENUS DES CREANCES DIVERSES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('764000', 'REVENUS VALEURS MOBIL. PLACEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('765000', 'ESCOMPTES OBTENUS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('767000', 'PROD. NETS SUR CESS. VALEURS MOB.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('767100', 'REVENUS CRE. RATT. PARTICIPATIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('768000', 'AUTRES PRODUITS FINANCIERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('771000', 'PRODUITS EXCEPT. SUR OPER. GESTION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('771100', 'DEDITS PENAL. SUR ACHATS & VENTES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('771300', 'LIBERALITES PERCUES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('771400', 'RENTREES SUR CREANCES AMORTIES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('771500', 'SUBVENTIONS D\'EQUILIBRE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('771700', 'DEGREVEM. IMPOTS (AUT. IMP. BENEF)', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('771800', 'AUTRES PROD. EXCEPT. SUR OP. GEST.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('772000', 'PRODUITS SUR EXERCICES ANTERIEURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('775000', 'PRODUITS CESSIONS ELEMENTS D\'ACTIF', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('775100', 'IMMOBILISATIONS INCORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('775200', 'IMMOBILISATIONS CORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('775600', 'IMMOBILISATIONS FINANCIERES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('775800', 'AUTRES ELEMENTS D\'ACTIF', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('777000', 'Q-P SUBV. INVEST. AU RESULT. EXERC', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('778000', 'AUTRES PRODUITS EXCEPTIONNELS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('778100', 'BONIS PROVENANT CLAUSES D\'INDEXAT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('778200', 'LOTS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('778300', 'BONIS RACHAT PAR ETS ACT. & OBLIG.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('778800', 'PRODUITS EXCEPTIONNELS DIVERS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('781000', 'REPRISES SUR AMORTISS. & PROVIS.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('781100', 'REPRIS. AMORT. IMMOB. CORP. & INC', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('781110', 'IMMOBILISATIONS INCORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('781120', 'IMMOBILISATIONS CORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('781500', 'REPRIS. PROVIS. RISQ. & CH. EXPLOI', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('781600', 'REP. PROV. DEPREC. IMM. CORP & INC', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('781610', 'IMMOBILISATIONS INCORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('781620', 'IMMOBILISATIONS CORPORELLES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('781700', 'REPRIS. PROV. DEPREC. ACT. CIRCUL.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('781730', 'STOCKS ET EN-COURS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('781740', 'CREANCES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('786000', 'REPRISES SUR PROVIS. POUR RISQUES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('786500', 'REP. PROV. RISQ. & CHARG. FINANC.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('786600', 'REPRIS. PROV. DEPREC. ELEM. FINANC', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('786620', 'IMMOBILISATIONS FINANCIERES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('786650', 'VALEURS MOBILIERES DE PLACEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('787000', 'REPRISES SUR PROVISIONS', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('787200', 'REPRISES SUR PROV. REGLEMENTEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('787250', 'AMORTISSEMENTS DEROGATOIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('787260', 'PROVISION SPECIALE DE REEVALUATION', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('787270', 'PLUS-VALUES REINVESTIES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('787300', 'REPRISES SUR PROV. REGLEMENTEES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('787400', 'REPRIS. SUR AUTRES PROV. REGLEMENT', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('787500', 'REPRIS. PROV. RISQ. & CHARG. EXPL.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('787600', 'REPRIS. PROV. POUR DEPREC. EXCEPT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('791000', 'TRANSFERTS DE CHARGES D\'EXPLOIT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('796000', 'TRANSFERTS DE CHARGES FINANC.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('797000', 'TRANSFERTS DE CHARGES EXCEPT.', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('201000', 'FRAIS D\'ETABLISSEMENT', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('209000', 'SORTIE D\'IMMOBILISATION', 'A', '', 'I', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('474100', 'DIVERS A REINTEGRER', 'A', '', 'I', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('474200', 'BENEFICE SCM', 'A', '', 'I', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('475000', 'PLUS VALUES A COURT TERME', 'A', '', 'I', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('530000', 'CAISSE', 'A', '', 'I', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('760000', 'PRODUITS FINANCIERS', 'A', '', 'I', 'AR_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('770000', 'PRODUITS EXCEPTIONNELS', 'A', '', 'I', 'AR_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('530010', 'CAISSE', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('607000', 'ACHATS DE MARCHANDISES', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('622700', 'FRAIS D\'ACTES ET DE CONTENTIEUX', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('438600', 'AUTRES CHARGES A PAYER', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('473000', 'DIVERS A DEDUIRE', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('613200', 'LOCATIONS IMMOBILIERES', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('616000', 'PRIMES D\'ASSURANCE', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('633800', 'AUTRES', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('695000', 'IMPOTS SUR LES BENEFICES', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('108100', 'COMPTE DE LEXPLOITANT', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('512030', 'EPARGNE', 'A', '', 'A', 'AR_paid:AP_paid');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('100000', 'CLASSE 1', 'H', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('300000', 'CLASSE 3', 'H', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('500000', 'CLASSE 5', 'H', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('600000', 'CLASSE 6', 'H', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('700000', 'CLASSE 7', 'H', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('108000', 'COMPTE DE LEXPLOITANT', 'A', '', 'I', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('200001', 'IMMOBILISATION', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('200000', 'CLASSE 2', 'H', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('400001', 'FOURNISSEURS ET COMPTES RATTACHES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('400000', 'CLASSE 4', 'H', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('695100', 'IMPOTS DUS EN FRANCE', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('646000', 'COTIS. SOCIAL. PERSON. EXPLOITANT', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('645000', 'CHARGES DE SECUR. SOC. ET PREVOY.', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('617000', 'ETUDES ET RECHERCHES', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('615000', 'ENTRETIEN ET REPARATIONS', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('613500', 'LOCATIONS MOBILIERES', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('611000', 'SOUS-TRAITANCE GENERALE', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('695500', 'DEBOURS PAYES POUR LE COMPTE', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('690000', 'PARTICIP. SAL. / IMPOTS SUR BEN.', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('687600', 'DOTAT. AUX PROV. DEPREC. EXCEPT.', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('681000', 'DOTATIONS AUX AMORT. & AUX PROVIS.', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('628100', 'CONCOURS DIVERS (COTISATIONS,...)', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('625600', 'MISSIONS', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('645800', 'COTISATIONS AUX AUTRES ORG. SOC.', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('641000', 'REMUNERATIONS DU PERSONNEL', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('625020', 'DEPLACEMENTS MOTO', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('622600', 'HONORAIRES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('621100', 'PERSONNEL INTERIMAIRE', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445500', 'TAXES SUR CA A DECAISSER', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('706000', 'PRESTATIONS DE SERVICES', 'A', '', 'I', 'IC_income');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('707000', 'VENTES DE MARCHANDISES', 'A', '', 'I', 'IC_sale');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445713', 'TVA COLLECTEE 19.6%', 'A', '', 'I', 'AR_tax:IC_taxpart:IC_taxservice:CT_tax');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('512020', 'BANQUE DEBIT', 'A', '', 'E', 'AP');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445711', 'TVA COLLECTEE  5.5%', 'A', '', 'I', 'AR_tax:IC_taxpart:IC_taxservice:CT_tax');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445661', 'TVA DEDUCTIBLE  5.5%', 'A', '', 'E', 'AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('512010', 'BANQUE CREDIT', 'A', '', 'I', 'AR:AR_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('681730', 'STOCKS ET EN-COURS', 'A', '', 'A', 'IC');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('580010', 'VIREMENT INTERNE', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('580000', 'VIREMENT INTERNE', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('766000', 'GAINS DE CHANGE', 'A', '', 'I', 'AR_amount:IC_income');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('472000', 'MOINS VALUES A COURT TERME', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('474000', 'DEFICIT SCM', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('670000', 'CHARGES FINANCIERES', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('645100', 'COTISATIONS A L\'URSSAF', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('645200', 'COTISATIONS AUX MUTUELES', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('645300', 'COTISATIONS AUX CAISSES RETR.', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('646400', 'COTISATIONS AUX ASSEDIC', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('623400', 'CADEAUX A LA CLIENTELE', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('437000', 'AUTRES ORGANISMES SOCIAUX', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('606100', 'FOURNITURES NON STOCK. EAU ENERG.', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('606300', 'FOURNIT. ENTRETIEN & PETIT EQUIP.', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('625010', 'DEPLACEMENTS AUTO', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('635110', 'TAXE PROFESSIONNELLE', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('645001', 'CSG', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('660000', 'CHARGES FINANCIERES', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('666000', 'PERTES DE CHANGE', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('512040', 'EXPLOITANT', 'A', '', 'E', 'AP_paid');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('431000', 'SECURITE SOCIALE', 'A', '', 'E', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('609400', 'D\'ETUDES & PRESTATIONS DE SERVICES', 'A', '', '', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('625100', 'VOYAGES ET DEPLACEMENTS', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('618300', 'DOCUMENTATION TECHNIQUE', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('445663', 'TVA DEDUCTIBLE 19.6%', 'A', '', 'E', 'AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('601000', 'ACHATS STOCKES MAT. PREM. (FOURN.)', 'A', '', 'E', 'AP_amount:IC_cogs');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('626000', 'FRAIS POSTAUX ET TELECOMMUNIC.', 'A', '', 'E', 'AP_amount');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('512000', 'BANQUE', 'A', '', 'A', 'AR_paid:AP_paid');
+--
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('999000', 'Foreign Exchange Gain', 'A', '', 'I', '');
+INSERT INTO "chart" ("accno", "description", "charttype", "gifi_accno", "category", "link") VALUES ('999010', 'Foreign Exchange Loss', 'A', '', 'E', '');
+--
+-- insert taxes
+--
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '445661'), 0.055);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '445663'), 0.196);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '445711'), 0.055);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '445713'), 0.196);
+--
+-- update defaults
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '681730'), income_accno_id = (select id from chart where accno = '707000'), expense_accno_id = (select id from chart where accno = '601000'), fxgain_accno_id = (select id from chart where accno = '999000'), fxloss_accno_id = (select id from chart where accno = '999010'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'EUR', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/German-Sample-chart.sql b/sql-ledger/sql/German-Sample-chart.sql
new file mode 100644 (file)
index 0000000..3ebfdec
--- /dev/null
@@ -0,0 +1,216 @@
+-- Einfacher Deutscher Kontenrahmen => Very Easy German Default Chart  
+-- Vorbereitet von / Prepared by Paul Tammes May 9th, 2002. Kommentar / Comments : finance@bermuda-holding.com
+-- Englische Texte für eigene Zwecke und um Refernz in SQL-Ledger Dokumentation zu erleichtern.
+-- English terms used mostly for my own reference and to make lookup in SQL-Ledger documentation easier.
+-- GIFI-codes werden benutzt/misbraucht um die art der Rechnung zu deuten, Fehler nicht ausgeschlossen denn 
+-- Ich bin kein Deutscher Steuerberater ;-( 
+-- GIFI field codes re-used for following specs:
+-- Link: Achtung, sehr wenig benutzt da mir die Kentnisse zum Deutschen System fehlen. Sehr gut aufpassen und wenn
+-- Ihr Fehler oder Praktische TIPS hat: gerne!
+-- Link: used to a minimum, update and customization may well be needed!
+-- A0  = Anlagevermögen                / Fixed Assets
+-- A1-1 = Warenbestand                 / Inventory
+-- A1-2 = Forderungen                  / Liabilities
+-- A1-3 = Liquide Mittel               / Assets
+-- A1-4        = Aktive Rechnungsabgrenzung    / Closing Account results 
+-- E    = Erträge                      / Income 
+-- K0  = Wareneinsatz                  / COGS
+-- K1   = Personalkosten               / Salaries etc
+-- K2   = Raumkosten                   / Rental etc
+-- K3   = Sonstige Kosten              / Various costs
+-- NA  = Neutrale Aufwendungen         / Neutral Costs 
+-- NE  - Neutrale Erlöse               / Neutral Income
+-- P0  = Eigenkapital                  / Equity
+-- P1  = Rückstellungen                / Reserves
+-- P2  = Fremdkapital Langfristig      / Liabilities Long Term
+-- P3  = Fremdkapital Kurzfristig      / Liabilities Short Term
+-- P4  = Passive Rechnungsabgrenzung   / Closing Account results 
+--
+-- A0
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0000','ANLAGEVERMÖGEN','H','A0','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0100','Konzessionen & Lizenzen','A','A0','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0135','EDV-Programme','A','A0','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0440','Maschinen','A','A0','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0500','Betriebsausstattung','A','A0','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0520','PKW','A','A0','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0650','Büroeinrichtung','A','A0','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('0670','GWG','A','A0','A','');
+-- A1-1
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1100','WARENBESTAND','H','A1-1','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1140','Warenbestand','A','A1-1','A','IC');
+-- A1-2
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1200','FORDERUNGEN','H','A1-2','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1201','Geleistete Anzahlungen','A','A1-2','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1210','Forderungen ohne Kontokorrent','A','A1-2','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1300','Sonstige Forderungen','A','A1-2','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1400','Anrechenbare Vorsteuer','A','A1-2','A','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1401','Anrechenbare Vorsteuer 7%','A','A1-2','A','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1402','Vorsteuer ig Erwerb','A','A1-2','A','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1403','Vorsteuer ig Erwerb 16%','A','A1-2','A','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1405','Anrechenbare Vorsteuer 16%','A','A1-2','A','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1406','Anrechenbare Vorsteuer 15%','A','A1-2','A','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1433','bezahlte Einfuhrumsatzsteuer','A','A1-2','A','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1370','Ungeklärte Posten','A','A1-2','A','');
+-- A1-3
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1600','LIQUIDE MITTEL','H','A1-3','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1601','Kasse','A','A1-3','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1700','Postgiro','A','A1-3','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1800','Bank','A','A1-3','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1810','Bank USD','A','A1-3','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1820','Kreditkarten','A','A1-3','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1890','Geldtransit','A','A1-3','A','');
+-- A1-4
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1900','Aktive Rechnungsabgrenzung','A','A1-4','A','');
+-- P0
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2000','EIGENKAPITAL','H','P0','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2001','Eigenkapital','A','P0','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2100','Privatentnahmen','A','P0','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2150','Privatsteuern','A','P0','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2180','Privateinlagen','A','P0','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2200','Sonderausgaben beschr.abzugsf.','A','P0','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2900','Gezeichnetes Kapital','A','P0','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2910','Ausstehende Einlagen','A','P0','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2970','Gewinnvortrag vor Verwendung','A','P0','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2978','Verlustvortrag vor Verwendung','A','P0','Q','');
+-- P1
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3000','RÜCKSTELLUNGEN','H','P1','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3030','Gewerbesteuerrückstellung','A','P1','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3070','Sonstige Rückstellungen','A','P1','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3095','Rückstellung für Abschlusskosten','A','P1','L','');
+-- P2
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3100','FREMDKAPITAL LANGFRISTIG','H','P2','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3160','Bankdarlehen','A','P2','L','');
+-- P3
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3200','FREMDKAPITAL KURZFRISTIG','H','P3','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3280','Erhaltene Anzahlungen','A','P3','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3310','Kreditoren ohne Kontokorrent','A','P3','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3500','Sonstige Verbindlichkeiten','A','P3','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3560','Darlehen','A','P3','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3700','Verbindl. Betr.steuern u.Abgaben','A','P3','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3720','Verbindlichkeiten Löhne und Gehälter','A','P3','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3730','Verbindlichkeiten Lohnsteuer','A','P3','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3740','Verbindlichkeiten Sozialversicherung','A','P3','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3800','Umsatzsteuer','A','P3','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3801','Umsatzsteuer 7%','A','P3','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3802','Umsatzsteuer ig. Erwerb','A','P3','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3803','Umsatzsteuer ig. Erwerb 16%','A','P3','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3805','Umsatzsteuer 16%','A','P3','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3806','Umsatzsteuer 15%','A','P3','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3815','Umsatzsteuer nicht fällig 16%','A','P3','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3816','Umsatzsteuer nicht fällig 15%','A','P3','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3820','Umsatzsteuer-Vorauszahlungen','A','P3','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3841','Umsatzsteuer Vorjahr','A','P3','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+-- P4
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3900','Aktive Rechnungsabgrenzung','A','P4','L','');
+-- K0
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5100','WARENEINGANG','H','K0','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5200','Wareneingang ohne Vorsteuer','A','K0','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5300','Wareneingang 7%','A','K0','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5400','Wareneingang 15%','A','K0','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5420','ig.Erwerb 7% VoSt. und 7% USt.','A','K0','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5425','ig.Erwerb 15% VoSt. und 15% USt.','A','K0','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5731','Erhaltene Skonti 7% Vorsteuer','A','K0','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5736','Erhaltene Skonti 15% Vorsteuer','A','K0','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5800','Anschaffungsnebenkosten','A','K0','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5900','Fremdarbeiten','A','K0','E','AP_amount:IC_cogs:IC_expense');
+-- K1
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6000','PERSONALKOSTEN','H','K1','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6001','Personalkosten','H','K1','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6010','Löhne','A','K1','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6020','Gehälter','A','K1','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6030','Aushilfslöhne','A','K1','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6040','Lohnsteuer Aushilfen','A','K1','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6080','Vermögenswirksame Leistungen','A','K1','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6090','Fahrtkostenerst.Whg./Arbeitsstätte','A','K1','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6110','Sozialversicherung','A','K1','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6120','Berufsgenossenschaft','A','K1','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6130','Freiw. Soz. Aufw. LSt- u. Soz.Vers.frei','A','K1','E','');
+-- K2
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6300','RAUMKOSTEN','H','K2','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6310','Miete','A','K2','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6315','Pacht','A','K2','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6320','Heizung','A','K2','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6325','Gas Strom Wasser','A','K2','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6330','Reinigung','A','K2','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6335','Instandhaltung betriebliche Räume','A','K2','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6345','Sonstige Raumkosten','A','K2','E','AP_amount:IC_expense');
+-- K3
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6400','SONSTIGE KOSTEN','H','K3','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6402','Abschreibungen','A','K3','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6403','Kaufleasing','A','K3','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6404','Sofortabschreibung GWG','A','K3','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6405','Sonstige Kosten','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6410','Versicherung','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6420','Beiträge und Gebühren','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6430','Sonstige Abgaben','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6470','Rep. und Instandhaltung BGA','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6520','Kfz-Versicherung','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6530','Lfd. Kfz-Kosten','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6540','Kfz-Reparaturen','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6560','Fremdfahrzeuge','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6570','Sonstige Kfz-Kosten','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6600','Werbung','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6610','Kundengeschenke bis DM 75.','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6620','Kundengeschenke über DM 75.-','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6630','Repräsentationkosten','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6640','Bewirtungskosten','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6644','Nicht abzugsf.Bewirtungskosten','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6650','Reisekosten Arbeitnehmer','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6660','Reisekosten Arbeitnehmer 12.3%','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6665','Reisekosten Arbeitnehmer 9.8%','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6670','Reisekosten Unternehmer','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6680','Reisekosten Unternehmer 12.3%','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6685','Reisekosten Unternehmer 9.8%','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6688','Reisekosten Unternehmer 5.7%','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6690','Km-Geld-Erstattung 8.2%','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6710','Verpackungsmaterial','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6740','Ausgangsfrachten','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6780','Fremdarbeiten','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6800','Porto','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6805','Telefon','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6815','Bürobedarf','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6820','Zeitschriften & Bücher','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6825','Rechts- und Beratungskosten','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6835','Mieten für Einrichtungen','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6840','Mietleasing','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6845','Werkzeuge und Kleingeräte','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6850','Betriebsbedarf','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6852','Gastättenbedarf','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6855','Nebenkosten des Geldverkehrs','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6880','Aufwendungen aus Kursdifferenzen','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6885','Erlöse aus Anlageverk.(Buchverlust)','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7610','Gewerbesteuer','A','K3','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7685','Kfz-Steuer','A','K3','E','AP_amount:IC_cogs:IC_expense');
+-- E
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8100','ERTRÄGE','H','E','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8120','Steuerfreie Umsätze 4 Nr. 1a UStG.','A','E','I','AR_amount:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8125','Steuerfreie ig. Lieferungen 1b UStG.','A','E','I','AR_amount:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8200','Erlöse ohne Umsatzsteuer','A','E','I','AR_amount:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8300','Erlöse 7% Umsatzsteuer','A','E','I','AR_amount:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8400','Erlöse 15% Umsatzsteuer','A','E','I','AR_amount:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8500','Provisionserlöse','A','E','I','AR_amount:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8630','Entnahme sonstg. Leistungen 7% USt.','A','E','I','AR_amount:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8640','Entnahme sonstg. Leistungen 15% USt.','A','E','I','AR_amount:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8731','Gew. Skonti 7% USt.','A','E','I','AR_amount:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8736','Gew. Skonti 15% USt.','A','E','I','AR_amount:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8840','Erträge aus Kursdifferenzen','A','E','I','AR_amount:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8845','Erlöse aus Anlageverk. (Buchgewinn)','A','E','I','AR_amount:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8900','Erträge aus Abgang von Anlageverm.','A','E','I','AR_amount:IC_sale:IC_income');
+-- NA
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9300','NEUTRALE AUFWENDUNGEN','H','NA','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9310','Zinsen kurzfr. Verbindlichkeiten','A','NA','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9320','Zinsen langfr. Verbindlichkeiten','A','NA','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9500','Ausserordentl.Aufwendungen','A','NA','E','');
+-- NE
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9600','NEUTRALE ERTRÄGE','H','NE','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9610','Guthabenzinsen','H','NE','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9700','Ausserordentl.Erträge','H','NE','I','');
+--
+-- Default settings
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '3801'),0.07);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '3805'),0.16);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '3806'),0.15);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '1140'), income_accno_id = (select id from chart where accno = '8120'), expense_accno_id = (select id from chart where accno = '5800'), fxgain_accno_id = (select id from chart where accno = '8840'), fxloss_accno_id = (select id from chart where accno = '6880'), invnumber = '0000', sonumber = '0000', ponumber = '0000', curr = 'EUR', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/German-Sample-gifi.sql b/sql-ledger/sql/German-Sample-gifi.sql
new file mode 100644 (file)
index 0000000..78eaed4
--- /dev/null
@@ -0,0 +1,19 @@
+-- Einfacher Kontoplan für Deutschland
+--
+INSERT INTO gifi (accno,description) VALUES ('A0', 'Anlagevermögen');
+INSERT INTO gifi (accno,description) VALUES ('A1-1', 'Warenbestand');
+INSERT INTO gifi (accno,description) VALUES ('A1-2', 'Forderungen');
+INSERT INTO gifi (accno,description) VALUES ('A1-3', 'Liquide Mittel');
+INSERT INTO gifi (accno,description) VALUES ('A1-4', 'Aktive Rechnungsabgrenzung');
+INSERT INTO gifi (accno,description) VALUES ('E', 'Erträge');
+INSERT INTO gifi (accno,description) VALUES ('K0', 'Wareneinsatz');
+INSERT INTO gifi (accno,description) VALUES ('K1', 'Personalkosten');
+INSERT INTO gifi (accno,description) VALUES ('K2', 'Raumkosten');
+INSERT INTO gifi (accno,description) VALUES ('K3', 'Sonstige Kosten');
+INSERT INTO gifi (accno,description) VALUES ('NA', 'Neutrale Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('NE', 'Neutrale Erlöse');
+INSERT INTO gifi (accno,description) VALUES ('P0', 'Eigenkapital');
+INSERT INTO gifi (accno,description) VALUES ('P1', 'Rückstellungen');
+INSERT INTO gifi (accno,description) VALUES ('P2', 'Fremdkapital Langfristig');
+INSERT INTO gifi (accno,description) VALUES ('P3', 'Fremdkapital Kurzfristig');
+INSERT INTO gifi (accno,description) VALUES ('P4', 'Passive Rechnungsabgrenzung');
diff --git a/sql-ledger/sql/Germany-DATEV-SKR03-chart.sql b/sql-ledger/sql/Germany-DATEV-SKR03-chart.sql
new file mode 100644 (file)
index 0000000..126ce22
--- /dev/null
@@ -0,0 +1,262 @@
+-- DATEV-SKR03 - Kontenrahmen
+-- Mon, 10 Feb 2003
+-- Yvonne Einberger
+
+
+-- Jetzt beginnt der Kontenrahmen !
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0002700','EDV-Software','A','A','','0002700');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0010000','Fabrikbauten','A','A','','0010000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0011000','Garagen','A','A','','0011000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0011100','Außenanlagen','A','A','','0011100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0011200','Hof-und Wegebefestigung','A','A','','0011200');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0011500','Andere Bauten','A','A','','0011500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0016500','Geschäftsbauten','A','A','','0016500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0008500','Grundstückswert eige.bebau.Grundst.','A','A','','0008500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0009000','Geschäftsbauten','A','A','','0009000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0017000','Fabrikbauten','A','A','','0017000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0017500','Garagen','A','A','','0017500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0017600','Außenanlage','A','A','','0017600');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0021000','Maschinen','A','A','','0021000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0022000','Maschinengebundene Werkzeuge','A','A','','0022000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0024000','Maschinelle Anlagen','A','A','','0024000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0028000','Betriebsvorrichtung','A','A','','0028000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0031000','Andere Anlagen','A','A','','0031000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0032000','PKW','A','A','','0032000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0035000','LKW','A','A','','0035000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0040000','Betriebsausstattung','A','A','','0040000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0041000','Geschäftsausstattung','A','A','','0041000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0042000','Büroeinrichtung','A','A','','0042000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0043000','Ladeneinrichtung','A','A','','0043000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0049000','Sons.Betriebs- Geschäftsausstattung','A','A','','0049000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0050400','Ant.a.herr.o.m.Mehrh.bet.Ges.schaft','A','A','','0050400');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0051300','Typisch stille Beteiligungen','A','A','','0051300');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0063100','- Restlaufzeit bis 1 Jahr','A','L','','0063100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0051600','Atypische stille Beteiligungen','A','A','','0051600');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0064000','- Restlaufzeit 1 bis 5 Jahre','A','L','','0064000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0065000','- Restlaufzeit größer als 5 Jahre','A','L','','0065000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0099600','Pauschalwertb.m.Restlaufzeit v. 1J.','A','A','','0099600');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0140000','Ford. a.Lieferungen und Leistungen','A','A','AR','0140000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0153000','Forderungen gegen Personal','A','A','','0153000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0154500','Umsatzsteuerforderungen','A','A','','0154500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0100000','Kasse','A','A','AR_paid:AP_paid','0100000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0120000','Bank','A','A','AR_paid:AP_paid','0120000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0096300','Körperschaftssteuerrückstellung','A','Q','','0096300');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0095700','Gewerbesteuerrückstellung','A','Q','','0095700');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0051000','Beteiligungen','A','A','','0051000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0063000','Verbindl.gegenüber Kreditinstituten','A','L','','0063000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0097000','Sonstige Rückstellungen','A','L','','0097000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0097400','Rückstellungen für Gewährleistungen','A','L','','0097400');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0097800','Aufwandsrückstellungen','A','L','','0097800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0099800','Einzelwertber.m.Restlaufzeit v.1 J.','A','A','','0099800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0146000','Zweifelhafte Forderungen','A','A','','0146000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0151100','Geleistete Anzahlungen 7%','A','A','','0151100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0151700','Geleistete Anzahlung 16%','A','A','','0151700');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0152500','Kautionen','A','A','','0152500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0154000','Steuerüberzahlungen','A','A','','0154000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0157000','Abziehbare Vorsteuer','A','A','AR_tax:AP_tax','0157000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0160000','Verbindlichkeiten aus Lief.u.Leist.','A','L','AP','0160000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0174100','Verbindl.a.Lohn-und Kirchensteuer','A','L','','0174100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0178100','Umsatzsteuer-Vorauszahlung 1/11','A','L','','0178100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0178900','Umsatzsteuer laufendes Jahr','A','L','','0178900');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0179000','Umsatzsteuer Vorjahr','A','L','','0179000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0179100','Umsatzsteuer frühere Jahre','A','L','','0179100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0180000','Privatentnahme allgemein','A','Q','','0180000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0189000','Privateinlagen','A','Q','','0189000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0211000','Zinsaufwendung f.kurzf.Verbindlichk','A','E','','0211000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0212000','Zinsaufwendung f.langf.Verbindlichk','A','E','','0212000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0221000','Kapitalertragssteuer','A','E','','0221000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0231000','Anlagenabgänge - bei Buchverlust','A','E','','0231000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0231500','Anlagenabgänge-Buchgewinn','A','I','','0231500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0237500','Grundsteuer','A','E','','0237500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0245000','Einstell.i.d.Pauschalwertbe.z.Forde','A','E','','0245000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0245100','Einstell.i.d.Einzelwertb.z.Forderun','A','E','','0245100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0250000','Außerordentliche Erträge','A','I','','0250000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0251000','Betriebsfremde Erträge n.außerorden','A','I','','0251000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0252000','Periodenfremde Erträge nicht außero','A','I','','0252000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0273000','Ertr.a.Herab.d.Pauschal.z.Forderung','A','I','','0273000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0273100','Ertr.a.Herab.d.Einzelw.z.Forderunge','A','I','','0273100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0273200','Ertr. aus abgeschriebenen Forderung','A','I','','0273200');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0274200','Versicherungsentschädigungen','A','I','','0274200');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0286800','Verlustvortrag nach Verwendung','A','L','','0286800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0286900','Vortrag auf neue Rechnungen','A','L','','0286900');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0375000','Erhaltene Boni 7% Vorsteuer','A','I','','0375000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0376000','Erhaltene Boni 16% Vorsteuer','A','I','','0376000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0380000','Anschaffungsnebenkosten','A','E','IC_cogs:IC_expense','0380000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0385000','Zölle und Einfuhrabgaben','A','E','IC_cogs:IC_expense','0385000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0396000','Bestandsver.Roh-,Hilfs-.Betriebs.','A','E','','0396000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0397000','Bestand Roh-,Hilfs-,u.Betriebsstoff','A','A','IC','0397000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0399000','Verrechnete Stoffkosten','A','E','IC_cogs:IC_expense','0399000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0400000','Material-und Stoffverbrauch','A','E','IC_cogs:IC_expense','0400000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0410000','Löhne und Gehälter','A','E','AP_amount','0410000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0412500','Ehegattengehalt','A','E','AP_amount','0412500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0342000','Innergemein.Erwerb 7% VorSt u. Ust','A','E','AP_amount','0342000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0342500','Innergem.Erwerb 16% VorSt u. Ust','A','E','AP_amount','0342500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0373100','Erhaltene Skonti 7% Vorsteuer','A','I','AP_paid','0373100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0373500','Erhaltene Skonti 16% Vorsteuer','A','I','AP_paid','0373500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0330000','Wareneingang 7% Vorsteuer','A','E','AP_amount','0330000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0413000','Gesetzlich soziale Aufwendungen','A','E','AP_amount','0413000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0413800','Beiträge zur Berufsgenossenschaftr','A','E','AP_amount','0413800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0414500','Freiwillige sozi.Aufw.lohnsteuerfr.','A','E','AP_amount','0414500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0414900','Pauschale Lohnsteuera.sons.Bezüge','A','E','AP_amount','0414900');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0416500','Aufwendung f.Altersversorgung','A','E','AP_amount','0416500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0417000','Vermögenswirksame Leistungen','A','E','AP_amount','0417000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0420000','Raumkosten','A','E','AP_amount:AP_tax','0420000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0417500','Fahrtkostenerst.Wohnung/Arbeitsstät','A','E','AP_amount','0417500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0419000','Aushilfslöhne','A','E','AP_amount','0419000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0419900','Lohnsteuer für Aushilfe','A','E','AP_amount','0419900');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0159000','Durchlaufende Posten','A','A','','0159000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0422000','Pacht','A','E','AP_amount','0422000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0423000','Heizung','A','E','AP_amount','0423000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0424000','Gas,Strom, Wasser','A','E','AP_amount','0424000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0425000','Reinigung','A','E','AP_amount','0425000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0426000','Instandhaltung betrieb.Räume','A','E','AP_amount','0426000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0428000','Sonstige Raumkosten','A','E','AP_amount','0428000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0432000','Gewerbesteuer','A','E','AP_amount','0432000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0439000','Sonstige Abgaben','A','E','AP_amount','0439000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0453000','Laufende Kfz-Betriebskosten','A','E','AP_amount','0453000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0454000','Kfz-Reparaturen','A','E','AP_amount','0454000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0455000','Garagenmiete','A','E','AP_amount','0455000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0457000','Fremdfahrzeuge','A','E','AP_amount','0457000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0458000','Sonstige Kfz-Kosten','A','E','AP_amount','0458000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0461000','Werbekosten','A','E','AP_amount','0461000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0463000','Geschenke bis 40 EUR','A','E','AP_amount','0463000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0463500','Geschenke über 40 EUR','A','E','AP_amount','0463500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0464000','Repräsentationskosten','A','E','AP_amount','0464000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0465000','Bewirtungskosten','A','E','AP_amount','0465000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0465400','Nicht abzugsfähige Bewirtungskosten','A','E','AP_amount','0465400');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0465500','Nicht abzugsfähige Betriebsausgaben','A','E','','0465500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0466300','Reisekosten Arbeitn.m.Vorsteuerabzu','A','E','AP_amount','0466300');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0466600','Reisekosten Arbeitn.Übernachtungsau','A','E','','0466600');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0466800','Kilometerentgelderstattung Arbeitne','A','E','','0466800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0467400','Reisekosten Untern.Verpflegungsmehr','A','E','','0467400');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0467600','Reisekosten Untern.Übernachtungsauf','A','E','','0467600');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0467800','Kilometererstattungsgeld Unternehme','A','E','','0467800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0470000','Kosten der Warenabgabe','A','E','IC_cogs','0470000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0471000','Verpackungsmaterial','A','E','IC_cogs','0471000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0473000','Ausgangsfracht','A','E','IC_cogs','0473000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0475000','Transportversicherung','A','E','IC_cogs','0475000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0476000','Verkaufsprovision','A','E','IC_cogs','0476000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0478000','Fremdarbeiten','A','E','IC_cogs','0478000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0479000','Aufwand für Gewährleistungen','A','E','','0479000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0480900','Sonstige Reparaturen u.Instandhalt.','A','E','AP_amount','0480900');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0481000','Mietleasing','A','E','AP_amount','0481000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0481500','Kaufleasing','A','E','AP_amount','0481500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0482000','AfA a.Aufw.f.d.Inga.u.Erw.Geschäfts','A','E','AP_amount','0482000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0482100','AfA a.Aufw.f.d.Währungsumst.a.Euro','A','E','AP_amount','0482100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0483000','Abschreibungen auf Sachanlagen','A','E','AP_amount','0483000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0485500','Sofortabschreibung GWG','A','E','AP_amount','0485500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0491000','Porto','A','E','AP_amount','0491000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0492000','Telefon','A','E','AP_amount','0492000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0492500','Telefax','A','E','AP_amount','0492500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0493000','Bürobedarf','A','E','AP_amount','0493000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0494000','Zeitschriften, Bücher','A','E','AP_amount','0494000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0494500','Fortbildungskosten','A','E','AP_amount','0494500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0494600','Freiwillige Sozialleistungen','A','E','','0494600');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0495000','Rechts- und Beratungskosten','A','E','AP_amount','0495000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0495500','Buchführungskosten','A','E','AP_amount','0495500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0495700','Abschluß- und Prüfungskosten','A','E','AP_amount','0495700');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0496000','Mieten für Einrichtungen','A','E','AP_amount','0496000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0497000','Nebenkosten des Geldverkehrs','A','E','','0497000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0498000','Betriebsbedarf','A','E','AP_amount','0498000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0498500','Werkzeuge und Kleingeräte','A','E','AP_amount','0498500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0498600','Sonstige Aufwendungen (Ausbuchung)','A','E','AP_amount','0498600');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0136000','Geldtransit','A','A','','0136000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0705000','Unfertige Erzeugnisse','A','A','IC','0705000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0708000','Unfertige Leistungen','A','A','IC','0708000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0711000','Fertige Erzeugnisse (Bestand)','A','A','IC','0711000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0714000','Waren (Bestand)','A','A','IC','0714000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0873100','Gewährte Skonti 7% USt','A','I','AP_paid','0873100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0873500','Gewährte Skonti 16% USt.','A','I','AP_paid','0873500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0875000','Gewährte Boni 7% USt.','A','I','','0875000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0876000','Gewährte Boni 16% USt.','A','I','','0876000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0882000','Erlöse aus Anlageverkäufen 16%Ust','A','I','IC_sale','0882000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0895500','Umsatzsteuervergütungen','A','I','','0895500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0890500','Entnahme v. Gegenst.o.USt.','A','I','','0890500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0266000','Erträge aus Kursdifferenzen','A','I','','0266000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0215000','Aufwendungen aus Kursdifferenzen','A','E','','0215000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0850000','Provisionserlöse','A','I','AR_amount:IC_income','0850000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0830000','Erlöse 7%USt','A','I','AR_amount:IC_sale:IC_income','0830000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0840000','Erlöse 16% USt.','A','I','AR_amount:IC_sale:IC_income','0840000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0177100','Umsatzsteuer 7%','A','L','AR_tax:IC_taxpart:IC_taxservice:CT_tax','0177100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0177500','Umsatzsteuer 16%','A','L','AR_tax:IC_taxpart:IC_taxservice:CT_tax','0177500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0178000','Umsatzsteuer-Vorauszahlungen','A','L','AP_amount','0178000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0157100','Abziebare Vorsteuer 7%','A','A','AP_tax:IC_taxpart:IC_taxservice:CT_tax','0157100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0398000','Bestand Waren','A','A','IC','0398000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0340000','Wareneingang 16% Vorsteuer','A','E','AP_amount:IC_cogs','0340000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0383000','Leergut','A','E','IC_cogs','0383000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0492700','Internetkosten','A','E','AP_amount:IC_expense','0492700');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0451000','Kfz-Steuer','A','E','AP_amount','0451000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0452000','Kfz-Versicherungen','A','E','AP_amount','0452000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0492100','Telefon D1 Handy','A','E','AP_amount:IC_expense','0492000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0157500','Abziehbare Vorsteuer 16%','A','A','AP_tax:IC_taxpart:IC_taxservice:CT_tax','0157500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0900000','Saldenvorträge,Sachkonten','A','L','','0900000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0286000','Gewinnvortrag nach Verwendung','A','L','','0286000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0320000','Wareneingang o.Steuer','A','E','AP_amount','0320000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0084000','Kapitalrücklage','A','Q','','0084000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0086000','Gewinnvortrag vor Verwendung','A','Q','','0086000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0086800','Verlustvortrag vor Verwendung','A','L','','0086800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0086900','Vortrag auf neue Rechnungen','A','Q','','0086900');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0081000','Ausstehende Einlagen a.d.gez.Kapital eingefordert','A','A','','0081000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0080100','Ausst.Einl.a.d.gezeichnete Kapital n.eingef.','A','A','','0080100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0093000','Sonderposten mit Rücklagenanteil steuerf.Rückl.','A','L','','0093000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0095000','Rückstellungen f.Pensionen u.ähnl.Verpflichtungen','A','Q','','0095000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0098300','Abgrenzung aktive latente Steuern','A','A','','0098300');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0098600','Damnum/Disagio','A','A','','0098600');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0099200','Wertberichtigungen','A','A','','0099200');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0016000','Bauten auf fremden Grundstücken','A','A','','0016000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0020000','Techn.Anlagen und Maschinen','A','A','','0020000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0030000','Andere Anlagen,Betrieb-und Geschäftsaus','A','A','','0030000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0050000','Finanzanlagen','A','A','','0050000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0060000','Verbindlichkeiten','A','L','','0060000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0080000','Gezeichnetes Kapital','A','Q','','0080000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0095500','Steuerrückstellung','A','Q','','0095500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0098000','Aktive Rechnungsabgrenzung','A','A','','0098000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0099000','Passive Rechnungsabgrenzung','A','L','','0099000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0134500','Eigene Anteile','A','A','','0134500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0134800','Sonstige Wertpapiere','A','A','','0134800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0150000','Sonstige Vermögensgegenstände','A','A','','0150000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0151000','Geleistete Anzahlung auf Vorräte','A','A','','0151000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0159400','Forderungen geg. verb. Unternehmen','A','A','','0159400');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0171000','Erhaltene Anzahlungen-Verbindlichke','A','L','','0171000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0175500','Lohn-und Gehaltsverrechnung','A','L','','0175500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0210000','Zinsen und ähnl.Aufwendungen','A','E','','0210000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0230000','Sonstige Aufwendungen','A','E','','0230000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0240000','Forderungsverlust-übliche Höhe','A','E','','0240000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0260000','Erträge aus Beteiligten','A','I','','0260000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0262000','Erträge a.and.Wertpap.u.Ausl.des FinanzAV','A','I','','0262000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0265000','Sonstige Zinsen und ähnliche Erträg','A','I','','0265000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0270000','Sonstige Erträge','A','I','','0270000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0310000','Fremdleistungen','A','E','','0310000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0421000','Miete','A','E','AP_amount','0421000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0048000','Geringwertige WG bis 410EUR','A','A','AP_amount','0048000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0097700','Rückstellung.f.Abschluß-u.Prüfungskosten','A','L','','0097700');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0087000','Festkapital','A','Q','','0087000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0088000','Variables Kapital','A','Q','','0088000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0093100','Sonderpost.m.Rücklageanteil nach §6bEStG','A','Q','','0093100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0093200','Sonderpost.m.Rücklageanteil n.35 EStR','A','Q','','0093200');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0130000','Wechsel a. Lieferungen u.Leistungen','A','A','','0130000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0131000','Besitzwechsel geg.verb.Unternehmen','A','A','','0131000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0132000','Besitzw.geg.Untern.m.Beteiligungsve','A','A','','0132000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0132700','Finanzwechsel','A','A','','0132700');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0133000','Schecks ','A','A','','0133000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0134000','Anteile verb.Untern.-Umlaufvermögen','A','A','','0134000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0272500','Erträge a.d.Abgang.v.Geg.d.UV','A','I','','0272500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0272000','Erträge a.d.Abgang v.Geg.d.AV','A','I','','0272000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0434000','Sonstige Betriebssteuern','A','E','AP_amount','0434000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0436000','Versicherungen','A','E','AP_amount','0436000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0438000','Beiträge','A','E','AP_amount','0438000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0450000','Fahrzugkosten','A','E','AP_amount','0450000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0700000','Unfertige Erzeugnisse unfert.Leistungen','A','A','','0700000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0900800','Saldenvorträge,Debitoren','A','L','','0900800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('0900900','Saldenvorträge,Kreditoren','A','L','','0900900');
+--
+-- Taxes
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '0397000'), income_accno_id = (select id from chart where accno = '0840000'), expense_accno_id = (select id from chart where accno = '0400000'), fxgain_accno_id = (select id from chart where accno = '0266000'), fxloss_accno_id = (select id from chart where accno = '0215000'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'EUR:USD', weightunit = 'kg';
+--
+INSERT INTO tax (chart_id,rate) VALUES ((SELECT id FROM chart WHERE accno = '0157100'),0.07);
+INSERT INTO tax (chart_id,rate) VALUES ((SELECT id FROM chart WHERE accno = '0157500'),0.16);
+INSERT INTO tax (chart_id,rate) VALUES ((SELECT id FROM chart WHERE accno = '0177100'),0.07);
+INSERT INTO tax (chart_id,rate) VALUES ((SELECT id FROM chart WHERE accno = '0177500'),0.16);
+
+
diff --git a/sql-ledger/sql/Germany-DATEV-SKR03-gifi.sql b/sql-ledger/sql/Germany-DATEV-SKR03-gifi.sql
new file mode 100644 (file)
index 0000000..36d11ab
--- /dev/null
@@ -0,0 +1,550 @@
+-- DATEV SKR03
+--
+INSERT INTO gifi (accno,description) VALUES ('0000100', 'Aufwand Geschäftsbetrieb');
+INSERT INTO gifi (accno,description) VALUES ('0000200', 'Aufwendungen Umstellung a.d.Euro');
+INSERT INTO gifi (accno,description) VALUES ('0001000', 'Konzession,gewerb.Schutzre.u.Werten');
+INSERT INTO gifi (accno,description) VALUES ('0001500', 'Konzessionen');
+INSERT INTO gifi (accno,description) VALUES ('0002700', 'EDV-Software');
+INSERT INTO gifi (accno,description) VALUES ('0003500', 'Geschäfts-oder Firmenwert');
+INSERT INTO gifi (accno,description) VALUES ('0003800', 'Anzahlungen a.Geschäft-o.Firmenwert');
+INSERT INTO gifi (accno,description) VALUES ('0003900', 'Anz.a.immaterielle Vermögsgegenstän');
+INSERT INTO gifi (accno,description) VALUES ('0004000', 'Verschmelzungsmehrwert');
+INSERT INTO gifi (accno,description) VALUES ('0005000', 'Grundstücke,grundstücksgl.Rechte..');
+INSERT INTO gifi (accno,description) VALUES ('0006000', 'Grundstücke u.grundstgl.Rech.o.Baut');
+INSERT INTO gifi (accno,description) VALUES ('0008000', 'Bauten a.eig. Grundstücken,Grgl.Rec');
+INSERT INTO gifi (accno,description) VALUES ('0008500', 'Grundstückswert eige.bebau.Grundst.');
+INSERT INTO gifi (accno,description) VALUES ('0009000', 'Geschäftsbauten');
+INSERT INTO gifi (accno,description) VALUES ('0010000', 'Fabrikbauten');
+INSERT INTO gifi (accno,description) VALUES ('0011000', 'Garagen');
+INSERT INTO gifi (accno,description) VALUES ('0011100', 'Außenanlagen');
+INSERT INTO gifi (accno,description) VALUES ('0011200', 'Hof-und Wegebefestigung');
+INSERT INTO gifi (accno,description) VALUES ('0011500', 'Andere Bauten');
+INSERT INTO gifi (accno,description) VALUES ('0012000', 'Geschäfts-,Fabrik-,andere Bau.imBau');
+INSERT INTO gifi (accno,description) VALUES ('0012900', 'Anz.Geschäfts-,Fabrik u. and.Bauten');
+INSERT INTO gifi (accno,description) VALUES ('0015000', 'Wohnbauten im Bau');
+INSERT INTO gifi (accno,description) VALUES ('0016000', 'Bauten auf fremden Grundstücken');
+INSERT INTO gifi (accno,description) VALUES ('0016500', 'Geschäftsbauten');
+INSERT INTO gifi (accno,description) VALUES ('0017000', 'Fabrikbauten');
+INSERT INTO gifi (accno,description) VALUES ('0017500', 'Garagen');
+INSERT INTO gifi (accno,description) VALUES ('0017600', 'Außenanlage');
+INSERT INTO gifi (accno,description) VALUES ('0020000', 'Techn.Anlagen und Maschinen');
+INSERT INTO gifi (accno,description) VALUES ('0021000', 'Maschinen');
+INSERT INTO gifi (accno,description) VALUES ('0022000', 'Maschinengebundene Werkzeuge');
+INSERT INTO gifi (accno,description) VALUES ('0024000', 'Maschinelle Anlagen');
+INSERT INTO gifi (accno,description) VALUES ('0028000', 'Betriebsvorrichtung');
+INSERT INTO gifi (accno,description) VALUES ('0029000', 'Techn.Anlagen u.Maschinen im Bau');
+INSERT INTO gifi (accno,description) VALUES ('0029900', 'Anz.a.techn.Anlagen und Maschinen');
+INSERT INTO gifi (accno,description) VALUES ('0030000', 'Andere Anlagen,Betrieb-Geschäftsaus');
+INSERT INTO gifi (accno,description) VALUES ('0031000', 'Andere Anlagen');
+INSERT INTO gifi (accno,description) VALUES ('0032000', 'PKW');
+INSERT INTO gifi (accno,description) VALUES ('0035000', 'LKW');
+INSERT INTO gifi (accno,description) VALUES ('0040000', 'Betriebsausstattung');
+INSERT INTO gifi (accno,description) VALUES ('0041000', 'Geschäftsausstattung');
+INSERT INTO gifi (accno,description) VALUES ('0042000', 'Büroeinrichtung');
+INSERT INTO gifi (accno,description) VALUES ('0043000', 'Ladeneinrichtung');
+INSERT INTO gifi (accno,description) VALUES ('0048000', 'Geringwertige Wirtschaftsg.b.800DM');
+INSERT INTO gifi (accno,description) VALUES ('0049000', 'Sons.Betriebs- Geschäftsausstattung');
+INSERT INTO gifi (accno,description) VALUES ('0049800', 'And. Anlagen,Betrieb/Geschäf.im Bau');
+INSERT INTO gifi (accno,description) VALUES ('0049900', 'Anz.and.Anlagen,Betrieb.Geschäftsau');
+INSERT INTO gifi (accno,description) VALUES ('0050000', 'Anteile a.verb.Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('0050400', 'Ant.a.herr.o.m.Mehrh.bet.Ges.schaft');
+INSERT INTO gifi (accno,description) VALUES ('0050500', 'Ausleihung an verb.Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('0051000', 'Beteiligungen');
+INSERT INTO gifi (accno,description) VALUES ('0051300', 'Typisch stille Beteiligungen');
+INSERT INTO gifi (accno,description) VALUES ('0051600', 'Atypische stille Beteiligungen');
+INSERT INTO gifi (accno,description) VALUES ('0052000', 'Ausl.a.Untern.m.Beteiligungsverhält');
+INSERT INTO gifi (accno,description) VALUES ('0052500', 'Wertpapiere des Anlagevermögens');
+INSERT INTO gifi (accno,description) VALUES ('0054000', 'Sonstige Ausleihungen');
+INSERT INTO gifi (accno,description) VALUES ('0057000', 'Genossenschaftsan.z.langf.Verbleib');
+INSERT INTO gifi (accno,description) VALUES ('0059500', 'Rückdeckansp.Lebensvers.langf.Verbl');
+INSERT INTO gifi (accno,description) VALUES ('0060000', 'Anleihen-nicht konvertibel');
+INSERT INTO gifi (accno,description) VALUES ('0063000', 'Verbindl.gegenüber Kreditinstituten');
+INSERT INTO gifi (accno,description) VALUES ('0070000', 'Verbind.gegenüber verb.Unternehmern');
+INSERT INTO gifi (accno,description) VALUES ('0071500', 'Verbind.gegen.Untern.m.Beteili.Verh');
+INSERT INTO gifi (accno,description) VALUES ('0073000', 'Verbindlichkeiten gegen. Gesellscha');
+INSERT INTO gifi (accno,description) VALUES ('0076000', 'Darl.typ.stiller Gesellschafter');
+INSERT INTO gifi (accno,description) VALUES ('0078000', 'Partiarische Darlehen');
+INSERT INTO gifi (accno,description) VALUES ('0080000', 'Gezeichnetes Kapital');
+INSERT INTO gifi (accno,description) VALUES ('0080100', 'Ausst.Einl.a.d.gezeichnete Kapital');
+INSERT INTO gifi (accno,description) VALUES ('0084000', 'Kapitalrücklage');
+INSERT INTO gifi (accno,description) VALUES ('0084600', 'Gesetzliche Rücklage');
+INSERT INTO gifi (accno,description) VALUES ('0085000', 'Rücklage für eigene Anteile');
+INSERT INTO gifi (accno,description) VALUES ('0085100', 'Satzungsmäßige Rücklagen');
+INSERT INTO gifi (accno,description) VALUES ('0086000', 'Gewinnvortrag vor Verwendung');
+INSERT INTO gifi (accno,description) VALUES ('0086800', 'Verlustvortrag vor Verwendung');
+INSERT INTO gifi (accno,description) VALUES ('0086900', 'Vortrag auf neue Rechnungen');
+INSERT INTO gifi (accno,description) VALUES ('0087000', 'Festkapital');
+INSERT INTO gifi (accno,description) VALUES ('0088000', 'Variables Kapital');
+INSERT INTO gifi (accno,description) VALUES ('0089000', 'Gesellschafter-Darlehen');
+INSERT INTO gifi (accno,description) VALUES ('0090000', 'Kommandit-Kapital');
+INSERT INTO gifi (accno,description) VALUES ('0091000', 'Verlustausgleichskonto');
+INSERT INTO gifi (accno,description) VALUES ('0092000', 'Gesellschafter-Darlehen');
+INSERT INTO gifi (accno,description) VALUES ('0093000', 'Sonderposten mit Rücklagenanteil');
+INSERT INTO gifi (accno,description) VALUES ('0093100', 'Sopo m.Rückl.ant.nach §6b EstG');
+INSERT INTO gifi (accno,description) VALUES ('0093200', 'Sopo m.Rückl.ant.Abschn.35 EstR');
+INSERT INTO gifi (accno,description) VALUES ('0093500', 'Sopo aus Währungsumstellung Euro');
+INSERT INTO gifi (accno,description) VALUES ('0094700', 'Sopo m.Rückl.ant. §7g Abs.1 EstG');
+INSERT INTO gifi (accno,description) VALUES ('0094800', 'Sopo m.Rückl.ant. §7g Abs.3,7 EstG');
+INSERT INTO gifi (accno,description) VALUES ('0095500', 'Steuerrückstellung');
+INSERT INTO gifi (accno,description) VALUES ('0095700', 'Gewerbesteuerrückstellung');
+INSERT INTO gifi (accno,description) VALUES ('0096300', 'Körperschaftssteuerrückstellung');
+INSERT INTO gifi (accno,description) VALUES ('0096900', 'Rückstellung für latente Steuern');
+INSERT INTO gifi (accno,description) VALUES ('0097000', 'Sonstige Rückstellungen');
+INSERT INTO gifi (accno,description) VALUES ('0097400', 'Rückstellungen für Gewährleistungen');
+INSERT INTO gifi (accno,description) VALUES ('0097600', 'Rücks.f.drohe.Verl.schweb.Geschäft');
+INSERT INTO gifi (accno,description) VALUES ('0097700', 'Rücks.f.Abschluß-u.Prüfungskosten');
+INSERT INTO gifi (accno,description) VALUES ('0097800', 'Aufwandsrückstellungen');
+INSERT INTO gifi (accno,description) VALUES ('0098000', 'Aktive Rechnungsabgrenzung');
+INSERT INTO gifi (accno,description) VALUES ('0098300', 'Abgrenzung aktive latente Steuern');
+INSERT INTO gifi (accno,description) VALUES ('0098600', 'Damnum/Disagio');
+INSERT INTO gifi (accno,description) VALUES ('0099000', 'Passive Rechnungsabgrenzung');
+INSERT INTO gifi (accno,description) VALUES ('0099200', 'Wertberichtigungen');
+INSERT INTO gifi (accno,description) VALUES ('0099600', 'Pauschalwertb.m.Restlaufzeit v. 1J.');
+INSERT INTO gifi (accno,description) VALUES ('0099800', 'Einzelwertber.m.Restlaufzeit v.1 J.');
+INSERT INTO gifi (accno,description) VALUES ('0100000', 'Kasse');
+INSERT INTO gifi (accno,description) VALUES ('0110000', 'Postbank');
+INSERT INTO gifi (accno,description) VALUES ('0120000', 'Bank');
+INSERT INTO gifi (accno,description) VALUES ('0121000', 'Dresdner Bank AG');
+INSERT INTO gifi (accno,description) VALUES ('0121009', 'Verrechnungskonto Dresdner Bank AG');
+INSERT INTO gifi (accno,description) VALUES ('0122000', 'Deutsche Bank AG');
+INSERT INTO gifi (accno,description) VALUES ('0130000', 'Wechsel a. Lieferungen u.Leistungen');
+INSERT INTO gifi (accno,description) VALUES ('0131000', 'Besitzwechsel geg.verb.Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('0132000', 'Besitzw.geg.Untern.m.Beteiligungsve');
+INSERT INTO gifi (accno,description) VALUES ('0132700', 'Finanzwechsel');
+INSERT INTO gifi (accno,description) VALUES ('0133000', 'Schecks (Eingang)');
+INSERT INTO gifi (accno,description) VALUES ('0133300', 'Schecks (Ausgang)');
+INSERT INTO gifi (accno,description) VALUES ('0133500', 'Überweisungen (unterwegs)');
+INSERT INTO gifi (accno,description) VALUES ('0134000', 'Anteile verb.Untern.-Umlaufvermögen');
+INSERT INTO gifi (accno,description) VALUES ('0134400', 'Anteil an herr.m.betei.Gesellschaft');
+INSERT INTO gifi (accno,description) VALUES ('0134500', 'Eigene Anteile');
+INSERT INTO gifi (accno,description) VALUES ('0134800', 'Sonstige Wertpapiere');
+INSERT INTO gifi (accno,description) VALUES ('0136000', 'Geldtransit');
+INSERT INTO gifi (accno,description) VALUES ('0136100', 'Geldtransit (Überweisungen)');
+INSERT INTO gifi (accno,description) VALUES ('0136200', 'Geldtransit,Bankeinzug/Lastschrift');
+INSERT INTO gifi (accno,description) VALUES ('0136300', 'Scheck / Wechsel');
+INSERT INTO gifi (accno,description) VALUES ('0140000', 'Ford. a.Lieferungen und Leistungen');
+INSERT INTO gifi (accno,description) VALUES ('0141100', 'Forderungssammelkonto Vorausre.');
+INSERT INTO gifi (accno,description) VALUES ('0141200', 'Forderungssammelkonto Anzahlungen');
+INSERT INTO gifi (accno,description) VALUES ('0146000', 'Zweifelhafte Forderungen');
+INSERT INTO gifi (accno,description) VALUES ('0147000', 'Forder.a.Liefe.u.Leis.geg.verb.Unte');
+INSERT INTO gifi (accno,description) VALUES ('0147800', 'Wertb.a.Ford.m.Rest.1j.geg.verb.Unt');
+INSERT INTO gifi (accno,description) VALUES ('0148000', 'Lief.u.Leis.geg.Untern.m.Beteiligve');
+INSERT INTO gifi (accno,description) VALUES ('0148800', 'Wertb.a.Ford.m.Rest.1j.Beteiligungs');
+INSERT INTO gifi (accno,description) VALUES ('0149000', 'Forderung a.Leis.u.Lief.geg.Gesells');
+INSERT INTO gifi (accno,description) VALUES ('0150000', 'Sonstige Vermögensgegenstände');
+INSERT INTO gifi (accno,description) VALUES ('0150300', 'Forde.geg.Vorstandsm.u.Geschäftsfüh');
+INSERT INTO gifi (accno,description) VALUES ('0150800', 'Forderungen gegen Gesellschafter');
+INSERT INTO gifi (accno,description) VALUES ('0151000', 'Geleistete Anzahlung auf Vorräte');
+INSERT INTO gifi (accno,description) VALUES ('0151100', 'Geleistete Anzahlungen 7%');
+INSERT INTO gifi (accno,description) VALUES ('0151700', 'Geleistete Anzahlung 16%');
+INSERT INTO gifi (accno,description) VALUES ('0152500', 'Kautionen');
+INSERT INTO gifi (accno,description) VALUES ('0153000', 'Forderungen gegen Personal');
+INSERT INTO gifi (accno,description) VALUES ('0154000', 'Steuerüberzahlungen');
+INSERT INTO gifi (accno,description) VALUES ('0154500', 'Umsatzsteuerforderungen');
+INSERT INTO gifi (accno,description) VALUES ('0154800', 'Vorsteuer im Folgejahr abziehbar');
+INSERT INTO gifi (accno,description) VALUES ('0154900', 'Körperschaftsteuerrückforderung');
+INSERT INTO gifi (accno,description) VALUES ('0155000', 'Darlehen');
+INSERT INTO gifi (accno,description) VALUES ('0156000', 'Aufzuteilende Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0156500', 'Aufzuteilende Vorsteuer 16%');
+INSERT INTO gifi (accno,description) VALUES ('0157000', 'Abziehbare Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0157100', 'Abziebare Vorsteuer 7%');
+INSERT INTO gifi (accno,description) VALUES ('0157200', 'Abziehb. VorSt innergemein. Erwerb');
+INSERT INTO gifi (accno,description) VALUES ('0157300', 'Abziehb.VorSt. innergem.Erwerb 16%');
+INSERT INTO gifi (accno,description) VALUES ('0157500', 'Abziehbare Vorsteuer 16%');
+INSERT INTO gifi (accno,description) VALUES ('0157800', 'Berichtigung d.Vorstabzugs früh.J.');
+INSERT INTO gifi (accno,description) VALUES ('0157900', 'Vorsteuer 0%');
+INSERT INTO gifi (accno,description) VALUES ('0158400', 'abziehb.VorSt IG Erwerb Neufahrzeug');
+INSERT INTO gifi (accno,description) VALUES ('0158800', 'Bezahlte Einfuhrumsatzsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0159000', 'Durchlaufende Posten');
+INSERT INTO gifi (accno,description) VALUES ('0159400', 'Forderungen geg. verb. Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('0159700', 'Ford.geg.Untern.m.Beteiligungsverh.');
+INSERT INTO gifi (accno,description) VALUES ('0160000', 'Verbindlichkeiten aus Lief.u.Leist.');
+INSERT INTO gifi (accno,description) VALUES ('0160100', 'Verbindlichkeiten a.Lief.und Leist.');
+INSERT INTO gifi (accno,description) VALUES ('0163000', 'Verbindl.Lief.u.Leist.gegü.verb.Unt');
+INSERT INTO gifi (accno,description) VALUES ('0164000', 'Verb.L.u.L gegü.Unter.Beteiligungsv');
+INSERT INTO gifi (accno,description) VALUES ('0165000', 'Verb.L.u.L gegü.Gesellschaftern');
+INSERT INTO gifi (accno,description) VALUES ('0166000', 'Schuldwechsel');
+INSERT INTO gifi (accno,description) VALUES ('0170000', 'Sonstige Verbindlichkeiten');
+INSERT INTO gifi (accno,description) VALUES ('0170500', 'Darlehen');
+INSERT INTO gifi (accno,description) VALUES ('0170900', 'Gewinnverfügungskonto stiller Ges.');
+INSERT INTO gifi (accno,description) VALUES ('0171000', 'Erhaltene Anzahlungen-Verbindlichke');
+INSERT INTO gifi (accno,description) VALUES ('0171100', 'Erhaltene,versteuert Anzahlungen 7%');
+INSERT INTO gifi (accno,description) VALUES ('0171700', 'Erhaltene,versteuerte Anzahl. 16%');
+INSERT INTO gifi (accno,description) VALUES ('0171900', 'Erhaltene Anzahlungen bis 1j.');
+INSERT INTO gifi (accno,description) VALUES ('0172200', 'Erhaltene Anzahlung');
+INSERT INTO gifi (accno,description) VALUES ('0172300', 'Verbindlichkeiten S-konto Vorausre.');
+INSERT INTO gifi (accno,description) VALUES ('0173200', 'Erhaltene Kautionen');
+INSERT INTO gifi (accno,description) VALUES ('0174100', 'Verbindl.a.Lohn-und Kirchensteuer');
+INSERT INTO gifi (accno,description) VALUES ('0175500', 'Lohn-und Gehaltsverrechnung');
+INSERT INTO gifi (accno,description) VALUES ('0175800', 'USt-Abzugsverfahren 16%');
+INSERT INTO gifi (accno,description) VALUES ('0175900', 'Ust 0%');
+INSERT INTO gifi (accno,description) VALUES ('0176000', 'Umsatzsteuer nicht fällig');
+INSERT INTO gifi (accno,description) VALUES ('0176100', 'Umsatzsteuer nicht fällig 7%');
+INSERT INTO gifi (accno,description) VALUES ('0176200', 'Umsatzsteuer nicht fällig EG Lief.');
+INSERT INTO gifi (accno,description) VALUES ('0177000', 'Umsatzsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0177100', 'Umsatzsteuer 7%');
+INSERT INTO gifi (accno,description) VALUES ('0177200', 'Umsatzsteuer aus innergem. Erwerb');
+INSERT INTO gifi (accno,description) VALUES ('0177300', 'Umsatzsteuer innergem.Erwerb 16%');
+INSERT INTO gifi (accno,description) VALUES ('0177500', 'Umsatzsteuer 16%');
+INSERT INTO gifi (accno,description) VALUES ('0177700', 'Ust aus im Inland stpfl. EG-Lief16%');
+INSERT INTO gifi (accno,description) VALUES ('0178000', 'Umsatzsteuer-Vorauszahlungen');
+INSERT INTO gifi (accno,description) VALUES ('0178100', 'Umsatzsteuer-Vorauszahlung 1/11');
+INSERT INTO gifi (accno,description) VALUES ('0178300', 'In Rechn unberecht.ausgew.gesch Ust');
+INSERT INTO gifi (accno,description) VALUES ('0178400', 'Ust IG Erwerb Neufahrzeug o.Ust ID');
+INSERT INTO gifi (accno,description) VALUES ('0178800', 'Einfuhrumsatzsteuer augeschoben bis');
+INSERT INTO gifi (accno,description) VALUES ('0178900', 'Umsatzsteuer laufendes Jahr');
+INSERT INTO gifi (accno,description) VALUES ('0179000', 'Umsatzsteuer Vorjahr');
+INSERT INTO gifi (accno,description) VALUES ('0179100', 'Umsatzsteuer frühere Jahre');
+INSERT INTO gifi (accno,description) VALUES ('0179200', 'Sonstige Verrechnungskonten');
+INSERT INTO gifi (accno,description) VALUES ('0180000', 'Privatentnahme allgemein');
+INSERT INTO gifi (accno,description) VALUES ('0181000', 'Privatsteuern');
+INSERT INTO gifi (accno,description) VALUES ('0189000', 'Privateinlagen');
+INSERT INTO gifi (accno,description) VALUES ('0200000', 'Außerordentliche Aufwendung');
+INSERT INTO gifi (accno,description) VALUES ('0201000', 'Betriebsfremde Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('0202000', 'Periodenfremde Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('0210000', 'Zinsen und ähnl.Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('0210300', 'Steuerl.abzugsfähig,and.Nebenl.Steu');
+INSERT INTO gifi (accno,description) VALUES ('0210400', 'Steuerl.nicht.abzugsf.ande.Nl.z.Ste');
+INSERT INTO gifi (accno,description) VALUES ('0210700', 'Zinsaufwendung-betriebliche Steuern');
+INSERT INTO gifi (accno,description) VALUES ('0210800', 'Zinsaufwendung-Personsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0210900', 'Zinsaufwendungen an verb.Unternehm.');
+INSERT INTO gifi (accno,description) VALUES ('0211000', 'Zinsaufwendung f.kurzf.Verbindlichk');
+INSERT INTO gifi (accno,description) VALUES ('0212000', 'Zinsaufwendung f.langf.Verbindlichk');
+INSERT INTO gifi (accno,description) VALUES ('0213000', 'Diskontaufwendung');
+INSERT INTO gifi (accno,description) VALUES ('0215000', 'Aufwendungen aus Kursdifferenzen');
+INSERT INTO gifi (accno,description) VALUES ('0216500', 'Aufw.a.d.Währungsumstell.a.d.Euro');
+INSERT INTO gifi (accno,description) VALUES ('0217000', 'Nicht abziehbare Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0217100', 'Nicht abziehbare Vorsteuer 7%');
+INSERT INTO gifi (accno,description) VALUES ('0217500', 'Nicht abziehbare Vorsteuer 16%');
+INSERT INTO gifi (accno,description) VALUES ('0220000', 'Körperschaftssteuer');
+INSERT INTO gifi (accno,description) VALUES ('0220300', 'Körperschaftssteuer für Vorjahr');
+INSERT INTO gifi (accno,description) VALUES ('0220500', 'Anrechb.Körperschaftsst.vereinn.Kap');
+INSERT INTO gifi (accno,description) VALUES ('0220800', 'Solidaritätszuschlag');
+INSERT INTO gifi (accno,description) VALUES ('0220900', 'Solidaritätszuschlag für Vorjahr');
+INSERT INTO gifi (accno,description) VALUES ('0221000', 'Kapitalertragssteuer');
+INSERT INTO gifi (accno,description) VALUES ('0221300', 'Anrechb.Solidaritätszusch.a.Zinsabs');
+INSERT INTO gifi (accno,description) VALUES ('0221500', 'Zinsabschlagsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0221800', 'Anrechb.Solidari.zuschlag a.Zinsabs');
+INSERT INTO gifi (accno,description) VALUES ('0228000', 'Stnachzahl.Vorj.v.Einkomm u.Ertrag');
+INSERT INTO gifi (accno,description) VALUES ('0228200', 'Sterstat.Vorj.Steuer v.Eink.u.Ertra');
+INSERT INTO gifi (accno,description) VALUES ('0228400', 'Ertr.a.d.Aufl.v.Rücks.f.St.v.Ein.Er');
+INSERT INTO gifi (accno,description) VALUES ('0228500', 'Steuernachzahlung Vorj.f.sons.Steue');
+INSERT INTO gifi (accno,description) VALUES ('0228700', 'Steuererstattung Vorj.f.sons.Steuer');
+INSERT INTO gifi (accno,description) VALUES ('0228900', 'Erträge a.d.Aufl.v. Rück.f.sons.Ste');
+INSERT INTO gifi (accno,description) VALUES ('0230000', 'Sonstige Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('0231000', 'Anlagenabgänge - bei Buchverlust');
+INSERT INTO gifi (accno,description) VALUES ('0231500', 'Anlagenabgänge-Buchgewinn');
+INSERT INTO gifi (accno,description) VALUES ('0232000', 'Verluste Abgang Gegenst.d.Anlagever');
+INSERT INTO gifi (accno,description) VALUES ('0232500', 'Verlust a.d.Abg.v.Gegens.d.Umlaufve');
+INSERT INTO gifi (accno,description) VALUES ('0234000', 'Einstellungen Sopo m.Rückanlageant.');
+INSERT INTO gifi (accno,description) VALUES ('0234500', 'Einstellungen Sopo m.R.(Sonderafa)');
+INSERT INTO gifi (accno,description) VALUES ('0237500', 'Grundsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0240000', 'Forderungsverlust-übliche Höhe');
+INSERT INTO gifi (accno,description) VALUES ('0241000', 'Einstellungen Sopo m.Rückl.(§7g )');
+INSERT INTO gifi (accno,description) VALUES ('0243000', 'Forderungsverluste-unüblich  hoch');
+INSERT INTO gifi (accno,description) VALUES ('0245000', 'Einstell.i.d.Pauschalwertbe.z.Forde');
+INSERT INTO gifi (accno,description) VALUES ('0245100', 'Einstell.i.d.Einzelwertb.z.Forderun');
+INSERT INTO gifi (accno,description) VALUES ('0249000', 'Aufwendung aus Verlustübernahme');
+INSERT INTO gifi (accno,description) VALUES ('0249200', 'Abgef.Gewinn aufgr.e.Gewinngemeinsc');
+INSERT INTO gifi (accno,description) VALUES ('0249300', 'Abgef.Gewinnant.an stille Gesellsch');
+INSERT INTO gifi (accno,description) VALUES ('0249500', 'Einst.Kapitalrückl.n.Vorschr.vere.K');
+INSERT INTO gifi (accno,description) VALUES ('0249600', 'Einstellungen in die gesetzl.Rückla');
+INSERT INTO gifi (accno,description) VALUES ('0250000', 'Außerordentliche Erträge');
+INSERT INTO gifi (accno,description) VALUES ('0251000', 'Betriebsfremde Erträge n.außerorden');
+INSERT INTO gifi (accno,description) VALUES ('0252000', 'Periodenfremde Erträge nicht außero');
+INSERT INTO gifi (accno,description) VALUES ('0260000', 'Erträge aus Beteiligten');
+INSERT INTO gifi (accno,description) VALUES ('0261700', 'Gewinn a.Anteila.nicht stbef.Kapita');
+INSERT INTO gifi (accno,description) VALUES ('0261900', 'Erträge a.Beteil.a.verb.Untérnehmer');
+INSERT INTO gifi (accno,description) VALUES ('0262000', 'Erträge a.anderen Wertp u.Ausl.Fina');
+INSERT INTO gifi (accno,description) VALUES ('0265000', 'Sonstige Zinsen und ähnliche Erträg');
+INSERT INTO gifi (accno,description) VALUES ('0265700', 'Zinserträge-betriebliche Steuern');
+INSERT INTO gifi (accno,description) VALUES ('0265800', 'Zinserträge-Körperschaftssteuer');
+INSERT INTO gifi (accno,description) VALUES ('0265900', 'Sons.Zinsen u.ähl.Ertr.a.verb.Unter');
+INSERT INTO gifi (accno,description) VALUES ('0266000', 'Erträge aus Kursdifferenzen');
+INSERT INTO gifi (accno,description) VALUES ('0266500', 'Erträge a.d.Währungumst.a.d. Euro');
+INSERT INTO gifi (accno,description) VALUES ('0267000', 'Diskonerträge');
+INSERT INTO gifi (accno,description) VALUES ('0270000', 'Sonstige Erträge');
+INSERT INTO gifi (accno,description) VALUES ('0270500', 'Sons.Erträge betrieb. u. regelmäßig');
+INSERT INTO gifi (accno,description) VALUES ('0271000', 'Ertrag a.d.Zuschreib.d.Anlagevermög');
+INSERT INTO gifi (accno,description) VALUES ('0271500', 'Ertr.a.Zuschreib.d.Umlaufvermögens');
+INSERT INTO gifi (accno,description) VALUES ('0272000', 'Ertr.a.d.Abgang v.Gegens.d.Anlageve');
+INSERT INTO gifi (accno,description) VALUES ('0272500', 'Ertä.a.d.Abg.v.Gegenst.d.Umlaufverm');
+INSERT INTO gifi (accno,description) VALUES ('0273000', 'Ertr.a.Herab.d.Pauschal.z.Forderung');
+INSERT INTO gifi (accno,description) VALUES ('0273100', 'Ertr.a.Herab.d.Einzelw.z.Forderunge');
+INSERT INTO gifi (accno,description) VALUES ('0273200', 'Ertr. aus abgeschriebenen Forderung');
+INSERT INTO gifi (accno,description) VALUES ('0273500', 'Ertr.a.d.Auflösung v.Rückstellungen');
+INSERT INTO gifi (accno,description) VALUES ('0273600', 'Ertr.a.d.steuerl.niedrig.Bewertung');
+INSERT INTO gifi (accno,description) VALUES ('0273700', 'Ertr.a.d..Aufl.v.Sonderp.m.Rücklage');
+INSERT INTO gifi (accno,description) VALUES ('0273800', 'Ertr.a.d.Aufl.v.Sopo.m.Rücklageant.');
+INSERT INTO gifi (accno,description) VALUES ('0273900', 'Erträge Aufl. Sopo m.R.(Ansparafa)');
+INSERT INTO gifi (accno,description) VALUES ('0274000', 'Erträge Auflösung Sopo (stfreie Rü)');
+INSERT INTO gifi (accno,description) VALUES ('0274100', 'Ertr.a.d.Aufl.v.Sonderp.m.Rücklagen');
+INSERT INTO gifi (accno,description) VALUES ('0274200', 'Versicherungsentschädigungen');
+INSERT INTO gifi (accno,description) VALUES ('0274300', 'Investitionszuschüsse-steuerpflicht');
+INSERT INTO gifi (accno,description) VALUES ('0274400', 'Investitionszulage-steuerfrei');
+INSERT INTO gifi (accno,description) VALUES ('0274500', 'Erträge aus Kapitalherabsetzung');
+INSERT INTO gifi (accno,description) VALUES ('0279000', 'Erträge aus Verlustübernahme');
+INSERT INTO gifi (accno,description) VALUES ('0279200', 'Erhalt.Gewinne aufgr.e.Gewinngemein');
+INSERT INTO gifi (accno,description) VALUES ('0279400', 'Erhalt.Gewinn aufgr.e.GAV-TeilGAV');
+INSERT INTO gifi (accno,description) VALUES ('0279500', 'Entnahme aus der Kapitalrücklage');
+INSERT INTO gifi (accno,description) VALUES ('0279600', 'Entnahme a.d. gesetzlichen Rücklage');
+INSERT INTO gifi (accno,description) VALUES ('0286000', 'Gewinnvortrag nach Verwendung');
+INSERT INTO gifi (accno,description) VALUES ('0286800', 'Verlustvortrag nach Verwendung');
+INSERT INTO gifi (accno,description) VALUES ('0286900', 'Vortrag auf neue Rechnungen');
+INSERT INTO gifi (accno,description) VALUES ('0287000', 'Vorabausschüttung');
+INSERT INTO gifi (accno,description) VALUES ('0289200', 'Verrechnete kalkulatorische Zinsen');
+INSERT INTO gifi (accno,description) VALUES ('0289300', 'Verrechnete kalkulatorische AfA');
+INSERT INTO gifi (accno,description) VALUES ('0299000', 'Aufwendung/Erträge Umrechnungsdiff');
+INSERT INTO gifi (accno,description) VALUES ('0300000', 'Roh,-Hilfs,-und Betriebsstoffe');
+INSERT INTO gifi (accno,description) VALUES ('0309000', 'Energiestoffe (Fertigung)');
+INSERT INTO gifi (accno,description) VALUES ('0310000', 'Fremdleistungen');
+INSERT INTO gifi (accno,description) VALUES ('0315000', 'Leist.v.ausländ.Untern.(0-Regelung)');
+INSERT INTO gifi (accno,description) VALUES ('0320000', 'Wareneingang');
+INSERT INTO gifi (accno,description) VALUES ('0330000', 'Wareneingang 7% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0340000', 'Wareneingang 16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0342000', 'Innergemein.Erwerb 7% VorSt u. Ust');
+INSERT INTO gifi (accno,description) VALUES ('0342500', 'Innergem.Erwerb 16% VorSt u. Ust');
+INSERT INTO gifi (accno,description) VALUES ('0355000', 'Steuerfreier innergem.Erwerb');
+INSERT INTO gifi (accno,description) VALUES ('0360000', 'Nicht abziehbare Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0370000', 'Nachlässe');
+INSERT INTO gifi (accno,description) VALUES ('0371000', 'Nachlässe 7% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0372000', 'Nachlässe 16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0373000', 'Erhaltene Skonti');
+INSERT INTO gifi (accno,description) VALUES ('0373100', 'Erhaltene Skonti 7% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0373500', 'Erhaltene Skonti 16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0374000', 'Erhaltene Boni');
+INSERT INTO gifi (accno,description) VALUES ('0375000', 'Erhaltene Boni 7% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0376000', 'Erhaltene Boni 16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0377000', 'Erhaltene Rabatte');
+INSERT INTO gifi (accno,description) VALUES ('0378000', 'Erhaltene Rabatte 7% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0379000', 'Erhaltene Rabatte 16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0380000', 'Anschaffungsnebenkosten');
+INSERT INTO gifi (accno,description) VALUES ('0383000', 'Leergut');
+INSERT INTO gifi (accno,description) VALUES ('0385000', 'Zölle und Einfuhrabgaben');
+INSERT INTO gifi (accno,description) VALUES ('0396000', 'Bestandsver.Roh-,Hilfs-.Betriebs.');
+INSERT INTO gifi (accno,description) VALUES ('0397000', 'Bestand Roh-,Hilfs-,u.Betriebsstoff');
+INSERT INTO gifi (accno,description) VALUES ('0398000', 'Bestand Waren');
+INSERT INTO gifi (accno,description) VALUES ('0399000', 'Verrechnete Stoffkosten');
+INSERT INTO gifi (accno,description) VALUES ('0400000', 'Material-und Stoffverbrauch');
+INSERT INTO gifi (accno,description) VALUES ('0410000', 'Löhne und Gehälter');
+INSERT INTO gifi (accno,description) VALUES ('0412400', 'Geschäftsführ.gehälter GmbH-Gesell.');
+INSERT INTO gifi (accno,description) VALUES ('0412500', 'Ehegattengehalt');
+INSERT INTO gifi (accno,description) VALUES ('0412600', 'Tantiemen');
+INSERT INTO gifi (accno,description) VALUES ('0412700', 'Geschäftsführergehälter');
+INSERT INTO gifi (accno,description) VALUES ('0412800', 'Vergütung a.angestellte Mitunterneh');
+INSERT INTO gifi (accno,description) VALUES ('0413000', 'Gesetzlich soziale Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('0413700', 'Gesetz.sozi.Aufw.f.Mitunternehmen');
+INSERT INTO gifi (accno,description) VALUES ('0413800', 'Beiträge zur Berufsgenossenschaftr');
+INSERT INTO gifi (accno,description) VALUES ('0414500', 'Freiwillige sozi.Aufw.lohnsteuerfr.');
+INSERT INTO gifi (accno,description) VALUES ('0414900', 'Pauschale Lohnsteuera.sons.Bezüge');
+INSERT INTO gifi (accno,description) VALUES ('0415000', 'Krankengeldzuschüsse');
+INSERT INTO gifi (accno,description) VALUES ('0416000', 'Versorgungskasse');
+INSERT INTO gifi (accno,description) VALUES ('0416500', 'Aufwendung f.Altersversorgung');
+INSERT INTO gifi (accno,description) VALUES ('0417000', 'Vermögenswirksame Leistungen');
+INSERT INTO gifi (accno,description) VALUES ('0417500', 'Fahrtkostenerst.Wohnung/Arbeitsstät');
+INSERT INTO gifi (accno,description) VALUES ('0419000', 'Aushilfslöhne');
+INSERT INTO gifi (accno,description) VALUES ('0419900', 'Lohnsteuer für Aushilfe');
+INSERT INTO gifi (accno,description) VALUES ('0420000', 'Raumkosten');
+INSERT INTO gifi (accno,description) VALUES ('0421000', 'Miete');
+INSERT INTO gifi (accno,description) VALUES ('0422000', 'Pacht');
+INSERT INTO gifi (accno,description) VALUES ('0423000', 'Heizung');
+INSERT INTO gifi (accno,description) VALUES ('0424000', 'Gas,Strom, Wasser');
+INSERT INTO gifi (accno,description) VALUES ('0425000', 'Reinigung');
+INSERT INTO gifi (accno,description) VALUES ('0426000', 'Instandhaltung betrieb.Räume');
+INSERT INTO gifi (accno,description) VALUES ('0427000', 'Abgaben f.betrieb.genutz.Grundstück');
+INSERT INTO gifi (accno,description) VALUES ('0428000', 'Sonstige Raumkosten');
+INSERT INTO gifi (accno,description) VALUES ('0430000', 'Nicht abziehbare Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('0430100', 'Nicht abziehbare Vorsteuer 7%');
+INSERT INTO gifi (accno,description) VALUES ('0430500', 'Nicht abziehbare Vorsteuer 16%');
+INSERT INTO gifi (accno,description) VALUES ('0432000', 'Gewerbesteuer');
+INSERT INTO gifi (accno,description) VALUES ('0434000', 'Sonstige Betriebssteuern');
+INSERT INTO gifi (accno,description) VALUES ('0435000', 'Verbrauchssteuer');
+INSERT INTO gifi (accno,description) VALUES ('0435500', 'Ökosteuer');
+INSERT INTO gifi (accno,description) VALUES ('0436000', 'Versicherungen');
+INSERT INTO gifi (accno,description) VALUES ('0437000', 'Nettoprä.f.Rückd.künf.Versorgungsle');
+INSERT INTO gifi (accno,description) VALUES ('0438000', 'Beiträge');
+INSERT INTO gifi (accno,description) VALUES ('0439000', 'Sonstige Abgaben');
+INSERT INTO gifi (accno,description) VALUES ('0439600', 'Steuerl.abzugs.Verspä.u.Zwangsgelde');
+INSERT INTO gifi (accno,description) VALUES ('0450000', 'Fahrzugkosten');
+INSERT INTO gifi (accno,description) VALUES ('0451000', 'Kfz-Steuer');
+INSERT INTO gifi (accno,description) VALUES ('0452000', 'Kfz-Versicherungen');
+INSERT INTO gifi (accno,description) VALUES ('0453000', 'Laufende Kfz-Betriebskosten');
+INSERT INTO gifi (accno,description) VALUES ('0454000', 'Kfz-Reparaturen');
+INSERT INTO gifi (accno,description) VALUES ('0455000', 'Garagenmiete');
+INSERT INTO gifi (accno,description) VALUES ('0457000', 'Fremdfahrzeuge');
+INSERT INTO gifi (accno,description) VALUES ('0458000', 'Sonstige Kfz-Kosten');
+INSERT INTO gifi (accno,description) VALUES ('0460000', 'Werbe-und Reisekosten');
+INSERT INTO gifi (accno,description) VALUES ('0461000', 'Werbekosten');
+INSERT INTO gifi (accno,description) VALUES ('0463000', 'Geschenke bis 75 DM');
+INSERT INTO gifi (accno,description) VALUES ('0463500', 'Geschenke bis 75 DM');
+INSERT INTO gifi (accno,description) VALUES ('0463800', 'Geschenke ausschließl.betrieb.genut');
+INSERT INTO gifi (accno,description) VALUES ('0464000', 'Repräsentationskosten');
+INSERT INTO gifi (accno,description) VALUES ('0465000', 'Bewirtungskosten');
+INSERT INTO gifi (accno,description) VALUES ('0465300', 'Aufmerksamkeiten');
+INSERT INTO gifi (accno,description) VALUES ('0465400', 'Nicht abzugsfähige Bewirtungskosten');
+INSERT INTO gifi (accno,description) VALUES ('0465500', 'Nicht abzugsfähige Betriebsausgaben');
+INSERT INTO gifi (accno,description) VALUES ('0466000', 'Reisekosten Arbeitnehmer');
+INSERT INTO gifi (accno,description) VALUES ('0466300', 'Reisekosten Arbeitn.m.Vorsteuerabzu');
+INSERT INTO gifi (accno,description) VALUES ('0466400', 'Reisekosten Arbeitn.Verpflegungmehr');
+INSERT INTO gifi (accno,description) VALUES ('0466600', 'Reisekosten Arbeitn.Übernachtungsau');
+INSERT INTO gifi (accno,description) VALUES ('0466800', 'Kilometerentgelderstattung Arbeitne');
+INSERT INTO gifi (accno,description) VALUES ('0467000', 'Reisekosten Unternehmer');
+INSERT INTO gifi (accno,description) VALUES ('0467400', 'Reisekosten Untern.Verpflegungsmehr');
+INSERT INTO gifi (accno,description) VALUES ('0467600', 'Reisekosten Untern.Übernachtungsauf');
+INSERT INTO gifi (accno,description) VALUES ('0467800', 'Kilometererstattungsgeld Unternehme');
+INSERT INTO gifi (accno,description) VALUES ('0470000', 'Kosten der Warenabgabe');
+INSERT INTO gifi (accno,description) VALUES ('0471000', 'Verpackungsmaterial');
+INSERT INTO gifi (accno,description) VALUES ('0473000', 'Ausgangsfracht');
+INSERT INTO gifi (accno,description) VALUES ('0475000', 'Transportversicherung');
+INSERT INTO gifi (accno,description) VALUES ('0476000', 'Verkaufsprovision');
+INSERT INTO gifi (accno,description) VALUES ('0478000', 'Fremdarbeiten');
+INSERT INTO gifi (accno,description) VALUES ('0479000', 'Aufwand für Gewährleistungen');
+INSERT INTO gifi (accno,description) VALUES ('0480900', 'Sonstige Reparaturen u.Instandhalt.');
+INSERT INTO gifi (accno,description) VALUES ('0481000', 'Mietleasing');
+INSERT INTO gifi (accno,description) VALUES ('0481500', 'Kaufleasing');
+INSERT INTO gifi (accno,description) VALUES ('0482000', 'AfA a.Aufw.f.d.Inga.u.Erw.Geschäfts');
+INSERT INTO gifi (accno,description) VALUES ('0482100', 'AfA a.Aufw.f.d.Währungsumst.a.Euro');
+INSERT INTO gifi (accno,description) VALUES ('0482200', 'Abschreibungen a.immat.Vermögensgeg');
+INSERT INTO gifi (accno,description) VALUES ('0482400', 'Abschreibung a.d.Geschäft-o.Firmenw');
+INSERT INTO gifi (accno,description) VALUES ('0482600', 'Außerplan.AfA a.immat.Vermögensgeg.');
+INSERT INTO gifi (accno,description) VALUES ('0483000', 'Abschreibungen auf Sachanlagen');
+INSERT INTO gifi (accno,description) VALUES ('0484000', 'Außerplanmäßig Abschr.a.Sachanlagen');
+INSERT INTO gifi (accno,description) VALUES ('0485000', 'Abschr.a.Sachanl.steuerl.Sondervors');
+INSERT INTO gifi (accno,description) VALUES ('0485500', 'Sofortabschreibung GWG');
+INSERT INTO gifi (accno,description) VALUES ('0486000', 'Abschreibungen auf aktivierte GWG');
+INSERT INTO gifi (accno,description) VALUES ('0487000', 'Abschreibungen auf Finanzanlagen');
+INSERT INTO gifi (accno,description) VALUES ('0487500', 'Abschr.a.Wertp.d.Umlaufvermögens');
+INSERT INTO gifi (accno,description) VALUES ('0490000', 'Sonstige betriebliche Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('0490500', 'Sons.Aufw.betriebl. und regelmäßig');
+INSERT INTO gifi (accno,description) VALUES ('0490900', 'Fremdleistungen');
+INSERT INTO gifi (accno,description) VALUES ('0491000', 'Porto');
+INSERT INTO gifi (accno,description) VALUES ('0492000', 'Telefon');
+INSERT INTO gifi (accno,description) VALUES ('0492500', 'Telefax');
+INSERT INTO gifi (accno,description) VALUES ('0493000', 'Bürobedarf');
+INSERT INTO gifi (accno,description) VALUES ('0494000', 'Zeitschriften, Bücher');
+INSERT INTO gifi (accno,description) VALUES ('0494500', 'Fortbildungskosten');
+INSERT INTO gifi (accno,description) VALUES ('0494600', 'Freiwillige Sozialleistungen');
+INSERT INTO gifi (accno,description) VALUES ('0495000', 'Rechts- und Beratungskosten');
+INSERT INTO gifi (accno,description) VALUES ('0495500', 'Buchführungskosten');
+INSERT INTO gifi (accno,description) VALUES ('0495700', 'Abschluß- und Prüfungskosten');
+INSERT INTO gifi (accno,description) VALUES ('0496000', 'Mieten für Einrichtungen');
+INSERT INTO gifi (accno,description) VALUES ('0497000', 'Nebenkosten des Geldverkehrs');
+INSERT INTO gifi (accno,description) VALUES ('0498000', 'Betriebsbedarf');
+INSERT INTO gifi (accno,description) VALUES ('0498500', 'Werkzeuge und Kleingeräte');
+INSERT INTO gifi (accno,description) VALUES ('0498600', 'Sonstige Aufwendungen (Ausbuchung)');
+INSERT INTO gifi (accno,description) VALUES ('0499000', 'Kalkulatorischer Unternehmerlohn');
+INSERT INTO gifi (accno,description) VALUES ('0499200', 'Kalkulatorische Zinsen');
+INSERT INTO gifi (accno,description) VALUES ('0499300', 'Kalkulatorische Aschreibungen');
+INSERT INTO gifi (accno,description) VALUES ('0499600', 'Herstellungskosten');
+INSERT INTO gifi (accno,description) VALUES ('0499700', 'Verwaltungskosten');
+INSERT INTO gifi (accno,description) VALUES ('0499800', 'Vertriebskosten');
+INSERT INTO gifi (accno,description) VALUES ('0700000', 'Unfertige Erzeu.unfert.Leistungen');
+INSERT INTO gifi (accno,description) VALUES ('0705000', 'Unfertige Erzeugnisse');
+INSERT INTO gifi (accno,description) VALUES ('0708000', 'Unfertige Leistungen');
+INSERT INTO gifi (accno,description) VALUES ('0709000', 'In Ausführung befindl. Bauaufträge');
+INSERT INTO gifi (accno,description) VALUES ('0709500', 'In Arbeit befindliche Aufträge');
+INSERT INTO gifi (accno,description) VALUES ('0710000', 'Fertige Erzeugnisse und Waren');
+INSERT INTO gifi (accno,description) VALUES ('0711000', 'Fertige Erzeugnisse (Bestand)');
+INSERT INTO gifi (accno,description) VALUES ('0714000', 'Waren (Bestand)');
+INSERT INTO gifi (accno,description) VALUES ('0810000', 'Steuerfreie Umsätze §4Nr.8ff UstG');
+INSERT INTO gifi (accno,description) VALUES ('0811000', 'Sonstige steuerfreie Umsätze Inland');
+INSERT INTO gifi (accno,description) VALUES ('0812000', 'Steuerfreie Umsätze §4Nr.1a UstG');
+INSERT INTO gifi (accno,description) VALUES ('0812500', 'Steuerfrei innergem. Lieferungen');
+INSERT INTO gifi (accno,description) VALUES ('0813000', 'Liefe.d.1.Abnehm.innergem.Dreiecksg');
+INSERT INTO gifi (accno,description) VALUES ('0815000', 'Sonstige steuerfreie Umsätze');
+INSERT INTO gifi (accno,description) VALUES ('0819000', 'Sonstige Erlöse (Ausbuchung 0%)');
+INSERT INTO gifi (accno,description) VALUES ('0819100', 'Sonstige Erlöse (Ausbuchung 16%)');
+INSERT INTO gifi (accno,description) VALUES ('0819200', 'Sonstige Erlöse (Ausbuchung 7%)');
+INSERT INTO gifi (accno,description) VALUES ('0820000', 'Erlöse');
+INSERT INTO gifi (accno,description) VALUES ('0830000', 'Erlöse 7%USt');
+INSERT INTO gifi (accno,description) VALUES ('0831000', 'Erlöse Inland stpfl. EG-Lieferung7%');
+INSERT INTO gifi (accno,description) VALUES ('0831500', 'Erlös Inland stpfl.EG-Lieferung 16%');
+INSERT INTO gifi (accno,description) VALUES ('0833900', 'Erl.EG-Land stpfl.so.Leist.(0-Regl)');
+INSERT INTO gifi (accno,description) VALUES ('0840000', 'Erlöse 16% USt.');
+INSERT INTO gifi (accno,description) VALUES ('0850000', 'Provisionserlöse');
+INSERT INTO gifi (accno,description) VALUES ('0852000', 'Erlöse Abfallverwertung');
+INSERT INTO gifi (accno,description) VALUES ('0854000', 'Erlös Leergut');
+INSERT INTO gifi (accno,description) VALUES ('0859000', 'Verrechnete sons. Sachbezüge');
+INSERT INTO gifi (accno,description) VALUES ('0859100', 'Sachbezüge 7% Ust (Waren)');
+INSERT INTO gifi (accno,description) VALUES ('0859500', 'Sachbezüge 16% Ust (Waren)');
+INSERT INTO gifi (accno,description) VALUES ('0860000', 'Sonstige Erlöse betriebl.u.regelmäß');
+INSERT INTO gifi (accno,description) VALUES ('0861000', 'Verrechnete sonstige Sachbezüge');
+INSERT INTO gifi (accno,description) VALUES ('0861100', 'Verr.sons.Sachbezüge 16%USt(Kfz-Ge)');
+INSERT INTO gifi (accno,description) VALUES ('0861400', 'Verrechnete sons.Sachbezüge o. USt');
+INSERT INTO gifi (accno,description) VALUES ('0862500', 'Sons. Erlöse betriebl.u.reg.steuerf');
+INSERT INTO gifi (accno,description) VALUES ('0865000', 'Erlöse Zinsen und Diskotspesen');
+INSERT INTO gifi (accno,description) VALUES ('0870000', 'Erlösschmälerungen');
+INSERT INTO gifi (accno,description) VALUES ('0871000', 'Erlösschmälerung 7% USt.');
+INSERT INTO gifi (accno,description) VALUES ('0872000', 'Erlösschmälerung 16% USt.');
+INSERT INTO gifi (accno,description) VALUES ('0872400', 'Erlösschmäler.a.stfrei.IG Lieferung');
+INSERT INTO gifi (accno,description) VALUES ('0872500', 'Erlösschmä.Inl.stpfl.EG-Lief. 7%USt');
+INSERT INTO gifi (accno,description) VALUES ('0872600', 'Erlösschmä.Inl.stpfl.EG-Lief.16%USt');
+INSERT INTO gifi (accno,description) VALUES ('0872700', 'Erlösschmä.and.EG Land stpfl.Liefer');
+INSERT INTO gifi (accno,description) VALUES ('0873000', 'Gewährte Skonti');
+INSERT INTO gifi (accno,description) VALUES ('0873100', 'Gewährte Skonti 7% USt');
+INSERT INTO gifi (accno,description) VALUES ('0873500', 'Gewährte Skonti 16% USt.');
+INSERT INTO gifi (accno,description) VALUES ('0874000', 'Gewährte Boni');
+INSERT INTO gifi (accno,description) VALUES ('0875000', 'Gewährte Boni 7% USt.');
+INSERT INTO gifi (accno,description) VALUES ('0876000', 'Gewährte Boni 16% USt.');
+INSERT INTO gifi (accno,description) VALUES ('0877000', 'Gewährte Rabatte');
+INSERT INTO gifi (accno,description) VALUES ('0878000', 'Gewährte Rabatte 7% USt.');
+INSERT INTO gifi (accno,description) VALUES ('0879000', 'Gewährte Rabatte 16% Ust.');
+INSERT INTO gifi (accno,description) VALUES ('0880000', 'Erlöse aus Anlagenverkäufen');
+INSERT INTO gifi (accno,description) VALUES ('0880100', 'Erlöse aus Anlagenverkäufen 16%USt.');
+INSERT INTO gifi (accno,description) VALUES ('0882000', 'Erlöse aus Anlageverkäufen 16%Ust');
+INSERT INTO gifi (accno,description) VALUES ('0882900', 'Erl.a.Anlagenverk.bei Buchgewinn');
+INSERT INTO gifi (accno,description) VALUES ('0890000', 'Unentgeldliche Wertabgaben');
+INSERT INTO gifi (accno,description) VALUES ('0890500', 'Entnahme v. Gegenst.o.USt.');
+INSERT INTO gifi (accno,description) VALUES ('0891000', 'Entnahme außerhalb d.Untern.16%USt.');
+INSERT INTO gifi (accno,description) VALUES ('0891500', 'Entnah.d.U.Zweckaußerh.d.Untn 7%USt');
+INSERT INTO gifi (accno,description) VALUES ('0891800', 'Entn.d.Untern.außerh.d.Untern.o.USt');
+INSERT INTO gifi (accno,description) VALUES ('0892000', 'Verw.v.Gegens.außerh.Untern.16%USt.');
+INSERT INTO gifi (accno,description) VALUES ('0892500', 'Unentgeldl.Erbring.sons.Leis.16%USt');
+INSERT INTO gifi (accno,description) VALUES ('0893200', 'Unentgelt.Erbring.sons.Leist. 7%Ust');
+INSERT INTO gifi (accno,description) VALUES ('0893500', 'Unentgeltl.Zuwend.v.Gegens. 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('0893900', 'Unentgeldl.Zuw.v.Gegens.ohne Ust');
+INSERT INTO gifi (accno,description) VALUES ('0894000', 'Unentgeltl.Zuw.v Waren 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('0894500', 'Unentgeltl.Zuw.von Waren 7% Ust');
+INSERT INTO gifi (accno,description) VALUES ('0895000', 'Nicht steuerbare Umsätze');
+INSERT INTO gifi (accno,description) VALUES ('0895500', 'Umsatzsteuervergütungen');
+INSERT INTO gifi (accno,description) VALUES ('0896000', 'Bestandsveränderung-unfertige Erzeu');
+INSERT INTO gifi (accno,description) VALUES ('0897000', 'Bestandsveränderung-unfertige Leist');
+INSERT INTO gifi (accno,description) VALUES ('0897500', 'Bestandsverä.i.Ausfü.befi.Bauaufträ');
+INSERT INTO gifi (accno,description) VALUES ('0897700', 'Bestandsverä.i.Arbeit befindl.Auftr');
+INSERT INTO gifi (accno,description) VALUES ('0898000', 'Bestandsverä.fertige Erzeugnisse');
+INSERT INTO gifi (accno,description) VALUES ('0899000', 'Andere aktivierte Eigenleistungen');
+INSERT INTO gifi (accno,description) VALUES ('0900000', 'Saldenverträge,Sachkonten');
+INSERT INTO gifi (accno,description) VALUES ('0900800', 'Saldenverträge,Debitoren');
+INSERT INTO gifi (accno,description) VALUES ('0900900', 'Saldenverträge,Kreditoren');
+INSERT INTO gifi (accno,description) VALUES ('0906000', 'Offene Posten aus 1990');
+INSERT INTO gifi (accno,description) VALUES ('0906900', 'Offene Posten aus 1999');
+INSERT INTO gifi (accno,description) VALUES ('0907000', 'Offene Posten aus 2000');
+INSERT INTO gifi (accno,description) VALUES ('0909000', 'Summenvortragskonto');
+INSERT INTO gifi (accno,description) VALUES ('0922000', 'Gezeichnetes kapital in DM');
+INSERT INTO gifi (accno,description) VALUES ('0922100', 'Gezeichnetes Kapital in Euro');
+INSERT INTO gifi (accno,description) VALUES ('0923000', 'Baukostenzuschüsse');
+INSERT INTO gifi (accno,description) VALUES ('0923200', 'Investitionszulagen');
+INSERT INTO gifi (accno,description) VALUES ('0923400', 'Investitionszuschüsse');
+INSERT INTO gifi (accno,description) VALUES ('0924500', 'Forde.a.Anlageverk.sons.Vermögensge');
+INSERT INTO gifi (accno,description) VALUES ('0925000', 'Eigenkapitalersetzende Ges''terdarl.');
+INSERT INTO gifi (accno,description) VALUES ('0926000', 'Kurzfristige Rückstellung');
+INSERT INTO gifi (accno,description) VALUES ('0926200', 'Mittelfristige Rückstellung');
+INSERT INTO gifi (accno,description) VALUES ('0926400', 'Langfristige Rückstellungen');
+INSERT INTO gifi (accno,description) VALUES ('0928000', 'Bemessungsgrundlage IG Erwerb 16%');
+INSERT INTO gifi (accno,description) VALUES ('0928100', 'Gegenkonto Bmsgrl. IG Erwerb 16%');
+INSERT INTO gifi (accno,description) VALUES ('0928200', 'Bemessungsgrundlage IG Erwerb 7%');
+INSERT INTO gifi (accno,description) VALUES ('0928400', 'Gegenkonto Bmsgrl. IG Erwerb 7%');
+INSERT INTO gifi (accno,description) VALUES ('0988100', 'Verrechnungskonto Abgang');
+INSERT INTO gifi (accno,description) VALUES ('0988200', 'Verrechnungskonto erh. Anzahlungen');
+INSERT INTO gifi (accno,description) VALUES ('0988210', 'Verrechnungskto Anzahlungen netto');
+INSERT INTO gifi (accno,description) VALUES ('0988220', 'Verrechnungskto.Anzahlungen brutto');
+INSERT INTO gifi (accno,description) VALUES ('0988300', 'Verrechnungskonto gel.Anzahlungen');
+INSERT INTO gifi (accno,description) VALUES ('0988400', 'Statistisches Konto Konzern AfA');
+INSERT INTO gifi (accno,description) VALUES ('0988500', 'Statistisches Konto kalkulator.AfA');
+INSERT INTO gifi (accno,description) VALUES ('0988600', 'Statistisches Konto außerplanm AfA');
+INSERT INTO gifi (accno,description) VALUES ('0988700', 'Statistisches Konto AfA (Konzern)');
+INSERT INTO gifi (accno,description) VALUES ('0988800', 'Statistisches Konto Sonderafa');
+INSERT INTO gifi (accno,description) VALUES ('0988900', 'Statistisches Konto AfA (SBil)');
+INSERT INTO gifi (accno,description) VALUES ('0989800', 'Statistisches Konto AfA (Kalkul.)');
+INSERT INTO gifi (accno,description) VALUES ('0989900', 'Statistisches Konto AfA');
+INSERT INTO gifi (accno,description) VALUES ('0999999', 'Fehlerauffangkonto');
diff --git a/sql-ledger/sql/Germany-SKR03-chart.sql b/sql-ledger/sql/Germany-SKR03-chart.sql
new file mode 100644 (file)
index 0000000..a7f87e2
--- /dev/null
@@ -0,0 +1,267 @@
+-- General COA
+-- provided by Yvonne
+-- June 13, 2002
+--
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('420','Büroeinrichtung','A','A','','420');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('430','Ladeneinrichtung','A','A','','430');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('440','Werkzeuge','A','A','','440');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('450','Einbauten','A','A','','450');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('460','Gerüst- und Schalungsmaterial','A','A','','460');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('480','Geringwertige Wirtschaftsgüter bis DM 800,-','A','A','','480');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('490','Sonstige Betriebs- und Geschäftsausstattung','A','A','','490');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('650','Verb. gg. Kreditinstituten - Restlaufz. größer 5 Jahre','A','L','','650');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1000','Kasse','A','A','AR_paid:AP_paid','1000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1200','Bank-Giro','A','A','AR_paid:AP_paid','1200');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1400','Forderungen aus Lief. und Leist. Kundengruppe 0','A','A','AR','1400');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1540','Steuerüberzahlungen','A','A','AR','1540');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1542','Steuererstattungsansprüche gg. anderen EU-Ländern','A','A','AR','1542');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1545','Umsatzsteuerforderungen','A','A','AR','1545');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1548','Vorsteuer im Folgejahr abziehbar','A','A','AR','1548');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1570','Abziehbare Vorsteuer','A','A','AR_tax:AP_tax:CT_tax','1570');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1571','Abziehbare Vorsteuer, 7%','A','A','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax','1571');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1575','Abziehbare Vorsteuer, 16%','A','A','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax','1575');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1576','Abziehbare Vorsteuer, 15%','A','A','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax','1576');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1577','Vorsteuer nach allg. Durchschnittssätzen UStVA KZ 63','A','A','AR_tax:AP_tax:CT_tax','1577');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1775','Umsatzsteuer, 16%','A','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax','1775');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1776','Umsatzsteuer, 15%','A','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax','1776');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1780','Umsatzsteuer - Vorauszahlungen','A','L','','1780');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1781','Umsatzsteuer - Vorauszahlungen 1/11','A','L','','1781');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1782','Nachsteuer, UStVA KZ 65','A','L','','1782');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1789','Umsatzsteuer laufendes Jahr','A','L','','1789');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1790','Umsatzsteuer Vorjahr','A','L','','1790');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1791','Umsatzsteuer frühere Jahre','A','L','','1791');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1820','Sonderausg. beschr. abzugsf. (Privat Vollhaft./Einzelu.)','A','','','1820');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1830','Sonderausg. unbeschr. abzugsf. (Privat Vollhaft./Einzelu.)','A','','','1830');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1840','Privatspenden (Privat Vollhafter / Einzelunternehmer)','A','','','1840');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1850','Außergewöhnliche Belastungen (Privat Vollhaft. / Einzelunt.)','A','','','1850');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1890','Privateinlagen (Privat Vollhafter / Einzelunternehmer)','A','','','1890');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('2010','Betriebsfremde Aufw. (soweit nicht außerordentlich)','A','','','2010');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('2020','Periodenfremde Aufw. (soweit nicht außerordentlich)','A','','','2020');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('2100','Zinsen und ähnliche Aufwendungen','A','','','2100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('2103','Steuerlich abzugsfähige, andere Nebenleistungen zu Steuern','A','','','2103');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('2104','Steuerlich nicht abzugsfähige, andere Nebenleistungen zu Steuern','A','','','2104');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('2107','Zinsaufwendungen §233a AO betriebliche Steuern','A','','','2107');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('2108','Zinsaufw. §233a, §234, §237 AO Personenst. §8 GewStG','A','','','2108');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('2109','Zinsaufwendungen an verbundene Unternehmen','A','','','2109');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('2110','Zinsaufwendungen für kurzfristige Verbindlichkeiten','A','','','2110');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3410','Wareneingang, 16% Vorsteuer','A','','','3410');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3736','Erhaltene Skonti, 16% Vorsteuer','A','','','3736');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3740','Erhaltene Boni','A','','','3740');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3750','Erhaltene Boni,   7% Vorsteuer','A','','','3750');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3760','Erhaltene Boni, 15%+16% Vorsteuer','A','','','3760');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3762','Erhaltene Boni, 16% Vorsteuer','A','','','3762');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3764','Erhaltene Boni, 15% Vorsteuer','A','','','3764');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3800','Anschaffungsnebenkosten','A','','','3800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3830','Leergut','A','','','3830');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3850','Zölle und Einfuhrabgaben','A','','','3850');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3960','Bestandsv. Roh-, Hilfs- u. Betriebsstoffe / bezogene Waren','A','','','3960');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3970','Bestand Roh-, Hilfs- und Betriebsstoffe','A','','','3970');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3980','Bestand Waren','A','','','3980');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3990','Verrechnete Stoffkosten','A','','','3990');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4000','Material- und Stoffverbrauch','A','E','AP_amount','4000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4100','Löhne und Gehälter','A','E','AP_amount','4100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4110','Löhne','A','E','AP_amount','4110');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4120','Gehälter','A','E','AP_amount','4120');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4124','Geschäftsführergehälter der GmbH-Gesellschafter','A','E','AP_amount','4124');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4125','Ehegattengehalt','A','E','AP_amount','4125');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4126','Tantiemen','A','E','AP_amount','4126');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4127','Geschäftsführergehälter','A','E','AP_amount','4127');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4128','Vergütungen an angestellte Mitunternehmer §15 EStG','A','E','AP_amount','4128');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4130','Gesetzliche soziale Aufwendungen','A','E','AP_amount','4130');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4137','Gesetzliche soziale Aufw. für Mitunternehmer §15 EStG','A','E','AP_amount','4137');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4138','Beiträge zur Berufsgenossenschaft','A','E','AP_amount','4138');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1360','Geldtransit Bank 1','A','A','','1360');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4140','Freiw. soziale Aufwendungen (lohnsteuerfrei)','A','E','AP_amount','4140');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4145','Freiw. soziale Aufwendungen (lohnsteuerpflichtig)','A','E','AP_amount','4145');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4149','Pauschale Lohnsteuer auf s. Bezüge (z.B. Fahrtkostenzuschuß)','A','E','AP_amount','4149');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4150','Krankengeldzuschüsse','A','E','AP_amount','4150');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4160','Versorgungskassen','A','E','AP_amount','4160');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4165','Aufwendungen für die Altersversorgung','A','E','AP_amount','4165');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4167','Pauschale Lohnsteuer auf s. Bezüge (z.B. Direktversicherung)','A','E','AP_amount','4167');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4168','Aufw. f. die Altersversorgung f. Mitunternehmer §15 EStG','A','E','AP_amount','4168');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4169','Aufwendungen für Unterstützung','A','E','AP_amount','4169');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4170','Vermögenswirksame Leistungen','A','E','AP_amount','4170');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4175','Fahrtkostenerstattung - Wohnung / Arbeitsstätte','A','E','AP_amount','4175');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4180','Bedienungsgelder','A','E','AP_amount','4180');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4190','Aushilfslöhne','A','E','AP_amount','4190');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4199','Lohnsteuer für Aushilfen','A','E','AP_amount','4199');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4200','Raumkosten','A','E','AP_amount','4200');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4210','Miete','A','E','AP_amount','4210');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4218','Gewerbesteuerlich zu berücks. Miete §8 GewStG','A','E','AP_amount','4218');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4219','Vergütung an Mitu. f. mietw. Überl. v. Wirtschaftsg. §15EStG','A','E','AP_amount','4219');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4220','Pacht','A','E','AP_amount','4220');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4228','Gewerbesteuerlich zu berücks. Pacht §8 GewStG','A','E','AP_amount','4228');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4229','Vergütung an Mitu. f. pachtw. Überl. v. Wirtschaftsg.§15EStG','A','E','AP_amount','4229');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4230','Heizung','A','E','AP_amount','4230');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4240','Gas, Strom, Wasser (Verwaltung, Vertrieb)','A','E','AP_amount','4240');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4250','Reinigung','A','E','AP_amount','4250');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4260','Instandhaltung betrieblicher Räume','A','E','AP_amount','4260');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4270','Abgaben für betrieblich genutzten Grundbesitz','A','E','AP_amount','4270');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4280','Sonstige Raumkosten','A','E','AP_amount','4280');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4320','Gewerbesteuer (Vorauszahlung)','A','E','AP_amount','4320');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4330','Gewerbeertragsteuer','A','E','AP_amount','4330');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4335','Gewerbekapitalsteuer','A','E','AP_amount','4335');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4340','Sonstige Betriebsteuern','A','E','AP_amount','4340');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4350','Verbrauchsteuer','A','E','AP_amount','4350');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4360','Versicherungen','A','E','AP_amount','4360');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4380','Beiträge','A','E','AP_amount','4380');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4390','Sonstige Abgaben','A','E','AP_amount','4390');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4396','Steuerlich abzugsfähige Verspätungszuschläge und Zwangsgelder','A','E','AP_amount','4396');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4397','Steuerlich nicht abzugsfähige Verspätungszuschläge und Zwangsgelder','A','E','AP_amount','4397');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4400','Besondere Kosten (zur freien Verfügung)','A','E','AP_amount','4400');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4500','Fahrzeugkosten','A','E','AP_amount','4500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4510','Kfz-Steuern','A','E','AP_amount','4510');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4520','Kfz-Versicherungen','A','E','AP_amount','4520');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4530','Laufende Kfz-Betriebskosten','A','E','AP_amount','4530');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4540','Kfz-Reparaturen','A','E','AP_amount','4540');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4550','Garagenmieten','A','E','AP_amount','4550');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4570','Fremdfahrzeuge','A','E','AP_amount','4570');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4580','Sonstige Kfz-Kosten','A','E','AP_amount','4580');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4600','Werbe- und Reisekosten','A','E','AP_amount','4600');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4610','Werbekosten','A','E','AP_amount','4610');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4630','Geschenke bis DM 75,00','A','E','AP_amount','4630');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4635','Geschenke über DM 75,00','A','E','AP_amount','4635');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4638','Geschenke ausschließlich betrieblich genutzt','A','E','AP_amount','4638');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4640','Repräsentationskosten','A','E','AP_amount','4640');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4650','Bewirtungskosten','A','E','AP_amount','4650');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4653','Aufwerksamkeiten','A','E','AP_amount','4653');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4654','Nicht abzugsfähige Bewirtungskosten','A','E','AP_amount','4654');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4655','Nicht abzugsfähige Betriebsausgaben','A','E','AP_amount','4655');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4660','Reisekosten Arbeitnehmer','A','E','AP_amount','4660');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4666','Reisekost. Arbeitn., 12,3%/13,1% VSt  Verpfl.Mehr- / Übern.Aufw.','A','E','AP_amount','4666');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4667','Reisekost. Arbeitn., 9,8%/10,5% VSt Gesamtpauschal.','A','E','AP_amount','4667');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4670','Reisekosten Unternehmer','A','E','AP_amount','4670');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4675','Reisekosten Unternehmer, 9,8/10,5% VSt sonst.Gesamtpauschal.','A','E','AP_amount','4675');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4676','Reisekost. Untern., 12,3%/13,1% VSt Verpfl.Mehr- / Übern.Aufw.','A','E','AP_amount','4676');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4677','Reisekosten Unternehmer, 9,8%/10,5% VSt Verpfl.Mehraufw. Gesamtpauschal.','A','E','AP_amount','4677');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4678','Km-Geld Erstattung, Unternehmer, 5,7%/6,1% VSt','A','E','AP_amount','4678');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4685','Km-Geld-Erstattung, Arbeitnehmer  8,2%/8,7% VSt','A','E','AP_amount','4685');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4700','Kosten der Warenabgabe','A','E','AP_amount:IC_expense:IC_cogs','4700');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4710','Verpackungsmaterial','A','E','AP_amount','4710');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4730','Ausgangsfrachten','A','E','AP_amount','4730');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4750','Transportversicherungen','A','E','AP_amount','4750');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4760','Verkaufsprovisionen','A','E','AP_amount','4760');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4780','Fremdarbeiten','A','E','AP_amount','4780');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4790','Aufwand für Gewährleistungen','A','E','AP_amount','4790');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4800','Reparat. u. Inst. v. Maschinen u. technischen Anlagen','A','E','AP_amount','4800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4805','Reparat. u. Inst. v. and. Anl. d. Betr.- u. Geschäftsausst.','A','E','AP_amount','4805');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4809','Sonstige Reparaturen und Instandhaltungen','A','E','AP_amount','4809');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4810','Mietleasing','A','E','AP_amount','4810');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4815','Kaufleasing','A','E','AP_amount','4815');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4820','Abschr. a. Aufw. f.d. Ingangs. u. Erw. des Geschäftsbetr.','A','E','AP_amount','4820');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4822','Abschr. a. immaterielle Vermögensgegenstände','A','E','AP_amount','4822');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4824','Abschreibung auf den Geschäfts- oder Firmenwert','A','E','AP_amount','4824');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4826','Außerplanm. Abschr. a. immaterielle Vermögensgegenstände','A','E','AP_amount','4826');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4830','Abschreibungen auf Sachanlagen','A','E','AP_amount','4830');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4840','Außerplanm. Abschreibungen auf Sachanlagen','A','E','AP_amount','4840');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4850','Abschr. a. Sachanl. aufgrund steuerl. Sondervorschriften','A','E','AP_amount','4850');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4855','Sofortabschreibung geringwertiger Wirtschaftsgüter','A','E','AP_amount','4855');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4860','Abschreibung auf aktivierte, geringwertige Wirtschaftsgüter','A','E','AP_amount','4860');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4865','Außerplanmäßige Abschr. a. aktivierte GWG','A','E','AP_amount','4865');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4870','Abschreibungen auf Finanzanlagen','A','E','AP_amount','4870');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4872','Abschr. aufgrund v. Verlustant. an Mitunt. §8 GewStG','A','E','AP_amount','4872');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4874','Abschr. a. Finanzanl. aufgrund steuerl. Sondervorschriften','A','E','AP_amount','4874');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4875','Abschreibungen auf Wertpapiere des Umlaufvermögens','A','E','AP_amount','4875');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4880','Abschr. a. Umlaufv. ohne Wertpapiere (soweit unübl. Höhe)','A','E','AP_amount','4880');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4882','Abschr. a. Umlaufv. steuerrechtl. bedingt (unübl. Höhe)','A','E','AP_amount','4882');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4887','Abschr. a. Umlaufv., steuerrechtlich bedingt (übl. Höhe)','A','E','AP_amount','4887');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4890','Vorwegn. künftiger Wertschw. im Umlaufv. (unübl. Höhe)','A','E','AP_amount','4890');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4900','Sonstige betriebliche Aufwendungen','A','E','AP_amount','4900');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4905','Sonstige Aufwendungen betrieblich und regelmäßig','A','E','AP_amount','4905');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4910','Porto','A','E','AP_amount','4910');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4920','Telefon','A','E','AP_amount','4920');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4925','Telefax, Fernschreiber','A','E','AP_amount','4925');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4930','Bürobedarf','A','E','AP_amount','4930');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4940','Zeitschriften, Bücher','A','E','AP_amount','4940');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4945','Fortbildungskosten','A','E','AP_amount','4945');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4946','Freiwillige Sozialleistungen','A','E','AP_amount','4946');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4948','Vergütungen an freiberufliche Mitunternehmer §15 EStG','A','E','AP_amount','4948');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4950','Rechts- und Beratungskosten','A','E','AP_amount','4950');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4955','Buchführungskosten','A','E','AP_amount','4955');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4957','Abschluß- und Prüfungskosten','A','E','AP_amount','4957');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4960','Mieten für Einrichtungen','A','E','AP_amount','4960');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4968','Gewerbest. zu berücks. Miete f. Einrichtungen §8 GewStG','A','','','4968');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4969','Aufwendungen für Abraum- und Abfallbeseitigung','A','E','AP_amount','4969');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4970','Nebenkosten des Geldverkehrs','A','E','AP_amount','4970');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4980','Betriebsbedarf','A','E','AP_amount','4980');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4985','Werkzeuge und Kleingeräte','A','E','AP_amount','4985');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4996','Herstellungskosten','A','E','AP_amount','4996');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4997','Verwaltungskosten','A','E','AP_amount','4997');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4998','Vertriebskosten','A','E','AP_amount','4998');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('4999','Gegenkonto 49960-49980','A','','','4999');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('7140','Fertige Waren (Bestand)','A','A','IC','7140');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8100','Steuerfreie Umsätze o. VSt-Abzug §4 Nr.8 ff. UStG','A','I','AR_amount:IC_sale','8100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8500','Provisionserlöse','A','I','AR_amount:IC_sale','8500');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8504','Provisionserlöse steuerfrei (§4 Nr.8ff UStG)','A','I','AR_amount:IC_sale','8504');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8505','Provisionserlöse steuerfrei (§4 Nr.5 UStG)','A','I','AR_amount:IC_sale','8505');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8506','Provisionserlöse,  7% USt','A','I','AR_amount:IC_sale','8506');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8507','Provisionserlöse, 15% Ust','A','I','AR_amount:IC_sale','8507');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8508','Provisionserlöse, 15%/16% USt','A','I','AR_amount:IC_sale','8508');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8509','Provisionserlöse, 16% Ust','A','I','AR_amount:IC_sale','8509');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8591','Sachbezüge,   7% USt (Waren)','A','I','AR_amount:IC_sale','8591');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8595','Sachbezüge, 15%/16% USt (Waren)','A','I','AR_amount:IC_sale','8595');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8596','Sachbezüge, 16% USt (Waren)','A','I','AR_amount:IC_sale','8596');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8597','Sachbezüge, 15% USt (Waren)','A','I','AR_amount:IC_sale','8597');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8630','Sonstige Erlöse betrieblich und regelmäßig, 7% USt','A','I','AR_amount:IC_sale','8630');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8645','Sonstige Erlöse betrieblich und regelmäßig, 16% Ust','A','I','AR_amount:IC_sale','8645');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8730','Gewährte Skonti','A','','','8730');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8731','Gewährte Skonti,  7% USt','A','','','8731');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8735','Gewährte Skonti, 16% Ust','A','','','8735');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8740','Gewährte Boni','A','','','8740');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8750','Gewährte Boni,  7% USt','A','','','8750');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8762','Gewährte Boni, 16% Ust','A','','','8762');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8770','Gewährte Rabatte','A','','','8770');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8780','Gewährte Rabatte,  7% USt','A','','','8780');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8792','Gewährte Rabatte, 16% Ust','A','','','8792');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8800','Erlöse aus Anlagenverkäufen','A','','','8800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8801','Erlöse aus Anlagenverkäufen 15%/16% USt (bei Buchverlust)','A','','','8801');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8810','Erlöse aus Anlagenverkäufen 16% USt (bei Buchverlust)','A','','','8810');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8815','Erlöse aus Anlagenverkäufen 15% USt (bei Buchverlust)','A','','','8815');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8820','Erlöse aus Anlagenverkäufen 15%/16% USt (bei Buchgewinn)','A','','','8820');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8829','Erlöse aus Anlagenverkäufen (bei Buchgewinn)','A','','','8829');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8830','Erlöse aus Anlagenverkäufen 16% USt (bei Buchgewinn)','A','','','8830');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8835','Erlöse aus Anlagenverkäufen 15% USt (bei Buchgewinn)','A','','','8835');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8900','Eigenverbrauch','A','','','8900');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8905','Entnahme Gegenstände ohne USt','A','','','8905');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8908','Entnahme von Gegenstände, 16% USt §1 Abs.1 Nr.2a UStG','A','','','8908');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8909','Entnahme von Gegenstände, 15% USt §1 Abs.1 Nr.2a UStG','A','','','8909');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8910','Entnahme von Gegenstände, 15%/16% USt §1 Abs.1 Nr.2a UStG','A','','','8910');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8915','Entnahme von Gegenstände, 7% USt §1 Abs.1 Nr.2a UStG','A','','','8915');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8920','Entnahme v. sonst. Leist., 15%/16% USt §1 A.1 Nr.2b UStG','A','','','8920');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8930','Entnahme v. sonst. Leist., 7% USt §1 A.1 Nr.2b UStG','A','','','8930');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8937','Entnahme v. sonst. Leist., 16% USt §1 A.1 Nr.2b UStG','A','','','8937');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8938','Entnahme v. sonst. Leist., 15% USt §1 A.1 Nr.2b UStG','A','','','8938');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8939','Entnahme v. sonst. Leist., ohne USt §1 A.1 Nr.2b UStG','A','','','8939');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8941','Eigenverbr., 7% Ust §4 A.1 Nr.5 1-7, A.7 EStG','A','','','8941');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8942','Eigenverbr., 16% Ust  §4 A.1 Nr.5 1-7, A.7 EStG','A','','','8942');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8944','Eigenverbr., ohne Ust §4 A.1 Nr.5 1-7, A.7 EStG','A','','','8944');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8950','Nicht steuerbare Umsätze','A','','','8950');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8955','Umsatzsteuervergütungen','A','','','8955');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8960','Bestandsveränd. - unfertige Erzeugnisse','A','','','8960');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8970','Bestandsveränd. - unfertige Leistungen','A','','','8970');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8975','Bestandsveränd. - in Ausführung befindliche Bauaufträge','A','','','8975');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8977','Bestandsveränd. - in Arbeit befindliche Aufträge','A','','','8977');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8980','Bestandsveränd. - fertige Erzeugnisse','A','','','8980');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8990','Bestandsveränd. - andere aktivierte Eigenleistungen','A','','','8990');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('9000','Saldenvorträge Sachkonten','A','','','9000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('9008','Saldenvorträge Debitoren','A','','','9008');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('9009','Saldenvorträge Kreditoren','A','','','9009');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('9100','Saldovortragskonto der Statistikkonten','A','','','9100');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1800','Privatentn. allg. (Privat Vollhafter / Einzelunternehmer)','A','Q','','1800');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('2000','Außerordentliche Aufwendungen','A','A','','2000');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('1600','Verb. aus Lief. und Leist. Lieferantengruppe 0','A','L','AP:CT_tax','1600');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('3400','Wareneingang, 16% Vorsteuer','A','E','AP_amount:CT_tax','3400');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8400','Umsatzerlöse 16%','A','I','AR_amount:IC_sale:CT_tax','8400');
+INSERT INTO chart (accno,description,charttype,category,link,gifi_accno) VALUES ('8840','Ertrge aus Kursdifferenzen','A','I','AR_amount:IC_sale:IC_income','8840');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '1571'),0.07);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '1575'),0.16);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '1576'),0.15);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '1775'),0.16);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '1776'),0.15);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '3400'),0.16);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '8400'),0.16);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '7140'), income_accno_id = (select id from chart where accno = '8400'), expense_accno_id = (select id from chart where accno = '4700'), fxgain_accno_id = (select id from chart where accno = '8840'), fxloss_accno_id = (select id from chart where accno = '8840'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'EUR:USD', weightunit = 'kg';
+--
+
diff --git a/sql-ledger/sql/Germany-SKR03-gifi.sql b/sql-ledger/sql/Germany-SKR03-gifi.sql
new file mode 100644 (file)
index 0000000..7fc0ff6
--- /dev/null
@@ -0,0 +1,1083 @@
+-- Kontenrahmen für Deutschland
+--
+INSERT INTO gifi (accno,description) VALUES ('0001', 'Aufw. f. die Ingangsetzung u. Erweit. des Geschäftsbetr.');
+INSERT INTO gifi (accno,description) VALUES ('0002', 'Aufw. f. die Währungsumstellung auf den EURO');
+INSERT INTO gifi (accno,description) VALUES ('0010', 'Konzess., gew. Schutzr. u. ähnl. Rechte/Werte sowie Liz.');
+INSERT INTO gifi (accno,description) VALUES ('0015', 'Konzessionen');
+INSERT INTO gifi (accno,description) VALUES ('0020', 'Gewerbliche Schutzrechte');
+INSERT INTO gifi (accno,description) VALUES ('0025', 'Ähnliche Rechte und Werte');
+INSERT INTO gifi (accno,description) VALUES ('0027', 'EDV-Software');
+INSERT INTO gifi (accno,description) VALUES ('0030', 'Lizenzen an gewerbl. Schutzr. u. ähnl. Rechten u. Werten');
+INSERT INTO gifi (accno,description) VALUES ('0035', 'Geschäfts- oder Firmenwert');
+INSERT INTO gifi (accno,description) VALUES ('0038', 'Anzahlungen auf Geschäfts- oder Firmenwert');
+INSERT INTO gifi (accno,description) VALUES ('0039', 'Anzahlungen auf immaterielle Vermögensgegenstände');
+INSERT INTO gifi (accno,description) VALUES ('0040', 'Verschmelzungsmehrwert');
+INSERT INTO gifi (accno,description) VALUES ('0050', 'Grundst., gl. Rechte/Bauten einschl. Bauten a. fr. Grundst.');
+INSERT INTO gifi (accno,description) VALUES ('0060', 'Grundstücke und grundstücksgleiche Rechte ohne Bauten');
+INSERT INTO gifi (accno,description) VALUES ('0065', 'Unbebaute Grundstücke');
+INSERT INTO gifi (accno,description) VALUES ('0070', 'Grundstücksgleiche Rechte (Erbbaurecht, Dauerwohnrecht)');
+INSERT INTO gifi (accno,description) VALUES ('0075', 'Grundstücke mit Substanzverzehr');
+INSERT INTO gifi (accno,description) VALUES ('0079', 'Anzahl. a. Grundst. u. grundstücksgl. Rechte ohne Bauten');
+INSERT INTO gifi (accno,description) VALUES ('0080', 'Bauten auf eigenen Grundst. und grundstücksgl. Rechten');
+INSERT INTO gifi (accno,description) VALUES ('0085', 'Grundstückswerte eigener bebauter Grundsstücke');
+INSERT INTO gifi (accno,description) VALUES ('0090', 'Geschäftsbauten');
+INSERT INTO gifi (accno,description) VALUES ('0100', 'Fabrikbauten');
+INSERT INTO gifi (accno,description) VALUES ('0110', 'Garagen');
+INSERT INTO gifi (accno,description) VALUES ('0111', 'Außenanlagen');
+INSERT INTO gifi (accno,description) VALUES ('0112', 'Hof- u. Wegebefestigungen');
+INSERT INTO gifi (accno,description) VALUES ('0113', 'Einrichtungen für Geschäfts- u. Fabrikbauten');
+INSERT INTO gifi (accno,description) VALUES ('0115', 'Andere Bauten');
+INSERT INTO gifi (accno,description) VALUES ('0120', 'Geschäfts-, Fabrik- u. andere Bauten im Bau');
+INSERT INTO gifi (accno,description) VALUES ('0129', 'Anz. a. Geschäfts-, Fabrik-, u.a. Bauten a. eig. Grundst+Rechte');
+INSERT INTO gifi (accno,description) VALUES ('0140', 'Wohnbauten');
+INSERT INTO gifi (accno,description) VALUES ('0145', 'Garagen');
+INSERT INTO gifi (accno,description) VALUES ('0146', 'Außenanlagen');
+INSERT INTO gifi (accno,description) VALUES ('0147', 'Hof- und Wegebefestigungen');
+INSERT INTO gifi (accno,description) VALUES ('0148', 'Einrichtungen für Wohnbauten');
+INSERT INTO gifi (accno,description) VALUES ('0150', 'Wohnbauten im Bau');
+INSERT INTO gifi (accno,description) VALUES ('0159', 'Anz. auf Wohnbauten auf eig. Grundstücken u. grundst.gl. Rechten');
+INSERT INTO gifi (accno,description) VALUES ('0160', 'Bauten auf fremden Grundstücken');
+INSERT INTO gifi (accno,description) VALUES ('0165', 'Geschäftsbauten');
+INSERT INTO gifi (accno,description) VALUES ('0170', 'Fabrikbauten');
+INSERT INTO gifi (accno,description) VALUES ('0175', 'Garagen');
+INSERT INTO gifi (accno,description) VALUES ('0176', 'Außenanlagen');
+INSERT INTO gifi (accno,description) VALUES ('0177', 'Hof- und Wegebefestigen');
+INSERT INTO gifi (accno,description) VALUES ('0178', 'Einrichtungen für Geschäfts- und Fabrikbauten');
+INSERT INTO gifi (accno,description) VALUES ('0179', 'Andere Bauten');
+INSERT INTO gifi (accno,description) VALUES ('0180', 'Geschäfts-, Fabrik- und andere Bauten im Bau');
+INSERT INTO gifi (accno,description) VALUES ('0189', 'Anzahl. a. Geschäfts-, Fabrik-, u.a. Bauten a. fr. Grundst.');
+INSERT INTO gifi (accno,description) VALUES ('0190', 'Wohnbauten');
+INSERT INTO gifi (accno,description) VALUES ('0191', 'Garagen');
+INSERT INTO gifi (accno,description) VALUES ('0192', 'Außenanlagen');
+INSERT INTO gifi (accno,description) VALUES ('0193', 'Hof- und Wegebefestigungen');
+INSERT INTO gifi (accno,description) VALUES ('0194', 'Einrichtungen für Wohnbauten');
+INSERT INTO gifi (accno,description) VALUES ('0195', 'Wohnbauten im Bau');
+INSERT INTO gifi (accno,description) VALUES ('0199', 'Anzahlungen auf Wohnbauten auf fremden Grundstücken');
+INSERT INTO gifi (accno,description) VALUES ('0200', 'Technische Anlagen und Maschinen');
+INSERT INTO gifi (accno,description) VALUES ('0210', 'Maschinen');
+INSERT INTO gifi (accno,description) VALUES ('0220', 'Maschinengebundene Werkzeuge');
+INSERT INTO gifi (accno,description) VALUES ('0240', 'Maschinelle Anlagen');
+INSERT INTO gifi (accno,description) VALUES ('0260', 'Transportanlagen und ähnliches');
+INSERT INTO gifi (accno,description) VALUES ('0280', 'Betriebsvorrichtungen');
+INSERT INTO gifi (accno,description) VALUES ('0290', 'Technische Anlagen und Maschinen im Bau');
+INSERT INTO gifi (accno,description) VALUES ('0299', 'Anzahlungen auf technische Anlagen und Maschinen');
+INSERT INTO gifi (accno,description) VALUES ('0300', 'Andere  Anlagen, Betriebs- und Geschäftsausstattung');
+INSERT INTO gifi (accno,description) VALUES ('0310', 'Andere Anlagen');
+INSERT INTO gifi (accno,description) VALUES ('0320', 'Pkw');
+INSERT INTO gifi (accno,description) VALUES ('0350', 'Lkw');
+INSERT INTO gifi (accno,description) VALUES ('0380', 'Sonstige Transportmittel');
+INSERT INTO gifi (accno,description) VALUES ('0400', 'Betriebsausstattung');
+INSERT INTO gifi (accno,description) VALUES ('0410', 'Geschäftsausstattung');
+INSERT INTO gifi (accno,description) VALUES ('0420', 'Büroeinrichtung');
+INSERT INTO gifi (accno,description) VALUES ('0430', 'Ladeneinrichtung');
+INSERT INTO gifi (accno,description) VALUES ('0440', 'Werkzeuge');
+INSERT INTO gifi (accno,description) VALUES ('0450', 'Einbauten');
+INSERT INTO gifi (accno,description) VALUES ('0460', 'Gerüst- und Schalungsmaterial');
+INSERT INTO gifi (accno,description) VALUES ('0480', 'Geringwertige Wirtschaftsgüter bis DM 800,-');
+INSERT INTO gifi (accno,description) VALUES ('0490', 'Sonstige Betriebs- und Geschäftsausstattung');
+INSERT INTO gifi (accno,description) VALUES ('0498', 'Andere Anlagen, Betriebs- und Geschäftsausstatt. im Bau');
+INSERT INTO gifi (accno,description) VALUES ('0499', 'Anzahl. a. andere Anlagen, Betriebs- u. Geschäftsausstatt.');
+INSERT INTO gifi (accno,description) VALUES ('0500', 'Anteile an verbundenen Unternehmen (Anlagevermögen)');
+INSERT INTO gifi (accno,description) VALUES ('0504', 'Anteile an herrschender oder mit Mehrheit beteiligter Gesellschaft');
+INSERT INTO gifi (accno,description) VALUES ('0505', 'Ausleihungen an verbundene Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('0510', 'Beteiligungen');
+INSERT INTO gifi (accno,description) VALUES ('0513', 'Typisch stille Beteiligungen');
+INSERT INTO gifi (accno,description) VALUES ('0516', 'Atypisch stille Beteiligungen');
+INSERT INTO gifi (accno,description) VALUES ('0517', 'Andere Beteiligungen an Kapitalgesellschaften');
+INSERT INTO gifi (accno,description) VALUES ('0518', 'Andere Beteiligungen an Personengesellschaften');
+INSERT INTO gifi (accno,description) VALUES ('0519', 'Beteiligung einer GmbH&CoKG an einer Komplementär GmbH');
+INSERT INTO gifi (accno,description) VALUES ('0520', 'Ausleihung an Untern. m.d.e. Beteiligungsverhältnis besteht');
+INSERT INTO gifi (accno,description) VALUES ('0525', 'Wertpapiere des Anlagevermögens');
+INSERT INTO gifi (accno,description) VALUES ('0530', 'Wertpapiere mit Gewinnbeteiligungsansprüchen');
+INSERT INTO gifi (accno,description) VALUES ('0535', 'Festverzinsliche Wertpapiere');
+INSERT INTO gifi (accno,description) VALUES ('0540', 'Sonstige Ausleihungen');
+INSERT INTO gifi (accno,description) VALUES ('0550', 'Darlehen / Sonstige Ausleihungen');
+INSERT INTO gifi (accno,description) VALUES ('0570', 'Genossenschaftsanteile zum langfristigen Verbleib');
+INSERT INTO gifi (accno,description) VALUES ('0580', 'Ausleihungen an Gesellschafter');
+INSERT INTO gifi (accno,description) VALUES ('0590', 'Ausleihungen an nahestehende Personen');
+INSERT INTO gifi (accno,description) VALUES ('0595', 'Rückdeckungsanspr. a. Lebensvers. z. langfrist. Verbleib');
+INSERT INTO gifi (accno,description) VALUES ('0600', 'Anleihen nicht konvertibel');
+INSERT INTO gifi (accno,description) VALUES ('0601', 'Anleihen nicht konvertibel - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('0605', 'Anleihen nicht konvertibel - Restlaufzeit 1 bis 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('0610', 'Anleihen nicht konvertibel - Restlaufzeit größer 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('0615', 'Anleihen konvertibel');
+INSERT INTO gifi (accno,description) VALUES ('0616', 'Anleihen konvertibel - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('0620', 'Anleihen konvertibel - Restlaufzeit 1 bis 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('0625', 'Anleihen konvertibel - Restlaufzeit größer 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('0630', 'Verbindlichkeiten gegenüber Kreditinstituten');
+INSERT INTO gifi (accno,description) VALUES ('0631', 'Verb. gg. Kreditinstituten - Restlaufz. bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('0640', 'Verb. gg. Kreditinstituten - Restlaufz. 1 bis 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('0650', 'Verb. gg. Kreditinstituten - Restlaufz. größer 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('0660', 'Verbindlichkeiten gg. Kreditinst. aus TZ-Verträgen');
+INSERT INTO gifi (accno,description) VALUES ('0661', 'Verb. gg. Kreditinst. aus TZ-Verträgen - Restl. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('0670', 'Verb. gg. Kreditinst. aus TZ-Verträgen - Restl. 1 bis 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('0680', 'Verb. gg. Kreditinst. aus TZ-Verträgen - Restl. größer 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('0700', 'Verbindlichkeiten gg. verbundenen Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('0701', 'Verb. gg. verbundenen Unternehmen - Restlaufz. b. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('0705', 'Verb. gg. verbundenen Unternehmen - Restlaufz. 1 b. 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('0710', 'Verb. gg. verb. Untern. - Restlaufz. gr. 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('0715', 'Verb. gg. Untern. mit denen ein Beteiligungsverh. besteht');
+INSERT INTO gifi (accno,description) VALUES ('0716', 'Verb. gg. U. m.d.e. Beteiligungsv. best. - Restl. b. 1 J');
+INSERT INTO gifi (accno,description) VALUES ('0720', 'Verb. gg. U. m.d.e. Beteiligungsv. best. - Restl. 1 b. 5  J');
+INSERT INTO gifi (accno,description) VALUES ('0725', 'Verb. gg. U. m.d.e. Beteiligungsv. best. - Restl. gr. 5  J');
+INSERT INTO gifi (accno,description) VALUES ('0730', 'Verbindlichkeiten gegenüber Gesellschaftern');
+INSERT INTO gifi (accno,description) VALUES ('0731', 'Verb. gg. Gesellschaftern - Restlaufz. bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('0740', 'Verb. gg. Gesellschaftern - Restlaufz. 1 bis 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('0750', 'Verb. gg. Gesellschaftern - Restlaufz. größer 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('0755', 'Verb. gg. Gesellschaftern für offene Ausschüttungen');
+INSERT INTO gifi (accno,description) VALUES ('0760', 'Darlehen typisch stiller Gesellschafter');
+INSERT INTO gifi (accno,description) VALUES ('0761', 'Darlehen typ. stiller Gesellschafter - Restlaufz. bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('0764', 'Darlehen typ. stiller Gesellschafter - Restlaufz. 1 bis 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('0767', 'Darlehen typ. stiller Gesellschafter - Restlaufz. größer 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('0770', 'Darlehen atypisch stiller Gesellschafter');
+INSERT INTO gifi (accno,description) VALUES ('0771', 'Darlehen atyp. stiller Gesellsch.- Restlaufz. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('0774', 'Darlehen atyp. stiller Gesellsch.- Restlaufz. 1 bis 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('0777', 'Darlehen atyp. stiller Gesellsch.- Restlaufz. größer 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('0780', 'Partiarische Darlehen');
+INSERT INTO gifi (accno,description) VALUES ('0781', 'Partiarische Darlehen - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('0784', 'Partiarische Darlehen - Restlaufzeit 1 bis 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('0787', 'Partiarische Darlehen - Restlaufzeit größer 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('0800', 'Gezeichnetes Kapital');
+INSERT INTO gifi (accno,description) VALUES ('0801', 'Ausst. Einl. a.d. gez. Kapital, nicht eingef. (Aktivausw.)');
+INSERT INTO gifi (accno,description) VALUES ('0810', 'Ausst. Einl. a.d. gez. Kapital, eingeford. (Aktivausw.)');
+INSERT INTO gifi (accno,description) VALUES ('0820', 'Ausst. Einl. a.d. gez. Kapital, nicht eingef. (Passivausw.)');
+INSERT INTO gifi (accno,description) VALUES ('0830', 'Ausst. Einl. a.d. gez. Kapital, eingef. (Passivausw.)');
+INSERT INTO gifi (accno,description) VALUES ('0839', 'Eingeforderte Nachschüsse');
+INSERT INTO gifi (accno,description) VALUES ('0840', 'Kapitalrücklage');
+INSERT INTO gifi (accno,description) VALUES ('0841', 'Kapitalrückl. durch Ausgabe von Anteilen über Nennbetrag');
+INSERT INTO gifi (accno,description) VALUES ('0842', 'Kap.Rückl. Schuldver. f. Wandl.- u. Optionsr. z. Erw. v. Ant');
+INSERT INTO gifi (accno,description) VALUES ('0843', 'Kapitalrückl. d. Zuzahl. gg. Gewähr e. Vorzuges f. Anteile');
+INSERT INTO gifi (accno,description) VALUES ('0844', 'Kapitalrückl. d. andere Zuzahlungen in das Eigenkapital');
+INSERT INTO gifi (accno,description) VALUES ('0845', 'Eingefordertes Nachschußkapital');
+INSERT INTO gifi (accno,description) VALUES ('0846', 'Gesetzliche Rücklage');
+INSERT INTO gifi (accno,description) VALUES ('0847', 'Gesetzliche Rücklage 50/45% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('0848', 'Gesetzliche Rücklage 30% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('0849', 'Gesetzliche Rücklage 0% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('0850', 'Rücklage für eigene Anteile');
+INSERT INTO gifi (accno,description) VALUES ('0851', 'Satzungsmäßige Rücklagen');
+INSERT INTO gifi (accno,description) VALUES ('0852', 'Satzungsmäßige Rücklage 50/45% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('0853', 'Satzungsmäßige Rücklage 30% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('0854', 'Satzungsmäßige Rücklage 0% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('0855', 'Andere Gewinnrücklagen 50/45% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('0856', 'Eigenkapitalanteil von Wertaufholungen');
+INSERT INTO gifi (accno,description) VALUES ('0857', 'Eigenkapitalanteil von Preissteigerungsrücklagen');
+INSERT INTO gifi (accno,description) VALUES ('0858', 'Andere Gewinnrücklagen 30% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('0859', 'Andere Gewinnrücklagen 0% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('0860', 'Gewinnvortrag vor Verwendung');
+INSERT INTO gifi (accno,description) VALUES ('0862', 'Gewinnvortrag 50/45% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('0864', 'Gewinnvortrag 30% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('0866', 'Gewinnvortrag 0% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('0868', 'Verlustvortrag vor Verwendung');
+INSERT INTO gifi (accno,description) VALUES ('0869', 'Vorträge auf neue Rechnung (Bilanz)');
+INSERT INTO gifi (accno,description) VALUES ('0870', 'Festkapital (Personenges. Vollhafter / Einzelu.)');
+INSERT INTO gifi (accno,description) VALUES ('0880', 'Variables Kapital  (Personenges. Vollhaft. / Einzelu.)');
+INSERT INTO gifi (accno,description) VALUES ('0890', 'Gesellsch.-Darlehen (Personenges. Vollhaft. / Einzelu.)');
+INSERT INTO gifi (accno,description) VALUES ('0900', 'Kommandit-Kapital (Personenges. Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('0910', 'Verlustausgleichskonto (Personenges. Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('0920', 'Gesellschafter-Darlehen (Personenges. Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('0930', 'Sonderposten mit Rücklageanteil');
+INSERT INTO gifi (accno,description) VALUES ('0931', 'Sonderposten mit Rücklageanteil §6b EStG');
+INSERT INTO gifi (accno,description) VALUES ('0932', 'Sonderposten mit Rücklageanteil Abschnitt 35 EStR');
+INSERT INTO gifi (accno,description) VALUES ('0933', 'Sonderposten mit Rücklageanteil §6dEStG');
+INSERT INTO gifi (accno,description) VALUES ('0934', 'Sonderposten mit Rücklageanteil §1 EntwLStG');
+INSERT INTO gifi (accno,description) VALUES ('0935', 'Sonderposten mit Rücklageanteil §3 Ausl-InvG');
+INSERT INTO gifi (accno,description) VALUES ('0936', 'Sonderposten mit Rücklageanteil §7d EStG');
+INSERT INTO gifi (accno,description) VALUES ('0937', 'Sonderposten mit Rücklageanteil §79 EStDV');
+INSERT INTO gifi (accno,description) VALUES ('0938', 'Sonderposten mit Rücklageanteil §80 EStDV');
+INSERT INTO gifi (accno,description) VALUES ('0939', 'Sonderposten mit Rücklageanteil §81 EStDV');
+INSERT INTO gifi (accno,description) VALUES ('0940', 'Sonderposten mit Rücklageanteil §82 EStDV');
+INSERT INTO gifi (accno,description) VALUES ('0941', 'Sonderposten mit Rücklageanteil §82a EStDV');
+INSERT INTO gifi (accno,description) VALUES ('0942', 'Sonderposten mit Rücklageanteil §82d EStDV');
+INSERT INTO gifi (accno,description) VALUES ('0943', 'Sonderposten mit Rücklageanteil §82e EStDV');
+INSERT INTO gifi (accno,description) VALUES ('0944', 'Sonderposten mit Rücklageanteil §14 BerlinFG');
+INSERT INTO gifi (accno,description) VALUES ('0945', 'Sonderposten mit Rücklageanteil §3 ZonenRFG / §4-6 FördergebietsG');
+INSERT INTO gifi (accno,description) VALUES ('0946', 'Sonderposten mit Rücklageanteil §52 Abs. 5 EStG');
+INSERT INTO gifi (accno,description) VALUES ('0947', 'Sonderposten mit Rücklageanteil §7g Abs. 1 EStG');
+INSERT INTO gifi (accno,description) VALUES ('0948', 'Sonderposten mit Rücklageanteil §7g Abs. 3 EStG');
+INSERT INTO gifi (accno,description) VALUES ('0949', 'Sonderposten mit Rücklageanteil §74 EStDV');
+INSERT INTO gifi (accno,description) VALUES ('0950', 'Rückstellungen für Pensionen und ähnliche Verpflichtungen');
+INSERT INTO gifi (accno,description) VALUES ('0955', 'Steuerrückstellungen');
+INSERT INTO gifi (accno,description) VALUES ('0957', 'Gewerbesteuerrückstellung');
+INSERT INTO gifi (accno,description) VALUES ('0963', 'Körperschaftsteuerrückstellung');
+INSERT INTO gifi (accno,description) VALUES ('0969', 'Rückstellungen für latente Steuern');
+INSERT INTO gifi (accno,description) VALUES ('0970', 'Sonstige Rückstellungen');
+INSERT INTO gifi (accno,description) VALUES ('0971', 'Rückst. unterl. Aufw. Instandhalt., Nachhol. in 3 Mon');
+INSERT INTO gifi (accno,description) VALUES ('0972', 'Rückst. unterl. Aufw. Instandhalt., Nachhol. in 4-12 Mon');
+INSERT INTO gifi (accno,description) VALUES ('0973', 'Rückstellungen für Abraum- und Abfallbeseitigung');
+INSERT INTO gifi (accno,description) VALUES ('0974', 'Rückstellungen für Gewährleistungen');
+INSERT INTO gifi (accno,description) VALUES ('0976', 'Rückst. f. drohende Verluste a. schwebenden Geschäften');
+INSERT INTO gifi (accno,description) VALUES ('0977', 'Rückstellungen für Abschluß- und Prüfungskosten');
+INSERT INTO gifi (accno,description) VALUES ('0978', 'Aufwandsrückstellungen gemäß § 249 Abs. 2 HGB');
+INSERT INTO gifi (accno,description) VALUES ('0979', 'Rückstellungen für den Umweltschutz');
+INSERT INTO gifi (accno,description) VALUES ('0980', 'Aktive Rechnungsabgrenzung');
+INSERT INTO gifi (accno,description) VALUES ('0983', 'Abgrenzung aktive latente Steuern');
+INSERT INTO gifi (accno,description) VALUES ('0984', 'Als Aufwand berücks. Zölle u. Verbrauchsst. a. Vorräte');
+INSERT INTO gifi (accno,description) VALUES ('0985', 'Als Aufwand berücks. Umsatzsteuer auf Anzahlungen');
+INSERT INTO gifi (accno,description) VALUES ('0986', 'Damnum / Disagio');
+INSERT INTO gifi (accno,description) VALUES ('0990', 'Passive Rechnungsabgrenzung');
+INSERT INTO gifi (accno,description) VALUES ('0992', 'Wertber.n (zur unterjährigen Kostenverrechnung f. BWA)');
+INSERT INTO gifi (accno,description) VALUES ('0996', 'Pauschalwertberichtigung a. Ford. - Restlaufz. bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('0997', 'Pauschalwertberichtigung a. Ford. - Restlaufz. größer 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('0998', 'Einzelwertberichtigung a. Ford. - Restlaufz. bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('0999', 'Einzelwertberichtigung a. Ford. - Restlaufz. größer 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1000', 'Kasse');
+INSERT INTO gifi (accno,description) VALUES ('1010', 'Nebenkasse 1');
+INSERT INTO gifi (accno,description) VALUES ('1020', 'Nebenkasse 2');
+INSERT INTO gifi (accno,description) VALUES ('1100', 'Postgiro');
+INSERT INTO gifi (accno,description) VALUES ('1110', 'Postgiro 1');
+INSERT INTO gifi (accno,description) VALUES ('1120', 'Postgiro 2');
+INSERT INTO gifi (accno,description) VALUES ('1130', 'Postgiro 3');
+INSERT INTO gifi (accno,description) VALUES ('1190', 'LZB-Guthaben');
+INSERT INTO gifi (accno,description) VALUES ('1195', 'Bundesbankguthaben');
+INSERT INTO gifi (accno,description) VALUES ('1200', 'Bank-Giro');
+INSERT INTO gifi (accno,description) VALUES ('1210', 'Bank-Giro 1');
+INSERT INTO gifi (accno,description) VALUES ('1220', 'Bank-Giro 2');
+INSERT INTO gifi (accno,description) VALUES ('1230', 'Bank-Giro 3');
+INSERT INTO gifi (accno,description) VALUES ('1300', 'Wechsel aus Lieferungen und Leistungen');
+INSERT INTO gifi (accno,description) VALUES ('1301', 'Wechsel aus Lieferungen u. Leistungen - Restlaufz. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1302', 'Wechsel aus Lieferungen u. Leistungen - Restl. größer 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1305', 'Wechsel aus Lieferungen u. Leistungen, bundesbankfähig');
+INSERT INTO gifi (accno,description) VALUES ('1310', 'Besitzwechsel gg. verbundenen Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('1311', 'Besitzwechsel gg. verbundenen Untern. - Restl. b. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1312', 'Besitzwechsel gg. verbundenen Untern. - Restl. gr. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1315', 'Besitzwechsel gg. verb. Unternehmen, bundesbankfähig');
+INSERT INTO gifi (accno,description) VALUES ('1320', 'Besitzwechsel gg. Untern. m.d.e. Beteiligungsverh. best.');
+INSERT INTO gifi (accno,description) VALUES ('1321', 'Besitzwechsel gg. U. m.d.e. Beteilig. best. - Restl. b. 1 J');
+INSERT INTO gifi (accno,description) VALUES ('1322', 'Besitzwechsel gg. U. m.d.e. Beteilig. best. - Restl. gr. 1 J');
+INSERT INTO gifi (accno,description) VALUES ('1325', 'Besitzwechsel gg. U. m.d.e. Beteilig. best., bundsbankfähig');
+INSERT INTO gifi (accno,description) VALUES ('1327', 'Finanzwechsel');
+INSERT INTO gifi (accno,description) VALUES ('1330', 'Schecks');
+INSERT INTO gifi (accno,description) VALUES ('1340', 'Anteile an verb. Unternehmen (Umlaufvermögen)');
+INSERT INTO gifi (accno,description) VALUES ('1344', 'Anteile an herrschender oder mit Mehrheit beteiligter Gesellschaft');
+INSERT INTO gifi (accno,description) VALUES ('1345', 'Eigene Anteile');
+INSERT INTO gifi (accno,description) VALUES ('1348', 'Sonstige Wertpapiere');
+INSERT INTO gifi (accno,description) VALUES ('1350', 'GmbH-Anteile zum kurzfristigen Verbleib');
+INSERT INTO gifi (accno,description) VALUES ('1352', 'Genossenschaftsanteile zum kurzfristigen Verbleib');
+INSERT INTO gifi (accno,description) VALUES ('1355', 'Ansprüche aus Rückdeckungsversicherungen');
+INSERT INTO gifi (accno,description) VALUES ('1360', 'Geldtransit Bank');
+INSERT INTO gifi (accno,description) VALUES ('1361', 'Geldtransit Bank 1');
+INSERT INTO gifi (accno,description) VALUES ('1362', 'Geldtransit Bank 2');
+INSERT INTO gifi (accno,description) VALUES ('1363', 'Geldtransit Bank 3');
+INSERT INTO gifi (accno,description) VALUES ('1369', 'Interne Umbuchung');
+INSERT INTO gifi (accno,description) VALUES ('1370', 'Verrechnungskonto Gewinnermittlung §4/3 EStG, ergebniswirksam');
+INSERT INTO gifi (accno,description) VALUES ('1371', 'Verrechnungskonto für Gewinnermittl. §4/3EStG, nicht ergebniswirksam');
+INSERT INTO gifi (accno,description) VALUES ('1380', 'Überleitungskonto Kostenstelle');
+INSERT INTO gifi (accno,description) VALUES ('1390', 'Verrechnungskonto Ist-Versteuerung');
+INSERT INTO gifi (accno,description) VALUES ('1400', 'Forderungen aus Lief. und Leist. Kundengruppe 0');
+INSERT INTO gifi (accno,description) VALUES ('1401', 'Forderungen aus Lief. und Leist. Kundengruppe 1');
+INSERT INTO gifi (accno,description) VALUES ('1402', 'Forderungen aus Lief. und Leist. Kundengruppe 2');
+INSERT INTO gifi (accno,description) VALUES ('1410', 'Forderungen aus Lief. und Leist. ohne Kontokorrent');
+INSERT INTO gifi (accno,description) VALUES ('1450', 'Forderungen nach §11, Abs.1 Satz 2 EStG für § 4/3 EStG');
+INSERT INTO gifi (accno,description) VALUES ('1451', 'Ford.a.Lief.u.Leist. ohne Kontokorrent - Restlaufz. b. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1455', 'Ford.a.Lief.u.Leist. ohne Kontokorrent - Restlaufz. gr.1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1460', 'Zweifelhafte Forderungen');
+INSERT INTO gifi (accno,description) VALUES ('1461', 'Zweifelhafte Forderungen - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1465', 'Zweifelhafte Forderungen - Restlaufzeit größer 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1470', 'Ford.a.Lief.u.Leist. gg. verbundenen Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('1471', 'Ford.a.Lief.u.Leist. gg. verb. Untern. - Restl. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1475', 'Ford.a.Lief.u.Leist. gg. verb. Untern. - Restl. größer 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1478', 'Wertber. a. Ford.a.L.u.L. gg. verb. U. - Restl. b. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1479', 'Wertber. a. Ford.a.L.u.L. gg. verb. U. - Restl. gr. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1480', 'Ford.a.L.u.L. gg. Untern. m.d.e. Beteiligungsverh. best.');
+INSERT INTO gifi (accno,description) VALUES ('1481', 'Ford.a.L.u.L. gg. U. m.d.e. Beteilig. best. - Restl. b. 1 J');
+INSERT INTO gifi (accno,description) VALUES ('1485', 'Ford.a.L.u.L. gg. U. m.d.e. Beteilig. best. - Restl. gr. 1 J');
+INSERT INTO gifi (accno,description) VALUES ('1488', 'Wertber. a. Ford. Restl. b. 1 J. gg. U. m.d.e. Beteilig.');
+INSERT INTO gifi (accno,description) VALUES ('1489', 'Wertber. a. Ford. Restl. gr. 1 J. gg. U. m.d.e. Beteilig.');
+INSERT INTO gifi (accno,description) VALUES ('1490', 'Ford.a.Lief.u.Leist. gegen Gesellschafter');
+INSERT INTO gifi (accno,description) VALUES ('1491', 'Ford.a.Lief.u.Leist. gg. Gesellsch.- Restlaufz. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1495', 'Ford.a.Lief.u.Leist. gg. Gesellsch.- Restlaufz. größer 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1499', 'Gegenkonto 14510-14980 bei Aufteilung Debitoren');
+INSERT INTO gifi (accno,description) VALUES ('1500', 'Sonstige Vermögensgegenstände');
+INSERT INTO gifi (accno,description) VALUES ('1501', 'Sonstige Vermögensgegenstände - Restlaufz. bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1502', 'Sonstige Vermögensgegenstände - Restlaufz. größer 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1503', 'Ford. gg. Vorstandsmitgl. u. Geschäftsf. - Restl. b. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1504', 'Ford. gg. Vorstandsmitgl. u. Geschäftsf. - Restl. gr. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1505', 'Ford. gg. Aufsichtsrats- u. Beiratsmitgl. - Restl. b. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1506', 'Ford. gg. Aufsichtsrats- u. Beiratsmitgl. - Restl. gr. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1507', 'Ford. gg. Gesellschafter - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1508', 'Ford. gg. Gesellschafter - Restlaufzeit größer 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1510', 'Geleistete Anzahlungen auf Vorräte');
+INSERT INTO gifi (accno,description) VALUES ('1511', 'Geleistete Anzahlungen, 7% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('1516', 'Geleistete Anzahlungen, 15% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('1517', 'Geleistete Anzahlungen, 16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('1521', 'Agenturwarenabrechnung');
+INSERT INTO gifi (accno,description) VALUES ('1525', 'Kautionen');
+INSERT INTO gifi (accno,description) VALUES ('1526', 'Kautionen - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1527', 'Kautionen - Restlaufzeit größer 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1530', 'Forderungen gegen Personal');
+INSERT INTO gifi (accno,description) VALUES ('1531', 'Forderungen gegen Personal - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1537', 'Forderungen gegen Personal - Restlaufzeit größer 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1540', 'Steuerüberzahlungen');
+INSERT INTO gifi (accno,description) VALUES ('1542', 'Steuererstattungsansprüche gg. anderen EU-Ländern');
+INSERT INTO gifi (accno,description) VALUES ('1545', 'Umsatzsteuerforderungen');
+INSERT INTO gifi (accno,description) VALUES ('1547', 'Forderungen aus entrichteten Verbrauchssteuern');
+INSERT INTO gifi (accno,description) VALUES ('1548', 'Vorsteuer im Folgejahr abziehbar');
+INSERT INTO gifi (accno,description) VALUES ('1549', 'Körperschaftsteuerrückforderung');
+INSERT INTO gifi (accno,description) VALUES ('1550', 'Darlehen');
+INSERT INTO gifi (accno,description) VALUES ('1551', 'Darlehen - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1555', 'Darlehen - Restlaufzeit größer 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1560', 'Aufzuteilende Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('1561', 'Aufzuteilende Vorsteuer, 7%');
+INSERT INTO gifi (accno,description) VALUES ('1562', 'Aufzuteilende Vorsteuer aus ig. Erwerb');
+INSERT INTO gifi (accno,description) VALUES ('1565', 'Aufzuteilende Vorsteuer, 16 %');
+INSERT INTO gifi (accno,description) VALUES ('1566', 'Aufzuteilende Vorsteuer, 15 %');
+INSERT INTO gifi (accno,description) VALUES ('1570', 'Abziehbare Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('1571', 'Abziehbare Vorsteuer, 7%');
+INSERT INTO gifi (accno,description) VALUES ('1572', 'Abziehbare Vorsteuer aus ig. Erwerb');
+INSERT INTO gifi (accno,description) VALUES ('1573', 'Abziehbare Vorsteuer aus ig. Erwerb, 16%');
+INSERT INTO gifi (accno,description) VALUES ('1575', 'Abziehbare Vorsteuer, 16%');
+INSERT INTO gifi (accno,description) VALUES ('1576', 'Abziehbare Vorsteuer, 15%');
+INSERT INTO gifi (accno,description) VALUES ('1577', 'Vorsteuer nach allg. Durchschnittssätzen UStVA KZ 63');
+INSERT INTO gifi (accno,description) VALUES ('1578', 'Berichtigung des VSt-Abzugs früherer Jahre UStVA KZ 64');
+INSERT INTO gifi (accno,description) VALUES ('1580', 'Gegenkonto Vorsteuer § 4/3 EStG');
+INSERT INTO gifi (accno,description) VALUES ('1581', 'Auflösung Vorsteuer aus Vorjahr § 4/3 EStG');
+INSERT INTO gifi (accno,description) VALUES ('1584', 'Abziehb. VSt. a. ig. Erw. v. Neufahrz. v. Lief. ohne USt-ID');
+INSERT INTO gifi (accno,description) VALUES ('1586', 'Kürzung BerlinFG');
+INSERT INTO gifi (accno,description) VALUES ('1588', 'Bezahlte Einfuhrumsatzsteuer');
+INSERT INTO gifi (accno,description) VALUES ('1590', 'Durchlaufende Posten');
+INSERT INTO gifi (accno,description) VALUES ('1593', 'Verrechnungskto erhalt. Anzahl. b. Buchung ü. Kundenkto');
+INSERT INTO gifi (accno,description) VALUES ('1594', 'Forderungen gegen verbundene Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('1595', 'Ford. gg. verbundene Unternehmen - Restlaufz. b. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1596', 'Ford. gg. verbundene Unternehmen - Restlaufz. gr. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1597', 'Ford. gg. Untern. mit denen ein Beteiligungsverh. besteht');
+INSERT INTO gifi (accno,description) VALUES ('1598', 'Ford. gg. U. m.d.e. Beteiligungsv. best. - Restl. b. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1599', 'Ford. gg. U. m.d.e. Beteiligungsv. best. - Restl. gr. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1600', 'Verb. aus Lief. und Leist. Lieferantengruppe 0');
+INSERT INTO gifi (accno,description) VALUES ('1601', 'Verb. aus Lief. und Leist. Lieferantengruppe 1');
+INSERT INTO gifi (accno,description) VALUES ('1602', 'Verb. aus Lief. und Leist. Lieferantengruppe 2');
+INSERT INTO gifi (accno,description) VALUES ('1610', 'Verb.a.L.u.L. ohne Kontokorrent');
+INSERT INTO gifi (accno,description) VALUES ('1624', 'Verbindlichkeiten aus Lief. u. Leist. für Investitionen für §4/3 EStG');
+INSERT INTO gifi (accno,description) VALUES ('1625', 'Verb.a.L.u.L. ohne Kontokorrent - Restl. b. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1626', 'Verb.a.L.u.L. ohne Kontokorrent - Restlaufz. 1 bis 5  J.');
+INSERT INTO gifi (accno,description) VALUES ('1628', 'Verb.a.L.u.L. ohne Kontokorrent - Restlaufz. größer 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('1630', 'Verb.a.Lief.u.Leist. gg. verbundenen Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('1631', 'Verb.a.L.u.L. gg. verb. Untern. - Restlaufz. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1635', 'Verb.a.L.u.L. gg. verb. Untern. - Restlaufz. 1 bis 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('1638', 'Verb.a.L.u.L. gg. verb. Untern. - Restlaufz. größer 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('1640', 'Verb.a.L.u.L. gg. Untern. m.d.e. Beteiligungsverh. best.');
+INSERT INTO gifi (accno,description) VALUES ('1641', 'Verb.a.L.u.L. gg. U. m.d.e. Beteilig. best. - Restl. b. 1 J');
+INSERT INTO gifi (accno,description) VALUES ('1645', 'Verb.a.L.u.L. gg. U. m.d.e. Beteilig. best. - Restl. 1 b 5 J');
+INSERT INTO gifi (accno,description) VALUES ('1648', 'Verb.a.L.u.L. gg. U. m.d.e. Beteilig. best. - Restl. gr. 5 J');
+INSERT INTO gifi (accno,description) VALUES ('1650', 'Verb.a.Lief.u.Leist. gegen Gesellschaftern');
+INSERT INTO gifi (accno,description) VALUES ('1651', 'Verb.a.Lief.u.Leist. gg. Gesellsch. - Restl. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1655', 'Verb.a.Lief.u.Leist. gg. Gesellsch. - Restl. 1 bis 5  J.');
+INSERT INTO gifi (accno,description) VALUES ('1658', 'Verb.a.Lief.u.Leist. gg. Gesellsch. - Restl. größer 5  J.');
+INSERT INTO gifi (accno,description) VALUES ('1659', 'Gegenkonto 16250-16580 bei Aufteilung Kreditoren-Konto');
+INSERT INTO gifi (accno,description) VALUES ('1660', 'Schuldwechsel');
+INSERT INTO gifi (accno,description) VALUES ('1661', 'Schuldwechsel - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1680', 'Schuldwechsel - Restlaufzeit 1 bis 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1690', 'Schuldwechsel - Restlaufzeit größer 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1700', 'Sonstige Verbindlichkeiten');
+INSERT INTO gifi (accno,description) VALUES ('1701', 'Sonstige Verbindlichkeiten - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1702', 'Sonstige Verbindlichkeiten - Restlaufzeit 1 bis 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1703', 'Sonstige Verbindlichkeiten - Restlaufzeit größer 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1704', 'Sonstige Verbindlichkeiten, z.B. nach §11,Abs.2,2 EStG für §4/3');
+INSERT INTO gifi (accno,description) VALUES ('1705', 'Darlehen');
+INSERT INTO gifi (accno,description) VALUES ('1706', 'Darlehen - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1707', 'Darlehen - Restlaufzeit 1 bis 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1708', 'Darlehen - Restlaufzeit größer 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1709', 'Gewinnverfügungskonto stiller Gesellschafter');
+INSERT INTO gifi (accno,description) VALUES ('1710', 'Erhaltene Anzahlungen (Verbindlichkeiten)');
+INSERT INTO gifi (accno,description) VALUES ('1711', 'Erhaltene verst. Anzahl., 7% USt (Verbindlichkeiten)');
+INSERT INTO gifi (accno,description) VALUES ('1716', 'Erhaltene verst. Anzahl., 15% USt (Verbindlichkeiten)');
+INSERT INTO gifi (accno,description) VALUES ('1717', 'Erhaltene verst. Anzahl., 16% USt (Verbindlichkeiten)');
+INSERT INTO gifi (accno,description) VALUES ('1719', 'Erhaltene Anzahlungen - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1720', 'Erhaltene Anzahlungen - Restlaufzeit 1 bis 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1721', 'Erhaltene Anzahlungen - Restlaufzeit größer 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1722', 'Erhaltene Anzahlungen (von Vorräten offen abgesetzt)');
+INSERT INTO gifi (accno,description) VALUES ('1731', 'Agenturwarenabrechnung');
+INSERT INTO gifi (accno,description) VALUES ('1732', 'Erhaltene Kautionen');
+INSERT INTO gifi (accno,description) VALUES ('1733', 'Erhaltene Kautionen - Restlaufzeit bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1734', 'Erhaltene Kautionen - Restlaufzeit 1 bis 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1735', 'Erhaltene Kautionen - Restlaufzeit größer 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1736', 'Verbindlichkeiten aus Betriebsteuern und Abgaben');
+INSERT INTO gifi (accno,description) VALUES ('1737', 'Verb. aus Betriebsteuern u. Abgaben - Restlaufz. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1738', 'Verb. aus Betriebsteuern u. Abgaben - Restlaufz. 1 bis 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('1739', 'Verb. aus Betriebsteuern u. Abgaben - Restl. größer 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('1740', 'Verbindlichkeiten aus Lohn und Gehalt');
+INSERT INTO gifi (accno,description) VALUES ('1741', 'Verbindlichkeiten aus Lohn- und Kirchensteuer');
+INSERT INTO gifi (accno,description) VALUES ('1742', 'Verbindlichkeiten im Rahmen der sozialen Sicherheit');
+INSERT INTO gifi (accno,description) VALUES ('1743', 'Verb. im Rahmen der sozialen Sicherheit - Restl. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('1744', 'Verb. im Rahmen der sozialen Sicherheit - Restl. 1 bis 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('1745', 'Verb. im Rahmen der sozialen Sicherheit - Restl. gr. 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('1746', 'Verbindlichkeiten aus Einbehaltungen');
+INSERT INTO gifi (accno,description) VALUES ('1747', 'Verbindlichkeiten für Verbrauchssteuern');
+INSERT INTO gifi (accno,description) VALUES ('1750', 'Verbindlichkeiten aus Vermögensbildung');
+INSERT INTO gifi (accno,description) VALUES ('1751', 'Verb. aus Vermögensbildung - Restlaufz. bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1752', 'Verb. aus Vermögensbildung - Restlaufz. 1 bis 5  Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1753', 'Verb. aus Vermögensbildung - Restlaufz. größer 5  Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1755', 'Lohn- und Gehaltsverrechnung');
+INSERT INTO gifi (accno,description) VALUES ('1758', 'Umsatzsteuerabzugsverfahren, 16% Umsatzsteuer');
+INSERT INTO gifi (accno,description) VALUES ('1759', 'Umsatzsteuerabzugsverfahren, 15% Umsatzsteuer');
+INSERT INTO gifi (accno,description) VALUES ('1760', 'Umsatzsteuer nicht fällig');
+INSERT INTO gifi (accno,description) VALUES ('1761', 'Umsatzsteuer nicht fällig , 7%');
+INSERT INTO gifi (accno,description) VALUES ('1762', 'Umsatzsteuer nicht fällig a.i. Inland steuerpfl. EU-Lief.');
+INSERT INTO gifi (accno,description) VALUES ('1763', 'Umsatzsteuer nicht fällig a.i. Inland steuerpfl. EU-Lief., 16%');
+INSERT INTO gifi (accno,description) VALUES ('1765', 'Umsatzsteuer nicht fällig, 16%');
+INSERT INTO gifi (accno,description) VALUES ('1766', 'Umsatzsteuer nicht fällig, 15%');
+INSERT INTO gifi (accno,description) VALUES ('1767', 'Umsatzsteuer a.i. and. EU-Land steuerpfl. Lief.');
+INSERT INTO gifi (accno,description) VALUES ('1768', 'Umsatzsteuer a.i. and. EU-Land steuerpfl. sonst. Lief./Werkl.');
+INSERT INTO gifi (accno,description) VALUES ('1769', 'Steuerzahlungen an andere EU-Länder');
+INSERT INTO gifi (accno,description) VALUES ('1770', 'Umsatzsteuer');
+INSERT INTO gifi (accno,description) VALUES ('1771', 'Umsatzsteuer, 7%');
+INSERT INTO gifi (accno,description) VALUES ('1772', 'Umsatzsteuer aus ig. Erwerb');
+INSERT INTO gifi (accno,description) VALUES ('1773', 'Umsatzsteuer aus ig. Erwerb, 16%');
+INSERT INTO gifi (accno,description) VALUES ('1775', 'Umsatzsteuer, 16%');
+INSERT INTO gifi (accno,description) VALUES ('1776', 'Umsatzsteuer, 15%');
+INSERT INTO gifi (accno,description) VALUES ('1777', 'Umsatzsteuer aus im Inland steuerpfl. EU-Lieferungen');
+INSERT INTO gifi (accno,description) VALUES ('1778', 'Umsatzsteuer aus im Inland steuerpfl. EU-Lieferungen, 16%');
+INSERT INTO gifi (accno,description) VALUES ('1779', 'Umsatzsteuer aus ig. Erwerb ohne Vorsteuerabzug');
+INSERT INTO gifi (accno,description) VALUES ('1780', 'Umsatzsteuer - Vorauszahlungen');
+INSERT INTO gifi (accno,description) VALUES ('1781', 'Umsatzsteuer - Vorauszahlungen 1/11');
+INSERT INTO gifi (accno,description) VALUES ('1782', 'Nachsteuer, UStVA KZ 65');
+INSERT INTO gifi (accno,description) VALUES ('1783', 'In Rechnung unber. ausgewiesene und geschuldete Steuer, UStVA KZ 69');
+INSERT INTO gifi (accno,description) VALUES ('1784', 'Umsatzsteuer aus ig. Erw. v. Neufahrz. v. Lief. ohne USt-ID');
+INSERT INTO gifi (accno,description) VALUES ('1788', 'Einfuhrumsatzsteuer aufgeschoben bis');
+INSERT INTO gifi (accno,description) VALUES ('1789', 'Umsatzsteuer laufendes Jahr');
+INSERT INTO gifi (accno,description) VALUES ('1790', 'Umsatzsteuer Vorjahr');
+INSERT INTO gifi (accno,description) VALUES ('1791', 'Umsatzsteuer frühere Jahre');
+INSERT INTO gifi (accno,description) VALUES ('1792', 'Abgrenzung für Grundstücke');
+INSERT INTO gifi (accno,description) VALUES ('1794', 'Abgrenzung für immaterielle Vermögensgegenstände');
+INSERT INTO gifi (accno,description) VALUES ('1795', 'Abgrenzung für Bauten auf eigenen Grundstücken');
+INSERT INTO gifi (accno,description) VALUES ('1796', 'Abgrenzung für andere Anlagen, B.u.G. Ausstattung');
+INSERT INTO gifi (accno,description) VALUES ('1797', 'Abgrenzung für Bauten auf fremden Grundstücken');
+INSERT INTO gifi (accno,description) VALUES ('1798', 'Abgrenzung für technische Anlagen und Maschinen');
+INSERT INTO gifi (accno,description) VALUES ('1799', 'Sonstige Verrechnungskonten (Interimskonten)');
+INSERT INTO gifi (accno,description) VALUES ('1793', 'Verrechnungskto geleist. Anzahl. bei Buchung über Lief.Kto.');
+INSERT INTO gifi (accno,description) VALUES ('1800', 'Privatentn. allg. (Privat Vollhafter / Einzelunternehmer)');
+INSERT INTO gifi (accno,description) VALUES ('1810', 'Privatsteuern (Privat Vollhafter / Einzelunternehmer)');
+INSERT INTO gifi (accno,description) VALUES ('1820', 'Sonderausg. beschr. abzugsf. (Privat Vollhaft./Einzelu.)');
+INSERT INTO gifi (accno,description) VALUES ('1830', 'Sonderausg. unbeschr. abzugsf. (Privat Vollhaft./Einzelu.)');
+INSERT INTO gifi (accno,description) VALUES ('1840', 'Privatspenden (Privat Vollhafter / Einzelunternehmer)');
+INSERT INTO gifi (accno,description) VALUES ('1850', 'Außergewöhnliche Belastungen (Privat Vollhaft. / Einzelunt.)');
+INSERT INTO gifi (accno,description) VALUES ('1860', 'Grundstücksaufwand (Privat Vollhafter / Einzelunternehmer)');
+INSERT INTO gifi (accno,description) VALUES ('1870', 'Grundstücksertrag (Privat Vollhafter / Einzelunternehmer)');
+INSERT INTO gifi (accno,description) VALUES ('1880', 'Eigenverbrauch (Privat Vollhafter / Einzelunternehmer)');
+INSERT INTO gifi (accno,description) VALUES ('1890', 'Privateinlagen (Privat Vollhafter / Einzelunternehmer)');
+INSERT INTO gifi (accno,description) VALUES ('1900', 'Privatentnahmen allgemein (Privat Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('1910', 'Privatsteuern (Privat Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('1920', 'Sonderausgaben beschränkt abzugsf. (Privat Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('1930', 'Sonderausgaben unbeschränkt abzugsf. (Privat Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('1940', 'Privatspenden (Privat Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('1950', 'Außergewöhnliche Belastungen (Privat Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('1960', 'Grundstücksaufwand (Privat Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('1970', 'Grundstücksertrag (Privat Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('1980', 'Eigenverbrauch (Privat Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('1990', 'Privateinlagen  (Privat Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('2000', 'Außerordentliche Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('2010', 'Betriebsfremde Aufw. (soweit nicht außerordentlich)');
+INSERT INTO gifi (accno,description) VALUES ('2020', 'Periodenfremde Aufw. (soweit nicht außerordentlich)');
+INSERT INTO gifi (accno,description) VALUES ('2100', 'Zinsen und ähnliche Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('2103', 'Steuerlich abzugsfähige, andere Nebenleistungen zu Steuern');
+INSERT INTO gifi (accno,description) VALUES ('2104', 'Steuerlich nicht abzugsfähige, andere Nebenleistungen zu Steuern');
+INSERT INTO gifi (accno,description) VALUES ('2107', 'Zinsaufwendungen §233a AO betriebliche Steuern');
+INSERT INTO gifi (accno,description) VALUES ('2108', 'Zinsaufw. §233a, §234, §237 AO Personenst. §8 GewStG');
+INSERT INTO gifi (accno,description) VALUES ('2109', 'Zinsaufwendungen an verbundene Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('2110', 'Zinsaufwendungen für kurzfristige Verbindlichkeiten');
+INSERT INTO gifi (accno,description) VALUES ('2118', 'In Dauerschuldzins. umqualif. Zinsen a. kurzfristige Verb.');
+INSERT INTO gifi (accno,description) VALUES ('2119', 'Zinsaufw. f. kurzfristige Verb. an verbunden Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('2120', 'Zinsaufwendungen für langfristige Verbindlichkeiten');
+INSERT INTO gifi (accno,description) VALUES ('2127', 'Renten u. dauernde Last. a. Gründung/Erwerb §8GewStG');
+INSERT INTO gifi (accno,description) VALUES ('2128', 'Zinsaufw. an Mitu. f. Hingabe v. langfrist. Kapital §15 EStG');
+INSERT INTO gifi (accno,description) VALUES ('2129', 'Zinsaufw. f. langfristige Verb. an verbundene Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('2130', 'Diskontaufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('2139', 'Diskontaufwendungen an verbundene Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('2140', 'Zinsähnliche Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('2149', 'Zinsähnliche Aufwendungen an verbundene Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('2150', 'Aufwendungen aus Kursdifferenzen');
+INSERT INTO gifi (accno,description) VALUES ('2170', 'Nicht abziehb. VSt a. Zinsen u. ähnl. Aufw.');
+INSERT INTO gifi (accno,description) VALUES ('2171', 'Nicht abziehb. VSt, 7% a. Zinsen u. ähnl. Aufw.');
+INSERT INTO gifi (accno,description) VALUES ('2175', 'Nicht abziehb. VSt. 16% a. Zinsen u. ähnl. Aufw.');
+INSERT INTO gifi (accno,description) VALUES ('2176', 'Nicht abziehb. VSt, 15% a. Zinsen u. ähnl. Aufw.');
+INSERT INTO gifi (accno,description) VALUES ('2200', 'Körperschaftsteuer');
+INSERT INTO gifi (accno,description) VALUES ('2203', 'Körperschaftsteuer für Vorjahre');
+INSERT INTO gifi (accno,description) VALUES ('2205', 'Anrechenbare Körperschaftssteuer auf vereinnahmte Kapitalerträge');
+INSERT INTO gifi (accno,description) VALUES ('2208', 'Solidaritätszuschlag');
+INSERT INTO gifi (accno,description) VALUES ('2209', 'Solidaritätszuschlag für Vorjahre');
+INSERT INTO gifi (accno,description) VALUES ('2210', 'Kapitalertragsteuer');
+INSERT INTO gifi (accno,description) VALUES ('2213', 'Anrechenbarer Solidaritätszuschlag auf Kapitalertragssteuer');
+INSERT INTO gifi (accno,description) VALUES ('2215', 'Zinsabschlagsteuer');
+INSERT INTO gifi (accno,description) VALUES ('2218', 'Anrechenbarer Solidaritätszuschlag auf Zinsabschlagsteuer');
+INSERT INTO gifi (accno,description) VALUES ('2223', 'Vermögensteuer für Vorjahre');
+INSERT INTO gifi (accno,description) VALUES ('2280', 'Steuernachz. Vorjahre f. Steuern v. Einkommen u. Ertrag');
+INSERT INTO gifi (accno,description) VALUES ('2282', 'Steuererstatt. Vorjahre f. Steuern v. Einkommen u. Ertrag');
+INSERT INTO gifi (accno,description) VALUES ('2284', 'Erträge a. Aufl. v. Rückst. f. Steuern v. Eink. u. Ertrag');
+INSERT INTO gifi (accno,description) VALUES ('2285', 'Steuernachzahlung Vorjahre für sonstige Steuern');
+INSERT INTO gifi (accno,description) VALUES ('2287', 'Steuererstattung Vorjahre für sonstige Steuern');
+INSERT INTO gifi (accno,description) VALUES ('2289', 'Erträge a. d. Auflösung v. Rückstell. f. sonstige Steuern');
+INSERT INTO gifi (accno,description) VALUES ('2300', 'Sonstige Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('2307', 'Sonstige Aufwendungen betriebsfremd und regelmäßig');
+INSERT INTO gifi (accno,description) VALUES ('2309', 'Sonstige Aufwendungen unregelmäßig');
+INSERT INTO gifi (accno,description) VALUES ('2310', 'Anlagenabgänge (Restbuchwert und Buchverlust)');
+INSERT INTO gifi (accno,description) VALUES ('2315', 'Anlagenabgänge (Restbuchwert bei Buchgewinn)');
+INSERT INTO gifi (accno,description) VALUES ('2320', 'Verluste a. Abgang v. Gegenst. d. Anlagevermögens');
+INSERT INTO gifi (accno,description) VALUES ('2325', 'Verluste a. Abgang v. Gegenst. d. Umlaufv. (außer Vorräte)');
+INSERT INTO gifi (accno,description) VALUES ('2340', 'Einstell. in Sonderpost. m. Rücklageant. (steuerfr. Rückl.)');
+INSERT INTO gifi (accno,description) VALUES ('2341', 'Einstell. in Sonderpost. m. Rücklageant. (Ansparabschreibungen)');
+INSERT INTO gifi (accno,description) VALUES ('2345', 'Einstell. in Sonderpost. m. Rücklageant. (Sonderabschr.)');
+INSERT INTO gifi (accno,description) VALUES ('2350', 'Grundstücksaufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('2375', 'Grundsteuer');
+INSERT INTO gifi (accno,description) VALUES ('2380', 'Spenden, steuerlich nicht absetzbar');
+INSERT INTO gifi (accno,description) VALUES ('2381', 'Beiträge u. Spenden f. wissenschaftl. u. kulturelle Zwecke');
+INSERT INTO gifi (accno,description) VALUES ('2382', 'Beiträge u. Spenden f. mildtätige Zwecke');
+INSERT INTO gifi (accno,description) VALUES ('2383', 'Beiträge u. Spenden f. kirchl., religiöse u. gemeinn. Zwecke');
+INSERT INTO gifi (accno,description) VALUES ('2384', 'Beiträge u. Spenden an politische Parteien');
+INSERT INTO gifi (accno,description) VALUES ('2385', 'Nicht abziehbare Hälfte der Aufsichtsratsvergütungen');
+INSERT INTO gifi (accno,description) VALUES ('2386', 'Abziehbare Aufsichtsratsvergütungen');
+INSERT INTO gifi (accno,description) VALUES ('2400', 'Forderungsverluste (übliche Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('2401', 'Forderungsverluste, 7% USt (übliche Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('2402', 'Ford.Verl. a. steuerfr. EU-Lief. (übliche Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('2403', 'Ford.Verl. a.i. Inl. steuerpfl. EU-Lief., 7% USt (übl. Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('2404', 'Ford.Verl. a.i. Inl. steuerpfl. EU-Lief., 15%+16%USt (übl. Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('2405', 'Forderungsverluste, 15%+16% USt (übliche Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('2406', 'Forderungsverluste, 16% USt (übliche Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('2407', 'Forderungsverluste, 15% USt (übliche Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('2408', 'Ford.Verl. a.i. Inl. steuerpfl. EU-Lief., 16%USt (übl. Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('2409', 'Ford.Verl. a.i. Inl. steuerpfl. EU-Lief., 15%USt (übl. Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('2430', 'Forderungsverlust unüblich hoch');
+INSERT INTO gifi (accno,description) VALUES ('2450', 'Einstellungen in Pauschalwertberichtigung zu Forderungen');
+INSERT INTO gifi (accno,description) VALUES ('2451', 'Einstellungen in Einzelwertberichtigung zu Forderungen');
+INSERT INTO gifi (accno,description) VALUES ('2490', 'Aufwendungen aus Verlustübernahme');
+INSERT INTO gifi (accno,description) VALUES ('2492', 'Abgef. Gew. aufgrund einer Gewinngemeinschaft');
+INSERT INTO gifi (accno,description) VALUES ('2493', 'Abgef. Gew. a. stille Gesellschafter §8 GewStG');
+INSERT INTO gifi (accno,description) VALUES ('2494', 'Abgef. Gew. a. Gewinn- oder Teilgewinnabführungsvertr.');
+INSERT INTO gifi (accno,description) VALUES ('2495', 'Einst. in die Kapitalrückl. n. Vorschr. d. vereinf. Kap.Herabs.');
+INSERT INTO gifi (accno,description) VALUES ('2496', 'Einst. in die gesetzliche Rücklage');
+INSERT INTO gifi (accno,description) VALUES ('2497', 'Einst. in die satzungsmäßige Rücklage');
+INSERT INTO gifi (accno,description) VALUES ('2498', 'Einst. in die Rücklage für eigene Anteile');
+INSERT INTO gifi (accno,description) VALUES ('2499', 'Einst. in andere Gewinnrücklagen');
+INSERT INTO gifi (accno,description) VALUES ('2500', 'Außerordentliche Erträge');
+INSERT INTO gifi (accno,description) VALUES ('2510', 'Betriebsfremde Erträge (soweit nicht außerordentlich)');
+INSERT INTO gifi (accno,description) VALUES ('2520', 'Periodenfremde Erträge (soweit nicht außerordentlich)');
+INSERT INTO gifi (accno,description) VALUES ('2600', 'Erträge aus Beteiligungen');
+INSERT INTO gifi (accno,description) VALUES ('2617', 'Gewinne a.Ant. an nicht steuerbefr. inländischen KG §9Nr.2aGewStG');
+INSERT INTO gifi (accno,description) VALUES ('2618', 'Gewinnanteile aus Mitunternehmerschaften §9 GewStG');
+INSERT INTO gifi (accno,description) VALUES ('2619', 'Erträge aus Beteiligungen an verbundenen Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('2620', 'Ertr. a. and. Wertpap. u. Ausl. d. Finanzanlageverm.');
+INSERT INTO gifi (accno,description) VALUES ('2649', 'Ertr. a. and. Wertpap. u. Ausl. d. Fin.Anl.Verm. a. verb. U.');
+INSERT INTO gifi (accno,description) VALUES ('2650', 'Sonstige Zinsen und ähnliche Erträge');
+INSERT INTO gifi (accno,description) VALUES ('2657', 'Zinserträge §233a AO betriebliche Steuern');
+INSERT INTO gifi (accno,description) VALUES ('2658', 'Zinserträge §233a AO Körperschaftsteuer / Vermögensteuer');
+INSERT INTO gifi (accno,description) VALUES ('2659', 'Sonstige Zinsen u. ähnliche Erträge aus verb. Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('2660', 'Erträge aus Kursdifferenzen');
+INSERT INTO gifi (accno,description) VALUES ('2670', 'Diskonterträge');
+INSERT INTO gifi (accno,description) VALUES ('2679', 'Diskonterträge aus verbundenen Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('2680', 'Zinsähnliche Erträge');
+INSERT INTO gifi (accno,description) VALUES ('2689', 'Zinsähnliche Erträge aus verbundenen Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('2700', 'Sonstige Erträge');
+INSERT INTO gifi (accno,description) VALUES ('2705', 'Sonstige Erträge betrieblich und regelmäßig');
+INSERT INTO gifi (accno,description) VALUES ('2707', 'Sonstige Erträge betriebsfremd und regelmäßig');
+INSERT INTO gifi (accno,description) VALUES ('2709', 'Sonstige Erträge unregelmäßig');
+INSERT INTO gifi (accno,description) VALUES ('2710', 'Erträge aus Zuschreibungen des Anlagevermögens');
+INSERT INTO gifi (accno,description) VALUES ('2715', 'Erträge aus Zuschreibungen des Umlaufvermögens');
+INSERT INTO gifi (accno,description) VALUES ('2720', 'Ertr. a. Abgang v. Gegenst. d. Anlagevermögens');
+INSERT INTO gifi (accno,description) VALUES ('2725', 'Ertr. a. Abgang v. Gegenst. d. Umlaufv.s (außer Vorräte)');
+INSERT INTO gifi (accno,description) VALUES ('2730', 'Ertr. a. Herabs. d. Pauschalwertber. zu Forderungen');
+INSERT INTO gifi (accno,description) VALUES ('2731', 'Ertr. a. Herabs. d. Einzelwertber. zu Forderungen');
+INSERT INTO gifi (accno,description) VALUES ('2732', 'Erträge aus abgeschriebenen Forderungen');
+INSERT INTO gifi (accno,description) VALUES ('2735', 'Erträge aus der Auflösung von Rückstellungen');
+INSERT INTO gifi (accno,description) VALUES ('2739', 'Erträge aus der Auflösung von Sonderpost. m. Rücklageant. (Ansparabschr.)');
+INSERT INTO gifi (accno,description) VALUES ('2740', 'Ertr. a. Aufl. v. Sonderp. m. Rückl.Ant. (steuerfr. Rückl.)');
+INSERT INTO gifi (accno,description) VALUES ('2741', 'Ertr. a. Aufl. v. Sonderp. m. Rückl.Ant. (Sonderabschr.)');
+INSERT INTO gifi (accno,description) VALUES ('2742', 'Versicherungsentschädigungen');
+INSERT INTO gifi (accno,description) VALUES ('2743', 'Investitionszuschüsse (steuerpflichtig)');
+INSERT INTO gifi (accno,description) VALUES ('2744', 'Investitionszulagen (steuerfrei)');
+INSERT INTO gifi (accno,description) VALUES ('2745', 'Erträge aus Kapitalherabsetzung');
+INSERT INTO gifi (accno,description) VALUES ('2750', 'Grundstückserträge');
+INSERT INTO gifi (accno,description) VALUES ('2780', 'Steuererstattung Vorjahre f. Steuern vom Eink. u. Ertrag');
+INSERT INTO gifi (accno,description) VALUES ('2785', 'Steuererstattung Vorjahre f. sonstige Steuern');
+INSERT INTO gifi (accno,description) VALUES ('2790', 'Erträge aus Verlustübernahme');
+INSERT INTO gifi (accno,description) VALUES ('2792', 'Erh. Gew. aufgrund einer Gewinngemeinschaft');
+INSERT INTO gifi (accno,description) VALUES ('2794', 'Erh. Gew. aufgrund eines Gew.- oder Teilgew.Abführ.Vertr.');
+INSERT INTO gifi (accno,description) VALUES ('2795', 'Entnahmen aus der Kapitalrücklage');
+INSERT INTO gifi (accno,description) VALUES ('2796', 'Entnahmen aus der gesetzlichen Rücklage');
+INSERT INTO gifi (accno,description) VALUES ('2797', 'Entnahmen aus satzungsgemäßen Rücklagen');
+INSERT INTO gifi (accno,description) VALUES ('2798', 'Entnahmen aus der Rücklage für eigene Anteile');
+INSERT INTO gifi (accno,description) VALUES ('2799', 'Entnahmen aus anderen Gewinnrücklagen');
+INSERT INTO gifi (accno,description) VALUES ('2860', 'Gewinnvortrag nach Verwendung');
+INSERT INTO gifi (accno,description) VALUES ('2862', 'Gewinnvortrag 50/45% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('2864', 'Gewinnvortrag 30% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('2866', 'Gewinnvortrag 0% Vorbelastung');
+INSERT INTO gifi (accno,description) VALUES ('2868', 'Verlustvortrag nach Verwendung');
+INSERT INTO gifi (accno,description) VALUES ('2869', 'Vorträge auf neue Rechnung (GuV)');
+INSERT INTO gifi (accno,description) VALUES ('2870', 'Ausschüttung');
+INSERT INTO gifi (accno,description) VALUES ('2890', 'Verrechneter kalkulatorischer Unternehmerlohn');
+INSERT INTO gifi (accno,description) VALUES ('2891', 'Verrechnete kalkulatorische Miete und Pacht');
+INSERT INTO gifi (accno,description) VALUES ('2892', 'Verrechnete kalkulatorische Zinsen');
+INSERT INTO gifi (accno,description) VALUES ('2893', 'Verrechnete kalkulatorische Abschreibung');
+INSERT INTO gifi (accno,description) VALUES ('2894', 'Verrechnete kalkulatorische Wagnisse');
+INSERT INTO gifi (accno,description) VALUES ('2895', 'Verrechneter kalkulatorischer Lohn für unentgeltliche Mitarbeiter');
+INSERT INTO gifi (accno,description) VALUES ('3000', 'Roh-, Hilfs- und Betriebsstoffe');
+INSERT INTO gifi (accno,description) VALUES ('3090', 'Energiestoffe (Fertigung)');
+INSERT INTO gifi (accno,description) VALUES ('3100', 'Fremdleistungen');
+INSERT INTO gifi (accno,description) VALUES ('3150', 'Leistungen von ausländischen Unternehmen (Nullregelung)');
+INSERT INTO gifi (accno,description) VALUES ('3200', 'Wareneingang');
+INSERT INTO gifi (accno,description) VALUES ('3300', 'Wareneingang,  7% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3340', 'Wareneingang, 15% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3400', 'Wareneingang, 15%+16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3410', 'Wareneingang, 16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3420', 'Innergem. Erwerb, 7% VSt u. 7% USt');
+INSERT INTO gifi (accno,description) VALUES ('3425', 'Innergem. Erwerb, 15%+16% VSt u. 15%+16% USt');
+INSERT INTO gifi (accno,description) VALUES ('3430', 'Innergem. Erwerb, ohne VSt-Abzug u. 7% USt');
+INSERT INTO gifi (accno,description) VALUES ('3431', 'Innergem. Erwerb, 16% VSt u. 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('3433', 'Innergem. Erwerb, 15% VSt u. 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('3435', 'Innergem. Erwerb, ohne VSt-Abzug u. 15%+16% USt');
+INSERT INTO gifi (accno,description) VALUES ('3436', 'Innergem. Erwerb, ohne VSt-Abzug u. 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('3437', 'Innergem. Erwerb, ohne VSt-Abzug u. 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('3440', 'Innergem. Erw. v. Neufahrz. v. Lief. ohne USt-ID, 15%+16% USt');
+INSERT INTO gifi (accno,description) VALUES ('3441', 'Innergem. Erw. v. Neufahrz. v. Lief. ohne USt-ID, 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('3442', 'Innergem. Erw. v. Neufahrz. v. Lief. ohne USt-ID, 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('3500', 'Wareneingang, 5% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3530', 'Wareneingang, 9% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3540', 'Wareneingang, 9,5% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3550', 'Steuerfreier innergemeinschaftlicher Erwerb');
+INSERT INTO gifi (accno,description) VALUES ('3600', 'Nicht abziehbare Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3610', 'Nicht abziehbare Vorsteuer,   7%');
+INSERT INTO gifi (accno,description) VALUES ('3650', 'Nicht abziehbare Vorsteuer, 16%');
+INSERT INTO gifi (accno,description) VALUES ('3660', 'Nicht abziehbare Vorsteuer, 15%');
+INSERT INTO gifi (accno,description) VALUES ('3700', 'Nachlässe');
+INSERT INTO gifi (accno,description) VALUES ('3710', 'Nachlässe, 7% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3720', 'Nachlässe, 15%+16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3722', 'Nachlässe, 16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3723', 'Nachlässe, 15% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3724', 'Nachlässe aus ig. Erwerb, 7% VSt und 7% USt');
+INSERT INTO gifi (accno,description) VALUES ('3725', 'Nachlässe aus ig. Erwerb, 15%+16% VSt und 15%+16% USt');
+INSERT INTO gifi (accno,description) VALUES ('3726', 'Nachlässe aus ig. Erwerb, 16% VSt und 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('3727', 'Nachlässe aus ig. Erwerb, 15% VSt und 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('3730', 'Erhaltene Skonti');
+INSERT INTO gifi (accno,description) VALUES ('3731', 'Erhaltene Skonti,   7% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3735', 'Erhaltene Skonti, 16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3736', 'Erhaltene Skonti, 15% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3740', 'Erhaltene Boni');
+INSERT INTO gifi (accno,description) VALUES ('3750', 'Erhaltene Boni,   7% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3760', 'Erhaltene Boni, 15%+16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3762', 'Erhaltene Boni, 16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3764', 'Erhaltene Boni, 15% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3770', 'Erhaltene Rabatte');
+INSERT INTO gifi (accno,description) VALUES ('3780', 'Erhaltene Rabatte, 7% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3790', 'Erhaltene Rabatte, 15%+16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3792', 'Erhaltene Rabatte, 16% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3794', 'Erhaltene Rabatte, 15% Vorsteuer');
+INSERT INTO gifi (accno,description) VALUES ('3800', 'Anschaffungsnebenkosten');
+INSERT INTO gifi (accno,description) VALUES ('3830', 'Leergut');
+INSERT INTO gifi (accno,description) VALUES ('3850', 'Zölle und Einfuhrabgaben');
+INSERT INTO gifi (accno,description) VALUES ('3960', 'Bestandsv. Roh-, Hilfs- u. Betriebsstoffe / bezogene Waren');
+INSERT INTO gifi (accno,description) VALUES ('3970', 'Bestand Roh-, Hilfs- und Betriebsstoffe');
+INSERT INTO gifi (accno,description) VALUES ('3980', 'Bestand Waren');
+INSERT INTO gifi (accno,description) VALUES ('3990', 'Verrechnete Stoffkosten');
+INSERT INTO gifi (accno,description) VALUES ('4000', 'Material- und Stoffverbrauch');
+INSERT INTO gifi (accno,description) VALUES ('4100', 'Löhne und Gehälter');
+INSERT INTO gifi (accno,description) VALUES ('4110', 'Löhne');
+INSERT INTO gifi (accno,description) VALUES ('4120', 'Gehälter');
+INSERT INTO gifi (accno,description) VALUES ('4124', 'Geschäftsführergehälter der GmbH-Gesellschafter');
+INSERT INTO gifi (accno,description) VALUES ('4125', 'Ehegattengehalt');
+INSERT INTO gifi (accno,description) VALUES ('4126', 'Tantiemen');
+INSERT INTO gifi (accno,description) VALUES ('4127', 'Geschäftsführergehälter');
+INSERT INTO gifi (accno,description) VALUES ('4128', 'Vergütungen an angestellte Mitunternehmer §15 EStG');
+INSERT INTO gifi (accno,description) VALUES ('4130', 'Gesetzliche soziale Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('4137', 'Gesetzliche soziale Aufw. für Mitunternehmer §15 EStG');
+INSERT INTO gifi (accno,description) VALUES ('4138', 'Beiträge zur Berufsgenossenschaft');
+INSERT INTO gifi (accno,description) VALUES ('4139', 'Ausgleichsabgabe i. S. d. Schwerbehindertengesetzes');
+INSERT INTO gifi (accno,description) VALUES ('4140', 'Freiw. soziale Aufwendungen (lohnsteuerfrei)');
+INSERT INTO gifi (accno,description) VALUES ('4145', 'Freiw. soziale Aufwendungen (lohnsteuerpflichtig)');
+INSERT INTO gifi (accno,description) VALUES ('4149', 'Pauschale Lohnsteuer auf s. Bezüge (z.B. Fahrtkostenzuschuß)');
+INSERT INTO gifi (accno,description) VALUES ('4150', 'Krankengeldzuschüsse');
+INSERT INTO gifi (accno,description) VALUES ('4160', 'Versorgungskassen');
+INSERT INTO gifi (accno,description) VALUES ('4165', 'Aufwendungen für die Altersversorgung');
+INSERT INTO gifi (accno,description) VALUES ('4167', 'Pauschale Lohnsteuer auf s. Bezüge (z.B. Direktversicherung)');
+INSERT INTO gifi (accno,description) VALUES ('4168', 'Aufw. f. die Altersversorgung f. Mitunternehmer §15 EStG');
+INSERT INTO gifi (accno,description) VALUES ('4169', 'Aufwendungen für Unterstützung');
+INSERT INTO gifi (accno,description) VALUES ('4170', 'Vermögenswirksame Leistungen');
+INSERT INTO gifi (accno,description) VALUES ('4175', 'Fahrtkostenerstattung - Wohnung / Arbeitsstätte');
+INSERT INTO gifi (accno,description) VALUES ('4180', 'Bedienungsgelder');
+INSERT INTO gifi (accno,description) VALUES ('4190', 'Aushilfslöhne');
+INSERT INTO gifi (accno,description) VALUES ('4199', 'Lohnsteuer für Aushilfen');
+INSERT INTO gifi (accno,description) VALUES ('4200', 'Raumkosten');
+INSERT INTO gifi (accno,description) VALUES ('4210', 'Miete');
+INSERT INTO gifi (accno,description) VALUES ('4218', 'Gewerbesteuerlich zu berücks. Miete §8 GewStG');
+INSERT INTO gifi (accno,description) VALUES ('4219', 'Vergütung an Mitu. f. mietw. Überl. v. Wirtschaftsg. §15EStG');
+INSERT INTO gifi (accno,description) VALUES ('4220', 'Pacht');
+INSERT INTO gifi (accno,description) VALUES ('4228', 'Gewerbesteuerlich zu berücks. Pacht §8 GewStG');
+INSERT INTO gifi (accno,description) VALUES ('4229', 'Vergütung an Mitu. f. pachtw. Überl. v. Wirtschaftsg.§15EStG');
+INSERT INTO gifi (accno,description) VALUES ('4230', 'Heizung');
+INSERT INTO gifi (accno,description) VALUES ('4240', 'Gas, Strom, Wasser (Verwaltung, Vertrieb)');
+INSERT INTO gifi (accno,description) VALUES ('4250', 'Reinigung');
+INSERT INTO gifi (accno,description) VALUES ('4260', 'Instandhaltung betrieblicher Räume');
+INSERT INTO gifi (accno,description) VALUES ('4270', 'Abgaben für betrieblich genutzten Grundbesitz');
+INSERT INTO gifi (accno,description) VALUES ('4280', 'Sonstige Raumkosten');
+INSERT INTO gifi (accno,description) VALUES ('4300', 'Nicht abziehb. VSt a. sonst. betriebl. Aufw./AfA');
+INSERT INTO gifi (accno,description) VALUES ('4301', 'Nicht abziehb. VSt, 7% a. sonst. betriebl. Aufw./AfA');
+INSERT INTO gifi (accno,description) VALUES ('4305', 'Nicht abziehb. VSt, 16% a. sonst. betriebl. Aufw./AfA');
+INSERT INTO gifi (accno,description) VALUES ('4306', 'Nicht abziehb. VSt, 15% a. sonst. betriebl. Aufw./AfA');
+INSERT INTO gifi (accno,description) VALUES ('4320', 'Gewerbesteuer (Vorauszahlung)');
+INSERT INTO gifi (accno,description) VALUES ('4330', 'Gewerbeertragsteuer');
+INSERT INTO gifi (accno,description) VALUES ('4335', 'Gewerbekapitalsteuer');
+INSERT INTO gifi (accno,description) VALUES ('4340', 'Sonstige Betriebsteuern');
+INSERT INTO gifi (accno,description) VALUES ('4350', 'Verbrauchsteuer');
+INSERT INTO gifi (accno,description) VALUES ('4360', 'Versicherungen');
+INSERT INTO gifi (accno,description) VALUES ('4370', 'Nettoprämie für Rückdeckung künftiger Versorgungsleistungen');
+INSERT INTO gifi (accno,description) VALUES ('4380', 'Beiträge');
+INSERT INTO gifi (accno,description) VALUES ('4390', 'Sonstige Abgaben');
+INSERT INTO gifi (accno,description) VALUES ('4396', 'Steuerlich abzugsfähige Verspätungszuschläge und Zwangsgelder');
+INSERT INTO gifi (accno,description) VALUES ('4397', 'Steuerlich nicht abzugsfähige Verspätungszuschläge und Zwangsgelder');
+INSERT INTO gifi (accno,description) VALUES ('4400', 'Besondere Kosten (zur freien Verfügung)');
+INSERT INTO gifi (accno,description) VALUES ('4500', 'Fahrzeugkosten');
+INSERT INTO gifi (accno,description) VALUES ('4510', 'Kfz-Steuern');
+INSERT INTO gifi (accno,description) VALUES ('4520', 'Kfz-Versicherungen');
+INSERT INTO gifi (accno,description) VALUES ('4530', 'Laufende Kfz-Betriebskosten');
+INSERT INTO gifi (accno,description) VALUES ('4540', 'Kfz-Reparaturen');
+INSERT INTO gifi (accno,description) VALUES ('4550', 'Garagenmieten');
+INSERT INTO gifi (accno,description) VALUES ('4570', 'Fremdfahrzeuge');
+INSERT INTO gifi (accno,description) VALUES ('4580', 'Sonstige Kfz-Kosten');
+INSERT INTO gifi (accno,description) VALUES ('4600', 'Werbe- und Reisekosten');
+INSERT INTO gifi (accno,description) VALUES ('4610', 'Werbekosten');
+INSERT INTO gifi (accno,description) VALUES ('4630', 'Geschenke bis DM 75,00');
+INSERT INTO gifi (accno,description) VALUES ('4635', 'Geschenke über DM 75,00');
+INSERT INTO gifi (accno,description) VALUES ('4638', 'Geschenke ausschließlich betrieblich genutzt');
+INSERT INTO gifi (accno,description) VALUES ('4640', 'Repräsentationskosten');
+INSERT INTO gifi (accno,description) VALUES ('4650', 'Bewirtungskosten');
+INSERT INTO gifi (accno,description) VALUES ('4653', 'Aufwerksamkeiten');
+INSERT INTO gifi (accno,description) VALUES ('4654', 'Nicht abzugsfähige Bewirtungskosten');
+INSERT INTO gifi (accno,description) VALUES ('4655', 'Nicht abzugsfähige Betriebsausgaben');
+INSERT INTO gifi (accno,description) VALUES ('4660', 'Reisekosten Arbeitnehmer');
+INSERT INTO gifi (accno,description) VALUES ('4666', 'Reisekost. Arbeitn., 12,3%/13,1% VSt  Verpfl.Mehr- / Übern.Aufw.');
+INSERT INTO gifi (accno,description) VALUES ('4667', 'Reisekost. Arbeitn., 9,8%/10,5% VSt Gesamtpauschal.');
+INSERT INTO gifi (accno,description) VALUES ('4670', 'Reisekosten Unternehmer');
+INSERT INTO gifi (accno,description) VALUES ('4675', 'Reisekosten Unternehmer, 9,8/10,5% VSt sonst.Gesamtpauschal.');
+INSERT INTO gifi (accno,description) VALUES ('4676', 'Reisekost. Untern., 12,3%/13,1% VSt Verpfl.Mehr- / Übern.Aufw.');
+INSERT INTO gifi (accno,description) VALUES ('4677', 'Reisekosten Unternehmer, 9,8%/10,5% VSt Verpfl.Mehraufw. Gesamtpauschal.');
+INSERT INTO gifi (accno,description) VALUES ('4678', 'Km-Geld Erstattung, Unternehmer, 5,7%/6,1% VSt');
+INSERT INTO gifi (accno,description) VALUES ('4685', 'Km-Geld-Erstattung, Arbeitnehmer  8,2%/8,7% VSt');
+INSERT INTO gifi (accno,description) VALUES ('4700', 'Kosten der Warenabgabe');
+INSERT INTO gifi (accno,description) VALUES ('4710', 'Verpackungsmaterial');
+INSERT INTO gifi (accno,description) VALUES ('4730', 'Ausgangsfrachten');
+INSERT INTO gifi (accno,description) VALUES ('4750', 'Transportversicherungen');
+INSERT INTO gifi (accno,description) VALUES ('4760', 'Verkaufsprovisionen');
+INSERT INTO gifi (accno,description) VALUES ('4780', 'Fremdarbeiten');
+INSERT INTO gifi (accno,description) VALUES ('4790', 'Aufwand für Gewährleistungen');
+INSERT INTO gifi (accno,description) VALUES ('4800', 'Reparat. u. Inst. v. Maschinen u. technischen Anlagen');
+INSERT INTO gifi (accno,description) VALUES ('4805', 'Reparat. u. Inst. v. and. Anl. d. Betr.- u. Geschäftsausst.');
+INSERT INTO gifi (accno,description) VALUES ('4809', 'Sonstige Reparaturen und Instandhaltungen');
+INSERT INTO gifi (accno,description) VALUES ('4810', 'Mietleasing');
+INSERT INTO gifi (accno,description) VALUES ('4814', 'Gewerbesteuerl. zu berücksicht. Mietleasing §8 GewStG');
+INSERT INTO gifi (accno,description) VALUES ('4815', 'Kaufleasing');
+INSERT INTO gifi (accno,description) VALUES ('4820', 'Abschr. a. Aufw. f.d. Ingangs. u. Erw. des Geschäftsbetr.');
+INSERT INTO gifi (accno,description) VALUES ('4822', 'Abschr. a. immaterielle Vermögensgegenstände');
+INSERT INTO gifi (accno,description) VALUES ('4824', 'Abschreibung auf den Geschäfts- oder Firmenwert');
+INSERT INTO gifi (accno,description) VALUES ('4826', 'Außerplanm. Abschr. a. immaterielle Vermögensgegenstände');
+INSERT INTO gifi (accno,description) VALUES ('4830', 'Abschreibungen auf Sachanlagen');
+INSERT INTO gifi (accno,description) VALUES ('4840', 'Außerplanm. Abschreibungen auf Sachanlagen');
+INSERT INTO gifi (accno,description) VALUES ('4850', 'Abschr. a. Sachanl. aufgrund steuerl. Sondervorschriften');
+INSERT INTO gifi (accno,description) VALUES ('4855', 'Sofortabschreibung geringwertiger Wirtschaftsgüter');
+INSERT INTO gifi (accno,description) VALUES ('4860', 'Abschreibung auf aktivierte, geringwertige Wirtschaftsgüter');
+INSERT INTO gifi (accno,description) VALUES ('4865', 'Außerplanmäßige Abschr. a. aktivierte GWG');
+INSERT INTO gifi (accno,description) VALUES ('4870', 'Abschreibungen auf Finanzanlagen');
+INSERT INTO gifi (accno,description) VALUES ('4872', 'Abschr. aufgrund v. Verlustant. an Mitunt. §8 GewStG');
+INSERT INTO gifi (accno,description) VALUES ('4874', 'Abschr. a. Finanzanl. aufgrund steuerl. Sondervorschriften');
+INSERT INTO gifi (accno,description) VALUES ('4875', 'Abschreibungen auf Wertpapiere des Umlaufvermögens');
+INSERT INTO gifi (accno,description) VALUES ('4879', 'Vorwegn. künft. Wertschw. bei Wertpapieren des Umlaufv.');
+INSERT INTO gifi (accno,description) VALUES ('4880', 'Abschr. a. Umlaufv. ohne Wertpapiere (soweit unübl. Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('4882', 'Abschr. a. Umlaufv. steuerrechtl. bedingt (unübl. Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('4885', 'Vorwegn. künft. Wertschw. Uml.V. auß. Vorr./Wertp. d. Uml.V.');
+INSERT INTO gifi (accno,description) VALUES ('4886', 'Abschr. a. Uml.V. auß. Vorr./Wertp. d. Uml.V. (übl. Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('4887', 'Abschr. a. Umlaufv., steuerrechtlich bedingt (übl. Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('4890', 'Vorwegn. künftiger Wertschw. im Umlaufv. (unübl. Höhe)');
+INSERT INTO gifi (accno,description) VALUES ('4900', 'Sonstige betriebliche Aufwendungen');
+INSERT INTO gifi (accno,description) VALUES ('4905', 'Sonstige Aufwendungen betrieblich und regelmäßig');
+INSERT INTO gifi (accno,description) VALUES ('4910', 'Porto');
+INSERT INTO gifi (accno,description) VALUES ('4920', 'Telefon');
+INSERT INTO gifi (accno,description) VALUES ('4925', 'Telefax, Fernschreiber');
+INSERT INTO gifi (accno,description) VALUES ('4930', 'Bürobedarf');
+INSERT INTO gifi (accno,description) VALUES ('4940', 'Zeitschriften, Bücher');
+INSERT INTO gifi (accno,description) VALUES ('4945', 'Fortbildungskosten');
+INSERT INTO gifi (accno,description) VALUES ('4946', 'Freiwillige Sozialleistungen');
+INSERT INTO gifi (accno,description) VALUES ('4948', 'Vergütungen an freiberufliche Mitunternehmer §15 EStG');
+INSERT INTO gifi (accno,description) VALUES ('4950', 'Rechts- und Beratungskosten');
+INSERT INTO gifi (accno,description) VALUES ('4955', 'Buchführungskosten');
+INSERT INTO gifi (accno,description) VALUES ('4957', 'Abschluß- und Prüfungskosten');
+INSERT INTO gifi (accno,description) VALUES ('4960', 'Mieten für Einrichtungen');
+INSERT INTO gifi (accno,description) VALUES ('4968', 'Gewerbest. zu berücks. Miete f. Einrichtungen §8 GewStG');
+INSERT INTO gifi (accno,description) VALUES ('4969', 'Aufwendungen für Abraum- und Abfallbeseitigung');
+INSERT INTO gifi (accno,description) VALUES ('4970', 'Nebenkosten des Geldverkehrs');
+INSERT INTO gifi (accno,description) VALUES ('4980', 'Betriebsbedarf');
+INSERT INTO gifi (accno,description) VALUES ('4985', 'Werkzeuge und Kleingeräte');
+INSERT INTO gifi (accno,description) VALUES ('4990', 'Kalkulatorischer Unternehmerlohn');
+INSERT INTO gifi (accno,description) VALUES ('4991', 'Kalkulatorische Miete und Pacht');
+INSERT INTO gifi (accno,description) VALUES ('4992', 'Kalkulatorischer Zinsen');
+INSERT INTO gifi (accno,description) VALUES ('4993', 'Kalkulatorische Abschreibungen');
+INSERT INTO gifi (accno,description) VALUES ('4994', 'Kalkulatorische Wagnisse');
+INSERT INTO gifi (accno,description) VALUES ('4995', 'Kalkulatorischer Lohn für unentgeltliche Mitarbeiter');
+INSERT INTO gifi (accno,description) VALUES ('4996', 'Herstellungskosten');
+INSERT INTO gifi (accno,description) VALUES ('4997', 'Verwaltungskosten');
+INSERT INTO gifi (accno,description) VALUES ('4998', 'Vertriebskosten');
+INSERT INTO gifi (accno,description) VALUES ('4999', 'Gegenkonto 49960-49980');
+INSERT INTO gifi (accno,description) VALUES ('7000', 'Unfertige Erzeugnisse, unfertige Leistungen (Bestand)');
+INSERT INTO gifi (accno,description) VALUES ('7050', 'Unfertige Erzeugnisse (Bestand)');
+INSERT INTO gifi (accno,description) VALUES ('7080', 'Unfertige Leistungen (Bestand)');
+INSERT INTO gifi (accno,description) VALUES ('7090', 'In Ausführung befindliche Bauaufträge');
+INSERT INTO gifi (accno,description) VALUES ('7095', 'In Arbeit befindliche Bauaufträge');
+INSERT INTO gifi (accno,description) VALUES ('7100', 'Fertige Erzeugnisse und Waren (Bestand)');
+INSERT INTO gifi (accno,description) VALUES ('7110', 'Fertige Erzeugnisse (Bestand)');
+INSERT INTO gifi (accno,description) VALUES ('7140', 'Fertige Waren (Bestand)');
+INSERT INTO gifi (accno,description) VALUES ('8000', 'Erlöse (zur freien Verfügung)');
+INSERT INTO gifi (accno,description) VALUES ('8100', 'Steuerfreie Umsätze o. VSt-Abzug §4 Nr.8 ff. UStG');
+INSERT INTO gifi (accno,description) VALUES ('8110', 'Sonstige steuerfreie o. VSt-Abzug Umsätze Inland');
+INSERT INTO gifi (accno,description) VALUES ('8120', 'Steuerfreie Umsätze m. VSt-Abzug §4 Nr.1a, 1c, 2-7 UStG');
+INSERT INTO gifi (accno,description) VALUES ('8125', 'Steuerfreie innergem. Lief. §4 Nr.1b UStG');
+INSERT INTO gifi (accno,description) VALUES ('8130', 'Lieferung d. ersten Abnehmers bei innergem. Dreiecksgesch. §25 b Abs. 2 UStG');
+INSERT INTO gifi (accno,description) VALUES ('8135', 'Steuerfreie ig. Lief. v. Neufahrz. an Abn. ohne UST-ID');
+INSERT INTO gifi (accno,description) VALUES ('8140', 'Steuerfreie Umsätze Offshore usw.');
+INSERT INTO gifi (accno,description) VALUES ('8150', 'Sonstige steuerfreie Umsätze Ausland (§4,2-7)');
+INSERT INTO gifi (accno,description) VALUES ('8195', 'Erlöse aus Geldspielautomaten, 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8196', 'Erlöse aus Geldspielautomaten, 15%/16% USt');
+INSERT INTO gifi (accno,description) VALUES ('8197', 'Erlöse aus Geldspielautomaten, 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8200', 'Erlöse');
+INSERT INTO gifi (accno,description) VALUES ('8300', 'Erlöse,  7% USt');
+INSERT INTO gifi (accno,description) VALUES ('8310', 'Erlöse a.i.Inland steuerpfl. EU-Lieferungen, 7% USt');
+INSERT INTO gifi (accno,description) VALUES ('8315', 'Erlöse a.i.Inland steuerpfl. EU-Lieferungen, 15%/16% USt');
+INSERT INTO gifi (accno,description) VALUES ('8320', 'Erlöse a.i. anderen EU-Land steuerpfl. Lieferungen');
+INSERT INTO gifi (accno,description) VALUES ('8330', 'Erlöse a.i.Inland steuerpfl. EU-Lieferungen, 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8335', 'Erlöse a.i.Inland steuerpfl. EU-Lieferungen, 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8339', 'Erlöse a.i. and. EU-Land steuerpfl. sonst. Leist. (Nullreg.)');
+INSERT INTO gifi (accno,description) VALUES ('8340', 'Erlöse, 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8400', 'Erlöse, 15%/16% USt');
+INSERT INTO gifi (accno,description) VALUES ('8410', 'Erlöse, 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8500', 'Provisionserlöse');
+INSERT INTO gifi (accno,description) VALUES ('8504', 'Provisionserlöse steuerfrei (§4 Nr.8ff UStG)');
+INSERT INTO gifi (accno,description) VALUES ('8505', 'Provisionserlöse steuerfrei (§4 Nr.5 UStG)');
+INSERT INTO gifi (accno,description) VALUES ('8506', 'Provisionserlöse,  7% USt');
+INSERT INTO gifi (accno,description) VALUES ('8507', 'Provisionserlöse, 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8508', 'Provisionserlöse, 15%/16% USt');
+INSERT INTO gifi (accno,description) VALUES ('8509', 'Provisionserlöse, 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8520', 'Erlöse Abfallverwertung');
+INSERT INTO gifi (accno,description) VALUES ('8540', 'Erlöse Leergut');
+INSERT INTO gifi (accno,description) VALUES ('8590', 'Verrechnete Sachbezüge (keine Waren)');
+INSERT INTO gifi (accno,description) VALUES ('8591', 'Sachbezüge,   7% USt (Waren)');
+INSERT INTO gifi (accno,description) VALUES ('8595', 'Sachbezüge, 15%/16% USt (Waren)');
+INSERT INTO gifi (accno,description) VALUES ('8596', 'Sachbezüge, 16% USt (Waren)');
+INSERT INTO gifi (accno,description) VALUES ('8597', 'Sachbezüge, 15% USt (Waren)');
+INSERT INTO gifi (accno,description) VALUES ('8600', 'Sonstige Erlöse betrieblich und regelmäßig');
+INSERT INTO gifi (accno,description) VALUES ('8610', 'Verrechnete sonstige Sachbezüge');
+INSERT INTO gifi (accno,description) VALUES ('8611', 'Verrechnete sonstige Sachbezüge 15%/16% USt (z.B. Kfz. Gestellung)');
+INSERT INTO gifi (accno,description) VALUES ('8612', 'Verrechnete sonstige Sachbezüge 16% USt (z.B. Kfz. Gestellung)');
+INSERT INTO gifi (accno,description) VALUES ('8613', 'Verrechnete sonstige Sachbezüge 15% USt (z.B. Kfz. Gestellung)');
+INSERT INTO gifi (accno,description) VALUES ('8614', 'Verrechnete sonstige Sachbezüge, ohne Umsatzsteuer');
+INSERT INTO gifi (accno,description) VALUES ('8625', 'Sonstige Erlöse betrieblich und regelmäßig, steuerfrei');
+INSERT INTO gifi (accno,description) VALUES ('8630', 'Sonstige Erlöse betrieblich und regelmäßig, 7% USt');
+INSERT INTO gifi (accno,description) VALUES ('8640', 'Sonstige Erlöse betrieblich und regelmäßig, 15%/16% USt');
+INSERT INTO gifi (accno,description) VALUES ('8645', 'Sonstige Erlöse betrieblich und regelmäßig, 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8647', 'Sonstige Erlöse betrieblich und regelmäßig, 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8650', 'Erlöse Zinsen und Diskontspesen');
+INSERT INTO gifi (accno,description) VALUES ('8660', 'Erlöse Zinsen und Diskontspesen aus verbundenen Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('8700', 'Erlösschmälerungen');
+INSERT INTO gifi (accno,description) VALUES ('8705', 'Erlösschmälerungen aus steuerfreien Umsätzen §4 Nr. 1a UStG');
+INSERT INTO gifi (accno,description) VALUES ('8710', 'Erlösschmälerungen,  7% USt');
+INSERT INTO gifi (accno,description) VALUES ('8720', 'Erlösschmälerungen, 15%/16% USt');
+INSERT INTO gifi (accno,description) VALUES ('8722', 'Erlösschmälerungen, 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8723', 'Erlösschmälerungen, 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8724', 'Erlösschmälerungen aus steuerfreien innergm. Lieferungen');
+INSERT INTO gifi (accno,description) VALUES ('8725', 'Erlösschmäl. a. im Inland steuerpfl. EU-Lieferungen, 7% USt');
+INSERT INTO gifi (accno,description) VALUES ('8726', 'Erlösschmäl. a. im Inland steuerpfl. EU-Lieferungen, 15%/16% USt');
+INSERT INTO gifi (accno,description) VALUES ('8727', 'Erlösschmäl. a. im anderen EU-Land steuerpfl. Lief.');
+INSERT INTO gifi (accno,description) VALUES ('8728', 'Erlösschmäl. a. im Inland steuerpfl. EU-Lieferungen, 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8729', 'Erlösschmäl. a. im Inland steuerpfl. EU-Lieferungen, 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8730', 'Gewährte Skonti');
+INSERT INTO gifi (accno,description) VALUES ('8731', 'Gewährte Skonti,  7% USt');
+INSERT INTO gifi (accno,description) VALUES ('8735', 'Gewährte Skonti, 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8736', 'Gewährte Skonti, 15% USt');
+INSERT INTO gifi (accno,description) VALUES ('8740', 'Gewährte Boni');
+INSERT INTO gifi (accno,description) VALUES ('8750', 'Gewährte Boni,  7% USt');
+INSERT INTO gifi (accno,description) VALUES ('8760', 'Gewährte Boni, 15%/16% USt');
+INSERT INTO gifi (accno,description) VALUES ('8762', 'Gewährte Boni, 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8764', 'Gewährte Boni, 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8770', 'Gewährte Rabatte');
+INSERT INTO gifi (accno,description) VALUES ('8780', 'Gewährte Rabatte,  7% USt');
+INSERT INTO gifi (accno,description) VALUES ('8790', 'Gewährte Rabatte, 15%/16% USt');
+INSERT INTO gifi (accno,description) VALUES ('8792', 'Gewährte Rabatte, 16% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8794', 'Gewährte Rabatte, 15% Ust');
+INSERT INTO gifi (accno,description) VALUES ('8800', 'Erlöse aus Anlagenverkäufen');
+INSERT INTO gifi (accno,description) VALUES ('8801', 'Erlöse aus Anlagenverkäufen 15%/16% USt (bei Buchverlust)');
+INSERT INTO gifi (accno,description) VALUES ('8810', 'Erlöse aus Anlagenverkäufen 16% USt (bei Buchverlust)');
+INSERT INTO gifi (accno,description) VALUES ('8815', 'Erlöse aus Anlagenverkäufen 15% USt (bei Buchverlust)');
+INSERT INTO gifi (accno,description) VALUES ('8820', 'Erlöse aus Anlagenverkäufen 15%/16% USt (bei Buchgewinn)');
+INSERT INTO gifi (accno,description) VALUES ('8829', 'Erlöse aus Anlagenverkäufen (bei Buchgewinn)');
+INSERT INTO gifi (accno,description) VALUES ('8830', 'Erlöse aus Anlagenverkäufen 16% USt (bei Buchgewinn)');
+INSERT INTO gifi (accno,description) VALUES ('8835', 'Erlöse aus Anlagenverkäufen 15% USt (bei Buchgewinn)');
+INSERT INTO gifi (accno,description) VALUES ('8840', 'Erträge aus Kursdifferenzen');
+INSERT INTO gifi (accno,description) VALUES ('8900', 'Eigenverbrauch');
+INSERT INTO gifi (accno,description) VALUES ('8905', 'Entnahme Gegenstände ohne USt');
+INSERT INTO gifi (accno,description) VALUES ('8908', 'Entnahme von Gegenstände, 16% USt §1 Abs.1 Nr.2a UStG');
+INSERT INTO gifi (accno,description) VALUES ('8909', 'Entnahme von Gegenstände, 15% USt §1 Abs.1 Nr.2a UStG');
+INSERT INTO gifi (accno,description) VALUES ('8910', 'Entnahme von Gegenstände, 15%/16% USt §1 Abs.1 Nr.2a UStG');
+INSERT INTO gifi (accno,description) VALUES ('8915', 'Entnahme von Gegenstände, 7% USt §1 Abs.1 Nr.2a UStG');
+INSERT INTO gifi (accno,description) VALUES ('8920', 'Entnahme v. sonst. Leist., 15%/16% USt §1 A.1 Nr.2b UStG');
+INSERT INTO gifi (accno,description) VALUES ('8930', 'Entnahme v. sonst. Leist., 7% USt §1 A.1 Nr.2b UStG');
+INSERT INTO gifi (accno,description) VALUES ('8937', 'Entnahme v. sonst. Leist., 16% USt §1 A.1 Nr.2b UStG');
+INSERT INTO gifi (accno,description) VALUES ('8938', 'Entnahme v. sonst. Leist., 15% USt §1 A.1 Nr.2b UStG');
+INSERT INTO gifi (accno,description) VALUES ('8939', 'Entnahme v. sonst. Leist., ohne USt §1 A.1 Nr.2b UStG');
+INSERT INTO gifi (accno,description) VALUES ('8940', 'Eigenverbr., 15%/16% Ust  §4 A.1 Nr.5 1-7, A.7 EStG');
+INSERT INTO gifi (accno,description) VALUES ('8941', 'Eigenverbr., 7% Ust §4 A.1 Nr.5 1-7, A.7 EStG');
+INSERT INTO gifi (accno,description) VALUES ('8942', 'Eigenverbr., 16% Ust  §4 A.1 Nr.5 1-7, A.7 EStG');
+INSERT INTO gifi (accno,description) VALUES ('8943', 'Eigenverbr., 15% Ust  §4 A.1 Nr.5 1-7, A.7 EStG');
+INSERT INTO gifi (accno,description) VALUES ('8944', 'Eigenverbr., ohne Ust §4 A.1 Nr.5 1-7, A.7 EStG');
+INSERT INTO gifi (accno,description) VALUES ('8945', 'Unentgeltl. Leist. v. Ges. an Ges., 15%/16% USt §1A.1 Nr.3 UStG');
+INSERT INTO gifi (accno,description) VALUES ('8946', 'Unentgeltl. Leist. v. Ges. an Ges., 7% USt §1A.1 Nr.3 UStG');
+INSERT INTO gifi (accno,description) VALUES ('8947', 'Unentgeltl. Leist. v. Ges. an Ges., 16% USt §1A.1 Nr.3 UStG');
+INSERT INTO gifi (accno,description) VALUES ('8948', 'Unentgeltl. Leist. v. Ges. an Ges., 15% USt §1A.1 Nr.3 UStG');
+INSERT INTO gifi (accno,description) VALUES ('8949', 'Unentgeltl. Leist. v. Ges. an Ges., ohne USt §1A.1 Nr.3 UStG');
+INSERT INTO gifi (accno,description) VALUES ('8950', 'Nicht steuerbare Umsätze');
+INSERT INTO gifi (accno,description) VALUES ('8955', 'Umsatzsteuervergütungen');
+INSERT INTO gifi (accno,description) VALUES ('8960', 'Bestandsveränd. - unfertige Erzeugnisse');
+INSERT INTO gifi (accno,description) VALUES ('8970', 'Bestandsveränd. - unfertige Leistungen');
+INSERT INTO gifi (accno,description) VALUES ('8975', 'Bestandsveränd. - in Ausführung befindliche Bauaufträge');
+INSERT INTO gifi (accno,description) VALUES ('8977', 'Bestandsveränd. - in Arbeit befindliche Aufträge');
+INSERT INTO gifi (accno,description) VALUES ('8980', 'Bestandsveränd. - fertige Erzeugnisse');
+INSERT INTO gifi (accno,description) VALUES ('8990', 'Bestandsveränd. - andere aktivierte Eigenleistungen');
+INSERT INTO gifi (accno,description) VALUES ('9000', 'Saldenvorträge Sachkonten');
+INSERT INTO gifi (accno,description) VALUES ('9008', 'Saldenvorträge Debitoren');
+INSERT INTO gifi (accno,description) VALUES ('9009', 'Saldenvorträge Kreditoren');
+INSERT INTO gifi (accno,description) VALUES ('9060', 'Offene Posten aus 1990');
+INSERT INTO gifi (accno,description) VALUES ('9085', 'Offene Posten aus 1985');
+INSERT INTO gifi (accno,description) VALUES ('9086', 'Offene Posten aus 1986');
+INSERT INTO gifi (accno,description) VALUES ('9087', 'Offene Posten aus 1987');
+INSERT INTO gifi (accno,description) VALUES ('9088', 'Offene Posten aus 1988');
+INSERT INTO gifi (accno,description) VALUES ('9089', 'Offene Posten aus 1989');
+INSERT INTO gifi (accno,description) VALUES ('9090', 'Summenvortragskonto');
+INSERT INTO gifi (accno,description) VALUES ('9091', 'Offene Posten aus 1991');
+INSERT INTO gifi (accno,description) VALUES ('9092', 'Offene Posten aus 1992');
+INSERT INTO gifi (accno,description) VALUES ('9093', 'Offene Posten aus 1993');
+INSERT INTO gifi (accno,description) VALUES ('9094', 'Offene Posten aus 1994');
+INSERT INTO gifi (accno,description) VALUES ('9095', 'Offene Posten aus 1995');
+INSERT INTO gifi (accno,description) VALUES ('9096', 'Offene Posten aus 1996');
+INSERT INTO gifi (accno,description) VALUES ('9097', 'Offene Posten aus 1997');
+INSERT INTO gifi (accno,description) VALUES ('9098', 'Offene Posten aus 1998');
+INSERT INTO gifi (accno,description) VALUES ('9100', 'Saldovortragskonto der Statistikkonten');
+INSERT INTO gifi (accno,description) VALUES ('9101', 'Verkaufstage');
+INSERT INTO gifi (accno,description) VALUES ('9102', 'Anzahl der Barkunden');
+INSERT INTO gifi (accno,description) VALUES ('9103', 'Beschäftigte Personen');
+INSERT INTO gifi (accno,description) VALUES ('9104', 'Unbezahlte Personen');
+INSERT INTO gifi (accno,description) VALUES ('9105', 'Verkaufskräfte');
+INSERT INTO gifi (accno,description) VALUES ('9106', 'Geschäftsraum qm');
+INSERT INTO gifi (accno,description) VALUES ('9107', 'Verkaufsraum qm');
+INSERT INTO gifi (accno,description) VALUES ('9108', 'Veränderungsrate positiv');
+INSERT INTO gifi (accno,description) VALUES ('9109', 'Veränderungsrate negativ');
+INSERT INTO gifi (accno,description) VALUES ('9110', 'Plan-WE (in Prozent)');
+INSERT INTO gifi (accno,description) VALUES ('9120', 'Erweiterungsinvestitionen');
+INSERT INTO gifi (accno,description) VALUES ('9135', 'Auftragseingang im Geschäftsjahr');
+INSERT INTO gifi (accno,description) VALUES ('9140', 'Auftragsbestand');
+INSERT INTO gifi (accno,description) VALUES ('9190', 'Gegenkonto für statistische Mengeneinheiten Konten 91010-91190');
+INSERT INTO gifi (accno,description) VALUES ('9199', 'Gegenkonto zu 91200, 91350-91400');
+INSERT INTO gifi (accno,description) VALUES ('9200', 'Beschäftigte Personen');
+INSERT INTO gifi (accno,description) VALUES ('9209', 'Gegenkonto zu 92000');
+INSERT INTO gifi (accno,description) VALUES ('9210', 'Produktive Löhne');
+INSERT INTO gifi (accno,description) VALUES ('9219', 'Gegenkonto zu 92100');
+INSERT INTO gifi (accno,description) VALUES ('9230', 'Baukostenzuschüsse');
+INSERT INTO gifi (accno,description) VALUES ('9232', 'Investitionszulagen');
+INSERT INTO gifi (accno,description) VALUES ('9234', 'Investitionszuschüsse');
+INSERT INTO gifi (accno,description) VALUES ('9239', 'Gegenkonto zu 92300-92380');
+INSERT INTO gifi (accno,description) VALUES ('9240', 'Investitionsverbindlichkeiten bei den Leistungsverbindlichkeiten');
+INSERT INTO gifi (accno,description) VALUES ('9244', 'Gegenkonto zu 92400');
+INSERT INTO gifi (accno,description) VALUES ('9245', 'Forderungen aus Anlagenverkäufen bei den sonstigen Vermögensgegenst.');
+INSERT INTO gifi (accno,description) VALUES ('9249', 'Gegenkonto zu 92450');
+INSERT INTO gifi (accno,description) VALUES ('9250', 'Eigenkapitalersetzende Gesellschafterdarlehen');
+INSERT INTO gifi (accno,description) VALUES ('9255', 'Ungesicherte Gesellschafterdarlehen mit Restlaufzeit > 5 Jahre');
+INSERT INTO gifi (accno,description) VALUES ('9259', 'Gegenkonto zu 92500-92580');
+INSERT INTO gifi (accno,description) VALUES ('9260', 'Kurzfristige Rückstellungen');
+INSERT INTO gifi (accno,description) VALUES ('9262', 'Mittelfristige Rückstellungen');
+INSERT INTO gifi (accno,description) VALUES ('9264', 'Langfristige Rückstellungen');
+INSERT INTO gifi (accno,description) VALUES ('9269', 'Gegenkonto zu 92600-92680');
+INSERT INTO gifi (accno,description) VALUES ('9270', 'Gegenkonto zu 92710-92780');
+INSERT INTO gifi (accno,description) VALUES ('9271', 'Verb. a. d. Begebung u. Übertragung v. Wechseln');
+INSERT INTO gifi (accno,description) VALUES ('9272', 'Verb. a. d. Begebung u. Übertr. v. Wechseln gg. verb. U.');
+INSERT INTO gifi (accno,description) VALUES ('9273', 'Verb. a. Bürgsch., Wechsel- u. Scheckbürgsch.');
+INSERT INTO gifi (accno,description) VALUES ('9274', 'Verb. a. Bürgsch., Wechsel- u. Scheckbürgsch. gg. verb. U.');
+INSERT INTO gifi (accno,description) VALUES ('9275', 'Verb. aus Gewährleistungsverträgen');
+INSERT INTO gifi (accno,description) VALUES ('9276', 'Verb. aus Gewährleistungsverträgen gg. verbund. Untern.');
+INSERT INTO gifi (accno,description) VALUES ('9277', 'Haftung a. d. Best. von Sicherheiten für fremde Verbindl.');
+INSERT INTO gifi (accno,description) VALUES ('9278', 'Haftung a.d. Best. v. Sicherh. f. fr. Verbindl. gg. verb. U.');
+INSERT INTO gifi (accno,description) VALUES ('9280', 'Gegenkonto zu 92810-92840');
+INSERT INTO gifi (accno,description) VALUES ('9281', 'Verpflichtungen aus Miet- und Leasingverträgen');
+INSERT INTO gifi (accno,description) VALUES ('9282', 'Verpflichtungen aus Miet- und Leasingverträgen gg. verb. Unternehm.');
+INSERT INTO gifi (accno,description) VALUES ('9283', 'Andere Verpflichtungen gem. §285 Nr.3 HGB');
+INSERT INTO gifi (accno,description) VALUES ('9284', 'Andere Verpflichtungen gem. §285 Nr.3 HGB gg. verb. Unternehmen');
+INSERT INTO gifi (accno,description) VALUES ('9410', 'Aussteh. Einl. §26 A.3 DMBilG nicht eingef. (Aktivausw.)');
+INSERT INTO gifi (accno,description) VALUES ('9411', 'Aussteh. Einl. §26 A.3 DMBilG eingef. (Aktivausweis)');
+INSERT INTO gifi (accno,description) VALUES ('9413', 'Aufw. f. Ingangs. u. Erw. d. Gesch.Betr. §31A.1 Nr.2 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9415', 'Nichtentgeltl. erw. immat. Verm.Gegenst. §31A.1 Nr.1 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9416', 'Nutzungsrechte gem. § 9 Abs.3 Satz 2 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9420', 'Ford. gg. verb. Untern. a. Ausgleichsverb. gem. §25 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9421', 'Ford. gg. verb. U. a. Ausgl.Verb. §25 DMBilG Restl. b. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('9422', 'Ford. gg. verb. U. a. Ausgl.Verb. §25 DMBilG Restl. gr. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('9426', 'Eingeforderte Einlagen §26 Abs. 3 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9427', 'Ausgleichsforderungen §24 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9428', 'Ausgleichsford. §24 DMBilG - Restlaufz. bis 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('9429', 'Ausgleichsford.  §24 DMBilG - Restlaufz. größer 1 Jahr');
+INSERT INTO gifi (accno,description) VALUES ('9430', 'Ford. nach dem VermG  §7 Abs. 6 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9431', 'Ford. nach dem VermG  §7 A.6 DMBilG - Restl. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('9432', 'Ford. nach dem VermG  §7 A.6 DMBilG - Restl. gr. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('9433', 'Vermögensvorteile §31 Abs.1 Nr. 3 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9434', 'Kapitalentwertungskonto');
+INSERT INTO gifi (accno,description) VALUES ('9435', 'Kapitalentwertungskonto §28 Abs.1 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9436', 'Kapitalentwertungskonto §26 Abs.4 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9438', 'Sonderverlustkonto aus Rückstellungen §17 Abs.4 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9440', 'Beteiligunsentwertungskonto §24 Abs.5 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9445', 'Vorläufige Gewinnrücklage §31 Abs.1 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9446', 'Sonderrücklage §7 Abs.6 Satz 2 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9447', 'Sonderrücklage §17 Abs.4 Satz 3 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9448', 'Sonderrücklage §24 Abs. 5 Satz 3 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9449', 'Sonderrücklage §27 Abs. 2 Satz 3 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9450', 'Rückst. f. Umweltbeeinträchtigung §17 A.2a DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9451', 'Nachrangiges Kapital §16 Abs. 3 Satz 2 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9453', 'Berichtig. v. Wertans. §36 DMBilG - Erhöhung d. Aktiva');
+INSERT INTO gifi (accno,description) VALUES ('9454', 'Berichtig. v. Wertans. §36 DMBilG - Verm. d. Aktivp.');
+INSERT INTO gifi (accno,description) VALUES ('9455', 'Berichtig. v. Wertans. §36 DMBilG - Erhöhung d. Passiva');
+INSERT INTO gifi (accno,description) VALUES ('9456', 'Berichtig. v. Wertans. §36 DMBilG - Verm. d. Passivp.');
+INSERT INTO gifi (accno,description) VALUES ('9457', 'Verb. gg. verb. Untern. a. Ausgleichsford. gem. §24 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9458', 'Verb. gg. verb. U. a. Ausgl.Ford. §24 DMBilG Restl. b. 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('9459', 'Verb. gg. verb. U. a. Ausgl.Ford. §24 DMBilG Restl. 1 b. 5 J');
+INSERT INTO gifi (accno,description) VALUES ('9460', 'Verb. gg. verb. U. a. Ausgl.Ford. §24 DMBilG Restl. gr. 5 J');
+INSERT INTO gifi (accno,description) VALUES ('9462', 'Verb. gg. verb. Untern. §26 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9463', 'Verb. gg. verb. Untern. §26 DMBilG - Restl. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('9464', 'Verb. gg. verb. Untern. §26 DMBilG - Restl. 1 bis 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('9465', 'Verb. gg. verb. Untern. §26 DMBilG - Restl. größer 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('9467', 'Ausgleichsverbindlichkeiten §25 Abs.1 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9468', 'Ausgleichsverb. §25 Abs.1 DMBilG - Restlaufz. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('9469', 'Ausgleichsverb. §25 A.1 DMBilG - Restlaufz. 1 bis 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('9470', 'Ausgleichsverb. §25 A.1 DMBilG - Restlaufz. größer 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('9472', 'Verb. nach dem VermG §7 Abs.6 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9473', 'Verb. nach dem VermG §7 A.6 DMBilG - Restl. bis 1 J.');
+INSERT INTO gifi (accno,description) VALUES ('9474', 'Verb. nach dem VermG §7 A.6 DMBilG - Restl. 1 bis 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('9475', 'Verb. nach dem VermG §7 A.6 DMBilG - Restl. größer 5 J.');
+INSERT INTO gifi (accno,description) VALUES ('9476', 'Verb. aus Rückzahlungsverpfl. 17 Abs.4a DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9477', 'Verb. a. Rückzahlg.Verpfl. - Restl. b. 1 J. §17 A.4a DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9478', 'Verb. a. Rückzahlg.Verpfl. - Restl. 1 b. 5 J. §17A.4a DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9479', 'Verb. a. Rückzahlg.Verpfl. - Restl. gr. 5 J. §17 A.4a DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9480', 'Auflösung Kapitalentwertungskonto §28 A.2 Satz 4 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9481', 'Entnahmen a. vorläufigen Gewinnrücklagen §31 A.6 DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9482', 'Entnahmen a. Sonderrückl. zum Ausgleich von Verlusten');
+INSERT INTO gifi (accno,description) VALUES ('9486', 'Abschreibungen auf Ausgleichsforderungen DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9487', 'Erträge aus der Auflösung von Rückstellungen DMBilG');
+INSERT INTO gifi (accno,description) VALUES ('9500', 'Anteil für Konto 09000-09090');
+INSERT INTO gifi (accno,description) VALUES ('9510', 'Anteil für Konto 09100-09190');
+INSERT INTO gifi (accno,description) VALUES ('9520', 'Anteil für Konto 09200-09290');
+INSERT INTO gifi (accno,description) VALUES ('9530', 'Anteil für Konto 08300-08390');
+INSERT INTO gifi (accno,description) VALUES ('9540', 'Anteil für Konto 08100-08190');
+INSERT INTO gifi (accno,description) VALUES ('9570', 'Anteil für Konto 08700-08790');
+INSERT INTO gifi (accno,description) VALUES ('9580', 'Anteil für Konto 08800-08890');
+INSERT INTO gifi (accno,description) VALUES ('9590', 'Anteil für Konto 08900-08990');
+INSERT INTO gifi (accno,description) VALUES ('9600', 'Name des Gesellschafters (Vollhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9610', 'Tätigkeitsvergütung (Vollhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9620', 'Tantieme (Vollhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9630', 'Darlehensverzinsung (Vollhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9640', 'Gebrauchsüberlassung (Vollhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9650', 'Sonstige Vergütungen (Vollhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9690', 'Restanteil (Vollhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9700', 'Name des Gesellschafters (Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9710', 'Tätigkeitsvergütung (Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9720', 'Tantieme (Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9730', 'Darlehensverzinsung (Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9740', 'Gebrauchsüberlassung (Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9750', 'Sonstige Vergütungen (Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9790', 'Restanteil (Teilhafter)');
+INSERT INTO gifi (accno,description) VALUES ('9890', 'Statistisches Konto für passive Lohnveredelung');
+INSERT INTO gifi (accno,description) VALUES ('9899', 'Gegenkonto zu 9890');
diff --git a/sql-ledger/sql/Italy-chart.sql b/sql-ledger/sql/Italy-chart.sql
new file mode 100644 (file)
index 0000000..0af8e9f
--- /dev/null
@@ -0,0 +1,179 @@
+--
+-- Chart of Accounts for Italy
+--
+-- From: Luca Venturini <luca@yepa.com>
+-- 9 Oct 2001
+--
+-- ('2001101'5 Conto ('6470005' diventa tassa (negativa)
+-- ('2001102'5 IVA su acquisti diventa Iva su acq. (20%)
+-- ('2001102'5 Introdotto un conto per ogni aliquota IVA
+-- ('2001102'7 Modificato numero di conto per la Ritenuta d'acconto
+-- ('2001103'1 Inseriti Fornitore-test e Consulente-test
+-- ('2001111'5 Invertito i ruoli di ('6470005' e ('6470010' (erano sbagliati)
+-- ('2001111'5 Eliminata l'applicabilita' della RA al cliente test
+-- ('2001112'0 Aggiunto IC_expense al conto ('7005005' (mancava un conto di default per i servizi)
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2010000','COSTI DI RICERCA, DI SVILUPPO E DI PUBBLICITA\'','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2010005','Spese di ricerca e di sviluppo','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2010010','Spese di pubblicita\'','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2015000','DIRITTI DI BREV. IND. E DIRITTI DI UTILIZZ DELLE OPERE DELL\'INGEGNO','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2015005','Brevetti','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2020005','Concessioni, licenze e diritti simili','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2025005','Avviamento','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2245000','TERRENI E FABBRICATI','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2245010','Fabbricati civili','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2250000','IMPIANTI E MACCHINARI','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2250005','Impianti generici','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2255000','ATTREZZATURE INDUSTRIALI E COMMERCIALI','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2255005','Attrezzature','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2255010','Mobili','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2255015','Macchine d\'ufficio','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2255025','Autovetture','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3005000','RIMANENZE MATERIE PRIME, SUSSIDIARIE E DI CONSUMO','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3005005','Rimanenze materie prime','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3020000','RIMANENZE PRODOTTI FINITI E MERCI','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3020005','Rimanenze prodotti finiti','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4001000','CREDITI VERSO CL. PER FATT. EM. ESIGIBILI ENTRO L\'ESER. SUCC.','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4001001','Crediti verso clienti per fatture emesse','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4064000','CREDITI VERSO ALTRI - CREDITI D\'IMPOSTA','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4064005','IRPEF acconto','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4064020','IRPEG acconto','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4064800','Credito verso erario per IVA','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4400000','DISPONIBILITA\' LIQUIDE','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4480105','Banca ...c/c','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4480400','Assegni','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4480500','Cassa e valori','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5005000','CAPITALE','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5005005','Capitale sociale','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5005010','Versamenti in conto capitale','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5020000','RISERVA LEGALE','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5020005','Riserva legale','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5080000','UTILI (PERDITE) PORTATI A NUOVO','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5080005','Utili esercizi precedenti','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5080010','Perdite esercizi precedenti','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5090000','UTILE (PERDITA) DELL\'ESERCIZIO','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5090005','Utile dell\'esercizio','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5090010','Perdita dell\'esercizio','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6200000','TRATTAMENTO DI FINE RAPPORTO DI LAVORO SUBORDINATO','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6220005','Trattamento di fine rapporto di lavoro subordinato','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6220010','Anticipazioni erogate su trattamento di fine rapporto di lavoro subordinato','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6435000','DEBITI VERSO BANCHE ESIGIBILI ENTRO ES. SUCC.','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6435005','Banca di ... c/c','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6436000','DEBITI VERSO BANCHE ESIGIBILI OLTRE ES. SUCC.','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6436005','Mutuo banca di ...','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6450000','DEBITI VERSO FORNITORI FATT. RICEVUTE ESIGIBILI ENTRO ES. SUCC.','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6450001','Debiti verso fornitori per fatture ricevute','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6470000','DEBITI TRIBUTARI','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6470005','IRPEF dipendenti','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6470010','IRPEF terzi','A','','L','AP_tax:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6470015','IVA da versare','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6470020','IVA in sospeso','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6470025','IRPEG sul reddito d\'esercizio','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6470030','ILOR sul reddito d\'esercizio','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6470050','Imposta patrimoniale','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6475000','DEBITI VERSO ISTITUTI PREV. ESIGIBILI ENTRO ES. SUCC.','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6475005','INPS','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6475010','INAIL','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6475020','Servizio sanitario nazionale (S.S.N.)','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6475025','ENASARCO','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480000','ALTRI DEBITI - IVA C/ERARIO','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480003','IVA su acquisti (4%)','A','','L','AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480004','IVA su acquisti (10%)','A','','L','AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480005','IVA su acquisti (20%)','A','','L','AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480006','IVA a credito su acquisti U.E.','A','','L','AP_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480010','IVA su fatture emesse','A','','L','AR_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480011','IVA a debito su acquisti U.E.','A','','L','AR_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480015','IVA su corrispettivi','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480020','IVA versata','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480025','IVA acconto','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480030','IVA a credito','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480035','IVA ulteriore detrazione','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480040','Crediti d\'imposta diversi','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480045','IVA pro-rata indetraibile','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480050','IVA da contabilità separata','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6480055','IVA c/riepilogativo','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6600000','RATEI E RISCONTI PASSIVI','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6690005','Ratei passivi','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('6692005','Risconti passivi','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7005000','COSTI PER MATERIE PRIME, SUSSIDIARIE, DI CONSUMO E DI MERCI','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7005005','Materie prime','A','','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7005015','Merci destinate alla rivendita','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7005020','Materiali di consumo destinati alla produzione','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7005030','Materiali di pulizia','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7005035','Combustibile per riscaldamento','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7005040','Cancelleria','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7005045','Materiale pubblicitario','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7005050','Carburanti e lubrificanti','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7025000','SPESE DI GESTIONE','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7025005','Energia elettrica','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7025015','Spese telefoniche','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7025025','Spese pubblicità/propaganda','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7025030','Spese di assicurazione','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7025040','Pulizia locali','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7025055','Viaggi e soggiorni amministratori','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7025060','Spese di rappresentanza per servizi interamente detraibili','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7025065','Altre spese di rappresentanza','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7025100','Altri servizi','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7028000','CARBURANTI E LUBRIFICANTI PER AUTOTRAZIONE','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7028005','Carburanti e lubrificanti autovetture','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7028010','Carburanti e lubrificanti autocarri etc.','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7030000','COMPENSI PROFESSIONALI','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7030005','Consulenza fiscale e tributaria','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7030015','Consulenza legale','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7030030','Compenso amministratori','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7035000','COSTI PER GODIMENTO BENI DI TERZI','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7035005','Fitti passivi','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7035050','Canoni di leasing','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7040000','COSTI PER IL PERSONALE','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7040005','Salari e stipendi','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7040010','Oneri sociali INPS','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7040015','Oneri sociali INAIL','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7040020','Oneri sociali C.E.','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7043000','AMMORTAMENTI E SVALUTAZIONI','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7043005','Ammortamenti immobilizzazioni immateriali','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7043100','Ammortamenti immobilizzazioni materiali','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7056000','ONERI DIVERSI DI GESTIONE','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7056010','Imposta di registro, bolli ,CC.GG., etc.','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7056015','Imposta camerale','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7056025','Tributi locali diversi','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7056040','Tassa possesso autoveicoli','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7260000','INTERESSI E ONERI FINANZIARI','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7260020','Interessi passivi bancari','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7260025','Interessi passivi mutui','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7875000','IMPOSTE SUL REDDITO DELL\'ESERCIZIO','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7875005','IRPEG corrente','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('7875020','IRPEG differita','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8005000','RICAVI DELLE VENDITE','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8005005','Ricavi cessione beni','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8015000','RICAVI DELLE PRESTAZIONI','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8015005','Ricavi per prestazioni a terzi','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8015015','Noleggio impianti e macchinari','A','','I','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8041000','INCREMENTI IMMOBILIZZAZIONI IMMATERIALI','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8041005','Brevetti','A','','I','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8041010','Spese di costituzione società','A','','I','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8041020','Spese pubblicità e propaganda','A','','I','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8045000','ALTRI RICAVI E PROVENTI','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('8045001','Cessione di materie prime, sussidiarie e semilavorati','A','','I','AR_amount');
+--
+-- foreign exchange gain / loss
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9990000','Foreign Exchange Gain','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('9990010','Foreign Exchange Loss','A','','E','');
+--
+-- insert taxes
+--
+--Ritenuta d'acconto
+INSERT INTO tax (chart_id, rate) VALUES ((SELECT id FROM chart WHERE accno = '6470010'), -0.2);
+--IVA Acquisti 4%
+INSERT INTO tax (chart_id, rate) VALUES ((SELECT id FROM chart WHERE accno = '6480003'), 0.04);
+--IVA Acquisti 10%
+INSERT INTO tax (chart_id, rate) VALUES ((SELECT id FROM chart WHERE accno = '6480004'), 0.1);
+--IVA Acquisti 20%
+INSERT INTO tax (chart_id, rate) VALUES ((SELECT id FROM chart WHERE accno = '6480005'), 0.2);
+--IVA Fatture Emesse
+INSERT INTO tax (chart_id, rate) VALUES ((SELECT id FROM chart WHERE accno = '6480010'), 0.2);
+--IVA su corrispettivi
+INSERT INTO tax (chart_id, rate) VALUES ((SELECT id FROM chart WHERE accno = '6480015'), 0.2);
+--
+-- update defaults
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '3020005'), income_accno_id = (select id from chart where accno = '8005005'), expense_accno_id = (select id from chart where accno = '7005005'), fxgain_accno_id = (select id from chart where accno = '9990000'), fxloss_accno_id = (select id from chart where accno = '9990010'), invnumber = '20010000', sonumber = '1000', ponumber = '1000', curr = 'EUR', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/Oracle-indices.sql b/sql-ledger/sql/Oracle-indices.sql
new file mode 100644 (file)
index 0000000..e55915b
--- /dev/null
@@ -0,0 +1,57 @@
+create index acc_trans_trans_id_key on acc_trans (trans_id);
+create index acc_trans_chart_id_key on acc_trans (chart_id);
+create index acc_trans_transdate_key on acc_trans (transdate);
+create index acc_trans_source_key on acc_trans (source);
+create index ap_id_key on ap (id);
+create index ap_transdate_key on ap (transdate);
+create index ap_invnumber_key on ap (invnumber);
+create index ap_ordnumber_key on ap (ordnumber);
+create index ap_vendor_id_key on ap (vendor_id);
+create index ap_employee_id_key on ap (employee_id);
+create index ar_id_key on ar (id);
+create index ar_transdate_key on ar (transdate);
+create index ar_invnumber_key on ar (invnumber);
+create index ar_ordnumber_key on ar (ordnumber);
+create index ar_customer_id_key on ar (customer_id);
+create index ar_employee_id_key on ar (employee_id);
+create index assembly_id_key on assembly (id);
+create index chart_id_key on chart (id);
+create unique index chart_accno_key on chart (accno);
+create index chart_category_key on chart (category);
+create index chart_link_key on chart (link);
+create index chart_gifi_accno_key on chart (gifi_accno);
+create index customer_id_key on customer (id);
+create index customer_customer_id_key on customertax (customer_id);
+create index customer_customernumber_key on customer (customernumber);
+create index customer_name_key on customer (name);
+create index customer_contact_key on customer (contact);
+create index employee_id_key on employee (id);
+create unique index employee_login_key on employee (login);
+create index employee_name_key on employee (name);
+create index exchangerate_ct_key on exchangerate (curr, transdate);
+create unique index gifi_accno_key on gifi (accno);
+create index gl_id_key on gl (id);
+create index gl_transdate_key on gl (transdate);
+create index gl_reference_key on gl (reference);
+create index gl_description_key on gl (description);
+create index gl_employee_id_key on gl (employee_id);
+create index invoice_id_key on invoice (id);
+create index invoice_trans_id_key on invoice (trans_id);
+create index makemodel_parts_id_key on makemodel (parts_id);
+create index oe_id_key on oe (id);
+create index oe_transdate_key on oe (transdate);
+create index oe_ordnumber_key on oe (ordnumber);
+create index oe_employee_id_key on oe (employee_id);
+create index orderitems_trans_id_key on orderitems (trans_id);
+create index parts_id_key on parts (id);
+create index parts_partnumber_key on parts (partnumber);
+create index parts_description_key on parts (description);
+create index partstax_parts_id_key on partstax (parts_id);
+create index vendor_id_key on vendor (id);
+create index vendor_name_key on vendor (name);
+create index vendor_vendornumber_key on vendor (vendornumber);
+create index vendor_contact_key on vendor (contact);
+create index vendortax_vendor_id_key on vendortax (vendor_id);
+create index shipto_trans_id_key on shipto (trans_id);
+create index project_id_key on project (id);
+create index partsgroup_id_key on partsgroup (id);
diff --git a/sql-ledger/sql/Oracle-tables.sql b/sql-ledger/sql/Oracle-tables.sql
new file mode 100644 (file)
index 0000000..d2bf7c7
--- /dev/null
@@ -0,0 +1,388 @@
+-- Oracle-tables.sql
+-- Paulo Rodrigues: added functions and triggers, Oct. 31, 2001
+-- 
+-- Modified for use with SL 2.0 and Oracle 9i2, Dec 13, 2002
+--
+ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
+--
+CREATE SEQUENCE id START WITH 10000 INCREMENT BY 1 MAXVALUE 2147483647 MINVALUE 1  CACHE 2;
+SELECT ID.NEXTVAL FROM DUAL;
+--
+CREATE TABLE makemodel (
+  parts_id INTEGER,
+  name VARCHAR2(100)
+);
+--
+CREATE TABLE gl (
+  id INTEGER,
+  reference VARCHAR2(50),
+  description VARCHAR2(100),
+  transdate DATE DEFAULT SYSDATE,
+  employee_id INTEGER,
+  notes VARCHAR2(4000) 
+);
+--
+CREATE TABLE chart (
+  id INTEGER,
+  accno VARCHAR2(20) NOT NULL,
+  description VARCHAR2(100),
+  charttype CHAR(1) DEFAULT 'A',
+  category CHAR(1),
+  link VARCHAR2(100),
+  gifi_accno VARCHAR2(20)
+);
+--
+CREATE TABLE gifi (
+  accno VARCHAR2(20),
+  description VARCHAR2(100)
+);
+--
+CREATE TABLE defaults (
+  inventory_accno_id INTEGER,
+  income_accno_id INTEGER,
+  expense_accno_id INTEGER,
+  fxgain_accno_id INTEGER,
+  fxloss_accno_id INTEGER,
+  invnumber VARCHAR2(30),
+  sonumber VARCHAR2(30),
+  yearend VARCHAR2(5),
+  weightunit VARCHAR2(5),
+  businessnumber VARCHAR2(30),
+  version VARCHAR2(8),
+  curr VARCHAR2(500),
+  closedto DATE,
+  revtrans CHAR(1) DEFAULT '0',
+  ponumber VARCHAR2(30)
+);
+INSERT INTO defaults (version) VALUES ('2.0.8');
+--
+CREATE TABLE acc_trans (
+  trans_id INTEGER,
+  chart_id INTEGER,
+  amount FLOAT,
+  transdate DATE DEFAULT SYSDATE,
+  source VARCHAR2(20),
+  cleared CHAR(1) DEFAULT '0',
+  fx_transaction CHAR(1) DEFAULT '0',
+  project_id INTEGER
+);
+--
+CREATE TABLE invoice (
+  id INTEGER,
+  trans_id INTEGER,
+  parts_id INTEGER,
+  description VARCHAR2(4000),
+  qty FLOAT,
+  allocated FLOAT,
+  sellprice FLOAT,
+  fxsellprice FLOAT,
+  discount FLOAT,
+  assemblyitem CHAR(1) DEFAULT '0',
+  unit VARCHAR2(5),
+  project_id INTEGER,
+  deliverydate DATE
+);
+--
+CREATE TABLE vendor (
+  id INTEGER,
+  name VARCHAR2(35),
+  addr1 VARCHAR2(35),
+  addr2 VARCHAR2(35),
+  addr3 VARCHAR2(35),
+  addr4 VARCHAR2(35),
+  contact VARCHAR2(35),
+  phone VARCHAR2(20),
+  fax VARCHAR2(20),
+  email VARCHAR2(50),
+  notes VARCHAR2(4000),
+  terms INTEGER DEFAULT 0,
+  taxincluded CHAR(1),
+  vendornumber VARCHAR2(40),
+  cc VARCHAR2(50),
+  bcc VARCHAR2(50)
+);
+--
+CREATE TABLE customer (
+  id INTEGER,
+  name VARCHAR2(35),
+  addr1 VARCHAR2(35),
+  addr2 VARCHAR2(35),
+  addr3 VARCHAR2(35),
+  addr4 VARCHAR2(35),
+  contact VARCHAR2(35),
+  phone VARCHAR2(20),
+  fax VARCHAR2(20),
+  email VARCHAR2(50),
+  notes VARCHAR2(4000),
+  discount FLOAT,
+  taxincluded CHAR(1),
+  creditlimit FLOAT,
+  terms INTEGER DEFAULT 0,
+  customernumber VARCHAR2(40),
+  cc VARCHAR2(50),
+  bcc VARCHAR2(50)
+);
+--
+CREATE TABLE parts (
+  id INTEGER,
+  partnumber VARCHAR2(30), 
+  description VARCHAR2(4000),
+  unit VARCHAR2(5),
+  listprice FLOAT,
+  sellprice FLOAT,
+  lastcost FLOAT,
+  priceupdate DATE DEFAULT SYSDATE,
+  weight FLOAT,
+  onhand FLOAT DEFAULT 0,
+  notes VARCHAR2(4000),
+  makemodel CHAR(1) DEFAULT '0',
+  assembly CHAR(1) DEFAULT '0',
+  alternate CHAR(1) DEFAULT '0',
+  rop FLOAT,
+  inventory_accno_id INTEGER,
+  income_accno_id INTEGER,
+  expense_accno_id INTEGER,
+  bin VARCHAR2(20),
+  obsolete CHAR(1) DEFAULT '0',
+  bom CHAR(1) DEFAULT '0',
+  image VARCHAR2(100),
+  drawing VARCHAR2(100),
+  microfiche VARCHAR2(100),
+  partsgroup_id INTEGER
+);
+--
+CREATE TABLE assembly (
+  id INTEGER,
+  parts_id INTEGER,
+  qty FLOAT,
+  bom CHAR(1)
+);
+--
+CREATE TABLE ar (
+  id INTEGER,
+  invnumber VARCHAR2(30),
+  transdate DATE DEFAULT SYSDATE,
+  customer_id INTEGER,
+  taxincluded CHAR(1),
+  amount FLOAT,
+  netamount FLOAT,
+  paid FLOAT,
+  datepaid DATE,
+  duedate DATE,
+  invoice CHAR(1) DEFAULT '0',
+  shippingpoint VARCHAR2(100),
+  terms INTEGER DEFAULT 0,
+  notes VARCHAR2(4000),
+  curr CHAR(3),
+  ordnumber VARCHAR2(30),
+  employee_id INTEGER
+);
+--
+CREATE TABLE ap (
+  id INTEGER,
+  invnumber VARCHAR2(30),
+  transdate DATE DEFAULT SYSDATE,
+  vendor_id INTEGER,
+  taxincluded CHAR(1) DEFAULT '0',
+  amount FLOAT,
+  netamount FLOAT,
+  paid FLOAT,
+  datepaid DATE,
+  duedate DATE,
+  invoice CHAR(1) DEFAULT '0',
+  ordnumber VARCHAR2(30),
+  curr CHAR(3),
+  notes VARCHAR2(4000),
+  employee_id INTEGER
+);
+--
+CREATE TABLE partstax (
+  parts_id INTEGER,
+  chart_id INTEGER
+);
+--
+CREATE TABLE tax (
+  chart_id INTEGER,
+  rate FLOAT,
+  taxnumber VARCHAR2(30)
+);
+--
+CREATE TABLE customertax (
+  customer_id INTEGER,
+  chart_id INTEGER
+);
+--
+CREATE TABLE vendortax (
+  vendor_id INTEGER,
+  chart_id INTEGER
+);
+--
+CREATE TABLE oe (
+  id INTEGER,
+  ordnumber VARCHAR2(30),
+  transdate DATE DEFAULT SYSDATE,
+  vendor_id INTEGER,
+  customer_id INTEGER,
+  amount FLOAT,
+  netamount FLOAT,
+  reqdate DATE,
+  taxincluded CHAR(1),
+  shippingpoint VARCHAR2(100),
+  notes VARCHAR2(4000),
+  curr CHAR(3),
+  employee_id INTEGER,
+  closed CHAR(1) DEFAULT '0'
+);
+--
+CREATE TABLE orderitems (
+  trans_id INTEGER,
+  parts_id INTEGER,
+  description VARCHAR2(4000),
+  qty FLOAT,
+  sellprice FLOAT,
+  discount FLOAT,
+  unit VARCHAR2(5),
+  project_id INTEGER,
+  reqdate DATE
+);
+--
+CREATE TABLE exchangerate (
+  curr CHAR(3),
+  transdate DATE,
+  buy FLOAT,
+  sell FLOAT
+);
+--
+CREATE TABLE employee (
+  id INTEGER,
+  login VARCHAR2(20),
+  name VARCHAR2(35),
+  addr1 VARCHAR2(35),
+  addr2 VARCHAR2(35),
+  addr3 VARCHAR2(35),
+  addr4 VARCHAR2(35),
+  workphone VARCHAR2(20),
+  homephone VARCHAR2(20),
+  startdate DATE DEFAULT SYSDATE,
+  enddate DATE,
+  notes VARCHAR2(4000)
+);
+--
+CREATE TABLE shipto (
+  trans_id INTEGER,
+  shiptoname VARCHAR2(35),
+  shiptoaddr1 VARCHAR2(35),
+  shiptoaddr2 VARCHAR2(35),
+  shiptoaddr3 VARCHAR2(35),
+  shiptoaddr4 VARCHAR2(35),
+  shiptocontact VARCHAR2(35),
+  shiptophone VARCHAR2(20),
+  shiptofax VARCHAR2(20),
+  shiptoemail VARCHAR2(50)
+);
+--
+CREATE TABLE project (
+  id INTEGER,
+  projectnumber VARCHAR2(50),
+  description VARCHAR2(4000)
+);
+--
+CREATE TABLE partsgroup (
+  id INTEGER,
+  partsgroup VARCHAR2(100)
+);
+--
+-- functions
+--
+CREATE OR REPLACE FUNCTION current_date RETURN date AS
+BEGIN
+  return(sysdate);--
+END;;
+--
+-- triggers
+--
+CREATE OR REPLACE TRIGGER glid BEFORE INSERT ON gl FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+CREATE OR REPLACE TRIGGER chartid BEFORE INSERT ON chart FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+CREATE OR REPLACE TRIGGER invoiceid BEFORE INSERT ON invoice FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+CREATE OR REPLACE TRIGGER vendorid BEFORE INSERT ON vendor FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+CREATE OR REPLACE TRIGGER customerid BEFORE INSERT ON customer FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+CREATE OR REPLACE TRIGGER partsid BEFORE INSERT ON parts FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+CREATE OR REPLACE TRIGGER arid BEFORE INSERT ON ar FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+CREATE OR REPLACE TRIGGER apid BEFORE INSERT ON ap FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+CREATE OR REPLACE TRIGGER oeid BEFORE INSERT ON oe FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+CREATE OR REPLACE TRIGGER employeeid BEFORE INSERT ON employee FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+CREATE OR REPLACE TRIGGER projectid BEFORE INSERT ON project FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+CREATE OR REPLACE TRIGGER partsgroupid BEFORE INSERT ON partsgroup FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+
diff --git a/sql-ledger/sql/Oracle-upgrade-1.8.0-1.8.4.sql b/sql-ledger/sql/Oracle-upgrade-1.8.0-1.8.4.sql
new file mode 100644 (file)
index 0000000..a3293a6
--- /dev/null
@@ -0,0 +1,28 @@
+--
+ALTER TABLE chart ADD gifi_accno VARCHAR2(20);
+--
+CREATE TABLE gifi (
+  accno VARCHAR2(20),
+  description VARCHAR2(100)
+);
+--
+CREATE UNIQUE INDEX chart_accno_key ON chart (accno);
+--
+CREATE TABLE mtemp (
+  parts_id INTEGER,
+  name VARCHAR2(100)
+);
+INSERT INTO mtemp SELECT parts_id, name FROM makemodel;
+DROP TABLE makemodel;
+ALTER TABLE mtemp RENAME TO makemodel;
+--
+ALTER TABLE defaults ADD closedto DATE;
+ALTER TABLE defaults ADD revtrans CHAR(1);
+--
+ALTER TABLE ap ADD notes VARCHAR2(4000);
+--
+ALTER TABLE customer ADD businessnumber VARCHAR2(40);
+ALTER TABLE vendor ADD businessnumber VARCHAR2(40);
+--
+UPDATE defaults SET version = '1.8.4', revtrans = '0';
+--
diff --git a/sql-ledger/sql/Oracle-upgrade-1.8.4-1.8.5.sql b/sql-ledger/sql/Oracle-upgrade-1.8.4-1.8.5.sql
new file mode 100644 (file)
index 0000000..d228b9e
--- /dev/null
@@ -0,0 +1,77 @@
+--
+ALTER TABLE customer ADD (customernumber VARCHAR2(40));
+UPDATE customer SET customernumber = businessnumber;
+ALTER TABLE customer DROP COLUMN businessnumber;
+CREATE INDEX customer_customernumber_key ON customer (customernumber);
+--
+ALTER TABLE vendor ADD (vendornumber VARCHAR2(40));
+UPDATE vendor SET vendornumber = businessnumber;
+ALTER TABLE vendor DROP COLUMN businessnumber;
+CREATE INDEX vendor_vendornumber_key ON vendor (vendornumber);
+--
+CREATE TABLE employee (
+  id INTEGER,
+  login VARCHAR2(20),
+  name VARCHAR2(35),
+  addr1 VARCHAR2(35),
+  addr2 VARCHAR2(35),
+  addr3 VARCHAR2(35),
+  addr4 VARCHAR2(35),
+  workphone VARCHAR2(20),
+  homephone VARCHAR2(20),
+  startdate DATE DEFAULT SYSDATE,
+  enddate DATE,
+  notes VARCHAR2(4000)
+);
+--
+CREATE OR REPLACE TRIGGER employeeid BEFORE INSERT ON employee FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+CREATE INDEX employee_id_key ON employee (id);
+CREATE UNIQUE INDEX employee_login_key ON employee (login);
+CREATE INDEX employee_name_key ON employee (name);
+--
+ALTER TABLE gl ADD (employee_id INTEGER);
+CREATE INDEX gl_employee_id_key ON gl (employee_id);
+ALTER TABLE ar ADD (employee_id INTEGER);
+CREATE INDEX ar_employee_id_key ON ar (employee_id);
+ALTER TABLE ap ADD (employee_id INTEGER);
+CREATE INDEX ap_employee_id_key ON ap (employee_id);
+ALTER TABLE oe ADD (employee_id INTEGER);
+CREATE INDEX oe_employee_id_key ON oe (employee_id);
+--
+ALTER TABLE invoice ADD (unit VARCHAR2(5));
+ALTER TABLE orderitems ADD (unit VARCHAR2(5));
+--
+UPDATE chart SET gifi_accno = '' WHERE gifi_accno = NULL;
+ALTER TABLE chart RENAME TO chartold;
+CREATE TABLE chart (
+  id INTEGER,
+  accno VARCHAR2(20) NOT NULL,
+  description VARCHAR2(100),
+  charttype CHAR(1) DEFAULT 'A',
+  category CHAR(1),
+  link VARCHAR2(100),
+  gifi_accno VARCHAR2(20)
+);
+INSERT INTO chart (id, accno, description, charttype, category, link, gifi_accno) SELECT id, accno, description, charttype, category, link, gifi_accno from chartold;
+DROP TABLE chartold;
+CREATE INDEX chart_id_key ON chart (id);
+CREATE UNIQUE INDEX chart_accno_key ON chart (accno);
+CREATE INDEX chart_category_key ON chart (category);
+CREATE INDEX chart_link_key ON chart (link);
+CREATE INDEX chart_gifi_accno_key ON chart (gifi_accno);
+--
+ALTER TABLE parts MODIFY inventory_accno_id;
+--
+ALTER TABLE defaults ADD (sonumber VARCHAR2(30));
+UPDATE defaults SET sonumber = ordnumber;
+ALTER TABLE defaults DROP COLUMN ordnumber;
+ALTER TABLE defaults ADD (ponumber VARCHAR2(30));
+--
+UPDATE defaults SET version = '1.8.5';
+--
diff --git a/sql-ledger/sql/Oracle-upgrade-1.8.5-2.0.0.sql b/sql-ledger/sql/Oracle-upgrade-1.8.5-2.0.0.sql
new file mode 100644 (file)
index 0000000..2d2231b
--- /dev/null
@@ -0,0 +1,100 @@
+--
+alter table customer add (cc VARCHAR2(50));
+alter table customer add (bcc VARCHAR2(50));
+--
+alter table vendor add (cc VARCHAR2(50));
+alter table vendor add (bcc VARCHAR2(50));
+--
+create table shipto (
+  trans_id integer,
+  shiptoname varchar2(35),
+  shiptoaddr1 varchar2(35),
+  shiptoaddr2 varchar2(35),
+  shiptoaddr3 varchar2(35),
+  shiptoaddr4 varchar2(35),
+  shiptocontact varchar2(35),
+  shiptophone varchar2(20),
+  shiptofax varchar2(20),
+  shiptoemail VARCHAR2(50)
+);
+--
+insert into shipto (trans_id, shiptoname, shiptoaddr1, shiptoaddr2, shiptoaddr3, shiptoaddr4, shiptocontact, shiptophone, shiptofax, shiptoemail) select id, shiptoname, shiptoaddr1, shiptoaddr2, shiptoaddr3, shiptoaddr4, shiptocontact, shiptophone, shiptofax, shiptoemail from customer where shiptoname != '' or shiptoname is not null;
+--
+insert into shipto (trans_id, shiptoname, shiptoaddr1, shiptoaddr2, shiptoaddr3, shiptoaddr4, shiptocontact, shiptophone, shiptofax, shiptoemail) select distinct on (a.id) a.id, c.shiptoname, c.shiptoaddr1, c.shiptoaddr2, c.shiptoaddr3, c.shiptoaddr4, c.shiptocontact, c.shiptophone, c.shiptofax, c.shiptoemail from customer c, ar a where a.customer_id = c.id;
+-- 
+insert into shipto (trans_id, shiptoname, shiptoaddr1, shiptoaddr2, shiptoaddr3, shiptoaddr4, shiptocontact, shiptophone, shiptofax, shiptoemail) select distinct on (o.id) o.id, c.shiptoname, c.shiptoaddr1, c.shiptoaddr2, c.shiptoaddr3, c.shiptoaddr4, c.shiptocontact, c.shiptophone, c.shiptofax, c.shiptoemail from customer c, oe o where o.customer_id = c.id;
+-- 
+create index shipto_trans_id_key on shipto (trans_id);
+--
+create table custome (
+  id integer,
+  name varchar2(35),
+  addr1 varchar2(35),
+  addr2 varchar2(35),
+  addr3 varchar2(35),
+  addr4 varchar2(35),
+  contact varchar2(35),
+  phone varchar2(20),
+  fax varchar2(20),
+  email VARCHAR2(50),
+  notes RCHAR2(4000),
+  discount float,
+  taxincluded char(1),
+  creditlimit float DEFAULT 0,
+  terms integer DEFAULT 0,
+  customernumber VARCHAR2(40),
+  cc VARCHAR2(50),
+  bcc VARCHAR2(50)
+);
+insert into custome (id, name, addr1, addr2, addr3, addr4, contact, phone, fax, email, notes, discount, taxincluded, creditlimit, terms, customernumber) select id, name, addr1, addr2, addr3, addr4, contact, phone, fax, email, notes, discount, taxincluded, creditlimit, terms, customernumber from customer;
+--
+drop table customer;
+alter table custome rename to customer;
+create index customer_id_key on customer (id);
+create index customer_name_key on customer (name);
+create index customer_contact_key on customer (contact);
+--
+alter table parts add (bom char(1) default '0');
+update parts set bom = '0';
+update parts set bom = '1' where assembly = '1';
+alter table parts add (image VARCHAR2(100));
+alter table parts add (drawing VARCHAR2(100));
+alter table parts add (microfiche VARCHAR2(100));
+--
+alter table gl add (notes VARCHAR2(4000));
+--
+alter table oe add (closed char(1) default '0');
+update oe set closed = '0';
+--
+create table project (
+  id integer,
+  projectnumber VARCHAR2(50),
+  description VARCHAR2(4000)
+);
+--
+create index project_id_key on project (id);
+--
+alter table acc_trans add (project_id integer);
+update acc_trans set cleared = '0' where cleared = '1';
+--
+alter table invoice add (project_id integer);
+alter table invoice add (deliverydate date);
+alter table orderitems add (project_id integer);
+alter table orderitems add (reqdate date);
+--
+CREATE OR REPLACE TRIGGER projectid BEFORE INSERT ON project FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+  FROM DUAL;--
+END;;
+--
+alter table gl add (reference VARCHAR2(50));
+update gl set reference = source;
+alter table gl drop column source;
+--
+create index gl_reference_key on gl (reference);
+create index acc_trans_source_key on acc_trans (source);
+--
+update defaults set version = '2.0.0';
+--
diff --git a/sql-ledger/sql/Oracle-upgrade-2.0.0-2.0.8.sql b/sql-ledger/sql/Oracle-upgrade-2.0.0-2.0.8.sql
new file mode 100644 (file)
index 0000000..eb65e9c
--- /dev/null
@@ -0,0 +1,19 @@
+--
+create table partsgroup (id integer, partsgroup varchar2(100));
+create index partsgroup_id_key on partsgroup (id);
+--
+alter table parts add (partsgroup_id integer);
+--
+alter table assembly add (bom char(1));
+update assembly set bom = '0' where assembly.id = parts.id and parts.bom = '0';
+update assembly set bom = '1' where assembly.id = parts.id and parts.bom = '1';
+--
+CREATE OR REPLACE TRIGGER partsgroupid BEFORE INSERT ON partsgroup FOR EACH ROW
+BEGIN
+  SELECT id.nextval
+  INTO :new.id
+FROM DUAL;--
+END;;
+--      
+update defaults set version = '2.0.8';
+--
diff --git a/sql-ledger/sql/Pg-indices.sql b/sql-ledger/sql/Pg-indices.sql
new file mode 100644 (file)
index 0000000..27a9e43
--- /dev/null
@@ -0,0 +1,57 @@
+create index acc_trans_trans_id_key on acc_trans (trans_id);
+create index acc_trans_chart_id_key on acc_trans (chart_id);
+create index acc_trans_transdate_key on acc_trans (transdate);
+create index acc_trans_source_key on acc_trans (lower(source));
+create index ap_id_key on ap (id);
+create index ap_transdate_key on ap (transdate);
+create index ap_invnumber_key on ap (lower(invnumber));
+create index ap_ordnumber_key on ap (lower(ordnumber));
+create index ap_vendor_id_key on ap (vendor_id);
+create index ap_employee_id_key on ap (employee_id);
+create index ar_id_key on ar (id);
+create index ar_transdate_key on ar (transdate);
+create index ar_invnumber_key on ar (lower(invnumber));
+create index ar_ordnumber_key on ar (lower(ordnumber));
+create index ar_customer_id_key on ar (customer_id);
+create index ar_employee_id_key on ar (employee_id);
+create index assembly_id_key on assembly (id);
+create index chart_id_key on chart (id);
+create unique index chart_accno_key on chart (accno);
+create index chart_category_key on chart (category);
+create index chart_link_key on chart (link);
+create index chart_gifi_accno_key on chart (gifi_accno);
+create index customer_id_key on customer (id);
+create index customer_customer_id_key on customertax (customer_id);
+create index customer_customernumber_key on customer (customernumber);
+create index customer_name_key on customer (name);
+create index customer_contact_key on customer (contact);
+create index employee_id_key on employee (id);
+create unique index employee_login_key on employee (login);
+create index employee_name_key on employee (name);
+create index exchangerate_ct_key on exchangerate (curr, transdate);
+create unique index gifi_accno_key on gifi (accno);
+create index gl_id_key on gl (id);
+create index gl_transdate_key on gl (transdate);
+create index gl_reference_key on gl (lower(reference));
+create index gl_description_key on gl (lower(description));
+create index gl_employee_id_key on gl (employee_id);
+create index invoice_id_key on invoice (id);
+create index invoice_trans_id_key on invoice (trans_id);
+create index makemodel_parts_id_key on makemodel (parts_id);
+create index oe_id_key on oe (id);
+create index oe_transdate_key on oe (transdate);
+create index oe_ordnumber_key on oe (lower(ordnumber));
+create index oe_employee_id_key on oe (employee_id);
+create index orderitems_trans_id_key on orderitems (trans_id);
+create index parts_id_key on parts (id);
+create index parts_partnumber_key on parts (lower(partnumber));
+create index parts_description_key on parts (lower(description));
+create index partstax_parts_id_key on partstax (parts_id);
+create index vendor_id_key on vendor (id);
+create index vendor_name_key on vendor (name);
+create index vendor_vendornumber_key on vendor (vendornumber);
+create index vendor_contact_key on vendor (contact);
+create index vendortax_vendor_id_key on vendortax (vendor_id);
+create index shipto_trans_id_key on shipto (trans_id);
+create index project_id_key on project (id);
+create index partsgroup_id_key on partsgroup (id);
diff --git a/sql-ledger/sql/Pg-tables.sql b/sql-ledger/sql/Pg-tables.sql
new file mode 100644 (file)
index 0000000..aed9787
--- /dev/null
@@ -0,0 +1,289 @@
+CREATE SEQUENCE id
+  start 10000;
+--
+SELECT nextval ('id');
+--
+CREATE TABLE makemodel (
+  parts_id int,
+  name text
+);
+--
+CREATE TABLE gl (
+  id int DEFAULT nextval ( 'id' ),
+  reference text,
+  description text,
+  transdate date DEFAULT current_date,
+  employee_id int,
+  notes text
+);
+--
+CREATE TABLE chart (
+  id int DEFAULT nextval ( 'id' ),
+  accno text NOT NULL,
+  description text,
+  charttype char(1) DEFAULT 'A',
+  category char(1),
+  link text,
+  gifi_accno text
+);
+--
+CREATE TABLE gifi (
+  accno text,
+  description text
+);
+--
+CREATE TABLE defaults (
+  inventory_accno_id int,
+  income_accno_id int,
+  expense_accno_id int,
+  fxgain_accno_id int,
+  fxloss_accno_id int,
+  invnumber text,
+  sonumber text,
+  yearend varchar(5),
+  weightunit varchar(5),
+  businessnumber text,
+  version varchar(8),
+  curr text,
+  closedto date,
+  revtrans bool DEFAULT 'f',
+  ponumber text
+);
+INSERT INTO defaults (version) VALUES ('2.0.8');
+--
+CREATE TABLE acc_trans (
+  trans_id int,
+  chart_id int,
+  amount float,
+  transdate date DEFAULT current_date,
+  source text,
+  cleared bool DEFAULT 'f',
+  fx_transaction bool DEFAULT 'f',
+  project_id int
+);
+--
+CREATE TABLE invoice (
+  id int DEFAULT nextval ( 'id' ),
+  trans_id int,
+  parts_id int,
+  description text,
+  qty float4,
+  allocated float4,
+  sellprice float,
+  fxsellprice float,
+  discount float4,
+  assemblyitem bool DEFAULT 'f',
+  unit varchar(5),
+  project_id int,
+  deliverydate date
+);
+--
+CREATE TABLE vendor (
+  id int DEFAULT nextval ( 'id' ),
+  name varchar(35),
+  addr1 varchar(35),
+  addr2 varchar(35),
+  addr3 varchar(35),
+  addr4 varchar(35),
+  contact varchar(35),
+  phone varchar(20),
+  fax varchar(20),
+  email text,
+  notes text,
+  terms int2 DEFAULT 0,
+  taxincluded bool,
+  vendornumber text,
+  cc text,
+  bcc text
+);
+--
+CREATE TABLE customer (
+  id int DEFAULT nextval ( 'id' ),
+  name varchar(35),
+  addr1 varchar(35),
+  addr2 varchar(35),
+  addr3 varchar(35),
+  addr4 varchar(35),
+  contact varchar(35),
+  phone varchar(20),
+  fax varchar(20),
+  email text,
+  notes text,
+  discount float4,
+  taxincluded bool,
+  creditlimit float DEFAULT 0,
+  terms int2 DEFAULT 0,
+  customernumber text,
+  cc text,
+  bcc text
+);
+--
+CREATE TABLE parts (
+  id int DEFAULT nextval ( 'id' ),
+  partnumber text,
+  description text,
+  unit varchar(5),
+  listprice float,
+  sellprice float,
+  lastcost float,
+  priceupdate date DEFAULT current_date,
+  weight float4,
+  onhand float4 DEFAULT 0,
+  notes text,
+  makemodel bool DEFAULT 'f',
+  assembly bool DEFAULT 'f',
+  alternate bool DEFAULT 'f',
+  rop float4,
+  inventory_accno_id int,
+  income_accno_id int,
+  expense_accno_id int,
+  bin text,
+  obsolete bool DEFAULT 'f',
+  bom bool DEFAULT 'f',
+  image text,
+  drawing text,
+  microfiche text,
+  partsgroup_id int
+);
+--
+CREATE TABLE assembly (
+  id int,
+  parts_id int,
+  qty float,
+  bom bool
+);
+--
+CREATE TABLE ar (
+  id int DEFAULT nextval ( 'id' ),
+  invnumber text,
+  transdate date DEFAULT current_date,
+  customer_id int,
+  taxincluded bool,
+  amount float,
+  netamount float,
+  paid float,
+  datepaid date,
+  duedate date,
+  invoice bool DEFAULT 'f',
+  shippingpoint text,
+  terms int2 DEFAULT 0,
+  notes text,
+  curr char(3),
+  ordnumber text,
+  employee_id int
+);
+--
+CREATE TABLE ap (
+  id int DEFAULT nextval ( 'id' ),
+  invnumber text,
+  transdate date DEFAULT current_date,
+  vendor_id int,
+  taxincluded bool DEFAULT 'f',
+  amount float,
+  netamount float,
+  paid float,
+  datepaid date,
+  duedate date,
+  invoice bool DEFAULT 'f',
+  ordnumber text,
+  curr char(3),
+  notes text,
+  employee_id int
+);
+--
+CREATE TABLE partstax (
+  parts_id int,
+  chart_id int
+);
+--
+CREATE TABLE tax (
+  chart_id int,
+  rate float,
+  taxnumber text
+);
+--
+CREATE TABLE customertax (
+  customer_id int,
+  chart_id int
+);
+--
+CREATE TABLE vendortax (
+  vendor_id int,
+  chart_id int
+);
+--
+CREATE TABLE oe (
+  id int default nextval('id'),
+  ordnumber text,
+  transdate date default current_date,
+  vendor_id int,
+  customer_id int,
+  amount float8,
+  netamount float8,
+  reqdate date,
+  taxincluded bool,
+  shippingpoint text,
+  notes text,
+  curr char(3),
+  employee_id int,
+  closed bool default 'f'
+);
+--
+CREATE TABLE orderitems (
+  trans_id int,
+  parts_id int,
+  description text,
+  qty float4,
+  sellprice float8,
+  discount float4,
+  unit varchar(5),
+  project_id int,
+  reqdate date
+);
+--
+CREATE TABLE exchangerate (
+  curr char(3),
+  transdate date,
+  buy float8,
+  sell float8
+);
+--
+CREATE TABLE employee (
+  id int DEFAULT nextval ('id'),
+  login text,
+  name Varchar(35),
+  addr1 varchar(35),
+  addr2 varchar(35),
+  addr3 varchar(35),
+  addr4 varchar(35),
+  workphone varchar(20),
+  homephone varchar(20),
+  startdate date default current_date,
+  enddate date,
+  notes text
+);
+--
+create table shipto (
+  trans_id int,
+  shiptoname varchar(35),
+  shiptoaddr1 varchar(35),
+  shiptoaddr2 varchar(35),
+  shiptoaddr3 varchar(35),
+  shiptoaddr4 varchar(35),
+  shiptocontact varchar(35),
+  shiptophone varchar(20),
+  shiptofax varchar(20),
+  shiptoemail text
+);
+--
+create table project (
+  id int default nextval('id'),
+  projectnumber text,
+  description text
+);
+--
+create table partsgroup (
+  id int default nextval('id'),
+  partsgroup text
+);
+--
diff --git a/sql-ledger/sql/Pg-upgrade-1.2.6-1.2.7.sql b/sql-ledger/sql/Pg-upgrade-1.2.6-1.2.7.sql
new file mode 100644 (file)
index 0000000..159f31b
--- /dev/null
@@ -0,0 +1,4 @@
+--
+-- add the field shiptoemail to the customer table
+--
+alter table customer add column shiptoemail text;
diff --git a/sql-ledger/sql/Pg-upgrade-1.2.7-1.4.0.sql b/sql-ledger/sql/Pg-upgrade-1.2.7-1.4.0.sql
new file mode 100644 (file)
index 0000000..04e1a79
--- /dev/null
@@ -0,0 +1,173 @@
+--
+CREATE TABLE newap (
+  id int DEFAULT nextval ( 'id' ),
+  invnumber text,
+  transdate date DEFAULT current_date,
+  vendor int,
+  taxincluded bool DEFAULT FALSE,
+  amount float,
+  netamount float,
+  paid float,
+  datepaid date,
+  duedate date,
+  invoice bool DEFAULT FALSE,
+  ordnumber text
+);
+--
+INSERT INTO newap (id, invnumber, transdate, vendor, amount, netamount, paid,
+datepaid, duedate, invoice, ordnumber)
+SELECT id, invnumber, transdate, vendor, amount, netamount, paid,
+datepaid, duedate, invoice, ordnumber
+FROM ap;
+--
+DROP TABLE ap;
+ALTER TABLE newap RENAME TO ap;
+--
+CREATE TABLE newar (
+  id int DEFAULT nextval ( 'id' ),
+  invnumber text,
+  transdate date DEFAULT current_date,
+  customer int,
+  taxincluded bool DEFAULT FALSE,
+  amount float,
+  netamount float,
+  paid float,
+  datepaid date,
+  duedate date,
+  invoice bool DEFAULT FALSE,
+  shippingpoint text,
+  terms int2,
+  notes text
+);
+--
+INSERT INTO newar (id, invnumber, transdate, customer, amount, netamount, paid,
+datepaid, duedate, invoice, shippingpoint, terms, notes)
+SELECT id, invnumber, transdate, customer, amount, netamount, paid,
+datepaid, duedate, invoice, shippingpoint, terms, notes
+FROM ar;
+--
+DROP TABLE ar;
+ALTER TABLE newar RENAME TO ar;
+--
+CREATE TABLE newcustomer (
+  id int DEFAULT nextval ( 'id' ),
+  name varchar(35),
+  addr1 varchar(35),
+  addr2 varchar(35),
+  addr3 varchar(35),
+  contact varchar(35),
+  phone varchar(20),
+  fax varchar(20),
+  email text,
+  notes text,
+  ytd float,
+  discount float4,
+  taxincluded bool,
+  creditlimit float,
+  terms int2,
+  shiptoname varchar(35),
+  shiptoaddr1 varchar(35),
+  shiptoaddr2 varchar(35),
+  shiptoaddr3 varchar(35),
+  shiptocontact varchar(20),
+  shiptophone varchar(20),
+  shiptofax varchar(20),
+  shiptoemail text
+);
+INSERT INTO newcustomer (
+id, name, addr1, addr2, addr3, contact, phone, fax, email, notes, ytd,
+discount, creditlimit, terms, shiptoname, shiptoaddr1, shiptoaddr2,
+shiptoaddr3, shiptocontact, shiptophone, shiptofax, shiptoemail )
+SELECT id, name, addr1, addr2, addr3, contact, phone, fax, email, notes, ytd,
+discount, creditlimit, terms, shiptoname, shiptoaddr1, shiptoaddr2,
+shiptoaddr3, shiptocontact, shiptophone, shiptofax, shiptoemail
+FROM customer;
+--
+DROP TABLE customer;
+ALTER TABLE newcustomer RENAME TO customer;
+--
+CREATE TABLE customertax (
+  customer_id int,
+  chart_id int
+);
+--
+CREATE TABLE newdefaults (
+  inventory_accno int,
+  income_accno int,
+  expense_accno int,
+  invnumber text,
+  ponumber text,
+  yearend varchar(5),
+  nativecurr varchar(3),
+  weightunit varchar(5)
+);
+--
+INSERT INTO newdefaults (
+inventory_accno, income_accno, expense_accno, invnumber, ponumber)
+SELECT inventory_accno, income_accno, expense_accno, invnumber, ponumber
+FROM defaults;
+--
+DROP TABLE defaults;
+ALTER TABLE newdefaults RENAME TO defaults;
+UPDATE defaults SET yearend = '1/31', nativecurr = 'CAD', weightunit = 'kg';
+--
+CREATE TABLE partstax (
+  parts_id int,
+  chart_id int
+);
+--
+CREATE TABLE tax (
+  chart_id int,
+  rate float,
+  number text
+);
+--
+CREATE TABLE newvendor (
+  id int DEFAULT nextval ( 'id' ),
+  name varchar(35),
+  addr1 varchar(35),
+  addr2 varchar(35),
+  addr3 varchar(35),
+  contact varchar(35),
+  phone varchar(20),
+  fax varchar(20),
+  email text,
+  notes text,
+  ytd float,
+  discount float4,
+  taxincluded bool,
+  creditlimit float,
+  terms int2
+);
+--
+INSERT INTO newvendor (
+id, name, addr1, addr2, addr3, contact, phone, fax, email, notes, ytd )
+SELECT id, name, addr1, addr2, addr3, contact, phone, fax, email, notes, ytd
+FROM vendor;
+--
+DROP TABLE vendor;
+ALTER TABLE newvendor RENAME TO vendor;
+--
+CREATE TABLE vendortax (
+  vendor_id int,
+  chart_id int
+);
+--
+ALTER TABLE chart RENAME TO oldchart;
+--
+CREATE TABLE chart (
+  id int DEFAULT nextval( 'id' ),
+  accno int UNIQUE,
+  description text,
+  balance float,
+  type char(1),
+  gifi int,
+  category char(1),
+  link text
+);
+--
+INSERT INTO chart SELECT * FROM oldchart;
+--
+DROP TABLE oldchart;
+--
+
diff --git a/sql-ledger/sql/Pg-upgrade-1.4.0-1.6.0.sql b/sql-ledger/sql/Pg-upgrade-1.4.0-1.6.0.sql
new file mode 100644 (file)
index 0000000..e0a3892
--- /dev/null
@@ -0,0 +1,126 @@
+alter table acc_trans rename column accno to chart_id;
+update acc_trans set chart_id =
+  (select id from chart where accno = acc_trans.chart_id);
+--
+alter table parts rename column inventory_accno to inventory_accno_id;
+alter table parts rename column income_accno to income_accno_id;
+alter table parts rename column expense_accno to expense_accno_id;
+alter table parts rename column number to partnumber;
+update parts set inventory_accno_id =
+  (select id from chart where chart.accno = parts.inventory_accno_id);
+update parts set income_accno_id =
+  (select id from chart where chart.accno = parts.income_accno_id);
+update parts set expense_accno_id =
+  (select id from chart where chart.accno = parts.expense_accno_id);
+--
+create table assembly (id int, parts_id int, qty float);
+--
+alter table defaults rename column inventory_accno to inventory_accno_id;
+alter table defaults rename column income_accno to income_accno_id;
+alter table defaults rename column expense_accno to expense_accno_id;
+alter table defaults add column businessnumber text;
+alter table defaults add column version varchar(8);
+update defaults set inventory_accno_id =
+  (select id from chart where chart.accno = defaults.inventory_accno_id);
+update defaults set income_accno_id =
+  (select id from chart where chart.accno = defaults.income_accno_id);
+update defaults set expense_accno_id =
+  (select id from chart where chart.accno = defaults.expense_accno_id);
+update defaults set version = '1.6.0';
+--
+alter table invoice rename column inventory_accno to inventory_accno_id;
+alter table invoice rename column income_accno to income_accno_id;
+alter table invoice rename column expense_accno to expense_accno_id;
+alter table invoice rename column number to partnumber;
+alter table invoice add column assemblyitem bool;
+update invoice set assemblyitem = 'f';
+update invoice set inventory_accno_id =
+  (select id from chart where invoice.inventory_accno_id = chart.accno);
+update invoice set income_accno_id =
+  (select id from chart where invoice.income_accno_id = chart.accno);
+update invoice set expense_accno_id =
+  (select id from chart where invoice.expense_accno_id = chart.accno);
+--
+alter table gl rename column comment to description;
+--
+create table newvendor (
+  id int default nextval ( 'id' ),
+  name varchar(35),
+  addr1 varchar(35),
+  addr2 varchar(35),
+  addr3 varchar(35),
+  addr4 varchar(35),
+  contact varchar(35),
+  phone varchar(20),
+  fax varchar(20),
+  email text,
+  notes text,
+  terms int2,
+  taxincluded bool
+);
+insert into newvendor (
+  id, name, addr1, addr2, addr3, contact, phone, fax, email, notes, terms,
+  taxincluded)
+  select
+  id, name, addr1, addr2, addr3, contact, phone, fax, email, notes, terms,
+  taxincluded from vendor;
+drop table vendor;
+alter table newvendor rename to vendor;
+--
+create table newcustomer (
+  id int default nextval ( 'id' ),
+  name varchar(35),
+  addr1 varchar(35),
+  addr2 varchar(35),
+  addr3 varchar(35),
+  addr4 varchar(35),
+  contact varchar(35),
+  phone varchar(20),
+  fax varchar(20),
+  email text,
+  notes text,
+  discount float4,
+  taxincluded bool,
+  creditlimit float,
+  terms int2,
+  shiptoname varchar(35),
+  shiptoaddr1 varchar(35),
+  shiptoaddr2 varchar(35),
+  shiptoaddr3 varchar(35),
+  shiptoaddr4 varchar(35),
+  shiptocontact varchar(20),
+  shiptophone varchar(20),
+  shiptofax varchar(20),
+  shiptoemail text
+);
+insert into newcustomer (
+  id, name, addr1, addr2, addr3, contact, phone, fax, email, notes, discount,
+  taxincluded, creditlimit, terms, shiptoname, shiptoaddr1, shiptoaddr2,
+  shiptoaddr3, shiptocontact, shiptophone, shiptofax, shiptoemail
+  )
+  select
+  id, name, addr1, addr2, addr3, contact, phone, fax, email, notes, discount,
+  taxincluded, creditlimit, terms, shiptoname, shiptoaddr1, shiptoaddr2,
+  shiptoaddr3, shiptocontact, shiptophone, shiptofax, shiptoemail
+  from customer;
+drop table customer;
+alter table newcustomer rename to customer;
+--
+drop index chart_accno_key;
+alter table chart rename to oldchart;
+create table chart (
+  id int default nextval('id'),
+  accno int unique,
+  description text,
+  charttype char(1),
+  gifi int,
+  category char(1),
+  link text
+);
+insert into chart (id, accno, description, charttype, gifi, category, link)
+  select id, accno, description, type, gifi, category, link from oldchart;
+drop table oldchart;
+--
+alter table tax rename column number to taxnumber;
+--
+-- apply
diff --git a/sql-ledger/sql/Pg-upgrade-1.6.0-1.8.0.sql b/sql-ledger/sql/Pg-upgrade-1.6.0-1.8.0.sql
new file mode 100644 (file)
index 0000000..4e98e1f
--- /dev/null
@@ -0,0 +1,104 @@
+--
+create table def (
+  inventory_accno_id int,
+  income_accno_id int,
+  expense_accno_id int,
+  fxgain_accno_id int,
+  fxloss_accno_id int,
+  invnumber text,
+  ordnumber text,
+  yearend varchar(5),
+  weightunit varchar(5),
+  businessnumber text,
+  version varchar(8),
+  curr text
+);
+insert into def (inventory_accno_id, income_accno_id, expense_accno_id, invnumber, ordnumber, yearend, weightunit, businessnumber, version, curr) select inventory_accno_id, income_accno_id, expense_accno_id, invnumber, ponumber, yearend, weightunit, businessnumber, version, nativecurr from defaults;
+drop table defaults;
+alter table def rename to defaults;
+update defaults set version = '1.8.0';
+--
+-- create a default accno for exchange rate gain and loss
+--
+select accno into temp from chart where category = 'I' order by accno desc limit 1;
+update temp set accno = accno + 1;
+insert into chart (accno) select accno from temp;
+update chart set description = 'Foreign Exchange Gain', category = 'I', charttype = 'A' where accno = (select accno from temp);
+update defaults set fxgain_accno_id = (select id from chart where chart.accno = temp.accno);
+drop table temp;
+select accno into temp from chart where category = 'E' order by accno desc limit 1;
+update temp set accno = accno + 1;
+insert into chart (accno) select accno from temp;
+update chart set description = 'Foreign Exchange Loss', category = 'E', charttype = 'A' where accno = (select accno from temp);
+update defaults set fxloss_accno_id = (select id from chart where chart.accno = temp.accno);
+drop table temp;
+--
+alter table parts add column bin text;
+alter table parts alter column onhand set default 0;
+update parts set onhand = 0 where onhand = NULL;
+alter table parts add column obsolete bool;
+alter table parts alter column obsolete set default 'f';
+update parts set obsolete = 'f';
+--
+alter table ap rename column vendor to vendor_id;
+alter table ap add column curr char(3);
+--
+alter table ar rename column customer to customer_id;
+alter table ar add column curr char(3);
+alter table ar add column ordnumber text;
+--
+alter table acc_trans add column source text;
+alter table acc_trans add column cleared bool;
+alter table acc_trans alter column cleared set default 'f';
+alter table acc_trans add column fx_transaction bool;
+alter table acc_trans alter column fx_transaction set default 'f';
+update acc_trans set cleared = 'f', fx_transaction = 'f';
+--
+create table oe (
+  id int default nextval('id'),
+  ordnumber text,
+  transdate date default current_date,
+  vendor_id int,
+  customer_id int,
+  amount float8,
+  netamount float8,
+  reqdate date,
+  taxincluded bool,
+  shippingpoint text,
+  notes text,
+  curr char(3)
+);
+--
+create table orderitems (
+  trans_id int,
+  parts_id int,
+  description text,
+  qty float4,
+  sellprice float8,
+  discount float4
+);
+--
+alter table invoice rename to invoiceold;
+create table invoice (
+  id int default nextval('id'),
+  trans_id int,
+  parts_id int,
+  description text,
+  qty float4,
+  allocated float4,
+  sellprice float8,
+  fxsellprice float8,
+  discount float4,
+  assemblyitem bool default 'f'
+);
+insert into invoice (id, trans_id, parts_id, description, qty, allocated, sellprice, fxsellprice, discount, assemblyitem) select id, trans_id, parts_id, description, qty, allocated, sellprice, sellprice, discount, assemblyitem from invoiceold;
+update invoice set assemblyitem = 'f' where assemblyitem = NULL;
+drop table invoiceold;
+--
+create table exchangerate (
+  curr char(3),
+  transdate date,
+  buy float8,
+  sell float8
+);
+--
diff --git a/sql-ledger/sql/Pg-upgrade-1.8.0-1.8.4.sql b/sql-ledger/sql/Pg-upgrade-1.8.0-1.8.4.sql
new file mode 100644 (file)
index 0000000..57b24f1
--- /dev/null
@@ -0,0 +1,21 @@
+--
+alter table chart add column gifi_accno text;
+--
+create table gifi (accno text, description text);
+create unique index gifi_accno_key on gifi (accno);
+--
+create table mtemp (parts_id int, name text);
+insert into mtemp select parts_id, name from makemodel;
+drop table makemodel;
+alter table mtemp rename to makemodel;
+--
+alter table defaults add column closedto date;
+alter table defaults add column revtrans bool;
+--
+alter table ap add column notes text;
+--
+alter table customer add column businessnumber text;
+alter table vendor add column businessnumber text;
+--
+update defaults set version = '1.8.4', revtrans = 'f';
+--
diff --git a/sql-ledger/sql/Pg-upgrade-1.8.4-1.8.5.sql b/sql-ledger/sql/Pg-upgrade-1.8.4-1.8.5.sql
new file mode 100644 (file)
index 0000000..807857a
--- /dev/null
@@ -0,0 +1,63 @@
+--
+alter table customer rename column businessnumber to customernumber;
+create index customer_customernumber_key on customer (customernumber);
+alter table vendor rename column businessnumber to vendornumber;
+create index vendor_vendornumber_key on vendor (vendornumber);
+--
+CREATE TABLE employee (
+  id int DEFAULT nextval ('id'),
+  login text,
+  name varchar(35),
+  addr1 varchar(35),
+  addr2 varchar(35),
+  addr3 varchar(35),
+  addr4 varchar(35),
+  workphone varchar(20),
+  homephone varchar(20),
+  startdate date default current_date,
+  enddate date,
+  notes text
+);
+--
+create index employee_id_key on employee (id);
+create unique index employee_login_key on employee (login);
+create index employee_name_key on employee (name);
+--
+alter table gl add column employee_id int;
+create index gl_employee_id_key on gl (employee_id);
+alter table ar add column employee_id int;
+create index ar_employee_id_key on ar (employee_id);
+alter table ap add column employee_id int;
+create index ap_employee_id_key on ap (employee_id);
+alter table oe add column employee_id int;
+create index oe_employee_id_key on oe (employee_id);
+--
+alter table invoice add column unit varchar(5);
+alter table orderitems add column unit varchar(5);
+--
+update chart set gifi_accno = '' where gifi_accno = NULL;
+alter table chart rename to chartold;
+CREATE TABLE chart (
+  id int DEFAULT nextval ('id'),
+  accno text NOT NULL,
+  description text,
+  charttype char(1) DEFAULT 'A',
+  category char(1),
+  link text,
+  gifi_accno text
+);
+insert into chart (id, accno, description, charttype, category, link, gifi_accno) select id, accno, description, charttype, category, link, gifi_accno from chartold;
+drop table chartold;
+create index chart_id_key on chart (id);
+create unique index chart_accno_key on chart (accno);
+create index chart_category_key on chart (category);
+create index chart_link_key on chart (link);
+create index chart_gifi_accno_key on chart (gifi_accno);
+--
+alter table parts alter column inventory_accno_id drop default;
+--
+alter table defaults rename ordnumber to sonumber;
+alter table defaults add column ponumber text;
+--
+update defaults set version = '1.8.5', ponumber = sonumber;
+--
diff --git a/sql-ledger/sql/Pg-upgrade-1.8.5-2.0.0.sql b/sql-ledger/sql/Pg-upgrade-1.8.5-2.0.0.sql
new file mode 100644 (file)
index 0000000..ebc1d07
--- /dev/null
@@ -0,0 +1,92 @@
+--
+alter table customer add column cc text;
+alter table customer add column bcc text;
+--
+alter table vendor add column cc text;
+alter table vendor add column bcc text;
+--
+create table shipto (
+  trans_id int,
+  shiptoname varchar(35),
+  shiptoaddr1 varchar(35),
+  shiptoaddr2 varchar(35),
+  shiptoaddr3 varchar(35),
+  shiptoaddr4 varchar(35),
+  shiptocontact varchar(35),
+  shiptophone varchar(20),
+  shiptofax varchar(20),
+  shiptoemail text
+);
+--
+insert into shipto (trans_id, shiptoname, shiptoaddr1, shiptoaddr2, shiptoaddr3, shiptoaddr4, shiptocontact, shiptophone, shiptofax, shiptoemail) select id, shiptoname, shiptoaddr1, shiptoaddr2, shiptoaddr3, shiptoaddr4, shiptocontact, shiptophone, shiptofax, shiptoemail from customer where shiptoname != '' or shiptoname is not null;
+--
+insert into shipto (trans_id, shiptoname, shiptoaddr1, shiptoaddr2, shiptoaddr3, shiptoaddr4, shiptocontact, shiptophone, shiptofax, shiptoemail) select distinct on (a.id) a.id, c.shiptoname, c.shiptoaddr1, c.shiptoaddr2, c.shiptoaddr3, c.shiptoaddr4, c.shiptocontact, c.shiptophone, c.shiptofax, c.shiptoemail from customer c, ar a where a.customer_id = c.id;
+--
+insert into shipto (trans_id, shiptoname, shiptoaddr1, shiptoaddr2, shiptoaddr3, shiptoaddr4, shiptocontact, shiptophone, shiptofax, shiptoemail) select distinct on (o.id) o.id, c.shiptoname, c.shiptoaddr1, c.shiptoaddr2, c.shiptoaddr3, c.shiptoaddr4, c.shiptocontact, c.shiptophone, c.shiptofax, c.shiptoemail from customer c, oe o where o.customer_id = c.id;
+--
+create index shipto_trans_id_key on shipto (trans_id);
+--
+create table custome (
+  id int default nextval('id'),
+  name varchar(35),
+  addr1 varchar(35),
+  addr2 varchar(35),
+  addr3 varchar(35),
+  addr4 varchar(35),
+  contact varchar(35),
+  phone varchar(20),
+  fax varchar(20),
+  email text,
+  notes text,
+  discount float4,
+  taxincluded bool,
+  creditlimit float DEFAULT 0,
+  terms int2 DEFAULT 0,
+  customernumber text,
+  cc text,
+  bcc text
+);
+insert into custome (id, name, addr1, addr2, addr3, addr4, contact, phone, fax, email, notes, discount, taxincluded, creditlimit, terms, customernumber) select id, name, addr1, addr2, addr3, addr4, contact, phone, fax, email, notes, discount, taxincluded, creditlimit, terms, customernumber from customer;
+--
+drop table customer;
+alter table custome rename to customer;
+create index customer_id_key on customer (id);
+create index customer_name_key on customer (name);
+create index customer_contact_key on customer (contact);
+--
+alter table parts add column bom boolean;
+alter table parts alter column bom set default 'f';
+update parts set bom = 'f';
+update parts set bom = 't' where assembly;
+alter table parts add column image text;
+alter table parts add column drawing text;
+alter table parts add column microfiche text;
+--
+alter table gl add column notes text;
+--
+alter table oe add column closed bool;
+alter table oe alter column closed set default 'f';
+update oe set closed = 'f';
+--
+create table project (
+  id int default nextval('id'),
+  projectnumber text,
+  description text
+);
+--
+create index project_id_key on project (id);
+--
+alter table acc_trans add column project_id int;
+update acc_trans set cleared = '0' where cleared = '1';
+--
+alter table invoice add column project_id int;
+alter table invoice add column deliverydate date;
+alter table orderitems add column project_id int;
+alter table orderitems add column reqdate date;
+--
+alter table gl rename source to reference;
+create index gl_reference_key on gl (reference);
+create index acc_trans_source_key on acc_trans (lower(source));
+--
+update defaults set version = '2.0.0';
+--
diff --git a/sql-ledger/sql/Pg-upgrade-2.0.0-2.0.8.sql b/sql-ledger/sql/Pg-upgrade-2.0.0-2.0.8.sql
new file mode 100644 (file)
index 0000000..ef73b1c
--- /dev/null
@@ -0,0 +1,12 @@
+--
+create table partsgroup (id int default nextval('id'), partsgroup text);
+create index partsgroup_id_key on partsgroup (id);
+-- 
+alter table parts add partsgroup_id int;
+--
+alter table assembly add bom bool;
+update assembly set bom = '0' where assembly.id = parts.id and parts.bom = '0';
+update assembly set bom = '1' where assembly.id = parts.id and parts.bom = '1';
+--
+update defaults set version = '2.0.8';
+--
diff --git a/sql-ledger/sql/Poland-chart.sql b/sql-ledger/sql/Poland-chart.sql
new file mode 100644 (file)
index 0000000..64960ca
--- /dev/null
@@ -0,0 +1,337 @@
+-- Chart of Account for Poland
+-- From: Peter Dabrowski <meritage@mail.com>
+-- Sun, 23 March 2003
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('000000000','Aktywa Trwa³e','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('001000000','¦rodki Trwa³e','A','','A','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('001010000','Grunty w³asne i prawa wieczystego u¿ytkowania gruntów','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('001020000','Budynki, locale i obiekty in¿ynierii l±dowej i wodnej','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('001030000','Urz±dzenia techniczne i maszyny','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('001040000','¦rodki transportu','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('001050000','Inne ¶rodki trwa³e','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('002000000','Warto¶ci niematerialne i prawne','A','','A','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('002010000','Koszty zakoñczonych prac rozwojowych','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('002020000','Nabyta warto¶æ firmy','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('002080000','Inne warto¶ci niematerialne i prawne','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('002090000','Zaliczki na warto¶ci niematerialne i prawne','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003000000','D³ugoterminowe aktywa finansowe','A','','A','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003010000','W jednostkach powi±zanych','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003010100','Udzia³y lub akcje','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003010200','Inne papiery warto¶ciowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003010300','Udzielone porzyczki','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003010400','Inne d³ugoterminowe aktywa finansowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003020000','W pozosta³ych jednostkach','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003020100','Udzia³y lub akcje','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003020200','Inne papiery warto¶ciowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003020300','Udzielone po¿yczki','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003020400','Inne d³ugoterminowe aktywa finansowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003090000','Inne investycje d³ugoterminowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('003090100','Inne rodzaje d³ugoterminowych aktywów finansowych','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('004000000','Investycje w nieruchomo¶ci i prawa','A','','A','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('004010000','Nieruchomo¶ci','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('004020000','Warto¶ci niematerialne i prawne','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('005000000','D³ugoterminowe rozliczenia miêdzyokresowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('005010000','Aktywa z tytu³u odroczonego podatku dochodowego','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('005020000','Inne rozliczenia miêdzyokresowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('006000000','Nale¿no¶ci d³ugoterminowe','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('006010000','Od jednostek powi±zanych','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('006020000','Od pozosta³ych jednostek','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('007000000','Odpisy umorzeniowe ¶rodków trwa³ych oraz warto¶ci niematerialnych i prawnych','A','','A','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('007010000','Odpisy umorzeniowe warto¶ci gruntów i prawa wieczystego u¿ytkowania gruntów','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('007020000','Odpisy umorzeniowe budynków, lokali i obiektów in¿ynierii l±dowej i wodnej','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('007030000','Odpisy umorzeniowe urz±dzeñ technicznych i maszyn','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('007040000','Odpisy umorzeniowe ¶rodków transportu','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('007050000','Odpisy umorzeniowe ulepszeñ obcych ¶rodków trwa³ych','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('007090000','Odpisy umorzeniowe innych ¶rodków trwa³ych','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('008000000','¦rodki trwa³e w budowie','A','','A','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('008010000','Inwestycje budowy ¶rodka trwa³ego','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('008020000','Ulepszenia ¶rodka trwa³ego','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('008030000','Nak³ady na budowê ¶rodka trwa³ego','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('008040000','Zaliczki na ¶rodki trwa³e w budowie','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('008050000','Ulepszenia obcych ¶rodków trwa³ych','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('009000000','Odpisy aktualizuj±ce d³ugoterminowe aktywa finansowe','A','','A','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('009010000','Odpisy aktualizuj±ce udzia³y i akcje w obcych jednostkach','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('009020000','Odpisy aktualizuj±ce lokaty','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('009030000','Odpisy aktualizuj±ce udzielone porzyczki d³ugoterminowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('009090000','Odpisy aktualizuj±ce inne rodzaje d³ugoterminowych aktywów finansowych','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('100000000','¦rodki pieniê¿ne, rachunki bankowe oraz inne krótkoterminowe aktywa finansowe','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('110000000','¦rodki pieniê¿ne w kasie','A','','A','AR:AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('110010000','Kasa krajowych ¶rodków pieniê¿nych','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('110020000','Kasa zagranicznych ¶rodków pieniê¿nych','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('113000000','Rachunki i kredyty bankowe','A','','A','AR:AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('113010000','Rachunek bie¿±cy','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('113020000','Rachunek ¶rodków wyodrêbnionych i zablokowanych','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('113030000','Rachunki kredytów bankowych','A','','A','AR_paid:AP_amount:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('113040000','Rachunek ¶rodków walutowych','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('114000000','Krótkoterminowe aktywa finansowe','A','','A','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('114010000','Krótkoterminowe aktywa finansowe w jednostkach powi±zanych','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('114010100','Udzia³y lub akcje','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('114010200','Inne papiery warto¶ciowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('114010300','Udzielone po¿yczki','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('114010400','Inne krótkoterminowe aktywa finansowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('114020000','Krótkoterminowe aktywa finansowe w pozosta³ych jednostkach','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('114020100','Udzia³y lub akcje','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('114020200','Inne papiery warto¶ciowe','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('114020400','Inne krótkoterminowe aktywa finansowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('115000000','Inne ¶rodki pieniê¿ne','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('116000000','Inne aktywa pieniê¿ne','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('117000000','Inne inwestycje krótkoterminowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('118000000','Krótkoterminowe rozliczenia miêdzyokresowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('200000000','Rozrachunki i roszczenia','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('220000000','Nale¿no¶ci krótkoterminowe','A','','L','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('220010000','Nale¿no¶ci od jednostek powi±zanych','A','','L','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('220010100','Nale¿no¶ci z tytu³u dostaw i us³ug','A','','L','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('220010110','Nale¿no¶ci z tytu³u dostaw i us³ug, o okresie sp³aty do 12 miesiêcy','A','','L','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('220010120','Nale¿no¶ci z tytu³u dostaw i us³ug, o okresie sp³aty powy¿ej 12 miesiêcy','A','','L','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('220010200','Inne nale¿no¶ci','A','','L','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('220010210','Zobowi±zania z tytu³u pokrycia kosztów ogólnego zarz±du','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('220010220','Zobowi±zania z tytu³u rozliczeñ VAT','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('221010000','Nale¿no¶ci od pozosta³ych jednostek','A','','L','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('221020100','Nale¿no¶ci z tytu³u dostaw i us³ug','A','','L','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('221020110','Nale¿no¶ci z tytu³u dostaw i us³ug, o okresie sp³aty do 12 miesiêcy','A','','L','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('221020120','Nale¿no¶ci z tytu³u dostaw i us³ug, o okresie sp³aty powy¿ej 12 miesiêcy','A','','L','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('221020200','Nale¿no¶ci z tytu³u podatków, dotacji, ce³, ubezpieczeñ spo³ecznych i zdrowotnych oraz innych ¶wiadczeñ','A','','L','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('221020300','Zaliczki przekazane dostawcom','A','','L','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('221020400','Nale¿no¶ci dochodzone na drodze s±dowej','A','','L','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('221020500','Inne nale¿no¶ci','A','','L','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222000000','Zobowi±zania krótkoterminowe','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222010000','Zobowi±zania wobec jednostek powiazanych','A','','L','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222010100','Zobowi±zania z tytu³u dostaw i us³ug','A','','L','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222010200','Zobowi±zania o okresie wymagalno¶ci do 12 miesiêcy','A','','L','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222010300','Zobowi±zania o okresie wymagalno¶ci powy¿ej 12 miesiêcy','A','','L','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222010400','Inne zobowi±zania','A','','L','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222020000','Zobowi±zania wobec pozosta³ych jednostek','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222020100','Kredyty i po¿yczki','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222020200','Zobowi±zania z tytu³u emisji d³u¿nych papierów warto¶ciowych','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222020300','Inne zobowi±zania finasowe','A','','L','AP_Amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222020400','Zobowiazania z tytu³u dostaw i us³ug','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222020500','Zobowi±zania o okresie wymagalno¶ci do 12 miesiêcy ','A','','L','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222020600','Zobowi±zania o okresie wymagalno¶ci powy¿ej 12 miesiêy','A','','L','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222020700','Zaliczki otrzmane na dostawy','A','','L','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222020800','Zobowi±zania wekslowe','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222020900','Zobowi±zania z tytu³u podatków, ce³, ubezpieczeñ i innych ¶wiadczeñ','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222021000','Zobowi±zania z tytu³u wynagrodzeñ','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('222021100','Inne zobowi±zania','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223000000','Rozrachunki publicznoprawne','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223010000','Rozrachunki z urzêdem skarbowym z tytu³u VAT','A','','L','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223020000','Rozliczenie nale¿nego VAT','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223020100','Rozliczenie nale¿nego VAT-22%','A','','L','AR_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223020200','Rozliczenie nale¿nego VAT-7%','A','','L','AR_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223020300','Rozliczenie nale¿nego VAT-0%','A','','L','AR_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223030000','Rozliczenie naliczonego VAT','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223030100','Rozliczenie naliczonego VAT-22%','A','','L','AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223030200','Rozliczenie naliczonego VAT-7%','A','','L','AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223030300','Rozliczenie naliczonego VAT-0%','A','','L','AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223040000','Korekty naliczonego VAT','A','','L','AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223050000','Rozrachunki z Urzêdem Celnym','A','','L','AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223060000','Rozrachunki z Urzêdem Skarbowym z tytu³u znaków akcyzy','A','','L','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223070000','Rozrachunki z Urzêdem Skarbowym z tytu³u podatku akcyzowego','A','','L','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223080000','Rozliczenie znaków akcyzy','A','','L','AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223090000','Rozrachunki z ZUS','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('223100000','Rozrachunki z Urzêdem Skarbowym z tytu³u podatku dochodowego od osób prawnych','A','','L','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('224000000','Rozrachunki z pracownikami','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('224010000','Rozrachunki z tytu³u wynagrodzeñ','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('224020000','Rozrachunki z tytu³u po¿yczek udzielonych pracownikom','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('224090000','Inne rozrachunki z pracownikami','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225000000','Zobowi±zania d³ugoterminowe','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225010000','Zobowi±zania wobec jednostek powi±zanych','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225010100','Zobowi±zania z tytu³u wyodrêbnienia sk³adników maj±tkowych','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225010200','Zobowi±zania z tytu³u podzia³u zysku','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225020000','Zobowi±zania wobec pozosta³ych jednostek','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225020100','Kredyty i po¿yczki otrzymane','A','','L','AR_amount:AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225020200','Kredyty i po¿yczki udzielone','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225020300','Zobowi±zania z tytu³u emisji d³u¿nych papierów warto¶ciowych','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225020400','Inne zobowi±zania kredytowe','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225020500','Inne zobowi±zania','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225030000','Rozrachunki z tytu³u wp³at na kapita³ zak³adowy','A','','L','AR_amount:APamount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225040000','Rozrachunki z tytu³u wk³adów niepieniê¿nych na kapita³ zak³adowy','A','','L','AR_amount:AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225050000','Rozrachunki z tytu³u podwy¿szenia kapita³u ze ¶rodków w³asnych spó³ki','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225060000','Rozrachunki z tytu³u umorzenia udzia³ów w³asnych','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225070000','Rozrachunki z tytu³u dywident','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225080000','Rozrachunki z tytu³u dop³at i zwrotu dop³at','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('225090000','Pozosta³e rozrachunki ze wspólnikami','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('229000000','Odpisy aktualizuj±ce rozrachunki','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('300000000','Materia³y i towary','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('330000000','Rozliczenie zakupu','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('330010000','Rozliczenie warto¶ci materia³ów i towarów w drodze','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('330020000','Warto¶ci dostaw niefakturowanych','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('330030000','Przychody wszelkich dostaw i us³ug i ich rozliczanie','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('330040000','Odhylenia cen ewidencyjnych od rzeczywistych cen nabycia lub zakupu','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('330050000','Koszty zakupu zawarte w fakturach dostawców','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('330060000','Op³aty manipulacyjne policzone przez Urz±d Celny','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('330070000','Niedobory, szkody i nadwy¿ki w transporcie','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('330080000','Znaki akcyzy wed³ug dokumentu SAD','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('330090000','Reklamacje faktur dostawców','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('331000000','Materia³y','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('331010000','Materia³y w magazynach w³asnych','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('331020000','Materia³y w magazynach obcych','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('331030000','Materia³y w przerobie','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('333000000','Towary','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('333010000','Towary w magazynach w³asnych','A','','A','IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('333020000','Towary w magazynach obcych','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('333030000','Towary w detalu','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('334000000','Odchylenia od cen ewidencyjnych materia³ów i towarów','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('334010000','Odpisy aktualizuj±ce warto¶æ materia³ów','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('334020000','Odpisy aktualizuj±ce warto¶æ towarów','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('400000000','Koszty wed³ug rodzajów i ich rozliczeñ','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440000000','Koszty wed³ug rodzajów','A','','E','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440010000','Zu¿ycie materia³ów i energii','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440010100','Zu¿ycie materia³ów biurowych','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440020000','Us³ugi obce','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440020100','Us³ugi celne','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440020200','Us³ugi telekomunikacyjne','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440020300','Us³ugi pocztowe','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440020400','Us³ugi kurierskie i transportowe','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440020500','Analizy sanitarne','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440020600','Us³ugi graficzne i drukarskie','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440030000','Podatki i op³aty','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440030100','Op³aty i prowizje bankowe','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440030200','Op³aty s±dowe, prawnicze i notarialne','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440030300','Op³aty skarbowe','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440030400','Koncesje','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440040000','Wynagrodzenia za pracê','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('441000000','¦wiadczenia na rzecz pracowników','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('442000000','Amortyzacja','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('443000000','Pozosta³e','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('449000000','Rozliczenie kosztów','A','','E','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('449010000','Nie podlegaj±ce rozliczeniu w czasie','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('449020000','Przypadaj±ce na przysz³e okresy','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('449030000','Koszty zgromadzone','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('449040000','Koszty nie wliczane do warto¶ci sprzeda¿y','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('500000000','Koszty wed³ug typów dzia³alno¶ci i ich rozliczenie','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('550000000','Koszty dzia³alno¶ci podstawowej-produkcyjnej','A','','E','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('550010000','Rozliczone koszta dzia³alno¶ci','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('550020000','Koszty nie zakoñczonych d³ugotrwa³ych us³ug','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('550030000','Straty zwi±zane z wykonaniem d³ugotrwa³ych us³ug','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('552000000','Koszty dzia³alno¶ci podstawowej-handlowej','A','','E','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('552010000','Koszty utrzymania punktów sprzeda¼y detalicznej','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('550200000','Koszty utrzymania hurtowni','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('552030000','Koszty sprzeda¿y wyrobów','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('552040000','Podatek akcyzowy','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('552050000','Op³aty celne','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('553000000','Koszty dzia³alno¶ci pomocniczej','A','','E','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('553010000','¦wiadczenia us³ug transportowych','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('555000000','Koszty zarz±du','A','','E','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('555010000','Koszty zarz±dzania jednostk±','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('555020000','¦wiadczenia us³ug na potrzeby reprezentacji i reklamy','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('558000000','Rozliczenie kosztów dzia³alno¶ci','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('600000000','Produkty i rozliczenia miêdzyokresowe','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('660000000','Pó³produkty i produkty w toku','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('661000000','Produkty gotowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('661010000','Wyroby gotowe','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('661020000','Wyroby poza jednostk±','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('662000000','Odchylenia od cen ewidencyjnych produktów','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('662010000','Odchylenia od cen evidencyjnych wyrobów gotowych','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('662020000','Odhylenia od cen evidencyjnych pó³fabrykatów','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('664000000','Rozliczenia miêdzyokresowe kosztów','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('664010000','Czynne rozliczenia miêdzyokresowe kosztów','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('664020000','Bierne rozliczenia miêdzyokresowe kosztów','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('665000000','Pozosta³e rozliczenia miêdzyokresowe','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('665010000','Czynne rozliczenia przysz³ych okresów','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('665020000','Bierne rozliczenia przysz³ych okresów','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('700000000','Przychody i koszty zwi±zane z ich osi±gniêciem','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('770000000','Sprzeda¿ produktów','A','','I','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('770010000','Sprzeda¿ produktów na kraj','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('770020000','Sprzeda¿ produktów na eksport','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('770030000','Sprzeda¿ us³ug na kraj','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('770040000','Sprzeda¿ us³ug na eksport','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('770100000','Koszty sprzedanych produktów','A','','E','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('770110000','Koszt w³asny sprzeda¿y produktów na kraj','A','','E','IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('770120000','Koszt w³asny sprzeda¿y produktów na eksport','A','','E','IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('770130000','Koszt w³asny sprzeda¿y us³ug na kraj','A','','E','IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('770140000','Koszt w³asny sprzeda¿y us³ug na export','A','','E','IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('773000000','Sprzeda¿ towarów','A','','I','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('773010000','Sprzeda¿ hurtowa towarów','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('773020000','Sprzeda¿ detaliczna towarów','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('773030000','Sprzeda¿ wysy³kowa towarów','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('773040000','Prowizja komisowa','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('773100000','Warto¶æ sprzedanych towarów w cenach zakupu','A','','E','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('773110000','Warto¶æ sprzedanych towarów w sprzeda¿y hurtowej','A','','E','IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('773120000','Warto¶æ sprzedanych towarów w sprzeda¿y detalicznej','A','','E','IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('773130000','Warto¶æ sprzedanych towarów w sprzeda¿y wysy³kowej','A','','E','IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('773140000','Prowizja komisowa','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('774000000','Sprzeda¿ materia³ów','A','','I','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('774010000','Materia³y','A','','I','AP_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('774020000','Opakowania','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('774030000','Odpady','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('774100000','Warto¶æ sprzedanych materia³ów','A','','E','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('774110000','Warto¶æ w cenach zakupu sprzedanych materia³ów','A','','E','IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('774120000','Warto¶æ w cenach zakupu sprzedanych opakowañ','A','','E','IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('774130000','Warto¶æ w cenach zakupu sprzedanych odpadów','A','','E','IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775000000','Przychody finansowe','A','','I','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775010000','Kwoty nale¿ne ze sprzeda¿y aktywów finansowych','A','','I','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775020000','Kwoty nale¿ne z tytu³u dywident','A','','I','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775030000','Otrzymane odsetki','A','','I','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775040000','Przychody ze zbycia investycji','A','','I','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775050000','Aktualizacja warto¶ci investycji-przychody','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775060000','Dodatnie ró¿nice kursu walut','A','','I','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775070000','Pozosta³e przychody finansowe','A','','I','AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775100000','Koszty finansowe','A','','E','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775110000','Warto¶æ sprzedanych investycji','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775120000','Odpisy z tytu³u utraty warto¶ci investycji-koszty','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775130000','Odsetki zap³acone','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775140000','Ujemne ró¿nice kursu walut','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('775190000','Pozosta³e koszty finansowe','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('776000000','Pozosta³e przychody operacyjne','A','','I','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('776010000','Przychody ze zbycia niefinansowych aktywów trwa³ych','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('776020000','Otrzymane dotacje','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('776030000','Przychody z us³ug socjalnych','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('776040000','Przychody ze wzrostu warto¶ci niefinansowych aktywów trwa³ych','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('776090000','Inne pozosta³e przychody operacyjne','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('776100000','Pozosta³e koszty operacyjne','A','','E','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('776110000','Warto¶æ sprzedanych niefinansowych aktywów trwa³ych','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('776120000','Dotacje przekazane','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('776130000','Odpisy z tytu³u utraty warto¶ci aktywów niefinansowych','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('776140000','Inne pozosta³e koszty operacyjne','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('777000000','Zyski nadzwyczajne','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('777100000','Straty nadzwyczajne','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('779000000','Obroty wewnêtrzne','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('779010000','Koszt wyrobów w³asnej produkcji wydanych do w³asnych sklepów','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('779020000','¦wiadczenia na rzecz ¶rodków trwa³ych w budowie','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('779040000','Koszt niedoborów produktów','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('779050000','Koszt zaniechania okre¶lonego rodzaju dzia³alno¶ci','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('779100000','Koszt obrotów wewnêtrznych','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('779110000','Koszt wytworzenia wyrobów gotowych wydanych do w³asnych sklepów','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('779120000','Koszt wytworzenia ¶wiadczeñ na rzecz ¶rodków trwa³ych w budowie','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('779130000','Koszt wytworzenia zakoñczonych prac rozwojowych','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('779140000','Koszt wytworzenia produktów uznanych za niedobory','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('779150000','Koszt zaniechania okre¶lonego rodzaju dzia³alno¶ci','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('800000000','Kapita³y w³asne i wynik finansowy','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('880000000','Kapita³ podstawowy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('880010000','Kapita³ zak³adowy','A','','Q','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('881000000','Fundusze wydzielone jednostkom zale¿nym','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('882000000','Nale¿ne wp³aty na kapita³ podstawowy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('883000000','Fundusze wydzielone jednostkom zale¿nym','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('884000000','Kapita³ zapasowy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('885000000','Kapita³ rezerwowy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('886000000','Kapita³ z aktualizacji wyceny','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('887000000','Rozliczenia wyniku finansowego','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('888000000','Rezerwy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('888010000','Rezerwa z tytu³u odroczonego podatku dochodowego','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('888020000','Rezerwa na ¶wiadczenia','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('888020100','Rezerwa d³ugoterminowa na ¶wiadczenia emerytalne i podobne','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('888020200','Rezerwa krótkoterminowa na ¶wiadczenia emerytalne i podobne','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('889090000','Pozosta³e rezerwy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('889090100','Pozosta³e rezerwy d³ugoterminowe','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('889090200','Pozosta³e rezerwy krótkoterminowe','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('890000000','Rozliczenia miêdzyokresowe','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('890010000','Ujemna warto¶æ firmy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('890020000','Inne rozliczenia miêdzyokresowe','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('890020100','Inne rozliczenia miêdzyokresowe d³ugoterminowe','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('890020200','Inne rozliczenia miêdzyokresowe krótkoterminowe','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('891000000','Fundusze specjalne','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('892000000','Wynik finansowy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('893000000','Odpisy z zysku netto w ci±gu roku obrotowego','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('893010000','Podatek dochodowy','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('893020000','Inne obowi±zkowe obci±¿enia wyniku finansowego','A','','Q','');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '223020100'),0.22);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '223020200'),0.07);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '223020300'),0);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '223030100'),0.22);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '223030200'),0.07);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '223030300'),0);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '333000000'), income_accno_id = (select id from chart where accno = '773010000'), expense_accno_id = (select id from chart where accno = '773110000'), fxgain_accno_id = (select id from chart where accno = '775060000'), fxloss_accno_id = (select id from chart where accno = '775140000'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'PLN:USD:EUR', weightunit = 'kg';
+--
+
+
diff --git a/sql-ledger/sql/Simplified_Chinese_Default-chart.sql b/sql-ledger/sql/Simplified_Chinese_Default-chart.sql
new file mode 100644 (file)
index 0000000..680adb8
--- /dev/null
@@ -0,0 +1,78 @@
+-- Default chart of accounts -- sample only
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2190','Ó¦¸¶ËùµÃË°','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2600','³¤ÆÚ¸ºÕ®','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3300','¹É·Ý×ʱ¾','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3500','±£ÁôÓ¯âÅ','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4000','ÏúÊÛÓ¯âÅ','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4300','ÚÑѯӯâÅ','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4400','ÆäËüÓ¯âÅ','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5000','»õÏú³É±¾','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5400','н×ÊÖ§³ö','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5600','ÈÕ³£¼°¹ÜÀíÖ§³ö','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1205','´ôÕʱ¸µÖ','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1000','Á÷¶¯×ʲú','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1800','×ʱ¾×ʲú','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1825','ÀۼƷÖÆÚ¸¶¿î - ×°è«¼°É豸.','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1845','ÀۼƷÖÆÚ¸¶¿î - ÔËÊ乤¾ß','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2000','Á÷¶¯¸ºÕ®','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2620','ÒøÐнè¿î','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3600','Á÷¶¯Ó¯âÅ','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2160','Ó¦¸¶¹«Ë¾Ë°','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3590','±£ÁôÓ¯âÅ - È¥Äê¶È','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3350','ÆÕͨ¹É·Ý','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1500','´æ»õ×ʲú','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5615','¹ã¸æÐÐÏú','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5790','¹¤¾ß','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5700','°ì¹«ÓÃÆ·','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5800','ȨÀû½ð','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5610','»á¼Æ·¨Îñ','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5685','±£ÏÕ','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5660','·ÖÆÚÖ§³ö','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5620','»µÕÊ','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5680','ËùµÃË°','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5690','ÀûÏ¢¼°ÒøÐÐÊÖÐø·Ñ','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5410','н×Ê','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5420','±£ÏÕÖ§³ö','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5430','ÍËÐݽðÖ§³ö','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5440','²¹³¥½ðÖ§³ö','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5470','Ô±¹¤¸£Àû','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4030','ÏúÊÛ / ÈíÌå','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4440','ÀûÏ¢','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5100','ÔË·Ñ','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5760','×â½ð','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1530','¿â´æ / ÈíÌå','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1540','¿â´æ / ¶þ¼¶Êг¡Áã¼þ','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4040','ÏúÊÛ / ¶þ¼¶Êг¡Áã¼þ','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5030','»õÏú³É±¾ / ÈíÌå','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5010','²É¹º','A','','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5040','»õÏú³É±¾ / ¶þ¼¶Êг¡Áã¼þ','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1065','ÁãÓýð','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1820','°ì¹«ÊÒװ諼°É豸','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5785','Â÷Ѽ°ÓéÀÖ','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2680','¹É¶«´û¿î','A','','L','AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5795','×¢²á·Ñ','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5780','µçÐÅ·Ñ','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5781','Íø·Á¬Ïß·Ñ','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5765','άÐÞ¹ÜÀí·Ñ','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2311','µØ·½Ë°','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4430','ÔËÏú·Ñ','A','','I','IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1520','¿â´æ / Ó²Ìå','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5020','»õÏú³É±¾ / Ó²Ìå','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2100','Ó¦¸¶ÕÊ¿î','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1840','ÔËÊ乤¾ß','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4330','³ÌʽÉè¼Æ','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4020','ÏúÊÛ / Ó²Ìå','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4320','ÚÑѯ','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1200','Ó¦ÊÕÕÊ¿î','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1061','֧Ʊ»§Í·','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2310','ÉÌÆ··þÎñË°','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+--
+-- exchange rate
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4450','Foreign Exchange Gain','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5810','Foreign Exchange Loss','A','','E','');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2310'),0.07);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2311'),0.08);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '1520'), income_accno_id = (select id from chart where accno = '4020'), expense_accno_id = (select id from chart where accno = '5010'), fxgain_accno_id = (select id from chart where accno = '4450'), fxloss_accno_id = (select id from chart where accno = '5810'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'CAD', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/Spain-chart.sql b/sql-ledger/sql/Spain-chart.sql
new file mode 100644 (file)
index 0000000..8c304a8
--- /dev/null
@@ -0,0 +1,132 @@
+-- Chart of Accounts for Spain (Cuadro del Plan de Contabilidad español)
+-- From: Federico Montesino Pouzols <fedemp@arrok.com>
+-- 23 Apr 2002
+-- 
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('099999999','Grupo 1: financiación básica','H','','','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('100000000','Capital','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('110000000','Reservas','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('120000000','Resultados pendientes de aplicación','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('130000000','Ingresos a distribuir en varios ejercicios','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('140000000','Provisiones para riesgos y gastos','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('150000000','Empréstitos y otras emisiones análogas','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('160000000','Deudas a largo plazo con empresas del grupo y asociadas','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('170000000','Deudas a largo plazo por prestamos recibidos y otros conceptos','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('180000000','Fianzas y depósitos recibidos a largo plazo','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('190000000','Situaciones transitorias de financiación','A','','A','');
+--
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('199999999','Grupo 2: inmovilizado','H','','','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('200000000','Gastos de establecimiento','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('210000000','Inmovilizaciones inmateriales','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('220000000','Inmovilizaciones materiales','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('230000000','Inmovilizaciones materiales en curso','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('240000000','Inversiones financieras en empresas del grupo y asociadas','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('250000000','Otras inversiones financieras permanentes','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('260000000','Fianzas y depósitos constituidos a largo plazo','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('270000000','Gastos a distribuir en varios ejercicios','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('280000000','Amortización acumulada del inmovilizado','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('290000000','Provisiones de inmovilizado','A','','A','');
+--
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('299999999','Grupo 3: existencias','H','','','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('300000000','Comerciales','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('310000000','Materias primas','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('320000000','Otros aprovisionamientos','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('330000000','Productos en curso','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('340000000','Productos semiterminados','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('350000000','Productos terminados','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('360000000','Subproductos, residuos y materiales recuperados','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('390000000','Provisiones por depreciación de existencias','A','','A','');
+--
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('399999999','Grupo 4: acreedores y deudores por operaciones de tráfico','H','','','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('400000000','Proveedores','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('410000000','Acreedores varios','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('430000000','Clientes','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('431000000','Clientes, efectos comerciales a cobrar','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('440000000','Deudores varios','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('460000000','Personal','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('470000000','Administraciones públicas','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('472000000','Hacienda Pública, IVA soportado','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('472000001','IVA soportado 4%','A','','P','AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('472000002','IVA soportado 7%','A','','P','AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('472000003','IVA soportado 16%','A','','P','AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('475100000','Hacienda Pública, acreedor por retenciones practicadas','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('473000000','Hacienda Pública, retenciones y pagos a cuenta','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('477000000','Hacienda Pública, IVA repercutido','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('477000001','IVA repercutido 4%','A','','P','AR_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('477000002','IVA repercutido 7%','A','','P','AR_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('477000003','IVA repercutido 16%','A','','P','AR_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('480000000','Ajustes por periodificación','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('490000000','Provisiones por operaciones de tráfico','A','','P','');
+--
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('499999999','Grupo 5: cuentas financieras','H','','','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('500000000','Empréstitos y otras emisiones análogas a corto plazo','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('510000000','Deudas a corto plazo con empresas del grupo y asociadas','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('520000000','Deudas a corto plazo por préstamos recibidos y otros conceptos','A','','P','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('530000000','Inversiones financieras a corto plazo en empresas del grupo y asociadas','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('540000000','Otras inversiones financieras temporales','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('550000000','Otras cuentas no bancarias','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('560000000','Fianzas y depósitos recibidos y constituidos a corto plazo','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('569000000','Tesorería','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('570000000','Caja, euros','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('571000000','Caja, moneda extranjera','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('572000000','Bancos e instituciones de crédito, c/c. vista, euros','A','','A','AR_paid:AP_paid:AP_amount:AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('573000000','Bancos e instituciones de crédito, c/c. vista, moneda extranjera','A','','A','AR_paid:AP_paid:AP_amount:AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('574000000','Bancos e instituciones de crédito, cuentas de ahorro, euros','A','','A','AR_paid:AP_paid:AP_amount:AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('575000000','Bancos e instituciones de crédito, cuentas de ahorro, moneda extranjera','A','','A','AR_paid:AP_paid:AP_amount:AR_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('580000000','Ajustes por periodificación','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('590000000','Provisiones financieras','A','','P','');
+--
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('599999999','Grupo 6: compras y gastos','H','','','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('600000000','Compras','A','','E','AP:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('608000000','Devoluciones de compras y operaciones similares','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('610000000','Variación de existencias','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('620000000','Servicios exteriores','A','','E','IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('630000000','Tributos','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('640000000','Gastos de personal','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('650000000','Otros gastos de gestión','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('660000000','Gastos financieros','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('665000000','Descuentos sobre ventas por pronto pago','A','','E','IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('668000000','Diferencias negativas de cambio','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('670000000','Pérdidas procedentes del inmovilizado y gastos excepcionales','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('680000000','Dotaciones para amortizaciones','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('690000000','Dotaciones a las provisiones','A','','E','');
+--
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('699999999','Grupo 7: ventas e ingresos','H','','','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('700000000','Ventas de mercaderías, de producción propia, de servicios, etc.','A','','I','AR:IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('708000000','Devoluciones de ventas y operaciones similares','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('710000000','Variación de existencias','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('730000000','Trabajos realizados para la empresa','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('740000000','Subvenciones a la explotación','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('750000000','Otros ingresos de gestión','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('760000000','Ingresos financieros','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('765000000','Descuentos sobre compras por pronto pago','A','','I','IC_sale:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('768000000','Diferencias positivas de cambio','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('770000000','Beneficios procedentes de inmovilizados e ingresos excepcionales','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('790000000','Excesos y aplicaciones de provisiones','A','','I','');
+--
+-- Taxes in Spain
+--
+-- IVA: 4, 7 or 16%
+-- IVA soportado
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '472000000'), 0.0);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '472000001'), 0.04);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '472000002'), 0.07);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '472000003'), 0.16);
+-- Recargo equivalente: 0.5, 1 or 4%
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '472000004'), 0.005);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '472000005'), 0.01);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '472000006'), 0.04);
+--
+-- IVA repercutido
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '477000000'), 0.0);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '477000001'), 0.04);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '477000002'), 0.07);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '477000003'), 0.16);
+-- Recargo equivalente: 0.5, 1 or 4%
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '477000004'), 0.005);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '477000005'), 0.01);
+INSERT INTO "tax" ("chart_id", "rate") VALUES ((SELECT id FROM chart WHERE accno = '477000006'), 0.04);
+--
+-- update defaults
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '300000000'), income_accno_id = (select id from chart where accno = '700000000'), expense_accno_id = (select id from chart where accno = '600000000'), fxgain_accno_id = (select id from chart where accno = '768000000'), fxloss_accno_id = (select id from chart where accno = '668000000'), invnumber = 'F00000000', sonumber = '100000000', ponumber = '100000000', yearend = '31/12', curr = 'EUR', weightunit = 'Kg', businessnumber = '';
+--
diff --git a/sql-ledger/sql/Swiss-German-chart.sql b/sql-ledger/sql/Swiss-German-chart.sql
new file mode 100644 (file)
index 0000000..75959ef
--- /dev/null
@@ -0,0 +1,160 @@
+-- Swiss chart of accounts
+-- adapted to numeric representation of chart no.
+--
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('10000','AKTIVEN','H','1','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11000','UMLAUFSVERMÖGEN','H','10000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11100','Flüssige Mittel','H','11000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11102','Bank CS Kt. 177929-11','A','11100','A','AR_paid:AP_paid');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11110','Forderungen','H','11000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11120','Vorräte und angefangene Arbeiten','H','11000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11128','Angefangene Arbeiten','A','11120','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11130','Aktive Rechnungsabgrenzung','A','11000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('14000','ANLAGEVERMÖGEN','H','10000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('18000','AKTIVIERTER AUFWAND UND AKTIVE BERICHTIGUNGSPOSTEN','H','10000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('18182','Entwicklungsaufwand','A','18000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('20000','PASSIVEN','H','2','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21000','FREMDKAPITAL KURZFRISTIG','H','20000','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21200','Kurzfristige Verbindlichkeiten aus Lieferungen und Leistungen','H','21000','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21201','Lieferanten','A','21200','L','AP');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21202','Personalaufwand','A','21200','L','AP');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21203','Sozialversicherungen','A','21200','L','AP');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21205','Leasing','A','21200','L','AP');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21210','Kurzfristige Finanzverbindlichkeiten','H','21000','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21220','Andere kurzfristige Verbindlichkeiten','H','21000','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21222','MWST (3,6)','A','21220','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21229','Gewinnausschüttung','A','21220','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21230','Passive Rechnungsabgrenzung, kurzfristige Rückstellungen','H','21000','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21235','Rückstellungen','A','21230','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('24000','FREMDKAPITAL LANGFRISTIG','H','20000','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('24256','Gesellschafter','A','24000','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('28000','EIGENKAPITAL','H','20000','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('28280','Stammkapital','A','28000','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('28290','Reserven, Bilanzgewinn','H','28000','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('28291','Reserven','A','28290','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('28295','Gewinnvortrag','A','28290','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('28296','Jahresgewinn','A','28290','Q','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('30000','BETRIEBSERTRAG AUS LIEFERUNGEN UND LEISTUNGEN','H','30000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('31000','PRODUKTIONSERTRAG','H','30000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('31001','Computer','A','31000','I','AR_amount:IC_sale');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('31005','Übrige Produkte','A','31000','I','AR_amount:IC_sale');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('32000','HANDELSERTRAG','H','30000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('32001','Hardware','A','32000','I','AR_amount:IC_sale');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('32002','Software OSS','A','32000','I','AR_amount:IC_sale');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('32003','Software kommerz.','A','32000','I','AR_amount:IC_sale');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('32005','Übrige','A','32000','I','AR_amount:IC_sale');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('34000','DIENSTLEISTUNGSERTRAG','H','30000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('34001','Beratung','A','34000','I','AR_amount:IC_income');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('34002','Installation','A','34000','I','AR_amount:IC_income');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('36000','ÜBRIGER ERTRAG','H','30000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('37000','EIGENLEISTUNGEN UND EIGENVERBRAUCH','H','30000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('37001','Eigenleistungen','A','37000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('37002','Eigenverbrauch','A','37000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('38000','BESTANDESÄNDERUNGEN ANGEFANGENE UND FERTIGGESTELLTE ARBEITUNG AUS PRODUKTION UND DIENSTLEISTUNG','H','30000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('38001','Bestandesänderungen','A','38000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('39000','ERTRAGSMINDERUNGEN AUS PRODUKTIONS-, HANDELS- UND DIENSTLEISTUNGSERTRÄGEN','H','30000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('40000','AUFWAND FÜR MATERIAL, WAREN UND DIENSTLEISTUNGEN','H','40000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('41000','MATERIALAUFWAND','H','40000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('41001','Computer','A','41000','E','AP_amount:IC_cogs');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('41005','Übrige Produkte','A','41000','E','AP_amount:IC_cogs');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('42000','HANDELSWARENAUFWAND','H','40000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('42001','Hardware','A','42000','E','AP_amount:IC_cogs');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('42002','Software OSS','A','32000','I','AP_amount:IC_cogs');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('42003','Software kommerz.','A','42000','I','AP_amount:IC_cogs');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('42005','Übrige','A','42000','E','AP_amount:IC_cogs');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('44000','AUFWAND FÜR DRITTLEISTUNGEN','H','40000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('46000','ÜBRIGER AUFWAND','H','40000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('47000','DIREKTE EINKAUFSSPESEN','H','40000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('47001','Einkaufsspesen','A','47000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('48000','BESTANDESVERÄNDERUNGEN, MATERIAL- UND WARENVERLUSTE','H','40000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('48001','Bestandesänderungen','A','48000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('49000','AUFWANDMINDERUNGEN','H','40000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('49005','Aufwandminderungen','A','49000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('50000','PERSONALAUFWAND','H','50000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('57000','SOZIALVERSICHERUNGSAUFWAND','H','50000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('58000','ÜBRIGER PERSONALAUFWAND','H','58000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('58005','Sonstiger Personalaufwand','A','58000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('59000','ARBEITSLEISTUNGEN DRITTER','H','50000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('60000','SONSTIGER BETRIEBSAUFWAND','H','60000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('61000','RAUMAUFWAND','H','60000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('61900','UNTERHALT, REPARATUREN, ERSATZ, LEASINGAUFWAND MOBILE SACHANLAGEN','H','60000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('61901','Unterhalt','A','61900','E','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('62000','FAHRZEUG- UND TRANSPORTAUFWAND','H','60000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('62002','Transportaufwand','A','62000','E','AP_amount');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('63000','SACHVERSICHERUNGEN, ABGABEN, GEBÜHREN, BEWILLIGUNGEN','H','60000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('65000','VERWALTUNGS- UND INFORMATIKAUFWAND','H','60000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('66000','WERBEAUFWAND','H','60000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('67000','ÜBRIGER BETRIEBSAUFWAND','H','60000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('67001','Übriger Betriebsaufwand','A','67000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('68000','FINANZERFOLG','H','60000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('68001','Finanzaufwand','A','68000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('68002','Bankspesen','A','68000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('68005','Finanzertrag','A','68000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('69000','ABSCHREIBUNGEN','H','60000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('69001','Abschreibungen','A','69000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('80000','AUSSERORDENTLICHER UND BETRIEBSFREMDER ERFOLG, STEUERN','H','80000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('80001','Ausserordentlicher Ertrag','A','80000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('80002','Ausserordentlicher Aufwand','A','80000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('89000','STEUERAUFWAND','H','80000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('89001','Steuern','A','80000','E','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('90000','ABSCHLUSS','H','90000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('91000','ERFOLGSRECHNUNG','H','91000','I','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('92000','BILANZ','H','92000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('93000','GEWINNVERWENDUNG','H','93000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('99000','SAMMEL- UND FEHLBUCHUNGEN','H','99000','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11121','Warenvorräte','A','11120','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('44001','Aufwand für Drittleistungen','A','44000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('63001','Betriebsversicherungen','A','63000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('57004','Unfallversicherung','A','57000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('57005','Krankentaggeldversicherung','A','57000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('57003','Berufliche Vorsorge','A','57000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('57002','FAK','A','57000','E','AP_amount:IC_income:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('65009','Übriger Verwaltungsaufwand','A','65000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('65003','Porti','A','65000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('65002','Telekomm','A','65000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('65001','Büromaterial','A','65000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('18181','Gründungsaufwand','A','18000','A','IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('50001','Löhne und Gehälter','A','50000','E','IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('50002','Erfolgsbeteiligungen','A','50000','E','IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21216','Gesellschafter','A','21210','L','AP');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('62001','Fahrzeugaufwand','A','62000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('58003','Spesen','A','58000','E','IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('65004','Fachliteratur','A','65000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('39001','Skonti','A','39000','I','IC_sale:IC_cogs:IC_income:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('39002','Rabatte, Preisnachlässe','A','39000','I','IC_sale:IC_cogs:IC_income:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('36005','Kursgewinn','A','39000','I','IC_sale:IC_cogs:IC_income');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('39006','Kursverlust','A','39000','E','IC_sale:IC_cogs:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('39005','Verluste aus Forderungen','A','39000','E','IC_sale:IC_cogs:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('14151','Mobiliar und Einrichtungen','A','14150','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('14152','Büromaschinen, EDV','A','14150','A','IC');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11119','Verrechnungssteuer','A','11110','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11118','MWST Vorsteuer auf Investitionen','A','11110','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('36004','Versand','A','36000','I','IC_income');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('36001','Reisezeit','A','36000','I','IC_income');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('36002','Reise (Fahrt)','A','36000','I','IC_income');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11117','MWST Vorsteuer auf Aufwand','A','11110','A','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21228','Geschuldete Steuern','A','21220','L','AP');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21223','MWST (7,6)','A','21220','L','AR_tax:AP_tax:IC_taxpart:IC_expense:IC_taxservice:CT_tax');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('57001','AHV, IV, EO, ALV','A','57000','E','AP_amount:IC_income:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21221','MWST (2,4)','A','21220','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21224','MWST (7.6) 1/2','A','21220','L','AR_tax:AP_tax:IC_taxpart:IC_expense:IC_taxservice:CT_tax');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('66001','Werbeaufwand','A','66000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21217','Privat','A','21210','L','AP');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11101','Kasse','A','11100','A','AR_paid:AP_paid');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('50005','Leistungen von Sozialversicherung','A','50000','E','AP_amount:IC_income:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('65005','Informatikaufwand','A','65000','E','AP_amount:IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('39004','Rundungsdifferenzen','A','39000','I','AR_paid:AP_paid');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('11111','Debitoren','A','11110','A','AR');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('61001','Miete','A','61000','E','IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('61002','Reinigung','A','61000','E','IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('61005','Übriger Raumaufwand','A','61000','E','IC_expense');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('36003','Essen','A','36000','I','IC_income');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('21231','Passive Rechnungsabgrenzung','A','21230','L','');
+INSERT INTO chart (accno,description,charttype,gifi_accno,category,link) VALUES ('67002','Produkteentwicklung','A','67000','E','');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '21222'),0.036);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '21223'),0.076);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '21221'),0.024);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '21224'),0.076);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '11121'), income_accno_id = (select id from chart where accno = '34002'), expense_accno_id = (select id from chart where accno = '42005'), fxgain_accno_id = (select id from chart where accno = '36005'), fxloss_accno_id = (select id from chart where accno = '39006'), invnumber = '2002000', sonumber = '2002000', ponumber = '2002000', curr = 'EUR:USD', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/Swiss-German-gifi.sql b/sql-ledger/sql/Swiss-German-gifi.sql
new file mode 100644 (file)
index 0000000..ecd526d
--- /dev/null
@@ -0,0 +1,55 @@
+--
+INSERT INTO gifi (accno,description) VALUES ('1','AKTIVEN');
+INSERT INTO gifi (accno,description) VALUES ('2','PASSIVEN');
+INSERT INTO gifi (accno,description) VALUES ('4','AUFWAND FÜR MATERIAL, WAREN UND DIENSTLEISTUNGEN');
+INSERT INTO gifi (accno,description) VALUES ('5','PERSONALAUFWAND');
+INSERT INTO gifi (accno,description) VALUES ('10000','ANLAGEVERMÖGEN');
+INSERT INTO gifi (accno,description) VALUES ('11000','Forderungen');
+INSERT INTO gifi (accno,description) VALUES ('11100','Bank');
+INSERT INTO gifi (accno,description) VALUES ('11110','MWST Vorsteuer auf Investitionen');
+INSERT INTO gifi (accno,description) VALUES ('11120','Angefangene Arbeiten');
+INSERT INTO gifi (accno,description) VALUES ('14150','Büromaschinen, EDV');
+INSERT INTO gifi (accno,description) VALUES ('18000','Gründungsaufwand');
+INSERT INTO gifi (accno,description) VALUES ('20000','FREMDKAPITAL LANGFRISTIG');
+INSERT INTO gifi (accno,description) VALUES ('21000','Kurzfristige Finanzverbindlichkeiten');
+INSERT INTO gifi (accno,description) VALUES ('21200','Sozialversicherungen');
+INSERT INTO gifi (accno,description) VALUES ('21210','Gesellschafter');
+INSERT INTO gifi (accno,description) VALUES ('21220','MWST (3,6)');
+INSERT INTO gifi (accno,description) VALUES ('21230','Passive Rechnungsabgrenzung');
+INSERT INTO gifi (accno,description) VALUES ('24000','Gesellschafter');
+INSERT INTO gifi (accno,description) VALUES ('28000','Stammkapital');
+INSERT INTO gifi (accno,description) VALUES ('28290','Gewinnvortrag');
+INSERT INTO gifi (accno,description) VALUES ('30000','ÜBRIGER ERTRAG');
+INSERT INTO gifi (accno,description) VALUES ('31000','Computer');
+INSERT INTO gifi (accno,description) VALUES ('32000','Software kommerz.');
+INSERT INTO gifi (accno,description) VALUES ('34000','Beratung');
+INSERT INTO gifi (accno,description) VALUES ('36000','Essen');
+INSERT INTO gifi (accno,description) VALUES ('37000','Eigenleistungen');
+INSERT INTO gifi (accno,description) VALUES ('38000','Bestandesänderungen');
+INSERT INTO gifi (accno,description) VALUES ('39000','Rabatte, Preisnachlässe');
+INSERT INTO gifi (accno,description) VALUES ('40000','AUFWANDMINDERUNGEN');
+INSERT INTO gifi (accno,description) VALUES ('41000','Übrige Produkte');
+INSERT INTO gifi (accno,description) VALUES ('42000','Software kommerz.');
+INSERT INTO gifi (accno,description) VALUES ('44000','Aufwand für Drittleistungen');
+INSERT INTO gifi (accno,description) VALUES ('47000','Einkaufsspesen');
+INSERT INTO gifi (accno,description) VALUES ('48000','Bestandesänderungen');
+INSERT INTO gifi (accno,description) VALUES ('49000','Aufwandminderungen');
+INSERT INTO gifi (accno,description) VALUES ('50000','Löhne und Gehälter');
+INSERT INTO gifi (accno,description) VALUES ('57000','FAK');
+INSERT INTO gifi (accno,description) VALUES ('58000','Spesen');
+INSERT INTO gifi (accno,description) VALUES ('60000','VERWALTUNGS- UND INFORMATIKAUFWAND');
+INSERT INTO gifi (accno,description) VALUES ('61000','Reinigung');
+INSERT INTO gifi (accno,description) VALUES ('61900','Unterhalt');
+INSERT INTO gifi (accno,description) VALUES ('62000','Fahrzeugaufwand');
+INSERT INTO gifi (accno,description) VALUES ('63000','Betriebsversicherungen');
+INSERT INTO gifi (accno,description) VALUES ('65000','Übriger Verwaltungsaufwand');
+INSERT INTO gifi (accno,description) VALUES ('66000','Werbeaufwand');
+INSERT INTO gifi (accno,description) VALUES ('67000','Produkteentwicklung');
+INSERT INTO gifi (accno,description) VALUES ('68000','Finanzaufwand');
+INSERT INTO gifi (accno,description) VALUES ('69000','Abschreibungen');
+INSERT INTO gifi (accno,description) VALUES ('80000','AUSSERORDENTLICHER UND BETRIEBSFREMDER ERFOLG, STEUERN');
+INSERT INTO gifi (accno,description) VALUES ('90000','ABSCHLUSS');
+INSERT INTO gifi (accno,description) VALUES ('91000','ERFOLGSRECHNUNG');
+INSERT INTO gifi (accno,description) VALUES ('92000','BILANZ');
+INSERT INTO gifi (accno,description) VALUES ('93000','GEWINNVERWENDUNG');
+INSERT INTO gifi (accno,description) VALUES ('99000','SAMMEL- UND FEHLBUCHUNGEN');
diff --git a/sql-ledger/sql/Traditional_Chinese_Default-chart.sql b/sql-ledger/sql/Traditional_Chinese_Default-chart.sql
new file mode 100644 (file)
index 0000000..68ebeac
--- /dev/null
@@ -0,0 +1,78 @@
+-- Default chart of accounts -- sample only
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2190','À³¥I©Ò±oµ|','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2600','ªø´Á­t¶Å','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3300','ªÑ¥÷¸ê¥»','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3500','«O¯d¬Õ¾l','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4000','¾P°â¬Õ¾l','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4300','¿Ô¸ß¬Õ¾l','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4400','¨ä¥¦¬Õ¾l','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5000','³f¾P¦¨¥»','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5400','Á~¸ê¤ä¥X','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5600','¤é±`¤ÎºÞ²z¤ä¥X','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1205','§b±b³Æ©è','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1000','¬y°Ê¸ê²£','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1800','¸ê¥»¸ê²£','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1825','²Ö­p¤À´Á¥I´Ú - ¸Ë¿X¤Î³]³Æ.','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1845','²Ö­p¤À´Á¥I´Ú - ¹B¿é¤u¨ã','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2000','¬y°Ê­t¶Å','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2620','»È¦æ­É´Ú','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3600','¬y°Ê¬Õ¾l','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2160','À³¥I¤½¥qµ|','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3590','«O¯d¬Õ¾l - ¥h¦~«×','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3350','´¶³qªÑ¥÷','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1500','¦s³f¸ê²£','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5615','¼s§i¦æ¾P','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5790','¤u¨ã','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5700','¿ì¤½¥Î«~','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5800','Åv§Qª÷','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5610','·|­pªk°È','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5685','«OÀI','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5660','¤À´Á¤ä¥X','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5620','Ãa±b','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5680','©Ò±oµ|','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5690','§Q®§¤Î»È¦æ¤âÄò¶O','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5410','Á~¸ê','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5420','«OÀI¤ä¥X','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5430','°h¥ðª÷¤ä¥X','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5440','¸ÉÀvª÷¤ä¥X','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5470','­û¤uºÖ§Q','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4030','¾P°â / ³nÅé','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4440','§Q®§','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5100','¹B¶O','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5760','¯²ª÷','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1530','®w¦s / ³nÅé','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1540','®w¦s / ¤G¯Å¥«³õ¹s¥ó','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4040','¾P°â / ¤G¯Å¥«³õ¹s¥ó','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5030','³f¾P¦¨¥» / ³nÅé','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5010','±ÄÁÊ','A','','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5040','³f¾P¦¨¥» / ¤G¯Å¥«³õ¹s¥ó','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1065','¹s¥Îª÷','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1820','¿ì¤½«Ç¸Ë¿X¤Î³]³Æ','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5785','®È¶O¤Î®T¼Ö','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2680','ªÑªF¶U´Ú','A','','L','AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5795','µù¥U¶O','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5780','¹q«H¶O','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5781','ºô¸ô³s½u¶O','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5765','ºû­×ºÞ²z¶O','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2311','¦a¤èµ|','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4430','¹B¾P¶O','A','','I','IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1520','®w¦s / µwÅé','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5020','³f¾P¦¨¥» / µwÅé','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2100','À³¥I±b´Ú','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1840','¹B¿é¤u¨ã','A','','A','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4330','µ{¦¡³]­p','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4020','¾P°â / µwÅé','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4320','¿Ô¸ß','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1200','À³¦¬±b´Ú','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1061','¤ä²¼¤áÀY','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2310','°Ó«~ªA°Èµ|','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+--
+-- exchange rate
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4450','Foreign Exchange Gain','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5810','Foreign Exchange Loss','A','','E','');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2310'),0.07);
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2311'),0.08);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '1520'), income_accno_id = (select id from chart where accno = '4020'), expense_accno_id = (select id from chart where accno = '5010'), fxgain_accno_id = (select id from chart where accno = '4450'), fxloss_accno_id = (select id from chart where accno = '5810'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'USD', weightunit = 'kg';
+--
diff --git a/sql-ledger/sql/US_General-chart.sql b/sql-ledger/sql/US_General-chart.sql
new file mode 100644 (file)
index 0000000..4506a71
--- /dev/null
@@ -0,0 +1,98 @@
+-- US_General COA
+-- modify as needed
+--
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1000','CURRENT ASSETS','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1060','Checking Account','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1065','Petty Cash','A','','A','AR_paid:AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1200','Accounts Receivables','A','','A','AR');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1205','Allowance for doubtful accounts','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1500','INVENTORY ASSETS','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1520','Inventory / Hardware','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1530','Inventory / Software','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1540','Inventory / Aftermarket Parts','A','','A','IC');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1800','CAPITAL ASSETS','H','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1820','Office Furniture & Equipment','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1825','Accum. Amort. -Furn. & Equip.','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1840','Vehicle','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('1845','Accum. Amort. -Vehicle','A','','A','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2000','CURRENT LIABILITIES','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2100','Accounts Payable','A','','L','AP');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2600','LONG TERM LIABILITIES','H','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2620','Bank Loans','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2680','Loans from Shareholders','A','','L','AP_paid');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3300','SHARE CAPITAL','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3350','Common Shares','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3500','RETAINED EARNINGS','H','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3590','Retained Earnings - prior years','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('3600','Current Earnings','A','','Q','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4000','SALES REVENUE','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4020','Sales / Hardware','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4030','Sales / Software','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4040','Sales / Aftermarket Parts','A','','I','AR_amount:IC_sale');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4300','CONSULTING REVENUE','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4320','Consulting','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4330','Programming','A','','I','AR_amount:IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4400','OTHER REVENUE','H','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4430','Shipping & Handling','A','','I','IC_income');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4440','Interest','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('4450','Foreign Exchange Gain','A','','I','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5000','COST OF GOODS SOLD','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5010','Purchases','A','','E','AP_amount:IC_cogs:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5020','COGS / Hardware','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5030','COGS / Software','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5040','COGS / Aftermarket Parts','A','','E','AP_amount:IC_cogs');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5100','Freight','A','','E','AP_amount:IC_expense');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5400','PAYROLL EXPENSES','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5410','Wages & Salaries','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5600','GENERAL & ADMINISTRATIVE EXPENSES','H','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5610','Accounting & Legal','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5615','Advertising & Promotions','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5620','Bad Debts','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5660','Amortization Expense','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5685','Insurance','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5690','Interest & Bank Charges','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5700','Office Supplies','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5760','Rent','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5765','Repair & Maintenance','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5780','Telephone','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5785','Travel & Entertainment','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5790','Utilities','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5795','Registrations','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5800','Licenses','A','','E','AP_amount');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5810','Foreign Exchange Loss','A','','E','');
+--
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2110','Accrued Income Tax - Federal','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2120','Accrued Income Tax - State','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2130','Accrued Franchise Tax','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2140','Accrued Real & Personal Prop Tax','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2150','Sales Tax','A','','L','AR_tax:AP_tax:IC_taxpart:IC_taxservice:CT_tax');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2160','Accrued Use Tax Payable','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2210','Accrued Wages','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2220','Accrued Comp Time','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2230','Accrued Holiday Pay','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2240','Accrued Vacation Pay','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2310','Accr. Benefits - 401K','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2320','Accr. Benefits - Stock Purchase','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2330','Accr. Benefits - Med, Den','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2340','Accr. Benefits - Payroll Taxes','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2350','Accr. Benefits - Credit Union','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2360','Accr. Benefits - Savings Bond','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2370','Accr. Benefits - Garnish','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('2380','Accr. Benefits - Charity Cont.','A','','L','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5420','Wages - Overtime','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5430','Benefits - Comp Time','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5440','Benefits - Payroll Taxes','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5450','Benefits - Workers Comp','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5460','Benefits - Pension','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5470','Benefits - General Benefits','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5510','Inc Tax Exp - Federal','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5520','Inc Tax Exp - State','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5530','Taxes - Real Estate','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5540','Taxes - Personal Property','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5550','Taxes - Franchise','A','','E','');
+insert into chart (accno,description,charttype,gifi_accno,category,link) values ('5560','Taxes - Foreign Withholding','A','','E','');
+--
+insert into tax (chart_id,rate) values ((select id from chart where accno = '2150'),0.05);
+--
+update defaults set inventory_accno_id = (select id from chart where accno = '1520'), income_accno_id = (select id from chart where accno = '4020'), expense_accno_id = (select id from chart where accno = '5020'), fxgain_accno_id = (select id from chart where accno = '4450'), fxloss_accno_id = (select id from chart where accno = '5810'), invnumber = '1000', sonumber = '1000', ponumber = '1000', curr = 'USD:CAD:EUR', weightunit = 'lbs';
+--
diff --git a/sql-ledger/templates/Brazilian_Portuguese-balance_sheet.html b/sql-ledger/templates/Brazilian_Portuguese-balance_sheet.html
new file mode 100644 (file)
index 0000000..20c3c51
--- /dev/null
@@ -0,0 +1,103 @@
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+  <p>BALAN&Ccedil;O<br>
+    <%period%>
+</h2>
+
+<table border=0>
+<tr>
+    <th align=left width=400 colspan=2>VALORES<br>
+      <hr align=left width=250 size=5 noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach asset_account%>
+<tr>
+  <td> </td>
+  <td><%asset_account%></td>
+  <td align=right><%asset_this_period%></td>
+  <td align=right><%asset_last_period%></td>
+</tr>
+<%end asset_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+    <th align=left colspan=2>TOTAL</th>
+  <td align=right><%total_assets_this_period%><hr noshade size=2></td>
+  <td align=right><%total_assets_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+    <th align=left colspan=4>BALAN&Ccedil;O<b> 
+      <hr align=left width=250 size=5 noshade></b></th>
+</tr>
+
+<%foreach liability_account%>
+<tr>
+  <td></td>
+  <td><%liability_account%></td>
+  <td align=right><%liability_this_period%></td>
+  <td align=right><%liability_last_period%></td>
+</tr>
+<%end liability_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+    <th align=left>Total</th>
+  <td align=right><%total_liabilities_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_liabilities_last_period%><br><hr noshade size=2></td>
+</tr>
+
+<tr>
+    <th align=left colspan=4>S&Oacute;CIOS (%)<br>
+      <hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach equity_account%>
+<tr>
+  <td></td>
+  <td><%equity_account%></td>
+  <td align=right><%equity_this_period%></td>
+  <td align=right><%equity_last_period%></td>
+</tr>
+<%end equity_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+    <th align=left>Total</th>
+  <td align=right><%total_equity_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_equity_last_period%><br><hr noshade size=2></td>
+</tr>
+
+<tr valign=top>
+    <th align=left colspan=2>TOTAIS</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+</table>
+
+
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-check.tex b/sql-ledger/templates/Brazilian_Portuguese-check.tex
new file mode 100644 (file)
index 0000000..ea62b00
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Número da Fatura} & \textbf{Data da Fatura}
+  & \textbf{Prazo} & \textbf{Aplicação} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-income_statement.html b/sql-ledger/templates/Brazilian_Portuguese-income_statement.html
new file mode 100644 (file)
index 0000000..3531122
--- /dev/null
@@ -0,0 +1,77 @@
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+  <p>DECLARA&Ccedil;&Atilde;O DE RENDIMENTOS<br>
+    <%period%>
+</h2>
+
+
+<table width=100% border=0>
+<tr>
+    <th width=400 align=left colspan=2>RENDIMENTOS<br>
+      <hr width=300 size=5 align=left noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach income_account%>
+<tr>
+  <td width=4> </td>
+  <td><%income_account%></td>
+  <td align=right><%income_this_period%></td>
+  <td align=right><%income_last_period%></td>
+</tr>
+<%end income_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+    <th align=left>Total</th>
+  <td align=right><%total_income_this_period%><hr noshade size=2></td>
+  <td align=right><%total_income_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+    <th align=left colspan=2>DESPESAS<br>
+      <hr width=300 size=5 align=left noshade></th>
+</tr>
+
+<%foreach expense_account%>
+<tr>
+  <td> </td>
+  <td><%expense_account%></td>
+  <td align=right><%expenses_this_period%></td>
+  <td align=right><%expenses_last_period%></td>
+</tr>
+<%end expense_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+    <th align=left>Total</th>
+  <td align=right><%total_expenses_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_expenses_last_period%><br><hr noshade size=2></td>
+</tr>
+
+<tr valign=top>
+    <th align=left colspan=2>RENDIMENTOS / (PREJUIZO)</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+
+</table>
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-invoice.html b/sql-ledger/templates/Brazilian_Portuguese-invoice.html
new file mode 100644 (file)
index 0000000..2871238
--- /dev/null
@@ -0,0 +1,315 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+            <h4> Telefone: 
+              <%tel%>
+              <br>
+              Fax: 
+              <%fax%>
+            </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+            <h4>FATURA</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+                <th align=right> Data</th>
+                <td width=10>&nbsp;</td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+                <th align=right>Entrega</th>
+                <td width=10>&nbsp;</td><td><%duedate%></td>
+    </tr>
+
+    <tr>
+                <th align=right>N&uacute;mero</th>
+                <td>&nbsp;</td><td><%invnumber%></td></tr>
+    </table></tr>
+  
+<!--
+    <tr>
+      <th align=right>Clerk:</th><td>&nbsp;</td><td><%employee%></td>
+    </tr>
+-->
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </table></td>
+    </table>
+  
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+        <th align=left><font color="ffffff">Para:</font></th>
+        <th align=left><font color="ffffff">Transportar Para:</font></th>
+    </tr>
+
+<!--
+     other variables which can be use:
+     contact, shiptocontact, shiptophone, shiptofax
+-->
+
+    <tr valign=top>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+      
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+        <th align=left><font color=ffffff>N&uacute;mero</font></th>
+        <th align=left><font color=ffffff>Descri&ccedil;&atilde;o</font></th>
+        <th><font color=ffffff>Quant.</font></th>
+      <th>&nbsp;</th>
+        <th><font color=ffffff>Pre&ccedil;o</font></th>
+        <th><font color=ffffff>Disc.</font></th>
+        <th><font color="ffffff">Total</font></th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+<!--
+you can also use netprice instead of sellprice if you
+don't want to show the discount
+netprice = sellprice - discount
+-->
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+    <tr>
+<%if taxincluded%>
+      <th colspan=5 align=right>Total</th>
+      <td colspan=2 align=right><%invtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+      <th colspan=5 align=right>Subtotal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+        <th colspan=5 align=right> 
+          <%taxdescription%>
+          em 
+          <%taxbase%>
+          @ 
+          <%taxrate%>
+          %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+<%if paid%>
+    <tr>
+        <th colspan=5 align=right>Pago</th>
+      <td colspan=2 align=right>- <%paid%></td>
+    </tr>
+<%end paid%>
+
+    <tr>
+      <td colspan=3>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+        <td colspan=3>Fatura para<b> 
+          <%terms%>
+          </b> dias</td>
+        <th colspan=2 align=right>Pendente</th>
+      <th colspan=2 align=right><%total%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+        <td>Obs.:</td>
+      <td><%notes%></td>
+<%end notes%>
+        <td align=right> Pre&ccedil;os em<b> 
+          <%currency%>
+          </b> <br>
+          <%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+
+<%if paid%>
+<tr>
+  <td colspan=7>
+    <table width=60%>
+      <tr>
+        <th align=left>Pagamentos</th>
+      </tr>
+      <tr>
+        <td colspan=4>
+         <hr noshade>
+       </td>
+      </tr>
+      <tr>
+        <th align=left>Data</th>
+           <th align=left>Conta</th>
+           <th align=left>Origem</th>
+           <th align=left>Total</th>
+      </tr>
+<%end paid%>
+
+<%foreach payment%>
+      <tr>
+        <td><%paymentdate%></td>
+       <td><%paymentaccount%></td>
+       <td><%paymentsource%></td>
+       <td><%payment%></td>
+      </tr>
+<%end payment%>
+
+<%if paid%>
+    </table>
+  </td>
+</tr>
+
+<tr>
+  <td>&nbsp;</td>
+</tr>
+<%end paid%>
+
+<tr>
+  <th colspan=7>
+  <br>
+    Obrigado por estarmos fazendo neg&oacute;cio! </th>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+        <td><font size=-3> </font> </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+<%foreach tax%>
+  <tr>
+    
+  <th colspan=7 align=left><font size=-2> 
+    <%taxdescription%>
+    Registro 
+    <%taxnumber%>
+    </font></th>
+  </tr>
+<%end tax%>
+
+<%if taxincluded%>
+  <tr>
+    
+  <th colspan=7 align=left><font size="-2">Impostos Inclusos.</font></th>
+  </tr>
+<%end taxincluded%>
+
+<!-- business number
+  <tr>
+    <th colspan=7 align=left><font size=-2>Business Number: <%businessnumber%></font></th>
+  </tr>
+-->
+
+<!-- banking information
+  <tr>
+    <th colspan=7 align=left>Banking Information:
+    <br>Bank
+    <br>Transit No.
+    <br>Account No.
+    </td>
+  </tr>
+-->
+
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-invoice.tex b/sql-ledger/templates/Brazilian_Portuguese-invoice.tex
new file mode 100644 (file)
index 0000000..15c407b
--- /dev/null
@@ -0,0 +1,223 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefone & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Disc} & \textbf{Amount} \\
+  & carried forward from page <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{0.5cm}
+
+\parbox[t]{1cm}{\hfill}
+  \parbox[t]{10.5cm}{
+  \textbf{To}
+  \vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{0.3cm}
+
+%<%if contact%>
+%Attn: <%contact%>
+%\vspace{0.3cm}
+%<%end contact%>
+\vspace{0.5cm}
+
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\parbox[t]{7.5cm}{
+\textbf{Ship To}
+\vspace{0.5cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+
+\vspace{0.3cm}
+
+\vspace{0.3cm}
+
+<%if shiptocontact%>
+Attn: <%shiptocontact%>
+\vspace{0.3cm}
+<%end shiptocontact%>
+
+<%if shiptophone%>
+Tel: <%shiptophone%>
+<%end shiptophone%>
+
+<%if shiptofax%>
+Fax: <%shiptofax%>
+<%end shiptofax%>
+
+<%shiptoemail%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{F A T U R A}
+\hfill
+
+\vspace{1cm}
+
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Data} & <%invdate%> \\
+  \textbf{Número} & <%invnumber%> \\
+  \textbf{Pedido} & <%ordnumber%> \\
+  \textbf{Produto} & <%employee%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Número} & \textbf{Descrição} & \textbf{Quant.} &
+    \textbf{Unid.} & \textbf{Preço} & \textbf{Disc.} & \textbf{Total} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> em <%taxbase%> & <%tax%> \\
+<%end tax%>
+<%if paid%>
+  \textbf{Pago} & - <%paid%> \\
+<%end paid%>
+  \hline
+  \textbf{Pendente} & \textbf{<%total%>} \\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Preços em \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+
+<%if paid%>
+\begin{tabularx}{10cm}{@{}lXlr@{}}
+  \textbf{Pagamentos} & & & \\
+  \hline
+  \textbf{Data} & \textbf{Conta} & \textbf{Origem} & \textbf{Total} \\
+<%end paid%>
+<%foreach payment%>
+  <%paymentdate%> & <%paymentaccount%> & <%paymentsource%> & <%payment%> \\
+<%end payment%>
+<%if paid%>
+\end{tabularx}
+<%end paid%>
+
+\vspace{1cm}
+
+\centerline{\textbf{Obrigado por estarmos fazendo negócio!}}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\end{document}
+
+
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-packing_list.html b/sql-ledger/templates/Brazilian_Portuguese-packing_list.html
new file mode 100644 (file)
index 0000000..4cdee74
--- /dev/null
@@ -0,0 +1,143 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr>
+  <td width=10>
+  </td> 
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <th colspan=2>
+            <h4 align=center>LISTA DE PRODUTOS</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+                <th align=right>Data</th>
+                <td width=10> </td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+                <th align=right>N&uacute;mero</th>
+                <td></td><td><%invnumber%></td></tr>
+    </table></tr>
+  
+    <tr>
+      <td> 
+      </td>
+    </tr>
+    </table></td>
+    </table>
+  
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+        <th align=left><font color="ffffff">Para:</font></th>
+    </tr>
+
+    <tr>
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+<%if shiptocontact%>
+          <p>Obs.: 
+            <%shiptocontact%>
+            <%end shiptocontact%>
+        </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td> 
+    </td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+        <th align=left><font color=ffffff>N&uacute;mero</font></th>
+        <th align=left><font color=ffffff>Descri&ccedil;&atilde;o</font></th>
+        <th><font color="ffffff">Quant.</font></th>
+      <th>&nbsp;</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+        <td>Obs.:</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      <%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+        <td><font size=-3> </font> </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+
+
+
+
+
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-packing_list.tex b/sql-ledger/templates/Brazilian_Portuguese-packing_list.tex
new file mode 100644 (file)
index 0000000..4810230
--- /dev/null
@@ -0,0 +1,116 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telephone & <%tel%>\\
+    Facsimile & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Bin} \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+
+\vspace{3.5cm}
+
+\textbf{LISTA DE PRODUTOS} \parbox{0.3cm}{\hfill} \textbf{L I S T}
+
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Data} & <%invdate%> \\
+  \textbf{Número} & <%invnumber%> \\
+  \textbf{Cliente} & <%customer_id%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Número} & \textbf{Descrição} & \textbf{Quant.} &
+    \textbf{Unid.} & \textbf{Bin} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%bin%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+\centerline{\textbf{ }}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-purchase_order.html b/sql-ledger/templates/Brazilian_Portuguese-purchase_order.html
new file mode 100644 (file)
index 0000000..54b25f3
--- /dev/null
@@ -0,0 +1,187 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Tel: <%tel%>
+      <br>Fax: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4> O R D E M &nbsp;&nbsp; D E &nbsp;&nbsp; C O M P R A</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Data</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Requerido por</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>N&uacutemero</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Para:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>N&uacutemero</th>
+      <th align=left><font color=ffffff>Descri&ccedil&atildeo</th>
+      <th><font color=ffffff>Quant.</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Pre&ccedilo (unit.)</th>
+      <th><font color=ffffff>Total</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=6><hr noshade></td>
+    </tr>
+    
+    <tr>
+      <th colspan=4 align=right>Subtotal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=4 align=right><%taxdescription%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=2>Faturado em <b><%terms%></b> dias</td>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%ordtotal%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Obs.:</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      Todos os pre&ccedilos em <b><%currency%></b>
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-purchase_order.tex b/sql-ledger/templates/Brazilian_Portuguese-purchase_order.tex
new file mode 100644 (file)
index 0000000..61bb518
--- /dev/null
@@ -0,0 +1,198 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefone & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Amount} \\
+  & carried forward from <%lastpage%> & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{0.5cm}
+
+\parbox[t]{1cm}{\hfill}
+\parbox[t]{10.5cm}{
+\textbf{To}
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{0.3cm}
+
+<%if contact%>
+Attn: <%contact%>
+\vspace{0.3cm}
+<%end contact%>
+
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\parbox[t]{7.5cm}{
+\textbf{Ship To}
+\vspace{0.3cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+
+\vspace{0.3cm}
+
+<%if shiptocontact%>
+Attn: <%shiptocontact%>
+\vspace{0.3cm}
+<%end shiptocontact%>
+
+<%if shiptophone%>
+Tel: <%shiptophone%>
+<%end shiptophone%>
+
+<%if shiptofax%>
+Fax: <%shiptofax%>
+<%end shiptofax%>
+
+<%shiptoemail%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{ORDEM DE COMPRA} \parbox{0.3cm}{\hfill} \textbf{O R D E R}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Data} & <%orddate%> \\
+<%if reqdate%>
+  \textbf{Requerido por} & <%reqdate%> \\
+<%end reqdate%>
+  \textbf{Número} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Número} & \textbf{Descrição} & \textbf{Quant.} &
+    \textbf{Unid.} & \textbf{Preço} & \textbf{Total} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> em <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Preços em \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+%\footnotetext[1]{\tiny }
+
+\end{document}
+
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-receipt.tex b/sql-ledger/templates/Brazilian_Portuguese-receipt.tex
new file mode 100644 (file)
index 0000000..ea62b00
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Número da Fatura} & \textbf{Data da Fatura}
+  & \textbf{Prazo} & \textbf{Aplicação} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-sales_order.html b/sql-ledger/templates/Brazilian_Portuguese-sales_order.html
new file mode 100644 (file)
index 0000000..480dc63
--- /dev/null
@@ -0,0 +1,221 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+            <h4> Telefone: 
+              <%tel%>
+              <br>
+              Fax: 
+              <%fax%>
+            </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+            <h4>ORDEM DE VENDA</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+                <th align=right>Data</th>
+                <td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+                <th align=right>Requerido por</th>
+                <td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+                <th align=right>N&uacute;mero</th>
+                <td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </table></tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </table></td>
+    </table>
+  
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+        <th align=left><font color="ffffff">Para:</font></th>
+        <th align=left><font color="ffffff">Transportar para:</font></th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+        <th align=left><font color=ffffff>N&uacute;mero</font></th>
+        <th align=left><font color=ffffff>Descri&ccedil;&atilde;o</font></th>
+        <th><font color=ffffff>Quant.</font></th>
+      <th>&nbsp;</th>
+        <th><font color=ffffff>Pre&ccedil;o</font></th>
+        <th><font color=ffffff>Disc.</font></th>
+        <th><font color="ffffff">Total</font></th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+    <tr>
+<%if taxincluded%>
+      <th colspan=5 align=right>Total</th>
+      <td colspan=2 align=right><%ordtotal%></td>
+<%end taxincluded%>
+
+<%if not taxincluded%>
+      <th colspan=5 align=right>Subtotal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+        <th colspan=5 align=right> 
+          <%taxdescription%>
+          em 
+          <%taxbase%>
+          @ 
+          <%taxrate%>
+          %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=5><hr noshade></td>
+    </tr>
+
+    <tr>
+        <td colspan=3>Faturar para<b> 
+          <%terms%>
+          </b> dias</td>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%ordtotal%></th>
+    </tr>
+<%if taxincluded%>
+    <tr>
+        <td colspan=3>Impostos inclusos do total</td>
+    </tr>
+<%end taxincluded%>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+        <td>Obs.:</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+        <td align=right> Pre&ccedil;os em<b> 
+          <%currency%>
+          </b><br>
+          <%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+        <td><font size=-3> </font> </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+
+
+
+
+
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-sales_order.tex b/sql-ledger/templates/Brazilian_Portuguese-sales_order.tex
new file mode 100644 (file)
index 0000000..4267143
--- /dev/null
@@ -0,0 +1,137 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefone & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Disc} & \textbf{Amount} \\
+  & carried forward from <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{ORDEM DE VENDA} \parbox{0.3cm}{\hfill} \textbf{O R D E R}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Data} & <%orddate%> \\
+  \textbf{Número} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Número} & \textbf{Descrição} & \textbf{Quant.} &
+    \textbf{Unid.} & \textbf{Preço} & \textbf{Disc.} & \textbf{Total} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> em <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Preços em \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-statement.html b/sql-ledger/templates/Brazilian_Portuguese-statement.html
new file mode 100644 (file)
index 0000000..963f658
--- /dev/null
@@ -0,0 +1,125 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+  <tr>
+    <td width=10>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr>
+         <td>
+           <h4>
+           <%company%>
+           <br><%address%>
+           </h4>
+         </td>
+         <th><img src=http://www.sql-ledger.org/images/sql-ledger.png border=0 width=64 height=58></th>
+         <td align=right>
+         <h4>
+         Tel: <%tel%>
+         <br>Fax: <%fax%>
+         </h4>
+         </td>
+       </tr>
+       <tr>
+         <th colspan=3>
+            <h4>RELAT&Oacute;RIO</h4>
+          </th>
+       </tr>
+       <tr>
+         <td colspan=3 align=right><%statementdate%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr valign=top>
+         <td><%name%>
+         <br><%addr1%>
+         <br><%addr2%>
+         <br><%addr3%>
+         <br><%addr4%>
+         <br>
+<%if customerphone%>
+         <br>Tel: <%customerphone%>
+<%end customerphone%>
+<%if customerfax%>
+         <br>Fax: <%customerfax%>
+<%end customerfax%>
+<%if email%>
+         <br><%email%>
+<%end email%>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+        <tr>
+             <th align=left>N&uacute;mero da Fatura</th>
+          <th width=15%>Data</th>
+             <th width=15%>Prazo</th>
+          <th width=10%>Atual</th>
+         <th width=10%>30</th>
+         <th width=10%>60</th>
+         <th width=10%>90+</th>
+       </tr>
+<%foreach invnumber%>
+       <tr>
+         <td><%invnumber%></td>
+         <td><%invdate%></td>
+         <td><%duedate%></td>
+         <td align=right><%c0%></td>
+         <td align=right><%c30%></td>
+         <td align=right><%c60%></td>
+         <td align=right><%c90%></td>
+       </tr>
+<%end invnumber%>
+        <tr>
+         <td colspan=7><hr size=1></td>
+       </tr>
+       <tr>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <th align=right><%c0total%></table></td>
+         <th align=right><%c30total%>
+         <th align=right><%c60total%>
+         <th align=right><%c90total%>
+       </tr>
+      </table>
+    
+  
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td align=right>
+      <table width=50%>
+        <tr>
+           <th>Total</th>
+          <th align=right><%total%></th>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td><hr noshade></td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    
+  <td>Porfavor pagar com<b> 
+    <%company%>
+    </b>. </td>
+  </tr>
+  <tr height=20></tr>
+
+
diff --git a/sql-ledger/templates/Brazilian_Portuguese-statement.tex b/sql-ledger/templates/Brazilian_Portuguese-statement.tex
new file mode 100644 (file)
index 0000000..fbc5b03
--- /dev/null
@@ -0,0 +1,137 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+
+      <%address%>}\hfill
+    \begin{tabular}[b]{rrr@{}}
+    Tel & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%statementdate%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%statementdate%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+  carried forward from <%lastpage%> & & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{1.5cm}
+
+\parbox[t]{1cm}{\hfill}
+\parbox[t]{10.5cm}{
+  
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+}
+\parbox[t]{7.5cm}{
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{RELATÓRIO} \hfill
+
+\hfill <%statementdate%>
+
+\vspace{2cm}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Número da Fatura \#} & \textbf{Data} & \textbf{Prazo} &
+  \textbf{Atual} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+<%foreach invnumber%>
+  <%invnumber%> & <%invdate%> & <%duedate%> &
+  <%c0%> & <%c30%> & <%c60%> & <%c90%> \\
+<%end invnumber%>
+\textbf{Subtotal} & & & <%c0total%> & <%c30total%> & <%c60total%> & <%c90total%>
+\end{tabular*}
+\rule{\textwidth}{1pt}
+
+\vspace{1cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Totais} & <%total%>
+\end{tabularx}
+
+\vfill
+
+Favor pagar com <%company%>
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Danish-balance_sheet.html b/sql-ledger/templates/Danish-balance_sheet.html
new file mode 100644 (file)
index 0000000..61929ed
--- /dev/null
@@ -0,0 +1,96 @@
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>STATUS
+<br><%period%>
+</h2>
+
+<table border=0>
+<tr>
+  <th align=left width=400 colspan=2>AKTIVER<br><hr align=left width=250 size=5 noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach asset_account%>
+<tr>
+  <td> </td>
+  <td><%asset_account%></td>
+  <td align=right><%asset_this_period%></td>
+  <td align=right><%asset_last_period%></td>
+</tr>
+<%end asset_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>SAMLEDE AKTIVER</th>
+  <td align=right><%total_assets_this_period%><hr noshade size=2></td>
+  <td align=right><%total_assets_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>PASSIVER<b><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach liability_account%>
+<tr>
+  <td></td>
+  <td><%liability_account%></td>
+  <td align=right><%liability_this_period%></td>
+  <td align=right><%liability_last_period%></td>
+</tr>
+<%end liability_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Samlet gæld</th>
+  <td align=right><%total_liabilities_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_liabilities_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>KAPITAL<br><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach equity_account%>
+<tr>
+  <td></td>
+  <td><%equity_account%></td>
+  <td align=right><%equity_this_period%></td>
+  <td align=right><%equity_last_period%></td>
+</tr>
+<%end equity_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Samlet egenkapital</th>
+  <td align=right><%total_equity_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_equity_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>SAMLET GÆLD OG EGENKAPITAL</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+</table>
diff --git a/sql-ledger/templates/Danish-check.tex b/sql-ledger/templates/Danish-check.tex
new file mode 100644 (file)
index 0000000..5b64e81
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Danish-income_statement.html b/sql-ledger/templates/Danish-income_statement.html
new file mode 100644 (file)
index 0000000..c065297
--- /dev/null
@@ -0,0 +1,73 @@
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>DRIFTSREGNSKAB
+<br><%period%>
+</h2>
+
+
+<table width=100% border=0>
+<tr>
+  <th width=400 align=left colspan=2>INDTÆGTER<br><hr width=300 size=5 align=left noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach income_account%>
+<tr>
+  <td width=4> </td>
+  <td><%income_account%></td>
+  <td align=right><%income_this_period%></td>
+  <td align=right><%income_last_period%></td>
+</tr>
+<%end income_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Samlede indtægter</th>
+  <td align=right><%total_income_this_period%><hr noshade size=2></td>
+  <td align=right><%total_income_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=2>UDGIFTER<br><hr width=300 size=5 align=left noshade></th>
+</tr>
+
+<%foreach expense_account%>
+<tr>
+  <td> </td>
+  <td><%expense_account%></td>
+  <td align=right><%expenses_this_period%></td>
+  <td align=right><%expenses_last_period%></td>
+</tr>
+<%end expense_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Samlede udgifter</th>
+  <td align=right><%total_expenses_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_expenses_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>RESULTAT</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+
+</table>
diff --git a/sql-ledger/templates/Danish-invoice.html b/sql-ledger/templates/Danish-invoice.html
new file mode 100644 (file)
index 0000000..d150a84
--- /dev/null
@@ -0,0 +1,273 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Tlf.: <%tel%>
+      <br>Fax: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>F A K T U R A</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Fakturadato</th><td width=10>&nbsp;</td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Betalingsdato</th><td width=10>&nbsp;</td><td><%duedate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Fakturanummer</th><td>&nbsp;</td><td><%invnumber%></td></tr>
+    </tr>
+  
+<!--
+    <tr>
+      <th align=right>Ekspederet af:</th><td>&nbsp;</td><td><%username%></td>
+    </tr>
+-->
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Faktureringsadresse:</th>
+     <%if shiptoname%>
+      <th align=left><font color=ffffff>Leveringsadresse:</th>
+     <%end shiptoname%>
+    </tr>
+
+<!--
+     other variables which can be use:
+     contact, shiptocontact, shiptophone, shiptofax
+-->
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+      
+     <%if shiptoname%>
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+     <%end shiptoname%>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Varenummer</th>
+      <th align=left><font color=ffffff>Beskrivelse</th>
+      <th><font color=ffffff>Antal</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Pris</th>
+      <th><font color=ffffff>Rabat</th>
+      <th><font color=ffffff>Beløb</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+<!--
+you can also use netprice instead of sellprice if you
+don't want to show the discount
+netprice = sellprice - discount
+-->
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+    <tr>
+<%if taxincluded%>
+      <th colspan=5 align=right>Total</th>
+      <td colspan=2 align=right><%invtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+      <th colspan=5 align=right>Subtotal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=5 align=right><%taxdescription%> på <%taxbase%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+<%if paid%>
+    <tr>
+      <th colspan=5 align=right>Allerede betalt</th>
+      <td colspan=2 align=right>- <%paid%></td>
+    </tr>
+<%end paid%>
+
+    <tr>
+      <td colspan=3>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=3>Betalingsfrist <b><%terms%></b> dage</td>
+      <th colspan=2 align=right>At betale</th>
+      <th colspan=2 align=right><%total%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Bemærkninger</td>
+      <td><%notes%></td>
+<%end notes%>
+      <td align=right>
+      Alle priser i <b><%currency%></b>.
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <th colspan=7>
+  <br>Tak for handelen!
+  </th>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Betalingsfrist <%terms%> dage fra fakturadato. Betaling herefter påregnes
+    1.5% per påbegyndt måned startende <%duedate%> og indtil det fulde beløb
+    er betalt. Returnerede varer modregnes 10% i ekspeditionsgebyr.
+    Et returnummer skal tildeles af <%company%> før varer returneres.
+    Returvarer skal forsendes forudbetalt og forsvarligt forsikret.
+    <%company%> kan ikke drages til ansvar for skade under transport.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+<%foreach tax%>
+  <tr>
+    <th colspan=7 align=left><font size=-2><%taxdescription%> noteret som <%taxnumber%></th>
+  </tr>
+<%end tax%>
+
+<%if taxincluded%>
+  <tr>
+    <th colspan=7 align=left><font size=-2>Alle beløb er inklusive moms.</th>
+  </tr>
+<%end taxincluded%>
+
+<!-- business number
+  <tr>
+    <th colspan=7 align=left><font size=-2>CVR-nummer: <%businessnumber%></font></th>
+  </tr>
+-->
+
+<!-- banking information
+  <tr>
+    <th colspan=7 align=left>Bank-oplysninger:
+    <br>Bank
+    <br>Banknummer
+    <br>Kontonummer
+    </td>
+  </tr>
+-->
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Danish-invoice.tex b/sql-ledger/templates/Danish-invoice.tex
new file mode 100644 (file)
index 0000000..6c3fa8b
--- /dev/null
@@ -0,0 +1,152 @@
+\documentclass[a4paper,twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage[danish]{babel}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Tlf. & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Nummer} & \textbf{Beskrivelse} & \textbf{Antal} &
+    \textbf{Enhed} & \textbf{Pris} & \textbf{Rabat} & \textbf{Beløb} \\
+  & overført fra side <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{F A K T U R A}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Dato} & <%invdate%> \\
+  \textbf{Nummer} & <%invnumber%> \\
+  \textbf{Kunde} & <%customer_id%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Nummer} & \textbf{Beskrivelse} & \textbf{Antal} &
+    \textbf{Enhed} & \textbf{Pris} & \textbf{Rabat} & \textbf{Beløb} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> på <%taxbase%> & <%tax%> \\
+<%end tax%>
+<%if paid%>
+  \textbf{Betalt} & - <%paid%> \\
+<%end paid%>
+  \hline
+  \textbf{At betale} & \textbf{<%total%>} \\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Alle priser i \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+\centerline{\textbf{Tak for handelen!}}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Betalingsfrist <%terms%> dage fra fakturadato. Betaling herefter påregnes
+1.5\% per påbegyndt måned startende <%duedate%> og indtil det fulde beløb
+er betalt. Returnerede varer modregnes 10\% i ekspeditionsgebyr.
+Et returnummer skal tildeles af <%company%> før varer returneres.
+Returvarer skal forsendes forudbetalt og forsvarligt forsikret.
+<%company%> kan ikke drages til ansvar for skade under transport.}
+
+\end{document}
diff --git a/sql-ledger/templates/Danish-packing_list.html b/sql-ledger/templates/Danish-packing_list.html
new file mode 100644 (file)
index 0000000..76e02b4
--- /dev/null
@@ -0,0 +1,145 @@
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr>
+  <td width=10>
+  </td> 
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <th colspan=2>
+      <h4 align=center>F Ø L G E S E D D E L</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Dato</th><td width=10> </td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Nummer</th><td></td><td><%invnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td> 
+      </td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Leveringsadresse:</th>
+    </tr>
+
+    <tr>
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+<%if shiptocontact%>
+      <p>Att.: <%shiptocontact%>
+<%end shiptocontact%>
+
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td> 
+    </td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Varenummer</th>
+      <th align=left><font color=ffffff>Beskrivelse</th>
+      <th><font color=ffffff>Antal</th>
+      <th>&nbsp;</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Bemærkninger</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      <%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Returnerede varer modregnes 10% i ekspeditionsgebyr.
+    Et returnummer skal tildeles af <%company%> før varer returneres.
+    Returvarer skal forsendes forudbetalt og forsvarligt forsikret.
+    <%company%> kan ikke drages til ansvar for skade under transport.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
diff --git a/sql-ledger/templates/Danish-packing_list.tex b/sql-ledger/templates/Danish-packing_list.tex
new file mode 100644 (file)
index 0000000..0d6bfc4
--- /dev/null
@@ -0,0 +1,123 @@
+\documentclass[a4paper,twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage[danish]{babel}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Tlf. & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Nummer} & \textbf{Beskrivelse} & \textbf{Antal} &
+    \textbf{Enhed} & \textbf{Varelager} \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+
+\vspace{3.5cm}
+
+\textbf{F Ø L G E S E D D E L}
+
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Dato} & <%invdate%> \\
+  \textbf{Nummer} & <%invnumber%> \\
+  \textbf{Kunde} & <%customer_id%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Nummer} & \textbf{Beskrivelse} & \textbf{Antal} &
+    \textbf{Enhed} & \textbf{Varelager} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%bin%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+\centerline{\textbf{Tak for ordren!}}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Returnerede varer modregnes 10\% i ekspeditionsgebyr.
+Et returnummer skal tildeles af <%company%> før varer returneres.
+Returvarer skal forsendes forudbetalt og forsvarligt forsikret.
+<%company%> kan ikke drages til ansvar for skade under transport.}
+
+\end{document}
diff --git a/sql-ledger/templates/Danish-purchase_order.html b/sql-ledger/templates/Danish-purchase_order.html
new file mode 100644 (file)
index 0000000..f9f21cd
--- /dev/null
@@ -0,0 +1,191 @@
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Tlf.: <%tel%>
+      <br>Fax: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>I N D K Ø B S O R D R E</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Ordredato</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Ønsket leveringsdato</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Ordrenummer</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Til:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Varenummer</th>
+      <th align=left><font color=ffffff>Beskrivelse</th>
+      <th><font color=ffffff>Antal</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Pris</th>
+      <th><font color=ffffff>Beløb</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=6><hr noshade></td>
+    </tr>
+    
+    <tr>
+      <th colspan=4 align=right>Subtotal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=4 align=right><%taxdescription%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=2>Betalingsfrist <b><%terms%></b> dage</td>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%total%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Bemærkninger</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      Alle priser i <b><%currency%></b>
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Betalingsfrist <%terms%> dage fra fakturadato. Betaling herefter påregnes
+    1.5% per påbegyndt måned startende <%duedate%> og indtil det fulde beløb
+    er betalt. Returnerede varer modregnes 10% i ekspeditionsgebyr.
+    Et returnummer skal tildeles af <%company%> før varer returneres.
+    Returvarer skal forsendes forudbetalt og forsvarligt forsikret.
+    <%company%> kan ikke drages til ansvar for skade under transport.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
diff --git a/sql-ledger/templates/Danish-purchase_order.tex b/sql-ledger/templates/Danish-purchase_order.tex
new file mode 100644 (file)
index 0000000..bdd7416
--- /dev/null
@@ -0,0 +1,143 @@
+\documentclass[a4paper,twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage[danish]{babel}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Tlf. & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Nummer} & \textbf{Beskrivelse} & \textbf{Antal} &
+    \textbf{Enhed} & \textbf{Pris} & \textbf{Beløb} \\
+  & carried forward from <%lastpage%> & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{I N D K Ø B S O R D R E}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Dato} & <%orddate%> \\
+<%if reqdate%>
+  \textbf{Ønsket leveringsdato} & <%reqdate%> \\
+<%end reqdate%>
+  \textbf{Ordrenummer} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Varenummer} & \textbf{Beskrivelse} & \textbf{Antal} &
+    \textbf{Enhed} & \textbf{Pris} & \textbf{Beløb} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Alle priser i \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+%\footnotetext[1]{\tiny }
+
+\end{document}
diff --git a/sql-ledger/templates/Danish-receipt.tex b/sql-ledger/templates/Danish-receipt.tex
new file mode 100644 (file)
index 0000000..5b64e81
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Danish-sales_order.html b/sql-ledger/templates/Danish-sales_order.html
new file mode 100644 (file)
index 0000000..f256522
--- /dev/null
@@ -0,0 +1,210 @@
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Tlf.: <%tel%>
+      <br>Fax: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>S A L G S O R D R E</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Ordredato</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Ønsket leveringsdato</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Ordrenummer</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Til:</th>
+      <th align=left><font color=ffffff>Leveringsadresse:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Varenummer</th>
+      <th align=left><font color=ffffff>Beskrivelse</th>
+      <th><font color=ffffff>Antal</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Pris</th>
+      <th><font color=ffffff>Rabat</th>
+      <th><font color=ffffff>Beløb</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+    <tr>
+<%if taxincluded%>
+      <th colspan=5 align=right>Total</th>
+      <td colspan=2 align=right><%ordtotal%></td>
+<%end taxincluded%>
+
+<%if not taxincluded%>
+      <th colspan=5 align=right>Subtotal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=5 align=right><%taxdescription%> på <%taxbase%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=5><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=3>Betalingsfrist netto <b><%terms%></b> dage</td>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%ordtotal%></th>
+    </tr>
+<%if taxincluded%>
+    <tr>
+      <td colspan=3>Total er inklusive moms</td>
+    </tr>
+<%end taxincluded%>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Bemærkninger</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      Alle priser i <b><%currency%></b>
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Et gebyr for annullering af ordre på 10% vil blive tillagt alle specialtilbud
+    og produkter som er blevet tilpasset, forbedret eller opgraderet på kundens anmodning.<br>
+    Varer som ikke kan returneres er anført ovenfor.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
diff --git a/sql-ledger/templates/Danish-sales_order.tex b/sql-ledger/templates/Danish-sales_order.tex
new file mode 100644 (file)
index 0000000..d7307cd
--- /dev/null
@@ -0,0 +1,144 @@
+\documentclass[a4paper,twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage[danish]{babel}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Tlf. & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Nummer} & \textbf{Beskrivelse} & \textbf{Antal} &
+    \textbf{Enhed} & \textbf{Pris} & \textbf{Rabat} & \textbf{Beløb} \\
+  & Overført fra side <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{S A L G S O R D R E}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Dato} & <%orddate%> \\
+  \textbf{Ordrenummer} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Varenummer} & \textbf{Beskrivelse} & \textbf{Antal} &
+    \textbf{Enhed} & \textbf{Pris} & \textbf{Rabat} & \textbf{Beløb} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> på <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Alle priser i \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Et gebyr for annullering af ordre på 10\% vil blive tillagt alle specialtilbud
+og produkter som er blevet tilpasset, forbedret eller opgraderet på kundens anmodning.
+Varer som ikke kan returneres er anført ovenfor.
+}
+
+\end{document}
diff --git a/sql-ledger/templates/Danish-statement.html b/sql-ledger/templates/Danish-statement.html
new file mode 100644 (file)
index 0000000..6fca322
--- /dev/null
@@ -0,0 +1,121 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+  <tr>
+    <td width=10>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr>
+         <td>
+           <h4>
+           <%company%>
+           <br><%address%>
+           </h4>
+         </td>
+         <th><img src=http://www.sql-ledger.org/images/sql-ledger.png border=0 width=64 height=58></th>
+         <td align=right>
+         <h4>
+         Tel: <%tel%>
+         <br>Fax: <%fax%>
+         </h4>
+         </td>
+       </tr>
+       <tr>
+         <th colspan=3><h4>S T A T E M E N T</h4></th>
+       </tr>
+       <tr>
+         <td colspan=3 align=right><%statementdate%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr valign=top>
+         <td><%name%>
+         <br><%addr1%>
+         <br><%addr2%>
+         <br><%addr3%>
+         <br><%addr4%>
+         <br>
+<%if customerphone%>
+         <br>Tel: <%customerphone%>
+<%end customerphone%>
+<%if customerfax%>
+         <br>Fax: <%customerfax%>
+<%end customerfax%>
+<%if email%>
+         <br><%email%>
+<%end email%>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+        <tr>
+         <th align=left>Invoice #</th>
+         <th width=15%>Date</th>
+         <th width=15%>Due</th>
+         <th width=10%>Current</th>
+         <th width=10%>30</th>
+         <th width=10%>60</th>
+         <th width=10%>90+</th>
+       </tr>
+<%foreach invnumber%>
+       <tr>
+         <td><%invnumber%></td>
+         <td><%invdate%></td>
+         <td><%duedate%></td>
+         <td align=right><%c0%></td>
+         <td align=right><%c30%></td>
+         <td align=right><%c60%></td>
+         <td align=right><%c90%></td>
+       </tr>
+<%end invnumber%>
+        <tr>
+         <td colspan=7><hr size=1></td>
+       </tr>
+       <tr>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <th align=right><%c0total%></td>
+         <th align=right><%c30total%></td>
+         <th align=right><%c60total%></td>
+         <th align=right><%c90total%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td align=right>
+      <table width=50%>
+        <tr>
+         <th>Total Outstanding</th>
+          <th align=right><%total%></th>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td><hr noshade></td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>Please make check payable to <b><%company%></b>.
+    </td>
+  </tr>
+  <tr height=20></tr>
+</table>
+
diff --git a/sql-ledger/templates/Danish-statement.tex b/sql-ledger/templates/Danish-statement.tex
new file mode 100644 (file)
index 0000000..0b63f75
--- /dev/null
@@ -0,0 +1,137 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+
+      <%address%>}\hfill
+    \begin{tabular}[b]{rrr@{}}
+    Tel & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%statementdate%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%statementdate%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+  carried forward from <%lastpage%> & & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{1.5cm}
+
+\parbox[t]{1cm}{\hfill}
+\parbox[t]{10.5cm}{
+  
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+}
+\parbox[t]{7.5cm}{
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{S T A T E M E N T} \hfill
+
+\hfill <%statementdate%>
+
+\vspace{2cm}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+<%foreach invnumber%>
+  <%invnumber%> & <%invdate%> & <%duedate%> &
+  <%c0%> & <%c30%> & <%c60%> & <%c90%> \\
+<%end invnumber%>
+\textbf{Subtotal} & & & <%c0total%> & <%c30total%> & <%c60total%> & <%c90total%>
+\end{tabular*}
+\rule{\textwidth}{1pt}
+
+\vspace{1cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Total outstanding} & <%total%>
+\end{tabularx}
+
+\vfill
+
+Please make check payable to <%company%>
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Default-balance_sheet.html b/sql-ledger/templates/Default-balance_sheet.html
new file mode 100644 (file)
index 0000000..478caab
--- /dev/null
@@ -0,0 +1,100 @@
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>BALANCE SHEET
+<br><%period%>
+</h2>
+
+<table border=0>
+<tr>
+  <th align=left width=400 colspan=2>ASSETS<br><hr align=left width=250 size=5 noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach asset_account%>
+<tr>
+  <td> </td>
+  <td><%asset_account%></td>
+  <td align=right><%asset_this_period%></td>
+  <td align=right><%asset_last_period%></td>
+</tr>
+<%end asset_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>TOTAL ASSETS</th>
+  <td align=right><%total_assets_this_period%><hr noshade size=2></td>
+  <td align=right><%total_assets_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>LIABILITIES<b><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach liability_account%>
+<tr>
+  <td></td>
+  <td><%liability_account%></td>
+  <td align=right><%liability_this_period%></td>
+  <td align=right><%liability_last_period%></td>
+</tr>
+<%end liability_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Total Liabilities</th>
+  <td align=right><%total_liabilities_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_liabilities_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>SHAREHOLDER'S EQUITY<br><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach equity_account%>
+<tr>
+  <td></td>
+  <td><%equity_account%></td>
+  <td align=right><%equity_this_period%></td>
+  <td align=right><%equity_last_period%></td>
+</tr>
+<%end equity_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Total Equity</th>
+  <td align=right><%total_equity_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_equity_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>TOTAL LIABILITIES & EQUITY</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+</table>
+
+
+
diff --git a/sql-ledger/templates/Default-check.tex b/sql-ledger/templates/Default-check.tex
new file mode 100644 (file)
index 0000000..a1ab201
--- /dev/null
@@ -0,0 +1,77 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{1.8cm}
+
+<%notes%>
+
+\vspace{0.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
+
+
diff --git a/sql-ledger/templates/Default-income_statement.html b/sql-ledger/templates/Default-income_statement.html
new file mode 100644 (file)
index 0000000..e9d6a40
--- /dev/null
@@ -0,0 +1,82 @@
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>INCOME STATEMENT
+<br><%period%>
+</h2>
+
+
+<table width=100% border=0>
+<tr>
+  <th width=400 align=left colspan=2>INCOME<br><hr width=300 size=5 align=left noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach income_account%>
+<tr>
+  <td width=4> </td>
+  <td><%income_account%></td>
+  <td align=right><%income_this_period%></td>
+  <td align=right><%income_last_period%></td>
+</tr>
+<%end income_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Total Income</th>
+  <td align=right><%total_income_this_period%><hr noshade size=2></td>
+  <td align=right><%total_income_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=2>EXPENSES<br><hr width=300 size=5 align=left noshade></th>
+</tr>
+
+<%foreach expense_account%>
+<tr>
+  <td> </td>
+  <td><%expense_account%></td>
+  <td align=right><%expenses_this_period%></td>
+  <td align=right><%expenses_last_period%></td>
+</tr>
+<%end expense_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Total Expenses</th>
+  <td align=right><%total_expenses_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_expenses_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>INCOME / (LOSS)</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+
+</table>
+
+
+
+
+
+
+
+
diff --git a/sql-ledger/templates/Default-invoice.html b/sql-ledger/templates/Default-invoice.html
new file mode 100644 (file)
index 0000000..0ba06cc
--- /dev/null
@@ -0,0 +1,309 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Telephone: <%tel%>
+      <br>Facsimile: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>I N V O I C E</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Invoice Date</th><td width=10>&nbsp;</td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Due Date</th><td width=10>&nbsp;</td><td><%duedate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Number</th><td>&nbsp;</td><td><%invnumber%></td></tr>
+    </tr>
+  
+<!--
+    <tr>
+      <th align=right>Clerk:</th><td>&nbsp;</td><td><%employee%></td>
+    </tr>
+-->
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>To:</th>
+      <th align=left><font color=ffffff>Ship To:</th>
+    </tr>
+
+<!--
+     other variables which can be use:
+     contact, shiptocontact, shiptophone, shiptofax
+-->
+
+    <tr valign=top>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+      
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Number</th>
+      <th align=left><font color=ffffff>Description</th>
+      <th><font color=ffffff>Qt'y</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Price</th>
+      <th><font color=ffffff>Disc</th>
+      <th><font color=ffffff>Amount</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+<!--
+you can also use netprice instead of sellprice if you
+don't want to show the discount
+netprice = sellprice - discount
+-->
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+    <tr>
+<%if taxincluded%>
+      <th colspan=5 align=right>Total</th>
+      <td colspan=2 align=right><%invtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+      <th colspan=5 align=right>Subtotal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=5 align=right><%taxdescription%> on <%taxbase%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+<%if paid%>
+    <tr>
+      <th colspan=5 align=right>Paid</th>
+      <td colspan=2 align=right>- <%paid%></td>
+    </tr>
+<%end paid%>
+
+    <tr>
+      <td colspan=3>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=3>Terms Net <b><%terms%></b> days</td>
+      <th colspan=2 align=right>Outstanding</th>
+      <th colspan=2 align=right><%total%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Notes</td>
+      <td><%notes%></td>
+<%end notes%>
+      <td align=right>
+      All prices in <b><%currency%></b> Funds
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+
+<%if paid%>
+<tr>
+  <td colspan=7>
+    <table width=60%>
+      <tr>
+        <th align=left>Payments</th>
+      </tr>
+      <tr>
+        <td colspan=4>
+         <hr noshade>
+       </td>
+      </tr>
+      <tr>
+        <th align=left>Date</th>
+       <th align=left>Account</th>
+       <th align=left>Source</th>
+       <th align=left>Amount</th>
+      </tr>
+<%end paid%>
+
+<%foreach payment%>
+      <tr>
+        <td><%paymentdate%></td>
+       <td><%paymentaccount%></td>
+       <td><%paymentsource%></td>
+       <td><%payment%></td>
+      </tr>
+<%end payment%>
+
+<%if paid%>
+    </table>
+  </td>
+</tr>
+
+<tr>
+  <td>&nbsp;</td>
+</tr>
+<%end paid%>
+
+<tr>
+  <th colspan=7>
+  <br>Thank you for your valued business!
+  </th>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Payment due NET <%terms%> Days from date of Invoice.
+    Interest on overdue amounts will acrue at the rate of 1.5% per month
+    from due date until paid in full. Items returned are subject to
+    a 10% restocking charge. A return authorization must be obtained
+    from <%company%> before goods are returned. Returns must be shipped
+    prepaid and properly insured. <%company%> will not be responsible
+    for damages during transit.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+<%foreach tax%>
+  <tr>
+    <th colspan=7 align=left><font size=-2><%taxdescription%> Registration <%taxnumber%></th>
+  </tr>
+<%end tax%>
+
+<%if taxincluded%>
+  <tr>
+    <th colspan=7 align=left><font size=-2>Taxes shown are included in price.</th>
+  </tr>
+<%end taxincluded%>
+
+<!-- business number
+  <tr>
+    <th colspan=7 align=left><font size=-2>Business Number: <%businessnumber%></font></th>
+  </tr>
+-->
+
+<!-- banking information
+  <tr>
+    <th colspan=7 align=left>Banking Information:
+    <br>Bank
+    <br>Transit No.
+    <br>Account No.
+    </td>
+  </tr>
+-->
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Default-invoice.tex b/sql-ledger/templates/Default-invoice.tex
new file mode 100644 (file)
index 0000000..58a340d
--- /dev/null
@@ -0,0 +1,231 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telephone & <%tel%>\\
+    Facsimile & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Disc} & \textbf{Amount} \\
+  & carried forward from page <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{0.5cm}
+
+\parbox[t]{1cm}{\hfill}
+  \parbox[t]{10.5cm}{
+  \textbf{To}
+  \vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{0.3cm}
+
+%<%if contact%>
+%Attn: <%contact%>
+%\vspace{0.3cm}
+%<%end contact%>
+\vspace{0.5cm}
+
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\parbox[t]{7.5cm}{
+\textbf{Ship To}
+\vspace{0.5cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+
+\vspace{0.3cm}
+
+\vspace{0.3cm}
+
+<%if shiptocontact%>
+Attn: <%shiptocontact%>
+\vspace{0.3cm}
+<%end shiptocontact%>
+
+<%if shiptophone%>
+Tel: <%shiptophone%>
+<%end shiptophone%>
+
+<%if shiptofax%>
+Fax: <%shiptofax%>
+<%end shiptofax%>
+
+<%shiptoemail%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{I N V O I C E}
+\hfill
+
+\vspace{1cm}
+
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date} & <%invdate%> \\
+  \textbf{Number} & <%invnumber%> \\
+  \textbf{Order} & <%ordnumber%> \\
+  \textbf{Clerk} & <%employee%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Disc} & \textbf{Amount} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%> \\
+<%end tax%>
+<%if paid%>
+  \textbf{Paid} & - <%paid%> \\
+<%end paid%>
+  \hline
+  \textbf{Balance Owing} & \textbf{<%total%>} \\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  All prices in \textbf{<%currency%>} funds.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+
+<%if paid%>
+\begin{tabularx}{10cm}{@{}lXlr@{}}
+  \textbf{Payments} & & & \\
+  \hline
+  \textbf{Date} & \textbf{Account} & \textbf{Source} & \textbf{Amount} \\
+<%end paid%>
+<%foreach payment%>
+  <%paymentdate%> & <%paymentaccount%> & <%paymentsource%> & <%payment%> \\
+<%end payment%>
+<%if paid%>
+\end{tabularx}
+<%end paid%>
+
+\vspace{1cm}
+
+\centerline{\textbf{Thank You for your valued business!}}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Payment due NET <%terms%> Days from date of Invoice. Interest on overdue
+amounts will acrue at the rate of 1.5\% per month starting <%duedate%>
+until paid in full. Items returned are subject to a 10\% restocking charge.
+A return authorization must be obtained from <%company%> before goods are
+returned. Returns must be shipped prepaid and properly insured.
+<%company%> will not be responsible for damages during transit.}
+
+\end{document}
+
+
+
diff --git a/sql-ledger/templates/Default-packing_list.html b/sql-ledger/templates/Default-packing_list.html
new file mode 100644 (file)
index 0000000..07ba8d6
--- /dev/null
@@ -0,0 +1,148 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr>
+  <td width=10>
+  </td> 
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <th colspan=2>
+      <h4 align=center>P A C K I N G &nbsp;&nbsp; L I S T</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Date</th><td width=10> </td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Number</th><td></td><td><%invnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td> 
+      </td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Ship To:</th>
+    </tr>
+
+    <tr>
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+<%if shiptocontact%>
+      <p>Attn: <%shiptocontact%>
+<%end shiptocontact%>
+
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td> 
+    </td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Number</th>
+      <th align=left><font color=ffffff>Description</th>
+      <th><font color=ffffff>Qt'y</th>
+      <th>&nbsp;</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Notes</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      <%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Items returned are subject to
+    a 10% restocking charge. A return authorization must be obtained
+    from <%company%> before goods are returned. Returns must be shipped
+    prepaid and properly insured. <%company%> will not be responsible
+    for damages during transit.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Default-packing_list.tex b/sql-ledger/templates/Default-packing_list.tex
new file mode 100644 (file)
index 0000000..fce1782
--- /dev/null
@@ -0,0 +1,122 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telephone & <%tel%>\\
+    Facsimile & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Bin} \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+
+\vspace{3.5cm}
+
+\textbf{P A C K I N G} \parbox{0.3cm}{\hfill} \textbf{L I S T}
+
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date} & <%invdate%> \\
+  \textbf{Number} & <%invnumber%> \\
+  \textbf{Customer} & <%customer_id%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Bin} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%bin%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+\centerline{\textbf{Thank You for your valued business!}}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Items returned are subject to a 10\% restocking charge.
+A return authorization must be obtained from <%company%> before goods are
+returned. Returns must be shipped prepaid and properly insured.
+<%company%> will not be responsible for damages during transit.}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Default-purchase_order.html b/sql-ledger/templates/Default-purchase_order.html
new file mode 100644 (file)
index 0000000..7df399e
--- /dev/null
@@ -0,0 +1,224 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Telephone: <%tel%>
+      <br>Facsimile: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>P U R C H A S E &nbsp;&nbsp; O R D E R</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Order Date</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Required by</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Number</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left width=50%><font color=ffffff>To:</th>
+      <th align=left width=50%><font color=ffffff>Ship To:</th>
+    </tr>
+
+    <tr valign=top>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+
+<br>
+<%if contact%>
+<br>Attn: <%contact%>
+<%end contact%>
+<%if vendorphone%>
+<br>Tel: <%vendorphone%>
+<%end vendorphone%>
+<%if vendorfax%>
+<br>Fax: <%vendorfax%>
+<%end vendorfax%>
+      </td>
+
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+
+<br>
+<%if shiptocontact%>
+<br>Attn: <%shiptocontact%>
+<%end shiptocontact%>
+<%if shiptophone%>
+<br>Tel: <%shiptophone%>
+<%end shiptophone%>
+<%if shiptofax%>
+<br>Fax: <%shiptofax%>
+<%end shiptofax%>
+
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Number</th>
+      <th align=left><font color=ffffff>Description</th>
+      <th><font color=ffffff>Qt'y</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Price</th>
+      <th><font color=ffffff>Amount</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=6><hr noshade></td>
+    </tr>
+    
+    <tr>
+      <th colspan=4 align=right>Subtotal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=4 align=right><%taxdescription%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=2>Terms Net <b><%terms%></b> days</td>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%ordtotal%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Notes</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      All prices in <b><%currency%></b> Funds
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Payment due NET <%terms%> Days from date of Invoice.
+    Interest on overdue amounts will acrue at the rate of 1.5% per month
+    from due date until paid in full. Items returned are subject to
+    a 10% restocking charge. A return authorization must be obtained
+    from <%company%> before goods are returned. Returns must be shipped
+    prepaid and properly insured. <%company%> will not be responsible
+    for damages during transit.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Default-purchase_order.tex b/sql-ledger/templates/Default-purchase_order.tex
new file mode 100644 (file)
index 0000000..4e1deb2
--- /dev/null
@@ -0,0 +1,198 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telephone & <%tel%>\\
+    Facsimile & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Amount} \\
+  & carried forward from <%lastpage%> & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{0.5cm}
+
+\parbox[t]{1cm}{\hfill}
+\parbox[t]{10.5cm}{
+\textbf{To}
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{0.3cm}
+
+<%if contact%>
+Attn: <%contact%>
+\vspace{0.3cm}
+<%end contact%>
+
+<%if vendorphone%>
+Tel: <%vendorphone%>
+<%end vendorphone%>
+
+<%if vendorfax%>
+Fax: <%vendorfax%>
+<%end vendorfax%>
+
+<%email%>
+}
+\parbox[t]{7.5cm}{
+\textbf{Ship To}
+\vspace{0.3cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+
+\vspace{0.3cm}
+
+<%if shiptocontact%>
+Attn: <%shiptocontact%>
+\vspace{0.3cm}
+<%end shiptocontact%>
+
+<%if shiptophone%>
+Tel: <%shiptophone%>
+<%end shiptophone%>
+
+<%if shiptofax%>
+Fax: <%shiptofax%>
+<%end shiptofax%>
+
+<%shiptoemail%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{P U R C H A S E} \parbox{0.3cm}{\hfill} \textbf{O R D E R}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date} & <%orddate%> \\
+<%if reqdate%>
+  \textbf{Required by} & <%reqdate%> \\
+<%end reqdate%>
+  \textbf{Number} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Amount} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  All prices in \textbf{<%currency%>} funds.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+%\footnotetext[1]{\tiny }
+
+\end{document}
+
+
diff --git a/sql-ledger/templates/Default-receipt.tex b/sql-ledger/templates/Default-receipt.tex
new file mode 100644 (file)
index 0000000..24427b3
--- /dev/null
@@ -0,0 +1,74 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{1.8cm}
+
+<%notes%>
+
+\vspace{0.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
diff --git a/sql-ledger/templates/Default-sales_order.html b/sql-ledger/templates/Default-sales_order.html
new file mode 100644 (file)
index 0000000..c09e13a
--- /dev/null
@@ -0,0 +1,212 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Telephone: <%tel%>
+      <br>Facsimile: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>S A L E S &nbsp;&nbsp; O R D E R</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Order Date</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Required by</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Number</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>To:</th>
+      <th align=left><font color=ffffff>Ship To:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Number</th>
+      <th align=left><font color=ffffff>Description</th>
+      <th><font color=ffffff>Qt'y</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Price</th>
+      <th><font color=ffffff>Disc</th>
+      <th><font color=ffffff>Amount</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+    <tr>
+<%if taxincluded%>
+      <th colspan=5 align=right>Total</th>
+      <td colspan=2 align=right><%ordtotal%></td>
+<%end taxincluded%>
+
+<%if not taxincluded%>
+      <th colspan=5 align=right>Subtotal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=5 align=right><%taxdescription%> on <%taxbase%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=5><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=3>Terms Net <b><%terms%></b> days</td>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%ordtotal%></th>
+    </tr>
+<%if taxincluded%>
+    <tr>
+      <td colspan=3>Tax is included in Total</td>
+    </tr>
+<%end taxincluded%>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Notes</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      All prices in <b><%currency%></b> Funds
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    A 10% order cancellation fee will be applied for any special order
+    products or products that have been customized, enhanced or
+    upgraded at customers request.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Default-sales_order.tex b/sql-ledger/templates/Default-sales_order.tex
new file mode 100644 (file)
index 0000000..d5ac40c
--- /dev/null
@@ -0,0 +1,143 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telephone & <%tel%>\\
+    Facsimile & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Disc} & \textbf{Amount} \\
+  & carried forward from <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{S A L E S} \parbox{0.3cm}{\hfill} \textbf{O R D E R}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date} & <%orddate%> \\
+  \textbf{Number} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Disc} & \textbf{Amount} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  All prices in \textbf{<%currency%>} funds.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+A 10\% order cancellation fee will be applied for any special order products or
+products that have been customized, enhanced or upgraded at customers request.
+Items which are non-returnable are indicated above.
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Default-statement.html b/sql-ledger/templates/Default-statement.html
new file mode 100644 (file)
index 0000000..6fca322
--- /dev/null
@@ -0,0 +1,121 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+  <tr>
+    <td width=10>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr>
+         <td>
+           <h4>
+           <%company%>
+           <br><%address%>
+           </h4>
+         </td>
+         <th><img src=http://www.sql-ledger.org/images/sql-ledger.png border=0 width=64 height=58></th>
+         <td align=right>
+         <h4>
+         Tel: <%tel%>
+         <br>Fax: <%fax%>
+         </h4>
+         </td>
+       </tr>
+       <tr>
+         <th colspan=3><h4>S T A T E M E N T</h4></th>
+       </tr>
+       <tr>
+         <td colspan=3 align=right><%statementdate%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr valign=top>
+         <td><%name%>
+         <br><%addr1%>
+         <br><%addr2%>
+         <br><%addr3%>
+         <br><%addr4%>
+         <br>
+<%if customerphone%>
+         <br>Tel: <%customerphone%>
+<%end customerphone%>
+<%if customerfax%>
+         <br>Fax: <%customerfax%>
+<%end customerfax%>
+<%if email%>
+         <br><%email%>
+<%end email%>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+        <tr>
+         <th align=left>Invoice #</th>
+         <th width=15%>Date</th>
+         <th width=15%>Due</th>
+         <th width=10%>Current</th>
+         <th width=10%>30</th>
+         <th width=10%>60</th>
+         <th width=10%>90+</th>
+       </tr>
+<%foreach invnumber%>
+       <tr>
+         <td><%invnumber%></td>
+         <td><%invdate%></td>
+         <td><%duedate%></td>
+         <td align=right><%c0%></td>
+         <td align=right><%c30%></td>
+         <td align=right><%c60%></td>
+         <td align=right><%c90%></td>
+       </tr>
+<%end invnumber%>
+        <tr>
+         <td colspan=7><hr size=1></td>
+       </tr>
+       <tr>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <th align=right><%c0total%></td>
+         <th align=right><%c30total%></td>
+         <th align=right><%c60total%></td>
+         <th align=right><%c90total%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td align=right>
+      <table width=50%>
+        <tr>
+         <th>Total Outstanding</th>
+          <th align=right><%total%></th>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td><hr noshade></td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>Please make check payable to <b><%company%></b>.
+    </td>
+  </tr>
+  <tr height=20></tr>
+</table>
+
diff --git a/sql-ledger/templates/Default-statement.tex b/sql-ledger/templates/Default-statement.tex
new file mode 100644 (file)
index 0000000..0b63f75
--- /dev/null
@@ -0,0 +1,137 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+
+      <%address%>}\hfill
+    \begin{tabular}[b]{rrr@{}}
+    Tel & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%statementdate%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%statementdate%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+  carried forward from <%lastpage%> & & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{1.5cm}
+
+\parbox[t]{1cm}{\hfill}
+\parbox[t]{10.5cm}{
+  
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+}
+\parbox[t]{7.5cm}{
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{S T A T E M E N T} \hfill
+
+\hfill <%statementdate%>
+
+\vspace{2cm}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+<%foreach invnumber%>
+  <%invnumber%> & <%invdate%> & <%duedate%> &
+  <%c0%> & <%c30%> & <%c60%> & <%c90%> \\
+<%end invnumber%>
+\textbf{Subtotal} & & & <%c0total%> & <%c30total%> & <%c60total%> & <%c90total%>
+\end{tabular*}
+\rule{\textwidth}{1pt}
+
+\vspace{1cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Total outstanding} & <%total%>
+\end{tabularx}
+
+\vfill
+
+Please make check payable to <%company%>
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Dutch-balance_sheet.html b/sql-ledger/templates/Dutch-balance_sheet.html
new file mode 100644 (file)
index 0000000..16ede70
--- /dev/null
@@ -0,0 +1,104 @@
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>BALANS
+<br><%period%>
+</h2>
+
+<table border=0>
+<tr>
+  <th align=left width=400 colspan=2>ACTIVA<br><hr align=left width=250 size=5 noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach asset_account%>
+<tr>
+  <td> </td>
+  <td><%asset_account%></td>
+  <td align=right><%asset_this_period%></td>
+  <td align=right><%asset_last_period%></td>
+</tr>
+<%end asset_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>Totaal Activa</th>
+  <td align=right><%total_assets_this_period%><hr noshade size=2></td>
+  <td align=right><%total_assets_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>PASSIVA<b><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach liability_account%>
+<tr>
+  <td></td>
+  <td><%liability_account%></td>
+  <td align=right><%liability_this_period%></td>
+  <td align=right><%liability_last_period%></td>
+</tr>
+<%end liability_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Totaal Passiva</th>
+  <td align=right><%total_liabilities_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_liabilities_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>ONVERDEELD RESULTAAT<br><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach equity_account%>
+<tr>
+  <td></td>
+  <td><%equity_account%></td>
+  <td align=right><%equity_this_period%></td>
+  <td align=right><%equity_last_period%></td>
+</tr>
+<%end equity_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Totaal Opbrengst</th>
+  <td align=right><%total_equity_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_equity_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>TOTAAL PASSIVA & RESULTAAT</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+</table>
+
+
+
+
+
+
+
diff --git a/sql-ledger/templates/Dutch-check.tex b/sql-ledger/templates/Dutch-check.tex
new file mode 100644 (file)
index 0000000..5b64e81
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Dutch-income_statement.html b/sql-ledger/templates/Dutch-income_statement.html
new file mode 100644 (file)
index 0000000..ce4fd24
--- /dev/null
@@ -0,0 +1,83 @@
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>INKOMSTEN OVERZICHT
+<br><%period%>
+</h2>
+
+
+<table width=100% border=0>
+<tr>
+  <th width=400 align=left colspan=2>INKOMSTEN<br><hr width=300 size=5 align=left noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach income_account%>
+<tr>
+  <td width=4> </td>
+  <td><%income_account%></td>
+  <td align=right><%income_this_period%></td>
+  <td align=right><%income_last_period%></td>
+</tr>
+<%end income_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Totaal Inkomsten</th>
+  <td align=right><%total_income_this_period%><hr noshade size=2></td>
+  <td align=right><%total_income_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=2>ONKOSTEN<br><hr width=300 size=5 align=left noshade></th>
+</tr>
+
+<%foreach expense_account%>
+<tr>
+  <td> </td>
+  <td><%expense_account%></td>
+  <td align=right><%expenses_this_period%></td>
+  <td align=right><%expenses_last_period%></td>
+</tr>
+<%end expense_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Totaal Onkosten</th>
+  <td align=right><%total_expenses_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_expenses_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>WINST / (VERLIES)</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+
+</table>
+
+
+
+
+
+
+
+
+
diff --git a/sql-ledger/templates/Dutch-invoice.html b/sql-ledger/templates/Dutch-invoice.html
new file mode 100644 (file)
index 0000000..9dc656c
--- /dev/null
@@ -0,0 +1,239 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Tel: <%tel%>
+      <br>Fax: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>F A C T U U R</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Factuurdatum</th><td width=10>&nbsp;</td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Vervaldatum</th><td width=10>&nbsp;</td><td><%duedate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Factuurnummer</th><td>&nbsp;</td><td><%invnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Factuuradres:</th>
+      <th align=left><font color=ffffff>Verzendadres:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+      
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>Regel</th>  -->
+      <th align=left><font color=ffffff>Artikelnummer</th>
+      <th align=left><font color=ffffff>Omschrijving</th>
+      <th><font color=ffffff>Aantal</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Prijs</th>
+      <th><font color=ffffff>Korting</th>
+      <th><font color=ffffff>Totaal</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+<!--
+you can also use netprice instead of sellprice if you
+don't want to show the discount
+netprice = sellprice - discount
+-->
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+    <tr>
+      <th colspan=5 align=right>Subtotaal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=5 align=right>BTW <%taxrate%>%</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+<%if paid%>
+    <tr>
+      <th colspan=5 align=right>Betaald</th>
+      <td colspan=2 align=right>- <%paid%></td>
+    </tr>
+<%end paid%>
+
+    <tr>
+      <td colspan=3>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=3>Betalen binnen <b><%terms%></b> dagen</td>
+      <th colspan=2 align=right>Openstaand</th>
+      <th colspan=2 align=right><%total%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Opmerkingen</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      Alle prijzen in <b><%currency%></b>
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <th colspan=7>
+  Gaarne u betaling overmaken op onderstaande giro- of bankrekening
+  <br>ten name van <%company%>
+  <br>onder vermelding van het factuurnummer.
+  </th>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Op al onze aanbiedingen/leveringen zijn, met uitsluiting van eventuele inkoop- of andere voorwaarden van de opdrachtgever,
+<br>de Algemene Voorwaarden van <%company%> van toepassing.
+<br>Deze Algemene Voorwaarden zijn gedeponeerd bij de Kamer van Koophandel te ........
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+    <tr>
+      <th colspan=7 align=left><font size=-2>BTW nummer:<%taxnumber%></th>
+    </tr>
+
+    <tr>
+      <th colspan=7 align=left><font size=-2>Kamer van Koophandel te ...... nummer:<%businessnumber%></th>
+    </tr>
+
+    <tr>
+      <th colspan=7 align=left><font size=-2>Girorekening:.........</th>
+    </tr>
+
+    <tr>
+      <th colspan=7 align=left><font size=-2>Bankrekening:..........</th>
+    </tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Dutch-invoice.tex b/sql-ledger/templates/Dutch-invoice.tex
new file mode 100644 (file)
index 0000000..c19d8e2
--- /dev/null
@@ -0,0 +1,138 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telephone & <%tel%>\\
+    Facsimile & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Disc} & \textbf{Amount} \\
+  & carried forward from page <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{F A K T U U R}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Datum} & <%invdate%> \\
+  \textbf{Faktuurnummer} & <%invnumber%> \\
+  \textbf{Klantnummer} & <%customer_id%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Artikelnr} & \textbf{Omschrijving} & \textbf{Aantal} &
+    \textbf{Eenheid} & \textbf{Prijs} & \textbf{Korting} & \textbf{Bedrag} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotaal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Totaal} & \textbf{<%total%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Alle prijzen in \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+\centerline{\textbf{Dank voor uw gewaardeerde klandizie!}}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Dutch-packing_list.html b/sql-ledger/templates/Dutch-packing_list.html
new file mode 100644 (file)
index 0000000..aea6ba7
--- /dev/null
@@ -0,0 +1,121 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr>
+  <td width=10>
+  </td> 
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <th colspan=2>
+      <h4 align=center>P A K B O N</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Factuurdatum</th><td width=10> </td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Factuurnummer</th><td></td><td><%invnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td> 
+      </td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Verzendadres:</th>
+    </tr>
+
+    <tr>
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td> 
+    </td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Artikelnummer</th>
+      <th align=left><font color=ffffff>Omschrijving</th>
+      <th><font color=ffffff>Aantal</th>
+      <th>&nbsp;</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Opmerkingen</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      <%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+
diff --git a/sql-ledger/templates/Dutch-packing_list.tex b/sql-ledger/templates/Dutch-packing_list.tex
new file mode 100644 (file)
index 0000000..84289bc
--- /dev/null
@@ -0,0 +1,114 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefoon & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Nummer} & \textbf{Omschrijving} & \textbf{Aantal} &
+    \textbf{Eenheid} & \textbf{Bin} \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+
+\vspace{3.5cm}
+
+\textbf{P A K B O N} \parbox{0.3cm}{\hfill} \textbf{L I S T}
+
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Datum} & <%invdate%> \\
+  \textbf{Faktuurnummer} & <%invnumber%> \\
+  \textbf{Klantnummer} & <%customer_id%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Nummer} & \textbf{Omschrijving} & \textbf{Aantal} &
+    \textbf{Eenheid} & \textbf{Bin} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%bin%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+\centerline{\textbf{Dank voor uw gewaardeerde klandizie!}}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Dutch-purchase_order.html b/sql-ledger/templates/Dutch-purchase_order.html
new file mode 100644 (file)
index 0000000..0cb58d7
--- /dev/null
@@ -0,0 +1,186 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Tel: <%tel%>
+      <br>Fax: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>I N K O O P&nbsp;&nbsp;B E S T E L L I N G</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Bestel Datum</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Lever datum</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Bestel nummer</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>To:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Nummer</th>
+      <th align=left><font color=ffffff>Omschrijving</th>
+      <th><font color=ffffff>Aantal</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Prijs</th>
+      <th><font color=ffffff>Bedrag</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=6><hr noshade></td>
+    </tr>
+    
+    <tr>
+      <th colspan=4 align=right>Subtotaal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=4 align=right><%taxdescription%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=2>Betalings termijn <b><%terms%></b> dagen</td>
+      <th colspan=2 align=right>Totaal</th>
+      <th colspan=2 align=right><%total%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Notes</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      Alle prijzen in <b><%currency%></b>'s
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td>&nbsp;
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Dutch-purchase_order.tex b/sql-ledger/templates/Dutch-purchase_order.tex
new file mode 100644 (file)
index 0000000..c6c68d1
--- /dev/null
@@ -0,0 +1,137 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefoon & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotaal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Bestel Nummer} & \textbf{Omschrijving} & \textbf{Aantal} &
+    \textbf{Eenheid} & \textbf{Prijs} & \textbf{Bedrag} \\
+  & carried forward from <%lastpage%> & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{I N K O O P B E S T E L L I N G} \parbox{0.3cm}{\hfill} \textbf{O R D E R}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Datum} & <%orddate%> \\
+<%if reqdate%>
+  \textbf{Gewenste Leverdatum} & <%reqdate%> \\
+<%end reqdate%>
+  \textbf{Bestel Nummer} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Nummer} & \textbf{Omschrijving} & \textbf{Aantal} &
+    \textbf{Eenheid} & \textbf{Prijs} & \textbf{Bedrag} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotaal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Alle prijzen in \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Dutch-receipt.tex b/sql-ledger/templates/Dutch-receipt.tex
new file mode 100644 (file)
index 0000000..5b64e81
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Dutch-sales_order.html b/sql-ledger/templates/Dutch-sales_order.html
new file mode 100644 (file)
index 0000000..42b20a9
--- /dev/null
@@ -0,0 +1,208 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Tel: <%tel%>
+      <br>Fax: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>V E R K O O P&nbsp;&nbsp;B E S T E L L I N G</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Bestel Datum</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Gewenste Leverdatum</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Bestel Nummer</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Aan:</th>
+      <th align=left><font color=ffffff>Verzenden aan:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Nummer</th>
+      <th align=left><font color=ffffff>Omschrijving</th>
+      <th><font color=ffffff>Aantal</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Prijs</th>
+      <th><font color=ffffff>Korting</th>
+      <th><font color=ffffff>Bedrag</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+    <tr>
+<%if taxincluded%>
+      <th colspan=5 align=right>Totaal</th>
+      <td colspan=2 align=right><%ordtotal%></td>
+<%end taxincluded%>
+
+<%if not taxincluded%>
+      <th colspan=5 align=right>Subtotaal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=5 align=right><%taxdescription%> over <%taxbase%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=5><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=3>Betalingstermijn <b><%terms%></b> dagen</td>
+      <th colspan=2 align=right>Totaal</th>
+      <th colspan=2 align=right><%ordtotal%></th>
+    </tr>
+<%if taxincluded%>
+    <tr>
+      <td colspan=3>Totaal bedrag is inclusief BTW.</td>
+    </tr>
+<%end taxincluded%>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Opmerkingen:</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      Alle prijzen in <b><%currency%></b>'s
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td>&nbsp;
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Dutch-sales_order.tex b/sql-ledger/templates/Dutch-sales_order.tex
new file mode 100644 (file)
index 0000000..79acb4d
--- /dev/null
@@ -0,0 +1,134 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefoon & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotaal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Nummer} & \textbf{Omschrijving} & \textbf{Aantal} &
+    \textbf{Eenheid} & \textbf{Prijs} & \textbf{Korting} & \textbf{Bedrag} \\
+  & Transport van <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{V E R K O O P} \parbox{0.3cm}{\hfill} \textbf{B E S T E L L I N G}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Datum} & <%orddate%> \\
+  \textbf{Bestel Nummer} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Nummer} & \textbf{Omschrijving} & \textbf{Aantal} &
+    \textbf{Eenheid} & \textbf{Prijs} & \textbf{Korting} & \textbf{Bedrag} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotaal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> over <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Totaal} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Alle prijzen in \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Dutch-statement.html b/sql-ledger/templates/Dutch-statement.html
new file mode 100644 (file)
index 0000000..599a2f5
--- /dev/null
@@ -0,0 +1,121 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+  <tr>
+    <td width=10>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr>
+         <td>
+           <h4>
+           <%company%>
+           <br><%address%>
+           </h4>
+         </td>
+         <th><img src=http://www.sql-ledger.org/images/sql-ledger.png border=0 width=64 height=58></th>
+         <td align=right>
+         <h4>
+         Tel: <%tel%>
+         <br>Fax: <%fax%>
+         </h4>
+         </td>
+       </tr>
+       <tr>
+         <th colspan=3><h4>O P E N S T A A N D E  &nbsp;&nbsp;F A C T U R E N</h4></th>
+       </tr>
+       <tr>
+         <td colspan=3 align=right><%statementdate%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr valign=top>
+         <td><%name%>
+         <br><%addr1%>
+         <br><%addr2%>
+         <br><%addr3%>
+         <br><%addr4%>
+         <br>
+<%if customerphone%>
+         <br>Tel: <%customerphone%>
+<%end customerphone%>
+<%if customerfax%>
+         <br>Fax: <%customerfax%>
+<%end customerfax%>
+<%if email%>
+         <br><%email%>
+<%end email%>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+        <tr>
+         <th align=left>Factuur #</th>
+         <th width=15%>Datum</th>
+         <th width=15%>Vervaldatum</th>
+         <th width=10%>Huidig</th>
+         <th width=10%>30</th>
+         <th width=10%>60</th>
+         <th width=10%>90+</th>
+       </tr>
+<%foreach invnumber%>
+       <tr>
+         <td><%invnumber%></td>
+         <td><%invdate%></td>
+         <td><%duedate%></td>
+         <td align=right><%c0%></td>
+         <td align=right><%c30%></td>
+         <td align=right><%c60%></td>
+         <td align=right><%c90%></td>
+       </tr>
+<%end invnumber%>
+        <tr>
+         <td colspan=7><hr size=1></td>
+       </tr>
+       <tr>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <th align=right><%c0total%></td>
+         <th align=right><%c30total%></td>
+         <th align=right><%c60total%></td>
+         <th align=right><%c90total%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td align=right>
+      <table width=50%>
+        <tr>
+         <th>Totaal Openstaand</th>
+          <th align=right><%total%></th>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td><hr noshade></td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>Maak de betalingen over aan<b><%company%></b>.
+    </td>
+  </tr>
+  <tr height=20></tr>
+</table>
+
diff --git a/sql-ledger/templates/Dutch-statement.tex b/sql-ledger/templates/Dutch-statement.tex
new file mode 100644 (file)
index 0000000..470bb1b
--- /dev/null
@@ -0,0 +1,137 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+
+      <%address%>}\hfill
+    \begin{tabular}[b]{rrr@{}}
+    Tel & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%statementdate%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%statementdate%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Factuur \#} & \textbf{Datum} & \textbf{Vervaldatum} &
+  \textbf{Huidig} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+  carried forward from <%lastpage%> & & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{1.5cm}
+
+\parbox[t]{1cm}{\hfill}
+\parbox[t]{10.5cm}{
+  
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+}
+\parbox[t]{7.5cm}{
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{O P E N S T A A N D E   F A C T U R E N} \hfill
+
+\hfill <%statementdate%>
+
+\vspace{2cm}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Factuur \#} & \textbf{Datum} & \textbf{Vervaldatum} &
+  \textbf{Huidig} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+<%foreach invnumber%>
+  <%invnumber%> & <%invdate%> & <%duedate%> &
+  <%c0%> & <%c30%> & <%c60%> & <%c90%> \\
+<%end invnumber%>
+\textbf{Subtotal} & & & <%c0total%> & <%c30total%> & <%c60total%> & <%c90total%>
+\end{tabular*}
+\rule{\textwidth}{1pt}
+
+\vspace{1cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Totaal openstaand} & <%total%>
+\end{tabularx}
+
+\vfill
+
+Maak U betalingen over aan <%company%>
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Estonian-balance_sheet.html b/sql-ledger/templates/Estonian-balance_sheet.html
new file mode 100644 (file)
index 0000000..dcfa40b
--- /dev/null
@@ -0,0 +1,103 @@
+<head>
+  <title>Bilanss</title>
+</head>
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>BILANSS
+<br><%period%>
+</h2>
+
+<table border=0>
+<tr>
+  <th align=left width=400 colspan=2>AKTIVA<br><hr align=left width=250 size=5 noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach asset_account%>
+<tr>
+  <td> </td>
+  <td><%asset_account%></td>
+  <td align=right><%asset_this_period%></td>
+  <td align=right><%asset_last_period%></td>
+</tr>
+<%end asset_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>AKTIVA KOKKU</th>
+  <td align=right><%total_assets_this_period%><hr noshade size=2></td>
+  <td align=right><%total_assets_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>PASSIVA<b><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach liability_account%>
+<tr>
+  <td></td>
+  <td><%liability_account%></td>
+  <td align=right><%liability_this_period%></td>
+  <td align=right><%liability_last_period%></td>
+</tr>
+<%end liability_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Passiva kokku</th>
+  <td align=right><%total_liabilities_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_liabilities_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>AKTSIAKAPITAL<br><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach equity_account%>
+<tr>
+  <td></td>
+  <td><%equity_account%></td>
+  <td align=right><%equity_this_period%></td>
+  <td align=right><%equity_last_period%></td>
+</tr>
+<%end equity_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Aktsiakapital kokku</th>
+  <td align=right><%total_equity_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_equity_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>KOKKU PASSIVA JA AKTSIAKAPITAL</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+</table>
+
+
+
diff --git a/sql-ledger/templates/Estonian-check.tex b/sql-ledger/templates/Estonian-check.tex
new file mode 100644 (file)
index 0000000..5b64e81
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Estonian-income_statement.html b/sql-ledger/templates/Estonian-income_statement.html
new file mode 100644 (file)
index 0000000..b0594ea
--- /dev/null
@@ -0,0 +1,84 @@
+<head>
+  <title>Kasumiaruanne</title>
+</head>
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>KASUMIARUANNE
+<br><%period%>
+</h2>
+
+
+<table width=100% border=0>
+<tr>
+  <th width=400 align=left colspan=2>TULUD<br><hr width=300 size=5 align=left noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach income_account%>
+<tr>
+  <td width=4> </td>
+  <td><%income_account%></td>
+  <td align=right><%income_this_period%></td>
+  <td align=right><%income_last_period%></td>
+</tr>
+<%end income_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Tulud kokku</th>
+  <td align=right><%total_income_this_period%><hr noshade size=2></td>
+  <td align=right><%total_income_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=2>KULUD<br><hr width=300 size=5 align=left noshade></th>
+</tr>
+
+<%foreach expense_account%>
+<tr>
+  <td> </td>
+  <td><%expense_account%></td>
+  <td align=right><%expenses_this_period%></td>
+  <td align=right><%expenses_last_period%></td>
+</tr>
+<%end expense_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Kulud kokku</th>
+  <td align=right><%total_expenses_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_expenses_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>KASUM / (KAHJUM)</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+
+</table>
+
+
+
+
+
+
+
diff --git a/sql-ledger/templates/Estonian-invoice.html b/sql-ledger/templates/Estonian-invoice.html
new file mode 100644 (file)
index 0000000..8660fb8
--- /dev/null
@@ -0,0 +1,215 @@
+<head>
+  <title>Arve</title>
+</head>
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr>
+  <td width=10>
+  </td> 
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <th colspan=2>
+      <h4 align=center>A R V E</h4>
+    </th>
+  </tr>
+
+  </table>
+
+<!-- other variables you can use include
+tel, fax, signature, username, businessnumber -->
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Kuupäev</th><td width=10> </td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Arve Nr.</th><td></td><td><%invnumber%></td></tr>
+    </tr>
+  
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Arve aadress:</th>
+      <th align=left><font color=ffffff>Tarneaadress:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+      
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Kood</th>
+      <th align=left><font color=ffffff>Selgitus</th>
+      <th colspan=2><font color=ffffff>Kogus</th>
+      <th><font color=ffffff>Hind</th>
+      <th><font color=ffffff>Alh%</th>
+      <th><font color=ffffff>Kogus</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+<!--
+you can also use netprice instead of sellprice if you
+don't want to show the discount
+netprice = sellprice - discount
+-->
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+    <tr>
+      <th colspan=5 align=right>Summa</th>
+      <td colspan=2 align=right><%subtotal%></td>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=5 align=right><%taxdescription%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+<%if paid%>
+    <tr>
+      <th colspan=5 align=right>Makstud</th>
+      <td colspan=2 align=right>- <%paid%></td>
+    </tr>
+<%end paid%>
+
+    <tr>
+      <td colspan=3> </td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=3>Maksetingimus <b><%terms%></b> päeva</td>
+      <th colspan=2 align=right>Lõppsumma</th>
+      <th colspan=2 align=right><%total%></th>
+    </tr>
+    
+    <tr>
+      <td> 
+      </td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Märkused</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      Kõik hinnad: <b><%currency%></b>
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td colspan=7 align=right>Summa sõnadega: <%sum_as_words_ee%> </td></tr>
+
+<tr><td> </td></tr>
+  
+<tr>
+  <th colspan=7>
+  Palun märkige pangatsheki saajaks <%company%>
+  <br>Täname meeldiva koostöö eest!
+  </th>
+</tr>
+
+
+<tr><td> </td></tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Maksetähtaeg <%terms%> päeva alates arve kuupäevast.
+    Intress tasumata summadelt on 1.5% kuus kuni arve täeliku tasumiseni.
+ Tagastatud toodetele kehtib 10% tagastamistasu. Enne toodete tagastamist on vajalik 
+<%company%> nõusolek. Tagastavad tooted peavad olema makstud ning kindlustatud,
+<%company%> ei vastuta transpordi käigus tekkinud kahjude eest.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+<%foreach tax%>
+<tr>
+  <th colspan=7 align=left><font size=-2><%taxdescription%> Registration <%taxnumber%></th>
+</tr>
+<%end tax%>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Estonian-invoice.tex b/sql-ledger/templates/Estonian-invoice.tex
new file mode 100644 (file)
index 0000000..bfa2f7a
--- /dev/null
@@ -0,0 +1,147 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefon & <%tel%>\\
+    Faks & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Vahesumma} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Kood} & \textbf{Kirjeldus} & \textbf{Kogus} &
+    \textbf{Ühik} & \textbf{Hind} & \textbf{Alh} & \textbf{Kokku} \\
+  & edasi kantud lehelt <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{A R V E}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Kuupäev} & <%invdate%> \\
+  \textbf{Number} & <%invnumber%> \\
+  \textbf{Klient} & <%customer_id%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Kood} & \textbf{Kirjeldus} & \textbf{Kogus} &
+    \textbf{Ühik} & \textbf{Hind} & \textbf{Alh} & \textbf{Kokku} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Vahesumma} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Summa} & \textbf{<%total%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Kõik hinnad \textbf{<%currency%>} funds.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+\centerline{\textbf{Täname meeldiva koostöö eest!}}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Maksetähtaeg <%terms%> päeva alates arve kuupäevast.
+    Intress tasumata summadelt on 1.5\% kuus kuni arve täeliku tasumiseni.
+ Tagastatud toodetele kehtib 10\% tagastamistasu. Enne toodete tagastamist on vajalik <%company%> nõusolek. Tagastavad tooted peavad olema makstud ning kindlustatud, <%company%> ei vastuta transpordi käigus tekkinud kahjude eest.}
+
+\end{document}
+
+
+
diff --git a/sql-ledger/templates/Estonian-packing_list.html b/sql-ledger/templates/Estonian-packing_list.html
new file mode 100644 (file)
index 0000000..0006307
--- /dev/null
@@ -0,0 +1,147 @@
+<head>
+  <title>Saateleht</title>
+</head>
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr>
+  <td width=10>
+  </td> 
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <th colspan=2>
+      <h4 align=center>S A A T E L E H T</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Kuupäev</th><td width=10> </td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Number</th><td></td><td><%invnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td> 
+      </td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Tarneaadress:</th>
+    </tr>
+
+    <tr>
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td> 
+    </td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Kood</th>
+      <th align=left><font color=ffffff>Selgitus</th>
+      <th><font color=ffffff>Kogus</th>
+      <th> </th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Märkused</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      <%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Tagastatud toodetele kehtib 10% tagastamistasu. Enne toodete tagastamist on vajalik 
+<%company%> nõusolek. Tagastavad tooted peavad olema makstud ning kindlustatud,
+    <%company%> ei vastuta transpordi käigus tekkinud kahjude eest.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+
+
+
+
+
+
diff --git a/sql-ledger/templates/Estonian-packing_list.tex b/sql-ledger/templates/Estonian-packing_list.tex
new file mode 100644 (file)
index 0000000..06c763a
--- /dev/null
@@ -0,0 +1,119 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefon & <%tel%>\\
+    Faks & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Kood} & \textbf{Kirjeldus} & \textbf{Kogus} &
+    \textbf{Ühik} & \textbf{Bin} \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+
+\vspace{3.5cm}
+
+\textbf{S A A T E L E H T} \parbox{0.3cm}{\hfill}
+
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date} & <%invdate%> \\
+  \textbf{Number} & <%invnumber%> \\
+  \textbf{Customer} & <%customer_id%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Kood} & \textbf{Selgitus} & \textbf{Kogus} &
+    \textbf{Ühik} & \textbf{Bin} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%bin%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+\centerline{\textbf{Täname meeldiva koostöö eest!}}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+ Tagastatud toodetele kehtib 10\% tagastamistasu. Enne toodete tagastamist on vajalik <%company%> nõusolek. Tagastavad tooted peavad olema makstud ning kindlustatud, <%company%> ei vastuta transpordi käigus tekkinud kahjude eest.}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Estonian-purchase_order.html b/sql-ledger/templates/Estonian-purchase_order.html
new file mode 100644 (file)
index 0000000..7ee0073
--- /dev/null
@@ -0,0 +1,195 @@
+<head>\r
+  <title>Ostutellimus</title>\r
+</head>\r
+\r
+<body bgcolor=ffffff>\r
+\r
+<table width=100%>\r
+<tr valign=bottom>\r
+  <td width=10>&nbsp;</td>\r
+  <td>\r
+  \r
+  <table width=100%>\r
+  <tr>\r
+    <td>\r
+      <h4>\r
+      <%company%>\r
+      <br><%address%>\r
+      </h4>\r
+    </td>\r
+\r
+    <td align=right>\r
+      <h4>\r
+      Tel: <%tel%>\r
+      <br>Fax: <%fax%>\r
+      </h4>\r
+    </td>\r
+  </tr>\r
+\r
+  <tr>\r
+    <th colspan=3>\r
+      <h4>O S T U T E L L I M U S</h4>\r
+    </th>\r
+  </tr>\r
+\r
+  </table>\r
+\r
+\r
+  <table width=100% callspacing=0 cellpadding=0>\r
+    \r
+  <tr>\r
+    <td align=right>\r
+    <table>\r
+    <tr>\r
+      <th align=right>Tellimuse Kpv</th><td width=10>&nbsp;</td><td><%orddate%></td>\r
+    </tr>\r
+  \r
+    <tr>\r
+      <th align=right>Required by</th><td width=10>&nbsp;</td><td><%reqdate%></td>\r
+    </tr>\r
+\r
+    <tr>\r
+      <th align=right>Number</th><td>&nbsp;</td><td><%ordnumber%></td></tr>\r
+    </tr>\r
+  \r
+    <tr>\r
+      <td>&nbsp;</td>\r
+    </tr>\r
+    </td>\r
+    </table>\r
+  </tr>\r
+\r
+  <tr>\r
+    <td>\r
+    <table width=100%>\r
+    <tr bgcolor=000000>\r
+      <th align=left><font color=ffffff>To:</th>\r
+    </tr>\r
+\r
+    <tr>\r
+      <td><%name%>\r
+      <br><%addr1%>\r
+      <br><%addr2%>\r
+      <br><%addr3%>\r
+      <br><%addr4%>\r
+      </td>\r
+    </tr>\r
+    </table>\r
+    </td>\r
+  </tr>\r
+\r
+  <tr>\r
+    <td>&nbsp;</td>\r
+  </tr>\r
+  \r
+  <tr>\r
+    <td>\r
+    <table width=100%>\r
+    <tr bgcolor=000000>\r
+<!--      <th align=right><font color=ffffff>No.</th>  -->\r
+      <th align=left><font color=ffffff>Number</th>\r
+      <th align=left><font color=ffffff>Description</th>\r
+      <th><font color=ffffff>Qt'y</th>\r
+      <th>&nbsp;</th>\r
+      <th><font color=ffffff>Price</th>\r
+      <th><font color=ffffff>Amount</th>\r
+    </tr>\r
+\r
+<%foreach number%>\r
+    <tr valign=top>\r
+<!--      <td align=right><%runningnumber%>.</td>\r
+adjust the colspan if you include this to shift subtotal one to the right\r
+-->\r
+      <td><%number%></td>\r
+      <td><%description%></td>\r
+      <td align=right><%qty%></td>\r
+      <td><%unit%></td>\r
+      <td align=right><%sellprice%></td>\r
+      <td align=right><%linetotal%></td>\r
+    </tr>\r
+<%end number%>\r
+\r
+    <tr>\r
+      <td colspan=6><hr noshade></td>\r
+    </tr>\r
+    \r
+    <tr>\r
+      <th colspan=4 align=right>Vahesumma</th>\r
+      <td colspan=2 align=right><%subtotal%></td>\r
+    </tr>\r
+\r
+<%foreach tax%>\r
+    <tr>\r
+      <th colspan=4 align=right><%taxdescription%> @ <%taxrate%> %</th>\r
+      <td colspan=2 align=right><%tax%></td>\r
+    </tr>\r
+<%end tax%>\r
+\r
+    <tr>\r
+      <td colspan=2>&nbsp;</td>\r
+      <td colspan=4><hr noshade></td>\r
+    </tr>\r
+\r
+    <tr>\r
+      <td colspan=2>Maksetähtaeg <b><%terms%></b> tööpäeva</td>\r
+      <th colspan=2 align=right>Kokku</th>\r
+      <th colspan=2 align=right><%total%></th>\r
+    </tr>\r
+\r
+    <tr>\r
+      <td>&nbsp;</td>\r
+    </tr>\r
+\r
+    </table>\r
+    </td>\r
+  </tr>\r
+\r
+<tr>\r
+  <td>\r
+  <table width=100%>\r
+    <tr valign=top>\r
+<%if notes%>\r
+      <td>Märkused</td>\r
+      <td><pre><%notes%></pre></td>\r
+<%end notes%>\r
+      <td align=right>\r
+      Kõik hinnad: <b><%currency%></b>\r
+      <br><%shippingpoint%>\r
+      </td>\r
+    </tr>\r
+\r
+  </table>\r
+  </td>\r
+</tr>\r
+\r
+<tr><td>&nbsp;</td></tr>\r
+  \r
+<tr>\r
+  <td>\r
+  <table width=100%>\r
+  <tr valign=top>\r
+    <td><font size=-3>\r
+    Maksetähtaeg <%terms%> päeva alates arve kuupäevast.\r
+    Intress tasumata summadelt on 1.5% kuus kuni arve täeliku tasumiseni.\r
+ Tagastatud toodetele kehtib 10% tagastamistasu. Enne toodete tagastamist on vajalik\r
+<%company%> nõusolek. Tagastavad tooted peavad olema makstud ning kindlustatud,\r
+<%company%> ei vastuta transpordi käigus tekkinud kahjude eest.\r
+    </font>\r
+    </td>\r
+    <td width=150>\r
+    X <hr noshade>\r
+    </td>\r
+  </tr>\r
+  </table>\r
+  </td>\r
+</tr>\r
+\r
+</table>\r
+\r
+</td>\r
+</tr>\r
+</table>\r
+\r
+</body>\r
+</html>\r
+\r
diff --git a/sql-ledger/templates/Estonian-purchase_order.tex b/sql-ledger/templates/Estonian-purchase_order.tex
new file mode 100644 (file)
index 0000000..ee1d778
--- /dev/null
@@ -0,0 +1,143 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefon & <%tel%>\\
+    Faks & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Vahesumma} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Kood} & \textbf{Kirjeldus} & \textbf{Kogus} &
+    \textbf{Ühik} & \textbf{Hind} & \textbf{Kogus} \\
+  & üle kantud lehelt <%lastpage%> & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{O S T U T E L L I M U S} \parbox{0.3cm}{\hfill}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date} & <%orddate%> \\
+<%if reqdate%>
+  \textbf{Required by} & <%reqdate%> \\
+<%end reqdate%>
+  \textbf{Number} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Kood} & \textbf{Kirjeldus} & \textbf{Kogus} &
+    \textbf{Ühik} & \textbf{Hind} & \textbf{Kokku} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Vahesumma} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Summa} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Kõik hinnad \textbf{<%currency%>} funds.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+%\footnotetext[1]{\tiny }
+
+\end{document}
+
+
diff --git a/sql-ledger/templates/Estonian-receipt.tex b/sql-ledger/templates/Estonian-receipt.tex
new file mode 100644 (file)
index 0000000..5b64e81
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Estonian-sales_order.html b/sql-ledger/templates/Estonian-sales_order.html
new file mode 100644 (file)
index 0000000..d608b73
--- /dev/null
@@ -0,0 +1,214 @@
+<head>\r
+  <title>Müügitellimus</title>\r
+</head>\r
+\r
+<body bgcolor=ffffff>\r
+\r
+<table width=100%>\r
+<tr valign=bottom>\r
+  <td width=10>&nbsp;</td>\r
+  <td>\r
+  \r
+  <table width=100%>\r
+  <tr>\r
+    <td>\r
+      <h4>\r
+      <%company%>\r
+      <br><%address%>\r
+      </h4>\r
+    </td>\r
+\r
+    <td align=right>\r
+      <h4>\r
+      Tel: <%tel%>\r
+      <br>Fax: <%fax%>\r
+      </h4>\r
+    </td>\r
+  </tr>\r
+\r
+  <tr>\r
+    <th colspan=3>\r
+      <h4>M Ü Ü G I T E L L I M U S</h4>\r
+    </th>\r
+  </tr>\r
+\r
+  </table>\r
+\r
+\r
+  <table width=100% callspacing=0 cellpadding=0>\r
+    \r
+  <tr>\r
+    <td align=right>\r
+    <table>\r
+    <tr>\r
+      <th align=right>Tellimuse kpv</th><td width=10>&nbsp;</td><td><%orddate%></td>\r
+    </tr>\r
+  \r
+    <tr>\r
+      <th align=right>Tarnekuupäev</th><td width=10>&nbsp;</td><td><%reqdate%></td>\r
+    </tr>\r
+\r
+    <tr>\r
+      <th align=right>Number</th><td>&nbsp;</td><td><%ordnumber%></td></tr>\r
+    </tr>\r
+  \r
+    <tr>\r
+      <td>&nbsp;</td>\r
+    </tr>\r
+    </td>\r
+    </table>\r
+  </tr>\r
+\r
+  <tr>\r
+    <td>\r
+    <table width=100%>\r
+    <tr bgcolor=000000>\r
+      <th align=left><font color=ffffff>Tellija aadress:</th>\r
+      <th align=left><font color=ffffff>Tarneaadress:</th>\r
+    </tr>\r
+\r
+    <tr>\r
+      <td><%name%>\r
+      <br><%addr1%>\r
+      <br><%addr2%>\r
+      <br><%addr3%>\r
+      <br><%addr4%>\r
+      </td>\r
+\r
+      <td><%shiptoname%>\r
+      <br><%shiptoaddr1%>\r
+      <br><%shiptoaddr2%>\r
+      <br><%shiptoaddr3%>\r
+      <br><%shiptoaddr4%>\r
+      </td>\r
+    </tr>\r
+    </table>\r
+    </td>\r
+  </tr>\r
+\r
+  <tr>\r
+    <td>&nbsp;</td>\r
+  </tr>\r
+  \r
+  <tr>\r
+    <td>\r
+    <table width=100%>\r
+    <tr bgcolor=000000>\r
+<!--      <th align=right><font color=ffffff>Nr.</th>  -->\r
+      <th align=left><font color=ffffff>Kood</th>\r
+      <th align=left><font color=ffffff>Selgitus</th>\r
+      <th><font color=ffffff>Kogus</th>\r
+      <th>&nbsp;</th>\r
+      <th><font color=ffffff>Hind</th>\r
+      <th><font color=ffffff>Allh%</th>\r
+      <th><font color=ffffff>Summa</th>\r
+    </tr>\r
+\r
+<%foreach number%>\r
+    <tr valign=top>\r
+<!--      <td align=right><%runningnumber%>.</td>\r
+adjust the colspan if you include this to shift subtotal one to the right\r
+-->\r
+      <td><%number%></td>\r
+      <td><%description%></td>\r
+      <td align=right><%qty%></td>\r
+      <td><%unit%></td>\r
+      <td align=right><%sellprice%></td>\r
+      <td align=right><%discount%></td>\r
+      <td align=right><%linetotal%></td>\r
+    </tr>\r
+<%end number%>\r
+\r
+    <tr>\r
+      <td colspan=7><hr noshade></td>\r
+    </tr>\r
+    \r
+    <tr>\r
+<%if taxincluded%>\r
+      <th colspan=5 align=right>Kokku</th>\r
+      <td colspan=2 align=right><%ordtotal%></td>\r
+<%end taxincluded%>\r
+\r
+<%if not taxincluded%>\r
+      <th colspan=5 align=right>Vahesumma</th>\r
+      <td colspan=2 align=right><%subtotal%></td>\r
+<%end taxincluded%>\r
+    </tr>\r
+\r
+<%foreach tax%>\r
+    <tr>\r
+      <th colspan=5 align=right><%taxdescription%> <%taxbase%> @ <%taxrate%> %</th>\r
+      <td colspan=2 align=right><%tax%></td>\r
+    </tr>\r
+<%end tax%>\r
+\r
+    <tr>\r
+      <td colspan=2>&nbsp;</td>\r
+      <td colspan=5><hr noshade></td>\r
+    </tr>\r
+\r
+    <tr>\r
+      <td colspan=3>Maksetähtaeg <b><%terms%></b> päeva</td>\r
+      <th colspan=2 align=right>Kokku</th>\r
+      <th colspan=2 align=right><%ordtotal%></th>\r
+    </tr>\r
+<%if taxincluded%>\r
+    <tr>\r
+      <td colspan=3>Summa sisaldab käibemaksu</td>\r
+    </tr>\r
+<%end taxincluded%>\r
+\r
+    <tr>\r
+      <td>&nbsp;</td>\r
+    </tr>\r
+\r
+    </table>\r
+    </td>\r
+  </tr>\r
+\r
+<tr>\r
+  <td>\r
+  <table width=100%>\r
+    <tr valign=top>\r
+<%if notes%>\r
+      <td>Märkused</td>\r
+      <td><pre><%notes%></pre></td>\r
+<%end notes%>\r
+      <td align=right>\r
+      Kõik hinnad <b><%currency%></b>\r
+      <br><%shippingpoint%>\r
+      </td>\r
+    </tr>\r
+\r
+  </table>\r
+  </td>\r
+</tr>\r
+\r
+<tr><td>&nbsp;</td></tr>\r
+  \r
+<tr>\r
+  <td>\r
+  <table width=100%>\r
+  <tr valign=top>\r
+    <td><font size=-3>\r
+       Eritellimusel tehtud toodetel ning toodetel mida on kliendi soovil \r
+    kohandatud või täiendatud on tellimuse katkestamise tasu 10% tellimuse hinnast.\r
+    </font>\r
+    </td>\r
+    <td width=150>\r
+    X <hr noshade>\r
+    </td>\r
+  </tr>\r
+  </table>\r
+  </td>\r
+</tr>\r
+\r
+</table>\r
+\r
+</td>\r
+</tr>\r
+</table>\r
+\r
+</body>\r
+</html>\r
+\r
diff --git a/sql-ledger/templates/Estonian-sales_order.tex b/sql-ledger/templates/Estonian-sales_order.tex
new file mode 100644 (file)
index 0000000..beb32c5
--- /dev/null
@@ -0,0 +1,141 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefon & <%tel%>\\
+    Faks & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Vahesumma} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Kood} & \textbf{Kirjeldus} & \textbf{Kogus} &
+    \textbf{Ühik} & \textbf{Hind} & \textbf{Kirjeldus} & \textbf{Kokku} \\
+  & carried forward from <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{M Ü Ü G I T E L L I M U S} \parbox{0.3cm}{\hfill}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Kuupäev} & <%orddate%> \\
+  \textbf{Number} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Kood} & \textbf{Kirjeldus} & \textbf{Kogus} &
+    \textbf{Ühik} & \textbf{Hind} & \textbf{Alh} & \textbf{Kokku} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Vahesumma} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Summa} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Kõik hinnad \textbf{<%currency%>} funds.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+ Tagastatud toodetele kehtib 10\% tagastamistasu. Enne toodete tagastamist on vajalik <%company%> nõusolek. Tagastavad tooted peavad olema makstud ning kindlustatud, <%company%> ei vastuta transpordi käigus tekkinud kahjude eest.}
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Estonian-statement.html b/sql-ledger/templates/Estonian-statement.html
new file mode 100644 (file)
index 0000000..6fca322
--- /dev/null
@@ -0,0 +1,121 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+  <tr>
+    <td width=10>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr>
+         <td>
+           <h4>
+           <%company%>
+           <br><%address%>
+           </h4>
+         </td>
+         <th><img src=http://www.sql-ledger.org/images/sql-ledger.png border=0 width=64 height=58></th>
+         <td align=right>
+         <h4>
+         Tel: <%tel%>
+         <br>Fax: <%fax%>
+         </h4>
+         </td>
+       </tr>
+       <tr>
+         <th colspan=3><h4>S T A T E M E N T</h4></th>
+       </tr>
+       <tr>
+         <td colspan=3 align=right><%statementdate%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr valign=top>
+         <td><%name%>
+         <br><%addr1%>
+         <br><%addr2%>
+         <br><%addr3%>
+         <br><%addr4%>
+         <br>
+<%if customerphone%>
+         <br>Tel: <%customerphone%>
+<%end customerphone%>
+<%if customerfax%>
+         <br>Fax: <%customerfax%>
+<%end customerfax%>
+<%if email%>
+         <br><%email%>
+<%end email%>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+        <tr>
+         <th align=left>Invoice #</th>
+         <th width=15%>Date</th>
+         <th width=15%>Due</th>
+         <th width=10%>Current</th>
+         <th width=10%>30</th>
+         <th width=10%>60</th>
+         <th width=10%>90+</th>
+       </tr>
+<%foreach invnumber%>
+       <tr>
+         <td><%invnumber%></td>
+         <td><%invdate%></td>
+         <td><%duedate%></td>
+         <td align=right><%c0%></td>
+         <td align=right><%c30%></td>
+         <td align=right><%c60%></td>
+         <td align=right><%c90%></td>
+       </tr>
+<%end invnumber%>
+        <tr>
+         <td colspan=7><hr size=1></td>
+       </tr>
+       <tr>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <th align=right><%c0total%></td>
+         <th align=right><%c30total%></td>
+         <th align=right><%c60total%></td>
+         <th align=right><%c90total%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td align=right>
+      <table width=50%>
+        <tr>
+         <th>Total Outstanding</th>
+          <th align=right><%total%></th>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td><hr noshade></td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>Please make check payable to <b><%company%></b>.
+    </td>
+  </tr>
+  <tr height=20></tr>
+</table>
+
diff --git a/sql-ledger/templates/Estonian-statement.tex b/sql-ledger/templates/Estonian-statement.tex
new file mode 100644 (file)
index 0000000..0b63f75
--- /dev/null
@@ -0,0 +1,137 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+
+      <%address%>}\hfill
+    \begin{tabular}[b]{rrr@{}}
+    Tel & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%statementdate%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%statementdate%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+  carried forward from <%lastpage%> & & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{1.5cm}
+
+\parbox[t]{1cm}{\hfill}
+\parbox[t]{10.5cm}{
+  
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+}
+\parbox[t]{7.5cm}{
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{S T A T E M E N T} \hfill
+
+\hfill <%statementdate%>
+
+\vspace{2cm}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+<%foreach invnumber%>
+  <%invnumber%> & <%invdate%> & <%duedate%> &
+  <%c0%> & <%c30%> & <%c60%> & <%c90%> \\
+<%end invnumber%>
+\textbf{Subtotal} & & & <%c0total%> & <%c30total%> & <%c60total%> & <%c90total%>
+\end{tabular*}
+\rule{\textwidth}{1pt}
+
+\vspace{1cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Total outstanding} & <%total%>
+\end{tabularx}
+
+\vfill
+
+Please make check payable to <%company%>
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/French-balance_sheet.html b/sql-ledger/templates/French-balance_sheet.html
new file mode 100644 (file)
index 0000000..56748d6
--- /dev/null
@@ -0,0 +1,109 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional">
+
+<html>
+
+<head>
+
+<title>Bilan</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-15">
+
+</head>
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>BILAN DE VÉRIFICATION
+<br><%period%>
+</h2>
+
+<table border=0>
+<tr>
+  <th align=left width=400 colspan=2>ACTIF<br><hr align=left width=250 size=5 noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach asset_account%>
+<tr>
+  <td> </td>
+  <td><%asset_account%></td>
+  <td align=right><%asset_this_period%></td>
+  <td align=right><%asset_last_period%></td>
+</tr>
+<%end asset_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>Total Actif</th>
+  <td align=right><%total_assets_this_period%><hr noshade size=2></td>
+  <td align=right><%total_assets_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>PASSIF<b><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach liability_account%>
+<tr>
+  <td></td>
+  <td><%liability_account%></td>
+  <td align=right><%liability_this_period%></td>
+  <td align=right><%liability_last_period%></td>
+</tr>
+<%end liability_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Total Passif</th>
+  <td align=right><%total_liabilities_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_liabilities_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>BENEFICES NON DISTRIBUÉS<br><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach equity_account%>
+<tr>
+  <td></td>
+  <td><%equity_account%></td>
+  <td align=right><%equity_this_period%></td>
+  <td align=right><%equity_last_period%></td>
+</tr>
+<%end equity_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Total Capital</th>
+  <td align=right><%total_equity_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_equity_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>TOTAL PASSIF & CAPITAL</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+</table>
+</body>
+</html>
diff --git a/sql-ledger/templates/French-check.tex b/sql-ledger/templates/French-check.tex
new file mode 100644 (file)
index 0000000..5b64e81
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/French-income_statement.html b/sql-ledger/templates/French-income_statement.html
new file mode 100644 (file)
index 0000000..e76df09
--- /dev/null
@@ -0,0 +1,86 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional">
+
+<html>
+
+<head>
+
+<title>Compte de Résultat</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-15">
+
+</head>
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>Compte de Résultat
+<br><%period%>
+</h2>
+
+
+<table width=100% border=0>
+<tr>
+  <th width=400 align=left colspan=2>RECETTES<br><hr width=300 size=5 align=left noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach income_account%>
+<tr>
+  <td width=4> </td>
+  <td><%income_account%></td>
+  <td align=right><%income_this_period%></td>
+  <td align=right><%income_last_period%></td>
+</tr>
+<%end income_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Total Recettes</th>
+  <td align=right><%total_income_this_period%><hr noshade size=2></td>
+  <td align=right><%total_income_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=2>DÉPENSES<br><hr width=300 size=5 align=left noshade></th>
+</tr>
+
+<%foreach expense_account%>
+<tr>
+  <td> </td>
+  <td><%expense_account%></td>
+  <td align=right><%expenses_this_period%></td>
+  <td align=right><%expenses_last_period%></td>
+</tr>
+<%end expense_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Total Dépenses</th>
+  <td align=right><%total_expenses_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_expenses_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>BENEFICES / PERTES (en <%currency%> )</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+
+</table>
+</body>
+</html>
diff --git a/sql-ledger/templates/French-invoice.html b/sql-ledger/templates/French-invoice.html
new file mode 100644 (file)
index 0000000..901a317
--- /dev/null
@@ -0,0 +1,309 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional">
+
+<html>
+
+<head>
+
+<title>A2A <%invnumber%> <%name%></title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-15">
+
+</head>
+
+<body bgcolor="ffffff">
+
+<table width="100%">
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width="100%">
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Tél&nbsp;: <%tel%>
+      <br>Fax&nbsp;: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>F A C T U R E</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width="100%" cellspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Date de facture</th><td width=10>&nbsp;</td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Date d'échéance</th><td width=10>&nbsp;</td><td><%duedate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>N° de facture</th><td>&nbsp;</td><td><%invnumber%></td></tr>
+    </tr>
+  
+<!--
+    <tr>
+      <th align=right>Correspondant</th><td>&amp;nbsp;</td><td><%employee%></td>
+    </tr>
+-->
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width="100%">
+    <tr bgcolor="000000">
+      <th align=left><font color=ffffff>Adresse de facturation</font></th>
+      <th align=left><font color=ffffff>Adresse d'envoi</font></th>
+    </tr>
+
+<!--
+     d'autres variables pouvant être utilisées ici :
+     contact, shiptocontact, shiptophone, shiptofax
+-->
+
+    <tr valign=top>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+      
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width="100%">
+    <tr bgcolor="000000">
+<!--      <th align=right><font color="ffffff">N°</font></th>  -->
+      <th align=left><font color="ffffff">N°</font></th>
+      <th align=left><font color="ffffff">Description</font></th>
+      <th><font color="ffffff">Qté</font></th>
+      <th>&nbsp;</th>
+      <th><font color="ffffff">Prix</font></th>
+      <th><font color="ffffff">Remise</font></th>
+      <th><font color="ffffff">Montant</font></th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+veuillez adapter le colspan si vous comptez inclure ce poste.
+ceci permettra de décaler le poste sous-total vers la gauche.
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+<!--
+vous pouvez également utiliser netprice à la place de sellprice
+si vous ne voulez pas afficher la remise
+netprice = sellprice - discount
+-->
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+    <tr>
+<%if taxincluded%>
+      <th colspan=5 align=right>Total</th>
+      <td colspan=2 align=right><%invtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+      <th colspan=5 align=right>Sous-total</th>
+      <td colspan=2 align=right><%subtotal%></td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=5 align=right><%taxdescription%></th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+<%if paid%>
+    <tr>
+      <th colspan=5 align=right>Déjà payé</th>
+      <td colspan=2 align=right>- <%paid%></td>
+    </tr>
+<%end paid%>
+
+    <tr>
+      <td colspan=3>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=3>À régler dans <b><%terms%></b> jours au plus tard.</td>
+      <th colspan=2 align=right>Solde à régler</th>
+      <th colspan=2 align=right><%total%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width="100%">
+    <tr valign=top>
+<%if notes%>
+      <td>À noter&nbsp;:</td>
+      <td><%notes%></td>
+<%end notes%>
+      <td align=right>
+      Tous prix indiqués en <b><%currency%></b>
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+
+<%if paid%>
+<tr>
+  <td colspan=7>
+    <table width="60%">
+      <tr>
+        <th align=left>Détail règlements</th>
+      </tr>
+      <tr>
+        <td colspan=4>
+         <hr noshade>
+       </td>
+      </tr>
+      <tr>
+        <th align=left>Date</th>
+       <th align=left>Compte</th>
+       <th align=left>Source</th>
+       <th align=left>Montant</th>
+      </tr>
+<%end paid%>
+
+<%foreach payment%>
+      <tr>
+        <td><%paymentdate%></td>
+       <td><%paymentaccount%></td>
+       <td><%paymentsource%></td>
+       <td><%payment%></td>
+      </tr>
+<%end payment%>
+
+<%if paid%>
+    </table>
+  </td>
+</tr>
+
+<tr>
+  <td>&nbsp;</td>
+</tr>
+<%end paid%>
+
+<tr>
+  <th colspan=7>
+  <!-- <br>Merci beaucoup&amp;nbsp;! -->
+  </th>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+
+<tr>
+  <td>
+  <table width="100%">
+  <tr valign=top>
+    <td><font size=-3>
+    &nbsp;
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+<!-- <%foreach tax%>
+  <tr>
+   <th colspan=7 align=left><font size=-2><%taxdescription%> Numéro de TVA <%taxnumber%></font></th>
+  </tr>
+<%end tax%> -->
+
+<%if taxincluded%>
+  <tr>
+    <th colspan=7 align=left><font size=-2>Les taxes affichés sont inclus dans le prix.</font></th>
+  </tr>
+<%end taxincluded%>
+
+<!-- business number
+  <tr>
+    <th colspan=7 align=left><font size=-2>Régistre de Commerce&amp;nbsp;: <%businessnumber%></font></th>
+  </tr>
+-->
+
+<!-- information banquaire -->
+  <tr><td>
+  <h6><center>N° TVA&nbsp;: &nbsp;&nbsp;Banque&nbsp;: &nbsp;&nbsp;N° de compte&nbsp;: &nbsp;&nbsp;Code SWIFT&nbsp;: </center>
+  </h6>
+    </td>
+  </tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
diff --git a/sql-ledger/templates/French-invoice.tex b/sql-ledger/templates/French-invoice.tex
new file mode 100644 (file)
index 0000000..2896fc9
--- /dev/null
@@ -0,0 +1,151 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage[frenchb]{babel}
+\usepackage[latin1]{inputenc}
+\usepackage{tabularx}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Téléphone & <%tel%>\\
+    Télécopieur & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Sous-total} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Numéro} & \textbf{Description} & \textbf{Qté} &
+    \textbf{Unité} & \textbf{Prix} & \textbf{Remise} & \textbf{Montant} \\
+  & reporté de la page <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{F A C T U R E}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date de facturation} & <%invdate%> \\
+  \textbf{Numéro de facture} & <%invnumber%> \\
+  \textbf{Numéro de client} & <%customer_id%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Numéro} & \textbf{Description} & \textbf{Qté} &
+    \textbf{Unité} & \textbf{Prix} & \textbf{Remise} & \textbf{Montant} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Sous-total} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> de <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%total%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Tous les prix indiqués sont en \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+\centerline{\textbf{Merci de faire affaire avec nous!}}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Le paiement doit être acquitté au plus tard <%terms%> jours à partir de
+la date de facturation. Des intérêts seront perçus à raison de 1.5\% par
+mois après <%duedate%> jusqu'à ce que le paiement soit complet. Les
+éléments retournés seront sujets à un supplément de remmagasinnage de
+10\%. Une autorisation de renvoi doit être obtenue au préalable auprès de
+<%company%>. Les frais de transports et d'assurance sur les éléments
+retournés devront être couvert par le client de façon appropriée.
+<%company%> ne peut être tenue responsable des dommages survenus pendant
+le transit.}
+
+\end{document}
diff --git a/sql-ledger/templates/French-packing_list.html b/sql-ledger/templates/French-packing_list.html
new file mode 100644 (file)
index 0000000..3fa2fec
--- /dev/null
@@ -0,0 +1,152 @@
+CTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional">
+
+<html>
+
+<head>
+
+<title>A2A <%invnumber%> <%name%></title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-15">
+
+</head>
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr>
+  <td width=10>
+  </td> 
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <th colspan=2>
+      <h4 align=center>L I S T E&nbsp;&nbsp;D ' E N V O I</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Date de facture&nbsp;:</th><td width=10> </td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Numéro de facture&nbsp;:</th><td></td><td><%invnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td> 
+      </td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Adresse d'envoi</th>
+    </tr>
+
+    <tr>
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td> 
+    </td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>N°</th>
+      <th align=left><font color=ffffff>Description</th>
+      <th><font color=ffffff>Qté</th>
+      <th>&nbsp;</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=center><%qty%></td>
+      <td><%unit%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>À noter&nbsp;:</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right><b>EXPÉDIÉ PAR&nbsp;: 
+      <%shippingpoint%></b>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3><!--
+    Conditions d'envoi :
+    Items returned are subject to
+    a 10% restocking charge. A return authorization must be obtained
+    from <%company%> before goods are returned. Returns must be shipped
+    prepaid and properly insured. <%company%> will not be responsible
+    for damages during transit. -->
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+</body>
+</html>
diff --git a/sql-ledger/templates/French-packing_list.tex b/sql-ledger/templates/French-packing_list.tex
new file mode 100644 (file)
index 0000000..87113de
--- /dev/null
@@ -0,0 +1,125 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage[frenchb]{babel}
+\usepackage[latin1]{inputenc}
+\usepackage{tabularx}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Téléphone & <%tel%>\\
+    Télécopieur & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Numéro} & \textbf{Description} & \textbf{Qté} &
+    \textbf{Unité} & \textbf{Bin} \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+
+\vspace{3.5cm}
+
+\textbf{L I S T E} \parbox{0.3cm}{\hfill} \textbf{D E}
+\parbox{0.3cm}{\hfill} \textbf{P A Q U E T A G E}
+
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date de facture} & <%invdate%> \\
+  \textbf{Numéro de facture} & <%invnumber%> \\
+  \textbf{Numéro de client} & <%customer_id%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Numéro} & \textbf{Description} & \textbf{Qté} &
+    \textbf{Unité} & \textbf{Bin} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%bin%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+\centerline{\textbf{Merci de faire affaire avec nous!}}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Les éléments retournés seront sujets à un supplément de remmagasinnage de
+10\%. Une autorisation de renvoi doit être obtenue au préalable auprès de
+<%company%>. Les frais de transports et d'assurance sur les éléments
+retournés devront être couvert par le client de façon appropriée.
+<%company%> ne peut être tenue responsable des dommages survenus pendant
+le transit.}
+
+\end{document}
diff --git a/sql-ledger/templates/French-purchase_order.html b/sql-ledger/templates/French-purchase_order.html
new file mode 100644 (file)
index 0000000..a5da0ad
--- /dev/null
@@ -0,0 +1,207 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional">
+
+<html>
+
+<head>
+
+<title>Commande <%ordnumber%> <%name%></title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-15">
+
+</head>
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Tél&nbsp;: <%tel%>
+      <br>Fax&nbsp;: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>B O N&nbsp;&nbsp;D E&nbsp;&nbsp;C O M M A N D E</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+ <table width=100% cellspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Date commande</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Requis pour</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>N° commande</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Commandé par</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>N°</th>
+      <th align=left><font color=ffffff>Description</th>
+      <th><font color=ffffff>Qté</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Prix</th>
+      <th><font color=ffffff>Montant</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+veuillez ajuster le colspan si vous voulez inclure ce poste pour décaler le sous-total vers la droite.
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=6><hr noshade></td>
+    </tr>
+    
+    <tr>
+      <th colspan=4 align=right>Sous-total</th>
+      <td colspan=2 align=right><%subtotal%></td>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=4 align=right><%taxdescription%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=2>À régler dans <b><%terms%></b> jours au plus tard</td>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%total%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>À noter&nbsp;:</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      Tous prix indiqués en <b><%currency%></b>
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td>
+<!--
+<font size=-3>
+    Payment due NET <%terms%> Days from date of Invoice.
+    Interest on overdue amounts will acrue at the rate of 1.5% per month
+    from due date until paid in full. Items returned are subject to
+    a 10% restocking charge. A return authorization must be obtained
+    from <%company%> before goods are returned. Returns must be shipped
+    prepaid and properly insured. <%company%> will not be responsible
+    for damages during transit.
+    </font>
+-->
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/French-purchase_order.tex b/sql-ledger/templates/French-purchase_order.tex
new file mode 100644 (file)
index 0000000..670d59c
--- /dev/null
@@ -0,0 +1,143 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage[frenchb]{babel}
+\usepackage[latin1]{inputenc}
+\usepackage{tabularx}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Téléphone & <%tel%>\\
+    Télécopieur & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Sous-total} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Amount} \\
+  & reporté de la page <%lastpage%> & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{B O N} \parbox{0.3cm}{\hfill} \textbf{D E} \parbox{0.3cm}{\hfill}
+\textbf{C O M M A N D E}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date de la commande} & <%orddate%> \\
+<%if reqdate%>
+  \textbf{Livrable le} & <%reqdate%> \\
+<%end reqdate%>
+  \textbf{Numéro de commande} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Numéro} & \textbf{Description} & \textbf{Qté} &
+    \textbf{Unité} & \textbf{Prix} & \textbf{Montant} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Sous-total} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> de <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Tous les prix indiqués sont en \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+%\footnotetext[1]{\tiny }
+
+\end{document}
diff --git a/sql-ledger/templates/French-receipt.tex b/sql-ledger/templates/French-receipt.tex
new file mode 100644 (file)
index 0000000..5b64e81
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/French-sales_order.html b/sql-ledger/templates/French-sales_order.html
new file mode 100644 (file)
index 0000000..492e75e
--- /dev/null
@@ -0,0 +1,229 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional">
+
+<html>
+
+<head>
+
+<title>Commande <%ordnumber%> <%name%></title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-15">
+
+</head>
+
+<body bgcolor="ffffff">
+
+<table width="100%">
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width="100%">
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Tél&nbsp;: <%tel%>
+      <br>Fax&nbsp;: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>B O N&nbsp;&nbsp;&nbsp;D E&nbsp;&nbsp;&nbsp;C O M M A N D E</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% cellspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Date commande</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Requis pour</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>N° commande</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width="100%">
+    <tr bgcolor="000000">
+      <th align=left><font color="ffffff">Commandé par</th>
+      <th align=left><font color="ffffff">Adresse d'envoi</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width="100%">
+    <tr bgcolor="000000">
+<!--      <th align=right><font color="ffffff">N°</th>  -->
+      <th align=left><font color="ffffff">N°</th>
+      <th align=left><font color="ffffff">Description</th>
+      <th><font color="ffffff">Qté</th>
+      <th>&nbsp;</th>
+      <th><font color="ffffff">Prix</th>
+      <th><font color="ffffff">Remise</th>
+      <th><font color="ffffff">Montant</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+    <tr>
+<%if taxincluded%>
+      <th colspan=5 align=right>Total</th>
+      <td colspan=2 align=right><%ordtotal%></td>
+<%end taxincluded%>
+
+<%if not taxincluded%>
+      <th colspan=5 align=right>Sous-total</th>
+      <td colspan=2 align=right><%subtotal%></td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=5 align=right><%taxdescription%></th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=5><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=3>À régler dans <b><%terms%></b> jours au plus tard</td>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%ordtotal%></th>
+    </tr>
+<%if taxincluded%>
+    <tr>
+      <td colspan=3>Taxe comprise dans Total</td>
+    </tr>
+<%end taxincluded%>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width="100%">
+    <tr valign=top>
+<%if notes%>
+      <td>À noter&nbsp;:</td>
+      <td><%notes%></td>
+<%end notes%>
+      <td align=right>
+      Tous prix indiqués en <b><%currency%></b>
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width="100%">
+  <tr valign=top>
+    <td><font size=-3>
+<!--
+    A 10% order cancellation fee will be applied for any special order
+    products or products that have been customized, enhanced or
+    upgraded at customers request.
+-->
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  <tr>
+  <td colspan=5>
+    <h6><center>N° TVA&nbsp;: &nbsp;&nbsp;Banque&nbsp;: &nbsp;&nbsp;N° de compte&nbsp;: &nbsp;&nbsp;Code SWIFT&nbsp;: </center>
+      </h6>
+  </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
diff --git a/sql-ledger/templates/French-sales_order.tex b/sql-ledger/templates/French-sales_order.tex
new file mode 100644 (file)
index 0000000..88e142f
--- /dev/null
@@ -0,0 +1,144 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage[frenchb]{babel}
+\usepackage[latin1]{inputenc}
+\usepackage{tabularx}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Téléphone & <%tel%>\\
+    Télécopieur & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Sous-total} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Numéro} & \textbf{Description} & \textbf{Qté} &
+    \textbf{Unité} & \textbf{Prix} & \textbf{Remise} & \textbf{Montant} \\
+  & reporté de la page <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{C O M M A N D E} \parbox{0.3cm}{\hfill} \textbf{C L I E N T}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date de la commande} & <%orddate%> \\
+  \textbf{Numéro de commande} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Numéro} & \textbf{Description} & \textbf{Qté} &
+    \textbf{Unité} & \textbf{Prix} & \textbf{Remise} & \textbf{Montant} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Sous-total} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> de <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Tous les prix indiqués sont en \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Un supplément de 10% sera appliqué à toute commande spécifique et à tout
+produit adapté, amélioré ou mis-à-jour à la demande du client. Les
+éléments non-retournables sont indiqués ci-dessus.
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/French-statement.html b/sql-ledger/templates/French-statement.html
new file mode 100644 (file)
index 0000000..c2c9a5d
--- /dev/null
@@ -0,0 +1,133 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional">
+
+<html>
+
+<head>
+
+<title>Extrait de compte pour <%name%></title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-15">
+
+</head>
+
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+  <tr>
+    <td width=10>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr>
+         <td>
+           <h4>
+           <%company%>
+           <br><%address%>
+           </h4>
+         </td>
+         <th></th>
+         <td align=right>
+         <h4>
+         Tél&nbsp;: <%tel%>
+         <br>Fax&nbsp;: <%fax%>
+         </h4>
+         </td>
+       </tr>
+       <tr>
+         <th colspan=3><h4>E X T R A I T&nbsp;&nbsp;D E&nbsp;&nbsp;C O M P T E</h4></th>
+       </tr>
+       <tr>
+         <td colspan=3 align=right><%statementdate%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr valign=top>
+         <td><%name%>
+         <br><%addr1%>
+         <br><%addr2%>
+         <br><%addr3%>
+         <br><%addr4%>
+         <br>
+<%if customerphone%>
+         <br>Tél&nbsp;: <%customerphone%>
+<%end customerphone%>
+<%if customerfax%>
+         <br>Fax&nbsp;: <%customerfax%>
+<%end customerfax%>
+<%if email%>
+         <br><%email%>
+<%end email%>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+        <tr>
+         <th align=left>Facture n°</th>
+         <th width=15%>Date</th>
+         <th width=15%>Echeance</th>
+         <th width=10%>Actuel</th>
+         <th width=10%>30</th>
+         <th width=10%>60</th>
+         <th width=10%>90+</th>
+       </tr>
+<%foreach invnumber%>
+       <tr>
+         <td><%invnumber%></td>
+         <td><%invdate%></td>
+         <td><%duedate%></td>
+         <td align=right><%c0%></td>
+         <td align=right><%c30%></td>
+         <td align=right><%c60%></td>
+         <td align=right><%c90%></td>
+       </tr>
+<%end invnumber%>
+        <tr>
+         <td colspan=7><hr size=1></td>
+       </tr>
+       <tr>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <th align=right><%c0total%></td>
+         <th align=right><%c30total%></td>
+         <th align=right><%c60total%></td>
+         <th align=right><%c90total%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td align=right>
+      <table width=50%>
+        <tr>
+         <th>Solde impayé</th>
+          <th align=right><%total%></th>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td><hr noshade></td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>Tout paiement au nom de <b><%company%></b>
+    </td>
+  </tr>
+  <tr height=20></tr>
+</table>
+</body>
+</html>
diff --git a/sql-ledger/templates/French-statement.tex b/sql-ledger/templates/French-statement.tex
new file mode 100644 (file)
index 0000000..0b63f75
--- /dev/null
@@ -0,0 +1,137 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+
+      <%address%>}\hfill
+    \begin{tabular}[b]{rrr@{}}
+    Tel & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%statementdate%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%statementdate%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+  carried forward from <%lastpage%> & & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{1.5cm}
+
+\parbox[t]{1cm}{\hfill}
+\parbox[t]{10.5cm}{
+  
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+}
+\parbox[t]{7.5cm}{
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{S T A T E M E N T} \hfill
+
+\hfill <%statementdate%>
+
+\vspace{2cm}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+<%foreach invnumber%>
+  <%invnumber%> & <%invdate%> & <%duedate%> &
+  <%c0%> & <%c30%> & <%c60%> & <%c90%> \\
+<%end invnumber%>
+\textbf{Subtotal} & & & <%c0total%> & <%c30total%> & <%c60total%> & <%c90total%>
+\end{tabular*}
+\rule{\textwidth}{1pt}
+
+\vspace{1cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Total outstanding} & <%total%>
+\end{tabularx}
+
+\vfill
+
+Please make check payable to <%company%>
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/German-balance_sheet.html b/sql-ledger/templates/German-balance_sheet.html
new file mode 100644 (file)
index 0000000..f0d6f5e
--- /dev/null
@@ -0,0 +1,100 @@
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>BILANZ
+<br><%period%>
+</h2>
+
+<table border=0>
+<tr>
+  <th align=left width=400 colspan=2>AKTIVA<br><hr align=left width=250 size=5 noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach asset_account%>
+<tr>
+  <td> </td>
+  <td><%asset_account%></td>
+  <td align=right><%asset_this_period%></td>
+  <td align=right><%asset_last_period%></td>
+</tr>
+<%end asset_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>TOTAL</th>
+  <td align=right><%total_assets_this_period%><hr noshade size=2></td>
+  <td align=right><%total_assets_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>PASSIVA<b><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach liability_account%>
+<tr>
+  <td></td>
+  <td><%liability_account%></td>
+  <td align=right><%liability_this_period%></td>
+  <td align=right><%liability_last_period%></td>
+</tr>
+<%end liability_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>TOTAL</th>
+  <td align=right><%total_liabilities_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_liabilities_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>EIGENTUM<br><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach equity_account%>
+<tr>
+  <td></td>
+  <td><%equity_account%></td>
+  <td align=right><%equity_this_period%></td>
+  <td align=right><%equity_last_period%></td>
+</tr>
+<%end equity_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>TOTAL</th>
+  <td align=right><%total_equity_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_equity_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>TOTAL PASSIVA & EIGETNTUM</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+</table>
+
+
+
diff --git a/sql-ledger/templates/German-check.tex b/sql-ledger/templates/German-check.tex
new file mode 100644 (file)
index 0000000..d6256e7
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Rechnung} & \textbf{Ausgestellt}
+  & \textbf{Fällig} & \textbf{Verrechnet} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/German-income_statement.html b/sql-ledger/templates/German-income_statement.html
new file mode 100644 (file)
index 0000000..aa3c22f
--- /dev/null
@@ -0,0 +1,78 @@
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>GEWINN & VERLUST
+<br><%period%>
+</h2>
+
+
+<table width=100% border=0>
+<tr>
+  <th width=400 align=left colspan=2>EINNAHMEN<br><hr width=300 size=5 align=left noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach income_account%>
+<tr>
+  <td width=4> </td>
+  <td><%income_account%></td>
+  <td align=right><%income_this_period%></td>
+  <td align=right><%income_last_period%></td>
+</tr>
+<%end income_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Totale Einnahmen</th>
+  <td align=right><%total_income_this_period%><hr noshade size=2></td>
+  <td align=right><%total_income_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=2>AUSGABEN<br><hr width=300 size=5 align=left noshade></th>
+</tr>
+
+<%foreach expense_account%>
+<tr>
+  <td> </td>
+  <td><%expense_account%></td>
+  <td align=right><%expenses_this_period%></td>
+  <td align=right><%expenses_last_period%></td>
+</tr>
+<%end expense_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Totale Ausgaben</th>
+  <td align=right><%total_expenses_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_expenses_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>GEWINN / (VERLUST)</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/German-invoice.html b/sql-ledger/templates/German-invoice.html
new file mode 100644 (file)
index 0000000..b2128c9
--- /dev/null
@@ -0,0 +1,265 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Telefon <%tel%>
+      <br>Telefax <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>R E C H N U N G</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Ausgestellt am</th><td width=10>&nbsp;</td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Bezahlbar bis</th><td width=10>&nbsp;</td><td><%duedate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Nummer</th><td>&nbsp;</td><td><%invnumber%></td></tr>
+    </tr>
+  
+<!--
+    <tr>
+      <th align=right>Clerk:</th><td>&nbsp;</td><td><%username%></td>
+    </tr>
+-->
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>An:</th>
+      <th align=left><font color=ffffff>Lieferaddresse:</th>
+    </tr>
+
+<!--
+     other variables which can be use:
+     contact, shiptocontact, shiptophone, shiptofax
+-->
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+      
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Nummer</th>
+      <th align=left><font color=ffffff>Beschreibung</th>
+      <th><font color=ffffff>Anz.</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Preis</th>
+      <th><font color=ffffff>Rab</th>
+      <th><font color=ffffff>Total</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+<!--
+you can also use netprice instead of sellprice if you
+don't want to show the discount
+netprice = sellprice - discount
+-->
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+<%if taxincluded%>
+    <tr>
+      <th colspan=5 align=right>Total</th>
+      <td colspan=2 align=right><%invtotal%></td>
+    </tr>
+<%end taxincluded%>
+<%if not taxincluded%>
+    <tr>
+      <th colspan=5 align=right>Zwischensumme</th>
+      <td colspan=2 align=right><%subtotal%></td>
+    </tr>
+<%end taxincluded%>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=5 align=right><%taxdescription%> auf <%taxbase%></th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+<%if paid%>
+    <tr>
+      <th colspan=5 align=right>Bezahlt</th>
+      <td colspan=2 align=right>- <%paid%></td>
+    </tr>
+<%end paid%>
+
+    <tr>
+      <td colspan=3>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=3>Bezahlbar innerhalb von <b><%terms%></b> Tagen</td>
+<%if total%>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%total%></th>
+<%end total%>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Bemerkungen:</td>
+      <td><%notes%></td>
+<%end notes%>
+      <td align=right>
+      Alle Preise in <b><%currency%></b>
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Rechnung ist bezahlbar innerhalb von <%terms%> Tagen.
+    Nach dem <%duedate%> werden Zinsen zu einem
+    monatlichen Satz von 1.5% verrechnet.
+    Waren bleiben im Besitz von <%company%> bis die Rechnung voll bezahlt ist.
+    Rückgaben werden mit 10% Lagergebühren belastet. Beschädigte Waren
+    und Waren ohne eine Rückgabenummer werden nicht entgegengenommen.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+<%foreach tax%>
+  <tr>
+    <th colspan=7 align=left><font size=-2><%taxdescription%> Registration <%taxnumber%></th>
+  </tr>
+<%end tax%>
+
+<%if taxincluded%>
+  <tr>
+    <th colspan=7 align=left><font size=-2>Steuern sind im Preis inbegriffen.</th>
+  </tr>
+<%end taxincluded%>
+
+<!-- business number
+  <tr>
+    <th colspan=7 align=left><font size=-2>Business Number: <%businessnumber%></font></th>
+  </tr>
+-->
+
+  <tr>
+    <th colspan=7 align=left>
+    <hr>
+    <br>Bankverbindung
+    <br>Bank
+    <br>Bankleitzahl
+    <br>Konto No.
+    </td>
+  </tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/German-invoice.tex b/sql-ledger/templates/German-invoice.tex
new file mode 100644 (file)
index 0000000..0b38bb5
--- /dev/null
@@ -0,0 +1,155 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefon & <%tel%>\\
+    Telefax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Nummer} & \textbf{Artikel} & \textbf{Anz} &
+    \textbf{Einh} & \textbf{Preis} & \textbf{Rab} & \textbf{Total} \\
+  & Übertrag von Seite <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{R E C H N U N G}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Datum} & <%invdate%> \\
+  \textbf{Nummer} & <%invnumber%> \\
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Nummer} & \textbf{Artikel} & \textbf{Anz} &
+    \textbf{Einh} & \textbf{Preis} & \textbf{Rab} & \textbf{Total} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Zwischensumme} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> auf <%taxbase%> & <%tax%> \\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%invtotal%>} \\
+<%if paid%>
+  \textbf{Bezahlt} & <%paid%> \\
+<%end paid%>
+<%if total%>
+  \textbf{Bezahlbar} & \textbf{<%total%>} \\
+<%end total%>
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Alle Preise in \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+%\vfill
+%\centerline{\textbf{salute}}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Rechnung ist bezahlbar innerhalb von <%terms%> Tagen.
+Nach dem <%duedate%> werden Zinsen zu einem
+monatlichen Satz von 1.5\% verrechnet.
+Waren bleiben im Besitz von <%company%> bis die Rechnung voll bezahlt ist.
+Rückgaben werden mit 10 Prozent Lagergebühren belastet. Beschädigte Waren
+und Waren ohne eine Rückgabenummer werden nicht entgegengenommen.
+}
+
+\end{document}
+
+
diff --git a/sql-ledger/templates/German-packing_list.html b/sql-ledger/templates/German-packing_list.html
new file mode 100644 (file)
index 0000000..09ef402
--- /dev/null
@@ -0,0 +1,146 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr>
+  <td width=10>
+  </td> 
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <th colspan=2>
+      <h4 align=center>V E R P P A C K U N G S L I S T E</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Datum</th><td width=10> </td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Nummer</th><td></td><td><%invnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td> 
+      </td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Zustellung an:</th>
+    </tr>
+
+    <tr>
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+<%if shiptocontact%>
+      <p>An: <%shiptocontact%>
+<%end shiptocontact%>
+
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td> 
+    </td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Nummer</th>
+      <th align=left><font color=ffffff>Artikel</th>
+      <th><font color=ffffff>Anz</th>
+      <th>&nbsp;</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Bemerkungen</td>
+      <td><%notes%></td>
+<%end notes%>
+      <td align=right>
+      <%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Beschädigte Waren und Waren ohne Rückgabenummer werden nicht
+    entgegengenommen. Lagerkosten werden mit 10% berrechnet.
+    Waren müssen ausreichended verpackt und versichert sein.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/German-packing_list.tex b/sql-ledger/templates/German-packing_list.tex
new file mode 100644 (file)
index 0000000..dbfc93b
--- /dev/null
@@ -0,0 +1,118 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefon & <%tel%>\\
+    Telefax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Nummer} & \textbf{Artikel} & \textbf{Anz} &
+    \textbf{Einh} & \textbf{Steige} \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+
+\vspace{3.5cm}
+
+\textbf{P A C K I N G} \parbox{0.3cm}{\hfill} \textbf{L I S T}
+
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Datum} & <%invdate%> \\
+  \textbf{Nummer} & <%invnumber%> \\
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rll@{}}
+  \textbf{Nummer} & \textbf{Artikel} & \textbf{Anz} &
+    \textbf{Einh} & \textbf{Steige} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%bin%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Beschädigte Waren und Waren ohne Rückgabenummer werden nicht
+entgegengenommen. Lagerkosten werden mit 10\% berrechnet.
+Waren müssen ausreichended verpackt und versichert sein.
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/German-purchase_order.html b/sql-ledger/templates/German-purchase_order.html
new file mode 100644 (file)
index 0000000..9771d02
--- /dev/null
@@ -0,0 +1,188 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Telefon <%tel%>
+      <br>Telefax <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>B E S T E L L U N G</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Bestellungsdatum</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Lieferbar bis</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Bestellnummer</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>An:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Nummer</th>
+      <th align=left><font color=ffffff>Artikel</th>
+      <th><font color=ffffff>Anz</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Preis</th>
+      <th><font color=ffffff>Total</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=6><hr noshade></td>
+    </tr>
+    
+    <tr>
+      <th colspan=4 align=right>Zwischensumme</th>
+      <td colspan=2 align=right><%subtotal%></td>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=4 align=right><%taxdescription%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=2>Netto <b><%terms%></b> Tage</td>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%total%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Bemerkungen</td>
+      <td><%notes%></td>
+<%end notes%>
+      <td align=right>
+      Alle Preise in <b><%currency%></b>
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    &nbsp;
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/German-purchase_order.tex b/sql-ledger/templates/German-purchase_order.tex
new file mode 100644 (file)
index 0000000..f56f1a3
--- /dev/null
@@ -0,0 +1,143 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefon & <%tel%>\\
+    Telefax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Zwischensumme} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Nummer} & \textbf{Artikel} & \textbf{Anz} &
+    \textbf{Einh} & \textbf{Preis} & \textbf{Total} \\
+  & Übertrag von <%lastpage%> & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{B E S T E L L U N G}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Datum} & <%orddate%> \\
+<%if reqdate%>
+  \textbf{Lieferung bis} & <%reqdate%> \\
+<%end reqdate%>
+  \textbf{Nummer} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Nummer} & \textbf{Artikel} & \textbf{Anz} &
+    \textbf{Einh} & \textbf{Preis} & \textbf{Total} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Zwischensumme} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Alle Preise in \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+%\footnotetext[1]{\tiny }
+
+\end{document}
+
+
diff --git a/sql-ledger/templates/German-receipt.tex b/sql-ledger/templates/German-receipt.tex
new file mode 100644 (file)
index 0000000..d6256e7
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Rechnung} & \textbf{Ausgestellt}
+  & \textbf{Fällig} & \textbf{Verrechnet} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/German-sales_order.html b/sql-ledger/templates/German-sales_order.html
new file mode 100644 (file)
index 0000000..edb8b90
--- /dev/null
@@ -0,0 +1,213 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Telefon <%tel%>
+      <br>Telefax <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>B E S T E L L U N G</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Datum</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Lieferbar bei</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Bestellnummer</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Verrechnet An:</th>
+      <th align=left><font color=ffffff>Lieferaddresse:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Nummer</th>
+      <th align=left><font color=ffffff>Artikel</th>
+      <th><font color=ffffff>Anz</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Preis</th>
+      <th><font color=ffffff>Rab</th>
+      <th><font color=ffffff>Total</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%discount%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=7><hr noshade></td>
+    </tr>
+    
+<%if taxincluded%>
+    <tr>
+      <th colspan=5 align=right>Total</th>
+      <td colspan=2 align=right><%ordtotal%></td>
+    </tr>
+<%end taxincluded%>
+
+<%if not taxincluded%>
+    <tr>
+      <th colspan=5 align=right>Zwischensumme</th>
+      <td colspan=2 align=right><%subtotal%></td>
+    </tr>
+<%end taxincluded%>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=5 align=right><%taxdescription%> auf <%taxbase%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=5><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=3>Netto <b><%terms%></b> Tage</td>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%ordtotal%></th>
+    </tr>
+<%if taxincluded%>
+    <tr>
+      <td colspan=3>Steuern sind im Preis inbegriffen</td>
+    </tr>
+<%end taxincluded%>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Bemerkungen</td>
+      <td><%notes%></td>
+<%end notes%>
+      <td align=right>
+      Alle Preise in <b><%currency%></b>
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Spezialprodukte werden nicht zurückgenommen. Für alle anderen Waren
+    wird eine 10% Stornogebühr verrechnet.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/German-sales_order.tex b/sql-ledger/templates/German-sales_order.tex
new file mode 100644 (file)
index 0000000..21948c6
--- /dev/null
@@ -0,0 +1,142 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telefon & <%tel%>\\
+    Telefax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Zwischensumme} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Nummer} & \textbf{Artikel} & \textbf{Anz} &
+    \textbf{Einh} & \textbf{Preis} & \textbf{Rab} & \textbf{Total} \\
+  & Übertrag von Seite <%lastpage%> & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{B E S T E L L U N G}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Datum} & <%orddate%> \\
+  \textbf{Nummer} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrrr@{}}
+  \textbf{Nummer} & \textbf{Artikel} & \textbf{Anz} &
+    \textbf{Einh} & \textbf{Preis} & \textbf{Rab} & \textbf{Total} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%discount%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Zwischensumme} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> auf <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  Alle Preise in \textbf{<%currency%>}.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Spezialprodukte werden nicht zurückgenommen. Für alle anderen Waren
+wird eine 10\% Stornogebühr verrechnet.
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/German-statement.html b/sql-ledger/templates/German-statement.html
new file mode 100644 (file)
index 0000000..6fca322
--- /dev/null
@@ -0,0 +1,121 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+  <tr>
+    <td width=10>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr>
+         <td>
+           <h4>
+           <%company%>
+           <br><%address%>
+           </h4>
+         </td>
+         <th><img src=http://www.sql-ledger.org/images/sql-ledger.png border=0 width=64 height=58></th>
+         <td align=right>
+         <h4>
+         Tel: <%tel%>
+         <br>Fax: <%fax%>
+         </h4>
+         </td>
+       </tr>
+       <tr>
+         <th colspan=3><h4>S T A T E M E N T</h4></th>
+       </tr>
+       <tr>
+         <td colspan=3 align=right><%statementdate%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr valign=top>
+         <td><%name%>
+         <br><%addr1%>
+         <br><%addr2%>
+         <br><%addr3%>
+         <br><%addr4%>
+         <br>
+<%if customerphone%>
+         <br>Tel: <%customerphone%>
+<%end customerphone%>
+<%if customerfax%>
+         <br>Fax: <%customerfax%>
+<%end customerfax%>
+<%if email%>
+         <br><%email%>
+<%end email%>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+        <tr>
+         <th align=left>Invoice #</th>
+         <th width=15%>Date</th>
+         <th width=15%>Due</th>
+         <th width=10%>Current</th>
+         <th width=10%>30</th>
+         <th width=10%>60</th>
+         <th width=10%>90+</th>
+       </tr>
+<%foreach invnumber%>
+       <tr>
+         <td><%invnumber%></td>
+         <td><%invdate%></td>
+         <td><%duedate%></td>
+         <td align=right><%c0%></td>
+         <td align=right><%c30%></td>
+         <td align=right><%c60%></td>
+         <td align=right><%c90%></td>
+       </tr>
+<%end invnumber%>
+        <tr>
+         <td colspan=7><hr size=1></td>
+       </tr>
+       <tr>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <th align=right><%c0total%></td>
+         <th align=right><%c30total%></td>
+         <th align=right><%c60total%></td>
+         <th align=right><%c90total%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td align=right>
+      <table width=50%>
+        <tr>
+         <th>Total Outstanding</th>
+          <th align=right><%total%></th>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td><hr noshade></td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>Please make check payable to <b><%company%></b>.
+    </td>
+  </tr>
+  <tr height=20></tr>
+</table>
+
diff --git a/sql-ledger/templates/German-statement.tex b/sql-ledger/templates/German-statement.tex
new file mode 100644 (file)
index 0000000..0b63f75
--- /dev/null
@@ -0,0 +1,137 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+
+      <%address%>}\hfill
+    \begin{tabular}[b]{rrr@{}}
+    Tel & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%statementdate%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%statementdate%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+  carried forward from <%lastpage%> & & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{1.5cm}
+
+\parbox[t]{1cm}{\hfill}
+\parbox[t]{10.5cm}{
+  
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+}
+\parbox[t]{7.5cm}{
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{S T A T E M E N T} \hfill
+
+\hfill <%statementdate%>
+
+\vspace{2cm}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+<%foreach invnumber%>
+  <%invnumber%> & <%invdate%> & <%duedate%> &
+  <%c0%> & <%c30%> & <%c60%> & <%c90%> \\
+<%end invnumber%>
+\textbf{Subtotal} & & & <%c0total%> & <%c30total%> & <%c60total%> & <%c90total%>
+\end{tabular*}
+\rule{\textwidth}{1pt}
+
+\vspace{1cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Total outstanding} & <%total%>
+\end{tabularx}
+
+\vfill
+
+Please make check payable to <%company%>
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Service-balance_sheet.html b/sql-ledger/templates/Service-balance_sheet.html
new file mode 100644 (file)
index 0000000..478caab
--- /dev/null
@@ -0,0 +1,100 @@
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>BALANCE SHEET
+<br><%period%>
+</h2>
+
+<table border=0>
+<tr>
+  <th align=left width=400 colspan=2>ASSETS<br><hr align=left width=250 size=5 noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach asset_account%>
+<tr>
+  <td> </td>
+  <td><%asset_account%></td>
+  <td align=right><%asset_this_period%></td>
+  <td align=right><%asset_last_period%></td>
+</tr>
+<%end asset_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>TOTAL ASSETS</th>
+  <td align=right><%total_assets_this_period%><hr noshade size=2></td>
+  <td align=right><%total_assets_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>LIABILITIES<b><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach liability_account%>
+<tr>
+  <td></td>
+  <td><%liability_account%></td>
+  <td align=right><%liability_this_period%></td>
+  <td align=right><%liability_last_period%></td>
+</tr>
+<%end liability_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Total Liabilities</th>
+  <td align=right><%total_liabilities_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_liabilities_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>SHAREHOLDER'S EQUITY<br><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach equity_account%>
+<tr>
+  <td></td>
+  <td><%equity_account%></td>
+  <td align=right><%equity_this_period%></td>
+  <td align=right><%equity_last_period%></td>
+</tr>
+<%end equity_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Total Equity</th>
+  <td align=right><%total_equity_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_equity_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>TOTAL LIABILITIES & EQUITY</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+</table>
+
+
+
diff --git a/sql-ledger/templates/Service-check.tex b/sql-ledger/templates/Service-check.tex
new file mode 100644 (file)
index 0000000..5b64e81
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Service-income_statement.html b/sql-ledger/templates/Service-income_statement.html
new file mode 100644 (file)
index 0000000..e9d6a40
--- /dev/null
@@ -0,0 +1,82 @@
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>INCOME STATEMENT
+<br><%period%>
+</h2>
+
+
+<table width=100% border=0>
+<tr>
+  <th width=400 align=left colspan=2>INCOME<br><hr width=300 size=5 align=left noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach income_account%>
+<tr>
+  <td width=4> </td>
+  <td><%income_account%></td>
+  <td align=right><%income_this_period%></td>
+  <td align=right><%income_last_period%></td>
+</tr>
+<%end income_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Total Income</th>
+  <td align=right><%total_income_this_period%><hr noshade size=2></td>
+  <td align=right><%total_income_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=2>EXPENSES<br><hr width=300 size=5 align=left noshade></th>
+</tr>
+
+<%foreach expense_account%>
+<tr>
+  <td> </td>
+  <td><%expense_account%></td>
+  <td align=right><%expenses_this_period%></td>
+  <td align=right><%expenses_last_period%></td>
+</tr>
+<%end expense_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td> </td>
+  <th align=left>Total Expenses</th>
+  <td align=right><%total_expenses_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_expenses_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>INCOME / (LOSS)</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+
+</table>
+
+
+
+
+
+
+
+
diff --git a/sql-ledger/templates/Service-invoice.html b/sql-ledger/templates/Service-invoice.html
new file mode 100644 (file)
index 0000000..8ae6897
--- /dev/null
@@ -0,0 +1,226 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr>
+  <td width=10>
+  </td> 
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      <br>Tel/Fax <%tel%> / <%fax%>
+      </h4>
+    </td>
+
+    <th colspan=2>
+      <h4 align=center>I N V O I C E</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Date</th><td width=10> </td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Number</th><td></td><td><%invnumber%></td></tr>
+    </tr>
+
+<!-- prepared by: <%username%>
+-->
+
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>To:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+      
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td> 
+    </td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Description</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Amount</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+      <td><%description%></td>
+      <td>&nbsp;</td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=3><hr noshade></td>
+    </tr>
+    
+    <tr>
+<%if taxincluded%>
+      <td>&nbsp;</td>
+      <th align=right>Total</th>
+      <td align=right><%invtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+      <td>&nbsp;</td>
+      <th align=right>Subtotal</th>
+      <td align=right><%subtotal%></td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=2 align=right><%taxdescription%></th>
+      <td align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+<!--
+  <%taxbase%> = total netamount for each tax bracket
+  <%taxrate%> = taxrate in percent
+-->
+     
+<%if paid%>
+    <tr>
+      <td>&nbsp;</td>
+      <th align=right>Paid</th>
+      <td align=right><%paid%></td>
+    </tr>
+<%end paid%>
+
+    <tr>
+      <td>&nbsp;</td>
+      <td colspan=2><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td>
+<%if terms%>
+Terms &nbsp;Net <b><%terms%></b> days
+<%end terms%>
+</td>
+      <th align=right>Total</th>
+      <th align=right><%total%></th>
+    </tr>
+    
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<%if notes%>
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+      <td>Notes</td>
+      <td><pre><%notes%></pre></td>
+      <td align=right>
+      &nbsp;
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+<%end notes%>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <th colspan=3>
+  Please make check payable to <%company%>
+  <br>Thank you for your valued business!
+  </th>
+</tr>
+
+
+<tr><td>&nbsp;</td></tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Payment due NET <%terms%> Days from date of Invoice.
+    Interest on overdue amounts will acrue at the rate of 1.5% per month
+    from due date until paid in full.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=3 align=left><font size=-2><%taxdescription%> Registration <%taxnumber%></th>
+    </tr>
+<%end tax%>
+
+<!--
+  %username% = user name
+  %businessnumber% = business number
+-->
+
+<!-- banking information
+    <tr>
+      <th colspan=3 align=left><font size=-2>Banking Information:
+      <br>Bank
+      <br>Transit No.
+      <br>Account No.
+      </th>
+    </tr>
+-->
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Service-invoice.tex b/sql-ledger/templates/Service-invoice.tex
new file mode 100644 (file)
index 0000000..810a50e
--- /dev/null
@@ -0,0 +1,151 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telephone & <%tel%>\\
+    Facsimile & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}p{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Amount} \\
+  & carried forward from <%lastpage%> & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{I N V O I C E}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date} & <%invdate%> \\
+  \textbf{Number} & <%invnumber%> \\
+  \textbf{Customer} & <%customer_id%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}p{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Amount} \\
+<%foreach number%>
+  <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%> \\
+<%end tax%>
+<%if paid%>
+  \textbf{Paid} & - <%paid%> \\
+<%end paid%>
+  \hline
+  \textbf{Balance Owing} & \textbf{<%total%>} \\
+
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  All prices in \textbf{<%currency%>} funds.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+\vfill
+\centerline{\textbf{Thank You for your valued business!}}
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+Payment due NET <%terms%> Days from date of Invoice. Interest on overdue
+amounts will acrue at the rate of 1.5\% per month starting <%duedate%>
+until paid in full.
+}
+
+\end{document}
+
+
diff --git a/sql-ledger/templates/Service-packing_list.html b/sql-ledger/templates/Service-packing_list.html
new file mode 100644 (file)
index 0000000..07ba8d6
--- /dev/null
@@ -0,0 +1,148 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr>
+  <td width=10>
+  </td> 
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <th colspan=2>
+      <h4 align=center>P A C K I N G &nbsp;&nbsp; L I S T</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Date</th><td width=10> </td><td><%invdate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Number</th><td></td><td><%invnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td> 
+      </td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Ship To:</th>
+    </tr>
+
+    <tr>
+      <td><%shiptoname%>
+      <br><%shiptoaddr1%>
+      <br><%shiptoaddr2%>
+      <br><%shiptoaddr3%>
+      <br><%shiptoaddr4%>
+<%if shiptocontact%>
+      <p>Attn: <%shiptocontact%>
+<%end shiptocontact%>
+
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td> 
+    </td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>Number</th>
+      <th align=left><font color=ffffff>Description</th>
+      <th><font color=ffffff>Qt'y</th>
+      <th>&nbsp;</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Notes</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      <%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Items returned are subject to
+    a 10% restocking charge. A return authorization must be obtained
+    from <%company%> before goods are returned. Returns must be shipped
+    prepaid and properly insured. <%company%> will not be responsible
+    for damages during transit.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Service-packing_list.tex b/sql-ledger/templates/Service-packing_list.tex
new file mode 100644 (file)
index 0000000..b5a6a8a
--- /dev/null
@@ -0,0 +1,120 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telephone & <%tel%>\\
+    Facsimile & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%invnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+\newpage
+
+\markright{<%company%>\hfill <%invnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}p{\descrwidth}@{\extracolsep\fill}rl@{}}
+  \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+
+\vspace{3.5cm}
+
+\textbf{P A C K I N G} \parbox{0.3cm}{\hfill} \textbf{L I S T}
+
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date} & <%invdate%> \\
+  \textbf{Number} & <%invnumber%> \\
+  \textbf{Customer} & <%customer_id%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}p{\descrwidth}@{\extracolsep\fill}rl@{}}
+  \textbf{Description} & \textbf{Qt'y} & \textbf{Unit} \\
+<%foreach number%>
+  <%description%> & <%qty%> & <%unit%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+%\vfill
+%\centerline{\textbf{Thank You for your valued business!}}
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+%\footnotetext[1]{\tiny
+%Items returned are subject to a 10\% restocking charge.
+%A return authorization must be obtained from <%company%> before goods are
+%returned. Returns must be shipped prepaid and properly insured.
+%<%company%> will not be responsible for damages during transit.}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Service-purchase_order.html b/sql-ledger/templates/Service-purchase_order.html
new file mode 100644 (file)
index 0000000..f2e9f7e
--- /dev/null
@@ -0,0 +1,194 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Telephone: <%tel%>
+      <br>Facsimile: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>P U R C H A S E &nbsp;&nbsp; O R D E R</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Order Date</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Required by</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Number</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>To:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Number</th>
+      <th align=left><font color=ffffff>Description</th>
+      <th><font color=ffffff>Qt'y</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Price</th>
+      <th><font color=ffffff>Amount</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=6><hr noshade></td>
+    </tr>
+    
+    <tr>
+      <th colspan=4 align=right>Subtotal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=4 align=right><%taxdescription%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=2>Terms Net <b><%terms%></b> days</td>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%total%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Notes</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      All prices in <b><%currency%></b> Funds
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Payment due NET <%terms%> Days from date of Invoice.
+    Interest on overdue amounts will acrue at the rate of 1.5% per month
+    from due date until paid in full. Items returned are subject to
+    a 10% restocking charge. A return authorization must be obtained
+    from <%company%> before goods are returned. Returns must be shipped
+    prepaid and properly insured. <%company%> will not be responsible
+    for damages during transit.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Service-purchase_order.tex b/sql-ledger/templates/Service-purchase_order.tex
new file mode 100644 (file)
index 0000000..e6cc92c
--- /dev/null
@@ -0,0 +1,143 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telephone & <%tel%>\\
+    Facsimile & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Amount} \\
+  & carried forward from <%lastpage%> & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{P U R C H A S E} \parbox{0.3cm}{\hfill} \textbf{O R D E R}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date} & <%orddate%> \\
+<%if reqdate%>
+  \textbf{Required by} & <%reqdate%> \\
+<%end reqdate%>
+  \textbf{Number} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}lp{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Number} & \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Amount} \\
+<%foreach number%>
+  <%number%> & <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  All prices in \textbf{<%currency%>} funds.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+%\footnotetext[1]{\tiny }
+
+\end{document}
+
+
diff --git a/sql-ledger/templates/Service-receipt.tex b/sql-ledger/templates/Service-receipt.tex
new file mode 100644 (file)
index 0000000..5b64e81
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Service-sales_order.html b/sql-ledger/templates/Service-sales_order.html
new file mode 100644 (file)
index 0000000..319cc3b
--- /dev/null
@@ -0,0 +1,198 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+<tr valign=bottom>
+  <td width=10>&nbsp;</td>
+  <td>
+  
+  <table width=100%>
+  <tr>
+    <td>
+      <h4>
+      <%company%>
+      <br><%address%>
+      </h4>
+    </td>
+
+    <td align=right>
+      <h4>
+      Telelephone: <%tel%>
+      <br>Facsimile: <%fax%>
+      </h4>
+    </td>
+  </tr>
+
+  <tr>
+    <th colspan=3>
+      <h4>S A L E S &nbsp;&nbsp; O R D E R</h4>
+    </th>
+  </tr>
+
+  </table>
+
+
+  <table width=100% callspacing=0 cellpadding=0>
+    
+  <tr>
+    <td align=right>
+    <table>
+    <tr>
+      <th align=right>Order Date</th><td width=10>&nbsp;</td><td><%orddate%></td>
+    </tr>
+  
+    <tr>
+      <th align=right>Required by</th><td width=10>&nbsp;</td><td><%reqdate%></td>
+    </tr>
+
+    <tr>
+      <th align=right>Number</th><td>&nbsp;</td><td><%ordnumber%></td></tr>
+    </tr>
+  
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+    </td>
+    </table>
+  </tr>
+
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+      <th align=left><font color=ffffff>To:</th>
+    </tr>
+
+    <tr>
+      <td><%name%>
+      <br><%addr1%>
+      <br><%addr2%>
+      <br><%addr3%>
+      <br><%addr4%>
+<%if contact%>
+      <p>Attn: <%contact%>
+%end contact%>
+
+      </td>
+    </tr>
+    </table>
+    </td>
+  </tr>
+
+  <tr>
+    <td>&nbsp;</td>
+  </tr>
+  
+  <tr>
+    <td>
+    <table width=100%>
+    <tr bgcolor=000000>
+<!--      <th align=right><font color=ffffff>No.</th>  -->
+      <th align=left><font color=ffffff>Number</th>
+      <th align=left><font color=ffffff>Description</th>
+      <th><font color=ffffff>Qt'y</th>
+      <th>&nbsp;</th>
+      <th><font color=ffffff>Price</th>
+      <th><font color=ffffff>Amount</th>
+    </tr>
+
+<%foreach number%>
+    <tr valign=top>
+<!--      <td align=right><%runningnumber%>.</td>
+adjust the colspan if you include this to shift subtotal one to the right
+-->
+      <td><%number%></td>
+      <td><%description%></td>
+      <td align=right><%qty%></td>
+      <td><%unit%></td>
+      <td align=right><%sellprice%></td>
+      <td align=right><%linetotal%></td>
+    </tr>
+<%end number%>
+
+    <tr>
+      <td colspan=6><hr noshade></td>
+    </tr>
+    
+    <tr>
+      <th colspan=4 align=right>Subtotal</th>
+      <td colspan=2 align=right><%subtotal%></td>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th colspan=4 align=right><%taxdescription%> @ <%taxrate%> %</th>
+      <td colspan=2 align=right><%tax%></td>
+    </tr>
+<%end tax%>
+
+    <tr>
+      <td colspan=2>&nbsp;</td>
+      <td colspan=4><hr noshade></td>
+    </tr>
+
+    <tr>
+      <td colspan=2>Terms Net <b><%terms%></b> days</td>
+      <th colspan=2 align=right>Total</th>
+      <th colspan=2 align=right><%total%></th>
+    </tr>
+
+    <tr>
+      <td>&nbsp;</td>
+    </tr>
+
+    </table>
+    </td>
+  </tr>
+
+<tr>
+  <td>
+  <table width=100%>
+    <tr valign=top>
+<%if notes%>
+      <td>Notes</td>
+      <td><pre><%notes%></pre></td>
+<%end notes%>
+      <td align=right>
+      All prices in <b><%currency%></b> Funds
+      <br><%shippingpoint%>
+      </td>
+    </tr>
+
+  </table>
+  </td>
+</tr>
+
+<tr><td>&nbsp;</td></tr>
+  
+<tr>
+  <td>
+  <table width=100%>
+  <tr valign=top>
+    <td><font size=-3>
+    Payment due NET <%terms%> Days from date of Invoice.
+    Interest on overdue amounts will acrue at the rate of 1.5% per month
+    from due date until paid in full. Items returned are subject to
+    a 10% restocking charge. A return authorization must be obtained
+    from <%company%> before goods are returned. Returns must be shipped
+    prepaid and properly insured. <%company%> will not be responsible
+    for damages during transit.
+    </font>
+    </td>
+    <td width=150>
+    X <hr noshade>
+    </td>
+  </tr>
+  </table>
+  </td>
+</tr>
+
+</table>
+
+</td>
+</tr>
+</table>
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Service-sales_order.tex b/sql-ledger/templates/Service-sales_order.tex
new file mode 100644 (file)
index 0000000..c5664e0
--- /dev/null
@@ -0,0 +1,139 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+      
+      <%address%>}\hfill
+    \begin{tabular}[b]{rr@{}}
+    Telephone & <%tel%>\\
+    Facsimile & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+    
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%ordnumber%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+  
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%ordnumber%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}p{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Amount} \\
+  & carried forward from <%lastpage%> & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{2cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{3.5cm}
+
+\textbf{S A L E S} \parbox{0.3cm}{\hfill} \textbf{O R D E R}
+\hfill
+\begin{tabular}[t]{l@{\hspace{0.3cm}}l}
+  \textbf{Date} & <%orddate%> \\
+  \textbf{Number} & <%ordnumber%>
+\end{tabular}
+
+\vspace{1cm}
+
+\begin{tabular*}{\textwidth}{@{}p{\descrwidth}@{\extracolsep\fill}rlrr@{}}
+  \textbf{Description} & \textbf{Qt'y} &
+    \textbf{Unit} & \textbf{Price} & \textbf{Amount} \\
+<%foreach number%>
+  <%description%> & <%qty%> &
+    <%unit%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+
+\parbox{\textwidth}{
+\rule{\textwidth}{2pt}
+
+\vspace{0.2cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  <%taxdescription%> on <%taxbase%> & <%tax%>\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>}\\
+\end{tabularx}
+
+\vspace{0.3cm}
+
+\hfill
+  All prices in \textbf{<%currency%>} funds.
+
+\vspace{12pt}
+
+<%if notes%>
+  <%notes%>
+<%end if%>
+
+}
+
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+%\footnotetext[1]{\tiny }
+
+\end{document}
+
diff --git a/sql-ledger/templates/Service-statement.html b/sql-ledger/templates/Service-statement.html
new file mode 100644 (file)
index 0000000..6fca322
--- /dev/null
@@ -0,0 +1,121 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+  <tr>
+    <td width=10>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr>
+         <td>
+           <h4>
+           <%company%>
+           <br><%address%>
+           </h4>
+         </td>
+         <th><img src=http://www.sql-ledger.org/images/sql-ledger.png border=0 width=64 height=58></th>
+         <td align=right>
+         <h4>
+         Tel: <%tel%>
+         <br>Fax: <%fax%>
+         </h4>
+         </td>
+       </tr>
+       <tr>
+         <th colspan=3><h4>S T A T E M E N T</h4></th>
+       </tr>
+       <tr>
+         <td colspan=3 align=right><%statementdate%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr valign=top>
+         <td><%name%>
+         <br><%addr1%>
+         <br><%addr2%>
+         <br><%addr3%>
+         <br><%addr4%>
+         <br>
+<%if customerphone%>
+         <br>Tel: <%customerphone%>
+<%end customerphone%>
+<%if customerfax%>
+         <br>Fax: <%customerfax%>
+<%end customerfax%>
+<%if email%>
+         <br><%email%>
+<%end email%>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+        <tr>
+         <th align=left>Invoice #</th>
+         <th width=15%>Date</th>
+         <th width=15%>Due</th>
+         <th width=10%>Current</th>
+         <th width=10%>30</th>
+         <th width=10%>60</th>
+         <th width=10%>90+</th>
+       </tr>
+<%foreach invnumber%>
+       <tr>
+         <td><%invnumber%></td>
+         <td><%invdate%></td>
+         <td><%duedate%></td>
+         <td align=right><%c0%></td>
+         <td align=right><%c30%></td>
+         <td align=right><%c60%></td>
+         <td align=right><%c90%></td>
+       </tr>
+<%end invnumber%>
+        <tr>
+         <td colspan=7><hr size=1></td>
+       </tr>
+       <tr>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <th align=right><%c0total%></td>
+         <th align=right><%c30total%></td>
+         <th align=right><%c60total%></td>
+         <th align=right><%c90total%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td align=right>
+      <table width=50%>
+        <tr>
+         <th>Total Outstanding</th>
+          <th align=right><%total%></th>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td><hr noshade></td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>Please make check payable to <b><%company%></b>.
+    </td>
+  </tr>
+  <tr height=20></tr>
+</table>
+
diff --git a/sql-ledger/templates/Service-statement.tex b/sql-ledger/templates/Service-statement.tex
new file mode 100644 (file)
index 0000000..0b63f75
--- /dev/null
@@ -0,0 +1,137 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+
+      <%address%>}\hfill
+    \begin{tabular}[b]{rrr@{}}
+    Tel & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%statementdate%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%statementdate%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+  carried forward from <%lastpage%> & & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{1.5cm}
+
+\parbox[t]{1cm}{\hfill}
+\parbox[t]{10.5cm}{
+  
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+}
+\parbox[t]{7.5cm}{
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{S T A T E M E N T} \hfill
+
+\hfill <%statementdate%>
+
+\vspace{2cm}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+<%foreach invnumber%>
+  <%invnumber%> & <%invdate%> & <%duedate%> &
+  <%c0%> & <%c30%> & <%c60%> & <%c90%> \\
+<%end invnumber%>
+\textbf{Subtotal} & & & <%c0total%> & <%c30total%> & <%c60total%> & <%c90total%>
+\end{tabular*}
+\rule{\textwidth}{1pt}
+
+\vspace{1cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Total outstanding} & <%total%>
+\end{tabularx}
+
+\vfill
+
+Please make check payable to <%company%>
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_A4-balance_sheet.html b/sql-ledger/templates/Spanish_A4-balance_sheet.html
new file mode 100644 (file)
index 0000000..aef74d0
--- /dev/null
@@ -0,0 +1,100 @@
+<head>
+  <title>Hoja de Balance</title>
+</head>
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>HOJA DE BALANCE
+<br><%period%>
+</h2>
+
+<table border=0>
+<tr>
+  <th align=left width=400 colspan=2>ACTIVOS<br><hr align=left width=250 size=5 noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach asset_account%>
+<tr>
+  <td>&nbsp;</td>
+  <td><%asset_account%></td>
+  <td align=right><%asset_this_period%></td>
+  <td align=right><%asset_last_period%></td>
+</tr>
+<%end asset_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>Total de activos</th>
+  <td align=right><%total_assets_this_period%><hr noshade size=2></td>
+  <td align=right><%total_assets_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>PASIVOS<b><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach liability_account%>
+<tr>
+  <td></td>
+  <td><%liability_account%></td>
+  <td align=right><%liability_this_period%></td>
+  <td align=right><%liability_last_period%></td>
+</tr>
+<%end liability_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Total de pasivos</th>
+  <td align=right><%total_liabilities_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_liabilities_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>CAPITAL<br><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach equity_account%>
+<tr>
+  <td></td>
+  <td><%equity_account%></td>
+  <td align=right><%equity_this_period%></td>
+  <td align=right><%equity_last_period%></td>
+</tr>
+<%end equity_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Capital total</th>
+  <td align=right><%total_equity_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_equity_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>Total de pasivos y capital</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+</table>
diff --git a/sql-ledger/templates/Spanish_A4-check.tex b/sql-ledger/templates/Spanish_A4-check.tex
new file mode 100644 (file)
index 0000000..a1ef969
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[a4paper,oneside]{article}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_A4-income_statement.html b/sql-ledger/templates/Spanish_A4-income_statement.html
new file mode 100644 (file)
index 0000000..fbb5653
--- /dev/null
@@ -0,0 +1,77 @@
+<head>
+  <title>Balance de Situación</title>
+</head>
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>BALANCE DE SITUACIÓN
+<br><%period%>
+</h2>
+
+
+<table width=100% border=0>
+<tr>
+  <th width=400 align=left colspan=2>INGRESOS<br><hr width=300 size=5 align=left noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach income_account%>
+<tr>
+  <td width=4>&nbsp;</td>
+  <td><%income_account%></td>
+  <td align=right><%income_this_period%></td>
+  <td align=right><%income_last_period%></td>
+</tr>
+<%end income_account%>
+
+<tr>
+  <td colspan=2>&nbsp;</td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td>&nbsp;</td>
+  <th align=left>Total de ingresos</th>
+  <td align=right><%total_income_this_period%><hr noshade size=2></td>
+  <td align=right><%total_income_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=2>GASTOS<br><hr width=300 size=5 align=left noshade></th>
+</tr>
+
+<%foreach expense_account%>
+<tr>
+  <td>&nbsp;</td>
+  <td><%expense_account%></td>
+  <td align=right><%expenses_this_period%></td>
+  <td align=right><%expenses_last_period%></td>
+</tr>
+<%end expense_account%>
+
+<tr>
+  <td colspan=2>&nbsp;</td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td>&nbsp;</td>
+  <th align=left>Total de gastos</th>
+  <td align=right><%total_expenses_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_expenses_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>GANANCIA/(PERDIDA)</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+
+</table>
diff --git a/sql-ledger/templates/Spanish_A4-invoice.html b/sql-ledger/templates/Spanish_A4-invoice.html
new file mode 100644 (file)
index 0000000..d274936
--- /dev/null
@@ -0,0 +1,153 @@
+<head>
+  <title>Factura de Instalaciones Industriales San José</title>
+</head>
+
+<body bgcolor="ffffff">
+    <!-- Cabecera -->
+    <table width="100%">
+       <tr valign=bottom>
+         <td width="10">&nbsp;</td>
+         <td>  
+           <table width=100%>
+               <tr>
+                 <th colspan="4"> </th>
+                 <th align="left">
+                   <h4>F A C T U R A</h4>
+                 </th>
+               </tr>
+               
+               <tr>
+                 <td colspan="5"> </td>
+               </tr>
+               
+               <tr>
+                 <td colspan="4"> </td>
+                 <td align="left"><%name%></td>
+               </tr>
+               
+               <tr>
+                 <td>Número</td>
+                 <td>Fecha</td>
+                 <td>Cód. Cliente</td> 
+                 <td width="10%"> </td>
+                 <td><%addr1%></td>
+               </tr>
+               <tr>
+                 <td><b><%invnumber%></b></td>
+                 <td><b><%invdate%></b></td>
+                 <td><b><%customer_id%></b></td>
+                 <td> </td>
+                 <td><%addr2%></td>
+               </tr>
+               <tr>
+                 <td colspan="4">
+                 <td><%addr3%></td>
+               </tr>
+               <tr>
+                 <td colspan="4">
+                 <td><%addr4%></td>
+               </tr>
+           </table>
+    </table>       
+
+    <!-- Cuerpo -->
+    <table width=100% cellspacing=0 cellpadding=0>
+       <tr>
+         <td>
+           <table width=100%>
+               <tr bgcolor=000000>
+                 <!--      <th align=left><font color=ffffff>Número</th> -->
+                 <!--      <th><font color=ffffff>Cant.</th> -->
+                 <th align="left"><font color="ffffff">Cant.</th>
+                 <th align="left"><font color="ffffff">Descripción</th>
+                 <th align="left"><font color="ffffff">Precio</th>
+                 <!--  <th align="left"><font color="ffffff">Dto.</th> -->
+                 <th align="left"><font color="ffffff">Importe</th>
+               </tr>
+
+               <tr>
+                 <td colspan="4"><hr noshade></td>
+               </tr>    
+               
+<%foreach number%>
+       <tr valign=top>
+         <!--      <td><%number%></td> -->
+         <!--      <td><%unit%></td> -->
+         <td align="right"><%qty%></td> 
+         <td align="left"><%description%></td>
+         <td align="right"><%sellprice%></td>
+         <!--      <td align=right><%discount%></td> -->
+         <td align="right"><%linetotal%></td>
+       </tr>
+<%end number%>
+    
+    <tr>
+      <td colspan="4"><hr noshade></td>
+    </tr>    
+  </table>
+    
+    <!-- Subtotales, impuestos y totales -->
+    <table width="100%">
+    <tr>
+<%if taxincluded%>
+    <th align=right>Total</th>
+    <td align=right><%invtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+    <th align="right">Base imponible</th>
+    <td align="right"><%subtotal%> &euro;</td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th align="right">IVA (<%taxrate%>%) sobre <%taxbase%>:</th>
+      <td align="right"><%tax%> &euro;</td>
+    </tr>
+<%end tax%>
+    
+<%if paid%>
+    <tr>
+      <th align="right">Pagado:</th>
+      <td align="right"><%paid%> &euro;</td>
+    </tr>
+<%end paid%>
+    
+    <tr>
+      <td>&nbsp;</td>
+      <td><hr noshade></td>
+    </tr>
+
+    <tr>
+      <th align="right">Total:</th>
+      <th align="right"><%invtotal%> &euro;</th>
+    </tr>
+    
+    <tr>
+      <td colspan="4">&nbsp;</td>
+    </tr>
+    
+    </table>
+
+
+    <!-- Pie -->
+    <table width="100%">
+       <tr valign=top>
+<%if notes%>
+         <td>Notas</td>
+         <td><%notes%></td>
+<%end notes%>
+  </tr>
+    
+<%if taxincluded%>
+    <tr>
+      <th colspan="2" align="left"><font size=-2>Los precios incluyen impuestos.</th>
+    </tr>
+<%end taxincluded%>
+    
+  </table>
+
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Spanish_A4-invoice.tex b/sql-ledger/templates/Spanish_A4-invoice.tex
new file mode 100644 (file)
index 0000000..1d0619e
--- /dev/null
@@ -0,0 +1,108 @@
+\documentclass[a4paper,oneside]{article}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\usepackage{marvosym}  % Euro \EUR
+\usepackage{fancyhdr}
+\setlength{\topmargin}{0cm}
+\setlength{\topskip}{0cm}
+\setlength{\headheight}{0cm}
+\setlength{\headsep}{0.5cm}
+\setlength{\textheight}{24.2cm}
+\setlength{\textwidth}{19cm}
+\setlength{\oddsidemargin}{-1.4cm}
+\setlength{\evensidemargin}{-1.4cm}
+\setlength{\footskip}{1cm}
+
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{13.0cm}
+
+\newsavebox{\hdr}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\sbox{\hdr}{
+
+\begin{minipage}[t]{0.6\linewidth}
+\vspace{2.2cm}
+
+\begin{tabular}[t]{p{1.7cm}p{2.4cm}p{1.7cm}}\\
+\centering{Número} & \centering{Fecha} & C. Cliente\\
+\centering{<%invnumber%>} & \centering{<%invdate%>} & \centering{<%customer_id%>}
+\end{tabular}
+\end{minipage}
+
+\begin{minipage}[t]{0.4\linewidth}
+\textbf{F A C T U R A} 
+\vspace{1cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+\end{minipage}
+
+}
+
+\pagestyle{fancy}
+\renewcommand{\headrulewidth}{0cm}
+\renewcommand{\footrulewidth}{0cm}
+\cfoot{\thepage}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+%\thispagestyle{empty}     %use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+\newpage
+\usebox{\hdr}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%end pagebreak%>
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\usebox{\hdr}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%foreach number%>
+  <%qty%> & <%description%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+\parbox{\textwidth}{
+\vspace{12pt}
+<%if notes%>
+  <%notes%>
+<%end if%>
+}
+
+\vfill
+
+\begin{flushright}
+\begin{tabularx}{10cm}{Xr@{}}
+  \textbf{Base imponible} & \textbf{<%subtotal%>} \EUR \\
+<%foreach tax%>
+  IVA (<%taxrate%>\%) sobre <%taxbase%> & <%tax%> \EUR\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%invtotal%>} \EUR\\
+\end{tabularx}
+\end{flushright}
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_A4-packing_list.html b/sql-ledger/templates/Spanish_A4-packing_list.html
new file mode 100644 (file)
index 0000000..c34d189
--- /dev/null
@@ -0,0 +1,155 @@
+<head>
+  <title>Albarán de Instalaciones Industriales San José</title>
+</head>
+
+<body bgcolor="ffffff">
+    <!-- Cabecera -->
+    <table width="100%">
+       <tr valign=bottom>
+         <td width="10">&nbsp;</td>
+         <td>  
+           <table width=100%>
+               <tr>
+                 <th colspan="5"> </th>
+                 <th align="left">
+                   <h4>A L B A R Á N</h4>
+                 </th>
+               </tr>
+               
+               <tr>
+                 <td colspan="6"> </td>
+               </tr>
+               
+               <tr>
+                 <td colspan="5"> </td>
+                 <td align="left"><%name%></td>
+               </tr>
+               
+               <tr>
+                 <td>Número</td>
+                 <td>Factura</td>
+                 <td>Fecha</td>
+                 <td>Cód. Cliente</td> 
+                 <td width="10%"> </td>
+                 <td><%addr1%></td>
+               </tr>
+               <tr>
+                 <td><b><%ordnumber%></b></td>
+                 <td><b><%invnumber%></b></td>
+                 <td><b><%invdate%></b></td>
+                 <td><b><%customer_id%></b></td>
+                 <td> </td>
+                 <td><%addr2%></td>
+               </tr>
+               <tr>
+                 <td colspan="5">
+                 <td><%addr3%></td>
+               </tr>
+               <tr>
+                 <td colspan="5">
+                 <td><%addr4%></td>
+               </tr>
+           </table>
+    </table>       
+
+    <!-- Cuerpo -->
+    <table width=100% cellspacing=0 cellpadding=0>
+       <tr>
+         <td>
+           <table width=100%>
+               <tr bgcolor=000000>
+                 <!--      <th align=left><font color=ffffff>Número</th> -->
+                 <!--      <th><font color=ffffff>Cant.</th> -->
+                 <th align="left"><font color="ffffff">Cant.</th>
+                 <th align="left"><font color="ffffff">Descripción</th>
+                 <th align="left"><font color="ffffff">Precio</th>
+                 <!--  <th align="left"><font color="ffffff">Dto.</th> -->
+                 <th align="left"><font color="ffffff">Importe</th>
+               </tr>
+
+               <tr>
+                 <td colspan="4"><hr noshade></td>
+               </tr>    
+               
+<%foreach number%>
+       <tr valign=top>
+         <!--      <td><%number%></td> -->
+         <!--      <td><%unit%></td> -->
+         <td align="right"><%qty%></td> 
+         <td align="left"><%description%></td>
+         <td align="right"><%sellprice%></td>
+         <!--      <td align=right><%discount%></td> -->
+         <td align="right"><%linetotal%></td>
+       </tr>
+<%end number%>
+    
+    <tr>
+      <td colspan="4"><hr noshade></td>
+    </tr>    
+  </table>
+    
+    <!-- Subtotales, impuestos y totales -->
+    <table width="100%">
+    <tr>
+<%if taxincluded%>
+    <th align=right>Total</th>
+    <td align=right><%invtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+    <th align="right">Base imponible</th>
+    <td align="right"><%subtotal%> &euro;</td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th align="right">IVA (<%taxrate%>%) sobre <%taxbase%>:</th>
+      <td align="right"><%tax%> &euro;</td>
+    </tr>
+<%end tax%>
+    
+<%if paid%>
+    <tr>
+      <th align="right">Pagado:</th>
+      <td align="right"><%paid%> &euro;</td>
+    </tr>
+<%end paid%>
+    
+    <tr>
+      <td>&nbsp;</td>
+      <td><hr noshade></td>
+    </tr>
+
+    <tr>
+      <th align="right">Total:</th>
+      <th align="right"><%invtotal%> &euro;</th>
+    </tr>
+    
+    <tr>
+      <td colspan="4">&nbsp;</td>
+    </tr>
+    
+    </table>
+
+
+    <!-- Pie -->
+    <table width="100%">
+       <tr valign=top>
+<%if notes%>
+         <td>Notas</td>
+         <td><%notes%></td>
+<%end notes%>
+  </tr>
+    
+<%if taxincluded%>
+    <tr>
+      <th colspan="2" align="left"><font size=-2>Los precios incluyen impuestos.</th>
+    </tr>
+<%end taxincluded%>
+    
+  </table>
+
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Spanish_A4-packing_list.tex b/sql-ledger/templates/Spanish_A4-packing_list.tex
new file mode 100644 (file)
index 0000000..312c349
--- /dev/null
@@ -0,0 +1,108 @@
+\documentclass[a4paper,oneside]{article}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\usepackage{marvosym}  % Euro \EUR
+\usepackage{fancyhdr}
+\setlength{\topmargin}{0cm}
+\setlength{\topskip}{0cm}
+\setlength{\headheight}{0cm}
+\setlength{\headsep}{0.5cm}
+\setlength{\textheight}{24.2cm}
+\setlength{\textwidth}{19cm}
+\setlength{\oddsidemargin}{-1.4cm}
+\setlength{\evensidemargin}{-1.4cm}
+\setlength{\footskip}{1cm}
+
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{13.0cm}
+
+\newsavebox{\hdr}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\sbox{\hdr}{
+
+\begin{minipage}[t]{0.6\linewidth}
+\vspace{2.2cm}
+
+\begin{tabular}[t]{p{1.7cm}p{1.7cm}p{2.4cm}p{1.7cm}}\\
+\centering{Número} & \centering{Número} & \centering{Fecha} & C. Cliente\\
+  \centering{<%ordnumber%>} & \centering{<%invnumber%>} & \centering{<%invdate%>} & \centering{<%customer_id%>}
+\end{tabular}
+\end{minipage}
+
+\begin{minipage}[t]{0.4\linewidth}
+\textbf{A L B A R Á N} 
+\vspace{1cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+\end{minipage}
+
+}
+
+\pagestyle{fancy}
+\renewcommand{\headrulewidth}{0cm}
+\renewcommand{\footrulewidth}{0cm}
+\cfoot{\thepage}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+%\thispagestyle{empty}     %use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+\newpage
+\usebox{\hdr}
+\vspace{0.5cm}
+
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%end pagebreak%>
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\usebox{\hdr}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%foreach number%>
+  <%qty%> & <%description%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+\parbox{\textwidth}{
+\vspace{12pt}
+<%if notes%>
+  <%notes%>
+<%end if%>
+}
+
+\vfill
+
+\begin{flushright}
+\begin{tabularx}{10cm}{Xr@{}}
+  \textbf{Base imponible} & \textbf{<%subtotal%>} \EUR \\
+<%foreach tax%>
+  IVA (<%taxrate%>\%) sobre <%taxbase%> & <%tax%> \EUR\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%invtotal%>} \EUR\\
+\end{tabularx}
+\end{flushright}
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_A4-purchase_order.html b/sql-ledger/templates/Spanish_A4-purchase_order.html
new file mode 100644 (file)
index 0000000..693fe65
--- /dev/null
@@ -0,0 +1,153 @@
+<head>
+  <title>Pedido de Instalaciones Industriales San José</title>
+</head>
+
+<body bgcolor="ffffff">
+    <!-- Cabecera -->
+    <table width="100%">
+       <tr valign=bottom>
+         <td width="10">&nbsp;</td>
+         <td>  
+           <table width=100%>
+               <tr>
+                 <th colspan="4"> </th>
+                 <th align="left">
+                   <h4>P E D I D O</h4>
+                 </th>
+               </tr>
+               
+               <tr>
+                 <td colspan="5"> </td>
+               </tr>
+               
+               <tr>
+                 <td colspan="4"> </td>
+                 <td align="left"><%name%></td>
+               </tr>
+               
+               <tr>
+                 <td>Número</td>
+                 <td>Fecha</td>
+                 <td>Cód. Proveedor</td> 
+                 <td width="10%"> </td>
+                 <td><%addr1%></td>
+               </tr>
+               <tr>
+                 <td><b><%ordnumber%></b></td>
+                 <td><b><%orddate%></b></td>
+                 <td><b><%vendor_id%></b></td>
+                 <td> </td>
+                 <td><%addr2%></td>
+               </tr>
+               <tr>
+                 <td colspan="4">
+                 <td><%addr3%></td>
+               </tr>
+               <tr>
+                 <td colspan="4">
+                 <td><%addr4%></td>
+               </tr>
+           </table>
+    </table>       
+
+    <!-- Cuerpo -->
+    <table width=100% cellspacing=0 cellpadding=0>
+       <tr>
+         <td>
+           <table width=100%>
+               <tr bgcolor=000000>
+                 <!--      <th align=left><font color=ffffff>Número</th> -->
+                 <!--      <th><font color=ffffff>Cant.</th> -->
+                 <th align="left"><font color="ffffff">Cant.</th>
+                 <th align="left"><font color="ffffff">Descripción</th>
+                 <th align="left"><font color="ffffff">Precio</th>
+                 <!--  <th align="left"><font color="ffffff">Dto.</th> -->
+                 <th align="left"><font color="ffffff">Importe</th>
+               </tr>
+
+               <tr>
+                 <td colspan="4"><hr noshade></td>
+               </tr>    
+               
+<%foreach number%>
+       <tr valign=top>
+         <!--      <td><%number%></td> -->
+         <!--      <td><%unit%></td> -->
+         <td align="right"><%qty%></td> 
+         <td align="left"><%description%></td>
+         <td align="right"><%sellprice%></td>
+         <!--      <td align=right><%discount%></td> -->
+         <td align="right"><%linetotal%></td>
+       </tr>
+<%end number%>
+    
+    <tr>
+      <td colspan="4"><hr noshade></td>
+    </tr>    
+  </table>
+    
+    <!-- Subtotales, impuestos y totales -->
+    <table width="100%">
+    <tr>
+<%if taxincluded%>
+    <th align="right">Total</th>
+    <td align="right"><%ordtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+    <th align="right">Base imponible</th>
+    <td align="right"><%subtotal%> &euro;</td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th align="right">IVA (<%taxrate%>%) sobre <%taxbase%>:</th>
+      <td align="right"><%tax%> &euro;</td>
+    </tr>
+<%end tax%>
+    
+<%if paid%>
+    <tr>
+      <th align="right">Pagado:</th>
+      <td align="right"><%paid%> &euro;</td>
+    </tr>
+<%end paid%>
+    
+    <tr>
+      <td>&nbsp;</td>
+      <td><hr noshade></td>
+    </tr>
+
+    <tr>
+      <th align="right">Total:</th>
+      <th align="right"><%ordtotal%> &euro;</th>
+    </tr>
+    
+    <tr>
+      <td colspan="4">&nbsp;</td>
+    </tr>
+    
+    </table>
+
+
+    <!-- Pie -->
+    <table width="100%">
+       <tr valign=top>
+<%if notes%>
+         <td>Notas</td>
+         <td><%notes%></td>
+<%end notes%>
+  </tr>
+    
+<%if taxincluded%>
+    <tr>
+      <th colspan="2" align="left"><font size=-2>Los precios incluyen impuestos.</th>
+    </tr>
+<%end taxincluded%>
+    
+  </table>
+
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Spanish_A4-purchase_order.tex b/sql-ledger/templates/Spanish_A4-purchase_order.tex
new file mode 100644 (file)
index 0000000..f8300ae
--- /dev/null
@@ -0,0 +1,107 @@
+\documentclass[a4paper,oneside]{article}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\usepackage{marvosym}  % Euro \EUR
+\usepackage{fancyhdr}
+\setlength{\topmargin}{0cm}
+\setlength{\topskip}{0cm}
+\setlength{\headheight}{0cm}
+\setlength{\headsep}{0.5cm}
+\setlength{\textheight}{24.2cm}
+\setlength{\textwidth}{19cm}
+\setlength{\oddsidemargin}{-1.4cm}
+\setlength{\evensidemargin}{-1.4cm}
+\setlength{\footskip}{1cm}
+
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{13.0cm}
+
+\newsavebox{\hdr}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\sbox{\hdr}{
+\begin{minipage}[t]{0.6\linewidth}
+\vspace{2.2cm}
+
+\begin{tabular}[t]{p{1.7cm}p{2.4cm}p{1.7cm}}\\
+\centering{Número} & \centering{Fecha} & C. Cliente\\
+\centering{<%ordnumber%>} & \centering{<%orddate%>} & \centering{<%vendor_id%>}
+\end{tabular}
+\end{minipage}
+
+\begin{minipage}[t]{0.4\linewidth}
+\textbf{P E D I D O} 
+\vspace{1cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+\end{minipage}
+
+}
+
+\pagestyle{fancy}
+\renewcommand{\headrulewidth}{0cm}
+\renewcommand{\footrulewidth}{0cm}
+\cfoot{\thepage}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+%\thispagestyle{empty}     %use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+\newpage
+\usebox{\hdr}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%end pagebreak%>
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\usebox{\hdr}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%foreach number%>
+  <%qty%> & <%description%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+\parbox{\textwidth}{
+\vspace{12pt}
+<%if notes%>
+  <%notes%>
+<%end if%>
+}
+
+\vfill
+
+\begin{flushright}
+\begin{tabularx}{10cm}{Xr@{}}
+  \textbf{Base imponible} & \textbf{<%subtotal%>} \EUR \\
+<%foreach tax%>
+  IVA (<%taxrate%>\%) sobre <%taxbase%> & <%tax%> \EUR\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>} \EUR\\
+\end{tabularx}
+\end{flushright}
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_A4-receipt.tex b/sql-ledger/templates/Spanish_A4-receipt.tex
new file mode 100644 (file)
index 0000000..a1ef969
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[a4paper,oneside]{article}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_A4-sales_order.html b/sql-ledger/templates/Spanish_A4-sales_order.html
new file mode 100644 (file)
index 0000000..d54f375
--- /dev/null
@@ -0,0 +1,153 @@
+<head>
+  <title>Presupuesto de Instalaciones Industriales San José</title>
+</head>
+
+<body bgcolor="ffffff">
+    <!-- Cabecera -->
+    <table width="100%">
+       <tr valign=bottom>
+         <td width="10">&nbsp;</td>
+         <td>  
+           <table width=100%>
+               <tr>
+                 <th colspan="4"> </th>
+                 <th align="left">
+                   <h4>P R E S U P U E S T O</h4>
+                 </th>
+               </tr>
+               
+               <tr>
+                 <td colspan="5"> </td>
+               </tr>
+               
+               <tr>
+                 <td colspan="4"> </td>
+                 <td align="left"><%name%></td>
+               </tr>
+               
+               <tr>
+                 <td>Número</td>
+                 <td>Fecha</td>
+                 <td>Cód. Cliente</td> 
+                 <td width="10%"> </td>
+                 <td><%addr1%></td>
+               </tr>
+               <tr>
+                 <td><b><%ordnumber%></b></td>
+                 <td><b><%orddate%></b></td>
+                 <td><b><%customer_id%></b></td>
+                 <td> </td>
+                 <td><%addr2%></td>
+               </tr>
+               <tr>
+                 <td colspan="4">
+                 <td><%addr3%></td>
+               </tr>
+               <tr>
+                 <td colspan="4">
+                 <td><%addr4%></td>
+               </tr>
+           </table>
+    </table>       
+
+    <!-- Cuerpo -->
+    <table width=100% cellspacing=0 cellpadding=0>
+       <tr>
+         <td>
+           <table width=100%>
+               <tr bgcolor=000000>
+                 <!--      <th align=left><font color=ffffff>Número</th> -->
+                 <!--      <th><font color=ffffff>Cant.</th> -->
+                 <th align="left"><font color="ffffff">Cant.</th>
+                 <th align="left"><font color="ffffff">Descripción</th>
+                 <th align="left"><font color="ffffff">Precio</th>
+                 <!--  <th align="left"><font color="ffffff">Dto.</th> -->
+                 <th align="left"><font color="ffffff">Importe</th>
+               </tr>
+
+               <tr>
+                 <td colspan="4"><hr noshade></td>
+               </tr>    
+               
+<%foreach number%>
+       <tr valign=top>
+         <!--      <td><%number%></td> -->
+         <!--      <td><%unit%></td> -->
+         <td align="right"><%qty%></td> 
+         <td align="left"><%description%></td>
+         <td align="right"><%sellprice%></td>
+         <!--      <td align=right><%discount%></td> -->
+         <td align="right"><%linetotal%></td>
+       </tr>
+<%end number%>
+    
+    <tr>
+      <td colspan="4"><hr noshade></td>
+    </tr>    
+  </table>
+    
+    <!-- Subtotales, impuestos y totales -->
+    <table width="100%">
+    <tr>
+<%if taxincluded%>
+    <th align=right>Total</th>
+    <td align=right><%ordtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+    <th align="right">Base imponible</th>
+    <td align="right"><%subtotal%> &euro;</td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th align="right">IVA (<%taxrate%>%) sobre <%taxbase%>:</th>
+      <td align="right"><%tax%> &euro;</td>
+    </tr>
+<%end tax%>
+    
+<%if paid%>
+    <tr>
+      <th align="right">Pagado:</th>
+      <td align="right"><%paid%> &euro;</td>
+    </tr>
+<%end paid%>
+    
+    <tr>
+      <td>&nbsp;</td>
+      <td><hr noshade></td>
+    </tr>
+
+    <tr>
+      <th align="right">Total:</th>
+      <th align="right"><%ordtotal%> &euro;</th>
+    </tr>
+    
+    <tr>
+      <td colspan="4">&nbsp;</td>
+    </tr>
+    
+    </table>
+
+
+    <!-- Pie -->
+    <table width="100%">
+       <tr valign=top>
+<%if notes%>
+         <td>Notas</td>
+         <td><%notes%></td>
+<%end notes%>
+  </tr>
+    
+<%if taxincluded%>
+    <tr>
+      <th colspan="2" align="left"><font size=-2>Los precios incluyen impuestos.</th>
+    </tr>
+<%end taxincluded%>
+    
+  </table>
+
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Spanish_A4-sales_order.tex b/sql-ledger/templates/Spanish_A4-sales_order.tex
new file mode 100644 (file)
index 0000000..f8300ae
--- /dev/null
@@ -0,0 +1,107 @@
+\documentclass[a4paper,oneside]{article}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\usepackage{marvosym}  % Euro \EUR
+\usepackage{fancyhdr}
+\setlength{\topmargin}{0cm}
+\setlength{\topskip}{0cm}
+\setlength{\headheight}{0cm}
+\setlength{\headsep}{0.5cm}
+\setlength{\textheight}{24.2cm}
+\setlength{\textwidth}{19cm}
+\setlength{\oddsidemargin}{-1.4cm}
+\setlength{\evensidemargin}{-1.4cm}
+\setlength{\footskip}{1cm}
+
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{13.0cm}
+
+\newsavebox{\hdr}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\sbox{\hdr}{
+\begin{minipage}[t]{0.6\linewidth}
+\vspace{2.2cm}
+
+\begin{tabular}[t]{p{1.7cm}p{2.4cm}p{1.7cm}}\\
+\centering{Número} & \centering{Fecha} & C. Cliente\\
+\centering{<%ordnumber%>} & \centering{<%orddate%>} & \centering{<%vendor_id%>}
+\end{tabular}
+\end{minipage}
+
+\begin{minipage}[t]{0.4\linewidth}
+\textbf{P E D I D O} 
+\vspace{1cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+\end{minipage}
+
+}
+
+\pagestyle{fancy}
+\renewcommand{\headrulewidth}{0cm}
+\renewcommand{\footrulewidth}{0cm}
+\cfoot{\thepage}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+%\thispagestyle{empty}     %use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+\newpage
+\usebox{\hdr}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%end pagebreak%>
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\usebox{\hdr}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%foreach number%>
+  <%qty%> & <%description%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+\parbox{\textwidth}{
+\vspace{12pt}
+<%if notes%>
+  <%notes%>
+<%end if%>
+}
+
+\vfill
+
+\begin{flushright}
+\begin{tabularx}{10cm}{Xr@{}}
+  \textbf{Base imponible} & \textbf{<%subtotal%>} \EUR \\
+<%foreach tax%>
+  IVA (<%taxrate%>\%) sobre <%taxbase%> & <%tax%> \EUR\\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>} \EUR\\
+\end{tabularx}
+\end{flushright}
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_A4-statement.html b/sql-ledger/templates/Spanish_A4-statement.html
new file mode 100644 (file)
index 0000000..6fca322
--- /dev/null
@@ -0,0 +1,121 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+  <tr>
+    <td width=10>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr>
+         <td>
+           <h4>
+           <%company%>
+           <br><%address%>
+           </h4>
+         </td>
+         <th><img src=http://www.sql-ledger.org/images/sql-ledger.png border=0 width=64 height=58></th>
+         <td align=right>
+         <h4>
+         Tel: <%tel%>
+         <br>Fax: <%fax%>
+         </h4>
+         </td>
+       </tr>
+       <tr>
+         <th colspan=3><h4>S T A T E M E N T</h4></th>
+       </tr>
+       <tr>
+         <td colspan=3 align=right><%statementdate%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr valign=top>
+         <td><%name%>
+         <br><%addr1%>
+         <br><%addr2%>
+         <br><%addr3%>
+         <br><%addr4%>
+         <br>
+<%if customerphone%>
+         <br>Tel: <%customerphone%>
+<%end customerphone%>
+<%if customerfax%>
+         <br>Fax: <%customerfax%>
+<%end customerfax%>
+<%if email%>
+         <br><%email%>
+<%end email%>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+        <tr>
+         <th align=left>Invoice #</th>
+         <th width=15%>Date</th>
+         <th width=15%>Due</th>
+         <th width=10%>Current</th>
+         <th width=10%>30</th>
+         <th width=10%>60</th>
+         <th width=10%>90+</th>
+       </tr>
+<%foreach invnumber%>
+       <tr>
+         <td><%invnumber%></td>
+         <td><%invdate%></td>
+         <td><%duedate%></td>
+         <td align=right><%c0%></td>
+         <td align=right><%c30%></td>
+         <td align=right><%c60%></td>
+         <td align=right><%c90%></td>
+       </tr>
+<%end invnumber%>
+        <tr>
+         <td colspan=7><hr size=1></td>
+       </tr>
+       <tr>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <th align=right><%c0total%></td>
+         <th align=right><%c30total%></td>
+         <th align=right><%c60total%></td>
+         <th align=right><%c90total%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td align=right>
+      <table width=50%>
+        <tr>
+         <th>Total Outstanding</th>
+          <th align=right><%total%></th>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td><hr noshade></td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>Please make check payable to <b><%company%></b>.
+    </td>
+  </tr>
+  <tr height=20></tr>
+</table>
+
diff --git a/sql-ledger/templates/Spanish_A4-statement.tex b/sql-ledger/templates/Spanish_A4-statement.tex
new file mode 100644 (file)
index 0000000..268bb1a
--- /dev/null
@@ -0,0 +1,137 @@
+\documentclass[a4paper,oneside]{article}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+
+      <%address%>}\hfill
+    \begin{tabular}[b]{rrr@{}}
+    Tel & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%statementdate%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%statementdate%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+  carried forward from <%lastpage%> & & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{1.5cm}
+
+\parbox[t]{1cm}{\hfill}
+\parbox[t]{10.5cm}{
+  
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+}
+\parbox[t]{7.5cm}{
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{S T A T E M E N T} \hfill
+
+\hfill <%statementdate%>
+
+\vspace{2cm}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+<%foreach invnumber%>
+  <%invnumber%> & <%invdate%> & <%duedate%> &
+  <%c0%> & <%c30%> & <%c60%> & <%c90%> \\
+<%end invnumber%>
+\textbf{Subtotal} & & & <%c0total%> & <%c30total%> & <%c60total%> & <%c90total%>
+\end{tabular*}
+\rule{\textwidth}{1pt}
+
+\vspace{1cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Total outstanding} & <%total%>
+\end{tabularx}
+
+\vfill
+
+Please make check payable to <%company%>
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_Letter-balance_sheet.html b/sql-ledger/templates/Spanish_Letter-balance_sheet.html
new file mode 100644 (file)
index 0000000..aef74d0
--- /dev/null
@@ -0,0 +1,100 @@
+<head>
+  <title>Hoja de Balance</title>
+</head>
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>HOJA DE BALANCE
+<br><%period%>
+</h2>
+
+<table border=0>
+<tr>
+  <th align=left width=400 colspan=2>ACTIVOS<br><hr align=left width=250 size=5 noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach asset_account%>
+<tr>
+  <td>&nbsp;</td>
+  <td><%asset_account%></td>
+  <td align=right><%asset_this_period%></td>
+  <td align=right><%asset_last_period%></td>
+</tr>
+<%end asset_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>Total de activos</th>
+  <td align=right><%total_assets_this_period%><hr noshade size=2></td>
+  <td align=right><%total_assets_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>PASIVOS<b><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach liability_account%>
+<tr>
+  <td></td>
+  <td><%liability_account%></td>
+  <td align=right><%liability_this_period%></td>
+  <td align=right><%liability_last_period%></td>
+</tr>
+<%end liability_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Total de pasivos</th>
+  <td align=right><%total_liabilities_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_liabilities_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr>
+  <th align=left colspan=4>CAPITAL<br><hr align=left width=250 size=5 noshade></th>
+</tr>
+
+<%foreach equity_account%>
+<tr>
+  <td></td>
+  <td><%equity_account%></td>
+  <td align=right><%equity_this_period%></td>
+  <td align=right><%equity_last_period%></td>
+</tr>
+<%end equity_account%>
+
+<tr>
+  <td colspan=2> </td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td></td>
+  <th align=left>Capital total</th>
+  <td align=right><%total_equity_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_equity_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>Total de pasivos y capital</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+</table>
diff --git a/sql-ledger/templates/Spanish_Letter-check.tex b/sql-ledger/templates/Spanish_Letter-check.tex
new file mode 100644 (file)
index 0000000..5b64e81
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_Letter-income_statement.html b/sql-ledger/templates/Spanish_Letter-income_statement.html
new file mode 100644 (file)
index 0000000..fbb5653
--- /dev/null
@@ -0,0 +1,77 @@
+<head>
+  <title>Balance de Situación</title>
+</head>
+
+<body bgcolor=ffffff>
+
+<h2 align=center>
+<%company%>
+<br><%address%>
+
+<p>BALANCE DE SITUACIÓN
+<br><%period%>
+</h2>
+
+
+<table width=100% border=0>
+<tr>
+  <th width=400 align=left colspan=2>INGRESOS<br><hr width=300 size=5 align=left noshade></th>
+  <th><%this_period%></th>
+  <th><%last_period%></th>
+</tr>
+
+<%foreach income_account%>
+<tr>
+  <td width=4>&nbsp;</td>
+  <td><%income_account%></td>
+  <td align=right><%income_this_period%></td>
+  <td align=right><%income_last_period%></td>
+</tr>
+<%end income_account%>
+
+<tr>
+  <td colspan=2>&nbsp;</td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td>&nbsp;</td>
+  <th align=left>Total de ingresos</th>
+  <td align=right><%total_income_this_period%><hr noshade size=2></td>
+  <td align=right><%total_income_last_period%><hr noshade size=2></td>
+</tr>
+
+<tr>
+  <th align=left colspan=2>GASTOS<br><hr width=300 size=5 align=left noshade></th>
+</tr>
+
+<%foreach expense_account%>
+<tr>
+  <td>&nbsp;</td>
+  <td><%expense_account%></td>
+  <td align=right><%expenses_this_period%></td>
+  <td align=right><%expenses_last_period%></td>
+</tr>
+<%end expense_account%>
+
+<tr>
+  <td colspan=2>&nbsp;</td>
+  <td><hr noshade size=1></td>
+  <td><hr noshade size=1></td>
+</tr>
+
+<tr valign=top>
+  <td>&nbsp;</td>
+  <th align=left>Total de gastos</th>
+  <td align=right><%total_expenses_this_period%><br><hr noshade size=2</td>
+  <td align=right><%total_expenses_last_period%><br><hr noshade size=2</td>
+</tr>
+
+<tr valign=top>
+  <th align=left colspan=2>GANANCIA/(PERDIDA)</th>
+  <td align=right><%total_this_period%><br><hr noshade size=2></td>
+  <td align=right><%total_last_period%><br><hr noshade size=2></td>
+</tr>
+
+</table>
diff --git a/sql-ledger/templates/Spanish_Letter-invoice.html b/sql-ledger/templates/Spanish_Letter-invoice.html
new file mode 100644 (file)
index 0000000..d274936
--- /dev/null
@@ -0,0 +1,153 @@
+<head>
+  <title>Factura de Instalaciones Industriales San José</title>
+</head>
+
+<body bgcolor="ffffff">
+    <!-- Cabecera -->
+    <table width="100%">
+       <tr valign=bottom>
+         <td width="10">&nbsp;</td>
+         <td>  
+           <table width=100%>
+               <tr>
+                 <th colspan="4"> </th>
+                 <th align="left">
+                   <h4>F A C T U R A</h4>
+                 </th>
+               </tr>
+               
+               <tr>
+                 <td colspan="5"> </td>
+               </tr>
+               
+               <tr>
+                 <td colspan="4"> </td>
+                 <td align="left"><%name%></td>
+               </tr>
+               
+               <tr>
+                 <td>Número</td>
+                 <td>Fecha</td>
+                 <td>Cód. Cliente</td> 
+                 <td width="10%"> </td>
+                 <td><%addr1%></td>
+               </tr>
+               <tr>
+                 <td><b><%invnumber%></b></td>
+                 <td><b><%invdate%></b></td>
+                 <td><b><%customer_id%></b></td>
+                 <td> </td>
+                 <td><%addr2%></td>
+               </tr>
+               <tr>
+                 <td colspan="4">
+                 <td><%addr3%></td>
+               </tr>
+               <tr>
+                 <td colspan="4">
+                 <td><%addr4%></td>
+               </tr>
+           </table>
+    </table>       
+
+    <!-- Cuerpo -->
+    <table width=100% cellspacing=0 cellpadding=0>
+       <tr>
+         <td>
+           <table width=100%>
+               <tr bgcolor=000000>
+                 <!--      <th align=left><font color=ffffff>Número</th> -->
+                 <!--      <th><font color=ffffff>Cant.</th> -->
+                 <th align="left"><font color="ffffff">Cant.</th>
+                 <th align="left"><font color="ffffff">Descripción</th>
+                 <th align="left"><font color="ffffff">Precio</th>
+                 <!--  <th align="left"><font color="ffffff">Dto.</th> -->
+                 <th align="left"><font color="ffffff">Importe</th>
+               </tr>
+
+               <tr>
+                 <td colspan="4"><hr noshade></td>
+               </tr>    
+               
+<%foreach number%>
+       <tr valign=top>
+         <!--      <td><%number%></td> -->
+         <!--      <td><%unit%></td> -->
+         <td align="right"><%qty%></td> 
+         <td align="left"><%description%></td>
+         <td align="right"><%sellprice%></td>
+         <!--      <td align=right><%discount%></td> -->
+         <td align="right"><%linetotal%></td>
+       </tr>
+<%end number%>
+    
+    <tr>
+      <td colspan="4"><hr noshade></td>
+    </tr>    
+  </table>
+    
+    <!-- Subtotales, impuestos y totales -->
+    <table width="100%">
+    <tr>
+<%if taxincluded%>
+    <th align=right>Total</th>
+    <td align=right><%invtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+    <th align="right">Base imponible</th>
+    <td align="right"><%subtotal%> &euro;</td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th align="right">IVA (<%taxrate%>%) sobre <%taxbase%>:</th>
+      <td align="right"><%tax%> &euro;</td>
+    </tr>
+<%end tax%>
+    
+<%if paid%>
+    <tr>
+      <th align="right">Pagado:</th>
+      <td align="right"><%paid%> &euro;</td>
+    </tr>
+<%end paid%>
+    
+    <tr>
+      <td>&nbsp;</td>
+      <td><hr noshade></td>
+    </tr>
+
+    <tr>
+      <th align="right">Total:</th>
+      <th align="right"><%invtotal%> &euro;</th>
+    </tr>
+    
+    <tr>
+      <td colspan="4">&nbsp;</td>
+    </tr>
+    
+    </table>
+
+
+    <!-- Pie -->
+    <table width="100%">
+       <tr valign=top>
+<%if notes%>
+         <td>Notas</td>
+         <td><%notes%></td>
+<%end notes%>
+  </tr>
+    
+<%if taxincluded%>
+    <tr>
+      <th colspan="2" align="left"><font size=-2>Los precios incluyen impuestos.</th>
+    </tr>
+<%end taxincluded%>
+    
+  </table>
+
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Spanish_Letter-invoice.tex b/sql-ledger/templates/Spanish_Letter-invoice.tex
new file mode 100644 (file)
index 0000000..8fdd38a
--- /dev/null
@@ -0,0 +1,110 @@
+% ve-invoice.tex
+\documentclass[letterpaper,oneside]{article}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+%\usepackage{marvosym}  % Euro \EUR
+\usepackage{fancyhdr}
+\setlength{\topmargin}{0cm}
+\setlength{\topskip}{0cm}
+\setlength{\headheight}{0cm}
+\setlength{\headsep}{0.5cm}
+\setlength{\textheight}{24.2cm}
+\setlength{\textwidth}{19cm}
+\setlength{\oddsidemargin}{-1.4cm}
+\setlength{\evensidemargin}{-1.4cm}
+\setlength{\footskip}{1cm}
+
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{13.0cm}
+
+\newsavebox{\hdr}
+
+%Or whatever font you want!
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\sbox{\hdr}{
+
+\begin{minipage}[t]{0.6\linewidth}
+\vspace{2.2cm}
+
+\begin{tabular}[t]{p{1.7cm}p{2.4cm}p{1.7cm}}\\
+\centering{Número} & \centering{Fecha} & C. Cliente\\
+\centering{<%invnumber%>} & \centering{<%invdate%>} & \centering{<%customer_id%>}
+\end{tabular}
+\end{minipage}
+
+\begin{minipage}[t]{0.4\linewidth}
+\textbf{F A C T U R A} 
+\vspace{1cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+\end{minipage}
+
+}
+
+\pagestyle{fancy}
+\renewcommand{\headrulewidth}{0cm}
+\renewcommand{\footrulewidth}{0cm}
+\cfoot{\thepage}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+%\thispagestyle{empty}     %use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+\newpage
+\usebox{\hdr}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%end pagebreak%>
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\usebox{\hdr}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%foreach number%>
+  <%qty%> & <%description%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+\parbox{\textwidth}{
+\vspace{12pt}
+<%if notes%>
+  <%notes%>
+<%end if%>
+}
+
+\vfill
+
+\begin{flushright}
+\begin{tabularx}{10cm}{Xr@{}}
+  \textbf{Base imponible} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  IVA (<%taxrate%>\%) sobre <%taxbase%> & <%tax%> \\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%invtotal%>} \\
+\end{tabularx}
+\end{flushright}
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_Letter-packing_list.html b/sql-ledger/templates/Spanish_Letter-packing_list.html
new file mode 100644 (file)
index 0000000..c34d189
--- /dev/null
@@ -0,0 +1,155 @@
+<head>
+  <title>Albarán de Instalaciones Industriales San José</title>
+</head>
+
+<body bgcolor="ffffff">
+    <!-- Cabecera -->
+    <table width="100%">
+       <tr valign=bottom>
+         <td width="10">&nbsp;</td>
+         <td>  
+           <table width=100%>
+               <tr>
+                 <th colspan="5"> </th>
+                 <th align="left">
+                   <h4>A L B A R Á N</h4>
+                 </th>
+               </tr>
+               
+               <tr>
+                 <td colspan="6"> </td>
+               </tr>
+               
+               <tr>
+                 <td colspan="5"> </td>
+                 <td align="left"><%name%></td>
+               </tr>
+               
+               <tr>
+                 <td>Número</td>
+                 <td>Factura</td>
+                 <td>Fecha</td>
+                 <td>Cód. Cliente</td> 
+                 <td width="10%"> </td>
+                 <td><%addr1%></td>
+               </tr>
+               <tr>
+                 <td><b><%ordnumber%></b></td>
+                 <td><b><%invnumber%></b></td>
+                 <td><b><%invdate%></b></td>
+                 <td><b><%customer_id%></b></td>
+                 <td> </td>
+                 <td><%addr2%></td>
+               </tr>
+               <tr>
+                 <td colspan="5">
+                 <td><%addr3%></td>
+               </tr>
+               <tr>
+                 <td colspan="5">
+                 <td><%addr4%></td>
+               </tr>
+           </table>
+    </table>       
+
+    <!-- Cuerpo -->
+    <table width=100% cellspacing=0 cellpadding=0>
+       <tr>
+         <td>
+           <table width=100%>
+               <tr bgcolor=000000>
+                 <!--      <th align=left><font color=ffffff>Número</th> -->
+                 <!--      <th><font color=ffffff>Cant.</th> -->
+                 <th align="left"><font color="ffffff">Cant.</th>
+                 <th align="left"><font color="ffffff">Descripción</th>
+                 <th align="left"><font color="ffffff">Precio</th>
+                 <!--  <th align="left"><font color="ffffff">Dto.</th> -->
+                 <th align="left"><font color="ffffff">Importe</th>
+               </tr>
+
+               <tr>
+                 <td colspan="4"><hr noshade></td>
+               </tr>    
+               
+<%foreach number%>
+       <tr valign=top>
+         <!--      <td><%number%></td> -->
+         <!--      <td><%unit%></td> -->
+         <td align="right"><%qty%></td> 
+         <td align="left"><%description%></td>
+         <td align="right"><%sellprice%></td>
+         <!--      <td align=right><%discount%></td> -->
+         <td align="right"><%linetotal%></td>
+       </tr>
+<%end number%>
+    
+    <tr>
+      <td colspan="4"><hr noshade></td>
+    </tr>    
+  </table>
+    
+    <!-- Subtotales, impuestos y totales -->
+    <table width="100%">
+    <tr>
+<%if taxincluded%>
+    <th align=right>Total</th>
+    <td align=right><%invtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+    <th align="right">Base imponible</th>
+    <td align="right"><%subtotal%> &euro;</td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th align="right">IVA (<%taxrate%>%) sobre <%taxbase%>:</th>
+      <td align="right"><%tax%> &euro;</td>
+    </tr>
+<%end tax%>
+    
+<%if paid%>
+    <tr>
+      <th align="right">Pagado:</th>
+      <td align="right"><%paid%> &euro;</td>
+    </tr>
+<%end paid%>
+    
+    <tr>
+      <td>&nbsp;</td>
+      <td><hr noshade></td>
+    </tr>
+
+    <tr>
+      <th align="right">Total:</th>
+      <th align="right"><%invtotal%> &euro;</th>
+    </tr>
+    
+    <tr>
+      <td colspan="4">&nbsp;</td>
+    </tr>
+    
+    </table>
+
+
+    <!-- Pie -->
+    <table width="100%">
+       <tr valign=top>
+<%if notes%>
+         <td>Notas</td>
+         <td><%notes%></td>
+<%end notes%>
+  </tr>
+    
+<%if taxincluded%>
+    <tr>
+      <th colspan="2" align="left"><font size=-2>Los precios incluyen impuestos.</th>
+    </tr>
+<%end taxincluded%>
+    
+  </table>
+
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Spanish_Letter-packing_list.tex b/sql-ledger/templates/Spanish_Letter-packing_list.tex
new file mode 100644 (file)
index 0000000..bf146ca
--- /dev/null
@@ -0,0 +1,108 @@
+\documentclass[letterpaper,oneside]{article}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+%\usepackage{marvosym}  % Euro \EUR
+\usepackage{fancyhdr}
+\setlength{\topmargin}{0cm}
+\setlength{\topskip}{0cm}
+\setlength{\headheight}{0cm}
+\setlength{\headsep}{0.5cm}
+\setlength{\textheight}{24.2cm}
+\setlength{\textwidth}{19cm}
+\setlength{\oddsidemargin}{-1.4cm}
+\setlength{\evensidemargin}{-1.4cm}
+\setlength{\footskip}{1cm}
+
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{13.0cm}
+
+\newsavebox{\hdr}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\sbox{\hdr}{
+
+\begin{minipage}[t]{0.6\linewidth}
+\vspace{2.2cm}
+
+\begin{tabular}[t]{p{1.7cm}p{1.7cm}p{2.4cm}p{1.7cm}}\\
+\centering{Número} & \centering{Número} & \centering{Fecha} & C. Cliente\\
+  \centering{<%ordnumber%>} & \centering{<%invnumber%>} & \centering{<%invdate%>} & \centering{<%customer_id%>}
+\end{tabular}
+\end{minipage}
+
+\begin{minipage}[t]{0.4\linewidth}
+\textbf{A L B A R Á N} 
+\vspace{1cm}
+
+<%shiptoname%>
+
+<%shiptoaddr1%>
+
+<%shiptoaddr2%>
+
+<%shiptoaddr3%>
+
+<%shiptoaddr4%>
+\end{minipage}
+
+}
+
+\pagestyle{fancy}
+\renewcommand{\headrulewidth}{0cm}
+\renewcommand{\footrulewidth}{0cm}
+\cfoot{\thepage}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+%\thispagestyle{empty}     %use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+\newpage
+\usebox{\hdr}
+\vspace{0.5cm}
+
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%end pagebreak%>
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\usebox{\hdr}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%foreach number%>
+  <%qty%> & <%description%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+\parbox{\textwidth}{
+\vspace{12pt}
+<%if notes%>
+  <%notes%>
+<%end if%>
+}
+
+\vfill
+
+\begin{flushright}
+\begin{tabularx}{10cm}{Xr@{}}
+  \textbf{Base imponible} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  IVA (<%taxrate%>\%) sobre <%taxbase%> & <%tax%> \\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%invtotal%>} \\
+\end{tabularx}
+\end{flushright}
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_Letter-purchase_order.html b/sql-ledger/templates/Spanish_Letter-purchase_order.html
new file mode 100644 (file)
index 0000000..693fe65
--- /dev/null
@@ -0,0 +1,153 @@
+<head>
+  <title>Pedido de Instalaciones Industriales San José</title>
+</head>
+
+<body bgcolor="ffffff">
+    <!-- Cabecera -->
+    <table width="100%">
+       <tr valign=bottom>
+         <td width="10">&nbsp;</td>
+         <td>  
+           <table width=100%>
+               <tr>
+                 <th colspan="4"> </th>
+                 <th align="left">
+                   <h4>P E D I D O</h4>
+                 </th>
+               </tr>
+               
+               <tr>
+                 <td colspan="5"> </td>
+               </tr>
+               
+               <tr>
+                 <td colspan="4"> </td>
+                 <td align="left"><%name%></td>
+               </tr>
+               
+               <tr>
+                 <td>Número</td>
+                 <td>Fecha</td>
+                 <td>Cód. Proveedor</td> 
+                 <td width="10%"> </td>
+                 <td><%addr1%></td>
+               </tr>
+               <tr>
+                 <td><b><%ordnumber%></b></td>
+                 <td><b><%orddate%></b></td>
+                 <td><b><%vendor_id%></b></td>
+                 <td> </td>
+                 <td><%addr2%></td>
+               </tr>
+               <tr>
+                 <td colspan="4">
+                 <td><%addr3%></td>
+               </tr>
+               <tr>
+                 <td colspan="4">
+                 <td><%addr4%></td>
+               </tr>
+           </table>
+    </table>       
+
+    <!-- Cuerpo -->
+    <table width=100% cellspacing=0 cellpadding=0>
+       <tr>
+         <td>
+           <table width=100%>
+               <tr bgcolor=000000>
+                 <!--      <th align=left><font color=ffffff>Número</th> -->
+                 <!--      <th><font color=ffffff>Cant.</th> -->
+                 <th align="left"><font color="ffffff">Cant.</th>
+                 <th align="left"><font color="ffffff">Descripción</th>
+                 <th align="left"><font color="ffffff">Precio</th>
+                 <!--  <th align="left"><font color="ffffff">Dto.</th> -->
+                 <th align="left"><font color="ffffff">Importe</th>
+               </tr>
+
+               <tr>
+                 <td colspan="4"><hr noshade></td>
+               </tr>    
+               
+<%foreach number%>
+       <tr valign=top>
+         <!--      <td><%number%></td> -->
+         <!--      <td><%unit%></td> -->
+         <td align="right"><%qty%></td> 
+         <td align="left"><%description%></td>
+         <td align="right"><%sellprice%></td>
+         <!--      <td align=right><%discount%></td> -->
+         <td align="right"><%linetotal%></td>
+       </tr>
+<%end number%>
+    
+    <tr>
+      <td colspan="4"><hr noshade></td>
+    </tr>    
+  </table>
+    
+    <!-- Subtotales, impuestos y totales -->
+    <table width="100%">
+    <tr>
+<%if taxincluded%>
+    <th align="right">Total</th>
+    <td align="right"><%ordtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+    <th align="right">Base imponible</th>
+    <td align="right"><%subtotal%> &euro;</td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th align="right">IVA (<%taxrate%>%) sobre <%taxbase%>:</th>
+      <td align="right"><%tax%> &euro;</td>
+    </tr>
+<%end tax%>
+    
+<%if paid%>
+    <tr>
+      <th align="right">Pagado:</th>
+      <td align="right"><%paid%> &euro;</td>
+    </tr>
+<%end paid%>
+    
+    <tr>
+      <td>&nbsp;</td>
+      <td><hr noshade></td>
+    </tr>
+
+    <tr>
+      <th align="right">Total:</th>
+      <th align="right"><%ordtotal%> &euro;</th>
+    </tr>
+    
+    <tr>
+      <td colspan="4">&nbsp;</td>
+    </tr>
+    
+    </table>
+
+
+    <!-- Pie -->
+    <table width="100%">
+       <tr valign=top>
+<%if notes%>
+         <td>Notas</td>
+         <td><%notes%></td>
+<%end notes%>
+  </tr>
+    
+<%if taxincluded%>
+    <tr>
+      <th colspan="2" align="left"><font size=-2>Los precios incluyen impuestos.</th>
+    </tr>
+<%end taxincluded%>
+    
+  </table>
+
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Spanish_Letter-purchase_order.tex b/sql-ledger/templates/Spanish_Letter-purchase_order.tex
new file mode 100644 (file)
index 0000000..177f4b8
--- /dev/null
@@ -0,0 +1,107 @@
+\documentclass[letterpaper,oneside]{article}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+%\usepackage{marvosym}  % Euro \EUR
+\usepackage{fancyhdr}
+\setlength{\topmargin}{0cm}
+\setlength{\topskip}{0cm}
+\setlength{\headheight}{0cm}
+\setlength{\headsep}{0.5cm}
+\setlength{\textheight}{24.2cm}
+\setlength{\textwidth}{19cm}
+\setlength{\oddsidemargin}{-1.4cm}
+\setlength{\evensidemargin}{-1.4cm}
+\setlength{\footskip}{1cm}
+
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{13.0cm}
+
+\newsavebox{\hdr}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\sbox{\hdr}{
+\begin{minipage}[t]{0.6\linewidth}
+\vspace{2.2cm}
+
+\begin{tabular}[t]{p{1.7cm}p{2.4cm}p{1.7cm}}\\
+\centering{Número} & \centering{Fecha} & C. Cliente\\
+\centering{<%ordnumber%>} & \centering{<%orddate%>} & \centering{<%vendor_id%>}
+\end{tabular}
+\end{minipage}
+
+\begin{minipage}[t]{0.4\linewidth}
+\textbf{O R D E N \quad D E \quad C O M P R A} 
+\vspace{1cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+\end{minipage}
+
+}
+
+\pagestyle{fancy}
+\renewcommand{\headrulewidth}{0cm}
+\renewcommand{\footrulewidth}{0cm}
+\cfoot{\thepage}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+%\thispagestyle{empty}     %use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+\newpage
+\usebox{\hdr}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%end pagebreak%>
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\usebox{\hdr}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%foreach number%>
+  <%qty%> & <%description%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+\parbox{\textwidth}{
+\vspace{12pt}
+<%if notes%>
+  <%notes%>
+<%end if%>
+}
+
+\vfill
+
+\begin{flushright}
+\begin{tabularx}{10cm}{Xr@{}}
+  \textbf{Base imponible} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  IVA (<%taxrate%>\%) sobre <%taxbase%> & <%tax%> \\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>} \\
+\end{tabularx}
+\end{flushright}
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_Letter-receipt.tex b/sql-ledger/templates/Spanish_Letter-receipt.tex
new file mode 100644 (file)
index 0000000..5b64e81
--- /dev/null
@@ -0,0 +1,71 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.4cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.0cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+
+\fontfamily{cmss}\fontsize{9pt}{9pt}\selectfont
+
+\parbox[t]{12cm}{
+  <%company%>
+
+  <%address%>}
+\hfill
+\parbox[t]{6cm}{\hfill <%source%>}
+
+\vspace*{0.6cm}
+
+<%text_amount%> \dotfill <%decimal%>/100 \makebox[0.5cm]{\hfill}
+
+\vspace{0.5cm}
+
+\hfill <%datepaid%> \makebox[2cm]{\hfill} <%amount%>
+
+\vspace{0.5cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+\vspace{2.8cm}
+
+<%company%>
+
+\vspace{0.5cm}
+
+<%name%> \hfill <%datepaid%> \hfill <%source%>
+
+\vspace{0.5cm}
+\begin{tabularx}{\textwidth}{lXrr@{}}
+\textbf{Invoice No.} & \textbf{Invoice Date}
+  & \textbf{Due} & \textbf{Applied} \\
+<%foreach invnumber%>
+<%invnumber%> & <%invdate%> \dotfill
+  & <%due%> & <%paid%> \\
+<%end invnumber%>
+\end{tabularx}
+
+\vfill
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_Letter-sales_order.html b/sql-ledger/templates/Spanish_Letter-sales_order.html
new file mode 100644 (file)
index 0000000..d54f375
--- /dev/null
@@ -0,0 +1,153 @@
+<head>
+  <title>Presupuesto de Instalaciones Industriales San José</title>
+</head>
+
+<body bgcolor="ffffff">
+    <!-- Cabecera -->
+    <table width="100%">
+       <tr valign=bottom>
+         <td width="10">&nbsp;</td>
+         <td>  
+           <table width=100%>
+               <tr>
+                 <th colspan="4"> </th>
+                 <th align="left">
+                   <h4>P R E S U P U E S T O</h4>
+                 </th>
+               </tr>
+               
+               <tr>
+                 <td colspan="5"> </td>
+               </tr>
+               
+               <tr>
+                 <td colspan="4"> </td>
+                 <td align="left"><%name%></td>
+               </tr>
+               
+               <tr>
+                 <td>Número</td>
+                 <td>Fecha</td>
+                 <td>Cód. Cliente</td> 
+                 <td width="10%"> </td>
+                 <td><%addr1%></td>
+               </tr>
+               <tr>
+                 <td><b><%ordnumber%></b></td>
+                 <td><b><%orddate%></b></td>
+                 <td><b><%customer_id%></b></td>
+                 <td> </td>
+                 <td><%addr2%></td>
+               </tr>
+               <tr>
+                 <td colspan="4">
+                 <td><%addr3%></td>
+               </tr>
+               <tr>
+                 <td colspan="4">
+                 <td><%addr4%></td>
+               </tr>
+           </table>
+    </table>       
+
+    <!-- Cuerpo -->
+    <table width=100% cellspacing=0 cellpadding=0>
+       <tr>
+         <td>
+           <table width=100%>
+               <tr bgcolor=000000>
+                 <!--      <th align=left><font color=ffffff>Número</th> -->
+                 <!--      <th><font color=ffffff>Cant.</th> -->
+                 <th align="left"><font color="ffffff">Cant.</th>
+                 <th align="left"><font color="ffffff">Descripción</th>
+                 <th align="left"><font color="ffffff">Precio</th>
+                 <!--  <th align="left"><font color="ffffff">Dto.</th> -->
+                 <th align="left"><font color="ffffff">Importe</th>
+               </tr>
+
+               <tr>
+                 <td colspan="4"><hr noshade></td>
+               </tr>    
+               
+<%foreach number%>
+       <tr valign=top>
+         <!--      <td><%number%></td> -->
+         <!--      <td><%unit%></td> -->
+         <td align="right"><%qty%></td> 
+         <td align="left"><%description%></td>
+         <td align="right"><%sellprice%></td>
+         <!--      <td align=right><%discount%></td> -->
+         <td align="right"><%linetotal%></td>
+       </tr>
+<%end number%>
+    
+    <tr>
+      <td colspan="4"><hr noshade></td>
+    </tr>    
+  </table>
+    
+    <!-- Subtotales, impuestos y totales -->
+    <table width="100%">
+    <tr>
+<%if taxincluded%>
+    <th align=right>Total</th>
+    <td align=right><%ordtotal%></td>
+<%end taxincluded%>
+<%if not taxincluded%>
+    <th align="right">Base imponible</th>
+    <td align="right"><%subtotal%> &euro;</td>
+<%end taxincluded%>
+    </tr>
+
+<%foreach tax%>
+    <tr>
+      <th align="right">IVA (<%taxrate%>%) sobre <%taxbase%>:</th>
+      <td align="right"><%tax%> &euro;</td>
+    </tr>
+<%end tax%>
+    
+<%if paid%>
+    <tr>
+      <th align="right">Pagado:</th>
+      <td align="right"><%paid%> &euro;</td>
+    </tr>
+<%end paid%>
+    
+    <tr>
+      <td>&nbsp;</td>
+      <td><hr noshade></td>
+    </tr>
+
+    <tr>
+      <th align="right">Total:</th>
+      <th align="right"><%ordtotal%> &euro;</th>
+    </tr>
+    
+    <tr>
+      <td colspan="4">&nbsp;</td>
+    </tr>
+    
+    </table>
+
+
+    <!-- Pie -->
+    <table width="100%">
+       <tr valign=top>
+<%if notes%>
+         <td>Notas</td>
+         <td><%notes%></td>
+<%end notes%>
+  </tr>
+    
+<%if taxincluded%>
+    <tr>
+      <th colspan="2" align="left"><font size=-2>Los precios incluyen impuestos.</th>
+    </tr>
+<%end taxincluded%>
+    
+  </table>
+
+
+</body>
+</html>
+
diff --git a/sql-ledger/templates/Spanish_Letter-sales_order.tex b/sql-ledger/templates/Spanish_Letter-sales_order.tex
new file mode 100644 (file)
index 0000000..fd51cb6
--- /dev/null
@@ -0,0 +1,107 @@
+\documentclass[letterpaper,oneside]{article}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+%\usepackage{marvosym}  % Euro \EUR
+\usepackage{fancyhdr}
+\setlength{\topmargin}{0cm}
+\setlength{\topskip}{0cm}
+\setlength{\headheight}{0cm}
+\setlength{\headsep}{0.5cm}
+\setlength{\textheight}{24.2cm}
+\setlength{\textwidth}{19cm}
+\setlength{\oddsidemargin}{-1.4cm}
+\setlength{\evensidemargin}{-1.4cm}
+\setlength{\footskip}{1cm}
+
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{13.0cm}
+
+\newsavebox{\hdr}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\sbox{\hdr}{
+\begin{minipage}[t]{0.6\linewidth}
+\vspace{2.2cm}
+
+\begin{tabular}[t]{p{1.7cm}p{2.4cm}p{1.7cm}}\\
+\centering{Número} & \centering{Fecha} & C. Cliente\\
+\centering{<%ordnumber%>} & \centering{<%orddate%>} & \centering{<%vendor_id%>}
+\end{tabular}
+\end{minipage}
+
+\begin{minipage}[t]{0.4\linewidth}
+\textbf{P E D I D O} 
+\vspace{1cm}
+
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+\end{minipage}
+
+}
+
+\pagestyle{fancy}
+\renewcommand{\headrulewidth}{0cm}
+\renewcommand{\footrulewidth}{0cm}
+\cfoot{\thepage}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+%\thispagestyle{empty}     %use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+\newpage
+\usebox{\hdr}
+%\markboth{\usebox{\hdr}}{\usebox{\hdr}}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%end pagebreak%>
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\usebox{\hdr}
+\vspace{0.5cm}
+
+\begin{tabular*}{\textwidth}{rp{\descrwidth}rr}
+  \textbf{Cant.} & \textbf{Descripción} & \textbf{Precio} & \textbf{Importe} \\ \hline
+<%foreach number%>
+  <%qty%> & <%description%> & <%sellprice%> & <%linetotal%> \\
+<%end number%>
+\end{tabular*}
+
+\parbox{\textwidth}{
+\vspace{12pt}
+<%if notes%>
+  <%notes%>
+<%end if%>
+}
+
+\vfill
+
+\begin{flushright}
+\begin{tabularx}{10cm}{Xr@{}}
+  \textbf{Base imponible} & \textbf{<%subtotal%>} \\
+<%foreach tax%>
+  IVA (<%taxrate%>\%) sobre <%taxbase%> & <%tax%> \\
+<%end tax%>
+  \hline
+  \textbf{Total} & \textbf{<%ordtotal%>} \\
+\end{tabularx}
+\end{flushright}
+
+%\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\end{document}
+
diff --git a/sql-ledger/templates/Spanish_Letter-statement.html b/sql-ledger/templates/Spanish_Letter-statement.html
new file mode 100644 (file)
index 0000000..6fca322
--- /dev/null
@@ -0,0 +1,121 @@
+
+<body bgcolor=ffffff>
+
+<table width=100%>
+  <tr>
+    <td width=10>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr>
+         <td>
+           <h4>
+           <%company%>
+           <br><%address%>
+           </h4>
+         </td>
+         <th><img src=http://www.sql-ledger.org/images/sql-ledger.png border=0 width=64 height=58></th>
+         <td align=right>
+         <h4>
+         Tel: <%tel%>
+         <br>Fax: <%fax%>
+         </h4>
+         </td>
+       </tr>
+       <tr>
+         <th colspan=3><h4>S T A T E M E N T</h4></th>
+       </tr>
+       <tr>
+         <td colspan=3 align=right><%statementdate%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+       <tr valign=top>
+         <td><%name%>
+         <br><%addr1%>
+         <br><%addr2%>
+         <br><%addr3%>
+         <br><%addr4%>
+         <br>
+<%if customerphone%>
+         <br>Tel: <%customerphone%>
+<%end customerphone%>
+<%if customerfax%>
+         <br>Fax: <%customerfax%>
+<%end customerfax%>
+<%if email%>
+         <br><%email%>
+<%end email%>
+         </td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>
+      <table width=100%>
+        <tr>
+         <th align=left>Invoice #</th>
+         <th width=15%>Date</th>
+         <th width=15%>Due</th>
+         <th width=10%>Current</th>
+         <th width=10%>30</th>
+         <th width=10%>60</th>
+         <th width=10%>90+</th>
+       </tr>
+<%foreach invnumber%>
+       <tr>
+         <td><%invnumber%></td>
+         <td><%invdate%></td>
+         <td><%duedate%></td>
+         <td align=right><%c0%></td>
+         <td align=right><%c30%></td>
+         <td align=right><%c60%></td>
+         <td align=right><%c90%></td>
+       </tr>
+<%end invnumber%>
+        <tr>
+         <td colspan=7><hr size=1></td>
+       </tr>
+       <tr>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <td>&nbsp;</td>
+         <th align=right><%c0total%></td>
+         <th align=right><%c30total%></td>
+         <th align=right><%c60total%></td>
+         <th align=right><%c90total%></td>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr height=10></tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td align=right>
+      <table width=50%>
+        <tr>
+         <th>Total Outstanding</th>
+          <th align=right><%total%></th>
+       </tr>
+      </table>
+    </td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td><hr noshade></td>
+  </tr>
+  <tr>
+    <td>&nbsp;</td>
+    <td>Please make check payable to <b><%company%></b>.
+    </td>
+  </tr>
+  <tr height=20></tr>
+</table>
+
diff --git a/sql-ledger/templates/Spanish_Letter-statement.tex b/sql-ledger/templates/Spanish_Letter-statement.tex
new file mode 100644 (file)
index 0000000..0b63f75
--- /dev/null
@@ -0,0 +1,137 @@
+\documentclass[twoside]{scrartcl}
+\usepackage[frame]{xy}
+\usepackage{tabularx}
+\usepackage[latin1]{inputenc}
+\setlength{\voffset}{0.5cm}
+\setlength{\hoffset}{-2.0cm}
+\setlength{\topmargin}{0cm}
+\setlength{\headheight}{0.5cm}
+\setlength{\headsep}{1cm}
+\setlength{\topskip}{0pt}
+\setlength{\oddsidemargin}{1.0cm}
+\setlength{\evensidemargin}{1.0cm}
+\setlength{\textwidth}{19.2cm}
+\setlength{\textheight}{24.5cm}
+\setlength{\footskip}{1cm}
+\setlength{\parindent}{0pt}
+\renewcommand{\baselinestretch}{1}
+\begin{document}
+
+\newlength{\descrwidth}\setlength{\descrwidth}{10cm}
+
+\newsavebox{\hdr}
+\sbox{\hdr}{
+  \fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+  \parbox{\textwidth}{
+    \parbox[b]{12cm}{
+      <%company%>
+
+      <%address%>}\hfill
+    \begin{tabular}[b]{rrr@{}}
+    Tel & <%tel%>\\
+    Fax & <%fax%>
+    \end{tabular}
+
+    \rule[1.5ex]{\textwidth}{0.5pt}
+  }
+}
+
+\fontfamily{cmss}\fontshape{n}\selectfont
+
+\markboth{<%company%>\hfill <%statementdate%>}{\usebox{\hdr}}
+
+\pagestyle{myheadings}
+%\thispagestyle{empty}     use this with letterhead paper
+
+<%pagebreak 90 27 48%>
+\end{tabular*}
+
+  \rule{\textwidth}{2pt}
+
+  \hfill
+  \begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Subtotal} & \textbf{<%sumcarriedforward%>} \\
+  \end{tabularx}
+
+\newpage
+
+\markright{<%company%>\hfill <%statementdate%>}
+
+\vspace*{-12pt}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+  carried forward from <%lastpage%> & & & & & & <%sumcarriedforward%> \\
+<%end pagebreak%>
+
+
+\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
+
+\vspace*{1.5cm}
+
+\parbox[t]{1cm}{\hfill}
+\parbox[t]{10.5cm}{
+  
+<%name%>
+
+<%addr1%>
+
+<%addr2%>
+
+<%addr3%>
+
+<%addr4%>
+
+}
+\parbox[t]{7.5cm}{
+<%if customerphone%>
+Tel: <%customerphone%>
+<%end customerphone%>
+
+<%if customerfax%>
+Fax: <%customerfax%>
+<%end customerfax%>
+
+<%email%>
+}
+\hfill
+
+\vspace{1cm}
+
+\textbf{S T A T E M E N T} \hfill
+
+\hfill <%statementdate%>
+
+\vspace{2cm}
+
+\begin{tabular*}{\textwidth}{@{}l@{\extracolsep\fill}ccrrrr@{}}
+  \textbf{Invoice \#} & \textbf{Date} & \textbf{Due} &
+  \textbf{Current} & \textbf{30} & \textbf{60} & \textbf{90+} \\
+<%foreach invnumber%>
+  <%invnumber%> & <%invdate%> & <%duedate%> &
+  <%c0%> & <%c30%> & <%c60%> & <%c90%> \\
+<%end invnumber%>
+\textbf{Subtotal} & & & <%c0total%> & <%c30total%> & <%c60total%> & <%c90total%>
+\end{tabular*}
+\rule{\textwidth}{1pt}
+
+\vspace{1cm}
+
+\hfill
+\begin{tabularx}{7cm}{Xr@{}}
+  \textbf{Total outstanding} & <%total%>
+\end{tabularx}
+
+\vfill
+
+Please make check payable to <%company%>
+
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\footnotetext[1]{\tiny
+}
+
+\end{document}
+
diff --git a/sql-ledger/users/members.default b/sql-ledger/users/members.default
new file mode 100644 (file)
index 0000000..5f7830d
--- /dev/null
@@ -0,0 +1,5 @@
+# SQL-Ledger Accounting members
+
+[root login]
+password=
+